Add theme manager, widget themes

pull/384/head
Alex Baker 8 years ago
parent 81d9b3fb3b
commit 142a9b3229

@ -0,0 +1,15 @@
package org.tasks.widget;
import org.tasks.injection.ActivityComponent;
public class WidgetConfigActivity extends BaseWidgetConfigActivity {
@Override
public void inject(ActivityComponent component) {
component.inject(this);
}
@Override
public void initiateThemePurchase() {
}
}

@ -34,7 +34,7 @@ public class BasicPreferences extends BaseBasicPreferences {
@Override
public void initiateThemePurchase() {
activityPreferences.setBoolean(R.string.p_purchased_themes, true);
preferences.setBoolean(R.string.p_purchased_themes, true);
recreate();
}
}

@ -0,0 +1,23 @@
package org.tasks.widget;
import org.tasks.R;
import org.tasks.injection.ActivityComponent;
import org.tasks.preferences.Preferences;
import javax.inject.Inject;
public class WidgetConfigActivity extends BaseWidgetConfigActivity {
@Inject Preferences preferences;
@Override
public void inject(ActivityComponent component) {
component.inject(this);
}
@Override
public void initiateThemePurchase() {
preferences.setBoolean(R.string.p_purchased_themes, true);
showThemeSelection();
}
}

@ -25,7 +25,7 @@ import com.todoroo.astrid.sync.SyncResultCallback;
import org.tasks.Broadcaster;
import org.tasks.R;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.Preferences;
import org.tasks.sync.IndeterminateProgressBarSyncResultCallback;
import org.tasks.sync.SyncThrottle;
@ -48,7 +48,7 @@ public class GtasksListFragment extends SubtasksListFragment {
@Inject GtasksPreferenceService gtasksPreferenceService;
@Inject SyncV2Service syncService;
@Inject TaskAttachmentDao taskAttachmentDao;
@Inject ActivityPreferences preferences;
@Inject Preferences preferences;
@Inject SyncThrottle syncThrottle;
@Inject DialogBuilder dialogBuilder;
@Inject Broadcaster broadcaster;

@ -34,7 +34,7 @@ import com.todoroo.astrid.ui.DraggableListView;
import org.tasks.R;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.Preferences;
import java.util.ArrayList;
import java.util.Arrays;
@ -52,7 +52,7 @@ public class OrderedMetadataListFragmentHelper<LIST> implements OrderedListFragm
private DialogBuilder dialogBuilder;
private final TaskListFragment fragment;
private final ActivityPreferences preferences;
private final Preferences preferences;
private final TaskAttachmentDao taskAttachmentDao;
private final TaskService taskService;
private final MetadataDao metadataDao;
@ -61,7 +61,7 @@ public class OrderedMetadataListFragmentHelper<LIST> implements OrderedListFragm
private LIST list;
public OrderedMetadataListFragmentHelper(ActivityPreferences preferences, TaskAttachmentDao taskAttachmentDao,
public OrderedMetadataListFragmentHelper(Preferences preferences, TaskAttachmentDao taskAttachmentDao,
TaskService taskService, MetadataDao metadataDao,
TaskListFragment fragment, OrderedMetadataListUpdater<LIST> updater,
DialogBuilder dialogBuilder) {
@ -200,7 +200,7 @@ public class OrderedMetadataListFragmentHelper<LIST> implements OrderedListFragm
private final class DraggableTaskAdapter extends TaskAdapter {
private DraggableTaskAdapter(Context context, ActivityPreferences preferences, TaskListFragment activity,
private DraggableTaskAdapter(Context context, Preferences preferences, TaskListFragment activity,
Cursor c, AtomicReference<String> query, DialogBuilder dialogBuilder) {
super(context, preferences, taskAttachmentDao, taskService, activity, c, query, null, dialogBuilder);
}

@ -68,6 +68,7 @@ public class InventoryHelper implements IabBroadcastReceiver.IabBroadcastListene
checkPurchase(R.string.sku_tasker, R.string.p_purchased_tasker);
checkPurchase(R.string.sku_tesla_unread, R.string.p_purchased_tesla_unread);
checkPurchase(R.string.sku_dashclock, R.string.p_purchased_dashclock);
checkPurchase(R.string.sku_themes, R.string.p_purchased_themes);
broadcaster.refresh();
} else {
Timber.e("query inventory failed: %s", result.getMessage());

@ -5,10 +5,11 @@ import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import org.tasks.injection.InjectingAppCompatActivity;
import org.tasks.injection.ThemedInjectingAppCompatActivity;
import timber.log.Timber;
public abstract class AbstractFragmentPluginAppCompatActivity extends InjectingAppCompatActivity {
public abstract class AbstractFragmentPluginAppCompatActivity extends ThemedInjectingAppCompatActivity {
protected boolean mIsCancelled = false;

@ -20,8 +20,8 @@ import org.tasks.billing.PurchaseHelperCallback;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.ActivityComponent;
import org.tasks.locale.bundle.PluginBundleValues;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.DefaultFilterProvider;
import org.tasks.preferences.Preferences;
import org.tasks.ui.MenuColorizer;
import java.util.Set;
@ -42,7 +42,7 @@ public final class TaskerSettingsActivity extends AbstractFragmentPluginAppCompa
@Bind(R.id.toolbar) Toolbar toolbar;
@Bind(R.id.text_view) TextView filterTitle;
@Inject ActivityPreferences preferences;
@Inject Preferences preferences;
@Inject DefaultFilterProvider defaultFilterProvider;
@Inject PurchaseHelper purchaseHelper;
@Inject DialogBuilder dialogBuilder;
@ -54,7 +54,6 @@ public final class TaskerSettingsActivity extends AbstractFragmentPluginAppCompa
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
preferences.applyThemeAndStatusBarColor();
setContentView(R.layout.tasker_settings);
ButterKnife.bind(this);

@ -0,0 +1,52 @@
package org.tasks.widget;
import android.content.Intent;
import org.tasks.R;
import org.tasks.billing.PurchaseHelper;
import org.tasks.billing.PurchaseHelperCallback;
import org.tasks.injection.ActivityComponent;
import javax.inject.Inject;
import timber.log.Timber;
public class WidgetConfigActivity extends BaseWidgetConfigActivity implements PurchaseHelperCallback {
private static final int REQUEST_PURCHASE = 10109;
@Inject PurchaseHelper purchaseHelper;
@Override
public void initiateThemePurchase() {
purchaseHelper.purchase(dialogBuilder, this, getString(R.string.sku_themes), getString(R.string.p_purchased_themes), REQUEST_PURCHASE, this);
}
@Override
public void purchaseCompleted(boolean success, final String sku) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (getString(R.string.sku_themes).equals(sku)) {
showThemeSelection();
} else {
Timber.d("Unhandled sku: %s", sku);
}
}
});
}
@Override
public void inject(ActivityComponent component) {
component.inject(this);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_PURCHASE) {
purchaseHelper.handleActivityResult(this, requestCode, resultCode, data);
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
}

@ -100,15 +100,15 @@
<activity
android:name=".activities.DatePickerActivity"
android:theme="@style/Theme.AppCompat.Dialog" />
android:theme="@style/TranslucentDialog" />
<activity
android:name=".activities.TimePickerActivity"
android:theme="@style/Theme.AppCompat.Dialog" />
android:theme="@style/TranslucentDialog" />
<activity
android:name=".activities.DateAndTimePickerActivity"
android:theme="@style/Theme.AppCompat.Dialog"
android:theme="@style/TranslucentDialog"
android:taskAffinity="" />
<activity

@ -26,7 +26,7 @@ import org.tasks.R;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.ActivityComponent;
import org.tasks.injection.InjectingAppCompatActivity;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.injection.ThemedInjectingAppCompatActivity;
import org.tasks.ui.MenuColorizer;
import javax.inject.Inject;
@ -36,13 +36,12 @@ import butterknife.ButterKnife;
import static android.text.TextUtils.isEmpty;
public class FilterSettingsActivity extends InjectingAppCompatActivity {
public class FilterSettingsActivity extends ThemedInjectingAppCompatActivity {
public static final String TOKEN_FILTER = "token_filter";
private CustomFilter filter;
@Inject ActivityPreferences preferences;
@Inject StoreObjectDao storeObjectDao;
@Inject DialogBuilder dialogBuilder;
@ -52,7 +51,7 @@ public class FilterSettingsActivity extends InjectingAppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
preferences.applyThemeAndStatusBarColor();
setContentView(R.layout.filter_settings_activity);
ButterKnife.bind(this);

@ -36,7 +36,7 @@ import org.tasks.R;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.ActivityComponent;
import org.tasks.injection.InjectingAppCompatActivity;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.injection.ThemedInjectingAppCompatActivity;
import org.tasks.ui.MenuColorizer;
import javax.inject.Inject;
@ -46,7 +46,7 @@ import butterknife.ButterKnife;
import static android.text.TextUtils.isEmpty;
public class TagSettingsActivity extends InjectingAppCompatActivity {
public class TagSettingsActivity extends ThemedInjectingAppCompatActivity {
public static final String TOKEN_NEW_FILTER = "newFilter"; //$NON-NLS-1$
public static final String TOKEN_AUTOPOPULATE_NAME = "autopopulateName"; //$NON-NLS-1$
@ -58,7 +58,6 @@ public class TagSettingsActivity extends InjectingAppCompatActivity {
@Inject TagService tagService;
@Inject TagDataDao tagDataDao;
@Inject ActivityPreferences preferences;
@Inject MetadataDao metadataDao;
@Inject DialogBuilder dialogBuilder;
@ -69,7 +68,7 @@ public class TagSettingsActivity extends InjectingAppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
preferences.applyThemeAndStatusBarColor();
setContentView(R.layout.tag_settings_activity);
ButterKnife.bind(this);

@ -27,7 +27,7 @@ import com.commonsware.cwac.tlv.TouchListView.DropListener;
import org.tasks.R;
import org.tasks.injection.ActivityComponent;
import org.tasks.injection.InjectingAppCompatActivity;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.injection.ThemedInjectingAppCompatActivity;
import org.tasks.preferences.Preferences;
import java.util.ArrayList;
@ -39,7 +39,7 @@ import javax.inject.Inject;
import butterknife.Bind;
import butterknife.ButterKnife;
public class BeastModePreferences extends InjectingAppCompatActivity {
public class BeastModePreferences extends ThemedInjectingAppCompatActivity {
@Bind(R.id.toolbar) Toolbar toolbar;
@Bind(android.R.id.list) TouchListView touchList;
@ -54,12 +54,12 @@ public class BeastModePreferences extends InjectingAppCompatActivity {
private HashMap<String, String> prefsToDescriptions;
@Inject ActivityPreferences preferences;
@Inject Preferences preferences;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
preferences.applyThemeAndStatusBarColor();
setContentView(R.layout.beast_mode_pref_activity);
ButterKnife.bind(this);

@ -45,9 +45,11 @@ import org.tasks.fragments.CommentBarFragment;
import org.tasks.fragments.TaskEditControlSetFragmentManager;
import org.tasks.injection.ActivityComponent;
import org.tasks.injection.InjectingAppCompatActivity;
import org.tasks.injection.ThemedInjectingAppCompatActivity;
import org.tasks.intents.TaskIntents;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.DefaultFilterProvider;
import org.tasks.preferences.Preferences;
import org.tasks.preferences.ThemeApplicator;
import org.tasks.receivers.RepeatConfirmationReceiver;
import org.tasks.ui.EmptyTaskEditFragment;
import org.tasks.ui.NavigationDrawerFragment;
@ -72,7 +74,7 @@ public class TaskListActivity extends InjectingAppCompatActivity implements
TaskEditFragment.TaskEditFragmentCallbackHandler,
CommentBarFragment.CommentBarFragmentCallback {
@Inject ActivityPreferences preferences;
@Inject Preferences preferences;
@Inject StartupService startupService;
@Inject SubtasksHelper subtasksHelper;
@Inject TaskService taskService;
@ -81,6 +83,7 @@ public class TaskListActivity extends InjectingAppCompatActivity implements
@Inject DefaultFilterProvider defaultFilterProvider;
@Inject GtasksListService gtasksListService;
@Inject TagDataDao tagDataDao;
@Inject ThemeApplicator themeApplicator;
public static final int REQUEST_UPGRADE = 505;
@ -99,8 +102,10 @@ public class TaskListActivity extends InjectingAppCompatActivity implements
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
themeApplicator.applyTheme();
startupService.onStartupApplication(this);
preferences.applyTheme();
setContentView(R.layout.task_list_activity);

@ -78,7 +78,7 @@ import org.tasks.injection.ForActivity;
import org.tasks.injection.FragmentComponent;
import org.tasks.injection.InjectingListFragment;
import org.tasks.notifications.NotificationManager;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.Preferences;
import org.tasks.ui.CheckBoxes;
import org.tasks.ui.MenuColorizer;
@ -134,7 +134,7 @@ public class TaskListFragment extends InjectingListFragment implements SwipeRefr
@Inject TaskDeleter taskDeleter;
@Inject TaskDuplicator taskDuplicator;
@Inject @ForActivity Context context;
@Inject ActivityPreferences preferences;
@Inject Preferences preferences;
@Inject NotificationManager notificationManager;
@Inject TaskAttachmentDao taskAttachmentDao;
@Inject GtasksPreferenceService gtasksPreferenceService;

@ -34,6 +34,7 @@ import org.tasks.filters.NavigationDrawerSeparator;
import org.tasks.filters.NavigationDrawerSubheader;
import org.tasks.preferences.BasicPreferences;
import org.tasks.preferences.HelpAndFeedbackActivity;
import org.tasks.preferences.Theme;
import org.tasks.ui.NavigationDrawerFragment;
import java.util.List;
@ -59,7 +60,7 @@ public class FilterAdapter extends ArrayAdapter<FilterListItem> {
private final LayoutInflater inflater;
public FilterAdapter(FilterProvider filterProvider, FilterCounter filterCounter, Activity activity,
ListView listView, boolean navigationDrawer) {
Theme theme, ListView listView, boolean navigationDrawer) {
super(activity, 0);
this.filterProvider = filterProvider;
this.filterCounter = filterCounter;
@ -67,7 +68,7 @@ public class FilterAdapter extends ArrayAdapter<FilterListItem> {
this.listView = listView;
this.navigationDrawer = navigationDrawer;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater = theme.getThemedLayoutInflater();
}
@Override

@ -39,7 +39,6 @@ import com.todoroo.astrid.data.RemoteModel;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.TaskAttachment;
import com.todoroo.astrid.files.FilesAction;
import com.todoroo.astrid.files.FilesControlSet;
import com.todoroo.astrid.notes.NotesAction;
import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.tags.TaskToTagMetadata;
@ -47,7 +46,7 @@ import com.todoroo.astrid.ui.CheckableImageView;
import org.tasks.R;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.Preferences;
import org.tasks.ui.CheckBoxes;
import java.util.concurrent.atomic.AtomicReference;
@ -95,7 +94,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
// --- instance variables
private final CheckBoxes checkBoxes;
private final ActivityPreferences preferences;
private final Preferences preferences;
private final TaskAttachmentDao taskAttachmentDao;
private final TaskService taskService;
@ -115,7 +114,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
protected final int minRowHeight;
public TaskAdapter(Context context, ActivityPreferences preferences, TaskAttachmentDao taskAttachmentDao, TaskService taskService, TaskListFragment fragment,
public TaskAdapter(Context context, Preferences preferences, TaskAttachmentDao taskAttachmentDao, TaskService taskService, TaskListFragment fragment,
Cursor c, AtomicReference<String> query, OnCompletedTaskListener onCompletedTaskListener,
DialogBuilder dialogBuilder) {
super(context, c, false);

@ -46,7 +46,7 @@ import org.tasks.dialogs.DialogBuilder;
import org.tasks.filters.FilterCriteriaProvider;
import org.tasks.injection.ActivityComponent;
import org.tasks.injection.InjectingAppCompatActivity;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.injection.ThemedInjectingAppCompatActivity;
import org.tasks.ui.MenuColorizer;
import java.util.ArrayList;
@ -66,7 +66,7 @@ import static android.text.TextUtils.isEmpty;
* @author Tim Su <tim@todoroo.com>
*
*/
public class CustomFilterActivity extends InjectingAppCompatActivity {
public class CustomFilterActivity extends ThemedInjectingAppCompatActivity {
private static final String IDENTIFIER_UNIVERSE = "active"; //$NON-NLS-1$
@ -139,7 +139,6 @@ public class CustomFilterActivity extends InjectingAppCompatActivity {
@Inject Database database;
@Inject StoreObjectDao storeObjectDao;
@Inject ActivityPreferences preferences;
@Inject DialogBuilder dialogBuilder;
@Inject FilterCriteriaProvider filterCriteriaProvider;
@ -150,8 +149,6 @@ public class CustomFilterActivity extends InjectingAppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
preferences.applyThemeAndStatusBarColor();
setContentView(R.layout.custom_filter_activity);
ButterKnife.bind(this);

@ -17,15 +17,16 @@ import org.tasks.R;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.ActivityComponent;
import org.tasks.injection.InjectingAppCompatActivity;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.injection.ThemedInjectingAppCompatActivity;
import org.tasks.preferences.BasicPreferences;
import org.tasks.preferences.Preferences;
import org.tasks.preferences.ResourceResolver;
import org.tasks.scheduling.AlarmManager;
import org.tasks.scheduling.CalendarNotificationIntentService;
import javax.inject.Inject;
public class CalendarReminderActivity extends InjectingAppCompatActivity {
public class CalendarReminderActivity extends ThemedInjectingAppCompatActivity {
public static final String TOKEN_EVENT_ID = "eventId";
public static final String TOKEN_EVENT_NAME = "eventName";
@ -39,7 +40,7 @@ public class CalendarReminderActivity extends InjectingAppCompatActivity {
private static final int IGNORE_PROMPT_COUNT = 3;
@Inject StartupService startupService;
@Inject ActivityPreferences preferences;
@Inject Preferences preferences;
@Inject ResourceResolver resourceResolver;
@Inject DialogBuilder dialogBuilder;
@Inject AlarmManager alarmManager;
@ -95,7 +96,7 @@ public class CalendarReminderActivity extends InjectingAppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
preferences.applyTheme();
startupService.onStartupApplication(this);
setContentView(R.layout.calendar_reminder_activity);

@ -43,7 +43,8 @@ import org.tasks.activities.DatePickerActivity;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.ForActivity;
import org.tasks.injection.FragmentComponent;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.Preferences;
import org.tasks.preferences.ThemeManager;
import org.tasks.time.DateTime;
import org.tasks.ui.TaskEditControlFragment;
@ -97,8 +98,9 @@ public class RepeatControlSet extends TaskEditControlFragment {
private Spinner repeatUntil;
@Inject DialogBuilder dialogBuilder;
@Inject ActivityPreferences preferences;
@Inject Preferences preferences;
@Inject @ForActivity Context context;
@Inject ThemeManager themeManager;
@Bind(R.id.clear) ImageView clear;
@Bind(R.id.display_row_edit) TextView displayView;
@ -438,7 +440,7 @@ public class RepeatControlSet extends TaskEditControlFragment {
dialogValue = 1;
}
new NumberPickerDialog(context, preferences.getDialogTheme(), new OnNumberPickedListener() {
new NumberPickerDialog(context, themeManager.getDialogThemeResId(), new OnNumberPickedListener() {
@Override
public void onNumberPicked(int number) {
setRepeatValue(number);

@ -30,7 +30,7 @@ import com.todoroo.astrid.ui.DraggableListView;
import org.tasks.R;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.Preferences;
import java.util.ArrayList;
import java.util.Collections;
@ -46,7 +46,7 @@ public class AstridOrderedListFragmentHelper<LIST> implements OrderedListFragmen
private final AstridOrderedListUpdater<LIST> updater;
private DialogBuilder dialogBuilder;
private final TaskListFragment fragment;
private final ActivityPreferences preferences;
private final Preferences preferences;
private final TaskAttachmentDao taskAttachmentDao;
private final TaskService taskService;
@ -54,7 +54,7 @@ public class AstridOrderedListFragmentHelper<LIST> implements OrderedListFragmen
private LIST list;
public AstridOrderedListFragmentHelper(ActivityPreferences preferences, TaskAttachmentDao taskAttachmentDao,
public AstridOrderedListFragmentHelper(Preferences preferences, TaskAttachmentDao taskAttachmentDao,
TaskService taskService, TaskListFragment fragment,
AstridOrderedListUpdater<LIST> updater, DialogBuilder dialogBuilder) {
this.preferences = preferences;
@ -188,7 +188,7 @@ public class AstridOrderedListFragmentHelper<LIST> implements OrderedListFragmen
private final class DraggableTaskAdapter extends TaskAdapter {
private DraggableTaskAdapter(Context context, ActivityPreferences preferences, TaskListFragment activity,
private DraggableTaskAdapter(Context context, Preferences preferences, TaskListFragment activity,
Cursor c, AtomicReference<String> query, DialogBuilder dialogBuilder) {
super(context, preferences, taskAttachmentDao, taskService, activity, c, query, null, dialogBuilder);
}

@ -28,7 +28,7 @@ import org.tasks.R;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.ForApplication;
import org.tasks.injection.FragmentComponent;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.Preferences;
import javax.inject.Inject;
@ -53,7 +53,7 @@ public class SubtasksListFragment extends TaskListFragment {
@Inject TaskService taskService;
@Inject SubtasksFilterUpdater subtasksFilterUpdater;
@Inject TaskAttachmentDao taskAttachmentDao;
@Inject ActivityPreferences preferences;
@Inject Preferences preferences;
@Inject @ForApplication Context context;
@Inject DialogBuilder dialogBuilder;
@Inject TaskListMetadataDao taskListMetadataDao;

@ -27,7 +27,7 @@ import org.tasks.R;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.ForApplication;
import org.tasks.injection.FragmentComponent;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.Preferences;
import javax.inject.Inject;
@ -43,7 +43,7 @@ public class SubtasksTagListFragment extends TagViewFragment {
@Inject TaskService taskService;
@Inject SubtasksFilterUpdater subtasksFilterUpdater;
@Inject TaskAttachmentDao taskAttachmentDao;
@Inject ActivityPreferences preferences;
@Inject Preferences preferences;
@Inject @ForApplication Context context;
@Inject DialogBuilder dialogBuilder;
@Inject TaskListMetadataDao taskListMetadataDao;

@ -31,7 +31,7 @@ import org.tasks.R;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.ForActivity;
import org.tasks.injection.FragmentComponent;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.ThemeManager;
import org.tasks.ui.TaskEditControlFragment;
import javax.inject.Inject;
@ -58,9 +58,9 @@ public class TimerControlSet extends TaskEditControlFragment {
private static final String EXTRA_ESTIMATED = "extra_estimated";
private static final String EXTRA_ELAPSED = "extra_elapsed";
@Inject ActivityPreferences preferences;
@Inject DialogBuilder dialogBuilder;
@Inject @ForActivity Context context;
@Inject ThemeManager themeManager;
@Bind(R.id.display_row_edit) TextView displayEdit;
@Bind(R.id.timer) Chronometer chronometer;
@ -86,8 +86,8 @@ public class TimerControlSet extends TaskEditControlFragment {
}
dialogView = inflater.inflate(R.layout.control_set_timers_dialog, null);
estimated = new TimeDurationControlSet(context, dialogView, R.id.estimatedDuration, preferences);
elapsed = new TimeDurationControlSet(context, dialogView, R.id.elapsedDuration, preferences);
estimated = new TimeDurationControlSet(context, dialogView, R.id.estimatedDuration, themeManager);
elapsed = new TimeDurationControlSet(context, dialogView, R.id.elapsedDuration, themeManager);
estimated.setTimeDuration(estimatedSeconds);
elapsed.setTimeDuration(elapsedSeconds);
refresh();

@ -11,26 +11,24 @@ import android.text.format.DateUtils;
import android.view.View;
import android.widget.TextView;
import com.todoroo.andlib.data.Property.IntegerProperty;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.ui.NNumberPickerDialog.OnNNumberPickedListener;
import org.tasks.R;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.ThemeManager;
public class TimeDurationControlSet implements OnNNumberPickedListener, View.OnClickListener {
private final Context context;
private final ThemeManager themeManager;
private final TextView timeButton;
private int timeDuration;
private int[] initialValues = null;
private NNumberPickerDialog dialog = null;
private ActivityPreferences activityPreferences;
public TimeDurationControlSet(Context context, View view,
int timeButtonId, ActivityPreferences activityPreferences) {
int timeButtonId, ThemeManager themeManager) {
this.context = context;
this.activityPreferences = activityPreferences;
this.themeManager = themeManager;
timeButton = (TextView)view.findViewById(timeButtonId);
((View) timeButton.getParent()).setOnClickListener(this);
@ -70,7 +68,7 @@ public class TimeDurationControlSet implements OnNNumberPickedListener, View.OnC
@Override
public void onClick(View v) {
if(dialog == null) {
dialog = new NNumberPickerDialog(context, activityPreferences.getDialogTheme(), this,
dialog = new NNumberPickerDialog(context, themeManager.getDialogThemeResId(), this,
context.getResources().getString(R.string.DLG_hour_minutes),
new int[] {0, 0}, new int[] {1, 5}, new int[] {0, 0},
new int[] {999, 59}, new String[] {":", null});

@ -10,7 +10,7 @@ import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
import org.tasks.dialogs.MyDatePickerDialog;
import org.tasks.injection.ActivityComponent;
import org.tasks.injection.InjectingAppCompatActivity;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.ThemeManager;
import org.tasks.time.DateTime;
import javax.inject.Inject;
@ -24,7 +24,7 @@ public class DateAndTimePickerActivity extends InjectingAppCompatActivity implem
private static final String EXTRA_DATE_SELECTED = "extra_date_selected";
public static final String EXTRA_TIMESTAMP = "extra_timestamp";
@Inject ActivityPreferences preferences;
@Inject ThemeManager themeManager;
private DateTime initial;
private boolean dateSelected;
@ -47,7 +47,7 @@ public class DateAndTimePickerActivity extends InjectingAppCompatActivity implem
if (datePickerDialog == null) {
datePickerDialog = new MyDatePickerDialog();
datePickerDialog.initialize(null, initial.getYear(), initial.getMonthOfYear() - 1, initial.getDayOfMonth());
datePickerDialog.setAccentColor(preferences.getDateTimePickerAccent());
datePickerDialog.setAccentColor(themeManager.getAppTheme().getDateTimePickerAccent());
datePickerDialog.show(fragmentManager, FRAG_TAG_DATE_PICKER);
}
datePickerDialog.setOnCancelListener(this);

@ -10,7 +10,7 @@ import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
import org.tasks.dialogs.MyDatePickerDialog;
import org.tasks.injection.ActivityComponent;
import org.tasks.injection.InjectingAppCompatActivity;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.ThemeManager;
import org.tasks.time.DateTime;
import javax.inject.Inject;
@ -24,7 +24,7 @@ public class DatePickerActivity extends InjectingAppCompatActivity
public static final String EXTRA_TIMESTAMP = "extra_timestamp";
@Inject ActivityPreferences preferences;
@Inject ThemeManager themeManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -38,7 +38,7 @@ public class DatePickerActivity extends InjectingAppCompatActivity
if (dialog == null) {
dialog = new MyDatePickerDialog();
dialog.initialize(null, initial.getYear(), initial.getMonthOfYear() - 1, initial.getDayOfMonth());
dialog.setAccentColor(preferences.getDateTimePickerAccent());
dialog.setAccentColor(themeManager.getAppTheme().getDateTimePickerAccent());
dialog.show(fragmentManager, FRAG_TAG_DATE_PICKER);
}
dialog.setOnDismissListener(this);

@ -13,7 +13,7 @@ import org.tasks.filters.FilterCounter;
import org.tasks.filters.FilterProvider;
import org.tasks.injection.ActivityComponent;
import org.tasks.injection.InjectingAppCompatActivity;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.ThemeManager;
import javax.inject.Inject;
@ -28,7 +28,7 @@ public class FilterSelectionActivity extends InjectingAppCompatActivity {
@Inject FilterProvider filterProvider;
@Inject FilterCounter filterCounter;
@Inject DialogBuilder dialogBuilder;
@Inject ActivityPreferences activityPreferences;
@Inject ThemeManager themeManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -36,9 +36,8 @@ public class FilterSelectionActivity extends InjectingAppCompatActivity {
final boolean returnFilter = getIntent().getBooleanExtra(EXTRA_RETURN_FILTER, false);
activityPreferences.applyDialogTheme();
final FilterAdapter filterAdapter = new FilterAdapter(filterProvider, filterCounter, this, null, false);
final FilterAdapter filterAdapter = new FilterAdapter(filterProvider, filterCounter, this,
themeManager.getAppTheme(), null, false);
filterAdapter.populateList();
dialogBuilder.newDialog()

@ -9,7 +9,7 @@ import com.todoroo.astrid.backup.TasksXmlImporter;
import org.tasks.files.FileExplore;
import org.tasks.injection.ActivityComponent;
import org.tasks.injection.InjectingAppCompatActivity;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.Preferences;
import javax.inject.Inject;
@ -18,7 +18,7 @@ public class ImportTaskActivity extends InjectingAppCompatActivity {
private static final int REQUEST_PICKER = 1000;
@Inject TasksXmlImporter xmlImporter;
@Inject ActivityPreferences preferences;
@Inject Preferences preferences;
@Override
protected void onCreate(Bundle savedInstanceState) {

@ -12,7 +12,7 @@ import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
import org.tasks.dialogs.MyTimePickerDialog;
import org.tasks.injection.ActivityComponent;
import org.tasks.injection.InjectingAppCompatActivity;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.ThemeManager;
import org.tasks.time.DateTime;
import javax.inject.Inject;
@ -26,7 +26,7 @@ public class TimePickerActivity extends InjectingAppCompatActivity implements Ti
public static final String EXTRA_TIMESTAMP = "extra_timestamp";
@Inject ActivityPreferences preferences;
@Inject ThemeManager themeManager;
private DateTime initial;
private boolean isChangingConfigurations;
@ -42,7 +42,7 @@ public class TimePickerActivity extends InjectingAppCompatActivity implements Ti
if (dialog == null) {
dialog = new MyTimePickerDialog();
dialog.initialize(null, initial.getHourOfDay(), initial.getMinuteOfHour(), 0, DateFormat.is24HourFormat(this));
dialog.setAccentColor(preferences.getDateTimePickerAccent());
dialog.setAccentColor(themeManager.getAppTheme().getDateTimePickerAccent());
dialog.show(fragmentManager, FRAG_TAG_TIME_PICKER);
}
dialog.setOnDismissListener(this);

@ -7,22 +7,22 @@ import android.support.v7.app.AlertDialog;
import com.todoroo.andlib.utility.AndroidUtilities;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.ThemeManager;
import javax.inject.Inject;
public class DialogBuilder {
private final Activity activity;
private final ActivityPreferences activityPreferences;
private ThemeManager themeManager;
@Inject
public DialogBuilder(Activity activity, ActivityPreferences activityPreferences) {
public DialogBuilder(Activity activity, ThemeManager themeManager) {
this.activity = activity;
this.activityPreferences = activityPreferences;
this.themeManager = themeManager;
}
public AlertDialog.Builder newDialog() {
return new AlertDialog.Builder(activity, activityPreferences.getDialogTheme());
return new AlertDialog.Builder(activity, themeManager.getDialogThemeResId());
}
public AlertDialog.Builder newMessageDialog(int message, Object... formatArgs) {
@ -30,7 +30,7 @@ public class DialogBuilder {
}
public ProgressDialog newProgressDialog() {
ProgressDialog progressDialog = new ProgressDialog(activity, activityPreferences.getDialogTheme());
ProgressDialog progressDialog = new ProgressDialog(activity, themeManager.getDialogThemeResId());
if (AndroidUtilities.preLollipop()) {
progressDialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.R.color.transparent));
}

@ -20,30 +20,33 @@ import org.tasks.R;
import org.tasks.injection.DialogFragmentComponent;
import org.tasks.injection.ForApplication;
import org.tasks.injection.InjectingDialogFragment;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.Preferences;
import org.tasks.preferences.Theme;
import org.tasks.preferences.ThemeManager;
import javax.inject.Inject;
public class ColorPickerDialog extends InjectingDialogFragment {
public class ThemePickerDialog extends InjectingDialogFragment {
public interface ColorPickerCallback {
void colorPicked(int index);
public interface ThemePickerCallback {
void themePicked(Theme theme);
void initiateThemePurchase();
}
@Inject DialogBuilder dialogBuilder;
@Inject @ForApplication Context context;
@Inject ActivityPreferences activityPreferences;
@Inject Preferences preferences;
@Inject ThemeManager themeManager;
private ColorPickerCallback callback;
private ThemePickerCallback callback;
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final String[] themes = context.getResources().getStringArray(R.array.themes);
final boolean purchasedThemes = activityPreferences.hasPurchase(R.string.p_purchased_themes);
final boolean purchasedThemes = preferences.hasPurchase(R.string.p_purchased_themes);
ListAdapter adapter = new ArrayAdapter<String>(context, R.layout.color_selection_row, themes) {
@Override
@ -56,13 +59,13 @@ public class ColorPickerDialog extends InjectingDialogFragment {
}
Resources resources = context.getResources();
Theme theme = themeManager.getTheme(position);
ImageView primary = (ImageView) row.findViewById(R.id.color_primary);
Drawable original = resources.getDrawable(purchasedThemes || position < 2
? R.drawable.ic_lens_black_24dp
: R.drawable.ic_vpn_key_black_24dp);
Drawable wrapped = DrawableCompat.wrap(original.mutate());
DrawableCompat.setTint(wrapped, activityPreferences.getPrimaryColor(position));
DrawableCompat.setTint(wrapped, theme.getPrimaryColor());
primary.setImageDrawable(wrapped);
TextView text = (TextView) row.findViewById(android.R.id.text1);
@ -78,7 +81,7 @@ public class ColorPickerDialog extends InjectingDialogFragment {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
if (purchasedThemes || which < 2) {
callback.colorPicked(which);
callback.themePicked(themeManager.getTheme(which));
} else {
callback.initiateThemePurchase();
}
@ -91,7 +94,7 @@ public class ColorPickerDialog extends InjectingDialogFragment {
public void onAttach(Activity activity) {
super.onAttach(activity);
callback = (ColorPickerCallback) activity;
callback = (ThemePickerCallback) activity;
}
@Override

@ -4,15 +4,20 @@ import android.os.Bundle;
import com.nononsenseapps.filepicker.FilePickerActivity;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.PermissionChecker;
import org.tasks.preferences.Preferences;
import org.tasks.preferences.ThemeApplicator;
import org.tasks.preferences.ThemeManager;
public class MyFilePickerActivity extends FilePickerActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
ActivityPreferences activityPreferences = new ActivityPreferences(this, new PermissionChecker(this));
activityPreferences.applyThemeAndStatusBarColor();
PermissionChecker permissionChecker = new PermissionChecker(this);
Preferences preferences = new Preferences(this, permissionChecker);
ThemeManager themeManager = new ThemeManager(this, preferences);
ThemeApplicator themeApplicator = new ThemeApplicator(this, themeManager);
themeApplicator.applyThemeAndStatusBarColor();
super.onCreate(savedInstanceState);
}

@ -1,6 +1,6 @@
package org.tasks.injection;
import org.tasks.dialogs.ColorPickerDialog;
import org.tasks.dialogs.ThemePickerDialog;
import org.tasks.widget.WidgetConfigDialog;
import org.tasks.activities.CalendarSelectionDialog;
@ -28,5 +28,5 @@ public interface DialogFragmentComponent {
void inject(WidgetConfigDialog widgetConfigDialog);
void inject(ColorPickerDialog colorPickerDialog);
void inject(ThemePickerDialog themePickerDialog);
}

@ -4,6 +4,7 @@ import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import org.tasks.analytics.Tracker;
import org.tasks.preferences.ThemeApplicator;
import javax.inject.Inject;

@ -5,7 +5,6 @@ import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v7.widget.Toolbar;
import android.view.View;
@ -14,8 +13,8 @@ import android.widget.LinearLayout;
import org.tasks.R;
import org.tasks.analytics.Tracker;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.AppCompatPreferenceActivity;
import org.tasks.preferences.ThemeApplicator;
import javax.inject.Inject;
@ -25,7 +24,7 @@ public abstract class InjectingPreferenceActivity extends AppCompatPreferenceAct
protected Toolbar toolbar;
@Inject ActivityPreferences activityPreferences;
@Inject ThemeApplicator themeApplicator;
@Inject Tracker tracker;
@Override
@ -35,7 +34,7 @@ public abstract class InjectingPreferenceActivity extends AppCompatPreferenceAct
.plus(new ActivityModule(this));
inject(activityComponent);
activityPreferences.applyThemeAndStatusBarColor();
themeApplicator.applyThemeAndStatusBarColor();
super.onCreate(savedInstanceState);

@ -0,0 +1,19 @@
package org.tasks.injection;
import android.os.Bundle;
import org.tasks.preferences.ThemeApplicator;
import javax.inject.Inject;
public abstract class ThemedInjectingAppCompatActivity extends InjectingAppCompatActivity {
@Inject ThemeApplicator themeApplicator;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
themeApplicator.applyThemeAndStatusBarColor();
}
}

@ -1,137 +0,0 @@
package org.tasks.preferences;
import android.app.Activity;
import android.content.Context;
import android.graphics.PixelFormat;
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import org.tasks.R;
import javax.inject.Inject;
import javax.inject.Singleton;
import static com.todoroo.andlib.utility.AndroidUtilities.atLeastLollipop;
@Singleton
public class ActivityPreferences extends Preferences {
private final Activity activity;
@Inject
public ActivityPreferences(Activity activity, PermissionChecker permissionChecker) {
super(activity, permissionChecker);
this.activity = activity;
}
public void applyThemeAndStatusBarColor() {
applyTheme();
applyStatusBarColor();
}
public String getThemeName() {
int themeIndex = getInt(R.string.p_theme, 0);
String[] themeNames = activity.getResources().getStringArray(R.array.themes);
return themeNames[themeIndex];
}
public void applyTheme() {
applyTheme(getTheme());
}
public void applyDialogTheme() {
applyTheme(getDialogTheme());
}
private void applyTheme(int theme) {
activity.setTheme(theme);
activity.getWindow().setFormat(PixelFormat.RGBA_8888);
}
private void applyStatusBarColor() {
if (atLeastLollipop()) {
activity.getWindow().setStatusBarColor(getPrimaryDarkColor());
}
}
public int getTheme() {
return getTheme(getInt(R.string.p_theme, -1));
}
public int getDialogTheme() {
Context contextThemeWrapper = new ContextThemeWrapper(activity, getTheme());
TypedValue typedValue = new TypedValue();
contextThemeWrapper.getTheme().resolveAttribute(R.attr.alertDialogTheme, typedValue, true);
return typedValue.data;
}
public int getDateTimePickerAccent() {
Context contextThemeWrapper = new ContextThemeWrapper(activity, getTheme());
TypedValue typedValue = new TypedValue();
contextThemeWrapper.getTheme().resolveAttribute(R.attr.asDateTimePickerAccent, typedValue, true);
return typedValue.data;
}
public int getPrimaryDarkColor() {
return getColorAttribute(R.attr.colorPrimaryDark);
}
private int getColorAttribute(int attribute) {
TypedValue typedValue = new TypedValue();
activity.getTheme().resolveAttribute(attribute, typedValue, true);
return typedValue.data;
}
public int getPrimaryColor(int themeIndex) {
Context contextThemeWrapper = new ContextThemeWrapper(activity, getTheme(themeIndex));
TypedValue typedValue = new TypedValue();
contextThemeWrapper.getTheme().resolveAttribute(R.attr.colorPrimary, typedValue, true);
return typedValue.data;
}
public int getTheme(int index) {
switch (index) {
case 1:
return R.style.Black;
case 2:
return R.style.Red;
case 3:
return R.style.Pink;
case 4:
return R.style.Purple;
case 5:
return R.style.DeepPurple;
case 6:
return R.style.Indigo;
case 7:
return R.style.Blue;
case 8:
return R.style.LightBlue;
case 9:
return R.style.Cyan;
case 10:
return R.style.Teal;
case 11:
return R.style.Green;
case 12:
return R.style.LightGreen;
case 13:
return R.style.Lime;
case 14:
return R.style.Yellow;
case 15:
return R.style.Amber;
case 16:
return R.style.Orange;
case 17:
return R.style.DeepOrange;
case 18:
return R.style.Brown;
case 19:
return R.style.Grey;
case 0:
default:
return R.style.BlueGrey;
}
}
}

@ -12,19 +12,20 @@ import com.todoroo.astrid.reminders.ReminderPreferences;
import org.tasks.R;
import org.tasks.analytics.Tracker;
import org.tasks.analytics.Tracking;
import org.tasks.dialogs.ColorPickerDialog;
import org.tasks.dialogs.ThemePickerDialog;
import org.tasks.injection.InjectingPreferenceActivity;
import javax.inject.Inject;
public abstract class BaseBasicPreferences extends InjectingPreferenceActivity implements ColorPickerDialog.ColorPickerCallback {
public abstract class BaseBasicPreferences extends InjectingPreferenceActivity implements ThemePickerDialog.ThemePickerCallback {
private static final String EXTRA_RESULT = "extra_result";
private static final String FRAG_TAG_THEME_PICKER = "frag_tag_theme_picker";
private static final int RC_PREFS = 10001;
@Inject Tracker tracker;
@Inject ActivityPreferences activityPreferences;
@Inject ThemeManager themeManager;
@Inject Preferences preferences;
private Bundle result;
@Override
@ -38,13 +39,13 @@ public abstract class BaseBasicPreferences extends InjectingPreferenceActivity i
addPreferencesFromResource(R.xml.preferences_privacy);
Preference themePreference = findPreference(getString(R.string.p_theme));
themePreference.setSummary(activityPreferences.getThemeName());
themePreference.setSummary(themeManager.getAppTheme().getName());
themePreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
FragmentManager fragmentManager = getFragmentManager();
if (fragmentManager.findFragmentByTag(FRAG_TAG_THEME_PICKER) == null) {
new ColorPickerDialog()
new ThemePickerDialog()
.show(fragmentManager, FRAG_TAG_THEME_PICKER);
}
return false;
@ -95,8 +96,9 @@ public abstract class BaseBasicPreferences extends InjectingPreferenceActivity i
}
@Override
public void colorPicked(int index) {
activityPreferences.setInt(R.string.p_theme, index);
public void themePicked(Theme theme) {
int index = theme.getThemeIndex();
preferences.setInt(R.string.p_theme, index);
tracker.reportEvent(Tracking.Events.SET_THEME, Integer.toString(index));
result.putBoolean(AppearancePreferences.EXTRA_RESTART, true);
recreate();

@ -80,6 +80,7 @@ public class Preferences {
return setting < 0 || setting > DateTime.MAX_MILLIS_PER_DAY ? defaultValue : setting;
}
@Deprecated
public boolean useDarkWidgetTheme(int widgetId) {
return getBoolean(WidgetConfigActivity.PREF_DARK_THEME + widgetId, false);
}

@ -0,0 +1,72 @@
package org.tasks.preferences;
import android.content.Context;
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import org.tasks.R;
public class Theme {
private final Context context;
private final int themeRes;
private final int themeIndex;
private final String name;
public Theme(Context context, int themeIndex, int themeRes, String name) {
this.themeIndex = themeIndex;
this.name = name;
this.context = new ContextThemeWrapper(context, themeRes);
this.themeRes = themeRes;
}
public LayoutInflater getThemedLayoutInflater() {
return (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public boolean isDark() {
return themeIndex == 1;
}
public String getName() {
return name;
}
public int getThemeIndex() {
return themeIndex;
}
public int getPrimaryColor() {
return resolveAttribute(R.attr.colorPrimary);
}
public int getContentBackground() {
return resolveAttribute(R.attr.asContentBackground);
}
public int getPrimaryDarkColor() {
return resolveAttribute(R.attr.colorPrimaryDark);
}
public int getTextColor() {
return resolveAttribute(R.attr.asTextColor);
}
public int getDateTimePickerAccent() {
return resolveAttribute(R.attr.asDateTimePickerAccent);
}
public int getAppThemeResId() {
return themeRes;
}
public int getDialogThemeResId() {
return resolveAttribute(R.attr.alertDialogTheme);
}
private int resolveAttribute(int attribute) {
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(attribute, typedValue, true);
return typedValue.data;
}
}

@ -0,0 +1,46 @@
package org.tasks.preferences;
import android.app.Activity;
import android.graphics.PixelFormat;
import javax.inject.Inject;
import static com.todoroo.andlib.utility.AndroidUtilities.atLeastLollipop;
public class ThemeApplicator {
private final Activity activity;
private final ThemeManager themeManager;
@Inject
public ThemeApplicator(Activity activity, ThemeManager themeManager) {
this.activity = activity;
this.themeManager = themeManager;
}
public void applyThemeAndStatusBarColor() {
applyTheme();
applyStatusBarColor();
}
public void applyTheme() {
Theme appTheme = themeManager.getAppTheme();
applyTheme(appTheme.getAppThemeResId());
}
public void applyDialogTheme() {
Theme appTheme = themeManager.getAppTheme();
applyTheme(appTheme.getDialogThemeResId());
}
private void applyTheme(int theme) {
activity.setTheme(theme);
activity.getWindow().setFormat(PixelFormat.RGBA_8888);
}
private void applyStatusBarColor() {
if (atLeastLollipop()) {
Theme appTheme = themeManager.getAppTheme();
activity.getWindow().setStatusBarColor(appTheme.getPrimaryDarkColor());
}
}
}

@ -0,0 +1,88 @@
package org.tasks.preferences;
import android.content.Context;
import org.tasks.R;
import org.tasks.injection.ForApplication;
import org.tasks.widget.WidgetConfigActivity;
import javax.inject.Inject;
import javax.inject.Singleton;
@Singleton
public class ThemeManager {
private final Context context;
private final Preferences preferences;
private final String[] themeNames;
@Inject
public ThemeManager(@ForApplication Context context, Preferences preferences) {
this.context = context;
this.preferences = preferences;
themeNames = context.getResources().getStringArray(R.array.themes);
}
public Theme getAppTheme() {
return getTheme(preferences.getInt(R.string.p_theme, 0));
}
public Theme getTheme(int themeIndex) {
return new Theme(context, themeIndex, getStyle(themeIndex), themeNames[themeIndex]);
}
public Theme getWidgetTheme(int widgetId) {
int defaultTheme = preferences.useDarkWidgetTheme(widgetId) ? 1 : 0;
return getTheme(preferences.getInt(WidgetConfigActivity.PREF_THEME + widgetId, defaultTheme));
}
public int getDialogThemeResId() {
return getAppTheme().getDialogThemeResId();
}
private int getStyle(int index) {
switch (index) {
case 1:
return R.style.Black;
case 2:
return R.style.Red;
case 3:
return R.style.Pink;
case 4:
return R.style.Purple;
case 5:
return R.style.DeepPurple;
case 6:
return R.style.Indigo;
case 7:
return R.style.Blue;
case 8:
return R.style.LightBlue;
case 9:
return R.style.Cyan;
case 10:
return R.style.Teal;
case 11:
return R.style.Green;
case 12:
return R.style.LightGreen;
case 13:
return R.style.Lime;
case 14:
return R.style.Yellow;
case 15:
return R.style.Amber;
case 16:
return R.style.Orange;
case 17:
return R.style.DeepOrange;
case 18:
return R.style.Brown;
case 19:
return R.style.Grey;
case 0:
default:
return R.style.BlueGrey;
}
}
}

@ -23,7 +23,7 @@ import org.tasks.activities.DatePickerActivity;
import org.tasks.activities.TimePickerActivity;
import org.tasks.injection.ForActivity;
import org.tasks.injection.FragmentComponent;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.Preferences;
import org.tasks.time.DateTime;
import java.util.ArrayList;
@ -64,7 +64,7 @@ public class DeadlineControlSet extends TaskEditControlFragment {
private String todayString;
private String tomorrowString;
@Inject ActivityPreferences preferences;
@Inject Preferences preferences;
@Inject @ForActivity Context context;
@Bind(R.id.due_date) Spinner dueDateSpinner;

@ -29,6 +29,7 @@ import org.tasks.filters.NavigationDrawerAction;
import org.tasks.injection.FragmentComponent;
import org.tasks.injection.InjectingFragment;
import org.tasks.preferences.AppearancePreferences;
import org.tasks.preferences.ThemeManager;
import javax.inject.Inject;
@ -61,6 +62,7 @@ public class NavigationDrawerFragment extends InjectingFragment {
@Inject FilterCounter filterCounter;
@Inject FilterProvider filterProvider;
@Inject ThemeManager themeManager;
@Override
public void onCreate(Bundle savedInstanceState) {
@ -138,7 +140,8 @@ public class NavigationDrawerFragment extends InjectingFragment {
}
private void setUpList() {
adapter = new FilterAdapter(filterProvider, filterCounter, getActivity(), mDrawerListView, true);
adapter = new FilterAdapter(filterProvider, filterCounter, getActivity(),
themeManager.getAppTheme(), mDrawerListView, true);
mDrawerListView.setAdapter(adapter);
registerForContextMenu(mDrawerListView);
}

@ -1,6 +1,5 @@
package org.tasks.widget;
import android.app.Fragment;
import android.app.FragmentManager;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
@ -9,13 +8,14 @@ import android.os.Bundle;
import org.tasks.R;
import org.tasks.analytics.Tracker;
import org.tasks.analytics.Tracking;
import org.tasks.injection.ActivityComponent;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.dialogs.ThemePickerDialog;
import org.tasks.injection.InjectingAppCompatActivity;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.preferences.Theme;
import javax.inject.Inject;
public class WidgetConfigActivity extends InjectingAppCompatActivity implements WidgetConfigDialog.WidgetConfigCallback {
public abstract class BaseWidgetConfigActivity extends InjectingAppCompatActivity implements WidgetConfigDialog.WidgetConfigCallback, ThemePickerDialog.ThemePickerCallback {
private static final String FRAG_TAG_WIDGET_CONFIG = "frag_tag_widget_config";
@ -24,14 +24,16 @@ public class WidgetConfigActivity extends InjectingAppCompatActivity implements
public static final String PREF_WIDGET_ID = "widget-id-";
public static final String PREF_SHOW_DUE_DATE = "widget-show-due-date-";
public static final String PREF_HIDE_CHECKBOXES = "widget-hide-checkboxes-";
public static final String PREF_DARK_THEME = "widget-dark-theme-";
@Deprecated public static final String PREF_DARK_THEME = "widget-dark-theme-";
public static final String PREF_THEME = "widget-theme-";
public static final String PREF_HIDE_HEADER = "widget-hide-header-";
public static final String PREF_WIDGET_OPACITY = "widget-opacity-";
private int appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
@Inject ActivityPreferences preferences;
@Inject Tracker tracker;
@Inject DialogBuilder dialogBuilder;
private int appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
private WidgetConfigDialog widgetConfigDialog;
@Override
public void onCreate(Bundle savedInstanceState) {
@ -49,32 +51,35 @@ public class WidgetConfigActivity extends InjectingAppCompatActivity implements
if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish();
} else {
preferences.applyDialogTheme();
FragmentManager fragmentManager = getFragmentManager();
Fragment fragment = fragmentManager.findFragmentByTag(FRAG_TAG_WIDGET_CONFIG);
if (fragment == null) {
WidgetConfigDialog widgetConfigDialog = WidgetConfigDialog.newWidgetConfigDialog(appWidgetId);
widgetConfigDialog = (WidgetConfigDialog) fragmentManager.findFragmentByTag(FRAG_TAG_WIDGET_CONFIG);
if (widgetConfigDialog == null) {
widgetConfigDialog = WidgetConfigDialog.newWidgetConfigDialog(appWidgetId);
widgetConfigDialog.show(fragmentManager, FRAG_TAG_WIDGET_CONFIG);
}
}
}
@Override
public void inject(ActivityComponent component) {
component.inject(this);
}
@Override
public void ok() {
tracker.reportEvent(Tracking.Events.WIDGET_ADD, getString(R.string.app_name));
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
setResult(RESULT_OK, resultValue);
finish();
}
@Override
public void done() {
public void cancel() {
finish();
}
@Override
public void themePicked(Theme theme) {
widgetConfigDialog.setTheme(theme);
}
protected void showThemeSelection() {
widgetConfigDialog.showThemeSelection();
}
}

@ -24,6 +24,7 @@ import org.tasks.BuildConfig;
import org.tasks.R;
import org.tasks.preferences.DefaultFilterProvider;
import org.tasks.preferences.Preferences;
import org.tasks.preferences.Theme;
import org.tasks.ui.WidgetCheckBoxes;
import timber.log.Timber;
@ -31,6 +32,7 @@ import timber.log.Timber;
public class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
private final WidgetCheckBoxes checkBoxes;
private final int themeTextColor;
private final int widgetId;
private final Database database;
private final TaskService taskService;
@ -39,7 +41,6 @@ public class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFac
private final Preferences preferences;
private final Context context;
private final String filterId;
private final boolean dark;
private final boolean showDueDates;
private final boolean hideCheckboxes;
@ -50,6 +51,7 @@ public class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFac
Preferences preferences,
Context context,
String filterId,
Theme theme,
int widgetId,
Database database,
TaskService taskService,
@ -63,8 +65,8 @@ public class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFac
this.taskService = taskService;
this.defaultFilterProvider = defaultFilterProvider;
themeTextColor = theme.getTextColor();
checkBoxes = new WidgetCheckBoxes(context);
dark = preferences.useDarkWidgetTheme(widgetId);
showDueDates = preferences.getBoolean(WidgetConfigActivity.PREF_SHOW_DUE_DATE + widgetId, false);
hideCheckboxes = preferences.getBoolean(WidgetConfigActivity.PREF_HIDE_CHECKBOXES + widgetId, false);
}
@ -134,7 +136,7 @@ public class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFac
}
String textContent;
Resources r = context.getResources();
int textColor = r.getColor(dark ? R.color.widget_text_color_dark : R.color.widget_text_color_light);
int textColor = themeTextColor;
textContent = task.getTitle();

@ -12,6 +12,8 @@ import org.tasks.injection.InjectingRemoteViewsService;
import org.tasks.injection.ServiceComponent;
import org.tasks.preferences.DefaultFilterProvider;
import org.tasks.preferences.Preferences;
import org.tasks.preferences.Theme;
import org.tasks.preferences.ThemeManager;
import javax.inject.Inject;
@ -24,6 +26,7 @@ public class ScrollableWidgetUpdateService extends InjectingRemoteViewsService {
@Inject Preferences preferences;
@Inject SubtasksHelper subtasksHelper;
@Inject DefaultFilterProvider defaultFilterProvider;
@Inject ThemeManager themeManager;
@Override
public void onStart(Intent intent, int startId) {
@ -45,8 +48,9 @@ public class ScrollableWidgetUpdateService extends InjectingRemoteViewsService {
String filterId = (String) extras.get(FILTER_ID);
int widgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
Theme theme = themeManager.getWidgetTheme(widgetId);
return new ScrollableViewsFactory(subtasksHelper, preferences, this, filterId,
widgetId, database, taskService, defaultFilterProvider);
theme, widgetId, database, taskService, defaultFilterProvider);
}
@Override

@ -20,6 +20,8 @@ import org.tasks.injection.InjectingAppWidgetProvider;
import org.tasks.intents.TaskIntents;
import org.tasks.preferences.DefaultFilterProvider;
import org.tasks.preferences.Preferences;
import org.tasks.preferences.Theme;
import org.tasks.preferences.ThemeManager;
import javax.inject.Inject;
@ -37,6 +39,7 @@ public class TasksWidget extends InjectingAppWidgetProvider {
@Inject Broadcaster broadcaster;
@Inject Preferences preferences;
@Inject DefaultFilterProvider defaultFilterProvider;
@Inject ThemeManager themeManager;
public static final String COMPLETE_TASK = "COMPLETE_TASK";
public static final String EDIT_TASK = "EDIT_TASK";
@ -93,21 +96,21 @@ public class TasksWidget extends InjectingAppWidgetProvider {
rvIntent.putExtra(ScrollableWidgetUpdateService.FILTER_ID, filterId);
rvIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id);
rvIntent.setData(Uri.parse(rvIntent.toUri(Intent.URI_INTENT_SCHEME)));
boolean darkTheme = preferences.useDarkWidgetTheme(id);
Theme theme = themeManager.getWidgetTheme(id);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.scrollable_widget);
if (preferences.getBoolean(WidgetConfigActivity.PREF_HIDE_HEADER + id, false)) {
remoteViews.setViewVisibility(R.id.widget_header, View.GONE);
}
int opacity = preferences.getInt(WidgetConfigActivity.PREF_WIDGET_OPACITY + id, WidgetConfigActivity.DEFAULT_OPACITY);
remoteViews.setImageViewBitmap(R.id.widget_background,
getSolidBackground(context.getResources().getColor(darkTheme ? R.color.widget_body_dark : R.color.widget_body_light)));
getSolidBackground(theme.getContentBackground()));
remoteViews.setImageViewBitmap(R.id.widget_header_background,
getSolidBackground(context.getResources().getColor(darkTheme ? R.color.widget_header_dark : R.color.blue_grey_500)));
getSolidBackground(theme.getPrimaryColor()));
if (opacity < 100) {
remoteViews.setInt(R.id.widget_background, "setAlpha", opacity);
remoteViews.setInt(R.id.widget_header_background, "setAlpha", opacity);
}
if (!darkTheme) {
if (!theme.isDark()) {
remoteViews.setInt(R.id.widget_header_separator, "setVisibility", View.GONE);
}

@ -2,6 +2,7 @@ package org.tasks.widget;
import android.app.Activity;
import android.app.Dialog;
import android.app.FragmentManager;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.DialogInterface;
@ -16,12 +17,15 @@ import com.todoroo.astrid.api.Filter;
import org.tasks.R;
import org.tasks.activities.FilterSelectionActivity;
import org.tasks.dialogs.ThemePickerDialog;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.DialogFragmentComponent;
import org.tasks.injection.ForApplication;
import org.tasks.injection.InjectingDialogFragment;
import org.tasks.preferences.DefaultFilterProvider;
import org.tasks.preferences.Preferences;
import org.tasks.preferences.Theme;
import org.tasks.preferences.ThemeManager;
import javax.inject.Inject;
@ -31,19 +35,19 @@ import butterknife.OnClick;
public class WidgetConfigDialog extends InjectingDialogFragment implements SeekBar.OnSeekBarChangeListener {
private static final String FRAG_TAG_THEME_SELECTION = "frag_tag_theme_selection";
private static final String EXTRA_FILTER = "extra_filter";
private static final String EXTRA_THEME = "extra_theme";
private static final String EXTRA_APP_WIDGET_ID = "extra_app_widget_id";
public static WidgetConfigDialog newWidgetConfigDialog(int appWidgetId) {
WidgetConfigDialog dialog = new WidgetConfigDialog();
dialog.setAppWidgetId(appWidgetId);
dialog.appWidgetId = appWidgetId;
return dialog;
}
public void setAppWidgetId(int appWidgetId) {
this.appWidgetId = appWidgetId;
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
opacity = progress;
updateOpacity();
}
@ -57,18 +61,23 @@ public class WidgetConfigDialog extends InjectingDialogFragment implements SeekB
}
public void setTheme(Theme theme) {
this.theme = theme.getThemeIndex();
updateTheme();
}
public interface WidgetConfigCallback {
void ok();
void done();
void cancel();
}
private static final int REQUEST_FILTER = 1005;
@Bind(R.id.opacity_value) TextView opacityValue;
@Bind(R.id.selected_filter) TextView selectedFilter;
@Bind(R.id.selected_theme) TextView selectedTheme;
@Bind(R.id.hideDueDate) CheckBox hideDueDate;
@Bind(R.id.darkTheme) CheckBox darkTheme;
@Bind(R.id.hideCheckboxes) CheckBox hideCheckBoxes;
@Bind(R.id.hideHeader) CheckBox hideHeader;
@Bind(R.id.opacity_seekbar) SeekBar opacitySeekbar;
@ -77,25 +86,33 @@ public class WidgetConfigDialog extends InjectingDialogFragment implements SeekB
@Inject DefaultFilterProvider defaultFilterProvider;
@Inject Preferences preferences;
@Inject @ForApplication Context context;
@Inject ThemeManager themeManager;
private int opacity = WidgetConfigActivity.DEFAULT_OPACITY;
private Filter filter;
private int theme = 0;
private int appWidgetId;
private WidgetConfigCallback callback;
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View view = getActivity().getLayoutInflater().inflate(R.layout.widget_config_activity, null);
View view = themeManager.getAppTheme().getThemedLayoutInflater().inflate(R.layout.widget_config_activity, null);
ButterKnife.bind(this, view);
opacitySeekbar.setProgress(opacity);
opacitySeekbar.setOnSeekBarChangeListener(this);
filter = defaultFilterProvider.getDefaultFilter();
if (savedInstanceState != null) {
theme = savedInstanceState.getInt(EXTRA_THEME);
filter = savedInstanceState.getParcelable(EXTRA_FILTER);
appWidgetId = savedInstanceState.getInt(EXTRA_APP_WIDGET_ID);
} else {
filter = defaultFilterProvider.getDefaultFilter();
opacitySeekbar.setProgress(WidgetConfigActivity.DEFAULT_OPACITY);
}
updateFilter();
updateTheme();
updateOpacity();
return dialogBuilder.newDialog()
@ -112,10 +129,19 @@ public class WidgetConfigDialog extends InjectingDialogFragment implements SeekB
}
@Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(EXTRA_APP_WIDGET_ID, appWidgetId);
outState.putInt(EXTRA_THEME, theme);
outState.putParcelable(EXTRA_FILTER, filter);
}
@Override
public void onCancel(DialogInterface dialog) {
super.onCancel(dialog);
callback.done();
callback.cancel();
}
@Override
@ -130,7 +156,11 @@ public class WidgetConfigDialog extends InjectingDialogFragment implements SeekB
}
private void updateOpacity() {
opacityValue.setText(Integer.toString(opacity));
opacityValue.setText(Integer.toString(opacitySeekbar.getProgress()));
}
private void updateTheme() {
selectedTheme.setText(themeManager.getTheme(theme).getName());
}
@OnClick(R.id.filter_selection)
@ -140,6 +170,14 @@ public class WidgetConfigDialog extends InjectingDialogFragment implements SeekB
}}, REQUEST_FILTER);
}
@OnClick(R.id.theme_selection)
public void showThemeSelection() {
FragmentManager fragmentManager = getFragmentManager();
if (fragmentManager.findFragmentByTag(FRAG_TAG_THEME_SELECTION) == null) {
new ThemePickerDialog().show(fragmentManager, FRAG_TAG_THEME_SELECTION);
}
}
@Override
protected void inject(DialogFragmentComponent component) {
component.inject(this);
@ -160,10 +198,10 @@ public class WidgetConfigDialog extends InjectingDialogFragment implements SeekB
private void saveConfiguration(){
preferences.setString(WidgetConfigActivity.PREF_WIDGET_ID + appWidgetId, defaultFilterProvider.getFilterPreferenceValue(filter));
preferences.setBoolean(WidgetConfigActivity.PREF_SHOW_DUE_DATE + appWidgetId, !hideDueDate.isChecked());
preferences.setBoolean(WidgetConfigActivity.PREF_DARK_THEME + appWidgetId, darkTheme.isChecked());
preferences.setBoolean(WidgetConfigActivity.PREF_HIDE_CHECKBOXES + appWidgetId, hideCheckBoxes.isChecked());
preferences.setBoolean(WidgetConfigActivity.PREF_HIDE_HEADER + appWidgetId, hideHeader.isChecked());
preferences.setInt(WidgetConfigActivity.PREF_WIDGET_OPACITY + appWidgetId, opacity);
preferences.setInt(WidgetConfigActivity.PREF_THEME + appWidgetId, theme);
preferences.setInt(WidgetConfigActivity.PREF_WIDGET_OPACITY + appWidgetId, opacitySeekbar.getProgress());
// force update after setting preferences
context.sendBroadcast(new Intent(context, TasksWidget.class) {{

@ -1,91 +1,113 @@
<?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"
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/filter_selection"
style="@style/WidgetConfigRow">
<TextView
android:id="@+id/selected_filter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:textColor="?attr/asTextColor"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toLeftOf="@id/selected_filter"
android:layout_toStartOf="@id/selected_filter"
android:text="@string/filter"
android:textColor="?attr/asTextColor"
android:textSize="18sp" />
</RelativeLayout>
<RelativeLayout
style="@style/WidgetConfigRow">
<TextView
android:id="@+id/opacity_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:textColor="?attr/asTextColor"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toLeftOf="@id/opacity_value"
android:layout_toStartOf="@id/opacity_value"
android:text="@string/opacity"
android:textColor="?attr/asTextColor"
android:textSize="18sp" />
</RelativeLayout>
<SeekBar
android:id="@+id/opacity_seekbar"
style="@style/WidgetConfigRow"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<CheckBox
android:id="@+id/darkTheme"
style="@style/WidgetConfigRow.CheckBox"
android:checked="false"
android:text="@string/EPr_use_dark_theme" />
<CheckBox
android:id="@+id/hideDueDate"
style="@style/WidgetConfigRow.CheckBox"
android:checked="false"
android:text="@string/widget_hide_due_date" />
<CheckBox
android:id="@+id/hideCheckboxes"
style="@style/WidgetConfigRow.CheckBox"
android:checked="false"
android:text="@string/widget_hide_checkboxes" />
<CheckBox
android:id="@+id/hideHeader"
style="@style/WidgetConfigRow.CheckBox"
android:checked="false"
android:text="@string/widget_hide_header" />
</LinearLayout>
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/filter_selection"
style="@style/WidgetConfigRow">
<TextView
android:id="@+id/selected_filter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:textColor="?attr/asTextColor"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toLeftOf="@id/selected_filter"
android:layout_toStartOf="@id/selected_filter"
android:text="@string/filter"
android:textColor="?attr/asTextColor"
android:textSize="18sp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/theme_selection"
style="@style/WidgetConfigRow">
<TextView
android:id="@+id/selected_theme"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:textColor="?attr/asTextColor"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toLeftOf="@id/selected_theme"
android:layout_toStartOf="@id/selected_theme"
android:text="@string/theme"
android:textColor="?attr/asTextColor"
android:textSize="18sp" />
</RelativeLayout>
<RelativeLayout style="@style/WidgetConfigRow">
<TextView
android:id="@+id/opacity_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:textColor="?attr/asTextColor"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toLeftOf="@id/opacity_value"
android:layout_toStartOf="@id/opacity_value"
android:text="@string/opacity"
android:textColor="?attr/asTextColor"
android:textSize="18sp" />
</RelativeLayout>
<SeekBar
android:id="@+id/opacity_seekbar"
style="@style/WidgetConfigRow"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<CheckBox
android:id="@+id/hideDueDate"
style="@style/WidgetConfigRow.CheckBox"
android:checked="false"
android:text="@string/widget_hide_due_date" />
<CheckBox
android:id="@+id/hideCheckboxes"
style="@style/WidgetConfigRow.CheckBox"
android:checked="false"
android:text="@string/widget_hide_checkboxes" />
<CheckBox
android:id="@+id/hideHeader"
style="@style/WidgetConfigRow.CheckBox"
android:checked="false"
android:text="@string/widget_hide_header" />
</LinearLayout>
</ScrollView>

@ -14,7 +14,7 @@
<LinearLayout android:id="@+id/taskbody"
android:layout_width="fill_parent"
android:layout_height="120dip"
android:background="@color/widget_body_light"
android:background="#ffffff"
android:orientation="vertical">
<TextView
@ -24,8 +24,7 @@
android:layout_marginTop="37dip"
android:padding="10dip"
android:gravity="center"
android:text="@string/TWi_loading"
style="@style/TextAppearance.Widget" />
android:text="@string/TWi_loading" />
</LinearLayout>
</LinearLayout>

@ -30,21 +30,21 @@
<TextView
android:id="@+id/widget_text"
style="@style/TextAppearance.Widget"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:singleLine="true" />
android:singleLine="true"
android:textSize="16sp" />
<TextView
android:id="@+id/widget_due_date"
style="@style/TextAppearance.WidgetDueDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center_vertical"
android:singleLine="true"
android:visibility="gone"/>
android:visibility="gone"
android:textSize="12sp" />
</LinearLayout>

@ -148,7 +148,6 @@
<string name="TEA_timer_comment_spent">الوقت المنقضي</string>
<string name="voice_create_prompt">تحدث لإنشاء مهمه</string>
<string name="EPr_voiceRemindersEnabled_title">منبهات الصوت</string>
<string name="EPr_use_dark_theme">خلفية داكنه</string>
<string name="delete_task">حذف المهمة</string>
<string name="voice_command_added_task">مهام مضافه</string>
<plurals name="Ntasks">

@ -268,7 +268,6 @@
<string name="EPr_voiceInputEnabled_title">Гласово въвеждане</string>
<string name="EPr_voiceRemindersEnabled_title">Гласови напомняния</string>
<string name="EPr_voiceRemindersEnabled_desc_enabled">Tasks ще изтоваря имената на задачите по време на напомняния за задача</string>
<string name="EPr_use_dark_theme">Тъмна тема</string>
<string name="delete_task">Изтрий задача</string>
<string name="voice_command_added_task">Добавена задача</string>
<string name="external_storage_unavailable">Не може да достъпвате до външната памет</string>

@ -222,7 +222,6 @@
<string name="TEA_timer_comment_spent">Strávený čas:</string>
<string name="voice_create_prompt">Mluvte pro vytvoření úkolu</string>
<string name="EPr_voiceRemindersEnabled_title">Hlasové upomínky</string>
<string name="EPr_use_dark_theme">Tmavé téma</string>
<string name="delete_task">Smazat úkol</string>
<string name="voice_command_added_task">Přidán úkol</string>
<string name="external_storage_unavailable">Není přístup k externí databázi</string>

@ -257,7 +257,6 @@
<string name="EPr_voiceInputEnabled_title">Spracheingabe aktivieren</string>
<string name="EPr_voiceRemindersEnabled_title">Sprach-Erinnerungen</string>
<string name="EPr_voiceRemindersEnabled_desc_enabled">Tasks wird Aufgabennamen bei der Erinnerung aussprechen</string>
<string name="EPr_use_dark_theme">Dunkles Theme</string>
<string name="delete_task">Aufgabe löschen</string>
<string name="voice_command_added_task">Hinzugefügte Aufgabe</string>
<string name="external_storage_unavailable">Kein Zugriff auf externen Speicher</string>

@ -224,7 +224,6 @@
<string name="EPr_voiceInputEnabled_title">Εισαγωγή φωνής</string>
<string name="EPr_voiceRemindersEnabled_title">Φωνητικές υπενθυμίσεις</string>
<string name="EPr_voiceRemindersEnabled_desc_enabled">Η εφαρμογή θα λέει να ονόματα των εργασιών κατά την διάρκεια των υπενθυμίσεων</string>
<string name="EPr_use_dark_theme">Σκοτεινό θέμα</string>
<string name="delete_task">Διαγραφή καθήκοντος</string>
<string name="voice_command_added_task">Η εργασία προστέθηκε</string>
<string name="external_storage_unavailable">Δεν είναι δυνατή η πρόσβαση σε εξωτερικά μέσα αποθήκευσης</string>

@ -261,7 +261,6 @@
<string name="EPr_voiceInputEnabled_title">Ingreso por voz</string>
<string name="EPr_voiceRemindersEnabled_title">Avisos de voz</string>
<string name="EPr_voiceRemindersEnabled_desc_enabled">Tasks dirá los nombres de las tareas durante los avisos</string>
<string name="EPr_use_dark_theme">Estilo oscuro</string>
<string name="delete_task">Eliminar tarea</string>
<string name="voice_command_added_task">Tarea agregada</string>
<string name="external_storage_unavailable">Almacenamiento externo inaccesible</string>

@ -194,7 +194,6 @@
<string name="voice_create_prompt">برای ایجاد یک وظیفه صحبت کنید</string>
<string name="EPr_voiceInputEnabled_title">ورودی صدا</string>
<string name="EPr_voiceRemindersEnabled_title">یادآور صوتی</string>
<string name="EPr_use_dark_theme">تم تاریک</string>
<string name="delete_task">حذف وظیفه</string>
<string name="voice_command_added_task">وظیفه اضافه شده</string>
<string name="external_storage_unavailable">عدم امکان دسترسی به حافظه خارجی</string>

@ -258,7 +258,6 @@
<string name="EPr_voiceInputEnabled_title">Entrée voix</string>
<string name="EPr_voiceRemindersEnabled_title">Rappels vocaux</string>
<string name="EPr_voiceRemindersEnabled_desc_enabled">Tasks donnera le nom de la tâche</string>
<string name="EPr_use_dark_theme">Thème foncé</string>
<string name="delete_task">Supprimer la tâche ? </string>
<string name="voice_command_added_task">Tâche ajoutée</string>
<string name="external_storage_unavailable">Impossible d\'accéder au stockage externe</string>

@ -263,7 +263,6 @@ Se visualizzi questo errore più volte, ti consigliamo di cancellare tutti i dat
<string name="EPr_voiceInputEnabled_title">Voce</string>
<string name="EPr_voiceRemindersEnabled_title">Promemoria vocali</string>
<string name="EPr_voiceRemindersEnabled_desc_enabled">Tasks pronuncerà il nome dell\'attività durante i promemoria</string>
<string name="EPr_use_dark_theme">Tema scuro</string>
<string name="delete_task">Elimina attività</string>
<string name="voice_command_added_task">Attività aggiunta</string>
<string name="external_storage_unavailable">Non posso accedere alla memoria esterna</string>

@ -241,7 +241,6 @@
<string name="EPr_voiceInputEnabled_title">קלט קולי</string>
<string name="EPr_voiceRemindersEnabled_title">תזכורות קוליות</string>
<string name="EPr_voiceRemindersEnabled_desc_enabled">אסטריד תאמר את שם המשימה כחלק מהתזכורת</string>
<string name="EPr_use_dark_theme">ערכת נושא כהה</string>
<string name="delete_task">מחק משימה</string>
<string name="voice_command_added_task">משימות שנוצרו</string>
<string name="external_storage_unavailable">לא ניתן לגשת לאחסון חיצוני</string>

@ -266,7 +266,6 @@
<string name="EPr_voiceInputEnabled_title">音声入力</string>
<string name="EPr_voiceRemindersEnabled_title">音声リマインダー</string>
<string name="EPr_voiceRemindersEnabled_desc_enabled">Tasks はタスクリマインダーでタスク名を話します</string>
<string name="EPr_use_dark_theme">ダークテーマ</string>
<string name="delete_task">タスクを削除</string>
<string name="voice_command_added_task">追加されたタスク</string>
<string name="external_storage_unavailable">外部メモリーにアクセスできません</string>

@ -269,7 +269,6 @@ Tasks의 백업에서 당신의 일정을 복구하시기 바랍니다.
<string name="EPr_voiceInputEnabled_title">음성 입력</string>
<string name="EPr_voiceRemindersEnabled_title">음성 알림</string>
<string name="EPr_voiceRemindersEnabled_desc_enabled">일정 알림기간 동안 일정 이름을 직접 말해 줍니다</string>
<string name="EPr_use_dark_theme">어두운 색상 테마</string>
<string name="delete_task">일정 지우기</string>
<string name="voice_command_added_task">추가된 일정</string>
<string name="external_storage_unavailable">외부 저장소에 접근할 수 없음</string>

@ -262,7 +262,6 @@
<string name="EPr_voiceInputEnabled_title">Spraakinvoer</string>
<string name="EPr_voiceRemindersEnabled_title">Gesproken herinneringen</string>
<string name="EPr_voiceRemindersEnabled_desc_enabled">Bij herinneringen zullen de taaknamen uitgesproken worden</string>
<string name="EPr_use_dark_theme">Donker thema</string>
<string name="delete_task">Verwijder taak</string>
<string name="voice_command_added_task">Toegevoegde taak</string>
<string name="external_storage_unavailable">Geen toegang tot externe opslag</string>

@ -227,7 +227,6 @@ i odzyskanie zadań z kopi zapasowej (Settings-&gt;Sync and backup-&gt;Backup-&g
<string name="EPr_voiceInputEnabled_title">Polecenia głosowe</string>
<string name="EPr_voiceRemindersEnabled_title">Przypomnienia głosowe</string>
<string name="EPr_voiceRemindersEnabled_desc_enabled">Tasks będzie mówił nazwę zadania podczas przypomnienia</string>
<string name="EPr_use_dark_theme">Ciemny motyw</string>
<string name="delete_task">Usuń zadanie</string>
<string name="voice_command_added_task">Dodane zadanie</string>
<string name="external_storage_unavailable">Brak dostępu do pamięci zewnętrznej</string>

@ -224,7 +224,6 @@
<string name="EPr_voiceInputEnabled_title">Entrada de voz</string>
<string name="EPr_voiceRemindersEnabled_title">Lembretes de voz</string>
<string name="EPr_voiceRemindersEnabled_desc_enabled">Tasks irá falar o nome das tarefas durante os lembretes</string>
<string name="EPr_use_dark_theme">Tema escuro</string>
<string name="delete_task">Excluir tarefa</string>
<string name="voice_command_added_task">Tarefa adicionada</string>
<string name="external_storage_unavailable">Não é possível acessar Cartão SD</string>

@ -250,7 +250,6 @@ das tarefas através de um backup em Definições-&gt;Sincronização e backup-&
<string name="EPr_voiceInputEnabled_title">Entrada por voz</string>
<string name="EPr_voiceRemindersEnabled_title">Lembretes de voz</string>
<string name="EPr_voiceRemindersEnabled_desc_enabled">O Tasks irá reproduzir o nome da tarefa durante os lembretes</string>
<string name="EPr_use_dark_theme">Tema escuro</string>
<string name="delete_task">Eliminar tarefa</string>
<string name="voice_command_added_task">Tarefa adicionada</string>
<string name="external_storage_unavailable">Não foi possível aceder ao disco externo</string>

@ -265,7 +265,6 @@
<string name="EPr_voiceInputEnabled_title">Голосовой ввод</string>
<string name="EPr_voiceRemindersEnabled_title">Голосовые напоминания</string>
<string name="EPr_voiceRemindersEnabled_desc_enabled">Tasks должен произносить название задач во время напоминаний</string>
<string name="EPr_use_dark_theme">Тёмная тема</string>
<string name="delete_task">Удалить задачу</string>
<string name="voice_command_added_task">Добавленная задача</string>
<string name="external_storage_unavailable">Не могу открыть внешний накопитель</string>

@ -243,7 +243,6 @@
<string name="EPr_voiceInputEnabled_title">Hlasový vstup</string>
<string name="EPr_voiceRemindersEnabled_title">Hlasové pripomienky</string>
<string name="EPr_voiceRemindersEnabled_desc_enabled">Tasks povie názov úlohy počas jej pripomenutia</string>
<string name="EPr_use_dark_theme">Tmavá téma</string>
<string name="delete_task">Vymazať úlohu</string>
<string name="voice_command_added_task">Pridaná úloha</string>
<string name="external_storage_unavailable">Nemožno získať prístup k externej pamäti</string>

@ -229,7 +229,6 @@
<string name="EPr_voiceInputEnabled_title">Vnos glasu</string>
<string name="EPr_voiceRemindersEnabled_title">Glasovni opomniki</string>
<string name="EPr_voiceRemindersEnabled_desc_enabled">Aplikacija Opravki bo med opominjanjem glede opravkov izgovarjala nazive opravkov</string>
<string name="EPr_use_dark_theme">Temni videz</string>
<string name="delete_task">Zbriši opravek</string>
<plurals name="Ntasks">
<item quantity="one">1 opravek</item>

@ -266,7 +266,6 @@ och återställer dina aktuella uppgifter från en backup
<string name="EPr_voiceInputEnabled_title">Röstindata</string>
<string name="EPr_voiceRemindersEnabled_title">Röstpåminnelser</string>
<string name="EPr_voiceRemindersEnabled_desc_enabled">Tasks läser upp uppgifterna vid påminnelse</string>
<string name="EPr_use_dark_theme">Mörkt tema</string>
<string name="delete_task">Radera uppgift</string>
<string name="voice_command_added_task">Uppgift skapad</string>
<string name="external_storage_unavailable">Kan inte komma åt externt lagringsutrymme</string>

@ -227,7 +227,6 @@
<string name="EPr_voiceInputEnabled_title">Голосове введення</string>
<string name="EPr_voiceRemindersEnabled_title">Голосові нагадування</string>
<string name="EPr_voiceRemindersEnabled_desc_enabled">Tasks повинен вимовляти назву завдань під час нагадувань</string>
<string name="EPr_use_dark_theme">Темна тема</string>
<string name="delete_task">Видалити завдання</string>
<plurals name="Ntasks">
<item quantity="one">1 завдання</item>

@ -210,7 +210,6 @@
<string name="EPr_voiceInputEnabled_title">語音輸入</string>
<string name="EPr_voiceRemindersEnabled_title">語音提醒</string>
<string name="EPr_voiceRemindersEnabled_desc_enabled">Tasks在工作提醒時會以語音說出工作名稱</string>
<string name="EPr_use_dark_theme">暗色主題</string>
<string name="delete_task">刪除工作</string>
<plurals name="Ntasks">
<item quantity="one">1 個工作</item>

@ -87,12 +87,6 @@
<color name="task_list_done">#ff777777</color>
<color name="task_edit_deadline_gray">#888888</color>
<color name="widget_text_color_light">#535353</color>
<color name="widget_text_color_dark">#ffffff</color>
<color name="widget_header_dark">#000000</color>
<color name="widget_body_light">#ffffff</color>
<color name="widget_body_dark">#000000</color>
<color name="drawer_background">#efefef</color>
<color name="drawer_background_dark">#303030</color>
<color name="drawer_background_selected">#dddddd</color>

@ -710,7 +710,6 @@ File %1$s contained %2$s.\n\n
<!-- Preference: Voice reminders description (true) -->
<string name="EPr_voiceRemindersEnabled_desc_enabled">Tasks will speak task names during task reminders</string>
<string name="EPr_use_dark_theme">Dark theme</string>
<string name="delete_task">Delete task</string>
<string name="voice_command_added_task">Added task</string>
<string name="external_storage_unavailable">Cannot access external storage</string>

@ -112,18 +112,6 @@
<item name="android:textColor">?attr/asDueDateCompletedColor</item>
</style>
<!-- ========================================================= Widget == -->
<style name="TextAppearance.Widget">
<item name="android:textSize">16sp</item>
<item name="android:textColor">@color/widget_text_color_light</item>
</style>
<style name="TextAppearance.WidgetDueDate">
<item name="android:textSize">12sp</item>
<item name="android:textColor">@color/widget_text_color_light</item>
</style>
<style name="FilePickerTheme" parent="NNF_BaseTheme.Light">
<item name="nnf_toolbarTheme">@style/ActionBarThemeOverlay</item>
</style>

Loading…
Cancel
Save