Increment ugit version to 0.8.7
[git-cola.git] / ugitlibs / repobrowsercontroller.py
blob6a75356cf1e4a54cd8a6c91ba1d8f03a04d47a93
1 #!/usr/bin/env python
2 import os
3 from PyQt4.QtGui import QDialog
4 from qobserver import QObserver
5 import utils
6 import qtutils
7 import defaults
8 from views import CommitGUI
10 def browse_git_branch(model, parent, branch):
11 if not branch: return
12 # Clone the model to allow opening multiple browsers
13 # with different sets of data
14 model = model.clone()
15 model.set_branch(branch)
16 view = CommitGUI(parent)
17 controller = RepoBrowserController(model, view)
18 view.show()
19 return view.exec_() == QDialog.Accepted
21 class RepoBrowserController(QObserver):
22 def __init__(self, model, view):
23 QObserver.__init__(self, model, view)
25 view.setWindowTitle('File Browser')
26 self.add_signals('itemSelectionChanged()', view.commit_list,)
27 self.add_actions('directory', self.action_directory_changed)
28 self.add_callbacks(commit_list = self.item_changed)
29 self.connect(
30 view.commit_list,
31 'itemDoubleClicked(QListWidgetItem*)',
32 self.item_double_clicked)
34 # Start at the root of the tree
35 model.set_directory('')
37 ######################################################################
38 # Actions
40 def action_directory_changed(self):
41 '''This is called in response to a change in the the
42 model's directory.'''
43 self.model.init_browser_data()
44 self.__display_items()
46 ######################################################################
47 # Qt callbacks
49 def item_changed(self,*rest):
50 '''This is called when the current item changes in the
51 file/directory list(aka the commit_list).'''
52 current = self.view.commit_list.currentRow()
53 item = self.view.commit_list.item(current)
54 if item is None or not item.isSelected():
55 self.view.revision.setText('')
56 self.view.commit_text.setText('')
57 return
59 directories = self.model.get_directories()
60 directory_entries = self.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 entries = directory_entries[dirent]
69 else:
70 # This is '..' which is a special case
71 # since it doesn't really exist
72 entries = []
73 self.view.commit_text.setText('\n'.join(entries))
74 self.view.revision.setText('')
75 else:
76 # This is a file entry. The current row is absolute,
77 # so get a relative index by subtracting the number
78 # of directory entries
79 idx = current - len(directories)
81 if idx >= len(self.model.get_subtree_sha1s()):
82 # This can happen when changing directories
83 return
85 objtype, sha1, name = self.model.get_subtree_node(idx)
87 catguts = self.model.cat_file(objtype, sha1)
88 self.view.commit_text.setText(catguts)
90 self.view.revision.setText(sha1)
91 self.view.revision.selectAll()
93 # Copy the sha1 into the clipboard
94 qtutils.set_clipboard(sha1)
96 def item_double_clicked(self,*rest):
97 '''This is called when an entry is double-clicked.
98 This callback changes the model's directory when
99 invoked on a directory item. When invoked on a file
100 it allows the file to be saved.'''
102 current = self.view.commit_list.currentRow()
103 directories = self.model.get_directories()
105 # A file item was double-clicked.
106 # Create a save-as dialog and export the file.
107 if current >= len(directories):
108 idx = current - len(directories)
110 objtype, sha1, name = \
111 self.model.get_subtree_node(idx)
113 nameguess = os.path.join(defaults.DIRECTORY, name)
115 filename = qtutils.save_dialog(self.view, 'Save', nameguess)
116 if not filename: return
118 defaults.DIRECTORY = os.path.dirname(filename)
119 contents = self.model.cat_file(objtype, sha1)
121 utils.write(filename, contents)
122 return
124 dirent = directories[current]
125 curdir = self.model.get_directory()
127 # '..' is a special case--it doesn't really exist...
128 if dirent == '..':
129 newdir = os.path.dirname(os.path.dirname(curdir))
130 if newdir == '':
131 self.model.set_directory(newdir)
132 else:
133 self.model.set_directory(newdir + os.sep)
134 else:
135 self.model.set_directory(curdir + dirent)
137 ######################################################################
139 def __display_items(self):
140 '''This method populates the commit_list(aka item list)
141 with the current directories and items. Directories are
142 always listed first.'''
144 self.view.commit_text.setText('')
145 self.view.revision.setText('')
147 dir_icon = utils.get_icon('dir.png')
148 file_icon = utils.get_icon('generic.png')
150 qtutils.set_items(self.view.commit_list,
151 map(lambda d: qtutils.create_listwidget_item(d, dir_icon),
152 self.model.get_directories()))
154 qtutils.add_items(self.view.commit_list,
155 map(lambda s: qtutils.create_listwidget_item(s, file_icon),
156 self.model.get_subtree_names()))