diff --git a/src/Kp2aBusinessLogic/Io/CachingFileStorage.cs b/src/Kp2aBusinessLogic/Io/CachingFileStorage.cs index 95dd50cf..13732716 100644 --- a/src/Kp2aBusinessLogic/Io/CachingFileStorage.cs +++ b/src/Kp2aBusinessLogic/Io/CachingFileStorage.cs @@ -430,8 +430,7 @@ namespace keepass2android.Io public string GetFilenameWithoutPathAndExt(IOConnectionInfo ioc) { - return UrlUtil.StripExtension( - UrlUtil.GetFileName(ioc.Path)); + return _cachedStorage.GetFilenameWithoutPathAndExt(ioc); } public bool RequiresCredentials(IOConnectionInfo ioc) diff --git a/src/Kp2aBusinessLogic/Io/JavaFileStorage.cs b/src/Kp2aBusinessLogic/Io/JavaFileStorage.cs index 0cb5c666..b423a093 100644 --- a/src/Kp2aBusinessLogic/Io/JavaFileStorage.cs +++ b/src/Kp2aBusinessLogic/Io/JavaFileStorage.cs @@ -154,7 +154,7 @@ namespace keepass2android.Io public string GetFilenameWithoutPathAndExt(IOConnectionInfo ioc) { return UrlUtil.StripExtension( - UrlUtil.GetFileName(IocToPath(ioc))); + _jfs.GetFilename(IocToPath(ioc))); } public bool RequiresCredentials(IOConnectionInfo ioc) diff --git a/src/java/JavaFileStorage/.classpath b/src/java/JavaFileStorage/.classpath index 2cde4747..88ceb869 100644 --- a/src/java/JavaFileStorage/.classpath +++ b/src/java/JavaFileStorage/.classpath @@ -1,11 +1,11 @@ - - + + diff --git a/src/java/JavaFileStorage/src/keepass2android/javafilestorage/DropboxFileStorage.java b/src/java/JavaFileStorage/src/keepass2android/javafilestorage/DropboxFileStorage.java index 029d52e6..df6932f6 100644 --- a/src/java/JavaFileStorage/src/keepass2android/javafilestorage/DropboxFileStorage.java +++ b/src/java/JavaFileStorage/src/keepass2android/javafilestorage/DropboxFileStorage.java @@ -507,4 +507,9 @@ public class DropboxFileStorage extends JavaFileStorageBase { return path; } + @Override + public String getFilename(String path) throws Exception { + return path.substring(path.lastIndexOf("/")+1); + } + } diff --git a/src/java/JavaFileStorage/src/keepass2android/javafilestorage/GoogleDriveFileStorage.java b/src/java/JavaFileStorage/src/keepass2android/javafilestorage/GoogleDriveFileStorage.java index 3fb7d685..35b8c935 100644 --- a/src/java/JavaFileStorage/src/keepass2android/javafilestorage/GoogleDriveFileStorage.java +++ b/src/java/JavaFileStorage/src/keepass2android/javafilestorage/GoogleDriveFileStorage.java @@ -11,6 +11,8 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; +import keepass2android.javafilestorage.JavaFileStorageBase.InvalidPathException; + import com.google.api.client.extensions.android.http.AndroidHttp; import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential; import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException; @@ -238,6 +240,27 @@ public class GoogleDriveFileStorage extends JavaFileStorageBase { return mAccount; } + public String getFilename() throws InvalidPathException { + + String[] parts = mAccountLocalPath.split("/"); + + String lastPart = parts[parts.length-1]; + int indexOfSeparator = lastPart.lastIndexOf(NAME_ID_SEP); + if (indexOfSeparator < 0) { + throw new InvalidPathException("cannot extract filename from " + mAccountLocalPath); + } + String name = lastPart.substring(0, indexOfSeparator); + try { + name = decode(name); + } catch (UnsupportedEncodingException e) { + // ignore + } + return name; + + + } + + }; @@ -805,6 +828,15 @@ public class GoogleDriveFileStorage extends JavaFileStorageBase { } return gdrivePath.getDisplayName(); } + + @Override + public String getFilename(String path) throws Exception + { + GDrivePath gdrivePath = new GDrivePath(); + gdrivePath.setPathWithoutVerify(path); + + return gdrivePath.getFilename(); + } } diff --git a/src/java/JavaFileStorage/src/keepass2android/javafilestorage/JavaFileStorage.java b/src/java/JavaFileStorage/src/keepass2android/javafilestorage/JavaFileStorage.java index 6de3036b..a7963d3e 100644 --- a/src/java/JavaFileStorage/src/keepass2android/javafilestorage/JavaFileStorage.java +++ b/src/java/JavaFileStorage/src/keepass2android/javafilestorage/JavaFileStorage.java @@ -120,6 +120,9 @@ public class FileEntry { public String getDisplayName(String path); + //returns something like "myfile.txt" from the given path, i.e. it's displayable and only the last part of the path + public String getFilename(String path) throws Exception; + public boolean checkForFileChangeFast(String path, String previousFileVersion) throws Exception; public String getCurrentFileVersionFast(String path); diff --git a/src/java/JavaFileStorage/src/keepass2android/javafilestorage/SkyDriveFileStorage.java b/src/java/JavaFileStorage/src/keepass2android/javafilestorage/SkyDriveFileStorage.java index 7f472893..73618a37 100644 --- a/src/java/JavaFileStorage/src/keepass2android/javafilestorage/SkyDriveFileStorage.java +++ b/src/java/JavaFileStorage/src/keepass2android/javafilestorage/SkyDriveFileStorage.java @@ -404,19 +404,6 @@ public class SkyDriveFileStorage extends JavaFileStorageBase { throw new SkyDriveException(message, code); } } - - private SkyDriveObject tryAddFileToCache(SkyDrivePath skyDrivePath) { - try { - SkyDriveObject obj = getSkyDriveObject(skyDrivePath); - if (obj != null) { - mFolderCache.put(obj.getId(), obj); - } - return obj; - } catch (Exception e) { - return null; - } - - } private SkyDriveObject tryAddToCache(String skyDriveId) { try { @@ -799,4 +786,11 @@ public class SkyDriveFileStorage extends JavaFileStorageBase { } + @Override + public String getFilename(String path) throws Exception { + SkyDrivePath p = new SkyDrivePath(); + p.setPathWithoutVerify(path); + return p.getFilename(); + } + } diff --git a/src/java/KP2ASoftKeyboard/.classpath b/src/java/KP2ASoftKeyboard/.classpath index d57ec025..51769745 100644 --- a/src/java/KP2ASoftKeyboard/.classpath +++ b/src/java/KP2ASoftKeyboard/.classpath @@ -2,8 +2,8 @@ + - diff --git a/src/java/android-filechooser/code/.classpath b/src/java/android-filechooser/code/.classpath index 7bc01d9a..51769745 100644 --- a/src/java/android-filechooser/code/.classpath +++ b/src/java/android-filechooser/code/.classpath @@ -1,9 +1,9 @@ - - + + diff --git a/src/keepass2android/CreateDatabaseActivity.cs b/src/keepass2android/CreateDatabaseActivity.cs index 75c387fc..b3bf43c4 100644 --- a/src/keepass2android/CreateDatabaseActivity.cs +++ b/src/keepass2android/CreateDatabaseActivity.cs @@ -388,7 +388,7 @@ namespace keepass2android return filename; } - private void OnCreateButton(string filename) + private bool OnCreateButton(string filename) { // Make sure file name exists if (filename.Length == 0) @@ -396,20 +396,21 @@ namespace keepass2android Toast.MakeText(this, Resource.String.error_filename_required, ToastLength.Long).Show(); - return; + return false; } IOConnectionInfo ioc = new IOConnectionInfo { Path = filename }; + IFileStorage fileStorage; try { - App.Kp2a.GetFileStorage(ioc); + fileStorage = App.Kp2a.GetFileStorage(ioc); } catch (NoFileStorageFoundException) { Toast.MakeText(this, "Unexpected scheme in "+filename, ToastLength.Long).Show(); - return; + return false; } if (ioc.IsLocalFile()) @@ -425,7 +426,7 @@ namespace keepass2android Toast.MakeText(this, Resource.String.error_invalid_path, ToastLength.Long).Show(); - return; + return false; } if (!parent.Exists()) @@ -436,7 +437,7 @@ namespace keepass2android Toast.MakeText(this, Resource.String.error_could_not_create_parent, ToastLength.Long).Show(); - return; + return false; } } @@ -450,16 +451,30 @@ namespace keepass2android GetText(Resource.String.error_file_not_create) + " " + ex.LocalizedMessage, ToastLength.Long).Show(); - return; + return false; } - _ioc = ioc; - UpdateIocView(); - - } + if (fileStorage.RequiresCredentials(ioc)) + { + Util.QueryCredentials(ioc, AfterQueryCredentials, this); + } + else + { + _ioc = ioc; + UpdateIocView(); + } + + + return true; } - + + private void AfterQueryCredentials(IOConnectionInfo ioc) + { + _ioc = ioc; + UpdateIocView(); + } + private class LaunchGroupActivity : FileOnFinish { readonly CreateDatabaseActivity _activity; diff --git a/src/keepass2android/Properties/AndroidManifest_net.xml b/src/keepass2android/Properties/AndroidManifest_net.xml index 42221f32..8a2e441f 100644 --- a/src/keepass2android/Properties/AndroidManifest_net.xml +++ b/src/keepass2android/Properties/AndroidManifest_net.xml @@ -1,5 +1,5 @@  - + @@ -21,7 +21,7 @@ - + diff --git a/src/keepass2android/Resources/Resource.designer.cs b/src/keepass2android/Resources/Resource.designer.cs index aad91775..c1a968a9 100644 --- a/src/keepass2android/Resources/Resource.designer.cs +++ b/src/keepass2android/Resources/Resource.designer.cs @@ -5834,7 +5834,7 @@ namespace keepass2android 16843055, 16843056, 16843057, - 16843788}; + 16843754}; // aapt resource value: 4 public const int MenuView_android_headerBackground = 4; diff --git a/src/keepass2android/Utils/Util.cs b/src/keepass2android/Utils/Util.cs index 0751091b..686390d6 100644 --- a/src/keepass2android/Utils/Util.cs +++ b/src/keepass2android/Utils/Util.cs @@ -114,12 +114,14 @@ namespace keepass2android * @return True if an Intent with the specified action can be sent and * responded to, false otherwise. */ - static bool IsIntentAvailable(Context context, String action, String type) + static bool IsIntentAvailable(Context context, String action, String type, List categories ) { PackageManager packageManager = context.PackageManager; Intent intent = new Intent(action); if (type != null) intent.SetType(type); + if (categories != null) + categories.ForEach(c => intent.AddCategory(c)); IList list = packageManager.QueryIntentActivities(intent, PackageInfoFlags.MatchDefaultOnly); @@ -130,10 +132,11 @@ namespace keepass2android public static void ShowBrowseDialog(string filename, Activity act, int requestCodeBrowse, bool forSaving) { - if ((!forSaving) && (IsIntentAvailable(act, Intent.ActionGetContent, "file/*"))) + if ((!forSaving) && (IsIntentAvailable(act, Intent.ActionGetContent, "*/*", new List { Intent.CategoryOpenable}))) { Intent i = new Intent(Intent.ActionGetContent); - i.SetType("file/*"); + i.SetType("*/*"); + i.AddCategory(Intent.CategoryOpenable); act.StartActivityForResult(i, requestCodeBrowse); } @@ -207,7 +210,7 @@ namespace keepass2android return ((int)Android.OS.Build.VERSION.SdkInt >= 14) && (activity.ActionBar != null); } - public delegate void FileSelectedHandler(string filename); + public delegate bool FileSelectedHandler(string filename); public static void ShowFilenameDialog(Activity activity, FileSelectedHandler onOpen, FileSelectedHandler onCreate, bool showBrowseButton, string defaultFilename, string detailsText, int requestCodeBrowse) @@ -233,7 +236,8 @@ namespace keepass2android openButton.Click += (sender, args) => { String fileName = ((EditText) dialog.FindViewById(Resource.Id.file_filename)).Text; - onOpen(fileName); + if (onOpen(fileName)) + dialog.Dismiss(); }; // Create button @@ -241,7 +245,8 @@ namespace keepass2android createButton.Click += (sender, args) => { String fileName = ((EditText)dialog.FindViewById(Resource.Id.file_filename)).Text; - onCreate(fileName); + if (onCreate(fileName)) + dialog.Dismiss(); }; Button cancelButton = (Button) dialog.FindViewById(Resource.Id.fnv_cancel); @@ -261,6 +266,32 @@ namespace keepass2android }; } + + public static void QueryCredentials(IOConnectionInfo ioc, Action afterQueryCredentials, Activity activity) + { + //Build dialog to query credentials: + AlertDialog.Builder builder = new AlertDialog.Builder(activity); + builder.SetTitle(activity.GetString(Resource.String.credentials_dialog_title)); + builder.SetPositiveButton(activity.GetString(Android.Resource.String.Ok), (dlgSender, dlgEvt) => + { + Dialog dlg = (Dialog)dlgSender; + string username = ((EditText)dlg.FindViewById(Resource.Id.cred_username)).Text; + string password = ((EditText)dlg.FindViewById(Resource.Id.cred_password)).Text; + int credentialRememberMode = ((Spinner)dlg.FindViewById(Resource.Id.cred_remember_mode)).SelectedItemPosition; + ioc.UserName = username; + ioc.Password = password; + ioc.CredSaveMode = (IOCredSaveMode)credentialRememberMode; + afterQueryCredentials(ioc); + }); + builder.SetView(activity.LayoutInflater.Inflate(Resource.Layout.url_credentials, null)); + builder.SetNeutralButton(activity.GetString(Android.Resource.String.Cancel), + (dlgSender, dlgEvt) => { }); + Dialog dialog = builder.Create(); + dialog.Show(); + ((EditText)dialog.FindViewById(Resource.Id.cred_username)).Text = ioc.UserName; + ((EditText)dialog.FindViewById(Resource.Id.cred_password)).Text = ioc.Password; + ((Spinner)dialog.FindViewById(Resource.Id.cred_remember_mode)).SetSelection((int)ioc.CredSaveMode); + } } } diff --git a/src/keepass2android/fileselect/FileSelectActivity.cs b/src/keepass2android/fileselect/FileSelectActivity.cs index 65dce0e3..613bfac0 100644 --- a/src/keepass2android/fileselect/FileSelectActivity.cs +++ b/src/keepass2android/fileselect/FileSelectActivity.cs @@ -236,29 +236,7 @@ namespace keepass2android if (fileStorage.RequiresCredentials(ioc)) { - //Build dialog to query credentials: - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.SetTitle(GetString(Resource.String.credentials_dialog_title)); - builder.SetPositiveButton(GetString(Android.Resource.String.Ok), (dlgSender, dlgEvt) => - { - Dialog dlg = (Dialog)dlgSender; - string username = ((EditText)dlg.FindViewById(Resource.Id.cred_username)).Text; - string password = ((EditText)dlg.FindViewById(Resource.Id.cred_password)).Text; - int credentialRememberMode = ((Spinner)dlg.FindViewById(Resource.Id.cred_remember_mode)).SelectedItemPosition; - ioc.UserName = username; - ioc.Password = password; - ioc.CredSaveMode = (IOCredSaveMode)credentialRememberMode; - PasswordActivity.Launch(this, ioc, AppTask); - Finish(); - }); - builder.SetView(LayoutInflater.Inflate(Resource.Layout.url_credentials, null)); - builder.SetNeutralButton(GetString(Android.Resource.String.Cancel), - (dlgSender, dlgEvt) => {}); - Dialog dialog = builder.Create(); - dialog.Show(); - ((EditText)dialog.FindViewById(Resource.Id.cred_username)).Text = ioc.UserName; - ((EditText)dialog.FindViewById(Resource.Id.cred_password)).Text = ioc.Password; - ((Spinner)dialog.FindViewById(Resource.Id.cred_remember_mode)).SetSelection((int)ioc.CredSaveMode); + Util.QueryCredentials(ioc, AfterQueryCredentials, this); } else { @@ -272,7 +250,15 @@ namespace keepass2android } } } + + + private void AfterQueryCredentials(IOConnectionInfo ioc) + { + PasswordActivity.Launch(this, ioc, AppTask); + Finish(); + } + protected override void OnListItemClick(ListView l, View v, int position, long id) { base.OnListItemClick(l, v, position, id); @@ -284,7 +270,7 @@ namespace keepass2android App.Kp2a.GetFileStorage(ioc) .PrepareFileUsage(new FileStorageSetupInitiatorActivity(this, OnActivityResult, null), ioc, 0, false); } - private void OnOpenButton(String fileName) + private bool OnOpenButton(String fileName) { IOConnectionInfo ioc = new IOConnectionInfo @@ -293,7 +279,9 @@ namespace keepass2android }; LaunchPasswordActivityForIoc(ioc); - + + return true; + } protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) diff --git a/src/keepass2android/keepass2android.csproj b/src/keepass2android/keepass2android.csproj index 76203524..6f20ace0 100644 --- a/src/keepass2android/keepass2android.csproj +++ b/src/keepass2android/keepass2android.csproj @@ -29,7 +29,7 @@ full False bin\Debug - DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;EXCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE + DEBUG;EXCLUDE_TWOFISH;INCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;INCLUDE_FILECHOOSER;INCLUDE_JAVAFILESTORAGE prompt 4 False