diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index b963ceb39..746449f7e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -247,7 +247,7 @@ public class KeychainProvider extends ContentProvider { return matcher; } - private KeychainDatabase mApgDatabase; + private KeychainDatabase mKeychainDatabase; /** * {@inheritDoc} @@ -255,7 +255,7 @@ public class KeychainProvider extends ContentProvider { @Override public boolean onCreate() { mUriMatcher = buildUriMatcher(); - mApgDatabase = new KeychainDatabase(getContext()); + mKeychainDatabase = new KeychainDatabase(getContext()); return true; } @@ -486,7 +486,7 @@ public class KeychainProvider extends ContentProvider { Log.v(Constants.TAG, "query(uri=" + uri + ", proj=" + Arrays.toString(projection) + ")"); SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); - SQLiteDatabase db = mApgDatabase.getReadableDatabase(); + SQLiteDatabase db = mKeychainDatabase.getReadableDatabase(); int match = mUriMatcher.match(uri); @@ -715,7 +715,7 @@ public class KeychainProvider extends ContentProvider { public Uri insert(Uri uri, ContentValues values) { Log.d(Constants.TAG, "insert(uri=" + uri + ", values=" + values.toString() + ")"); - final SQLiteDatabase db = mApgDatabase.getWritableDatabase(); + final SQLiteDatabase db = mKeychainDatabase.getWritableDatabase(); Uri rowUri = null; long rowId = -1; @@ -792,7 +792,7 @@ public class KeychainProvider extends ContentProvider { public int delete(Uri uri, String selection, String[] selectionArgs) { Log.v(Constants.TAG, "delete(uri=" + uri + ")"); - final SQLiteDatabase db = mApgDatabase.getWritableDatabase(); + final SQLiteDatabase db = mKeychainDatabase.getWritableDatabase(); int count; final int match = mUriMatcher.match(uri); @@ -853,7 +853,7 @@ public class KeychainProvider extends ContentProvider { public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { Log.v(Constants.TAG, "update(uri=" + uri + ", values=" + values.toString() + ")"); - final SQLiteDatabase db = mApgDatabase.getWritableDatabase(); + final SQLiteDatabase db = mKeychainDatabase.getWritableDatabase(); String defaultSelection = null; int count = 0; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java index 837295018..52b06a2ae 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java @@ -25,13 +25,13 @@ import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; -import android.view.View.OnClickListener; import android.view.ViewGroup; -import android.view.animation.AlphaAnimation; -import android.view.animation.Animation; -import android.widget.*; +import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; -import com.beardedhen.androidbootstrap.BootstrapButton; +import android.widget.ImageView; +import android.widget.Spinner; +import android.widget.TextView; + import org.spongycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; @@ -50,8 +50,6 @@ public class AppSettingsFragment extends Fragment implements private AppSettings mAppSettings; // view - private LinearLayout mAdvancedSettingsContainer; - private BootstrapButton mAdvancedSettingsButton; private TextView mAppNameView; private ImageView mAppIconView; private Spinner mEncryptionAlgorithm; @@ -117,11 +115,6 @@ public class AppSettingsFragment extends Fragment implements R.id.api_app_settings_select_key_fragment); mSelectKeyFragment.setCallback(this); - mAdvancedSettingsButton = (BootstrapButton) view - .findViewById(R.id.api_app_settings_advanced_button); - mAdvancedSettingsContainer = (LinearLayout) view - .findViewById(R.id.api_app_settings_advanced); - mAppNameView = (TextView) view.findViewById(R.id.api_app_settings_app_name); mAppIconView = (ImageView) view.findViewById(R.id.api_app_settings_app_icon); mEncryptionAlgorithm = (Spinner) view @@ -176,35 +169,6 @@ public class AppSettingsFragment extends Fragment implements public void onNothingSelected(AdapterView parent) { } }); - - final Animation visibleAnimation = new AlphaAnimation(0.0f, 1.0f); - visibleAnimation.setDuration(250); - final Animation invisibleAnimation = new AlphaAnimation(1.0f, 0.0f); - invisibleAnimation.setDuration(250); - - // TODO: Better: collapse/expand animation - // final Animation animation2 = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, - // Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, -1.0f, - // Animation.RELATIVE_TO_SELF, 0.0f);u - // animation2.setDuration(150); - - mAdvancedSettingsButton.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - if (mAdvancedSettingsContainer.getVisibility() == View.VISIBLE) { - mAdvancedSettingsContainer.startAnimation(invisibleAnimation); - mAdvancedSettingsContainer.setVisibility(View.GONE); - mAdvancedSettingsButton.setText(getString(R.string.api_settings_show_advanced)); - mAdvancedSettingsButton.setLeftIcon("fa-caret-up"); - } else { - mAdvancedSettingsContainer.startAnimation(visibleAnimation); - mAdvancedSettingsContainer.setVisibility(View.VISIBLE); - mAdvancedSettingsButton.setText(getString(R.string.api_settings_hide_advanced)); - mAdvancedSettingsButton.setLeftIcon("fa-caret-down"); - } - } - }); } private void setPackage(String packageName) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java index 28c9c7b28..4ccfd393f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -108,11 +108,6 @@ public class EncryptActivity extends DrawerActivity { private String mInputFilename = null; private String mOutputFilename = null; - private Integer mShortAnimationDuration = null; - private boolean mFileAdvancedSettingsVisible = false; - private TextView mFileAdvancedSettings = null; - private LinearLayout mFileAdvancedSettingsContainer = null; - private FontAwesomeText mAdvancedSettingsIcon; private boolean mAsciiArmorDemand = false; private boolean mOverrideAsciiArmor = false; @@ -147,9 +142,6 @@ public class EncryptActivity extends DrawerActivity { updateMode(); updateActionBarButtons(); - - // retrieve and cache the system's short animation time - mShortAnimationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime); } /** @@ -795,49 +787,10 @@ public class EncryptActivity extends DrawerActivity { } }); - mAdvancedSettingsIcon = (FontAwesomeText) findViewById(R.id.advancedSettingsIcon); - mFileAdvancedSettingsContainer = (LinearLayout) findViewById(R.id.fileAdvancedSettingsContainer); - mFileAdvancedSettings = (TextView) findViewById(R.id.advancedSettings); - LinearLayout advancedSettingsControl = (LinearLayout) findViewById(R.id.advancedSettingsControl); - advancedSettingsControl.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - mFileAdvancedSettingsVisible = !mFileAdvancedSettingsVisible; - if (mFileAdvancedSettingsVisible) { - mAdvancedSettingsIcon.setIcon("fa-chevron-down"); - mFileAdvancedSettingsContainer.setVisibility(View.VISIBLE); - AlphaAnimation animation = new AlphaAnimation(0f, 1f); - animation.setDuration(mShortAnimationDuration); - mFileAdvancedSettingsContainer.startAnimation(animation); - mFileAdvancedSettings.setText(R.string.btn_encryption_advanced_settings_hide); - } else { - mAdvancedSettingsIcon.setIcon("fa-chevron-right"); - AlphaAnimation animation = new AlphaAnimation(1f, 0f); - animation.setDuration(mShortAnimationDuration); - animation.setAnimationListener(new Animation.AnimationListener() { - @Override - public void onAnimationStart(Animation animation) { - // do nothing - } - @Override - public void onAnimationEnd(Animation animation) { - // making sure that at the end the container is completely removed from view - mFileAdvancedSettingsContainer.setVisibility(View.GONE); - } - @Override - public void onAnimationRepeat(Animation animation) { - // do nothing - } - }); - mFileAdvancedSettingsContainer.startAnimation(animation); - mFileAdvancedSettings.setText(R.string.btn_encryption_advanced_settings_show); - } - } - }); mFileCompression = (Spinner) findViewById(R.id.fileCompression); Choice[] choices = new Choice[]{ diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java new file mode 100644 index 000000000..f9a5b92f3 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 . + */ + +package org.sufficientlysecure.keychain.ui.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.animation.AlphaAnimation; +import android.view.animation.Animation; +import android.widget.LinearLayout; +import android.widget.TextView; +import com.beardedhen.androidbootstrap.FontAwesomeText; +import org.sufficientlysecure.keychain.R; + +/** + * Class representing a LinearLayout that can fold and hide it's content when pressed + * To use just add the following to your xml layout + + + + + + + + */ +public class FoldableLinearLayout extends LinearLayout { + + private FontAwesomeText mFoldableIcon; + private boolean mFolded; + private boolean mHasMigrated = false; + private Integer mShortAnimationDuration = null; + private TextView mFoldableTextView = null; + private LinearLayout mFoldableContainer = null; + private View mFoldableLayout = null; + + private String mFoldedIconName; + private String mUnFoldedIconName; + private String mFoldedLabel; + private String mUnFoldedLabel; + + public FoldableLinearLayout(Context context) { + super(context); + processAttributes(context, null); + } + + public FoldableLinearLayout(Context context, AttributeSet attrs) { + super(context, attrs); + processAttributes(context, attrs); + } + + public FoldableLinearLayout(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs); + processAttributes(context, attrs); + } + + /** + * Load given attributes to inner variables, + * @param context + * @param attrs + */ + private void processAttributes(Context context, AttributeSet attrs) { + if(attrs != null) { + TypedArray a = context.obtainStyledAttributes(attrs, + R.styleable.FoldableLinearLayout, 0, 0); + mFoldedIconName = a.getString(R.styleable.FoldableLinearLayout_foldedIcon); + mUnFoldedIconName = a.getString(R.styleable.FoldableLinearLayout_unFoldedIcon); + mFoldedLabel = a.getString(R.styleable.FoldableLinearLayout_foldedLabel); + mUnFoldedLabel = a.getString(R.styleable.FoldableLinearLayout_unFoldedLabel); + a.recycle(); + } + // If any attribute isn't found then set a default one + mFoldedIconName = (mFoldedIconName == null) ? "fa-chevron-right" : mFoldedIconName; + mUnFoldedIconName = (mUnFoldedIconName == null) ? "fa-chevron-down" : mUnFoldedIconName; + mFoldedLabel = (mFoldedLabel == null) ? context.getString(R.id.none) : mFoldedLabel; + mUnFoldedLabel = (mUnFoldedLabel == null) ? context.getString(R.id.none) : mUnFoldedLabel; + } + + @Override + protected void onFinishInflate() { + // if the migration has already happened + // there is no need to move any children + if(!mHasMigrated) { + migrateChildrenToContainer(); + mHasMigrated = true; + } + + initialiseInnerViews(); + + super.onFinishInflate(); + } + + /** + * Migrates Child views as declared in xml to the inner foldableContainer + */ + private void migrateChildrenToContainer() { + // Collect children of FoldableLinearLayout as declared in XML + int childNum = getChildCount(); + View[] children = new View[childNum]; + + for(int i = 0; i < childNum; i++) { + children[i] = getChildAt(i); + } + if(children[0].getId() == R.id.foldableControl) { + + } + + // remove all of them from FoldableLinearLayout + detachAllViewsFromParent(); + + // Inflate the inner foldable_linearlayout.xml + LayoutInflater inflator = (LayoutInflater)getContext().getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + + mFoldableLayout = inflator.inflate(R.layout.foldable_linearlayout, this, true); + mFoldableContainer = (LinearLayout) mFoldableLayout.findViewById(R.id.foldableContainer); + + // Push previously collected children into foldableContainer. + for(int i = 0; i < childNum; i++) { + addView(children[i]); + } + } + + private void initialiseInnerViews() { + mFoldableIcon = (FontAwesomeText) mFoldableLayout.findViewById(R.id.foldableIcon); + mFoldableIcon.setIcon(mFoldedIconName); + mFoldableTextView = (TextView) mFoldableLayout.findViewById(R.id.foldableText); + mFoldableTextView.setText(mFoldedLabel); + + // retrieve and cache the system's short animation time + mShortAnimationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime); + + LinearLayout foldableControl = (LinearLayout) mFoldableLayout.findViewById(R.id.foldableControl); + foldableControl.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + mFolded = !mFolded; + if (mFolded) { + mFoldableIcon.setIcon(mUnFoldedIconName); + mFoldableContainer.setVisibility(View.VISIBLE); + AlphaAnimation animation = new AlphaAnimation(0f, 1f); + animation.setDuration(mShortAnimationDuration); + mFoldableContainer.startAnimation(animation); + mFoldableTextView.setText(mUnFoldedLabel); + + } else { + mFoldableIcon.setIcon(mFoldedIconName); + AlphaAnimation animation = new AlphaAnimation(1f, 0f); + animation.setDuration(mShortAnimationDuration); + animation.setAnimationListener(new Animation.AnimationListener() { + @Override + public void onAnimationStart(Animation animation) { } + + @Override + public void onAnimationEnd(Animation animation) { + // making sure that at the end the container is completely removed from view + mFoldableContainer.setVisibility(View.GONE); + } + + @Override + public void onAnimationRepeat(Animation animation) { } + }); + mFoldableContainer.startAnimation(animation); + mFoldableTextView.setText(mFoldedLabel); + } + } + }); + + } + + /** + * Adds provided child view to foldableContainer View + * @param child + */ + @Override + public void addView(View child) { + if(mFoldableContainer != null) { + mFoldableContainer.addView(child); + } + } +} diff --git a/OpenPGP-Keychain/src/main/res/layout/api_app_settings_fragment.xml b/OpenPGP-Keychain/src/main/res/layout/api_app_settings_fragment.xml index a8b68859b..a7917ad4e 100644 --- a/OpenPGP-Keychain/src/main/res/layout/api_app_settings_fragment.xml +++ b/OpenPGP-Keychain/src/main/res/layout/api_app_settings_fragment.xml @@ -2,6 +2,7 @@ @@ -42,24 +43,13 @@ android:layout_height="wrap_content" tools:layout="@layout/select_secret_key_layout_fragment" /> - - - + android:layout_height="match_parent" + custom:foldedLabel="@string/btn_encryption_advanced_settings_show" + custom:unFoldedLabel="@string/btn_encryption_advanced_settings_hide" + custom:foldedIcon="fa-chevron-right" + custom:unFoldedIcon="fa-chevron-down"> - + + + \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/encrypt_content.xml b/OpenPGP-Keychain/src/main/res/layout/encrypt_content.xml index bb947fb5a..03fe496c6 100644 --- a/OpenPGP-Keychain/src/main/res/layout/encrypt_content.xml +++ b/OpenPGP-Keychain/src/main/res/layout/encrypt_content.xml @@ -1,8 +1,9 @@ - + android:layout_height="match_parent" + custom:foldedLabel="@string/btn_encryption_advanced_settings_show" + custom:unFoldedLabel="@string/btn_encryption_advanced_settings_hide" + custom:foldedIcon="fa-chevron-right" + custom:unFoldedIcon="fa-chevron-down"> - + - - + - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/OpenPGP-Keychain/src/main/res/layout/encrypt_content_adv_settings.xml b/OpenPGP-Keychain/src/main/res/layout/encrypt_content_adv_settings.xml new file mode 100644 index 000000000..2281759d1 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/layout/encrypt_content_adv_settings.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/foldable_linearlayout.xml b/OpenPGP-Keychain/src/main/res/layout/foldable_linearlayout.xml new file mode 100644 index 000000000..2b863d52b --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/layout/foldable_linearlayout.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/values/attr.xml b/OpenPGP-Keychain/src/main/res/values/attr.xml new file mode 100644 index 000000000..86622b3e0 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/values/attr.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file