123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495 |
- //
- // SKPreferenceController.m
- // Skim
- //
- // Created by Christiaan Hofman on 2/10/07.
- /*
- This software is Copyright (c) 2007-2018
- Christiaan Hofman. All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
- - Neither the name of Christiaan Hofman nor the names of any
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #import "SKPreferenceController.h"
- //#import "SKGeneralPreferences.h"
- //#import "SKDisplayPreferences.h"
- //#import "SKNotesPreferences.h"
- //#import "SKSyncPreferences.h"
- //#import "NSUserDefaultsController_SKExtensions.h"
- //#import "SKFontWell.h"
- //#import "SKStringConstants.h"
- //#import "NSView_SKExtensions.h"
- //#import "NSGraphics_SKExtensions.h"
- //#import "NSGeometry_SKExtensions.h"
- //#import "NSAnimationContext_SKExtensions.h"
- //#import "DropboxPreferences.h"
- /*#import "KMOCRPreferences.h" //恢复OCR架上版本样式*/
- #define SKPreferencesToolbarIdentifier @"SKPreferencesToolbarIdentifier"
- #define SKPreferenceWindowFrameAutosaveName @"SKPreferenceWindow"
- #define SKLastSelectedPreferencePaneKey @"SKLastSelectedPreferencePane"
- #define NIBNAME_KEY @"nibName"
- #define BOTTOM_MARGIN 27.0
- #define INITIALUSERDEFAULTS_KEY @"InitialUserDefaults"
- #define RESETTABLEKEYS_KEY @"ResettableKeys"
- #import <PDF_Master-Swift.h>
- static inline NSRect SKShrinkRect(NSRect rect, CGFloat amount, NSRectEdge edge) {
- NSRect ignored;
- NSDivideRect(rect, &ignored, &rect, amount, edge);
- return rect;
- }
- @implementation SKPreferenceController
- //@synthesize resetButtons;
- static SKPreferenceController *sharedPrefenceController = nil;
- + (id)sharedPrefenceController {
- if (sharedPrefenceController == nil)
- [[self alloc] init];
- return sharedPrefenceController;
- }
- + (id)allocWithZone:(NSZone *)zone {
- return sharedPrefenceController ?: [super allocWithZone:zone];
- }
- - (id)init {
- if (sharedPrefenceController == nil) {
- self = [super initWithWindowNibName:@"PreferenceWindow"];
- if (self) {
- preferencePanes = [[NSArray alloc] initWithObjects:
- [[SKGeneralPreferences alloc] init],
- [[KMDisplayPreferences alloc] init],
- [[KMNotesPreferences alloc] init],
- // [[[SKSyncPreferences alloc] init] autorelease],
-
- // [[[DropboxPreferences alloc] init] autorelease],
- // [[[KMOCRPreferences alloc] init] autorelease], nil]; //恢复OCR架上版本样式
- // [[[DropboxPreferences alloc] init] autorelease],
- nil];
- history = [[NSMutableArray alloc] init];
- historyIndex = 0;
- }
- sharedPrefenceController = self;
- } else if (self != sharedPrefenceController) {
- NSLog(@"Attempt to allocate second instance of %@", [self class]);
- self = sharedPrefenceController;
- }
- return self;
- }
- - (void)dealloc {
- currentPane = nil;
- // SKDESTROY(preferencePanes);
- // SKDESTROY(resetButtons);
- // SKDESTROY(history);
- // [super dealloc];
- }
- - (NSViewController<SKPreferencePane> *)preferencePaneForItemIdentifier:(NSString *)itemIdent {
- [self panelControlSelectColor:itemIdent];
- for (NSViewController<SKPreferencePane> *pane in preferencePanes)
- if ([[pane nibName] isEqualToString:itemIdent])
- return pane;
- return nil;
- }
- - (void)selectPane:(NSViewController<SKPreferencePane> *)pane {
- if ([pane isEqual:currentPane] == NO) {
- if (pane) {
- historyIndex++;
- if ([history count] > historyIndex)
- [history removeObjectsInRange:NSMakeRange(historyIndex, [history count] - historyIndex)];
- [history addObject:pane];
- } else {
- pane = [history objectAtIndex:historyIndex];
- }
-
- NSWindow *window = [self window];
- NSView *contentView = [window contentView];
- NSView *oldView = [currentPane view];
- NSView *view = [pane view];
- NSRect frame = SKShrinkRect([window frame], NSHeight([contentView frame]) - NSMaxY([view frame]), NSMinYEdge);
-
- // make sure edits are committed
- [currentPane commitEditing];
- [[NSUserDefaultsController sharedUserDefaultsController] commitEditing];
-
- currentPane = pane;
-
- [window setTitle:[currentPane title]];
- [[NSUserDefaults standardUserDefaults] setObject:[currentPane nibName] forKey:SKLastSelectedPreferencePaneKey];
- [[window toolbar] setSelectedItemIdentifier:[currentPane nibName]];
- if ([[NSUserDefaults standardUserDefaults] boolForKey:SKStringConstants.disableAnimationsKey]) {
- [contentView replaceSubview:oldView with:view];
- [window setFrame:frame display:YES];
- } else {
- NSTimeInterval duration = [window animationResizeTime:frame];
- [contentView displayIfNeeded];
- [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context){
- [context setDuration:duration];
- [[contentView animator] replaceSubview:oldView with:view];
- [[window animator] setFrame:frame display:YES];
- }
- completionHandler:^{}];
- }
- }
- }
- - (void)windowDidLoad {
- if (@available(macOS 11.0,*)) {
- self.window.toolbarStyle = NSWindowToolbarStyleExpanded;
- }
-
- NSWindow *window = [self window];
- NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:SKPreferencesToolbarIdentifier];
-
- [toolbar setAllowsUserCustomization:NO];
- [toolbar setAutosavesConfiguration:NO];
- [toolbar setVisible:YES];
- [toolbar setDelegate:self];
- [window setToolbar:toolbar];
- [window setShowsToolbarButton:NO];
-
- [[window contentView] setWantsLayer:YES];
-
- // we want to restore the top of the window, while without the force it restores the bottom position without the size
- [window setFrameUsingName:SKPreferenceWindowFrameAutosaveName force:YES];
- [self setWindowFrameAutosaveName:SKPreferenceWindowFrameAutosaveName];
-
- // [NSGraphicsContext SKAutoSizeButtons:resetButtons rightAlign:false];
-
- CGFloat width = 0.0;
- NSRect frame;
- NSViewController<SKPreferencePane> *pane;
- NSView *view;
- for (pane in preferencePanes)
- width = fmax(width, NSWidth([[pane view] frame]));
- for (pane in preferencePanes) {
- view = [pane view];
- frame = [view frame];
- if (([view autoresizingMask] & NSViewWidthSizable))
- frame.size.width = width;
- else
- frame.origin.x = floor(0.5 * (width - NSWidth(frame)));
- frame.origin.y = BOTTOM_MARGIN;
- [view setFrame:frame];
- }
-
- currentPane = [self preferencePaneForItemIdentifier:[[NSUserDefaults standardUserDefaults] stringForKey:SKLastSelectedPreferencePaneKey]] ?: [preferencePanes objectAtIndex:0];
- [toolbar setSelectedItemIdentifier:[currentPane nibName]];
- // [window setTitle:[currentPane title]];
- // [history addObject:currentPane];
-
- view = [currentPane view];
- frame = [window frame];
- frame.size.width = width;
- frame = SKShrinkRect(frame, NSHeight([[window contentView] frame]) - NSMaxY([view frame]), NSMinYEdge);
- [window setFrame:frame display:NO];
-
- [[window contentView] addSubview:view];
- }
- - (void)windowDidResignMain:(NSNotification *)notification {
- [[[self window] contentView] deactivateWellSubcontrols];
- }
- - (void)windowWillClose:(NSNotification *)notification {
- // make sure edits are committed
- [currentPane commitEditing];
- [[NSUserDefaultsController sharedUserDefaultsController] commitEditing];
- }
- - (void)selectPaneWithIdentifier:(NSString *)itemIdentifier {
- [self selectPane:[self preferencePaneForItemIdentifier:itemIdentifier]];
- }
- - (void)panelControlSelectColor:(NSString *)identifier {
- for (NSToolbarItem *item in self.window.toolbar.items) {
- if ([item.itemIdentifier isEqualToString:identifier]) {
- if ([item.itemIdentifier isEqualToString:@"GeneralPreferences"]) {
- item.image = [NSImage imageNamed:@"KMImageNameElseSettingsGeneralSel"];
- } else if ([item.itemIdentifier isEqualToString:@"DisplayPreferences"]){
- item.image = [NSImage imageNamed:@"KMImageNameElseSettingsViewSel"];
- } else if ([item.itemIdentifier isEqualToString:@"NotesPreferences"]){
- item.image = [NSImage imageNamed:@"KMImageNameElseSettingsAnnotationSel"];
- } else if ([item.itemIdentifier isEqualToString:@"SyncPreferences"]){
- item.image = [NSImage imageNamed:@"KMImageNameElseSettingsSynchronizeSel"];
- } else if ([item.itemIdentifier isEqualToString:@"DropboxPreferences"]){
- item.image = [NSImage imageNamed:@"KMImageNameElseSettingsDropboxSel"];
- }
- } else {
- if ([item.itemIdentifier isEqualToString:@"GeneralPreferences"]) {
- item.image = [NSImage imageNamed:@"KMImageNameElseSettingsGeneralNor"];
- } else if ([item.itemIdentifier isEqualToString:@"DisplayPreferences"]){
- item.image = [NSImage imageNamed:@"KMImageNameElseSettingsViewNor"];
- } else if ([item.itemIdentifier isEqualToString:@"NotesPreferences"]){
- item.image = [NSImage imageNamed:@"KMImageNameElseSettingsAnnotationNor"];
- } else if ([item.itemIdentifier isEqualToString:@"SyncPreferences"]){
- item.image = [NSImage imageNamed:@"KMImageNameElseSettingsSynchronizeNor"];
- } else if ([item.itemIdentifier isEqualToString:@"DropboxPreferences"]){
- item.image = [NSImage imageNamed:@"KMImageNameElseSettingsDropboxNor"];
- }
- }
- }
- }
- #pragma mark Actions
- - (void)selectPaneAction:(id)sender {
- [self panelControlSelectColor:[sender itemIdentifier]];
-
- [self selectPane:[self preferencePaneForItemIdentifier:[sender itemIdentifier]]];
- }
- - (void)resetAllSheetDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
- if (returnCode == NSAlertFirstButtonReturn) {
- [[NSUserDefaultsController sharedUserDefaultsController] revertToInitialValues:nil];
- for (NSViewController<SKPreferencePane> *pane in preferencePanes) {
- if ([pane respondsToSelector:@selector(defaultsDidRevert)])
- [pane defaultsDidRevert];
- }
-
- //重置OCR后,记录切换值
- [[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"KMStatusPlanPopUpBtnKey"];
- [[NSUserDefaults standardUserDefaults] synchronize];
- }
- }
- - (IBAction)resetAll:(id)sender {
- NSAlert *alert = [[NSAlert alloc] init];
- [alert setMessageText:NSLocalizedString(@"Reset all preferences to their original values?", @"Message in alert dialog when pressing Reset All button")];
- [alert setInformativeText:NSLocalizedString(@"Choosing Reset will restore all settings to the state they were in when PDF Reader Pro Edition was first installed.", @"Informative text in alert dialog when pressing Reset All button")];
- [alert addButtonWithTitle:NSLocalizedString(@"Reset", @"Button title")];
- [alert addButtonWithTitle:NSLocalizedString(@"Cancel", @"Button title")];
- [alert beginSheetModalForWindow:[self window]
- modalDelegate:self
- didEndSelector:@selector(resetAllSheetDidEnd:returnCode:contextInfo:)
- contextInfo:NULL];
- }
- - (void)resetCurrentSheetDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
- if (returnCode == NSAlertFirstButtonReturn) {
- NSURL *initialUserDefaultsURL = [[NSBundle mainBundle] URLForResource:INITIALUSERDEFAULTS_KEY withExtension:@"plist"];
- NSArray *resettableKeys = [[[NSDictionary dictionaryWithContentsOfURL:initialUserDefaultsURL] objectForKey:RESETTABLEKEYS_KEY] objectForKey:[currentPane nibName]];
- [[NSUserDefaultsController sharedUserDefaultsController] revertToInitialValuesForKeys:resettableKeys];
- if ([currentPane respondsToSelector:@selector(defaultsDidRevert)])
- [currentPane defaultsDidRevert];
- if ([[currentPane title] isEqualToString:@"OCR"]) { //重置OCR后,记录切换值
- [[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"KMStatusPlanPopUpBtnKey"];
- [[NSUserDefaults standardUserDefaults] synchronize];
- }
- }
- }
- - (IBAction)resetCurrent:(id)sender {
- if (currentPane == nil) {
- NSBeep();
- return;
- }
- NSString *label = [currentPane title];
- NSAlert *alert = [[NSAlert alloc] init];
- [alert setMessageText:[NSString stringWithFormat:NSLocalizedString(@"Reset %@ preferences to their original values?", @"Message in alert dialog when pressing Reset All button"), label]];
- [alert setInformativeText:[NSString stringWithFormat:NSLocalizedString(@"Choosing Reset will restore all settings in this pane to the state they were in when PDF Reader Pro Edition was first installed.", @"Informative text in alert dialog when pressing Reset All button"), label]];
- [alert addButtonWithTitle:NSLocalizedString(@"Reset", @"Button title")];
- [alert addButtonWithTitle:NSLocalizedString(@"Cancel", @"Button title")];
- [alert beginSheetModalForWindow:[self window]
- modalDelegate:self
- didEndSelector:@selector(resetCurrentSheetDidEnd:returnCode:contextInfo:)
- contextInfo:NULL];
- }
- - (IBAction)doGoToNextPage:(id)sender {
- NSUInteger itemIndex = [preferencePanes indexOfObject:currentPane];
- if (itemIndex != NSNotFound && ++itemIndex < [preferencePanes count])
- [self selectPane:[preferencePanes objectAtIndex:itemIndex]];
- }
- - (IBAction)doGoToPreviousPage:(id)sender {
- NSUInteger itemIndex = [preferencePanes indexOfObject:currentPane];
- if (itemIndex != NSNotFound && itemIndex-- > 0)
- [self selectPane:[preferencePanes objectAtIndex:itemIndex]];
- }
- - (IBAction)doGoToFirstPage:(id)sender {
- [self selectPane:[preferencePanes objectAtIndex:0]];
- }
- - (IBAction)doGoToLastPage:(id)sender {
- [self selectPane:[preferencePanes lastObject]];
- }
- - (IBAction)doGoBack:(id)sender {
- if (historyIndex > 0) {
- historyIndex--;
- [self selectPane:nil];
- }
- }
- - (IBAction)doGoForward:(id)sender {
- if (historyIndex + 1 < [history count]) {
- historyIndex++;
- [self selectPane:nil];
- }
- }
- - (IBAction)changeFont:(id)sender {
- // [[[[self window] contentView] activeFontWell] changeFontFromFontManager:sender];
- }
- - (IBAction)changeAttributes:(id)sender {
- // [[[[self window] contentView] activeFontWell] changeAttributesFromFontManager:sender];
- }
- - (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
- if ([menuItem action] == @selector(doGoToNextPage:) || [menuItem action] == @selector(doGoToLastPage:))
- return [currentPane isEqual:[preferencePanes lastObject]] == NO;
- else if ([menuItem action] == @selector(doGoToPreviousPage:) || [menuItem action] == @selector(doGoToFirstPage:))
- return [currentPane isEqual:[preferencePanes objectAtIndex:0]] == NO;
- else if ([menuItem action] == @selector(doGoBack:))
- return historyIndex > 0;
- else if ([menuItem action] == @selector(doGoForward:))
- return historyIndex + 1 < [history count];
- return YES;
- }
- #pragma mark Toolbar
- - (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdent willBeInsertedIntoToolbar:(BOOL)willBeInserted {
- NSViewController<SKPreferencePane> *pane = [self preferencePaneForItemIdentifier:itemIdent];
- NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdent];
- [item setLabel:[pane title]];
- NSImage * ima = nil;
- if ([itemIdent isEqualToString:@"GeneralPreferences"]) {
- ima = [NSImage imageNamed:@"KMImageNameElseSettingsGeneralNor"];//generalPreferences
- } else if ([itemIdent isEqualToString:@"DisplayPreferences"]){
- ima = [NSImage imageNamed:@"KMImageNameElseSettingsViewNor"];//displayPreferences
- } else if ([itemIdent isEqualToString:@"NotesPreferences"]){
- ima = [NSImage imageNamed:@"KMImageNameElseSettingsAnnotationNor"];//notesPreferences
- } else if ([itemIdent isEqualToString:@"SyncPreferences"]){
- ima = [NSImage imageNamed:@"KMImageNameElseSettingsSynchronizeNor"];//syncPreferences
- } else if ([itemIdent isEqualToString:@"DropboxPreferences"]){
- ima = [NSImage imageNamed:@"KMImageNameElseSettingsDropboxNor"];//dropboxPreferences
- }
- //恢复OCR架上版本样式
- // else if ([itemIdent isEqualToString:@"KMOCRPreferences"]) {
- // ima = [NSImage imageNamed:@"ocrPreferences"];
- // }
- [item setImage:ima];
- [item setTarget:self];
- [item setAction:@selector(selectPaneAction:)];
- return item;
- }
- - (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar {
- return [preferencePanes valueForKey:NIBNAME_KEY];
- }
- - (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar {
- return [self toolbarDefaultItemIdentifiers:toolbar];
- }
- - (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar {
- return [self toolbarDefaultItemIdentifiers:toolbar];
- }
- @end
- @implementation SKPreferenceWindow
- - (BOOL)respondsToSelector:(SEL)aSelector {
- return aSelector != @selector(toggleToolbarShow:) && aSelector != @selector(runToolbarCustomizationPalette:) && [super respondsToSelector:aSelector];
- }
- @end
- @implementation SKIBArray
- static void setObjectAtIndex(id __strong *object, id obj, NSUInteger i, unsigned long *mutationsPtr) {
- if (object[i] != obj) {
- // [object[i] release];
- object[i] = obj;
- (*mutationsPtr)++;
- }
- }
- #define SYNTHESIZE_OBJECT_ACCESSORS(i) \
- @dynamic object##i; \
- - (id)object##i { return object[i-1]; } \
- - (void)setObject##i:(id)obj { setObjectAtIndex(object, obj, i-1, &mutations); }
- SYNTHESIZE_OBJECT_ACCESSORS(1)
- SYNTHESIZE_OBJECT_ACCESSORS(2)
- SYNTHESIZE_OBJECT_ACCESSORS(3)
- SYNTHESIZE_OBJECT_ACCESSORS(4)
- SYNTHESIZE_OBJECT_ACCESSORS(5)
- SYNTHESIZE_OBJECT_ACCESSORS(6)
- SYNTHESIZE_OBJECT_ACCESSORS(7)
- SYNTHESIZE_OBJECT_ACCESSORS(8)
- SYNTHESIZE_OBJECT_ACCESSORS(9)
- - (void)dealloc {
- NSUInteger i;
- for (i = 0; i < 9; i++)
- setObjectAtIndex(object, nil, i, &mutations);
- // [super dealloc];
- }
- - (NSUInteger)count {
- NSUInteger i;
- for (i = 0; i < 9; i++)
- if (object[i] == nil) break;
- return i;
- }
- - (id)objectAtIndex:(NSUInteger)anIndex {
- return object[anIndex];
- }
- - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len {
- if (state->state == 0) {
- state->state = 1;
- // state->itemsPtr = object;
- state->mutationsPtr = &mutations;
- return [self count];
- }
- return 0;
- }
- @end
|