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 invalidate];
38 [uiUpdateTimer release];
41 [wellFormedParser release];
42 [findPanelController release];
43 [jumpToLinePanelController release];
44 [unsavedChangesPanelController release];
49 - (IBAction)selectTab:(id)sender {
51 [self selectTabById:[sender tag]];
56 - (IBAction)selectTabById:(int)tabId {
71 tabName = @"parametersTab";
76 tabName = @"resultTab";
81 [tabView selectTabViewItemWithIdentifier:tabName];
86 - (void)textViewDidChangeSelection:(NSNotification *)aNotification {
91 - (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem {
93 [[self undoManager] removeAllActions];
101 // NSLog(@"updateUI running...");
103 [uiUpdateTimer invalidate];
104 [uiUpdateTimer release];
106 uiUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(uiUpdateTimerTarget:) userInfo:nil repeats:NO];
108 [uiUpdateTimer retain];
114 - (void)uiUpdateTimerTarget:(NSTimer *)timer {
124 NSString *activeTabIdentifier = [[tabView selectedTabViewItem] identifier];
125 NSString *activeResultTabIdentifier = [[resultTabView selectedTabViewItem] identifier];
127 BOOL xmlTabIsVisible = [activeTabIdentifier isEqualToString:@"xmlTab"];
128 BOOL xsltTabIsVisible = !xmlTabIsVisible && [activeTabIdentifier isEqualToString:@"xsltTab"];
129 BOOL paramTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible) && [activeTabIdentifier isEqualToString:@"parametersTab"];
130 BOOL resultTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible || paramTabIsVisible);
131 BOOL resultTabHtmlIsVisible = resultTabIsVisible && [activeResultTabIdentifier isEqualToString:@"htmlResult"];
132 BOOL resultTabXslfoIsVisible = resultTabIsVisible && !resultTabHtmlIsVisible && [activeResultTabIdentifier isEqualToString:@"xslfoResult"];
133 // BOOL resultTabTextIsVisible = resultTabIsVisible && !(resultTabHtmlIsVisible || resultTabXslfoIsVisible);
135 // NSLog(@"xml: %d, xslt: %d, param: %d, result: %d, reshtml: %d, resxslfo: %d, restext: %d", xmlTabIsVisible, xsltTabIsVisible, paramTabIsVisible, resultTabIsVisible, resultTabHtmlIsVisible, resultTabXslfoIsVisible, resultTabTextIsVisible);
137 if (xmlTabIsVisible) {
138 [saveXmlFilenameField setObjectValue:[workset xmlFilename]];
139 [saveXmlFilenameField setToolTip:[workset xmlFilename]];
140 [saveXmlButton setEnabled:[self canSaveXmlNow]];
141 [saveXmlAsButton setEnabled:[self canSaveXmlAsNow]];
142 [xmlTagStackField setStringValue:[xmlView calculateTagStack]];
144 if ([defaults boolForKey:@"enableWellformedCheck"]) {
145 [xmlView checkWellFormed];
146 if ([workset hasXmlCode] && [xmlView hasError]) {
147 [xmlWellFormedIcon setImage:warningIcon];
148 [xmlWellFormedIcon setToolTip:[xmlView valueForKey:@"errorString"]];
149 [self setValue:[xmlView valueForKey:@"errorString"] forKey:@"drawerMessage"];
151 [xmlWellFormedIcon setImage:nil];
152 [xmlWellFormedIcon setToolTip:nil];
153 [self setValue:nil forKey:@"drawerMessage"];
157 } else if (xsltTabIsVisible) {
158 [saveXsltFilenameField setObjectValue:[workset xsltFilename]];
159 [saveXsltFilenameField setToolTip:[workset xsltFilename]];
160 [saveXsltButton setEnabled:[self canSaveXsltNow]];
161 [saveXsltAsButton setEnabled:[self canSaveXsltAsNow]];
162 [xsltTagStackField setStringValue:[xsltView calculateTagStack]];
164 if ([defaults boolForKey:@"enableWellformedCheck"]) {
165 [xsltView checkWellFormed];
166 if ([workset hasXsltCode] && [xsltView hasError]) {
167 [xsltWellFormedIcon setImage:warningIcon];
168 [xsltWellFormedIcon setToolTip:[xsltView valueForKey:@"errorString"]];
169 [self setValue:[xsltView valueForKey:@"errorString"] forKey:@"drawerMessage"];
171 [xsltWellFormedIcon setImage:nil];
172 [xsltWellFormedIcon setToolTip:nil];
173 [self setValue:nil forKey:@"drawerMessage"];
177 } else if (paramTabIsVisible) {
178 [paramRemoveButton setEnabled:[parameterTable selectedRow] != -1];
179 [parameterTable reloadData];
180 } else if (resultTabIsVisible) {
181 [saveResultAsButton setEnabled:[self canSaveResultAsNow]];
182 [saveResultButton setEnabled:[self canSaveResultNow]];
183 [autoSaveCheckbox setEnabled:[workset hasResultFilename]];
184 [openResultURLButton setEnabled:[workset hasResultFilename]];
185 [autoShowCheckbox setEnabled:[openResultURLButton isEnabled]];
186 [saveResultFilenameField setObjectValue:[workset resultFilename]];
187 [saveResultFilenameField setToolTip:[workset resultFilename]];
189 if (resultTabHtmlIsVisible) {
190 [self resizeWebView];
191 [self updateResultWebView];
192 } else if (resultTabXslfoIsVisible) {
193 [self updateResultImageView];
194 [pdfCurrentPageField setIntValue: (pdfPageCount ? (pdfCurrentPage + 1) : 0)];
195 [pdfPageCountField setIntValue:pdfPageCount];
197 [pdfPreviousPageButton setEnabled:pdfCurrentPage > 0];
198 [pdfNextPageButton setEnabled:pdfCurrentPage < (pdfPageCount - 1)];
199 [pdfSaveAsButton setEnabled:(pdfPageCount > 0)];
200 // } else if (resultTabTextIsVisible) {
206 [processButton setEnabled:[self canProcessNow]];
208 // move this to xmlview.
209 // [self updateWellFormedIcons];
213 [resultView setString:[workset stringResult]];
218 - (void)updateResultWebView {
219 if (!webViewUpToDate) {
220 WebFrame *mainFrame = [resultWebView mainFrame];
221 // [mainFrame loadHTMLString:[workset stringResult] baseURL:nil];
222 [mainFrame loadHTMLString:[workset stringResult] baseURL:[NSURL URLWithString:[webViewBaseURL stringValue]]];
223 // [mainFrame loadHTMLString:[workset stringResult] baseURL:[NSURL URLWithString:@"file:///Users/liyanage/Sites/primavera/images/x"]];
224 webViewUpToDate = YES;
229 - (void)updateResultImageView {
230 if (!imageViewUpToDate) {
231 [self renderFo:self];
232 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];
307 return [super validateMenuItem:menuItem];
311 - (IBAction)showInBrowser:(id)sender {
318 - (void)updateCompleteUI {
320 [xmlView setString:[workset xmlCode]];
321 [xsltView setString:[workset xsltCode]];
326 - (void)textDidChange:(NSNotification *)aNotification {
328 id sender = [aNotification object];
330 if ([sender isEqual:xmlView]) {
331 [workset setXmlCode:[xmlView string]];
333 } else if ([sender isEqual:xsltView]) {
334 [workset setXsltCode:[xsltView string]];
338 [self updateChangeCount:NSChangeDone];
345 - (NSTabView *)tabView {
351 - (BOOL)canJumpToLineNow {
353 NSTextView *view = [self currentTextView];
355 return (view == xmlView) || (view == xsltView);
360 - (IBAction)showJumpToLinePanel:(id)sender {
362 [NSApp beginSheet:[jumpToLinePanelController window]
363 modalForWindow:[[[self windowControllers] objectAtIndex:0] window]
368 [NSApp runModalForWindow:[jumpToLinePanelController window]];
369 [NSApp endSheet:[jumpToLinePanelController window]];
370 [[jumpToLinePanelController window] orderOut:self];
372 if ([jumpToLinePanelController lineNumber] == 0) {
376 [((XMLTextView *)[self currentTextView]) selectLineByNumber:[jumpToLinePanelController lineNumber]];
378 // NSLog(@"jump to line: %d", [jumpToLinePanelController lineNumber]);
383 - (IBAction)showFindPanel:(id)sender {
385 [findPanelController refresh];
387 [NSApp beginSheet:[findPanelController window]
388 modalForWindow:[[[self windowControllers] objectAtIndex:0] window]
393 [NSApp runModalForWindow:[findPanelController window]];
394 [NSApp endSheet:[findPanelController window]];
395 [[findPanelController window] orderOut:self];
397 if ([findPanelController aborted]) {
401 [self findStringWithSearchFlags:[findPanelController searchFlags]];
408 - (IBAction)findNext:(id)sender {
410 [self findStringWithSearchFlags:[findPanelController searchFlags] & NSCaseInsensitiveSearch];
415 - (IBAction)findPrevious:(id)sender {
417 [self findStringWithSearchFlags:([findPanelController searchFlags] | NSBackwardsSearch)];
421 - (BOOL)canUseSelectionForFindNow {
423 NSTextView *view = [self currentTextView];
424 NSRange selectedRange;
430 selectedRange = [view selectedRange];
432 if (selectedRange.length < 1) {
442 - (IBAction)useSelectionForFind:(id)sender {
445 NSTextView *view = [self currentTextView];
447 text = [[view string] substringWithRange:[view selectedRange]];
449 [findPanelController setFindString:text];
458 NSString *currentTabViewItem = [[[self tabView] selectedTabViewItem] identifier];
460 if ([currentTabViewItem isEqualToString:@"xmlTab"]
461 || [currentTabViewItem isEqualToString:@"xsltTab"]
462 || [currentTabViewItem isEqualToString:@"resultTab"]) {
470 - (BOOL)canFindAgainNow {
472 return ([findPanelController findString] != nil) && [self canFindNow];
477 - (void)findStringWithSearchFlags:(int)flags {
479 NSTextView *currentView;
482 NSRange selectedRange, leftRange, rightRange, resultRange, searchRange;
484 NSPasteboard *findBoard = [NSPasteboard pasteboardWithName:NSFindPboard];
486 string = [findBoard stringForType:NSStringPboardType];
488 currentView = [self currentTextView];
489 if (currentView == nil) {
493 text = [currentView string];
495 selectedRange = [currentView selectedRange];
496 leftRange = NSMakeRange(0, selectedRange.location);
497 rightRange = NSMakeRange(NSMaxRange(selectedRange), [text length] - NSMaxRange(selectedRange));
499 if (flags & NSBackwardsSearch) {
500 searchRange = leftRange;
502 searchRange = rightRange;
505 resultRange = [text rangeOfString:string options:flags range:searchRange];
507 if (resultRange.location == NSNotFound) {
512 [currentView setSelectedRange:resultRange];
513 [currentView scrollRangeToVisible:resultRange];
520 - (NSTextView *)currentTextView {
522 NSString *currentTabViewItem = [[[self tabView] selectedTabViewItem] identifier];
524 if ([currentTabViewItem isEqualToString:@"xmlTab"]) {
526 } else if ([currentTabViewItem isEqualToString:@"xsltTab"]) {
528 } else if ([currentTabViewItem isEqualToString:@"resultTab"]) {
540 - (IBAction)process:(id)sender {
543 const char **params = [[workset parameterSet] cArray];
545 struct timeval tstart, tend;
546 gettimeofday(&tstart, NULL);
550 if ([workset hasXsltFilename]) {
551 [processor setBaseUri:[NSString stringWithFormat:@"file://%@", [workset xsltFilename]]];
554 if (![processor processStrings:[XMLUtils getDataWithEncodingFromString:[workset xmlCode]] withXslt:[XMLUtils getDataWithEncodingFromString:[workset xsltCode]] andParameters:params]) {
556 [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"];
559 [errorDrawer openOnEdge:NSMinYEdge];
560 [self showErrorLocation:nil];
564 gettimeofday(&tend, NULL);
566 processingTime = ((tend.tv_sec * 1000000 + tend.tv_usec) - (tstart.tv_sec * 1000000 + tstart.tv_usec)) / 1000;
568 [workset setResult:[processor result]];
569 [workset setResultEncoding:[processor resultEncoding]];
572 // [errorDrawer close];
573 [self selectTabById:RESULT];
574 [processingTimeField setStringValue:[NSString stringWithFormat:@"Time: %ldms", processingTime]];
577 webViewUpToDate = NO;
578 imageViewUpToDate = NO;
586 if (resultDirty && [autoSaveCheckbox state] == NSOnState) {
587 [self saveResult:nil];
594 if ([autoShowCheckbox state] == NSOnState) {
595 [self openResultURL:nil];
601 - (IBAction)loadXml:(id)sender {
603 NSOpenPanel *panel = [NSOpenPanel openPanel];
605 if ([panel runModalForDirectory:nil file:nil types:nil] == NSOKButton) {
607 // NSLog(@"choosen: %@", [[panel filenames] objectAtIndex:0]);
609 [workset setXmlCode:[XMLUtils getStringWithEncodingFromFile:[[panel filenames] objectAtIndex:0]]];
610 [workset setXmlFilename:[[panel filenames] objectAtIndex:0]];
611 [self updateChangeCount:NSChangeDone];
612 [self updateCompleteUI];
620 - (IBAction)loadXslt:(id)sender {
622 NSOpenPanel *panel = [NSOpenPanel openPanel];
624 if ([panel runModalForDirectory:nil file:nil types:nil] == NSOKButton) {
626 // NSLog(@"choosen: %@", [[panel filenames] objectAtIndex:0]);
628 [workset setXsltCode:[XMLUtils getStringWithEncodingFromFile:[[panel filenames] objectAtIndex:0]]];
629 [workset setXsltFilename:[[panel filenames] objectAtIndex:0]];
630 [self updateChangeCount:NSChangeDone];
631 [self updateCompleteUI];
639 - (BOOL)canSaveXmlAsNow {
640 return [workset hasXmlCode];
643 - (BOOL)canSaveXmlNow {
644 return [workset hasXmlFilename] && xmlDirty;
647 - (BOOL)canSaveXsltAsNow {
648 return [workset hasXsltCode];
651 - (BOOL)canSaveXsltNow {
652 return [workset hasXsltFilename] && xsltDirty;
655 - (BOOL)canSaveResultAsNow {
656 return [workset hasResult];
659 - (BOOL)canSaveResultNow {
660 return [workset hasResultFilename] && resultDirty;
666 - (IBAction)saveXmlAs:(id)sender {
668 NSSavePanel *panel = [NSSavePanel savePanel];
670 if ([panel runModal] == NSFileHandlingPanelOKButton) {
672 [workset setXmlFilename:[panel filename]];
680 - (IBAction)saveXml:(id)sender {
683 if ([workset hasXmlFilename]) {
692 - (IBAction)saveXsltAs:(id)sender {
694 NSSavePanel *panel = [NSSavePanel savePanel];
696 if ([panel runModal] == NSFileHandlingPanelOKButton) {
698 [workset setXsltFilename:[panel filename]];
706 - (IBAction)saveXslt:(id)sender {
708 if ([workset hasXsltFilename]) {
718 - (IBAction)saveResultAs:(id)sender {
720 NSSavePanel *panel = [NSSavePanel savePanel];
722 if ([panel runModal] == NSFileHandlingPanelOKButton) {
724 [workset setResultFilename:[panel filename]];
726 [self saveResult:nil];
731 - (IBAction)saveResult:(id)sender {
733 if ([workset hasResultFilename]) {
735 [[workset result] writeToFile:[workset resultFilename] atomically:NO];
746 - (IBAction)saveCurrentAs:(id)sender {
748 NSString *activeTabIdentifier = [[tabView selectedTabViewItem] identifier];
749 BOOL xmlTabIsVisible = [activeTabIdentifier isEqualToString:@"xmlTab"];
750 BOOL xsltTabIsVisible = !xmlTabIsVisible && [activeTabIdentifier isEqualToString:@"xsltTab"];
751 BOOL paramTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible) && [activeTabIdentifier isEqualToString:@"parametersTab"];
752 BOOL resultTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible || paramTabIsVisible);
754 if (xmlTabIsVisible) {
755 [self saveXmlAs:sender];
756 } else if (xsltTabIsVisible) {
757 [self saveXsltAs:sender];
758 } else if (resultTabIsVisible) {
759 [self saveResultAs:sender];
767 - (IBAction)saveCurrent:(id)sender {
769 NSString *activeTabIdentifier = [[tabView selectedTabViewItem] identifier];
770 BOOL xmlTabIsVisible = [activeTabIdentifier isEqualToString:@"xmlTab"];
771 BOOL xsltTabIsVisible = !xmlTabIsVisible && [activeTabIdentifier isEqualToString:@"xsltTab"];
772 BOOL paramTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible) && [activeTabIdentifier isEqualToString:@"parametersTab"];
773 BOOL resultTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible || paramTabIsVisible);
775 if (xmlTabIsVisible) {
776 [self saveXml:sender];
777 } else if (xsltTabIsVisible) {
778 [self saveXslt:sender];
779 } else if (resultTabIsVisible) {
780 [self saveResult:sender];
790 - (IBAction)openResultURL:(id)sender {
792 // NSLog(@"openResultURL running...");
794 if ([workset hasResultFilename]) {
796 [[NSWorkspace sharedWorkspace] openURL:[NSURL fileURLWithPath:[workset resultFilename]]];
802 - (IBAction)newParameter:(id)sender {
804 [[workset parameterSet] addParameter:@"name" withValue:@"value"];
809 - (IBAction)removeParameter:(id)sender {
811 int row = [parameterTable selectedRow];
814 [[workset parameterSet] removeParameterAtIndex:row];
822 - (int)numberOfRowsInTableView:(NSTableView *)aTableView {
823 return [[workset parameterSet] count];
826 - (id)tableView:(NSTableView *)aTableView
827 objectValueForTableColumn:(NSTableColumn *)aTableColumn
830 return [[workset parameterSet] getField:[aTableColumn identifier] atIndex:rowIndex];
835 - (void)tableView:(NSTableView *)aTableView
836 setObjectValue:(id)anObject
837 forTableColumn:(NSTableColumn *)aTableColumn
840 [[workset parameterSet] setField:[aTableColumn identifier] atIndex:rowIndex toString:anObject];
846 - (IBAction)setProcessorType:(id)sender {
848 int newType = [sender tag];
850 if ([processor processorType] == newType) {
854 [self switchProcessorToType:newType updateUI:NO];
859 - (IBAction)switchProcessorToType:(int)newType updateUI:(BOOL)updateUI {
861 XSLTProcessor *newProcessor = nil;
863 newProcessor = [XSLTProcessorFactory makeProcessorOfType:newType];
866 NSLog(@"Unable to create new processor of type '%d'", newType);
870 processor = newProcessor;
873 [processorTypePopUp selectItemAtIndex:[processorTypePopUp indexOfItemWithTag:newType]];
881 - (id)handleProcessScriptCommand:(NSScriptCommand *)command {
883 if ([self canProcessNow]) {
892 - (id)handleExportScriptCommand:(NSScriptCommand *)command {
894 NSDictionary *args = [command evaluatedArguments];
895 NSString *file = [args objectForKey:@"File"];
901 [workset setResultFilename:file];
903 [self saveResult:nil];
910 - (id)handleSetParamScriptCommand:(NSScriptCommand *)command {
912 NSDictionary *args = [command evaluatedArguments];
913 NSString *paramName = [args objectForKey:@"Name"];
914 NSString *paramValue = [args objectForKey:@"Value"];
916 [[workset parameterSet] removeParameterByName:paramName];
918 [[workset parameterSet] addParameter:paramName withValue:paramValue];
925 - (id)handleClearParamScriptCommand:(NSScriptCommand *)command {
927 NSDictionary *args = [command evaluatedArguments];
928 NSString *paramName = [args objectForKey:@"Name"];
930 [[workset parameterSet] removeParameterByName:paramName];
935 - (id)handleSetProcessorTypeScriptCommand:(NSScriptCommand *)command {
937 NSDictionary *args = [command evaluatedArguments];
938 NSString *processorType = [args objectForKey:@"Name"];
940 if ([processorType caseInsensitiveCompare:@"libxslt"] == NSOrderedSame) {
942 [self switchProcessorToType:PROCESSORTYPE_LIBXSLT updateUI:YES];
944 } else if ([processorType caseInsensitiveCompare:@"sablotron"] == NSOrderedSame) {
946 [self switchProcessorToType:PROCESSORTYPE_SABLOTRON updateUI:YES];
948 } else if ([processorType caseInsensitiveCompare:@"saxon"] == NSOrderedSame) {
950 [self switchProcessorToType:PROCESSORTYPE_SAXON updateUI:YES];
952 } else if ([processorType caseInsensitiveCompare:@"xalan-j"] == NSOrderedSame) {
954 [self switchProcessorToType:PROCESSORTYPE_XALAN_J updateUI:YES];
957 NSLog(@"unknown processor");
965 - (BOOL)handleDroppedFile:(NSString *)filename forTextView:(NSTextView *)sender {
967 NSString *fileContents = [XMLUtils getStringWithEncodingFromFile:filename];
969 if ([sender isEqual: xmlView]) {
971 [self setXmlcode:fileContents];
972 [workset setXmlFilename:filename];
974 } else if ([sender isEqual:xsltView]) {
976 [self setXsltcode:fileContents];
977 [workset setXsltFilename:filename];
981 NSLog(@"Unknown sender view");
993 - (NSString *)xmlcode {
994 return [workset xmlCode];
997 - (void)setXmlcode:(NSString *)s {
999 NSString *currentContents = [[[NSString alloc] initWithString:[self xmlcode]] autorelease];
1001 [[self undoManager] registerUndoWithTarget:self
1002 selector:@selector(setXmlcode:)
1003 object:currentContents];
1005 [workset setXmlCode:s];
1006 [self updateCompleteUI];
1011 - (NSString *)xsltcode {
1012 return [workset xsltCode];
1015 - (void)setXsltcode:(NSString *)s {
1017 NSString *currentContents = [[[NSString alloc] initWithString:[self xsltcode]] autorelease];
1019 [[self undoManager] registerUndoWithTarget:self
1020 selector:@selector(setXsltcode:)
1021 object:currentContents];
1023 [workset setXsltCode:s];
1024 [self updateCompleteUI];
1028 - (NSString *)result {
1029 return [workset stringResult];
1034 - (void)tableViewSelectionDidChange:(NSNotification *)notification {
1039 - (void)checkForExternalModifications {
1043 if ([workset xmlModifiedExternally] && xmlDirty || [workset xsltModifiedExternally] && xsltDirty) {
1045 /* external changes conflicting with local changes detected.
1046 * Ask the user if we should keep the local unsaved changes
1048 keep = [self showUnsavedChangesPanel];
1052 if ([workset xmlModifiedExternally] && !(xmlDirty && keep)) {
1053 [workset reloadXmlFromFile];
1054 [self updateChangeCount:NSChangeDone];
1055 [self updateCompleteUI];
1059 if ([workset xsltModifiedExternally] && !(xsltDirty && keep)) {
1060 [workset reloadXsltFromFile];
1061 [self updateChangeCount:NSChangeDone];
1062 [self updateCompleteUI];
1071 - (BOOL)showUnsavedChangesPanel {
1073 [NSApp beginSheet:[unsavedChangesPanelController window]
1074 modalForWindow:[[[self windowControllers] objectAtIndex:0] window]
1079 [NSApp runModalForWindow:[unsavedChangesPanelController window]];
1080 [NSApp endSheet:[unsavedChangesPanelController window]];
1081 [[unsavedChangesPanelController window] orderOut:self];
1083 return ([unsavedChangesPanelController keepChanges]);
1087 - (void)xslfoRenderThread {
1089 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1091 XSL_FO_Renderer *xfr = [[[XSL_FO_Renderer alloc] init] autorelease];
1092 xslfoRendererResultData = [xfr render:[workset result]];
1095 [xslfoRendererLock unlockWithCondition:2];
1100 - (IBAction)renderFo:(id)sender {
1102 xslfoRendererLock = [[[NSConditionLock alloc] initWithCondition:1] autorelease];
1103 [NSThread detachNewThreadSelector:@selector(xslfoRenderThread) toTarget:self withObject:nil];
1104 [xslfoRendererLock lockWhenCondition:2];
1105 [xslfoRendererLock unlock];
1107 if (!xslfoRendererResultData) {
1108 NSLog(@"Unable to render, NULL result");
1112 [xslfoRendererResultData retain];
1114 pdfData = xslfoRendererResultData;
1116 NSImage *pdfImage = [[[NSImage alloc] initWithData:xslfoRendererResultData] autorelease];
1117 [pdfImage setBackgroundColor:[NSColor whiteColor]];
1119 [pdfImage setCacheMode:NSImageCacheNever];
1121 NSClipView *clipView = (NSClipView *)[resultImageView superview];
1122 NSScrollView *scrollView = (NSScrollView *)[clipView superview];
1124 [resultImageView setImage:pdfImage];
1125 [resultImageView setFrameSize:[pdfImage size]];
1126 [resultImageView display];
1128 [clipView scrollToPoint:NSMakePoint([resultImageView frame].origin.x, [resultImageView frame].size.height - [clipView frame].size.height + [resultImageView frame].origin.y)];
1129 [scrollView reflectScrolledClipView:clipView];
1131 pdfPageCount = [[[pdfImage representations] objectAtIndex:0] pageCount];
1137 - (IBAction)pdfPreviousPage:(id)sender {
1139 if (pdfCurrentPage > 0) {
1141 [[[[resultImageView image] representations] objectAtIndex:0] setCurrentPage:pdfCurrentPage];
1142 [resultImageView setNeedsDisplay:YES];
1148 - (IBAction)pdfNextPage:(id)sender {
1150 if (pdfCurrentPage < (pdfPageCount - 1)) {
1152 [[[[resultImageView image] representations] objectAtIndex:0] setCurrentPage:pdfCurrentPage];
1153 [resultImageView setNeedsDisplay:YES];
1160 - (IBAction)pdfSaveAs:(id)sender {
1162 NSSavePanel *panel = [NSSavePanel savePanel];
1164 if ([panel runModal] == NSFileHandlingPanelOKButton) {
1166 [pdfData writeToFile:[panel filename] atomically:YES];
1175 - (void)windowDidBecomeMain:(NSNotification *)aNotification {
1177 [self checkForExternalModifications];
1181 - (void)windowDidResize:(NSNotification *)aNotification {
1183 [self resizeWebView];
1187 - (void)resizeWebView {
1189 // [[[resultWebView mainFrame] frameView] setFrame:[resultWebView frame]];
1190 [resultWebView setNeedsDisplay:YES];
1198 - (NSString *)windowNibName
1200 // Override returning the nib file name of the document
1201 // 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.
1202 return @"MyDocument";
1205 - (void)windowControllerDidLoadNib:(NSWindowController *) aController
1210 NSSize errorDrawerSize;
1212 [super windowControllerDidLoadNib:aController];
1214 [resultImageView setImageFrameStyle:NSImageFramePhoto];
1215 [resultImageView setImageScaling:NSScaleNone];
1216 [resultImageView setImageAlignment:NSImageAlignCenter];
1217 [resultImageView setEditable:NO];
1219 [resultWebView setTextSizeMultiplier:0.9];
1221 warningIcon = [xmlWellFormedIcon image];
1223 [self updateCompleteUI];
1225 errorDrawerSize = [errorDrawer contentSize];
1226 errorDrawerSize.height = 130;
1227 [errorDrawer setContentSize:errorDrawerSize];
1229 NSFont *computerFont = [NSFont fontWithName:@"Courier" size:12.0];
1230 [resultView setFont:computerFont];
1232 [tabView registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]];
1236 if (findPanelController == nil) {
1237 findPanelController = [[FindPanelController alloc] initWithWindowNibName:@"FindPanel"];
1238 // NSLog(@"init find panel controller: %@", findPanelController);
1241 if (jumpToLinePanelController == nil) {
1242 jumpToLinePanelController = [[JumpToLinePanelController alloc] initWithWindowNibName:@"JumpToLine"];
1243 // NSLog(@"init jump to line panel controller: %@", jumpToLinePanelController);
1246 if (unsavedChangesPanelController == nil) {
1247 unsavedChangesPanelController = [[UnsavedChangesPanelController alloc] initWithWindowNibName:@"UnsavedChanges"];
1248 // NSLog(@"init unsaved changes panel controller: %@", unsavedChangesPanelController);
1254 - (void)canCloseDocumentWithDelegate:(id)delegate shouldCloseSelector:(SEL)shouldCloseSelector contextInfo:(void *)contextInfo {
1256 [uiUpdateTimer invalidate];
1257 [super canCloseDocumentWithDelegate:delegate shouldCloseSelector:shouldCloseSelector contextInfo:contextInfo];
1267 - (IBAction)showErrorLocation:(id)sender {
1269 XMLTextView *textView;
1272 if ([processor errorSource] == XSLT_ERROR_SOURCE_XML) {
1273 [self selectTabById:XML];
1276 [self selectTabById:XSLT];
1277 textView = xsltView;
1280 errorLine = [processor errorLine];
1282 [textView selectLineByNumber:errorLine];
1286 - (NSData *)dataRepresentationOfType:(NSString *)aType
1288 // Insert code here to write your document from the given data. You can also choose to override -fileWrapperRepresentationOfType: or -writeToFile:ofType: instead.
1289 return [NSArchiver archivedDataWithRootObject:workset];
1292 - (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType
1294 // Insert code here to read your document from the given data. You can also choose to override -loadFileWrapperRepresentation:ofType: or -readFromFile:ofType: instead.
1297 workset = [[NSUnarchiver unarchiveObjectWithData:data] retain];
1298 [self updateCompleteUI];