add edit long press action
This commit is contained in:
parent
2b01219e5c
commit
cacf739f6d
4 changed files with 101 additions and 3 deletions
|
@ -405,6 +405,14 @@ public class PasswordStore extends AppCompatActivity {
|
||||||
startActivityForResult(intent, PgpHandler.REQUEST_CODE_DECRYPT_AND_VERIFY);
|
startActivityForResult(intent, PgpHandler.REQUEST_CODE_DECRYPT_AND_VERIFY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void editPassword(PasswordItem item) {
|
||||||
|
Intent intent = new Intent(this, PgpHandler.class);
|
||||||
|
intent.putExtra("NAME", item.toString());
|
||||||
|
intent.putExtra("FILE_PATH", item.getFile().getAbsolutePath());
|
||||||
|
intent.putExtra("Operation", "EDIT");
|
||||||
|
startActivityForResult(intent, PgpHandler.REQUEST_CODE_EDIT);
|
||||||
|
}
|
||||||
|
|
||||||
public void createPassword() {
|
public void createPassword() {
|
||||||
if (!PasswordRepository.isInitialized()) {
|
if (!PasswordRepository.isInitialized()) {
|
||||||
new AlertDialog.Builder(this)
|
new AlertDialog.Builder(this)
|
||||||
|
|
|
@ -65,6 +65,7 @@ public class PgpHandler extends AppCompatActivity implements OpenPgpServiceConne
|
||||||
public static final int REQUEST_CODE_DECRYPT_AND_VERIFY = 9913;
|
public static final int REQUEST_CODE_DECRYPT_AND_VERIFY = 9913;
|
||||||
public static final int REQUEST_CODE_GET_KEY = 9914;
|
public static final int REQUEST_CODE_GET_KEY = 9914;
|
||||||
public static final int REQUEST_CODE_GET_KEY_IDS = 9915;
|
public static final int REQUEST_CODE_GET_KEY_IDS = 9915;
|
||||||
|
public static final int REQUEST_CODE_EDIT = 9916;
|
||||||
|
|
||||||
public final class Constants {
|
public final class Constants {
|
||||||
public static final String TAG = "Keychain";
|
public static final String TAG = "Keychain";
|
||||||
|
@ -146,7 +147,8 @@ public class PgpHandler extends AppCompatActivity implements OpenPgpServiceConne
|
||||||
|
|
||||||
public void editPassword() {
|
public void editPassword() {
|
||||||
|
|
||||||
// if in encrypt or (in decrypt and password is invisible), do nothing
|
// if in encrypt or in decrypt and password is invisible
|
||||||
|
// (because !showPassword, so this will instantly close), do nothing
|
||||||
if (findViewById(R.id.crypto_password_show) == null
|
if (findViewById(R.id.crypto_password_show) == null
|
||||||
|| findViewById(R.id.crypto_container).getVisibility() != View.VISIBLE)
|
|| findViewById(R.id.crypto_container).getVisibility() != View.VISIBLE)
|
||||||
return;
|
return;
|
||||||
|
@ -353,6 +355,10 @@ public class PgpHandler extends AppCompatActivity implements OpenPgpServiceConne
|
||||||
case REQUEST_CODE_GET_KEY_IDS:
|
case REQUEST_CODE_GET_KEY_IDS:
|
||||||
getKeyIds(data);
|
getKeyIds(data);
|
||||||
break;
|
break;
|
||||||
|
case REQUEST_CODE_EDIT: {
|
||||||
|
edit(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (resultCode == RESULT_CANCELED) {
|
} else if (resultCode == RESULT_CANCELED) {
|
||||||
setResult(RESULT_CANCELED, data);
|
setResult(RESULT_CANCELED, data);
|
||||||
|
@ -456,6 +462,39 @@ public class PgpHandler extends AppCompatActivity implements OpenPgpServiceConne
|
||||||
setResult(RESULT_OK);
|
setResult(RESULT_OK);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// edit
|
||||||
|
if (requestCode == REQUEST_CODE_EDIT && os != null) {
|
||||||
|
try {
|
||||||
|
if (returnToCiphertextField) {
|
||||||
|
findViewById(R.id.progress_bar).setVisibility(View.GONE);
|
||||||
|
findViewById(R.id.progress_bar_label).setVisibility(View.GONE);
|
||||||
|
|
||||||
|
findViewById(R.id.crypto_container).setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
Typeface monoTypeface = Typeface.createFromAsset(getAssets(), "fonts/sourcecodepro.ttf");
|
||||||
|
String[] passContent = os.toString("UTF-8").split("\n");
|
||||||
|
((TextView) findViewById(R.id.crypto_password_show))
|
||||||
|
.setTypeface(monoTypeface);
|
||||||
|
((TextView) findViewById(R.id.crypto_password_show))
|
||||||
|
.setText(passContent[0]);
|
||||||
|
|
||||||
|
String extraContent = os.toString("UTF-8").replaceFirst(".*\n", "");
|
||||||
|
if (extraContent.length() != 0) {
|
||||||
|
((TextView) findViewById(R.id.crypto_extra_show))
|
||||||
|
.setTypeface(monoTypeface);
|
||||||
|
((TextView) findViewById(R.id.crypto_extra_show))
|
||||||
|
.setText(extraContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
editPassword();
|
||||||
|
} else {
|
||||||
|
Log.d("PGPHANDLER", "Error message after decrypt : " + os.toString());
|
||||||
|
}
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
Log.e(Constants.TAG, "UnsupportedEncodingException", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: {
|
case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: {
|
||||||
|
@ -560,6 +599,24 @@ public class PgpHandler extends AppCompatActivity implements OpenPgpServiceConne
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void edit(Intent data) {
|
||||||
|
// exactly same as decrypt, only we want a different callback
|
||||||
|
data.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY);
|
||||||
|
|
||||||
|
findViewById(R.id.progress_bar).setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
try {
|
||||||
|
InputStream is = FileUtils.openInputStream(new File(getIntent().getExtras().getString("FILE_PATH")));
|
||||||
|
|
||||||
|
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
OpenPgpApi api = new OpenPgpApi(this, mServiceConnection.getService());
|
||||||
|
api.executeApiAsync(data, is, os, new PgpCallback(true, os, REQUEST_CODE_EDIT));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO (low priority but still...) android M potential permissions crashes
|
// TODO (low priority but still...) android M potential permissions crashes
|
||||||
@Override
|
@Override
|
||||||
public void onBound(IOpenPgpService2 service) {
|
public void onBound(IOpenPgpService2 service) {
|
||||||
|
@ -591,6 +648,14 @@ public class PgpHandler extends AppCompatActivity implements OpenPgpServiceConne
|
||||||
// String keys = keyIDs.split(",").length > 1 ? keyIDs : keyIDs.split(",")[0];
|
// String keys = keyIDs.split(",").length > 1 ? keyIDs : keyIDs.split(",")[0];
|
||||||
// ((TextView) findViewById(R.id.crypto_key_ids)).setText(keys);
|
// ((TextView) findViewById(R.id.crypto_key_ids)).setText(keys);
|
||||||
// }
|
// }
|
||||||
|
} else if (extra.getString("Operation").equals("EDIT")) {
|
||||||
|
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 + "/");
|
||||||
|
edit(new Intent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl
|
||||||
private final PasswordFragment.OnFragmentInteractionListener listener;
|
private final PasswordFragment.OnFragmentInteractionListener listener;
|
||||||
private final Set<Integer> selectedItems;
|
private final Set<Integer> selectedItems;
|
||||||
private ActionMode mActionMode;
|
private ActionMode mActionMode;
|
||||||
|
private Boolean canEdit;
|
||||||
|
|
||||||
// Provide a reference to the views for each data item
|
// Provide a reference to the views for each data item
|
||||||
// Complex data items may need more than one view per item, and
|
// Complex data items may need more than one view per item, and
|
||||||
|
@ -85,6 +86,14 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl
|
||||||
toggleSelection(holder.getAdapterPosition(), holder.card, pass.getType());
|
toggleSelection(holder.getAdapterPosition(), holder.card, pass.getType());
|
||||||
if (selectedItems.isEmpty()) {
|
if (selectedItems.isEmpty()) {
|
||||||
mActionMode.finish();
|
mActionMode.finish();
|
||||||
|
} else if (selectedItems.size() == 1 && !canEdit) {
|
||||||
|
if (values.get(selectedItems.iterator().next()).getType() == PasswordItem.TYPE_PASSWORD) {
|
||||||
|
canEdit = true;
|
||||||
|
mActionMode.invalidate();
|
||||||
|
}
|
||||||
|
} else if (selectedItems.size() >= 1 && canEdit) {
|
||||||
|
canEdit = false;
|
||||||
|
mActionMode.invalidate();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
listener.onFragmentInteraction(pass);
|
listener.onFragmentInteraction(pass);
|
||||||
|
@ -99,8 +108,10 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
toggleSelection(holder.getAdapterPosition(), holder.card, pass.getType());
|
toggleSelection(holder.getAdapterPosition(), holder.card, pass.getType());
|
||||||
|
canEdit = pass.getType() == PasswordItem.TYPE_PASSWORD;
|
||||||
// Start the CAB using the ActionMode.Callback
|
// Start the CAB using the ActionMode.Callback
|
||||||
mActionMode = activity.startSupportActionMode(mActionModeCallback);
|
mActionMode = activity.startSupportActionMode(mActionModeCallback);
|
||||||
|
mActionMode.invalidate();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -123,7 +134,12 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl
|
||||||
// may be called multiple times if the mode is invalidated.
|
// may be called multiple times if the mode is invalidated.
|
||||||
@Override
|
@Override
|
||||||
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
||||||
return false; // Return false if nothing is done
|
if (canEdit) {
|
||||||
|
menu.findItem(R.id.menu_edit_password).setVisible(true);
|
||||||
|
} else {
|
||||||
|
menu.findItem(R.id.menu_edit_password).setVisible(false);
|
||||||
|
}
|
||||||
|
return true; // Return false if nothing is done
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when the user selects a contextual menu item
|
// Called when the user selects a contextual menu item
|
||||||
|
@ -134,6 +150,10 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl
|
||||||
activity.deletePasswords(PasswordRecyclerAdapter.this, new TreeSet<>(selectedItems));
|
activity.deletePasswords(PasswordRecyclerAdapter.this, new TreeSet<>(selectedItems));
|
||||||
mode.finish(); // Action picked, so close the CAB
|
mode.finish(); // Action picked, so close the CAB
|
||||||
return true;
|
return true;
|
||||||
|
case R.id.menu_edit_password:
|
||||||
|
activity.editPassword(values.get(selectedItems.iterator().next()));
|
||||||
|
mode.finish();
|
||||||
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,12 @@
|
||||||
|
|
||||||
<item android:id="@+id/menu_delete_password"
|
<item android:id="@+id/menu_delete_password"
|
||||||
android:icon="@drawable/ic_action_discard"
|
android:icon="@drawable/ic_action_discard"
|
||||||
app:showAsAction="always"
|
app:showAsAction="ifRoom"
|
||||||
android:title="Delete"/>
|
android:title="Delete"/>
|
||||||
|
|
||||||
|
<item android:id="@+id/menu_edit_password"
|
||||||
|
android:icon="@drawable/ic_action_edit"
|
||||||
|
app:showAsAction="ifRoom"
|
||||||
|
android:title="Edit"/>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue