dag: update column allocation algorithm description
[git-cola.git] / cola / icons.py
blobe7488e04d91f85439e0bc9c8f405f8f310f3fd98
1 """The only file where icon filenames are mentioned"""
3 from __future__ import absolute_import, division, unicode_literals
4 import mimetypes
5 import os
7 from qtpy import QtGui
9 from . import qtcompat
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().
46 """
47 return 'icons:' + basename
50 @memoize
51 def from_name(name):
52 """Return a QIcon from an absolute filename or "icons:basename.svg" name"""
53 return QtGui.QIcon(name)
56 def icon(basename):
57 """Given a basename returns a QIcon from the corresponding cola icon"""
58 return from_name(name_from_basename(basename))
61 @memoize
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.
67 """
68 if hasattr(QtGui.QIcon, 'fromTheme'):
69 base, ext = os.path.splitext(name)
70 if fallback:
71 qicon = QtGui.QIcon.fromTheme(base, icon(fallback))
72 else:
73 qicon = QtGui.QIcon.fromTheme(base)
74 if not qicon.isNull():
75 return qicon
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:
86 return icon_name
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:
98 icon = default()
99 elif icon and isinstance(icon, (str, ustr)):
100 icon = QtGui.QIcon(icon)
101 return icon
104 @memoize
105 def from_style(key):
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):
112 if deleted:
113 icon_name = 'circle-slash-red.svg'
114 elif staged:
115 icon_name = 'staged.svg'
116 elif untracked:
117 icon_name = 'question-plain.svg'
118 else:
119 icon_name = basename_from_filename(filename)
120 return icon_name
123 # Icons creators and SVG file references
125 def add():
126 return from_theme('list-add', fallback='plus.svg')
129 def branch():
130 return icon('git-branch.svg')
133 def check_name():
134 return name_from_basename('check.svg')
137 def close():
138 return icon('x.svg')
141 def cola():
142 return from_theme('git-cola.svg')
145 def compare():
146 return icon('git-compare.svg')
149 def configure():
150 return from_theme('configure', fallback='gear.svg')
153 def copy():
154 return from_theme('edit-copy.svg')
157 def default_app():
158 return icon('telescope.svg')
161 def dot_name():
162 return name_from_basename('primitive-dot.svg')
165 def download():
166 return icon('file-download.svg')
169 def discard():
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
175 # icons are needed.
177 def folder():
178 return icon('folder.svg')
181 def directory():
182 return icon('file-directory.svg')
185 def diff():
186 return icon('diff.svg')
189 def edit():
190 return icon('pencil.svg')
193 def ellipsis():
194 return icon('ellipsis.svg')
197 def external():
198 return icon('link-external.svg')
201 def file_code():
202 return icon('file-code.svg')
205 def file_text():
206 return icon('file-text.svg')
209 def file_zip():
210 return icon('file-zip.svg')
213 def fold():
214 return icon('fold.svg')
217 def merge():
218 return icon('git-merge.svg')
221 def modified_name():
222 return name_from_basename('modified.svg')
225 def new():
226 return icon('folder-new.svg')
229 def ok():
230 return icon('check.svg')
233 def open_directory():
234 return icon('folder.svg')
237 def partial_name():
238 return name_from_basename('partial.svg')
241 def pull():
242 return icon('repo-pull.svg')
245 def push():
246 return icon('repo-push.svg')
249 def question():
250 return icon('question.svg')
253 def remove():
254 return from_theme('list-remove', fallback='circle-slash.svg')
257 def repo():
258 return icon('repo.svg')
261 def save():
262 return icon('desktop-download.svg')
265 def search():
266 return icon('search.svg')
269 def select_all():
270 return from_theme('edit-select-all.svg')
273 def staged():
274 return icon('staged.svg')
277 def staged_name():
278 return name_from_basename('staged.svg')
281 def star():
282 return icon('star.svg')
285 def sync():
286 return icon('sync.svg')
289 def tag():
290 return icon('tag.svg')
293 def undo():
294 return from_theme('edit-undo', fallback='edit-undo.svg')
297 def unfold():
298 return icon('unfold.svg')
301 def visualize():
302 return icon('eye.svg')
305 def upstream_name():
306 return name_from_basename('upstream.svg')
309 def zoom_fit_best():
310 return from_theme('zoom-fit-best.svg')
313 def zoom_in():
314 return from_theme('zoom-in.svg')
317 def zoom_out():
318 return from_theme('zoom-out.svg')