1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_forms.hxx"
26 #include "clipboarddispatcher.hxx"
27 #include <editeng/editview.hxx>
28 
29 /** === begin UNO includes === **/
30 #include <com/sun/star/lang/DisposedException.hpp>
31 /** === end UNO includes === **/
32 #include <svtools/cliplistener.hxx>
33 #include <svtools/transfer.hxx>
34 
35 //........................................................................
36 namespace frm
37 {
38 //........................................................................
39 
40     using namespace ::com::sun::star::uno;
41     using namespace ::com::sun::star::frame;
42     using namespace ::com::sun::star::lang;
43     using namespace ::com::sun::star::util;
44     using namespace ::com::sun::star::beans;
45 
46 	//====================================================================
47     namespace
48     {
createClipboardURL(OClipboardDispatcher::ClipboardFunc _eFunc)49         static URL createClipboardURL( OClipboardDispatcher::ClipboardFunc _eFunc )
50         {
51             URL aURL;
52             switch ( _eFunc )
53             {
54             case OClipboardDispatcher::eCut:
55                 aURL.Complete = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:Cut" ) );
56                 break;
57             case OClipboardDispatcher::eCopy:
58                 aURL.Complete = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:Copy" ) );
59                 break;
60             case OClipboardDispatcher::ePaste:
61                 aURL.Complete = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:Paste" ) );
62                 break;
63             }
64             return aURL;
65         }
66     }
67 
68 	//====================================================================
69 	//= OClipboardDispatcher
70 	//====================================================================
71 	//--------------------------------------------------------------------
OClipboardDispatcher(EditView & _rView,ClipboardFunc _eFunc)72     OClipboardDispatcher::OClipboardDispatcher( EditView& _rView, ClipboardFunc _eFunc )
73         :ORichTextFeatureDispatcher( _rView, createClipboardURL( _eFunc ) )
74         ,m_eFunc( _eFunc )
75         ,m_bLastKnownEnabled( sal_True )
76     {
77     }
78 
79 	//--------------------------------------------------------------------
implIsEnabled() const80     sal_Bool OClipboardDispatcher::implIsEnabled( ) const
81     {
82         sal_Bool bEnabled = sal_False;
83         switch ( m_eFunc )
84         {
85         case eCut:
86             bEnabled = !getEditView()->IsReadOnly() && getEditView()->HasSelection();
87             break;
88 
89         case eCopy:
90             bEnabled = getEditView()->HasSelection();
91             break;
92 
93         case ePaste:
94             bEnabled = !getEditView()->IsReadOnly();
95             break;
96         }
97         return bEnabled;
98     }
99 
100 	//--------------------------------------------------------------------
buildStatusEvent() const101     FeatureStateEvent OClipboardDispatcher::buildStatusEvent() const
102     {
103         FeatureStateEvent aEvent( ORichTextFeatureDispatcher::buildStatusEvent() );
104         aEvent.IsEnabled = implIsEnabled();
105         return aEvent;
106     }
107 
108 	//--------------------------------------------------------------------
invalidateFeatureState_Broadcast()109     void OClipboardDispatcher::invalidateFeatureState_Broadcast()
110     {
111         sal_Bool bEnabled = implIsEnabled();
112         if ( m_bLastKnownEnabled == bEnabled )
113             // nothing changed -> no notification
114             return;
115         m_bLastKnownEnabled = bEnabled;
116 
117         ORichTextFeatureDispatcher::invalidateFeatureState_Broadcast();
118     }
119 
120 	//--------------------------------------------------------------------
dispatch(const URL &,const Sequence<PropertyValue> &)121     void SAL_CALL OClipboardDispatcher::dispatch( const URL& /*_rURL*/, const Sequence< PropertyValue >& /*Arguments*/ ) throw (RuntimeException)
122     {
123         ::osl::MutexGuard aGuard( m_aMutex );
124         if ( !getEditView() )
125             throw DisposedException();
126 
127         switch ( m_eFunc )
128         {
129         case eCut:
130             getEditView()->Cut();
131             break;
132 
133         case eCopy:
134             getEditView()->Copy();
135             break;
136 
137         case ePaste:
138             getEditView()->Paste();
139             break;
140         }
141     }
142 
143 	//====================================================================
144 	//= OPasteClipboardDispatcher
145 	//====================================================================
146 	//--------------------------------------------------------------------
OPasteClipboardDispatcher(EditView & _rView)147     OPasteClipboardDispatcher::OPasteClipboardDispatcher( EditView& _rView )
148         :OClipboardDispatcher( _rView, ePaste )
149         ,m_pClipListener( NULL )
150         ,m_bPastePossible( sal_False )
151     {
152         m_pClipListener = new TransferableClipboardListener( LINK( this, OPasteClipboardDispatcher, OnClipboardChanged ) );
153         m_pClipListener->acquire();
154 		m_pClipListener->AddRemoveListener( _rView.GetWindow(), sal_True );
155 
156         // initial state
157 		TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( _rView.GetWindow() ) );
158 		m_bPastePossible = ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) || aDataHelper.HasFormat( SOT_FORMAT_RTF ) );
159     }
160 
161 	//--------------------------------------------------------------------
~OPasteClipboardDispatcher()162     OPasteClipboardDispatcher::~OPasteClipboardDispatcher()
163     {
164         if ( !isDisposed() )
165         {
166             acquire();
167             dispose();
168         }
169     }
170 
171 	//--------------------------------------------------------------------
IMPL_LINK(OPasteClipboardDispatcher,OnClipboardChanged,TransferableDataHelper *,_pDataHelper)172     IMPL_LINK( OPasteClipboardDispatcher, OnClipboardChanged, TransferableDataHelper*, _pDataHelper )
173     {
174         OSL_ENSURE( _pDataHelper, "OPasteClipboardDispatcher::OnClipboardChanged: ooops!" );
175 		m_bPastePossible = _pDataHelper->HasFormat( SOT_FORMAT_STRING )
176                         || _pDataHelper->HasFormat( SOT_FORMAT_RTF );
177 
178         invalidate();
179 
180         return 0L;
181     }
182 
183 	//--------------------------------------------------------------------
disposing(::osl::ClearableMutexGuard & _rClearBeforeNotify)184     void OPasteClipboardDispatcher::disposing( ::osl::ClearableMutexGuard& _rClearBeforeNotify )
185     {
186         OSL_ENSURE( getEditView() && getEditView()->GetWindow(), "OPasteClipboardDispatcher::disposing: EditView should not (yet) be disfunctional here!" );
187         if ( getEditView() && getEditView()->GetWindow() && m_pClipListener )
188     		m_pClipListener->AddRemoveListener( getEditView()->GetWindow(), sal_False );
189         m_pClipListener->release();
190         m_pClipListener = NULL;
191 
192         OClipboardDispatcher::disposing( _rClearBeforeNotify );
193     }
194 
195 	//--------------------------------------------------------------------
implIsEnabled() const196     sal_Bool OPasteClipboardDispatcher::implIsEnabled( ) const
197     {
198         return m_bPastePossible && OClipboardDispatcher::implIsEnabled();
199     }
200 
201 //........................................................................
202 }   // namespace frm
203 //........................................................................
204 
205