Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
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"
31 : #endif
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>
40 :
41 : namespace frm
42 : {
43 :
44 20 : RichTextControl::RichTextControl( RichTextEngine* _pEngine, vcl::Window* _pParent, WinBits _nStyle,
45 : ITextAttributeListener* _pTextAttribListener, ITextSelectionListener* _pSelectionListener )
46 : :Control( _pParent, implInitStyle( _nStyle ) )
47 20 : ,m_pImpl( NULL )
48 : {
49 20 : implInit( _pEngine, _pTextAttribListener, _pSelectionListener );
50 20 : }
51 :
52 :
53 20 : void RichTextControl::implInit( RichTextEngine* _pEngine, ITextAttributeListener* _pTextAttribListener, ITextSelectionListener* _pSelectionListener )
54 : {
55 20 : m_pImpl = new RichTextControlImpl( this, _pEngine, _pTextAttribListener, _pSelectionListener );
56 20 : SetCompoundControl( true );
57 20 : }
58 :
59 :
60 60 : RichTextControl::~RichTextControl( )
61 : {
62 20 : disposeOnce();
63 40 : }
64 :
65 20 : void RichTextControl::dispose()
66 : {
67 20 : delete m_pImpl;
68 20 : Control::dispose();
69 20 : }
70 :
71 :
72 0 : AttributeState RichTextControl::getState( AttributeId _nAttributeId ) const
73 : {
74 0 : return m_pImpl->getAttributeState( _nAttributeId );
75 : }
76 :
77 :
78 0 : void RichTextControl::executeAttribute( AttributeId _nAttributeId, const SfxPoolItem* _pArgument )
79 : {
80 0 : SfxItemSet aToApplyAttributes( getView().GetEmptyItemSet() );
81 0 : if ( !m_pImpl->executeAttribute( getView().GetAttribs(), aToApplyAttributes, _nAttributeId, _pArgument, m_pImpl->getSelectedScriptType() ) )
82 : {
83 : OSL_FAIL( "RichTextControl::executeAttribute: cannot handle the given attribute!" );
84 0 : return;
85 : }
86 :
87 0 : applyAttributes( aToApplyAttributes );
88 : }
89 :
90 :
91 0 : void RichTextControl::applyAttributes( const SfxItemSet& _rAttributesToApply )
92 : {
93 : // apply
94 0 : if ( HasChildPathFocus() )
95 0 : getView().HideCursor();
96 :
97 0 : bool bOldUpdateMode = getEngine().GetUpdateMode(); // TODO: guard?
98 0 : getEngine().SetUpdateMode( false );
99 :
100 0 : getView().SetAttribs( _rAttributesToApply );
101 :
102 0 : getEngine().SetUpdateMode( bOldUpdateMode );
103 0 : getView().Invalidate();
104 :
105 0 : if ( HasChildPathFocus() )
106 0 : getView().ShowCursor();
107 :
108 0 : 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)
111 0 : }
112 :
113 :
114 0 : void RichTextControl::enableAttributeNotification( AttributeId _nAttributeId, ITextAttributeListener* _pListener )
115 : {
116 0 : m_pImpl->enableAttributeNotification( _nAttributeId, _pListener );
117 0 : }
118 :
119 :
120 0 : void RichTextControl::disableAttributeNotification( AttributeId _nAttributeId )
121 : {
122 0 : m_pImpl->disableAttributeNotification( _nAttributeId );
123 0 : }
124 :
125 :
126 0 : bool RichTextControl::isMappableSlot( SfxSlotId _nSlotId )
127 : {
128 0 : switch ( _nSlotId )
129 : {
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:
148 0 : return true;
149 : }
150 0 : return false;
151 : }
152 :
153 :
154 0 : void RichTextControl::Resize()
155 : {
156 0 : m_pImpl->layoutWindow();
157 0 : Invalidate();
158 0 : }
159 :
160 :
161 0 : void RichTextControl::GetFocus()
162 : {
163 0 : getViewport().GrabFocus();
164 0 : }
165 :
166 :
167 64 : WinBits RichTextControl::implInitStyle( WinBits nStyle )
168 : {
169 64 : if ( !( nStyle & WB_NOTABSTOP ) )
170 64 : nStyle |= WB_TABSTOP;
171 64 : return nStyle;
172 : }
173 :
174 :
175 218 : void RichTextControl::StateChanged( StateChangedType _nStateChange )
176 : {
177 218 : if ( _nStateChange == StateChangedType::Style )
178 : {
179 44 : SetStyle( implInitStyle( GetStyle() ) );
180 44 : m_pImpl->notifyStyleChanged();
181 : }
182 174 : else if ( _nStateChange == StateChangedType::Zoom )
183 : {
184 0 : m_pImpl->notifyZoomChanged();
185 : }
186 174 : else if ( _nStateChange == StateChangedType::InitShow )
187 : {
188 0 : m_pImpl->notifyInitShow();
189 : }
190 218 : Control::StateChanged( _nStateChange );
191 218 : }
192 :
193 :
194 0 : bool RichTextControl::PreNotify( NotifyEvent& _rNEvt )
195 : {
196 0 : if ( IsWindowOrChild( _rNEvt.GetWindow() ) )
197 : {
198 0 : if ( MouseNotifyEvent::KEYINPUT == _rNEvt.GetType() )
199 : {
200 0 : const ::KeyEvent* pKeyEvent = _rNEvt.GetKeyEvent();
201 :
202 0 : sal_uInt16 nCode = pKeyEvent->GetKeyCode().GetCode();
203 0 : bool bShift = pKeyEvent->GetKeyCode().IsShift();
204 0 : bool bCtrl = pKeyEvent->GetKeyCode().IsMod1();
205 0 : bool bAlt = pKeyEvent->GetKeyCode().IsMod2();
206 0 : if ( ( KEY_TAB == nCode ) && bCtrl && !bAlt )
207 : {
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 0 : vcl::KeyCode aNewCode( KEY_TAB, bShift, false, false, false );
211 0 : ::KeyEvent aNewEvent( pKeyEvent->GetCharCode(), aNewCode );
212 0 : Control::KeyInput( aNewEvent );
213 0 : return true; // handled
214 : }
215 :
216 : #if OSL_DEBUG_LEVEL > 0
217 : if ( ( ( KEY_F12 == nCode )
218 : || ( KEY_F11 == nCode )
219 : )
220 : && bCtrl
221 : && bAlt
222 : )
223 : {
224 : bool bLoad = KEY_F11 == nCode;
225 : struct
226 : {
227 : const sal_Char* pDescription;
228 : const sal_Char* pExtension;
229 : EETextFormat eFormat;
230 : } aExportFormats[] =
231 : {
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 }
236 : };
237 :
238 : ::sfx2::FileDialogHelper aFP( bLoad ? com::sun::star::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE : com::sun::star::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION, 0, this );
239 :
240 : for ( size_t i = 0; i < SAL_N_ELEMENTS( aExportFormats ); ++i )
241 : {
242 : aFP.AddFilter(
243 : OUString::createFromAscii( aExportFormats[i].pDescription ),
244 : OUString::createFromAscii( aExportFormats[i].pExtension ) );
245 : }
246 : ErrCode nResult = aFP.Execute();
247 : if ( nResult == 0 )
248 : {
249 : OUString sFileName = aFP.GetPath();
250 : SvStream* pStream = ::utl::UcbStreamHelper::CreateStream(
251 : sFileName, ( bLoad ? StreamMode::READ : StreamMode::WRITE | StreamMode::TRUNC ) | StreamMode::SHARE_DENYALL
252 : );
253 : if ( pStream )
254 : {
255 : EETextFormat eFormat = EE_FORMAT_XML;
256 : OUString sFilter = aFP.GetCurrentFilter();
257 : for ( size_t i = 0; i < SAL_N_ELEMENTS( aExportFormats ); ++i )
258 : {
259 : if ( sFilter.equalsAscii( aExportFormats[i].pDescription ) )
260 : {
261 : eFormat = aExportFormats[i].eFormat;
262 : break;
263 : }
264 : }
265 : if ( bLoad )
266 : {
267 : INetURLObject aURL( sFileName );
268 : aURL.removeSegment();
269 : getEngine().Read( *pStream, aURL.GetMainURL( INetURLObject::NO_DECODE ), eFormat );
270 : }
271 : else
272 : {
273 : getEngine().Write( *pStream, eFormat );
274 : }
275 : }
276 : DELETEZ( pStream );
277 : }
278 : return true; // handled
279 : }
280 : #endif
281 : }
282 : }
283 0 : return Control::PreNotify( _rNEvt );
284 : }
285 :
286 :
287 99 : bool RichTextControl::Notify( NotifyEvent& _rNEvt )
288 : {
289 99 : bool nDone = false;
290 99 : if ( _rNEvt.GetType() == MouseNotifyEvent::COMMAND )
291 : {
292 0 : const CommandEvent& rEvent = *_rNEvt.GetCommandEvent();
293 0 : nDone = m_pImpl->HandleCommand( rEvent );
294 : }
295 99 : return nDone || Control::Notify( _rNEvt );
296 : }
297 :
298 :
299 133 : void RichTextControl::Draw( OutputDevice* _pDev, const Point& _rPos, const Size& _rSize, DrawFlags _nFlags )
300 : {
301 133 : m_pImpl->Draw( _pDev, _rPos, _rSize, _nFlags );
302 133 : }
303 :
304 :
305 0 : EditView& RichTextControl::getView()
306 : {
307 0 : return *m_pImpl->getView( RichTextControlImpl::GrantAccess() );
308 : }
309 :
310 :
311 0 : const EditView& RichTextControl::getView() const
312 : {
313 0 : return *m_pImpl->getView( RichTextControlImpl::GrantAccess() );
314 : }
315 :
316 :
317 0 : EditEngine& RichTextControl::getEngine() const
318 : {
319 0 : return *m_pImpl->getEngine( RichTextControlImpl::GrantAccess() );
320 : }
321 :
322 :
323 0 : vcl::Window& RichTextControl::getViewport() const
324 : {
325 0 : return *m_pImpl->getViewport( RichTextControlImpl::GrantAccess() );
326 : }
327 :
328 :
329 24 : void RichTextControl::SetReadOnly( bool _bReadOnly )
330 : {
331 24 : m_pImpl->SetReadOnly( _bReadOnly );
332 24 : }
333 :
334 :
335 24 : bool RichTextControl::IsReadOnly() const
336 : {
337 24 : return m_pImpl->IsReadOnly();
338 : }
339 :
340 :
341 20 : void RichTextControl::SetBackgroundColor( )
342 : {
343 20 : m_pImpl->SetBackgroundColor( );
344 20 : }
345 :
346 :
347 0 : void RichTextControl::SetBackgroundColor( const Color& _rColor )
348 : {
349 0 : m_pImpl->SetBackgroundColor( _rColor );
350 0 : }
351 :
352 :
353 24 : void RichTextControl::SetHideInactiveSelection( bool _bHide )
354 : {
355 24 : m_pImpl->SetHideInactiveSelection( _bHide );
356 24 : }
357 :
358 :
359 24 : bool RichTextControl::GetHideInactiveSelection() const
360 : {
361 24 : return m_pImpl->GetHideInactiveSelection( );
362 : }
363 :
364 :
365 138 : } // namespace frm
366 :
367 :
368 :
369 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|