diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 6fcda0296..df4574b4f 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,13 +1,13 @@ + android:versionCode="60" + android:versionName="2.0.0-rc1"> + android:value="60" /> diff --git a/res/drawable/btn_check_0.png b/res/drawable/btn_check_0.png index 3615c3165..8bd6db1f1 100644 Binary files a/res/drawable/btn_check_0.png and b/res/drawable/btn_check_0.png differ diff --git a/res/drawable/btn_check_25.png b/res/drawable/btn_check_25.png index 14b72cac7..4108bfa3e 100644 Binary files a/res/drawable/btn_check_25.png and b/res/drawable/btn_check_25.png differ diff --git a/res/drawable/btn_check_50.png b/res/drawable/btn_check_50.png index ee85bf696..60363ca74 100644 Binary files a/res/drawable/btn_check_50.png and b/res/drawable/btn_check_50.png differ diff --git a/res/drawable/btn_check_75.png b/res/drawable/btn_check_75.png index a969539d1..55795fc2f 100644 Binary files a/res/drawable/btn_check_75.png and b/res/drawable/btn_check_75.png differ diff --git a/res/drawable/btn_check_off.png b/res/drawable/btn_check_off.png index 7e2ea8590..56d386154 100644 Binary files a/res/drawable/btn_check_off.png and b/res/drawable/btn_check_off.png differ diff --git a/res/drawable/btn_check_off_pressed.png b/res/drawable/btn_check_off_pressed.png index 88be2ddfc..47c1a460f 100644 Binary files a/res/drawable/btn_check_off_pressed.png and b/res/drawable/btn_check_off_pressed.png differ diff --git a/res/drawable/btn_check_on.png b/res/drawable/btn_check_on.png index e4b741538..fc517a108 100644 Binary files a/res/drawable/btn_check_on.png and b/res/drawable/btn_check_on.png differ diff --git a/res/drawable/btn_check_on_pressed.png b/res/drawable/btn_check_on_pressed.png index 716a7f778..ee2175d04 100644 Binary files a/res/drawable/btn_check_on_pressed.png and b/res/drawable/btn_check_on_pressed.png differ diff --git a/res/layout/task_list_row.xml b/res/layout/task_list_row.xml index 2cce1354a..2318430ea 100644 --- a/res/layout/task_list_row.xml +++ b/res/layout/task_list_row.xml @@ -69,6 +69,15 @@ android:paddingRight="10dip" android:singleLine="true"/> + + #FFFB6666 #ffF0E89E + #ff88AAFF #ff888888 #ff888888 diff --git a/res/values/strings.xml b/res/values/strings.xml index a78269425..2a05d9ba7 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -84,6 +84,10 @@ Tags: No Tags + Left + Over Time + Spent + Add Tags Display @@ -227,6 +231,7 @@ Wish me luck!\n Synchronize Now! Clear Personal Data Clear data for selected services? + No Synchronizers Enabled! diff --git a/src/com/timsu/astrid/activities/SyncPreferences.java b/src/com/timsu/astrid/activities/SyncPreferences.java index e1e47c397..1b7966cb6 100644 --- a/src/com/timsu/astrid/activities/SyncPreferences.java +++ b/src/com/timsu/astrid/activities/SyncPreferences.java @@ -9,17 +9,16 @@ import android.widget.Button; import com.timsu.astrid.R; import com.timsu.astrid.sync.Synchronizer; -import com.timsu.astrid.sync.Synchronizer.SynchronizerListener; +import com.timsu.astrid.utilities.Constants; import com.timsu.astrid.utilities.DialogUtilities; public class SyncPreferences extends PreferenceActivity { - + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.sync_preferences); - syncFinished = true; getListView().addFooterView(getLayoutInflater().inflate( R.layout.sync_footer, getListView(), false)); @@ -28,7 +27,7 @@ public class SyncPreferences extends PreferenceActivity { syncButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Preferences.setSyncLastSync(SyncPreferences.this, null); + setResult(Constants.RESULT_SYNCHRONIZE); finish(); } }); diff --git a/src/com/timsu/astrid/activities/TaskList.java b/src/com/timsu/astrid/activities/TaskList.java index fec5494c0..91c10dc9e 100644 --- a/src/com/timsu/astrid/activities/TaskList.java +++ b/src/com/timsu/astrid/activities/TaskList.java @@ -59,7 +59,9 @@ import com.timsu.astrid.data.task.TaskController; import com.timsu.astrid.data.task.TaskIdentifier; import com.timsu.astrid.data.task.TaskModelForList; import com.timsu.astrid.sync.Synchronizer; +import com.timsu.astrid.sync.Synchronizer.SynchronizerListener; import com.timsu.astrid.utilities.Constants; +import com.timsu.astrid.utilities.DialogUtilities; import com.timsu.astrid.utilities.Preferences; import com.timsu.astrid.utilities.StartupReceiver; @@ -105,8 +107,6 @@ public class TaskList extends Activity { public static final int FLING_VEL_THRESHOLD = 300; // UI components - private TaskController controller; - private TagController tagController = null; private ListView listView; private Button addButton; private View layout; @@ -127,6 +127,11 @@ public class TaskList extends Activity { static boolean shouldCloseInstance = false; + // database controllers + private TaskController taskController; + private TagController tagController; + + /* ====================================================================== * ======================================================= initialization * ====================================================================== */ @@ -140,13 +145,15 @@ public class TaskList extends Activity { StartupReceiver.onStartupApplication(this); shouldCloseInstance = false; - controller = new TaskController(this); - controller.open(); + taskController = new TaskController(this); + taskController.open(); tagController = new TagController(this); tagController.open(); + Synchronizer.setTagController(tagController); + Synchronizer.setTaskController(taskController); + setupUIComponents(); - fillData(); // auto sync Integer autoSyncHours = Preferences.autoSyncFrequency(this); @@ -155,11 +162,10 @@ public class TaskList extends Activity { if(lastSync == null || lastSync.getTime() + 1000L*3600*autoSyncHours < System.currentTimeMillis()) { - Synchronizer.synchronize(this, new SynchronizationListener() { - show dialog! - }); + Synchronizer.synchronize(this, true, null); } - } + } else + fillData(); } public void setupUIComponents() { @@ -345,15 +351,15 @@ public class TaskList extends Activity { if(filterTag != null) { List tasks = tagController.getTaggedTasks(this, filterTag.getTagIdentifier()); - tasksCursor = controller.getTaskListCursorById(tasks); + tasksCursor = taskController.getTaskListCursorById(tasks); } else { if(filterShowDone) - tasksCursor = controller.getAllTaskListCursor(); + tasksCursor = taskController.getAllTaskListCursor(); else - tasksCursor = controller.getActiveTaskListCursor(); + tasksCursor = taskController.getActiveTaskListCursor(); } startManagingCursor(tasksCursor); - taskArray = controller.createTaskListFromCursor(tasksCursor); + taskArray = taskController.createTaskListFromCursor(tasksCursor); // read tags and apply filters int hiddenTasks = 0; // # of tasks hidden @@ -456,7 +462,7 @@ public class TaskList extends Activity { @Override public TaskController getTaskController() { - return controller; + return taskController; } @Override @@ -542,7 +548,16 @@ public class TaskList extends Activity { protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); - if(requestCode == ACTIVITY_TAGS && resultCode == RESULT_CANCELED) + if(resultCode == Constants.RESULT_SYNCHRONIZE) { + Synchronizer.synchronize(this, false, new SynchronizerListener() { + @Override + public void onSynchronizerFinished(int numServicesSynced) { + if(numServicesSynced == 0) + DialogUtilities.okDialog(TaskList.this, getResources().getString( + R.string.sync_no_synchronizers), null); + } + }); + } else if(requestCode == ACTIVITY_TAGS && resultCode == RESULT_CANCELED) filterTag = null; } @@ -576,7 +591,7 @@ public class TaskList extends Activity { new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - controller.deleteTask(taskId); + taskController.deleteTask(taskId); fillData(); } }) @@ -648,7 +663,7 @@ public class TaskList extends Activity { else { task.stopTimerAndUpdateElapsedTime(); } - controller.saveTask(task); + taskController.saveTask(task); fillData(); return true; @@ -697,7 +712,7 @@ public class TaskList extends Activity { @Override protected void onDestroy() { super.onDestroy(); - controller.close(); + taskController.close(); if(tagController != null) tagController.close(); } diff --git a/src/com/timsu/astrid/activities/TaskListAdapter.java b/src/com/timsu/astrid/activities/TaskListAdapter.java index bd6fc55b9..ce3955f00 100644 --- a/src/com/timsu/astrid/activities/TaskListAdapter.java +++ b/src/com/timsu/astrid/activities/TaskListAdapter.java @@ -105,6 +105,7 @@ public class TaskListAdapter extends ArrayAdapter { // find UI components final TextView name = ((TextView)view.findViewById(R.id.text1)); final TextView dueDateView = ((TextView)view.findViewById(R.id.text_dueDate)); + final TextView remainingTimeView = ((TextView)view.findViewById(R.id.text_remainingTime)); final TextView tagsView = ((TextView)view.findViewById(R.id.text_tags)); final CheckBox progress = ((CheckBox)view.findViewById(R.id.cb1)); final ImageView timer = ((ImageView)view.findViewById(R.id.imageLeft)); @@ -114,6 +115,7 @@ public class TaskListAdapter extends ArrayAdapter { view.setTag(task); progress.setTag(task); + // name String nameValue = task.getName(); if(task.getHiddenUntil() != null && task.getHiddenUntil().after(new Date())) nameValue = "(" + r.getString(R.string.taskList_hiddenPrefix) + ") " + nameValue; @@ -172,6 +174,40 @@ public class TaskListAdapter extends ArrayAdapter { dueDateView.setVisibility(View.GONE); } + // remaining time + if(task.getElapsedSeconds() > 0 || task.getEstimatedSeconds() > 0 || + task.getTimerStart() != null) { + remainingTimeView.setVisibility(View.VISIBLE); + int elapsed = task.getElapsedSeconds(); + if(task.getTimerStart() != null) + elapsed += ((System.currentTimeMillis() - task.getTimerStart().getTime())/1000); + String remainingString = ""; + if(!task.isTaskCompleted() && task.getEstimatedSeconds() > 0) { + int remaining = task.getEstimatedSeconds() - elapsed; + remainingString = DateUtilities.getShortDurationString(r, + (int)Math.abs(remaining), 1) + " "; + if(remaining >= 0) + remainingString += r.getString(R.string.taskList_remaining); + else + remainingString += r.getString(R.string.taskList_overtime); + } else if(elapsed > 0) { + remainingString = DateUtilities.getShortDurationString(r, + (int)Math.abs(elapsed), 1) + " " + + r.getString(R.string.taskList_spent); + } + + if(remainingString.length() == 0) { + remainingTimeView.setVisibility(View.GONE); + } else { + hasProperties = true; + remainingTimeView.setText(remainingString); + if(task.isTaskCompleted()) + remainingTimeView.setTextColor(r.getColor(R.color.taskList_completedDate)); + } + } else { + remainingTimeView.setVisibility(View.GONE); + } + // tags List tags = hooks.getTagsFor(task); StringBuilder tagString = new StringBuilder(); diff --git a/src/com/timsu/astrid/data/AbstractController.java b/src/com/timsu/astrid/data/AbstractController.java index f54a330a4..fa14f2107 100644 --- a/src/com/timsu/astrid/data/AbstractController.java +++ b/src/com/timsu/astrid/data/AbstractController.java @@ -34,7 +34,6 @@ abstract public class AbstractController { // special columns public static final String KEY_ROWID = "_id"; - // database and table names protected static final String TASK_TABLE_NAME = "tasks"; protected static final String TAG_TABLE_NAME = "tags"; @@ -42,6 +41,9 @@ abstract public class AbstractController { protected static final String ALERT_TABLE_NAME = "alerts"; protected static final String SYNC_TABLE_NAME = "sync"; + abstract public void open(); + abstract public void close(); + // cursor iterator public static class CursorIterator implements Iterator { diff --git a/src/com/timsu/astrid/data/alerts/AlertController.java b/src/com/timsu/astrid/data/alerts/AlertController.java index a20f26dd9..84d7b0103 100644 --- a/src/com/timsu/astrid/data/alerts/AlertController.java +++ b/src/com/timsu/astrid/data/alerts/AlertController.java @@ -130,14 +130,14 @@ public class AlertController extends AbstractController { * initialization call) * @throws SQLException if the database could be neither opened or created */ - public AlertController open() throws SQLException { + @Override + public void open() throws SQLException { alertDatabase = new AlertDatabaseHelper(context, ALERT_TABLE_NAME, ALERT_TABLE_NAME).getWritableDatabase(); - - return this; } /** Closes database resource */ + @Override public void close() { alertDatabase.close(); } diff --git a/src/com/timsu/astrid/data/sync/SyncDataController.java b/src/com/timsu/astrid/data/sync/SyncDataController.java index 3c74b80c1..d1b95ba7f 100644 --- a/src/com/timsu/astrid/data/sync/SyncDataController.java +++ b/src/com/timsu/astrid/data/sync/SyncDataController.java @@ -119,15 +119,15 @@ public class SyncDataController extends AbstractController { * initialization call) * @throws SQLException if the database could be neither opened or created */ - public SyncDataController open() throws SQLException { + @Override + public void open() throws SQLException { SQLiteOpenHelper helper = new SyncMappingDatabaseHelper(context, SYNC_TABLE_NAME, SYNC_TABLE_NAME); syncDatabase = helper.getWritableDatabase(); - - return this; } /** Closes database resource */ + @Override public void close() { syncDatabase.close(); } diff --git a/src/com/timsu/astrid/data/tag/TagController.java b/src/com/timsu/astrid/data/tag/TagController.java index 026506302..be3697615 100644 --- a/src/com/timsu/astrid/data/tag/TagController.java +++ b/src/com/timsu/astrid/data/tag/TagController.java @@ -209,15 +209,16 @@ public class TagController extends AbstractController { * initialization call) * @throws SQLException if the database could be neither opened or created */ - public TagController open() throws SQLException { + @Override + public void open() throws SQLException { tagToTaskMapDatabase = new TagToTaskMappingDatabaseHelper(context, TAG_TASK_MAP_NAME, TAG_TASK_MAP_NAME).getWritableDatabase(); tagDatabase = new TagModelDatabaseHelper(context, TAG_TABLE_NAME, TAG_TABLE_NAME).getWritableDatabase(); - return this; } /** Closes database resource */ + @Override public void close() { tagDatabase.close(); tagToTaskMapDatabase.close(); diff --git a/src/com/timsu/astrid/data/task/TaskController.java b/src/com/timsu/astrid/data/task/TaskController.java index 8ce850075..6ace154e9 100644 --- a/src/com/timsu/astrid/data/task/TaskController.java +++ b/src/com/timsu/astrid/data/task/TaskController.java @@ -364,14 +364,15 @@ public class TaskController extends AbstractController { * initialization call) * @throws SQLException if the database could be neither opened or created */ - public TaskController open() throws SQLException { + @Override + public void open() throws SQLException { SQLiteOpenHelper databaseHelper = new TaskModelDatabaseHelper( context, TASK_TABLE_NAME, TASK_TABLE_NAME); database = databaseHelper.getWritableDatabase(); - return this; } /** Closes database resource */ + @Override public void close() { database.close(); } diff --git a/src/com/timsu/astrid/sync/SynchronizationService.java b/src/com/timsu/astrid/sync/SynchronizationService.java index 1f4422f99..08b6a35fe 100644 --- a/src/com/timsu/astrid/sync/SynchronizationService.java +++ b/src/com/timsu/astrid/sync/SynchronizationService.java @@ -105,10 +105,10 @@ public abstract class SynchronizationService { /** Create a task on the remote server * - * @return listName list name to create it on. null -> inbox + * @return primaryTag primary tag of this task. null if no tags exist. * @return remote id */ - String createTask(String listName) throws IOException; + String createTask(String primaryTag) throws IOException; /** Fetch remote task. Used to re-read merged tasks * @@ -153,7 +153,7 @@ public abstract class SynchronizationService { TagController tagController = Synchronizer.getTagController(activity); AlertController alertController = Synchronizer.getAlertController(activity); - // get data out of the database + // 1. get data out of the database HashSet mappings = syncController.getSyncMapping(getId()); HashSet activeTasks = taskController. getActiveTaskIdentifiers(); @@ -162,7 +162,7 @@ public abstract class SynchronizationService { HashMap tags = tagController.getAllTagsAsMap(activity); - // build local maps / lists + // 2. build helper data structures HashMap remoteIdToSyncMapping = new HashMap(); HashMap localIdToSyncMapping = @@ -177,34 +177,47 @@ public abstract class SynchronizationService { mappedTasks.add(mapping.getTask()); } - // build remote map + // 3. build map of remote tasks HashMap remoteChangeMap = new HashMap(); + HashMap newRemoteTasks = new HashMap(); for(TaskProxy remoteTask : remoteTasks) { if(remoteIdToSyncMapping.containsKey(remoteTask.getRemoteId())) { SyncMapping mapping = remoteIdToSyncMapping.get(remoteTask.getRemoteId()); remoteChangeMap.put(mapping.getTask(), remoteTask); + } else if(remoteTask.name != null){ + newRemoteTasks.put(remoteTask.name, remoteTask); } } - // grab tasks without a sync mapping and create them remotely + // 4. CREATE: grab tasks without a sync mapping and create them remotely log.append(">> on remote server:\n"); - syncHandler.post(new Runnable() { - @Override - public void run() { - progressDialog.setMessage("Sending locally created tasks"); - progressDialog.setProgress(0); - } - }); + syncHandler.post(new ProgressLabelUpdater("Sending locally created tasks")); HashSet newlyCreatedTasks = new HashSet(activeTasks); newlyCreatedTasks.removeAll(mappedTasks); for(TaskIdentifier taskId : newlyCreatedTasks) { + TaskModelForSync task = taskController.fetchTaskForSync(taskId); + + /* If there exists an incoming remote task with the same name and + * no mapping, we don't want to create this on the remote server. + * Instead, we create a mapping and do an update. */ + if(newRemoteTasks.containsKey(task.getName())) { + TaskProxy remoteTask = newRemoteTasks.get(task.getName()); + SyncMapping mapping = new SyncMapping(taskId, getId(), + remoteTask.getRemoteId()); + syncController.saveSyncMapping(mapping); + localChanges.add(mapping); + remoteChangeMap.put(taskId, remoteTask); + localIdToSyncMapping.put(taskId, mapping); + continue; + } + + // grab the primary tag for this task LinkedList taskTags = tagController.getTaskTags(activity, taskId); String listName = null; if(taskTags.size() > 0) { listName = tags.get(taskTags.get(0)).getName(); - // strip the underline if(listName.startsWith(TagModelForView.HIDDEN_FROM_MAIN_LIST_PREFIX)) listName = listName.substring(1); } @@ -212,27 +225,19 @@ public abstract class SynchronizationService { SyncMapping mapping = new SyncMapping(taskId, getId(), remoteId); syncController.saveSyncMapping(mapping); - TaskModelForSync task = taskController.fetchTaskForSync( - mapping.getTask()); TaskProxy localTask = new TaskProxy(getId(), remoteId, false); localTask.readFromTaskModel(task); helper.pushTask(localTask, mapping); // update stats - log.append("add " + task.getName() + "\n"); + log.append("added " + task.getName() + "\n"); stats.remoteCreatedTasks++; syncHandler.post(new ProgressUpdater(stats.remoteCreatedTasks, newlyCreatedTasks.size())); } - // find deleted tasks and remove them from the list - syncHandler.post(new Runnable() { - @Override - public void run() { - progressDialog.setMessage("Sending locally deleted tasks"); - progressDialog.setProgress(0); - } - }); + // 5. DELETE: find deleted tasks and remove them from the list + syncHandler.post(new ProgressLabelUpdater("Sending locally deleted tasks")); HashSet deletedTasks = new HashSet( mappedTasks); deletedTasks.removeAll(allTasks); @@ -247,20 +252,14 @@ public abstract class SynchronizationService { remoteChangeMap.remove(taskId); // update stats - log.append("del #" + taskId.getId() + "\n"); + log.append("deleted id #" + taskId.getId() + "\n"); stats.remoteDeletedTasks++; syncHandler.post(new ProgressUpdater(stats.remoteDeletedTasks, deletedTasks.size())); } - // for each updated local task - syncHandler.post(new Runnable() { - @Override - public void run() { - progressDialog.setMessage("Sending locally edited tasks"); - progressDialog.setProgress(0); - } - }); + // 6. UPDATE: for each updated local task + syncHandler.post(new ProgressLabelUpdater("Sending locally edited tasks")); for(SyncMapping mapping : localChanges) { TaskProxy localTask = new TaskProxy(getId(), mapping.getRemoteId(), false); @@ -274,9 +273,9 @@ public abstract class SynchronizationService { remoteConflict = remoteChangeMap.get(mapping.getTask()); localTask.mergeWithOther(remoteConflict); stats.mergedTasks++; - log.append("mrg " + task.getName() + "\n"); + log.append("merged " + task.getName() + "\n"); } else { - log.append("upd " + task.getName() + "\n"); + log.append("updated " + task.getName() + "\n"); } try { @@ -297,15 +296,9 @@ public abstract class SynchronizationService { localChanges.size())); } - // load remote information + // 7. REMOTE SYNC load remote information log.append(">> on astrid:\n"); - syncHandler.post(new Runnable() { - @Override - public void run() { - progressDialog.setMessage("Updating local tasks"); - progressDialog.setProgress(0); - } - }); + syncHandler.post(new ProgressLabelUpdater("Updating local tasks")); for(TaskProxy remoteTask : remoteTasks) { SyncMapping mapping = null; TaskModelForSync task = null; @@ -321,22 +314,22 @@ public abstract class SynchronizationService { if(task == null) { task = new TaskModelForSync(); setupTaskDefaults(activity, task); - log.append("add " + remoteTask.name + "\n"); + log.append("added " + remoteTask.name + "\n"); } else { mapping = localIdToSyncMapping.get(task.getTaskIdentifier()); - log.append("mov " + remoteTask.name + "\n"); + log.append("merged " + remoteTask.name + "\n"); } } else { mapping = remoteIdToSyncMapping.get(remoteTask.getRemoteId()); if(remoteTask.isDeleted()) { taskController.deleteTask(mapping.getTask()); syncController.deleteSyncMapping(mapping); - log.append("del " + remoteTask.name + "\n"); + log.append("deleted " + remoteTask.name + "\n"); stats.localDeletedTasks++; continue; } - log.append("upd " + remoteTask.name + "\n"); + log.append("updated " + remoteTask.name + "\n"); task = taskController.fetchTaskForSync( mapping.getTask()); } @@ -424,7 +417,8 @@ public abstract class SynchronizationService { if(localCreatedTasks + localUpdatedTasks + localDeletedTasks + mergedTasks + remoteCreatedTasks + remoteDeletedTasks + remoteUpdatedTasks == 0) { - DialogUtilities.okDialog(activity, "Sync: Up to date!", finishListener); + if(!Synchronizer.isAutoSync()) + DialogUtilities.okDialog(activity, "Sync: Up to date!", finishListener); return; } @@ -467,4 +461,15 @@ public abstract class SynchronizationService { progressDialog.setProgress(100*step/outOf); } } + + protected class ProgressLabelUpdater implements Runnable { + String label; + public ProgressLabelUpdater(String label) { + this.label = label; + } + public void run() { + progressDialog.setMessage(label); + progressDialog.setProgress(0); + } + } } diff --git a/src/com/timsu/astrid/sync/Synchronizer.java b/src/com/timsu/astrid/sync/Synchronizer.java index c14d23b54..25ff9d970 100644 --- a/src/com/timsu/astrid/sync/Synchronizer.java +++ b/src/com/timsu/astrid/sync/Synchronizer.java @@ -1,10 +1,13 @@ package com.timsu.astrid.sync; +import java.lang.reflect.InvocationTargetException; import java.util.Date; import android.app.Activity; import android.content.Context; +import android.util.Log; +import com.timsu.astrid.data.AbstractController; import com.timsu.astrid.data.alerts.AlertController; import com.timsu.astrid.data.sync.SyncDataController; import com.timsu.astrid.data.tag.TagController; @@ -22,9 +25,11 @@ public class Synchronizer { } /** Synchronize all activated sync services */ - public static void synchronize(Activity activity, SynchronizerListener listener) { + public static void synchronize(Activity activity, boolean isAutoSync, + SynchronizerListener listener) { currentStep = ServiceWrapper._FIRST_SERVICE.ordinal(); servicesSynced = 0; + autoSync = isAutoSync; callback = listener; continueSynchronization(activity); } @@ -88,6 +93,9 @@ public class Synchronizer { /** On finished callback */ private static SynchronizerListener callback; + /** If this synchronization was automatically initiated */ + private static boolean autoSync; + /** Called to do the next step of synchronization. Run me on the UI thread! */ static void continueSynchronization(Activity activity) { @@ -119,65 +127,95 @@ public class Synchronizer { callback.onSynchronizerFinished(servicesSynced); } - // --- package helpers + /** Was this sync automatically initiated? */ + static boolean isAutoSync() { + return autoSync; + } - static SyncDataController getSyncController(Activity activity) { - if(syncController == null) { - syncController = new SyncDataController(activity); - syncController.open(); + // --- controller stuff + + private static class ControllerWrapper { + TYPE controller; + Class typeClass; + boolean override; + + public ControllerWrapper(Class cls) { + override = false; + controller = null; + typeClass = cls; + } + + public TYPE get(Activity activity) { + if(controller == null) { + try { + controller = typeClass.getConstructors()[0].newInstance( + activity); + } catch (IllegalArgumentException e) { + Log.e(getClass().getSimpleName(), e.toString()); + } catch (SecurityException e) { + Log.e(getClass().getSimpleName(), e.toString()); + } catch (InstantiationException e) { + Log.e(getClass().getSimpleName(), e.toString()); + } catch (IllegalAccessException e) { + Log.e(getClass().getSimpleName(), e.toString()); + } catch (InvocationTargetException e) { + Log.e(getClass().getSimpleName(), e.toString()); + } + controller.open(); + } + return controller; + } + + public void set(TYPE newController) { + override = newController != null; + controller = newController; + } + + public void close() { + if(controller != null && !override) { + controller.close(); + controller = null; + } } - return syncController; + } + + private static ControllerWrapper syncController = + new ControllerWrapper(SyncDataController.class); + private static ControllerWrapper taskController = + new ControllerWrapper(TaskController.class); + private static ControllerWrapper tagController = + new ControllerWrapper(TagController.class); + private static ControllerWrapper alertController = + new ControllerWrapper(AlertController.class); + + static SyncDataController getSyncController(Activity activity) { + return syncController.get(activity); } static TaskController getTaskController(Activity activity) { - if(taskController == null) { - taskController = new TaskController(activity); - taskController.open(); - } - return taskController; + return taskController.get(activity); } static TagController getTagController(Activity activity) { - if(tagController == null) { - tagController = new TagController(activity); - tagController.open(); - } - return tagController; + return tagController.get(activity); } static AlertController getAlertController(Activity activity) { - if(alertController == null) { - alertController = new AlertController(activity); - alertController.open(); - } - return alertController; + return alertController.get(activity); } - // --- controller stuff - private static SyncDataController syncController = null; - private static TaskController taskController = null; - private static TagController tagController = null; - private static AlertController alertController = null; - - private static void closeControllers() { - if(syncController != null) { - syncController.close(); - syncController = null; - } - - if(taskController != null) { - taskController.close(); - taskController = null; - } + public static void setTaskController(TaskController taskController) { + Synchronizer.taskController.set(taskController); + } - if(tagController != null) { - tagController.close(); - tagController = null; - } + public static void setTagController(TagController tagController) { + Synchronizer.tagController.set(tagController); + } - if(alertController != null) { - alertController.close(); - alertController = null; - } + private static void closeControllers() { + syncController.close(); + taskController.close(); + tagController.close(); + alertController.close(); } } diff --git a/src/com/timsu/astrid/utilities/Constants.java b/src/com/timsu/astrid/utilities/Constants.java index c2cff024d..0c5d2283f 100644 --- a/src/com/timsu/astrid/utilities/Constants.java +++ b/src/com/timsu/astrid/utilities/Constants.java @@ -14,6 +14,6 @@ public class Constants { /** Return to the task list view */ public static final int RESULT_GO_HOME = Activity.RESULT_FIRST_USER; - /** Callback from synchronization */ + /** Callback to force synchronization */ public static final int RESULT_SYNCHRONIZE = Activity.RESULT_FIRST_USER + 1; }