camelot.camelot.view.controls.navpane

Package camelot :: Package camelot :: Package view :: Package controls :: Module navpane |
[hide private]
[frames] | no frames]

# Source Code for Module camelot.camelot.view.controls.navpane

      1  #  ============================================================================
      2  #
      3  #  Copyright (C) 2007-2008 Conceptive Engineering bvba. All rights reserved.
      4  #  www.conceptive.be / project-camelot@conceptive.be
      5  #
      6  #  This file is part of the Camelot Library.
      7  #
      8  #  This file may be used under the terms of the GNU General Public
      9  #  License version 2.0 as published by the Free Software Foundation
     10  #  and appearing in the file LICENSE.GPL included in the packaging of
     11  #  this file.  Please review the following information to ensure GNU
     12  #  General Public Licensing requirements will be met:
     13  #  http://www.trolltech.com/products/qt/opensource.html
     14  #
     15  #  If you are unsure which license is appropriate for your use, please
     16  #  review the following information:
     17  #  http://www.trolltech.com/products/qt/licensing.html or contact
     18  #  project-camelot@conceptive.be.
     19  #
     20  #  This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
     21  #  WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
     22  #
     23  #  For use of this library in commercial applications, please contact
     24  #  project-camelot@conceptive.be
     25  #
     26  #  ============================================================================
     27
     28  """left navigation pane"""
     29
     30  import os
     31  import sys
     32  import logging
     33
     34  logger = logging.getLogger('camelot.view.controls.navpane')
     35
     36  from PyQt4 import QtGui
     37  from PyQt4 import QtCore
     38  from PyQt4.QtCore import Qt
     39
     40  import settings
     41  from camelot.view import art
     42  from camelot.view.model_thread import get_model_thread
     43  from camelot.view.helpers import addActions, createAction
     44  from camelot.view.controls.modeltree import ModelItem, ModelTree
     45  from appscheme import scheme, defaultUI
     46
     47  QT_MAJOR_VERSION = float('.'.join(str(QtCore.QT_VERSION_STR).split('.')[0:2]))
     48
     49  _ = lambda x:x
     50
     51
     52 -class PaneCaption(QtGui.QLabel):
     53    """Navigation pane Caption"""
     54 -  def __init__(self,
     55                 text,
     56                 textbold=True,
     57                 textindent=3,
     58                 width=160,
     59                 height=32,
     60                 objectname='PaneCaption',
     61                 parent=None):
     62
     63      super(PaneCaption, self).__init__(parent)
     64
     65      self.setText(text)
     66
     67      if textbold:
     68        self.textbold()
     69
     70      font = self.font()
     71      font.setPointSize(font.pointSize() + 2)
     72      self.setFont(font)
     73
     74      self.setIndent(textindent)
     75
     76      self.setObjectName(objectname)
     77
     78      style = """
     79      QLabel#PaneCaption {
     80        margin: 3px 0 0 3px;
     81        border: 1px solid %s;
     82        color: %s;
     83        background-color: %s;
     84      }
     85      """ % (scheme.bordercolor(),
     86             scheme.captiontextcolor(),
     87             scheme.captionbackground())
     88
     89      self.setStyleSheet(style);
     90      self.setFixedHeight(height)
     91      self.resize(width, height)
     92
     93 -  def textbold(self):
     94      font = self.font()
     95      font.setBold(True)
     96      font.setPointSize(font.pointSize() + 1)
     97      self.setFont(font)
     98
     99
    100 -class PaneButton(QtGui.QWidget):
    101    """Custom made navigation pane pushbutton"""
    102    INDEX = 0  # Keep track of the buttons
    103
    104 -  def __init__(self,
    105                 text,
    106                 buttonicon='',
    107                 textbold=True,
    108                 textleft=True,
    109                 width=160,
    110                 height=32,
    111                 objectname='PaneButton',
    112                 parent=None):
    113
    114      super(PaneButton, self).__init__(parent)
    115
    116      option = QtGui.QBoxLayout.LeftToRight if textleft \
    117                                            else QtGui.QBoxLayout.RightToLeft
    118      self.layout = QtGui.QBoxLayout(option)
    119      self.layout.setSpacing(0)
    120      self.layout.setContentsMargins(3,0,0,0)
    121
    122      if buttonicon:
    123        self.icon = QtGui.QLabel()
    124        self.icon.setPixmap(QtGui.QPixmap(buttonicon))
    125        self.layout.addWidget(self.icon)
    126
    127      self.label = QtGui.QLabel(text)
    128
    129      self.layout.addWidget(self.label, 2)
    130
    131      self.setLayout(self.layout)
    132
    133      if textbold:
    134        self.textbold()
    135
    136      self.setObjectName(objectname)
    137
    138      self.stylenormal = """
    139      QWidget#PaneButton * {
    140        margin: 0;
    141        padding-left: 3px;
    142        color : %s;
    143        border-color : %s;
    144        background-color : %s;
    145      }
    146      """ % (scheme.textcolor(),
    147             scheme.bordercolor(),
    148             scheme.normalbackground())
    149
    150      self.stylehovered = """
    151      QWidget#PaneButton * {
    152        margin: 0;
    153        padding-left: 3px;
    154        color : %s;
    155        background-color : %s;
    156      }
    157      """ % (scheme.textcolor(),
    158             scheme.hoveredbackground())
    159
    160      self.styleselected = """
    161      QWidget#PaneButton * {
    162        margin: 0;
    163        padding-left: 3px;
    164        color : %s;
    165        background-color : %s;
    166      }
    167      """ % (scheme.selectedcolor(),
    168             scheme.selectedbackground())
    169
    170      self.styleselectedover = """
    171      QWidget#PaneButton * {
    172        margin: 0;
    173        padding-left: 3px;
    174        color : %s;
    175        background-color : %s;
    176      }
    177      """ % (scheme.selectedcolor(),
    178             scheme.selectedbackground(inverted=True))
    179
    180      self.setStyleSheet(self.stylenormal)
    181      self.setFixedHeight(height)
    182      self.resize(width, height)
    183      self.selected = False
    184      self.index = PaneButton.INDEX
    185      PaneButton.INDEX += 1
    186
    187 -  def textbold(self):
    188      font = self.label.font()
    189      font.setBold(True)
    190      self.label.setFont(font)
    191
    192 -  def enterEvent(self, event):
    193      if self.selected:
    194        self.setStyleSheet(self.styleselectedover)
    195      else:
    196        self.setStyleSheet(self.stylehovered)
    197
    198 -  def leaveEvent(self, event):
    199      if self.selected:
    200        self.setStyleSheet(self.styleselected)
    201      else:
    202        self.setStyleSheet(self.stylenormal)
    203
    204 -  def mousePressEvent(self, event):
    205      if self.selected:
    206        return
    207      else:
    208        self.selected = True
    209        self.setStyleSheet(self.styleselectedover)
    210        # Python shortcut SIGNAL, any object can be passed
    211        self.emit(QtCore.SIGNAL('indexselected'),
    212                  (self.index, self.label.text()))
    213
    214
    215 -class NavigationPane(QtGui.QDockWidget):
    216    """ms office-like navigation pane in Qt"""
    217
    218 -  def __init__(self, app_admin, objectname='NavigationPane', parent=None):
    219      super(NavigationPane, self).__init__(parent)
    220      self.app_admin = app_admin
    221      self.sections = app_admin.getSections()
    222      buttons = [PaneButton(label, icon)
    223                 for (section,(label, icon)) in self.sections]
    224      self.setFeatures(QtGui.QDockWidget.NoDockWidgetFeatures)
    225
    226      self.setcontent(buttons)
    227      self.parent = parent
    228
    229      self.currentbutton = -1
    230
    231      self.caption = PaneCaption('')
    232      self.setTitleBarWidget(self.caption)
    233
    234      self.setObjectName(objectname)
    235
    236      # Tried selecting QDockWidget but it's not working
    237      # so we must undo this margin in children stylesheets :)
    238      #style = 'margin: 0 0 0 3px;'
    239      #self.setStyleSheet(style)
    240
    241 -  def setcontent(self, buttons):
    242      logger.debug('setting up pane content')
    243      self.content = QtGui.QWidget()
    244      self.content.setObjectName('NavPaneContent')
    245
    246      style = """
    247      QWidget#NavPaneContent {
    248        margin-left: 3px;
    249        background-color: %s;
    250      }
    251      """ % scheme.bordercolor()
    252
    253      self.content.setStyleSheet(style)
    254
    255      self.mt = get_model_thread()
    256      # TODO: Should a separator be added between the tree
    257      #       and the buttons?
    258      #self.treewidget = PaneTree(self)
    259      header_labels = ['']
    260      self.treewidget = ModelTree(header_labels, self)
    261      self.treewidget.setObjectName('NavPaneTree')
    262
    263      style = """
    264      QWidget#NavPaneTree {
    265        margin-left: 3px;
    266        border: 1px solid %s;
    267      }
    268      """ % scheme.bordercolor()
    269
    270      self.treewidget.setStyleSheet(style)
    271
    272      # context menu
    273      self.treewidget.contextmenu = QtGui.QMenu(self)
    274      newWindowAct = createAction(self,
    275                                  _('Open in New Window'),
    276                                  self.popWindow,
    277                                  'Ctrl+Enter')
    278
    279      addActions(self.treewidget.contextmenu, (newWindowAct,))
    280      self.treewidget.setContextMenuPolicy(Qt.CustomContextMenu)
    281      self.connect(self.treewidget,
    282                   QtCore.SIGNAL('customContextMenuRequested(const QPoint &)'),
    283                   self.createContextMenu)
    284
    285      layout = QtGui.QVBoxLayout()
    286      layout.setSpacing(1)
    287      layout.setContentsMargins(1,1,1,1)
    288      layout.addWidget(self.treewidget)
    289
    290      if buttons:
    291        for b in buttons:
    292          layout.addWidget(b)
    293          self.connect(b, QtCore.SIGNAL('indexselected'), self.change_current)
    294        self.buttons = buttons
    295
    296      self.content.setLayout(layout)
    297      self.setWidget(self.content)
    298
    299 -  def set_models_in_tree(self, models):
    300      self.treewidget.clear()
    301      self.models = models
    302      #self.treeitems = []
    303
    304      if not models:
    305        return
    306
    307      self.treewidget.clear_model_items()
    308
    309      for model in models:
    310        logger.debug('loading model %s' % str(model[0]))
    311        #item = PaneTreeItem(self.treewidget, [model[0].getName()])
    312        item = ModelItem(self.treewidget, [model[0].getName()])
    313        #self.treeitems.append(item)
    314        self.treewidget.modelitems.append(item)
    315
    316      self.treewidget.update()
    317
    318 -  def change_current(self, (index, text)):
    319      logger.debug('set current to %s' % text)
    320
    321      if self.currentbutton != -1:
    322        button = self.buttons[self.currentbutton]
    323        button.setStyleSheet(button.stylenormal)
    324        button.selected = False
    325      self.caption.setText(text)
    326      self.currentbutton = index
    327
    328      def get_models_for_tree():
    329        """Return pairs of (Admin,query) classes for items in the tree"""
    330        section = self.sections[index][0]
    331        return self.app_admin.getEntitiesAndQueriesInSection(section)
    332
    333      self.mt.post(get_models_for_tree,
    334                   lambda models:self.set_models_in_tree(models))
    335
    336 -  def createContextMenu(self, point):
    337      logger.debug('creating context menu')
    338      item = self.treewidget.itemAt(point)
    339      if item:
    340        #column = 0
    341        #flag = QtGui.QItemSelectionModel.SelectCurrent
    342        #self.treewidget.setCurrentItem(item, column, flag)
    343        self.treewidget.setCurrentItem(item)
    344        self.treewidget.contextmenu.popup(self.cursor().pos())
    345
    346 -  def popWindow(self):
    347      """pops a model window in parent's workspace"""
    348      logger.debug('poping a window in parent')
    349      item = self.treewidget.currentItem()
    350      #column = 0
    351      #self.parent.createMdiChild(item, column)
    352      self.parent.createMdiChild(item)
    353