/*******************************************************************************
* Copyright (c) 2010 Weltevree Beheer BV, Remain Software & Industrial-TSI
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wim Jongman - initial API and implementation
*******************************************************************************/
package org.eclipse.ecf.salvo.ui.internal.editor;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.ecf.protocol.nntp.model.IArticle;
import org.eclipse.ecf.protocol.nntp.model.INewsgroup;
import org.eclipse.ecf.salvo.ui.internal.Activator;
import org.eclipse.ecf.salvo.ui.internal.resources.ISalvoResource;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.layout.TreeColumnLayout;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;
/**
* This editor fills a lazy table tree with the article information and to the
* left of this table a static table is attached that contains information icons
* like follow and attachments indicators.
*
* @author wim.jongman@gmail.com
*
*/
public class ArticlePanel extends EditorPart implements ISelectionListener {
public class ArticlePanelSideTableMeasureListener implements Listener {
public void handleEvent(Event event) {
event.height = tree.getItemHeight();
}
}
/**
* Calculate the index match between the static side table and the dynamic
* main table and then annotate the article in the side table.
*
* @author wim.jongman@gmail.com
*
*/
private final class ArticlePanelTreePaintListener implements PaintListener {
public void paintControl(PaintEvent e) {
if(tree.getTopItem() == null)
return;
try {
// Stop & start drawing of the main tree seems to trigger
// flooding of paint events.
// tree.setRedraw(false);
// Stop the sidetable from flickering
sideTable.setVisible(false);
// Calculate the current visible top and bottom indices in the
// main tree.
int itemHeight = tree.getItemHeight();
Rectangle clientArea = tree.getClientArea();
int offset = tree.getTopItem().getBounds().y;
// Walk over the current visible articles and set/remove the
// icons in the side tree
int counter = 0;
while (true) {
// Get the item at the next visible location
Point point = new Point(0, counter++ * itemHeight);
TreeItem itemd = null;
if (clientArea.height > point.y)
itemd = tree.getItem(new Point(0, point.y + offset));
if (itemd == null || itemd.getData() == null)
return;
IArticle article = (IArticle) ((ISalvoResource) itemd
.getData()).getObject();
// Make the side tree just as long as the (resized) main
// tree
sideTable.setItemCount(counter);
// Set some icons if required
sideTable.getItem(counter - 1).setImage(1,
getImage(article, 1));
sideTable.getItem(counter - 1).setImage(2,
getImage(article, 2));
}
} finally {
// int s = (tree.getVerticalBar().getSelection() / 2) * 2;
// if (s == tree.getVerticalBar().getSelection()) {
// sideTable.setItemCount(sideTable.getItemCount() + 1);
// sideTable.getItem(sideTable.getItemCount() - 1).setText(1,
// (sideTable.getItemCount() - 1) + "");
// sideTable.showItem(sideTable.getItem(sideTable
// .getItemCount() - 1));
// }
sideTable.pack();
sideTable.setVisible(true);
// tree.setVisible(true);
}
}
/**
* Decorate this row.
*
* @param article
* @param row
* @return
*/
private Image getImage(IArticle article, int row) {
if (row == 1)
if (!article.isReply() && article.isCommenting()
|| article.isMine())
return Activator.getDefault().getImageRegistry().get(
"messages.gif");
if (row == 2)
if (article.isMarked())
return Activator.getDefault().getImageRegistry().get(
"follow.gif");
return null;
}
}
public ArticlePanel() {
}
private Tree sideTable;
private TreeViewer treeViewer;
public static final String ID = "org.eclipse.ecf.salvo.ui.articlepanel";
private Tree tree;
private INewsgroup savedNewsgroup;
@Override
public void doSave(IProgressMonitor monitor) {
}
@Override
public void doSaveAs() {
}
@Override
public void init(IEditorSite site, IEditorInput input)
throws PartInitException {
setSite(site);
setInput(input);
}
@Override
public boolean isDirty() {
return false;
}
@Override
public boolean isSaveAsAllowed() {
return false;
}
@Override
public void createPartControl(Composite parent) {
final GridLayout gridLayout = new GridLayout();
gridLayout.horizontalSpacing = 0;
gridLayout.verticalSpacing = 0;
gridLayout.marginWidth = 0;
gridLayout.marginHeight = 0;
parent.setLayout(gridLayout);
final ToolBar toolBar = new ToolBar(parent, SWT.NONE);
final ToolItem newItemToolItem = new ToolItem(toolBar, SWT.PUSH);
newItemToolItem.setText("New item");
final ToolItem newItemToolItem_1 = new ToolItem(toolBar, SWT.PUSH);
newItemToolItem_1.setText("New item");
// composite_1.setSize(494, 174);
TreeColumnLayout layout1 = new TreeColumnLayout();
TreeColumnLayout layout2 = new TreeColumnLayout();
final Composite tableComposite = new Composite(parent, SWT.NONE);
tableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
true));
final GridLayout gridLayout_1 = new GridLayout();
gridLayout_1.numColumns = 2;
gridLayout_1.verticalSpacing = 0;
gridLayout_1.marginWidth = 0;
gridLayout_1.marginHeight = 0;
gridLayout_1.horizontalSpacing = 0;
tableComposite.setLayout(gridLayout_1);
// do something with the result
final Composite tree1Composite = new Composite(tableComposite, SWT.NONE);
tree1Composite.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false,
true));
sideTable = new Tree(tree1Composite, SWT.NONE);
sideTable.setLinesVisible(true);
sideTable.setHeaderVisible(true);
sideTable.addListener(SWT.MeasureItem,
new ArticlePanelSideTableMeasureListener());
final TreeColumn column1 = new TreeColumn(sideTable, SWT.NONE);
layout1.setColumnData(column1, new ColumnWeightData(00));
final TreeColumn column2 = new TreeColumn(sideTable, SWT.NONE);
column2.setResizable(false);
column2.setWidth(18);
layout1.setColumnData(column2, new ColumnWeightData(50));
final TreeColumn column3 = new TreeColumn(sideTable, SWT.NONE);
column3.setResizable(false);
column3.setWidth(18);
layout1.setColumnData(column3, new ColumnWeightData(50));
tree1Composite.setLayout(layout1);
column1.setWidth(0);
final Composite tree2Composite = new Composite(tableComposite, SWT.NONE);
tree2Composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
true));
final GridLayout gridLayout_3 = new GridLayout();
gridLayout_3.marginWidth = 0;
treeViewer = new TreeViewer(tree2Composite, SWT.VIRTUAL
| SWT.FULL_SELECTION);
tree = treeViewer.getTree();
tree.setLinesVisible(true);
treeViewer.setUseHashlookup(true);
treeViewer.setLabelProvider(new ArticlePaneLabelProvider());
treeViewer.setContentProvider(new ArticlePanelContentProvider());
tree.setHeaderVisible(true);
tree.addPaintListener(new ArticlePanelTreePaintListener());
final TreeColumn newColumnTreeColumn_2 = new TreeColumn(tree, SWT.NONE);
newColumnTreeColumn_2.setText("subject");
layout2.setColumnData(newColumnTreeColumn_2, new ColumnWeightData(50));
final TreeColumn newColumnTreeColumn_3 = new TreeColumn(tree, SWT.NONE);
newColumnTreeColumn_3.setText("from");
layout2.setColumnData(newColumnTreeColumn_3, new ColumnWeightData(25));
newColumnTreeColumn_3.setMoveable(true);
final TreeColumn newColumnTreeColumn_4 = new TreeColumn(tree, SWT.NONE);
newColumnTreeColumn_4.setText("sent");
layout2.setColumnData(newColumnTreeColumn_4, new ColumnPixelData(100));
newColumnTreeColumn_4.setMoveable(true);
final TreeColumn newColumnTreeColumn_5 = new TreeColumn(tree, SWT.NONE);
newColumnTreeColumn_5.setText("size");
layout2.setColumnData(newColumnTreeColumn_5, new ColumnPixelData(40));
newColumnTreeColumn_5.setMoveable(true);
tree2Composite.setLayout(layout2);
getSite().setSelectionProvider(treeViewer);
addContextMenu(treeViewer);
getSite().getWorkbenchWindow().getSelectionService()
.addPostSelectionListener(this);
setInput(((ArticlePanelInput) getEditorInput()).getNewsgroup());
}
private void addContextMenu(TreeViewer viewer) {
MenuManager menuMgr = new MenuManager();
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager mgr) {
fillContextMenu(mgr);
}
});
// Create menu.
Menu menu = menuMgr.createContextMenu(viewer.getControl());
viewer.getControl().setMenu(menu);
// Register menu for extension.
getSite().registerContextMenu(menuMgr, viewer);
}
protected void fillContextMenu(IMenuManager mgr) {
mgr.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
@Override
public void dispose() {
getSite().getWorkbenchWindow().getSelectionService()
.removePostSelectionListener(this);
super.dispose();
}
@Override
public void setFocus() {
tree.setFocus();
}
private void setInput(INewsgroup group) {
// TODO Spin of a Job that loads the articles in the newsgroup
// new NewsgroupArticleLoaderJob(group).schedule();
if (group != savedNewsgroup) {
savedNewsgroup = group;
((ArticlePanelInput) getEditorInput()).setNewsGroup(group);
setPartName(group.getNewsgroupName());
treeViewer.getTree().clearAll(true);
treeViewer.setInput(group);
}
}
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
if (part == this) {
return;
}
if (selection instanceof IStructuredSelection) {
if (((IStructuredSelection) selection).getFirstElement() instanceof ISalvoResource) {
if (((ISalvoResource) ((IStructuredSelection) selection)
.getFirstElement()).getObject() instanceof INewsgroup) {
setInput((INewsgroup) ((ISalvoResource) ((IStructuredSelection) selection)
.getFirstElement()).getObject());
}
}
}
}
public void updateArticle(ISalvoResource resource) {
treeViewer.update(resource, null);
}
}