| Index: chrome/browser/ui/views/base_shell_dialog_win.h
|
| diff --git a/chrome/browser/ui/views/base_shell_dialog_win.h b/chrome/browser/ui/views/base_shell_dialog_win.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..df1cd9b274b7e527fe79d449b0acd2811f0d7632
|
| --- /dev/null
|
| +++ b/chrome/browser/ui/views/base_shell_dialog_win.h
|
| @@ -0,0 +1,115 @@
|
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#ifndef CHROME_BROWSER_UI_VIEWS_BASE_SHELL_DIALOG_WIN_H_
|
| +#define CHROME_BROWSER_UI_VIEWS_BASE_SHELL_DIALOG_WIN_H_
|
| +#pragma once
|
| +
|
| +#include <set>
|
| +
|
| +#include "chrome/browser/ui/base_shell_dialog.h"
|
| +#include "base/threading/thread.h"
|
| +#include <shlobj.h>
|
| +
|
| +// Helpers to show certain types of Windows shell dialogs in a way that doesn't
|
| +// block the UI of the entire app.
|
| +
|
| +class ShellDialogThread : public base::Thread {
|
| + public:
|
| + ShellDialogThread() : base::Thread("Chrome_ShellDialogThread") { }
|
| + ~ShellDialogThread() {
|
| + Stop();
|
| + }
|
| +
|
| + protected:
|
| + void Init() {
|
| + // Initializes the COM library on the current thread.
|
| + CoInitialize(NULL);
|
| + }
|
| +
|
| + void CleanUp() {
|
| + // Closes the COM library on the current thread. CoInitialize must
|
| + // be balanced by a corresponding call to CoUninitialize.
|
| + CoUninitialize();
|
| + }
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(ShellDialogThread);
|
| +};
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +// A base class for all shell dialog implementations that handles showing a
|
| +// shell dialog modally on its own thread.
|
| +class BaseShellDialogImpl {
|
| + public:
|
| + BaseShellDialogImpl();
|
| + virtual ~BaseShellDialogImpl();
|
| +
|
| + protected:
|
| + // Represents a run of a dialog.
|
| + struct RunState {
|
| + // Owning HWND, may be null.
|
| + HWND owner;
|
| +
|
| + // Thread dialog is run on.
|
| + base::Thread* dialog_thread;
|
| + };
|
| +
|
| + // Called at the beginning of a modal dialog run. Disables the owner window
|
| + // and tracks it. Returns the message loop of the thread that the dialog will
|
| + // be run on.
|
| + RunState BeginRun(HWND owner);
|
| +
|
| + // Cleans up after a dialog run. If the run_state has a valid HWND this makes
|
| + // sure that the window is enabled. This is essential because BeginRun
|
| + // aggressively guards against multiple modal dialogs per HWND. Must be called
|
| + // on the UI thread after the result of the dialog has been determined.
|
| + //
|
| + // In addition this deletes the Thread in RunState.
|
| + void EndRun(RunState run_state);
|
| +
|
| + // Returns true if a modal shell dialog is currently active for the specified
|
| + // owner. Must be called on the UI thread.
|
| + bool IsRunningDialogForOwner(HWND owner) const;
|
| +
|
| + // Disables the window |owner|. Can be run from either the ui or the dialog
|
| + // thread. Can be called on either the UI or the dialog thread. This function
|
| + // is called on the dialog thread after the modal Windows Common dialog
|
| + // functions return because Windows automatically re-enables the owning
|
| + // window when those functions return, but we don't actually want them to be
|
| + // re-enabled until the response of the dialog propagates back to the UI
|
| + // thread, so we disable the owner manually after the Common dialog function
|
| + // returns.
|
| + void DisableOwner(HWND owner);
|
| +
|
| + private:
|
| + // Creates a thread to run a shell dialog on. Each dialog requires its own
|
| + // thread otherwise in some situations where a singleton owns a single
|
| + // instance of this object we can have a situation where a modal dialog in
|
| + // one window blocks the appearance of a modal dialog in another.
|
| + static base::Thread* CreateDialogThread();
|
| +
|
| + // Enables the window |owner_|. Can only be run from the ui thread.
|
| + void EnableOwner(HWND owner);
|
| +
|
| + // A list of windows that currently own active shell dialogs for this
|
| + // instance. For example, if the DownloadManager owns an instance of this
|
| + // object and there are two browser windows open both with Save As dialog
|
| + // boxes active, this list will consist of the two browser windows' HWNDs.
|
| + // The derived class must call EndRun once the dialog is done showing to
|
| + // remove the owning HWND from this list.
|
| + // This object is static since it is maintained for all instances of this
|
| + // object - i.e. you can't have two file pickers open for the
|
| + // same owner, even though they might be represented by different instances
|
| + // of this object.
|
| + // This set only contains non-null HWNDs. NULL hwnds are not added to this
|
| + // list.
|
| + typedef std::set<HWND> Owners;
|
| + static Owners owners_;
|
| + static int instance_count_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(BaseShellDialogImpl);
|
| +};
|
| +
|
| +#endif // CHROME_BROWSER_UI_VIEWS_BASE_SHELL_DIALOG_WIN_H_
|
|
|