2 from __future__
import division
, absolute_import
, unicode_literals
8 from qtpy
.QtCore
import Qt
10 from qtpy
import QtWidgets
14 from .. import resources
15 from .. import hotkeys
17 from .. import qtutils
18 from .. import version
22 def about_dialog(context
):
23 """Launches the Help -> About dialog"""
24 view
= AboutView(context
, qtutils
.active_window())
29 class ExpandingTabBar(QtWidgets
.QTabBar
):
30 """A TabBar with tabs that expand to fill the empty space
32 The setExpanding(True) method does not work in practice because
33 it respects the OS style. We override the style by implementing
34 tabSizeHint() so that we can specify the size explicitly.
38 def tabSizeHint(self
, tab_index
):
39 width
= self
.parent().width() / max(1, self
.count()) - 1
40 size
= super(ExpandingTabBar
, self
).tabSizeHint(tab_index
)
45 class ExpandingTabWidget(QtWidgets
.QTabWidget
):
47 def __init__(self
, parent
=None):
48 super(ExpandingTabWidget
, self
).__init
__(parent
)
49 self
.setTabBar(ExpandingTabBar(self
))
51 def resizeEvent(self
, event
):
52 """Forward resize events to the ExpandingTabBar"""
53 # Qt does not resize the tab bar when the dialog is resized
54 # so manually forward resize events to the tab bar.
55 width
= event
.size().width()
56 height
= self
.tabBar().height()
57 self
.tabBar().resize(width
, height
)
58 return super(ExpandingTabWidget
, self
).resizeEvent(event
)
61 class AboutView(QtWidgets
.QDialog
):
62 """Provides the git-cola 'About' dialog"""
64 def __init__(self
, context
, parent
=None):
65 QtWidgets
.QDialog
.__init
__(self
, parent
)
67 self
.context
= context
68 self
.setWindowTitle(N_('About git-cola'))
69 self
.setWindowModality(Qt
.WindowModal
)
72 logo_pixmap
= icons
.cola().pixmap(defs
.huge_icon
, defs
.large_icon
)
74 self
.logo_label
= QtWidgets
.QLabel()
75 self
.logo_label
.setPixmap(logo_pixmap
)
76 self
.logo_label
.setAlignment(Qt
.AlignCenter
)
78 self
.logo_text_label
= QtWidgets
.QLabel()
79 self
.logo_text_label
.setText('Git Cola')
80 self
.logo_text_label
.setAlignment(Qt
.AlignLeft | Qt
.AlignCenter
)
82 font
= self
.logo_text_label
.font()
83 font
.setPointSize(defs
.logo_text
)
84 self
.logo_text_label
.setFont(font
)
86 self
.text
= qtutils
.textbrowser(text
=copyright_text())
87 self
.version
= qtutils
.textbrowser(text
=version_text(context
))
88 self
.authors
= qtutils
.textbrowser(text
=authors_text())
89 self
.translators
= qtutils
.textbrowser(text
=translators_text())
91 self
.tabs
= ExpandingTabWidget()
92 self
.tabs
.addTab(self
.text
, N_('About'))
93 self
.tabs
.addTab(self
.version
, N_('Version'))
94 self
.tabs
.addTab(self
.authors
, N_('Authors'))
95 self
.tabs
.addTab(self
.translators
, N_('Translators'))
97 self
.close_button
= qtutils
.close_button()
98 self
.close_button
.setDefault(True)
100 self
.logo_layout
= qtutils
.hbox(defs
.no_margin
, defs
.button_spacing
,
101 self
.logo_label
, self
.logo_text_label
,
104 self
.button_layout
= qtutils
.hbox(defs
.spacing
, defs
.margin
,
105 qtutils
.STRETCH
, self
.close_button
)
107 self
.main_layout
= qtutils
.vbox(defs
.no_margin
, defs
.spacing
,
111 self
.setLayout(self
.main_layout
)
113 qtutils
.connect_button(self
.close_button
, self
.accept
)
115 self
.resize(defs
.scale(600), defs
.scale(720))
118 def copyright_text():
120 Git Cola: The highly caffeinated Git GUI
122 Copyright (C) 2007-2018 David Aguilar and contributors
124 This program is free software: you can redistribute it and/or
125 modify it under the terms of the GNU General Public License
126 version 2 as published by the Free Software Foundation.
128 This program is distributed in the hope that it will
129 be useful, but WITHOUT ANY WARRANTY; without even the
130 implied warranty of MERCHANTABILITY or
131 FITNESS FOR A PARTICULAR PURPOSE.
133 See the GNU General Public License for more details.
135 You should have received a copy of the
136 GNU General Public License along with this program.
137 If not, see http://www.gnu.org/licenses/.
142 def version_text(context
):
143 git_version
= version
.git_version(context
)
144 cola_version
= version
.version()
145 build_version
= version
.build_version()
146 python_path
= sys
.executable
147 python_version
= sys
.version
148 qt_version
= qtpy
.QT_VERSION
149 qtpy_version
= qtpy
.__version
__
150 pyqt_api_name
= qtpy
.API_NAME
151 if qtpy
.PYQT5
or qtpy
.PYQT4
:
152 pyqt_api_version
= qtpy
.PYQT_VERSION
154 pyqt_api_version
= qtpy
.PYSIDE_VERSION
156 pyqt_api_version
= 'unknown'
158 platform_version
= platform
.platform()
160 # Only show the build version if _build_version.py exists
162 build_version
= '(%s)' % build_version
167 cola_version
=cola_version
,
168 build_version
=build_version
,
169 git_version
=git_version
,
170 platform_version
=platform_version
,
171 pyqt_api_name
=pyqt_api_name
,
172 pyqt_api_version
=pyqt_api_version
,
173 python_path
=python_path
,
174 python_version
=python_version
,
175 qt_version
=qt_version
,
176 qtpy_version
=qtpy_version
)
180 Git Cola version %(cola_version)s %(build_version)s
182 <li> %(platform_version)s
183 <li> Python (%(python_path)s) %(python_version)s
184 <li> Git %(git_version)s
185 <li> Qt %(qt_version)s
186 <li> QtPy %(qtpy_version)s
187 <li> %(pyqt_api_name)s %(pyqt_api_version)s
192 def link(url
, text
, palette
=None):
194 palette
= QtGui
.QPalette()
196 color
= palette
.color(QtGui
.QPalette
.Foreground
)
197 rgb
= 'rgb(%s, %s, %s)' % (color
.red(), color
.green(), color
.blue())
198 scope
= dict(rgb
=rgb
, text
=text
, url
=url
)
201 <a style="font-style: italic; text-decoration: none; color: %(rgb)s;"
208 def mailto(email
, text
, palette
):
209 return link('mailto:%s' % email
, text
, palette
) + '<br>'
212 def render_authors(authors
):
213 """Render a list of author details into richtext html"""
215 x
.setdefault('email', '')
219 <strong>%(name)s</strong><br>
220 <em>%(title)s</em><br>
223 """ % author
) for author
in authors
]
225 return ''.join(entries
)
228 def contributors_text(authors
, prelude
='', epilogue
=''):
229 author_text
= render_authors(authors
)
230 scope
= dict(author_text
=author_text
, epilogue
=epilogue
, prelude
=prelude
)
240 palette
= QtGui
.QPalette()
241 contact
= N_('Email contributor')
243 # The names listed here are listed in the same order as
244 # `git shortlog --summary --numbered --no-merges`
245 # Please submit a pull request if you would like to include your
246 # email address in the about screen.
247 # See the `generate-about` script in the "todo" branch.
248 # vim :read! ./Meta/generate-about
249 dict(name
='David Aguilar',
250 title
=N_('Maintainer (since 2007) and developer'),
251 email
=mailto('davvid@gmail.com', contact
, palette
)),
252 dict(name
='Daniel Harding', title
=N_('Developer')),
253 dict(name
='V字龍(Vdragon)', title
=N_('Developer'),
254 email
=mailto('Vdragon.Taiwan@gmail.com', contact
, palette
)),
255 dict(name
='Efimov Vasily', title
=N_('Developer')),
256 dict(name
='Guillaume de Bure', title
=N_('Developer')),
257 dict(name
='Uri Okrent', title
=N_('Developer')),
258 dict(name
='Alex Chernetz', title
=N_('Developer')),
259 dict(name
='Andreas Sommer', title
=N_('Developer')),
260 dict(name
='Thomas Kluyver', title
=N_('Developer')),
261 dict(name
='Javier Rodriguez Cuevas', title
=N_('Developer')),
262 dict(name
='Minarto Margoliono', title
=N_('Developer')),
263 dict(name
='Szymon Judasz', title
=N_('Developer')),
264 dict(name
='Ville Skyttä', title
=N_('Developer')),
265 dict(name
='Igor Galarraga', title
=N_('Developer')),
266 dict(name
='Stanislaw Halik', title
=N_('Developer')),
267 dict(name
='Virgil Dupras', title
=N_('Developer')),
268 dict(name
='Barry Roberts', title
=N_('Developer')),
269 dict(name
='wsdfhjxc', title
=N_('Developer')),
270 dict(name
='xhl', title
=N_('Developer')),
271 dict(name
='Stefan Naewe', title
=N_('Developer')),
272 dict(name
='Benedict Lee', title
=N_('Developer')),
273 dict(name
='Filip Danilović', title
=N_('Developer')),
274 dict(name
='Pavel Rehak', title
=N_('Developer')),
275 dict(name
='Steffen Prohaska', title
=N_('Developer')),
276 dict(name
='Michael Geddes', title
=N_('Developer')),
277 dict(name
='Rustam Safin', title
=N_('Developer')),
278 dict(name
='Alex Gulyás', title
=N_('Developer')),
279 dict(name
='David Martínez Martí', title
=N_('Developer')),
280 dict(name
='Justin Lecher', title
=N_('Developer')),
281 dict(name
='Kai Krakow', title
=N_('Developer')),
282 dict(name
='Karl Bielefeldt', title
=N_('Developer')),
283 dict(name
='Marco Costalba', title
=N_('Developer')),
284 dict(name
='Michael Homer', title
=N_('Developer')),
285 dict(name
='Sebastian Schuberth', title
=N_('Developer')),
286 dict(name
='Sven Claussner', title
=N_('Developer')),
287 dict(name
='real', title
=N_('Developer')),
288 dict(name
='v.paritskiy', title
=N_('Developer')),
289 dict(name
='林博仁(Buo-ren Lin)', title
=N_('Developer')),
290 dict(name
='AJ Bagwell', title
=N_('Developer')),
291 dict(name
='Adrien be', title
=N_('Developer')),
292 dict(name
='Andrej', title
=N_('Developer')),
293 dict(name
='Audrius Karabanovas', title
=N_('Developer')),
294 dict(name
='Barrett Lowe', title
=N_('Developer')),
295 dict(name
='Ben Boeckel', title
=N_('Developer')),
296 dict(name
='Boris W', title
=N_('Developer')),
297 dict(name
='Charles', title
=N_('Developer')),
298 dict(name
='Clément Pit--Claudel', title
=N_('Developer')),
299 dict(name
='Daniel Haskin', title
=N_('Developer')),
300 dict(name
='Daniel King', title
=N_('Developer')),
301 dict(name
='Daniel Pavel', title
=N_('Developer')),
302 dict(name
='David Zumbrunnen', title
=N_('Developer')),
303 dict(name
='George Vasilakos', title
=N_('Developer')),
304 dict(name
='Ilya Tumaykin', title
=N_('Developer')),
305 dict(name
='Iulian Udrea', title
=N_('Developer')),
306 dict(name
='Jake Biesinger', title
=N_('Developer')),
307 dict(name
='Jakub Szymański', title
=N_('Developer')),
308 dict(name
='Jamie Pate', title
=N_('Developer')),
309 dict(name
='Jean-Francois Dagenais', title
=N_('Developer')),
310 dict(name
='Karthik Manamcheri', title
=N_('Developer')),
311 dict(name
='Kelvie Wong', title
=N_('Developer')),
312 dict(name
='Kyle', title
=N_('Developer')),
313 dict(name
='Maciej Filipiak', title
=N_('Developer')),
314 dict(name
='Maicon D. Filippsen', title
=N_('Developer')),
315 dict(name
='Markus Heidelberg', title
=N_('Developer')),
316 dict(name
='Matthew E. Levine', title
=N_('Developer')),
317 dict(name
='Matthias Mailänder', title
=N_('Developer')),
318 dict(name
='Md. Mahbub Alam', title
=N_('Developer')),
319 dict(name
='Mikhail Terekhov', title
=N_('Developer')),
320 dict(name
='Paul Hildebrandt', title
=N_('Developer')),
321 dict(name
='Paul Weingardt', title
=N_('Developer')),
322 dict(name
='Paulo Fidalgo', title
=N_('Developer')),
323 dict(name
='Petr Gladkikh', title
=N_('Developer')),
324 dict(name
='Philip Stark', title
=N_('Developer')),
325 dict(name
='Radek Postołowicz', title
=N_('Developer')),
326 dict(name
='Rainer Müller', title
=N_('Developer')),
327 dict(name
='Rolando Espinoza', title
=N_('Developer')),
328 dict(name
="Samsul Ma'arif", title
=N_('Developer')),
329 dict(name
='Sebastian Brass', title
=N_('Developer')),
330 dict(name
='Vaibhav Sagar', title
=N_('Developer')),
331 dict(name
='Ved Vyas', title
=N_('Developer')),
332 dict(name
='Voicu Hodrea', title
=N_('Developer')),
333 dict(name
='Wesley Wong', title
=N_('Developer')),
334 dict(name
='Wolfgang Ocker', title
=N_('Developer')),
335 dict(name
='Zhang Han', title
=N_('Developer')),
336 dict(name
='beauxq', title
=N_('Developer')),
337 dict(name
='ochristi', title
=N_('Developer')),
339 bug_url
= 'https://github.com/git-cola/git-cola/issues'
340 bug_link
= link(bug_url
, bug_url
)
341 scope
= dict(bug_link
=bug_link
)
344 Please use %(bug_link)s to report issues.
348 return contributors_text(authors
, prelude
=prelude
)
351 def translators_text():
352 palette
= QtGui
.QPalette()
353 contact
= N_('Email contributor')
356 # See the `generate-about` script in the "todo" branch.
357 # vim :read! ./Meta/generate-about --translators
358 dict(name
='V字龍(Vdragon)',
359 title
=N_('Traditional Chinese (Taiwan) translation'),
360 email
=mailto('Vdragon.Taiwan@gmail.com', contact
, palette
)),
361 dict(name
='Pavel Rehak',
362 title
=N_('Czech translation')),
363 dict(name
='Vitor Lobo',
364 title
=N_('Brazilian translation')),
365 dict(name
='Zhang Han',
366 title
=N_('Simplified Chinese translation')),
367 dict(name
='Igor Kopach',
368 title
=N_('Ukranian translation')),
369 dict(name
='Barış ÇELİK',
370 title
=N_('Turkish translation')),
371 dict(name
='Minarto Margoliono',
372 title
=N_('Indonesian translation')),
373 dict(name
='Rafael Nascimento',
374 title
=N_('Brazilian translation')),
375 dict(name
='Sven Claussner',
376 title
=N_('German translation')),
378 title
=N_('Russian translation')),
379 dict(name
='Victorhck',
380 title
=N_('Spanish translation')),
381 dict(name
='Guo Yunhe',
382 title
=N_('Simplified Chinese translation')),
383 dict(name
='Kai Krakow',
384 title
=N_('German translation')),
385 dict(name
='Louis Rousseau',
386 title
=N_('French translation')),
387 dict(name
='Mickael Albertus',
388 title
=N_('French translation')),
389 dict(name
='Peter Dave Hello',
390 title
=N_('Traditional Chinese (Taiwan) translation')),
391 dict(name
='Pilar Molina Lopez',
392 title
=N_('Spanish translation')),
393 dict(name
="Samsul Ma'arif",
394 title
=N_('Indonesian translation')),
396 title
=N_('Spanish translation')),
398 title
=N_('Hungarian translation')),
400 title
=N_('Czech translation')),
401 dict(name
='Łukasz Wojniłowicz',
402 title
=N_('Polish translation')),
405 bug_url
= 'https://github.com/git-cola/git-cola/issues'
406 bug_link
= link(bug_url
, bug_url
)
407 scope
= dict(bug_link
=bug_link
)
411 Git Cola has been translated into different languages thanks
412 to the help of the individuals listed below.
416 Translation is approximate. If you find a mistake,
417 please let us know by opening an issue on Github:
426 We invite you to participate in translation by adding or updating
427 a translation and opening a pull request.
433 return contributors_text(translators
, prelude
=prelude
)
436 def show_shortcuts():
437 hotkeys_html
= resources
.doc(N_('hotkeys.html'))
439 from qtpy
import QtWebEngineWidgets
440 except (ImportError, qtpy
.PythonQtError
):
441 # redhat disabled QtWebKit in their qt build but don't punish the users
442 webbrowser
.open_new_tab('file://' + hotkeys_html
)
445 html
= core
.read(hotkeys_html
)
447 parent
= qtutils
.active_window()
448 widget
= QtWidgets
.QDialog()
449 widget
.setWindowModality(Qt
.WindowModal
)
450 widget
.setWindowTitle(N_('Shortcuts'))
452 web
= QtWebEngineWidgets
.QWebEngineView(parent
)
455 layout
= qtutils
.hbox(defs
.no_margin
, defs
.spacing
, web
)
456 widget
.setLayout(layout
)
457 widget
.resize(800, min(parent
.height(), 600))
458 qtutils
.add_action(widget
, N_('Close'), widget
.accept
,
459 hotkeys
.QUESTION
, *hotkeys
.ACCEPT
)