Solve search list and add edit for contextmenu in code

This commit is contained in:
J-Jamet
2018-02-14 20:21:44 +01:00
parent e574fba0a5
commit e5467bc54b
7 changed files with 173 additions and 78 deletions

View File

@@ -83,7 +83,7 @@ public abstract class EntryEditActivity extends LockCloseHideActivity
protected int mSelectedIconID = -1;
/**
* Launch EntryEditActivity to update an existing entry
* launch EntryEditActivity to update an existing entry
* @param act from activity
* @param pw Entry to update
*/
@@ -105,7 +105,7 @@ public abstract class EntryEditActivity extends LockCloseHideActivity
}
/**
* Launch EntryEditActivity to add a new entry
* launch EntryEditActivity to add a new entry
* @param act from activity
* @param pw Group who will contains new entry
*/
@@ -172,7 +172,7 @@ public abstract class EntryEditActivity extends LockCloseHideActivity
View iconButton = findViewById(R.id.icon_button);
iconButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
IconPickerDialogFragment.Launch(EntryEditActivity.this);
IconPickerDialogFragment.launch(EntryEditActivity.this);
}
});

View File

@@ -31,40 +31,43 @@ import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import com.keepassdroid.database.Database;
import com.keepassdroid.fragments.GroupEditDialogFragment;
import com.keepassdroid.fragments.IconPickerDialogFragment;
import com.keepassdroid.tasks.ProgressTask;
import com.keepassdroid.database.PwEntry;
import com.keepassdroid.database.PwNode;
import com.keepassdroid.database.edit.DeleteEntry;
import com.keepassdroid.database.edit.DeleteGroup;
import com.keepassdroid.adapters.NodeAdapter;
import com.kunzisoft.keepass.KeePass;
import com.kunzisoft.keepass.R;
import com.keepassdroid.app.App;
import com.keepassdroid.database.Database;
import com.keepassdroid.database.PwDatabase;
import com.keepassdroid.database.PwDatabaseV3;
import com.keepassdroid.database.PwDatabaseV4;
import com.keepassdroid.database.PwEntry;
import com.keepassdroid.database.PwGroup;
import com.keepassdroid.database.PwGroupId;
import com.keepassdroid.database.PwGroupV3;
import com.keepassdroid.database.PwGroupV4;
import com.keepassdroid.database.PwNode;
import com.keepassdroid.database.edit.AddGroup;
import com.keepassdroid.database.edit.DeleteEntry;
import com.keepassdroid.database.edit.DeleteGroup;
import com.keepassdroid.dialog.ReadOnlyDialog;
import com.keepassdroid.fragments.GroupEditDialogFragment;
import com.keepassdroid.fragments.IconPickerDialogFragment;
import com.keepassdroid.tasks.ProgressTask;
import com.keepassdroid.view.GroupAddEntryView;
import com.keepassdroid.view.GroupRootView;
import com.keepassdroid.view.GroupViewOnlyView;
import com.kunzisoft.keepass.KeePass;
import com.kunzisoft.keepass.R;
public abstract class GroupActivity extends GroupBaseActivity
implements GroupEditDialogFragment.CreateGroupListener, IconPickerDialogFragment.IconPickerListener {
private static final String TAG_CREATE_GROUP = "TAG_CREATE_GROUP";
implements GroupEditDialogFragment.EditGroupListener, IconPickerDialogFragment.IconPickerListener {
protected boolean addGroupEnabled = false;
protected boolean addEntryEnabled = false;
protected boolean isRoot = false;
protected boolean readOnly = false;
protected EditGroupDialogAction editGroupDialogAction = EditGroupDialogAction.NONE;
private enum EditGroupDialogAction {
CREATION, UPDATE, NONE
}
private static final String TAG = "Group Activity:";
@@ -167,8 +170,10 @@ public abstract class GroupActivity extends GroupBaseActivity
addGroup.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
editGroupDialogAction = EditGroupDialogAction.CREATION;
GroupEditDialogFragment groupEditDialogFragment = new GroupEditDialogFragment();
groupEditDialogFragment.show(getSupportFragmentManager(), TAG_CREATE_GROUP);
groupEditDialogFragment.show(getSupportFragmentManager(),
GroupEditDialogFragment.TAG_CREATE_GROUP);
}
});
}
@@ -187,7 +192,7 @@ public abstract class GroupActivity extends GroupBaseActivity
setGroupTitle();
setGroupIcon();
NodeAdapter nodeAdapter = new NodeAdapter(this, mCurrentGroup);
NodeAdapter nodeAdapter = new NodeAdapter(this, mCurrentGroup, true);
nodeAdapter.setOnNodeClickListener(this);
nodeAdapter.setNodeMenuListener(new NodeAdapter.NodeMenuListener() {
@Override
@@ -203,6 +208,24 @@ public abstract class GroupActivity extends GroupBaseActivity
return true;
}
@Override
public boolean onEditMenuClick(PwNode node) {
mAdapter.registerANodeToUpdate(node);
switch (node.getType()) {
case GROUP:
editGroupDialogAction = EditGroupDialogAction.UPDATE;
GroupEditDialogFragment groupEditDialogFragment =
GroupEditDialogFragment.build(node);
groupEditDialogFragment.show(getSupportFragmentManager(),
GroupEditDialogFragment.TAG_CREATE_GROUP);
break;
case ENTRY:
EntryEditActivity.Launch(GroupActivity.this, (PwEntry) node);
break;
}
return true;
}
@Override
public boolean onDeleteMenuClick(PwNode node) {
switch (node.getType()) {
@@ -241,23 +264,6 @@ public abstract class GroupActivity extends GroupBaseActivity
pt.run();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case EntryEditActivity.ADD_OR_UPDATE_ENTRY_REQUEST_CODE:
if (resultCode == EntryEditActivity.ADD_ENTRY_RESULT_CODE ||
resultCode == EntryEditActivity.UPDATE_ENTRY_RESULT_CODE) {
PwNode newNode = (PwNode) data.getSerializableExtra(EntryEditActivity.ADD_OR_UPDATE_ENTRY_KEY);
if (resultCode == EntryEditActivity.ADD_ENTRY_RESULT_CODE)
mAdapter.addNode(newNode);
if (resultCode == EntryEditActivity.UPDATE_ENTRY_RESULT_CODE)
mAdapter.updateLastNodeClicked();
}
break;
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
@@ -269,25 +275,37 @@ public abstract class GroupActivity extends GroupBaseActivity
}
@Override
public void approveCreateGroup(Bundle bundle) {
public void approveEditGroup(Bundle bundle) {
String GroupName = bundle.getString(GroupEditDialogFragment.KEY_NAME);
int GroupIconID = bundle.getInt(GroupEditDialogFragment.KEY_ICON_ID);
Handler handler = new Handler();
AddGroup task = new AddGroup(this, App.getDB(), GroupName, GroupIconID, mCurrentGroup,
new AfterAddNode(handler), false);
ProgressTask pt = new ProgressTask(this, task, R.string.saving_database);
pt.run();
switch (editGroupDialogAction) {
case CREATION:
// If edit group creation
Handler handler = new Handler();
AddGroup task = new AddGroup(this, App.getDB(), GroupName, GroupIconID, mCurrentGroup,
new AfterAddNode(handler), false);
ProgressTask pt = new ProgressTask(this, task, R.string.saving_database);
pt.run();
break;
case UPDATE:
// If edit group update
// TODO UpdateGroup
break;
}
editGroupDialogAction = EditGroupDialogAction.NONE;
}
@Override
public void cancelCreateGroup(Bundle bundle) {
public void cancelEditGroup(Bundle bundle) {
// Do nothing here
}
@Override
// For icon in create tree dialog
public void iconPicked(Bundle bundle) {
GroupEditDialogFragment groupEditDialogFragment = (GroupEditDialogFragment) getSupportFragmentManager().findFragmentByTag(TAG_CREATE_GROUP);
GroupEditDialogFragment groupEditDialogFragment =
(GroupEditDialogFragment) getSupportFragmentManager()
.findFragmentByTag(GroupEditDialogFragment.TAG_CREATE_GROUP);
if (groupEditDialogFragment != null) {
groupEditDialogFragment.iconPicked(bundle);
}

View File

@@ -102,7 +102,6 @@ public abstract class GroupBaseActivity extends LockCloseListActivity
setResult(KeePass.EXIT_NORMAL);
styleScrollBars();
}
protected void styleScrollBars() {
@@ -123,7 +122,6 @@ public abstract class GroupBaseActivity extends LockCloseListActivity
if ( tv != null ) {
tv.setText(getText(R.string.root));
}
}
}
}
@@ -148,6 +146,7 @@ public abstract class GroupBaseActivity extends LockCloseListActivity
@Override
public void onNodeClick(PwNode node) {
mAdapter.registerANodeToUpdate(node);
switch (node.getType()) {
case GROUP:
GroupActivity.Launch(this, (PwGroup) node);
@@ -209,9 +208,7 @@ public abstract class GroupBaseActivity extends LockCloseListActivity
if ( ! super.onPrepareOptionsMenu(menu) ) {
return false;
}
setSortMenuText(menu);
return true;
}
@@ -330,6 +327,23 @@ public abstract class GroupBaseActivity extends LockCloseListActivity
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case EntryEditActivity.ADD_OR_UPDATE_ENTRY_REQUEST_CODE:
if (resultCode == EntryEditActivity.ADD_ENTRY_RESULT_CODE ||
resultCode == EntryEditActivity.UPDATE_ENTRY_RESULT_CODE) {
PwNode newNode = (PwNode) data.getSerializableExtra(EntryEditActivity.ADD_OR_UPDATE_ENTRY_KEY);
if (resultCode == EntryEditActivity.ADD_ENTRY_RESULT_CODE)
mAdapter.addNode(newNode);
if (resultCode == EntryEditActivity.UPDATE_ENTRY_RESULT_CODE)
mAdapter.updateLastNodeRegister();
}
break;
}
}
@Override
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
/*

View File

@@ -40,9 +40,6 @@ import com.kunzisoft.keepass.R;
public class NodeAdapter extends RecyclerView.Adapter<BasicViewHolder> {
private static final int MENU_OPEN = Menu.FIRST;
private static final int MENU_DELETE = MENU_OPEN + 1;
private SortedList<PwNode> nodeSortedList;
private Context context;
@@ -53,12 +50,29 @@ public class NodeAdapter extends RecyclerView.Adapter<BasicViewHolder> {
private OnNodeClickCallback onNodeClickCallback;
private int nodePositionToUpdate;
private NodeMenuListener nodeMenuListener;
private boolean activateContextMenu;
/**
* Create node list adapter without contextMenu
* @param context Context to use
* @param mainNode Main node as group to build children
*/
public NodeAdapter(final Context context, PwGroup mainNode) {
this(context, mainNode, false);
}
/**
* Create node list adapter with contextMenu or not
* @param context Context to use
* @param mainNode Main node as group to build children
* @param mainNode true if contextMenu need to be shown
*/
public NodeAdapter(final Context context, PwGroup mainNode, boolean activateContextMenu) {
this.inflater = LayoutInflater.from(context);
this.context = context;
this.textSize = PrefsUtil.getListTextSize(context);
this.sortByName = PrefsUtil.isListSortByName(context);
this.activateContextMenu = activateContextMenu;
this.nodePositionToUpdate = -1;
this.nodeSortedList = new SortedList<>(PwNode.class, new SortedListAdapterCallback<PwNode>(this) {
@@ -98,9 +112,19 @@ public class NodeAdapter extends RecyclerView.Adapter<BasicViewHolder> {
}
/**
* Update the last Node clicked in the list
* Register a node to update before an action
* Call updateLastNodeRegister() after the action to update the node
* @param node Node to register
*/
public void updateLastNodeClicked() {
public void registerANodeToUpdate(PwNode node) {
nodePositionToUpdate = nodeSortedList.indexOf(node);
}
/**
* Update the last Node register in the list
* Work if only registerANodeToUpdate(PwNode node) is called before
*/
public void updateLastNodeRegister() {
// Don't really update here, sorted list knows each original ref, so we just notify a change
try {
notifyItemChanged(nodePositionToUpdate);
@@ -155,8 +179,11 @@ public class NodeAdapter extends RecyclerView.Adapter<BasicViewHolder> {
// Assign click
holder.container.setOnClickListener(
new OnNodeClickListener(subNode));
holder.container.setOnCreateContextMenuListener(
new ContextMenuBuilder(subNode, nodeMenuListener));
// Context menu
if (activateContextMenu) {
holder.container.setOnCreateContextMenuListener(
new ContextMenuBuilder(subNode, nodeMenuListener));
}
// Assign text size
holder.text.setTextSize(textSize);
}
@@ -192,6 +219,7 @@ public class NodeAdapter extends RecyclerView.Adapter<BasicViewHolder> {
*/
public interface NodeMenuListener {
boolean onOpenMenuClick(PwNode node);
boolean onEditMenuClick(PwNode node);
boolean onDeleteMenuClick(PwNode node);
}
@@ -207,7 +235,6 @@ public class NodeAdapter extends RecyclerView.Adapter<BasicViewHolder> {
@Override
public void onClick(View v) {
nodePositionToUpdate = nodeSortedList.indexOf(node);
if (onNodeClickCallback != null)
onNodeClickCallback.onNodeClick(node);
}
@@ -218,6 +245,10 @@ public class NodeAdapter extends RecyclerView.Adapter<BasicViewHolder> {
*/
private class ContextMenuBuilder implements View.OnCreateContextMenuListener {
private static final int MENU_OPEN = Menu.FIRST;
private static final int MENU_EDIT = MENU_OPEN + 1;
private static final int MENU_DELETE = MENU_EDIT + 1;
private PwNode node;
private NodeMenuListener menuListener;
@@ -231,6 +262,9 @@ public class NodeAdapter extends RecyclerView.Adapter<BasicViewHolder> {
MenuItem clearMenu = contextMenu.add(Menu.NONE, MENU_OPEN, Menu.NONE, R.string.menu_open);
clearMenu.setOnMenuItemClickListener(mOnMyActionClickListener);
if (!App.getDB().readOnly && !node.equals(App.getDB().pm.getRecycleBin())) {
// TODO make edit for group
// clearMenu = contextMenu.add(Menu.NONE, MENU_EDIT, Menu.NONE, R.string.menu_edit);
// clearMenu.setOnMenuItemClickListener(mOnMyActionClickListener);
clearMenu = contextMenu.add(Menu.NONE, MENU_DELETE, Menu.NONE, R.string.menu_delete);
clearMenu.setOnMenuItemClickListener(mOnMyActionClickListener);
}
@@ -244,6 +278,8 @@ public class NodeAdapter extends RecyclerView.Adapter<BasicViewHolder> {
switch ( item.getItemId() ) {
case MENU_OPEN:
return menuListener.onOpenMenuClick(node);
case MENU_EDIT:
return menuListener.onEditMenuClick(node);
case MENU_DELETE:
return menuListener.onDeleteMenuClick(node);
default:

View File

@@ -32,28 +32,42 @@ import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import com.kunzisoft.keepass.R;
import com.keepassdroid.database.PwNode;
import com.keepassdroid.icons.Icons;
import com.kunzisoft.keepass.R;
public class GroupEditDialogFragment extends DialogFragment
implements IconPickerDialogFragment.IconPickerListener {
public static final String TAG_CREATE_GROUP = "TAG_CREATE_GROUP";
public static final String KEY_NAME = "name";
public static final String KEY_ICON_ID = "icon_id";
private CreateGroupListener createGroupListener;
private EditGroupListener editGroupListener;
private TextView nameField;
private ImageButton iconButton;
private int mSelectedIconID;
private View root;
public static GroupEditDialogFragment build(PwNode group) {
Bundle bundle = new Bundle();
bundle.putString(KEY_NAME, group.getDisplayTitle());
// TODO Change
bundle.putInt(KEY_ICON_ID, group.getIcon().hashCode());
GroupEditDialogFragment fragment = new GroupEditDialogFragment();
fragment.setArguments(bundle);
return fragment;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
// Verify that the host activity implements the callback interface
try {
// Instantiate the NoticeDialogListener so we can send events to the host
createGroupListener = (CreateGroupListener) context;
createGroupListener = (CreateGroupListener) context;
editGroupListener = (EditGroupListener) context;
} catch (ClassCastException e) {
// The activity doesn't implement the interface, throw exception
throw new ClassCastException(context.toString()
@@ -64,22 +78,30 @@ public class GroupEditDialogFragment extends DialogFragment
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
LayoutInflater inflater = getActivity().getLayoutInflater();
root = inflater.inflate(R.layout.group_edit, null);
nameField = (TextView) root.findViewById(R.id.group_name);
iconButton = (ImageButton) root.findViewById(R.id.icon_button);
if (getArguments() != null
&& getArguments().containsKey(KEY_NAME)
&& getArguments().containsKey(KEY_ICON_ID)) {
nameField.setText(getArguments().getString(KEY_NAME));
populateIcon(getArguments().getInt(KEY_ICON_ID));
}
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(root)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
TextView nameField = (TextView) root.findViewById(R.id.group_name);
String name = nameField.getText().toString();
if ( name.length() > 0 ) {
Bundle bundle = new Bundle();
bundle.putString(KEY_NAME, name);
bundle.putInt(KEY_ICON_ID, mSelectedIconID);
createGroupListener.approveCreateGroup(bundle);
editGroupListener.approveEditGroup(bundle);
GroupEditDialogFragment.this.getDialog().cancel();
}
@@ -91,7 +113,7 @@ public class GroupEditDialogFragment extends DialogFragment
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Bundle bundle = new Bundle();
createGroupListener.cancelCreateGroup(bundle);
editGroupListener.cancelEditGroup(bundle);
GroupEditDialogFragment.this.getDialog().cancel();
}
@@ -108,15 +130,18 @@ public class GroupEditDialogFragment extends DialogFragment
return builder.create();
}
private void populateIcon(int iconId) {
iconButton.setImageResource(Icons.iconToResId(iconId));
}
@Override
public void iconPicked(Bundle bundle) {
mSelectedIconID = bundle.getInt(IconPickerDialogFragment.KEY_ICON_ID);
ImageButton currIconButton = (ImageButton) root.findViewById(R.id.icon_button);
currIconButton.setImageResource(Icons.iconToResId(mSelectedIconID));
populateIcon(mSelectedIconID);
}
public interface CreateGroupListener {
void approveCreateGroup(Bundle bundle);
void cancelCreateGroup(Bundle bundle);
public interface EditGroupListener {
void approveEditGroup(Bundle bundle);
void cancelEditGroup(Bundle bundle);
}
}

View File

@@ -45,7 +45,7 @@ public class IconPickerDialogFragment extends DialogFragment {
public static final String KEY_ICON_ID = "icon_id";
private IconPickerListener iconPickerListener;
public static void Launch(StylishActivity activity) {
public static void launch(StylishActivity activity) {
// Create an instance of the dialog fragment and show it
IconPickerDialogFragment dialog = new IconPickerDialogFragment();
dialog.show(activity.getSupportFragmentManager(), "NoticeDialogFragment");

View File

@@ -28,13 +28,13 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import com.keepassdroid.activities.GroupBaseActivity;
import com.keepassdroid.adapters.NodeAdapter;
import com.keepassdroid.app.App;
import com.keepassdroid.database.Database;
import com.keepassdroid.utils.MenuUtil;
import com.kunzisoft.keepass.KeePass;
import com.kunzisoft.keepass.R;
import com.keepassdroid.database.Database;
import com.keepassdroid.activities.GroupBaseActivity;
import com.keepassdroid.app.App;
import com.keepassdroid.utils.MenuUtil;
public class SearchResultsActivity extends GroupBaseActivity {
@@ -109,7 +109,9 @@ public class SearchResultsActivity extends GroupBaseActivity {
setGroupTitle();
setNodeAdapter(new NodeAdapter(this, mCurrentGroup));
NodeAdapter nodeAdapter = new NodeAdapter(this, mCurrentGroup);
nodeAdapter.setOnNodeClickListener(this);
setNodeAdapter(nodeAdapter);
}
private String getSearchStr(Intent queryIntent) {