Merge pull request #180 from sbosley/120507_sb_remove_emergent_tags

People view
pull/14/head
sbosley 14 years ago
commit 06ba019b15

@ -5,7 +5,14 @@
*/
package com.todoroo.andlib.data;
import static com.todoroo.andlib.sql.SqlConstants.COMMA;
import static com.todoroo.andlib.sql.SqlConstants.LEFT_PARENTHESIS;
import static com.todoroo.andlib.sql.SqlConstants.RIGHT_PARENTHESIS;
import static com.todoroo.andlib.sql.SqlConstants.SPACE;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Field;
import com.todoroo.andlib.sql.Operator;
/**
* Property represents a typed column in a database.
@ -150,6 +157,21 @@ public abstract class Property<TYPE> extends Field implements Cloneable {
PropertyVisitor<RETURN, PARAMETER> visitor, PARAMETER data) {
return visitor.visitString(this, data);
}
public Criterion in(final String[] value) {
final Field field = this;
return new Criterion(Operator.in) {
@Override
protected void populate(StringBuilder sb) {
sb.append(field).append(SPACE).append(Operator.in).append(SPACE).append(LEFT_PARENTHESIS).append(SPACE);
for (String s : value) {
sb.append("\"").append(s.toString()).append("\"").append(COMMA);
}
sb.deleteCharAt(sb.length() - 1).append(RIGHT_PARENTHESIS);
}
};
}
}
/**

@ -11,7 +11,7 @@ import static com.todoroo.andlib.sql.SqlConstants.SPACE;
public abstract class Criterion {
protected final Operator operator;
Criterion(Operator operator) {
public Criterion(Operator operator) {
this.operator = operator;
}

@ -2,24 +2,24 @@ package com.todoroo.andlib.sql;
@SuppressWarnings("nls")
public final class SqlConstants {
static final String SELECT = "SELECT";
static final String DISTINCT = "DISTINCT";
static final String SPACE = " ";
static final String AS = "AS";
static final String COMMA = ",";
static final String FROM = "FROM";
static final String ON = "ON";
static final String JOIN = "JOIN";
static final String ALL = "*";
static final String LEFT_PARENTHESIS = "(";
static final String RIGHT_PARENTHESIS = ")";
static final String AND = "AND";
static final String BETWEEN = "BETWEEN";
static final String LIKE = "LIKE";
static final String OR = "OR";
static final String ORDER_BY = "ORDER BY";
static final String GROUP_BY = "GROUP BY";
static final String WHERE = "WHERE";
public static final String SELECT = "SELECT";
public static final String DISTINCT = "DISTINCT";
public static final String SPACE = " ";
public static final String AS = "AS";
public static final String COMMA = ",";
public static final String FROM = "FROM";
public static final String ON = "ON";
public static final String JOIN = "JOIN";
public static final String ALL = "*";
public static final String LEFT_PARENTHESIS = "(";
public static final String RIGHT_PARENTHESIS = ")";
public static final String AND = "AND";
public static final String BETWEEN = "BETWEEN";
public static final String LIKE = "LIKE";
public static final String OR = "OR";
public static final String ORDER_BY = "ORDER BY";
public static final String GROUP_BY = "GROUP BY";
public static final String WHERE = "WHERE";
public static final String EXISTS = "EXISTS";
public static final String NOT = "NOT";
public static final String LIMIT = "LIMIT";

@ -8,6 +8,7 @@ package com.todoroo.astrid.data;
import android.content.ContentValues;
import android.net.Uri;
import android.text.TextUtils;
import com.todoroo.andlib.data.AbstractModel;
import com.todoroo.andlib.data.Property;
@ -91,6 +92,13 @@ public final class User extends RemoteModel {
super.readPropertiesFromCursor(cursor);
}
public String getDisplayName() {
String name = getValue(NAME);
if (!TextUtils.isEmpty(name))
return name;
return getValue(EMAIL);
}
@Override
public long getId() {
return getIdHelper(ID);

@ -320,6 +320,16 @@
<activity android:name="com.todoroo.astrid.tags.TagFilterExposer$DeleteTagActivity" android:theme="@style/Theme.FullTransparent" />
<activity android:name="com.todoroo.astrid.tags.TagFilterExposer$RenameTagActivity" android:theme="@style/Theme.FullTransparent" />
<!-- People view -->
<receiver android:name="com.todoroo.astrid.people.PeopleFilterExposer">
<intent-filter>
<action android:name="com.timsu.astrid.REQUEST_PEOPLE_FILTERS"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
<activity android:name="com.todoroo.astrid.people.PeopleViewActivity"
android:windowSoftInputMode="stateHidden|adjustResize"/>
<!-- alarms -->
<receiver android:name="com.todoroo.astrid.alarms.AlarmTaskRepeatListener">
<intent-filter>

@ -241,7 +241,7 @@ public class EditPeopleControlSet extends PopupControlSet {
@Override
public void run() {
ArrayList<JSONObject> collaborators = new ArrayList<JSONObject>();
TodorooCursor<Metadata> tags = TagService.getInstance().getTags(task.getId());
TodorooCursor<Metadata> tags = TagService.getInstance().getTags(task.getId(), true);
try {
Metadata metadata = new Metadata();
for(tags.moveToFirst(); !tags.isAfterLast(); tags.moveToNext()) {

@ -394,7 +394,7 @@ public final class ActFmSyncService {
}
if(Flags.checkAndClear(Flags.TAGS_CHANGED) || newlyCreated) {
TodorooCursor<Metadata> cursor = TagService.getInstance().getTags(task.getId());
TodorooCursor<Metadata> cursor = TagService.getInstance().getTags(task.getId(), false);
try {
if(cursor.getCount() == 0) {
params.add("tags");
@ -740,6 +740,10 @@ public final class ActFmSyncService {
}, done, "tasks:" + tagData.getId(), "tag_id", tagData.getValue(TagData.REMOTE_ID));
}
public void fetchTasksForUser(final User user, final boolean manual, Runnable done) {
invokeFetchList("task", manual, null, new TaskListItemProcessor(false),
done, "user_" + user.getId(), "user_id", user.getValue(User.REMOTE_ID));
}
/**

@ -25,6 +25,7 @@ import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.RemoteModel;
import com.todoroo.astrid.data.TagData;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.User;
import com.todoroo.astrid.service.AstridDependencyInjector;
import com.todoroo.astrid.service.TagDataService;
import com.todoroo.astrid.service.TaskService;
@ -273,6 +274,11 @@ public class ActFmSyncV2Provider extends SyncV2Provider {
public void synchronizeList(Object list, final boolean manual,
final SyncResultCallback callback) {
if (list instanceof User) {
synchronizeUser((User) list, manual, callback);
return;
}
if(!(list instanceof TagData))
return;
@ -299,6 +305,27 @@ public class ActFmSyncV2Provider extends SyncV2Provider {
}).start();
}
private void synchronizeUser(final User user, final boolean manual, final SyncResultCallback callback) {
if (user.getValue(User.REMOTE_ID) == 0)
return;
new Thread(new Runnable() {
@Override
public void run() {
callback.started();
callback.incrementMax(100);
actFmSyncService.waitUntilEmpty();
actFmSyncService.fetchTasksForUser(user, manual, new Runnable() {
public void run() {
callback.finished();
}
});
callback.incrementProgress(50);
}
}).start();
}
private void fetchTagData(final TagData tagData, final boolean noRemoteId,
final boolean manual, final SyncResultCallback callback,
final AtomicInteger finisher) {

@ -8,6 +8,7 @@ import com.todoroo.andlib.sql.Query;
import com.todoroo.astrid.dao.Database;
import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria;
import com.todoroo.astrid.dao.StoreObjectDao;
import com.todoroo.astrid.dao.UserDao;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.service.AddOnService;
import com.todoroo.astrid.service.AstridDependencyInjector;
@ -44,6 +45,9 @@ public final class PluginServices {
@Autowired
StoreObjectDao storeObjectDao;
@Autowired
UserDao userDao;
private static PluginServices instance;
static {
@ -86,6 +90,10 @@ public final class PluginServices {
return getInstance().storeObjectDao;
}
public static UserDao getUserDao() {
return getInstance().userDao;
}
// -- helpers
/**

@ -0,0 +1,38 @@
package com.todoroo.astrid.people;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentFilter;
import android.widget.ListView;
import com.todoroo.astrid.adapter.FilterAdapter;
import com.todoroo.astrid.utility.Constants;
public class PeopleFilterAdapter extends FilterAdapter {
public static final String BROADCAST_REQUEST_PEOPLE_FILTERS = Constants.PACKAGE + ".REQUEST_PEOPLE_FILTERS"; //$NON-NLS-1$
public static final String BROADCAST_SEND_PEOPLE_FILTERS = Constants.PACKAGE + ".SEND_PEOPLE_FILTERS"; //$NON-NLS-1$
public PeopleFilterAdapter(Activity activity, ListView listView,
int rowLayout, boolean skipIntentFilters) {
super(activity, listView, rowLayout, skipIntentFilters);
}
@Override
public void getLists() {
Intent broadcastIntent = new Intent(BROADCAST_REQUEST_PEOPLE_FILTERS);
activity.sendBroadcast(broadcastIntent);
}
@Override
public void registerRecevier() {
IntentFilter peopleFilter = new IntentFilter(BROADCAST_SEND_PEOPLE_FILTERS);
activity.registerReceiver(filterReceiver, peopleFilter);
getLists();
}
@Override
public void unregisterRecevier() {
activity.unregisterReceiver(filterReceiver);
}
}

@ -0,0 +1,142 @@
package com.todoroo.astrid.people;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import com.timsu.astrid.R;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Field;
import com.todoroo.andlib.sql.Join;
import com.todoroo.andlib.sql.Order;
import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.sql.QueryTemplate;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.astrid.actfm.sync.ActFmSyncService;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.FilterListItem;
import com.todoroo.astrid.api.FilterWithCustomIntent;
import com.todoroo.astrid.api.FilterWithUpdate;
import com.todoroo.astrid.core.PluginServices;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.TagData;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.User;
import com.todoroo.astrid.tags.TagService;
public class PeopleFilterExposer extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
FilterListItem[] listAsArray = prepareFilters(context);
Intent broadcastIntent = new Intent(PeopleFilterAdapter.BROADCAST_SEND_PEOPLE_FILTERS);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, listAsArray);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, "people"); //$NON-NLS-1$
context.sendBroadcast(broadcastIntent);
}
private FilterListItem[] prepareFilters(Context context) {
TodorooCursor<User> users = PluginServices.getUserDao().query(Query.select(User.PROPERTIES)
.orderBy(Order.asc(User.NAME), Order.asc(User.EMAIL)));
try {
FilterListItem[] items = new FilterListItem[users.getCount() + 1];
items[0] = mySharedTasks(context);
User user = new User();
int i = 1;
for (users.moveToFirst(); !users.isAfterLast(); users.moveToNext()) {
user.readFromCursor(users);
Filter currFilter = filterFromUserData(user);
items[i] = currFilter;
i++;
}
return items;
} finally {
users.close();
}
}
@SuppressWarnings("nls")
public static FilterWithCustomIntent filterFromUserData(User user) {
String email = user.getValue(User.EMAIL);
String title = user.getDisplayName();
QueryTemplate userTemplate = new QueryTemplate().where(
Criterion.or(Task.USER.like("%" + email + "%"),
Task.USER_ID.eq(user.getValue(User.REMOTE_ID))));
FilterWithUpdate filter = new FilterWithUpdate(title, title, userTemplate, null);
filter.customTaskList = new ComponentName(ContextManager.getContext(), PersonViewFragment.class);
ContentValues values = new ContentValues();
values.put(Task.USER_ID.name, user.getValue(User.REMOTE_ID));
try {
JSONObject userJson = new JSONObject();
ActFmSyncService.JsonHelper.jsonFromUser(userJson, user);
values.put(Task.USER.name, userJson.toString());
} catch (JSONException e) {
// Ignored
}
filter.valuesForNewTasks = values;
String imageUrl = user.getValue(User.PICTURE);
filter.imageUrl = imageUrl;
Bundle extras = new Bundle();
extras.putLong(PersonViewFragment.EXTRA_USER_ID_LOCAL, user.getId());
filter.customExtras = extras;
return filter;
}
@SuppressWarnings("nls")
public static FilterWithCustomIntent mySharedTasks(Context context) {
AndroidUtilities.copyDatabases(context, "/sdcard/databases");
TodorooCursor<TagData> tagsWithMembers = PluginServices.getTagDataService()
.query(Query.select(TagData.NAME, TagData.MEMBERS).where(TagData.MEMBER_COUNT.gt(0)));
String[] names;
try {
if (tagsWithMembers.getCount() == 0) {
names = new String[1];
names[0] = "\"\"";
} else {
names = new String[tagsWithMembers.getCount()];
TagData curr = new TagData();
int i = 0;
for (tagsWithMembers.moveToFirst(); !tagsWithMembers.isAfterLast(); tagsWithMembers.moveToNext()) {
curr.readFromCursor(tagsWithMembers);
names[i] = "\"" + curr.getValue(TagData.NAME) + "\"";
System.err.println("Tag data " + curr.getValue(TagData.NAME) + " has members " + curr.getValue(TagData.MEMBERS));
i++;
}
}
} finally {
tagsWithMembers.close();
}
String title = context.getString(R.string.actfm_my_shared_tasks_title);
QueryTemplate template = new QueryTemplate().join(Join.inner(Metadata.TABLE.as("mtags"),
Criterion.and(Task.ID.eq(Field.field("mtags." + Metadata.TASK.name)),
Field.field("mtags." + Metadata.KEY.name).eq(TagService.KEY),
Field.field("mtags." + TagService.TAG.name).in(names))));
FilterWithUpdate filter = new FilterWithUpdate(title, title, template, null);
filter.customTaskList = new ComponentName(ContextManager.getContext(), PersonViewFragment.class);
Bundle extras = new Bundle();
extras.putBoolean(PersonViewFragment.EXTRA_HIDE_QUICK_ADD, true);
filter.customExtras = extras;
return filter;
}
}

@ -0,0 +1,24 @@
package com.todoroo.astrid.people;
import android.app.Activity;
import com.timsu.astrid.R;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.astrid.activity.FilterListFragment;
import com.todoroo.astrid.adapter.FilterAdapter;
public class PeopleListFragment extends FilterListFragment {
@Override
protected FilterAdapter instantiateAdapter() {
return new PeopleFilterAdapter(getActivity(), null, R.layout.filter_adapter_row, false);
}
@Override
protected int getLayout(Activity activity) {
if (AndroidUtilities.isTabletSized(activity))
return R.layout.people_list_fragment_3pane;
else
return R.layout.people_list_fragment;
}
}

@ -0,0 +1,79 @@
package com.todoroo.astrid.people;
import android.content.Intent;
import android.os.Bundle;
import com.timsu.astrid.R;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.astrid.activity.FilterListFragment;
import com.todoroo.astrid.activity.TaskListActivity;
import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.FilterListItem;
import com.todoroo.astrid.api.FilterWithUpdate;
import com.todoroo.astrid.helper.AsyncImageView;
import com.todoroo.astrid.ui.MainMenuPopover;
public class PeopleViewActivity extends TaskListActivity {
private AsyncImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
imageView = (AsyncImageView) findViewById(R.id.person_image);
imageView.setDefaultImageResource(R.drawable.icn_default_person_image);
}
@Override
protected int getContentView() {
return R.layout.people_view_wrapper_activity;
}
@Override
protected Filter getDefaultFilter() {
return PeopleFilterExposer.mySharedTasks(this);
}
@Override
protected Class<? extends FilterListFragment> getFilterListClass() {
return PeopleListFragment.class;
}
@Override
protected int getHeaderView() {
return R.layout.header_people_view;
}
@Override
public boolean onFilterItemClicked(FilterListItem item) {
boolean result = super.onFilterItemClicked(item);
if (result && item instanceof FilterWithUpdate)
imageView.setUrl(((FilterWithUpdate) item).imageUrl);
else
imageView.setUrl(null);
return result;
}
private static final int[] FORBIDDEN_MENU_ITEMS = {
TaskListFragment.MENU_NEW_FILTER_ID,
TaskListFragment.MENU_ADDONS_ID,
MainMenuPopover.MAIN_MENU_ITEM_FRIENDS
};
@Override
public boolean shouldAddMenuItem(int itemId) {
return AndroidUtilities.indexOf(FORBIDDEN_MENU_ITEMS, itemId) < 0;
}
@Override
public void mainMenuItemSelected(int item, Intent customIntent) {
if (item == MainMenuPopover.MAIN_MENU_ITEM_LISTS) {
finish();
return;
}
super.mainMenuItemSelected(item, customIntent);
}
}

@ -0,0 +1,129 @@
package com.todoroo.astrid.people;
import android.content.Intent;
import android.support.v4.view.Menu;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.timsu.astrid.R;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.actfm.sync.ActFmPreferenceService;
import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.dao.UserDao;
import com.todoroo.astrid.data.User;
import com.todoroo.astrid.helper.ProgressBarSyncResultCallback;
import com.todoroo.astrid.service.SyncV2Service;
import com.todoroo.astrid.service.ThemeService;
public class PersonViewFragment extends TaskListFragment {
public static final String EXTRA_USER_ID_LOCAL = "user_local_id"; //$NON-NLS-1$
public static final String EXTRA_HIDE_QUICK_ADD = "hide_quickAdd"; //$NON-NLS-1$
private static final String LAST_FETCH_KEY = "actfm_last_user_"; //$NON-NLS-1$
protected static final int MENU_REFRESH_ID = MENU_SUPPORT_ID + 1;
@Autowired UserDao userDao;
@Autowired SyncV2Service syncService;
@Autowired ActFmPreferenceService actFmPreferenceService;
protected View taskListView;
private User user;
@Override
protected View getListBody(ViewGroup root) {
ViewGroup parent = (ViewGroup) getActivity().getLayoutInflater().inflate(R.layout.task_list_body_person, root, false);
taskListView = super.getListBody(parent);
parent.addView(taskListView);
return parent;
}
@Override
protected void initializeData() {
super.initializeData();
if (extras.containsKey(EXTRA_USER_ID_LOCAL)) {
user = userDao.fetch(extras.getLong(EXTRA_USER_ID_LOCAL), User.PROPERTIES);
}
((TextView)taskListView.findViewById(android.R.id.empty)).setText(getEmptyDisplayString());
}
@Override
protected void setupQuickAddBar() {
super.setupQuickAddBar();
quickAddBar.setUsePeopleControl(false);
if (user != null)
quickAddBar.getQuickAddBox().setHint(getString(R.string.TLA_quick_add_hint_assign, user.getDisplayName()));
if (extras.containsKey(EXTRA_HIDE_QUICK_ADD))
quickAddBar.setVisibility(View.GONE);
}
@Override
protected void addSyncRefreshMenuItem(Menu menu, int themeFlags) {
if(actFmPreferenceService.isLoggedIn()) {
addMenuItem(menu, R.string.actfm_TVA_menu_refresh,
ThemeService.getDrawable(R.drawable.icn_menu_refresh, themeFlags), MENU_REFRESH_ID, true);
} else {
super.addSyncRefreshMenuItem(menu, themeFlags);
}
}
@Override
public boolean handleOptionsMenuItemSelected(int id, Intent intent) {
switch (id) {
case MENU_REFRESH_ID:
refreshData(true);
return true;
}
return super.handleOptionsMenuItemSelected(id, intent);
}
@Override
protected void initiateAutomaticSyncImpl() {
if (!isCurrentTaskListFragment())
return;
if (user != null) {
long lastAutoSync = Preferences.getLong(LAST_FETCH_KEY + user.getId(), 0);
if (DateUtilities.now() - lastAutoSync > DateUtilities.ONE_HOUR)
refreshData(false);
}
}
private void refreshData(final boolean manual) {
if (user != null) {
((TextView)taskListView.findViewById(android.R.id.empty)).setText(R.string.DLG_loading);
syncService.synchronizeList(user, manual, new ProgressBarSyncResultCallback(getActivity(), this,
R.id.progressBar, new Runnable() {
@Override
public void run() {
if (manual)
ContextManager.getContext().sendBroadcast(new Intent(AstridApiConstants.BROADCAST_EVENT_REFRESH));
else
refresh();
((TextView)taskListView.findViewById(android.R.id.empty)).setText(getEmptyDisplayString());
}
}));
}
}
private String getEmptyDisplayString() {
String userName = user != null ? user.getDisplayName() : null;
return TextUtils.isEmpty(userName) ? getString(R.string.actfm_my_shared_tasks_empty) : getString(R.string.TLA_no_items_person, userName);
}
}

@ -38,7 +38,7 @@ public class TagCaseMigrator {
public void performTagCaseMigration(@SuppressWarnings("unused") Context context) {
if (!Preferences.getBoolean(PREF_CASE_MIGRATION_PERFORMED, false)) {
TagService.Tag[] allTagData = TagService.getInstance().getGroupedTags(
TagService.GROUPED_TAGS_BY_ALPHA, Criterion.all);
TagService.GROUPED_TAGS_BY_ALPHA, Criterion.all, false);
boolean shouldShowDialog = false;
for (int i = 0; i < allTagData.length - 1; i++) {

@ -35,7 +35,7 @@ public class TagCustomFilterCriteriaExposer extends BroadcastReceiver {
// built in criteria: tags
{
TagService.Tag[] tags = TagService.getInstance().getGroupedTags(TagService.GROUPED_TAGS_BY_SIZE,
TaskDao.TaskCriteria.activeAndVisible());
TaskDao.TaskCriteria.activeAndVisible(), false);
String[] tagNames = new String[tags.length];
for(int i = 0; i < tags.length; i++)
tagNames[i] = tags[i].tag;

@ -37,7 +37,7 @@ public class TagDetailExposer extends BroadcastReceiver {
}
public String getTaskDetails(long id) {
String tagList = TagService.getInstance().getTagsAsString(id);
String tagList = TagService.getInstance().getTagsAsString(id, false);
if(tagList.length() == 0)
return null;

@ -193,10 +193,15 @@ public final class TagService {
* @param activeStatus criterion for specifying completed or uncompleted
* @return empty array if no tags, otherwise array
*/
public Tag[] getGroupedTags(Order order, Criterion activeStatus) {
public Tag[] getGroupedTags(Order order, Criterion activeStatus, boolean includeEmergent) {
Criterion criterion;
if (includeEmergent)
criterion = Criterion.and(activeStatus, MetadataCriteria.withKey(KEY));
else
criterion = Criterion.and(activeStatus, MetadataCriteria.withKey(KEY), Criterion.not(TAG.in(getEmergentTags())));
Query query = Query.select(TAG, REMOTE_ID, COUNT).
join(Join.inner(Task.TABLE, Metadata.TASK.eq(Task.ID))).
where(Criterion.and(activeStatus, MetadataCriteria.withKey(KEY))).
where(criterion).
orderBy(order).groupBy(TAG);
TodorooCursor<Metadata> cursor = metadataDao.query(query);
try {
@ -211,15 +216,38 @@ public final class TagService {
}
}
private String[] getEmergentTags() {
TodorooCursor<TagData> emergent = tagDataService.query(Query.select(TagData.NAME)
.where(Functions.bitwiseAnd(TagData.FLAGS, TagData.FLAG_EMERGENT).gt(0)));
try {
String[] tags = new String[emergent.getCount()];
TagData data = new TagData();
for (int i = 0; i < emergent.getCount(); i++) {
emergent.moveToPosition(i);
data.readFromCursor(emergent);
tags[i] = data.getValue(TagData.NAME);
}
return tags;
} finally {
emergent.close();
}
}
/**
* Return tags on the given task
*
* @param taskId
* @return cursor. PLEASE CLOSE THE CURSOR!
*/
public TodorooCursor<Metadata> getTags(long taskId) {
Query query = Query.select(TAG, REMOTE_ID).where(Criterion.and(MetadataCriteria.withKey(KEY),
MetadataCriteria.byTask(taskId))).orderBy(Order.asc(Functions.upper(TAG)));
public TodorooCursor<Metadata> getTags(long taskId, boolean includeEmergent) {
Criterion criterion;
if (includeEmergent)
criterion = Criterion.and(MetadataCriteria.withKey(KEY),
MetadataCriteria.byTask(taskId));
else
criterion = Criterion.and(MetadataCriteria.withKey(KEY),
MetadataCriteria.byTask(taskId), Criterion.not(TAG.in(getEmergentTags())));
Query query = Query.select(TAG, REMOTE_ID).where(criterion).orderBy(Order.asc(Functions.upper(TAG)));
return metadataDao.query(query);
}
@ -229,8 +257,8 @@ public final class TagService {
* @param taskId
* @return empty string if no tags, otherwise string
*/
public String getTagsAsString(long taskId) {
return getTagsAsString(taskId, ", ");
public String getTagsAsString(long taskId, boolean includeEmergent) {
return getTagsAsString(taskId, ", ", includeEmergent);
}
/**
@ -239,9 +267,9 @@ public final class TagService {
* @param taskId
* @return empty string if no tags, otherwise string
*/
public String getTagsAsString(long taskId, String separator) {
protected String getTagsAsString(long taskId, String separator, boolean includeEmergent) {
StringBuilder tagBuilder = new StringBuilder();
TodorooCursor<Metadata> tags = getTags(taskId);
TodorooCursor<Metadata> tags = getTags(taskId, includeEmergent);
try {
int length = tags.getCount();
Metadata metadata = new Metadata();
@ -285,7 +313,7 @@ public final class TagService {
HashMap<String, Tag> tags = new HashMap<String, Tag>();
Tag[] tagsByAlpha = getGroupedTags(TagService.GROUPED_TAGS_BY_ALPHA,
TaskCriteria.activeAndVisible());
TaskCriteria.activeAndVisible(), false);
for(Tag tag : tagsByAlpha)
if(!TextUtils.isEmpty(tag.tag))
tags.put(tag.tag, tag);
@ -297,7 +325,7 @@ public final class TagService {
tagData.readFromCursor(cursor);
String tagName = tagData.getValue(TagData.NAME).trim();
Tag tag = new Tag(tagData);
if(tagData.getValue(TagData.DELETION_DATE) > 0) {
if(tagData.getValue(TagData.DELETION_DATE) > 0 || tagData.getFlag(TagData.FLAGS, TagData.FLAG_EMERGENT)) {
tags.remove(tagName);
continue;
}

@ -223,7 +223,7 @@ public final class TagsControlSet extends PopupControlSet {
public void readFromTask(Task task) {
super.readFromTask(task);
if(model.getId() != AbstractModel.NO_ID) {
TodorooCursor<Metadata> cursor = tagService.getTags(model.getId());
TodorooCursor<Metadata> cursor = tagService.getTags(model.getId(), false);
LinkedHashSet<String> tags = new LinkedHashSet<String>(cursor.getCount());
try {
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_selected="false" android:drawable="@drawable/people_menu_button_blue_off"/>
<item android:state_selected="true" android:drawable="@drawable/people_menu_button_blue_on"/>
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_selected="false" android:drawable="@drawable/people_menu_button_dark_blue_off"/>
<item android:state_selected="true" android:drawable="@drawable/people_menu_button_dark_blue_on"/>
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_selected="false" android:drawable="@drawable/people_menu_button_red_off"/>
<item android:state_selected="true" android:drawable="@drawable/people_menu_button_red_on"/>
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/main_menu"
android:layout_width="51dip"
android:layout_height="fill_parent"
android:src="?attr/asPeopleMenu"
android:scaleType="fitCenter"/>
<View
android:layout_width="1px"
android:layout_height="fill_parent"
android:layout_marginLeft="-1px"
android:background="?attr/asSeparatorBackground"
android:layout_marginBottom="4dip"
android:layout_marginTop="4dip"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical">
<RelativeLayout
android:id="@+id/lists_nav"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="5dip"
android:paddingRight="5dip"
android:paddingLeft="5dip"
android:gravity="center_vertical">
<TextView
android:id="@+id/list_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="@string/BFE_Active"
android:singleLine="true"
android:layout_weight="1"
android:ellipsize="end"
style="@style/TextAppearance.ActionBar_ListsHeader"/>
<ImageView
android:id="@+id/list_disclosure_arrow"
android:layout_width="12dip"
android:layout_height="12dip"
android:layout_marginLeft="10dip"
android:layout_toRightOf="@id/list_title"
android:layout_alignBottom="@id/list_title"
android:src="?attr/asListsDisclosure"
android:scaleType="fitCenter"/>
</RelativeLayout>
</LinearLayout>
<com.todoroo.astrid.helper.AsyncImageView
android:id="@+id/person_image"
android:layout_width="51dip"
android:layout_height="fill_parent"
android:scaleType="centerCrop"/>
<Button
android:id="@+id/comments"
android:layout_width="51dip"
android:layout_height="fill_parent"
android:background="?attr/asCommentButtonImg"
android:textColor="@android:color/white"
android:paddingBottom="6dip"
android:visibility="gone"/>
</LinearLayout>

@ -2,8 +2,9 @@
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<ScrollView
android:layout_width="280dip"
android:layout_height="340dip"
android:layout_height="wrap_content"
android:layout_below="@+id/gdi_arrow_up"
android:paddingBottom="3dip"
android:background="?attr/asListPopoverBg">
<LinearLayout
android:layout_width="wrap_content"

@ -0,0 +1,20 @@
<?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:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="?attr/asListPopoverBg"
android:orientation="vertical">
<!-- List -->
<ListView android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="370dip"
android:layout_alignParentTop="true"
android:scrollbars="vertical"
android:divider="@android:color/transparent"
android:cacheColorHint="#00000000"/>
</LinearLayout>

@ -0,0 +1,20 @@
<?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:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="?attr/asListPopoverBg"
android:orientation="vertical">
<!-- List -->
<ListView android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentTop="true"
android:scrollbars="vertical"
android:divider="@android:color/transparent"
android:cacheColorHint="#00000000"/>
</LinearLayout>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="@style/Content"
android:id="@+id/tasklist_fragment_container">
</FrameLayout>

@ -0,0 +1,11 @@
<?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="wrap_content"
android:layout_weight="100">
<!-- List body goes here -->
</LinearLayout>

@ -30,6 +30,7 @@
<attr name="asTaskEditArrow" format="reference" />
<attr name="asRepeatIcon" format="reference" />
<attr name="asMainMenu" format="reference" />
<attr name="asPeopleMenu" format="reference" />
<attr name="asAbBackgroundColor" format="color"/>
<attr name="asListPopoverBg" format="reference"/>
<attr name="asListArrowUp" format="reference"/>

@ -46,6 +46,12 @@
<!-- Cancel button for task view prompt -->
<string name="actfm_view_task_cancel">Stay Here</string>
<!-- Title for the "My Shared Tasks" filter -->
<string name="actfm_my_shared_tasks_title">My Shared Tasks</string>
<!-- Empty list for the "My Shared Tasks" filter -->
<string name="actfm_my_shared_tasks_empty">No shared tasks</string>
<!-- ================================================== TagViewActivity == -->
<!-- Tag View Activity: Add Comment hint -->

@ -100,6 +100,9 @@
<!-- Task List: Displayed instead of list when no items present -->
<string name="TLA_no_items">You have no tasks! \n Want to add something?</string>
<!-- Task List: Displayed instead of list when no items present in people view (%s-> person's name) -->
<string name="TLA_no_items_person">%s has no\ntasks shared with you</string>
<!-- Menu: Add-ons -->
<string name="TLA_menu_addons">Add-ons</string>
@ -139,7 +142,7 @@
<!-- Quick Add Edit Box Hint-->
<string name="TLA_quick_add_hint">Add a task</string>
<!-- Quick Add Edit Box Hint for assigning -->
<!-- Quick Add Edit Box Hint for assigning (%s -> name)-->
<string name="TLA_quick_add_hint_assign">Tap to assign %s a task</string>
<!-- Notification Volumne notification-->

@ -27,6 +27,7 @@
<item name="asEditRowBackground">@drawable/task_edit_background</item>
<item name="asEditTabBackground">@drawable/custom_tab_indicator_dark</item>
<item name="asMainMenu">@drawable/menu_button_blue</item>
<item name="asPeopleMenu">@drawable/people_menu_button_blue</item>
<item name="asThemeTextColor">@color/blue_theme_color</item>
<item name="asListsDisclosure">@drawable/lists_disclosure_blue</item>
<item name="asAbBackgroundColor">#000000</item>
@ -75,6 +76,7 @@
<item name="asEditRowBackground">@drawable/task_edit_background_white</item>
<item name="asEditTabBackground">@drawable/custom_tab_indicator</item>
<item name="asMainMenu">@drawable/menu_button_red</item>
<item name="asPeopleMenu">@drawable/people_menu_button_red</item>
<item name="asThemeTextColor">@color/red_theme_color</item>
<item name="asListsDisclosure">@drawable/lists_disclosure_red</item>
<item name="asTaskEditArrow">@drawable/taskedit_arrow_up_white</item>
@ -96,6 +98,7 @@
<item name="asCommentButtonImg">@drawable/comment_dark_blue</item>
<item name="asFilledCommentButtonImg">@drawable/comment_dark_blue_filled</item>
<item name="asMainMenu">@drawable/menu_button_dark_blue</item>
<item name="asPeopleMenu">@drawable/people_menu_button_dark_blue</item>
<item name="asThemeTextColor">@color/dark_blue_theme_color</item>
<item name="asListsDisclosure">@drawable/lists_disclosure_dark_blue</item>
<item name="asRepeatIcon">@drawable/icn_edit_repeats_dark_blue</item>

@ -302,10 +302,10 @@ public class AstridActivity extends FragmentActivity
}
}
protected Fragment setupFragment(String tag, int container, Class<? extends Fragment> cls, boolean createImmediate) {
protected Fragment setupFragment(String tag, int container, Class<? extends Fragment> cls, boolean createImmediate, boolean replace) {
final FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentByTag(tag);
if(fragment == null) {
if(fragment == null || replace) {
try {
fragment = cls.newInstance();
} catch (InstantiationException e) {

@ -118,14 +118,18 @@ public class FilterListFragment extends ListFragment {
// Check that the container activity has implemented the callback interface
try {
mListener = (OnFilterItemClickedListener) activity;
adapter = new FilterAdapter(getActivity(), null,
R.layout.filter_adapter_row, false);
adapter = instantiateAdapter();
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFilterItemClickedListener"); //$NON-NLS-1$
}
}
protected FilterAdapter instantiateAdapter() {
return new FilterAdapter(getActivity(), null,
R.layout.filter_adapter_row, false);
}
/* (non-Javadoc)
* @see com.todoroo.astrid.fragment.ExpandableListFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)
*/
@ -133,15 +137,18 @@ public class FilterListFragment extends ListFragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Activity activity = getActivity();
int layout;
if (AndroidUtilities.isTabletSized(activity))
layout = R.layout.filter_list_activity_3pane;
else
layout = R.layout.filter_list_activity;
int layout = getLayout(activity);
ViewGroup parent = (ViewGroup) activity.getLayoutInflater().inflate(layout, container, false);
return parent;
}
protected int getLayout(Activity activity) {
if (AndroidUtilities.isTabletSized(activity))
return R.layout.filter_list_activity_3pane;
else
return R.layout.filter_list_activity;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
@ -152,6 +159,7 @@ public class FilterListFragment extends ListFragment {
//ImageView backButton = (ImageView) getView().findViewById(R.id.back);
newListButton = getView().findViewById(R.id.new_list_button);
if (newListButton != null)
newListButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {

@ -44,6 +44,8 @@ import com.todoroo.astrid.api.FilterListItem;
import com.todoroo.astrid.core.CoreFilterExposer;
import com.todoroo.astrid.core.CustomFilterExposer;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.people.PeopleListFragment;
import com.todoroo.astrid.people.PeopleViewActivity;
import com.todoroo.astrid.service.StatisticsConstants;
import com.todoroo.astrid.service.StatisticsService;
import com.todoroo.astrid.service.ThemeService;
@ -68,6 +70,8 @@ public class TaskListActivity extends AstridActivity implements MainMenuListener
public static final String OPEN_TASK = "openTask"; //$NON-NLS-1$
private static final String PEOPLE_VIEW = "peopleView"; //$NON-NLS-1$
@Autowired private ABTestEventReportingService abTestEventReportingService;
private View listsNav;
@ -147,19 +151,15 @@ public class TaskListActivity extends AstridActivity implements MainMenuListener
super.onCreate(savedInstanceState);
DependencyInjectionService.getInstance().inject(this);
if (AndroidUtilities.isTabletSized(this)) {
setContentView(R.layout.task_list_wrapper_activity_3pane);
} else if (Preferences.getIntegerFromString(R.string.p_swipe_lists_performance_key, 3) == 0) {
setContentView(R.layout.task_list_wrapper_activity_no_swipe);
} else {
setContentView(R.layout.task_list_wrapper_activity);
int contentView = getContentView();
if (contentView == R.layout.task_list_wrapper_activity)
swipeEnabled = true;
}
setContentView(contentView);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
actionBar.setCustomView(R.layout.header_nav_views);
actionBar.setCustomView(getHeaderView());
listsNav = actionBar.getCustomView().findViewById(R.id.lists_nav);
listsNavDisclosure = (ImageView) actionBar.getCustomView().findViewById(R.id.list_disclosure_arrow);
@ -176,6 +176,7 @@ public class TaskListActivity extends AstridActivity implements MainMenuListener
if (extras != null)
extras = (Bundle) extras.clone();
Filter savedFilter = getIntent().getParcelableExtra(TaskListFragment.TOKEN_FILTER);
if (Intent.ACTION_SEARCH.equals(getIntent().getAction())) {
String query = getIntent().getStringExtra(SearchManager.QUERY).trim();
@ -185,14 +186,14 @@ public class TaskListActivity extends AstridActivity implements MainMenuListener
"%" + //$NON-NLS-1$
query.toUpperCase() + "%")), //$NON-NLS-1$
null);
if (extras == null)
extras = new Bundle();
extras.putParcelable(TaskListFragment.TOKEN_FILTER, savedFilter);
}
if (savedFilter == null)
savedFilter = CoreFilterExposer.buildInboxFilter(getResources());
savedFilter = getDefaultFilter();
if (extras == null)
extras = new Bundle();
extras.putParcelable(TaskListFragment.TOKEN_FILTER, savedFilter);
if (swipeIsEnabled()) {
FilterListFragment flf = getFilterListFragment();
@ -219,6 +220,23 @@ public class TaskListActivity extends AstridActivity implements MainMenuListener
abTestEventReportingService.trackUserRetention();
}
protected int getHeaderView() {
return R.layout.header_nav_views;
}
protected int getContentView() {
if (AndroidUtilities.isTabletSized(this))
return R.layout.task_list_wrapper_activity_3pane;
else if (Preferences.getIntegerFromString(R.string.p_swipe_lists_performance_key, 3) == 0)
return R.layout.task_list_wrapper_activity_no_swipe;
else
return R.layout.task_list_wrapper_activity;
}
protected Filter getDefaultFilter() {
return CoreFilterExposer.buildInboxFilter(getResources());
}
private boolean swipeIsEnabled() {
return fragmentLayout == LAYOUT_SINGLE && swipeEnabled;
}
@ -264,17 +282,26 @@ public class TaskListActivity extends AstridActivity implements MainMenuListener
createCommentsPopover();
}
boolean peopleView = getIntent().getBooleanExtra(PEOPLE_VIEW, false);
Class<? extends FilterListFragment> filterFragmentClass =
peopleView ? PeopleListFragment.class : FilterListFragment.class;
setupFragment(FilterListFragment.TAG_FILTERLIST_FRAGMENT,
R.id.filterlist_fragment_container, FilterListFragment.class, false);
R.id.filterlist_fragment_container, filterFragmentClass, false, false);
} else {
fragmentLayout = LAYOUT_SINGLE;
actionBar.setDisplayHomeAsUpEnabled(true);
listsNav.setOnClickListener(popupMenuClickListener);
createListsPopover();
setupPopoverWithFilterList((FilterListFragment) setupFragment(FilterListFragment.TAG_FILTERLIST_FRAGMENT, 0, FilterListFragment.class, true));
setupPopoverWithFilterList((FilterListFragment) setupFragment(FilterListFragment.TAG_FILTERLIST_FRAGMENT, 0,
getFilterListClass(), true, false));
}
}
protected Class<? extends FilterListFragment> getFilterListClass() {
return FilterListFragment.class;
}
private void createListsPopover() {
listsPopover = new FragmentPopover(this, R.layout.list_dropdown_popover);
listsPopover.setOnDismissListener(new OnDismissListener() {
@ -315,19 +342,22 @@ public class TaskListActivity extends AstridActivity implements MainMenuListener
private void createMainMenuPopover() {
int layout;
if (AndroidUtilities.isTabletSized(this))
boolean isTablet = AndroidUtilities.isTabletSized(this);
if (isTablet)
layout = R.layout.main_menu_popover_tablet;
else
layout = R.layout.main_menu_popover;
mainMenuPopover = new MainMenuPopover(this, layout, (fragmentLayout != LAYOUT_SINGLE));
mainMenuPopover.setMenuListener(this);
mainMenuPopover = new MainMenuPopover(this, layout, (fragmentLayout != LAYOUT_SINGLE), this);
mainMenuPopover.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss() {
mainMenu.setSelected(false);
}
});
if (isTablet)
setupMainMenuForPeopleViewState(getIntent().getBooleanExtra(PEOPLE_VIEW, false));
}
private void setupPopoverWithFragment(FragmentPopover popover, Fragment frag, LayoutParams params) {
@ -640,18 +670,31 @@ public class TaskListActivity extends AstridActivity implements MainMenuListener
getIntent().putExtra(TOKEN_SOURCE, Constants.SOURCE_DEFAULT); // Only report source once
}
@Override
public boolean shouldAddMenuItem(int itemId) {
return true;
}
@Override
public void mainMenuItemSelected(int item, Intent customIntent) {
TaskListFragment tlf = getTaskListFragment();
switch (item) {
case MainMenuPopover.MAIN_MENU_ITEM_LISTS:
if (fragmentLayout == LAYOUT_SINGLE)
listsNav.performClick();
else
togglePeopleView();
return;
case MainMenuPopover.MAIN_MENU_ITEM_SEARCH:
onSearchRequested();
return;
case MainMenuPopover.MAIN_MENU_ITEM_FRIENDS:
// Doesn't exist yet
if (fragmentLayout != LAYOUT_SINGLE) {
togglePeopleView();
} else {
Intent peopleIntent = new Intent(this, PeopleViewActivity.class);
startActivity(peopleIntent);
}
return;
case MainMenuPopover.MAIN_MENU_ITEM_SUGGESTIONS:
// Doesn't exist yet
@ -664,6 +707,29 @@ public class TaskListActivity extends AstridActivity implements MainMenuListener
tlf.handleOptionsMenuItemSelected(item, customIntent);
}
private void togglePeopleView() {
FilterListFragment flf = getFilterListFragment();
boolean peopleMode = !(flf instanceof PeopleListFragment);
if (peopleMode)
setupFragment(FilterListFragment.TAG_FILTERLIST_FRAGMENT, R.id.filterlist_fragment_container,
PeopleListFragment.class, false, true);
else
setupFragment(FilterListFragment.TAG_FILTERLIST_FRAGMENT,
R.id.filterlist_fragment_container, FilterListFragment.class, false, true);
setupMainMenuForPeopleViewState(peopleMode);
getIntent().putExtra(PEOPLE_VIEW, peopleMode);
}
private void setupMainMenuForPeopleViewState(boolean inPeopleMode) {
mainMenuPopover.setFixedItemVisibility(0, inPeopleMode ? View.VISIBLE : View.GONE, true);
mainMenuPopover.setFixedItemVisibility(1, inPeopleMode ? View.GONE : View.VISIBLE, true);
TypedValue tv = new TypedValue();
getTheme().resolveAttribute(inPeopleMode ? R.attr.asPeopleMenu : R.attr.asMainMenu, tv, false);
mainMenu.setImageResource(tv.data);
}
public MainMenuPopover getMainMenuPopover() {
return mainMenuPopover;
}

@ -125,12 +125,12 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
// --- menu codes
protected static final int MENU_ADDONS_ID = R.string.TLA_menu_addons;
public static final int MENU_ADDONS_ID = R.string.TLA_menu_addons;
protected static final int MENU_SETTINGS_ID = R.string.TLA_menu_settings;
protected static final int MENU_SORT_ID = R.string.TLA_menu_sort;
protected static final int MENU_SYNC_ID = R.string.TLA_menu_sync;
protected static final int MENU_SUPPORT_ID = R.string.TLA_menu_support;
protected static final int MENU_NEW_FILTER_ID = R.string.FLA_new_filter;
public static final int MENU_NEW_FILTER_ID = R.string.FLA_new_filter;
protected static final int MENU_ADDON_INTENT_ID = Menu.FIRST + 199;
protected static final int CONTEXT_MENU_EDIT_TASK_ID = R.string.TAd_contextEditTask;
@ -509,7 +509,7 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
getView().findViewById(R.id.progressBar).setVisibility(View.GONE);
}
private void setupQuickAddBar() {
protected void setupQuickAddBar() {
quickAddBar = (QuickAddBar) getView().findViewById(R.id.taskListFooter);
quickAddBar.initialize(getActivity(), this, mListener);

@ -80,7 +80,7 @@ public class FilterAdapter extends ArrayAdapter<Filter> {
private final DisplayMetrics metrics = new DisplayMetrics();
/** receiver for new filters */
private final FilterReceiver filterReceiver = new FilterReceiver();
protected final FilterReceiver filterReceiver = new FilterReceiver();
private final BladeFilterReceiver bladeFilterReceiver = new BladeFilterReceiver();
private boolean shouldUseBladeFilter = true;

@ -138,7 +138,7 @@ public class Astrid2TaskProvider extends ContentProvider {
public Cursor getTags() {
Tag[] tags = TagService.getInstance().getGroupedTags(TagService.GROUPED_TAGS_BY_SIZE,
Criterion.all);
Criterion.all, true);
MatrixCursor ret = new MatrixCursor(TAGS_FIELD_LIST);
@ -195,7 +195,7 @@ public class Astrid2TaskProvider extends ContentProvider {
task.readFromCursor(cursor);
StringBuilder taskTags = new StringBuilder();
TodorooCursor<Metadata> tagCursor = TagService.getInstance().getTags(task.getId());
TodorooCursor<Metadata> tagCursor = TagService.getInstance().getTags(task.getId(), true);
try {
for(tagCursor.moveToFirst(); !tagCursor.isAfterLast(); tagCursor.moveToNext())
taskTags.append(tagCursor.get(TagService.TAG)).append(TAG_SEPARATOR);

@ -229,6 +229,7 @@ public class StartupService {
.setMessage(R.string.DB_corrupted_body)
.setPositiveButton(R.string.DLG_ok, null)
.create().show();
e.printStackTrace();
}
/**

@ -505,6 +505,9 @@ public class TaskService {
task.mergeWith(forTask);
}
if (task.getValue(Task.USER_ID) != Task.USER_ID_SELF)
task.putTransitory(TRANS_ASSIGNED, true);
boolean markup = taskService.quickAdd(task);
if (markup)
task.putTransitory(TRANS_QUICK_ADD_MARKUP, true);

@ -138,6 +138,8 @@ public class ThemeService {
return R.drawable.icn_menu_sort_by_size_dark;
case R.drawable.icn_menu_search:
return R.drawable.icn_menu_search_dark;
case R.drawable.icn_menu_friends:
return R.drawable.icn_menu_friends_dark;
case R.drawable.icn_menu_lists:
return R.drawable.icn_menu_lists_dark;
case R.drawable.icn_menu_plugins:

@ -28,6 +28,7 @@ public class MainMenuPopover extends FragmentPopover implements InterceptTouchLi
public static final int MAIN_MENU_ITEM_SETTINGS = R.string.TLA_menu_settings;
public interface MainMenuListener {
public boolean shouldAddMenuItem(int itemId);
public void mainMenuItemSelected(int item, Intent customIntent);
}
@ -43,7 +44,7 @@ public class MainMenuPopover extends FragmentPopover implements InterceptTouchLi
this.mListener = listener;
}
public MainMenuPopover(Context context, int layout, boolean isTablet) {
public MainMenuPopover(Context context, int layout, boolean isTablet, MainMenuListener listener) {
super(context, layout);
TouchInterceptingFrameLayout rootLayout = (TouchInterceptingFrameLayout) getContentView();
@ -68,6 +69,8 @@ public class MainMenuPopover extends FragmentPopover implements InterceptTouchLi
topFixed = (LinearLayout) getContentView().findViewById(R.id.topFixedItems);
bottomFixed = (LinearLayout) getContentView().findViewById(R.id.bottomFixedItems);
mListener = listener;
addFixedItems(isTablet);
}
@ -94,10 +97,12 @@ public class MainMenuPopover extends FragmentPopover implements InterceptTouchLi
private void addFixedItems(boolean isTablet) {
int themeFlags = isTablet ? ThemeService.FLAG_FORCE_DARK : 0;
if (!isTablet)
addMenuItem(R.string.TLA_menu_lists,
ThemeService.getDrawable(R.drawable.icn_menu_lists, themeFlags),
MAIN_MENU_ITEM_LISTS, null, topFixed); // Lists item
addMenuItem(R.string.TLA_menu_friends,
ThemeService.getDrawable(R.drawable.icn_menu_friends, themeFlags),
MAIN_MENU_ITEM_FRIENDS, null, topFixed);
addMenuItem(R.string.TLA_menu_search,
ThemeService.getDrawable(R.drawable.icn_menu_search, themeFlags),
MAIN_MENU_ITEM_SEARCH, null, topFixed);
@ -106,6 +111,14 @@ public class MainMenuPopover extends FragmentPopover implements InterceptTouchLi
MAIN_MENU_ITEM_SETTINGS, null, bottomFixed); // Settings item
}
public void setFixedItemVisibility(int index, int visibility, boolean top) {
LinearLayout container = top ? topFixed : bottomFixed;
if (index < 0 || index >= container.getChildCount())
return;
container.getChildAt(index).setVisibility(visibility);
}
@Override
protected int getArrowLeftMargin(View arrow) {
return mRect.centerX() - arrow.getMeasuredWidth() / 2 - (int) (12 * metrics.density);
@ -136,11 +149,15 @@ public class MainMenuPopover extends FragmentPopover implements InterceptTouchLi
// --- Private helpers ---
private void addMenuItem(int title, int imageRes, int id, Intent customIntent, ViewGroup container) {
if (mListener != null && !mListener.shouldAddMenuItem(id))
return;
View item = setupItemWithParams(title, imageRes);
addViewWithListener(item, container, id, customIntent);
}
private void addMenuItem(CharSequence title, Drawable image, int id, Intent customIntent, ViewGroup container) {
if (mListener != null && !mListener.shouldAddMenuItem(id))
return;
View item = setupItemWithParams(title, image);
addViewWithListener(item, container, id, customIntent);
}

@ -70,6 +70,7 @@ public class QuickAddBar extends LinearLayout {
private RepeatControlSet repeatControl;
private GCalControlSet gcalControl;
private EditPeopleControlSet peopleControl;
private boolean usePeopleControl = true;
@Autowired AddOnService addOnService;
@Autowired ExceptionService exceptionService;
@ -178,6 +179,11 @@ public class QuickAddBar extends LinearLayout {
setUpQuickAddControlSets();
}
public void setUsePeopleControl(boolean usePeopleControl) {
this.usePeopleControl = usePeopleControl;
peopleControl.getDisplayView().setVisibility(usePeopleControl ? View.VISIBLE : View.GONE);
}
private void setUpQuickAddControlSets() {
repeatControl = new RepeatControlSet(activity,
@ -245,7 +251,7 @@ public class QuickAddBar extends LinearLayout {
try {
if (title != null)
title = title.trim();
boolean assignedToMe = peopleControl.willBeAssignedToMe();
boolean assignedToMe = usePeopleControl ? peopleControl.willBeAssignedToMe() : true;
if (!assignedToMe && !actFmPreferenceService.isLoggedIn()) {
DialogInterface.OnClickListener okListener = new DialogInterface.OnClickListener() {
@Override

Loading…
Cancel
Save