~ubuntu-branches/ubuntu/quantal/basenji/quantal

« back to all changes in this revision

Viewing changes to Basenji/src/Gui/Widgets/ItemInfo.cs

  • Committer: Package Import Robot
  • Author(s): Patrick Ulbrich
  • Date: 2011-10-02 18:01:08 UTC
  • Revision ID: package-import@ubuntu.com-20111002180108-alcxkgmgv0oj7ipq
Tags: upstream-0.8.0
ImportĀ upstreamĀ versionĀ 0.8.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// ItemInfo.cs
 
2
// 
 
3
// Copyright (C) 2008 - 2011 Patrick Ulbrich
 
4
//
 
5
// This program is free software: you can redistribute it and/or modify
 
6
// it under the terms of the GNU General Public License as published by
 
7
// the Free Software Foundation, either version 3 of the License, or
 
8
// (at your option) any later version.
 
9
//
 
10
// This program is distributed in the hope that it will be useful,
 
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
// GNU General Public License for more details.
 
14
//
 
15
// You should have received a copy of the GNU General Public License
 
16
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
17
//
 
18
 
 
19
using System;
 
20
using System.Collections.Generic;
 
21
using System.Text;
 
22
using Gtk;
 
23
using Cairo;
 
24
using Basenji.Gui.Base;
 
25
using VolumeDB;
 
26
using VolumeDB.Metadata;
 
27
 
 
28
namespace Basenji.Gui.Widgets
 
29
{
 
30
        public partial class ItemInfo : BinBase
 
31
        {
 
32
                private const int MAX_PREVIEW_WIDTH     = 128; // native thumbnail size
 
33
                /* The previews height is determined by its parent Iteminfo widget automatically,
 
34
                 * which should be ~MAX_PREVIEW_WIDTH.
 
35
                 * Don't force a height or the iteminfo widget will do crazy 
 
36
                 * up/down jumps when showing/hiding the preview.
 
37
                private const int MAX_PREVIEW_HEIGHT = 128; // native thumbnail size
 
38
                */
 
39
                
 
40
                private static readonly string STR_BY   = S._("by");
 
41
                private static readonly string STR_FROM = S._("from");
 
42
                
 
43
                private bool isMinimized;
 
44
                
 
45
                public ItemInfo() {
 
46
                        isMinimized = false;
 
47
                        BuildGui();
 
48
                }
 
49
                
 
50
                public void ShowInfo(VolumeItem item, VolumeDatabase db) {
 
51
                        if (item == null)
 
52
                                throw new ArgumentNullException("item");
 
53
                        if (db == null)
 
54
                                throw new ArgumentNullException("db");
 
55
                        
 
56
                        // update item preview
 
57
                        itemPreview.Preview(item, db);
 
58
                        if (!itemPreview.EnableGenericIcons && !Minimized) {
 
59
                                if (itemPreview.IsThumbnailPreview)
 
60
                                        itemPreview.Show();
 
61
                                else
 
62
                                        itemPreview.Hide();
 
63
                        }
 
64
                        
 
65
                        // update item properties
 
66
                        FillPropertyBox(item);
 
67
                        
 
68
                        // HACK :
 
69
                        // somehow the cells of the outer hbox
 
70
                        // don't match the gradient of this widget
 
71
                        // if ShowInfo() is called a second time.
 
72
                        outerBox.QueueDraw();
 
73
                        
 
74
                        this.Show();
 
75
                }
 
76
 
 
77
                public void Clear() {
 
78
                        itemPreview.Clear();
 
79
                        propertyBox.Clear();
 
80
                }
 
81
 
 
82
                public bool Minimized {
 
83
                        get {
 
84
                                return isMinimized;
 
85
                        }
 
86
                        set {
 
87
                                isMinimized = value;
 
88
                                
 
89
                                if (!itemPreview.EnableGenericIcons) {
 
90
                                        // do not show hidden generic icon
 
91
                                        if (itemPreview.IsThumbnailPreview || value)
 
92
                                                itemPreview.Visible = !value;
 
93
                                } else {
 
94
                                        itemPreview.Visible = !value;
 
95
                                }
 
96
                                
 
97
                                if (propertyBox.Minimized != value)
 
98
                                        propertyBox.Minimized = value;
 
99
                        }
 
100
                }
 
101
                
 
102
                private void FillPropertyBox(VolumeItem item) {
 
103
                        ItemProperty[] properties;
 
104
                        Dictionary<string, string> nameProperty;
 
105
                        
 
106
                        switch (item.GetVolumeItemType()) {
 
107
                                case VolumeItemType.FileVolumeItem:
 
108
                                case VolumeItemType.DirectoryVolumeItem:
 
109
                                
 
110
                                        ItemProperty.GetFSItemProperties((FileSystemVolumeItem)item, 
 
111
                                                                 out properties, 
 
112
                                                                 out nameProperty);
 
113
                                        break;
 
114
                                case VolumeItemType.AudioTrackVolumeItem:
 
115
                                        
 
116
                                        ItemProperty.GetAudioCdItemProperties((AudioTrackVolumeItem)item,
 
117
                                                                      out properties,
 
118
                                                                      out nameProperty);
 
119
                                        break;
 
120
                                default:
 
121
                                        throw new NotImplementedException("Iteminfo has not been implemented for this itemtype yet");
 
122
                        }                       
 
123
                        
 
124
                        propertyBox.SetProperties(properties);
 
125
 
 
126
                        string tmp;
 
127
                        if (nameProperty.TryGetValue("title", out tmp)) {
 
128
                                // title found (e.g. html or doc file)
 
129
                                // may be followed optionally by artist and/or album (audio file)
 
130
                                StringBuilder sbName = new StringBuilder();
 
131
                                StringBuilder sbTooltip = new StringBuilder();
 
132
                
 
133
                                sbName.AppendFormat("<b>{0}</b>", Util.Escape(tmp));
 
134
                                sbTooltip.Append(tmp);
 
135
 
 
136
                                if (nameProperty.TryGetValue("artist", out tmp)) {                                                              
 
137
                                        sbName.AppendFormat(" <i>{0}</i> {1}", STR_BY, Util.Escape(tmp));
 
138
                                        sbTooltip.AppendFormat(" {0} {1}", STR_BY, tmp);
 
139
                                }
 
140
 
 
141
                                if (nameProperty.TryGetValue("album", out tmp)) {
 
142
                                        sbName.AppendFormat(" <i>{0}</i> {1}", STR_FROM, Util.Escape(tmp));
 
143
                                        sbTooltip.AppendFormat(" {0} {1}", STR_FROM, tmp);
 
144
                                }
 
145
                                        
 
146
                                propertyBox.SetNameProperty(sbName.ToString(), sbTooltip.ToString());
 
147
                        } else {
 
148
                                // name expected
 
149
                                if (!nameProperty.TryGetValue("name", out tmp))
 
150
                                        throw new ArgumentException("Name expected");
 
151
                        
 
152
                                propertyBox.SetNameProperty(string.Format("<b>{0}</b>", Util.Escape(tmp)), tmp);
 
153
                        }
 
154
                }
 
155
 
 
156
#region ItemProperty class
 
157
                // helper class that returns properties sorted by priority
 
158
                private class ItemProperty : IComparable<ItemProperty>
 
159
                {
 
160
                        public string   name;
 
161
                        public string   value;
 
162
                        public int              priority;
 
163
 
 
164
                        private static readonly string[] KEYWORD_SEPARATORS = { "; " };
 
165
 
 
166
                        private ItemProperty(string name, string value, int priority) {
 
167
                                this.name               = name;
 
168
                                this.value              = value;
 
169
                                this.priority   = priority;
 
170
                        }
 
171
        
 
172
                        public int CompareTo(ItemProperty p) {
 
173
                                return (this.priority - p.priority);
 
174
                        }
 
175
                        
 
176
                        public static void GetFSItemProperties(FileSystemVolumeItem item, 
 
177
                                                               out ItemProperty[] properties, 
 
178
                                                               out Dictionary<string, string> nameProperty) {
 
179
                                
 
180
                                List<ItemProperty> tmp;
 
181
                                GetCommonItemProperties(item, out tmp, out nameProperty);
 
182
                                
 
183
                                tmp.Add(new ItemProperty(S._("Location"), item.Location, 202));
 
184
                                tmp.Add(new ItemProperty(S._("Last write time"), item.LastWriteTime.ToString(), 205));
 
185
                                
 
186
                                if (item.IsSymLink) {
 
187
                                        FileSystemVolumeItem targetItem = item.GetSymLinkTargetItem();
 
188
                                        string symlinkTargetPath = null;
 
189
                                        
 
190
                                        if (targetItem.Location != "/" && targetItem.Name != "/")
 
191
                                                symlinkTargetPath = string.Format("{0}/{1}", targetItem.Location, targetItem.Name);
 
192
                                        else
 
193
                                                symlinkTargetPath = targetItem.Location + targetItem.Name;
 
194
                                
 
195
                                        tmp.Add(new ItemProperty(S._("Symlink target"), symlinkTargetPath, 203));
 
196
                                }
 
197
                                
 
198
                                if (item is FileVolumeItem) {
 
199
                                        FileVolumeItem fvi = (FileVolumeItem)item;
 
200
                                        string sizeStr = Util.GetSizeStr(fvi.Size);
 
201
                                        string hash = fvi.Hash;
 
202
        
 
203
                                        tmp.Add(new ItemProperty(S._("Size"), sizeStr, 204));
 
204
                                        if (!string.IsNullOrEmpty(hash))
 
205
                                                tmp.Add(new ItemProperty(S._("Hash"), hash, 207));
 
206
                                }
 
207
 
 
208
                                if (!string.IsNullOrEmpty(item.MimeType))
 
209
                                        tmp.Add(new ItemProperty(S._("Filetype"), item.MimeType, 206));
 
210
                                
 
211
                                tmp.Sort(); // sort by priority
 
212
                                properties = tmp.ToArray();
 
213
                        }
 
214
                        
 
215
                        public static void GetAudioCdItemProperties(AudioTrackVolumeItem item, 
 
216
                                                               out ItemProperty[] properties, 
 
217
                                                               out Dictionary<string, string> nameProperty) {
 
218
                                
 
219
                                const int PCM_FACTOR = (44100 * 16 * 2) / 8;
 
220
                                
 
221
                                List<ItemProperty> tmp;
 
222
                                GetCommonItemProperties(item, out tmp, out nameProperty);
 
223
                                
 
224
                                tmp.Add(new ItemProperty(S._("Duration"), FormatDuration(item.Duration), 202));                         
 
225
                                tmp.Add(new ItemProperty(S._("Size"), Util.GetSizeStr((long)(item.Duration.TotalSeconds * PCM_FACTOR)), 203));
 
226
                                tmp.Add(new ItemProperty(S._("Track No."), (item.ItemID - 1).ToString(), 204));
 
227
                                
 
228
                                if (!string.IsNullOrEmpty(item.MimeType))
 
229
                                        tmp.Add(new ItemProperty(S._("Type"), item.MimeType, 205));
 
230
                                
 
231
                                tmp.Sort(); // sort by priority
 
232
                                properties = tmp.ToArray();
 
233
                        }
 
234
                        
 
235
                        private static void GetCommonItemProperties(VolumeItem item,
 
236
                                                                    out List<ItemProperty> properties,
 
237
                                                                        out Dictionary<string, string> nameProperty) {
 
238
                                
 
239
                                List<ItemProperty> tmp = new List<ItemProperty>();
 
240
                                nameProperty = new Dictionary<string, string>();
 
241
                                
 
242
                                //
 
243
                                // add metadata properties first (higher priority)
 
244
                                //
 
245
                                
 
246
                                if (!item.MetaData.IsEmpty) {
 
247
                                        Dictionary<MetadataType, string> metadata = item.MetaData.ToDictionary();
 
248
                                        
 
249
                                        //
 
250
                                        // cherry-pick interesting properties
 
251
                                        //
 
252
                                        string val;
 
253
                                        
 
254
                                        /* audio properties*/
 
255
                                        if (metadata.TryGetValue(MetadataType.GENRE, out val)) {
 
256
                                                // NOTE: genre keyword is used in e.g. deb packages as well
 
257
                                                tmp.Add(new ItemProperty(S._("Genre"), RemoveSimilarIDTags(val), 105));
 
258
                                        }
 
259
                                        
 
260
                                        if (metadata.TryGetValue(MetadataType.ARTIST, out val)) {
 
261
                                                //tmp2.Add(new ItemProperty(S._("Artist"), val, 101));
 
262
                                                nameProperty.Add("artist", RemoveSimilarIDTags(val));
 
263
                                        }
 
264
                                        
 
265
                                        if (metadata.TryGetValue(MetadataType.TITLE, out val)) {
 
266
                                                // NOTE: title keyword is used in e.g. html or doc files as well
 
267
                                                //tmp2.Add(new ItemProperty(S._("Title"), val, 101));
 
268
                                                nameProperty.Add("title", RemoveSimilarIDTags(val));
 
269
                                        }
 
270
                                        
 
271
                                        if (metadata.TryGetValue(MetadataType.ALBUM, out val)) {
 
272
                                                //tmp2.Add(new ItemProperty(S._("Album"), val, 103));
 
273
                                                nameProperty.Add("album", RemoveSimilarIDTags(val));
 
274
                                        }
 
275
                                        
 
276
                                        if (metadata.TryGetValue(MetadataType.YEAR, out val)) {
 
277
                                                tmp.Add(new ItemProperty(S._("Year"), RemoveSimilarIDTags(val), 104));
 
278
                                        }
 
279
                                        
 
280
                                        if (metadata.TryGetValue(MetadataType.DESCRIPTION, out val)) {
 
281
                                                // NOTE: description keyword is used in e.g. html files as well
 
282
                                                tmp.Add(new ItemProperty(S._("Description"), RemoveSimilarIDTags(val), 110));
 
283
                                        }
 
284
                                        
 
285
                                        /* audio / picture / video properties */
 
286
                                        if (metadata.TryGetValue(MetadataType.DURATION, out val)) {
 
287
                                                tmp.Add(new ItemProperty(S._("Duration"), FormatDuration(MetadataUtils.MetadataDurationToTimespan(val)), 106));
 
288
                                        }
 
289
                                        
 
290
                                        if (metadata.TryGetValue(MetadataType.SIZE, out val)) {
 
291
                                                // NOTE: size keyword is used in e.g. deb packages as well (unpacked size in kb)
 
292
                                                if (item.MimeType.StartsWith("image") || item.MimeType.StartsWith("video"))
 
293
                                                        tmp.Add(new ItemProperty(S._("Dimensions"), val, 107));
 
294
                                        }
 
295
                                        
 
296
                                        /* other properties*/
 
297
                                        if (metadata.TryGetValue(MetadataType.FORMAT, out val)) {
 
298
                                                tmp.Add(new ItemProperty(S._("Format"), val, 108));
 
299
                                        }
 
300
                                        
 
301
                                        if (metadata.TryGetValue(MetadataType.AUTHOR, out val)) {
 
302
                                                tmp.Add(new ItemProperty(S._("Author"), val, 111));
 
303
                                        }
 
304
                                        
 
305
                                        if (metadata.TryGetValue(MetadataType.COPYRIGHT, out val)) {
 
306
                                                tmp.Add(new ItemProperty(S._("Copyright"), val, 112));
 
307
                                        }
 
308
                                        
 
309
                                        if (metadata.TryGetValue(MetadataType.PRODUCER, out val)) {
 
310
                                                tmp.Add(new ItemProperty(S._("Producer"), val, 115));
 
311
                                        }
 
312
                                        
 
313
                                        if (metadata.TryGetValue(MetadataType.CREATOR, out val)) {
 
314
                                                tmp.Add(new ItemProperty(S._("Creator"), val, 114));
 
315
                                        }
 
316
                                        
 
317
                                        if (metadata.TryGetValue(MetadataType.SOFTWARE, out val)) {
 
318
                                                tmp.Add(new ItemProperty(S._("Software"), val, 116));
 
319
                                        }
 
320
                                        
 
321
                                        if (metadata.TryGetValue(MetadataType.LANGUAGE, out val)) {
 
322
                                                tmp.Add(new ItemProperty(S._("Language"), val, 113));
 
323
                                        }
 
324
                                        
 
325
                                        if (metadata.TryGetValue(MetadataType.PAGE_COUNT, out val)) {
 
326
                                                tmp.Add(new ItemProperty(S._("Page count"), val, 109));
 
327
                                        }
 
328
                                        
 
329
                                        if (metadata.TryGetValue(MetadataType.FILENAME, out val)) {
 
330
                                                // count files in archives 
 
331
                                                // (filenames were joined by MetadataStore.ToDictionary())
 
332
                                                string[] filenames = val.Split(KEYWORD_SEPARATORS, StringSplitOptions.None);
 
333
                                                tmp.Add(new ItemProperty(S._("File count"), filenames.Length.ToString(), 117));
 
334
                                        }
 
335
                                        
 
336
                                        if (Global.EnableDebugging) {
 
337
                                                foreach (KeyValuePair<MetadataType, string> pair in metadata) {
 
338
                                                        Platform.Common.Diagnostics.Debug.WriteLine(
 
339
                                                                String.Format("{0}: {1}", pair.Key, pair.Value));
 
340
                                                }
 
341
                                        }
 
342
                                                
 
343
                                }
 
344
                                
 
345
                                //
 
346
                                // add common item properties (low priority, shown only if there's room left)
 
347
                                //
 
348
                                
 
349
                                if (!nameProperty.ContainsKey("title")) {
 
350
                                        // no title metadata
 
351
                                        // or artist and/or album metadata only
 
352
                                        nameProperty.Clear();
 
353
                                        // use name instead
 
354
                                        nameProperty.Add("name", item.Name);
 
355
                                }
 
356
                                
 
357
                                if (item.Note.Length > 0)
 
358
                                        tmp.Add(new ItemProperty(S._("Note"), item.Note, 301));
 
359
                                                
 
360
                                if (item.Keywords.Length > 0)
 
361
                                        tmp.Add(new ItemProperty(S._("Keywords"), item.Keywords, 302));
 
362
                                
 
363
                                properties = tmp;
 
364
                        }
 
365
 
 
366
                        private static string RemoveSimilarIDTags(string separatedTags) {
 
367
                                // Dirty hack, tries to remove similar IDv2/IDv3 tag keywords,
 
368
                                // i.e. tags that were equal in the IDv2 and the IDv3 header up to a certain length.
 
369
                                // (e.g "MP3 Title Number 1" (IDv3 tag) and "MP3 Title Numb" (IDv2 tag)
 
370
                                // In this case the shorter one is removed.                             
 
371
                                // Fully equal keywords can not occur, they have been filtered out in the scanning process.
 
372
                                // NOTE: This function may fail if the keyword itself contains the separator string ("; ").
 
373
                                
 
374
                                if (separatedTags.IndexOf(KEYWORD_SEPARATORS[0]) > -1) {
 
375
                                        string[] tags = separatedTags.Split(KEYWORD_SEPARATORS, StringSplitOptions.None);
 
376
                                        if (tags.Length == 2) {
 
377
                                                if (tags[0].StartsWith(tags[1]))
 
378
                                                        return tags[0];
 
379
                                                else if (tags[1].StartsWith(tags[0]))
 
380
                                                        return tags[1];
 
381
                                        }
 
382
                                }
 
383
                                return separatedTags;
 
384
                        }
 
385
                        
 
386
                        private static string FormatDuration(TimeSpan duration) {
 
387
                                // duration.ToString() also returns ms.
 
388
                                return string.Format("{0:D2}:{1:D2}:{2:D2}",
 
389
                                                     duration.Hours,
 
390
                                                     duration.Minutes,
 
391
                                                     duration.Seconds);
 
392
                        }
 
393
                }
 
394
#endregion
 
395
        }
 
396
        
 
397
        // gui initialization
 
398
        public partial class ItemInfo : BinBase
 
399
        {
 
400
                private HBox            outerBox;
 
401
                private ItemPreview     itemPreview;
 
402
                private PropertyBox     propertyBox;
 
403
                
 
404
                protected override void BuildGui() {
 
405
                        itemPreview = new ItemPreview();
 
406
                        itemPreview.RoundedCorners              = true;
 
407
                        itemPreview.EnableGenericIcons  = false;
 
408
                        /*itemPreview.HeightRequest     = MAX_PREVIEW_HEIGHT;*/
 
409
                        itemPreview.WidthRequest                = MAX_PREVIEW_WIDTH;
 
410
                        // set no_window flag to disable background drawing
 
411
                        itemPreview.SetFlag(WidgetFlags.NoWindow);
 
412
                        
 
413
                        propertyBox = new PropertyBox(this);
 
414
        
 
415
                        outerBox = new HBox(false, 12);
 
416
                        outerBox.BorderWidth = 6;
 
417
                        outerBox.PackStart(itemPreview, false, false, 0);
 
418
                        outerBox.PackStart(propertyBox, true, true, 0);
 
419
                        
 
420
                        // (Gtk.Frame derives from Gtk.Bin which has no window)
 
421
                        Frame frame = new Frame();
 
422
                        frame.Add(outerBox);
 
423
                        
 
424
                        // TODO:
 
425
                        // setting the no_window flag on current windows GTK seems to be buggy. 
 
426
                        // remove no_window flag and use a solid bg color instead of a gradient.
 
427
                        // check later if the flag is working.
 
428
                        if (Platform.Common.Diagnostics.CurrentPlatform.IsWin32) {
 
429
                                Gdk.Color baseColor = Style.Base(StateType.Normal);
 
430
 
 
431
                                itemPreview.Flags = itemPreview.Flags ^ (int)WidgetFlags.NoWindow;
 
432
                                itemPreview.ModifyBg(StateType.Normal, baseColor);
 
433
                                
 
434
                                EventBox eb = new EventBox();
 
435
                                eb.ModifyBg(StateType.Normal, baseColor);
 
436
                                eb.Add(frame);
 
437
                                
 
438
                                this.Add(eb);                           
 
439
                                return;
 
440
                        }
 
441
                        
 
442
                        frame.ExposeEvent += OnExposeEvent;
 
443
                        this.Add(frame);
 
444
                }
 
445
 
 
446
                [GLib.ConnectBefore()]
 
447
                private void OnExposeEvent (object o, ExposeEventArgs args)     {
 
448
                        int x = args.Event.Area.X;
 
449
                        int y = args.Event.Area.Y;
 
450
                        int width = args.Event.Area.Width;
 
451
                        int height = args.Event.Area.Height;
 
452
                        
 
453
                        Gdk.Color startColor = Style.Mid(StateType.Normal);
 
454
                        Gdk.Color stopColor = Style.Light(StateType.Normal);
 
455
                        double alpha = .7;
 
456
                        
 
457
                        using (Context cr = Gdk.CairoHelper.Create(args.Event.Window)) {        
 
458
                                cr.MoveTo (x, y);
 
459
                                cr.Rectangle(x, y, width, height);
 
460
                                
 
461
                                Gradient pat = new LinearGradient(x, y, x, y + height / 1.2);
 
462
                                pat.AddColorStop(0, ToCairoColor(startColor, alpha));
 
463
                                pat.AddColorStop(1, ToCairoColor(stopColor, alpha));
 
464
                                
 
465
                                cr.Pattern = pat;
 
466
                                cr.Fill();
 
467
                        }
 
468
                }
 
469
                
 
470
                private static Cairo.Color ToCairoColor(Gdk.Color c, double alpha) {
 
471
                        double gdk_max = (double)ushort.MaxValue;
 
472
                        return new Cairo.Color(c.Red / gdk_max,
 
473
                                               c.Green / gdk_max,
 
474
                                               c.Blue / gdk_max,
 
475
                                               alpha);
 
476
                }
 
477
                
 
478
#region PropertyBox class
 
479
                private class PropertyBox : VBox
 
480
                {
 
481
                        private Label           lblName;
 
482
                        private Arrow           btnArrow;
 
483
                        private Table[]         tbls;
 
484
                        private HBox            hbox;
 
485
                        private Label[]         captionLbls;
 
486
                        private Label[]         valueLbls;
 
487
                        private ItemInfo        owner;
 
488
                        
 
489
                        private const int MAX_ITEM_PROPERTIES   = 8; // must be a multiple of 2
 
490
                        private const int WIDTH                                 = 2;
 
491
                        private const int HEIGHT                                = MAX_ITEM_PROPERTIES / WIDTH;
 
492
                        
 
493
                        public PropertyBox(ItemInfo owner) : base(false, 12) {
 
494
                                this.owner = owner;
 
495
                                
 
496
                                this.captionLbls        = new Label[MAX_ITEM_PROPERTIES];
 
497
                                this.valueLbls          = new Label[MAX_ITEM_PROPERTIES];
 
498
                                
 
499
                                this.lblName = WindowBase.CreateLabel(string.Empty, true);
 
500
                                this.lblName.Ellipsize = Pango.EllipsizeMode.End;
 
501
 
 
502
                                this.tbls = new Table[WIDTH];
 
503
                                this.hbox = new HBox(false, 12);
 
504
                                
 
505
                                for (int i = 0; i < WIDTH; i++) {
 
506
                                        this.tbls[i] = WindowBase.CreateTable(HEIGHT, 2, 6); // 2 = caption + value
 
507
                                        this.hbox.PackStart(tbls[i], true, true, 0);
 
508
                                }
 
509
        
 
510
                                int tbl = 0, y = 0;
 
511
                                for (int i = 0; i < MAX_ITEM_PROPERTIES; i++, y++) {
 
512
        
 
513
                                        if (i == HEIGHT) {
 
514
                                                y = 0;
 
515
                                                tbl++;
 
516
                                        }
 
517
                                        
 
518
                                        // create caption label
 
519
                                        this.captionLbls[i] = WindowBase.CreateLabel(string.Empty, true);
 
520
                                        
 
521
                                        // create value label
 
522
                                        this.valueLbls[i] = WindowBase.CreateLabel(string.Empty, false);
 
523
                                        this.valueLbls[i].Ellipsize = Pango.EllipsizeMode.End;
 
524
                                        
 
525
                                        // attach caption and value labels to the table
 
526
                                        WindowBase.TblAttach(tbls[tbl], captionLbls[i], 0, y);
 
527
                                        this.tbls[tbl].Attach(valueLbls[i], 1, 2, (uint)y, (uint)(y + 1));
 
528
                                }
 
529
 
 
530
                                // custom button
 
531
                                HBox hb = new HBox(false, 6);
 
532
                                this.btnArrow = new Arrow(ArrowType.Down, ShadowType.None);
 
533
                                hb.PackStart(btnArrow, false, false, 0);
 
534
                                hb.PackStart(lblName, true, true, 0);
 
535
                                
 
536
                                Button btn = new Button(hb);
 
537
                                btn.Clicked += OnBtnClicked;
 
538
                                
 
539
                                this.PackStart(btn, true, false, 0);
 
540
                                this.PackStart(hbox, true, true, 0);
 
541
                        }
 
542
        
 
543
                        public void SetNameProperty(string name, string tooltip) {
 
544
                                lblName.LabelProp = name;
 
545
                                lblName.TooltipText = tooltip;
 
546
                        }
 
547
        
 
548
                        public void SetProperties(ItemProperty[] properties) {
 
549
                                int itemCount = (properties.Length < MAX_ITEM_PROPERTIES) ? properties.Length : MAX_ITEM_PROPERTIES;
 
550
                                
 
551
                                // hide second table when it won't contain labels
 
552
                                tbls[1].Visible = (itemCount > HEIGHT);
 
553
                                
 
554
                                for (int i = 0; i < itemCount; i++) {
 
555
                                        ItemProperty p = properties[i];
 
556
                                        
 
557
                                        captionLbls[i].LabelProp = string.Format("<b>{0}:</b>", p.name);
 
558
                                        
 
559
                                        // remove linebreaks
 
560
                                        valueLbls[i].LabelProp = p.value.Replace('\n', ' ').Replace('\r', ' ');
 
561
                                        valueLbls[i].TooltipText = p.value;
 
562
                                }
 
563
                                
 
564
                                // clear remaining labels
 
565
                                for (int i = itemCount; i < MAX_ITEM_PROPERTIES; i++) {
 
566
                                        captionLbls[i].LabelProp = string.Empty;
 
567
 
 
568
                                        valueLbls[i].LabelProp = string.Empty;
 
569
                                        valueLbls[i].TooltipText = string.Empty;
 
570
                                }
 
571
                        }
 
572
 
 
573
                        public void Clear() {
 
574
                                SetNameProperty(string.Empty, string.Empty);
 
575
                                for (int i = 0; i < MAX_ITEM_PROPERTIES; i++) {
 
576
                                        captionLbls[i].LabelProp = String.Empty;
 
577
                                        valueLbls[i].LabelProp = valueLbls[i].TooltipText = String.Empty;
 
578
                                }
 
579
                        }
 
580
 
 
581
                        public bool Minimized {
 
582
                                get {
 
583
                                        return !hbox.Visible;
 
584
                                }
 
585
                                set {                                   
 
586
                                        if (value) {
 
587
                                                btnArrow.ArrowType = ArrowType.Right;
 
588
                                                hbox.Visible = false;
 
589
                                        } else {
 
590
                                                btnArrow.ArrowType = ArrowType.Down;
 
591
                                                hbox.Visible = true;
 
592
                                        }
 
593
                                        
 
594
                                        if (owner.Minimized != value)
 
595
                                                owner.Minimized = value;
 
596
                                }
 
597
                        }
 
598
                        
 
599
                        private void OnBtnClicked(object sender, EventArgs args) {
 
600
                                Minimized = !Minimized;
 
601
                        }
 
602
                }
 
603
#endregion
 
604
 
 
605
        }
 
606
}