Home | History | Annotate | Download | only in applescript
      1 // Copyright (c) 2012 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/mac/scoped_nsobject.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/time/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/ui/browser.h"
     15 #include "chrome/browser/ui/browser_commands.h"
     16 #include "chrome/browser/ui/browser_finder.h"
     17 #include "chrome/browser/ui/browser_navigator.h"
     18 #include "chrome/browser/ui/browser_tabstrip.h"
     19 #include "chrome/browser/ui/browser_window.h"
     20 #include "chrome/browser/ui/cocoa/applescript/constants_applescript.h"
     21 #include "chrome/browser/ui/cocoa/applescript/error_applescript.h"
     22 #import "chrome/browser/ui/cocoa/applescript/tab_applescript.h"
     23 #include "chrome/browser/ui/host_desktop.h"
     24 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
     25 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     26 #include "chrome/common/url_constants.h"
     27 #include "content/public/browser/web_contents.h"
     28 
     29 @interface WindowAppleScript(WindowAppleScriptPrivateMethods)
     30 // The NSWindow that corresponds to this window.
     31 - (NSWindow*)nativeHandle;
     32 @end
     33 
     34 @implementation WindowAppleScript
     35 
     36 - (id)init {
     37   // Check which mode to open a new window.
     38   NSScriptCommand* command = [NSScriptCommand currentCommand];
     39   NSString* mode = [[[command evaluatedArguments]
     40       objectForKey:@"KeyDictionary"] objectForKey:@"mode"];
     41   AppController* appDelegate = [NSApp delegate];
     42 
     43   Profile* lastProfile = [appDelegate lastProfile];
     44 
     45   if (!lastProfile) {
     46     AppleScript::SetError(AppleScript::errGetProfile);
     47     return nil;
     48   }
     49 
     50   Profile* profile;
     51   if ([mode isEqualToString:AppleScript::kIncognitoWindowMode]) {
     52     profile = lastProfile->GetOffTheRecordProfile();
     53   }
     54   else if ([mode isEqualToString:AppleScript::kNormalWindowMode] || !mode) {
     55     profile = lastProfile;
     56   } else {
     57     // Mode cannot be anything else
     58     AppleScript::SetError(AppleScript::errInvalidMode);
     59     return nil;
     60   }
     61   // Set the mode to nil, to ensure that it is not set once more.
     62   [[[command evaluatedArguments] objectForKey:@"KeyDictionary"]
     63       setValue:nil forKey:@"mode"];
     64   return [self initWithProfile:profile];
     65 }
     66 
     67 - (id)initWithProfile:(Profile*)aProfile {
     68   if (!aProfile) {
     69     [self release];
     70     return nil;
     71   }
     72 
     73   if ((self = [super init])) {
     74     browser_ = new Browser(
     75         Browser::CreateParams(aProfile, chrome::HOST_DESKTOP_TYPE_NATIVE));
     76     chrome::NewTab(browser_);
     77     browser_->window()->Show();
     78     base::scoped_nsobject<NSNumber> numID(
     79         [[NSNumber alloc] initWithInt:browser_->session_id().id()]);
     80     [self setUniqueID:numID];
     81   }
     82   return self;
     83 }
     84 
     85 - (id)initWithBrowser:(Browser*)aBrowser {
     86   if (!aBrowser) {
     87     [self release];
     88     return nil;
     89   }
     90 
     91   if ((self = [super init])) {
     92     // It is safe to be weak, if a window goes away (eg user closing a window)
     93     // the applescript runtime calls appleScriptWindows in
     94     // BrowserCrApplication and this particular window is never returned.
     95     browser_ = aBrowser;
     96     base::scoped_nsobject<NSNumber> numID(
     97         [[NSNumber alloc] initWithInt:browser_->session_id().id()]);
     98     [self setUniqueID:numID];
     99   }
    100   return self;
    101 }
    102 
    103 - (NSWindow*)nativeHandle {
    104   // window() can be NULL during startup.
    105   if (browser_->window())
    106     return browser_->window()->GetNativeWindow();
    107   return nil;
    108 }
    109 
    110 - (NSNumber*)activeTabIndex {
    111   // Note: applescript is 1-based, that is lists begin with index 1.
    112   int activeTabIndex = browser_->tab_strip_model()->active_index() + 1;
    113   if (!activeTabIndex) {
    114     return nil;
    115   }
    116   return [NSNumber numberWithInt:activeTabIndex];
    117 }
    118 
    119 - (void)setActiveTabIndex:(NSNumber*)anActiveTabIndex {
    120   // Note: applescript is 1-based, that is lists begin with index 1.
    121   int atIndex = [anActiveTabIndex intValue] - 1;
    122   if (atIndex >= 0 && atIndex < browser_->tab_strip_model()->count())
    123     browser_->tab_strip_model()->ActivateTabAt(atIndex, true);
    124   else
    125     AppleScript::SetError(AppleScript::errInvalidTabIndex);
    126 }
    127 
    128 - (NSString*)mode {
    129   Profile* profile = browser_->profile();
    130   if (profile->IsOffTheRecord())
    131     return AppleScript::kIncognitoWindowMode;
    132   return AppleScript::kNormalWindowMode;
    133 }
    134 
    135 - (void)setMode:(NSString*)theMode {
    136   // cannot set mode after window is created.
    137   if (theMode) {
    138     AppleScript::SetError(AppleScript::errSetMode);
    139   }
    140 }
    141 
    142 - (TabAppleScript*)activeTab {
    143   TabAppleScript* currentTab =
    144       [[[TabAppleScript alloc] initWithWebContents:
    145           browser_->tab_strip_model()->GetActiveWebContents()] autorelease];
    146   [currentTab setContainer:self
    147                   property:AppleScript::kTabsProperty];
    148   return currentTab;
    149 }
    150 
    151 - (NSArray*)tabs {
    152   TabStripModel* tabStrip = browser_->tab_strip_model();
    153   NSMutableArray* tabs = [NSMutableArray arrayWithCapacity:tabStrip->count()];
    154 
    155   for (int i = 0; i < tabStrip->count(); ++i) {
    156     // Check to see if tab is closing.
    157     content::WebContents* webContents = tabStrip->GetWebContentsAt(i);
    158     if (webContents->IsBeingDestroyed()) {
    159       continue;
    160     }
    161 
    162     base::scoped_nsobject<TabAppleScript> tab(
    163         [[TabAppleScript alloc] initWithWebContents:webContents]);
    164     [tab setContainer:self
    165              property:AppleScript::kTabsProperty];
    166     [tabs addObject:tab];
    167   }
    168   return tabs;
    169 }
    170 
    171 - (void)insertInTabs:(TabAppleScript*)aTab {
    172   // This method gets called when a new tab is created so
    173   // the container and property are set here.
    174   [aTab setContainer:self
    175             property:AppleScript::kTabsProperty];
    176 
    177   // Set how long it takes a tab to be created.
    178   base::TimeTicks newTabStartTime = base::TimeTicks::Now();
    179   content::WebContents* contents = chrome::AddSelectedTabWithURL(
    180       browser_,
    181       GURL(chrome::kChromeUINewTabURL),
    182       ui::PAGE_TRANSITION_TYPED);
    183   CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(contents);
    184   core_tab_helper->set_new_tab_start_time(newTabStartTime);
    185   [aTab setWebContents:contents];
    186 }
    187 
    188 - (void)insertInTabs:(TabAppleScript*)aTab atIndex:(int)index {
    189   // This method gets called when a new tab is created so
    190   // the container and property are set here.
    191   [aTab setContainer:self
    192             property:AppleScript::kTabsProperty];
    193 
    194   // Set how long it takes a tab to be created.
    195   base::TimeTicks newTabStartTime = base::TimeTicks::Now();
    196   chrome::NavigateParams params(browser_, GURL(chrome::kChromeUINewTabURL),
    197                                 ui::PAGE_TRANSITION_TYPED);
    198   params.disposition = NEW_FOREGROUND_TAB;
    199   params.tabstrip_index = index;
    200   chrome::Navigate(&params);
    201   CoreTabHelper* core_tab_helper =
    202       CoreTabHelper::FromWebContents(params.target_contents);
    203   core_tab_helper->set_new_tab_start_time(newTabStartTime);
    204 
    205   [aTab setWebContents:params.target_contents];
    206 }
    207 
    208 - (void)removeFromTabsAtIndex:(int)index {
    209   if (index < 0 || index >= browser_->tab_strip_model()->count())
    210     return;
    211   browser_->tab_strip_model()->CloseWebContentsAt(
    212       index, TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
    213 }
    214 
    215 - (NSNumber*)orderedIndex {
    216   return [NSNumber numberWithInt:[[self nativeHandle] orderedIndex]];
    217 }
    218 
    219 - (void)setOrderedIndex:(NSNumber*)anIndex {
    220   int index = [anIndex intValue] - 1;
    221   if (index < 0 || index >= static_cast<int>(chrome::GetTotalBrowserCount())) {
    222     AppleScript::SetError(AppleScript::errWrongIndex);
    223     return;
    224   }
    225   [[self nativeHandle] setOrderedIndex:index];
    226 }
    227 
    228 - (NSComparisonResult)windowComparator:(WindowAppleScript*)otherWindow {
    229   int thisIndex = [[self orderedIndex] intValue];
    230   int otherIndex = [[otherWindow orderedIndex] intValue];
    231   if (thisIndex < otherIndex)
    232     return NSOrderedAscending;
    233   else if (thisIndex > otherIndex)
    234     return NSOrderedDescending;
    235   // Indexes can never be same.
    236   NOTREACHED();
    237   return NSOrderedSame;
    238 }
    239 
    240 // Get and set values from the associated NSWindow.
    241 - (id)valueForUndefinedKey:(NSString*)key {
    242   return [[self nativeHandle] valueForKey:key];
    243 }
    244 
    245 - (void)setValue:(id)value forUndefinedKey:(NSString*)key {
    246   [[self nativeHandle] setValue:(id)value forKey:key];
    247 }
    248 
    249 - (void)handlesCloseScriptCommand:(NSCloseCommand*)command {
    250   // window() can be NULL during startup.
    251   if (browser_->window())
    252     browser_->window()->Close();
    253 }
    254 
    255 - (NSNumber*)presenting {
    256   BOOL presentingValue = NO;
    257   if (browser_->window())
    258     presentingValue = browser_->window()->IsFullscreenWithoutChrome();
    259   return [NSNumber numberWithBool:presentingValue];
    260 }
    261 
    262 - (void)handlesEnterPresentationMode:(NSScriptCommand*)command {
    263   if (browser_->window()) {
    264     browser_->window()->EnterFullscreen(
    265         GURL(), FEB_TYPE_FULLSCREEN_EXIT_INSTRUCTION);
    266   }
    267 }
    268 
    269 - (void)handlesExitPresentationMode:(NSScriptCommand*)command {
    270   if (browser_->window())
    271     browser_->window()->ExitFullscreen();
    272 }
    273 
    274 @end
    275