Browse Source

Merge 04ec5bf7d7febbf550855ba7c24da6cb07a33955 into ad3bf3c256978024d5fa528d479ec85dfeb8a6e5

Tobias Kaminsky 7 years ago
parent
commit
f845448491
58 changed files with 1029 additions and 344 deletions
  1. 1 1
      build.gradle
  2. 1 1
      scripts/lint/lint-results.txt
  3. 21 4
      src/main/java/com/owncloud/android/authentication/AccountUtils.java
  4. 9 0
      src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java
  5. 5 1
      src/main/java/com/owncloud/android/db/ProviderMeta.java
  6. 3 3
      src/main/java/com/owncloud/android/media/MediaControlView.java
  7. 2 1
      src/main/java/com/owncloud/android/media/MediaService.java
  8. 28 1
      src/main/java/com/owncloud/android/providers/FileContentProvider.java
  9. 2 1
      src/main/java/com/owncloud/android/syncadapter/FileSyncAdapter.java
  10. 82 39
      src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java
  11. 12 1
      src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java
  12. 27 29
      src/main/java/com/owncloud/android/ui/activity/FingerprintActivity.java
  13. 4 1
      src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.java
  14. 2 1
      src/main/java/com/owncloud/android/ui/activity/FolderSyncActivity.java
  15. 2 1
      src/main/java/com/owncloud/android/ui/activity/ManageAccountsActivity.java
  16. 2 1
      src/main/java/com/owncloud/android/ui/activity/NotificationsActivity.java
  17. 23 8
      src/main/java/com/owncloud/android/ui/activity/ParticipateActivity.java
  18. 20 4
      src/main/java/com/owncloud/android/ui/activity/PassCodeActivity.java
  19. 32 1
      src/main/java/com/owncloud/android/ui/activity/Preferences.java
  20. 2 1
      src/main/java/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java
  21. 34 6
      src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java
  22. 6 2
      src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.java
  23. 55 6
      src/main/java/com/owncloud/android/ui/activity/UserInfoActivity.java
  24. 6 1
      src/main/java/com/owncloud/android/ui/adapter/AccountListAdapter.java
  25. 3 1
      src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java
  26. 7 12
      src/main/java/com/owncloud/android/ui/adapter/FileListListAdapter.java
  27. 3 2
      src/main/java/com/owncloud/android/ui/adapter/FolderSyncAdapter.java
  28. 19 2
      src/main/java/com/owncloud/android/ui/dialog/CreateFolderDialogFragment.java
  29. 3 5
      src/main/java/com/owncloud/android/ui/dialog/IndeterminateProgressDialog.java
  30. 2 1
      src/main/java/com/owncloud/android/ui/dialog/LoadingDialog.java
  31. 18 1
      src/main/java/com/owncloud/android/ui/dialog/RenameFileDialogFragment.java
  32. 12 0
      src/main/java/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java
  33. 8 4
      src/main/java/com/owncloud/android/ui/dialog/SortingOrderDialogFragment.java
  34. 40 16
      src/main/java/com/owncloud/android/ui/dialog/SyncedFolderPreferencesDialogFragment.java
  35. 29 16
      src/main/java/com/owncloud/android/ui/fragment/EditShareFragment.java
  36. 46 6
      src/main/java/com/owncloud/android/ui/fragment/ExtendedListFragment.java
  37. 2 1
      src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java
  38. 23 10
      src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java
  39. 35 14
      src/main/java/com/owncloud/android/ui/fragment/ShareFileFragment.java
  40. 25 1
      src/main/java/com/owncloud/android/ui/fragment/contactsbackup/ContactListFragment.java
  41. 19 1
      src/main/java/com/owncloud/android/ui/fragment/contactsbackup/ContactsBackupFragment.java
  42. 2 2
      src/main/java/com/owncloud/android/ui/notifications/NotificationUtils.java
  43. 2 2
      src/main/java/com/owncloud/android/ui/preview/FileDownloadFragment.java
  44. 2 6
      src/main/java/com/owncloud/android/utils/BitmapUtils.java
  45. 11 113
      src/main/java/com/owncloud/android/utils/DisplayUtils.java
  46. 1 1
      src/main/java/com/owncloud/android/utils/MimeTypeUtil.java
  47. 321 0
      src/main/java/com/owncloud/android/utils/ThemeUtils.java
  48. BIN
      src/main/res/drawable-hdpi/ic_arrow_back.png
  49. BIN
      src/main/res/drawable-mdpi/ic_arrow_back.png
  50. BIN
      src/main/res/drawable-xhdpi/ic_arrow_back.png
  51. BIN
      src/main/res/drawable-xxhdpi/ic_arrow_back.png
  52. BIN
      src/main/res/drawable-xxxhdpi/ic_arrow_back.png
  53. 1 2
      src/main/res/layout/account_item.xml
  54. 1 0
      src/main/res/layout/drawer_header.xml
  55. 3 3
      src/main/res/layout/edit_share_layout.xml
  56. 0 3
      src/main/res/layout/list_fragment.xml
  57. 4 4
      src/main/res/values/strings.xml
  58. 6 0
      src/main/res/values/styles.xml

+ 1 - 1
build.gradle

@@ -184,7 +184,7 @@ dependencies {
     compile 'com.jakewharton:disklrucache:2.0.2'
     compile "com.android.support:appcompat-v7:${supportLibraryVersion}"
     compile "com.android.support:cardview-v7:${supportLibraryVersion}"
-    compile 'com.getbase:floatingactionbutton:1.10.1'
+    compile 'com.github.tobiasKaminsky:android-floating-action-button:1.10.2'
     compile 'com.google.code.findbugs:annotations:2.0.1'
     compile group: 'commons-io', name: 'commons-io', version: '2.4'
     compile 'com.github.evernote:android-job:v1.1.9'

+ 1 - 1
scripts/lint/lint-results.txt

@@ -1,2 +1,2 @@
 DO NOT TOUCH; GENERATED BY DRONE
-      <span class="mdl-layout-title">Lint Report: 73 errors and 853 warnings</span>
+      <span class="mdl-layout-title">Lint Report: 72 errors and 853 warnings</span>

+ 21 - 4
src/main/java/com/owncloud/android/authentication/AccountUtils.java

@@ -28,10 +28,13 @@ import android.net.Uri;
 import android.preference.PreferenceManager;
 
 import com.owncloud.android.MainApp;
+import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.lib.common.accounts.AccountTypeUtils;
 import com.owncloud.android.lib.common.accounts.AccountUtils.Constants;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.resources.status.OwnCloudVersion;
+import com.owncloud.android.operations.GetCapabilitiesOperarion;
 
 import java.util.Locale;
 
@@ -143,19 +146,33 @@ public class AccountUtils {
         }
         return null;
     }
-    
 
-    public static boolean setCurrentOwnCloudAccount(Context context, String accountName) {
+
+    public static boolean setCurrentOwnCloudAccount(final Context context, String accountName) {
         boolean result = false;
         if (accountName != null) {
             boolean found;
-            for (Account account : getAccounts(context)) {
+            for (final Account account : getAccounts(context)) {
                 found = (account.name.equals(accountName));
                 if (found) {
                     SharedPreferences.Editor appPrefs = PreferenceManager
                             .getDefaultSharedPreferences(context).edit();
                     appPrefs.putString("select_oc_account", accountName);
-    
+
+                    // update credentials
+                    Thread t = new Thread(new Runnable() {
+                        @Override
+                        public void run() {
+                            FileDataStorageManager storageManager = new FileDataStorageManager(account,
+                                    context.getContentResolver());
+                            GetCapabilitiesOperarion getCapabilities = new GetCapabilitiesOperarion();
+                            RemoteOperationResult updateResult = getCapabilities.execute(storageManager, context);
+                            Log_OC.w(TAG, "Update Capabilities: " + updateResult.isSuccess());
+                        }
+                    });
+
+                    t.start();
+
                     appPrefs.apply();
                     result = true;
                     break;

+ 9 - 0
src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java

@@ -1908,6 +1908,10 @@ public class FileDataStorageManager {
         cv.put(ProviderTableMeta.CAPABILITIES_FILES_VERSIONING, capability.getFilesVersioning().getValue());
         cv.put(ProviderTableMeta.CAPABILITIES_FILES_DROP, capability.getFilesFileDrop().getValue());
         cv.put(ProviderTableMeta.CAPABILITIES_EXTERNAL_LINKS, capability.getExternalLinks().getValue());
+        cv.put(ProviderTableMeta.CAPABILITIES_SERVER_NAME, capability.getServerName());
+        cv.put(ProviderTableMeta.CAPABILITIES_SERVER_COLOR, capability.getServerColor());
+        cv.put(ProviderTableMeta.CAPABILITIES_SERVER_BACKGROUND_URL, capability.getServerBackground());
+        cv.put(ProviderTableMeta.CAPABILITIES_SERVER_SLOGAN, capability.getServerSlogan());
 
         if (capabilityExists(mAccount.name)) {
             if (getContentResolver() != null) {
@@ -2047,6 +2051,11 @@ public class FileDataStorageManager {
                     .getColumnIndex(ProviderTableMeta.CAPABILITIES_FILES_DROP))));
             capability.setExternalLinks(CapabilityBooleanType.fromValue(c.getInt(c
                     .getColumnIndex(ProviderTableMeta.CAPABILITIES_EXTERNAL_LINKS))));
+            capability.setServerName(c.getString(c.getColumnIndex(ProviderTableMeta.CAPABILITIES_SERVER_NAME)));
+            capability.setServerColor(c.getString(c.getColumnIndex(ProviderTableMeta.CAPABILITIES_SERVER_COLOR)));
+            capability.setServerBackground(c.getString(c.getColumnIndex(
+                    ProviderTableMeta.CAPABILITIES_SERVER_BACKGROUND_URL)));
+            capability.setServerSlogan(c.getString(c.getColumnIndex(ProviderTableMeta.CAPABILITIES_SERVER_SLOGAN)));
         }
         return capability;
     }

+ 5 - 1
src/main/java/com/owncloud/android/db/ProviderMeta.java

@@ -32,7 +32,7 @@ import com.owncloud.android.MainApp;
 public class ProviderMeta {
 
     public static final String DB_NAME = "filelist";
-    public static final int DB_VERSION = 21;
+    public static final int DB_VERSION = 22;
 
     private ProviderMeta() {
     }
@@ -147,6 +147,10 @@ public class ProviderMeta {
         public static final String CAPABILITIES_FILES_VERSIONING = "files_versioning";
         public static final String CAPABILITIES_FILES_DROP = "files_drop";
         public static final String CAPABILITIES_EXTERNAL_LINKS = "external_links";
+        public static final String CAPABILITIES_SERVER_NAME = "server_name";
+        public static final String CAPABILITIES_SERVER_COLOR = "server_color";
+        public static final String CAPABILITIES_SERVER_BACKGROUND_URL = "background_url";
+        public static final String CAPABILITIES_SERVER_SLOGAN = "server_slogan";
 
         public static final String CAPABILITIES_DEFAULT_SORT_ORDER = CAPABILITIES_ACCOUNT_NAME
                 + " collate nocase asc";

+ 3 - 3
src/main/java/com/owncloud/android/media/MediaControlView.java

@@ -39,7 +39,7 @@ import android.widget.SeekBar.OnSeekBarChangeListener;
 import android.widget.TextView;
 
 import com.owncloud.android.R;
-import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.ThemeUtils;
 
 import java.util.Formatter;
 import java.util.Locale;
@@ -223,10 +223,10 @@ public class MediaControlView extends FrameLayout /* implements OnLayoutChangeLi
         if (mProgress != null) {
             if (mProgress instanceof SeekBar) {
                 SeekBar seeker = (SeekBar) mProgress;
-                DisplayUtils.colorPreLollipopHorizontalSeekBar(seeker);
+                ThemeUtils.colorPreLollipopHorizontalSeekBar(seeker);
                 seeker.setOnSeekBarChangeListener(this);
             } else {
-                DisplayUtils.colorPreLollipopHorizontalProgressBar(mProgress);
+                ThemeUtils.colorPreLollipopHorizontalProgressBar(mProgress);
             }
             mProgress.setMax(1000);
         }

+ 2 - 1
src/main/java/com/owncloud/android/media/MediaService.java

@@ -42,6 +42,7 @@ import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.activity.FileActivity;
 import com.owncloud.android.ui.activity.FileDisplayActivity;
+import com.owncloud.android.utils.ThemeUtils;
 
 import java.io.IOException;
 
@@ -228,7 +229,7 @@ public class MediaService extends Service implements OnCompletionListener, OnPre
 
         mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
         mNotificationBuilder = new NotificationCompat.Builder(this);
-        mNotificationBuilder.setColor(this.getResources().getColor(R.color.primary));
+        mNotificationBuilder.setColor(ThemeUtils.primaryColor());
         mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
         mBinder = new MediaServiceBinder(this);
     }

+ 28 - 1
src/main/java/com/owncloud/android/providers/FileContentProvider.java

@@ -1010,6 +1010,29 @@ public class FileContentProvider extends ContentProvider {
             if (!upgraded) {
                 Log_OC.i(SQL, String.format(Locale.ENGLISH, UPGRADE_VERSION_MSG, oldVersion, newVersion));
             }
+
+            if (oldVersion < 22 && newVersion >= 22) {
+                Log_OC.i(SQL, "Entering in the #22 Adding user theming to capabilities table");
+                db.beginTransaction();
+                try {
+                    db.execSQL(ALTER_TABLE + ProviderTableMeta.CAPABILITIES_TABLE_NAME +
+                            ADD_COLUMN + ProviderTableMeta.CAPABILITIES_SERVER_NAME + " TEXT ");
+                    db.execSQL(ALTER_TABLE + ProviderTableMeta.CAPABILITIES_TABLE_NAME +
+                            ADD_COLUMN + ProviderTableMeta.CAPABILITIES_SERVER_COLOR + " TEXT ");
+                    db.execSQL(ALTER_TABLE + ProviderTableMeta.CAPABILITIES_TABLE_NAME +
+                            ADD_COLUMN + ProviderTableMeta.CAPABILITIES_SERVER_BACKGROUND_URL + " TEXT ");
+                    db.execSQL(ALTER_TABLE + ProviderTableMeta.CAPABILITIES_TABLE_NAME +
+                            ADD_COLUMN + ProviderTableMeta.CAPABILITIES_SERVER_SLOGAN + " TEXT ");
+                    upgraded = true;
+                    db.setTransactionSuccessful();
+                } finally {
+                    db.endTransaction();
+                }
+            }
+
+            if (!upgraded) {
+                Log_OC.i(SQL, String.format(Locale.ENGLISH, UPGRADE_VERSION_MSG, oldVersion, newVersion));
+            }
         }
     }
 
@@ -1090,7 +1113,11 @@ public class FileContentProvider extends ContentProvider {
                 + ProviderTableMeta.CAPABILITIES_FILES_UNDELETE + INTEGER  // boolean
                 + ProviderTableMeta.CAPABILITIES_FILES_VERSIONING + INTEGER   // boolean
                 + ProviderTableMeta.CAPABILITIES_FILES_DROP + INTEGER  // boolean
-                + ProviderTableMeta.CAPABILITIES_EXTERNAL_LINKS + " INTEGER );");   // boolean
+                + ProviderTableMeta.CAPABILITIES_EXTERNAL_LINKS + INTEGER  // boolean
+                + ProviderTableMeta.CAPABILITIES_SERVER_NAME + TEXT
+                + ProviderTableMeta.CAPABILITIES_SERVER_COLOR + TEXT
+                + ProviderTableMeta.CAPABILITIES_SERVER_SLOGAN + TEXT
+                + ProviderTableMeta.CAPABILITIES_SERVER_BACKGROUND_URL + " TEXT );");
     }
 
     private void createUploadsTable(SQLiteDatabase db) {

+ 2 - 1
src/main/java/com/owncloud/android/syncadapter/FileSyncAdapter.java

@@ -46,6 +46,7 @@ import com.owncloud.android.operations.RefreshFolderOperation;
 import com.owncloud.android.operations.UpdateOCVersionOperation;
 import com.owncloud.android.ui.activity.ErrorsWhileCopyingHandlerActivity;
 import com.owncloud.android.utils.DataHolderUtil;
+import com.owncloud.android.utils.ThemeUtils;
 
 import org.apache.jackrabbit.webdav.DavException;
 
@@ -507,7 +508,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
     private NotificationCompat.Builder createNotificationBuilder() {
         NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getContext());
         notificationBuilder.setSmallIcon(R.drawable.notification_icon).setAutoCancel(true);
-        notificationBuilder.setColor(getContext().getResources().getColor(R.color.primary));
+        notificationBuilder.setColor(ThemeUtils.primaryColor());
         return notificationBuilder;
     }
     

+ 82 - 39
src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java

@@ -28,6 +28,7 @@ import android.accounts.AccountManagerFuture;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.res.Configuration;
+import android.graphics.Color;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.os.Bundle;
@@ -37,14 +38,17 @@ import android.support.design.widget.NavigationView;
 import android.support.v4.view.GravityCompat;
 import android.support.v4.widget.DrawerLayout;
 import android.support.v7.app.ActionBarDrawerToggle;
+import android.text.Html;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
+import android.webkit.URLUtil;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
+import com.bumptech.glide.Glide;
 import com.bumptech.glide.request.animation.GlideAnimation;
 import com.bumptech.glide.request.target.SimpleTarget;
 import com.owncloud.android.MainApp;
@@ -71,6 +75,7 @@ import com.owncloud.android.ui.events.MenuItemClickEvent;
 import com.owncloud.android.ui.events.SearchEvent;
 import com.owncloud.android.ui.fragment.OCFileListFragment;
 import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.ThemeUtils;
 import com.owncloud.android.utils.svg.MenuSimpleTarget;
 
 import org.greenrobot.eventbus.EventBus;
@@ -249,6 +254,7 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
         // Set the drawer toggle as the DrawerListener
         mDrawerLayout.addDrawerListener(mDrawerToggle);
         mDrawerToggle.setDrawerIndicatorEnabled(true);
+        mDrawerToggle.getDrawerArrowDrawable().setColor(ThemeUtils.fontColor());
     }
 
     /**
@@ -260,6 +266,7 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
         mAccountEndAccountAvatar = (ImageView) findNavigationViewChildById(R.id.drawer_account_end);
 
         mAccountChooserToggle = (ImageView) findNavigationViewChildById(R.id.drawer_account_chooser_toogle);
+        mAccountChooserToggle.setColorFilter(ThemeUtils.fontColor());
 
         if (getResources().getBoolean(R.bool.allow_profile_click)) {
             mAccountChooserToggle.setImageResource(R.drawable.ic_down);
@@ -284,7 +291,7 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
         mQuotaProgressBar = (ProgressBar) findQuotaViewById(R.id.drawer_quota_ProgressBar);
         mQuotaTextPercentage = (TextView) findQuotaViewById(R.id.drawer_quota_percentage);
         mQuotaTextLink = (TextView) findQuotaViewById(R.id.drawer_quota_link);
-        DisplayUtils.colorPreLollipopHorizontalProgressBar(mQuotaProgressBar);
+        ThemeUtils.colorPreLollipopHorizontalProgressBar(mQuotaProgressBar);
     }
 
     /**
@@ -293,11 +300,7 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
      * @param navigationView the drawers navigation view
      */
     protected void setupDrawerMenu(NavigationView navigationView) {
-        // on pre lollipop the light theme adds a black tint to icons with white coloring
-        // ruining the generic avatars, so tinting for icons is deactivated pre lollipop
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
-            navigationView.setItemIconTintList(null);
-        }
+        navigationView.setItemIconTintList(null);
 
         // setup actions for drawer menu items
         navigationView.setNavigationItemSelectedListener(
@@ -410,36 +413,27 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
 
     private void selectNavigationItem(final MenuItem menuItem) {
 
+        setDrawerMenuItemChecked(menuItem.getItemId());
+
         switch (menuItem.getItemId()) {
             case R.id.nav_all_files:
-                menuItem.setChecked(true);
-                mCheckedMenuItem = menuItem.getItemId();
                 showFiles(false);
                 EventBus.getDefault().post(new ChangeMenuEvent());
                 break;
             case R.id.nav_favorites:
-                menuItem.setChecked(true);
-                mCheckedMenuItem = menuItem.getItemId();
-
                 switchToSearchFragment(new SearchEvent("", SearchOperation.SearchType.FAVORITE_SEARCH,
                         SearchEvent.UnsetType.NO_UNSET), menuItem);
                 break;
             case R.id.nav_photos:
-                menuItem.setChecked(true);
-                mCheckedMenuItem = menuItem.getItemId();
-
                 switchToSearchFragment(new SearchEvent("image/%", SearchOperation.SearchType.CONTENT_TYPE_SEARCH,
                         SearchEvent.UnsetType.NO_UNSET), menuItem);
                 break;
             case R.id.nav_on_device:
-                menuItem.setChecked(true);
-                mCheckedMenuItem = menuItem.getItemId();
                 EventBus.getDefault().post(new ChangeMenuEvent());
                 showFiles(true);
                 break;
             case R.id.nav_uploads:
-                Intent uploadListIntent = new Intent(getApplicationContext(),
-                        UploadListActivity.class);
+                Intent uploadListIntent = new Intent(getApplicationContext(), UploadListActivity.class);
                 uploadListIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                 startActivity(uploadListIntent);
                 break;
@@ -465,8 +459,7 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
                 startActivity(settingsIntent);
                 break;
             case R.id.nav_participate:
-                Intent participateIntent = new Intent(getApplicationContext(),
-                        ParticipateActivity.class);
+                Intent participateIntent = new Intent(getApplicationContext(), ParticipateActivity.class);
                 startActivity(participateIntent);
                 break;
             case R.id.nav_logout:
@@ -478,35 +471,22 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
                 createAccount(false);
                 break;
             case R.id.drawer_menu_account_manage:
-                Intent manageAccountsIntent = new Intent(getApplicationContext(),
-                        ManageAccountsActivity.class);
+                Intent manageAccountsIntent = new Intent(getApplicationContext(), ManageAccountsActivity.class);
                 startActivityForResult(manageAccountsIntent, ACTION_MANAGE_ACCOUNTS);
                 break;
             case R.id.nav_recently_added:
-                menuItem.setChecked(true);
-                mCheckedMenuItem = menuItem.getItemId();
-
                 switchToSearchFragment(new SearchEvent("%",SearchOperation.SearchType.CONTENT_TYPE_SEARCH,
                         SearchEvent.UnsetType.UNSET_BOTTOM_NAV_BAR), menuItem);
                 break;
             case R.id.nav_recently_modified:
-                menuItem.setChecked(true);
-                mCheckedMenuItem = menuItem.getItemId();
-
                 switchToSearchFragment(new SearchEvent("", SearchOperation.SearchType.RECENTLY_MODIFIED_SEARCH,
                         SearchEvent.UnsetType.UNSET_BOTTOM_NAV_BAR), menuItem);
                 break;
             case R.id.nav_shared:
-                menuItem.setChecked(true);
-                mCheckedMenuItem = menuItem.getItemId();
-
                 switchToSearchFragment(new SearchEvent("", SearchOperation.SearchType.SHARED_SEARCH,
                         SearchEvent.UnsetType.UNSET_BOTTOM_NAV_BAR), menuItem);
                 break;
             case R.id.nav_videos:
-                menuItem.setChecked(true);
-                mCheckedMenuItem = menuItem.getItemId();
-
                 switchToSearchFragment(new SearchEvent("video/%", SearchOperation.SearchType.CONTENT_TYPE_SEARCH,
                         SearchEvent.UnsetType.UNSET_BOTTOM_NAV_BAR), menuItem);
                 break;
@@ -743,9 +723,11 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
             TextView username = (TextView) findNavigationViewChildById(R.id.drawer_username);
             TextView usernameFull = (TextView) findNavigationViewChildById(R.id.drawer_username_full);
             usernameFull.setText(account.name);
+            usernameFull.setTextColor(ThemeUtils.fontColor());
             try {
                 OwnCloudAccount oca = new OwnCloudAccount(account, this);
                 username.setText(oca.getDisplayName());
+                username.setTextColor(ThemeUtils.fontColor());
             } catch (com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException e) {
                 Log_OC.w(TAG, "Couldn't read display name of account fallback to account name");
                 username.setText(AccountUtils.getAccountUsername(account.name));
@@ -821,7 +803,7 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
      */
     private void setQuotaInformation(long usedSpace, long totalSpace, int relative) {
         mQuotaProgressBar.setProgress(relative);
-        DisplayUtils.colorHorizontalProgressBar(mQuotaProgressBar, DisplayUtils.getRelativeInfoColor(this, relative));
+        ThemeUtils.colorHorizontalProgressBar(mQuotaProgressBar, DisplayUtils.getRelativeInfoColor(this, relative));
 
         updateQuotaLink();
 
@@ -906,9 +888,26 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
      * @param menuItemId the menu item to be highlighted
      */
     protected void setDrawerMenuItemChecked(int menuItemId) {
-        if (mNavigationView != null && mNavigationView.getMenu() != null && mNavigationView.getMenu().findItem
-                (menuItemId) != null) {
-            mNavigationView.getMenu().findItem(menuItemId).setChecked(true);
+        if (mNavigationView != null && mNavigationView.getMenu() != null &&
+                mNavigationView.getMenu().findItem(menuItemId) != null) {
+
+            MenuItem item = mNavigationView.getMenu().findItem(menuItemId);
+            item.setChecked(true);
+
+            // reset all tinted icons
+            for (int i = 0; i < mNavigationView.getMenu().size(); i++) {
+                MenuItem menuItem = mNavigationView.getMenu().getItem(i);
+                if (menuItem.getIcon() != null) {
+                    menuItem.getIcon().clearColorFilter();
+                    menuItem.setTitle(Html.fromHtml("<font color='#000000'>" + menuItem.getTitle() + "</font>"));
+                }
+            }
+
+            ThemeUtils.tintDrawable(item.getIcon(), ThemeUtils.primaryColor());
+
+            String colorHex = ThemeUtils.colorToHexString(ThemeUtils.primaryColor());
+            item.setTitle(Html.fromHtml("<font color='" + colorHex + "'>" + item.getTitle() + "</font>"));
+
             mCheckedMenuItem = menuItemId;
         } else {
             Log_OC.w(TAG, "setDrawerMenuItemChecked has been called with invalid menu-item-ID");
@@ -1000,6 +999,43 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
         }
     }
 
+    public void updateHeaderBackground() {
+        if (getAccount() != null &&
+                getStorageManager().getCapability(getAccount().name).getServerBackground() != null) {
+            final LinearLayout navigationHeader = (LinearLayout) findNavigationViewChildById(R.id.drawer_header_view);
+
+            if (navigationHeader != null) {
+                String background = getStorageManager().getCapability(getAccount().name).getServerBackground();
+
+                if (URLUtil.isValidUrl(background) || background.isEmpty()) {
+                    // background image
+                    SimpleTarget target = new SimpleTarget<Drawable>() {
+                        @Override
+                        public void onResourceReady(Drawable resource, GlideAnimation glideAnimation) {
+                            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
+                                navigationHeader.setBackgroundDrawable(resource);
+                            } else {
+                                navigationHeader.setBackground(resource);
+                            }
+                        }
+                    };
+
+                    Glide.with(this)
+                            .load(background)
+                            .centerCrop()
+                            .placeholder(R.drawable.background)
+                            .error(R.drawable.background)
+                            .crossFade()
+                            .into(target);
+                } else {
+                    // plain color
+                    int color = Color.parseColor(background);
+                    navigationHeader.setBackgroundColor(color);
+                }
+            }
+        }
+    }
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -1058,6 +1094,7 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
         updateAccountList();
         updateExternalLinksInDrawer();
         updateQuotaLink();
+        updateHeaderBackground();
     }
 
     @Override
@@ -1111,7 +1148,13 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
      * @return The view if found or <code>null</code> otherwise.
      */
     private View findNavigationViewChildById(int id) {
-        return ((NavigationView) findViewById(R.id.nav_view)).getHeaderView(0).findViewById(id);
+        NavigationView view = ((NavigationView) findViewById(R.id.nav_view));
+
+        if (view != null) {
+            return view.getHeaderView(0).findViewById(id);
+        } else {
+            return null;
+        }
     }
 
     /**

+ 12 - 1
src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java

@@ -56,6 +56,8 @@ import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewTreeObserver;
+import android.widget.EditText;
+import android.widget.ImageView;
 import android.widget.Toast;
 
 import com.owncloud.android.MainApp;
@@ -102,6 +104,7 @@ import com.owncloud.android.utils.ErrorMessageAdapter;
 import com.owncloud.android.utils.MimeTypeUtil;
 import com.owncloud.android.utils.PermissionUtil;
 import com.owncloud.android.utils.PushUtils;
+import com.owncloud.android.utils.ThemeUtils;
 
 import org.greenrobot.eventbus.EventBus;
 import org.greenrobot.eventbus.Subscribe;
@@ -247,7 +250,7 @@ public class FileDisplayActivity extends HookActivity
                             }
                         });
 
-                DisplayUtils.colorSnackbar(this, snackbar);
+                ThemeUtils.colorSnackbar(this, snackbar);
 
                 snackbar.show();
             } else {
@@ -660,6 +663,14 @@ public class FileDisplayActivity extends HookActivity
         final MenuItem item = menu.findItem(R.id.action_search);
         searchView = (SearchView) MenuItemCompat.getActionView(item);
 
+        // hacky as no default way is provided
+        int fontColor = ThemeUtils.fontColor();
+        EditText editText = (EditText) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
+        editText.setHintTextColor(fontColor);
+        editText.setTextColor(fontColor);
+        ImageView searchClose = (ImageView) searchView.findViewById(android.support.v7.appcompat.R.id.search_close_btn);
+        searchClose.setColorFilter(ThemeUtils.fontColor());
+
         // populate list of menu items to show/hide when drawer is opened/closed
         mDrawerMenuItemstoShowHideList = new ArrayList<>(4);
         mDrawerMenuItemstoShowHideList.add(menu.findItem(R.id.action_sort));

+ 27 - 29
src/main/java/com/owncloud/android/ui/activity/FingerprintActivity.java

@@ -1,4 +1,4 @@
-/**
+/*
  *   Nextcloud Android client application
  *
  *   @author Florian Lentz
@@ -28,6 +28,7 @@ import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.res.ColorStateList;
 import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.hardware.fingerprint.FingerprintManager;
 import android.os.Build;
@@ -40,6 +41,7 @@ import android.support.annotation.RequiresApi;
 import android.support.v4.app.ActivityCompat;
 import android.support.v4.graphics.drawable.DrawableCompat;
 import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
 import android.view.KeyEvent;
 import android.widget.ImageView;
 import android.widget.TextView;
@@ -49,6 +51,7 @@ import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.utils.AnalyticsUtils;
+import com.owncloud.android.utils.ThemeUtils;
 
 import java.io.IOException;
 import java.security.InvalidAlgorithmParameterException;
@@ -68,6 +71,7 @@ import javax.crypto.SecretKey;
 /**
  * Activity to handle access to the app based on the fingerprint.
  */
+@TargetApi(Build.VERSION_CODES.M)
 public class FingerprintActivity extends AppCompatActivity {
 
     private static final String TAG = FingerprintActivity.class.getSimpleName();
@@ -83,10 +87,6 @@ public class FingerprintActivity extends AppCompatActivity {
     private static final String KEY_NAME = "Nextcloud";
     private Cipher cipher;
 
-    private FingerprintHandler helper;
-
-    private FingerprintManager.CryptoObject cryptoObject;
-
     private CancellationSignal cancellationSignal;
 
     /**
@@ -97,6 +97,14 @@ public class FingerprintActivity extends AppCompatActivity {
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.fingerprintlock);
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            getWindow().setStatusBarColor(ThemeUtils.primaryDarkColor());
+        }
+
+        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+        toolbar.setTitleTextColor(ThemeUtils.fontColor());
+        toolbar.setBackground(new ColorDrawable(ThemeUtils.primaryColor()));
     }
 
     private void startFingerprint() {
@@ -111,13 +119,11 @@ public class FingerprintActivity extends AppCompatActivity {
         }
         KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
 
-        if (!keyguardManager.isKeyguardSecure()) {
-            return;
-        } else {
+        if (keyguardManager.isKeyguardSecure()) {
             generateKey();
 
             if (cipherInit()) {
-                cryptoObject = new FingerprintManager.CryptoObject(cipher);
+                FingerprintManager.CryptoObject cryptoObject = new FingerprintManager.CryptoObject(cipher);
                 FingerprintHandler.Callback callback = new FingerprintHandler.Callback() {
                     @Override
                     public void onAuthenticated() {
@@ -140,7 +146,7 @@ public class FingerprintActivity extends AppCompatActivity {
                     }
                 };
 
-                helper = new FingerprintHandler(fingerprintTextView, callback);
+                FingerprintHandler helper = new FingerprintHandler(fingerprintTextView, callback);
                 cancellationSignal = new CancellationSignal();
                 if (ActivityCompat.checkSelfPermission(MainApp.getAppContext(), Manifest.permission.USE_FINGERPRINT)
                         != PackageManager.PERMISSION_GRANTED) {
@@ -157,7 +163,7 @@ public class FingerprintActivity extends AppCompatActivity {
         AnalyticsUtils.setCurrentScreenName(this, SCREEN_NAME, TAG);
         startFingerprint();
         ImageView imageView = (ImageView)findViewById(R.id.fingerprinticon);
-        imageView.setImageDrawable(getDrawable(R.drawable.ic_fingerprint));
+        imageView.setImageDrawable(ThemeUtils.tintDrawable(R.drawable.ic_fingerprint, ThemeUtils.primaryColor()));
     }
 
     @Override
@@ -174,14 +180,10 @@ public class FingerprintActivity extends AppCompatActivity {
      * @return 'True' when the key event was processed by this method.
      */
     @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event){
-        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount()== 0){
-            return true;
-        }
-        return super.onKeyDown(keyCode, event);
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        return keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0 || super.onKeyDown(keyCode, event);
     }
 
-    @TargetApi(Build.VERSION_CODES.M)
     protected void generateKey() {
         try {
             keyStore = KeyStore.getInstance(ANDROID_KEY_STORE);
@@ -192,11 +194,7 @@ public class FingerprintActivity extends AppCompatActivity {
         KeyGenerator keyGenerator;
         try {
             keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);
-        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
-            return;
-        }
 
-        try {
             keyStore.load(null);
             keyGenerator.init(
                     new KeyGenParameterSpec.Builder(
@@ -207,12 +205,12 @@ public class FingerprintActivity extends AppCompatActivity {
                             .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
                             .build());
             keyGenerator.generateKey();
-        } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException | CertificateException | IOException e) {
-            return;
+        } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException | CertificateException | IOException |
+                NoSuchProviderException e) {
+            Log_OC.e(TAG, "Exception: " + e.getMessage());
         }
     }
 
-    @TargetApi(Build.VERSION_CODES.M)
     public boolean cipherInit() {
         try {
             cipher = Cipher.getInstance(
@@ -240,8 +238,8 @@ public class FingerprintActivity extends AppCompatActivity {
         }
     }
 
-    private void fingerprintResult(boolean fingerok) {
-        if (fingerok) {
+    private void fingerprintResult(boolean fingerOk) {
+        if (fingerOk) {
             Intent resultIntent = new Intent();
             resultIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
             resultIntent.putExtra(KEY_CHECK_RESULT, true);
@@ -304,9 +302,9 @@ class FingerprintHandler extends FingerprintManager.AuthenticationCallback {
     private Callback callback;
 
     // Constructor
-    FingerprintHandler(TextView mtext, Callback mcallback) {
-        text = mtext;
-        callback = mcallback;
+    FingerprintHandler(TextView mText, Callback mCallback) {
+        text = mText;
+        callback = mCallback;
     }
 
     @Override

+ 4 - 1
src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.java

@@ -26,6 +26,7 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.Resources.NotFoundException;
+import android.graphics.PorterDuff;
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.support.v4.app.Fragment;
@@ -55,6 +56,7 @@ import com.owncloud.android.ui.fragment.OCFileListFragment;
 import com.owncloud.android.utils.AnalyticsUtils;
 import com.owncloud.android.utils.DataHolderUtil;
 import com.owncloud.android.utils.ErrorMessageAdapter;
+import com.owncloud.android.utils.ThemeUtils;
 
 import java.util.ArrayList;
 
@@ -103,7 +105,7 @@ public class FolderPickerActivity extends FileActivity implements FileFragment.C
         if (getIntent().getStringExtra(EXTRA_ACTION) != null) {
             caption = getIntent().getStringExtra(EXTRA_ACTION);
         } else {
-            caption = getString(R.string.default_display_name_for_root_folder);
+            caption = ThemeUtils.getDefaultDisplayNameForRootFolder();
         }
         getSupportActionBar().setTitle(caption);
 
@@ -367,6 +369,7 @@ public class FolderPickerActivity extends FileActivity implements FileFragment.C
         mCancelBtn = (Button) findViewById(R.id.folder_picker_btn_cancel);
         mCancelBtn.setOnClickListener(this);
         mChooseBtn = (Button) findViewById(R.id.folder_picker_btn_choose);
+        mChooseBtn.getBackground().setColorFilter(ThemeUtils.primaryColor(), PorterDuff.Mode.SRC_ATOP);
         mChooseBtn.setOnClickListener(this);
     }
     

+ 2 - 1
src/main/java/com/owncloud/android/ui/activity/FolderSyncActivity.java

@@ -53,6 +53,7 @@ import com.owncloud.android.ui.dialog.SyncedFolderPreferencesDialogFragment;
 import com.owncloud.android.ui.dialog.parcel.SyncedFolderParcelable;
 import com.owncloud.android.utils.AnalyticsUtils;
 import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.ThemeUtils;
 
 import java.io.File;
 import java.util.ArrayList;
@@ -111,7 +112,7 @@ public class FolderSyncActivity extends FileActivity implements FolderSyncAdapte
 
         setupContent();
 
-        getSupportActionBar().setTitle(getString(R.string.drawer_folder_sync));
+        ThemeUtils.setColoredTitle(getSupportActionBar(), getString(R.string.drawer_folder_sync));
         getSupportActionBar().setDisplayHomeAsUpEnabled(true);
     }
 

+ 2 - 1
src/main/java/com/owncloud/android/ui/activity/ManageAccountsActivity.java

@@ -53,6 +53,7 @@ import com.owncloud.android.ui.adapter.AccountListItem;
 import com.owncloud.android.ui.helpers.FileOperationsHelper;
 import com.owncloud.android.utils.AnalyticsUtils;
 import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.ThemeUtils;
 
 import org.parceler.Parcels;
 
@@ -90,7 +91,7 @@ public class ManageAccountsActivity extends FileActivity
         super.onCreate(savedInstanceState);
 
         mTintedCheck = DrawableCompat.wrap(ContextCompat.getDrawable(this, R.drawable.ic_account_circle_white_18dp));
-        int tint = ContextCompat.getColor(this, R.color.primary);
+        int tint = ThemeUtils.primaryColor();
         DrawableCompat.setTint(mTintedCheck, tint);
 
         setContentView(R.layout.accounts_layout);

+ 2 - 1
src/main/java/com/owncloud/android/ui/activity/NotificationsActivity.java

@@ -54,6 +54,7 @@ import com.owncloud.android.lib.resources.notifications.models.Notification;
 import com.owncloud.android.ui.adapter.NotificationListAdapter;
 import com.owncloud.android.utils.AnalyticsUtils;
 import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.ThemeUtils;
 
 import java.io.IOException;
 import java.util.List;
@@ -119,7 +120,7 @@ public class NotificationsActivity extends FileActivity {
 
         // setup drawer
         setupDrawer(R.id.nav_notifications);
-        getSupportActionBar().setTitle(getString(R.string.drawer_item_notifications));
+        ThemeUtils.setColoredTitle(getSupportActionBar(), getString(R.string.drawer_item_notifications));
 
         swipeListRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
             @Override

+ 23 - 8
src/main/java/com/owncloud/android/ui/activity/ParticipateActivity.java

@@ -22,8 +22,10 @@
 package com.owncloud.android.ui.activity;
 
 import android.content.Intent;
+import android.graphics.PorterDuff;
 import android.net.Uri;
 import android.os.Bundle;
+import android.support.v7.widget.AppCompatButton;
 import android.text.Html;
 import android.text.method.LinkMovementMethod;
 import android.view.MenuItem;
@@ -32,6 +34,8 @@ import android.widget.TextView;
 
 import com.owncloud.android.R;
 import com.owncloud.android.utils.AnalyticsUtils;
+import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.ThemeUtils;
 
 /**
  * Activity providing information about ways to participate in the app's development.
@@ -52,7 +56,11 @@ public class ParticipateActivity extends FileActivity {
 
         // setup drawer
         setupDrawer(R.id.nav_participate);
-        getSupportActionBar().setTitle(getString(R.string.drawer_participate));
+
+        if (getSupportActionBar() != null) {
+            getSupportActionBar().setTitle(ThemeUtils.getColoredTitle(getString(R.string.drawer_participate),
+                    ThemeUtils.fontColor()));
+        }
 
         setupContent();
     }
@@ -71,27 +79,34 @@ public class ParticipateActivity extends FileActivity {
         contributeIrcView.setMovementMethod(LinkMovementMethod.getInstance());
         contributeIrcView.setText(Html.fromHtml(
                 getString(R.string.participate_contribute_irc_text,
-                        getString(R.string.irc_weblink)
-                )));
+                        ThemeUtils.colorToHexString(ThemeUtils.primaryColor()),
+                        getString(R.string.irc_weblink))));
 
         TextView contributeForumView = (TextView) findViewById(R.id.participate_contribute_forum_text);
         contributeForumView.setMovementMethod(LinkMovementMethod.getInstance());
         contributeForumView.setText(Html.fromHtml(
                 getString(R.string.participate_contribute_forum_text,
-                        getString(R.string.help_link)
-                )));
+                        ThemeUtils.colorToHexString(ThemeUtils.primaryColor()),
+                        getString(R.string.help_link))));
 
         TextView contributeTranslationView = (TextView) findViewById(R.id.participate_contribute_translate_text);
         contributeTranslationView.setMovementMethod(LinkMovementMethod.getInstance());
         contributeTranslationView.setText(Html.fromHtml(
-                getString(R.string.participate_contribute_translate_text, getString(R.string.translation_link))));
+                getString(R.string.participate_contribute_translate_text,
+                        ThemeUtils.colorToHexString(ThemeUtils.primaryColor()),
+                        getString(R.string.translation_link))));
 
         TextView contributeGithubView = (TextView) findViewById(R.id.participate_contribute_github_text);
         contributeGithubView.setMovementMethod(LinkMovementMethod.getInstance());
-        contributeGithubView.setText(Html.fromHtml(getString(R.string.participate_contribute_github_text,
+        contributeGithubView.setText(Html.fromHtml(
+                getString(R.string.participate_contribute_github_text,
+                        ThemeUtils.colorToHexString(ThemeUtils.primaryColor()),
                 getString(R.string.contributing_link))));
 
-        findViewById(R.id.participate_testing_report).setOnClickListener(new View.OnClickListener() {
+        AppCompatButton reportButton = (AppCompatButton) findViewById(R.id.participate_testing_report);
+        reportButton.getBackground().setColorFilter(ThemeUtils.primaryColor(), PorterDuff.Mode.SRC_ATOP);
+        reportButton.setTextColor(ThemeUtils.fontColor());
+        reportButton.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.report_issue_link))));

+ 20 - 4
src/main/java/com/owncloud/android/ui/activity/PassCodeActivity.java

@@ -1,4 +1,4 @@
-/**
+/*
  *   ownCloud Android client application
  *
  *   @author Bartek Przybylski
@@ -24,6 +24,7 @@ package com.owncloud.android.ui.activity;
 
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.graphics.PorterDuff;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
 import android.support.v7.app.AppCompatActivity;
@@ -41,6 +42,7 @@ import android.widget.Toast;
 import com.owncloud.android.R;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.utils.AnalyticsUtils;
+import com.owncloud.android.utils.ThemeUtils;
 
 import java.util.Arrays;
 
@@ -92,15 +94,29 @@ public class PassCodeActivity extends AppCompatActivity {
         setContentView(R.layout.passcodelock);
         
         mBCancel = (Button) findViewById(R.id.cancel);
+        mBCancel.getBackground().setColorFilter(ThemeUtils.primaryColor(), PorterDuff.Mode.SRC_ATOP);
+
         mPassCodeHdr = (TextView) findViewById(R.id.header);
         mPassCodeHdrExplanation = (TextView) findViewById(R.id.explanation);
+
         mPassCodeEditTexts[0] = (EditText) findViewById(R.id.txt0);
+        mPassCodeEditTexts[0].setTextColor(ThemeUtils.primaryColor());
+        mPassCodeEditTexts[0].getBackground().setColorFilter(ThemeUtils.primaryColor(), PorterDuff.Mode.SRC_ATOP);
         mPassCodeEditTexts[0].requestFocus();
         getWindow().setSoftInputMode(
                 android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
+
         mPassCodeEditTexts[1] = (EditText) findViewById(R.id.txt1);
+        mPassCodeEditTexts[1].setTextColor(ThemeUtils.primaryColor());
+        mPassCodeEditTexts[1].getBackground().setColorFilter(ThemeUtils.primaryColor(), PorterDuff.Mode.SRC_ATOP);
+
         mPassCodeEditTexts[2] = (EditText) findViewById(R.id.txt2);
+        mPassCodeEditTexts[2].setTextColor(ThemeUtils.primaryColor());
+        mPassCodeEditTexts[2].getBackground().setColorFilter(ThemeUtils.primaryColor(), PorterDuff.Mode.SRC_ATOP);
+
         mPassCodeEditTexts[3] = (EditText) findViewById(R.id.txt3);
+        mPassCodeEditTexts[3].setTextColor(ThemeUtils.primaryColor());
+        mPassCodeEditTexts[3].getBackground().setColorFilter(ThemeUtils.primaryColor(), PorterDuff.Mode.SRC_ATOP);
 
         if (ACTION_CHECK.equals(getIntent().getAction())) {
             /// this is a pass code request; the user has to input the right value
@@ -423,8 +439,8 @@ public class PassCodeActivity extends AppCompatActivity {
      * Sets the input fields to empty strings and puts the focus on the first one.
      */
     protected void clearBoxes(){
-        for (int i=0; i < mPassCodeEditTexts.length; i++) {
-            mPassCodeEditTexts[i].setText("");
+        for (EditText mPassCodeEditText : mPassCodeEditTexts) {
+            mPassCodeEditText.setText("");
         }
         mPassCodeEditTexts[0].requestFocus();
     }
@@ -483,7 +499,7 @@ public class PassCodeActivity extends AppCompatActivity {
          * @param lastOne       'True' means that watcher corresponds to the last position of the
          *                      pass code.
          */
-        public PassCodeDigitTextWatcher(int index, boolean lastOne) {
+        PassCodeDigitTextWatcher(int index, boolean lastOne) {
             mIndex = index;
             mLastOne  = lastOne;
             if (mIndex < 0) {

+ 32 - 1
src/main/java/com/owncloud/android/ui/activity/Preferences.java

@@ -30,6 +30,8 @@ import android.content.SharedPreferences;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Configuration;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
@@ -72,6 +74,7 @@ import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.utils.AnalyticsUtils;
 import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.ThemeUtils;
 
 import java.io.IOException;
 
@@ -133,6 +136,11 @@ public class Preferences extends PreferenceActivity
     @SuppressWarnings("deprecation")
     @Override
     public void onCreate(Bundle savedInstanceState) {
+
+        if (ThemeUtils.themingEnabled()) {
+            setTheme(R.style.FallbackThemingTheme);
+        }
+
         getDelegate().installViewFactory();
         getDelegate().onCreate(savedInstanceState);
         super.onCreate(savedInstanceState);
@@ -140,7 +148,17 @@ public class Preferences extends PreferenceActivity
 
         ActionBar actionBar = getSupportActionBar();
         actionBar.setDisplayHomeAsUpEnabled(true);
-        actionBar.setTitle(R.string.actionbar_settings);
+        ThemeUtils.setColoredTitle(actionBar, getString(R.string.actionbar_settings));
+        actionBar.setBackgroundDrawable(new ColorDrawable(ThemeUtils.primaryColor()));
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            getWindow().setStatusBarColor(ThemeUtils.primaryDarkColor());
+        }
+
+        Drawable backArrow = getResources().getDrawable(R.drawable.ic_arrow_back);
+        actionBar.setHomeAsUpIndicator(ThemeUtils.tintDrawable(backArrow, ThemeUtils.fontColor()));
+
+        int accentColor = ThemeUtils.primaryAccentColor();
 
         // retrieve user's base uri
         setupBaseUri();
@@ -166,8 +184,15 @@ public class Preferences extends PreferenceActivity
         // Register context menu for list of preferences.
         registerForContextMenu(getListView());
 
+        // General
+        PreferenceCategory preferenceCategoryGeneral = (PreferenceCategory) findPreference("general");
+        preferenceCategoryGeneral.setTitle(ThemeUtils.getColoredTitle(getString(R.string.prefs_category_general),
+                accentColor));
+
         // Synced folders
         PreferenceCategory preferenceCategoryFolderSync = (PreferenceCategory) findPreference("folder_sync");
+        preferenceCategoryFolderSync.setTitle(ThemeUtils.getColoredTitle(getString(R.string.drawer_folder_sync),
+                accentColor));
         PreferenceScreen preferenceScreen = (PreferenceScreen) findPreference("preference_screen");
 
         if (!getResources().getBoolean(R.bool.syncedFolder_light)) {
@@ -211,6 +236,8 @@ public class Preferences extends PreferenceActivity
         }
 
         PreferenceCategory preferenceCategoryDetails = (PreferenceCategory) findPreference("details");
+        preferenceCategoryDetails.setTitle(ThemeUtils.getColoredTitle(getString(R.string.prefs_category_details),
+                accentColor));
 
         boolean fPassCodeEnabled = getResources().getBoolean(R.bool.passcode_enabled);
         pCode = (SwitchPreference) findPreference(PassCodeActivity.PREFERENCE_SET_PASSCODE);
@@ -309,6 +336,8 @@ public class Preferences extends PreferenceActivity
         }
 
         PreferenceCategory preferenceCategoryMore = (PreferenceCategory) findPreference("more");
+        preferenceCategoryMore.setTitle(ThemeUtils.getColoredTitle(getString(R.string.prefs_category_more),
+                accentColor));
 
         boolean calendarContactsEnabled = getResources().getBoolean(R.bool.davdroid_integration_enabled);
         Preference pCalendarContacts = findPreference("calendar_contacts");
@@ -578,6 +607,8 @@ public class Preferences extends PreferenceActivity
 
         // About category
         PreferenceCategory preferenceCategoryAbout = (PreferenceCategory) findPreference("about");
+        preferenceCategoryAbout.setTitle(ThemeUtils.getColoredTitle(getString(R.string.prefs_category_about),
+                accentColor));
 
         /* About App */
         pAboutApp = findPreference("about_app");

+ 2 - 1
src/main/java/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java

@@ -88,6 +88,7 @@ import com.owncloud.android.ui.helpers.UriUploader;
 import com.owncloud.android.utils.DataHolderUtil;
 import com.owncloud.android.utils.ErrorMessageAdapter;
 import com.owncloud.android.utils.FileStorageUtils;
+import com.owncloud.android.utils.ThemeUtils;
 
 import java.io.File;
 import java.io.FileWriter;
@@ -294,7 +295,7 @@ public class ReceiveExternalFilesActivity extends FileActivity
 
             mTintedCheck = DrawableCompat.wrap(ContextCompat.getDrawable(parent,
                     R.drawable.ic_account_circle_white_18dp));
-            int tint = ContextCompat.getColor(parent, R.color.primary);
+            int tint = ThemeUtils.primaryColor();
             DrawableCompat.setTint(mTintedCheck, tint);
 
             mAccountListAdapter = new AccountListAdapter(parent, getAccountListItems(parent), mTintedCheck);

+ 34 - 6
src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java

@@ -33,6 +33,7 @@ import android.widget.ProgressBar;
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.utils.ThemeUtils;
 
 /**
  * Base class providing toolbar registration functionality, see {@link #setupToolbar()}.
@@ -49,7 +50,7 @@ public abstract class ToolbarActivity extends BaseActivity {
      * Toolbar setup that must be called in implementer's {@link #onCreate} after {@link #setContentView} if they
      * want to use the toolbar.
      */
-    protected void setupToolbar() {
+    protected void setupToolbar(boolean useBackgroundImage) {
         Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
         setSupportActionBar(toolbar);
 
@@ -57,14 +58,34 @@ public abstract class ToolbarActivity extends BaseActivity {
         if (mProgressBar != null) {
             mProgressBar.setIndeterminateDrawable(
                     ContextCompat.getDrawable(this, R.drawable.actionbar_progress_indeterminate_horizontal));
+
+            ThemeUtils.colorToolbarProgressBar(this, ThemeUtils.primaryColor());
+        }
+
+        ThemeUtils.colorStatusBar(this, ThemeUtils.primaryDarkColor());
+
+        if (toolbar.getOverflowIcon() != null) {
+            ThemeUtils.tintDrawable(toolbar.getOverflowIcon(), ThemeUtils.fontColor());
+        }
+
+        if (toolbar.getNavigationIcon() != null) {
+            ThemeUtils.tintDrawable(toolbar.getNavigationIcon(), ThemeUtils.fontColor());
+        }
+
+        if (!useBackgroundImage) {
+            toolbar.setBackgroundColor(ThemeUtils.primaryColor());
         }
     }
 
+    protected void setupToolbar() {
+        setupToolbar(false);
+    }
+
     /**
      * Updates title bar and home buttons (state and icon).
      */
     protected void updateActionBarTitleAndHomeButton(OCFile chosenFile) {
-        String title = getString(R.string.default_display_name_for_root_folder);    // default
+        String title = ThemeUtils.getDefaultDisplayNameForRootFolder();    // default
         boolean inRoot;
 
         // choose the appropriate title
@@ -89,13 +110,20 @@ public abstract class ToolbarActivity extends BaseActivity {
             titleToSet = title;
         }
 
-        // set the chosen title
+        // set & color the chosen title
         ActionBar actionBar = getSupportActionBar();
-        actionBar.setTitle(titleToSet);
+        ThemeUtils.setColoredTitle(actionBar, titleToSet);
 
         // set home button properties
-        actionBar.setDisplayHomeAsUpEnabled(true);
-        actionBar.setDisplayShowTitleEnabled(true);
+        if (actionBar != null) {
+            actionBar.setDisplayHomeAsUpEnabled(true);
+            actionBar.setDisplayShowTitleEnabled(true);
+        }
+
+        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+        if (toolbar.getNavigationIcon() != null) {
+            ThemeUtils.tintDrawable(toolbar.getNavigationIcon(), ThemeUtils.fontColor());
+        }
     }
 
     /**

+ 6 - 2
src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.java

@@ -23,6 +23,7 @@ package com.owncloud.android.ui.activity;
 import android.accounts.Account;
 import android.app.Activity;
 import android.content.Intent;
+import android.graphics.PorterDuff;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Environment;
@@ -31,6 +32,7 @@ import android.support.v4.app.Fragment;
 import android.support.v4.app.FragmentManager;
 import android.support.v4.app.FragmentTransaction;
 import android.support.v7.app.ActionBar;
+import android.support.v7.widget.AppCompatButton;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
@@ -52,6 +54,7 @@ import com.owncloud.android.ui.fragment.ExtendedListFragment;
 import com.owncloud.android.ui.fragment.LocalFileListFragment;
 import com.owncloud.android.utils.AnalyticsUtils;
 import com.owncloud.android.utils.FileStorageUtils;
+import com.owncloud.android.utils.ThemeUtils;
 
 import java.io.File;
 
@@ -133,7 +136,8 @@ public class UploadFilesActivity extends FileActivity implements
         // Set input controllers
         mCancelBtn = (Button) findViewById(R.id.upload_files_btn_cancel);
         mCancelBtn.setOnClickListener(this);
-        mUploadBtn = (Button) findViewById(R.id.upload_files_btn_upload);
+        mUploadBtn = (AppCompatButton) findViewById(R.id.upload_files_btn_upload);
+        mUploadBtn.getBackground().setColorFilter(ThemeUtils.primaryAccentColor(), PorterDuff.Mode.SRC_ATOP);
         mUploadBtn.setOnClickListener(this);
 
         int localBehaviour = PreferenceManager.getUploaderBehaviour(this);
@@ -353,7 +357,7 @@ public class UploadFilesActivity extends FileActivity implements
         if(checked) {
             selectAll.setIcon(R.drawable.ic_select_none);
         } else {
-            selectAll.setIcon(R.drawable.ic_select_all);
+            selectAll.setIcon(ThemeUtils.tintDrawable(R.drawable.ic_select_all, ThemeUtils.primaryColor()));
         }
     }
 

+ 55 - 6
src/main/java/com/owncloud/android/ui/activity/UserInfoActivity.java

@@ -32,22 +32,29 @@ import android.app.FragmentManager;
 import android.content.ContentResolver;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.os.Bundle;
 import android.support.annotation.ColorInt;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
-import android.support.v4.content.ContextCompat;
+import android.support.design.widget.AppBarLayout;
 import android.support.v4.graphics.drawable.DrawableCompat;
 import android.text.TextUtils;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
+import android.webkit.URLUtil;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.request.animation.GlideAnimation;
+import com.bumptech.glide.request.target.SimpleTarget;
 import com.google.gson.Gson;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
@@ -187,12 +194,16 @@ public class UserInfoActivity extends FileActivity {
         setContentView(R.layout.user_info_layout);
         unbinder = ButterKnife.bind(this);
 
-        setupToolbar();
-        updateActionBarTitleAndHomeButtonByString("");
-
         setAccount(AccountUtils.getCurrentOwnCloudAccount(this));
         onAccountSet(false);
 
+        boolean useBackgroundImage = URLUtil.isValidUrl(
+                getStorageManager().getCapability(account.name).getServerBackground());
+
+        setupToolbar(useBackgroundImage);
+        updateActionBarTitleAndHomeButtonByString("");
+
+
         if (userInfo != null) {
             populateUserInfoUi(userInfo);
             emptyContentContainer.setVisibility(View.GONE);
@@ -201,6 +212,8 @@ public class UserInfoActivity extends FileActivity {
             setMultiListLoadingMessage();
             fetchAndSetData();
         }
+
+        setHeaderImage();
     }
 
     @Override
@@ -255,12 +268,48 @@ public class UserInfoActivity extends FileActivity {
         }
     }
 
+    private void setHeaderImage() {
+        if (getStorageManager().getCapability(account.name).getServerBackground() != null) {
+            final AppBarLayout appBar = (AppBarLayout) findViewById(R.id.appbar);
+
+            if (appBar != null) {
+                String background = getStorageManager().getCapability(account.name).getServerBackground();
+
+                if (URLUtil.isValidUrl(background)) {
+                    // background image
+                    SimpleTarget target = new SimpleTarget<Drawable>() {
+                        @Override
+                        public void onResourceReady(Drawable resource, GlideAnimation glideAnimation) {
+                            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
+                                appBar.setBackgroundDrawable(resource);
+                            } else {
+                                appBar.setBackground(resource);
+                            }
+                        }
+                    };
+
+                    Glide.with(this)
+                            .load(background)
+                            .centerCrop()
+                            .placeholder(R.drawable.background)
+                            .error(R.drawable.background)
+                            .crossFade()
+                            .into(target);
+                } else {
+                    // plain color
+                    int color = Color.parseColor(background);
+                    appBar.setBackgroundColor(color);
+                }
+            }
+        }
+    }
+
     private void populateUserInfoUi(UserInfo userInfo) {
         userName.setText(account.name);
         DisplayUtils.setAvatar(account, UserInfoActivity.this,
-                mCurrentAccountAvatarRadiusDimension, getResources(), getStorageManager(),avatar);
+                mCurrentAccountAvatarRadiusDimension, getResources(), getStorageManager(), avatar);
 
-        int tint = ContextCompat.getColor(this, R.color.primary);
+        int tint = Color.parseColor(getStorageManager().getCapability(account.name).getServerColor());
 
         if (userInfo != null) {
             if (!TextUtils.isEmpty(userInfo.getDisplayName())) {

+ 6 - 1
src/main/java/com/owncloud/android/ui/adapter/AccountListAdapter.java

@@ -35,6 +35,7 @@ import com.owncloud.android.lib.common.OwnCloudAccount;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.activity.BaseActivity;
 import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.ThemeUtils;
 
 import java.util.List;
 
@@ -105,7 +106,11 @@ public class AccountListAdapter extends ArrayAdapter<AccountListItem> implements
     private View setupAddAccountListItem(ViewGroup parent) {
         LayoutInflater inflater = mContext.getLayoutInflater();
         View actionView = inflater.inflate(R.layout.account_action, parent, false);
-        ((TextView) actionView.findViewById(R.id.user_name)).setText(R.string.prefs_add_account);
+
+        TextView userName = (TextView) actionView.findViewById(R.id.user_name);
+        userName.setText(R.string.prefs_add_account);
+        userName.setTextColor(ThemeUtils.primaryColor());
+
         ((ImageView) actionView.findViewById(R.id.user_icon)).setImageResource(R.drawable.ic_account_plus);
 
         // bind action listener

+ 3 - 1
src/main/java/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java

@@ -50,6 +50,7 @@ import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.activity.FileActivity;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.MimeTypeUtil;
+import com.owncloud.android.utils.ThemeUtils;
 
 import java.io.File;
 import java.lang.ref.WeakReference;
@@ -77,7 +78,7 @@ public class ExpandableUploadListAdapter extends BaseExpandableListAdapter imple
     private UploadGroup[] mUploadGroups = null;
 
     interface Refresh {
-        public void refresh();
+        void refresh();
     }
 
     abstract class UploadGroup implements Refresh {
@@ -713,6 +714,7 @@ public class ExpandableUploadListAdapter extends BaseExpandableListAdapter imple
         TextView tv = (TextView) convertView.findViewById(R.id.uploadListGroupName);
         tv.setText(String.format(mParentActivity.getString(R.string.uploads_view_group_header),
                 group.getGroupName(), group.getGroupItemCount()));
+        tv.setTextColor(ThemeUtils.primaryAccentColor());
         return convertView;
     }
 

+ 7 - 12
src/main/java/com/owncloud/android/ui/adapter/FileListListAdapter.java

@@ -65,6 +65,7 @@ import com.owncloud.android.ui.interfaces.OCFileListFragmentInterface;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.utils.MimeTypeUtil;
+import com.owncloud.android.utils.ThemeUtils;
 
 import java.io.File;
 import java.util.ArrayList;
@@ -338,8 +339,8 @@ public class FileListListAdapter extends BaseAdapter {
                     ) {
                 if (parentList.isItemChecked(position)) {
                     view.setBackgroundColor(mContext.getResources().getColor(R.color.selected_item_background));
-                    checkBoxV.setImageDrawable(DisplayUtils.tintDrawable(R.drawable.ic_checkbox_marked,
-                            R.color.primary));
+                    checkBoxV.setImageDrawable(ThemeUtils.tintDrawable(R.drawable.ic_checkbox_marked,
+                            ThemeUtils.primaryColor()));
                 } else {
                     view.setBackgroundColor(Color.WHITE);
                     checkBoxV.setImageResource(R.drawable.ic_checkbox_blank_outline);
@@ -400,25 +401,19 @@ public class FileListListAdapter extends BaseAdapter {
                     }
 
                     if (file.getMimetype().equalsIgnoreCase("image/png")) {
-                        fileIcon.setBackgroundColor(mContext.getResources()
-                                .getColor(R.color.background_color));
+                        fileIcon.setBackgroundColor(mContext.getResources().getColor(R.color.background_color));
                     }
 
 
                 } else {
-                    fileIcon.setImageResource(MimeTypeUtil.getFileTypeIconId(file.getMimetype(),
-                            file.getFileName()));
+                    fileIcon.setImageResource(MimeTypeUtil.getFileTypeIconId(file.getMimetype(), file.getFileName()));
                 }
 
 
             } else {
                 // Folder
-                fileIcon.setImageDrawable(
-                        MimeTypeUtil.getFolderTypeIcon(
-                                file.isSharedWithMe() || file.isSharedWithSharee(),
-                                file.isSharedViaLink()
-                        )
-                );
+                fileIcon.setImageDrawable(MimeTypeUtil.getFolderTypeIcon(file.isSharedWithMe() ||
+                        file.isSharedWithSharee(), file.isSharedViaLink()));
             }
         }
         return view;

+ 3 - 2
src/main/java/com/owncloud/android/ui/adapter/FolderSyncAdapter.java

@@ -35,7 +35,7 @@ import com.afollestad.sectionedrecyclerview.SectionedRecyclerViewAdapter;
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.SyncedFolderDisplayItem;
 import com.owncloud.android.datamodel.ThumbnailsCacheManager;
-import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.ThemeUtils;
 
 import java.io.File;
 import java.util.ArrayList;
@@ -195,7 +195,8 @@ public class FolderSyncAdapter extends SectionedRecyclerViewAdapter<FolderSyncAd
 
     private void setSyncButtonActiveIcon(ImageButton syncStatusButton, boolean enabled) {
         if(enabled) {
-            syncStatusButton.setImageDrawable(DisplayUtils.tintDrawable(R.drawable.ic_cloud_sync_on, R.color.primary));
+            syncStatusButton.setImageDrawable(ThemeUtils.tintDrawable(R.drawable.ic_cloud_sync_on,
+                    ThemeUtils.primaryColor()));
         } else {
             syncStatusButton.setImageResource(R.drawable.ic_cloud_sync_off);
         }

+ 19 - 2
src/main/java/com/owncloud/android/ui/dialog/CreateFolderDialogFragment.java

@@ -22,6 +22,7 @@ package com.owncloud.android.ui.dialog;
 
 import android.app.Dialog;
 import android.content.DialogInterface;
+import android.graphics.PorterDuff;
 import android.os.Bundle;
 import android.support.v4.app.DialogFragment;
 import android.support.v7.app.AlertDialog;
@@ -36,6 +37,7 @@ import com.owncloud.android.R;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.resources.files.FileUtils;
 import com.owncloud.android.ui.activity.ComponentsGetter;
+import com.owncloud.android.utils.ThemeUtils;
 
 /**
  *  Dialog to input the name for a new folder to create.  
@@ -65,9 +67,22 @@ public class CreateFolderDialogFragment
         return frag;
         
     }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+
+        int color = ThemeUtils.primaryAccentColor();
+
+        AlertDialog alertDialog = (AlertDialog) getDialog();
+
+        alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(color);
+        alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(color);
+    }
     
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
+        int accentColor = ThemeUtils.primaryAccentColor();
         mParentFolder = getArguments().getParcelable(ARG_PARENT_FOLDER);
         
         // Inflate the layout for the dialog
@@ -78,13 +93,15 @@ public class CreateFolderDialogFragment
         EditText inputText = ((EditText)v.findViewById(R.id.user_input));
         inputText.setText("");
         inputText.requestFocus();
-        
+        inputText.getBackground().setColorFilter(accentColor, PorterDuff.Mode.SRC_ATOP);
+
         // Build the dialog  
         AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
         builder.setView(v)
                .setPositiveButton(R.string.common_ok, this)
                .setNegativeButton(R.string.common_cancel, this)
-               .setTitle(R.string.uploader_info_dirname);
+                .setTitle(ThemeUtils.getColoredTitle(getResources().getString(R.string.uploader_info_dirname),
+                        accentColor));
         Dialog d = builder.create();
         d.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
         return d;

+ 3 - 5
src/main/java/com/owncloud/android/ui/dialog/IndeterminateProgressDialog.java

@@ -29,6 +29,7 @@ import android.view.KeyEvent;
 import android.widget.ProgressBar;
 
 import com.owncloud.android.R;
+import com.owncloud.android.utils.ThemeUtils;
 
 
 public class IndeterminateProgressDialog extends DialogFragment {
@@ -67,7 +68,7 @@ public class IndeterminateProgressDialog extends DialogFragment {
             @Override
             public void onShow(DialogInterface dialog) {
                 ProgressBar v = (ProgressBar) progressDialog.findViewById(android.R.id.progress);
-                v.getIndeterminateDrawable().setColorFilter(getResources().getColor(R.color.color_accent),
+                v.getIndeterminateDrawable().setColorFilter(ThemeUtils.primaryAccentColor(),
                         android.graphics.PorterDuff.Mode.MULTIPLY);
 
             }
@@ -87,10 +88,7 @@ public class IndeterminateProgressDialog extends DialogFragment {
                 public boolean onKey(DialogInterface dialog, int keyCode,
                         KeyEvent event) {
 
-                    if( keyCode == KeyEvent.KEYCODE_BACK) {
-                        return true;
-                    }
-                    return false;
+                    return keyCode == KeyEvent.KEYCODE_BACK;
                 }
 
             };

+ 2 - 1
src/main/java/com/owncloud/android/ui/dialog/LoadingDialog.java

@@ -30,6 +30,7 @@ import android.widget.ProgressBar;
 import android.widget.TextView;
 
 import com.owncloud.android.R;
+import com.owncloud.android.utils.ThemeUtils;
 
 public class LoadingDialog extends DialogFragment {
 
@@ -62,7 +63,7 @@ public class LoadingDialog extends DialogFragment {
         // set progress wheel color
         ProgressBar progressBar  = (ProgressBar) v.findViewById(R.id.loadingBar);
         progressBar.getIndeterminateDrawable().setColorFilter(
-                getResources().getColor(R.color.color_accent), PorterDuff.Mode.SRC_IN);
+                ThemeUtils.primaryAccentColor(), PorterDuff.Mode.SRC_IN);
         
         return v;
     }

+ 18 - 1
src/main/java/com/owncloud/android/ui/dialog/RenameFileDialogFragment.java

@@ -28,6 +28,7 @@ package com.owncloud.android.ui.dialog;
 
 import android.app.Dialog;
 import android.content.DialogInterface;
+import android.graphics.PorterDuff;
 import android.os.Bundle;
 import android.support.v4.app.DialogFragment;
 import android.support.v7.app.AlertDialog;
@@ -42,6 +43,7 @@ import com.owncloud.android.R;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.resources.files.FileUtils;
 import com.owncloud.android.ui.activity.ComponentsGetter;
+import com.owncloud.android.utils.ThemeUtils;
 
 
 /**
@@ -71,8 +73,21 @@ public class RenameFileDialogFragment
         
     }
 
+    @Override
+    public void onStart() {
+        super.onStart();
+
+        int color = ThemeUtils.primaryAccentColor();
+
+        AlertDialog alertDialog = (AlertDialog) getDialog();
+
+        alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(color);
+        alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(color);
+    }
+
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
+        int accentColor = ThemeUtils.primaryAccentColor();
         mTargetFile = getArguments().getParcelable(ARG_TARGET_FILE);
 
         // Inflate the layout for the dialog
@@ -92,13 +107,15 @@ public class RenameFileDialogFragment
                     Math.max(selectionStart, selectionEnd));
         }
         inputText.requestFocus();
+        inputText.getBackground().setColorFilter(accentColor, PorterDuff.Mode.SRC_ATOP);
         
         // Build the dialog  
         AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
         builder.setView(v)
                .setPositiveButton(R.string.common_ok, this)
                .setNegativeButton(R.string.common_cancel, this)
-               .setTitle(R.string.rename_dialog_title);
+                .setTitle(ThemeUtils.getColoredTitle(getResources().getString(R.string.rename_dialog_title),
+                        accentColor));
         Dialog d = builder.create();
         d.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
         return d;

+ 12 - 0
src/main/java/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java

@@ -20,6 +20,7 @@ package com.owncloud.android.ui.dialog;
 
 import android.app.Dialog;
 import android.content.DialogInterface;
+import android.graphics.PorterDuff;
 import android.os.Bundle;
 import android.support.v4.app.DialogFragment;
 import android.support.v7.app.AlertDialog;
@@ -33,6 +34,7 @@ import android.widget.Toast;
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.ui.activity.FileActivity;
+import com.owncloud.android.utils.ThemeUtils;
 
 /**
  * Dialog to input the password for sharing a file/folder.
@@ -46,6 +48,15 @@ public class SharePasswordDialogFragment extends DialogFragment
     private static final String ARG_FILE = "FILE";
     private static final String ARG_CREATE_SHARE = "CREATE_SHARE";
 
+    @Override
+    public void onStart() {
+        super.onStart();
+
+        AlertDialog alertDialog = (AlertDialog) getDialog();
+        alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(ThemeUtils.primaryAccentColor());
+        alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(ThemeUtils.primaryAccentColor());
+    }
+
     public static final String PASSWORD_FRAGMENT = "PASSWORD_FRAGMENT";
 
     private OCFile mFile;
@@ -80,6 +91,7 @@ public class SharePasswordDialogFragment extends DialogFragment
 
         // Setup layout
         EditText inputText = ((EditText)v.findViewById(R.id.share_password));
+        inputText.getBackground().setColorFilter(ThemeUtils.primaryAccentColor(), PorterDuff.Mode.SRC_ATOP);
         inputText.setText("");
         inputText.requestFocus();
 

+ 8 - 4
src/main/java/com/owncloud/android/ui/dialog/SortingOrderDialogFragment.java

@@ -26,6 +26,7 @@ import android.graphics.Typeface;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
 import android.support.v4.app.DialogFragment;
+import android.support.v7.widget.AppCompatButton;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -34,7 +35,7 @@ import android.widget.TextView;
 
 import com.owncloud.android.R;
 import com.owncloud.android.lib.common.utils.Log_OC;
-import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.ThemeUtils;
 
 /**
  * Dialog to show and choose the sorting order for the file listing.
@@ -70,6 +71,7 @@ public class SortingOrderDialogFragment extends DialogFragment {
 
     private int mSortOrder;
     private boolean mSortAscending;
+    private AppCompatButton mCancel;
 
     public static SortingOrderDialogFragment newInstance(int sortOrder, boolean ascending) {
         SortingOrderDialogFragment dialogFragment = new SortingOrderDialogFragment();
@@ -121,6 +123,8 @@ public class SortingOrderDialogFragment extends DialogFragment {
         mSortByModificationDateDescendingButton = (ImageButton) view.findViewById(R.id.sortByModificationDateDescending);
         mSortBySizeAscendingButton = (ImageButton) view.findViewById(R.id.sortBySizeAscending);
         mSortBySizeDescendingButton = (ImageButton) view.findViewById(R.id.sortBySizeDescending);
+        mCancel = (AppCompatButton) view.findViewById(R.id.cancel);
+        mCancel.setTextColor(ThemeUtils.primaryAccentColor());
 
         mSortByNameAscendingText = (TextView) view.findViewById(R.id.sortByNameAZText);
         mSortByNameDescendingText = (TextView) view.findViewById(R.id.sortByNameZAText);
@@ -196,8 +200,8 @@ public class SortingOrderDialogFragment extends DialogFragment {
      * @param textView    the text view, the text color to be set
      */
     private void colorActiveSortingIconAndText(ImageButton imageButton, TextView textView) {
-        int color = getResources().getColor(R.color.color_accent);
-        DisplayUtils.colorImageButton(imageButton, color);
+        int color = ThemeUtils.primaryAccentColor();
+        ThemeUtils.colorImageButton(imageButton, color);
         textView.setTextColor(color);
         textView.setTypeface(Typeface.DEFAULT_BOLD);
     }
@@ -208,7 +212,7 @@ public class SortingOrderDialogFragment extends DialogFragment {
      * @param view the parent view
      */
     private void setupListeners(View view) {
-        view.findViewById(R.id.cancel).setOnClickListener(new View.OnClickListener() {
+        mCancel.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View view) {
                 dismiss();

+ 40 - 16
src/main/java/com/owncloud/android/ui/dialog/SyncedFolderPreferencesDialogFragment.java

@@ -1,20 +1,20 @@
-/**
+/*
  * Nextcloud Android client application
  *
  * @author Andy Scherzinger
  * Copyright (C) 2016 Andy Scherzinger
  * Copyright (C) 2016 Nextcloud
- * <p>
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
  * License as published by the Free Software Foundation; either
  * version 3 of the License, or any later version.
- * <p>
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
- * <p>
+ *
  * You should have received a copy of the GNU Affero General Public
  * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
@@ -29,13 +29,14 @@ import android.os.Bundle;
 import android.support.annotation.NonNull;
 import android.support.v4.app.DialogFragment;
 import android.support.v7.app.AlertDialog;
+import android.support.v7.widget.AppCompatButton;
+import android.support.v7.widget.AppCompatCheckBox;
 import android.support.v7.widget.SwitchCompat;
 import android.text.style.StyleSpan;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
-import android.widget.CheckBox;
 import android.widget.TextView;
 
 import com.owncloud.android.R;
@@ -44,6 +45,7 @@ import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.activity.FolderPickerActivity;
 import com.owncloud.android.ui.dialog.parcel.SyncedFolderParcelable;
 import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.ThemeUtils;
 
 /**
  * Dialog to show the preferences/configuration of a synced folder allowing the user to change the different parameters.
@@ -58,14 +60,16 @@ public class SyncedFolderPreferencesDialogFragment extends DialogFragment {
 
     protected View mView = null;
     private SwitchCompat mEnabledSwitch;
-    private CheckBox mUploadOnWifiCheckbox;
-    private CheckBox mUploadOnChargingCheckbox;
-    private CheckBox mUploadUseSubfoldersCheckbox;
+    private AppCompatCheckBox mUploadOnWifiCheckbox;
+    private AppCompatCheckBox mUploadOnChargingCheckbox;
+    private AppCompatCheckBox mUploadUseSubfoldersCheckbox;
     private TextView mUploadBehaviorSummary;
     private TextView mLocalFolderPath;
     private TextView mRemoteFolderSummary;
 
     private SyncedFolderParcelable mSyncedFolder;
+    private AppCompatButton mCancel;
+    private AppCompatButton mSave;
 
     public static SyncedFolderPreferencesDialogFragment newInstance(SyncedFolderDisplayItem syncedFolder, int section) {
         SyncedFolderPreferencesDialogFragment dialogFragment = new SyncedFolderPreferencesDialogFragment();
@@ -122,19 +126,35 @@ public class SyncedFolderPreferencesDialogFragment extends DialogFragment {
      * @param view the parent view
      */
     private void setupDialogElements(View view) {
+        int accentColor = ThemeUtils.primaryAccentColor();
+
         // find/saves UI elements
         mEnabledSwitch = (SwitchCompat) view.findViewById(R.id.sync_enabled);
+        ThemeUtils.tintSwitch(mEnabledSwitch, accentColor);
+
         mLocalFolderPath = (TextView) view.findViewById(R.id.folder_sync_settings_local_folder_path);
 
         mRemoteFolderSummary = (TextView) view.findViewById(R.id.remote_folder_summary);
 
-        mUploadOnWifiCheckbox = (CheckBox) view.findViewById(R.id.setting_instant_upload_on_wifi_checkbox);
-        mUploadOnChargingCheckbox = (CheckBox) view.findViewById(R.id.setting_instant_upload_on_charging_checkbox);
-        mUploadUseSubfoldersCheckbox = (CheckBox) view.findViewById(R.id
-                .setting_instant_upload_path_use_subfolders_checkbox);
+        mUploadOnWifiCheckbox = (AppCompatCheckBox) view.findViewById(R.id.setting_instant_upload_on_wifi_checkbox);
+        ThemeUtils.tintCheckbox(mUploadOnWifiCheckbox, accentColor);
+
+        mUploadOnChargingCheckbox = (AppCompatCheckBox) view.findViewById(
+                R.id.setting_instant_upload_on_charging_checkbox);
+        ThemeUtils.tintCheckbox(mUploadOnChargingCheckbox, accentColor);
+
+        mUploadUseSubfoldersCheckbox = (AppCompatCheckBox) view.findViewById(
+                R.id.setting_instant_upload_path_use_subfolders_checkbox);
+        ThemeUtils.tintCheckbox(mUploadUseSubfoldersCheckbox, accentColor);
 
         mUploadBehaviorSummary = (TextView) view.findViewById(R.id.setting_instant_behaviour_summary);
 
+        mCancel = (AppCompatButton) view.findViewById(R.id.cancel);
+        mCancel.setTextColor(accentColor);
+
+        mSave = (AppCompatButton) view.findViewById(R.id.save);
+        mSave.setTextColor(accentColor);
+
         // Set values
         setEnabled(mSyncedFolder.getEnabled());
         mLocalFolderPath.setText(
@@ -182,8 +202,8 @@ public class SyncedFolderPreferencesDialogFragment extends DialogFragment {
      * @param view the parent view
      */
     private void setupListeners(View view) {
-        view.findViewById(R.id.save).setOnClickListener(new OnSyncedFolderSaveClickListener());
-        view.findViewById(R.id.cancel).setOnClickListener(new OnSyncedFolderCancelClickListener());
+        mSave.setOnClickListener(new OnSyncedFolderSaveClickListener());
+        mCancel.setOnClickListener(new OnSyncedFolderCancelClickListener());
 
         view.findViewById(R.id.setting_instant_upload_on_wifi_container).setOnClickListener(
                 new OnClickListener() {
@@ -234,7 +254,9 @@ public class SyncedFolderPreferencesDialogFragment extends DialogFragment {
                     @Override
                     public void onClick(View v) {
                         AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-                        builder.setTitle(R.string.prefs_instant_behaviour_dialogTitle)
+                        builder.setTitle(ThemeUtils.getColoredTitle(
+                                getResources().getString(R.string.prefs_instant_behaviour_dialogTitle),
+                                ThemeUtils.primaryAccentColor()))
                                 .setSingleChoiceItems(getResources().getTextArray(R.array.pref_behaviour_entries),
                                         mSyncedFolder.getUploadActionInteger(),
                                         new
@@ -248,7 +270,9 @@ public class SyncedFolderPreferencesDialogFragment extends DialogFragment {
                                                         dialog.dismiss();
                                                     }
                                                 });
-                        builder.create().show();
+                        Dialog dialog = builder.create();
+                        dialog.show();
+
                     }
                 });
     }

+ 29 - 16
src/main/java/com/owncloud/android/ui/fragment/EditShareFragment.java

@@ -22,8 +22,10 @@
 package com.owncloud.android.ui.fragment;
 
 import android.accounts.Account;
+import android.graphics.PorterDuff;
 import android.os.Bundle;
 import android.support.v4.app.Fragment;
+import android.support.v7.widget.AppCompatCheckBox;
 import android.support.v7.widget.SwitchCompat;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -44,6 +46,7 @@ import com.owncloud.android.lib.resources.shares.ShareType;
 import com.owncloud.android.lib.resources.status.OwnCloudVersion;
 import com.owncloud.android.ui.activity.FileActivity;
 import com.owncloud.android.utils.AnalyticsUtils;
+import com.owncloud.android.utils.ThemeUtils;
 
 public class EditShareFragment extends Fragment {
 
@@ -132,6 +135,9 @@ public class EditShareFragment extends Fragment {
         ((TextView)view.findViewById(R.id.editShareTitle)).setText(
                 getResources().getString(R.string.share_with_edit_title, mShare.getSharedWithDisplayName()));
 
+        View headerDivider = view.findViewById(R.id.share_header_divider);
+        headerDivider.getBackground().setColorFilter(ThemeUtils.primaryAccentColor(), PorterDuff.Mode.SRC_ATOP);
+
         // Setup layout
         refreshUiFromState(view);
 
@@ -154,35 +160,42 @@ public class EditShareFragment extends Fragment {
             boolean isNotReshareableFederatedSupported = (serverVersion != null &&
                     serverVersion.isNotReshareableFederatedSupported());
 
-            CompoundButton compound = (CompoundButton) editShareView.findViewById(R.id.canShareSwitch);
+            int accentColor = ThemeUtils.primaryAccentColor();
+
+            SwitchCompat shareSwitch = (SwitchCompat) editShareView.findViewById(R.id.canShareSwitch);
+            ThemeUtils.tintSwitch(shareSwitch, accentColor, true);
 
             if (isFederated) {
-                compound.setVisibility(View.INVISIBLE);
+                shareSwitch.setVisibility(View.INVISIBLE);
             }
-            compound.setChecked((sharePermissions & OCShare.SHARE_PERMISSION_FLAG) > 0);
+            shareSwitch.setChecked((sharePermissions & OCShare.SHARE_PERMISSION_FLAG) > 0);
 
-            compound = (CompoundButton) editShareView.findViewById(R.id.canEditSwitch);
+            SwitchCompat switchCompat = (SwitchCompat) editShareView.findViewById(R.id.canEditSwitch);
+            ThemeUtils.tintSwitch(switchCompat, accentColor, true);
             int anyUpdatePermission = OCShare.CREATE_PERMISSION_FLAG | OCShare.UPDATE_PERMISSION_FLAG |
                     OCShare.DELETE_PERMISSION_FLAG;
             boolean canEdit = (sharePermissions & anyUpdatePermission) > 0;
-            compound.setChecked(canEdit);
+            switchCompat.setChecked(canEdit);
 
             boolean areEditOptionsAvailable = !isFederated || isNotReshareableFederatedSupported;
 
             if (mFile.isFolder() && areEditOptionsAvailable) {
                 /// TODO change areEditOptionsAvailable in order to delete !isFederated
                 // from checking when iOS is ready
-                compound = (CompoundButton) editShareView.findViewById(R.id.canEditCreateCheckBox);
-                compound.setChecked((sharePermissions & OCShare.CREATE_PERMISSION_FLAG) > 0);
-                compound.setVisibility((canEdit) ? View.VISIBLE : View.GONE);
-
-                compound = (CompoundButton) editShareView.findViewById(R.id.canEditChangeCheckBox);
-                compound.setChecked((sharePermissions & OCShare.UPDATE_PERMISSION_FLAG) > 0);
-                compound.setVisibility((canEdit) ? View.VISIBLE : View.GONE);
-
-                compound = (CompoundButton) editShareView.findViewById(R.id.canEditDeleteCheckBox);
-                compound.setChecked((sharePermissions & OCShare.DELETE_PERMISSION_FLAG) > 0);
-                compound.setVisibility((canEdit) ? View.VISIBLE : View.GONE);
+                AppCompatCheckBox checkBox = (AppCompatCheckBox) editShareView.findViewById(R.id.canEditCreateCheckBox);
+                checkBox.setChecked((sharePermissions & OCShare.CREATE_PERMISSION_FLAG) > 0);
+                checkBox.setVisibility((canEdit) ? View.VISIBLE : View.GONE);
+                ThemeUtils.tintCheckbox(checkBox, accentColor);
+
+                checkBox = (AppCompatCheckBox) editShareView.findViewById(R.id.canEditChangeCheckBox);
+                checkBox.setChecked((sharePermissions & OCShare.UPDATE_PERMISSION_FLAG) > 0);
+                checkBox.setVisibility((canEdit) ? View.VISIBLE : View.GONE);
+                ThemeUtils.tintCheckbox(checkBox, accentColor);
+
+                checkBox = (AppCompatCheckBox) editShareView.findViewById(R.id.canEditDeleteCheckBox);
+                checkBox.setChecked((sharePermissions & OCShare.DELETE_PERMISSION_FLAG) > 0);
+                checkBox.setVisibility((canEdit) ? View.VISIBLE : View.GONE);
+                ThemeUtils.tintCheckbox(checkBox, accentColor);
             }
 
             setPermissionsListening(editShareView, true);

+ 46 - 6
src/main/java/com/owncloud/android/ui/fragment/ExtendedListFragment.java

@@ -1,20 +1,20 @@
-/**
+/*
  * ownCloud Android client application
  *
  * @author Mario Danic
  * Copyright (C) 2017 Mario Danic
  * Copyright (C) 2012 Bartek Przybylski
  * Copyright (C) 2012-2016 ownCloud Inc.
- * <p>
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2,
  * as published by the Free Software Foundation.
- * <p>
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * <p>
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
@@ -24,6 +24,7 @@ package com.owncloud.android.ui.fragment;
 import android.animation.LayoutTransition;
 import android.app.Activity;
 import android.content.res.Configuration;
+import android.graphics.PorterDuff;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -57,6 +58,7 @@ import android.widget.ProgressBar;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
+import com.getbase.floatingactionbutton.AddFloatingActionButton;
 import com.getbase.floatingactionbutton.FloatingActionButton;
 import com.getbase.floatingactionbutton.FloatingActionsMenu;
 import com.owncloud.android.MainApp;
@@ -74,6 +76,7 @@ import com.owncloud.android.ui.adapter.FileListListAdapter;
 import com.owncloud.android.ui.adapter.LocalFileListAdapter;
 import com.owncloud.android.ui.events.SearchEvent;
 import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.ThemeUtils;
 
 import org.greenrobot.eventbus.EventBus;
 import org.parceler.Parcel;
@@ -288,8 +291,17 @@ public class ExtendedListFragment extends Fragment
             }
         });
 
+        int fontColor = ThemeUtils.fontColor();
 
         LinearLayout searchBar = (LinearLayout) searchView.findViewById(R.id.search_bar);
+        TextView searchBadge = (TextView) searchView.findViewById(R.id.search_badge);
+
+        searchBadge.setTextColor(fontColor);
+        searchBadge.setHintTextColor(fontColor);
+
+        ImageView searchButton = (ImageView) searchView.findViewById(R.id.search_button);
+        searchButton.setImageDrawable(ThemeUtils.tintDrawable(R.drawable.ic_search, fontColor));
+
         searchBar.setLayoutTransition(new LayoutTransition());
     }
 
@@ -426,10 +438,31 @@ public class ExtendedListFragment extends Fragment
         mListView.setEmptyView(mRefreshEmptyLayout);
         mGridView.setEmptyView(mRefreshEmptyLayout);
 
+        int primaryColor = ThemeUtils.primaryColor();
+        int primaryColorDark = ThemeUtils.primaryDarkColor();
+        int fontColor = ThemeUtils.fontColor();
+
         mFabMain = (FloatingActionsMenu) v.findViewById(R.id.fab_main);
+
+        AddFloatingActionButton addButton = mFabMain.getAddButton();
+        addButton.setColorNormal(primaryColor);
+        addButton.setColorPressed(primaryColorDark);
+        addButton.setPlusColor(fontColor);
+
         mFabUpload = (FloatingActionButton) v.findViewById(R.id.fab_upload);
+        mFabUpload.setColorNormal(primaryColor);
+        mFabUpload.setColorPressed(primaryColorDark);
+        mFabUpload.setIconDrawable(ThemeUtils.tintDrawable(R.drawable.ic_action_upload, fontColor));
+
         mFabMkdir = (FloatingActionButton) v.findViewById(R.id.fab_mkdir);
+        mFabMkdir.setColorNormal(primaryColor);
+        mFabMkdir.setColorPressed(primaryColorDark);
+        mFabMkdir.setIconDrawable(ThemeUtils.tintDrawable(R.drawable.ic_action_create_dir, fontColor));
+
         mFabUploadFromApp = (FloatingActionButton) v.findViewById(R.id.fab_upload_from_app);
+        mFabUploadFromApp.setColorNormal(primaryColor);
+        mFabUploadFromApp.setColorPressed(primaryColorDark);
+        mFabUploadFromApp.setIconDrawable(ThemeUtils.tintDrawable(R.drawable.ic_import, fontColor));
 
         boolean searchSupported = AccountUtils.hasSearchSupport(AccountUtils.
                 getCurrentOwnCloudAccount(MainApp.getAppContext()));
@@ -508,6 +541,8 @@ public class ExtendedListFragment extends Fragment
         mEmptyListHeadline = (TextView) view.findViewById(R.id.empty_list_view_headline);
         mEmptyListIcon = (ImageView) view.findViewById(R.id.empty_list_icon);
         mEmptyListProgress = (ProgressBar) view.findViewById(R.id.empty_list_progress);
+        mEmptyListProgress.getIndeterminateDrawable().setColorFilter(ThemeUtils.primaryColor(),
+                PorterDuff.Mode.SRC_IN);
     }
 
     /**
@@ -737,7 +772,7 @@ public class ExtendedListFragment extends Fragment
                     mEmptyListMessage.setText(message);
 
                     if (tintIcon) {
-                        mEmptyListIcon.setImageDrawable(DisplayUtils.tintDrawable(icon, R.color.primary));
+                        mEmptyListIcon.setImageDrawable(ThemeUtils.tintDrawable(icon, ThemeUtils.primaryColor()));
                     }
 
                     mEmptyListIcon.setVisibility(View.VISIBLE);
@@ -832,8 +867,13 @@ public class ExtendedListFragment extends Fragment
     }
 
     protected void onCreateSwipeToRefresh(SwipeRefreshLayout refreshLayout) {
+        int primaryColor = ThemeUtils.primaryColor();
+        int darkColor = ThemeUtils.primaryDarkColor();
+        int accentColor = ThemeUtils.primaryAccentColor();
+
         // Colors in animations
-        refreshLayout.setColorSchemeResources(R.color.color_accent, R.color.primary, R.color.primary_dark);
+        // TODO change this to use darker and lighter color, again.
+        refreshLayout.setColorSchemeColors(accentColor, primaryColor, darkColor);
         refreshLayout.setOnRefreshListener(this);
     }
 

+ 2 - 1
src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java

@@ -53,6 +53,7 @@ import com.owncloud.android.ui.dialog.RenameFileDialogFragment;
 import com.owncloud.android.utils.AnalyticsUtils;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.MimeTypeUtil;
+import com.owncloud.android.utils.ThemeUtils;
 
 import java.lang.ref.WeakReference;
 
@@ -143,7 +144,7 @@ public class FileDetailFragment extends FileFragment implements OnClickListener
         if (mLayout == R.layout.file_details_fragment) {
             mView.findViewById(R.id.fdFavorite).setOnClickListener(this);
             ProgressBar progressBar = (ProgressBar)mView.findViewById(R.id.fdProgressBar);
-            DisplayUtils.colorPreLollipopHorizontalProgressBar(progressBar);
+            ThemeUtils.colorPreLollipopHorizontalProgressBar(progressBar);
             mProgressListener = new ProgressListener(progressBar);
             mView.findViewById(R.id.fdCancelBtn).setOnClickListener(this);
         }

+ 23 - 10
src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java

@@ -94,6 +94,7 @@ import com.owncloud.android.utils.AnalyticsUtils;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.utils.MimeTypeUtil;
+import com.owncloud.android.utils.ThemeUtils;
 
 import org.greenrobot.eventbus.EventBus;
 import org.greenrobot.eventbus.Subscribe;
@@ -175,9 +176,9 @@ public class OCFileListFragment extends ExtendedListFragment implements OCFileLi
         super.onCreate(savedInstanceState);
         setHasOptionsMenu(true);
         mSystemBarActionModeColor = getResources().getColor(R.color.action_mode_status_bar_background);
-        mSystemBarColor = getResources().getColor(R.color.primary_dark);
-        mProgressBarActionModeColor = getResources().getColor(R.color.action_mode_background);
-        mProgressBarColor = getResources().getColor(R.color.primary);
+        mSystemBarColor = ThemeUtils.primaryDarkColor();
+        mProgressBarActionModeColor = ThemeUtils.primaryDarkColor();
+        mProgressBarColor = ThemeUtils.primaryColor();
         mMultiChoiceModeListener = new MultiChoiceModeListener();
 
         if (savedInstanceState != null) {
@@ -593,8 +594,8 @@ public class OCFileListFragment extends ExtendedListFragment implements OCFileLi
             mode.invalidate();
 
             //set gray color
-            DisplayUtils.colorStatusBar(getActivity(), mSystemBarActionModeColor);
-            DisplayUtils.colorToolbarProgressBar(getActivity(), mProgressBarActionModeColor);
+            ThemeUtils.colorStatusBar(getActivity(), mSystemBarActionModeColor);
+            ThemeUtils.colorToolbarProgressBar(getActivity(), mProgressBarActionModeColor);
 
             // hide FAB in multi selection mode
             setFabEnabled(false);
@@ -641,8 +642,8 @@ public class OCFileListFragment extends ExtendedListFragment implements OCFileLi
             mActiveActionMode = null;
 
             // reset to previous color
-            DisplayUtils.colorStatusBar(getActivity(), mSystemBarColor);
-            DisplayUtils.colorToolbarProgressBar(getActivity(), mProgressBarColor);
+            ThemeUtils.colorStatusBar(getActivity(), mSystemBarColor);
+            ThemeUtils.colorToolbarProgressBar(getActivity(), mProgressBarColor);
 
             // show FAB on multi selection mode exit
             if (!mHideFab && !searchFragment) {
@@ -1315,7 +1316,7 @@ public class OCFileListFragment extends ExtendedListFragment implements OCFileLi
                     setTitle(R.string.drawer_item_shared);
                     break;
                 default:
-                    setTitle(R.string.default_display_name_for_root_folder);
+                    setTitle(ThemeUtils.getDefaultDisplayNameForRootFolder());
                     break;
             }
         }
@@ -1377,7 +1378,7 @@ public class OCFileListFragment extends ExtendedListFragment implements OCFileLi
         menuItemAddRemoveValue = MenuItemAddRemove.ADD_GRID_AND_SORT_WITH_SEARCH;
         if (getActivity() != null) {
             getActivity().invalidateOptionsMenu();
-            setTitle(R.string.default_display_name_for_root_folder);
+            setTitle(ThemeUtils.getDefaultDisplayNameForRootFolder());
         }
 
         getActivity().getIntent().removeExtra(OCFileListFragment.SEARCH_EVENT);
@@ -1534,7 +1535,19 @@ public class OCFileListFragment extends ExtendedListFragment implements OCFileLi
             @Override
             public void run() {
                 if (getActivity() != null && ((FileDisplayActivity) getActivity()).getSupportActionBar() != null) {
-                    ((FileDisplayActivity) getActivity()).getSupportActionBar().setTitle(title);
+                    ThemeUtils.setColoredTitle(((FileDisplayActivity) getActivity()).getSupportActionBar(),
+                            title, getContext());
+                }
+            }
+        });
+    }
+
+    private void setTitle(final String title) {
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                if (getActivity() != null && ((FileDisplayActivity) getActivity()).getSupportActionBar() != null) {
+                    ThemeUtils.setColoredTitle(((FileDisplayActivity) getActivity()).getSupportActionBar(), title);
                 }
             }
         });

+ 35 - 14
src/main/java/com/owncloud/android/ui/fragment/ShareFileFragment.java

@@ -25,6 +25,7 @@ import android.accounts.Account;
 import android.app.Activity;
 import android.content.Intent;
 import android.graphics.Bitmap;
+import android.graphics.PorterDuff;
 import android.net.Uri;
 import android.os.Bundle;
 import android.support.design.widget.Snackbar;
@@ -59,6 +60,7 @@ import com.owncloud.android.ui.dialog.SharePasswordDialogFragment;
 import com.owncloud.android.utils.AnalyticsUtils;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.MimeTypeUtil;
+import com.owncloud.android.utils.ThemeUtils;
 
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -191,6 +193,13 @@ public class ShareFileFragment extends Fragment implements ShareUserListAdapter.
                              Bundle savedInstanceState) {
         Log_OC.d(TAG, "onCreateView");
 
+        // use grey as fallback for elements where custom theming is not available
+        if (ThemeUtils.themingEnabled()) {
+            getContext().getTheme().applyStyle(R.style.FallbackThemingTheme, true);
+        }
+
+        int accentColor = ThemeUtils.primaryAccentColor();
+
         // Inflate the layout for this fragment
         View view = inflater.inflate(R.layout.share_file_layout, container, false);
 
@@ -207,10 +216,17 @@ public class ShareFileFragment extends Fragment implements ShareUserListAdapter.
             }
         }
 
+        // Title
+        TextView title = (TextView) view.findViewById(R.id.shareWithUsersSectionTitle);
+        title.setTextColor(accentColor);
+
         // Name
         TextView fileNameHeader = (TextView) view.findViewById(R.id.shareFileName);
         fileNameHeader.setText(getResources().getString(R.string.share_file, mFile.getFileName()));
 
+        View headerDivider = view.findViewById(R.id.share_header_divider);
+        headerDivider.getBackground().setColorFilter(ThemeUtils.primaryAccentColor(), PorterDuff.Mode.SRC_ATOP);
+
         // Size
         TextView size = (TextView) view.findViewById(R.id.shareFileSize);
         if (mFile.isFolder()) {
@@ -220,8 +236,8 @@ public class ShareFileFragment extends Fragment implements ShareUserListAdapter.
         }
 
         //  Add User Button
-        Button addUserGroupButton = (Button)
-                view.findViewById(R.id.addUserButton);
+        Button addUserGroupButton = (Button) view.findViewById(R.id.addUserButton);
+        addUserGroupButton.getBackground().setColorFilter(accentColor, PorterDuff.Mode.SRC_ATOP);
         addUserGroupButton.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View view) {
@@ -267,6 +283,7 @@ public class ShareFileFragment extends Fragment implements ShareUserListAdapter.
     private void initShareViaLinkListener(View shareView) {
         mOnShareViaLinkSwitchCheckedChangeListener = new OnShareViaLinkListener();
         SwitchCompat shareViaLinkSwitch = (SwitchCompat) shareView.findViewById(R.id.shareViaLinkSectionSwitch);
+        ThemeUtils.tintSwitch(shareViaLinkSwitch, ThemeUtils.primaryAccentColor(), true);
         shareViaLinkSwitch.setOnCheckedChangeListener(mOnShareViaLinkSwitchCheckedChangeListener);
     }
 
@@ -327,8 +344,10 @@ public class ShareFileFragment extends Fragment implements ShareUserListAdapter.
     private void initExpirationListener(View shareView) {
         mOnExpirationDateInteractionListener = new OnExpirationDateInteractionListener();
 
-        ((SwitchCompat) shareView.findViewById(R.id.shareViaLinkExpirationSwitch)).
-                setOnCheckedChangeListener(mOnExpirationDateInteractionListener);
+        SwitchCompat expirationSwitch = (SwitchCompat) shareView.findViewById(R.id.shareViaLinkExpirationSwitch);
+        expirationSwitch.setOnCheckedChangeListener(mOnExpirationDateInteractionListener);
+
+        ThemeUtils.tintSwitch(expirationSwitch, ThemeUtils.primaryAccentColor());
 
         shareView.findViewById(R.id.shareViaLinkExpirationLabel).
                 setOnClickListener(mOnExpirationDateInteractionListener);
@@ -357,8 +376,7 @@ public class ShareFileFragment extends Fragment implements ShareUserListAdapter.
                 return;
             }
             if (isChecked) {
-                ExpirationDatePickerDialogFragment dialog =
-                        ExpirationDatePickerDialogFragment.newInstance(mFile, -1);
+                ExpirationDatePickerDialogFragment dialog = ExpirationDatePickerDialogFragment.newInstance(mFile, -1);
                 dialog.show(
                         getActivity().getSupportFragmentManager(),
                         ExpirationDatePickerDialogFragment.DATE_PICKER_DIALOG
@@ -406,8 +424,9 @@ public class ShareFileFragment extends Fragment implements ShareUserListAdapter.
     private void initPasswordListener(View shareView) {
         mOnPasswordInteractionListener = new OnPasswordInteractionListener();
 
-        ((SwitchCompat) shareView.findViewById(R.id.shareViaLinkPasswordSwitch)).
-                setOnCheckedChangeListener(mOnPasswordInteractionListener);
+        SwitchCompat passwordSwitch = (SwitchCompat) shareView.findViewById(R.id.shareViaLinkPasswordSwitch);
+        passwordSwitch.setOnCheckedChangeListener(mOnPasswordInteractionListener);
+        ThemeUtils.tintSwitch(passwordSwitch, ThemeUtils.primaryAccentColor());
 
         shareView.findViewById(R.id.shareViaLinkPasswordLabel).setOnClickListener(mOnPasswordInteractionListener);
 
@@ -430,7 +449,7 @@ public class ShareFileFragment extends Fragment implements ShareUserListAdapter.
         @Override
         public void onCheckedChanged(CompoundButton switchView, boolean isChecked) {
             if (!isResumed()) {
-                // very important, setCheched(...) is called automatically during
+                // very important, setChecked(...) is called automatically during
                 // Fragment recreation on device rotations
                 return;
             }
@@ -470,9 +489,9 @@ public class ShareFileFragment extends Fragment implements ShareUserListAdapter.
     private void initEditPermissionListener(View shareView) {
         mOnEditPermissionInteractionListener = new OnEditPermissionInteractionListener();
 
-        ((SwitchCompat) shareView.findViewById(R.id.shareViaLinkEditPermissionSwitch)).
-                setOnCheckedChangeListener(mOnEditPermissionInteractionListener);
-
+        SwitchCompat permissionSwitch = (SwitchCompat) shareView.findViewById(R.id.shareViaLinkEditPermissionSwitch);
+        permissionSwitch.setOnCheckedChangeListener(mOnEditPermissionInteractionListener);
+        ThemeUtils.tintSwitch(permissionSwitch, ThemeUtils.primaryAccentColor());
     }
 
     /**
@@ -484,8 +503,9 @@ public class ShareFileFragment extends Fragment implements ShareUserListAdapter.
     private void initHideFileListingListener(View shareView) {
         mOnHideFileListingPermissionInteractionListener = new OnHideFileListingPermissionInteractionListener();
 
-        ((SwitchCompat) shareView.findViewById(R.id.shareViaLinkFileListingPermissionSwitch)).
-                setOnCheckedChangeListener(mOnHideFileListingPermissionInteractionListener);
+        SwitchCompat permissionSwitch = (SwitchCompat) shareView.findViewById(R.id.shareViaLinkFileListingPermissionSwitch);
+        permissionSwitch.setOnCheckedChangeListener(mOnHideFileListingPermissionInteractionListener);
+        ThemeUtils.tintSwitch(permissionSwitch, ThemeUtils.primaryAccentColor());
     }
 
     /**
@@ -729,6 +749,7 @@ public class ShareFileFragment extends Fragment implements ShareUserListAdapter.
 
             // GetLink button
             AppCompatButton getLinkButton = getGetLinkButton();
+            getLinkButton.getBackground().setColorFilter(ThemeUtils.primaryAccentColor(), PorterDuff.Mode.SRC_ATOP);
             getLinkButton.setVisibility(View.VISIBLE);
             getLinkButton.setOnClickListener(new View.OnClickListener() {
                 @Override

+ 25 - 1
src/main/java/com/owncloud/android/ui/fragment/contactsbackup/ContactListFragment.java

@@ -31,7 +31,9 @@ import android.content.IntentFilter;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.PorterDuff;
 import android.os.AsyncTask;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.provider.ContactsContract;
@@ -53,10 +55,10 @@ import android.widget.Button;
 import android.widget.CheckedTextView;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
-import android.widget.Toast;
 import android.widget.ProgressBar;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
+import android.widget.Toast;
 
 import com.evernote.android.job.JobRequest;
 import com.evernote.android.job.util.support.PersistableBundleCompat;
@@ -72,6 +74,7 @@ import com.owncloud.android.ui.events.VCardToggleEvent;
 import com.owncloud.android.ui.fragment.FileFragment;
 import com.owncloud.android.utils.BitmapUtils;
 import com.owncloud.android.utils.PermissionUtil;
+import com.owncloud.android.utils.ThemeUtils;
 
 import org.greenrobot.eventbus.EventBus;
 import org.greenrobot.eventbus.Subscribe;
@@ -217,6 +220,8 @@ public class ContactListFragment extends FileFragment {
             }
         });
 
+        restoreContacts.setTextColor(ThemeUtils.primaryAccentColor());
+
         return view;
     }
 
@@ -313,6 +318,7 @@ public class ContactListFragment extends FileFragment {
             badge = (ImageView) itemView.findViewById(R.id.contactlist_item_icon);
             name = (CheckedTextView) itemView.findViewById(R.id.contactlist_item_name);
 
+
             itemView.setTag(this);
         }
 
@@ -616,8 +622,17 @@ class ContactListAdapter extends RecyclerView.Adapter<ContactListFragment.Contac
 
             if (checkedVCards.contains(position)) {
                 holder.getName().setChecked(true);
+
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+                    holder.getName().getCheckMarkDrawable()
+                            .setColorFilter(ThemeUtils.primaryAccentColor(), PorterDuff.Mode.SRC_ATOP);
+                }
             } else {
                 holder.getName().setChecked(false);
+
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+                    holder.getName().getCheckMarkDrawable().clearColorFilter();
+                }
             }
 
             holder.getName().setText(getDisplayName(vcard));
@@ -651,6 +666,11 @@ class ContactListAdapter extends RecyclerView.Adapter<ContactListFragment.Contac
                     holder.getName().setChecked(!holder.getName().isChecked());
 
                     if (holder.getName().isChecked()) {
+                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+                            holder.getName().getCheckMarkDrawable()
+                                    .setColorFilter(ThemeUtils.primaryAccentColor(), PorterDuff.Mode.SRC_ATOP);
+                        }
+
                         if (!checkedVCards.contains(verifiedPosition)) {
                             checkedVCards.add(verifiedPosition);
                         }
@@ -658,6 +678,10 @@ class ContactListAdapter extends RecyclerView.Adapter<ContactListFragment.Contac
                             EventBus.getDefault().post(new VCardToggleEvent(true));
                         }
                     } else {
+                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+                            holder.getName().getCheckMarkDrawable().clearColorFilter();
+                        }
+
                         if (checkedVCards.contains(verifiedPosition)) {
                             checkedVCards.remove(verifiedPosition);
                         }

+ 19 - 1
src/main/java/com/owncloud/android/ui/fragment/contactsbackup/ContactsBackupFragment.java

@@ -24,6 +24,7 @@ import android.Manifest;
 import android.accounts.Account;
 import android.app.DatePickerDialog;
 import android.content.DialogInterface;
+import android.graphics.PorterDuff;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
@@ -54,6 +55,7 @@ import com.owncloud.android.ui.activity.ContactsPreferenceActivity;
 import com.owncloud.android.ui.fragment.FileFragment;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.PermissionUtil;
+import com.owncloud.android.utils.ThemeUtils;
 
 import java.util.Calendar;
 import java.util.Collections;
@@ -77,6 +79,9 @@ public class ContactsBackupFragment extends FileFragment implements DatePickerDi
     @BindView(R.id.contacts_header_restore)
     public TextView contactsRestoreHeader;
 
+    @BindView(R.id.contacts_header_backup)
+    public TextView contactsBackupHeader;
+
     @BindView(R.id.contacts_datepicker)
     public AppCompatButton contactsDatePickerBtn;
 
@@ -101,6 +106,10 @@ public class ContactsBackupFragment extends FileFragment implements DatePickerDi
     @Override
     public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
 
+        // use grey as fallback for elements where custom theming is not available
+        if (ThemeUtils.themingEnabled()) {
+            getContext().getTheme().applyStyle(R.style.FallbackThemingTheme, true);
+        }
         View view = inflater.inflate(R.layout.contacts_backup_fragment, null);
         ButterKnife.bind(this, view);
 
@@ -115,6 +124,7 @@ public class ContactsBackupFragment extends FileFragment implements DatePickerDi
 
         arbitraryDataProvider = new ArbitraryDataProvider(getContext().getContentResolver());
 
+        ThemeUtils.tintSwitch(backupSwitch, ThemeUtils.primaryAccentColor());
         backupSwitch.setChecked(arbitraryDataProvider.getBooleanValue(account, PREFERENCE_CONTACTS_AUTOMATIC_BACKUP));
 
         onCheckedChangeListener = new CompoundButton.OnCheckedChangeListener() {
@@ -151,6 +161,14 @@ public class ContactsBackupFragment extends FileFragment implements DatePickerDi
             calendarPickerOpen = true;
         }
 
+        int accentColor = ThemeUtils.primaryAccentColor();
+        contactsDatePickerBtn.getBackground().setColorFilter(accentColor, PorterDuff.Mode.SRC_ATOP);
+        view.findViewById(R.id.contacts_backup_now).getBackground()
+                .setColorFilter(accentColor, PorterDuff.Mode.SRC_ATOP);
+
+        contactsRestoreHeader.setTextColor(accentColor);
+        contactsBackupHeader.setTextColor(accentColor);
+
         return view;
     }
 
@@ -336,7 +354,7 @@ public class ContactsBackupFragment extends FileFragment implements DatePickerDi
                             }
                         });
 
-                DisplayUtils.colorSnackbar(contactsPreferenceActivity, snackbar);
+                ThemeUtils.colorSnackbar(contactsPreferenceActivity, snackbar);
 
                 snackbar.show();
 

+ 2 - 2
src/main/java/com/owncloud/android/ui/notifications/NotificationUtils.java

@@ -26,7 +26,7 @@ import android.os.HandlerThread;
 import android.os.Process;
 import android.support.v4.app.NotificationCompat;
 
-import com.owncloud.android.R;
+import com.owncloud.android.utils.ThemeUtils;
 
 import java.util.Random;
 
@@ -51,7 +51,7 @@ public class NotificationUtils {
      */
     public static NotificationCompat.Builder newNotificationBuilder(Context context) {
         return new NotificationCompat.Builder(context).
-            setColor(context.getResources().getColor(R.color.primary));
+                setColor(ThemeUtils.primaryColor());
     }
 
     @SuppressFBWarnings("DMI")

+ 2 - 2
src/main/java/com/owncloud/android/ui/preview/FileDownloadFragment.java

@@ -35,7 +35,7 @@ import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.fragment.FileFragment;
-import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.ThemeUtils;
 
 import java.lang.ref.WeakReference;
 
@@ -138,7 +138,7 @@ public class FileDownloadFragment extends FileFragment implements OnClickListene
         mView = inflater.inflate(R.layout.file_download_fragment, container, false);
         
         ProgressBar progressBar = (ProgressBar)mView.findViewById(R.id.progressBar);
-        DisplayUtils.colorPreLollipopHorizontalProgressBar(progressBar);
+        ThemeUtils.colorPreLollipopHorizontalProgressBar(progressBar);
         mProgressListener = new ProgressListener(progressBar);
 
         (mView.findViewById(R.id.cancelBtn)).setOnClickListener(this);

+ 2 - 6
src/main/java/com/owncloud/android/utils/BitmapUtils.java

@@ -56,12 +56,8 @@ public class BitmapUtils {
         final Options options = new Options();
         options.inScaled = true;
         options.inPurgeable = true;
-        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
-            options.inPreferQualityOverSpeed = false;
-        }
-        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
-            options.inMutable = false;
-        }
+        options.inPreferQualityOverSpeed = false;
+        options.inMutable = false;
 
         // make a false load of the bitmap to get its dimensions
         options.inJustDecodeBounds = true;

+ 11 - 113
src/main/java/com/owncloud/android/utils/DisplayUtils.java

@@ -1,4 +1,4 @@
-/**
+/*
  * Nextcloud Android client application
  *
  * @author Andy Scherzinger
@@ -31,22 +31,14 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.graphics.Color;
 import android.graphics.Point;
-import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.PictureDrawable;
 import android.net.Uri;
 import android.os.Build;
-import android.support.annotation.ColorInt;
-import android.support.annotation.ColorRes;
-import android.support.annotation.DrawableRes;
 import android.support.annotation.NonNull;
 import android.support.design.widget.BottomNavigationView;
-import android.support.design.widget.Snackbar;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.content.res.ResourcesCompat;
-import android.support.v4.graphics.drawable.DrawableCompat;
 import android.text.Spannable;
 import android.text.SpannableStringBuilder;
 import android.text.format.DateUtils;
@@ -54,9 +46,6 @@ import android.text.style.StyleSpan;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
-import android.widget.ImageButton;
-import android.widget.ProgressBar;
-import android.widget.SeekBar;
 
 import com.bumptech.glide.GenericRequestBuilder;
 import com.bumptech.glide.Glide;
@@ -76,7 +65,6 @@ import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.resources.files.SearchOperation;
 import com.owncloud.android.ui.TextDrawable;
 import com.owncloud.android.ui.activity.FileDisplayActivity;
-import com.owncloud.android.ui.activity.ToolbarActivity;
 import com.owncloud.android.ui.events.MenuItemClickEvent;
 import com.owncloud.android.ui.events.SearchEvent;
 import com.owncloud.android.ui.fragment.OCFileListFragment;
@@ -324,7 +312,12 @@ public class DisplayUtils {
      */
     public static int getRelativeInfoColor(Context context, int relative) {
         if (relative < RELATIVE_THRESHOLD_WARNING) {
-            return context.getResources().getColor(R.color.infolevel_info);
+            if (ThemeUtils.colorToHexString(ThemeUtils.primaryColor()).equalsIgnoreCase(
+                    ThemeUtils.colorToHexString(context.getResources().getColor(R.color.primary)))) {
+                return context.getResources().getColor(R.color.infolevel_info);
+            } else {
+                return Color.GRAY;
+            }
         } else if (relative >= RELATIVE_THRESHOLD_WARNING && relative < RELATIVE_THRESHOLD_CRITICAL) {
             return context.getResources().getColor(R.color.infolevel_warning);
         } else {
@@ -388,81 +381,6 @@ public class DisplayUtils {
         return size;
     }
 
-    /**
-     * sets the coloring of the given progress bar to color_accent.
-     *
-     * @param progressBar the progress bar to be colored
-     */
-    public static void colorPreLollipopHorizontalProgressBar(ProgressBar progressBar) {
-        if (progressBar != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
-            colorHorizontalProgressBar(progressBar, progressBar.getResources().getColor(R.color.color_accent));
-        }
-    }
-
-    /**
-     * sets the tinting of the given ImageButton's icon to color_accent.
-     *
-     * @param imageButton the image button who's icon should be colored
-     */
-    public static void colorImageButton(ImageButton imageButton, @ColorInt int color) {
-        if (imageButton != null) {
-            imageButton.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
-        }
-    }
-
-    /**
-     * sets the coloring of the given progress bar to color_accent.
-     *
-     * @param progressBar the progress bar to be colored
-     * @param color       the color to be used
-     */
-    public static void colorHorizontalProgressBar(ProgressBar progressBar, @ColorInt int color) {
-        if (progressBar != null) {
-            progressBar.getIndeterminateDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
-            progressBar.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
-        }
-    }
-
-    /**
-     * sets the coloring of the given seek bar to color_accent.
-     *
-     * @param seekBar the seek bar to be colored
-     */
-    public static void colorPreLollipopHorizontalSeekBar(SeekBar seekBar) {
-        if (seekBar != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
-            colorPreLollipopHorizontalProgressBar(seekBar);
-
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
-                int color = seekBar.getResources().getColor(R.color.color_accent);
-                seekBar.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);
-                seekBar.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);
-            }
-        }
-    }
-
-    /**
-     * set the Nextcloud standard colors for the snackbar.
-     *
-     * @param context  the context relevant for setting the color according to the context's theme
-     * @param snackbar the snackbar to be colored
-     */
-    public static void colorSnackbar(Context context, Snackbar snackbar) {
-        // Changing action button text color
-        snackbar.setActionTextColor(ContextCompat.getColor(context, R.color.white));
-    }
-
-    /**
-     * Sets the color of the status bar to {@code color} on devices with OS version lollipop or higher.
-     *
-     * @param fragmentActivity fragment activity
-     * @param color            the color
-     */
-    public static void colorStatusBar(FragmentActivity fragmentActivity, @ColorInt int color) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            fragmentActivity.getWindow().setStatusBarColor(color);
-        }
-    }
-
     /**
      * styling of given spanText within a given text.
      *
@@ -478,18 +396,6 @@ public class DisplayUtils {
         return sb;
     }
 
-    /**
-     * Sets the color of the progressbar to {@code color} within the given toolbar.
-     *
-     * @param activity         the toolbar activity instance
-     * @param progressBarColor the color to be used for the toolbar's progress bar
-     */
-    public static void colorToolbarProgressBar(FragmentActivity activity, int progressBarColor) {
-        if (activity instanceof ToolbarActivity) {
-            ((ToolbarActivity) activity).setProgressBarBackgroundColor(progressBarColor);
-        }
-    }
-
     public interface AvatarGenerationListener {
         void avatarGenerated(Drawable avatarDrawable, Object callContext);
 
@@ -674,27 +580,19 @@ public class DisplayUtils {
      *
      * @param inputStream        The File InputStream
      */
-    public static String getData(InputStream inputStream){
+    public static String getData(InputStream inputStream) {
 
         BufferedReader buffreader = new BufferedReader(new InputStreamReader(inputStream));
         String line;
         StringBuilder text = new StringBuilder();
         try {
-            while (( line = buffreader.readLine()) != null) {
+            while ((line = buffreader.readLine()) != null) {
                 text.append(line);
                 text.append('\n');
             }
         } catch (IOException e) {
-            Log_OC.e(TAG,e.getMessage());
+            Log_OC.e(TAG, e.getMessage());
         }
         return text.toString();
     }
-
-    public static Drawable tintDrawable(@DrawableRes int id, @ColorRes int color) {
-        Drawable drawable = ResourcesCompat.getDrawable(MainApp.getAppContext().getResources(), id, null);
-        drawable = DrawableCompat.wrap(drawable);
-        DrawableCompat.setTint(drawable, MainApp.getAppContext().getResources().getColor(color));
-        return drawable;
-    }
-
 }

+ 1 - 1
src/main/java/com/owncloud/android/utils/MimeTypeUtil.java

@@ -106,7 +106,7 @@ public class MimeTypeUtil {
             drawableId = R.drawable.ic_menu_archive;
         }
 
-        return DisplayUtils.tintDrawable(drawableId, R.color.primary);
+        return ThemeUtils.tintDrawable(drawableId, ThemeUtils.primaryColor());
     }
 
     public static Drawable getDefaultFolderIcon() {

+ 321 - 0
src/main/java/com/owncloud/android/utils/ThemeUtils.java

@@ -0,0 +1,321 @@
+/**
+ * ownCloud Android client application
+ *
+ * @author David A. Velasco
+ * Copyright (C) 2015 ownCloud Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.owncloud.android.utils;
+
+import android.accounts.Account;
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.support.annotation.ColorInt;
+import android.support.annotation.DrawableRes;
+import android.support.design.widget.Snackbar;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.content.ContextCompat;
+import android.support.v4.content.res.ResourcesCompat;
+import android.support.v4.graphics.ColorUtils;
+import android.support.v4.graphics.drawable.DrawableCompat;
+import android.support.v7.app.ActionBar;
+import android.support.v7.widget.AppCompatCheckBox;
+import android.support.v7.widget.SwitchCompat;
+import android.text.Html;
+import android.text.Spanned;
+import android.widget.ImageButton;
+import android.widget.ProgressBar;
+import android.widget.SeekBar;
+
+import com.owncloud.android.MainApp;
+import com.owncloud.android.R;
+import com.owncloud.android.authentication.AccountUtils;
+import com.owncloud.android.datamodel.FileDataStorageManager;
+import com.owncloud.android.lib.resources.status.OCCapability;
+import com.owncloud.android.ui.activity.ToolbarActivity;
+
+/**
+ * Utility class with methods for client side theming.
+ */
+public class ThemeUtils {
+
+    public static int primaryAccentColor() {
+        OCCapability capability = getCapability();
+
+        try {
+            float adjust;
+            if (darkTheme()){
+                adjust = +0.1f;
+            } else {
+                adjust = -0.1f;
+            }
+            return adjustLightness(adjust, Color.parseColor(capability.getServerColor()));
+        } catch (Exception e) {
+            return MainApp.getAppContext().getResources().getColor(R.color.color_accent);
+        }
+    }
+
+    public static int primaryDarkColor() {
+        OCCapability capability = getCapability();
+
+        try {
+            return adjustLightness(-0.2f, Color.parseColor(capability.getServerColor()));
+        } catch (Exception e) {
+            return MainApp.getAppContext().getResources().getColor(R.color.primary_dark);
+        }
+    }
+
+    public static int primaryColor() {
+        OCCapability capability = getCapability();
+
+        try {
+            return Color.parseColor(capability.getServerColor());
+        } catch (Exception e) {
+            return MainApp.getAppContext().getResources().getColor(R.color.primary);
+        }
+    }
+
+    public static boolean themingEnabled() {
+        return getCapability().getServerColor() != null && !getCapability().getServerColor().isEmpty();
+    }
+
+    /**
+     * @return int font color to use
+     * adapted from https://github.com/nextcloud/server/blob/master/apps/theming/lib/Util.php#L90-L102
+     */
+    public static int fontColor() {
+        if (darkTheme()) {
+            return Color.WHITE;
+        } else {
+            return Color.BLACK;
+        }
+    }
+
+    /**
+     * Tests if dark color is set
+     * @return true if dark theme -> e.g.use light font color, darker accent color
+     */
+    public static boolean darkTheme() {
+        int primaryColor = primaryColor();
+
+        int red = Color.red(primaryColor);
+        int green = Color.green(primaryColor);
+        int blue = Color.blue(primaryColor);
+
+        return ((0.299 * red + 0.587 * green + 0.114 * blue) / 255) <= 0.5;
+    }
+
+    /**
+     * Set color of title to white/black depending on background color
+     *
+     * @param actionBar actionBar to be used
+     * @param title     title to be shown
+     */
+    public static void setColoredTitle(ActionBar actionBar, String title) {
+        String colorHex = colorToHexString(fontColor());
+        actionBar.setTitle(Html.fromHtml("<font color='" + colorHex + "'>" + title + "</font>"));
+    }
+
+    public static Spanned getColoredTitle(String title, int color) {
+        String colorHex = colorToHexString(color);
+        return Html.fromHtml("<font color='" + colorHex + "'>" + title + "</font>");
+    }
+
+    /**
+     * Set color of title to white/black depending on background color
+     *
+     * @param actionBar actionBar to be used
+     * @param titleId   title to be shown
+     */
+    public static void setColoredTitle(ActionBar actionBar, int titleId, Context context) {
+        String colorHex = colorToHexString(fontColor());
+        String title = context.getString(titleId);
+        actionBar.setTitle(Html.fromHtml("<font color='" + colorHex + "'>" + title + "</font>"));
+    }
+
+    public static String getDefaultDisplayNameForRootFolder() {
+        OCCapability capability = getCapability();
+
+        if (capability.getServerSlogan() == null || capability.getServerSlogan().isEmpty()) {
+            return MainApp.getAppContext().getResources().getString(R.string.default_display_name_for_root_folder);
+        } else {
+            return capability.getServerSlogan();
+        }
+    }
+
+    public static int adjustLightness(float lightnessDelta, int color) {
+        float[] hsl = new float[3];
+        ColorUtils.RGBToHSL(Color.red(color), Color.green(color), Color.blue(color), hsl);
+
+        hsl[2] += lightnessDelta;
+
+        return ColorUtils.HSLToColor(hsl);
+    }
+
+    /**
+     * sets the coloring of the given progress bar to color_accent.
+     *
+     * @param progressBar the progress bar to be colored
+     */
+    public static void colorPreLollipopHorizontalProgressBar(ProgressBar progressBar) {
+        if (progressBar != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
+            colorHorizontalProgressBar(progressBar, ThemeUtils.primaryAccentColor());
+        }
+    }
+
+    /**
+     * sets the tinting of the given ImageButton's icon to color_accent.
+     *
+     * @param imageButton the image button who's icon should be colored
+     */
+    public static void colorImageButton(ImageButton imageButton, @ColorInt int color) {
+        if (imageButton != null) {
+            imageButton.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
+        }
+    }
+
+    /**
+     * sets the coloring of the given progress bar to color_accent.
+     *
+     * @param progressBar the progress bar to be colored
+     * @param color       the color to be used
+     */
+    public static void colorHorizontalProgressBar(ProgressBar progressBar, @ColorInt int color) {
+        if (progressBar != null) {
+            progressBar.getIndeterminateDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
+            progressBar.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
+        }
+    }
+
+    /**
+     * sets the coloring of the given seek bar to color_accent.
+     *
+     * @param seekBar the seek bar to be colored
+     */
+    public static void colorPreLollipopHorizontalSeekBar(SeekBar seekBar) {
+        if (seekBar != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
+            colorPreLollipopHorizontalProgressBar(seekBar);
+
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+                int color = ThemeUtils.primaryAccentColor();
+                seekBar.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);
+                seekBar.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);
+            }
+        }
+    }
+
+    /**
+     * set the Nextcloud standard colors for the snackbar.
+     *
+     * @param context  the context relevant for setting the color according to the context's theme
+     * @param snackbar the snackbar to be colored
+     */
+    public static void colorSnackbar(Context context, Snackbar snackbar) {
+        // Changing action button text color
+        snackbar.setActionTextColor(ContextCompat.getColor(context, R.color.white));
+    }
+
+    /**
+     * Sets the color of the status bar to {@code color} on devices with OS version lollipop or higher.
+     *
+     * @param fragmentActivity fragment activity
+     * @param color            the color
+     */
+    public static void colorStatusBar(FragmentActivity fragmentActivity, @ColorInt int color) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            fragmentActivity.getWindow().setStatusBarColor(color);
+        }
+    }
+
+    /**
+     * Sets the color of the progressbar to {@code color} within the given toolbar.
+     *
+     * @param activity         the toolbar activity instance
+     * @param progressBarColor the color to be used for the toolbar's progress bar
+     */
+    public static void colorToolbarProgressBar(FragmentActivity activity, int progressBarColor) {
+        if (activity instanceof ToolbarActivity) {
+            ((ToolbarActivity) activity).setProgressBarBackgroundColor(progressBarColor);
+        }
+    }
+
+    public static void tintCheckbox(AppCompatCheckBox checkBox, int color) {
+        checkBox.setSupportButtonTintList(new ColorStateList(
+                new int[][]{
+                        new int[]{-android.R.attr.state_checked},
+                        new int[]{android.R.attr.state_checked},
+                },
+                new int[]{
+                        Color.GRAY,
+                        color
+                }
+        ));
+    }
+
+    public static void tintSwitch(SwitchCompat switchView, int color) {
+        tintSwitch(switchView, color, false);
+    }
+
+    public static void tintSwitch(SwitchCompat switchView, int color, boolean colorText) {
+        if (colorText) {
+            switchView.setTextColor(color);
+        }
+
+        int trackColor = Color.argb(77, Color.red(color), Color.green(color), Color.blue(color));
+
+        // setting the thumb color
+        DrawableCompat.setTintList(switchView.getThumbDrawable(), new ColorStateList(
+                new int[][]{new int[]{android.R.attr.state_checked}, new int[]{}},
+                new int[]{color, Color.WHITE}));
+
+        // setting the track color
+        DrawableCompat.setTintList(switchView.getTrackDrawable(), new ColorStateList(
+                new int[][]{new int[]{android.R.attr.state_checked}, new int[]{}},
+                new int[]{trackColor, Color.parseColor("#4D000000")}));
+    }
+
+    public static Drawable tintDrawable(@DrawableRes int id, int color) {
+        Drawable drawable = ResourcesCompat.getDrawable(MainApp.getAppContext().getResources(), id, null);
+
+        return tintDrawable(drawable, color);
+    }
+
+    public static Drawable tintDrawable(Drawable drawable, int color) {
+        Drawable wrap = DrawableCompat.wrap(drawable);
+        wrap.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
+
+        return wrap;
+    }
+
+    public static String colorToHexString(int color) {
+        return String.format("#%06X", 0xFFFFFF & color);
+    }
+
+    private static OCCapability getCapability() {
+        Account account = AccountUtils.getCurrentOwnCloudAccount(MainApp.getAppContext());
+
+        if (account != null) {
+            Context context = MainApp.getAppContext();
+
+            FileDataStorageManager storageManager = new FileDataStorageManager(account, context.getContentResolver());
+            return storageManager.getCapability(account.name);
+        } else {
+            return new OCCapability();
+        }
+    }
+}

BIN
src/main/res/drawable-hdpi/ic_arrow_back.png


BIN
src/main/res/drawable-mdpi/ic_arrow_back.png


BIN
src/main/res/drawable-xhdpi/ic_arrow_back.png


BIN
src/main/res/drawable-xxhdpi/ic_arrow_back.png


BIN
src/main/res/drawable-xxxhdpi/ic_arrow_back.png


+ 1 - 2
src/main/res/layout/account_item.xml

@@ -51,8 +51,7 @@
             android:layout_height="wrap_content"
             android:layout_gravity="bottom|right"
             android:background="@drawable/round_bgnd"
-            android:src="@drawable/ic_account_circle_white_18dp"
-            android:tint="@color/primary"/>
+            android:src="@drawable/ic_account_circle_white_18dp"/>
     </FrameLayout>
 
     <LinearLayout

+ 1 - 0
src/main/res/layout/drawer_header.xml

@@ -19,6 +19,7 @@
   License along with this program. If not, see <http://www.gnu.org/licenses/>.
   -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:id="@+id/drawer_header_view"
               android:layout_width="match_parent"
               android:layout_height="@dimen/nav_drawer_header_height"
               android:background="@drawable/background"

+ 3 - 3
src/main/res/layout/edit_share_layout.xml

@@ -64,7 +64,7 @@
             style="?android:attr/listSeparatorTextViewStyle"
             />
 
-        <CheckBox
+        <android.support.v7.widget.AppCompatCheckBox
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:id="@+id/canEditCreateCheckBox"
@@ -72,7 +72,7 @@
             android:visibility="gone"
             />
 
-        <CheckBox
+        <android.support.v7.widget.AppCompatCheckBox
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:id="@+id/canEditChangeCheckBox"
@@ -80,7 +80,7 @@
             android:visibility="gone"
             />
 
-        <CheckBox
+        <android.support.v7.widget.AppCompatCheckBox
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:id="@+id/canEditDeleteCheckBox"

+ 0 - 3
src/main/res/layout/list_fragment.xml

@@ -88,9 +88,6 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentRight="true"
-        app:fab_addButtonColorNormal="@color/primary_button_background_color"
-        app:fab_addButtonColorPressed="@color/primary"
-        app:fab_addButtonPlusIconColor="@color/white"
         app:fab_labelStyle="@style/menu_labels_style"
         android:layout_marginBottom="@dimen/standard_margin"
         android:layout_marginRight="@dimen/standard_margin"

+ 4 - 4
src/main/res/values/strings.xml

@@ -565,10 +565,10 @@
     <string name="participate_release_candidate_headline">Release candidate</string>
     <string name="participate_release_candidate_text">The release candidate (RC) is a snapshot of the upcoming release and is expected to be stable. Testing your individual setup could help ensure this. Sign up for testing on the Play store or manually look in the \"versions\" section on F-Droid.</string>
     <string name="participate_contribute_headline">Actively Contribute</string>
-    <string name="participate_contribute_irc_text">Join the chat on IRC: &lt;a href=\"%1$s\">#nextcloud-mobile&lt;/a></string>
-    <string name="participate_contribute_forum_text">Help others on the &lt;a href=\"%1$s\">forum&lt;/a></string>
-    <string name="participate_contribute_translate_text">&lt;a href=\"%1$s\">Translate&lt;/a> the app</string>
-    <string name="participate_contribute_github_text">Review, amend and write code, see &lt;a href=\"%1$s\">CONTRIBUTING.md&lt;a> for details</string>
+    <string name="participate_contribute_irc_text">Join the chat on IRC: &lt;font color=\"%1$s\">&lt;a href=\"%2$s\">#nextcloud-mobile&lt;/a>&lt;/font></string>
+    <string name="participate_contribute_forum_text">Help others on the &lt;font color=\"%1$s\">&lt;a href=\"%2$s\">forum&lt;/a>&lt;/font></string>
+    <string name="participate_contribute_translate_text">&lt;font color=\"%1$s\">&lt;a href=\"%2$s\">Translate&lt;/a>&lt;/font> the app</string>
+    <string name="participate_contribute_github_text">Review, amend and write code, see &lt;font color=\"%1$s\">&lt;a href=\"%2$s\">CONTRIBUTING.md&lt;a>&lt;/font> for details</string>
     <string name="move_to">Move to&#8230;</string>
     <string name="copy_to">Copy to&#8230;</string>
     <string name="choose_remote_folder">Choose folder&#8230;</string>

+ 6 - 0
src/main/res/values/styles.xml

@@ -35,6 +35,12 @@
 		<item name="searchViewStyle">@style/ownCloud.SearchView</item>
 	</style>
 
+	<style name="FallbackThemingTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+		<item name="colorPrimary">#616161</item>
+		<item name="colorPrimaryDark">#424242</item>
+		<item name="colorAccent">#757575</item>
+	</style>
+
 	<!-- seperate action bar style for activities without an action bar -->
 	<style name="Theme.ownCloud.Toolbar" parent="Theme.AppCompat.Light.NoActionBar">
 		<item name="windowNoTitle">true</item>