GetParentForModalDialog() was called from the ctor initialized list before m_windowStyle could be initialized by the base class ctor in several different places, meaning that the check for wxDIALOG_NO_PARENT in this function was using uninitialized variable. Fix this by passing the style parameter explicitly to this function to allow using it from derived class ctors. Still keep an overload which uses the actual window parent and flags which is simpler to use for later calls to this function. Thanks valgrind for finding this one. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64019 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
303 lines
8.8 KiB
C++
303 lines
8.8 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/gtk/msgdlg.cpp
|
|
// Purpose: wxMessageDialog for GTK+2
|
|
// Author: Vaclav Slavik
|
|
// Modified by:
|
|
// Created: 2003/02/28
|
|
// RCS-ID: $Id$
|
|
// Copyright: (c) Vaclav Slavik, 2003
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#if wxUSE_MSGDLG && !defined(__WXGPE__)
|
|
|
|
#include "wx/msgdlg.h"
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/intl.h"
|
|
#endif
|
|
|
|
#include "wx/gtk/private.h"
|
|
#include "wx/gtk/private/messagetype.h"
|
|
#include "wx/gtk/private/mnemonics.h"
|
|
#include <gtk/gtk.h>
|
|
|
|
#if wxUSE_LIBHILDON
|
|
#include <hildon-widgets/hildon-note.h>
|
|
#endif // wxUSE_LIBHILDON
|
|
|
|
#if wxUSE_LIBHILDON2
|
|
#include <hildon/hildon.h>
|
|
#endif // wxUSE_LIBHILDON2
|
|
|
|
IMPLEMENT_CLASS(wxMessageDialog, wxDialog)
|
|
|
|
wxMessageDialog::wxMessageDialog(wxWindow *parent,
|
|
const wxString& message,
|
|
const wxString& caption,
|
|
long style,
|
|
const wxPoint& WXUNUSED(pos))
|
|
: wxMessageDialogWithCustomLabels
|
|
(
|
|
GetParentForModalDialog(parent, style),
|
|
message,
|
|
caption,
|
|
style
|
|
)
|
|
{
|
|
}
|
|
|
|
wxString wxMessageDialog::GetDefaultYesLabel() const
|
|
{
|
|
return GTK_STOCK_YES;
|
|
}
|
|
|
|
wxString wxMessageDialog::GetDefaultNoLabel() const
|
|
{
|
|
return GTK_STOCK_NO;
|
|
}
|
|
|
|
wxString wxMessageDialog::GetDefaultOKLabel() const
|
|
{
|
|
return GTK_STOCK_OK;
|
|
}
|
|
|
|
wxString wxMessageDialog::GetDefaultCancelLabel() const
|
|
{
|
|
return GTK_STOCK_CANCEL;
|
|
}
|
|
|
|
void wxMessageDialog::DoSetCustomLabel(wxString& var, const ButtonLabel& label)
|
|
{
|
|
int stockId = label.GetStockId();
|
|
if ( stockId == wxID_NONE )
|
|
{
|
|
wxMessageDialogWithCustomLabels::DoSetCustomLabel(var, label);
|
|
var = wxConvertMnemonicsToGTK(var);
|
|
}
|
|
else // stock label
|
|
{
|
|
var = wxGetStockGtkID(stockId);
|
|
}
|
|
}
|
|
|
|
void wxMessageDialog::GTKCreateMsgDialog()
|
|
{
|
|
GtkWindow * const parent = m_parent ? GTK_WINDOW(m_parent->m_widget) : NULL;
|
|
|
|
#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
|
|
const char *stockIcon = "";
|
|
|
|
switch ( GetEffectiveIcon() )
|
|
{
|
|
case wxICON_ERROR:
|
|
stockIcon = "qgn_note_gene_syserror";
|
|
break;
|
|
|
|
case wxICON_WARNING:
|
|
stockIcon = "qgn_note_gene_syswarning";
|
|
break;
|
|
|
|
case wxICON_QUESTION:
|
|
stockIcon = "qgn_note_confirm";
|
|
break;
|
|
|
|
case wxICON_INFORMATION:
|
|
stockIcon = "qgn_note_info";
|
|
break;
|
|
}
|
|
|
|
// there is no generic note creation function in public API so we have no
|
|
// choice but to use g_object_new() directly
|
|
m_widget = (GtkWidget *)g_object_new
|
|
(
|
|
HILDON_TYPE_NOTE,
|
|
#if wxUSE_LIBHILDON
|
|
"note_type", HILDON_NOTE_CONFIRMATION_BUTTON_TYPE,
|
|
#else // wxUSE_LIBHILDON
|
|
"note_type", HILDON_NOTE_TYPE_CONFIRMATION_BUTTON,
|
|
#endif // wxUSE_LIBHILDON /wxUSE_LIBHILDON2
|
|
"description", (const char *)GetFullMessage().utf8_str(),
|
|
"icon", stockIcon,
|
|
NULL
|
|
);
|
|
#else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
|
|
GtkMessageType type = GTK_MESSAGE_ERROR;
|
|
GtkButtonsType buttons = GTK_BUTTONS_NONE;
|
|
|
|
// when using custom labels, we have to add all the buttons ourselves
|
|
if ( !HasCustomLabels() )
|
|
{
|
|
if ( m_dialogStyle & wxYES_NO )
|
|
{
|
|
if ( !(m_dialogStyle & wxCANCEL) )
|
|
buttons = GTK_BUTTONS_YES_NO;
|
|
//else: no standard GTK_BUTTONS_YES_NO_CANCEL so leave as NONE
|
|
}
|
|
else if ( m_dialogStyle & wxOK )
|
|
{
|
|
buttons = m_dialogStyle & wxCANCEL ? GTK_BUTTONS_OK_CANCEL
|
|
: GTK_BUTTONS_OK;
|
|
}
|
|
}
|
|
|
|
if ( !wxGTKImpl::ConvertMessageTypeFromWX(GetEffectiveIcon(), &type) )
|
|
{
|
|
// if no style is explicitly specified, detect the suitable icon
|
|
// ourselves (this can be disabled by using wxICON_NONE)
|
|
type = m_dialogStyle & wxYES ? GTK_MESSAGE_QUESTION : GTK_MESSAGE_INFO;
|
|
}
|
|
|
|
wxString message;
|
|
#if GTK_CHECK_VERSION(2, 6, 0)
|
|
bool needsExtMessage = false;
|
|
if ( gtk_check_version(2, 6, 0) == NULL && !m_extendedMessage.empty() )
|
|
{
|
|
message = m_message;
|
|
needsExtMessage = true;
|
|
}
|
|
else // extended message not needed or not supported
|
|
#endif // GTK+ 2.6+
|
|
{
|
|
message = GetFullMessage();
|
|
}
|
|
|
|
m_widget = gtk_message_dialog_new(parent,
|
|
GTK_DIALOG_MODAL,
|
|
type,
|
|
buttons,
|
|
"%s",
|
|
(const char*)wxGTK_CONV(message));
|
|
|
|
#if GTK_CHECK_VERSION(2, 6, 0)
|
|
if ( needsExtMessage )
|
|
{
|
|
gtk_message_dialog_format_secondary_text
|
|
(
|
|
(GtkMessageDialog *)m_widget,
|
|
"%s",
|
|
(const char *)wxGTK_CONV(m_extendedMessage)
|
|
);
|
|
}
|
|
#endif // GTK+ 2.6+
|
|
#endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2/!wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
|
|
|
|
g_object_ref(m_widget);
|
|
|
|
if (m_caption != wxMessageBoxCaptionStr)
|
|
gtk_window_set_title(GTK_WINDOW(m_widget), wxGTK_CONV(m_caption));
|
|
|
|
GtkDialog * const dlg = GTK_DIALOG(m_widget);
|
|
|
|
if ( m_dialogStyle & wxSTAY_ON_TOP )
|
|
{
|
|
gtk_window_set_keep_above(GTK_WINDOW(m_widget), TRUE);
|
|
}
|
|
|
|
// we need to add buttons manually if we use custom labels or always for
|
|
// Yes/No/Cancel dialog as GTK+ doesn't support it natively and when using
|
|
// Hildon we add all the buttons manually as it doesn't support too many of
|
|
// the combinations we may have
|
|
#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
|
|
static const bool addButtons = true;
|
|
#else // !wxUSE_LIBHILDON
|
|
const bool addButtons = buttons == GTK_BUTTONS_NONE;
|
|
#endif // wxUSE_LIBHILDON/!wxUSE_LIBHILDON
|
|
|
|
if ( m_dialogStyle & wxYES_NO ) // Yes/No or Yes/No/Cancel dialog
|
|
{
|
|
if ( addButtons )
|
|
{
|
|
gtk_dialog_add_button(dlg, wxGTK_CONV(GetNoLabel()),
|
|
GTK_RESPONSE_NO);
|
|
gtk_dialog_add_button(dlg, wxGTK_CONV(GetYesLabel()),
|
|
GTK_RESPONSE_YES);
|
|
|
|
if ( m_dialogStyle & wxCANCEL )
|
|
{
|
|
gtk_dialog_add_button(dlg, wxGTK_CONV(GetCancelLabel()),
|
|
GTK_RESPONSE_CANCEL);
|
|
}
|
|
}
|
|
|
|
// it'd probably be harmless to call gtk_dialog_set_default_response()
|
|
// twice but why do it if we're going to change the default below
|
|
// anyhow
|
|
if ( !(m_dialogStyle & wxCANCEL_DEFAULT) )
|
|
{
|
|
gtk_dialog_set_default_response(dlg,
|
|
m_dialogStyle & wxNO_DEFAULT
|
|
? GTK_RESPONSE_NO
|
|
: GTK_RESPONSE_YES);
|
|
}
|
|
}
|
|
else if ( addButtons ) // Ok or Ok/Cancel dialog
|
|
{
|
|
gtk_dialog_add_button(dlg, wxGTK_CONV(GetOKLabel()), GTK_RESPONSE_OK);
|
|
if ( m_dialogStyle & wxCANCEL )
|
|
{
|
|
gtk_dialog_add_button(dlg, wxGTK_CONV(GetCancelLabel()),
|
|
GTK_RESPONSE_CANCEL);
|
|
}
|
|
}
|
|
|
|
if ( m_dialogStyle & wxCANCEL_DEFAULT )
|
|
{
|
|
gtk_dialog_set_default_response(dlg, GTK_RESPONSE_CANCEL);
|
|
}
|
|
}
|
|
|
|
int wxMessageDialog::ShowModal()
|
|
{
|
|
// break the mouse capture as it would interfere with modal dialog (see
|
|
// wxDialog::ShowModal)
|
|
wxWindow * const win = wxWindow::GetCapture();
|
|
if ( win )
|
|
win->GTKReleaseMouseAndNotify();
|
|
|
|
if ( !m_widget )
|
|
{
|
|
GTKCreateMsgDialog();
|
|
wxCHECK_MSG( m_widget, wxID_CANCEL,
|
|
wxT("failed to create GtkMessageDialog") );
|
|
}
|
|
|
|
// This should be necessary, but otherwise the
|
|
// parent TLW will disappear..
|
|
if (m_parent)
|
|
gtk_window_present( GTK_WINDOW(m_parent->m_widget) );
|
|
|
|
gint result = gtk_dialog_run(GTK_DIALOG(m_widget));
|
|
gtk_widget_destroy(m_widget);
|
|
g_object_unref(m_widget);
|
|
m_widget = NULL;
|
|
|
|
switch (result)
|
|
{
|
|
default:
|
|
wxFAIL_MSG(wxT("unexpected GtkMessageDialog return code"));
|
|
// fall through
|
|
|
|
case GTK_RESPONSE_CANCEL:
|
|
case GTK_RESPONSE_DELETE_EVENT:
|
|
case GTK_RESPONSE_CLOSE:
|
|
return wxID_CANCEL;
|
|
case GTK_RESPONSE_OK:
|
|
return wxID_OK;
|
|
case GTK_RESPONSE_YES:
|
|
return wxID_YES;
|
|
case GTK_RESPONSE_NO:
|
|
return wxID_NO;
|
|
}
|
|
}
|
|
|
|
|
|
#endif // wxUSE_MSGDLG && !defined(__WXGPE__)
|