예제 #1
0
bool wxFileDialog::Create(wxWindow *parent, const wxString& message,
                           const wxString& defaultDir,
                           const wxString& defaultFileName,
                           const wxString& wildCard,
                           long style, const wxPoint& pos,
                           const wxSize& sz,
                           const wxString& name)
{
    parent = GetParentForModalDialog(parent, style);

    if (!wxFileDialogBase::Create(parent, message, defaultDir, defaultFileName,
                                  wildCard, style, pos, sz, name))
    {
        return false;
    }

    if (!PreCreation(parent, pos, wxDefaultSize) ||
        !CreateBase(parent, wxID_ANY, pos, wxDefaultSize, style,
                wxDefaultValidator, wxT("filedialog")))
    {
        wxFAIL_MSG( wxT("wxFileDialog creation failed") );
        return false;
    }

    GtkFileChooserAction gtk_action;
    GtkWindow* gtk_parent = NULL;
    if (parent)
        gtk_parent = GTK_WINDOW( gtk_widget_get_toplevel(parent->m_widget) );

    const gchar* ok_btn_stock;
    if ( style & wxFD_SAVE )
    {
        gtk_action = GTK_FILE_CHOOSER_ACTION_SAVE;
        ok_btn_stock = GTK_STOCK_SAVE;
    }
    else
    {
        gtk_action = GTK_FILE_CHOOSER_ACTION_OPEN;
        ok_btn_stock = GTK_STOCK_OPEN;
    }

    m_widget = gtk_file_chooser_dialog_new(
                   wxGTK_CONV(m_message),
                   gtk_parent,
                   gtk_action,
                   GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                   ok_btn_stock, GTK_RESPONSE_ACCEPT,
                   NULL);
    g_object_ref(m_widget);
    GtkFileChooser* file_chooser = GTK_FILE_CHOOSER(m_widget);

    m_fc.SetWidget(file_chooser);

    gtk_dialog_set_default_response(GTK_DIALOG(m_widget), GTK_RESPONSE_ACCEPT);

    if ( style & wxFD_MULTIPLE )
        gtk_file_chooser_set_select_multiple(file_chooser, true);

    // gtk_widget_hide_on_delete is used here to avoid that Gtk automatically
    // destroys the dialog when the user press ESC on the dialog: in that case
    // a second call to ShowModal() would result in a bunch of Gtk-CRITICAL
    // errors...
    g_signal_connect(m_widget,
                    "delete_event",
                    G_CALLBACK (gtk_widget_hide_on_delete),
                    this);

    // local-only property could be set to false to allow non-local files to be
    // loaded. In that case get/set_uri(s) should be used instead of
    // get/set_filename(s) everywhere and the GtkFileChooserDialog should
    // probably also be created with a backend, e.g. "gnome-vfs", "default", ...
    // (gtk_file_chooser_dialog_new_with_backend). Currently local-only is kept
    // as the default - true:
    // gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(m_widget), true);

    g_signal_connect (m_widget, "response",
        G_CALLBACK (gtk_filedialog_response_callback), this);

    g_signal_connect (m_widget, "selection-changed",
        G_CALLBACK (gtk_filedialog_selchanged_callback), this);

    // deal with extensions/filters
    SetWildcard(wildCard);

    wxString defaultFileNameWithExt = defaultFileName;
    if ( !wildCard.empty() && !defaultFileName.empty() &&
            !wxFileName(defaultFileName).HasExt() )
    {
        // append the default extension, if any, to the initial file name: GTK
        // won't do it for us by default (unlike e.g. MSW)
        const wxFileName fnWC(m_fc.GetCurrentWildCard());
        if ( fnWC.HasExt() )
        {
            // Notice that we shouldn't append the extension if it's a wildcard
            // because this is not useful: the user would need to change it to use
            // some fixed extension anyhow.
            const wxString& ext = fnWC.GetExt();
            if ( ext.find_first_of("?*") == wxString::npos )
                defaultFileNameWithExt << "." << ext;
        }
    }


    // if defaultDir is specified it should contain the directory and
    // defaultFileName should contain the default name of the file, however if
    // directory is not given, defaultFileName contains both
    wxFileName fn;
    if ( defaultDir.empty() )
        fn.Assign(defaultFileNameWithExt);
    else if ( !defaultFileNameWithExt.empty() )
        fn.Assign(defaultDir, defaultFileNameWithExt);
    else
        fn.AssignDir(defaultDir);

    // set the initial file name and/or directory
    fn.MakeAbsolute(); // GTK+ needs absolute path
    const wxString dir = fn.GetPath();
    if ( !dir.empty() )
    {
        gtk_file_chooser_set_current_folder(file_chooser, wxGTK_CONV_FN(dir));
    }

    const wxString fname = fn.GetFullName();
    if ( style & wxFD_SAVE )
    {
        if ( !fname.empty() )
        {
            gtk_file_chooser_set_current_name(file_chooser, wxGTK_CONV_FN(fname));
        }

#if GTK_CHECK_VERSION(2,7,3)
        if ((style & wxFD_OVERWRITE_PROMPT)
#ifndef __WXGTK3__
            && gtk_check_version(2,7,3) == NULL
#endif
            )
        {
            gtk_file_chooser_set_do_overwrite_confirmation(file_chooser, true);
        }
#endif
    }
    else // wxFD_OPEN
    {
        if ( !fname.empty() )
        {
            gtk_file_chooser_set_filename(file_chooser,
                                          wxGTK_CONV_FN(fn.GetFullPath()));
        }
    }

    if ( style & wxFD_PREVIEW )
    {
        GtkWidget *previewImage = gtk_image_new();

        gtk_file_chooser_set_preview_widget(file_chooser, previewImage);
        g_signal_connect(m_widget, "update-preview",
                         G_CALLBACK(gtk_filedialog_update_preview_callback),
                         previewImage);
    }

    return true;
}