mirror of https://github.com/tasks/tasks
merged dummy-conflicts from git
commit
e5c677412e
Binary file not shown.
@ -0,0 +1,42 @@
|
||||
package com.todoroo.andlib.widget;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.gesture.Gesture;
|
||||
import android.gesture.GestureLibraries;
|
||||
import android.gesture.GestureLibrary;
|
||||
import android.gesture.GestureOverlayView;
|
||||
import android.gesture.Prediction;
|
||||
import android.gesture.GestureOverlayView.OnGesturePerformedListener;
|
||||
|
||||
import com.todoroo.andlib.widget.GestureService.GestureInterface;
|
||||
|
||||
public class Api4GestureDetector implements OnGesturePerformedListener {
|
||||
private final GestureLibrary mLibrary;
|
||||
private final GestureInterface listener;
|
||||
|
||||
public Api4GestureDetector(Activity activity, int view, int gestureLibrary, GestureInterface listener) {
|
||||
this.listener = listener;
|
||||
mLibrary = GestureLibraries.fromRawResource(activity, gestureLibrary);
|
||||
|
||||
if(mLibrary.load()) {
|
||||
GestureOverlayView gestures = (GestureOverlayView) activity.findViewById(view);
|
||||
gestures.addOnGesturePerformedListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
|
||||
ArrayList<Prediction> predictions = mLibrary.recognize(gesture);
|
||||
|
||||
// We want at least one prediction
|
||||
if (predictions.size() > 0) {
|
||||
Prediction prediction = predictions.get(0);
|
||||
// We want at least some confidence in the result
|
||||
if (prediction.score > 1.0) {
|
||||
listener.gesturePerformed(prediction.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
package com.todoroo.andlib.widget;
|
||||
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import com.todoroo.andlib.utility.AndroidUtilities;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* All API versions-friendly gesture detector. On SDK < 4, nothing happens
|
||||
* @author Tim Su <tim@todoroo.com>
|
||||
*
|
||||
*/
|
||||
public class GestureService {
|
||||
|
||||
public interface GestureInterface {
|
||||
public void gesturePerformed(String gesture);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register gesture detector. If android SDK version is not correct,
|
||||
* a {@link VerifyError} will be throw. Catch this explicitly.
|
||||
*
|
||||
* @param activity
|
||||
* @param view
|
||||
* @param gestureLibrary
|
||||
* @param listener
|
||||
* @throws VerifyError
|
||||
*/
|
||||
public static void registerGestureDetector(Activity activity, int view,
|
||||
int gestureLibrary, GestureInterface listener) throws VerifyError {
|
||||
if(AndroidUtilities.getSdkVersion() > 3)
|
||||
new Api4GestureDetector(activity, view, gestureLibrary, listener);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,111 +1,34 @@
|
||||
/**
|
||||
* See the file "LICENSE" for the full license governing this code.
|
||||
*/
|
||||
package com.todoroo.astrid.alarms;
|
||||
|
||||
|
||||
import android.content.ContentValues;
|
||||
|
||||
import com.todoroo.andlib.data.AbstractModel;
|
||||
import com.todoroo.andlib.data.Property;
|
||||
import com.todoroo.andlib.data.Property.IntegerProperty;
|
||||
import com.todoroo.andlib.data.Property.LongProperty;
|
||||
import com.todoroo.andlib.data.Property.StringProperty;
|
||||
import com.todoroo.andlib.data.Table;
|
||||
import com.todoroo.andlib.data.TodorooCursor;
|
||||
import com.todoroo.astrid.model.Task;
|
||||
import com.todoroo.astrid.model.Metadata;
|
||||
|
||||
/**
|
||||
* Data Model which represents an alarm
|
||||
* Metadata entry for a task alarm
|
||||
*
|
||||
* @author Tim Su <tim@todoroo.com>
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("nls")
|
||||
public class Alarm extends AbstractModel {
|
||||
|
||||
// --- table
|
||||
|
||||
public static final Table TABLE = new Table("alarm", Alarm.class);
|
||||
public class Alarm {
|
||||
|
||||
// --- properties
|
||||
/** metadata key */
|
||||
public static final String METADATA_KEY = "alarm"; //$NON-NLS-1$
|
||||
|
||||
/** ID */
|
||||
public static final LongProperty ID = new LongProperty(
|
||||
TABLE, ID_PROPERTY_NAME);
|
||||
/** time of alarm */
|
||||
public static final LongProperty TIME = new LongProperty(Metadata.TABLE,
|
||||
Metadata.VALUE1.name);
|
||||
|
||||
/** Associated Task */
|
||||
public static final LongProperty TASK = new LongProperty(
|
||||
TABLE, "task");
|
||||
|
||||
/** Alarm Time */
|
||||
public static final LongProperty TIME = new LongProperty(
|
||||
TABLE, "time");
|
||||
|
||||
/** Alarm Type (see constants) */
|
||||
public static final IntegerProperty TYPE = new IntegerProperty(
|
||||
TABLE, "type");
|
||||
|
||||
/** Alarm Ringtone */
|
||||
public static final StringProperty RINGTONE = new StringProperty(
|
||||
TABLE, "ringtone");
|
||||
|
||||
/** List of all properties for this model */
|
||||
public static final Property<?>[] PROPERTIES = generateProperties(Alarm.class);
|
||||
/** alarm type */
|
||||
public static final IntegerProperty TYPE = new IntegerProperty(Metadata.TABLE,
|
||||
Metadata.VALUE2.name);
|
||||
|
||||
// --- constants
|
||||
|
||||
/** this alarm was already triggered */
|
||||
public static final int TYPE_TRIGGERED = 0;
|
||||
|
||||
/** this alarm is single-shot */
|
||||
public static final int TYPE_SINGLE = 1;
|
||||
|
||||
/** this alarm repeats itself until turned off */
|
||||
public static final int TYPE_REPEATING = 2;
|
||||
|
||||
// --- defaults
|
||||
|
||||
/** Default values container */
|
||||
private static final ContentValues defaultValues = new ContentValues();
|
||||
|
||||
static {
|
||||
defaultValues.put(TYPE.name, TYPE_SINGLE);
|
||||
defaultValues.put(RINGTONE.name, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentValues getDefaultValues() {
|
||||
return defaultValues;
|
||||
}
|
||||
|
||||
// --- data access boilerplate
|
||||
|
||||
public Alarm() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Alarm(TodorooCursor<Alarm> cursor) {
|
||||
this();
|
||||
readPropertiesFromCursor(cursor);
|
||||
}
|
||||
|
||||
public void readFromCursor(TodorooCursor<Alarm> cursor) {
|
||||
super.readPropertiesFromCursor(cursor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return getIdHelper(ID);
|
||||
};
|
||||
|
||||
// --- parcelable helpers
|
||||
|
||||
private static final Creator<Task> CREATOR = new ModelCreator<Task>(Task.class);
|
||||
|
||||
@Override
|
||||
protected Creator<? extends AbstractModel> getCreator() {
|
||||
return CREATOR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,92 @@
|
||||
package com.todoroo.astrid.alarms;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashSet;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.timsu.astrid.R;
|
||||
import com.todoroo.andlib.data.TodorooCursor;
|
||||
import com.todoroo.andlib.widget.DateControlSet;
|
||||
import com.todoroo.astrid.activity.TaskEditActivity.TaskEditControlSet;
|
||||
import com.todoroo.astrid.model.Metadata;
|
||||
import com.todoroo.astrid.model.Task;
|
||||
|
||||
/**
|
||||
* Control set to manage adding and removing tags
|
||||
*
|
||||
* @author Tim Su <tim@todoroo.com>
|
||||
*
|
||||
*/
|
||||
public final class AlarmControlSet implements TaskEditControlSet {
|
||||
|
||||
// --- instance variables
|
||||
|
||||
private final LinearLayout alertsContainer;
|
||||
private final Activity activity;
|
||||
|
||||
public AlarmControlSet(Activity activity, ViewGroup parent) {
|
||||
View v = LayoutInflater.from(activity).inflate(R.layout.alarm_control, parent, true);
|
||||
|
||||
this.activity = activity;
|
||||
this.alertsContainer = (LinearLayout) v.findViewById(R.id.alert_container);
|
||||
v.findViewById(R.id.alarms_add).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
addAlarm(new Date());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromTask(Task task) {
|
||||
alertsContainer.removeAllViews();
|
||||
TodorooCursor<Metadata> cursor = AlarmService.getInstance().getAlarms(task.getId());
|
||||
try {
|
||||
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext())
|
||||
addAlarm(new Date(cursor.get(Alarm.TIME)));
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToModel(Task task) {
|
||||
LinkedHashSet<Long> alarms = new LinkedHashSet<Long>();
|
||||
for(int i = 0; i < alertsContainer.getChildCount(); i++) {
|
||||
DateControlSet set = (DateControlSet) alertsContainer.getChildAt(i).getTag();
|
||||
if(set == null)
|
||||
continue;
|
||||
Date date = set.getDate();
|
||||
if(date != null)
|
||||
alarms.add(set.getDate().getTime());
|
||||
}
|
||||
AlarmService.getInstance().synchronizeAlarms(task.getId(), alarms);
|
||||
}
|
||||
|
||||
private boolean addAlarm(Date alert) {
|
||||
final View alertItem = LayoutInflater.from(activity).inflate(R.layout.alarm_edit_row, null);
|
||||
alertsContainer.addView(alertItem);
|
||||
|
||||
DateControlSet dcs = new DateControlSet(activity, (Button)alertItem.findViewById(R.id.date),
|
||||
(Button)alertItem.findViewById(R.id.time));
|
||||
dcs.setDate(alert);
|
||||
alertItem.setTag(dcs);
|
||||
|
||||
ImageButton reminderRemoveButton;
|
||||
reminderRemoveButton = (ImageButton)alertItem.findViewById(R.id.button1);
|
||||
reminderRemoveButton.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
alertsContainer.removeView(alertItem);
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,79 @@
|
||||
/**
|
||||
* See the file "LICENSE" for the full license governing this code.
|
||||
*/
|
||||
package com.todoroo.astrid.alarms;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.text.format.DateUtils;
|
||||
|
||||
import com.timsu.astrid.R;
|
||||
import com.todoroo.andlib.data.TodorooCursor;
|
||||
import com.todoroo.andlib.utility.DateUtilities;
|
||||
import com.todoroo.astrid.api.AstridApiConstants;
|
||||
import com.todoroo.astrid.api.DetailExposer;
|
||||
import com.todoroo.astrid.model.Metadata;
|
||||
|
||||
/**
|
||||
* Exposes Task Detail for tags, i.e. "Tags: frogs, animals"
|
||||
*
|
||||
* @author Tim Su <tim@todoroo.com>
|
||||
*
|
||||
*/
|
||||
public class AlarmDetailExposer extends BroadcastReceiver implements DetailExposer {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
// get tags associated with this task
|
||||
long taskId = intent.getLongExtra(AstridApiConstants.EXTRAS_TASK_ID, -1);
|
||||
if(taskId == -1)
|
||||
return;
|
||||
|
||||
boolean extended = intent.getBooleanExtra(AstridApiConstants.EXTRAS_EXTENDED, false);
|
||||
String taskDetail = getTaskDetails(context, taskId, extended);
|
||||
if(taskDetail == null)
|
||||
return;
|
||||
|
||||
// transmit
|
||||
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_DETAILS);
|
||||
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, AlarmService.IDENTIFIER);
|
||||
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, taskDetail);
|
||||
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_EXTENDED, extended);
|
||||
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId);
|
||||
context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTaskDetails(Context context, long id, boolean extended) {
|
||||
if(extended)
|
||||
return null;
|
||||
|
||||
TodorooCursor<Metadata> cursor = AlarmService.getInstance().getAlarms(id);
|
||||
long nextTime = -1;
|
||||
try {
|
||||
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
|
||||
long time = cursor.get(Alarm.TIME);
|
||||
if(time > DateUtilities.now()) {
|
||||
nextTime = time;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(nextTime == -1)
|
||||
return null;
|
||||
CharSequence durationString = DateUtils.getRelativeDateTimeString(context,
|
||||
nextTime, DateUtils.MINUTE_IN_MILLIS, DateUtils.WEEK_IN_MILLIS,
|
||||
DateUtils.FORMAT_ABBREV_ALL);
|
||||
return context.getString(R.string.alarm_ADE_detail, durationString);
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPluginIdentifier() {
|
||||
return AlarmService.IDENTIFIER;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
package com.todoroo.astrid.alarms;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import com.todoroo.andlib.data.TodorooCursor;
|
||||
import com.todoroo.andlib.utility.DateUtilities;
|
||||
import com.todoroo.astrid.api.AstridApiConstants;
|
||||
import com.todoroo.astrid.model.Metadata;
|
||||
|
||||
public class AlarmTaskRepeatListener extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
long taskId = intent.getLongExtra(AstridApiConstants.EXTRAS_TASK_ID, -1);
|
||||
if(taskId == -1)
|
||||
return;
|
||||
|
||||
long oldDueDate = intent.getLongExtra(AstridApiConstants.EXTRAS_OLD_DUE_DATE, 0);
|
||||
if(oldDueDate == 0)
|
||||
oldDueDate = DateUtilities.now();
|
||||
long newDueDate = intent.getLongExtra(AstridApiConstants.EXTRAS_NEW_DUE_DATE, -1);
|
||||
if(newDueDate <= 0 || newDueDate <= oldDueDate)
|
||||
return;
|
||||
|
||||
TodorooCursor<Metadata> cursor = AlarmService.getInstance().getAlarms(taskId);
|
||||
try {
|
||||
if(cursor.getCount() == 0)
|
||||
return;
|
||||
|
||||
Metadata metadata = new Metadata();
|
||||
LinkedHashSet<Long> alarms = new LinkedHashSet<Long>(cursor.getCount());
|
||||
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
|
||||
metadata.readFromCursor(cursor);
|
||||
alarms.add(metadata.getValue(Alarm.TIME) + (newDueDate - oldDueDate));
|
||||
}
|
||||
AlarmService.getInstance().synchronizeAlarms(taskId, alarms);
|
||||
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 231 B |
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- See the file "LICENSE" for the full license governing this code. -->
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<TextView android:id="@+id/alarms_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/alarm_ACS_label"
|
||||
style="@style/TextAppearance.GEN_EditLabel" />
|
||||
|
||||
<LinearLayout android:id="@+id/alert_container"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
</LinearLayout>
|
||||
|
||||
<Button android:id="@+id/alarms_add"
|
||||
android:text="@string/alarm_ACS_button"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</merge>
|
||||
|
||||
@ -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.7"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<Button android:id="@+id/time"
|
||||
android:layout_weight="1"
|
||||
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_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>
|
||||
@ -1,32 +1,103 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical" android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/pdv_body">
|
||||
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" style="@style/TextAppearance.GEN_EditLabel"
|
||||
android:text="@string/producteev_PPr_header" />
|
||||
<ImageView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="5dip"
|
||||
android:paddingBottom="5dip"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/pdv_logo" />
|
||||
|
||||
<LinearLayout android:orientation="horizontal"
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:paddingBottom="10dip"
|
||||
android:textSize="16sp"
|
||||
android:textColor="#ffffff"
|
||||
android:text="@string/producteev_PLA_body" />
|
||||
|
||||
<TextView android:id="@+id/error"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingBottom="20dip"
|
||||
android:textColor="#ff0000"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
android:visibility="gone" />
|
||||
|
||||
<EditText android:id="@+id/email"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:hint="@string/producteev_PLA_email"
|
||||
android:contentDescription="E-Mail with which you registered to Producteev-service"
|
||||
android:inputType="textEmailAddress"/>
|
||||
|
||||
<EditText android:id="@+id/password"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:contentDescription="Password for your Producteev account"
|
||||
android:hint="@string/producteev_PLA_password"
|
||||
android:inputType="textPassword"/>
|
||||
|
||||
<LinearLayout android:id="@+id/newUserLayout"
|
||||
android:layout_width="fill_parent" android:layout_height="wrap_content"
|
||||
android:paddingTop="5dip" android:baselineAligned="false">
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="20dip"
|
||||
android:visibility="gone">
|
||||
|
||||
<EditText android:id="@+id/confirmPassword"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:hint="@string/producteev_PLA_confirmPassword"
|
||||
android:inputType="textPassword"/>
|
||||
|
||||
<EditText android:id="@+id/firstName"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:hint="@string/producteev_PLA_firstName"
|
||||
android:inputType="textPersonName"/>
|
||||
|
||||
<Button android:id="@+id/done" android:layout_width="fill_parent"
|
||||
<EditText android:id="@+id/lastName"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:hint="@string/producteev_PLA_lastName"
|
||||
android:inputType="textPersonName"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="5dip"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<Button android:id="@+id/signIn" android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content" android:layout_weight="1"
|
||||
android:text="@string/DLG_done" />
|
||||
android:text="@string/producteev_PLA_signIn" />
|
||||
|
||||
<Button android:id="@+id/cancel" android:layout_width="fill_parent"
|
||||
<Button android:id="@+id/createNew" android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content" android:layout_weight="1"
|
||||
android:text="@android:string/cancel" />
|
||||
android:text="@string/producteev_PLA_createNew" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<EditText android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent" android:hint="E-Mail"
|
||||
android:contentDescription="E-Mail with which you registered to Producteev-service"
|
||||
android:id="@+id/Poducteev_EMail_EditText" android:inputType="textEmailAddress"></EditText>
|
||||
<EditText android:layout_height="wrap_content"
|
||||
android:id="@+id/Producteev_Password_EditText"
|
||||
android:contentDescription="Password for your Producteev account"
|
||||
android:hint="Password" android:layout_width="fill_parent"
|
||||
android:inputType="textPassword"></EditText>
|
||||
|
||||
<TextView android:id="@+id/terms"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:paddingTop="10dip"
|
||||
android:textSize="16sp"
|
||||
android:textColor="#0000ff"
|
||||
android:linksClickable="true"
|
||||
android:text="@string/producteev_PLA_terms" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- See the file "LICENSE" for the full license governing this code. -->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/taskListParent"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:background="@drawable/background_gradient"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- Header -->
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
android:background="@drawable/edit_header">
|
||||
|
||||
<!-- Back Button -->
|
||||
<ImageView android:id="@+id/back"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1"
|
||||
android:src="@drawable/tango_previous"
|
||||
android:paddingLeft="5dip"
|
||||
android:paddingRight="8dip"/>
|
||||
|
||||
<!-- List Label -->
|
||||
<TextView android:id="@+id/listLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="100"
|
||||
android:singleLine="true"
|
||||
android:paddingTop="6dip"
|
||||
android:paddingRight="50dip"
|
||||
style="@style/TextAppearance.TLA_Header"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="100">
|
||||
|
||||
<!-- No Tasks label -->
|
||||
<TextView android:id="@android:id/empty"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:visibility="gone"
|
||||
android:text="@string/TLA_no_items"
|
||||
style="@style/TextAppearance.TLA_NoItems"/>
|
||||
|
||||
<!-- Task List -->
|
||||
<ListView android:id="@android:id/list"
|
||||
android:scrollbars="vertical"
|
||||
android:cacheColorHint="#00000000"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<!-- Footer -->
|
||||
<LinearLayout
|
||||
android:id="@+id/taskListFooter"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<!-- Quick Add Button -->
|
||||
<ImageButton android:id="@+id/quickAddButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:visibility="gone"
|
||||
android:src="@drawable/tango_add"
|
||||
android:scaleType="fitCenter"/>
|
||||
|
||||
<!-- Quick Add Task -->
|
||||
<EditText android:id="@+id/quickAddText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="100"
|
||||
android:hint="@string/TLA_quick_add_hint"
|
||||
android:singleLine="true"
|
||||
android:autoText="true"
|
||||
android:capitalize="sentences"/>
|
||||
|
||||
<!-- Extended Add Button -->
|
||||
<ImageButton android:id="@+id/extendedAddButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:src="@drawable/tango_edit"
|
||||
android:scaleType="fitCenter"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- See the file "LICENSE" for the full license governing this code. -->
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- Resources for built-in timers plug-in -->
|
||||
|
||||
<!-- Task Edit Activity: Container Label -->
|
||||
<string name="alarm_ACS_label">Alarms</string>
|
||||
|
||||
<!-- Task Edit Activity: Add New Alarn -->
|
||||
<string name="alarm_ACS_button">Add an Alarm</string>
|
||||
|
||||
<!-- Task Detail for Alarms (%s -> time)-->
|
||||
<string name="alarm_ADE_detail">Alarm %s</string>
|
||||
|
||||
<string-array name="reminders_alarm">
|
||||
<!-- reminders related to alarm -->
|
||||
<item>Alarm!</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
@ -0,0 +1,102 @@
|
||||
/**
|
||||
* See the file "LICENSE" for the full license governing this code.
|
||||
*/
|
||||
package com.todoroo.astrid.legacy;
|
||||
|
||||
|
||||
import android.content.ContentValues;
|
||||
|
||||
import com.todoroo.andlib.data.AbstractModel;
|
||||
import com.todoroo.andlib.data.Property;
|
||||
import com.todoroo.andlib.data.Property.LongProperty;
|
||||
import com.todoroo.andlib.data.Table;
|
||||
import com.todoroo.andlib.data.TodorooCursor;
|
||||
import com.todoroo.astrid.model.Task;
|
||||
|
||||
/**
|
||||
* Data Model which represents an alarm. This is a transitional class -
|
||||
* Alarms are moved over to metadata
|
||||
*
|
||||
* @author Tim Su <tim@todoroo.com>
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("nls")
|
||||
@Deprecated
|
||||
public class TransitionalAlarm extends AbstractModel {
|
||||
|
||||
// --- table
|
||||
|
||||
public static final Table TABLE = new Table("alarm", TransitionalAlarm.class);
|
||||
|
||||
// --- properties
|
||||
|
||||
/** ID */
|
||||
public static final LongProperty ID = new LongProperty(
|
||||
TABLE, ID_PROPERTY_NAME);
|
||||
|
||||
/** Associated Task */
|
||||
public static final LongProperty TASK = new LongProperty(
|
||||
TABLE, "task");
|
||||
|
||||
/** Alarm Time */
|
||||
public static final LongProperty TIME = new LongProperty(
|
||||
TABLE, "time");
|
||||
|
||||
/** List of all properties for this model */
|
||||
public static final Property<?>[] PROPERTIES = generateProperties(TransitionalAlarm.class);
|
||||
|
||||
// --- constants
|
||||
|
||||
/** this alarm was already triggered */
|
||||
public static final int TYPE_TRIGGERED = 0;
|
||||
|
||||
/** this alarm is single-shot */
|
||||
public static final int TYPE_SINGLE = 1;
|
||||
|
||||
/** this alarm repeats itself until turned off */
|
||||
public static final int TYPE_REPEATING = 2;
|
||||
|
||||
// --- defaults
|
||||
|
||||
/** Default values container */
|
||||
private static final ContentValues defaultValues = new ContentValues();
|
||||
|
||||
static {
|
||||
//
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentValues getDefaultValues() {
|
||||
return defaultValues;
|
||||
}
|
||||
|
||||
// --- data access boilerplate
|
||||
|
||||
public TransitionalAlarm() {
|
||||
super();
|
||||
}
|
||||
|
||||
public TransitionalAlarm(TodorooCursor<TransitionalAlarm> cursor) {
|
||||
this();
|
||||
readPropertiesFromCursor(cursor);
|
||||
}
|
||||
|
||||
public void readFromCursor(TodorooCursor<TransitionalAlarm> cursor) {
|
||||
super.readPropertiesFromCursor(cursor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return getIdHelper(ID);
|
||||
};
|
||||
|
||||
// --- parcelable helpers
|
||||
|
||||
private static final Creator<Task> CREATOR = new ModelCreator<Task>(Task.class);
|
||||
|
||||
@Override
|
||||
protected Creator<? extends AbstractModel> getCreator() {
|
||||
return CREATOR;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,134 @@
|
||||
package com.todoroo.astrid.repeats;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
|
||||
import com.google.ical.values.Frequency;
|
||||
import com.google.ical.values.RRule;
|
||||
import com.google.ical.values.Weekday;
|
||||
import com.google.ical.values.WeekdayNum;
|
||||
import com.todoroo.andlib.test.TodorooTestCase;
|
||||
import com.todoroo.andlib.utility.DateUtilities;
|
||||
import com.todoroo.astrid.model.Task;
|
||||
|
||||
public class AdvancedRepeatTests extends TodorooTestCase {
|
||||
|
||||
|
||||
public static void assertDatesEqual(long date, long other) {
|
||||
assertEquals("Expected: " + new Date(date) + ", Actual: " + new Date(other),
|
||||
date, other);
|
||||
}
|
||||
|
||||
public void testDailyWithDaysOfWeek() throws ParseException {
|
||||
RRule rrule = new RRule();
|
||||
rrule.setInterval(1);
|
||||
rrule.setFreq(Frequency.DAILY);
|
||||
rrule.setByDay(Collections.singletonList(new WeekdayNum(0, Weekday.FR)));
|
||||
|
||||
Task task = new Task();
|
||||
long thursday = task.createDueDate(Task.URGENCY_SPECIFIC_DAY, new Date(113, 7, 1).getTime());
|
||||
task.setValue(Task.DUE_DATE, thursday);
|
||||
|
||||
// repeat once => due date should become friday
|
||||
long friday = thursday + DateUtilities.ONE_DAY;
|
||||
long nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());
|
||||
assertDatesEqual(friday, nextDueDate);
|
||||
|
||||
// repeat again => due date should be one week from friday
|
||||
long nextFriday = friday + DateUtilities.ONE_WEEK;
|
||||
task.setValue(Task.DUE_DATE, friday);
|
||||
nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());
|
||||
assertDatesEqual(nextFriday, nextDueDate);
|
||||
|
||||
// now try with thursday, and repeat every 2 days. expect next friday
|
||||
rrule.setInterval(2);
|
||||
task.setValue(Task.DUE_DATE, thursday);
|
||||
nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());
|
||||
assertDatesEqual(nextFriday, nextDueDate);
|
||||
|
||||
// again with friday, expect next friday
|
||||
task.setValue(Task.DUE_DATE, friday);
|
||||
nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());
|
||||
assertDatesEqual(nextFriday, nextDueDate);
|
||||
}
|
||||
|
||||
public void testMonthlyWithDaysOfWeek() throws ParseException {
|
||||
RRule rrule = new RRule();
|
||||
rrule.setInterval(1);
|
||||
rrule.setFreq(Frequency.MONTHLY);
|
||||
rrule.setByDay(Arrays.asList(new WeekdayNum[] {
|
||||
new WeekdayNum(0, Weekday.SU),
|
||||
new WeekdayNum(0, Weekday.MO),
|
||||
new WeekdayNum(0, Weekday.TU),
|
||||
new WeekdayNum(0, Weekday.WE),
|
||||
new WeekdayNum(0, Weekday.TH),
|
||||
new WeekdayNum(0, Weekday.FR),
|
||||
new WeekdayNum(0, Weekday.SA),
|
||||
}));
|
||||
|
||||
Task task = new Task();
|
||||
long thursday = task.createDueDate(Task.URGENCY_SPECIFIC_DAY, new Date(113, 7, 1).getTime());
|
||||
task.setValue(Task.DUE_DATE, thursday);
|
||||
|
||||
// repeat once => due date should become next month on the first
|
||||
long nextMonth = task.createDueDate(Task.URGENCY_SPECIFIC_DAY, new Date(113, 8, 1).getTime());
|
||||
long nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());
|
||||
assertDatesEqual(nextMonth, nextDueDate);
|
||||
|
||||
// only allow thursdays
|
||||
rrule.setByDay(Arrays.asList(new WeekdayNum[] {
|
||||
new WeekdayNum(0, Weekday.TH),
|
||||
}));
|
||||
long nextMonthOnThursday = task.createDueDate(Task.URGENCY_SPECIFIC_DAY, new Date(113, 8, 5).getTime());
|
||||
nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());
|
||||
assertDatesEqual(nextMonthOnThursday, nextDueDate);
|
||||
}
|
||||
|
||||
public void testDueDateInPast() throws ParseException {
|
||||
RRule rrule = new RRule();
|
||||
rrule.setInterval(1);
|
||||
rrule.setFreq(Frequency.DAILY);
|
||||
|
||||
Task task = new Task();
|
||||
|
||||
// repeat once => due date should become tomorrow
|
||||
long past = task.createDueDate(Task.URGENCY_SPECIFIC_DAY, new Date(110, 7, 1).getTime());
|
||||
task.setValue(Task.DUE_DATE, past);
|
||||
long today = task.createDueDate(Task.URGENCY_SPECIFIC_DAY, DateUtilities.now());
|
||||
long nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());
|
||||
assertDatesEqual(today, nextDueDate);
|
||||
|
||||
// test specific day & time
|
||||
long pastWithTime = task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, new Date(110, 7, 1, 10, 4).getTime());
|
||||
task.setValue(Task.DUE_DATE, pastWithTime);
|
||||
Date date = new Date(DateUtilities.now() / 1000L * 1000L);
|
||||
date.setHours(10);
|
||||
date.setMinutes(4);
|
||||
date.setSeconds(0);
|
||||
long todayWithTime = task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, date.getTime()) / 1000L * 1000L;
|
||||
if(todayWithTime < DateUtilities.now())
|
||||
todayWithTime += DateUtilities.ONE_DAY;
|
||||
nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());
|
||||
assertDatesEqual(todayWithTime, nextDueDate);
|
||||
}
|
||||
|
||||
public void testDueDateInPastRepeatMultiple() throws ParseException {
|
||||
RRule rrule = new RRule();
|
||||
rrule.setInterval(1);
|
||||
rrule.setFreq(Frequency.DAILY);
|
||||
Task task = new Task();
|
||||
|
||||
// repeat once => due date should become tomorrow
|
||||
long past = task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, new Date(110, 7, 1, 0, 0, 0).getTime());
|
||||
task.setValue(Task.DUE_DATE, past);
|
||||
long nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());
|
||||
assertTrue(nextDueDate > DateUtilities.now());
|
||||
task.setValue(Task.DUE_DATE, nextDueDate);
|
||||
long evenMoreNextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());
|
||||
assertNotSame(nextDueDate, evenMoreNextDueDate);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue