diff options
Diffstat (limited to 'basctl/source/basicide/IDEComboBox.cxx')
-rw-r--r-- | basctl/source/basicide/IDEComboBox.cxx | 529 |
1 files changed, 529 insertions, 0 deletions
diff --git a/basctl/source/basicide/IDEComboBox.cxx b/basctl/source/basicide/IDEComboBox.cxx new file mode 100644 index 000000000..423e5c5d1 --- /dev/null +++ b/basctl/source/basicide/IDEComboBox.cxx @@ -0,0 +1,529 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <strings.hrc> +#include <basidesh.hxx> +#include <basobj.hxx> +#include <IDEComboBox.hxx> +#include <iderdll.hxx> +#include <iderid.hxx> +#include <localizationmgr.hxx> +#include <managelang.hxx> + +#include <sfx2/dispatch.hxx> +#include <sfx2/frame.hxx> +#include <sfx2/sfxsids.hrc> +#include <svtools/langtab.hxx> +#include <tools/debug.hxx> +#include <vcl/svapp.hxx> +#include <vcl/toolbox.hxx> +#include <vcl/event.hxx> + +namespace basctl +{ +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; + +/*! Macro for implementation two methods for LibBoxControl Class + * + * @code + * SfxToolBoxControl* LibBoxControl::CreateImpl(sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox& rTbx) + * { + * return new LibBoxControl(nSlotId, nId, rTbx); + * } + * + * void LibBoxControl::RegisterControl(sal_uInt16 nSlotId, SfxModule* pMod) + * { + * SfxToolBoxControl::RegisterToolBoxControl( + * pMod, SfxTbxCtrlFactory(* LibBoxControl::CreateImpl, typeid(nItemClass), nSlotId)); + * } + * @endcode + * @see Macro SFX_DECL_TOOLBOX_CONTROL + */ +SFX_IMPL_TOOLBOX_CONTROL(LibBoxControl, SfxStringItem); + +LibBoxControl::LibBoxControl(sal_uInt16 nSlotId, ToolBoxItemId nId, ToolBox& rTbx) + : SfxToolBoxControl(nSlotId, nId, rTbx) +{ +} + +void LibBoxControl::StateChangedAtToolBoxControl(sal_uInt16, SfxItemState eState, + const SfxPoolItem* pState) +{ + LibBox* pBox = static_cast<LibBox*>(GetToolBox().GetItemWindow(GetId())); + + DBG_ASSERT(pBox, "Box not found"); + if (!pBox) + return; + + if (eState != SfxItemState::DEFAULT) + pBox->set_sensitive(false); + else + { + pBox->set_sensitive(true); + pBox->Update(dynamic_cast<SfxStringItem const*>(pState)); + } +} + +VclPtr<InterimItemWindow> LibBoxControl::CreateItemWindow(vcl::Window* pParent) +{ + return VclPtr<LibBox>::Create(pParent); +} + +DocListenerBox::DocListenerBox(vcl::Window* pParent) + : InterimItemWindow(pParent, "modules/BasicIDE/ui/combobox.ui", "ComboBox") + , m_xWidget(m_xBuilder->weld_combo_box("combobox")) + , maNotifier(*this) +{ + InitControlBase(m_xWidget.get()); + + m_xWidget->connect_changed(LINK(this, DocListenerBox, SelectHdl)); + m_xWidget->connect_key_press(LINK(this, DocListenerBox, KeyInputHdl)); +} + +void DocListenerBox::set_sensitive(bool bSensitive) +{ + Enable(bSensitive); + m_xWidget->set_sensitive(bSensitive); +} + +IMPL_LINK(DocListenerBox, KeyInputHdl, const KeyEvent&, rKEvt, bool) +{ + return HandleKeyInput(rKEvt); +} + +bool DocListenerBox::HandleKeyInput(const KeyEvent& rKEvt) { return ChildKeyInput(rKEvt); } + +IMPL_LINK_NOARG(DocListenerBox, SelectHdl, weld::ComboBox&, void) { Select(); } + +DocListenerBox::~DocListenerBox() { disposeOnce(); } + +void DocListenerBox::dispose() +{ + maNotifier.dispose(); + m_xWidget.reset(); + InterimItemWindow::dispose(); +} + +/// Only calls FillBox(). Parameter is not used. +void DocListenerBox::onDocumentCreated(const ScriptDocument& /*_rDoc*/) { FillBox(); } + +/// Only calls FillBox(). Parameter is not used. +void DocListenerBox::onDocumentOpened(const ScriptDocument& /*_rDoc*/) { FillBox(); } + +/// Only calls FillBox(). Parameter is not used. +void DocListenerBox::onDocumentSaveAsDone(const ScriptDocument& /*_rDoc*/) { FillBox(); } + +/// Only calls FillBox(). Parameter is not used. +void DocListenerBox::onDocumentClosed(const ScriptDocument& /*_rDoc*/) { FillBox(); } + +/// Not interested in. Do nothing. +void DocListenerBox::onDocumentSave(const ScriptDocument& /*_rDoc*/) {} + +/// Not interested in. Do nothing. +void DocListenerBox::onDocumentSaveDone(const ScriptDocument& /*_rDoc*/) {} + +/// Not interested in. Do nothing. +void DocListenerBox::onDocumentSaveAs(const ScriptDocument& /*_rDoc*/) {} + +/// Not interested in. Do nothing. +void DocListenerBox::onDocumentTitleChanged(const ScriptDocument& /*_rDoc*/) {} + +/// Not interested in. Do nothing. +void DocListenerBox::onDocumentModeChanged(const ScriptDocument& /*_rDoc*/) {} + +LibBox::LibBox(vcl::Window* pParent) + : DocListenerBox(pParent) +{ + FillBox(); + mbIgnoreSelect = true; // do not yet transfer select of 0 + mbFillBox = true; + m_xWidget->set_active(0); + maCurrentText = m_xWidget->get_text(0); + mbIgnoreSelect = false; + + m_xWidget->connect_focus_in(LINK(this, LibBox, FocusInHdl)); + m_xWidget->connect_focus_out(LINK(this, LibBox, FocusOutHdl)); + + SetSizePixel(m_xWidget->get_preferred_size()); +} + +LibBox::~LibBox() { disposeOnce(); } + +void LibBox::dispose() +{ + ClearBox(); + DocListenerBox::dispose(); +} + +void LibBox::Update(const SfxStringItem* pItem) +{ + // if ( !pItem || !pItem->GetValue().Len() ) + FillBox(); + + if (pItem) + { + maCurrentText = pItem->GetValue(); + if (maCurrentText.isEmpty()) + maCurrentText = IDEResId(RID_STR_ALL); + } + + if (m_xWidget->get_active_text() != maCurrentText) + m_xWidget->set_active_text(maCurrentText); +} + +void LibBox::ReleaseFocus() +{ + SfxViewShell* pCurSh = SfxViewShell::Current(); + DBG_ASSERT(pCurSh, "Current ViewShell not found!"); + + if (!pCurSh) + return; + + vcl::Window* pShellWin = pCurSh->GetWindow(); + if (pShellWin) + { + pShellWin->GrabFocus(); + return; + } + + weld::Window* pWin = Application::GetDefDialogParent(); + if (!pWin) + return; + pWin->grab_focus(); +} + +void LibBox::FillBox() +{ + m_xWidget->freeze(); + mbIgnoreSelect = true; + + maCurrentText = m_xWidget->get_active_text(); + + ClearBox(); + + // create list box entries + LibEntry* pEntry = new LibEntry(ScriptDocument::getApplicationScriptDocument(), + LIBRARY_LOCATION_UNKNOWN, OUString()); + OUString sId(weld::toId(pEntry)); + m_xWidget->append(sId, IDEResId(RID_STR_ALL)); + + InsertEntries(ScriptDocument::getApplicationScriptDocument(), LIBRARY_LOCATION_USER); + InsertEntries(ScriptDocument::getApplicationScriptDocument(), LIBRARY_LOCATION_SHARE); + + ScriptDocuments aDocuments( + ScriptDocument::getAllScriptDocuments(ScriptDocument::DocumentsSorted)); + for (auto const& doc : aDocuments) + { + InsertEntries(doc, LIBRARY_LOCATION_DOCUMENT); + } + + m_xWidget->thaw(); + + int nIndex = m_xWidget->find_text(maCurrentText); + if (nIndex != -1) + m_xWidget->set_active(nIndex); + else + m_xWidget->set_active(0); + maCurrentText = m_xWidget->get_active_text(); + mbIgnoreSelect = false; +} + +void LibBox::InsertEntries(const ScriptDocument& rDocument, LibraryLocation eLocation) +{ + // get a sorted list of library names + Sequence<OUString> aLibNames = rDocument.getLibraryNames(); + sal_Int32 nLibCount = aLibNames.getLength(); + const OUString* pLibNames = aLibNames.getConstArray(); + + for (sal_Int32 i = 0; i < nLibCount; ++i) + { + OUString aLibName = pLibNames[i]; + if (eLocation == rDocument.getLibraryLocation(aLibName)) + { + OUString aName(rDocument.getTitle(eLocation)); + OUString aEntryText(CreateMgrAndLibStr(aName, aLibName)); + LibEntry* pEntry = new LibEntry(rDocument, eLocation, aLibName); + m_xWidget->append(weld::toId(pEntry), aEntryText); + } + } +} + +bool LibBox::HandleKeyInput(const KeyEvent& rKEvt) +{ + bool bDone = false; + + sal_uInt16 nKeyCode = rKEvt.GetKeyCode().GetCode(); + switch (nKeyCode) + { + case KEY_RETURN: + { + NotifyIDE(); + bDone = true; + } + break; + case KEY_ESCAPE: + { + m_xWidget->set_active_text(maCurrentText); + ReleaseFocus(); + bDone = true; + } + break; + } + + return bDone || DocListenerBox::HandleKeyInput(rKEvt); +} + +IMPL_LINK_NOARG(LibBox, FocusInHdl, weld::Widget&, void) +{ + if (mbFillBox) + { + FillBox(); + mbFillBox = false; + } +} + +IMPL_LINK_NOARG(LibBox, FocusOutHdl, weld::Widget&, void) +{ + // comboboxes can be comprised of multiple widgets, ensure all have lost focus + if (m_xWidget && !m_xWidget->has_focus()) + mbFillBox = true; +} + +void LibBox::Select() +{ + if (m_xWidget->changed_by_direct_pick()) + { + if (!mbIgnoreSelect) + NotifyIDE(); + else + m_xWidget->set_active_text(maCurrentText); // (Select after Escape) + } +} + +void LibBox::NotifyIDE() +{ + LibEntry* pEntry = weld::fromId<LibEntry*>(m_xWidget->get_active_id()); + if (pEntry) + { + const ScriptDocument& aDocument(pEntry->GetDocument()); + SfxUnoAnyItem aDocumentItem(SID_BASICIDE_ARG_DOCUMENT_MODEL, + uno::Any(aDocument.getDocumentOrNull())); + const OUString& aLibName = pEntry->GetLibName(); + SfxStringItem aLibNameItem(SID_BASICIDE_ARG_LIBNAME, aLibName); + if (SfxDispatcher* pDispatcher = GetDispatcher()) + pDispatcher->ExecuteList(SID_BASICIDE_LIBSELECTED, SfxCallMode::SYNCHRON, + { &aDocumentItem, &aLibNameItem }); + } + ReleaseFocus(); +} + +void LibBox::ClearBox() +{ + sal_Int32 nCount = m_xWidget->get_count(); + for (sal_Int32 i = 0; i < nCount; ++i) + { + LibEntry* pEntry = weld::fromId<LibEntry*>(m_xWidget->get_id(i)); + delete pEntry; + } + m_xWidget->clear(); +} + +// class LanguageBoxControl ---------------------------------------------- + +/*! Macro for implementation two methods for LanguageBoxControl Class + * + * @code + * SfxToolBoxControl* LanguageBoxControl::CreateImpl(sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox& rTbx) + * { + * return new LanguageBoxControl(nSlotId, nId, rTbx); + * } + * + * void LanguageBoxControl::RegisterControl(sal_uInt16 nSlotId, SfxModule* pMod) + * { + * SfxToolBoxControl::RegisterToolBoxControl( + * pMod, SfxTbxCtrlFactory(* LanguageBoxControl::CreateImpl, typeid(nItemClass), nSlotId)); + * } + * @endcode + * @see Macro SFX_DECL_TOOLBOX_CONTROL + */ +SFX_IMPL_TOOLBOX_CONTROL(LanguageBoxControl, SfxStringItem); + +LanguageBoxControl::LanguageBoxControl(sal_uInt16 nSlotId, ToolBoxItemId nId, ToolBox& rTbx) + : SfxToolBoxControl(nSlotId, nId, rTbx) +{ +} + +void LanguageBoxControl::StateChangedAtToolBoxControl(sal_uInt16, SfxItemState eState, + const SfxPoolItem* pItem) +{ + if (LanguageBox* pBox = static_cast<LanguageBox*>(GetToolBox().GetItemWindow(GetId()))) + { + if (eState != SfxItemState::DEFAULT) + pBox->set_sensitive(false); + else + { + pBox->set_sensitive(true); + pBox->Update(dynamic_cast<SfxStringItem const*>(pItem)); + } + } +} + +VclPtr<InterimItemWindow> LanguageBoxControl::CreateItemWindow(vcl::Window* pParent) +{ + return VclPtr<LanguageBox>::Create(pParent); +} + +// class basctl::LanguageBox ----------------------------------------------- +LanguageBox::LanguageBox(vcl::Window* pParent) + : DocListenerBox(pParent) + , msNotLocalizedStr(IDEResId(RID_STR_TRANSLATION_NOTLOCALIZED)) + , msDefaultLanguageStr(IDEResId(RID_STR_TRANSLATION_DEFAULT)) + , mbIgnoreSelect(false) +{ + FillBox(); + + SetSizePixel(m_xWidget->get_preferred_size()); +} + +LanguageBox::~LanguageBox() { disposeOnce(); } + +void LanguageBox::dispose() +{ + ClearBox(); + DocListenerBox::dispose(); +} + +void LanguageBox::FillBox() +{ + m_xWidget->freeze(); + mbIgnoreSelect = true; + msCurrentText = m_xWidget->get_active_text(); + ClearBox(); + + sal_Int32 nSelPos = -1; + + std::shared_ptr<LocalizationMgr> pCurMgr(GetShell()->GetCurLocalizationMgr()); + if (pCurMgr->isLibraryLocalized()) + { + set_sensitive(true); + Locale aDefaultLocale = pCurMgr->getStringResourceManager()->getDefaultLocale(); + Locale aCurrentLocale = pCurMgr->getStringResourceManager()->getCurrentLocale(); + Sequence<Locale> aLocaleSeq = pCurMgr->getStringResourceManager()->getLocales(); + const Locale* pLocale = aLocaleSeq.getConstArray(); + sal_Int32 i, nCount = aLocaleSeq.getLength(); + for (i = 0; i < nCount; ++i) + { + bool bIsDefault = localesAreEqual(aDefaultLocale, pLocale[i]); + bool bIsCurrent = localesAreEqual(aCurrentLocale, pLocale[i]); + LanguageType eLangType = LanguageTag::convertToLanguageType(pLocale[i]); + OUString sLanguage = SvtLanguageTable::GetLanguageString(eLangType); + if (bIsDefault) + { + sLanguage += " " + msDefaultLanguageStr; + } + LanguageEntry* pEntry = new LanguageEntry(pLocale[i], bIsDefault); + OUString sId(weld::toId(pEntry)); + m_xWidget->append(sId, sLanguage); + + if (bIsCurrent) + nSelPos = i; + } + + if (nSelPos != -1) + msCurrentText = m_xWidget->get_text(nSelPos); + } + else + { + m_xWidget->append_text(msNotLocalizedStr); + nSelPos = 0; + set_sensitive(false); + } + + m_xWidget->thaw(); + m_xWidget->set_active(nSelPos); + mbIgnoreSelect = false; +} + +void LanguageBox::ClearBox() +{ + sal_Int32 nCount = m_xWidget->get_count(); + for (sal_Int32 i = 0; i < nCount; ++i) + { + LanguageEntry* pEntry = weld::fromId<LanguageEntry*>(m_xWidget->get_id(i)); + delete pEntry; + } + m_xWidget->clear(); +} + +void LanguageBox::SetLanguage() +{ + LanguageEntry* pEntry = weld::fromId<LanguageEntry*>(m_xWidget->get_active_id()); + if (pEntry) + GetShell()->GetCurLocalizationMgr()->handleSetCurrentLocale(pEntry->m_aLocale); +} + +void LanguageBox::Select() +{ + if (!mbIgnoreSelect) + SetLanguage(); + else + m_xWidget->set_active_text(msCurrentText); // Select after Escape +} + +bool LanguageBox::HandleKeyInput(const KeyEvent& rKEvt) +{ + bool bDone = false; + + sal_uInt16 nKeyCode = rKEvt.GetKeyCode().GetCode(); + switch (nKeyCode) + { + case KEY_RETURN: + { + SetLanguage(); + bDone = true; + } + break; + case KEY_ESCAPE: + { + m_xWidget->set_active_text(msCurrentText); + bDone = true; + } + break; + } + + return bDone || DocListenerBox::HandleKeyInput(rKEvt); +} + +void LanguageBox::Update(const SfxStringItem* pItem) +{ + FillBox(); + + if (pItem && !pItem->GetValue().isEmpty()) + { + msCurrentText = pItem->GetValue(); + if (m_xWidget->get_active_text() != msCurrentText) + m_xWidget->set_active_text(msCurrentText); + } +} + +} // namespace basctl + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |