summaryrefslogtreecommitdiff
path: root/svx
diff options
context:
space:
mode:
authorAkshay Deep <akshaydeepiitr@gmail.com>2017-07-30 15:03:56 +0530
committerHeiko Tietze <tietze.heiko@googlemail.com>2017-08-10 10:28:19 +0200
commite74be9ad773c7769c5d8765bb2ac234967e420ec (patch)
tree09699787837732c4103e7666ce21f4c6824fe10c /svx
parent86bc72072ece83c3560dbf874d6469f771c95289 (diff)
Search feature for Special Characters
1. Name data stored in map 2. Retrive the data to compare with search string 3. create search control 4. populate search results 5. Read-only subset listbox meanwhile Change-Id: I689bbee0dd9a226261c37a5824af7f83a510167d Reviewed-on: https://gerrit.libreoffice.org/40563 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Heiko Tietze <tietze.heiko@googlemail.com> Tested-by: Heiko Tietze <tietze.heiko@googlemail.com>
Diffstat (limited to 'svx')
-rw-r--r--svx/Library_svx.mk1
-rw-r--r--svx/source/dialog/charmap.cxx14
-rw-r--r--svx/source/dialog/searchcharmap.cxx475
3 files changed, 486 insertions, 4 deletions
diff --git a/svx/Library_svx.mk b/svx/Library_svx.mk
index d326ad7365eb..d1c310fe29af 100644
--- a/svx/Library_svx.mk
+++ b/svx/Library_svx.mk
@@ -108,6 +108,7 @@ $(eval $(call gb_Library_add_exception_objects,svx,\
svx/source/customshapes/EnhancedCustomShapeHandle \
svx/source/dialog/_bmpmask \
svx/source/dialog/charmap \
+ svx/source/dialog/searchcharmap \
svx/source/dialog/connctrl \
svx/source/dialog/_contdlg \
svx/source/dialog/contwnd \
diff --git a/svx/source/dialog/charmap.cxx b/svx/source/dialog/charmap.cxx
index 5f4d17043f30..4904de3ab689 100644
--- a/svx/source/dialog/charmap.cxx
+++ b/svx/source/dialog/charmap.cxx
@@ -25,6 +25,8 @@
#include <rtl/textenc.h>
#include <svx/ucsubset.hxx>
+#include <unordered_map>
+
#include <svx/strings.hrc>
@@ -146,7 +148,7 @@ void SvxShowCharSet::MouseButtonDown( const MouseEvent& rMEvt )
CaptureMouse();
int nIndex = PixelToMapIndex( rMEvt.GetPosPixel() );
- // Fire the focus event
+ // Fire the focus event
SelectIndex( nIndex, true);
}
@@ -231,7 +233,7 @@ int SvxShowCharSet::LastInView() const
}
-inline Point SvxShowCharSet::MapIndexToPixel( int nIndex ) const
+Point SvxShowCharSet::MapIndexToPixel( int nIndex ) const
{
const int nBase = FirstInView();
int x = ((nIndex - nBase) % COLUMN_COUNT) * nX;
@@ -650,7 +652,6 @@ void SvxShowCharSet::OutputIndex( int nNewIndex )
{
SelectIndex( nNewIndex, true );
aSelectHdl.Call( this );
-
}
@@ -763,9 +764,13 @@ SubsetMap::SubsetMap( const FontCharMapRef& rxFontCharMap )
const Subset* SubsetMap::GetNextSubset( bool bFirst ) const
{
if( bFirst )
+ {
maSubsetIterator = maSubsets.begin();
+ }
+
if( maSubsetIterator == maSubsets.end() )
return nullptr;
+
const Subset* s = &*(maSubsetIterator++);
return s;
}
@@ -781,7 +786,8 @@ const Subset* SubsetMap::GetSubsetByUnicode( sal_UCS4 cChar ) const
inline Subset::Subset(sal_UCS4 nMin, sal_UCS4 nMax, const OUString& rName)
: mnRangeMin(nMin), mnRangeMax(nMax), maRangeName(rName)
-{}
+{
+}
void SubsetMap::InitList()
{
diff --git a/svx/source/dialog/searchcharmap.cxx b/svx/source/dialog/searchcharmap.cxx
new file mode 100644
index 000000000000..2e4379440015
--- /dev/null
+++ b/svx/source/dialog/searchcharmap.cxx
@@ -0,0 +1,475 @@
+/* -*- 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/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/builderfactory.hxx>
+#include <vcl/fontcharmap.hxx>
+#include <svtools/colorcfg.hxx>
+
+#include <rtl/textenc.h>
+#include <svx/ucsubset.hxx>
+#include <unordered_map>
+
+
+#include <svx/strings.hrc>
+
+#include <svx/searchcharmap.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/svxdlg.hxx>
+
+#include "charmapacc.hxx"
+#include "uiobject.hxx"
+
+#include <com/sun/star/accessibility/AccessibleEventObject.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <comphelper/types.hxx>
+#include <svl/itemset.hxx>
+#include <unicode/uchar.h>
+#include "rtl/ustrbuf.hxx"
+
+using namespace ::com::sun::star::accessibility;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star;
+
+
+SvxSearchCharSet::SvxSearchCharSet(vcl::Window* pParent)
+ : SvxShowCharSet(pParent),
+ nCount(0)
+{
+}
+
+VCL_BUILDER_FACTORY(SvxSearchCharSet)
+
+
+int SvxSearchCharSet::LastInView() const
+{
+ sal_uIntPtr nIndex = FirstInView();
+ nIndex += ROW_COUNT * COLUMN_COUNT - 1;
+ sal_uIntPtr nCompare = sal::static_int_cast<sal_uIntPtr>(nCount - 1);
+ if (nIndex > nCompare)
+ nIndex = nCompare;
+ return nIndex;
+}
+
+
+void SvxSearchCharSet::KeyInput(const KeyEvent& rKEvt)
+{
+ vcl::KeyCode aCode = rKEvt.GetKeyCode();
+
+ if (aCode.GetModifier())
+ {
+ Control::KeyInput(rKEvt);
+ return;
+ }
+
+ int tmpSelected = nSelectedIndex;
+
+ switch (aCode.GetCode())
+ {
+ case KEY_SPACE:
+ aSelectHdl.Call( this );
+ break;
+ case KEY_LEFT:
+ --tmpSelected;
+ break;
+ case KEY_RIGHT:
+ ++tmpSelected;
+ break;
+ case KEY_UP:
+ tmpSelected -= COLUMN_COUNT;
+ break;
+ case KEY_DOWN:
+ tmpSelected += COLUMN_COUNT;
+ break;
+ case KEY_PAGEUP:
+ tmpSelected -= ROW_COUNT * COLUMN_COUNT;
+ break;
+ case KEY_PAGEDOWN:
+ tmpSelected += ROW_COUNT * COLUMN_COUNT;
+ break;
+ case KEY_HOME:
+ tmpSelected = 0;
+ break;
+ case KEY_END:
+ tmpSelected = nCount - 1;
+ break;
+ case KEY_TAB: // some fonts have a character at these unicode control codes
+ case KEY_ESCAPE:
+ case KEY_RETURN:
+ Control::KeyInput(rKEvt);
+ tmpSelected = - 1; // mark as invalid
+ break;
+ default:
+ {
+ tmpSelected = -1;
+ }
+ }
+
+ if ( tmpSelected >= 0 )
+ {
+ SelectIndex( tmpSelected, true );
+ aPreSelectHdl.Call( this );
+ }
+}
+
+void SvxSearchCharSet::SelectCharacter( const Subset* sub )
+{
+ if ( !mxFontCharMap.is() )
+ RecalculateFont( *this );
+
+ // get next available char of current font
+ sal_UCS4 cChar = sub->GetRangeMin();
+ int nMapIndex = 0;
+
+ while(cChar <= sub->GetRangeMax() && nMapIndex == 0)
+ {
+ for(auto it = m_aItemList.begin(); it!= m_aItemList.end(); it++)
+ if(it->second == cChar)
+ {
+ nMapIndex = it->first;
+ break;
+ }
+ cChar++;
+ }
+
+ if(nMapIndex == 0)
+ SelectIndex( 0 );
+ else
+ SelectIndex( nMapIndex );
+ aHighHdl.Call(this);
+ // move selected item to top row if not in focusf
+ aVscrollSB->SetThumbPos( nMapIndex / COLUMN_COUNT );
+ Invalidate();
+}
+
+void SvxSearchCharSet::Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& )
+{
+ InitSettings(rRenderContext);
+ RecalculateFont(rRenderContext);
+ DrawChars_Impl(rRenderContext, FirstInView(), LastInView());
+}
+
+void SvxSearchCharSet::DrawChars_Impl(vcl::RenderContext& rRenderContext, int n1, int n2)
+{
+ if (n1 > LastInView() || n2 < FirstInView())
+ return;
+
+ Size aOutputSize(GetOutputSizePixel());
+ if (aVscrollSB->IsVisible())
+ aOutputSize.Width() -= aVscrollSB->GetOptimalSize().Width();
+
+ int i;
+ for (i = 1; i < COLUMN_COUNT; ++i)
+ {
+ rRenderContext.DrawLine(Point(nX * i + m_nXGap, 0),
+ Point(nX * i + m_nXGap, aOutputSize.Height()));
+ }
+ for (i = 1; i < ROW_COUNT; ++i)
+ {
+ rRenderContext.DrawLine(Point(0, nY * i + m_nYGap),
+ Point(aOutputSize.Width(), nY * i + m_nYGap));
+ }
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ const Color aWindowTextColor(rStyleSettings.GetFieldTextColor());
+ Color aHighlightColor(rStyleSettings.GetHighlightColor());
+ Color aHighlightTextColor(rStyleSettings.GetHighlightTextColor());
+ Color aFaceColor(rStyleSettings.GetFaceColor());
+ Color aLightColor(rStyleSettings.GetLightColor());
+ Color aShadowColor(rStyleSettings.GetShadowColor());
+
+ int nTextHeight = rRenderContext.GetTextHeight();
+ tools::Rectangle aBoundRect;
+ for (i = n1; i <= n2; ++i)
+ {
+ Point pix = MapIndexToPixel(i);
+ int x = pix.X();
+ int y = pix.Y();
+
+ OUStringBuffer buf;
+ std::unordered_map<sal_Int32, sal_UCS4>::const_iterator got = m_aItemList.find (i);
+ sal_UCS4 sName;
+
+ if(got == m_aItemList.end())
+ continue;
+ else
+ sName = got->second;
+
+ buf.appendUtf32(sName);
+ OUString aCharStr(buf.makeStringAndClear());
+ int nTextWidth = rRenderContext.GetTextWidth(aCharStr);
+ int tx = x + (nX - nTextWidth + 1) / 2;
+ int ty = y + (nY - nTextHeight + 1) / 2;
+ Point aPointTxTy(tx, ty);
+
+ // adjust position before it gets out of bounds
+ if (rRenderContext.GetTextBoundRect(aBoundRect, aCharStr) && !aBoundRect.IsEmpty())
+ {
+ // zero advance width => use ink width to center glyph
+ if (!nTextWidth)
+ {
+ aPointTxTy.X() = x - aBoundRect.Left() + (nX - aBoundRect.GetWidth() + 1) / 2;
+ }
+
+ aBoundRect += aPointTxTy;
+
+ // shift back vertically if needed
+ int nYLDelta = aBoundRect.Top() - y;
+ int nYHDelta = (y + nY) - aBoundRect.Bottom();
+ if (nYLDelta <= 0)
+ aPointTxTy.Y() -= nYLDelta - 1;
+ else if (nYHDelta <= 0)
+ aPointTxTy.Y() += nYHDelta - 1;
+
+ // shift back horizontally if needed
+ int nXLDelta = aBoundRect.Left() - x;
+ int nXHDelta = (x + nX) - aBoundRect.Right();
+ if (nXLDelta <= 0)
+ aPointTxTy.X() -= nXLDelta - 1;
+ else if (nXHDelta <= 0)
+ aPointTxTy.X() += nXHDelta - 1;
+ }
+
+ Color aTextCol = rRenderContext.GetTextColor();
+ if (i != nSelectedIndex)
+ {
+ rRenderContext.SetTextColor(aWindowTextColor);
+ rRenderContext.DrawText(aPointTxTy, aCharStr);
+ }
+ else
+ {
+ Color aLineCol = rRenderContext.GetLineColor();
+ Color aFillCol = rRenderContext.GetFillColor();
+ rRenderContext.SetLineColor();
+ Point aPointUL(x + 1, y + 1);
+ if (HasFocus())
+ {
+ rRenderContext.SetFillColor(aHighlightColor);
+ rRenderContext.DrawRect(getGridRectangle(aPointUL, aOutputSize));
+
+ rRenderContext.SetTextColor(aHighlightTextColor);
+ rRenderContext.DrawText(aPointTxTy, aCharStr);
+ }
+ else
+ {
+ rRenderContext.SetFillColor(aFaceColor);
+ rRenderContext.DrawRect(getGridRectangle(aPointUL, aOutputSize));
+
+ rRenderContext.SetLineColor(aLightColor);
+ rRenderContext.DrawLine(aPointUL, Point(x + nX - 1, y + 1));
+ rRenderContext.DrawLine(aPointUL, Point(x + 1, y + nY - 1));
+
+ rRenderContext.SetLineColor(aShadowColor);
+ rRenderContext.DrawLine(Point(x + 1, y + nY - 1), Point(x + nX - 1, y + nY - 1));
+ rRenderContext.DrawLine(Point(x + nX - 1, y + nY - 1), Point(x + nX - 1, y + 1));
+
+ rRenderContext.DrawText(aPointTxTy, aCharStr);
+ }
+ rRenderContext.SetLineColor(aLineCol);
+ rRenderContext.SetFillColor(aFillCol);
+ }
+ rRenderContext.SetTextColor(aTextCol);
+ }
+}
+
+sal_UCS4 SvxSearchCharSet::GetSelectCharacter() const
+{
+ if( nSelectedIndex >= 0 )
+ {
+ std::unordered_map<sal_Int32,sal_UCS4>::const_iterator got = m_aItemList.find (nSelectedIndex);
+
+ if(got == m_aItemList.end())
+ return 1;
+ else
+ return got->second;
+ }
+ return 1;
+}
+
+void SvxSearchCharSet::RecalculateFont(vcl::RenderContext& rRenderContext)
+{
+ if (!mbRecalculateFont)
+ return;
+
+ Size aSize(GetOutputSizePixel());
+ long nSBWidth = aVscrollSB->GetOptimalSize().Width();
+ aSize.Width() -= nSBWidth;
+
+ vcl::Font aFont = rRenderContext.GetFont();
+ aFont.SetWeight(WEIGHT_LIGHT);
+ aFont.SetAlignment(ALIGN_TOP);
+ int nFontHeight = (aSize.Height() - 5) * 2 / (3 * ROW_COUNT);
+ maFontSize = rRenderContext.PixelToLogic(Size(0, nFontHeight));
+ aFont.SetFontSize(maFontSize);
+ aFont.SetTransparent(true);
+ rRenderContext.SetFont(aFont);
+ rRenderContext.GetFontCharMap(mxFontCharMap);
+
+ nX = aSize.Width() / COLUMN_COUNT;
+ nY = aSize.Height() / ROW_COUNT;
+
+ //scrollbar settings -- error
+ aVscrollSB->setPosSizePixel(aSize.Width(), 0, nSBWidth, aSize.Height());
+ aVscrollSB->SetRangeMin(0);
+ int nLastRow = (nCount - 1 + COLUMN_COUNT) / COLUMN_COUNT;
+ aVscrollSB->SetRangeMax(nLastRow);
+ aVscrollSB->SetPageSize(ROW_COUNT - 1);
+ aVscrollSB->SetVisibleSize(ROW_COUNT);
+
+ aVscrollSB->Show();
+
+ // rearrange CharSet element in sync with nX- and nY-multiples
+ Size aDrawSize(nX * COLUMN_COUNT, nY * ROW_COUNT);
+ m_nXGap = (aSize.Width() - aDrawSize.Width()) / 2;
+ m_nYGap = (aSize.Height() - aDrawSize.Height()) / 2;
+
+ mbRecalculateFont = false;
+}
+
+void SvxSearchCharSet::SelectIndex( int nNewIndex, bool bFocus )
+{
+ if( !aVscrollSB )
+ return;
+
+ if ( !mxFontCharMap.is() )
+ RecalculateFont( *this );
+
+ if( nNewIndex < 0 )
+ {
+ aVscrollSB->SetThumbPos( 0 );
+ nSelectedIndex = bFocus ? 0 : -1;
+ Invalidate();
+ }
+ else if( nNewIndex < FirstInView() )
+ {
+ // need to scroll up to see selected item
+ int nOldPos = aVscrollSB->GetThumbPos();
+ int nDelta = (FirstInView() - nNewIndex + COLUMN_COUNT-1) / COLUMN_COUNT;
+ aVscrollSB->SetThumbPos( nOldPos - nDelta );
+ nSelectedIndex = nNewIndex;
+ Invalidate();
+ }
+ else if( nNewIndex > LastInView() )
+ {
+ // need to scroll down to see selected item
+ int nOldPos = aVscrollSB->GetThumbPos();
+ int nDelta = (nNewIndex - LastInView() + COLUMN_COUNT) / COLUMN_COUNT;
+ aVscrollSB->SetThumbPos( nOldPos + nDelta );
+ if( nNewIndex < nCount )
+ {
+ nSelectedIndex = nNewIndex;
+ Invalidate();
+ }
+ else if (nOldPos != aVscrollSB->GetThumbPos())
+ {
+ Invalidate();
+ }
+ }
+ else
+ {
+ nSelectedIndex = nNewIndex;
+ Invalidate();
+ }
+
+ if( nSelectedIndex >= 0 )
+ {
+ if( m_xAccessible.is() )
+ {
+ svx::SvxShowCharSetItem* pItem = ImplGetItem(nSelectedIndex);
+ // Don't fire the focus event.
+ if ( bFocus )
+ m_xAccessible->fireEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, Any(), makeAny(pItem->GetAccessible()) ); // this call assures that m_pItem is set
+ else
+ m_xAccessible->fireEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED_NOFOCUS, Any(), makeAny(pItem->GetAccessible()) ); // this call assures that m_pItem is set
+
+ assert(pItem->m_xItem.is() && "No accessible created!");
+ Any aOldAny, aNewAny;
+ aNewAny <<= AccessibleStateType::FOCUSED;
+ // Don't fire the focus event.
+ if ( bFocus )
+ pItem->m_xItem->fireEvent( AccessibleEventId::STATE_CHANGED, aOldAny, aNewAny );
+
+ aNewAny <<= AccessibleStateType::SELECTED;
+ pItem->m_xItem->fireEvent( AccessibleEventId::STATE_CHANGED, aOldAny, aNewAny );
+ }
+ }
+ aHighHdl.Call( this );
+}
+
+SvxSearchCharSet::~SvxSearchCharSet()
+{
+ disposeOnce();
+}
+
+void SvxSearchCharSet::dispose()
+{
+ m_aItemList.clear();
+
+ SvxShowCharSet::dispose();
+}
+
+svx::SvxShowCharSetItem* SvxSearchCharSet::ImplGetItem( int _nPos )
+{
+ ItemsMap::iterator aFind = m_aItems.find(_nPos);
+ if ( aFind == m_aItems.end() )
+ {
+ OSL_ENSURE(m_xAccessible.is(), "Who wants to create a child of my table without a parent?");
+ std::shared_ptr<svx::SvxShowCharSetItem> xItem(new svx::SvxShowCharSetItem(*this,
+ m_xAccessible->getTable(), sal::static_int_cast< sal_uInt16 >(_nPos)));
+ aFind = m_aItems.insert(ItemsMap::value_type(_nPos, xItem)).first;
+ OUStringBuffer buf;
+ std::unordered_map<sal_Int32,sal_UCS4>::const_iterator got = m_aItemList.find (_nPos);
+ buf.appendUtf32( got->second );
+ aFind->second->maText = buf.makeStringAndClear();
+ Point pix = MapIndexToPixel( _nPos );
+ aFind->second->maRect = tools::Rectangle( Point( pix.X() + 1, pix.Y() + 1 ), Size(nX-1,nY-1) );
+ }
+
+ return aFind->second.get();
+}
+
+sal_Int32 SvxSearchCharSet::getMaxCharCount() const
+{
+ return nCount;
+}
+
+void SvxSearchCharSet::ClearPreviousData()
+{
+ m_aItemList.clear();
+ nCount = 0;
+ Invalidate();
+}
+
+void SvxSearchCharSet::AppendCharToList(sal_UCS4 sChar)
+{
+ m_aItemList.insert(std::make_pair(nCount++, sChar));
+}
+
+void SvxSearchCharSet::AppendCharList(std::vector<sal_UCS4> sList)
+{
+ std::vector<sal_UCS4>::iterator list_iter = sList.begin();
+ while(list_iter != sList.end())
+ {
+ AppendCharToList(*list_iter);
+ list_iter++;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */