5 // Created by Marc Liyanage on Sun Mar 03 2002.
6 // Copyright (c) 2001 __MyCompanyName__. All rights reserved.
10 #import "MyDocument.h"
16 @implementation MyDocument
20 if (self = [super init]) {
21 workset = [[Workset alloc] init];
22 processor = [XSLTProcessorFactory makeProcessorOfType:PROCESSORTYPE_SABLOTRON];
23 wellFormedParser = [[XMLParserLibxml alloc] init];
28 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
29 NSDictionary *appDefaults = [NSDictionary
30 dictionaryWithObject:@"YES" forKey:@"AnalyzeCode"];
32 [defaults registerDefaults:appDefaults];
42 [wellFormedParser release];
43 [findPanelController release];
44 [jumpToLinePanelController release];
45 [unsavedChangesPanelController release];
49 - (IBAction)selectTab:(id)sender {
51 [self selectTabById:[sender tag]];
60 - (IBAction)selectTabById:(int)tabId {
75 tabName = @"parametersTab";
80 tabName = @"resultTab";
86 [tabView selectTabViewItemWithIdentifier:tabName];
90 - (void)textViewDidChangeSelection:(NSNotification *)aNotification {
95 - (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem {
97 [[self undoManager] removeAllActions];
107 // NSLog(@"updateUI running...");
109 [uiUpdateTimer invalidate];
110 [uiUpdateTimer release];
112 uiUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(uiUpdateTimerTarget:) userInfo:nil repeats:NO];
114 [uiUpdateTimer retain];
119 - (void)uiUpdateTimerTarget:(NSTimer *)timer {
131 NSString *activeTabIdentifier = [[tabView selectedTabViewItem] identifier];
132 NSString *activeResultTabIdentifier = [[resultTabView selectedTabViewItem] identifier];
134 BOOL xmlTabIsVisible = [activeTabIdentifier isEqualToString:@"xmlTab"];
135 BOOL xsltTabIsVisible = !xmlTabIsVisible && [activeTabIdentifier isEqualToString:@"xsltTab"];
136 BOOL paramTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible) && [activeTabIdentifier isEqualToString:@"parametersTab"];
137 BOOL resultTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible || paramTabIsVisible);
138 BOOL resultTabHtmlIsVisible = resultTabIsVisible && [activeResultTabIdentifier isEqualToString:@"htmlResult"];
139 BOOL resultTabXslfoIsVisible = resultTabIsVisible && !resultTabHtmlIsVisible && [activeResultTabIdentifier isEqualToString:@"xslfoResult"];
140 BOOL resultTabTextIsVisible = resultTabIsVisible && !(resultTabHtmlIsVisible || resultTabXslfoIsVisible);
142 // NSLog(@"xml: %d, xslt: %d, param: %d, result: %d, reshtml: %d, resxslfo: %d, restext: %d", xmlTabIsVisible, xsltTabIsVisible, paramTabIsVisible, resultTabIsVisible, resultTabHtmlIsVisible, resultTabXslfoIsVisible, resultTabTextIsVisible);
144 if (xmlTabIsVisible) {
145 [saveXmlFilenameField setObjectValue:[workset xmlFilename]];
146 [saveXmlFilenameField setToolTip:[workset xmlFilename]];
147 [saveXmlButton setEnabled:[self canSaveXmlNow]];
148 [saveXmlAsButton setEnabled:[self canSaveXmlAsNow]];
149 [xmlTagStackField setStringValue:[xmlView calculateTagStack]];
151 [xmlView checkWellFormed];
152 if ([workset hasXmlCode] && [xmlView hasError]) {
153 [xmlWellFormedIcon setImage:warningIcon];
154 [xmlWellFormedIcon setToolTip:[xmlView valueForKey:@"errorString"]];
156 [xmlWellFormedIcon setImage:nil];
157 [xmlWellFormedIcon setToolTip:nil];
160 } else if (xsltTabIsVisible) {
161 [saveXsltFilenameField setObjectValue:[workset xsltFilename]];
162 [saveXsltFilenameField setToolTip:[workset xsltFilename]];
163 [saveXsltButton setEnabled:[self canSaveXsltNow]];
164 [saveXsltAsButton setEnabled:[self canSaveXsltAsNow]];
165 [xsltTagStackField setStringValue:[xsltView calculateTagStack]];
167 [xsltView checkWellFormed];
168 if ([workset hasXsltCode] && [xsltView hasError]) {
169 [xsltWellFormedIcon setImage:warningIcon];
170 [xsltWellFormedIcon setToolTip:[xsltView valueForKey:@"errorString"]];
172 [xsltWellFormedIcon setImage:nil];
173 [xsltWellFormedIcon setToolTip:nil];
176 } else if (paramTabIsVisible) {
177 [paramRemoveButton setEnabled:[parameterTable selectedRow] != -1];
178 [parameterTable reloadData];
179 } else if (resultTabIsVisible) {
180 [saveResultAsButton setEnabled:[self canSaveResultAsNow]];
181 [saveResultButton setEnabled:[self canSaveResultNow]];
182 [autoSaveCheckbox setEnabled:[workset hasResultFilename]];
183 [openResultURLButton setEnabled:[workset hasResultFilename]];
184 [autoShowCheckbox setEnabled:[openResultURLButton isEnabled]];
185 [saveResultFilenameField setObjectValue:[workset resultFilename]];
186 [saveResultFilenameField setToolTip:[workset resultFilename]];
188 if (resultTabHtmlIsVisible) {
189 [self resizeWebView];
190 [self updateResultWebView];
191 } else if (resultTabXslfoIsVisible) {
192 [self updateResultImageView];
193 [pdfCurrentPageField setIntValue: (pdfPageCount ? (pdfCurrentPage + 1) : 0)];
194 [pdfPageCountField setIntValue:pdfPageCount];
196 [pdfPreviousPageButton setEnabled:pdfCurrentPage > 0];
197 [pdfNextPageButton setEnabled:pdfCurrentPage < (pdfPageCount - 1)];
198 [pdfSaveAsButton setEnabled:(pdfPageCount > 0)];
199 // } else if (resultTabTextIsVisible) {
205 [processButton setEnabled:[self canProcessNow]];
207 // move this to xmlview.
208 // [self updateWellFormedIcons];
212 [resultView setString:[workset stringResult]];
217 - (void)updateResultWebView {
218 if (!webViewUpToDate) {
219 WebFrame *mainFrame = [resultWebView mainFrame];
220 // [mainFrame loadHTMLString:[workset stringResult] baseURL:nil];
221 [mainFrame loadHTMLString:[workset stringResult] baseURL:[NSURL URLWithString:[webViewBaseURL stringValue]]];
222 // [mainFrame loadHTMLString:[workset stringResult] baseURL:[NSURL URLWithString:@"file:///Users/liyanage/Sites/primavera/images/x"]];
223 webViewUpToDate = YES;
228 - (void)updateResultImageView {
229 if (!imageViewUpToDate) {
230 [self renderFo:self];
231 imageViewUpToDate = YES;
237 - (BOOL)canProcessNow {
239 return [workset hasXmlCode] && [workset hasXsltCode];
243 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
245 // NSLog(@"validate: %@, tag: %d", menuItem, [menuItem tag]);
247 NSString *activeTabIdentifier = [[tabView selectedTabViewItem] identifier];
248 BOOL xmlTabIsVisible = [activeTabIdentifier isEqualToString:@"xmlTab"];
249 BOOL xsltTabIsVisible = !xmlTabIsVisible && [activeTabIdentifier isEqualToString:@"xsltTab"];
250 BOOL paramTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible) && [activeTabIdentifier isEqualToString:@"parametersTab"];
251 BOOL resultTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible || paramTabIsVisible);
254 switch ([menuItem tag]) {
257 return [self canProcessNow];
261 return [workset hasResultFilename];
265 return [self canFindNow];
268 case 13: // Find Next
269 case 14: // Find Previous
270 return [self canFindAgainNow];
273 case 15: // Use Selection for Find
274 return [self canUseSelectionForFindNow];
277 case 16: // Jump to Line
278 return [self canJumpToLineNow];
281 case 17: // Save Current Pane
282 if (xmlTabIsVisible) {
283 return [self canSaveXmlNow];
284 } else if (xsltTabIsVisible) {
285 return [self canSaveXsltNow];
286 } else if (resultTabIsVisible) {
287 return [self canSaveResultNow];
291 case 18: // Save Current Pane As...
292 if (xmlTabIsVisible) {
293 return [self canSaveXmlAsNow];
294 } else if (xsltTabIsVisible) {
295 return [self canSaveXsltAsNow];
296 } else if (resultTabIsVisible) {
297 return [self canSaveResultAsNow];
310 - (IBAction)showInBrowser:(id)sender {
317 - (void)updateCompleteUI {
319 [xmlView setString:[workset xmlCode]];
320 [xsltView setString:[workset xsltCode]];
325 - (void)textDidChange:(NSNotification *)aNotification {
327 id sender = [aNotification object];
329 if ([sender isEqual:xmlView]) {
330 [workset setXmlCode:[xmlView string]];
332 } else if ([sender isEqual:xsltView]) {
333 [workset setXsltCode:[xsltView string]];
337 [self updateChangeCount:NSChangeDone];
344 - (NSTabView *)tabView {
350 - (BOOL)canJumpToLineNow {
352 NSTextView *view = [self currentTextView];
354 return (view == xmlView) || (view == xsltView);
359 - (IBAction)showJumpToLinePanel:(id)sender {
361 [NSApp beginSheet:[jumpToLinePanelController window]
362 modalForWindow:[[[self windowControllers] objectAtIndex:0] window]
367 [NSApp runModalForWindow:[jumpToLinePanelController window]];
368 [NSApp endSheet:[jumpToLinePanelController window]];
369 [[jumpToLinePanelController window] orderOut:self];
371 if ([jumpToLinePanelController lineNumber] == 0) {
375 [((XMLTextView *)[self currentTextView]) selectLineByNumber:[jumpToLinePanelController lineNumber]];
377 // NSLog(@"jump to line: %d", [jumpToLinePanelController lineNumber]);
382 - (IBAction)showFindPanel:(id)sender {
384 [findPanelController refresh];
386 [NSApp beginSheet:[findPanelController window]
387 modalForWindow:[[[self windowControllers] objectAtIndex:0] window]
392 [NSApp runModalForWindow:[findPanelController window]];
393 [NSApp endSheet:[findPanelController window]];
394 [[findPanelController window] orderOut:self];
396 if ([findPanelController aborted]) {
400 [self findStringWithSearchFlags:[findPanelController searchFlags]];
407 - (IBAction)findNext:(id)sender {
409 [self findStringWithSearchFlags:[findPanelController searchFlags] & NSCaseInsensitiveSearch];
414 - (IBAction)findPrevious:(id)sender {
416 [self findStringWithSearchFlags:([findPanelController searchFlags] | NSBackwardsSearch)];
420 - (BOOL)canUseSelectionForFindNow {
422 NSTextView *view = [self currentTextView];
423 NSRange selectedRange;
429 selectedRange = [view selectedRange];
431 if (selectedRange.length < 1) {
441 - (IBAction)useSelectionForFind:(id)sender {
444 NSTextView *view = [self currentTextView];
446 text = [[view string] substringWithRange:[view selectedRange]];
448 [findPanelController setFindString:text];
457 NSString *currentTabViewItem = [[[self tabView] selectedTabViewItem] identifier];
459 if ([currentTabViewItem isEqualToString:@"xmlTab"]
460 || [currentTabViewItem isEqualToString:@"xsltTab"]
461 || [currentTabViewItem isEqualToString:@"resultTab"]) {
469 - (BOOL)canFindAgainNow {
471 return ([findPanelController findString] != nil) && [self canFindNow];
476 - (void)findStringWithSearchFlags:(int)flags {
478 NSTextView *currentView;
481 NSRange selectedRange, leftRange, rightRange, resultRange, searchRange;
483 NSPasteboard *findBoard = [NSPasteboard pasteboardWithName:NSFindPboard];
485 string = [findBoard stringForType:NSStringPboardType];
487 currentView = [self currentTextView];
488 if (currentView == nil) {
492 text = [currentView string];
494 selectedRange = [currentView selectedRange];
495 leftRange = NSMakeRange(0, selectedRange.location);
496 rightRange = NSMakeRange(NSMaxRange(selectedRange), [text length] - NSMaxRange(selectedRange));
498 if (flags & NSBackwardsSearch) {
499 searchRange = leftRange;
501 searchRange = rightRange;
504 resultRange = [text rangeOfString:string options:flags range:searchRange];
506 if (resultRange.location == NSNotFound) {
511 [currentView setSelectedRange:resultRange];
512 [currentView scrollRangeToVisible:resultRange];
519 - (NSTextView *)currentTextView {
521 NSString *currentTabViewItem = [[[self tabView] selectedTabViewItem] identifier];
523 if ([currentTabViewItem isEqualToString:@"xmlTab"]) {
525 } else if ([currentTabViewItem isEqualToString:@"xsltTab"]) {
527 } else if ([currentTabViewItem isEqualToString:@"resultTab"]) {
539 - (IBAction)process:(id)sender {
542 const char **params = [[workset parameterSet] cArray];
544 struct timeval tstart, tend;
545 gettimeofday(&tstart, NULL);
549 if ([workset hasXsltFilename]) {
550 [processor setBaseUri:[NSString stringWithFormat:@"file://%@", [workset xsltFilename]]];
553 if (![processor processStrings:[XMLUtils getDataWithEncodingFromString:[workset xmlCode]] withXslt:[XMLUtils getDataWithEncodingFromString:[workset xsltCode]] andParameters:params]) {
555 [drawerMessageField setStringValue:[NSString stringWithFormat:@"Error on line %d of your %@ code:\n%@", [processor errorLine], ([processor errorSource] == XSLT_ERROR_SOURCE_XML ? @"XML" : @"XSLT"), [processor errorMessage]]];
558 [errorDrawer openOnEdge:NSMinYEdge];
559 [self showErrorLocation:nil];
563 gettimeofday(&tend, NULL);
565 processingTime = ((tend.tv_sec * 1000000 + tend.tv_usec) - (tstart.tv_sec * 1000000 + tstart.tv_usec)) / 1000;
567 [workset setResult:[processor result]];
568 [workset setResultEncoding:[processor resultEncoding]];
572 [self selectTabById:RESULT];
573 [processingTimeField setStringValue:[NSString stringWithFormat:@"Time: %ldms", processingTime]];
576 webViewUpToDate = NO;
577 imageViewUpToDate = NO;
585 if (resultDirty && [autoSaveCheckbox state] == NSOnState) {
586 [self saveResult:nil];
593 if ([autoShowCheckbox state] == NSOnState) {
594 [self openResultURL:nil];
600 - (IBAction)loadXml:(id)sender {
602 NSOpenPanel *panel = [NSOpenPanel openPanel];
604 if ([panel runModalForDirectory:nil file:nil types:nil] == NSOKButton) {
606 // NSLog(@"choosen: %@", [[panel filenames] objectAtIndex:0]);
608 [workset setXmlCode:[XMLUtils getStringWithEncodingFromFile:[[panel filenames] objectAtIndex:0]]];
609 [workset setXmlFilename:[[panel filenames] objectAtIndex:0]];
610 [self updateChangeCount:NSChangeDone];
611 [self updateCompleteUI];
619 - (IBAction)loadXslt:(id)sender {
621 NSOpenPanel *panel = [NSOpenPanel openPanel];
623 if ([panel runModalForDirectory:nil file:nil types:nil] == NSOKButton) {
625 // NSLog(@"choosen: %@", [[panel filenames] objectAtIndex:0]);
627 [workset setXsltCode:[XMLUtils getStringWithEncodingFromFile:[[panel filenames] objectAtIndex:0]]];
628 [workset setXsltFilename:[[panel filenames] objectAtIndex:0]];
629 [self updateChangeCount:NSChangeDone];
630 [self updateCompleteUI];
638 - (BOOL)canSaveXmlAsNow {
639 return [workset hasXmlCode];
642 - (BOOL)canSaveXmlNow {
643 return [workset hasXmlFilename] && xmlDirty;
646 - (BOOL)canSaveXsltAsNow {
647 return [workset hasXsltCode];
650 - (BOOL)canSaveXsltNow {
651 return [workset hasXsltFilename] && xsltDirty;
654 - (BOOL)canSaveResultAsNow {
655 return [workset hasResult];
658 - (BOOL)canSaveResultNow {
659 return [workset hasResultFilename] && resultDirty;
665 - (IBAction)saveXmlAs:(id)sender {
667 NSSavePanel *panel = [NSSavePanel savePanel];
669 if ([panel runModal] == NSFileHandlingPanelOKButton) {
671 [workset setXmlFilename:[panel filename]];
679 - (IBAction)saveXml:(id)sender {
682 if ([workset hasXmlFilename]) {
691 - (IBAction)saveXsltAs:(id)sender {
693 NSSavePanel *panel = [NSSavePanel savePanel];
695 if ([panel runModal] == NSFileHandlingPanelOKButton) {
697 [workset setXsltFilename:[panel filename]];
705 - (IBAction)saveXslt:(id)sender {
707 if ([workset hasXsltFilename]) {
717 - (IBAction)saveResultAs:(id)sender {
719 NSSavePanel *panel = [NSSavePanel savePanel];
721 if ([panel runModal] == NSFileHandlingPanelOKButton) {
723 [workset setResultFilename:[panel filename]];
725 [self saveResult:nil];
730 - (IBAction)saveResult:(id)sender {
732 if ([workset hasResultFilename]) {
734 [[workset result] writeToFile:[workset resultFilename] atomically:NO];
745 - (IBAction)saveCurrentAs:(id)sender {
747 NSString *activeTabIdentifier = [[tabView selectedTabViewItem] identifier];
748 BOOL xmlTabIsVisible = [activeTabIdentifier isEqualToString:@"xmlTab"];
749 BOOL xsltTabIsVisible = !xmlTabIsVisible && [activeTabIdentifier isEqualToString:@"xsltTab"];
750 BOOL paramTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible) && [activeTabIdentifier isEqualToString:@"parametersTab"];
751 BOOL resultTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible || paramTabIsVisible);
753 if (xmlTabIsVisible) {
754 return [self saveXmlAs:sender];
755 } else if (xsltTabIsVisible) {
756 return [self saveXsltAs:sender];
757 } else if (resultTabIsVisible) {
758 return [self saveResultAs:sender];
766 - (IBAction)saveCurrent:(id)sender {
768 NSString *activeTabIdentifier = [[tabView selectedTabViewItem] identifier];
769 BOOL xmlTabIsVisible = [activeTabIdentifier isEqualToString:@"xmlTab"];
770 BOOL xsltTabIsVisible = !xmlTabIsVisible && [activeTabIdentifier isEqualToString:@"xsltTab"];
771 BOOL paramTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible) && [activeTabIdentifier isEqualToString:@"parametersTab"];
772 BOOL resultTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible || paramTabIsVisible);
774 if (xmlTabIsVisible) {
775 return [self saveXml:sender];
776 } else if (xsltTabIsVisible) {
777 return [self saveXslt:sender];
778 } else if (resultTabIsVisible) {
779 return [self saveResult:sender];
789 - (IBAction)openResultURL:(id)sender {
791 // NSLog(@"openResultURL running...");
793 if ([workset hasResultFilename]) {
795 [[NSWorkspace sharedWorkspace] openURL:[NSURL fileURLWithPath:[workset resultFilename]]];
801 - (IBAction)newParameter:(id)sender {
803 [[workset parameterSet] addParameter:@"name" withValue:@"value"];
808 - (IBAction)removeParameter:(id)sender {
810 int row = [parameterTable selectedRow];
813 [[workset parameterSet] removeParameterAtIndex:row];
821 - (int)numberOfRowsInTableView:(NSTableView *)aTableView {
822 return [[workset parameterSet] count];
825 - (id)tableView:(NSTableView *)aTableView
826 objectValueForTableColumn:(NSTableColumn *)aTableColumn
829 return [[workset parameterSet] getField:[aTableColumn identifier] atIndex:rowIndex];
834 - (void)tableView:(NSTableView *)aTableView
835 setObjectValue:(id)anObject
836 forTableColumn:(NSTableColumn *)aTableColumn
839 [[workset parameterSet] setField:[aTableColumn identifier] atIndex:rowIndex toString:anObject];
845 - (IBAction)setProcessorType:(id)sender {
847 int newType = [sender tag];
849 if ([processor processorType] == newType) {
853 [self switchProcessorToType:newType updateUI:NO];
858 - (IBAction)switchProcessorToType:(int)newType updateUI:(BOOL)updateUI {
860 XSLTProcessor *newProcessor = nil;
862 newProcessor = [XSLTProcessorFactory makeProcessorOfType:newType];
865 NSLog(@"Unable to create new processor of type '%d'", newType);
869 processor = newProcessor;
872 [processorTypePopUp selectItemAtIndex:[processorTypePopUp indexOfItemWithTag:newType]];
880 - (id)handleProcessScriptCommand:(NSScriptCommand *)command {
882 if ([self canProcessNow]) {
891 - (id)handleExportScriptCommand:(NSScriptCommand *)command {
893 NSDictionary *args = [command evaluatedArguments];
894 NSString *file = [args objectForKey:@"File"];
900 [workset setResultFilename:file];
902 [self saveResult:nil];
909 - (id)handleSetParamScriptCommand:(NSScriptCommand *)command {
911 NSDictionary *args = [command evaluatedArguments];
912 NSString *paramName = [args objectForKey:@"Name"];
913 NSString *paramValue = [args objectForKey:@"Value"];
915 [[workset parameterSet] removeParameterByName:paramName];
917 [[workset parameterSet] addParameter:paramName withValue:paramValue];
924 - (id)handleClearParamScriptCommand:(NSScriptCommand *)command {
926 NSDictionary *args = [command evaluatedArguments];
927 NSString *paramName = [args objectForKey:@"Name"];
929 [[workset parameterSet] removeParameterByName:paramName];
934 - (id)handleSetProcessorTypeScriptCommand:(NSScriptCommand *)command {
936 NSDictionary *args = [command evaluatedArguments];
937 NSString *processorType = [args objectForKey:@"Name"];
939 if ([processorType caseInsensitiveCompare:@"libxslt"] == NSOrderedSame) {
941 [self switchProcessorToType:PROCESSORTYPE_LIBXSLT updateUI:YES];
943 } else if ([processorType caseInsensitiveCompare:@"sablotron"] == NSOrderedSame) {
945 [self switchProcessorToType:PROCESSORTYPE_SABLOTRON updateUI:YES];
947 } else if ([processorType caseInsensitiveCompare:@"saxon"] == NSOrderedSame) {
949 [self switchProcessorToType:PROCESSORTYPE_SAXON updateUI:YES];
951 } else if ([processorType caseInsensitiveCompare:@"xalan-j"] == NSOrderedSame) {
953 [self switchProcessorToType:PROCESSORTYPE_XALAN_J updateUI:YES];
956 NSLog(@"unknown processor");
964 - (BOOL)handleDroppedFile:(NSString *)filename forTextView:(NSTextView *)sender {
966 NSString *fileContents = [XMLUtils getStringWithEncodingFromFile:filename];
968 if ([sender isEqual: xmlView]) {
970 [self setXmlcode:fileContents];
971 [workset setXmlFilename:filename];
973 } else if ([sender isEqual:xsltView]) {
975 [self setXsltcode:fileContents];
976 [workset setXsltFilename:filename];
980 NSLog(@"Unknown sender view");
992 - (NSString *)xmlcode {
993 return [workset xmlCode];
996 - (void)setXmlcode:(NSString *)s {
998 NSString *currentContents = [[[NSString alloc] initWithString:[self xmlcode]] autorelease];
1000 [[self undoManager] registerUndoWithTarget:self
1001 selector:@selector(setXmlcode:)
1002 object:currentContents];
1004 [workset setXmlCode:s];
1005 [self updateCompleteUI];
1010 - (NSString *)xsltcode {
1011 return [workset xsltCode];
1014 - (void)setXsltcode:(NSString *)s {
1016 NSString *currentContents = [[[NSString alloc] initWithString:[self xsltcode]] autorelease];
1018 [[self undoManager] registerUndoWithTarget:self
1019 selector:@selector(setXsltcode:)
1020 object:currentContents];
1022 [workset setXsltCode:s];
1023 [self updateCompleteUI];
1027 - (NSString *)result {
1028 return [workset stringResult];
1033 - (void)tableViewSelectionDidChange:(NSNotification *)notification {
1038 - (void)checkForExternalModifications {
1042 if ([workset xmlModifiedExternally] && xmlDirty || [workset xsltModifiedExternally] && xsltDirty) {
1044 /* external changes conflicting with local changes detected.
1045 * Ask the user if we should keep the local unsaved changes
1047 keep = [self showUnsavedChangesPanel];
1051 if ([workset xmlModifiedExternally] && !(xmlDirty && keep)) {
1052 [workset reloadXmlFromFile];
1053 [self updateChangeCount:NSChangeDone];
1054 [self updateCompleteUI];
1058 if ([workset xsltModifiedExternally] && !(xsltDirty && keep)) {
1059 [workset reloadXsltFromFile];
1060 [self updateChangeCount:NSChangeDone];
1061 [self updateCompleteUI];
1070 - (BOOL)showUnsavedChangesPanel {
1072 [NSApp beginSheet:[unsavedChangesPanelController window]
1073 modalForWindow:[[[self windowControllers] objectAtIndex:0] window]
1078 [NSApp runModalForWindow:[unsavedChangesPanelController window]];
1079 [NSApp endSheet:[unsavedChangesPanelController window]];
1080 [[unsavedChangesPanelController window] orderOut:self];
1082 return ([unsavedChangesPanelController keepChanges]);
1086 - (IBAction)renderFo:(id)sender {
1088 XSL_FO_Renderer *xfr = [[XSL_FO_Renderer alloc] init];
1090 NSData *resultData = [xfr render:[workset result]];
1095 NSLog(@"Unable to render, NULL result");
1099 [resultData retain];
1101 pdfData = resultData;
1103 NSImage *pdfImage = [[[NSImage alloc] initWithData:resultData] autorelease];
1104 [pdfImage setBackgroundColor:[NSColor whiteColor]];
1106 [pdfImage setCacheMode:NSImageCacheNever];
1108 NSClipView *clipView = (NSClipView *)[resultImageView superview];
1109 NSScrollView *scrollView = (NSScrollView *)[clipView superview];
1111 [resultImageView setImage:pdfImage];
1112 [resultImageView setFrameSize:[pdfImage size]];
1113 [resultImageView display];
1115 [clipView scrollToPoint:NSMakePoint([resultImageView frame].origin.x, [resultImageView frame].size.height - [clipView frame].size.height + [resultImageView frame].origin.y)];
1116 [scrollView reflectScrolledClipView:clipView];
1118 pdfPageCount = [[[pdfImage representations] objectAtIndex:0] pageCount];
1124 - (IBAction)pdfPreviousPage:(id)sender {
1126 if (pdfCurrentPage > 0) {
1128 [[[[resultImageView image] representations] objectAtIndex:0] setCurrentPage:pdfCurrentPage];
1129 [resultImageView setNeedsDisplay:YES];
1135 - (IBAction)pdfNextPage:(id)sender {
1137 if (pdfCurrentPage < (pdfPageCount - 1)) {
1139 [[[[resultImageView image] representations] objectAtIndex:0] setCurrentPage:pdfCurrentPage];
1140 [resultImageView setNeedsDisplay:YES];
1147 - (IBAction)pdfSaveAs:(id)sender {
1149 NSSavePanel *panel = [NSSavePanel savePanel];
1151 if ([panel runModal] == NSFileHandlingPanelOKButton) {
1153 [pdfData writeToFile:[panel filename] atomically:YES];
1162 - (void)windowDidBecomeMain:(NSNotification *)aNotification {
1164 [self checkForExternalModifications];
1168 - (void)windowDidResize:(NSNotification *)aNotification {
1170 [self resizeWebView];
1174 - (void)resizeWebView {
1176 // [[[resultWebView mainFrame] frameView] setFrame:[resultWebView frame]];
1177 [resultWebView setNeedsDisplay:YES];
1185 - (NSString *)windowNibName
1187 // Override returning the nib file name of the document
1188 // If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
1189 return @"MyDocument";
1192 - (void)windowControllerDidLoadNib:(NSWindowController *) aController
1197 NSSize errorDrawerSize;
1199 [super windowControllerDidLoadNib:aController];
1201 [resultImageView setImageFrameStyle:NSImageFramePhoto];
1202 [resultImageView setImageScaling:NSScaleNone];
1203 [resultImageView setImageAlignment:NSImageAlignCenter];
1204 [resultImageView setEditable:NO];
1206 [resultWebView setTextSizeMultiplier:0.9];
1208 warningIcon = [xmlWellFormedIcon image];
1210 [self updateCompleteUI];
1212 errorDrawerSize = [errorDrawer contentSize];
1213 errorDrawerSize.height = 130;
1214 [errorDrawer setContentSize:errorDrawerSize];
1216 NSFont *computerFont = [NSFont fontWithName:@"Courier" size:12.0];
1217 [resultView setFont:computerFont];
1219 [tabView registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]];
1223 if (findPanelController == nil) {
1224 findPanelController = [[FindPanelController alloc] initWithWindowNibName:@"FindPanel"];
1225 // NSLog(@"init find panel controller: %@", findPanelController);
1228 if (jumpToLinePanelController == nil) {
1229 jumpToLinePanelController = [[JumpToLinePanelController alloc] initWithWindowNibName:@"JumpToLine"];
1230 // NSLog(@"init jump to line panel controller: %@", jumpToLinePanelController);
1233 if (unsavedChangesPanelController == nil) {
1234 unsavedChangesPanelController = [[UnsavedChangesPanelController alloc] initWithWindowNibName:@"UnsavedChanges"];
1235 // NSLog(@"init unsaved changes panel controller: %@", unsavedChangesPanelController);
1244 - (IBAction)showErrorLocation:(id)sender {
1246 XMLTextView *textView;
1249 if ([processor errorSource] == XSLT_ERROR_SOURCE_XML) {
1250 [self selectTabById:XML];
1253 [self selectTabById:XSLT];
1254 textView = xsltView;
1257 errorLine = [processor errorLine];
1259 [textView selectLineByNumber:errorLine];
1263 - (NSData *)dataRepresentationOfType:(NSString *)aType
1265 // Insert code here to write your document from the given data. You can also choose to override -fileWrapperRepresentationOfType: or -writeToFile:ofType: instead.
1266 return [NSArchiver archivedDataWithRootObject:workset];
1269 - (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType
1271 // Insert code here to read your document from the given data. You can also choose to override -loadFileWrapperRepresentation:ofType: or -readFromFile:ofType: instead.
1274 workset = [[NSUnarchiver unarchiveObjectWithData:data] retain];
1275 [self updateCompleteUI];