From 019a1015546ab203eb366a71811d6c75b130fd40 Mon Sep 17 00:00:00 2001 From: Bibiko Date: Wed, 1 Dec 2010 12:23:22 +0000 Subject: =?UTF-8?q?=E2=80=A2=20added=20=20chance=20to=20cancel=20an=20acti?= =?UTF-8?q?vity=20-=20up=20to=20now=20a=20running=20Bundle=20command=20-?= =?UTF-8?q?=20from=20the=20Activities=20pane=20(toggable=20via=20double-cl?= =?UTF-8?q?icking=20at=20Table=20Information=20header);=20it's=20still=20t?= =?UTF-8?q?entative=20and=20the=20correct=20cancel=20icon=20will=20follow?= =?UTF-8?q?=20asap=20=E2=80=A2=20added=20notification=20system=20for=20upd?= =?UTF-8?q?ating=20the=20activities=20pane=20(SPActivitiesUpdateNotificati?= =?UTF-8?q?on)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Interfaces/English.lproj/DBView.xib | 162 +++++----------- Source/SPActivityTextFieldCell.h | 49 +++++ Source/SPActivityTextFieldCell.m | 357 +++++++++++++++++++++++++++++++++++ Source/SPAppController.h | 8 +- Source/SPAppController.m | 31 +-- Source/SPConstants.h | 1 + Source/SPConstants.m | 1 + Source/SPCopyTable.m | 9 +- Source/SPDatabaseDocument.h | 8 +- Source/SPDatabaseDocument.m | 20 +- Source/SPStringAdditions.h | 2 +- Source/SPStringAdditions.m | 21 +-- Source/SPTableInfo.h | 1 + Source/SPTableInfo.m | 89 +++++++-- Source/SPTableTextFieldCell.m | 5 + Source/SPTextViewAdditions.m | 9 +- sequel-pro.xcodeproj/project.pbxproj | 6 + 17 files changed, 607 insertions(+), 172 deletions(-) create mode 100644 Source/SPActivityTextFieldCell.h create mode 100644 Source/SPActivityTextFieldCell.m diff --git a/Interfaces/English.lproj/DBView.xib b/Interfaces/English.lproj/DBView.xib index d8df8add..2f2c4d25 100644 --- a/Interfaces/English.lproj/DBView.xib +++ b/Interfaces/English.lproj/DBView.xib @@ -23,12 +23,13 @@ YES + YES com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin com.apple.WebKitIBPlugin + com.apple.InterfaceBuilder.CocoaPlugin PluginDependencyRecalculationVersion @@ -85,7 +86,6 @@ 290 {{5, 2}, {204, 19}} - YES 343014976 @@ -178,7 +178,6 @@ 4362 {218, 38} - YES @@ -223,7 +222,7 @@ controlColor 3 - MC42NjY2NjY2NjY3AA + MC42NjY2NjY2ODY1AA @@ -268,7 +267,6 @@ {{1, 1}, {218, 38}} - @@ -284,7 +282,6 @@ -2147483392 {{-100, -100}, {15, 8}} - _doScroller: 0.42105263471603394 @@ -294,7 +291,6 @@ -2147483392 {{-100, -100}, {223, 15}} - 1 _doScroller: @@ -303,7 +299,6 @@ {{-1, -13}, {220, 40}} - 2 @@ -314,7 +309,6 @@ {214, 26} - NSView @@ -337,7 +331,6 @@ 4352 {214, 354} - YES @@ -404,7 +397,6 @@ {214, 354} - @@ -415,7 +407,6 @@ -2147483392 {{197, 0}, {15, 292}} - _doScroller: 0.096045196056365967 @@ -426,7 +417,6 @@ -2147483392 {{-100, -100}, {141, 11}} - 257 _doScroller: @@ -435,7 +425,6 @@ {214, 354} - 528 @@ -446,13 +435,11 @@ {{0, 27}, {214, 354}} - NSView {214, 381} - 2 6 @@ -486,7 +473,6 @@ {214, 381} - NSView @@ -509,7 +495,6 @@ 4352 {214, 145} - YES @@ -519,14 +504,14 @@ YES - info - 145.8690185546875 - 42.868999481201172 + name + 211 + 43 1000 75628096 2048 - Information + 3 @@ -535,8 +520,8 @@ - 337772096 - 272761856 + 337772097 + 272762880 Text Cell @@ -552,10 +537,18 @@ 3 2 - + + 6 + System + _sourceListBackgroundColor + + 1 + MC44MzkyMTU2OTU5IDAuODY2NjY2Njc0NiAwLjg5ODAzOTIyMTgAA + + - 17 - 1379926016 + 45 + 1377828864 2 @@ -568,7 +561,6 @@ {214, 145} - @@ -579,18 +571,15 @@ -2147483392 {{-100, -100}, {15, 20}} - _doScroller: - 0.48965516686439514 - 0.94736838340759277 + 0.99315071105957031 -2147483392 {{-100, -100}, {141, 11}} - 257 _doScroller: @@ -599,13 +588,12 @@ {214, 145} - - 544 + 528 - QSAAAEEgAABBmAAAQZgAAA + QSAAAEEgAABCPAAAQjwAAA @@ -622,7 +610,6 @@ 4352 {214, 145} - YES @@ -649,7 +636,7 @@ 337772096 - 272761856 + 272762880 Text Cell @@ -689,7 +676,6 @@ {214, 145} - @@ -700,7 +686,6 @@ -2147483392 {{-100, -100}, {15, 20}} - _doScroller: 0.48965516686439514 @@ -711,7 +696,6 @@ -2147483392 {{-100, -100}, {141, 11}} - 257 _doScroller: @@ -720,7 +704,6 @@ {214, 145} - 512 @@ -731,13 +714,11 @@ {{0, 382}, {214, 145}} - NSView {{0, 23}, {214, 527}} - 2 NO @@ -788,7 +769,6 @@ 268 {{-1, -1}, {32, 24}} - YES 67239424 @@ -813,7 +793,6 @@ 268 {{30, -1}, {32, 24}} - YES 71433792 @@ -1011,7 +990,6 @@ 268 {{61, -1}, {32, 24}} - YES 67239424 @@ -1036,7 +1014,6 @@ 268 {{92, -1}, {32, 24}} - YES -2080244224 @@ -1063,7 +1040,6 @@ {{0, 1}, {214, 23}} - YES YES NO @@ -1072,7 +1048,6 @@ {214, 550} - NSView @@ -1085,7 +1060,6 @@ 274 {{-7, -10}, {741, 564}} - YES @@ -1110,7 +1084,6 @@ 289 {{662, -1}, {32, 24}} - YES 71433792 @@ -1218,7 +1191,6 @@ -2147483356 {{124, -1}, {33, 25}} - YES -2080244224 @@ -1253,14 +1225,12 @@ 4352 {694, 289} - YES 256 {694, 17} - @@ -1268,7 +1238,6 @@ -2147483392 {{-26, 0}, {16, 17}} - YES @@ -1822,7 +1791,6 @@ {{1, 17}, {694, 289}} - @@ -1833,7 +1801,6 @@ -2147483392 {{674, 17}, {15, 274}} - _doScroller: 0.9480968713760376 @@ -1843,7 +1810,6 @@ -2147483392 {{1, 291}, {694, 15}} - 1 _doScroller: @@ -1859,7 +1825,6 @@ {{1, 0}, {694, 17}} - @@ -1869,7 +1834,6 @@ {{-1, 22}, {696, 307}} - 562 @@ -1884,7 +1848,6 @@ 292 {{-1, -1}, {32, 25}} - YES -1543373312 @@ -1909,7 +1872,6 @@ 292 {{93, -1}, {32, 25}} - YES -2080244224 @@ -1934,7 +1896,6 @@ 292 {{30, -1}, {32, 25}} - YES -1543373312 @@ -1959,7 +1920,6 @@ 292 {{61, -1}, {32, 25}} - YES -1543373312 @@ -1996,7 +1956,6 @@ {{125, 0}, {507, 23}} - YES 130560 @@ -2017,7 +1976,6 @@ 289 {{632, -1}, {32, 25}} - YES -1543373312 @@ -2040,7 +1998,6 @@ {695, 329} - NSView @@ -2058,7 +2015,6 @@ 268 {{3, 3}, {49, 14}} - YES 68288064 @@ -2097,7 +2053,6 @@ {{678, 4}, {10, 13}} - YES 130560 @@ -2116,7 +2071,6 @@ {{0, 181}, {695, 20}} - 1 MC42NzU3Njg0OTQ2IDAuNzIxOTQ4MTQ2OCAwLjc2NTMwNjExNTIAA @@ -2159,14 +2113,12 @@ 4352 {694, 140} - YES 256 {694, 17} - @@ -2174,7 +2126,6 @@ -2147483392 {{-26, 0}, {16, 17}} - YES @@ -2430,7 +2381,6 @@ {{1, 17}, {694, 140}} - @@ -2441,7 +2391,6 @@ -2147483392 {{611, 17}, {15, 126}} - _doScroller: 0.97794115543365479 @@ -2451,7 +2400,6 @@ -2147483392 {{1, 143}, {610, 15}} - 1 _doScroller: @@ -2466,7 +2414,6 @@ {{1, 0}, {694, 17}} - @@ -2476,7 +2423,6 @@ {{-1, 23}, {696, 158}} - 562 @@ -2491,7 +2437,6 @@ 292 {{-1, 0}, {32, 25}} - YES -1543373312 @@ -2513,7 +2458,6 @@ 292 {{61, 0}, {32, 25}} - YES -2080244224 @@ -2535,7 +2479,6 @@ 292 {{30, 0}, {32, 25}} - YES -1543373312 @@ -2569,7 +2512,6 @@ {{93, 1}, {602, 23}} - YES 130560 @@ -2585,19 +2527,16 @@ {{0, 330}, {695, 201}} - NSView {{7, 10}, {695, 531}} - 2 {{10, 7}, {706, 544}} - Structure @@ -6358,13 +6297,11 @@ {{215, 0}, {729, 550}} - NSView {{0, -1}, {944, 550}} - YES 2 DBViewSplitter @@ -6372,7 +6309,6 @@ {943, 549} - NSView @@ -7095,7 +7031,7 @@ View - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} {213, 107} @@ -7249,7 +7185,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8 {{0, 0}, {1440, 878}} {213, 129} - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} 7 @@ -7259,7 +7195,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8 Reset Auto Increment NSWindow - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} {255, 95} @@ -7422,7 +7358,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8 {{0, 0}, {1280, 1002}} {255, 117} - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} 1 @@ -7432,7 +7368,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8 New Relation NSPanel - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} 256 @@ -8033,7 +7969,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8 {302, 307} {{0, 0}, {1440, 878}} - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} 9 @@ -8043,7 +7979,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8 New Trigger NSPanel - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} {360, 348} @@ -8450,7 +8386,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8 {{0, 0}, {1680, 1028}} {360, 370} - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} 3 @@ -8462,7 +8398,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8 View - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} {213, 50} @@ -8582,7 +8518,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8 {{0, 0}, {1920, 1178}} {213, 72} - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} 9 @@ -8594,7 +8530,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8 View - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} {213, 107} @@ -8729,7 +8665,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8 {{0, 0}, {1440, 878}} {213, 129} - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} 15 @@ -8741,7 +8677,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8 View - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} {350, 200} @@ -8964,7 +8900,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8 {{0, 0}, {1680, 1028}} {350, 222} - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} SPCreateSyntaxSheet @@ -8977,7 +8913,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8 View - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} {213, 107} @@ -9147,7 +9083,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8 {{0, 0}, {1440, 878}} {213, 129} - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} 31 @@ -9157,7 +9093,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8 MySQL Help NSPanel - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} {351, 120} @@ -9555,7 +9491,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8 {{0, 0}, {1280, 1002}} {351, 136} - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} MYSQL_HELP_WINDOW @@ -9566,7 +9502,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8 Filter NSPanel - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} {380, 170} @@ -10211,7 +10147,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8 {{0, 0}, {1280, 778}} {380, 192} - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} SPTableFilterPanel @@ -10711,7 +10647,7 @@ bGQgTmFtZQkgID0gQAoJCQkJICBMRU5HVEgoYEBgKSA+IEA Secure Text Input Sheet NSPanel - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} 256 @@ -10815,7 +10751,7 @@ bGQgTmFtZQkgID0gQAoJCQkJICBMRU5HVEgoYEBgKSA+IEA {338, 150} {{0, 0}, {1280, 778}} - {1.79769e+308, 1.79769e+308} + {3.40282e+38, 3.40282e+38} @@ -10998,7 +10934,7 @@ bGQgTmFtZQkgID0gQAoJCQkJICBMRU5HVEgoYEBgKSA+IEA disabledControlTextColor 3 - MC4zMzMzMzMzMzMzAA + MC4zMzMzMzMzNDMzAA @@ -25671,7 +25607,7 @@ bGQgTmFtZQkgID0gQAoJCQkJICBMRU5HVEgoYEBgKSA+IEA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{59, 184}, {943, 549}} + {{76, 64}, {943, 549}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -26177,7 +26113,7 @@ bGQgTmFtZQkgID0gQAoJCQkJICBMRU5HVEgoYEBgKSA+IEA - 7715 + 7720 diff --git a/Source/SPActivityTextFieldCell.h b/Source/SPActivityTextFieldCell.h new file mode 100644 index 00000000..4f027710 --- /dev/null +++ b/Source/SPActivityTextFieldCell.h @@ -0,0 +1,49 @@ +// +// $Id: SPActivityTextFieldCell.h 2781 2010-10-19 23:37:15Z stuart02 $ +// +// SPActivityTextFieldCell.h +// sequel-pro +// +// Created by Hans-Jörg Bibiko on Dec 01, 2010 +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at + +#import "ImageAndTextCell.h" + +@interface SPActivityTextFieldCell : ImageAndTextCell + +{ + NSString *activityName; + NSString *activityInfo; + NSDictionary *contextInfo; + + NSButtonCell *cancelButton; + + NSInteger drawState; + + NSColor *mainStringColor; + NSColor *subStringColor; +} + +@property(readwrite,retain) NSString *activityName; +@property(readwrite,retain) NSString *activityInfo; +@property(readwrite,retain) NSDictionary *contextInfo; + +- (void)invertFontColors; +- (void)restoreFontColors; + +@end diff --git a/Source/SPActivityTextFieldCell.m b/Source/SPActivityTextFieldCell.m new file mode 100644 index 00000000..856fde52 --- /dev/null +++ b/Source/SPActivityTextFieldCell.m @@ -0,0 +1,357 @@ +// +// $Id: SPActivityTextFieldCell.m 2691 2010-09-25 12:21:03Z stuart02 $ +// +// SPActivityTextFieldCell.m +// sequel-pro +// +// Created by Hans-Jörg Bibiko on Dec 01, 2010 +// Copyright (c) 2008 Stuart Connolly. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at + +#import "SPActivityTextFieldCell.h" + +#define FAVORITE_NAME_FONT_SIZE 12.0 + +@interface SPActivityTextFieldCell (PrivateAPI) + +- (NSAttributedString *)constructSubStringAttributedString; +- (NSAttributedString *)attributedStringForFavoriteName; +- (NSDictionary *)mainStringAttributedStringAttributes; +- (NSDictionary *)subStringAttributedStringAttributes; + +@end + +@implementation SPActivityTextFieldCell + +/** + * Provide a method to derive the link rect from a cell rect. + */ +static inline NSRect SPTextLinkRectFromCellRect(NSRect inRect) +{ + return NSMakeRect(inRect.origin.x + inRect.size.width - 30, inRect.origin.y - 1, 15, inRect.size.height); +} + + +@synthesize activityName; +@synthesize activityInfo; +@synthesize contextInfo; + +/** + * Init. + */ +- (id)init +{ + if ((self = [super init])) { + mainStringColor = [NSColor blackColor]; + subStringColor = [NSColor grayColor]; + activityName = nil; + activityInfo = nil; + cancelButton = nil; + contextInfo = nil; + drawState = SPLinkDrawStateNormal; + + cancelButton = [[NSButtonCell alloc] init]; + [cancelButton setButtonType:NSMomentaryChangeButton]; + [cancelButton setImagePosition:NSImageRight]; + [cancelButton setTitle:@""]; + [cancelButton setBordered:NO]; + [cancelButton setShowsBorderOnlyWhileMouseInside:YES]; + [cancelButton setImage:[NSImage imageNamed:@"link-arrow"]]; + [cancelButton setAlternateImage:[NSImage imageNamed:@"link-arrow-clicked"]]; + } + + return self; +} + +/** + * Encodes using a given receiver. + */ +- (void) encodeWithCoder:(NSCoder *)coder +{ + [super encodeWithCoder:coder]; +} + +- (id)copyWithZone:(NSZone *)zone +{ + SPActivityTextFieldCell *cell = (SPActivityTextFieldCell *)[super copyWithZone:zone]; + + cell->activityName = nil; + if (activityName) cell->activityName = [activityName copyWithZone:zone]; + + cell->activityInfo = nil; + if (activityInfo) cell->activityInfo = [activityInfo copyWithZone:zone]; + + cell->contextInfo = nil; + if (contextInfo) cell->contextInfo = [contextInfo copyWithZone:zone]; + + cell->cancelButton = nil; + if (cancelButton) cell->cancelButton = [cancelButton copyWithZone:zone]; + + return cell; +} + + +/** + * Draws the actual cell. + */ +- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView +{ + + [cancelButton setEnabled:(contextInfo != nil)]; + + (([self isHighlighted]) && (![[self highlightColorWithFrame:cellFrame inView:controlView] isEqualTo:[NSColor secondarySelectedControlColor]])) ? [self invertFontColors] : [self restoreFontColors]; + + // Construct and get the sub text attributed string + NSAttributedString *mainString = [self attributedStringForFavoriteName]; + NSAttributedString *subString = [self constructSubStringAttributedString]; + + NSRect subFrame = NSMakeRect(0.0, 0.0, [subString size].width, [subString size].height); + + // Total height of both strings with a 2 pixel separation space + CGFloat totalHeight = [mainString size].height + [subString size].height + 1.0; + + cellFrame.origin.y += (cellFrame.size.height - totalHeight) / 2.0; + cellFrame.origin.x += 10.0; // Indent main string from image + + // Position the sub text's frame rect + subFrame.origin.y = [mainString size].height + cellFrame.origin.y + 1.0; + subFrame.origin.x = cellFrame.origin.x; + + cellFrame.size.height = totalHeight; + + NSInteger i; + CGFloat maxWidth = cellFrame.size.width - 30; + CGFloat mainStringWidth = [mainString size].width; + CGFloat subStringWidth = [subString size].width; + + // Set a right-padding + maxWidth -= 10; + + if (maxWidth < mainStringWidth) { + for (i = 0; i <= [mainString length]; i++) { + if ([[mainString attributedSubstringFromRange:NSMakeRange(0, i)] size].width >= maxWidth && i >= 3) { + mainString = [[[NSMutableAttributedString alloc] initWithString:[[[mainString attributedSubstringFromRange:NSMakeRange(0, i - 3)] string] stringByAppendingString:@"..."] attributes:[self mainStringAttributedStringAttributes]] autorelease]; + } + } + } + + if (maxWidth < subStringWidth) { + for (i = 0; i <= [subString length]; i++) { + if ([[subString attributedSubstringFromRange:NSMakeRange(0, i)] size].width >= maxWidth && i >= 3) { + subString = [[[NSMutableAttributedString alloc] initWithString:[[[subString attributedSubstringFromRange:NSMakeRange(0, i - 3)] string] stringByAppendingString:@"..."] attributes:[self subStringAttributedStringAttributes]] autorelease]; + } + } + } + + [mainString drawInRect:NSMakeRect(cellFrame.origin.x, cellFrame.origin.y, cellFrame.size.width-30, cellFrame.size.height)]; + [subString drawInRect:subFrame]; + + NSRect linkRect = SPTextLinkRectFromCellRect(cellFrame); + + // Get the new link state + NSInteger newDrawState = ([self isHighlighted])? + ((([(NSTableView *)[self controlView] editedColumn] != -1 + || [[[self controlView] window] firstResponder] == [self controlView]) + && [[[self controlView] window] isKeyWindow])?SPLinkDrawStateHighlight:SPLinkDrawStateBackgroundHighlight): + SPLinkDrawStateNormal; + + // Update the link arrow style if the state has changed + if (drawState != newDrawState) { + drawState = newDrawState; + switch (drawState) { + case SPLinkDrawStateNormal: + [cancelButton setImage:[NSImage imageNamed:@"link-arrow"]]; + [cancelButton setAlternateImage:[NSImage imageNamed:@"link-arrow-clicked"]]; + break; + case SPLinkDrawStateHighlight: + [cancelButton setImage:[NSImage imageNamed:@"link-arrow-highlighted"]]; + [cancelButton setAlternateImage:[NSImage imageNamed:@"link-arrow-highlighted-clicked"]]; + break; + case SPLinkDrawStateBackgroundHighlight: + [cancelButton setImage:[NSImage imageNamed:@"link-arrow-clicked"]]; + [cancelButton setAlternateImage:[NSImage imageNamed:@"link-arrow"]]; + break; + } + } + + [cancelButton drawWithFrame:linkRect inView:controlView]; +} + +- (NSRect)expansionFrameWithFrame:(NSRect)cellFrame inView:(NSView *)view +{ + return NSZeroRect; +} + +/** + * Allow hit tracking for cancel functionality + */ +- (NSUInteger)hitTestForEvent:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView +{ + return NSCellHitContentArea | NSCellHitTrackableArea; +} + +/** + * Allow mouse tracking within the button cell, to support expected click + * behaviour in the button cell. + */ +- (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)untilMouseUp +{ + + NSPoint p = [controlView convertPoint:[theEvent locationInWindow] fromView:nil]; + NSRect linkRect = SPTextLinkRectFromCellRect(cellFrame); + linkRect.origin.x += 15; + + // Fast path for if not in button rect - just pass to super + if (!NSMouseInRect(p, linkRect, [controlView isFlipped])) + return [super trackMouse:theEvent inRect:cellFrame ofView:controlView untilMouseUp:untilMouseUp]; + + // Ignore events other than mouse down. + if ([theEvent type] != NSLeftMouseDown) return YES; + + // Continue tracking the mouse while it's down, updating the state as it enters and leaves the cell, + // until it is released; if still within the cell, follow the link. + BOOL mouseInButton = YES; + while (1) { + if (mouseInButton) { + + // Highlight the button + [cancelButton highlight:YES withFrame:linkRect inView:controlView]; + + // Continue to track until mouse completes a click or exits the cell while still down + BOOL mouseClicked = [cancelButton trackMouse:theEvent inRect:linkRect ofView:controlView untilMouseUp:NO]; + if (mouseClicked) { + + // Remove highlight, and follow the link + [cancelButton highlight:NO withFrame:linkRect inView:controlView]; + + // Cancel activity + if([contextInfo objectForKey:@"type"] && [[contextInfo objectForKey:@"type"] isEqualToString:@"bashcommand"]) { + NSInteger pid = [[contextInfo objectForKey:@"pid"] intValue]; + if(pid > 0) { + NSTask *killTask = [[NSTask alloc] init]; + [killTask setLaunchPath:@"/bin/sh"]; + [killTask setArguments:[NSArray arrayWithObjects:@"-c", [NSString stringWithFormat:@"kill -9 -%ld", pid], nil]]; + [killTask launch]; + [killTask waitUntilExit]; + [killTask release]; + } + } + return YES; + } + + // Mouse has exited the cell. Remove highlight. + mouseInButton = NO; + [cancelButton highlight:NO withFrame:linkRect inView:controlView]; + } + + // Keep tracking the mouse outside the button, until the mouse button is released or it reenters the button + theEvent = [[controlView window] nextEventMatchingMask: NSLeftMouseUpMask | NSLeftMouseDraggedMask]; + p = [controlView convertPoint:[theEvent locationInWindow] fromView:nil]; + mouseInButton = NSMouseInRect(p, linkRect, [controlView isFlipped]); + + // If the event is a mouse release, break the loop. + if ([theEvent type] == NSLeftMouseUp) break; + } + + return YES; +} + +- (NSSize)cellSize +{ + NSSize cellSize = [super cellSize]; + NSAttributedString *mainString = [self attributedStringForFavoriteName]; + NSAttributedString *subString = [self constructSubStringAttributedString]; + + // 15 := indention 10 from image to string plus 5 px padding + CGFloat theWidth = MAX([mainString size].width, [subString size].width) + (([self image] != nil) ? [[self image] size].width : 0) + 15; + + CGFloat totalHeight = [mainString size].height + [subString size].height + 1.0; + + cellSize.width = theWidth; + cellSize.height = totalHeight + 13.0; + return cellSize; +} + +/** + * Inverts the displayed font colors when the cell is selected. + */ +- (void)invertFontColors +{ + mainStringColor = [NSColor whiteColor]; + subStringColor = [NSColor whiteColor]; +} + +/** + * Restores the displayed font colors once the cell is no longer selected. + */ +- (void)restoreFontColors +{ + mainStringColor = [NSColor blackColor]; + subStringColor = [NSColor grayColor]; +} + +/** + * Dealloc. + */ +- (void)dealloc +{ + if(activityName) [activityName release], activityName = nil; + if(activityInfo) [activityInfo release], activityInfo = nil; + if(contextInfo) [contextInfo release], contextInfo = nil; + if(cancelButton) [cancelButton release]; + + [super dealloc]; +} + +@end + +@implementation SPActivityTextFieldCell (PrivateAPI) + +/** + * Constructs the attributed string to be used as the cell's substring. + */ +- (NSAttributedString *)constructSubStringAttributedString +{ + return [[[NSAttributedString alloc] initWithString:activityInfo attributes:[self subStringAttributedStringAttributes]] autorelease]; +} + +/** + * Constructs the attributed string for the cell's favorite name. + */ +- (NSAttributedString *)attributedStringForFavoriteName +{ + return [[[NSAttributedString alloc] initWithString:activityName attributes:[self mainStringAttributedStringAttributes]] autorelease]; +} + +/** + * Returns the attributes of the cell's main string. + */ +- (NSDictionary *)mainStringAttributedStringAttributes +{ + return [NSDictionary dictionaryWithObjectsAndKeys:mainStringColor, NSForegroundColorAttributeName, [NSFont systemFontOfSize:FAVORITE_NAME_FONT_SIZE], NSFontAttributeName, nil]; +} + +/** + * Returns the attributes of the cell's sub string. + */ +- (NSDictionary *)subStringAttributedStringAttributes +{ + return [NSDictionary dictionaryWithObjectsAndKeys:subStringColor, NSForegroundColorAttributeName, [NSFont systemFontOfSize:[NSFont smallSystemFontSize]], NSFontAttributeName, nil]; +} + +@end diff --git a/Source/SPAppController.h b/Source/SPAppController.h index d96af12f..2fb4aef2 100644 --- a/Source/SPAppController.h +++ b/Source/SPAppController.h @@ -50,7 +50,7 @@ NSMutableDictionary *bundleKeyEquivalents; NSMutableDictionary *installedBundleUUIDs; - NSMutableArray *runningBASHprocesses; + NSMutableArray *runningActivitiesArray; } @@ -97,9 +97,9 @@ - (NSArray *)bundleCategoriesForScope:(NSString*)scope; - (NSArray *)bundleItemsForScope:(NSString*)scope; - (NSDictionary *)bundleKeyEquivalentsForScope:(NSString*)scope; -- (void)registerBASHCommand:(NSDictionary*)commandDict; -- (void)unRegisterBASHCommand:(NSInteger)pid; -- (NSArray*)runningBASHProcesses; +- (void)registerActivity:(NSDictionary*)commandDict; +- (void)removeRegisteredActivity:(NSInteger)pid; +- (NSArray*)runningActivities; - (void)handleEventWithURL:(NSURL*)url; diff --git a/Source/SPAppController.m b/Source/SPAppController.m index ad456b89..67d0427f 100644 --- a/Source/SPAppController.m +++ b/Source/SPAppController.m @@ -57,7 +57,7 @@ bundleUsedScopes = [[NSMutableArray alloc] initWithCapacity:1]; bundleKeyEquivalents = [[NSMutableDictionary alloc] initWithCapacity:1]; installedBundleUUIDs = [[NSMutableDictionary alloc] initWithCapacity:1]; - runningBASHprocesses = [[NSMutableArray alloc] init]; + runningActivitiesArray = [[NSMutableArray alloc] init]; [NSApp setDelegate:self]; } @@ -781,7 +781,14 @@ return; } - NSString *output = [cmd runBashCommandWithEnvironment:env atCurrentDirectoryPath:nil callerDocument:self withName:([cmdData objectForKey:SPBundleFileNameKey])?[cmdData objectForKey:SPBundleFileNameKey]:@"" error:&err]; + NSString *output = [cmd runBashCommandWithEnvironment:env + atCurrentDirectoryPath:nil + callerInstance:self + contextInfo:[NSDictionary dictionaryWithObjectsAndKeys: + ([cmdData objectForKey:SPBundleFileNameKey])?:@"-", @"name", + NSLocalizedString(@"General", @"general menu item label"), @"scope", + nil] + error:&err]; [[NSFileManager defaultManager] removeItemAtPath:bundleInputFilePath error:nil]; @@ -832,24 +839,24 @@ } -- (void)registerBASHCommand:(NSDictionary*)commandDict +- (void)registerActivity:(NSDictionary*)commandDict { - [runningBASHprocesses addObject:commandDict]; + [runningActivitiesArray addObject:commandDict]; } -- (void)unRegisterBASHCommand:(NSInteger)pid +- (void)removeRegisteredActivity:(NSInteger)pid { - for(id cmd in runningBASHprocesses) { + for(id cmd in runningActivitiesArray) { if([[cmd objectForKey:@"pid"] integerValue] == pid) { - [runningBASHprocesses removeObject:cmd]; + [runningActivitiesArray removeObject:cmd]; break; } } } -- (NSArray*)runningBASHProcesses +- (NSArray*)runningActivities { - return (NSArray*)runningBASHprocesses; + return (NSArray*)runningActivitiesArray; } #pragma mark - @@ -1538,7 +1545,7 @@ for (NSWindow *aWindow in [NSApp orderedWindows]) { if([[aWindow windowController] isMemberOfClass:[SPWindowController class]]) { for(SPDatabaseDocument *doc in [[aWindow windowController] documents]) { - for(NSDictionary* cmd in [doc runningBASHProcesses]) { + for(NSDictionary* cmd in [doc runningActivities]) { NSInteger pid = [[cmd objectForKey:@"pid"] intValue]; NSTask *killTask = [[NSTask alloc] init]; [killTask setLaunchPath:@"/bin/sh"]; @@ -1550,7 +1557,7 @@ } } } - for(NSDictionary* cmd in [self runningBASHProcesses]) { + for(NSDictionary* cmd in [self runningActivities]) { NSInteger pid = [[cmd objectForKey:@"pid"] intValue]; NSTask *killTask = [[NSTask alloc] init]; [killTask setLaunchPath:@"/bin/sh"]; @@ -1577,7 +1584,7 @@ if(bundleCategories) [bundleCategories release]; if(bundleKeyEquivalents) [bundleKeyEquivalents release]; if(installedBundleUUIDs) [installedBundleUUIDs release]; - if (runningBASHprocesses) [runningBASHprocesses release]; + if (runningActivitiesArray) [runningActivitiesArray release]; [prefsController release], prefsController = nil; diff --git a/Source/SPConstants.h b/Source/SPConstants.h index fce149f0..5327fd45 100644 --- a/Source/SPConstants.h +++ b/Source/SPConstants.h @@ -358,6 +358,7 @@ extern NSString *SPNoBOMforSQLdumpFile; extern NSString *SPContentFilters; extern NSString *SPDocumentTaskEndNotification; extern NSString *SPDocumentTaskStartNotification; +extern NSString *SPActivitiesUpdateNotification; extern NSString *SPFieldEditorSheetFont; extern NSString *SPLastSQLFileEncoding; extern NSString *SPPrintBackground; diff --git a/Source/SPConstants.m b/Source/SPConstants.m index 2ab44912..495a7580 100644 --- a/Source/SPConstants.m +++ b/Source/SPConstants.m @@ -170,6 +170,7 @@ NSString *SPNoBOMforSQLdumpFile = @"NoBOMforSQLdumpFile"; NSString *SPContentFilters = @"ContentFilters"; NSString *SPDocumentTaskEndNotification = @"DocumentTaskEnded"; NSString *SPDocumentTaskStartNotification = @"DocumentTaskStarted"; +NSString *SPActivitiesUpdateNotification = @"ActivitiesUpdateNotification"; NSString *SPFieldEditorSheetFont = @"FieldEditorSheetFont"; NSString *SPLastSQLFileEncoding = @"lastSqlFileEncoding"; NSString *SPPrintBackground = @"PrintBackground"; diff --git a/Source/SPCopyTable.m b/Source/SPCopyTable.m index 94e0eb45..86fb9d85 100644 --- a/Source/SPCopyTable.m +++ b/Source/SPCopyTable.m @@ -923,7 +923,14 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; return; } - NSString *output = [cmd runBashCommandWithEnvironment:env atCurrentDirectoryPath:nil callerDocument:[[NSApp delegate] frontDocument] withName:([cmdData objectForKey:SPBundleFileNameKey])?[cmdData objectForKey:SPBundleFileNameKey]:@"" error:&err]; + NSString *output = [cmd runBashCommandWithEnvironment:env + atCurrentDirectoryPath:nil + callerInstance:[[NSApp delegate] frontDocument] + contextInfo:[NSDictionary dictionaryWithObjectsAndKeys: + ([cmdData objectForKey:SPBundleFileNameKey])?:@"-", @"name", + NSLocalizedString(@"Data Table", @"data table menu item label"), @"scope", + nil] + error:&err]; [[NSFileManager defaultManager] removeItemAtPath:bundleInputFilePath error:nil]; diff --git a/Source/SPDatabaseDocument.h b/Source/SPDatabaseDocument.h index 16330b39..57131de8 100644 --- a/Source/SPDatabaseDocument.h +++ b/Source/SPDatabaseDocument.h @@ -189,7 +189,7 @@ NSMutableDictionary *spfPreferences; NSMutableDictionary *spfDocData; - NSMutableArray *runningBASHprocesses; + NSMutableArray *runningActivitiesArray; NSString *keyChainID; @@ -357,9 +357,9 @@ // Scripting - (void)handleSchemeCommand:(NSDictionary*)commandDict; -- (void)registerBASHCommand:(NSDictionary*)commandDict; -- (void)unRegisterBASHCommand:(NSInteger)pid; -- (NSArray*)runningBASHProcesses; +- (void)registerActivity:(NSDictionary*)commandDict; +- (void)removeRegisteredActivity:(NSInteger)pid; +- (NSArray*)runningActivities; - (NSDictionary*)shellVariables; // State saving and setting diff --git a/Source/SPDatabaseDocument.m b/Source/SPDatabaseDocument.m index b71ef8f8..309679fe 100644 --- a/Source/SPDatabaseDocument.m +++ b/Source/SPDatabaseDocument.m @@ -116,7 +116,7 @@ spfSession = nil; spfPreferences = [[NSMutableDictionary alloc] init]; spfDocData = [[NSMutableDictionary alloc] init]; - runningBASHprocesses = [[NSMutableArray alloc] init]; + runningActivitiesArray = [[NSMutableArray alloc] init]; titleAccessoryView = nil; taskProgressWindow = nil; @@ -3675,7 +3675,7 @@ } // Terminate all running BASH commands - for(NSDictionary* cmd in [self runningBASHProcesses]) { + for(NSDictionary* cmd in [self runningActivities]) { NSInteger pid = [[cmd objectForKey:@"pid"] intValue]; NSTask *killTask = [[NSTask alloc] init]; [killTask setLaunchPath:@"/bin/sh"]; @@ -4757,24 +4757,24 @@ NSLog(@"received: %@", commandDict); } -- (void)registerBASHCommand:(NSDictionary*)commandDict +- (void)registerActivity:(NSDictionary*)commandDict { - [runningBASHprocesses addObject:commandDict]; + [runningActivitiesArray addObject:commandDict]; } -- (void)unRegisterBASHCommand:(NSInteger)pid +- (void)removeRegisteredActivity:(NSInteger)pid { - for(id cmd in runningBASHprocesses) { + for(id cmd in runningActivitiesArray) { if([[cmd objectForKey:@"pid"] integerValue] == pid) { - [runningBASHprocesses removeObject:cmd]; + [runningActivitiesArray removeObject:cmd]; break; } } } -- (NSArray*)runningBASHProcesses +- (NSArray*)runningActivities { - return (NSArray*)runningBASHprocesses; + return (NSArray*)runningActivitiesArray; } - (NSDictionary*)shellVariables @@ -5077,7 +5077,7 @@ if (taskProgressWindow) [taskProgressWindow release]; if (serverSupport) [serverSupport release]; if (processID) [processID release]; - if (runningBASHprocesses) [runningBASHprocesses release]; + if (runningActivitiesArray) [runningActivitiesArray release]; [super dealloc]; } diff --git a/Source/SPStringAdditions.h b/Source/SPStringAdditions.h index b0e085aa..042e69f0 100644 --- a/Source/SPStringAdditions.h +++ b/Source/SPStringAdditions.h @@ -77,7 +77,7 @@ static inline id NSMutableAttributedStringAttributeAtIndex (NSMutableAttributedS - (CGFloat)levenshteinDistanceWithWord:(NSString *)stringB; -- (NSString *)runBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atCurrentDirectoryPath:(NSString*)path callerDocument:(id)caller withName:(NSString*)name error:(NSError**)theError; +- (NSString *)runBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atCurrentDirectoryPath:(NSString*)path callerInstance:(id)caller contextInfo:(NSDictionary*)contextInfo error:(NSError**)theError; - (NSString *)runBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atCurrentDirectoryPath:(NSString*)path error:(NSError**)theError; @end diff --git a/Source/SPStringAdditions.m b/Source/SPStringAdditions.m index 658baadb..27b8fcd0 100644 --- a/Source/SPStringAdditions.m +++ b/Source/SPStringAdditions.m @@ -451,7 +451,7 @@ * @param theError If not nil and the bash command failed it contains the returned error message as NSLocalizedDescriptionKey * */ -- (NSString *)runBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atCurrentDirectoryPath:(NSString*)path callerDocument:(id)caller withName:(NSString*)name error:(NSError**)theError +- (NSString *)runBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atCurrentDirectoryPath:(NSString*)path callerInstance:(id)caller contextInfo:(NSDictionary*)contextInfo error:(NSError**)theError { BOOL userTerminated = NO; @@ -549,14 +549,16 @@ NSFileHandle *stderr_file = [stderr_pipe fileHandleForReading]; [bashTask launch]; NSInteger pid = -1; - if(caller != nil && [caller respondsToSelector:@selector(registerBASHCommand:)]) { + if(caller != nil && [caller respondsToSelector:@selector(registerActivity:)]) { // register command pid = [bashTask processIdentifier]; NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInteger:pid], @"pid", - name, @"name", + (contextInfo)?:[NSDictionary dictionary], @"contextInfo", + @"bashcommand", @"type", [[NSDate date] descriptionWithCalendarFormat:@"%H:%M:%S" timeZone:nil locale:[[NSUserDefaults standardUserDefaults] dictionaryRepresentation]], @"starttime", nil]; - [caller registerBASHCommand:dict]; + [caller registerActivity:dict]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:SPActivitiesUpdateNotification object:nil]; } // Listen to ⌘. to terminate @@ -584,15 +586,12 @@ [bashTask waitUntilExit]; // unregister BASH command if it was registered - if(pid >= 0) [caller unRegisterBASHCommand:pid]; - - if(userTerminated) { - if(bashTask) [bashTask release]; - NSBeep(); - NSLog(@"“%@” was terminated by user.", ([self length] > 50) ? [self substringToIndex:50] : self); - return @""; + if(pid >= 0) { + [caller removeRegisteredActivity:pid]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:SPActivitiesUpdateNotification object:nil]; } + // Remove script file if used if(redirectForScript) [[NSFileManager defaultManager] removeItemAtPath:scriptFilePath error:nil]; diff --git a/Source/SPTableInfo.h b/Source/SPTableInfo.h index bae3da4e..8663ac6a 100644 --- a/Source/SPTableInfo.h +++ b/Source/SPTableInfo.h @@ -38,6 +38,7 @@ NSMutableArray *info; NSMutableArray *activities; + BOOL _activitiesWillBeUpdated; } - (void)tableChanged:(NSNotification *)notification; diff --git a/Source/SPTableInfo.m b/Source/SPTableInfo.m index ba24040a..3dc64b01 100644 --- a/Source/SPTableInfo.m +++ b/Source/SPTableInfo.m @@ -27,6 +27,8 @@ #import "SPDatabaseDocument.h" #import "SPTablesList.h" #import "SPTableData.h" +#import "SPActivityTextFieldCell.h" +#import "SPTableTextFieldCell.h" @interface SPTableInfo (PrivateAPI) @@ -41,6 +43,7 @@ if ((self = [super init])) { info = [[NSMutableArray alloc] init]; activities = [[NSMutableArray alloc] init]; + _activitiesWillBeUpdated = NO; } return self; @@ -48,19 +51,26 @@ - (void)awakeFromNib { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(tableChanged:) name:SPTableChangedNotification object:tableDocumentInstance]; - [tableInfoScrollView setAlphaValue:1.0f]; - [activitiesScrollView setAlphaValue:0.0f]; + // Register activities update notifications for add/remove BASH commands etc. + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(updateActivities) + name:SPActivitiesUpdateNotification + object:nil]; - // [self performSelector:@selector(updateActivities) withObject:nil afterDelay:1.0f]; + [tableInfoScrollView setHidden:NO]; + [activitiesScrollView setHidden:YES]; + // Add activities header [activities addObject:[NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"ACTIVITIES", @"header for activities pane"), @"name", nil]]; [activitiesTable reloadData]; + // Add Information header [info addObject:NSLocalizedString(@"TABLE INFORMATION", @"header for table info pane")]; [infoTable reloadData]; } @@ -80,11 +90,14 @@ NSMutableArray *acts = [NSMutableArray array]; [acts removeAllObjects]; [acts addObject:[NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"ACTIVITIES", @"header for activities pane"), @"name", nil]]; - [acts addObjectsFromArray:[tableDocumentInstance runningBASHProcesses]]; - [acts addObjectsFromArray:[[NSApp delegate] runningBASHProcesses]]; + [acts addObjectsFromArray:[tableDocumentInstance runningActivities]]; + [acts addObjectsFromArray:[[NSApp delegate] runningActivities]]; + _activitiesWillBeUpdated = YES; [activities setArray:acts]; + _activitiesWillBeUpdated = NO; [activitiesTable reloadData]; - // [self performSelector:@selector(updateActivities) withObject:nil afterDelay:1.0f]; + [infoTable deselectAll:nil]; + [activitiesTable deselectAll:nil]; } /** @@ -285,10 +298,33 @@ if(aTableView == infoTable) { return [info objectAtIndex:rowIndex]; } else { - if(rowIndex > -1 && rowIndex < [activities count]) - return [NSArrayObjectAtIndex(activities,rowIndex) objectForKey:@"name"]; - else + if(rowIndex == 0) + { + SPTableTextFieldCell *c = [[[SPTableTextFieldCell alloc] initTextCell:NSLocalizedString(@"ACTIVITIES", @"header for activities pane")] autorelease]; + [aTableColumn setDataCell:c]; + return NSLocalizedString(@"ACTIVITIES", @"header for activities pane"); + } + else if(!_activitiesWillBeUpdated && rowIndex > 0 && rowIndex < [activities count]) { + NSDictionary *dict = NSArrayObjectAtIndex(activities,rowIndex); + SPActivityTextFieldCell *c = [[[SPActivityTextFieldCell alloc] init] autorelease]; + [c setActivityName:[[dict objectForKey:@"contextInfo"] objectForKey:@"name"]]; + if([dict objectForKey:@"type"] && [[dict objectForKey:@"type"] isEqualToString:@"bashcommand"]) { + [c setContextInfo:[NSDictionary dictionaryWithObjectsAndKeys:[dict objectForKey:@"type"], @"type", [dict objectForKey:@"pid"], @"pid", nil]]; + [c setActivityInfo:[NSString stringWithFormat:@"[%@] %@: %@", [[dict objectForKey:@"contextInfo"] objectForKey:@"scope"], NSLocalizedString(@"started", @"started"), [dict objectForKey:@"starttime"]]]; + } + else { + [c setActivityInfo:@"..."]; + } + [aTableColumn setDataCell:c]; + return [dict objectForKey:@"name"]; + } else { + SPActivityTextFieldCell *c = [[[SPActivityTextFieldCell alloc] init] autorelease]; + [c setActivityName:@"..."]; + [c setActivityInfo:@""]; + [aTableColumn setDataCell:c]; return @"..."; + } + return @""; } } @@ -300,28 +336,51 @@ - (BOOL)tableView:(NSTableView *)aTableView shouldSelectRow:(NSInteger)rowIndex { if(rowIndex == 0) return YES; + if(aTableView == infoTable) { + return NO; + } else { + return YES; + } return NO; } - (BOOL)tableView:(NSTableView *)aTableView shouldEditTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex { if(rowIndex > 0) return NO; - if([tableInfoScrollView alphaValue] == 1.0f) { - [tableInfoScrollView setAlphaValue:0.0f]; - [activitiesScrollView setAlphaValue:1.0f]; + + if(![tableInfoScrollView isHidden]) { + [tableInfoScrollView setHidden:YES]; + [activitiesScrollView setHidden:NO]; + [[NSApp mainWindow] makeFirstResponder:activitiesTable]; } else { - [tableInfoScrollView setAlphaValue:1.0f]; - [activitiesScrollView setAlphaValue:0.0f]; + [activitiesScrollView setHidden:YES]; + [tableInfoScrollView setHidden:NO]; + [[NSApp mainWindow] makeFirstResponder:infoTable]; } + [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 +{ + if(aTableView == activitiesTable) { + if(rowIndex == 0) return @""; + if(mouseLocation.x > rect->origin.x + rect->size.width - 30) + return NSLocalizedString(@"Cancel", @"cancel"); + NSDictionary *dict = NSArrayObjectAtIndex(activities,rowIndex); + if([[dict objectForKey:@"contextInfo"] objectForKey:@"name"]) + return [[dict objectForKey:@"contextInfo"] objectForKey:@"name"]; + return @""; + } + return nil; +} + - (BOOL)tableView:(NSTableView *)aTableView isGroupRow:(NSInteger)row { - // This makes the top row (TABLE INFORMATION) have the diff styling + // This makes the top row (TABLE INFORMATION/ACTIVITIES) have the diff styling return (row == 0); } diff --git a/Source/SPTableTextFieldCell.m b/Source/SPTableTextFieldCell.m index bcfa0138..33508517 100644 --- a/Source/SPTableTextFieldCell.m +++ b/Source/SPTableTextFieldCell.m @@ -56,6 +56,11 @@ } +- (NSRect)expansionFrameWithFrame:(NSRect)cellFrame inView:(NSView *)view +{ + return NSMakeRect(cellFrame.origin.x, cellFrame.origin.y, [self cellSize].width, [self cellSize].height); +} + - (NSSize)cellSize { NSSize cellSize = [super cellSize]; diff --git a/Source/SPTextViewAdditions.m b/Source/SPTextViewAdditions.m index e613dac1..70548bf3 100644 --- a/Source/SPTextViewAdditions.m +++ b/Source/SPTextViewAdditions.m @@ -603,7 +603,14 @@ return; } - NSString *output = [cmd runBashCommandWithEnvironment:env atCurrentDirectoryPath:nil callerDocument:[[NSApp delegate] frontDocument] withName:([cmdData objectForKey:SPBundleFileNameKey])?[cmdData objectForKey:SPBundleFileNameKey]:@"" error:&err]; + NSString *output = [cmd runBashCommandWithEnvironment:env + atCurrentDirectoryPath:nil + callerInstance:[[NSApp delegate] frontDocument] + contextInfo:[NSDictionary dictionaryWithObjectsAndKeys: + ([cmdData objectForKey:SPBundleFileNameKey])?:@"-", @"name", + NSLocalizedString(@"Input Field", @"input field menu item label"), @"scope", + nil] + error:&err]; [[NSFileManager defaultManager] removeItemAtPath:bundleInputFilePath error:nil]; diff --git a/sequel-pro.xcodeproj/project.pbxproj b/sequel-pro.xcodeproj/project.pbxproj index 5283eb72..97c6b3e8 100644 --- a/sequel-pro.xcodeproj/project.pbxproj +++ b/sequel-pro.xcodeproj/project.pbxproj @@ -395,6 +395,7 @@ BC34F3281292AD6F000DA1AA /* SPConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 173284E91088FEDE0062E892 /* SPConstants.m */; }; BC398A2D121D526200BE3EF4 /* SPCopyTable.m in Sources */ = {isa = PBXBuildFile; fileRef = BC398A2C121D526200BE3EF4 /* SPCopyTable.m */; }; BC4DF1981158FB280059FABD /* SPNavigatorOutlineView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC4DF1971158FB280059FABD /* SPNavigatorOutlineView.m */; }; + BC5750D512A6233900911BA2 /* SPActivityTextFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BC5750D312A6233900911BA2 /* SPActivityTextFieldCell.m */; }; BC5AD7FF10FB262F008769E3 /* field-small-square.tiff in Resources */ = {isa = PBXBuildFile; fileRef = BC5AD7FE10FB262F008769E3 /* field-small-square.tiff */; }; BC65C3B2107CE3EE003F7B02 /* ImportAccessory.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC65C3B0107CE3EE003F7B02 /* ImportAccessory.xib */; }; BC675A141072039C00C5ACD4 /* SPContentFilterManager.m in Sources */ = {isa = PBXBuildFile; fileRef = BC675A131072039C00C5ACD4 /* SPContentFilterManager.m */; }; @@ -1119,6 +1120,8 @@ BC398A2C121D526200BE3EF4 /* SPCopyTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPCopyTable.m; sourceTree = ""; }; BC4DF1961158FB280059FABD /* SPNavigatorOutlineView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPNavigatorOutlineView.h; sourceTree = ""; }; BC4DF1971158FB280059FABD /* SPNavigatorOutlineView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPNavigatorOutlineView.m; sourceTree = ""; }; + BC5750D312A6233900911BA2 /* SPActivityTextFieldCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPActivityTextFieldCell.m; sourceTree = ""; }; + BC5750D412A6233900911BA2 /* SPActivityTextFieldCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPActivityTextFieldCell.h; sourceTree = ""; }; BC5AD7FE10FB262F008769E3 /* field-small-square.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = "field-small-square.tiff"; sourceTree = ""; }; BC65C3B1107CE3EE003F7B02 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/ImportAccessory.xib; sourceTree = ""; }; BC675A121072039C00C5ACD4 /* SPContentFilterManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPContentFilterManager.h; sourceTree = ""; }; @@ -1342,6 +1345,8 @@ 171312CD109D23C700FB465F /* SPTableTextFieldCell.m */, B57747DA0F7A89D0003B34F9 /* SPFavoriteTextFieldCell.h */, B57747DB0F7A89D0003B34F9 /* SPFavoriteTextFieldCell.m */, + BC5750D312A6233900911BA2 /* SPActivityTextFieldCell.m */, + BC5750D412A6233900911BA2 /* SPActivityTextFieldCell.h */, ); name = Cells; sourceTree = ""; @@ -3123,6 +3128,7 @@ BC1944D01297291800A236CD /* SPBundleCommandTextView.m in Sources */, BC77C5E4129AA69E009AD832 /* SPBundleHTMLOutputController.m in Sources */, 58DC10D312A1B8DF00B76DA5 /* SPMenuAdditions.m in Sources */, + BC5750D512A6233900911BA2 /* SPActivityTextFieldCell.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; -- cgit v1.2.3