mirror of
https://github.com/moparisthebest/keepass2android
synced 2024-11-24 18:22:21 -05:00
implemented action items for move and delete (includes extension of apptasks to delete/move multiple items)
fixed display issue in QuickUnlock fixed text color of recent files
This commit is contained in:
parent
fabe0904c0
commit
af02ca7599
@ -95,6 +95,7 @@ Global
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
|
||||
|
@ -56,8 +56,9 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="database\CheckDatabaseForChanges.cs" />
|
||||
<Compile Include="database\edit\DeleteMultipleItems.cs" />
|
||||
<Compile Include="database\edit\EditGroup.cs" />
|
||||
<Compile Include="database\edit\MoveElement.cs" />
|
||||
<Compile Include="database\edit\MoveElements.cs" />
|
||||
<Compile Include="database\KdbDatabaseFormat.cs" />
|
||||
<Compile Include="database\KdbxDatabaseFormat.cs" />
|
||||
<Compile Include="database\PwEntryOutput.cs" />
|
||||
|
@ -57,6 +57,8 @@ namespace keepass2android
|
||||
CopyFileRequiredForEditing,
|
||||
DuplicateUuidsError,
|
||||
DuplicateUuidsErrorAdditional,
|
||||
KdbBetaWarning
|
||||
KdbBetaWarning,
|
||||
DeletingItems,
|
||||
AskDeletePermanentlyItems
|
||||
}
|
||||
}
|
||||
|
@ -16,16 +16,19 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Android.Content;
|
||||
using KeePassLib;
|
||||
using KeePassLib.Interfaces;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
public class DeleteEntry : DeleteRunnable {
|
||||
|
||||
private readonly PwEntry _entry;
|
||||
private UiStringKey _statusMessage;
|
||||
|
||||
public DeleteEntry(Context ctx, IKp2aApp app, PwEntry entry, OnFinish finish):base(finish, app) {
|
||||
public DeleteEntry(Context ctx, IKp2aApp app, PwEntry entry, OnFinish finish):base(finish, app) {
|
||||
Ctx = ctx;
|
||||
Db = app.GetDb();
|
||||
_entry = entry;
|
||||
@ -48,76 +51,15 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
public override void Run()
|
||||
{
|
||||
StatusLogger.UpdateMessage(UiStringKey.DeletingEntry);
|
||||
PwDatabase pd = Db.KpDatabase;
|
||||
protected override void PerformDelete(List<PwGroup> touchedGroups, List<PwGroup> permanentlyDeletedGroups)
|
||||
{
|
||||
DoDeleteEntry(_entry, touchedGroups);
|
||||
}
|
||||
|
||||
PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true);
|
||||
|
||||
bool bUpdateGroupList = false;
|
||||
DateTime dtNow = DateTime.Now;
|
||||
PwEntry pe = _entry;
|
||||
PwGroup pgParent = pe.ParentGroup;
|
||||
if(pgParent != null)
|
||||
{
|
||||
pgParent.Entries.Remove(pe);
|
||||
//TODO check if RecycleBin is deleted
|
||||
//TODO no recycle bin in KDB
|
||||
|
||||
if ((DeletePermanently) || (!CanRecycle))
|
||||
{
|
||||
PwDeletedObject pdo = new PwDeletedObject(pe.Uuid, dtNow);
|
||||
pd.DeletedObjects.Add(pdo);
|
||||
|
||||
_onFinishToRun = new ActionOnFinish((success, message) =>
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
// Mark parent dirty
|
||||
Db.Dirty.Add(pgParent);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Let's not bother recovering from a failure to save a deleted entry. It is too much work.
|
||||
App.LockDatabase(false);
|
||||
}
|
||||
}, OnFinishToRun);
|
||||
}
|
||||
else // Recycle
|
||||
{
|
||||
EnsureRecycleBinExists(ref pgRecycleBin, ref bUpdateGroupList);
|
||||
|
||||
pgRecycleBin.AddEntry(pe, true, true);
|
||||
pe.Touch(false);
|
||||
|
||||
_onFinishToRun = new ActionOnFinish( (success, message) =>
|
||||
{
|
||||
if ( success ) {
|
||||
// Mark previous parent dirty
|
||||
Db.Dirty.Add(pgParent);
|
||||
// Mark new parent dirty
|
||||
Db.Dirty.Add(pgRecycleBin);
|
||||
// mark root dirty if recycle bin was created
|
||||
if (bUpdateGroupList)
|
||||
Db.Dirty.Add(Db.Root);
|
||||
} else {
|
||||
// Let's not bother recovering from a failure to save a deleted entry. It is too much work.
|
||||
App.LockDatabase(false);
|
||||
}
|
||||
|
||||
}, OnFinishToRun);
|
||||
}
|
||||
}
|
||||
|
||||
// Commit database
|
||||
SaveDb save = new SaveDb(Ctx, App, OnFinishToRun, false);
|
||||
save.SetStatusLogger(StatusLogger);
|
||||
save.Run();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override UiStringKey StatusMessage
|
||||
{
|
||||
get { return UiStringKey.DeletingEntry; }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Android.Content;
|
||||
using KeePassLib;
|
||||
|
||||
@ -68,96 +69,15 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void Run() {
|
||||
StatusLogger.UpdateMessage(UiStringKey.DeletingGroup);
|
||||
//from KP Desktop
|
||||
PwGroup pg = _group;
|
||||
PwGroup pgParent = pg.ParentGroup;
|
||||
if(pgParent == null) return; // Can't remove virtual or root group
|
||||
|
||||
PwDatabase pd = Db.KpDatabase;
|
||||
PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true);
|
||||
|
||||
pgParent.Groups.Remove(pg);
|
||||
|
||||
if ((DeletePermanently) || (!CanRecycle))
|
||||
{
|
||||
pg.DeleteAllObjects(pd);
|
||||
|
||||
PwDeletedObject pdo = new PwDeletedObject(pg.Uuid, DateTime.Now);
|
||||
pd.DeletedObjects.Add(pdo);
|
||||
_onFinishToRun = new AfterDeletePermanently(OnFinishToRun, App, _group);
|
||||
}
|
||||
else // Recycle
|
||||
{
|
||||
bool groupListUpdateRequired = false;
|
||||
EnsureRecycleBinExists(ref pgRecycleBin, ref groupListUpdateRequired);
|
||||
|
||||
pgRecycleBin.AddGroup(pg, true, true);
|
||||
pg.Touch(false);
|
||||
_onFinishToRun = new ActionOnFinish((success, message) =>
|
||||
{
|
||||
if ( success ) {
|
||||
// Mark new parent (Recycle bin) dirty
|
||||
PwGroup parent = _group.ParentGroup;
|
||||
if ( parent != null ) {
|
||||
Db.Dirty.Add(parent);
|
||||
}
|
||||
//Mark old parent dirty:
|
||||
Db.Dirty.Add(pgParent);
|
||||
protected override void PerformDelete(List<PwGroup> touchedGroups, List<PwGroup> permanentlyDeletedGroups)
|
||||
{
|
||||
DoDeleteGroup(_group, touchedGroups, permanentlyDeletedGroups);
|
||||
}
|
||||
|
||||
// mark root dirty if recycle bin was created
|
||||
if (groupListUpdateRequired)
|
||||
Db.Dirty.Add(Db.Root);
|
||||
} else {
|
||||
// Let's not bother recovering from a failure to save a deleted group. It is too much work.
|
||||
App.LockDatabase(false);
|
||||
}
|
||||
}, OnFinishToRun);
|
||||
}
|
||||
|
||||
// Save
|
||||
SaveDb save = new SaveDb(Ctx, App, OnFinishToRun, DontSave);
|
||||
save.SetStatusLogger(StatusLogger);
|
||||
save.Run();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private class AfterDeletePermanently : OnFinish {
|
||||
readonly IKp2aApp _app;
|
||||
|
||||
readonly PwGroup _group;
|
||||
|
||||
public AfterDeletePermanently(OnFinish finish, IKp2aApp app, PwGroup group):base(finish) {
|
||||
_app = app;
|
||||
_group = group;
|
||||
}
|
||||
|
||||
public override void Run() {
|
||||
if ( Success ) {
|
||||
// Remove from group global
|
||||
_app.GetDb().Groups.Remove(_group.Uuid);
|
||||
|
||||
// Remove group from the dirty global (if it is present), not a big deal if this fails (doesn't throw)
|
||||
_app.GetDb().Dirty.Remove(_group);
|
||||
|
||||
// Mark parent dirty
|
||||
PwGroup parent = _group.ParentGroup;
|
||||
if ( parent != null ) {
|
||||
_app.GetDb().Dirty.Add(parent);
|
||||
}
|
||||
} else {
|
||||
// Let's not bother recovering from a failure to save a deleted group. It is too much work.
|
||||
_app.LockDatabase(false);
|
||||
}
|
||||
|
||||
base.Run();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
public override UiStringKey StatusMessage
|
||||
{
|
||||
get { return UiStringKey.DeletingGroup; }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Android.Content;
|
||||
using KeePassLib;
|
||||
|
||||
@ -5,12 +7,13 @@ namespace keepass2android
|
||||
{
|
||||
public abstract class DeleteRunnable : RunnableOnFinish
|
||||
{
|
||||
protected DeleteRunnable(OnFinish finish, IKp2aApp app):base(finish)
|
||||
protected DeleteRunnable(OnFinish finish, IKp2aApp app)
|
||||
: base(finish)
|
||||
{
|
||||
App = app;
|
||||
App = app;
|
||||
}
|
||||
|
||||
protected IKp2aApp App;
|
||||
protected IKp2aApp App;
|
||||
|
||||
protected Database Db;
|
||||
|
||||
@ -22,9 +25,9 @@ namespace keepass2android
|
||||
Db = db;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private bool _deletePermanently = true;
|
||||
|
||||
|
||||
public bool DeletePermanently
|
||||
{
|
||||
get
|
||||
@ -44,52 +47,61 @@ namespace keepass2android
|
||||
|
||||
protected bool CanRecycleGroup(PwGroup pgParent)
|
||||
{
|
||||
bool bShiftPressed = false;
|
||||
PwDatabase pd = Db.KpDatabase;
|
||||
PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true);
|
||||
bool bPermanent = false;
|
||||
if (pgParent != null)
|
||||
{
|
||||
if (pd.RecycleBinEnabled == false)
|
||||
{
|
||||
Android.Util.Log.Debug("KP2A", "CanRecycle? No, RecycleBinIsNotEnabled");
|
||||
bPermanent = true;
|
||||
else if (bShiftPressed)
|
||||
bPermanent = true;
|
||||
}
|
||||
|
||||
else if (pgRecycleBin == null)
|
||||
{
|
||||
} // Recycle
|
||||
else if (pgParent == pgRecycleBin)
|
||||
{
|
||||
Android.Util.Log.Debug("KP2A", "CanRecycle? No, Can't recycle RecycleBin");
|
||||
bPermanent = true;
|
||||
}
|
||||
|
||||
else if (pgParent.IsContainedIn(pgRecycleBin))
|
||||
{
|
||||
Android.Util.Log.Debug("KP2A", "CanRecycle? No, "+pgParent.Name+" is in RecycleBin");
|
||||
bPermanent = true;
|
||||
}
|
||||
|
||||
}
|
||||
return !bPermanent;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected void EnsureRecycleBinExists(ref PwGroup pgRecycleBin,
|
||||
ref bool bGroupListUpdateRequired)
|
||||
ref bool bGroupListUpdateRequired)
|
||||
{
|
||||
if ((Db == null) || (Db.KpDatabase == null)) { return; }
|
||||
|
||||
if(pgRecycleBin == Db.KpDatabase.RootGroup)
|
||||
|
||||
if (pgRecycleBin == Db.KpDatabase.RootGroup)
|
||||
{
|
||||
pgRecycleBin = null;
|
||||
}
|
||||
|
||||
if(pgRecycleBin == null)
|
||||
|
||||
if (pgRecycleBin == null)
|
||||
{
|
||||
pgRecycleBin = new PwGroup(true, true, App.GetResourceString(UiStringKey.RecycleBin),
|
||||
PwIcon.TrashBin)
|
||||
PwIcon.TrashBin)
|
||||
{
|
||||
EnableAutoType = false,
|
||||
EnableSearching = false,
|
||||
EnableAutoType = false,
|
||||
EnableSearching = false,
|
||||
IsExpanded = false
|
||||
};
|
||||
|
||||
Db.KpDatabase.RootGroup.AddGroup(pgRecycleBin, true);
|
||||
Db.Groups[pgRecycleBin.Uuid] = pgRecycleBin;
|
||||
Db.KpDatabase.RecycleBinUuid = pgRecycleBin.Uuid;
|
||||
|
||||
|
||||
bGroupListUpdateRequired = true;
|
||||
}
|
||||
else { System.Diagnostics.Debug.Assert(pgRecycleBin.Uuid.Equals(Db.KpDatabase.RecycleBinUuid)); }
|
||||
@ -99,36 +111,155 @@ namespace keepass2android
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
|
||||
public void Start()
|
||||
{
|
||||
if (CanRecycle)
|
||||
{
|
||||
App.AskYesNoCancel(UiStringKey.AskDeletePermanently_title,
|
||||
QuestionsResourceId,
|
||||
(dlgSender, dlgEvt) =>
|
||||
{
|
||||
DeletePermanently = true;
|
||||
ProgressTask pt = new ProgressTask(App, Ctx, this);
|
||||
pt.Run();
|
||||
},
|
||||
(dlgSender, dlgEvt) => {
|
||||
DeletePermanently = false;
|
||||
ProgressTask pt = new ProgressTask(App, Ctx, this);
|
||||
pt.Run();
|
||||
},
|
||||
(dlgSender, dlgEvt) => {},
|
||||
Ctx);
|
||||
App.AskYesNoCancel(UiStringKey.AskDeletePermanently_title,
|
||||
QuestionsResourceId,
|
||||
(dlgSender, dlgEvt) =>
|
||||
{
|
||||
DeletePermanently = true;
|
||||
ProgressTask pt = new ProgressTask(App, Ctx, this);
|
||||
pt.Run();
|
||||
},
|
||||
(dlgSender, dlgEvt) =>
|
||||
{
|
||||
DeletePermanently = false;
|
||||
ProgressTask pt = new ProgressTask(App, Ctx, this);
|
||||
pt.Run();
|
||||
},
|
||||
(dlgSender, dlgEvt) => { },
|
||||
Ctx);
|
||||
|
||||
|
||||
|
||||
} else
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ProgressTask pt = new ProgressTask(App, Ctx, this);
|
||||
pt.Run();
|
||||
}
|
||||
}
|
||||
|
||||
protected void DoDeleteEntry(PwEntry pe, List<PwGroup> touchedGroups)
|
||||
{
|
||||
PwDatabase pd = Db.KpDatabase;
|
||||
|
||||
PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true);
|
||||
|
||||
bool bUpdateGroupList = false;
|
||||
DateTime dtNow = DateTime.Now;
|
||||
|
||||
PwGroup pgParent = pe.ParentGroup;
|
||||
if (pgParent != null)
|
||||
{
|
||||
pgParent.Entries.Remove(pe);
|
||||
//TODO check if RecycleBin is deleted
|
||||
//TODO no recycle bin in KDB
|
||||
|
||||
if ((DeletePermanently) || (!CanRecycle))
|
||||
{
|
||||
PwDeletedObject pdo = new PwDeletedObject(pe.Uuid, dtNow);
|
||||
pd.DeletedObjects.Add(pdo);
|
||||
touchedGroups.Add(pgParent);
|
||||
}
|
||||
else // Recycle
|
||||
{
|
||||
EnsureRecycleBinExists(ref pgRecycleBin, ref bUpdateGroupList);
|
||||
|
||||
pgRecycleBin.AddEntry(pe, true, true);
|
||||
pe.Touch(false);
|
||||
|
||||
touchedGroups.Add(pgParent);
|
||||
// Mark new parent dirty
|
||||
touchedGroups.Add(pgRecycleBin);
|
||||
// mark root dirty if recycle bin was created
|
||||
touchedGroups.Add(Db.Root);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void Run()
|
||||
{
|
||||
StatusLogger.UpdateMessage(StatusMessage);
|
||||
|
||||
List<PwGroup> touchedGroups = new List<PwGroup>();
|
||||
List<PwGroup> permanentlyDeletedGroups = new List<PwGroup>();
|
||||
Android.Util.Log.Debug("KP2A", "Calling PerformDelete..");
|
||||
PerformDelete(touchedGroups, permanentlyDeletedGroups);
|
||||
|
||||
_onFinishToRun = new ActionOnFinish((success, message) =>
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
foreach (var g in touchedGroups)
|
||||
Db.Dirty.Add(g);
|
||||
foreach (var g in permanentlyDeletedGroups)
|
||||
{
|
||||
//remove groups from global lists if present there
|
||||
Db.Dirty.Remove(g);
|
||||
Db.Groups.Remove(g.Uuid);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Let's not bother recovering from a failure to save. It is too much work.
|
||||
App.LockDatabase(false);
|
||||
}
|
||||
}, OnFinishToRun);
|
||||
|
||||
// Commit database
|
||||
SaveDb save = new SaveDb(Ctx, App, OnFinishToRun, false);
|
||||
save.SetStatusLogger(StatusLogger);
|
||||
save.Run();
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected abstract void PerformDelete(List<PwGroup> touchedGroups, List<PwGroup> permanentlyDeletedGroups);
|
||||
|
||||
public abstract UiStringKey StatusMessage { get; }
|
||||
|
||||
protected bool DoDeleteGroup(PwGroup pg, List<PwGroup> touchedGroups, List<PwGroup> permanentlyDeletedGroups)
|
||||
{
|
||||
PwGroup pgParent = pg.ParentGroup;
|
||||
if (pgParent == null) return false;
|
||||
|
||||
PwDatabase pd = Db.KpDatabase;
|
||||
PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true);
|
||||
|
||||
pgParent.Groups.Remove(pg);
|
||||
touchedGroups.Add(pgParent);
|
||||
if ((DeletePermanently) || (!CanRecycle))
|
||||
{
|
||||
pg.DeleteAllObjects(pd);
|
||||
|
||||
PwDeletedObject pdo = new PwDeletedObject(pg.Uuid, DateTime.Now);
|
||||
pd.DeletedObjects.Add(pdo);
|
||||
|
||||
|
||||
permanentlyDeletedGroups.Add(pg);
|
||||
|
||||
}
|
||||
else // Recycle
|
||||
{
|
||||
bool groupListUpdateRequired = false;
|
||||
EnsureRecycleBinExists(ref pgRecycleBin, ref groupListUpdateRequired);
|
||||
|
||||
pgRecycleBin.AddGroup(pg, true, true);
|
||||
pg.Touch(false);
|
||||
// Mark new parent (Recycle bin) touched
|
||||
touchedGroups.Add(pg.ParentGroup);
|
||||
// mark root touched if recycle bin was created
|
||||
if (groupListUpdateRequired)
|
||||
touchedGroups.Add(Db.Root);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,70 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Android.Content;
|
||||
using KeePassLib;
|
||||
using KeePassLib.Interfaces;
|
||||
|
||||
namespace keepass2android.database.edit
|
||||
{
|
||||
public class MoveElement: RunnableOnFinish
|
||||
{
|
||||
private readonly IStructureItem _elementToMove;
|
||||
private readonly PwGroup _targetGroup;
|
||||
private readonly Context _ctx;
|
||||
private readonly IKp2aApp _app;
|
||||
|
||||
public MoveElement(IStructureItem elementToMove, PwGroup targetGroup, Context ctx, IKp2aApp app, OnFinish finish) : base(finish)
|
||||
{
|
||||
_elementToMove = elementToMove;
|
||||
_targetGroup = targetGroup;
|
||||
_ctx = ctx;
|
||||
_app = app;
|
||||
}
|
||||
|
||||
public override void Run()
|
||||
{
|
||||
|
||||
_app.GetDb().Dirty.Add(_elementToMove.ParentGroup);
|
||||
|
||||
PwGroup pgParent = _elementToMove.ParentGroup;
|
||||
if (pgParent != _targetGroup)
|
||||
{
|
||||
if (pgParent != null) // Remove from parent
|
||||
{
|
||||
PwEntry entry = _elementToMove as PwEntry;
|
||||
if (entry != null)
|
||||
{
|
||||
pgParent.Entries.Remove(entry);
|
||||
_targetGroup.AddEntry(entry, true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
PwGroup group = (PwGroup)_elementToMove;
|
||||
if ((_targetGroup == group) || (_targetGroup.IsContainedIn(group)))
|
||||
{
|
||||
Finish(false, _app.GetResourceString(UiStringKey.CannotMoveGroupHere));
|
||||
return;
|
||||
}
|
||||
pgParent.Groups.Remove(group);
|
||||
_targetGroup.AddGroup(group, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_onFinishToRun = new ActionOnFinish((success, message) =>
|
||||
{
|
||||
if (!success)
|
||||
{ // Let's not bother recovering from a failure.
|
||||
_app.LockDatabase(false);
|
||||
}
|
||||
}, OnFinishToRun);
|
||||
|
||||
// Save
|
||||
SaveDb save = new SaveDb(_ctx, _app, OnFinishToRun, false);
|
||||
save.SetStatusLogger(StatusLogger);
|
||||
save.Run();
|
||||
}
|
||||
}
|
||||
}
|
@ -951,7 +951,9 @@ namespace keepass2android
|
||||
}
|
||||
else
|
||||
{
|
||||
FindViewById(Resource.Id.entry_tags_label).Visibility = ViewStates.Gone;
|
||||
var view = FindViewById(Resource.Id.entry_tags_label);
|
||||
if (view != null)
|
||||
view.Visibility = ViewStates.Gone;
|
||||
FindViewById(Resource.Id.entry_tags).Visibility = ViewStates.Gone;
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,8 @@ using Android.Content.PM;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
[Activity(Label = "@string/app_name", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden, Theme = "@style/MyTheme_ActionBar")]
|
||||
[Activity(Label = "@string/app_name", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden, Theme = "@style/MyTheme_ActionBar")]
|
||||
[MetaData("android.app.searchable", Resource = AppNames.Searchable)]
|
||||
[MetaData("android.app.default_searchable",Value="keepass2android.search.SearchResults")]
|
||||
public class GroupActivity : GroupBaseActivity {
|
||||
|
||||
@ -83,8 +84,12 @@ namespace keepass2android
|
||||
get { return App.Kp2a.GetDb().CanWrite && ((this.Group.ParentGroup != null) || App.Kp2a.GetDb().DatabaseFormat.CanHaveEntriesInRootGroup); }
|
||||
}
|
||||
|
||||
public override bool OnCreateOptionsMenu(IMenu menu)
|
||||
{
|
||||
return base.OnCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
protected override void OnCreate (Bundle savedInstanceState)
|
||||
protected override void OnCreate (Bundle savedInstanceState)
|
||||
{
|
||||
base.OnCreate (savedInstanceState);
|
||||
|
||||
|
@ -16,6 +16,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Android.App;
|
||||
@ -182,6 +183,7 @@ namespace keepass2android
|
||||
private String strCachedGroupUuid = null;
|
||||
|
||||
|
||||
|
||||
public String UuidGroup {
|
||||
get {
|
||||
if (strCachedGroupUuid == null) {
|
||||
@ -222,6 +224,11 @@ namespace keepass2android
|
||||
get { return (BaseAdapter) FragmentManager.FindFragmentById<GroupListFragment>(Resource.Id.list_fragment).ListAdapter; }
|
||||
}
|
||||
|
||||
public virtual bool IsSearchResult
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/*TODO
|
||||
* protected override void OnListItemClick(ListView l, View v, int position, long id) {
|
||||
base.OnListItemClick(l, v, position, id);
|
||||
@ -234,7 +241,9 @@ namespace keepass2android
|
||||
*/
|
||||
protected override void OnCreate(Bundle savedInstanceState) {
|
||||
base.OnCreate(savedInstanceState);
|
||||
|
||||
|
||||
Android.Util.Log.Debug("KP2A", "Creating GBA");
|
||||
|
||||
AppTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent);
|
||||
|
||||
// Likely the app has been killed exit the activity
|
||||
@ -266,8 +275,8 @@ namespace keepass2android
|
||||
|
||||
|
||||
|
||||
FindViewById(Resource.Id.cancel_insert_element).Click += (sender, args) => StopMovingElement();
|
||||
FindViewById(Resource.Id.insert_element).Click += (sender, args) => InsertElement();
|
||||
FindViewById(Resource.Id.cancel_insert_element).Click += (sender, args) => StopMovingElements();
|
||||
FindViewById(Resource.Id.insert_element).Click += (sender, args) => InsertElements();
|
||||
|
||||
SetResult(KeePass.ExitNormal);
|
||||
|
||||
@ -275,13 +284,15 @@ namespace keepass2android
|
||||
|
||||
}
|
||||
|
||||
private void InsertElement()
|
||||
private void InsertElements()
|
||||
{
|
||||
MoveElementTask moveElementTask = (MoveElementTask)AppTask;
|
||||
IStructureItem elementToMove = App.Kp2a.GetDb().KpDatabase.RootGroup.FindObject(moveElementTask.Uuid, true, null);
|
||||
MoveElementsTask moveElementsTask = (MoveElementsTask)AppTask;
|
||||
IEnumerable<IStructureItem> elementsToMove =
|
||||
moveElementsTask.Uuids.Select(uuid => App.Kp2a.GetDb().KpDatabase.RootGroup.FindObject(uuid, true, null));
|
||||
|
||||
|
||||
|
||||
var moveElement = new MoveElement(elementToMove, Group, this, App.Kp2a, new ActionOnFinish((success, message) => { StopMovingElement(); if (!String.IsNullOrEmpty(message)) Toast.MakeText(this, message, ToastLength.Long).Show();}));
|
||||
var moveElement = new MoveElements(elementsToMove.ToList(), Group, this, App.Kp2a, new ActionOnFinish((success, message) => { StopMovingElements(); if (!String.IsNullOrEmpty(message)) Toast.MakeText(this, message, ToastLength.Long).Show();}));
|
||||
var progressTask = new ProgressTask(App.Kp2a, this, moveElement);
|
||||
progressTask.Run();
|
||||
|
||||
@ -381,34 +392,34 @@ namespace keepass2android
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/*
|
||||
public override bool OnCreateOptionsMenu(IMenu menu) {
|
||||
return base.OnCreateOptionsMenu(menu);
|
||||
|
||||
public override bool OnCreateOptionsMenu(IMenu menu) {
|
||||
base.OnCreateOptionsMenu(menu);
|
||||
|
||||
MenuInflater inflater = MenuInflater;
|
||||
inflater.Inflate(Resource.Menu.group, menu);
|
||||
var searchManager = (SearchManager) GetSystemService(SearchService);
|
||||
IMenuItem searchItem = menu.FindItem(Resource.Id.menu_search);
|
||||
var view = MenuItemCompat.GetActionView(searchItem);
|
||||
var searchView = view.JavaCast<Android.Support.V7.Widget.SearchView>();
|
||||
MenuInflater inflater = MenuInflater;
|
||||
inflater.Inflate(Resource.Menu.group, menu);
|
||||
var searchManager = (SearchManager) GetSystemService(SearchService);
|
||||
IMenuItem searchItem = menu.FindItem(Resource.Id.menu_search);
|
||||
var view = MenuItemCompat.GetActionView(searchItem);
|
||||
var searchView = view.JavaCast<Android.Support.V7.Widget.SearchView>();
|
||||
|
||||
searchView.SetSearchableInfo(searchManager.GetSearchableInfo(ComponentName));
|
||||
searchView.SetOnSuggestionListener(new SuggestionListener(searchView.SuggestionsAdapter, this, searchItem));
|
||||
searchView.SetOnQueryTextListener(new OnQueryTextListener(this));
|
||||
searchView.SetSearchableInfo(searchManager.GetSearchableInfo(ComponentName));
|
||||
searchView.SetOnSuggestionListener(new SuggestionListener(searchView.SuggestionsAdapter, this, searchItem));
|
||||
searchView.SetOnQueryTextListener(new OnQueryTextListener(this));
|
||||
|
||||
var item = menu.FindItem(Resource.Id.menu_sync);
|
||||
if (item != null)
|
||||
{
|
||||
if (App.Kp2a.GetDb().Ioc.IsLocalFile())
|
||||
item.SetVisible(false);
|
||||
else
|
||||
item.SetVisible(true);
|
||||
var item = menu.FindItem(Resource.Id.menu_sync);
|
||||
if (item != null)
|
||||
{
|
||||
if (App.Kp2a.GetDb().Ioc.IsLocalFile())
|
||||
item.SetVisible(false);
|
||||
else
|
||||
item.SetVisible(true);
|
||||
}
|
||||
//return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
public override bool OnPrepareOptionsMenu(IMenu menu) {
|
||||
if ( ! base.OnPrepareOptionsMenu(menu) ) {
|
||||
@ -613,10 +624,10 @@ namespace keepass2android
|
||||
|
||||
public bool IsBeingMoved(PwUuid uuid)
|
||||
{
|
||||
MoveElementTask moveElementTask = AppTask as MoveElementTask;
|
||||
if (moveElementTask != null)
|
||||
MoveElementsTask moveElementsTask = AppTask as MoveElementsTask;
|
||||
if (moveElementsTask != null)
|
||||
{
|
||||
if (moveElementTask.Uuid.Equals(uuid))
|
||||
if (moveElementsTask.Uuids.Any(uuidMoved => uuidMoved.Equals(uuid)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -629,16 +640,16 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
|
||||
public void StartMovingElement()
|
||||
public void StartMovingElements()
|
||||
{
|
||||
|
||||
ShowInsertElementButtons();
|
||||
ShowInsertElementsButtons();
|
||||
//TODO Required? GroupView.ListView.InvalidateViews();
|
||||
BaseAdapter adapter = (BaseAdapter)ListAdapter;
|
||||
adapter.NotifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void ShowInsertElementButtons()
|
||||
public void ShowInsertElementsButtons()
|
||||
{
|
||||
FindViewById(Resource.Id.fabCancelAddNew).Visibility = ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabAddNewGroup).Visibility = ViewStates.Gone;
|
||||
@ -649,14 +660,17 @@ namespace keepass2android
|
||||
FindViewById(Resource.Id.divider2).Visibility = ViewStates.Visible;
|
||||
}
|
||||
|
||||
public void StopMovingElement()
|
||||
public void StopMovingElements()
|
||||
{
|
||||
try
|
||||
{
|
||||
MoveElementTask moveElementTask = (MoveElementTask)AppTask;
|
||||
IStructureItem elementToMove = App.Kp2a.GetDb().KpDatabase.RootGroup.FindObject(moveElementTask.Uuid, true, null);
|
||||
if (elementToMove.ParentGroup != Group)
|
||||
App.Kp2a.GetDb().Dirty.Add(elementToMove.ParentGroup);
|
||||
MoveElementsTask moveElementsTask = (MoveElementsTask)AppTask;
|
||||
foreach (var uuid in moveElementsTask.Uuids)
|
||||
{
|
||||
IStructureItem elementToMove = App.Kp2a.GetDb().KpDatabase.RootGroup.FindObject(uuid, true, null);
|
||||
if (elementToMove.ParentGroup != Group)
|
||||
App.Kp2a.GetDb().Dirty.Add(elementToMove.ParentGroup);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -680,7 +694,9 @@ namespace keepass2android
|
||||
|
||||
public class GroupListFragment : ListFragment, AbsListView.IMultiChoiceModeListener
|
||||
{
|
||||
public override void OnActivityCreated(Bundle savedInstanceState)
|
||||
private ActionMode _mode;
|
||||
|
||||
public override void OnActivityCreated(Bundle savedInstanceState)
|
||||
{
|
||||
base.OnActivityCreated(savedInstanceState);
|
||||
if (App.Kp2a.GetDb().CanWrite)
|
||||
@ -709,29 +725,53 @@ namespace keepass2android
|
||||
|
||||
public bool OnActionItemClicked(ActionMode mode, IMenuItem item)
|
||||
{
|
||||
var listView = FragmentManager.FindFragmentById<GroupListFragment>(Resource.Id.list_fragment).ListView;
|
||||
var checkedItemPositions = listView.CheckedItemPositions;
|
||||
|
||||
List<IStructureItem> checkedItems = new List<IStructureItem>();
|
||||
for (int i = 0; i < checkedItemPositions.Size(); i++)
|
||||
{
|
||||
if (checkedItemPositions.ValueAt(i))
|
||||
{
|
||||
//TODO make sure position is also correct when scrolling (more items in adapter than on screen)
|
||||
checkedItems.Add(((PwGroupListAdapter) ListAdapter).GetItemAtPosition(checkedItemPositions.KeyAt(i)));
|
||||
}
|
||||
}
|
||||
|
||||
//shouldn't happen, just in case...
|
||||
if (!checkedItems.Any())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (item.ItemId)
|
||||
{
|
||||
|
||||
case Resource.Id.menu_delete:
|
||||
/*Handler handler = new Handler();
|
||||
DeleteEntry task = new DeleteEntry(Activity, App.Kp2a, _entry,
|
||||
new GroupBaseActivity.RefreshTask(handler, ((GroupBaseActivity)Activity)));
|
||||
task.Start();*/
|
||||
Toast.MakeText(((GroupBaseActivity) Activity), "todo delete", ToastLength.Long).Show();
|
||||
return true;
|
||||
Handler handler = new Handler();
|
||||
DeleteMultipleItems task = new DeleteMultipleItems((GroupBaseActivity)Activity, App.Kp2a.GetDb(), checkedItems,
|
||||
new GroupBaseActivity.RefreshTask(handler, ((GroupBaseActivity)Activity)), App.Kp2a);
|
||||
task.Start();
|
||||
break;
|
||||
case Resource.Id.menu_move:
|
||||
/*NavigateToFolderAndLaunchMoveElementTask navMove =
|
||||
new NavigateToFolderAndLaunchMoveElementTask(_entry.ParentGroup, _entry.Uuid, _isSearchResult);
|
||||
((GroupBaseActivity)Activity).StartTask(navMove);*/
|
||||
Toast.MakeText(((GroupBaseActivity)Activity), "todo move", ToastLength.Long).Show();
|
||||
return true;
|
||||
/*TODO for search results case Resource.Id.menu_navigate:
|
||||
NavigateToFolder navNavigate = new NavigateToFolder(_entry.ParentGroup, true);
|
||||
((GroupBaseActivity)Activity).StartTask(navNavigate);
|
||||
return true;*/
|
||||
var navMove = new NavigateToFolderAndLaunchMoveElementTask(checkedItems.First().ParentGroup, checkedItems.Select(i => i.Uuid).ToList(), ((GroupBaseActivity)Activity).IsSearchResult);
|
||||
((GroupBaseActivity)Activity).StartTask(navMove);
|
||||
break;
|
||||
/*TODO for search results case Resource.Id.menu_navigate:
|
||||
NavigateToFolder navNavigate = new NavigateToFolder(_entry.ParentGroup, true);
|
||||
((GroupBaseActivity)Activity).StartTask(navNavigate);
|
||||
break;*/
|
||||
default:
|
||||
return false;
|
||||
|
||||
|
||||
}
|
||||
return false;
|
||||
listView.ClearChoices();
|
||||
((BaseAdapter)ListAdapter).NotifyDataSetChanged();
|
||||
if (_mode != null)
|
||||
mode.Finish();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool OnCreateActionMode(ActionMode mode, IMenu menu)
|
||||
@ -741,7 +781,7 @@ namespace keepass2android
|
||||
//mode.Title = "Select Items";
|
||||
Android.Util.Log.Debug("KP2A", "Create action mode" + mode);
|
||||
((PwGroupListAdapter)ListView.Adapter).NotifyDataSetChanged();
|
||||
|
||||
_mode = mode;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -750,6 +790,7 @@ namespace keepass2android
|
||||
Android.Util.Log.Debug("KP2A", "Destroy action mode" + mode);
|
||||
|
||||
((PwGroupListAdapter)ListView.Adapter).NotifyDataSetChanged();
|
||||
_mode = null;
|
||||
}
|
||||
|
||||
public bool OnPrepareActionMode(ActionMode mode, IMenu menu)
|
||||
|
@ -24,6 +24,7 @@ using Android.Widget;
|
||||
using Android.Preferences;
|
||||
using KeePassLib;
|
||||
using keepass2android.view;
|
||||
using KeePassLib.Interfaces;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
@ -327,7 +328,18 @@ namespace keepass2android
|
||||
|
||||
return ev;
|
||||
}
|
||||
|
||||
|
||||
public IStructureItem GetItemAtPosition(int keyAt)
|
||||
{
|
||||
if (keyAt < _groupsForViewing.Count)
|
||||
{
|
||||
return _groupsForViewing[keyAt];
|
||||
}
|
||||
else
|
||||
{
|
||||
return _entriesForViewing[keyAt - _groupsForViewing.Count];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -68,8 +68,8 @@ namespace keepass2android
|
||||
|
||||
if (App.Kp2a.GetDb().KpDatabase.Name != "")
|
||||
{
|
||||
FindViewById(Resource.Id.filename_label).Visibility = ViewStates.Invisible;
|
||||
((TextView) FindViewById(Resource.Id.qu_filename)).Text = App.Kp2a.GetDb().KpDatabase.Name;
|
||||
FindViewById(Resource.Id.filename_label).Visibility = ViewStates.Visible;
|
||||
((TextView) FindViewById(Resource.Id.filename_label)).Text = App.Kp2a.GetDb().KpDatabase.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -78,11 +78,11 @@ namespace keepass2android
|
||||
.GetBoolean(GetString(Resource.String.RememberRecentFiles_key),
|
||||
Resources.GetBoolean(Resource.Boolean.RememberRecentFiles_default)))
|
||||
{
|
||||
((TextView) FindViewById(Resource.Id.qu_filename)).Text = App.Kp2a.GetFileStorage(_ioc).GetDisplayName(_ioc);
|
||||
((TextView) FindViewById(Resource.Id.filename_label)).Text = App.Kp2a.GetFileStorage(_ioc).GetDisplayName(_ioc);
|
||||
}
|
||||
else
|
||||
{
|
||||
((TextView) FindViewById(Resource.Id.qu_filename)).Text = "*****";
|
||||
((TextView) FindViewById(Resource.Id.filename_label)).Text = "*****";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -77,7 +77,7 @@
|
||||
android:src="@drawable/toolbar_bg_quickunlock"
|
||||
app:layout_collapseMode="parallax" />
|
||||
<TextView
|
||||
android:id="@+id/qu_filename"
|
||||
android:id="@+id/filename_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
@ -114,7 +114,7 @@ android:paddingRight="16dp"
|
||||
android:text="@string/QuickUnlock_label"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/qu_filename"
|
||||
android:layout_below="@id/filename_label"
|
||||
android:textSize="14sp"
|
||||
/>
|
||||
|
||||
|
@ -20,5 +20,7 @@
|
||||
<TextView android:id="@+id/file_filename" xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="4sp"
|
||||
android:textColor="#cccccc"
|
||||
android:paddingTop="4sp"
|
||||
android:paddingBottom="4sp"
|
||||
/>
|
@ -26,14 +26,14 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:text="Insert here"
|
||||
android:text="@string/insert_element_here"
|
||||
style="@style/BottomBarButton" />
|
||||
<Button
|
||||
android:id="@+id/cancel_insert_element"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:text="Cancel"
|
||||
android:text="@string/cancel"
|
||||
style="@style/BottomBarButton" />
|
||||
</RelativeLayout>
|
||||
<View
|
||||
@ -47,6 +47,8 @@
|
||||
android:id="@+id/main_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_above="@id/divider2"
|
||||
android:layout_below="@id/top"
|
||||
android:fitsSystemWindows="true">
|
||||
<fragment
|
||||
android:name="keepass2android.GroupListFragment"
|
||||
|
@ -17,10 +17,9 @@
|
||||
<ListView
|
||||
android:id="@android:id/list"
|
||||
android:layout_weight="1"
|
||||
android:textColor="#cccccc"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:paddingRight="8dp"
|
||||
android:paddingLeft="8dp" />
|
||||
android:paddingRight="0dp"
|
||||
android:paddingLeft="0dp" />
|
||||
|
||||
</LinearLayout>
|
@ -9,7 +9,7 @@
|
||||
<string name="accept">Accept</string>
|
||||
<string name="deny">Deny</string>
|
||||
<string name="add_entry">Add entry</string>
|
||||
<string name="edit_entry">Add entry</string>
|
||||
<string name="edit_entry">Edit entry</string>
|
||||
<string name="add_url_entry">Create entry for URL</string>
|
||||
<string name="add_group">Add group</string>
|
||||
<string name="add_group_title">Add Group</string>
|
||||
@ -348,6 +348,7 @@
|
||||
<string name="RecycleBin">Recycle Bin</string>
|
||||
<string name="AskDeletePermanentlyEntry">Do you want to delete this entry permanently? Press No to recycle.</string>
|
||||
<string name="AskDeletePermanentlyGroup">Do you want to delete this group permanently? Press No to recycle.</string>
|
||||
<string name="AskDeletePermanentlyItems">Do you want to delete the selected elements permanently? Press No to recycle.</string>
|
||||
<string name="AskDeletePermanently_title">Delete permanently?</string>
|
||||
<string name="AskReloadFile_title">Reload file?</string>
|
||||
<string name="AskReloadFile">The file which is currently open was changed by another program. Do you want to reload it?</string>
|
||||
@ -360,6 +361,7 @@
|
||||
<string name="AddingGroup">Adding group…</string>
|
||||
<string name="DeletingEntry">Deleting entry…</string>
|
||||
<string name="DeletingGroup">Deleting group…</string>
|
||||
<string name="DeletingItems">Deleting elements…</string>
|
||||
<string name="SettingPassword">Setting password…</string>
|
||||
<string name="UndoingChanges">Undoing changes…</string>
|
||||
<string name="TransformingKey">Transforming master key…</string>
|
||||
|
@ -53,9 +53,14 @@ namespace keepass2android
|
||||
|
||||
|
||||
private Database _db;
|
||||
|
||||
|
||||
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
public override bool IsSearchResult
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
{
|
||||
base.OnCreate(savedInstanceState);
|
||||
|
||||
|
@ -5,6 +5,7 @@ using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Widget;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using KeePassLib;
|
||||
using KeePassLib.Security;
|
||||
using KeePassLib.Utility;
|
||||
@ -546,13 +547,13 @@ namespace keepass2android
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// User is about to move an entry or group to another group
|
||||
/// User is about to move entries and/or groups to another group
|
||||
/// </summary>
|
||||
public class MoveElementTask: AppTask
|
||||
public class MoveElementsTask: AppTask
|
||||
{
|
||||
public const String UuidKey = "MoveElement_Uuid";
|
||||
public const String UuidsKey = "MoveElement_Uuids";
|
||||
|
||||
public PwUuid Uuid
|
||||
public IEnumerable<PwUuid> Uuids
|
||||
{
|
||||
get;
|
||||
set;
|
||||
@ -560,23 +561,33 @@ namespace keepass2android
|
||||
|
||||
public override void Setup(Bundle b)
|
||||
{
|
||||
Uuid = new PwUuid(MemUtil.HexStringToByteArray(b.GetString(UuidKey)));
|
||||
}
|
||||
public override IEnumerable<IExtra> Extras
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new StringExtra { Key = UuidKey, Value = MemUtil.ByteArrayToHexString(Uuid.UuidBytes) };
|
||||
}
|
||||
Uuids = b.GetString(UuidsKey).Split(';')
|
||||
.Where(s => !String.IsNullOrEmpty(s))
|
||||
.Select(stringPart => new PwUuid(MemUtil.HexStringToByteArray(stringPart)))
|
||||
.ToList(); //property might be accessed several times, avoid parsing each time
|
||||
}
|
||||
|
||||
public override IEnumerable<IExtra> Extras
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new StringExtra
|
||||
{
|
||||
Key = UuidsKey,
|
||||
Value = Uuids.Select(uuid => MemUtil.ByteArrayToHexString(uuid.UuidBytes))
|
||||
.Aggregate((a, b) => a + ";" + b)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public override void StartInGroupActivity(GroupBaseActivity groupBaseActivity)
|
||||
{
|
||||
base.StartInGroupActivity(groupBaseActivity);
|
||||
groupBaseActivity.StartMovingElement();
|
||||
groupBaseActivity.StartMovingElements();
|
||||
}
|
||||
public override void SetupGroupBaseActivityButtons(GroupBaseActivity groupBaseActivity)
|
||||
{
|
||||
groupBaseActivity.ShowInsertElementButtons();
|
||||
groupBaseActivity.ShowInsertElementsButtons();
|
||||
}
|
||||
}
|
||||
|
||||
@ -902,19 +913,20 @@ namespace keepass2android
|
||||
|
||||
public class NavigateToFolderAndLaunchMoveElementTask: NavigateAndLaunchTask {
|
||||
|
||||
public NavigateToFolderAndLaunchMoveElementTask():base(){
|
||||
public NavigateToFolderAndLaunchMoveElementTask()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public NavigateToFolderAndLaunchMoveElementTask(PwGroup groups, PwUuid uuid, bool toastEnable = false)
|
||||
:base(groups, new MoveElementTask() { Uuid = uuid }, toastEnable) {
|
||||
public NavigateToFolderAndLaunchMoveElementTask(PwGroup groups, List<PwUuid> uuids, bool toastEnable = false)
|
||||
:base(groups, new MoveElementsTask() { Uuids = uuids }, toastEnable) {
|
||||
}
|
||||
|
||||
public override void Setup(Bundle b) {
|
||||
base.Setup(b);
|
||||
|
||||
TaskToBeLaunchedAfterNavigation = new MoveElementTask ();
|
||||
TaskToBeLaunchedAfterNavigation = new MoveElementsTask ();
|
||||
TaskToBeLaunchedAfterNavigation.Setup (b);
|
||||
|
||||
}
|
||||
|
@ -35,17 +35,18 @@
|
||||
<Command type="BeforeBuild" command="UseManifestDebug.bat" />
|
||||
</CustomCommands>
|
||||
</CustomCommands>
|
||||
<EmbedAssembliesIntoApk>False</EmbedAssembliesIntoApk>
|
||||
<EmbedAssembliesIntoApk>True</EmbedAssembliesIntoApk>
|
||||
<AndroidSupportedAbis>armeabi,armeabi-v7a,x86</AndroidSupportedAbis>
|
||||
<AndroidUseSharedRuntime>True</AndroidUseSharedRuntime>
|
||||
<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>
|
||||
<AndroidLinkSkip />
|
||||
<BundleAssemblies>False</BundleAssemblies>
|
||||
<AndroidCreatePackagePerAbi>False</AndroidCreatePackagePerAbi>
|
||||
<AndroidStoreUncompressedFileExtensions />
|
||||
<MandroidI18n />
|
||||
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
|
||||
<JavaOptions />
|
||||
<MonoDroidExtraArgs />
|
||||
<Debugger>Xamarin</Debugger>
|
||||
<AndroidEnableMultiDex>False</AndroidEnableMultiDex>
|
||||
<DevInstrumentationEnabled>True</DevInstrumentationEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>none</DebugType>
|
||||
@ -223,7 +224,9 @@
|
||||
<Compile Include="views\TextWithHelp.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\xml\searchable.xml" />
|
||||
<AndroidResource Include="Resources\xml\searchable.xml">
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
<AndroidAsset Include="Assets\fontawesome-webfont.ttf" />
|
||||
<AndroidAsset Include="Assets\SourceCodePro-Regular.ttf" />
|
||||
<None Include="packages.config" />
|
||||
@ -540,7 +543,7 @@
|
||||
<Name>KeePassLib2Android</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Kp2aBusinessLogic\Kp2aBusinessLogic.csproj">
|
||||
<Project>{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}</Project>
|
||||
<Project>{53a9cb7f-6553-4bc0-b56b-9410bb2e59aa}</Project>
|
||||
<Name>Kp2aBusinessLogic</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\KP2AKdbLibraryBinding\KP2AKdbLibraryBinding.csproj">
|
||||
@ -842,7 +845,9 @@
|
||||
<AndroidResource Include="Resources\drawable\ic_menu_copy_holo_light.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\xml\searchable_debug.xml" />
|
||||
<AndroidResource Include="Resources\xml\searchable_debug.xml">
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\device_access_new_account_holodark.png" />
|
||||
@ -1317,7 +1322,7 @@
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\ic_nav_about.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-mhdpi\ic_arrow_back_white_24dp.png" />
|
||||
<AndroidResource Include="Resources\drawable-mdpi\ic_arrow_back_white_24dp.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\ic_arrow_back_white_24dp.png" />
|
||||
|
@ -58,7 +58,8 @@ namespace keepass2android.search
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
protected override void OnNewIntent(Intent intent)
|
||||
{
|
||||
ProcessIntent(intent);
|
||||
@ -156,6 +157,11 @@ namespace keepass2android.search
|
||||
StartActivity(i);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool IsSearchResult
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ namespace keepass2android.view
|
||||
task.Start();
|
||||
return true;
|
||||
case MenuMove:
|
||||
_groupBaseActivity.StartTask(new MoveElementTask { Uuid = _pwGroup.Uuid });
|
||||
_groupBaseActivity.StartTask(new MoveElementsTask { Uuid = _pwGroup.Uuid });
|
||||
return true;
|
||||
case MenuEdit:
|
||||
_groupBaseActivity.EditGroup(_pwGroup);
|
||||
|
Loading…
Reference in New Issue
Block a user