~ubuntu-branches/ubuntu/raring/codeblocks/raring-proposed

« back to all changes in this revision

Viewing changes to src/plugins/contrib/MouseSap/MouseSap.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Cosme Domínguez Díaz
  • Date: 2010-08-09 04:38:38 UTC
  • mfrom: (1.1.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20100809043838-a59ygguym4eg0jgw
Tags: 10.05-0ubuntu1
* New upstream release. Closes (LP: #322350)
 - Switch to dpkg-source 3.0 (quilt) format
 - Remove unneeded README.source
 - Add debian/get-source-orig script that removes all
   Windows prebuilt binaries
* Bump Standards-Version to 3.9.1
 - Stop shipping *.la files
* debian/control
 - Add cdbs package as Build-Depend
 - Add libbz2-dev and zlib1g-dev packages as
   Build-Depends (needed by libhelp_plugin.so)
 - Remove dpatch package of Build-Depends
 - Add codeblocks-contrib-debug package
 - Split architecture-independent files of codeblocks
   package in codeblocks-common package
* debian/rules
 - Switch to CDBS rules system
 - Add parallel build support
 - Add a call to debian/get-source-orig script
 - Use lzma compression (saves 23,5 MB of free space)
* debian/patches
 - Refresh 01_codeblocks_plugin_path
 - Add 02_no_Makefiles_in_debian_dir to remove any link
   in codeblocks build system to deleted Makefiles of debian directory
 - Drop 02_ftbfs_gcc44 and 03_ftbfs_glib221 (merged in upstream)
* debian/watch
 - Update to use the new host (berlios.de)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************
 
2
 * Name:      MouseSap.cpp
 
3
 * Purpose:   Code::Blocks plugin
 
4
 * Author:    Pecan<>
 
5
 * Copyright: (c) Pecan
 
6
 * License:   GPL
 
7
 **************************************************************/
 
8
// This plugin emulates Linux GPM functions within the editors in linux and msWindows.
 
9
// If selected text, paste selected text at current cursor position
 
10
// If selected text, and user middle-clicks inside selection, copy to clipboard
 
11
// If no selected text, paste clipboard data at cursor position
 
12
// If selected text, and user switches editors, copy selection to clipboard
 
13
 
 
14
#if defined(__GNUG__) && !defined(__APPLE__)
 
15
        #pragma implementation "MouseSap.h"
 
16
#endif
 
17
 
 
18
 
 
19
#include <sdk.h>
 
20
#ifndef CB_PRECOMP
 
21
        #include <wx/intl.h>
 
22
        #include <wx/listctrl.h>
 
23
        #include "cbeditor.h"
 
24
        #include "configmanager.h"
 
25
        #include "editormanager.h"
 
26
        #include "manager.h"
 
27
        #include "personalitymanager.h"
 
28
        #include "sdk_events.h" // EVT_APP_STARTUP_DONE
 
29
#endif
 
30
 
 
31
#include <wx/fileconf.h> // wxFileConfig
 
32
#include <wx/clipbrd.h>
 
33
#include <wx/strconv.h>
 
34
#include "cbstyledtextctrl.h"
 
35
#include "MouseSap.h"
 
36
 
 
37
#if defined(__WXGTK__)
 
38
    // hack to avoid name-conflict between wxWidgets GSocket and the one defined
 
39
    // in newer glib-headers
 
40
    #define GSocket GLibSocket
 
41
    #include "gtk/gtk.h"
 
42
    #undef GSocket
 
43
#endif
 
44
 
 
45
// Register the plugin
 
46
namespace
 
47
{
 
48
    PluginRegistrant<MouseSap> reg(_T("MouseSap"));
 
49
};
 
50
 
 
51
int ID_DLG_DONE = wxNewId();
 
52
 
 
53
// ----------------------------------------------------------------------------
 
54
BEGIN_EVENT_TABLE(MouseSap, cbPlugin)
 
55
        // add events here...
 
56
END_EVENT_TABLE()
 
57
// ----------------------------------------------------------------------------
 
58
//  Statics
 
59
// ----------------------------------------------------------------------------
 
60
// global used by mouse events to get user configuration settings
 
61
// and plugin routine support
 
62
MouseSap* MouseSap::pMouseSap;
 
63
 
 
64
// ----------------------------------------------------------------------------
 
65
MouseSap::MouseSap()
 
66
// ----------------------------------------------------------------------------
 
67
{
 
68
        //ctor
 
69
        // anchor to this one and only object
 
70
    pMouseSap = this;
 
71
}
 
72
// ----------------------------------------------------------------------------
 
73
MouseSap::~MouseSap()
 
74
// ----------------------------------------------------------------------------
 
75
{
 
76
        //dtor
 
77
}
 
78
 
 
79
// ----------------------------------------------------------------------------
 
80
void MouseSap::OnAttach()
 
81
// ----------------------------------------------------------------------------
 
82
{
 
83
        // do whatever initialization you need for your plugin
 
84
        // NOTE: after this function, the inherited member variable
 
85
        // IsAttached() will be TRUE...
 
86
        // You should check for it in other functions, because if it
 
87
        // is FALSE, it means that the application did *not* "load"
 
88
        // (see: does not need) this plugin...
 
89
 
 
90
    m_pMyLog = NULL;
 
91
    m_pMMSapEvents = 0;
 
92
 
 
93
    wxWindow* pcbWindow = Manager::Get()->GetAppWindow();
 
94
    m_pMS_Window = pcbWindow;
 
95
    #if defined(LOGGING)
 
96
        wxLog::EnableLogging(true);
 
97
        /*wxLogWindow**/ m_pMyLog = new wxLogWindow(pcbWindow, wxT("MouseSap"), true, false);
 
98
        wxLog::SetActiveTarget(m_pMyLog);
 
99
        m_pMyLog->Flush();
 
100
        m_pMyLog->GetFrame()->Move(20,20);
 
101
        wxLogMessage(_T("Logging MouseSap version %s"),wxString(wxT(VERSION)).c_str());
 
102
        #endif
 
103
 
 
104
    // names of windows we're allowed to attach
 
105
    m_UsableWindows.Add(_T("sciwindow"));
 
106
 
 
107
    m_bMouseSapEnabled    = true;
 
108
 
 
109
    // Create filename like MouseSap.ini
 
110
    //memorize the key file name as {%HOME%}\MouseSap.ini
 
111
    m_ConfigFolder = ConfigManager::GetConfigFolder();
 
112
    m_DataFolder = ConfigManager::GetDataFolder();
 
113
    m_ExecuteFolder = FindAppPath(wxTheApp->argv[0], ::wxGetCwd(), wxEmptyString);
 
114
 
 
115
    //GTK GetConfigFolder is returning double "//?, eg, "/home/pecan//.codeblocks"
 
116
    // remove the double //s from filename //+v0.4.11
 
117
    m_ConfigFolder.Replace(_T("//"),_T("/"));
 
118
    m_ExecuteFolder.Replace(_T("//"),_T("/"));
 
119
 
 
120
    // get the CodeBlocks "personality" argument
 
121
    wxString m_Personality = Manager::Get()->GetPersonalityManager()->GetPersonality();
 
122
        if (m_Personality == wxT("default")) m_Personality = wxEmptyString;
 
123
     LOGIT( _T("Personality is[%s]"), m_Personality.GetData() );
 
124
 
 
125
    // if MouseSap.ini is in the executable folder, use it
 
126
    // else use the default config folder
 
127
    m_CfgFilenameStr = m_ExecuteFolder + wxFILE_SEP_PATH;
 
128
    if (not m_Personality.IsEmpty()) m_CfgFilenameStr << m_Personality + wxT(".") ;
 
129
    m_CfgFilenameStr << _T("MouseSap.ini");
 
130
 
 
131
    if (::wxFileExists(m_CfgFilenameStr)) {;/*OK Use exe path*/}
 
132
    else //use the default.conf folder
 
133
    {   m_CfgFilenameStr = m_ConfigFolder + wxFILE_SEP_PATH;
 
134
        if (not m_Personality.IsEmpty()) m_CfgFilenameStr << m_Personality + wxT(".") ;
 
135
        m_CfgFilenameStr << _T("MouseSap.ini");
 
136
    }
 
137
    //LOGIT(_T("MouseSap Config Filename:[%s]"), m_CfgFilenameStr.GetData());
 
138
    // read configuaton file
 
139
    //wxFileConfig cfgFile(wxEmptyString,     // appname
 
140
    //                    wxEmptyString,      // vendor
 
141
    //                    m_CfgFilenameStr,   // local filename
 
142
    //                    wxEmptyString,      // global file
 
143
    //                    wxCONFIG_USE_LOCAL_FILE);
 
144
    //
 
145
    //cfgFile.Read(_T("MouseSapEnabled"),  &MouseSapEnabled ) ;
 
146
 
 
147
    // Pointer to "Search Results" Window (first listCtrl window)
 
148
 
 
149
    // Catch creation of windows
 
150
    Connect( wxEVT_CREATE,
 
151
        (wxObjectEventFunction) (wxEventFunction)
 
152
        (wxCommandEventFunction) &MouseSap::OnWindowOpen);
 
153
 
 
154
    // Catch Destroyed windows
 
155
    Connect( wxEVT_DESTROY,
 
156
        (wxObjectEventFunction) (wxEventFunction)
 
157
        (wxCommandEventFunction) &MouseSap::OnWindowClose);
 
158
 
 
159
    // Set current plugin version
 
160
        PluginInfo* pInfo = (PluginInfo*)(Manager::Get()->GetPluginManager()->GetPluginInfo(this));
 
161
        pInfo->version = wxT(VERSION);
 
162
 
 
163
        // register event sink AppStartupDone
 
164
    Manager::Get()->RegisterEventSink(cbEVT_APP_STARTUP_DONE, new cbEventFunctor<MouseSap, CodeBlocksEvent>(this, &MouseSap::OnAppStartupDone));
 
165
 
 
166
        return ;
 
167
}
 
168
// ----------------------------------------------------------------------------
 
169
void MouseSap::OnRelease(bool appShutDown)
 
170
// ----------------------------------------------------------------------------
 
171
{
 
172
        // do de-initialization for your plugin
 
173
        // if appShutDown is false, the plugin is unloaded because Code::Blocks is being shut down,
 
174
        // which means you must not use any of the SDK Managers
 
175
        // NOTE: after this function, the inherited member variable
 
176
        // IsAttached() will be FALSE...
 
177
 
 
178
        // Remove all Mouse event handlers
 
179
        DetachAll();
 
180
        #if defined(LOGGING)
 
181
        // deleting the log crashes CB on exit
 
182
        //-delete pMyLog;
 
183
        //-m_pMyLog = 0;
 
184
    #endif
 
185
 
 
186
    delete m_pMMSapEvents;
 
187
    m_pMMSapEvents = 0;
 
188
    m_bMouseSapEnabled = false;
 
189
}
 
190
// ----------------------------------------------------------------------------
 
191
cbConfigurationPanel* MouseSap::GetConfigurationPanel(wxWindow* parent)
 
192
// ----------------------------------------------------------------------------
 
193
{
 
194
        //create and display the configuration dialog for your plugin
 
195
        return 0;
 
196
}
 
197
// ----------------------------------------------------------------------------
 
198
bool MouseSap::IsAttachedTo(wxWindow* p)
 
199
// ----------------------------------------------------------------------------
 
200
{
 
201
    if ( wxNOT_FOUND == m_EditorPtrs.Index(p))
 
202
        return false;
 
203
    return true;
 
204
 
 
205
}//IsAttachedTo
 
206
// ----------------------------------------------------------------------------
 
207
void MouseSap::Attach(wxWindow *p)
 
208
// ----------------------------------------------------------------------------{
 
209
{
 
210
        if (!p || IsAttachedTo(p))
 
211
                return;         // already attached !!!
 
212
 
 
213
    // allow only static windows to be attached by codeblocks
 
214
    // Disappearing frames/windows cause crashes
 
215
    // eg., wxArrayString m_UsableWindows = "sciwindow notebook";
 
216
 
 
217
    wxString windowName = p->GetName().MakeLower();
 
218
 
 
219
    if (wxNOT_FOUND == m_UsableWindows.Index(windowName,false))
 
220
     {
 
221
        #if defined(LOGGING)
 
222
        LOGIT(wxT("MMSap::Attach skipping [%s]"), p->GetName().c_str());
 
223
        #endif
 
224
        return;
 
225
     }
 
226
 
 
227
    #if defined(LOGGING)
 
228
    LOGIT(wxT("MMSap::Attach - attaching to [%s] %p"), p->GetName().c_str(),p);
 
229
    #endif
 
230
 
 
231
    //add window to our array, attach a mouse event handler
 
232
    m_EditorPtrs.Add(p);
 
233
    if ( not m_pMMSapEvents ) m_pMMSapEvents = new MMSapEvents(p);
 
234
    MMSapEvents* thisEvtHndlr = m_pMMSapEvents;
 
235
 
 
236
    p->Connect(wxEVT_MIDDLE_DOWN,
 
237
                    (wxObjectEventFunction)(wxEventFunction)
 
238
                    (wxMouseEventFunction)&MMSapEvents::OnMouseEvent,
 
239
                     NULL, thisEvtHndlr);
 
240
    p->Connect(wxEVT_MIDDLE_UP,
 
241
                    (wxObjectEventFunction)(wxEventFunction)
 
242
                    (wxMouseEventFunction)&MMSapEvents::OnMouseEvent,
 
243
                     NULL, thisEvtHndlr);
 
244
    p->Connect(wxEVT_KILL_FOCUS ,
 
245
                    (wxObjectEventFunction)(wxEventFunction)
 
246
                    (wxFocusEventFunction)&MMSapEvents::OnKillFocusEvent,
 
247
                     NULL, thisEvtHndlr);
 
248
    #if defined(LOGGING)
 
249
     LOGIT(_T("MMSap:Attach Window:%p Handler:%p"), p,thisEvtHndlr);
 
250
    #endif
 
251
}
 
252
 
 
253
// ----------------------------------------------------------------------------
 
254
void MouseSap::AttachRecursively(wxWindow *p)
 
255
// ----------------------------------------------------------------------------{
 
256
{
 
257
        if (!p)
 
258
                return;
 
259
 
 
260
        Attach(p);
 
261
 
 
262
        // this is the standard way wxWidgets uses to iterate through children...
 
263
        for (wxWindowList::compatibility_iterator node = p->GetChildren().GetFirst();
 
264
                node;
 
265
                node = node->GetNext())
 
266
        {
 
267
                // recursively attach each child
 
268
                wxWindow *win = (wxWindow *)node->GetData();
 
269
 
 
270
                if (win)
 
271
                        AttachRecursively(win);
 
272
        }
 
273
}
 
274
// ----------------------------------------------------------------------------
 
275
wxWindow* MouseSap::FindWindowRecursively(const wxWindow* parent, const wxWindow* handle)
 
276
// ----------------------------------------------------------------------------{
 
277
{
 
278
    if ( parent )
 
279
    {
 
280
        // see if this is the one we're looking for
 
281
        if ( parent == handle )
 
282
            return (wxWindow *)parent;
 
283
 
 
284
        // It wasn't, so check all its children
 
285
        for ( wxWindowList::compatibility_iterator node = parent->GetChildren().GetFirst();
 
286
              node;
 
287
              node = node->GetNext() )
 
288
        {
 
289
            // recursively check each child
 
290
            wxWindow *win = (wxWindow *)node->GetData();
 
291
            wxWindow *retwin = FindWindowRecursively(win, handle);
 
292
            if (retwin)
 
293
                return retwin;
 
294
        }
 
295
    }
 
296
 
 
297
    // Not found
 
298
    return NULL;
 
299
}
 
300
// ----------------------------------------------------------------------------
 
301
wxWindow* MouseSap::winExists(wxWindow *parent)
 
302
// ----------------------------------------------------------------------------{
 
303
{
 
304
 
 
305
    if ( !parent )
 
306
    {
 
307
        return NULL;
 
308
    }
 
309
 
 
310
    // start at very top of wx's windows
 
311
    for ( wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst();
 
312
          node;
 
313
          node = node->GetNext() )
 
314
    {
 
315
        // recursively check each window & its children
 
316
        wxWindow* win = node->GetData();
 
317
        wxWindow* retwin = FindWindowRecursively(win, parent);
 
318
        if (retwin)
 
319
            return retwin;
 
320
    }
 
321
 
 
322
    return NULL;
 
323
}//winExists
 
324
// ----------------------------------------------------------------------------
 
325
void MouseSap::Detach(wxWindow* thisEditor)
 
326
// ----------------------------------------------------------------------------
 
327
{
 
328
    if ( (thisEditor) && (m_EditorPtrs.Index(thisEditor) != wxNOT_FOUND))
 
329
    {
 
330
         #if defined(LOGGING)
 
331
          LOGIT(_T("MMSap:Detaching %p"), thisEditor);
 
332
         #endif
 
333
 
 
334
        MMSapEvents* thisEvtHandler = m_pMMSapEvents;
 
335
        m_EditorPtrs.Remove(thisEditor);
 
336
 
 
337
        // If win already deleted, dont worry about receiving events
 
338
            if ( not winExists(thisEditor) )
 
339
            {
 
340
            #if defined(LOGGING)
 
341
                LOGIT(_T("MMSap:DetachAll window NOT found %p"), thisEditor);
 
342
            #endif
 
343
            } else {
 
344
            thisEditor->Disconnect(wxEVT_MIDDLE_DOWN,
 
345
                            (wxObjectEventFunction)(wxEventFunction)
 
346
                            (wxMouseEventFunction)&MMSapEvents::OnMouseEvent,
 
347
                             NULL, thisEvtHandler);
 
348
            thisEditor->Disconnect(wxEVT_MIDDLE_UP,
 
349
                            (wxObjectEventFunction)(wxEventFunction)
 
350
                            (wxMouseEventFunction)&MMSapEvents::OnMouseEvent,
 
351
                             NULL, thisEvtHandler);
 
352
            thisEditor->Disconnect(wxEVT_KILL_FOCUS ,
 
353
                            (wxObjectEventFunction)(wxEventFunction)
 
354
                            (wxFocusEventFunction)&MMSapEvents::OnKillFocusEvent,
 
355
                            NULL, thisEvtHandler);
 
356
 
 
357
        }//fi (not winExists
 
358
 
 
359
        #if defined(LOGGING)
 
360
         LOGIT(_T("Detach: Editor:%p EvtHndlr: %p"),thisEditor,thisEvtHandler);
 
361
        #endif
 
362
    }//if (thisEditor..
 
363
}//Detach
 
364
// ----------------------------------------------------------------------------
 
365
void MouseSap::DetachAll()
 
366
// ----------------------------------------------------------------------------
 
367
{
 
368
        // delete all handlers
 
369
    #if defined(LOGGING)
 
370
        LOGIT(wxT("MMSap:DetachAll - detaching all [%d] targets"),m_EditorPtrs.GetCount() );
 
371
    #endif
 
372
 
 
373
    // Detach from memorized windows and remove event handlers
 
374
    while( m_EditorPtrs.GetCount() )
 
375
    {
 
376
            wxWindow* pw = (wxWindow*)m_EditorPtrs.Item(0);
 
377
        Detach(pw);
 
378
    }//elihw
 
379
 
 
380
    m_EditorPtrs.Empty();
 
381
 
 
382
    // say no windows attached
 
383
    m_bEditorsAttached = false;
 
384
    return;
 
385
 
 
386
}//DetachAll
 
387
// ----------------------------------------------------------------------------
 
388
wxString MouseSap::FindAppPath(const wxString& argv0, const wxString& cwd, const wxString& appVariableName)
 
389
// ----------------------------------------------------------------------------
 
390
{
 
391
    // Find the absolute path where this application has been run from.
 
392
    // argv0 is wxTheApp->argv[0]
 
393
    // cwd is the current working directory (at startup)
 
394
    // appVariableName is the name of a variable containing the directory for this app, e.g.
 
395
    // MYAPPDIR. This is checked first.
 
396
 
 
397
    wxString str;
 
398
 
 
399
    // Try appVariableName
 
400
    if (!appVariableName.IsEmpty())
 
401
    {
 
402
        str = wxGetenv(appVariableName);
 
403
        if (!str.IsEmpty())
 
404
            return str;
 
405
    }
 
406
 
 
407
#if defined(__WXMAC__) && !defined(__DARWIN__)
 
408
    // On Mac, the current directory is the relevant one when
 
409
    // the application starts.
 
410
    return cwd;
 
411
#endif
 
412
 
 
413
    if (wxIsAbsolutePath(argv0))
 
414
        return wxPathOnly(argv0);
 
415
    else
 
416
    {
 
417
        // Is it a relative path?
 
418
        wxString currentDir(cwd);
 
419
        if (currentDir.Last() != wxFILE_SEP_PATH)
 
420
            currentDir += wxFILE_SEP_PATH;
 
421
 
 
422
        str = currentDir + argv0;
 
423
        if (wxFileExists(str))
 
424
            return wxPathOnly(str);
 
425
    }
 
426
 
 
427
    // OK, it's neither an absolute path nor a relative path.
 
428
    // Search PATH.
 
429
 
 
430
    wxPathList pathList;
 
431
    pathList.AddEnvList(wxT("PATH"));
 
432
    str = pathList.FindAbsoluteValidPath(argv0);
 
433
    if (!str.IsEmpty())
 
434
        return wxPathOnly(str);
 
435
 
 
436
    // Failed
 
437
    return wxEmptyString;
 
438
}
 
439
// ----------------------------------------------------------------------------
 
440
//    MouseSap Routines to push/remove mouse event handlers
 
441
// ----------------------------------------------------------------------------
 
442
void MouseSap::OnAppStartupDone(CodeBlocksEvent& event)
 
443
// ----------------------------------------------------------------------------
 
444
{
 
445
    // EVT_APP_STARTUP_DONE
 
446
    //attach windows
 
447
    #if defined(LOGGING)
 
448
    LOGIT(_T("MouseSap::AppStartupDone"));
 
449
    #endif
 
450
 
 
451
    OnAppStartupDoneInit();
 
452
 
 
453
    event.Skip();
 
454
    return;
 
455
}//OnAppStartupDone
 
456
// ----------------------------------------------------------------------------
 
457
void MouseSap::OnAppStartupDoneInit()
 
458
// ----------------------------------------------------------------------------
 
459
{
 
460
    if (not GetMouseSapEnabled() )    //v04.14
 
461
        return;
 
462
 
 
463
    if (! m_bEditorsAttached)
 
464
    {
 
465
        AttachRecursively(Manager::Get()->GetAppWindow());
 
466
        m_bEditorsAttached = true;
 
467
    }
 
468
}
 
469
// ----------------------------------------------------------------------------
 
470
void MouseSap::OnWindowOpen(wxEvent& event)
 
471
// ----------------------------------------------------------------------------
 
472
{
 
473
    // wxEVT_CREATE entry
 
474
    // Have to do this especially for split windows since CodeBlocks does not have
 
475
    // events when opening/closing split windows
 
476
 
 
477
    wxWindow* pWindow = (wxWindow*)(event.GetEventObject());
 
478
 
 
479
    // Some code (at times) is not issuing event EVT_APP_STARTUP_DONE
 
480
    // so here we do it ourselves. If not initialized and this is the first
 
481
    // scintilla window, initialize now.
 
482
    if ( (not m_bEditorsAttached)
 
483
        && ( pWindow->GetName().Lower() == wxT("sciwindow")) )
 
484
        OnAppStartupDoneInit();
 
485
 
 
486
    // Attach a split window (or any other window)
 
487
    if ( m_bEditorsAttached )
 
488
    {
 
489
        wxWindow* pWindow = (wxWindow*)(event.GetEventObject());
 
490
        cbEditor* ed = 0;
 
491
        ed  = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
 
492
        if (ed)
 
493
        {
 
494
            if (pWindow->GetParent() ==  ed)
 
495
            {   Attach(pWindow);
 
496
                #ifdef LOGGING
 
497
                    LOGIT( _T("OnWindowOpen Attached:%p name: %s"),
 
498
                            pWindow, pWindow->GetName().GetData() );
 
499
                #endif //LOGGING
 
500
            }
 
501
        }//fi (ed)
 
502
    }//fi m_bNote...
 
503
 
 
504
    event.Skip();
 
505
}//OnWindowOpen
 
506
// ----------------------------------------------------------------------------
 
507
void MouseSap::OnWindowClose(wxEvent& event)
 
508
// ----------------------------------------------------------------------------
 
509
{
 
510
    // wxEVT_DESTROY entry
 
511
 
 
512
    wxWindow* pWindow = (wxWindow*)(event.GetEventObject());
 
513
 
 
514
    if ( (pWindow) && (m_EditorPtrs.Index(pWindow) != wxNOT_FOUND))
 
515
    {   // window is one of ours
 
516
        Detach(pWindow);
 
517
        #ifdef LOGGING
 
518
         LOGIT( _T("OnWindowClose Detached %p"), pWindow);
 
519
        #endif //LOGGING
 
520
    }
 
521
    event.Skip();
 
522
}//OnWindowClose
 
523
////////////////////////////////////////////////////////////////////////////////
 
524
// ----------------------------------------------------------------------------
 
525
//      MOUSE Select and Paste Events
 
526
// ----------------------------------------------------------------------------
 
527
///////////////////////////////////////////////////////////////////////////////
 
528
BEGIN_EVENT_TABLE(MMSapEvents, wxEvtHandler)
 
529
    //-Deprecated- EVT_MOUSE_EVENTS( MMSapEvents::OnMouseEvent)
 
530
    // Using Connect/Disconnect events  and EVT_CREATE/EVT_DESTROY
 
531
    // wxWidgets events since split-windows were
 
532
    // introduced without providing codeblocks events to plugins.
 
533
    // Without CB events, event handlers were being leaked for each split
 
534
    // window.
 
535
END_EVENT_TABLE()
 
536
// ----------------------------------------------------------------------------
 
537
MMSapEvents::~MMSapEvents()
 
538
// ----------------------------------------------------------------------------
 
539
{
 
540
    #if defined(LOGGING)
 
541
     LOGIT(_T("MMSapEvents dtor"));
 
542
    #endif
 
543
    return;
 
544
}//dtor
 
545
 
 
546
// ----------------------------------------------------------------------------
 
547
void MMSapEvents::OnMouseEvent(wxMouseEvent& event)    //MSW
 
548
// ----------------------------------------------------------------------------
 
549
{
 
550
 
 
551
    //remember event window pointer
 
552
    //-wxObject* pEvtObject = event.GetEventObject();
 
553
    int eventType = event.GetEventType();
 
554
 
 
555
    #if defined(__WXMSW__)
 
556
    // Why is an event getting in here when this window doesnt have the OS focus
 
557
    MouseSap* pMMSap = MouseSap::pMouseSap;
 
558
    if (::wxGetActiveWindow() != pMMSap->m_pMS_Window)
 
559
        {event.Skip(); return;}
 
560
    #endif
 
561
 
 
562
    // differentiate window, left, right split window
 
563
    cbEditor* ed = 0;
 
564
    cbStyledTextCtrl* pControl = 0;
 
565
    cbStyledTextCtrl* pLeftSplitWin = 0;
 
566
    cbStyledTextCtrl* pRightSplitWin = 0;
 
567
 
 
568
    ed  = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
 
569
    if ( not ed ) { event.Skip(); return; }
 
570
 
 
571
    pControl = ed->GetControl();
 
572
    // editor must have the current focus
 
573
    if ( pControl not_eq wxWindow::FindFocus()  )
 
574
        { event.Skip(); return; }
 
575
 
 
576
    pLeftSplitWin = ed->GetLeftSplitViewControl();
 
577
    pRightSplitWin = ed->GetRightSplitViewControl();
 
578
 
 
579
    #if defined(LOGGING)
 
580
    //LOGIT(_T("OnMouseSap[%d]"), eventType);
 
581
    #endif
 
582
 
 
583
    if ( eventType == wxEVT_MIDDLE_DOWN)
 
584
    {
 
585
        OnMiddleMouseDown( event, pControl );
 
586
        return;
 
587
    }// if KeyDown
 
588
 
 
589
    else if ( eventType == wxEVT_MIDDLE_UP )
 
590
    {   // We have to return so we can preserve the selection on gtk
 
591
        return;
 
592
    }// if KeyUp
 
593
 
 
594
    // pass the event onward
 
595
    event.Skip();
 
596
 
 
597
}//OnMouseEvent
 
598
// ----------------------------------------------------------------------------
 
599
void MMSapEvents::OnMiddleMouseDown(wxMouseEvent& event, cbStyledTextCtrl* ed)
 
600
// ----------------------------------------------------------------------------
 
601
{
 
602
    // If selected text, paste selected text at current cursor position
 
603
    // If selected text, and user middle-clicks inside selection, copy to clipboard
 
604
    // If no selected text, paste clipboard data at cursor position
 
605
 
 
606
    int pos = ed->PositionFromPoint(wxPoint(event.GetX(), event.GetY()));
 
607
 
 
608
    if(pos == wxSCI_INVALID_POSITION)
 
609
        return;
 
610
 
 
611
    int start = ed->GetSelectionStart();
 
612
    int end = ed->GetSelectionEnd();
 
613
 
 
614
    const wxString selectedText = ed->GetSelectedText();
 
615
 
 
616
    // If no current selection, or shift key is down, use paste from the clipboard
 
617
    bool shiftKeyState = ::wxGetKeyState(WXK_SHIFT);
 
618
 
 
619
    if (  shiftKeyState || selectedText.IsEmpty() )
 
620
    {
 
621
        PasteFromClipboard( event, ed, shiftKeyState );
 
622
        return;
 
623
    }
 
624
 
 
625
    //if user middle-clicked inside the selection, copy to clipboard
 
626
    if ( (pos >= start) && (pos <= end) )
 
627
    {
 
628
        #if defined(__WXGTK__)
 
629
            gtk_clipboard_set_text(
 
630
                gtk_clipboard_get(GDK_SELECTION_PRIMARY),
 
631
                selectedText.mb_str(wxConvUTF8),
 
632
                selectedText.Length() );
 
633
        #else //__WXMSW__
 
634
                if (wxTheClipboard->Open())
 
635
                {
 
636
                    wxTheClipboard->AddData(new wxTextDataObject(selectedText));
 
637
                    wxTheClipboard->Close();
 
638
                }
 
639
        #endif
 
640
        return;
 
641
    }//if
 
642
 
 
643
    if(pos < ed->GetCurrentPos())
 
644
    {
 
645
        start += selectedText.length();
 
646
        end += selectedText.length();
 
647
    }
 
648
 
 
649
    #if defined(LOGGING)
 
650
    //LOGIT( _T("pos,start,end[%d][%d][%d]"), pos, start, end);
 
651
    #endif
 
652
 
 
653
    // paste selected text at current cursor position
 
654
    ed->InsertText(pos, selectedText);
 
655
    //-SetSelection(start, end);
 
656
    ed->GotoPos(pos);
 
657
    ed->SetSelectionVoid(pos, pos+selectedText.length());
 
658
    #if defined(LOGGING)
 
659
    LOGIT( _T("OnMiddleMouseDown[%s]"), selectedText.c_str());
 
660
    #endif
 
661
 
 
662
} // end of OnGPM
 
663
// ----------------------------------------------------------------------------
 
664
void MMSapEvents::PasteFromClipboard( wxMouseEvent& event, cbStyledTextCtrl* ed, bool shiftKeyState )
 
665
// ----------------------------------------------------------------------------
 
666
{
 
667
    // Set the current position to the mouse click point and
 
668
    // then paste in the PRIMARY selection, if any.
 
669
 
 
670
    #if defined(LOGGING)
 
671
    LOGIT( _T("MMSapEvents pasting from Clipboard"));
 
672
    #endif
 
673
 
 
674
    int pos = ed->PositionFromPoint(wxPoint(event.GetX(), event.GetY()));
 
675
    if(pos == wxSCI_INVALID_POSITION)
 
676
        return;
 
677
 
 
678
    int start = ed->GetSelectionStart();
 
679
    int end = ed->GetSelectionEnd();
 
680
 
 
681
    wxTextDataObject data;
 
682
    bool gotData = false;
 
683
    if (wxTheClipboard->Open())
 
684
    {
 
685
        wxTheClipboard->UsePrimarySelection(true);
 
686
        gotData = wxTheClipboard->GetData(data);
 
687
        wxTheClipboard->UsePrimarySelection(false);
 
688
        wxTheClipboard->Close();
 
689
    }
 
690
    if (gotData)
 
691
    {
 
692
        wxString text = data.GetText() ;
 
693
        //if shiftstate
 
694
        if (  shiftKeyState
 
695
                &&  ((pos >= start) && (pos <= end) ) )
 
696
        {
 
697
            //-ed->Paste(); does not work on linux
 
698
            ed->SetTargetStart(start);
 
699
            ed->SetTargetEnd(end);
 
700
            ed->ReplaceTarget(text);
 
701
 
 
702
        }
 
703
        else
 
704
        {
 
705
            ed->InsertText(pos, text);
 
706
            ed->SetSelectionVoid(pos, pos + text.Length());
 
707
        }
 
708
    }
 
709
 
 
710
}
 
711
// ----------------------------------------------------------------------------
 
712
void MMSapEvents::OnKillFocusEvent( wxFocusEvent& event )
 
713
// ----------------------------------------------------------------------------
 
714
{
 
715
    //For GTK, we copy the selected text to the PRIMARY clipboard
 
716
    // when we lose the focus
 
717
 
 
718
    #if not defined(__WXGTK__)
 
719
        event.Skip(); return;
 
720
    #endif
 
721
 
 
722
    // If selected text, copy to clipboard
 
723
 
 
724
    //remember event window pointer
 
725
    wxObject* pEvtObject = event.GetEventObject();
 
726
 
 
727
    cbStyledTextCtrl* pControl = 0;
 
728
    cbEditor* ed = 0;
 
729
    wxString selectedText = wxEmptyString;
 
730
    if ( ((wxWindow*)pEvtObject)->GetName().Lower() == _T("sciwindow") )
 
731
    {   ed = (cbEditor*)((wxWindow*)pEvtObject)->GetParent();
 
732
        pControl = (cbStyledTextCtrl*)pEvtObject;
 
733
    }
 
734
 
 
735
    if ( ed ) do
 
736
    {
 
737
        if ( not MouseSap::pMouseSap->IsAttachedTo( pControl ) )
 
738
            break;
 
739
 
 
740
        selectedText = pControl->GetSelectedText();
 
741
        if ( selectedText.IsEmpty() )
 
742
            break;
 
743
 
 
744
        #if defined(__WXGTK__)
 
745
            gtk_clipboard_set_text(
 
746
                gtk_clipboard_get(GDK_SELECTION_PRIMARY),
 
747
                selectedText.mb_str(wxConvUTF8),
 
748
                selectedText.Length() );
 
749
        #else //__WXMSW__ //testing
 
750
                if (wxTheClipboard->Open())
 
751
                {
 
752
                    wxTheClipboard->AddData(new wxTextDataObject(selectedText));
 
753
                    wxTheClipboard->Close();
 
754
                }
 
755
        #endif
 
756
 
 
757
        #if defined(LOGGING)
 
758
            DumpClipboard();
 
759
            if (ed && pControl && (not selectedText.IsEmpty()))
 
760
            LOGIT( _T("OnKillFocus[%s][%s]"), ed->GetTitle().c_str(),selectedText.c_str());
 
761
        #endif
 
762
    }while(false);
 
763
 
 
764
    event.Skip();
 
765
 
 
766
} // end of OnGPM
 
767
// ----------------------------------------------------------------------------
 
768
void MMSapEvents::DumpClipboard()
 
769
// ----------------------------------------------------------------------------
 
770
{
 
771
 #if defined(LOGGING)
 
772
    wxTextDataObject primaryData;
 
773
    wxTextDataObject normalData;
 
774
    bool gotPrimaryData = false;
 
775
    bool gotNormalData = false;
 
776
    wxString primaryText = wxEmptyString;
 
777
    wxString normalText = wxEmptyString;
 
778
 
 
779
    if (wxTheClipboard->Open())
 
780
    {
 
781
        wxTheClipboard->UsePrimarySelection(true);
 
782
        gotPrimaryData = wxTheClipboard->GetData(primaryData);
 
783
        wxTheClipboard->UsePrimarySelection(false);
 
784
        gotNormalData = wxTheClipboard->GetData(normalData);
 
785
        wxTheClipboard->Close();
 
786
    }
 
787
    else {
 
788
        LOGIT(wxT("DumpClipboard: failed to open"));
 
789
        return;
 
790
    }
 
791
 
 
792
    if (gotPrimaryData)
 
793
        primaryText = primaryData.GetText() ;
 
794
    if (gotNormalData)
 
795
        normalText = normalData.GetText() ;
 
796
    LOGIT(wxT("Clipboard Primary[%s]"), primaryText.c_str() );
 
797
    LOGIT(wxT("Clipboard Normal[%s]"),  normalText.c_str() );
 
798
  #endif //defined(LOGGING)
 
799
}//DumpClipboard
 
800
///////////////////////////////////////////////////////////////////////////////////
 
801
//  The way Scintilla does GPM
 
802
///////////////////////////////////////////////////////////////////////////////////
 
803
////#ifdef __WXGTK__
 
804
////void ScintillaWX::DoMiddleButtonUp(Point pt) {
 
805
////    // Set the current position to the mouse click point and
 
806
////    // then paste in the PRIMARY selection, if any.  wxGTK only.
 
807
////    int newPos = PositionFromLocation(pt);
 
808
////    MovePositionTo(newPos, noSel, true);
 
809
////
 
810
////    pdoc->BeginUndoAction();
 
811
////    wxTextDataObject data;
 
812
////    bool gotData = false;
 
813
////    if (wxTheClipboard->Open()) {
 
814
////        wxTheClipboard->UsePrimarySelection(true);
 
815
////        gotData = wxTheClipboard->GetData(data);
 
816
////        wxTheClipboard->UsePrimarySelection(false);
 
817
////        wxTheClipboard->Close();
 
818
////    }
 
819
////    if (gotData) {
 
820
////        wxString   text = wxTextBuffer::Translate(data.GetText(),
 
821
////                                                  wxConvertEOLMode(pdoc->eolMode));
 
822
////        wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
 
823
////        int        len = strlen(buf);
 
824
////        pdoc->InsertString(currentPos, buf, len);
 
825
////        SetEmptySelection(currentPos + len);
 
826
////    }
 
827
////    pdoc->EndUndoAction();
 
828
////    NotifyChange();
 
829
////    Redraw();
 
830
////
 
831
////    ShowCaretAtCurrentPosition();
 
832
////    EnsureCaretVisible();
 
833
////}
 
834
////#else
 
835
////void ScintillaWX::DoMiddleButtonUp(Point WXUNUSED(pt)) {
 
836
////}