mirror of
https://github.com/moparisthebest/keepass2android
synced 2024-11-22 17:22:17 -05:00
Implemented UI for sync
Fixed bugs
This commit is contained in:
parent
16c08cbe8a
commit
deeaa673a5
@ -27,10 +27,16 @@ namespace keepass2android.Io
|
|||||||
{
|
{
|
||||||
if (!ioc.IsLocalFile())
|
if (!ioc.IsLocalFile())
|
||||||
return false;
|
return false;
|
||||||
DateTime previousDate;
|
if (previousFileVersion == null)
|
||||||
if (!DateTime.TryParse(previousFileVersion, out previousDate))
|
|
||||||
return false;
|
return false;
|
||||||
return File.GetLastWriteTimeUtc(ioc.Path) > previousDate;
|
DateTime previousDate;
|
||||||
|
if (!DateTime.TryParse(previousFileVersion, CultureInfo.InvariantCulture, DateTimeStyles.None, out previousDate))
|
||||||
|
return false;
|
||||||
|
DateTime currentModificationDate = File.GetLastWriteTimeUtc(ioc.Path);
|
||||||
|
TimeSpan diff = currentModificationDate - previousDate;
|
||||||
|
return diff > TimeSpan.FromSeconds(1);
|
||||||
|
//don't use > operator because milliseconds are truncated
|
||||||
|
return File.GetLastWriteTimeUtc(ioc.Path) - previousDate >= TimeSpan.FromSeconds(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ namespace keepass2android.Io
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// Note: This function may return false even if the file might have changed. The function
|
/// Note: This function may return false even if the file might have changed. The function
|
||||||
/// should focus on being fast and cheap instead of doing things like hashing or downloading a full file.
|
/// should focus on being fast and cheap instead of doing things like hashing or downloading a full file.
|
||||||
|
/// previousFileVersion may be null to indicate no previous version is known.
|
||||||
/// <returns>Returns true if a change was detected, false otherwise.</returns>
|
/// <returns>Returns true if a change was detected, false otherwise.</returns>
|
||||||
bool CheckForFileChangeFast(IOConnectionInfo ioc , string previousFileVersion);
|
bool CheckForFileChangeFast(IOConnectionInfo ioc , string previousFileVersion);
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
_handler.Post(() =>
|
_handler.Post(() =>
|
||||||
{
|
{
|
||||||
if (String.IsNullOrEmpty(submessage))
|
if (!String.IsNullOrEmpty(submessage))
|
||||||
{
|
{
|
||||||
_progressDialog.SetMessage(_message + " (" + submessage + ")");
|
_progressDialog.SetMessage(_message + " (" + submessage + ")");
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ namespace keepass2android
|
|||||||
ParsingDatabase,
|
ParsingDatabase,
|
||||||
CheckingTargetFileForChanges,
|
CheckingTargetFileForChanges,
|
||||||
TitleSyncQuestion,
|
TitleSyncQuestion,
|
||||||
MessageSyncQuestions,
|
MessageSyncQuestion,
|
||||||
SynchronizingDatabase
|
SynchronizingDatabase
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -75,8 +75,9 @@ namespace keepass2android
|
|||||||
if (fileStorage.CheckForFileChangeFast(ioc, _app.GetDb().LastFileVersion) //first try to use the fast change detection
|
if (fileStorage.CheckForFileChangeFast(ioc, _app.GetDb().LastFileVersion) //first try to use the fast change detection
|
||||||
|| (FileHashChanged(ioc, _app.GetDb().KpDatabase.HashOfFileOnDisk))) //if that fails, hash the file and compare:
|
|| (FileHashChanged(ioc, _app.GetDb().KpDatabase.HashOfFileOnDisk))) //if that fails, hash the file and compare:
|
||||||
{
|
{
|
||||||
|
|
||||||
//ask user...
|
//ask user...
|
||||||
_app.AskYesNoCancel(UiStringKey.TitleSyncQuestion, UiStringKey.MessageSyncQuestions,
|
_app.AskYesNoCancel(UiStringKey.TitleSyncQuestion, UiStringKey.MessageSyncQuestion,
|
||||||
//yes = sync
|
//yes = sync
|
||||||
(sender, args) =>
|
(sender, args) =>
|
||||||
{
|
{
|
||||||
@ -85,7 +86,6 @@ namespace keepass2android
|
|||||||
//note: when synced, the file might be downloaded once again from the server. Caching the data
|
//note: when synced, the file might be downloaded once again from the server. Caching the data
|
||||||
//in the hashing function would solve this but increases complexity. I currently assume the files are
|
//in the hashing function would solve this but increases complexity. I currently assume the files are
|
||||||
//small.
|
//small.
|
||||||
StatusLogger.UpdateSubMessage(_app.GetResourceString(UiStringKey.SynchronizingDatabase));
|
|
||||||
MergeIn(fileStorage, ioc);
|
MergeIn(fileStorage, ioc);
|
||||||
PerformSaveWithoutCheck(fileStorage, ioc);
|
PerformSaveWithoutCheck(fileStorage, ioc);
|
||||||
Finish(true);
|
Finish(true);
|
||||||
@ -108,8 +108,6 @@ namespace keepass2android
|
|||||||
},
|
},
|
||||||
_ctx
|
_ctx
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -125,7 +123,8 @@ namespace keepass2android
|
|||||||
bSuccess = false;
|
bSuccess = false;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
Finish (false, e.ToString());
|
Kp2aLog.Log("Error while saving: "+e.ToString());
|
||||||
|
Finish (false, e.Message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,7 +137,7 @@ namespace keepass2android
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
_workerThread = new Thread(runHandler);
|
_workerThread = new Thread(runHandler);
|
||||||
_workerThread.Run();
|
_workerThread.Start();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -156,6 +155,8 @@ namespace keepass2android
|
|||||||
|
|
||||||
private void MergeIn(IFileStorage fileStorage, IOConnectionInfo ioc)
|
private void MergeIn(IFileStorage fileStorage, IOConnectionInfo ioc)
|
||||||
{
|
{
|
||||||
|
StatusLogger.UpdateSubMessage(_app.GetResourceString(UiStringKey.SynchronizingDatabase));
|
||||||
|
|
||||||
PwDatabase pwImp = new PwDatabase();
|
PwDatabase pwImp = new PwDatabase();
|
||||||
PwDatabase pwDatabase = _app.GetDb().KpDatabase;
|
PwDatabase pwDatabase = _app.GetDb().KpDatabase;
|
||||||
pwImp.New(new IOConnectionInfo(), pwDatabase.MasterKey);
|
pwImp.New(new IOConnectionInfo(), pwDatabase.MasterKey);
|
||||||
@ -170,6 +171,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
private void PerformSaveWithoutCheck(IFileStorage fileStorage, IOConnectionInfo ioc)
|
private void PerformSaveWithoutCheck(IFileStorage fileStorage, IOConnectionInfo ioc)
|
||||||
{
|
{
|
||||||
|
StatusLogger.UpdateSubMessage("");
|
||||||
_app.GetDb().SaveData(_ctx);
|
_app.GetDb().SaveData(_ctx);
|
||||||
_app.GetDb().LastFileVersion = fileStorage.GetCurrentFileVersionFast(ioc);
|
_app.GetDb().LastFileVersion = fileStorage.GetCurrentFileVersionFast(ioc);
|
||||||
}
|
}
|
||||||
|
@ -228,6 +228,14 @@ namespace Kp2aUnitTests
|
|||||||
Assert.Fail("TODO: Test ");
|
Assert.Fail("TODO: Test ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TestReloadWhenCancelSync()
|
||||||
|
{
|
||||||
|
//when a change is detected and the user cancels saving, the app should display the "file was modified - reload?" question.
|
||||||
|
Assert.Fail("TODO: Test ");
|
||||||
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void TestSaveAsWhenSyncError()
|
public void TestSaveAsWhenSyncError()
|
||||||
{
|
{
|
||||||
|
@ -42,6 +42,10 @@ namespace keepass2android
|
|||||||
if (TimeoutHelper.CheckShutdown(this, _ioc))
|
if (TimeoutHelper.CheckShutdown(this, _ioc))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
//todo: it seems like OnResume can be called after dismissing a dialog, e.g. the Delete-permanently-Dialog.
|
||||||
|
//in this case the following check might run in parallel with the check performed during the SaveDb check (triggered after the
|
||||||
|
//aforementioned dialog is closed) which can cause odd behavior. However, this is a rare case and hard to resolve so this is currently
|
||||||
|
//accepted. (If the user clicks cancel on the reload-dialog, everything will work.)
|
||||||
App.Kp2a.CheckForOpenFileChanged(this);
|
App.Kp2a.CheckForOpenFileChanged(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ namespace keepass2android
|
|||||||
if (TimeoutHelper.CheckShutdown(this, _ioc))
|
if (TimeoutHelper.CheckShutdown(this, _ioc))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
//todo: see LockCloseActivity.OnResume
|
||||||
App.Kp2a.CheckForOpenFileChanged(this);
|
App.Kp2a.CheckForOpenFileChanged(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1067
src/keepass2android/Resources/Resource.designer.cs
generated
1067
src/keepass2android/Resources/Resource.designer.cs
generated
File diff suppressed because it is too large
Load Diff
@ -61,6 +61,8 @@
|
|||||||
<string name="LastInfoVersionCode_key">LastInfoVersion</string>
|
<string name="LastInfoVersionCode_key">LastInfoVersion</string>
|
||||||
|
|
||||||
<string name="UseFileTransactions_key">UseFileTransactions</string>
|
<string name="UseFileTransactions_key">UseFileTransactions</string>
|
||||||
|
<string name="CheckForFileChangesOnSave_key">CheckForFileChangesOnSave</string>
|
||||||
|
|
||||||
<string name="MarketURL">market://details?id=</string>
|
<string name="MarketURL">market://details?id=</string>
|
||||||
<string name="SuggestionsURL">https://keepass2android.codeplex.com/workitem/list/basic</string>
|
<string name="SuggestionsURL">https://keepass2android.codeplex.com/workitem/list/basic</string>
|
||||||
<string name="TranslationURL">http://crowdin.net/project/keepass2android</string>
|
<string name="TranslationURL">http://crowdin.net/project/keepass2android</string>
|
||||||
|
@ -218,6 +218,9 @@
|
|||||||
<string name="credentials_dialog_title">Enter server credentials</string>
|
<string name="credentials_dialog_title">Enter server credentials</string>
|
||||||
<string name="UseFileTransactions_title">File transactions</string>
|
<string name="UseFileTransactions_title">File transactions</string>
|
||||||
<string name="UseFileTransactions_summary">Use file transactions for writing databases</string>
|
<string name="UseFileTransactions_summary">Use file transactions for writing databases</string>
|
||||||
|
<string name="CheckForFileChangesOnSave_title">Check for modifications</string>
|
||||||
|
<string name="CheckForFileChangesOnSave_summary">Check whether the file was modified externally before saving changes.</string>
|
||||||
|
|
||||||
<string name="ShowCopyToClipboardNotification_title">Clipboard notifications</string>
|
<string name="ShowCopyToClipboardNotification_title">Clipboard notifications</string>
|
||||||
<string name="ShowCopyToClipboardNotification_summary">Make username and password accessible through the notification bar and clipboard. Beware of password sniffers!</string>
|
<string name="ShowCopyToClipboardNotification_summary">Make username and password accessible through the notification bar and clipboard. Beware of password sniffers!</string>
|
||||||
<string name="ShowKp2aKeyboardNotification_title">KP2A keyboard notification</string>
|
<string name="ShowKp2aKeyboardNotification_title">KP2A keyboard notification</string>
|
||||||
@ -251,9 +254,23 @@
|
|||||||
<string name="DecodingDatabase">Decoding database…</string>
|
<string name="DecodingDatabase">Decoding database…</string>
|
||||||
<string name="ParsingDatabase">Parsing database…</string>
|
<string name="ParsingDatabase">Parsing database…</string>
|
||||||
<string name="CheckingTargetFileForChanges">Checking target file for changes…</string>
|
<string name="CheckingTargetFileForChanges">Checking target file for changes…</string>
|
||||||
|
<string name="TitleSyncQuestion">Merge changes?</string>
|
||||||
<string name="ChangeLog_title">Change log</string>
|
<string name="MessageSyncQuestion">The database file was modified externally. Do you want to load and merge the changes before saving? Select No if you want to overwrite the external changes.</string>
|
||||||
<string name="ChangeLog_0_8_3"><b>Version 0.8.3</b>\n
|
<string name="SynchronizingDatabase">Merging changes…</string>
|
||||||
|
|
||||||
|
<string name="ChangeLog_title">Change log</string>
|
||||||
|
<string name="ChangeLog_0_8_4">
|
||||||
|
<b>Version 0.8.4</b>\n
|
||||||
|
* External changes are detected and merged when saving\n
|
||||||
|
* Improved loading performance\n
|
||||||
|
* Improved search toolbar with suggestions\n
|
||||||
|
? New app logo!\n
|
||||||
|
? Added support for .kdbp format for faster loading/saving\n
|
||||||
|
? Improved editing of extra strings and hidden display when protected\n
|
||||||
|
Thanks to Alex Vallat for his code contributions!\n
|
||||||
|
Thanks to Niki Hüttner (www.close-cut.de) for the new logo!\n
|
||||||
|
</string>
|
||||||
|
<string name="ChangeLog_0_8_3"><b>Version 0.8.3</b>\n
|
||||||
* Username/TAN index displayed in entry list (see settings)\n
|
* Username/TAN index displayed in entry list (see settings)\n
|
||||||
* Entries can be created if search from browser doesn\'t return results\n
|
* Entries can be created if search from browser doesn\'t return results\n
|
||||||
* KP2A keyboard provides possibility to search for credentials for current app\n
|
* KP2A keyboard provides possibility to search for credentials for current app\n
|
||||||
|
@ -148,7 +148,14 @@
|
|||||||
android:summary="@string/UseFileTransactions_summary"
|
android:summary="@string/UseFileTransactions_summary"
|
||||||
android:defaultValue="true"
|
android:defaultValue="true"
|
||||||
android:title="@string/UseFileTransactions_title"
|
android:title="@string/UseFileTransactions_title"
|
||||||
android:key="@string/UseFileTransactions_key" />
|
android:key="@string/UseFileTransactions_key" />
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:enabled="true"
|
||||||
|
android:persistent="true"
|
||||||
|
android:summary="@string/CheckForFileChangesOnSave_summary"
|
||||||
|
android:defaultValue="true"
|
||||||
|
android:title="@string/CheckForFileChangesOnSave_title"
|
||||||
|
android:key="@string/CheckForFileChangesOnSave_key" />
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
@ -103,6 +103,8 @@ namespace keepass2android
|
|||||||
return prefs.GetBoolean(ctx.Resources.GetString(Resource.String.keyfile_key), ctx.Resources.GetBoolean(Resource.Boolean.keyfile_default));
|
return prefs.GetBoolean(ctx.Resources.GetString(Resource.String.keyfile_key), ctx.Resources.GetBoolean(Resource.Boolean.keyfile_default));
|
||||||
case PreferenceKey.UseFileTransactions:
|
case PreferenceKey.UseFileTransactions:
|
||||||
return prefs.GetBoolean(ctx.Resources.GetString(Resource.String.UseFileTransactions_key), true);
|
return prefs.GetBoolean(ctx.Resources.GetString(Resource.String.UseFileTransactions_key), true);
|
||||||
|
case PreferenceKey.CheckForFileChangesOnSave:
|
||||||
|
return prefs.GetBoolean(ctx.Resources.GetString(Resource.String.CheckForFileChangesOnSave_key), true);
|
||||||
default:
|
default:
|
||||||
throw new Exception("unexpected key!");
|
throw new Exception("unexpected key!");
|
||||||
}
|
}
|
||||||
@ -163,22 +165,25 @@ namespace keepass2android
|
|||||||
EventHandler<DialogClickEventArgs> cancelHandler,
|
EventHandler<DialogClickEventArgs> cancelHandler,
|
||||||
Context ctx)
|
Context ctx)
|
||||||
{
|
{
|
||||||
|
Handler handler = new Handler(Looper.MainLooper);
|
||||||
|
handler.Post(() =>
|
||||||
|
{
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
|
||||||
|
builder.SetTitle(GetResourceString(titleKey));
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
|
builder.SetMessage(GetResourceString(messageKey));
|
||||||
builder.SetTitle(GetResourceString(titleKey));
|
|
||||||
|
|
||||||
builder.SetMessage(GetResourceString(messageKey));
|
builder.SetPositiveButton(Resource.String.yes, yesHandler);
|
||||||
|
|
||||||
builder.SetPositiveButton(Resource.String.yes, yesHandler);
|
builder.SetNegativeButton(Resource.String.no, noHandler);
|
||||||
|
|
||||||
builder.SetNegativeButton(Resource.String.no, noHandler);
|
builder.SetNeutralButton(ctx.GetString(Android.Resource.String.Cancel),
|
||||||
|
cancelHandler);
|
||||||
builder.SetNeutralButton(ctx.GetString(Android.Resource.String.Cancel),
|
|
||||||
cancelHandler);
|
|
||||||
|
|
||||||
Dialog dialog = builder.Create();
|
|
||||||
dialog.Show();
|
|
||||||
|
|
||||||
|
Dialog dialog = builder.Create();
|
||||||
|
dialog.Show();
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Handler UiThreadHandler
|
public Handler UiThreadHandler
|
||||||
|
@ -371,7 +371,9 @@
|
|||||||
</AndroidResource>
|
</AndroidResource>
|
||||||
<AndroidResource Include="Resources\xml\preferences.xml" />
|
<AndroidResource Include="Resources\xml\preferences.xml" />
|
||||||
<AndroidResource Include="Resources\xml\searchable.xml" />
|
<AndroidResource Include="Resources\xml\searchable.xml" />
|
||||||
<AndroidResource Include="Resources\values\strings.xml" />
|
<AndroidResource Include="Resources\values\strings.xml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</AndroidResource>
|
||||||
<AndroidResource Include="Resources\menu-v11\entry.xml" />
|
<AndroidResource Include="Resources\menu-v11\entry.xml" />
|
||||||
<AndroidResource Include="Resources\menu-v11\password.xml" />
|
<AndroidResource Include="Resources\menu-v11\password.xml" />
|
||||||
<AndroidResource Include="Resources\menu-v11\entry_edit.xml" />
|
<AndroidResource Include="Resources\menu-v11\entry_edit.xml" />
|
||||||
|
Loading…
Reference in New Issue
Block a user