dev.stuconnolly.com / svn / safaritabs

  1. /*
  2.  *  $Id: STSessionRestoreController.m 225 2011-08-13 21:16:20Z stuart $
  3.  *
  4.  *  SafariTabs
  5.  *  http://stuconnolly.com/projects/safaritabs/
  6.  *
  7.  *  Copyright (c) 2010 Stuart Connolly. All rights reserved.
  8.  *
  9.  *  This program is free software: you can redistribute it and/or modify
  10.  *  it under the terms of the GNU General Public License as published by
  11.  *  the Free Software Foundation, either version 3 of the License, or
  12.  *  (at your option) any later version.
  13.  *
  14.  *  This program is distributed in the hope that it will be useful,
  15.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17.  *  GNU General Public License for more details.
  18.  *
  19.  *  You should have received a copy of the GNU General Public License
  20.  *  along with this program. If not, see <http://www.gnu.org/licenses/>.
  21.  */
  22.  
  23. #import "STSessionRestoreController.h"
  24. #import "STSessionRestoreTextFieldCell.h"
  25. #import "STSafariPluginHandler.h"
  26. #import "STSessionHandler.h"
  27.  
  28. #import "STSessionRestoreTab.h"
  29. #import "BrowserDocument.h"
  30.  
  31. #import "STConstants.h"
  32. #import "STUtilities.h"
  33.  
  34. @interface STSessionRestoreController ()
  35.  
  36. - (NSUInteger)_numberOfSelectedTabs;
  37. - (NSMutableArray *)_constructArrayOfSelectedTabURLs:(NSMutableArray *)tabs;
  38. - (NSMutableArray *)_constructArrayOfTabsFromArray:(NSMutableArray *)tabs;
  39.  
  40. @end
  41.  
  42. @implementation STSessionRestoreController
  43.  
  44. /*!
  45.  * Initializes an instance of STSessionRestoreController with the supplied delegate.
  46.  *
  47.  * @return The initialized object
  48.  */
  49. - (id)initWithDelegate:(id)delegate
  50. {
  51.     if ((self = [super initWithWindowNibName:@"STSessionRestore"])) {
  52.         _delegate = delegate;
  53.     }
  54.    
  55.     return self;
  56. }
  57.  
  58. /*!
  59.  * Setup various interface controls.
  60.  */
  61. - (void)awakeFromNib
  62. {
  63.     [[tabRestoreTableView tableColumnWithIdentifier:STTableViewTabTitleColumnIdentifier] setDataCell:[[[STSessionRestoreTextFieldCell alloc] init] autorelease]];
  64.     [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh]; // Make pretty icons
  65.    
  66.     [self updateUserInterface];
  67.    
  68.     tabRestoreTableViewBoxIsVisible = YES;
  69.     [self toggleTabRestoreTableView:self];
  70. }
  71.  
  72. /*!
  73.  * Sets the tabs to restore for the last session.
  74.  *
  75.  * @param tabs The array of tabs
  76.  */
  77. - (void)setSessionRestoreTabs:(NSMutableArray *)tabs
  78. {
  79.     if (_sessionRestoreTabs != tabs) {
  80.         [_sessionRestoreTabs release];
  81.         _sessionRestoreTabs = [tabs retain];
  82.     }
  83. }
  84.  
  85. #pragma mark -
  86. #pragma mark IB Action Methods
  87.  
  88. /*!
  89.  * Restores all tabs.
  90.  *
  91.  * @param sender The object calling the method
  92.  */
  93. - (IBAction)restoreAllTabs:(id)sender
  94. {
  95.     [[[STSafariPluginHandler sharedInstance] sessionHandler] restoreTabsFromWindows:(NSArray *)[NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] dataForKey:STWindowsAndTabs]]];
  96.    
  97.     [self close];
  98.     [NSApp abortModal];
  99. }
  100.  
  101. /*!
  102.  * Cancels tab restoration.
  103.  *
  104.  * @param sender The object calling the method
  105.  */
  106. - (IBAction)dontRestoreTabs:(id)sender
  107. {
  108.     [self close];
  109.     [NSApp abortModal];
  110. }
  111.  
  112. /*!
  113.  * Restores the selected tabs.
  114.  *
  115.  * @param sender The object calling the method
  116.  */
  117. - (IBAction)restoreSelectedTabs:(id)sender
  118. {
  119.     STSessionHandler *sessionHandler = [[STSafariPluginHandler sharedInstance] sessionHandler];
  120.    
  121.     if ([_sessionRestoreTabs count] == [self _numberOfSelectedTabs]) {
  122.         [sessionHandler restoreTabsFromWindows:(NSArray *)[NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] dataForKey:STWindowsAndTabs]]];
  123.     }
  124.     else {
  125.         [sessionHandler openBrowserWithTabs:[self _constructArrayOfSelectedTabURLs:_sessionRestoreTabs] inDocument:[[[NSDocumentController sharedDocumentController] documents] objectAtIndex:0]];
  126.     }
  127.    
  128.     [self close];
  129.     [NSApp abortModal];
  130. }
  131.  
  132. /*!
  133.  * Toggles (shows/hides) the tab restore table view.
  134.  *
  135.  * @param sender The object calling the method
  136.  */
  137. - (IBAction)toggleTabRestoreTableView:(id)sender
  138. {
  139.     // Performs the calculations necessary for the showing and hiding and subsequent automatic window
  140.     // resizing whenever the user clicks the sender.
  141.     //
  142.     // Adapted from Larry L. Fransson at http://homepage.mac.com/lfransson/Cocoa/FileSharing1.html
  143.    
  144.     CGFloat newHeight;
  145.     NSView *view = [[showTabRestoreTableViewButton superview] superview];
  146.     NSRect frame = [NSWindow contentRectForFrameRect:[[self window] frame] styleMask:[[self window] styleMask]];
  147.    
  148.     tableViewBoxHeight = [tabRestoreTableViewBox bounds].size.height;
  149.    
  150.     NSUInteger showButtonMask = [showTabRestoreTableViewButton autoresizingMask];
  151.    
  152.     // Set views not to autoresize
  153.     [view setAutoresizingMask:0];
  154.     [showTabRestoreTableViewButton setAutoresizingMask:0];
  155.     [dontRestoreTabsButton setAutoresizingMask:0];
  156.     [restoreTabsButton setAutoresizingMask:0];
  157.    
  158.     if (tabRestoreTableViewBoxIsVisible) {
  159.         newHeight = (frame.size.height - tableViewBoxHeight);
  160.        
  161.         frame.origin.y   += frame.size.height;
  162.         frame.origin.y   -= newHeight;
  163.         frame.size.height = newHeight;
  164.        
  165.         [selectedTabCountTextField setHidden:YES];
  166.         [tabRestoreTableViewBox setHidden:YES];
  167.        
  168.         frame = [NSWindow frameRectForContentRect:frame styleMask:[[tabRestoreTableViewBox window] styleMask]];
  169.         [[tabRestoreTableViewBox window] setFrame:frame display:YES animate:YES];
  170.        
  171.         [showTabRestoreTableViewButton setHidden:NO];
  172.        
  173.         [dontRestoreTabsButton setTitle:STLocalizedString(@"Don't restore")];
  174.         [dontRestoreTabsButton setAction:@selector(dontRestoreTabs:)];
  175.        
  176.         [restoreTabsButton setTitle:STLocalizedString(@"Restore All Tabs")];
  177.         [restoreTabsButton setAction:@selector(restoreAllTabs:)];
  178.         [restoreTabsButton setEnabled:YES];
  179.        
  180.         // Re-enable autoresizing
  181.         [view setAutoresizingMask:showButtonMask];
  182.         [showTabRestoreTableViewButton setAutoresizingMask:showButtonMask];
  183.         [dontRestoreTabsButton setAutoresizingMask:showButtonMask];
  184.         [restoreTabsButton setAutoresizingMask:showButtonMask];
  185.        
  186.         tabRestoreTableViewBoxIsVisible = NO;
  187.     }
  188.     else {
  189.         newHeight = (frame.size.height + tableViewBoxHeight);
  190.        
  191.         frame.origin.y   += frame.size.height;
  192.         frame.origin.y   -= newHeight;
  193.         frame.size.height = newHeight;
  194.        
  195.         frame = [NSWindow frameRectForContentRect:frame styleMask:[[tabRestoreTableViewBox window] styleMask]];
  196.         [[tabRestoreTableViewBox window] setFrame:frame display:YES animate:YES];
  197.        
  198.         [showTabRestoreTableViewButton setHidden:YES];
  199.         [tabRestoreTableViewBox setHidden:NO];
  200.         [selectedTabCountTextField setHidden:NO];
  201.        
  202.         [dontRestoreTabsButton setTitle:STLocalizedString(@"Cancel")];
  203.         [dontRestoreTabsButton setAction:@selector(toggleTabRestoreTableView:)];
  204.        
  205.         [restoreTabsButton setTitle:STLocalizedString(@"Restore Tabs")];
  206.         [restoreTabsButton setAction:@selector(restoreSelectedTabs:)];
  207.        
  208.         [view setAutoresizingMask:showButtonMask];
  209.         [showTabRestoreTableViewButton setAutoresizingMask:showButtonMask];
  210.         [dontRestoreTabsButton setAutoresizingMask:showButtonMask];
  211.         [restoreTabsButton setAutoresizingMask:showButtonMask];
  212.        
  213.         tabRestoreTableViewBoxIsVisible = YES;
  214.     }
  215.    
  216.     [self updateUserInterface];
  217. }
  218.  
  219. /*!
  220.  * Toggles (enables/disables) the 'Dont ask to restore again' checkbox.
  221.  *
  222.  * @param sender The object calling the method
  223.  */
  224. - (IBAction)toggleDontAskToRestoreAgain:(id)sender
  225. {
  226.     [[NSUserDefaults standardUserDefaults] setInteger:(![sender state]) forKey:STTabRestoreLaunchAction];
  227. }
  228.  
  229. /*!
  230.  * Displays the session restore panel with the supplied archived window data.
  231.  *
  232.  * @param data The archived window data
  233.  */
  234. - (void)displaySessionRestorePanelUsingData:(NSData *)data
  235. {
  236.     NSMutableArray *windows = (NSMutableArray *)[NSKeyedUnarchiver unarchiveObjectWithData:data];
  237.    
  238.     [self setSessionRestoreTabs:[self _constructArrayOfTabsFromArray:windows]];
  239.    
  240.     if ([_sessionRestoreTabs count] != 0) {
  241.         [NSApp runModalForWindow:[self window]];
  242.     }
  243. }
  244.  
  245. /*!
  246.  * Updates the user interface with respect to the tab restore table view and number of selected tabs.
  247.  */
  248. - (void)updateUserInterface
  249. {    
  250.     [tabRestoreTableView reloadData];
  251.    
  252.     if (tabRestoreTableViewBoxIsVisible) {
  253.         [restoreTabsButton setEnabled:([self _numberOfSelectedTabs] > 0)];
  254.     }
  255.    
  256.     [selectedTabCountTextField setStringValue:[NSString stringWithFormat:STLocalizedString(@"Selected tab count"), (unsigned long)[self _numberOfSelectedTabs], (unsigned long)[_sessionRestoreTabs count]]];
  257. }
  258.  
  259. #pragma mark -
  260.  
  261. /*!
  262.  * @brief Dealloc.
  263.  */
  264. - (void)dealloc
  265. {
  266.     [_sessionRestoreTabs release], _sessionRestoreTabs = nil;
  267.    
  268.     [super dealloc];
  269. }
  270.  
  271. /*!
  272.  * Returns the number of selected tabs within the session restore table view.
  273.  *
  274.  * @return An unsigned integer indicating the number of selected tabs.
  275.  */
  276. - (NSUInteger)_numberOfSelectedTabs
  277. {
  278.     NSUInteger selectedCount = 0;
  279.    
  280.     for (STSessionRestoreTab *tab in _sessionRestoreTabs)
  281.     {
  282.         if ([[tab tabEnabled] boolValue]) selectedCount++;
  283.     }
  284.    
  285.     return selectedCount;
  286. }
  287.  
  288. /*!
  289.  * Constructs an array of NSURLs of the currently selected tabs within the session restore table view.
  290.  *
  291.  * @param tabs An array of all the tabs within the table view.
  292.  *
  293.  * @return An array of NUSRLs
  294.  */
  295. - (NSMutableArray *)_constructArrayOfSelectedTabURLs:(NSMutableArray *)tabs
  296. {
  297.     NSMutableArray *tabURLs = [NSMutableArray array];
  298.    
  299.     for (STSessionRestoreTab *tab in tabs)
  300.     {
  301.         if ([[tab tabEnabled] boolValue]) {
  302.             [tabURLs addObject:[tab tabURL]];
  303.         }
  304.     }
  305.    
  306.     return tabURLs;
  307. }
  308.  
  309. /*!
  310.  * Constructs an array of STSessionRestoreTabs from the supplied tab array.
  311.  *
  312.  * @param array An array of saved tabs
  313.  *
  314.  * @return An array of STSessionRestoreTabs
  315.  */
  316. - (NSMutableArray *)_constructArrayOfTabsFromArray:(NSMutableArray *)array
  317. {
  318.     NSMutableArray *tabs = [NSMutableArray array];
  319.    
  320.     for (NSArray *savedTabs in array)
  321.     {
  322.         NSDictionary *tabDictionary;
  323.         NSEnumerator *tabEnumerator = [savedTabs objectEnumerator];
  324.        
  325.         while ((tabDictionary = [tabEnumerator nextObject]))
  326.         {
  327.             NSString *tabTile = [tabDictionary objectForKey:STTabTitleKey];
  328.             NSURL *tabURL     = [tabDictionary objectForKey:STTabURLKey];
  329.             NSImage *tabIcon  = [tabDictionary objectForKey:STTabIconKey];
  330.            
  331.             if ((tabTile) && (tabURL) && (tabIcon)) {
  332.                 [tabs addObject:[STSessionRestoreTab tabWithTitle:tabTile url:tabURL icon:tabIcon]];
  333.             }
  334.         }
  335.     }
  336.    
  337.     return tabs;
  338. }
  339.  
  340. @end
  341.