1 """The only file where icon filenames are mentioned"""
3 from __future__
import absolute_import
, division
, unicode_literals
8 from qtpy
import QtWidgets
10 from . import qtcompat
11 from . import resources
12 from .compat
import ustr
13 from .decorators
import memoize
17 KNOWN_FILE_MIME_TYPES
= [
18 ('text', 'file-code.svg'),
19 ('image', 'file-media.svg'),
20 ('octet', 'file-binary.svg'),
23 KNOWN_FILE_EXTENSIONS
= {
24 '.bash': 'file-code.svg',
25 '.c': 'file-code.svg',
26 '.cpp': 'file-code.svg',
27 '.css': 'file-code.svg',
28 '.cxx': 'file-code.svg',
29 '.h': 'file-code.svg',
30 '.hpp': 'file-code.svg',
31 '.hs': 'file-code.svg',
32 '.html': 'file-code.svg',
33 '.java': 'file-code.svg',
34 '.js': 'file-code.svg',
35 '.ksh': 'file-code.svg',
36 '.lisp': 'file-code.svg',
37 '.perl': 'file-code.svg',
38 '.pl': 'file-code.svg',
39 '.py': 'file-code.svg',
40 '.rb': 'file-code.svg',
41 '.rs': 'file-code.svg',
42 '.sh': 'file-code.svg',
43 '.zsh': 'file-code.svg',
49 icon_dir
= resources
.icon_dir(theme
)
50 qtcompat
.add_search_path('icons', icon_dir
)
55 (N_('Default'), 'default'),
56 (N_('Dark Theme'), 'dark'),
57 (N_('Light Theme'), 'light'),
61 def name_from_basename(basename
):
62 """Prefix the basename with "icons:" so that git-cola's icons are found
64 "icons" is registered with Qt's resource system during install().
67 return 'icons:' + basename
72 """Return a QIcon from an absolute filename or "icons:basename.svg" name"""
73 return QtGui
.QIcon(name
)
77 """Given a basename returns a QIcon from the corresponding cola icon"""
78 return from_name(name_from_basename(basename
))
82 def from_theme(name
, fallback
=None):
83 """Grab an icon from the current theme with a fallback
85 Support older versions of Qt checking for fromTheme's availability.
88 if hasattr(QtGui
.QIcon
, 'fromTheme'):
89 base
, _
= os
.path
.splitext(name
)
91 qicon
= QtGui
.QIcon
.fromTheme(base
, icon(fallback
))
93 qicon
= QtGui
.QIcon
.fromTheme(base
)
94 if not qicon
.isNull():
96 return icon(fallback
or name
)
99 def basename_from_filename(filename
):
100 """Returns an icon name based on the filename"""
101 mimetype
= mimetypes
.guess_type(filename
)[0]
102 if mimetype
is not None:
103 mimetype
= mimetype
.lower()
104 for filetype
, icon_name
in KNOWN_FILE_MIME_TYPES
:
105 if filetype
in mimetype
:
107 extension
= os
.path
.splitext(filename
)[1]
108 return KNOWN_FILE_EXTENSIONS
.get(extension
.lower(), 'file-text.svg')
111 def from_filename(filename
):
112 basename
= basename_from_filename(filename
)
113 return from_name(name_from_basename(basename
))
116 def mkicon(value
, default
=None):
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
):
132 icon_name
= 'circle-slash-red.svg'
134 icon_name
= 'staged.svg'
136 icon_name
= 'question-plain.svg'
138 icon_name
= basename_from_filename(filename
)
142 # Icons creators and SVG file references
145 return from_theme('list-add', fallback
='plus.svg')
149 return icon('a-z-order.svg')
153 return icon('git-branch.svg')
157 return name_from_basename('check.svg')
165 return icon('git-cola.svg')
169 return icon('document-save-symbolic.svg')
173 return icon('git-compare.svg')
177 return from_theme('configure', fallback
='gear.svg')
181 return from_theme('edit-copy.svg')
185 return icon('telescope.svg')
189 return name_from_basename('primitive-dot.svg')
193 return icon('file-download.svg')
197 return icon('trashcan.svg')
200 # folder vs directory: directory is opaque, folder is just an outline
201 # directory is used for the File Browser, where more contrast with the file
205 return icon('folder.svg')
209 return icon('file-directory.svg')
213 return icon('diff.svg')
217 return icon('pencil.svg')
221 return icon('ellipsis.svg')
225 return icon('link-external.svg')
229 return icon('file-code.svg')
233 return icon('file-text.svg')
237 return icon('file-zip.svg')
241 return icon('fold.svg')
245 return icon('git-merge.svg')
249 return icon('modified.svg')
253 return name_from_basename('modified.svg')
257 return icon('folder-new.svg')
261 return icon('check.svg')
264 def open_directory():
265 return icon('folder.svg')
269 return name_from_basename('partial.svg')
273 return icon('repo-pull.svg')
277 return icon('repo-push.svg')
281 return icon('question.svg')
285 return from_theme('list-remove', fallback
='circle-slash.svg')
289 return icon('repo.svg')
292 def reverse_chronological():
293 return icon('last-first-order.svg')
297 return icon('desktop-download.svg')
301 return icon('search.svg')
305 return from_theme('edit-select-all.svg')
309 return icon('staged.svg')
313 return name_from_basename('staged.svg')
317 return icon('star.svg')
321 return icon('sync.svg')
325 return icon('tag.svg')
329 return from_theme('edit-undo', fallback
='edit-undo.svg')
333 return icon('unfold.svg')
337 return icon('eye.svg')
341 return name_from_basename('upstream.svg')
345 return icon('zoom-fit-best.svg')
349 return icon('zoom-in.svg')
353 return icon('zoom-out.svg')