~alexlauni/unity-lens-music/horizontal-renderer

« back to all changes in this revision

Viewing changes to src/simple-scope.vala

  • Committer: Alex Launi
  • Date: 2011-09-08 15:51:46 UTC
  • Revision ID: alex.launi@canonical.com-20110908155146-ozfz6so41sdmg4dc
revert scope simplification

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2011 Canonical Ltd
3
 
 *
4
 
 * This program is free software: you can redistribute it and/or modify
5
 
 * it under the terms of the GNU General Public License version 3 as
6
 
 * published by the Free Software Foundation.
7
 
 *
8
 
 * This program is distributed in the hope that it will be useful,
9
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 
 * GNU General Public License for more details.
12
 
 *
13
 
 * You should have received a copy of the GNU General Public License
14
 
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
 
 *
16
 
 * Authored by Alex Launi <alex.launi@canonical.com>
17
 
 *
18
 
 */
19
 
 
20
 
using GLib;
21
 
 
22
 
namespace Unity.MusicLens
23
 
{
24
 
  public abstract class SimpleScope : Object
25
 
  {
26
 
    public Unity.Scope Scope { get; protected set; }
27
 
 
28
 
    protected abstract int num_results_without_search { get; }
29
 
    protected abstract int num_results_global_search { get; }
30
 
    protected abstract int num_results_lens_search { get; }
31
 
 
32
 
    protected abstract void perform_search (LensSearch? search, Dee.Model results_model, List<Filter> filters, int max_results = -1);
33
 
    
34
 
    protected bool is_dirty;
35
 
    protected LensSearch? previous_search;
36
 
 
37
 
    public SimpleScope ()
38
 
    {
39
 
      is_dirty = true;
40
 
      previous_search = null;
41
 
 
42
 
      /* Listen for filter changes */
43
 
      Scope.filters_changed.connect(
44
 
                                    () => { 
45
 
                                      if (Scope.active_search != null)
46
 
                                        {
47
 
                                          is_dirty = true;
48
 
                                          Scope.notify_property ("active-search");
49
 
                                        }
50
 
                                    }
51
 
                                    );
52
 
 
53
 
      /* Listen for changes to the lens search entry */
54
 
      Scope.notify["active-search"].connect (
55
 
                                             (obj, pspec) => { 
56
 
                                               var search = Scope.active_search;
57
 
                                               if (!(is_dirty || search_has_really_changed (previous_search, search)))
58
 
                                                 return;
59
 
                                               is_dirty = false;
60
 
                                               update_search_async.begin (search);
61
 
                                               previous_search = search;
62
 
                                             }
63
 
                                             );
64
 
 
65
 
      /* Listen for changes to the global search */
66
 
      Scope.notify["active-global-search"].connect (
67
 
                                                    (obj, pspec) => { 
68
 
                                                      var search = Scope.active_global_search;
69
 
                                                      
70
 
                                                      if (search_is_invalid (search))
71
 
                                                        return;
72
 
 
73
 
                                                      if (!search_has_really_changed (previous_search, search))
74
 
                                                        return;
75
 
 
76
 
                                                      update_global_search_async.begin (search);
77
 
                                                      previous_search = search;
78
 
                                                    }
79
 
                                                    );
80
 
    }
81
 
 
82
 
    /* based on the filters(?) get the default results to show when the music lens is
83
 
     * just opened without filters, like when someone hits Super+M
84
 
     */
85
 
    private async void update_without_search_async (LensSearch search)
86
 
    {
87
 
      perform_search_async.begin (search, num_results_without_search);
88
 
    }
89
 
    
90
 
    /**
91
 
     * results for a global search from just hitting Super. here we want to return
92
 
     * a smaller number of results with 0 filters.
93
 
     */
94
 
    private async void update_global_search_async (LensSearch search)
95
 
    {
96
 
      var results_model = Scope.global_results_model;
97
 
      
98
 
      if (search_is_invalid (search))
99
 
        {
100
 
          results_model.clear ();
101
 
          return;
102
 
        }
103
 
      
104
 
      perform_search_async.begin (search, num_results_global_search);
105
 
    }
106
 
    
107
 
    private async void update_search_async (LensSearch search)
108
 
    {
109
 
      // just pretend like there's no search
110
 
      if (search_is_invalid (search))
111
 
        {
112
 
          update_without_search_async.begin (search);
113
 
          return;
114
 
        }
115
 
      
116
 
      perform_search_async.begin (search, num_results_lens_search);
117
 
    }
118
 
 
119
 
    private async void perform_search_async (LensSearch search, int max_results)
120
 
    {
121
 
      var results_model = Scope.results_model;
122
 
            
123
 
      /* Prevent concurrent searches and concurrent updates of our models,
124
 
       * by preventing any notify signals from propagating to us.
125
 
       * Important: Remeber to thaw the notifys again! */
126
 
      List<Filter> filters = new List<Filter> ();
127
 
      Filter filter = Scope.get_filter ("genre");
128
 
      if (filter.filtering)
129
 
        filters.append (filter);
130
 
 
131
 
      filter = Scope.get_filter ("decade");
132
 
      if (filter.filtering)
133
 
        filters.append (filter);
134
 
 
135
 
      Scope.freeze_notify ();
136
 
      
137
 
      results_model.clear ();
138
 
      perform_search (search, results_model, filters, max_results);
139
 
      
140
 
      /* Allow new searches once we enter an idle again.
141
 
       * We don't do it directly from here as that could mean we start
142
 
       * changing the model even before we had flushed out current changes
143
 
       */
144
 
      Idle.add (() => {
145
 
          Scope.thaw_notify ();
146
 
          return false;
147
 
        });
148
 
      
149
 
      search.finished ();
150
 
    }
151
 
 
152
 
    private bool search_is_invalid (LensSearch? search)
153
 
    {
154
 
      /* This boolean expression is unfolded as we seem to get
155
 
       * some null dereference if we join them in a big || expression */
156
 
      if (search == null)
157
 
        return true;
158
 
      else if (search.search_string == null)
159
 
        return true;
160
 
      
161
 
      return search.search_string.strip() == "";
162
 
    }
163
 
    
164
 
    private bool search_has_really_changed (LensSearch? old_search,
165
 
                                            LensSearch? new_search)
166
 
    {
167
 
      if (old_search == null && new_search == null)
168
 
        return false;
169
 
      
170
 
      string s1, s2;
171
 
      
172
 
      if (old_search == null)
173
 
        {
174
 
          s1 = new_search.search_string;
175
 
          if (s1 == null || s1.strip() == "")
176
 
            return false;
177
 
          else
178
 
            return true;
179
 
        }
180
 
      else if (new_search == null)
181
 
        {
182
 
          s2 = old_search.search_string;
183
 
          if (s2 == null || s2.strip() == "")
184
 
            return false;
185
 
          else
186
 
            return true;
187
 
        }
188
 
      else
189
 
        {
190
 
          s1 = new_search.search_string;
191
 
          s2 = old_search.search_string;
192
 
          if (s1 == null)
193
 
            {
194
 
              if (s2 == null || s2.strip() == "")
195
 
                return false;
196
 
              else
197
 
                return true;
198
 
            }
199
 
          else if (s2 == null)
200
 
            {
201
 
              if (s1 == null || s1.strip() == "")
202
 
                return false;
203
 
              else
204
 
                return true;
205
 
            }
206
 
          else
207
 
            return s1.strip () != s2.strip ();
208
 
        }
209
 
    }
210
 
  }
211
 
}