diff options
author | Caolán McNamara <caolanm@redhat.com> | 2013-04-30 20:44:06 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2013-05-01 14:42:05 +0100 |
commit | 9e5c35454d07f880a2cb52d9a808633b908bb859 (patch) | |
tree | b436edac62601268ffa16841720faf857c859c9e /vcl | |
parent | 26bda9f4a82c9b1956a10e3dc52a99bc2f850ada (diff) |
create a HIG compliant MessageDialog and map to GtkMessageDialog
Change-Id: If86387619ff00a652ea418292fbb0026b867a431
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/source/window/builder.cxx | 105 | ||||
-rw-r--r-- | vcl/source/window/dialog.cxx | 3 | ||||
-rw-r--r-- | vcl/source/window/layout.cxx | 176 |
3 files changed, 275 insertions, 9 deletions
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx index a879eb3c887d..2f3b364a89a1 100644 --- a/vcl/source/window/builder.cxx +++ b/vcl/source/window/builder.cxx @@ -144,6 +144,7 @@ VclBuilder::VclBuilder(Window *pParent, OUString sUIDir, OUString sUIFile, OStri , m_pParserState(new ParserState) { m_bToplevelHasDeferredInit = (pParent && pParent->IsDialog()) ? ((Dialog*)pParent)->isDeferredInit() : false; + m_bToplevelHasDeferredProperties = m_bToplevelHasDeferredInit; sal_Int32 nIdx = m_sHelpRoot.lastIndexOf('.'); if (nIdx != -1) @@ -944,6 +945,13 @@ Window *VclBuilder::makeObject(Window *pParent, const OString &name, const OStri nBits |= WB_SIZEABLE; pWindow = new Dialog(pParent, nBits); } + else if (name == "GtkMessageDialog") + { + WinBits nBits = WB_MOVEABLE|WB_3DLOOK|WB_CLOSEABLE; + if (extractResizable(rMap)) + nBits |= WB_SIZEABLE; + pWindow = new MessageDialog(pParent, nBits); + } else if (name == "GtkBox") { bVertical = extractOrientation(rMap); @@ -1256,6 +1264,27 @@ namespace } } +//Any properties from .ui load we couldn't set because of potential virtual methods +//during ctor are applied here +void VclBuilder::setDeferredProperties() +{ + if (!m_bToplevelHasDeferredProperties) + return; + set_properties(m_pParent, m_aDeferredProperties); + m_aDeferredProperties.clear(); + m_bToplevelHasDeferredProperties = false; +} + +void VclBuilder::set_properties(Window *pWindow, const stringmap &rProps) +{ + for (stringmap::const_iterator aI = rProps.begin(), aEnd = rProps.end(); aI != aEnd; ++aI) + { + const OString &rKey = aI->first; + const OString &rValue = aI->second; + pWindow->set_property(rKey, rValue); + } +} + Window *VclBuilder::insertObject(Window *pParent, const OString &rClass, const OString &rID, stringmap &rProps, stringmap &rPango, stringmap &rAtk, @@ -1294,12 +1323,10 @@ Window *VclBuilder::insertObject(Window *pParent, const OString &rClass, if (pCurrentChild) { - for (stringmap::iterator aI = rProps.begin(), aEnd = rProps.end(); aI != aEnd; ++aI) - { - const OString &rKey = aI->first; - const OString &rValue = aI->second; - pCurrentChild->set_property(rKey, rValue); - } + if (pCurrentChild == m_pParent && m_bToplevelHasDeferredProperties) + m_aDeferredProperties = rProps; + else + set_properties(pCurrentChild, rProps); for (stringmap::iterator aI = rPango.begin(), aEnd = rPango.end(); aI != aEnd; ++aI) { @@ -1529,15 +1556,19 @@ void VclBuilder::handleChild(Window *pParent, xmlreader::XmlReader &reader) if (VclFrame *pFrameParent = dynamic_cast<VclFrame*>(pParent)) pFrameParent->designate_label(pCurrentChild); } - if (sInternalChild.equals("vbox")) + if (sInternalChild.equals("vbox") || sInternalChild.equals("messagedialog-vbox")) { if (Dialog *pBoxParent = dynamic_cast<Dialog*>(pParent)) pBoxParent->set_content_area(static_cast<VclBox*>(pCurrentChild)); } - else if (sInternalChild.equals("action_area")) + else if (sInternalChild.equals("action_area") || sInternalChild.equals("messagedialog-action_area")) { - if (Dialog *pBoxParent = dynamic_cast<Dialog*>(pParent)) + Window *pContentArea = pCurrentChild->GetParent(); + assert(pContentArea && pContentArea->GetType() == WINDOW_CONTAINER); + if (Dialog *pBoxParent = dynamic_cast<Dialog*>(pContentArea ? pContentArea->GetParent() : NULL)) + { pBoxParent->set_action_area(static_cast<VclButtonBox*>(pCurrentChild)); + } } //To-Do make reorder a virtual in Window, move this foo @@ -2222,6 +2253,8 @@ Window* VclBuilder::handleObject(Window *pParent, xmlreader::XmlReader &reader) collectPangoAttribute(reader, aPangoAttributes); else if (name.equals("relation")) collectAtkAttribute(reader, aAtkAttributes); + else if (name.equals("action-widget")) + handleActionWidget(reader); } } @@ -2424,6 +2457,28 @@ void VclBuilder::collectProperty(xmlreader::XmlReader &reader, const OString &rI } } +void VclBuilder::handleActionWidget(xmlreader::XmlReader &reader) +{ + xmlreader::Span name; + int nsId; + + OString sResponse; + + while (reader.nextAttribute(&nsId, &name)) + { + if (name.equals("response")) + { + name = reader.getAttributeValue(false); + sResponse = OString(name.begin, name.length); + } + } + + reader.nextItem(xmlreader::XmlReader::TEXT_RAW, &name, &nsId); + OString sID = OString(name.begin, name.length); + set_response(sID, sResponse.toInt32()); +} + + void VclBuilder::collectAccelerator(xmlreader::XmlReader &reader, stringmap &rMap) { xmlreader::Span name; @@ -2482,6 +2537,38 @@ PopupMenu *VclBuilder::get_menu(OString sID) return NULL; } +short VclBuilder::get_response(const Window *pWindow) const +{ + for (std::vector<WinAndId>::const_iterator aI = m_aChildren.begin(), + aEnd = m_aChildren.end(); aI != aEnd; ++aI) + { + if (aI->m_pWindow == pWindow) + { + return aI->m_nResponseId; + } + } + + //how did we not find sID ? + assert(false); + return RET_CANCEL; +} + +void VclBuilder::set_response(OString sID, short nResponse) +{ + for (std::vector<WinAndId>::iterator aI = m_aChildren.begin(), + aEnd = m_aChildren.end(); aI != aEnd; ++aI) + { + if (aI->m_sID.equals(sID)) + { + aI->m_nResponseId = nResponse; + return; + } + } + + //how did we not find sID ? + assert(false); +} + void VclBuilder::delete_by_name(OString sID) { for (std::vector<WinAndId>::iterator aI = m_aChildren.begin(), diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx index c37588a74fde..4ea01eb635e5 100644 --- a/vcl/source/window/dialog.cxx +++ b/vcl/source/window/dialog.cxx @@ -711,6 +711,7 @@ void Dialog::StateChanged( StateChangedType nType ) if (isLayoutEnabled()) { mbIsCalculatingInitialLayoutSize = true; + setDeferredProperties(); setOptimalLayoutSize(); mbIsCalculatingInitialLayoutSize = false; } @@ -900,6 +901,8 @@ void Dialog::ImplEndExecuteModal() short Dialog::Execute() { + setDeferredProperties(); + if ( !ImplStartExecuteModal() ) return 0; diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx index 27bb34dec24d..84351e2709da 100644 --- a/vcl/source/window/layout.cxx +++ b/vcl/source/window/layout.cxx @@ -10,6 +10,7 @@ #include <com/sun/star/accessibility/AccessibleRole.hpp> #include <vcl/dialog.hxx> #include <vcl/layout.hxx> +#include <vcl/msgbox.hxx> #include "window.h" VclContainer::VclContainer(Window *pParent, WinBits nStyle) @@ -1565,6 +1566,181 @@ bool VclSizeGroup::set_property(const OString &rKey, const OString &rValue) return true; } +MessageDialog::MessageDialog(Window* pParent, WinBits nStyle) + : Dialog(pParent, nStyle) + , m_pGrid(NULL) + , m_pImage(NULL) + , m_pPrimaryMessage(NULL) + , m_pSecondaryMessage(NULL) +{ + SetType(WINDOW_MESSBOX); +} + +MessageDialog::MessageDialog(Window* pParent, const OString& rID, const OUString& rUIXMLDescription) + : Dialog(pParent, rID, rUIXMLDescription, WINDOW_MESSBOX) + , m_pGrid(NULL) + , m_pImage(NULL) + , m_pPrimaryMessage(NULL) + , m_pSecondaryMessage(NULL) +{ +} + +MessageDialog::~MessageDialog() +{ + delete m_pSecondaryMessage; + delete m_pPrimaryMessage; + delete m_pImage; + delete m_pGrid; +} + +IMPL_LINK(MessageDialog, ButtonHdl, Button *, pButton) +{ + //for now insist that we have a builder, we can relax that in + //the future if we need it + assert(m_pUIBuilder); + EndDialog(m_pUIBuilder->get_response(pButton)); + return 0; +} + +void MessageDialog::setButtonHandlers() +{ + SAL_WARN_IF(!m_pUIBuilder, "vcl.layout", "MessageDialog non-ui load button responses not implemented yet"); + if (!m_pUIBuilder) + return; + VclButtonBox *pButtonBox = get_action_area(); + assert(pButtonBox); + for (Window* pChild = pButtonBox->GetWindow(WINDOW_FIRSTCHILD); pChild; + pChild = pChild->GetWindow(WINDOW_NEXT)) + { + switch (pChild->GetType()) + { + case WINDOW_PUSHBUTTON: + { + PushButton* pButton = (PushButton*)pChild; + pButton->SetClickHdl(LINK(this, MessageDialog, ButtonHdl)); + break; + } + //for now at least, insist that the response ids match + //the default actions for those widgets, and leave + //their default handlers in place + case WINDOW_OKBUTTON: + assert(m_pUIBuilder->get_response(pChild) == RET_OK); + break; + case WINDOW_CANCELBUTTON: + assert(m_pUIBuilder->get_response(pChild) == RET_CANCEL); + break; + case WINDOW_HELPBUTTON: + assert(m_pUIBuilder->get_response(pChild) == RET_HELP); + break; + default: + SAL_WARN("vcl.layout", "The type of widget " << + pChild->GetHelpId() << " is currently not handled"); + break; + } + //The default is to stick the focus into the first widget + //that accepts it, and if that happens and its a button + //then that becomes the new default button, so explicitly + //put the focus into the default button + if (pChild->GetStyle() & WB_DEFBUTTON) + pChild->GrabFocus(); + } +} + +short MessageDialog::Execute() +{ + setDeferredProperties(); + + if (!m_pGrid) + { + VclContainer *pContainer = get_content_area(); + assert(pContainer); + + m_pGrid = new VclGrid(pContainer); + m_pGrid->set_column_spacing(12); + + m_pImage = new FixedImage(m_pGrid, WB_CENTER | WB_VCENTER | WB_3DLOOK); + m_pImage->SetImage(WarningBox::GetStandardImage()); + m_pImage->set_grid_left_attach(0); + m_pImage->set_grid_top_attach(0); + m_pImage->set_valign(VCL_ALIGN_START); + m_pImage->Show(); + + WinBits nWinStyle = WB_LEFT | WB_VCENTER | WB_WORDBREAK | WB_NOLABEL | WB_NOTABSTOP; + + m_pPrimaryMessage = new VclMultiLineEdit(m_pGrid, nWinStyle); + m_pPrimaryMessage->SetPaintTransparent(true); + m_pPrimaryMessage->EnableCursor(false); + Font aFont = GetSettings().GetStyleSettings().GetLabelFont(); + aFont.SetSize( Size( 0, aFont.GetSize().Height() * 1.2 ) ); + aFont.SetWeight(WEIGHT_BOLD); + m_pPrimaryMessage->SetControlFont(aFont); + m_pPrimaryMessage->set_grid_left_attach(1); + m_pPrimaryMessage->set_grid_top_attach(0); + m_pPrimaryMessage->set_hexpand(true); + m_pPrimaryMessage->SetText(m_sPrimaryString); + m_pPrimaryMessage->Show(!m_sPrimaryString.isEmpty()); + + m_pSecondaryMessage = new VclMultiLineEdit(m_pGrid, nWinStyle); + m_pSecondaryMessage->SetPaintTransparent(true); + m_pSecondaryMessage->EnableCursor(false); + m_pSecondaryMessage->set_grid_left_attach(1); + m_pSecondaryMessage->set_grid_top_attach(1); + m_pSecondaryMessage->set_hexpand(true); + m_pSecondaryMessage->SetText(m_sSecondaryString); + m_pSecondaryMessage->Show(!m_sSecondaryString.isEmpty()); + + m_pGrid->Show(); + + setButtonHandlers(); + } + return Dialog::Execute(); +} + +OUString MessageDialog::get_primary_text() const +{ + const_cast<MessageDialog*>(this)->setDeferredProperties(); + + return m_sPrimaryString; +} + +OUString MessageDialog::get_secondary_text() const +{ + const_cast<MessageDialog*>(this)->setDeferredProperties(); + + return m_sSecondaryString; +} + +bool MessageDialog::set_property(const OString &rKey, const OString &rValue) +{ + if (rKey == "text") + set_primary_text(OStringToOUString(rValue, RTL_TEXTENCODING_UTF8)); + else if (rKey == "secondary-text") + set_secondary_text(OStringToOUString(rValue, RTL_TEXTENCODING_UTF8)); + else + return Dialog::set_property(rKey, rValue); + return true; +} + +void MessageDialog::set_primary_text(const OUString &rPrimaryString) +{ + m_sPrimaryString = rPrimaryString; + if (m_pPrimaryMessage) + { + m_pPrimaryMessage->SetText(m_sPrimaryString); + m_pPrimaryMessage->Show(!m_sPrimaryString.isEmpty()); + } +} + +void MessageDialog::set_secondary_text(const OUString &rSecondaryString) +{ + m_sSecondaryString = rSecondaryString; + if (m_pSecondaryMessage) + { + m_pSecondaryMessage->SetText(OUString("\n") + m_sSecondaryString); + m_pSecondaryMessage->Show(!m_sSecondaryString.isEmpty()); + } +} + Size getLegacyBestSizeForChildren(const Window &rWindow) { Rectangle aBounds; |