forked from laullon/gitx
-
Notifications
You must be signed in to change notification settings - Fork 0
/
FileViewerController.m
321 lines (264 loc) · 10.5 KB
/
FileViewerController.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
//
// FileViewerController.m
// GitX
//
// Created by German Laullon on 11/06/10.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import "FileViewerController.h"
#import "PBGitHistoryController.h"
#import "PBGitDefaults.h"
#define GROUP_LABEL @"Label" // string
#define GROUP_SEPARATOR @"HasSeparator" // BOOL as NSNumber
#define GROUP_SELECTION_MODE @"SelectionMode" // MGScopeBarGroupSelectionMode (int) as NSNumber
#define GROUP_ITEMS @"Items" // array of dictionaries, each containing the following keys:
#define ITEM_IDENTIFIER @"Identifier" // string
#define ITEM_NAME @"Name" // string
@implementation FileViewerController
#pragma mark Setup and teardown
- (id)initWithRepository:(PBGitRepository *)theRepository andController:(id)theController;
{
repository=theRepository;
controller=theController;
return [self initWithNibName:@"FileViewer" bundle:[NSBundle mainBundle]];
}
- (void)awakeFromNib
{
self.groups = [NSMutableArray arrayWithCapacity:0];
scopeBar.delegate = self;
NSArray *items = [NSArray arrayWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:
(commit)?@"commit":@"diff", ITEM_IDENTIFIER,
@"Diff", ITEM_NAME,
nil],
[NSDictionary dictionaryWithObjectsAndKeys:
@"source", ITEM_IDENTIFIER,
@"Source", ITEM_NAME,
nil],
[NSDictionary dictionaryWithObjectsAndKeys:
@"blame", ITEM_IDENTIFIER,
@"Blame", ITEM_NAME,
nil],
[NSDictionary dictionaryWithObjectsAndKeys:
@"log", ITEM_IDENTIFIER,
@"History", ITEM_NAME,
nil],
nil];
[self.groups addObject:[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], GROUP_SEPARATOR,
[NSNumber numberWithInt:MGRadioSelectionMode], GROUP_SELECTION_MODE, // single selection group.
items, GROUP_ITEMS,
nil]];
[scopeBar reloadData];
[webViewFileViwer setUIDelegate:self];
[webViewFileViwer setFrameLoadDelegate:self];
[webViewFileViwer setResourceLoadDelegate:self];}
- (void)dealloc
{
self.groups = nil;
[super dealloc];
}
#pragma mark JavaScript log.js methods
- (void) selectCommit:(NSString*)c
{
NSLog(@"[FileViewerController controller:%@]",controller);
if([(PBGitHistoryController *)controller selectCommit:sha])
NSLog(@"---");
NSLog(@"[FileViewerController selectCommit:%@]",c);
}
#pragma mark MGScopeBarDelegate methods
- (int)numberOfGroupsInScopeBar:(MGScopeBar *)theScopeBar
{
return [self.groups count];
}
- (NSArray *)scopeBar:(MGScopeBar *)theScopeBar itemIdentifiersForGroup:(int)groupNumber
{
return [[self.groups objectAtIndex:groupNumber] valueForKeyPath:[NSString stringWithFormat:@"%@.%@", GROUP_ITEMS, ITEM_IDENTIFIER]];
}
- (NSString *)scopeBar:(MGScopeBar *)theScopeBar labelForGroup:(int)groupNumber
{
return [[self.groups objectAtIndex:groupNumber] objectForKey:GROUP_LABEL]; // might be nil, which is fine (nil means no label).
}
- (NSString *)scopeBar:(MGScopeBar *)theScopeBar titleOfItem:(NSString *)identifier inGroup:(int)groupNumber
{
NSArray *items = [[self.groups objectAtIndex:groupNumber] objectForKey:GROUP_ITEMS];
if (items) {
for (NSDictionary *item in items) {
if ([[item objectForKey:ITEM_IDENTIFIER] isEqualToString:identifier]) {
return [item objectForKey:ITEM_NAME];
break;
}
}
}
return nil;
}
- (MGScopeBarGroupSelectionMode)scopeBar:(MGScopeBar *)theScopeBar selectionModeForGroup:(int)groupNumber
{
return [[[self.groups objectAtIndex:groupNumber] objectForKey:GROUP_SELECTION_MODE] intValue];
}
- (void)scopeBar:(MGScopeBar *)theScopeBar selectedStateChanged:(BOOL)selected forItem:(NSString *)identifier inGroup:(int)groupNumber
{
NSString *path = [NSString stringWithFormat:@"html/views/%@", identifier];
NSString *html = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html" inDirectory:path];
NSLog(@"[FileViewerController scopeBar:selectedStateChanged] -> file: '%@' (%@)",html,identifier);
NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:html]];
[[webViewFileViwer mainFrame] loadRequest:request];
}
- (void)showFile:(NSString *)f sha:(NSString *)s{
file=f;
sha=s;
NSString *show=[[[scopeBar selectedItems] objectAtIndex:0] objectAtIndex:0];
NSLog(@"[showFile:sha] showFile:%@ sha:%@ (show=%@)",file,sha,show);
[self scopeBar:scopeBar selectedStateChanged:true forItem:show inGroup:0];
}
# pragma mark WebKitDelegate methods
- (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame
{
NSLog(@"[Alert] message = %@",message);
}
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)sel
{
NSLog(@"[%@ %s]: self = %@ (%i)", [self class], _cmd, self,[self respondsToSelector:sel]);
return NO;
}
- (void)webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)windowObject forFrame:(WebFrame *)frame
{
id script = [sender windowScriptObject];
NSLog(@"Controller: %@", controller);
[script setValue:controller forKey:@"Controller"];
[script setValue:[PBGitDefaults alloc] forKey:@"Config"];
}
- (void)webView:(WebView *)webView addMessageToConsole:(NSDictionary *)dictionary
{
NSLog(@"Error from webkit: %@", dictionary);
}
- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
{
NSString *show=[[[scopeBar selectedItems] objectAtIndex:0] objectAtIndex:0];
NSString *path = [NSString stringWithFormat:@"html/views/%@", show];
NSString *formatFile = [[NSBundle mainBundle] pathForResource:@"format" ofType:@"html" inDirectory:path];
//NSString *testFile = [NSString stringWithFormat:@"%@/test.html",NSHomeDirectory()];
NSString *format;
if(formatFile!=nil)
format=[NSString stringWithContentsOfURL:[NSURL fileURLWithPath:formatFile] encoding:NSUTF8StringEncoding error:nil];
NSString *txt;
if(show==@"source")
txt=[repository outputForArguments:[NSArray arrayWithObjects:@"show", [self refSpec], nil]];
else if(show==@"blame")
txt=[self parseBlame:[repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"blame", @"-p", file, sha, nil]]];
else if(show==@"diff"){
NSString *diff_p=[repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"show", @"--pretty=format:", sha, file, nil]];
NSString *diff_l=[repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff", file, nil]];
txt=[NSString stringWithFormat:@"%@\n%@",diff_p,diff_l];
}
else if(show==@"commit")
txt=[repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff", (sha!=nil)?sha:file, (sha!=nil)?file:nil, nil]];
else if(show==@"log")
txt=[self parseLog:[repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"log", [NSString stringWithFormat:@"--pretty=format:%@",format], @"--", file, nil]]];
else
return; // XXXX controlar mejor.
NSLog(@"didFinishLoadForFrame -> txt: '%@'",([txt length]>180)?[txt substringToIndex:180]:txt);
id script = [webViewFileViwer windowScriptObject];
[script callWebScriptMethod:@"showFile"
withArguments:[NSArray arrayWithObjects:txt, nil]];
//[[[[[sender mainFrame] DOMDocument] documentElement] outerHTML] writeToFile:testFile atomically:YES encoding:NSUTF8StringEncoding error:nil];
}
- (NSString*)refSpec
{
return [NSString stringWithFormat:@"%@:%@", (sha!=nil)?sha:@"HEAD", file];
}
-(NSString *)parseLog:(NSString *)string
{
return string;
}
-(NSString *)parseBlame:(NSString *)string
{
string=[string stringByReplacingOccurrencesOfString:@"<" withString:@"<"];
string=[string stringByReplacingOccurrencesOfString:@">" withString:@">"];
NSArray *lines = [string componentsSeparatedByString:@"\n"];
NSString *line;
NSMutableDictionary *headers=[NSMutableDictionary dictionary];
NSMutableString *res=[NSMutableString string];
[res appendString:@"<table class='blocks'>\n"];
int i=0;
while(i<[lines count]){
line=[lines objectAtIndex:i];
NSArray *header=[line componentsSeparatedByString:@" "];
if([header count]==4){
int nLines=[(NSString *)[header objectAtIndex:3] intValue];
[res appendFormat:@"<tr class='block l%d'>\n",nLines];
line=[lines objectAtIndex:++i];
if([[[line componentsSeparatedByString:@" "] objectAtIndex:0] isEqual:@"author"]){
NSString *author=line;
NSString *summary=nil;
while(summary==nil){
line=[lines objectAtIndex:i++];
if([[[line componentsSeparatedByString:@" "] objectAtIndex:0] isEqual:@"summary"]){
summary=line;
}
}
NSString *block=[NSString stringWithFormat:@"<td><p class='author'>%@</p><p class='summary'>%@</p></td>\n<td>\n",author,summary];
[headers setObject:block forKey:[header objectAtIndex:0]];
}
[res appendString:[headers objectForKey:[header objectAtIndex:0]]];
NSMutableString *code=[NSMutableString string];
do{
line=[lines objectAtIndex:i++];
}while([line characterAtIndex:0]!='\t');
line=[line stringByReplacingOccurrencesOfString:@"\t" withString:@" "];
[code appendString:line];
[code appendString:@"\n"];
int n;
for(n=1;n<nLines;n++){
line=[lines objectAtIndex:i++];
do{
line=[lines objectAtIndex:i++];
}while([line characterAtIndex:0]!='\t');
line=[line stringByReplacingOccurrencesOfString:@"\t" withString:@" "];
[code appendString:line];
[code appendString:@"\n"];
}
[res appendFormat:@"<pre class='first-line: %@;brush: objc'>%@</pre>",[header objectAtIndex:2],code];
[res appendString:@"</td>\n"];
}else{
break;
}
[res appendString:@"</tr>\n"];
}
[res appendString:@"</table>\n"];
//NSLog(@"%@",res);
return (NSString *)res;
}
#pragma mark Accessors and properties
/*
- (IBAction)updateFileViwer:(id)sender
{
NSString *type
int option=[displayControl selectedSegment];
if(option==0)
type=@"source";
else if(option==1)
type=@"blame";
else if(option==2)
type=@"diff";
}
- (void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
{
NSString *messageString = [error localizedDescription];
NSString *moreString = [error localizedFailureReason] ?
[error localizedFailureReason] :
NSLocalizedString(@"Try typing the URL again.", nil);
messageString = [NSString stringWithFormat:@"%@. %@", messageString, moreString];
NSLog(@"ERROR!!!! - %@",messageString);
}
/*
NSArray *objects = [treeController selectedObjects];
NSArray *content = [treeController content];
if ([objects count] && [content count]) {
PBGitTree *treeItem = [objects objectAtIndex:0];
currentFileBrowserSelectionPath = [treeItem.fullPath componentsSeparatedByString:@"/"];
NSString *txt=[treeItem contents:[displayControl selectedSegment]];
*/
@synthesize groups;
@synthesize commit;
@end