sbSmartMediaListColumnSpecUpdater.jsm
Go to the documentation of this file.
1 /*
2 //
3 // BEGIN SONGBIRD GPL
4 //
5 // This file is part of the Songbird web player.
6 //
7 // Copyright(c) 2005-2008 POTI, Inc.
8 // http://songbirdnest.com
9 //
10 // This file may be licensed under the terms of of the
11 // GNU General Public License Version 2 (the "GPL").
12 //
13 // Software distributed under the License is distributed
14 // on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
15 // express or implied. See the GPL for the specific language
16 // governing rights and limitations.
17 //
18 // You should have received a copy of the GPL along with this
19 // program. If not, go to http://www.gnu.org/licenses/gpl.html
20 // or write to the Free Software Foundation, Inc.,
21 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 // END SONGBIRD GPL
24 //
25 */
26 
27 Components.utils.import("resource://app/jsmodules/sbProperties.jsm");
28 Components.utils.import("resource://app/jsmodules/sbLibraryUtils.jsm");
29 Components.utils.import("resource://app/jsmodules/sbProperties.jsm");
30 Components.utils.import("resource://app/jsmodules/sbColumnSpecParser.jsm");
31 
32 EXPORTED_SYMBOLS = ["SmartMediaListColumnSpecUpdater"];
33 
34 const Cc = Components.classes;
35 const Ci = Components.interfaces;
36 
37 var SmartMediaListColumnSpecUpdater = {
38 
39  update: function(list) {
40  var sort;
41  var sortDirection;
42  var columnWidth;
43 
44  var storageGuid = list.getProperty(SBProperties.storageGUID);
45  var storageList = list.library.getMediaItem(storageGuid);
46 
47  // if we are limiting, use the selectby property/direction as sort
48  if (list.limitType != Ci.sbILocalDatabaseSmartMediaList.LIMIT_TYPE_NONE) {
49  if (list.randomSelection) {
50  // unless we are selecting randomly, in which case we want the ordinal
51  // order (unsorted)
52  sort = SBProperties.ordinal;
53  sortDirection = "a";
54  } else {
55  sort = list.selectPropertyID;
56  sortDirection = list.selectDirection ? "a" : "d";
57  }
58  } else {
59  // if there is one rule, use it as the sort, otherwise use
60  // default (artistname)
61  if (list.conditionCount == 1) {
62  var condition = list.getConditionAt(0);
63  if (!this._isDummyProperty(condition.propertyID)) {
64  sort = condition.propertyID;
65  } else {
66  sort = SBProperties.artistName;
67  }
68  } else {
69  sort = SBProperties.artistName;
70  }
71  }
72 
73  // find the property in the smartplaylistpropertyregistrar
74  var registeredProp;
75  var registrar =
76  Cc["@songbirdnest.com/Songbird/SmartPlaylistPropertyRegistrar;1"]
77  .getService(Ci.sbISmartPlaylistPropertyRegistrar);
78  var props = registrar.getPropertiesForContext("default");
79  while (props.hasMoreElements()) {
80  var p = props.getNext();
81  p.QueryInterface(Ci.sbISmartPlaylistProperty);
82  if (p.propertyID == sort) {
83  registeredProp = p;
84  break;
85  }
86  }
87  // if not found, the property was not in the registrar, this could be a
88  // programmatically built smart playlist, or the user might have turned on
89  // the extended property list, which is not restricted to the registered
90  // properties, so make something up.
91  if (!registeredProp) {
92  registeredProp = {};
93  registeredProp.propertyID = sort;
94  registeredProp.defaultColumnWidth = 80;
95  registeredProp.defaultSortDirection = this._getDefaultSortDirection(sort);
96  }
97 
98  // if we haven't got a sort direction yet, use the one in the registrar
99  if (!sortDirection) {
100  sortDirection = registeredProp.defaultSortDirection;
101  }
102  columnWidth = registeredProp.defaultColumnWidth;
103 
104  // get the current user column spec
105  var userSpecs = this._getColumnSpec(storageList);
106 
107  // make the new default column specs based on the library specs
108  var columnMap = this._getColumnSpec(LibraryUtils.mainLibrary);
109 
110  var currentUserSpec = storageList.getProperty(SBProperties.columnSpec);
111  var currentDefaultSpec = storageList.getProperty(SBProperties.defaultColumnSpec);
112 
113  // Has the user deviated from the default?
114  // If so, we shouldn't undo their changes.
115  var userModifiedColumns = currentUserSpec != currentDefaultSpec;
116 
117  // playlists have an ordinal column by default, make sure it's in both
118  // default and user spec
119 
120  var ordinal = {
121  property: SBProperties.ordinal,
122  sort: "a",
123  width: 42
124  }
125  if (!this._getColumn(columnMap, SBProperties.ordinal)) {
126  ColumnSpecParser.reduceWidthsProportionally(columnMap, ordinal.width);
127  columnMap.unshift(ordinal);
128  }
129  if (!this._getColumn(userSpecs, SBProperties.ordinal)) {
130  ColumnSpecParser.reduceWidthsProportionally(userSpecs, ordinal.width);
131  userSpecs.unshift(ordinal);
132  }
133 
134  // new column arrays (default and user)
135 
136  var defaultCols = columnMap;
137  var cols = userSpecs;
138 
139  // if the new sort column is not in the spec arrays, proportionally resize
140  // the other columns to make room for it, and add it
141  var newSort = {
142  property: sort,
143  sort: null,
144  width: columnWidth
145  };
146 
147  if (!this._getColumn(defaultCols, sort)) {
148  ColumnSpecParser.reduceWidthsProportionally(defaultCols, columnWidth);
149  defaultCols.push(newSort);
150  }
151 
152  if (!this._getColumn(cols, sort)) {
153  ColumnSpecParser.reduceWidthsProportionally(cols, columnWidth);
154  cols.push(newSort);
155  }
156 
157  // reset the sort field for everything but our actual sort column
158  function resetObsoleteSorts(aArray) {
159  for (var i=0;i<aArray.length;i++) {
160  var col = aArray[i];
161  if (col.property != sort) {
162  col.sort = null;
163  } else {
164  col.sort = sortDirection;
165  }
166  }
167  }
168  resetObsoleteSorts(defaultCols);
169  if (!userModifiedColumns) {
170  // Only reset the current sort if the user hasn't
171  // manually set it
172  resetObsoleteSorts(cols);
173  }
174 
175  // rebuild the column spec strings
176  function makeSpecString(aArray) {
177  var spec = "";
178  for (var i=0;i<aArray.length;i++) {
179  var col = aArray[i];
180  if (spec != "") spec += " ";
181  spec += col.property;
182  if (col.width) {
183  spec += " ";
184  spec += col.width;
185  }
186  if (col.sort) {
187  if (col.sort == "ascending") {
188  col.sort = "a";
189  }
190  else if (col.sort == "descending") {
191  col.sort = "d";
192  }
193  spec += " ";
194  spec += col.sort;
195  }
196  }
197  return spec;
198  }
199  var defaultSpec = makeSpecString(defaultCols);
200  var userSpec = makeSpecString(cols);
201 
202  // set the new column spec to the storage list.
203  storageList.setProperty(SBProperties.defaultColumnSpec, defaultSpec);
204  storageList.setProperty(SBProperties.columnSpec, userSpec);
205  },
206 
207  _getColumn: function(aColumnArray, aPropertyID) {
208  for each (var column in aColumnArray) {
209  if (column.property == aPropertyID)
210  return column;
211  }
212  return null;
213  },
214 
215  _getColumnSpec: function(aMediaList) {
216  var parser = new ColumnSpecParser(aMediaList, null);
217  return parser.columnMap;
218  },
219 
220  _getDefaultSortDirection: function(prop) {
221  var pm = Components.classes["@songbirdnest.com/Songbird/Properties/PropertyManager;1"]
222  .getService(Components.interfaces.sbIPropertyManager);
223  var info = pm.getPropertyInfo(prop);
224  switch (info.type) {
225  case "datetime":
226  case "number":
227  case "boolean":
228  case "duration":
229  case "rating":
230  return "d";
231  case "text":
232  case "uri":
233  return "a";
234  }
235  return "d";
236  },
237 
238  _isDummyProperty: function(aProperty) {
239  var pm = Cc["@songbirdnest.com/Songbird/Properties/PropertyManager;1"]
240  .getService(Components.interfaces.sbIPropertyManager);
241  var info = pm.getPropertyInfo(aProperty);
242  return (info instanceof Ci.sbIDummyPropertyInfo);
243  }
244 }
var registrar
function width(ele) rect(ele).width
return null
Definition: FeedWriter.js:1143
Javascript wrappers for common library tasks.
_getSelectedPageStyle s i