Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hyperlink #123 to the respective issue/ticket #214

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Classes/Controllers/PBGitHistoryController.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@
- (void)showCommitsFromTree:(id)sender;
- (void)showInFinderAction:(id)sender;
- (void)openFilesAction:(id)sender;
- (void) showConfigureGitxTicketUrl:(id)sender;
- (void) showTicketWithNumber:(NSString *)ticketNumber;
- (NSArray *)menuItemsForTicketLink:(NSString *)ticketNumber;

// Repository Methods
- (IBAction) createBranch:(id)sender;
Expand Down
94 changes: 94 additions & 0 deletions Classes/Controllers/PBGitHistoryController.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
#define QLPreviewPanel NSClassFromString(@"QLPreviewPanel")
#import "PBQLTextView.h"
#import "GLFileView.h"
#import "PBGitXConfigureTicketURLSheet.h"
#import <ObjectiveGit/GTRepository.h>
#import <ObjectiveGit/GTConfiguration.h>
#import <AppKit/AppKit.h>



#define kHistorySelectedDetailIndexKey @"PBHistorySelectedDetailIndex"
Expand Down Expand Up @@ -640,6 +645,95 @@ - (NSArray *)menuItemsForPaths:(NSArray *)paths
return menuItems;
}

- (void) showConfigureGitxTicketUrl:(id)sender
{
[PBGitXConfigureTicketURLSheet beginConfigureTicketURLSheetForRepo:self.repository];
}

- (NSString *) ticketURLPattern
{
NSError *error = nil;
GTConfiguration* config = [self.repository.gtRepo configurationWithError:&error];
NSString * currentTicketURL = [config stringForKey:GITX_TICKET_URL_SETTING];
if (currentTicketURL != nil) {
return currentTicketURL;
}
// not configured, but look if remote.origin is github and default to its issues
NSString * originURL = [config stringForKey:@"remote.origin.url"];
if (originURL != nil) {
NSString *regexString = @"github.com/([^/]+/[^/]+)\\.git";
NSRegularExpressionOptions options = NSRegularExpressionCaseInsensitive;
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexString options:options error:&error];
if (error) {
NSLog(@"%@", [error description]);
return nil;
}
NSTextCheckingResult *result = [regex firstMatchInString:originURL options:0 range:NSMakeRange(0, [originURL length])];
if (result) {
NSString* githubRepository = [originURL substringWithRange:[result rangeAtIndex:1]];
return [NSString stringWithFormat:@"https://github.com/%@/issues/{id}", githubRepository];
}
}
return nil;
}

- (NSURL *) assembleTicketUrlWithNumber:(NSString *)ticketNumber
{
NSString * pattern = [self ticketURLPattern];
if (pattern != nil) {
NSArray * parts = [pattern componentsSeparatedByString:@"{id}"];
BOOL found = [parts count] > 1;
NSString * urlStr = [parts componentsJoinedByString:ticketNumber];
if (!found) {
urlStr = [urlStr stringByAppendingString:ticketNumber];
}
NSLog(@"urlStr: %@", urlStr);
return [NSURL URLWithString:urlStr];
}
return nil;
}

- (void) showTicketWithNumber:(NSString *)ticketNumber
{
NSURL * url = [self assembleTicketUrlWithNumber:ticketNumber];
NSLog(@"URL: %@", url);
if (url != nil) {
[[NSWorkspace sharedWorkspace] openURL:url];
}
else {
[self showConfigureGitxTicketUrl:nil];
}
}

- (void) copyTicketUrl:(id)sender
{
NSString *ticketNumber = [sender representedObject];
NSURL * ticketURL = [self assembleTicketUrlWithNumber:ticketNumber];
if (ticketURL != nil) {
[[NSPasteboard generalPasteboard] clearContents];
[[NSPasteboard generalPasteboard] setString:[ticketURL description] forType:NSPasteboardTypeString];
}
}

- (NSArray *)menuItemsForTicketLink:(NSString *)ticketNumber;
{
NSMutableArray *menuItems = [NSMutableArray array];

NSMenuItem *configureGitxTicketUrl = [[NSMenuItem alloc] initWithTitle:@"Configure Ticket/Issue URL..."
action:@selector(showConfigureGitxTicketUrl:)
keyEquivalent:@""];
[menuItems addObject:configureGitxTicketUrl];
if ([self ticketURLPattern] != nil) {
NSMenuItem *copyTicketUrl = [[NSMenuItem alloc] initWithTitle:@"Copy URL"
action:@selector(copyTicketUrl:)
keyEquivalent:@""];
copyTicketUrl.representedObject = ticketNumber;
[menuItems addObject:copyTicketUrl];
}

return [NSArray arrayWithArray:menuItems];
}

#pragma mark NSSplitView delegate methods

Expand Down
17 changes: 15 additions & 2 deletions Classes/Controllers/PBWebHistoryController.m
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,12 @@ - (NSArray *) webView:(WebView *)sender
return [NSArray arrayWithObject:item];
return nil;
}


if ([[node className] hasPrefix:@"ticket"]) {
NSString *ticketNumber = [[[[node childNodes] item:0] textContent] substringFromIndex:1];
return [historyController menuItemsForTicketLink:ticketNumber];
}

node = [node parentNode];
}

Expand All @@ -162,7 +167,15 @@ - (void)webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary
newFrameName:(NSString *)frameName
decisionListener:(id < WebPolicyDecisionListener >)listener
{
[[NSWorkspace sharedWorkspace] openURL:[request URL]];
if ([[[request URL] scheme] isEqualToString:@"file"]) {
if ([[[request URL] fragment] hasPrefix:@"ticket:"]) {
NSString * ticketNumber = [[[request URL] fragment] substringFromIndex:7];
[historyController showTicketWithNumber:ticketNumber];
}
}
else {
[[NSWorkspace sharedWorkspace] openURL:[request URL]];
}
}

- getConfig:(NSString *)key
Expand Down
30 changes: 30 additions & 0 deletions Classes/Views/PBGitXConfigureTicketURLSheet.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// PBGitXConfigureTicketURLSheet.h
// GitX
//
// Created by Mathias Leppich on 7/11/13.
// Copyright 2013 Mathias Leppich. All rights reserved.
//

#import <Cocoa/Cocoa.h>

#import "RJModalRepoSheet.h"

#define GITX_TICKET_URL_SETTING @"gitx.ticketurl"

@interface PBGitXConfigureTicketURLSheet : RJModalRepoSheet
{
NSImageView *iconView;
NSTextField *ticketURLTextField;
}

+ (void)beginConfigureTicketURLSheetForRepo:(PBGitRepository *)repo;

- (void)beginConfigureTicketURLSheet;

- (IBAction)closeMessageSheet:(id)sender;

@property IBOutlet NSImageView *iconView;
@property IBOutlet NSTextField *ticketURLTextField;

@end
98 changes: 98 additions & 0 deletions Classes/Views/PBGitXConfigureTicketURLSheet.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
//
// PBGitXConfigureTicketURLSheet.m
// GitX
//
// Created by Mathias Leppich on 7/11/13.
// Copyright 2013 Mathias Leppich. All rights reserved.
//

#import "PBGitXConfigureTicketURLSheet.h"

#import "PBGitRepository.h"
#import <ObjectiveGit/GTRepository.h>
#import <ObjectiveGit/GTConfiguration.h>

@interface PBGitXConfigureTicketURLSheet ()

@end

@implementation PBGitXConfigureTicketURLSheet

@synthesize iconView, ticketURLTextField;


#pragma mark -
#pragma mark PBGitXConfigureTicketURLSheet

+ (void)beginConfigureTicketURLSheetForRepo:(PBGitRepository *)repo
{
PBGitXConfigureTicketURLSheet *sheet = [[self alloc] initWithWindowNibName:@"PBGitXConfigureTicketURLSheet"
forRepo:repo];
[sheet beginConfigureTicketURLSheet];
}

- (id)initWithWindowNibName:(NSString *)windowNibName
forRepo:(PBGitRepository *)repo
{
self = [super initWithWindowNibName:windowNibName forRepo:repo];
if (!self)
return nil;
return self;
}

- (IBAction)closeMessageSheet:(id)sender
{
[self hide];
}

#pragma mark Private
- (void)beginConfigureTicketURLSheet {
[self window];

[self loadSettings];

[self show];
}

- (void)loadSettings {
NSError *error = nil;
GTConfiguration* config = [self.repository.gtRepo configurationWithError:&error];
NSString * currentTicketURL = [config stringForKey:GITX_TICKET_URL_SETTING];
if (currentTicketURL == nil) {
currentTicketURL = @"";
}
ticketURLTextField.stringValue = currentTicketURL;
NSLog(@"loadSettings: %@", currentTicketURL);
}

- (void)persistSettings {
NSString * currentTicketURL = [ticketURLTextField stringValue];
NSLog(@"persistSettings: %@", currentTicketURL);
NSError *error = nil;
GTConfiguration* config = [self.repository.gtRepo configurationWithError:&error];
if ([currentTicketURL isEqualToString:@""]) {
[config deleteValueForKey:GITX_TICKET_URL_SETTING error:&error];
} else {
[config setString:currentTicketURL forKey:GITX_TICKET_URL_SETTING];
}
}

- (void)show {
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(controlTextDidChange:)
name: NSControlTextDidChangeNotification
object: ticketURLTextField];
[super show];
}

- (void)hide {
[[NSNotificationCenter defaultCenter] removeObserver: self];
[super hide];
}

- (void)controlTextDidChange:(NSNotification *)obj {
[NSObject cancelPreviousPerformRequestsWithTarget:self];
[self performSelector:@selector(persistSettings) withObject:self afterDelay:0.2];
}

@end
10 changes: 10 additions & 0 deletions GitX.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
911112370E5A097800BF76B4 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 911112360E5A097800BF76B4 /* Security.framework */; };
913D5E500E55645900CECEA2 /* gitx in Resources */ = {isa = PBXBuildFile; fileRef = 913D5E490E55644600CECEA2 /* gitx */; };
A2EA3604178ECB5300636291 /* PBGitXConfigureTicketURLSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = A2EA3603178ECB5300636291 /* PBGitXConfigureTicketURLSheet.xib */; };
A2EA3610178ED22A00636291 /* PBGitXConfigureTicketURLSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = A2EA360F178ED22A00636291 /* PBGitXConfigureTicketURLSheet.m */; };
BC0444AD17648CC900353E6D /* AddRemoteTemplate.png in Resources */ = {isa = PBXBuildFile; fileRef = BC0444AC17648CC900353E6D /* AddRemoteTemplate.png */; };
BC0444B817648D0200353E6D /* BranchHighlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = BC0444B717648D0200353E6D /* BranchHighlighted.png */; };
BC0444BA17648DA800353E6D /* FolderHighlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = BC0444B917648DA700353E6D /* FolderHighlighted.png */; };
Expand Down Expand Up @@ -644,6 +646,9 @@
8D1107320486CEB800E47090 /* GitX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GitX.app; sourceTree = BUILT_PRODUCTS_DIR; };
911112360E5A097800BF76B4 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = "<absolute>"; };
913D5E490E55644600CECEA2 /* gitx */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gitx; sourceTree = BUILT_PRODUCTS_DIR; };
A2EA3603178ECB5300636291 /* PBGitXConfigureTicketURLSheet.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PBGitXConfigureTicketURLSheet.xib; sourceTree = "<group>"; };
A2EA360E178ED22A00636291 /* PBGitXConfigureTicketURLSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitXConfigureTicketURLSheet.h; sourceTree = "<group>"; };
A2EA360F178ED22A00636291 /* PBGitXConfigureTicketURLSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitXConfigureTicketURLSheet.m; sourceTree = "<group>"; };
BC0444AC17648CC900353E6D /* AddRemoteTemplate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = AddRemoteTemplate.png; sourceTree = "<group>"; };
BC0444B717648D0200353E6D /* BranchHighlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = BranchHighlighted.png; sourceTree = "<group>"; };
BC0444B917648DA700353E6D /* FolderHighlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = FolderHighlighted.png; sourceTree = "<group>"; };
Expand Down Expand Up @@ -935,6 +940,7 @@
4A5D75BE14A9A90500DF6C68 /* PBGitHistoryView.xib */,
4A5D75BF14A9A90500DF6C68 /* PBGitSidebarView.xib */,
4A5D75C014A9A90500DF6C68 /* PBGitXMessageSheet.xib */,
A2EA3603178ECB5300636291 /* PBGitXConfigureTicketURLSheet.xib */,
);
path = XIBs;
sourceTree = "<group>";
Expand Down Expand Up @@ -1176,6 +1182,8 @@
4A5D777014A9AEB000DF6C68 /* PBSourceViewItems.h */,
4A5D777114A9AEB000DF6C68 /* PBSourceViewRemote.h */,
4A5D777214A9AEB000DF6C68 /* PBSourceViewRemote.m */,
A2EA360E178ED22A00636291 /* PBGitXConfigureTicketURLSheet.h */,
A2EA360F178ED22A00636291 /* PBGitXConfigureTicketURLSheet.m */,
);
path = Views;
sourceTree = "<group>";
Expand Down Expand Up @@ -1499,6 +1507,7 @@
BC0444C617648EBE00353E6D /* TagHighlighted.png in Resources */,
BC77578C176766B60048BB48 /* [email protected] in Resources */,
BC775797176766C60048BB48 /* [email protected] in Resources */,
A2EA3604178ECB5300636291 /* PBGitXConfigureTicketURLSheet.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -1642,6 +1651,7 @@
643952741603E9BC00BB7AFF /* PBGitSubmodule.m in Sources */,
643952771603EF9B00BB7AFF /* PBGitSVSubmoduleItem.m in Sources */,
4AB057E31652652000DE751D /* GitRepoFinder.m in Sources */,
A2EA3610178ED22A00636291 /* PBGitXConfigureTicketURLSheet.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Loading