- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / applescript / window_applescript.mm
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       content::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                                 content::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