Bug fixes in preparation for 2.7:

- Fixed a couple issues with German localization
  - not listing smart lists in synchronization dialog
  - fixed bug where hiding a tag that corresponds to an RTM list doesn't work well
  - localizing more synchronization strings
pull/14/head
Tim Su 17 years ago
parent 309431bcdc
commit 96e5f46ef9

Binary file not shown.

Binary file not shown.

@ -1,50 +1,43 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- <!--
ASTRID: Android's Simple Task Recording Dashboard ASTRID: Android's Simple Task Recording Dashboard Copyright (c) 2009 Tim
Su This program is free software; you can redistribute it and/or modify
Copyright (c) 2009 Tim Su 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
This program is free software; you can redistribute it and/or modify option) any later version. This program is distributed in the hope that
it under the terms of the GNU General Public License as published by it will be useful, but WITHOUT ANY WARRANTY; without even the implied
the Free Software Foundation; either version 2 of the License, or warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
(at your option) any later version. 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,
This program is distributed in the hope that it will be useful, but write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY Boston, MA 02111-1307 USA
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
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- application --> <!-- application -->
<string name="app_name">Astrid</string> <string name="app_name">Astrid</string>
<!-- General String Constants --> <!-- General String Constants -->
<skip /> <skip />
<!-- Importance Labels --> <!-- Importance Labels -->
<string name="importance_1">!!!!</string> <string name="importance_1">!!!!</string>
<string name="importance_2">!!!</string> <string name="importance_2">!!!</string>
<string name="importance_3">!!</string> <string name="importance_3">!!</string>
<string name="importance_4">!</string> <string name="importance_4">!</string>
<!-- Repeat Interval Labels --> <!-- Repeat Interval Labels -->
<string name="repeat_days">Tag(e)</string> <string name="repeat_days">Tag(e)</string>
<string name="repeat_weeks">Woche(n)</string> <string name="repeat_weeks">Woche(n)</string>
<string name="repeat_months">Monat(e)</string> <string name="repeat_months">Monat(e)</string>
<string name="repeat_hours">Stunde(n)</string> <string name="repeat_hours">Stunde(n)</string>
<!-- Plurals --> <!-- Plurals -->
<plurals name="Ntasks"> <plurals name="Ntasks">
<item quantity="one">1 Aufgabe</item> <item quantity="one">1 Aufgabe</item>
<item quantity="other">%d Aufgaben</item> <item quantity="other">%d Aufgaben</item>
</plurals> </plurals>
<plurals name="NactiveTasks"> <plurals name="NactiveTasks">
<item quantity="one">%d / %d Aktiv</item> <item quantity="one">%d / %d Aktiv</item>
<item quantity="other">%d / %d Aktiv</item> <item quantity="other">%d / %d Aktiv</item>
</plurals> </plurals>
<plurals name="Nalarms"> <plurals name="Nalarms">
@ -58,11 +51,11 @@
</plurals> </plurals>
<!-- Time Constants --> <!-- Time Constants -->
<string name="dateFormatter">d. MMM</string> <!-- used for long due <string name="dateFormatter">d. MMMM</string> <!-- used for long due
dates. c.f. Java's SimpleDateFormat --> dates. c.f. Java's SimpleDateFormat -->
<string name="daysVertical">D\na\ny\ns</string> <!-- vertical labels <string name="daysVertical">T\na\ng\ne</string> <!-- vertical labels
are used in the number dialogs --> are used in the number dialogs -->
<string name="hoursVertical">H\no\nu\nr\ns</string> <string name="hoursVertical">S\nt\nu\nn\nd\ne\nn</string>
<plurals name="Ndays"> <plurals name="Ndays">
<item quantity="one">1 Tag</item> <item quantity="one">1 Tag</item>
<item quantity="other">%d Tage</item> <item quantity="other">%d Tage</item>

@ -261,6 +261,7 @@ If you don\'t want to see the new task right after you complete the old one, you
<string name="p_sync_quiet">sync_dialogs</string> <string name="p_sync_quiet">sync_dialogs</string>
<string name="sync_quiet_title">Hide Dialogs</string> <string name="sync_quiet_title">Hide Dialogs</string>
<string name="sync_quiet_desc">Hide the Sync Results dialogs</string> <string name="sync_quiet_desc">Hide the Sync Results dialogs</string>
<string name="p_sync_bgwifi">sync_bgwifi</string>
<string name="sync_bgwifi_title">Auto-Sync Wifi Only</string> <string name="sync_bgwifi_title">Auto-Sync Wifi Only</string>
<string name="sync_bgwifi_desc">If set, auto-sync only happens when Wifi is active</string> <string name="sync_bgwifi_desc">If set, auto-sync only happens when Wifi is active</string>
<string name="sync_error">Sync Error! Sorry for the inconvenience! Error:</string> <string name="sync_error">Sync Error! Sorry for the inconvenience! Error:</string>
@ -276,6 +277,7 @@ occur (it is a minor drain on battery).
</string> </string>
<string name="sync_now">Synchronize Now!</string> <string name="sync_now">Synchronize Now!</string>
<string name="sync_forget">Clear Personal Data</string> <string name="sync_forget">Clear Personal Data</string>
<string name="sync_uptodate">Sync: Up to date!</string>
<string name="sync_forget_confirm">Clear data for selected services?</string> <string name="sync_forget_confirm">Clear data for selected services?</string>
<string name="sync_no_synchronizers">No Synchronizers Enabled!</string> <string name="sync_no_synchronizers">No Synchronizers Enabled!</string>
<string name="sync_last_sync">Last Sync Date: %s</string> <string name="sync_last_sync">Last Sync Date: %s</string>
@ -288,6 +290,14 @@ occur (it is a minor drain on battery).
<string name="sync_result_updated">Updated: %d</string> <string name="sync_result_updated">Updated: %d</string>
<string name="sync_result_deleted">Deleted: %d</string> <string name="sync_result_deleted">Deleted: %d</string>
<string name="sync_result_merged">Merged: %d</string> <string name="sync_result_merged">Merged: %d</string>
<string name="sync_progress_remote">Reading Remote Data</string>
<string name="sync_progress_rxlist">Reading List: %s</string>
<string name="sync_progress_repeating">Synchronizing Repeating Task</string>
<string name="sync_progress_localtx">Sending Task: %s</string>
<string name="sync_progress_localdel">Locally Deleted Tasks</string>
<string name="sync_progress_remotetx">Receiving Task: %s</string>
<!-- Dialog Boxes --> <!-- Dialog Boxes -->
<skip /> <skip />

@ -24,17 +24,19 @@ import org.w3c.dom.Element;
public class RtmList extends RtmData { public class RtmList extends RtmData {
private final String id; private final String id;
private final boolean smart;
private final String name; private final String name;
public RtmList(String id, String name) { public RtmList(String id, String name, boolean smart) {
this.id = id; this.id = id;
this.name = name; this.name = name;
this.smart = smart;
} }
public RtmList(Element elt) { public RtmList(Element elt) {
id = elt.getAttribute("id"); id = elt.getAttribute("id");
name = elt.getAttribute("name"); name = elt.getAttribute("name");
smart = elt.getAttribute("smart") == "1";
} }
public String getId() { public String getId() {
@ -44,4 +46,8 @@ public class RtmList extends RtmData {
public String getName() { public String getName() {
return name; return name;
} }
public boolean isSmart() {
return smart;
}
} }

@ -146,7 +146,26 @@ public class TagController extends AbstractController {
return saveSucessful; return saveSucessful;
} }
/** Returns a TaskModelForView corresponding to the given TaskIdentifier */ /** Returns a TaskModelForView corresponding to the given Tag Name */
public TagModelForView fetchTagFromName(String name) throws SQLException {
Cursor cursor = tagDatabase.query(true, TAG_TABLE_NAME,
TagModelForView.FIELD_LIST,
AbstractTagModel.NAME + " = ?", new String[] {name}, null, null, null, null);
try {
if (cursor != null) {
cursor.moveToFirst();
TagModelForView model = new TagModelForView(cursor);
return model;
}
return null;
} finally {
if(cursor != null)
cursor.close();
}
}
/** Returns a TaskModelForView corresponding to the given TagIdentifier */
public TagModelForView fetchTagForView(TagIdentifier tagId) throws SQLException { public TagModelForView fetchTagForView(TagIdentifier tagId) throws SQLException {
long id = tagId.getId(); long id = tagId.getId();
Cursor cursor = tagDatabase.query(true, TAG_TABLE_NAME, Cursor cursor = tagDatabase.query(true, TAG_TABLE_NAME,

@ -51,6 +51,8 @@ import com.timsu.astrid.R;
import com.timsu.astrid.activities.TaskList; import com.timsu.astrid.activities.TaskList;
import com.timsu.astrid.data.enums.Importance; import com.timsu.astrid.data.enums.Importance;
import com.timsu.astrid.data.sync.SyncMapping; import com.timsu.astrid.data.sync.SyncMapping;
import com.timsu.astrid.data.tag.TagController;
import com.timsu.astrid.data.tag.TagModelForView;
import com.timsu.astrid.data.task.AbstractTaskModel; import com.timsu.astrid.data.task.AbstractTaskModel;
import com.timsu.astrid.data.task.TaskModelForSync; import com.timsu.astrid.data.task.TaskModelForSync;
import com.timsu.astrid.utilities.DialogUtilities; import com.timsu.astrid.utilities.DialogUtilities;
@ -168,7 +170,7 @@ public class RTMSyncProvider extends SynchronizationProvider {
private void performSyncInNewThread(final Context context) { private void performSyncInNewThread(final Context context) {
try { try {
postUpdate(new ProgressLabelUpdater("Reading remote data")); postUpdate(new ProgressLabelUpdater(context, R.string.sync_progress_remote));
postUpdate(new ProgressUpdater(0, 5)); postUpdate(new ProgressUpdater(0, 5));
// get RTM timeline // get RTM timeline
@ -188,13 +190,15 @@ public class RTMSyncProvider extends SynchronizationProvider {
TaskModelForSync task = synchronizer.getTaskController(context). TaskModelForSync task = synchronizer.getTaskController(context).
fetchTaskForSync(getSingleTaskForSync()); fetchTaskForSync(getSingleTaskForSync());
localTask.readFromTaskModel(task); localTask.readFromTaskModel(task);
postUpdate(new ProgressLabelUpdater("Synchronizing repeating task")); postUpdate(new ProgressLabelUpdater(context, R.string.sync_progress_repeating));
pushLocalTask(timeline, localTask, null, mapping); pushLocalTask(timeline, localTask, null, mapping);
} }
// load RTM lists // load RTM lists
RtmLists lists = rtmService.lists_getList(); RtmLists lists = rtmService.lists_getList();
for(RtmList list : lists.getLists().values()) { for(RtmList list : lists.getLists().values()) {
if(list.isSmart())
continue;
listNameToIdMap.put(list.getName().toLowerCase(), list.getId()); listNameToIdMap.put(list.getName().toLowerCase(), list.getId());
listIdToNameMap.put(list.getId(), list.getName()); listIdToNameMap.put(list.getId(), list.getName());
@ -218,8 +222,9 @@ public class RTMSyncProvider extends SynchronizationProvider {
postUpdate(new ProgressUpdater(3, 5)); postUpdate(new ProgressUpdater(3, 5));
RtmTasks tasks = rtmService.tasks_getList(null, filter, lastSyncDate); RtmTasks tasks = rtmService.tasks_getList(null, filter, lastSyncDate);
postUpdate(new ProgressUpdater(5, 5)); postUpdate(new ProgressUpdater(5, 5));
addTasksToList(tasks, remoteChanges); addTasksToList(context, tasks, remoteChanges);
} catch (Exception e) { } catch (Exception e) {
Log.e("rtmsync", "Error sync-ing list!", e);
remoteChanges.clear(); remoteChanges.clear();
shouldSyncIndividualLists = true; shouldSyncIndividualLists = true;
} }
@ -227,21 +232,22 @@ public class RTMSyncProvider extends SynchronizationProvider {
if(shouldSyncIndividualLists) { if(shouldSyncIndividualLists) {
int progress = 0; int progress = 0;
for(final Entry<String, String> entry : listIdToNameMap.entrySet()) { for(final Entry<String, String> entry : listIdToNameMap.entrySet()) {
postUpdate(new ProgressLabelUpdater("Reading " + postUpdate(new ProgressLabelUpdater(context,
" list: " + entry.getValue())); R.string.sync_progress_rxlist, entry.getValue()));
postUpdate(new ProgressUpdater(progress++, postUpdate(new ProgressUpdater(progress++,
listIdToNameMap.size())); listIdToNameMap.size()));
try { try {
Thread.sleep(1500); Thread.sleep(1500);
RtmTasks tasks = rtmService.tasks_getList(entry.getKey(), RtmTasks tasks = rtmService.tasks_getList(entry.getKey(),
filter, lastSyncDate); filter, lastSyncDate);
addTasksToList(tasks, remoteChanges); addTasksToList(context, tasks, remoteChanges);
} catch (Exception e) { } catch (Exception e) {
Log.e("rtmsync", "Error sync-ing list!", e);
postUpdate(new Runnable() { postUpdate(new Runnable() {
public void run() { public void run() {
DialogUtilities.okDialog(context, DialogUtilities.okDialog(context,
"List '" + entry.getValue() + "Sorry, list '" + entry.getValue() +
"' import failed (too big?)", null); "' import failed. Try again later!", null);
} }
}); });
continue; continue;
@ -250,7 +256,7 @@ public class RTMSyncProvider extends SynchronizationProvider {
postUpdate(new ProgressUpdater(1, 1)); postUpdate(new ProgressUpdater(1, 1));
} }
synchronizeTasks(context, remoteChanges, new RtmSyncHelper(timeline)); synchronizeTasks(context, remoteChanges, new RtmSyncHelper(context, timeline));
// add a bit of fudge time so we don't load tasks we just edited // add a bit of fudge time so we don't load tasks we just edited
Date syncTime = new Date(System.currentTimeMillis() + 1000); Date syncTime = new Date(System.currentTimeMillis() + 1000);
@ -268,11 +274,12 @@ public class RTMSyncProvider extends SynchronizationProvider {
// --- helper methods // --- helper methods
/** Add the tasks read from RTM to the given list */ /** Add the tasks read from RTM to the given list */
private void addTasksToList(RtmTasks tasks, LinkedList<TaskProxy> list) { private void addTasksToList(Context context, RtmTasks tasks, LinkedList<TaskProxy> list) {
for(RtmTaskList taskList : tasks.getLists()) { for(RtmTaskList taskList : tasks.getLists()) {
for(RtmTaskSeries taskSeries : taskList.getSeries()) { for(RtmTaskSeries taskSeries : taskList.getSeries()) {
TaskProxy remoteTask = TaskProxy remoteTask =
parseRemoteTask(taskList.getId(), taskSeries); parseRemoteTask(taskList.getId(), taskSeries,
synchronizer.getTagController(context));
list.add(remoteTask); list.add(remoteTask);
} }
} }
@ -296,7 +303,7 @@ public class RTMSyncProvider extends SynchronizationProvider {
if(remoteTask == null) { if(remoteTask == null) {
RtmTaskSeries rtmTask = rtmService.tasks_getTask(id.taskSeriesId, task.name); RtmTaskSeries rtmTask = rtmService.tasks_getTask(id.taskSeriesId, task.name);
if(rtmTask != null) if(rtmTask != null)
remoteTask = parseRemoteTask(id.listId, rtmTask); remoteTask = parseRemoteTask(id.listId, rtmTask, null);
} }
if(remoteTask == null) if(remoteTask == null)
remoteTask = getDefaultTaskProxy(); remoteTask = getDefaultTaskProxy();
@ -339,8 +346,16 @@ public class RTMSyncProvider extends SynchronizationProvider {
// tags // tags
if(task.tags != null && !task.tags.equals(remoteTask.tags)) { if(task.tags != null && !task.tags.equals(remoteTask.tags)) {
String listName = listIdToNameMap.get(id.listId); String listName = listIdToNameMap.get(id.listId);
if(task.tags.size() > 0 && listName.equals(task.tags.getFirst()))
task.tags.remove(0); // if the first tag is the list, or _list, remove it
if(task.tags.size() > 0) {
String firstTag = task.tags.getFirst();
if(firstTag.startsWith(TagModelForView.HIDDEN_FROM_MAIN_LIST_PREFIX))
firstTag = firstTag.substring(TagModelForView.HIDDEN_FROM_MAIN_LIST_PREFIX.length());
if(firstTag.equals(listName))
task.tags.remove(0);
}
rtmService.tasks_setTags(timeline, id.listId, id.taskSeriesId, rtmService.tasks_setTags(timeline, id.listId, id.taskSeriesId,
id.taskId, task.tags.toArray(new String[task.tags.size()])); id.taskId, task.tags.toArray(new String[task.tags.size()]));
} }
@ -367,7 +382,8 @@ public class RTMSyncProvider extends SynchronizationProvider {
} }
/** Create a task proxy for the given RtmTaskSeries */ /** Create a task proxy for the given RtmTaskSeries */
private TaskProxy parseRemoteTask(String listId, RtmTaskSeries rtmTaskSeries) { private TaskProxy parseRemoteTask(String listId, RtmTaskSeries
rtmTaskSeries, TagController tagController) {
TaskProxy task = new TaskProxy(getId(), TaskProxy task = new TaskProxy(getId(),
new RtmId(listId, rtmTaskSeries).toString()); new RtmId(listId, rtmTaskSeries).toString());
@ -391,7 +407,13 @@ public class RTMSyncProvider extends SynchronizationProvider {
if(listName != null && !listName.equals(INBOX_LIST_NAME)) { if(listName != null && !listName.equals(INBOX_LIST_NAME)) {
if(tagsList == null) if(tagsList == null)
tagsList = new LinkedList<String>(); tagsList = new LinkedList<String>();
tagsList.addFirst(listName);
// if user has created a hidden version of this tag, use it
String hiddenName = TagModelForView.HIDDEN_FROM_MAIN_LIST_PREFIX + listName;
if(tagController != null && tagController.fetchTagFromName(hiddenName) != null)
tagsList.addFirst(hiddenName);
else
tagsList.addFirst(listName);
} }
if(tagsList != null) if(tagsList != null)
task.tags = tagsList; task.tags = tagsList;
@ -463,8 +485,9 @@ public class RTMSyncProvider extends SynchronizationProvider {
class RtmSyncHelper implements SynchronizeHelper { class RtmSyncHelper implements SynchronizeHelper {
private String timeline; private String timeline;
private String lastCreatedTask = null; private String lastCreatedTask = null;
private Context context;
public RtmSyncHelper(String timeline) { public RtmSyncHelper(Context context, String timeline) {
this.timeline = timeline; this.timeline = timeline;
} }
public String createTask(TaskModelForSync task) throws IOException { public String createTask(TaskModelForSync task) throws IOException {
@ -494,7 +517,7 @@ public class RTMSyncProvider extends SynchronizationProvider {
task.name); task.name);
if(rtmTask == null) if(rtmTask == null)
return task; // can't fetch return task; // can't fetch
return parseRemoteTask(id.listId, rtmTask); return parseRemoteTask(id.listId, rtmTask, synchronizer.getTagController(context));
} }
} }

@ -215,7 +215,7 @@ public abstract class SynchronizationProvider {
log.append(">> on remote server:\n"); log.append(">> on remote server:\n");
for(TaskIdentifier taskId : data.newlyCreatedTasks) { for(TaskIdentifier taskId : data.newlyCreatedTasks) {
TaskModelForSync task = taskController.fetchTaskForSync(taskId); TaskModelForSync task = taskController.fetchTaskForSync(taskId);
postUpdate(new ProgressLabelUpdater("Sending local task: " + postUpdate(new ProgressLabelUpdater(context, R.string.sync_progress_localtx,
task.getName())); task.getName()));
postUpdate(new ProgressUpdater(stats.remoteCreatedTasks, postUpdate(new ProgressUpdater(stats.remoteCreatedTasks,
data.newlyCreatedTasks.size())); data.newlyCreatedTasks.size()));
@ -250,7 +250,7 @@ public abstract class SynchronizationProvider {
} }
// 2. DELETE: find deleted tasks and remove them from the list // 2. DELETE: find deleted tasks and remove them from the list
postUpdate(new ProgressLabelUpdater("Sending locally deleted tasks")); postUpdate(new ProgressLabelUpdater(context, R.string.sync_progress_localdel));
for(TaskIdentifier taskId : data.deletedTasks) { for(TaskIdentifier taskId : data.deletedTasks) {
SyncMapping mapping = data.localIdToSyncMapping.get(taskId); SyncMapping mapping = data.localIdToSyncMapping.get(taskId);
syncController.deleteSyncMapping(mapping); syncController.deleteSyncMapping(mapping);
@ -278,7 +278,7 @@ public abstract class SynchronizationProvider {
localTask.readTagsFromController(task.getTaskIdentifier(), localTask.readTagsFromController(task.getTaskIdentifier(),
tagController, data.tags); tagController, data.tags);
postUpdate(new ProgressLabelUpdater("Sending local task: " + postUpdate(new ProgressLabelUpdater(context, R.string.sync_progress_localtx,
task.getName())); task.getName()));
postUpdate(new ProgressUpdater(stats.remoteUpdatedTasks, postUpdate(new ProgressUpdater(stats.remoteUpdatedTasks,
data.localChanges.size())); data.localChanges.size()));
@ -317,10 +317,8 @@ public abstract class SynchronizationProvider {
postUpdate(new ProgressUpdater(0, 1)); postUpdate(new ProgressUpdater(0, 1));
for(TaskProxy remoteTask : remoteTasks) { for(TaskProxy remoteTask : remoteTasks) {
if(remoteTask.name != null) if(remoteTask.name != null)
postUpdate(new ProgressLabelUpdater("Updating local " + postUpdate(new ProgressLabelUpdater(context, R.string.sync_progress_remotetx,
"tasks: " + remoteTask.name)); remoteTask.name));
else
postUpdate(new ProgressLabelUpdater("Updating local tasks"));
SyncMapping mapping = null; SyncMapping mapping = null;
TaskModelForSync task = null; TaskModelForSync task = null;
@ -527,7 +525,8 @@ public abstract class SynchronizationProvider {
mergedTasks + remoteCreatedTasks + remoteDeletedTasks + mergedTasks + remoteCreatedTasks + remoteDeletedTasks +
remoteUpdatedTasks == 0) { remoteUpdatedTasks == 0) {
if(!isBackgroundService()) if(!isBackgroundService())
DialogUtilities.okDialog(context, "Sync: Up to date!", finishListener); DialogUtilities.okDialog(context, context.getResources().
getString(R.string.sync_uptodate), finishListener);
return; return;
} }
@ -577,8 +576,8 @@ public abstract class SynchronizationProvider {
protected class ProgressLabelUpdater implements Runnable { protected class ProgressLabelUpdater implements Runnable {
String label; String label;
public ProgressLabelUpdater(String label) { public ProgressLabelUpdater(Context context, int id, Object... args) {
this.label = label; this.label = context.getResources().getString(id, args);
} }
public void run() { public void run() {
if(isBackgroundService()) { if(isBackgroundService()) {

@ -212,11 +212,10 @@ public class Synchronizer {
typeClass = cls; typeClass = cls;
} }
@SuppressWarnings("unchecked")
public TYPE get(Context context) { public TYPE get(Context context) {
if(controller == null) { if(controller == null) {
try { try {
controller = (TYPE)typeClass.getConstructors()[0].newInstance( controller = typeClass.getConstructors()[0].newInstance(
context); context);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
Log.e(getClass().getSimpleName(), e.toString()); Log.e(getClass().getSimpleName(), e.toString());

Loading…
Cancel
Save