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];
48 - (IBAction)selectTab:(id)sender {
50 [self selectTabById:[sender tag]];
55 - (IBAction)selectTabById:(int)tabId {
70 tabName = @"parametersTab";
75 tabName = @"resultTab";
80 [tabView selectTabViewItemWithIdentifier:tabName];
85 - (void)textViewDidChangeSelection:(NSNotification *)aNotification {
90 - (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem {
92 [[self undoManager] removeAllActions];
100 // NSLog(@"updateUI running...");
102 [uiUpdateTimer invalidate];
103 [uiUpdateTimer release];
105 uiUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(uiUpdateTimerTarget:) userInfo:nil repeats:NO];
107 [uiUpdateTimer retain];
113 - (void)uiUpdateTimerTarget:(NSTimer *)timer {
123 NSString *activeTabIdentifier = [[tabView selectedTabViewItem] identifier];
124 NSString *activeResultTabIdentifier = [[resultTabView selectedTabViewItem] identifier];
126 BOOL xmlTabIsVisible = [activeTabIdentifier isEqualToString:@"xmlTab"];
127 BOOL xsltTabIsVisible = !xmlTabIsVisible && [activeTabIdentifier isEqualToString:@"xsltTab"];
128 BOOL paramTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible) && [activeTabIdentifier isEqualToString:@"parametersTab"];
129 BOOL resultTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible || paramTabIsVisible);
130 BOOL resultTabHtmlIsVisible = resultTabIsVisible && [activeResultTabIdentifier isEqualToString:@"htmlResult"];
131 BOOL resultTabXslfoIsVisible = resultTabIsVisible && !resultTabHtmlIsVisible && [activeResultTabIdentifier isEqualToString:@"xslfoResult"];
132 BOOL resultTabTextIsVisible = resultTabIsVisible && !(resultTabHtmlIsVisible || resultTabXslfoIsVisible);
134 // NSLog(@"xml: %d, xslt: %d, param: %d, result: %d, reshtml: %d, resxslfo: %d, restext: %d", xmlTabIsVisible, xsltTabIsVisible, paramTabIsVisible, resultTabIsVisible, resultTabHtmlIsVisible, resultTabXslfoIsVisible, resultTabTextIsVisible);
136 if (xmlTabIsVisible) {
137 [saveXmlFilenameField setObjectValue:[workset xmlFilename]];
138 [saveXmlFilenameField setToolTip:[workset xmlFilename]];
139 [saveXmlButton setEnabled:[self canSaveXmlNow]];
140 [saveXmlAsButton setEnabled:[self canSaveXmlAsNow]];
141 [xmlTagStackField setStringValue:[xmlView calculateTagStack]];
143 if ([defaults boolForKey:@"enableWellformedCheck"]) {
144 [xmlView checkWellFormed];
145 if ([workset hasXmlCode] && [xmlView hasError]) {
146 [xmlWellFormedIcon setImage:warningIcon];
147 [xmlWellFormedIcon setToolTip:[xmlView valueForKey:@"errorString"]];
148 [self setValue:[xmlView valueForKey:@"errorString"] forKey:@"drawerMessage"];
150 [xmlWellFormedIcon setImage:nil];
151 [xmlWellFormedIcon setToolTip:nil];
152 [self setValue:nil forKey:@"drawerMessage"];
156 } else if (xsltTabIsVisible) {
157 [saveXsltFilenameField setObjectValue:[workset xsltFilename]];
158 [saveXsltFilenameField setToolTip:[workset xsltFilename]];
159 [saveXsltButton setEnabled:[self canSaveXsltNow]];
160 [saveXsltAsButton setEnabled:[self canSaveXsltAsNow]];
161 [xsltTagStackField setStringValue:[xsltView calculateTagStack]];
163 if ([defaults boolForKey:@"enableWellformedCheck"]) {
164 [xsltView checkWellFormed];
165 if ([workset hasXsltCode] && [xsltView hasError]) {
166 [xsltWellFormedIcon setImage:warningIcon];
167 [xsltWellFormedIcon setToolTip:[xsltView valueForKey:@"errorString"]];
168 [self setValue:[xsltView valueForKey:@"errorString"] forKey:@"drawerMessage"];
170 [xsltWellFormedIcon setImage:nil];
171 [xsltWellFormedIcon setToolTip:nil];
172 [self setValue:nil forKey:@"drawerMessage"];
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;
236 - (BOOL)canProcessNow {
238 return [workset hasXmlCode] && [workset hasXsltCode];
242 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
244 // NSLog(@"validate: %@, tag: %d", menuItem, [menuItem tag]);
246 NSString *activeTabIdentifier = [[tabView selectedTabViewItem] identifier];
247 BOOL xmlTabIsVisible = [activeTabIdentifier isEqualToString:@"xmlTab"];
248 BOOL xsltTabIsVisible = !xmlTabIsVisible && [activeTabIdentifier isEqualToString:@"xsltTab"];
249 BOOL paramTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible) && [activeTabIdentifier isEqualToString:@"parametersTab"];
250 BOOL resultTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible || paramTabIsVisible);
253 switch ([menuItem tag]) {
256 return [self canProcessNow];
260 return [workset hasResultFilename];
264 return [self canFindNow];
267 case 13: // Find Next
268 case 14: // Find Previous
269 return [self canFindAgainNow];
272 case 15: // Use Selection for Find
273 return [self canUseSelectionForFindNow];
276 case 16: // Jump to Line
277 return [self canJumpToLineNow];
280 case 17: // Save Current Pane
281 if (xmlTabIsVisible) {
282 return [self canSaveXmlNow];
283 } else if (xsltTabIsVisible) {
284 return [self canSaveXsltNow];
285 } else if (resultTabIsVisible) {
286 return [self canSaveResultNow];
290 case 18: // Save Current Pane As...
291 if (xmlTabIsVisible) {
292 return [self canSaveXmlAsNow];
293 } else if (xsltTabIsVisible) {
294 return [self canSaveXsltAsNow];
295 } else if (resultTabIsVisible) {
296 return [self canSaveResultAsNow];
309 - (IBAction)showInBrowser:(id)sender {
316 - (void)updateCompleteUI {
318 [xmlView setString:[workset xmlCode]];
319 [xsltView setString:[workset xsltCode]];
324 - (void)textDidChange:(NSNotification *)aNotification {
326 id sender = [aNotification object];
328 if ([sender isEqual:xmlView]) {
329 [workset setXmlCode:[xmlView string]];
331 } else if ([sender isEqual:xsltView]) {
332 [workset setXsltCode:[xsltView string]];
336 [self updateChangeCount:NSChangeDone];
343 - (NSTabView *)tabView {
349 - (BOOL)canJumpToLineNow {
351 NSTextView *view = [self currentTextView];
353 return (view == xmlView) || (view == xsltView);
358 - (IBAction)showJumpToLinePanel:(id)sender {
360 [NSApp beginSheet:[jumpToLinePanelController window]
361 modalForWindow:[[[self windowControllers] objectAtIndex:0] window]
366 [NSApp runModalForWindow:[jumpToLinePanelController window]];
367 [NSApp endSheet:[jumpToLinePanelController window]];
368 [[jumpToLinePanelController window] orderOut:self];
370 if ([jumpToLinePanelController lineNumber] == 0) {
374 [((XMLTextView *)[self currentTextView]) selectLineByNumber:[jumpToLinePanelController lineNumber]];
376 // NSLog(@"jump to line: %d", [jumpToLinePanelController lineNumber]);
381 - (IBAction)showFindPanel:(id)sender {
383 [findPanelController refresh];
385 [NSApp beginSheet:[findPanelController window]
386 modalForWindow:[[[self windowControllers] objectAtIndex:0] window]
391 [NSApp runModalForWindow:[findPanelController window]];
392 [NSApp endSheet:[findPanelController window]];
393 [[findPanelController window] orderOut:self];
395 if ([findPanelController aborted]) {
399 [self findStringWithSearchFlags:[findPanelController searchFlags]];
406 - (IBAction)findNext:(id)sender {
408 [self findStringWithSearchFlags:[findPanelController searchFlags] & NSCaseInsensitiveSearch];
413 - (IBAction)findPrevious:(id)sender {
415 [self findStringWithSearchFlags:([findPanelController searchFlags] | NSBackwardsSearch)];
419 - (BOOL)canUseSelectionForFindNow {
421 NSTextView *view = [self currentTextView];
422 NSRange selectedRange;
428 selectedRange = [view selectedRange];
430 if (selectedRange.length < 1) {
440 - (IBAction)useSelectionForFind:(id)sender {
443 NSTextView *view = [self currentTextView];
445 text = [[view string] substringWithRange:[view selectedRange]];
447 [findPanelController setFindString:text];
456 NSString *currentTabViewItem = [[[self tabView] selectedTabViewItem] identifier];
458 if ([currentTabViewItem isEqualToString:@"xmlTab"]
459 || [currentTabViewItem isEqualToString:@"xsltTab"]
460 || [currentTabViewItem isEqualToString:@"resultTab"]) {
468 - (BOOL)canFindAgainNow {
470 return ([findPanelController findString] != nil) && [self canFindNow];
475 - (void)findStringWithSearchFlags:(int)flags {
477 NSTextView *currentView;
480 NSRange selectedRange, leftRange, rightRange, resultRange, searchRange;
482 NSPasteboard *findBoard = [NSPasteboard pasteboardWithName:NSFindPboard];
484 string = [findBoard stringForType:NSStringPboardType];
486 currentView = [self currentTextView];
487 if (currentView == nil) {
491 text = [currentView string];
493 selectedRange = [currentView selectedRange];
494 leftRange = NSMakeRange(0, selectedRange.location);
495 rightRange = NSMakeRange(NSMaxRange(selectedRange), [text length] - NSMaxRange(selectedRange));
497 if (flags & NSBackwardsSearch) {
498 searchRange = leftRange;
500 searchRange = rightRange;
503 resultRange = [text rangeOfString:string options:flags range:searchRange];
505 if (resultRange.location == NSNotFound) {
510 [currentView setSelectedRange:resultRange];
511 [currentView scrollRangeToVisible:resultRange];
518 - (NSTextView *)currentTextView {
520 NSString *currentTabViewItem = [[[self tabView] selectedTabViewItem] identifier];
522 if ([currentTabViewItem isEqualToString:@"xmlTab"]) {
524 } else if ([currentTabViewItem isEqualToString:@"xsltTab"]) {
526 } else if ([currentTabViewItem isEqualToString:@"resultTab"]) {
538 - (IBAction)process:(id)sender {
541 const char **params = [[workset parameterSet] cArray];
543 struct timeval tstart, tend;
544 gettimeofday(&tstart, NULL);
548 if ([workset hasXsltFilename]) {
549 [processor setBaseUri:[NSString stringWithFormat:@"file://%@", [workset xsltFilename]]];
552 if (![processor processStrings:[XMLUtils getDataWithEncodingFromString:[workset xmlCode]] withXslt:[XMLUtils getDataWithEncodingFromString:[workset xsltCode]] andParameters:params]) {
554 [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"];
557 [errorDrawer openOnEdge:NSMinYEdge];
558 [self showErrorLocation:nil];
562 gettimeofday(&tend, NULL);
564 processingTime = ((tend.tv_sec * 1000000 + tend.tv_usec) - (tstart.tv_sec * 1000000 + tstart.tv_usec)) / 1000;
566 [workset setResult:[processor result]];
567 [workset setResultEncoding:[processor resultEncoding]];
570 // [errorDrawer close];
571 [self selectTabById:RESULT];
572 [processingTimeField setStringValue:[NSString stringWithFormat:@"Time: %ldms", processingTime]];
575 webViewUpToDate = NO;
576 imageViewUpToDate = NO;
584 if (resultDirty && [autoSaveCheckbox state] == NSOnState) {
585 [self saveResult:nil];
592 if ([autoShowCheckbox state] == NSOnState) {
593 [self openResultURL:nil];
599 - (IBAction)loadXml:(id)sender {
601 NSOpenPanel *panel = [NSOpenPanel openPanel];
603 if ([panel runModalForDirectory:nil file:nil types:nil] == NSOKButton) {
605 // NSLog(@"choosen: %@", [[panel filenames] objectAtIndex:0]);
607 [workset setXmlCode:[XMLUtils getStringWithEncodingFromFile:[[panel filenames] objectAtIndex:0]]];
608 [workset setXmlFilename:[[panel filenames] objectAtIndex:0]];
609 [self updateChangeCount:NSChangeDone];
610 [self updateCompleteUI];
618 - (IBAction)loadXslt:(id)sender {
620 NSOpenPanel *panel = [NSOpenPanel openPanel];
622 if ([panel runModalForDirectory:nil file:nil types:nil] == NSOKButton) {
624 // NSLog(@"choosen: %@", [[panel filenames] objectAtIndex:0]);
626 [workset setXsltCode:[XMLUtils getStringWithEncodingFromFile:[[panel filenames] objectAtIndex:0]]];
627 [workset setXsltFilename:[[panel filenames] objectAtIndex:0]];
628 [self updateChangeCount:NSChangeDone];
629 [self updateCompleteUI];
637 - (BOOL)canSaveXmlAsNow {
638 return [workset hasXmlCode];
641 - (BOOL)canSaveXmlNow {
642 return [workset hasXmlFilename] && xmlDirty;
645 - (BOOL)canSaveXsltAsNow {
646 return [workset hasXsltCode];
649 - (BOOL)canSaveXsltNow {
650 return [workset hasXsltFilename] && xsltDirty;
653 - (BOOL)canSaveResultAsNow {
654 return [workset hasResult];
657 - (BOOL)canSaveResultNow {
658 return [workset hasResultFilename] && resultDirty;
664 - (IBAction)saveXmlAs:(id)sender {
666 NSSavePanel *panel = [NSSavePanel savePanel];
668 if ([panel runModal] == NSFileHandlingPanelOKButton) {
670 [workset setXmlFilename:[panel filename]];
678 - (IBAction)saveXml:(id)sender {
681 if ([workset hasXmlFilename]) {
690 - (IBAction)saveXsltAs:(id)sender {
692 NSSavePanel *panel = [NSSavePanel savePanel];
694 if ([panel runModal] == NSFileHandlingPanelOKButton) {
696 [workset setXsltFilename:[panel filename]];
704 - (IBAction)saveXslt:(id)sender {
706 if ([workset hasXsltFilename]) {
716 - (IBAction)saveResultAs:(id)sender {
718 NSSavePanel *panel = [NSSavePanel savePanel];
720 if ([panel runModal] == NSFileHandlingPanelOKButton) {
722 [workset setResultFilename:[panel filename]];
724 [self saveResult:nil];
729 - (IBAction)saveResult:(id)sender {
731 if ([workset hasResultFilename]) {
733 [[workset result] writeToFile:[workset resultFilename] atomically:NO];
744 - (IBAction)saveCurrentAs:(id)sender {
746 NSString *activeTabIdentifier = [[tabView selectedTabViewItem] identifier];
747 BOOL xmlTabIsVisible = [activeTabIdentifier isEqualToString:@"xmlTab"];
748 BOOL xsltTabIsVisible = !xmlTabIsVisible && [activeTabIdentifier isEqualToString:@"xsltTab"];
749 BOOL paramTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible) && [activeTabIdentifier isEqualToString:@"parametersTab"];
750 BOOL resultTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible || paramTabIsVisible);
752 if (xmlTabIsVisible) {
753 return [self saveXmlAs:sender];
754 } else if (xsltTabIsVisible) {
755 return [self saveXsltAs:sender];
756 } else if (resultTabIsVisible) {
757 return [self saveResultAs:sender];
765 - (IBAction)saveCurrent:(id)sender {
767 NSString *activeTabIdentifier = [[tabView selectedTabViewItem] identifier];
768 BOOL xmlTabIsVisible = [activeTabIdentifier isEqualToString:@"xmlTab"];
769 BOOL xsltTabIsVisible = !xmlTabIsVisible && [activeTabIdentifier isEqualToString:@"xsltTab"];
770 BOOL paramTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible) && [activeTabIdentifier isEqualToString:@"parametersTab"];
771 BOOL resultTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible || paramTabIsVisible);
773 if (xmlTabIsVisible) {
774 return [self saveXml:sender];
775 } else if (xsltTabIsVisible) {
776 return [self saveXslt:sender];
777 } else if (resultTabIsVisible) {
778 return [self saveResult:sender];
788 - (IBAction)openResultURL:(id)sender {
790 // NSLog(@"openResultURL running...");
792 if ([workset hasResultFilename]) {
794 [[NSWorkspace sharedWorkspace] openURL:[NSURL fileURLWithPath:[workset resultFilename]]];
800 - (IBAction)newParameter:(id)sender {
802 [[workset parameterSet] addParameter:@"name" withValue:@"value"];
807 - (IBAction)removeParameter:(id)sender {
809 int row = [parameterTable selectedRow];
812 [[workset parameterSet] removeParameterAtIndex:row];
820 - (int)numberOfRowsInTableView:(NSTableView *)aTableView {
821 return [[workset parameterSet] count];
824 - (id)tableView:(NSTableView *)aTableView
825 objectValueForTableColumn:(NSTableColumn *)aTableColumn
828 return [[workset parameterSet] getField:[aTableColumn identifier] atIndex:rowIndex];
833 - (void)tableView:(NSTableView *)aTableView
834 setObjectValue:(id)anObject
835 forTableColumn:(NSTableColumn *)aTableColumn
838 [[workset parameterSet] setField:[aTableColumn identifier] atIndex:rowIndex toString:anObject];
844 - (IBAction)setProcessorType:(id)sender {
846 int newType = [sender tag];
848 if ([processor processorType] == newType) {
852 [self switchProcessorToType:newType updateUI:NO];
857 - (IBAction)switchProcessorToType:(int)newType updateUI:(BOOL)updateUI {
859 XSLTProcessor *newProcessor = nil;
861 newProcessor = [XSLTProcessorFactory makeProcessorOfType:newType];
864 NSLog(@"Unable to create new processor of type '%d'", newType);
868 processor = newProcessor;
871 [processorTypePopUp selectItemAtIndex:[processorTypePopUp indexOfItemWithTag:newType]];
879 - (id)handleProcessScriptCommand:(NSScriptCommand *)command {
881 if ([self canProcessNow]) {
890 - (id)handleExportScriptCommand:(NSScriptCommand *)command {
892 NSDictionary *args = [command evaluatedArguments];
893 NSString *file = [args objectForKey:@"File"];
899 [workset setResultFilename:file];
901 [self saveResult:nil];
908 - (id)handleSetParamScriptCommand:(NSScriptCommand *)command {
910 NSDictionary *args = [command evaluatedArguments];
911 NSString *paramName = [args objectForKey:@"Name"];
912 NSString *paramValue = [args objectForKey:@"Value"];
914 [[workset parameterSet] removeParameterByName:paramName];
916 [[workset parameterSet] addParameter:paramName withValue:paramValue];
923 - (id)handleClearParamScriptCommand:(NSScriptCommand *)command {
925 NSDictionary *args = [command evaluatedArguments];
926 NSString *paramName = [args objectForKey:@"Name"];
928 [[workset parameterSet] removeParameterByName:paramName];
933 - (id)handleSetProcessorTypeScriptCommand:(NSScriptCommand *)command {
935 NSDictionary *args = [command evaluatedArguments];
936 NSString *processorType = [args objectForKey:@"Name"];
938 if ([processorType caseInsensitiveCompare:@"libxslt"] == NSOrderedSame) {
940 [self switchProcessorToType:PROCESSORTYPE_LIBXSLT updateUI:YES];
942 } else if ([processorType caseInsensitiveCompare:@"sablotron"] == NSOrderedSame) {
944 [self switchProcessorToType:PROCESSORTYPE_SABLOTRON updateUI:YES];
946 } else if ([processorType caseInsensitiveCompare:@"saxon"] == NSOrderedSame) {
948 [self switchProcessorToType:PROCESSORTYPE_SAXON updateUI:YES];
950 } else if ([processorType caseInsensitiveCompare:@"xalan-j"] == NSOrderedSame) {
952 [self switchProcessorToType:PROCESSORTYPE_XALAN_J updateUI:YES];
955 NSLog(@"unknown processor");
963 - (BOOL)handleDroppedFile:(NSString *)filename forTextView:(NSTextView *)sender {
965 NSString *fileContents = [XMLUtils getStringWithEncodingFromFile:filename];
967 if ([sender isEqual: xmlView]) {
969 [self setXmlcode:fileContents];
970 [workset setXmlFilename:filename];
972 } else if ([sender isEqual:xsltView]) {
974 [self setXsltcode:fileContents];
975 [workset setXsltFilename:filename];
979 NSLog(@"Unknown sender view");
991 - (NSString *)xmlcode {
992 return [workset xmlCode];
995 - (void)setXmlcode:(NSString *)s {
997 NSString *currentContents = [[[NSString alloc] initWithString:[self xmlcode]] autorelease];
999 [[self undoManager] registerUndoWithTarget:self
1000 selector:@selector(setXmlcode:)
1001 object:currentContents];
1003 [workset setXmlCode:s];
1004 [self updateCompleteUI];
1009 - (NSString *)xsltcode {
1010 return [workset xsltCode];
1013 - (void)setXsltcode:(NSString *)s {
1015 NSString *currentContents = [[[NSString alloc] initWithString:[self xsltcode]] autorelease];
1017 [[self undoManager] registerUndoWithTarget:self
1018 selector:@selector(setXsltcode:)
1019 object:currentContents];
1021 [workset setXsltCode:s];
1022 [self updateCompleteUI];
1026 - (NSString *)result {
1027 return [workset stringResult];
1032 - (void)tableViewSelectionDidChange:(NSNotification *)notification {
1037 - (void)checkForExternalModifications {
1041 if ([workset xmlModifiedExternally] && xmlDirty || [workset xsltModifiedExternally] && xsltDirty) {
1043 /* external changes conflicting with local changes detected.
1044 * Ask the user if we should keep the local unsaved changes
1046 keep = [self showUnsavedChangesPanel];
1050 if ([workset xmlModifiedExternally] && !(xmlDirty && keep)) {
1051 [workset reloadXmlFromFile];
1052 [self updateChangeCount:NSChangeDone];
1053 [self updateCompleteUI];
1057 if ([workset xsltModifiedExternally] && !(xsltDirty && keep)) {
1058 [workset reloadXsltFromFile];
1059 [self updateChangeCount:NSChangeDone];
1060 [self updateCompleteUI];
1069 - (BOOL)showUnsavedChangesPanel {
1071 [NSApp beginSheet:[unsavedChangesPanelController window]
1072 modalForWindow:[[[self windowControllers] objectAtIndex:0] window]
1077 [NSApp runModalForWindow:[unsavedChangesPanelController window]];
1078 [NSApp endSheet:[unsavedChangesPanelController window]];
1079 [[unsavedChangesPanelController window] orderOut:self];
1081 return ([unsavedChangesPanelController keepChanges]);
1085 - (void)xslfoRenderThread {
1087 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1089 XSL_FO_Renderer *xfr = [[[XSL_FO_Renderer alloc] init] autorelease];
1090 xslfoRendererResultData = [xfr render:[workset result]];
1093 [xslfoRendererLock unlockWithCondition:2];
1098 - (IBAction)renderFo:(id)sender {
1100 xslfoRendererLock = [[[NSConditionLock alloc] initWithCondition:1] autorelease];
1101 [NSThread detachNewThreadSelector:@selector(xslfoRenderThread) toTarget:self withObject:nil];
1102 [xslfoRendererLock lockWhenCondition:2];
1103 [xslfoRendererLock unlock];
1105 if (!xslfoRendererResultData) {
1106 NSLog(@"Unable to render, NULL result");
1110 [xslfoRendererResultData retain];
1112 pdfData = xslfoRendererResultData;
1114 NSImage *pdfImage = [[[NSImage alloc] initWithData:xslfoRendererResultData] autorelease];
1115 [pdfImage setBackgroundColor:[NSColor whiteColor]];
1117 [pdfImage setCacheMode:NSImageCacheNever];
1119 NSClipView *clipView = (NSClipView *)[resultImageView superview];
1120 NSScrollView *scrollView = (NSScrollView *)[clipView superview];
1122 [resultImageView setImage:pdfImage];
1123 [resultImageView setFrameSize:[pdfImage size]];
1124 [resultImageView display];
1126 [clipView scrollToPoint:NSMakePoint([resultImageView frame].origin.x, [resultImageView frame].size.height - [clipView frame].size.height + [resultImageView frame].origin.y)];
1127 [scrollView reflectScrolledClipView:clipView];
1129 pdfPageCount = [[[pdfImage representations] objectAtIndex:0] pageCount];
1135 - (IBAction)pdfPreviousPage:(id)sender {
1137 if (pdfCurrentPage > 0) {
1139 [[[[resultImageView image] representations] objectAtIndex:0] setCurrentPage:pdfCurrentPage];
1140 [resultImageView setNeedsDisplay:YES];
1146 - (IBAction)pdfNextPage:(id)sender {
1148 if (pdfCurrentPage < (pdfPageCount - 1)) {
1150 [[[[resultImageView image] representations] objectAtIndex:0] setCurrentPage:pdfCurrentPage];
1151 [resultImageView setNeedsDisplay:YES];
1158 - (IBAction)pdfSaveAs:(id)sender {
1160 NSSavePanel *panel = [NSSavePanel savePanel];
1162 if ([panel runModal] == NSFileHandlingPanelOKButton) {
1164 [pdfData writeToFile:[panel filename] atomically:YES];
1173 - (void)windowDidBecomeMain:(NSNotification *)aNotification {
1175 [self checkForExternalModifications];
1179 - (void)windowDidResize:(NSNotification *)aNotification {
1181 [self resizeWebView];
1185 - (void)resizeWebView {
1187 // [[[resultWebView mainFrame] frameView] setFrame:[resultWebView frame]];
1188 [resultWebView setNeedsDisplay:YES];
1196 - (NSString *)windowNibName
1198 // Override returning the nib file name of the document
1199 // 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.
1200 return @"MyDocument";
1203 - (void)windowControllerDidLoadNib:(NSWindowController *) aController
1208 NSSize errorDrawerSize;
1210 [super windowControllerDidLoadNib:aController];
1212 [resultImageView setImageFrameStyle:NSImageFramePhoto];
1213 [resultImageView setImageScaling:NSScaleNone];
1214 [resultImageView setImageAlignment:NSImageAlignCenter];
1215 [resultImageView setEditable:NO];
1217 [resultWebView setTextSizeMultiplier:0.9];
1219 warningIcon = [xmlWellFormedIcon image];
1221 [self updateCompleteUI];
1223 errorDrawerSize = [errorDrawer contentSize];
1224 errorDrawerSize.height = 130;
1225 [errorDrawer setContentSize:errorDrawerSize];
1227 NSFont *computerFont = [NSFont fontWithName:@"Courier" size:12.0];
1228 [resultView setFont:computerFont];
1230 [tabView registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]];
1234 if (findPanelController == nil) {
1235 findPanelController = [[FindPanelController alloc] initWithWindowNibName:@"FindPanel"];
1236 // NSLog(@"init find panel controller: %@", findPanelController);
1239 if (jumpToLinePanelController == nil) {
1240 jumpToLinePanelController = [[JumpToLinePanelController alloc] initWithWindowNibName:@"JumpToLine"];
1241 // NSLog(@"init jump to line panel controller: %@", jumpToLinePanelController);
1244 if (unsavedChangesPanelController == nil) {
1245 unsavedChangesPanelController = [[UnsavedChangesPanelController alloc] initWithWindowNibName:@"UnsavedChanges"];
1246 // NSLog(@"init unsaved changes panel controller: %@", unsavedChangesPanelController);
1252 - (void)canCloseDocumentWithDelegate:(id)delegate shouldCloseSelector:(SEL)shouldCloseSelector contextInfo:(void *)contextInfo {
1254 [uiUpdateTimer invalidate];
1255 [super canCloseDocumentWithDelegate:delegate shouldCloseSelector:shouldCloseSelector contextInfo:contextInfo];
1265 - (IBAction)showErrorLocation:(id)sender {
1267 XMLTextView *textView;
1270 if ([processor errorSource] == XSLT_ERROR_SOURCE_XML) {
1271 [self selectTabById:XML];
1274 [self selectTabById:XSLT];
1275 textView = xsltView;
1278 errorLine = [processor errorLine];
1280 [textView selectLineByNumber:errorLine];
1284 - (NSData *)dataRepresentationOfType:(NSString *)aType
1286 // Insert code here to write your document from the given data. You can also choose to override -fileWrapperRepresentationOfType: or -writeToFile:ofType: instead.
1287 return [NSArchiver archivedDataWithRootObject:workset];
1290 - (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType
1292 // Insert code here to read your document from the given data. You can also choose to override -loadFileWrapperRepresentation:ofType: or -readFromFile:ofType: instead.
1295 workset = [[NSUnarchiver unarchiveObjectWithData:data] retain];
1296 [self updateCompleteUI];