1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "richtextvclcontrol.hxx"
21 #include "richtextimplcontrol.hxx"
22 #include <svl/itempool.hxx>
23 #include <svl/itemset.hxx>
24 #include <svl/languageoptions.hxx>
25 #if OSL_DEBUG_LEVEL > 0
26 #include <unotools/ucbstreamhelper.hxx>
27 #include <vcl/msgbox.hxx>
28 #include <sfx2/filedlghelper.hxx>
29 #include <tools/urlobj.hxx>
30 #include "com/sun/star/ui/dialogs/TemplateDescription.hpp"
32 #include <editeng/scripttypeitem.hxx>
33 #include <editeng/editeng.hxx>
34 #include <editeng/editview.hxx>
35 #include <editeng/eeitem.hxx>
36 #include <editeng/fontitem.hxx>
37 #include <editeng/fhgtitem.hxx>
38 #include <editeng/editids.hrc>
39 #include <svx/svxids.hrc>
44 RichTextControl::RichTextControl( RichTextEngine
* _pEngine
, vcl::Window
* _pParent
, WinBits _nStyle
,
45 ITextAttributeListener
* _pTextAttribListener
, ITextSelectionListener
* _pSelectionListener
)
46 :Control( _pParent
, implInitStyle( _nStyle
) )
49 implInit( _pEngine
, _pTextAttribListener
, _pSelectionListener
);
53 void RichTextControl::implInit( RichTextEngine
* _pEngine
, ITextAttributeListener
* _pTextAttribListener
, ITextSelectionListener
* _pSelectionListener
)
55 m_pImpl
= new RichTextControlImpl( this, _pEngine
, _pTextAttribListener
, _pSelectionListener
);
56 SetCompoundControl( true );
60 RichTextControl::~RichTextControl( )
65 void RichTextControl::dispose()
72 AttributeState
RichTextControl::getState( AttributeId _nAttributeId
) const
74 return m_pImpl
->getAttributeState( _nAttributeId
);
78 void RichTextControl::executeAttribute( AttributeId _nAttributeId
, const SfxPoolItem
* _pArgument
)
80 SfxItemSet
aToApplyAttributes( getView().GetEmptyItemSet() );
81 if ( !m_pImpl
->executeAttribute( getView().GetAttribs(), aToApplyAttributes
, _nAttributeId
, _pArgument
, m_pImpl
->getSelectedScriptType() ) )
83 OSL_FAIL( "RichTextControl::executeAttribute: cannot handle the given attribute!" );
87 applyAttributes( aToApplyAttributes
);
91 void RichTextControl::applyAttributes( const SfxItemSet
& _rAttributesToApply
)
94 if ( HasChildPathFocus() )
95 getView().HideCursor();
97 bool bOldUpdateMode
= getEngine().GetUpdateMode(); // TODO: guard?
98 getEngine().SetUpdateMode( false );
100 getView().SetAttribs( _rAttributesToApply
);
102 getEngine().SetUpdateMode( bOldUpdateMode
);
103 getView().Invalidate();
105 if ( HasChildPathFocus() )
106 getView().ShowCursor();
108 m_pImpl
->updateAllAttributes();
109 // TODO: maybe we should have a list of attributes which need to be updated
110 // (the handler for the just executed attribute should know)
114 void RichTextControl::enableAttributeNotification( AttributeId _nAttributeId
, ITextAttributeListener
* _pListener
)
116 m_pImpl
->enableAttributeNotification( _nAttributeId
, _pListener
);
120 void RichTextControl::disableAttributeNotification( AttributeId _nAttributeId
)
122 m_pImpl
->disableAttributeNotification( _nAttributeId
);
126 bool RichTextControl::isMappableSlot( SfxSlotId _nSlotId
)
130 case SID_ATTR_PARA_ADJUST_LEFT
:
131 case SID_ATTR_PARA_ADJUST_CENTER
:
132 case SID_ATTR_PARA_ADJUST_RIGHT
:
133 case SID_ATTR_PARA_ADJUST_BLOCK
:
134 case SID_SET_SUPER_SCRIPT
:
135 case SID_SET_SUB_SCRIPT
:
136 case SID_ATTR_PARA_LINESPACE_10
:
137 case SID_ATTR_PARA_LINESPACE_15
:
138 case SID_ATTR_PARA_LINESPACE_20
:
139 case SID_ATTR_PARA_LEFT_TO_RIGHT
:
140 case SID_ATTR_PARA_RIGHT_TO_LEFT
:
141 case SID_TEXTDIRECTION_TOP_TO_BOTTOM
:
142 case SID_TEXTDIRECTION_LEFT_TO_RIGHT
:
143 case SID_ATTR_CHAR_LATIN_FONT
:
144 case SID_ATTR_CHAR_LATIN_FONTHEIGHT
:
145 case SID_ATTR_CHAR_LATIN_LANGUAGE
:
146 case SID_ATTR_CHAR_LATIN_POSTURE
:
147 case SID_ATTR_CHAR_LATIN_WEIGHT
:
154 void RichTextControl::Resize()
156 m_pImpl
->layoutWindow();
161 void RichTextControl::GetFocus()
163 getViewport().GrabFocus();
167 WinBits
RichTextControl::implInitStyle( WinBits nStyle
)
169 if ( !( nStyle
& WB_NOTABSTOP
) )
170 nStyle
|= WB_TABSTOP
;
175 void RichTextControl::StateChanged( StateChangedType _nStateChange
)
177 if ( _nStateChange
== StateChangedType::Style
)
179 SetStyle( implInitStyle( GetStyle() ) );
180 m_pImpl
->notifyStyleChanged();
182 else if ( _nStateChange
== StateChangedType::Zoom
)
184 m_pImpl
->notifyZoomChanged();
186 else if ( _nStateChange
== StateChangedType::InitShow
)
188 m_pImpl
->notifyInitShow();
190 Control::StateChanged( _nStateChange
);
194 bool RichTextControl::PreNotify( NotifyEvent
& _rNEvt
)
196 if ( IsWindowOrChild( _rNEvt
.GetWindow() ) )
198 if ( MouseNotifyEvent::KEYINPUT
== _rNEvt
.GetType() )
200 const ::KeyEvent
* pKeyEvent
= _rNEvt
.GetKeyEvent();
202 sal_uInt16 nCode
= pKeyEvent
->GetKeyCode().GetCode();
203 bool bShift
= pKeyEvent
->GetKeyCode().IsShift();
204 bool bCtrl
= pKeyEvent
->GetKeyCode().IsMod1();
205 bool bAlt
= pKeyEvent
->GetKeyCode().IsMod2();
206 if ( ( KEY_TAB
== nCode
) && bCtrl
&& !bAlt
)
208 // Ctrl-Tab is used to step out of the control
209 // -> build a new key event without the Ctrl-key, and let the very base class handle it
210 vcl::KeyCode
aNewCode( KEY_TAB
, bShift
, false, false, false );
211 ::KeyEvent
aNewEvent( pKeyEvent
->GetCharCode(), aNewCode
);
212 Control::KeyInput( aNewEvent
);
213 return true; // handled
216 #if OSL_DEBUG_LEVEL > 0
217 if ( ( ( KEY_F12
== nCode
)
218 || ( KEY_F11
== nCode
)
224 bool bLoad
= KEY_F11
== nCode
;
227 const sal_Char
* pDescription
;
228 const sal_Char
* pExtension
;
229 EETextFormat eFormat
;
232 { "OASIS OpenDocument (*.xml)", "*.xml", EE_FORMAT_XML
},
233 { "HyperText Markup Language (*.html)", "*.html", EE_FORMAT_HTML
},
234 { "Rich Text format (*.rtf)", "*.rtf", EE_FORMAT_RTF
},
235 { "Text (*.txt)", "*.txt", EE_FORMAT_TEXT
}
238 ::sfx2::FileDialogHelper
aFP( bLoad
? css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE
: css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION
, FileDialogFlags::NONE
, this );
240 for (auto & aExportFormat
: aExportFormats
)
243 OUString::createFromAscii( aExportFormat
.pDescription
),
244 OUString::createFromAscii( aExportFormat
.pExtension
) );
246 ErrCode nResult
= aFP
.Execute();
249 OUString sFileName
= aFP
.GetPath();
250 SvStream
* pStream
= ::utl::UcbStreamHelper::CreateStream(
251 sFileName
, ( bLoad
? StreamMode::READ
: StreamMode::WRITE
| StreamMode::TRUNC
) | StreamMode::SHARE_DENYALL
255 EETextFormat eFormat
= EE_FORMAT_XML
;
256 OUString sFilter
= aFP
.GetCurrentFilter();
257 for (auto & aExportFormat
: aExportFormats
)
259 if ( sFilter
.equalsAscii( aExportFormat
.pDescription
) )
261 eFormat
= aExportFormat
.eFormat
;
267 INetURLObject
aURL( sFileName
);
268 aURL
.removeSegment();
269 getEngine().Read( *pStream
, aURL
.GetMainURL( INetURLObject::NO_DECODE
), eFormat
);
273 getEngine().Write( *pStream
, eFormat
);
278 return true; // handled
283 return Control::PreNotify( _rNEvt
);
287 bool RichTextControl::Notify( NotifyEvent
& _rNEvt
)
290 if ( _rNEvt
.GetType() == MouseNotifyEvent::COMMAND
)
292 const CommandEvent
& rEvent
= *_rNEvt
.GetCommandEvent();
293 bDone
= m_pImpl
->HandleCommand( rEvent
);
295 return bDone
|| Control::Notify( _rNEvt
);
299 void RichTextControl::Draw( OutputDevice
* _pDev
, const Point
& _rPos
, const Size
& _rSize
, DrawFlags _nFlags
)
301 m_pImpl
->Draw( _pDev
, _rPos
, _rSize
, _nFlags
);
305 EditView
& RichTextControl::getView()
307 return *m_pImpl
->getView( RichTextControlImpl::GrantAccess() );
311 const EditView
& RichTextControl::getView() const
313 return *m_pImpl
->getView( RichTextControlImpl::GrantAccess() );
317 EditEngine
& RichTextControl::getEngine() const
319 return *m_pImpl
->getEngine( RichTextControlImpl::GrantAccess() );
323 vcl::Window
& RichTextControl::getViewport() const
325 return *m_pImpl
->getViewport( RichTextControlImpl::GrantAccess() );
329 void RichTextControl::SetReadOnly( bool _bReadOnly
)
331 m_pImpl
->SetReadOnly( _bReadOnly
);
335 bool RichTextControl::IsReadOnly() const
337 return m_pImpl
->IsReadOnly();
341 void RichTextControl::SetBackgroundColor( )
343 m_pImpl
->SetBackgroundColor( );
347 void RichTextControl::SetBackgroundColor( const Color
& _rColor
)
349 m_pImpl
->SetBackgroundColor( _rColor
);
353 void RichTextControl::SetHideInactiveSelection( bool _bHide
)
355 m_pImpl
->SetHideInactiveSelection( _bHide
);
359 bool RichTextControl::GetHideInactiveSelection() const
361 return m_pImpl
->GetHideInactiveSelection( );
368 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */