1 """The only file where icon filenames are mentioned"""
2 from __future__
import absolute_import
, division
, print_function
, unicode_literals
6 from qtpy
import QtWidgets
9 from . import decorators
10 from . import qtcompat
11 from . import resources
12 from .compat
import ustr
16 KNOWN_FILE_MIME_TYPES
= [
17 ('text', 'file-code.svg'),
18 ('image', 'file-media.svg'),
19 ('octet', 'file-binary.svg'),
22 KNOWN_FILE_EXTENSIONS
= {
23 '.bash': 'file-code.svg',
24 '.c': 'file-code.svg',
25 '.cpp': 'file-code.svg',
26 '.css': 'file-code.svg',
27 '.cxx': 'file-code.svg',
28 '.h': 'file-code.svg',
29 '.hpp': 'file-code.svg',
30 '.hs': 'file-code.svg',
31 '.html': 'file-code.svg',
32 '.java': 'file-code.svg',
33 '.js': 'file-code.svg',
34 '.ksh': 'file-code.svg',
35 '.lisp': 'file-code.svg',
36 '.perl': 'file-code.svg',
37 '.pl': 'file-code.svg',
38 '.py': 'file-code.svg',
39 '.rb': 'file-code.svg',
40 '.rs': 'file-code.svg',
41 '.sh': 'file-code.svg',
42 '.zsh': 'file-code.svg',
48 icon_dir
= resources
.icon_dir(theme
)
49 qtcompat
.add_search_path('icons', icon_dir
)
54 (N_('Default'), 'default'),
55 (N_('Dark Theme'), 'dark'),
56 (N_('Light Theme'), 'light'),
60 def name_from_basename(basename
):
61 """Prefix the basename with "icons:" so that git-cola's icons are found
63 "icons" is registered with Qt's resource system during install().
66 return 'icons:' + basename
71 """Return a QIcon from an absolute filename or "icons:basename.svg" name"""
72 return QtGui
.QIcon(name
)
76 """Given a basename returns a QIcon from the corresponding cola icon"""
77 return from_name(name_from_basename(basename
))
80 def from_theme(name
, fallback
=None):
81 """Grab an icon from the current theme with a fallback
83 Support older versions of Qt checking for fromTheme's availability.
86 if hasattr(QtGui
.QIcon
, 'fromTheme'):
87 base
, _
= os
.path
.splitext(name
)
89 qicon
= QtGui
.QIcon
.fromTheme(base
, icon(fallback
))
91 qicon
= QtGui
.QIcon
.fromTheme(base
)
92 if not qicon
.isNull():
94 return icon(fallback
or name
)
97 def basename_from_filename(filename
):
98 """Returns an icon name based on the filename"""
99 mimetype
= core
.guess_mimetype(filename
)
100 if mimetype
is not None:
101 mimetype
= mimetype
.lower()
102 for filetype
, icon_name
in KNOWN_FILE_MIME_TYPES
:
103 if filetype
in mimetype
:
105 extension
= os
.path
.splitext(filename
)[1]
106 return KNOWN_FILE_EXTENSIONS
.get(extension
.lower(), 'file-text.svg')
109 def from_filename(filename
):
110 """Return a QIcon from a filename"""
111 basename
= basename_from_filename(filename
)
112 return from_name(name_from_basename(basename
))
115 def mkicon(value
, default
=None):
116 """Create an icon from a string value"""
117 if value
is None and default
is not None:
119 elif value
and isinstance(value
, (str, ustr
)):
120 value
= QtGui
.QIcon(value
)
125 """Maintain a cache of standard icons and return cache entries."""
126 style
= QtWidgets
.QApplication
.instance().style()
127 return style
.standardIcon(key
)
130 def status(filename
, deleted
, is_staged
, untracked
):
131 """Status icon for a file"""
133 icon_name
= 'circle-slash-red.svg'
135 icon_name
= 'staged.svg'
137 icon_name
= 'question-plain.svg'
139 icon_name
= basename_from_filename(filename
)
143 # Icons creators and SVG file references
147 """Three-bars icon"""
148 return icon('three-bars.svg')
153 return from_theme('list-add', fallback
='plus.svg')
157 """Alphabetical icon"""
158 return from_theme('view-sort', fallback
='a-z-order.svg')
163 return icon('git-branch.svg')
167 """Checkmark icon name"""
168 return name_from_basename('check.svg')
172 """Cherry-pick icon"""
173 return icon('git-commit.svg')
176 def circle_slash_red():
177 """A circle with a slash through it"""
178 return icon('circle-slash-red.svg')
188 return icon('git-cola.svg')
193 return icon('document-save-symbolic.svg')
198 return icon('git-compare.svg')
203 return icon('gear.svg')
208 return from_theme('edit-cut', fallback
='edit-cut.svg')
213 return from_theme('edit-copy', fallback
='edit-copy.svg')
218 return from_theme('edit-paste', fallback
='edit-paste.svg')
223 return icon('play.svg')
228 return from_theme('edit-delete', fallback
='trashcan.svg')
232 """Default app icon"""
233 return icon('telescope.svg')
238 return name_from_basename('primitive-dot.svg')
243 return icon('file-download.svg')
248 return from_theme('delete', fallback
='trashcan.svg')
251 # folder vs directory: directory is opaque, folder is just an outline
252 # directory is used for the File Browser, where more contrast with the file
258 return from_theme('folder', fallback
='folder.svg')
263 return from_theme('folder', fallback
='file-directory.svg')
268 return icon('diff.svg')
273 return from_theme('document-edit', fallback
='pencil.svg')
278 return icon('ellipsis.svg')
282 """External link icon"""
283 return icon('link-external.svg')
288 return icon('file-code.svg')
293 return icon('file-text.svg')
297 """Zip file / tarball icon"""
298 return icon('file-zip.svg')
303 return icon('fold.svg')
308 return icon('git-merge.svg')
313 return icon('modified.svg')
317 """Modified icon name"""
318 return name_from_basename('modified.svg')
323 return from_theme('go-next', fallback
='arrow-down.svg')
328 return from_theme('go-previous', fallback
='arrow-up.svg')
332 """Add new/add-to-list icon"""
333 return from_theme('list-add', fallback
='folder-new.svg')
338 return from_theme('checkmark', fallback
='check.svg')
341 def open_directory():
342 """Open directory icon"""
343 return from_theme('folder', fallback
='folder.svg')
348 return icon('arrow-up.svg')
352 """Go to next item icon"""
353 return icon('arrow-down.svg')
357 """Partial icon name"""
358 return name_from_basename('partial.svg')
363 return icon('repo-pull.svg')
368 return icon('repo-push.svg')
373 return icon('question.svg')
378 return from_theme('list-remove', fallback
='circle-slash.svg')
382 """Repository icon"""
383 return icon('repo.svg')
386 def reverse_chronological():
387 """Reverse chronological icon"""
388 return icon('last-first-order.svg')
393 return from_theme('document-save', fallback
='desktop-download.svg')
398 return from_theme('search', fallback
='search.svg')
402 """Select all icon"""
403 return from_theme('edit-select-all', fallback
='edit-select-all')
408 return icon('staged.svg')
412 """Staged icon name"""
413 return name_from_basename('staged.svg')
418 return icon('star.svg')
422 """Sync/update icon"""
423 return icon('sync.svg')
428 return icon('tag.svg')
433 return icon('terminal.svg')
438 return from_theme('edit-undo', fallback
='edit-undo.svg')
443 return from_theme('edit-redo', fallback
='edit-redo.svg')
446 def style_dialog_apply():
447 """Apply icon from the current style"""
448 return from_style(QtWidgets
.QStyle
.SP_DialogApplyButton
)
451 def style_dialog_discard():
452 """Discard icon for the current style"""
453 return from_style(QtWidgets
.QStyle
.SP_DialogDiscardButton
)
456 def style_dialog_reset():
457 """Reset icon for the current style"""
458 return from_style(QtWidgets
.QStyle
.SP_DialogResetButton
)
462 """Expand/unfold icon"""
463 return icon('unfold.svg')
467 """An eye icon to represent visualization"""
468 return icon('eye.svg')
472 """Upstream branch icon name"""
473 return name_from_basename('upstream.svg')
477 """Zoom-to-fit icon"""
478 return from_theme('zoom-fit-best', fallback
='zoom-fit-best.svg')
483 return from_theme('zoom-in', fallback
='zoom-in.svg')
488 return from_theme('zoom-out', fallback
='zoom-out.svg')