106ea87205
...which was introduced with3ead3ad52f
"Gradually typed Link" to distinguish the new, typed versions from the old, untyped ones, but is no longer necessary since382eb1a23c
"remove untyped Link<>" removed the old versions. Change-Id: I494025df486a16a45861fcd8192dfe0275b1103c
1830 lines
61 KiB
C++
1830 lines
61 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 "hangulhanjadlg.hxx"
|
|
#include <dialmgr.hxx>
|
|
|
|
#include <cuires.hrc>
|
|
#include "helpid.hrc"
|
|
|
|
#include <algorithm>
|
|
#include <vcl/controllayout.hxx>
|
|
#include <vcl/msgbox.hxx>
|
|
#include <vcl/builderfactory.hxx>
|
|
#include <vcl/decoview.hxx>
|
|
#include <unotools/lingucfg.hxx>
|
|
#include <unotools/linguprops.hxx>
|
|
#include <com/sun/star/linguistic2/ConversionDictionaryType.hpp>
|
|
#include <com/sun/star/linguistic2/ConversionDirection.hpp>
|
|
#include <com/sun/star/linguistic2/ConversionDictionaryList.hpp>
|
|
#include <com/sun/star/i18n/TextConversionOption.hpp>
|
|
#include <com/sun/star/util/XFlushable.hpp>
|
|
|
|
#include <comphelper/processfactory.hxx>
|
|
#include <comphelper/string.hxx>
|
|
#include "svtools/treelistentry.hxx"
|
|
|
|
#define HHC editeng::HangulHanjaConversion
|
|
#define LINE_CNT static_cast< sal_uInt16 >(2)
|
|
#define MAXNUM_SUGGESTIONS 50
|
|
|
|
|
|
namespace svx
|
|
{
|
|
|
|
using namespace ::com::sun::star;
|
|
using namespace css::uno;
|
|
using namespace css::linguistic2;
|
|
using namespace css::lang;
|
|
using namespace css::container;
|
|
|
|
|
|
namespace
|
|
{
|
|
class FontSwitch
|
|
{
|
|
private:
|
|
OutputDevice& m_rDev;
|
|
|
|
public:
|
|
inline FontSwitch( OutputDevice& _rDev, const vcl::Font& _rTemporaryFont )
|
|
:m_rDev( _rDev )
|
|
{
|
|
m_rDev.Push( PushFlags::FONT );
|
|
m_rDev.SetFont( _rTemporaryFont );
|
|
}
|
|
inline ~FontSwitch( )
|
|
{
|
|
m_rDev.Pop( );
|
|
}
|
|
};
|
|
}
|
|
|
|
/** a class which allows to draw two texts in a pseudo-ruby way (which basically
|
|
means one text above or below the other, and a little bit smaller)
|
|
*/
|
|
class PseudoRubyText
|
|
{
|
|
public:
|
|
enum RubyPosition
|
|
{
|
|
eAbove, eBelow
|
|
};
|
|
|
|
protected:
|
|
OUString m_sPrimaryText;
|
|
OUString m_sSecondaryText;
|
|
RubyPosition m_ePosition;
|
|
|
|
public:
|
|
PseudoRubyText();
|
|
void init( const OUString& rPrimaryText, const OUString& rSecondaryText, const RubyPosition& rPosition );
|
|
const OUString& getPrimaryText() const { return m_sPrimaryText; }
|
|
const OUString& getSecondaryText() const { return m_sSecondaryText; }
|
|
|
|
public:
|
|
void Paint( OutputDevice& _rDevice, const Rectangle& _rRect, DrawTextFlags _nTextStyle,
|
|
Rectangle* _pPrimaryLocation, Rectangle* _pSecondaryLocation );
|
|
};
|
|
|
|
PseudoRubyText::PseudoRubyText()
|
|
: m_ePosition(eAbove)
|
|
{
|
|
}
|
|
|
|
void PseudoRubyText::init( const OUString& rPrimaryText, const OUString& rSecondaryText, const RubyPosition& rPosition )
|
|
{
|
|
m_sPrimaryText = rPrimaryText;
|
|
m_sSecondaryText = rSecondaryText;
|
|
m_ePosition = rPosition;
|
|
}
|
|
|
|
|
|
void PseudoRubyText::Paint(vcl::RenderContext& rRenderContext, const Rectangle& _rRect, DrawTextFlags _nTextStyle,
|
|
Rectangle* _pPrimaryLocation, Rectangle* _pSecondaryLocation )
|
|
{
|
|
Size aPlaygroundSize(_rRect.GetSize());
|
|
|
|
// the font for the secondary text:
|
|
vcl::Font aSmallerFont(rRenderContext.GetFont());
|
|
// heuristic: 80% of the original size
|
|
aSmallerFont.SetFontHeight( (long)( 0.8 * aSmallerFont.GetFontHeight() ) );
|
|
|
|
// let's calculate the size of our two texts
|
|
Rectangle aPrimaryRect = rRenderContext.GetTextRect( _rRect, m_sPrimaryText, _nTextStyle );
|
|
Rectangle aSecondaryRect;
|
|
{
|
|
FontSwitch aFontRestore(rRenderContext, aSmallerFont);
|
|
aSecondaryRect = rRenderContext.GetTextRect(_rRect, m_sSecondaryText, _nTextStyle);
|
|
}
|
|
|
|
// position these rectangles properly
|
|
// x-axis:
|
|
sal_Int32 nCombinedWidth = ::std::max( aSecondaryRect.GetWidth(), aPrimaryRect.GetWidth() );
|
|
// the rectangle where both texts will reside is as high as possible, and as wide as the
|
|
// widest of both text rects
|
|
aPrimaryRect.Left() = aSecondaryRect.Left() = _rRect.Left();
|
|
aPrimaryRect.Right() = aSecondaryRect.Right() = _rRect.Left() + nCombinedWidth;
|
|
if (DrawTextFlags::Right & _nTextStyle)
|
|
{
|
|
// move the rectangles to the right
|
|
aPrimaryRect.Move( aPlaygroundSize.Width() - nCombinedWidth, 0 );
|
|
aSecondaryRect.Move( aPlaygroundSize.Width() - nCombinedWidth, 0 );
|
|
}
|
|
else if (DrawTextFlags::Center & _nTextStyle)
|
|
{
|
|
// center the rectangles
|
|
aPrimaryRect.Move( ( aPlaygroundSize.Width() - nCombinedWidth ) / 2, 0 );
|
|
aSecondaryRect.Move( ( aPlaygroundSize.Width() - nCombinedWidth ) / 2, 0 );
|
|
}
|
|
|
|
// y-axis:
|
|
sal_Int32 nCombinedHeight = aPrimaryRect.GetHeight() + aSecondaryRect.GetHeight();
|
|
// align to the top, for the moment
|
|
aPrimaryRect.Move( 0, _rRect.Top() - aPrimaryRect.Top() );
|
|
aSecondaryRect.Move( 0, aPrimaryRect.Top() + aPrimaryRect.GetHeight() - aSecondaryRect.Top() );
|
|
if (DrawTextFlags::Bottom & _nTextStyle)
|
|
{
|
|
// move the rects to the bottom
|
|
aPrimaryRect.Move( 0, aPlaygroundSize.Height() - nCombinedHeight );
|
|
aSecondaryRect.Move( 0, aPlaygroundSize.Height() - nCombinedHeight );
|
|
}
|
|
else if (DrawTextFlags::VCenter & _nTextStyle)
|
|
{
|
|
// move the rects to the bottom
|
|
aPrimaryRect.Move( 0, ( aPlaygroundSize.Height() - nCombinedHeight ) / 2 );
|
|
aSecondaryRect.Move( 0, ( aPlaygroundSize.Height() - nCombinedHeight ) / 2 );
|
|
}
|
|
|
|
// 'til here, everything we did assumes that the secondary text is painted _below_ the primary
|
|
// text. If this isn't the case, we need to correct the rectangles
|
|
if (eAbove == m_ePosition)
|
|
{
|
|
sal_Int32 nVertDistance = aSecondaryRect.Top() - aPrimaryRect.Top();
|
|
aSecondaryRect.Move( 0, -nVertDistance );
|
|
aPrimaryRect.Move( 0, nCombinedHeight - nVertDistance );
|
|
}
|
|
|
|
// now draw the texts
|
|
// as we already calculated the precise rectangles for the texts, we don't want to
|
|
// use the alignment flags given - within it's rect, every text is centered
|
|
DrawTextFlags nDrawTextStyle( _nTextStyle );
|
|
nDrawTextStyle &= ~DrawTextFlags( DrawTextFlags::Right | DrawTextFlags::Left | DrawTextFlags::Bottom | DrawTextFlags::Top );
|
|
nDrawTextStyle |= DrawTextFlags::Center | DrawTextFlags::VCenter;
|
|
|
|
rRenderContext.DrawText( aPrimaryRect, m_sPrimaryText, nDrawTextStyle );
|
|
{
|
|
FontSwitch aFontRestore(rRenderContext, aSmallerFont);
|
|
rRenderContext.DrawText( aSecondaryRect, m_sSecondaryText, nDrawTextStyle );
|
|
}
|
|
|
|
// outta here
|
|
if (_pPrimaryLocation)
|
|
*_pPrimaryLocation = aPrimaryRect;
|
|
if (_pSecondaryLocation)
|
|
*_pSecondaryLocation = aSecondaryRect;
|
|
}
|
|
|
|
class RubyRadioButton : public RadioButton
|
|
{
|
|
|
|
public:
|
|
RubyRadioButton( vcl::Window* _pParent, WinBits nBits );
|
|
void init( const OUString& rPrimaryText, const OUString& rSecondaryText, const PseudoRubyText::RubyPosition& rPosition );
|
|
virtual Size GetOptimalSize() const override;
|
|
|
|
protected:
|
|
virtual void Paint( vcl::RenderContext& /*rRenderContext*/, const Rectangle& _rRect ) override;
|
|
|
|
private:
|
|
PseudoRubyText m_aRubyText;
|
|
};
|
|
|
|
RubyRadioButton::RubyRadioButton( vcl::Window* _pParent, WinBits nBits )
|
|
:RadioButton( _pParent, nBits )
|
|
{
|
|
}
|
|
|
|
void RubyRadioButton::init( const OUString& rPrimaryText, const OUString& rSecondaryText, const PseudoRubyText::RubyPosition& rPosition )
|
|
{
|
|
m_aRubyText.init( rPrimaryText, rSecondaryText, rPosition );
|
|
}
|
|
|
|
|
|
void RubyRadioButton::Paint(vcl::RenderContext& rRenderContext, const Rectangle&)
|
|
{
|
|
HideFocus();
|
|
|
|
// calculate the size of the radio image - we're to paint our text _after_ this image
|
|
DBG_ASSERT( !GetModeRadioImage(), "RubyRadioButton::Paint: images not supported!" );
|
|
Size aImageSize = GetRadioImage(rRenderContext.GetSettings(), DrawButtonFlags::NONE).GetSizePixel();
|
|
aImageSize.Width() = CalcZoom( aImageSize.Width() ) + 2; // + 2 because otherwise the radiobuttons
|
|
aImageSize.Height() = CalcZoom( aImageSize.Height() ) + 2; // appear a bit cut from right and top.
|
|
|
|
Rectangle aOverallRect( Point( 0, 0 ), GetOutputSizePixel() );
|
|
aOverallRect.Left() += aImageSize.Width() + 4; // 4 is the separator between the image and the text
|
|
// inflate the rect a little bit (because the VCL radio button does the same)
|
|
Rectangle aTextRect( aOverallRect );
|
|
++aTextRect.Left(); --aTextRect.Right();
|
|
++aTextRect.Top(); --aTextRect.Bottom();
|
|
|
|
// calculate the text flags for the painting
|
|
DrawTextFlags nTextStyle = DrawTextFlags::Mnemonic;
|
|
WinBits nStyle = GetStyle( );
|
|
|
|
// the horizontal alignment
|
|
if ( nStyle & WB_RIGHT )
|
|
nTextStyle |= DrawTextFlags::Right;
|
|
else if ( nStyle & WB_CENTER )
|
|
nTextStyle |= DrawTextFlags::Center;
|
|
else
|
|
nTextStyle |= DrawTextFlags::Left;
|
|
// the vertical alignment
|
|
if ( nStyle & WB_BOTTOM )
|
|
nTextStyle |= DrawTextFlags::Bottom;
|
|
else if ( nStyle & WB_VCENTER )
|
|
nTextStyle |= DrawTextFlags::VCenter;
|
|
else
|
|
nTextStyle |= DrawTextFlags::Top;
|
|
// mnemonics
|
|
if ( 0 == ( nStyle & WB_NOLABEL ) )
|
|
nTextStyle |= DrawTextFlags::Mnemonic;
|
|
|
|
// paint the ruby text
|
|
Rectangle aPrimaryTextLocation;
|
|
Rectangle aSecondaryTextLocation;
|
|
|
|
m_aRubyText.Paint(rRenderContext, aTextRect, nTextStyle, &aPrimaryTextLocation, &aSecondaryTextLocation);
|
|
|
|
// the focus rectangle is to be painted around both texts
|
|
Rectangle aCombinedRect(aPrimaryTextLocation);
|
|
aCombinedRect.Union(aSecondaryTextLocation);
|
|
SetFocusRect(aCombinedRect);
|
|
|
|
// let the base class paint the radio button
|
|
// for this, give it the proper location to paint the image (vertically centered, relative to our text)
|
|
Rectangle aImageLocation( Point( 0, 0 ), aImageSize );
|
|
sal_Int32 nTextHeight = aSecondaryTextLocation.Bottom() - aPrimaryTextLocation.Top();
|
|
aImageLocation.Top() = aPrimaryTextLocation.Top() + ( nTextHeight - aImageSize.Height() ) / 2;
|
|
aImageLocation.Bottom() = aImageLocation.Top() + aImageSize.Height();
|
|
SetStateRect( aImageLocation );
|
|
DrawRadioButtonState(rRenderContext);
|
|
|
|
// mouse clicks should be recognized in a rect which is one pixel larger in each direction, plus
|
|
// includes the image
|
|
aCombinedRect.Left() = aImageLocation.Left();
|
|
++aCombinedRect.Right();
|
|
--aCombinedRect.Top();
|
|
++aCombinedRect.Bottom();
|
|
|
|
SetMouseRect(aCombinedRect);
|
|
|
|
// paint the focus rect, if necessary
|
|
if (HasFocus())
|
|
ShowFocus(aTextRect);
|
|
}
|
|
|
|
Size RubyRadioButton::GetOptimalSize() const
|
|
{
|
|
vcl::Font aSmallerFont( GetFont() );
|
|
aSmallerFont.SetFontHeight( static_cast<long>( 0.8 * aSmallerFont.GetFontHeight() ) );
|
|
Rectangle rect( Point(), Size( SAL_MAX_INT32, SAL_MAX_INT32 ) );
|
|
|
|
Size aPrimarySize = GetTextRect( rect, m_aRubyText.getPrimaryText() ).GetSize();
|
|
Size aSecondarySize;
|
|
{
|
|
FontSwitch aFontRestore( const_cast<RubyRadioButton&>(*this), aSmallerFont );
|
|
aSecondarySize = GetTextRect( rect, m_aRubyText.getSecondaryText() ).GetSize();
|
|
}
|
|
|
|
Size minimumSize = CalcMinimumSize();
|
|
minimumSize.Height() = aPrimarySize.Height() + aSecondarySize.Height() + 5;
|
|
minimumSize.Width() = aPrimarySize.Width() + aSecondarySize.Width() + 5;
|
|
return minimumSize;
|
|
}
|
|
|
|
VCL_BUILDER_FACTORY_ARGS(RubyRadioButton, WB_LEFT|WB_VCENTER)
|
|
|
|
SuggestionSet::SuggestionSet( vcl::Window* pParent )
|
|
: ValueSet( pParent, pParent->GetStyle() | WB_BORDER )
|
|
|
|
{
|
|
}
|
|
|
|
SuggestionSet::~SuggestionSet()
|
|
{
|
|
disposeOnce();
|
|
}
|
|
|
|
void SuggestionSet::dispose()
|
|
{
|
|
ClearSet();
|
|
ValueSet::dispose();
|
|
}
|
|
|
|
void SuggestionSet::UserDraw( const UserDrawEvent& rUDEvt )
|
|
{
|
|
vcl::RenderContext* pDev = rUDEvt.GetRenderContext();
|
|
Rectangle aRect = rUDEvt.GetRect();
|
|
sal_uInt16 nItemId = rUDEvt.GetItemId();
|
|
|
|
OUString sText = *static_cast< OUString* >( GetItemData( nItemId ) );
|
|
pDev->DrawText( aRect, sText, DrawTextFlags::Center | DrawTextFlags::VCenter );
|
|
}
|
|
|
|
void SuggestionSet::ClearSet()
|
|
{
|
|
sal_uInt16 i, nCount = GetItemCount();
|
|
for ( i = 0; i < nCount; ++i )
|
|
delete static_cast< OUString* >( GetItemData(i) );
|
|
Clear();
|
|
}
|
|
|
|
SuggestionDisplay::SuggestionDisplay( vcl::Window* pParent, WinBits nBits )
|
|
: Control( pParent, nBits )
|
|
, m_bDisplayListBox( true )
|
|
, m_aValueSet( VclPtr<SuggestionSet>::Create(this) )
|
|
, m_aListBox( VclPtr<ListBox>::Create(this,GetStyle() | WB_BORDER) )
|
|
, m_bInSelectionUpdate( false )
|
|
{
|
|
m_aValueSet->SetSelectHdl( LINK( this, SuggestionDisplay, SelectSuggestionValueSetHdl ) );
|
|
m_aListBox->SetSelectHdl( LINK( this, SuggestionDisplay, SelectSuggestionListBoxHdl ) );
|
|
|
|
m_aValueSet->SetLineCount( LINE_CNT );
|
|
m_aValueSet->SetStyle( m_aValueSet->GetStyle() | WB_ITEMBORDER | WB_FLATVALUESET | WB_VSCROLL );
|
|
m_aValueSet->SetBorderStyle( WindowBorderStyle::MONO );
|
|
OUString aOneCharacter("AU");
|
|
long nItemWidth = 2*GetTextWidth( aOneCharacter );
|
|
m_aValueSet->SetItemWidth( nItemWidth );
|
|
|
|
Size aSize( approximate_char_width() * 48, GetTextHeight() * 5 );
|
|
m_aValueSet->SetSizePixel( aSize );
|
|
m_aListBox->SetSizePixel( aSize );
|
|
|
|
implUpdateDisplay();
|
|
}
|
|
|
|
SuggestionDisplay::~SuggestionDisplay()
|
|
{
|
|
disposeOnce();
|
|
}
|
|
|
|
void SuggestionDisplay::dispose()
|
|
{
|
|
m_aValueSet.disposeAndClear();
|
|
m_aListBox.disposeAndClear();
|
|
Control::dispose();
|
|
}
|
|
|
|
void SuggestionDisplay::implUpdateDisplay()
|
|
{
|
|
bool bShowBox = IsVisible() && m_bDisplayListBox;
|
|
bool bShowSet = IsVisible() && !m_bDisplayListBox;
|
|
|
|
m_aListBox->Show( bShowBox );
|
|
m_aValueSet->Show( bShowSet );
|
|
}
|
|
|
|
void SuggestionDisplay::StateChanged( StateChangedType nStateChange )
|
|
{
|
|
if( StateChangedType::Visible == nStateChange )
|
|
implUpdateDisplay();
|
|
}
|
|
|
|
bool SuggestionDisplay::hasCurrentControl()
|
|
{
|
|
return m_bDisplayListBox || m_aValueSet;
|
|
}
|
|
|
|
Control& SuggestionDisplay::implGetCurrentControl()
|
|
{
|
|
if( m_bDisplayListBox )
|
|
return *m_aListBox.get();
|
|
return *m_aValueSet.get();
|
|
}
|
|
|
|
void SuggestionDisplay::KeyInput( const KeyEvent& rKEvt )
|
|
{
|
|
implGetCurrentControl().KeyInput( rKEvt );
|
|
}
|
|
void SuggestionDisplay::KeyUp( const KeyEvent& rKEvt )
|
|
{
|
|
implGetCurrentControl().KeyUp( rKEvt );
|
|
}
|
|
void SuggestionDisplay::Activate()
|
|
{
|
|
implGetCurrentControl().Activate();
|
|
}
|
|
void SuggestionDisplay::Deactivate()
|
|
{
|
|
implGetCurrentControl().Deactivate();
|
|
}
|
|
void SuggestionDisplay::GetFocus()
|
|
{
|
|
if (hasCurrentControl())
|
|
implGetCurrentControl().GetFocus();
|
|
else
|
|
Control::LoseFocus();
|
|
}
|
|
void SuggestionDisplay::LoseFocus()
|
|
{
|
|
if (hasCurrentControl())
|
|
implGetCurrentControl().LoseFocus();
|
|
else
|
|
Control::LoseFocus();
|
|
}
|
|
void SuggestionDisplay::Command( const CommandEvent& rCEvt )
|
|
{
|
|
implGetCurrentControl().Command( rCEvt );
|
|
}
|
|
|
|
void SuggestionDisplay::DisplayListBox( bool bDisplayListBox )
|
|
{
|
|
if( m_bDisplayListBox != bDisplayListBox )
|
|
{
|
|
Control& rOldControl = implGetCurrentControl();
|
|
bool bHasFocus = rOldControl.HasFocus();
|
|
|
|
m_bDisplayListBox = bDisplayListBox;
|
|
|
|
if( bHasFocus )
|
|
{
|
|
Control& rNewControl = implGetCurrentControl();
|
|
rNewControl.GrabFocus();
|
|
}
|
|
|
|
implUpdateDisplay();
|
|
}
|
|
}
|
|
|
|
IMPL_LINK( SuggestionDisplay, SelectSuggestionValueSetHdl, ValueSet*, pControl, void )
|
|
{
|
|
SelectSuggestionHdl(pControl);
|
|
}
|
|
IMPL_LINK( SuggestionDisplay, SelectSuggestionListBoxHdl, ListBox&, rControl, void )
|
|
{
|
|
SelectSuggestionHdl(&rControl);
|
|
}
|
|
void SuggestionDisplay::SelectSuggestionHdl( Control* pControl )
|
|
{
|
|
if( m_bInSelectionUpdate )
|
|
return;
|
|
|
|
m_bInSelectionUpdate = true;
|
|
if( pControl == m_aListBox.get() )
|
|
{
|
|
sal_uInt16 nPos = m_aListBox->GetSelectEntryPos();
|
|
m_aValueSet->SelectItem( nPos+1 ); //itemid == pos+1 (id 0 has special meaning)
|
|
}
|
|
else
|
|
{
|
|
sal_uInt16 nPos = m_aValueSet->GetSelectItemId()-1; //itemid == pos+1 (id 0 has special meaning)
|
|
m_aListBox->SelectEntryPos( nPos );
|
|
}
|
|
m_bInSelectionUpdate = false;
|
|
m_aSelectLink.Call( *this );
|
|
}
|
|
|
|
void SuggestionDisplay::SetSelectHdl( const Link<SuggestionDisplay&,void>& rLink )
|
|
{
|
|
m_aSelectLink = rLink;
|
|
}
|
|
void SuggestionDisplay::Clear()
|
|
{
|
|
m_aListBox->Clear();
|
|
m_aValueSet->Clear();
|
|
}
|
|
void SuggestionDisplay::InsertEntry( const OUString& rStr )
|
|
{
|
|
sal_uInt16 nItemId = m_aListBox->InsertEntry( rStr ) + 1; //itemid == pos+1 (id 0 has special meaning)
|
|
m_aValueSet->InsertItem( nItemId );
|
|
OUString* pItemData = new OUString( rStr );
|
|
m_aValueSet->SetItemData( nItemId, pItemData );
|
|
}
|
|
void SuggestionDisplay::SelectEntryPos( sal_uInt16 nPos )
|
|
{
|
|
m_aListBox->SelectEntryPos( nPos );
|
|
m_aValueSet->SelectItem( nPos+1 ); //itemid == pos+1 (id 0 has special meaning)
|
|
}
|
|
sal_uInt16 SuggestionDisplay::GetEntryCount() const
|
|
{
|
|
return m_aListBox->GetEntryCount();
|
|
}
|
|
OUString SuggestionDisplay::GetEntry( sal_uInt16 nPos ) const
|
|
{
|
|
return m_aListBox->GetEntry( nPos );
|
|
}
|
|
OUString SuggestionDisplay::GetSelectEntry() const
|
|
{
|
|
return m_aListBox->GetSelectEntry();
|
|
}
|
|
void SuggestionDisplay::SetHelpIds()
|
|
{
|
|
this->SetHelpId( HID_HANGULDLG_SUGGESTIONS );
|
|
m_aValueSet->SetHelpId( HID_HANGULDLG_SUGGESTIONS_GRID );
|
|
m_aListBox->SetHelpId( HID_HANGULDLG_SUGGESTIONS_LIST );
|
|
}
|
|
|
|
VCL_BUILDER_FACTORY_ARGS( SuggestionDisplay, WB_ITEMBORDER | WB_FLATVALUESET | WB_VSCROLL );
|
|
|
|
HangulHanjaConversionDialog::HangulHanjaConversionDialog( vcl::Window* _pParent, HHC::ConversionDirection _ePrimaryDirection )
|
|
:ModalDialog( _pParent, "HangulHanjaConversionDialog", "cui/ui/hangulhanjaconversiondialog.ui" )
|
|
,m_pIgnoreNonPrimary( nullptr )
|
|
,m_bDocumentMode( true )
|
|
{
|
|
get( m_pFind, "find" );
|
|
get( m_pIgnore, "ignore" );
|
|
get( m_pSuggestions, "suggestions" );
|
|
get( m_pSimpleConversion, "simpleconversion" );
|
|
get( m_pHangulBracketed, "hangulbracket" );
|
|
get( m_pHanjaBracketed, "hanjabracket" );
|
|
get( m_pHangulOnly, "hangulonly" );
|
|
get( m_pHanjaOnly, "hanjaonly" );
|
|
get( m_pReplaceByChar, "replacebychar" );
|
|
get( m_pOptions, "options" );
|
|
get( m_pIgnore, "ignore" );
|
|
get( m_pIgnoreAll, "ignoreall" );
|
|
get( m_pReplace, "replace" );
|
|
get( m_pReplaceAll, "replaceall" );
|
|
get( m_pWordInput, "wordinput" );
|
|
get( m_pOriginalWord, "originalword" );
|
|
get( m_pHanjaAbove, "hanja_above" );
|
|
get( m_pHanjaBelow, "hanja_below" );
|
|
get( m_pHangulAbove, "hangul_above" );
|
|
get( m_pHangulBelow, "hangul_below" );
|
|
|
|
m_pSuggestions->set_height_request( m_pSuggestions->GetTextHeight() * 5 );
|
|
m_pSuggestions->set_width_request( m_pSuggestions->approximate_char_width() * 48 );
|
|
|
|
const OUString sHangul(CUI_RESSTR(RID_SVXSTR_HANGUL));
|
|
const OUString sHanja(CUI_RESSTR(RID_SVXSTR_HANJA));
|
|
m_pHanjaAbove->init( sHangul, sHanja, PseudoRubyText::eAbove );
|
|
m_pHanjaBelow->init( sHangul, sHanja, PseudoRubyText::eBelow );
|
|
m_pHangulAbove->init( sHanja, sHangul, PseudoRubyText::eAbove );
|
|
m_pHangulBelow->init( sHanja, sHangul, PseudoRubyText::eBelow );
|
|
|
|
m_pWordInput->SetModifyHdl( LINK( this, HangulHanjaConversionDialog, OnSuggestionModified ) );
|
|
m_pSuggestions->SetSelectHdl( LINK( this, HangulHanjaConversionDialog, OnSuggestionSelected ) );
|
|
m_pReplaceByChar->SetClickHdl( LINK( this, HangulHanjaConversionDialog, ClickByCharacterHdl ) );
|
|
m_pHangulOnly->SetClickHdl( LINK( this, HangulHanjaConversionDialog, OnConversionDirectionClicked ) );
|
|
m_pHanjaOnly->SetClickHdl( LINK( this, HangulHanjaConversionDialog, OnConversionDirectionClicked ) );
|
|
m_pOptions->SetClickHdl( LINK( this, HangulHanjaConversionDialog, OnOption ) );
|
|
|
|
if ( editeng::HangulHanjaConversion::eHangulToHanja == _ePrimaryDirection )
|
|
{
|
|
m_pIgnoreNonPrimary = m_pHangulOnly;
|
|
}
|
|
else
|
|
{
|
|
m_pIgnoreNonPrimary = m_pHanjaOnly;
|
|
}
|
|
|
|
// initial focus
|
|
FocusSuggestion( );
|
|
|
|
// initial control values
|
|
m_pSimpleConversion->Check();
|
|
|
|
m_pSuggestions->SetHelpIds();
|
|
}
|
|
|
|
HangulHanjaConversionDialog::~HangulHanjaConversionDialog()
|
|
{
|
|
disposeOnce();
|
|
}
|
|
|
|
void HangulHanjaConversionDialog::dispose()
|
|
{
|
|
m_pFind.clear();
|
|
m_pIgnore.clear();
|
|
m_pIgnoreAll.clear();
|
|
m_pReplace.clear();
|
|
m_pReplaceAll.clear();
|
|
m_pOptions.clear();
|
|
m_pSuggestions.clear();
|
|
m_pSimpleConversion.clear();
|
|
m_pHangulBracketed.clear();
|
|
m_pHanjaBracketed.clear();
|
|
m_pWordInput.clear();
|
|
m_pOriginalWord.clear();
|
|
m_pHanjaAbove.clear();
|
|
m_pHanjaBelow.clear();
|
|
m_pHangulAbove.clear();
|
|
m_pHangulBelow.clear();
|
|
m_pHangulOnly.clear();
|
|
m_pHanjaOnly.clear();
|
|
m_pReplaceByChar.clear();
|
|
m_pIgnoreNonPrimary.clear();
|
|
ModalDialog::dispose();
|
|
}
|
|
|
|
void HangulHanjaConversionDialog::FillSuggestions( const css::uno::Sequence< OUString >& _rSuggestions )
|
|
{
|
|
m_pSuggestions->Clear();
|
|
const OUString* pSuggestions = _rSuggestions.getConstArray();
|
|
const OUString* pSuggestionsEnd = _rSuggestions.getConstArray() + _rSuggestions.getLength();
|
|
while ( pSuggestions != pSuggestionsEnd )
|
|
m_pSuggestions->InsertEntry( *pSuggestions++ );
|
|
|
|
// select the first suggestion, and fill in the suggestion edit field
|
|
OUString sFirstSuggestion;
|
|
if ( m_pSuggestions->GetEntryCount() )
|
|
{
|
|
sFirstSuggestion = m_pSuggestions->GetEntry( 0 );
|
|
m_pSuggestions->SelectEntryPos( 0 );
|
|
}
|
|
m_pWordInput->SetText( sFirstSuggestion );
|
|
m_pWordInput->SaveValue();
|
|
OnSuggestionModified( *m_pWordInput );
|
|
}
|
|
|
|
|
|
void HangulHanjaConversionDialog::SetOptionsChangedHdl( const Link<LinkParamNone*,void>& _rHdl )
|
|
{
|
|
m_aOptionsChangedLink = _rHdl;
|
|
}
|
|
|
|
|
|
void HangulHanjaConversionDialog::SetIgnoreHdl( const Link<Button*,void>& _rHdl )
|
|
{
|
|
m_pIgnore->SetClickHdl( _rHdl );
|
|
}
|
|
|
|
|
|
void HangulHanjaConversionDialog::SetIgnoreAllHdl( const Link<Button*,void>& _rHdl )
|
|
{
|
|
m_pIgnoreAll->SetClickHdl( _rHdl );
|
|
}
|
|
|
|
|
|
void HangulHanjaConversionDialog::SetChangeHdl( const Link<Button*,void>& _rHdl )
|
|
{
|
|
m_pReplace->SetClickHdl( _rHdl );
|
|
}
|
|
|
|
|
|
void HangulHanjaConversionDialog::SetChangeAllHdl( const Link<Button*,void>& _rHdl )
|
|
{
|
|
m_pReplaceAll->SetClickHdl( _rHdl );
|
|
}
|
|
|
|
|
|
void HangulHanjaConversionDialog::SetFindHdl( const Link<Button*,void>& _rHdl )
|
|
{
|
|
m_pFind->SetClickHdl( _rHdl );
|
|
}
|
|
|
|
|
|
void HangulHanjaConversionDialog::SetConversionFormatChangedHdl( const Link<Button*,void>& _rHdl )
|
|
{
|
|
m_pSimpleConversion->SetClickHdl( _rHdl );
|
|
m_pHangulBracketed->SetClickHdl( _rHdl );
|
|
m_pHanjaBracketed->SetClickHdl( _rHdl );
|
|
m_pHanjaAbove->SetClickHdl( _rHdl );
|
|
m_pHanjaBelow->SetClickHdl( _rHdl );
|
|
m_pHangulAbove->SetClickHdl( _rHdl );
|
|
m_pHangulBelow->SetClickHdl( _rHdl );
|
|
}
|
|
|
|
|
|
void HangulHanjaConversionDialog::SetClickByCharacterHdl( const Link<CheckBox*,void>& _rHdl )
|
|
{
|
|
m_aClickByCharacterLink = _rHdl;
|
|
}
|
|
|
|
|
|
IMPL_LINK_NOARG( HangulHanjaConversionDialog, OnSuggestionSelected, SuggestionDisplay&, void )
|
|
{
|
|
m_pWordInput->SetText( m_pSuggestions->GetSelectEntry() );
|
|
OnSuggestionModified( *m_pWordInput );
|
|
}
|
|
|
|
|
|
IMPL_LINK_NOARG( HangulHanjaConversionDialog, OnSuggestionModified, Edit&, void )
|
|
{
|
|
m_pFind->Enable( m_pWordInput->IsValueChangedFromSaved() );
|
|
|
|
bool bSameLen = m_pWordInput->GetText().getLength() == m_pOriginalWord->GetText().getLength();
|
|
m_pReplace->Enable( m_bDocumentMode && bSameLen );
|
|
m_pReplaceAll->Enable( m_bDocumentMode && bSameLen );
|
|
}
|
|
|
|
|
|
IMPL_LINK( HangulHanjaConversionDialog, ClickByCharacterHdl, Button*, pBox, void )
|
|
{
|
|
m_aClickByCharacterLink.Call( static_cast<CheckBox*>(pBox) );
|
|
|
|
bool bByCharacter = static_cast<CheckBox*>(pBox)->IsChecked();
|
|
m_pSuggestions->DisplayListBox( !bByCharacter );
|
|
}
|
|
|
|
|
|
IMPL_LINK( HangulHanjaConversionDialog, OnConversionDirectionClicked, Button *, pBox, void )
|
|
{
|
|
CheckBox *pOtherBox = nullptr;
|
|
if ( pBox == m_pHangulOnly )
|
|
pOtherBox = m_pHanjaOnly;
|
|
else if ( pBox == m_pHanjaOnly )
|
|
pOtherBox = m_pHangulOnly;
|
|
if ( pBox && pOtherBox )
|
|
{
|
|
bool bBoxChecked = static_cast<CheckBox*>(pBox)->IsChecked();
|
|
if ( bBoxChecked )
|
|
pOtherBox->Check( false );
|
|
pOtherBox->Enable( !bBoxChecked );
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG( HangulHanjaConversionDialog, OnOption, Button*, void )
|
|
{
|
|
ScopedVclPtrInstance< HangulHanjaOptionsDialog > aOptDlg(this);
|
|
aOptDlg->Execute();
|
|
m_aOptionsChangedLink.Call( nullptr );
|
|
}
|
|
|
|
|
|
OUString HangulHanjaConversionDialog::GetCurrentString( ) const
|
|
{
|
|
return m_pOriginalWord->GetText( );
|
|
}
|
|
|
|
|
|
void HangulHanjaConversionDialog::FocusSuggestion( )
|
|
{
|
|
m_pWordInput->GrabFocus();
|
|
}
|
|
|
|
|
|
namespace
|
|
{
|
|
void lcl_modifyWindowStyle( vcl::Window* _pWin, WinBits _nSet, WinBits _nReset )
|
|
{
|
|
DBG_ASSERT( 0 == ( _nSet & _nReset ), "lcl_modifyWindowStyle: set _and_ reset the same bit?" );
|
|
if ( _pWin )
|
|
_pWin->SetStyle( ( _pWin->GetStyle() | _nSet ) & ~_nReset );
|
|
}
|
|
}
|
|
|
|
|
|
void HangulHanjaConversionDialog::SetCurrentString( const OUString& _rNewString,
|
|
const Sequence< OUString >& _rSuggestions, bool _bOriginatesFromDocument )
|
|
{
|
|
m_pOriginalWord->SetText( _rNewString );
|
|
|
|
bool bOldDocumentMode = m_bDocumentMode;
|
|
m_bDocumentMode = _bOriginatesFromDocument; // before FillSuggestions!
|
|
FillSuggestions( _rSuggestions );
|
|
|
|
m_pIgnoreAll->Enable( m_bDocumentMode );
|
|
|
|
// switch the def button depending if we're working for document text
|
|
if ( bOldDocumentMode != m_bDocumentMode )
|
|
{
|
|
vcl::Window* pOldDefButton = nullptr;
|
|
vcl::Window* pNewDefButton = nullptr;
|
|
if ( m_bDocumentMode )
|
|
{
|
|
pOldDefButton = m_pFind;
|
|
pNewDefButton = m_pReplace;
|
|
}
|
|
else
|
|
{
|
|
pOldDefButton = m_pReplace;
|
|
pNewDefButton = m_pFind;
|
|
}
|
|
|
|
DBG_ASSERT( WB_DEFBUTTON == ( pOldDefButton->GetStyle( ) & WB_DEFBUTTON ),
|
|
"HangulHanjaConversionDialog::SetCurrentString: wrong previous default button (1)!" );
|
|
DBG_ASSERT( 0 == ( pNewDefButton->GetStyle( ) & WB_DEFBUTTON ),
|
|
"HangulHanjaConversionDialog::SetCurrentString: wrong previous default button (2)!" );
|
|
|
|
lcl_modifyWindowStyle( pOldDefButton, 0, WB_DEFBUTTON );
|
|
lcl_modifyWindowStyle( pNewDefButton, WB_DEFBUTTON, 0 );
|
|
|
|
// give the focus to the new def button temporarily - VCL is somewhat peculiar
|
|
// in recognizing a new default button
|
|
VclPtr<vcl::Window> xSaveFocusId = Window::SaveFocus();
|
|
pNewDefButton->GrabFocus();
|
|
Window::EndSaveFocus( xSaveFocusId );
|
|
}
|
|
}
|
|
|
|
|
|
OUString HangulHanjaConversionDialog::GetCurrentSuggestion( ) const
|
|
{
|
|
return m_pWordInput->GetText();
|
|
}
|
|
|
|
|
|
void HangulHanjaConversionDialog::SetByCharacter( bool _bByCharacter )
|
|
{
|
|
m_pReplaceByChar->Check( _bByCharacter );
|
|
m_pSuggestions->DisplayListBox( !_bByCharacter );
|
|
}
|
|
|
|
|
|
void HangulHanjaConversionDialog::SetConversionDirectionState(
|
|
bool _bTryBothDirections,
|
|
HHC::ConversionDirection _ePrimaryConversionDirection )
|
|
{
|
|
// default state: try both direction
|
|
m_pHangulOnly->Check( false );
|
|
m_pHangulOnly->Enable();
|
|
m_pHanjaOnly->Check( false );
|
|
m_pHanjaOnly->Enable();
|
|
|
|
if (!_bTryBothDirections)
|
|
{
|
|
CheckBox *pBox = _ePrimaryConversionDirection == HHC::eHangulToHanja?
|
|
m_pHangulOnly : m_pHanjaOnly;
|
|
pBox->Check();
|
|
OnConversionDirectionClicked( pBox );
|
|
}
|
|
}
|
|
|
|
|
|
bool HangulHanjaConversionDialog::GetUseBothDirections( ) const
|
|
{
|
|
return !m_pHangulOnly->IsChecked() && !m_pHanjaOnly->IsChecked();
|
|
}
|
|
|
|
|
|
HHC::ConversionDirection HangulHanjaConversionDialog::GetDirection(
|
|
HHC::ConversionDirection eDefaultDirection ) const
|
|
{
|
|
HHC::ConversionDirection eDirection = eDefaultDirection;
|
|
if ( m_pHangulOnly->IsChecked() && !m_pHanjaOnly->IsChecked() )
|
|
eDirection = HHC::eHangulToHanja;
|
|
else if ( !m_pHangulOnly->IsChecked() && m_pHanjaOnly->IsChecked() )
|
|
eDirection = HHC::eHanjaToHangul;
|
|
return eDirection;
|
|
}
|
|
|
|
|
|
void HangulHanjaConversionDialog::SetConversionFormat( HHC::ConversionFormat _eType )
|
|
{
|
|
switch ( _eType )
|
|
{
|
|
case HHC::eSimpleConversion: m_pSimpleConversion->Check(); break;
|
|
case HHC::eHangulBracketed: m_pHangulBracketed->Check(); break;
|
|
case HHC::eHanjaBracketed: m_pHanjaBracketed->Check(); break;
|
|
case HHC::eRubyHanjaAbove: m_pHanjaAbove->Check(); break;
|
|
case HHC::eRubyHanjaBelow: m_pHanjaBelow->Check(); break;
|
|
case HHC::eRubyHangulAbove: m_pHangulAbove->Check(); break;
|
|
case HHC::eRubyHangulBelow: m_pHangulBelow->Check(); break;
|
|
default:
|
|
OSL_FAIL( "HangulHanjaConversionDialog::SetConversionFormat: unknown type!" );
|
|
}
|
|
}
|
|
|
|
|
|
HHC::ConversionFormat HangulHanjaConversionDialog::GetConversionFormat( ) const
|
|
{
|
|
if ( m_pSimpleConversion->IsChecked() )
|
|
return HHC::eSimpleConversion;
|
|
if ( m_pHangulBracketed->IsChecked() )
|
|
return HHC::eHangulBracketed;
|
|
if ( m_pHanjaBracketed->IsChecked() )
|
|
return HHC::eHanjaBracketed;
|
|
if ( m_pHanjaAbove->IsChecked() )
|
|
return HHC::eRubyHanjaAbove;
|
|
if ( m_pHanjaBelow->IsChecked() )
|
|
return HHC::eRubyHanjaBelow;
|
|
if ( m_pHangulAbove->IsChecked() )
|
|
return HHC::eRubyHangulAbove;
|
|
if ( m_pHangulBelow->IsChecked() )
|
|
return HHC::eRubyHangulBelow;
|
|
|
|
OSL_FAIL( "HangulHanjaConversionDialog::GetConversionFormat: no radio checked?" );
|
|
return HHC::eSimpleConversion;
|
|
}
|
|
|
|
|
|
void HangulHanjaConversionDialog::EnableRubySupport( bool bVal )
|
|
{
|
|
m_pHanjaAbove->Enable( bVal );
|
|
m_pHanjaBelow->Enable( bVal );
|
|
m_pHangulAbove->Enable( bVal );
|
|
m_pHangulBelow->Enable( bVal );
|
|
}
|
|
|
|
|
|
void HangulHanjaOptionsDialog::Init()
|
|
{
|
|
if( !m_xConversionDictionaryList.is() )
|
|
{
|
|
m_xConversionDictionaryList = ConversionDictionaryList::create( ::comphelper::getProcessComponentContext() );
|
|
}
|
|
|
|
m_aDictList.clear();
|
|
m_pDictsLB->Clear();
|
|
|
|
Reference< XNameContainer > xNameCont = m_xConversionDictionaryList->getDictionaryContainer();
|
|
if( xNameCont.is() )
|
|
{
|
|
Sequence< OUString > aDictNames( xNameCont->getElementNames() );
|
|
|
|
const OUString* pDic = aDictNames.getConstArray();
|
|
sal_Int32 nCount = aDictNames.getLength();
|
|
|
|
sal_Int32 i;
|
|
for( i = 0 ; i < nCount ; ++i )
|
|
{
|
|
Any aAny( xNameCont->getByName( pDic[ i ] ) );
|
|
Reference< XConversionDictionary > xDic;
|
|
if( ( aAny >>= xDic ) && xDic.is() )
|
|
{
|
|
if( LANGUAGE_KOREAN == LanguageTag( xDic->getLocale() ).getLanguageType() )
|
|
{
|
|
m_aDictList.push_back( xDic );
|
|
AddDict( xDic->getName(), xDic->isActive() );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG(HangulHanjaOptionsDialog, OkHdl, Button*, void)
|
|
{
|
|
sal_uInt32 nCnt = m_aDictList.size();
|
|
sal_uInt32 n = 0;
|
|
sal_uInt32 nActiveDics = 0;
|
|
Sequence< OUString > aActiveDics;
|
|
|
|
aActiveDics.realloc( nCnt );
|
|
OUString* pActActiveDic = aActiveDics.getArray();
|
|
|
|
while( nCnt )
|
|
{
|
|
Reference< XConversionDictionary > xDict = m_aDictList[ n ];
|
|
SvTreeListEntry* pEntry = m_pDictsLB->SvTreeListBox::GetEntry( n );
|
|
|
|
DBG_ASSERT( xDict.is(), "-HangulHanjaOptionsDialog::OkHdl(): someone is evaporated..." );
|
|
DBG_ASSERT( pEntry, "-HangulHanjaOptionsDialog::OkHdl(): no one there in list?" );
|
|
|
|
bool bActive = m_pDictsLB->GetCheckButtonState( pEntry ) == SvButtonState::Checked;
|
|
xDict->setActive( bActive );
|
|
Reference< util::XFlushable > xFlush( xDict, uno::UNO_QUERY );
|
|
if( xFlush.is() )
|
|
xFlush->flush();
|
|
|
|
if( bActive )
|
|
{
|
|
pActActiveDic[ nActiveDics ] = xDict->getName();
|
|
++nActiveDics;
|
|
}
|
|
|
|
++n;
|
|
--nCnt;
|
|
}
|
|
|
|
// save configuration
|
|
aActiveDics.realloc( nActiveDics );
|
|
Any aTmp;
|
|
SvtLinguConfig aLngCfg;
|
|
aTmp <<= aActiveDics;
|
|
aLngCfg.SetProperty( UPH_ACTIVE_CONVERSION_DICTIONARIES, aTmp );
|
|
|
|
aTmp <<= bool( m_pIgnorepostCB->IsChecked() );
|
|
aLngCfg.SetProperty( UPH_IS_IGNORE_POST_POSITIONAL_WORD, aTmp );
|
|
|
|
aTmp <<= bool( m_pShowrecentlyfirstCB->IsChecked() );
|
|
aLngCfg.SetProperty( UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST, aTmp );
|
|
|
|
aTmp <<= bool( m_pAutoreplaceuniqueCB->IsChecked() );
|
|
aLngCfg.SetProperty( UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES, aTmp );
|
|
|
|
EndDialog( RET_OK );
|
|
}
|
|
|
|
IMPL_LINK_NOARG(HangulHanjaOptionsDialog, DictsLB_SelectHdl, SvTreeListBox*, void)
|
|
{
|
|
bool bSel = m_pDictsLB->FirstSelected() != nullptr;
|
|
|
|
m_pEditPB->Enable(bSel);
|
|
m_pDeletePB->Enable(bSel);
|
|
}
|
|
|
|
IMPL_LINK_NOARG(HangulHanjaOptionsDialog, NewDictHdl, Button*, void)
|
|
{
|
|
OUString aName;
|
|
ScopedVclPtrInstance< HangulHanjaNewDictDialog > aNewDlg(this);
|
|
aNewDlg->Execute();
|
|
if( aNewDlg->GetName( aName ) )
|
|
{
|
|
if( m_xConversionDictionaryList.is() )
|
|
{
|
|
try
|
|
{
|
|
Reference< XConversionDictionary > xDic =
|
|
m_xConversionDictionaryList->addNewDictionary( aName, LanguageTag::convertToLocale( LANGUAGE_KOREAN ), ConversionDictionaryType::HANGUL_HANJA );
|
|
|
|
if( xDic.is() )
|
|
{
|
|
//adapt local caches:
|
|
m_aDictList.push_back( xDic );
|
|
AddDict( xDic->getName(), xDic->isActive() );
|
|
}
|
|
}
|
|
catch( const ElementExistException& )
|
|
{
|
|
}
|
|
catch( const NoSupportException& )
|
|
{
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG(HangulHanjaOptionsDialog, EditDictHdl, Button*, void)
|
|
{
|
|
SvTreeListEntry* pEntry = m_pDictsLB->FirstSelected();
|
|
DBG_ASSERT( pEntry, "+HangulHanjaEditDictDialog::EditDictHdl(): call of edit should not be possible with no selection!" );
|
|
if( pEntry )
|
|
{
|
|
ScopedVclPtrInstance< HangulHanjaEditDictDialog > aEdDlg(this, m_aDictList, m_pDictsLB->GetSelectEntryPos());
|
|
aEdDlg->Execute();
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG(HangulHanjaOptionsDialog, DeleteDictHdl, Button*, void)
|
|
{
|
|
sal_uLong nSelPos = m_pDictsLB->GetSelectEntryPos();
|
|
if( nSelPos != TREELIST_ENTRY_NOTFOUND )
|
|
{
|
|
Reference< XConversionDictionary > xDic( m_aDictList[ nSelPos ] );
|
|
if( m_xConversionDictionaryList.is() && xDic.is() )
|
|
{
|
|
Reference< XNameContainer > xNameCont = m_xConversionDictionaryList->getDictionaryContainer();
|
|
if( xNameCont.is() )
|
|
{
|
|
try
|
|
{
|
|
xNameCont->removeByName( xDic->getName() );
|
|
|
|
//adapt local caches:
|
|
m_aDictList.erase(m_aDictList.begin()+nSelPos );
|
|
m_pDictsLB->RemoveEntry(nSelPos);
|
|
}
|
|
catch( const ElementExistException& )
|
|
{
|
|
}
|
|
catch( const NoSupportException& )
|
|
{
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
HangulHanjaOptionsDialog::HangulHanjaOptionsDialog(vcl::Window* _pParent)
|
|
: ModalDialog( _pParent, "HangulHanjaOptDialog",
|
|
"cui/ui/hangulhanjaoptdialog.ui" )
|
|
, m_pCheckButtonData(nullptr)
|
|
, m_xConversionDictionaryList(nullptr)
|
|
{
|
|
get(m_pDictsLB, "dicts");
|
|
get(m_pIgnorepostCB, "ignorepost");
|
|
get(m_pShowrecentlyfirstCB, "showrecentfirst");
|
|
get(m_pAutoreplaceuniqueCB, "autoreplaceunique");
|
|
get(m_pNewPB, "new");
|
|
get(m_pEditPB, "edit");
|
|
get(m_pDeletePB, "delete");
|
|
get(m_pOkPB, "ok");
|
|
|
|
m_pDictsLB->set_height_request(m_pDictsLB->GetTextHeight() * 5);
|
|
m_pDictsLB->set_width_request(m_pDictsLB->approximate_char_width() * 32);
|
|
m_pDictsLB->SetStyle( m_pDictsLB->GetStyle() | WB_CLIPCHILDREN | WB_HSCROLL | WB_FORCE_MAKEVISIBLE );
|
|
m_pDictsLB->SetSelectionMode( SelectionMode::Single );
|
|
m_pDictsLB->SetHighlightRange();
|
|
m_pDictsLB->SetSelectHdl( LINK( this, HangulHanjaOptionsDialog, DictsLB_SelectHdl ) );
|
|
m_pDictsLB->SetDeselectHdl( LINK( this, HangulHanjaOptionsDialog, DictsLB_SelectHdl ) );
|
|
|
|
m_pOkPB->SetClickHdl( LINK( this, HangulHanjaOptionsDialog, OkHdl ) );
|
|
m_pNewPB->SetClickHdl( LINK( this, HangulHanjaOptionsDialog, NewDictHdl ) );
|
|
m_pEditPB->SetClickHdl( LINK( this, HangulHanjaOptionsDialog, EditDictHdl ) );
|
|
m_pDeletePB->SetClickHdl( LINK( this, HangulHanjaOptionsDialog, DeleteDictHdl ) );
|
|
|
|
SvtLinguConfig aLngCfg;
|
|
Any aTmp;
|
|
bool bVal = bool();
|
|
aTmp = aLngCfg.GetProperty( UPH_IS_IGNORE_POST_POSITIONAL_WORD );
|
|
if( aTmp >>= bVal )
|
|
m_pIgnorepostCB->Check( bVal );
|
|
|
|
aTmp = aLngCfg.GetProperty( UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST );
|
|
if( aTmp >>= bVal )
|
|
m_pShowrecentlyfirstCB->Check( bVal );
|
|
|
|
aTmp = aLngCfg.GetProperty( UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES );
|
|
if( aTmp >>= bVal )
|
|
m_pAutoreplaceuniqueCB->Check( bVal );
|
|
|
|
Init();
|
|
}
|
|
|
|
HangulHanjaOptionsDialog::~HangulHanjaOptionsDialog()
|
|
{
|
|
disposeOnce();
|
|
}
|
|
|
|
void HangulHanjaOptionsDialog::dispose()
|
|
{
|
|
if (m_pDictsLB)
|
|
{
|
|
SvTreeListEntry* pEntry = m_pDictsLB->First();
|
|
while( pEntry )
|
|
{
|
|
delete static_cast<OUString const *>(pEntry->GetUserData());
|
|
pEntry->SetUserData( nullptr );
|
|
pEntry = m_pDictsLB->Next( pEntry );
|
|
}
|
|
}
|
|
|
|
delete m_pCheckButtonData;
|
|
m_pCheckButtonData = nullptr;
|
|
|
|
m_pDictsLB.clear();
|
|
m_pIgnorepostCB.clear();
|
|
m_pShowrecentlyfirstCB.clear();
|
|
m_pAutoreplaceuniqueCB.clear();
|
|
m_pNewPB.clear();
|
|
m_pEditPB.clear();
|
|
m_pDeletePB.clear();
|
|
m_pOkPB.clear();
|
|
ModalDialog::dispose();
|
|
}
|
|
|
|
void HangulHanjaOptionsDialog::AddDict( const OUString& _rName, bool _bChecked )
|
|
{
|
|
SvTreeListEntry* pEntry = m_pDictsLB->SvTreeListBox::InsertEntry( _rName );
|
|
m_pDictsLB->SetCheckButtonState( pEntry, _bChecked? SvButtonState::Checked : SvButtonState::Unchecked );
|
|
pEntry->SetUserData( new OUString( _rName ) );
|
|
}
|
|
|
|
IMPL_LINK_NOARG(HangulHanjaNewDictDialog, OKHdl, Button*, void)
|
|
{
|
|
OUString aName(comphelper::string::stripEnd(m_pDictNameED->GetText(), ' '));
|
|
|
|
m_bEntered = !aName.isEmpty();
|
|
if( m_bEntered )
|
|
m_pDictNameED->SetText( aName ); // do this in case of trailing chars have been deleted
|
|
|
|
EndDialog( RET_OK );
|
|
}
|
|
|
|
IMPL_LINK_NOARG(HangulHanjaNewDictDialog, ModifyHdl, Edit&, void)
|
|
{
|
|
OUString aName(comphelper::string::stripEnd(m_pDictNameED->GetText(), ' '));
|
|
|
|
m_pOkBtn->Enable( !aName.isEmpty() );
|
|
}
|
|
|
|
HangulHanjaNewDictDialog::HangulHanjaNewDictDialog(vcl::Window* pParent)
|
|
: ModalDialog(pParent, "HangulHanjaAddDialog", "cui/ui/hangulhanjaadddialog.ui")
|
|
, m_bEntered(false)
|
|
{
|
|
get(m_pOkBtn, "ok");
|
|
get(m_pDictNameED, "entry");
|
|
|
|
m_pOkBtn->SetClickHdl( LINK( this, HangulHanjaNewDictDialog, OKHdl ) );
|
|
m_pDictNameED->SetModifyHdl( LINK( this, HangulHanjaNewDictDialog, ModifyHdl ) );
|
|
}
|
|
|
|
HangulHanjaNewDictDialog::~HangulHanjaNewDictDialog()
|
|
{
|
|
disposeOnce();
|
|
}
|
|
|
|
void HangulHanjaNewDictDialog::dispose()
|
|
{
|
|
m_pDictNameED.clear();
|
|
m_pOkBtn.clear();
|
|
ModalDialog::dispose();
|
|
}
|
|
|
|
bool HangulHanjaNewDictDialog::GetName( OUString& _rRetName ) const
|
|
{
|
|
if( m_bEntered )
|
|
_rRetName = comphelper::string::stripEnd(m_pDictNameED->GetText(), ' ');
|
|
|
|
return m_bEntered;
|
|
}
|
|
|
|
class SuggestionList
|
|
{
|
|
private:
|
|
protected:
|
|
std::vector<OUString*> m_vElements;
|
|
sal_uInt16 m_nNumOfEntries;
|
|
// index of the internal iterator, used for First() and Next() methods
|
|
sal_uInt16 m_nAct;
|
|
|
|
const OUString* Next_();
|
|
public:
|
|
SuggestionList();
|
|
~SuggestionList();
|
|
|
|
void Set( const OUString& _rElement, sal_uInt16 _nNumOfElement );
|
|
bool Reset( sal_uInt16 _nNumOfElement );
|
|
const OUString* Get( sal_uInt16 _nNumOfElement ) const;
|
|
void Clear();
|
|
|
|
const OUString* First();
|
|
const OUString* Next();
|
|
|
|
inline sal_uInt16 GetCount() const { return m_nNumOfEntries; }
|
|
};
|
|
|
|
SuggestionList::SuggestionList() :
|
|
m_vElements(MAXNUM_SUGGESTIONS, static_cast<OUString*>(nullptr))
|
|
{
|
|
m_nAct = m_nNumOfEntries = 0;
|
|
}
|
|
|
|
SuggestionList::~SuggestionList()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
void SuggestionList::Set( const OUString& _rElement, sal_uInt16 _nNumOfElement )
|
|
{
|
|
bool bRet = _nNumOfElement < m_vElements.size();
|
|
if( bRet )
|
|
{
|
|
if( m_vElements[_nNumOfElement] != nullptr )
|
|
*(m_vElements[_nNumOfElement]) = _rElement;
|
|
else
|
|
{
|
|
m_vElements[_nNumOfElement] = new OUString( _rElement );
|
|
++m_nNumOfEntries;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool SuggestionList::Reset( sal_uInt16 _nNumOfElement )
|
|
{
|
|
bool bRet = _nNumOfElement < m_vElements.size();
|
|
if( bRet )
|
|
{
|
|
if( m_vElements[_nNumOfElement] != nullptr )
|
|
{
|
|
delete m_vElements[_nNumOfElement];
|
|
m_vElements[_nNumOfElement] = nullptr;
|
|
--m_nNumOfEntries;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
const OUString* SuggestionList::Get( sal_uInt16 _nNumOfElement ) const
|
|
{
|
|
if( _nNumOfElement < m_vElements.size())
|
|
return m_vElements[_nNumOfElement];
|
|
return nullptr;
|
|
}
|
|
|
|
void SuggestionList::Clear()
|
|
{
|
|
if( m_nNumOfEntries )
|
|
{
|
|
for( std::vector<OUString*>::iterator it = m_vElements.begin(); it != m_vElements.end(); ++it )
|
|
if( *it != nullptr )
|
|
{
|
|
delete *it;
|
|
*it = nullptr;
|
|
}
|
|
|
|
m_nNumOfEntries = m_nAct = 0;
|
|
}
|
|
}
|
|
|
|
const OUString* SuggestionList::Next_()
|
|
{
|
|
const OUString* pRet = nullptr;
|
|
while( m_nAct < m_vElements.size() && !pRet )
|
|
{
|
|
pRet = m_vElements[ m_nAct ];
|
|
if( !pRet )
|
|
++m_nAct;
|
|
}
|
|
|
|
return pRet;
|
|
}
|
|
|
|
const OUString* SuggestionList::First()
|
|
{
|
|
m_nAct = 0;
|
|
return Next_();
|
|
}
|
|
|
|
const OUString* SuggestionList::Next()
|
|
{
|
|
const OUString* pRet;
|
|
|
|
if( m_nAct < m_nNumOfEntries )
|
|
{
|
|
++m_nAct;
|
|
pRet = Next_();
|
|
}
|
|
else
|
|
pRet = nullptr;
|
|
|
|
return pRet;
|
|
}
|
|
|
|
|
|
bool SuggestionEdit::ShouldScroll( bool _bUp ) const
|
|
{
|
|
bool bRet = false;
|
|
|
|
if( _bUp )
|
|
{
|
|
if( !m_pPrev )
|
|
bRet = m_pScrollBar->GetThumbPos() > m_pScrollBar->GetRangeMin();
|
|
}
|
|
else
|
|
{
|
|
if( !m_pNext )
|
|
bRet = m_pScrollBar->GetThumbPos() < ( m_pScrollBar->GetRangeMax() - 4 );
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
void SuggestionEdit::DoJump( bool _bUp )
|
|
{
|
|
const Link<Control&,void>& rLoseFocusHdl = GetLoseFocusHdl();
|
|
rLoseFocusHdl.Call( *this );
|
|
m_pScrollBar->SetThumbPos( m_pScrollBar->GetThumbPos() + ( _bUp? -1 : 1 ) );
|
|
|
|
( static_cast< HangulHanjaEditDictDialog* >( GetParentDialog() ) )->UpdateScrollbar();
|
|
}
|
|
|
|
SuggestionEdit::SuggestionEdit( vcl::Window* pParent, WinBits nBits )
|
|
: Edit(pParent, nBits)
|
|
, m_pPrev(nullptr)
|
|
, m_pNext(nullptr)
|
|
, m_pScrollBar(nullptr)
|
|
{
|
|
}
|
|
|
|
SuggestionEdit::~SuggestionEdit()
|
|
{
|
|
disposeOnce();
|
|
}
|
|
|
|
void SuggestionEdit::dispose()
|
|
{
|
|
m_pPrev.clear();
|
|
m_pNext.clear();
|
|
m_pScrollBar.clear();
|
|
Edit::dispose();
|
|
}
|
|
|
|
bool SuggestionEdit::PreNotify( NotifyEvent& rNEvt )
|
|
{
|
|
bool bHandled = false;
|
|
if( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
|
|
{
|
|
const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
|
|
const vcl::KeyCode& rKeyCode = pKEvt->GetKeyCode();
|
|
sal_uInt16 nMod = rKeyCode.GetModifier();
|
|
sal_uInt16 nCode = rKeyCode.GetCode();
|
|
if( nCode == KEY_TAB && ( !nMod || KEY_SHIFT == nMod ) )
|
|
{
|
|
bool bUp = KEY_SHIFT == nMod;
|
|
if( ShouldScroll( bUp ) )
|
|
{
|
|
DoJump( bUp );
|
|
SetSelection( Selection( 0, SELECTION_MAX ) );
|
|
// Tab-travel doesn't really happen, so emulate it by setting a selection manually
|
|
bHandled = true;
|
|
}
|
|
}
|
|
else if( KEY_UP == nCode || KEY_DOWN == nCode )
|
|
{
|
|
bool bUp = KEY_UP == nCode;
|
|
if( ShouldScroll( bUp ) )
|
|
{
|
|
DoJump( bUp );
|
|
bHandled = true;
|
|
}
|
|
else if( bUp )
|
|
{
|
|
if( m_pPrev )
|
|
{
|
|
m_pPrev->GrabFocus();
|
|
bHandled = true;
|
|
}
|
|
}
|
|
else if( m_pNext )
|
|
{
|
|
m_pNext->GrabFocus();
|
|
bHandled = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( !bHandled )
|
|
bHandled = Edit::PreNotify( rNEvt );
|
|
return bHandled;
|
|
}
|
|
|
|
void SuggestionEdit::init( ScrollBar* pScrollBar, SuggestionEdit* pPrev, SuggestionEdit* pNext)
|
|
{
|
|
m_pScrollBar = pScrollBar;
|
|
m_pPrev = pPrev;
|
|
m_pNext = pNext;
|
|
}
|
|
|
|
VCL_BUILDER_FACTORY_ARGS(SuggestionEdit, WB_LEFT|WB_VCENTER|WB_BORDER)
|
|
|
|
namespace
|
|
{
|
|
bool GetConversions( const Reference< XConversionDictionary >& _xDict,
|
|
const OUString& _rOrg,
|
|
Sequence< OUString >& _rEntries )
|
|
{
|
|
bool bRet = false;
|
|
if( _xDict.is() && !_rOrg.isEmpty() )
|
|
{
|
|
try
|
|
{
|
|
_rEntries = _xDict->getConversions( _rOrg,
|
|
0,
|
|
_rOrg.getLength(),
|
|
ConversionDirection_FROM_LEFT,
|
|
css::i18n::TextConversionOption::NONE );
|
|
bRet = _rEntries.getLength() > 0;
|
|
}
|
|
catch( const IllegalArgumentException& )
|
|
{
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
}
|
|
|
|
|
|
IMPL_LINK_NOARG( HangulHanjaEditDictDialog, ScrollHdl, ScrollBar*, void )
|
|
{
|
|
UpdateScrollbar();
|
|
}
|
|
|
|
IMPL_LINK_NOARG( HangulHanjaEditDictDialog, OriginalModifyHdl, Edit&, void )
|
|
{
|
|
m_bModifiedOriginal = true;
|
|
m_aOriginal = comphelper::string::stripEnd( m_aOriginalLB->GetText(), ' ' );
|
|
|
|
UpdateSuggestions();
|
|
UpdateButtonStates();
|
|
}
|
|
|
|
IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl1, Edit&, rEdit, void )
|
|
{
|
|
EditModify( &rEdit, 0 );
|
|
}
|
|
|
|
IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl2, Edit&, rEdit, void )
|
|
{
|
|
EditModify( &rEdit, 1 );
|
|
}
|
|
|
|
IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl3, Edit&, rEdit, void )
|
|
{
|
|
EditModify( &rEdit, 2 );
|
|
}
|
|
|
|
IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl4, Edit&, rEdit, void )
|
|
{
|
|
EditModify( &rEdit, 3 );
|
|
}
|
|
|
|
IMPL_LINK_NOARG( HangulHanjaEditDictDialog, BookLBSelectHdl, ListBox&, void )
|
|
{
|
|
InitEditDictDialog( m_aBookLB->GetSelectEntryPos() );
|
|
}
|
|
|
|
IMPL_LINK_NOARG( HangulHanjaEditDictDialog, NewPBPushHdl, Button*, void )
|
|
{
|
|
DBG_ASSERT( m_pSuggestions, "-HangulHanjaEditDictDialog::NewPBPushHdl(): no suggestions... search in hell..." );
|
|
Reference< XConversionDictionary > xDict = m_rDictList[ m_nCurrentDict ];
|
|
if( xDict.is() && m_pSuggestions )
|
|
{
|
|
//delete old entry
|
|
bool bRemovedSomething = DeleteEntryFromDictionary( m_aOriginal, xDict );
|
|
|
|
OUString aLeft( m_aOriginal );
|
|
const OUString* pRight = m_pSuggestions->First();
|
|
bool bAddedSomething = false;
|
|
while( pRight )
|
|
{
|
|
try
|
|
{
|
|
//add new entry
|
|
xDict->addEntry( aLeft, *pRight );
|
|
bAddedSomething = true;
|
|
}
|
|
catch( const IllegalArgumentException& )
|
|
{
|
|
}
|
|
catch( const ElementExistException& )
|
|
{
|
|
}
|
|
|
|
pRight = m_pSuggestions->Next();
|
|
}
|
|
|
|
if( bAddedSomething || bRemovedSomething )
|
|
InitEditDictDialog( m_nCurrentDict );
|
|
}
|
|
else
|
|
{
|
|
SAL_INFO( "cui.dialogs", "dictionary faded away..." );
|
|
}
|
|
}
|
|
|
|
bool HangulHanjaEditDictDialog::DeleteEntryFromDictionary( const OUString&, const Reference< XConversionDictionary >& xDict )
|
|
{
|
|
bool bRemovedSomething = false;
|
|
if( xDict.is() )
|
|
{
|
|
OUString aOrg( m_aOriginal );
|
|
Sequence< OUString > aEntries;
|
|
GetConversions( xDict, m_aOriginal, aEntries );
|
|
|
|
sal_uInt32 n = aEntries.getLength();
|
|
OUString* pEntry = aEntries.getArray();
|
|
while( n )
|
|
{
|
|
try
|
|
{
|
|
xDict->removeEntry( aOrg, *pEntry );
|
|
bRemovedSomething = true;
|
|
}
|
|
catch( const NoSuchElementException& )
|
|
{ // can not be...
|
|
}
|
|
|
|
++pEntry;
|
|
--n;
|
|
}
|
|
}
|
|
return bRemovedSomething;
|
|
}
|
|
|
|
IMPL_LINK_NOARG( HangulHanjaEditDictDialog, DeletePBPushHdl, Button*, void )
|
|
{
|
|
if( DeleteEntryFromDictionary( m_aOriginal, m_rDictList[ m_nCurrentDict ] ) )
|
|
{
|
|
m_aOriginal.clear();
|
|
m_bModifiedOriginal = true;
|
|
InitEditDictDialog( m_nCurrentDict );
|
|
}
|
|
}
|
|
|
|
void HangulHanjaEditDictDialog::InitEditDictDialog( sal_uInt32 _nSelDict )
|
|
{
|
|
if( m_pSuggestions )
|
|
m_pSuggestions->Clear();
|
|
|
|
if( m_nCurrentDict != _nSelDict )
|
|
{
|
|
m_nCurrentDict = _nSelDict;
|
|
m_aOriginal.clear();
|
|
m_bModifiedOriginal = true;
|
|
}
|
|
|
|
UpdateOriginalLB();
|
|
|
|
m_aOriginalLB->SetText( !m_aOriginal.isEmpty() ? m_aOriginal : m_aEditHintText, Selection( 0, SELECTION_MAX ) );
|
|
m_aOriginalLB->GrabFocus();
|
|
|
|
UpdateSuggestions();
|
|
UpdateButtonStates();
|
|
}
|
|
|
|
void HangulHanjaEditDictDialog::UpdateOriginalLB()
|
|
{
|
|
m_aOriginalLB->Clear();
|
|
Reference< XConversionDictionary > xDict = m_rDictList[ m_nCurrentDict ];
|
|
if( xDict.is() )
|
|
{
|
|
Sequence< OUString > aEntries = xDict->getConversionEntries( ConversionDirection_FROM_LEFT );
|
|
sal_uInt32 n = aEntries.getLength();
|
|
OUString* pEntry = aEntries.getArray();
|
|
while( n )
|
|
{
|
|
m_aOriginalLB->InsertEntry( *pEntry );
|
|
|
|
++pEntry;
|
|
--n;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SAL_INFO( "cui.dialogs", "dictionary faded away..." );
|
|
}
|
|
}
|
|
|
|
void HangulHanjaEditDictDialog::UpdateButtonStates()
|
|
{
|
|
bool bHaveValidOriginalString = !m_aOriginal.isEmpty() && m_aOriginal != m_aEditHintText;
|
|
bool bNew = bHaveValidOriginalString && m_pSuggestions && m_pSuggestions->GetCount() > 0;
|
|
bNew = bNew && ( m_bModifiedSuggestions || m_bModifiedOriginal );
|
|
|
|
m_aNewPB->Enable( bNew );
|
|
m_aDeletePB->Enable(!m_bModifiedOriginal && bHaveValidOriginalString);
|
|
}
|
|
|
|
void HangulHanjaEditDictDialog::UpdateSuggestions()
|
|
{
|
|
Sequence< OUString > aEntries;
|
|
bool bFound = GetConversions( m_rDictList[ m_nCurrentDict ], m_aOriginal, aEntries );
|
|
if( bFound )
|
|
{
|
|
m_bModifiedOriginal = false;
|
|
|
|
if( m_pSuggestions )
|
|
m_pSuggestions->Clear();
|
|
|
|
//fill found entries into boxes
|
|
sal_uInt32 nCnt = aEntries.getLength();
|
|
if( nCnt )
|
|
{
|
|
if( !m_pSuggestions )
|
|
m_pSuggestions = new SuggestionList;
|
|
|
|
const OUString* pSugg = aEntries.getConstArray();
|
|
sal_uInt32 n = 0;
|
|
while( nCnt )
|
|
{
|
|
m_pSuggestions->Set( pSugg[ n ], sal_uInt16( n ) );
|
|
++n;
|
|
--nCnt;
|
|
}
|
|
}
|
|
m_bModifiedSuggestions = false;
|
|
}
|
|
|
|
m_aScrollSB->SetThumbPos( 0 );
|
|
UpdateScrollbar(); // will force edits to be filled new
|
|
}
|
|
|
|
void HangulHanjaEditDictDialog::SetEditText( Edit& _rEdit, sal_uInt16 _nEntryNum )
|
|
{
|
|
OUString aStr;
|
|
if( m_pSuggestions )
|
|
{
|
|
const OUString* p = m_pSuggestions->Get( _nEntryNum );
|
|
if( p )
|
|
aStr = *p;
|
|
}
|
|
|
|
_rEdit.SetText( aStr );
|
|
}
|
|
|
|
void HangulHanjaEditDictDialog::EditModify( Edit* _pEdit, sal_uInt8 _nEntryOffset )
|
|
{
|
|
m_bModifiedSuggestions = true;
|
|
|
|
OUString aTxt( _pEdit->GetText() );
|
|
sal_uInt16 nEntryNum = m_nTopPos + _nEntryOffset;
|
|
if( aTxt.isEmpty() )
|
|
{
|
|
//reset suggestion
|
|
if( m_pSuggestions )
|
|
m_pSuggestions->Reset( nEntryNum );
|
|
}
|
|
else
|
|
{
|
|
//set suggestion
|
|
if( !m_pSuggestions )
|
|
m_pSuggestions = new SuggestionList;
|
|
m_pSuggestions->Set( aTxt, nEntryNum );
|
|
}
|
|
|
|
UpdateButtonStates();
|
|
}
|
|
|
|
HangulHanjaEditDictDialog::HangulHanjaEditDictDialog( vcl::Window* _pParent, HHDictList& _rDictList, sal_uInt32 _nSelDict )
|
|
:ModalDialog ( _pParent, "HangulHanjaEditDictDialog", "cui/ui/hangulhanjaeditdictdialog.ui" )
|
|
,m_aEditHintText ( CUI_RESSTR(RID_SVXSTR_EDITHINT) )
|
|
,m_rDictList ( _rDictList )
|
|
,m_nCurrentDict ( 0xFFFFFFFF )
|
|
,m_pSuggestions ( nullptr )
|
|
,m_nTopPos ( 0 )
|
|
,m_bModifiedSuggestions ( false )
|
|
,m_bModifiedOriginal ( false )
|
|
{
|
|
get( m_aBookLB, "book" );
|
|
get( m_aOriginalLB, "original" );
|
|
get( m_aNewPB, "new" );
|
|
get( m_aDeletePB, "delete" );
|
|
get( m_aScrollSB, "scrollbar" );
|
|
get( m_aEdit1, "edit1" );
|
|
get( m_aEdit2, "edit2" );
|
|
get( m_aEdit3, "edit3" );
|
|
get( m_aEdit4, "edit4" );
|
|
|
|
m_aEdit1->init( m_aScrollSB, nullptr, m_aEdit2 );
|
|
m_aEdit2->init( m_aScrollSB, m_aEdit1, m_aEdit3 );
|
|
m_aEdit3->init( m_aScrollSB, m_aEdit2, m_aEdit4 );
|
|
m_aEdit4->init( m_aScrollSB, m_aEdit3, nullptr );
|
|
|
|
m_aOriginalLB->SetModifyHdl( LINK( this, HangulHanjaEditDictDialog, OriginalModifyHdl ) );
|
|
|
|
m_aNewPB->SetClickHdl( LINK( this, HangulHanjaEditDictDialog, NewPBPushHdl ) );
|
|
m_aNewPB->Enable( false );
|
|
|
|
m_aDeletePB->SetClickHdl( LINK( this, HangulHanjaEditDictDialog, DeletePBPushHdl ) );
|
|
m_aDeletePB->Enable( false );
|
|
|
|
#if( MAXNUM_SUGGESTIONS <= 4 )
|
|
#error number of suggestions should not under-run the value of 5
|
|
#endif
|
|
|
|
Link<ScrollBar*,void> aScrLk( LINK( this, HangulHanjaEditDictDialog, ScrollHdl ) );
|
|
m_aScrollSB->SetScrollHdl( aScrLk );
|
|
m_aScrollSB->SetEndScrollHdl( aScrLk );
|
|
m_aScrollSB->SetRangeMin( 0 );
|
|
m_aScrollSB->SetRangeMax( MAXNUM_SUGGESTIONS );
|
|
m_aScrollSB->SetPageSize( 4 ); // because we have 4 edits / page
|
|
m_aScrollSB->SetVisibleSize( 4 );
|
|
|
|
m_aEdit1->SetModifyHdl( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl1 ) );
|
|
m_aEdit2->SetModifyHdl( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl2 ) );
|
|
m_aEdit3->SetModifyHdl( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl3 ) );
|
|
m_aEdit4->SetModifyHdl( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl4 ) );
|
|
|
|
m_aBookLB->SetSelectHdl( LINK( this, HangulHanjaEditDictDialog, BookLBSelectHdl ) );
|
|
sal_uInt32 nDictCnt = m_rDictList.size();
|
|
for( sal_uInt32 n = 0 ; n < nDictCnt ; ++n )
|
|
{
|
|
Reference< XConversionDictionary > xDic( m_rDictList[n] );
|
|
OUString aName;
|
|
if( xDic.is() )
|
|
aName = xDic->getName();
|
|
m_aBookLB->InsertEntry( aName );
|
|
}
|
|
m_aBookLB->SelectEntryPos( sal_uInt16( _nSelDict ) );
|
|
|
|
InitEditDictDialog( _nSelDict );
|
|
}
|
|
|
|
HangulHanjaEditDictDialog::~HangulHanjaEditDictDialog()
|
|
{
|
|
disposeOnce();
|
|
}
|
|
|
|
void HangulHanjaEditDictDialog::dispose()
|
|
{
|
|
delete m_pSuggestions;
|
|
m_pSuggestions = nullptr;
|
|
m_aBookLB.clear();
|
|
m_aOriginalLB.clear();
|
|
m_aEdit1.clear();
|
|
m_aEdit2.clear();
|
|
m_aEdit3.clear();
|
|
m_aEdit4.clear();
|
|
m_aScrollSB.clear();
|
|
m_aNewPB.clear();
|
|
m_aDeletePB.clear();
|
|
ModalDialog::dispose();
|
|
}
|
|
|
|
void HangulHanjaEditDictDialog::UpdateScrollbar()
|
|
{
|
|
sal_uInt16 nPos = sal_uInt16( m_aScrollSB->GetThumbPos() );
|
|
m_nTopPos = nPos;
|
|
|
|
SetEditText( *m_aEdit1, nPos++ );
|
|
SetEditText( *m_aEdit2, nPos++ );
|
|
SetEditText( *m_aEdit3, nPos++ );
|
|
SetEditText( *m_aEdit4, nPos );
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|