mirror of
https://github.com/textmate/textmate.git
synced 2026-04-28 03:00:34 -04:00
Update Open Favorite to use OakChooser
This commit is contained in:
@@ -353,11 +353,9 @@ BOOL HasDocumentWindow (NSArray* windows)
|
||||
|
||||
- (IBAction)openFavorites:(id)sender
|
||||
{
|
||||
OakFilterWindowController* controller = [OakFilterWindowController new];
|
||||
controller.dataSource = [FavoritesDataSource favoritesDataSource];
|
||||
controller.action = @selector(didSelectFavorite:);
|
||||
controller.allowsMultipleSelection = YES;
|
||||
[controller showWindow:self];
|
||||
FavoriteChooser* chooser = [FavoriteChooser sharedInstance];
|
||||
chooser.action = @selector(didSelectFavorite:);
|
||||
[chooser showWindow:self];
|
||||
}
|
||||
|
||||
- (void)didSelectFavorite:(id)sender
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#import <OakFilterList/OakFilterList.h>
|
||||
#import <text/ctype.h>
|
||||
#import <OakFilterList/OakChooser.h>
|
||||
|
||||
@interface FavoritesDataSource : NSObject <FilterListDataSource>
|
||||
+ (FavoritesDataSource*)favoritesDataSource;
|
||||
@property (nonatomic, readonly) NSString* filterString;
|
||||
@interface FavoriteChooser : OakChooser
|
||||
+ (instancetype)sharedInstance;
|
||||
@end
|
||||
|
||||
@@ -1,166 +1,139 @@
|
||||
#import "Favorites.h"
|
||||
#import <OakAppKit/OakUIConstructionFunctions.h>
|
||||
#import <OakFoundation/NSString Additions.h>
|
||||
#import <OakSystem/application.h>
|
||||
#import <text/ranker.h>
|
||||
#import <io/entries.h>
|
||||
#import <text/case.h>
|
||||
#import <text/ctype.h>
|
||||
#import <io/path.h>
|
||||
#import <ns/ns.h>
|
||||
|
||||
// ===================
|
||||
// = View Controller =
|
||||
// ===================
|
||||
|
||||
@interface FavoritesViewController : NSViewController
|
||||
@property (nonatomic, retain) NSSearchField* searchField;
|
||||
@property (nonatomic, retain) FavoritesDataSource* favoritesDataSource;
|
||||
@end
|
||||
|
||||
@implementation FavoritesViewController
|
||||
- (id)initWithFavoritesDataSource:(FavoritesDataSource*)aDataSource
|
||||
@interface FavoriteChooser ()
|
||||
{
|
||||
if(self = [super init])
|
||||
{
|
||||
self.favoritesDataSource = aDataSource;
|
||||
|
||||
self.searchField = [[NSSearchField alloc] initWithFrame:NSMakeRect(10, 10, 180, 22)];
|
||||
self.searchField.autoresizingMask = NSViewWidthSizable|NSViewMinYMargin;
|
||||
self.searchField.target = self.favoritesDataSource;
|
||||
self.searchField.action = @selector(search:);
|
||||
[self.searchField.cell setScrollable:YES];
|
||||
|
||||
self.view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 200, NSMaxY(self.searchField.frame) + 8)];
|
||||
self.view.autoresizingMask = NSViewWidthSizable|NSViewMinYMargin;
|
||||
[self.view addSubview:self.searchField];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
self.searchField.target = nil;
|
||||
self.searchField.action = NULL;
|
||||
}
|
||||
|
||||
- (void)setSearchFieldDelegate:(id)aDelegate
|
||||
{
|
||||
self.searchField.delegate = aDelegate;
|
||||
}
|
||||
@end
|
||||
|
||||
// ===============
|
||||
// = Data Source =
|
||||
// ===============
|
||||
|
||||
@implementation FavoritesDataSource
|
||||
{
|
||||
std::string favoritesPath;
|
||||
std::multimap<std::string, std::string, text::less_t> favorites;
|
||||
std::string filterString;
|
||||
FavoritesViewController* viewController;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation FavoriteChooser
|
||||
+ (instancetype)sharedInstance
|
||||
{
|
||||
static id sharedInstance = [self new];
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (NSViewController*)viewController
|
||||
- (id)init
|
||||
{
|
||||
if(!viewController)
|
||||
viewController = [[FavoritesViewController alloc] initWithFavoritesDataSource:self];
|
||||
return viewController;
|
||||
}
|
||||
|
||||
- (id)initWithCxxPath:(std::string const&)aPath
|
||||
{
|
||||
if(self = [super init])
|
||||
if((self = [super init]))
|
||||
{
|
||||
favoritesPath = aPath;
|
||||
filterString = "";
|
||||
self.window.title = @"Open Favorite";
|
||||
self.window.frameAutosaveName = @"Open Favorite";
|
||||
self.tableView.allowsMultipleSelection = YES;
|
||||
|
||||
citerate(entry, path::entries(favoritesPath))
|
||||
NSDictionary* views = @{
|
||||
@"searchField" : self.searchField,
|
||||
@"topDivider" : OakCreateHorizontalLine([NSColor grayColor], [NSColor lightGrayColor]),
|
||||
@"scrollView" : self.scrollView,
|
||||
@"bottomDivider" : OakCreateHorizontalLine([NSColor grayColor], [NSColor lightGrayColor]),
|
||||
@"statusTextField" : self.statusTextField,
|
||||
@"itemCountTextField" : self.itemCountTextField,
|
||||
};
|
||||
|
||||
NSView* contentView = self.window.contentView;
|
||||
for(NSView* view in [views allValues])
|
||||
{
|
||||
if((*entry)->d_type == DT_LNK)
|
||||
[view setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
[contentView addSubview:view];
|
||||
}
|
||||
|
||||
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(8)-[searchField(>=50)]-(8)-|" options:0 metrics:nil views:views]];
|
||||
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView(==topDivider,==bottomDivider)]|" options:0 metrics:nil views:views]];
|
||||
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[statusTextField]-[itemCountTextField]-|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:views]];
|
||||
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(2)-[searchField]-(8)-[topDivider][scrollView(>=50)][bottomDivider]-(4)-[statusTextField]-(5)-|" options:0 metrics:nil views:views]];
|
||||
|
||||
std::string const favoritesPath = oak::application_t::support("Favorites");
|
||||
for(auto const& entry : path::entries(favoritesPath))
|
||||
{
|
||||
if(entry->d_type == DT_LNK)
|
||||
{
|
||||
std::string const& path = path::resolve(path::join(favoritesPath, (*entry)->d_name));
|
||||
if(strncmp("[DIR] ", (*entry)->d_name, 6) == 0)
|
||||
std::string const path = path::resolve(path::join(favoritesPath, entry->d_name));
|
||||
if(strncmp("[DIR] ", entry->d_name, 6) == 0)
|
||||
{
|
||||
citerate(subentry, path::entries(path))
|
||||
for(auto const& subentry : path::entries(path))
|
||||
{
|
||||
if((*subentry)->d_type == DT_DIR)
|
||||
favorites.emplace(text::format("%s — %s", (*subentry)->d_name, (*entry)->d_name + 6), path::join(path, (*subentry)->d_name));
|
||||
if(subentry->d_type == DT_DIR)
|
||||
favorites.emplace(text::format("%s — %s", subentry->d_name, entry->d_name + 6), path::join(path, subentry->d_name));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
favorites.emplace((*entry)->d_name, path);
|
||||
favorites.emplace(entry->d_name, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[self updateItems:self];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (FavoritesDataSource*)favoritesDataSource
|
||||
- (void)showWindow:(id)sender
|
||||
{
|
||||
return [[self alloc] initWithCxxPath:oak::application_t::support("Favorites")];
|
||||
}
|
||||
|
||||
- (NSString*)title
|
||||
{
|
||||
return @"Open Favorite";
|
||||
}
|
||||
|
||||
- (NSString*)filterString
|
||||
{
|
||||
return [NSString stringWithCxxString:filterString];
|
||||
}
|
||||
|
||||
- (IBAction)search:(id)sender
|
||||
{
|
||||
ASSERT([sender respondsToSelector:@selector(stringValue)]);
|
||||
NSString* objCStr = [[sender stringValue] lowercaseString] ?: @"";
|
||||
std::string const newFilterString = to_s(objCStr);
|
||||
if(newFilterString != filterString)
|
||||
if(![self.window isVisible])
|
||||
{
|
||||
filterString = newFilterString;
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:FLDataSourceItemsDidChangeNotification object:self];
|
||||
self.filterString = @"";
|
||||
if([self.tableView numberOfRows])
|
||||
[self.tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:0] byExtendingSelection:NO];
|
||||
}
|
||||
[super showWindow:sender];
|
||||
}
|
||||
|
||||
- (NSArray*)items
|
||||
- (void)updateItems:(id)sender
|
||||
{
|
||||
std::multimap< double, std::pair<std::string, std::string> > ranked;
|
||||
iterate(pair, favorites)
|
||||
std::string const filter = to_s(self.filterString);
|
||||
|
||||
std::multimap<double, NSDictionary*> ranked;
|
||||
for(auto const& pair : favorites)
|
||||
{
|
||||
if(filterString == "")
|
||||
if(filter == NULL_STR || filter == "")
|
||||
{
|
||||
ranked.emplace(ranked.size(), *pair);
|
||||
ranked.emplace(ranked.size(), @{
|
||||
@"name" : [NSString stringWithCxxString:pair.first],
|
||||
@"info" : [NSString stringWithCxxString:path::with_tilde(pair.second)],
|
||||
@"path" : [NSString stringWithCxxString:pair.second],
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
double rank = oak::rank(filterString, pair->first);
|
||||
std::vector<std::pair<size_t, size_t>> ranges;
|
||||
double rank = oak::rank(filter, pair.first, &ranges);
|
||||
if(rank > 0)
|
||||
ranked.emplace(-rank, *pair);
|
||||
{
|
||||
ranked.emplace(-rank, @{
|
||||
@"name" : CreateAttributedStringWithMarkedUpRanges(pair.first, ranges),
|
||||
@"info" : [NSString stringWithCxxString:path::with_tilde(pair.second)],
|
||||
@"path" : [NSString stringWithCxxString:pair.second],
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NSMutableArray* items = [NSMutableArray array];
|
||||
iterate(pair, ranked)
|
||||
NSMutableArray* res = [NSMutableArray array];
|
||||
for(auto const& pair : ranked)
|
||||
[res addObject:pair.second];
|
||||
self.items = res;
|
||||
}
|
||||
|
||||
- (void)updateStatusText:(id)sender
|
||||
{
|
||||
if(self.tableView.selectedRow != -1)
|
||||
{
|
||||
[items addObject:@{
|
||||
@"title" : [NSString stringWithCxxString:pair->second.first],
|
||||
@"path" : [NSString stringWithCxxString:pair->second.second],
|
||||
}];
|
||||
NSDictionary* item = self.items[self.tableView.selectedRow];
|
||||
self.statusTextField.stringValue = [item objectForKey:@"info"];
|
||||
}
|
||||
else
|
||||
{
|
||||
self.statusTextField.stringValue = @"";
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
- (NSAttributedString*)displayStringForItem:(id)anItem
|
||||
{
|
||||
std::string str = to_s((NSString*)[anItem objectForKey:@"title"]);
|
||||
return [[NSAttributedString alloc] initWithString:[NSString stringWithCxxString:str]];
|
||||
}
|
||||
|
||||
- (NSAttributedString*)infoStringForItem:(id)anItem
|
||||
{
|
||||
std::string str = path::with_tilde(to_s((NSString*)[anItem objectForKey:@"path"]));
|
||||
return [[NSAttributedString alloc] initWithString:[NSString stringWithCxxString:str]];
|
||||
}
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user