Plugins/ViewManagerPlugins/MdiArea/MdiArea.py

changeset 0
de9c2efb9d02
child 13
1af94a91f439
equal deleted inserted replaced
-1:000000000000 0:de9c2efb9d02
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2008 - 2009 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the mdi area viewmanager class.
8 """
9
10 from PyQt4.QtCore import *
11 from PyQt4.QtGui import *
12
13 from ViewManager.ViewManager import ViewManager
14
15 import QScintilla.Editor
16
17 import UI.PixmapCache
18
19 from E4Gui.E4Action import E4Action, addActions
20
21 import Utilities
22
23 class MdiArea(QMdiArea, ViewManager):
24 """
25 Class implementing the mdi area viewmanager class.
26
27 @signal editorChanged(string) emitted when the current editor has changed
28 """
29 def __init__(self, parent):
30 """
31 Constructor
32
33 @param parent parent widget (QWidget)
34 @param ui reference to the main user interface
35 @param dbs reference to the debug server object
36 """
37 QMdiArea.__init__(self, parent)
38 ViewManager.__init__(self)
39 self.lastFN = ''
40 self.__removingView = False
41
42 self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
43 self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
44
45 self.__windowMapper = QSignalMapper(self)
46
47 self.connect(self.__windowMapper, SIGNAL('mapped(QWidget*)'),
48 self.setActiveSubWindow)
49 self.connect(self, SIGNAL('subWindowActivated(QMdiSubWindow*)'),
50 self.__subWindowActivated)
51
52 def canCascade(self):
53 """
54 Public method to signal if cascading of managed windows is available.
55
56 @return flag indicating cascading of windows is available
57 """
58 return True
59
60 def canTile(self):
61 """
62 Public method to signal if tiling of managed windows is available.
63
64 @return flag indicating tiling of windows is available
65 """
66 return True
67
68 def canSplit(self):
69 """
70 public method to signal if splitting of the view is available.
71
72 @return flag indicating splitting of the view is available.
73 """
74 return False
75
76 def tile(self):
77 """
78 Public method to tile the managed windows.
79 """
80 self.tileSubWindows()
81
82 def cascade(self):
83 """
84 Public method to cascade the managed windows.
85 """
86 self.cascadeSubWindows()
87
88 def _removeAllViews(self):
89 """
90 Protected method to remove all views (i.e. windows)
91 """
92 for win in self.editors:
93 self._removeView(win)
94
95 def _removeView(self, win):
96 """
97 Protected method to remove a view (i.e. window)
98
99 @param win editor window to be removed
100 """
101 self.__removingView = True
102 self.lastFN = ''
103 win.removeEventFilter(self)
104 self.closeActiveSubWindow()
105 win.closeIt()
106 self.__removingView = False
107
108 def _addView(self, win, fn = None, noName = ""):
109 """
110 Protected method to add a view (i.e. window)
111
112 @param win editor window to be added
113 @param fn filename of this editor
114 @param noName name to be used for an unnamed editor (string or QString)
115 """
116 self.addSubWindow(win)
117 if fn is None:
118 if not noName:
119 self.untitledCount += 1
120 noName = self.trUtf8("Untitled {0}").format(self.untitledCount)
121 win.setWindowTitle(noName)
122 win.setNoName(noName)
123 else:
124 if self.lastFN != fn:
125 self.lastFN = fn
126 win.show()
127 if win.hasSyntaxErrors():
128 self.__setSubWindowIcon(win, UI.PixmapCache.getIcon("syntaxError.png"))
129 else:
130 self.__setSubWindowIcon(win, UI.PixmapCache.getIcon("empty.png"))
131
132 # Make the editor window a little bit smaller to make the whole
133 # window with all decorations visible. This is not the most elegant
134 # solution but more of a workaround for another QWorkspace strangeness.
135 # 25 points are subtracted to give space for the scrollbars
136 pw = win.parentWidget()
137 sz = QSize(self.width() - 25, self.height() - 25)
138 pw.resize(sz)
139
140 win.setFocus()
141 win.installEventFilter(self)
142
143 def _showView(self, win, fn = None):
144 """
145 Private method to show a view (i.e. window)
146
147 @param win editor window to be shown
148 @param fn filename of this editor (string)
149 """
150 if fn is not None and self.lastFN != fn:
151 self.lastFN = fn
152 win.show()
153 win.setFocus()
154
155 def activeWindow(self):
156 """
157 Private method to return the active (i.e. current) window.
158
159 @return reference to the active editor
160 """
161 subWindow = self.activeSubWindow()
162 if subWindow is None:
163 return None
164 else:
165 return subWindow.widget()
166
167 def showWindowMenu(self, windowMenu):
168 """
169 Public method to set up the viewmanager part of the Window menu.
170
171 @param windowMenu reference to the window menu
172 """
173 self.windowsMenu = QMenu(self.trUtf8('&Windows'))
174
175 menu = self.windowsMenu
176 idx = 1
177 for subWindow in self.subWindowList():
178 sv = subWindow.widget()
179 if idx == 10:
180 menu.addSeparator()
181 menu = menu.addMenu(self.trUtf8("&More"))
182 fn = sv.fileName
183 if fn:
184 txt = Utilities.compactPath(fn, self.ui.maxMenuFilePathLen)
185 else:
186 txt = sv.windowTitle()
187 accel = ""
188 if idx < 10:
189 accel = "&%d. " % idx
190 elif idx < 36:
191 accel = "&%c. " % chr(idx - 9 + ord("@"))
192 act = menu.addAction("%s%s" % (accel, txt))
193 self.connect(act, SIGNAL("triggered()"),
194 self.__windowMapper, SLOT("map()"))
195 self.__windowMapper.setMapping(act, subWindow)
196 idx += 1
197
198 addActions(windowMenu,
199 [None, self.nextChildAct, self.prevChildAct,
200 self.tileAct, self.cascadeAct,
201 self.restoreAllAct, self.iconizeAllAct,
202 None])
203 act = windowMenu.addMenu(self.windowsMenu)
204 if len(self.editors) == 0:
205 act.setEnabled(False)
206
207 def _initWindowActions(self):
208 """
209 Protected method to define the user interface actions for window handling.
210 """
211 self.tileAct = E4Action(self.trUtf8('Tile'),
212 self.trUtf8('&Tile'), 0, 0, self, 'vm_window_tile')
213 self.tileAct.setStatusTip(self.trUtf8('Tile the windows'))
214 self.tileAct.setWhatsThis(self.trUtf8(
215 """<b>Tile the windows</b>"""
216 """<p>Rearrange and resize the windows so that they are tiled.</p>"""
217 ))
218 self.connect(self.tileAct, SIGNAL('triggered()'), self.tile)
219 self.windowActions.append(self.tileAct)
220
221 self.cascadeAct = E4Action(self.trUtf8('Cascade'),
222 self.trUtf8('&Cascade'), 0, 0, self, 'vm_window_cascade')
223 self.cascadeAct.setStatusTip(self.trUtf8('Cascade the windows'))
224 self.cascadeAct.setWhatsThis(self.trUtf8(
225 """<b>Cascade the windows</b>"""
226 """<p>Rearrange and resize the windows so that they are cascaded.</p>"""
227 ))
228 self.connect(self.cascadeAct, SIGNAL('triggered()'), self.cascade)
229 self.windowActions.append(self.cascadeAct)
230
231 self.nextChildAct = E4Action(self.trUtf8('Next'),
232 self.trUtf8('&Next'), 0, 0, self, 'vm_window_next')
233 self.nextChildAct.setStatusTip(self.trUtf8('Activate next window'))
234 self.nextChildAct.setWhatsThis(self.trUtf8(
235 """<b>Next</b>"""
236 """<p>Activate the next window of the list of open windows.</p>"""
237 ))
238 self.connect(self.nextChildAct, SIGNAL('triggered()'), self.activateNextSubWindow)
239 self.windowActions.append(self.nextChildAct)
240
241 self.prevChildAct = E4Action(self.trUtf8('Previous'),
242 self.trUtf8('&Previous'), 0, 0, self, 'vm_window_previous')
243 self.prevChildAct.setStatusTip(self.trUtf8('Activate previous window'))
244 self.prevChildAct.setWhatsThis(self.trUtf8(
245 """<b>Previous</b>"""
246 """<p>Activate the previous window of the list of open windows.</p>"""
247 ))
248 self.connect(self.prevChildAct, SIGNAL('triggered()'),
249 self.activatePreviousSubWindow)
250 self.windowActions.append(self.prevChildAct)
251
252 self.restoreAllAct = E4Action(self.trUtf8('Restore All'),
253 self.trUtf8('&Restore All'), 0, 0, self, 'vm_window_restore_all')
254 self.restoreAllAct.setStatusTip(self.trUtf8('Restore all windows'))
255 self.restoreAllAct.setWhatsThis(self.trUtf8(
256 """<b>Restore All</b>"""
257 """<p>Restores all windows to their original size.</p>"""
258 ))
259 self.connect(self.restoreAllAct, SIGNAL('triggered()'), self.__restoreAllWindows)
260 self.windowActions.append(self.restoreAllAct)
261
262 self.iconizeAllAct = E4Action(self.trUtf8('Iconize All'),
263 self.trUtf8('&Iconize All'), 0, 0, self, 'vm_window_iconize_all')
264 self.iconizeAllAct.setStatusTip(self.trUtf8('Iconize all windows'))
265 self.iconizeAllAct.setWhatsThis(self.trUtf8(
266 """<b>Iconize All</b>"""
267 """<p>Iconizes all windows.</p>"""
268 ))
269 self.connect(self.iconizeAllAct, SIGNAL('triggered()'), self.__iconizeAllWindows)
270 self.windowActions.append(self.iconizeAllAct)
271
272 def setEditorName(self, editor, newName):
273 """
274 Public method to change the displayed name of the editor.
275
276 @param editor editor window to be changed
277 @param newName new name to be shown (string or QString)
278 """
279 pass
280
281 def __setSubWindowIcon(self, widget, icon):
282 """
283 Private method to set the icon of a subwindow given it's internal widget.
284
285 @param widget reference to the internal widget (QWidget)
286 @param icon reference to the icon (QIcon)
287 """
288 for subWindow in self.subWindowList():
289 if subWindow.widget() == widget:
290 subWindow.setWindowIcon(icon)
291 return
292
293 def _modificationStatusChanged(self, m, editor):
294 """
295 Protected slot to handle the modificationStatusChanged signal.
296
297 @param m flag indicating the modification status (boolean)
298 @param editor editor window changed
299 """
300 if m:
301 self.__setSubWindowIcon(editor, UI.PixmapCache.getIcon("fileModified.png"))
302 elif editor.hasSyntaxErrors():
303 self.__setSubWindowIcon(editor, UI.PixmapCache.getIcon("syntaxError.png"))
304 else:
305 self.__setSubWindowIcon(editor, UI.PixmapCache.getIcon("empty.png"))
306 self._checkActions(editor)
307
308 def _syntaxErrorToggled(self, editor):
309 """
310 Protected slot to handle the syntaxerrorToggled signal.
311
312 @param editor editor that sent the signal
313 """
314 if editor.hasSyntaxErrors():
315 self.__setSubWindowIcon(editor, UI.PixmapCache.getIcon("syntaxError.png"))
316 else:
317 self.__setSubWindowIcon(editor, UI.PixmapCache.getIcon("empty.png"))
318
319 ViewManager._syntaxErrorToggled(self, editor)
320
321 def __subWindowActivated(self, subWindow):
322 """
323 Private slot to handle the windowActivated signal.
324
325 @param subWindow the activated subwindow (QMdiSubWindow)
326 """
327 if subWindow is not None:
328 editor = subWindow.widget()
329 self._checkActions(editor)
330 if editor is not None:
331 fn = editor.getFileName()
332 self.emit(SIGNAL('editorChanged'), fn)
333
334 def eventFilter(self, watched, event):
335 """
336 Public method called to filter the event queue.
337
338 @param watched the QObject being watched
339 @param event the event that occurred
340 @return flag indicating, whether the event was handled (boolean)
341 """
342 if event.type() == QEvent.Close and \
343 not self.__removingView and \
344 isinstance(watched, QScintilla.Editor.Editor):
345 watched.close()
346 return True
347
348 return False
349
350 def __restoreAllWindows(self):
351 """
352 Private slot to restore all windows.
353 """
354 for win in self.subWindowList():
355 win.showNormal()
356
357 def __iconizeAllWindows(self):
358 """
359 Private slot to iconize all windows.
360 """
361 for win in self.subWindowList():
362 win.showMinimized()

eric ide

mercurial