~ubuntu-branches/ubuntu/precise/gnome-do/precise-proposed

« back to all changes in this revision

Viewing changes to Do.Addins/src/Do.UI/IconProvider.cs

  • Committer: Bazaar Package Importer
  • Author(s): Christopher James Halse Rogers
  • Date: 2008-09-14 10:09:40 UTC
  • mto: (0.1.8 sid)
  • mto: This revision was merged to the branch mainline in revision 7.
  • Revision ID: james.westby@ubuntu.com-20080914100940-kyghudg7py14bu2z
Tags: upstream-0.6.0.0
ImportĀ upstreamĀ versionĀ 0.6.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 
20
20
using System;
21
21
using System.IO;
 
22
using System.Reflection;
22
23
using System.Collections.Generic;
23
 
using System.Reflection;
24
24
 
25
25
using Gtk;
26
26
using Gdk;
27
27
 
28
28
namespace Do.UI
29
29
{
30
 
                
31
30
        public static class IconProvider
32
31
        {
33
 
        
34
32
                public static readonly Pixbuf UnknownPixbuf;
35
 
                public const int DefaultIconSize = 80;
 
33
                const int DefaultIconSize = 80;
36
34
                
37
 
                // Cache of loaded icons: key is "iconname_size".
38
 
                static Dictionary<string, Pixbuf> pixbufCache;
39
 
 
40
 
                static IconTheme  [] themes;
41
35
 
42
36
                static IconProvider ()
43
37
                {
44
 
                        pixbufCache = new Dictionary<string, Pixbuf> ();
45
 
                                                
46
38
                        UnknownPixbuf = new Pixbuf (Colorspace.Rgb, true, 8, 1, 1);
47
39
                        UnknownPixbuf.Fill (0x00000000);
48
 
 
49
 
                        themes = new IconTheme  [2];
50
 
                        themes  [0] = IconTheme.Default;
51
 
                        
52
 
                        IconTheme.Default.Changed += OnDefaultIconThemeChanged;
 
40
                }
 
41
                
 
42
                static bool IconIsEmbeddedResource (string name)
 
43
                {
 
44
                        return name.IndexOf ("@") > 0;
 
45
                }
 
46
                
 
47
                static bool IconIsFile (string name)
 
48
                {
 
49
                        return name.StartsWith ("/") ||
 
50
                                   name.StartsWith ("~/") || 
 
51
                                   name.StartsWith ("file://",
 
52
                                        StringComparison.OrdinalIgnoreCase);
 
53
                }
 
54
                
 
55
                static Pixbuf IconFromEmbeddedResource (string name, int size)
 
56
                {
 
57
                        Pixbuf pixbuf = null;
 
58
                        string resource, assemblyName;
 
59
                        
 
60
                        resource = name.Substring (0, name.IndexOf ("@"));
 
61
                        assemblyName = name.Substring (resource.Length + 1);
 
62
                        try {
 
63
                                foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies ()) {
 
64
                                        if (asm.FullName != assemblyName) continue;
 
65
                                        pixbuf = new Pixbuf (asm, resource, size, size);
 
66
                                        break;
 
67
                                }
 
68
                        } catch (Exception e) {
 
69
                                Console.Error.WriteLine ("Failed to load icon resource {0} " +
 
70
                                    "from assembly {1}: {2}", resource, assemblyName, e.Message); 
 
71
                                pixbuf = null;
 
72
                        }
 
73
                        return pixbuf;
 
74
                }
 
75
                
 
76
                static Pixbuf IconFromFile (string name, int size)
 
77
                {
 
78
                        Pixbuf pixbuf;
 
79
                        
 
80
                        name = name.Replace ("~", Paths.UserHome);
 
81
                        try     {
 
82
                                pixbuf = new Pixbuf (name, size, size);
 
83
                        } catch {
 
84
                                pixbuf = null;
 
85
                        }
 
86
                        return pixbuf;
 
87
                }
 
88
                
 
89
                static Pixbuf IconFromTheme (string name, int size, IconTheme theme)
 
90
                {
 
91
                        Pixbuf pixbuf = null;
 
92
                        string name_noext;
 
93
                        
 
94
                        // We may have to remove the extension.
 
95
                        if (name.Contains (".")) {
 
96
                                name_noext = name.Remove (name.LastIndexOf ("."));
 
97
                        } else {
 
98
                                name_noext = name;
 
99
                        }
 
100
                        try     {
 
101
                                if (theme.HasIcon (name)) {  
 
102
                                        pixbuf = theme.LoadIcon (name, size, 0);
 
103
                                } else if (theme.HasIcon (name_noext)) { 
 
104
                                        pixbuf = theme.LoadIcon (name_noext, size, 0);
 
105
                                } else if (name == "gnome-mime-text-plain" &&
 
106
                                           theme.HasIcon ("gnome-mime-text")) { 
 
107
                                        pixbuf = theme.LoadIcon ("gnome-mime-text", size, 0);
 
108
                                }
 
109
                        } catch {
 
110
                                pixbuf = null;
 
111
                        }
 
112
                        
 
113
                        
 
114
                        return pixbuf;
 
115
                }
 
116
                
 
117
                static Pixbuf GenericFileIcon (int size)
 
118
                {
 
119
                        Pixbuf pixbuf = null;
 
120
                        if (IconTheme.Default.HasIcon ("gtk-file")) {
 
121
                                try {
 
122
                                        pixbuf = IconTheme.Default.LoadIcon ("gtk-file", size, 0);
 
123
                                } catch {
 
124
                                        pixbuf = null;                                  
 
125
                                }
 
126
                        }
 
127
                        return pixbuf;
 
128
                }
 
129
                
 
130
                static Pixbuf UnknownIcon (int size)
 
131
                {
 
132
                        Pixbuf pixbuf = null;
 
133
                        
 
134
                        if (IconTheme.Default.HasIcon ("emblem-noread")) {
 
135
                                try {
 
136
                                        pixbuf = IconTheme.Default.LoadIcon ("emblem-noread", size, 0);
 
137
                                } catch {
 
138
                                        pixbuf = null;                                  
 
139
                                }
 
140
                        }
 
141
                        return pixbuf;
53
142
                }
54
143
 
55
144
                public static Pixbuf PixbufFromIconName (string name, int size)
56
145
                {                       
57
146
                        Pixbuf pixbuf;                                                                  
58
 
                        string name_noext, iconKey, resourceName, resourceNamespace;
59
 
                        IconTheme theme;
60
 
                        
61
 
                        if (string.IsNullOrEmpty (name)) return null;   
62
 
 
63
 
                        // Is the icon name in cache?
64
 
                        iconKey = string.Format ("{0}_{1}", name, size);
65
 
                        if (pixbufCache.TryGetValue (iconKey, out pixbuf)) {                            
66
 
                                return pixbuf;
67
 
                        }
68
 
                         
69
 
                        // TODO: Use a GNOME ThumbnailFactory
70
 
 
71
 
                        // The icon can be loaded from a loaded assembly if the icon has 
72
 
                        // the format: "resource@assemblyname".
73
 
                        
74
 
                        if (name.IndexOf ("@") > 0) {
75
 
                                resourceName = name.Substring (0, name.IndexOf ("@"));
76
 
                                resourceNamespace = name.Substring (resourceName.Length +1);
77
 
                                                                
78
 
                                // loop though all loaded assemblies in the AppDomain
79
 
                                foreach (Assembly asmb in AppDomain.CurrentDomain.GetAssemblies ())     {                                       
80
 
                                        if (new AssemblyName (asmb.FullName).Name.Equals (resourceNamespace)) {
81
 
                                                try     {
82
 
                                                        pixbuf = new Pixbuf (asmb, resourceName, size, size);
83
 
                                                        break;                                                                                                          
84
 
                                                } catch {
85
 
                                                        // TODO: Should we log this error?
86
 
                                                }
87
 
                                        }
88
 
                                }
89
 
                        } 
90
 
                        else {                          
91
 
                                if (name.StartsWith ("/") ||
92
 
                                        name.StartsWith ("~/") || 
93
 
                                    name.StartsWith ("file://", StringComparison.OrdinalIgnoreCase)) {
94
 
                                        try     {
95
 
                                                pixbuf = new Pixbuf (name, size, size);
96
 
                                        } catch {
97
 
                                                // Could not load from file.
98
 
                                                pixbuf = null;
99
 
                                        }                       
100
 
                                } else {                                        
101
 
                                        if (name.Contains (".")) {
102
 
                                                name_noext = name.Remove (name.LastIndexOf ("."));
103
 
                                        }
104
 
                                        else {
105
 
                                                name_noext = name;
106
 
                                        }
107
 
                                        
108
 
                                        theme = IconTheme.Default;
109
 
                                        try     {
110
 
                                                if (theme.HasIcon (name)) {  
111
 
                                                        pixbuf = theme.LoadIcon (name, size, 0);
112
 
                                                }
113
 
                                                else if (theme.HasIcon (name_noext)) { 
114
 
                                                        pixbuf = theme.LoadIcon (name_noext, size, 0);
115
 
                                                }
116
 
                                                else if (name == "gnome-mime-text-plain" &&
117
 
                                                                 theme.HasIcon ("gnome-mime-text")) { 
118
 
                                                        pixbuf = theme.LoadIcon ("gnome-mime-text", size, 0);
119
 
                                                }
120
 
                                        } catch {
121
 
                                                pixbuf = null;
122
 
                                        }               
123
 
                                        
124
 
 
125
 
                                        // Try Tango theme if no icon was found.
126
 
                                        // This code duplication (loop unrolling) was necessary
127
 
                                        // becuase something funny was happening with the icon loading
128
 
                                        // when using themes stored in an array.
129
 
                                        if (pixbuf == null) {
130
 
                                                theme = new IconTheme ();
131
 
                                                theme.CustomTheme = "Tango";
132
 
                                                try     {
133
 
                                                                if (theme.HasIcon (name)) {  
134
 
                                                                        pixbuf = theme.LoadIcon (name, size, 0);
135
 
                                                                }
136
 
                                                                else if (theme.HasIcon (name_noext)) { 
137
 
                                                                        pixbuf = theme.LoadIcon (name_noext, size, 0);
138
 
                                                                }
139
 
                                                                else if (name == "gnome-mime-text-plain" &&
140
 
                                                                                                 theme.HasIcon ("gnome-mime-text")) { 
141
 
                                                                        pixbuf = theme.LoadIcon ("gnome-mime-text", size, 0);
142
 
                                                                }
143
 
                                                        } catch {
144
 
                                                                pixbuf = null;
145
 
                                                        }               
146
 
                                        }
147
 
                                }
148
 
                                        
149
 
                                theme = IconTheme.Default;
150
 
                                if (pixbuf == null && name.StartsWith ("gnome-mime") &&
151
 
                                                themes [0].HasIcon ("gtk-file")) {
152
 
                                        try {
153
 
                                                pixbuf = themes [0].LoadIcon ("gtk-file", size, 0);
154
 
                                        } catch {
155
 
                                                pixbuf = null;                                  
156
 
                                        }
157
 
                                }
158
 
                                if (pixbuf == null && themes [0].HasIcon ("emblem-noread")) {
159
 
                                        try {
160
 
                                                pixbuf = themes [0].LoadIcon ("emblem-noread", size, 0);
161
 
                                        } catch {
162
 
                                                pixbuf = null;                                  
163
 
                                        }
164
 
                                }
165
 
                        }
166
 
                        
167
 
                        if (pixbuf == null) {
 
147
                        
 
148
                        if (null == name)
 
149
                                throw new ArgumentNullException ("name");
 
150
                        
 
151
                        do {
 
152
                                // The icon can be loaded from a loaded assembly if the icon has
 
153
                                // the format: "resource@assemblyname".
 
154
                                if (IconIsEmbeddedResource (name)) {
 
155
                                        pixbuf = IconFromEmbeddedResource (name, size);
 
156
                                        break;
 
157
                                } 
 
158
                                if (IconIsFile (name)) {
 
159
                                        pixbuf = IconFromFile (name, size);
 
160
                                        break;
 
161
                                }
 
162
                                // Try to load icon from defaul theme.
 
163
                                pixbuf = IconFromTheme (name, size, IconTheme.Default);
 
164
 
 
165
                                // Try to load a generic file icon.
 
166
                                if (pixbuf == null && name.StartsWith ("gnome-mime"))
 
167
                                        pixbuf = GenericFileIcon (size);
 
168
                    } while (false);
 
169
                        
 
170
                        // Try to load a pretty "no icon found" icon.
 
171
                        if (pixbuf == null)
 
172
                                pixbuf = UnknownIcon (size);
 
173
                        // If all else fails, use the UnknownPixbuf.
 
174
                        if (pixbuf == null)
168
175
                                pixbuf = UnknownPixbuf;
169
 
                        }                       
170
 
                        // Cache icon pixbuf.
171
 
                        if (pixbuf != null && pixbuf != UnknownPixbuf) {
172
 
                                pixbufCache [iconKey] = pixbuf;                         
173
 
                        }
174
176
                        
175
177
                        return pixbuf;
176
178
                }
177
 
                                                        
178
 
                static void OnDefaultIconThemeChanged (object sender, EventArgs args)
179
 
                {
180
 
                        pixbufCache.Clear ();
181
 
                }
182
179
        }
183
180
}