Set<IFolder> parentsToUpdate = new HashSet<IFolder>();
List<Object> expandedElements = new ArrayList<Object>(Arrays.asList(fViewer.getExpandedElements()));
try {
fViewer.getControl().getParent().setRedraw(false);
for (Entry<IFolder, IFolder> entry : entries) {
IFolder reparentedFolder = entry.getKey();
IFolder oldParent = entry.getValue();
/* Reparent while keeping the Selection / Expansion */
ISelection selection = fViewer.getSelection();
boolean expand = expandedElements.contains(reparentedFolder);
fViewer.remove(oldParent, new Object[] { reparentedFolder });
fViewer.refresh(reparentedFolder.getParent(), false);
fViewer.setSelection(selection);
if (expand)
fViewer.setExpandedState(reparentedFolder, expand);
/* Remember to update parents */
parentsToUpdate.add(oldParent);
parentsToUpdate.add(reparentedFolder.getParent());
}
} finally {
fViewer.getControl().getParent().setRedraw(true);
}
/* Update old Parents of Reparented Bookmarks */
for (IFolder folder : parentsToUpdate)
updateFolderAndParents(folder);
}
/* Handle Updated Folders */
if (updatedFolders != null) {
for (IFolder folder : updatedFolders) {
if (fInput.equals(folder))
fViewer.refresh(fInput);
else
fViewer.refresh(folder);
}
}
}
});
}
/* Folders got deleted */
public void entitiesDeleted(final Set<FolderEvent> events) {
JobRunner.runInUIThread(fViewer.getControl(), new Runnable() {
public void run() {
/* Retrieve Removed Folders */
Set<IFolder> removedFolders = null;
for (FolderEvent event : events) {
if (event.isRoot() && event.getEntity().getParent() != null) {
if (removedFolders == null)
removedFolders = new HashSet<IFolder>();
removedFolders.add(event.getEntity());
}
}
/* Event not interesting for us or we are disposed */
if (removedFolders == null || removedFolders.size() == 0)
return;
/* Ask Filter */
if (fBookmarkFilter.needsRefresh(IFolder.class, events))
fViewer.refresh(false);
/* Ask Group */
else if (fBookmarkGrouping.needsRefresh(IFolder.class))
fViewer.refresh(false);
/* React normally then */
else
fViewer.remove(removedFolders.toArray());
/* Update Read-State counters on Parents */
if (!fBookmarkGrouping.isActive()) {
for (FolderEvent event : events) {
IFolder eventParent = event.getEntity().getParent();
if (eventParent != null && eventParent.getParent() != null)
updateFolderAndParents(eventParent);
}
}
}
});
}
/* Folders got added */
public void entitiesAdded(final Set<FolderEvent> events) {
JobRunner.runInUIThread(SELECTION_DELAY, fViewer.getControl(), new Runnable() {
public void run() {
/* Reveal and Select added Folders */
final List<IFolder> addedFolders = new ArrayList<IFolder>();
for (FolderEvent folderEvent : events) {
IFolder addedFolder = folderEvent.getEntity();
if (addedFolder.getParent() != null)
addedFolders.add(addedFolder);
}
if (!addedFolders.isEmpty())
fViewer.setSelection(new StructuredSelection(addedFolders), true);
}
});
}
};
/* BookMark Listener */
fBookMarkListener = new BookMarkListener() {
/* BookMarks got Updated */
public void entitiesUpdated(final Set<BookMarkEvent> events) {
JobRunner.runInUIThread(fViewer.getControl(), new Runnable() {
public void run() {
Set<IBookMark> updatedBookMarks = null;
Map<IBookMark, IFolder> reparentedBookMarks = null;
/* Retrieve Updated BookMarks */
for (BookMarkEvent event : events) {
if (event.isRoot()) {
/* BookMark got reparented */
if (event.getOldParent() != null) {
if (reparentedBookMarks == null)
reparentedBookMarks = new HashMap<IBookMark, IFolder>();
reparentedBookMarks.put(event.getEntity(), event.getOldParent());
}
/* Normal Update */
else {
if (updatedBookMarks == null)
updatedBookMarks = new HashSet<IBookMark>();
updatedBookMarks.add(event.getEntity());
}
}
}
/* Event not interesting for us or we are disposed */
if (updatedBookMarks == null && reparentedBookMarks == null)
return;
/* Ask Filter */
if (fBookmarkFilter.needsRefresh(IBookMark.class, events))
fViewer.refresh(false);
/* Ask Group */
else if (fBookmarkGrouping.needsRefresh(IBookMark.class))
fViewer.refresh(false);
/* Handle reparented Folders */
else if (reparentedBookMarks != null) {
Set<Entry<IBookMark, IFolder>> entries = reparentedBookMarks.entrySet();
Set<IFolder> parentsToUpdate = new HashSet<IFolder>();
try {
fViewer.getControl().getParent().setRedraw(false);
for (Entry<IBookMark, IFolder> entry : entries) {
IBookMark reparentedBookMark = entry.getKey();
IFolder oldParent = entry.getValue();
/* Reparent while keeping the Selection */
ISelection selection = fViewer.getSelection();
fViewer.remove(oldParent, new Object[] { reparentedBookMark });
fViewer.refresh(reparentedBookMark.getParent(), false);
fViewer.setSelection(selection);
/* Remember to update parents */
parentsToUpdate.add(oldParent);
parentsToUpdate.add(reparentedBookMark.getParent());
}
} finally {
fViewer.getControl().getParent().setRedraw(true);
}
/* Update old Parents of Reparented Bookmarks */
for (IFolder folder : parentsToUpdate)
updateFolderAndParents(folder);
}
/* Handle Updated Folders */
if (updatedBookMarks != null)
fViewer.update(updatedBookMarks.toArray(), null);
}
});
}
/* BookMarks got Deleted */
public void entitiesDeleted(final Set<BookMarkEvent> events) {
JobRunner.runInUIThread(fViewer.getControl(), new Runnable() {
public void run() {
/* Retrieve Removed BookMarks */
Set<IBookMark> removedBookMarks = null;
for (BookMarkEvent event : events) {
if (event.isRoot()) {
if (removedBookMarks == null)
removedBookMarks = new HashSet<IBookMark>();
removedBookMarks.add(event.getEntity());
}
}
/* Event not interesting for us or we are disposed */
if (removedBookMarks == null || removedBookMarks.size() == 0)
return;
/* Ask Filter */
if (fBookmarkFilter.needsRefresh(IBookMark.class, events))
fViewer.refresh(false);
/* Ask Group */
else if (fBookmarkGrouping.needsRefresh(IBookMark.class))
fViewer.refresh(false);
/* React normally then */
else
fViewer.remove(removedBookMarks.toArray());
/* Update Read-State counters on Parents */
if (!fBookmarkGrouping.isActive()) {
for (BookMarkEvent event : events) {
IFolder eventParent = event.getEntity().getParent();
if (eventParent != null && eventParent.getParent() != null)
updateFolderAndParents(eventParent);
}
}
}
});
}
/* BookMarks got Added */
public void entitiesAdded(Set<BookMarkEvent> events) {
/* Reveal and Select if single Entity added */
if (events.size() == 1) {
final BookMarkEvent event = events.iterator().next();
JobRunner.runInUIThread(fViewer.getControl(), new Runnable() {
public void run() {
expand(event.getEntity().getParent());
}
});
}
}
};
{
/* SearchMark Listener */
fSearchMarkListener = new SearchMarkListener() {
/* SearchMarks got Updated */
public void entitiesUpdated(final Set<SearchMarkEvent> events) {
JobRunner.runInUIThread(fViewer.getControl(), new Runnable() {
public void run() {
Set<ISearchMark> updatedSearchMarks = null;
Map<ISearchMark, IFolder> reparentedSearchMarks = null;
/* Retrieve Updated SearchMarks */
for (SearchMarkEvent event : events) {
if (event.isRoot()) {
/* SearchMark got reparented */
if (event.getOldParent() != null) {
if (reparentedSearchMarks == null)
reparentedSearchMarks = new HashMap<ISearchMark, IFolder>();
reparentedSearchMarks.put(event.getEntity(), event.getOldParent());
}
/* Normal Update */
else {
if (updatedSearchMarks == null)
updatedSearchMarks = new HashSet<ISearchMark>();
updatedSearchMarks.add(event.getEntity());
}
}
}
/* Event not interesting for us or we are disposed */
if (updatedSearchMarks == null && reparentedSearchMarks == null)
return;
/* Ask Filter */
if (fBookmarkFilter.needsRefresh(ISearchMark.class, events))
fViewer.refresh(false);
/* Ask Group */
else if (fBookmarkGrouping.needsRefresh(ISearchMark.class))
fViewer.refresh(false);
/* Handle reparented SearchMarks */
else if (reparentedSearchMarks != null) {
Set<Entry<ISearchMark, IFolder>> entries = reparentedSearchMarks.entrySet();
Set<IFolder> parentsToUpdate = new HashSet<IFolder>();
try {
fViewer.getControl().getParent().setRedraw(false);
for (Entry<ISearchMark, IFolder> entry : entries) {
ISearchMark reparentedSearchMark = entry.getKey();
IFolder oldParent = entry.getValue();
/* Reparent while keeping the Selection */
ISelection selection = fViewer.getSelection();
fViewer.remove(oldParent, new Object[] { reparentedSearchMark });
fViewer.refresh(reparentedSearchMark.getParent(), false);