Consolidated model classes into a single class
[ugit.git] / py / repobrowsercontroller.py
blob57cc29f51f340799544904b24d4f76a30bb8e9ac
1 #!/usr/bin/env python
2 import os
3 from PyQt4.QtGui import QFileDialog
4 from qobserver import QObserver
5 import cmds
6 import utils
7 import qtutils
8 import defaults
10 class GitRepoBrowserController (QObserver):
11 def __init__ (self, model, view):
12 QObserver.__init__ (self, model, view)
14 view.setWindowTitle ('Git Repo Browser')
16 self.add_signals ('itemSelectionChanged()',
17 view.commitList,)
19 self.add_actions (model, 'directory',
20 self.action_directory_changed)
22 self.add_callbacks (model, {
23 'commitList': self.cb_item_changed,
26 self.connect (view.commitList,
27 'itemDoubleClicked(QListWidgetItem*)',
28 lambda(x): self.cb_item_double_clicked (model))
30 # Start at the root of the tree
31 model.set_directory('')
33 ######################################################################
34 # ACTIONS
35 ######################################################################
37 def action_directory_changed (self, model):
38 '''This is called in response to a change in the the
39 model's directory.'''
40 model.init_browser_data()
41 self.__display_items (model)
43 ######################################################################
44 # CALLBACKS
45 ######################################################################
47 def cb_item_changed (self, model):
48 '''This is called when the current item changes in the
49 file/directory list (aka the commitList).'''
50 current = self.view.commitList.currentRow()
51 item = self.view.commitList.item (current)
52 if item is None or not item.isSelected():
53 self.view.revisionLine.setText ('')
54 self.view.commitText.setText ('')
55 return
56 item_names = model.get_item_names()
57 item_sha1s = model.get_item_sha1s()
58 item_types = model.get_item_types()
59 directories = model.get_directories()
60 directory_entries = model.get_directory_entries()
62 if current < len (directories):
63 # This is a directory...
64 dirent = directories[current]
65 if dirent != '..':
66 # This is a real directory for which
67 # we have child entries
68 msg = utils.header ('Directory:' + dirent)
69 entries = directory_entries[dirent]
70 else:
71 # This is '..' which is a special case
72 # since it doesn't really exist
73 msg = utils.header ('Parent Directory')
74 entries = []
76 contents = '\n'.join (entries)
78 self.view.commitText.setText (msg + contents)
79 self.view.revisionLine.setText ('')
80 else:
81 # This is a file entry. The current row is absolute,
82 # so get a relative index by subtracting the number
83 # of directory entries
84 idx = current - len (directories)
86 if idx >= len (item_sha1s):
87 # This can happen when changing directories
88 return
90 sha1 = item_sha1s[idx]
91 objtype = item_types[idx]
92 filename = item_names[idx]
94 guts = cmds.git_cat_file (objtype, sha1)
95 header = utils.header ('File: ' + filename)
96 contents = guts
98 self.view.commitText.setText (header + contents)
100 self.view.revisionLine.setText (sha1)
101 self.view.revisionLine.selectAll()
103 # Copy the sha1 into the clipboard
104 qtutils.set_clipboard (sha1)
106 def cb_item_double_clicked (self, model):
107 '''This is called when an entry is double-clicked.
108 This callback changes the model's directory when
109 invoked on a directory item. When invoked on a file
110 it allows the file to be saved.'''
112 current = self.view.commitList.currentRow()
113 directories = model.get_directories()
115 # A file item was double-clicked.
116 # Create a save-as dialog and export the file.
117 if current >= len (directories):
118 idx = current - len (directories)
120 names = model.get_item_names()
121 sha1s = model.get_item_sha1s()
122 types = model.get_item_types()
124 objtype = types[idx]
125 sha1 = sha1s[idx]
126 name = names[idx]
128 file_to_save = os.path.join(defaults.DIRECTORY, name)
130 qstr_filename = QFileDialog.getSaveFileName(self.view,
131 'Git File Export', file_to_save)
132 if not qstr_filename: return
134 filename = str (qstr_filename)
135 defaults.DIRECTORY = os.path.dirname (filename)
136 contents = cmds.git_cat_file (objtype, sha1)
138 file = open (filename, 'w')
139 file.write (contents)
140 file.close()
141 return
143 dirent = directories[current]
144 curdir = model.get_directory()
146 # '..' is a special case--it doesn't really exist...
147 if dirent == '..':
148 newdir = os.path.dirname (os.path.dirname (curdir))
149 if newdir == '':
150 model.set_directory (newdir)
151 else:
152 model.set_directory (newdir + os.sep)
153 else:
154 model.set_directory (curdir + dirent)
156 ######################################################################
157 # PRIVATE HELPER METHODS
158 ######################################################################
160 def __display_items (self, model):
161 '''This method populates the commitList (aka item list)
162 with the current directories and items. Directories are
163 always listed first.'''
165 self.view.commitList.clear()
166 self.view.commitText.setText ('')
167 self.view.revisionLine.setText ('')
169 dir_icon = utils.get_directory_icon()
170 file_icon = utils.get_file_icon()
172 for entry in model.get_directories():
173 item = qtutils.create_listwidget_item(entry, dir_icon)
174 self.view.commitList.addItem (item)
176 for entry in model.get_item_names():
177 item = qtutils.create_listwidget_item(entry, file_icon)
178 self.view.commitList.addItem (item)