001: /*
002: The contents of this file are subject to the Common Public Attribution License
003: Version 1.0 (the "License"); you may not use this file except in compliance with
004: the License. You may obtain a copy of the License at
005: http://www.projity.com/license . The License is based on the Mozilla Public
006: License Version 1.1 but Sections 14 and 15 have been added to cover use of
007: software over a computer network and provide for limited attribution for the
008: Original Developer. In addition, Exhibit A has been modified to be consistent
009: with Exhibit B.
010:
011: Software distributed under the License is distributed on an "AS IS" basis,
012: WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
013: specific language governing rights and limitations under the License. The
014: Original Code is OpenProj. The Original Developer is the Initial Developer and
015: is Projity, Inc. All portions of the code written by Projity are Copyright (c)
016: 2006, 2007. All Rights Reserved. Contributors Projity, Inc.
017:
018: Alternatively, the contents of this file may be used under the terms of the
019: Projity End-User License Agreeement (the Projity License), in which case the
020: provisions of the Projity License are applicable instead of those above. If you
021: wish to allow use of your version of this file only under the terms of the
022: Projity License and not to allow others to use your version of this file under
023: the CPAL, indicate your decision by deleting the provisions above and replace
024: them with the notice and other provisions required by the Projity License. If
025: you do not delete the provisions above, a recipient may use your version of this
026: file under either the CPAL or the Projity License.
027:
028: [NOTE: The text of this license may differ slightly from the text of the notices
029: in Exhibits A and B of the license at http://www.projity.com/license. You should
030: use the latest text at http://www.projity.com/license for your modifications.
031: You may not remove this license text from the source files.]
032:
033: Attribution Information: Attribution Copyright Notice: Copyright � 2006, 2007
034: Projity, Inc. Attribution Phrase (not exceeding 10 words): Powered by OpenProj,
035: an open source solution from Projity. Attribution URL: http://www.projity.com
036: Graphic Image as provided in the Covered Code as file: openproj_logo.png with
037: alternatives listed on http://www.projity.com/logo
038:
039: Display of Attribution Information is required in Larger Works which are defined
040: in the CPAL as a work which combines Covered Code or portions thereof with code
041: not governed by the terms of the CPAL. However, in addition to the other notice
042: obligations, all copies of the Covered Code in Executable and Source Code form
043: distributed must, as a form of attribution of the original author, include on
044: each user interface screen the "OpenProj" logo visible to all users. The
045: OpenProj logo should be located horizontally aligned with the menu bar and left
046: justified on the top left of the screen adjacent to the File menu. The logo
047: must be at least 100 x 25 pixels. When users click on the "OpenProj" logo it
048: must direct them back to http://www.projity.com.
049: */
050: package com.projity.timescale;
051:
052: import java.text.SimpleDateFormat;
053: import java.util.Calendar;
054:
055: import com.projity.util.DateTime;
056: import com.projity.util.Environment;
057:
058: /**
059: *
060: */
061: public class TimeScale {
062: protected int minWidth;
063: protected int tableMinWidth;
064: protected int normalMinWidth;
065: protected long minDuration;
066: protected int number1;
067: protected int number2;
068: protected int calendarField1;
069: protected int calendarField2;
070: protected double ratio = -1.0;
071: protected String pattern1;
072: protected String pattern2;
073: protected int trunc1 = -1;
074: protected int trunc2 = -1;
075: protected boolean upperCase1 = false;
076: protected boolean upperCase2 = false;
077:
078: // private Date recycledDate=new Date();
079: private ExtendedDateFormat recycledDateFormat;
080:
081: /**
082: *
083: */
084: public TimeScale() {
085: recycledDateFormat = DateTime.extendedUtcDateFormatInstance();
086: }
087:
088: private Calendar tmp = DateTime.calendarInstance();
089:
090: public long floor1(long t) {
091: tmp.setTimeInMillis(t);
092: floor(tmp, calendarField1, number1, -1);
093: return tmp.getTimeInMillis();
094: }
095:
096: public long ceil1(long t) {
097: tmp.setTimeInMillis(t);
098: ceil(tmp, calendarField1, number1, -1);
099: return tmp.getTimeInMillis();
100: }
101:
102: public void floor1(Calendar calendar) {
103: floor(calendar, calendarField1, number1, -1);
104: }
105:
106: public void floor1(Calendar calendar, long startReference) {
107:
108: floor(calendar, calendarField1, number1, startReference);
109: }
110:
111: public void floor2(Calendar calendar) {
112: floor(calendar, calendarField2, number2, -1);
113: }
114:
115: public void floor2(Calendar calendar, long startReference) {
116: floor(calendar, calendarField2, number2, startReference);
117: }
118:
119: public void ceil1(Calendar calendar) {
120: ceil(calendar, calendarField1, number1, -1);
121: }
122:
123: public void ceil1(Calendar calendar, long startReference) {
124:
125: ceil(calendar, calendarField1, number1, startReference);
126: }
127:
128: public void ceil2(Calendar calendar) {
129: ceil(calendar, calendarField2, number2, -1);
130: }
131:
132: public void ceil2(Calendar calendar, long startReference) {
133: ceil(calendar, calendarField2, number2, startReference);
134: }
135:
136: protected void floor(Calendar calendar, int calendarField,
137: int number, long startReference) {
138: CalendarUtil.floor(calendar, calendarField, number);
139: // if (number>1){
140: // long ref=calendar.getTimeInMillis();
141: // if (calendarField==2&&number==3){
142: // System.out.println("floor: "+CalendarUtil.toString(calendar)+", ref="+CalendarUtil.toString(ref)+", startReference="+CalendarUtil.toString(startReference));
143: // }
144: // if (startReference==-1) calendar.set(calendarField,calendar.getActualMinimum(calendarField));
145: // else calendar.setTimeInMillis(startReference);
146: // if (calendarField==2&&number==3){
147: // System.out.println("floor#2: "+CalendarUtil.toString(calendar));
148: // }
149: // while(calendar.getTimeInMillis()<=ref){
150: // calendar.add(calendarField,number);
151: // if (calendarField==2&&number==3){
152: // System.out.println("floor#3: "+CalendarUtil.toString(calendar));
153: // }
154: //
155: // }
156: // if (calendarField==2&&number==3){
157: // System.out.println("floor#3.9: "+CalendarUtil.toString(calendar));
158: // }
159: // calendar.add(calendarField,-number);
160: // if (calendarField==2&&number==3){
161: // System.out.println("floor#4: "+CalendarUtil.toString(calendar));
162: // }
163: //
164: // }
165: }
166:
167: protected void ceil(Calendar calendar, int calendarField,
168: int number, long startReference) {
169: Calendar ref = DateTime.calendarInstance();
170: ref.setTimeInMillis(calendar.getTimeInMillis());
171: floor(ref, calendarField, number, startReference);
172: if (ref.getTimeInMillis() == calendar.getTimeInMillis())
173: return;
174: floor(calendar, calendarField, number, startReference);
175: calendar.add(calendarField, number);
176: }
177:
178: public void increment1(Calendar calendar) {
179: calendar.add(calendarField1, number1);
180: }
181:
182: public void increment2(Calendar calendar) {
183: calendar.add(calendarField2, number2);
184: }
185:
186: public String getText1(long t) {
187: tmp.setTimeInMillis(t);
188: recycledDateFormat.applyPattern(pattern1);
189: String r = recycledDateFormat.format(tmp.getTime());
190: if (trunc1 >= 0) {
191: // patch for Chinese week display
192: if (Environment.isChinese()) {
193: int len = r.length();
194: if (len > 2)
195: return r.substring(len - trunc1);
196: }
197: r = r.substring(0, trunc1);
198: }
199: if (upperCase1)
200: r = r.toUpperCase();
201: return r;
202: }
203:
204: public String getText2(long t) {
205: tmp.setTimeInMillis(t);
206: recycledDateFormat.applyPattern(pattern2);
207: String r = recycledDateFormat.format(tmp.getTime());
208: if (trunc2 >= 0)
209: r = r.substring(0, trunc2);
210: if (upperCase2)
211: r = r.toUpperCase();
212: return r;
213: }
214:
215: public void toggleWidth(boolean normal) {
216: if ((minWidth == normalMinWidth) != normal) {
217: if (normal)
218: minWidth = normalMinWidth;
219: else
220: minWidth = tableMinWidth;
221: updateRatio();
222: }
223: }
224:
225: public double getRatio() {
226: if (ratio == -1.0)
227: updateRatio();
228: return ratio;
229: }
230:
231: private void updateRatio() {
232: minDuration = CalendarUtil.getMinDuration(calendarField1)
233: * number1;
234: ratio = ((double) minWidth) / ((double) minDuration);
235: }
236:
237: public double toTime(double x) {
238: return x / getRatio();
239: }
240:
241: public double toX(double t) {
242: return t * getRatio();
243: }
244:
245: /**
246: * @param calendarField1 The calendarField1 to set.
247: */
248: public void setCalendarField1(int calendarField1) {
249: this .calendarField1 = calendarField1;
250: }
251:
252: /**
253: * @param calendarField2 The calendarField2 to set.
254: */
255: public void setCalendarField2(int calendarField2) {
256: this .calendarField2 = calendarField2;
257: }
258:
259: /**
260: * @param minWidth The minWidth to set.
261: */
262: public void setNormalMinWidth(int normalMinWidth) {
263: this .normalMinWidth = normalMinWidth;
264: minWidth = normalMinWidth;
265: }
266:
267: /**
268: * @param minWidth The minWidth to set.
269: */
270: public void setNormalMinWidthChinese(int normalMinWidth) {
271: if (Environment.isChinese()) { //overrides because it's called after setNormalMinWidth()
272: this .normalMinWidth = normalMinWidth;
273: minWidth = normalMinWidth;
274: }
275: }
276:
277: /**
278: * @param number1 The number1 to set.
279: */
280: public void setNumber1(int number1) {
281: this .number1 = number1;
282: }
283:
284: /**
285: * @param number2 The number2 to set.
286: */
287: public void setNumber2(int number2) {
288: this .number2 = number2;
289: }
290:
291: /**
292: * @param pattern1 The pattern1 to set.
293: */
294: public void setPattern1(String pattern1) {
295: this .pattern1 = pattern1;
296: }
297:
298: /**
299: * @param pattern2 The pattern2 to set.
300: */
301: public void setPattern2(String pattern2) {
302: this .pattern2 = pattern2;
303: }
304:
305: /**
306: * @param trunc1 The trunc1 to set.
307: */
308: public void setTrunc1(int trunc1) {
309: this .trunc1 = trunc1;
310: }
311:
312: /**
313: * @param trunc2 The trunc2 to set.
314: */
315: public void setTrunc2(int trunc2) {
316: this .trunc2 = trunc2;
317: }
318:
319: /**
320: * @param uppercase1 The uppercase1 to set.
321: */
322: public void setUpperCase1(boolean upperCase1) {
323: this .upperCase1 = upperCase1;
324: }
325:
326: /**
327: * @param uppercase2 The uppercase2 to set.
328: */
329: public void setUpperCase2(boolean upperCase2) {
330: this .upperCase2 = upperCase2;
331: }
332:
333: public void setTableMinWidth(int tableMinWidth) {
334: this .tableMinWidth = tableMinWidth;
335: }
336:
337: public Object clone() {
338: TimeScale t = new TimeScale();
339: t.minWidth = minWidth;
340: t.tableMinWidth = tableMinWidth;
341: t.normalMinWidth = normalMinWidth;
342: t.minDuration = minDuration;
343: t.number1 = number1;
344: t.number2 = number2;
345: t.calendarField1 = calendarField1;
346: t.calendarField2 = calendarField2;
347: t.ratio = ratio;
348: t.pattern1 = pattern1;
349: t.pattern2 = pattern2;
350: t.trunc1 = trunc1;
351: t.trunc2 = trunc2;
352: t.upperCase1 = upperCase1;
353: t.upperCase2 = upperCase2;
354: return t;
355: }
356:
357: /**
358: * Get millis between smallest intervals
359: * @return
360: */
361: public long getIntervalDuration() {
362: return CalendarUtil.getMinDuration(calendarField1) * number1;
363: }
364: }
|