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}.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.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.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.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.Build.0 = Release|Any CPU
|
||||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
|
||||||
|
@ -56,8 +56,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="database\CheckDatabaseForChanges.cs" />
|
<Compile Include="database\CheckDatabaseForChanges.cs" />
|
||||||
|
<Compile Include="database\edit\DeleteMultipleItems.cs" />
|
||||||
<Compile Include="database\edit\EditGroup.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\KdbDatabaseFormat.cs" />
|
||||||
<Compile Include="database\KdbxDatabaseFormat.cs" />
|
<Compile Include="database\KdbxDatabaseFormat.cs" />
|
||||||
<Compile Include="database\PwEntryOutput.cs" />
|
<Compile Include="database\PwEntryOutput.cs" />
|
||||||
|
@ -57,6 +57,8 @@ namespace keepass2android
|
|||||||
CopyFileRequiredForEditing,
|
CopyFileRequiredForEditing,
|
||||||
DuplicateUuidsError,
|
DuplicateUuidsError,
|
||||||
DuplicateUuidsErrorAdditional,
|
DuplicateUuidsErrorAdditional,
|
||||||
KdbBetaWarning
|
KdbBetaWarning,
|
||||||
|
DeletingItems,
|
||||||
|
AskDeletePermanentlyItems
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,17 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
|
using KeePassLib.Interfaces;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
public class DeleteEntry : DeleteRunnable {
|
public class DeleteEntry : DeleteRunnable {
|
||||||
|
|
||||||
private readonly PwEntry _entry;
|
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;
|
Ctx = ctx;
|
||||||
@ -48,76 +51,15 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Run()
|
protected override void PerformDelete(List<PwGroup> touchedGroups, List<PwGroup> permanentlyDeletedGroups)
|
||||||
{
|
{
|
||||||
StatusLogger.UpdateMessage(UiStringKey.DeletingEntry);
|
DoDeleteEntry(_entry, touchedGroups);
|
||||||
PwDatabase pd = Db.KpDatabase;
|
}
|
||||||
|
|
||||||
PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true);
|
public override UiStringKey StatusMessage
|
||||||
|
|
||||||
bool bUpdateGroupList = false;
|
|
||||||
DateTime dtNow = DateTime.Now;
|
|
||||||
PwEntry pe = _entry;
|
|
||||||
PwGroup pgParent = pe.ParentGroup;
|
|
||||||
if(pgParent != null)
|
|
||||||
{
|
{
|
||||||
pgParent.Entries.Remove(pe);
|
get { return UiStringKey.DeletingEntry; }
|
||||||
//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();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
|
|
||||||
@ -68,95 +69,14 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void PerformDelete(List<PwGroup> touchedGroups, List<PwGroup> permanentlyDeletedGroups)
|
||||||
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);
|
DoDeleteGroup(_group, touchedGroups, permanentlyDeletedGroups);
|
||||||
|
|
||||||
PwDeletedObject pdo = new PwDeletedObject(pg.Uuid, DateTime.Now);
|
|
||||||
pd.DeletedObjects.Add(pdo);
|
|
||||||
_onFinishToRun = new AfterDeletePermanently(OnFinishToRun, App, _group);
|
|
||||||
}
|
}
|
||||||
else // Recycle
|
|
||||||
|
public override UiStringKey StatusMessage
|
||||||
{
|
{
|
||||||
bool groupListUpdateRequired = false;
|
get { return UiStringKey.DeletingGroup; }
|
||||||
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);
|
|
||||||
|
|
||||||
// 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();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
|
|
||||||
@ -5,7 +7,8 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
public abstract class DeleteRunnable : RunnableOnFinish
|
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;
|
||||||
}
|
}
|
||||||
@ -44,24 +47,33 @@ namespace keepass2android
|
|||||||
|
|
||||||
protected bool CanRecycleGroup(PwGroup pgParent)
|
protected bool CanRecycleGroup(PwGroup pgParent)
|
||||||
{
|
{
|
||||||
bool bShiftPressed = false;
|
|
||||||
PwDatabase pd = Db.KpDatabase;
|
PwDatabase pd = Db.KpDatabase;
|
||||||
PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true);
|
PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true);
|
||||||
bool bPermanent = false;
|
bool bPermanent = false;
|
||||||
if (pgParent != null)
|
if (pgParent != null)
|
||||||
{
|
{
|
||||||
if (pd.RecycleBinEnabled == false)
|
if (pd.RecycleBinEnabled == false)
|
||||||
|
{
|
||||||
|
Android.Util.Log.Debug("KP2A", "CanRecycle? No, RecycleBinIsNotEnabled");
|
||||||
bPermanent = true;
|
bPermanent = true;
|
||||||
else if (bShiftPressed)
|
}
|
||||||
bPermanent = true;
|
|
||||||
else if (pgRecycleBin == null)
|
else if (pgRecycleBin == null)
|
||||||
{
|
{
|
||||||
} // Recycle
|
} // Recycle
|
||||||
else if (pgParent == pgRecycleBin)
|
else if (pgParent == pgRecycleBin)
|
||||||
|
{
|
||||||
|
Android.Util.Log.Debug("KP2A", "CanRecycle? No, Can't recycle RecycleBin");
|
||||||
bPermanent = true;
|
bPermanent = true;
|
||||||
|
}
|
||||||
|
|
||||||
else if (pgParent.IsContainedIn(pgRecycleBin))
|
else if (pgParent.IsContainedIn(pgRecycleBin))
|
||||||
|
{
|
||||||
|
Android.Util.Log.Debug("KP2A", "CanRecycle? No, "+pgParent.Name+" is in RecycleBin");
|
||||||
bPermanent = true;
|
bPermanent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
return !bPermanent;
|
return !bPermanent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +124,8 @@ namespace keepass2android
|
|||||||
ProgressTask pt = new ProgressTask(App, Ctx, this);
|
ProgressTask pt = new ProgressTask(App, Ctx, this);
|
||||||
pt.Run();
|
pt.Run();
|
||||||
},
|
},
|
||||||
(dlgSender, dlgEvt) => {
|
(dlgSender, dlgEvt) =>
|
||||||
|
{
|
||||||
DeletePermanently = false;
|
DeletePermanently = false;
|
||||||
ProgressTask pt = new ProgressTask(App, Ctx, this);
|
ProgressTask pt = new ProgressTask(App, Ctx, this);
|
||||||
pt.Run();
|
pt.Run();
|
||||||
@ -122,13 +135,131 @@ namespace keepass2android
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
ProgressTask pt = new ProgressTask(App, Ctx, this);
|
ProgressTask pt = new ProgressTask(App, Ctx, this);
|
||||||
pt.Run();
|
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
|
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;
|
FindViewById(Resource.Id.entry_tags).Visibility = ViewStates.Gone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ using Android.Content.PM;
|
|||||||
namespace keepass2android
|
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")]
|
[MetaData("android.app.default_searchable",Value="keepass2android.search.SearchResults")]
|
||||||
public class GroupActivity : GroupBaseActivity {
|
public class GroupActivity : GroupBaseActivity {
|
||||||
|
|
||||||
@ -83,6 +84,10 @@ namespace keepass2android
|
|||||||
get { return App.Kp2a.GetDb().CanWrite && ((this.Group.ParentGroup != null) || App.Kp2a.GetDb().DatabaseFormat.CanHaveEntriesInRootGroup); }
|
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)
|
||||||
{
|
{
|
||||||
|
@ -16,6 +16,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Android.App;
|
using Android.App;
|
||||||
@ -182,6 +183,7 @@ namespace keepass2android
|
|||||||
private String strCachedGroupUuid = null;
|
private String strCachedGroupUuid = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public String UuidGroup {
|
public String UuidGroup {
|
||||||
get {
|
get {
|
||||||
if (strCachedGroupUuid == null) {
|
if (strCachedGroupUuid == null) {
|
||||||
@ -222,6 +224,11 @@ namespace keepass2android
|
|||||||
get { return (BaseAdapter) FragmentManager.FindFragmentById<GroupListFragment>(Resource.Id.list_fragment).ListAdapter; }
|
get { return (BaseAdapter) FragmentManager.FindFragmentById<GroupListFragment>(Resource.Id.list_fragment).ListAdapter; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual bool IsSearchResult
|
||||||
|
{
|
||||||
|
get { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
/*TODO
|
/*TODO
|
||||||
* protected override void OnListItemClick(ListView l, View v, int position, long id) {
|
* protected override void OnListItemClick(ListView l, View v, int position, long id) {
|
||||||
base.OnListItemClick(l, v, position, id);
|
base.OnListItemClick(l, v, position, id);
|
||||||
@ -235,6 +242,8 @@ namespace keepass2android
|
|||||||
protected override void OnCreate(Bundle savedInstanceState) {
|
protected override void OnCreate(Bundle savedInstanceState) {
|
||||||
base.OnCreate(savedInstanceState);
|
base.OnCreate(savedInstanceState);
|
||||||
|
|
||||||
|
Android.Util.Log.Debug("KP2A", "Creating GBA");
|
||||||
|
|
||||||
AppTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent);
|
AppTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent);
|
||||||
|
|
||||||
// Likely the app has been killed exit the activity
|
// 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.cancel_insert_element).Click += (sender, args) => StopMovingElements();
|
||||||
FindViewById(Resource.Id.insert_element).Click += (sender, args) => InsertElement();
|
FindViewById(Resource.Id.insert_element).Click += (sender, args) => InsertElements();
|
||||||
|
|
||||||
SetResult(KeePass.ExitNormal);
|
SetResult(KeePass.ExitNormal);
|
||||||
|
|
||||||
@ -275,13 +284,15 @@ namespace keepass2android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InsertElement()
|
private void InsertElements()
|
||||||
{
|
{
|
||||||
MoveElementTask moveElementTask = (MoveElementTask)AppTask;
|
MoveElementsTask moveElementsTask = (MoveElementsTask)AppTask;
|
||||||
IStructureItem elementToMove = App.Kp2a.GetDb().KpDatabase.RootGroup.FindObject(moveElementTask.Uuid, true, null);
|
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);
|
var progressTask = new ProgressTask(App.Kp2a, this, moveElement);
|
||||||
progressTask.Run();
|
progressTask.Run();
|
||||||
|
|
||||||
@ -381,9 +392,9 @@ namespace keepass2android
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
public override bool OnCreateOptionsMenu(IMenu menu) {
|
public override bool OnCreateOptionsMenu(IMenu menu) {
|
||||||
base.OnCreateOptionsMenu(menu);
|
return base.OnCreateOptionsMenu(menu);
|
||||||
|
|
||||||
MenuInflater inflater = MenuInflater;
|
MenuInflater inflater = MenuInflater;
|
||||||
inflater.Inflate(Resource.Menu.group, menu);
|
inflater.Inflate(Resource.Menu.group, menu);
|
||||||
@ -404,9 +415,9 @@ namespace keepass2android
|
|||||||
else
|
else
|
||||||
item.SetVisible(true);
|
item.SetVisible(true);
|
||||||
}
|
}
|
||||||
|
//return true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -613,10 +624,10 @@ namespace keepass2android
|
|||||||
|
|
||||||
public bool IsBeingMoved(PwUuid uuid)
|
public bool IsBeingMoved(PwUuid uuid)
|
||||||
{
|
{
|
||||||
MoveElementTask moveElementTask = AppTask as MoveElementTask;
|
MoveElementsTask moveElementsTask = AppTask as MoveElementsTask;
|
||||||
if (moveElementTask != null)
|
if (moveElementsTask != null)
|
||||||
{
|
{
|
||||||
if (moveElementTask.Uuid.Equals(uuid))
|
if (moveElementsTask.Uuids.Any(uuidMoved => uuidMoved.Equals(uuid)))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -629,16 +640,16 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void StartMovingElement()
|
public void StartMovingElements()
|
||||||
{
|
{
|
||||||
|
|
||||||
ShowInsertElementButtons();
|
ShowInsertElementsButtons();
|
||||||
//TODO Required? GroupView.ListView.InvalidateViews();
|
//TODO Required? GroupView.ListView.InvalidateViews();
|
||||||
BaseAdapter adapter = (BaseAdapter)ListAdapter;
|
BaseAdapter adapter = (BaseAdapter)ListAdapter;
|
||||||
adapter.NotifyDataSetChanged();
|
adapter.NotifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ShowInsertElementButtons()
|
public void ShowInsertElementsButtons()
|
||||||
{
|
{
|
||||||
FindViewById(Resource.Id.fabCancelAddNew).Visibility = ViewStates.Gone;
|
FindViewById(Resource.Id.fabCancelAddNew).Visibility = ViewStates.Gone;
|
||||||
FindViewById(Resource.Id.fabAddNewGroup).Visibility = ViewStates.Gone;
|
FindViewById(Resource.Id.fabAddNewGroup).Visibility = ViewStates.Gone;
|
||||||
@ -649,15 +660,18 @@ namespace keepass2android
|
|||||||
FindViewById(Resource.Id.divider2).Visibility = ViewStates.Visible;
|
FindViewById(Resource.Id.divider2).Visibility = ViewStates.Visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StopMovingElement()
|
public void StopMovingElements()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MoveElementTask moveElementTask = (MoveElementTask)AppTask;
|
MoveElementsTask moveElementsTask = (MoveElementsTask)AppTask;
|
||||||
IStructureItem elementToMove = App.Kp2a.GetDb().KpDatabase.RootGroup.FindObject(moveElementTask.Uuid, true, null);
|
foreach (var uuid in moveElementsTask.Uuids)
|
||||||
|
{
|
||||||
|
IStructureItem elementToMove = App.Kp2a.GetDb().KpDatabase.RootGroup.FindObject(uuid, true, null);
|
||||||
if (elementToMove.ParentGroup != Group)
|
if (elementToMove.ParentGroup != Group)
|
||||||
App.Kp2a.GetDb().Dirty.Add(elementToMove.ParentGroup);
|
App.Kp2a.GetDb().Dirty.Add(elementToMove.ParentGroup);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
//don't crash if adding to dirty fails but log the exception:
|
//don't crash if adding to dirty fails but log the exception:
|
||||||
@ -680,6 +694,8 @@ namespace keepass2android
|
|||||||
|
|
||||||
public class GroupListFragment : ListFragment, AbsListView.IMultiChoiceModeListener
|
public class GroupListFragment : ListFragment, AbsListView.IMultiChoiceModeListener
|
||||||
{
|
{
|
||||||
|
private ActionMode _mode;
|
||||||
|
|
||||||
public override void OnActivityCreated(Bundle savedInstanceState)
|
public override void OnActivityCreated(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
base.OnActivityCreated(savedInstanceState);
|
base.OnActivityCreated(savedInstanceState);
|
||||||
@ -709,29 +725,53 @@ namespace keepass2android
|
|||||||
|
|
||||||
public bool OnActionItemClicked(ActionMode mode, IMenuItem item)
|
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)
|
switch (item.ItemId)
|
||||||
{
|
{
|
||||||
|
|
||||||
case Resource.Id.menu_delete:
|
case Resource.Id.menu_delete:
|
||||||
/*Handler handler = new Handler();
|
Handler handler = new Handler();
|
||||||
DeleteEntry task = new DeleteEntry(Activity, App.Kp2a, _entry,
|
DeleteMultipleItems task = new DeleteMultipleItems((GroupBaseActivity)Activity, App.Kp2a.GetDb(), checkedItems,
|
||||||
new GroupBaseActivity.RefreshTask(handler, ((GroupBaseActivity)Activity)));
|
new GroupBaseActivity.RefreshTask(handler, ((GroupBaseActivity)Activity)), App.Kp2a);
|
||||||
task.Start();*/
|
task.Start();
|
||||||
Toast.MakeText(((GroupBaseActivity) Activity), "todo delete", ToastLength.Long).Show();
|
break;
|
||||||
return true;
|
|
||||||
case Resource.Id.menu_move:
|
case Resource.Id.menu_move:
|
||||||
/*NavigateToFolderAndLaunchMoveElementTask navMove =
|
var navMove = new NavigateToFolderAndLaunchMoveElementTask(checkedItems.First().ParentGroup, checkedItems.Select(i => i.Uuid).ToList(), ((GroupBaseActivity)Activity).IsSearchResult);
|
||||||
new NavigateToFolderAndLaunchMoveElementTask(_entry.ParentGroup, _entry.Uuid, _isSearchResult);
|
((GroupBaseActivity)Activity).StartTask(navMove);
|
||||||
((GroupBaseActivity)Activity).StartTask(navMove);*/
|
break;
|
||||||
Toast.MakeText(((GroupBaseActivity)Activity), "todo move", ToastLength.Long).Show();
|
|
||||||
return true;
|
|
||||||
/*TODO for search results case Resource.Id.menu_navigate:
|
/*TODO for search results case Resource.Id.menu_navigate:
|
||||||
NavigateToFolder navNavigate = new NavigateToFolder(_entry.ParentGroup, true);
|
NavigateToFolder navNavigate = new NavigateToFolder(_entry.ParentGroup, true);
|
||||||
((GroupBaseActivity)Activity).StartTask(navNavigate);
|
((GroupBaseActivity)Activity).StartTask(navNavigate);
|
||||||
return true;*/
|
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)
|
public bool OnCreateActionMode(ActionMode mode, IMenu menu)
|
||||||
@ -741,7 +781,7 @@ namespace keepass2android
|
|||||||
//mode.Title = "Select Items";
|
//mode.Title = "Select Items";
|
||||||
Android.Util.Log.Debug("KP2A", "Create action mode" + mode);
|
Android.Util.Log.Debug("KP2A", "Create action mode" + mode);
|
||||||
((PwGroupListAdapter)ListView.Adapter).NotifyDataSetChanged();
|
((PwGroupListAdapter)ListView.Adapter).NotifyDataSetChanged();
|
||||||
|
_mode = mode;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -750,6 +790,7 @@ namespace keepass2android
|
|||||||
Android.Util.Log.Debug("KP2A", "Destroy action mode" + mode);
|
Android.Util.Log.Debug("KP2A", "Destroy action mode" + mode);
|
||||||
|
|
||||||
((PwGroupListAdapter)ListView.Adapter).NotifyDataSetChanged();
|
((PwGroupListAdapter)ListView.Adapter).NotifyDataSetChanged();
|
||||||
|
_mode = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OnPrepareActionMode(ActionMode mode, IMenu menu)
|
public bool OnPrepareActionMode(ActionMode mode, IMenu menu)
|
||||||
|
@ -24,6 +24,7 @@ using Android.Widget;
|
|||||||
using Android.Preferences;
|
using Android.Preferences;
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
using keepass2android.view;
|
using keepass2android.view;
|
||||||
|
using KeePassLib.Interfaces;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
@ -328,6 +329,17 @@ namespace keepass2android
|
|||||||
return ev;
|
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 != "")
|
if (App.Kp2a.GetDb().KpDatabase.Name != "")
|
||||||
{
|
{
|
||||||
FindViewById(Resource.Id.filename_label).Visibility = ViewStates.Invisible;
|
FindViewById(Resource.Id.filename_label).Visibility = ViewStates.Visible;
|
||||||
((TextView) FindViewById(Resource.Id.qu_filename)).Text = App.Kp2a.GetDb().KpDatabase.Name;
|
((TextView) FindViewById(Resource.Id.filename_label)).Text = App.Kp2a.GetDb().KpDatabase.Name;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -78,11 +78,11 @@ namespace keepass2android
|
|||||||
.GetBoolean(GetString(Resource.String.RememberRecentFiles_key),
|
.GetBoolean(GetString(Resource.String.RememberRecentFiles_key),
|
||||||
Resources.GetBoolean(Resource.Boolean.RememberRecentFiles_default)))
|
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
|
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"
|
android:src="@drawable/toolbar_bg_quickunlock"
|
||||||
app:layout_collapseMode="parallax" />
|
app:layout_collapseMode="parallax" />
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/qu_filename"
|
android:id="@+id/filename_label"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
@ -114,7 +114,7 @@ android:paddingRight="16dp"
|
|||||||
android:text="@string/QuickUnlock_label"
|
android:text="@string/QuickUnlock_label"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/qu_filename"
|
android:layout_below="@id/filename_label"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -20,5 +20,7 @@
|
|||||||
<TextView android:id="@+id/file_filename" xmlns:android="http://schemas.android.com/apk/res/android"
|
<TextView android:id="@+id/file_filename" xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
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_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentLeft="true"
|
||||||
android:text="Insert here"
|
android:text="@string/insert_element_here"
|
||||||
style="@style/BottomBarButton" />
|
style="@style/BottomBarButton" />
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/cancel_insert_element"
|
android:id="@+id/cancel_insert_element"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:text="Cancel"
|
android:text="@string/cancel"
|
||||||
style="@style/BottomBarButton" />
|
style="@style/BottomBarButton" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
<View
|
<View
|
||||||
@ -47,6 +47,8 @@
|
|||||||
android:id="@+id/main_content"
|
android:id="@+id/main_content"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:layout_above="@id/divider2"
|
||||||
|
android:layout_below="@id/top"
|
||||||
android:fitsSystemWindows="true">
|
android:fitsSystemWindows="true">
|
||||||
<fragment
|
<fragment
|
||||||
android:name="keepass2android.GroupListFragment"
|
android:name="keepass2android.GroupListFragment"
|
||||||
|
@ -17,10 +17,9 @@
|
|||||||
<ListView
|
<ListView
|
||||||
android:id="@android:id/list"
|
android:id="@android:id/list"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:textColor="#cccccc"
|
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:paddingRight="8dp"
|
android:paddingRight="0dp"
|
||||||
android:paddingLeft="8dp" />
|
android:paddingLeft="0dp" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -9,7 +9,7 @@
|
|||||||
<string name="accept">Accept</string>
|
<string name="accept">Accept</string>
|
||||||
<string name="deny">Deny</string>
|
<string name="deny">Deny</string>
|
||||||
<string name="add_entry">Add entry</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_url_entry">Create entry for URL</string>
|
||||||
<string name="add_group">Add group</string>
|
<string name="add_group">Add group</string>
|
||||||
<string name="add_group_title">Add Group</string>
|
<string name="add_group_title">Add Group</string>
|
||||||
@ -348,6 +348,7 @@
|
|||||||
<string name="RecycleBin">Recycle Bin</string>
|
<string name="RecycleBin">Recycle Bin</string>
|
||||||
<string name="AskDeletePermanentlyEntry">Do you want to delete this entry permanently? Press No to recycle.</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="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="AskDeletePermanently_title">Delete permanently?</string>
|
||||||
<string name="AskReloadFile_title">Reload file?</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>
|
<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="AddingGroup">Adding group…</string>
|
||||||
<string name="DeletingEntry">Deleting entry…</string>
|
<string name="DeletingEntry">Deleting entry…</string>
|
||||||
<string name="DeletingGroup">Deleting group…</string>
|
<string name="DeletingGroup">Deleting group…</string>
|
||||||
|
<string name="DeletingItems">Deleting elements…</string>
|
||||||
<string name="SettingPassword">Setting password…</string>
|
<string name="SettingPassword">Setting password…</string>
|
||||||
<string name="UndoingChanges">Undoing changes…</string>
|
<string name="UndoingChanges">Undoing changes…</string>
|
||||||
<string name="TransformingKey">Transforming master key…</string>
|
<string name="TransformingKey">Transforming master key…</string>
|
||||||
|
@ -55,6 +55,11 @@ namespace keepass2android
|
|||||||
private Database _db;
|
private Database _db;
|
||||||
|
|
||||||
|
|
||||||
|
public override bool IsSearchResult
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnCreate(Bundle savedInstanceState)
|
protected override void OnCreate(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
base.OnCreate(savedInstanceState);
|
base.OnCreate(savedInstanceState);
|
||||||
|
@ -5,6 +5,7 @@ using Android.Content;
|
|||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
using KeePassLib.Security;
|
using KeePassLib.Security;
|
||||||
using KeePassLib.Utility;
|
using KeePassLib.Utility;
|
||||||
@ -546,13 +547,13 @@ namespace keepass2android
|
|||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <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>
|
/// </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;
|
get;
|
||||||
set;
|
set;
|
||||||
@ -560,23 +561,33 @@ namespace keepass2android
|
|||||||
|
|
||||||
public override void Setup(Bundle b)
|
public override void Setup(Bundle b)
|
||||||
{
|
{
|
||||||
Uuid = new PwUuid(MemUtil.HexStringToByteArray(b.GetString(UuidKey)));
|
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
|
public override IEnumerable<IExtra> Extras
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
yield return new StringExtra { Key = UuidKey, Value = MemUtil.ByteArrayToHexString(Uuid.UuidBytes) };
|
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)
|
public override void StartInGroupActivity(GroupBaseActivity groupBaseActivity)
|
||||||
{
|
{
|
||||||
base.StartInGroupActivity(groupBaseActivity);
|
base.StartInGroupActivity(groupBaseActivity);
|
||||||
groupBaseActivity.StartMovingElement();
|
groupBaseActivity.StartMovingElements();
|
||||||
}
|
}
|
||||||
public override void SetupGroupBaseActivityButtons(GroupBaseActivity groupBaseActivity)
|
public override void SetupGroupBaseActivityButtons(GroupBaseActivity groupBaseActivity)
|
||||||
{
|
{
|
||||||
groupBaseActivity.ShowInsertElementButtons();
|
groupBaseActivity.ShowInsertElementsButtons();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -902,19 +913,20 @@ namespace keepass2android
|
|||||||
|
|
||||||
public class NavigateToFolderAndLaunchMoveElementTask: NavigateAndLaunchTask {
|
public class NavigateToFolderAndLaunchMoveElementTask: NavigateAndLaunchTask {
|
||||||
|
|
||||||
public NavigateToFolderAndLaunchMoveElementTask():base(){
|
public NavigateToFolderAndLaunchMoveElementTask()
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public NavigateToFolderAndLaunchMoveElementTask(PwGroup groups, PwUuid uuid, bool toastEnable = false)
|
public NavigateToFolderAndLaunchMoveElementTask(PwGroup groups, List<PwUuid> uuids, bool toastEnable = false)
|
||||||
:base(groups, new MoveElementTask() { Uuid = uuid }, toastEnable) {
|
:base(groups, new MoveElementsTask() { Uuids = uuids }, toastEnable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Setup(Bundle b) {
|
public override void Setup(Bundle b) {
|
||||||
base.Setup(b);
|
base.Setup(b);
|
||||||
|
|
||||||
TaskToBeLaunchedAfterNavigation = new MoveElementTask ();
|
TaskToBeLaunchedAfterNavigation = new MoveElementsTask ();
|
||||||
TaskToBeLaunchedAfterNavigation.Setup (b);
|
TaskToBeLaunchedAfterNavigation.Setup (b);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -35,17 +35,18 @@
|
|||||||
<Command type="BeforeBuild" command="UseManifestDebug.bat" />
|
<Command type="BeforeBuild" command="UseManifestDebug.bat" />
|
||||||
</CustomCommands>
|
</CustomCommands>
|
||||||
</CustomCommands>
|
</CustomCommands>
|
||||||
<EmbedAssembliesIntoApk>False</EmbedAssembliesIntoApk>
|
<EmbedAssembliesIntoApk>True</EmbedAssembliesIntoApk>
|
||||||
<AndroidSupportedAbis>armeabi,armeabi-v7a,x86</AndroidSupportedAbis>
|
<AndroidSupportedAbis>armeabi,armeabi-v7a,x86</AndroidSupportedAbis>
|
||||||
<AndroidUseSharedRuntime>True</AndroidUseSharedRuntime>
|
<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>
|
||||||
<AndroidLinkSkip />
|
<AndroidLinkSkip />
|
||||||
<BundleAssemblies>False</BundleAssemblies>
|
<BundleAssemblies>False</BundleAssemblies>
|
||||||
<AndroidCreatePackagePerAbi>False</AndroidCreatePackagePerAbi>
|
<AndroidCreatePackagePerAbi>False</AndroidCreatePackagePerAbi>
|
||||||
<AndroidStoreUncompressedFileExtensions />
|
<AndroidStoreUncompressedFileExtensions />
|
||||||
<MandroidI18n />
|
<MandroidI18n />
|
||||||
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
|
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
|
||||||
<JavaOptions />
|
<Debugger>Xamarin</Debugger>
|
||||||
<MonoDroidExtraArgs />
|
<AndroidEnableMultiDex>False</AndroidEnableMultiDex>
|
||||||
|
<DevInstrumentationEnabled>True</DevInstrumentationEnabled>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>none</DebugType>
|
<DebugType>none</DebugType>
|
||||||
@ -223,7 +224,9 @@
|
|||||||
<Compile Include="views\TextWithHelp.cs" />
|
<Compile Include="views\TextWithHelp.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<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\fontawesome-webfont.ttf" />
|
||||||
<AndroidAsset Include="Assets\SourceCodePro-Regular.ttf" />
|
<AndroidAsset Include="Assets\SourceCodePro-Regular.ttf" />
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
@ -540,7 +543,7 @@
|
|||||||
<Name>KeePassLib2Android</Name>
|
<Name>KeePassLib2Android</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\Kp2aBusinessLogic\Kp2aBusinessLogic.csproj">
|
<ProjectReference Include="..\Kp2aBusinessLogic\Kp2aBusinessLogic.csproj">
|
||||||
<Project>{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}</Project>
|
<Project>{53a9cb7f-6553-4bc0-b56b-9410bb2e59aa}</Project>
|
||||||
<Name>Kp2aBusinessLogic</Name>
|
<Name>Kp2aBusinessLogic</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\KP2AKdbLibraryBinding\KP2AKdbLibraryBinding.csproj">
|
<ProjectReference Include="..\KP2AKdbLibraryBinding\KP2AKdbLibraryBinding.csproj">
|
||||||
@ -842,7 +845,9 @@
|
|||||||
<AndroidResource Include="Resources\drawable\ic_menu_copy_holo_light.png" />
|
<AndroidResource Include="Resources\drawable\ic_menu_copy_holo_light.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AndroidResource Include="Resources\xml\searchable_debug.xml" />
|
<AndroidResource Include="Resources\xml\searchable_debug.xml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</AndroidResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AndroidResource Include="Resources\drawable-hdpi\device_access_new_account_holodark.png" />
|
<AndroidResource Include="Resources\drawable-hdpi\device_access_new_account_holodark.png" />
|
||||||
@ -1317,7 +1322,7 @@
|
|||||||
<AndroidResource Include="Resources\drawable-xhdpi\ic_nav_about.png" />
|
<AndroidResource Include="Resources\drawable-xhdpi\ic_nav_about.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<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>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AndroidResource Include="Resources\drawable-hdpi\ic_arrow_back_white_24dp.png" />
|
<AndroidResource Include="Resources\drawable-hdpi\ic_arrow_back_white_24dp.png" />
|
||||||
|
@ -59,6 +59,7 @@ namespace keepass2android.search
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected override void OnNewIntent(Intent intent)
|
protected override void OnNewIntent(Intent intent)
|
||||||
{
|
{
|
||||||
ProcessIntent(intent);
|
ProcessIntent(intent);
|
||||||
@ -156,6 +157,11 @@ namespace keepass2android.search
|
|||||||
StartActivity(i);
|
StartActivity(i);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool IsSearchResult
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ namespace keepass2android.view
|
|||||||
task.Start();
|
task.Start();
|
||||||
return true;
|
return true;
|
||||||
case MenuMove:
|
case MenuMove:
|
||||||
_groupBaseActivity.StartTask(new MoveElementTask { Uuid = _pwGroup.Uuid });
|
_groupBaseActivity.StartTask(new MoveElementsTask { Uuid = _pwGroup.Uuid });
|
||||||
return true;
|
return true;
|
||||||
case MenuEdit:
|
case MenuEdit:
|
||||||
_groupBaseActivity.EditGroup(_pwGroup);
|
_groupBaseActivity.EditGroup(_pwGroup);
|
||||||
|
Loading…
Reference in New Issue
Block a user