1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_forms.hxx"
30 #include "clipboarddispatcher.hxx"
31 #include <editeng/editview.hxx>
32 
33 /** === begin UNO includes === **/
34 #include <com/sun/star/lang/DisposedException.hpp>
35 /** === end UNO includes === **/
36 #include <svtools/cliplistener.hxx>
37 #include <svtools/transfer.hxx>
38 
39 //........................................................................
40 namespace frm
41 {
42 //........................................................................
43 
44     using namespace ::com::sun::star::uno;
45     using namespace ::com::sun::star::frame;
46     using namespace ::com::sun::star::lang;
47     using namespace ::com::sun::star::util;
48     using namespace ::com::sun::star::beans;
49 
50 	//====================================================================
51     namespace
52     {
53         static URL createClipboardURL( OClipboardDispatcher::ClipboardFunc _eFunc )
54         {
55             URL aURL;
56             switch ( _eFunc )
57             {
58             case OClipboardDispatcher::eCut:
59                 aURL.Complete = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:Cut" ) );
60                 break;
61             case OClipboardDispatcher::eCopy:
62                 aURL.Complete = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:Copy" ) );
63                 break;
64             case OClipboardDispatcher::ePaste:
65                 aURL.Complete = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:Paste" ) );
66                 break;
67             }
68             return aURL;
69         }
70     }
71 
72 	//====================================================================
73 	//= OClipboardDispatcher
74 	//====================================================================
75 	//--------------------------------------------------------------------
76     OClipboardDispatcher::OClipboardDispatcher( EditView& _rView, ClipboardFunc _eFunc )
77         :ORichTextFeatureDispatcher( _rView, createClipboardURL( _eFunc ) )
78         ,m_eFunc( _eFunc )
79         ,m_bLastKnownEnabled( sal_True )
80     {
81     }
82 
83 	//--------------------------------------------------------------------
84     sal_Bool OClipboardDispatcher::implIsEnabled( ) const
85     {
86         sal_Bool bEnabled = sal_False;
87         switch ( m_eFunc )
88         {
89         case eCut:
90             bEnabled = !getEditView()->IsReadOnly() && getEditView()->HasSelection();
91             break;
92 
93         case eCopy:
94             bEnabled = getEditView()->HasSelection();
95             break;
96 
97         case ePaste:
98             bEnabled = !getEditView()->IsReadOnly();
99             break;
100         }
101         return bEnabled;
102     }
103 
104 	//--------------------------------------------------------------------
105     FeatureStateEvent OClipboardDispatcher::buildStatusEvent() const
106     {
107         FeatureStateEvent aEvent( ORichTextFeatureDispatcher::buildStatusEvent() );
108         aEvent.IsEnabled = implIsEnabled();
109         return aEvent;
110     }
111 
112 	//--------------------------------------------------------------------
113     void OClipboardDispatcher::invalidateFeatureState_Broadcast()
114     {
115         sal_Bool bEnabled = implIsEnabled();
116         if ( m_bLastKnownEnabled == bEnabled )
117             // nothing changed -> no notification
118             return;
119         m_bLastKnownEnabled = bEnabled;
120 
121         ORichTextFeatureDispatcher::invalidateFeatureState_Broadcast();
122     }
123 
124 	//--------------------------------------------------------------------
125     void SAL_CALL OClipboardDispatcher::dispatch( const URL& /*_rURL*/, const Sequence< PropertyValue >& /*Arguments*/ ) throw (RuntimeException)
126     {
127         ::osl::MutexGuard aGuard( m_aMutex );
128         if ( !getEditView() )
129             throw DisposedException();
130 
131         switch ( m_eFunc )
132         {
133         case eCut:
134             getEditView()->Cut();
135             break;
136 
137         case eCopy:
138             getEditView()->Copy();
139             break;
140 
141         case ePaste:
142             getEditView()->Paste();
143             break;
144         }
145     }
146 
147 	//====================================================================
148 	//= OPasteClipboardDispatcher
149 	//====================================================================
150 	//--------------------------------------------------------------------
151     OPasteClipboardDispatcher::OPasteClipboardDispatcher( EditView& _rView )
152         :OClipboardDispatcher( _rView, ePaste )
153         ,m_pClipListener( NULL )
154         ,m_bPastePossible( sal_False )
155     {
156         m_pClipListener = new TransferableClipboardListener( LINK( this, OPasteClipboardDispatcher, OnClipboardChanged ) );
157         m_pClipListener->acquire();
158 		m_pClipListener->AddRemoveListener( _rView.GetWindow(), sal_True );
159 
160         // initial state
161 		TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( _rView.GetWindow() ) );
162 		m_bPastePossible = ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) || aDataHelper.HasFormat( SOT_FORMAT_RTF ) );
163     }
164 
165 	//--------------------------------------------------------------------
166     OPasteClipboardDispatcher::~OPasteClipboardDispatcher()
167     {
168         if ( !isDisposed() )
169         {
170             acquire();
171             dispose();
172         }
173     }
174 
175 	//--------------------------------------------------------------------
176     IMPL_LINK( OPasteClipboardDispatcher, OnClipboardChanged, TransferableDataHelper*, _pDataHelper )
177     {
178         OSL_ENSURE( _pDataHelper, "OPasteClipboardDispatcher::OnClipboardChanged: ooops!" );
179 		m_bPastePossible = _pDataHelper->HasFormat( SOT_FORMAT_STRING )
180                         || _pDataHelper->HasFormat( SOT_FORMAT_RTF );
181 
182         invalidate();
183 
184         return 0L;
185     }
186 
187 	//--------------------------------------------------------------------
188     void OPasteClipboardDispatcher::disposing( ::osl::ClearableMutexGuard& _rClearBeforeNotify )
189     {
190         OSL_ENSURE( getEditView() && getEditView()->GetWindow(), "OPasteClipboardDispatcher::disposing: EditView should not (yet) be disfunctional here!" );
191         if ( getEditView() && getEditView()->GetWindow() && m_pClipListener )
192     		m_pClipListener->AddRemoveListener( getEditView()->GetWindow(), sal_False );
193         m_pClipListener->release();
194         m_pClipListener = NULL;
195 
196         OClipboardDispatcher::disposing( _rClearBeforeNotify );
197     }
198 
199 	//--------------------------------------------------------------------
200     sal_Bool OPasteClipboardDispatcher::implIsEnabled( ) const
201     {
202         return m_bPastePossible && OClipboardDispatcher::implIsEnabled();
203     }
204 
205 //........................................................................
206 }   // namespace frm
207 //........................................................................
208 
209