~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to wxPython/wx/tools/XRCed/listener.py

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Name:         listener.py
 
2
# Purpose:      Listener for dispatching events from view to presenter
 
3
# Author:       Roman Rolinsky <rolinsky@femagsoft.com>
 
4
# Created:      07.06.2007
 
5
# RCS-ID:       $Id: listener.py 71790 2012-06-17 15:43:08Z ROL $
 
6
 
 
7
import wx
 
8
import os,sys,shutil,tempfile
 
9
from globals import *
 
10
from presenter import Presenter
 
11
from component import Manager
 
12
from model import Model
 
13
import view
 
14
import undo
 
15
from generate import PythonOptions
 
16
 
 
17
class _Listener:
 
18
    '''
 
19
    Installs event handlers to view objects and delegates some events
 
20
    to Presenter.
 
21
    '''
 
22
    def Install(self, frame, tree, panel, toolFrame, testWin):
 
23
        '''Set event handlers.'''
 
24
        self.frame = frame
 
25
        self.tree = tree
 
26
        self.panel = panel
 
27
        self.toolFrame = toolFrame
 
28
        self.testWin = testWin
 
29
        self.lastSearch = None
 
30
 
 
31
        self.dataElem = wx.CustomDataObject('XRCED_elem')
 
32
        self.dataNode = wx.CustomDataObject('XRCED_node')
 
33
 
 
34
        # Some local members
 
35
        self.inUpdateUI = self.inIdle = False
 
36
        self.clipboardHasData = False
 
37
        
 
38
        # Component events
 
39
        wx.EVT_MENU_RANGE(frame, Manager.firstId, Manager.lastId,
 
40
                          self.OnComponentCreate)
 
41
        wx.EVT_MENU_RANGE(frame, Manager.firstId + ID.SHIFT, Manager.lastId + ID.SHIFT,
 
42
                          self.OnComponentReplace)
 
43
 
 
44
        wx.EVT_MENU(frame, ID.REF, self.OnReference)
 
45
        wx.EVT_MENU(frame, ID.COMMENT, self.OnComment)
 
46
 
 
47
        # Other events
 
48
        frame.Bind(wx.EVT_IDLE, self.OnIdle)
 
49
        frame.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
 
50
#        frame.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
 
51
#        wx.EVT_KEY_UP(frame, tools.OnKeyUp)
 
52
#        wx.EVT_ICONIZE(frame, self.OnIconize)
 
53
 
 
54
        frame.Bind(wx.EVT_ACTIVATE, self.OnFrameActivate)
 
55
        if toolFrame:
 
56
            toolFrame.Bind(wx.EVT_ACTIVATE, self.OnFrameActivate)
 
57
        if frame.miniFrame:
 
58
            frame.miniFrame.Bind(wx.EVT_ACTIVATE, self.OnFrameActivate)
 
59
        
 
60
        # Menubar events
 
61
        # File
 
62
        frame.Bind(wx.EVT_MENU, self.OnRecentFile, id=wx.ID_FILE1, id2=wx.ID_FILE9)
 
63
        wx.EVT_MENU(frame, wx.ID_NEW, self.OnNew)
 
64
        wx.EVT_MENU(frame, wx.ID_OPEN, self.OnOpen)
 
65
        wx.EVT_MENU(frame, wx.ID_SAVE, self.OnSaveOrSaveAs)
 
66
        wx.EVT_MENU(frame, wx.ID_SAVEAS, self.OnSaveOrSaveAs)
 
67
        wx.EVT_MENU(frame, frame.ID_GENERATE_PYTHON, self.OnGeneratePython)
 
68
        wx.EVT_MENU(frame, wx.ID_PREFERENCES, self.OnPrefs)
 
69
        wx.EVT_MENU(frame, wx.ID_EXIT, self.OnExit)
 
70
        if frame.miniFrame:
 
71
            wx.EVT_MENU(frame.miniFrame, wx.ID_EXIT, self.OnExit)
 
72
 
 
73
        # Edit
 
74
        wx.EVT_MENU(frame, wx.ID_UNDO, self.OnUndo)
 
75
        wx.EVT_MENU(frame, wx.ID_REDO, self.OnRedo)
 
76
        wx.EVT_MENU(frame, wx.ID_CUT, self.OnCut)
 
77
        wx.EVT_MENU(frame, wx.ID_COPY, self.OnCopy)
 
78
        wx.EVT_MENU(frame, wx.ID_PASTE, self.OnMenuPaste)
 
79
        wx.EVT_MENU(frame, ID.PASTE, self.OnCmdPaste)
 
80
        wx.EVT_MENU(frame, ID.PASTE_SIBLING, self.OnPasteSibling)
 
81
        wx.EVT_MENU(frame, wx.ID_DELETE, self.OnDelete)
 
82
        wx.EVT_MENU(frame, frame.ID_UNSELECT, self.OnUnselect)
 
83
        wx.EVT_MENU(frame, frame.ID_TOOL_PASTE, self.OnToolPaste)
 
84
        wx.EVT_MENU(frame, wx.ID_FIND, self.OnFind)
 
85
        wx.EVT_MENU(frame, frame.ID_FINDAGAIN, self.OnFindAgain)
 
86
        wx.EVT_MENU(frame, frame.ID_LOCATE, self.OnLocate)
 
87
        wx.EVT_MENU(frame, frame.ID_TOOL_LOCATE, self.OnLocate)
 
88
        # View
 
89
        wx.EVT_MENU(frame, frame.ID_EMBED_PANEL, self.OnEmbedPanel)
 
90
        wx.EVT_MENU(frame, frame.ID_SHOW_TOOLS, self.OnShowTools)
 
91
        wx.EVT_MENU(frame, frame.ID_TEST, self.OnTest)
 
92
        wx.EVT_MENU(frame, wx.ID_REFRESH, self.OnRefresh)
 
93
        wx.EVT_MENU(frame, frame.ID_AUTO_REFRESH, self.OnAutoRefresh)
 
94
        wx.EVT_MENU(frame, frame.ID_TEST_HIDE, self.OnTestHide)
 
95
        wx.EVT_MENU(frame, frame.ID_SHOW_XML, self.OnShowXML)
 
96
        # Move
 
97
        wx.EVT_MENU(frame, frame.ID_MOVEUP, self.OnMoveUp)
 
98
        wx.EVT_MENU(frame, frame.ID_MOVEDOWN, self.OnMoveDown)
 
99
        wx.EVT_MENU(frame, frame.ID_MOVELEFT, self.OnMoveLeft)
 
100
        wx.EVT_MENU(frame, frame.ID_MOVERIGHT, self.OnMoveRight)        
 
101
        # Help
 
102
        wx.EVT_MENU(frame, wx.ID_ABOUT, self.OnHelpAbout)
 
103
        wx.EVT_MENU(frame, wx.ID_HELP_CONTENTS, self.OnHelpContents)
 
104
        wx.EVT_MENU(frame, frame.ID_README, self.OnHelpReadme)
 
105
        if get_debug():
 
106
            wx.EVT_MENU(frame, frame.ID_DEBUG_CMD, self.OnDebugCMD)
 
107
 
 
108
        # Pulldown menu commands
 
109
        wx.EVT_MENU(frame, ID.SUBCLASS, self.OnSubclass)
 
110
        wx.EVT_MENU(frame, ID.COLLAPSE, self.OnCollapse)
 
111
        wx.EVT_MENU(frame, ID.COLLAPSE_ALL, self.OnCollapseAll)
 
112
        wx.EVT_MENU(frame, ID.EXPAND, self.OnExpand)
 
113
 
 
114
        # Update events
 
115
        wx.EVT_UPDATE_UI(frame, wx.ID_SAVE, self.OnUpdateUI)
 
116
        wx.EVT_UPDATE_UI(frame, wx.ID_CUT, self.OnUpdateUI)
 
117
        wx.EVT_UPDATE_UI(frame, wx.ID_COPY, self.OnUpdateUI)
 
118
        wx.EVT_UPDATE_UI(frame, wx.ID_PASTE, self.OnUpdateUI)
 
119
        wx.EVT_UPDATE_UI(frame, wx.ID_DELETE, self.OnUpdateUI)
 
120
        wx.EVT_UPDATE_UI(frame, frame.ID_LOCATE, self.OnUpdateUI)
 
121
        wx.EVT_UPDATE_UI(frame, frame.ID_FINDAGAIN, self.OnUpdateUI)
 
122
        wx.EVT_UPDATE_UI(frame, frame.ID_TOOL_LOCATE, self.OnUpdateUI)
 
123
        wx.EVT_UPDATE_UI(frame, frame.ID_TOOL_PASTE, self.OnUpdateUI)
 
124
        wx.EVT_UPDATE_UI(frame, wx.ID_UNDO, self.OnUpdateUI)
 
125
        wx.EVT_UPDATE_UI(frame, wx.ID_REDO, self.OnUpdateUI)
 
126
        wx.EVT_UPDATE_UI(frame, frame.ID_TEST, self.OnUpdateUI)
 
127
        wx.EVT_UPDATE_UI(frame, frame.ID_MOVEUP, self.OnUpdateUI)
 
128
        wx.EVT_UPDATE_UI(frame, frame.ID_MOVEDOWN, self.OnUpdateUI)
 
129
        wx.EVT_UPDATE_UI(frame, frame.ID_MOVELEFT, self.OnUpdateUI)
 
130
        wx.EVT_UPDATE_UI(frame, frame.ID_MOVERIGHT, self.OnUpdateUI)
 
131
        wx.EVT_UPDATE_UI(frame, wx.ID_REFRESH, self.OnUpdateUI)
 
132
        wx.EVT_UPDATE_UI(frame, frame.ID_SHOW_XML, self.OnUpdateUI)
 
133
        wx.EVT_UPDATE_UI(frame, ID.COLLAPSE, self.OnUpdateUI)
 
134
        wx.EVT_UPDATE_UI(frame, ID.EXPAND, self.OnUpdateUI)
 
135
        wx.EVT_UPDATE_UI(frame, ID.SUBCLASS, self.OnUpdateUI)
 
136
 
 
137
        wx.EVT_MENU_HIGHLIGHT_ALL(self.frame, self.OnMenuHighlight)
 
138
 
 
139
        # XMLTree events
 
140
        tree.Bind(wx.EVT_LEFT_DOWN, self.OnTreeLeftDown)
 
141
        tree.Bind(wx.EVT_RIGHT_DOWN, self.OnTreeRightDown)
 
142
        tree.Bind(wx.EVT_TREE_SEL_CHANGING, self.OnTreeSelChanging)
 
143
        tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTreeSelChanged)
 
144
        tree.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnTreeItemCollapsed)
 
145
 
 
146
        # AttributePanel events
 
147
        panel.nb.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGING, self.OnPanelPageChanging)
 
148
        panel.nb.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPanelPageChanged)
 
149
        panel.pinButton.Bind(wx.EVT_BUTTON, self.OnPanelTogglePin)
 
150
 
 
151
        # Make important keys work when focus is in the panel frame
 
152
        self.accels = wx.AcceleratorTable([
 
153
            (wx.ACCEL_NORMAL, wx.WXK_F5, frame.ID_TEST),
 
154
            (wx.ACCEL_NORMAL, wx.WXK_F6, frame.ID_TEST_HIDE),
 
155
            (wx.ACCEL_CTRL, ord('r'), wx.ID_REFRESH),
 
156
            ])
 
157
        if frame.miniFrame:
 
158
            self.frame.miniFrame.SetAcceleratorTable(self.accels)
 
159
            # Propagate all menu commands to the frame
 
160
            self.frame.miniFrame.Bind(wx.EVT_MENU, lambda evt: frame.ProcessEvent(evt))
 
161
 
 
162
        # Tool panel events
 
163
        toolPanel = g.toolPanel
 
164
        toolPanel.tp.Bind(wx.EVT_TOOLBOOK_PAGE_CHANGED, self.OnToolPanelPageChanged)
 
165
        wx.EVT_COMMAND_RANGE(toolPanel.tp, Manager.firstId, Manager.lastId,
 
166
                             wx.wxEVT_COMMAND_BUTTON_CLICKED,
 
167
                             self.OnComponentTool)
 
168
        if toolFrame:
 
169
            toolFrame.Bind(wx.EVT_CLOSE, self.OnCloseToolFrame)
 
170
 
 
171
    def InstallTestWinEvents(self):
 
172
        self.idleAfterSizeBound = False
 
173
        frame = self.testWin.GetFrame()
 
174
        frame.Bind(wx.EVT_CLOSE, self.OnCloseTestWin)
 
175
        frame.Bind(wx.EVT_SIZE, self.OnSizeTestWin)
 
176
        frame.SetAcceleratorTable(self.accels)
 
177
        frame.Bind(wx.EVT_MENU, self.OnTestWinEvent)
 
178
        frame.Bind(wx.EVT_BUTTON, self.OnTestWinEvent)
 
179
 
 
180
    def OnTestWinEvent(self, evt):
 
181
        TRACE('Test window event: %s', evt)
 
182
 
 
183
    def Uninstall(self):
 
184
        '''Unbind some event before destroying.'''
 
185
        self.frame.Unbind(wx.EVT_IDLE)
 
186
 
 
187
    def OnComponentCreate(self, evt):
 
188
        '''Hadnler for creating new elements.'''
 
189
        state = self.tree.GetFullState() # state just before
 
190
        comp = Manager.findById(evt.GetId())
 
191
        if comp.groups[0] == 'component':
 
192
            node = Model.createComponentNode('Component')
 
193
            item = Presenter.create(comp, node)
 
194
        else:
 
195
            item = Presenter.create(comp)
 
196
        itemIndex = self.tree.ItemFullIndex(item)
 
197
        g.undoMan.RegisterUndo(undo.UndoPasteCreate(itemIndex, state))
 
198
 
 
199
    def OnComponentReplace(self, evt):
 
200
        '''Hadnler for creating new elements.'''
 
201
        comp = Manager.findById(evt.GetId() - ID.SHIFT)
 
202
        item = self.tree.GetSelection()
 
203
        index = self.tree.ItemFullIndex(item)
 
204
        oldComp = Presenter.comp
 
205
        oldNode = Presenter.replace(comp)
 
206
        g.undoMan.RegisterUndo(undo.UndoReplace(index, oldComp, oldNode))
 
207
 
 
208
    def OnReference(self, evt):
 
209
        '''Create reference to an existing object.'''
 
210
        ref = wx.GetTextFromUser('Create reference to:', 'Create reference')
 
211
        if not ref: return
 
212
        Presenter.createRef(ref)
 
213
 
 
214
    def OnComment(self, evt):
 
215
        '''Create comment node.'''
 
216
        Presenter.createComment()
 
217
 
 
218
    def OnNew(self, evt):
 
219
        '''wx.ID_NEW hadndler.'''
 
220
        if not self.AskSave(): return
 
221
        if self.testWin.IsShown(): self.testWin.Destroy()
 
222
        Presenter.init()
 
223
 
 
224
    def OnOpen(self, evt):
 
225
        '''wx.ID_OPEN handler.'''
 
226
        if not self.AskSave(): return
 
227
        exts = 'XRC files (*.xrc)|*.xrc'
 
228
        if g.useMeta: exts += '|CRX files (*.crx)|*.crx'
 
229
        dlg = wx.FileDialog(self.frame, 'Open', os.path.dirname(Presenter.path),
 
230
                            '', exts, wx.OPEN | wx.CHANGE_DIR)
 
231
        if dlg.ShowModal() == wx.ID_OK:
 
232
            if self.testWin.IsShown(): self.testWin.Destroy()
 
233
            # Clear old undo data
 
234
            g.undoMan.Clear()
 
235
            path = dlg.GetPath()
 
236
            wx.BeginBusyCursor()
 
237
            try:
 
238
                Presenter.open(path)
 
239
                self.frame.SetStatusText('Data loaded')
 
240
                self.SaveRecent(path)
 
241
            finally:
 
242
                wx.EndBusyCursor()
 
243
        dlg.Destroy()
 
244
 
 
245
    def OnRecentFile(self, evt):
 
246
        '''wx.ID_FILE<n> handler.'''
 
247
        if not self.AskSave(): return
 
248
 
 
249
        # get the pathname based on the menu ID
 
250
        fileNum = evt.GetId() - wx.ID_FILE1
 
251
        path = g.fileHistory.GetHistoryFile(fileNum)
 
252
            
 
253
        wx.BeginBusyCursor()
 
254
        try:
 
255
            if self.testWin.IsShown(): self.testWin.Destroy()
 
256
            Presenter.open(path)
 
257
            self.frame.SetStatusText('Data loaded')
 
258
            # add it back to the history so it will be moved up the list
 
259
            self.SaveRecent(path)
 
260
        finally:
 
261
            wx.EndBusyCursor()
 
262
 
 
263
    def OnSaveOrSaveAs(self, evt):
 
264
        '''wx.ID_SAVE and wx.ID_SAVEAS handler'''
 
265
        path = Presenter.path
 
266
        if evt.GetId() == wx.ID_SAVEAS or not path:
 
267
            dirname = os.path.abspath(os.path.dirname(path))
 
268
            exts = 'XRC files (*.xrc)|*.xrc'
 
269
            if g.useMeta: exts += '|CRX files (*.crx)|*.crx'
 
270
            dlg = wx.FileDialog(self.frame, 'Save As', dirname, '', exts,
 
271
                               wx.SAVE | wx.OVERWRITE_PROMPT | wx.CHANGE_DIR)
 
272
            if dlg.ShowModal() == wx.ID_OK:
 
273
                path = dlg.GetPath()
 
274
                if isinstance(path, unicode):
 
275
                    path = path.encode(sys.getfilesystemencoding())
 
276
                if not os.path.splitext(path)[1]:
 
277
                    if g.useMeta:
 
278
                        path += '.crx'
 
279
                    else:
 
280
                        path += '.xrc'
 
281
                dlg.Destroy()
 
282
            else:
 
283
                dlg.Destroy()
 
284
                return
 
285
 
 
286
        if g.conf.localconf:
 
287
            # if we already have a localconf then it needs to be
 
288
            # copied to a new config with the new name
 
289
            lc = g.conf.localconf
 
290
            nc = Presenter.createLocalConf(path)
 
291
            flag, key, idx = lc.GetFirstEntry()
 
292
            while flag:
 
293
                nc.Write(key, lc.Read(key))
 
294
                flag, key, idx = lc.GetNextEntry(idx)
 
295
            g.conf.localconf = nc
 
296
        else:
 
297
            # otherwise create a new one
 
298
            g.conf.localconf = Presenter.createLocalConf(path)
 
299
        wx.BeginBusyCursor()
 
300
        try:
 
301
            Presenter.save(path) # save temporary file first
 
302
            if g.conf.localconf.ReadBool("autogenerate", False):
 
303
                pypath = g.conf.localconf.Read("filename")
 
304
                embed = g.conf.localconf.ReadBool("embedResource", False)
 
305
                genGettext = g.conf.localconf.ReadBool("genGettext", False)
 
306
                Presenter.generatePython(path, pypath, embed, genGettext)
 
307
            self.frame.SetStatusText('Data saved')
 
308
            self.SaveRecent(path)
 
309
        finally:
 
310
            wx.EndBusyCursor()        
 
311
 
 
312
    def OnPrefs(self, evt):
 
313
        self.frame.ShowPrefs()
 
314
 
 
315
    def OnExit(self, evt):
 
316
        '''wx.ID_EXIT handler'''
 
317
        self.frame.Close()
 
318
        
 
319
    def OnGeneratePython(self, evt):
 
320
        if Presenter.modified or not g.conf.localconf:
 
321
            wx.MessageBox("Save the XRC file first!", "Error")
 
322
            return
 
323
        
 
324
        dlg = PythonOptions(view.frame, g.conf.localconf, Presenter.path)
 
325
        dlg.ShowModal()
 
326
        dlg.Destroy()
 
327
        
 
328
    def SaveRecent(self, path):
 
329
        '''Append path to recently used files.'''
 
330
        g.fileHistory.AddFileToHistory(path)
 
331
 
 
332
    def AskSave(self):
 
333
        '''Show confirmation dialog.'''
 
334
        if not Presenter.modified: return True
 
335
        flags = wx.ICON_EXCLAMATION | wx.YES_NO | wx.CANCEL | wx.CENTRE
 
336
        dlg = wx.MessageDialog(self.frame, 'File is modified. Save before exit?',
 
337
                               'Save before too late?', flags)
 
338
        say = dlg.ShowModal()
 
339
        dlg.Destroy()
 
340
        wx.Yield()
 
341
        if say == wx.ID_YES:
 
342
            self.OnSaveOrSaveAs(wx.CommandEvent(wx.EVT_MENU.typeId, wx.ID_SAVE))
 
343
            # If save was successful, modified flag is unset
 
344
            if not Presenter.modified: return True
 
345
        elif say == wx.ID_NO:
 
346
            Presenter.setModified(False)
 
347
            return True
 
348
        return False
 
349
 
 
350
    def OnCloseWindow(self, evt):
 
351
        '''wx.EVT_CLOSE handler'''
 
352
        if not self.AskSave(): return
 
353
        if self.testWin.object: self.testWin.Destroy()
 
354
        self.panel.undo = False # prevent undo
 
355
        g.undoMan.Clear()        
 
356
        # Remember sizes and position
 
357
        conf = g.conf
 
358
        if g.useAUI:
 
359
            conf.perspective = view.frame.mgr.SavePerspective()
 
360
        if not self.frame.IsIconized():
 
361
            conf.pos = self.frame.GetPosition()
 
362
            if wx.Platform == '__WXMAC__':
 
363
                conf.size = self.frame.GetClientSize()
 
364
            else:
 
365
                conf.size = self.frame.GetSize()
 
366
            if not g.useAUI:
 
367
                if conf.embedPanel:
 
368
                    conf.sashPos = self.frame.splitter.GetSashPosition()
 
369
                else:
 
370
                    if self.frame.miniFrame:
 
371
                        conf.panelPos = self.frame.miniFrame.GetPosition()
 
372
                        conf.panelSize = self.frame.miniFrame.GetSize()
 
373
                if conf.showToolPanel and self.toolFrame:
 
374
                    conf.toolPanelPos = self.toolFrame.GetPosition()
 
375
                    conf.toolPanelSize = self.toolFrame.GetSize()
 
376
        #self.tree.UnselectAll()
 
377
        g.undoMan.Clear()
 
378
        #self.panel.Destroy()            # destroy panel before tree
 
379
        self.Uninstall()
 
380
        self.frame.Destroy()
 
381
 
 
382
    def OnUndo(self, evt):
 
383
        if g.undoMan.CanUndo():
 
384
            g.undoMan.Undo()
 
385
 
 
386
    def OnRedo(self, evt):
 
387
        if g.undoMan.CanRedo():
 
388
            g.undoMan.Redo()
 
389
 
 
390
    def OnCut(self, evt):
 
391
        '''wx.ID_CUT handler.'''
 
392
        item = self.tree.GetSelection()
 
393
        index = self.tree.ItemFullIndex(item)
 
394
        state = self.tree.GetFullState()        
 
395
        node = Presenter.cut()
 
396
        g.undoMan.RegisterUndo(undo.UndoCutDelete(index, state, node))
 
397
 
 
398
    def OnDelete(self, evt):
 
399
        '''wx.ID_DELETE handler.'''
 
400
        if len(self.tree.GetSelections()) == 1:
 
401
            item = self.tree.GetSelection()
 
402
            index = self.tree.ItemFullIndex(item)
 
403
            state = self.tree.GetFullState()
 
404
            node = Presenter.delete(self.tree.GetSelection())
 
405
            g.undoMan.RegisterUndo(undo.UndoCutDelete(index, state, node))
 
406
        else:
 
407
            # Save all if multiselection
 
408
            g.undoMan.RegisterUndo(undo.UndoGlobal())
 
409
            Presenter.deleteMany(self.tree.GetSelections())
 
410
 
 
411
    def OnCopy(self, evt):
 
412
        '''wx.ID_COPY handler.'''
 
413
        Presenter.copy()
 
414
 
 
415
    def OnMenuPaste(self, evt):
 
416
        '''wx.ID_PASTE handler (for XMLTreeMenu).'''
 
417
        state = self.tree.GetFullState() # state just before
 
418
        item = Presenter.paste()
 
419
        if not item: return     # error in paste()
 
420
        itemIndex = self.tree.ItemFullIndex(item)
 
421
        g.undoMan.RegisterUndo(undo.UndoPasteCreate(itemIndex, state))
 
422
 
 
423
    def OnCmdPaste(self, evt):
 
424
        '''ID.PASTE handler (for Edit menu and shortcuts).'''
 
425
        TRACE('OnCmdPaste')
 
426
        state = wx.GetMouseState()
 
427
        forceSibling = state.AltDown()
 
428
        forceInsert = state.ShiftDown()
 
429
        g.Presenter.updateCreateState(forceSibling, forceInsert)
 
430
        state = self.tree.GetFullState() # state just before
 
431
        item = Presenter.paste()
 
432
        if not item: return     # error in paste()
 
433
        itemIndex = self.tree.ItemFullIndex(item)
 
434
        g.undoMan.RegisterUndo(undo.UndoPasteCreate(itemIndex, state))
 
435
 
 
436
    def OnToolPaste(self, evt):
 
437
        '''frame.ID_TOOL_PASTE handler.'''
 
438
        state = wx.GetMouseState()
 
439
        # Ctrl+click does not work with tools on Mac, Alt+click often
 
440
        # bound to window move on wxGTK
 
441
        if wx.Platform == '__WXMAC__':
 
442
            forceSibling = state.AltDown()
 
443
        else:
 
444
            forceSibling = state.ControlDown()
 
445
        forceInsert = state.ShiftDown()
 
446
        g.Presenter.updateCreateState(forceSibling, forceInsert)
 
447
        treeState = self.tree.GetFullState() # state just before
 
448
        item = Presenter.paste()
 
449
        if not item: return     # error in paste()
 
450
        itemIndex = self.tree.ItemFullIndex(item)
 
451
        g.undoMan.RegisterUndo(undo.UndoPasteCreate(itemIndex, treeState)) 
 
452
 
 
453
    def OnPasteSibling(self, evt):
 
454
        '''ID.PASTE_SIBLING handler.'''
 
455
        forceSibling = True
 
456
        state = wx.GetMouseState()
 
457
        forceInsert = state.ShiftDown()
 
458
        g.Presenter.updateCreateState(forceSibling, forceInsert)
 
459
        treeState = self.tree.GetFullState() # state just before
 
460
        item = Presenter.paste()
 
461
        itemIndex = self.tree.ItemFullIndex(item)
 
462
        g.undoMan.RegisterUndo(undo.UndoPasteCreate(itemIndex, treeState))
 
463
 
 
464
    def OnUnselect(self, evt):
 
465
        self.tree.UnselectAll()
 
466
        if not Presenter.applied: Presenter.update()
 
467
        Presenter.setData(self.tree.root)
 
468
 
 
469
    def OnMoveUp(self, evt):
 
470
        self.inIdle = True
 
471
        g.undoMan.RegisterUndo(undo.UndoGlobal())
 
472
        Presenter.moveUp()
 
473
        self.inIdle = False
 
474
 
 
475
    def OnMoveDown(self, evt):
 
476
        self.inIdle = True
 
477
        g.undoMan.RegisterUndo(undo.UndoGlobal()) 
 
478
        Presenter.moveDown()
 
479
        self.inIdle = False
 
480
    
 
481
    def OnMoveLeft(self, evt):
 
482
        self.inIdle = True
 
483
        g.undoMan.RegisterUndo(undo.UndoGlobal()) 
 
484
        Presenter.moveLeft()
 
485
        self.inIdle = False
 
486
 
 
487
    def OnMoveRight(self, evt):
 
488
        self.inIdle = True
 
489
        g.undoMan.RegisterUndo(undo.UndoGlobal()) 
 
490
        Presenter.moveRight()
 
491
        self.inIdle = False
 
492
 
 
493
    def OnFind(self, evt):
 
494
        name = wx.GetTextFromUser('Find name:', caption='Find')
 
495
        if not name: return
 
496
        self.lastSearch = name
 
497
        self.frame.SetStatusText('Looking for "%s"' % name)
 
498
        if Presenter.item == self.tree.root:
 
499
            item = self.tree.Find(self.tree.root, name)
 
500
        else:
 
501
            # Find from current position
 
502
            item = Presenter.item
 
503
            while item:
 
504
                found = self.tree.Find(item, name)
 
505
                if found: 
 
506
                    item = found
 
507
                    break
 
508
                # Search the rest of the current subtree, then go up
 
509
                next = self.tree.GetNextSibling(item)
 
510
                while not next:
 
511
                    next = self.tree.GetItemParent(item)
 
512
                    if next == self.tree.root:
 
513
                        next = None
 
514
                        break
 
515
                    item = next
 
516
                    next = self.tree.GetNextSibling(next)
 
517
                item = next
 
518
            if not item: 
 
519
                ask = wx.MessageBox('Search failed. Search from the root?', 
 
520
                                    'Question', wx.YES_NO)
 
521
                if ask == wx.YES:
 
522
                    item = self.tree.Find(self.tree.root, name)
 
523
                else:
 
524
                    self.frame.SetStatusText('')
 
525
                    return
 
526
        if not item: 
 
527
            self.frame.SetStatusText('Search failed')
 
528
            wx.LogError('No such name')
 
529
            return
 
530
        self.frame.SetStatusText('Search succeded')
 
531
        Presenter.unselect()
 
532
        self.tree.EnsureVisible(item)
 
533
        self.tree.SelectItem(item)        
 
534
 
 
535
    def OnFindAgain(self, evt):
 
536
        self.frame.SetStatusText('Looking for "%s"' % self.lastSearch)
 
537
        if Presenter.item == self.tree.root:
 
538
            item = self.tree.Find(self.tree.root, self.lastSearch)
 
539
        else:
 
540
            # Find from current position
 
541
            item = Presenter.item        
 
542
            while item:
 
543
                # Search the rest of the current subtree, then go up
 
544
                next = self.tree.GetNextSibling(item)
 
545
                while not next:
 
546
                    next = self.tree.GetItemParent(item)
 
547
                    if next == self.tree.root:
 
548
                        next = None
 
549
                        break
 
550
                    item = next
 
551
                    next = self.tree.GetNextSibling(next)
 
552
                item = next
 
553
                if item:
 
554
                    found = self.tree.Find(item, self.lastSearch)
 
555
                    if found: 
 
556
                        item = found
 
557
                        break
 
558
            if not item: 
 
559
                ask = wx.MessageBox('Search failed. Search from the root?', 
 
560
                                    'Question', wx.YES_NO)
 
561
                if ask == wx.YES:
 
562
                    item = self.tree.Find(self.tree.root, name)
 
563
                    if not item: 
 
564
                        self.frame.SetStatusText('Search failed')
 
565
                        wx.LogError('Search from the root failed.')
 
566
                        return
 
567
                else:
 
568
                    self.frame.SetStatusText('')
 
569
                    return
 
570
        self.lastFoundItem = item
 
571
        self.frame.SetStatusText('Search succeded')
 
572
        Presenter.unselect()
 
573
        self.tree.EnsureVisible(item)
 
574
        self.tree.SelectItem(item)                
 
575
 
 
576
    def OnLocate(self, evt):
 
577
        frame = self.testWin.GetFrame()
 
578
        frame.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDownTestWin)
 
579
        frame.Bind(wx.EVT_MOUSE_CAPTURE_LOST, self.OnCaptureLostTestWin)
 
580
        frame.CaptureMouse()
 
581
        wx.SetCursor(wx.CROSS_CURSOR)
 
582
 
 
583
    def OnRefresh(self, evt):
 
584
        if self.testWin.IsShown():
 
585
            self.testWin.isDirty = True
 
586
            Presenter.refreshTestWin()
 
587
 
 
588
    def OnAutoRefresh(self, evt):
 
589
        g.conf.autoRefresh = evt.IsChecked()
 
590
        self.frame.menuBar.Check(self.frame.ID_AUTO_REFRESH, g.conf.autoRefresh)
 
591
        if g.conf.embedPanel:
 
592
            self.frame.tb.ToggleTool(self.frame.ID_AUTO_REFRESH, g.conf.autoRefresh)
 
593
        else:
 
594
            self.frame.miniFrame.tb.ToggleTool(self.frame.ID_AUTO_REFRESH, g.conf.autoRefresh)
 
595
 
 
596
    def OnHelpAbout(self, evt):
 
597
        str = '''\
 
598
XRCed version %s
 
599
 
 
600
(c) Roman Rolinsky <rollrom@users.sourceforge.net>
 
601
Homepage: http://xrced.sourceforge.net\
 
602
''' % version
 
603
        dlg = wx.MessageDialog(self.frame, str, 'About XRCed', wx.OK | wx.CENTRE)
 
604
        dlg.ShowModal()
 
605
        dlg.Destroy()
 
606
 
 
607
    def OnHelpContents(self, evt):
 
608
      self.frame.htmlCtrl.DisplayContents()
 
609
          
 
610
    def OnHelpReadme(self, evt):
 
611
        self.frame.ShowReadme()
 
612
 
 
613
    # Simple emulation of python command line
 
614
    def OnDebugCMD(self, evt):
 
615
        while 1:
 
616
            try:
 
617
                exec raw_input('C:\> ')
 
618
            except EOFError:
 
619
                print '^D'
 
620
                break
 
621
            except:
 
622
                import traceback
 
623
                (etype, value, tb) =sys.exc_info()
 
624
                tblist =traceback.extract_tb(tb)[1:]
 
625
                msg =' '.join(traceback.format_exception_only(etype, value)
 
626
                        +traceback.format_list(tblist))
 
627
                print msg
 
628
 
 
629
    def OnEmbedPanel(self, evt):
 
630
        self.frame.EmbedUnembed(evt.IsChecked())
 
631
 
 
632
    def OnShowTools(self, evt):
 
633
        conf = g.conf
 
634
        self.toolFrame.Show()
 
635
        conf.showToolPanel = True
 
636
        
 
637
    def OnTest(self, evt):
 
638
        if not Presenter.item: return
 
639
        Presenter.createTestWin(Presenter.item)
 
640
 
 
641
    # Test window events
 
642
 
 
643
    def OnCloseTestWin(self, evt):
 
644
        TRACE('OnCloseTestWin')
 
645
        Presenter.closeTestWin()
 
646
 
 
647
    def OnSizeTestWin(self, evt):
 
648
        TRACE('OnSizeTestWin')
 
649
        if view.testWin.hl and not self.idleAfterSizeBound:
 
650
            self.idleAfterSizeBound = True
 
651
            frame = self.testWin.GetFrame()
 
652
            frame.Bind(wx.EVT_IDLE, self.OnIdleAfterSize)
 
653
        evt.Skip()
 
654
 
 
655
    def OnIdleAfterSize(self, evt):
 
656
        frame = self.testWin.GetFrame()
 
657
        frame.Unbind(wx.EVT_IDLE)
 
658
        self.idleAfterSizeBound = False
 
659
        TRACE('OnIdleAfterSize')
 
660
        Presenter.highlight(Presenter.item)
 
661
 
 
662
    def OnTestHide(self, evt):
 
663
        Presenter.closeTestWin()
 
664
 
 
665
    def OnCaptureLostTestWin(self, evt):
 
666
        frame = self.testWin.GetFrame()
 
667
        wx.SetCursor(wx.NullCursor)
 
668
        frame.ReleaseMouse()
 
669
        frame.Unbind(wx.EVT_LEFT_DOWN)
 
670
        self.frame.tb.ToggleTool(view.frame.ID_TOOL_LOCATE, False)
 
671
        self.frame.miniFrame.tb.ToggleTool(view.frame.ID_TOOL_LOCATE, False)
 
672
 
 
673
    def OnLeftDownTestWin(self, evt):
 
674
        frame = self.testWin.GetFrame()
 
675
        wx.SetCursor(wx.NullCursor)
 
676
        frame.ReleaseMouse()
 
677
        frame.Unbind(wx.EVT_LEFT_DOWN)
 
678
        self.frame.tb.ToggleTool(view.frame.ID_TOOL_LOCATE, False)
 
679
        self.frame.miniFrame.tb.ToggleTool(view.frame.ID_TOOL_LOCATE, False)
 
680
 
 
681
        scrPos = view.testWin.object.ClientToScreen(evt.GetPosition())
 
682
        obj = wx.FindWindowAtPoint(scrPos)
 
683
        if not obj: return
 
684
        item = self.testWin.FindObjectItem(self.testWin.item, obj)
 
685
        if not item: return
 
686
        # If window has a sizer use it as parent
 
687
        if obj.GetSizer():
 
688
            obj = obj.GetSizer()
 
689
            item = self.testWin.FindObjectItem(self.testWin.item, obj)
 
690
        Presenter.unselect()
 
691
        self.tree.EnsureVisible(item)
 
692
        self.tree.SelectItem(item)
 
693
 
 
694
    def OnShowXML(self, evt):
 
695
        Presenter.showXML()
 
696
 
 
697
    def OnMenuHighlight(self, evt):
 
698
        menuId = evt.GetMenuId()
 
699
        if menuId != -1:
 
700
            menu = evt.GetEventObject()
 
701
            try:
 
702
                help = menu.GetHelpString(menuId)
 
703
                if menuId == wx.ID_UNDO:
 
704
                    help += ' ' + g.undoMan.GetUndoLabel()
 
705
                elif menuId == wx.ID_REDO:
 
706
                    help += ' ' + g.undoMan.GetRedoLabel()
 
707
                self.frame.SetStatusText(help)
 
708
            except:
 
709
                self.frame.SetStatusText('')
 
710
        else:
 
711
            self.frame.SetStatusText('')
 
712
 
 
713
    def OnUpdateUI(self, evt):
 
714
        if self.inUpdateUI: return          # Recursive call protection
 
715
        self.inUpdateUI = True
 
716
        container = Presenter.container
 
717
        comp = Presenter.comp
 
718
        treeNode = self.tree.GetPyData(Presenter.item)
 
719
        isComment = treeNode and treeNode.nodeType == treeNode.COMMENT_NODE
 
720
        # Wokraround for wxMSW: view.tree.GetPrevSibling crashes
 
721
        if evt.GetId() in [self.frame.ID_MOVEUP, self.frame.ID_MOVERIGHT,
 
722
                           self.frame.ID_MOVEDOWN, self.frame.ID_MOVELEFT] and \
 
723
            Presenter.item is view.tree.root:
 
724
            pass
 
725
        elif evt.GetId() in [wx.ID_CUT, wx.ID_COPY, wx.ID_DELETE]:
 
726
            evt.Enable(bool(self.tree.GetSelection()))
 
727
        elif evt.GetId() in [self.frame.ID_MOVEUP, self.frame.ID_MOVERIGHT]:
 
728
            evt.Enable(view.tree.GetPrevSibling(Presenter.item).IsOk())
 
729
        elif evt.GetId() == self.frame.ID_MOVEDOWN:
 
730
            evt.Enable(view.tree.GetNextSibling(Presenter.item).IsOk())
 
731
        elif evt.GetId() == self.frame.ID_MOVELEFT:
 
732
            evt.Enable(container is not Manager.rootComponent and \
 
733
                       view.tree.GetItemParent(Presenter.item).IsOk())
 
734
        elif evt.GetId() == wx.ID_SAVE:
 
735
            evt.Enable(Presenter.modified)
 
736
#        elif evt.GetId() in [self.frame.ID_SHOW_XML]:
 
737
#            evt.Enable(len(self.tree.GetSelections()) == 1)
 
738
        elif evt.GetId() in [wx.ID_PASTE, self.frame.ID_TOOL_PASTE]:
 
739
            evt.Enable(self.clipboardHasData)
 
740
        elif evt.GetId() in [self.frame.ID_TEST,
 
741
                             self.frame.ID_MOVEUP, self.frame.ID_MOVEDOWN,
 
742
                             self.frame.ID_MOVELEFT, self.frame.ID_MOVERIGHT]:
 
743
            evt.Enable(bool(self.tree.GetSelection()))
 
744
        elif evt.GetId() in [self.frame.ID_LOCATE, self.frame.ID_TOOL_LOCATE,
 
745
                             wx.ID_REFRESH]:
 
746
            evt.Enable(self.testWin.IsShown())
 
747
        elif evt.GetId() == self.frame.ID_FINDAGAIN:
 
748
            evt.Enable(self.lastSearch is not None)
 
749
        elif evt.GetId() == wx.ID_UNDO:  evt.Enable(g.undoMan.CanUndo())
 
750
        elif evt.GetId() == wx.ID_REDO:  evt.Enable(g.undoMan.CanRedo())
 
751
        elif evt.GetId() in [ID.COLLAPSE, ID.EXPAND]:
 
752
            evt.Enable(not self.tree.GetSelection() or
 
753
                       len(self.tree.GetSelections()) == 1 and \
 
754
                           self.tree.ItemHasChildren(self.tree.GetSelection()))
 
755
        elif evt.GetId() == ID.SUBCLASS:
 
756
            evt.Enable(not isComment)
 
757
        self.inUpdateUI = False
 
758
 
 
759
    def OnIdle(self, evt):
 
760
        if self.inIdle: return          # Recursive call protection
 
761
        self.inIdle = True
 
762
        if not Presenter.applied:
 
763
            item = self.tree.GetSelection()
 
764
            if item: Presenter.update(item)
 
765
 
 
766
        # Check clipboard
 
767
        if not wx.TheClipboard.IsOpened():
 
768
            self.clipboardHasData = False
 
769
            if wx.TheClipboard.IsSupported(self.dataElem.GetFormat()):
 
770
                self.clipboardHasData = True
 
771
            elif wx.TheClipboard.IsSupported(self.dataNode.GetFormat()):
 
772
                self.clipboardHasData = True
 
773
 
 
774
        self.inIdle = False
 
775
 
 
776
    def OnIconize(self, evt):
 
777
        conf = g.conf
 
778
        if evt.Iconized():
 
779
            conf.pos = self.frame.GetPosition()
 
780
            conf.size = self.frame.GetSize()
 
781
            if conf.embedPanel:
 
782
                conf.sashPos = self.frame.splitter.GetSashPosition()
 
783
            elif self.miniFrame:
 
784
                conf.panelPos = self.miniFrame.GetPosition()
 
785
                conf.panelSize = self.miniFrame.GetSize()
 
786
                self.miniFrame.Show(False)
 
787
        else:
 
788
            if not conf.embedPanel and self.miniFrame:
 
789
                self.miniFrame.Show(True)
 
790
        evt.Skip()
 
791
 
 
792
    def OnSubclass(self, evt):
 
793
        node = self.tree.GetPyData(Presenter.item)
 
794
        subclass = node.getAttribute('subclass')
 
795
        dlg = wx.TextEntryDialog(self.frame, 'Subclass:', defaultValue=subclass)
 
796
        if dlg.ShowModal() == wx.ID_OK:
 
797
            subclass = dlg.GetValue()
 
798
            Presenter.subclass(Presenter.item, subclass)
 
799
        dlg.Destroy()        
 
800
 
 
801
    # Expand/collapse subtree
 
802
    def OnExpand(self, evt):
 
803
        if self.tree.GetSelection(): 
 
804
            map(self.tree.ExpandAllChildren, self.tree.GetSelections())
 
805
        else: 
 
806
            self.tree.ExpandAll()
 
807
 
 
808
    def OnCollapse(self, evt):
 
809
        # Prevent multiple calls to setData
 
810
        self.tree.Unbind(wx.EVT_TREE_ITEM_COLLAPSED)
 
811
        if self.tree.GetSelection(): 
 
812
            map(self.tree.CollapseAllChildren, self.tree.GetSelections())
 
813
        else: 
 
814
            self.tree.CollapseAll()
 
815
        self.tree.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnTreeItemCollapsed)
 
816
        if not self.tree.GetSelection():
 
817
            if not Presenter.applied: Presenter.update()
 
818
            Presenter.setData(self.tree.root)
 
819
 
 
820
    def OnCollapseAll(self, evt):
 
821
        # Prevent multiple calls to setData
 
822
        self.tree.Unbind(wx.EVT_TREE_ITEM_COLLAPSED)
 
823
        self.tree.UnselectAll()
 
824
        self.tree.CollapseAll()
 
825
        self.tree.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnTreeItemCollapsed)
 
826
        if not Presenter.applied: Presenter.update()
 
827
        Presenter.setData(self.tree.root)
 
828
 
 
829
    #
 
830
    # XMLTree event handlers
 
831
    #
 
832
    
 
833
    def OnTreeLeftDown(self, evt):
 
834
        pt = evt.GetPosition();
 
835
        item, flags = self.tree.HitTest(pt)
 
836
        if flags & wx.TREE_HITTEST_NOWHERE or not item:
 
837
            # Unselecting seems to be broken on wxGTK!!!
 
838
            Presenter.unselect()
 
839
        evt.Skip()
 
840
 
 
841
    def OnTreeRightDown(self, evt):
 
842
        if wx.Platform == '__WXMAC__':
 
843
            forceSibling = evt.AltDown()
 
844
        else:
 
845
            forceSibling = evt.ControlDown()
 
846
        forceInsert = evt.ShiftDown()
 
847
        Presenter.popupMenu(forceSibling, forceInsert, evt.GetPosition())
 
848
 
 
849
    def OnTreeSelChanging(self, evt):
 
850
        #TRACE('OnTreeSelChanging: %s=>%s', evt.GetOldItem(), evt.GetItem())
 
851
        #TRACE('Selection: %s', self.tree.GetSelections())
 
852
        if not self.tree.GetSelections(): return
 
853
        # Permit multiple selection for same level only
 
854
        state = wx.GetMouseState()
 
855
        oldItem = evt.GetOldItem()
 
856
        if oldItem and (state.ShiftDown() or state.ControlDown()) and \
 
857
           self.tree.GetItemParent(oldItem) != self.tree.GetItemParent(evt.GetItem()):
 
858
            evt.Veto()
 
859
            self.frame.SetStatusText('Veto selection (not same level)')
 
860
            return
 
861
        # If panel has a pending undo, register it
 
862
        if Presenter.panelIsDirty():
 
863
            Presenter.registerUndoEdit()
 
864
        evt.Skip()
 
865
 
 
866
    def OnTreeSelChanged(self, evt):
 
867
        TRACE('OnTreeSelChanged: %s=>%s', evt.GetOldItem(), evt.GetItem())
 
868
        TRACE('Selection: %s', self.tree.GetSelections())
 
869
        # On wxMSW (at least) two selection events are generated
 
870
        if not self.tree.GetSelections(): return
 
871
        if evt.GetOldItem():
 
872
            if not Presenter.applied:
 
873
                Presenter.update(evt.GetOldItem())
 
874
            # Refresh test window after finishing
 
875
            if g.conf.autoRefresh and self.testWin.IsDirty():
 
876
                wx.CallAfter(Presenter.refreshTestWin)
 
877
        # Tell presenter to update current data and view
 
878
        item = evt.GetItem()
 
879
        if not item: item = self.tree.root
 
880
        wx.CallAfter(Presenter.setData, item)
 
881
        # Set initial sibling/insert modes
 
882
        Presenter.createSibling = not Presenter.comp.isContainer()
 
883
        Presenter.insertBefore = False
 
884
        evt.Skip()
 
885
 
 
886
    def OnTreeItemCollapsed(self, evt):
 
887
        # If no selection, reset panel
 
888
        if not self.tree.GetSelection():
 
889
            if not Presenter.applied: Presenter.update()
 
890
            Presenter.setData(self.tree.root)
 
891
        evt.Skip()
 
892
 
 
893
    def OnPanelPageChanging(self, evt):
 
894
        TRACE('OnPanelPageChanging: %d=>%d', evt.GetOldSelection(), evt.GetSelection())
 
895
        # Register undo if something was changed
 
896
        i = evt.GetOldSelection()
 
897
        if i >= 0 and Presenter.panelIsDirty():
 
898
            g.undoMan.RegisterUndo(self.panel.undo)
 
899
        evt.Skip()
 
900
 
 
901
    def OnPanelPageChanged(self, evt):
 
902
        TRACE('OnPanelPageChanged: %d=>%d', evt.GetOldSelection(), evt.GetSelection())
 
903
        # Register new undo 
 
904
        if Presenter.panelIsDirty():
 
905
            Presenter.createUndoEdit(page=evt.GetSelection())
 
906
        # Refresh test window after finishing
 
907
        if g.conf.autoRefresh and self.testWin.IsDirty():
 
908
            wx.CallAfter(Presenter.refreshTestWin)
 
909
        evt.Skip()
 
910
 
 
911
    def OnPanelTogglePin(self, evt):
 
912
        g.conf.panelPinState = evt.GetIsDown()
 
913
        evt.Skip()
 
914
 
 
915
    # Tool panel
 
916
 
 
917
    def OnToolPanelPageChanged(self, evt):
 
918
        TRACE('OnToolPanelPageChanged: %d > %d', evt.GetOldSelection(), evt.GetSelection())
 
919
        # Update tool frame (if exists)
 
920
        panel = g.toolPanel.panels[evt.GetSelection()]
 
921
        if self.toolFrame:
 
922
            self.toolFrame.SetTitle(panel.name)
 
923
        evt.Skip()
 
924
 
 
925
    def OnComponentTool(self, evt):
 
926
        '''Hadnler for creating new elements.'''
 
927
        comp = Manager.findById(evt.GetId())
 
928
        # Check compatibility
 
929
        if Presenter.checkCompatibility(comp):
 
930
            state = self.tree.GetFullState() # state just before
 
931
            if comp.groups[0] == 'component':
 
932
                node = Model.createComponentNode('Component')
 
933
                item = Presenter.create(comp, node)
 
934
            else:
 
935
                item = Presenter.create(comp)
 
936
            itemIndex = self.tree.ItemFullIndex(item)
 
937
            g.undoMan.RegisterUndo(undo.UndoPasteCreate(itemIndex, state))
 
938
        evt.Skip()
 
939
 
 
940
    def OnCloseToolFrame(self, evt):
 
941
        '''wx.EVT_CLOSE handler'''
 
942
        conf = g.conf
 
943
        if not self.toolFrame.IsIconized():
 
944
            if conf.showToolPanel:
 
945
                conf.toolPanelPos = self.toolFrame.GetPosition()
 
946
                conf.toolPanelSize = self.toolFrame.GetSize()
 
947
        self.toolFrame.Show(False)
 
948
        conf.showToolPanel = False
 
949
 
 
950
    def OnFrameActivate(self, evt):
 
951
        if evt.GetActive():
 
952
            TRACE('Setting active frame')
 
953
            g.lastActiveFrame = evt.GetEventObject()
 
954
        evt.Skip()
 
955
 
 
956
        
 
957
# Singleton class
 
958
Listener = g.Listener = _Listener()