Source code for camelot.view.controls.navpane2
# ============================================================================
#
# Copyright (C) 2007-2011 Conceptive Engineering bvba. All rights reserved.
# www.conceptive.be / project-camelot@conceptive.be
#
# This file is part of the Camelot Library.
#
# This file may be used under the terms of the GNU General Public
# License version 2.0 as published by the Free Software Foundation
# and appearing in the file license.txt included in the packaging of
# this file. Please review this information to ensure GNU
# General Public Licensing requirements will be met.
#
# If you are unsure which license is appropriate for your use, please
# visit www.python-camelot.com or contact project-camelot@conceptive.be
#
# This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
# WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
# For use of this library in commercial applications, please contact
# project-camelot@conceptive.be
#
# ============================================================================
"""left navigation pane"""
import logging
logger = logging.getLogger('camelot.view.controls.navpane2')
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import Qt
from PyQt4.QtGui import QMenu
from PyQt4.QtGui import QFrame
from PyQt4.QtGui import QWidget
from PyQt4.QtGui import QToolBox
from PyQt4.QtGui import QDockWidget
from PyQt4.QtGui import QVBoxLayout
from camelot.admin.action.application_action import ApplicationActionGuiContext
from camelot.core.utils import variant_to_pyobject
from camelot.view.model_thread import post
from camelot.view.controls.modeltree import ModelItem
from camelot.view.controls.modeltree import ModelTree
[docs]class PaneSection(QWidget):
def __init__(self, parent, section, workspace):
super(PaneSection, self).__init__(parent)
self._items = []
self._workspace = workspace
self._section = section
layout = QVBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
section_tree = ModelTree(parent=self)
# i hate the sunken frame style
section_tree.setFrameShape(QFrame.NoFrame)
section_tree.setFrameShadow(QFrame.Plain)
section_tree.contextmenu = QMenu(self)
section_tree.setContextMenuPolicy(Qt.CustomContextMenu)
section_tree.customContextMenuRequested.connect(self.create_context_menu)
section_tree.setObjectName( 'SectionTree' )
section_tree.itemClicked.connect( self._item_clicked )
section_tree.setWordWrap( False )
layout.addWidget( section_tree )
self.setLayout(layout)
post( section.get_items, self.set_items )
@QtCore.pyqtSlot(object)
[docs] def set_items(self, items):
logger.debug('setting items for current navpane section')
section_tree = self.findChild(QtGui.QWidget, 'SectionTree')
self._items = items
if section_tree:
section_tree.clear()
section_tree.clear_model_items()
if not items: return
for item in items:
label = item.get_verbose_name()
icon = item.get_icon()
model_item = ModelItem( section_tree,
[unicode(label)],
item )
if icon:
model_item.set_icon(icon.getQIcon())
section_tree.modelitems.append( model_item )
section_tree.resizeColumnToContents( 0 )
@QtCore.pyqtSlot(bool)
def _action_triggered( self, _checked ):
action = self.sender()
mode_name = variant_to_pyobject( action.data() )
self._run_current_action( mode_name )
@QtCore.pyqtSlot(QtGui.QTreeWidgetItem, int)
def _item_clicked(self, _item, _column):
self._run_current_action()
def _run_current_action( self, mode_name=None ):
section_tree = self.findChild(QtGui.QWidget, 'SectionTree')
if section_tree:
item = section_tree.currentItem()
index = section_tree.indexFromItem(item)
section_item = self._items[index.row()]
gui_context = ApplicationActionGuiContext()
gui_context.mode_name = mode_name
gui_context.workspace = self._workspace
gui_context.admin = self._section.admin
section_item.get_action().gui_run( gui_context )
[docs]class NavigationPane(QDockWidget):
def __init__(self, app_admin, workspace, parent):
super(NavigationPane, self).__init__(parent)
self._workspace = workspace
self.app_admin = app_admin
tb = QToolBox()
tb.setFrameShape(QFrame.NoFrame)
tb.layout().setContentsMargins(0,0,0,0)
tb.layout().setSpacing(1)
tb.setObjectName('toolbox')
tb.setMouseTracking(True)
# hack for removing the dock title bar
self.setTitleBarWidget(QWidget())
self.setWidget(tb)
self.setFeatures(QDockWidget.NoDockWidgetFeatures)
self.app_admin.sections_changed_signal.connect(self.update_sections)
self.update_sections()
[docs] def wheelEvent(self, wheel_event):
steps = -1 * wheel_event.delta() / (8 * 15)
toolbox = self.findChild(QtGui.QWidget, 'toolbox')
if steps and toolbox:
current_index = toolbox.currentIndex()
toolbox.setCurrentIndex( max( 0, min( current_index + steps, toolbox.count() ) ) )
@QtCore.pyqtSlot()
[docs] def update_sections(self):
post(self.app_admin.get_sections, self.set_sections)
[docs] def get_sections(self):
return self._sections
@QtCore.pyqtSlot(object)
[docs] def set_sections(self, sections):
logger.debug('setting navpane sections')
if not sections:
self.setMaximumWidth(0)
return
toolbox = self.findChild(QtGui.QWidget, 'toolbox')
animation = QtCore.QPropertyAnimation(toolbox, 'minimumWidth', self)
animation.setDuration( 500 )
animation.setStartValue( 0 )
animation.setEndValue( 220 )
if self._workspace:
animation.finished.connect(self._workspace._background_widget.makeInteractive)
animation.start()
# performs QToolBox clean up
# QToolbox won't delete items we have to do it explicitly
count = toolbox.count()
while count:
item = toolbox.widget(count-1)
toolbox.removeItem(count-1)
item.deleteLater()
count -= 1
for section in sections:
# TODO: old navpane used translation here
name = unicode( section.get_verbose_name() )
icon = section.get_icon().getQIcon()
pwdg = PaneSection(toolbox, section, self._workspace)
toolbox.addItem(pwdg, icon, name)
toolbox.setCurrentIndex(0)
# WARNING: hardcoded width
#self._toolbox.setMinimumWidth(220)