1 from PyQt4
import QtGui
2 from PyQt4
import QtCore
3 from PyQt4
.QtCore
import Qt
4 from PyQt4
.QtCore
import SIGNAL
7 def create_widget_class(Base
):
9 # Mix-in for standard view operations
10 def __init__(self
, parent
=None):
11 super(Widget
, self
).__init
__(parent
)
14 """Automatically centers dialogs"""
16 left
= self
.parent().x()
17 width
= self
.parent().width()
18 center_x
= left
+ width
/2
20 x
= center_x
- self
.width()/2
24 # Call the base Qt show()
28 """Returns the name of the view class"""
29 return self
.__class
__.__name
__.lower()
31 def apply_state(self
, state
):
32 """Imports data for view save/restore"""
34 self
.resize(state
['width'], state
['height'])
38 self
.move(state
['x'], state
['y'])
42 def export_state(self
):
43 """Exports data for view save/restore"""
47 'width': self
.width(),
48 'height': self
.height(),
54 def create_tree_class(Base
):
56 def __init__(self
, parent
=None):
57 super(Tree
, self
).__init
__(parent
)
58 self
.setAlternatingRowColors(True)
59 self
.setUniformRowHeights(True)
60 self
.setAllColumnsShowFocus(True)
61 self
.setAnimated(True)
63 def key_pressed(self
):
66 def keyPressEvent(self
, event
):
68 Override keyPressEvent to allow LeftArrow to work on non-directories.
70 When LeftArrow is pressed on a file entry or an unexpanded directory,
71 then move the current index to the parent directory.
73 This simplifies navigation using the keyboard.
74 For power-users, we support Vim keybindings ;-P
77 # Check whether the item is expanded before calling the base class
78 # keyPressEvent otherwise we end up collapsing and changing the
79 # current index in one shot, which we don't want to do.
80 index
= self
.currentIndex()
81 was_expanded
= self
.isExpanded(index
)
82 was_collapsed
= not was_expanded
85 # Rewrite the event before marshalling to QTreeView.event()
90 event
= QtGui
.QKeyEvent(event
.type(),
95 event
= QtGui
.QKeyEvent(event
.type(),
100 event
= QtGui
.QKeyEvent(event
.type(),
103 # Remap 'L' to 'Right'
104 elif key
== Qt
.Key_L
:
105 event
= QtGui
.QKeyEvent(event
.type(),
109 # Re-read the event key to take the remappings into account
112 result
= super(Tree
, self
).keyPressEvent(event
)
114 # Let others hook in here before we change the indexes
115 self
.emit(SIGNAL('indexAboutToChange()'))
117 # Try to select the first item if the model index is invalid
118 if not index
.isValid():
119 index
= self
.model().index(0, 0, QtCore
.QModelIndex())
121 self
.setCurrentIndex(index
)
123 # Automatically select the first entry when expanding a directory
124 elif (key
== Qt
.Key_Right
and was_collapsed
and
125 self
.isExpanded(index
)):
126 index
= self
.moveCursor(self
.MoveDown
, event
.modifiers())
127 self
.setCurrentIndex(index
)
129 # Process non-root entries with valid parents only.
130 elif key
== Qt
.Key_Left
and index
.parent().isValid():
132 # File entries have rowCount() == 0
133 if self
.model().itemFromIndex(index
).rowCount() == 0:
134 self
.setCurrentIndex(index
.parent())
136 # Otherwise, do this for collapsed directories only
138 self
.setCurrentIndex(index
.parent())
141 # Tree is a closure over "Base"
145 Widget
= create_widget_class(QtGui
.QWidget
)
146 Dialog
= create_widget_class(QtGui
.QDialog
)
147 MainWindow
= create_widget_class(QtGui
.QMainWindow
)
149 TreeView
= create_tree_class(QtGui
.QTreeView
)
150 TreeWidget
= create_tree_class(QtGui
.QTreeWidget
)