/* GNU General Public License CacheWolf is a software for PocketPC, Win and Linux that enables paperless caching. It supports the sites geocaching.com and opencaching.de Copyright (C) 2006 CacheWolf development team See http://www.cachewolf.de/ for more information. 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. 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package CacheWolf.controls; import CacheWolf.Preferences; import CacheWolf.utils.MyLocale; import ewe.fx.Color; import ewe.fx.DrawnIcon; import ewe.fx.Insets; import ewe.fx.Point; import ewe.reflect.FieldTransfer; import ewe.sys.Convert; import ewe.sys.Locale; import ewe.sys.Time; import ewe.sys.TimeOfDay; import ewe.sys.Vm; import ewe.ui.CardPanel; import ewe.ui.CellPanel; import ewe.ui.Control; import ewe.ui.ControlEvent; import ewe.ui.Editor; import ewe.ui.InputPanelTableModel; import ewe.ui.MultiPanel; import ewe.ui.TableCellAttributes; import ewe.ui.TableControl; import ewe.ui.TableEvent; import ewe.ui.TableModel; import ewe.ui.UIConstants; import ewe.ui.mButton; import ewe.util.Vector; import ewe.util.mString; public class DateTimeChooser extends Editor { MultiPanel panels = new CardPanel(); public int year; public String monthName; public int month; public int day; public int hour; public int minute; public String time; Time dateSet; public boolean autoAdvance = true; public boolean didAll = false; TableControl dayChooser, monthChooser, yearChooser, timeChooser; public Locale locale = Vm.getLocale(); Control dayDisplay; Control monthDisplay; Control yearDisplay; Control timeDisplay; //Control minuteDisplay; Time getDate() { Time t = (Time) dateSet.getCopy(); t.day = day; t.month = month; t.year = year; t.hour = hour; t.minute = minute; t.update(); return t; } void addTable(TableControl tc, TableModel tm, String pName) { tc.setTableModel(tm); tc.setClickMode(true); panels.addItem(tc, pName, null); //tc.addListener(this); } boolean added = false; Control addTopData(CellPanel cp, String field) { Control dl = new mButton();//DumbLabel(1,10); cp.addNext(addField(dl, field), HSTRETCH, HFILL); dl.addListener(this); //dl.anchor = CENTER; dl.modify(DrawFlat, 0); dl.borderStyle = BDR_OUTLINE | BF_TOP | BF_RIGHT | BF_SQUARE; //if (!added) dl.borderStyle |= BF_LEFT; added = true; dl.borderColor = Color.Black; return dl; } public String firstPanel = "monthName"; public void reset(Time t) { setDate(t); didAll = false; newDate(); panels.select(firstPanel); } public CellPanel addTopSection(CellPanel addTo, Control cp) { int IconSize; if (Vm.isMobile() && Preferences.itself().getScreenWidth() >= 400) IconSize = 30; else IconSize = 30; addTo.modify(DrawFlat, 0); addTo.defaultTags.set(INSETS, new Insets(0, 0, 0, 0)); mButton b = new mButton(); b.borderStyle = BDR_OUTLINE | BF_LEFT | BF_TOP | BF_RIGHT | BF_SQUARE; b.image = new DrawnIcon(DrawnIcon.CROSS, IconSize, IconSize, new Color(0x80, 0, 0)); addTo.addNext(addField(b, "reject")).setCell(DONTSTRETCH); addTo.addNext(cp, HSTRETCH, HFILL); b = new mButton(); b.borderStyle = BDR_OUTLINE | BF_TOP | BF_RIGHT | BF_SQUARE; b.image = new DrawnIcon(DrawnIcon.TICK, IconSize, IconSize, new Color(0, 0x80, 0)); addTo.addNext(addField(b, "accept")).setCell(DONTSTRETCH); return addTo; } CardPanel cards = new CardPanel(); public DateTimeChooser(Locale l) { if (l != null) locale = l; setDate(new Time()); addLast(cards); CellPanel addTo = new CellPanel(); cards.addItem(addTo, "full", null); CellPanel cp = new CellPanel(); CellPanel top = new CellPanel(); cp.equalWidths = true; firstPanel = "day"; dayDisplay = addTopData(cp, "day"); monthDisplay = addTopData(cp, "monthName"); yearDisplay = addTopData(cp, "year"); timeDisplay = addTopData(cp, "time"); cp.endRow(); addTopSection(top, cp); addTo.addLast(top).setCell(HSTRETCH); addTo.addLast((Control) panels); addTable(dayChooser = new TableControl(), new dayChooserTableModel(locale), "day"); addTable(monthChooser = new TableControl(), new monthChooserTableModel(locale), "monthName"); addTable(yearChooser = new TableControl(), new yearChooserTableModel(), "year"); addTable(timeChooser = new TableControl(), new timeChooserTableModel(), "time"); // the following is already done in addTopSection? /* mButton b = new mButton(); //b.borderStyle = BDR_OUTLINE|BF_LEFT|BF_TOP|BF_RIGHT|BF_SQUARE; b.image = new DrawnIcon(DrawnIcon.CROSS,10,10,new Color(0x80,0,0)); addField(b,"reject"); b.image = new DrawnIcon(DrawnIcon.CROSS,10,10,new Color(0x80,0,0)); b = new mButton(); b.image = new DrawnIcon(DrawnIcon.TICK,10,10,new Color(0,0x80,0)); addField(b,"accept"); */ newDate(); } public void fieldChanged(FieldTransfer ft, Editor ed) { newDate(); } public void action(FieldTransfer ft, Editor ed) { String n = ft.fieldName; if (n.equals("day") || n.equals("monthName") || n.equals("year") || n.equals("time")) panels.select(n); if (n.equals("accept") || n.equals("entered")) exit(IDOK); if (n.equals("reject")) exit(IDCANCEL); } public void onControlEvent(ControlEvent ev) { if (ev instanceof TableEvent && ev.type == TableEvent.CELL_CLICKED) { if (ev.target == dayChooser) { day = Convert.toInt((String) ((TableEvent) ev).cellData); newDate(); toControls("day"); if (autoAdvance && !didAll) { panels.select("monthName"); } } else if (ev.target == monthChooser) { month = (int) ((ewe.sys.Long) (((TableEvent) ev).cellData)).value; newDate(); monthName = locale.getString(Locale.SHORT_MONTH, month, 0); toControls("monthName"); if (autoAdvance && !didAll) { panels.select("year"); didAll = true; } } else if (ev.target == yearChooser) { String p = (String) ((TableEvent) ev).cellData; int dec = year % 100; year -= dec; if (p.charAt(0) == 'C') { if (p.charAt(1) == '+') year = year + 100 + dec; else year = year - 100 + dec; } else { int val = Convert.toInt(p); if (val > 9) year = val * 100; else { dec = dec * 10 + val; year += dec % 100; } } newDate(); toControls("year"); } else if (ev.target == timeChooser) { timeChooserTableModel tcm = (timeChooserTableModel) timeChooser.getTableModel(); int newHour = tcm.getHourFor(((TableEvent) ev).row, ((TableEvent) ev).col); if (newHour > -1) hour = newHour; int newMinute = tcm.getMinuteFor(((TableEvent) ev).row, ((TableEvent) ev).col); if (newMinute > -1) minute = newMinute; time = MyLocale.formatLong(hour, "00") + ":" + MyLocale.formatLong(minute, "00"); tcm.set(hour, minute); timeChooser.repaintNow(); newDate(); toControls("time"); } } if (ev.type == ControlEvent.CANCELLED) exit(IDCANCEL); else super.onControlEvent(ev); } private void setDate(Time t) { dateSet = t; if (!t.isValid()) t = new Time(); Time.toString(t, t instanceof TimeOfDay ? t.getFormat() : locale.getString(Locale.SHORT_DATE_FORMAT, 0, 0), locale); day = t.day; month = t.month; year = t.year; hour = t.hour; minute = t.minute; time = MyLocale.formatLong(hour, "00") + ":" + MyLocale.formatLong(minute, "00"); monthName = locale.getString(Locale.SHORT_MONTH, t.month, 0); toControls("day,month,year,monthName,time"); } private void newDate() { Time t = new Time(day, month, year); t.hour = hour; t.minute = minute; Time t2 = t; if (!t2.isValid()) t2 = new Time(day = 1, month, year); if (!t2.isValid()) t2 = new Time(); if (t2 != t) { setDate(t2); } dayChooserTableModel dcm = (dayChooserTableModel) dayChooser.getTableModel(); dcm.set(day, month, year); monthChooserTableModel mcm = (monthChooserTableModel) monthChooser.getTableModel(); mcm.set(day, month, year); timeChooserTableModel tcm = (timeChooserTableModel) timeChooser.getTableModel(); tcm.set(hour, minute); //dayChooser.repaintNow(); //monthChooser.repaintNow(); } public int getDay() { return day; } public int getMonth() { return month; } public int getYear() { return year; } public String getTime() { return time; } public int getHour() { return hour; } public int getMinute() { return minHeight; } } // DateTimeChooser //------------------------------------------------------- class monthChooserTableModel extends InputPanelTableModel { //------------------------------------------------------- int chosenMonth; Locale locale = Vm.getLocale(); monthChooserTableModel(Locale locale) { this.locale = locale; numRows = 3; numCols = 4; hasColumnHeaders = false; hasRowHeaders = false; fillToEqualHeights = fillToEqualWidths = true; } void set(int day, int month, int year) { int old = chosenMonth; chosenMonth = month; if (old != chosenMonth) refreshMonth(old); } int getMonthFor(int row, int cell) { if (row == -1 || cell == -1) return 0; int idx = row * 4 + cell; return idx + 1; } Point getCellFor(int month, Point dest) { month--; int row = (month / 4) % 3; int col = month % 4; return Point.unNull(dest).set(col, row); } void refreshMonth(int month) { Point p = getCellFor(month, null); table.repaintCell(p.y, p.x); } public TableCellAttributes getCellAttributes(int row, int col, boolean isSelected, TableCellAttributes ta) { ta.flat = true; ta = super.getCellAttributes(row, col, isSelected, ta); ta.borderStyle = fixBorder(UIConstants.BDR_OUTLINE | UIConstants.BF_BOTTOM | UIConstants.BF_RIGHT, row, col, true); if (getMonthFor(row, col) == chosenMonth && !isSelected) { ta.fillColor = new Color(0x80, 0x80, 0xff); } return ta; } public Object getCellText(int row, int col) { return locale.getString(Locale.SHORT_MONTH, getMonthFor(row, col), 0); } public Object getCellData(int row, int col) { int month = getMonthFor(row, col); return new ewe.sys.Long().set(month); } } //------------------------------------------------------- class dayChooserTableModel extends InputPanelTableModel { //------------------------------------------------------- Vector days = new Vector(); Locale locale = Vm.getLocale(); int firstDayIndex = 0; int numDays = 28; int chosenDay = 0; void set(int day, int month, int year) { numDays = Time.numberOfDays(month, year); Time t = new Time(1, month, year); firstDayIndex = Time.indexOfDayInWeek(t.dayOfWeek, locale) - 1; int oldDay = chosenDay; chosenDay = day; if (oldDay != chosenDay) refreshDay(oldDay); } int getDayFor(int row, int cell) { if (row == -1 || cell == -1) return 0; int idx = row * 7 + cell; if (idx >= firstDayIndex && idx < firstDayIndex + numDays) return idx - firstDayIndex + 1; idx = idx + 35; if (idx >= firstDayIndex && idx < firstDayIndex + numDays) return idx - firstDayIndex + 1; return 0; } Point getCellFor(int day, Point dest) { day += firstDayIndex - 1; int row = (day / 7) % 5; int col = day % 7; return Point.unNull(dest).set(col, row); } void refreshDay(int day) { Point p = getCellFor(day, null); table.repaintCell(p.y, p.x); } public TableCellAttributes getCellAttributes(int row, int col, boolean isSelected, TableCellAttributes ta) { ta.flat = true; ta = super.getCellAttributes(row, col, isSelected, ta); ta.borderStyle = fixBorder(UIConstants.BDR_OUTLINE | UIConstants.BF_BOTTOM | UIConstants.BF_RIGHT, row, col, true); if (getDayFor(row, col) == chosenDay && !isSelected) { ta.fillColor = new Color(0x80, 0x80, 0xff); } return ta; } dayChooserTableModel(Locale l) { this.locale = l; numRows = 5; numCols = 7; hasColumnHeaders = true; hasRowHeaders = false; for (int i = 1; i <= 7; i++) days.add(l.getString(Locale.SHORT_DAY_OF_WEEK, i, 0)); fillToEqualHeights = fillToEqualWidths = true; } public boolean canSelect(int row, int col) { return (getDayFor(row, col) != 0); } public Object getCellData(int row, int col) { if (row == -1) return days.get(col); else { int val = getDayFor(row, col); if (val == 0) return null; return Convert.toString(val); } } } //------------------------------------------------------- class yearChooserTableModel extends InputPanelTableModel { //------------------------------------------------------- yearChooserTableModel() { numRows = 4; numCols = 4; hasColumnHeaders = false; hasRowHeaders = false; } String[] all = mString.split("19xx|7|8|9|20xx|4|5|6|21xx|1|2|3|18xx|0|C+|C-"); public Object getCellText(int row, int col) { if (row >= 0 && col >= 0) return all[col + row * 4]; return null; } public Object getCellData(int row, int col) { String str = (String) getCellText(row, col); if (str.length() > 2) str = str.substring(0, 2); return str; } public TableCellAttributes getCellAttributes(int row, int col, boolean isSelected, TableCellAttributes ta) { ta.flat = true; ta = super.getCellAttributes(row, col, isSelected, ta); return ta; } } //------------------------------------------------------- class timeChooserTableModel extends InputPanelTableModel { // ------------------------------------------------------- int chosenHour = -2, chosenMinute = -2; timeChooserTableModel() { numRows = 6; numCols = 15; hasColumnHeaders = false; hasRowHeaders = false; } void set(int hour, int minute) { int old = chosenHour; chosenHour = hour; if (old != chosenHour) refreshHour(old); old = chosenMinute; chosenMinute = minute; if (old != chosenMinute) refreshMinute(old); } int getHourFor(int row, int cell) { if (row == -1 || cell == -1) return 0; if (cell >= 4) return -1; return row * 4 + cell; } Point getCellForHour(int hour, Point dest) { int row = (hour / 4) % 6; int col = hour % 4; return Point.unNull(dest).set(col, row); } void refreshHour(int hour) { Point p = getCellForHour(hour, null); table.repaintCell(p.y, p.x); } int getMinuteFor(int row, int cell) { if (row == -1 || cell == -1) return 0; if (cell <= 4) return -1; return row * 10 + cell - 5; } Point getCellForMinute(int minute, Point dest) { int row = (minute / 10) % 6; int col = minute % 10; return Point.unNull(dest).set(col, row); } void refreshMinute(int minute) { Point p = getCellForMinute(minute, null); table.repaintCell(p.y, p.x); } public Object getCellText(int row, int col) { if (row >= 0 && col >= 0) if (col < 4) return Convert.toString(row * 4 + col); else if (col == 4) return ""; else return Convert.toString(row * 10 + col - 5); return null; } public Object getCellData(int row, int col) { return getCellText(row, col); } public TableCellAttributes getCellAttributes(int row, int col, boolean isSelected, TableCellAttributes ta) { ta.flat = true; if (col == 4) { ta = super.getCellAttributes(row, col, isSelected, ta); ta.fillColor = Color.LightGray; } else ta = super.getCellAttributes(row, col, isSelected, ta); if (getHourFor(row, col) == chosenHour && !isSelected) { ta.fillColor = new Color(0x80, 0x80, 0xff); } if (getMinuteFor(row, col) == chosenMinute && !isSelected) { ta.fillColor = new Color(0x80, 0x80, 0xff); } return ta; } public int calculateColWidth(int col) { if (col == 4) return 4; else if (col < 4) return super.calculateColWidth(col) + 2; else return super.calculateColWidth(col); } }