Logo Search packages:      
Sourcecode: adun.app version File versions  Download package

ULSystemViewController.m

/*
   Project: UL

   Copyright (C) 2005 Michael Johnston & Jordi Villa-Freixa

   Author: Michael Johnston

   This application is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This application is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/

#include <AppKit/AppKit.h>
#include "ULSystemViewController.h"

@implementation ULSystemViewController

/************************

Initialisation Methods

************************/

- (id) initWithSystemController: (id) object modelViewController: (id) mVC
{
      if(self = [super init])
      {
            if([NSBundle loadNibNamed: @"System" owner: self] == NO)
            {
                  NSWarnLog(@"Problem loading interface");
                  return nil;
            }

            systemController = [object retain];
            mainViewController = mVC;
            metadataController = [mainViewController metadataController];
            allowedFileTypes = [[NSArray arrayWithObjects: @"PDB", @"pdb", nil] retain];
            isBuilding = NO;

            //register for some notifications from about the build process state

            [[NSNotificationCenter defaultCenter] addObserver: self
                  selector: @selector(handleNotification:)
                  name: @"ULSystemBuildSectionCompleted"
                  object: nil];
            [[NSNotificationCenter defaultCenter] addObserver: self
                  selector: @selector(handleNotification:)
                  name: @"ULSystemBuildWillStart"
                  object: nil];
            [[NSNotificationCenter defaultCenter] addObserver: self
                  selector: @selector(handleNotification:)
                  name: @"ULSystemBuildDidAbortNotification"
                  object: nil];
            [[NSNotificationCenter defaultCenter] addObserver: self
                  selector: @selector(handleNotification:)
                  name: @"ULSystemBuilderWillBeginInitialisationNotification"
                  object: nil];
            [[NSNotificationCenter defaultCenter] addObserver: self
                  selector: @selector(handleNotification:)
                  name: @"ULSystemBuilderWillBeginInitialisationStepNotification"
                  object: nil];
            [[NSNotificationCenter defaultCenter] addObserver: self
                  selector: @selector(handleNotification:)
                  name: @"ULSystemBuilderCompletedInitialisationStepNotification"
                  object: nil];

            [tabView setDelegate: self];
            preprocessTabViewItem = [[tabView tabViewItemAtIndex: 0] retain];
            [systemWindow center];
            [systemWindow setDelegate: self];

      }
      return self;
}

- (void) dealloc
{
      [outlineDelegate release];
      [currentOptions release];
      [systemController release];
      [allowedFileTypes release];
      [super dealloc];
}

- (void) _insertString: (NSString*) string fontType: (NSString*) fontType
{
      NSRange fontRange, range;
      NSMutableAttributedString* boldString;
      NSFont* font;
      NSFontManager *fontManager = [NSFontManager sharedFontManager];

      font = [NSFont userFontOfSize: 12];
      if([fontType isEqual: @"Bold"])
            font = [fontManager convertFont: font toHaveTrait: NSBoldFontMask];

      range = NSMakeRange([[logView textStorage] length], 0);
      [[logView textStorage] replaceCharactersInRange: range withString: string];
      fontRange = NSMakeRange(range.location, [string length]);   
      
      [[logView textStorage] beginEditing];
      [[logView textStorage] addAttribute: NSFontAttributeName value: font range: fontRange];
      [[logView textStorage] endEditing];
      [logView scrollRangeToVisible: NSMakeRange([[logView textStorage] length], 0)];
}

- (void) handleNotification: (NSNotification*) aNotification
{
      NSRange range;
      NSMutableString* buildInfo;

      [progressView display];
      [progressIndicator display];  
      [progressBar display];  

      if([[aNotification name] isEqual: @"ULSystemBuildWillStart"])
      {
            [progressBar setDoubleValue: 0.0];
            [progressIndicator setStringValue: @"Beginning Build"];
            NSDebugLLog(@"ULSystemViewController", @"Recieved %@", [aNotification name]);
      }
      else if([[aNotification name] isEqual: @"ULSystemBuildSectionCompleted"])
      {
            [progressBar incrementBy: 25];
            [progressIndicator setStringValue: [aNotification object]];
            NSDebugLLog(@"ULSystemViewController", @"Recieved %@", [aNotification name]);

            [self _insertString: [aNotification object] fontType: @"Bold"];
            buildInfo = [NSMutableString stringWithCapacity: 1];
            [buildInfo appendString: @"\n"];
            [buildInfo appendString: [[aNotification userInfo] 
                        objectForKey: @"ULBuildSectionUserInfoKey"]];
            [buildInfo appendString: @"\n"];
            [self _insertString: buildInfo fontType: @"Normal"];
      }
      else if([[aNotification name] isEqual: @"ULSystemBuildDidAbortNotification"])
      {
            [progressIndicator setStringValue: 
                  [NSString stringWithFormat: @"Build Aborted! - At position %@", [aNotification object]]];
      
            [self _insertString: [aNotification object] fontType: @"Bold"];

            buildInfo = [NSMutableString stringWithCapacity: 1];
            [buildInfo appendString: @"\n"];
            [buildInfo appendString: [[aNotification userInfo] 
                        objectForKey: @"ULBuildSectionUserInfoKey"]];
            [buildInfo appendString: @"\n"];
            [self _insertString: buildInfo fontType: @"Normal"];
      }     
      else if([[aNotification name] isEqual: @"ULSystemBuilderWillBeginInitialisationNotification"])
      {
            [progressBar setDoubleValue: 0.0];
            [progressIndicator setStringValue: [aNotification object]]; 
      }
      else if([[aNotification name] isEqual: @"ULSystemBuilderCompletedInitialisationStepNotification"])
      {     
            [progressBar incrementBy: 33];
            [progressIndicator setStringValue: [aNotification object]]; 
      }
      else if([[aNotification name] isEqual: @"ULSystemBuilderWillBeginInitialisationStepNotification"])
      {
            [progressIndicator setStringValue: [aNotification object]]; 
      }
      
      [progressIndicator display];  
      [progressBar display];  
      [progressView display];
}

/*********************

Opening and closing the system window
We use the same interface for system creation , system analysis and pdb analysis
just changing the button names.
See note on changing this to delegate pattern

**********************/

- (void) _setDelegateForOptions: (id) options
{
      [outlineDelegate release];
      outlineDelegate = [[ULOutlineViewDelegate alloc]
                        initWithOptions: options];    
      [optionsView setDataSource: outlineDelegate];
      [optionsView setDelegate: outlineDelegate];
      [optionsView reloadData];
}

//opening a create system window

00200 - (void) open: (id) sender
{
      ULIOManager* ioManager; 
      NSArray* plugins;
      NSRange range;

      //if the window is already open do nothing
      //except bring it to the front if neccessary

      if([systemWindow isVisible])
      {
            if(![systemWindow isKeyWindow])
                  [systemWindow makeKeyAndOrderFront: self];
            
            return;
      }

      //scan local adun directory for plugins
      ioManager = [ULIOManager appIOManager];

      [[logView textStorage] deleteCharactersInRange: 
            NSMakeRange(0, [[logView textStorage] length])];
      
      //we have to make sure nothing is left from a previous
      //hidden solvent build

      currentOptions = nil;
      [self _setDelegateForOptions: currentOptions];
      
      [systemController removeMolecule];

      plugins = [ioManager configurationPlugins];
      [pluginList removeAllItems];
      [pluginList addItemWithTitle: @"None"];
      [pluginList addItemsWithTitles: plugins];
      [pluginList selectItemWithTitle: @"None"];

      [forcefieldLabel setStringValue: @"Force Field"];
      [forcefieldList removeAllItems];
      [forcefieldList addItemWithTitle: @"Enzymix"];
      [forcefieldList selectItemWithTitle: @"Enzymix"];

      [moleculePathField setStringValue: @""];
      [systemWindow setTitle: @"Create System"];
      [progressIndicator setStringValue: @""];
      [progressBar setDoubleValue: 0.0];
      [buttonOne setTitle: @"Create"];
      [systemWindow makeKeyAndOrderFront: self];
      [systemWindow setAutodisplay: YES];

      [buttonTwo setEnabled: NO];
      [buttonThree setEnabled: NO];
      
      if([tabView numberOfTabViewItems] == 1)
            [tabView insertTabViewItem: preprocessTabViewItem
                  atIndex: 0];
      //removes some display problems with the inserted tab
      [tabView selectFirstTabViewItem: self];
      [tabView selectLastTabViewItem: self];
      [[tabView selectedTabViewItem] setLabel: @"Build"];
}

00262 - (void) close: (id) sender
{
      [optionsView setDelegate: nil];
      [optionsView setDataSource: nil];
      [optionsView reloadData];
      [outlineDelegate release];
      outlineDelegate = nil;
      [currentOptions release];
      currentOptions =  nil;
      [moleculePathField setStringValue: @""];
      [systemController removeMolecule];
      [[logView textStorage] deleteCharactersInRange: 
            NSMakeRange(0, [[logView textStorage] length])];
} 

00277 - (void) doButtonAction: (id) sender
{
      [self createSystem: sender];
}

- (void) doButtonThreeAction: (id) sender
{
      [self continueBuild];
}

- (void) doButtonTwoAction: (id) sender
{
      [self cancelBuild];
}

/************************

Creating a System

************************/

00298 - (void) showFileBrowser: (id) sender
{
      id fileBrowser;
      int result;
      NSRange endRange;
      NSMutableString* failString;

      //if there is a current build prevent loading
      // another until  it ends

      if(isBuilding)
      {
            NSRunAlertPanel(@"Alert",
                  @"You must continue or cancel the current build!",
                  @"Dismiss", 
                  nil, 
                  nil);

            return;
      }

      [progressBar setDoubleValue: 0.0];
      fileBrowser = [NSOpenPanel openPanel];
      [fileBrowser setTitle: @"Load PDB"];
      [fileBrowser setDirectory: [[NSUserDefaults standardUserDefaults] stringForKey:@"PDBDirectory"]];
      [fileBrowser setAllowsMultipleSelection: NO];
      result = [fileBrowser runModalForTypes: allowedFileTypes];
      if(result == NSOKButton)
      {
            if([allowedFileTypes containsObject: [[fileBrowser filename] pathExtension]])
                  [moleculePathField setStringValue: [fileBrowser filename]];
            else
                  NSRunAlertPanel(@"Error", 
                        [NSString stringWithFormat: @"Unknown file type - %@\nSupported types %@", 
                              [[fileBrowser filename] pathExtension], allowedFileTypes],
                        @"Dismiss",
                        nil,
                        nil);
            
            [[logView textStorage] deleteCharactersInRange: 
                  NSMakeRange(0, [[logView textStorage] length])];

            endRange = NSMakeRange([[logView string] length], 0);
            failString = [NSMutableString stringWithCapacity: 1];
            NS_DURING
            {
                  [systemController setBuildMolecule: [moleculePathField stringValue]];
                  [currentOptions release];
                  currentOptions = [systemController buildOptions];
                  [currentOptions retain];
                  [self _setDelegateForOptions: currentOptions];
            }
            NS_HANDLER
            {
                  failString = [NSMutableString stringWithCapacity: 1];
                  [failString appendString: @"Failed to load molecule ...\n"];
                  [failString appendString: [localException reason]];
                  [failString appendString: @"\n"];   

                  if([[localException name] isEqual: @"ULBuildException"])
                  {
                        [failString appendString: [[localException userInfo] 
                              objectForKey:
                              @"ULBuildRecoverySuggestionKey"]];
                        [failString appendString: @"\n"];   
                  }

                  [logView replaceCharactersInRange: endRange withString: failString];
                  NSRunAlertPanel(@"Load Molecule Failed", 
                        [localException reason], 
                        @"Dismiss", 
                        nil, 
                        nil);
            }
            NS_ENDHANDLER           
      }
}

- (void) _logBuildError: (NSError*) buildError
{
      NSMutableString* failString;
      NSString* recoveryString;

      [self _insertString: @"*****  Detected Build Errors  *****\n\n" fontType: @"Bold"];
      failString = [NSMutableString stringWithCapacity: 1];

      [failString appendString: @"\n"];
      [failString appendString: [[buildError userInfo] 
            objectForKey: @"ULBuildErrorDetailedDesciptionKey"]];
      [failString appendString: @"\n"];
      
      [self _insertString: failString fontType: @"Normal"];

      recoveryString = [[buildError userInfo] 
                        objectForKey: @"ULBuildErrorRecoverySuggestionKey"];
      if(recoveryString != nil)
      {     
            [self _insertString: @"***** Recovery Suggestion *****\n\n" 
                  fontType: @"Bold"];
            [failString deleteCharactersInRange: NSMakeRange(0, [failString length])];
            [failString appendFormat: @"%@\n", recoveryString];
            [self _insertString: failString fontType: @"Normal"];
      }
}

- (void) _logULBuildException: (NSException*) localException
{
      NSMutableString* failString;

      [self _insertString: @"*****  Build Failed  *****\n\n" fontType: @"Bold"];
                  
      failString = [NSMutableString stringWithCapacity: 1];
      [failString appendString: [localException reason]];
      [failString appendString: @"\n"];

      if([[localException userInfo] objectForKey: @"ULBuildExceptionDetailedDescriptionKey"] != nil)  
      {
            [failString appendString: [[localException userInfo] 
                        objectForKey: @"ULBuildRecoverySuggestionKey"]];
            [failString appendString: @"\n"];   
      }

      if([[localException userInfo] objectForKey: @"ULBuildRecoverySuggestionKey"] != nil)      
      {
            [failString appendString: [[localException userInfo] 
                        objectForKey: @"ULBuildRecoverySuggestionKey"]];
            [failString appendString: @"\n"];   
      }
      [self _insertString: failString fontType: @"Normal"];
      NSRunAlertPanel(@"Build Failed", [localException reason], @"Dismiss", nil, nil);
}

- (void) _logUnexpectedBuildException: (NSException*) localException
{
      NSMutableString* failString;

      failString = [NSMutableString stringWithCapacity: 1];
      [self _insertString: @"*****  Unexpected Build Failure  *****\n\n" fontType: @"Bold"];
      [failString appendString: [localException reason]];
      [failString appendString: @"\n"];   
      [failString appendString: [[localException userInfo] description]];
      [failString appendString: @"\n"];   
      [failString appendString: 
            @"Please file a support request with the pdb used attached and this build log "];
      [failString appendString: @"at the Adun Project Page:"];
      [failString appendString: @"\nhttp://gna.org/projects/adun\n"];
      [self _insertString: failString fontType: @"Normal"];
      NSRunAlertPanel(@"Unexpected build failure", 
                        @"See log for details", 
                        @"Dismiss",
                        nil, 
                        nil);
}

00452 - (void) createSystem: (id)sender
{
      BOOL cancel = NO;
      NSString* filePath;
      NSString* output;
      NSMutableString* failString;
      NSError* buildError;
      int choice;

      /*
       * isBuilding is set to yes until the build
       * A) Completes
       * B) raises an exception 
       * C) is canceled by the user
       */

      isBuilding = YES;

      NS_DURING
      {     
            [[logView textStorage] deleteCharactersInRange: 
                  NSMakeRange(0, [[logView textStorage] length])];

            [self _insertString: @"*****  Beginning Build  *****\n\n" fontType: @"Bold"];
            if(currentOptions == nil)
                  [NSException raise: @"ULBuildException"
                        format: @"No molecule has been loaded"];

            buildError = nil;
            if(![systemController buildSystemWithOptions: currentOptions error: &buildError])
            {
                  failString = [NSMutableString stringWithCapacity: 1];
                  [failString appendString:[[buildError userInfo] 
                        objectForKey: @"NSLocalizedDescriptionKey"]];
                  [failString appendString: @"\n\n ** Check the log window for more details. **\n\n"];
                  [failString appendString: @"Choose 'Continue' to ignore the errors "];
                  [failString appendString: @" or 'Cancel' to abort."];
                  [self _logBuildError: buildError];
                  NSRunAlertPanel(@"Build Error",
                        failString,
                        @"Dismiss",
                        nil,
                        nil); 
                  [buttonOne setEnabled: NO];
                  [buttonTwo setEnabled: YES];
                  [buttonThree setEnabled: YES];
            }
            else
            {
                  [progressIndicator setStringValue: @"Complete"];
                  [metadataController displayMetadataForModelObject: [systemController valueForKey:@"System"]
                        allowEditing: YES
                        runModal: YES];
            
                  [self _insertString: @"*****  Build Complete  *****\n" fontType: @"Bold"];
                  [systemController saveSystem];
                  [systemWindow orderFront: self];

                  isBuilding = NO;
            }
      }
      NS_HANDLER
      {     
            isBuilding = NO;

            if([[localException name] isEqual: @"ULBuildException"])
                  [self _logULBuildException: localException];
            else
                  [self _logUnexpectedBuildException: localException];
      }
      NS_ENDHANDLER
}

00525 - (void) continueBuild
{
      NSError* buildError;
      NSMutableString* failString;

      NS_DURING
      {
            [self _insertString: @"Resuming build - ignoring previous errors.\n\n"
                  fontType: @"Bold"];
            buildError = nil;
            if(![systemController resumeBuild: currentOptions error: &buildError])  
            {
                  [self _logBuildError: buildError];
                  failString = [NSMutableString stringWithCapacity: 1];
                  [failString appendString:[[buildError userInfo] 
                        objectForKey: @"NSLocalizedDescriptionKey"]];
                  [failString appendString: @"\nCheck the log window for more details.\n\n"];
                  [failString appendString: @"Choose 'Continue' to ignore the errors "];
                  [failString appendString: @" or 'Cancel' to abort."];
                  NSRunAlertPanel(@"Build Error",
                        failString,
                        @"Dismiss",
                        nil,
                        nil); 
            }     
            else
            {
                  [progressIndicator setStringValue: @"Complete"];
                  [metadataController displayMetadataForModelObject: [systemController valueForKey:@"System"]
                        allowEditing: YES
                        runModal: YES];
                        
                  [self _insertString: @"*****  Build Complete  *****\n" fontType: @"Bold"];
                  [systemController saveSystem];
                  [systemWindow orderFront: self];
                  [buttonOne setEnabled: YES];
                  [buttonTwo setEnabled: NO];
                  [buttonThree setEnabled: NO];
                  isBuilding = NO;
            }
      }
      NS_HANDLER
      {
            if([[localException name] isEqual: @"ULBuildException"])
                  [self _logULBuildException: localException];
            else
                  [self _logUnexpectedBuildException: localException];
                  
            [buttonOne setEnabled: YES];
            [buttonTwo setEnabled: NO];
            [buttonThree setEnabled: NO];
            isBuilding = NO;
      }
      NS_ENDHANDLER
}

00581 - (void) cancelBuild
{
      NSMutableString* failString;

      [self _insertString: @"*****  Build Canceled  *****\n\n" fontType: @"Bold"];
      failString = [NSMutableString stringWithCapacity: 1];
      [failString appendString: @"User canceled build due to above errors."];
      [failString appendString: @"\n"];
      [self _insertString: failString fontType: @"Normal"];
      [progressIndicator setStringValue: 
      [NSString stringWithFormat: @"Build Canceled"]];
      [buttonOne setEnabled: YES];
      [buttonTwo setEnabled: NO];
      [buttonThree setEnabled: NO];
      [systemController cancelBuild];
      isBuilding = NO;
}

/******************

Tabview Delegate methods

********************/

- (void)tabView: (NSTabView *)tabView didSelectTabViewItem: (NSTabViewItem *)tabViewItem
{
      id holder;

      holder = currentOptions;

      if([[tabViewItem label] isEqual: @"Preprocess"])
            currentOptions = [systemController preprocessOptions];
      else
            currentOptions = [systemController buildOptions];
            
      [currentOptions retain];
      [holder release];
      [self _setDelegateForOptions: currentOptions];
}

- (BOOL) tabView: (NSTabView *) tabView shouldSelectTabViewItem: (NSTabViewItem*) tabViewItem
{
      if(isBuilding)
      {
            NSRunAlertPanel(@"Alert",
                  @"You must continue or cancel the current build!",
                  @"Dismiss", 
                  nil, 
                  nil);
            
            return NO;
      }

      return YES;
}

/******************

Window Delegate Methods

*******************/

- (void) windowWillClose: (NSNotification*) aNotification
{
      [self close: self];
      [systemWindow orderOut:self];
}

- (BOOL) windowShouldClose: (id) sender
{
      if(isBuilding)
      {
            NSRunAlertPanel(@"Alert",
                  @"You must continue or cancel the current build!",
                  @"Dismiss", 
                  nil, 
                  nil);
            
            return NO;
      }
      
      return YES;
}

@end

Generated by  Doxygen 1.6.0   Back to index