Refactoring Part 1: Dynamic menus (stable)
This commit is contained in:
@@ -1,52 +0,0 @@
|
||||
//
|
||||
// The MIT License (MIT)
|
||||
// Copyright (c) 2018 Oleg Geier
|
||||
//
|
||||
// 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.
|
||||
|
||||
#import "FeedConfig+CoreDataClass.h"
|
||||
|
||||
@class FeedItem;
|
||||
|
||||
@interface FeedConfig (Ext)
|
||||
/// Enum type to distinguish different @c FeedConfig types
|
||||
typedef enum int16_t {
|
||||
GROUP = 0,
|
||||
FEED = 1,
|
||||
SEPARATOR = 2
|
||||
} FeedConfigType;
|
||||
/**
|
||||
Iteration block for descendants of @c FeedItem.
|
||||
|
||||
@param parent The parent @c FeedConfig where this @c FeedItem belongs to.
|
||||
@param item Currently processed @c FeedItem.
|
||||
@return Return @c YES to continue processing. Return @c NO to stop processing and exit early.
|
||||
*/
|
||||
typedef BOOL (^FeedConfigRecursiveItemsBlock) (FeedConfig *parent, FeedItem *item);
|
||||
|
||||
@property (getter=typ, setter=setTyp:) FeedConfigType typ;
|
||||
@property (readonly) NSArray<FeedConfig*> *sortedChildren;
|
||||
@property (readonly) NSIndexPath *indexPath;
|
||||
|
||||
- (BOOL)descendantFeedItems:(FeedConfigRecursiveItemsBlock)block;
|
||||
- (void)calculateAndSetScheduled;
|
||||
- (void)mergeChangesAndSave;
|
||||
- (NSString*)readableRefreshString;
|
||||
- (NSString*)readableDescription;
|
||||
@end
|
||||
@@ -1,104 +0,0 @@
|
||||
//
|
||||
// The MIT License (MIT)
|
||||
// Copyright (c) 2018 Oleg Geier
|
||||
//
|
||||
// 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.
|
||||
|
||||
#import "FeedConfig+Ext.h"
|
||||
#import "Feed+CoreDataClass.h"
|
||||
|
||||
@implementation FeedConfig (Ext)
|
||||
/// Enum tpye getter see @c FeedConfigType
|
||||
- (FeedConfigType)typ { return (FeedConfigType)self.type; }
|
||||
/// Enum type setter see @c FeedConfigType
|
||||
- (void)setTyp:(FeedConfigType)typ { self.type = typ; }
|
||||
|
||||
/**
|
||||
Sorted children array based on sort order provided in feed settings.
|
||||
|
||||
@return Sorted array of @c FeedConfig items.
|
||||
*/
|
||||
- (NSArray<FeedConfig *> *)sortedChildren {
|
||||
if (self.children.count == 0)
|
||||
return nil;
|
||||
return [self.children sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"sortIndex" ascending:YES]]];
|
||||
}
|
||||
|
||||
- (NSIndexPath *)indexPath {
|
||||
if (self.parent == nil)
|
||||
return [NSIndexPath indexPathWithIndex:(NSUInteger)self.sortIndex];
|
||||
return [self.parent.indexPath indexPathByAddingIndex:(NSUInteger)self.sortIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
Iterate over all descendant @c FeedItems in sub groups
|
||||
|
||||
@param block Will yield the current parent config and feed item. Return @c NO to cancel iteration.
|
||||
@return Returns @c NO if the iteration was canceled early. Otherwise @c YES.
|
||||
*/
|
||||
- (BOOL)descendantFeedItems:(FeedConfigRecursiveItemsBlock)block {
|
||||
if (self.children.count > 0) {
|
||||
for (FeedConfig *config in self.sortedChildren) {
|
||||
if ([config descendantFeedItems:block] == NO)
|
||||
return NO;
|
||||
}
|
||||
} else if (self.feed.items.count > 0) {
|
||||
for (FeedItem* item in self.feed.items) {
|
||||
if (block(self, item) == NO)
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
/// @return Time interval respecting the selected unit. E.g., returns @c 180 for @c '3m'
|
||||
- (NSTimeInterval)timeInterval {
|
||||
static const int unit[] = {1, 60, 3600, 86400, 604800}; // smhdw
|
||||
return self.refreshNum * unit[self.refreshUnit % 5];
|
||||
}
|
||||
|
||||
/// Calculate date from @c refreshNum and @c refreshUnit and set as next scheduled feed update.
|
||||
- (void)calculateAndSetScheduled {
|
||||
self.scheduled = [[NSDate date] dateByAddingTimeInterval:[self timeInterval]];
|
||||
}
|
||||
|
||||
/// Update item with @c mergeChanges:YES and save the context
|
||||
- (void)mergeChangesAndSave {
|
||||
[self.managedObjectContext performBlockAndWait:^{
|
||||
[self.managedObjectContext refreshObject:self mergeChanges:YES];
|
||||
[self.managedObjectContext save:nil];
|
||||
}];
|
||||
}
|
||||
|
||||
/// @return Formatted string for update interval ( e.g., @c 30m or @c 12h )
|
||||
- (NSString*)readableRefreshString {
|
||||
return [NSString stringWithFormat:@"%d%c", self.refreshNum, [@"smhdw" characterAtIndex:self.refreshUnit % 5]];
|
||||
}
|
||||
|
||||
/// @return Simplified description of the feed object.
|
||||
- (NSString*)readableDescription {
|
||||
switch (self.typ) {
|
||||
case SEPARATOR: return @"-------------";
|
||||
case GROUP: return [NSString stringWithFormat:@"%@", self.name];
|
||||
case FEED:
|
||||
return [NSString stringWithFormat:@"%@ (%@) - %@", self.name, self.url, [self readableRefreshString]];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -109,22 +109,13 @@
|
||||
item.refreshUnit = (int16_t)self.refreshUnit.indexOfSelectedItem;
|
||||
|
||||
if (self.shouldDeletePrevArticles) {
|
||||
[StoreCoordinator overwriteConfig:item withFeed:self.feedResult];
|
||||
[item.managedObjectContext performBlockAndWait:^{
|
||||
// TODO: move to separate function and add icon download
|
||||
if (!item.meta) {
|
||||
item.meta = [[FeedMeta alloc] initWithEntity:FeedMeta.entity insertIntoManagedObjectContext:item.managedObjectContext];
|
||||
}
|
||||
item.meta.httpEtag = self.httpEtag;
|
||||
item.meta.httpModified = self.httpDate;
|
||||
}];
|
||||
[item updateRSSFeed:self.feedResult];
|
||||
[item setEtag:self.httpEtag modified:self.httpDate];
|
||||
}
|
||||
if ([item.managedObjectContext hasChanges]) {
|
||||
self.objectIsModified = YES;
|
||||
[item calculateAndSetScheduled];
|
||||
[item.managedObjectContext performBlockAndWait:^{
|
||||
[item.managedObjectContext refreshObject:item mergeChanges:YES];
|
||||
}];
|
||||
[item.managedObjectContext refreshObject:item mergeChanges:YES];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,9 +213,7 @@
|
||||
NSString *name = ((NSTextField*)self.view).stringValue;
|
||||
if (![item.name isEqualToString: name]) {
|
||||
item.name = name;
|
||||
[item.managedObjectContext performBlockAndWait:^{
|
||||
[item.managedObjectContext refreshObject:item mergeChanges:YES];
|
||||
}];
|
||||
[item.managedObjectContext refreshObject:item mergeChanges:YES];
|
||||
[self.delegate modalDidUpdateFeedConfig:item];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
// SOFTWARE.
|
||||
|
||||
#import "SettingsFeeds.h"
|
||||
#import "AppHook.h"
|
||||
#import "BarMenu.h"
|
||||
#import "ModalSheet.h"
|
||||
#import "ModalFeedEdit.h"
|
||||
@@ -47,27 +46,16 @@ static NSString *dragNodeType = @"baRSS-feed-drag";
|
||||
[self.outlineView registerForDraggedTypes:[NSArray arrayWithObject:dragNodeType]];
|
||||
[self.dataStore setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"sortIndex" ascending:YES]]];
|
||||
|
||||
NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
|
||||
[childContext setParentContext:[(AppHook*)NSApp persistentContainer].viewContext];
|
||||
// childContext.automaticallyMergesChangesFromParent = YES;
|
||||
NSUndoManager *um = [[NSUndoManager alloc] init];
|
||||
um.groupsByEvent = NO;
|
||||
um.levelsOfUndo = 30;
|
||||
childContext.undoManager = um;
|
||||
self.undoManager = [[NSUndoManager alloc] init];
|
||||
self.undoManager.groupsByEvent = NO;
|
||||
self.undoManager.levelsOfUndo = 30;
|
||||
|
||||
self.dataStore.managedObjectContext = childContext;
|
||||
self.undoManager = self.dataStore.managedObjectContext.undoManager;
|
||||
self.dataStore.managedObjectContext = [StoreCoordinator createChildContext];
|
||||
self.dataStore.managedObjectContext.undoManager = self.undoManager;
|
||||
}
|
||||
|
||||
- (void)saveAndRebuildMenu {
|
||||
[self.dataStore.managedObjectContext performBlock:^{
|
||||
[StoreCoordinator saveContext:self.dataStore.managedObjectContext];
|
||||
[[(AppHook*)NSApp barMenu] rebuildMenu]; // updating individual items was way to complicated ...
|
||||
[self.dataStore.managedObjectContext.parentContext performBlock:^{
|
||||
[StoreCoordinator saveContext:self.dataStore.managedObjectContext.parentContext];
|
||||
}];
|
||||
|
||||
}];
|
||||
- (void)saveChanges {
|
||||
[StoreCoordinator saveContext:self.dataStore.managedObjectContext andParent:YES];
|
||||
}
|
||||
|
||||
- (IBAction)addFeed:(id)sender {
|
||||
@@ -84,7 +72,7 @@ static NSString *dragNodeType = @"baRSS-feed-drag";
|
||||
sp.name = @"---";
|
||||
sp.typ = SEPARATOR;
|
||||
[self.undoManager endUndoGrouping];
|
||||
[self saveAndRebuildMenu];
|
||||
[self saveChanges];
|
||||
}
|
||||
|
||||
- (IBAction)remove:(id)sender {
|
||||
@@ -93,7 +81,7 @@ static NSString *dragNodeType = @"baRSS-feed-drag";
|
||||
[self incrementIndicesBy:-1 forSubsequentNodes:path];
|
||||
[self.dataStore remove:sender];
|
||||
[self.undoManager endUndoGrouping];
|
||||
[self saveAndRebuildMenu];
|
||||
[self saveChanges];
|
||||
}
|
||||
|
||||
- (IBAction)doubleClickOutlineView:(NSOutlineView*)sender {
|
||||
@@ -139,7 +127,7 @@ static NSString *dragNodeType = @"baRSS-feed-drag";
|
||||
}
|
||||
|
||||
- (void)modalDidUpdateFeedConfig:(FeedConfig*)config {
|
||||
[self saveAndRebuildMenu];
|
||||
[self saveChanges]; // TODO: adjust total count
|
||||
}
|
||||
|
||||
- (FeedConfig*)insertSortedItemAtSelection {
|
||||
@@ -178,7 +166,8 @@ static NSString *dragNodeType = @"baRSS-feed-drag";
|
||||
root = [root descendantNodeAtIndexPath:parentPath];
|
||||
|
||||
for (NSUInteger i = [path indexAtPosition:path.length - 1]; i < root.childNodes.count; i++) {
|
||||
((FeedConfig*)[root.childNodes[i] representedObject]).sortIndex += val;
|
||||
FeedConfig *conf = [root.childNodes[i] representedObject];
|
||||
conf.sortIndex += val;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,7 +186,7 @@ static NSString *dragNodeType = @"baRSS-feed-drag";
|
||||
- (void)outlineView:(NSOutlineView *)outlineView draggingSession:(NSDraggingSession *)session endedAtPoint:(NSPoint)screenPoint operation:(NSDragOperation)operation {
|
||||
[self.undoManager endUndoGrouping];
|
||||
if (self.dataStore.managedObjectContext.hasChanges) {
|
||||
[self saveAndRebuildMenu];
|
||||
[self saveChanges];
|
||||
} else {
|
||||
[self.undoManager disableUndoRegistration];
|
||||
[self.undoManager undoNestedGroup];
|
||||
@@ -228,6 +217,11 @@ static NSString *dragNodeType = @"baRSS-feed-drag";
|
||||
--updateIndex;
|
||||
}
|
||||
}
|
||||
for (NSUInteger i = self.currentlyDraggedNodes.count; i > 0; i--) { // sorted that way to handle children first
|
||||
FeedConfig *fc = [self.currentlyDraggedNodes[i - 1] representedObject];
|
||||
[fc.managedObjectContext refreshObject:fc mergeChanges:YES]; // make sure unreadCount is correct
|
||||
[fc markUnread:-fc.unreadCount ancestorsOnly:YES];
|
||||
}
|
||||
|
||||
// decrement sort indices at source
|
||||
for (NSTreeNode *node in self.currentlyDraggedNodes)
|
||||
@@ -243,6 +237,7 @@ static NSString *dragNodeType = @"baRSS-feed-drag";
|
||||
for (NSUInteger i = 0; i < self.currentlyDraggedNodes.count; i++) {
|
||||
FeedConfig *fc = [self.currentlyDraggedNodes[i] representedObject];
|
||||
fc.sortIndex = (int32_t)(updateIndex + i);
|
||||
[fc markUnread:fc.unreadCount ancestorsOnly:YES];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
@@ -322,14 +317,16 @@ static NSString *dragNodeType = @"baRSS-feed-drag";
|
||||
|
||||
- (void)undo:(id)sender {
|
||||
[self.undoManager undo];
|
||||
[StoreCoordinator restoreUnreadCount];
|
||||
[self saveChanges];
|
||||
[self.dataStore rearrangeObjects]; // update ordering
|
||||
[self saveAndRebuildMenu];
|
||||
}
|
||||
|
||||
- (void)redo:(id)sender {
|
||||
[self.undoManager redo];
|
||||
[StoreCoordinator restoreUnreadCount];
|
||||
[self saveChanges];
|
||||
[self.dataStore rearrangeObjects]; // update ordering
|
||||
[self saveAndRebuildMenu];
|
||||
}
|
||||
|
||||
- (void)enterPressed:(id)sender {
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#import "AppHook.h"
|
||||
#import "BarMenu.h"
|
||||
#import "UserPrefs.h"
|
||||
#import "StoreCoordinator.h"
|
||||
#import <ServiceManagement/ServiceManagement.h>
|
||||
|
||||
|
||||
@@ -57,6 +58,15 @@
|
||||
CFRelease(helperIdentifier);
|
||||
}
|
||||
|
||||
- (IBAction)fixCache:(NSButton *)sender {
|
||||
[StoreCoordinator deleteUnreferencedFeeds];
|
||||
[StoreCoordinator restoreUnreadCount];
|
||||
}
|
||||
|
||||
- (IBAction)changeMenuBarIconSetting:(NSButton*)sender {
|
||||
[[(AppHook*)NSApp barMenu] updateBarIcon];
|
||||
}
|
||||
|
||||
- (IBAction)changeHttpApplication:(NSPopUpButton *)sender {
|
||||
[UserPrefs setHttpApplication:sender.selectedItem.representedObject];
|
||||
}
|
||||
@@ -68,31 +78,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: add self to login items
|
||||
|
||||
- (IBAction)checkmarkClicked:(NSButton*)sender {
|
||||
// TODO: Could be optimized by updating only the relevant parts
|
||||
[[(AppHook*)NSApp barMenu] rebuildMenu];
|
||||
}
|
||||
|
||||
- (IBAction)changeMenuBarIconSetting:(NSButton*)sender {
|
||||
[[(AppHook*)NSApp barMenu] updateBarIcon];
|
||||
}
|
||||
|
||||
- (IBAction)changeMenuHeaderSetting:(NSButton*)sender {
|
||||
BOOL recursive = YES;
|
||||
NSString *bindingKey = [[sender infoForBinding:@"value"] valueForKey:NSObservedKeyPathKey];
|
||||
if ([bindingKey containsString:@"values.global"]) {
|
||||
recursive = NO; // item is in menu bar menu, no need to go recursive
|
||||
}
|
||||
[[(AppHook*)NSApp barMenu] updateMenuHeaders:recursive];
|
||||
}
|
||||
|
||||
- (IBAction)changeMenuItemUpdateAll:(NSButton*)sender {
|
||||
BOOL checked = (sender.state == NSControlStateValueOn);
|
||||
[[(AppHook*)NSApp barMenu] setItemUpdateAllHidden:!checked];
|
||||
}
|
||||
|
||||
#pragma mark - Helper methods
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14113" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14113"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14313.18"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -45,7 +45,6 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="changeMenuItemUpdateAll:" target="-2" id="Zb8-Oi-JVr"/>
|
||||
<binding destination="iU7-KA-nY5" name="value" keyPath="values.globalUpdateAll" id="FrQ-u0-lFo">
|
||||
<dictionary key="options">
|
||||
<bool key="NSAllowsEditingMultipleValuesSelection" value="NO"/>
|
||||
@@ -62,7 +61,6 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="changeMenuHeaderSetting:" target="-2" id="Tte-Vw-oMq"/>
|
||||
<binding destination="iU7-KA-nY5" name="value" keyPath="values.globalOpenUnread" id="c20-0p-cPb">
|
||||
<dictionary key="options">
|
||||
<bool key="NSAllowsEditingMultipleValuesSelection" value="NO"/>
|
||||
@@ -79,7 +77,6 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="changeMenuHeaderSetting:" target="-2" id="zRA-Ht-Qj1"/>
|
||||
<binding destination="iU7-KA-nY5" name="value" keyPath="values.groupOpenUnread" id="mCn-aE-DwT">
|
||||
<dictionary key="options">
|
||||
<bool key="NSAllowsEditingMultipleValuesSelection" value="NO"/>
|
||||
@@ -96,7 +93,6 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="changeMenuHeaderSetting:" target="-2" id="4sR-3H-A6H"/>
|
||||
<binding destination="iU7-KA-nY5" name="value" keyPath="values.feedOpenUnread" id="Qyh-BN-P74">
|
||||
<dictionary key="options">
|
||||
<bool key="NSAllowsEditingMultipleValuesSelection" value="NO"/>
|
||||
@@ -113,7 +109,6 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="changeMenuHeaderSetting:" target="-2" id="gcu-x5-gUa"/>
|
||||
<binding destination="iU7-KA-nY5" name="value" keyPath="values.globalMarkRead" id="uiO-3M-xfT">
|
||||
<dictionary key="options">
|
||||
<bool key="NSAllowsEditingMultipleValuesSelection" value="NO"/>
|
||||
@@ -130,7 +125,6 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="changeMenuHeaderSetting:" target="-2" id="rTt-3J-rkn"/>
|
||||
<binding destination="iU7-KA-nY5" name="value" keyPath="values.groupMarkRead" id="YLZ-t8-Jbk">
|
||||
<dictionary key="options">
|
||||
<bool key="NSAllowsEditingMultipleValuesSelection" value="NO"/>
|
||||
@@ -147,7 +141,6 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="changeMenuHeaderSetting:" target="-2" id="2cM-mG-Lnw"/>
|
||||
<binding destination="iU7-KA-nY5" name="value" keyPath="values.feedMarkRead" id="mYj-26-0OV">
|
||||
<dictionary key="options">
|
||||
<bool key="NSAllowsEditingMultipleValuesSelection" value="NO"/>
|
||||
@@ -164,7 +157,6 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="changeMenuHeaderSetting:" target="-2" id="anc-id-9sf"/>
|
||||
<binding destination="iU7-KA-nY5" name="value" keyPath="values.globalMarkUnread" id="drp-87-kfY">
|
||||
<dictionary key="options">
|
||||
<bool key="NSAllowsEditingMultipleValuesSelection" value="NO"/>
|
||||
@@ -181,7 +173,6 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="changeMenuHeaderSetting:" target="-2" id="98j-A6-A2m"/>
|
||||
<binding destination="iU7-KA-nY5" name="value" keyPath="values.groupMarkUnread" id="bJP-0I-l7t">
|
||||
<dictionary key="options">
|
||||
<bool key="NSAllowsEditingMultipleValuesSelection" value="NO"/>
|
||||
@@ -198,7 +189,6 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="changeMenuHeaderSetting:" target="-2" id="Muv-3Y-LU0"/>
|
||||
<binding destination="iU7-KA-nY5" name="value" keyPath="values.feedMarkUnread" id="mRu-7M-3bu">
|
||||
<dictionary key="options">
|
||||
<bool key="NSAllowsEditingMultipleValuesSelection" value="NO"/>
|
||||
@@ -232,7 +222,6 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="checkmarkClicked:" target="-2" id="PUq-gk-16h"/>
|
||||
<binding destination="iU7-KA-nY5" name="value" keyPath="values.groupUnreadCount" id="Mg5-xJ-L3n">
|
||||
<dictionary key="options">
|
||||
<bool key="NSAllowsEditingMultipleValuesSelection" value="NO"/>
|
||||
@@ -249,7 +238,6 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="checkmarkClicked:" target="-2" id="dfY-Sm-GHz"/>
|
||||
<binding destination="iU7-KA-nY5" name="value" keyPath="values.feedUnreadCount" id="hnm-Q2-kbs">
|
||||
<dictionary key="options">
|
||||
<bool key="NSAllowsEditingMultipleValuesSelection" value="NO"/>
|
||||
@@ -266,7 +254,6 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="checkmarkClicked:" target="-2" id="hzW-x5-kBO"/>
|
||||
<binding destination="iU7-KA-nY5" name="value" keyPath="values.feedTickMark" id="xKL-Lh-tBL">
|
||||
<dictionary key="options">
|
||||
<bool key="NSAllowsEditingMultipleValuesSelection" value="NO"/>
|
||||
@@ -446,6 +433,17 @@
|
||||
<action selector="changeDefaultRSSReader:" target="-2" id="ul1-1K-oJb"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="QwE-M7-q2R">
|
||||
<rect key="frame" x="206" y="279" width="100" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Fix Cache" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="ady-2s-Ggm">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="fixCache:" target="-2" id="gbM-hA-UVF"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<point key="canvasLocation" x="140" y="-155.5"/>
|
||||
</customView>
|
||||
|
||||
Reference in New Issue
Block a user