/* vim: set ft=objc ts=4 et sw=4 nowrap: */ /* * ProjectWindowController.m * * Copyright (c) 2002 * * Author: Andreas Heppel * * This program 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 program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ProjectWindowController.h" #include "AppController.h" #include "Constants.h" #include "Functions.h" #include "Project.h" #include "Inspectors/InspectorsWin.h" #include "PreferencesWindowController.h" #include "ParametersWindowController.h" #include #include @implementation ProjectWindowController - (id) init { [self initWithWindowNibName: @"ProjectWindow"]; return self; } - (id) initWithWindowNibName: (NSString *) windowNibName { self = [super initWithWindowNibName: windowNibName]; // we do this as early as possible, since this data // is need when trackView is reloaded. and you never know when ... audioRoot = @"audio"; dataRoot = @"data"; cdRoot = @"cd"; // We set our autosave window frame name and restore the one from the user's defaults. [[self window] setFrameAutosaveName: @"ProjectWindow"]; [[self window] setFrameUsingName: @"ProjectWindow"]; return self; } - (void) dealloc { [[NSNotificationCenter defaultCenter] removeObserver: self name: BurnerInUse object: nil]; [super dealloc]; } // // action methods // - (BOOL) validateMenuItem: (NSMenuItem*)item { SEL action = [item action]; int audioRow = [trackView rowForItem: audioRoot]; int dataRow = [trackView rowForItem: dataRoot]; int cdRow = [trackView rowForItem: cdRoot]; int selRow = [trackView selectedRow]; int numSelRows = [trackView numberOfSelectedRows]; if (sel_eq(action, @selector(deleteFile:))) { if ((numSelRows == 0) || ((numSelRows == 1) && ((selRow == audioRow) || (selRow == dataRow) || (selRow == cdRow)))) { return NO; } } if (sel_eq(action, @selector(runCDrecorder:))) { if ([[AppController appController] burnerInUse] || ([[self document] numberOfTracks] <= 0)) { return NO; } } return YES; } - (void) deleteFile: (id)sender { int i; int audioRow = [trackView rowForItem: audioRoot]; int dataRow = [trackView rowForItem: dataRoot]; int cdRow = [trackView rowForItem: cdRoot]; int selRow = [trackView selectedRow]; int numSelRows = [trackView numberOfSelectedRows]; if ((numSelRows == 0) || ((numSelRows == 1) && ((selRow == audioRow) || (selRow == dataRow) || (selRow == cdRow)))) { NSBeep(); return; } for (i = [[self document] numberOfAudioTracks]-1; i >= 0; i--) { if ([trackView isRowSelected: audioRow+i+1]){ // add 1 because of parent in outline view [[self document] deleteTrackOfType: TrackTypeAudio atIndex: i]; } } for (i = [[self document] numberOfDataTracks]-1; i >= 0; i--) { if ([trackView isRowSelected: dataRow+i+1]){ // add 1 because of parent in outline view [[self document] deleteTrackOfType: TrackTypeData atIndex: i]; } } [self updateWindow]; [trackView deselectAll: self]; // update the audio CD panel if ([[self window] isKeyWindow]) { [self updateAudioCDPanel]; [self updateTrackInspector]; } return; } - (void) runCDrecorder: (id)sender { if (![[AppController appController] burnerInUse] && [[self document] numberOfTracks] > 0) { ParametersWindowController *paramsPanel; BOOL burn = YES; if ([openParamsCheckBox state]) { int rc; paramsPanel = [[ParametersWindowController alloc] initWithWindowNibName: @"ParametersWindow"]; rc = [NSApp runModalForWindow: [paramsPanel window]]; // If parameter entry gets cancelled, we stop here if (rc == NSCancelButton) burn = NO; [paramsPanel release]; } if (burn) { if (![[AppController appController] lockBurner]) { NSBeep(); return; } [[self document] burnToCD]; } } else { NSBeep(); } } // // document related methods // - (void) setDocument: (NSDocument *)document { [super setDocument: document]; /* and we need cdrecord to write it */ [self updateWindow]; if ([[self document] numberOfAudioTracks] > 0) [trackView expandItem: audioRoot]; if ([[self document] numberOfDataTracks] > 0) [trackView expandItem: dataRoot]; } - (void)saveDocument: (id)sender { if ([[self document] isDocumentEdited] == YES) { [[self document] saveDocument: sender]; } return; } - (void)saveDocumentAs: (id)sender { [[self document] saveDocumentAs: sender]; return; } - (void)saveDocumentTo: (id)sender { [[self document] saveDocumentTo: sender]; return; } - (void)burnerInUse: (id)sender { [self updateWindow]; } // // delegate methods // - (void) outlineViewSelectionDidChange: (NSNotification *) not { [self updateTrackInspector]; } - (BOOL) windowShouldClose: (id) window { // We remove our window from our list of opened windows [[AppController appController] removeProjectWindow: [self window]]; // We update our last project window on top if it was the current selected one if ([[AppController appController] lastProjectWindowOnTop] == [self window]) { [[AppController appController] setLastProjectWindowOnTop: nil]; } return YES; } - (void) awakeFromNib { // We set the last window on top [[AppController appController] setLastProjectWindowOnTop: [self window]]; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(burnerInUse:) name: BurnerInUse object: nil]; // We add our window to our list of opened windows [[AppController appController] addProjectWindow: [self window]]; } - (void) windowDidLoad { NSImage *image; image = [NSImage imageNamed: @"iconBurn.tiff"]; [image setScalesWhenResized: YES]; [image setSize: NSMakeSize(24,24)]; [recordButton setImagePosition: NSImageRight]; [recordButton setImage: image]; [openParamsCheckBox setState: YES]; } - (void) windowDidBecomeKey: (NSNotification *) not { // We set the last window on top [[AppController appController] setLastProjectWindowOnTop: [self window]]; // update the audio CD panel [self updateAudioCDPanel]; [self updateTrackInspector]; } // // access / mutation methods // - (long) totalTime { return [(Project*)[self document] totalLength]; } // // Other methods // - (void) displayTotalTime { long totalTime; // Frames totalTime = [(Project*)[self document] totalLength]; [totalLength setDoubleValue: (double)framesToSize((double)totalTime)]; } - (void) updateWindow { [trackView reloadData]; [self displayTotalTime]; [self enableBurnButton]; } - (void) updateAudioCDPanel { int i; NSArray *keys; NSMutableArray *allCDs = [NSMutableArray new]; keys = [[self document] allCddbIds]; for (i = 0; i < [keys count]; i++) { NSDictionary *orgCD = [[self document] cdForKey: [keys objectAtIndex: i]]; NSDictionary *newCD = [NSDictionary dictionaryWithObjectsAndKeys: [keys objectAtIndex: i], @"cddbId", [orgCD objectForKey: @"artist"], @"artist", [orgCD objectForKey: @"title"], @"title", nil]; [allCDs addObject: newCD]; } [[NSNotificationCenter defaultCenter] postNotificationName: AudioCDMessage object: nil userInfo: [NSDictionary dictionaryWithObjectsAndKeys: allCDs, @"cds", nil]]; } - (void) updateTrackInspector { // // change data in track inspector if necessary int i; int audioRow = [trackView rowForItem: audioRoot]; int dataRow = [trackView rowForItem: dataRoot]; NSMutableArray *tracks = [NSMutableArray new]; audioRow += 1; dataRow += 1; for (i = 0; i < [[self document] numberOfAudioTracks]; i++) { if ([trackView isRowSelected: audioRow+i]) [tracks addObject: [[self document] trackOfType: TrackTypeAudio atIndex: i]]; } for (i = 0; i < [[self document] numberOfDataTracks]; i++) { if ([trackView isRowSelected: dataRow+i]) [tracks addObject: [[self document] trackOfType: TrackTypeData atIndex: i]]; } [[NSNotificationCenter defaultCenter] postNotificationName: TrackSelectionChanged object: nil userInfo: [NSDictionary dictionaryWithObject: tracks forKey: @"Tracks"]]; [tracks release]; } - (void) enableBurnButton { if ([[AppController appController] burnerInUse] || ([[self document] numberOfTracks] <= 0)) { [recordButton setEnabled: NO]; } else { [recordButton setEnabled: YES]; } } // // class methods // + (void)initialize { static BOOL initialized = NO; /* Make sure code only gets executed once. */ if (initialized == YES) return; initialized = YES; [NSApp registerServicesMenuSendTypes: nil returnTypes: [NSArray arrayWithObjects: AudioCDPboardType, nil]]; return; } @end