e00032ba6a
Change-Id: I70f34ac5e9b5d2f2d6c0375e823908eaa2e540b2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129487 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
529 lines
15 KiB
C++
529 lines
15 KiB
C++
/* -*- 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: */
|