diff options
Diffstat (limited to 'Source/SPWindowController.m')
-rw-r--r-- | Source/SPWindowController.m | 379 |
1 files changed, 5 insertions, 374 deletions
diff --git a/Source/SPWindowController.m b/Source/SPWindowController.m index ed538312..eeecca68 100644 --- a/Source/SPWindowController.m +++ b/Source/SPWindowController.m @@ -32,9 +32,9 @@ enum { #import "SPWindowController.h" #import "SPDatabaseDocument.h" -#import "PSMTabDragAssistant.h" #import "SPDatabaseViewController.h" #import "SPAppController.h" +#import "PSMTabDragAssistant.h" #import <PSMTabBar/PSMTabBarControl.h> #import <PSMTabBar/PSMTabStyle.h> @@ -101,6 +101,9 @@ enum { { [[NSNotificationCenter defaultCenter] removeObserver:self]; + // Tear down the animations on the tab bar to stop redraws + [tabBar destroyAnimations]; + [managedDatabaseConnections release]; [super dealloc]; @@ -112,7 +115,7 @@ enum { /** * Add a new database connection to the window, in a tab view. */ -- (IBAction) addNewConnection:(id)sender +- (IBAction)addNewConnection:(id)sender { // Create a new database connection view SPDatabaseDocument *newTableDocument = [[SPDatabaseDocument alloc] init]; @@ -356,378 +359,6 @@ enum { } #pragma mark - -#pragma mark Tab view delegate methods - -/** - * Called when a tab item is about to be selected. - */ -- (void)tabView:(NSTabView *)tabView willSelectTabViewItem:(NSTabViewItem *)tabViewItem -{ - [selectedTableDocument willResignActiveTabInWindow]; -} - -/** - * Called when a tab item was selected. - */ -- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem -{ - if ([[PSMTabDragAssistant sharedDragAssistant] isDragging]) return; - selectedTableDocument = [tabViewItem identifier]; - [selectedTableDocument didBecomeActiveTabInWindow]; - if ([[self window] isKeyWindow]) [selectedTableDocument tabDidBecomeKey]; - [self updateAllTabTitles:self]; -} - -/** - * Called to determine whether a tab view item can be closed - */ -- (BOOL)tabView:(NSTabView *)aTabView shouldCloseTabViewItem:(NSTabViewItem *)tabViewItem -{ - SPDatabaseDocument *theDocument = [tabViewItem identifier]; - if (![theDocument parentTabShouldClose]) return NO; - return YES; -} - -/** - * Called after a tab view item is closed. - */ -- (void)tabView:(NSTabView *)aTabView didCloseTabViewItem:(NSTabViewItem *)tabViewItem -{ - SPDatabaseDocument *theDocument = [tabViewItem identifier]; - [theDocument removeObserver:self forKeyPath:@"isProcessing"]; - [theDocument parentTabDidClose]; -} - -/** - * Called to allow dragging of tab view items - */ -- (BOOL)tabView:(NSTabView *)aTabView shouldDragTabViewItem:(NSTabViewItem *)tabViewItem fromTabBar:(PSMTabBarControl *)tabBarControl -{ - return YES; -} - -/** - * Called when a tab finishes a drop. This is called with the new tabView. - */ -- (void)tabView:(NSTabView*)aTabView didDropTabViewItem:(NSTabViewItem *)tabViewItem inTabBar:(PSMTabBarControl *)tabBarControl -{ - SPDatabaseDocument *draggedDocument = [tabViewItem identifier]; - - // Grab a reference to the old window - NSWindow *draggedFromWindow = [draggedDocument parentWindow]; - - // If the window changed, perform additional processing. - if (draggedFromWindow != [tabBarControl window]) { - - // Update the old window, ensuring the toolbar is cleared to prevent issues with toolbars in multiple windows - [draggedFromWindow setToolbar:nil]; - [[draggedFromWindow windowController] updateSelectedTableDocument]; - - // Update the item's document's window and controller - [draggedDocument willResignActiveTabInWindow]; - [draggedDocument setParentWindowController:[[tabBarControl window] windowController]]; - [draggedDocument setParentWindow:[tabBarControl window]]; - [draggedDocument didBecomeActiveTabInWindow]; - - // Update window controller's active tab, and update the document's isProcessing observation - [[[tabBarControl window] windowController] updateSelectedTableDocument]; - [draggedDocument removeObserver:[draggedFromWindow windowController] forKeyPath:@"isProcessing"]; - [[[tabBarControl window] windowController] _updateProgressIndicatorForItem:tabViewItem]; - } - - // Check the window and move it to front if it's key (eg for new window creation) - if ([[tabBarControl window] isKeyWindow]) [[tabBarControl window] orderFront:self]; -} - -/** - * Respond to dragging events entering the tab in the tab bar. - * Allows custom behaviours - for example, if dragging text, switch to the custom - * query view. - */ -- (void)draggingEvent:(id <NSDraggingInfo>)dragEvent enteredTabBar:(PSMTabBarControl *)tabBarControl tabView:(NSTabViewItem *)tabViewItem -{ - SPDatabaseDocument *theDocument = [tabViewItem identifier]; - - if (![theDocument isCustomQuerySelected] - && [[[dragEvent draggingPasteboard] types] indexOfObject:NSStringPboardType] != NSNotFound) - { - [theDocument viewQuery:self]; - } -} - -/** - * Show tooltip for a tab view item. - */ -- (NSString *)tabView:(NSTabView *)aTabView toolTipForTabViewItem:(NSTabViewItem *)tabViewItem -{ - - NSInteger tabIndex = [tabView indexOfTabViewItem:tabViewItem]; - - if([[tabBar cells] count] < (NSUInteger)tabIndex) return @""; - - PSMTabBarCell *theCell = [[tabBar cells] objectAtIndex:tabIndex]; - - // If cell is selected show tooltip if truncated only - if([theCell tabState] & PSMTab_SelectedMask) { - - CGFloat cellWidth = [theCell width]; - CGFloat titleWidth = [theCell stringSize].width; - CGFloat closeButtonWidth = 0; - - if([theCell hasCloseButton]) - closeButtonWidth = [theCell closeButtonRectForFrame:[theCell frame]].size.width; - - if(titleWidth > cellWidth - closeButtonWidth) - return [theCell title]; - - return @""; - - // if cell is not selected show full title plus MySQL version is enabled as tooltip - } else { - if([[tabViewItem identifier] respondsToSelector:@selector(tabTitleForTooltip)]) - return [[tabViewItem identifier] tabTitleForTooltip]; - - return @""; - - } - -} - -/** - * Allow window closing of the last tab item. - */ -- (void)tabView:(NSTabView *)aTabView closeWindowForLastTabViewItem:(NSTabViewItem *)tabViewItem -{ - [[aTabView window] close]; -} - -/** - * When dragging a tab off a tab bar, add a shadow to the drag window. - */ -- (void)tabViewDragWindowCreated:(NSWindow *)dragWindow -{ - [dragWindow setHasShadow:YES]; -} - -/** - * Allow dragging and dropping of tabs to any position, including out of a tab bar - * to create a new window. - */ -- (BOOL)tabView:(NSTabView*)aTabView shouldDropTabViewItem:(NSTabViewItem *)tabViewItem inTabBar:(PSMTabBarControl *)tabBarControl -{ - return YES; -} - -/** - * When a tab is dragged off a tab bar, create a new window containing a new - * (empty) tab bar to hold it. - */ -- (PSMTabBarControl *)tabView:(NSTabView *)aTabView newTabBarForDraggedTabViewItem:(NSTabViewItem *)tabViewItem atPoint:(NSPoint)point -{ - - // Create the new window controller, with no tabs - SPWindowController *newWindowController = [[SPWindowController alloc] initWithWindowNibName:@"MainWindow"]; - NSWindow *newWindow = [newWindowController window]; - - CGFloat toolbarHeight = 0; - if ([[[self window] toolbar] isVisible]) { - NSRect innerFrame = [NSWindow contentRectForFrameRect:[[self window] frame] styleMask:[[self window] styleMask]]; - toolbarHeight = innerFrame.size.height - [[[self window] contentView] frame].size.height; - } - - // Adjust the positioning as appropriate - point.y += toolbarHeight; - if ([[NSUserDefaults standardUserDefaults] boolForKey:SPAlwaysShowWindowTabBar]) point.y += kPSMTabBarControlHeight; - - // Set the new window position and size - NSRect targetWindowFrame = [[self window] frame]; - targetWindowFrame.size.height -= toolbarHeight; - [newWindow setFrame:targetWindowFrame display:NO]; - [newWindow setFrameTopLeftPoint:point]; - - // Set the window controller as the window's delegate - [newWindow setDelegate:newWindowController]; - - // Set window title - [newWindow setTitle:[[[tabViewItem identifier] parentWindow] title]]; - - // Return the window's tab bar - return [newWindowController valueForKey:@"tabBar"]; -} - -/** - * When dragging a tab off the tab bar, return an image so that a - * drag placeholder can be displayed. - */ -- (NSImage *)tabView:(NSTabView *)aTabView imageForTabViewItem:(NSTabViewItem *)tabViewItem offset:(NSSize *)offset styleMask:(unsigned int *)styleMask -{ - NSImage *viewImage = [[NSImage alloc] init]; - - // Capture an image of the entire window - CGImageRef windowImage = CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, (unsigned int)[[self window] windowNumber], kCGWindowImageBoundsIgnoreFraming); - NSBitmapImageRep *viewRep = [[NSBitmapImageRep alloc] initWithCGImage:windowImage]; - [viewImage addRepresentation:viewRep]; - - // Calculate the titlebar+toolbar height - CGFloat contentViewOffsetY = [[self window] frame].size.height - [[[self window] contentView] frame].size.height; - offset->height = contentViewOffsetY + [tabBar frame].size.height; - - // Draw over the tab bar area - [viewImage lockFocus]; - [[NSColor windowBackgroundColor] set]; - NSRectFill([tabBar frame]); - [viewImage unlockFocus]; - - // Draw the tab bar background in the tab bar area - [viewImage lockFocus]; - NSRect tabFrame = [tabBar frame]; - [[NSColor windowBackgroundColor] set]; - NSRectFill(tabFrame); - - // Draw the background flipped, which is actually the right way up - NSAffineTransform *transform = [NSAffineTransform transform]; - [transform translateXBy:0.0f yBy:[[[self window] contentView] frame].size.height]; - [transform scaleXBy:1.0f yBy:-1.0f]; - [transform concat]; - [(id <PSMTabStyle>)[[aTabView delegate] style] drawBackgroundInRect:tabFrame]; - [viewImage unlockFocus]; - - return [viewImage autorelease]; -} - -/** - * Displays the current tab's context menu. - */ -- (NSMenu *)tabView:(NSTabView *)aTabView menuForTabViewItem:(NSTabViewItem *)tabViewItem -{ - NSMenu *menu = [[NSMenu alloc] init]; - - [menu addItemWithTitle:NSLocalizedString(@"Close Tab", @"close tab context menu item") action:@selector(closeTab:) keyEquivalent:@""]; - [menu insertItem:[NSMenuItem separatorItem] atIndex:1]; - [menu addItemWithTitle:NSLocalizedString(@"Open in New Tab", @"open connection in new tab context menu item") action:@selector(openDatabaseInNewTab:) keyEquivalent:@""]; - - return [menu autorelease]; -} - -/** - * When tab drags start, show all the tab bars. This allows adding tabs to windows - * containing only one tab - where the bar is normally hidden. - */ -- (void)tabDragStarted:(id)sender -{ - [tabBar setHideForSingleTab:NO]; -} - -/** - * When tab drags stop, set tab bars to automatically hide again for only one tab. - */ -- (void)tabDragStopped:(id)sender -{ - if (![[NSUserDefaults standardUserDefaults] boolForKey:SPAlwaysShowWindowTabBar]) { - [tabBar setHideForSingleTab:YES]; - } -} - -#pragma mark - -#pragma mark Window delegate methods - -/** - * Determine whether the window is permitted to close. - * Go through the tabs in this window, and ask the database connection view - * in each one if it can be closed, returning YES only if all can be closed. - */ -- (BOOL)windowShouldClose:(id)sender -{ - - // Iterate through all tabs if more than one tab is opened only otherwise - // [... parentTabShouldClose] will be called twice [see self closeTab:(id)sender] - if([[tabView tabViewItems] count] > 1) - for (NSTabViewItem *eachItem in [tabView tabViewItems]) { - SPDatabaseDocument *eachDocument = [eachItem identifier]; - if (![eachDocument parentTabShouldClose]) return NO; - } - - // Remove global session data if the last window of a session will be closed - if([[NSApp delegate] sessionURL] && [[[NSApp delegate] orderedDatabaseConnectionWindows] count] == 1) { - [[NSApp delegate] setSessionURL:nil]; - [[NSApp delegate] setSpfSessionDocData:nil]; - } - - return YES; -} - -/** - * When the window does close, close all tabs. - */ -- (void)windowWillClose:(NSNotification *)notification - -{ - for (NSTabViewItem *eachItem in [tabView tabViewItems]) { - [tabView removeTabViewItem:eachItem]; - } - [self autorelease]; -} - -/** - * When the window becomes key, inform the selected tab and - * update menu items. - */ -- (void)windowDidBecomeKey:(NSNotification *)notification -{ - [selectedTableDocument tabDidBecomeKey]; - - // Update the "Close window" item - [closeWindowMenuItem setTitle:NSLocalizedString(@"Close Window", @"Close Window menu item")]; - [closeWindowMenuItem setKeyEquivalentModifierMask:(NSCommandKeyMask | NSShiftKeyMask)]; - - // Ensure the "Close tab" item is enabled and has the standard shortcut - [closeTabMenuItem setEnabled:YES]; - [closeTabMenuItem setKeyEquivalent:@"w"]; - [closeTabMenuItem setKeyEquivalentModifierMask:NSCommandKeyMask]; -} - -/** - * When the window resigns key, update menu items. - */ -- (void)windowDidResignKey:(NSNotification *)notification -{ - // Disable the "Close tab" menu item - [closeTabMenuItem setEnabled:NO]; - [closeTabMenuItem setKeyEquivalent:@""]; - - // Update the "Close window" item to show only "Close" - [closeWindowMenuItem setTitle:NSLocalizedString(@"Close", @"Close menu item")]; - [closeWindowMenuItem setKeyEquivalentModifierMask:NSCommandKeyMask]; -} - -/** - * If the window is resized, notify all the tabs. - */ -- (void)windowDidResize:(NSNotification *)notification -{ - for (NSTabViewItem *eachItem in [tabView tabViewItems]) { - SPDatabaseDocument *eachDocument = [eachItem identifier]; - [eachDocument tabDidResize]; - } -} - -/** - * If the window is entering fullscreen, update the front tab's titlebar status view visibility. - */ -- (void)windowWillEnterFullScreen:(NSNotification *)notification -{ - [selectedTableDocument updateTitlebarStatusVisibilityForcingHide:YES]; -} - -/** - * If the window exits fullscreen, update the front tab's titlebar status view visibility. - */ -- (void)windowDidExitFullScreen:(NSNotification *)notification -{ - [selectedTableDocument updateTitlebarStatusVisibilityForcingHide:NO]; -} - -#pragma mark - #pragma mark First responder forwarding to active tab /** |