/*******************************************************************************
* Copyright (c) 2009, G. Weirich and Elexis
* 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:
* G. Weirich - initial implementation
*
*******************************************************************************/
package ch.elexis.agenda.ui.week;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.ScrollBar;
import ch.elexis.actions.Activator;
import ch.elexis.agenda.data.Termin;
import ch.elexis.agenda.preferences.PreferenceConstants;
import ch.elexis.agenda.ui.BaseView;
import ch.elexis.agenda.ui.IAgendaLayout;
import ch.elexis.agenda.ui.TerminLabel;
import ch.elexis.core.data.activator.CoreHub;
import ch.elexis.core.ui.util.SWTHelper;
import ch.elexis.data.Query;
import ch.elexis.dialogs.TerminDialog;
import ch.rgw.tools.StringTool;
import ch.rgw.tools.TimeTool;
public class ProportionalSheet extends Composite implements IAgendaLayout {
static final int LEFT_OFFSET_DEFAULT = 20;
static final int PADDING_DEFAULT = 5;
int left_offset, padding;
private AgendaWeek view;
private MenuManager contextMenuManager;
private List<TerminLabel> tlabels;
private double ppm;
private int sheetHeight;
private String[] resources;
private int textWidth;
private double sheetWidth;
private double widthPerColumn;
public ProportionalSheet(Composite parent, AgendaWeek v){
super(parent, SWT.NO_BACKGROUND);
view = v;
addControlListener(new ControlAdapter() {
@Override
public void controlResized(ControlEvent e){
layout();
recalc();
}
});
addPaintListener(new TimePainter());
addMouseListener(new MouseAdapter() {
@Override
public void mouseDoubleClick(MouseEvent e){
String startOfDayTimeInMinutes =
CoreHub.globalCfg
.get(PreferenceConstants.AG_DAY_PRESENTATION_STARTS_AT, "0000");
int sodtHours = Integer.parseInt(startOfDayTimeInMinutes.substring(0, 2));
int sodtMinutes = Integer.parseInt(startOfDayTimeInMinutes.substring(2));
int minute = (int) Math.round(e.y / ppm);
TimeTool tt = new TimeTool(Activator.getDefault().getActDate());
int hour = minute / 60;
minute = minute - (60 * hour);
int raster = 15;
minute = ((minute + (raster >> 1)) / raster) * raster;
tt.set(TimeTool.AM_PM, TimeTool.AM);
tt.set(TimeTool.HOUR, hour + sodtHours);
tt.set(TimeTool.MINUTE, minute + sodtMinutes);
TerminDialog dlg = new TerminDialog(null);
dlg.create();
dlg.setTime(tt);
if (dlg.open() == Dialog.OK) {
refresh();
}
}
@Override
public void mouseDown(MouseEvent e){
super.mouseDown(e);
}
});
// setBackground(Desk.getColor(Desk.COL_GREEN));
left_offset = LEFT_OFFSET_DEFAULT;
padding = PADDING_DEFAULT;
}
private boolean isBetween(int x, double lower, double upper){
int y = (int) Math.round(lower);
int z = (int) Math.round(upper);
if ((x >= y) && (x <= z)) {
return true;
}
return false;
}
public MenuManager getContextMenuManager(){
return contextMenuManager;
}
public void clear(){
while (tlabels != null && tlabels.size() > 0) {
tlabels.remove(0).dispose();
}
recalc();
}
synchronized void refresh(){
String[] days = view.getDisplayedDays();
Query<Termin> qbe = new Query<Termin>(Termin.class);
qbe.add("BeiWem", "=", Activator.getDefault().getActResource());
qbe.startGroup();
for (String date : days) {
qbe.add("Tag", "=", date);
qbe.or();
}
qbe.endGroup();
List<Termin> apps = qbe.execute();
// clear old TerminLabel list
if (tlabels != null) {
for (TerminLabel terminLabel : tlabels) {
terminLabel.dispose();
}
tlabels.clear();
} else {
tlabels = new LinkedList<TerminLabel>();
}
// populate new TerminLabel list
for (Termin termin : apps) {
String dStart = termin.getDay();
int idx = StringTool.getIndex(days, dStart);
if (idx != -1) {
TerminLabel terminLabel = new TerminLabel(this);
terminLabel.set(termin, idx);
tlabels.add(terminLabel);
}
}
TerminLabel.checkAllCollisions(tlabels);
recalc();
}
void recalc(){
if (tlabels != null) {
ppm = BaseView.getPixelPerMinute();
String startOfDayTimeInMinutes =
CoreHub.globalCfg.get(PreferenceConstants.AG_DAY_PRESENTATION_STARTS_AT, "0000");
int sodtHours = Integer.parseInt(startOfDayTimeInMinutes.substring(0, 2));
int sodtMinutes = Integer.parseInt(startOfDayTimeInMinutes.substring(2));
int sodtM = (sodtHours * 60);
sodtM += sodtMinutes;
String endOfDayTimeInMinutes =
CoreHub.globalCfg.get(PreferenceConstants.AG_DAY_PRESENTATION_ENDS_AT, "2359");
int eodtHours = Integer.parseInt(endOfDayTimeInMinutes.substring(0, 2));
int eodtMinutes = Integer.parseInt(endOfDayTimeInMinutes.substring(2));
int eodtM = (eodtHours * 60);
eodtM += eodtMinutes;
sheetHeight = (int) Math.round(ppm * (eodtM - sodtM));
ScrolledComposite sc = (ScrolledComposite) getParent();
Point mySize = getSize();
if (mySize.x > 0.0) {
if (mySize.y != sheetHeight) {
setSize(mySize.x, sheetHeight);
sc.setMinSize(getSize());
// sc.layout();
}
ScrollBar bar = sc.getVerticalBar();
int barWidth = 14;
if (bar != null) {
barWidth = bar.getSize().x;
}
resources = view.getDisplayedDays();
int count = resources.length;
Point textSize = SWTHelper.getStringBounds(this, "88:88"); //$NON-NLS-1$
textWidth = textSize.x;
left_offset = textWidth + 2;
sheetWidth = mySize.x - 2 * left_offset - barWidth;
widthPerColumn = sheetWidth / count;
ColumnHeader header = view.getHeader();
header.recalc(widthPerColumn, left_offset, padding, textSize.y);
for (TerminLabel l : tlabels) {
l.refresh();
}
sc.layout();
}
}
}
public double getPixelPerMinute(){
return ppm;
}
public double getWidthPerColumn(){
return widthPerColumn;
}
public int getPadding(){
return padding;
}
public int getLeftOffset(){
return left_offset;
}
class TimePainter implements PaintListener {
public void paintControl(PaintEvent e){
GC gc = e.gc;
gc.fillRectangle(e.x, e.y, e.width, e.height);
int y = 0;
TimeTool runner = new TimeTool();
String dayStartsAt =
CoreHub.globalCfg.get(PreferenceConstants.AG_DAY_PRESENTATION_STARTS_AT, "0000");
runner.set(dayStartsAt); //$NON-NLS-1$
String dayEndsAt =
CoreHub.globalCfg.get(PreferenceConstants.AG_DAY_PRESENTATION_ENDS_AT, "2359");
TimeTool limit = new TimeTool(dayEndsAt); //$NON-NLS-1$
Point textSize = gc.textExtent("88:88"); //$NON-NLS-1$
int textwidth = textSize.x;
int quarter = (int) Math.round(15.0 * BaseView.getPixelPerMinute());
int w = ProportionalSheet.this.getSize().x - 5;
int left = 0;
int right = w - textwidth;
while (runner.isBefore(limit)) {
gc.drawLine(left, y, w, y); // volle Linie
String time = runner.toString(TimeTool.TIME_SMALL);
gc.drawText(time, 0, y + 1);
gc.drawText(time, right, y + 1);
y += quarter;
gc.drawLine(textwidth - 3, y, textwidth, y);
gc.drawLine(right, y, right + 3, y);
y += quarter;
gc.drawLine(textwidth - 6, y, textwidth, y);
gc.drawLine(right, y, right + 6, y);
y += quarter;
gc.drawLine(textwidth - 3, y, textwidth, y);
gc.drawLine(right, y, right + 3, y);
y += quarter;
runner.addHours(1);
}
}
}
public Composite getComposite(){
return this;
}
}