Home | History | Annotate | Download | only in applescript
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #import "chrome/browser/ui/cocoa/applescript/window_applescript.h"
      6 
      7 #include "base/logging.h"
      8 #import "base/memory/scoped_nsobject.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/time.h"
     11 #import "chrome/browser/app_controller_mac.h"
     12 #import "chrome/browser/chrome_browser_application_mac.h"
     13 #include "chrome/browser/profiles/profile.h"
     14 #include "chrome/browser/tabs/tab_strip_model.h"
     15 #include "chrome/browser/ui/browser.h"
     16 #include "chrome/browser/ui/browser_list.h"
     17 #include "chrome/browser/ui/browser_navigator.h"
     18 #include "chrome/browser/ui/browser_window.h"
     19 #include "chrome/browser/ui/cocoa/applescript/constants_applescript.h"
     20 #include "chrome/browser/ui/cocoa/applescript/error_applescript.h"
     21 #import "chrome/browser/ui/cocoa/applescript/tab_applescript.h"
     22 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
     23 #include "chrome/common/url_constants.h"
     24 #include "content/browser/tab_contents/tab_contents.h"
     25 
     26 @interface WindowAppleScript(WindowAppleScriptPrivateMethods)
     27 // The NSWindow that corresponds to this window.
     28 - (NSWindow*)nativeHandle;
     29 @end
     30 
     31 @implementation WindowAppleScript
     32 
     33 - (id)init {
     34   // Check which mode to open a new window.
     35   NSScriptCommand* command = [NSScriptCommand currentCommand];
     36   NSString* mode = [[[command evaluatedArguments]
     37       objectForKey:@"KeyDictionary"] objectForKey:@"mode"];
     38   AppController* appDelegate = [NSApp delegate];
     39 
     40   Profile* defaultProfile = [appDelegate defaultProfile];
     41 
     42   if (!defaultProfile) {
     43     AppleScript::SetError(AppleScript::errGetProfile);
     44     return nil;
     45   }
     46 
     47   Profile* profile;
     48   if ([mode isEqualToString:AppleScript::kIncognitoWindowMode]) {
     49     profile = defaultProfile->GetOffTheRecordProfile();
     50   }
     51   else if ([mode isEqualToString:AppleScript::kNormalWindowMode] || !mode) {
     52     profile = defaultProfile;
     53   } else {
     54     // Mode cannot be anything else
     55     AppleScript::SetError(AppleScript::errInvalidMode);
     56     return nil;
     57   }
     58   // Set the mode to nil, to ensure that it is not set once more.
     59   [[[command evaluatedArguments] objectForKey:@"KeyDictionary"]
     60       setValue:nil forKey:@"mode"];
     61   return [self initWithProfile:profile];
     62 }
     63 
     64 - (id)initWithProfile:(Profile*)aProfile {
     65   if (!aProfile) {
     66     [self release];
     67     return nil;
     68   }
     69 
     70   if ((self = [super init])) {
     71     browser_ = Browser::Create(aProfile);
     72     browser_->NewTab();
     73     browser_->window()->Show();
     74     scoped_nsobject<NSNumber> numID(
     75         [[NSNumber alloc] initWithInt:browser_->session_id().id()]);
     76     [self setUniqueID:numID];
     77   }
     78   return self;
     79 }
     80 
     81 - (id)initWithBrowser:(Browser*)aBrowser {
     82   if (!aBrowser) {
     83     [self release];
     84     return nil;
     85   }
     86 
     87   if ((self = [super init])) {
     88     // It is safe to be weak, if a window goes away (eg user closing a window)
     89     // the applescript runtime calls appleScriptWindows in
     90     // BrowserCrApplication and this particular window is never returned.
     91     browser_ = aBrowser;
     92     scoped_nsobject<NSNumber> numID(
     93         [[NSNumber alloc] initWithInt:browser_->session_id().id()]);
     94     [self setUniqueID:numID];
     95   }
     96   return self;
     97 }
     98 
     99 - (NSWindow*)nativeHandle {
    100   // window() can be NULL during startup.
    101   if (browser_->window())
    102     return browser_->window()->GetNativeHandle();
    103   return nil;
    104 }
    105 
    106 - (NSNumber*)activeTabIndex {
    107   // Note: applescript is 1-based, that is lists begin with index 1.
    108   int activeTabIndex = browser_->active_index() + 1;
    109   if (!activeTabIndex) {
    110     return nil;
    111   }
    112   return [NSNumber numberWithInt:activeTabIndex];
    113 }
    114 
    115 - (void)setActiveTabIndex:(NSNumber*)anActiveTabIndex {
    116   // Note: applescript is 1-based, that is lists begin with index 1.
    117   int atIndex = [anActiveTabIndex intValue] - 1;
    118   if (atIndex >= 0 && atIndex < browser_->tab_count())
    119     browser_->ActivateTabAt(atIndex, true);
    120   else
    121     AppleScript::SetError(AppleScript::errInvalidTabIndex);
    122 }
    123 
    124 - (NSString*)mode {
    125   Profile* profile = browser_->profile();
    126   if (profile->IsOffTheRecord())
    127     return AppleScript::kIncognitoWindowMode;
    128   return AppleScript::kNormalWindowMode;
    129 }
    130 
    131 - (void)setMode:(NSString*)theMode {
    132   // cannot set mode after window is created.
    133   if (theMode) {
    134     AppleScript::SetError(AppleScript::errSetMode);
    135   }
    136 }
    137 
    138 - (TabAppleScript*)activeTab {
    139   TabAppleScript* currentTab =
    140       [[[TabAppleScript alloc]
    141           initWithTabContent:browser_->GetSelectedTabContentsWrapper()]
    142               autorelease];
    143   [currentTab setContainer:self
    144                   property:AppleScript::kTabsProperty];
    145   return currentTab;
    146 }
    147 
    148 - (NSArray*)tabs {
    149   NSMutableArray* tabs = [NSMutableArray
    150       arrayWithCapacity:browser_->tab_count()];
    151 
    152   for (int i = 0; i < browser_->tab_count(); ++i) {
    153     // Check to see if tab is closing.
    154     if (browser_->GetTabContentsAt(i)->is_being_destroyed()) {
    155       continue;
    156     }
    157 
    158     scoped_nsobject<TabAppleScript> tab(
    159         [[TabAppleScript alloc]
    160             initWithTabContent:(browser_->GetTabContentsWrapperAt(i))]);
    161     [tab setContainer:self
    162              property:AppleScript::kTabsProperty];
    163     [tabs addObject:tab];
    164   }
    165   return tabs;
    166 }
    167 
    168 - (void)insertInTabs:(TabAppleScript*)aTab {
    169   // This method gets called when a new tab is created so
    170   // the container and property are set here.
    171   [aTab setContainer:self
    172             property:AppleScript::kTabsProperty];
    173 
    174   // Set how long it takes a tab to be created.
    175   base::TimeTicks newTabStartTime = base::TimeTicks::Now();
    176   TabContentsWrapper* contents =
    177       browser_->AddSelectedTabWithURL(GURL(chrome::kChromeUINewTabURL),
    178                                       PageTransition::TYPED);
    179   contents->tab_contents()->set_new_tab_start_time(newTabStartTime);
    180   [aTab setTabContent:contents];
    181 }
    182 
    183 - (void)insertInTabs:(TabAppleScript*)aTab atIndex:(int)index {
    184   // This method gets called when a new tab is created so
    185   // the container and property are set here.
    186   [aTab setContainer:self
    187             property:AppleScript::kTabsProperty];
    188 
    189   // Set how long it takes a tab to be created.
    190   base::TimeTicks newTabStartTime = base::TimeTicks::Now();
    191   browser::NavigateParams params(browser_,
    192                                  GURL(chrome::kChromeUINewTabURL),
    193                                  PageTransition::TYPED);
    194   params.disposition = NEW_FOREGROUND_TAB;
    195   params.tabstrip_index = index;
    196   browser::Navigate(&params);
    197   params.target_contents->tab_contents()->set_new_tab_start_time(
    198       newTabStartTime);
    199 
    200   [aTab setTabContent:params.target_contents];
    201 }
    202 
    203 - (void)removeFromTabsAtIndex:(int)index {
    204   browser_->tabstrip_model()->DetachTabContentsAt(index);
    205 }
    206 
    207 - (NSNumber*)orderedIndex{
    208   return [NSNumber numberWithInt:[[self nativeHandle] orderedIndex]];
    209 }
    210 
    211 - (void)setOrderedIndex:(NSNumber*)anIndex {
    212   int index = [anIndex intValue] - 1;
    213   if (index < 0 || index >= (int)BrowserList::size()) {
    214     AppleScript::SetError(AppleScript::errWrongIndex);
    215     return;
    216   }
    217   [[self nativeHandle] setOrderedIndex:index];
    218 }
    219 
    220 - (NSComparisonResult)windowComparator:(WindowAppleScript*)otherWindow {
    221   int thisIndex = [[self orderedIndex] intValue];
    222   int otherIndex = [[otherWindow orderedIndex] intValue];
    223   if (thisIndex < otherIndex)
    224     return NSOrderedAscending;
    225   else if (thisIndex > otherIndex)
    226     return NSOrderedDescending;
    227   // Indexes can never be same.
    228   NOTREACHED();
    229   return NSOrderedSame;
    230 }
    231 
    232 // Get and set values from the associated NSWindow.
    233 - (id)valueForUndefinedKey:(NSString*)key {
    234   return [[self nativeHandle] valueForKey:key];
    235 }
    236 
    237 - (void)setValue:(id)value forUndefinedKey:(NSString*)key {
    238   [[self nativeHandle] setValue:(id)value forKey:key];
    239 }
    240 
    241 - (void)handlesCloseScriptCommand:(NSCloseCommand*)command {
    242   // window() can be NULL during startup.
    243   if (browser_->window())
    244     browser_->window()->Close();
    245 }
    246 
    247 @end
    248