mirror of
https://github.com/moparisthebest/keepass2android
synced 2024-11-26 03:02:24 -05:00
added offline mode
This commit is contained in:
parent
d2850f5ea6
commit
ec4fe32b29
@ -54,19 +54,21 @@ namespace keepass2android.Io
|
||||
void LoadedFromRemoteInSync(IOConnectionInfo ioc);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Implements the IFileStorage interface as a proxy: A base storage is used as a remote storage. Local files are used to cache the
|
||||
/// files on remote.
|
||||
/// </summary>
|
||||
public class CachingFileStorage: IFileStorage
|
||||
public class CachingFileStorage : IFileStorage, IOfflineSwitchable
|
||||
{
|
||||
protected readonly IFileStorage _cachedStorage;
|
||||
|
||||
protected readonly OfflineSwitchableFileStorage _cachedStorage;
|
||||
private readonly ICacheSupervisor _cacheSupervisor;
|
||||
private readonly string _streamCacheDir;
|
||||
|
||||
public CachingFileStorage(IFileStorage cachedStorage, string cacheDir, ICacheSupervisor cacheSupervisor)
|
||||
{
|
||||
_cachedStorage = cachedStorage;
|
||||
_cachedStorage = new OfflineSwitchableFileStorage(cachedStorage);
|
||||
_cacheSupervisor = cacheSupervisor;
|
||||
_streamCacheDir = cacheDir + Java.IO.File.Separator + "OfflineCache" + Java.IO.File.Separator;
|
||||
if (!Directory.Exists(_streamCacheDir))
|
||||
@ -610,5 +612,11 @@ namespace keepass2android.Io
|
||||
return File.OpenRead(CachedFilePath(ioc));
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsOffline
|
||||
{
|
||||
get { return _cachedStorage.IsOffline; }
|
||||
set { _cachedStorage.IsOffline = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
191
src/Kp2aBusinessLogic/Io/OfflineSwitchableFileStorage.cs
Normal file
191
src/Kp2aBusinessLogic/Io/OfflineSwitchableFileStorage.cs
Normal file
@ -0,0 +1,191 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using KeePassLib.Serialization;
|
||||
|
||||
namespace keepass2android.Io
|
||||
{
|
||||
public interface IOfflineSwitchable
|
||||
{
|
||||
bool IsOffline { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encapsulates another IFileStorage. Allows to switch to offline mode by throwing
|
||||
/// an exception when trying to read or write a file.
|
||||
/// </summary>
|
||||
public class OfflineSwitchableFileStorage : IFileStorage, IOfflineSwitchable
|
||||
{
|
||||
private readonly IFileStorage _baseStorage;
|
||||
public bool IsOffline { get; set; }
|
||||
|
||||
public OfflineSwitchableFileStorage(IFileStorage baseStorage)
|
||||
{
|
||||
_baseStorage = baseStorage;
|
||||
}
|
||||
|
||||
public IEnumerable<string> SupportedProtocols
|
||||
{
|
||||
get { return _baseStorage.SupportedProtocols; }
|
||||
}
|
||||
|
||||
public void Delete(IOConnectionInfo ioc)
|
||||
{
|
||||
_baseStorage.Delete(ioc);
|
||||
}
|
||||
|
||||
public bool CheckForFileChangeFast(IOConnectionInfo ioc, string previousFileVersion)
|
||||
{
|
||||
return _baseStorage.CheckForFileChangeFast(ioc, previousFileVersion);
|
||||
}
|
||||
|
||||
public string GetCurrentFileVersionFast(IOConnectionInfo ioc)
|
||||
{
|
||||
return _baseStorage.GetCurrentFileVersionFast(ioc);
|
||||
}
|
||||
|
||||
public Stream OpenFileForRead(IOConnectionInfo ioc)
|
||||
{
|
||||
AssertOnline();
|
||||
return _baseStorage.OpenFileForRead(ioc);
|
||||
}
|
||||
|
||||
private void AssertOnline()
|
||||
{
|
||||
if (IsOffline)
|
||||
{
|
||||
//throw new Exception(_app.GetResourceString(UiStringKey.InOfflineMode));
|
||||
throw new OfflineModeException();
|
||||
}
|
||||
}
|
||||
|
||||
public IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction)
|
||||
{
|
||||
AssertOnline();
|
||||
return _baseStorage.OpenWriteTransaction(ioc, useFileTransaction);
|
||||
}
|
||||
|
||||
public string GetFilenameWithoutPathAndExt(IOConnectionInfo ioc)
|
||||
{
|
||||
return _baseStorage.GetFilenameWithoutPathAndExt(ioc);
|
||||
}
|
||||
|
||||
public bool RequiresCredentials(IOConnectionInfo ioc)
|
||||
{
|
||||
return _baseStorage.RequiresCredentials(ioc);
|
||||
}
|
||||
|
||||
public void CreateDirectory(IOConnectionInfo ioc, string newDirName)
|
||||
{
|
||||
_baseStorage.CreateDirectory(ioc, newDirName);
|
||||
}
|
||||
|
||||
public IEnumerable<FileDescription> ListContents(IOConnectionInfo ioc)
|
||||
{
|
||||
return _baseStorage.ListContents(ioc);
|
||||
}
|
||||
|
||||
public FileDescription GetFileDescription(IOConnectionInfo ioc)
|
||||
{
|
||||
return _baseStorage.GetFileDescription(ioc);
|
||||
}
|
||||
|
||||
public bool RequiresSetup(IOConnectionInfo ioConnection)
|
||||
{
|
||||
if (IsOffline)
|
||||
return false;
|
||||
return _baseStorage.RequiresSetup(ioConnection);
|
||||
}
|
||||
|
||||
public string IocToPath(IOConnectionInfo ioc)
|
||||
{
|
||||
return _baseStorage.IocToPath(ioc);
|
||||
}
|
||||
|
||||
public void StartSelectFile(IFileStorageSetupInitiatorActivity activity, bool isForSave, int requestCode, string protocolId)
|
||||
{
|
||||
_baseStorage.StartSelectFile(activity, isForSave, requestCode, protocolId);
|
||||
}
|
||||
|
||||
public void PrepareFileUsage(IFileStorageSetupInitiatorActivity activity, IOConnectionInfo ioc, int requestCode,
|
||||
bool alwaysReturnSuccess)
|
||||
{
|
||||
if (IsOffline)
|
||||
{
|
||||
Intent intent = new Intent();
|
||||
activity.IocToIntent(intent, ioc);
|
||||
activity.OnImmediateResult(requestCode, (int)FileStorageResults.FileUsagePrepared, intent);
|
||||
return;
|
||||
}
|
||||
|
||||
_baseStorage.PrepareFileUsage(activity, ioc, requestCode, alwaysReturnSuccess);
|
||||
}
|
||||
|
||||
public void PrepareFileUsage(Context ctx, IOConnectionInfo ioc)
|
||||
{
|
||||
if (IsOffline)
|
||||
return;
|
||||
_baseStorage.PrepareFileUsage(ctx, ioc);
|
||||
}
|
||||
|
||||
public void OnCreate(IFileStorageSetupActivity activity, Bundle savedInstanceState)
|
||||
{
|
||||
_baseStorage.OnCreate(activity, savedInstanceState);
|
||||
}
|
||||
|
||||
public void OnResume(IFileStorageSetupActivity activity)
|
||||
{
|
||||
_baseStorage.OnResume(activity);
|
||||
}
|
||||
|
||||
public void OnStart(IFileStorageSetupActivity activity)
|
||||
{
|
||||
_baseStorage.OnStart(activity);
|
||||
}
|
||||
|
||||
public void OnActivityResult(IFileStorageSetupActivity activity, int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
_baseStorage.OnActivityResult(activity, requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
public string GetDisplayName(IOConnectionInfo ioc)
|
||||
{
|
||||
return _baseStorage.GetDisplayName(ioc);
|
||||
}
|
||||
|
||||
public string CreateFilePath(string parent, string newFilename)
|
||||
{
|
||||
return _baseStorage.CreateFilePath(parent, newFilename);
|
||||
}
|
||||
|
||||
public IOConnectionInfo GetParentPath(IOConnectionInfo ioc)
|
||||
{
|
||||
return _baseStorage.GetParentPath(ioc);
|
||||
}
|
||||
|
||||
public IOConnectionInfo GetFilePath(IOConnectionInfo folderPath, string filename)
|
||||
{
|
||||
return _baseStorage.GetFilePath(folderPath, filename);
|
||||
}
|
||||
|
||||
public bool IsPermanentLocation(IOConnectionInfo ioc)
|
||||
{
|
||||
return _baseStorage.IsPermanentLocation(ioc);
|
||||
}
|
||||
|
||||
public bool IsReadOnly(IOConnectionInfo ioc)
|
||||
{
|
||||
return _baseStorage.IsReadOnly(ioc);
|
||||
}
|
||||
}
|
||||
|
||||
public class OfflineModeException : Exception
|
||||
{
|
||||
public override string Message
|
||||
{
|
||||
get { return "Working offline."; }
|
||||
}
|
||||
}
|
||||
}
|
@ -79,6 +79,7 @@
|
||||
<Compile Include="Io\IFileStorage.cs" />
|
||||
<Compile Include="Io\IoUtil.cs" />
|
||||
<Compile Include="Io\JavaFileStorage.cs" />
|
||||
<Compile Include="Io\OfflineSwitchableFileStorage.cs" />
|
||||
<Compile Include="Io\SftpFileStorage.cs" />
|
||||
<Compile Include="Io\SkyDriveFileStorage.cs" />
|
||||
<Compile Include="IProgressDialog.cs" />
|
||||
|
@ -61,6 +61,7 @@ namespace keepass2android
|
||||
DuplicateUuidsErrorAdditional,
|
||||
DeletingItems,
|
||||
AskDeletePermanentlyItems,
|
||||
AskDeletePermanentlyItemsNoRecycle
|
||||
AskDeletePermanentlyItemsNoRecycle,
|
||||
InOfflineMode
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -102,6 +102,8 @@ namespace keepass2android
|
||||
|
||||
|
||||
private Task<MemoryStream> _loadDbTask;
|
||||
private bool _loadDbTaskOffline; //indicate if preloading was started with offline mode
|
||||
|
||||
private IOConnectionInfo _ioConnection;
|
||||
private String _keyFileOrProvider;
|
||||
bool _showPassword;
|
||||
@ -687,6 +689,7 @@ namespace keepass2android
|
||||
private string mDrawerTitle;
|
||||
private MeasuringRelativeLayout.MeasureArgs _measureArgs;
|
||||
private ActivityDesign _activityDesign;
|
||||
|
||||
|
||||
internal class MyActionBarDrawerToggle : ActionBarDrawerToggle
|
||||
{
|
||||
@ -862,7 +865,7 @@ namespace keepass2android
|
||||
InitializeTogglePasswordButton();
|
||||
InitializeKeyfileBrowseButton();
|
||||
|
||||
InitializeQuickUnlockCheckbox();
|
||||
InitializeOptionCheckboxes();
|
||||
|
||||
RestoreState(savedInstanceState);
|
||||
|
||||
@ -1270,6 +1273,17 @@ namespace keepass2android
|
||||
CheckBox cbQuickUnlock = (CheckBox) FindViewById(Resource.Id.enable_quickunlock);
|
||||
App.Kp2a.SetQuickUnlockEnabled(cbQuickUnlock.Checked);
|
||||
|
||||
if (App.Kp2a.OfflineMode != _loadDbTaskOffline)
|
||||
{
|
||||
//keep the loading result if we loaded in online-mode (now offline) and the task is completed
|
||||
if (!App.Kp2a.OfflineMode || !_loadDbTask.IsCompleted)
|
||||
{
|
||||
//discard the pre-loading task
|
||||
_loadDbTask = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//avoid password being visible while loading:
|
||||
_showPassword = false;
|
||||
MakePasswordMaskedOrVisible();
|
||||
@ -1577,6 +1591,20 @@ namespace keepass2android
|
||||
base.OnResume();
|
||||
_activityDesign.ReapplyTheme();
|
||||
|
||||
CheckBox cbOfflineMode = (CheckBox)FindViewById(Resource.Id.work_offline);
|
||||
App.Kp2a.OfflineMode = cbOfflineMode.Checked = App.Kp2a.OfflineModePreference; //this won't overwrite new user settings because every change is directly saved in settings
|
||||
LinearLayout offlineModeContainer = FindViewById<LinearLayout>(Resource.Id.work_offline_container);
|
||||
if (App.Kp2a.GetFileStorage(_ioConnection) is IOfflineSwitchable)
|
||||
{
|
||||
offlineModeContainer.Visibility = ViewStates.Visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
offlineModeContainer.Visibility = ViewStates.Gone;
|
||||
App.Kp2a.OfflineMode = false;
|
||||
}
|
||||
|
||||
|
||||
EditText pwd = FindViewById<EditText>(Resource.Id.password_edit);
|
||||
pwd.PostDelayed(() =>
|
||||
{
|
||||
@ -1650,14 +1678,22 @@ namespace keepass2android
|
||||
{
|
||||
// Create task to kick off file loading while the user enters the password
|
||||
_loadDbTask = Task.Factory.StartNew<MemoryStream>(PreloadDbFile);
|
||||
_loadDbTaskOffline = App.Kp2a.OfflineMode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeQuickUnlockCheckbox() {
|
||||
private void InitializeOptionCheckboxes() {
|
||||
CheckBox cbQuickUnlock = (CheckBox)FindViewById(Resource.Id.enable_quickunlock);
|
||||
cbQuickUnlock.Checked = _prefs.GetBoolean(GetString(Resource.String.QuickUnlockDefaultEnabled_key), true);
|
||||
|
||||
CheckBox cbOfflineMode = (CheckBox)FindViewById(Resource.Id.work_offline);
|
||||
cbOfflineMode.CheckedChange += (sender, args) =>
|
||||
{
|
||||
App.Kp2a.OfflineModePreference = App.Kp2a.OfflineMode = args.IsChecked;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
private String GetKeyFile(String filename) {
|
||||
|
@ -308,12 +308,51 @@
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_height="wrap_content" />
|
||||
<LinearLayout
|
||||
android:id="@+id/enable_quickunlock_container"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/enable_quickunlock"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/enable_quickunlock" />
|
||||
<keepass2android.views.Kp2aShortHelpView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TextAppearance_Help_Dense"
|
||||
android:textColor="@color/light_gray"
|
||||
app:help_text="@string/help_quickunlock"
|
||||
app:title_text="@string/enable_quickunlock"
|
||||
android:text="@string/help_quickunlock"
|
||||
android:background="?android:attr/selectableItemBackground"/>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/work_offline_container"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/work_offline"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/UseOfflineMode" />
|
||||
<keepass2android.views.Kp2aShortHelpView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TextAppearance_Help_Dense"
|
||||
android:textColor="@color/light_gray"
|
||||
app:help_text="@string/UseOfflineMode_Info"
|
||||
app:title_text="@string/UseOfflineMode"
|
||||
android:text="@string/UseOfflineMode_Info"
|
||||
android:background="?android:attr/selectableItemBackground"/>
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/spacing"
|
||||
android:layout_width="fill_parent"
|
||||
|
@ -47,6 +47,14 @@
|
||||
android:icon="@drawable/ic_popup_sync"
|
||||
android:title="@string/synchronize_database_menu"
|
||||
app:showAsAction="never"
|
||||
/>
|
||||
<item android:id="@+id/menu_work_offline"
|
||||
android:title="@string/UseOfflineMode"
|
||||
app:showAsAction="never"
|
||||
/>
|
||||
<item android:id="@+id/menu_work_online"
|
||||
android:title="@string/UseOnlineMode"
|
||||
app:showAsAction="never"
|
||||
/>
|
||||
|
||||
<item android:id="@+id/menu_sort"
|
||||
|
@ -20,9 +20,11 @@
|
||||
<resources>
|
||||
|
||||
<attr name="help_text" format="string" />
|
||||
<attr name="title_text" format="string" />
|
||||
<declare-styleable name="Kp2aShortHelpView">
|
||||
<attr name="android:text"/>
|
||||
<attr name="help_text" />
|
||||
<attr name="title_text" />
|
||||
</declare-styleable>
|
||||
<declare-styleable name="TextWithHelp">
|
||||
<attr name="android:text"/>
|
||||
@ -88,6 +90,8 @@
|
||||
<string name="FileHandling_prefs_key">FileHandling_prefs_key</string>
|
||||
<string name="keyboardswitch_prefs_key">keyboardswitch_prefs_key</string>
|
||||
|
||||
<string name="OfflineMode_key">OfflineMode_key</string>
|
||||
|
||||
<string name="QuickUnlockDefaultEnabled_key">Enable_QuickUnlock_by_default</string>
|
||||
<string name="QuickUnlockLength_key">QuickUnlockLength</string>
|
||||
<string name="QuickUnlockLength_default">3</string>
|
||||
|
@ -386,6 +386,11 @@
|
||||
<string name="SynchronizingDatabase">Merging changes…</string>
|
||||
<string name="YesSynchronize">Yes, merge</string>
|
||||
<string name="NoOverwrite">No, overwrite</string>
|
||||
|
||||
<string name="UseOfflineMode">Work offline</string>
|
||||
<string name="UseOnlineMode">Work online</string>
|
||||
<string name="UseOfflineMode_Info">Avoid any network traffic by using the local cache copy of the file. Changes are stored in the local cache only and will only be uploaded when switching back to online mode.</string>
|
||||
<string name="InOfflineMode">Working offline.</string>
|
||||
|
||||
<string name="SynchronizingCachedDatabase">Synchronizing cached database…</string>
|
||||
<string name="DownloadingRemoteFile">Downloading remote file…</string>
|
||||
@ -453,7 +458,9 @@
|
||||
<string name="help_database_location">You can store your database locally on your Android device or in the cloud (non-Offline version only). Keepass2Android makes the database available even if you are offline. As the database is securely encrypted with AES 256 bit encryption, nobody will be able to access your passwords except you. We recommend to select Dropbox: It\'s accessible on all your devices and even provides backups of previous file versions.</string>
|
||||
<string name="hint_database_location">Select where you want to store the database:</string>
|
||||
<string name="button_change_location">Change location</string>
|
||||
|
||||
|
||||
<string name="help_quickunlock">If enabled, Keepass2Android stays running in the background even when the database is locked. This allows to unlock the database later with only a short part of the master password.</string>
|
||||
|
||||
<string name="master_password">Master password</string>
|
||||
<string name="help_master_password">Your database is encrypted with the password you enter here. Choose a strong password in order to keep the database safe! Tip: Make up a sentence or two and use the first letters of the words as password. Include punctuation marks.</string>
|
||||
<string name="hint_master_password">Select a master password to protect your database:</string>
|
||||
|
@ -116,7 +116,20 @@
|
||||
</style>
|
||||
|
||||
|
||||
<style name="EditEntryButton">
|
||||
<style name="TextAppearance_Help_Dense">
|
||||
<item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
|
||||
<item name="android:textSize">18sp</item>
|
||||
<item name="android:paddingLeft">6sp</item>
|
||||
<item name="android:paddingRight">6sp</item>
|
||||
<item name="android:paddingBottom">0sp</item>
|
||||
<item name="android:gravity">center_vertical</item>
|
||||
<item name="android:layout_gravity">center_vertical</item>
|
||||
<item name="android:layout_marginRight">4dip</item>
|
||||
<item name="android:layout_marginLeft">4dip</item>
|
||||
</style>
|
||||
|
||||
|
||||
<style name="EditEntryButton">
|
||||
<item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
|
||||
<item name="android:layout_marginTop">12dip</item>
|
||||
<item name="android:layout_marginLeft">24dip</item>
|
||||
|
@ -410,21 +410,27 @@ namespace keepass2android
|
||||
}
|
||||
public IFileStorage GetFileStorage(IOConnectionInfo iocInfo, bool allowCache)
|
||||
{
|
||||
IFileStorage fileStorage;
|
||||
if (iocInfo.IsLocalFile())
|
||||
return new BuiltInFileStorage(this);
|
||||
fileStorage = new BuiltInFileStorage(this);
|
||||
else
|
||||
{
|
||||
IFileStorage innerFileStorage = GetCloudFileStorage(iocInfo);
|
||||
|
||||
if (DatabaseCacheEnabled && allowCache)
|
||||
{
|
||||
return new CachingFileStorage(innerFileStorage, Application.Context.CacheDir.Path, this);
|
||||
fileStorage = new CachingFileStorage(innerFileStorage, Application.Context.CacheDir.Path, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
return innerFileStorage;
|
||||
fileStorage = innerFileStorage;
|
||||
}
|
||||
}
|
||||
if (fileStorage is IOfflineSwitchable)
|
||||
{
|
||||
((IOfflineSwitchable)fileStorage).IsOffline = App.Kp2a.OfflineMode;
|
||||
}
|
||||
return fileStorage;
|
||||
}
|
||||
|
||||
private IFileStorage GetCloudFileStorage(IOConnectionInfo iocInfo)
|
||||
@ -591,13 +597,23 @@ namespace keepass2android
|
||||
|
||||
public void CouldntSaveToRemote(IOConnectionInfo ioc, Exception e)
|
||||
{
|
||||
ShowToast(Application.Context.GetString(Resource.String.CouldNotSaveToRemote, e.Message));
|
||||
var errorMessage = GetErrorMessageForFileStorageException(e);
|
||||
ShowToast(Application.Context.GetString(Resource.String.CouldNotSaveToRemote, errorMessage));
|
||||
}
|
||||
|
||||
|
||||
private string GetErrorMessageForFileStorageException(Exception e)
|
||||
{
|
||||
string errorMessage = e.Message;
|
||||
if (e is OfflineModeException)
|
||||
errorMessage = GetResourceString(UiStringKey.InOfflineMode);
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
|
||||
public void CouldntOpenFromRemote(IOConnectionInfo ioc, Exception ex)
|
||||
{
|
||||
ShowToast(Application.Context.GetString(Resource.String.CouldNotLoadFromRemote, ex.Message));
|
||||
var errorMessage = GetErrorMessageForFileStorageException(ex);
|
||||
ShowToast(Application.Context.GetString(Resource.String.CouldNotLoadFromRemote, errorMessage));
|
||||
}
|
||||
|
||||
public void UpdatedCachedFileOnLoad(IOConnectionInfo ioc)
|
||||
@ -667,6 +683,31 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
public bool OfflineModePreference
|
||||
{
|
||||
get
|
||||
{
|
||||
var prefs = PreferenceManager.GetDefaultSharedPreferences(Application.Context);
|
||||
return prefs.GetBoolean(Application.Context.GetString(Resource.String.OfflineMode_key), false);
|
||||
}
|
||||
set
|
||||
{
|
||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(Application.Context);
|
||||
ISharedPreferencesEditor edit = prefs.Edit();
|
||||
edit.PutBoolean(Application.Context.GetString(Resource.String.OfflineMode_key), value);
|
||||
edit.Commit();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// true if the app is used in offline mode
|
||||
/// </summary>
|
||||
public bool OfflineMode
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public void OnScreenOff()
|
||||
{
|
||||
if (PreferenceManager.GetDefaultSharedPreferences(Application.Context)
|
||||
|
@ -334,6 +334,7 @@ namespace keepass2android
|
||||
protected override void OnResume()
|
||||
{
|
||||
base.OnResume();
|
||||
App.Kp2a.OfflineMode = false; //no matter what the preferences are, file selection or db creation is performed offline. PasswordActivity might set this to true.
|
||||
Kp2aLog.Log("FileSelect.OnResume");
|
||||
|
||||
_design.ReapplyTheme();
|
||||
|
@ -50,6 +50,8 @@ namespace keepass2android.views
|
||||
}
|
||||
}
|
||||
|
||||
public string TitleText { get; set; }
|
||||
|
||||
private void UpdateView()
|
||||
{
|
||||
if (!String.IsNullOrEmpty(_helpText))
|
||||
@ -72,8 +74,11 @@ namespace keepass2android.views
|
||||
MovementMethod = LinkMovementMethod.Instance;
|
||||
Click += (sender, args) =>
|
||||
{
|
||||
string title = Context.GetString(AppNames.AppNameResource);
|
||||
if (!string.IsNullOrEmpty(TitleText))
|
||||
title = TitleText;
|
||||
new AlertDialog.Builder(Context)
|
||||
.SetTitle(Context.GetString(AppNames.AppNameResource))
|
||||
.SetTitle(title)
|
||||
.SetMessage(_helpText)
|
||||
.SetPositiveButton(Android.Resource.String.Ok, (o, eventArgs) => { })
|
||||
.Show();
|
||||
@ -91,6 +96,7 @@ namespace keepass2android.views
|
||||
TypedArray a = Context.ObtainStyledAttributes(
|
||||
attrs,
|
||||
Resource.Styleable.Kp2aShortHelpView);
|
||||
TitleText = a.GetString(Resource.Styleable.Kp2aShortHelpView_title_text);
|
||||
HelpText = a.GetString(Resource.Styleable.Kp2aShortHelpView_help_text);
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user