/**
* Created on Oct 5, 2008
*
* Copyright 2008 Vuze, Inc. All rights reserved.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.gudy.azureus2.ui.swt.views.tableitems;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.Display;
import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.config.ParameterListener;
import org.gudy.azureus2.core3.util.AERunnable;
import org.gudy.azureus2.core3.util.DisplayFormatters;
import org.gudy.azureus2.core3.util.SystemTime;
import org.gudy.azureus2.core3.util.TimeFormatter;
import org.gudy.azureus2.ui.swt.Utils;
import org.gudy.azureus2.ui.swt.views.ViewUtils;
import org.gudy.azureus2.ui.swt.views.table.CoreTableColumnSWT;
import org.gudy.azureus2.plugins.ui.menus.MenuItem;
import org.gudy.azureus2.plugins.ui.menus.MenuItemFillListener;
import org.gudy.azureus2.plugins.ui.menus.MenuItemListener;
import org.gudy.azureus2.plugins.ui.tables.TableCell;
import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
import org.gudy.azureus2.plugins.ui.tables.TableCellToolTipListener;
import org.gudy.azureus2.plugins.ui.tables.TableContextMenuItem;
/**
* @author TuxPaper
* @created Oct 5, 2008
*
*/
public abstract class ColumnDateSizer
extends CoreTableColumnSWT
implements TableCellRefreshListener, TableCellToolTipListener
{
private static int PADDING = 10;
int curFormat = 0;
int[] maxWidthUsed = new int[TimeFormatter.DATEFORMATS_DESC.length];
Date[] maxWidthDate = new Date[TimeFormatter.DATEFORMATS_DESC.length];
private boolean showTime = true;
private boolean multiline = true;
private String tableFormatOverride = "";
private static Font fontBold;
private ViewUtils.CustomDateFormat cdf;
/**
* @param name
* @param tableID
*/
public ColumnDateSizer(Class forDataSrouceType, String columnID, int width, String tableID) {
super(forDataSrouceType, columnID, ALIGN_TRAIL, width, tableID);
final TableContextMenuItem menuShowTime = addContextMenuItem(
"TableColumn.menu.date_added.time", MENU_STYLE_HEADER);
menuShowTime.setStyle(TableContextMenuItem.STYLE_CHECK);
menuShowTime.addFillListener(new MenuItemFillListener() {
public void menuWillBeShown(MenuItem menu, Object data) {
menu.setData(showTime);
}
});
menuShowTime.addListener(new MenuItemListener() {
public void selected(MenuItem menu, Object target) {
showTime = !showTime;
setUserData("showTime", new Long(showTime ? 1 : 0));
maxWidthUsed = new int[TimeFormatter.DATEFORMATS_DESC.length];
maxWidthDate = new Date[TimeFormatter.DATEFORMATS_DESC.length];
curFormat = -1;
recalcWidth(new Date(), null);
if (curFormat < 0) {
curFormat = TimeFormatter.DATEFORMATS_DESC.length - 1;
}
}
});
COConfigurationManager.addAndFireParameterListener(
"Table.column.dateformat", new ParameterListener() {
public void parameterChanged(String parameterName) {
tableFormatOverride = COConfigurationManager.getStringParameter(
"Table.column.dateformat", "");
if (tableFormatOverride == null) {
tableFormatOverride = "";
}
curFormat = -1;
if (tableFormatOverride.length() == 0) {
recalcWidth(new Date(),null);
if (curFormat < 0) {
curFormat = TimeFormatter.DATEFORMATS_DESC.length - 1;
}
menuShowTime.setVisible(true);
} else {
invalidateCells();
menuShowTime.setVisible(false);
}
}
});
cdf = ViewUtils.addCustomDateFormat( this );
}
// @see com.aelitis.azureus.ui.common.table.impl.TableColumnImpl#postConfigLoad()
public void postConfigLoad() {
Object oShowTime = getUserData("showTime");
if (oShowTime instanceof Number) {
Number nShowTime = (Number) oShowTime;
showTime = nShowTime.byteValue() == 1;
} else {
int userMode = COConfigurationManager.getIntParameter("User Mode");
showTime = userMode > 1;
}
cdf.update();
super.postConfigLoad();
}
// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
public final void refresh(TableCell cell) {
refresh(cell, 0);
}
// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
public void refresh( TableCell cell, long timestamp) {
refresh( cell, timestamp, null );
}
public void refresh(final TableCell cell, final long timestamp, final String prefix ) {
if (!cell.setSortValue(timestamp) && cell.isValid()) {
return;
}
if (timestamp <= 0) {
cell.setText("");
return;
}
SimpleDateFormat format = cdf.getDateFormat();
if ( format != null ){
Date date = new Date(timestamp);
try {
String date_str = format.format(date);
if ( prefix != null ){
date_str = prefix + date_str;
}
cell.setText(date_str);
return;
} catch (Exception e) {
}
}
if (tableFormatOverride.length() > 0) {
Date date = new Date(timestamp);
try {
SimpleDateFormat temp = new SimpleDateFormat(tableFormatOverride);
String date_str = temp.format(date);
if ( prefix != null ){
date_str = prefix + date_str;
}
cell.setText(date_str);
return;
} catch (Exception e) {
// probably illegalargumentexception
}
}
Utils.execSWTThread(new AERunnable() {
public void runSupport() {
Date date = new Date(timestamp);
if (curFormat >= 0) {
if (multiline && cell.getHeight() < 20) {
multiline = false;
}
String suffix = showTime && !multiline ? " hh:mm a" : "";
int newWidth = calcWidth(date, TimeFormatter.DATEFORMATS_DESC[curFormat] + suffix, prefix );
//SimpleDateFormat temp2 = new SimpleDateFormat(TimeFormatter.DATEFORMATS_DESC[curFormat] + suffix + (showTime && multiline ? "\nh:mm a" : ""));
//System.out.println(curFormat + ":newWidth=" + newWidth + ":max=" + maxWidthUsed[curFormat] + ":cell=" + cell.getWidth() + "::" + temp2.format(date));
if (newWidth > cell.getWidth() - PADDING) {
if (newWidth > maxWidthUsed[curFormat]) {
maxWidthUsed[curFormat] = newWidth;
maxWidthDate[curFormat] = date;
}
recalcWidth(date, prefix);
}
String s = TimeFormatter.DATEFORMATS_DESC[curFormat] + suffix;
SimpleDateFormat temp = new SimpleDateFormat(s
+ (showTime && multiline ? "\nh:mm a" : ""));
String date_str = temp.format(date);
if ( prefix != null ){
date_str = prefix + date_str;
}
cell.setText(date_str);
}
}
});
}
// @see com.aelitis.azureus.ui.common.table.impl.TableColumnImpl#setWidth(int)
public void setWidth(int width) {
int oldWidth = this.getWidth();
super.setWidth(width);
if (oldWidth == width) {
return;
}
if (maxWidthDate != null && curFormat >= 0) {
if (maxWidthDate[curFormat] == null) {
maxWidthDate[curFormat] = new Date();
}
recalcWidth(maxWidthDate[curFormat], null );
}
}
private void recalcWidth(Date date, String prefix) {
String suffix = showTime && !multiline ? " hh:mm a" : "";
int width = getWidth();
if (maxWidthDate == null) {
maxWidthUsed = new int[TimeFormatter.DATEFORMATS_DESC.length];
maxWidthDate = new Date[TimeFormatter.DATEFORMATS_DESC.length];
}
int idxFormat = TimeFormatter.DATEFORMATS_DESC.length - 1;
GC gc = new GC(Display.getDefault());
if (fontBold == null) {
FontData[] fontData = gc.getFont().getFontData();
for (int i = 0; i < fontData.length; i++) {
FontData fd = fontData[i];
fd.setStyle(SWT.BOLD);
}
fontBold = new Font(gc.getDevice(), fontData);
}
gc.setFont(fontBold);
try {
Point minSize = new Point(99999, 0);
for (int i = 0; i < TimeFormatter.DATEFORMATS_DESC.length; i++) {
if (maxWidthUsed[i] > width - PADDING) {
continue;
}
SimpleDateFormat temp = new SimpleDateFormat(
TimeFormatter.DATEFORMATS_DESC[i] + suffix);
Point newSize = gc.stringExtent(temp.format(date));
if (newSize.x < width - PADDING) {
idxFormat = i;
if (maxWidthUsed[i] < newSize.x) {
maxWidthUsed[i] = newSize.x;
maxWidthDate[i] = date;
}
break;
}
if (newSize.x < minSize.x) {
minSize = newSize;
idxFormat = i;
}
}
} catch (Throwable t) {
return;
} finally {
gc.dispose();
}
if (curFormat != idxFormat) {
//System.out.println("switch fmt to " + idxFormat + ", max=" + maxWidthUsed[idxFormat]);
curFormat = idxFormat;
invalidateCells();
}
}
private int calcWidth(Date date, String format, String prefix ) {
GC gc = new GC(Display.getDefault());
if (fontBold == null) {
FontData[] fontData = gc.getFont().getFontData();
for (int i = 0; i < fontData.length; i++) {
FontData fd = fontData[i];
fd.setStyle(SWT.BOLD);
}
fontBold = new Font(gc.getDevice(), fontData);
}
gc.setFont(fontBold);
SimpleDateFormat temp = new SimpleDateFormat(format);
String date_str = temp.format(date);
if ( prefix != null ){
date_str = prefix + date_str;
}
Point newSize = gc.stringExtent(date_str);
gc.dispose();
return newSize.x;
}
public boolean getShowTime() {
return showTime;
}
public void setShowTime(boolean showTime) {
this.showTime = showTime;
}
/**
* @return the multiline
*/
public boolean isMultiline() {
return multiline;
}
/**
* @param multiline the multiline to set
*/
public void setMultiline(boolean multiline) {
this.multiline = multiline;
}
public void cellHover(TableCell cell) {
Object ds = cell.getSortValue();
if (ds instanceof Number) {
long timestamp = ((Number) ds).longValue();
if ( timestamp > 0 ){
long eta = (SystemTime.getCurrentTime() - timestamp) / 1000;
if (eta > 0) {
cell.setToolTip(DisplayFormatters.formatETA(eta, false));
}
}
}
}
public void cellHoverComplete(TableCell cell) {
cell.setToolTip(null);
}
}