1 """The only file where icon filenames are mentioned"""
3 from __future__
import absolute_import
, division
, unicode_literals
10 from . import resources
11 from .compat
import ustr
12 from .decorators
import memoize
15 KNOWN_FILE_MIME_TYPES
= [
16 ('text', 'file-code.svg'),
17 ('image', 'file-media.svg'),
18 ('python', 'file-code.svg'),
19 ('ruby', 'file-code.svg'),
20 ('shell', 'file-code.svg'),
21 ('perl', 'file-code.svg'),
22 ('octet', 'file-binary.svg'),
25 KNOWN_FILE_EXTENSIONS
= {
26 '.java': 'file-code.svg',
27 '.groovy': 'file-code.svg',
28 '.cpp': 'file-code.svg',
29 '.c': 'file-code.svg',
30 '.h': 'file-code.svg',
31 '.cxx': 'file-code.svg',
35 def install(icon_themes
):
36 for theme
in icon_themes
:
37 icon_dir
= resources
.icon_dir(theme
)
38 qtcompat
.add_search_path('icons', icon_dir
)
41 def name_from_basename(basename
):
42 """Prefix the basename with "icons:" so that git-cola's icons are found
44 "icons" is registered with Qt's resource system during install().
47 return 'icons:' + basename
52 """Return a QIcon from an absolute filename or "icons:basename.svg" name"""
53 return QtGui
.QIcon(name
)
57 """Given a basename returns a QIcon from the corresponding cola icon"""
58 return from_name(name_from_basename(basename
))
62 def from_theme(name
, fallback
=None):
63 """Grab an icon from the current theme with a fallback
65 Support older versions of Qt checking for fromTheme's availability.
68 if hasattr(QtGui
.QIcon
, 'fromTheme'):
69 base
, ext
= os
.path
.splitext(name
)
71 qicon
= QtGui
.QIcon
.fromTheme(base
, icon(fallback
))
73 qicon
= QtGui
.QIcon
.fromTheme(base
)
74 if not qicon
.isNull():
76 return icon(fallback
or name
)
79 def basename_from_filename(filename
):
80 """Returns an icon name based on the filename"""
81 mimetype
= mimetypes
.guess_type(filename
)[0]
82 if mimetype
is not None:
83 mimetype
= mimetype
.lower()
84 for filetype
, icon_name
in KNOWN_FILE_MIME_TYPES
:
85 if filetype
in mimetype
:
87 extension
= os
.path
.splitext(filename
)[1]
88 return KNOWN_FILE_EXTENSIONS
.get(extension
.lower(), 'file-text.svg')
91 def from_filename(filename
):
92 basename
= basename_from_filename(filename
)
93 return from_name(name_from_basename(basename
))
96 def mkicon(icon
, default
=None):
97 if icon
is None and default
is not None:
99 elif icon
and isinstance(icon
, (str, ustr
)):
100 icon
= QtGui
.QIcon(icon
)
106 """Maintain a cache of standard icons and return cache entries."""
107 style
= QtGui
.QApplication
.instance().style()
108 return style
.standardIcon(key
)
111 def status(filename
, deleted
, staged
, untracked
):
113 icon_name
= 'circle-slash-red.svg'
115 icon_name
= 'staged.svg'
117 icon_name
= 'question-plain.svg'
119 icon_name
= basename_from_filename(filename
)
123 # Icons creators and SVG file references
126 return from_theme('list-add', fallback
='plus.svg')
130 return icon('git-branch.svg')
134 return name_from_basename('check.svg')
142 return from_theme('git-cola.svg')
146 return icon('git-compare.svg')
150 return from_theme('configure', fallback
='gear.svg')
154 return from_theme('edit-copy.svg')
158 return icon('telescope.svg')
162 return name_from_basename('primitive-dot.svg')
166 return icon('file-download.svg')
170 return icon('trashcan.svg')
173 # folder vs directory: directory is opaque, folder is just an outline
174 # directory is used for the File Browser, where more contrast with the file
178 return icon('folder.svg')
182 return icon('file-directory.svg')
186 return icon('diff.svg')
190 return icon('pencil.svg')
194 return icon('ellipsis.svg')
198 return icon('link-external.svg')
202 return icon('file-code.svg')
206 return icon('file-text.svg')
210 return icon('file-zip.svg')
214 return icon('fold.svg')
218 return icon('git-merge.svg')
222 return name_from_basename('modified.svg')
226 return icon('folder-new.svg')
230 return icon('check.svg')
233 def open_directory():
234 return icon('folder.svg')
238 return name_from_basename('partial.svg')
242 return icon('repo-pull.svg')
246 return icon('repo-push.svg')
250 return icon('question.svg')
254 return from_theme('list-remove', fallback
='circle-slash.svg')
258 return icon('repo.svg')
262 return icon('desktop-download.svg')
266 return icon('search.svg')
270 return from_theme('edit-select-all.svg')
274 return icon('staged.svg')
278 return name_from_basename('staged.svg')
282 return icon('star.svg')
286 return icon('sync.svg')
290 return icon('tag.svg')
294 return from_theme('edit-undo', fallback
='edit-undo.svg')
298 return icon('unfold.svg')
302 return icon('eye.svg')
306 return name_from_basename('upstream.svg')
310 return from_theme('zoom-fit-best.svg')
314 return from_theme('zoom-in.svg')
318 return from_theme('zoom-out.svg')