5 // Created by Marc Liyanage on Sun Mar 03 2002.
6 // Copyright (c) 2001 __MyCompanyName__. All rights reserved.
10 #import "MyDocument.h"
12 #import <Foundation/NSDebug.h>
16 @implementation MyDocument
20 // NSZombieEnabled = YES;
22 if (self = [super init]) {
23 workset = [[Workset alloc] init];
24 processor = [XSLTProcessorFactory makeProcessorOfType:PROCESSORTYPE_SABLOTRON];
25 wellFormedParser = [[XMLParserLibxml alloc] init];
30 defaults = [NSUserDefaults standardUserDefaults];
37 [uiUpdateTimer release];
40 [wellFormedParser release];
41 [findPanelController release];
42 [jumpToLinePanelController release];
43 [unsavedChangesPanelController release];
47 - (IBAction)selectTab:(id)sender {
49 [self selectTabById:[sender tag]];
58 - (IBAction)selectTabById:(int)tabId {
73 tabName = @"parametersTab";
78 tabName = @"resultTab";
84 [tabView selectTabViewItemWithIdentifier:tabName];
88 - (void)textViewDidChangeSelection:(NSNotification *)aNotification {
93 - (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem {
95 [[self undoManager] removeAllActions];
105 // NSLog(@"updateUI running...");
107 [uiUpdateTimer invalidate];
108 [uiUpdateTimer release];
110 uiUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(uiUpdateTimerTarget:) userInfo:nil repeats:NO];
112 [uiUpdateTimer retain];
117 - (void)uiUpdateTimerTarget:(NSTimer *)timer {
129 NSString *activeTabIdentifier = [[tabView selectedTabViewItem] identifier];
130 NSString *activeResultTabIdentifier = [[resultTabView selectedTabViewItem] identifier];
132 BOOL xmlTabIsVisible = [activeTabIdentifier isEqualToString:@"xmlTab"];
133 BOOL xsltTabIsVisible = !xmlTabIsVisible && [activeTabIdentifier isEqualToString:@"xsltTab"];
134 BOOL paramTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible) && [activeTabIdentifier isEqualToString:@"parametersTab"];
135 BOOL resultTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible || paramTabIsVisible);
136 BOOL resultTabHtmlIsVisible = resultTabIsVisible && [activeResultTabIdentifier isEqualToString:@"htmlResult"];
137 BOOL resultTabXslfoIsVisible = resultTabIsVisible && !resultTabHtmlIsVisible && [activeResultTabIdentifier isEqualToString:@"xslfoResult"];
138 BOOL resultTabTextIsVisible = resultTabIsVisible && !(resultTabHtmlIsVisible || resultTabXslfoIsVisible);
140 // NSLog(@"xml: %d, xslt: %d, param: %d, result: %d, reshtml: %d, resxslfo: %d, restext: %d", xmlTabIsVisible, xsltTabIsVisible, paramTabIsVisible, resultTabIsVisible, resultTabHtmlIsVisible, resultTabXslfoIsVisible, resultTabTextIsVisible);
142 if (xmlTabIsVisible) {
143 [saveXmlFilenameField setObjectValue:[workset xmlFilename]];
144 [saveXmlFilenameField setToolTip:[workset xmlFilename]];
145 [saveXmlButton setEnabled:[self canSaveXmlNow]];
146 [saveXmlAsButton setEnabled:[self canSaveXmlAsNow]];
147 [xmlTagStackField setStringValue:[xmlView calculateTagStack]];
149 if ([defaults boolForKey:@"enableWellformedCheck"]) {
150 [xmlView checkWellFormed];
151 if ([workset hasXmlCode] && [xmlView hasError]) {
152 [xmlWellFormedIcon setImage:warningIcon];
153 [xmlWellFormedIcon setToolTip:[xmlView valueForKey:@"errorString"]];
154 [self setValue:[xmlView valueForKey:@"errorString"] forKey:@"drawerMessage"];
156 [xmlWellFormedIcon setImage:nil];
157 [xmlWellFormedIcon setToolTip:nil];
158 [self setValue:nil forKey:@"drawerMessage"];
162 } else if (xsltTabIsVisible) {
163 [saveXsltFilenameField setObjectValue:[workset xsltFilename]];
164 [saveXsltFilenameField setToolTip:[workset xsltFilename]];
165 [saveXsltButton setEnabled:[self canSaveXsltNow]];
166 [saveXsltAsButton setEnabled:[self canSaveXsltAsNow]];
167 [xsltTagStackField setStringValue:[xsltView calculateTagStack]];
169 if ([defaults boolForKey:@"enableWellformedCheck"]) {
170 [xsltView checkWellFormed];
171 if ([workset hasXsltCode] && [xsltView hasError]) {
172 [xsltWellFormedIcon setImage:warningIcon];
173 [xsltWellFormedIcon setToolTip:[xsltView valueForKey:@"errorString"]];
174 [self setValue:[xsltView valueForKey:@"errorString"] forKey:@"drawerMessage"];
176 [xsltWellFormedIcon setImage:nil];
177 [xsltWellFormedIcon setToolTip:nil];
178 [self setValue:nil forKey:@"drawerMessage"];
182 } else if (paramTabIsVisible) {
183 [paramRemoveButton setEnabled:[parameterTable selectedRow] != -1];
184 [parameterTable reloadData];
185 } else if (resultTabIsVisible) {
186 [saveResultAsButton setEnabled:[self canSaveResultAsNow]];
187 [saveResultButton setEnabled:[self canSaveResultNow]];
188 [autoSaveCheckbox setEnabled:[workset hasResultFilename]];
189 [openResultURLButton setEnabled:[workset hasResultFilename]];
190 [autoShowCheckbox setEnabled:[openResultURLButton isEnabled]];
191 [saveResultFilenameField setObjectValue:[workset resultFilename]];
192 [saveResultFilenameField setToolTip:[workset resultFilename]];
194 if (resultTabHtmlIsVisible) {
195 [self resizeWebView];
196 [self updateResultWebView];
197 } else if (resultTabXslfoIsVisible) {
198 [self updateResultImageView];
199 [pdfCurrentPageField setIntValue: (pdfPageCount ? (pdfCurrentPage + 1) : 0)];
200 [pdfPageCountField setIntValue:pdfPageCount];
202 [pdfPreviousPageButton setEnabled:pdfCurrentPage > 0];
203 [pdfNextPageButton setEnabled:pdfCurrentPage < (pdfPageCount - 1)];
204 [pdfSaveAsButton setEnabled:(pdfPageCount > 0)];
205 // } else if (resultTabTextIsVisible) {
211 [processButton setEnabled:[self canProcessNow]];
213 // move this to xmlview.
214 // [self updateWellFormedIcons];
218 [resultView setString:[workset stringResult]];
223 - (void)updateResultWebView {
224 if (!webViewUpToDate) {
225 WebFrame *mainFrame = [resultWebView mainFrame];
226 // [mainFrame loadHTMLString:[workset stringResult] baseURL:nil];
227 [mainFrame loadHTMLString:[workset stringResult] baseURL:[NSURL URLWithString:[webViewBaseURL stringValue]]];
228 // [mainFrame loadHTMLString:[workset stringResult] baseURL:[NSURL URLWithString:@"file:///Users/liyanage/Sites/primavera/images/x"]];
229 webViewUpToDate = YES;
234 - (void)updateResultImageView {
235 if (!imageViewUpToDate) {
236 [self renderFo:self];
237 imageViewUpToDate = YES;
243 - (BOOL)canProcessNow {
245 return [workset hasXmlCode] && [workset hasXsltCode];
249 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
251 // NSLog(@"validate: %@, tag: %d", menuItem, [menuItem tag]);
253 NSString *activeTabIdentifier = [[tabView selectedTabViewItem] identifier];
254 BOOL xmlTabIsVisible = [activeTabIdentifier isEqualToString:@"xmlTab"];
255 BOOL xsltTabIsVisible = !xmlTabIsVisible && [activeTabIdentifier isEqualToString:@"xsltTab"];
256 BOOL paramTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible) && [activeTabIdentifier isEqualToString:@"parametersTab"];
257 BOOL resultTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible || paramTabIsVisible);
260 switch ([menuItem tag]) {
263 return [self canProcessNow];
267 return [workset hasResultFilename];
271 return [self canFindNow];
274 case 13: // Find Next
275 case 14: // Find Previous
276 return [self canFindAgainNow];
279 case 15: // Use Selection for Find
280 return [self canUseSelectionForFindNow];
283 case 16: // Jump to Line
284 return [self canJumpToLineNow];
287 case 17: // Save Current Pane
288 if (xmlTabIsVisible) {
289 return [self canSaveXmlNow];
290 } else if (xsltTabIsVisible) {
291 return [self canSaveXsltNow];
292 } else if (resultTabIsVisible) {
293 return [self canSaveResultNow];
297 case 18: // Save Current Pane As...
298 if (xmlTabIsVisible) {
299 return [self canSaveXmlAsNow];
300 } else if (xsltTabIsVisible) {
301 return [self canSaveXsltAsNow];
302 } else if (resultTabIsVisible) {
303 return [self canSaveResultAsNow];
316 - (IBAction)showInBrowser:(id)sender {
323 - (void)updateCompleteUI {
325 [xmlView setString:[workset xmlCode]];
326 [xsltView setString:[workset xsltCode]];
331 - (void)textDidChange:(NSNotification *)aNotification {
333 id sender = [aNotification object];
335 if ([sender isEqual:xmlView]) {
336 [workset setXmlCode:[xmlView string]];
338 } else if ([sender isEqual:xsltView]) {
339 [workset setXsltCode:[xsltView string]];
343 [self updateChangeCount:NSChangeDone];
350 - (NSTabView *)tabView {
356 - (BOOL)canJumpToLineNow {
358 NSTextView *view = [self currentTextView];
360 return (view == xmlView) || (view == xsltView);
365 - (IBAction)showJumpToLinePanel:(id)sender {
367 [NSApp beginSheet:[jumpToLinePanelController window]
368 modalForWindow:[[[self windowControllers] objectAtIndex:0] window]
373 [NSApp runModalForWindow:[jumpToLinePanelController window]];
374 [NSApp endSheet:[jumpToLinePanelController window]];
375 [[jumpToLinePanelController window] orderOut:self];
377 if ([jumpToLinePanelController lineNumber] == 0) {
381 [((XMLTextView *)[self currentTextView]) selectLineByNumber:[jumpToLinePanelController lineNumber]];
383 // NSLog(@"jump to line: %d", [jumpToLinePanelController lineNumber]);
388 - (IBAction)showFindPanel:(id)sender {
390 [findPanelController refresh];
392 [NSApp beginSheet:[findPanelController window]
393 modalForWindow:[[[self windowControllers] objectAtIndex:0] window]
398 [NSApp runModalForWindow:[findPanelController window]];
399 [NSApp endSheet:[findPanelController window]];
400 [[findPanelController window] orderOut:self];
402 if ([findPanelController aborted]) {
406 [self findStringWithSearchFlags:[findPanelController searchFlags]];
413 - (IBAction)findNext:(id)sender {
415 [self findStringWithSearchFlags:[findPanelController searchFlags] & NSCaseInsensitiveSearch];
420 - (IBAction)findPrevious:(id)sender {
422 [self findStringWithSearchFlags:([findPanelController searchFlags] | NSBackwardsSearch)];
426 - (BOOL)canUseSelectionForFindNow {
428 NSTextView *view = [self currentTextView];
429 NSRange selectedRange;
435 selectedRange = [view selectedRange];
437 if (selectedRange.length < 1) {
447 - (IBAction)useSelectionForFind:(id)sender {
450 NSTextView *view = [self currentTextView];
452 text = [[view string] substringWithRange:[view selectedRange]];
454 [findPanelController setFindString:text];
463 NSString *currentTabViewItem = [[[self tabView] selectedTabViewItem] identifier];
465 if ([currentTabViewItem isEqualToString:@"xmlTab"]
466 || [currentTabViewItem isEqualToString:@"xsltTab"]
467 || [currentTabViewItem isEqualToString:@"resultTab"]) {
475 - (BOOL)canFindAgainNow {
477 return ([findPanelController findString] != nil) && [self canFindNow];
482 - (void)findStringWithSearchFlags:(int)flags {
484 NSTextView *currentView;
487 NSRange selectedRange, leftRange, rightRange, resultRange, searchRange;
489 NSPasteboard *findBoard = [NSPasteboard pasteboardWithName:NSFindPboard];
491 string = [findBoard stringForType:NSStringPboardType];
493 currentView = [self currentTextView];
494 if (currentView == nil) {
498 text = [currentView string];
500 selectedRange = [currentView selectedRange];
501 leftRange = NSMakeRange(0, selectedRange.location);
502 rightRange = NSMakeRange(NSMaxRange(selectedRange), [text length] - NSMaxRange(selectedRange));
504 if (flags & NSBackwardsSearch) {
505 searchRange = leftRange;
507 searchRange = rightRange;
510 resultRange = [text rangeOfString:string options:flags range:searchRange];
512 if (resultRange.location == NSNotFound) {
517 [currentView setSelectedRange:resultRange];
518 [currentView scrollRangeToVisible:resultRange];
525 - (NSTextView *)currentTextView {
527 NSString *currentTabViewItem = [[[self tabView] selectedTabViewItem] identifier];
529 if ([currentTabViewItem isEqualToString:@"xmlTab"]) {
531 } else if ([currentTabViewItem isEqualToString:@"xsltTab"]) {
533 } else if ([currentTabViewItem isEqualToString:@"resultTab"]) {
545 - (IBAction)process:(id)sender {
548 const char **params = [[workset parameterSet] cArray];
550 struct timeval tstart, tend;
551 gettimeofday(&tstart, NULL);
555 if ([workset hasXsltFilename]) {
556 [processor setBaseUri:[NSString stringWithFormat:@"file://%@", [workset xsltFilename]]];
559 if (![processor processStrings:[XMLUtils getDataWithEncodingFromString:[workset xmlCode]] withXslt:[XMLUtils getDataWithEncodingFromString:[workset xsltCode]] andParameters:params]) {
561 [self setValue:[NSString stringWithFormat:@"Error on line %d of your %@ code:\n%@", [processor errorLine], ([processor errorSource] == XSLT_ERROR_SOURCE_XML ? @"XML" : @"XSLT"), [processor errorMessage]] forKey:@"drawerMessage"];
564 [errorDrawer openOnEdge:NSMinYEdge];
565 [self showErrorLocation:nil];
569 gettimeofday(&tend, NULL);
571 processingTime = ((tend.tv_sec * 1000000 + tend.tv_usec) - (tstart.tv_sec * 1000000 + tstart.tv_usec)) / 1000;
573 [workset setResult:[processor result]];
574 [workset setResultEncoding:[processor resultEncoding]];
577 // [errorDrawer close];
578 [self selectTabById:RESULT];
579 [processingTimeField setStringValue:[NSString stringWithFormat:@"Time: %ldms", processingTime]];
582 webViewUpToDate = NO;
583 imageViewUpToDate = NO;
591 if (resultDirty && [autoSaveCheckbox state] == NSOnState) {
592 [self saveResult:nil];
599 if ([autoShowCheckbox state] == NSOnState) {
600 [self openResultURL:nil];
606 - (IBAction)loadXml:(id)sender {
608 NSOpenPanel *panel = [NSOpenPanel openPanel];
610 if ([panel runModalForDirectory:nil file:nil types:nil] == NSOKButton) {
612 // NSLog(@"choosen: %@", [[panel filenames] objectAtIndex:0]);
614 [workset setXmlCode:[XMLUtils getStringWithEncodingFromFile:[[panel filenames] objectAtIndex:0]]];
615 [workset setXmlFilename:[[panel filenames] objectAtIndex:0]];
616 [self updateChangeCount:NSChangeDone];
617 [self updateCompleteUI];
625 - (IBAction)loadXslt:(id)sender {
627 NSOpenPanel *panel = [NSOpenPanel openPanel];
629 if ([panel runModalForDirectory:nil file:nil types:nil] == NSOKButton) {
631 // NSLog(@"choosen: %@", [[panel filenames] objectAtIndex:0]);
633 [workset setXsltCode:[XMLUtils getStringWithEncodingFromFile:[[panel filenames] objectAtIndex:0]]];
634 [workset setXsltFilename:[[panel filenames] objectAtIndex:0]];
635 [self updateChangeCount:NSChangeDone];
636 [self updateCompleteUI];
644 - (BOOL)canSaveXmlAsNow {
645 return [workset hasXmlCode];
648 - (BOOL)canSaveXmlNow {
649 return [workset hasXmlFilename] && xmlDirty;
652 - (BOOL)canSaveXsltAsNow {
653 return [workset hasXsltCode];
656 - (BOOL)canSaveXsltNow {
657 return [workset hasXsltFilename] && xsltDirty;
660 - (BOOL)canSaveResultAsNow {
661 return [workset hasResult];
664 - (BOOL)canSaveResultNow {
665 return [workset hasResultFilename] && resultDirty;
671 - (IBAction)saveXmlAs:(id)sender {
673 NSSavePanel *panel = [NSSavePanel savePanel];
675 if ([panel runModal] == NSFileHandlingPanelOKButton) {
677 [workset setXmlFilename:[panel filename]];
685 - (IBAction)saveXml:(id)sender {
688 if ([workset hasXmlFilename]) {
697 - (IBAction)saveXsltAs:(id)sender {
699 NSSavePanel *panel = [NSSavePanel savePanel];
701 if ([panel runModal] == NSFileHandlingPanelOKButton) {
703 [workset setXsltFilename:[panel filename]];
711 - (IBAction)saveXslt:(id)sender {
713 if ([workset hasXsltFilename]) {
723 - (IBAction)saveResultAs:(id)sender {
725 NSSavePanel *panel = [NSSavePanel savePanel];
727 if ([panel runModal] == NSFileHandlingPanelOKButton) {
729 [workset setResultFilename:[panel filename]];
731 [self saveResult:nil];
736 - (IBAction)saveResult:(id)sender {
738 if ([workset hasResultFilename]) {
740 [[workset result] writeToFile:[workset resultFilename] atomically:NO];
751 - (IBAction)saveCurrentAs:(id)sender {
753 NSString *activeTabIdentifier = [[tabView selectedTabViewItem] identifier];
754 BOOL xmlTabIsVisible = [activeTabIdentifier isEqualToString:@"xmlTab"];
755 BOOL xsltTabIsVisible = !xmlTabIsVisible && [activeTabIdentifier isEqualToString:@"xsltTab"];
756 BOOL paramTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible) && [activeTabIdentifier isEqualToString:@"parametersTab"];
757 BOOL resultTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible || paramTabIsVisible);
759 if (xmlTabIsVisible) {
760 return [self saveXmlAs:sender];
761 } else if (xsltTabIsVisible) {
762 return [self saveXsltAs:sender];
763 } else if (resultTabIsVisible) {
764 return [self saveResultAs:sender];
772 - (IBAction)saveCurrent:(id)sender {
774 NSString *activeTabIdentifier = [[tabView selectedTabViewItem] identifier];
775 BOOL xmlTabIsVisible = [activeTabIdentifier isEqualToString:@"xmlTab"];
776 BOOL xsltTabIsVisible = !xmlTabIsVisible && [activeTabIdentifier isEqualToString:@"xsltTab"];
777 BOOL paramTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible) && [activeTabIdentifier isEqualToString:@"parametersTab"];
778 BOOL resultTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible || paramTabIsVisible);
780 if (xmlTabIsVisible) {
781 return [self saveXml:sender];
782 } else if (xsltTabIsVisible) {
783 return [self saveXslt:sender];
784 } else if (resultTabIsVisible) {
785 return [self saveResult:sender];
795 - (IBAction)openResultURL:(id)sender {
797 // NSLog(@"openResultURL running...");
799 if ([workset hasResultFilename]) {
801 [[NSWorkspace sharedWorkspace] openURL:[NSURL fileURLWithPath:[workset resultFilename]]];
807 - (IBAction)newParameter:(id)sender {
809 [[workset parameterSet] addParameter:@"name" withValue:@"value"];
814 - (IBAction)removeParameter:(id)sender {
816 int row = [parameterTable selectedRow];
819 [[workset parameterSet] removeParameterAtIndex:row];
827 - (int)numberOfRowsInTableView:(NSTableView *)aTableView {
828 return [[workset parameterSet] count];
831 - (id)tableView:(NSTableView *)aTableView
832 objectValueForTableColumn:(NSTableColumn *)aTableColumn
835 return [[workset parameterSet] getField:[aTableColumn identifier] atIndex:rowIndex];
840 - (void)tableView:(NSTableView *)aTableView
841 setObjectValue:(id)anObject
842 forTableColumn:(NSTableColumn *)aTableColumn
845 [[workset parameterSet] setField:[aTableColumn identifier] atIndex:rowIndex toString:anObject];
851 - (IBAction)setProcessorType:(id)sender {
853 int newType = [sender tag];
855 if ([processor processorType] == newType) {
859 [self switchProcessorToType:newType updateUI:NO];
864 - (IBAction)switchProcessorToType:(int)newType updateUI:(BOOL)updateUI {
866 XSLTProcessor *newProcessor = nil;
868 newProcessor = [XSLTProcessorFactory makeProcessorOfType:newType];
871 NSLog(@"Unable to create new processor of type '%d'", newType);
875 processor = newProcessor;
878 [processorTypePopUp selectItemAtIndex:[processorTypePopUp indexOfItemWithTag:newType]];
886 - (id)handleProcessScriptCommand:(NSScriptCommand *)command {
888 if ([self canProcessNow]) {
897 - (id)handleExportScriptCommand:(NSScriptCommand *)command {
899 NSDictionary *args = [command evaluatedArguments];
900 NSString *file = [args objectForKey:@"File"];
906 [workset setResultFilename:file];
908 [self saveResult:nil];
915 - (id)handleSetParamScriptCommand:(NSScriptCommand *)command {
917 NSDictionary *args = [command evaluatedArguments];
918 NSString *paramName = [args objectForKey:@"Name"];
919 NSString *paramValue = [args objectForKey:@"Value"];
921 [[workset parameterSet] removeParameterByName:paramName];
923 [[workset parameterSet] addParameter:paramName withValue:paramValue];
930 - (id)handleClearParamScriptCommand:(NSScriptCommand *)command {
932 NSDictionary *args = [command evaluatedArguments];
933 NSString *paramName = [args objectForKey:@"Name"];
935 [[workset parameterSet] removeParameterByName:paramName];
940 - (id)handleSetProcessorTypeScriptCommand:(NSScriptCommand *)command {
942 NSDictionary *args = [command evaluatedArguments];
943 NSString *processorType = [args objectForKey:@"Name"];
945 if ([processorType caseInsensitiveCompare:@"libxslt"] == NSOrderedSame) {
947 [self switchProcessorToType:PROCESSORTYPE_LIBXSLT updateUI:YES];
949 } else if ([processorType caseInsensitiveCompare:@"sablotron"] == NSOrderedSame) {
951 [self switchProcessorToType:PROCESSORTYPE_SABLOTRON updateUI:YES];
953 } else if ([processorType caseInsensitiveCompare:@"saxon"] == NSOrderedSame) {
955 [self switchProcessorToType:PROCESSORTYPE_SAXON updateUI:YES];
957 } else if ([processorType caseInsensitiveCompare:@"xalan-j"] == NSOrderedSame) {
959 [self switchProcessorToType:PROCESSORTYPE_XALAN_J updateUI:YES];
962 NSLog(@"unknown processor");
970 - (BOOL)handleDroppedFile:(NSString *)filename forTextView:(NSTextView *)sender {
972 NSString *fileContents = [XMLUtils getStringWithEncodingFromFile:filename];
974 if ([sender isEqual: xmlView]) {
976 [self setXmlcode:fileContents];
977 [workset setXmlFilename:filename];
979 } else if ([sender isEqual:xsltView]) {
981 [self setXsltcode:fileContents];
982 [workset setXsltFilename:filename];
986 NSLog(@"Unknown sender view");
998 - (NSString *)xmlcode {
999 return [workset xmlCode];
1002 - (void)setXmlcode:(NSString *)s {
1004 NSString *currentContents = [[[NSString alloc] initWithString:[self xmlcode]] autorelease];
1006 [[self undoManager] registerUndoWithTarget:self
1007 selector:@selector(setXmlcode:)
1008 object:currentContents];
1010 [workset setXmlCode:s];
1011 [self updateCompleteUI];
1016 - (NSString *)xsltcode {
1017 return [workset xsltCode];
1020 - (void)setXsltcode:(NSString *)s {
1022 NSString *currentContents = [[[NSString alloc] initWithString:[self xsltcode]] autorelease];
1024 [[self undoManager] registerUndoWithTarget:self
1025 selector:@selector(setXsltcode:)
1026 object:currentContents];
1028 [workset setXsltCode:s];
1029 [self updateCompleteUI];
1033 - (NSString *)result {
1034 return [workset stringResult];
1039 - (void)tableViewSelectionDidChange:(NSNotification *)notification {
1044 - (void)checkForExternalModifications {
1048 if ([workset xmlModifiedExternally] && xmlDirty || [workset xsltModifiedExternally] && xsltDirty) {
1050 /* external changes conflicting with local changes detected.
1051 * Ask the user if we should keep the local unsaved changes
1053 keep = [self showUnsavedChangesPanel];
1057 if ([workset xmlModifiedExternally] && !(xmlDirty && keep)) {
1058 [workset reloadXmlFromFile];
1059 [self updateChangeCount:NSChangeDone];
1060 [self updateCompleteUI];
1064 if ([workset xsltModifiedExternally] && !(xsltDirty && keep)) {
1065 [workset reloadXsltFromFile];
1066 [self updateChangeCount:NSChangeDone];
1067 [self updateCompleteUI];
1076 - (BOOL)showUnsavedChangesPanel {
1078 [NSApp beginSheet:[unsavedChangesPanelController window]
1079 modalForWindow:[[[self windowControllers] objectAtIndex:0] window]
1084 [NSApp runModalForWindow:[unsavedChangesPanelController window]];
1085 [NSApp endSheet:[unsavedChangesPanelController window]];
1086 [[unsavedChangesPanelController window] orderOut:self];
1088 return ([unsavedChangesPanelController keepChanges]);
1092 - (void)xslfoRenderThread {
1094 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1096 XSL_FO_Renderer *xfr = [[[XSL_FO_Renderer alloc] init] autorelease];
1097 xslfoRendererResultData = [xfr render:[workset result]];
1100 [xslfoRendererLock unlockWithCondition:2];
1105 - (IBAction)renderFo:(id)sender {
1107 xslfoRendererLock = [[[NSConditionLock alloc] initWithCondition:1] autorelease];
1108 [NSThread detachNewThreadSelector:@selector(xslfoRenderThread) toTarget:self withObject:nil];
1109 [xslfoRendererLock lockWhenCondition:2];
1110 [xslfoRendererLock unlock];
1112 if (!xslfoRendererResultData) {
1113 NSLog(@"Unable to render, NULL result");
1117 [xslfoRendererResultData retain];
1119 pdfData = xslfoRendererResultData;
1121 NSImage *pdfImage = [[[NSImage alloc] initWithData:xslfoRendererResultData] autorelease];
1122 [pdfImage setBackgroundColor:[NSColor whiteColor]];
1124 [pdfImage setCacheMode:NSImageCacheNever];
1126 NSClipView *clipView = (NSClipView *)[resultImageView superview];
1127 NSScrollView *scrollView = (NSScrollView *)[clipView superview];
1129 [resultImageView setImage:pdfImage];
1130 [resultImageView setFrameSize:[pdfImage size]];
1131 [resultImageView display];
1133 [clipView scrollToPoint:NSMakePoint([resultImageView frame].origin.x, [resultImageView frame].size.height - [clipView frame].size.height + [resultImageView frame].origin.y)];
1134 [scrollView reflectScrolledClipView:clipView];
1136 pdfPageCount = [[[pdfImage representations] objectAtIndex:0] pageCount];
1142 - (IBAction)pdfPreviousPage:(id)sender {
1144 if (pdfCurrentPage > 0) {
1146 [[[[resultImageView image] representations] objectAtIndex:0] setCurrentPage:pdfCurrentPage];
1147 [resultImageView setNeedsDisplay:YES];
1153 - (IBAction)pdfNextPage:(id)sender {
1155 if (pdfCurrentPage < (pdfPageCount - 1)) {
1157 [[[[resultImageView image] representations] objectAtIndex:0] setCurrentPage:pdfCurrentPage];
1158 [resultImageView setNeedsDisplay:YES];
1165 - (IBAction)pdfSaveAs:(id)sender {
1167 NSSavePanel *panel = [NSSavePanel savePanel];
1169 if ([panel runModal] == NSFileHandlingPanelOKButton) {
1171 [pdfData writeToFile:[panel filename] atomically:YES];
1180 - (void)windowDidBecomeMain:(NSNotification *)aNotification {
1182 [self checkForExternalModifications];
1186 - (void)windowDidResize:(NSNotification *)aNotification {
1188 [self resizeWebView];
1192 - (void)resizeWebView {
1194 // [[[resultWebView mainFrame] frameView] setFrame:[resultWebView frame]];
1195 [resultWebView setNeedsDisplay:YES];
1203 - (NSString *)windowNibName
1205 // Override returning the nib file name of the document
1206 // 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.
1207 return @"MyDocument";
1210 - (void)windowControllerDidLoadNib:(NSWindowController *) aController
1215 NSSize errorDrawerSize;
1217 [super windowControllerDidLoadNib:aController];
1219 [resultImageView setImageFrameStyle:NSImageFramePhoto];
1220 [resultImageView setImageScaling:NSScaleNone];
1221 [resultImageView setImageAlignment:NSImageAlignCenter];
1222 [resultImageView setEditable:NO];
1224 [resultWebView setTextSizeMultiplier:0.9];
1226 warningIcon = [xmlWellFormedIcon image];
1228 [self updateCompleteUI];
1230 errorDrawerSize = [errorDrawer contentSize];
1231 errorDrawerSize.height = 130;
1232 [errorDrawer setContentSize:errorDrawerSize];
1234 NSFont *computerFont = [NSFont fontWithName:@"Courier" size:12.0];
1235 [resultView setFont:computerFont];
1237 [tabView registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]];
1241 if (findPanelController == nil) {
1242 findPanelController = [[FindPanelController alloc] initWithWindowNibName:@"FindPanel"];
1243 // NSLog(@"init find panel controller: %@", findPanelController);
1246 if (jumpToLinePanelController == nil) {
1247 jumpToLinePanelController = [[JumpToLinePanelController alloc] initWithWindowNibName:@"JumpToLine"];
1248 // NSLog(@"init jump to line panel controller: %@", jumpToLinePanelController);
1251 if (unsavedChangesPanelController == nil) {
1252 unsavedChangesPanelController = [[UnsavedChangesPanelController alloc] initWithWindowNibName:@"UnsavedChanges"];
1253 // NSLog(@"init unsaved changes panel controller: %@", unsavedChangesPanelController);
1259 - (void)canCloseDocumentWithDelegate:(id)delegate shouldCloseSelector:(SEL)shouldCloseSelector contextInfo:(void *)contextInfo {
1261 [uiUpdateTimer invalidate];
1262 [super canCloseDocumentWithDelegate:delegate shouldCloseSelector:shouldCloseSelector contextInfo:contextInfo];
1272 - (IBAction)showErrorLocation:(id)sender {
1274 XMLTextView *textView;
1277 if ([processor errorSource] == XSLT_ERROR_SOURCE_XML) {
1278 [self selectTabById:XML];
1281 [self selectTabById:XSLT];
1282 textView = xsltView;
1285 errorLine = [processor errorLine];
1287 [textView selectLineByNumber:errorLine];
1291 - (NSData *)dataRepresentationOfType:(NSString *)aType
1293 // Insert code here to write your document from the given data. You can also choose to override -fileWrapperRepresentationOfType: or -writeToFile:ofType: instead.
1294 return [NSArchiver archivedDataWithRootObject:workset];
1297 - (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType
1299 // Insert code here to read your document from the given data. You can also choose to override -loadFileWrapperRepresentation:ofType: or -readFromFile:ofType: instead.
1302 workset = [[NSUnarchiver unarchiveObjectWithData:data] retain];
1303 [self updateCompleteUI];