appman-vala/src/IconDirectory.vala

193 lines
6.6 KiB
Vala

/**
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
namespace Appman {
private class IconDirectory : GLib.Object {
private int size;
private IconDirectoryType type;
private int max_size;
private int min_size;
private int threshold;
private string directory;
private GLib.HashTable<string, string> icons;
private bool valid;
public IconDirectory(string[, ] properties, string directory_abs) {
//
valid = true;
directory = directory_abs;
icons = new GLib.HashTable<string, string>(s => s.hash(), (a,b) => a == b);
// Set some defaults, which we will override with values
// from matrix.
size = -1;
type = IconDirectoryType.Threshold;
max_size = -1;
min_size = -1;
threshold = 2;
// Scan all icons in given directory
create_icon_list();
if (!valid) {
return;
}
// Read values from matrix
scan_matrix(properties);
if (!valid) {
return;
}
}
private void scan_matrix(string[, ] matrix) {
for (int i = 0; i < matrix.length[0]; i++) {
string key = matrix[i, 0].down();
if (key == "size") {
size = int.parse(matrix[i, 1]);
} else if (key == "type") {
string val = matrix[i, 1].down();
if (val == "fixed") {
type = IconDirectoryType.Fixed;
} else if (val == "scalable") {
type = IconDirectoryType.Scalable;
} else if (val == "threshold") {
type = IconDirectoryType.Threshold;
}
} else if (key == "maxsize") {
max_size = int.parse(matrix[i, 1]);
} else if (key == "minsize") {
min_size = int.parse(matrix[i, 1]);
} else if (key == "threshold") {
threshold = int.parse(matrix[i, 1]);
}
// It is totally okay if there are other keys.
// Most themes include a "Context=" key.
// But we're not interested in that.
}
// The only value that is mandatory to be set is 'Size'
if (size == -1) {
valid = false;
return;
}
// If 'Type' has not been set it is already set
// to 'Threshold'.
// If 'Threshold' has not been set it is already set
// to 2.
// If 'MaxSize' or 'MinSize' has not been set
// we set it to 'Size'.
if (max_size == -1) {
max_size = size;
}
if (min_size == -1) {
min_size = size;
}
}
private void create_icon_list() {
GLib.File dir = GLib.File.new_for_path(directory);
try {
FileEnumerator child_enum = dir.enumerate_children(
GLib.FileAttribute.STANDARD_NAME,
GLib.FileQueryInfoFlags.NONE);
GLib.FileInfo child_info;
while ((child_info = child_enum.next_file()) != null) {
string child_name = child_info.get_name();
string child_name_d = child_name.down();
if (child_name_d.has_suffix(".png") ||
child_name_d.has_suffix(".jpg") ||
child_name_d.has_suffix(".svg") ||
child_name_d.has_suffix(".xpm")) {
string child_name_key = child_name.substring(0, child_name.length-4);
this.icons.insert(child_name_key, directory+"/"+child_name);
}
}
} catch (Error e) {
// This probably means that a directory that is given
// in the index.theme file is not present.
// We just silently ignore this.
valid = false;
return;
}
}
public bool is_valid() {
return valid;
}
public bool is_scalable() {
if (type == IconDirectoryType.Scalable) {
return true;
}
return false;
}
public int maximum_size() {
switch (type) {
case IconDirectoryType.Fixed:
return size;
case IconDirectoryType.Scalable:
return max_size;
case IconDirectoryType.Threshold:
return size+threshold;
default:
return 0;
}
}
public string? get_icon(string name) {
if (!valid) {
return null;
}
string icon_path = null;
bool found_icon = icons.lookup_extended(name, null, out icon_path);
if (found_icon) {
return icon_path;
}
return null;
}
/* Calculate icon size from path */
public int get_icon_size() {
int size = 0;
int index = 2;
for (int j = 0; j < 4; j++) { index = directory.index_of_char('/', index) + 1; }
string psize = directory.substring(index, directory.index_of_char('/', index)-index);
index = psize.index_of_char('x');
if (index > 0) size = int.parse(psize.substring(0,index));
return size;
}
}
private enum IconDirectoryType {
Fixed,
Scalable,
Threshold;
}
}