diff --git a/app/build.gradle b/app/build.gradle
index d453f775..7cfaf3de 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -18,10 +18,16 @@ android {
}
}
}
+repositories {
+ maven { url 'http://clinker.47deg.com/nexus/content/groups/public' }
+}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':libraries:openpgp-api-lib')
compile 'org.eclipse.jgit:org.eclipse.jgit:3.4.+'
compile 'org.apache.commons:commons-io:1.3.2'
+ compile ('com.fortysevendeg.swipelistview:swipelistview:1.0-SNAPSHOT@aar') {
+ transitive = true
+ }
}
diff --git a/app/src/main/java/com/zeapo/pwdstore/PasswordFragment.java b/app/src/main/java/com/zeapo/pwdstore/PasswordFragment.java
index db214cc5..d9346892 100644
--- a/app/src/main/java/com/zeapo/pwdstore/PasswordFragment.java
+++ b/app/src/main/java/com/zeapo/pwdstore/PasswordFragment.java
@@ -1,20 +1,27 @@
package com.zeapo.pwdstore;
import android.app.Activity;
+import android.content.Context;
import android.os.Bundle;
import android.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.ScaleAnimation;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
+import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
+import com.fortysevendeg.swipelistview.BaseSwipeListViewListener;
+import com.fortysevendeg.swipelistview.SwipeListView;
+import com.fortysevendeg.swipelistview.SwipeListViewListener;
import com.zeapo.pwdstore.utils.PasswordAdapter;
import com.zeapo.pwdstore.utils.PasswordItem;
import com.zeapo.pwdstore.utils.PasswordRepository;
@@ -29,14 +36,14 @@ import java.util.List;
* with a GridView.
*
*/
-public class PasswordFragment extends Fragment implements ExpandableListView.OnGroupClickListener {
+public class PasswordFragment extends Fragment implements SwipeListViewListener {
private OnFragmentInteractionListener mListener;
/**
* The fragment's ListView/GridView.
*/
- private ExpandableListView mListView;
+ private SwipeListView mListView;
/**
* The Adapter which will be used to populate the ListView/GridView with
@@ -64,11 +71,11 @@ public class PasswordFragment extends Fragment implements ExpandableListView.OnG
View view = inflater.inflate(R.layout.fragment_password, container, false);
// Set the adapter
- mListView = (ExpandableListView) view.findViewById(R.id.pass_list);
- mListView.setAdapter((android.widget.ExpandableListAdapter) mAdapter);
-
+ mListView = (SwipeListView) view.findViewById(R.id.pass_list);
+ ((AdapterView) mListView).setAdapter(mAdapter);
// Set OnItemClickListener so we can be notified on item clicks
- mListView.setOnGroupClickListener(this);
+// mListView.setOnItemClickListener(this);
+ mListView.setSwipeListViewListener(this);
mListView.setSelectionFromTop(getArguments().getInt("Position"), 0);
return view;
@@ -98,23 +105,105 @@ public class PasswordFragment extends Fragment implements ExpandableListView.OnG
}
- @Override
- public boolean onGroupClick(ExpandableListView expandableListView, View view, int i, long l) {
- if( ((PasswordItem) mAdapter.getGroup(i)).getType() == PasswordItem.TYPE_CATEGORY ){
- if (null != mListener) {
- // Notify the active callbacks interface (the activity, if the
- // fragment is attached to one) that an item has been selected.
- mListener.onFragmentInteraction(mAdapter.getItem(i));
- }
- } else {
- if (expandableListView.isGroupExpanded(i)) {
- expandableListView.collapseGroup(i);
- } else {
- expandableListView.expandGroup(i);
- }
+// @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ PasswordItem item = mAdapter.getItem(position);
+ if (item.getType() == PasswordItem.TYPE_PASSWORD) {
+// if (item.selected) {
+// item.selected = false;
+// } else {
+// View right = view.findViewById(R.id.row_buttons);
+// ScaleAnimation animation = new ScaleAnimation(view.getX(), 0, view.getY(), 0, Animation.RELATIVE_TO_SELF, (float)0.5, Animation.RELATIVE_TO_SELF, (float)0.5);
+// right.setAnimation(animation);
+// item.selected = true;
+// }
+ } else if (null != mListener) {
+ // Notify the active callbacks interface (the activity, if the
+ // fragment is attached to one) that an item has been selected.
+ mListener.onFragmentInteraction(mAdapter.getItem(position));
}
- return true;
+ }
+
+ @Override
+ public void onOpened(int i, boolean b) {
+
+ }
+
+ @Override
+ public void onClosed(int i, boolean b) {
+
+ }
+
+ @Override
+ public void onListChanged() {
+
+ }
+
+ @Override
+ public void onMove(int i, float v) {
+
+ }
+
+ @Override
+ public void onStartOpen(int i, int i2, boolean b) {
+
+ }
+
+ @Override
+ public void onStartClose(int i, boolean b) {
+
+ }
+
+ @Override
+ public void onClickFrontView(int i) {
+ if (mAdapter.getItem(i).getType() == PasswordItem.TYPE_PASSWORD) {
+ mListView.openAnimate(i);
+ } else if (null != mListener) {
+ // Notify the active callbacks interface (the activity, if the
+ // fragment is attached to one) that an item has been selected.
+ mListener.onFragmentInteraction(mAdapter.getItem(i));
+ }
+ }
+
+ @Override
+ public void onClickBackView(int i) {
+ mListView.closeAnimate(i);
+ }
+
+ @Override
+ public void onDismiss(int[] ints) {
+
+ }
+
+ @Override
+ public int onChangeSwipeMode(int i) {
+ return 0;
+ }
+
+ @Override
+ public void onChoiceChanged(int i, boolean b) {
+
+ }
+
+ @Override
+ public void onChoiceStarted() {
+
+ }
+
+ @Override
+ public void onChoiceEnded() {
+
+ }
+
+ @Override
+ public void onFirstListItem() {
+
+ }
+
+ @Override
+ public void onLastListItem() {
+
}
public interface OnFragmentInteractionListener {
@@ -125,7 +214,7 @@ public class PasswordFragment extends Fragment implements ExpandableListView.OnG
public void updateAdapter() {
mAdapter.clear();
mAdapter.addAll(PasswordRepository.getPasswords(new File(getArguments().getString("Path"))));
- mListView.setAdapter((ExpandableListAdapter) mAdapter);
+ mListView.setAdapter((ListAdapter) mAdapter);
}
}
diff --git a/app/src/main/java/com/zeapo/pwdstore/PasswordStore.java b/app/src/main/java/com/zeapo/pwdstore/PasswordStore.java
index 62475867..dff6721d 100644
--- a/app/src/main/java/com/zeapo/pwdstore/PasswordStore.java
+++ b/app/src/main/java/com/zeapo/pwdstore/PasswordStore.java
@@ -249,14 +249,6 @@ public class PasswordStore extends Activity implements ToCloneOrNot.OnFragmentI
public void onFragmentInteraction(PasswordItem item) {
if (item.getType() == PasswordItem.TYPE_CATEGORY) {
checkLocalRepository(item.getFile());
- } else {
- try {
-
-
- } catch (Exception e) {
-// TODO handle problems
- e.printStackTrace();
- }
}
}
public void decryptPassword(PasswordItem item) {
diff --git a/app/src/main/java/com/zeapo/pwdstore/crypto/PgpHandler.java b/app/src/main/java/com/zeapo/pwdstore/crypto/PgpHandler.java
index 68c71c4b..423b513d 100644
--- a/app/src/main/java/com/zeapo/pwdstore/crypto/PgpHandler.java
+++ b/app/src/main/java/com/zeapo/pwdstore/crypto/PgpHandler.java
@@ -34,6 +34,7 @@ import com.zeapo.pwdstore.utils.PasswordRepository;
import org.apache.commons.io.FileUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.util.StringUtils;
+import org.openintents.openpgp.IOpenPgpService;
import org.openintents.openpgp.OpenPgpError;
import org.openintents.openpgp.OpenPgpSignatureResult;
import org.openintents.openpgp.util.OpenPgpApi;
@@ -48,7 +49,7 @@ import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
-public class PgpHandler extends Activity {
+public class PgpHandler extends Activity implements OpenPgpServiceConnection.OnBound{
private OpenPgpServiceConnection mServiceConnection;
@@ -57,6 +58,8 @@ public class PgpHandler extends Activity {
SharedPreferences settings;
private Activity activity;
+ private ProgressDialog bindingDialog;
+
public static final int REQUEST_CODE_SIGN = 9910;
public static final int REQUEST_CODE_ENCRYPT = 9911;
public static final int REQUEST_CODE_SIGN_AND_ENCRYPT = 9912;
@@ -74,7 +77,7 @@ public class PgpHandler extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- activity = this;
+ this.activity = this;
// some persistance
settings = PreferenceManager.getDefaultSharedPreferences(this);
@@ -91,31 +94,13 @@ public class PgpHandler extends Activity {
// bind to service
mServiceConnection = new OpenPgpServiceConnection(
- PgpHandler.this, providerPackageName);
+ PgpHandler.this, providerPackageName, this );
mServiceConnection.bindToService();
-
- Bundle extra = getIntent().getExtras();
- if (extra.getString("Operation").equals("DECRYPT")) {
- setContentView(R.layout.decrypt_layout);
- ((TextView) findViewById(R.id.crypto_password_file)).setText(extra.getString("NAME"));
- String cat = new File(extra.getString("FILE_PATH").replace(PasswordRepository.getWorkTree().getAbsolutePath(), ""))
- .getParentFile().getName();
-
- ((TextView) findViewById(R.id.crypto_password_category)).setText(cat + "/");
- } else if (extra.getString("Operation").equals("ENCRYPT")) {
- setContentView(R.layout.encrypt_layout);
- String cat = extra.getString("FILE_PATH");
- cat = cat.replace(PasswordRepository.getWorkTree().getAbsolutePath(), "");
- cat = cat + "/";
- ((TextView) findViewById(R.id.crypto_password_category)).setText(cat);
- } else if (extra.getString("Operation").equals("GET_KEY_ID")) {
- setContentView(R.layout.key_id);
- if (!keyIDs.isEmpty()) {
- String keys = keyIDs.split(",").length > 1 ? keyIDs : keyIDs.split(",")[0];
- ((TextView) findViewById(R.id.crypto_key_ids)).setText(keys);
- }
- }
+ bindingDialog = new ProgressDialog(this);
+ bindingDialog.setMessage("Waiting for OpenKeychain...");
+ bindingDialog.setCancelable(false);
+ bindingDialog.show();
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
@@ -176,7 +161,6 @@ public class PgpHandler extends Activity {
Toast.LENGTH_LONG).show();
Log.e(Constants.TAG, "onError getErrorId:" + error.getErrorId());
Log.e(Constants.TAG, "onError getMessage:" + error.getMessage());
- Log.e(Constants.TAG, " " + error.toString());
}
});
}
@@ -279,6 +263,8 @@ public class PgpHandler extends Activity {
@Override
public void onReturn(Intent result) {
+ bindingDialog.dismiss();
+
switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) {
case OpenPgpApi.RESULT_CODE_SUCCESS: {
showToast("SUCCESS");
@@ -366,6 +352,7 @@ public class PgpHandler extends Activity {
handleError(error);
break;
}
+
}
}
}
@@ -462,5 +449,32 @@ public class PgpHandler extends Activity {
}
+ @Override
+ public void onBound(IOpenPgpService service) {
+ Log.i("PGP", "ISBOUND!!");
+
+ Bundle extra = getIntent().getExtras();
+ if (extra.getString("Operation").equals("DECRYPT")) {
+ setContentView(R.layout.decrypt_layout);
+ ((TextView) findViewById(R.id.crypto_password_file)).setText(extra.getString("NAME"));
+ String cat = new File(extra.getString("FILE_PATH").replace(PasswordRepository.getWorkTree().getAbsolutePath(), ""))
+ .getParentFile().getName();
+
+ ((TextView) findViewById(R.id.crypto_password_category)).setText(cat + "/");
+ decryptAndVerify(new Intent());
+ } else if (extra.getString("Operation").equals("ENCRYPT")) {
+ setContentView(R.layout.encrypt_layout);
+ String cat = extra.getString("FILE_PATH");
+ cat = cat.replace(PasswordRepository.getWorkTree().getAbsolutePath(), "");
+ cat = cat + "/";
+ ((TextView) findViewById(R.id.crypto_password_category)).setText(cat);
+ } else if (extra.getString("Operation").equals("GET_KEY_ID")) {
+ setContentView(R.layout.key_id);
+ if (!keyIDs.isEmpty()) {
+ String keys = keyIDs.split(",").length > 1 ? keyIDs : keyIDs.split(",")[0];
+ ((TextView) findViewById(R.id.crypto_key_ids)).setText(keys);
+ }
+ }
+ }
}
diff --git a/app/src/main/java/com/zeapo/pwdstore/utils/PasswordAdapter.java b/app/src/main/java/com/zeapo/pwdstore/utils/PasswordAdapter.java
index fbc7d817..2aaa0bf5 100644
--- a/app/src/main/java/com/zeapo/pwdstore/utils/PasswordAdapter.java
+++ b/app/src/main/java/com/zeapo/pwdstore/utils/PasswordAdapter.java
@@ -9,9 +9,11 @@ import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ExpandableListAdapter;
+import android.widget.GridLayout;
import android.widget.ImageButton;
import android.widget.TextView;
@@ -23,13 +25,14 @@ import org.apache.commons.io.FileUtils;
import java.util.ArrayList;
-public class PasswordAdapter extends ArrayAdapter implements ExpandableListAdapter{
+public class PasswordAdapter extends ArrayAdapter{
private final PasswordStore activity;
private final ArrayList values;
static class ViewHolder {
public TextView name;
public TextView type;
+ public TextView back_name;
}
public PasswordAdapter(PasswordStore activity, ArrayList values) {
@@ -38,74 +41,47 @@ public class PasswordAdapter extends ArrayAdapter implements Exp
this.activity = activity;
}
- @Override
- public void registerDataSetObserver(DataSetObserver dataSetObserver) {
-
- }
@Override
- public void unregisterDataSetObserver(DataSetObserver dataSetObserver) {
-
- }
-
- @Override
- public int getGroupCount() {
- return values.size();
- }
-
- @Override
- public int getChildrenCount(int i) {
- if (values.get(i).getType() == PasswordItem.TYPE_CATEGORY)
- return 0;
- else
- return 1;
- }
-
- @Override
- public Object getGroup(int i) {
- return values.get(i);
- }
-
- @Override
- public Object getChild(int i, int i2) {
- return null;
- }
-
- @Override
- public long getGroupId(int i) {
- return 0;
- }
-
- @Override
- public long getChildId(int i, int i2) {
- return 0;
- }
-
- @Override
- public boolean hasStableIds() {
- return false;
- }
-
- @Override
- public View getGroupView(int i, boolean b, View convertView, ViewGroup viewGroup) {
+ public View getView(int i, View convertView, ViewGroup viewGroup) {
View rowView = convertView;
- PasswordItem pass = values.get(i);
+ final PasswordItem pass = values.get(i);
// reuse for performance, holder pattern!
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- rowView = inflater.inflate(R.layout.password_row_layout, null);
+ rowView = inflater.inflate(R.layout.password_row_layout, viewGroup, false);
ViewHolder viewHolder = new ViewHolder();
viewHolder.name = (TextView) rowView.findViewById(R.id.label);
+ viewHolder.back_name = (TextView) rowView.findViewById(R.id.label_back);
viewHolder.type = (TextView) rowView.findViewById(R.id.type);
rowView.setTag(viewHolder);
+
+
+ View.OnClickListener onClickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ switch (view.getId()) {
+ case R.id.crypto_show_button:
+ activity.decryptPassword(pass);
+ break;
+ case R.id.crypto_delete_button:
+ activity.deletePassword(pass);
+ break;
+ }
+ }
+ };
+
+ ((ImageButton) rowView.findViewById(R.id.crypto_show_button)).setOnClickListener(onClickListener);
+ ((ImageButton) rowView.findViewById(R.id.crypto_delete_button)).setOnClickListener(onClickListener);
}
ViewHolder holder = (ViewHolder) rowView.getTag();
holder.name.setText(pass.toString());
+ holder.back_name.setText(pass.toString());
if (pass.getType() == PasswordItem.TYPE_CATEGORY) {
holder.name.setTextColor(this.activity.getResources().getColor(android.R.color.holo_blue_dark));
@@ -115,71 +91,11 @@ public class PasswordAdapter extends ArrayAdapter implements Exp
holder.type.setText("Password: ");
holder.name.setTextColor(this.activity.getResources().getColor(android.R.color.holo_orange_dark));
holder.name.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
+
+ holder.back_name.setTextColor(this.activity.getResources().getColor(android.R.color.white));
+ holder.back_name.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD_ITALIC));
}
return rowView;
}
-
- @Override
- public View getChildView(int i, int i2, boolean b, View view, ViewGroup viewGroup) {
- final PasswordItem pass = values.get(i);
-
- LayoutInflater inflater = (LayoutInflater) this.activity
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- view = inflater.inflate(R.layout.child_row_layout, null);
-
- View.OnClickListener onClickListener = new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- switch (view.getId()) {
- case R.id.crypto_show_button:
- activity.decryptPassword(pass);
- break;
- case R.id.crypto_delete_button:
- activity.deletePassword(pass);
- break;
- }
- }
- };
-
- ((ImageButton) view.findViewById(R.id.crypto_show_button)).setOnClickListener(onClickListener);
- ((ImageButton) view.findViewById(R.id.crypto_delete_button)).setOnClickListener(onClickListener);
-
- return view;
- }
-
- @Override
- public boolean isChildSelectable(int i, int i2) {
- return false;
- }
-
- @Override
- public boolean areAllItemsEnabled() {
- return false;
- }
-
- @Override
- public boolean isEmpty() {
- return false;
- }
-
- @Override
- public void onGroupExpanded(int i) {
-
- }
-
- @Override
- public void onGroupCollapsed(int i) {
-
- }
-
- @Override
- public long getCombinedChildId(long l, long l2) {
- return 0;
- }
-
- @Override
- public long getCombinedGroupId(long l) {
- return 0;
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/zeapo/pwdstore/utils/PasswordItem.java b/app/src/main/java/com/zeapo/pwdstore/utils/PasswordItem.java
index 4403d16b..75d0838c 100644
--- a/app/src/main/java/com/zeapo/pwdstore/utils/PasswordItem.java
+++ b/app/src/main/java/com/zeapo/pwdstore/utils/PasswordItem.java
@@ -11,6 +11,7 @@ public class PasswordItem implements Comparable{
private String name;
private PasswordItem parent;
private File file;
+ public boolean selected = false;
/** Create a password item
*
diff --git a/app/src/main/res/drawable-xxhdpi/gray_rectangle.xml b/app/src/main/res/drawable-xxhdpi/gray_rectangle.xml
new file mode 100644
index 00000000..b1858c80
--- /dev/null
+++ b/app/src/main/res/drawable-xxhdpi/gray_rectangle.xml
@@ -0,0 +1,24 @@
+
+
+
+ -
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/child_row_layout.xml b/app/src/main/res/layout/child_row_layout.xml
index 0fc5e33d..75efefad 100644
--- a/app/src/main/res/layout/child_row_layout.xml
+++ b/app/src/main/res/layout/child_row_layout.xml
@@ -2,7 +2,9 @@
+ android:layout_height="match_parent"
+ android:id="@+id/child_row_layout"
+ android:layout_marginTop="@dimen/activity_vertical_margin">
-
+ android:background="@drawable/rectangle"
+ android:orientation="vertical">
+ android:layout_marginLeft="@dimen/activity_horizontal_margin"/>
-
-
-
-
-
-
-
+ android:layout_marginLeft="@dimen/activity_horizontal_margin"/>
+
-
-
+ swipe:swipeFrontView="@+id/front"
+ swipe:swipeBackView="@+id/back"
+ swipe:swipeActionLeft="reveal"
+ swipe:swipeActionRight="reveal"
+ swipe:swipeMode="both"
+ swipe:swipeCloseAllItemsWhenMoveList="true"
+ swipe:swipeOpenOnLongPress="true"
+ swipe:swipeAnimationTime="200"
+ android:listSelector="#00000000"/>
+
diff --git a/app/src/main/res/layout/password_row_layout.xml b/app/src/main/res/layout/password_row_layout.xml
index f8d656fd..641f4f85 100644
--- a/app/src/main/res/layout/password_row_layout.xml
+++ b/app/src/main/res/layout/password_row_layout.xml
@@ -1,25 +1,71 @@
-
-
+
+
+
-
-
+ android:tag="back"
+ android:background="@drawable/gray_rectangle"
+ android:layout_gravity="left|center_vertical">
+
+
+
+
+
+
+
+
+
+
+
+
+
+