diff --git a/MacPass/Base.lproj/InspectorView.xib b/MacPass/Base.lproj/InspectorView.xib
index f8054422..4f490d22 100644
--- a/MacPass/Base.lproj/InspectorView.xib
+++ b/MacPass/Base.lproj/InspectorView.xib
@@ -50,7 +50,6 @@
268
{{57, 409}, {204, 17}}
-
_NS:1535
{249, 750}
@@ -100,7 +99,6 @@
{{20, 401}, {32, 32}}
-
_NS:9
YES
@@ -126,10 +124,10 @@
{278, 30}
-
_NS:9
HNHGradientView
@@ -165,7 +158,7 @@
12
{{0, 30}, {278, 369}}
-
+
_NS:9
@@ -175,7 +168,7 @@
256
{278, 369}
-
+
_NS:28
Entry
@@ -253,7 +246,6 @@
{278, 443}
-
_NS:9
NSView
@@ -956,110 +948,17 @@
- 3116
-
-
-
-
- HNHGradientView
- NSView
-
- IBProjectSource
- ./Classes/HNHGradientView.h
-
-
-
- MPInspectorViewController
- MPViewController
-
- showImagePopup:
- id
-
-
- showImagePopup:
-
- showImagePopup:
- id
-
-
-
- HNHGradientView
- NSTextField
- MPPopupImageView
- NSTextField
- NSTextField
- NSTextField
- NSTabView
-
-
-
- bottomBar
- HNHGradientView
-
-
- createdTextField
- NSTextField
-
-
- itemImageView
- MPPopupImageView
-
-
- itemNameTextField
- NSTextField
-
-
- modifiedTextField
- NSTextField
-
-
- noSelectionInfo
- NSTextField
-
-
- tabView
- NSTabView
-
-
-
- IBProjectSource
- ./Classes/MPInspectorViewController.h
-
-
-
- MPPopupImageView
- NSImageView
-
- IBProjectSource
- ./Classes/MPPopupImageView.h
-
-
-
- MPViewController
- NSViewController
-
- IBProjectSource
- ./Classes/MPViewController.h
-
-
-
- NSLayoutConstraint
- NSObject
-
- IBProjectSource
- ./Classes/NSLayoutConstraint.h
-
-
-
+ 3117
+
0
IBCocoaFramework
YES
3
-
- {128, 128}
- {15, 15}
-
+
+ NSActionTemplate
+ {15, 15}
+
YES
diff --git a/MacPass/MPEntryTableDataSource.m b/MacPass/MPEntryTableDataSource.m
index 501e52be..3eb3b8c9 100644
--- a/MacPass/MPEntryTableDataSource.m
+++ b/MacPass/MPEntryTableDataSource.m
@@ -28,8 +28,8 @@
if(![item isKindOfClass:[KPKEntry class]]) {
return NO;
}
- KPKEntry *entry = (KPKEntry *)item;
- [pboard writeObjects:@[entry.uuid]];
+ KPKEntry *draggedEntry = (KPKEntry *)item;
+ [pboard writeObjects:@[draggedEntry]];
return YES;
}
diff --git a/MacPass/MPOutlineDataSource.m b/MacPass/MPOutlineDataSource.m
index 67c77440..6ae6a8ec 100644
--- a/MacPass/MPOutlineDataSource.m
+++ b/MacPass/MPOutlineDataSource.m
@@ -18,8 +18,8 @@
@interface MPOutlineDataSource ()
-@property (weak) KPKGroup *draggedGroup;
-@property (weak) KPKEntry *draggedEntry;
+@property (weak) KPKGroup *localDraggedGroup;
+@property (weak) KPKEntry *localDraggedEntry;
@end
@@ -27,104 +27,173 @@
@implementation MPOutlineDataSource
- (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pasteboard {
- self.draggedGroup = nil;
if([items count] == 1) {
id item = [[items lastObject] representedObject];
if(![item isKindOfClass:[KPKGroup class]]) {
return NO;
}
- [pasteboard setString:self.draggedGroup.name forType:KPKGroupUTI];
- self.draggedGroup = item;
- return (nil != self.draggedGroup.parent);
+ KPKGroup *draggedGroup = item;
+ [pasteboard writeObjects:@[draggedGroup]];
+ return (nil != draggedGroup.parent);
}
return NO;
}
- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id)info proposedItem:(id)item proposedChildIndex:(NSInteger)index {
+
+ /* Clean up our local search */
+ self.localDraggedEntry = nil;
+ self.localDraggedGroup = nil;
+
info.animatesToDestination = YES;
- NSDragOperation oprationMask = NSDragOperationMove;
+ NSDragOperation operationMask = NSDragOperationMove;
/*
If we can support copy on drag, this can be used
to optain the dragging modifier mask the user presses
- if([info draggingSourceOperationMask] == NSDragOperationCopy) {
- oprationMask = NSDragOperationCopy;
- }
*/
-
- NSPasteboard *pasteBoard = [info draggingPasteboard];
- NSArray *types = [pasteBoard types];
- if([types count] > 1 || [types count] == 0) {
- return NSDragOperationNone; // We cannot work with more than one type
+ BOOL localCopy = NO;
+ if([info draggingSourceOperationMask] == NSDragOperationCopy) {
+ operationMask = NSDragOperationCopy;
+ localCopy = YES;
}
-
+
+
+ /* Check if the Target is the root group */
id targetItem = [item representedObject];
- if( ![targetItem isKindOfClass:[KPKGroup class]] && ![targetItem isKindOfClass:[KPKEntry class]]) {
+ if( ![targetItem isKindOfClass:[KPKGroup class]] ) {
return NSDragOperationNone; // Block all unknown types
}
- MPDocument *document = [[[outlineView window] windowController] document];
- NSString *draggedType = [types lastObject];
- if([draggedType isEqualToString:KPKGroupUTI]) {
- // dragging group
- self.draggedEntry = nil;
- }
- else if([draggedType isEqualToString:KPKUUIDUTI]) {
- NSArray *uuids = [pasteBoard readObjectsForClasses:@[[NSUUID class]] options:nil];
- if([uuids count] != 1) {
- return NSDragOperationNone; // NO entry readable
- }
- self.draggedGroup = nil;
- self.draggedEntry = [document findEntry:[uuids lastObject]];
- }
- else {
- return NSDragOperationNone; // unkonw type
+
+ NSPasteboard *pasteBoard = [info draggingPasteboard];
+ KPKGroup *draggedGroup = nil;
+ KPKEntry *draggedEntry = nil;
+ BOOL couldReadPasteboard = [self _readDataFromPasteboard:pasteBoard group:&draggedGroup entry:&draggedEntry];
+ if(!couldReadPasteboard) {
+ return NSDragOperationNone;
}
KPKGroup *targetGroup = targetItem;
BOOL validTarget = YES;
- if(self.draggedGroup) {
- if( self.draggedGroup == targetGroup ) {
+ MPDocument *document = [[[outlineView window] windowController] document];
+ /* Dragging Groups */
+ if(draggedGroup) {
+ self.localDraggedGroup = [document findGroup:draggedGroup.uuid];
+ if( [draggedGroup.uuid isEqual:targetGroup.uuid] ) {
return NSDragOperationNone; // Groups cannot be moved inside themselves
}
- if( self.draggedGroup.parent == targetGroup ) {
- validTarget &= index != NSOutlineViewDropOnItemIndex;
- validTarget &= index != [self.draggedGroup.parent.groups indexOfObject:self.draggedGroup];
+ if(self.localDraggedGroup) {
+ if( self.localDraggedGroup.parent == targetGroup ) {
+ validTarget &= index != NSOutlineViewDropOnItemIndex;
+ validTarget &= index != [self.localDraggedGroup.parent.groups indexOfObject:self.localDraggedGroup];
+ }
+ BOOL isAnchesor = [self.localDraggedGroup isAnchestorOfGroup:targetGroup];
+ validTarget &= !isAnchesor;
+ }
+ else {
+ operationMask = NSDragOperationCopy;
}
- BOOL isAnchesor = [self.draggedGroup isAnchestorOfGroup:targetGroup];
- validTarget &= !isAnchesor;
}
- else if(self.draggedEntry) {
- validTarget = self.draggedEntry.parent != targetGroup;
- [outlineView setDropItem:item dropChildIndex:NSOutlineViewDropOnItemIndex];
+ else if(draggedEntry) {
+ self.localDraggedEntry = [document findEntry:draggedEntry.uuid];
+ if(self.localDraggedEntry) {
+ /* local Copy is always valid regardless of parent */
+ validTarget = localCopy ? YES : self.localDraggedEntry.parent != targetGroup;
+ [outlineView setDropItem:item dropChildIndex:NSOutlineViewDropOnItemIndex];
+ }
+ else {
+ /* Entry copy is always valid */
+ operationMask = NSDragOperationCopy;
+ }
}
- return validTarget ? oprationMask : NSDragOperationNone;
+ return validTarget ? operationMask : NSDragOperationNone;
}
- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id)info item:(id)item childIndex:(NSInteger)index {
info.animatesToDestination = YES;
- NSPasteboard *pasteBoard = [info draggingPasteboard];
- NSArray *types = [pasteBoard types];
- if([types count] > 1 || [types count] == 0) {
- return NO; // We cannot work with more than one type
- }
id targetItem = [item representedObject];
if(![targetItem isKindOfClass:[KPKGroup class]]) {
return NO; // Wrong
}
+ NSPasteboard *pasteBoard = [info draggingPasteboard];
+ KPKGroup *draggedGroup = nil;
+ KPKEntry *draggedEntry = nil;
+ BOOL validPateboard = [self _readDataFromPasteboard:pasteBoard group:&draggedGroup entry:&draggedEntry];
+ if(!validPateboard) {
+ return NO;
+ }
+
+ BOOL copyItem = ([info draggingSourceOperationMask] == NSDragOperationCopy);
+
KPKGroup *targetGroup = (KPKGroup *)targetItem;
+ if(draggedGroup) {
+ if(copyItem || (nil == self.localDraggedGroup) ) {
+ /*
+ Scenarios:
+ a) Local copy
+ b) Drag from other document
+ */
+ return NO;
+ }
+ else if(self.localDraggedGroup) {
+ /* Simple move */
+ [self.localDraggedGroup moveToGroup:targetGroup atIndex:index];
+ [self.localDraggedGroup.undoManager setActionName:NSLocalizedString(@"MOVE_GROUP", "")];
+ return YES;
+ }
+ /* Nothing valid */
+ return NO;
+ }
+ else if(draggedEntry) {
+ if(copyItem || (nil == self.localDraggedEntry)) {
+ /*
+ Scenarios:
+ a) Local copy
+ b) Drag from other document
+ */
+ return NO;
+ }
+ else if(self.localDraggedEntry) {
+ [self.localDraggedEntry moveToGroup:targetGroup atIndex:index];
+ [self.localDraggedEntry.undoManager setActionName:NSLocalizedString(@"MOVE_ENTRY", "")];
+ return YES;
+ }
+ }
+ return NO;
+}
+
+- (BOOL)_readDataFromPasteboard:(NSPasteboard *)pasteboard group:(KPKGroup **)group entry:(KPKEntry **)entry;{
+
+ if(entry == NULL || group == NULL) {
+ return NO; // Need valid pointers
+ }
+ /* Cleanup old stuff */
+
+ NSArray *types = [pasteboard types];
+ if([types count] > 1 || [types count] == 0) {
+ return NO;
+ }
NSString *draggedType = [types lastObject];
if([draggedType isEqualToString:KPKGroupUTI]) {
- [self.draggedGroup moveToGroup:targetGroup atIndex:index];
- [self.draggedGroup.undoManager setActionName:NSLocalizedString(@"MOVE_GROUP", "")];
+ // dragging group
+ NSArray *groups = [pasteboard readObjectsForClasses:@[[KPKGroup class]] options:nil];
+ if([groups count] != 1) {
+ return NO;
+ }
+ *group = [groups lastObject];
return YES;
}
- else if([draggedType isEqualToString:KPKUUIDUTI]) {
- [self.draggedEntry moveToGroup:targetGroup atIndex:index];
- [self.draggedEntry.undoManager setActionName:NSLocalizedString(@"MOVE_ENTRY", "")];
+ else if([draggedType isEqualToString:KPKEntryUTI]) {
+ NSArray *entries = [pasteboard readObjectsForClasses:@[[KPKEntry class]] options:nil];
+ if([entries count] != 1) {
+ return NO; // NO entry readable
+ }
+ *entry = [entries lastObject];
return YES;
}
return NO;
}
+
@end
diff --git a/MacPass/MPOutlineViewController.m b/MacPass/MPOutlineViewController.m
index 0dbb0272..0f5e4bad 100644
--- a/MacPass/MPOutlineViewController.m
+++ b/MacPass/MPOutlineViewController.m
@@ -73,7 +73,7 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
[_outlineView setMenu:[self _contextMenu]];
[_outlineView setAllowsEmptySelection:YES];
[_outlineView setFloatsGroupRows:NO];
- [_outlineView registerForDraggedTypes:@[ KPKGroupUTI, KPKUUIDUTI ]];
+ [_outlineView registerForDraggedTypes:@[ KPKGroupUTI, KPKEntryUTI ]];
[_outlineView setDraggingSourceOperationMask:NSDragOperationEvery forLocal:YES];
[_bottomBar setBorderType:HNHBorderTop];
[_addGroupButton setAction:[MPActionHelper actionOfType:MPActionAddGroup]];