/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.redgeek.android.eventrend.datum; import java.util.Calendar; import net.redgeek.android.eventrend.EvenTrendActivity; import net.redgeek.android.eventrend.Preferences; import net.redgeek.android.eventrend.R; import net.redgeek.android.eventrend.db.CategoryDbTable; import net.redgeek.android.eventrend.db.EntryDbTable; import net.redgeek.android.eventrend.primitives.TimeSeriesCollector; import net.redgeek.android.eventrend.util.DateUtil; import net.redgeek.android.eventrend.util.DynamicSpinner; import android.app.DatePickerDialog; import android.app.Dialog; import android.app.TimePickerDialog; import android.database.Cursor; import android.graphics.Color; import android.os.Bundle; import android.view.Gravity; import android.view.KeyEvent; import android.view.View; import android.widget.AdapterView; import android.widget.Button; import android.widget.DatePicker; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.TimePicker; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.TableRow.LayoutParams; public class EntryEditActivity extends EvenTrendActivity { // Dialog IDs static final int TIME_DIALOG_ID = 0; static final int DATE_DIALOG_ID = 1; // UI elements private DynamicSpinner mCategoryMenu; private LinearLayout mCategoryMenuRow; private TextView mCategoryChanged; private EditText mValueView; private TextView mValueChanged; private TextView mTimestampView; private TextView mTimestampChangedView; private Button mOk; private Button mDelete; private TextView mAggregationView; private Button mPickDate; private Button mPickTime; private Button mPickNow; // Listeners private OnItemSelectedListener mCategoryMenuListener; private View.OnClickListener mPickDateListener; private View.OnClickListener mPickTimeListener; private View.OnClickListener mPickNowListener; private View.OnKeyListener mValueViewListener; private View.OnClickListener mOkListener; private View.OnClickListener mDeleteListener; private DatePickerDialog.OnDateSetListener mDateSetListener; private TimePickerDialog.OnTimeSetListener mTimeSetListener; // Private data private EntryDbTable.Row mEntry; private Long mRowId; private long mCategoryId = 0; private float mValue = (float) 0.0; private boolean mTimestampChanged = false; private boolean mSave = false; private int mAggregation; // Prefs private int mHistory; private float mSmoothing; private float mSensitivity; // original values private long mOriginalCategoryId; private float mOriginalValue; private DateUtil.DateItem mOriginalTimestamp; // picker values private DateUtil.DateItem mPickerTimestamp; private Calendar mCal; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.entry_edit); setupData(icicle); setupUI(); populateFields(mEntry); saveOriginalValues(); setTimestamp(); } private void setupData(Bundle icicle) { if (icicle != null) { mRowId = icicle.getLong(EntryDbTable.KEY_ROWID); if (mRowId < 0) mRowId = null; } if (mRowId == null || mRowId < 0) { Bundle extras = getIntent().getExtras(); if (extras != null) { mRowId = extras.getLong(EntryDbTable.KEY_ROWID); } } if (mRowId != null) { mEntry = getDbh().fetchEntry(mRowId); mCategoryId = mEntry.getCategoryId(); } mCal = Calendar.getInstance(); mOriginalTimestamp = new DateUtil.DateItem(); mPickerTimestamp = new DateUtil.DateItem(); } private void setupPrefs() { mHistory = Preferences.getHistory(getCtx()); mSmoothing = Preferences.getSmoothingConstant(getCtx()); mSensitivity = Preferences.getStdDevSensitivity(getCtx()); } private void setupUI() { setupListeners(); mCategoryMenuRow = (LinearLayout) findViewById(R.id.entry_edit_category_menu_row); mCategoryMenu = (DynamicSpinner) new DynamicSpinner(this); mCategoryMenuRow.addView(mCategoryMenu, new LinearLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); mCategoryMenuRow.setGravity(Gravity.RIGHT | Gravity.CENTER_VERTICAL); mCategoryChanged = (TextView) findViewById(R.id.entry_edit_category_changed); mCategoryMenu.setOnItemSelectedListener(mCategoryMenuListener); setupMenu(); mValueView = (EditText) findViewById(R.id.entry_edit_value); mValueChanged = (TextView) findViewById(R.id.entry_edit_value_changed); mValueView.setOnKeyListener(mValueViewListener); mTimestampView = (TextView) findViewById(R.id.entry_edit_timestamp); mTimestampChangedView = (TextView) findViewById(R.id.entry_edit_timestamp_changed); mAggregationView = (TextView) findViewById(R.id.entry_edit_n_entries); mPickDate = (Button) findViewById(R.id.entry_set_date); mPickDate.setOnClickListener(mPickDateListener); mPickTime = (Button) findViewById(R.id.entry_set_time); mPickTime.setOnClickListener(mPickTimeListener); mPickNow = (Button) findViewById(R.id.entry_set_now); mPickNow.setOnClickListener(mPickNowListener); mOk = (Button) findViewById(R.id.entry_edit_ok); mOk.setOnClickListener(mOkListener); mDelete = (Button) findViewById(R.id.entry_edit_delete); mDelete.setOnClickListener(mDeleteListener); } private void setupListeners() { mCategoryMenuListener = new OnItemSelectedListener() { public void onItemSelected(AdapterView parent, View v, int position, long id) { mCategoryId = (long) mCategoryMenu.getMappingFromPosition(position); updateCategoryMarker(); } public void onNothingSelected(AdapterView arg0) { return; } }; mPickDateListener = new View.OnClickListener() { public void onClick(View v) { showDialog(DATE_DIALOG_ID); } }; mPickTimeListener = new View.OnClickListener() { public void onClick(View v) { showDialog(TIME_DIALOG_ID); } }; mPickNowListener = new View.OnClickListener() { public void onClick(View v) { resetTimestamp(); } }; mValueViewListener = new View.OnKeyListener() { public boolean onKey(View v, int keyCode, KeyEvent event) { updateValueMarker(); return false; } }; mDateSetListener = new DatePickerDialog.OnDateSetListener() { public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { mPickerTimestamp.mYear = year; mPickerTimestamp.mMonth = monthOfYear; mPickerTimestamp.mDay = dayOfMonth; updateDisplay(); } }; mTimeSetListener = new TimePickerDialog.OnTimeSetListener() { public void onTimeSet(TimePicker view, int hourOfDay, int minute) { mPickerTimestamp.mHour = hourOfDay; mPickerTimestamp.mMinute = minute; mPickerTimestamp.mSecond = 0; updateDisplay(); } }; mOkListener = new View.OnClickListener() { public void onClick(View view) { mSave = true; setResult(RESULT_OK); finish(); } }; mDeleteListener = new View.OnClickListener() { public void onClick(View view) { getDbh().deleteEntry(mRowId); TimeSeriesCollector tsc = new TimeSeriesCollector(getDbh()); tsc.setHistory(mHistory); tsc.setSmoothing(mSmoothing); tsc.setSmoothing(mSensitivity); tsc.setInterpolators(((EvenTrendActivity) getCtx()).getInterpolators()); tsc.updateTimeSeriesMetaLocking(true); tsc.updateCategoryTrend(mCategoryId); setResult(RESULT_OK); getDbh().close(); finish(); } }; } public void setupMenu() { Cursor c = getDbh().fetchAllCategories(); c.moveToFirst(); for (int i = 0; i < c.getCount(); i++) { long catId = CategoryDbTable.getId(c); String label = CategoryDbTable.getCategoryName(c); mCategoryMenu.addSpinnerItem(label, catId); if (mCategoryId == catId) { mCategoryMenu.setSelection(i); } c.moveToNext(); } c.close(); } @Override protected Dialog onCreateDialog(int id) { switch (id) { case TIME_DIALOG_ID: return new TimePickerDialog(this, mTimeSetListener, mPickerTimestamp.mHour, mPickerTimestamp.mMinute, false); case DATE_DIALOG_ID: return new DatePickerDialog(this, mDateSetListener, mPickerTimestamp.mYear, mPickerTimestamp.mMonth, mPickerTimestamp.mDay); } return null; } @Override protected void onPrepareDialog(int id, Dialog dialog) { switch (id) { case TIME_DIALOG_ID: ((TimePickerDialog) dialog).updateTime(mPickerTimestamp.mHour, mPickerTimestamp.mMinute); break; case DATE_DIALOG_ID: ((DatePickerDialog) dialog).updateDate(mPickerTimestamp.mYear, mPickerTimestamp.mMonth, mPickerTimestamp.mDay); break; } } private void saveOriginalValues() { mOriginalTimestamp.mMillis = mPickerTimestamp.mMillis; mCal.setTimeInMillis(mOriginalTimestamp.mMillis); mOriginalTimestamp.setTo(mCal); mPickerTimestamp.setTo(mCal); mOriginalCategoryId = mCategoryId; mOriginalValue = mValue; } public void setTimestamp() { mCal.setTimeInMillis(mPickerTimestamp.mMillis); mPickerTimestamp.setTo(mCal); updateDisplay(); } public void resetTimestamp() { mCal.setTimeInMillis(System.currentTimeMillis()); mPickerTimestamp.setTo(mCal); updateDisplay(); } private void updateValueMarker() { String s = mValueView.getText().toString(); if (s.equals("")) { mValueChanged.setText("*"); mOk.setClickable(false); mOk.setTextColor(Color.LTGRAY); return; } float value = Float.valueOf(s).floatValue(); if (value != mOriginalValue) { mValueChanged.setText("*"); } else { mValueChanged.setText(""); } mOk.setClickable(true); mOk.setTextColor(Color.BLACK); } private void updateCategoryMarker() { if (mCategoryId != mOriginalCategoryId) { mCategoryChanged.setText("*"); } else { mCategoryChanged.setText(""); } } private void updateTimestampMarker() { if (mPickerTimestamp.isEqual(mOriginalTimestamp)) { mTimestampChangedView.setText(""); mTimestampChanged = false; } else { mTimestampChangedView.setText("*"); mTimestampChanged = true; } } private void updateDisplay() { mCal.set(Calendar.YEAR, mPickerTimestamp.mYear); mCal.set(Calendar.MONTH, mPickerTimestamp.mMonth); mCal.set(Calendar.DAY_OF_MONTH, mPickerTimestamp.mDay); mCal.set(Calendar.HOUR_OF_DAY, mPickerTimestamp.mHour); mCal.set(Calendar.MINUTE, mPickerTimestamp.mMinute); mCal.set(Calendar.SECOND, mPickerTimestamp.mSecond); mPickerTimestamp.setTo(mCal); mTimestampView.setText(DateUtil.toTimestamp(mCal)); updateCategoryMarker(); updateValueMarker(); updateTimestampMarker(); } private void populateFields(EntryDbTable.Row entry) { if (mRowId != null) { if (entry == null) mEntry = getDbh().fetchEntry(mRowId); else mEntry = entry; mCategoryId = mEntry.getCategoryId(); mValue = mEntry.getValue(); mPickerTimestamp.mMillis = mEntry.getTimestamp(); mAggregation = mEntry.getNEntries(); mValueView.setText(String.valueOf(mValue)); mTimestampView.setText(DateUtil.toTimestamp(mPickerTimestamp.mMillis)); mAggregationView.setText(Integer.valueOf(mAggregation).toString()); } } @Override protected void onSaveInstanceState(Bundle outState) { if (mRowId != null) outState.putLong(CategoryDbTable.KEY_ROWID, mRowId); else outState.putLong(CategoryDbTable.KEY_ROWID, -1); super.onSaveInstanceState(outState); } @Override protected void onPause() { super.onPause(); saveState(); } @Override protected void onResume() { super.onResume(); setupPrefs(); populateFields(null); } private void saveState() { if (mSave == true) { EntryDbTable.Row entry = new EntryDbTable.Row(); entry.setId(mRowId); entry.setCategoryId(mCategoryId); entry.setValue(Float.valueOf(mValueView.getText().toString()) .floatValue()); entry.setTimestamp(mPickerTimestamp.mMillis); if (mRowId != null) { CategoryDbTable.Row cat = getDbh().fetchCategory(mCategoryId); if (mTimestampChanged == true && cat != null) { EntryDbTable.Row other = getDbh().fetchCategoryEntryInPeriod( cat.getId(), cat.getPeriodMs(), entry.getTimestamp()); if (other != null) { other.setValue(other.getValue() + entry.getValue()); other.setNEntries(other.getNEntries() + entry.getNEntries()); getDbh().updateEntry(other); getDbh().deleteEntry(entry.getId()); if (cat != null) { TimeSeriesCollector tsc = new TimeSeriesCollector(getDbh()); tsc.setHistory(mHistory); tsc.setSmoothing(mSmoothing); tsc.setSensitivity(mSensitivity); tsc.setInterpolators(((EvenTrendActivity) getCtx()) .getInterpolators()); tsc.updateTimeSeriesMetaLocking(true); tsc.updateCategoryTrend(mCategoryId); } return; } } getDbh().updateEntry(entry); if (cat != null) { TimeSeriesCollector tsc = new TimeSeriesCollector(getDbh()); tsc.setHistory(mHistory); tsc.setSmoothing(mSmoothing); tsc.setSensitivity(mSensitivity); tsc.setInterpolators(((EvenTrendActivity) getCtx()) .getInterpolators()); tsc.updateTimeSeriesMetaLocking(true); tsc.updateCategoryTrend(mCategoryId); } } } } }