mirror of
https://github.com/moparisthebest/keepass2android
synced 2024-12-22 06:58:50 -05:00
move duplicated file-browsing code to FileSelectHelper
This commit is contained in:
parent
53877a16a9
commit
86bfae57c3
@ -62,8 +62,8 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool isForSave = (requestCode == RequestCodeFileStorageSelectionForPrimarySelect) ?
|
bool isForSave = (requestCode != RequestCodeFileStorageSelectionForPrimarySelect)
|
||||||
IsStorageSelectionForSave : true;
|
|| IsStorageSelectionForSave;
|
||||||
|
|
||||||
|
|
||||||
StartSelectFile(isForSave, browseRequestCode, protocolId);
|
StartSelectFile(isForSave, browseRequestCode, protocolId);
|
||||||
@ -85,8 +85,8 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
IOConnectionInfo ioc = new IOConnectionInfo();
|
IOConnectionInfo ioc = new IOConnectionInfo();
|
||||||
SetIoConnectionFromIntent(ioc, data);
|
SetIoConnectionFromIntent(ioc, data);
|
||||||
bool isForSave = (requestCode == RequestCodeFileFileBrowseForWritableLocation) ?
|
bool isForSave = (requestCode == RequestCodeFileFileBrowseForWritableLocation)
|
||||||
true : IsStorageSelectionForSave;
|
|| IsStorageSelectionForSave;
|
||||||
|
|
||||||
StartFileChooser(ioc.Path, requestCode, isForSave);
|
StartFileChooser(ioc.Path, requestCode, isForSave);
|
||||||
|
|
||||||
@ -164,6 +164,8 @@ namespace keepass2android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract void StartFileChooser(string path, int requestCode, bool isForSave);
|
||||||
|
|
||||||
protected abstract void ShowToast(string text);
|
protected abstract void ShowToast(string text);
|
||||||
|
|
||||||
protected abstract void ShowInvalidSchemeMessage(string dataString);
|
protected abstract void ShowInvalidSchemeMessage(string dataString);
|
||||||
@ -187,7 +189,7 @@ namespace keepass2android
|
|||||||
protected abstract bool IsStorageSelectionForSave { get; }
|
protected abstract bool IsStorageSelectionForSave { get; }
|
||||||
|
|
||||||
|
|
||||||
private void IocSelected(IOConnectionInfo ioc, int requestCode)
|
protected void IocSelected(IOConnectionInfo ioc, int requestCode)
|
||||||
{
|
{
|
||||||
if (requestCode == RequestCodeFileFileBrowseForWritableLocation)
|
if (requestCode == RequestCodeFileFileBrowseForWritableLocation)
|
||||||
{
|
{
|
||||||
@ -245,44 +247,6 @@ namespace keepass2android
|
|||||||
protected abstract void StartFileStorageSelection(int requestCode,
|
protected abstract void StartFileStorageSelection(int requestCode,
|
||||||
bool allowThirdPartyGet, bool allowThirdPartySend);
|
bool allowThirdPartyGet, bool allowThirdPartySend);
|
||||||
|
|
||||||
protected bool OnReceivedSftpData(string filename, int requestCode, bool isForSave)
|
|
||||||
{
|
|
||||||
IOConnectionInfo ioc = new IOConnectionInfo { Path = filename };
|
|
||||||
#if !EXCLUDE_FILECHOOSER
|
|
||||||
StartFileChooser(ioc.Path, requestCode, isForSave);
|
|
||||||
#else
|
|
||||||
IocSelected(ioc, requestCode);
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void StartFileChooser(string path, int requestCode, bool isForSave);
|
|
||||||
|
|
||||||
protected bool OnOpenButton(string fileName, int requestCode, Action dismissDialog)
|
|
||||||
{
|
|
||||||
|
|
||||||
IOConnectionInfo ioc = new IOConnectionInfo
|
|
||||||
{
|
|
||||||
Path = fileName
|
|
||||||
};
|
|
||||||
|
|
||||||
int lastSlashPos = fileName.LastIndexOf('/');
|
|
||||||
int lastDotPos = fileName.LastIndexOf('.');
|
|
||||||
if (lastSlashPos >= lastDotPos) //no dot after last slash or == in case neither / nor .
|
|
||||||
{
|
|
||||||
ShowFilenameWarning(fileName, () => { IocSelected(ioc, requestCode); dismissDialog(); }, () => { /* don't do anything, leave dialog open, let user try again*/ });
|
|
||||||
//signal that the dialog should be kept open
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
IocSelected(ioc, requestCode);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void ShowFilenameWarning(string fileName, Action onUserWantsToContinue, Action onUserWantsToCorrect);
|
|
||||||
|
|
||||||
|
|
||||||
protected virtual void CopyFile(IOConnectionInfo targetIoc, IOConnectionInfo sourceIoc)
|
protected virtual void CopyFile(IOConnectionInfo targetIoc, IOConnectionInfo sourceIoc)
|
||||||
{
|
{
|
||||||
|
@ -111,7 +111,7 @@ namespace keepass2android
|
|||||||
defaulFilename = "file://" + defaulFilename;
|
defaulFilename = "file://" + defaulFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
StartFileChooser(defaulFilename, RequestCodeKeyFile, false);
|
new FileSelectHelper(this, false, RequestCodeKeyFile).StartFileChooser(defaulFilename);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -244,28 +244,6 @@ namespace keepass2android
|
|||||||
_restoringInstanceState = false;
|
_restoringInstanceState = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartFileChooser(string defaultPath, int requestCode, bool forSave)
|
|
||||||
{
|
|
||||||
#if !EXCLUDE_FILECHOOSER
|
|
||||||
Kp2aLog.Log("FSA: defaultPath=" + defaultPath);
|
|
||||||
string fileProviderAuthority = FileChooserFileProvider.TheAuthority;
|
|
||||||
if (defaultPath.StartsWith("file://"))
|
|
||||||
{
|
|
||||||
fileProviderAuthority = "keepass2android."+AppNames.PackagePart+".android-filechooser.localfile";
|
|
||||||
}
|
|
||||||
Intent i = Keepass2android.Kp2afilechooser.Kp2aFileChooserBridge.GetLaunchFileChooserIntent(this, fileProviderAuthority,
|
|
||||||
defaultPath);
|
|
||||||
|
|
||||||
if (forSave)
|
|
||||||
{
|
|
||||||
i.PutExtra("group.pals.android.lib.ui.filechooser.FileChooserActivity.save_dialog", true);
|
|
||||||
i.PutExtra("group.pals.android.lib.ui.filechooser.FileChooserActivity.default_file_ext", "kdbx");
|
|
||||||
}
|
|
||||||
|
|
||||||
StartActivityForResult(i, requestCode);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void UpdateIocView()
|
private void UpdateIocView()
|
||||||
{
|
{
|
||||||
@ -343,17 +321,20 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
App.Kp2a.GetFileStorage(protocolId).StartSelectFile(new FileStorageSetupInitiatorActivity(this,
|
FileSelectHelper fileSelectHelper = new FileSelectHelper(this, true, RequestCodeDbFilename)
|
||||||
OnActivityResult,
|
|
||||||
defaultPath =>
|
|
||||||
{
|
{
|
||||||
if (defaultPath.StartsWith("sftp://"))
|
DefaultExtension = "kdbx"
|
||||||
Util.ShowSftpDialog(this, OnReceiveSftpData, () => { });
|
};
|
||||||
else
|
fileSelectHelper.OnOpen += (sender, info) =>
|
||||||
Util.ShowFilenameDialog(this, OnCreateButton, null, null, false, defaultPath, GetString(Resource.String.enter_filename_details_url),
|
{
|
||||||
Intents.RequestCodeFileBrowseForOpen);
|
_ioc = info;
|
||||||
}
|
UpdateIocView();
|
||||||
), true, RequestCodeDbFilename, protocolId);
|
};
|
||||||
|
App.Kp2a.GetFileStorage(protocolId).StartSelectFile(
|
||||||
|
new FileStorageSetupInitiatorActivity(this,OnActivityResult,s => fileSelectHelper.PerformManualFileSelect(s)),
|
||||||
|
true,
|
||||||
|
RequestCodeDbFilename,
|
||||||
|
protocolId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -436,16 +417,14 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
IOConnectionInfo ioc = new IOConnectionInfo();
|
IOConnectionInfo ioc = new IOConnectionInfo();
|
||||||
PasswordActivity.SetIoConnectionFromIntent(ioc, data);
|
PasswordActivity.SetIoConnectionFromIntent(ioc, data);
|
||||||
StartFileChooser(ioc.Path, RequestCodeDbFilename, true);
|
|
||||||
|
new FileSelectHelper(this, true, RequestCodeDbFilename) { DefaultExtension = "kdbx" }
|
||||||
|
.StartFileChooser(ioc.Path);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool OnReceiveSftpData(string filename)
|
|
||||||
{
|
|
||||||
StartFileChooser(filename, RequestCodeDbFilename, true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string ConvertFilenameToIocPath(string filename)
|
private static string ConvertFilenameToIocPath(string filename)
|
||||||
{
|
{
|
||||||
@ -457,86 +436,6 @@ namespace keepass2android
|
|||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool OnCreateButton(string filename, Dialog dialog)
|
|
||||||
{
|
|
||||||
// Make sure file name exists
|
|
||||||
if (filename.Length == 0)
|
|
||||||
{
|
|
||||||
Toast.MakeText(this,
|
|
||||||
Resource.String.error_filename_required,
|
|
||||||
ToastLength.Long).Show();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
IOConnectionInfo ioc = new IOConnectionInfo { Path = filename };
|
|
||||||
IFileStorage fileStorage;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
fileStorage = App.Kp2a.GetFileStorage(ioc);
|
|
||||||
}
|
|
||||||
catch (NoFileStorageFoundException)
|
|
||||||
{
|
|
||||||
Toast.MakeText(this,
|
|
||||||
"Unexpected scheme in "+filename,
|
|
||||||
ToastLength.Long).Show();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ioc.IsLocalFile())
|
|
||||||
{
|
|
||||||
// Try to create the file
|
|
||||||
File file = new File(filename);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File parent = file.ParentFile;
|
|
||||||
|
|
||||||
if (parent == null || (parent.Exists() && !parent.IsDirectory))
|
|
||||||
{
|
|
||||||
Toast.MakeText(this,
|
|
||||||
Resource.String.error_invalid_path,
|
|
||||||
ToastLength.Long).Show();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!parent.Exists())
|
|
||||||
{
|
|
||||||
// Create parent dircetory
|
|
||||||
if (!parent.Mkdirs())
|
|
||||||
{
|
|
||||||
Toast.MakeText(this,
|
|
||||||
Resource.String.error_could_not_create_parent,
|
|
||||||
ToastLength.Long).Show();
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
System.IO.File.Create(filename);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (IOException ex)
|
|
||||||
{
|
|
||||||
Toast.MakeText(
|
|
||||||
this,
|
|
||||||
GetText(Resource.String.error_file_not_create) + " "
|
|
||||||
+ ex.LocalizedMessage,
|
|
||||||
ToastLength.Long).Show();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (fileStorage.RequiresCredentials(ioc))
|
|
||||||
{
|
|
||||||
Util.QueryCredentials(ioc, AfterQueryCredentials, this);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_ioc = ioc;
|
|
||||||
UpdateIocView();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AfterQueryCredentials(IOConnectionInfo ioc)
|
private void AfterQueryCredentials(IOConnectionInfo ioc)
|
||||||
{
|
{
|
||||||
|
@ -62,17 +62,19 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
App.Kp2a.GetFileStorage(protocolId).StartSelectFile(new FileStorageSetupInitiatorActivity(this,
|
FileSelectHelper fileSelectHelper = new FileSelectHelper(this, true, RequestCodeDbFilename)
|
||||||
OnActivityResult,
|
|
||||||
defaultPath =>
|
|
||||||
{
|
{
|
||||||
if (defaultPath.StartsWith("sftp://"))
|
DefaultExtension = _ffp[_fileFormatIndex].DefaultExtension
|
||||||
Util.ShowSftpDialog(this, OnReceiveSftpData, () => { });
|
};
|
||||||
else
|
fileSelectHelper.OnOpen += (sender, ioc) =>
|
||||||
Util.ShowFilenameDialog(this, OnCreateButton, null, null, false, defaultPath, GetString(Resource.String.enter_filename_details_url),
|
{
|
||||||
Intents.RequestCodeFileBrowseForOpen);
|
ExportTo(ioc);
|
||||||
}
|
};
|
||||||
), true, RequestCodeDbFilename, protocolId);
|
App.Kp2a.GetFileStorage(protocolId).StartSelectFile(
|
||||||
|
new FileStorageSetupInitiatorActivity(this, OnActivityResult, s => fileSelectHelper.PerformManualFileSelect(s)),
|
||||||
|
true,
|
||||||
|
RequestCodeDbFilename,
|
||||||
|
protocolId);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -149,7 +151,9 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
IOConnectionInfo ioc = new IOConnectionInfo();
|
IOConnectionInfo ioc = new IOConnectionInfo();
|
||||||
PasswordActivity.SetIoConnectionFromIntent(ioc, data);
|
PasswordActivity.SetIoConnectionFromIntent(ioc, data);
|
||||||
StartFileChooser(ioc.Path, RequestCodeDbFilename, true);
|
new FileSelectHelper(this, true, RequestCodeDbFilename)
|
||||||
|
{ DefaultExtension = _ffp[_fileFormatIndex].DefaultExtension}
|
||||||
|
.StartFileChooser(ioc.Path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Finish();
|
Finish();
|
||||||
@ -176,39 +180,6 @@ namespace keepass2android
|
|||||||
get { return 0; }
|
get { return 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool OnCreateButton(string filename, Dialog dialog)
|
|
||||||
{
|
|
||||||
if (filename.Length == 0)
|
|
||||||
{
|
|
||||||
Toast.MakeText(this,
|
|
||||||
Resource.String.error_filename_required,
|
|
||||||
ToastLength.Long).Show();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
IOConnectionInfo ioc = new IOConnectionInfo { Path = filename };
|
|
||||||
try
|
|
||||||
{
|
|
||||||
App.Kp2a.GetFileStorage(ioc);
|
|
||||||
}
|
|
||||||
catch (NoFileStorageFoundException)
|
|
||||||
{
|
|
||||||
Toast.MakeText(this,
|
|
||||||
"Unexpected scheme in " + filename,
|
|
||||||
ToastLength.Long).Show();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ExportTo(new IOConnectionInfo() { Path = filename });
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool OnReceiveSftpData(string filename)
|
|
||||||
{
|
|
||||||
StartFileChooser(filename, RequestCodeDbFilename, true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string ConvertFilenameToIocPath(string filename)
|
private static string ConvertFilenameToIocPath(string filename)
|
||||||
{
|
{
|
||||||
if ((filename != null) && (filename.StartsWith("file://")))
|
if ((filename != null) && (filename.StartsWith("file://")))
|
||||||
@ -219,29 +190,6 @@ namespace keepass2android
|
|||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartFileChooser(string defaultPath, int requestCode, bool forSave)
|
|
||||||
{
|
|
||||||
#if !EXCLUDE_FILECHOOSER
|
|
||||||
Kp2aLog.Log("FSA: defaultPath=" + defaultPath);
|
|
||||||
string fileProviderAuthority = FileChooserFileProvider.TheAuthority;
|
|
||||||
if (defaultPath.StartsWith("file://"))
|
|
||||||
{
|
|
||||||
fileProviderAuthority = "keepass2android."+AppNames.PackagePart+".android-filechooser.localfile";
|
|
||||||
}
|
|
||||||
Intent i = Keepass2android.Kp2afilechooser.Kp2aFileChooserBridge.GetLaunchFileChooserIntent(this, fileProviderAuthority,
|
|
||||||
defaultPath);
|
|
||||||
|
|
||||||
if (forSave)
|
|
||||||
{
|
|
||||||
i.PutExtra("group.pals.android.lib.ui.filechooser.FileChooserActivity.save_dialog", true);
|
|
||||||
i.PutExtra("group.pals.android.lib.ui.filechooser.FileChooserActivity.default_file_ext", _ffp[_fileFormatIndex].DefaultExtension);
|
|
||||||
}
|
|
||||||
|
|
||||||
StartActivityForResult(i, requestCode);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ExportDb : RunnableOnFinish
|
public class ExportDb : RunnableOnFinish
|
||||||
{
|
{
|
||||||
private readonly IKp2aApp _app;
|
private readonly IKp2aApp _app;
|
||||||
|
242
src/keepass2android/FileSelectHelper.cs
Normal file
242
src/keepass2android/FileSelectHelper.cs
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
using Android.App;
|
||||||
|
using Android.Content;
|
||||||
|
using Android.OS;
|
||||||
|
using Android.Runtime;
|
||||||
|
using Android.Views;
|
||||||
|
using Android.Widget;
|
||||||
|
using Java.IO;
|
||||||
|
using keepass2android.Io;
|
||||||
|
using KeePassLib.Serialization;
|
||||||
|
using KeePassLib.Utility;
|
||||||
|
|
||||||
|
namespace keepass2android
|
||||||
|
{
|
||||||
|
public class FileSelectHelper
|
||||||
|
{
|
||||||
|
private readonly Activity _activity;
|
||||||
|
private readonly bool _isForSave;
|
||||||
|
private readonly int _requestCode;
|
||||||
|
|
||||||
|
public string DefaultExtension { get; set; }
|
||||||
|
|
||||||
|
public FileSelectHelper(Activity activity, bool isForSave, int requestCode)
|
||||||
|
{
|
||||||
|
_activity = activity;
|
||||||
|
_isForSave = isForSave;
|
||||||
|
_requestCode = requestCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowSftpDialog(Activity activity, Util.FileSelectedHandler onStartBrowse, Action onCancel)
|
||||||
|
{
|
||||||
|
#if !EXCLUDE_JAVAFILESTORAGE && !NoNet
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||||
|
View dlgContents = activity.LayoutInflater.Inflate(Resource.Layout.sftpcredentials, null);
|
||||||
|
builder.SetView(dlgContents);
|
||||||
|
builder.SetPositiveButton(Android.Resource.String.Ok,
|
||||||
|
(sender, args) =>
|
||||||
|
{
|
||||||
|
string host = dlgContents.FindViewById<EditText>(Resource.Id.sftp_host).Text;
|
||||||
|
string portText = dlgContents.FindViewById<EditText>(Resource.Id.sftp_port).Text;
|
||||||
|
int port = Keepass2android.Javafilestorage.SftpStorage.DefaultSftpPort;
|
||||||
|
if (!string.IsNullOrEmpty(portText))
|
||||||
|
int.TryParse(portText, out port);
|
||||||
|
string user = dlgContents.FindViewById<EditText>(Resource.Id.sftp_user).Text;
|
||||||
|
string password = dlgContents.FindViewById<EditText>(Resource.Id.sftp_password).Text;
|
||||||
|
string initialPath = dlgContents.FindViewById<EditText>(Resource.Id.sftp_initial_dir).Text;
|
||||||
|
string sftpPath = new Keepass2android.Javafilestorage.SftpStorage().BuildFullPath(host, port, initialPath, user,
|
||||||
|
password);
|
||||||
|
onStartBrowse(sftpPath);
|
||||||
|
});
|
||||||
|
EventHandler<DialogClickEventArgs> evtH = new EventHandler<DialogClickEventArgs>((sender, e) => onCancel());
|
||||||
|
|
||||||
|
builder.SetNegativeButton(Android.Resource.String.Cancel, evtH);
|
||||||
|
builder.SetTitle(activity.GetString(Resource.String.enter_sftp_login_title));
|
||||||
|
Dialog dialog = builder.Create();
|
||||||
|
|
||||||
|
dialog.Show();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PerformManualFileSelect(string defaultPath)
|
||||||
|
{
|
||||||
|
if (defaultPath.StartsWith("sftp://"))
|
||||||
|
ShowSftpDialog(_activity, StartFileChooser, ReturnCancel);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Func<string, Dialog, bool> onOpen = (filename, dialog) => OnOpenButton(filename, dialog);
|
||||||
|
Util.ShowFilenameDialog(_activity,
|
||||||
|
!_isForSave ? onOpen : null,
|
||||||
|
_isForSave ? onOpen : null,
|
||||||
|
ReturnCancel,
|
||||||
|
false,
|
||||||
|
defaultPath,
|
||||||
|
_activity.GetString(Resource.String.enter_filename_details_url),
|
||||||
|
_requestCode)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReturnCancel()
|
||||||
|
{
|
||||||
|
if (OnCancel != null)
|
||||||
|
OnCancel(this, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void ShowFilenameWarning(string fileName, Action onUserWantsToContinue, Action onUserWantsToCorrect)
|
||||||
|
{
|
||||||
|
new AlertDialog.Builder(_activity)
|
||||||
|
.SetPositiveButton(keepass2android.Resource.String.Continue, delegate { onUserWantsToContinue(); })
|
||||||
|
.SetMessage(Resource.String.NoFilenameWarning)
|
||||||
|
.SetCancelable(false)
|
||||||
|
.SetNegativeButton(Android.Resource.String.Cancel, delegate { onUserWantsToCorrect(); })
|
||||||
|
.Create()
|
||||||
|
.Show();
|
||||||
|
|
||||||
|
}
|
||||||
|
private bool OnOpenButton(string filename, Dialog dialog)
|
||||||
|
{
|
||||||
|
|
||||||
|
IOConnectionInfo ioc = new IOConnectionInfo
|
||||||
|
{
|
||||||
|
Path = filename
|
||||||
|
};
|
||||||
|
|
||||||
|
// Make sure file name exists
|
||||||
|
if (filename.Length == 0)
|
||||||
|
{
|
||||||
|
Toast.MakeText(_activity,
|
||||||
|
Resource.String.error_filename_required,
|
||||||
|
ToastLength.Long).Show();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int lastSlashPos = filename.LastIndexOf('/');
|
||||||
|
int lastDotPos = filename.LastIndexOf('.');
|
||||||
|
if (lastSlashPos >= lastDotPos) //no dot after last slash or == in case neither / nor .
|
||||||
|
{
|
||||||
|
ShowFilenameWarning(filename, () => { IocSelected(ioc); dialog.Dismiss(); }, () => { /* don't do anything, leave dialog open, let user try again*/ });
|
||||||
|
//signal that the dialog should be kept open
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IFileStorage fileStorage;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fileStorage = App.Kp2a.GetFileStorage(ioc);
|
||||||
|
}
|
||||||
|
catch (NoFileStorageFoundException)
|
||||||
|
{
|
||||||
|
Toast.MakeText(_activity,
|
||||||
|
"Unexpected scheme in "+filename,
|
||||||
|
ToastLength.Long).Show();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_isForSave && ioc.IsLocalFile())
|
||||||
|
{
|
||||||
|
// Try to create the file
|
||||||
|
File file = new File(filename);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File parent = file.ParentFile;
|
||||||
|
|
||||||
|
if (parent == null || (parent.Exists() && !parent.IsDirectory))
|
||||||
|
{
|
||||||
|
Toast.MakeText(_activity,
|
||||||
|
Resource.String.error_invalid_path,
|
||||||
|
ToastLength.Long).Show();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parent.Exists())
|
||||||
|
{
|
||||||
|
// Create parent dircetory
|
||||||
|
if (!parent.Mkdirs())
|
||||||
|
{
|
||||||
|
Toast.MakeText(_activity,
|
||||||
|
Resource.String.error_could_not_create_parent,
|
||||||
|
ToastLength.Long).Show();
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.IO.File.Create(filename);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
Toast.MakeText(
|
||||||
|
_activity,
|
||||||
|
_activity.GetText(Resource.String.error_file_not_create) + " "
|
||||||
|
+ ex.LocalizedMessage,
|
||||||
|
ToastLength.Long).Show();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (fileStorage.RequiresCredentials(ioc))
|
||||||
|
{
|
||||||
|
Util.QueryCredentials(ioc, IocSelected, _activity);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IocSelected(ioc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void IocSelected(IOConnectionInfo ioc)
|
||||||
|
{
|
||||||
|
if (OnOpen != null)
|
||||||
|
OnOpen(this, ioc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool StartFileChooser(string defaultPath)
|
||||||
|
{
|
||||||
|
#if !EXCLUDE_FILECHOOSER
|
||||||
|
Kp2aLog.Log("FSA: defaultPath=" + defaultPath);
|
||||||
|
string fileProviderAuthority = FileChooserFileProvider.TheAuthority;
|
||||||
|
if (defaultPath.StartsWith("file://"))
|
||||||
|
{
|
||||||
|
fileProviderAuthority = _activity.PackageName + ".android-filechooser.localfile";
|
||||||
|
}
|
||||||
|
Intent i = Keepass2android.Kp2afilechooser.Kp2aFileChooserBridge.GetLaunchFileChooserIntent(_activity, fileProviderAuthority,
|
||||||
|
defaultPath);
|
||||||
|
|
||||||
|
|
||||||
|
if (_isForSave)
|
||||||
|
{
|
||||||
|
i.PutExtra("group.pals.android.lib.ui.filechooser.FileChooserActivity.save_dialog", true);
|
||||||
|
string ext;
|
||||||
|
if (!string.IsNullOrEmpty(DefaultExtension))
|
||||||
|
{
|
||||||
|
ext = DefaultExtension;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ext = UrlUtil.GetExtension(defaultPath);
|
||||||
|
}
|
||||||
|
if ((ext != String.Empty) && (ext.Contains("?") == false))
|
||||||
|
i.PutExtra("group.pals.android.lib.ui.filechooser.FileChooserActivity.default_file_ext", ext);
|
||||||
|
}
|
||||||
|
_activity.StartActivityForResult(i, _requestCode);
|
||||||
|
|
||||||
|
#else
|
||||||
|
Toast.MakeText(this, "File chooser is excluded!", ToastLength.Long).Show();
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler OnCancel;
|
||||||
|
|
||||||
|
public event EventHandler<IOConnectionInfo> OnOpen;
|
||||||
|
}
|
||||||
|
}
|
@ -96,21 +96,15 @@ namespace keepass2android
|
|||||||
|
|
||||||
protected override void StartSelectFile( bool isForSave, int browseRequestCode, string protocolId)
|
protected override void StartSelectFile( bool isForSave, int browseRequestCode, string protocolId)
|
||||||
{
|
{
|
||||||
var startManualFileSelect = new Action<string>(defaultPath =>
|
FileSelectHelper fileSelectHelper = new FileSelectHelper(this, isForSave, browseRequestCode);
|
||||||
|
fileSelectHelper.OnOpen += (sender, ioc) =>
|
||||||
{
|
{
|
||||||
if (defaultPath.StartsWith("sftp://"))
|
IocSelected(ioc,browseRequestCode);
|
||||||
Util.ShowSftpDialog(this, filename => OnReceivedSftpData(filename, browseRequestCode, isForSave), ReturnCancel);
|
};
|
||||||
else
|
|
||||||
Util.ShowFilenameDialog(this,
|
|
||||||
!isForSave ? delegate(string filename, Dialog dialog) { return OnOpenButton(filename, browseRequestCode, dialog.Dismiss); } : (Func<string, Dialog, bool>) null,
|
|
||||||
isForSave ? delegate(string filename, Dialog dialog) { return OnOpenButton(filename, browseRequestCode, dialog.Dismiss); } : (Func<string, Dialog, bool>) null,
|
|
||||||
ReturnCancel, false, defaultPath, GetString(Resource.String.enter_filename_details_url),
|
|
||||||
browseRequestCode);
|
|
||||||
});
|
|
||||||
;
|
|
||||||
App.Kp2a.GetFileStorage(protocolId).StartSelectFile(new FileStorageSetupInitiatorActivity(this,
|
App.Kp2a.GetFileStorage(protocolId).StartSelectFile(new FileStorageSetupInitiatorActivity(this,
|
||||||
OnActivityResult,
|
OnActivityResult,
|
||||||
startManualFileSelect
|
s => fileSelectHelper.PerformManualFileSelect(s)
|
||||||
), isForSave, browseRequestCode, protocolId);
|
), isForSave, browseRequestCode, protocolId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,43 +193,9 @@ namespace keepass2android
|
|||||||
|
|
||||||
protected override void StartFileChooser(string defaultPath, int requestCode, bool forSave)
|
protected override void StartFileChooser(string defaultPath, int requestCode, bool forSave)
|
||||||
{
|
{
|
||||||
#if !EXCLUDE_FILECHOOSER
|
new FileSelectHelper(this, forSave, requestCode).StartFileChooser(defaultPath);
|
||||||
Kp2aLog.Log("FSA: defaultPath=" + defaultPath);
|
|
||||||
string fileProviderAuthority = FileChooserFileProvider.TheAuthority;
|
|
||||||
if (defaultPath.StartsWith("file://"))
|
|
||||||
{
|
|
||||||
fileProviderAuthority = PackageName + ".android-filechooser.localfile";
|
|
||||||
}
|
|
||||||
Intent i = Keepass2android.Kp2afilechooser.Kp2aFileChooserBridge.GetLaunchFileChooserIntent(this, fileProviderAuthority,
|
|
||||||
defaultPath);
|
|
||||||
|
|
||||||
|
|
||||||
if (forSave)
|
|
||||||
{
|
|
||||||
i.PutExtra("group.pals.android.lib.ui.filechooser.FileChooserActivity.save_dialog", true);
|
|
||||||
var ext = UrlUtil.GetExtension(defaultPath);
|
|
||||||
if ((ext != String.Empty) && (ext.Contains("?")==false))
|
|
||||||
i.PutExtra("group.pals.android.lib.ui.filechooser.FileChooserActivity.default_file_ext", ext);
|
|
||||||
}
|
|
||||||
StartActivityForResult(i, requestCode);
|
|
||||||
|
|
||||||
#else
|
|
||||||
Toast.MakeText(this, "File chooser is excluded!", ToastLength.Long).Show();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ShowFilenameWarning(string fileName, Action onUserWantsToContinue, Action onUserWantsToCorrect)
|
|
||||||
{
|
|
||||||
new AlertDialog.Builder(this)
|
|
||||||
.SetPositiveButton(Resource.String.Continue, delegate { onUserWantsToContinue(); } )
|
|
||||||
.SetMessage(Resource.String.NoFilenameWarning)
|
|
||||||
.SetCancelable(false)
|
|
||||||
.SetNegativeButton(Android.Resource.String.Cancel, delegate { onUserWantsToCorrect(); })
|
|
||||||
.Create()
|
|
||||||
.Show();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void OnDismiss(IDialogInterface dialog)
|
public void OnDismiss(IDialogInterface dialog)
|
||||||
|
@ -149,6 +149,7 @@
|
|||||||
<Compile Include="EntryActivityClasses\StandardStringView.cs" />
|
<Compile Include="EntryActivityClasses\StandardStringView.cs" />
|
||||||
<Compile Include="EntryActivityClasses\ToggleVisibilityPopupMenuItem.cs" />
|
<Compile Include="EntryActivityClasses\ToggleVisibilityPopupMenuItem.cs" />
|
||||||
<Compile Include="EntryActivityClasses\WriteBinaryToFilePopupItem.cs" />
|
<Compile Include="EntryActivityClasses\WriteBinaryToFilePopupItem.cs" />
|
||||||
|
<Compile Include="FileSelectHelper.cs" />
|
||||||
<Compile Include="FingerprintModule.cs" />
|
<Compile Include="FingerprintModule.cs" />
|
||||||
<Compile Include="FingerprintSamsungIdentifier.cs" />
|
<Compile Include="FingerprintSamsungIdentifier.cs" />
|
||||||
<Compile Include="FingerprintSetupActivity.cs" />
|
<Compile Include="FingerprintSetupActivity.cs" />
|
||||||
|
Loading…
Reference in New Issue
Block a user