diff --git a/res/layout/file_selection.xml b/res/layout/file_selection.xml
index 857810208..3592228eb 100644
--- a/res/layout/file_selection.xml
+++ b/res/layout/file_selection.xml
@@ -17,57 +17,42 @@
You should have received a copy of the GNU General Public License
along with KeePassDroid. If not, see .
-->
-
-
+
+
+
+
+
-
-
-
-
-
-
-
+ android:layout_above="@id/file_filename"
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:text="Enter database filename:"/>
-
-
-
\ No newline at end of file
+ android:layout_below="@id/file_listtop"
+ android:layout_above="@id/label_open_by_filename"/>
+
\ No newline at end of file
diff --git a/res/layout/file_selection_no_recent.xml b/res/layout/file_selection_no_recent.xml
new file mode 100644
index 000000000..bac4ddfe6
--- /dev/null
+++ b/res/layout/file_selection_no_recent.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a4b84e5e3..4e87030d7 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -72,6 +72,8 @@
Add entry
Passwords do not match.
A title is required.
+ A filename is required.
+ Could not create file:
Search
Search
Entry title/description
@@ -98,4 +100,7 @@
Saving database...
Loading database...
Working...
+ Creating new database...
+ This file already exists.
+ Enter database password
diff --git a/src/com/keepassdroid/PasswordActivity.java b/src/com/keepassdroid/PasswordActivity.java
index cceb707a7..d03204d53 100644
--- a/src/com/keepassdroid/PasswordActivity.java
+++ b/src/com/keepassdroid/PasswordActivity.java
@@ -190,6 +190,10 @@ public class PasswordActivity extends Activity {
String fileName = getEditText(R.id.pass_filename);
+
+ // Clear before we load
+ KeePass.db.clear();
+
Handler handler = new Handler();
LoadDB task = new LoadDB(KeePass.db, PasswordActivity.this, fileName, pass, key, new AfterLoad(handler));
ProgressTask pt = new ProgressTask(PasswordActivity.this, task, R.string.loading_database);
diff --git a/src/com/keepassdroid/SetPasswordDialog.java b/src/com/keepassdroid/SetPasswordDialog.java
index 8c7ae8554..a6b84b17b 100644
--- a/src/com/keepassdroid/SetPasswordDialog.java
+++ b/src/com/keepassdroid/SetPasswordDialog.java
@@ -29,26 +29,41 @@ import android.widget.Toast;
import com.android.keepass.KeePass;
import com.android.keepass.R;
+import com.keepassdroid.database.FileOnFinish;
import com.keepassdroid.database.OnFinish;
import com.keepassdroid.database.SetPassword;
public class SetPasswordDialog extends CancelDialog {
private byte[] masterKey;
+ private String mKeyfile;
+ private FileOnFinish mFinish;
public SetPasswordDialog(Context context) {
super(context);
}
+ public SetPasswordDialog(Context context, FileOnFinish finish) {
+ super(context);
+
+ mFinish = finish;
+ }
+
public byte[] getKey() {
return masterKey;
}
+
+ public String keyfile() {
+ return mKeyfile;
+ }
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.set_password);
+ setTitle(R.string.password_title);
+
// Ok button
Button okButton = (Button) findViewById(R.id.ok);
okButton.setOnClickListener(new View.OnClickListener() {
@@ -69,6 +84,7 @@ public class SetPasswordDialog extends CancelDialog {
TextView keyfileView = (TextView) findViewById(R.id.pass_keyfile);
String keyfile = keyfileView.getText().toString();
+ mKeyfile = keyfile;
// Verify that a password or keyfile is set
if ( pass.length() == 0 && keyfile.length() == 0 ) {
@@ -77,7 +93,7 @@ public class SetPasswordDialog extends CancelDialog {
}
- SetPassword sp = new SetPassword(KeePass.db, pass, keyfile, new AfterSave(new Handler()));
+ SetPassword sp = new SetPassword(KeePass.db, pass, keyfile, new AfterSave(mFinish, new Handler()));
ProgressTask pt = new ProgressTask(getContext(), sp, R.string.saving_database);
pt.run();
}
@@ -91,18 +107,27 @@ public class SetPasswordDialog extends CancelDialog {
@Override
public void onClick(View v) {
cancel();
+ if ( mFinish != null ) {
+ mFinish.run();
+ }
}
});
}
private class AfterSave extends OnFinish {
- public AfterSave(Handler handler) {
- super(handler);
+ private FileOnFinish mFinish;
+
+ public AfterSave(FileOnFinish finish, Handler handler) {
+ super(finish, handler);
+ mFinish = finish;
}
@Override
public void run() {
if ( mSuccess ) {
+ if ( mFinish != null ) {
+ mFinish.setFilename(mKeyfile);
+ }
dismiss();
} else {
displayMessage(getContext());
diff --git a/src/com/keepassdroid/database/CreateDB.java b/src/com/keepassdroid/database/CreateDB.java
new file mode 100644
index 000000000..c7bee2535
--- /dev/null
+++ b/src/com/keepassdroid/database/CreateDB.java
@@ -0,0 +1,75 @@
+/*
+ * 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 2 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 .
+ *
+ */
+package com.keepassdroid.database;
+
+import org.phoneid.keepassj2me.PwDbHeader;
+import org.phoneid.keepassj2me.PwManager;
+
+import com.android.keepass.KeePass;
+import com.keepassdroid.Database;
+
+public class CreateDB extends RunnableOnFinish {
+
+ private final int DEFAULT_ENCRYPTION_ROUNDS = 300;
+
+ private String mFilename;
+ private boolean mDontSave;
+
+ public CreateDB(String filename, OnFinish finish, boolean dontSave) {
+ super(finish);
+
+ mFilename = filename;
+ mDontSave = dontSave;
+ }
+
+ @Override
+ public void run() {
+ // Create new database record
+ Database db = new Database();
+ KeePass.db = db;
+
+ // Create the PwManager
+ PwManager pm = new PwManager();
+ pm.algorithm = PwDbHeader.ALGO_AES;
+ pm.numKeyEncRounds = DEFAULT_ENCRYPTION_ROUNDS;
+ pm.name = "KeePass Password Manager";
+ // Build the root group
+ pm.constructTree(null);
+
+ // Set Database state
+ db.gRoot = pm.rootGroup;
+ db.mPM = pm;
+ db.mFilename = mFilename;
+
+ // Add a couple default groups
+ AddGroup internet = new AddGroup(db, "Internet", pm.rootGroup, null, true);
+ internet.run();
+ AddGroup email = new AddGroup(db, "eMail", pm.rootGroup, null, true);
+ email.run();
+
+ // Commit changes
+ SaveDB save = new SaveDB(db, mFinish, mDontSave);
+ mFinish = null;
+ save.run();
+
+
+ }
+
+}
diff --git a/src/com/keepassdroid/database/FileOnFinish.java b/src/com/keepassdroid/database/FileOnFinish.java
new file mode 100644
index 000000000..d6f7a6ec3
--- /dev/null
+++ b/src/com/keepassdroid/database/FileOnFinish.java
@@ -0,0 +1,21 @@
+package com.keepassdroid.database;
+
+public class FileOnFinish extends OnFinish {
+ private String mFilename = "";
+ protected FileOnFinish mOnFinish;
+
+ public FileOnFinish(FileOnFinish finish) {
+ super(finish);
+
+ mOnFinish = finish;
+ }
+
+ public void setFilename(String filename) {
+ mFilename = filename;
+ }
+
+ public String getFilename() {
+ return mFilename;
+ }
+
+}
diff --git a/src/com/keepassdroid/database/OnFinish.java b/src/com/keepassdroid/database/OnFinish.java
index e93b8d01e..1ec03b7ee 100644
--- a/src/com/keepassdroid/database/OnFinish.java
+++ b/src/com/keepassdroid/database/OnFinish.java
@@ -35,7 +35,9 @@ public class OnFinish implements Runnable {
protected OnFinish mOnFinish;
protected Handler mHandler;
-
+
+ public OnFinish() {
+ }
public OnFinish(Handler handler) {
mOnFinish = null;
diff --git a/src/com/keepassdroid/database/SetPassword.java b/src/com/keepassdroid/database/SetPassword.java
index ad3100073..9a78b706c 100644
--- a/src/com/keepassdroid/database/SetPassword.java
+++ b/src/com/keepassdroid/database/SetPassword.java
@@ -31,6 +31,7 @@ public class SetPassword extends RunnableOnFinish {
private String mPassword;
private String mKeyfile;
private Database mDb;
+ private boolean mDontSave;
public SetPassword(Database db, String password, String keyfile, OnFinish finish) {
super(finish);
@@ -38,6 +39,16 @@ public class SetPassword extends RunnableOnFinish {
mDb = db;
mPassword = password;
mKeyfile = keyfile;
+ mDontSave = false;
+ }
+
+ public SetPassword(Database db, String password, String keyfile, OnFinish finish, boolean dontSave) {
+ super(finish);
+
+ mDb = db;
+ mPassword = password;
+ mKeyfile = keyfile;
+ mDontSave = dontSave;
}
@Override
@@ -62,7 +73,7 @@ public class SetPassword extends RunnableOnFinish {
// Save Database
mFinish = new AfterSave(backupKey, mFinish);
- SaveDB save = new SaveDB(mDb, mFinish);
+ SaveDB save = new SaveDB(mDb, mFinish, mDontSave);
save.run();
}
diff --git a/src/com/keepassdroid/fileselect/FileDbHelper.java b/src/com/keepassdroid/fileselect/FileDbHelper.java
index 2584cbbbe..4b82735d6 100644
--- a/src/com/keepassdroid/fileselect/FileDbHelper.java
+++ b/src/com/keepassdroid/fileselect/FileDbHelper.java
@@ -206,4 +206,9 @@ public class FileDbHelper {
return cursor.getString(0);
}
+
+ public boolean hasRecentFiles() {
+ Cursor cursor = fetchAllFiles();
+ return cursor.getCount() > 0;
+ }
}
diff --git a/src/com/keepassdroid/fileselect/FileSelectActivity.java b/src/com/keepassdroid/fileselect/FileSelectActivity.java
index 67d2c01e0..baeaa6ade 100644
--- a/src/com/keepassdroid/fileselect/FileSelectActivity.java
+++ b/src/com/keepassdroid/fileselect/FileSelectActivity.java
@@ -19,9 +19,10 @@
*/
package com.keepassdroid.fileselect;
+import java.io.File;
import java.io.FileNotFoundException;
+import java.io.IOException;
-import android.app.Activity;
import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
@@ -36,8 +37,14 @@ import android.widget.Toast;
import com.android.keepass.R;
import com.keepassdroid.AboutDialog;
+import com.keepassdroid.GroupActivity;
import com.keepassdroid.PasswordActivity;
+import com.keepassdroid.ProgressTask;
+import com.keepassdroid.SetPasswordDialog;
import com.keepassdroid.Util;
+import com.keepassdroid.database.CreateDB;
+import com.keepassdroid.database.FileOnFinish;
+import com.keepassdroid.database.OnFinish;
import com.keepassdroid.intents.TimeoutIntents;
public class FileSelectActivity extends ListActivity {
@@ -49,18 +56,119 @@ public class FileSelectActivity extends ListActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.file_selection);
-
- Button openButton = (Button) findViewById(R.id.file_button);
- openButton.setOnClickListener(new ClickHandler(this));
-
mDbHelper = new FileDbHelper(this);
mDbHelper.open();
+ if ( mDbHelper.hasRecentFiles() ) {
+ setContentView(R.layout.file_selection);
+ } else {
+ setContentView(R.layout.file_selection_no_recent);
+ }
+
+ // Open button
+ Button openButton = (Button) findViewById(R.id.open);
+ openButton.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ String fileName = Util.getEditText(FileSelectActivity.this, R.id.file_filename);
+
+ try {
+ PasswordActivity.Launch(FileSelectActivity.this, fileName);
+ } catch (FileNotFoundException e) {
+ Toast.makeText(FileSelectActivity.this, R.string.FileNotFound, Toast.LENGTH_LONG).show();
+ }
+
+ }
+ });
+
+ // Create button
+ Button createButton = (Button) findViewById(R.id.create);
+ createButton.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ String filename = Util.getEditText(FileSelectActivity.this, R.id.file_filename);
+
+ // Make sure file name exists
+ if ( filename.length() == 0 ) {
+ Toast.makeText(FileSelectActivity.this, R.string.error_filename_required, Toast.LENGTH_LONG).show();
+ return;
+ }
+
+ // Try to create the file
+ File file = new File(filename);
+ try {
+ if ( file.exists() ) {
+ Toast.makeText(FileSelectActivity.this, R.string.error_database_exists, Toast.LENGTH_LONG).show();
+ return;
+ }
+
+ file.createNewFile();
+ } catch (IOException e) {
+ Toast.makeText(FileSelectActivity.this, getText(R.string.error_file_not_create) + " " + e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
+ return;
+ }
+
+ // Prep an object to collect a password once the database has been created
+ CollectPassword password = new CollectPassword(new LaunchGroupActivity(filename));
+
+ // Create the new database
+ CreateDB create = new CreateDB(filename, password, true);
+ ProgressTask createTask = new ProgressTask(FileSelectActivity.this, create, R.string.progress_create);
+ createTask.run();
+
+ }
+
+
+ });
+
+
fillData();
}
+ private class LaunchGroupActivity extends FileOnFinish {
+ private String mFilename;
+
+ public LaunchGroupActivity(String filename) {
+ super(null);
+
+ mFilename = filename;
+ }
+
+ @Override
+ public void run() {
+ if ( mSuccess ) {
+ // Add to recent files
+ FileDbHelper dbHelper = new FileDbHelper(FileSelectActivity.this);
+ dbHelper.open();
+ dbHelper.createFile(mFilename, getFilename());
+ dbHelper.close();
+
+ GroupActivity.Launch(FileSelectActivity.this, null, GroupActivity.ADD_GROUP_ONLY);
+
+ } else {
+ File file = new File(mFilename);
+ file.delete();
+ }
+ }
+ }
+
+ private class CollectPassword extends FileOnFinish {
+
+ public CollectPassword(FileOnFinish finish) {
+ super(finish);
+ }
+
+ @Override
+ public void run() {
+ SetPasswordDialog password = new SetPasswordDialog(FileSelectActivity.this, mOnFinish);
+ password.show();
+ }
+
+ }
+
private void fillData() {
// Get all of the rows from the database and create the item list
Cursor filesCursor = mDbHelper.fetchAllFiles();
@@ -118,26 +226,6 @@ public class FileSelectActivity extends ListActivity {
sendBroadcast(new Intent(TimeoutIntents.CANCEL));
}
- private class ClickHandler implements View.OnClickListener {
- Activity mAct;
-
- ClickHandler(Activity act) {
- mAct = act;
- }
-
- @Override
- public void onClick(View v) {
- String fileName = Util.getEditText(mAct, R.id.file_filename);
-
- try {
- PasswordActivity.Launch(mAct, fileName);
- } catch (FileNotFoundException e) {
- Toast.makeText(mAct, R.string.FileNotFound, Toast.LENGTH_LONG).show();
- }
-
- }
-
- }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
diff --git a/src/org/phoneid/keepassj2me/PwManager.java b/src/org/phoneid/keepassj2me/PwManager.java
index 8fb172c3b..e098cbbe5 100644
--- a/src/org/phoneid/keepassj2me/PwManager.java
+++ b/src/org/phoneid/keepassj2me/PwManager.java
@@ -71,7 +71,7 @@ public class PwManager {
// Master key used to encrypt the whole database
public byte masterKey[] = new byte[32];
// Algorithm used to encrypt the database
- int algorithm;
+ public int algorithm;
public int numKeyEncRounds;
// Debugging entries
@@ -80,7 +80,7 @@ public class PwManager {
public byte[] finalKey;
// root group
- PwGroup rootGroup;
+ public PwGroup rootGroup;
public int getAlgorithm() {
return algorithm;