2 * Copyright (C) 2011 Morphoss Ltd
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation, either version 3 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 package com
.morphoss
.acal
.widget
;
21 import java
.util
.ArrayList
;
23 import android
.app
.Dialog
;
24 import android
.content
.Context
;
25 import android
.content
.SharedPreferences
;
26 import android
.content
.SharedPreferences
.Editor
;
27 import android
.preference
.PreferenceManager
;
28 import android
.view
.View
;
29 import android
.view
.View
.OnClickListener
;
30 import android
.widget
.AdapterView
;
31 import android
.widget
.AdapterView
.OnItemSelectedListener
;
32 import android
.widget
.Button
;
33 import android
.widget
.CheckBox
;
34 import android
.widget
.CompoundButton
;
35 import android
.widget
.CompoundButton
.OnCheckedChangeListener
;
36 import android
.widget
.DatePicker
;
37 import android
.widget
.DatePicker
.OnDateChangedListener
;
38 import android
.widget
.Spinner
;
39 import android
.widget
.TimePicker
;
40 import android
.widget
.TimePicker
.OnTimeChangedListener
;
42 import com
.morphoss
.acal
.R
;
43 import com
.morphoss
.acal
.acaltime
.AcalDateTime
;
44 import com
.morphoss
.acal
.acaltime
.AcalDateTimeFormatter
;
47 * A dialog for selecting a date, with a time and a timezone (or perhaps floating, or just as a date)
48 * @author Morphoss Ltd
51 public class DateTimeDialog
extends Dialog
52 implements OnClickListener
, OnTimeChangedListener
, OnDateChangedListener
,
53 OnCheckedChangeListener
, OnItemSelectedListener
56 private static final String TZPREFNAME
= "recentTimeZone-";
57 private Context context
;
58 private DateTimeSetListener dialogListener
;
60 private Button setButton
;
61 private Button cancelButton
;
62 private DatePicker datePicker
;
63 private TimePicker timePicker
;
64 private CheckBox dateOnlyCheckBox
;
65 private Spinner timeZoneSpinner
;
66 private TimeZoneListAdapter tzListAdapter
;
67 private boolean allowDateVsDateTimeSwitching
= true;
69 private int oldTimeZoneWas
= 0;
71 private ArrayList
<String
> recentZones
;
73 private AcalDateTime currentDateTime
;
74 private final boolean use24HourTime
;
75 private final boolean allowTimeZoneSetting
;
76 private SharedPreferences prefs
;
79 * A dialog for selecting a date, with a time and a timezone (or perhaps floating, or just as a date)
80 * @param context A UIcontext.
81 * @param dateTimeValue The initial setting
82 * @param twentyFourHourTime Whether to use am/pm or 24hour time
83 * @param allowDateTimeSwitching Whether the user can control whether this is a pure date.
84 * @param allowTimeZones Whether the user can select a time zone.
85 * @param listener The listener for the result.
87 public DateTimeDialog(Context context
, AcalDateTime dateTimeValue
, boolean twentyFourHourTime
,
88 boolean allowDateTimeSwitching
, boolean allowTimeZones
, DateTimeSetListener listener
) {
90 this.context
= context
;
91 this.dialogListener
= listener
;
93 use24HourTime
= twentyFourHourTime
;
94 setContentView(R
.layout
.datetime_dialog
);
95 allowDateVsDateTimeSwitching
= allowDateTimeSwitching
;
96 allowTimeZoneSetting
= allowTimeZones
;
98 recentZones
= new ArrayList
<String
>(10);
99 prefs
= PreferenceManager
.getDefaultSharedPreferences(context
);
100 String recentZonePref
;
101 for( int i
=0; i
<10; i
++ ) {
102 recentZonePref
= prefs
.getString(TZPREFNAME
+i
, null);
103 if ( recentZonePref
!= null ) {
104 recentZones
.add(recentZonePref
);
108 currentDateTime
= (dateTimeValue
== null ?
new AcalDateTime() : dateTimeValue
.clone());
113 private void populateLayout() {
115 setButton
= (Button
)this.findViewById(R
.id
.DateTimeSetButton
);
116 cancelButton
= (Button
)this.findViewById(R
.id
.DateTimeCancelButton
);
117 setButton
.setOnClickListener(this);
118 cancelButton
.setOnClickListener(this);
120 datePicker
= (DatePicker
) this.findViewById(R
.id
.datePicker
);
121 datePicker
.init(currentDateTime
.getYear(), currentDateTime
.getMonth() - 1, currentDateTime
.getMonthDay(),this);
123 timePicker
= (TimePicker
) this.findViewById(R
.id
.timePicker
);
124 timePicker
.setIs24HourView(use24HourTime
);
125 timePicker
.setCurrentHour((int) currentDateTime
.getHour());
126 timePicker
.setCurrentMinute((int) currentDateTime
.getMinute());
127 timePicker
.setOnTimeChangedListener(this);
128 timePicker
.setAddStatesFromChildren(true);
130 dateOnlyCheckBox
= (CheckBox
) this.findViewById(R
.id
.DateTimeIsDate
);
132 timeZoneSpinner
= (Spinner
) this.findViewById(R
.id
.DateTimeZoneSelect
);
133 tzListAdapter
= new TimeZoneListAdapter(this.context
, currentDateTime
.getTimeZone(), recentZones
);
134 timeZoneSpinner
.setAdapter(tzListAdapter
);
135 timeZoneSpinner
.setOnItemSelectedListener(this);
137 if ( allowDateVsDateTimeSwitching
) {
138 dateOnlyCheckBox
.setChecked(currentDateTime
.isDate());
139 dateOnlyCheckBox
.setOnCheckedChangeListener(this);
142 dateOnlyCheckBox
.setVisibility(View
.GONE
);
143 if ( currentDateTime
.isDate() ) {
144 timePicker
.setVisibility(View
.GONE
);
145 timeZoneSpinner
.setVisibility(View
.GONE
);
148 if ( !allowTimeZoneSetting
)
149 timeZoneSpinner
.setVisibility(View
.GONE
);
155 private void updateLayout() {
156 timePicker
.setEnabled(!dateOnlyCheckBox
.isChecked());
157 timeZoneSpinner
.setSelection(dateOnlyCheckBox
.isChecked() ?
0 : tzListAdapter
.getPositionOf(currentDateTime
.getTimeZoneId()));
158 timeZoneSpinner
.setEnabled(!dateOnlyCheckBox
.isChecked());
159 this.setTitle(AcalDateTimeFormatter
.fmtFull(currentDateTime
,use24HourTime
));
163 private void toggleIsDate( boolean isDate
) {
164 if ( isDate
) oldTimeZoneWas
= timeZoneSpinner
.getSelectedItemPosition();
165 currentDateTime
.setAsDate(isDate
);
167 currentDateTime
.setTimeZone(tzListAdapter
.getTzId(oldTimeZoneWas
));
168 timeZoneSpinner
.setSelection(oldTimeZoneWas
);
174 public void onClick(View v
) {
175 if (v
== setButton
) {
179 dialogListener
.onDateTimeSet(currentDateTime
);
181 if ( !currentDateTime
.isFloating() ) {
182 String currentZone
= currentDateTime
.getTimeZoneId();
183 Editor e
= prefs
.edit();
184 e
.putString(TZPREFNAME
+0, currentZone
);
185 for( int i
=0,j
=1; i
<recentZones
.size() && j
<10; i
++) {
186 if ( !recentZones
.get(i
).equals(currentZone
) ) {
187 e
.putString(TZPREFNAME
+j
, recentZones
.get(i
));
200 public void onCheckedChanged(CompoundButton buttonView
, boolean isChecked
) {
201 if ( buttonView
== dateOnlyCheckBox
) toggleIsDate(isChecked
);
206 public void onItemSelected(AdapterView
<?
> parent
, View view
, int pos
, long id
) {
207 currentDateTime
.setTimeZone(tzListAdapter
.getTzId(timeZoneSpinner
.getSelectedItemPosition()));
213 public void onNothingSelected(AdapterView
<?
> parent
) {
218 private void fixFocusAndApply() {
219 // force the datepicker & timepicker to lose focus and the typed value is available !
220 timePicker
.clearFocus();
222 // re-read the values, in my case they are now changed
223 currentDateTime
.setHour(timePicker
.getCurrentHour());
224 currentDateTime
.setMinute(timePicker
.getCurrentMinute());
226 datePicker
.clearFocus();
227 currentDateTime
.setYearMonthDay(datePicker
.getYear(), datePicker
.getMonth()+1, datePicker
.getDayOfMonth());
232 public void onTimeChanged(TimePicker view
, int hourOfDay
, int minute
) {
233 currentDateTime
.setHour(hourOfDay
);
234 currentDateTime
.setMinute(minute
);
240 public void onDateChanged(DatePicker view
, int year
, int monthOfYear
, int dayOfMonth
) {
241 currentDateTime
.setYearMonthDay(year
, monthOfYear
+1, dayOfMonth
);