Compare commits

..

No commits in common. "e4815f091d2d52c2e4a5e4f3625f7bd922e368bf" and "8788dd9fe8b43e2ff5409e7a513e24ba64578ed5" have entirely different histories.

8 changed files with 293 additions and 269 deletions

View file

@ -1,29 +0,0 @@
# -*- coding: utf-8 -*-
import os
from glob import glob
from django.core.management.base import BaseCommand
import app.monkey_patch
from ... import models
from ... import tasks
class Command(BaseCommand):
"""
rebuild posters for all items.
"""
help = 'rebuild all posters for all items.'
args = ''
def handle(self, **options):
offset = 0
chunk = 100
count = models.Item.objects.count()
while offset <= count:
for i in models.Item.objects.all().order_by('id')[offset:offset+chunk]:
print(i)
if i.poster:
i.poster.delete()
i.make_poster()
offset += chunk

View file

@ -4,12 +4,14 @@ pandora.ui.editDialog = function() {
var ui = pandora.user.ui, var ui = pandora.user.ui,
hasChanged = false, hasChanged = false,
ids = ui.listSelection, ids = ui.listSelection.filter(function(id) {
keys = ['editable'].concat(pandora.site.itemKeys.filter(function(key) { return pandora.$ui.list.value(id, 'editable');
}),
keys = pandora.site.itemKeys.filter(function(key) {
return key.id != '*' return key.id != '*'
}).map(function(key) { }).map(function(key) {
return key.id return key.id
})), }),
listKeys = pandora.site.itemKeys.filter(function(key) { listKeys = pandora.site.itemKeys.filter(function(key) {
return Ox.isArray(key.type); return Ox.isArray(key.type);
}).map(function(key){ }).map(function(key){
@ -88,46 +90,22 @@ pandora.ui.editDialog = function() {
}, function(result) { }, function(result) {
var data = {}, var data = {},
isMixed = {}, isMixed = {},
updateTitle = false, items = result.data.items;
items = result.data.items.filter(function(item) { keys.forEach(function(key) {
if (!item.editable) {
updateTitle = true
}
return item.editable;
});
if (updateTitle) {
that.options({
title: Ox._('Edit Metadata for {0}', [
Ox.formatNumber(items.length) + ' ' + Ox._(
items.length == 1 ? pandora.site.itemName.singular : pandora.site.itemName.plural
)
])
})
// no editable items
if (!items.length) {
that.close()
return
}
}
keys.filter(function(key) {
return key != 'editable'
}).forEach(function(key) {
var isArray = Ox.contains(listKeys, key), var isArray = Ox.contains(listKeys, key),
values = items.map(function(item) { values = items.map(function(item) {
return item[key]; return item[key];
}); });
if (isArray) { if (isArray) {
values = values.map(function(value) { values = values.map(function(value) {
value = value || [] return (value || []).join(separator);
return value.join ? value.join(separator) : value;
}); });
} }
if (Ox.unique(values).length > 1) { if (Ox.unique(values).length > 1) {
isMixed[key] = true; isMixed[key] = true;
} }
data[key] = isMixed[key] ? null data[key] = isMixed[key] ? null
: isArray && values.length ? values[0].split(separator) : isArray ? values[0].split(separator)
: values[0]; : values[0];
}); });
that.options({ that.options({

View file

@ -3,12 +3,14 @@
pandora.ui.editDocumentsDialog = function() { pandora.ui.editDocumentsDialog = function() {
var ui = pandora.user.ui, var ui = pandora.user.ui,
hasChanged = false, hasChanged = false,
ids = ui.collectionSelection, ids = ui.collectionSelection.filter(function(id) {
keys = ['editable'].concat(pandora.site.documentKeys.filter(function(key) { return pandora.$ui.list.value(id, 'editable');
}),
keys = pandora.site.documentKeys.filter(function(key) {
return key.id != '*' return key.id != '*'
}).map(function(key) { }).map(function(key) {
return key.id return key.id
})), }),
listKeys = pandora.site.documentKeys.filter(function(key) { listKeys = pandora.site.documentKeys.filter(function(key) {
return Ox.isArray(key.type); return Ox.isArray(key.type);
}).map(function(key){ }).map(function(key){
@ -87,31 +89,8 @@ pandora.ui.editDocumentsDialog = function() {
}, function(result) { }, function(result) {
var data = {}, var data = {},
isMixed = {}, isMixed = {},
updateTitle = false, items = result.data.items;
items = result.data.items.filter(function(item) { keys.forEach(function(key) {
if (!item.editable) {
updateTitle = true
}
return item.editable;
});
if (updateTitle) {
that.options({
title: Ox._('Edit Metadata for {0}', [
Ox.formatNumber(items.length) + ' ' + Ox._(
items.length == 1 ? 'Document' : 'Documents'
)
])
})
// no editable items
if (!items.length) {
that.close()
return
}
}
keys.filter(function(key) {
return key != 'editable'
}).forEach(function(key) {
var isArray = Ox.contains(listKeys, key), var isArray = Ox.contains(listKeys, key),
values = items.map(function(item) { values = items.map(function(item) {
return item[key]; return item[key];

View file

@ -198,7 +198,9 @@ pandora.ui.infoView = function(data, isMixed) {
top: margin + 'px', top: margin + 'px',
right: margin + 'px' right: margin + 'px'
}) })
.appendTo($info); .appendTo($info),
$capabilities;
[$options, $edit].forEach(function($element) { [$options, $edit].forEach(function($element) {
$element.find('input').css({ $element.find('input').css({
@ -344,7 +346,7 @@ pandora.ui.infoView = function(data, isMixed) {
.append(formatKey('Rights Level', 'statistics')) .append(formatKey('Rights Level', 'statistics'))
.append($rightsLevel) .append($rightsLevel)
.appendTo($statistics); .appendTo($statistics);
pandora.renderRightsLevel(that, $rightsLevel, data, isMixed, isMultiple, canEdit); renderRightsLevel();
// Notes -------------------------------------------------------------------- // Notes --------------------------------------------------------------------
@ -494,6 +496,15 @@ pandora.ui.infoView = function(data, isMixed) {
return ret; return ret;
} }
function getRightsLevelElement(rightsLevel) {
return Ox.Theme.formatColorLevel(
rightsLevel,
pandora.site.rightsLevels.map(function(rightsLevel) {
return rightsLevel.name;
})
);
}
function getValue(key, value) { function getValue(key, value) {
return !value ? '' return !value ? ''
: Ox.contains(specialListKeys, key) ? value.join('; ') : Ox.contains(specialListKeys, key) ? value.join('; ')
@ -501,6 +512,81 @@ pandora.ui.infoView = function(data, isMixed) {
: value; : value;
} }
function renderCapabilities(rightsLevel) {
var capabilities = [].concat(
canEdit ? [{name: 'canSeeItem', symbol: 'Find'}] : [],
[
{name: 'canPlayClips', symbol: 'PlayInToOut'},
{name: 'canPlayVideo', symbol: 'Play'},
{name: 'canDownloadVideo', symbol: 'Download'}
]
),
userLevels = canEdit ? pandora.site.userLevels : [pandora.user.level];
$capabilities.empty();
userLevels.forEach(function(userLevel, i) {
var $element,
$line = $('<div>')
.css({
height: '16px',
marginBottom: '4px'
})
.appendTo($capabilities);
if (canEdit) {
$element = Ox.Theme.formatColorLevel(i, userLevels.map(function(userLevel) {
return Ox.toTitleCase(userLevel);
}), [0, 240]);
Ox.Label({
textAlign: 'center',
title: Ox.toTitleCase(userLevel),
width: 60
})
.addClass('OxColor OxColorGradient')
.css({
float: 'left',
height: '12px',
paddingTop: '2px',
background: $element.css('background'),
fontSize: '8px',
color: $element.css('color')
})
.data({OxColor: $element.data('OxColor')})
.appendTo($line);
}
capabilities.forEach(function(capability) {
var hasCapability = pandora.hasCapability(capability.name, userLevel) >= rightsLevel,
$element = Ox.Theme.formatColorLevel(hasCapability, ['', '']);
Ox.Button({
tooltip: (canEdit ? Ox.toTitleCase(userLevel) : 'You') + ' '
+ (hasCapability ? 'can' : 'can\'t') + ' '
+ Ox.toSlashes(capability.name)
.split('/').slice(1).join(' ')
.toLowerCase(),
title: capability.symbol,
type: 'image'
})
.addClass('OxColor OxColorGradient')
.css({background: $element.css('background')})
.css('margin' + (canEdit ? 'Left' : 'Right'), '4px')
.data({OxColor: $element.data('OxColor')})
.appendTo($line);
});
if (!canEdit) {
Ox.Button({
title: Ox._('Help'),
tooltip: Ox._('About Rights'),
type: 'image'
})
.css({marginLeft: '52px'})
.bindEvent({
click: function() {
pandora.UI.set({page: 'rights'});
}
})
.appendTo($line);
}
});
}
function renderGroup(keys) { function renderGroup(keys) {
var $element; var $element;
keys.forEach(function(key) { displayedKeys.push(key) }); keys.forEach(function(key) { displayedKeys.push(key) });
@ -546,6 +632,53 @@ pandora.ui.infoView = function(data, isMixed) {
} }
} }
function renderRightsLevel() {
var $rightsLevelElement = getRightsLevelElement(data.rightslevel),
$rightsLevelSelect;
$rightsLevel.empty();
if (canEdit) {
$rightsLevelSelect = Ox.Select({
items: pandora.site.rightsLevels.map(function(rightsLevel, i) {
return {id: i, title: rightsLevel.name};
}),
width: 128,
value: data.rightslevel
})
.addClass('OxColor OxColorGradient')
.css({
marginBottom: '4px',
background: $rightsLevelElement.css('background')
})
.data({OxColor: $rightsLevelElement.data('OxColor')})
.bindEvent({
change: function(event) {
var rightsLevel = event.value;
$rightsLevelElement = getRightsLevelElement(rightsLevel);
$rightsLevelSelect
.css({background: $rightsLevelElement.css('background')})
.data({OxColor: $rightsLevelElement.data('OxColor')})
renderCapabilities(rightsLevel);
var edit = {
id: isMultiple ? ui.listSelection : data.id,
rightslevel: rightsLevel
};
pandora.api.edit(edit, function(result) {
that.triggerEvent('change', Ox.extend({}, 'rightslevel', rightsLevel));
});
}
})
.appendTo($rightsLevel);
} else {
$rightsLevelElement
.css({
marginBottom: '4px'
})
.appendTo($rightsLevel);
}
$capabilities = $('<div>').appendTo($rightsLevel);
renderCapabilities(data.rightslevel);
}
function toggleIconSize() { function toggleIconSize() {
iconSize = iconSize == 256 ? 512 : 256; iconSize = iconSize == 256 ? 512 : 256;
iconWidth = iconRatio > 1 ? iconSize : Math.round(iconSize * iconRatio); iconWidth = iconRatio > 1 ? iconSize : Math.round(iconSize * iconRatio);

View file

@ -204,7 +204,9 @@ pandora.ui.infoView = function(data, isMixed) {
top: margin + 'px', top: margin + 'px',
right: margin + 'px' right: margin + 'px'
}) })
.appendTo($info); .appendTo($info),
$capabilities;
[$options, $edit].forEach(function($element) { [$options, $edit].forEach(function($element) {
$element.find('input').css({ $element.find('input').css({
@ -435,7 +437,7 @@ pandora.ui.infoView = function(data, isMixed) {
.append(formatKey(Ox._('Rights Level'), 'statistics')) .append(formatKey(Ox._('Rights Level'), 'statistics'))
.append($rightsLevel) .append($rightsLevel)
.appendTo($statistics); .appendTo($statistics);
pandora.renderRightsLevel(that, $rightsLevel, data, isMixed, isMultiple, canEdit); renderRightsLevel();
// User and Groups --------------------------------------------------------- // User and Groups ---------------------------------------------------------
if (!isMultiple) { if (!isMultiple) {
@ -626,12 +628,100 @@ pandora.ui.infoView = function(data, isMixed) {
return formatLink(key, ret, key == 'date' && value); return formatLink(key, ret, key == 'date' && value);
} }
function getRightsLevelElement(rightsLevel) {
return Ox.Theme.formatColorLevel(
rightsLevel,
pandora.site.rightsLevels.map(function(rightsLevel) {
return rightsLevel.name;
})
);
}
function getValue(key, value) { function getValue(key, value) {
return !value ? '' return !value ? ''
: Ox.contains(listKeys, key) ? value.join(', ') : Ox.contains(listKeys, key) ? value.join(', ')
: value; : value;
} }
function renderCapabilities(rightsLevel) {
var capabilities = [].concat(
canEdit ? [{name: 'canSeeItem', symbol: 'Find'}] : [],
[
{name: 'canPlayClips', symbol: 'PlayInToOut'},
{name: 'canPlayVideo', symbol: 'Play'},
{name: 'canDownloadVideo', symbol: 'Download'}
]
),
userLevels = canEdit ? pandora.site.userLevels : [pandora.user.level];
$capabilities.empty();
userLevels.forEach(function(userLevel, i) {
var $element,
$line = $('<div>')
.css({
height: '16px',
marginBottom: '4px'
})
.appendTo($capabilities);
if (canEdit) {
$element = Ox.Theme.formatColorLevel(i, userLevels.map(function(userLevel) {
return Ox.toTitleCase(userLevel);
}), [0, 240]);
Ox.Label({
textAlign: 'center',
title: Ox._(Ox.toTitleCase(userLevel)),
width: 60
})
.addClass('OxColor OxColorGradient')
.css({
float: 'left',
height: '12px',
paddingTop: '2px',
background: $element.css('background'),
fontSize: '8px',
color: $element.css('color')
})
.data({OxColor: $element.data('OxColor')})
.appendTo($line);
}
capabilities.forEach(function(capability) {
var hasCapability = pandora.hasCapability(capability.name, userLevel) >= rightsLevel,
$element = Ox.Theme.formatColorLevel(hasCapability, ['', '']);
Ox.Button({
tooltip: Ox._('{0} '
+ (hasCapability ? 'can' : 'can\'t') + ' '
+ Ox.toSlashes(capability.name)
.split('/').slice(1).join(' ')
.toLowerCase()
.replace('see item', 'see the item')
.replace('play video', 'play the full video')
.replace('download video', 'download the video'),
[canEdit ? Ox._(Ox.toTitleCase(userLevel)) : Ox._('You')]),
title: capability.symbol,
type: 'image'
})
.addClass('OxColor OxColorGradient')
.css({background: $element.css('background')})
.css('margin' + (canEdit ? 'Left' : 'Right'), '4px')
.data({OxColor: $element.data('OxColor')})
.appendTo($line);
});
if (!canEdit) {
Ox.Button({
title: Ox._('Help'),
tooltip: Ox._('About Rights'),
type: 'image'
})
.css({marginLeft: '52px'})
.bindEvent({
click: function() {
pandora.UI.set({page: 'rights'});
}
})
.appendTo($line);
}
});
}
function renderGroup(keys) { function renderGroup(keys) {
var $element; var $element;
if (canEdit || keys.filter(function(key) { if (canEdit || keys.filter(function(key) {
@ -667,6 +757,53 @@ pandora.ui.infoView = function(data, isMixed) {
} }
} }
function renderRightsLevel() {
var $rightsLevelElement = getRightsLevelElement(data.rightslevel),
$rightsLevelSelect;
$rightsLevel.empty();
if (canEdit) {
$rightsLevelSelect = Ox.Select({
items: pandora.site.rightsLevels.map(function(rightsLevel, i) {
return {id: i, title: Ox._(rightsLevel.name)};
}),
width: 128,
value: data.rightslevel
})
.addClass('OxColor OxColorGradient')
.css({
marginBottom: '4px',
background: $rightsLevelElement.css('background')
})
.data({OxColor: $rightsLevelElement.data('OxColor')})
.bindEvent({
change: function(event) {
var rightsLevel = event.value;
$rightsLevelElement = getRightsLevelElement(rightsLevel);
$rightsLevelSelect
.css({background: $rightsLevelElement.css('background')})
.data({OxColor: $rightsLevelElement.data('OxColor')})
renderCapabilities(rightsLevel);
var edit = {
id: isMultiple ? ui.listSelection : data.id,
rightslevel: rightsLevel
};
pandora.api.edit(edit, function(result) {
that.triggerEvent('change', Ox.extend({}, 'rightslevel', rightsLevel));
});
}
})
.appendTo($rightsLevel);
} else {
$rightsLevelElement
.css({
marginBottom: '4px'
})
.appendTo($rightsLevel);
}
$capabilities = $('<div>').appendTo($rightsLevel);
renderCapabilities(data.rightslevel);
}
function toggleIconSize() { function toggleIconSize() {
iconSize = iconSize == 256 ? 512 : 256; iconSize = iconSize == 256 ? 512 : 256;
iconWidth = iconRatio > 1 ? iconSize : Math.round(iconSize * iconRatio); iconWidth = iconRatio > 1 ? iconSize : Math.round(iconSize * iconRatio);

View file

@ -14,144 +14,3 @@ pandora.cleanupDate = function(value) {
return value return value
}; };
pandora.renderRightsLevel = function(that, $rightsLevel, data, isMixed, isMultiple, canEdit) {
var rightsLevels = pandora.site.rightsLevels.map(function(rightsLevel) {
return rightsLevel.name;
}).concat(isMultiple ? ['Mixed'] : []),
rightsLevel = isMixed.rightslevel ? rightsLevels.length - 1 : data.rightslevel,
$capabilities,
$rightsLevelElement = getRightsLevelElement(rightsLevel),
$rightsLevelSelect;
$rightsLevel.empty();
if (canEdit) {
$rightsLevelSelect = Ox.Select({
items: pandora.site.rightsLevels.map(function(rightsLevel, i) {
return {id: i, title: Ox._(rightsLevel.name)};
}).concat(isMultiple ? [
{id: rightsLevels.length - 1, title: Ox._('Mixed'), disabled: true}
] : []),
width: 128,
value: rightsLevel
})
.addClass('OxColor OxColorGradient')
.css({
marginBottom: '4px',
background: $rightsLevelElement.css('background')
})
.data({OxColor: $rightsLevelElement.data('OxColor')})
.bindEvent({
change: function(event) {
var rightsLevel = event.value;
$rightsLevelElement = getRightsLevelElement(rightsLevel);
$rightsLevelSelect
.css({background: $rightsLevelElement.css('background')})
.data({OxColor: $rightsLevelElement.data('OxColor')})
if (rightsLevel < pandora.site.rightsLevels.length) {
renderCapabilities(rightsLevel);
var edit = {
id: isMultiple ? ui.listSelection : data.id,
rightslevel: rightsLevel
};
pandora.api.edit(edit, function(result) {
that.triggerEvent('change', Ox.extend({}, 'rightslevel', rightsLevel));
});
}
}
})
.appendTo($rightsLevel);
} else {
$rightsLevelElement
.css({
marginBottom: '4px'
})
.appendTo($rightsLevel);
}
$capabilities = $('<div>').appendTo($rightsLevel);
!isMixed.rightslevel && renderCapabilities(data.rightslevel);
function getRightsLevelElement(rightsLevel) {
return Ox.Theme.formatColorLevel(rightsLevel, rightsLevels)
}
function renderCapabilities(rightsLevel) {
var capabilities = [].concat(
canEdit ? [{name: 'canSeeItem', symbol: 'Find'}] : [],
[
{name: 'canPlayClips', symbol: 'PlayInToOut'},
{name: 'canPlayVideo', symbol: 'Play'},
{name: 'canDownloadVideo', symbol: 'Download'}
]
),
userLevels = canEdit ? pandora.site.userLevels : [pandora.user.level];
$capabilities.empty();
userLevels.forEach(function(userLevel, i) {
var $element,
$line = $('<div>')
.css({
height: '16px',
marginBottom: '4px'
})
.appendTo($capabilities);
if (canEdit) {
$element = Ox.Theme.formatColorLevel(i, userLevels.map(function(userLevel) {
return Ox.toTitleCase(userLevel);
}), [0, 240]);
Ox.Label({
textAlign: 'center',
title: Ox._(Ox.toTitleCase(userLevel)),
width: 60
})
.addClass('OxColor OxColorGradient')
.css({
float: 'left',
height: '12px',
paddingTop: '2px',
background: $element.css('background'),
fontSize: '8px',
color: $element.css('color')
})
.data({OxColor: $element.data('OxColor')})
.appendTo($line);
}
capabilities.forEach(function(capability) {
var hasCapability = pandora.hasCapability(capability.name, userLevel) >= rightsLevel,
$element = Ox.Theme.formatColorLevel(hasCapability, ['', '']);
Ox.Button({
tooltip: Ox._('{0} '
+ (hasCapability ? 'can' : 'can\'t') + ' '
+ Ox.toSlashes(capability.name)
.split('/').slice(1).join(' ')
.toLowerCase()
.replace('see item', 'see the item')
.replace('play video', 'play the full video')
.replace('download video', 'download the video'),
[canEdit ? Ox._(Ox.toTitleCase(userLevel)) : Ox._('You')]),
title: capability.symbol,
type: 'image'
})
.addClass('OxColor OxColorGradient')
.css({background: $element.css('background')})
.css('margin' + (canEdit ? 'Left' : 'Right'), '4px')
.data({OxColor: $element.data('OxColor')})
.appendTo($line);
});
if (!canEdit) {
Ox.Button({
title: Ox._('Help'),
tooltip: Ox._('About Rights'),
type: 'image'
})
.css({marginLeft: '52px'})
.bindEvent({
click: function() {
pandora.UI.set({page: 'rights'});
}
})
.appendTo($line);
}
});
}
}

View file

@ -442,37 +442,7 @@ pandora.ui.mainMenu = function() {
}); });
} }
} else if (data.id == 'deletefromarchive') { } else if (data.id == 'deletefromarchive') {
if (ui.section == 'items') { if (ui.section == 'documents') {
var ids;
if (ui.item) {
ids = [ui.item]
} else {
ids = ui.listSelection
}
pandora.api.find({
query: {
conditions: [{
key: 'id',
operator: '&',
value: ids
}],
operator: '&'
},
keys: ['id', 'title'],
range: [0, ui.listSelection.length]
}, function(result) {
pandora.$ui.deleteItemsDialog = pandora.ui.deleteItemsDialog({
items: result.data.items
}, function() {
Ox.Request.clearCache();
if (ui.item) {
pandora.UI.set({item: ''});
} else {
pandora.$ui.list.reloadList()
}
}).open();
});
} else if (ui.section == 'documents') {
var files; var files;
if (ui.document) { if (ui.document) {
files = [pandora.$ui.document.info()]; files = [pandora.$ui.document.info()];
@ -1394,9 +1364,6 @@ pandora.ui.mainMenu = function() {
{ id: 'clearclipboard', title: Ox._('Clear Clipboard'), disabled: !clipboardItems}, { id: 'clearclipboard', title: Ox._('Clear Clipboard'), disabled: !clipboardItems},
{}, {},
{ id: 'delete', title: Ox._('{0} {1} {2}', [deleteVerb, selectionItemName, listName]), disabled: !canDelete, keyboard: 'delete' }, { id: 'delete', title: Ox._('{0} {1} {2}', [deleteVerb, selectionItemName, listName]), disabled: !canDelete, keyboard: 'delete' },
ui._list ? [
{ id: 'deletefromarchive', title: Ox._('{0} {1} {2}', [Ox._('Delete'), selectionItemName, Ox._('from Archive')]), disabled: !canDelete }
] : [],
{}, {},
{ id: 'undo', title: undoText ? Ox._('Undo {0}', [undoText]) : Ox._('Undo'), disabled: !undoText, keyboard: 'control z' }, { id: 'undo', title: undoText ? Ox._('Undo {0}', [undoText]) : Ox._('Undo'), disabled: !undoText, keyboard: 'control z' },
{ id: 'redo', title: redoText ? Ox._('Redo {0}', [redoText]) : Ox._('Redo'), disabled: !redoText, keyboard: 'shift control z' }, { id: 'redo', title: redoText ? Ox._('Redo {0}', [redoText]) : Ox._('Redo'), disabled: !redoText, keyboard: 'shift control z' },

View file

@ -725,11 +725,11 @@ pandora.uploadDroppedFiles = function(files) {
pandora.enableBatchEdit = function(section) { pandora.enableBatchEdit = function(section) {
var ui = pandora.user.ui; var ui = pandora.user.ui;
if (section == 'documents') { if (section == 'documents') {
return !ui.document && ui.collectionSelection.length > 1 && ui.collectionSelection.some(function(item) { return !ui.document && ui.collectionSelection.length > 1 && ui.collectionSelection.every(function(item) {
return pandora.$ui.list && pandora.$ui.list.value(item, 'editable'); return pandora.$ui.list && pandora.$ui.list.value(item, 'editable');
}) })
} else { } else {
return !ui.item && ui.listSelection.length > 1 && ui.listSelection.some(function(item) { return !ui.item && ui.listSelection.length > 1 && ui.listSelection.every(function(item) {
return pandora.$ui.list && pandora.$ui.list.value(item, 'editable'); return pandora.$ui.list && pandora.$ui.list.value(item, 'editable');
}) })
} }