mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Implement add group. Still need to move it to the backgroud.
This commit is contained in:
@@ -18,12 +18,6 @@
|
||||
<!-- whenever the user invokes search while in this Activity. -->
|
||||
<meta-data android:name="android.app.default_searchable"
|
||||
android:value=".search.SearchResults" />
|
||||
</activity>
|
||||
<activity android:name=".GroupAddEntryActivity">
|
||||
<!-- This metadata entry causes .app.SearchQueryResults to be the default context -->
|
||||
<!-- whenever the user invokes search while in this Activity. -->
|
||||
<meta-data android:name="android.app.default_searchable"
|
||||
android:value=".search.SearchResults" />
|
||||
</activity>
|
||||
<activity android:name=".EntryActivity"></activity>
|
||||
<activity android:name=".LockingActivity"></activity>
|
||||
|
||||
38
res/layout/create_group.xml
Normal file
38
res/layout/create_group.xml
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2009 Brian Pellin.
|
||||
|
||||
This file is part of KeePassDroid.
|
||||
|
||||
KeePassDroid 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.
|
||||
|
||||
KeePassDroid 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 KeePassDroid. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
<EditText android:id="@+id/group_name"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/hint_group_name"/>
|
||||
<Button android:id="@+id/ok"
|
||||
android:layout_width="100sp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/group_name"
|
||||
android:text="@string/pass_ok"/>
|
||||
<Button android:id="@+id/cancel"
|
||||
android:layout_width="100sp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/group_name"
|
||||
android:layout_toRightOf="@id/ok"
|
||||
android:text="@string/cancel"/>
|
||||
</RelativeLayout>
|
||||
@@ -43,9 +43,15 @@
|
||||
android:scaleType="fitXY"
|
||||
android:tint="@color/blue_highlight"
|
||||
android:src="@android:drawable/divider_horizontal_dark"/>
|
||||
<Button android:id="@+id/add_group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:text="@string/add_group"/>
|
||||
<Button android:id="@+id/add_entry"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toRightOf="@id/add_group"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:text="@string/add_entry"/>
|
||||
<ImageView android:id="@+id/divider2"
|
||||
|
||||
63
res/layout/group_root.xml
Normal file
63
res/layout/group_root.xml
Normal file
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2009 Brian Pellin.
|
||||
|
||||
This file is part of KeePassDroid.
|
||||
|
||||
KeePassDroid 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.
|
||||
|
||||
KeePassDroid 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 KeePassDroid. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
<TextView android:id="@+id/group_header"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="15sp"
|
||||
android:text="@string/current_group"
|
||||
android:textStyle="bold"
|
||||
android:layout_weight="0"/>
|
||||
<TextView android:id="@+id/group_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@id/group_header"
|
||||
android:layout_toRightOf="@id/group_header"
|
||||
android:layout_marginLeft="3sp"
|
||||
android:text="@string/root"
|
||||
style="@style/GroupTextSmall"
|
||||
android:layout_weight="0"/>
|
||||
<ImageView android:id="@+id/divider1"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/group_header"
|
||||
android:scaleType="fitXY"
|
||||
android:tint="@color/blue_highlight"
|
||||
android:src="@android:drawable/divider_horizontal_dark"/>
|
||||
<Button android:id="@+id/add_group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:text="@string/add_group"/>
|
||||
<ImageView android:id="@+id/divider2"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@id/add_group"
|
||||
android:scaleType="fitXY"
|
||||
android:tint="@color/blue_highlight"
|
||||
android:src="@android:drawable/divider_horizontal_dark"/>
|
||||
<ListView android:id="@android:id/list"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@id/divider2"
|
||||
android:layout_below="@id/divider1"/>
|
||||
</RelativeLayout>
|
||||
@@ -1,10 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2009 Brian Pellin.
|
||||
|
||||
This file is part of KeePassDroid.
|
||||
|
||||
KeePassDroid 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.
|
||||
|
||||
KeePassDroid 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 KeePassDroid. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<resources>
|
||||
<string name="app_name">KeePassDroid</string>
|
||||
<string name="no_keys">No entries in the database or group.</string>
|
||||
<string name="FileNotFound">File not found.</string>
|
||||
<string name="InvalidPassword">Invalid password or key file.</string>
|
||||
<string name="pass_ok">Ok</string>
|
||||
<string name="cancel">Cancel</string>
|
||||
<string name="entry_title">Name: </string>
|
||||
<string name="entry_user_name">User Name: </string>
|
||||
<string name="entry_url">URL: </string>
|
||||
@@ -44,7 +63,10 @@
|
||||
<string name="entry_confpassword">Confirm password:</string>
|
||||
|
||||
<string name="disclaimer_formal">KeePassDroid Copyright 2009 Brian Pellin comes with ABSOLUTELY NO WARRANTY; This is free software, and you are welcome to redistribute it under the conditions of the GPL version 2 or later.</string>
|
||||
<string name="add_entry">Add Entry</string>
|
||||
<string name="add_group_title">Add Group</string>
|
||||
<string name="hint_group_name">Group name</string>
|
||||
<string name="add_group">Add group</string>
|
||||
<string name="add_entry">Add entry</string>
|
||||
<string name="error_pass_match">Passwords do not match.</string>
|
||||
<string name="error_title_required">A title is required.</string>
|
||||
<string name="menu_search">Search</string>
|
||||
@@ -58,4 +80,6 @@
|
||||
<string name="hint_conf_pass">confirm password</string>
|
||||
<string name="hint_comment">comment</string>
|
||||
<string name="no_url_handler">No handler for this url.</string>
|
||||
<string name="error_no_name">A name is required.</string>
|
||||
<string name="error_could_not_create_group">Error creating group.</string>
|
||||
</resources>
|
||||
|
||||
@@ -106,6 +106,29 @@ public class Database {
|
||||
return searchHelper.search(this, str);
|
||||
}
|
||||
|
||||
public void NewGroup(String name, PwGroup parent) throws PwManagerOutputException, IOException {
|
||||
// Generate new group
|
||||
PwGroup group = mPM.newGroup(name, parent);
|
||||
|
||||
// Commit to disk
|
||||
try {
|
||||
SaveData();
|
||||
} catch (PwManagerOutputException e) {
|
||||
mPM.removeGroup(group);
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
mPM.removeGroup(group);
|
||||
throw e;
|
||||
}
|
||||
|
||||
// Mark parent group dirty
|
||||
gDirty.put(parent, new WeakReference<PwGroup>(parent));
|
||||
|
||||
// Add group to global list
|
||||
gGroups.put(group.groupId, new WeakReference<PwGroup>(group));
|
||||
|
||||
}
|
||||
|
||||
public void NewEntry(PwEntry entry) throws IOException, PwManagerOutputException {
|
||||
PwGroup parent = entry.parent;
|
||||
|
||||
|
||||
@@ -19,21 +19,62 @@
|
||||
*/
|
||||
package com.android.keepass;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import org.phoneid.keepassj2me.PwGroup;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.android.keepass.keepasslib.PwManagerOutputException;
|
||||
|
||||
public class GroupActivity extends GroupBaseActivity {
|
||||
|
||||
|
||||
public static final int UNINIT = -1;
|
||||
public static final int VIEW_ONLY = 0;
|
||||
public static final int ADD_GROUP_ONLY = 1;
|
||||
public static final int FULL = 2;
|
||||
|
||||
public static void Launch(Activity act, PwGroup group, int mode) {
|
||||
Intent i = new Intent(act, GroupActivity.class);
|
||||
|
||||
if ( group != null ) {
|
||||
i.putExtra(KEY_ENTRY, group.groupId);
|
||||
}
|
||||
|
||||
i.putExtra(KEY_MODE, mode);
|
||||
|
||||
act.startActivityForResult(i,0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.group_view_only);
|
||||
setResult(KeePass.EXIT_NORMAL);
|
||||
|
||||
Intent intent = getIntent();
|
||||
|
||||
int id = getIntent().getIntExtra(KEY_ENTRY, -1);
|
||||
int mode = intent.getIntExtra(KEY_MODE, UNINIT);
|
||||
|
||||
switch ( mode ) {
|
||||
case FULL:
|
||||
setContentView(R.layout.group_add_entry);
|
||||
break;
|
||||
case ADD_GROUP_ONLY:
|
||||
setContentView(R.layout.group_root);
|
||||
break;
|
||||
default:
|
||||
setContentView(R.layout.group_view_only);
|
||||
}
|
||||
|
||||
int id = intent.getIntExtra(KEY_ENTRY, -1);
|
||||
|
||||
if ( id == -1 ) {
|
||||
mGroup = KeePass.db.gRoot;
|
||||
@@ -43,8 +84,69 @@ public class GroupActivity extends GroupBaseActivity {
|
||||
}
|
||||
assert(mGroup != null);
|
||||
|
||||
if ( mode == FULL || mode == ADD_GROUP_ONLY ) {
|
||||
// Add Group button
|
||||
Button addGroup = (Button) findViewById(R.id.add_group);
|
||||
addGroup.setOnClickListener(new GroupAddHandler(this, mGroup));
|
||||
}
|
||||
|
||||
if ( mode == FULL ) {
|
||||
// Add Entry button
|
||||
Button addEntry = (Button) findViewById(R.id.add_entry);
|
||||
addEntry.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
EntryEditActivity.Launch(GroupActivity.this, mGroup);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setGroupTitle();
|
||||
|
||||
setListAdapter(new PwListAdapter(this, mGroup));
|
||||
}
|
||||
|
||||
private class GroupAddHandler implements View.OnClickListener {
|
||||
private GroupBaseActivity mAct;
|
||||
private PwGroup mGroup;
|
||||
private GroupCreateDialog mDialog;
|
||||
|
||||
GroupAddHandler(GroupBaseActivity act, PwGroup group) {
|
||||
mAct = act;
|
||||
mGroup = group;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
GroupCreateDialog dialog = new GroupCreateDialog(mAct);
|
||||
mDialog = dialog;
|
||||
|
||||
// Register Listener
|
||||
dialog.setOnDismissListener(new Dialog.OnDismissListener() {
|
||||
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
String res = mDialog.getResponse();
|
||||
try {
|
||||
KeePass.db.NewGroup(res, mGroup);
|
||||
} catch (PwManagerOutputException e) {
|
||||
Toast.makeText(mAct, R.string.error_could_not_create_group, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(mAct, R.string.error_could_not_create_group, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
mAct.refreshIfDirty();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import android.widget.TextView;
|
||||
|
||||
public abstract class GroupBaseActivity extends LockingListActivity {
|
||||
public static final String KEY_ENTRY = "entry";
|
||||
public static final String KEY_MODE = "mode";
|
||||
|
||||
protected static final int MENU_LOCK = Menu.FIRST;
|
||||
protected static final int MENU_SEARCH = Menu.FIRST + 1;
|
||||
@@ -54,6 +55,10 @@ public abstract class GroupBaseActivity extends LockingListActivity {
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
refreshIfDirty();
|
||||
}
|
||||
|
||||
public void refreshIfDirty() {
|
||||
if ( KeePass.db.gDirty.get(mGroup) != null ) {
|
||||
KeePass.db.gDirty.remove(mGroup);
|
||||
BaseAdapter adapter = (BaseAdapter) getListAdapter();
|
||||
|
||||
@@ -19,43 +19,56 @@
|
||||
*/
|
||||
package com.android.keepass;
|
||||
|
||||
import org.phoneid.keepassj2me.PwGroup;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class GroupAddEntryActivity extends GroupActivity {
|
||||
|
||||
public static void Launch(Activity act, PwGroup group) {
|
||||
Intent i = new Intent(act, GroupAddEntryActivity.class);
|
||||
public class GroupCreateDialog extends Dialog {
|
||||
Context mCtx;
|
||||
String mRes;
|
||||
|
||||
public GroupCreateDialog(Context context) {
|
||||
super(context);
|
||||
|
||||
i.putExtra(KEY_ENTRY, group.groupId);
|
||||
|
||||
act.startActivityForResult(i,0);
|
||||
mCtx = context;
|
||||
}
|
||||
|
||||
public String getResponse() {
|
||||
return mRes;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.group_add_entry);
|
||||
styleScrollBars();
|
||||
setContentView(R.layout.create_group);
|
||||
setTitle(R.string.add_group_title);
|
||||
|
||||
// Add Entry button
|
||||
Button addEntry = (Button) findViewById(R.id.add_entry);
|
||||
addEntry.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
Button okButton = (Button) findViewById(R.id.ok);
|
||||
okButton.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
EntryEditActivity.Launch(GroupAddEntryActivity.this, mGroup);
|
||||
TextView nameField = (TextView) findViewById(R.id.group_name);
|
||||
String name = nameField.getText().toString();
|
||||
|
||||
if ( name.length() > 0 ) {
|
||||
mRes = name;
|
||||
dismiss();
|
||||
} else {
|
||||
Toast.makeText(mCtx, R.string.error_no_name, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
setGroupTitle();
|
||||
|
||||
|
||||
Button cancel = (Button) findViewById(R.id.cancel);
|
||||
cancel.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -232,7 +232,7 @@ public class PasswordActivity extends Activity {
|
||||
}
|
||||
|
||||
if ( mLaunch ) {
|
||||
GroupActivity.Launch(PasswordActivity.this, null);
|
||||
GroupActivity.Launch(PasswordActivity.this, null, GroupActivity.ADD_GROUP_ONLY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public class PwGroupView extends ClickView {
|
||||
|
||||
void onClick() {
|
||||
|
||||
GroupAddEntryActivity.Launch(mAct, mPw);
|
||||
GroupActivity.Launch(mAct, mPw, GroupActivity.FULL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,8 @@ public class PwGroup {
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public static final Date NEVER_EXPIRE = PwEntry.NEVER_EXPIRE;
|
||||
|
||||
/** Size of byte buffer needed to hold this struct. */
|
||||
public static final int BUF_SIZE = 124;
|
||||
|
||||
@@ -31,6 +31,9 @@ import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Random;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.bouncycastle.crypto.digests.SHA256Digest;
|
||||
@@ -296,6 +299,7 @@ public class PwManager {
|
||||
Vector<PwGroup> rootChildGroups = getGrpRoots();
|
||||
rootGroup.childGroups = rootChildGroups;
|
||||
rootGroup.childEntries = new Vector<PwEntry>();
|
||||
rootGroup.level = -1;
|
||||
for (int i=0; i<rootChildGroups.size(); i++) {
|
||||
rootChildGroups.elementAt(i).parent = rootGroup;
|
||||
constructTree(rootChildGroups.elementAt(i));
|
||||
@@ -319,4 +323,70 @@ public class PwManager {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public PwGroup newGroup(String name, PwGroup parent) {
|
||||
// Initialize group
|
||||
PwGroup group = new PwGroup();
|
||||
|
||||
group.parent = parent;
|
||||
group.groupId = newGroupId();
|
||||
group.imageId = 0;
|
||||
group.name = name;
|
||||
|
||||
Date now = Calendar.getInstance().getTime();
|
||||
group.tCreation = now;
|
||||
group.tLastAccess = now;
|
||||
group.tLastMod = now;
|
||||
group.tExpire = PwGroup.NEVER_EXPIRE;
|
||||
|
||||
group.level = parent.level + 1;
|
||||
|
||||
group.childEntries = new Vector<PwEntry>();
|
||||
group.childGroups = new Vector<PwGroup>();
|
||||
|
||||
// Add group PwManager and Parent
|
||||
parent.childGroups.add(group);
|
||||
groups.add(group);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
public void removeGroup(PwGroup group) {
|
||||
group.parent.childGroups.remove(group);
|
||||
groups.remove(group);
|
||||
}
|
||||
|
||||
/** Generates an unused random group id
|
||||
* @return new group id
|
||||
*/
|
||||
private int newGroupId() {
|
||||
boolean foundUnusedId = false;
|
||||
int newId = 0;
|
||||
|
||||
Random random = new Random();
|
||||
|
||||
while ( ! foundUnusedId ) {
|
||||
newId = random.nextInt();
|
||||
|
||||
if ( ! isGroupIdUsed(newId) ) {
|
||||
foundUnusedId = true;
|
||||
}
|
||||
}
|
||||
|
||||
return newId;
|
||||
}
|
||||
|
||||
/** Determine if an id number is already in use
|
||||
* @param id ID number to check for
|
||||
* @return True if the ID is used, false otherwise
|
||||
*/
|
||||
private boolean isGroupIdUsed(int id) {
|
||||
for ( int i = 0; i < groups.size(); i++ ) {
|
||||
if ( groups.get(i).groupId == id ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user