Commit 25d0eddc authored by ananta@chromium.org's avatar ananta@chromium.org

Added support for displaying the select folder picker in Chrome ASH on Windows 8.

The current behavior is that the select folder picker displays in desktop mode even when
when performed in ASH.

Fixes are as below:-
1. In the Chrome browser added plumbing in the SelectFileDialogImpl class to forward this
   operation of to the metro viewer process via the newly added function HandedSelectFolder
   which lives in the aura namespace in the remote_window_host_win.cc file.

2. In the metro viewer code added a new class FolderPickerSession which provides the functionality
   for displaying the metro select folder picker and returning the results from the same.

3. The following IPC messages provide the necessary functionality to funnel the request
   and the result between the browser and the metro viewer process.
   MetroViewerHostMsg_DisplaySelectFolder
   MetroViewerHostMsg_SelectFolderDone

I also added code to save away the metro root window in the RemoteRootWindowHostWin class
when we receive the MetroViewerHostMsg_SetTargetSurface IPC from the viewer process. We 
return this window in the RemoteRootWindowHostWin::GetAcceleratedWidget function. This
change although not needed for this CL seems correct. 

BUG=230087
R=cpu,sky

Review URL: https://codereview.chromium.org/14282002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@195224 0039d316-1c4b-4281-b951-d872f2087c98
parent 4a17172f
...@@ -93,6 +93,13 @@ void HandleSaveFile( ...@@ -93,6 +93,13 @@ void HandleSaveFile(
callback); callback);
} }
void HandleSelectFolder(const string16& title,
const SelectFolderCompletion& callback) {
DCHECK(aura::RemoteRootWindowHostWin::Instance());
aura::RemoteRootWindowHostWin::Instance()->HandleSelectFolder(title,
callback);
}
RemoteRootWindowHostWin* g_instance = NULL; RemoteRootWindowHostWin* g_instance = NULL;
RemoteRootWindowHostWin* RemoteRootWindowHostWin::Instance() { RemoteRootWindowHostWin* RemoteRootWindowHostWin::Instance() {
...@@ -145,6 +152,8 @@ bool RemoteRootWindowHostWin::OnMessageReceived(const IPC::Message& message) { ...@@ -145,6 +152,8 @@ bool RemoteRootWindowHostWin::OnMessageReceived(const IPC::Message& message) {
OnFileOpenDone) OnFileOpenDone)
IPC_MESSAGE_HANDLER(MetroViewerHostMsg_MultiFileOpenDone, IPC_MESSAGE_HANDLER(MetroViewerHostMsg_MultiFileOpenDone,
OnMultiFileOpenDone) OnMultiFileOpenDone)
IPC_MESSAGE_HANDLER(MetroViewerHostMsg_SelectFolderDone,
OnSelectFolderDone)
IPC_MESSAGE_UNHANDLED(handled = false) IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP() IPC_END_MESSAGE_MAP()
return handled; return handled;
...@@ -158,13 +167,13 @@ void RemoteRootWindowHostWin::HandleOpenFile( ...@@ -158,13 +167,13 @@ void RemoteRootWindowHostWin::HandleOpenFile(
if (!host_) if (!host_)
return; return;
// Can only one of these operations in flight. // Can only have one of these operations in flight.
DCHECK(file_open_completion_callback_.is_null()); DCHECK(file_open_completion_callback_.is_null());
file_open_completion_callback_ = callback; file_open_completion_callback_ = callback;
host_->Send(new MetroViewerHostMsg_DisplayFileOpen(title, host_->Send(new MetroViewerHostMsg_DisplayFileOpen(title,
filter, filter,
default_path.value(), default_path,
false)); false));
} }
...@@ -176,13 +185,13 @@ void RemoteRootWindowHostWin::HandleOpenMultipleFiles( ...@@ -176,13 +185,13 @@ void RemoteRootWindowHostWin::HandleOpenMultipleFiles(
if (!host_) if (!host_)
return; return;
// Can only one of these operations in flight. // Can only have one of these operations in flight.
DCHECK(multi_file_open_completion_callback_.is_null()); DCHECK(multi_file_open_completion_callback_.is_null());
multi_file_open_completion_callback_ = callback; multi_file_open_completion_callback_ = callback;
host_->Send(new MetroViewerHostMsg_DisplayFileOpen(title, host_->Send(new MetroViewerHostMsg_DisplayFileOpen(title,
filter, filter,
default_path.value(), default_path,
true)); true));
} }
...@@ -202,13 +211,26 @@ void RemoteRootWindowHostWin::HandleSaveFile( ...@@ -202,13 +211,26 @@ void RemoteRootWindowHostWin::HandleSaveFile(
params.filter = filter; params.filter = filter;
params.filter_index = filter_index; params.filter_index = filter_index;
// Can only one of these operations in flight. // Can only have one of these operations in flight.
DCHECK(file_saveas_completion_callback_.is_null()); DCHECK(file_saveas_completion_callback_.is_null());
file_saveas_completion_callback_ = callback; file_saveas_completion_callback_ = callback;
host_->Send(new MetroViewerHostMsg_DisplayFileSaveAs(params)); host_->Send(new MetroViewerHostMsg_DisplayFileSaveAs(params));
} }
void RemoteRootWindowHostWin::HandleSelectFolder(
const string16& title,
const SelectFolderCompletion& callback) {
if (!host_)
return;
// Can only have one of these operations in flight.
DCHECK(select_folder_completion_callback_.is_null());
select_folder_completion_callback_ = callback;
host_->Send(new MetroViewerHostMsg_DisplaySelectFolder(title));
}
void RemoteRootWindowHostWin::SetDelegate(RootWindowHostDelegate* delegate) { void RemoteRootWindowHostWin::SetDelegate(RootWindowHostDelegate* delegate) {
delegate_ = delegate; delegate_ = delegate;
} }
...@@ -404,17 +426,17 @@ void RemoteRootWindowHostWin::OnTouchMoved(int32 x, ...@@ -404,17 +426,17 @@ void RemoteRootWindowHostWin::OnTouchMoved(int32 x,
} }
void RemoteRootWindowHostWin::OnFileSaveAsDone(bool success, void RemoteRootWindowHostWin::OnFileSaveAsDone(bool success,
string16 filename, const base::FilePath& filename,
int filter_index) { int filter_index) {
if (success) { if (success) {
file_saveas_completion_callback_.Run( file_saveas_completion_callback_.Run(filename, filter_index, NULL);
base::FilePath(filename), filter_index, NULL);
} }
file_saveas_completion_callback_.Reset(); file_saveas_completion_callback_.Reset();
} }
void RemoteRootWindowHostWin::OnFileOpenDone(bool success, string16 filename) { void RemoteRootWindowHostWin::OnFileOpenDone(bool success,
const base::FilePath& filename) {
if (success) { if (success) {
file_open_completion_callback_.Run( file_open_completion_callback_.Run(
base::FilePath(filename), 0, NULL); base::FilePath(filename), 0, NULL);
...@@ -431,6 +453,15 @@ void RemoteRootWindowHostWin::OnMultiFileOpenDone( ...@@ -431,6 +453,15 @@ void RemoteRootWindowHostWin::OnMultiFileOpenDone(
multi_file_open_completion_callback_.Reset(); multi_file_open_completion_callback_.Reset();
} }
void RemoteRootWindowHostWin::OnSelectFolderDone(
bool success,
const base::FilePath& folder) {
if (success) {
select_folder_completion_callback_.Run(base::FilePath(folder), 0, NULL);
}
select_folder_completion_callback_.Reset();
}
void RemoteRootWindowHostWin::DispatchKeyboardMessage(ui::EventType type, void RemoteRootWindowHostWin::DispatchKeyboardMessage(ui::EventType type,
uint32 vkey, uint32 vkey,
uint32 repeat_count, uint32 repeat_count,
......
...@@ -38,6 +38,9 @@ typedef base::Callback<void(const std::vector<base::FilePath>&, void*)> ...@@ -38,6 +38,9 @@ typedef base::Callback<void(const std::vector<base::FilePath>&, void*)>
typedef base::Callback<void(const base::FilePath&, int, void*)> typedef base::Callback<void(const base::FilePath&, int, void*)>
SaveFileCompletion; SaveFileCompletion;
typedef base::Callback<void(const base::FilePath&, int, void*)>
SelectFolderCompletion;
// Handles the open file operation for Metro Chrome Ash. The callback passed in // Handles the open file operation for Metro Chrome Ash. The callback passed in
// is invoked when we receive the opened file name from the metro viewer. // is invoked when we receive the opened file name from the metro viewer.
AURA_EXPORT void HandleOpenFile( AURA_EXPORT void HandleOpenFile(
...@@ -65,6 +68,10 @@ AURA_EXPORT void HandleSaveFile( ...@@ -65,6 +68,10 @@ AURA_EXPORT void HandleSaveFile(
const string16& default_extension, const string16& default_extension,
const SaveFileCompletion& callback); const SaveFileCompletion& callback);
// Handles the select folder for Metro Chrome Ash. The callback passed in
// is invoked when we receive the folder name from the metro viewer.
AURA_EXPORT void HandleSelectFolder(const string16& title,
const SelectFolderCompletion& callback);
// RootWindowHost implementaton that receives events from a different // RootWindowHost implementaton that receives events from a different
// process. In the case of Windows this is the Windows 8 (aka Metro) // process. In the case of Windows this is the Windows 8 (aka Metro)
...@@ -103,6 +110,9 @@ class AURA_EXPORT RemoteRootWindowHostWin : public RootWindowHost { ...@@ -103,6 +110,9 @@ class AURA_EXPORT RemoteRootWindowHostWin : public RootWindowHost {
const string16& default_extension, const string16& default_extension,
const SaveFileCompletion& callback); const SaveFileCompletion& callback);
void HandleSelectFolder(const string16& title,
const SelectFolderCompletion& callback);
private: private:
explicit RemoteRootWindowHostWin(const gfx::Rect& bounds); explicit RemoteRootWindowHostWin(const gfx::Rect& bounds);
virtual ~RemoteRootWindowHostWin(); virtual ~RemoteRootWindowHostWin();
...@@ -131,12 +141,12 @@ class AURA_EXPORT RemoteRootWindowHostWin : public RootWindowHost { ...@@ -131,12 +141,12 @@ class AURA_EXPORT RemoteRootWindowHostWin : public RootWindowHost {
void OnTouchUp(int32 x, int32 y, uint64 timestamp, uint32 pointer_id); void OnTouchUp(int32 x, int32 y, uint64 timestamp, uint32 pointer_id);
void OnTouchMoved(int32 x, int32 y, uint64 timestamp, uint32 pointer_id); void OnTouchMoved(int32 x, int32 y, uint64 timestamp, uint32 pointer_id);
void OnFileSaveAsDone(bool success, void OnFileSaveAsDone(bool success,
string16 filename, const base::FilePath& filename,
int filter_index); int filter_index);
void OnFileOpenDone(bool success, string16 filename); void OnFileOpenDone(bool success, const base::FilePath& filename);
void OnMultiFileOpenDone(bool success, void OnMultiFileOpenDone(bool success,
const std::vector<base::FilePath>& files); const std::vector<base::FilePath>& files);
void OnSelectFolderDone(bool success, const base::FilePath& folder);
// RootWindowHost overrides: // RootWindowHost overrides:
virtual void SetDelegate(RootWindowHostDelegate* delegate) OVERRIDE; virtual void SetDelegate(RootWindowHostDelegate* delegate) OVERRIDE;
virtual RootWindow* GetRootWindow() OVERRIDE; virtual RootWindow* GetRootWindow() OVERRIDE;
...@@ -185,10 +195,11 @@ class AURA_EXPORT RemoteRootWindowHostWin : public RootWindowHost { ...@@ -185,10 +195,11 @@ class AURA_EXPORT RemoteRootWindowHostWin : public RootWindowHost {
scoped_ptr<ui::ViewProp> prop_; scoped_ptr<ui::ViewProp> prop_;
// Saved callbacks which inform the caller about the result of the open file/ // Saved callbacks which inform the caller about the result of the open file/
// save file operations. // save file/select operations.
OpenFileCompletion file_open_completion_callback_; OpenFileCompletion file_open_completion_callback_;
OpenMultipleFilesCompletion multi_file_open_completion_callback_; OpenMultipleFilesCompletion multi_file_open_completion_callback_;
SaveFileCompletion file_saveas_completion_callback_; SaveFileCompletion file_saveas_completion_callback_;
SelectFolderCompletion select_folder_completion_callback_;
DISALLOW_COPY_AND_ASSIGN(RemoteRootWindowHostWin); DISALLOW_COPY_AND_ASSIGN(RemoteRootWindowHostWin);
}; };
......
...@@ -73,18 +73,22 @@ IPC_MESSAGE_CONTROL4(MetroViewerHostMsg_TouchMoved, ...@@ -73,18 +73,22 @@ IPC_MESSAGE_CONTROL4(MetroViewerHostMsg_TouchMoved,
// Informs the browser of the result of a file save as operation. // Informs the browser of the result of a file save as operation.
IPC_MESSAGE_CONTROL3(MetroViewerHostMsg_FileSaveAsDone, IPC_MESSAGE_CONTROL3(MetroViewerHostMsg_FileSaveAsDone,
bool, /* success */ bool, /* success */
string16, /* filename */ base::FilePath, /* filename */
int) /* filter_index */ int) /* filter_index */
// Informs the browser of the result of a file open operation. // Informs the browser of the result of a file open operation.
IPC_MESSAGE_CONTROL2(MetroViewerHostMsg_FileOpenDone, IPC_MESSAGE_CONTROL2(MetroViewerHostMsg_FileOpenDone,
bool, /* success */ bool, /* success */
string16) /* filename */ base::FilePath) /* filename */
IPC_MESSAGE_CONTROL2(MetroViewerHostMsg_MultiFileOpenDone, IPC_MESSAGE_CONTROL2(MetroViewerHostMsg_MultiFileOpenDone,
bool, /* success */ bool, /* success */
std::vector<base::FilePath>) /* filenames */ std::vector<base::FilePath>) /* filenames */
// Informs the browser of the result of a select folder operation.
IPC_MESSAGE_CONTROL2(MetroViewerHostMsg_SelectFolderDone,
bool, /* success */
base::FilePath) /* filepath*/
// Messages sent from the browser to the viewer: // Messages sent from the browser to the viewer:
...@@ -100,7 +104,7 @@ IPC_STRUCT_BEGIN(MetroViewerHostMsg_SaveAsDialogParams) ...@@ -100,7 +104,7 @@ IPC_STRUCT_BEGIN(MetroViewerHostMsg_SaveAsDialogParams)
IPC_STRUCT_MEMBER(string16, title) IPC_STRUCT_MEMBER(string16, title)
// The suggested file name. // The suggested file name.
IPC_STRUCT_MEMBER(string16, suggested_name) IPC_STRUCT_MEMBER(base::FilePath, suggested_name)
// The save as filter to be used. // The save as filter to be used.
IPC_STRUCT_MEMBER(string16, filter) IPC_STRUCT_MEMBER(string16, filter)
...@@ -119,8 +123,11 @@ IPC_MESSAGE_CONTROL1(MetroViewerHostMsg_DisplayFileSaveAs, ...@@ -119,8 +123,11 @@ IPC_MESSAGE_CONTROL1(MetroViewerHostMsg_DisplayFileSaveAs,
// Requests the viewer to display the file open dialog. // Requests the viewer to display the file open dialog.
IPC_MESSAGE_CONTROL4(MetroViewerHostMsg_DisplayFileOpen, IPC_MESSAGE_CONTROL4(MetroViewerHostMsg_DisplayFileOpen,
string16, /* title */ string16, /* title */
string16, /* filter */ string16, /* filter */
string16, /* Default path */ base::FilePath, /* Default path */
bool) /* allow_multi_select */ bool) /* allow_multi_select */
// Requests the viewer to display the select folder dialog.
IPC_MESSAGE_CONTROL1(MetroViewerHostMsg_DisplaySelectFolder,
string16) /* title */
...@@ -575,6 +575,12 @@ void SelectFileDialogImpl::SelectFileImpl( ...@@ -575,6 +575,12 @@ void SelectFileDialogImpl::SelectFileImpl(
base::Bind(&ui::SelectFileDialog::Listener::MultiFilesSelected, base::Bind(&ui::SelectFileDialog::Listener::MultiFilesSelected,
base::Unretained(listener_))); base::Unretained(listener_)));
return; return;
} else if (type == SELECT_FOLDER) {
aura::HandleSelectFolder(
UTF16ToWide(title),
base::Bind(&ui::SelectFileDialog::Listener::FileSelected,
base::Unretained(listener_)));
return;
} }
} }
HWND owner = owning_window HWND owner = owning_window
......
...@@ -81,6 +81,8 @@ class ChromeChannelListener : public IPC::Listener { ...@@ -81,6 +81,8 @@ class ChromeChannelListener : public IPC::Listener {
OnDisplayFileOpenDialog) OnDisplayFileOpenDialog)
IPC_MESSAGE_HANDLER(MetroViewerHostMsg_DisplayFileSaveAs, IPC_MESSAGE_HANDLER(MetroViewerHostMsg_DisplayFileSaveAs,
OnDisplayFileSaveAsDialog) OnDisplayFileSaveAsDialog)
IPC_MESSAGE_HANDLER(MetroViewerHostMsg_DisplaySelectFolder,
OnDisplayFolderPicker)
IPC_MESSAGE_UNHANDLED(__debugbreak()) IPC_MESSAGE_UNHANDLED(__debugbreak())
IPC_END_MESSAGE_MAP() IPC_END_MESSAGE_MAP()
return true; return true;
...@@ -101,7 +103,7 @@ class ChromeChannelListener : public IPC::Listener { ...@@ -101,7 +103,7 @@ class ChromeChannelListener : public IPC::Listener {
void OnDisplayFileOpenDialog(const string16& title, void OnDisplayFileOpenDialog(const string16& title,
const string16& filter, const string16& filter,
const string16& default_path, const base::FilePath& default_path,
bool allow_multiple_files) { bool allow_multiple_files) {
ui_proxy_->PostTask(FROM_HERE, ui_proxy_->PostTask(FROM_HERE,
base::Bind(&ChromeAppViewAsh::OnDisplayFileOpenDialog, base::Bind(&ChromeAppViewAsh::OnDisplayFileOpenDialog,
...@@ -121,6 +123,14 @@ class ChromeChannelListener : public IPC::Listener { ...@@ -121,6 +123,14 @@ class ChromeChannelListener : public IPC::Listener {
params)); params));
} }
void OnDisplayFolderPicker(const string16& title) {
ui_proxy_->PostTask(
FROM_HERE,
base::Bind(&ChromeAppViewAsh::OnDisplayFolderPicker,
base::Unretained(app_view_),
title));
}
scoped_refptr<base::MessageLoopProxy> ui_proxy_; scoped_refptr<base::MessageLoopProxy> ui_proxy_;
ChromeAppViewAsh* app_view_; ChromeAppViewAsh* app_view_;
}; };
...@@ -468,22 +478,23 @@ void ChromeAppViewAsh::OnSetCursor(HCURSOR cursor) { ...@@ -468,22 +478,23 @@ void ChromeAppViewAsh::OnSetCursor(HCURSOR cursor) {
::SetCursor(HCURSOR(cursor)); ::SetCursor(HCURSOR(cursor));
} }
void ChromeAppViewAsh::OnDisplayFileOpenDialog(const string16& title, void ChromeAppViewAsh::OnDisplayFileOpenDialog(
const string16& filter, const string16& title,
const string16& default_path, const string16& filter,
bool allow_multiple_files) { const base::FilePath& default_path,
bool allow_multiple_files) {
DVLOG(1) << __FUNCTION__; DVLOG(1) << __FUNCTION__;
// The OpenFilePickerSession instance is deleted when we receive a // The OpenFilePickerSession instance is deleted when we receive a
// callback from the OpenFilePickerSession class about the completion of the // callback from the OpenFilePickerSession class about the completion of the
// operation. // operation.
OpenFilePickerSession* open_file_picker = FilePickerSessionBase* file_picker_ =
new OpenFilePickerSession(this, new OpenFilePickerSession(this,
title, title,
filter, filter,
default_path, default_path.value(),
allow_multiple_files); allow_multiple_files);
open_file_picker->Run(); file_picker_->Run();
} }
void ChromeAppViewAsh::OnDisplayFileSaveAsDialog( void ChromeAppViewAsh::OnDisplayFileSaveAsDialog(
...@@ -491,11 +502,20 @@ void ChromeAppViewAsh::OnDisplayFileSaveAsDialog( ...@@ -491,11 +502,20 @@ void ChromeAppViewAsh::OnDisplayFileSaveAsDialog(
DVLOG(1) << __FUNCTION__; DVLOG(1) << __FUNCTION__;
// The SaveFilePickerSession instance is deleted when we receive a // The SaveFilePickerSession instance is deleted when we receive a
// callback from the OpenFilePickerSession class about the completion of the // callback from the SaveFilePickerSession class about the completion of the
// operation. // operation.
SaveFilePickerSession* save_file_picker = FilePickerSessionBase* file_picker_ =
new SaveFilePickerSession(this, params); new SaveFilePickerSession(this, params);
save_file_picker->Run(); file_picker_->Run();
}
void ChromeAppViewAsh::OnDisplayFolderPicker(const string16& title) {
DVLOG(1) << __FUNCTION__;
// The FolderPickerSession instance is deleted when we receive a
// callback from the FolderPickerSession class about the completion of the
// operation.
FilePickerSessionBase* file_picker_ = new FolderPickerSession(this, title);
file_picker_->Run();
} }
void ChromeAppViewAsh::OnOpenFileCompleted( void ChromeAppViewAsh::OnOpenFileCompleted(
...@@ -509,7 +529,7 @@ void ChromeAppViewAsh::OnOpenFileCompleted( ...@@ -509,7 +529,7 @@ void ChromeAppViewAsh::OnOpenFileCompleted(
success, open_file_picker->filenames())); success, open_file_picker->filenames()));
} else { } else {
ui_channel_->Send(new MetroViewerHostMsg_FileOpenDone( ui_channel_->Send(new MetroViewerHostMsg_FileOpenDone(
success, open_file_picker->result())); success, base::FilePath(open_file_picker->result())));
} }
} }
delete open_file_picker; delete open_file_picker;
...@@ -523,12 +543,25 @@ void ChromeAppViewAsh::OnSaveFileCompleted( ...@@ -523,12 +543,25 @@ void ChromeAppViewAsh::OnSaveFileCompleted(
if (ui_channel_) { if (ui_channel_) {
ui_channel_->Send(new MetroViewerHostMsg_FileSaveAsDone( ui_channel_->Send(new MetroViewerHostMsg_FileSaveAsDone(
success, success,
save_file_picker->result(), base::FilePath(save_file_picker->result()),
save_file_picker->filter_index())); save_file_picker->filter_index()));
} }
delete save_file_picker; delete save_file_picker;
} }
void ChromeAppViewAsh::OnFolderPickerCompleted(
FolderPickerSession* folder_picker,
bool success) {
DVLOG(1) << __FUNCTION__;
DVLOG(1) << "Success: " << success;
if (ui_channel_) {
ui_channel_->Send(new MetroViewerHostMsg_SelectFolderDone(
success,
base::FilePath(folder_picker->result())));
}
delete folder_picker;
}
HRESULT ChromeAppViewAsh::OnActivate( HRESULT ChromeAppViewAsh::OnActivate(
winapp::Core::ICoreApplicationView*, winapp::Core::ICoreApplicationView*,
winapp::Activation::IActivatedEventArgs* args) { winapp::Activation::IActivatedEventArgs* args) {
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <windows.ui.input.h> #include <windows.ui.input.h>
#include <windows.ui.viewmanagement.h> #include <windows.ui.viewmanagement.h>
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/string16.h" #include "base/string16.h"
#include "ui/base/events/event_constants.h" #include "ui/base/events/event_constants.h"
...@@ -22,6 +23,8 @@ namespace IPC { ...@@ -22,6 +23,8 @@ namespace IPC {
class OpenFilePickerSession; class OpenFilePickerSession;
class SaveFilePickerSession; class SaveFilePickerSession;
class FolderPickerSession;
class FilePickerSessionBase;
struct MetroViewerHostMsg_SaveAsDialogParams; struct MetroViewerHostMsg_SaveAsDialogParams;
...@@ -45,10 +48,11 @@ class ChromeAppViewAsh ...@@ -45,10 +48,11 @@ class ChromeAppViewAsh
void OnSetCursor(HCURSOR cursor); void OnSetCursor(HCURSOR cursor);
void OnDisplayFileOpenDialog(const string16& title, void OnDisplayFileOpenDialog(const string16& title,
const string16& filter, const string16& filter,
const string16& default_path, const base::FilePath& default_path,
bool allow_multiple_files); bool allow_multiple_files);
void OnDisplayFileSaveAsDialog( void OnDisplayFileSaveAsDialog(
const MetroViewerHostMsg_SaveAsDialogParams& params); const MetroViewerHostMsg_SaveAsDialogParams& params);
void OnDisplayFolderPicker(const string16& title);
// This function is invoked when the open file operation completes. The // This function is invoked when the open file operation completes. The
// result of the operation is passed in along with the OpenFilePickerSession // result of the operation is passed in along with the OpenFilePickerSession
...@@ -64,6 +68,13 @@ class ChromeAppViewAsh ...@@ -64,6 +68,13 @@ class ChromeAppViewAsh
void OnSaveFileCompleted(SaveFilePickerSession* save_file_picker, void OnSaveFileCompleted(SaveFilePickerSession* save_file_picker,
bool success); bool success);
// This function is invoked when the folder picker operation completes. The
// result of the operation is passed in along with the FolderPickerSession
// instance which is deleted after we read the required information from
// the FolderPickerSession class.
void OnFolderPickerCompleted(FolderPickerSession* folder_picker,
bool success);
private: private:
HRESULT OnActivate(winapp::Core::ICoreApplicationView* view, HRESULT OnActivate(winapp::Core::ICoreApplicationView* view,
winapp::Activation::IActivatedEventArgs* args); winapp::Activation::IActivatedEventArgs* args);
...@@ -109,6 +120,7 @@ class ChromeAppViewAsh ...@@ -109,6 +120,7 @@ class ChromeAppViewAsh
EventRegistrationToken visibility_changed_token_; EventRegistrationToken visibility_changed_token_;
EventRegistrationToken accel_keydown_token_; EventRegistrationToken accel_keydown_token_;
EventRegistrationToken accel_keyup_token_; EventRegistrationToken accel_keyup_token_;
EventRegistrationToken window_activated_token_;
// Keep state about which button is currently down, if any, as PointerMoved // Keep state about which button is currently down, if any, as PointerMoved
// events do not contain that state, but Ash's MouseEvents need it. // events do not contain that state, but Ash's MouseEvents need it.
......
...@@ -377,7 +377,7 @@ SaveFilePickerSession::SaveFilePickerSession( ...@@ -377,7 +377,7 @@ SaveFilePickerSession::SaveFilePickerSession(
: FilePickerSessionBase(app_view, : FilePickerSessionBase(app_view,
params.title, params.title,
params.filter, params.filter,
params.suggested_name), params.suggested_name.value()),
filter_index_(params.filter_index) { filter_index_(params.filter_index) {
} }
...@@ -544,3 +544,72 @@ HRESULT SaveFilePickerSession::FilePickerDone(SaveFileAsyncOp* async, ...@@ -544,3 +544,72 @@ HRESULT SaveFilePickerSession::FilePickerDone(SaveFileAsyncOp* async,
return S_OK; return S_OK;
} }
FolderPickerSession::FolderPickerSession(ChromeAppViewAsh* app_view,
const string16& title)
: FilePickerSessionBase(app_view, title, L"", L"") {}
HRESULT FolderPickerSession::StartFilePicker() {
mswrw::HStringReference class_name(
RuntimeClass_Windows_Storage_Pickers_FolderPicker);
// Create the folder picker.
mswr::ComPtr<winstorage::Pickers::IFolderPicker> picker;
HRESULT hr = ::Windows::Foundation::ActivateInstance(
class_name.Get(), picker.GetAddressOf());
CheckHR(hr);
// Set the file type filter
mswr::ComPtr<winfoundtn::Collections::IVector<HSTRING>> filter;
hr = picker->get_FileTypeFilter(filter.GetAddressOf());
if (FAILED(hr))
return hr;
hr = filter->Append(mswrw::HStringReference(L"*").Get());
if (FAILED(hr))
return hr;
mswr::ComPtr<FolderPickerAsyncOp> completion;
hr = picker->PickSingleFolderAsync(&completion);
if (FAILED(hr))
return hr;
// Create the callback method.
typedef winfoundtn::IAsyncOperationCompletedHandler<
winstorage::StorageFolder*> HandlerDoneType;
mswr::ComPtr<HandlerDoneType> handler(mswr::Callback<HandlerDoneType>(
this, &FolderPickerSession::FolderPickerDone));
DCHECK(handler.Get() != NULL);
hr = completion->put_Completed(handler.Get());
return hr;
}
HRESULT FolderPickerSession::FolderPickerDone(FolderPickerAsyncOp* async,
AsyncStatus status) {
if (status == Completed) {
mswr::ComPtr<winstorage::IStorageFolder> folder;
HRESULT hr = async->GetResults(folder.GetAddressOf());
if (folder) {
mswr::ComPtr<winstorage::IStorageItem> storage_item;
if (SUCCEEDED(hr))
hr = folder.As(&storage_item);
mswrw::HString file_path;
if (SUCCEEDED(hr))
hr = storage_item->get_Path(file_path.GetAddressOf());
if (SUCCEEDED(hr)) {
string16 path_str = MakeStdWString(file_path.Get());
result_ = path_str;
success_ = true;
}
} else {
LOG(ERROR) << "NULL IStorageItem";
}
} else {
LOG(ERROR) << "Unexpected async status " << status;
}
app_view_->OnFolderPickerCompleted(this, success_);
return S_OK;
}
...@@ -144,5 +144,23 @@ class SaveFilePickerSession : public FilePickerSessionBase { ...@@ -144,5 +144,23 @@ class SaveFilePickerSession : public FilePickerSessionBase {
DISALLOW_COPY_AND_ASSIGN(SaveFilePickerSession); DISALLOW_COPY_AND_ASSIGN(SaveFilePickerSession);
}; };
// Provides functionality to display the folder picker.
class FolderPickerSession : public FilePickerSessionBase {
public:
explicit FolderPickerSession(ChromeAppViewAsh* app_view,
const string16& title);
private:
virtual HRESULT StartFilePicker() OVERRIDE;
typedef winfoundtn::IAsyncOperation<winstorage::StorageFolder*>
FolderPickerAsyncOp;
// Called asynchronously when the folder picker is done.
HRESULT FolderPickerDone(FolderPickerAsyncOp* async, AsyncStatus status);
DISALLOW_COPY_AND_ASSIGN(FolderPickerSession);
};
#endif // CHROME_BROWSER_UI_METRO_DRIVER_FILE_PICKER_ASH_H_ #endif // CHROME_BROWSER_UI_METRO_DRIVER_FILE_PICKER_ASH_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment