HistoryView: Allow dragging of refs to move them

This commit is contained in:
Pieter de Bie
2008-11-01 21:08:23 +01:00
parent 90db001409
commit 4cefe8ee92
12 changed files with 352 additions and 41 deletions
+6
View File
@@ -44,6 +44,7 @@
F56CC7290E65E0AD004307B4 /* PBGitGraphLine.m in Sources */ = {isa = PBXBuildFile; fileRef = F56CC7280E65E0AD004307B4 /* PBGitGraphLine.m */; };
F56CC7320E65E0E5004307B4 /* PBGraphCellInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = F56CC7310E65E0E5004307B4 /* PBGraphCellInfo.m */; };
F57240BB0E9678EA00D8EE66 /* deleted_file.png in Resources */ = {isa = PBXBuildFile; fileRef = F57240BA0E9678EA00D8EE66 /* deleted_file.png */; };
F574A2850EAE2EAC003F2CB1 /* PBRefController.m in Sources */ = {isa = PBXBuildFile; fileRef = F574A2840EAE2EAC003F2CB1 /* PBRefController.m */; };
F574A2910EAE2FF4003F2CB1 /* PBGitConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 93FCCBA80EA8AF450061B02B /* PBGitConfig.m */; };
F57CC3910E05DDF2000472E2 /* PBEasyPipe.m in Sources */ = {isa = PBXBuildFile; fileRef = F57CC3900E05DDF2000472E2 /* PBEasyPipe.m */; };
F57CC4410E05E496000472E2 /* PBGitWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = F57CC4400E05E496000472E2 /* PBGitWindowController.m */; };
@@ -161,6 +162,8 @@
F56CC7300E65E0E5004307B4 /* PBGraphCellInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGraphCellInfo.h; sourceTree = "<group>"; };
F56CC7310E65E0E5004307B4 /* PBGraphCellInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGraphCellInfo.m; sourceTree = "<group>"; };
F57240BA0E9678EA00D8EE66 /* deleted_file.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = deleted_file.png; path = Images/deleted_file.png; sourceTree = "<group>"; };
F574A2830EAE2EAC003F2CB1 /* PBRefController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBRefController.h; sourceTree = "<group>"; };
F574A2840EAE2EAC003F2CB1 /* PBRefController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBRefController.m; sourceTree = "<group>"; };
F57CC38F0E05DDF2000472E2 /* PBEasyPipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBEasyPipe.h; sourceTree = "<group>"; };
F57CC3900E05DDF2000472E2 /* PBEasyPipe.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBEasyPipe.m; sourceTree = "<group>"; };
F57CC43F0E05E496000472E2 /* PBGitWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitWindowController.h; sourceTree = "<group>"; };
@@ -498,6 +501,8 @@
F565262A0E03D89B00F03B52 /* PBWebHistoryController.m */,
F52BCE050E84211300AA3741 /* PBGitHistoryController.h */,
F52BCE060E84211300AA3741 /* PBGitHistoryController.m */,
F574A2830EAE2EAC003F2CB1 /* PBRefController.h */,
F574A2840EAE2EAC003F2CB1 /* PBRefController.m */,
);
name = History;
sourceTree = "<group>";
@@ -649,6 +654,7 @@
F5FE6C030EB13BC900F30D12 /* PBServicesController.m in Sources */,
F50A41230EBB875D00208746 /* PBNiceSplitView.m in Sources */,
F5FC41F40EBCBD4300191D80 /* PBGitXProtocol.m in Sources */,
F574A2850EAE2EAC003F2CB1 /* PBRefController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
+3
View File
@@ -14,6 +14,9 @@
IBOutlet WebView* webView;
IBOutlet PBWebHistoryController* webController;
IBOutlet PBGitHistoryController *controller;
NSPoint mouseDownPoint;
}
@property (readonly) NSPoint mouseDownPoint;
@end
+41 -1
View File
@@ -7,10 +7,17 @@
//
#import "PBCommitList.h"
#import "PBGitRevisionCell.h"
@implementation PBCommitList
@synthesize mouseDownPoint;
- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL) local
{
NSLog(@"a");
return NSDragOperationCopy;
}
- (void) keyDown: (id) event
{
NSString* character = [event charactersIgnoringModifiers];
@@ -33,4 +40,37 @@
[controller copyCommitInfo];
};
- (void)mouseDown:(NSEvent *)theEvent
{
mouseDownPoint = [[self window] mouseLocationOutsideOfEventStream];
[super mouseDown:theEvent];
}
- (NSImage *)dragImageForRowsWithIndexes:(NSIndexSet *)dragRows
tableColumns:(NSArray *)tableColumns
event:(NSEvent *)dragEvent
offset:(NSPointPointer)dragImageOffset
{
NSPoint location = [self convertPointFromBase:mouseDownPoint];
int row = [self rowAtPoint:location];
int column = [self columnAtPoint:location];
PBGitRevisionCell *cell = (PBGitRevisionCell *)[self preparedCellAtColumn:column row:row];
int index = [cell indexAtX:location.x];
if (index == -1)
return [super dragImageForRowsWithIndexes:dragRows tableColumns:tableColumns event:dragEvent offset:dragImageOffset];
NSRect rect = [cell rectAtIndex:index];
NSImage *newImage = [[NSImage alloc] initWithSize:NSMakeSize(rect.size.width + 3, rect.size.height + 3)];
rect.origin = NSMakePoint(0.5, 0.5);
[newImage lockFocus];
[cell drawLabelAtIndex:index inRect:rect];
[newImage unlockFocus];
*dragImageOffset = NSMakePoint(rect.size.width / 2 + 10, 0);
return newImage;
}
@end
+5 -2
View File
@@ -17,7 +17,7 @@
NSString* details;
NSString *_patch;
NSArray* parents;
NSArray* refs;
NSMutableArray* refs;
NSDate* date;
char sign;
id lineInfo;
@@ -26,10 +26,13 @@
- initWithRepository:(PBGitRepository*) repo andSha:(NSString*) sha;
- (void)addRef:(id)ref;
@property (copy) NSString* sha;
@property (copy) NSString* subject;
@property (copy) NSString* author;
@property (retain) NSArray* parents, *refs;
@property (retain) NSArray* parents;
@property (retain) NSMutableArray* refs;
@property (copy) NSDate* date;
@property (readonly) NSString* dateString;
@property (readonly) NSString* patch;
+8
View File
@@ -62,6 +62,14 @@
return [PBGitTree rootForCommit: self];
}
- (void)addRef:(id)ref
{
if (!self.refs)
self.refs = [NSMutableArray arrayWithObject:ref];
else
[self.refs addObject:ref];
}
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
{
return NO;
+1
View File
@@ -18,6 +18,7 @@
IBOutlet NSTreeController* treeController;
IBOutlet NSOutlineView* fileBrowser;
IBOutlet NSTableView* commitList;
IBOutlet id webView;
int selectedTab;
+2 -1
View File
@@ -10,6 +10,7 @@
#import "CWQuickLook.h"
#import "PBGitGrapher.h"
#import "PBGitRevisionCell.h"
#import "PBCommitList.h"
#define QLPreviewPanel NSClassFromString(@"QLPreviewPanel")
@@ -38,7 +39,7 @@
// Set a sort descriptor for the subject column in the history list, as
// It can't be sorted by default (because it's bound to a PBGitCommit)
[[commitList tableColumnWithIdentifier:@"subject"] setSortDescriptorPrototype:[[NSSortDescriptor alloc] initWithKey:@"subject" ascending:YES]];
[super awakeFromNib];
// We bind this ourselves because otherwise we would lose our selection
[branchesController bind:@"selectionIndexes" toObject:repository withKeyPath:@"currentBranch" options:nil];
+78 -4
View File
@@ -8,7 +8,7 @@
<string key="IBDocument.HIToolboxVersion">352.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="9"/>
<integer value="3"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -1344,6 +1344,9 @@
<reference key="NSSuperview"/>
<string key="NSClassName">NSView</string>
</object>
<object class="NSCustomObject" id="892732705">
<string key="NSClassName">PBRefController</string>
</object>
</object>
<object class="IBObjectContainer" key="IBDocument.Objects">
<object class="NSMutableArray" key="connectionRecords">
@@ -1866,6 +1869,38 @@
</object>
<int key="connectionID">230</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">commitController</string>
<reference key="source" ref="892732705"/>
<reference key="destination" ref="391209158"/>
</object>
<int key="connectionID">232</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">commitList</string>
<reference key="source" ref="892732705"/>
<reference key="destination" ref="254268962"/>
</object>
<int key="connectionID">233</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">historyController</string>
<reference key="source" ref="892732705"/>
<reference key="destination" ref="1001"/>
</object>
<int key="connectionID">234</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">dataSource</string>
<reference key="source" ref="254268962"/>
<reference key="destination" ref="892732705"/>
</object>
<int key="connectionID">235</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -2366,6 +2401,11 @@
<reference key="object" ref="882172208"/>
<reference key="parent" ref="604026377"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">231</int>
<reference key="object" ref="892732705"/>
<reference key="parent" ref="1002"/>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
@@ -2411,6 +2451,7 @@
<string>224.IBPluginDependency</string>
<string>225.IBPluginDependency</string>
<string>23.IBPluginDependency</string>
<string>231.IBPluginDependency</string>
<string>24.IBPluginDependency</string>
<string>25.IBPluginDependency</string>
<string>26.IBPluginDependency</string>
@@ -2502,6 +2543,7 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>PBCommitList</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<integer value="0" id="8"/>
@@ -2567,7 +2609,7 @@
</object>
</object>
<nil key="sourceID"/>
<int key="maxID">230</int>
<int key="maxID">235</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -2696,6 +2738,29 @@
<string key="minorKey">PBQLOutlineView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">PBRefController</string>
<string key="superclassName">NSObject</string>
<object class="NSMutableDictionary" key="outlets">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>commitController</string>
<string>commitList</string>
<string>historyController</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>NSArrayController</string>
<string>PBCommitList</string>
<string>PBGitHistoryController</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">PBRefController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">PBUnsortableTableHeader</string>
<string key="superclassName">NSTableHeaderView</string>
@@ -2724,8 +2789,17 @@
<string key="className">PBWebController</string>
<string key="superclassName">NSObject</string>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">view</string>
<string key="NS.object.0">WebView</string>
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>repository</string>
<string>view</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>id</string>
<string>WebView</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
+4
View File
@@ -18,5 +18,9 @@
IBOutlet PBGitHistoryController *controller;
}
- (int) indexAtX:(float)x;
- (NSRect) rectAtIndex:(int)index;
- (void) drawLabelAtIndex:(int)index inRect:(NSRect)rect;
@property(retain) PBGitCommit* objectValue;
@end
+85 -33
View File
@@ -143,45 +143,65 @@
return [NSColor yellowColor];
}
- (void) drawRefsInRect: (NSRect*) rect
-(NSArray *)rectsForRefsinRect:(NSRect) rect;
{
static const float ref_padding = 10.0f;
static const float ref_spacing = 2.0f;
NSMutableArray *array = [NSMutableArray array];
static const int ref_padding = 10;
static const int ref_spacing = 2;
NSRect lastRect = rect;
lastRect.origin.x = round(lastRect.origin.x) - 0.5;
lastRect.origin.y = round(lastRect.origin.y) - 0.5;
for (PBGitRef *ref in self.objectValue.refs) {
NSMutableDictionary* attributes = [self attributesForRefLabelSelected:NO isCurrentBranch:NO];
NSSize textSize = [[ref shortName] sizeWithAttributes:attributes];
NSRect newRect = lastRect;
newRect.size.width = textSize.width + ref_padding;
newRect.size.height = textSize.height;
newRect.origin.y = rect.origin.y + (rect.size.height - newRect.size.height) / 2;
[array addObject:[NSValue valueWithRect:newRect]];
lastRect = newRect;
lastRect.origin.x += (int)lastRect.size.width + ref_spacing;
}
return array;
}
NSArray* refs = [self.objectValue refs];
NSRect refRect = (NSRect){rect->origin, rect->size};
- (void) drawLabelAtIndex:(int)index inRect:(NSRect)rect
{
NSArray *refs = self.objectValue.refs;
PBGitRef *ref = [refs objectAtIndex:index];
BOOL isCurBranch = [ref.ref isEqualToString:[[[controller repository] headRef] simpleRef]];
NSMutableDictionary* attributes = [self attributesForRefLabelSelected:[self isHighlighted]
isCurrentBranch:isCurBranch];
NSBezierPath *border = [NSBezierPath bezierPathWithRoundedRect:rect cornerRadius: 2.0];
[[self colorForRef:ref] set];
[border fill];
[[ref shortName] drawInRect:rect withAttributes:attributes];
[border stroke];
}
- (void) drawRefsInRect: (NSRect *)refRect
{
[[NSColor blackColor] setStroke];
int index;
for (index = 0; index < [refs count]; ++index) {
PBGitRef *ref = [refs objectAtIndex:index];
BOOL isCurBranch = [ref.ref isEqualToString:[[[controller repository] headRef] simpleRef]];
NSMutableDictionary* attributes = [self attributesForRefLabelSelected:[self isHighlighted]
isCurrentBranch:isCurBranch];
NSSize refSize = [[ref shortName] sizeWithAttributes:attributes];
refRect.size.width = refSize.width + ref_padding;
refRect.size.height = refSize.height;
refRect.origin.y = rect->origin.y + (rect->size.height - refRect.size.height) / 2;
// Round rects to 0.5 pixels in order to draw only a single pixel
refRect.origin.x = round(refRect.origin.x) - 0.5;
refRect.origin.y = round(refRect.origin.y) - 0.5;
NSBezierPath *border = [NSBezierPath bezierPathWithRoundedRect:refRect cornerRadius: 2.0];
[[self colorForRef: ref] set];
[border fill];
[[ref shortName] drawInRect:refRect withAttributes:attributes];
[border stroke];
refRect.origin.x += (int)refRect.size.width + ref_spacing;
NSRect lastRect;
int index = 0;
for (NSValue *rectValue in [self rectsForRefsinRect:*refRect])
{
NSRect rect = [rectValue rectValue];
[self drawLabelAtIndex:index inRect:rect];
lastRect = rect;
++index;
}
rect->size.width -= refRect.origin.x - rect->origin.x;
rect->origin.x = refRect.origin.x;
refRect->size.width -= lastRect.origin.x - refRect->origin.x + lastRect.size.width;
refRect->origin.x = lastRect.origin.x + lastRect.size.width;
}
- (void) drawWithFrame: (NSRect) rect inView:(NSView *)view
@@ -207,6 +227,7 @@
[self drawCircleInRect: ownRect];
}
if ([self.objectValue refs])
[self drawRefsInRect:&rect];
@@ -226,4 +247,35 @@
return [[super objectValue] nonretainedObjectValue];
}
- (int) indexAtX:(float)x
{
cellInfo = [self.objectValue lineInfo];
float pathWidth = 0;
if (cellInfo && ![controller hasNonlinearPath])
pathWidth = 10 + 10 * cellInfo.numColumns;
int index = 0;
NSRect refRect = NSMakeRect(pathWidth, 0, 1000, 10000);
for (NSValue *rectValue in [self rectsForRefsinRect:refRect])
{
NSRect rect = [rectValue rectValue];
if (x >= rect.origin.x && x <= (rect.origin.x + rect.size.width))
return index;
++index;
}
return -1;
}
- (NSRect) rectAtIndex:(int)index
{
cellInfo = [self.objectValue lineInfo];
float pathWidth = 0;
if (cellInfo && ![controller hasNonlinearPath])
pathWidth = 10 + 10 * cellInfo.numColumns;
NSRect refRect = NSMakeRect(pathWidth, 0, 1000, 10000);
return [[[self rectsForRefsinRect:refRect] objectAtIndex:index] rectValue];
}
@end
+19
View File
@@ -0,0 +1,19 @@
//
// PBLabelController.h
// GitX
//
// Created by Pieter de Bie on 21-10-08.
// Copyright 2008 Pieter de Bie. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "PBGitHistoryController.h"
#import "PBCommitList.h"
@interface PBRefController : NSObject {
IBOutlet __weak PBGitHistoryController *historyController;
IBOutlet NSArrayController *commitController;
IBOutlet PBCommitList *commitList;
}
@end
+100
View File
@@ -0,0 +1,100 @@
//
// PBLabelController.m
// GitX
//
// Created by Pieter de Bie on 21-10-08.
// Copyright 2008 Pieter de Bie. All rights reserved.
//
#import "PBRefController.h"
#import "PBGitRevisionCell.h"
@implementation PBRefController
- (void)awakeFromNib
{
[commitList registerForDraggedTypes:[NSArray arrayWithObject:@"PBGitRef"]];
}
- (BOOL)tableView:(NSTableView *)tv writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard*)pboard
{
NSPoint location = [tv convertPointFromBase:[(PBCommitList *)tv mouseDownPoint]];
int row = [tv rowAtPoint:location];
int column = [tv columnAtPoint:location];
if (column != 0)
return NO;
PBGitRevisionCell *cell = (PBGitRevisionCell *)[tv preparedCellAtColumn:column row:row];
int index = [cell indexAtX:location.x];
if (index == -1)
return NO;
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:[NSArray arrayWithObjects:[NSNumber numberWithInt:row], [NSNumber numberWithInt:index], NULL]];
[pboard declareTypes:[NSArray arrayWithObject:@"PBGitRef"] owner:self];
[pboard setData:data forType:@"PBGitRef"];
return YES;
}
- (NSDragOperation)tableView:(NSTableView*)tv
validateDrop:(id <NSDraggingInfo>)info
proposedRow:(int)row
proposedDropOperation:(NSTableViewDropOperation)operation
{
if (operation == NSTableViewDropAbove)
return NSDragOperationNone;
NSPasteboard *pboard = [info draggingPasteboard];
if ([pboard dataForType:@"PBGitRef"])
return NSDragOperationMove;
return NSDragOperationNone;
}
- (BOOL)tableView:(NSTableView *)aTableView
acceptDrop:(id <NSDraggingInfo>)info
row:(int)row
dropOperation:(NSTableViewDropOperation)operation
{
if (operation != NSTableViewDropOn)
return NO;
NSPasteboard *pboard = [info draggingPasteboard];
NSData *data = [pboard dataForType:@"PBGitRef"];
if (!data)
return NO;
NSArray *numbers = [NSKeyedUnarchiver unarchiveObjectWithData:data];
int oldRow = [[numbers objectAtIndex:0] intValue];
int oldRefIndex = [[numbers objectAtIndex:1] intValue];
PBGitCommit *oldCommit = [[commitController arrangedObjects] objectAtIndex: oldRow];
PBGitRef *ref = [[oldCommit refs] objectAtIndex:oldRefIndex];
PBGitCommit *dropCommit = [[commitController arrangedObjects] objectAtIndex:row];
int a = [[NSAlert alertWithMessageText:@"Change branch"
defaultButton:@"Change"
alternateButton:@"Cancel"
otherButton:nil
informativeTextWithFormat:@"Do you want to change branch\n\n\t'%@'\n\n to point to commit\n\n\t'%@'", [ref shortName], [dropCommit subject]] runModal];
if (a != NSAlertDefaultReturn)
return NO;
int retValue = 1;
[historyController.repository outputForArguments:[NSArray arrayWithObjects:@"update-ref", @"-mUpdate from GitX", [ref ref], [dropCommit sha], NULL] retValue:&retValue];
if (retValue)
return NO;
[dropCommit addRef:ref];
[oldCommit.refs removeObject:ref];
if ([oldCommit.refs count] == 0)
oldCommit.refs = NULL;
[commitController rearrangeObjects];
[aTableView needsToDrawRect:[aTableView rectOfRow:oldRow]];
return YES;
}
@end