/******************************************************************************* * Copyright (c) 2009, 2010 Progress Software Corporation. * 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 ******************************************************************************/ package org.fusesource.tools.messaging.editors; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; 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.Display; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.fusesource.tools.messaging.IConstants; import org.fusesource.tools.messaging.MessageEvent; import org.fusesource.tools.messaging.core.IListener; import org.fusesource.tools.messaging.core.IMessageChangeListener; import org.fusesource.tools.messaging.core.IMessagesManager; import org.fusesource.tools.messaging.ui.Column; import org.fusesource.tools.messaging.ui.DefaultMessageTableViewer; import org.fusesource.tools.messaging.ui.TableContentProvider; import org.fusesource.tools.messaging.ui.TableLabelProvider; public class MessageReceiverTable { private static final String RECEIVED_MESSAGES = "Received Messages"; protected static final Column[] COLUMNS = { new Column(RECEIVED_MESSAGES, 1.0f) }; protected TableViewer tableViewer; protected static Font DEFAULT_FONT, BOLD_FONT; protected List<MessageEvent> allMessagesList; protected IListener listener; private IMessageChangeListener newMsgNotifications; private boolean isColumnsVisible = false; private boolean isBlockCleared = false; public MessageReceiverTable() { allMessagesList = new ArrayList<MessageEvent>(); } /** * * @param parent * @param hintHeight * should pass actual value or -1 */ protected void createControl(Composite parent, int hintHeight) { Composite composite = new Composite(parent, SWT.BORDER); GridLayout layout = new GridLayout(1, false); composite.setLayout(layout); setupViewer(composite); GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); if (hintHeight != -1) { gridData.heightHint = hintHeight; } tableViewer.getTable().setLayoutData(gridData); initFonts(); } protected void initFonts() { DEFAULT_FONT = tableViewer.getTable().getFont(); if (BOLD_FONT == null) { FontData[] fontData = DEFAULT_FONT.getFontData(); for (FontData fdata : fontData) { fdata.setStyle(fdata.getStyle() | SWT.BOLD); } BOLD_FONT = new Font(tableViewer.getTable().getDisplay(), fontData); } } protected void setupViewer(Composite parent) { tableViewer = new DefaultMessageTableViewer(parent, SWT.NONE | SWT.FULL_SELECTION, IConstants.EMPTY_STRING); Table table = tableViewer.getTable(); setTableProperties(table); addColumns(parent.getBounds()); tableViewer.setColumnProperties(getColumnProperties()); tableViewer.setContentProvider(getContentProvider()); tableViewer.setLabelProvider(getLabelProvider()); tableViewer.setInput(getInput()); } protected String[] getColumnProperties() { return new String[] { RECEIVED_MESSAGES }; } protected void addColumns(Rectangle bounds) { int width = bounds.width; if (width < 100) { width = getDefaultWidth(); } Column[] columns = getColumns(); for (Column column : columns) { TableColumn c = new TableColumn(tableViewer.getTable(), SWT.FULL_SELECTION); c.setText(column.getColumnName()); c.setWidth((int) (width * column.getWidthValue())); c.setResizable(true); } } protected int getDefaultWidth() { return 500; } protected Object getInput() { return allMessagesList; } protected IBaseLabelProvider getLabelProvider() { return new MRTLabelProvider(); } protected IContentProvider getContentProvider() { return new TableContentProvider(); } protected void setTableProperties(Table table) { table.setHeaderVisible(true); table.setLinesVisible(true); } protected Column[] getColumns() { return COLUMNS; } public TableViewer getViewer() { return tableViewer; } public IListener getListener() { return listener; } // Called when selection changes... public void setInput(IListener listener) { this.listener = listener; addNotificationListener(); reloadTableData(); } protected void reloadTableData() { allMessagesList.clear(); IMessagesManager messagesManager = listener.getMessagesManager(); if (messagesManager == null) { return; } List<MessageEvent> messages = new ArrayList<MessageEvent>(messagesManager.getMessages()); if (messages.isEmpty()) { updateUI(); return; } // Mark all as read... for (MessageEvent messageEvent : messages) { messagesManager.resetFlag(messageEvent, IMessageChangeListener.MESSAGE_READ); } allMessagesList.addAll(messages); updateColumns(); updateUI(); } protected void updateColumns() { if (isColumnsVisible) { return; } if (allMessagesList != null && allMessagesList.size() > 0) { MessageEvent messageTypeWrapper = allMessagesList.get(0); Map<String, String> metadata = messageTypeWrapper.getMetadata(); if (metadata != null) { StringBuffer columnString = new StringBuffer(); Set<String> keySet = metadata.keySet(); for (String string : keySet) { columnString.append(string); columnString.append(";"); } ((DefaultMessageTableViewer) tableViewer).refreshTable(columnString.toString()); isColumnsVisible = true; } } } public void updateUI() { Runnable object = new Runnable() { public void run() { /* * UI-822 - When message in-flow is too fast and the editor gets disposed, already * scheduled threads try to refresh the viewer. We get widget disposed exception * that case. Fix is to skip the refresh call when the editor is actually disposed */ if (!isBlockCleared) { getViewer().refresh(); } } }; Display.getDefault().asyncExec(object); } private void addNotificationListener() { if (newMsgNotifications == null) { newMsgNotifications = new IMessageChangeListener() { public void messageChangeEvent(final MessageEvent me, int kind) { if (IMessageChangeListener.MESSAGE_ADDED == kind) { allMessagesList.add(me); Runnable object = new Runnable() { public void run() { updateColumns(); updateUI(); } }; Display.getDefault().asyncExec(object); } else if (IMessageChangeListener.MESSAGE_REMOVED == kind) { allMessagesList.remove(me); updateUI(); } } public void messagesClearedEvent(List<MessageEvent> clearedMsgs) { allMessagesList.clear(); updateUI(); } }; IMessagesManager messagesManager = listener.getMessagesManager(); if (messagesManager != null) { messagesManager.addMessageChangeListener(newMsgNotifications); } } } public void removeNotificationsListener() { if (listener == null || newMsgNotifications == null) { return; } listener.getMessagesManager().removeMessageChangeListener(newMsgNotifications); isBlockCleared = true; } protected class MRTLabelProvider extends TableLabelProvider { @Override public Font getFont(Object element) { if (element instanceof MessageEvent) { MessageEvent message = (MessageEvent) element; if (listener.getMessagesManager().hasFlag(message, IMessageChangeListener.MESSAGE_UNREAD)) { return BOLD_FONT; } } return DEFAULT_FONT; } } }