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