~ubuntu-branches/ubuntu/raring/banshee/raring

« back to all changes in this revision

Viewing changes to .pc/0007-Remove-irrelevant-media.patch/src/Extensions/Banshee.MeeGo/Banshee.MeeGo/MediaPanelContents.cs

  • Committer: Package Import Robot
  • Author(s): Chow Loong Jin
  • Date: 2012-01-23 23:16:49 UTC
  • mfrom: (6.3.22 experimental)
  • Revision ID: package-import@ubuntu.com-20120123231649-safm1f8eycltcgsf
Tags: 2.3.4.ds-1ubuntu1
* Merge from Debian Experimental, remaining changes:
  + Enable and recommend SoundMenu and Disable NotificationArea by default
  + Disable boo and karma extensions
  + Enable and suggest u1ms
  + Move desktop file for Meego UI to /usr/share/une/applications
  + Change the url for the Amazon store redirector
  + [08dea2c] Revert "Fix invalid cast causing ftbfs with libgpod"
* [b617fe0] Convert Ubuntu-specific patches to gbp-pq patches
* Also fixes Launchpad bugs:
  - Fixes race condition while starting (LP: #766303)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// MediaPanelContents.cs
 
3
// 
 
4
// Author:
 
5
//   Aaron Bockover <abockover@novell.com>
 
6
// 
 
7
// Copyright 2010 Novell, Inc.
 
8
// 
 
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
10
// of this software and associated documentation files (the "Software"), to deal
 
11
// in the Software without restriction, including without limitation the rights
 
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
13
// copies of the Software, and to permit persons to whom the Software is
 
14
// furnished to do so, subject to the following conditions:
 
15
// 
 
16
// The above copyright notice and this permission notice shall be included in
 
17
// all copies or substantial portions of the Software.
 
18
// 
 
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
25
// THE SOFTWARE.
 
26
 
 
27
using System;
 
28
using System.Collections.Generic;
 
29
 
 
30
using Mono.Unix;
 
31
using Gtk;
 
32
 
 
33
using Hyena;
 
34
using Hyena.Data;
 
35
using Hyena.Gui;
 
36
using Hyena.Data.Gui;
 
37
 
 
38
using Banshee.ServiceStack;
 
39
using Banshee.Sources;
 
40
using Banshee.Sources.Gui;
 
41
using Banshee.Collection;
 
42
using Banshee.Collection.Gui;
 
43
using Banshee.MediaEngine;
 
44
using Banshee.Gui;
 
45
using Banshee.Gui.Widgets;
 
46
 
 
47
namespace Banshee.MeeGo
 
48
{
 
49
    public class MediaPanelContents : Table, ITrackModelSourceContents
 
50
    {
 
51
        private ArtistListView artist_view;
 
52
        private AlbumListView album_view;
 
53
        private TerseTrackListView track_view;
 
54
 
 
55
        private SourceComboBox source_combo_box;
 
56
        private SearchEntry search_entry;
 
57
        private MeeGoTrackInfoDisplay track_info_display;
 
58
 
 
59
        private ISource source;
 
60
        private Dictionary<object, double> model_positions = new Dictionary<object, double> ();
 
61
 
 
62
        protected MediaPanelContents (IntPtr raw) : base (raw)
 
63
        {
 
64
        }
 
65
 
 
66
        public MediaPanelContents () : base (2, 2, false)
 
67
        {
 
68
            BorderWidth = 5;
 
69
            RowSpacing = 6;
 
70
            ColumnSpacing = 7;
 
71
            RedrawOnAllocate = true;
 
72
            AppPaintable = true;
 
73
 
 
74
            BuildHeader ();
 
75
            BuildLibrary ();
 
76
            BuildNowPlaying ();
 
77
            ConnectEvents ();
 
78
 
 
79
            SetSource (ServiceManager.SourceManager.ActiveSource);
 
80
        }
 
81
 
 
82
        private void ConnectEvents ()
 
83
        {
 
84
            ServiceManager.SourceManager.ActiveSourceChanged += OnActiveSourceChanged;
 
85
 
 
86
            ServiceManager.Get<InterfaceActionService> ().TrackActions ["SearchForSameArtistAction"].Activated += OnProgrammaticSearch;
 
87
            ServiceManager.Get<InterfaceActionService> ().TrackActions ["SearchForSameAlbumAction"].Activated += OnProgrammaticSearch;
 
88
 
 
89
            ServiceManager.PlayerEngine.ConnectEvent ((args) => track_info_display.Visible =
 
90
                ServiceManager.PlayerEngine.CurrentState != PlayerState.Idle,
 
91
                PlayerEvent.StateChange | PlayerEvent.StartOfStream);
 
92
 
 
93
            source_combo_box.Model.Filter = (source) => source is ITrackModelSource;
 
94
            source_combo_box.Model.Refresh ();
 
95
            source_combo_box.UpdateActiveSource ();
 
96
 
 
97
            search_entry.Changed += OnSearchEntryChanged;
 
98
 
 
99
            artist_view.SelectionProxy.Changed += OnBrowserViewSelectionChanged;
 
100
            album_view.SelectionProxy.Changed += OnBrowserViewSelectionChanged;
 
101
        }
 
102
 
 
103
#region UI Construction
 
104
 
 
105
        private void BuildHeader ()
 
106
        {
 
107
            Attach (new Label {
 
108
                    Markup = String.Format ("<span font_desc=\"Droid Sans Bold\" " +
 
109
                        "size=\"x-large\" foreground=\"#606eff\">{0}</span>",
 
110
                        GLib.Markup.EscapeText (Catalog.GetString ("Media"))),
 
111
                    Xalign = 0.0f
 
112
                },
 
113
                0, 2, 0, 1,
 
114
                AttachOptions.Fill | AttachOptions.Expand,
 
115
                AttachOptions.Shrink, 12, 0);
 
116
        }
 
117
 
 
118
        private void BuildLibrary ()
 
119
        {
 
120
            var box = new MeeGoHeaderBox () { Title = Catalog.GetString ("Library") };
 
121
 
 
122
            // Build the Library Header
 
123
            var header = new HBox () {
 
124
                Spacing = 5,
 
125
                BorderWidth = 5
 
126
            };
 
127
 
 
128
            var app_button = new Button (new Image () {
 
129
                IconSize = (int)IconSize.LargeToolbar,
 
130
                IconName = "media-player-banshee"
 
131
            }) {
 
132
                TooltipText = Catalog.GetString ("Launch the Banshee Media Player")
 
133
            };
 
134
            app_button.Clicked += (o, e) => {
 
135
                ServiceManager.SourceManager.SetActiveSource (ServiceManager.SourceManager.MusicLibrary);
 
136
                ServiceManager.Get<MeeGoService> ().PresentPrimaryInterface ();
 
137
            };
 
138
 
 
139
            header.PackStart (source_combo_box = new SourceComboBox (), false, false, 0);
 
140
            header.PackStart (app_button, false, false, 0);
 
141
            header.PackStart (search_entry = new SearchEntry (), true, true, 0);
 
142
            box.PackStartHighlighted (header, false, false, 0, MeeGoHeaderBox.HighlightFlags.Background);
 
143
 
 
144
            // Build the Library Views
 
145
            var views = new HBox () { Spacing = 5 };
 
146
            views.PackStart (SetupView (artist_view = new ArtistListView () {
 
147
                    Name = "meego-panel-artists",
 
148
                    WidthRequest = 150,
 
149
                    DoNotRenderNullModel = true
 
150
                }), false, false, 0);
 
151
            views.PackStart (SetupView (album_view = new AlbumListView () {
 
152
                    Name = "meego-panel-albums",
 
153
                    DoNotRenderNullModel = true
 
154
                }), true, true, 0);
 
155
            box.PackStart (views, true, true, 0);
 
156
 
 
157
            Attach (box, 0, 1, 1, 2,
 
158
                AttachOptions.Expand | AttachOptions.Fill,
 
159
                AttachOptions.Expand | AttachOptions.Fill,
 
160
                0, 0);
 
161
        }
 
162
 
 
163
        private void BuildNowPlaying ()
 
164
        {
 
165
            var box = new MeeGoHeaderBox () { Title = Catalog.GetString ("Now Playing") };
 
166
 
 
167
            var seek_slider = new ConnectedSeekSlider (SeekSliderLayout.Horizontal);
 
168
            seek_slider.StreamPositionLabel.FormatString = "<small>{0}</small>";
 
169
 
 
170
            track_info_display = new MeeGoTrackInfoDisplay () {
 
171
                HeightRequest = 64,
 
172
                NoShowAll = true
 
173
            };
 
174
 
 
175
            track_view = new TerseTrackListView () {
 
176
                Name = "meego-panel-tracks",
 
177
                WidthRequest = 220
 
178
            };
 
179
            track_view.ColumnController.Insert (new Column (null, "indicator",
 
180
                new ColumnCellStatusIndicator (null), 0.05, true, 20, 20), 0);
 
181
 
 
182
            box.PackStartHighlighted (track_info_display, false, false, 0, MeeGoHeaderBox.HighlightFlags.Background);
 
183
            box.PackStartHighlighted (seek_slider, false, false, 0, MeeGoHeaderBox.HighlightFlags.Background);
 
184
            box.PackStart (SetupView (track_view), true, true, 0);
 
185
            box.PackStartHighlighted (new PlaybackBox (), false, false, 0, MeeGoHeaderBox.HighlightFlags.TopLine);
 
186
 
 
187
            Attach (box, 1, 2, 1, 2,
 
188
                AttachOptions.Shrink,
 
189
                AttachOptions.Expand | AttachOptions.Fill,
 
190
                0, 0);
 
191
        }
 
192
 
 
193
        private ScrolledWindow SetupView (Widget view)
 
194
        {
 
195
            var scrolled = new ScrolledWindow () {
 
196
                VscrollbarPolicy = PolicyType.Automatic,
 
197
                HscrollbarPolicy = PolicyType.Never,
 
198
                ShadowType = ShadowType.None
 
199
            };
 
200
            scrolled.Add (view);
 
201
            return scrolled;
 
202
        }
 
203
 
 
204
#endregion
 
205
 
 
206
#region Background Rendering
 
207
 
 
208
        protected override void OnParentSet (Widget previous)
 
209
        {
 
210
            base.OnParentSet (previous);
 
211
 
 
212
            if (Parent != null) {
 
213
                Parent.ModifyBg (StateType.Normal, Style.White);
 
214
            }
 
215
        }
 
216
 
 
217
        protected override bool OnExposeEvent (Gdk.EventExpose evnt)
 
218
        {
 
219
            if (!Visible || !IsMapped) {
 
220
                return true;
 
221
            }
 
222
 
 
223
            RenderBackground (evnt.Window, evnt.Region);
 
224
            foreach (var child in Children) {
 
225
                PropagateExpose (child, evnt);
 
226
            }
 
227
 
 
228
            return true;
 
229
        }
 
230
 
 
231
        private void RenderBackground (Gdk.Window window, Gdk.Region region)
 
232
        {
 
233
            var cr = Gdk.CairoHelper.Create (window);
 
234
 
 
235
            var grad = new Cairo.LinearGradient (0, 0, 0, Allocation.Height);
 
236
            grad.AddColorStop (0, CairoExtensions.RgbToColor (0xffffff));
 
237
            grad.AddColorStop (1, CairoExtensions.RgbToColor (0xc3c3c3));
 
238
            cr.Pattern = grad;
 
239
            cr.Rectangle (0, 0, Allocation.Width, Allocation.Height);
 
240
            cr.Fill ();
 
241
            grad.Destroy ();
 
242
 
 
243
            CairoExtensions.DisposeContext (cr);
 
244
        }
 
245
 
 
246
#endregion
 
247
 
 
248
#region Event Handlers
 
249
 
 
250
        private void OnProgrammaticSearch (object o, EventArgs args)
 
251
        {
 
252
            Source source = ServiceManager.SourceManager.ActiveSource;
 
253
            search_entry.Ready = false;
 
254
            search_entry.Query = source.FilterQuery;
 
255
            search_entry.Ready = true;
 
256
        }
 
257
 
 
258
        private void OnBrowserViewSelectionChanged (object o, EventArgs args)
 
259
        {
 
260
            // Scroll the raising filter view to the top if "all" is selected
 
261
            var selection = (Hyena.Collections.Selection)o;
 
262
            if (!selection.AllSelected) {
 
263
                return;
 
264
            }
 
265
 
 
266
            if (artist_view.Selection == selection) {
 
267
                artist_view.ScrollTo (0);
 
268
            } else if (album_view.Selection == selection) {
 
269
                album_view.ScrollTo (0);
 
270
            }
 
271
        }
 
272
 
 
273
        private void OnSearchEntryChanged (object o, EventArgs args)
 
274
        {
 
275
            var source = ServiceManager.SourceManager.ActiveSource;
 
276
            if (source == null) {
 
277
                return;
 
278
            }
 
279
 
 
280
            source.FilterType = (TrackFilterType)search_entry.ActiveFilterID;
 
281
            source.FilterQuery = search_entry.Query;
 
282
        }
 
283
 
 
284
        private void OnActiveSourceChanged (SourceEventArgs args)
 
285
        {
 
286
            ThreadAssist.ProxyToMain (delegate {
 
287
                var source = ServiceManager.SourceManager.ActiveSource;
 
288
 
 
289
                search_entry.Ready = false;
 
290
                search_entry.CancelSearch ();
 
291
                search_entry.SearchSensitive = source != null && source.CanSearch;
 
292
 
 
293
                if (source != null && source.FilterQuery != null) {
 
294
                    search_entry.Query = source.FilterQuery;
 
295
                    search_entry.ActivateFilter ((int)source.FilterType);
 
296
                }
 
297
 
 
298
                ResetSource ();
 
299
                SetSource (source);
 
300
 
 
301
                search_entry.Ready = true;
 
302
 
 
303
                if (source != null && source != ServiceManager.SourceManager.MusicLibrary
 
304
                     && source.Parent != ServiceManager.SourceManager.MusicLibrary) {
 
305
                     ServiceManager.Get<MeeGoService> ().PresentPrimaryInterface ();
 
306
                }
 
307
            });
 
308
        }
 
309
 
 
310
        internal void SyncSearchEntry ()
 
311
        {
 
312
            OnActiveSourceChanged (null);
 
313
        }
 
314
 
 
315
#endregion
 
316
 
 
317
#region View<->Model binding
 
318
 
 
319
        private void SetModel<T> (IListModel<T> model)
 
320
        {
 
321
            ListView<T> view = FindListView <T> ();
 
322
            if (view != null) {
 
323
                SetModel (view, model);
 
324
            } else {
 
325
                Hyena.Log.DebugFormat ("Unable to find view for model {0}", model);
 
326
            }
 
327
        }
 
328
 
 
329
        private void SetModel<T> (ListView<T> view, IListModel<T> model)
 
330
        {
 
331
            if (view.Model != null) {
 
332
                model_positions[view.Model] = view.Vadjustment.Value;
 
333
            }
 
334
 
 
335
            if (model == null) {
 
336
                view.SetModel (null);
 
337
                return;
 
338
            }
 
339
 
 
340
            if (!model_positions.ContainsKey (model)) {
 
341
                model_positions[model] = 0.0;
 
342
            }
 
343
 
 
344
            view.SetModel (model, model_positions[model]);
 
345
        }
 
346
 
 
347
        private ListView<T> FindListView<T> ()
 
348
        {
 
349
            foreach (var view in new IListView [] { artist_view, album_view, track_view }) {
 
350
                if (view is ListView<T>) {
 
351
                    return (ListView<T>)view;
 
352
                }
 
353
            }
 
354
            return null;
 
355
        }
 
356
 
 
357
#endregion
 
358
 
 
359
#region ISourceContents
 
360
 
 
361
        public bool SetSource (ISource source)
 
362
        {
 
363
            var track_source = source as ITrackModelSource;
 
364
            var filterable_source = source as IFilterableSource;
 
365
            if (track_source == null) {
 
366
                return false;
 
367
            }
 
368
 
 
369
            this.source = source;
 
370
 
 
371
            SetModel (track_view, track_source.TrackModel);
 
372
 
 
373
            if (filterable_source != null && filterable_source.CurrentFilters != null) {
 
374
                foreach (var model in filterable_source.CurrentFilters) {
 
375
                    if (model is IListModel<ArtistInfo>) {
 
376
                        SetModel (artist_view, (model as IListModel<ArtistInfo>));
 
377
                    } else if (model is IListModel<AlbumInfo>) {
 
378
                        SetModel (album_view, (model as IListModel<AlbumInfo>));
 
379
                    }
 
380
                }
 
381
            }
 
382
 
 
383
            return true;
 
384
        }
 
385
 
 
386
        public void ResetSource ()
 
387
        {
 
388
            source = null;
 
389
            SetModel (track_view, null);
 
390
            SetModel (artist_view, null);
 
391
            SetModel (album_view, null);
 
392
            track_view.HeaderVisible = false;
 
393
        }
 
394
 
 
395
        public ISource Source {
 
396
            get { return source; }
 
397
        }
 
398
 
 
399
        public Widget Widget {
 
400
            get { return this; }
 
401
        }
 
402
 
 
403
#endregion
 
404
 
 
405
#region ITrackModelSourceContents
 
406
 
 
407
        public IListView<TrackInfo> TrackView {
 
408
            get { return track_view; }
 
409
        }
 
410
 
 
411
#endregion
 
412
 
 
413
    }
 
414
}