home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Freelog 112
/
FreelogNo112-NovembreDecembre2012.iso
/
Multimedia
/
Songbird
/
Songbird_2.0.0-2311_windows-i686-msvc8.exe
/
components
/
sbPlaylistCommandsBuilder.js
< prev
next >
Wrap
Text File
|
2012-06-08
|
53KB
|
1,419 lines
/*
*=BEGIN SONGBIRD GPL
*
* This file is part of the Songbird web player.
*
* Copyright(c) 2005-2011 POTI, Inc.
* http://www.songbirdnest.com
*
* This file may be licensed under the terms of of the
* GNU General Public License Version 2 (the ``GPL'').
*
* Software distributed under the License is distributed
* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the GPL for the specific language
* governing rights and limitations.
*
* You should have received a copy of the GPL along with this
* program. If not, go to http://www.gnu.org/licenses/gpl.html
* or write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*=END SONGBIRD GPL
*/
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://app/jsmodules/ArrayConverter.jsm");
Components.utils.import("resource://app/jsmodules/DebugUtils.jsm");
const Ci = Components.interfaces;
const SONGBIRD_PLAYLISTCOMMANDSBUILDER_CONTRACTID = "@songbirdnest.com/Songbird/PlaylistCommandsBuilder;1";
const SONGBIRD_PLAYLISTCOMMANDSBUILDER_CLASSNAME = "Songbird Playlist Commands Builder";
const SONGBIRD_PLAYLISTCOMMANDSBUILDER_CID = Components.ID("{18c4b63c-d5b4-4aa2-918f-a31304d254ec}");
const SONGBIRD_PLAYLISTCOMMANDSBUILDER_IID = Ci.sbIPlaylistCommandsBuilder;
const SONGBIRD_PLAYLISTCOMMANDS_TYPE_ACTION = "action";
const SONGBIRD_PLAYLISTCOMMANDS_TYPE_SEPARATOR = "separator";
const SONGBIRD_PLAYLISTCOMMANDS_TYPE_MENU = "submenu";
const SONGBIRD_PLAYLISTCOMMANDS_TYPE_FLAG = "flag";
const SONGBIRD_PLAYLISTCOMMANDS_TYPE_VALUE = "value";
const SONGBIRD_PLAYLISTCOMMANDS_TYPE_CHOICE = "choice";
const SONGBIRD_PLAYLISTCOMMANDS_TYPE_CHOICEITEM = "choiceitem";
const SONGBIRD_PLAYLISTCOMMANDS_TYPE_CUSTOM = "custom";
const SONGBIRD_PLAYLISTCOMMANDS_TYPE_SUBOBJECT = "subobject";
const SONGBIRD_PLAYLISTCOMMANDSBUILDER_APPEND = 0;
const SONGBIRD_PLAYLISTCOMMANDSBUILDER_BEFORE = 1;
const SONGBIRD_PLAYLISTCOMMANDSBUILDER_AFTER = 2;
// ----------------------------------------------------------------------------
function PlaylistCommandsBuilder() {
this.m_Context.commands = this;
this.m_root_commands = new Array();
this.m_menus = new Array();
var menuitem = { id : null,
m_Type : SONGBIRD_PLAYLISTCOMMANDS_TYPE_MENU,
m_Menu : this.m_root_commands};
this.m_menus.push(menuitem);
this.m_listeners = new Array();
this.id = null;
this.parentCommandObject = null;
this.targetFlags = 0;
}
// ----------------------------------------------------------------------------
PlaylistCommandsBuilder.prototype.constructor = PlaylistCommandsBuilder;
// ----------------------------------------------------------------------------
PlaylistCommandsBuilder.prototype = {
classDescription: SONGBIRD_PLAYLISTCOMMANDSBUILDER_CLASSNAME,
classID: SONGBIRD_PLAYLISTCOMMANDSBUILDER_CID,
contractID: SONGBIRD_PLAYLISTCOMMANDSBUILDER_CONTRACTID,
m_Context : {
medialist : null,
playlist : null,
window : null,
commands : null,
implementorContext: null,
QueryInterface : XPCOMUtils.generateQI([Ci.sbIPlaylistCommandsContext,
Ci.sbIPlaylistCommandsBuilderContext]),
},
m_menus : null,
m_root_commands : null,
m_InitCallback : null,
m_ShutdownCallback : null,
m_VisibleCallback : null,
m_listeners : null,
/**
* ----------------------------------------------------------------------------
* sbIPlaylistCommandsBuilder Implementation
* ----------------------------------------------------------------------------
*/
// ----------------------------------------------------------------------------
// Submenus
// ----------------------------------------------------------------------------
init: function PlaylistCommandsBuilder_init(aId)
{
this.m_menus[0].id = aId;
this.id = aId;
},
appendSubmenu: function
PlaylistCommandsBuilder_appendSubmenu(aParentSubMenuId,
aSubMenuId,
aLabel,
aTooltipText)
{
var props = { m_Name : aLabel,
m_Tooltip : aTooltipText };
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_APPEND,
null,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_MENU,
aSubMenuId,
props);
},
insertSubmenuBefore: function
PlaylistCommandsBuilder_insertSubmenuBefore(aParentSubMenuId,
aBeforeId,
aSubMenuId,
aLabel,
aTooltipText)
{
var props = { m_Name : aLabel,
m_Tooltip : aTooltipText };
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_BEFORE,
aBeforeId,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_MENU,
aSubMenuId,
props);
},
insertSubmenuAfter: function
PlaylistCommandsBuilder_insertSubmenuAfter(aParentSubMenuId,
aAfterId,
aSubMenuId,
aLabel,
aTooltipText)
{
var props = { m_Name : aLabel,
m_Tooltip : aTooltipText };
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_AFTER,
aAfterId,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_MENU,
aSubMenuId,
props);
},
// ----------------------------------------------------------------------------
// Actions
// ----------------------------------------------------------------------------
appendAction: function
PlaylistCommandsBuilder_appendAction(aParentSubMenuId,
aId,
aLabel,
aTooltipText,
aTriggerCallback)
{
var props = { m_Name : aLabel,
m_Tooltip : aTooltipText,
m_TriggerCallback : aTriggerCallback }
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_APPEND,
null,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_ACTION,
aId,
props);
},
insertActionBefore:
function PlaylistCommandsBuilder_insertActionBefore(aParentSubMenuId,
aBeforeId,
aId,
aLabel,
aTooltipText,
aTriggerCallback)
{
var props = { m_Name : aLabel,
m_Tooltip : aTooltipText,
m_TriggerCallback : aTriggerCallback }
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_BEFORE,
aBeforeId,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_ACTION,
aId,
props);
},
insertActionAfter: function
PlaylistCommandsBuilder_insertActionAfter(aParentSubMenuId,
aAfterId,
aId,
aLabel,
aTooltipText,
aTriggerCallback)
{
var props = { m_Name : aLabel,
m_Tooltip : aTooltipText,
m_TriggerCallback : aTriggerCallback }
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_AFTER,
aAfterId,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_ACTION,
aId,
props);
},
// ----------------------------------------------------------------------------
// Separators
// ----------------------------------------------------------------------------
appendSeparator: function
PlaylistCommandsBuilder_appendSeparator(aParentSubMenuId, aId)
{
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_APPEND,
null,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_SEPARATOR,
aId);
},
insertSeparatorBefore: function
PlaylistCommandsBuilder_insertSeparatorBefore(aParentSubMenuId,
aBeforeId,
aId)
{
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_BEFORE,
aBeforeId,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_SEPARATOR,
aId);
},
insertSeparatorAfter: function
PlaylistCommandsBuilder_insertSeparatorAfter(aParentSubMenuId,
aAfterId,
aId)
{
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_AFTER,
aAfterId,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_SEPARATOR,
aId);
},
// ----------------------------------------------------------------------------
// Flag
// ----------------------------------------------------------------------------
appendFlag: function
PlaylistCommandsBuilder_appendFlag(aParentSubMenuId,
aId,
aLabel,
aTooltipText,
aTriggerCallback,
aValueCallback)
{
var props = { m_Name : aLabel,
m_Tooltip : aTooltipText,
m_TriggerCallback : aTriggerCallback,
m_ValueCallback : aValueCallback };
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_APPEND,
null,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_FLAG,
aId,
props);
},
insertFlagBefore: function
PlaylistCommandsBuilder_insertFlagBefore(aParentSubMenuId,
aBeforeId,
aId,
aLabel,
aTooltipText,
aTriggerCallback,
aValueCallback)
{
var props = { m_Name : aLabel,
m_Tooltip : aTooltipText,
m_TriggerCallback : aTriggerCallback,
m_ValueCallback : aValueCallback };
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_BEFORE,
aBeforeId,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_FLAG,
aId,
props);
},
insertFlagAfter: function
PlaylistCommandsBuilder_insertFlagAfter(aParentSubMenuId,
aAfterId,
aId,
aLabel,
aTooltipText,
aTriggerCallback,
aValueCallback)
{
var props = { m_Name : aLabel,
m_Tooltip : aTooltipText,
m_TriggerCallback : aTriggerCallback,
m_ValueCallback : aValueCallback };
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_AFTER,
aAfterId,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_FLAG,
aId,
props);
},
// ----------------------------------------------------------------------------
// Value
// ----------------------------------------------------------------------------
appendValue: function
PlaylistCommandsBuilder_appendValue(aParentSubMenuId,
aId,
aLabel,
aTooltipText,
aTriggerCallback,
aValueCallback)
{
var props = { m_Name : aLabel,
m_Tooltip : aTooltipText,
m_TriggerCallback : aTriggerCallback,
m_ValueCallback : aValueCallback };
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_APPEND,
null,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_VALUE,
aId,
props);
},
insertValueBefore: function
PlaylistCommandsBuilder_insertValueBefore(aParentSubMenuId,
aBeforeId,
aId,
aLabel,
aTooltipText,
aTriggerCallback,
aValueCallback)
{
var props = { m_Name : aLabel,
m_Tooltip : aTooltipText,
m_TriggerCallback : aTriggerCallback,
m_ValueCallback : aValueCallback };
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_BEFORE,
aBeforeId,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_VALUE,
aId,
props);
},
insertValueAfter: function
PlaylistCommandsBuilder_insertValueAfter(aParentSubMenuId,
aAfterId,
aId,
aLabel,
aTooltipText,
aTriggerCallback,
aValueCallback)
{
var props = { m_Name : aLabel,
m_Tooltip : aTooltipText,
m_TriggerCallback : aTriggerCallback,
m_ValueCallback : aValueCallback };
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_AFTER,
aAfterId,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_VALUE,
aId,
props);
},
// ----------------------------------------------------------------------------
// Choice menus
// ----------------------------------------------------------------------------
appendChoiceMenu: function
PlaylistCommandsBuilder_appendChoiceMenu(aParentSubMenuId,
aId,
aLabel,
aTooltipText,
aItemCallback)
{
var props = { m_Name : aLabel,
m_Tooltip : aTooltipText,
m_ItemCallback : aItemCallback };
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_APPEND,
null,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_CHOICE,
aId,
props);
},
insertChoiceMenuBefore: function
PlaylistCommandsBuilder_insertChoiceMenuBefore(aParentSubMenuId,
aBeforeId,
aId,
aLabel,
aTooltipText,
aItemCallback)
{
var props = { m_Name : aLabel,
m_Tooltip : aTooltipText,
m_ItemCallback : aItemCallback };
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_BEFORE,
aBeforeId,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_CHOICE,
aId,
props);
},
insertChoiceMenuAfter: function
PlaylistCommandsBuilder_insertChoiceMenuAfter(aParentSubMenuId,
aAfterId,
aId,
aLabel,
aTooltipText,
aItemCallback)
{
var props = { m_Name : aLabel,
m_Tooltip : aTooltipText,
m_ItemCallback : aItemCallback };
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_AFTER,
aAfterId,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_CHOICE,
aId,
props);
},
// ----------------------------------------------------------------------------
// Choice Menu Items
// ----------------------------------------------------------------------------
appendChoiceMenuItem: function
PlaylistCommandsBuilder_appendChoiceMenuItem(aParentSubMenuId,
aId,
aLabel,
aTooltipText,
aTriggerCallback)
{
var props = { m_Name : aLabel,
m_Tooltip : aTooltipText,
m_TriggerCallback : aTriggerCallback };
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_APPEND,
null,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_CHOICEITEM,
aId,
props);
},
insertChoiceMenuItemBefore: function
PlaylistCommandsBuilder_insertChoiceMenuItemBefore(aParentSubMenuId,
aBeforeId,
aId,
aLabel,
aTooltipText,
aTriggerCallback)
{
var props = { m_Name : aLabel,
m_Tooltip : aTooltipText,
m_TriggerCallback : aTriggerCallback };
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_BEFORE,
aBeforeId,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_CHOICEITEM,
aId,
props);
},
insertChoiceMenuItemAfter: function
PlaylistCommandsBuilder_insertChoiceMenuItemAfter(aParentSubMenuId,
aAfterId,
aId,
aLabel,
aTooltipText,
aTriggerCallback)
{
var props = { m_Name : aLabel,
m_Tooltip : aTooltipText,
m_TriggerCallback : aTriggerCallback };
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_AFTER,
aAfterId,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_CHOICEITEM,
aId,
props);
},
// ----------------------------------------------------------------------------
// Custom Items
// ----------------------------------------------------------------------------
appendCustomItem: function
PlaylistCommandsBuilder_appendCustomItem(aParentSubMenuId,
aId,
aInstantiationCallback,
aRefreshCallback)
{
var props = { m_InstantiationCallback : aInstantiationCallback,
m_RefreshCallback : aRefreshCallback};
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_APPEND,
null,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_CUSTOM,
aId,
props);
},
insertCustomItemBefore: function
PlaylistCommandsBuilder_insertCustomItemBefore(aParentSubMenuId,
aBeforeId,
aId,
aInstantiationCallback,
aRefreshCallback)
{
var props = { m_InstantiationCallback : aInstantiationCallback,
m_RefreshCallback : aRefreshCallback};
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_BEFORE,
aBeforeId,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_CUSTOM,
aId,
props);
},
insertCustomItemAfter: function
PlaylistCommandsBuilder_insertCustomItemAfter(aParentSubMenuId,
aAfterId,
aId,
aInstantiationCallback,
aRefreshCallback)
{
var props = { m_InstantiationCallback : aInstantiationCallback,
m_RefreshCallback : aRefreshCallback};
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_AFTER,
aAfterId,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_CUSTOM,
aId,
props);
},
// ----------------------------------------------------------------------------
// sbIPlaylistCommands Items
// ----------------------------------------------------------------------------
appendPlaylistCommands: function
PlaylistCommandsBuilder_appendPlaylistCommands(aParentSubMenuId,
aId,
aPlaylistCommands)
{
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_APPEND,
null,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_SUBOBJECT,
aId,
null,
aPlaylistCommands);
},
insertPlaylistCommandsBefore: function
PlaylistCommandsBuilder_insertPlaylistCommandsBefore(aParentSubMenuId,
aBeforeId,
aId,
aPlaylistCommands)
{
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_BEFORE,
aBeforeId,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_SUBOBJECT,
aId,
null,
aPlaylistCommands);
},
insertPlaylistCommandsAfter: function
PlaylistCommandsBuilder_insertPlaylistCommandsAfter(aParentSubMenuId,
aAfterId,
aId,
aPlaylistCommands)
{
this._insertCommand(SONGBIRD_PLAYLISTCOMMANDSBUILDER_AFTER,
aAfterId,
aParentSubMenuId,
SONGBIRD_PLAYLISTCOMMANDS_TYPE_SUBOBJECT,
aId,
null,
aPlaylistCommands);
},
// ----------------------------------------------------------------------------
setCommandShortcut: function
PlaylistCommandsBuilder_setCommandShortcut(aParentSubMenuId,
aCommandId,
aShortcutKey,
aShortcutKeyCode,
aShortcutModifiers,
aShortcutIsLocal)
{
var props = { m_ShortcutKey : aShortcutKey,
m_ShortcutKeycode : aShortcutKeyCode,
m_ShortcutModifiers : aShortcutModifiers,
m_ShortcutIsLocal : aShortcutIsLocal };
this._setCommandProperties(aParentSubMenuId, aCommandId, props);
},
setCommandEnabledCallback: function
PlaylistCommandsBuilder_setCommandEnabledCallback(aParentSubMenuId,
aCommandId,
aEnabledCallback)
{
var props = { m_EnabledCallback : aEnabledCallback };
this._setCommandProperties(aParentSubMenuId, aCommandId, props);
},
setCommandVisibleCallback: function
PlaylistCommandsBuilder_setCommandVisibleCallback(aParentSubMenuId,
aCommandId,
aVisibleCallback)
{
var props = { m_VisibleCallback : aVisibleCallback };
this._setCommandProperties(aParentSubMenuId, aCommandId, props);
},
setInitCallback: function
PlaylistCommandsBuilder_setInitCallback(aInitCallback)
{
this.m_InitCallback = aInitCallback;
},
setShutdownCallback: function
PlaylistCommandsBuilder_setShutdownCallback(aShutdownCallback)
{
this.m_ShutdownCallback = aShutdownCallback;
},
setVisibleCallback: function
PlaylistCommandsBuilder_setVisibleCallback(aVisibleCallback)
{
this.m_VisibleCallback = aVisibleCallback;
},
// ----------------------------------------------------------------------------
removeCommand: function
PlaylistCommandsBuilder_removeCommand(aParentSubMenuId,
aCommandId)
{
var menu = this._getMenu(aParentSubMenuId);
var index = this._getCommandIndex(menu, aCommandId);
if (index != -1)
{
this._removeCommandTree(menu, index);
}
else {
this.LOG("A command object with an id of " + aCommandId +
" could not be found for removal");
}
},
removeAllCommands: function
PlaylistCommandsBuilder_removeAllCommands(aParentSubMenuId)
{
var menu = this._getMenu(aParentSubMenuId);
while (menu.length) {
this._removeCommandTree(menu, 0);
}
if (!aParentSubMenuId) {
// after removing all commands, the only remaining menu is the root menu
if (this.m_menus.length != 1) {
throw new Error("Menu list is not empty after removeAllCommands (item 1 = " +
this.m_menus[1].id + ")");
}
}
},
shutdown: function PlaylistCommandsBuilder_shutdown()
{
// empty arrays, remove any remaining sbIPlaylistCommands reference
// this also removes all references to item callback functions
this.removeAllCommands();
// reset references for all callback functions for the entire command set
this.m_InitCallback = null;
this.m_ShutdownCallback = null;
this.m_VisibleCallback = null;
// and forget context
if (this.m_Context)
{
this.m_Context.playlist = null;
this.m_Context.medialist = null;
this.m_Context.window = null;
this.m_Context.commands = this;
this.m_Context = null;
this.m_CommandSubObject = null;
this.parentCommandObject = null;
}
},
// ----------------------------------------------------------------------------
_insertCommand: function
PlaylistCommandsBuilder__insertCommand(aInsertHow,
aRefPointId,
aParentSubMenuId,
aType,
aId,
aPropArray,
aCommandSubObject)
{
if (!aId) return;
switch (aType) {
case SONGBIRD_PLAYLISTCOMMANDS_TYPE_ACTION:
case SONGBIRD_PLAYLISTCOMMANDS_TYPE_SEPARATOR:
case SONGBIRD_PLAYLISTCOMMANDS_TYPE_MENU:
case SONGBIRD_PLAYLISTCOMMANDS_TYPE_FLAG:
case SONGBIRD_PLAYLISTCOMMANDS_TYPE_VALUE:
case SONGBIRD_PLAYLISTCOMMANDS_TYPE_CHOICE:
case SONGBIRD_PLAYLISTCOMMANDS_TYPE_CHOICEITEM:
case SONGBIRD_PLAYLISTCOMMANDS_TYPE_CUSTOM:
case SONGBIRD_PLAYLISTCOMMANDS_TYPE_SUBOBJECT:
break;
default:
// unknown type !
throw new Error("Unknown type in insertCommand");
}
var menu = this._getMenu(aParentSubMenuId);
var index = this._getCommandIndex(menu, aId);
if (index >= 0) {
throw new Error("Duplicate command '" +
aId +
"' in menu '" +
(aParentSubMenuId ? aParentSubMenuId : "<rootmenu>"));
}
var refindex = ((aInsertHow != SONGBIRD_PLAYLISTCOMMANDSBUILDER_APPEND) &&
aRefPointId) ?
this._getCommandIndex(menu, aRefPointId) : -1;
var vrefindex = refindex;
switch (aInsertHow) {
case SONGBIRD_PLAYLISTCOMMANDSBUILDER_APPEND:
break;
case SONGBIRD_PLAYLISTCOMMANDSBUILDER_AFTER:
vrefindex++;
// fallthru
case SONGBIRD_PLAYLISTCOMMANDSBUILDER_BEFORE:
if (refindex < 0) {
throw new Error("Reference command '" +
aRefPointId +
"' not found in menu '" +
(aParentSubMenuId ? aParentSubMenuId : "<rootmenu>"));
}
break;
}
this._insertCommandInArray(menu,
vrefindex,
aType,
aId,
aPropArray,
aCommandSubObject);
},
_insertCommandInArray: function
PlaylistCommandsBuilder__insertCommandInArray(aMenu,
aInsertionIndex,
aType,
aId,
aPropArray,
aCommandSubObject)
{
var item = { m_ParentMenu : aMenu,
m_Type : aType,
id : aId };
if (aPropArray) {
for (var i in aPropArray) {
item[i] = aPropArray[i];
}
}
switch (aType) {
case SONGBIRD_PLAYLISTCOMMANDS_TYPE_SEPARATOR:
item.m_Flex = 1;
item.m_Name = "*separator*";
break;
case SONGBIRD_PLAYLISTCOMMANDS_TYPE_SUBOBJECT:
if (!aCommandSubObject) return 0;
aCommandSubObject = aCommandSubObject.QueryInterface(Components.
interfaces.
sbIPlaylistCommands);
aCommandSubObject.parentCommandObject = this;
item.m_CommandSubObject = aCommandSubObject;
break;
case SONGBIRD_PLAYLISTCOMMANDS_TYPE_MENU:
case SONGBIRD_PLAYLISTCOMMANDS_TYPE_CHOICE:
var menuitem = { id : aId,
m_Type : aType,
m_Menu : new Array() };
if (aType == SONGBIRD_PLAYLISTCOMMANDS_TYPE_CHOICE) {
menuitem.m_ItemCallback = aPropArray.m_ItemCallback;
}
this.m_menus.push(menuitem);
break;
}
// insert the item in the menu at the requested position
if (aInsertionIndex < 0 || aInsertionIndex >= aMenu.length)
aMenu.push(item);
else
aMenu.splice(aInsertionIndex, 0, item);
},
_removeCommandTree: function
PlaylistCommandsBuilder__removeCommandTree(aMenu, aIndex) {
if (aIndex >= aMenu.length || aIndex < 0) {
throw new Error("Invalid index " + aIndex + " in _removeCommandTree");
}
var item = aMenu[aIndex];
if (item.m_Type == SONGBIRD_PLAYLISTCOMMANDS_TYPE_MENU ||
item.m_Type == SONGBIRD_PLAYLISTCOMMANDS_TYPE_CHOICE) {
var submenu = this._getMenu(item.id);
if (submenu && submenu != this.m_root_commands) {
while(submenu.length > 0) {
this._removeCommandTree(submenu, 0);
}
var idx = this._getMenuIndex(item.id);
if (idx > 0 && idx < this.m_menus.length) { // yes, '>', we do not want the root menu
// discard the item callback in case this is a choicemenu
this.m_menus[idx].m_ItemCallback = null;
// command array is empty by now, discard it now
this.m_menus[idx].m_Menu = null;
// remove the menu entry
this.m_menus.splice(idx, 1);
}
}
}
// Remove the command item
aMenu[aIndex].m_InstantiationCallback = null;
aMenu[aIndex].m_RefreshCallback = null;
aMenu[aIndex].m_ValueCallback = null;
aMenu[aIndex].m_EnabledCallback = null;
aMenu[aIndex].m_VisibleCallback = null;
aMenu[aIndex].m_TriggerCallback = null;
aMenu.splice(aIndex, 1);
},
_getMenu: function PlaylistCommandsBuilder__getMenu(aSubMenuId)
{
// null is the root menu
if (!aSubMenuId) return this.m_root_commands;
for (var i=0;i<this.m_menus.length;i++) {
if (this.m_menus[i].id == aSubMenuId) {
return this.m_menus[i].m_Menu;
}
}
throw new Error("Submenu " + aSubMenuId + " not found");
},
_getMenuIndex: function PlaylistCommandsBuilder__getMenuIndex(aSubMenuId)
{
if (!aSubMenuId) return 0;
for (var i=0;i<this.m_menus.length;i++) {
if (this.m_menus[i].id == aSubMenuId) {
return i;
}
}
throw new Error("Submenu " + aSubMenuId + " not found");
return -1;
},
_getCommandIndex: function
PlaylistCommandsBuilder__getCommandIndex(aSubMenu, aCommandId)
{
if (!aSubMenu) return -1;
for (var i=0;i<aSubMenu.length;i++) {
if (aSubMenu[i].id == aCommandId) {
return i;
}
}
return -1;
},
_getCommandProperty: function
PlaylistCommandsBuilder__getCommandProperty(aSubMenuId,
aIndex,
aHost,
aProperty,
aDefault)
{
try {
var menu = this._getMenu(aSubMenuId);
if (!menu) return aDefault;
if (aIndex >= menu.length) return aDefault;
var prop = menu[aIndex][aProperty];
if (prop === undefined) return aDefault;
if (typeof(prop) == "object" && prop.handleCallback) {
return prop.handleCallback(this.m_Context,
aSubMenuId,
menu[aIndex].id,
aHost,
aProperty.substr(2));
}
return prop;
} catch (e) {
this.LOG("_getCommandProperty(" + aSubMenuId + ", " + aIndex + " (" +
menu[aIndex].id + "), " + aHost + ", " + aProperty + ", " +
aDefault + ") - " + e);
}
return aDefault;
},
_getMenuProperty: function
PlaylistCommandsBuilder__getMenuProperty(aMenu, aHost, aProperty, aDefault)
{
try {
var prop = aMenu[aProperty];
if (prop === undefined) return aDefault;
if (typeof(prop) == "object" && prop.handleCallback) {
return prop.handleCallback(this.m_Context,
aMenu.m_ParentMenu,
aMenu.id,
aHost,
aProperty.substr(2));
}
return prop;
} catch (e) {
this.LOG("_getMenuProperty(" + aMenu.id + ", " + aHost +
", " + aProperty + ", " + aDefault + ") - " + e);
}
return aDefault;
},
_setCommandProperties: function
PlaylistCommandsBuilder__setCommandProperties(aSubMenuId, aCommandId, aPropArray)
{
var menu = this._getMenu(aSubMenuId);
var index = this._getCommandIndex(menu, aCommandId);
if (index >= menu.length || index < 0) {
throw new Error("Invalid command index " + index + " in _setCommandProperties");
}
for (var i in aPropArray) {
menu[index][i] = aPropArray[i];
}
},
// not used for now, this may eventually be needed if we want to allow
// changing the item callback for a choicemenu
_setMenuProperties: function
PlaylistCommandsBuilder__setMenuProperties(aMenu, aPropArray)
{
for (var i in aPropArray) {
aMenu[i] = aPropArray[i];
}
},
/**
* ----------------------------------------------------------------------------
* sbIPlaylistCommands Implementation
* ----------------------------------------------------------------------------
*/
addCommandObject: function PlaylistCommandsBuilder_addCommandObject
( aCommandObject )
{
this.appendPlaylistCommands(null,
aCommandObject.id,
aCommandObject);
this.notifyListeners("onCommandAdded", aCommandObject);
},
removeCommandObject: function PlaylistCommandsBuilder_removeCommandObject
( aCommandObject )
{
this.removeCommand(null, aCommandObject.id);
this.notifyListeners("onCommandRemoved", aCommandObject);
},
addListener: function PlaylistCommandsBuilder_addListener ( aListener )
{
this.m_listeners.push(aListener);
},
removeListener: function PlaylistCommandsBuilder_removeListener ( aListener )
{
let index = this.m_listeners.indexOf(aListener);
if (index >= 0) {
// remove it
this.m_listeners.splice(index, 1);
}
},
notifyListeners: function PlaylistCommandsBuilder_notifyListeners
( aTriggerFunction, aCommandObject )
{
for (var i = 0 ; i < this.m_listeners.length; i++) {
var listener = this.m_listeners[i]
if (listener instanceof Ci.sbIPlaylistCommandsListener)
{
try
{
listener[aTriggerFunction](aCommandObject);
}
catch (err) {
Components.utils.reportError("Could not signal " + aTriggerFunction +
" to PlaylistCommandsListener. Failed with error: " + err.description);
}
}
}
if (this.parentCommandObject)
{
// bubble the signal to the parent command object
this.parentCommandObject.notifyListeners(aTriggerFunction, aCommandObject);
}
},
getVisible: function PlaylistCommandsBuilder_getVisible( aHost )
{
if (this.m_VisibleCallback &&
typeof(this.m_VisibleCallback) == "object" &&
this.m_VisibleCallback.handleCallback) {
return this.m_VisibleCallback.handleCallback(this.m_Context, aHost, "Visible");
}
return true;
},
getNumCommands: function
PlaylistCommandsBuilder_getNumCommands( aSubMenuId, aHost )
{
var menu = this._getMenu(aSubMenuId);
return menu.length;
},
getCommandId: function
PlaylistCommandsBuilder_getCommandId( aSubMenuId, aIndex, aHost )
{
return this._getCommandProperty(aSubMenuId,
aIndex,
aHost,
"id",
"");
},
getCommandType: function
PlaylistCommandsBuilder_getCommandType( aSubMenuId, aIndex, aHost )
{
return this._getCommandProperty(aSubMenuId,
aIndex,
aHost,
"m_Type",
"");
},
getCommandText: function
PlaylistCommandsBuilder_getCommandText( aSubMenuId, aIndex, aHost )
{
return this._getCommandProperty(aSubMenuId,
aIndex,
aHost,
"m_Name",
"");
},
getCommandFlex: function
PlaylistCommandsBuilder_getCommandFlex( aSubMenuId, aIndex, aHost )
{
return this._getCommandProperty(aSubMenuId,
aIndex,
aHost,
"m_Flex",
false);
},
getCommandToolTipText: function
PlaylistCommandsBuilder_getCommandToolTipText( aSubMenuId, aIndex, aHost )
{
return this._getCommandProperty(aSubMenuId,
aIndex,
aHost,
"m_Tooltip",
"");
},
getCommandValue: function
PlaylistCommandsBuilder_getCommandValue( aSubMenuId, aIndex, aHost )
{
return this._getCommandProperty(aSubMenuId,
aIndex,
aHost,
"m_ValueCallback",
"");
},
instantiateCustomCommand: function
PlaylistCommandsBuilder_instantiateCustomCommand( aSubMenuId,
aIndex,
aHost,
aId,
aDocument )
{
var menu = this._getMenu(aSubMenuId);
if (aIndex >= menu.length || aIndex < 0) {
throw new Error("Invalid index " + index + " in instantiateCustomCommand");
}
var cb = menu[aIndex].m_InstantiationCallback;
if (cb) return cb.handleCallback(this.m_Context,
menu[aIndex].m_ParentMenu,
menu[aIndex].id,
aHost,
aDocument);
throw new Error("No custom command instantiation callback defined for command " + aId);
},
refreshCustomCommand: function
PlaylistCommandsBuilder_refreshCustomCommand( aSubMenuId,
aIndex,
aHost,
aId,
aElement )
{
var menu = this._getMenu(aSubMenuId);
if (aIndex >= menu.length || aIndex < 0) {
throw new Error("Invalid index " + index + " in refreshCustomCommand");
}
var cb = menu[aIndex].m_RefreshCallback;
if (cb) cb.handleCallback(this.m_Context,
menu[aIndex].m_ParentMenu,
menu[aIndex].id,
aHost,
aElement);
},
getCommandVisible: function
PlaylistCommandsBuilder_getCommandVisible( aSubMenuId, aIndex, aHost )
{
return this._getCommandProperty(aSubMenuId,
aIndex,
aHost,
"m_VisibleCallback",
true);
},
getCommandFlag: function
PlaylistCommandsBuilder_getCommandFlag( aSubMenuId, aIndex, aHost )
{
return this._getCommandProperty(aSubMenuId,
aIndex,
aHost,
"m_ValueCallback",
false);
},
getCommandChoiceItem: function
PlaylistCommandsBuilder_getCommandChoiceItem( aChoiceMenu, aHost )
{
var menuindex = this._getMenuIndex(aChoiceMenu);
if (menuindex < 0 || menuindex >= this.m_menus.length) {
throw new Error("Choice menu id not found : " + aChoiceMenu + " in getCommandChoiceItem");
}
var menu = this.m_menus[menuindex];
if (menu.m_Type != SONGBIRD_PLAYLISTCOMMANDS_TYPE_CHOICE) return "";
return this._getMenuProperty(menu, aHost, "m_ItemCallback", "");
},
getCommandEnabled: function
PlaylistCommandsBuilder_getCommandEnabled( aSubMenuId, aIndex, aHost )
{
return this._getCommandProperty(aSubMenuId,
aIndex,
aHost,
"m_EnabledCallback",
true);
},
getCommandShortcutModifiers: function
PlaylistCommandsBuilder_getCommandShortcutModifiers( aSubMenuId, aIndex, aHost )
{
return this._getCommandProperty(aSubMenuId,
aIndex,
aHost,
"m_ShortcutModifiers",
"");
},
getCommandShortcutKey: function
PlaylistCommandsBuilder_getCommandShortcutKey( aSubMenuId, aIndex, aHost )
{
return this._getCommandProperty(aSubMenuId,
aIndex,
aHost,
"m_ShortcutKey",
"");
},
getCommandShortcutKeycode: function
PlaylistCommandsBuilder_getCommandShortcutKeycode( aSubMenuId, aIndex, aHost )
{
return this._getCommandProperty(aSubMenuId,
aIndex,
aHost,
"m_ShortcutKeycode",
"");
},
getCommandShortcutLocal: function
PlaylistCommandsBuilder_getCommandShortcutLocal( aSubMenuId, aIndex, aHost )
{
return this._getCommandProperty(aSubMenuId,
aIndex,
aHost,
"m_ShortcutIsLocal",
false);
},
getCommandSubObject: function
PlaylistCommandsBuilder_getCommandSubObject( aSubMenuId, aIndex, aHost )
{
return this._getCommandProperty(aSubMenuId,
aIndex,
aHost,
"m_CommandSubObject",
null);
},
getChildrenCommandObjects: function
PlaylistCommandsBuilder_getChildrenCommandObjects()
{
var subCommandArray = new Array();
for (var i=0; i < this.getNumCommands(null, null); i++) {
var subCommand = this.getCommandSubObject("", i, "");
subCommandArray.push(subCommand);
}
return ArrayConverter.enumerator(subCommandArray);
},
onCommand: function
PlaylistCommandsBuilder_onCommand(aSubMenuId, aIndex, aHost, id, value)
{
var menu = this._getMenu(aSubMenuId);
if (aIndex >= menu.length || aIndex < 0) {
throw new Error("Invalid index " + index + " in PlaylistCommandsBuilder::onCommand");
}
if (menu[aIndex].id != id) {
throw new Error("Id do not match in PlaylistCommandsBuilder::onCommand (" +
id +
"/" +
menu[aIndex].id +
")");
}
var cb = menu[aIndex].m_TriggerCallback;
if (cb === undefined || !cb.handleCallback) {
throw new Error("No callback defined for command " + id);
}
cb.handleCallback(this.m_Context,
aSubMenuId,
menu[aIndex].id,
aHost,
value);
},
duplicate: function PlaylistCommandsBuilder_duplicate()
{
// duplicate this
var obj = this.dupObject(this);
// after duplication, the arrays are shared between the two objects,
// so copy the command structure over to the new object, with new arrays
obj.m_menus = new Array();
for (var i=0;i<this.m_menus.length;i++) {
var menuitem = this.dupObject(this.m_menus[i]);
menuitem.m_Menu = new Array();
for (var j=0;j<this.m_menus[i].m_Menu.length;j++) {
var item = this.dupObject(this.m_menus[i].m_Menu[j]);
// if the item is an sbIPlaylistCommands sub-object, duplicate it as well
if (item.m_CommandSubObject) {
item.m_CommandSubObject = item.m_CommandSubObject.duplicate();
}
menuitem.m_Menu.push(item);
}
obj.m_menus.push(menuitem);
}
obj.m_root_commands = obj.m_menus[0].m_Menu;
obj.m_Context = this.dupObject(this.m_Context);
// return the copy
return obj;
},
dupObject: function PlaylistCommandsBuilder_dupObject(obj) {
var r = {};
for ( var i in obj )
{
r[ i ] = obj[ i ];
}
return r;
},
initCommands: function PlaylistCommandsBuilder_initCommands(aHost) {
for (var i=0;i<this.m_menus.length;i++) {
for (var j=0;j<this.m_menus[i].m_Menu.length;j++) {
if (this.m_menus[i].m_Menu[j].m_CommandSubObject) {
this.m_menus[i].m_Menu[j].m_CommandSubObject.initCommands(aHost);
}
}
}
if (this.m_InitCallback &&
typeof(this.m_InitCallback) == "object" &&
this.m_InitCallback.handleCallback) {
this.m_InitCallback.handleCallback(this.m_Context, aHost, null);
}
},
shutdownCommands: function PlaylistCommandsBuilder_shutdownCommands() {
for (var i=0;i<this.m_menus.length;i++) {
for (var j=0;j<this.m_menus[i].m_Menu.length;j++) {
if (this.m_menus[i].m_Menu[j].m_CommandSubObject) {
try {
this.m_menus[i].m_Menu[j].m_CommandSubObject.shutdownCommands();
}
catch (e)
{
Components.utils.reportError(e);
}
}
}
}
if (this.m_ShutdownCallback &&
typeof(this.m_ShutdownCallback) == "object" &&
this.m_ShutdownCallback.handleCallback) {
this.m_ShutdownCallback.handleCallback(this.m_Context, null, null);
}
this.shutdown();
},
setContext: function PlaylistCommandsBuilder_setContext( context )
{
for (var i=0;i<this.m_menus.length;i++) {
for (var j=0;j<this.m_menus[i].m_Menu.length;j++) {
if (this.m_menus[i].m_Menu[j].m_CommandSubObject) {
this.m_menus[i].m_Menu[j].m_CommandSubObject.setContext(context);
}
}
}
this.m_Context.playlist = context.playlist;
this.m_Context.medialist = context.medialist;
this.m_Context.window = context.window;
this.m_Context.commands = this;
},
// ----------------------------------------------------------------------------
LOG: DebugUtils.generateLogFunction("sbPlaylistCommandsBuilder"),
// ----------------------------------------------------------------------------
/**
* See nsISupports.idl
*/
QueryInterface: XPCOMUtils.generateQI([Ci.sbIPlaylistCommands,
Ci.sbIPlaylistCommandsBuilder]),
}; // PlaylistCommandsBuilder.prototype
function NSGetModule(compMgr, fileSpec) {
return XPCOMUtils.generateModule([PlaylistCommandsBuilder]);
}