Skip to content

Commit

Permalink
Add a visual indication for the defaults in the encoding/collation me…
Browse files Browse the repository at this point in the history
…nus in table structure view (final part of #2237)
  • Loading branch information
dmoagx committed Nov 2, 2015
1 parent f02fb78 commit 7c7660b
Show file tree
Hide file tree
Showing 5 changed files with 316 additions and 2 deletions.
20 changes: 18 additions & 2 deletions Interfaces/English.lproj/DBView.xib
Original file line number Diff line number Diff line change
Expand Up @@ -1675,7 +1675,7 @@
<nil key="NSMenuItem"/>
<bool key="NSMenuItemRespectAlignment">YES</bool>
<object class="NSMenu" key="NSMenu" id="856601787">
<string key="NSTitle">OtherViews</string>
<string key="NSTitle">encodingPopupMenu</string>
<array class="NSMutableArray" key="NSMenuItems"/>
</object>
<int key="NSSelectedIndex">-1</int>
Expand Down Expand Up @@ -1717,7 +1717,7 @@
<nil key="NSMenuItem"/>
<bool key="NSMenuItemRespectAlignment">YES</bool>
<object class="NSMenu" key="NSMenu" id="65801928">
<string key="NSTitle">OtherViews</string>
<string key="NSTitle">collationPopupMenu</string>
<array class="NSMutableArray" key="NSMenuItems"/>
</object>
<int key="NSSelectedIndex">-1</int>
Expand Down Expand Up @@ -17350,6 +17350,22 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA</bytes>
</object>
<string key="id">7299</string>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="856601787"/>
<reference key="destination" ref="239767357"/>
</object>
<string key="id">Jbs-NM-Lzb</string>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="65801928"/>
<reference key="destination" ref="239767357"/>
</object>
<string key="id">Dcc-ay-7AU</string>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">delegate</string>
Expand Down
53 changes: 53 additions & 0 deletions Source/SPPillAttachmentCell.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//
// SPPillAttachmentCell.h
// sequel-pro
//
// Created by Max Lohrmann on 01.11.15.
// Copyright (c) 2015 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>

#import <Foundation/Foundation.h>

/**
* This is a simple TextAttachmentCell which takes the stringValue
* and displays it in a "pill", much like the tokens in an NSTokenTextField.
*
* It is designed to be used with static labels rather than inside user input text fields.
*
* To use it:
*
* NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
* SPPillAttachmentCell *cell = [[SPPillAttachmentCell alloc] init];
* [cell setStringValue:@"..."];
* [attachment setAttachmentCell:[cell autorelease];
* NSAttributedString *att = [NSAttributedString attributedStringWithAttachment:[attachment autorelease]];
* [otherAttributedString appendAttributedString:att];
*
*/
@interface SPPillAttachmentCell : NSTextAttachmentCell {
NSColor *_borderColor;
NSGradient *_gradient;
}
@end
113 changes: 113 additions & 0 deletions Source/SPPillAttachmentCell.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
//
// SPPillAttachmentCell.m
// sequel-pro
//
// Created by Max Lohrmann on 01.11.15.
// Copyright (c) 2015 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>

#import "SPPillAttachmentCell.h"


@implementation SPPillAttachmentCell

- (id)init
{
if(self = [super init]) {
_borderColor = [[NSColor colorWithCalibratedRed:168/255.0 green:184/255.0 blue:249/255.0 alpha: 1] retain];
_gradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithCalibratedRed:199/255.0 green:216/255.0 blue:244/255.0 alpha: 1]
endingColor:[NSColor colorWithCalibratedRed:217/255.0 green:229/255.0 blue:247/255.0 alpha: 1]];
}
return self;
}

- (void)dealloc
{
SPClear(_borderColor);
SPClear(_gradient);

[super dealloc];
}

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
[self drawWithFrame:cellFrame inView:controlView characterIndex:NSNotFound];
}

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView characterIndex:(NSUInteger)charIndex
{
[self drawWithFrame:cellFrame inView:controlView characterIndex:charIndex layoutManager:nil];
}

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView characterIndex:(NSUInteger)charIndex layoutManager:(NSLayoutManager *)layoutManager
{
CGFloat bRadius = cellFrame.size.height/2.0;
NSBezierPath* rectanglePath = [NSBezierPath bezierPathWithRoundedRect:NSInsetRect(cellFrame,1,1) xRadius:bRadius yRadius:bRadius];
[_gradient drawInBezierPath: rectanglePath angle: -90];
[_borderColor setStroke];
[rectanglePath setLineWidth:1.0];
[rectanglePath stroke];

[self drawInteriorWithFrame:cellFrame inView:controlView];
}

- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
NSString* textContent = [self stringValue];
NSMutableParagraphStyle* rectangleStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy];
[rectangleStyle setAlignment:NSCenterTextAlignment];

NSMutableDictionary *rectangleFontAttributes = [NSMutableDictionary dictionaryWithDictionary:[self attributes]];
[rectangleFontAttributes setObject:[rectangleStyle autorelease] forKey:NSParagraphStyleAttributeName];

//cellFrame.origin.y += [[self font] descender];
[textContent drawInRect:cellFrame withAttributes:rectangleFontAttributes];
}

- (NSPoint)cellBaselineOffset
{
//Not used in menu
return NSMakePoint(0, [[self font] descender]-1);
}

- (NSRect)cellFrameForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(NSRect)lineFrag glyphPosition:(NSPoint)position characterIndex:(NSUInteger)charIndex
{
NSSize sz = [self cellSize];
CGFloat offset = (lineFrag.size.height - sz.height) / 2;
return NSMakeRect(0, [[self font] descender]+offset, sz.width+(2*12), sz.height);
}

- (NSSize)cellSize
{
//Not used in menu
return [[self stringValue] sizeWithAttributes:[self attributes]];
}

- (NSDictionary *)attributes
{
return @{NSFontAttributeName: [self font],NSForegroundColorAttributeName: [NSColor controlTextColor]};
}

@end
126 changes: 126 additions & 0 deletions Source/SPTableStructureDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,27 @@
#import "SPTableStructureLoading.h"
#import "SPServerSupport.h"
#import "SPTablesList.h"
#import "SPPillAttachmentCell.h"

#import <SPMySQL/SPMySQL.h>

struct _cmpMap {
NSString *title; // the title of the "pill"
NSString *tooltipPart; // the tooltip of the menuitem
NSString *cmpWith; // the string to match against
};

/**
* This function will compare the representedObject of every item in menu against
* every map->cmpWith. If they match it will append a pill-like (similar to a TokenFieldCell's token)
* element labelled map->title to the menu item's title. If map->tooltipPart is set,
* it will also be added to the menu item's tooltip.
*
* This is used with the encoding/collation popup menus to add visual indicators for the
* table-level and default encoding/collation.
*/
static void _BuildMenuWithPills(NSMenu *menu,struct _cmpMap *map,size_t mapEntries);

@interface SPTableStructure (PrivateAPI)

- (void)sheetDidEnd:(id)sheet returnCode:(NSInteger)returnCode contextInfo:(NSString *)contextInfo;
Expand Down Expand Up @@ -69,6 +87,7 @@ - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColum
NSString *columnEncoding = [rowData objectForKey:@"encodingName"];
NSString *columnCollation = [rowData objectForKey:@"collationName"]; // loadTable: has already inferred it, if not set explicit

#warning Building the collation menu here is a big performance hog. This should be done in menuNeedsUpdate: below!
NSPopUpButtonCell *collationCell = [tableColumn dataCell];
[collationCell removeAllItems];
[collationCell addItemWithTitle:@"dummy"];
Expand Down Expand Up @@ -698,4 +717,111 @@ - (NSString *)comboBoxCell:(NSComboBoxCell *)aComboBoxCell completedString:(NSSt
return @"";
}

#pragma mark -
#pragma mark Menu delegate methods (encoding/collation dropdown menu)

- (void)menuNeedsUpdate:(NSMenu *)menu
{
//NOTE: NSTableView will usually copy the menu and call this method on the copy. Matching with == won't work!

//walk through the menu and clear the attributedTitle if set. This will remove the gray color from the default items
for(NSMenuItem *item in [menu itemArray]) {
if([item attributedTitle]) {
[item setAttributedTitle:nil];
}
}

NSDictionary *rowData = NSArrayObjectAtIndex(tableFields, [tableSourceView selectedRow]);

if([[menu title] isEqualToString:@"encodingPopupMenu"]) {
NSString *tableEncoding = [tableDataInstance tableEncoding];
//NSString *databaseEncoding = [databaseDataInstance getDatabaseDefaultCharacterSet];
//NSString *serverEncoding = [databaseDataInstance getServerDefaultCharacterSet];

struct _cmpMap defaultCmp[] = {
{
NSLocalizedString(@"Table",@"Table Structure : Encoding dropdown : 'item is table default' marker"),
[NSString stringWithFormat:NSLocalizedString(@"This is the default encoding of table “%@”.", @"Table Structure : Encoding dropdown : table marker tooltip"),selectedTable],
tableEncoding
},
/* //we could, but that might confuse users even more plus there is no inheritance between a columns charset and the db/server default
{
NSLocalizedString(@"Database",@"Table Structure : Encoding dropdown : 'item is database default' marker"),
[NSString stringWithFormat:NSLocalizedString(@"This is the default encoding of database “%@”.", @"Table Structure : Encoding dropdown : database marker tooltip"),[tableDocumentInstance database]],
databaseEncoding
},
{
NSLocalizedString(@"Server",@"Table Structure : Encoding dropdown : 'item is server default' marker"),
NSLocalizedString(@"This is the default encoding of this server.", @"Table Structure : Encoding dropdown : server marker tooltip"),
serverEncoding
} */
};

_BuildMenuWithPills(menu, defaultCmp, COUNT_OF(defaultCmp));
}
else if([[menu title] isEqualToString:@"collationPopupMenu"]) {
NSString *encoding = [rowData objectForKey:@"encodingName"];
NSString *encodingDefaultCollation = [databaseDataInstance getDefaultCollationForEncoding:encoding];
NSString *tableCollation = [tableDataInstance statusValueForKey:@"Collation"];
//NSString *databaseCollation = [databaseDataInstance getDatabaseDefaultCollation];
//NSString *serverCollation = [databaseDataInstance getServerDefaultCollation];

struct _cmpMap defaultCmp[] = {
{
NSLocalizedString(@"Default",@"Table Structure : Collation dropdown : 'item is the same as the default collation of the row's charset' marker"),
[NSString stringWithFormat:NSLocalizedString(@"This is the default collation of encoding “%@”.", @"Table Structure : Collation dropdown : default marker tooltip"),encoding],
encodingDefaultCollation
},
{
NSLocalizedString(@"Table",@"Table Structure : Collation dropdown : 'item is the same as the collation of table' marker"),
[NSString stringWithFormat:NSLocalizedString(@"This is the default collation of table “%@”.", @"Table Structure : Collation dropdown : table marker tooltip"),selectedTable],
tableCollation
},
/* // see the comment for charset above
{
NSLocalizedString(@"Database",@"Table Structure : Collation dropdown : 'item is the same as the collation of database' marker"),
[NSString stringWithFormat:NSLocalizedString(@"This is the default collation of database “%@”.", @"Table Structure : Collation dropdown : database marker tooltip"),[tableDocumentInstance database]],
databaseCollation
},
{
NSLocalizedString(@"Server",@"Table Structure : Collation dropdown : 'item is the same as the collation of server' marker"),
NSLocalizedString(@"This is the default collation of this server.", @"Table Structure : Collation dropdown : server marker tooltip"),
serverCollation
} */
};

_BuildMenuWithPills(menu, defaultCmp, COUNT_OF(defaultCmp));
}
}

@end

void _BuildMenuWithPills(NSMenu *menu,struct _cmpMap *map,size_t mapEntries)
{
NSDictionary *baseAttrs = @{NSFontAttributeName:[menu font],NSParagraphStyleAttributeName: [NSParagraphStyle defaultParagraphStyle]};

for(NSMenuItem *item in [menu itemArray]) {
NSMutableAttributedString *itemStr = [[NSMutableAttributedString alloc] initWithString:[item title] attributes:baseAttrs];
NSString *value = [item representedObject];

NSMutableArray *tooltipParts = [NSMutableArray array];
for (unsigned int i = 0; i < mapEntries; ++i) {
struct _cmpMap *cmp = &map[i];
if([cmp->cmpWith isEqualToString:value]) {
SPPillAttachmentCell *cell = [[SPPillAttachmentCell alloc] init];
[cell setStringValue:cmp->title];
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
[attachment setAttachmentCell:[cell autorelease]];
NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:[attachment autorelease]];

[[itemStr mutableString] appendString:@" "];
[itemStr appendAttributedString:attachmentString];

if(cmp->tooltipPart) [tooltipParts addObject:cmp->tooltipPart];
}
}
if([tooltipParts count]) [item setToolTip:[tooltipParts componentsJoinedByString:@" "]];

[item setAttributedTitle:[itemStr autorelease]];
}
}
6 changes: 6 additions & 0 deletions sequel-pro.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@
17F90E481210B42700274C98 /* SPExportFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 17F90E471210B42700274C98 /* SPExportFile.m */; };
17F90E4B1210B43A00274C98 /* SPExportFileUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 17F90E4A1210B43A00274C98 /* SPExportFileUtilities.m */; };
17FDB04C1280778B00DBBBC2 /* SPFontPreviewTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 17FDB04B1280778B00DBBBC2 /* SPFontPreviewTextField.m */; };
1A564F74237E2E4958CA593A /* SPPillAttachmentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A56463D14569A0B56EE8BAC /* SPPillAttachmentCell.m */; };
296DC89F0F8FD336002A3258 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 296DC89E0F8FD336002A3258 /* WebKit.framework */; };
296DC8B60F909194002A3258 /* MGTemplateEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = 296DC8A70F909194002A3258 /* MGTemplateEngine.m */; };
296DC8B70F909194002A3258 /* RegexKitLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 296DC8AB0F909194002A3258 /* RegexKitLite.m */; };
Expand Down Expand Up @@ -859,6 +860,8 @@
17F90E4A1210B43A00274C98 /* SPExportFileUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPExportFileUtilities.m; sourceTree = "<group>"; };
17FDB04A1280778B00DBBBC2 /* SPFontPreviewTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPFontPreviewTextField.h; sourceTree = "<group>"; };
17FDB04B1280778B00DBBBC2 /* SPFontPreviewTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPFontPreviewTextField.m; sourceTree = "<group>"; };
1A56463D14569A0B56EE8BAC /* SPPillAttachmentCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPPillAttachmentCell.m; sourceTree = "<group>"; };
1A564C0C0FFB444D2E5CA447 /* SPPillAttachmentCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPPillAttachmentCell.h; sourceTree = "<group>"; };
296DC89E0F8FD336002A3258 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = /System/Library/Frameworks/WebKit.framework; sourceTree = "<absolute>"; };
296DC8A50F909194002A3258 /* MGTemplateMarker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGTemplateMarker.h; sourceTree = "<group>"; };
296DC8A60F909194002A3258 /* MGTemplateFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGTemplateFilter.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1441,6 +1444,8 @@
B57747DB0F7A89D0003B34F9 /* SPFavoriteTextFieldCell.m */,
BC5750D412A6233900911BA2 /* SPActivityTextFieldCell.h */,
BC5750D312A6233900911BA2 /* SPActivityTextFieldCell.m */,
1A56463D14569A0B56EE8BAC /* SPPillAttachmentCell.m */,
1A564C0C0FFB444D2E5CA447 /* SPPillAttachmentCell.h */,
);
name = Cells;
sourceTree = "<group>";
Expand Down Expand Up @@ -3348,6 +3353,7 @@
501B1D181728A3DA0017C92E /* SPCharsetCollationHelper.m in Sources */,
50E217B318174246009D3580 /* SPColorSelectorView.m in Sources */,
50E217B618174280009D3580 /* SPFavoriteColorSupport.m in Sources */,
1A564F74237E2E4958CA593A /* SPPillAttachmentCell.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down

0 comments on commit 7c7660b

Please sign in to comment.