5 // Created by Marc Liyanage on Sun Mar 03 2002.
6 // Copyright (c) 2001 __MyCompanyName__. All rights reserved.
10 #import "MyDocument.h"
14 @implementation MyDocument
17 [MyDocument setKeys:[NSArray arrayWithObject:@"xmlDirty"] triggerChangeNotificationsForDependentKey:@"canSaveXmlNow"];
18 [MyDocument setKeys:[NSArray arrayWithObject:@"xsltDirty"] triggerChangeNotificationsForDependentKey:@"canSaveXsltNow"];
19 [MyDocument setKeys:[NSArray arrayWithObject:@"resultDirty"] triggerChangeNotificationsForDependentKey:@"canSaveResultNow"];
25 if (self = [super init]) {
26 workset = [[Workset alloc] init];
27 processor = [XSLTProcessorFactory makeProcessorOfType:PROCESSORTYPE_SABLOTRON];
28 wellFormedParser = [[XMLParserLibxml alloc] init];
29 [self setValue:[NSNumber numberWithBool:NO] forKey:@"xmlDirty"];
30 [self setValue:[NSNumber numberWithBool:NO] forKey:@"xsltDirty"];
31 [self setValue:[NSNumber numberWithBool:NO] forKey:@"resultDirty"];
32 [self setValue:@"" forKey:@"messageLog"];
35 defaults = [NSUserDefaults standardUserDefaults];
37 [self setValue:[NSNumber numberWithInt:2] forKey:@"processorType"];
44 // NSLog(@"doc dealloc");
48 [wellFormedParser release];
49 [findPanelController release];
50 [jumpToLinePanelController release];
51 [unsavedChangesPanelController release];
60 - (void)windowWillClose:(NSNotification *)aNotification {
62 [uiUpdateTimer invalidate];
63 [uiUpdateTimer release];
66 // NSLog(@"windowwillclose");
71 - (IBAction)selectTab:(id)sender {
73 [self selectTabById:[sender tag]];
78 - (IBAction)selectTabById:(int)tabId {
93 tabName = @"parametersTab";
98 tabName = @"resultTab";
103 [tabView selectTabViewItemWithIdentifier:tabName];
108 - (void)textViewDidChangeSelection:(NSNotification *)aNotification {
113 - (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem {
115 [[self undoManager] removeAllActions];
123 // NSLog(@"updateUI running...");
125 [uiUpdateTimer invalidate];
126 [uiUpdateTimer release];
128 uiUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(uiUpdateTimerTarget:) userInfo:nil repeats:NO];
130 [uiUpdateTimer retain];
136 - (void)uiUpdateTimerTarget:(NSTimer *)timer {
138 // NSLog(@"timer target");
150 // NSLog(@"keypath test: %@", [self valueForKeyPath:@"xmlView.hasError"]);
152 NSString *activeTabIdentifier = [[tabView selectedTabViewItem] identifier];
153 NSString *activeResultTabIdentifier = [[resultTabView selectedTabViewItem] identifier];
155 BOOL xmlTabIsVisible = [activeTabIdentifier isEqualToString:@"xmlTab"];
156 BOOL xsltTabIsVisible = !xmlTabIsVisible && [activeTabIdentifier isEqualToString:@"xsltTab"];
157 BOOL paramTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible) && [activeTabIdentifier isEqualToString:@"parametersTab"];
158 BOOL resultTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible || paramTabIsVisible);
159 BOOL resultTabHtmlIsVisible = resultTabIsVisible && [activeResultTabIdentifier isEqualToString:@"htmlResult"];
160 BOOL resultTabXslfoIsVisible = resultTabIsVisible && !resultTabHtmlIsVisible && [activeResultTabIdentifier isEqualToString:@"xslfoResult"];
161 // BOOL resultTabTextIsVisible = resultTabIsVisible && !(resultTabHtmlIsVisible || resultTabXslfoIsVisible);
163 // NSLog(@"xml: %d, xslt: %d, param: %d, result: %d, reshtml: %d, resxslfo: %d, restext: %d", xmlTabIsVisible, xsltTabIsVisible, paramTabIsVisible, resultTabIsVisible, resultTabHtmlIsVisible, resultTabXslfoIsVisible, resultTabTextIsVisible);
165 if (xmlTabIsVisible) {
166 [xmlView calculateTagStack];
168 if ([defaults boolForKey:@"enableWellformedCheck"]) {
169 [xmlView checkWellFormed];
170 if ([workset hasXmlCode] && [xmlView valueForKey:@"hasError"]) {
171 // [self setValue:[xmlView valueForKey:@"errorString"] forKey:@"drawerMessage"];
172 [self logMessage:[xmlView valueForKey:@"errorString"]];
174 [self clearMessageLog];
175 // [self setValue:nil forKey:@"drawerMessage"];
179 } else if (xsltTabIsVisible) {
180 [xsltView calculateTagStack];
182 if ([defaults boolForKey:@"enableWellformedCheck"]) {
183 [xsltView checkWellFormed];
184 if ([workset hasXsltCode] && [xsltView valueForKey:@"hasError"]) {
185 // [self setValue:[xsltView valueForKey:@"errorString"] forKey:@"drawerMessage"];
187 // [self setValue:nil forKey:@"drawerMessage"];
191 } else if (paramTabIsVisible) {
192 [paramRemoveButton setEnabled:[parameterTable selectedRow] != -1];
193 [parameterTable reloadData];
194 } else if (resultTabIsVisible) {
195 [autoShowCheckbox setEnabled:[openResultURLButton isEnabled]];
197 if (resultTabHtmlIsVisible) {
198 [self resizeWebView];
199 [self updateResultWebView];
200 } else if (resultTabXslfoIsVisible) {
201 [self updateResultPDFView];
202 [pdfCurrentPageField setIntValue: (pdfPageCount ? (pdfCurrentPage + 1) : 0)];
203 [pdfPageCountField setIntValue:pdfPageCount];
205 // [pdfPreviousPageButton setEnabled:pdfCurrentPage > 0];
206 // [pdfNextPageButton setEnabled:pdfCurrentPage < (pdfPageCount - 1)];
207 [pdfSaveAsButton setEnabled:(pdfPageCount > 0)];
208 // } else if (resultTabTextIsVisible) {
214 [processButton setEnabled:[self canProcessNow]];
216 // move this to xmlview.
217 // [self updateWellFormedIcons];
222 - (void)updateResultWebView {
223 if (!webViewUpToDate) {
224 WebFrame *mainFrame = [resultWebView mainFrame];
225 [mainFrame loadHTMLString:[workset stringResult] baseURL:[NSURL URLWithString:[webViewBaseURL stringValue]]];
226 webViewUpToDate = YES;
231 - (void)updateResultPDFView {
232 if (!PDFViewUpToDate) { // todo rename method name and instance variable
233 [self renderFo:self];
234 PDFViewUpToDate = YES;
239 - (BOOL)canProcessNow {
240 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 [workset hasXmlCode];
294 } else if (xsltTabIsVisible) {
295 return [workset hasXsltCode];
296 } else if (resultTabIsVisible) {
297 return [workset hasResult];
307 return [super validateMenuItem:menuItem];
311 - (IBAction)showInBrowser:(id)sender {
318 - (void)updateCompleteUI {
320 [xmlView setString:[workset valueForKey:@"xmlCode"]];
321 [xsltView setString:[workset valueForKey:@"xsltCode"]];
326 - (void)textDidChange:(NSNotification *)aNotification {
328 id sender = [aNotification object];
330 if ([sender isEqual:xmlView]) {
331 [workset setValue:[xmlView string] forKey:@"xmlCode"];
332 [self setValue:[NSNumber numberWithBool:YES] forKey:@"xmlDirty"];
333 } else if ([sender isEqual:xsltView]) {
334 [workset setValue:[xsltView string] forKey:@"xsltCode"];
335 [self setValue:[NSNumber numberWithBool:YES] forKey:@"xsltDirty"];
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"]) {
539 - (IBAction)process:(id)sender {
541 const char **params = [[workset valueForKey:@"parameterSet"] cArray];
543 struct timeval tstart, tend;
544 gettimeofday(&tstart, NULL);
548 if ([workset hasXsltFilename]) {
549 [processor setBaseUri:[NSString stringWithFormat:@"file://%@", [workset valueForKey:@"xsltFilename"]]];
552 if (![processor processStrings:[XMLUtils getDataWithEncodingFromString:[workset valueForKey:@"xmlCode"]] withXslt:[XMLUtils getDataWithEncodingFromString:[workset valueForKey:@"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 setValue:[processor result] forKey:@"result"];
567 [workset setResultEncoding:[processor resultEncoding]];
568 [self setValue:[NSNumber numberWithBool:YES] forKey:@"resultDirty"];
570 // [errorDrawer close];
571 [self selectTabById:RESULT];
572 [processingTimeField setStringValue:[NSString stringWithFormat:@"Time: %ldms", processingTime]];
575 webViewUpToDate = NO;
576 PDFViewUpToDate = NO;
584 if (resultDirty && [autoSaveCheckbox state] == NSOnState) {
585 [self saveResult:nil];
592 if ([autoShowCheckbox state] == NSOnState) {
593 [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 setValue:[XMLUtils getStringWithEncodingFromFile:[[panel filenames] objectAtIndex:0]] forKey:@"xmlCode"];
610 [workset setValue:[[panel filenames] objectAtIndex:0] forKey:@"xmlFilename"];
611 [self updateChangeCount:NSChangeDone];
612 [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 setValue:[XMLUtils getStringWithEncodingFromFile:[[panel filenames] objectAtIndex:0]] forKey:@"xsltCode"];
627 [workset setValue:[[panel filenames] objectAtIndex:0] forKey:@"xsltFilename"];
628 [self updateChangeCount:NSChangeDone];
629 [self updateCompleteUI];
637 - (BOOL)canSaveXmlNow {
638 return [workset hasXmlFilename] && xmlDirty;
641 - (BOOL)canSaveXsltNow {
642 return [workset hasXsltFilename] && xsltDirty;
645 - (BOOL)canSaveResultNow {
646 return [workset hasResultFilename] && resultDirty;
652 - (IBAction)saveXmlAs:(id)sender {
654 NSSavePanel *panel = [NSSavePanel savePanel];
656 if ([panel runModal] == NSFileHandlingPanelOKButton) {
658 [workset setValue:[panel filename] forKey:@"xmlFilename"];
666 - (IBAction)saveXml:(id)sender {
669 if ([workset hasXmlFilename]) {
671 [self setValue:[NSNumber numberWithBool:NO] forKey:@"xmlDirty"];
678 - (IBAction)saveXsltAs:(id)sender {
680 NSSavePanel *panel = [NSSavePanel savePanel];
682 if ([panel runModal] == NSFileHandlingPanelOKButton) {
684 [workset setValue:[panel filename] forKey:@"xsltFilename"];
692 - (IBAction)saveXslt:(id)sender {
694 if ([workset hasXsltFilename]) {
696 [self setValue:[NSNumber numberWithBool:NO] forKey:@"xsltDirty"];
704 - (IBAction)saveResultAs:(id)sender {
706 NSSavePanel *panel = [NSSavePanel savePanel];
708 if ([panel runModal] == NSFileHandlingPanelOKButton) {
710 [workset setValue:[panel filename] forKey:@"resultFilename"];
712 [self saveResult:nil];
717 - (IBAction)saveResult:(id)sender {
719 [workset saveResult];
720 [self setValue:[NSNumber numberWithBool:NO] forKey:@"resultDirty"];
727 - (IBAction)saveCurrentAs:(id)sender {
729 NSString *activeTabIdentifier = [[tabView selectedTabViewItem] identifier];
730 BOOL xmlTabIsVisible = [activeTabIdentifier isEqualToString:@"xmlTab"];
731 BOOL xsltTabIsVisible = !xmlTabIsVisible && [activeTabIdentifier isEqualToString:@"xsltTab"];
732 BOOL paramTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible) && [activeTabIdentifier isEqualToString:@"parametersTab"];
733 BOOL resultTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible || paramTabIsVisible);
735 if (xmlTabIsVisible) {
736 [self saveXmlAs:sender];
737 } else if (xsltTabIsVisible) {
738 [self saveXsltAs:sender];
739 } else if (resultTabIsVisible) {
740 [self saveResultAs:sender];
748 - (IBAction)saveCurrent:(id)sender {
750 NSString *activeTabIdentifier = [[tabView selectedTabViewItem] identifier];
751 BOOL xmlTabIsVisible = [activeTabIdentifier isEqualToString:@"xmlTab"];
752 BOOL xsltTabIsVisible = !xmlTabIsVisible && [activeTabIdentifier isEqualToString:@"xsltTab"];
753 BOOL paramTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible) && [activeTabIdentifier isEqualToString:@"parametersTab"];
754 BOOL resultTabIsVisible = !(xmlTabIsVisible || xsltTabIsVisible || paramTabIsVisible);
756 if (xmlTabIsVisible) {
757 [self saveXml:sender];
758 } else if (xsltTabIsVisible) {
759 [self saveXslt:sender];
760 } else if (resultTabIsVisible) {
761 [self saveResult:sender];
771 - (IBAction)openResultURL:(id)sender {
773 // NSLog(@"openResultURL running...");
775 if ([workset hasResultFilename]) {
777 [[NSWorkspace sharedWorkspace] openURL:[NSURL fileURLWithPath:[workset valueForKey:@"resultFilename"]]];
783 - (IBAction)newParameter:(id)sender {
785 [[workset valueForKey:@"parameterSet"] addParameter:@"name" withValue:@"value"];
790 - (IBAction)removeParameter:(id)sender {
792 int row = [parameterTable selectedRow];
795 [[workset valueForKey:@"parameterSet"] removeParameterAtIndex:row];
803 - (int)numberOfRowsInTableView:(NSTableView *)aTableView {
804 return [(ParameterSet *)[workset valueForKey:@"parameterSet"] count];
807 - (id)tableView:(NSTableView *)aTableView
808 objectValueForTableColumn:(NSTableColumn *)aTableColumn
811 return [[workset valueForKey:@"parameterSet"] getField:[aTableColumn identifier] atIndex:rowIndex];
816 - (void)tableView:(NSTableView *)aTableView
817 setObjectValue:(id)anObject
818 forTableColumn:(NSTableColumn *)aTableColumn
821 [[workset valueForKey:@"parameterSet"] setField:[aTableColumn identifier] atIndex:rowIndex toString:anObject];
827 - (IBAction)setProcessorType:(id)sender {
829 int newType = [sender tag];
831 if ([processor processorType] == newType) {
835 [self switchProcessorToType:newType updateUI:NO];
840 - (IBAction)switchProcessor:(id)sender {
841 // sender -> selected item?
842 // [self setValue:[NSNumber numberWithInt:[[sender selectedItem] tag]] forKey:@"processorType"];
843 [self switchProcessorToType:[[sender selectedItem] tag] updateUI:YES];
847 - (IBAction)switchProcessorToType:(int)newType updateUI:(BOOL)updateUI {
849 XSLTProcessor *newProcessor = nil;
851 newProcessor = [XSLTProcessorFactory makeProcessorOfType:newType];
854 NSLog(@"Unable to create new processor of type '%d'", newType);
857 [self setValue:newProcessor forKey:@"processor"];
858 [self setValue:[NSNumber numberWithInt:newType] forKey:@"processorType"];
861 [processorTypePopUp selectItemAtIndex:[processorTypePopUp indexOfItemWithTag:newType]];
868 - (id)handleProcessScriptCommand:(NSScriptCommand *)command {
870 if ([self canProcessNow]) {
879 - (id)handleExportScriptCommand:(NSScriptCommand *)command {
881 NSDictionary *args = [command evaluatedArguments];
882 NSString *file = [args objectForKey:@"File"];
888 [workset setValue:file forKey:@"resultFilename"];
890 [self saveResult:nil];
897 - (id)handleSetParamScriptCommand:(NSScriptCommand *)command {
899 NSDictionary *args = [command evaluatedArguments];
900 NSString *paramName = [args objectForKey:@"Name"];
901 NSString *paramValue = [args objectForKey:@"Value"];
903 [[workset valueForKey:@"parameterSet"] removeParameterByName:paramName];
905 [[workset valueForKey:@"parameterSet"] addParameter:paramName withValue:paramValue];
912 - (id)handleClearParamScriptCommand:(NSScriptCommand *)command {
914 NSDictionary *args = [command evaluatedArguments];
915 NSString *paramName = [args objectForKey:@"Name"];
917 [[workset valueForKey:@"parameterSet"] removeParameterByName:paramName];
922 - (id)handleSetProcessorTypeScriptCommand:(NSScriptCommand *)command {
924 NSDictionary *args = [command evaluatedArguments];
925 NSString *processorTypeString = [args objectForKey:@"Name"];
927 if ([processorTypeString caseInsensitiveCompare:@"libxslt"] == NSOrderedSame) {
929 [self switchProcessorToType:PROCESSORTYPE_LIBXSLT updateUI:YES];
931 } else if ([processorTypeString caseInsensitiveCompare:@"sablotron"] == NSOrderedSame) {
933 [self switchProcessorToType:PROCESSORTYPE_SABLOTRON updateUI:YES];
935 } else if ([processorTypeString caseInsensitiveCompare:@"saxon"] == NSOrderedSame) {
937 [self switchProcessorToType:PROCESSORTYPE_SAXON updateUI:YES];
939 } else if ([processorTypeString caseInsensitiveCompare:@"xalan-j"] == NSOrderedSame) {
941 [self switchProcessorToType:PROCESSORTYPE_XALAN_J updateUI:YES];
944 NSLog(@"unknown processor");
952 - (BOOL)handleDroppedFile:(NSString *)filename forTextView:(NSTextView *)sender {
954 NSString *fileContents = [XMLUtils getStringWithEncodingFromFile:filename];
956 if ([sender isEqual: xmlView]) {
958 [self setXmlcode:fileContents];
959 [workset setValue:filename forKey:@"xmlFilename"];
961 } else if ([sender isEqual:xsltView]) {
963 [self setXsltcode:fileContents];
964 [workset setValue:filename forKey:@"xsltFilename"];
968 NSLog(@"Unknown sender view");
978 - (void)logMessage:(NSString *)string {
979 [self setValue:[NSString stringWithFormat:@"%@\n---\n%@", string, messageLog] forKey:@"messageLog"];
982 - (void)clearMessageLog {
983 [self setValue:@"" forKey:@"messageLog"];
988 - (NSString *)xmlcode {
989 return [workset valueForKey:@"xmlCode"];
992 - (void)setXmlcode:(NSString *)s {
994 NSString *currentContents = [[[NSString alloc] initWithString:[self xmlcode]] autorelease];
996 [[self undoManager] registerUndoWithTarget:self
997 selector:@selector(setXmlcode:)
998 object:currentContents];
1000 [workset setValue:s forKey:@"xmlCode"];
1001 [self updateCompleteUI];
1006 - (NSString *)xsltcode {
1007 return [workset valueForKey:@"xsltCode"];
1010 - (void)setXsltcode:(NSString *)s {
1012 NSString *currentContents = [[[NSString alloc] initWithString:[self xsltcode]] autorelease];
1014 [[self undoManager] registerUndoWithTarget:self
1015 selector:@selector(setXsltcode:)
1016 object:currentContents];
1018 [workset setValue:s forKey:@"xsltCode"];
1019 [self updateCompleteUI];
1023 - (NSString *)result {
1024 return [workset stringResult];
1029 - (void)tableViewSelectionDidChange:(NSNotification *)notification {
1034 - (void)checkForExternalModifications {
1038 if ([workset xmlModifiedExternally] && xmlDirty || [workset xsltModifiedExternally] && xsltDirty) {
1040 /* external changes conflicting with local changes detected.
1041 * Ask the user if we should keep the local unsaved changes
1043 keep = [self showUnsavedChangesPanel];
1047 if ([workset xmlModifiedExternally] && !(xmlDirty && keep)) {
1048 [workset reloadXmlFromFile];
1049 [self updateChangeCount:NSChangeDone];
1050 [self updateCompleteUI];
1051 [self setValue:[NSNumber numberWithBool:NO] forKey:@"xmlDirty"];
1054 if ([workset xsltModifiedExternally] && !(xsltDirty && keep)) {
1055 [workset reloadXsltFromFile];
1056 [self updateChangeCount:NSChangeDone];
1057 [self updateCompleteUI];
1058 [self setValue:[NSNumber numberWithBool:NO] forKey:@"xsltDirty"];
1066 - (BOOL)showUnsavedChangesPanel {
1068 [NSApp beginSheet:[unsavedChangesPanelController window]
1069 modalForWindow:[[[self windowControllers] objectAtIndex:0] window]
1074 [NSApp runModalForWindow:[unsavedChangesPanelController window]];
1075 [NSApp endSheet:[unsavedChangesPanelController window]];
1076 [[unsavedChangesPanelController window] orderOut:self];
1078 return ([unsavedChangesPanelController keepChanges]);
1082 - (void)xslfoRenderThread {
1084 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1086 XSL_FO_Renderer *xfr = [[[XSL_FO_Renderer alloc] init] autorelease];
1087 xslfoRendererResultData = [xfr render:[workset valueForKey:@"result"]];
1090 [xslfoRendererLock unlockWithCondition:2];
1095 - (IBAction)renderFo:(id)sender {
1097 xslfoRendererLock = [[[NSConditionLock alloc] initWithCondition:1] autorelease];
1098 [NSThread detachNewThreadSelector:@selector(xslfoRenderThread) toTarget:self withObject:nil];
1099 [xslfoRendererLock lockWhenCondition:2];
1100 [xslfoRendererLock unlock];
1102 if (!xslfoRendererResultData) {
1103 NSLog(@"Unable to render, NULL result");
1107 [self setValue:xslfoRendererResultData forKey:@"pdfData"];
1110 // pdfPageCount = [[[pdfImage representations] objectAtIndex:0] pageCount];
1111 // pdfCurrentPage = 0;
1113 PDFDocument *doc = [[[PDFDocument alloc] initWithData:xslfoRendererResultData] autorelease];
1114 [resultPDFView setDocument:doc];
1115 NSLog(@"pdfview %@", resultPDFView);
1122 - (IBAction)pdfSaveAs:(id)sender {
1124 NSSavePanel *panel = [NSSavePanel savePanel];
1126 if ([panel runModal] == NSFileHandlingPanelOKButton) {
1128 [pdfData writeToFile:[panel filename] atomically:YES];
1137 - (void)windowDidBecomeMain:(NSNotification *)aNotification {
1139 [self checkForExternalModifications];
1143 - (void)windowDidResize:(NSNotification *)aNotification {
1145 [self resizeWebView];
1149 - (void)resizeWebView {
1151 // [[[resultWebView mainFrame] frameView] setFrame:[resultWebView frame]];
1152 [resultWebView setNeedsDisplay:YES];
1160 - (NSString *)windowNibName
1162 // Override returning the nib file name of the document
1163 // 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.
1164 return @"MyDocument";
1168 //- (void)awakeFromNib {
1169 // NSLog(@"awake %@", [self valueForKey:@"processorType"]);
1170 // [self switchProcessorToType:2 updateUI:YES];
1173 - (void)windowControllerDidLoadNib:(NSWindowController *) aController {
1175 NSSize errorDrawerSize;
1177 [super windowControllerDidLoadNib:aController];
1179 [resultWebView setTextSizeMultiplier:0.9];
1181 warningIcon = [xmlWellFormedIcon image];
1183 [self updateCompleteUI];
1185 errorDrawerSize = [errorDrawer contentSize];
1186 errorDrawerSize.height = 130;
1187 [errorDrawer setContentSize:errorDrawerSize];
1189 NSFont *computerFont = [NSFont fontWithName:@"Courier" size:12.0];
1190 [resultView setFont:computerFont];
1192 [tabView registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]];
1194 if (findPanelController == nil) {
1195 findPanelController = [[FindPanelController alloc] initWithWindowNibName:@"FindPanel"];
1196 // NSLog(@"init find panel controller: %@", findPanelController);
1199 if (jumpToLinePanelController == nil) {
1200 jumpToLinePanelController = [[JumpToLinePanelController alloc] initWithWindowNibName:@"JumpToLine"];
1201 // NSLog(@"init jump to line panel controller: %@", jumpToLinePanelController);
1204 if (unsavedChangesPanelController == nil) {
1205 unsavedChangesPanelController = [[UnsavedChangesPanelController alloc] initWithWindowNibName:@"UnsavedChanges"];
1206 // NSLog(@"init unsaved changes panel controller: %@", unsavedChangesPanelController);
1209 // [self switchProcessorToType:2 updateUI:YES];
1211 // [processorTypePopUp selectItemAtIndex:[processorTypePopUp indexOfItemWithTag:[[self valueForKey:@"processorType"] intValue]]];
1213 [self switchProcessorToType:[[self valueForKey:@"processorType"] intValue] updateUI:YES];
1218 - (void)canCloseDocumentWithDelegate:(id)delegate shouldCloseSelector:(SEL)shouldCloseSelector contextInfo:(void *)contextInfo {
1220 [uiUpdateTimer invalidate];
1221 [super canCloseDocumentWithDelegate:delegate shouldCloseSelector:shouldCloseSelector contextInfo:contextInfo];
1231 - (IBAction)showErrorLocation:(id)sender {
1233 XMLTextView *textView;
1236 if ([processor errorSource] == XSLT_ERROR_SOURCE_XML) {
1237 [self selectTabById:XML];
1240 [self selectTabById:XSLT];
1241 textView = xsltView;
1244 errorLine = [processor errorLine];
1246 [textView selectLineByNumber:errorLine];
1250 - (NSData *)dataRepresentationOfType:(NSString *)aType {
1251 NSMutableData *data = [[[NSMutableData alloc] init] autorelease];
1252 NSKeyedArchiver *archiver = [[[NSKeyedArchiver alloc] initForWritingWithMutableData:data] autorelease];
1253 [archiver setOutputFormat:NSPropertyListXMLFormat_v1_0];
1254 [archiver encodeObject:workset forKey:@"workset"];
1255 [archiver encodeInt:[processor processorType] forKey:@"processorType"];
1256 [archiver finishEncoding];
1261 - (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType {
1263 NSKeyedUnarchiver *unarchiver = [[[NSKeyedUnarchiver alloc] initForReadingWithData:data] autorelease];
1265 [self setValue:[unarchiver decodeObjectForKey:@"workset"] forKey:@"workset"];
1267 int docProcessorType = [unarchiver decodeIntForKey:@"processorType"];
1269 if (docProcessorType) {
1270 [self setValue:[NSNumber numberWithInt:docProcessorType] forKey:@"processorType"];
1273 [unarchiver finishDecoding];