Copy link to clipboard
Copied
In Bridge CC 2019 I use collections to track track various workflow states, such as which sites I have uploaded an image to.
Thus a single image may be in multiple collections - but I can't see how to determine which collections an image is in. (Other than browsing every collection which would be tedious). Am I missing something?
Ideally I would like the equivalent to the function that is in Photoshop Elements, where a right click on a image gives an option to "Remove from Album" and it shows the albums the image can be removed from.
Copy link to clipboard
Copied
I am not aware of a method within Bridge.
Knowing that collections are actually XML plain text files with a .filelist extension and where they are located, one can use a tool that can search the content of the files for a specific image name. In the screenshot below, I have used TextWrangler/BBEdit on the Mac OS:
Copy link to clipboard
Copied
BBEdit on Mac, Notepad++ on Windows. Do a multi-file search in the Collections folder.
Copy link to clipboard
Copied
Save this script as a ".jsx" file and put it in your Bridge Startup Scripts folder (Preferences->Startup Scripts and click the reveal button.) Relaunch Bridge, select ONE file, and select the command from the Tools menu.
This will search your collections and show a dialog listing which ones that file is in. Bridge apparently cannot search Smart Collections, not sure if that's a bug or what.
-------------------------
#target bridge
if(BridgeTalk.appName == 'bridge'){
var newCommand = new MenuElement('command', 'Find in Collections...', 'at the end of Tools');
}
newCommand.onSelect = function (){
collFind();
}
function collFind(){
var foundColl = '';
var j = 0;
var k = 0;
try{
app.synchronousMode = true;
if(app.document.selectionsLength != 1){
alert('Please select one file to search for in Collections.');
return(false);
}
else{
var sFile = app.document.selections;
var CollList = app.getCollections();
var sCollList = app.getSmartCollections();
for(j=0;j < CollList.length; j++){
if(app.isCollectionMember(CollList
foundColl = foundColl + '\r' + CollList
}
}
if(foundColl == ''){
alert(sFile.name + ' is not in any Collections');
return(true);
}
else{
alert(foundColl);
}
}
app.synchronousMode = false;
}
catch(e){
alert(e + ' ' + e.line);
return;
}
}
-------------------------
Copy link to clipboard
Copied
Thanks. That script is helpful for me.
I also submitted a Bridge feature request to have the equivalent of the PSE option to Remove from Album.
Copy link to clipboard
Copied
Try this instead.
#target bridge
if(BridgeTalk.appName == 'bridge'){
var FM = new MenuElement('command', 'Find in Collections...', 'at the end of Tools');
var FC = new MenuElement('command', 'Find in Collections...', 'after Thumbnail/Open', this.menuID);
}
FM.onSelect = function (){
collFind();
}
FC.onSelect = function(){
collFind();
}
function collFind(){
var foundColl = [];
var j = 0;
var k = 0;
try{
app.synchronousMode = true;
if(app.document.selectionsLength != 1){
alert('Please select one file to search for in Collections.');
return(false);
}
else{
var sFile = app.document.selections;
var CollList = app.getCollections();
var sCollList = app.getSmartCollections();
for(j=0;j < CollList.length; j++){
if(app.isCollectionMember(CollList
foundColl
k++;
}
}
if(foundColl == ''){
alert(sFile[0].name + ' is not in any collections');
return(true);
}
else{
var w = new Window('palette', 'Find in Collections', undefined, {closeButton:true});
w.preferredSize = [350, 350];
g = w.add('group', undefined, '');
g.orientation = 'column';
g.preferredSize = [300, 150];
g.alignChildren = ['fill', 'fill'];
s = g.add('statictext', undefined, '', {multiline: true});
lb = g.add('listbox', undefined, '', {multiselect:true});
lb.preferredSize = [250, 125];
for(j=0;j < foundColl.length; j++){
lb.add('item', foundColl
}
g2 = w.add('group', undefined, '');
g2.orientation = 'row';
g2.preferredSize = [300, 150];
g2.alignChildren = ['fill', 'fill'];
br = g2.add('button', undefined, 'Remove');
b = g2.add('button', undefined, 'Close');
s.text = sFile[0].name + ' is in the following collections:\r\r\
Select collection(s) and click Remove button to remove ' + sFile[0].name + ' from collection(s).';
g.layout.layout(true);
g2.layout.layout(true);
w.layout.layout(true);
w.show();
b.onClick = function(){
w.close();
}
br.onClick = function(){
var m = 'Remove ' + sFile[0].name + ' from Collections?';
if(confirm(m)){
for(var a in lb.selection){
app.removeCollectionMember(foundColl, sFile[0]);
lb.remove(lb.selection);
}
}
}
}
}
app.synchronousMode = false;
}
catch(e){
alert(e + ' ' + e.line);
return;
}
}
Copy link to clipboard
Copied
Thank you for that enhanced script. Just what I was looking for.
Copy link to clipboard
Copied
Please test that and see how it works. I'm not aware of any bugs but no promises.
Copy link to clipboard
Copied
I had an initial problem when I copied and pasted the text into an editor without seeing that the long line 117 had split into into 2 lines. This created a syntax error when Bridge tried to load the script. After I reunited those two pieces into a single line of code it loaded and ran OK.
The only unexpected behavior I have found is that it lets me select multiple two collections in the removal dialog, but only removes the image from one of them. I think it should either prohibit multi-select in that dialog, or allow it and remove the image from the multiple selected collections.
Copy link to clipboard
Copied
It should loop through and remove from any collection you have selected in the listbox. I'll have to do some testing. I've already run into two new Bridge bugs while writing this.
Copy link to clipboard
Copied
Ah - I see it has looped around but removed the image from the wrong collections. i.e.
One image in 4 collections.
I selected collections 2 and 3 for removal.
The image was removed from 1 and 2 instead of from 2 and 3.
Copy link to clipboard
Copied
I’ll have to do more testing. This was thrown together pretty quickly.
Copy link to clipboard
Copied
Ok, new approach to removing items from collections. This should handle things correctly. Please test.
Only known issue is that Bridge takes a long time to check large collections. Not sure if its a caching issue or what. If you have numerous large collections (I have some over 2000 items) its slow.
----------------------------
/*
CollectionSearch created by David M. Converse ©2019
www.lumigraphics.com
Last updated 2-13-2019
This script uses Extendscript and ScriptUI to find which collections a selected file belongs to and allows the user
to delete it from chosen collections.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#target bridge
if(BridgeTalk.appName == 'bridge'){
var FM = new MenuElement('command', 'Find in Collections...', 'at the end of Tools');
var FC = new MenuElement('command', 'Find in Collections...', 'after Thumbnail/Open', this.menuID);
}
FM.onSelect = function (){
collFind();
}
FC.onSelect = function(){
collFind();
}
function collFind(){
var foundColl = [];
var j = 0;
var k = 0;
try{
if(app.document.selectionsLength != 1){
alert('Please select one file to search for in Collections.');
return(false);
}
else{
var sFile = app.document.selections;
var CollList = app.getCollections();
for(j=0;j < CollList.length; j++){
if(app.isCollectionMember(CollList
foundColl
k++;
}
}
if(foundColl == ''){
alert(sFile[0].name + ' is not in any collections');
return(true);
}
else{
var w = new Window('palette', 'Find in Collections', undefined, {closeButton:true});
w.preferredSize = [350, 350];
g = w.add('group', undefined, '');
g.orientation = 'column';
g.preferredSize = [300, 150];
g.alignChildren = ['fill', 'fill'];
s = g.add('statictext', undefined, '', {multiline: true});
lb = g.add('listbox', undefined, '', {multiselect:true});
lb.preferredSize = [250, 125];
for(j=0;j < foundColl.length; j++){
lb.add('item', foundColl
}
g2 = w.add('group', undefined, '');
g2.orientation = 'row';
g2.preferredSize = [300, 150];
g2.alignChildren = ['fill', 'fill'];
br = g2.add('button', undefined, 'Remove');
b = g2.add('button', undefined, 'Close');
s.text = sFile[0].name + ' is in the following collections:\r\r\
Select collection(s) and click Remove button to remove ' + sFile[0].name + ' from collection(s).';
g.layout.layout(true);
g2.layout.layout(true);
w.layout.layout(true);
w.show();
b.onClick = function(){
w.close();
}
br.onClick = function(){
var m = 'Remove ' + sFile[0].name + ' from Collections?';
if(confirm(m)){
var n = 0;
var o = [];
for(j=0;j < lb.items.length; j++){
if(lb.items
o
o[n+1] = lb.items
n = n + 2;
}
}
for(j=0;j < o.length; j++){
app.removeCollectionMember(o
lb.remove(o[j+1]);
j++
}
}
}
}
}
}
catch(e){
alert(e + ' ' + e.line);
return;
}
}
----------------------------
Copy link to clipboard
Copied
Good - that third version passed the test that version 2 had failed. I have "unmarked" version 2 as being the correct answer.
I'm tempted to mark version 3 as correct but my doing so seems to jinx it 🙂 Perhaps it can be flagged after a few more people have proven it. Thanks!
I have 20 collections and currently they are small. Perhaps a refinement that would reassure users with large collections would be to display a preliminary message saying "searching collections, please wait", rather than giving no indication of work in progress.
Copy link to clipboard
Copied
I filed a bug about how long it takes to read a large collection. Doing a text search is faster. Ugh.
There isn’t an an easy way to show an operation in progress. I played around with a text field in the top navbar but haven’t had time to make it actually work right.
Copy link to clipboard
Copied
I've tried both using the navbar and using a window to display progress, and managed to not only crash Bridge but corrupt preferences so Bridge won't relaunch on both platforms. So it looks like a progress notification is not happening, unless whatever new bug this triggers is fixed. Ugh.
Copy link to clipboard
Copied
Thank you for fighting the good fight David!
Copy link to clipboard
Copied
Seconded!
I'm glad I asked the question, and thank you for your efforts.
Copy link to clipboard
Copied
I don't have time to work on it more, but there are at least two other ways to do this that might work. I'll do some more testing later- I want to include this in my Utility Script Pack if I can get it stable and working faster.
Copy link to clipboard
Copied
Ok let's test this one... I'm doing a text search of the actual collection files, not using the built-in features at all. Please test to see how it works.
---------------------------------
/*
CollectionSearch created by David M. Converse ©2019
www.lumigraphics.com
Last updated 2-20-2019
This script uses Extendscript and ScriptUI to find which collections
a selected file belongs to and allows the user to delete it from chosen collections.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#target bridge
if(BridgeTalk.appName == 'bridge'){
var FM = new MenuElement('command', 'Find in Collections...', 'at the end of Tools');
var FC = new MenuElement('command', 'Find in Collections...', 'after Thumbnail/Open', this.menuID);
}
var scriptf = File($.fileName);
var bfo = scriptf.parent.parent;
var cfo = Folder(bfo + '/Collections/');
FM.onSelect = function (){
collFind();
}
FC.onSelect = function(){
collFind();
}
function collFind(){
var foundColl = [];
var j = 0;
var k = 0;
var l = 0;
try{
if(app.document.selectionsLength != 1){
alert('Please select one file to search for in Collections.');
return(false);
}
else{
var sFile = app.document.selections;
var collList = app.getCollections();
app.synchronousMode = true;
var c = cfo.getFiles();
for(j = 0; j < c.length; j++){
cF = c
cF.open('r');
var cChildren = cF.read();
cF.close();
var matchuri = sFile[0].uri;
if(cChildren.search(matchuri) != -1){
for(var m = 0; m < collList.length; m++){
if((collList
foundColl
k++;
}
}
}
}
app.synchronousMode = false;
if(foundColl.length == 0){
alert(sFile[0].name + ' is not in any collections');
return(true);
}
else{
var w = new Window('palette', 'Find in Collections', undefined, {closeButton:true});
w.preferredSize = [350, 350];
g = w.add('group', undefined, '');
g.orientation = 'column';
g.preferredSize = [300, 200];
g.alignChildren = ['fill', 'fill'];
s = g.add('statictext', undefined, '', {multiline: true});
lb = g.add('listbox', undefined, '', {multiselect:true});
lb.preferredSize = [250, 125];
for(j=0;j < foundColl.length; j++){
lb.add('item', foundColl
}
s2 = g.add('statictext', undefined, '');
g2 = w.add('group', undefined, '');
g2.orientation = 'row';
g2.preferredSize = [300, 150];
g2.alignChildren = ['fill', 'fill'];
br = g2.add('button', undefined, 'Remove');
b = g2.add('button', undefined, 'Close');
s.text = sFile[0].name + ' is in the following collections:';
s2.text = 'Select collection(s) and click Remove button to remove ' + sFile[0].name;
g.layout.layout(true);
g2.layout.layout(true);
w.layout.layout(true);
w.show();
b.onClick = function(){
w.close();
}
br.onClick = function(){
var m = 'Remove ' + sFile[0].name + ' from Collections?';
if(confirm(m)){
var n = 0;
var o = [];
for(j=0;j < lb.items.length; j++){
if(lb.items
o
o[n+1] = lb.items
n = n + 2;
}
}
for(j=0;j < o.length; j++){
app.removeCollectionMember(o
lb.remove(o[j+1]);
j++;
}
}
}
}
}
}
catch(e){
alert(e + ' ' + e.line);
return;
}
}
Copy link to clipboard
Copied
This Feb 20 version also passes my (admittedly simple) simple testing, and is distinctly faster than the Feb 13 version, so I'm going with this one.
Thanks again.
Copy link to clipboard
Copied
I switched to reading the actual collection XML files and doing a text search. Its MUCH faster with large collections.
This script will be released as part of my updated Utility Script Pack soon.
Copy link to clipboard
Copied
Great stuff Lumigraphics – thanks for sharing!
Bridge apparently cannot search Smart Collections, not sure if that's a bug or what.
That is a shame, however it makes sense… Smart collections are a live search.
Copy link to clipboard
Copied
Smart collections are saved as a search. There might be a way to run the search and access the results, but I’m not diving in it that deep. Regular collections actually have the file paths saved in them.
Found another bug, I wanted the No button (actually should be Ok and Cancel) in the confirm dialog to be default. The devs didn’t even bother testing their code for the dialog. The same call works right in ESTK but wrong in Bridge. :sigh:
Copy link to clipboard
Copied
Hmmm… The search criteria are saved into the .collection XML file, but no actual image URI paths. I agree that the URI paths for a regular collection are saved into the .filelist XML file. Are we both saying the same thing?