diff options
104 files changed, 1687 insertions, 5290 deletions
diff --git a/Frameworks/PSMTabBar/PSMRolloverButton.h b/Frameworks/PSMTabBar/PSMRolloverButton.h index 9f339a50..5a2ac368 100644 --- a/Frameworks/PSMTabBar/PSMRolloverButton.h +++ b/Frameworks/PSMTabBar/PSMRolloverButton.h @@ -24,11 +24,11 @@ - (nullable NSImage *)rolloverImage; // tracking rect for mouse events -- (void)rolloverFrameDidChange:(nonnull NSNotification *)inNotification; +- (void)rolloverFrameDidChange:(nonnull NSNotification *)notification; - (void)addTrackingRect; - (void)removeTrackingRect; -- (void)mouseEntered:(nullable NSEvent *)theEvent; -- (void)mouseExited:(nullable NSEvent *)theEvent; +- (void)mouseEntered:(nullable NSEvent *)event; +- (void)mouseExited:(nullable NSEvent *)event; @end diff --git a/Frameworks/PSMTabBar/PSMRolloverButton.m b/Frameworks/PSMTabBar/PSMRolloverButton.m index 4ded63b7..975ff296 100644 --- a/Frameworks/PSMTabBar/PSMRolloverButton.m +++ b/Frameworks/PSMTabBar/PSMRolloverButton.m @@ -20,6 +20,7 @@ selector:@selector(rolloverFrameDidChange:) name:NSViewFrameDidChangeNotification object:self]; + [self setPostsFrameChangedNotifications:YES]; [self resetCursorRects]; @@ -28,17 +29,6 @@ _usualImage = nil; } -- (void)dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - [self removeTrackingRect]; - [_rolloverImage release]; - [_usualImage release]; - - [super dealloc]; -} - // the regular image - (void)setUsualImage:(NSImage *)newImage { @@ -66,7 +56,7 @@ return _rolloverImage; } -//Remove old tracking rects when we change superviews +// Remove old tracking rects when we change superviews - (void)viewWillMoveToSuperview:(NSView *)newSuperview { [self removeTrackingRect]; @@ -95,7 +85,7 @@ [self resetCursorRects]; } -- (void)rolloverFrameDidChange:(NSNotification *)inNotification +- (void)rolloverFrameDidChange:(NSNotification *)notification { [self resetCursorRects]; } @@ -104,15 +94,18 @@ { // assign a tracking rect to watch for mouse enter/exit NSRect trackRect = [self bounds]; - NSPoint localPoint = [self convertPoint:[[self window] convertScreenToBase:[NSEvent mouseLocation]] - fromView:nil]; - BOOL mouseInside = NSPointInRect(localPoint, trackRect); + NSPoint localPoint = [self convertPoint:[[self window] convertScreenToBase:[NSEvent mouseLocation]] fromView:nil]; + + BOOL mouseInside = NSPointInRect(localPoint, trackRect); _myTrackingRectTag = [self addTrackingRect:trackRect owner:self userData:nil assumeInside:mouseInside]; - if (mouseInside) + + if (mouseInside) { [self mouseEntered:nil]; - else + } + else { [self mouseExited:nil]; + } } - (void)removeTrackingRect @@ -120,24 +113,25 @@ if (_myTrackingRectTag != -1) { [self removeTrackingRect:_myTrackingRectTag]; } + _myTrackingRectTag = -1; } // override for rollover effect -- (void)mouseEntered:(nullable NSEvent *)theEvent +- (void)mouseEntered:(nullable NSEvent *)event { // set rollover image [self setImage:_rolloverImage]; - [super mouseEntered:theEvent]; + [super mouseEntered:event]; } -- (void)mouseExited:(nullable NSEvent *)theEvent +- (void)mouseExited:(nullable NSEvent *)event { // restore usual image [self setImage:_usualImage]; - [super mouseExited:theEvent]; + [super mouseExited:event]; } - (void)resetCursorRects @@ -162,26 +156,42 @@ #pragma mark - #pragma mark Archiving -- (void)encodeWithCoder:(NSCoder *)aCoder { - [super encodeWithCoder:aCoder]; - if ([aCoder allowsKeyedCoding]) { - [aCoder encodeObject:_rolloverImage forKey:@"rolloverImage"]; - [aCoder encodeObject:_usualImage forKey:@"usualImage"]; - [aCoder encodeInteger:_myTrackingRectTag forKey:@"myTrackingRectTag"]; +- (void)encodeWithCoder:(NSCoder *)coder +{ + [super encodeWithCoder:coder]; + + if ([coder allowsKeyedCoding]) { + [coder encodeObject:_rolloverImage forKey:@"rolloverImage"]; + [coder encodeObject:_usualImage forKey:@"usualImage"]; + [coder encodeInteger:_myTrackingRectTag forKey:@"myTrackingRectTag"]; } } -- (id)initWithCoder:(NSCoder *)aDecoder { - self = [super initWithCoder:aDecoder]; - if (self) { - if ([aDecoder allowsKeyedCoding]) { - _rolloverImage = [[aDecoder decodeObjectForKey:@"rolloverImage"] retain]; - _usualImage = [[aDecoder decodeObjectForKey:@"usualImage"] retain]; - _myTrackingRectTag = [aDecoder decodeIntegerForKey:@"myTrackingRectTag"]; +- (id)initWithCoder:(NSCoder *)decoder +{ + if ((self = [super initWithCoder:decoder])) { + if ([decoder allowsKeyedCoding]) { + _rolloverImage = [[decoder decodeObjectForKey:@"rolloverImage"] retain]; + _usualImage = [[decoder decodeObjectForKey:@"usualImage"] retain]; + _myTrackingRectTag = [decoder decodeIntegerForKey:@"myTrackingRectTag"]; } } + return self; } +#pragma mark - + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [self removeTrackingRect]; + + [_rolloverImage release]; + [_usualImage release]; + + [super dealloc]; +} @end diff --git a/Frameworks/PSMTabBar/PSMTabBarCell.m b/Frameworks/PSMTabBar/PSMTabBarCell.m index 80fe4ec0..fb869f47 100644 --- a/Frameworks/PSMTabBar/PSMTabBarCell.m +++ b/Frameworks/PSMTabBar/PSMTabBarCell.m @@ -432,8 +432,11 @@ [image lockFocusFlipped:YES]; #endif [self setFrame:tabDrawFrame]; - [(id <PSMTabStyle>)[(PSMTabBarControl *)_customControlView style] drawTabCell:self]; + + [(id <PSMTabStyle>)[(PSMTabBarControl *)_customControlView style] drawTabCellForDragImage:self]; + [self setFrame:oldFrame]; + [image unlockFocus]; // Add the indicator if appropriate diff --git a/Frameworks/PSMTabBar/PSMTabBarControl.h b/Frameworks/PSMTabBar/PSMTabBarControl.h index ad9de748..dee4ed8a 100644 --- a/Frameworks/PSMTabBar/PSMTabBarControl.h +++ b/Frameworks/PSMTabBar/PSMTabBarControl.h @@ -15,13 +15,16 @@ #define PSMTabDragDidEndNotification @"PSMTabDragDidEndNotification" #define PSMTabDragDidBeginNotification @"PSMTabDragDidBeginNotification" -#define kPSMTabBarControlHeight 34 +#define kPSMTabBarControlHeight 25 #define kPSMTabBarControlDefaultHeightCollapsed 0 // can be changed with a property + // internal cell border #define MARGIN_X 6 -#define MARGIN_Y 5 +#define MARGIN_Y 6 + // padding between objects #define kPSMTabBarCellPadding 4 + // fixed size objects #define kPSMMinimumTitleWidth 30 #define kPSMTabBarIndicatorWidth 16.0f @@ -48,13 +51,13 @@ typedef enum { } PSMTabBarTearOffStyle; enum { - PSMTab_SelectedMask = 1 << 1, - PSMTab_LeftIsSelectedMask = 1 << 2, - PSMTab_RightIsSelectedMask = 1 << 3, + PSMTab_SelectedMask = 1 << 1, + PSMTab_LeftIsSelectedMask = 1 << 2, + PSMTab_RightIsSelectedMask = 1 << 3, PSMTab_PositionLeftMask = 1 << 4, - PSMTab_PositionMiddleMask = 1 << 5, - PSMTab_PositionRightMask = 1 << 6, - PSMTab_PositionSingleMask = 1 << 7 + PSMTab_PositionMiddleMask = 1 << 5, + PSMTab_PositionRightMask = 1 << 6, + PSMTab_PositionSingleMask = 1 << 7 }; @interface PSMTabBarControl : NSControl { diff --git a/Frameworks/PSMTabBar/PSMTabBarControl.m b/Frameworks/PSMTabBar/PSMTabBarControl.m index 18b5a296..3e3c1e30 100644 --- a/Frameworks/PSMTabBar/PSMTabBarControl.m +++ b/Frameworks/PSMTabBar/PSMTabBarControl.m @@ -11,11 +11,6 @@ #import "PSMOverflowPopUpButton.h" #import "PSMRolloverButton.h" #import "PSMTabStyle.h" -#import "PSMMetalTabStyle.h" -#import "PSMAquaTabStyle.h" -#import "PSMUnifiedTabStyle.h" -#import "PSMCardTabStyle.h" -#import "PSMAdiumTabStyle.h" #import "PSMSequelProTabStyle.h" #import "PSMTabDragAssistant.h" #import "PSMTabBarController.h" @@ -161,6 +156,7 @@ // new tab button NSRect addTabButtonRect = NSMakeRect([self frame].size.width - [style rightMarginForTabBarControl] + 1, 3.0f, 16.0f, 16.0f); _addTabButton = [[PSMRolloverButton alloc] initWithFrame:addTabButtonRect]; + if (_addTabButton) { NSImage *newButtonImage = [style addTabButtonImage]; if (newButtonImage) { @@ -369,31 +365,16 @@ - (void)setStyleNamed:(NSString *)name { id <PSMTabStyle> newStyle; - -/* if ([name isEqualToString:@"Aqua"]) { - newStyle = [[PSMAquaTabStyle alloc] init]; - - } else if ([name isEqualToString:@"Unified"]) { - newStyle = [[PSMUnifiedTabStyle alloc] init]; - - } else if ([name isEqualToString:@"Adium"]) { - newStyle = [[PSMAdiumTabStyle alloc] init]; - - } else if ([name isEqualToString:@"Card"]) { - newStyle = [[PSMCardTabStyle alloc] init]; - - } else if ([name isEqualToString:@"Metal"]) { - newStyle = [[PSMMetalTabStyle alloc] init]; - } else */ if ([name isEqualToString:@"SequelPro"]) { newStyle = [[PSMSequelProTabStyle alloc] init]; - - } else { + } + else { newStyle = [[PSMSequelProTabStyle alloc] init]; } [self setStyle:newStyle]; + [newStyle release]; } diff --git a/Frameworks/PSMTabBar/PSMTabBarController.m b/Frameworks/PSMTabBar/PSMTabBarController.m index eddf4174..53f11c63 100644 --- a/Frameworks/PSMTabBar/PSMTabBarController.m +++ b/Frameworks/PSMTabBar/PSMTabBarController.m @@ -214,7 +214,7 @@ _addButtonRect.size = [[_control addTabButton] frame].size; if ([_control orientation] == PSMTabBarHorizontalOrientation) { _addButtonRect.origin.y = MARGIN_Y; - _addButtonRect.origin.x += [[cellWidths valueForKeyPath:@"@sum.floatValue"] floatValue] + MARGIN_X; + _addButtonRect.origin.x += [[cellWidths valueForKeyPath:@"@sum.floatValue"] floatValue] + MARGIN_X; } else { _addButtonRect.origin.x = 0; _addButtonRect.origin.y = [[cellWidths lastObject] floatValue]; diff --git a/Frameworks/PSMTabBar/PSMTabDragView.m b/Frameworks/PSMTabBar/PSMTabDragView.m index 5be56b10..aa066d86 100644 --- a/Frameworks/PSMTabBar/PSMTabDragView.m +++ b/Frameworks/PSMTabBar/PSMTabDragView.m @@ -34,7 +34,9 @@ srcRect.size = [_image size]; [_image drawInRect:[self bounds] fromRect:srcRect operation:NSCompositeSourceOver fraction:primaryAlpha]; + srcRect.size = [_alternateImage size]; + [_alternateImage drawInRect:[self bounds] fromRect:srcRect operation:NSCompositeSourceOver fraction:alternateAlpha]; } diff --git a/Frameworks/PSMTabBar/PSMTabStyle.h b/Frameworks/PSMTabBar/PSMTabStyle.h index 23c826fa..0688c8a9 100644 --- a/Frameworks/PSMTabBar/PSMTabStyle.h +++ b/Frameworks/PSMTabBar/PSMTabStyle.h @@ -7,8 +7,10 @@ // /* -Protocol to be observed by all style delegate objects. These objects handle the drawing responsibilities for PSMTabBarCell; once the control has been assigned a style, the background and cells draw consistent with that style. Design pattern and implementation by David Smith, Seth Willits, and Chris Forsythe, all touch up and errors by John P. :-) -*/ + * Protocol to be observed by all style delegate objects. + * These objects handle the drawing responsibilities for PSMTabBarCell; once the control has been assigned a style, the background and cells draw consistent with that style. + * Design pattern and implementation by David Smith, Seth Willits, and Chris Forsythe, all touch up and errors by John P. :-) + */ #import "PSMTabBarCell.h" #import "PSMTabBarControl.h" @@ -45,6 +47,7 @@ Protocol to be observed by all style delegate objects. These objects handle the // drawing - (void)drawTabCell:(PSMTabBarCell *)cell; +- (void)drawTabCellForDragImage:(PSMTabBarCell *)cell; - (void)drawBackgroundInRect:(NSRect)rect; - (void)drawTabBar:(PSMTabBarControl *)bar inRect:(NSRect)rect; diff --git a/Frameworks/PSMTabBar/Styles/PSMAdiumTabStyle.h b/Frameworks/PSMTabBar/Styles/PSMAdiumTabStyle.h deleted file mode 100644 index fac9a427..00000000 --- a/Frameworks/PSMTabBar/Styles/PSMAdiumTabStyle.h +++ /dev/null @@ -1,39 +0,0 @@ -// -// PSMAdiumTabStyle.h -// PSMTabBarControl -// -// Created by Kent Sutherland on 5/26/06. -// Copyright 2006 Kent Sutherland. All rights reserved. -// - -#import <Cocoa/Cocoa.h> -#import "PSMTabStyle.h" - -@interface PSMAdiumTabStyle : NSObject <PSMTabStyle> -{ - NSImage *_closeButton, *_closeButtonDown, *_closeButtonOver; - NSImage *_closeDirtyButton, *_closeDirtyButtonDown, *_closeDirtyButtonOver; - NSImage *_addTabButtonImage, *_addTabButtonPressedImage, *_addTabButtonRolloverImage; - NSImage *_gradientImage; - - NSDictionary *_objectCountStringAttributes; - - PSMTabBarOrientation orientation; - PSMTabBarControl *tabBar; - - BOOL _drawsUnified, _drawsRight; -} - -- (void)loadImages; - -- (BOOL)drawsUnified; -- (void)setDrawsUnified:(BOOL)value; -- (BOOL)drawsRight; -- (void)setDrawsRight:(BOOL)value; - -- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView*)controlView; - -- (void)encodeWithCoder:(NSCoder *)aCoder; -- (id)initWithCoder:(NSCoder *)aDecoder; - -@end diff --git a/Frameworks/PSMTabBar/Styles/PSMAdiumTabStyle.m b/Frameworks/PSMTabBar/Styles/PSMAdiumTabStyle.m deleted file mode 100644 index be14707d..00000000 --- a/Frameworks/PSMTabBar/Styles/PSMAdiumTabStyle.m +++ /dev/null @@ -1,1050 +0,0 @@ -// -// PSMAdiumTabStyle.m -// PSMTabBarControl -// -// Created by Kent Sutherland on 5/26/06. -// Copyright 2006 Kent Sutherland. All rights reserved. -// - -#import "PSMAdiumTabStyle.h" -#import "PSMTabBarCell.h" -#import "PSMTabBarControl.h" -#import "NSBezierPath_AMShading.h" - -#define Adium_CellPadding 2 -#define Adium_MARGIN_X 4 -#define kPSMAdiumCounterPadding 3.0 -#define kPSMAdiumObjectCounterRadius 7.0 -#define kPSMAdiumCounterMinWidth 20 - -#define kPSMTabBarControlSourceListHeight 28 - -#define kPSMTabBarLargeImageHeight kPSMTabBarControlSourceListHeight - 4 -#define kPSMTabBarLargeImageWidth kPSMTabBarLargeImageHeight - -@implementation PSMAdiumTabStyle - -- (NSString *)name -{ - return @"Adium"; -} - -#pragma mark - -#pragma mark Creation/Destruction - -- (id)init -{ - if ( (self = [super init]) ) { - [self loadImages]; - _drawsUnified = NO; - _drawsRight = NO; - - _objectCountStringAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:[[NSFontManager sharedFontManager] convertFont:[NSFont fontWithName:@"Helvetica" size:11.0] toHaveTrait:NSBoldFontMask], NSFontAttributeName, - [[NSColor whiteColor] colorWithAlphaComponent:0.85], NSForegroundColorAttributeName, - nil, nil]; - } - return self; -} - -- (void)loadImages -{ - _closeButton = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front"]]; - _closeButtonDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front_Pressed"]]; - _closeButtonOver = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front_Rollover"]]; - - _closeDirtyButton = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabCloseDirty_Front"]]; - _closeDirtyButtonDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabCloseDirty_Front_Pressed"]]; - _closeDirtyButtonOver = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabCloseDirty_Front_Rollover"]]; - - _addTabButtonImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNew"]]; - _addTabButtonPressedImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNewPressed"]]; - _addTabButtonRolloverImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNewRollover"]]; - - _gradientImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AdiumGradient"]]; -} - -- (void)dealloc -{ - [_closeButton release]; - [_closeButtonDown release]; - [_closeButtonOver release]; - - [_closeDirtyButton release]; - [_closeDirtyButtonDown release]; - [_closeDirtyButtonOver release]; - - [_addTabButtonImage release]; - [_addTabButtonPressedImage release]; - [_addTabButtonRolloverImage release]; - - [_gradientImage release]; - - [_objectCountStringAttributes release]; - - [super dealloc]; -} - -#pragma mark - -#pragma mark Drawing Style Accessors - -- (BOOL)drawsUnified -{ - return _drawsUnified; -} - -- (void)setDrawsUnified:(BOOL)value -{ - _drawsUnified = value; -} - -- (BOOL)drawsRight -{ - return _drawsRight; -} - -- (void)setDrawsRight:(BOOL)value -{ - _drawsRight = value; -} - -#pragma mark - -#pragma mark Control Specific - -- (CGFloat)leftMarginForTabBarControl -{ - return 3.0f; -} - -- (CGFloat)rightMarginForTabBarControl -{ - return 24.0f; -} - -- (CGFloat)topMarginForTabBarControl -{ - return 10.0f; -} - -- (void)setOrientation:(PSMTabBarOrientation)value -{ - orientation = value; -} - -#pragma mark - -#pragma mark Add Tab Button - -- (NSImage *)addTabButtonImage -{ - return _addTabButtonImage; -} - -- (NSImage *)addTabButtonPressedImage -{ - return _addTabButtonPressedImage; -} - -- (NSImage *)addTabButtonRolloverImage -{ - return _addTabButtonRolloverImage; -} - -#pragma mark - -#pragma mark Cell Specific - -- (NSRect)dragRectForTabCell:(PSMTabBarCell *)cell orientation:(PSMTabBarOrientation)tabOrientation -{ - NSRect dragRect = [cell frame]; - - if ([cell tabState] & PSMTab_SelectedMask) { - if (tabOrientation == PSMTabBarHorizontalOrientation) { - dragRect.size.width++; - dragRect.size.height -= 2.0; - } - } - - return dragRect; -} - -- (BOOL)closeButtonIsEnabledForCell:(PSMTabBarCell *)cell -{ - return ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]); - -} -- (NSRect)closeButtonRectForTabCell:(PSMTabBarCell *)cell withFrame:(NSRect)cellFrame -{ - if ([self closeButtonIsEnabledForCell:cell] == NO) { - return NSZeroRect; - } - - NSRect result; - result.size = [_closeButton size]; - - switch (orientation) { - case PSMTabBarHorizontalOrientation: - { - result.origin.x = cellFrame.origin.x + Adium_MARGIN_X; - result.origin.y = cellFrame.origin.y + MARGIN_Y + 2.0; - if ([cell state] == NSOnState) { - result.origin.y -= 1; - } - break; - } - - case PSMTabBarVerticalOrientation: - { - result.origin.x = NSMaxX(cellFrame) - (Adium_MARGIN_X*2) - NSWidth(result); - result.origin.y = NSMinY(cellFrame) + (NSHeight(cellFrame) / 2) - (result.size.height / 2) + 1; - break; - } - } - - return result; -} - -- (NSRect)iconRectForTabCell:(PSMTabBarCell *)cell -{ - if ([cell hasIcon] == NO) { - return NSZeroRect; - } - - NSRect cellFrame = [cell frame]; - NSImage *icon = [[[cell representedObject] identifier] icon]; - NSSize iconSize = [icon size]; - - NSRect result; - result.size = iconSize; - - switch (orientation) - { - case PSMTabBarHorizontalOrientation: - result.origin.x = cellFrame.origin.x + Adium_MARGIN_X; - result.origin.y = cellFrame.origin.y + MARGIN_Y; - break; - - case PSMTabBarVerticalOrientation: - result.origin.x = NSMaxX(cellFrame) - (Adium_MARGIN_X * 2) - NSWidth(result); - result.origin.y = NSMinY(cellFrame) + (NSHeight(cellFrame) / 2) - (NSHeight(result) / 2) + 1; - break; - } - - // For horizontal tabs, center in available space (in case icon image is smaller than kPSMTabBarIconWidth) - if (orientation == PSMTabBarHorizontalOrientation) { - if (iconSize.width < kPSMTabBarIconWidth) - result.origin.x += (kPSMTabBarIconWidth - iconSize.width) / 2.0; - if (iconSize.height < kPSMTabBarIconWidth) - result.origin.y += (kPSMTabBarIconWidth - iconSize.height) / 2.0; - } - - if ([cell state] == NSOnState) { - result.origin.y -= 1; - } - - return result; -} - -- (NSRect)indicatorRectForTabCell:(PSMTabBarCell *)cell -{ - NSRect cellFrame = [cell frame]; - - if ([[cell indicator] isHidden]) { - return NSZeroRect; - } - - NSRect result; - result.size = NSMakeSize(kPSMTabBarIndicatorWidth, kPSMTabBarIndicatorWidth); - result.origin.x = cellFrame.origin.x + cellFrame.size.width - Adium_MARGIN_X - kPSMTabBarIndicatorWidth; - result.origin.y = cellFrame.origin.y + MARGIN_Y; - - if ([cell state] == NSOnState) { - result.origin.y -= 1; - } - - return result; -} - -- (NSSize)sizeForObjectCounterRectForTabCell:(PSMTabBarCell *)cell -{ - NSSize size; - CGFloat countWidth = [[self attributedObjectCountValueForTabCell:cell] size].width; - - countWidth += (2 * kPSMAdiumObjectCounterRadius - 6.0 + kPSMAdiumCounterPadding); - - if (countWidth < kPSMAdiumCounterMinWidth) { - countWidth = kPSMAdiumCounterMinWidth; - } - - size = NSMakeSize(countWidth, 2 * kPSMAdiumObjectCounterRadius); // temp - - return size; -} - -- (NSRect)objectCounterRectForTabCell:(PSMTabBarCell *)cell -{ - NSRect cellFrame; - NSRect result; - - if ([cell count] == 0) { - return NSZeroRect; - } - - cellFrame = [cell frame]; - result.size = [self sizeForObjectCounterRectForTabCell:cell]; - result.origin.x = NSMaxX(cellFrame) - Adium_MARGIN_X - result.size.width; - result.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; - - if (![[cell indicator] isHidden]) { - result.origin.x -= kPSMTabBarIndicatorWidth + Adium_CellPadding; - } - - return result; -} - -- (CGFloat)minimumWidthOfTabCell:(PSMTabBarCell *)cell -{ - CGFloat resultWidth = 0.0; - - // left margin - resultWidth = Adium_MARGIN_X; - - // close button? - if ([self closeButtonIsEnabledForCell:cell]) { - resultWidth += MAX([_closeButton size].width, NSWidth([self iconRectForTabCell:cell])) + Adium_CellPadding; - } - - // icon? - /*if ([cell hasIcon]) { - resultWidth += kPSMTabBarIconWidth + Adium_CellPadding; - }*/ - - // the label - resultWidth += kPSMMinimumTitleWidth; - - // object counter? - if (([cell count] > 0) && (orientation == PSMTabBarHorizontalOrientation)) { - resultWidth += NSWidth([self objectCounterRectForTabCell:cell]) + Adium_CellPadding; - } - - // indicator? - if ([[cell indicator] isHidden] == NO) { - resultWidth += Adium_CellPadding + kPSMTabBarIndicatorWidth; - } - - // right margin - resultWidth += Adium_MARGIN_X; - - return ceil(resultWidth); -} - -- (CGFloat)desiredWidthOfTabCell:(PSMTabBarCell *)cell -{ - CGFloat resultWidth = 0.0; - - // left margin - resultWidth = Adium_MARGIN_X; - - // close button? - if ([self closeButtonIsEnabledForCell:cell]) { - resultWidth += MAX([_closeButton size].width, NSWidth([self iconRectForTabCell:cell])) + Adium_CellPadding; - } - - // icon? - /*if ([cell hasIcon]) { - resultWidth += kPSMTabBarIconWidth + Adium_CellPadding; - }*/ - - // the label - resultWidth += [[cell attributedStringValue] size].width + Adium_CellPadding; - - // object counter? - if (([cell count] > 0) && (orientation == PSMTabBarHorizontalOrientation)){ - resultWidth += [self objectCounterRectForTabCell:cell].size.width + Adium_CellPadding; - } - - // indicator? - if ([[cell indicator] isHidden] == NO) { - resultWidth += Adium_CellPadding + kPSMTabBarIndicatorWidth; - } - - // right margin - resultWidth += Adium_MARGIN_X; - - return ceil(resultWidth); -} - -- (CGFloat)tabCellHeight -{ - return ((orientation == PSMTabBarHorizontalOrientation) ? kPSMTabBarControlHeight : kPSMTabBarControlSourceListHeight); -} - -#pragma mark - -#pragma mark Cell Values - -- (NSAttributedString *)attributedObjectCountValueForTabCell:(PSMTabBarCell *)cell -{ - NSString *contents = [NSString stringWithFormat:@"%lu", (unsigned long)[cell count]]; - return [[[NSMutableAttributedString alloc] initWithString:contents attributes:_objectCountStringAttributes] autorelease]; -} - -- (NSAttributedString *)attributedStringValueForTabCell:(PSMTabBarCell *)cell -{ - NSMutableAttributedString *attrStr; - NSString *contents = [cell stringValue]; - attrStr = [[[NSMutableAttributedString alloc] initWithString:contents] autorelease]; - NSRange range = NSMakeRange(0, [contents length]); - - // Add font attribute - [attrStr addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:11.0] range:range]; - [attrStr addAttribute:NSForegroundColorAttributeName value:[NSColor controlTextColor] range:range]; - - // Paragraph Style for Truncating Long Text - static NSMutableParagraphStyle *TruncatingTailParagraphStyle = nil; - if (!TruncatingTailParagraphStyle) { - TruncatingTailParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; - [TruncatingTailParagraphStyle setLineBreakMode:NSLineBreakByTruncatingTail]; - } - [attrStr addAttribute:NSParagraphStyleAttributeName value:TruncatingTailParagraphStyle range:range]; - - return attrStr; -} - -#pragma mark - -#pragma mark Cell Drawing - -- (CGFloat)heightOfAttributedString:(NSAttributedString *)inAttributedString withWidth:(CGFloat)width -{ - static NSMutableDictionary *cache; - if (!cache) - cache = [[NSMutableDictionary alloc] init]; - if ([cache count] > 100) //100 items should be trivial in terms of memory overhead, but sufficient - [cache removeAllObjects]; - NSNumber *cachedHeight = [cache objectForKey:inAttributedString]; - if (cachedHeight) - return [cachedHeight doubleValue]; - else { - NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:inAttributedString]; - NSTextContainer *textContainer = [[NSTextContainer alloc] initWithContainerSize:NSMakeSize(width, 1e7)]; - NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; - - //Configure - [textContainer setLineFragmentPadding:0.0]; - [layoutManager addTextContainer:textContainer]; - [textStorage addLayoutManager:layoutManager]; - - //Force the layout manager to layout its text - (void)[layoutManager glyphRangeForTextContainer:textContainer]; - - CGFloat height = [layoutManager usedRectForTextContainer:textContainer].size.height; - - [textStorage release]; - [textContainer release]; - [layoutManager release]; - - [cache setObject:[NSNumber numberWithDouble:height] forKey:inAttributedString]; - - return height; - } -} - -- (void)drawObjectCounterInCell:(PSMTabBarCell *)cell withRect:(NSRect)myRect -{ - myRect.size.width -= kPSMAdiumCounterPadding; - myRect.origin.x += kPSMAdiumCounterPadding; - - [[cell countColor] ?: [NSColor colorWithCalibratedWhite:0.3 alpha:0.6] set]; - NSBezierPath *path = [NSBezierPath bezierPath]; - [path setLineWidth:1.0]; - - if ([cell state] == NSOnState) { - myRect.origin.y -= 1.0; - } - - [path moveToPoint:NSMakePoint(NSMinX(myRect) + kPSMAdiumObjectCounterRadius, NSMinY(myRect))]; - [path lineToPoint:NSMakePoint(NSMaxX(myRect) - kPSMAdiumObjectCounterRadius, NSMinY(myRect))]; - [path appendBezierPathWithArcWithCenter:NSMakePoint(NSMaxX(myRect) - kPSMAdiumObjectCounterRadius, NSMinY(myRect) + kPSMAdiumObjectCounterRadius) - radius:kPSMAdiumObjectCounterRadius - startAngle:270.0 - endAngle:90.0]; - [path lineToPoint:NSMakePoint(NSMinX(myRect) + kPSMAdiumObjectCounterRadius, NSMaxY(myRect))]; - [path appendBezierPathWithArcWithCenter:NSMakePoint(NSMinX(myRect) + kPSMAdiumObjectCounterRadius, NSMinY(myRect) + kPSMAdiumObjectCounterRadius) - radius:kPSMAdiumObjectCounterRadius - startAngle:90.0 - endAngle:270.0]; - [path fill]; - - // draw attributed string centered in area - NSRect counterStringRect; - NSAttributedString *counterString = [self attributedObjectCountValueForTabCell:cell]; - counterStringRect.size = [counterString size]; - counterStringRect.origin.x = myRect.origin.x + ((myRect.size.width - counterStringRect.size.width) / 2.0) + 0.25; - counterStringRect.origin.y = myRect.origin.y + ((myRect.size.height - counterStringRect.size.height) / 2.0) + 0.5; - [counterString drawInRect:counterStringRect]; -} - -- (NSBezierPath *)bezierPathWithRoundedRect:(NSRect)rect radius:(CGFloat)radius -{ - NSBezierPath *path = [NSBezierPath bezierPath]; - NSPoint topLeft, topRight, bottomLeft, bottomRight; - - topLeft = NSMakePoint(rect.origin.x, rect.origin.y); - topRight = NSMakePoint(rect.origin.x + rect.size.width, rect.origin.y); - bottomLeft = NSMakePoint(rect.origin.x, rect.origin.y + rect.size.height); - bottomRight = NSMakePoint(rect.origin.x + rect.size.width, rect.origin.y + rect.size.height); - - [path appendBezierPathWithArcWithCenter:NSMakePoint(topLeft.x + radius, topLeft.y + radius) - radius:radius - startAngle:180 - endAngle:270 - clockwise:NO]; - [path lineToPoint:NSMakePoint(topRight.x - radius, topRight.y)]; - - [path appendBezierPathWithArcWithCenter:NSMakePoint(topRight.x - radius, topRight.y + radius) - radius:radius - startAngle:270 - endAngle:0 - clockwise:NO]; - [path lineToPoint:NSMakePoint(bottomRight.x, bottomRight.y - radius)]; - - [path appendBezierPathWithArcWithCenter:NSMakePoint(bottomRight.x - radius, bottomRight.y - radius) - radius:radius - startAngle:0 - endAngle:90 - clockwise:NO]; - [path lineToPoint:NSMakePoint(bottomLeft.x + radius, bottomLeft.y)]; - - [path appendBezierPathWithArcWithCenter:NSMakePoint(bottomLeft.x + radius, bottomLeft.y - radius) - radius:radius - startAngle:90 - endAngle:180 - clockwise:NO]; - [path lineToPoint:NSMakePoint(topLeft.x, topLeft.y + radius)]; - - return path; -} - -- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView*)controlView -{ - NSRect cellFrame = [cell frame]; - - if ((orientation == PSMTabBarVerticalOrientation) && - [cell hasLargeImage]) { - NSImage *image = [[[cell representedObject] identifier] largeImage]; - cellFrame.origin.x += Adium_MARGIN_X; - - NSRect imageDrawingRect = NSMakeRect(cellFrame.origin.x, - cellFrame.origin.y - ((kPSMTabBarControlSourceListHeight - kPSMTabBarLargeImageHeight) / 2), - kPSMTabBarLargeImageWidth, kPSMTabBarLargeImageHeight); - - [NSGraphicsContext saveGraphicsState]; - //Use a transform to draw an arbitrary image in our flipped view - NSAffineTransform *transform = [NSAffineTransform transform]; - [transform translateXBy:imageDrawingRect.origin.x yBy:(imageDrawingRect.origin.y + imageDrawingRect.size.height)]; - [transform scaleXBy:1.0 yBy:-1.0]; - [transform concat]; - - imageDrawingRect.origin = NSMakePoint(0,0); - - //Create Rounding. - CGFloat userIconRoundingRadius = (kPSMTabBarLargeImageWidth / 4.0); - if (userIconRoundingRadius > 3) userIconRoundingRadius = 3; - NSBezierPath *clipPath = [self bezierPathWithRoundedRect:imageDrawingRect radius:userIconRoundingRadius]; - [clipPath addClip]; - - [image drawInRect:imageDrawingRect - fromRect:NSMakeRect(0, 0, [image size].width, [image size].height) - operation:NSCompositeSourceOver - fraction:1.0]; - - [NSGraphicsContext restoreGraphicsState]; - - cellFrame.origin.x += imageDrawingRect.size.width; - cellFrame.size.width -= imageDrawingRect.size.width; - } - - // label rect - NSRect labelRect; - labelRect.origin.x = cellFrame.origin.x + Adium_MARGIN_X; - labelRect.size.width = cellFrame.size.width - (labelRect.origin.x - cellFrame.origin.x) - Adium_CellPadding; - labelRect.size.height = cellFrame.size.height; - switch (orientation) - { - case PSMTabBarHorizontalOrientation: - labelRect.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; - break; - case PSMTabBarVerticalOrientation: - labelRect.origin.y = cellFrame.origin.y; - break; - } - - if ([self closeButtonIsEnabledForCell:cell]) { - /* The close button and the icon (if present) are drawn combined, changing on-hover */ - NSRect closeButtonRect = [cell closeButtonRectForFrame:cellFrame]; - NSRect iconRect = [self iconRectForTabCell:cell]; - NSRect drawingRect; - NSImage *closeButtonOrIcon = nil; - - if ([cell hasIcon]) { - /* If the cell has an icon and a close button, determine which rect should be used and use it consistently - * This only matters for horizontal tabs; vertical tabs look fine without making this adjustment. - */ - if (NSWidth(iconRect) > NSWidth(closeButtonRect)) { - closeButtonRect.origin.x = NSMinX(iconRect) + NSWidth(iconRect)/2 - NSWidth(closeButtonRect)/2; - } - } - - if ([cell closeButtonPressed]) { - closeButtonOrIcon = ([cell isEdited] ? _closeDirtyButtonDown : _closeButtonDown); - drawingRect = closeButtonRect; - - } else if ([cell closeButtonOver]) { - closeButtonOrIcon = ([cell isEdited] ? _closeDirtyButtonOver : _closeButtonOver); - drawingRect = closeButtonRect; - - } else if ((orientation == PSMTabBarVerticalOrientation) && - ([cell count] > 0)) { - /* In vertical tabs, the count indicator supercedes the icon */ - NSSize counterSize = [self sizeForObjectCounterRectForTabCell:cell]; - if (counterSize.width > NSWidth(closeButtonRect)) { - closeButtonRect.origin.x -= (counterSize.width - NSWidth(closeButtonRect)); - closeButtonRect.size.width = counterSize.width; - } - - closeButtonRect.origin.y = cellFrame.origin.y + ((NSHeight(cellFrame) - counterSize.height) / 2); - closeButtonRect.size.height = counterSize.height; - - drawingRect = closeButtonRect; - [self drawObjectCounterInCell:cell withRect:drawingRect]; - /* closeButtonOrIcon == nil */ - - } else if ([cell hasIcon]) { - closeButtonOrIcon = [[[cell representedObject] identifier] icon]; - drawingRect = iconRect; - - } else { - closeButtonOrIcon = ([cell isEdited] ? _closeDirtyButton : _closeButton); - drawingRect = closeButtonRect; - } - - [closeButtonOrIcon drawInRect:drawingRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f respectFlipped:YES hints:nil]; - - // scoot label over - switch (orientation) - { - case PSMTabBarHorizontalOrientation: - { - CGFloat oldOrigin = labelRect.origin.x; - if (NSWidth(iconRect) > NSWidth(closeButtonRect)) { - labelRect.origin.x = (NSMaxX(iconRect) + (Adium_CellPadding * 2)); - } else { - labelRect.origin.x = (NSMaxX(closeButtonRect) + (Adium_CellPadding * 2)); - } - labelRect.size.width -= (NSMinX(labelRect) - oldOrigin); - break; - } - case PSMTabBarVerticalOrientation: - { - //Generate the remaining label rect directly from the location of the close button, allowing for padding - if (NSWidth(iconRect) > NSWidth(closeButtonRect)) { - labelRect.size.width = NSMinX(iconRect) - Adium_CellPadding - NSMinX(labelRect); - } else { - labelRect.size.width = NSMinX(closeButtonRect) - Adium_CellPadding - NSMinX(labelRect); - } - - break; - } - } - - } else if ([cell hasIcon]) { - /* The close button is disabled; the cell has an icon */ - NSRect iconRect = [self iconRectForTabCell:cell]; - NSImage *icon = [[[cell representedObject] identifier] icon]; - - [icon drawInRect:iconRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f respectFlipped:YES hints:nil]; - - // scoot label over by the size of the standard close button - switch (orientation) - { - case PSMTabBarHorizontalOrientation: - labelRect.origin.x += (NSWidth(iconRect) + Adium_CellPadding); - labelRect.size.width -= (NSWidth(iconRect) + Adium_CellPadding); - break; - case PSMTabBarVerticalOrientation: - labelRect.size.width -= (NSWidth(iconRect) + Adium_CellPadding); - break; - } - } - - if ([cell state] == NSOnState) { - labelRect.origin.y -= 1; - } - - if (![[cell indicator] isHidden]) { - labelRect.size.width -= (kPSMTabBarIndicatorWidth + Adium_CellPadding); - } - - // object counter - //The object counter takes up space horizontally... - if (([cell count] > 0) && - (orientation == PSMTabBarHorizontalOrientation)) { - NSRect counterRect = [self objectCounterRectForTabCell:cell]; - - [self drawObjectCounterInCell:cell withRect:counterRect]; - labelRect.size.width -= NSWidth(counterRect) + Adium_CellPadding; - } - - // draw label - NSAttributedString *attributedString = [cell attributedStringValue]; - if (orientation == PSMTabBarVerticalOrientation) { - //Calculate the centered rect - CGFloat stringHeight = [self heightOfAttributedString:attributedString withWidth:NSWidth(labelRect)]; - if (stringHeight < labelRect.size.height) { - labelRect.origin.y += (NSHeight(labelRect) - stringHeight) / 2.0; - } - } - - [attributedString drawInRect:labelRect]; -} - -- (void)drawTabCell:(PSMTabBarCell *)cell -{ - NSRect cellFrame = [cell frame]; - NSColor *lineColor = nil; - NSBezierPath *bezier = [NSBezierPath bezierPath]; - lineColor = [NSColor grayColor]; - - [bezier setLineWidth:1.0]; - - //disable antialiasing of bezier paths - [NSGraphicsContext saveGraphicsState]; - [[NSGraphicsContext currentContext] setShouldAntialias:NO]; - - NSShadow *shadow = [[NSShadow alloc] init]; - [shadow setShadowOffset:NSMakeSize(-2, -2)]; - [shadow setShadowBlurRadius:2]; - [shadow setShadowColor:[NSColor colorWithCalibratedWhite:0.6 alpha:1.0]]; - - if ([cell state] == NSOnState) { - // selected tab - if (orientation == PSMTabBarHorizontalOrientation) { - NSRect aRect = NSMakeRect(cellFrame.origin.x, cellFrame.origin.y, NSWidth(cellFrame), cellFrame.size.height - 2.5); - - // background - if (_drawsUnified) { - if ([[[tabBar tabView] window] isKeyWindow]) { - NSBezierPath *path = [NSBezierPath bezierPathWithRect:aRect]; - [path linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.835 alpha:1.0] - endColor:[NSColor colorWithCalibratedWhite:0.843 alpha:1.0]]; - } else { - [[NSColor windowBackgroundColor] set]; - NSRectFill(aRect); - } - } else { - [_gradientImage drawInRect:NSMakeRect(NSMinX(aRect), NSMinY(aRect), NSWidth(aRect), NSHeight(aRect)) fromRect:NSMakeRect(0, 0, [_gradientImage size].width, [_gradientImage size].height) operation:NSCompositeSourceOver fraction:1.0]; - } - - // frame - [lineColor set]; - [bezier setLineWidth:1.0]; - [bezier moveToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y)]; - [bezier lineToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y + aRect.size.height)]; - - [shadow setShadowOffset:NSMakeSize(-2, -2)]; - [shadow set]; - [bezier stroke]; - - bezier = [NSBezierPath bezierPath]; - [bezier setLineWidth:1.0]; - [bezier moveToPoint:NSMakePoint(NSMinX(aRect), NSMaxY(aRect))]; - [bezier lineToPoint:NSMakePoint(NSMaxX(aRect), NSMaxY(aRect))]; - [bezier lineToPoint:NSMakePoint(NSMaxX(aRect), NSMinY(aRect))]; - - if ([[cell customControlView] frame].size.height < 2) { - // special case of hidden control; need line across top of cell - [bezier moveToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y + 0.5)]; - [bezier lineToPoint:NSMakePoint(aRect.origin.x+aRect.size.width, aRect.origin.y + 0.5)]; - } - - [shadow setShadowOffset:NSMakeSize(2, -2)]; - [shadow set]; - [bezier stroke]; - } else { - NSRect aRect; - - if (_drawsRight) { - aRect = NSMakeRect(cellFrame.origin.x - 1, cellFrame.origin.y, cellFrame.size.width - 3, cellFrame.size.height); - } else { - aRect = NSMakeRect(cellFrame.origin.x + 2, cellFrame.origin.y, cellFrame.size.width - 2, cellFrame.size.height); - } - - // background - if (_drawsUnified) { - if ([[[tabBar tabView] window] isKeyWindow]) { - NSBezierPath *path = [NSBezierPath bezierPathWithRect:aRect]; - [path linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.835 alpha:1.0] - endColor:[NSColor colorWithCalibratedWhite:0.843 alpha:1.0]]; - } else { - [[NSColor windowBackgroundColor] set]; - NSRectFill(aRect); - } - } else { - NSBezierPath *path = [NSBezierPath bezierPathWithRect:aRect]; - if (_drawsRight) { - [path linearVerticalGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.92 alpha:1.0] - endColor:[NSColor colorWithCalibratedWhite:0.98 alpha:1.0]]; - } else { - [path linearVerticalGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.98 alpha:1.0] - endColor:[NSColor colorWithCalibratedWhite:0.92 alpha:1.0]]; - } - } - - // frame - //top line - [lineColor set]; - [bezier setLineWidth:1.0]; - [bezier moveToPoint:NSMakePoint(NSMinX(aRect), NSMinY(aRect))]; - [bezier lineToPoint:NSMakePoint(NSMaxX(aRect), NSMinY(aRect))]; - [bezier stroke]; - - //outer edge and bottom lines - bezier = [NSBezierPath bezierPath]; - [bezier setLineWidth:1.0]; - if (_drawsRight) { - //Right - [bezier moveToPoint:NSMakePoint(NSMaxX(aRect), NSMinY(aRect))]; - [bezier lineToPoint:NSMakePoint(NSMaxX(aRect), NSMaxY(aRect))]; - //Bottom - [bezier lineToPoint:NSMakePoint(NSMinX(aRect), NSMaxY(aRect))]; - } else { - //Left - [bezier moveToPoint:NSMakePoint(NSMinX(aRect), NSMinY(aRect))]; - [bezier lineToPoint:NSMakePoint(NSMinX(aRect), NSMaxY(aRect))]; - //Bottom - [bezier lineToPoint:NSMakePoint(NSMaxX(aRect), NSMaxY(aRect))]; - } - [shadow setShadowOffset:NSMakeSize((_drawsRight ? 2 : -2), -2)]; - [shadow set]; - [bezier stroke]; - } - } else { - // unselected tab - NSRect aRect = NSMakeRect(cellFrame.origin.x, cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height); - - // rollover - if ([cell isHighlighted]) { - [[NSColor colorWithCalibratedWhite:0.0 alpha:0.1] set]; - NSRectFillUsingOperation(aRect, NSCompositeSourceAtop); - } - - // frame - [lineColor set]; - - if (orientation == PSMTabBarHorizontalOrientation) { - [bezier moveToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y)]; - [bezier lineToPoint:NSMakePoint(aRect.origin.x + aRect.size.width, aRect.origin.y)]; - if (!([cell tabState] & PSMTab_RightIsSelectedMask)) { - //draw the tab divider - [bezier lineToPoint:NSMakePoint(aRect.origin.x + aRect.size.width, aRect.origin.y + aRect.size.height)]; - } - [bezier stroke]; - - } else { - //No outline for vertical - } - } - - [NSGraphicsContext restoreGraphicsState]; - [shadow release]; - - [self drawInteriorWithTabCell:cell inView:[cell customControlView]]; -} - -- (void)drawBackgroundInRect:(NSRect)rect -{ - //Draw for our whole bounds; it'll be automatically clipped to fit the appropriate drawing area - rect = [tabBar bounds]; - - switch (orientation) { - case PSMTabBarHorizontalOrientation: - if (_drawsUnified && [[[tabBar tabView] window] isKeyWindow]) { - if ([[[tabBar tabView] window] isKeyWindow]) { - NSBezierPath *backgroundPath = [NSBezierPath bezierPathWithRect:rect]; - [backgroundPath linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.835 alpha:1.0] - endColor:[NSColor colorWithCalibratedWhite:0.843 alpha:1.0]]; - } else { - [[NSColor windowBackgroundColor] set]; - NSRectFill(rect); - } - } else { - [[NSColor colorWithCalibratedWhite:0.85 alpha:0.6] set]; - [NSBezierPath fillRect:rect]; - } - break; - - case PSMTabBarVerticalOrientation: - //This is the Mail.app source list background color... which differs from the iTunes one. - [[NSColor colorWithCalibratedRed:.9059 - green:.9294 - blue:.9647 - alpha:1.0] set]; - NSRectFill(rect); - break; - } - - //Draw the border and shadow around the tab bar itself - [NSGraphicsContext saveGraphicsState]; - [[NSGraphicsContext currentContext] setShouldAntialias:NO]; - - NSShadow *shadow = [[NSShadow alloc] init]; - [shadow setShadowBlurRadius:2]; - [shadow setShadowColor:[NSColor colorWithCalibratedWhite:0.6 alpha:1.0]]; - - [[NSColor grayColor] set]; - - NSBezierPath *path = [NSBezierPath bezierPath]; - [path setLineWidth:1.0]; - - switch (orientation) { - case PSMTabBarHorizontalOrientation: - { - rect.origin.y++; - [path moveToPoint:NSMakePoint(rect.origin.x, rect.origin.y)]; - [path lineToPoint:NSMakePoint(rect.origin.x + rect.size.width, rect.origin.y)]; - [shadow setShadowOffset:NSMakeSize(2, -2)]; - - [shadow set]; - [path stroke]; - - break; - } - - case PSMTabBarVerticalOrientation: - { - NSPoint startPoint, endPoint; - NSSize shadowOffset; - - //Draw vertical shadow - if (_drawsRight) { - startPoint = NSMakePoint(NSMinX(rect), NSMinY(rect)); - endPoint = NSMakePoint(NSMinX(rect), NSMaxY(rect)); - shadowOffset = NSMakeSize(2, -2); - } else { - startPoint = NSMakePoint(NSMaxX(rect) - 1, NSMinY(rect)); - endPoint = NSMakePoint(NSMaxX(rect) - 1, NSMaxY(rect)); - shadowOffset = NSMakeSize(-2, -2); - } - - [path moveToPoint:startPoint]; - [path lineToPoint:endPoint]; - [shadow setShadowOffset:shadowOffset]; - - [shadow set]; - [path stroke]; - - [path removeAllPoints]; - - //Draw top horizontal shadow - startPoint = NSMakePoint(NSMinX(rect), NSMinY(rect)); - endPoint = NSMakePoint(NSMaxX(rect), NSMinY(rect)); - shadowOffset = NSMakeSize(0, -1); - - [path moveToPoint:startPoint]; - [path lineToPoint:endPoint]; - [shadow setShadowOffset:shadowOffset]; - - [shadow set]; - [path stroke]; - - break; - } - } - - [shadow release]; - [NSGraphicsContext restoreGraphicsState]; -} - -- (void)drawTabBar:(PSMTabBarControl *)bar inRect:(NSRect)rect -{ - if (orientation != [bar orientation]) { - orientation = [bar orientation]; - } - - if (tabBar != bar) { - [tabBar release]; - tabBar = [bar retain]; - } - - [self drawBackgroundInRect:rect]; - - // no tab view == not connected - if (![bar tabView]) { - NSRect labelRect = rect; - labelRect.size.height -= 4.0; - labelRect.origin.y += 4.0; - NSMutableAttributedString *attrStr; - NSString *contents = @"PSMTabBarControl"; - attrStr = [[[NSMutableAttributedString alloc] initWithString:contents] autorelease]; - NSRange range = NSMakeRange(0, [contents length]); - [attrStr addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:11.0] range:range]; - NSMutableParagraphStyle *centeredParagraphStyle = nil; - - if (!centeredParagraphStyle) { - centeredParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; - [centeredParagraphStyle setAlignment:NSCenterTextAlignment]; - } - - [attrStr addAttribute:NSParagraphStyleAttributeName value:centeredParagraphStyle range:range]; - [centeredParagraphStyle release]; - [attrStr drawInRect:labelRect]; - return; - } - - // draw cells - NSEnumerator *e = [[bar cells] objectEnumerator]; - PSMTabBarCell *cell; - while ( (cell = [e nextObject]) ) { - if ([bar isAnimating] || (![cell isInOverflowMenu] && NSIntersectsRect([cell frame], rect))) { - [cell drawWithFrame:[cell frame] inView:bar]; - } - } -} - -#pragma mark - -#pragma mark Archiving - -- (void)encodeWithCoder:(NSCoder *)aCoder -{ - if ([aCoder allowsKeyedCoding]) { - [aCoder encodeObject:_closeButton forKey:@"closeButton"]; - [aCoder encodeObject:_closeButtonDown forKey:@"closeButtonDown"]; - [aCoder encodeObject:_closeButtonOver forKey:@"closeButtonOver"]; - [aCoder encodeObject:_closeDirtyButton forKey:@"closeDirtyButton"]; - [aCoder encodeObject:_closeDirtyButtonDown forKey:@"closeDirtyButtonDown"]; - [aCoder encodeObject:_closeDirtyButtonOver forKey:@"closeDirtyButtonOver"]; - [aCoder encodeObject:_addTabButtonImage forKey:@"addTabButtonImage"]; - [aCoder encodeObject:_addTabButtonPressedImage forKey:@"addTabButtonPressedImage"]; - [aCoder encodeObject:_addTabButtonRolloverImage forKey:@"addTabButtonRolloverImage"]; - [aCoder encodeBool:_drawsUnified forKey:@"drawsUnified"]; - [aCoder encodeBool:_drawsRight forKey:@"drawsRight"]; - } -} - -- (id)initWithCoder:(NSCoder *)aDecoder -{ - if ( (self = [super init]) ) { - if ([aDecoder allowsKeyedCoding]) { - _closeButton = [[aDecoder decodeObjectForKey:@"closeButton"] retain]; - _closeButtonDown = [[aDecoder decodeObjectForKey:@"closeButtonDown"] retain]; - _closeButtonOver = [[aDecoder decodeObjectForKey:@"closeButtonOver"] retain]; - _closeDirtyButton = [[aDecoder decodeObjectForKey:@"closeDirtyButton"] retain]; - _closeDirtyButtonDown = [[aDecoder decodeObjectForKey:@"closeDirtyButtonDown"] retain]; - _closeDirtyButtonOver = [[aDecoder decodeObjectForKey:@"closeDirtyButtonOver"] retain]; - _addTabButtonImage = [[aDecoder decodeObjectForKey:@"addTabButtonImage"] retain]; - _addTabButtonPressedImage = [[aDecoder decodeObjectForKey:@"addTabButtonPressedImage"] retain]; - _addTabButtonRolloverImage = [[aDecoder decodeObjectForKey:@"addTabButtonRolloverImage"] retain]; - _drawsUnified = [aDecoder decodeBoolForKey:@"drawsUnified"]; - _drawsRight = [aDecoder decodeBoolForKey:@"drawsRight"]; - } - } - return self; -} - -@end diff --git a/Frameworks/PSMTabBar/Styles/PSMAquaTabStyle.h b/Frameworks/PSMTabBar/Styles/PSMAquaTabStyle.h deleted file mode 100644 index d3448e41..00000000 --- a/Frameworks/PSMTabBar/Styles/PSMAquaTabStyle.h +++ /dev/null @@ -1,38 +0,0 @@ -// -// PSMAquaTabStyle.h -// PSMTabBarControl -// -// Created by John Pannell on 2/17/06. -// Copyright 2006 Positive Spin Media. All rights reserved. -// - -#import <Cocoa/Cocoa.h> -#import "PSMTabStyle.h" - -@interface PSMAquaTabStyle : NSObject <PSMTabStyle> { - NSImage *aquaTabBg; - NSImage *aquaTabBgDown; - NSImage *aquaTabBgDownGraphite; - NSImage *aquaTabBgDownNonKey; - NSImage *aquaDividerDown; - NSImage *aquaDivider; - NSImage *aquaCloseButton; - NSImage *aquaCloseButtonDown; - NSImage *aquaCloseButtonOver; - NSImage *aquaCloseDirtyButton; - NSImage *aquaCloseDirtyButtonDown; - NSImage *aquaCloseDirtyButtonOver; - NSImage *_addTabButtonImage; - NSImage *_addTabButtonPressedImage; - NSImage *_addTabButtonRolloverImage; - - NSDictionary *_objectCountStringAttributes; - PSMTabBarControl *tabBar; -} - -- (void)loadImages; -- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView*)controlView; - -- (void)encodeWithCoder:(NSCoder *)aCoder; -- (id)initWithCoder:(NSCoder *)aDecoder; -@end diff --git a/Frameworks/PSMTabBar/Styles/PSMAquaTabStyle.m b/Frameworks/PSMTabBar/Styles/PSMAquaTabStyle.m deleted file mode 100644 index a96724c0..00000000 --- a/Frameworks/PSMTabBar/Styles/PSMAquaTabStyle.m +++ /dev/null @@ -1,573 +0,0 @@ -// -// PSMAquaTabStyle.m -// PSMTabBarControl -// -// Created by John Pannell on 2/17/06. -// Copyright 2006 Positive Spin Media. All rights reserved. -// - -#import "PSMAquaTabStyle.h" -#import "PSMTabBarCell.h" -#import "PSMTabBarControl.h" - -#define kPSMAquaObjectCounterRadius 7.0 -#define kPSMAquaCounterMinWidth 20 - -@implementation PSMAquaTabStyle - -- (NSString *)name -{ - return @"Aqua"; -} - -#pragma mark - -#pragma mark Creation/Destruction - -- (id) init -{ - if ( (self = [super init]) ) { - [self loadImages]; - - _objectCountStringAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:[[NSFontManager sharedFontManager] convertFont:[NSFont fontWithName:@"Helvetica" size:11.0] toHaveTrait:NSBoldFontMask], NSFontAttributeName, - [[NSColor whiteColor] colorWithAlphaComponent:0.85], NSForegroundColorAttributeName, - nil, nil]; - } - return self; -} - -- (void) loadImages -{ - // Aqua Tabs Images - aquaTabBg = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabsBackground"]]; - [aquaTabBg setFlipped:YES]; - - aquaTabBgDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabsDown"]]; - [aquaTabBgDown setFlipped:YES]; - - aquaTabBgDownGraphite = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabsDownGraphite"]]; - [aquaTabBgDown setFlipped:YES]; - - aquaTabBgDownNonKey = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabsDownNonKey"]]; - [aquaTabBgDown setFlipped:YES]; - - aquaDividerDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabsSeparatorDown"]]; - [aquaDivider setFlipped:NO]; - - aquaDivider = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabsSeparator"]]; - [aquaDivider setFlipped:NO]; - - aquaCloseButton = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front"]]; - aquaCloseButtonDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front_Pressed"]]; - aquaCloseButtonOver = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front_Rollover"]]; - - aquaCloseDirtyButton = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabCloseDirty_Front"]]; - aquaCloseDirtyButtonDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabCloseDirty_Front_Pressed"]]; - aquaCloseDirtyButtonOver = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabCloseDirty_Front_Rollover"]]; - - _addTabButtonImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNew"]]; - _addTabButtonPressedImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNewPressed"]]; - _addTabButtonRolloverImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNewRollover"]]; -} - -- (void)dealloc -{ - [aquaTabBg release]; - [aquaTabBgDown release]; - [aquaDividerDown release]; - [aquaDivider release]; - [aquaCloseButton release]; - [aquaCloseButtonDown release]; - [aquaCloseButtonOver release]; - [aquaCloseDirtyButton release]; - [aquaCloseDirtyButtonDown release]; - [aquaCloseDirtyButtonOver release]; - [_addTabButtonImage release]; - [_addTabButtonPressedImage release]; - [_addTabButtonRolloverImage release]; - - [_objectCountStringAttributes release]; - - [super dealloc]; -} - -#pragma mark - -#pragma mark Control Specifics - -- (CGFloat)leftMarginForTabBarControl -{ - return 0.0f; -} - -- (CGFloat)rightMarginForTabBarControl -{ - return 24.0f; -} - -- (CGFloat)topMarginForTabBarControl -{ - return 0.0f; -} - -- (void)setOrientation:(PSMTabBarOrientation)value -{ - -} - -#pragma mark - -#pragma mark Add Tab Button - -- (NSImage *)addTabButtonImage -{ - return _addTabButtonImage; -} - -- (NSImage *)addTabButtonPressedImage -{ - return _addTabButtonPressedImage; -} - -- (NSImage *)addTabButtonRolloverImage -{ - return _addTabButtonRolloverImage; -} - -#pragma mark - -#pragma mark Cell Specifics - -- (NSRect)dragRectForTabCell:(PSMTabBarCell *)cell orientation:(PSMTabBarOrientation)orientation -{ - return [cell frame]; -} - -- (NSRect)closeButtonRectForTabCell:(PSMTabBarCell *)cell withFrame:(NSRect)cellFrame -{ - if ([cell hasCloseButton] == NO) { - return NSZeroRect; - } - - NSRect result; - result.size = [aquaCloseButton size]; - result.origin.x = cellFrame.origin.x + MARGIN_X; - result.origin.y = cellFrame.origin.y + MARGIN_Y + 2.0; - - return result; -} - -- (NSRect)iconRectForTabCell:(PSMTabBarCell *)cell -{ - NSRect cellFrame = [cell frame]; - - if ([cell hasIcon] == NO) { - return NSZeroRect; - } - - NSRect result; - result.size = NSMakeSize(kPSMTabBarIconWidth, kPSMTabBarIconWidth); - result.origin.x = cellFrame.origin.x + MARGIN_X; - result.origin.y = cellFrame.origin.y + MARGIN_Y; - - if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { - result.origin.x += [aquaCloseButton size].width + kPSMTabBarCellPadding; - } - - return result; -} - -- (NSRect)indicatorRectForTabCell:(PSMTabBarCell *)cell -{ - NSRect cellFrame = [cell frame]; - - if ([[cell indicator] isHidden]) { - return NSZeroRect; - } - - NSRect result; - result.size = NSMakeSize(kPSMTabBarIndicatorWidth, kPSMTabBarIndicatorWidth); - result.origin.x = cellFrame.origin.x + cellFrame.size.width - MARGIN_X - kPSMTabBarIndicatorWidth; - result.origin.y = cellFrame.origin.y + MARGIN_Y; - - return result; -} - -- (NSRect)objectCounterRectForTabCell:(PSMTabBarCell *)cell -{ - NSRect cellFrame = [cell frame]; - - if ([cell count] == 0) { - return NSZeroRect; - } - - CGFloat countWidth = [[self attributedObjectCountValueForTabCell:cell] size].width; - countWidth += (2 * kPSMAquaObjectCounterRadius - 6.0); - if (countWidth < kPSMAquaCounterMinWidth) { - countWidth = kPSMAquaCounterMinWidth; - } - - NSRect result; - result.size = NSMakeSize(countWidth, 2 * kPSMAquaObjectCounterRadius); // temp - result.origin.x = cellFrame.origin.x + cellFrame.size.width - MARGIN_X - result.size.width; - result.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; - - if (![[cell indicator] isHidden]) { - result.origin.x -= kPSMTabBarIndicatorWidth + kPSMTabBarCellPadding; - } - - return result; -} - -- (CGFloat)minimumWidthOfTabCell:(PSMTabBarCell *)cell -{ - CGFloat resultWidth = 0.0; - - // left margin - resultWidth = MARGIN_X; - - // close button? - if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) - resultWidth += [aquaCloseButton size].width + kPSMTabBarCellPadding; - - // icon? - if ([cell hasIcon]) { - resultWidth += kPSMTabBarIconWidth + kPSMTabBarCellPadding; - } - - // the label - resultWidth += kPSMMinimumTitleWidth; - - // object counter? - if ([cell count] > 0) { - resultWidth += [self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding; - } - - // indicator? - if ([[cell indicator] isHidden] == NO) { - resultWidth += kPSMTabBarCellPadding + kPSMTabBarIndicatorWidth; - } - - // right margin - resultWidth += MARGIN_X; - - return ceil(resultWidth); -} - -- (CGFloat)desiredWidthOfTabCell:(PSMTabBarCell *)cell -{ - CGFloat resultWidth = 0.0; - - // left margin - resultWidth = MARGIN_X; - - // close button? - if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { - resultWidth += [aquaCloseButton size].width + kPSMTabBarCellPadding; - } - - // icon? - if ([cell hasIcon]) { - resultWidth += kPSMTabBarIconWidth + kPSMTabBarCellPadding; - } - - // the label - resultWidth += [[cell attributedStringValue] size].width; - - // object counter? - if ([cell count] > 0) { - resultWidth += [self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding; - } - - // indicator? - if ([[cell indicator] isHidden] == NO) { - resultWidth += kPSMTabBarCellPadding + kPSMTabBarIndicatorWidth; - } - - // right margin - resultWidth += MARGIN_X; - - return ceil(resultWidth); -} - -- (CGFloat)tabCellHeight -{ - return kPSMTabBarControlHeight; -} - -#pragma mark - -#pragma mark Cell Values - -- (NSAttributedString *)attributedObjectCountValueForTabCell:(PSMTabBarCell *)cell -{ - NSString *contents = [NSString stringWithFormat:@"%lu", (unsigned long)[cell count]]; - return [[[NSMutableAttributedString alloc] initWithString:contents attributes:_objectCountStringAttributes] autorelease]; -} - -- (NSAttributedString *)attributedStringValueForTabCell:(PSMTabBarCell *)cell -{ - NSMutableAttributedString *attrStr; - NSString * contents = [cell stringValue]; - attrStr = [[[NSMutableAttributedString alloc] initWithString:contents] autorelease]; - NSRange range = NSMakeRange(0, [contents length]); - - [attrStr addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:11.0] range:range]; - - // Paragraph Style for Truncating Long Text - static NSMutableParagraphStyle *TruncatingTailParagraphStyle = nil; - if (!TruncatingTailParagraphStyle) { - TruncatingTailParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; - [TruncatingTailParagraphStyle setLineBreakMode:NSLineBreakByTruncatingTail]; - [TruncatingTailParagraphStyle setAlignment:NSCenterTextAlignment]; - } - [attrStr addAttribute:NSParagraphStyleAttributeName value:TruncatingTailParagraphStyle range:range]; - - return attrStr; -} - -#pragma mark - -#pragma mark Drawing - -- (void)drawTabCell:(PSMTabBarCell *)cell; -{ - NSRect cellFrame = [cell frame]; - - // Selected Tab - if ([cell state] == NSOnState) { - NSRect aRect = NSMakeRect(cellFrame.origin.x, cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height-2.5); - aRect.size.height -= 0.5; - - // proper tint - NSControlTint currentTint; - if ([cell controlTint] == NSDefaultControlTint) - currentTint = [NSColor currentControlTint]; - else - currentTint = [cell controlTint]; - - if (![[[cell customControlView] window] isKeyWindow]) - currentTint = NSClearControlTint; - - NSImage *bgImage; - switch (currentTint) { - case NSGraphiteControlTint: - bgImage = aquaTabBgDownGraphite; - break; - case NSClearControlTint: - bgImage = aquaTabBgDownNonKey; - break; - case NSBlueControlTint: - default: - bgImage = aquaTabBgDown; - break; - } - - [bgImage drawInRect:cellFrame fromRect:NSMakeRect(0.0, 0.0, 1.0, 22.0) operation:NSCompositeSourceOver fraction:1.0]; - [aquaDivider compositeToPoint:NSMakePoint(cellFrame.origin.x + cellFrame.size.width - 1.0, cellFrame.origin.y + cellFrame.size.height) operation:NSCompositeSourceOver]; - - aRect.size.height+=0.5; - - } else { // Unselected Tab - - NSRect aRect = NSMakeRect(cellFrame.origin.x, cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height); - aRect.origin.y += 0.5; - aRect.origin.x += 1.5; - aRect.size.width -= 1; - - aRect.origin.x -= 1; - aRect.size.width += 1; - - // Rollover - if ([cell isHighlighted]) { - [[NSColor colorWithCalibratedWhite:0.0 alpha:0.1] set]; - NSRectFillUsingOperation(aRect, NSCompositeSourceAtop); - } - - [aquaDivider compositeToPoint:NSMakePoint(cellFrame.origin.x + cellFrame.size.width - 1.0, cellFrame.origin.y + cellFrame.size.height) operation:NSCompositeSourceOver]; - } - - [self drawInteriorWithTabCell:cell inView:[cell customControlView]]; -} - -- (void)drawBackgroundInRect:(NSRect)rect -{ - if (rect.size.height <= 22.0) { - //Draw for our whole bounds; it'll be automatically clipped to fit the appropriate drawing area - rect = [tabBar bounds]; - - [aquaTabBg drawInRect:rect fromRect:NSMakeRect(0.0, 0.0, 1.0, 22.0) operation:NSCompositeSourceOver fraction:1.0]; - } -} - -- (void)drawTabBar:(PSMTabBarControl *)bar inRect:(NSRect)rect -{ - if (tabBar != bar) { - tabBar = bar; - } - - [self drawBackgroundInRect:rect]; - - // no tab view == not connected - if (![bar tabView]) { - NSRect labelRect = rect; - labelRect.size.height -= 4.0; - labelRect.origin.y += 4.0; - NSMutableAttributedString *attrStr; - NSString *contents = @"PSMTabBarControl"; - attrStr = [[[NSMutableAttributedString alloc] initWithString:contents] autorelease]; - NSRange range = NSMakeRange(0, [contents length]); - [attrStr addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:11.0] range:range]; - NSMutableParagraphStyle *centeredParagraphStyle = nil; - if (!centeredParagraphStyle) { - centeredParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; - [centeredParagraphStyle setAlignment:NSCenterTextAlignment]; - } - [attrStr addAttribute:NSParagraphStyleAttributeName value:centeredParagraphStyle range:range]; - [centeredParagraphStyle release]; - [attrStr drawInRect:labelRect]; - return; - } - - // Draw cells - NSEnumerator *e = [[bar cells] objectEnumerator]; - PSMTabBarCell *cell; - while ( (cell = [e nextObject]) ) { - if ([bar isAnimating] || (![cell isInOverflowMenu] && NSIntersectsRect([cell frame], rect))) { - [cell drawWithFrame:[cell frame] inView:bar]; - } - } -} - -- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView*)controlView -{ - NSRect cellFrame = [cell frame]; - CGFloat labelPosition = cellFrame.origin.x + MARGIN_X; - - // close button - if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { - NSSize closeButtonSize = NSZeroSize; - NSRect closeButtonRect = [cell closeButtonRectForFrame:cellFrame]; - NSImage *closeButton = nil; - - closeButton = [cell isEdited] ? aquaCloseDirtyButton : aquaCloseButton; - - if ([cell closeButtonOver]) closeButton = [cell isEdited] ? aquaCloseDirtyButtonOver : aquaCloseButtonOver; - if ([cell closeButtonPressed]) closeButton = [cell isEdited] ? aquaCloseDirtyButtonDown : aquaCloseButtonDown; - - closeButtonSize = [closeButton size]; - - [closeButton drawInRect:closeButtonRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f respectFlipped:YES hints:nil]; - - // scoot label over - labelPosition += closeButtonSize.width + kPSMTabBarCellPadding; - } - - // icon - if ([cell hasIcon]) { - NSRect iconRect = [self iconRectForTabCell:cell]; - NSImage *icon = [[[cell representedObject] identifier] icon]; - - // center in available space (in case icon image is smaller than kPSMTabBarIconWidth) - if ([icon size].width < kPSMTabBarIconWidth) { - iconRect.origin.x += (kPSMTabBarIconWidth - [icon size].width) / 2.0; - } - - if ([icon size].height < kPSMTabBarIconWidth) { - iconRect.origin.y -= (kPSMTabBarIconWidth - [icon size].height) / 2.0; - } - - [icon drawInRect:iconRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f respectFlipped:YES hints:nil]; - - // scoot label over - labelPosition += iconRect.size.width + kPSMTabBarCellPadding; - } - - // label rect - NSRect labelRect; - labelRect.origin.x = labelPosition; - labelRect.size.width = cellFrame.size.width - (labelRect.origin.x - cellFrame.origin.x) - kPSMTabBarCellPadding; - labelRect.size.height = cellFrame.size.height; - labelRect.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; - - if (![[cell indicator] isHidden]) { - labelRect.size.width -= (kPSMTabBarIndicatorWidth + kPSMTabBarCellPadding); - } - - // object counter - if ([cell count] > 0) { - [[cell countColor] ?: [NSColor colorWithCalibratedWhite:0.3 alpha:0.45] set]; - NSBezierPath *path = [NSBezierPath bezierPath]; - NSRect myRect = [self objectCounterRectForTabCell:cell]; - [path moveToPoint:NSMakePoint(myRect.origin.x + kPSMAquaObjectCounterRadius, myRect.origin.y)]; - [path lineToPoint:NSMakePoint(myRect.origin.x + myRect.size.width - kPSMAquaObjectCounterRadius, myRect.origin.y)]; - [path appendBezierPathWithArcWithCenter:NSMakePoint(myRect.origin.x + myRect.size.width - kPSMAquaObjectCounterRadius, myRect.origin.y + kPSMAquaObjectCounterRadius) radius:kPSMAquaObjectCounterRadius startAngle:270.0 endAngle:90.0]; - [path lineToPoint:NSMakePoint(myRect.origin.x + kPSMAquaObjectCounterRadius, myRect.origin.y + myRect.size.height)]; - [path appendBezierPathWithArcWithCenter:NSMakePoint(myRect.origin.x + kPSMAquaObjectCounterRadius, myRect.origin.y + kPSMAquaObjectCounterRadius) radius:kPSMAquaObjectCounterRadius startAngle:90.0 endAngle:270.0]; - [path fill]; - - // draw attributed string centered in area - NSRect counterStringRect; - NSAttributedString *counterString = [self attributedObjectCountValueForTabCell:cell]; - counterStringRect.size = [counterString size]; - counterStringRect.origin.x = myRect.origin.x + ((myRect.size.width - counterStringRect.size.width) / 2.0) + 0.25; - counterStringRect.origin.y = myRect.origin.y + ((myRect.size.height - counterStringRect.size.height) / 2.0) + 0.5; - [counterString drawInRect:counterStringRect]; - - labelRect.size.width -= myRect.size.width + kPSMTabBarCellPadding; - } - - // Draw Label - [[cell attributedStringValue] drawInRect:labelRect]; -} - -#pragma mark - -#pragma mark Archiving - -- (void)encodeWithCoder:(NSCoder *)aCoder { - - //[super encodeWithCoder:aCoder]; -/* - if ([aCoder allowsKeyedCoding]) { - [aCoder encodeObject:aquaTabBg forKey:@"aquaTabBg"]; - [aCoder encodeObject:aquaTabBgDown forKey:@"aquaTabBgDown"]; - [aCoder encodeObject:aquaTabBgDownGraphite forKey:@"aquaTabBgDownGraphite"]; - [aCoder encodeObject:aquaTabBgDownNonKey forKey:@"aquaTabBgDownNonKey"]; - [aCoder encodeObject:aquaDividerDown forKey:@"aquaDividerDown"]; - [aCoder encodeObject:aquaDivider forKey:@"aquaDivider"]; - [aCoder encodeObject:aquaCloseButton forKey:@"aquaCloseButton"]; - [aCoder encodeObject:aquaCloseButtonDown forKey:@"aquaCloseButtonDown"]; - [aCoder encodeObject:aquaCloseButtonOver forKey:@"aquaCloseButtonOver"]; - [aCoder encodeObject:aquaCloseDirtyButton forKey:@"aquaCloseDirtyButton"]; - [aCoder encodeObject:aquaCloseDirtyButtonDown forKey:@"aquaCloseDirtyButtonDown"]; - [aCoder encodeObject:aquaCloseDirtyButtonOver forKey:@"aquaCloseDirtyButtonOver"]; - [aCoder encodeObject:_addTabButtonImage forKey:@"addTabButtonImage"]; - [aCoder encodeObject:_addTabButtonPressedImage forKey:@"addTabButtonPressedImage"]; - [aCoder encodeObject:_addTabButtonRolloverImage forKey:@"addTabButtonRolloverImage"]; - } - */ -} - -- (id)initWithCoder:(NSCoder *)aDecoder { - - self = [self init]; - if (self) { -/* - if ([aDecoder allowsKeyedCoding]) { - aquaTabBg = [[aDecoder decodeObjectForKey:@"aquaTabBg"] retain]; - aquaTabBgDown = [[aDecoder decodeObjectForKey:@"aquaTabBgDown"] retain]; - aquaTabBgDownGraphite = [[aDecoder decodeObjectForKey:@"aquaTabBgDownGraphite"] retain]; - aquaTabBgDownNonKey = [[aDecoder decodeObjectForKey:@"aquaTabBgDownNonKey"] retain]; - aquaDividerDown = [[aDecoder decodeObjectForKey:@"aquaDividerDown"] retain]; - aquaDivider = [[aDecoder decodeObjectForKey:@"aquaDivider"] retain]; - aquaCloseButton = [[aDecoder decodeObjectForKey:@"aquaCloseButton"] retain]; - aquaCloseButtonDown = [[aDecoder decodeObjectForKey:@"aquaCloseButtonDown"] retain]; - aquaCloseButtonOver = [[aDecoder decodeObjectForKey:@"aquaCloseButtonOver"] retain]; - aquaCloseDirtyButton = [[aDecoder decodeObjectForKey:@"aquaCloseDirtyButton"] retain]; - aquaCloseDirtyButtonDown = [[aDecoder decodeObjectForKey:@"aquaCloseDirtyButtonDown"] retain]; - aquaCloseDirtyButtonOver = [[aDecoder decodeObjectForKey:@"aquaCloseDirtyButtonOver"] retain]; - _addTabButtonImage = [[aDecoder decodeObjectForKey:@"addTabButtonImage"] retain]; - _addTabButtonPressedImage = [[aDecoder decodeObjectForKey:@"addTabButtonPressedImage"] retain]; - _addTabButtonRolloverImage = [[aDecoder decodeObjectForKey:@"addTabButtonRolloverImage"] retain]; - - } -*/ - } - return self; -} - -@end diff --git a/Frameworks/PSMTabBar/Styles/PSMCardTabStyle.h b/Frameworks/PSMTabBar/Styles/PSMCardTabStyle.h deleted file mode 100644 index b04f83d1..00000000 --- a/Frameworks/PSMTabBar/Styles/PSMCardTabStyle.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// PSMCardTabStyle.h -// Fichiers -// -// Created by Michael Monscheuer on 05.11.09. -// Copyright 2009 WriteFlow KG, Wien. All rights reserved. -// - -#import <Cocoa/Cocoa.h> -#import "PSMTabStyle.h" - -@interface PSMCardTabStyle : NSObject <PSMTabStyle> -{ - NSImage *unifiedCloseButton; - NSImage *unifiedCloseButtonDown; - NSImage *unifiedCloseButtonOver; - NSImage *unifiedCloseDirtyButton; - NSImage *unifiedCloseDirtyButtonDown; - NSImage *unifiedCloseDirtyButtonOver; - NSImage *_addTabButtonImage; - NSImage *_addTabButtonPressedImage; - NSImage *_addTabButtonRolloverImage; - - NSDictionary *_objectCountStringAttributes; - - CGFloat leftMargin; - PSMTabBarControl *tabBar; -} - -- (void)setLeftMarginForTabBarControl:(CGFloat)margin; - -@end diff --git a/Frameworks/PSMTabBar/Styles/PSMCardTabStyle.m b/Frameworks/PSMTabBar/Styles/PSMCardTabStyle.m deleted file mode 100644 index d81458f1..00000000 --- a/Frameworks/PSMTabBar/Styles/PSMCardTabStyle.m +++ /dev/null @@ -1,643 +0,0 @@ -// -// PSMCardTabStyle.m -// Fichiers -// -// Created by Michael Monscheuer on 05.11.09. -// Copyright 2009 WriteFlow KG, Wien. All rights reserved. -// - -#import "PSMCardTabStyle.h" -#import "PSMTabBarCell.h" -#import "PSMTabBarControl.h" -#import "NSBezierPath_AMShading.h" - -#define kPSMUnifiedObjectCounterRadius 7.0 -#define kPSMUnifiedCounterMinWidth 20 - -@interface PSMCardTabStyle (Private) -- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView*)controlView; -@end - -@implementation PSMCardTabStyle - -- (NSString *)name -{ - return @"Card"; -} - -#pragma mark - -#pragma mark Creation/Destruction - -- (id) init -{ - if ( (self = [super init]) ) { - unifiedCloseButton = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front"]]; - unifiedCloseButtonDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front_Pressed"]]; - unifiedCloseButtonOver = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front_Rollover"]]; - - unifiedCloseDirtyButton = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabCloseDirty_Front"]]; - unifiedCloseDirtyButtonDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabCloseDirty_Front_Pressed"]]; - unifiedCloseDirtyButtonOver = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabCloseDirty_Front_Rollover"]]; - - _addTabButtonImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNew"]]; - _addTabButtonPressedImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNewPressed"]]; - _addTabButtonRolloverImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNewRollover"]]; - - _objectCountStringAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:[[NSFontManager sharedFontManager] convertFont:[NSFont fontWithName:@"Helvetica" size:11.0] toHaveTrait:NSBoldFontMask], NSFontAttributeName, - [[NSColor whiteColor] colorWithAlphaComponent:0.85], NSForegroundColorAttributeName, - nil, nil]; - - leftMargin = 5.0; - } - return self; -} - -- (void)dealloc -{ - [unifiedCloseButton release]; - [unifiedCloseButtonDown release]; - [unifiedCloseButtonOver release]; - [unifiedCloseDirtyButton release]; - [unifiedCloseDirtyButtonDown release]; - [unifiedCloseDirtyButtonOver release]; - [_addTabButtonImage release]; - [_addTabButtonPressedImage release]; - [_addTabButtonRolloverImage release]; - - [_objectCountStringAttributes release]; - - [super dealloc]; -} - -#pragma mark - -#pragma mark Control Specific - -- (void)setLeftMarginForTabBarControl:(CGFloat)margin -{ - leftMargin = margin; -} - -- (CGFloat)leftMarginForTabBarControl -{ - return leftMargin; -} - -- (CGFloat)rightMarginForTabBarControl -{ - return 5.0f; -// return 24.0f; -} - -- (CGFloat)topMarginForTabBarControl -{ - return 10.0f; -} - -- (void)setOrientation:(PSMTabBarOrientation)value -{ - -} - -#pragma mark - -#pragma mark Add Tab Button - -- (NSImage *)addTabButtonImage -{ - return _addTabButtonImage; -} - -- (NSImage *)addTabButtonPressedImage -{ - return _addTabButtonPressedImage; -} - -- (NSImage *)addTabButtonRolloverImage -{ - return _addTabButtonRolloverImage; -} - -#pragma mark - -#pragma mark Cell Specific - -- (NSRect)dragRectForTabCell:(PSMTabBarCell *)cell orientation:(PSMTabBarOrientation)orientation -{ - NSRect dragRect = [cell frame]; - dragRect.size.width++; - return dragRect; -} - -- (NSRect)closeButtonRectForTabCell:(PSMTabBarCell *)cell withFrame:(NSRect)cellFrame -{ - if ([cell hasCloseButton] == NO || [cell isCloseButtonSuppressed]) { - return NSZeroRect; - } - - NSRect result; - result.size = [unifiedCloseButton size]; - result.origin.x = cellFrame.origin.x + MARGIN_X; - result.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; - - return result; -} - -- (NSRect)iconRectForTabCell:(PSMTabBarCell *)cell -{ - NSRect cellFrame = [cell frame]; - - if ([cell hasIcon] == NO) { - return NSZeroRect; - } - - NSRect result; - result.size = NSMakeSize(kPSMTabBarIconWidth, kPSMTabBarIconWidth); - result.origin.x = cellFrame.origin.x + MARGIN_X; - result.origin.y = cellFrame.origin.y + MARGIN_Y - 1.0; - - if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { - result.origin.x += [unifiedCloseButton size].width + kPSMTabBarCellPadding; - } - - return result; -} - -- (NSRect)indicatorRectForTabCell:(PSMTabBarCell *)cell -{ - NSRect cellFrame = [cell frame]; - - if ([[cell indicator] isHidden]) { - return NSZeroRect; - } - - NSRect result; - result.size = NSMakeSize(kPSMTabBarIndicatorWidth, kPSMTabBarIndicatorWidth); - result.origin.x = cellFrame.origin.x + cellFrame.size.width - MARGIN_X - kPSMTabBarIndicatorWidth; - result.origin.y = cellFrame.origin.y + MARGIN_Y - 1.0; - - return result; -} - -- (NSRect)objectCounterRectForTabCell:(PSMTabBarCell *)cell -{ - NSRect cellFrame = [cell frame]; - - if ([cell count] == 0) { - return NSZeroRect; - } - - CGFloat countWidth = [[self attributedObjectCountValueForTabCell:cell] size].width; - countWidth += (2 * kPSMUnifiedObjectCounterRadius - 6.0); - if (countWidth < kPSMUnifiedCounterMinWidth) { - countWidth = kPSMUnifiedCounterMinWidth; - } - - NSRect result; - result.size = NSMakeSize(countWidth, 2 * kPSMUnifiedObjectCounterRadius); // temp - result.origin.x = cellFrame.origin.x + cellFrame.size.width - MARGIN_X - result.size.width; - result.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; - - if (![[cell indicator] isHidden]) { - result.origin.x -= kPSMTabBarIndicatorWidth + kPSMTabBarCellPadding; - } - - return result; -} - - -- (CGFloat)minimumWidthOfTabCell:(PSMTabBarCell *)cell -{ - CGFloat resultWidth = 0.0; - - // left margin - resultWidth = MARGIN_X; - - // close button? - if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { - resultWidth += [unifiedCloseButton size].width + kPSMTabBarCellPadding; - } - - // icon? - if ([cell hasIcon]) { - resultWidth += kPSMTabBarIconWidth + kPSMTabBarCellPadding; - } - - // the label - resultWidth += kPSMMinimumTitleWidth; - - // object counter? - if ([cell count] > 0) { - resultWidth += [self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding; - } - - // indicator? - if ([[cell indicator] isHidden] == NO) - resultWidth += kPSMTabBarCellPadding + kPSMTabBarIndicatorWidth; - - // right margin - resultWidth += MARGIN_X; - - return ceil(resultWidth); -} - -- (CGFloat)desiredWidthOfTabCell:(PSMTabBarCell *)cell -{ - CGFloat resultWidth = 0.0; - - // left margin - resultWidth = MARGIN_X; - - // close button? - if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) - resultWidth += [unifiedCloseButton size].width + kPSMTabBarCellPadding; - - // icon? - if ([cell hasIcon]) { - resultWidth += kPSMTabBarIconWidth + kPSMTabBarCellPadding; - } - - // the label - resultWidth += [[cell attributedStringValue] size].width; - - // object counter? - if ([cell count] > 0) { - resultWidth += [self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding; - } - - // indicator? - if ([[cell indicator] isHidden] == NO) - resultWidth += kPSMTabBarCellPadding + kPSMTabBarIndicatorWidth; - - // right margin - resultWidth += MARGIN_X; - - return ceil(resultWidth); -} - -- (CGFloat)tabCellHeight -{ - return kPSMTabBarControlHeight; -} - -#pragma mark - -#pragma mark Cell Values - -- (NSAttributedString *)attributedObjectCountValueForTabCell:(PSMTabBarCell *)cell -{ - NSString *contents = [NSString stringWithFormat:@"%lu", (unsigned long)[cell count]]; - return [[[NSMutableAttributedString alloc] initWithString:contents attributes:_objectCountStringAttributes] autorelease]; -} - -- (NSAttributedString *)attributedStringValueForTabCell:(PSMTabBarCell *)cell -{ - NSMutableAttributedString *attrStr; - NSString * contents = [cell stringValue]; - attrStr = [[[NSMutableAttributedString alloc] initWithString:contents] autorelease]; - NSRange range = NSMakeRange(0, [contents length]); - - [attrStr addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:11.0] range:range]; - - // Paragraph Style for Truncating Long Text - static NSMutableParagraphStyle *TruncatingTailParagraphStyle = nil; - if (!TruncatingTailParagraphStyle) { - TruncatingTailParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; - [TruncatingTailParagraphStyle setLineBreakMode:NSLineBreakByTruncatingTail]; - } - [attrStr addAttribute:NSParagraphStyleAttributeName value:TruncatingTailParagraphStyle range:range]; - - return attrStr; -} - -#pragma mark - -#pragma mark ---- drawing ---- - -- (void)drawTabCell:(PSMTabBarCell *)cell -{ - NSRect cellFrame = [cell frame]; - BOOL showsBaselineSeparator = NO; -/* - NSToolbar *toolbar = [[[cell controlView] window] toolbar]; - BOOL showsBaselineSeparator = (toolbar && [toolbar respondsToSelector:@selector(showsBaselineSeparator)] && [toolbar showsBaselineSeparator]); -*/ - if (!showsBaselineSeparator) { - cellFrame.origin.y += 3.0; - cellFrame.size.height -= 3.0; - } - - - NSColor * lineColor = nil; - NSBezierPath* bezier = [NSBezierPath bezierPath]; - lineColor = [NSColor colorWithCalibratedWhite:0.576 alpha:1.0]; - - if (!showsBaselineSeparator || [cell state] == NSOnState) - { -// // selected tab -// NSRect aRect = NSMakeRect(cellFrame.origin.x+0.5, cellFrame.origin.y-0.5, cellFrame.size.width, cellFrame.size.height); - // selected tab - NSRect aRect = NSMakeRect(cellFrame.origin.x+.5, cellFrame.origin.y+0.5, cellFrame.size.width-1.0, cellFrame.size.height-1.0); - - // frame - CGFloat radius = MIN(6.0, 0.5f * MIN(NSWidth(aRect), NSHeight(aRect)))-0.5; -// NSRect rect = NSInsetRect(aRect, radius, radius); - - [bezier moveToPoint: NSMakePoint(NSMinX(aRect),NSMaxY(aRect))]; - [bezier appendBezierPathWithArcFromPoint:NSMakePoint(NSMinX(aRect),NSMinY(aRect)) toPoint:NSMakePoint(NSMidX(aRect),NSMinY(aRect)) radius:radius]; - [bezier appendBezierPathWithArcFromPoint:NSMakePoint(NSMaxX(aRect),NSMinY(aRect)) toPoint:NSMakePoint(NSMaxX(aRect),NSMaxY(aRect)) radius:radius]; - [bezier lineToPoint: NSMakePoint(NSMaxX(aRect),NSMaxY(aRect))]; - -/* - [bezier appendBezierPathWithArcWithCenter:NSMakePoint(NSMinX(rect), NSMinY(rect)) radius:radius startAngle:180.0 endAngle:270.0]; - - [bezier appendBezierPathWithArcWithCenter:NSMakePoint(NSMaxX(rect), NSMinY(rect)) radius:radius startAngle:270.0 endAngle:360.0]; - - NSPoint cornerPoint = NSMakePoint(NSMaxX(aRect), NSMaxY(aRect)); - [bezier appendBezierPathWithPoints:&cornerPoint count:1]; - - cornerPoint = NSMakePoint(NSMinX(aRect), NSMaxY(aRect)); - [bezier appendBezierPathWithPoints:&cornerPoint count:1]; - - [bezier closePath]; -*/ - - //[[NSColor windowBackgroundColor] set]; - //[bezier fill]; - if ([NSApp isActive]) { - if ([cell state] == NSOnState) { - [bezier linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.99 alpha:1.0] - endColor:[NSColor colorWithCalibratedWhite:0.941 alpha:1.0]]; - } else if ([cell isHighlighted]) { - [bezier linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.80 alpha:1.0] - endColor:[NSColor colorWithCalibratedWhite:0.80 alpha:1.0]]; - } else { - [bezier linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.835 alpha:1.0] - endColor:[NSColor colorWithCalibratedWhite:0.843 alpha:1.0]]; - } - } - - [lineColor set]; - [bezier stroke]; - - } - else - { - // unselected tab - NSRect aRect = NSMakeRect(cellFrame.origin.x, cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height); - aRect.origin.y += 0.5; - aRect.origin.x += 1.5; - aRect.size.width -= 1; - - aRect.origin.x -= 1; - aRect.size.width += 1; - - // rollover - if ([cell isHighlighted]) - { - [[NSColor colorWithCalibratedWhite:0.0 alpha:0.1] set]; - NSRectFillUsingOperation(aRect, NSCompositeSourceAtop); - } - - // frame - - [lineColor set]; - [bezier moveToPoint:NSMakePoint(aRect.origin.x + aRect.size.width, aRect.origin.y-0.5)]; - if (!([cell tabState] & PSMTab_RightIsSelectedMask)) { - [bezier lineToPoint:NSMakePoint(NSMaxX(aRect), NSMaxY(aRect))]; - } - - [bezier stroke]; - - // Create a thin lighter line next to the dividing line for a bezel effect - if (!([cell tabState] & PSMTab_RightIsSelectedMask)) { - [[[NSColor redColor] colorWithAlphaComponent:0.5] set]; - [NSBezierPath strokeLineFromPoint:NSMakePoint(NSMaxX(aRect)+1.0, aRect.origin.y-0.5) - toPoint:NSMakePoint(NSMaxX(aRect)+1.0, NSMaxY(aRect)-2.5)]; - } - - // If this is the leftmost tab, we want to draw a line on the left, too - if ([cell tabState] & PSMTab_PositionLeftMask) - { - [lineColor set]; - [NSBezierPath strokeLineFromPoint:NSMakePoint(aRect.origin.x,aRect.origin.y-0.5) - toPoint:NSMakePoint(aRect.origin.x,NSMaxY(aRect)-2.5)]; - [[[NSColor redColor] colorWithAlphaComponent:0.5] set]; - [NSBezierPath strokeLineFromPoint:NSMakePoint(aRect.origin.x+1.0,aRect.origin.y-0.5) - toPoint:NSMakePoint(aRect.origin.x+1.0,NSMaxY(aRect)-2.5)]; - } - } - - [self drawInteriorWithTabCell:cell inView:[cell customControlView]]; -} - - -- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView*)controlView -{ - NSRect cellFrame = [cell frame]; - - BOOL showsBaselineSeparator = NO; -/* - NSToolbar *toolbar = [[[cell customControlView] window] toolbar]; - BOOL showsBaselineSeparator = (toolbar && [toolbar respondsToSelector:@selector(showsBaselineSeparator)] && [toolbar showsBaselineSeparator]); -*/ - if (!showsBaselineSeparator) { - cellFrame.origin.y += 3.0; - cellFrame.size.height -= 3.0; - } - - CGFloat labelPosition = cellFrame.origin.x + MARGIN_X; - - // close button - if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { - NSSize closeButtonSize = NSZeroSize; - NSRect closeButtonRect = [cell closeButtonRectForFrame:cellFrame]; - NSImage * closeButton = nil; - - closeButton = [cell isEdited] ? unifiedCloseDirtyButton : unifiedCloseButton; - - if ([cell closeButtonOver]) closeButton = [cell isEdited] ? unifiedCloseDirtyButtonOver : unifiedCloseButtonOver; - if ([cell closeButtonPressed]) closeButton = [cell isEdited] ? unifiedCloseDirtyButtonDown : unifiedCloseButtonDown; - - closeButtonSize = [closeButton size]; - - [closeButton drawInRect:closeButtonRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f respectFlipped:YES hints:nil]; - - // scoot label over - labelPosition += closeButtonSize.width + kPSMTabBarCellPadding; - } - - // icon - if ([cell hasIcon]) { - NSRect iconRect = [self iconRectForTabCell:cell]; - NSImage *icon = [[[cell representedObject] identifier] icon]; - - // center in available space (in case icon image is smaller than kPSMTabBarIconWidth) - if ([icon size].width < kPSMTabBarIconWidth) { - iconRect.origin.x += (kPSMTabBarIconWidth - [icon size].width) / 2.0; - } - if ([icon size].height < kPSMTabBarIconWidth) { - iconRect.origin.y -= (kPSMTabBarIconWidth - [icon size].height) / 2.0; - } - - [icon drawInRect:iconRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f respectFlipped:YES hints:nil]; - - // scoot label over - labelPosition += iconRect.size.width + kPSMTabBarCellPadding; - } - - // label rect - NSRect labelRect; - labelRect.origin.x = labelPosition; - labelRect.size.width = cellFrame.size.width - (labelRect.origin.x - cellFrame.origin.x) - kPSMTabBarCellPadding; - NSSize s = [[cell attributedStringValue] size]; - labelRect.origin.y = cellFrame.origin.y + (cellFrame.size.height-s.height)/2 + 1; - labelRect.size.height = s.height; - - if (![[cell indicator] isHidden]) { - labelRect.size.width -= (kPSMTabBarIndicatorWidth + kPSMTabBarCellPadding); - } - - // object counter - if ([cell count] > 0) { - [[cell countColor] ?: [NSColor colorWithCalibratedWhite:0.3 alpha:0.6] set]; - NSBezierPath *path = [NSBezierPath bezierPath]; - NSRect myRect = [self objectCounterRectForTabCell:cell]; - myRect.origin.y -= 1.0; - [path moveToPoint:NSMakePoint(myRect.origin.x + kPSMUnifiedObjectCounterRadius, myRect.origin.y)]; - [path lineToPoint:NSMakePoint(myRect.origin.x + myRect.size.width - kPSMUnifiedObjectCounterRadius, myRect.origin.y)]; - [path appendBezierPathWithArcWithCenter:NSMakePoint(myRect.origin.x + myRect.size.width - kPSMUnifiedObjectCounterRadius, myRect.origin.y + kPSMUnifiedObjectCounterRadius) radius:kPSMUnifiedObjectCounterRadius startAngle:270.0 endAngle:90.0]; - [path lineToPoint:NSMakePoint(myRect.origin.x + kPSMUnifiedObjectCounterRadius, myRect.origin.y + myRect.size.height)]; - [path appendBezierPathWithArcWithCenter:NSMakePoint(myRect.origin.x + kPSMUnifiedObjectCounterRadius, myRect.origin.y + kPSMUnifiedObjectCounterRadius) radius:kPSMUnifiedObjectCounterRadius startAngle:90.0 endAngle:270.0]; - [path fill]; - - // draw attributed string centered in area - NSRect counterStringRect; - NSAttributedString *counterString = [self attributedObjectCountValueForTabCell:cell]; - counterStringRect.size = [counterString size]; - counterStringRect.origin.x = myRect.origin.x + ((myRect.size.width - counterStringRect.size.width) / 2.0) + 0.25; - counterStringRect.origin.y = myRect.origin.y + ((myRect.size.height - counterStringRect.size.height) / 2.0) + 0.5; - [counterString drawInRect:counterStringRect]; - - labelRect.size.width -= myRect.size.width + kPSMTabBarCellPadding; - } - - // label - [[cell attributedStringValue] drawInRect:labelRect]; -} - -- (void)drawBackgroundInRect:(NSRect)rect -{ - //Draw for our whole bounds; it'll be automatically clipped to fit the appropriate drawing area - rect = [tabBar bounds]; - - NSRect gradientRect = rect; - gradientRect.size.height -= 1.0; - - NSBezierPath *path = [NSBezierPath bezierPathWithRect:gradientRect]; - [path linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.835 alpha:1.0] - endColor:[NSColor colorWithCalibratedWhite:0.843 alpha:1.0]]; - [[NSColor colorWithCalibratedWhite:0.576 alpha:1.0] set]; - - - if (![[[tabBar tabView] window] isKeyWindow]) { - [[NSColor windowBackgroundColor] set]; - NSRectFill(gradientRect); - } -} - -- (void)drawTabBar:(PSMTabBarControl *)bar inRect:(NSRect)rect -{ - [NSGraphicsContext saveGraphicsState]; - - // draw button separator - for(PSMTabBarCell *cell in [bar cells]) - { - if([cell state] == NSOnState) - { - [[NSColor colorWithCalibratedWhite:0.576 alpha:1.0] set]; - - [NSBezierPath strokeLineFromPoint:NSMakePoint(rect.origin.x,NSMaxY(rect)-0.5) - toPoint:NSMakePoint(NSMinX([cell frame]),NSMaxY(rect)-0.5)]; - [NSBezierPath strokeLineFromPoint:NSMakePoint(NSMaxX([cell frame]),NSMaxY(rect)-0.5) - toPoint:NSMakePoint(NSMaxX(rect),NSMaxY(rect)-0.5)]; - } - } - - tabBar = bar; - [self drawBackgroundInRect:rect]; - - // no tab view == not connected - if (![bar tabView]) { - NSRect labelRect = rect; - labelRect.size.height -= 4.0; - labelRect.origin.y += 4.0; - NSMutableAttributedString *attrStr; - NSString *contents = @"PSMTabBarControl"; - attrStr = [[[NSMutableAttributedString alloc] initWithString:contents] autorelease]; - NSRange range = NSMakeRange(0, [contents length]); - [attrStr addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:11.0] range:range]; - NSMutableParagraphStyle *centeredParagraphStyle = nil; - if (!centeredParagraphStyle) { - centeredParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; - [centeredParagraphStyle setAlignment:NSCenterTextAlignment]; - } - [attrStr addAttribute:NSParagraphStyleAttributeName value:centeredParagraphStyle range:range]; - [centeredParagraphStyle release]; - [attrStr drawInRect:labelRect]; - - goto EXIT; - } - - // draw cells - NSEnumerator *e = [[bar cells] objectEnumerator]; - PSMTabBarCell *cell; - while ( (cell = [e nextObject]) ) { - if ([bar isAnimating] || (![cell isInOverflowMenu] && NSIntersectsRect([cell frame], rect))) { - [cell drawWithFrame:[cell frame] inView:bar]; - } - } - -EXIT: - [NSGraphicsContext restoreGraphicsState]; - -} - -#pragma mark - -#pragma mark Archiving - -- (void)encodeWithCoder:(NSCoder *)aCoder -{ -/* - //[super encodeWithCoder:aCoder]; - if ([aCoder allowsKeyedCoding]) { - [aCoder encodeObject:unifiedCloseButton forKey:@"unifiedCloseButton"]; - [aCoder encodeObject:unifiedCloseButtonDown forKey:@"unifiedCloseButtonDown"]; - [aCoder encodeObject:unifiedCloseButtonOver forKey:@"unifiedCloseButtonOver"]; - [aCoder encodeObject:unifiedCloseDirtyButton forKey:@"unifiedCloseDirtyButton"]; - [aCoder encodeObject:unifiedCloseDirtyButtonDown forKey:@"unifiedCloseDirtyButtonDown"]; - [aCoder encodeObject:unifiedCloseDirtyButtonOver forKey:@"unifiedCloseDirtyButtonOver"]; - [aCoder encodeObject:_addTabButtonImage forKey:@"addTabButtonImage"]; - [aCoder encodeObject:_addTabButtonPressedImage forKey:@"addTabButtonPressedImage"]; - [aCoder encodeObject:_addTabButtonRolloverImage forKey:@"addTabButtonRolloverImage"]; - } -*/ -} - -- (id)initWithCoder:(NSCoder *)aDecoder -{ - self = [self init]; - if (self) { - /* - if ([aDecoder allowsKeyedCoding]) { - unifiedCloseButton = [[aDecoder decodeObjectForKey:@"unifiedCloseButton"] retain]; - unifiedCloseButtonDown = [[aDecoder decodeObjectForKey:@"unifiedCloseButtonDown"] retain]; - unifiedCloseButtonOver = [[aDecoder decodeObjectForKey:@"unifiedCloseButtonOver"] retain]; - unifiedCloseDirtyButton = [[aDecoder decodeObjectForKey:@"unifiedCloseDirtyButton"] retain]; - unifiedCloseDirtyButtonDown = [[aDecoder decodeObjectForKey:@"unifiedCloseDirtyButtonDown"] retain]; - unifiedCloseDirtyButtonOver = [[aDecoder decodeObjectForKey:@"unifiedCloseDirtyButtonOver"] retain]; - _addTabButtonImage = [[aDecoder decodeObjectForKey:@"addTabButtonImage"] retain]; - _addTabButtonPressedImage = [[aDecoder decodeObjectForKey:@"addTabButtonPressedImage"] retain]; - _addTabButtonRolloverImage = [[aDecoder decodeObjectForKey:@"addTabButtonRolloverImage"] retain]; - } - */ - } - return self; -} - -@end diff --git a/Frameworks/PSMTabBar/Styles/PSMMetalTabStyle.h b/Frameworks/PSMTabBar/Styles/PSMMetalTabStyle.h deleted file mode 100644 index 22cb7bc8..00000000 --- a/Frameworks/PSMTabBar/Styles/PSMMetalTabStyle.h +++ /dev/null @@ -1,34 +0,0 @@ -// -// PSMMetalTabStyle.h -// PSMTabBarControl -// -// Created by John Pannell on 2/17/06. -// Copyright 2006 Positive Spin Media. All rights reserved. -// - -#import <Cocoa/Cocoa.h> -#import "PSMTabStyle.h" - -@interface PSMMetalTabStyle : NSObject <PSMTabStyle> { - NSImage *metalCloseButton; - NSImage *metalCloseButtonDown; - NSImage *metalCloseButtonOver; - NSImage *metalCloseDirtyButton; - NSImage *metalCloseDirtyButtonDown; - NSImage *metalCloseDirtyButtonOver; - NSImage *_addTabButtonImage; - NSImage *_addTabButtonPressedImage; - NSImage *_addTabButtonRolloverImage; - - NSDictionary *_objectCountStringAttributes; - - PSMTabBarOrientation orientation; - PSMTabBarControl *tabBar; -} - -- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView*)controlView; - -- (void)encodeWithCoder:(NSCoder *)aCoder; -- (id)initWithCoder:(NSCoder *)aDecoder; - -@end diff --git a/Frameworks/PSMTabBar/Styles/PSMMetalTabStyle.m b/Frameworks/PSMTabBar/Styles/PSMMetalTabStyle.m deleted file mode 100644 index cdce6507..00000000 --- a/Frameworks/PSMTabBar/Styles/PSMMetalTabStyle.m +++ /dev/null @@ -1,654 +0,0 @@ -// -// PSMMetalTabStyle.m -// PSMTabBarControl -// -// Created by John Pannell on 2/17/06. -// Copyright 2006 Positive Spin Media. All rights reserved. -// - -#import "PSMMetalTabStyle.h" -#import "PSMTabBarCell.h" -#import "PSMTabBarControl.h" - -#define kPSMMetalObjectCounterRadius 7.0 -#define kPSMMetalCounterMinWidth 20 - -@implementation PSMMetalTabStyle - -- (NSString *)name -{ - return @"Metal"; -} - -#pragma mark - -#pragma mark Creation/Destruction - -- (id) init -{ - if ( (self = [super init]) ) { - metalCloseButton = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"TabClose_Front"]]; - metalCloseButtonDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"TabClose_Front_Pressed"]]; - metalCloseButtonOver = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"TabClose_Front_Rollover"]]; - - metalCloseDirtyButton = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"TabClose_Dirty"]]; - metalCloseDirtyButtonDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"TabClose_Dirty_Pressed"]]; - metalCloseDirtyButtonOver = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"TabClose_Dirty_Rollover"]]; - - _addTabButtonImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"TabNewMetal"]]; - _addTabButtonPressedImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"TabNewMetalPressed"]]; - _addTabButtonRolloverImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"TabNewMetalRollover"]]; - - _objectCountStringAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:[[NSFontManager sharedFontManager] convertFont:[NSFont fontWithName:@"Helvetica" size:11.0] toHaveTrait:NSBoldFontMask], NSFontAttributeName, - [[NSColor whiteColor] colorWithAlphaComponent:0.85], NSForegroundColorAttributeName, - nil, nil]; - } - return self; -} - -- (void)dealloc -{ - [metalCloseButton release]; - [metalCloseButtonDown release]; - [metalCloseButtonOver release]; - [metalCloseDirtyButton release]; - [metalCloseDirtyButtonDown release]; - [metalCloseDirtyButtonOver release]; - [_addTabButtonImage release]; - [_addTabButtonPressedImage release]; - [_addTabButtonRolloverImage release]; - - [_objectCountStringAttributes release]; - - [super dealloc]; -} - -#pragma mark - -#pragma mark Control Specific - -- (CGFloat)leftMarginForTabBarControl -{ - return 10.0f; -} - -- (CGFloat)rightMarginForTabBarControl -{ - return 24.0f; -} - -- (CGFloat)topMarginForTabBarControl -{ - return 10.0f; -} - -- (void)setOrientation:(PSMTabBarOrientation)value -{ - orientation = value; -} - -#pragma mark - -#pragma mark Add Tab Button - -- (NSImage *)addTabButtonImage -{ - return _addTabButtonImage; -} - -- (NSImage *)addTabButtonPressedImage -{ - return _addTabButtonPressedImage; -} - -- (NSImage *)addTabButtonRolloverImage -{ - return _addTabButtonRolloverImage; -} - -#pragma mark - -#pragma mark Cell Specific - -- (NSRect)dragRectForTabCell:(PSMTabBarCell *)cell orientation:(PSMTabBarOrientation)tabOrientation -{ - NSRect dragRect = [cell frame]; - dragRect.size.width++; - - if ([cell tabState] & PSMTab_SelectedMask) { - if (tabOrientation == PSMTabBarHorizontalOrientation) { - dragRect.size.height -= 2.0; - } else { - dragRect.size.height += 1.0; - dragRect.origin.y -= 1.0; - dragRect.origin.x += 2.0; - dragRect.size.width -= 3.0; - } - } else if (tabOrientation == PSMTabBarVerticalOrientation) { - dragRect.origin.x--; - } - - return dragRect; -} - -- (NSRect)closeButtonRectForTabCell:(PSMTabBarCell *)cell withFrame:(NSRect)cellFrame -{ - if ([cell hasCloseButton] == NO) { - return NSZeroRect; - } - - NSRect result; - result.size = [metalCloseButton size]; - result.origin.x = cellFrame.origin.x + MARGIN_X; - result.origin.y = cellFrame.origin.y + MARGIN_Y + 2.0; - - if ([cell state] == NSOnState) { - result.origin.y -= 1; - } - - return result; -} - -- (NSRect)iconRectForTabCell:(PSMTabBarCell *)cell -{ - NSRect cellFrame = [cell frame]; - - if ([cell hasIcon] == NO) { - return NSZeroRect; - } - - NSRect result; - result.size = NSMakeSize(kPSMTabBarIconWidth, kPSMTabBarIconWidth); - result.origin.x = cellFrame.origin.x + MARGIN_X; - result.origin.y = cellFrame.origin.y + MARGIN_Y; - - if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { - result.origin.x += [metalCloseButton size].width + kPSMTabBarCellPadding; - } - - if ([cell state] == NSOnState) { - result.origin.y -= 1; - } - - return result; -} - -- (NSRect)indicatorRectForTabCell:(PSMTabBarCell *)cell -{ - NSRect cellFrame = [cell frame]; - - if ([[cell indicator] isHidden]) { - return NSZeroRect; - } - - NSRect result; - result.size = NSMakeSize(kPSMTabBarIndicatorWidth, kPSMTabBarIndicatorWidth); - result.origin.x = cellFrame.origin.x + cellFrame.size.width - MARGIN_X - kPSMTabBarIndicatorWidth; - result.origin.y = cellFrame.origin.y + MARGIN_Y; - - if ([cell state] == NSOnState) { - result.origin.y -= 1; - } - - return result; -} - -- (NSRect)objectCounterRectForTabCell:(PSMTabBarCell *)cell -{ - NSRect cellFrame = [cell frame]; - - if ([cell count] == 0) { - return NSZeroRect; - } - - CGFloat countWidth = [[self attributedObjectCountValueForTabCell:cell] size].width; - countWidth += (2 * kPSMMetalObjectCounterRadius - 6.0); - if (countWidth < kPSMMetalCounterMinWidth) { - countWidth = kPSMMetalCounterMinWidth; - } - - NSRect result; - result.size = NSMakeSize(countWidth, 2 * kPSMMetalObjectCounterRadius); // temp - result.origin.x = cellFrame.origin.x + cellFrame.size.width - MARGIN_X - result.size.width; - result.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; - - if (![[cell indicator] isHidden]) { - result.origin.x -= kPSMTabBarIndicatorWidth + kPSMTabBarCellPadding; - } - - return result; -} - - -- (CGFloat)minimumWidthOfTabCell:(PSMTabBarCell *)cell -{ - CGFloat resultWidth = 0.0; - - // left margin - resultWidth = MARGIN_X; - - // close button? - if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { - resultWidth += [metalCloseButton size].width + kPSMTabBarCellPadding; - } - - // icon? - if ([cell hasIcon]) { - resultWidth += kPSMTabBarIconWidth + kPSMTabBarCellPadding; - } - - // the label - resultWidth += kPSMMinimumTitleWidth; - - // object counter? - if ([cell count] > 0) { - resultWidth += [self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding; - } - - // indicator? - if ([[cell indicator] isHidden] == NO) - resultWidth += kPSMTabBarCellPadding + kPSMTabBarIndicatorWidth; - - // right margin - resultWidth += MARGIN_X; - - return ceil(resultWidth); -} - -- (CGFloat)desiredWidthOfTabCell:(PSMTabBarCell *)cell -{ - CGFloat resultWidth = 0.0; - - // left margin - resultWidth = MARGIN_X; - - // close button? - if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) - resultWidth += [metalCloseButton size].width + kPSMTabBarCellPadding; - - // icon? - if ([cell hasIcon]) { - resultWidth += kPSMTabBarIconWidth + kPSMTabBarCellPadding; - } - - // the label - resultWidth += [[cell attributedStringValue] size].width; - - // object counter? - if ([cell count] > 0) { - resultWidth += [self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding; - } - - // indicator? - if ([[cell indicator] isHidden] == NO) - resultWidth += kPSMTabBarCellPadding + kPSMTabBarIndicatorWidth; - - // right margin - resultWidth += MARGIN_X; - - return ceil(resultWidth); -} - -- (CGFloat)tabCellHeight -{ - return kPSMTabBarControlHeight; -} - -#pragma mark - -#pragma mark Cell Values - -- (NSAttributedString *)attributedObjectCountValueForTabCell:(PSMTabBarCell *)cell -{ - NSString *contents = [NSString stringWithFormat:@"%lu", (unsigned long)[cell count]]; - return [[[NSMutableAttributedString alloc] initWithString:contents attributes:_objectCountStringAttributes] autorelease]; -} - -- (NSAttributedString *)attributedStringValueForTabCell:(PSMTabBarCell *)cell -{ - NSMutableAttributedString *attrStr; - NSString *contents = [cell stringValue]; - attrStr = [[[NSMutableAttributedString alloc] initWithString:contents] autorelease]; - NSRange range = NSMakeRange(0, [contents length]); - - // Add font attribute - [attrStr addAttribute:NSFontAttributeName value:[NSFont boldSystemFontOfSize:11.0] range:range]; - [attrStr addAttribute:NSForegroundColorAttributeName value:[[NSColor textColor] colorWithAlphaComponent:0.75] range:range]; - - // Add shadow attribute - NSShadow* shadow; - shadow = [[[NSShadow alloc] init] autorelease]; - CGFloat shadowAlpha; - if (([cell state] == NSOnState) || [cell isHighlighted]) { - shadowAlpha = 0.8; - } else { - shadowAlpha = 0.5; - } - [shadow setShadowColor:[NSColor colorWithCalibratedWhite:1.0 alpha:shadowAlpha]]; - [shadow setShadowOffset:NSMakeSize(0, -1)]; - [shadow setShadowBlurRadius:1.0]; - [attrStr addAttribute:NSShadowAttributeName value:shadow range:range]; - - // Paragraph Style for Truncating Long Text - static NSMutableParagraphStyle *TruncatingTailParagraphStyle = nil; - if (!TruncatingTailParagraphStyle) { - TruncatingTailParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; - [TruncatingTailParagraphStyle setLineBreakMode:NSLineBreakByTruncatingTail]; - [TruncatingTailParagraphStyle setAlignment:NSCenterTextAlignment]; - } - [attrStr addAttribute:NSParagraphStyleAttributeName value:TruncatingTailParagraphStyle range:range]; - - return attrStr; -} - -#pragma mark - -#pragma mark ---- drawing ---- - -- (void)drawTabCell:(PSMTabBarCell *)cell -{ - NSRect cellFrame = [cell frame]; - NSColor *lineColor = nil; - NSBezierPath *bezier = [NSBezierPath bezierPath]; - lineColor = [NSColor darkGrayColor]; - - //disable antialiasing of bezier paths - [NSGraphicsContext saveGraphicsState]; - [[NSGraphicsContext currentContext] setShouldAntialias:NO]; - - if ([cell state] == NSOnState) { - // selected tab - if (orientation == PSMTabBarHorizontalOrientation) { - NSRect aRect = NSMakeRect(cellFrame.origin.x, cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height-2.5); - - // background - aRect.origin.x += 1.0; - aRect.size.width--; - aRect.size.height -= 0.5; - NSDrawWindowBackground(aRect); - aRect.size.width++; - aRect.size.height += 0.5; - - // frame - aRect.origin.x -= 0.5; - [lineColor set]; - [bezier setLineWidth:1.0]; - [bezier moveToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y)]; - [bezier lineToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y+aRect.size.height-1.5)]; - [bezier lineToPoint:NSMakePoint(aRect.origin.x+1.5, aRect.origin.y+aRect.size.height)]; - [bezier lineToPoint:NSMakePoint(aRect.origin.x+aRect.size.width-2.5, aRect.origin.y+aRect.size.height)]; - [bezier lineToPoint:NSMakePoint(aRect.origin.x+aRect.size.width, aRect.origin.y+aRect.size.height-1.5)]; - [bezier lineToPoint:NSMakePoint(aRect.origin.x+aRect.size.width, aRect.origin.y)]; - if ([[cell customControlView] frame].size.height < 2) { - // special case of hidden control; need line across top of cell - [bezier moveToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y+0.5)]; - [bezier lineToPoint:NSMakePoint(aRect.origin.x+aRect.size.width, aRect.origin.y+0.5)]; - } - } else { - NSRect aRect = NSMakeRect(cellFrame.origin.x + 2, cellFrame.origin.y, cellFrame.size.width - 2, cellFrame.size.height); - - // background - aRect.origin.x++; - aRect.size.height--; - NSDrawWindowBackground(aRect); - aRect.origin.x--; - aRect.size.height++; - - // frame - [lineColor set]; - [bezier setLineWidth:1.0]; - [bezier moveToPoint:NSMakePoint(aRect.origin.x + aRect.size.width, aRect.origin.y)]; - [bezier lineToPoint:NSMakePoint(aRect.origin.x + 2, aRect.origin.y)]; - [bezier lineToPoint:NSMakePoint(aRect.origin.x + 0.5, aRect.origin.y + 2)]; - [bezier lineToPoint:NSMakePoint(aRect.origin.x + 0.5, aRect.origin.y + aRect.size.height - 3)]; - [bezier lineToPoint:NSMakePoint(aRect.origin.x + 3, aRect.origin.y + aRect.size.height)]; - [bezier lineToPoint:NSMakePoint(aRect.origin.x + aRect.size.width, aRect.origin.y + aRect.size.height)]; - } - - [bezier stroke]; - } else { - - // unselected tab - NSRect aRect = NSMakeRect(cellFrame.origin.x, cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height); - aRect.origin.y += 0.5; - aRect.origin.x += 1.5; - aRect.size.width -= 1; - - // rollover - if ([cell isHighlighted]) { - [[NSColor colorWithCalibratedWhite:0.0 alpha:0.1] set]; - NSRectFillUsingOperation(aRect, NSCompositeSourceAtop); - } - - [lineColor set]; - - if (orientation == PSMTabBarHorizontalOrientation) { - aRect.origin.x -= 1; - aRect.size.width += 1; - - // frame - [bezier moveToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y)]; - [bezier lineToPoint:NSMakePoint(aRect.origin.x + aRect.size.width, aRect.origin.y)]; - if (!([cell tabState] & PSMTab_RightIsSelectedMask)) { - [bezier lineToPoint:NSMakePoint(aRect.origin.x + aRect.size.width, aRect.origin.y + aRect.size.height)]; - } - } else { - if (!([cell tabState] & PSMTab_LeftIsSelectedMask)) { - [bezier moveToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y)]; - [bezier lineToPoint:NSMakePoint(aRect.origin.x + aRect.size.width, aRect.origin.y)]; - } - - if (!([cell tabState] & PSMTab_RightIsSelectedMask)) { - [bezier moveToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y + aRect.size.height)]; - [bezier lineToPoint:NSMakePoint(aRect.origin.x + aRect.size.width, aRect.origin.y + aRect.size.height)]; - } - } - [bezier stroke]; - } - - [NSGraphicsContext restoreGraphicsState]; - - [self drawInteriorWithTabCell:cell inView:[cell customControlView]]; -} - - -- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView*)controlView -{ - NSRect cellFrame = [cell frame]; - CGFloat labelPosition = cellFrame.origin.x + MARGIN_X; - - // close button - if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { - NSSize closeButtonSize = NSZeroSize; - NSRect closeButtonRect = [cell closeButtonRectForFrame:cellFrame]; - NSImage * closeButton = nil; - - closeButton = [cell isEdited] ? metalCloseDirtyButton : metalCloseButton; - if ([cell closeButtonOver]) closeButton = [cell isEdited] ? metalCloseDirtyButtonOver : metalCloseButtonOver; - if ([cell closeButtonPressed]) closeButton = [cell isEdited] ? metalCloseDirtyButtonDown : metalCloseButtonDown; - - closeButtonSize = [closeButton size]; - - [closeButton drawInRect:closeButtonRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f respectFlipped:YES hints:nil]; - - // scoot label over - labelPosition += closeButtonSize.width + kPSMTabBarCellPadding; - } - - // icon - if ([cell hasIcon]) { - NSRect iconRect = [self iconRectForTabCell:cell]; - NSImage *icon = [[[cell representedObject] identifier] icon]; - - if ([controlView isFlipped]) { - iconRect.origin.y += iconRect.size.height; - } - - // center in available space (in case icon image is smaller than kPSMTabBarIconWidth) - if ([icon size].width < kPSMTabBarIconWidth) { - iconRect.origin.x += (kPSMTabBarIconWidth - [icon size].width)/2.0; - } - if ([icon size].height < kPSMTabBarIconWidth) { - iconRect.origin.y -= (kPSMTabBarIconWidth - [icon size].height)/2.0; - } - - [icon drawInRect:iconRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f respectFlipped:YES hints:nil]; - - // scoot label over - labelPosition += iconRect.size.width + kPSMTabBarCellPadding; - } - - // label rect - NSRect labelRect; - labelRect.origin.x = labelPosition; - labelRect.size.width = cellFrame.size.width - (labelRect.origin.x - cellFrame.origin.x) - kPSMTabBarCellPadding; - labelRect.size.height = cellFrame.size.height; - labelRect.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; - - if ([cell state] == NSOnState) { - labelRect.origin.y -= 1; - } - - if (![[cell indicator] isHidden]) { - labelRect.size.width -= (kPSMTabBarIndicatorWidth + kPSMTabBarCellPadding); - } - - // object counter - if ([cell count] > 0) { - [[cell countColor] ?: [NSColor colorWithCalibratedWhite:0.3 alpha:0.6] set]; - NSBezierPath *path = [NSBezierPath bezierPath]; - NSRect myRect = [self objectCounterRectForTabCell:cell]; - if ([cell state] == NSOnState) { - myRect.origin.y -= 1.0; - } - [path moveToPoint:NSMakePoint(myRect.origin.x + kPSMMetalObjectCounterRadius, myRect.origin.y)]; - [path lineToPoint:NSMakePoint(myRect.origin.x + myRect.size.width - kPSMMetalObjectCounterRadius, myRect.origin.y)]; - [path appendBezierPathWithArcWithCenter:NSMakePoint(myRect.origin.x + myRect.size.width - kPSMMetalObjectCounterRadius, myRect.origin.y + kPSMMetalObjectCounterRadius) radius:kPSMMetalObjectCounterRadius startAngle:270.0 endAngle:90.0]; - [path lineToPoint:NSMakePoint(myRect.origin.x + kPSMMetalObjectCounterRadius, myRect.origin.y + myRect.size.height)]; - [path appendBezierPathWithArcWithCenter:NSMakePoint(myRect.origin.x + kPSMMetalObjectCounterRadius, myRect.origin.y + kPSMMetalObjectCounterRadius) radius:kPSMMetalObjectCounterRadius startAngle:90.0 endAngle:270.0]; - [path fill]; - - // draw attributed string centered in area - NSRect counterStringRect; - NSAttributedString *counterString = [self attributedObjectCountValueForTabCell:cell]; - counterStringRect.size = [counterString size]; - counterStringRect.origin.x = myRect.origin.x + ((myRect.size.width - counterStringRect.size.width) / 2.0) + 0.25; - counterStringRect.origin.y = myRect.origin.y + ((myRect.size.height - counterStringRect.size.height) / 2.0) + 0.5; - [counterString drawInRect:counterStringRect]; - - // shrink label width to make room for object counter - labelRect.size.width -= myRect.size.width + kPSMTabBarCellPadding; - } - - // draw label - [[cell attributedStringValue] drawInRect:labelRect]; -} - -- (void)drawBackgroundInRect:(NSRect)rect -{ - //Draw for our whole bounds; it'll be automatically clipped to fit the appropriate drawing area - rect = [tabBar bounds]; - - if (orientation == PSMTabBarVerticalOrientation && [tabBar frame].size.width < 2) { - return; - } - - [NSGraphicsContext saveGraphicsState]; - [[NSGraphicsContext currentContext] setShouldAntialias:NO]; - - [[NSColor colorWithCalibratedWhite:0.0 alpha:0.2] set]; - NSRectFillUsingOperation(rect, NSCompositeSourceAtop); - [[NSColor darkGrayColor] set]; - - if (orientation == PSMTabBarHorizontalOrientation) { - [NSBezierPath strokeLineFromPoint:NSMakePoint(rect.origin.x, rect.origin.y + 0.5) toPoint:NSMakePoint(rect.origin.x + rect.size.width, rect.origin.y + 0.5)]; - [NSBezierPath strokeLineFromPoint:NSMakePoint(rect.origin.x, rect.origin.y + rect.size.height - 0.5) toPoint:NSMakePoint(rect.origin.x + rect.size.width, rect.origin.y + rect.size.height - 0.5)]; - } else { - [NSBezierPath strokeLineFromPoint:NSMakePoint(rect.origin.x, rect.origin.y + 0.5) toPoint:NSMakePoint(rect.origin.x, rect.origin.y + rect.size.height + 0.5)]; - [NSBezierPath strokeLineFromPoint:NSMakePoint(rect.origin.x + rect.size.width, rect.origin.y + 0.5) toPoint:NSMakePoint(rect.origin.x + rect.size.width, rect.origin.y + rect.size.height + 0.5)]; - } - - [NSGraphicsContext restoreGraphicsState]; -} - -- (void)drawTabBar:(PSMTabBarControl *)bar inRect:(NSRect)rect -{ - if (orientation != [bar orientation]) { - orientation = [bar orientation]; - } - - if (tabBar != bar) { - tabBar = bar; - } - - [self drawBackgroundInRect:rect]; - - // no tab view == not connected - if (![bar tabView]) { - NSRect labelRect = rect; - labelRect.size.height -= 4.0; - labelRect.origin.y += 4.0; - NSMutableAttributedString *attrStr; - NSString *contents = @"PSMTabBarControl"; - attrStr = [[[NSMutableAttributedString alloc] initWithString:contents] autorelease]; - NSRange range = NSMakeRange(0, [contents length]); - [attrStr addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:11.0] range:range]; - NSMutableParagraphStyle *centeredParagraphStyle = nil; - if (!centeredParagraphStyle) { - centeredParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; - [centeredParagraphStyle setAlignment:NSCenterTextAlignment]; - } - [attrStr addAttribute:NSParagraphStyleAttributeName value:centeredParagraphStyle range:range]; - [centeredParagraphStyle release]; - [attrStr drawInRect:labelRect]; - return; - } - - // draw cells - NSEnumerator *e = [[bar cells] objectEnumerator]; - PSMTabBarCell *cell; - while ( (cell = [e nextObject]) ) { - if ([bar isAnimating] || (![cell isInOverflowMenu] && NSIntersectsRect([cell frame], rect))) { - [cell drawWithFrame:[cell frame] inView:bar]; - } - } -} - -#pragma mark - -#pragma mark Archiving - -- (void)encodeWithCoder:(NSCoder *)aCoder -{ - //[super encodeWithCoder:aCoder]; -/* - if ([aCoder allowsKeyedCoding]) { - [aCoder encodeObject:metalCloseButton forKey:@"metalCloseButton"]; - [aCoder encodeObject:metalCloseButtonDown forKey:@"metalCloseButtonDown"]; - [aCoder encodeObject:metalCloseButtonOver forKey:@"metalCloseButtonOver"]; - [aCoder encodeObject:metalCloseDirtyButton forKey:@"metalCloseDirtyButton"]; - [aCoder encodeObject:metalCloseDirtyButtonDown forKey:@"metalCloseDirtyButtonDown"]; - [aCoder encodeObject:metalCloseDirtyButtonOver forKey:@"metalCloseDirtyButtonOver"]; - [aCoder encodeObject:_addTabButtonImage forKey:@"addTabButtonImage"]; - [aCoder encodeObject:_addTabButtonPressedImage forKey:@"addTabButtonPressedImage"]; - [aCoder encodeObject:_addTabButtonRolloverImage forKey:@"addTabButtonRolloverImage"]; - } -*/ -} - -- (id)initWithCoder:(NSCoder *)aDecoder -{ - self = [self init]; - if (self) { - -/* - if ([aDecoder allowsKeyedCoding]) { - metalCloseButton = [[aDecoder decodeObjectForKey:@"metalCloseButton"] retain]; - metalCloseButtonDown = [[aDecoder decodeObjectForKey:@"metalCloseButtonDown"] retain]; - metalCloseButtonOver = [[aDecoder decodeObjectForKey:@"metalCloseButtonOver"] retain]; - metalCloseDirtyButton = [[aDecoder decodeObjectForKey:@"metalCloseDirtyButton"] retain]; - metalCloseDirtyButtonDown = [[aDecoder decodeObjectForKey:@"metalCloseDirtyButtonDown"] retain]; - metalCloseDirtyButtonOver = [[aDecoder decodeObjectForKey:@"metalCloseDirtyButtonOver"] retain]; - _addTabButtonImage = [[aDecoder decodeObjectForKey:@"addTabButtonImage"] retain]; - _addTabButtonPressedImage = [[aDecoder decodeObjectForKey:@"addTabButtonPressedImage"] retain]; - _addTabButtonRolloverImage = [[aDecoder decodeObjectForKey:@"addTabButtonRolloverImage"] retain]; - } -*/ - } - return self; -} - -@end diff --git a/Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.h b/Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.h index d6f541a5..2e82845e 100644 --- a/Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.h +++ b/Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.h @@ -25,7 +25,8 @@ #import <Cocoa/Cocoa.h> #import "PSMTabStyle.h" -@interface PSMSequelProTabStyle : NSObject <PSMTabStyle> { +@interface PSMSequelProTabStyle : NSObject <PSMTabStyle> +{ BOOL systemVersionIsAtLeast10_7_0; BOOL systemVersionIsAtLeast10_10_0; @@ -45,7 +46,7 @@ PSMTabBarControl *tabBar; } -- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView*)controlView; +- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView *)controlView; - (void)encodeWithCoder:(NSCoder *)aCoder; - (id)initWithCoder:(NSCoder *)aDecoder; diff --git a/Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.m b/Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.m index 4329032b..30501bb8 100644 --- a/Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.m +++ b/Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.m @@ -1,6 +1,4 @@ // -// $Id: PSMSequelProTabStyle.m 2317 2010-06-15 10:19:41Z avenjamin $ -// // PSMSequelProTabStyle.m // sequel-pro // @@ -31,10 +29,9 @@ #define kPSMSequelProObjectCounterRadius 7.0f #define kPSMSequelProCounterMinWidth 20 #define kPSMSequelProTabCornerRadius 0 -#define MARGIN_X 6 #ifndef __MAC_10_10 -#define __MAC_10_10 101000 +#define __MAC_10_10 101000 #endif #if __MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_10 @@ -46,12 +43,20 @@ typedef struct { } NSOperatingSystemVersion; @interface NSProcessInfo () + - (NSOperatingSystemVersion)operatingSystemVersion; - (BOOL)isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion)version; -@end +@end #endif +@interface PSMSequelProTabStyle () + +- (NSColor *)_lineColorForTabCellDrawing; +- (void)_drawTabCell:(PSMTabBarCell *)cell withBackgroundColor:(NSColor *)backgroundColor lineColor:(NSColor *)lineColor; + +@end + @implementation PSMSequelProTabStyle - (NSString *)name @@ -69,9 +74,11 @@ typedef struct { // This code actually belongs in it's own class, but since both PSMTabBar.framework // and SP itself would need it, the loader will complain about a duplicate class implementation. NSProcessInfo *procInfo = [NSProcessInfo processInfo]; - if([procInfo respondsToSelector:@selector(isOperatingSystemAtLeastVersion:)]) { + + if ([procInfo respondsToSelector:@selector(isOperatingSystemAtLeastVersion:)]) { NSOperatingSystemVersion os10_7_0 = {10,7,0}; NSOperatingSystemVersion os10_10_0 = {10,10,0}; + systemVersionIsAtLeast10_7_0 = [procInfo isOperatingSystemAtLeastVersion:os10_7_0]; systemVersionIsAtLeast10_10_0 = [procInfo isOperatingSystemAtLeastVersion:os10_10_0]; } @@ -85,21 +92,23 @@ typedef struct { systemVersionIsAtLeast10_10_0 = (versionMajor > 10 || (versionMajor == 10 && versionMinor >= 10)); } - sequelProCloseButton = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"SequelProTabClose"]]; - sequelProCloseButtonDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"SequelProTabClose_Pressed"]]; - sequelProCloseButtonOver = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"SequelProTabClose_Rollover"]]; + NSBundle *bundle = [PSMTabBarControl bundle]; + + sequelProCloseButton = [[NSImage alloc] initByReferencingFile:[bundle pathForImageResource:@"SequelProTabClose"]]; + sequelProCloseButtonDown = [[NSImage alloc] initByReferencingFile:[bundle pathForImageResource:@"SequelProTabClose_Pressed"]]; + sequelProCloseButtonOver = [[NSImage alloc] initByReferencingFile:[bundle pathForImageResource:@"SequelProTabClose_Rollover"]]; - sequelProCloseDirtyButton = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"SequelProTabDirty"]]; - sequelProCloseDirtyButtonDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"SequelProTabDirty_Pressed"]]; - sequelProCloseDirtyButtonOver = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"SequelProTabDirty_Rollover"]]; + sequelProCloseDirtyButton = [[NSImage alloc] initByReferencingFile:[bundle pathForImageResource:@"SequelProTabDirty"]]; + sequelProCloseDirtyButtonDown = [[NSImage alloc] initByReferencingFile:[bundle pathForImageResource:@"SequelProTabDirty_Pressed"]]; + sequelProCloseDirtyButtonOver = [[NSImage alloc] initByReferencingFile:[bundle pathForImageResource:@"SequelProTabDirty_Rollover"]]; - _addTabButtonImage = [[NSImage alloc] initByReferencingFile:[[NSBundle mainBundle] pathForImageResource:@"button_add"]]; - _addTabButtonPressedImage = [[NSImage alloc] initByReferencingFile:[[NSBundle mainBundle] pathForImageResource:@"button_add"]]; - _addTabButtonRolloverImage = [[NSImage alloc] initByReferencingFile:[[NSBundle mainBundle] pathForImageResource:@"button_add"]]; + _addTabButtonImage = [[NSImage alloc] initByReferencingFile:[bundle pathForImageResource:@"AddTabButton"]]; + _addTabButtonPressedImage = [[NSImage alloc] initByReferencingFile:[bundle pathForImageResource:@"AddTabButton"]]; + _addTabButtonRolloverImage = [[NSImage alloc] initByReferencingFile:[bundle pathForImageResource:@"AddTabButton"]]; - _objectCountStringAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:[[NSFontManager sharedFontManager] convertFont:[NSFont fontWithName:@"Helvetica" size:11.0f] toHaveTrait:NSBoldFontMask], NSFontAttributeName, - [[NSColor whiteColor] colorWithAlphaComponent:0.85f], NSForegroundColorAttributeName, - nil, nil]; + _objectCountStringAttributes = [[NSDictionary alloc] initWithObjectsAndKeys: + [[NSFontManager sharedFontManager] convertFont:[NSFont fontWithName:@"Helvetica" size:11.0f] toHaveTrait:NSBoldFontMask], NSFontAttributeName, + [[NSColor whiteColor] colorWithAlphaComponent:0.85f], NSForegroundColorAttributeName, nil, nil]; } return self; } @@ -371,7 +380,6 @@ typedef struct { [textShadow setShadowColor:[NSColor colorWithCalibratedWhite:1.0f alpha:shadowAlpha]]; [textShadow setShadowOffset:NSMakeSize(0, -1)]; [textShadow setShadowBlurRadius:1.0f]; -// [attrStr addAttribute:NSShadowAttributeName value:textShadow range:range]; // Paragraph Style for Truncating Long Text static NSMutableParagraphStyle *TruncatingTailParagraphStyle = nil; @@ -433,23 +441,22 @@ typedef struct { } } - // Step 2 - (void)drawBackgroundInRect:(NSRect)rect { - //Draw for our whole bounds; it'll be automatically clipped to fit the appropriate drawing area + // Draw for our whole bounds; it'll be automatically clipped to fit the appropriate drawing area rect = [tabBar bounds]; - // find active cell + // Find active cell PSMTabBarCell *selectedCell = nil; + for (PSMTabBarCell *aCell in [tabBar cells]) { if (aCell.tabState & PSMTab_SelectedMask) { selectedCell = aCell; break; } } - - + [NSGraphicsContext saveGraphicsState]; [[NSGraphicsContext currentContext] setShouldAntialias:NO]; @@ -465,22 +472,14 @@ typedef struct { shadowAlpha = 0.3f; } - // fill in background of tab bar + // Fill in background of tab bar [[NSColor colorWithCalibratedWhite:backgroundCalibratedWhite alpha:1.0f] set]; - NSRectFill(NSMakeRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height - 10)); - - - // fill active tab strip - [[self fillColorForCell:selectedCell] set]; - NSRectFill(NSMakeRect(rect.origin.x, rect.origin.y + rect.size.height - 9, rect.size.width, 8)); + NSRectFill(NSMakeRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height)); // Draw horizontal line across the top edge [[NSColor colorWithCalibratedWhite:lineCalibratedWhite alpha:1.0f] set]; [NSBezierPath strokeLineFromPoint:NSMakePoint(rect.origin.x, rect.origin.y + 0.5f) toPoint:NSMakePoint(rect.origin.x + rect.size.width, rect.origin.y + 0.5f)]; - // Draw horizontal line across the baseline for each tab - [NSBezierPath strokeLineFromPoint:NSMakePoint(rect.origin.x, rect.origin.y + rect.size.height - 9.5f) toPoint:NSMakePoint(rect.origin.x + rect.size.width, rect.origin.y + rect.size.height - 9.5f)]; - // Draw horizontal line across the bottom edge [NSBezierPath strokeLineFromPoint:NSMakePoint(rect.origin.x, rect.origin.y + rect.size.height - 0.5f) toPoint:NSMakePoint(rect.origin.x + rect.size.width, rect.origin.y + rect.size.height - 0.5f)]; @@ -490,51 +489,27 @@ typedef struct { // Step 3 - (void)drawTabCell:(PSMTabBarCell *)cell { - // don't draw cells when collapsed - if (tabBar.isTabBarHidden) { - return; - } - - NSRect cellFrame = cell.frame; - NSColor *lineColor = nil; + // Don't draw cells when collapsed + if ([tabBar isTabBarHidden]) return; + + NSColor *lineColor = [self _lineColorForTabCellDrawing]; NSColor *fillColor = [self fillColorForCell:cell]; - // Set up colours - if (([[tabBar window] isMainWindow] || [[[tabBar window] attachedSheet] isMainWindow]) && [NSApp isActive]) { - lineColor = [NSColor grayColor]; - - } else { - lineColor = [NSColor colorWithCalibratedWhite:0.49f alpha:1.0f]; - - } - - // setup fill rect - NSRect fillRect = NSMakeRect(cellFrame.origin.x, cellFrame.origin.y + 1, cellFrame.size.width, cellFrame.size.height - 10); - + [self _drawTabCell:cell withBackgroundColor:fillColor lineColor:lineColor]; - // draw - [NSGraphicsContext saveGraphicsState]; + [self drawInteriorWithTabCell:cell inView:[cell customControlView]]; +} - [fillColor set]; - NSRectFill(fillRect); - - // stroke left edge - [lineColor setStroke]; - NSPoint point1 = NSMakePoint(fillRect.origin.x + fillRect.size.width - 0.5, fillRect.origin.y); - NSPoint point2 = NSMakePoint(fillRect.origin.x + fillRect.size.width - 0.5, fillRect.origin.y + fillRect.size.height); - [NSBezierPath strokeLineFromPoint:point1 toPoint:point2]; - - // stroke bottom edge unless active cell - if (cell.state != NSOnState) { - point1 = NSMakePoint(fillRect.origin.x, fillRect.origin.y + fillRect.size.height - 0.5); - point2 = NSMakePoint(fillRect.origin.x + fillRect.size.width, fillRect.origin.y + fillRect.size.height - 0.5); - [NSBezierPath strokeLineFromPoint:point1 toPoint:point2]; - } +/** + * Same as above, but doesn't draw the left hand (right had of the actual tab) border for the tab drag image. + */ +- (void)drawTabCellForDragImage:(PSMTabBarCell *)cell +{ + NSColor *fillColor = [self fillColorForCell:cell]; - [NSGraphicsContext restoreGraphicsState]; - - [self drawInteriorWithTabCell:cell inView:[cell customControlView]]; + [self _drawTabCell:cell withBackgroundColor:fillColor lineColor:nil]; + [self drawInteriorWithTabCell:cell inView:[cell customControlView]]; } // Step 4 @@ -547,13 +522,21 @@ typedef struct { if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed] && [cell isHighlighted]) { NSRect closeButtonRect = [cell closeButtonRectForFrame:cellFrame]; - NSImage * closeButton = nil; + NSImage *closeButton = nil; closeButton = [cell isEdited] ? sequelProCloseDirtyButton : sequelProCloseButton; if ([cell closeButtonOver]) closeButton = [cell isEdited] ? sequelProCloseDirtyButtonOver : sequelProCloseButtonOver; if ([cell closeButtonPressed]) closeButton = [cell isEdited] ? sequelProCloseDirtyButtonDown : sequelProCloseButtonDown; + // Slightly darken background tabs on mouse over + if ([cell state] == NSOffState) { + NSColor *lineColor = [self _lineColorForTabCellDrawing]; + NSColor *fillColor = [[self fillColorForCell:cell] shadowWithLevel:0.03f]; + + [self _drawTabCell:cell withBackgroundColor:fillColor lineColor:lineColor]; + } + [closeButton drawInRect:closeButtonRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f respectFlipped:YES hints:nil]; } @@ -677,42 +660,55 @@ typedef struct { - (void)encodeWithCoder:(NSCoder *)aCoder { - //[super encodeWithCoder:aCoder]; -/* - if ([aCoder allowsKeyedCoding]) { - [aCoder encodeObject:sequelProCloseButton forKey:@"sequelProCloseButton"]; - [aCoder encodeObject:sequelProCloseButtonDown forKey:@"sequelProCloseButtonDown"]; - [aCoder encodeObject:sequelProCloseButtonOver forKey:@"sequelProCloseButtonOver"]; - [aCoder encodeObject:sequelProCloseDirtyButton forKey:@"sequelProCloseDirtyButton"]; - [aCoder encodeObject:sequelProCloseDirtyButtonDown forKey:@"sequelProCloseDirtyButtonDown"]; - [aCoder encodeObject:sequelProCloseDirtyButtonOver forKey:@"sequelProCloseDirtyButtonOver"]; - [aCoder encodeObject:_addTabButtonImage forKey:@"addTabButtonImage"]; - [aCoder encodeObject:_addTabButtonPressedImage forKey:@"addTabButtonPressedImage"]; - [aCoder encodeObject:_addTabButtonRolloverImage forKey:@"addTabButtonRolloverImage"]; - } -*/ } - (id)initWithCoder:(NSCoder *)aDecoder { - self = [self init]; - if (self) { - -/* - if ([aDecoder allowsKeyedCoding]) { - sequelProCloseButton = [[aDecoder decodeObjectForKey:@"sequelProCloseButton"] retain]; - sequelProCloseButtonDown = [[aDecoder decodeObjectForKey:@"sequelProCloseButtonDown"] retain]; - sequelProCloseButtonOver = [[aDecoder decodeObjectForKey:@"sequelProCloseButtonOver"] retain]; - sequelProCloseDirtyButton = [[aDecoder decodeObjectForKey:@"sequelProCloseDirtyButton"] retain]; - sequelProCloseDirtyButtonDown = [[aDecoder decodeObjectForKey:@"sequelProCloseDirtyButtonDown"] retain]; - sequelProCloseDirtyButtonOver = [[aDecoder decodeObjectForKey:@"sequelProCloseDirtyButtonOver"] retain]; - _addTabButtonImage = [[aDecoder decodeObjectForKey:@"addTabButtonImage"] retain]; - _addTabButtonPressedImage = [[aDecoder decodeObjectForKey:@"addTabButtonPressedImage"] retain]; - _addTabButtonRolloverImage = [[aDecoder decodeObjectForKey:@"addTabButtonRolloverImage"] retain]; - } -*/ - } - return self; + return [self init]; +} + +#pragma mark - +#pragma mark Private API + +- (void)_drawTabCell:(PSMTabBarCell *)cell withBackgroundColor:(NSColor *)backgroundColor lineColor:(NSColor *)lineColor +{ + NSRect cellFrame = [cell frame]; + + // Setup fill rect + NSRect fillRect = NSMakeRect(cellFrame.origin.x, cellFrame.origin.y + 1, cellFrame.size.width, cellFrame.size.height - 1.5); + + // Draw + [NSGraphicsContext saveGraphicsState]; + + [backgroundColor set]; + NSRectFill(fillRect); + + if (lineColor) { + + // Stroke left edge + [lineColor setStroke]; + + NSPoint point1 = NSMakePoint(fillRect.origin.x + fillRect.size.width - 0.5, fillRect.origin.y); + NSPoint point2 = NSMakePoint(fillRect.origin.x + fillRect.size.width - 0.5, fillRect.origin.y + fillRect.size.height); + + [NSBezierPath strokeLineFromPoint:point1 toPoint:point2]; + } + + [NSGraphicsContext restoreGraphicsState]; +} + +- (NSColor *)_lineColorForTabCellDrawing +{ + NSColor *lineColor = nil; + + if (([[tabBar window] isMainWindow] || [[[tabBar window] attachedSheet] isMainWindow]) && [NSApp isActive]) { + lineColor = [NSColor grayColor]; + } + else { + lineColor = [NSColor colorWithCalibratedWhite:0.49f alpha:1.0f]; + } + + return lineColor; } @end diff --git a/Frameworks/PSMTabBar/Styles/PSMUnifiedTabStyle.h b/Frameworks/PSMTabBar/Styles/PSMUnifiedTabStyle.h deleted file mode 100644 index d44bbcdc..00000000 --- a/Frameworks/PSMTabBar/Styles/PSMUnifiedTabStyle.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// PSMUnifiedTabStyle.h -// -------------------- -// -// Created by Keith Blount on 30/04/2006. -// Copyright 2006 __MyCompanyName__. All rights reserved. -// - -#import <Cocoa/Cocoa.h> -#import "PSMTabStyle.h" - -@interface PSMUnifiedTabStyle : NSObject <PSMTabStyle> -{ - NSImage *unifiedCloseButton; - NSImage *unifiedCloseButtonDown; - NSImage *unifiedCloseButtonOver; - NSImage *unifiedCloseDirtyButton; - NSImage *unifiedCloseDirtyButtonDown; - NSImage *unifiedCloseDirtyButtonOver; - NSImage *_addTabButtonImage; - NSImage *_addTabButtonPressedImage; - NSImage *_addTabButtonRolloverImage; - - NSDictionary *_objectCountStringAttributes; - - CGFloat leftMargin; - PSMTabBarControl *tabBar; -} -- (void)setLeftMarginForTabBarControl:(CGFloat)margin; -@end diff --git a/Frameworks/PSMTabBar/Styles/PSMUnifiedTabStyle.m b/Frameworks/PSMTabBar/Styles/PSMUnifiedTabStyle.m deleted file mode 100644 index 882c1741..00000000 --- a/Frameworks/PSMTabBar/Styles/PSMUnifiedTabStyle.m +++ /dev/null @@ -1,598 +0,0 @@ -// -// PSMUnifiedTabStyle.m -// -------------------- -// -// Created by Keith Blount on 30/04/2006. -// Copyright 2006 __MyCompanyName__. All rights reserved. -// - -#import "PSMUnifiedTabStyle.h" -#import "PSMTabBarCell.h" -#import "PSMTabBarControl.h" -#import "NSBezierPath_AMShading.h" - -#define kPSMUnifiedObjectCounterRadius 7.0 -#define kPSMUnifiedCounterMinWidth 20 - -@interface PSMUnifiedTabStyle (Private) -- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView*)controlView; -@end - -@implementation PSMUnifiedTabStyle - -- (NSString *)name -{ - return @"Unified"; -} - -#pragma mark - -#pragma mark Creation/Destruction - -- (id) init -{ - if ( (self = [super init]) ) { - unifiedCloseButton = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front"]]; - unifiedCloseButtonDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front_Pressed"]]; - unifiedCloseButtonOver = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front_Rollover"]]; - - unifiedCloseDirtyButton = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabCloseDirty_Front"]]; - unifiedCloseDirtyButtonDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabCloseDirty_Front_Pressed"]]; - unifiedCloseDirtyButtonOver = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabCloseDirty_Front_Rollover"]]; - - _addTabButtonImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNew"]]; - _addTabButtonPressedImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNewPressed"]]; - _addTabButtonRolloverImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNewRollover"]]; - - _objectCountStringAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:[[NSFontManager sharedFontManager] convertFont:[NSFont fontWithName:@"Helvetica" size:11.0] toHaveTrait:NSBoldFontMask], NSFontAttributeName, - [[NSColor whiteColor] colorWithAlphaComponent:0.85], NSForegroundColorAttributeName, - nil, nil]; - - leftMargin = 5.0; - } - return self; -} - -- (void)dealloc -{ - [unifiedCloseButton release]; - [unifiedCloseButtonDown release]; - [unifiedCloseButtonOver release]; - [unifiedCloseDirtyButton release]; - [unifiedCloseDirtyButtonDown release]; - [unifiedCloseDirtyButtonOver release]; - [_addTabButtonImage release]; - [_addTabButtonPressedImage release]; - [_addTabButtonRolloverImage release]; - - [_objectCountStringAttributes release]; - - [super dealloc]; -} - -#pragma mark - -#pragma mark Control Specific - -- (void)setLeftMarginForTabBarControl:(CGFloat)margin -{ - leftMargin = margin; -} - -- (CGFloat)leftMarginForTabBarControl -{ - return leftMargin; -} - -- (CGFloat)rightMarginForTabBarControl -{ - return 24.0f; -} - -- (CGFloat)topMarginForTabBarControl -{ - return 10.0f; -} - -- (void)setOrientation:(PSMTabBarOrientation)value -{ - -} - -#pragma mark - -#pragma mark Add Tab Button - -- (NSImage *)addTabButtonImage -{ - return _addTabButtonImage; -} - -- (NSImage *)addTabButtonPressedImage -{ - return _addTabButtonPressedImage; -} - -- (NSImage *)addTabButtonRolloverImage -{ - return _addTabButtonRolloverImage; -} - -#pragma mark - -#pragma mark Cell Specific - -- (NSRect)dragRectForTabCell:(PSMTabBarCell *)cell orientation:(PSMTabBarOrientation)orientation -{ - NSRect dragRect = [cell frame]; - dragRect.size.width++; - return dragRect; -} - -- (NSRect)closeButtonRectForTabCell:(PSMTabBarCell *)cell withFrame:(NSRect)cellFrame -{ - if ([cell hasCloseButton] == NO) { - return NSZeroRect; - } - - NSRect result; - result.size = [unifiedCloseButton size]; - result.origin.x = cellFrame.origin.x + MARGIN_X; - result.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; - - return result; -} - -- (NSRect)iconRectForTabCell:(PSMTabBarCell *)cell -{ - NSRect cellFrame = [cell frame]; - - if ([cell hasIcon] == NO) { - return NSZeroRect; - } - - NSRect result; - result.size = NSMakeSize(kPSMTabBarIconWidth, kPSMTabBarIconWidth); - result.origin.x = cellFrame.origin.x + MARGIN_X; - result.origin.y = cellFrame.origin.y + MARGIN_Y - 1.0; - - if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { - result.origin.x += [unifiedCloseButton size].width + kPSMTabBarCellPadding; - } - - return result; -} - -- (NSRect)indicatorRectForTabCell:(PSMTabBarCell *)cell -{ - NSRect cellFrame = [cell frame]; - - if ([[cell indicator] isHidden]) { - return NSZeroRect; - } - - NSRect result; - result.size = NSMakeSize(kPSMTabBarIndicatorWidth, kPSMTabBarIndicatorWidth); - result.origin.x = cellFrame.origin.x + cellFrame.size.width - MARGIN_X - kPSMTabBarIndicatorWidth; - result.origin.y = cellFrame.origin.y + MARGIN_Y - 1.0; - - return result; -} - -- (NSRect)objectCounterRectForTabCell:(PSMTabBarCell *)cell -{ - NSRect cellFrame = [cell frame]; - - if ([cell count] == 0) { - return NSZeroRect; - } - - CGFloat countWidth = [[self attributedObjectCountValueForTabCell:cell] size].width; - countWidth += (2 * kPSMUnifiedObjectCounterRadius - 6.0); - if (countWidth < kPSMUnifiedCounterMinWidth) { - countWidth = kPSMUnifiedCounterMinWidth; - } - - NSRect result; - result.size = NSMakeSize(countWidth, 2 * kPSMUnifiedObjectCounterRadius); // temp - result.origin.x = cellFrame.origin.x + cellFrame.size.width - MARGIN_X - result.size.width; - result.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; - - if (![[cell indicator] isHidden]) { - result.origin.x -= kPSMTabBarIndicatorWidth + kPSMTabBarCellPadding; - } - - return result; -} - - -- (CGFloat)minimumWidthOfTabCell:(PSMTabBarCell *)cell -{ - CGFloat resultWidth = 0.0; - - // left margin - resultWidth = MARGIN_X; - - // close button? - if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { - resultWidth += [unifiedCloseButton size].width + kPSMTabBarCellPadding; - } - - // icon? - if ([cell hasIcon]) { - resultWidth += kPSMTabBarIconWidth + kPSMTabBarCellPadding; - } - - // the label - resultWidth += kPSMMinimumTitleWidth; - - // object counter? - if ([cell count] > 0) { - resultWidth += [self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding; - } - - // indicator? - if ([[cell indicator] isHidden] == NO) - resultWidth += kPSMTabBarCellPadding + kPSMTabBarIndicatorWidth; - - // right margin - resultWidth += MARGIN_X; - - return ceil(resultWidth); -} - -- (CGFloat)desiredWidthOfTabCell:(PSMTabBarCell *)cell -{ - CGFloat resultWidth = 0.0; - - // left margin - resultWidth = MARGIN_X; - - // close button? - if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) - resultWidth += [unifiedCloseButton size].width + kPSMTabBarCellPadding; - - // icon? - if ([cell hasIcon]) { - resultWidth += kPSMTabBarIconWidth + kPSMTabBarCellPadding; - } - - // the label - resultWidth += [[cell attributedStringValue] size].width; - - // object counter? - if ([cell count] > 0) { - resultWidth += [self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding; - } - - // indicator? - if ([[cell indicator] isHidden] == NO) - resultWidth += kPSMTabBarCellPadding + kPSMTabBarIndicatorWidth; - - // right margin - resultWidth += MARGIN_X; - - return ceil(resultWidth); -} - -- (CGFloat)tabCellHeight -{ - return kPSMTabBarControlHeight; -} - -#pragma mark - -#pragma mark Cell Values - -- (NSAttributedString *)attributedObjectCountValueForTabCell:(PSMTabBarCell *)cell -{ - NSString *contents = [NSString stringWithFormat:@"%lu", (unsigned long)[cell count]]; - return [[[NSMutableAttributedString alloc] initWithString:contents attributes:_objectCountStringAttributes] autorelease]; -} - -- (NSAttributedString *)attributedStringValueForTabCell:(PSMTabBarCell *)cell -{ - NSMutableAttributedString *attrStr; - NSString * contents = [cell stringValue]; - attrStr = [[[NSMutableAttributedString alloc] initWithString:contents] autorelease]; - NSRange range = NSMakeRange(0, [contents length]); - - [attrStr addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:11.0] range:range]; - - // Paragraph Style for Truncating Long Text - static NSMutableParagraphStyle *TruncatingTailParagraphStyle = nil; - if (!TruncatingTailParagraphStyle) { - TruncatingTailParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; - [TruncatingTailParagraphStyle setLineBreakMode:NSLineBreakByTruncatingTail]; - } - [attrStr addAttribute:NSParagraphStyleAttributeName value:TruncatingTailParagraphStyle range:range]; - - return attrStr; -} - -#pragma mark - -#pragma mark ---- drawing ---- - -- (void)drawTabCell:(PSMTabBarCell *)cell -{ - NSRect cellFrame = [cell frame]; - - NSToolbar *toolbar = [[[cell customControlView] window] toolbar]; - BOOL showsBaselineSeparator = (toolbar && [toolbar respondsToSelector:@selector(showsBaselineSeparator)] && [toolbar showsBaselineSeparator]); - if (!showsBaselineSeparator) { - cellFrame.origin.y += 1.0; - cellFrame.size.height -= 1.0; - } - - NSColor * lineColor = nil; - NSBezierPath* bezier = [NSBezierPath bezierPath]; - lineColor = [NSColor colorWithCalibratedWhite:0.576 alpha:1.0]; - - if (!showsBaselineSeparator || [cell state] == NSOnState) - { - // selected tab - NSRect aRect = NSMakeRect(cellFrame.origin.x+0.5, cellFrame.origin.y-0.5, cellFrame.size.width, cellFrame.size.height); - - // frame - CGFloat radius = MIN(6.0, 0.5f * MIN(NSWidth(aRect), NSHeight(aRect))); - NSRect rect = NSInsetRect(aRect, radius, radius); - - [bezier appendBezierPathWithArcWithCenter:NSMakePoint(NSMinX(rect), NSMinY(rect)) radius:radius startAngle:180.0 endAngle:270.0]; - - [bezier appendBezierPathWithArcWithCenter:NSMakePoint(NSMaxX(rect), NSMinY(rect)) radius:radius startAngle:270.0 endAngle:360.0]; - - NSPoint cornerPoint = NSMakePoint(NSMaxX(aRect), NSMaxY(aRect)); - [bezier appendBezierPathWithPoints:&cornerPoint count:1]; - - cornerPoint = NSMakePoint(NSMinX(aRect), NSMaxY(aRect)); - [bezier appendBezierPathWithPoints:&cornerPoint count:1]; - - [bezier closePath]; - - //[[NSColor windowBackgroundColor] set]; - //[bezier fill]; - if ([NSApp isActive]) { - if ([cell state] == NSOnState) { - [bezier linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.99 alpha:1.0] - endColor:[NSColor colorWithCalibratedWhite:0.941 alpha:1.0]]; - } else if ([cell isHighlighted]) { - [bezier linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.80 alpha:1.0] - endColor:[NSColor colorWithCalibratedWhite:0.80 alpha:1.0]]; - } else { - [bezier linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.835 alpha:1.0] - endColor:[NSColor colorWithCalibratedWhite:0.843 alpha:1.0]]; - } - } - - [lineColor set]; - [bezier stroke]; - } - else - { - // unselected tab - NSRect aRect = NSMakeRect(cellFrame.origin.x, cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height); - aRect.origin.y += 0.5; - aRect.origin.x += 1.5; - aRect.size.width -= 1; - - aRect.origin.x -= 1; - aRect.size.width += 1; - - // rollover - if ([cell isHighlighted]) - { - [[NSColor colorWithCalibratedWhite:0.0 alpha:0.1] set]; - NSRectFillUsingOperation(aRect, NSCompositeSourceAtop); - } - - // frame - - [lineColor set]; - [bezier moveToPoint:NSMakePoint(aRect.origin.x + aRect.size.width, aRect.origin.y-0.5)]; - if (!([cell tabState] & PSMTab_RightIsSelectedMask)) { - [bezier lineToPoint:NSMakePoint(NSMaxX(aRect), NSMaxY(aRect))]; - } - - [bezier stroke]; - - // Create a thin lighter line next to the dividing line for a bezel effect - if (!([cell tabState] & PSMTab_RightIsSelectedMask)) { - [[[NSColor whiteColor] colorWithAlphaComponent:0.5] set]; - [NSBezierPath strokeLineFromPoint:NSMakePoint(NSMaxX(aRect)+1.0, aRect.origin.y-0.5) - toPoint:NSMakePoint(NSMaxX(aRect)+1.0, NSMaxY(aRect)-2.5)]; - } - - // If this is the leftmost tab, we want to draw a line on the left, too - if ([cell tabState] & PSMTab_PositionLeftMask) - { - [lineColor set]; - [NSBezierPath strokeLineFromPoint:NSMakePoint(aRect.origin.x,aRect.origin.y-0.5) - toPoint:NSMakePoint(aRect.origin.x,NSMaxY(aRect)-2.5)]; - [[[NSColor whiteColor] colorWithAlphaComponent:0.5] set]; - [NSBezierPath strokeLineFromPoint:NSMakePoint(aRect.origin.x+1.0,aRect.origin.y-0.5) - toPoint:NSMakePoint(aRect.origin.x+1.0,NSMaxY(aRect)-2.5)]; - } - } - - [self drawInteriorWithTabCell:cell inView:[cell customControlView]]; -} - - -- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView*)controlView -{ - NSRect cellFrame = [cell frame]; - CGFloat labelPosition = cellFrame.origin.x + MARGIN_X; - - // close button - if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { - NSSize closeButtonSize = NSZeroSize; - NSRect closeButtonRect = [cell closeButtonRectForFrame:cellFrame]; - NSImage * closeButton = nil; - - closeButton = [cell isEdited] ? unifiedCloseDirtyButton : unifiedCloseButton; - - if ([cell closeButtonOver]) closeButton = [cell isEdited] ? unifiedCloseDirtyButtonOver : unifiedCloseButtonOver; - if ([cell closeButtonPressed]) closeButton = [cell isEdited] ? unifiedCloseDirtyButtonDown : unifiedCloseButtonDown; - - closeButtonSize = [closeButton size]; - - [closeButton drawInRect:closeButtonRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f respectFlipped:YES hints:nil]; - - // scoot label over - labelPosition += closeButtonSize.width + kPSMTabBarCellPadding; - } - - // icon - if ([cell hasIcon]) { - NSRect iconRect = [self iconRectForTabCell:cell]; - NSImage *icon = [[[cell representedObject] identifier] icon]; - - // center in available space (in case icon image is smaller than kPSMTabBarIconWidth) - if ([icon size].width < kPSMTabBarIconWidth) { - iconRect.origin.x += (kPSMTabBarIconWidth - [icon size].width) / 2.0; - } - if ([icon size].height < kPSMTabBarIconWidth) { - iconRect.origin.y -= (kPSMTabBarIconWidth - [icon size].height) / 2.0; - } - - [icon drawInRect:iconRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f respectFlipped:YES hints:nil]; - - // scoot label over - labelPosition += iconRect.size.width + kPSMTabBarCellPadding; - } - - // label rect - NSRect labelRect; - labelRect.origin.x = labelPosition; - labelRect.size.width = cellFrame.size.width - (labelRect.origin.x - cellFrame.origin.x) - kPSMTabBarCellPadding; - NSSize s = [[cell attributedStringValue] size]; - labelRect.origin.y = cellFrame.origin.y + (cellFrame.size.height-s.height) / 2.0 - 1.0; - labelRect.size.height = s.height; - - if (![[cell indicator] isHidden]) { - labelRect.size.width -= (kPSMTabBarIndicatorWidth + kPSMTabBarCellPadding); - } - - // object counter - if ([cell count] > 0) { - [[cell countColor] ?: [NSColor colorWithCalibratedWhite:0.3 alpha:0.6] set]; - NSBezierPath *path = [NSBezierPath bezierPath]; - NSRect myRect = [self objectCounterRectForTabCell:cell]; - myRect.origin.y -= 1.0; - [path moveToPoint:NSMakePoint(myRect.origin.x + kPSMUnifiedObjectCounterRadius, myRect.origin.y)]; - [path lineToPoint:NSMakePoint(myRect.origin.x + myRect.size.width - kPSMUnifiedObjectCounterRadius, myRect.origin.y)]; - [path appendBezierPathWithArcWithCenter:NSMakePoint(myRect.origin.x + myRect.size.width - kPSMUnifiedObjectCounterRadius, myRect.origin.y + kPSMUnifiedObjectCounterRadius) radius:kPSMUnifiedObjectCounterRadius startAngle:270.0 endAngle:90.0]; - [path lineToPoint:NSMakePoint(myRect.origin.x + kPSMUnifiedObjectCounterRadius, myRect.origin.y + myRect.size.height)]; - [path appendBezierPathWithArcWithCenter:NSMakePoint(myRect.origin.x + kPSMUnifiedObjectCounterRadius, myRect.origin.y + kPSMUnifiedObjectCounterRadius) radius:kPSMUnifiedObjectCounterRadius startAngle:90.0 endAngle:270.0]; - [path fill]; - - // draw attributed string centered in area - NSRect counterStringRect; - NSAttributedString *counterString = [self attributedObjectCountValueForTabCell:cell]; - counterStringRect.size = [counterString size]; - counterStringRect.origin.x = myRect.origin.x + ((myRect.size.width - counterStringRect.size.width) / 2.0) + 0.25; - counterStringRect.origin.y = myRect.origin.y + ((myRect.size.height - counterStringRect.size.height) / 2.0) + 0.5; - [counterString drawInRect:counterStringRect]; - - labelRect.size.width -= myRect.size.width + kPSMTabBarCellPadding; - } - - // label - [[cell attributedStringValue] drawInRect:labelRect]; -} - -- (void)drawBackgroundInRect:(NSRect)rect -{ - //Draw for our whole bounds; it'll be automatically clipped to fit the appropriate drawing area - rect = [tabBar bounds]; - - NSRect gradientRect = rect; - gradientRect.size.height -= 1.0; - - NSBezierPath *path = [NSBezierPath bezierPathWithRect:gradientRect]; - [path linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.835 alpha:1.0] - endColor:[NSColor colorWithCalibratedWhite:0.843 alpha:1.0]]; - [[NSColor colorWithCalibratedWhite:0.576 alpha:1.0] set]; - [NSBezierPath strokeLineFromPoint:NSMakePoint(rect.origin.x, NSMaxY(rect) - 0.5) - toPoint:NSMakePoint(NSMaxX(rect), NSMaxY(rect) - 0.5)]; - - if (![[[tabBar tabView] window] isKeyWindow]) { - [[NSColor windowBackgroundColor] set]; - NSRectFill(gradientRect); - } -} - -- (void)drawTabBar:(PSMTabBarControl *)bar inRect:(NSRect)rect -{ - tabBar = bar; - [self drawBackgroundInRect:rect]; - - // no tab view == not connected - if (![bar tabView]) { - NSRect labelRect = rect; - labelRect.size.height -= 4.0; - labelRect.origin.y += 4.0; - NSMutableAttributedString *attrStr; - NSString *contents = @"PSMTabBarControl"; - attrStr = [[[NSMutableAttributedString alloc] initWithString:contents] autorelease]; - NSRange range = NSMakeRange(0, [contents length]); - [attrStr addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:11.0] range:range]; - NSMutableParagraphStyle *centeredParagraphStyle = nil; - if (!centeredParagraphStyle) { - centeredParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; - [centeredParagraphStyle setAlignment:NSCenterTextAlignment]; - } - [attrStr addAttribute:NSParagraphStyleAttributeName value:centeredParagraphStyle range:range]; - [centeredParagraphStyle release]; - [attrStr drawInRect:labelRect]; - return; - } - - // draw cells - NSEnumerator *e = [[bar cells] objectEnumerator]; - PSMTabBarCell *cell; - while ( (cell = [e nextObject]) ) { - if ([bar isAnimating] || (![cell isInOverflowMenu] && NSIntersectsRect([cell frame], rect))) { - [cell drawWithFrame:[cell frame] inView:bar]; - } - } -} - -#pragma mark - -#pragma mark Archiving - -- (void)encodeWithCoder:(NSCoder *)aCoder -{ -/* - //[super encodeWithCoder:aCoder]; - if ([aCoder allowsKeyedCoding]) { - [aCoder encodeObject:unifiedCloseButton forKey:@"unifiedCloseButton"]; - [aCoder encodeObject:unifiedCloseButtonDown forKey:@"unifiedCloseButtonDown"]; - [aCoder encodeObject:unifiedCloseButtonOver forKey:@"unifiedCloseButtonOver"]; - [aCoder encodeObject:unifiedCloseDirtyButton forKey:@"unifiedCloseDirtyButton"]; - [aCoder encodeObject:unifiedCloseDirtyButtonDown forKey:@"unifiedCloseDirtyButtonDown"]; - [aCoder encodeObject:unifiedCloseDirtyButtonOver forKey:@"unifiedCloseDirtyButtonOver"]; - [aCoder encodeObject:_addTabButtonImage forKey:@"addTabButtonImage"]; - [aCoder encodeObject:_addTabButtonPressedImage forKey:@"addTabButtonPressedImage"]; - [aCoder encodeObject:_addTabButtonRolloverImage forKey:@"addTabButtonRolloverImage"]; - } -*/ -} - -- (id)initWithCoder:(NSCoder *)aDecoder -{ - self = [self init]; - if (self) { - /* - if ([aDecoder allowsKeyedCoding]) { - unifiedCloseButton = [[aDecoder decodeObjectForKey:@"unifiedCloseButton"] retain]; - unifiedCloseButtonDown = [[aDecoder decodeObjectForKey:@"unifiedCloseButtonDown"] retain]; - unifiedCloseButtonOver = [[aDecoder decodeObjectForKey:@"unifiedCloseButtonOver"] retain]; - unifiedCloseDirtyButton = [[aDecoder decodeObjectForKey:@"unifiedCloseDirtyButton"] retain]; - unifiedCloseDirtyButtonDown = [[aDecoder decodeObjectForKey:@"unifiedCloseDirtyButtonDown"] retain]; - unifiedCloseDirtyButtonOver = [[aDecoder decodeObjectForKey:@"unifiedCloseDirtyButtonOver"] retain]; - _addTabButtonImage = [[aDecoder decodeObjectForKey:@"addTabButtonImage"] retain]; - _addTabButtonPressedImage = [[aDecoder decodeObjectForKey:@"addTabButtonPressedImage"] retain]; - _addTabButtonRolloverImage = [[aDecoder decodeObjectForKey:@"addTabButtonRolloverImage"] retain]; - } - */ - } - return self; -} - -@end diff --git a/Frameworks/SPMySQLFramework/SPMySQLFramework.xcodeproj/project.pbxproj b/Frameworks/SPMySQLFramework/SPMySQLFramework.xcodeproj/project.pbxproj index 778b97f9..aa7989fc 100644 --- a/Frameworks/SPMySQLFramework/SPMySQLFramework.xcodeproj/project.pbxproj +++ b/Frameworks/SPMySQLFramework/SPMySQLFramework.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 177916A21E88733000EE3043 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 177916A01E88733000EE3043 /* LICENSE */; }; 17E3A57B1885A286009CF372 /* SPMySQLDataTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 17E3A5791885A286009CF372 /* SPMySQLDataTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17E3A57C1885A286009CF372 /* SPMySQLDataTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = 17E3A57A1885A286009CF372 /* SPMySQLDataTypes.m */; }; 507FF1E51BC0D82300104523 /* DataConversion_Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 507FF1811BC0C64100104523 /* DataConversion_Tests.m */; }; @@ -93,6 +94,8 @@ 0867D6A5FE840307C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; }; 089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; }; + 177916A01E88733000EE3043 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; }; + 177916A11E88733000EE3043 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; }; 17E3A5791885A286009CF372 /* SPMySQLDataTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPMySQLDataTypes.h; sourceTree = "<group>"; }; 17E3A57A1885A286009CF372 /* SPMySQLDataTypes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPMySQLDataTypes.m; sourceTree = "<group>"; }; 32DBCF5E0370ADEE00C91783 /* SPMySQLFramework_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SPMySQLFramework_Prefix.pch; path = Source/SPMySQLFramework_Prefix.pch; sourceTree = "<group>"; }; @@ -133,7 +136,6 @@ 584F16A71752911100D150A6 /* SPMySQLStreamingResultStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SPMySQLStreamingResultStore.m; path = Source/SPMySQLStreamingResultStore.m; sourceTree = "<group>"; }; 586A99F914F02E21007F82BF /* SPMySQLStreamingResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SPMySQLStreamingResult.h; path = Source/SPMySQLStreamingResult.h; sourceTree = "<group>"; }; 586A99FA14F02E21007F82BF /* SPMySQLStreamingResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SPMySQLStreamingResult.m; path = Source/SPMySQLStreamingResult.m; sourceTree = "<group>"; }; - 586AA0E714F1CEC8007F82BF /* Readme.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Readme.txt; sourceTree = "<group>"; }; 586AA16514F30C5F007F82BF /* Convenience Methods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Convenience Methods.h"; path = "Source/SPMySQLResult Categories/Convenience Methods.h"; sourceTree = "<group>"; }; 586AA16614F30C5F007F82BF /* Convenience Methods.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "Convenience Methods.m"; path = "Source/SPMySQLResult Categories/Convenience Methods.m"; sourceTree = "<group>"; }; 586AA81214F6C648007F82BF /* SPMySQLArrayAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SPMySQLArrayAdditions.h; path = Source/SPMySQLArrayAdditions.h; sourceTree = "<group>"; }; @@ -204,7 +206,8 @@ 0867D691FE84028FC02AAC07 /* SPMySQLFramework */ = { isa = PBXGroup; children = ( - 586AA0E714F1CEC8007F82BF /* Readme.txt */, + 177916A01E88733000EE3043 /* LICENSE */, + 177916A11E88733000EE3043 /* README.md */, 5884127614CC63830078027F /* SPMySQL.h */, 58C0077714E1DFFF00AC489A /* Protocols */, 08FB77AEFE84172EC02AAC07 /* Classes */, @@ -540,6 +543,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 177916A21E88733000EE3043 /* LICENSE in Resources */, 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Interfaces/English.lproj/ConnectionView.xib b/Interfaces/English.lproj/ConnectionView.xib index f11e8fbc..05ced791 100644 --- a/Interfaces/English.lproj/ConnectionView.xib +++ b/Interfaces/English.lproj/ConnectionView.xib @@ -1,8 +1,9 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10116" systemVersion="15E65" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none"> +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6751" systemVersion="13F1507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none"> <dependencies> <deployment identifier="macosx"/> - <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10116"/> + <development version="5100" identifier="xcode"/> + <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6751"/> </dependencies> <objects> <customObject id="-2" userLabel="File's Owner" customClass="SPConnectionController"> @@ -182,7 +183,7 @@ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="firstColumnOnly" selectionHighlightStyle="sourceList" columnReordering="NO" columnSelection="YES" columnResizing="NO" autosaveColumns="NO" id="4913" customClass="SPFavoritesOutlineView"> - <rect key="frame" x="0.0" y="0.0" width="200" height="19"/> + <rect key="frame" x="0.0" y="0.0" width="200" height="483"/> <autoresizingMask key="autoresizingMask"/> <size key="intercellSpacing" width="3" height="2"/> <color key="backgroundColor" name="_sourceListBackgroundColor" catalog="System" colorSpace="catalog"/> @@ -252,7 +253,7 @@ <scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="5588"> <rect key="frame" x="0.0" y="0.0" width="681" height="481"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> - <clipView key="contentView" id="gFs-TM-wGu"> + <clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="gFs-TM-wGu"> <rect key="frame" x="0.0" y="0.0" width="681" height="481"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> @@ -1625,7 +1626,7 @@ DQ <rect key="frame" x="0.0" y="0.0" width="578" height="293"/> <autoresizingMask key="autoresizingMask"/> <subviews> - <textView editable="NO" drawsBackground="NO" importsGraphics="NO" verticallyResizable="YES" id="5434"> + <textView editable="NO" drawsBackground="NO" importsGraphics="NO" id="5434"> <rect key="frame" x="0.0" y="0.0" width="578" height="293"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="textColor" red="0.90196078999999996" green="0.90196078999999996" blue="0.90196078999999996" alpha="1" colorSpace="calibratedRGB"/> @@ -2378,8 +2379,6 @@ DQ </fragment> </attributedString> <color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> - <size key="minSize" width="578" height="293"/> - <size key="maxSize" width="1156" height="10000000"/> <connections> <outlet property="delegate" destination="-2" id="5462"/> </connections> @@ -2545,7 +2544,7 @@ DQ <action selector="renameNode:" target="-2" id="5819"/> </connections> </menuItem> - <menuItem title="Remove" id="5794"> + <menuItem title="Delete" id="5794"> <modifierMask key="keyEquivalentModifierMask"/> <connections> <action selector="removeNode:" target="-2" id="5802"/> @@ -2596,8 +2595,8 @@ DQ <image name="button_action" width="30" height="22"/> <image name="button_add" width="30" height="22"/> <image name="button_add_folder" width="30" height="22"/> - <image name="button_bar_handle" width="11" height="23"/> - <image name="button_bar_spacer" width="10" height="23"/> + <image name="button_bar_handle" width="15" height="23"/> + <image name="button_bar_spacer" width="11" height="23"/> <image name="key-icon" width="16" height="9"/> <image name="key-icon-alternate" width="16" height="9"/> </resources> diff --git a/Interfaces/English.lproj/Console.xib b/Interfaces/English.lproj/Console.xib index 9cbd0526..fb852146 100644 --- a/Interfaces/English.lproj/Console.xib +++ b/Interfaces/English.lproj/Console.xib @@ -1,7 +1,7 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?xml version="1.0" encoding="UTF-8"?> <document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6751" systemVersion="13F1507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none"> <dependencies> - <deployment identifier="macosx"/> + <deployment identifier="macosx"/> <development version="5100" identifier="xcode"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6751"/> </dependencies> @@ -22,7 +22,7 @@ </connections> </customObject> <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> - <customObject id="-3" userLabel="Application"/> + <customObject id="-3" userLabel="Application" customClass="NSObject"/> <window title="Console" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" showsToolbarButton="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="3" userLabel="Console" customClass="NSPanel"> <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/> <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/> @@ -33,8 +33,8 @@ <rect key="frame" x="0.0" y="0.0" width="575" height="203"/> <autoresizingMask key="autoresizingMask"/> <subviews> - <imageView id="71"> - <rect key="frame" x="62" y="0.0" width="513" height="23"/> + <imageView misplaced="YES" id="71"> + <rect key="frame" x="-1" y="0.0" width="578" height="23"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/> <imageCell key="cell" refusesFirstResponder="YES" alignment="left" animates="YES" imageScaling="axesIndependently" image="button_bar_spacer" id="72"/> </imageView> @@ -49,7 +49,7 @@ <action selector="saveConsoleAs:" target="-2" id="54"/> </connections> </button> - <searchField verticalHuggingPriority="750" id="8"> + <searchField wantsLayer="YES" verticalHuggingPriority="750" id="8"> <rect key="frame" x="10" y="174" width="531" height="19"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> <searchFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" placeholderString="Filter" usesSingleLineMode="YES" bezelStyle="round" id="13"> @@ -65,14 +65,14 @@ <rect key="frame" x="-1" y="22" width="578" height="144"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" id="Jw2-4l-Mr3"> - <rect key="frame" x="1" y="17" width="576" height="126"/> + <rect key="frame" x="1" y="0.0" width="576" height="143"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" autosaveColumns="NO" rowHeight="16" headerView="112" id="14"> <rect key="frame" x="0.0" y="0.0" width="576" height="126"/> <autoresizingMask key="autoresizingMask"/> <size key="intercellSpacing" width="3" height="2"/> - <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/> <tableColumns> <tableColumn identifier="messageDate" editable="NO" width="100" minWidth="50" maxWidth="1000" id="18"> @@ -135,7 +135,6 @@ </connections> </tableView> </subviews> - <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> </clipView> <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="15"> <rect key="frame" x="1" y="127" width="576" height="16"/> @@ -148,6 +147,9 @@ <tableHeaderView key="headerView" id="112"> <rect key="frame" x="0.0" y="0.0" width="576" height="17"/> <autoresizingMask key="autoresizingMask"/> + <connections> + <outlet property="menu" destination="DCA-JR-zjw" id="2UH-9N-pS2"/> + </connections> </tableHeaderView> </scrollView> <progressIndicator hidden="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" minValue="16" maxValue="100" doubleValue="16" bezeled="NO" indeterminate="YES" controlSize="small" style="spinning" id="62"> @@ -157,20 +159,20 @@ <button toolTip="Clear Console" id="73"> <rect key="frame" x="30" y="-1" width="32" height="25"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> - <buttonCell key="cell" type="roundTextured" title="Clear" bezelStyle="texturedRounded" image="button_clear" imagePosition="only" alignment="center" state="on" imageScaling="proportionallyDown" inset="2" id="74"> - <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> + <buttonCell key="cell" type="roundTextured" title="Clear" bezelStyle="texturedRounded" image="button_clear" imagePosition="only" alignment="center" alternateImage="button_clear" state="on" imageScaling="proportionallyDown" inset="2" id="74"> + <behavior key="behavior" lightByContents="YES"/> <font key="font" metaFont="system"/> </buttonCell> <connections> <action selector="clearConsole:" target="-2" id="75"/> </connections> </button> - <popUpButton id="77"> + <popUpButton id="77" userLabel="Gear Menu Button"> <rect key="frame" x="-2" y="0.0" width="36" height="23"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <popUpButtonCell key="cell" type="bevel" bezelStyle="regularSquare" imagePosition="right" alignment="center" lineBreakMode="truncatingTail" inset="2" pullsDown="YES" arrowPosition="noArrow" selectedItem="80" id="78"> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> - <font key="font" metaFont="system"/> + <font key="font" metaFont="menu"/> <menu key="menu" title="OtherViews" id="79"> <items> <menuItem image="button_action" hidden="YES" id="83"/> @@ -241,6 +243,7 @@ </textField> </subviews> </view> + <point key="canvasLocation" x="139.5" y="161.5"/> </window> <customView id="49" userLabel="saveLogView"> <rect key="frame" x="0.0" y="0.0" width="278" height="79"/> @@ -272,7 +275,7 @@ </button> </subviews> </customView> - <menu id="64"> + <menu id="64" userLabel="Table Row Context Menu"> <items> <menuItem title="Copy" id="65"> <modifierMask key="keyEquivalentModifierMask"/> @@ -283,10 +286,50 @@ </items> </menu> <userDefaultsController representsSharedInstance="YES" id="89"/> + <menu id="DCA-JR-zjw" userLabel="Table Header Context Menu"> + <items> + <menuItem title="Time" state="on" id="Eqs-r2-Xz7"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="toggleShowTimeStamps:" target="-2" id="OMU-jP-CeY"/> + <binding destination="89" name="value" keyPath="values.ConsoleShowTimestamps" id="62b-Yd-Tlr"> + <dictionary key="options"> + <bool key="NSConditionallySetsEnabled" value="NO"/> + </dictionary> + </binding> + </connections> + </menuItem> + <menuItem title="Connection" state="on" id="xEF-YU-b4J"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="toggleShowConnections:" target="-2" id="Hhw-0n-qWg"/> + <binding destination="89" name="value" keyPath="values.ConsoleShowConnections" id="YKo-wm-6u8"> + <dictionary key="options"> + <bool key="NSConditionallySetsEnabled" value="NO"/> + </dictionary> + </binding> + </connections> + </menuItem> + <menuItem title="Database" state="on" id="kNX-td-f8A"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="toggleShowDatabases:" target="-2" id="1z7-qp-tCQ"/> + <binding destination="89" name="value" keyPath="values.ConsoleShowDatabases" id="0w1-96-uH9"> + <dictionary key="options"> + <bool key="NSConditionallySetsEnabled" value="NO"/> + </dictionary> + </binding> + </connections> + </menuItem> + <menuItem title="Query" state="on" enabled="NO" id="VWx-bC-aFb"> + <modifierMask key="keyEquivalentModifierMask"/> + </menuItem> + </items> + </menu> </objects> <resources> - <image name="button_action" width="16" height="16"/> - <image name="button_bar_spacer" width="10" height="29"/> - <image name="button_clear" width="32" height="23"/> + <image name="button_action" width="30" height="22"/> + <image name="button_bar_spacer" width="11" height="23"/> + <image name="button_clear" width="30" height="22"/> </resources> </document> diff --git a/Interfaces/English.lproj/DBView.xib b/Interfaces/English.lproj/DBView.xib index 05c769e3..8742c655 100644 --- a/Interfaces/English.lproj/DBView.xib +++ b/Interfaces/English.lproj/DBView.xib @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none"> +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6751" systemVersion="13F1507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none"> <dependencies> <deployment identifier="macosx"/> <development version="5100" identifier="xcode"/> - <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/> - <plugIn identifier="com.apple.WebKitIBPlugin" version="10117"/> + <plugIn identifier="com.apple.WebKitIBPlugin" version="11762"/> + <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6751"/> </dependencies> <objects> <customObject id="-2" userLabel="File's Owner" customClass="SPDatabaseDocument"> @@ -104,7 +104,7 @@ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" selectionHighlightStyle="sourceList" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" typeSelect="NO" id="6685"> - <rect key="frame" x="0.0" y="0.0" width="218" height="19"/> + <rect key="frame" x="0.0" y="0.0" width="218" height="38"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> <size key="intercellSpacing" width="3" height="2"/> <color key="backgroundColor" name="_sourceListBackgroundColor" catalog="System" colorSpace="catalog"/> @@ -165,7 +165,7 @@ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <tableView identifier="TablesListTableView" focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="sequential" selectionHighlightStyle="sourceList" columnReordering="NO" autosaveColumns="NO" id="22" customClass="SPTableView"> - <rect key="frame" x="0.0" y="0.0" width="214" height="19"/> + <rect key="frame" x="0.0" y="0.0" width="214" height="334"/> <autoresizingMask key="autoresizingMask"/> <size key="intercellSpacing" width="3" height="2"/> <color key="backgroundColor" name="_sourceListBackgroundColor" catalog="System" colorSpace="catalog"/> @@ -231,7 +231,7 @@ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="sequential" selectionHighlightStyle="sourceList" columnReordering="NO" multipleSelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="45" id="7692" userLabel="Table View (Activities)"> - <rect key="frame" x="0.0" y="0.0" width="216" height="47"/> + <rect key="frame" x="0.0" y="0.0" width="216" height="166"/> <autoresizingMask key="autoresizingMask"/> <size key="intercellSpacing" width="3" height="2"/> <color key="backgroundColor" name="_sourceListBackgroundColor" catalog="System" colorSpace="catalog"/> @@ -276,7 +276,7 @@ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="sequential" selectionHighlightStyle="sourceList" columnReordering="NO" multipleSelection="NO" autosaveColumns="NO" typeSelect="NO" id="4484"> - <rect key="frame" x="0.0" y="0.0" width="214" height="19"/> + <rect key="frame" x="0.0" y="0.0" width="214" height="166"/> <autoresizingMask key="autoresizingMask"/> <size key="intercellSpacing" width="3" height="2"/> <color key="backgroundColor" name="_sourceListBackgroundColor" catalog="System" colorSpace="catalog"/> @@ -464,25 +464,25 @@ <rect key="frame" x="215" y="0.0" width="728" height="549"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> - <tabView controlSize="small" type="rightTabsBezelBorder" initialItem="28" id="25"> - <rect key="frame" x="-7" y="-10" width="741" height="564"/> + <tabView misplaced="YES" controlSize="small" type="rightTabsBezelBorder" initialItem="28" id="25"> + <rect key="frame" x="-7" y="-10" width="741" height="566"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <tabViewItems> <tabViewItem label="Structure" identifier="source" id="28"> <view key="view" identifier="StructureTabView" id="29"> - <rect key="frame" x="10" y="7" width="706" height="544"/> + <rect key="frame" x="10" y="7" width="702" height="546"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <splitView dividerStyle="thin" id="674"> - <rect key="frame" x="7" y="10" width="695" height="530"/> + <rect key="frame" x="7" y="10" width="691" height="532"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <customView identifier="TableStructureColumnsView" id="673"> - <rect key="frame" x="0.0" y="0.0" width="695" height="328"/> + <rect key="frame" x="0.0" y="0.0" width="691" height="329"/> <autoresizingMask key="autoresizingMask"/> <subviews> <button toolTip="Edit Table Details (⌘4)" id="6009"> - <rect key="frame" x="632" y="-1" width="32" height="25"/> + <rect key="frame" x="628" y="-1" width="32" height="25"/> <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/> <buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="button_edit" imagePosition="overlaps" alignment="center" enabled="NO" state="on" inset="2" id="6010"> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> @@ -495,12 +495,12 @@ </connections> </button> <imageView id="5129"> - <rect key="frame" x="-1" y="0.0" width="692" height="23"/> + <rect key="frame" x="-1" y="0.0" width="688" height="23"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/> <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="axesIndependently" image="button_bar_spacer" id="5130"/> </imageView> <popUpButton id="8025"> - <rect key="frame" x="663" y="0.0" width="36" height="23"/> + <rect key="frame" x="659" y="0.0" width="36" height="23"/> <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/> <popUpButtonCell key="cell" type="bevel" bezelStyle="regularSquare" imagePosition="right" alignment="center" lineBreakMode="truncatingTail" state="on" inset="2" pullsDown="YES" arrowPosition="noArrow" selectedItem="8028" id="8026"> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> @@ -595,14 +595,14 @@ </connections> </button> <scrollView focusRingType="none" autohidesScrollers="YES" horizontalLineScroll="18" horizontalPageScroll="10" verticalLineScroll="18" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="231"> - <rect key="frame" x="-1" y="22" width="696" height="306"/> + <rect key="frame" x="-1" y="22" width="692" height="306"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" id="07n-i9-O0i"> - <rect key="frame" x="1" y="23" width="694" height="282"/> + <rect key="frame" x="1" y="0.0" width="690" height="305"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <tableView identifier="TableStructureColumnsTableView" focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" alternatingRowBackgroundColors="YES" multipleSelection="NO" autosaveName="SPTableStructureSource" rowHeight="16" headerView="3926" id="232" customClass="SPTableView"> - <rect key="frame" x="0.0" y="0.0" width="688" height="18"/> + <rect key="frame" x="0.0" y="0.0" width="690" height="283"/> <autoresizingMask key="autoresizingMask"/> <size key="intercellSpacing" width="3" height="2"/> <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> @@ -675,7 +675,7 @@ </buttonCell> <tableColumnResizingMask key="resizingMask" userResizable="YES"/> </tableColumn> - <tableColumn identifier="binary" width="37" minWidth="14" maxWidth="37" id="749"> + <tableColumn identifier="binary" width="37" minWidth="14" maxWidth="39" id="749"> <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Binary"> <font key="font" metaFont="smallSystem"/> <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/> @@ -799,7 +799,6 @@ </connections> </tableView> </subviews> - <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> </clipView> <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="3925"> <rect key="frame" x="1" y="289" width="690" height="16"/> @@ -810,7 +809,7 @@ <autoresizingMask key="autoresizingMask"/> </scroller> <tableHeaderView key="headerView" id="3926"> - <rect key="frame" x="0.0" y="0.0" width="692" height="23"/> + <rect key="frame" x="0.0" y="0.0" width="690" height="17"/> <autoresizingMask key="autoresizingMask"/> <connections> <outlet property="menu" destination="8056" id="Uxa-5O-Q0T"/> @@ -834,11 +833,11 @@ </subviews> </customView> <customView identifier="TableStructureIndexesView" id="672"> - <rect key="frame" x="0.0" y="329" width="695" height="201"/> + <rect key="frame" x="0.0" y="330" width="691" height="202"/> <autoresizingMask key="autoresizingMask"/> <subviews> <imageView id="5148"> - <rect key="frame" x="-1" y="0.0" width="692" height="23"/> + <rect key="frame" x="-1" y="0.0" width="688" height="23"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/> <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="axesIndependently" image="button_bar_spacer" id="5149"/> </imageView> @@ -878,14 +877,14 @@ </connections> </button> <scrollView identifier="TableStructureIndexesTableScrollView" focusRingType="none" autohidesScrollers="YES" horizontalLineScroll="18" horizontalPageScroll="10" verticalLineScroll="18" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="287"> - <rect key="frame" x="-1" y="22" width="696" height="159"/> + <rect key="frame" x="-1" y="22" width="692" height="160"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" id="N3x-Gt-GZH"> - <rect key="frame" x="1" y="23" width="694" height="135"/> + <rect key="frame" x="1" y="0.0" width="690" height="159"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <tableView identifier="TableStructureIndexesTableView" focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" alternatingRowBackgroundColors="YES" multipleSelection="NO" autosaveColumns="NO" rowHeight="16" headerView="3923" id="289" customClass="SPTableView"> - <rect key="frame" x="0.0" y="0.0" width="690" height="18"/> + <rect key="frame" x="0.0" y="0.0" width="690" height="136"/> <autoresizingMask key="autoresizingMask"/> <size key="intercellSpacing" width="3" height="2"/> <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> @@ -1016,10 +1015,9 @@ </connections> </tableView> </subviews> - <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> </clipView> <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="3922"> - <rect key="frame" x="1" y="142" width="690" height="16"/> + <rect key="frame" x="1" y="143" width="690" height="16"/> <autoresizingMask key="autoresizingMask"/> </scroller> <scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="3921"> @@ -1027,12 +1025,12 @@ <autoresizingMask key="autoresizingMask"/> </scroller> <tableHeaderView key="headerView" id="3923"> - <rect key="frame" x="0.0" y="0.0" width="694" height="23"/> + <rect key="frame" x="0.0" y="0.0" width="690" height="17"/> <autoresizingMask key="autoresizingMask"/> </tableHeaderView> </scrollView> <view id="6024"> - <rect key="frame" x="0.0" y="181" width="695" height="20"/> + <rect key="frame" x="0.0" y="182" width="691" height="20"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> <subviews> <textField verticalHuggingPriority="750" id="6027"> @@ -1045,7 +1043,7 @@ </textFieldCell> </textField> <imageView id="4503"> - <rect key="frame" x="678" y="3" width="10" height="13"/> + <rect key="frame" x="674" y="3" width="10" height="13"/> <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/> <imageCell key="cell" refusesFirstResponder="YES" alignment="left" image="grabber-horizontal" id="4504"/> </imageView> @@ -1194,7 +1192,7 @@ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="kdv-Wp-s5h"> <rect key="frame" x="0.0" y="0.0" width="607" height="27"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <autoresizingMask key="autoresizingMask"/> <subviews> <ruleEditor nestingMode="compound" canRemoveAllRows="YES" rowHeight="25" id="FF9-z2-9od"> <rect key="frame" x="0.0" y="0.0" width="607" height="27"/> @@ -1358,11 +1356,11 @@ <rect key="frame" x="-1" y="-2" width="696" height="450"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" id="lwO-LP-RWZ"> - <rect key="frame" x="1" y="23" width="694" height="426"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <rect key="frame" x="1" y="0.0" width="694" height="449"/> + <autoresizingMask key="autoresizingMask"/> <subviews> <tableView identifier="TableContentTableView" focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="none" alternatingRowBackgroundColors="YES" autosaveColumns="NO" rowHeight="16" headerView="3920" id="36" customClass="SPCopyTable"> - <rect key="frame" x="0.0" y="0.0" width="626" height="18"/> + <rect key="frame" x="0.0" y="0.0" width="694" height="426"/> <autoresizingMask key="autoresizingMask"/> <size key="intercellSpacing" width="3" height="2"/> <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> @@ -1389,7 +1387,6 @@ </connections> </tableView> </subviews> - <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> </clipView> <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="0.021626397967338562" horizontal="YES" id="3919"> <rect key="frame" x="1" y="458" width="429" height="15"/> @@ -1400,7 +1397,7 @@ <autoresizingMask key="autoresizingMask"/> </scroller> <tableHeaderView key="headerView" id="3920"> - <rect key="frame" x="0.0" y="0.0" width="694" height="23"/> + <rect key="frame" x="0.0" y="0.0" width="694" height="17"/> <autoresizingMask key="autoresizingMask"/> </tableHeaderView> </scrollView> @@ -1420,7 +1417,7 @@ </tabViewItem> <tabViewItem label="Custom Query" identifier="customQuery" id="119"> <view key="view" identifier="QueryTabView" id="120"> - <rect key="frame" x="10" y="7" width="706" height="544"/> + <rect key="frame" x="10" y="7" width="706" height="546"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <imageView id="7965"> @@ -1488,37 +1485,35 @@ </connections> </button> <splitView dividerStyle="thin" id="7206" customClass="SPSplitView"> - <rect key="frame" x="6" y="33" width="696" height="509"/> + <rect key="frame" x="6" y="33" width="696" height="511"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <view id="7207"> <rect key="frame" x="0.0" y="0.0" width="696" height="391"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> - <splitView id="7209" customClass="SPSplitView"> - <rect key="frame" x="0.0" y="0.0" width="696" height="389"/> + <splitView misplaced="YES" id="7209" customClass="SPSplitView"> + <rect key="frame" x="0.0" y="0.0" width="696" height="387"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <customView id="7210"> - <rect key="frame" x="0.0" y="0.0" width="696" height="143"/> + <rect key="frame" x="0.0" y="0.0" width="696" height="142"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <scrollView focusRingType="none" autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" id="8251"> - <rect key="frame" x="0.0" y="1" width="696" height="143"/> + <rect key="frame" x="0.0" y="1" width="696" height="142"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" id="npE-bg-ppa"> - <rect key="frame" x="1" y="1" width="694" height="141"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <rect key="frame" x="1" y="1" width="694" height="140"/> + <autoresizingMask key="autoresizingMask"/> <subviews> - <textView focusRingType="none" importsGraphics="NO" richText="NO" horizontallyResizable="YES" findStyle="panel" allowsDocumentBackgroundColorChange="YES" allowsUndo="YES" usesRuler="YES" usesFontPanel="YES" verticallyResizable="YES" id="8254" customClass="SPTextView"> - <rect key="frame" x="0.0" y="0.0" width="694" height="141"/> + <textView focusRingType="none" importsGraphics="NO" richText="NO" horizontallyResizable="YES" usesFontPanel="YES" findStyle="panel" allowsDocumentBackgroundColorChange="YES" allowsUndo="YES" usesRuler="YES" id="8254" customClass="SPTextView"> + <rect key="frame" x="0.0" y="0.0" width="694" height="140"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> - <size key="minSize" width="694" height="141"/> + <size key="minSize" width="694" height="140"/> <size key="maxSize" width="100000" height="10000000"/> <color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> - <size key="minSize" width="694" height="141"/> - <size key="maxSize" width="100000" height="10000000"/> <connections> <binding destination="1907" name="textColor" keyPath="values.CustomQueryEditorTextColor" id="8258"> <dictionary key="options"> @@ -1540,23 +1535,23 @@ <autoresizingMask key="autoresizingMask"/> </scroller> <scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="8252"> - <rect key="frame" x="224" y="1" width="15" height="133"/> + <rect key="frame" x="679" y="1" width="16" height="140"/> <autoresizingMask key="autoresizingMask"/> </scroller> </scrollView> </subviews> </customView> <customView id="7211"> - <rect key="frame" x="0.0" y="152" width="696" height="237"/> + <rect key="frame" x="0.0" y="151" width="696" height="236"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <imageView id="7222"> - <rect key="frame" x="0.0" y="214" width="696" height="23"/> + <rect key="frame" x="0.0" y="213" width="696" height="23"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="axesIndependently" image="button_bar_spacer" id="7230"/> </imageView> <popUpButton id="7221"> - <rect key="frame" x="0.0" y="214" width="35" height="23"/> + <rect key="frame" x="0.0" y="213" width="35" height="23"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <popUpButtonCell key="cell" type="bevel" bezelStyle="regularSquare" imagePosition="right" alignment="center" lineBreakMode="truncatingTail" inset="2" pullsDown="YES" arrowPosition="noArrow" autoenablesItems="NO" selectedItem="7236" id="7231"> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> @@ -1691,7 +1686,7 @@ Gw </popUpButtonCell> </popUpButton> <popUpButton toolTip="Choose a favorite from the menu or save queries to the favorites (⌥⌘F)" verticalHuggingPriority="750" id="7218"> - <rect key="frame" x="38" y="214" width="129" height="22"/> + <rect key="frame" x="38" y="213" width="129" height="22"/> <autoresizingMask key="autoresizingMask" flexibleMinY="YES"/> <popUpButtonCell key="cell" type="recessed" title="Query Favorites" bezelStyle="recessed" alignment="center" controlSize="small" lineBreakMode="clipping" borderStyle="borderAndBezel" inset="2" pullsDown="YES" preferredEdge="maxY" selectedItem="7264" id="7262"> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/> @@ -1727,7 +1722,7 @@ Gw </connections> </popUpButton> <popUpButton toolTip="Choose a query from your recent queries (⌥⌘Y)" verticalHuggingPriority="750" id="7217"> - <rect key="frame" x="177" y="214" width="145" height="22"/> + <rect key="frame" x="177" y="213" width="145" height="22"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <popUpButtonCell key="cell" type="recessed" title="Query History" bezelStyle="recessed" alignment="center" controlSize="small" lineBreakMode="clipping" borderStyle="borderAndBezel" inset="2" pullsDown="YES" preferredEdge="maxY" selectedItem="7273" id="7271"> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/> @@ -1779,14 +1774,14 @@ Gw </connections> </popUpButton> <scrollView focusRingType="none" autohidesScrollers="YES" horizontalLineScroll="18" horizontalPageScroll="10" verticalLineScroll="18" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="7223"> - <rect key="frame" x="0.0" y="-1" width="696" height="215"/> + <rect key="frame" x="0.0" y="-1" width="696" height="214"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" id="NVV-XL-mVZ"> - <rect key="frame" x="1" y="23" width="694" height="191"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <rect key="frame" x="1" y="0.0" width="694" height="213"/> + <autoresizingMask key="autoresizingMask"/> <subviews> <tableView identifier="CustomQueryResultsTableView" focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" autosaveColumns="NO" rowHeight="16" headerView="7227" id="7224" customClass="SPCopyTable"> - <rect key="frame" x="0.0" y="0.0" width="694" height="191"/> + <rect key="frame" x="0.0" y="0.0" width="694" height="190"/> <autoresizingMask key="autoresizingMask"/> <size key="intercellSpacing" width="3" height="2"/> <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> @@ -1813,7 +1808,6 @@ Gw </connections> </tableView> </subviews> - <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> </clipView> <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="YES" id="7226"> <rect key="frame" x="1" y="199" width="693" height="15"/> @@ -1824,12 +1818,12 @@ Gw <autoresizingMask key="autoresizingMask"/> </scroller> <tableHeaderView key="headerView" id="7227"> - <rect key="frame" x="0.0" y="0.0" width="694" height="23"/> + <rect key="frame" x="0.0" y="0.0" width="694" height="17"/> <autoresizingMask key="autoresizingMask"/> </tableHeaderView> </scrollView> <popUpButton verticalHuggingPriority="750" id="8316" customClass="SPComboPopupButton"> - <rect key="frame" x="508" y="214" width="180" height="22"/> + <rect key="frame" x="508" y="213" width="180" height="22"/> <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/> <popUpButtonCell key="cell" type="roundRect" title="Run Current" bezelStyle="roundedRect" alignment="center" controlSize="small" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" pullsDown="YES" selectedItem="8319" id="8317" customClass="SPComboPopupButtonCell"> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> @@ -1875,11 +1869,11 @@ Gw </subviews> </view> <view id="7208"> - <rect key="frame" x="0.0" y="392" width="696" height="117"/> + <rect key="frame" x="0.0" y="392" width="696" height="119"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <textField verticalHuggingPriority="750" id="7429"> - <rect key="frame" x="15" y="91" width="363" height="14"/> + <rect key="frame" x="15" y="93" width="363" height="14"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Query Status" id="7430"> <font key="font" metaFont="smallSystemBold"/> @@ -1888,21 +1882,19 @@ Gw </textFieldCell> </textField> <scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" id="8245"> - <rect key="frame" x="12" y="12" width="672" height="72"/> + <rect key="frame" x="12" y="12" width="672" height="74"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="Nr9-eI-xLJ"> - <rect key="frame" x="0.0" y="0.0" width="672" height="72"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <rect key="frame" x="0.0" y="0.0" width="672" height="74"/> + <autoresizingMask key="autoresizingMask"/> <subviews> - <textView editable="NO" drawsBackground="NO" importsGraphics="NO" horizontallyResizable="YES" usesFontPanel="YES" verticallyResizable="YES" allowsNonContiguousLayout="YES" id="8248"> - <rect key="frame" x="0.0" y="0.0" width="672" height="72"/> + <textView editable="NO" drawsBackground="NO" importsGraphics="NO" horizontallyResizable="YES" usesFontPanel="YES" allowsNonContiguousLayout="YES" id="8248"> + <rect key="frame" x="0.0" y="0.0" width="672" height="74"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> - <size key="minSize" width="672" height="72"/> + <size key="minSize" width="672" height="74"/> <size key="maxSize" width="887" height="10000000"/> <color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> - <size key="minSize" width="672" height="72"/> - <size key="maxSize" width="887" height="10000000"/> </textView> </subviews> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> @@ -1967,17 +1959,15 @@ Gw <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" id="fhZ-nZ-AwI"> <rect key="frame" x="1" y="1" width="552" height="70"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <autoresizingMask key="autoresizingMask"/> <subviews> - <textView importsGraphics="NO" richText="NO" findStyle="panel" continuousSpellChecking="YES" verticallyResizable="YES" smartInsertDelete="YES" id="8236"> + <textView importsGraphics="NO" richText="NO" findStyle="panel" continuousSpellChecking="YES" smartInsertDelete="YES" id="8236"> <rect key="frame" x="0.0" y="0.0" width="552" height="70"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <size key="minSize" width="552" height="70"/> <size key="maxSize" width="1097" height="10000000"/> <color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> - <size key="minSize" width="552" height="70"/> - <size key="maxSize" width="1097" height="10000000"/> <connections> <outlet property="delegate" destination="1277" id="8237"/> </connections> @@ -2014,17 +2004,15 @@ Gw <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" id="nV8-ly-BSi"> <rect key="frame" x="1" y="1" width="552" height="197"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <autoresizingMask key="autoresizingMask"/> <subviews> - <textView editable="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" id="8242" customClass="SPTextView"> + <textView editable="NO" importsGraphics="NO" richText="NO" id="8242" customClass="SPTextView"> <rect key="frame" x="0.0" y="0.0" width="552" height="197"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <size key="minSize" width="552" height="197"/> <size key="maxSize" width="1097" height="10000000"/> <color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> - <size key="minSize" width="552" height="197"/> - <size key="maxSize" width="1097" height="10000000"/> <connections> <outlet property="delegate" destination="1277" id="8243"/> </connections> @@ -2130,19 +2118,13 @@ Gw <action selector="updateTableCollation:" target="1277" id="5840"/> </connections> </popUpButton> - <box verticalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" id="5806"> + <box verticalHuggingPriority="750" boxType="separator" id="5806"> <rect key="frame" x="25" y="427" width="650" height="5"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> - <color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/> - <color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> - <font key="titleFont" metaFont="system"/> </box> - <box verticalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" id="5807"> + <box verticalHuggingPriority="750" boxType="separator" id="5807"> <rect key="frame" x="24" y="316" width="650" height="5"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> - <color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/> - <color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> - <font key="titleFont" metaFont="system"/> </box> <textField verticalHuggingPriority="750" id="5775"> <rect key="frame" x="175" y="400" width="100" height="14"/> @@ -2350,11 +2332,11 @@ Gw <rect key="frame" x="6" y="32" width="696" height="474"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="EaV-iG-q8t"> - <rect key="frame" x="1" y="23" width="694" height="450"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <rect key="frame" x="1" y="0.0" width="694" height="473"/> + <autoresizingMask key="autoresizingMask"/> <subviews> <tableView identifier="TableRelationsTableView" focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" alternatingRowBackgroundColors="YES" autosaveColumns="NO" rowHeight="16" headerView="5545" id="5548" customClass="SPCopyTable"> - <rect key="frame" x="0.0" y="0.0" width="694" height="18"/> + <rect key="frame" x="0.0" y="0.0" width="694" height="450"/> <autoresizingMask key="autoresizingMask"/> <size key="intercellSpacing" width="3" height="2"/> <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> @@ -2459,7 +2441,6 @@ Gw </connections> </tableView> </subviews> - <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> </clipView> <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="5546"> <rect key="frame" x="1" y="470" width="688" height="15"/> @@ -2470,7 +2451,7 @@ Gw <autoresizingMask key="autoresizingMask"/> </scroller> <tableHeaderView key="headerView" id="5545"> - <rect key="frame" x="0.0" y="0.0" width="694" height="23"/> + <rect key="frame" x="0.0" y="0.0" width="694" height="17"/> <autoresizingMask key="autoresizingMask"/> </tableHeaderView> </scrollView> @@ -2538,11 +2519,11 @@ Gw <rect key="frame" x="6" y="32" width="696" height="474"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="tlh-Sg-Saf"> - <rect key="frame" x="1" y="23" width="694" height="450"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <rect key="frame" x="1" y="0.0" width="694" height="473"/> + <autoresizingMask key="autoresizingMask"/> <subviews> <tableView identifier="TableTriggersTableView" focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" alternatingRowBackgroundColors="YES" autosaveColumns="NO" rowHeight="16" headerView="6704" id="6701" customClass="SPCopyTable"> - <rect key="frame" x="0.0" y="0.0" width="693" height="18"/> + <rect key="frame" x="0.0" y="0.0" width="694" height="450"/> <autoresizingMask key="autoresizingMask"/> <size key="intercellSpacing" width="3" height="2"/> <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> @@ -2647,7 +2628,6 @@ Gw </connections> </tableView> </subviews> - <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> </clipView> <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="6703"> <rect key="frame" x="1" y="457" width="694" height="16"/> @@ -2658,7 +2638,7 @@ Gw <autoresizingMask key="autoresizingMask"/> </scroller> <tableHeaderView key="headerView" id="6704"> - <rect key="frame" x="0.0" y="0.0" width="694" height="23"/> + <rect key="frame" x="0.0" y="0.0" width="694" height="17"/> <autoresizingMask key="autoresizingMask"/> </tableHeaderView> </scrollView> @@ -3414,12 +3394,9 @@ Gw <outlet property="nextKeyView" destination="6834" id="6848"/> </connections> </textField> - <box verticalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" id="6852"> + <box verticalHuggingPriority="750" boxType="separator" id="6852"> <rect key="frame" x="-3" y="92" width="306" height="5"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> - <color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/> - <color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> - <font key="titleFont" metaFont="system"/> </box> </subviews> </view> @@ -3437,10 +3414,10 @@ Gw <rect key="frame" x="0.0" y="0.0" width="379" height="369"/> <autoresizingMask key="autoresizingMask"/> <subviews> - <box autoresizesSubviews="NO" title="Table:" borderType="line" id="5660"> + <box autoresizesSubviews="NO" borderType="line" title="Table:" id="5660"> <rect key="frame" x="17" y="231" width="345" height="56"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> - <view key="contentView"> + <view key="contentView" id="G3T-Zw-qVw"> <rect key="frame" x="1" y="1" width="343" height="40"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> @@ -3473,13 +3450,11 @@ Gw </textField> </subviews> </view> - <color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/> - <color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> </box> - <box autoresizesSubviews="NO" title="Name" borderType="line" id="7798"> + <box autoresizesSubviews="NO" borderType="line" title="Name" id="7798"> <rect key="frame" x="17" y="291" width="345" height="58"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> - <view key="contentView"> + <view key="contentView" id="PBs-KU-8Dt"> <rect key="frame" x="1" y="1" width="343" height="42"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> @@ -3506,13 +3481,11 @@ Gw </textField> </subviews> </view> - <color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/> - <color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> </box> - <box autoresizesSubviews="NO" title="Action" borderType="line" id="5659"> + <box autoresizesSubviews="NO" borderType="line" title="Action" id="5659"> <rect key="frame" x="17" y="49" width="345" height="87"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> - <view key="contentView"> + <view key="contentView" id="Z9B-3e-PSv"> <rect key="frame" x="1" y="1" width="343" height="71"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> @@ -3578,13 +3551,11 @@ Gw </textField> </subviews> </view> - <color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/> - <color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> </box> - <box autoresizesSubviews="NO" title="References" borderType="line" id="5652"> + <box autoresizesSubviews="NO" borderType="line" title="References" id="5652"> <rect key="frame" x="17" y="140" width="345" height="87"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> - <view key="contentView"> + <view key="contentView" id="APb-Qe-OSq"> <rect key="frame" x="1" y="1" width="343" height="71"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> @@ -3641,8 +3612,6 @@ Gw </textField> </subviews> </view> - <color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/> - <color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> </box> <button verticalHuggingPriority="750" tag="1" id="5599"> <rect key="frame" x="268" y="13" width="96" height="28"/> @@ -3702,10 +3671,10 @@ Gw <userLayoutGuide location="323" affinity="minX"/> </userGuides> <subviews> - <box autoresizesSubviews="NO" title="Trigger:" borderType="line" id="6770"> + <box autoresizesSubviews="NO" borderType="line" title="Trigger:" id="6770"> <rect key="frame" x="17" y="219" width="326" height="109"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> - <view key="contentView"> + <view key="contentView" id="Otf-WX-kyk"> <rect key="frame" x="1" y="1" width="324" height="93"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> @@ -3779,8 +3748,6 @@ Gw </textField> </subviews> </view> - <color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/> - <color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> </box> <button verticalHuggingPriority="750" tag="1" id="6768"> <rect key="frame" x="249" y="13" width="96" height="28"/> @@ -3814,17 +3781,15 @@ DQ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" id="ouK-7i-Xtd"> <rect key="frame" x="1" y="1" width="318" height="168"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <autoresizingMask key="autoresizingMask"/> <subviews> - <textView importsGraphics="NO" richText="NO" findStyle="panel" allowsUndo="YES" usesFontPanel="YES" verticallyResizable="YES" smartInsertDelete="YES" id="8230" customClass="SPTextView"> + <textView importsGraphics="NO" richText="NO" usesFontPanel="YES" findStyle="panel" allowsUndo="YES" smartInsertDelete="YES" id="8230" customClass="SPTextView"> <rect key="frame" x="0.0" y="0.0" width="318" height="168"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <size key="minSize" width="318" height="168"/> <size key="maxSize" width="592" height="10000000"/> <color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> - <size key="minSize" width="318" height="168"/> - <size key="maxSize" width="592" height="10000000"/> <connections> <outlet property="scrollView" destination="8227" id="8231"/> </connections> @@ -3927,17 +3892,15 @@ DQ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" id="w4Z-p1-GZA"> <rect key="frame" x="1" y="1" width="381" height="204"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <autoresizingMask key="autoresizingMask"/> <subviews> - <textView editable="NO" importsGraphics="NO" verticallyResizable="YES" id="8219"> + <textView editable="NO" importsGraphics="NO" id="8219"> <rect key="frame" x="0.0" y="0.0" width="381" height="204"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <size key="minSize" width="381" height="204"/> <size key="maxSize" width="753" height="10000000"/> <color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> - <size key="minSize" width="381" height="204"/> - <size key="maxSize" width="753" height="10000000"/> <connections> <outlet property="delegate" destination="134" id="8220"/> </connections> @@ -4035,17 +3998,15 @@ Gw <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" id="IdI-fg-CXh"> <rect key="frame" x="1" y="1" width="411" height="264"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <autoresizingMask key="autoresizingMask"/> <subviews> - <textView editable="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" id="8213" customClass="SPTextView"> + <textView editable="NO" importsGraphics="NO" richText="NO" id="8213" customClass="SPTextView"> <rect key="frame" x="0.0" y="0.0" width="411" height="264"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <size key="minSize" width="411" height="264"/> <size key="maxSize" width="824" height="10000000"/> <color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> - <size key="minSize" width="411" height="264"/> - <size key="maxSize" width="824" height="10000000"/> <connections> <outlet property="scrollView" destination="8210" id="8214"/> </connections> @@ -4111,17 +4072,15 @@ Gw <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" id="aEl-zD-ga2"> <rect key="frame" x="1" y="1" width="363" height="175"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <autoresizingMask key="autoresizingMask"/> <subviews> - <textView editable="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" id="8202"> + <textView editable="NO" importsGraphics="NO" richText="NO" id="8202"> <rect key="frame" x="0.0" y="0.0" width="363" height="175"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <size key="minSize" width="363" height="175"/> <size key="maxSize" width="717" height="10000000"/> <color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> - <size key="minSize" width="363" height="175"/> - <size key="maxSize" width="717" height="10000000"/> </textView> </subviews> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> @@ -4268,12 +4227,9 @@ Gw <action selector="helpSearchFindPreviousInPage:" target="134" id="5505"/> </connections> </button> - <box verticalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" id="5509"> + <box verticalHuggingPriority="750" boxType="separator" id="5509"> <rect key="frame" x="0.0" y="269" width="505" height="5"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> - <color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/> - <color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> - <font key="titleFont" metaFont="system"/> </box> <segmentedControl verticalHuggingPriority="750" id="5510"> <rect key="frame" x="347" y="279" width="152" height="20"/> @@ -4359,8 +4315,8 @@ Gw <rect key="frame" x="0.0" y="0.0" width="752" height="142"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" id="e9P-dP-cyb"> - <rect key="frame" x="0.0" y="23" width="752" height="119"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <rect key="frame" x="0.0" y="0.0" width="752" height="142"/> + <autoresizingMask key="autoresizingMask"/> <subviews> <tableView identifier="AdvancedFilterTableView" verticalHuggingPriority="750" allowsExpansionToolTips="YES" selectionHighlightStyle="sourceList" alternatingRowBackgroundColors="YES" emptySelection="NO" autosaveColumns="NO" headerView="8145" id="8144" customClass="SPCopyTable"> <rect key="frame" x="0.0" y="0.0" width="752" height="119"/> @@ -4389,7 +4345,6 @@ Gw </connections> </tableView> </subviews> - <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> </clipView> <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="8143"> <rect key="frame" x="1" y="95.851600000000005" width="751.5" height="15"/> @@ -4400,7 +4355,7 @@ Gw <autoresizingMask key="autoresizingMask"/> </scroller> <tableHeaderView key="headerView" id="8145"> - <rect key="frame" x="0.0" y="0.0" width="752" height="23"/> + <rect key="frame" x="0.0" y="0.0" width="752" height="17"/> <autoresizingMask key="autoresizingMask"/> </tableHeaderView> </scrollView> @@ -4494,23 +4449,20 @@ Gw <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" copiesOnScroll="NO" id="FLj-pH-h40"> <rect key="frame" x="1" y="1" width="510" height="90"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <autoresizingMask key="autoresizingMask"/> <subviews> - <textView editable="NO" importsGraphics="NO" findStyle="panel" verticallyResizable="YES" allowsNonContiguousLayout="YES" id="8207" customClass="SPTextView"> + <textView editable="NO" importsGraphics="NO" findStyle="panel" allowsNonContiguousLayout="YES" id="8207" customClass="SPTextView"> <rect key="frame" x="0.0" y="0.0" width="510" height="90"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <size key="minSize" width="510" height="90"/> <size key="maxSize" width="518" height="10000000"/> <color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> - <size key="minSize" width="510" height="90"/> - <size key="maxSize" width="518" height="10000000"/> <connections> <outlet property="delegate" destination="67" id="8208"/> </connections> </textView> </subviews> - <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> </clipView> <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="YES" id="8206"> <rect key="frame" x="1" y="119" width="232" height="15"/> @@ -4865,8 +4817,8 @@ Gw <rect key="frame" x="0.0" y="0.0" width="360" height="157"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" drawsBackground="NO" id="en7-kg-fIt"> - <rect key="frame" x="1" y="23" width="358" height="133"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <rect key="frame" x="1" y="0.0" width="358" height="156"/> + <autoresizingMask key="autoresizingMask"/> <subviews> <tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" selectionHighlightStyle="sourceList" alternatingRowBackgroundColors="YES" columnReordering="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="14" headerView="6890" id="6889"> <rect key="frame" x="0.0" y="0.0" width="358" height="133"/> @@ -4933,7 +4885,7 @@ Gw <autoresizingMask key="autoresizingMask"/> </scroller> <tableHeaderView key="headerView" id="6890"> - <rect key="frame" x="0.0" y="0.0" width="358" height="23"/> + <rect key="frame" x="0.0" y="0.0" width="358" height="17"/> <autoresizingMask key="autoresizingMask"/> </tableHeaderView> </scrollView> @@ -5552,17 +5504,15 @@ Gw <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" id="Jv9-hI-7CJ"> <rect key="frame" x="1" y="1" width="392" height="110"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <autoresizingMask key="autoresizingMask"/> <subviews> - <textView editable="NO" importsGraphics="NO" richText="NO" allowsUndo="YES" verticallyResizable="YES" allowsNonContiguousLayout="YES" quoteSubstitution="YES" dashSubstitution="YES" smartInsertDelete="YES" id="UVh-gz-xnJ"> + <textView editable="NO" importsGraphics="NO" richText="NO" allowsUndo="YES" allowsNonContiguousLayout="YES" quoteSubstitution="YES" dashSubstitution="YES" smartInsertDelete="YES" id="UVh-gz-xnJ"> <rect key="frame" x="0.0" y="0.0" width="392" height="110"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <size key="minSize" width="392" height="110"/> <size key="maxSize" width="463" height="10000000"/> <color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> - <size key="minSize" width="392" height="110"/> - <size key="maxSize" width="463" height="10000000"/> </textView> </subviews> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> @@ -5593,9 +5543,9 @@ Gw <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="AYA-4f-zEy"> <rect key="frame" x="0.0" y="0.0" width="384" height="152"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <autoresizingMask key="autoresizingMask"/> <subviews> - <textView editable="NO" drawsBackground="NO" importsGraphics="NO" richText="NO" findStyle="panel" usesFontPanel="YES" verticallyResizable="YES" allowsNonContiguousLayout="YES" id="Bfr-0R-dqh"> + <textView editable="NO" drawsBackground="NO" importsGraphics="NO" richText="NO" usesFontPanel="YES" findStyle="panel" allowsNonContiguousLayout="YES" id="Bfr-0R-dqh"> <rect key="frame" x="0.0" y="0.0" width="384" height="152"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> @@ -5610,8 +5560,6 @@ Gw </fragment> </attributedString> <color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> - <size key="minSize" width="384" height="152"/> - <size key="maxSize" width="463" height="10000000"/> </textView> </subviews> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> @@ -5640,8 +5588,8 @@ Gw <image name="NSRightFacingTriangleTemplate" width="9" height="12"/> <image name="button_action" width="30" height="22"/> <image name="button_add" width="30" height="22"/> - <image name="button_bar_handle" width="11" height="23"/> - <image name="button_bar_spacer" width="10" height="23"/> + <image name="button_bar_handle" width="15" height="23"/> + <image name="button_bar_spacer" width="11" height="23"/> <image name="button_duplicate" width="30" height="22"/> <image name="button_edit" width="30" height="22"/> <image name="button_edit_mode" width="30" height="22"/> diff --git a/Interfaces/English.lproj/DatabaseProcessList.xib b/Interfaces/English.lproj/DatabaseProcessList.xib index d6d995ce..0e6fe127 100644 --- a/Interfaces/English.lproj/DatabaseProcessList.xib +++ b/Interfaces/English.lproj/DatabaseProcessList.xib @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?xml version="1.0" encoding="UTF-8"?> <document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6751" systemVersion="13F1507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none"> <dependencies> <deployment identifier="macosx"/> @@ -23,7 +23,7 @@ </connections> </customObject> <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> - <customObject id="-3" userLabel="Application"/> + <customObject id="-3" userLabel="Application" customClass="NSObject"/> <window title="Processes" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="3" userLabel="Process List"> <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/> <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/> @@ -38,7 +38,7 @@ <rect key="frame" x="-1" y="22" width="642" height="148"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" id="ze9-NR-RuY"> - <rect key="frame" x="1" y="17" width="640" height="130"/> + <rect key="frame" x="1" y="0.0" width="640" height="147"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" columnReordering="NO" autosaveColumns="NO" rowHeight="16" headerView="14" id="17"> @@ -168,7 +168,6 @@ </connections> </tableView> </subviews> - <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> </clipView> <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" controlSize="small" horizontal="YES" id="15"> <rect key="frame" x="-100" y="-100" width="358" height="11"/> @@ -183,7 +182,7 @@ <autoresizingMask key="autoresizingMask"/> </tableHeaderView> </scrollView> - <searchField verticalHuggingPriority="750" id="6"> + <searchField wantsLayer="YES" verticalHuggingPriority="750" id="6"> <rect key="frame" x="10" y="176" width="601" height="19"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> <searchFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" placeholderString="Filter" usesSingleLineMode="YES" bezelStyle="round" sendsSearchStringImmediately="YES" id="22"> @@ -199,8 +198,8 @@ <rect key="frame" x="619" y="178" width="16" height="16"/> <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/> </progressIndicator> - <imageView id="74"> - <rect key="frame" x="62" y="0.0" width="578" height="23"/> + <imageView misplaced="YES" id="74"> + <rect key="frame" x="0.0" y="0.0" width="640" height="23"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/> <imageCell key="cell" refusesFirstResponder="YES" alignment="left" animates="YES" imageScaling="axesIndependently" image="button_bar_spacer" id="86"/> </imageView> @@ -218,8 +217,8 @@ <button toolTip="Refresh process list (⌘R)" id="75"> <rect key="frame" x="30" y="-1" width="32" height="25"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> - <buttonCell key="cell" type="roundTextured" title="Clear" bezelStyle="texturedRounded" image="button_refresh" imagePosition="only" alignment="center" state="on" imageScaling="proportionallyDown" inset="2" id="85"> - <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> + <buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="button_refresh" imagePosition="overlaps" alignment="center" alternateImage="button_refresh" state="on" imageScaling="proportionallyDown" inset="2" id="85"> + <behavior key="behavior" lightByContents="YES"/> <font key="font" metaFont="system"/> <string key="keyEquivalent">r</string> <modifierMask key="keyEquivalentModifierMask" command="YES"/> @@ -332,6 +331,7 @@ <connections> <outlet property="delegate" destination="-2" id="111"/> </connections> + <point key="canvasLocation" x="139" y="161.5"/> </window> <menu id="51" userLabel="Contextual Menu"> <items> @@ -437,8 +437,8 @@ Gw </window> </objects> <resources> - <image name="button_action" width="16" height="16"/> - <image name="button_bar_spacer" width="10" height="29"/> - <image name="button_refresh" width="32" height="23"/> + <image name="button_action" width="30" height="22"/> + <image name="button_bar_spacer" width="11" height="23"/> + <image name="button_refresh" width="30" height="22"/> </resources> </document> diff --git a/Interfaces/English.lproj/ExportDialog.xib b/Interfaces/English.lproj/ExportDialog.xib index 1c50f463..dd1f4f13 100644 --- a/Interfaces/English.lproj/ExportDialog.xib +++ b/Interfaces/English.lproj/ExportDialog.xib @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> -<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none"> +<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6751" systemVersion="13F1507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none"> <dependencies> <deployment identifier="macosx"/> <development version="5100" identifier="xcode"/> - <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/> + <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6751"/> </dependencies> <objects> <customObject id="-2" userLabel="File's Owner" customClass="SPExportController"> @@ -456,7 +456,7 @@ Gw <autoresizingMask key="autoresizingMask"/> </scroller> <tableHeaderView key="headerView" id="1226"> - <rect key="frame" x="0.0" y="0.0" width="412" height="23"/> + <rect key="frame" x="0.0" y="0.0" width="412" height="17"/> <autoresizingMask key="autoresizingMask"/> </tableHeaderView> </scrollView> diff --git a/Interfaces/English.lproj/MainMenu.xib b/Interfaces/English.lproj/MainMenu.xib index 0d021499..40174585 100644 --- a/Interfaces/English.lproj/MainMenu.xib +++ b/Interfaces/English.lproj/MainMenu.xib @@ -1,8 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="16C67" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none"> +<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6751" systemVersion="13F1507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none"> <dependencies> <deployment identifier="macosx"/> - <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/> + <development version="5100" identifier="xcode"/> + <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6751"/> </dependencies> <objects> <customObject id="-2" userLabel="File's Owner" customClass="NSApplication"> @@ -862,6 +863,7 @@ <action selector="showServerProcesses:" target="-1" id="1036"/> </connections> </menuItem> + <menuItem isSeparatorItem="YES" id="rzU-6x-Xih"/> <menuItem title="Shutdown Server…" id="jZI-ad-FsC"> <modifierMask key="keyEquivalentModifierMask"/> <connections> diff --git a/Interfaces/English.lproj/MainWindow.xib b/Interfaces/English.lproj/MainWindow.xib index ed58bf1a..8c7f21c2 100644 --- a/Interfaces/English.lproj/MainWindow.xib +++ b/Interfaces/English.lproj/MainWindow.xib @@ -1,8 +1,9 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9532" systemVersion="15D21" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none"> +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6751" systemVersion="13F1507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none"> <dependencies> <deployment identifier="macosx"/> - <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9532"/> + <development version="5100" identifier="xcode"/> + <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6751"/> </dependencies> <objects> <customObject id="-2" userLabel="File's Owner" customClass="SPWindowController"> @@ -24,8 +25,8 @@ <rect key="frame" x="0.0" y="0.0" width="948" height="555"/> <autoresizingMask key="autoresizingMask"/> <subviews> - <customView id="3" customClass="PSMTabBarControl"> - <rect key="frame" x="0.0" y="521" width="948" height="34"/> + <customView misplaced="YES" id="3" customClass="PSMTabBarControl"> + <rect key="frame" x="0.0" y="530" width="948" height="25"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> <connections> <outlet property="delegate" destination="-2" id="12"/> @@ -33,8 +34,8 @@ <outlet property="tabView" destination="4" id="9"/> </connections> </customView> - <tabView drawsBackground="NO" type="noTabsNoBorder" id="4"> - <rect key="frame" x="0.0" y="0.0" width="948" height="521"/> + <tabView misplaced="YES" drawsBackground="NO" type="noTabsNoBorder" id="4"> + <rect key="frame" x="0.0" y="1" width="948" height="529"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <font key="font" metaFont="system"/> <tabViewItems/> diff --git a/Resources/English.lproj/ContentFilterManager.strings b/Resources/English.lproj/ContentFilterManager.strings Binary files differindex 68922c24..f611c269 100644 --- a/Resources/English.lproj/ContentFilterManager.strings +++ b/Resources/English.lproj/ContentFilterManager.strings diff --git a/Resources/English.lproj/ContentPaginationView.strings b/Resources/English.lproj/ContentPaginationView.strings Binary files differindex 482afec1..6d04a4ca 100644 --- a/Resources/English.lproj/ContentPaginationView.strings +++ b/Resources/English.lproj/ContentPaginationView.strings diff --git a/Resources/English.lproj/DBView.strings b/Resources/English.lproj/DBView.strings Binary files differindex b3b20196..70e81d49 100644 --- a/Resources/English.lproj/DBView.strings +++ b/Resources/English.lproj/DBView.strings diff --git a/Resources/English.lproj/DatabaseProcessList.strings b/Resources/English.lproj/DatabaseProcessList.strings Binary files differindex 679e4faf..db3e803a 100644 --- a/Resources/English.lproj/DatabaseProcessList.strings +++ b/Resources/English.lproj/DatabaseProcessList.strings diff --git a/Resources/English.lproj/FieldEditorSheet.strings b/Resources/English.lproj/FieldEditorSheet.strings Binary files differindex 816cb986..d1d67fa6 100644 --- a/Resources/English.lproj/FieldEditorSheet.strings +++ b/Resources/English.lproj/FieldEditorSheet.strings diff --git a/Resources/English.lproj/InfoPlist.strings b/Resources/English.lproj/InfoPlist.strings index 64644f83..9ccbabf1 100644 --- a/Resources/English.lproj/InfoPlist.strings +++ b/Resources/English.lproj/InfoPlist.strings @@ -1,4 +1,4 @@ /* Localized versions of Info.plist keys */ -CFBundleGetInfoString = "Sequel Pro version 1.1, Copyright 2002-2016 Sequel Pro and CocoaMySQL team."; -NSHumanReadableCopyright = "Copyright 2002-2016 Sequel Pro and CocoaMySQL team.";
\ No newline at end of file +CFBundleGetInfoString = "Sequel Pro version 1.2, Copyright 2002-2017 Sequel Pro and CocoaMySQL team."; +NSHumanReadableCopyright = "Copyright 2002-2017 Sequel Pro and CocoaMySQL team."; diff --git a/Resources/English.lproj/Localizable.strings b/Resources/English.lproj/Localizable.strings Binary files differindex 388e535c..3b494d6d 100644 --- a/Resources/English.lproj/Localizable.strings +++ b/Resources/English.lproj/Localizable.strings diff --git a/Resources/English.lproj/Preferences.strings b/Resources/English.lproj/Preferences.strings Binary files differindex d0513701..ee24c412 100644 --- a/Resources/English.lproj/Preferences.strings +++ b/Resources/English.lproj/Preferences.strings diff --git a/Resources/English.lproj/QueryFavoriteManager.strings b/Resources/English.lproj/QueryFavoriteManager.strings Binary files differindex 622a6341..33ac193d 100644 --- a/Resources/English.lproj/QueryFavoriteManager.strings +++ b/Resources/English.lproj/QueryFavoriteManager.strings diff --git a/Scripts/build.sh b/Scripts/build.sh index 5348152a..681a98fa 100755 --- a/Scripts/build.sh +++ b/Scripts/build.sh @@ -40,11 +40,16 @@ then exit 1 fi +FRAMEWORKS_LIST="/tmp/sp.frameworks.$$" +FILES_TO_SIGN_LIST="/tmp/sp.filelist.$$" BUILD_PRODUCT="${BUILT_PRODUCTS_DIR}/${TARGET_NAME}${WRAPPER_SUFFIX}" FRAMEWORKS_PATH="${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}" +SHARED_SUPPORT_DIR="${BUILD_PRODUCT}/Contents/SharedSupport" dev_sign_resource() { + log "Signing resource: $1" + codesign -f -s 'Sequel Pro Development' "$1" 2> /dev/null } @@ -92,86 +97,124 @@ dist_code_sign() echo $ERRORS } -echo 'Updating build version...' +copy_default_bundles() +{ + log "Copying default bundles from '${SRCROOT}/SharedSupport/Default Bundles' to '${SHARED_SUPPORT_DIR}'" + + # Copy all Default Bundles to build product + rm -rf "${SHARED_SUPPORT_DIR}/Default Bundles" + + mkdir -p "${SHARED_SUPPORT_DIR}/Default Bundles" + + cp -R "${SRCROOT}/SharedSupport/Default Bundles" "${SHARED_SUPPORT_DIR}" +} + +copy_default_themes() +{ + log "Copying default bundles from '${SRCROOT}/SharedSupport/Default Themes' to '${SHARED_SUPPORT_DIR}'" + + # Copy all Default Themes to build product + rm -rf "${SHARED_SUPPORT_DIR}/Default Themes" + + mkdir -p "${SHARED_SUPPORT_DIR}/Default Themes" + + cp -R "${SRCROOT}/SharedSupport/Default Themes" "${SHARED_SUPPORT_DIR}" +} + +set_spotlight_comment() +{ + log "Setting Spotlight comment to 'MySQL database pancakes with syrup'" + + # Add a SpotLight comment (can't use applescript from a continuous integration server, so we manually set the binaryplist with xattr - but if this fails fall back to applescript) + xattr -wx com.apple.metadata:kMDItemFinderComment "62 70 6C 69 73 74 30 30 5F 10 22 4D 79 53 51 4C 20 64 61 74 61 62 61 73 65 20 70 61 6E 63 61 6B 65 73 20 77 69 74 68 20 73 79 72 75 70 08 00 00 00 00 00 00 01 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2D" "${BUILD_PRODUCT}" + + if [ $? -ne 0 ] ; then + osascript -e "tell application \"Finder\" to set comment of (alias (POSIX file \"${BUILD_PRODUCT}\")) to \"MySQL database pancakes with syrup\"" + fi +} + +remove_temp_files() +{ + rm "$FRAMEWORKS_LIST" + rm "$FILES_TO_SIGN_LIST" +} + +log() +{ + echo $1 +} + +log 'Updating build number (build-version.pl)...' # Add the build/bundle version "${SRCROOT}/Scripts/build-version.pl" -# Remove the .ibplugin from within frameworks -rm -rf "${BUILD_PRODUCT}/Contents/Frameworks/ShortcutRecorder.framework/Versions/A/Resources/ShortcutRecorder.ibplugin" +copy_default_bundles +copy_default_themes # Perform 'Release' or 'Distribution' build specific actions if [[ "$CONFIGURATION" == 'Release' || "$CONFIGURATION" == 'Distribution' ]] then + log 'Updating localizations (localize.sh)...' + "${SRCROOT}/Scripts/localize.sh" - printf "Running trim-application.sh to strip application resources for distribution...\n\n" + log "Stripping application resources for distribution (trim-application.sh)..." "${SRCROOT}/Scripts/trim-application.sh" -p "$BUILD_PRODUCT" -a -fi - -SHARED_SUPPORT_DIR="${BUILD_PRODUCT}/Contents/SharedSupport" - -# Copy all Default Bundles to build product -rm -rf "${SHARED_SUPPORT_DIR}/Default Bundles" - -mkdir -p "${SHARED_SUPPORT_DIR}/Default Bundles" - -cp -R "${SRCROOT}/SharedSupport/Default Bundles" "${SHARED_SUPPORT_DIR}" - -# Copy all Default Themes to build product -rm -rf "${SHARED_SUPPORT_DIR}/Default Themes" -mkdir -p "${SHARED_SUPPORT_DIR}/Default Themes" + # Remove the .ibplugin from within frameworks + rm -rf "${BUILD_PRODUCT}/Contents/Frameworks/ShortcutRecorder.framework/Versions/A/Resources/ShortcutRecorder.ibplugin" -cp -R "${SRCROOT}/SharedSupport/Default Themes" "${SHARED_SUPPORT_DIR}" - -# Add a SpotLight comment (can't use applescript from a continuous integration server, so we manually set the binaryplist with xattr - but if this fails fall back to applescript) -xattr -wx com.apple.metadata:kMDItemFinderComment "62 70 6C 69 73 74 30 30 5F 10 22 4D 79 53 51 4C 20 64 61 74 61 62 61 73 65 20 70 61 6E 63 61 6B 65 73 20 77 69 74 68 20 73 79 72 75 70 08 00 00 00 00 00 00 01 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2D" "${BUILD_PRODUCT}" -if [ $? -ne 0 ] ; then - osascript -e "tell application \"Finder\" to set comment of (alias (POSIX file \"${BUILD_PRODUCT}\")) to \"MySQL database pancakes with syrup\"" + set_spotlight_comment fi - -FRAMEWORKS_LIST="/tmp/sp.frameworks.$$" ls -d -1 "$FRAMEWORKS_PATH"/** > "$FRAMEWORKS_LIST" -FILES_TO_SIGN_LIST="/tmp/sp.filelist.$$" echo "${BUILD_PRODUCT}/Contents/Library/QuickLook/Sequel Pro.qlgenerator" >> "$FILES_TO_SIGN_LIST" echo "${BUILD_PRODUCT}/Contents/Resources/SequelProTunnelAssistant" >> "$FILES_TO_SIGN_LIST" echo "${BUILD_PRODUCT}" >> "$FILES_TO_SIGN_LIST" - # Perform distribution specific tasks if this is a 'Distribution' build if [ "$CONFIGURATION" == 'Distribution' ] then - echo 'Checking for localizations to copy in, using the "ResourcesToCopy" directory...' + log 'Checking for localizations to copy in, using the "ResourcesToCopy" directory...' if [ -e "${SRCROOT}/ResourcesToCopy" ] then TRANSLATIONS_BASE="${SRCROOT}/languagetranslations" IBSTRINGSDIR="${SRCROOT}/ibstrings" XIB_BASE="${SRCROOT}/Interfaces/English.lproj" + rm -rf "${IBSTRINGSDIR}" &> /dev/null rm -rf "${TRANSLATIONS_BASE}" &> /dev/null - echo "Creating IB strings files for rekeying..." + log "Creating IB strings files for rekeying..." + cp -R "${SRCROOT}/ResourcesToCopy" "${TRANSLATIONS_BASE}" + mkdir -p "$IBSTRINGSDIR/English.lproj" + find "${XIB_BASE}" \( -name "*.xib" \) | while read FILE; do ibtool "$FILE" --export-strings-file "$IBSTRINGSDIR/English.lproj/`basename "$FILE" .xib`.strings" done - echo "Rekeying localization files, translating xibs, merging localizations..." + log "Rekeying localization files, translating xibs, merging localizations..." + find "${TRANSLATIONS_BASE}" \( -name "*.lproj" \) | while read FILE; do loc=`basename "$FILE"` + mkdir "$IBSTRINGSDIR/$loc" + printf "\tProcessing: $loc\n" + find "$FILE" \( -name "*.strings" \) | while read STRFILE; do + file=`basename "$STRFILE" .strings` ibkeyfile="$IBSTRINGSDIR/English.lproj/$file.strings" xibfile="$XIB_BASE/$file.xib" transfile="$IBSTRINGSDIR/$loc/$file.strings" + if [ -e "$ibkeyfile" ] && [ -e "$xibfile" ]; then "${BUILT_PRODUCTS_DIR}/xibLocalizationPostprocessor" "$STRFILE" "$ibkeyfile" "$transfile" @@ -187,22 +230,24 @@ then rm -rf "${IBSTRINGSDIR}" &> /dev/null rm -rf "${TRANSLATIONS_BASE}" &> /dev/null else - echo 'No localizations to copy.' + log 'No localizations to copy.' fi - echo 'Performing distribution build code signing...' + log 'Performing distribution build code signing...' VERIFY_ERRORS=$(dist_code_sign "$FRAMEWORKS_LIST" "$FILES_TO_SIGN_LIST") if [ "$VERIFY_ERRORS" != '' ] then - echo "error: Signing verification threw an error: $VERIFY_ERRORS" - echo "error: All distribution builds must be signed with the key used for all previous distribution signing!" + log "error: Signing verification threw an error: $VERIFY_ERRORS" + log "error: All distribution builds must be signed with the key used for all previous distribution signing!" + + remove_temp_files exit 1 fi - echo 'Running package-application.sh to package application for distribution...' + log 'Running package-application.sh to package application for distribution...' "${SRCROOT}/Scripts/package-application.sh" -p "$BUILD_PRODUCT" fi @@ -210,7 +255,7 @@ fi # Development build code signing if [ "$CONFIGURATION" == 'Debug' ] then - echo 'Performing development build code signing...' + log 'Performing development build code signing...' dev_code_sign "$FRAMEWORKS_LIST" dev_code_sign "$FILES_TO_SIGN_LIST" @@ -219,7 +264,6 @@ then touch "$BUILD_PRODUCT" fi -rm "$FRAMEWORKS_LIST" -rm "$FILES_TO_SIGN_LIST" +remove_temp_files exit 0 diff --git a/Source/SPAboutController.m b/Source/SPAboutController.m index 30be7cfb..712f311c 100644 --- a/Source/SPAboutController.m +++ b/Source/SPAboutController.m @@ -30,6 +30,8 @@ #import "SPAboutController.h" +static NSString *SPSnapshotBuildIndicator = @"Snapshot"; + static NSString *SPCreditsFilename = @"Credits"; static NSString *SPLicenseFilename = @"License"; @@ -56,12 +58,13 @@ static NSString *SPShortVersionHashKey = @"SPVersionShortHash"; NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; // If the version string has a prefix of 'Nightly' then this is obviously a nighly build. - BOOL isNightly = [version hasPrefix:@"Nightly"]; + NSRange matchRange = [version rangeOfString:SPSnapshotBuildIndicator]; + BOOL isSnapshotBuild = (matchRange.location != NSNotFound); // Set the application name, but only include the major version if this is not a nightly build. - [appNameVersionTextField setStringValue:isNightly ? @"Sequel Pro" : [NSString stringWithFormat:@"Sequel Pro %@", version]]; + [appNameVersionTextField setStringValue:isSnapshotBuild ? @"Sequel Pro" : [NSString stringWithFormat:@"Sequel Pro %@", version]]; - [self _setVersionLabel:isNightly]; + [self _setVersionLabel:isSnapshotBuild]; // Get the credits file contents NSAttributedString *credits = [[[NSAttributedString alloc] initWithPath:[[NSBundle mainBundle] pathForResource:SPCreditsFilename ofType:@"rtf"] documentAttributes:nil] autorelease]; @@ -102,9 +105,9 @@ static NSString *SPShortVersionHashKey = @"SPVersionShortHash"; /** * Set the UI version labels. * - * @param isNightly Indicates whether or not this is a nightly build. + * @param isSnapshot Indicates whether or not this is a snapshot build. */ -- (void)_setVersionLabel:(BOOL)isNightly +- (void)_setVersionLabel:(BOOL)isSnapshotBuild { NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; @@ -122,7 +125,7 @@ static NSString *SPShortVersionHashKey = @"SPVersionShortHash"; else { textFieldString = [NSString stringWithFormat:@"%@ %@%@", - isNightly ? NSLocalizedString(@"Nightly Build", @"nightly build label") : NSLocalizedString(@"Build", @"build label"), + isSnapshotBuild ? NSLocalizedString(@"Snapshot Build", @"snapshot build label") : NSLocalizedString(@"Build", @"build label"), bundleVersion, hashIsEmpty ? @"" : [NSString stringWithFormat:@" (%@)", versionHash]]; } diff --git a/Source/SPAlertSheets.h b/Source/SPAlertSheets.h index c92b635d..8bc74971 100644 --- a/Source/SPAlertSheets.h +++ b/Source/SPAlertSheets.h @@ -39,7 +39,6 @@ modalDelegate:(id)modalDelegate didEndSelector:(SEL)didEndSelector contextInfo:(void *)contextInfo - msg:(NSString *)msg infoText:(NSString *)infoText returnCode:(NSInteger *)returnCode; diff --git a/Source/SPAlertSheets.m b/Source/SPAlertSheets.m index 258aac6d..fc98dc7c 100644 --- a/Source/SPAlertSheets.m +++ b/Source/SPAlertSheets.m @@ -53,7 +53,6 @@ modalDelegate:(id)modalDelegate didEndSelector:(SEL)didEndSelector contextInfo:(void *)contextInfo - msg:(NSString *)msg infoText:(NSString *)infoText returnCode:(NSInteger *)returnCode { @@ -69,7 +68,6 @@ modalDelegate:modalDelegate didEndSelector:didEndSelector contextInfo:contextInfo - msg:msg infoText:infoText returnCode:returnCode]; } @@ -93,43 +91,37 @@ aButton = [alert addButtonWithTitle:alternateButton]; [aButton setTag:NSAlertAlternateReturn]; } + if (otherButton) { aButton = [alert addButtonWithTitle:otherButton]; [aButton setTag:NSAlertOtherReturn]; } // Set alert style - [alert setAlertStyle:NSWarningAlertStyle]; - if(alertStyle) - [alert setAlertStyle:alertStyle]; + [alert setAlertStyle:alertStyle ? alertStyle : NSWarningAlertStyle]; // Set the informative message if supplied if (infoText) [alert setInformativeText:infoText]; - // Set the informative message if supplied - if (msg) [alert setMessageText:msg]; - // Run the alert on the main thread [alert beginSheetModalForWindow:docWindow modalDelegate:modalDelegate didEndSelector:didEndSelector contextInfo:contextInfo]; // wait for the sheet NSModalSession session = [NSApp beginModalSessionForWindow:[alert window]]; + for (;;) { // Since the returnCode can only be -1, 0, or 1 // run the session until returnCode was changed in // the didEndSelector method of the calling class - if(returnCode != &initialReturnCode) - break; + if (returnCode != &initialReturnCode) break; // Execute code on DefaultRunLoop [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; // Break the run loop if sheet was closed - if ([NSApp runModalSession:session] != NSRunContinuesResponse - || ![[alert window] isVisible]) - break; + if ([NSApp runModalSession:session] != NSRunContinuesResponse || ![[alert window] isVisible]) break; // Execute code on DefaultRunLoop [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode diff --git a/Source/SPAppController.m b/Source/SPAppController.m index 24b981af..3028c0f6 100644 --- a/Source/SPAppController.m +++ b/Source/SPAppController.m @@ -50,6 +50,7 @@ #import "SPWindowManagement.h" #import "SPCopyTable.h" #import "SPSyntaxParser.h" +#import "SPOSInfo.h" #import <PSMTabBar/PSMTabBarControl.h> #import <Sparkle/Sparkle.h> @@ -825,7 +826,14 @@ // remove percent encoding NSMutableArray *decodedPathComponents = [NSMutableArray arrayWithCapacity:pathComponents.count]; for (NSString *component in pathComponents) { - [decodedPathComponents addObject:component.stringByRemovingPercentEncoding]; + NSString *decoded; + if([SPOSInfo isOSVersionAtLeastMajor:10 minor:9 patch:0]) { + decoded = [component stringByRemovingPercentEncoding]; + } + else { + decoded = [component stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + } + [decodedPathComponents addObject:decoded]; } pathComponents = decodedPathComponents.copy; @@ -1323,11 +1331,9 @@ if([firstResponder numberOfSelectedRows]) { NSMutableArray *sel = [NSMutableArray array]; NSIndexSet *selectedRows = [firstResponder selectedRowIndexes]; - NSUInteger rowIndex = [selectedRows firstIndex]; - while ( rowIndex != NSNotFound ) { + [selectedRows enumerateIndexesUsingBlock:^(NSUInteger rowIndex, BOOL * _Nonnull stop) { [sel addObject:[NSString stringWithFormat:@"%ld", (long)rowIndex]]; - rowIndex = [selectedRows indexGreaterThanIndex:rowIndex]; - } + }]; [env setObject:[sel componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableSelectedRowIndices]; } @@ -1601,7 +1607,7 @@ NSMenu *menu = [[[NSApp mainMenu] itemWithTag:SPMainMenuBundles] submenu]; // Clean menu - [menu compatibleRemoveAllItems]; + [menu removeAllItems]; // Set up the bundle search paths // First process all in Application Support folder installed ones then Default ones diff --git a/Source/SPArrayAdditions.m b/Source/SPArrayAdditions.m index 0fe75483..0b851c1d 100644 --- a/Source/SPArrayAdditions.m +++ b/Source/SPArrayAdditions.m @@ -133,14 +133,10 @@ NSMutableArray *subArray = [NSMutableArray arrayWithCapacity:[indexes count]]; NSUInteger count = [self count]; - NSUInteger index = [indexes firstIndex]; - while ( index != NSNotFound ) - { + [indexes enumerateIndexesUsingBlock:^(NSUInteger index, BOOL * _Nonnull stop) { if ( index < count ) [subArray addObject: [self objectAtIndex: index]]; - - index = [indexes indexGreaterThanIndex: index]; - } + }]; return subArray; } diff --git a/Source/SPBundleCommandRunner.m b/Source/SPBundleCommandRunner.m index 08fad6f1..e884e21d 100644 --- a/Source/SPBundleCommandRunner.m +++ b/Source/SPBundleCommandRunner.m @@ -164,21 +164,29 @@ if([doc getConnection] == nil) doc = nil; else { - for (NSWindow *aWindow in [NSApp orderedWindows]) { - if([[[[aWindow windowController] class] description] isEqualToString:@"SPWindowController"]) { - if([[[aWindow windowController] documents] count] && [[[[[[aWindow windowController] documents] objectAtIndex:0] class] description] isEqualToString:@"SPDatabaseDocument"]) { + for (NSWindow *aWindow in [NSApp orderedWindows]) + { + if ([[[[aWindow windowController] class] description] isEqualToString:@"SPWindowController"]) { + + SPWindowController *windowController = (SPWindowController *)[aWindow windowController]; + NSArray *documents = [windowController documents]; + + if ([documents count] && [[[[documents objectAtIndex:0] class] description] isEqualToString:@"SPDatabaseDocument"]) { // Check if connected - if([[[[aWindow windowController] documents] objectAtIndex:0] getConnection]) - doc = [[[aWindow windowController] documents] objectAtIndex:0]; - else + if ([[documents objectAtIndex:0] getConnection]) { + doc = [documents objectAtIndex:0]; + } + else { doc = nil; + } } } - if(doc) break; + + if (doc) break; } } - if(doc != nil) { + if (doc != nil) { [doc setProcessID:uuid]; diff --git a/Source/SPBundleEditorController.m b/Source/SPBundleEditorController.m index e95c5d8c..ddac2b9e 100644 --- a/Source/SPBundleEditorController.m +++ b/Source/SPBundleEditorController.m @@ -29,7 +29,6 @@ // More info at <https://github.com/sequelpro/sequelpro> #import "SPBundleEditorController.h" -#import "SPMenuAdditions.h" #import "SPBundleCommandRunner.h" #import "SPOutlineView.h" #import "SPBundleCommandTextView.h" @@ -245,7 +244,7 @@ } NSMenuItem *anItem; - [inputGeneralScopePopUpMenu compatibleRemoveAllItems]; + [inputGeneralScopePopUpMenu removeAllItems]; anItem = [[NSMenuItem alloc] initWithTitle:SP_BUNDLEEDITOR_SCOPE_GENERAL_STRING action:@selector(scopeButtonChanged:) keyEquivalent:@""]; [anItem setTag:kGeneralScopeArrayIndex]; [inputGeneralScopePopUpMenu addItem:anItem]; diff --git a/Source/SPBundleHTMLOutputController.m b/Source/SPBundleHTMLOutputController.m index ecf16faa..6d9f70be 100644 --- a/Source/SPBundleHTMLOutputController.m +++ b/Source/SPBundleHTMLOutputController.m @@ -73,9 +73,7 @@ static NSString *SPSaveDocumentAction = @"SPSaveDocument"; [webView setDrawsBackground:YES]; [webView setEditable:NO]; [webView setShouldCloseWithWindow:YES]; -#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 [webView setShouldUpdateWhileOffscreen:NO]; -#endif suppressExceptionAlerting = NO; } diff --git a/Source/SPCategoryAdditions.h b/Source/SPCategoryAdditions.h index 991cb60c..f2e08f53 100644 --- a/Source/SPCategoryAdditions.h +++ b/Source/SPCategoryAdditions.h @@ -42,7 +42,6 @@ #import "SPWindowAdditions.h" #import "SPDataAdditions.h" #import "SPDataBase64EncodingAdditions.h" -#import "SPMenuAdditions.h" #import "SPNotLoaded.h" #import "SPMainThreadTrampoline.h" #import "SPColorAdditions.h" diff --git a/Source/SPCompatibility.h b/Source/SPCompatibility.h new file mode 100644 index 00000000..0154bb2a --- /dev/null +++ b/Source/SPCompatibility.h @@ -0,0 +1,151 @@ +// +// SPCompatibility.h +// sequel-pro +// +// Created by Max Lohrmann on 31.03.17. +// Copyright (c) 2017 Max Lohrmann. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +// More info at <https://github.com/sequelpro/sequelpro> + +/** + * This file contains declarations for backward compatibility to + * older XCode versions / SDKs. + * + * The current minimum required SDK is 10.8! + */ + +#ifndef SPCompatibility +#define SPCompatibility + +#pragma mark - 10.8 Mountain Lion + +#ifndef __MAC_10_8 +#define __MAC_10_8 1080 +#endif + +#if __MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_8 +#error You need to have at least SDK 10.8! +#endif + +#pragma mark - 10.9 Mavericks + +#ifndef __MAC_10_9 +#define __MAC_10_9 1090 +#endif + +#if __MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_9 + +@interface NSString (Mavericks) + +@property (readonly, copy) NSString *stringByRemovingPercentEncoding; + +@end + +#endif + +#pragma mark - 10.10 Yosemite + +#ifndef __MAC_10_10 +#define __MAC_10_10 101000 +#endif + +#if __MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_10 + +// This enum is available since 10.5 but only got a "name" in 10.10 +typedef NSUInteger NSCellHitResult; + +@compatibility_alias NSTitlebarAccessoryViewController NSViewController; + +@interface NSViewController (NSTitlebarAccessoryViewController) + +@property NSLayoutAttribute layoutAttribute; + +@end + +@interface NSWindow (Yosemite) + +- (NSArray *)titlebarAccessoryViewControllers; +- (void)removeTitlebarAccessoryViewControllerAtIndex:(NSInteger)index; +- (void)addTitlebarAccessoryViewController:(NSTitlebarAccessoryViewController *)controller; + +@end + +// This code is available since 10.8 but public only since 10.10 +typedef struct { + NSInteger majorVersion; + NSInteger minorVersion; + NSInteger patchVersion; +} NSOperatingSystemVersion; + +@interface NSProcessInfo () +- (NSOperatingSystemVersion)operatingSystemVersion; +- (BOOL)isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion)version; +@end + +#endif + +#pragma mark - 10.11 El Capitan + +#ifndef __MAC_10_11 +#define __MAC_10_11 101100 +#endif + +#if !__has_feature(objc_kindof) +#define __kindof +#endif + +#if __MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_11 + +// formal protocol since 10.11, NSObject category before +@protocol WebFrameLoadDelegate <NSObject> +@end + +@interface NSOpenPanel (ElCapitan) + +@property (getter=isAccessoryViewDisclosed) BOOL accessoryViewDisclosed; + +@end + +#endif + +#pragma mark - 10.12 Sierra + +#ifndef __MAC_10_12 +#define __MAC_10_12 101200 +#endif + +#if __MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_12 + +//those enums got renamed in 10.12, probably for consistency +#define NSAlertStyleInformational NSInformationalAlertStyle +#define NSAlertStyleWarning NSWarningAlertStyle +#define NSAlertStyleCritical NSCriticalAlertStyle + +@interface NSWindow (Sierra) ++ (void)setAllowsAutomaticWindowTabbing:(BOOL)arg; +@end + +#endif + +#endif diff --git a/Source/SPConnectionController.m b/Source/SPConnectionController.m index a2159b4f..1ccde091 100644 --- a/Source/SPConnectionController.m +++ b/Source/SPConnectionController.m @@ -63,22 +63,6 @@ static NSString *SPRemoveNode = @"RemoveNode"; static NSString *SPExportFavoritesFilename = @"SequelProFavorites.plist"; #endif -#if __MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_6 -@interface NSSavePanel (NSSavePanel_unpublishedUntilSnowLeopardAPI) - -- (void)setShowsHiddenFiles:(BOOL)flag; - -@end -#endif - -#if __MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_11 -@interface NSOpenPanel (NSOpenPanel_ElCaptian) - -@property (getter=isAccessoryViewDisclosed) BOOL accessoryViewDisclosed; - -@end -#endif - /** * This is a utility function to validate SSL key/certificate files * @param fileData The contents of the file @@ -875,14 +859,9 @@ static NSComparisonResult _compareFavoritesUsingKey(id favorite1, id favorite2, NSMutableArray *nodes = [NSMutableArray array]; NSIndexSet *indexes = [favoritesOutlineView selectedRowIndexes]; - NSUInteger currentIndex = [indexes firstIndex]; - - while (currentIndex != NSNotFound) - { + [indexes enumerateIndexesUsingBlock:^(NSUInteger currentIndex, BOOL * _Nonnull stop) { [nodes addObject:[favoritesOutlineView itemAtRow:currentIndex]]; - - currentIndex = [indexes indexGreaterThanIndex:currentIndex]; - } + }]; return nodes; } @@ -1595,7 +1574,7 @@ static NSComparisonResult _compareFavoritesUsingKey(id favorite1, id favorite2, // If this node only has one child and it's not another group node, don't bother proceeding if (([nodes count] == 1) && (![[nodes objectAtIndex:0] isGroup])) { [nodes release]; - return; + return; } for (SPTreeNode *treeNode in nodes) @@ -1605,19 +1584,6 @@ static NSComparisonResult _compareFavoritesUsingKey(id favorite1, id favorite2, } } - NSMutableIndexSet *indexes = [[NSMutableIndexSet alloc] init]; - - NSUInteger i = [indexes lastIndex]; - - while (i != NSNotFound) - { - [nodes removeObjectAtIndex:i]; - - i = [indexes indexLessThanIndex:i]; - } - - [indexes release]; - [nodes sortUsingFunction:_compareFavoritesUsingKey context:key]; if (reverseFavoritesSort) [nodes reverse]; diff --git a/Source/SPConstants.h b/Source/SPConstants.h index 161b5b0b..1419ec9a 100644 --- a/Source/SPConstants.h +++ b/Source/SPConstants.h @@ -665,25 +665,6 @@ typedef NS_ENUM(NSInteger,SPErrorCode) { // error codes in SPErrorDomain void _SPClear(id *addr); #define SPClear(x) _SPClear(&x) -//Backwards compatibility -#ifndef __MAC_10_7 -#define __MAC_10_7 1070 -#endif -#ifndef __MAC_10_8 -#define __MAC_10_8 1080 -#endif -#ifndef __MAC_10_10 -#define __MAC_10_10 101000 -#endif -#ifndef __MAC_10_11 -#define __MAC_10_11 101100 -#endif - -// This enum is available since 10.5 but only got a "name" in 10.10 -#if __MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_10 -typedef NSUInteger NSCellHitResult; -#endif - // Stolen from Stack Overflow: http://stackoverflow.com/questions/969130 #define SPLog(fmt, ...) NSLog((@"%s:%d: " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__) diff --git a/Source/SPContentFilterManager.m b/Source/SPContentFilterManager.m index fe20bcf1..5dc0c48b 100644 --- a/Source/SPContentFilterManager.m +++ b/Source/SPContentFilterManager.m @@ -237,7 +237,7 @@ static NSString *SPExportFilterAction = @"SPExportFilter"; NSUInteger insertIndex; // Store pending changes in Clause - [[self window] makeFirstResponder:contentFilterNameTextField]; + [[self window] makeFirstResponder:nil]; // Duplicate a selected filter if sender == self if(sender == self) @@ -298,7 +298,7 @@ static NSString *SPExportFilterAction = @"SPExportFilter"; { // Complete editing in the window - [[sender window] makeFirstResponder:[sender window]]; + [[self window] makeFirstResponder:nil]; NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Remove selected content filters?", @"remove selected content filters message") defaultButton:NSLocalizedString(@"Remove", @"remove button") @@ -609,11 +609,9 @@ static NSString *SPExportFilterAction = @"SPExportFilter"; // TODO: still rely on a NSArray but in the future rewrite it to use the NSIndexSet directly NSMutableArray *draggedRows = [[NSMutableArray alloc] initWithCapacity:1]; - NSUInteger rowIndex = [draggedIndexes firstIndex]; - while ( rowIndex != NSNotFound ) { + [draggedIndexes enumerateIndexesUsingBlock:^(NSUInteger rowIndex, BOOL * _Nonnull stop) { [draggedRows addObject:[NSNumber numberWithInteger:rowIndex]]; - rowIndex = [draggedIndexes indexGreaterThanIndex: rowIndex]; - } + }]; NSInteger destinationRow = row; @@ -805,16 +803,9 @@ static NSString *SPExportFilterAction = @"SPExportFilter"; if (returnCode == NSAlertDefaultReturn) { NSIndexSet *indexes = [contentFilterTableView selectedRowIndexes]; - // Get last index - NSUInteger currentIndex = [indexes lastIndex]; - - while (currentIndex != NSNotFound) - { + [indexes enumerateIndexesWithOptions:NSEnumerationReverse usingBlock:^(NSUInteger currentIndex, BOOL * _Nonnull stop) { [contentFilters removeObjectAtIndex:currentIndex]; - - // Get next index (beginning from the end) - currentIndex = [indexes indexLessThanIndex:currentIndex]; - } + }]; if ([contentFilters count] == 2) { [contentFilterNameTextField setStringValue:@""]; diff --git a/Source/SPCopyTable.m b/Source/SPCopyTable.m index 8a8c8fa9..ed7b1d71 100644 --- a/Source/SPCopyTable.m +++ b/Source/SPCopyTable.m @@ -168,19 +168,15 @@ static const NSInteger kBlobAsImageFile = 4; [result appendString:@"\n"]; } - NSUInteger c; - id cellData = nil; - // Create an array of table column mappings for fast iteration NSUInteger *columnMappings = calloc(numColumns, sizeof(NSUInteger)); - for ( c = 0; c < numColumns; c++ ) - columnMappings[c] = (NSUInteger)[[NSArrayObjectAtIndex(columns, c) identifier] integerValue]; + for (NSUInteger ci = 0; ci < numColumns; ci++ ) + columnMappings[ci] = (NSUInteger)[[NSArrayObjectAtIndex(columns, ci) identifier] integerValue]; // Loop through the rows, adding their descriptive contents - NSUInteger rowIndex = [selectedRows firstIndex]; NSString *nullString = [prefs objectForKey:SPNullValue]; Class spmysqlGeometryData = [SPMySQLGeometryData class]; - NSUInteger rowCounter = 0; + __block NSUInteger rowCounter = 0; if((withBlobHandling == kBlobAsFile || withBlobHandling == kBlobAsImageFile) && tmpBlobFileDirectory && [tmpBlobFileDirectory length]) { NSFileManager *fm = [NSFileManager defaultManager]; @@ -188,10 +184,9 @@ static const NSInteger kBlobAsImageFile = 4; [fm createDirectoryAtPath:tmpBlobFileDirectory withIntermediateDirectories:YES attributes:nil error:nil]; } - while ( rowIndex != NSNotFound ) - { - for ( c = 0; c < numColumns; c++ ) { - cellData = SPDataStorageObjectAtRowAndColumn(tableStorage, rowIndex, columnMappings[c]); + [selectedRows enumerateIndexesUsingBlock:^(NSUInteger rowIndex, BOOL * _Nonnull stop) { + for (NSUInteger c = 0; c < numColumns; c++ ) { + id cellData = SPDataStorageObjectAtRowAndColumn(tableStorage, rowIndex, columnMappings[c]); // Copy the shown representation of the cell - custom NULL display strings, (not loaded), // definable representation of any blobs or binary texts. @@ -262,10 +257,7 @@ static const NSInteger kBlobAsImageFile = 4; [result deleteCharactersInRange:NSMakeRange([result length]-1, 1)]; } [result appendString:@"\n"]; - - // Select the next row index - rowIndex = [selectedRows indexGreaterThanIndex:rowIndex]; - } + }]; // Remove the trailing line end if ([result length]) { @@ -306,20 +298,16 @@ static const NSInteger kBlobAsImageFile = 4; [result appendString:@"\n"]; } - NSUInteger c; - id cellData = nil; - // Create an array of table column mappings for fast iteration NSUInteger *columnMappings = calloc(numColumns, sizeof(NSUInteger)); - for ( c = 0; c < numColumns; c++ ) - columnMappings[c] = (NSUInteger)[[NSArrayObjectAtIndex(columns, c) identifier] integerValue]; + for (NSUInteger ci = 0; ci < numColumns; ci++ ) + columnMappings[ci] = (NSUInteger)[[NSArrayObjectAtIndex(columns, ci) identifier] integerValue]; // Loop through the rows, adding their descriptive contents - NSUInteger rowIndex = [selectedRows firstIndex]; NSString *nullString = [prefs objectForKey:SPNullValue]; Class spmysqlGeometryData = [SPMySQLGeometryData class]; - NSUInteger rowCounter = 0; + __block NSUInteger rowCounter = 0; if((withBlobHandling == kBlobAsFile || withBlobHandling == kBlobAsImageFile) && tmpBlobFileDirectory && [tmpBlobFileDirectory length]) { NSFileManager *fm = [NSFileManager defaultManager]; @@ -327,10 +315,9 @@ static const NSInteger kBlobAsImageFile = 4; [fm createDirectoryAtPath:tmpBlobFileDirectory withIntermediateDirectories:YES attributes:nil error:nil]; } - while ( rowIndex != NSNotFound ) - { - for ( c = 0; c < numColumns; c++ ) { - cellData = SPDataStorageObjectAtRowAndColumn(tableStorage, rowIndex, columnMappings[c]); + [selectedRows enumerateIndexesUsingBlock:^(NSUInteger rowIndex, BOOL * _Nonnull stop) { + for (NSUInteger c = 0; c < numColumns; c++ ) { + id cellData = SPDataStorageObjectAtRowAndColumn(tableStorage, rowIndex, columnMappings[c]); // Copy the shown representation of the cell - custom NULL display strings, (not loaded), // definable representation of any blobs or binary texts. @@ -401,10 +388,7 @@ static const NSInteger kBlobAsImageFile = 4; [result deleteCharactersInRange:NSMakeRange([result length]-1, 1)]; } [result appendString:@"\n"]; - - // Select the next row index - rowIndex = [selectedRows indexGreaterThanIndex:rowIndex]; - } + }]; // Remove the trailing line end if ([result length]) { @@ -625,24 +609,20 @@ static const NSInteger kBlobAsImageFile = 4; NSIndexSet *selectedRows = [self selectedRowIndexes]; NSMutableString *result = [NSMutableString stringWithCapacity:2000]; - NSUInteger c; - id cellData = nil; // Create an array of table column mappings for fast iteration NSUInteger *columnMappings = calloc(numColumns, sizeof(NSUInteger)); - for ( c = 0; c < numColumns; c++ ) - columnMappings[c] = (NSUInteger)[[NSArrayObjectAtIndex(columns, c) identifier] integerValue]; + for (NSUInteger ci = 0; ci < numColumns; ci++ ) + columnMappings[ci] = (NSUInteger)[[NSArrayObjectAtIndex(columns, ci) identifier] integerValue]; // Loop through the rows, adding their descriptive contents - NSUInteger rowIndex = [selectedRows firstIndex]; NSString *nullString = [prefs objectForKey:SPNullValue]; Class nsDataClass = [NSData class]; Class spmysqlGeometryData = [SPMySQLGeometryData class]; NSStringEncoding connectionEncoding = [mySQLConnection stringEncoding]; - while ( rowIndex != NSNotFound ) - { - for ( c = 0; c < numColumns; c++ ) { - cellData = SPDataStorageObjectAtRowAndColumn(tableStorage, rowIndex, columnMappings[c]); + [selectedRows enumerateIndexesUsingBlock:^(NSUInteger rowIndex, BOOL * _Nonnull stop) { + for (NSUInteger c = 0; c < numColumns; c++ ) { + id cellData = SPDataStorageObjectAtRowAndColumn(tableStorage, rowIndex, columnMappings[c]); // Copy the shown representation of the cell - custom NULL display strings, (not loaded), // and the string representation of any blobs or binary texts. @@ -673,10 +653,7 @@ static const NSInteger kBlobAsImageFile = 4; } [result appendString:@"\n"]; - - // Retrieve the next selected row index - rowIndex = [selectedRows indexGreaterThanIndex:rowIndex]; - } + }]; // Trim the trailing line ending if ([result length]) { @@ -1307,11 +1284,9 @@ static const NSInteger kBlobAsImageFile = 4; if([self numberOfSelectedRows]) { NSMutableArray *sel = [NSMutableArray array]; NSIndexSet *selectedRows = [self selectedRowIndexes]; - NSUInteger rowIndex = [selectedRows firstIndex]; - while ( rowIndex != NSNotFound ) { + [selectedRows enumerateIndexesUsingBlock:^(NSUInteger rowIndex, BOOL * _Nonnull stop) { [sel addObject:[NSString stringWithFormat:@"%llu", (unsigned long long)rowIndex]]; - rowIndex = [selectedRows indexGreaterThanIndex:rowIndex]; - } + }]; [env setObject:[sel componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableSelectedRowIndices]; } diff --git a/Source/SPMenuAdditions.m b/Source/SPCreateDatabaseInfo.h index f4544808..8ddc6268 100644 --- a/Source/SPMenuAdditions.m +++ b/Source/SPCreateDatabaseInfo.h @@ -1,9 +1,9 @@ // -// SPMenuAdditions.m +// SPCreateDatabaseInfo.m // sequel-pro // -// Created by Rowan Beentje on November 27, 2010. -// Copyright (c) 2010 Rowan Beentje. All rights reserved. +// Created by David Rekowski on April 29, 2010. +// Copyright (c) 2010 David Rekowski. All rights reserved. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -28,19 +28,15 @@ // // More info at <https://github.com/sequelpro/sequelpro> -#import "SPMenuAdditions.h" - -@implementation NSMenu (SPMenuAdditions) - -// Add a 10.5-compatible removeAllItems -- (void)compatibleRemoveAllItems +@interface SPCreateDatabaseInfo : NSObject { - if ([self respondsToSelector:@selector(removeAllItems)]) { - [(id)self removeAllItems]; - } - else { - while ([self numberOfItems]) [self removeItemAtIndex:0]; - } + NSString *databaseName; + NSString *defaultEncoding; + NSString *defaultCollation; } +@property (readwrite, retain) NSString *databaseName; +@property (readwrite, retain) NSString *defaultEncoding; +@property (readwrite, retain) NSString *defaultCollation; + @end diff --git a/UnitTests/SPMenuAdditionsTests.m b/Source/SPCreateDatabaseInfo.m index 7e8b5ecc..0dc4c123 100644 --- a/UnitTests/SPMenuAdditionsTests.m +++ b/Source/SPCreateDatabaseInfo.m @@ -1,9 +1,9 @@ // -// SPMenuAdditionsTests.m +// SPCreateDatabaseInfo.m // sequel-pro // -// Created by Stuart Connolly (stuconnolly.com) on March 20, 2011. -// Copyright (c) 2011 Stuart Connolly. All rights reserved. +// Created by David Rekowski on April 29, 2010. +// Copyright (c) 2010 David Rekowski. All rights reserved. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -28,50 +28,21 @@ // // More info at <https://github.com/sequelpro/sequelpro> -#import "SPMenuAdditions.h" +#import "SPCreateDatabaseInfo.h" -#import <XCTest/XCTest.h> +@implementation SPCreateDatabaseInfo -/** - * @class SPMenuAdditionsTests SPMenuAdditionsTests.h - * - * @author Stuart Connolly http://stuconnolly.com/ - * - * SPMenuAdditionsTests tests class. - */ -@interface SPMenuAdditionsTests : XCTestCase -{ - NSMenu *menu; -} - -@end - -static NSString *SPTestMenuItemTitle = @"Menu Item"; - -@implementation SPMenuAdditionsTests +@synthesize databaseName; +@synthesize defaultEncoding; +@synthesize defaultCollation; -- (void)setUp +- (void)dealloc { - NSUInteger num = 5; - - menu = [[NSMenu alloc] init]; - - for (NSUInteger i = 0; i < num; i++) - { - [menu addItemWithTitle:[NSString stringWithFormat:@"%@ %ld", SPTestMenuItemTitle, (unsigned long)i] action:NULL keyEquivalent:@""]; - } -} + if (databaseName) SPClear(databaseName); + if (defaultEncoding) SPClear(defaultEncoding); + if (defaultCollation) SPClear(defaultCollation); -- (void)tearDown -{ - [menu release], menu = nil; -} - -- (void)testCompatibleRemoveAllItems -{ - [menu compatibleRemoveAllItems]; - - XCTAssertFalse([menu numberOfItems], @"The menu should have no menu items."); + [super dealloc]; } @end diff --git a/Source/SPCustomQuery.m b/Source/SPCustomQuery.m index 4150d5a4..591bcb12 100644 --- a/Source/SPCustomQuery.m +++ b/Source/SPCustomQuery.m @@ -754,7 +754,7 @@ if (![mySQLConnection lastQueryWasCancelled]) { [tableDocumentInstance setTaskIndicatorShouldAnimate:NO]; - [SPAlertSheets beginWaitingAlertSheetWithTitle:@"title" + [SPAlertSheets beginWaitingAlertSheetWithTitle:NSLocalizedString(@"MySQL Error", @"mysql error message") defaultButton:NSLocalizedString(@"Run All", @"run all button") alternateButton:NSLocalizedString(@"Continue", @"continue button") otherButton:NSLocalizedString(@"Stop", @"stop button") @@ -763,7 +763,6 @@ modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"runAllContinueStopSheet" - msg:NSLocalizedString(@"MySQL Error", @"mysql error message") infoText:[mySQLConnection lastErrorMessage] returnCode:&runAllContinueStopSheetReturnCode]; @@ -803,7 +802,7 @@ // Reload table list if at least one query began with drop, alter, rename, or create if(tableListNeedsReload || databaseWasChanged) { // Build database pulldown menu - [tableDocumentInstance setDatabases:self]; + [[tableDocumentInstance onMainThread] setDatabases:self]; if (databaseWasChanged) // Reset the current database diff --git a/Source/SPDataAdditions.m b/Source/SPDataAdditions.m index 65605577..53d18274 100644 --- a/Source/SPDataAdditions.m +++ b/Source/SPDataAdditions.m @@ -149,6 +149,7 @@ uint32_t LimitUInt32(NSUInteger i); unsigned char *lenPtr = paddedBytes + (paddedLength - 4); memcpy(lenPtr, &bigIntDataLength, 4); + size_t bytesWritten; CCCryptorStatus res = CCCrypt( kCCEncrypt, // operation mode kCCAlgorithmAES128, // algorithm @@ -160,7 +161,7 @@ uint32_t LimitUInt32(NSUInteger i); paddedLength, // length of raw data paddedBytes, // output buffer. overwriting input is OK paddedLength, // output buffer size - NULL // number of bytes written. not relevant here + &bytesWritten // number of bytes written. not relevant here, but 10.6 fails if omitted ); if(res != kCCSuccess) @@ -168,7 +169,7 @@ uint32_t LimitUInt32(NSUInteger i); reason:[NSString stringWithFormat:@"CCCrypt() failed! (CCCryptorStatus=%d)",res] userInfo:@{@"cryptorStatus":@(res)}]; - // the return code of CCCrypt() is not always reliable, better check it again + // CVE-2016-4711: the return code of CCCrypt() is not always reliable, better check it again if(memcmp(lenPtr, &bigIntDataLength, 4) == 0) @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Encrypted data is same as plaintext data!" userInfo:nil]; @@ -203,6 +204,7 @@ uint32_t LimitUInt32(NSUInteger i); // Decrypt the data unsigned char *decryptedBytes = calloc(1,encryptedLength); + size_t bytesRead; CCCryptorStatus res = CCCrypt( kCCDecrypt, // operation mode kCCAlgorithmAES128, // algorithm @@ -214,7 +216,7 @@ uint32_t LimitUInt32(NSUInteger i); encryptedLength, // length of raw data decryptedBytes, // output buffer. overwriting input is OK encryptedLength, // output buffer size - NULL // number of bytes written. not relevant here + &bytesRead // number of bytes decrypted. not relevant here, but 10.6 fails if omitted ); if(res != kCCSuccess) { diff --git a/Source/SPDataImport.m b/Source/SPDataImport.m index 1f619070..058ff916 100644 --- a/Source/SPDataImport.m +++ b/Source/SPDataImport.m @@ -690,10 +690,10 @@ } // Update available databases - [tableDocumentInstance setDatabases:self]; + [[tableDocumentInstance onMainThread] setDatabases:self]; // Update current selected database - [[tableDocumentInstance onMainThread] refreshCurrentDatabase]; + [tableDocumentInstance refreshCurrentDatabase]; // Update current database tables [tablesListInstance updateTables:self]; @@ -1092,7 +1092,7 @@ [query release]; if ([mySQLConnection queryErrored]) { - [tableDocumentInstance showConsole:nil]; + [[tableDocumentInstance onMainThread] showConsole:nil]; [errors appendFormat: NSLocalizedString(@"[ERROR in row %ld] %@\n", @"error text when reading of csv file gave errors"), (long)(rowsImported+1),[mySQLConnection lastErrorMessage]]; @@ -1132,7 +1132,7 @@ // If an error occurred, run the queries individually to get exact line errors if (!importMethodIsUpdate && [mySQLConnection queryErrored]) { - [tableDocumentInstance showConsole:nil]; + [[tableDocumentInstance onMainThread] showConsole:nil]; for (i = 0; i < csvRowsThisQuery; i++) { if (progressCancelled) break; query = [[NSMutableString alloc] initWithString:insertBaseString]; diff --git a/Source/SPDatabaseAction.h b/Source/SPDatabaseAction.h index 7ca8d402..98143ad8 100644 --- a/Source/SPDatabaseAction.h +++ b/Source/SPDatabaseAction.h @@ -30,19 +30,7 @@ @class SPTablesList; @class SPMySQLConnection; - -@interface SPCreateDatabaseInfo : NSObject -{ - NSString *databaseName; - NSString *defaultEncoding; - NSString *defaultCollation; -} - -@property (readwrite,retain) NSString *databaseName; -@property (readwrite,retain) NSString *defaultEncoding; -@property (readwrite,retain) NSString *defaultCollation; - -@end +@class SPCreateDatabaseInfo; @interface SPDatabaseAction : NSObject { @@ -70,7 +58,9 @@ * This method creates a new database. * * @param dbInfo database name/charset/collation (charset, collation may be nil) + * * @return success + * * @see createDatabase:withEncoding:collation: */ - (BOOL)createDatabase:(SPCreateDatabaseInfo *)dbInfo; @@ -81,6 +71,7 @@ * @param database name of the new database to be created * @param encoding charset of the new database (can be nil to skip) * @param collation sorting collation of the new database (can be nil) + * * @return YES on success, otherwise NO */ - (BOOL)createDatabase:(NSString *)database withEncoding:(NSString *)encoding collation:(NSString *)collation; diff --git a/Source/SPDatabaseAction.m b/Source/SPDatabaseAction.m index 413e2378..ad96fed1 100644 --- a/Source/SPDatabaseAction.m +++ b/Source/SPDatabaseAction.m @@ -29,25 +29,10 @@ // More info at <https://github.com/sequelpro/sequelpro> #import "SPDatabaseAction.h" +#import "SPCreateDatabaseInfo.h" #import <SPMySQL/SPMySQL.h> -@implementation SPCreateDatabaseInfo - -@synthesize databaseName; -@synthesize defaultEncoding; -@synthesize defaultCollation; - -- (void)dealloc -{ - [self setDatabaseName:nil]; - [self setDefaultEncoding:nil]; - [self setDefaultCollation:nil]; - [super dealloc]; -} - -@end - #pragma mark - @implementation SPDatabaseAction @@ -65,17 +50,18 @@ - (BOOL)createDatabase:(NSString *)database withEncoding:(NSString *)encoding collation:(NSString *)collation { - if(![database length]) { + if (![database length]) { SPLog(@"'database' should not be nil or empty!"); return NO; } NSMutableString *query = [NSMutableString stringWithFormat:@"CREATE DATABASE %@", [database backtickQuotedString]]; - if([encoding length]) { // [nil length] == 0 + if ([encoding length]) { // [nil length] == 0 [query appendFormat:@" DEFAULT CHARACTER SET = %@",[encoding backtickQuotedString]]; } - if([collation length]) { + + if ([collation length]) { [query appendFormat:@" DEFAULT COLLATE = %@",[collation backtickQuotedString]]; } diff --git a/Source/SPDatabaseCopy.h b/Source/SPDatabaseCopy.h index 3adf7fa0..57f29653 100644 --- a/Source/SPDatabaseCopy.h +++ b/Source/SPDatabaseCopy.h @@ -40,6 +40,7 @@ * * @param sourceDatabase information tuple about source database * @param targetDatabaseName the name of the target database + * * @result success */ - (BOOL)copyDatabaseFrom:(SPCreateDatabaseInfo *)sourceDatabase to:(NSString *)targetDatabaseName withContent:(BOOL)copyWithContent; diff --git a/Source/SPDatabaseCopy.m b/Source/SPDatabaseCopy.m index 94a5e896..976bd809 100644 --- a/Source/SPDatabaseCopy.m +++ b/Source/SPDatabaseCopy.m @@ -30,6 +30,7 @@ #import "SPDatabaseCopy.h" #import "SPTableCopy.h" +#import "SPCreateDatabaseInfo.h" #import <SPMySQL/SPMySQL.h> @@ -38,10 +39,11 @@ - (BOOL)copyDatabaseFrom:(SPCreateDatabaseInfo *)sourceDatabase to:(NSString *)targetDatabaseName withContent:(BOOL)copyWithContent { NSArray *tables = nil; - - // Check whether the source database exists and the target database doesn't. - BOOL sourceExists = [[connection databases] containsObject:[sourceDatabase databaseName]]; - BOOL targetExists = [[connection databases] containsObject:targetDatabaseName]; + NSArray *databases = [connection databases]; + + // Check whether the source database exists and the target database doesn't + BOOL sourceExists = [databases containsObject:[sourceDatabase databaseName]]; + BOOL targetExists = [databases containsObject:targetDatabaseName]; if (!sourceExists || targetExists) return NO; diff --git a/Source/SPDatabaseDocument.h b/Source/SPDatabaseDocument.h index 6596ca8c..fc00f647 100644 --- a/Source/SPDatabaseDocument.h +++ b/Source/SPDatabaseDocument.h @@ -269,7 +269,9 @@ NSArray *statusValues; + // Alert return codes NSInteger saveDocPrefSheetStatus; + NSInteger confirmCopyDatabaseReturnCode; // Properties SPWindowController *parentWindowController; diff --git a/Source/SPDatabaseDocument.m b/Source/SPDatabaseDocument.m index 6b61a99e..d19b3f4c 100644 --- a/Source/SPDatabaseDocument.m +++ b/Source/SPDatabaseDocument.m @@ -29,22 +29,13 @@ // // More info at <https://github.com/sequelpro/sequelpro> -// Forward-declare for 10.7 compatibility -#if !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 -enum { - NSFullScreenWindowMask = 1 << 14 -}; -#endif - #import "SPDatabaseDocument.h" #import "SPConnectionController.h" #import "SPConnectionHandler.h" #import "SPConnectionControllerInitializer.h" - #import "SPTablesList.h" #import "SPTableStructure.h" #import "SPDatabaseStructure.h" -#ifndef SP_CODA /* headers */ #import "SPFileHandle.h" #import "SPKeychain.h" #import "SPTableContent.h" @@ -55,20 +46,14 @@ enum { #import "SPGrowlController.h" #import "SPExportController.h" #import "SPSplitView.h" -#endif #import "SPQueryController.h" #import "SPQueryDocumentsController.h" -#ifndef SP_CODA /* headers */ #import "SPWindowController.h" -#endif #import "SPNavigatorController.h" -#ifndef SP_CODA /* headers */ #import "SPSQLParser.h" #import "SPTableData.h" -#endif #import "SPDatabaseData.h" #import "SPDatabaseStructure.h" -#ifndef SP_CODA /* headers */ #import "SPAppController.h" #import "SPWindowManagement.h" #import "SPExtendedTableInfo.h" @@ -86,92 +71,56 @@ enum { #import "SPDatabaseRename.h" #import "SPTableRelations.h" #import "SPCopyTable.h" -#endif #import "SPServerSupport.h" -#ifndef SP_CODA /* headers */ #import "SPTooltip.h" -#endif #import "SPDatabaseViewController.h" -#ifndef SP_CODA /* headers */ #import "SPBundleHTMLOutputController.h" #import "SPConnectionDelegate.h" -#endif #import "SPThreadAdditions.h" #import "RegexKitLite.h" #import "SPTextView.h" #import "SPFavoriteColorSupport.h" - -#ifdef SP_CODA /* headers */ -#import "SPAlertSheets.h" -#import "NSNotificationCenterThreadingAdditions.h" -#import "SPCustomQuery.h" -#import "SPDatabaseRename.h" -#endif - #import "SPCharsetCollationHelper.h" #import "SPGotoDatabaseController.h" #import "SPFunctions.h" +#import "SPCreateDatabaseInfo.h" #import <SPMySQL/SPMySQL.h> #include <libkern/OSAtomic.h> // Constants +static NSString *SPCopyDatabaseAction = @"SPCopyDatabase"; +static NSString *SPConfirmCopyDatabaseAction = @"SPConfirmCopyDatabase"; static NSString *SPRenameDatabaseAction = @"SPRenameDatabase"; static NSString *SPAlterDatabaseAction = @"SPAlterDatabase"; + static int64_t SPDatabaseDocumentInstanceCounter = 0; @interface SPDatabaseDocument () - (void)_addDatabase; - (void)_alterDatabase; - -#ifndef SP_CODA /* method decls */ - (void)_copyDatabase; -#endif - - (void)_renameDatabase; - (void)_removeDatabase; - (void)_selectDatabaseAndItem:(NSDictionary *)selectionDetails; - -#ifndef SP_CODA /* method decls */ - (void)_processDatabaseChangedBundleTriggerActions; -#endif +- (void)_addPreferenceObservers; +- (void)_removePreferenceObservers; @end @implementation SPDatabaseDocument -#ifndef SP_CODA /* ivars */ @synthesize sqlFileURL; @synthesize sqlFileEncoding; @synthesize parentWindowController; @synthesize parentTabViewItem; -#endif @synthesize isProcessing; @synthesize serverSupport; @synthesize databaseStructureRetrieval; -#ifndef SP_CODA /* ivars */ @synthesize processID; -#endif - -#ifdef SP_CODA /* ivars */ -@synthesize allDatabases; -@synthesize delegate; -@synthesize tableDataInstance; -@synthesize customQueryInstance; -@synthesize queryProgressBar; -@synthesize databaseSheet; -@synthesize databaseNameField; -@synthesize databaseEncodingButton; -@synthesize addDatabaseButton; -@synthesize databaseDataInstance; -@synthesize databaseRenameSheet; -@synthesize databaseRenameNameField; -@synthesize renameDatabaseButton; -@synthesize chooseDatabaseButton; -@synthesize structureContentSwitcher; -#endif @synthesize instanceId; #pragma mark - @@ -280,7 +229,6 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; - (void)awakeFromNib { -#ifndef SP_CODA if (_mainNibLoaded) return; _mainNibLoaded = YES; @@ -313,35 +261,24 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; // Set the connection controller's delegate [connectionController setDelegate:self]; - // Register observers for when the DisplayTableViewVerticalGridlines preference changes - [prefs addObserver:self forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL]; - [prefs addObserver:tableSourceInstance forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL]; - [prefs addObserver:tableContentInstance forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL]; - [prefs addObserver:customQueryInstance forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL]; - [prefs addObserver:tableRelationsInstance forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL]; - [prefs addObserver:[SPQueryController sharedQueryController] forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL]; - - // Register observers for the when the UseMonospacedFonts preference changes - [prefs addObserver:tableSourceInstance forKeyPath:SPUseMonospacedFonts options:NSKeyValueObservingOptionNew context:NULL]; - [prefs addObserver:[SPQueryController sharedQueryController] forKeyPath:SPUseMonospacedFonts options:NSKeyValueObservingOptionNew context:NULL]; + // Register preference observers to allow live UI-linked preference changes + [self _addPreferenceObservers]; - [prefs addObserver:tableContentInstance forKeyPath:SPGlobalResultTableFont options:NSKeyValueObservingOptionNew context:NULL]; - [prefs addObserver:tableContentInstance forKeyPath:SPDisplayBinaryDataAsHex options:NSKeyValueObservingOptionNew context:NULL]; - - // Register observers for when the logging preference changes - [prefs addObserver:[SPQueryController sharedQueryController] forKeyPath:SPConsoleEnableLogging options:NSKeyValueObservingOptionNew context:NULL]; + // Register for notifications + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(willPerformQuery:) + name:@"SMySQLQueryWillBePerformed" + object:self]; - // Register a second observer for when the logging preference changes so we can tell the current connection about it - [prefs addObserver:self forKeyPath:SPConsoleEnableLogging options:NSKeyValueObservingOptionNew context:NULL]; -#endif + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(hasPerformedQuery:) + name:@"SMySQLQueryHasBeenPerformed" + object:self]; - // Register for notifications - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willPerformQuery:) - name:@"SMySQLQueryWillBePerformed" object:self]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hasPerformedQuery:) - name:@"SMySQLQueryHasBeenPerformed" object:self]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillTerminate:) - name:@"NSApplicationWillTerminateNotification" object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(applicationWillTerminate:) + name:@"NSApplicationWillTerminateNotification" + object:nil]; #ifndef SP_CODA // Find the Database -> Database Encoding menu (it's not in our nib, so we can't use interface builder) @@ -466,6 +403,10 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; #pragma mark - #pragma mark Connection callback and methods +/** + * + * This method *MUST* be called from the UI thread! + */ - (void)setConnection:(SPMySQLConnection *)theConnection { if ([theConnection userTriggeredDisconnect]) { @@ -483,7 +424,10 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; #ifndef SP_CODA // Set the fileURL and init the preferences (query favs, filters, and history) if available for that URL - [self setFileURL:[[SPQueryController sharedQueryController] registerDocumentWithFileURL:[self fileURL] andContextInfo:spfPreferences]]; + NSURL *newURL = [[SPQueryController sharedQueryController] registerDocumentWithFileURL:[self fileURL] andContextInfo:spfPreferences]; +#warning debug code for #2266 + if(!newURL) NSLog(@"#2266: Trying to set nil fileURL in %s from queryController=%@ oldFileURL=%@ contextInfo=%@", __func__, [SPQueryController sharedQueryController], [self fileURL], spfPreferences); + [self setFileURL:newURL]; // ...but hide the icon while the document is temporary if ([self isUntitled]) [[parentWindow standardWindowButton:NSWindowDocumentIconButton] setImage:nil]; @@ -652,7 +596,7 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; * * @return The document's connection */ -- (SPMySQLConnection *) getConnection +- (SPMySQLConnection *)getConnection { return mySQLConnection; } @@ -660,9 +604,9 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; /** * Sets this connection's Keychain ID. */ -- (void)setKeychainID:(NSString *)theID +- (void)setKeychainID:(NSString *)theId { - keyChainID = [[NSString stringWithString:theID] retain]; + keyChainID = [[NSString stringWithString:theId] retain]; } #pragma mark - @@ -670,6 +614,8 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; /** * sets up the database select toolbar item + * + * This method *MUST* be called from the UI thread! */ - (IBAction)setDatabases:(id)sender; { @@ -928,7 +874,24 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; - (IBAction)copyDatabase:(id)sender { if (![tablesListInstance selectionShouldChangeInTableView:nil]) return; - + + // Inform the user that we don't support copying objects other than tables and ask them if they'd like to proceed + if ([tablesListInstance hasNonTableObjects]) { + [SPAlertSheets beginWaitingAlertSheetWithTitle:NSLocalizedString(@"Only Partially Supported", @"partial copy database support message") + defaultButton:NSLocalizedString(@"Continue", "continue button") + alternateButton:NSLocalizedString(@"Cancel", @"cancel button") + otherButton:nil + alertStyle:NSAlertStyleWarning + docWindow:parentWindow + modalDelegate:self + didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) + contextInfo:SPConfirmCopyDatabaseAction + infoText:[NSString stringWithFormat:NSLocalizedString(@"Duplicating the database '%@' is only partially supported as it contains objects other tables (i.e. views, procedures, functions, etc.), which will not be copied.\n\nWould you like to continue?", @"partial copy database support informative message"), selectedDatabase] + returnCode:&confirmCopyDatabaseReturnCode]; + + if (confirmCopyDatabaseReturnCode == NSAlertAlternateReturn) return; + } + [databaseCopyNameField setStringValue:selectedDatabase]; [copyDatabaseMessageField setStringValue:selectedDatabase]; @@ -936,16 +899,29 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; modalForWindow:parentWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) - contextInfo:@"copyDatabase"]; + contextInfo:SPCopyDatabaseAction]; } #endif /** - * opens the rename database sheet and renames the databsae + * Opens the rename database sheet and renames the databsae. */ - (IBAction)renameDatabase:(id)sender { if (![tablesListInstance selectionShouldChangeInTableView:nil]) return; + + // We currently don't support moving any objects other than tables (i.e. views, functions, procs, etc.) from one database to another + // so inform the user and don't allow them to proceed. Copy/duplicate is more appropriate in this case, but with the same limitation. + if ([tablesListInstance hasNonTableObjects]) { + SPOnewayAlertSheet( + NSLocalizedString(@"Database Rename Unsupported", @"databsse rename unsupported message"), + parentWindow, + [NSString stringWithFormat:NSLocalizedString( + @"Ranaming the database '%@' is currently unsupported as it contains objects other than tables (i.e. views, procedures, functions, etc.).\n\nIf you would like to rename a database please use the 'Duplicate Database', move any non-table objects manually then drop the old database.", + @"databsse rename unsupported informative message"), selectedDatabase] + ); + return; + } [databaseRenameNameField setStringValue:selectedDatabase]; [renameDatabaseMessageField setStringValue:[NSString stringWithFormat:NSLocalizedString(@"Rename database '%@' to:", @"rename database message"), selectedDatabase]]; @@ -972,8 +948,8 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; NSAlert *alert = [NSAlert alertWithMessageText:[NSString stringWithFormat:NSLocalizedString(@"Delete database '%@'?", @"delete database message"), [self database]] defaultButton:NSLocalizedString(@"Delete", @"delete button") alternateButton:NSLocalizedString(@"Cancel", @"cancel button") - otherButton:nil - informativeTextWithFormat:NSLocalizedString(@"Are you sure you want to delete the database '%@'? This operation cannot be undone.", @"delete database informative message"), [self database]]; + otherButton:nil + informativeTextWithFormat:NSLocalizedString(@"Are you sure you want to delete the database '%@'? This operation cannot be undone.", @"delete database informative message"), [self database]]; NSArray *buttons = [alert buttons]; @@ -1010,9 +986,6 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; serverVariablesController = [[SPServerVariablesController alloc] init]; [serverVariablesController setConnection:mySQLConnection]; - - // Register to obeserve table view vertical grid line pref changes - [prefs addObserver:serverVariablesController forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL]; } [serverVariablesController displayServerVariablesSheetAttachedToWindow:parentWindow]; @@ -1027,9 +1000,6 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; processListController = [[SPProcessListController alloc] init]; [processListController setConnection:mySQLConnection]; - - // Register to obeserve table view vertical grid line pref changes - [prefs addObserver:processListController forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL]; } [processListController displayProcessListWindow]; @@ -1088,26 +1058,29 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; /** * Alert sheet method. Invoked when an alert sheet is dismissed. - * - * if contextInfo == removeDatabase -> Remove the selected database - * if contextInfo == addDatabase -> Add a new database - * if contextInfo == copyDatabase -> Duplicate the selected database - * if contextInfo == renameDatabase -> Rename the selected database */ - (void)sheetDidEnd:(id)sheet returnCode:(NSInteger)returnCode contextInfo:(NSString *)contextInfo { #ifndef SP_CODA - if([contextInfo isEqualToString:@"saveDocPrefSheetStatus"]) { + + // Those that are just setting a return code and don't need to order out the sheet. See SPAlertSheets+beginWaitingAlertSheetWithTitle: + if ([contextInfo isEqualToString:@"saveDocPrefSheetStatus"]) { saveDocPrefSheetStatus = returnCode; return; } + else if ([contextInfo isEqualToString:SPConfirmCopyDatabaseAction]) { + confirmCopyDatabaseReturnCode = returnCode; + return; + } #endif // Order out current sheet to suppress overlapping of sheets - if ([sheet respondsToSelector:@selector(orderOut:)]) + if ([sheet respondsToSelector:@selector(orderOut:)]) { [sheet orderOut:nil]; - else if ([sheet respondsToSelector:@selector(window)]) + } + else if ([sheet respondsToSelector:@selector(window)]) { [[sheet window] orderOut:nil]; + } // Remove the current database if ([contextInfo isEqualToString:@"removeDatabase"]) { @@ -1147,7 +1120,7 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; } } #ifndef SP_CODA - else if ([contextInfo isEqualToString:@"copyDatabase"]) { + else if ([contextInfo isEqualToString:SPCopyDatabaseAction]) { if (returnCode == NSOKButton) { [self _copyDatabase]; } @@ -1197,6 +1170,8 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; /** * Reset the current selected database name + * + * This method MAY be called from UI and background threads! */ - (void)refreshCurrentDatabase { @@ -1214,23 +1189,21 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; dbName = NSArrayObjectAtIndex(eachRow, 0); } - // TODO: there have been crash reports because dbName == nil at this point. When could that happen? - if(dbName && ![dbName isNSNull]) { - if(![dbName isEqualToString:selectedDatabase]) { + SPMainQSync(^{ + // TODO: there have been crash reports because dbName == nil at this point. When could that happen? + if(dbName && ![dbName isNSNull]) { + if(![dbName isEqualToString:selectedDatabase]) { + if (selectedDatabase) SPClear(selectedDatabase); + selectedDatabase = [[NSString alloc] initWithString:dbName]; + [chooseDatabaseButton selectItemWithTitle:selectedDatabase]; + [self updateWindowTitle:self]; + } + } else { if (selectedDatabase) SPClear(selectedDatabase); - selectedDatabase = [[NSString alloc] initWithString:dbName]; - [chooseDatabaseButton selectItemWithTitle:selectedDatabase]; -#ifndef SP_CODA /* [self updateWindowTitle:self] */ + [chooseDatabaseButton selectItemAtIndex:0]; [self updateWindowTitle:self]; -#endif } - } else { - if (selectedDatabase) SPClear(selectedDatabase); - [chooseDatabaseButton selectItemAtIndex:0]; -#ifndef SP_CODA /* [self updateWindowTitle:self] */ - [self updateWindowTitle:self]; -#endif - } + }); } //query finished @@ -3399,7 +3372,7 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; if(!spf || ![spf count] || readError != nil || [convError length] || !(format == NSPropertyListXMLFormat_v1_0 || format == NSPropertyListBinaryFormat_v1_0)) { - [SPAlertSheets beginWaitingAlertSheetWithTitle:@"title" + [SPAlertSheets beginWaitingAlertSheetWithTitle:[NSString stringWithFormat:NSLocalizedString(@"Error while reading connection data file", @"error while reading connection data file")] defaultButton:NSLocalizedString(@"OK", @"OK button") alternateButton:NSLocalizedString(@"Ignore", @"ignore button") otherButton:nil @@ -3408,7 +3381,6 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"saveDocPrefSheetStatus" - msg:[NSString stringWithFormat:NSLocalizedString(@"Error while reading connection data file", @"error while reading connection data file")] infoText:[NSString stringWithFormat:NSLocalizedString(@"Connection data file “%@” couldn't be read. Please try to save the document under a different name.", @"message error while reading connection data file and suggesting to save it under a differnet name"), [fileName lastPathComponent]] returnCode:&saveDocPrefSheetStatus]; @@ -3564,7 +3536,10 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; [preferences setObject:[spfStructure objectForKey:SPContentFilters] forKey:SPContentFilters]; [[SPQueryController sharedQueryController] registerDocumentWithFileURL:[NSURL fileURLWithPath:fileName] andContextInfo:preferences]; - [self setFileURL:[NSURL fileURLWithPath:fileName]]; + NSURL *newURL = [NSURL fileURLWithPath:fileName]; +#warning debug code for #2266 + if(!newURL) NSLog(@"#2266: Trying to set nil fileURL in %s from fileName=%@", __func__, fileName); + [self setFileURL:newURL]; [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:[NSURL fileURLWithPath:fileName]]; [self updateWindowTitle:self]; @@ -4008,10 +3983,11 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; if (newIsVisible == windowTitleStatusViewIsVisible) return; if (newIsVisible) { - if (NSClassFromString(@"NSTitlebarAccessoryViewController")) { // OS X 10.11 and later + Class controllerClass; + if ((controllerClass = NSClassFromString(@"NSTitlebarAccessoryViewController"))) { // OS X 10.11 and later [titleAccessoryView setFrame:NSMakeRect(0, 0, titleAccessoryView.frame.size.width, 120)]; // make it really tall, so that it's on the top right of the title/toolbar area, instead of the bottom right (AppKit will not prevent it from going behind the toolbar) - NSTitlebarAccessoryViewController *accessoryViewController = [[[NSTitlebarAccessoryViewController alloc] init] autorelease]; + NSTitlebarAccessoryViewController *accessoryViewController = [[[controllerClass alloc] init] autorelease]; accessoryViewController.view = titleAccessoryView; accessoryViewController.layoutAttribute = NSLayoutAttributeRight; [parentWindow addTitlebarAccessoryViewController:accessoryViewController]; @@ -4492,6 +4468,7 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; { // Coax the main split view into actually checking its constraints [contentViewSplitter setPosition:[[[contentViewSplitter subviews] objectAtIndex:0] bounds].size.width ofDividerAtIndex:0]; + // If the task interface is visible, and this tab is frontmost, re-center the task child window if (_isWorkingLevel && [parentWindowController selectedTableDocument] == self) [self centerTaskWindow]; } @@ -4500,17 +4477,19 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; /** * Set the parent window */ -- (void)setParentWindow:(NSWindow *)aWindow +- (void)setParentWindow:(NSWindow *)window { -#ifndef SP_CODA + NSWindow *favoritesOutlineViewWindow = [(NSView *)[connectionController favoritesOutlineView] window]; + // If the window is being set for the first time - connection controller is visible - update focus - if (!parentWindow && !mySQLConnection) { - [aWindow makeFirstResponder:(NSResponder *)[connectionController favoritesOutlineView]]; + if (!parentWindow && !mySQLConnection && window == favoritesOutlineViewWindow) { + [window makeFirstResponder:(NSResponder *)[connectionController favoritesOutlineView]]; } -#endif - parentWindow = aWindow; + parentWindow = window; + SPSSHTunnel *currentTunnel = [connectionController valueForKeyPath:@"sshTunnel"]; + if (currentTunnel) [currentTunnel setParentWindow:parentWindow]; } @@ -5118,7 +5097,10 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; } if (![self isSaveInBundle]) { - [self setFileURL:[NSURL fileURLWithPath:path]]; + NSURL *newURL = [NSURL fileURLWithPath:path]; +#warning debug code for #2266 + if(!newURL) NSLog(@"#2266: Trying to set nil fileURL in %s from path=%@", __func__, path); + [self setFileURL:newURL]; } [spfDocData setObject:[NSNumber numberWithBool:([[data objectForKey:@"connection"] objectForKey:@"password"]) ? YES : NO] forKey:@"save_password"]; @@ -5794,7 +5776,7 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; ); } -- (void)registerActivity:(NSDictionary*)commandDict +- (void)registerActivity:(NSDictionary *)commandDict { [runningActivitiesArray addObject:commandDict]; [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:SPActivitiesUpdateNotification object:self]; @@ -5832,74 +5814,74 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:SPActivitiesUpdateNotification object:self]; } -- (void)setActivityPaneHidden:(NSNumber*)hide +- (void)setActivityPaneHidden:(NSNumber *)hide { - if(hide.boolValue) { - [tableInfoScrollView setHidden:YES]; - [documentActivityScrollView setHidden:NO]; - } else { + if (hide.boolValue) { [documentActivityScrollView setHidden:YES]; [tableInfoScrollView setHidden:NO]; } + else { + [tableInfoScrollView setHidden:YES]; + [documentActivityScrollView setHidden:NO]; + } } -- (NSArray*)runningActivities +- (NSArray *)runningActivities { return (NSArray*)runningActivitiesArray; } -- (NSDictionary*)shellVariables +- (NSDictionary *)shellVariables { - - if(!_isConnected) return @{}; + if (!_isConnected) return @{}; NSMutableDictionary *env = [NSMutableDictionary dictionary]; if (tablesListInstance) { - if([tablesListInstance selectedDatabase]) + + if ([tablesListInstance selectedDatabase]) { [env setObject:[tablesListInstance selectedDatabase] forKey:SPBundleShellVariableSelectedDatabase]; + } - if ([tablesListInstance tableName]) + if ([tablesListInstance tableName]) { [env setObject:[tablesListInstance tableName] forKey:SPBundleShellVariableSelectedTable]; + } - if ([tablesListInstance selectedTableItems]) + if ([tablesListInstance selectedTableItems]) { [env setObject:[[tablesListInstance selectedTableItems] componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableSelectedTables]; + } - if ([tablesListInstance allDatabaseNames]) + if ([tablesListInstance allDatabaseNames]) { [env setObject:[[tablesListInstance allDatabaseNames] componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableAllDatabases]; + } - if ([tablesListInstance allTableNames]) - [env setObject:[[tablesListInstance allTableNames] componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableAllTables]; - - if ([tablesListInstance allViewNames]) - [env setObject:[[tablesListInstance allViewNames] componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableAllViews]; - - if ([tablesListInstance allFunctionNames]) - [env setObject:[[tablesListInstance allFunctionNames] componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableAllFunctions]; - - if ([tablesListInstance allProcedureNames]) - [env setObject:[[tablesListInstance allProcedureNames] componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableAllProcedures]; - - if ([self user]) + if ([self user]) { [env setObject:[self user] forKey:SPBundleShellVariableCurrentUser]; + } - if ([self host]) + if ([self host]) { [env setObject:[self host] forKey:SPBundleShellVariableCurrentHost]; + } - if ([self port]) + if ([self port]) { [env setObject:[self port] forKey:SPBundleShellVariableCurrentPort]; + } - [env setObject:([self databaseEncoding])?:@"" forKey:SPBundleShellVariableDatabaseEncoding]; + [env setObject:[[tablesListInstance allTableNames] componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableAllTables]; + [env setObject:[[tablesListInstance allViewNames] componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableAllViews]; + [env setObject:[[tablesListInstance allFunctionNames] componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableAllFunctions]; + [env setObject:[[tablesListInstance allProcedureNames] componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableAllProcedures]; + [env setObject:([self databaseEncoding]) ? : @"" forKey:SPBundleShellVariableDatabaseEncoding]; } - if(1) - [env setObject:@"mysql" forKey:SPBundleShellVariableRDBMSType]; + [env setObject:@"mysql" forKey:SPBundleShellVariableRDBMSType]; - if([self mySQLVersion]) + if ([self mySQLVersion]) { [env setObject:[self mySQLVersion] forKey:SPBundleShellVariableRDBMSVersion]; + } - return (NSDictionary*)env; + return (NSDictionary *)env; } #endif @@ -6092,6 +6074,10 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; #ifndef SP_CODA /* whole database operations */ +/** + * + * This method *MUST* be called from the UI thread! + */ - (void)_copyDatabase { if ([[databaseCopyNameField stringValue] isEqualToString:@""]) { @@ -6124,6 +6110,10 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; } #endif +/** + * + * This method *MUST* be called from the UI thread! + */ - (void)_renameDatabase { NSString *newDatabaseName = [databaseRenameNameField stringValue]; @@ -6168,6 +6158,8 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; /** * Adds a new database. + * + * This method *MUST* be called from the UI thread! */ - (void)_addDatabase { @@ -6238,6 +6230,8 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; /** * Removes the current database. + * + * This method *MUST* be called from the UI thread! */ - (void)_removeDatabase { @@ -6454,35 +6448,64 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; } #endif -#pragma mark - +/** + * Add any necessary preference observers to allow live updating on changes. + */ +- (void)_addPreferenceObservers +{ + // Register observers for when the DisplayTableViewVerticalGridlines preference changes + [prefs addObserver:self forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL]; + [prefs addObserver:tableSourceInstance forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL]; + [prefs addObserver:tableContentInstance forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL]; + [prefs addObserver:customQueryInstance forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL]; + [prefs addObserver:tableRelationsInstance forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL]; + [prefs addObserver:[SPQueryController sharedQueryController] forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL]; -- (void)dealloc + // Register observers for the when the UseMonospacedFonts preference changes + [prefs addObserver:tableSourceInstance forKeyPath:SPUseMonospacedFonts options:NSKeyValueObservingOptionNew context:NULL]; + [prefs addObserver:[SPQueryController sharedQueryController] forKeyPath:SPUseMonospacedFonts options:NSKeyValueObservingOptionNew context:NULL]; + + [prefs addObserver:tableContentInstance forKeyPath:SPGlobalResultTableFont options:NSKeyValueObservingOptionNew context:NULL]; + [prefs addObserver:tableContentInstance forKeyPath:SPDisplayBinaryDataAsHex options:NSKeyValueObservingOptionNew context:NULL]; + + // Register observers for when the logging preference changes + [prefs addObserver:[SPQueryController sharedQueryController] forKeyPath:SPConsoleEnableLogging options:NSKeyValueObservingOptionNew context:NULL]; + + // Register a second observer for when the logging preference changes so we can tell the current connection about it + [prefs addObserver:self forKeyPath:SPConsoleEnableLogging options:NSKeyValueObservingOptionNew context:NULL]; +} + +/** + * Remove any previously added preference observers. + */ +- (void)_removePreferenceObservers { - NSAssert([NSThread isMainThread], @"Calling %s from a background thread is not supported!",__func__); -#ifndef SP_CODA /* Unregister observers */ - // Unregister observers + [prefs removeObserver:self forKeyPath:SPConsoleEnableLogging]; [prefs removeObserver:self forKeyPath:SPDisplayTableViewVerticalGridlines]; - [prefs removeObserver:tableSourceInstance forKeyPath:SPDisplayTableViewVerticalGridlines]; - [prefs removeObserver:tableContentInstance forKeyPath:SPDisplayTableViewVerticalGridlines]; - [prefs removeObserver:customQueryInstance forKeyPath:SPDisplayTableViewVerticalGridlines]; - [prefs removeObserver:tableRelationsInstance forKeyPath:SPDisplayTableViewVerticalGridlines]; - [prefs removeObserver:[SPQueryController sharedQueryController] forKeyPath:SPDisplayTableViewVerticalGridlines]; + [prefs removeObserver:tableSourceInstance forKeyPath:SPUseMonospacedFonts]; - [prefs removeObserver:[SPQueryController sharedQueryController] forKeyPath:SPUseMonospacedFonts]; + [prefs removeObserver:tableContentInstance forKeyPath:SPGlobalResultTableFont]; [prefs removeObserver:tableContentInstance forKeyPath:SPDisplayBinaryDataAsHex]; + + [prefs removeObserver:customQueryInstance forKeyPath:SPDisplayTableViewVerticalGridlines]; + [prefs removeObserver:tableRelationsInstance forKeyPath:SPDisplayTableViewVerticalGridlines]; + [prefs removeObserver:tableSourceInstance forKeyPath:SPDisplayTableViewVerticalGridlines]; + [prefs removeObserver:tableContentInstance forKeyPath:SPDisplayTableViewVerticalGridlines]; + + [prefs removeObserver:[SPQueryController sharedQueryController] forKeyPath:SPUseMonospacedFonts]; [prefs removeObserver:[SPQueryController sharedQueryController] forKeyPath:SPConsoleEnableLogging]; - [prefs removeObserver:self forKeyPath:SPConsoleEnableLogging]; - - if (processListController) { - [processListController close]; - [prefs removeObserver:processListController forKeyPath:SPDisplayTableViewVerticalGridlines]; - } - - if (serverVariablesController) { - [prefs removeObserver:serverVariablesController forKeyPath:SPDisplayTableViewVerticalGridlines]; - } -#endif + [prefs removeObserver:[SPQueryController sharedQueryController] forKeyPath:SPDisplayTableViewVerticalGridlines]; +} + +#pragma mark - + +- (void)dealloc +{ + NSAssert([NSThread isMainThread], @"Calling %s from a background thread is not supported!", __func__); + + // Unregister observers + [self _removePreferenceObservers]; [[NSNotificationCenter defaultCenter] removeObserver:self]; [NSObject cancelPreviousPerformRequestsWithTarget:self]; @@ -6490,13 +6513,11 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; // see -(void)awakeFromNib for the reasoning behind this. SPClear(chooseDatabaseButton); SPClear(historyControl); - -#ifndef SP_CODA /* release nib objects */ + for (id retainedObject in nibObjectsToRelease) [retainedObject release]; SPClear(nibObjectsToRelease); -#endif - + // Tell listeners that this database document is being closed - fixes retain cycles and allows cleanup [[NSNotificationCenter defaultCenter] postNotificationName:SPDocumentWillCloseNotification object:self]; @@ -6505,55 +6526,36 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; SPClear(allDatabases); SPClear(allSystemDatabases); SPClear(gotoDatabaseController); -#ifndef SP_CODA /* dealloc ivars */ SPClear(undoManager); SPClear(printWebView); -#endif SPClear(selectedDatabaseEncoding); -#ifndef SP_CODA + [taskProgressWindow close]; -#endif + if (processListController) [processListController close]; + if (selectedTableName) SPClear(selectedTableName); if (connectionController) SPClear(connectionController); -#ifndef SP_CODA /* dealloc ivars */ if (processListController) SPClear(processListController); if (serverVariablesController) SPClear(serverVariablesController); -#endif if (mySQLConnection) SPClear(mySQLConnection); if (selectedDatabase) SPClear(selectedDatabase); if (mySQLVersion) SPClear(mySQLVersion); -#ifndef SP_CODA if (taskDrawTimer) [taskDrawTimer invalidate], SPClear(taskDrawTimer); if (taskFadeInStartDate) SPClear(taskFadeInStartDate); -#endif if (queryEditorInitString) SPClear(queryEditorInitString); -#ifndef SP_CODA if (sqlFileURL) SPClear(sqlFileURL); if (spfFileURL) SPClear(spfFileURL); if (spfPreferences) SPClear(spfPreferences); if (spfSession) SPClear(spfSession); if (spfDocData) SPClear(spfDocData); -#endif if (keyChainID) SPClear(keyChainID); -#ifndef SP_CODA if (mainToolbar) SPClear(mainToolbar); -#endif if (titleAccessoryView) SPClear(titleAccessoryView); -#ifndef SP_CODA if (taskProgressWindow) SPClear(taskProgressWindow); -#endif if (serverSupport) SPClear(serverSupport); -#ifndef SP_CODA /* dealloc ivars */ if (processID) SPClear(processID); if (runningActivitiesArray) SPClear(runningActivitiesArray); -#endif - -#ifdef SP_CODA - if (tablesListInstance) [tablesListInstance release]; - if (customQueryInstance) [customQueryInstance release]; -#endif - if (alterDatabaseCharsetHelper) SPClear(alterDatabaseCharsetHelper); if (addDatabaseCharsetHelper) SPClear(addDatabaseCharsetHelper); diff --git a/Source/SPDatabaseRename.h b/Source/SPDatabaseRename.h index becf460e..678fd962 100644 --- a/Source/SPDatabaseRename.h +++ b/Source/SPDatabaseRename.h @@ -40,6 +40,7 @@ * * @param sourceDatabase information tuple about the source database * @param targetDatabase the name of the target database + * * @result success */ - (BOOL)renameDatabaseFrom:(SPCreateDatabaseInfo *)sourceDatabase to:(NSString *)targetDatabase; diff --git a/Source/SPDatabaseRename.m b/Source/SPDatabaseRename.m index a6b393be..0c980384 100644 --- a/Source/SPDatabaseRename.m +++ b/Source/SPDatabaseRename.m @@ -32,6 +32,7 @@ #import "SPTableCopy.h" #import "SPViewCopy.h" #import "SPTablesList.h" +#import "SPCreateDatabaseInfo.h" #import <SPMySQL/SPMySQL.h> @@ -46,6 +47,9 @@ @implementation SPDatabaseRename +/** + * Note that this doesn't currently support moving any non-table objects (i.e. views, proc, functions, events, etc). + */ - (BOOL)renameDatabaseFrom:(SPCreateDatabaseInfo *)sourceDatabase to:(NSString *)targetDatabase { // Check, whether the source database exists and the target database doesn't @@ -55,23 +59,13 @@ if (!sourceExists || targetExists) return NO; NSArray *tables = [tablesList allTableNames]; -// NSArray *views = [tablesList allViewNames]; // TODO: handle views when renaming database - + BOOL success = [self createDatabase:targetDatabase withEncoding:[sourceDatabase defaultEncoding] collation:[sourceDatabase defaultCollation]]; [self _moveTables:tables fromDatabase:[sourceDatabase databaseName] toDatabase:targetDatabase]; -#warning Section disabled because it might destroy data (views, functions, events, ...) -/* - tables = [connection tablesFromDatabase:[sourceDatabase databaseName]]; - - if ([tables count] == 0) { - [self _dropDatabase:[sourceDatabase databaseName]]; - } -*/ - return success; } diff --git a/Source/SPEditorPreferencePane.m b/Source/SPEditorPreferencePane.m index 7eaecf47..7fc810ea 100644 --- a/Source/SPEditorPreferencePane.m +++ b/Source/SPEditorPreferencePane.m @@ -351,7 +351,7 @@ static NSString *SPCustomColorSchemeNameLC = @"user-defined"; [defaultItem setTarget:self]; // Build theme selection submenu - [themeSelectionMenu compatibleRemoveAllItems]; + [themeSelectionMenu removeAllItems]; [themeSelectionMenu addItem:defaultItem]; [themeSelectionMenu addItem:[NSMenuItem separatorItem]]; @@ -749,7 +749,7 @@ static NSString *SPCustomColorSchemeNameLC = @"user-defined"; [[NSColorPanel sharedColorPanel] close]; - [SPAlertSheets beginWaitingAlertSheetWithTitle:@"title" + [SPAlertSheets beginWaitingAlertSheetWithTitle:NSLocalizedString(@"Unsaved Theme", @"unsaved theme message") defaultButton:NSLocalizedString(@"Proceed", @"proceed button") alternateButton:NSLocalizedString(@"Cancel", @"cancel button") otherButton:nil @@ -758,7 +758,6 @@ static NSString *SPCustomColorSchemeNameLC = @"user-defined"; modalDelegate:self didEndSelector:@selector(checkForUnsavedThemeDidEndSheet:returnCode:contextInfo:) contextInfo:nil - msg:NSLocalizedString(@"Unsaved Theme", @"unsaved theme message") infoText:NSLocalizedString(@"The current color theme is unsaved. Do you want to proceed without saving it?", @"unsaved theme informative message") returnCode:&checkForUnsavedThemeSheetStatus]; diff --git a/Source/SPFavoriteNode.h b/Source/SPFavoriteNode.h index 6a132767..77c867fd 100644 --- a/Source/SPFavoriteNode.h +++ b/Source/SPFavoriteNode.h @@ -29,12 +29,13 @@ // More info at <https://github.com/sequelpro/sequelpro> #import "SPNamedNode.h" + /** * @class SPFavoriteNode SPFavoriteNode.h * * @author Stuart Connolly http://stuconnolly.com/ * - * Tree node the represents a connection favorite. + * Tree node that represents a connection favorite. */ @interface SPFavoriteNode : NSObject <NSCopying, NSCoding, SPNamedNode> { diff --git a/Source/SPFieldEditorController.m b/Source/SPFieldEditorController.m index 0298973d..b79355b5 100644 --- a/Source/SPFieldEditorController.m +++ b/Source/SPFieldEditorController.m @@ -41,13 +41,6 @@ #import <SPMySQL/SPMySQL.h> -#if __MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_7 -@interface NSTextView (LionPlus) -- (void)setUsesFindBar:(BOOL)value; -- (BOOL)usesFindBar; -@end -#endif - typedef enum { TextSegment = 0, ImageSegment, diff --git a/Source/SPFieldMapperController.m b/Source/SPFieldMapperController.m index 6d5caf41..ee80174a 100644 --- a/Source/SPFieldMapperController.m +++ b/Source/SPFieldMapperController.m @@ -992,14 +992,12 @@ static NSUInteger SPSourceColumnTypeInteger = 1; [toBeEditedRowIndexes removeIndex:toBeRemovedIndex]; // Renumber indexes greater than toBeRemovedIndex - NSInteger currentIndex = [toBeEditedRowIndexes firstIndex]; - while(currentIndex != NSNotFound) { - if(currentIndex > toBeRemovedIndex) { + [toBeEditedRowIndexes enumerateIndexesUsingBlock:^(NSUInteger currentIndex, BOOL * _Nonnull stop) { + if(currentIndex > (NSUInteger)toBeRemovedIndex) { [toBeEditedRowIndexes addIndex:currentIndex-1]; [toBeEditedRowIndexes removeIndex:currentIndex]; } - currentIndex = [toBeEditedRowIndexes indexGreaterThanIndex:currentIndex]; - } + }]; [self _setupFieldMappingPopUpMenus]; [fieldMapperTableView reloadData]; @@ -1155,15 +1153,10 @@ static NSUInteger SPSourceColumnTypeInteger = 1; NSIndexSet *indexes = [globalValuesTableView selectedRowIndexes]; - // get last index - NSUInteger currentIndex = [indexes lastIndex]; - - while (currentIndex != NSNotFound) { + [indexes enumerateIndexesWithOptions:NSEnumerationReverse usingBlock:^(NSUInteger currentIndex, BOOL * _Nonnull stop) { [fieldMappingGlobalValues removeObjectAtIndex:currentIndex+numberOfImportColumns]; [fieldMappingGlobalValuesSQLMarked removeObjectAtIndex:currentIndex+numberOfImportColumns]; - // get next index (beginning from the end) - currentIndex = [indexes indexLessThanIndex:currentIndex]; - } + }]; [globalValuesTableView reloadData]; @@ -2047,7 +2040,7 @@ static NSUInteger SPSourceColumnTypeInteger = 1; #endif // Re-init recent menu - [recentGlobalValueMenu compatibleRemoveAllItems]; + [recentGlobalValueMenu removeAllItems]; for(id item in recents) [recentGlobalValueMenu addItemWithTitle:item action:@selector(insertRecentGlobalValue:) keyEquivalent:@""]; diff --git a/Source/SPFunctions.m b/Source/SPFunctions.m index 93008059..461304e0 100644 --- a/Source/SPFunctions.m +++ b/Source/SPFunctions.m @@ -44,11 +44,10 @@ void SPMainQSync(void (^block)(void)) int SPBetterRandomBytes(uint8_t *buf, size_t count) { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_7 if([SPOSInfo isOSVersionAtLeastMajor:10 minor:7 patch:0]) { return SecRandomCopyBytes(kSecRandomDefault, count, buf); } -#endif + // Version for 10.6 // https://developer.apple.com/library/prerelease/mac/documentation/Security/Conceptual/cryptoservices/RandomNumberGenerationAPIs/RandomNumberGenerationAPIs.html#//apple_ref/doc/uid/TP40011172-CH12-SW1 FILE *fp = fopen("/dev/random", "r"); diff --git a/Source/SPGroupNode.h b/Source/SPGroupNode.h index d12f7465..6ce05e05 100644 --- a/Source/SPGroupNode.h +++ b/Source/SPGroupNode.h @@ -29,6 +29,7 @@ // More info at <https://github.com/sequelpro/sequelpro> #import "SPNamedNode.h" + /** * @class SPGroupNode SPGroupNode.h * diff --git a/Source/SPIndexesController.h b/Source/SPIndexesController.h index 82bc0a03..a21f88e4 100644 --- a/Source/SPIndexesController.h +++ b/Source/SPIndexesController.h @@ -35,10 +35,7 @@ @class SPMySQLConnection; @class SPTableView; -@interface SPIndexesController : NSWindowController -#ifdef SP_CODA -<NSTableViewDelegate, NSTableViewDataSource> -#endif +@interface SPIndexesController : NSWindowController <NSTableViewDelegate, NSTableViewDataSource> { // Controllers IBOutlet SPDatabaseDocument *dbDocument; @@ -62,7 +59,6 @@ IBOutlet NSButton *addIndexedColumnButton; IBOutlet NSButton *removeIndexedColumnButton; IBOutlet NSButton *confirmAddIndexButton; -#ifndef SP_CODA IBOutlet NSBox *anchoredButtonBar; // Advanced options view @@ -71,9 +67,8 @@ IBOutlet NSButton *indexAdvancedOptionsViewLabelButton; IBOutlet NSPopUpButton *indexStorageTypePopUpButton; IBOutlet NSTextField *indexKeyBlockSizeTextField; -#endif - BOOL _mainNibLoaded; + BOOL mainNibLoaded; BOOL isMyISAMTable; BOOL isInnoDBTable; NSString *table; @@ -81,30 +76,17 @@ NSMutableArray *fields, *indexes, *indexedFields; NSArray *supportsLength, *requiresLength; -#ifndef SP_CODA /* ivars */ NSUserDefaults *prefs; -#endif SPMySQLConnection *connection; - -#ifndef SP_CODA /* ivars */ + BOOL showAdvancedView; NSInteger heightOffset; NSUInteger windowMinWidth; NSUInteger windowMinHeigth; -#endif } -#ifdef SP_CODA -@property (assign) SPTableView* indexesTableView; -@property (assign) SPTableStructure* tableStructure; -@property (assign) NSButton* addIndexButton; -@property (assign) NSButton* removeIndexButton; - -- (void)setDatabaseDocument:(SPDatabaseDocument*)db; -#endif - /** * @property table The table currently being viewed */ diff --git a/Source/SPIndexesController.m b/Source/SPIndexesController.m index 5b239ec0..debeaf30 100644 --- a/Source/SPIndexesController.m +++ b/Source/SPIndexesController.m @@ -50,14 +50,13 @@ static const NSString *SPNewIndexIndexedColumns = @"IndexedColumns"; static const NSString *SPNewIndexStorageType = @"IndexStorageType"; static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; -@interface SPIndexesController (PrivateAPI) +@interface SPIndexesController () +- (BOOL)_isFullTextIndexSelected; - (void)_addAdditionalIndexTypes; - (void)_reloadIndexedColumnsTableData; - - (void)_addIndexUsingDetails:(NSDictionary *)indexDetails; - (void)_removeIndexUsingDetails:(NSDictionary *)indexDetails; - - (void)_resizeWindowForAdvancedOptionsViewByHeightDelta:(NSInteger)delta; @end @@ -67,32 +66,18 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; @synthesize table; @synthesize connection; -#ifdef SP_CODA -@synthesize indexesTableView; -@synthesize tableStructure; -@synthesize addIndexButton; -@synthesize removeIndexButton; -#endif - #pragma mark - - (id)init { -#ifndef SP_CODA - NSString* nibName = @"IndexesView"; -#else - NSString* nibName = @"SQLIndexes"; -#endif - - if ((self = [super initWithWindowNibName:nibName])) { - _mainNibLoaded = NO; + if ((self = [super initWithWindowNibName:@"IndexesView"])) { + mainNibLoaded = NO; table = @""; fields = [[NSMutableArray alloc] init]; indexes = [[NSMutableArray alloc] init]; indexedFields = [[NSMutableArray alloc] init]; -#ifndef SP_CODA /* init ivars */ prefs = [NSUserDefaults standardUserDefaults]; showAdvancedView = NO; @@ -100,7 +85,6 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; heightOffset = 0; windowMinWidth = [[self window] minSize].width; windowMinHeigth = [[self window] minSize].height; -#endif // Create an array of field types that supporting specifying an index length prefix supportsLength = [[NSArray alloc] initWithObjects: @@ -119,18 +103,14 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; - (void)awakeFromNib { // As this controller also loads its own nib, it may call awakeFromNib multiple times; perform setup only once. - if (_mainNibLoaded) return; - _mainNibLoaded = YES; + if (mainNibLoaded) return; + mainNibLoaded = YES; -#ifndef SP_CODA /* patch */ // Set the index tables view's vertical gridlines if required [indexesTableView setGridStyleMask:([prefs boolForKey:SPDisplayTableViewVerticalGridlines]) ? NSTableViewSolidVerticalGridLineMask : NSTableViewGridNone]; // Set the strutcture and index view's font BOOL useMonospacedFont = [prefs boolForKey:SPUseMonospacedFonts]; -#else - BOOL useMonospacedFont = NO; -#endif CGFloat monospacedFontSize = [prefs floatForKey:SPMonospacedFontSize] > 0 ? [prefs floatForKey:SPMonospacedFontSize] : [NSFont smallSystemFontSize]; @@ -147,9 +127,7 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; [[fieldColumn dataCell] setFont:useMonospacedFont ? [NSFont fontWithName:SPDefaultMonospacedFontName size:monospacedFontSize] : [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; } -#ifndef SP_CODA /* patch */ [prefs addObserver:self forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL]; -#endif } #pragma mark - @@ -234,7 +212,6 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; [addIndexedColumnButton setEnabled:([indexedFields count] < [fields count])]; -#ifndef SP_CODA // MyISAM and InnoDB tables only support BTREE storage types so disable the storage type popup button // as it's the default anyway. [indexStorageTypePopUpButton setEnabled:(!(isMyISAMTable || isInnoDBTable))]; @@ -242,8 +219,7 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; // The ability to specify an index's key block size was added in MySQL 5.1.10 so disable the textfield // if it's not supported. [indexKeyBlockSizeTextField setEnabled:[[dbDocument serverSupport] supportsIndexKeyBlockSize]]; -#endif - + // Begin the sheet [NSApp beginSheet:[self window] modalForWindow:[dbDocument parentWindow] @@ -304,7 +280,10 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; [[buttons objectAtIndex:0] setKeyEquivalentModifierMask:NSCommandKeyMask]; [[buttons objectAtIndex:1] setKeyEquivalent:@"\r"]; - [alert beginSheetModalForWindow:[dbDocument parentWindow] modalDelegate:self didEndSelector:@selector(removeIndexSheetDidEnd:returnCode:contextInfo:) contextInfo:(hasForeignKey) ? @"removeIndexAndForeignKey" : @"removeIndex"]; + [alert beginSheetModalForWindow:[dbDocument parentWindow] + modalDelegate:self + didEndSelector:@selector(removeIndexSheetDidEnd:returnCode:contextInfo:) + contextInfo:(hasForeignKey) ? @"removeIndexAndForeignKey" : @"removeIndex"]; } /** @@ -317,9 +296,7 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; if (indexType == SPPrimaryKeyMenuTag) { [indexNameTextField setEnabled:NO]; [indexNameTextField setStringValue:@"PRIMARY"]; -#ifndef SP_CODA [indexStorageTypePopUpButton setEnabled:NO]; -#endif } else { [indexNameTextField setEnabled:YES]; @@ -327,15 +304,14 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; if ([[indexNameTextField stringValue] isEqualToString:@"PRIMARY"]) { [indexNameTextField setStringValue:@""]; } - -#ifndef SP_CODA + // Specifiying an index storage type (i.e. HASH or BTREE) is not permitted with SPATIAL indexes [indexStorageTypePopUpButton setEnabled:(indexType != SPSpatialMenuTag) && !(isMyISAMTable || isInnoDBTable)]; -#endif } - [indexSizeTableColumn setHidden:[[indexTypePopUpButton selectedItem] tag] == SPFullTextMenuTag]; - [indexesTableView reloadData]; + [indexSizeTableColumn setHidden:[self _isFullTextIndexSelected]]; + + [self _reloadIndexedColumnsTableData]; } /** @@ -343,12 +319,10 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; */ - (IBAction)closeSheet:(id)sender { -#ifndef SP_CODA // Close the advanced options view if it's open [indexAdvancedOptionsView setHidden:YES]; [indexAdvancedOptionsViewButton setState:NSOffState]; showAdvancedView = NO; -#endif // Hide the size column [indexSizeTableColumn setHidden:YES]; @@ -357,11 +331,9 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; [NSApp endSheet:[sender window] returnCode:[sender tag]]; [[sender window] orderOut:self]; - -#ifndef SP_CODA + // Clear the index key block size field [indexKeyBlockSizeTextField setStringValue:@""]; -#endif } /** @@ -410,7 +382,6 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; */ - (IBAction)toggleAdvancedIndexOptionsView:(id)sender { -#ifndef SP_CODA showAdvancedView = (!showAdvancedView); [indexAdvancedOptionsViewButton setState:showAdvancedView]; @@ -429,8 +400,7 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; [indexSizeTableColumn setHidden:hideSizesColumn]; - [self _resizeWindowForAdvancedOptionsViewByHeightDelta:(showAdvancedView) ? ([indexAdvancedOptionsView frame].size.height + 10) : 0]; -#endif + [self _resizeWindowForAdvancedOptionsViewByHeightDelta:showAdvancedView ? ([indexAdvancedOptionsView frame].size.height + 10) : 0]; } #pragma mark - @@ -444,7 +414,7 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex { - if(tableView == indexesTableView) { + if (tableView == indexesTableView) { return [[indexes objectAtIndex:rowIndex] objectForKey:[tableColumn identifier]]; } else { @@ -497,7 +467,7 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; // If the field is of type TEXT or BLOB then a index prefix length is required so change the default // placeholder of 'optional' to 'required', BUT only if the index type is not FULLTEXT. - BOOL isFullTextType = [[indexTypePopUpButton selectedItem] tag] == SPFullTextMenuTag; + BOOL isFullTextType = [self _isFullTextIndexSelected]; [cell setPlaceholderString:([requiresLength containsObject:[[[indexedFields objectAtIndex:rowIndex] objectForKey:@"type"] uppercaseString]] && !isFullTextType) ? NSLocalizedString(@"required", @"required placeholder string") : NSLocalizedString(@"optional", @"optional placeholder string")]; } @@ -511,7 +481,7 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; */ - (NSInteger)numberOfItemsInComboBoxCell:(NSComboBoxCell *)comboBoxCell { - return ([fields count] - [indexedFields count]); + return [fields count] - [indexedFields count]; } /** @@ -525,7 +495,7 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; NSString *name = [[availableFields objectAtIndex:index] objectForKey:@"name"]; - [availableFields release]; + SPClear(availableFields); return name; } @@ -579,13 +549,6 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; [indexes setArray:tableIndexes]; } -#ifdef SP_CODA -- (void)setDatabaseDocument:(SPDatabaseDocument*)db -{ - dbDocument = db; -} -#endif - #pragma mark - #pragma mark Other methods @@ -617,7 +580,7 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; } } - [copy release]; + SPClear(copy); // In the event that we removed duplicate columns reload the table view to ensure that the next time // it is open we don't cause the table view to ask for rows that no longer exist. @@ -625,7 +588,7 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; [indexDetails setObject:indexedFields forKey:SPNewIndexIndexedColumns]; [indexDetails setObject:[indexNameTextField stringValue] forKey:SPNewIndexIndexName]; - + switch ([[indexTypePopUpButton selectedItem] tag]) { case SPPrimaryKeyMenuTag: @@ -644,8 +607,7 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; [indexDetails setObject:@"SPATIAL" forKey:SPNewIndexIndexType]; break; } - -#ifndef SP_CODA + // If there is a key block size set it means the database version supports it if ([[indexKeyBlockSizeTextField stringValue] length]) { [indexDetails setObject:[NSNumber numberWithInteger:[indexKeyBlockSizeTextField integerValue]] forKey:SPNewIndexKeyBlockSize]; @@ -654,7 +616,6 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; if (([indexStorageTypePopUpButton indexOfSelectedItem] > 0) && ([[indexTypePopUpButton selectedItem] tag] != SPSpatialMenuTag)) { [indexDetails setObject:[indexStorageTypePopUpButton titleOfSelectedItem] forKey:SPNewIndexStorageType]; } -#endif if ([NSThread isMainThread]) { [NSThread detachNewThreadWithName:SPCtxt(@"SPIndexesController index creation thread", dbDocument) target:self selector:@selector(_addIndexUsingDetails:) object:indexDetails]; @@ -733,7 +694,7 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; { // Remove index if ([menuItem action] == @selector(removeIndex:)) { - return ([indexesTableView numberOfSelectedRows] == 1); + return [indexesTableView numberOfSelectedRows] == 1; } // Reset AUTO_INCREMENT @@ -755,6 +716,14 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; #pragma mark Private API methods /** + * Is the currently selected index type FULLTEXT. + */ +- (BOOL)_isFullTextIndexSelected +{ + return [indexTypePopUpButton selectedTag] == SPFullTextMenuTag; +} + +/** * Adds any additional index types depending on the table type. */ - (void)_addAdditionalIndexTypes @@ -780,7 +749,7 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; } // FULLTEXT only works with MyISAM and (InnoDB since 5.6.4) - if(isMyISAMTable || (isInnoDBTable && [[dbDocument serverSupport] supportsFulltextOnInnoDB])) { + if (isMyISAMTable || (isInnoDBTable && [[dbDocument serverSupport] supportsFulltextOnInnoDB])) { NSMenuItem *fullTextMenuItem = [[[NSMenuItem alloc] init] autorelease]; [fullTextMenuItem setTitle:NSLocalizedString(@"FULLTEXT", @"full text index menu item title")]; @@ -798,22 +767,22 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; NSUInteger sizeRequiredFieldAndNotYetSet = 0; NSUInteger sizeRequired = 0; + BOOL isFullTextType = [self _isFullTextIndexSelected]; + for (NSDictionary *field in indexedFields) { - if ([requiresLength containsObject:[[field objectForKey:@"type"] uppercaseString]]) { + if (!isFullTextType && [requiresLength containsObject:[[field objectForKey:@"type"] uppercaseString]]) { sizeRequired++; sizeRequiredFieldAndNotYetSet++; if ([field objectForKey:@"Size"] && [(NSString *)[field objectForKey:@"Size"] length]) { sizeRequiredFieldAndNotYetSet--; + } } } - } -#ifndef SP_CODA // Only toggle the sizes column if the advanced view is hidden and at least one field requires a size if (!showAdvancedView) [indexSizeTableColumn setHidden:!sizeRequired]; -#endif // Validate Add Button [confirmAddIndexButton setEnabled:!sizeRequiredFieldAndNotYetSet]; @@ -837,9 +806,8 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; NSString *indexName = [indexDetails objectForKey:SPNewIndexIndexName]; NSString *indexType = [indexDetails objectForKey:SPNewIndexIndexType]; NSString *indexStorageType = [indexDetails objectForKey:SPNewIndexStorageType]; - NSNumber *indexKeyBlockSize = [indexDetails objectForKey:SPNewIndexKeyBlockSize]; - - NSArray *indexedColumns = [indexDetails objectForKey:SPNewIndexIndexedColumns]; + NSNumber *indexKeyBlockSize = [indexDetails objectForKey:SPNewIndexKeyBlockSize]; + NSArray *indexedColumns = [indexDetails objectForKey:SPNewIndexIndexedColumns]; // Interface validation should prevent this, but just to be safe if ([indexedColumns count] > 0) { @@ -875,52 +843,54 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; [tempIndexedColumns addObject:[columnName backtickQuotedString]]; } } - - if ((![indexType isEqualToString:@"INDEX"]) && (![indexType isEqualToString:@"PRIMARY KEY"])) indexType = [indexType stringByAppendingFormat:@" INDEX"]; - // Build the query - NSMutableString *query = [NSMutableString stringWithFormat:@"ALTER TABLE %@ ADD %@", [table backtickQuotedString], indexType]; + if ([tempIndexedColumns count]) { - // If supplied specify the index's name - if ([indexName length]) { - [query appendString:@" "]; - [query appendString:indexName]; - } + if ((![indexType isEqualToString:@"INDEX"]) && (![indexType isEqualToString:@"PRIMARY KEY"])) indexType = [indexType stringByAppendingFormat:@" INDEX"]; - // If supplied specify the index's storage type - if (indexStorageType) { - [query appendString:@" USING "]; - [query appendString:indexStorageType]; - } + // Build the query + NSMutableString *query = [NSMutableString stringWithFormat:@"ALTER TABLE %@ ADD %@", [table backtickQuotedString], indexType]; - // Add the columns - [query appendFormat:@" (%@)", [tempIndexedColumns componentsJoinedByCommas]]; - - // If supplied specify the index's key block size - if (indexKeyBlockSize) { - [query appendFormat:@" KEY_BLOCK_SIZE = %ld", (long)[indexKeyBlockSize integerValue]]; - } + // If supplied specify the index's name + if ([indexName length]) { + [query appendString:@" "]; + [query appendString:indexName]; + } - // Execute the query - [connection queryString:query]; + // If supplied specify the index's storage type + if (indexStorageType) { + [query appendString:@" USING "]; + [query appendString:indexStorageType]; + } - // Release temp array - [tempIndexedColumns release]; + // Add the columns + [query appendFormat:@" (%@)", [tempIndexedColumns componentsJoinedByCommas]]; - // Check for errors, but only if the query wasn't cancelled - if ([connection queryErrored] && ![connection lastQueryWasCancelled]) { - SPOnewayAlertSheet( - NSLocalizedString(@"Unable to add index", @"add index error message"), - [dbDocument parentWindow], - [NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to add the index.\n\nMySQL said: %@", @"add index error informative message"), [connection lastErrorMessage]] - ); - } - else { - [tableData resetAllData]; - [dbDocument setStatusRequiresReload:YES]; + // If supplied specify the index's key block size + if (indexKeyBlockSize) { + [query appendFormat:@" KEY_BLOCK_SIZE = %ld", (long)[indexKeyBlockSize integerValue]]; + } - [tableStructure loadTable:table]; + // Execute the query + [connection queryString:query]; + + // Check for errors, but only if the query wasn't cancelled + if ([connection queryErrored] && ![connection lastQueryWasCancelled]) { + SPOnewayAlertSheet( + NSLocalizedString(@"Unable to add index", @"add index error message"), + [dbDocument parentWindow], + [NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to add the index.\n\nMySQL said: %@", @"add index error informative message"), [connection lastErrorMessage]] + ); + } + else { + [tableData resetAllData]; + [dbDocument setStatusRequiresReload:YES]; + + [tableStructure loadTable:table]; + } } + + SPClear(tempIndexedColumns); } // Reset indexed fields to default @@ -1017,14 +987,11 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; NSUInteger popUpMask = [indexTypePopUpButton autoresizingMask]; NSUInteger nameFieldMask = [indexNameTextField autoresizingMask]; NSUInteger scrollMask = [indexedColumnsScrollView autoresizingMask]; -#ifndef SP_CODA NSUInteger buttonMask = [indexAdvancedOptionsViewButton autoresizingMask]; NSUInteger textFieldMask = [indexAdvancedOptionsViewLabelButton autoresizingMask]; NSUInteger advancedViewMask = [indexAdvancedOptionsView autoresizingMask]; -#endif NSUInteger typeLabelMask = [indexTypeLabel autoresizingMask]; NSUInteger nameLabelMask = [indexNameLabel autoresizingMask]; -#ifndef SP_CODA NSUInteger buttonBarMask = [(NSView*)anchoredButtonBar autoresizingMask]; NSRect frame = [[self window] frame]; @@ -1035,27 +1002,22 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; [[self window] setFrame:frame display:YES animate:YES]; } -#endif [indexTypePopUpButton setAutoresizingMask:NSViewNotSizable | NSViewMinYMargin]; [indexNameTextField setAutoresizingMask:NSViewNotSizable | NSViewMinYMargin]; [indexedColumnsScrollView setAutoresizingMask:NSViewNotSizable | NSViewMinYMargin]; -#ifndef SP_CODA [indexAdvancedOptionsViewButton setAutoresizingMask:NSViewNotSizable | NSViewMinYMargin]; [indexAdvancedOptionsViewLabelButton setAutoresizingMask:NSViewNotSizable | NSViewMinYMargin]; [indexAdvancedOptionsView setAutoresizingMask:NSViewNotSizable | NSViewMinYMargin]; -#endif [indexTypeLabel setAutoresizingMask:NSViewNotSizable | NSViewMinYMargin]; [indexNameLabel setAutoresizingMask:NSViewNotSizable | NSViewMinYMargin]; -#ifndef SP_CODA + [(NSView*)anchoredButtonBar setAutoresizingMask:NSViewNotSizable | NSViewMinYMargin]; NSInteger newMinHeight = (windowMinHeigth - heightOffset + delta < windowMinHeigth) ? windowMinHeigth : windowMinHeigth - heightOffset + delta; [[self window] setMinSize:NSMakeSize(windowMinWidth, newMinHeight)]; -#endif -#ifndef SP_CODA frame.origin.y += heightOffset; frame.size.height -= heightOffset; @@ -1065,21 +1027,17 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; frame.size.height += heightOffset; [[self window] setFrame:frame display:YES animate:YES]; -#endif [indexTypePopUpButton setAutoresizingMask:popUpMask]; [indexNameTextField setAutoresizingMask:nameFieldMask]; [indexedColumnsScrollView setAutoresizingMask:scrollMask]; -#ifndef SP_CODA [indexAdvancedOptionsViewButton setAutoresizingMask:buttonMask]; [indexAdvancedOptionsViewLabelButton setAutoresizingMask:textFieldMask]; [indexAdvancedOptionsView setAutoresizingMask:advancedViewMask]; -#endif [indexTypeLabel setAutoresizingMask:typeLabelMask]; [indexNameLabel setAutoresizingMask:nameLabelMask]; -#ifndef SP_CODA + [(NSView*)anchoredButtonBar setAutoresizingMask:buttonBarMask]; -#endif } #pragma mark - @@ -1095,9 +1053,7 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; if (indexedFields) SPClear(indexedFields); -#ifndef SP_CODA [prefs removeObserver:self forKeyPath:SPDisplayTableViewVerticalGridlines]; -#endif [super dealloc]; } diff --git a/Source/SPKeychain.m b/Source/SPKeychain.m index 49e2de69..94b561c5 100644 --- a/Source/SPKeychain.m +++ b/Source/SPKeychain.m @@ -230,10 +230,8 @@ */ - (BOOL)passwordExistsForName:(NSString *)name account:(NSString *)account { -#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 // "kSecClassGenericPassword" was introduced with the 10.7 SDK. // It won't work on 10.6 either (meaning this code never matches properly there). - // (That's why there are compile time and runtime checks here) if([SPOSInfo isOSVersionAtLeastMajor:10 minor:7 patch:0]) { NSMutableDictionary *query = [NSMutableDictionary dictionary]; @@ -248,7 +246,9 @@ return SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&result) == errSecSuccess; } -#endif + + //Version for 10.6 + SecKeychainItemRef item; SecKeychainSearchRef search = NULL; NSInteger numberOfItemsFound = 0; diff --git a/Source/SPOSInfo.m b/Source/SPOSInfo.m index b862e898..412b634a 100644 --- a/Source/SPOSInfo.m +++ b/Source/SPOSInfo.m @@ -29,26 +29,7 @@ // More info at <https://github.com/sequelpro/sequelpro> #import "SPOSInfo.h" - -// Needed because this class is also compiled with SequelProTunnelAssistant which can't access SPConstants.h -#ifndef __MAC_10_10 -#define __MAC_10_10 101000 -#endif - -#if __MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_10 -// This code is available since 10.8 but public only since 10.10 -typedef struct { - NSInteger majorVersion; - NSInteger minorVersion; - NSInteger patchVersion; -} NSOperatingSystemVersion; - -@interface NSProcessInfo () -- (NSOperatingSystemVersion)operatingSystemVersion; -- (BOOL)isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion)version; -@end - -#endif +#import "SPCompatibility.h" // Needed because this class is also compiled with SequelProTunnelAssistant int SPOSVersionCompare(SPOSVersion left, SPOSVersion right) { diff --git a/Source/SPProcessListController.m b/Source/SPProcessListController.m index d04273e1..8290b5d9 100644 --- a/Source/SPProcessListController.m +++ b/Source/SPProcessListController.m @@ -54,6 +54,8 @@ static NSString *SPTableViewIDColumnIdentifier = @"Id"; - (void)_killProcessQueryWithId:(long long)processId; - (void)_killProcessConnectionWithId:(long long)processId; - (void)_updateServerProcessesFilterForFilterString:(NSString *)filterString; +- (void)_addPreferenceObservers; +- (void)_removePreferenceObservers; @end @@ -111,9 +113,8 @@ static NSString *SPTableViewIDColumnIdentifier = @"Id"; if (columnWidth) [column setWidth:[columnWidth floatValue]]; } - - // Register as an observer for the when the UseMonospacedFonts preference changes - [prefs addObserver:self forKeyPath:SPUseMonospacedFonts options:NSKeyValueObservingOptionNew context:NULL]; + + [self _addPreferenceObservers]; } /** @@ -140,10 +141,7 @@ static NSString *SPTableViewIDColumnIdentifier = @"Id"; NSMutableString *string = [NSMutableString string]; NSIndexSet *rows = [processListTableView selectedRowIndexes]; - NSUInteger i = [rows firstIndex]; - - while (i != NSNotFound) - { + [rows enumerateIndexesUsingBlock:^(NSUInteger i, BOOL * _Nonnull stop) { if (i < [processesFiltered count]) { NSDictionary *process = NSArrayObjectAtIndex(processesFiltered, i); @@ -160,9 +158,7 @@ static NSString *SPTableViewIDColumnIdentifier = @"Id"; [string appendString:stringTmp]; [string appendString:@"\n"]; } - - i = [rows indexGreaterThanIndex:i]; - } + }]; NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard]; @@ -765,14 +761,35 @@ static NSString *SPTableViewIDColumnIdentifier = @"Id"; [saveProcessesButton setTitle:NSLocalizedString(@"Save View As...", @"save view as button title")]; } +/** + * Add any necessary preference observers to allow live updating on changes. + */ +- (void)_addPreferenceObservers +{ + // Register as an observer for the when the UseMonospacedFonts preference changes + [prefs addObserver:self forKeyPath:SPUseMonospacedFonts options:NSKeyValueObservingOptionNew context:NULL]; + + // Register to obeserve table view vertical grid line pref changes + [prefs addObserver:self forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL]; +} + +/** + * Remove any previously added preference observers. + */ +- (void)_removePreferenceObservers +{ + [prefs removeObserver:self forKeyPath:SPUseMonospacedFonts]; + [prefs removeObserver:self forKeyPath:SPDisplayTableViewVerticalGridlines]; +} + #pragma mark - - (void)dealloc { - [prefs removeObserver:self forKeyPath:SPUseMonospacedFonts]; - processListThreadRunning = NO; - + + [self _removePreferenceObservers]; + SPClear(processes); if (autoRefreshTimer) SPClear(autoRefreshTimer); diff --git a/Source/SPQueryConsoleDataSource.m b/Source/SPQueryConsoleDataSource.m index eaac2151..eb669051 100644 --- a/Source/SPQueryConsoleDataSource.m +++ b/Source/SPQueryConsoleDataSource.m @@ -97,4 +97,15 @@ static NSUInteger SPMessageTruncateCharacterLength = 256; #endif } +- (BOOL)tableView:(NSTableView *)aTableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard +{ + NSString *string = [self sqlStringForRowIndexes:rowIndexes]; + if([string length]) { + [pboard declareTypes:@[NSStringPboardType] owner:self]; + return [pboard setString:string forType:NSStringPboardType]; + } + + return NO; +} + @end diff --git a/Source/SPQueryController.h b/Source/SPQueryController.h index 8d128fe3..12ff6d7b 100644 --- a/Source/SPQueryController.h +++ b/Source/SPQueryController.h @@ -84,6 +84,10 @@ extern NSString *SPTableViewDatabaseColumnID; + (SPQueryController *)sharedQueryController; +/** + * Calls -sqlStringForForRowIndexes: with the current selection and + * puts the output into the general Pasteboard (only if non-empty) + */ - (IBAction)copy:(id)sender; - (IBAction)clearConsole:(id)sender; - (IBAction)saveConsoleAs:(id)sender; @@ -103,4 +107,17 @@ extern NSString *SPTableViewDatabaseColumnID; - (NSUInteger)consoleMessageCount; +/** + * Returns the console messages specified by indexes as a string, each message separated by "\n". + * @param indexes The indexes of rows to be returned. + * Invalid indexes will be skipped silently. + * nil is treated as an empty set. + * + * If no (valid) indexes are given, @"" will be returned. + * The output may include other info like timestamp, host, etc. if shown in the table view, as part of a comment. + * + * THIS METHOD IS NOT THREAD-SAFE! + */ +- (NSString *)sqlStringForRowIndexes:(NSIndexSet *)indexes; + @end diff --git a/Source/SPQueryController.m b/Source/SPQueryController.m index c57621d8..41d71154 100644 --- a/Source/SPQueryController.m +++ b/Source/SPQueryController.m @@ -150,54 +150,13 @@ static SPQueryController *sharedQueryController = nil; */ - (void)copy:(id)sender { -#ifndef SP_CODA NSResponder *firstResponder = [[self window] firstResponder]; if ((firstResponder == consoleTableView) && ([consoleTableView numberOfSelectedRows] > 0)) { - - NSMutableString *string = [NSMutableString string]; + NSIndexSet *rows = [consoleTableView selectedRowIndexes]; - NSUInteger i = [rows firstIndex]; - - BOOL includeTimestamps = ![[consoleTableView tableColumnWithIdentifier:SPTableViewDateColumnID] isHidden]; - BOOL includeConnections = ![[consoleTableView tableColumnWithIdentifier:SPTableViewConnectionColumnID] isHidden]; - BOOL includeDatabases = ![[consoleTableView tableColumnWithIdentifier:SPTableViewDatabaseColumnID] isHidden]; - - [string setString:@""]; - - while (i != NSNotFound) - { - if (i < [messagesVisibleSet count]) { - SPConsoleMessage *message = NSArrayObjectAtIndex(messagesVisibleSet, i); - - if (includeTimestamps || includeConnections || includeDatabases) [string appendString:@"/* "]; - - NSDate *date = [message messageDate]; - if (includeTimestamps && date) { - [string appendString:[dateFormatter stringFromDate:date]]; - [string appendString:@" "]; - } - - NSString *connection = [message messageConnection]; - if (includeConnections && connection) { - [string appendString:connection]; - [string appendString:@" "]; - } - - NSString *database = [message messageDatabase]; - if (includeDatabases && database) { - [string appendString:database]; - [string appendString:@" "]; - } - - if (includeTimestamps || includeConnections || includeDatabases) [string appendString:@"*/ "]; - - [string appendFormat:@"%@\n", [message message]]; - } - - i = [rows indexGreaterThanIndex:i]; - } + NSString *string = [self sqlStringForRowIndexes:rows]; NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard]; @@ -205,7 +164,50 @@ static SPQueryController *sharedQueryController = nil; [pasteBoard declareTypes:@[NSStringPboardType] owner:nil]; [pasteBoard setString:string forType:NSStringPboardType]; } -#endif +} + +- (NSString *)sqlStringForRowIndexes:(NSIndexSet *)rows +{ + if(![rows count]) return @""; + + NSMutableString *string = [[NSMutableString alloc] init]; + + BOOL includeTimestamps = ![[consoleTableView tableColumnWithIdentifier:SPTableViewDateColumnID] isHidden]; + BOOL includeConnections = ![[consoleTableView tableColumnWithIdentifier:SPTableViewConnectionColumnID] isHidden]; + BOOL includeDatabases = ![[consoleTableView tableColumnWithIdentifier:SPTableViewDatabaseColumnID] isHidden]; + + [rows enumerateIndexesUsingBlock:^(NSUInteger i, BOOL * _Nonnull stop) { + if (i < [messagesVisibleSet count]) { + SPConsoleMessage *message = NSArrayObjectAtIndex(messagesVisibleSet, i); + + if (includeTimestamps || includeConnections || includeDatabases) [string appendString:@"/* "]; + + NSDate *date = [message messageDate]; + if (includeTimestamps && date) { + [string appendString:[dateFormatter stringFromDate:date]]; + [string appendString:@" "]; + } + + NSString *connection = [message messageConnection]; + if (includeConnections && connection) { + [string appendString:connection]; + [string appendString:@" "]; + } + + NSString *database = [message messageDatabase]; + if (includeDatabases && database) { + [string appendString:database]; + [string appendString:@" "]; + } + + if (includeTimestamps || includeConnections || includeDatabases) [string appendString:@"*/ "]; + + [string appendString:[message message]]; + [string appendString:@"\n"]; + } + }]; + + return [string autorelease]; } /** diff --git a/Source/SPQueryControllerInitializer.m b/Source/SPQueryControllerInitializer.m index fc03d107..f8292b37 100644 --- a/Source/SPQueryControllerInitializer.m +++ b/Source/SPQueryControllerInitializer.m @@ -85,6 +85,9 @@ static NSString *SPCompletionTokensSnippetsKey = @"function_argument_snippets"; { [[column dataCell] setFont:(useMonospacedFont) ? [NSFont fontWithName:SPDefaultMonospacedFontName size:monospacedFontSize] : [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; } + + //allow drag-out copying of selected rows + [consoleTableView setDraggingSourceOperationMask:NSDragOperationCopy forLocal:NO]; #endif } diff --git a/Source/SPQueryFavoriteManager.m b/Source/SPQueryFavoriteManager.m index ceb1efc4..2f88bbcf 100644 --- a/Source/SPQueryFavoriteManager.m +++ b/Source/SPQueryFavoriteManager.m @@ -730,11 +730,9 @@ // TODO: still rely on a NSArray but in the future rewrite it to use the NSIndexSet directly NSMutableArray *draggedRows = [[NSMutableArray alloc] initWithCapacity:1]; - NSUInteger rowIndex = [draggedIndexes firstIndex]; - while ( rowIndex != NSNotFound ) { + [draggedIndexes enumerateIndexesUsingBlock:^(NSUInteger rowIndex, BOOL * _Nonnull stop) { [draggedRows addObject:[NSNumber numberWithUnsignedInteger:rowIndex]]; - rowIndex = [draggedIndexes indexGreaterThanIndex: rowIndex]; - } + }]; NSInteger destinationRow = row; NSInteger offset = 0; @@ -791,14 +789,9 @@ if (returnCode == NSAlertDefaultReturn) { NSIndexSet *indexes = [favoritesTableView selectedRowIndexes]; - // get last index - NSUInteger currentIndex = [indexes lastIndex]; - - while (currentIndex != NSNotFound) { + [indexes enumerateIndexesWithOptions:NSEnumerationReverse usingBlock:^(NSUInteger currentIndex, BOOL * _Nonnull stop) { [favorites removeObjectAtIndex:currentIndex]; - // get next index (beginning from the end) - currentIndex = [indexes indexLessThanIndex:currentIndex]; - } + }]; [favoritesArrayController rearrangeObjects]; [favoritesTableView reloadData]; diff --git a/Source/SPServerVariablesController.m b/Source/SPServerVariablesController.m index dade0687..86bce928 100644 --- a/Source/SPServerVariablesController.m +++ b/Source/SPServerVariablesController.m @@ -53,6 +53,8 @@ { if ((self = [super initWithWindowNibName:@"DatabaseServerVariables"])) { variables = [[NSMutableArray alloc] init]; + + prefs = [NSUserDefaults standardUserDefaults]; } return self; @@ -60,8 +62,6 @@ - (void)awakeFromNib { - prefs = [NSUserDefaults standardUserDefaults]; - // Set the process table view's vertical gridlines if required [variablesTableView setGridStyleMask:([prefs boolForKey:SPDisplayTableViewVerticalGridlines]) ? NSTableViewSolidVerticalGridLineMask : NSTableViewGridNone]; @@ -74,8 +74,7 @@ [[column dataCell] setFont:useMonospacedFont ? [NSFont fontWithName:SPDefaultMonospacedFontName size:monospacedFontSize] : [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; } - // Register as an observer for the when the UseMonospacedFonts preference changes - [prefs addObserver:self forKeyPath:SPUseMonospacedFonts options:NSKeyValueObservingOptionNew context:NULL]; + [self _addPreferenceObservers]; } #pragma mark - @@ -342,13 +341,10 @@ if ((firstResponder == variablesTableView) && ([variablesTableView numberOfSelectedRows] > 0)) { - NSString *string = @""; + NSMutableString *string = [[NSMutableString alloc] init]; NSIndexSet *rows = [variablesTableView selectedRowIndexes]; - NSUInteger i = [rows firstIndex]; - - while (i != NSNotFound) - { + [rows enumerateIndexesUsingBlock:^(NSUInteger i, BOOL * _Nonnull stop) { if (i < [variablesFiltered count]) { NSDictionary *variable = NSArrayObjectAtIndex(variablesFiltered, i); @@ -357,29 +353,49 @@ // Decide what to include in the string if (name && value) { - string = [string stringByAppendingFormat:@"%@ = %@\n", variableName, variableValue]; + [string appendFormat:@"%@ = %@\n", variableName, variableValue]; } else { - string = [string stringByAppendingFormat:@"%@\n", (name) ? variableName : variableValue]; + [string appendFormat:@"%@\n", (name) ? variableName : variableValue]; } } - - i = [rows indexGreaterThanIndex:i]; - } + }]; NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard]; // Copy the string to the pasteboard [pasteBoard declareTypes:@[NSStringPboardType] owner:nil]; [pasteBoard setString:string forType:NSStringPboardType]; + [string release]; } } +/** + * Add any necessary preference observers to allow live updating on changes. + */ +- (void)_addPreferenceObservers +{ + // Register as an observer for the when the UseMonospacedFonts preference changes + [prefs addObserver:self forKeyPath:SPUseMonospacedFonts options:NSKeyValueObservingOptionNew context:NULL]; + + // Register to obeserve table view vertical grid line pref changes + [prefs addObserver:self forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL]; +} + +/** + * Remove any previously added preference observers. + */ +- (void)_removePreferenceObservers +{ + [prefs removeObserver:self forKeyPath:SPUseMonospacedFonts]; + [prefs removeObserver:self forKeyPath:SPDisplayTableViewVerticalGridlines]; +} + #pragma mark - - (void)dealloc { - [prefs removeObserver:self forKeyPath:SPUseMonospacedFonts]; + [self _removePreferenceObservers]; SPClear(variables); diff --git a/Source/SPTableContent.m b/Source/SPTableContent.m index 416b7cd8..0738fe96 100644 --- a/Source/SPTableContent.m +++ b/Source/SPTableContent.m @@ -243,20 +243,16 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper [nibLoader release]; -#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_7 //let's see if we can use the NSPopover (10.7+) or have to make do with our legacy clone. //this is using reflection right now, as our SDK is 10.8 but our minimum supported version is 10.6 Class popOverClass = NSClassFromString(@"NSPopover"); - if(popOverClass) - { + if(popOverClass) { paginationPopover = [[popOverClass alloc] init]; [paginationPopover setDelegate:(SPTableContent<NSPopoverDelegate> *)self]; [paginationPopover setContentViewController:paginationViewController]; [paginationPopover setBehavior:NSPopoverBehaviorTransient]; } - else -#endif - { + else { [paginationBox setContentView:[paginationViewController view]]; // Add the pagination view to the content area @@ -1638,13 +1634,11 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper } #endif -#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_7 - (void)popoverDidClose:(NSNotification *)notification { //not to hide the view, but to change the paginationButton [self setPaginationViewVisibility:NO]; } -#endif /** * Show or hide the pagination layer, also changing the first responder as appropriate. @@ -1672,7 +1666,6 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper } } -#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_7 if(paginationPopover) { if(makeVisible) { [paginationPopover showRelativeToRect:[paginationButton bounds] ofView:paginationButton preferredEdge:NSMinYEdge]; @@ -1684,7 +1677,6 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper } return; } -#endif if (makeVisible) { if (paginationViewFrame.size.height == paginationViewHeight) return; diff --git a/Source/SPTableContentDelegate.m b/Source/SPTableContentDelegate.m index a510108b..186fbfcc 100644 --- a/Source/SPTableContentDelegate.m +++ b/Source/SPTableContentDelegate.m @@ -519,9 +519,7 @@ else { [cell setTextColor:blackColor]; } - - NSDictionary *columnDefinition = [[(id <SPDatabaseContentViewDelegate>)[tableContentView delegate] dataColumnDefinitions] objectAtIndex:columnIndex]; - + if ([self cellValueIsDisplayedAsHexForColumn:[[tableColumn identifier] integerValue]]) { [cell setTextColor:rowIndex == [tableContentView selectedRow] ? whiteColor : blueColor]; } diff --git a/Source/SPTableCopy.h b/Source/SPTableCopy.h index c0d87929..eba968c6 100644 --- a/Source/SPTableCopy.h +++ b/Source/SPTableCopy.h @@ -41,6 +41,7 @@ * @param name name of the table in the source database * @param sourceDB name of the source database * @param targetDB name of the target database + * * @return YES on success, NO on any kind of error (unspecified) */ - (BOOL)copyTable:(NSString *)name from:(NSString *)sourceDB to:(NSString *)targetDB; @@ -61,6 +62,7 @@ * @param sourceDB name of the source database * @param targetDB name of the target database * @param copyWithContent whether to copy the content too, otherwise only structure + * * @return YES on success, NO on any kind of error (unspecified) */ - (BOOL)copyTable:(NSString *)tableName from:(NSString *)sourceDB to: (NSString *)targetDB withContent:(BOOL)copyWithContent; @@ -72,6 +74,7 @@ * @param sourceDB name of the source database * @param targetDB name of the target database * @param copyWithContent whether to copy the content too, otherwise only structure + * * @return YES on success, NO on any kind of error (unspecified) * * This method is able to copy InnoDB tables with foreign key constraints. diff --git a/Source/SPTableCopy.m b/Source/SPTableCopy.m index 07f03846..bc13bc5c 100644 --- a/Source/SPTableCopy.m +++ b/Source/SPTableCopy.m @@ -117,7 +117,7 @@ success = NO; } - // re-enable id creation + // Re-enable id creation [connection queryString:@"/*!40101 SET SQL_MODE=@OLD_SQL_MODE */"]; if ([connection queryErrored]) { @@ -147,11 +147,12 @@ { NSString *showCreateTableStatment = [NSString stringWithFormat:@"SHOW CREATE TABLE %@.%@", [sourceDatabase backtickQuotedString], [tableName backtickQuotedString]]; - SPMySQLResult *theResult = [connection queryString:showCreateTableStatment]; + SPMySQLResult *result = [connection queryString:showCreateTableStatment]; - if([theResult numberOfRows] > 0) return [[theResult getRowAsArray] objectAtIndex:1]; + if ([result numberOfRows] > 0) return [[result getRowAsArray] objectAtIndex:1]; - NSLog(@"query <%@> failed to return the expected result.\n Error state: %@ (%lu)",showCreateTableStatment,[connection lastErrorMessage],[connection lastErrorID]); + SPLog(@"query <%@> failed to return the expected result.\n Error state: %@ (%lu)", showCreateTableStatment, [connection lastErrorMessage], [connection lastErrorID]); + return nil; } diff --git a/Source/SPTableData.m b/Source/SPTableData.m index 8033d5a0..d095c33b 100644 --- a/Source/SPTableData.m +++ b/Source/SPTableData.m @@ -524,7 +524,7 @@ } /** - * Analyse a CREATE TABLE tring to extract the field details, primary key, unique keys, and table encoding. + * Analyse a CREATE TABLE string to extract the field details, primary key, unique keys, and table encoding. * @param tableDef @"CREATE TABLE ..." * @param tableType Can either be Table or View. Value is copied to the result and not used otherwise * @return A dict containing info about the table's structure @@ -532,6 +532,9 @@ * In future this could also be used to retrieve the majority of index information * assuming information like cardinality isn't needed. * This function is rather long due to the painful parsing required, but is fast. + * + * *WARNING* This method is only designed to handle the output of a "SHOW CREATE ..." query. + * DO NOT try to use it with user-defined input. The code does not handle the full possible syntax! */ - (NSDictionary *)parseCreateStatement:(NSString *)tableDef ofType:(NSString *)tableType { @@ -785,7 +788,7 @@ NSUInteger stringStart = NSMaxRange(charsetDefinitionRange); NSUInteger i; for (i = stringStart; i < [createTableParser length]; i++) { - if ([createTableParser characterAtIndex:i] == ' ') break; + if ([whitespaceAndNewlineSet characterIsMember:[createTableParser characterAtIndex:i]]) break; } // Catch the "default" character encoding: diff --git a/Source/SPTableInfo.h b/Source/SPTableInfo.h index 13a72976..94c10bd8 100644 --- a/Source/SPTableInfo.h +++ b/Source/SPTableInfo.h @@ -28,14 +28,19 @@ // // More info at <https://github.com/sequelpro/sequelpro> +@class SPTableView; +@class SPTablesList; +@class SPTableData; +@class SPDatabaseDocument; + @interface SPTableInfo : NSObject { - IBOutlet NSTableView *infoTable; - IBOutlet id tableList; - IBOutlet id tableListInstance; - IBOutlet id tableDataInstance; - IBOutlet id tableDocumentInstance; + IBOutlet SPTableView *tableList; + IBOutlet SPTablesList *tableListInstance; + IBOutlet SPTableData *tableDataInstance; + IBOutlet SPDatabaseDocument *tableDocumentInstance; + IBOutlet NSTableView *infoTable; IBOutlet NSTableView *activitiesTable; IBOutlet NSScrollView *tableInfoScrollView; diff --git a/Source/SPTableInfo.m b/Source/SPTableInfo.m index b72d55f8..ce9546d9 100644 --- a/Source/SPTableInfo.m +++ b/Source/SPTableInfo.m @@ -63,19 +63,20 @@ - (void)awakeFromNib { [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(tableChanged:) - name:SPTableChangedNotification - object:tableDocumentInstance]; + selector:@selector(tableChanged:) + name:SPTableChangedNotification + object:tableDocumentInstance]; + [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(tableChanged:) - name:SPTableInfoChangedNotification - object:tableDocumentInstance]; + selector:@selector(tableChanged:) + name:SPTableInfoChangedNotification + object:tableDocumentInstance]; // Register activities update notifications for add/remove BASH commands etc. [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(updateActivities) - name:SPActivitiesUpdateNotification - object:nil]; + selector:@selector(updateActivities) + name:SPActivitiesUpdateNotification + object:nil]; // Add activities header [activities addObject:@{@"name" : NSLocalizedString(@"ACTIVITIES", @"header for activities pane")}]; @@ -147,6 +148,7 @@ } [infoTable reloadData]; + return; } @@ -195,8 +197,10 @@ if([[tableStatus objectForKey:@"Data_length"] unboxNull]) { [info addObject:[NSString stringWithFormat:NSLocalizedString(@"size: %@", @"Table Info Section : table size on disk"), [NSString stringForByteSize:[[tableStatus objectForKey:@"Data_length"] longLongValue]]]]; } + NSString *tableEnc = [tableDataInstance tableEncoding]; NSString *tableColl = [tableStatus objectForKey:@"Collation"]; + if([tableColl length]) { // instead of @"latin1 (latin1_german_ci)" we can just show @"latin1 (german_ci)" if([tableColl hasPrefix:[NSString stringWithFormat:@"%@_",tableEnc]]) tableColl = [tableColl substringFromIndex:([tableEnc length]+1)]; @@ -382,11 +386,11 @@ return (row == 0 ? 25 : [tableView rowHeight]); } -- (BOOL)tableView:(NSTableView *)aTableView shouldSelectRow:(NSInteger)rowIndex +- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)rowIndex { if (rowIndex == 0) return YES; - if (aTableView == infoTable) { + if (tableView == infoTable) { return NO; } else { @@ -396,7 +400,7 @@ return NO; } -- (BOOL)tableView:(NSTableView *)aTableView shouldEditTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex +- (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex { if (rowIndex > 0) return NO; @@ -411,14 +415,15 @@ [infoTable deselectAll:nil]; [activitiesTable deselectAll:nil]; + [self updateActivities]; return NO; } -- (NSString *)tableView:(NSTableView *)aTableView toolTipForCell:(NSCell *)aCell rect:(NSRectPointer)rect tableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex mouseLocation:(NSPoint)mouseLocation +- (NSString *)tableView:(NSTableView *)tableView toolTipForCell:(NSCell *)cell rect:(NSRectPointer)rect tableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex mouseLocation:(NSPoint)mouseLocation { - if (aTableView == activitiesTable) { + if (tableView == activitiesTable) { if (rowIndex == 0) return @""; if (mouseLocation.x > rect->origin.x + rect->size.width - 30) { @@ -437,23 +442,23 @@ return nil; } -- (BOOL)tableView:(NSTableView *)aTableView isGroupRow:(NSInteger)row +- (BOOL)tableView:(NSTableView *)tableView isGroupRow:(NSInteger)row { // This makes the top row (TABLE INFORMATION/ACTIVITIES) have the diff styling - return (row == 0); + return row == 0; } -- (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex +- (void)tableView:(NSTableView *)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex { - if (aTableView == infoTable) { - if (rowIndex > 0 && [[aTableColumn identifier] isEqualToString:@"info"]) { - [(ImageAndTextCell*)aCell setImage:[NSImage imageNamed:@"table-property"]]; - [(ImageAndTextCell*)aCell setIndentationLevel:1]; - [(ImageAndTextCell*)aCell setDrawsBackground:NO]; + if (tableView == infoTable) { + if (rowIndex > 0 && [[tableColumn identifier] isEqualToString:@"info"]) { + [(ImageAndTextCell*)cell setImage:[NSImage imageNamed:@"table-property"]]; + [(ImageAndTextCell*)cell setIndentationLevel:1]; + [(ImageAndTextCell*)cell setDrawsBackground:NO]; } else { - [(ImageAndTextCell*)aCell setImage:nil]; - [(ImageAndTextCell*)aCell setIndentationLevel:0]; + [(ImageAndTextCell*)cell setImage:nil]; + [(ImageAndTextCell*)cell setIndentationLevel:0]; } } } diff --git a/Source/SPTableRelations.h b/Source/SPTableRelations.h index 1ab7f1b7..6fa2bd57 100644 --- a/Source/SPTableRelations.h +++ b/Source/SPTableRelations.h @@ -34,7 +34,7 @@ @class SPTablesList; @class SPTableData; -@interface SPTableRelations : NSObject +@interface SPTableRelations : NSObject <NSTableViewDelegate, NSTableViewDataSource> { IBOutlet SPDatabaseDocument *tableDocumentInstance; IBOutlet SPTablesList *tablesListInstance; @@ -85,8 +85,8 @@ - (void)tableSelectionChanged:(NSNotification *)notification; // Task interaction -- (void)startDocumentTaskForTab:(NSNotification *)aNotification; -- (void)endDocumentTaskForTab:(NSNotification *)aNotification; +- (void)startDocumentTaskForTab:(NSNotification *)notification; +- (void)endDocumentTaskForTab:(NSNotification *)notification; // Other - (NSArray *)relationDataForPrinting; diff --git a/Source/SPTableRelations.m b/Source/SPTableRelations.m index f358d133..20059fbb 100644 --- a/Source/SPTableRelations.m +++ b/Source/SPTableRelations.m @@ -373,27 +373,6 @@ static NSString *SPRelationOnDeleteKey = @"on_delete"; } #pragma mark - -#pragma mark TextField delegate methods - -- (void)controlTextDidChange:(NSNotification *)notification -{ - // Make sure the user does not enter a taken name, using the quickly-generated incomplete list - if ([notification object] == constraintName) { - NSString *userValue = [[constraintName stringValue] lowercaseString]; - - // Make field red and disable add button - if ([takenConstraintNames containsObject:userValue]) { - [constraintName setTextColor:[NSColor redColor]]; - [confirmAddRelationButton setEnabled:NO]; - } - else { - [constraintName setTextColor:[NSColor controlTextColor]]; - [confirmAddRelationButton setEnabled:YES]; - } - } -} - -#pragma mark - #pragma mark Tableview datasource methods - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView @@ -413,44 +392,13 @@ static NSString *SPRelationOnDeleteKey = @"on_delete"; } #pragma mark - -#pragma mark Tableview delegate methods - -/** - * Called whenever the relations table view selection changes. - */ -- (void)tableViewSelectionDidChange:(NSNotification *)notification -{ - [removeRelationButton setEnabled:([relationsTableView numberOfSelectedRows] > 0)]; -} - -/* - * Double-click action on table cells - for the time being, return - * NO to disable editing. - */ -- (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex -{ - if ([tableDocumentInstance isWorking]) return NO; - - return NO; -} - -/** - * Disable row selection while the document is working. - */ -- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)rowIndex -{ - return ![tableDocumentInstance isWorking]; -} - -#pragma mark - #pragma mark Task interaction /** * Disable all content interactive elements during an ongoing task. */ -- (void)startDocumentTaskForTab:(NSNotification *)aNotification +- (void)startDocumentTaskForTab:(NSNotification *)notification { - // Only proceed if this view is selected. if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:SPMainToolbarTableRelations]) return; @@ -462,7 +410,7 @@ static NSString *SPRelationOnDeleteKey = @"on_delete"; /** * Enable all content interactive elements after an ongoing task. */ -- (void)endDocumentTaskForTab:(NSNotification *)aNotification +- (void)endDocumentTaskForTab:(NSNotification *)notification { // Only proceed if this view is selected. if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:SPMainToolbarTableRelations]) return; @@ -529,10 +477,7 @@ static NSString *SPRelationOnDeleteKey = @"on_delete"; NSString *thisTable = [tablesListInstance tableName]; NSIndexSet *selectedSet = [relationsTableView selectedRowIndexes]; - NSUInteger row = [selectedSet lastIndex]; - - while (row != NSNotFound) - { + [selectedSet enumerateIndexesWithOptions:NSEnumerationReverse usingBlock:^(NSUInteger row, BOOL * _Nonnull stop) { NSString *relationName = [[relationData objectAtIndex:row] objectForKey:SPRelationNameKey]; NSString *query = [NSString stringWithFormat:@"ALTER TABLE %@ DROP FOREIGN KEY %@", [thisTable backtickQuotedString], [relationName backtickQuotedString]]; @@ -547,11 +492,9 @@ static NSString *SPRelationOnDeleteKey = @"on_delete"; ); // Abort loop - break; - } - - row = [selectedSet indexLessThanIndex:row]; - } + *stop = YES; + } + }]; [self _refreshRelationDataForcingCacheRefresh:YES]; } diff --git a/Source/SPMenuAdditions.h b/Source/SPTableRelationsDelegate.h index 6c1070b2..79b1e914 100644 --- a/Source/SPMenuAdditions.h +++ b/Source/SPTableRelationsDelegate.h @@ -1,9 +1,9 @@ // -// SPMenuAdditions.h +// SPTableRelationsDelegate.h // sequel-pro // -// Created by Rowan Beentje on November 27, 2010. -// Copyright (c) 2010 Rowan Beentje. All rights reserved. +// Created by Stuart Connolly (stuconnolly.com) on March 28, 2017. +// Copyright (c) 2017 Stuart Connolly. All rights reserved. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -28,9 +28,8 @@ // // More info at <https://github.com/sequelpro/sequelpro> -@interface NSMenu (SPMenuAdditions) +#import "SPTableRelations.h" -// Add a 10.5-compatible removeAllItems -- (void)compatibleRemoveAllItems; +@interface SPTableRelations (SPTableRelationsDelegate) @end diff --git a/Source/SPTableRelationsDelegate.m b/Source/SPTableRelationsDelegate.m new file mode 100644 index 00000000..bf083318 --- /dev/null +++ b/Source/SPTableRelationsDelegate.m @@ -0,0 +1,87 @@ +// +// SPTableRelationsDelegate.m +// sequel-pro +// +// Created by Stuart Connolly (stuconnolly.com) on March 28, 2017. +// Copyright (c) 2017 Stuart Connolly. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +// More info at <https://github.com/sequelpro/sequelpro> + +#import "SPTableRelationsDelegate.h" +#import "SPDatabaseDocument.h" + +@implementation SPTableRelations (SPTableRelationsDelegate) + +#pragma mark - +#pragma mark TextField delegate methods + +- (void)controlTextDidChange:(NSNotification *)notification +{ + // Make sure the user does not enter a taken name, using the quickly-generated incomplete list + if ([notification object] == constraintName) { + NSString *userValue = [[constraintName stringValue] lowercaseString]; + + // Make field red and disable add button + if ([takenConstraintNames containsObject:userValue]) { + [constraintName setTextColor:[NSColor redColor]]; + [confirmAddRelationButton setEnabled:NO]; + } + else { + [constraintName setTextColor:[NSColor controlTextColor]]; + [confirmAddRelationButton setEnabled:YES]; + } + } +} + +#pragma mark - +#pragma mark Tableview delegate methods + +/** + * Called whenever the relations table view selection changes. + */ +- (void)tableViewSelectionDidChange:(NSNotification *)notification +{ + [removeRelationButton setEnabled:([relationsTableView numberOfSelectedRows] > 0)]; +} + +/* + * Double-click action on table cells - for the time being, return + * NO to disable editing. + */ +- (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex +{ + if ([tableDocumentInstance isWorking]) return NO; + + return NO; +} + +/** + * Disable row selection while the document is working. + */ +- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)rowIndex +{ + return ![tableDocumentInstance isWorking]; +} + +@end diff --git a/Source/SPTableTriggers.m b/Source/SPTableTriggers.m index 96d2fb40..23911279 100644 --- a/Source/SPTableTriggers.m +++ b/Source/SPTableTriggers.m @@ -68,6 +68,8 @@ static SPTriggerEventTag TagForEvent(NSString *mysql); - (void)_refreshTriggerDataForcingCacheRefresh:(BOOL)clearAllCaches; - (void)_openTriggerSheet; - (void)_reopenTriggerSheet:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo; +- (void)_addPreferenceObservers; +- (void)_removePreferenceObservers; @end @@ -114,8 +116,7 @@ static SPTriggerEventTag TagForEvent(NSString *mysql); [[column dataCell] setFont:useMonospacedFont ? [NSFont fontWithName:SPDefaultMonospacedFontName size:monospacedFontSize] : [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; } - // Register as an observer for the when the UseMonospacedFonts preference changes - [prefs addObserver:self forKeyPath:SPUseMonospacedFonts options:NSKeyValueObservingOptionNew context:NULL]; + [self _addPreferenceObservers]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(triggerStatementTextDidChange:) @@ -414,10 +415,7 @@ static SPTriggerEventTag TagForEvent(NSString *mysql); NSString *database = [tableDocumentInstance database]; NSIndexSet *selectedSet = [triggersTableView selectedRowIndexes]; - NSUInteger row = [selectedSet lastIndex]; - - while (row != NSNotFound) - { + [selectedSet enumerateIndexesWithOptions:NSEnumerationReverse usingBlock:^(NSUInteger row, BOOL * _Nonnull stop) { NSString *triggerName = [[triggerData objectAtIndex:row] objectForKey:SPTriggerName]; NSString *query = [NSString stringWithFormat:@"DROP TRIGGER %@.%@", [database backtickQuotedString], [triggerName backtickQuotedString]]; @@ -431,11 +429,9 @@ static SPTriggerEventTag TagForEvent(NSString *mysql); [NSString stringWithFormat:NSLocalizedString(@"The selected trigger couldn't be deleted.\n\nMySQL said: %@", @"error deleting trigger informative message"), [connection lastErrorMessage]] ); // Abort loop - break; + *stop = YES; } - - row = [selectedSet indexLessThanIndex:row]; - } + }]; [self _refreshTriggerDataForcingCacheRefresh:YES]; } @@ -639,6 +635,27 @@ static SPTriggerEventTag TagForEvent(NSString *mysql); [self performSelector:@selector(_openTriggerSheet) withObject:nil afterDelay:0.0]; } +/** + * Add any necessary preference observers to allow live updating on changes. + */ +- (void)_addPreferenceObservers +{ + // Register as an observer for the when the UseMonospacedFonts preference changes + [prefs addObserver:self forKeyPath:SPUseMonospacedFonts options:NSKeyValueObservingOptionNew context:NULL]; + + // Register observers for when the DisplayTableViewVerticalGridlines preference changes + [prefs addObserver:self forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL]; +} + +/** + * Remove any previously added preference observers. + */ +- (void)_removePreferenceObservers +{ + [prefs removeObserver:self forKeyPath:SPUseMonospacedFonts]; + [prefs removeObserver:self forKeyPath:SPDisplayTableViewVerticalGridlines]; +} + #pragma mark - - (void)dealloc @@ -647,7 +664,8 @@ static SPTriggerEventTag TagForEvent(NSString *mysql); SPClear(editedTrigger); [[NSNotificationCenter defaultCenter] removeObserver:self]; - [prefs removeObserver:self forKeyPath:SPUseMonospacedFonts]; + + [self _removePreferenceObservers]; [super dealloc]; } diff --git a/Source/SPTablesList.h b/Source/SPTablesList.h index 433879ea..e299654c 100644 --- a/Source/SPTablesList.h +++ b/Source/SPTablesList.h @@ -38,52 +38,43 @@ @class SPTableContent; @class SPSplitView; @class SPCharsetCollationHelper; - -#ifdef SP_CODA -@class SQLSidebarViewController; -#endif +@class SPCustomQuery; +@class SPTableImport; +@class SPTableData; +@class SPTableInfo; +@class SPTableTriggers; +@class SPExtendedTableInfo; @interface SPTablesList : NSObject <NSTextFieldDelegate, NSTableViewDelegate> { - IBOutlet SPDatabaseDocument* tableDocumentInstance; - IBOutlet SPTableStructure* tableSourceInstance; - IBOutlet SPTableContent* tableContentInstance; -#ifndef SP_CODA /* ivars */ - IBOutlet id customQueryInstance; - IBOutlet id tableDumpInstance; - IBOutlet id tableDataInstance; - IBOutlet id extendedTableInfoInstance; -#endif - IBOutlet SPDatabaseData* databaseDataInstance; -#ifndef SP_CODA /* ivars */ - IBOutlet id tableInfoInstance; - IBOutlet id tableTriggersInstance; + IBOutlet SPDatabaseDocument *tableDocumentInstance; + IBOutlet SPTableStructure *tableSourceInstance; + IBOutlet SPTableContent *tableContentInstance; + IBOutlet SPDatabaseData *databaseDataInstance; IBOutlet SPHistoryController *spHistoryControllerInstance; + IBOutlet SPCustomQuery *customQueryInstance; + IBOutlet SPTableImport *tableDumpInstance; + IBOutlet SPTableData *tableDataInstance; + IBOutlet SPExtendedTableInfo *extendedTableInfoInstance; + IBOutlet SPTableInfo *tableInfoInstance; + IBOutlet SPTableTriggers *tableTriggersInstance; IBOutlet id copyTableSheet; -#endif IBOutlet SPTableView *tablesListView; -#ifndef SP_CODA /* ivars */ IBOutlet id copyTableButton; IBOutlet id copyTableNameField; IBOutlet id copyTableMessageField; IBOutlet NSButton *copyTableContentSwitch; -#endif IBOutlet id tableSheet; IBOutlet id tableNameField; IBOutlet id tableEncodingButton; IBOutlet id tableCollationButton; IBOutlet id tableTypeButton; IBOutlet id toolbarAddButton; -#ifdef SP_CODA - id toolbarDeleteButton; -#endif -#ifndef SP_CODA + IBOutlet id toolbarActionsButton; -#endif IBOutlet id toolbarReloadButton; IBOutlet id addTableButton; -#ifndef SP_CODA IBOutlet id truncateTableButton; IBOutlet SPSplitView *tableListSplitView; IBOutlet SPSplitView *tableListFilterSplitView; @@ -101,11 +92,9 @@ IBOutlet NSMenuItem *copyCreateSyntaxMenuItem; IBOutlet NSMenuItem *separatorTableMenuItem2; IBOutlet NSMenuItem *separatorTableMenuItem3; -#endif SPMySQLConnection *mySQLConnection; - -#ifndef SP_CODA /* ivars */ + // Table list context menu items IBOutlet NSMenuItem *removeTableContextMenuItem; IBOutlet NSMenuItem *duplicateTableContextMenuItem; @@ -118,7 +107,6 @@ IBOutlet NSMenuItem *copyCreateSyntaxContextMenuItem; IBOutlet NSMenuItem *separatorTableContextMenuItem2; IBOutlet NSMenuItem *separatorTableContextMenuItem3; -#endif NSMutableArray *tables; NSMutableArray *filteredTables; @@ -131,13 +119,7 @@ BOOL tableListContainsViews; BOOL alertSheetOpened; -#ifndef SP_CODA /* ivars */ NSFont *smallSystemFont; -#endif - -#ifdef SP_CODA - SQLSidebarViewController* sidebarViewController; -#endif SPCharsetCollationHelper *addTableCharsetHelper; } @@ -147,25 +129,20 @@ - (IBAction)addTable:(nullable id)sender; - (IBAction)closeSheet:(nullable id)sender; - (IBAction)removeTable:(nullable id)sender; - -#ifndef SP_CODA /* method decls */ - (IBAction)copyTable:(nullable id)sender; - (IBAction)renameTable:(nullable id)sender; - (IBAction)truncateTable:(nullable id)sender; - (IBAction)openTableInNewTab:(nullable id)sender; - (IBAction)openTableInNewWindow:(nullable id)sender; - (IBAction)togglePaneCollapse:(nullable id)sender; -#endif +- (IBAction)updateFilter:(nullable id)sender; // Additional methods - (void)setConnection:(nonnull SPMySQLConnection *)theConnection; - (void)setSelectionState:(nullable NSDictionary *)selectionDetails; - -#ifndef SP_CODA /* method decls */ - (void)selectTableAtIndex:(nullable NSNumber *)row; - (void)makeTableListFilterHaveFocus; - (void)makeTableListHaveFocus; -#endif // Getters - (nonnull NSArray *)selectedTableNames; @@ -184,18 +161,20 @@ - (nonnull NSArray *)allDatabaseNames; - (nonnull NSArray *)allSystemDatabaseNames; - (nullable NSString *)selectedDatabase; +- (BOOL)hasViews; +- (BOOL)hasFunctions; +- (BOOL)hasProcedures; +- (BOOL)hasEvents; +- (BOOL)hasNonTableObjects; // Setters - (BOOL)selectItemWithName:(nullable NSString *)theName; -#ifndef SP_CODA /* method decls */ - (BOOL)selectItemsWithNames:(nonnull NSArray *)theNames; // Table list filter interaction - (void)showFilter; - (void)hideFilter; - (void)clearFilter; -#endif -- (IBAction) updateFilter:(nullable id)sender; // Task interaction - (void)startDocumentTaskForTab:(nullable NSNotification *)aNotification; @@ -203,28 +182,6 @@ - (void)setTableListSelectability:(BOOL)isSelectable; - (BOOL)isTableNameValid:(nullable NSString *)tableName forType:(SPTableType)tableType; - (BOOL)isTableNameValid:(nullable NSString *)tableName forType:(SPTableType)tableType ignoringSelectedTable:(BOOL)ignoreSelectedTable; - -#ifdef SP_CODA /* method decls */ -@property (assign) SPTableStructure* tableSourceInstance; -@property (assign) SPTableContent* tableContentInstance; -@property (assign) id toolbarAddButton; -@property (assign) id toolbarDeleteButton; -@property (assign) id toolbarReloadButton; -@property (assign) id tableSheet; -@property (assign) id tableNameField; -@property (assign) id tableEncodingButton; -@property (assign) id tableTypeButton; -@property (assign) id databaseDataInstance; -@property (assign) id addTableButton; -@property (assign) SPTableView* tablesListView; -@property (assign) SQLSidebarViewController* sidebarViewController; - -- (BOOL)selectionShouldChangeInTableView:(NSTableView *)aTableView; -- (void)setDatabaseDocument:(SPDatabaseDocument*)val; -- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex; - -#endif - - (BOOL)selectionShouldChangeInTableView:(nullable NSTableView *)aTableView; @end diff --git a/Source/SPTablesList.m b/Source/SPTablesList.m index 3cc8ae3a..2fa26229 100644 --- a/Source/SPTablesList.m +++ b/Source/SPTablesList.m @@ -34,39 +34,24 @@ #import "SPTableStructure.h" #import "SPDatabaseStructure.h" #import "SPDatabaseViewController.h" - -#ifndef SP_CODA /* headers */ #import "SPTableContent.h" -#endif #import "SPTableData.h" -#ifndef SP_CODA /* headers */ #import "SPTableInfo.h" #import "SPDataImport.h" #import "SPTableView.h" #import "ImageAndTextCell.h" #import "RegexKitLite.h" -#endif #import "SPDatabaseData.h" #import "SPAlertSheets.h" -#ifndef SP_CODA /* headers */ #import "SPNavigatorController.h" #import "SPHistoryController.h" -#endif #import "SPServerSupport.h" -#ifndef SP_CODA /* headers */ #import "SPWindowController.h" #import "SPAppController.h" #import "SPSplitView.h" -#endif #import "SPThreadAdditions.h" #import "SPFunctions.h" - -#ifdef SP_CODA -#import "SQLSidebarViewController.h" -#endif - #import "SPCharsetCollationHelper.h" - #import "SPWindowManagement.h" #import <SPMySQL/SPMySQL.h> @@ -75,50 +60,31 @@ static NSString *SPAddRow = @"SPAddRow"; static NSString *SPAddNewTable = @"SPAddNewTable"; static NSString *SPRemoveTable = @"SPRemoveTable"; -#ifndef SP_CODA static NSString *SPTruncateTable = @"SPTruncateTable"; static NSString *SPDuplicateTable = @"SPDuplicateTable"; -#endif @interface SPTablesList () -#ifndef SP_CODA -- (void)_removeTable:(NSNumber *)force; +- (void)_removeTable:(BOOL)force; - (void)_truncateTable; -#endif - (void)_addTable; -#ifndef SP_CODA - (void)_copyTable; -#endif - (void)_renameTableOfType:(SPTableType)tableType from:(NSString *)oldTableName to:(NSString *)newTableName; - (void)_duplicateConnectionToFrontTab; - (NSMutableArray *)_allSchemaObjectsOfType:(SPTableType)type; +- (BOOL)_databaseHasObjectOfType:(SPTableType)type; + @end @implementation SPTablesList -#ifdef SP_CODA -@synthesize sidebarViewController; -@synthesize databaseDataInstance; -@synthesize toolbarAddButton; -@synthesize toolbarDeleteButton; -@synthesize toolbarReloadButton; -@synthesize tableSourceInstance; -@synthesize tableContentInstance; -@synthesize tableSheet; -@synthesize tableNameField; -@synthesize tableEncodingButton; -@synthesize tableTypeButton; -@synthesize addTableButton; -@synthesize tablesListView; -#endif - #pragma mark - #pragma mark Initialisation - (id)init { if ((self = [super init])) { + tables = [[NSMutableArray alloc] init]; filteredTables = tables; tableTypes = [[NSMutableArray alloc] init]; @@ -128,11 +94,11 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; tableListContainsViews = NO; selectedTableType = SPTableTypeNone; selectedTableName = nil; -#ifndef SP_CODA + [tables addObject:NSLocalizedString(@"TABLES", @"header for table list")]; smallSystemFont = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]; -#endif + addTableCharsetHelper = nil; //initialized in awakeFromNib } @@ -141,8 +107,6 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; - (void)awakeFromNib { -#ifndef SP_CODA - // Configure the table information pane [tableListSplitView setCollapsibleSubviewIndex:1]; @@ -157,22 +121,20 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; // Disable tab edit behaviour in the tables list [tablesListView setTabEditingDisabled:YES]; -#endif // Add observers for document task activity [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(startDocumentTaskForTab:) name:SPDocumentTaskStartNotification object:tableDocumentInstance]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(endDocumentTaskForTab:) name:SPDocumentTaskEndNotification object:tableDocumentInstance]; -#ifndef SP_CODA [tablesListView registerForDraggedTypes:@[SPNavigatorTableDataPasteboardDragType]]; -#endif - + //create the charset helper addTableCharsetHelper = [[SPCharsetCollationHelper alloc] initWithCharsetButton:tableEncodingButton CollationButton:tableCollationButton]; } @@ -768,9 +730,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; } else if ([contextInfo isEqualToString:SPRemoveTable]) { if (returnCode == NSAlertDefaultReturn) { - [self performSelector:@selector(_removeTable:) - withObject:[NSNumber numberWithInteger:[[(NSAlert *)sheet suppressionButton] state]] - afterDelay:0.0]; + [self _removeTable:([[(NSAlert *)sheet suppressionButton] state] == NSOnState)]; } } #ifndef SP_CODA @@ -1212,14 +1172,13 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; { NSIndexSet *indexes = [tablesListView selectedRowIndexes]; - NSUInteger currentIndex = [indexes firstIndex]; - NSMutableArray *selTables = [NSMutableArray array]; + NSMutableArray *selTables = [NSMutableArray arrayWithCapacity:[indexes count]]; - while (currentIndex != NSNotFound) { + [indexes enumerateIndexesUsingBlock:^(NSUInteger currentIndex, BOOL * _Nonnull stop) { if([[filteredTableTypes objectAtIndex:currentIndex] integerValue] == SPTableTypeTable) [selTables addObject:[filteredTables objectAtIndex:currentIndex]]; - currentIndex = [indexes indexGreaterThanIndex:currentIndex]; - } + }]; + return selTables; } @@ -1227,13 +1186,12 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; { NSIndexSet *indexes = [tablesListView selectedRowIndexes]; - NSUInteger currentIndex = [indexes firstIndex]; - NSMutableArray *selTables = [NSMutableArray array]; + NSMutableArray *selTables = [NSMutableArray arrayWithCapacity:[indexes count]]; - while (currentIndex != NSNotFound) { + [indexes enumerateIndexesUsingBlock:^(NSUInteger currentIndex, BOOL * _Nonnull stop) { [selTables addObject:[filteredTables objectAtIndex:currentIndex]]; - currentIndex = [indexes indexGreaterThanIndex:currentIndex]; - } + }]; + return selTables; } @@ -1241,13 +1199,12 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; { NSIndexSet *indexes = [tablesListView selectedRowIndexes]; - NSUInteger currentIndex = [indexes firstIndex]; - NSMutableArray *selTables = [NSMutableArray array]; + NSMutableArray *selTables = [NSMutableArray arrayWithCapacity:[indexes count]]; - while (currentIndex != NSNotFound) { + [indexes enumerateIndexesUsingBlock:^(NSUInteger currentIndex, BOOL * _Nonnull stop) { [selTables addObject:[filteredTableTypes objectAtIndex:currentIndex]]; - currentIndex = [indexes indexGreaterThanIndex:currentIndex]; - } + }]; + return selTables; } @@ -1276,57 +1233,66 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; } /** - * Database tables accessors for a given table type + * Database tables accessors for a given table type. */ - (NSArray *)allTableAndViewNames { NSMutableArray *returnArray = [NSMutableArray array]; - NSUInteger i; - NSUInteger cnt = [[self tables] count]; - for(i=0; i<cnt; i++) { - SPTableType tt = (SPTableType)[NSArrayObjectAtIndex([self tableTypes],i) integerValue]; - if(tt == SPTableTypeTable || tt == SPTableTypeView) + + for (NSUInteger i = 0; i < [[self tables] count]; i++) + { + SPTableType tt = (SPTableType)[NSArrayObjectAtIndex([self tableTypes], i) integerValue]; + + if (tt == SPTableTypeTable || tt == SPTableTypeView) { [returnArray addObject:NSArrayObjectAtIndex([self tables], i)]; + } } + return returnArray; } +/** + * Returns an array of all table names. + */ - (NSArray *)allTableNames { return [self _allSchemaObjectsOfType:SPTableTypeTable]; } +/** + * Returns an array of view names. + */ - (NSArray *)allViewNames { NSMutableArray *returnArray = [self _allSchemaObjectsOfType:SPTableTypeView]; + [returnArray sortUsingSelector:@selector(compare:)]; + return returnArray; } +/** + * Returns an array of all procedure names. + */ - (NSArray *)allProcedureNames { return [self _allSchemaObjectsOfType:SPTableTypeProc]; } + +/** + * Returns an array of all function names. + */ - (NSArray *)allFunctionNames { return [self _allSchemaObjectsOfType:SPTableTypeFunc]; } +/** + * Returns an array of event names. + */ - (NSArray *)allEventNames { - return [self _allSchemaObjectsOfType:SPTableTypeEvent]; -} - -- (NSMutableArray *)_allSchemaObjectsOfType:(SPTableType)type -{ - NSMutableArray *returnArray = [NSMutableArray array]; - NSInteger i; - NSInteger cnt = [[self tables] count]; - for(i=0; i<cnt; i++) { - if([NSArrayObjectAtIndex([self tableTypes],i) integerValue] == type) - [returnArray addObject:NSArrayObjectAtIndex([self tables], i)]; - } - return returnArray; + return [self _allSchemaObjectsOfType:SPTableTypeEvent]; } /** @@ -1358,6 +1324,46 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; return tableTypes; } +/** + * Returns whether or not the current database contains any views. + */ +- (BOOL)hasViews +{ + return [self _databaseHasObjectOfType:SPTableTypeView]; +} + +/** + * Returns whether or not the current database contains any functions. + */ +- (BOOL)hasFunctions +{ + return [self _databaseHasObjectOfType:SPTableTypeFunc]; +} + +/** + * Returns whether or not the current database has any procedures. + */ +- (BOOL)hasProcedures +{ + return [self _databaseHasObjectOfType:SPTableTypeProc]; +} + +/** + * Returns whether or not the current database has any events. + */ +- (BOOL)hasEvents +{ + return [self _databaseHasObjectOfType:SPTableTypeEvent]; +} + +/** + * Returns whether or not the current database has any non-table objects. + */ +- (BOOL)hasNonTableObjects +{ + return [self hasViews] || [self hasProcedures] || [self hasFunctions] || [self hasEvents]; +} + #pragma mark - #pragma mark Setter methods @@ -2168,7 +2174,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; - (void)setDatabaseDocument:(SPDatabaseDocument*)val { tableDocumentInstance = val; - } +} #endif #pragma mark - @@ -2177,7 +2183,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; /** * Removes the selected object (table, view, procedure, function, etc.) from the database and tableView. */ -- (void)_removeTable:(NSNumber *)force +- (void)_removeTable:(BOOL)force { NSIndexSet *indexes = [tablesListView selectedRowIndexes]; @@ -2186,7 +2192,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; // Get last index NSUInteger currentIndex = [indexes lastIndex]; - if ([force boolValue]) { + if (force) { [mySQLConnection queryString:@"SET FOREIGN_KEY_CHECKS = 0"]; } @@ -2266,7 +2272,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; } } - if ([force boolValue]) { + if (force) { [mySQLConnection queryString:@"SET FOREIGN_KEY_CHECKS = 1"]; } @@ -2304,33 +2310,23 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; { NSIndexSet *indexes = [tablesListView selectedRowIndexes]; - // Get last index - NSUInteger currentIndex = [indexes lastIndex]; - - while (currentIndex != NSNotFound) - { + [indexes enumerateIndexesWithOptions:NSEnumerationReverse usingBlock:^(NSUInteger currentIndex, BOOL * _Nonnull stop) { [mySQLConnection queryString:[NSString stringWithFormat: @"TRUNCATE TABLE %@", [[filteredTables objectAtIndex:currentIndex] backtickQuotedString]]]; // Couldn't truncate table if ([mySQLConnection queryErrored]) { - NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Error truncating table", @"error truncating table message") - defaultButton:NSLocalizedString(@"OK", @"OK button") - alternateButton:nil - otherButton:nil - informativeTextWithFormat:NSLocalizedString(@"An error occurred while trying to truncate the table '%@'.\n\nMySQL said: %@", @"error truncating table informative message"), - [filteredTables objectAtIndex:currentIndex], [mySQLConnection lastErrorMessage]]; - - [alert setAlertStyle:NSCriticalAlertStyle]; + SPOnewayAlertSheetWithStyle( + NSLocalizedString(@"Error truncating table", @"error truncating table message"), + nil, + [tableDocumentInstance parentWindow], + [NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to truncate the table '%@'.\n\nMySQL said: %@", @"error truncating table informative message"), [filteredTables objectAtIndex:currentIndex], [mySQLConnection lastErrorMessage]], + NSCriticalAlertStyle + ); - [alert beginSheetModalForWindow:[tableDocumentInstance parentWindow] - modalDelegate:self - didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) - contextInfo:@"truncateTableError"]; + *stop = YES; } - // Get next index (beginning from the end) - currentIndex = [indexes indexLessThanIndex:currentIndex]; - } + }]; // Ensure the the table's content view is updated to show that it has been truncated [tableDocumentInstance setContentRequiresReload:YES]; @@ -2753,6 +2749,35 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; [NSException raise:@"Object of unknown type" format:NSLocalizedString(@"An error occured while renaming. '%@' is of an unknown type.", @"rename error - don't know what type the renamed thing is"), oldTableName]; } +- (NSMutableArray *)_allSchemaObjectsOfType:(SPTableType)type +{ + NSMutableArray *returnArray = [NSMutableArray array]; + + for (NSUInteger i = 0; i < [[self tables] count]; i++) + { + if ([NSArrayObjectAtIndex([self tableTypes], i) integerValue] == type) { + [returnArray addObject:NSArrayObjectAtIndex([self tables], i)]; + } + } + + return returnArray; +} + +- (BOOL)_databaseHasObjectOfType:(SPTableType)type +{ + BOOL hasObjectOfType = NO; + + for (NSUInteger i = 0; i < [[self tables] count]; i++) + { + if ([NSArrayObjectAtIndex([self tableTypes], i) integerValue] == type) { + hasObjectOfType = YES; + break; + } + } + + return hasObjectOfType; +} + #pragma mark - - (void)dealloc @@ -2761,12 +2786,10 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; SPClear(tables); SPClear(tableTypes); -#ifndef SP_CODA + if (isTableListFiltered && filteredTables) SPClear(filteredTables); if (isTableListFiltered && filteredTableTypes) SPClear(filteredTableTypes); -#endif if (selectedTableName) SPClear(selectedTableName); - if (addTableCharsetHelper) SPClear(addTableCharsetHelper); [super dealloc]; diff --git a/Source/SPTooltip.m b/Source/SPTooltip.m index 54a997f6..ff68fdbe 100644 --- a/Source/SPTooltip.m +++ b/Source/SPTooltip.m @@ -83,12 +83,6 @@ static CGFloat slow_in_out (CGFloat t) @end -@interface WebView (LeopardOnly) - -- (void)setDrawsBackground:(BOOL)drawsBackground; - -@end - @implementation SPTooltip // ================== diff --git a/Source/SPUserManager.h b/Source/SPUserManager.h index 5ce1e6bc..ffee376d 100644 --- a/Source/SPUserManager.h +++ b/Source/SPUserManager.h @@ -81,7 +81,7 @@ BOOL isInitializing; NSMutableString *errorsString; - // MySQL 5.7.6 removes the "Password" columns and only uses the "plugin"+"authentication_string" columns + // MySQL 5.7.6 removes the "Password" columns and only uses the "plugin" + "authentication_string" columns BOOL requiresPost576PasswordHandling; } @@ -114,14 +114,14 @@ - (IBAction)closeErrorsSheet:(id)sender; - (IBAction)doubleClickSchemaPriv:(id)sender; -// Schema Privieges +// Schema privieges - (IBAction)addSchemaPriv:(id)sender; - (IBAction)removeSchemaPriv:(id)sender; // Refresh - (IBAction)refresh:(id)sender; -// Core Data notifications +// Core data notifications - (BOOL)insertUser:(SPUserMO *)user; - (BOOL)deleteUser:(SPUserMO *)user; - (BOOL)updateUser:(SPUserMO *)user; diff --git a/Source/SPUserManager.m b/Source/SPUserManager.m index 8280242f..c06025d2 100644 --- a/Source/SPUserManager.m +++ b/Source/SPUserManager.m @@ -221,20 +221,24 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn"; */ - (void)_initializeTree:(NSArray *)items { - // Retrieve all the user data in order to be able to initialise the schema privs for each child, // copying into a dictionary keyed by user, each with all the host rows. NSMutableDictionary *schemaPrivilegeData = [NSMutableDictionary dictionary]; SPMySQLResult *queryResults = [connection queryString:@"SELECT * FROM mysql.db"]; + [queryResults setReturnDataAsStrings:YES]; - for (NSDictionary *privRow in queryResults) { + + for (NSDictionary *privRow in queryResults) + { if (![schemaPrivilegeData objectForKey:[privRow objectForKey:@"User"]]) { [schemaPrivilegeData setObject:[NSMutableArray array] forKey:[privRow objectForKey:@"User"]]; } + [[schemaPrivilegeData objectForKey:[privRow objectForKey:@"User"]] addObject:privRow]; // If "all database" values were found, add them to the schemas list if not already present NSString *schemaName = [privRow objectForKey:@"Db"]; + if ([schemaName isEqualToString:@""] || [schemaName isEqualToString:@"%"]) { if (![schemas containsObject:schemaName]) { [schemas addObject:schemaName]; @@ -269,11 +273,20 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn"; // original values for comparison purposes [parent setPrimitiveValue:username forKey:@"user"]; [parent setPrimitiveValue:username forKey:@"originaluser"]; - if(requiresPost576PasswordHandling) { + + if (requiresPost576PasswordHandling) { [parent setPrimitiveValue:[item objectForKey:@"plugin"] forKey:@"plugin"]; - NSString *pwHash = [item objectForKey:@"authentication_string"]; - [parent setPrimitiveValue:pwHash forKey:@"authentication_string"]; - if([pwHash length]) [parent setPrimitiveValue:@"sequelpro_dummy_password" forKey:@"password"]; // for the UI dialog + + NSString *passwordHash = [item objectForKey:@"authentication_string"]; + + if (![passwordHash isNSNull]) { + [parent setPrimitiveValue:passwordHash forKey:@"authentication_string"]; + + // for the UI dialog + if ([passwordHash length]) { + [parent setPrimitiveValue:@"sequelpro_dummy_password" forKey:@"password"]; + } + } } else { [parent setPrimitiveValue:[item objectForKey:@"Password"] forKey:@"password"]; @@ -535,7 +548,6 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn"; */ - (IBAction)doApply:(id)sender { - // If editing can't be committed, cancel the apply if (![treeController commitEditing]) { return; @@ -953,6 +965,9 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn"; if (!isInitializing) [outlineView reloadData]; } +#pragma mark - +#pragma mark Core data notifications + - (BOOL)updateUser:(SPUserMO *)user { if (![user parent]) { @@ -1290,6 +1305,9 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn"; return YES; } +#pragma mark - +#pragma mark Private API + /** * Gets any NSManagedObject (SPUser) from the managedObjectContext that may * already exist with the given username. @@ -1446,9 +1464,6 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn"; return YES; } -#pragma mark - -#pragma mark Private API - /** * Renames a user account using the supplied parameters. * @@ -1511,7 +1526,6 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn"; { [[NSNotificationCenter defaultCenter] removeObserver:self]; - SPClear(managedObjectContext); SPClear(persistentStoreCoordinator); SPClear(managedObjectModel); diff --git a/Source/SPWindow.m b/Source/SPWindow.m index cda7eb63..18c4fae3 100644 --- a/Source/SPWindow.m +++ b/Source/SPWindow.m @@ -31,15 +31,21 @@ #import "SPWindow.h" #import "SPWindowController.h" -@interface NSWindow (LionPlusMethods) -- (void)toggleFullScreen:(id)sender; -@end - @implementation SPWindow @synthesize isSheetWhichCanBecomeMain; #pragma mark - + ++ (void)initialize +{ + // Disable automatic window tabbing on 10.12+ + if ([NSWindow respondsToSelector:@selector(setAllowsAutomaticWindowTabbing:)]) { + [NSWindow setAllowsAutomaticWindowTabbing:NO]; + } +} + +#pragma mark - #pragma mark Keyboard shortcut additions /** @@ -140,7 +146,9 @@ { if ([[self windowController] respondsToSelector:@selector(selectedTableDocument)]) { return [[[self windowController] selectedTableDocument] undoManager]; + } + return [super undoManager]; } @@ -153,7 +161,6 @@ */ - (BOOL)canBecomeMainWindow { - // If this window is a sheet which is permitted to become main, respond appropriately if ([self isSheet] && isSheetWhichCanBecomeMain) { return [self isVisible]; @@ -190,7 +197,6 @@ - (BOOL)validateMenuItem:(NSMenuItem *)menuItem { - // If the item is the Show/Hide Toolbar menu item, override the text to allow correct translation if ([menuItem action] == @selector(toggleToolbarShown:)) { BOOL theResponse = [super validateMenuItem:menuItem]; diff --git a/Source/SPWindowController.m b/Source/SPWindowController.m index cddf6b09..7f3c687b 100644 --- a/Source/SPWindowController.m +++ b/Source/SPWindowController.m @@ -39,15 +39,6 @@ #import <PSMTabBar/PSMTabBarControl.h> #import <PSMTabBar/PSMTabStyle.h> -// Forward-declare for 10.7 compatibility -#if !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 -enum { - NSWindowCollectionBehaviorFullScreenPrimary = 1 << 7, - NSWindowCollectionBehaviorFullScreenAuxiliary = 1 << 8, - NSFullScreenWindowMask = 1 << 14 -}; -#endif - @interface SPWindowController () - (void)_setUpTabBar; diff --git a/Source/Sequel-Pro.pch b/Source/Sequel-Pro.pch index f3b2fd16..dc6bbf9b 100644 --- a/Source/Sequel-Pro.pch +++ b/Source/Sequel-Pro.pch @@ -32,7 +32,9 @@ // Nearly every class uses constants #import "SPConstants.h" - + + #import "SPCompatibility.h" + // Make all our custom additions available #import "SPCategoryAdditions.h" #endif @@ -11,8 +11,8 @@ Build Instructions ================== * Install the [latest version of Xcode](https://itunes.apple.com/au/app/xcode/id497799835) - * Install [Github for Mac](https://desktop.github.com/) (or [Tower](https://www.git-tower.com/), or [SourceTree](https://www.sourcetreeapp.com/), or […](http://git-scm.com/downloads/guis)) - * Click "Clone in Desktop" on the right sidebar of our [github page](https://github.com/sequelpro/sequelpro) + * Install [GitHub for Mac](https://desktop.github.com/) (or [Tower](https://www.git-tower.com/), or [SourceTree](https://www.sourcetreeapp.com/), or […](http://git-scm.com/downloads/guis)) + * Click "Clone in Desktop" on the right sidebar of our [GitHub page](https://github.com/sequelpro/sequelpro) * Open `sequel-pro.xcodeproj` * Click the `Run` button in the toolbar * If the above doesn't work, please file a [bug report](https://github.com/sequelpro/sequelpro/issues/new) diff --git a/sequel-pro.xcodeproj/project.pbxproj b/sequel-pro.xcodeproj/project.pbxproj index b84b20e4..4866e18f 100644 --- a/sequel-pro.xcodeproj/project.pbxproj +++ b/sequel-pro.xcodeproj/project.pbxproj @@ -28,6 +28,7 @@ 11B55BFE1189E3B2009EF465 /* SPDatabaseAction.m in Sources */ = {isa = PBXBuildFile; fileRef = 11B55BFD1189E3B2009EF465 /* SPDatabaseAction.m */; }; 11C211301180EC9A00758039 /* SPDatabaseRename.m in Sources */ = {isa = PBXBuildFile; fileRef = 11C2109D1180E70800758039 /* SPDatabaseRename.m */; }; 17005CB316D6CF0000AF81F4 /* SPTableTriggersDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 17005CB216D6CF0000AF81F4 /* SPTableTriggersDelegate.m */; }; + 171156551E8B0F96002E6363 /* SPTableRelationsDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 171156541E8B0F96002E6363 /* SPTableRelationsDelegate.m */; }; 171312CE109D23C700FB465F /* SPTableTextFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 171312CD109D23C700FB465F /* SPTableTextFieldCell.m */; }; 1713C740140D8AEF00CFD461 /* SPQueryDocumentsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1713C73F140D8AEF00CFD461 /* SPQueryDocumentsController.m */; }; 1713C75F140D8D5900CFD461 /* SPQueryConsoleDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 1713C75E140D8D5900CFD461 /* SPQueryConsoleDataSource.m */; }; @@ -64,7 +65,6 @@ 174CE11E10AB80B5008F892B /* DatabaseProcessList.xib in Resources */ = {isa = PBXBuildFile; fileRef = 174CE11C10AB80B5008F892B /* DatabaseProcessList.xib */; }; 174CE14210AB9281008F892B /* SPProcessListController.m in Sources */ = {isa = PBXBuildFile; fileRef = 174CE14110AB9281008F892B /* SPProcessListController.m */; }; 175EC63512733B36009A7C0F /* SPExportControllerDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 175EC63412733B36009A7C0F /* SPExportControllerDelegate.m */; }; - 1760599F1336199D0098E162 /* SPMenuAdditionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1760599E1336199D0098E162 /* SPMenuAdditionsTests.m */; }; 1761FD480EF03A6F00331368 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1761FD460EF03A6F00331368 /* MainMenu.xib */; }; 176E14D115570FE300FAF326 /* SPBundleCommandRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = 176E14D015570FE300FAF326 /* SPBundleCommandRunner.m */; }; 177E792E0FCB54EC00E9E122 /* database-small.png in Resources */ = {isa = PBXBuildFile; fileRef = 177E792B0FCB54EC00E9E122 /* database-small.png */; }; @@ -99,8 +99,21 @@ 17A20AC6124F9B110095CEFB /* SPServerSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 17A20AC5124F9B110095CEFB /* SPServerSupport.m */; }; 17A7773411C52D8E001E27B4 /* SPIndexesController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17A7773311C52D8E001E27B4 /* SPIndexesController.m */; }; 17A7773811C52E61001E27B4 /* IndexesView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17A7773611C52E61001E27B4 /* IndexesView.xib */; }; + 17AD35F51E79888D000F213E /* button_clear@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 17AD35F41E79888D000F213E /* button_clear@2x.png */; }; 17AED4161888BD67008E380F /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5EAC0FC0EC87FF900CC579C /* Security.framework */; }; 17AF787B11FC41C00073D043 /* SPExportFilenameUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 17AF787A11FC41C00073D043 /* SPExportFilenameUtilities.m */; }; + 17B548631E81FFA600175D5A /* SPCreateDatabaseInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 17B548621E81FFA600175D5A /* SPCreateDatabaseInfo.m */; }; + 17B548711E82B02100175D5A /* button_bar_handle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 17B548661E82B02100175D5A /* button_bar_handle@2x.png */; }; + 17B548721E82B02100175D5A /* button_duplicate@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 17B548671E82B02100175D5A /* button_duplicate@2x.png */; }; + 17B548731E82B02100175D5A /* button_edit_mode_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 17B548681E82B02100175D5A /* button_edit_mode_selected@2x.png */; }; + 17B548741E82B02100175D5A /* button_edit_mode@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 17B548691E82B02100175D5A /* button_edit_mode@2x.png */; }; + 17B548751E82B02100175D5A /* button_edit@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 17B5486A1E82B02100175D5A /* button_edit@2x.png */; }; + 17B548761E82B02100175D5A /* button_left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 17B5486B1E82B02100175D5A /* button_left@2x.png */; }; + 17B548771E82B02100175D5A /* button_pagination@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 17B5486C1E82B02100175D5A /* button_pagination@2x.png */; }; + 17B548781E82B02100175D5A /* button_remove@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 17B5486D1E82B02100175D5A /* button_remove@2x.png */; }; + 17B548791E82B02100175D5A /* button_right@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 17B5486E1E82B02100175D5A /* button_right@2x.png */; }; + 17B5487A1E82B02100175D5A /* button_select_all@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 17B5486F1E82B02100175D5A /* button_select_all@2x.png */; }; + 17B5487B1E82B02100175D5A /* button_select_none@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 17B548701E82B02100175D5A /* button_select_none@2x.png */; }; 17BA2A3215275D8600389803 /* SPExportInterfaceController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17BA2A3115275D8600389803 /* SPExportInterfaceController.m */; }; 17C058880FC9FC390077E9CF /* SPNarrowDownCompletion.m in Sources */ = {isa = PBXBuildFile; fileRef = 17C058870FC9FC390077E9CF /* SPNarrowDownCompletion.m */; }; 17CC97F310B4ABE90034CD7A /* SPAboutController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17CC97F210B4ABE90034CD7A /* SPAboutController.m */; }; @@ -119,7 +132,6 @@ 17D3DC201281816E002A163A /* SPDatabaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17D3DC1F1281816E002A163A /* SPDatabaseViewController.m */; }; 17D5B49E1553059F00EF3BB3 /* SPViewCopy.m in Sources */ = {isa = PBXBuildFile; fileRef = 17D5B49D1553059F00EF3BB3 /* SPViewCopy.m */; }; 17DB5F441555CA300046834B /* SPMutableArrayAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1798F19715501838004B0AB8 /* SPMutableArrayAdditions.m */; }; - 17DB5F4A1555CA810046834B /* SPMenuAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 58DC10D212A1B8DF00B76DA5 /* SPMenuAdditions.m */; }; 17DD52B7115071D0007D8950 /* SPPrintTemplate.html in Resources */ = {isa = PBXBuildFile; fileRef = 17DD52B6115071D0007D8950 /* SPPrintTemplate.html */; }; 17DD52C3115074B3007D8950 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 17DD52C1115074B3007D8950 /* InfoPlist.strings */; }; 17DD52C6115074CB007D8950 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 17DD52C4115074CB007D8950 /* Localizable.strings */; }; @@ -345,9 +357,6 @@ 58B9074A11BD9B34000826E5 /* overflowImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 58B9070A11BD9B34000826E5 /* overflowImage.png */; }; 58B9074B11BD9B34000826E5 /* overflowImagePressed.png in Resources */ = {isa = PBXBuildFile; fileRef = 58B9070B11BD9B34000826E5 /* overflowImagePressed.png */; }; 58B9074C11BD9B34000826E5 /* pi.png in Resources */ = {isa = PBXBuildFile; fileRef = 58B9070C11BD9B34000826E5 /* pi.png */; }; - 58B9075311BD9B34000826E5 /* TabNewMetal.png in Resources */ = {isa = PBXBuildFile; fileRef = 58B9071311BD9B34000826E5 /* TabNewMetal.png */; }; - 58B9075411BD9B34000826E5 /* TabNewMetalPressed.png in Resources */ = {isa = PBXBuildFile; fileRef = 58B9071411BD9B34000826E5 /* TabNewMetalPressed.png */; }; - 58B9075511BD9B34000826E5 /* TabNewMetalRollover.png in Resources */ = {isa = PBXBuildFile; fileRef = 58B9071511BD9B34000826E5 /* TabNewMetalRollover.png */; }; 58B9075611BD9B34000826E5 /* NSBezierPath_AMShading.h in Headers */ = {isa = PBXBuildFile; fileRef = 58B9071611BD9B34000826E5 /* NSBezierPath_AMShading.h */; }; 58B9075711BD9B34000826E5 /* NSBezierPath_AMShading.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B9071711BD9B34000826E5 /* NSBezierPath_AMShading.m */; }; 58B9075811BD9B34000826E5 /* NSString_AITruncation.h in Headers */ = {isa = PBXBuildFile; fileRef = 58B9071811BD9B34000826E5 /* NSString_AITruncation.h */; }; @@ -404,7 +413,6 @@ 58DA8863103E15B5000B98DF /* SPLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 58DA8862103E15B5000B98DF /* SPLogger.m */; }; 58DC0D5F1293293400B76DA5 /* ShortcutRecorder.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 58DC0D5E1293293400B76DA5 /* ShortcutRecorder.framework */; }; 58DC0D7C12932AB200B76DA5 /* ShortcutRecorder.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 58DC0D5E1293293400B76DA5 /* ShortcutRecorder.framework */; }; - 58DC10D312A1B8DF00B76DA5 /* SPMenuAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 58DC10D212A1B8DF00B76DA5 /* SPMenuAdditions.m */; }; 58DF9F3315AB26C2003B4330 /* SPDateAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 58DF9F3215AB26C2003B4330 /* SPDateAdditions.m */; }; 58DF9F7315AB8509003B4330 /* SPSplitView.m in Sources */ = {isa = PBXBuildFile; fileRef = 58DF9F7215AB8509003B4330 /* SPSplitView.m */; }; 58DFC91615CB3501003B4330 /* BGHUDButtonCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 58DFC91515CB3501003B4330 /* BGHUDButtonCell.m */; }; @@ -663,6 +671,8 @@ 11D44DEF118F5887002AA43C /* OCMock.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OCMock.framework; path = Frameworks/OCMock.framework; sourceTree = "<group>"; }; 17005CB116D6CF0000AF81F4 /* SPTableTriggersDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPTableTriggersDelegate.h; sourceTree = "<group>"; }; 17005CB216D6CF0000AF81F4 /* SPTableTriggersDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPTableTriggersDelegate.m; sourceTree = "<group>"; }; + 171156531E8B0F96002E6363 /* SPTableRelationsDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPTableRelationsDelegate.h; sourceTree = "<group>"; }; + 171156541E8B0F96002E6363 /* SPTableRelationsDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPTableRelationsDelegate.m; sourceTree = "<group>"; }; 1713122F109C7DF600FB465F /* build.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = build.sh; sourceTree = "<group>"; }; 171312CC109D23C700FB465F /* SPTableTextFieldCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPTableTextFieldCell.h; sourceTree = "<group>"; }; 171312CD109D23C700FB465F /* SPTableTextFieldCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPTableTextFieldCell.m; sourceTree = "<group>"; }; @@ -734,7 +744,6 @@ 175EC63312733B36009A7C0F /* SPExportControllerDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPExportControllerDelegate.h; sourceTree = "<group>"; }; 175EC63412733B36009A7C0F /* SPExportControllerDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPExportControllerDelegate.m; sourceTree = "<group>"; }; 175EC64C12733CDF009A7C0F /* SPCategoryAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPCategoryAdditions.h; sourceTree = "<group>"; }; - 1760599E1336199D0098E162 /* SPMenuAdditionsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPMenuAdditionsTests.m; sourceTree = "<group>"; }; 1761FD470EF03A6F00331368 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = "<group>"; }; 1761FD9D0EF0488900331368 /* build-version.pl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; path = "build-version.pl"; sourceTree = "<group>"; }; 176E14CF15570FE300FAF326 /* SPBundleCommandRunner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPBundleCommandRunner.h; sourceTree = "<group>"; }; @@ -802,8 +811,22 @@ 17A7773211C52D8E001E27B4 /* SPIndexesController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPIndexesController.h; sourceTree = "<group>"; }; 17A7773311C52D8E001E27B4 /* SPIndexesController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPIndexesController.m; sourceTree = "<group>"; }; 17A7773711C52E61001E27B4 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Interfaces/English.lproj/IndexesView.xib; sourceTree = "<group>"; }; + 17AD35F41E79888D000F213E /* button_clear@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_clear@2x.png"; sourceTree = "<group>"; }; 17AF787911FC41C00073D043 /* SPExportFilenameUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPExportFilenameUtilities.h; sourceTree = "<group>"; }; 17AF787A11FC41C00073D043 /* SPExportFilenameUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPExportFilenameUtilities.m; sourceTree = "<group>"; }; + 17B548611E81FFA600175D5A /* SPCreateDatabaseInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPCreateDatabaseInfo.h; sourceTree = "<group>"; }; + 17B548621E81FFA600175D5A /* SPCreateDatabaseInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPCreateDatabaseInfo.m; sourceTree = "<group>"; }; + 17B548661E82B02100175D5A /* button_bar_handle@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_bar_handle@2x.png"; sourceTree = "<group>"; }; + 17B548671E82B02100175D5A /* button_duplicate@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_duplicate@2x.png"; sourceTree = "<group>"; }; + 17B548681E82B02100175D5A /* button_edit_mode_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_edit_mode_selected@2x.png"; sourceTree = "<group>"; }; + 17B548691E82B02100175D5A /* button_edit_mode@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_edit_mode@2x.png"; sourceTree = "<group>"; }; + 17B5486A1E82B02100175D5A /* button_edit@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_edit@2x.png"; sourceTree = "<group>"; }; + 17B5486B1E82B02100175D5A /* button_left@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_left@2x.png"; sourceTree = "<group>"; }; + 17B5486C1E82B02100175D5A /* button_pagination@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_pagination@2x.png"; sourceTree = "<group>"; }; + 17B5486D1E82B02100175D5A /* button_remove@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_remove@2x.png"; sourceTree = "<group>"; }; + 17B5486E1E82B02100175D5A /* button_right@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_right@2x.png"; sourceTree = "<group>"; }; + 17B5486F1E82B02100175D5A /* button_select_all@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_select_all@2x.png"; sourceTree = "<group>"; }; + 17B548701E82B02100175D5A /* button_select_none@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_select_none@2x.png"; sourceTree = "<group>"; }; 17B7B591101602AE00F057DE /* libssl.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libssl.dylib; path = /usr/lib/libssl.dylib; sourceTree = "<absolute>"; }; 17BA2A3015275D8600389803 /* SPExportInterfaceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPExportInterfaceController.h; sourceTree = "<group>"; }; 17BA2A3115275D8600389803 /* SPExportInterfaceController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPExportInterfaceController.m; sourceTree = "<group>"; }; @@ -972,6 +995,7 @@ 50837F731E50DCD4004FAE8A /* SPJSONFormatterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPJSONFormatterTests.m; sourceTree = "<group>"; }; 5089B0251BE714E300E226CD /* SPIdMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPIdMenu.h; sourceTree = "<group>"; }; 5089B0261BE714E300E226CD /* SPIdMenu.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPIdMenu.m; sourceTree = "<group>"; }; + 50A77DA61E8EB903007466BC /* SPCompatibility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SPCompatibility.h; sourceTree = "<group>"; }; 50A9F8AF19EAD4B90053E571 /* SPGotoDatabaseController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPGotoDatabaseController.h; sourceTree = "<group>"; }; 50A9F8B019EAD4B90053E571 /* SPGotoDatabaseController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPGotoDatabaseController.m; sourceTree = "<group>"; }; 50D3C34A1A75B8A800B5429C /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/GotoDatabaseDialog.xib; sourceTree = "<group>"; }; @@ -1159,16 +1183,6 @@ 58B9072C11BD9B34000826E5 /* PSMTabDragWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSMTabDragWindowController.h; sourceTree = "<group>"; }; 58B9072D11BD9B34000826E5 /* PSMTabDragWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PSMTabDragWindowController.m; sourceTree = "<group>"; }; 58B9072E11BD9B34000826E5 /* PSMTabStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSMTabStyle.h; sourceTree = "<group>"; }; - 58B9073011BD9B34000826E5 /* PSMAdiumTabStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSMAdiumTabStyle.h; sourceTree = "<group>"; }; - 58B9073111BD9B34000826E5 /* PSMAdiumTabStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PSMAdiumTabStyle.m; sourceTree = "<group>"; }; - 58B9073211BD9B34000826E5 /* PSMAquaTabStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSMAquaTabStyle.h; sourceTree = "<group>"; }; - 58B9073311BD9B34000826E5 /* PSMAquaTabStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PSMAquaTabStyle.m; sourceTree = "<group>"; }; - 58B9073411BD9B34000826E5 /* PSMCardTabStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSMCardTabStyle.h; sourceTree = "<group>"; }; - 58B9073511BD9B34000826E5 /* PSMCardTabStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PSMCardTabStyle.m; sourceTree = "<group>"; }; - 58B9073611BD9B34000826E5 /* PSMMetalTabStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSMMetalTabStyle.h; sourceTree = "<group>"; }; - 58B9073711BD9B34000826E5 /* PSMMetalTabStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PSMMetalTabStyle.m; sourceTree = "<group>"; }; - 58B9073811BD9B34000826E5 /* PSMUnifiedTabStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSMUnifiedTabStyle.h; sourceTree = "<group>"; }; - 58B9073911BD9B34000826E5 /* PSMUnifiedTabStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PSMUnifiedTabStyle.m; sourceTree = "<group>"; }; 58B9077D11BD9B64000826E5 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; }; 58B9088711BDB7AA000826E5 /* PSMTabBar-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "PSMTabBar-Info.plist"; path = "Plists/PSMTabBar-Info.plist"; sourceTree = "<group>"; }; 58B9095B11C3A3EC000826E5 /* xibLocalizationPostprocessor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = xibLocalizationPostprocessor.m; sourceTree = "<group>"; }; @@ -1202,8 +1216,6 @@ 58DA8861103E15B5000B98DF /* SPLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPLogger.h; sourceTree = "<group>"; }; 58DA8862103E15B5000B98DF /* SPLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPLogger.m; sourceTree = "<group>"; }; 58DC0D5E1293293400B76DA5 /* ShortcutRecorder.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ShortcutRecorder.framework; path = Frameworks/ShortcutRecorder.framework; sourceTree = "<group>"; }; - 58DC10D112A1B8DF00B76DA5 /* SPMenuAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPMenuAdditions.h; sourceTree = "<group>"; }; - 58DC10D212A1B8DF00B76DA5 /* SPMenuAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPMenuAdditions.m; sourceTree = "<group>"; }; 58DF9F3115AB26C2003B4330 /* SPDateAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPDateAdditions.h; sourceTree = "<group>"; }; 58DF9F3215AB26C2003B4330 /* SPDateAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPDateAdditions.m; sourceTree = "<group>"; }; 58DF9F7115AB8509003B4330 /* SPSplitView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPSplitView.h; sourceTree = "<group>"; }; @@ -1453,6 +1465,8 @@ 11C2109D1180E70800758039 /* SPDatabaseRename.m */, 11B55BFC1189E3B2009EF465 /* SPDatabaseAction.h */, 11B55BFD1189E3B2009EF465 /* SPDatabaseAction.m */, + 17B548611E81FFA600175D5A /* SPCreateDatabaseInfo.h */, + 17B548621E81FFA600175D5A /* SPCreateDatabaseInfo.m */, ); name = "Database Actions"; sourceTree = "<group>"; @@ -1479,6 +1493,17 @@ name = "Table Triggers"; sourceTree = "<group>"; }; + 171156501E8B0F40002E6363 /* Table Relations */ = { + isa = PBXGroup; + children = ( + 387BBBA60FBCB6CB00B31746 /* SPTableRelations.h */, + 387BBBA70FBCB6CB00B31746 /* SPTableRelations.m */, + 171156531E8B0F96002E6363 /* SPTableRelationsDelegate.h */, + 171156541E8B0F96002E6363 /* SPTableRelationsDelegate.m */, + ); + name = "Table Relations"; + sourceTree = "<group>"; + }; 171312CF109D23CA00FB465F /* Cells */ = { isa = PBXGroup; children = ( @@ -1639,8 +1664,6 @@ 17E641490EF01EF6001BC333 /* SPCustomQuery.m */, 177E7A210FCB6A2E00E9E122 /* SPExtendedTableInfo.h */, 177E7A220FCB6A2E00E9E122 /* SPExtendedTableInfo.m */, - 387BBBA60FBCB6CB00B31746 /* SPTableRelations.h */, - 387BBBA70FBCB6CB00B31746 /* SPTableRelations.m */, 17E641500EF01EF6001BC333 /* SPDatabaseDocument.h */, 17E641510EF01EF6001BC333 /* SPDatabaseDocument.m */, 17D3DC1E1281816E002A163A /* SPDatabaseViewController.h */, @@ -1649,6 +1672,7 @@ 17386E08151924E9002DC206 /* Table Content */, 17D38F691279E17D00672B13 /* Table Structure */, 17005CB016D6CEA400AF81F4 /* Table Triggers */, + 171156501E8B0F40002E6363 /* Table Relations */, 1792C28910AE1C7200ABE758 /* Controller Categories */, ); name = "Main View Controllers"; @@ -2007,7 +2031,6 @@ isa = PBXGroup; children = ( 380F4EF40FC0B68F00B0BFD7 /* SPStringAdditionsTests.m */, - 1760599E1336199D0098E162 /* SPMenuAdditionsTests.m */, 1798F1C2155018D4004B0AB8 /* SPMutableArrayAdditionsTests.m */, 502D21F51BA50710000D4CE7 /* SPDataAdditionsTests.m */, ); @@ -2176,6 +2199,17 @@ isa = PBXGroup; children = ( 17BFC80D10D3FF5200A3B112 /* Icons */, + 17B548661E82B02100175D5A /* button_bar_handle@2x.png */, + 17B548671E82B02100175D5A /* button_duplicate@2x.png */, + 17B548681E82B02100175D5A /* button_edit_mode_selected@2x.png */, + 17B548691E82B02100175D5A /* button_edit_mode@2x.png */, + 17B5486A1E82B02100175D5A /* button_edit@2x.png */, + 17B5486B1E82B02100175D5A /* button_left@2x.png */, + 17B5486C1E82B02100175D5A /* button_pagination@2x.png */, + 17B5486D1E82B02100175D5A /* button_remove@2x.png */, + 17B5486E1E82B02100175D5A /* button_right@2x.png */, + 17B5486F1E82B02100175D5A /* button_select_all@2x.png */, + 17B548701E82B02100175D5A /* button_select_none@2x.png */, C9AD7C8116761B3300234EEE /* button_action.png */, C9AD7C8216761B3300234EEE /* button_action@2x.png */, 582E93F5168298C6003459FD /* button_add_folder.png */, @@ -2186,6 +2220,7 @@ C9C9943F1678A439001F5DA8 /* button_bar_spacer.png */, 582E940D1682A2AD003459FD /* button_bar_spacer@2x.png */, 582E94151682A463003459FD /* button_clear.png */, + 17AD35F41E79888D000F213E /* button_clear@2x.png */, 582E94171682A4B4003459FD /* button_duplicate.png */, 582E942316835EA9003459FD /* button_edit.png */, 582E941E16835DD4003459FD /* button_edit_mode.png */, @@ -2466,6 +2501,7 @@ 507FF1111BBCC57600104523 /* SPFunctions.m */, 5089B0251BE714E300E226CD /* SPIdMenu.h */, 5089B0261BE714E300E226CD /* SPIdMenu.m */, + 50A77DA61E8EB903007466BC /* SPCompatibility.h */, ); name = Utility; sourceTree = "<group>"; @@ -2610,18 +2646,8 @@ 58B9072F11BD9B34000826E5 /* Styles */ = { isa = PBXGroup; children = ( - 58B9073011BD9B34000826E5 /* PSMAdiumTabStyle.h */, - 58B9073111BD9B34000826E5 /* PSMAdiumTabStyle.m */, - 58B9073211BD9B34000826E5 /* PSMAquaTabStyle.h */, - 58B9073311BD9B34000826E5 /* PSMAquaTabStyle.m */, - 58B9073411BD9B34000826E5 /* PSMCardTabStyle.h */, - 58B9073511BD9B34000826E5 /* PSMCardTabStyle.m */, - 58B9073611BD9B34000826E5 /* PSMMetalTabStyle.h */, - 58B9073711BD9B34000826E5 /* PSMMetalTabStyle.m */, B55F8E5D11C67CA0006A3386 /* PSMSequelProTabStyle.h */, B55F8E5E11C67CA0006A3386 /* PSMSequelProTabStyle.m */, - 58B9073811BD9B34000826E5 /* PSMUnifiedTabStyle.h */, - 58B9073911BD9B34000826E5 /* PSMUnifiedTabStyle.m */, ); path = Styles; sourceTree = "<group>"; @@ -2685,8 +2711,6 @@ B52460D40F8EF92300171639 /* SPArrayAdditions.m */, 1789343A0F30C1DD0097539A /* SPStringAdditions.h */, 1789343B0F30C1DD0097539A /* SPStringAdditions.m */, - 58DC10D112A1B8DF00B76DA5 /* SPMenuAdditions.h */, - 58DC10D212A1B8DF00B76DA5 /* SPMenuAdditions.m */, 584D878915140FEB00F24774 /* SPObjectAdditions.h */, 584D878A15140FEB00F24774 /* SPObjectAdditions.m */, B52460D50F8EF92300171639 /* SPTextViewAdditions.h */, @@ -2975,9 +2999,6 @@ 58B9074A11BD9B34000826E5 /* overflowImage.png in Resources */, 58B9074B11BD9B34000826E5 /* overflowImagePressed.png in Resources */, 58B9074C11BD9B34000826E5 /* pi.png in Resources */, - 58B9075311BD9B34000826E5 /* TabNewMetal.png in Resources */, - 58B9075411BD9B34000826E5 /* TabNewMetalPressed.png in Resources */, - 58B9075511BD9B34000826E5 /* TabNewMetalRollover.png in Resources */, B55F8E6611C67D8A006A3386 /* AddTabButton.png in Resources */, B55F8E6711C67D8A006A3386 /* AddTabButtonPushed.png in Resources */, B55F8E6811C67D8A006A3386 /* AddTabButtonRollover.png in Resources */, @@ -3000,6 +3021,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 17B548731E82B02100175D5A /* button_edit_mode_selected@2x.png in Resources */, 17E641D10EF02036001BC333 /* grabber-horizontal.png in Resources */, 17E641D20EF02036001BC333 /* grabber-vertical.png in Resources */, 17E641F20EF02036001BC333 /* toolbar-switch-to-structure.png in Resources */, @@ -3010,12 +3032,14 @@ 3876E1501CC0B26000D85154 /* button_add@2x.png in Resources */, 17E641FD0EF02088001BC333 /* sequel-pro.scriptTerminology in Resources */, 1761FD480EF03A6F00331368 /* MainMenu.xib in Resources */, + 17B548711E82B02100175D5A /* button_bar_handle@2x.png in Resources */, B5E2C5FA0F2353B5007446E0 /* table-property.png in Resources */, 58186D210F4CB38900851FE9 /* ConnectionErrorDialog.xib in Resources */, 5885940F0F7AEE6000ED0E67 /* sparkle-public-key.pem in Resources */, B5E92F190F75B2D100012500 /* ExportDialog.xib in Resources */, B57747D20F7A891A003B34F9 /* Preferences.xib in Resources */, B57748420F7A8B57003B34F9 /* database.png in Resources */, + 17B548751E82B02100175D5A /* button_edit@2x.png in Resources */, B58731280F838C9E00087794 /* PreferenceDefaults.plist in Resources */, B52460DB0F8EF93B00171639 /* Console.xib in Resources */, BC2C8E220FA8C2DB008468C7 /* SPMySQLHelpTemplate.html in Resources */, @@ -3030,10 +3054,12 @@ 588B2CC90FE5641E00EC5FC0 /* ssh-connecting.png in Resources */, 588B2CCA0FE5641E00EC5FC0 /* ssh-disconnected.png in Resources */, 5822CAE110011C8000DCC3D6 /* ConnectionView.xib in Resources */, + 17B548761E82B02100175D5A /* button_left@2x.png in Resources */, BCA6F631100FA7D700E80253 /* FieldEditorSheet.xib in Resources */, 58D2E22E101222870063EF1D /* link-arrow-clicked.png in Resources */, 58D2E22F101222870063EF1D /* link-arrow-highlighted-clicked.png in Resources */, 58D2E230101222870063EF1D /* link-arrow.png in Resources */, + 17B548781E82B02100175D5A /* button_remove@2x.png in Resources */, 581068B61015411B0068C6E2 /* link-arrow-highlighted.png in Resources */, 581069B410167EC10068C6E2 /* SequelProTunnelAssistant in Resources */, 4D90B7A2101E0D1500D116A1 /* UserManagerView.xib in Resources */, @@ -3057,6 +3083,7 @@ BC962D661144EACA006170BD /* CompletionTokens.plist in Resources */, 17E0937E114AE154007FC1B4 /* SPTableInfoPrintTemplate.html in Resources */, B51D6B9E114C310C0074704E /* toolbar-switch-to-table-triggers.png in Resources */, + 17AD35F51E79888D000F213E /* button_clear@2x.png in Resources */, 17DD52B7115071D0007D8950 /* SPPrintTemplate.html in Resources */, 17F90E2C1210B34900274C98 /* Credits.rtf in Resources */, 17DD52C3115074B3007D8950 /* InfoPlist.strings in Resources */, @@ -3074,6 +3101,8 @@ BC09D7E012A786FB0030DB64 /* cancel-highlighted.png in Resources */, BC09D7E112A786FB0030DB64 /* cancel-hovered-highlighted.png in Resources */, BC09D7E212A786FB0030DB64 /* cancel-hovered.png in Resources */, + 17B548721E82B02100175D5A /* button_duplicate@2x.png in Resources */, + 17B548791E82B02100175D5A /* button_right@2x.png in Resources */, BC09D7E312A786FB0030DB64 /* cancel.png in Resources */, 58F48AA3161D03C6008536A1 /* quick-connect-icon.pdf in Resources */, 58F48B2E161D08C0008536A1 /* quick-connect-icon-white.pdf in Resources */, @@ -3084,6 +3113,7 @@ C9F92710162D38D70051CB2E /* toolbar-switch-to-table-info@2x.png in Resources */, C9F92712162D39E60051CB2E /* toolbar-switch-to-browse.png in Resources */, C9F92714162D39FE0051CB2E /* toolbar-switch-to-browse@2x.png in Resources */, + 17B5487B1E82B02100175D5A /* button_select_none@2x.png in Resources */, C9AD7C781676138000234EEE /* database-small@2x.png in Resources */, C9AD7C7B1676158C00234EEE /* toolbar-switch-to-sql.png in Resources */, C9AD7C7C1676158C00234EEE /* toolbar-switch-to-sql@2x.png in Resources */, @@ -3097,6 +3127,7 @@ C9AD7C8B1676204300234EEE /* button_info_pane_show.png in Resources */, C9AD7C8C1676204300234EEE /* button_info_pane_show@2x.png in Resources */, 58FEEF3D1676D14B009CD478 /* appIcon.icns in Resources */, + 17B5487A1E82B02100175D5A /* button_select_all@2x.png in Resources */, 58FEEF451676D160009CD478 /* Generic.icns in Resources */, 58FEEF461676D160009CD478 /* SPF.icns in Resources */, 58FEEF471676D160009CD478 /* SQL.icns in Resources */, @@ -3107,6 +3138,7 @@ C9C994461678A5CD001F5DA8 /* button_pane_show@2x.png in Resources */, C9C994491678B3E6001F5DA8 /* table-small-square.png in Resources */, C9C9944A1678B3E6001F5DA8 /* table-small-square@2x.png in Resources */, + 17B548741E82B02100175D5A /* button_edit_mode@2x.png in Resources */, C9C9944D1678BCFA001F5DA8 /* table-small.png in Resources */, C9C9944E1678BCFA001F5DA8 /* table-small@2x.png in Resources */, 582E939D168296F3003459FD /* link-arrow-clicked@2x.png in Resources */, @@ -3139,6 +3171,7 @@ 582E9488168380D6003459FD /* sync_arrows_06.png in Resources */, 582E948F168383F0003459FD /* table-view-small-square.png in Resources */, 582E9490168383F0003459FD /* table-view-small.png in Resources */, + 17B548771E82B02100175D5A /* button_pagination@2x.png in Resources */, 582E94A816839AD5003459FD /* toolbar-preferences-autoupdate.png in Resources */, 582E94AA16839AEF003459FD /* toolbar-preferences-general.png in Resources */, 582E94AE16839C4A003459FD /* toolbar-preferences-notifications.png in Resources */, @@ -3200,10 +3233,8 @@ 50EA92641AB23EAD008D3C4F /* SPDatabaseCopy.m in Sources */, 50D3C35D1A77217800B5429C /* SPParserUtils.c in Sources */, 380F4EF50FC0B68F00B0BFD7 /* SPStringAdditionsTests.m in Sources */, - 1760599F1336199D0098E162 /* SPMenuAdditionsTests.m in Sources */, 1798F1C4155018E2004B0AB8 /* SPMutableArrayAdditionsTests.m in Sources */, 17DB5F441555CA300046834B /* SPMutableArrayAdditions.m in Sources */, - 17DB5F4A1555CA810046834B /* SPMenuAdditions.m in Sources */, 1717F9661557E0450065C036 /* SPStringAdditions.m in Sources */, 1717FA401558313A0065C036 /* RegexKitLite.m in Sources */, 50D3C35C1A771C4C00B5429C /* SPParserUtilsTest.m in Sources */, @@ -3311,6 +3342,7 @@ B52460D80F8EF92300171639 /* SPTextViewAdditions.m in Sources */, 296DC8B60F909194002A3258 /* MGTemplateEngine.m in Sources */, 296DC8B70F909194002A3258 /* RegexKitLite.m in Sources */, + 17B548631E81FFA600175D5A /* SPCreateDatabaseInfo.m in Sources */, 296DC8B80F909194002A3258 /* ICUTemplateMatcher.m in Sources */, 296DC8B90F909194002A3258 /* MGTemplateStandardMarkers.m in Sources */, 296DC8BA0F909194002A3258 /* NSArray_DeepMutableCopy.m in Sources */, @@ -3422,10 +3454,10 @@ 17D3C671128AD8160047709F /* SPSingleton.m in Sources */, 17D3C6D3128B1C900047709F /* SPFavoritesOutlineView.m in Sources */, 50D3C3521A77135F00B5429C /* SPParserUtils.c in Sources */, + 171156551E8B0F96002E6363 /* SPTableRelationsDelegate.m in Sources */, BC68BFC7128D4EAE004907D9 /* SPBundleEditorController.m in Sources */, BC1944D01297291800A236CD /* SPBundleCommandTextView.m in Sources */, BC77C5E4129AA69E009AD832 /* SPBundleHTMLOutputController.m in Sources */, - 58DC10D312A1B8DF00B76DA5 /* SPMenuAdditions.m in Sources */, BC5750D512A6233900911BA2 /* SPActivityTextFieldCell.m in Sources */, BC0ED3DA12A9196C00088461 /* SPChooseMenuItemDialog.m in Sources */, 583CA21512EC8B2200C9E763 /* SPWindow.m in Sources */, |