3 from PyQt4
.QtCore
import SIGNAL
4 from PyQt4
.QtGui
import QFileDialog
5 from qobserver
import QObserver
11 class GitRepoBrowserController (QObserver
):
12 def __init__ (self
, model
, view
):
13 QObserver
.__init
__ (self
, model
, view
)
15 model
.add_observer (self
)
17 view
.setWindowTitle ('Git Repo Browser')
19 self
.add_signals ('itemSelectionChanged()',
22 self
.add_actions (model
, 'directory',
23 self
.action_directory_changed
)
25 self
.add_callbacks (model
, {
26 'commitList': self
.cb_item_changed
,
29 self
.connect (view
.commitList
,
30 SIGNAL ('itemDoubleClicked(QListWidgetItem*)'),
31 lambda(x
): self
.cb_item_double_clicked (model
))
33 # Collect data for the model
34 tree_info
= cmds
.git_ls_tree (model
.get_branch())
36 types
= map ( lambda (x
): x
[1], tree_info
)
37 sha1s
= map ( lambda (x
): x
[2], tree_info
)
38 files
= map ( lambda (x
): x
[3], tree_info
)
40 model
.add_types (*types
)
41 model
.add_files (*files
)
42 model
.add_sha1s (*sha1s
)
46 self
.__display
_items
(model
)
48 ######################################################################
50 ######################################################################
52 def action_directory_changed (self
, model
, *args
):
53 '''This is called in response to a change in the the
56 self
.__display
_items
(model
)
58 ######################################################################
60 ######################################################################
62 def cb_item_changed (self
, model
, *args
):
63 '''This is called when the current item changes in the
64 file/directory list (aka the commitList).'''
65 current
= self
.view
.commitList
.currentRow()
66 item
= self
.view
.commitList
.item (current
)
67 if item
is None or not item
.isSelected():
68 self
.view
.revisionLine
.setText ('')
69 self
.view
.commitText
.setText ('')
71 item_names
= model
.get_item_names()
72 item_sha1s
= model
.get_item_sha1s()
73 item_types
= model
.get_item_types()
74 directories
= model
.get_directories()
75 directory_entries
= model
.get_directory_entries()
77 if current
< len (directories
):
78 # This is a directory...
79 dirent
= directories
[current
]
81 # This is a real directory for which
82 # we have child entries
83 msg
= 'Directory: ' + dirent
84 header
= utils
.html_header (msg
)
85 entries
= directory_entries
[dirent
]
87 # This is '..' which is a special case
88 # since it doesn't really exist
89 msg
= 'Parent Directory'
90 header
= utils
.html_header (msg
)
93 contents
= '<pre>%s</pre>' % '\n'.join (entries
)
95 self
.view
.commitText
.setHtml (header
+ contents
)
96 self
.view
.revisionLine
.setText ('')
98 # This is a file entry. The current row is absolute,
99 # so get a relative index by subtracting the number
100 # of directory entries
101 idx
= current
- len (directories
)
103 if idx
>= len (item_sha1s
):
104 # This can happen when changing directories
107 sha1
= item_sha1s
[idx
]
108 objtype
= item_types
[idx
]
109 filename
= item_names
[idx
]
111 guts
= cmds
.git_cat_file (objtype
, sha1
)
112 header
= utils
.html_header ('File: ' + filename
)
113 contents
= '<pre>%s</pre>' % utils
.html_encode (guts
)
115 self
.view
.commitText
.setHtml (header
+ contents
)
117 self
.view
.revisionLine
.setText (sha1
)
118 self
.view
.revisionLine
.selectAll()
120 # Copy the sha1 into the clipboard
121 qtutils
.set_clipboard (sha1
)
123 def cb_item_double_clicked (self
, model
):
124 '''This is called when an entry is double-clicked.
125 This callback changes the model's directory when
126 invoked on a directory item. When invoked on a file
127 it allows the file to be saved.'''
129 current
= self
.view
.commitList
.currentRow()
130 directories
= model
.get_directories()
132 # A file item was double-clicked.
133 # Create a save-as dialog and export the file.
134 if current
>= len (directories
):
135 idx
= current
- len (directories
)
137 names
= model
.get_item_names()
138 sha1s
= model
.get_item_sha1s()
139 types
= model
.get_item_types()
145 file_to_save
= os
.path
.join(defaults
.DIRECTORY
, name
)
147 qstr_filename
= QFileDialog
.getSaveFileName(self
.view
,
148 'Git File Export', file_to_save
)
149 if not qstr_filename
: return
151 filename
= str (qstr_filename
)
152 defaults
.DIRECTORY
= os
.path
.dirname (filename
)
153 cmds
.git_cat_file (objtype
, sha1
, filename
)
156 dirent
= directories
[current
]
157 curdir
= model
.get_directory()
160 newdir
= os
.path
.normpath (curdir
+ '..')
161 if newdir
== '.' or not newdir
:
162 model
.set_directory ('')
164 model
.set_directory (newdir
+ '/')
166 model
.set_directory (curdir
+ dirent
)
168 ######################################################################
169 # PRIVATE HELPER METHODS
170 ######################################################################
172 def __display_items (self
, model
):
173 '''This method populates the commitList (aka item list)
174 with the current directories and items. Directories are
175 always listed first.'''
177 self
.view
.commitList
.clear()
178 self
.view
.commitText
.setText ('')
179 self
.view
.revisionLine
.setText ('')
181 dir_icon
= utils
.get_directory_icon()
182 file_icon
= utils
.get_file_icon()
184 for entry
in model
.get_directories():
185 item
= qtutils
.create_listwidget_item(entry
, dir_icon
)
186 self
.view
.commitList
.addItem (item
)
188 for entry
in model
.get_item_names():
189 item
= qtutils
.create_listwidget_item(entry
, file_icon
)
190 self
.view
.commitList
.addItem (item
)