maint: format code using black
[git-cola.git] / cola / widgets / startup.py
blobfa42f16d6dffaf53f72a4dfa422a439d3eac487e
1 """Provides the git-cola startup dialog
3 The startup dialog is presented when no repositories can be
4 found at startup.
6 """
7 from __future__ import division, absolute_import, unicode_literals
9 from qtpy.QtCore import Qt
10 from qtpy import QtCore
11 from qtpy import QtGui
12 from qtpy import QtWidgets
14 from ..i18n import N_
15 from .. import core
16 from .. import display
17 from .. import guicmds
18 from .. import icons
19 from .. import qtutils
20 from .. import version
21 from . import clone
22 from . import defs
23 from . import standard
26 class StartupDialog(standard.Dialog):
27 """Provides a GUI to Open or Clone a git repository."""
29 def __init__(self, context, parent=None):
30 standard.Dialog.__init__(self, parent)
31 self.context = context
32 self.setWindowTitle(N_('git-cola'))
34 # Top-most large icon
35 logo_pixmap = icons.cola().pixmap(defs.huge_icon, defs.huge_icon)
37 self.logo_label = QtWidgets.QLabel()
38 self.logo_label.setPixmap(logo_pixmap)
39 self.logo_label.setAlignment(Qt.AlignCenter)
41 self.logo_text_label = qtutils.label(text=version.cola_version())
42 self.logo_text_label.setAlignment(Qt.AlignCenter)
44 self.repodir = None
45 if context.runtask:
46 self.runtask = context.runtask
47 else:
48 self.runtask = context.runtask = qtutils.RunTask(parent=self)
50 self.new_button = qtutils.create_button(text=N_('New...'), icon=icons.new())
51 self.open_button = qtutils.create_button(
52 text=N_('Open...'), icon=icons.folder()
54 self.clone_button = qtutils.create_button(
55 text=N_('Clone...'), icon=icons.cola()
57 self.close_button = qtutils.close_button()
59 self.bookmarks_model = bookmarks_model = QtGui.QStandardItemModel()
60 self.items = items = []
62 item = QtGui.QStandardItem(N_('Open...'))
63 item.setEditable(False)
64 item.setIcon(icons.open_directory())
65 bookmarks_model.appendRow(item)
67 # The tab bar allows choosing between Folder and List mode
68 self.tab_bar = QtWidgets.QTabBar()
69 self.tab_bar.setMovable(False)
70 self.tab_bar.addTab(icons.directory(), N_('Folder'))
71 self.tab_bar.addTab(icons.three_bars(), N_('List'))
73 # Bookmarks/"Favorites" and Recent are lists of {name,path: str}
74 settings = context.settings
75 bookmarks = settings.bookmarks
76 recent = settings.recent
77 all_repos = bookmarks + recent
79 directory_icon = icons.directory()
80 user_role = Qt.UserRole
81 normalize = display.normalize_path
82 paths = set([normalize(repo['path']) for repo in all_repos])
83 short_paths = display.shorten_paths(paths)
84 self.short_paths = short_paths
86 added = set()
87 for repo in all_repos:
88 path = normalize(repo['path'])
89 if path in added:
90 continue
91 added.add(path)
93 item = QtGui.QStandardItem(path)
94 item.setEditable(False)
95 item.setData(path, user_role)
96 item.setIcon(directory_icon)
97 item.setToolTip(path)
98 item.setText(self.short_paths.get(path, path))
99 bookmarks_model.appendRow(item)
100 items.append(item)
102 selection_mode = QtWidgets.QAbstractItemView.SingleSelection
103 self.bookmarks = bookmarks = QtWidgets.QListView()
104 bookmarks.setSelectionMode(selection_mode)
105 bookmarks.setModel(bookmarks_model)
106 bookmarks.setViewMode(QtWidgets.QListView.IconMode)
107 bookmarks.setResizeMode(QtWidgets.QListView.Adjust)
108 bookmarks.setGridSize(make_size(defs.large_icon))
109 bookmarks.setIconSize(make_size(defs.medium_icon))
110 bookmarks.setDragEnabled(False)
111 bookmarks.setWordWrap(True)
113 self.tab_layout = qtutils.vbox(
114 defs.no_margin, defs.no_spacing, self.tab_bar, self.bookmarks
117 self.logo_layout = qtutils.vbox(
118 defs.no_margin,
119 defs.spacing,
120 self.logo_label,
121 self.logo_text_label,
122 defs.button_spacing,
123 qtutils.STRETCH,
126 self.button_layout = qtutils.hbox(
127 defs.no_margin,
128 defs.spacing,
129 self.open_button,
130 self.clone_button,
131 self.new_button,
132 qtutils.STRETCH,
133 self.close_button,
136 self.main_layout = qtutils.grid(defs.margin, defs.spacing)
137 self.main_layout.addItem(self.logo_layout, 1, 1)
138 self.main_layout.addItem(self.tab_layout, 1, 2)
139 self.main_layout.addItem(self.button_layout, 2, 1, columnSpan=2)
140 self.setLayout(self.main_layout)
142 qtutils.connect_button(self.open_button, self.open_repo)
143 qtutils.connect_button(self.clone_button, self.clone_repo)
144 qtutils.connect_button(self.new_button, self.new_repo)
145 qtutils.connect_button(self.close_button, self.reject)
147 # pylint: disable=no-member
148 self.tab_bar.currentChanged.connect(self.tab_changed)
149 self.bookmarks.activated.connect(self.open_bookmark)
151 self.init_state(settings, self.resize_widget)
152 self.setFocusProxy(self.bookmarks)
153 self.bookmarks.setFocus()
155 # Update the list mode
156 list_mode = context.cfg.get('cola.startupmode', default='folder')
157 self.list_mode = list_mode
158 if list_mode == 'list':
159 self.tab_bar.setCurrentIndex(1)
161 def tab_changed(self, idx):
162 bookmarks = self.bookmarks
163 if idx == 0:
164 bookmarks.setViewMode(QtWidgets.QListView.IconMode)
165 bookmarks.setIconSize(make_size(defs.medium_icon))
166 bookmarks.setGridSize(make_size(defs.large_icon))
167 list_mode = 'folder'
168 for item in self.items:
169 path = item.data(Qt.UserRole)
170 item.setText(self.short_paths.get(path, path))
171 else:
172 bookmarks.setViewMode(QtWidgets.QListView.ListMode)
173 bookmarks.setIconSize(make_size(defs.default_icon))
174 bookmarks.setGridSize(QtCore.QSize())
175 list_mode = 'list'
176 for item in self.items:
177 path = item.data(Qt.UserRole)
178 item.setText(path)
180 if list_mode != self.list_mode:
181 self.list_mode = list_mode
182 self.context.cfg.set_user('cola.startupmode', list_mode)
184 def resize_widget(self):
185 screen = QtWidgets.QApplication.instance().desktop()
186 self.setGeometry(
187 screen.width() // 4,
188 screen.height() // 4,
189 screen.width() // 2,
190 screen.height() // 2,
193 def find_git_repo(self):
195 Return a path to a git repository
197 This is the entry point for external callers.
198 This method finds a git repository by allowing the
199 user to browse to one on the filesystem or by creating
200 a new one with git-clone.
203 self.show()
204 self.raise_()
205 if self.exec_() == QtWidgets.QDialog.Accepted:
206 return self.repodir
207 return None
209 def open_repo(self):
210 self.repodir = self.get_selected_bookmark()
211 if not self.repodir:
212 self.repodir = qtutils.opendir_dialog(
213 N_('Open Git Repository...'), core.getcwd()
215 if self.repodir:
216 self.accept()
218 def clone_repo(self):
219 context = self.context
220 progress = standard.progress('', '', self)
221 clone.clone_repo(context, self, True, progress, self.clone_repo_done, False)
223 def clone_repo_done(self, task):
224 if task.cmd and task.cmd.status == 0:
225 self.repodir = task.destdir
226 self.accept()
227 else:
228 clone.task_finished(task)
230 def new_repo(self):
231 context = self.context
232 repodir = guicmds.new_repo(context)
233 if repodir:
234 self.repodir = repodir
235 self.accept()
237 def open_bookmark(self, index):
238 if index.row() == 0:
239 self.open_repo()
240 else:
241 self.repodir = self.bookmarks_model.data(index, Qt.UserRole)
242 if not self.repodir:
243 return
244 if not core.exists(self.repodir):
245 self.handle_broken_repo(index)
246 return
247 self.accept()
249 def handle_broken_repo(self, index):
250 settings = self.context.settings
251 all_repos = settings.bookmarks + settings.recent
252 repodir = self.bookmarks_model.data(index, Qt.UserRole)
254 repo = next(repo for repo in all_repos if repo['path'] == repodir)
255 title = N_('Repository Not Found')
256 text = N_('%s could not be opened. Remove from bookmarks?') % repo['path']
257 logo = icons.from_style(QtWidgets.QStyle.SP_MessageBoxWarning)
258 if standard.question(title, text, N_('Remove'), logo=logo):
259 self.context.settings.remove_bookmark(repo['path'], repo['name'])
260 self.context.settings.remove_recent(repo['path'])
261 self.context.settings.save()
263 item = self.bookmarks_model.item(index.row())
264 self.items.remove(item)
265 self.bookmarks_model.removeRow(index.row())
267 def get_selected_bookmark(self):
268 selected = self.bookmarks.selectedIndexes()
269 if selected and selected[0].row() != 0:
270 return self.bookmarks_model.data(selected[0], Qt.UserRole)
271 return None
274 def make_size(size):
275 """Construct a QSize from a single value"""
276 return QtCore.QSize(size, size)