Avoid raising an exception when a child cannot be started.
[ugit.git] / ugitlibs / repobrowsercontroller.py
blob4c6e520ca80b0284743f2b2764162e71d3e62ba7
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(init=False)
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.commitList,)
27 self.add_actions('directory', self.action_directory_changed)
28 self.add_callbacks(commitList = self.item_changed)
29 self.connect(
30 view.commitList, 'itemDoubleClicked(QListWidgetItem*)',
31 self.item_double_clicked)
33 # Start at the root of the tree
34 model.set_directory('')
36 ######################################################################
37 # Actions
39 def action_directory_changed(self):
40 '''This is called in response to a change in the the
41 model's directory.'''
42 self.model.init_browser_data()
43 self.__display_items()
45 ######################################################################
46 # Qt callbacks
48 def item_changed(self,*rest):
49 '''This is called when the current item changes in the
50 file/directory list(aka the commitList).'''
51 current = self.view.commitList.currentRow()
52 item = self.view.commitList.item(current)
53 if item is None or not item.isSelected():
54 self.view.revisionLine.setText('')
55 self.view.commitText.setText('')
56 return
58 directories = self.model.get_directories()
59 directory_entries = self.model.get_directory_entries()
61 if current < len(directories):
62 # This is a directory...
63 dirent = directories[current]
64 if dirent != '..':
65 # This is a real directory for which
66 # we have child entries
67 msg = utils.header('Directory:' + dirent)
68 entries = directory_entries[dirent]
69 else:
70 # This is '..' which is a special case
71 # since it doesn't really exist
72 msg = utils.header('Parent Directory')
73 entries = []
75 contents = '\n'.join(entries)
77 self.view.commitText.setText(msg + contents)
78 self.view.revisionLine.setText('')
79 else:
80 # This is a file entry. The current row is absolute,
81 # so get a relative index by subtracting the number
82 # of directory entries
83 idx = current - len(directories)
85 if idx >= len(self.model.get_subtree_sha1s()):
86 # This can happen when changing directories
87 return
89 objtype, sha1, name = \
90 self.model.get_subtree_node(idx)
92 guts = self.model.cat_file(objtype, sha1)
93 header = utils.header('File: ' + name)
94 contents = guts
96 self.view.commitText.setText(header + contents)
98 self.view.revisionLine.setText(sha1)
99 self.view.revisionLine.selectAll()
101 # Copy the sha1 into the clipboard
102 qtutils.set_clipboard(sha1)
104 def item_double_clicked(self,*rest):
105 '''This is called when an entry is double-clicked.
106 This callback changes the model's directory when
107 invoked on a directory item. When invoked on a file
108 it allows the file to be saved.'''
110 current = self.view.commitList.currentRow()
111 directories = self.model.get_directories()
113 # A file item was double-clicked.
114 # Create a save-as dialog and export the file.
115 if current >= len(directories):
116 idx = current - len(directories)
118 objtype, sha1, name = \
119 self.model.get_subtree_node(idx)
121 nameguess = os.path.join(defaults.DIRECTORY, name)
123 filename = qtutils.save_dialog(self.view, 'Save', nameguess)
124 if not filename: return
126 defaults.DIRECTORY = os.path.dirname(filename)
127 contents = self.model.cat_file(objtype, sha1)
129 utils.write(filename, contents)
130 return
132 dirent = directories[current]
133 curdir = self.model.get_directory()
135 # '..' is a special case--it doesn't really exist...
136 if dirent == '..':
137 newdir = os.path.dirname(os.path.dirname(curdir))
138 if newdir == '':
139 self.model.set_directory(newdir)
140 else:
141 self.model.set_directory(newdir + os.sep)
142 else:
143 self.model.set_directory(curdir + dirent)
145 ######################################################################
147 def __display_items(self):
148 '''This method populates the commitList(aka item list)
149 with the current directories and items. Directories are
150 always listed first.'''
152 self.view.commitText.setText('')
153 self.view.revisionLine.setText('')
155 dir_icon = utils.get_directory_icon()
156 file_icon = utils.get_file_icon()
158 qtutils.set_items(self.view.commitList,
159 map(lambda d: qtutils.create_listwidget_item(d, dir_icon),
160 self.model.get_directories()))
162 qtutils.add_items(self.view.commitList,
163 map(lambda s: qtutils.create_listwidget_item(s, file_icon),
164 self.model.get_subtree_names()))