mirror of https://github.com/tasks/tasks
1.9 beta release:
- added tabbed interface for editor - added ability to set fixed-time notifications - fixed some crashespull/14/head
parent
8c3aaab57e
commit
b78e5aa309
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2008 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.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Button android:id="@+id/date"
|
||||
android:layout_weight="0.45"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<Button android:id="@+id/time"
|
||||
android:layout_weight="0.45"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<ImageButton android:id="@+id/button1"
|
||||
style="?android:attr/buttonStyleInset"
|
||||
android:src="@android:drawable/ic_delete"
|
||||
android:layout_weight="0.1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_marginTop="2dip"
|
||||
android:layout_marginRight="2dip"
|
||||
android:layout_marginBottom="2dip"
|
||||
android:gravity="center_vertical"
|
||||
/>
|
||||
</LinearLayout>
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* ASTRID: Android's Simple Task Recording Dashboard
|
||||
*
|
||||
* Copyright (c) 2009 Tim Su
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
package com.timsu.astrid.activities;
|
||||
|
||||
import android.app.TabActivity;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.timsu.astrid.R;
|
||||
import com.timsu.astrid.data.task.AbstractTaskModel;
|
||||
import com.timsu.astrid.data.task.TaskController;
|
||||
import com.timsu.astrid.data.task.TaskIdentifier;
|
||||
import com.timsu.astrid.utilities.DialogUtilities;
|
||||
|
||||
/** Hack hack for tabbed activity. Should provide better interaction
|
||||
*
|
||||
* @author timsu
|
||||
*/
|
||||
public abstract class TaskModificationTabbedActivity<MODEL_TYPE extends
|
||||
AbstractTaskModel> extends TabActivity {
|
||||
protected static final String LOAD_INSTANCE_TOKEN = TaskModificationActivity.LOAD_INSTANCE_TOKEN;
|
||||
protected TaskController controller;
|
||||
protected MODEL_TYPE model;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
controller = new TaskController(this);
|
||||
controller.open();
|
||||
|
||||
try {
|
||||
// check if we have a TaskIdentifier
|
||||
TaskIdentifier identifier = null;
|
||||
Bundle extras = getIntent().getExtras();
|
||||
if(savedInstanceState != null && savedInstanceState.containsKey(LOAD_INSTANCE_TOKEN)) {
|
||||
identifier = new TaskIdentifier(savedInstanceState.getLong(
|
||||
LOAD_INSTANCE_TOKEN));
|
||||
} else if(extras != null && extras.containsKey(LOAD_INSTANCE_TOKEN))
|
||||
identifier = new TaskIdentifier(extras.getLong(
|
||||
LOAD_INSTANCE_TOKEN));
|
||||
|
||||
model = getModel(identifier);
|
||||
} catch (Exception e) {
|
||||
showErrorAndFinish(R.string.error_opening, e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void showErrorAndFinish(int prefix, Throwable e) {
|
||||
Resources r = getResources();
|
||||
DialogUtilities.okDialog(this,
|
||||
r.getString(prefix) + " " +
|
||||
e.getLocalizedMessage(), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
abstract protected MODEL_TYPE getModel(TaskIdentifier identifier);
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
controller.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
if(model.getTaskIdentifier() != null)
|
||||
outState.putLong(LOAD_INSTANCE_TOKEN, model.getTaskIdentifier().getId());
|
||||
}
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* ASTRID: Android's Simple Task Recording Dashboard
|
||||
*
|
||||
* Copyright (c) 2009 Tim Su
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
package com.timsu.astrid.data.alerts;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.util.Log;
|
||||
|
||||
import com.timsu.astrid.data.AbstractController;
|
||||
import com.timsu.astrid.data.AbstractModel;
|
||||
import com.timsu.astrid.data.task.TaskIdentifier;
|
||||
|
||||
|
||||
/** A single tag on a task */
|
||||
public class Alert extends AbstractModel {
|
||||
|
||||
/** Version number of this model */
|
||||
static final int VERSION = 1;
|
||||
|
||||
// field names
|
||||
|
||||
static final String TASK = "task";
|
||||
static final String DATE = "date";
|
||||
|
||||
/** Default values container */
|
||||
private static final ContentValues defaultValues = new ContentValues();
|
||||
|
||||
@Override
|
||||
public ContentValues getDefaultValues() {
|
||||
return defaultValues;
|
||||
}
|
||||
|
||||
static String[] FIELD_LIST = new String[] {
|
||||
AbstractController.KEY_ROWID,
|
||||
TASK,
|
||||
DATE,
|
||||
};
|
||||
|
||||
// --- database helper
|
||||
|
||||
/** Database Helper manages creating new tables and updating old ones */
|
||||
static class AlertDatabaseHelper extends SQLiteOpenHelper {
|
||||
String tableName;
|
||||
|
||||
AlertDatabaseHelper(Context context, String databaseName, String tableName) {
|
||||
super(context, databaseName, null, VERSION);
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
String sql = new StringBuilder().
|
||||
append("CREATE TABLE ").append(tableName).append(" (").
|
||||
append(AbstractController.KEY_ROWID).append(" integer primary key autoincrement, ").
|
||||
append(TASK).append(" integer not null,").
|
||||
append(DATE).append(" integer not null,").
|
||||
append("unique (").append(TASK).append(",").append(DATE).append(")").
|
||||
append(");").toString();
|
||||
db.execSQL(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
Log.w(getClass().getSimpleName(), "Upgrading database from version " +
|
||||
oldVersion + " to " + newVersion + ".");
|
||||
|
||||
switch(oldVersion) {
|
||||
default:
|
||||
// we don't know how to handle it... do the unfortunate thing
|
||||
Log.e(getClass().getSimpleName(), "Unsupported migration, table dropped!");
|
||||
db.execSQL("DROP TABLE IF EXISTS " + tableName);
|
||||
onCreate(db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --- constructor pass-through
|
||||
|
||||
Alert(TaskIdentifier task, Date date) {
|
||||
super();
|
||||
setTask(task);
|
||||
setDate(date);
|
||||
}
|
||||
|
||||
public Alert(Cursor cursor) {
|
||||
super(cursor);
|
||||
}
|
||||
|
||||
// --- getters and setters: expose them as you see fit
|
||||
|
||||
public boolean isNew() {
|
||||
return getCursor() == null;
|
||||
}
|
||||
|
||||
public TaskIdentifier getTask() {
|
||||
return new TaskIdentifier(retrieveInteger(TASK));
|
||||
}
|
||||
|
||||
public Date getDate() {
|
||||
return new Date(retrieveLong(DATE));
|
||||
}
|
||||
|
||||
private void setTask(TaskIdentifier task) {
|
||||
setValues.put(TASK, task.getId());
|
||||
}
|
||||
|
||||
private void setDate(Date date) {
|
||||
setValues.put(DATE, date.getTime());
|
||||
}
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* ASTRID: Android's Simple Task Recording Dashboard
|
||||
*
|
||||
* Copyright (c) 2009 Tim Su
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
package com.timsu.astrid.data.alerts;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.SQLException;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
||||
import com.timsu.astrid.data.AbstractController;
|
||||
import com.timsu.astrid.data.alerts.Alert.AlertDatabaseHelper;
|
||||
import com.timsu.astrid.data.task.TaskIdentifier;
|
||||
|
||||
/** Controller for Tag-related operations */
|
||||
public class AlertController extends AbstractController {
|
||||
|
||||
private SQLiteDatabase alertDatabase;
|
||||
|
||||
/** Get a cursor to tag identifiers */
|
||||
public Cursor getTaskAlertsCursor(TaskIdentifier taskId) throws SQLException {
|
||||
Cursor cursor = alertDatabase.query(ALERT_TABLE_NAME,
|
||||
Alert.FIELD_LIST, Alert.TASK + " = ?",
|
||||
new String[] { taskId.idAsString() }, null, null, null);
|
||||
return cursor;
|
||||
}
|
||||
/** Get a list of tag identifiers for the given task */
|
||||
public List<Date> getTaskAlerts(Activity activity, TaskIdentifier
|
||||
taskId) throws SQLException {
|
||||
List<Date> list = new LinkedList<Date>();
|
||||
Cursor cursor = alertDatabase.query(ALERT_TABLE_NAME,
|
||||
Alert.FIELD_LIST, Alert.TASK + " = ?",
|
||||
new String[] { taskId.idAsString() }, null, null, null);
|
||||
activity.startManagingCursor(cursor);
|
||||
|
||||
if(cursor.getCount() == 0)
|
||||
return list;
|
||||
do {
|
||||
cursor.moveToNext();
|
||||
list.add(new Alert(cursor).getDate());
|
||||
} while(!cursor.isLast());
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/** Remove all alerts from the task */
|
||||
public boolean removeAlerts(TaskIdentifier taskId)
|
||||
throws SQLException{
|
||||
return alertDatabase.delete(ALERT_TABLE_NAME,
|
||||
String.format("%s = ?",
|
||||
Alert.TASK),
|
||||
new String[] { taskId.idAsString() }) > 0;
|
||||
}
|
||||
|
||||
/** Add the given tag to the task */
|
||||
public boolean addAlert(TaskIdentifier taskId, Date date)
|
||||
throws SQLException {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(Alert.DATE, date.getTime());
|
||||
values.put(Alert.TASK, taskId.getId());
|
||||
return alertDatabase.insert(ALERT_TABLE_NAME, Alert.TASK,
|
||||
values) >= 0;
|
||||
}
|
||||
|
||||
// --- boilerplate
|
||||
|
||||
/**
|
||||
* Constructor - takes the context to allow the database to be
|
||||
* opened/created
|
||||
*/
|
||||
public AlertController(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the notes database. If it cannot be opened, try to create a new
|
||||
* instance of the database. If it cannot be created, throw an exception to
|
||||
* signal the failure
|
||||
*
|
||||
* @return this (self reference, allowing this to be chained in an
|
||||
* initialization call)
|
||||
* @throws SQLException if the database could be neither opened or created
|
||||
*/
|
||||
public AlertController open() throws SQLException {
|
||||
alertDatabase = new AlertDatabaseHelper(context,
|
||||
ALERT_TABLE_NAME, ALERT_TABLE_NAME).getWritableDatabase();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Closes database resource */
|
||||
public void close() {
|
||||
alertDatabase.close();
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package com.timsu.astrid.data.task;
|
||||
|
||||
public class VisibilityProperty {
|
||||
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* ASTRID: Android's Simple Task Recording Dashboard
|
||||
*
|
||||
* Copyright (c) 2009 Tim Su
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
package com.timsu.astrid.widget;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
|
||||
/** Date Control Set with an "enabled" checkbox" to toggle date / null */
|
||||
public class DateWithNullControlSet extends DateControlSet {
|
||||
|
||||
private CheckBox activatedCheckBox;
|
||||
|
||||
public DateWithNullControlSet(Activity activity, int checkBoxId, int dateButtonId, int timeButtonId) {
|
||||
super(activity);
|
||||
activatedCheckBox = (CheckBox)activity.findViewById(checkBoxId);
|
||||
dateButton = (Button)activity.findViewById(dateButtonId);
|
||||
timeButton = (Button)activity.findViewById(timeButtonId);
|
||||
|
||||
activatedCheckBox.setOnCheckedChangeListener(
|
||||
new OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView,
|
||||
boolean isChecked) {
|
||||
dateButton.setEnabled(isChecked);
|
||||
timeButton.setEnabled(isChecked);
|
||||
}
|
||||
});
|
||||
dateButton.setOnClickListener(this);
|
||||
timeButton.setOnClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getDate() {
|
||||
if(!activatedCheckBox.isChecked())
|
||||
return null;
|
||||
return super.getDate();
|
||||
}
|
||||
|
||||
/** Initialize the components for the given date field */
|
||||
@Override
|
||||
public void setDate(Date newDate) {
|
||||
activatedCheckBox.setChecked(newDate != null);
|
||||
dateButton.setEnabled(newDate != null);
|
||||
timeButton.setEnabled(newDate != null);
|
||||
|
||||
super.setDate(newDate);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue