Source code for gsdview.qtwindowlistmenu

# -*- coding: utf-8 -*-

### Copyright (C) 2008-2012 Antonio Valentino <a_valentino@users.sf.net>

### This file is part of GSDView.

### GSDView is free software; you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation; either version 2 of the License, or
### (at your option) any later version.

### GSDView is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
### GNU General Public License for more details.

### You should have received a copy of the GNU General Public License
### along with GSDView; if not, write to the Free Software
### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.


'''Window Menu

Python port of the Window Wenu component from Qt Solutions.

'''


from qt import QtCore, QtGui


__author__ = 'Antonio Valentino <a_valentino@users.sf.net>'
__date__ = '$Date: 2009-09-04 20:24:24 +0200 (ven, 04 set 2009) $'
__revision__ = '$Revision: 531 $'


[docs]class QtWindowListMenu(QtGui.QMenu): '''The QtWindowListMenu class is a menu that provides navigation commands for the subwindows in a QMdiArea. It is typically used as the conventional "Windows" item in an MDI application's menubar. It provides some standard commands for arranging and closing the MDI subwindows, corresponding to the slots of QMdiArea, as well as shortcuts to navigate directly to each of them. Usage: After creation, use attachToMdiArea() to tell the QtWindowListMenu object which QMdiArea object it should provide navigation commands for. It can then be added to a QMenuBar (or other objects that can take QMenus or QActions, like QToolButton or QMenu) in the ordinary way, since QtWindowListMenu is a QMenu subclass. The subwindow navigation items may be given a common icon with setDefaultIcon(). The item icon for a specific subwindow can be set with setWindowIcon(). Customization: Additional menu items (actions) can be inserted into this menu in the ordinary way for a QMenu. The standardAction() method gives access to the standard navigation items, which can be used to change their icon, shortcut, visibility etc. Ultimately, the whole menu can be customized by overriding syncWithMdiArea() in a subclass of QtWindowListMenu. If a QtWindowListMenu is showed and opened before being attached to a QMdiArea, it will try to auto-attach itself to the closest sibling object that is or inherits QMdiArea, if any exists. This behaviour is intended for special usecases; normally you will want to explicitly specify the desired QMdiArea with attachToMdiArea(). .. seealso:: QMdiArea, QMdiSubWindow, QMenuBar, QAction The *StandardAction* enumeration specifies the standard menu items of a QtWindowListMenu. :Enum: * CloseAction * CloseAllAction * TileAction * CascadeAction * NextAction * PrevAction .. seealso:: standardAction() :SLOTS: * :meth:`syncWithMdiArea` * :meth:`activateWindow` * :meth:`windowDestroyed` ''' CloseAction = 0 CloseAllAction = 1 TileAction = 3 CascadeAction = 4 NextAction = 6 PrevAction = 7 def __init__(self, parent, **kwargs): '''Constructs a QtWindowListMenu object. The *parent* parameter is passed to the QMenu constructor. Although this parameter has the conventional default of 0, you will normally want to explicitly provide a parent object, since the later adding of this menu object to an action container (e.g. QMenuBar) does not cause a reparenting. The container is normally the natural choice for *parent*. ''' super(QtWindowListMenu, self).__init__(parent, **kwargs) self.mdi = None self.setTitle(self.tr('&Windows')) self.aboutToShow.connect(self.syncWithMdiArea) self._stdGroup = QtGui.QActionGroup(self, exclusive=False) self._winGroup = QtGui.QActionGroup(self, exclusive=True) #, triggered=self.activateWindow) # @COMPATIBILITY: with pyside 1.0.1 self._winGroup.triggered.connect(self.activateWindow) # Create the standard menu items. # @Note: Creation order must match the StandardAction enum values ;-) QtGui.QAction(self.tr('Cl&ose'), self._stdGroup, shortcut=self.tr('Ctrl+F4'), statusTip=self.tr('Close the active window')) QtGui.QAction(self.tr('Close &All'), self._stdGroup, statusTip=self.tr('Close all the windows')) act = self._stdGroup.addAction('') act.setSeparator(True) QtGui.QAction(self.tr('&Tile'), self._stdGroup, statusTip=self.tr('Tile the windows')) QtGui.QAction(self.tr('&Cascade'), self._stdGroup, statusTip=self.tr('Cascade the windows')) act = self._stdGroup.addAction('') act.setSeparator(True) QtGui.QAction(self.tr('Ne&xt'), self._stdGroup, statusTip=self.tr('Move the focus to the next window')) QtGui.QAction(self.tr('Pre&vious'), self._stdGroup, statusTip=self.tr( 'Move the focus to the previous window')) act = self._stdGroup.addAction('') act.setSeparator(True) self.addActions(self._stdGroup.actions()) self._winMap = {} # QMap<QAction *, QMdiSubWindow *> self._iconMap = {} # QMap<const QMdiSubWindow *, QIcon> self._defIcon = QtGui.QIcon()
[docs] def attachToMdiArea(self, mdiArea): '''Instructs this menu to display navigation actions for the QMdiArea *mdiArea*. This should be done before this menu is shown. Specifying a null *mdiArea* is meaningless and will generate a warning. For special usecases, see the note about auto-attachment in the class description. ''' if mdiArea == self.mdi: return acts = self._stdGroup.actions() acts = dict(zip(['CloseAction', 'CloseAllAction', '', 'TileAction', 'CascadeAction', '', 'NextAction', 'PrevAction'], acts)) if self.mdi: # i.e. we have previously been attached mdi = self.mdi acts['CloseAction'].triggered.disconnect(mdi.closeActiveSubWindow) acts['CloseAllAction'].triggered.disconnect(mdi.closeAllSubWindows) acts['TileAction'].triggered.disconnect(mdi.tileSubWindows) acts['CascadeAction'].triggered.disconnect(mdi.cascadeSubWindows) acts['NextAction'].triggered.disconnect(mdi.activateNextSubWindow) acts['PrevAction'].triggered.disconnect( mdi.activatePreviousSubWindow) self.mdi = mdiArea if not self.mdi: QtCore.qWarning('QtWindowListMenu::attachToMdiArea(): ' 'mdiArea is 0; menu will be empty.') return acts['CloseAction'].triggered.connect(self.mdi.closeActiveSubWindow) acts['CloseAllAction'].triggered.connect(self.mdi.closeAllSubWindows) acts['TileAction'].triggered.connect(self.mdi.tileSubWindows) acts['CascadeAction'].triggered.connect(self.mdi.cascadeSubWindows) acts['NextAction'].triggered.connect(self.mdi.activateNextSubWindow) acts['PrevAction'].triggered.connect( self.mdi.activatePreviousSubWindow)
[docs] def attachedMdiArea(self): '''Returns the QMdiArea this menu is currently attached to, or None if not yet attached. .. seealso:: attachToMdiArea() ''' return self.mdi
def _attachToClosestMdiAreaObject(self): '''Attach the menu to the most likely intended MDI area object Heuristic method to auto-attach to the most likely intended mdiArea object, i.e. the closest "sibling" mdiArea widget. In the typical case, there will be only one in the mainwindow that owns this menu, and this method will find it. ''' if self.mdi: return True mdi = None parent = self while not mdi: parent = parent.parentWidget() if not parent: return False if isinstance(mdi, QtGui.QMdiArea): mdi = parent else: mdi = parent.findChild(QtGui.QMdiArea) self.attachToMdiArea(mdi) return True @QtCore.Slot()
[docs] def syncWithMdiArea(self): '''Syncronize with MDI area This slot is executed immediately prior to each opening of this menu. It removes the previous subwindow navigation actions and adds new ones according to the current state of the attached QMdiArea. :C++ signature: `void syncWithMdiArea()` ''' if not self.mdi and not self._attachToClosestMdiAreaObject(): return self._stdGroup.setEnabled(len(self.mdi.subWindowList()) > 0) self._winMap.clear() for act in self._winGroup.actions(): self.removeAction(act) self._winGroup.removeAction(act) del act idx = 1 for idx, win in enumerate(self.mdi.subWindowList()): if win.isWindowModified(): modMarker = "*" else: modMarker = "" title = win.windowTitle().replace('[*]', modMarker) if idx < 8: text = '&%d %s' % (idx + 1, title) else: text = '%d %s' % (idx + 1, title) icon = self._iconMap.get(win, self._defIcon) action = QtGui.QAction(icon, text, self._winGroup, checkable=True) action.setChecked(win == self.mdi.activeSubWindow()) self._winMap[action] = win self.addActions(self._winGroup.actions())
@QtCore.Slot(QtGui.QAction)
[docs] def activateWindow(self, act): '''Activate the corresponding sub-window in the MDI area This slot is executed when the user selects one of the subwindow navigation actions, given in *act*. It causes the corresponding subwindow in the attached QMdiArea object to be activated. :C++ signature: `void activateWindow(QAction *act)`` ''' if not self.mdi and not self._attachToClosestMdiAreaObject(): return self.mdi.setActiveSubWindow(self._winMap.get(act))
@QtCore.Slot(QtCore.QObject)
[docs] def windowDestroyed(self, obj): '''This slot is executed whenever a subwindow (*obj*) of the attached QMdiArea, for which an icon has been, is deleted. It clears that icon. :C++ signature: `void windowDestroyed(QObject *obj)` ''' del self._iconMap[obj]
[docs] def setWindowIcon(self, window, icon): '''Sets *icon* as the icon of the menu item corresponding to the mdi subwindow *window*. If *icon* is a null icon, the current item icon will be cleared. .. seealso:: windowIcon() ''' if not window: return if icon is None: del self._iconMap[window] else: self._iconMap[window] = icon window.destroyed.connect(self.windowDestroyed)
[docs] def windowIcon(self, window): '''Returns the icon of the menu item corresponding to the mdi subwindow *window*. This will be a null icon if none has been explicitly set. .. seealso:: setWindowIcon() ''' #return self._iconMap.get(window) return self._iconMap[window]
[docs] def setDefaultIcon(self, icon): '''Sets *icon* as the default icon for the subwindow navigation items in this QtWindowListMenu. If *icon* is a null icon, then the default icon will be cleared. .. seealso:: defaultIcon() ''' self._defIcon = icon
[docs] def defaultIcon(self): '''Returns the default icon for the subwindow navigation items in this QtWindowListMenu. This will be a null icon if none has been explicitly set. .. seealso:: setDefaultIcon() ''' return self._defIcon
[docs] def standardAction(self, item): '''Returns a pointer to the standard navigation action of this menu specified by *item*. This can be used to customize the look, shortcut, tool tip, etc. of this item, or to provide alternative access to it through a tool button etc. The returned object is owned by this QtWindowListMenu, and must not be deleted. If you want QtWindowListMenu to not display this action, set its "visible" property to false. ''' return self._stdGroup.actions()[item]

Get GSDView at SourceForge.net. Fast, secure and Free Open Source software downloads