mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
b=671820 implement async nsIFilePicker::Open and make sync Show close window on response r=roc
--HG-- extra : transplant_source : %AC%C4%9AB%03%FC%29tE%3D%10X%7F%B4%ED%B6%07%D8%5C%BC
This commit is contained in:
parent
b018fea56e
commit
232b0c107b
@ -35,6 +35,17 @@ using namespace mozilla;
|
||||
|
||||
nsIFile *nsFilePicker::mPrevDisplayDirectory = nullptr;
|
||||
|
||||
// Some GObject functions expect functions for gpointer arguments.
|
||||
// gpointer is void* but C++ doesn't like casting functions to void*.
|
||||
template<class T> static inline gpointer
|
||||
FuncToGpointer(T aFunction)
|
||||
{
|
||||
return reinterpret_cast<gpointer>
|
||||
(reinterpret_cast<uintptr_t>
|
||||
// This cast just provides a warning if T is not a function.
|
||||
(reinterpret_cast<void (*)()>(aFunction)));
|
||||
}
|
||||
|
||||
// XXXdholbert -- this function is duplicated in nsPrintDialogGTK.cpp
|
||||
// and needs to be unified in some generic utility class.
|
||||
static GtkWindow *
|
||||
@ -177,6 +188,7 @@ NS_IMPL_ISUPPORTS1(nsFilePicker, nsIFilePicker)
|
||||
nsFilePicker::nsFilePicker()
|
||||
: mMode(nsIFilePicker::modeOpen),
|
||||
mSelectedType(0),
|
||||
mRunning(false),
|
||||
mAllowURLs(false)
|
||||
{
|
||||
}
|
||||
@ -362,6 +374,25 @@ nsFilePicker::Show(PRInt16 *aReturn)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aReturn);
|
||||
|
||||
nsresult rv = Open(nullptr);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
while (mRunning) {
|
||||
g_main_context_iteration(nullptr, TRUE);
|
||||
}
|
||||
|
||||
*aReturn = mResult;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFilePicker::Open(nsIFilePickerShownCallback *aCallback)
|
||||
{
|
||||
// Can't show two dialogs concurrently with the same filepicker
|
||||
if (mRunning)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
nsXPIDLCString title;
|
||||
title.Adopt(ToNewUTF8String(mTitle));
|
||||
|
||||
@ -398,8 +429,13 @@ nsFilePicker::Show(PRInt16 *aReturn)
|
||||
g_signal_connect(file_chooser, "update-preview", G_CALLBACK(UpdateFilePreviewWidget), img_preview);
|
||||
}
|
||||
|
||||
if (parent_widget && parent_widget->group) {
|
||||
gtk_window_group_add_window(parent_widget->group, GTK_WINDOW(file_chooser));
|
||||
GtkWindow *window = GTK_WINDOW(file_chooser);
|
||||
gtk_window_set_modal(window, TRUE);
|
||||
if (parent_widget) {
|
||||
gtk_window_set_destroy_with_parent(window, TRUE);
|
||||
if (parent_widget->group) {
|
||||
gtk_window_group_add_window(parent_widget->group, window);
|
||||
}
|
||||
}
|
||||
|
||||
NS_ConvertUTF16toUTF8 defaultName(mDefault);
|
||||
@ -475,13 +511,43 @@ nsFilePicker::Show(PRInt16 *aReturn)
|
||||
}
|
||||
|
||||
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(file_chooser), TRUE);
|
||||
gint response = gtk_dialog_run(GTK_DIALOG(file_chooser));
|
||||
|
||||
mRunning = true;
|
||||
mCallback = aCallback;
|
||||
NS_ADDREF_THIS();
|
||||
g_signal_connect(file_chooser, "response", G_CALLBACK(OnResponse), this);
|
||||
g_signal_connect(file_chooser, "destroy", G_CALLBACK(OnDestroy), this);
|
||||
gtk_widget_show(file_chooser);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsFilePicker::OnResponse(GtkWidget* file_chooser, gint response_id,
|
||||
gpointer user_data)
|
||||
{
|
||||
static_cast<nsFilePicker*>(user_data)->
|
||||
Done(file_chooser, response_id);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsFilePicker::OnDestroy(GtkWidget* file_chooser, gpointer user_data)
|
||||
{
|
||||
static_cast<nsFilePicker*>(user_data)->
|
||||
Done(file_chooser, GTK_RESPONSE_CANCEL);
|
||||
}
|
||||
|
||||
void
|
||||
nsFilePicker::Done(GtkWidget* file_chooser, gint response)
|
||||
{
|
||||
mRunning = false;
|
||||
|
||||
PRInt16 result;
|
||||
switch (response) {
|
||||
case GTK_RESPONSE_OK:
|
||||
case GTK_RESPONSE_ACCEPT:
|
||||
ReadValuesFromFileChooser(file_chooser);
|
||||
*aReturn = nsIFilePicker::returnOK;
|
||||
result = nsIFilePicker::returnOK;
|
||||
if (mMode == nsIFilePicker::modeSave) {
|
||||
nsCOMPtr<nsIFile> file;
|
||||
GetFile(getter_AddRefs(file));
|
||||
@ -489,7 +555,7 @@ nsFilePicker::Show(PRInt16 *aReturn)
|
||||
bool exists = false;
|
||||
file->Exists(&exists);
|
||||
if (exists)
|
||||
*aReturn = nsIFilePicker::returnReplace;
|
||||
result = nsIFilePicker::returnReplace;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -497,16 +563,32 @@ nsFilePicker::Show(PRInt16 *aReturn)
|
||||
case GTK_RESPONSE_CANCEL:
|
||||
case GTK_RESPONSE_CLOSE:
|
||||
case GTK_RESPONSE_DELETE_EVENT:
|
||||
*aReturn = nsIFilePicker::returnCancel;
|
||||
result = nsIFilePicker::returnCancel;
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_WARNING("Unexpected response");
|
||||
*aReturn = nsIFilePicker::returnCancel;
|
||||
result = nsIFilePicker::returnCancel;
|
||||
break;
|
||||
}
|
||||
|
||||
// A "response" signal won't be sent again but "destroy" will be.
|
||||
g_signal_handlers_disconnect_by_func(file_chooser,
|
||||
FuncToGpointer(OnDestroy), this);
|
||||
|
||||
// When response_id is GTK_RESPONSE_DELETE_EVENT or when called from
|
||||
// OnDestroy, the widget would be destroyed anyway but it is fine if
|
||||
// gtk_widget_destroy is called more than once. gtk_widget_destroy has
|
||||
// requests that any remaining references be released, but the reference
|
||||
// count will not be decremented again if GtkWindow's reference has already
|
||||
// been released.
|
||||
gtk_widget_destroy(file_chooser);
|
||||
|
||||
return NS_OK;
|
||||
if (mCallback) {
|
||||
mCallback->Done(result);
|
||||
mCallback = nullptr;
|
||||
} else {
|
||||
mResult = result;
|
||||
}
|
||||
NS_RELEASE_THIS();
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIFilePicker (less what's in nsBaseFilePicker)
|
||||
NS_IMETHOD Open(nsIFilePickerShownCallback *aCallback);
|
||||
NS_IMETHODIMP AppendFilters(PRInt32 aFilterMask);
|
||||
NS_IMETHODIMP AppendFilter(const nsAString& aTitle, const nsAString& aFilter);
|
||||
NS_IMETHODIMP SetDefaultString(const nsAString& aString);
|
||||
@ -38,6 +39,7 @@ public:
|
||||
NS_IMETHODIMP GetFiles(nsISimpleEnumerator **aFiles);
|
||||
NS_IMETHODIMP Show(PRInt16 *aReturn);
|
||||
|
||||
// nsBaseFilePicker
|
||||
virtual void InitNative(nsIWidget *aParent, const nsAString& aTitle, PRInt16 aMode);
|
||||
|
||||
static void Shutdown();
|
||||
@ -46,11 +48,19 @@ protected:
|
||||
|
||||
void ReadValuesFromFileChooser(GtkWidget *file_chooser);
|
||||
|
||||
static void OnResponse(GtkWidget* dialog, gint response_id,
|
||||
gpointer user_data);
|
||||
static void OnDestroy(GtkWidget* dialog, gpointer user_data);
|
||||
void Done(GtkWidget* dialog, gint response_id);
|
||||
|
||||
nsCOMPtr<nsIWidget> mParentWidget;
|
||||
nsCOMPtr<nsIFilePickerShownCallback> mCallback;
|
||||
nsCOMArray<nsIFile> mFiles;
|
||||
|
||||
PRInt16 mMode;
|
||||
PRInt16 mSelectedType;
|
||||
PRInt16 mResult;
|
||||
bool mRunning;
|
||||
bool mAllowURLs;
|
||||
nsCString mFileURL;
|
||||
nsString mTitle;
|
||||
|
Loading…
Reference in New Issue
Block a user