47 private $Type =
'Threshold';
51 private $Threshold = 2;
53 function __construct ($infos)
55 $this->Size = $infos[
'Size'];
56 $this->MinSize = $infos[
'Size'];
57 $this->MaxSize = $infos[
'Size'];
58 foreach ([
'Type',
'MaxSize',
'MinSize',
'Threshold'] as $key) {
59 if (isset($infos[$key])) {
60 $this->$key = $infos[$key];
64 if ($this->Type ==
'Threshold') {
65 $this->MinSize = $this->Size - $this->Threshold;
66 $this->MaxSize = $this->Size + $this->Threshold;
70 function MatchesSize ($size)
72 switch ($this->Type) {
74 return ($this->Size == $size);
78 return (($this->MinSize <= $size) && ($size <= $this->MaxSize));
82 function SizeDistance ($size)
84 switch ($this->Type) {
86 return abs($this->Size - $size);
90 if ($size < $this->MinSize) {
91 return $this->MinSize - $size;
93 if ($size > $this->MaxSize) {
94 return $size - $this->MaxSize;
107 private $subdirs = [];
111 function __construct ($folder, $default_parent)
113 $this->path = $folder;
114 $datas = @parse_ini_file($folder .
'/index.theme', TRUE, INI_SCANNER_RAW);
115 if ($datas === FALSE) {
118 if (isset($datas[
'Icon Theme'][
'Directories']) && !empty($datas[
'Icon Theme'][
'Directories'])) {
119 $dirs = preg_split(
'/,/', $datas[
'Icon Theme'][
'Directories']);
120 foreach ($dirs as $name) {
121 if (isset($datas[$name])) {
122 $this->subdirs[strtolower($datas[$name][
'Context'])][$name] =
new IconThemeDir($datas[$name]);
127 if (isset($datas[
'Icon Theme'][
'Inherits'])) {
128 $this->parent = $datas[
'Icon Theme'][
'Inherits'];
130 $this->parent = $default_parent;
134 function FindIcon ($context, $icon, $size)
136 $context = strtolower($context);
137 return $this->FindIconHelper($context, $icon, $size);
140 function FindIconHelper ($context, $icon, $size)
142 $filename = $this->LookupIcon($context, $icon, $size);
143 if ($filename != NULL) {
146 if (isset(static::$fallbacks[$context .
'/' . $icon])) {
147 foreach (static::$fallbacks[$context .
'/' . $icon] as $fallback) {
148 $filename = $this->LookupIcon($fallback[0], $fallback[1], $size);
149 if ($filename != NULL) {
155 if ($this->parent !== NULL) {
156 $parentTheme = $this->findTheme($this->parent);
157 if ($parentTheme === NULL) {
158 $parentTheme = $this->findTheme(static::$default_theme);
160 return $parentTheme->FindIconHelper($context, $icon, $size);
166 function LookupIcon ($context, $iconname, $size)
168 if (!isset($this->subdirs[$context])) {
171 foreach ($this->subdirs[$context] as $path => &$subdir) {
172 if ($subdir->MatchesSize($size)) {
173 foreach (static::$extensions as $extension) {
174 $filename = $this->path .
'/' . $path .
'/' . $iconname .
'.' . $extension;
175 if (file_exists($filename)) {
182 if (static::$find_closest) {
183 $minimal_size = PHP_INT_MAX;
184 foreach ($this->subdirs[$context] as $path => &$subdir) {
185 if (($sizedistance = $subdir->SizeDistance($size)) < $minimal_size) {
186 foreach (static::$extensions as $extension) {
187 $filename = $this->path .
'/' . $path .
'/' . $iconname .
'.' . $extension;
188 if (file_exists($filename)) {
189 $closest_filename = $filename;
190 $minimal_size = $sizedistance;
196 if (isset($closest_filename)) {
197 return $closest_filename;
203 static public $default_theme =
'breezy';
204 static public $extensions = [
'png',
'xpm',
'svg'];
205 static public $find_closest = FALSE;
208 static public $session_var =
'IconThemes';
210 static public function loadThemes ($path)
213 if ($dir = opendir(
"$path")) {
214 while (($file = readdir($dir)) !== FALSE) {
215 if (file_exists(
"$path/$file/index.theme") && !preg_match(
"/^\./", $file)) {
217 if ($file == static::$default_theme) {
218 $themes[$file] =
new IconTheme(
"$path/$file", NULL);
220 $themes[$file] =
new IconTheme(
"$path/$file", static::$default_theme);
228 $_SESSION[static::$session_var] = $themes;
231 static public function findThemeIcon ($theme, $context, $icon, $size)
234 if (!preg_match(
'/^[a-zA-Z0-9_\-]+$/', $icon)) {
235 trigger_error(
'Error: Wrong icon name received');
236 die(
'Error: wrong icon name received');
238 if (!isset($_SESSION[static::$session_var])) {
239 trigger_error(
'Error: no theme found in session');
240 die(
'Error: no theme found in session');
242 if (isset($_SESSION[static::$session_var][$theme])) {
243 return $_SESSION[static::$session_var][$theme]->FindIcon($context, $icon, $size);
245 return $_SESSION[static::$session_var][static::$default_theme]->FindIcon($context, $icon, $size);
248 public function findTheme ($theme)
250 if (isset($_SESSION[static::$session_var][$theme])) {
251 return $_SESSION[static::$session_var][$theme];
257 static public $fallbacks = [
258 'types/user-group' => [
259 [
'applications',
'system-users']
261 'types/resource-group' => [
262 [
'actions',
'resource-group']
265 [
'places',
'user-identity'],
266 [
'status',
'avatar-default'],
269 [
'mimetypes',
'x-office-contact'],
271 'types/certificate' => [
272 [
'mimetypes',
'stock_certificate'],
273 [
'mimetypes',
'application-certificate'],
274 [
'actions',
'view-certificate'],
276 'applications/user-info' => [
277 [
'actions',
'user-properties'],
278 [
'types',
'contact'],
279 [
'mimetypes',
'x-office-contact'],
281 [
'places',
'user-identity'],
282 [
'status',
'avatar-default'],
284 'applications/office-calendar' => [
285 [
'mimetypes',
'x-office-calendar'],
287 'applications/os-linux' => [
288 [
'applications',
'linux'],
290 'applications/os-windows' => [
291 [
'applications',
'windows'],
293 'applications/samba' => [
294 [
'applications',
'os-windows'],
295 [
'applications',
'windows'],
297 'applications/config-language' => [
298 [
'applications',
'locale'],
299 [
'applications',
'preferences-desktop-locale'],
301 'mimetypes/text-csv' => [
302 [
'mimetypes',
'x-office-spreadsheet'],
303 [
'mimetypes',
'text-x-generic'],
305 'mimetypes/application-pdf' => [
306 [
'mimetypes',
'x-office-document'],
308 'actions/application-exit' => [
309 [
'actions',
'system-log-out'],
311 'actions/archive' => [
312 [
'mimetypes',
'application-x-archive'],
314 'actions/document-export' => [
315 [
'actions',
'document-send'],
317 'actions/download' => [
318 [
'actions',
'document-save'],
320 'actions/document-restore' => [
321 [
'actions',
'document-import'],
322 [
'actions',
'document-open'],
324 'actions/document-edit' => [
326 [
'applications',
'text-editor'],
327 [
'applications',
'accessories-text-editor'],
328 [
'actions',
'document-open'],
330 'actions/snapshot' => [
331 [
'actions',
'document-save'],
333 'actions/system-reboot' => [
334 [
'actions',
'view-refresh'],
336 'actions/system-update' => [
337 [
'applications',
'system-software-update'],
339 'actions/system-reinstall' => [
340 [
'applications',
'system-installer'],
342 'actions/task-start' => [
343 [
'actions',
'media-playback-start'],
345 'actions/task-stop' => [
346 [
'actions',
'media-playback-stop'],
348 'actions/task-schedule' => [
349 [
'actions',
'chronometer'],
350 [
'actions',
'smallclock'],
353 [
'actions',
'go-up'],
354 [
'actions',
'arrow-up'],
356 'actions/upload' => [
357 [
'actions',
'document-import'],
361 [
'actions',
'go-down'],
362 [
'actions',
'arrow-down'],
364 'actions/previous' => [
365 [
'actions',
'go-previous'],
366 [
'actions',
'arrow-left'],
369 [
'actions',
'go-next'],
370 [
'actions',
'arrow-right'],
372 'actions/submit' => [
373 [
'actions',
'go-jump'],
375 'categories/settings' => [
376 [
'categories',
'gnome-settings'],
377 [
'categories',
'preferences-other'],
378 [
'categories',
'preferences-system'],
380 'categories/checks' => [
381 [
'actions',
'view-task'],
382 [
'actions',
'view-calendar-tasks'],
383 [
'actions',
'checkbox'],
384 [
'status',
'task-complete'],
386 'devices/server' => [
387 [
'places',
'server'],
388 [
'places',
'network-server'],
390 'devices/media-cdrom' => [
391 [
'devices',
'media-optical'],
393 'devices/terminal' => [
394 [
'applications',
'utilities-terminal'],
396 'devices/computer-windows' => [
397 [
'applications',
'os-windows'],
398 [
'applications',
'windows'],
400 'devices/template' => [
401 [
'actions',
'document-new'],
403 'status/object-locked' => [
404 [
'status',
'changes-prevent'],
406 'status/object-unlocked' => [
407 [
'status',
'changes-allow'],
409 'status/task-waiting' => [
410 [
'actions',
'task-schedule'],
412 'places/folder-network' => [
413 [
'places',
'folder-remote'],