diff options
author | Akshay Deep <akshaydeepiitr@gmail.com> | 2017-05-11 13:27:38 +0530 |
---|---|---|
committer | Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de> | 2017-06-19 14:36:32 +0200 |
commit | 710a39414569995bd5a8631a948c939dc73bcef9 (patch) | |
tree | e3da87fd9012713605004e8bd20ca2b98df45ac5 /cui | |
parent | cacb75aa0bea36d4e5fc083a75a8b376133d3d65 (diff) |
GSoC: Glyph View and Recent Characters Control in Special Characters dialog
Change-Id: Ia55f3fefe7c14327cff2e996ab0038dc52f9b017
Reviewed-on: https://gerrit.libreoffice.org/37496
Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de>
Tested-by: Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de>
Diffstat (limited to 'cui')
-rw-r--r-- | cui/Library_cui.mk | 1 | ||||
-rw-r--r-- | cui/source/dialogs/charwin.cxx | 213 | ||||
-rw-r--r-- | cui/source/dialogs/cuicharmap.cxx | 504 | ||||
-rw-r--r-- | cui/source/factory/init.cxx | 5 | ||||
-rw-r--r-- | cui/source/inc/charwin.hxx | 56 | ||||
-rw-r--r-- | cui/source/inc/cuicharmap.hxx | 22 | ||||
-rw-r--r-- | cui/uiconfig/ui/specialcharacters.ui | 278 |
7 files changed, 834 insertions, 245 deletions
diff --git a/cui/Library_cui.mk b/cui/Library_cui.mk index 2b9663a7cc93..4f1a89dffa83 100644 --- a/cui/Library_cui.mk +++ b/cui/Library_cui.mk @@ -91,6 +91,7 @@ $(eval $(call gb_Library_add_exception_objects,cui,\ cui/source/dialogs/about \ cui/source/dialogs/colorpicker \ cui/source/dialogs/cuicharmap \ + cui/source/dialogs/charwin \ cui/source/dialogs/cuifmsearch \ cui/source/dialogs/cuigaldlg \ cui/source/dialogs/cuigrfflt \ diff --git a/cui/source/dialogs/charwin.cxx b/cui/source/dialogs/charwin.cxx new file mode 100644 index 000000000000..5f9a7fa49765 --- /dev/null +++ b/cui/source/dialogs/charwin.cxx @@ -0,0 +1,213 @@ +/* -*- 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 <vcl/settings.hxx> +#include <vcl/builderfactory.hxx> +#include "charwin.hxx" +#include <comphelper/propertysequence.hxx> +#include <comphelper/dispatchcommand.hxx> +#include <sfx2/app.hxx> +#include "cuicharmap.hxx" +#include "macroass.hxx" + +using namespace com::sun::star; + + +SvxCharView::SvxCharView(vcl::Window* pParent) + : Control(pParent, WB_TABSTOP | WB_BORDER) + , mnY(0) +{ +} + +VCL_BUILDER_FACTORY(SvxCharView) + +void SvxCharView::MouseButtonDown( const MouseEvent& rMEvt ) +{ + if ( rMEvt.IsLeft() ) + { + maMouseClickHdl.Call(this); + if ( !(rMEvt.GetClicks() % 2) ) + { + InsertCharToDoc(); + } + } + + Control::MouseButtonDown(rMEvt); +} + +void SvxCharView::KeyInput( const KeyEvent& rKEvt ) +{ + vcl::KeyCode aCode = rKEvt.GetKeyCode(); + + switch (aCode.GetCode()) + { + case KEY_SPACE: + case KEY_RETURN: + InsertCharToDoc(); + break; + } + Control::KeyInput(rKEvt); +} + +void SvxCharView::InsertCharToDoc() +{ + if(GetText().isEmpty()) + return; + + uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() ); + + uno::Sequence<beans::PropertyValue> aArgs(2); + aArgs[0].Name = OUString::fromUtf8("Symbols"); + aArgs[0].Value <<= GetText(); + + aArgs[1].Name = OUString::fromUtf8("FontName"); + aArgs[1].Value <<= maFont.GetFamilyName(); + + comphelper::dispatchCommand(".uno:InsertSymbol", aArgs); +} + +void SvxCharView::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&) +{ + rRenderContext.SetFont(maFont); + + const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); + const Color aWindowTextColor(rStyleSettings.GetFieldTextColor()); + Color aHighlightColor(rStyleSettings.GetHighlightColor()); + Color aHighlightTextColor(rStyleSettings.GetHighlightTextColor()); + Color aLightColor(rStyleSettings.GetLightColor()); + + const OUString aText = GetText(); + const Size aSize(GetOutputSizePixel()); + + long nAvailWidth = aSize.Width(); + long nWinHeight = GetOutputSizePixel().Height(); + + bool bGotBoundary = true; + bool bShrankFont = false; + vcl::Font aOrigFont(rRenderContext.GetFont()); + Size aFontSize(aOrigFont.GetFontSize()); + ::tools::Rectangle aBoundRect; + + for (long nFontHeight = aFontSize.Height(); nFontHeight > 0; nFontHeight -= 1) + { + if (!rRenderContext.GetTextBoundRect( aBoundRect, aText ) || aBoundRect.IsEmpty()) + { + bGotBoundary = false; + break; + } + + //only shrink in the single glyph large view mode + long nTextWidth = aBoundRect.GetWidth(); + if (nAvailWidth > nTextWidth) + break; + vcl::Font aFont(aOrigFont); + aFontSize.Height() = nFontHeight; + aFont.SetFontSize(aFontSize); + rRenderContext.SetFont(aFont); + mnY = (nWinHeight - GetTextHeight()) / 2; + bShrankFont = true; + } + + Point aPoint(2, mnY); + + if (!bGotBoundary) + aPoint.X() = (aSize.Width() - rRenderContext.GetTextWidth(aText)) / 2; + else + { + // adjust position + aBoundRect += aPoint; + + // vertical adjustment + int nYLDelta = aBoundRect.Top(); + int nYHDelta = aSize.Height() - aBoundRect.Bottom(); + if( nYLDelta <= 0 ) + aPoint.Y() -= nYLDelta - 1; + else if( nYHDelta <= 0 ) + aPoint.Y() += nYHDelta - 1; + + // centrally align glyph + aPoint.X() = -aBoundRect.Left() + (aSize.Width() - aBoundRect.GetWidth()) / 2; + } + + if (HasFocus()) + { + rRenderContext.SetFillColor(aHighlightColor); + rRenderContext.DrawRect(tools::Rectangle(Point(0, 0), Size(GetOutputSizePixel().Width(), GetOutputSizePixel().Height()))); + + rRenderContext.SetTextColor(aHighlightTextColor); + rRenderContext.DrawText(aPoint, aText); + } + else + { + rRenderContext.SetFillColor(aLightColor); + rRenderContext.DrawRect(tools::Rectangle(Point(0, 0), Size(GetOutputSizePixel().Width(), GetOutputSizePixel().Height()))); + + rRenderContext.SetTextColor(aWindowTextColor); + rRenderContext.DrawText(aPoint, aText); + } + + if (bShrankFont) + rRenderContext.SetFont(aOrigFont); +} + +void SvxCharView::setInsertCharHdl(const Link<SvxCharView*,void> &rLink) +{ + maInsertCharHdl = rLink; +} + +void SvxCharView::setMouseClickHdl(const Link<SvxCharView*,void> &rLink) +{ + maMouseClickHdl = rLink; +} + +void SvxCharView::SetFont( const vcl::Font& rFont ) +{ + long nWinHeight = GetOutputSizePixel().Height(); + maFont = vcl::Font(rFont); + maFont.SetWeight(WEIGHT_NORMAL); + maFont.SetAlignment(ALIGN_TOP); + maFont.SetFontSize(PixelToLogic(Size(0, nWinHeight / 2))); + maFont.SetTransparent(true); + Control::SetFont(maFont); + + mnY = (nWinHeight - GetTextHeight()) / 2; + + Invalidate(); +} + +Size SvxCharView::GetOptimalSize() const +{ + const vcl::Font &rFont = GetFont(); + const Size rFontSize = rFont.GetFontSize(); + long nWinHeight = LogicToPixel(rFontSize).Height() * 2; + return Size( GetTextWidth( GetText() ) + 2 * 12, nWinHeight ); +} + +void SvxCharView::Resize() +{ + Control::Resize(); + SetFont(GetFont()); +} + + +void SvxCharView::SetText( const OUString& rText ) +{ + Control::SetText( rText ); + Invalidate(); +} diff --git a/cui/source/dialogs/cuicharmap.cxx b/cui/source/dialogs/cuicharmap.cxx index 8d1180a9e9b3..59c9225a3e42 100644 --- a/cui/source/dialogs/cuicharmap.cxx +++ b/cui/source/dialogs/cuicharmap.cxx @@ -33,6 +33,11 @@ #include <vcl/builderfactory.hxx> #include <vcl/fontcharmap.hxx> #include <svl/stritem.hxx> +#include <officecfg/Office/Common.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/propertysequence.hxx> +#include <comphelper/dispatchcommand.hxx> +#include <sfx2/app.hxx> #include <cuires.hrc> #include <dialmgr.hxx> @@ -43,18 +48,19 @@ #include <editeng/fontitem.hxx> #include "macroass.hxx" +using namespace css; + // class SvxCharacterMap ================================================= SvxCharacterMap::SvxCharacterMap( vcl::Window* pParent, bool bOne_, const SfxItemSet* pSet ) : SfxModalDialog(pParent, "SpecialCharactersDialog", "cui/ui/specialcharacters.ui") , bOne( bOne_ ) , pSubsetMap( nullptr ) + , mxContext(comphelper::getProcessComponentContext()) { get(m_pShowSet, "showcharset"); get(m_pShowChar, "showchar"); m_pShowChar->SetCentered(true); - get(m_pShowText, "showtext"); - m_pShowText->SetMaxTextLen(CHARMAP_MAXLEN); get(m_pOKBtn, "ok"); get(m_pFontText, "fontft"); get(m_pFontLB, "fontlb"); @@ -68,7 +74,23 @@ SvxCharacterMap::SvxCharacterMap( vcl::Window* pParent, bool bOne_, const SfxIte get(m_pDecimalCodeText, "decimalvalue"); //lock the size request of this widget to the width of the original .ui string m_pHexCodeText->set_width_request(m_pHexCodeText->get_preferred_size().Width()); - get(m_pSymbolText, "symboltext"); + + get( m_pRecentCharView[0], "viewchar1" ); + get( m_pRecentCharView[1], "viewchar2" ); + get( m_pRecentCharView[2], "viewchar3" ); + get( m_pRecentCharView[3], "viewchar4" ); + get( m_pRecentCharView[4], "viewchar5" ); + get( m_pRecentCharView[5], "viewchar6" ); + get( m_pRecentCharView[6], "viewchar7" ); + get( m_pRecentCharView[7], "viewchar8" ); + get( m_pRecentCharView[8], "viewchar9" ); + get( m_pRecentCharView[9], "viewchar10" ); + get( m_pRecentCharView[10], "viewchar11" ); + get( m_pRecentCharView[11], "viewchar12" ); + get( m_pRecentCharView[12], "viewchar13" ); + get( m_pRecentCharView[13], "viewchar14" ); + get( m_pRecentCharView[14], "viewchar15" ); + get( m_pRecentCharView[15], "viewchar16" ); const SfxBoolItem* pItem = SfxItemSet::GetItem<SfxBoolItem>(pSet, FN_PARAM_1, false); if ( pItem ) @@ -108,19 +130,42 @@ SvxCharacterMap::~SvxCharacterMap() disposeOnce(); } +short SvxCharacterMap::Execute() +{ + if( SvxShowCharSet::getSelectedChar() == ' ') + { + m_pOKBtn->Disable(); + } + else + { + sal_UCS4 cChar = m_pShowSet->GetSelectCharacter(); + // using the new UCS4 constructor + OUString aOUStr( &cChar, 1 ); + m_pShowChar->SetText(aOUStr); + m_pOKBtn->Enable(); + } + + return ModalDialog::Execute(); +} + void SvxCharacterMap::dispose() { + for(int i = 0; i < 16; i++) + m_pRecentCharView[i].clear(); + m_pShowSet.clear(); - m_pShowText.clear(); m_pOKBtn.clear(); m_pFontText.clear(); m_pFontLB.clear(); m_pSubsetText.clear(); m_pSubsetLB.clear(); - m_pSymbolText.clear(); m_pShowChar.clear(); m_pHexCodeText.clear(); m_pDecimalCodeText.clear(); + + maRecentCharList.clear(); + maRecentCharFontList.clear(); + SfxModalDialog::dispose(); } @@ -137,172 +182,94 @@ sal_UCS4 SvxCharacterMap::GetChar() const } -OUString SvxCharacterMap::GetCharacters() const -{ - return m_pShowText->GetText(); -} - - void SvxCharacterMap::DisableFontSelection() { m_pFontText->Disable(); m_pFontLB->Disable(); } -short SvxCharacterMap::Execute() + +void SvxCharacterMap::getRecentCharacterList() { - short nResult = SfxModalDialog::Execute(); - if ( nResult == RET_OK ) + //retrieve recent character list + css::uno::Sequence< OUString > rRecentCharList( officecfg::Office::Common::RecentCharacters::RecentCharacterList::get() ); + for (int i = 0; i < rRecentCharList.getLength(); ++i) { - SfxItemSet* pSet = GetItemSet(); - if ( pSet ) - { - const SfxItemPool* pPool = pSet->GetPool(); - const vcl::Font& rFont( GetCharFont() ); - pSet->Put( SfxStringItem( pPool->GetWhich(SID_CHARMAP), GetCharacters() ) ); - pSet->Put( SvxFontItem( rFont.GetFamilyType(), rFont.GetFamilyName(), - rFont.GetStyleName(), rFont.GetPitch(), rFont.GetCharSet(), pPool->GetWhich(SID_ATTR_CHAR_FONT) ) ); - pSet->Put( SfxStringItem( pPool->GetWhich(SID_FONT_NAME), rFont.GetFamilyName() ) ); - pSet->Put( SfxInt32Item( pPool->GetWhich(SID_ATTR_CHAR), GetChar() ) ); - } + maRecentCharList.push_back(rRecentCharList[i]); } - return nResult; + //retrieve recent character font list + css::uno::Sequence< OUString > rRecentCharFontList( officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::get() ); + for (int i = 0; i < rRecentCharFontList.getLength(); ++i) + { + maRecentCharFontList.push_back(rRecentCharFontList[i]); + } } - -// class SvxShowText ===================================================== - -SvxShowText::SvxShowText(vcl::Window* pParent) - : Control(pParent) - , mnY(0) - , mbCenter(false) -{} - -VCL_BUILDER_FACTORY(SvxShowText) - -void SvxShowText::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&) +void SvxCharacterMap::updateRecentCharControl() { - rRenderContext.SetFont(maFont); - - Color aTextCol = rRenderContext.GetTextColor(); - - const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); - const Color aWindowTextColor(rStyleSettings.GetDialogTextColor()); - rRenderContext.SetTextColor(aWindowTextColor); - - const OUString aText = GetText(); - const Size aSize(GetOutputSizePixel()); - - long nAvailWidth = aSize.Width(); - long nWinHeight = GetOutputSizePixel().Height(); - - bool bGotBoundary = true; - bool bShrankFont = false; - vcl::Font aOrigFont(rRenderContext.GetFont()); - Size aFontSize(aOrigFont.GetFontSize()); - ::tools::Rectangle aBoundRect; - - for (long nFontHeight = aFontSize.Height(); nFontHeight > 0; nFontHeight -= 5) + int i = 0; + for ( std::deque< OUString >::iterator it = maRecentCharList.begin(), it2 = maRecentCharFontList.begin(); + it != maRecentCharList.end() || it2 != maRecentCharFontList.end(); + ++it, ++it2, i++) { - if (!rRenderContext.GetTextBoundRect( aBoundRect, aText ) || aBoundRect.IsEmpty()) - { - bGotBoundary = false; - break; - } - if (!mbCenter) - break; - //only shrink in the single glyph large view mode - long nTextWidth = aBoundRect.GetWidth(); - if (nAvailWidth > nTextWidth) - break; - vcl::Font aFont(aOrigFont); - aFontSize.Height() = nFontHeight; - aFont.SetFontSize(aFontSize); - rRenderContext.SetFont(aFont); - mnY = (nWinHeight - GetTextHeight()) / 2; - bShrankFont = true; + m_pRecentCharView[i]->SetText(*it); + vcl::Font rFont = m_pRecentCharView[i]->GetControlFont(); + rFont.SetFamilyName( *it2 ); + m_pRecentCharView[i]->SetFont(rFont); + m_pRecentCharView[i]->Show(); } - Point aPoint(2, mnY); - // adjust position using ink boundary if possible - if (!bGotBoundary) - aPoint.X() = (aSize.Width() - rRenderContext.GetTextWidth(aText)) / 2; - else + for(; i < 16 ; i++) { - // adjust position before it gets out of bounds - aBoundRect += aPoint; - - // shift back vertically if needed - int nYLDelta = aBoundRect.Top(); - int nYHDelta = aSize.Height() - aBoundRect.Bottom(); - if( nYLDelta <= 0 ) - aPoint.Y() -= nYLDelta - 1; - else if( nYHDelta <= 0 ) - aPoint.Y() += nYHDelta - 1; - - if (mbCenter) - { - // move glyph to middle of cell - aPoint.X() = -aBoundRect.Left() + (aSize.Width() - aBoundRect.GetWidth()) / 2; - } - else - { - // shift back horizontally if needed - int nXLDelta = aBoundRect.Left(); - int nXHDelta = aSize.Width() - aBoundRect.Right(); - if( nXLDelta <= 0 ) - aPoint.X() -= nXLDelta - 1; - else if( nXHDelta <= 0 ) - aPoint.X() += nXHDelta - 1; - } + m_pRecentCharView[i]->SetText(OUString()); + m_pRecentCharView[i]->Hide(); } - - rRenderContext.DrawText(aPoint, aText); - rRenderContext.SetTextColor(aTextCol); - if (bShrankFont) - rRenderContext.SetFont(aOrigFont); } - -void SvxShowText::SetFont( const vcl::Font& rFont ) +void SvxCharacterMap::updateRecentCharacterList(const OUString& sTitle, const OUString& rFont) { - long nWinHeight = GetOutputSizePixel().Height(); - maFont = vcl::Font(rFont); - maFont.SetWeight(WEIGHT_NORMAL); - maFont.SetAlignment(ALIGN_TOP); - maFont.SetFontSize(PixelToLogic(Size(0, nWinHeight / 2))); - maFont.SetTransparent(true); - Control::SetFont(maFont); + auto itChar = std::find_if(maRecentCharList.begin(), + maRecentCharList.end(), + [sTitle] (const OUString & a) { return a == sTitle; }); - mnY = (nWinHeight - GetTextHeight()) / 2; + auto itChar2 = std::find_if(maRecentCharFontList.begin(), + maRecentCharFontList.end(), + [rFont] (const OUString & a) { return a == rFont; }); - Invalidate(); -} + // if recent char to be added is already in list, remove it + if( itChar != maRecentCharList.end() && itChar2 != maRecentCharFontList.end() ) + { + maRecentCharList.erase( itChar ); + maRecentCharFontList.erase( itChar2); + } -Size SvxShowText::GetOptimalSize() const -{ - const vcl::Font &rFont = GetFont(); - const Size rFontSize = rFont.GetFontSize(); - long nWinHeight = LogicToPixel(rFontSize).Height() * 2; - return Size( GetTextWidth( GetText() ) + 2 * 12, nWinHeight ); -} + if (maRecentCharList.size() == 16) + { + maRecentCharList.pop_back(); + maRecentCharFontList.pop_back(); + } -void SvxShowText::Resize() -{ - Control::Resize(); - SetFont(GetFont()); //force recalculation of size -} + maRecentCharList.push_front(sTitle); + maRecentCharFontList.push_front(rFont); + css::uno::Sequence< OUString > aRecentCharList(maRecentCharList.size()); + css::uno::Sequence< OUString > aRecentCharFontList(maRecentCharFontList.size()); -void SvxShowText::SetText( const OUString& rText ) -{ - Control::SetText( rText ); - Invalidate(); -} + for (size_t i = 0; i < maRecentCharList.size(); ++i) + { + aRecentCharList[i] = maRecentCharList[i]; + aRecentCharFontList[i] = maRecentCharFontList[i]; + } + std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create(mxContext)); + officecfg::Office::Common::RecentCharacters::RecentCharacterList::set(aRecentCharList, batch); + officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set(aRecentCharFontList, batch); + batch->commit(); + + updateRecentCharControl(); +} -// class SvxCharacterMap ================================================= void SvxCharacterMap::init() { @@ -312,12 +279,6 @@ void SvxCharacterMap::init() aFont.SetPitch( PITCH_DONTKNOW ); aFont.SetCharSet( RTL_TEXTENCODING_DONTKNOW ); - if (bOne) - { - m_pSymbolText->Hide(); - m_pShowText->Hide(); - } - OUString aDefStr( aFont.GetFamilyName() ); OUString aLastName; int nCount = GetDevFontCount(); @@ -357,9 +318,9 @@ void SvxCharacterMap::init() m_pFontLB->SelectEntryPos(0); FontSelectHdl(*m_pFontLB); - m_pOKBtn->SetClickHdl( LINK( this, SvxCharacterMap, OKHdl ) ); m_pFontLB->SetSelectHdl( LINK( this, SvxCharacterMap, FontSelectHdl ) ); m_pSubsetLB->SetSelectHdl( LINK( this, SvxCharacterMap, SubsetSelectHdl ) ); + m_pOKBtn->SetClickHdl( LINK( this, SvxCharacterMap, InsertClickHdl ) ); m_pShowSet->SetDoubleClickHdl( LINK( this, SvxCharacterMap, CharDoubleClickHdl ) ); m_pShowSet->SetSelectHdl( LINK( this, SvxCharacterMap, CharSelectHdl ) ); m_pShowSet->SetHighlightHdl( LINK( this, SvxCharacterMap, CharHighlightHdl ) ); @@ -368,9 +329,26 @@ void SvxCharacterMap::init() m_pHexCodeText->SetModifyHdl( LINK( this, SvxCharacterMap, HexCodeChangeHdl ) ); if( SvxShowCharSet::getSelectedChar() == ' ') + { m_pOKBtn->Disable(); + } else + { + sal_UCS4 cChar = m_pShowSet->GetSelectCharacter(); + // using the new UCS4 constructor + OUString aOUStr( &cChar, 1 ); + m_pShowChar->SetText(aOUStr); m_pOKBtn->Enable(); + } + + getRecentCharacterList(); + updateRecentCharControl(); + + for(int i = 0; i < 16; i++) + { + m_pRecentCharView[i]->setMouseClickHdl(LINK(this,SvxCharacterMap, RecentClickHdl)); + m_pRecentCharView[i]->SetLoseFocusHdl(LINK(this,SvxCharacterMap, LoseFocusHdl)); + } } @@ -399,20 +377,6 @@ void SvxCharacterMap::SetCharFont( const vcl::Font& rFont ) } -IMPL_LINK_NOARG(SvxCharacterMap, OKHdl, Button*, void) -{ - OUString aStr = m_pShowText->GetText(); - - if ( aStr.isEmpty() ) - { - sal_UCS4 cChar = m_pShowSet->GetSelectCharacter(); - // using the new UCS4 constructor - OUString aOUStr( &cChar, 1 ); - m_pShowText->SetText( aOUStr ); - } - EndDialog( RET_OK ); -} - void SvxCharacterMap::fillAllSubsets(ListBox &rListBox) { SubsetMap aAll(nullptr); @@ -426,6 +390,25 @@ void SvxCharacterMap::fillAllSubsets(ListBox &rListBox) } +void SvxCharacterMap::insertCharToDoc(const OUString& sGlyph) +{ + if(sGlyph.isEmpty()) + return; + + uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() ); + + uno::Sequence<beans::PropertyValue> aArgs(2); + aArgs[0].Name = OUString::fromUtf8("Symbols"); + aArgs[0].Value <<= sGlyph; + + aArgs[1].Name = OUString::fromUtf8("FontName"); + aArgs[1].Value <<= aFont.GetFamilyName(); + comphelper::dispatchCommand(".uno:InsertSymbol", aArgs); + + updateRecentCharacterList(sGlyph, aFont.GetFamilyName()); +} + + IMPL_LINK_NOARG(SvxCharacterMap, FontSelectHdl, ListBox&, void) { const sal_Int32 nPos = m_pFontLB->GetSelectEntryPos(); @@ -440,7 +423,6 @@ IMPL_LINK_NOARG(SvxCharacterMap, FontSelectHdl, ListBox&, void) // notify children using this font m_pShowSet->SetFont( aFont ); m_pShowChar->SetFont( aFont ); - m_pShowText->SetControlFont( aFont ); // setup unicode subset listbar with font specific subsets, // hide unicode subset listbar for symbol fonts @@ -490,46 +472,39 @@ IMPL_LINK_NOARG(SvxCharacterMap, SubsetSelectHdl, ListBox&, void) m_pSubsetLB->SelectEntryPos( nPos ); } +IMPL_LINK(SvxCharacterMap, RecentClickHdl, SvxCharView*, rView, void) +{ + m_pShowChar->SetText( rView->GetText() ); + m_pShowChar->SetFont(rView->GetFont()); + m_pShowChar->Update(); + rView->GrabFocus(); + rView->Invalidate(); + m_pOKBtn->Enable(); +} IMPL_LINK_NOARG(SvxCharacterMap, CharDoubleClickHdl, SvxShowCharSet*, void) { - if (bOne) - { - sal_UCS4 cChar = m_pShowSet->GetSelectCharacter(); - m_pShowText->SetText(OUString(&cChar, 1)); - } - EndDialog( RET_OK ); + sal_UCS4 cChar = m_pShowSet->GetSelectCharacter(); + // using the new UCS4 constructor + OUString aOUStr( &cChar, 1 ); + insertCharToDoc(aOUStr); } - IMPL_LINK_NOARG(SvxCharacterMap, CharSelectHdl, SvxShowCharSet*, void) { - if ( !bOne ) - { - OUString aText = m_pShowText->GetText(); - Selection aSelection = m_pShowText->GetSelection(); - aSelection.Justify(); - long nLen = aSelection.Len(); - - if ( aText.getLength() != CHARMAP_MAXLEN || nLen > 0 ) - { - sal_UCS4 cChar = m_pShowSet->GetSelectCharacter(); - // using the new UCS4 constructor - OUString aOUStr( &cChar, 1 ); + m_pOKBtn->Enable(); +} - long nPos = aSelection.Min(); - if( aText.getLength() ) - { - m_pShowText->SetText( aText.copy( 0, nPos ) + aOUStr + aText.copy( nPos + nLen ) ); - } - else - m_pShowText->SetText( aOUStr ); +IMPL_LINK_NOARG(SvxCharacterMap, InsertClickHdl, Button*, void) +{ + insertCharToDoc(m_pShowChar->GetText()); + EndDialog(RET_OK); +} - m_pShowText->SetSelection(Selection(nPos + aOUStr.getLength())); - } - } - m_pOKBtn->Enable(); +IMPL_STATIC_LINK(SvxCharacterMap, LoseFocusHdl, Control&, pItem, void) +{ + pItem.Invalidate(); } @@ -555,8 +530,13 @@ IMPL_LINK_NOARG(SvxCharacterMap, CharHighlightHdl, SvxShowCharSet*, void) else m_pSubsetLB->SetNoSelection(); } - m_pShowChar->SetText( aText ); - m_pShowChar->Update(); + + if(m_pShowSet->HasFocus()) + { + m_pShowChar->SetText( aText ); + m_pShowChar->SetFont( aFont ); + m_pShowChar->Update(); + } // show char codes if ( bSelect ) @@ -624,4 +604,136 @@ IMPL_LINK_NOARG(SvxCharacterMap, CharPreSelectHdl, SvxShowCharSet*, void) m_pOKBtn->Enable(); } + +// class SvxShowText ===================================================== + +SvxShowText::SvxShowText(vcl::Window* pParent) + : Control(pParent) + , mnY(0) + , mbCenter(false) +{} + +VCL_BUILDER_FACTORY(SvxShowText) + +void SvxShowText::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&) +{ + rRenderContext.SetFont(maFont); + + Color aTextCol = rRenderContext.GetTextColor(); + + const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); + const Color aWindowTextColor(rStyleSettings.GetDialogTextColor()); + rRenderContext.SetTextColor(aWindowTextColor); + + const OUString aText = GetText(); + const Size aSize(GetOutputSizePixel()); + + long nAvailWidth = aSize.Width(); + long nWinHeight = GetOutputSizePixel().Height(); + + bool bGotBoundary = true; + bool bShrankFont = false; + vcl::Font aOrigFont(rRenderContext.GetFont()); + Size aFontSize(aOrigFont.GetFontSize()); + ::tools::Rectangle aBoundRect; + + for (long nFontHeight = aFontSize.Height(); nFontHeight > 0; nFontHeight -= 5) + { + if (!rRenderContext.GetTextBoundRect( aBoundRect, aText ) || aBoundRect.IsEmpty()) + { + bGotBoundary = false; + break; + } + if (!mbCenter) + break; + //only shrink in the single glyph large view mode + long nTextWidth = aBoundRect.GetWidth(); + if (nAvailWidth > nTextWidth) + break; + vcl::Font aFont(aOrigFont); + aFontSize.Height() = nFontHeight; + aFont.SetFontSize(aFontSize); + rRenderContext.SetFont(aFont); + mnY = (nWinHeight - GetTextHeight()) / 2; + bShrankFont = true; + } + + Point aPoint(2, mnY); + // adjust position using ink boundary if possible + if (!bGotBoundary) + aPoint.X() = (aSize.Width() - rRenderContext.GetTextWidth(aText)) / 2; + else + { + // adjust position before it gets out of bounds + aBoundRect += aPoint; + + // shift back vertically if needed + int nYLDelta = aBoundRect.Top(); + int nYHDelta = aSize.Height() - aBoundRect.Bottom(); + if( nYLDelta <= 0 ) + aPoint.Y() -= nYLDelta - 1; + else if( nYHDelta <= 0 ) + aPoint.Y() += nYHDelta - 1; + + if (mbCenter) + { + // move glyph to middle of cell + aPoint.X() = -aBoundRect.Left() + (aSize.Width() - aBoundRect.GetWidth()) / 2; + } + else + { + // shift back horizontally if needed + int nXLDelta = aBoundRect.Left(); + int nXHDelta = aSize.Width() - aBoundRect.Right(); + if( nXLDelta <= 0 ) + aPoint.X() -= nXLDelta - 1; + else if( nXHDelta <= 0 ) + aPoint.X() += nXHDelta - 1; + } + } + + rRenderContext.DrawText(aPoint, aText); + rRenderContext.SetTextColor(aTextCol); + if (bShrankFont) + rRenderContext.SetFont(aOrigFont); +} + + +void SvxShowText::SetFont( const vcl::Font& rFont ) +{ + long nWinHeight = GetOutputSizePixel().Height(); + maFont = vcl::Font(rFont); + maFont.SetWeight(WEIGHT_NORMAL); + maFont.SetAlignment(ALIGN_TOP); + maFont.SetFontSize(PixelToLogic(Size(0, nWinHeight / 2))); + maFont.SetTransparent(true); + Control::SetFont(maFont); + + mnY = (nWinHeight - GetTextHeight()) / 2; + + Invalidate(); +} + +Size SvxShowText::GetOptimalSize() const +{ + const vcl::Font &rFont = GetFont(); + const Size rFontSize = rFont.GetFontSize(); + long nWinHeight = LogicToPixel(rFontSize).Height() * 2; + return Size( GetTextWidth( GetText() ) + 2 * 12, nWinHeight ); +} + +void SvxShowText::Resize() +{ + Control::Resize(); + SetFont(GetFont()); //force recalculation of size +} + + +void SvxShowText::SetText( const OUString& rText ) +{ + Control::SetText( rText ); + Invalidate(); +} + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cui/source/factory/init.cxx b/cui/source/factory/init.cxx index fd7cbc63e50c..e23077a0342b 100644 --- a/cui/source/factory/init.cxx +++ b/cui/source/factory/init.cxx @@ -32,7 +32,10 @@ SAL_DLLPUBLIC_EXPORT bool GetSpecialCharsForEdit(vcl::Window* i_pParent, const v aDlg->SetCharFont(i_rFont); if ( aDlg->Execute() == RET_OK ) { - o_rResult = aDlg->GetCharacters(); + sal_UCS4 cChar = aDlg->GetChar(); + // using the new UCS4 constructor + OUString aOUStr( &cChar, 1 ); + o_rResult = aOUStr; bRet = true; } return bRet; diff --git a/cui/source/inc/charwin.hxx b/cui/source/inc/charwin.hxx new file mode 100644 index 000000000000..7feb06800fe5 --- /dev/null +++ b/cui/source/inc/charwin.hxx @@ -0,0 +1,56 @@ +/* -*- 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 . + */ + +#ifndef INCLUDED_CUI_SOURCE_INC_CHARWIN_HXX +#define INCLUDED_CUI_SOURCE_INC_CHARWIN_HXX + +#include <vcl/ctrl.hxx> + +class SvxCharView : public Control +{ +public: + SvxCharView(vcl::Window* pParent); + + void SetFont( const vcl::Font& rFont ); + void SetText( const OUString& rText ) override; + void InsertCharToDoc(); + + virtual void Resize() override; + + virtual Size GetOptimalSize() const override; + + void setInsertCharHdl(const Link<SvxCharView*,void> &rLink); + void setMouseClickHdl(const Link<SvxCharView*,void> &rLink); + +protected: + virtual void Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&) override; + + virtual void MouseButtonDown( const MouseEvent& rMEvt ) override; + + virtual void KeyInput( const KeyEvent& rKEvt ) override; + +private: + long mnY; + vcl::Font maFont; + + Link<SvxCharView*, void> maInsertCharHdl; + Link<SvxCharView*, void> maMouseClickHdl; +}; + +#endif diff --git a/cui/source/inc/cuicharmap.hxx b/cui/source/inc/cuicharmap.hxx index 8d83798ecdbe..4f1a63f5ec71 100644 --- a/cui/source/inc/cuicharmap.hxx +++ b/cui/source/inc/cuicharmap.hxx @@ -26,7 +26,9 @@ #include <vcl/lstbox.hxx> #include <sfx2/basedlgs.hxx> #include <svx/charmap.hxx> +#include "charwin.hxx" +using namespace ::com::sun::star; class SubsetMap; #define CHARMAP_MAXLEN 32 @@ -68,22 +70,26 @@ private: void init(); VclPtr<SvxShowCharSet> m_pShowSet; - VclPtr<Edit> m_pShowText; VclPtr<PushButton> m_pOKBtn; VclPtr<FixedText> m_pFontText; VclPtr<ListBox> m_pFontLB; VclPtr<FixedText> m_pSubsetText; VclPtr<ListBox> m_pSubsetLB; - VclPtr<FixedText> m_pSymbolText; VclPtr<SvxShowText> m_pShowChar; VclPtr<Edit> m_pHexCodeText; VclPtr<Edit> m_pDecimalCodeText; + VclPtr<SvxCharView> m_pRecentCharView[16]; vcl::Font aFont; bool bOne; const SubsetMap* pSubsetMap; + + std::deque<OUString> maRecentCharList; + std::deque<OUString> maRecentCharFontList; + + uno::Reference< uno::XComponentContext > mxContext; + enum class Radix : sal_Int16 {decimal = 10, hexadecimal=16}; - DECL_LINK(OKHdl, Button*, void); DECL_LINK(FontSelectHdl, ListBox&, void); DECL_LINK(SubsetSelectHdl, ListBox&, void); DECL_LINK(CharDoubleClickHdl, SvxShowCharSet*,void); @@ -92,6 +98,9 @@ private: DECL_LINK(CharPreSelectHdl, SvxShowCharSet*, void); DECL_LINK(DecimalCodeChangeHdl, Edit&, void); DECL_LINK(HexCodeChangeHdl, Edit&, void); + DECL_LINK(RecentClickHdl, SvxCharView*, void); + DECL_LINK(InsertClickHdl, Button*, void); + DECL_STATIC_LINK(SvxCharacterMap, LoseFocusHdl, Control&, void); static void fillAllSubsets(ListBox &rListBox); void selectCharByCode(Radix radix); @@ -99,6 +108,7 @@ private: public: SvxCharacterMap( vcl::Window* pParent, bool bOne=true, const SfxItemSet* pSet=nullptr ); virtual ~SvxCharacterMap() override; + virtual short Execute() override; virtual void dispose() override; void DisableFontSelection(); @@ -109,9 +119,11 @@ public: void SetChar( sal_UCS4 ); sal_UCS4 GetChar() const; - OUString GetCharacters() const; + void getRecentCharacterList(); //gets both recent char and recent char font list + void updateRecentCharacterList(const OUString& rChar, const OUString& rFont); - virtual short Execute() override; + void updateRecentCharControl(); + void insertCharToDoc(const OUString& sChar); }; #endif diff --git a/cui/uiconfig/ui/specialcharacters.ui b/cui/uiconfig/ui/specialcharacters.ui index 80ec3d2ad7b5..130f564d24b3 100644 --- a/cui/uiconfig/ui/specialcharacters.ui +++ b/cui/uiconfig/ui/specialcharacters.ui @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.19.0 --> +<!-- Generated with glade 3.18.3 --> <interface> <requires lib="gtk+" version="3.0"/> <requires lib="LibreOffice" version="1.0"/> @@ -140,44 +140,6 @@ </packing> </child> <child> - <object class="GtkBox" id="box2"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="spacing">12</property> - <child> - <object class="GtkLabel" id="symboltext"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="valign">center</property> - <property name="label" translatable="yes">Characters:</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="showtext"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="valign">center</property> - <property name="invisible_char">•</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">2</property> - <property name="width">2</property> - </packing> - </child> - <child> <object class="svxlo-SvxShowCharSet" id="showcharset"> <property name="width_request">580</property> <property name="height_request">250</property> @@ -221,8 +183,8 @@ <object class="GtkLabel" id="hexlabel"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="label" translatable="yes">Hexadecimal:</property> <property name="xalign">0</property> + <property name="label" translatable="yes">Hexadecimal:</property> </object> <packing> <property name="left_attach">0</property> @@ -240,7 +202,7 @@ <property name="can_focus">True</property> <property name="halign">center</property> <property name="width_chars">8</property> - <property name="text" translatable="no">A2</property> + <property name="text">A2</property> </object> <packing> <property name="left_attach">1</property> @@ -251,7 +213,7 @@ <object class="GtkLabel" id="hexulabel"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="label" translatable="no">U+</property> + <property name="label">U+</property> <property name="width_chars">3</property> <property name="single_line_mode">True</property> <property name="max_width_chars">3</property> @@ -272,8 +234,8 @@ <object class="GtkLabel" id="decimallabel"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="label" translatable="yes">Decimal:</property> <property name="xalign">0</property> + <property name="label" translatable="yes">Decimal:</property> </object> <packing> <property name="left_attach">0</property> @@ -304,6 +266,236 @@ <property name="top_attach">1</property> </packing> </child> + <child> + <object class="GtkBox" id="box1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">12</property> + <child> + <object class="GtkLabel" id="symboltext1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">start</property> + <property name="valign">start</property> + <property name="label" translatable="yes">Recent Characters:</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox" id="box3"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="cuilo-SvxCharView" id="viewchar1"> + <property name="width_request">40</property> + <property name="height_request">35</property> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="cuilo-SvxCharView" id="viewchar2"> + <property name="width_request">40</property> + <property name="height_request">35</property> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="cuilo-SvxCharView" id="viewchar3"> + <property name="width_request">40</property> + <property name="height_request">35</property> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="cuilo-SvxCharView" id="viewchar4"> + <property name="width_request">40</property> + <property name="height_request">35</property> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">3</property> + </packing> + </child> + <child> + <object class="cuilo-SvxCharView" id="viewchar5"> + <property name="width_request">40</property> + <property name="height_request">35</property> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">4</property> + </packing> + </child> + <child> + <object class="cuilo-SvxCharView" id="viewchar6"> + <property name="width_request">40</property> + <property name="height_request">35</property> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">5</property> + </packing> + </child> + <child> + <object class="cuilo-SvxCharView" id="viewchar7"> + <property name="width_request">40</property> + <property name="height_request">35</property> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">6</property> + </packing> + </child> + <child> + <object class="cuilo-SvxCharView" id="viewchar8"> + <property name="width_request">40</property> + <property name="height_request">35</property> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">7</property> + </packing> + </child> + <child> + <object class="cuilo-SvxCharView" id="viewchar9"> + <property name="width_request">40</property> + <property name="height_request">35</property> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">8</property> + </packing> + </child> + <child> + <object class="cuilo-SvxCharView" id="viewchar10"> + <property name="width_request">40</property> + <property name="height_request">35</property> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">9</property> + </packing> + </child> + <child> + <object class="cuilo-SvxCharView" id="viewchar11"> + <property name="width_request">40</property> + <property name="height_request">35</property> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">10</property> + </packing> + </child> + <child> + <object class="cuilo-SvxCharView" id="viewchar12"> + <property name="width_request">40</property> + <property name="height_request">35</property> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">11</property> + </packing> + </child> + <child> + <object class="cuilo-SvxCharView" id="viewchar13"> + <property name="width_request">40</property> + <property name="height_request">35</property> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">12</property> + </packing> + </child> + <child> + <object class="cuilo-SvxCharView" id="viewchar14"> + <property name="width_request">40</property> + <property name="height_request">35</property> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">13</property> + </packing> + </child> + <child> + <object class="cuilo-SvxCharView" id="viewchar15"> + <property name="width_request">40</property> + <property name="height_request">35</property> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">14</property> + </packing> + </child> + <child> + <object class="cuilo-SvxCharView" id="viewchar16"> + <property name="width_request">40</property> + <property name="height_request">35</property> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">15</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + <property name="width">2</property> + </packing> + </child> </object> <packing> <property name="expand">False</property> |