Merge pull request #136 from sbosley/120216_sb_bugfixes

Bug fixes
pull/14/head
Tim Su 13 years ago
commit 4eaeaf97d8

@ -16,7 +16,6 @@
<classpathentry exported="true" kind="lib" path="libs/httpmime-4.1.1.jar"/>
<classpathentry exported="true" kind="lib" path="libs/rfc2445-4Mar2011.jar"/>
<classpathentry exported="true" kind="lib" path="libs/jackson-core-asl-1.6.7.jar"/>
<classpathentry exported="true" kind="lib" path="libs/crittercism_v1_2_5.jar"/>
<classpathentry exported="true" kind="lib" path="libs/jchronic-0.2.3.jar"/>
<classpathentry exported="true" kind="lib" path="libs/guava-11.0.1.jar"/>
<classpathentry exported="true" kind="lib" path="libs/google-api-client-1.6.0-beta.jar"/>
@ -30,5 +29,6 @@
<classpathentry exported="true" kind="lib" path="libs/google-oauth-client-1.6.0-beta.jar"/>
<classpathentry exported="true" kind="lib" path="libs/google-oauth-client-extensions-1.6.0-beta.jar"/>
<classpathentry exported="true" kind="lib" path="libs/gson-1.7.1.jar"/>
<classpathentry kind="lib" path="libs/crittercism_v2_0_1.jar"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

@ -150,10 +150,13 @@
</activity>
<!-- Start of Crittercism.com Code -->
<activity android:name="com.crittercism.FeedbackActivity" />
<activity android:name="com.crittercism.FeedbackCreateActivity" />
<activity android:name="com.crittercism.FeedbackDetailsActivity" />
<activity android:name="com.crittercism.NotificationActivity" />
<activity android:name="com.crittercism.NewFeedbackSpringboardActivity" android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"></activity>
<activity android:name="com.crittercism.NewFeedbackIssueListActivity" android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"></activity>
<activity android:name="com.crittercism.NewFeedbackQuestionListActivity" android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"></activity>
<activity android:name="com.crittercism.NewFeedbackItemDetailsActivity" android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"></activity>
<activity android:name="com.crittercism.NewFeedbackCreateActivity" android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"></activity>
<activity android:name="com.crittercism.NotificationActivity"/>
<service android:name="com.crittercism.service.CrittercismService"
android:process="com.crittercism.service" android:exported="true">
<intent-filter>

@ -4,6 +4,9 @@
package com.todoroo.astrid.actfm.sync;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.json.JSONException;
@ -17,9 +20,11 @@ import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.dao.TaskDao.TaskCriteria;
import com.todoroo.astrid.data.RemoteModel;
import com.todoroo.astrid.data.TagData;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.service.AstridDependencyInjector;
import com.todoroo.astrid.service.TagDataService;
import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.sync.SyncResultCallback;
import com.todoroo.astrid.sync.SyncV2Provider;
@ -31,12 +36,43 @@ import com.todoroo.astrid.tags.TagService;
*/
public class ActFmSyncV2Provider extends SyncV2Provider {
private static final int NUM_THREADS = 20;
@Autowired ActFmPreferenceService actFmPreferenceService;
@Autowired ActFmSyncService actFmSyncService;
@Autowired TaskService taskService;
@Autowired TagDataService tagDataService;
private final PushQueuedArgs<Task> taskPusher = new PushQueuedArgs<Task>() {
@Override
public Task getRemoteModelInstance(TodorooCursor<Task> cursor) {
return new Task(cursor);
}
@Override
public void pushRemoteModel(Task model) {
actFmSyncService.pushTaskOnSave(model, model.getMergedValues());
}
};
private final PushQueuedArgs<TagData> tagPusher = new PushQueuedArgs<TagData>() {
@Override
public void pushRemoteModel(TagData model) {
actFmSyncService.pushTagDataOnSave(model, model.getMergedValues());
}
@Override
public TagData getRemoteModelInstance(
TodorooCursor<TagData> cursor) {
return new TagData(cursor);
}
};
static {
AstridDependencyInjector.initialize();
}
@ -91,6 +127,7 @@ public class ActFmSyncV2Provider extends SyncV2Provider {
public void run() {
int time = Preferences.getInt(LAST_TAG_FETCH_TIME, 0);
try {
pushQueuedTags(callback, finisher, time);
time = actFmSyncService.fetchTags(time);
Preferences.setInt(LAST_TAG_FETCH_TIME, time);
} catch (JSONException e) {
@ -114,7 +151,7 @@ public class ActFmSyncV2Provider extends SyncV2Provider {
actFmSyncService.fetchActiveTasks(manual, handler, new Runnable() {
@Override
public void run() {
pushQueued(callback, finisher);
pushQueuedTasks(callback, finisher);
callback.incrementProgress(30);
if(finisher.decrementAndGet() == 0) {
@ -125,27 +162,26 @@ public class ActFmSyncV2Provider extends SyncV2Provider {
});
}
private void pushQueued(final SyncResultCallback callback,
final AtomicInteger finisher) {
TodorooCursor<Task> cursor = taskService.query(Query.select(Task.PROPERTIES).
where(Criterion.or(
Criterion.and(TaskCriteria.isActive(),
Task.REMOTE_ID.eq(0)),
Criterion.and(Task.REMOTE_ID.gt(0),
Task.MODIFICATION_DATE.gt(Task.LAST_SYNC)))));
private static interface PushQueuedArgs<T extends RemoteModel> {
public T getRemoteModelInstance(TodorooCursor<T> cursor);
public void pushRemoteModel(T model);
}
private <T extends RemoteModel> void pushQueued(final SyncResultCallback callback, final AtomicInteger finisher,
TodorooCursor<T> cursor, boolean awaitTermination, final PushQueuedArgs<T> pusher) {
try {
callback.incrementMax(cursor.getCount() * 20);
finisher.addAndGet(cursor.getCount());
ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
for(int i = 0; i < cursor.getCount(); i++) {
cursor.moveToNext();
final Task task = new Task(cursor);
final T model = pusher.getRemoteModelInstance(cursor);
new Thread(new Runnable() {
executor.submit(new Runnable() {
public void run() {
try {
actFmSyncService.pushTaskOnSave(task, task.getMergedValues());
pusher.pushRemoteModel(model);
} finally {
callback.incrementProgress(20);
if(finisher.decrementAndGet() == 0) {
@ -154,13 +190,44 @@ public class ActFmSyncV2Provider extends SyncV2Provider {
}
}
}
}).start();
});
}
executor.shutdown();
if (awaitTermination)
try {
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} finally {
cursor.close();
}
}
private void pushQueuedTasks(final SyncResultCallback callback,
final AtomicInteger finisher) {
TodorooCursor<Task> taskCursor = taskService.query(Query.select(Task.PROPERTIES).
where(Criterion.or(
Criterion.and(TaskCriteria.isActive(),
Task.REMOTE_ID.eq(0)),
Criterion.and(Task.REMOTE_ID.gt(0),
Task.MODIFICATION_DATE.gt(Task.LAST_SYNC)))));
pushQueued(callback, finisher, taskCursor, false, taskPusher);
}
private void pushQueuedTags(final SyncResultCallback callback,
final AtomicInteger finisher, int lastTagSyncTime) {
TodorooCursor<TagData> tagDataCursor = tagDataService.query(Query.select(TagData.PROPERTIES)
.where(Criterion.or(
TagData.REMOTE_ID.eq(0),
Criterion.and(TagData.REMOTE_ID.gt(0),
TagData.MODIFICATION_DATE.gt(lastTagSyncTime)))));
pushQueued(callback, finisher, tagDataCursor, true, tagPusher);
}
// --- synchronize list
@Override
@ -173,9 +240,6 @@ public class ActFmSyncV2Provider extends SyncV2Provider {
TagData tagData = (TagData) list;
final boolean noRemoteId = tagData.getValue(TagData.REMOTE_ID) == 0;
if(noRemoteId && !manual)
return;
callback.started();
callback.incrementMax(100);

@ -2,17 +2,22 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dip"
android:paddingTop="10dip"
android:paddingBottom="10dip"
android:paddingLeft="0dip"
android:paddingRight="0dip"
android:gravity="center_vertical"
android:orientation="horizontal" >
<CheckBox
android:id="@+id/completeBox"
android:layout_width="45dip"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:button="@drawable/btn_check" />
<com.todoroo.astrid.ui.CheckableImageView
android:id="@+id/completeBox"
android:layout_width="45dip"
android:layout_height="fill_parent"
android:layout_marginRight="5dip"
android:layout_marginLeft="5dip"
android:gravity="center"
android:padding="8dip"
android:src="@drawable/btn_check" />
<com.todoroo.astrid.ui.ErrorCatchingEditText
android:id="@+id/title"

@ -37,12 +37,13 @@
android:paddingBottom="1dip">
<CheckBox
<com.todoroo.astrid.ui.CheckableImageView
android:id="@+id/completeBox"
android:layout_width="45dip"
android:padding="8dip"
android:layout_height="fill_parent"
android:layout_alignParentTop="true"
android:layout_marginLeft="10dip"
android:layout_marginLeft="2dip"
android:button="@drawable/btn_check" />
<!-- assignee photo -->

@ -43,10 +43,11 @@
android:visibility="gone" >
</greendroid.widget.AsyncImageView>
<CheckBox
<com.todoroo.astrid.ui.CheckableImageView
android:id="@+id/completeBox"
android:layout_width="45dip"
android:layout_marginLeft="13dip"
android:padding="8dip"
android:layout_marginLeft="5dip"
android:layout_height="fill_parent"
android:minHeight="40dip"
android:scaleType="center"

@ -392,9 +392,8 @@ public class TaskListActivity extends AstridActivity implements MainMenuListener
}
if (data.getBooleanExtra(TaskEditFragment.TOKEN_TAGS_CHANGED, false))
tagsChanged(true);
} else {
tlf.refresh();
}
tlf.refresh();
}
}

@ -66,7 +66,7 @@ import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;
import com.crittercism.FeedbackActivity;
import com.crittercism.NewFeedbackSpringboardActivity;
import com.timsu.astrid.R;
import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.data.TodorooCursor;
@ -1594,7 +1594,7 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
intent = new Intent(getActivity(), TaskEditActivity.class);
intent.putExtra(TaskEditFragment.TOKEN_ID, clone.getId());
intent.putExtra(TOKEN_FILTER, filter);
startActivityForResult(intent, ACTIVITY_EDIT_TASK);
getActivity().startActivityForResult(intent, ACTIVITY_EDIT_TASK);
transitionForTaskEdit();
return true;
@ -1643,7 +1643,7 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
public void showSupport() {
StatisticsService.reportEvent(StatisticsConstants.TLA_MENU_HELP);
Intent intent = new Intent(getActivity(), FeedbackActivity.class);
Intent intent = new Intent(getActivity(), NewFeedbackSpringboardActivity.class);
startActivity(intent);
}

@ -79,6 +79,7 @@ import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.taskrabbit.TaskRabbitDataService;
import com.todoroo.astrid.taskrabbit.TaskRabbitTaskContainer;
import com.todoroo.astrid.timers.TimerDecorationExposer;
import com.todoroo.astrid.ui.CheckableImageView;
import com.todoroo.astrid.utility.Constants;
/**
@ -271,7 +272,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
viewHolder.nameView = (TextView)view.findViewById(R.id.title);
viewHolder.picture = (AsyncImageView)view.findViewById(R.id.picture);
viewHolder.pictureBorder = (ImageView)view.findViewById(R.id.pictureBorder);
viewHolder.completeBox = (CheckBox)view.findViewById(R.id.completeBox);
viewHolder.completeBox = (CheckableImageView)view.findViewById(R.id.completeBox);
viewHolder.dueDate = (TextView)view.findViewById(R.id.dueDate);
viewHolder.details1 = (TextView)view.findViewById(R.id.details1);
viewHolder.details2 = (TextView)view.findViewById(R.id.details2);
@ -337,7 +338,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
public ViewGroup rowBody;
public TextView nameView;
public View importance; // for legacy importance style
public CheckBox completeBox;
public CheckableImageView completeBox;
public AsyncImageView picture;
public ImageView pictureBorder;
public TextView dueDate;
@ -398,7 +399,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
}
// complete box
final CheckBox completeBox = viewHolder.completeBox; {
final CheckableImageView completeBox = viewHolder.completeBox; {
// show item as completed if it was recently checked
if(completedItems.get(task.getId()) != null) {
task.setValue(Task.COMPLETION_DATE,
@ -441,7 +442,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
}
// importance bar
final CheckBox checkBoxView = viewHolder.completeBox; {
final CheckableImageView checkBoxView = viewHolder.completeBox; {
// Logic for legacy style
boolean useLegacyImportance = Preferences.getBoolean(R.string.p_useLegacyImportanceStyle, false);
if (useLegacyImportance) {
@ -454,12 +455,12 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
if (value >= IMPORTANCE_RESOURCES.length)
value = IMPORTANCE_RESOURCES.length - 1;
if (useLegacyImportance) {
checkBoxView.setButtonDrawable(R.drawable.btn_check);
checkBoxView.setImageResource(R.drawable.btn_check);
viewHolder.importance.setBackgroundResource(LEGACY_IMPORTANCE_RESOURCES[value]);
} else if (!TextUtils.isEmpty(task.getValue(Task.RECURRENCE))) {
checkBoxView.setButtonDrawable(IMPORTANCE_REPEAT_RESOURCES[value]);
checkBoxView.setImageResource(IMPORTANCE_REPEAT_RESOURCES[value]);
} else {
checkBoxView.setButtonDrawable(IMPORTANCE_RESOURCES[value]);
checkBoxView.setImageResource(IMPORTANCE_RESOURCES[value]);
}
if (pictureView != null && pictureView.getVisibility() == View.VISIBLE) {
checkBoxView.setVisibility(View.INVISIBLE);

@ -0,0 +1,98 @@
package com.todoroo.astrid.ui;
import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewDebug;
import android.widget.Checkable;
import android.widget.ImageView;
public class CheckableImageView extends ImageView implements Checkable {
private static final int[] CHECKED_STATE_SET = {
android.R.attr.state_checked
};
public CheckableImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public static interface OnCheckedChangeListener {
public void onCheckedChanged(Checkable c, boolean isChecked);
}
@Override
public boolean performClick() {
toggle();
return super.performClick();
}
private boolean mChecked;
private boolean mBroadcasting;
private OnCheckedChangeListener mOnCheckedChangeListener;
public void toggle() {
setChecked(!mChecked);
}
@ViewDebug.ExportedProperty
public boolean isChecked() {
return mChecked;
}
/**
* <p>Changes the checked state of this button.</p>
*
* @param checked true to check the button, false to uncheck it
*/
public void setChecked(boolean checked) {
if (mChecked != checked) {
mChecked = checked;
refreshDrawableState();
// Avoid infinite recursions if setChecked() is called from a listener
if (mBroadcasting) {
return;
}
mBroadcasting = true;
if (mOnCheckedChangeListener != null) {
mOnCheckedChangeListener.onCheckedChanged(this, mChecked);
}
mBroadcasting = false;
}
}
/**
* Register a callback to be invoked when the checked state of this button
* changes.
*
* @param listener the callback to call on checked state change
*/
public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
mOnCheckedChangeListener = listener;
}
@Override
public int[] onCreateDrawableState(int extraSpace) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
if (isChecked()) {
mergeDrawableStates(drawableState, CHECKED_STATE_SET);
}
return drawableState;
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
if (getDrawable() != null) {
int[] myDrawableState = getDrawableState();
// Set the state of the Drawable
getDrawable().setState(myDrawableState);
invalidate();
}
}
}

@ -1,11 +1,10 @@
package com.todoroo.astrid.ui;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import com.timsu.astrid.R;
@ -24,7 +23,7 @@ import com.todoroo.astrid.service.TaskService;
public class EditTextControlSet extends TaskEditControlSet {
private EditText editText;
private final StringProperty property;
protected CheckBox completeBox;
protected CheckableImageView completeBox;
private final int editTextId;
@Autowired
@ -41,18 +40,17 @@ public class EditTextControlSet extends TaskEditControlSet {
@Override
protected void afterInflate() {
this.editText = (EditText) getView().findViewById(editTextId);
this.completeBox = (CheckBox) getView().findViewById(R.id.completeBox);
this.completeBox = (CheckableImageView) getView().findViewById(R.id.completeBox);
}
@Override
protected void readFromTaskOnInitialize() {
editText.setTextKeepState(model.getValue(property));
completeBox.setChecked(model.isCompleted());
completeBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
completeBox.setOnClickListener(new OnClickListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
ScaleAnimation scaleAnimation = new ScaleAnimation(1.6f, 1.0f, 1.6f, 1.0f,
public void onClick(View v) {
ScaleAnimation scaleAnimation = new ScaleAnimation(1.5f, 1.0f, 1.5f, 1.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(100);
// set check box to actual action item state

@ -47,9 +47,9 @@ public class EditTitleControlSet extends EditTextControlSet implements Importanc
valueToUse = TaskAdapter.IMPORTANCE_RESOURCES.length - 1;
if(valueToUse < TaskAdapter.IMPORTANCE_RESOURCES.length) {
if (isRepeating) {
completeBox.setButtonDrawable(TaskAdapter.IMPORTANCE_REPEAT_RESOURCES[valueToUse]);
completeBox.setImageResource(TaskAdapter.IMPORTANCE_REPEAT_RESOURCES[valueToUse]);
} else {
completeBox.setButtonDrawable(TaskAdapter.IMPORTANCE_RESOURCES[valueToUse]);
completeBox.setImageResource(TaskAdapter.IMPORTANCE_RESOURCES[valueToUse]);
}
}
}

Loading…
Cancel
Save