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 <vcl/waitobj.hxx>
21 : #include <cppuhelper/interfacecontainer.hxx>
22 : #include <com/sun/star/util/URL.hpp>
23 : #include <vcl/msgbox.hxx>
24 : #include <tools/debug.hxx>
25 : #include <vcl/stdtext.hxx>
26 : #include <comphelper/types.hxx>
27 : #include <comphelper/sequence.hxx>
28 : #include "framectr.hxx"
29 : #include "datman.hxx"
30 : #include "bibresid.hxx"
31 : #include "bib.hrc"
32 : #include <toolkit/helper/vclunohelper.hxx>
33 : #include "bibconfig.hxx"
34 : #include <cppuhelper/implbase1.hxx> // helper for implementations
35 : #include <vcl/svapp.hxx>
36 : #include "bibliography.hrc"
37 : #include <comphelper/processfactory.hxx>
38 : #include <com/sun/star/form/XConfirmDeleteListener.hpp>
39 : #include <com/sun/star/form/runtime/XFormController.hpp>
40 : #include <com/sun/star/beans/PropertyState.hpp>
41 : #include <com/sun/star/beans/PropertyValue.hpp>
42 : #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
43 : #include <com/sun/star/sdbcx/Privilege.hpp>
44 : #include <com/sun/star/sdbc/XResultSetUpdate.hpp>
45 : #include <com/sun/star/sdb/FilterDialog.hpp>
46 : #include <com/sun/star/sdb/RowChangeAction.hpp>
47 : #include <com/sun/star/frame/CommandGroup.hpp>
48 : #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
49 : #include <sot/exchange.hxx>
50 : #include <sot/formats.hxx>
51 : #include <vcl/edit.hxx>
52 : #include <osl/mutex.hxx>
53 :
54 : #include <boost/unordered_map.hpp>
55 :
56 : using namespace osl;
57 : using namespace cppu;
58 : using namespace com::sun::star::sdbc;
59 : using namespace com::sun::star::frame;
60 : using namespace com::sun::star::uno;
61 : using namespace com::sun::star;
62 :
63 : using ::rtl::OUString;
64 :
65 : #define C2U(cChar) OUString::createFromAscii(cChar)
66 :
67 : struct DispatchInfo
68 : {
69 : const char* pCommand;
70 : sal_Int16 nGroupId;
71 : sal_Bool bActiveConnection;
72 : };
73 :
74 : struct CacheDispatchInfo
75 : {
76 : sal_Int16 nGroupId;
77 : sal_Bool bActiveConnection;
78 : };
79 :
80 : // Attention: commands must be sorted by command groups. Implementation is dependent
81 : // on this!!
82 : static DispatchInfo SupportedCommandsArray[] =
83 : {
84 : { ".uno:Undo" , frame::CommandGroup::EDIT , sal_False },
85 : { ".uno:Cut" , frame::CommandGroup::EDIT , sal_False },
86 : { ".uno:Copy" , frame::CommandGroup::EDIT , sal_False },
87 : { ".uno:Paste" , frame::CommandGroup::EDIT , sal_False },
88 : { ".uno:SelectAll" , frame::CommandGroup::EDIT , sal_False },
89 : { ".uno:CloseDoc" , frame::CommandGroup::DOCUMENT , sal_False },
90 : { ".uno:StatusBarVisible" , frame::CommandGroup::VIEW , sal_False },
91 : { ".uno:AvailableToolbars" , frame::CommandGroup::VIEW , sal_False },
92 : { ".uno:Bib/standardFilter" , frame::CommandGroup::DATA , sal_True },
93 : { ".uno:Bib/DeleteRecord" , frame::CommandGroup::DATA , sal_True },
94 : { ".uno:Bib/InsertRecord" , frame::CommandGroup::DATA , sal_True },
95 : { ".uno:Bib/query" , frame::CommandGroup::DATA , sal_True },
96 : { ".uno:Bib/autoFilter" , frame::CommandGroup::DATA , sal_True },
97 : { ".uno:Bib/source" , frame::CommandGroup::DATA , sal_True },
98 : { ".uno:Bib/removeFilter" , frame::CommandGroup::DATA , sal_True },
99 : { ".uno:Bib/sdbsource" , frame::CommandGroup::DATA , sal_True },
100 : { ".uno:Bib/Mapping" , frame::CommandGroup::DATA , sal_True },
101 : { 0 , 0 , sal_False }
102 : };
103 :
104 : typedef ::boost::unordered_map< ::rtl::OUString, CacheDispatchInfo, rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > CmdToInfoCache;
105 :
106 0 : const CmdToInfoCache& GetCommandToInfoCache()
107 : {
108 : static sal_Bool bCacheInitialized = sal_False;
109 0 : static CmdToInfoCache aCmdToInfoCache;
110 :
111 0 : if ( !bCacheInitialized )
112 : {
113 0 : ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
114 0 : if ( !bCacheInitialized )
115 : {
116 0 : sal_Int32 i( 0 );
117 0 : while ( SupportedCommandsArray[i].pCommand != 0 )
118 : {
119 0 : rtl::OUString aCommand( rtl::OUString::createFromAscii( SupportedCommandsArray[i].pCommand ));
120 :
121 : CacheDispatchInfo aDispatchInfo;
122 0 : aDispatchInfo.nGroupId = SupportedCommandsArray[i].nGroupId;
123 0 : aDispatchInfo.bActiveConnection = SupportedCommandsArray[i].bActiveConnection;
124 0 : aCmdToInfoCache.insert( CmdToInfoCache::value_type( aCommand, aDispatchInfo ));
125 0 : ++i;
126 0 : }
127 0 : bCacheInitialized = sal_True;
128 0 : }
129 : }
130 :
131 0 : return aCmdToInfoCache;
132 : }
133 :
134 :
135 : class BibFrameCtrl_Impl : public cppu::WeakImplHelper1 < XFrameActionListener >
136 : {
137 : public:
138 : Mutex aMutex;
139 : OMultiTypeInterfaceContainerHelper aLC;
140 :
141 : BibFrameController_Impl* pController;
142 :
143 0 : BibFrameCtrl_Impl()
144 : : aLC( aMutex )
145 0 : , pController(0)
146 0 : {}
147 :
148 : ~BibFrameCtrl_Impl();
149 :
150 : virtual void SAL_CALL frameAction(const FrameActionEvent& aEvent) throw( RuntimeException );
151 : virtual void SAL_CALL disposing( const lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
152 : };
153 :
154 :
155 0 : BibFrameCtrl_Impl::~BibFrameCtrl_Impl()
156 : {
157 0 : }
158 :
159 0 : void BibFrameCtrl_Impl::frameAction(const FrameActionEvent& aEvent) throw( uno::RuntimeException )
160 : {
161 0 : if ( pController && aEvent.Frame == pController->getFrame())
162 : {
163 0 : if(aEvent.Action == FrameAction_FRAME_ACTIVATED)
164 : {
165 0 : pController->activate();
166 : }
167 0 : else if(aEvent.Action == FrameAction_FRAME_DEACTIVATING)
168 : {
169 0 : pController->deactivate();
170 : }
171 : }
172 0 : }
173 :
174 0 : void BibFrameCtrl_Impl::disposing( const lang::EventObject& /*Source*/ )
175 : throw (::com::sun::star::uno::RuntimeException)
176 : {
177 0 : ::SolarMutexGuard aGuard;
178 0 : if ( pController )
179 0 : pController->getFrame()->removeFrameActionListener( this );
180 0 : }
181 :
182 0 : BibFrameController_Impl::BibFrameController_Impl( const uno::Reference< awt::XWindow > & xComponent,
183 : BibDataManager* pDataManager)
184 : :xWindow( xComponent )
185 : ,m_xDatMan( pDataManager )
186 : ,pDatMan( pDataManager )
187 0 : ,pBibMod(NULL)
188 : {
189 0 : Window* pParent = VCLUnoHelper::GetWindow( xWindow );
190 0 : pParent->SetUniqueId(UID_BIB_FRAME_WINDOW);
191 0 : bDisposing=sal_False;
192 0 : bHierarchical=sal_True;
193 0 : pImp = new BibFrameCtrl_Impl;
194 0 : pImp->pController = this;
195 0 : pImp->acquire();
196 0 : }
197 :
198 0 : BibFrameController_Impl::~BibFrameController_Impl()
199 : {
200 0 : pImp->pController = NULL;
201 0 : pImp->release();
202 0 : delete pDatMan;
203 0 : if(pBibMod)
204 0 : CloseBibModul(pBibMod);
205 0 : }
206 :
207 0 : ::rtl::OUString SAL_CALL BibFrameController_Impl::getImplementationName() throw (::com::sun::star::uno::RuntimeException)
208 : {
209 0 : return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.extensions.Bibliography"));
210 : }
211 :
212 0 : sal_Bool SAL_CALL BibFrameController_Impl::supportsService( const ::rtl::OUString& sServiceName ) throw (::com::sun::star::uno::RuntimeException)
213 : {
214 0 : return ( sServiceName == "com.sun.star.frame.Bibliography" || sServiceName == "com.sun.star.frame.Controller" );
215 : }
216 :
217 0 : ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL BibFrameController_Impl::getSupportedServiceNames() throw (::com::sun::star::uno::RuntimeException)
218 : {
219 : // return only top level services ...
220 : // base services are included there and should be asked by uno-rtti.
221 0 : ::com::sun::star::uno::Sequence< ::rtl::OUString > lNames(1);
222 0 : lNames[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Bibliography"));
223 0 : return lNames;
224 : }
225 :
226 0 : void BibFrameController_Impl::attachFrame( const uno::Reference< XFrame > & xArg ) throw (::com::sun::star::uno::RuntimeException)
227 : {
228 0 : xFrame = xArg;
229 0 : xFrame->addFrameActionListener( pImp );
230 0 : }
231 :
232 0 : sal_Bool BibFrameController_Impl::attachModel( const uno::Reference< XModel > & /*xModel*/ ) throw (::com::sun::star::uno::RuntimeException)
233 : {
234 0 : return sal_False;
235 : }
236 :
237 0 : sal_Bool BibFrameController_Impl::suspend( sal_Bool bSuspend ) throw (::com::sun::star::uno::RuntimeException)
238 : {
239 0 : if ( bSuspend )
240 0 : getFrame()->removeFrameActionListener( pImp );
241 : else
242 0 : getFrame()->addFrameActionListener( pImp );
243 0 : return sal_True;
244 : }
245 :
246 0 : uno::Any BibFrameController_Impl::getViewData() throw (::com::sun::star::uno::RuntimeException)
247 : {
248 0 : return uno::Any();
249 : }
250 :
251 0 : void BibFrameController_Impl::restoreViewData( const uno::Any& /*Value*/ ) throw (::com::sun::star::uno::RuntimeException)
252 : {
253 0 : }
254 :
255 0 : uno::Reference< XFrame > BibFrameController_Impl::getFrame() throw (::com::sun::star::uno::RuntimeException)
256 : {
257 0 : return xFrame;
258 : }
259 :
260 0 : uno::Reference< XModel > BibFrameController_Impl::getModel() throw (::com::sun::star::uno::RuntimeException)
261 : {
262 0 : return uno::Reference< XModel > ();
263 : }
264 :
265 0 : void BibFrameController_Impl::dispose() throw (::com::sun::star::uno::RuntimeException)
266 : {
267 0 : bDisposing = sal_True;
268 0 : lang::EventObject aObject;
269 0 : aObject.Source = (XController*)this;
270 0 : pImp->aLC.disposeAndClear(aObject);
271 0 : m_xDatMan = 0;
272 0 : pDatMan = 0;
273 0 : aStatusListeners.clear();
274 0 : }
275 :
276 0 : void BibFrameController_Impl::addEventListener( const uno::Reference< lang::XEventListener > & aListener ) throw (::com::sun::star::uno::RuntimeException)
277 : {
278 0 : pImp->aLC.addInterface( ::getCppuType((const Reference< lang::XEventListener >*)0), aListener );
279 0 : }
280 :
281 0 : void BibFrameController_Impl::removeEventListener( const uno::Reference< lang::XEventListener > & aListener ) throw (::com::sun::star::uno::RuntimeException)
282 : {
283 0 : pImp->aLC.removeInterface( ::getCppuType((const Reference< lang::XEventListener >*)0), aListener );
284 0 : }
285 :
286 0 : uno::Reference< frame::XDispatch > BibFrameController_Impl::queryDispatch( const util::URL& aURL, const rtl::OUString& /*aTarget*/, sal_Int32 /*nSearchFlags*/ ) throw (::com::sun::star::uno::RuntimeException)
287 : {
288 0 : if ( !bDisposing )
289 : {
290 0 : const CmdToInfoCache& rCmdCache = GetCommandToInfoCache();
291 0 : CmdToInfoCache::const_iterator pIter = rCmdCache.find( aURL.Complete );
292 0 : if ( pIter != rCmdCache.end() )
293 : {
294 0 : if (( pDatMan->HasActiveConnection() ) ||
295 0 : ( !pIter->second.bActiveConnection ))
296 0 : return (frame::XDispatch*) this;
297 : }
298 : }
299 :
300 0 : return uno::Reference< frame::XDispatch > ();
301 : }
302 :
303 0 : uno::Sequence<uno::Reference< XDispatch > > BibFrameController_Impl::queryDispatches( const uno::Sequence<DispatchDescriptor>& aDescripts ) throw (::com::sun::star::uno::RuntimeException)
304 : {
305 0 : uno::Sequence< uno::Reference< XDispatch > > aDispatches( aDescripts.getLength() );
306 0 : for ( sal_Int32 i=0; i<aDescripts.getLength(); ++i )
307 0 : aDispatches[i] = queryDispatch( aDescripts[i].FeatureURL, aDescripts[i].FrameName, aDescripts[i].SearchFlags );
308 0 : return aDispatches;
309 : }
310 :
311 0 : uno::Sequence< ::sal_Int16 > SAL_CALL BibFrameController_Impl::getSupportedCommandGroups()
312 : throw (::com::sun::star::uno::RuntimeException)
313 : {
314 0 : uno::Sequence< ::sal_Int16 > aDispatchInfo( 4 );
315 :
316 0 : aDispatchInfo[0] = frame::CommandGroup::EDIT;
317 0 : aDispatchInfo[1] = frame::CommandGroup::DOCUMENT;
318 0 : aDispatchInfo[2] = frame::CommandGroup::DATA;
319 0 : aDispatchInfo[3] = frame::CommandGroup::VIEW;
320 :
321 0 : return aDispatchInfo;
322 : }
323 :
324 0 : uno::Sequence< frame::DispatchInformation > SAL_CALL BibFrameController_Impl::getConfigurableDispatchInformation( ::sal_Int16 nCommandGroup )
325 : throw (::com::sun::star::uno::RuntimeException)
326 : {
327 0 : const CmdToInfoCache& rCmdCache = GetCommandToInfoCache();
328 :
329 0 : sal_Bool bGroupFound( sal_False );
330 0 : frame::DispatchInformation aDispatchInfo;
331 0 : std::list< frame::DispatchInformation > aDispatchInfoList;
332 :
333 0 : if (( nCommandGroup == frame::CommandGroup::EDIT ) ||
334 : ( nCommandGroup == frame::CommandGroup::DOCUMENT ) ||
335 : ( nCommandGroup == frame::CommandGroup::DATA ) ||
336 : ( nCommandGroup == frame::CommandGroup::VIEW ))
337 : {
338 0 : CmdToInfoCache::const_iterator pIter = rCmdCache.begin();
339 0 : while ( pIter != rCmdCache.end() )
340 : {
341 0 : if ( pIter->second.nGroupId == nCommandGroup )
342 : {
343 0 : bGroupFound = sal_True;
344 0 : aDispatchInfo.Command = pIter->first;
345 0 : aDispatchInfo.GroupId = pIter->second.nGroupId;
346 0 : aDispatchInfoList.push_back( aDispatchInfo );
347 : }
348 0 : else if ( bGroupFound )
349 0 : break;
350 :
351 0 : ++pIter;
352 : }
353 : }
354 :
355 : ::com::sun::star::uno::Sequence< ::com::sun::star::frame::DispatchInformation > aSeq =
356 0 : comphelper::containerToSequence< ::com::sun::star::frame::DispatchInformation, std::list< ::com::sun::star::frame::DispatchInformation > >( aDispatchInfoList );
357 :
358 0 : return aSeq;
359 : }
360 :
361 0 : sal_Bool canInsertRecords(const Reference< beans::XPropertySet>& _rxCursorSet)
362 : {
363 0 : sal_Int32 nPriv = 0;
364 0 : _rxCursorSet->getPropertyValue(C2U("Privileges")) >>= nPriv;
365 0 : return ((_rxCursorSet.is() && (nPriv & sdbcx::Privilege::INSERT) != 0));
366 : }
367 :
368 0 : sal_Bool BibFrameController_Impl::SaveModified(const Reference< form::runtime::XFormController>& xController)
369 : {
370 0 : if (!xController.is())
371 0 : return sal_False;
372 :
373 0 : Reference< XResultSetUpdate> _xCursor = Reference< XResultSetUpdate>(xController->getModel(), UNO_QUERY);
374 :
375 0 : if (!_xCursor.is())
376 0 : return sal_False;
377 :
378 0 : Reference< beans::XPropertySet> _xSet = Reference< beans::XPropertySet>(_xCursor, UNO_QUERY);
379 0 : if (!_xSet.is())
380 0 : return sal_False;
381 :
382 : // need to save?
383 0 : sal_Bool bIsNew = ::comphelper::getBOOL(_xSet->getPropertyValue(C2U("IsNew")));
384 0 : sal_Bool bIsModified = ::comphelper::getBOOL(_xSet->getPropertyValue(C2U("IsModified")));
385 0 : sal_Bool bResult = !bIsModified;
386 0 : if (bIsModified)
387 : {
388 : try
389 : {
390 0 : if (bIsNew)
391 0 : _xCursor->insertRow();
392 : else
393 0 : _xCursor->updateRow();
394 0 : bResult = sal_True;
395 : }
396 0 : catch(const Exception&)
397 : {
398 : OSL_FAIL("SaveModified: Exception occurred!");
399 : }
400 : }
401 0 : return bResult;
402 : }
403 :
404 0 : static Window* lcl_GetFocusChild( Window* pParent )
405 : {
406 0 : sal_uInt16 nChildren = pParent->GetChildCount();
407 0 : for( sal_uInt16 nChild = 0; nChild < nChildren; ++nChild)
408 : {
409 0 : Window* pChild = pParent->GetChild( nChild );
410 0 : if(pChild->HasFocus())
411 0 : return pChild;
412 0 : Window* pSubChild = lcl_GetFocusChild( pChild );
413 0 : if(pSubChild)
414 0 : return pSubChild;
415 : }
416 0 : return 0;
417 : }
418 :
419 : //class XDispatch
420 0 : void BibFrameController_Impl::dispatch(const util::URL& _rURL, const uno::Sequence< beans::PropertyValue >& aArgs) throw (::com::sun::star::uno::RuntimeException)
421 : {
422 0 : if ( !bDisposing )
423 : {
424 0 : ::SolarMutexGuard aGuard;
425 0 : Window* pParent = VCLUnoHelper::GetWindow( xWindow );
426 0 : WaitObject aWaitObject( pParent );
427 :
428 0 : String aCommand( _rURL.Path);
429 0 : if(aCommand.EqualsAscii("Bib/Mapping"))
430 : {
431 0 : pDatMan->CreateMappingDialog(pParent);
432 : }
433 0 : else if(aCommand.EqualsAscii("Bib/source"))
434 : {
435 0 : ChangeDataSource(aArgs);
436 : }
437 0 : else if(aCommand.EqualsAscii("Bib/sdbsource"))
438 : {
439 0 : rtl::OUString aURL = pDatMan->CreateDBChangeDialog(pParent);
440 0 : if(!aURL.isEmpty())
441 : {
442 : try
443 : {
444 0 : uno::Sequence< beans::PropertyValue > aNewDataSource(2);
445 0 : beans::PropertyValue* pProps = aNewDataSource.getArray();
446 0 : pProps[0].Value <<= rtl::OUString();
447 0 : pProps[1].Value <<= aURL;
448 0 : ChangeDataSource(aNewDataSource);
449 : }
450 0 : catch(const Exception&)
451 : {
452 : OSL_FAIL("Exception catched while changing the data source");
453 : }
454 0 : }
455 : }
456 0 : else if(aCommand.EqualsAscii("Bib/autoFilter"))
457 : {
458 0 : sal_uInt16 nCount = aStatusListeners.size();
459 0 : for ( sal_uInt16 n=0; n<nCount; n++ )
460 : {
461 0 : BibStatusDispatch *pObj = &aStatusListeners[n];
462 0 : if ( pObj->aURL.Path == C2U("Bib/removeFilter") )
463 : {
464 0 : FeatureStateEvent aEvent;
465 0 : aEvent.FeatureURL = pObj->aURL;
466 0 : aEvent.IsEnabled = sal_True;
467 0 : aEvent.Requery = sal_False;
468 0 : aEvent.Source = (XDispatch *) this;
469 0 : pObj->xListener->statusChanged( aEvent );
470 : //break; because there are more than one
471 : }
472 : }
473 :
474 0 : const beans::PropertyValue* pPropertyValue = aArgs.getConstArray();
475 0 : uno::Any aValue=pPropertyValue[0].Value;
476 0 : rtl::OUString aQuery;
477 0 : aValue >>= aQuery;
478 :
479 0 : aValue=pPropertyValue[1].Value;
480 0 : rtl::OUString aQueryField;
481 0 : aValue >>= aQueryField;
482 0 : BibConfig* pConfig = BibModul::GetConfig();
483 0 : pConfig->setQueryField(aQueryField);
484 0 : pDatMan->startQueryWith(aQuery);
485 : }
486 0 : else if(aCommand.EqualsAscii("Bib/standardFilter"))
487 : {
488 : try
489 : {
490 0 : uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
491 :
492 : // create the dialog object
493 0 : uno::Reference< ui::dialogs::XExecutableDialog > xDialog = sdb::FilterDialog::createWithQuery(xContext, pDatMan->getParser(),
494 0 : Reference<sdbc::XRowSet>(pDatMan->getForm(), uno::UNO_QUERY_THROW), xWindow);
495 : // execute it
496 0 : if ( xDialog->execute( ) )
497 : {
498 : // the dialog has been executed successfully, and the filter on the query composer
499 : // has been changed
500 0 : ::rtl::OUString sNewFilter = pDatMan->getParser()->getFilter();
501 0 : pDatMan->setFilter( sNewFilter );
502 0 : }
503 : }
504 0 : catch( const uno::Exception& )
505 : {
506 : OSL_FAIL( "BibFrameController_Impl::dispatch: caught an exception!" );
507 : }
508 :
509 0 : sal_uInt16 nCount = aStatusListeners.size();
510 0 : for ( sal_uInt16 n=0; n<nCount; n++ )
511 : {
512 0 : BibStatusDispatch *pObj = &aStatusListeners[n];
513 0 : if ( pObj->aURL.Path == C2U("Bib/removeFilter") && pDatMan->getParser().is())
514 : {
515 0 : FeatureStateEvent aEvent;
516 0 : aEvent.FeatureURL = pObj->aURL;
517 0 : aEvent.IsEnabled = !pDatMan->getParser()->getFilter().isEmpty();
518 0 : aEvent.Requery = sal_False;
519 0 : aEvent.Source = (XDispatch *) this;
520 0 : pObj->xListener->statusChanged( aEvent );
521 : }
522 : }
523 : }
524 0 : else if(aCommand.EqualsAscii("Bib/removeFilter"))
525 : {
526 0 : RemoveFilter();
527 : }
528 0 : else if( _rURL.Complete == "slot:5503" || aCommand.EqualsAscii("CloseDoc") )
529 : {
530 : Application::PostUserEvent( STATIC_LINK( this, BibFrameController_Impl,
531 0 : DisposeHdl ), 0 );
532 :
533 : }
534 0 : else if(aCommand.EqualsAscii("Bib/InsertRecord"))
535 : {
536 0 : Reference<form::runtime::XFormController > xFormCtrl = pDatMan->GetFormController();
537 0 : if(SaveModified(xFormCtrl))
538 : {
539 : try
540 : {
541 0 : Reference< sdbc::XResultSet > xCursor( pDatMan->getForm(), UNO_QUERY );
542 0 : xCursor->last();
543 :
544 0 : Reference< XResultSetUpdate > xUpdateCursor( pDatMan->getForm(), UNO_QUERY );
545 0 : xUpdateCursor->moveToInsertRow();
546 : }
547 0 : catch(const Exception&)
548 : {
549 : OSL_FAIL("Exception in last() or moveToInsertRow()");
550 : }
551 0 : }
552 : }
553 0 : else if(aCommand.EqualsAscii("Bib/DeleteRecord"))
554 : {
555 0 : Reference< ::com::sun::star::sdbc::XResultSet > xCursor(pDatMan->getForm(), UNO_QUERY);
556 0 : Reference< XResultSetUpdate > xUpdateCursor(xCursor, UNO_QUERY);
557 0 : Reference< beans::XPropertySet > xSet(pDatMan->getForm(), UNO_QUERY);
558 0 : sal_Bool bIsNew = ::comphelper::getBOOL(xSet->getPropertyValue(C2U("IsNew")));
559 0 : if(!bIsNew)
560 : {
561 0 : sal_uInt32 nCount = 0;
562 0 : xSet->getPropertyValue(C2U("RowCount")) >>= nCount;
563 : // naechste position festellen
564 0 : sal_Bool bSuccess = sal_False;
565 0 : sal_Bool bLeft = sal_False;
566 0 : sal_Bool bRight = sal_False;
567 : try
568 : {
569 0 : bLeft = xCursor->isLast() && nCount > 1;
570 0 : bRight= !xCursor->isLast();
571 : // ask for confirmation
572 0 : Reference< frame::XController > xCtrl = pImp->pController;
573 0 : Reference< form::XConfirmDeleteListener > xConfirm(pDatMan->GetFormController(),UNO_QUERY);
574 0 : if (xConfirm.is())
575 : {
576 0 : sdb::RowChangeEvent aEvent;
577 0 : aEvent.Source = Reference< XInterface > (xCursor, UNO_QUERY);
578 0 : aEvent.Action = sdb::RowChangeAction::DELETE;
579 0 : aEvent.Rows = 1;
580 0 : bSuccess = xConfirm->confirmDelete(aEvent);
581 : }
582 :
583 : // das Ding loeschen
584 0 : if (bSuccess)
585 0 : xUpdateCursor->deleteRow();
586 : }
587 0 : catch(const Exception&)
588 : {
589 0 : bSuccess = sal_False;
590 : }
591 0 : if (bSuccess)
592 : {
593 0 : if (bLeft || bRight)
594 0 : xCursor->relative(bRight ? 1 : -1);
595 : else
596 : {
597 0 : sal_Bool bCanInsert = canInsertRecords(xSet);
598 : // kann noch ein Datensatz eingefuegt weden
599 : try
600 : {
601 0 : if (bCanInsert)
602 0 : xUpdateCursor->moveToInsertRow();
603 : else
604 : // Datensatz bewegen um Stati neu zu setzen
605 0 : xCursor->first();
606 : }
607 0 : catch(const Exception&)
608 : {
609 : OSL_FAIL("DeleteRecord : exception caught !");
610 : }
611 : }
612 : }
613 0 : }
614 : }
615 0 : else if(aCommand.EqualsAscii("Cut"))
616 : {
617 0 : Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
618 0 : if(pChild)
619 : {
620 0 : KeyEvent aEvent( 0, KEYFUNC_CUT );
621 0 : pChild->KeyInput( aEvent );
622 : }
623 : }
624 0 : else if(aCommand.EqualsAscii("Copy"))
625 : {
626 0 : Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
627 0 : if(pChild)
628 : {
629 0 : KeyEvent aEvent( 0, KEYFUNC_COPY );
630 0 : pChild->KeyInput( aEvent );
631 : }
632 : }
633 0 : else if(aCommand.EqualsAscii("Paste"))
634 : {
635 0 : Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
636 0 : if(pChild)
637 : {
638 0 : KeyEvent aEvent( 0, KEYFUNC_PASTE );
639 0 : pChild->KeyInput( aEvent );
640 : }
641 0 : }
642 : }
643 0 : }
644 0 : IMPL_STATIC_LINK( BibFrameController_Impl, DisposeHdl, void*, EMPTYARG )
645 : {
646 0 : pThis->xFrame->dispose();
647 0 : return 0;
648 : };
649 :
650 : //-----------------------------------------------------------------------------
651 0 : void BibFrameController_Impl::addStatusListener(
652 : const uno::Reference< frame::XStatusListener > & aListener,
653 : const util::URL& aURL)
654 : throw (::com::sun::star::uno::RuntimeException)
655 : {
656 0 : BibConfig* pConfig = BibModul::GetConfig();
657 : // create a new Reference and insert into listener array
658 0 : aStatusListeners.push_back( new BibStatusDispatch( aURL, aListener ) );
659 :
660 : // den ersten Status synchron zusenden
661 0 : FeatureStateEvent aEvent;
662 0 : aEvent.FeatureURL = aURL;
663 0 : aEvent.Requery = sal_False;
664 0 : aEvent.Source = (XDispatch *) this;
665 0 : if ( aURL.Path == C2U("StatusBarVisible") )
666 : {
667 0 : aEvent.IsEnabled = sal_False;
668 0 : aEvent.State <<= sal_Bool( sal_False );
669 : }
670 0 : else if ( aURL.Path == C2U("Bib/hierarchical") )
671 : {
672 0 : aEvent.IsEnabled = sal_True;
673 0 : const char* pHier = bHierarchical? "" : "*" ;
674 0 : aEvent.State <<= rtl::OUString::createFromAscii(pHier);
675 : }
676 0 : else if(aURL.Path == C2U("Bib/MenuFilter"))
677 : {
678 0 : aEvent.IsEnabled = sal_True;
679 0 : aEvent.FeatureDescriptor=pDatMan->getQueryField();
680 :
681 0 : uno::Sequence<rtl::OUString> aStringSeq=pDatMan->getQueryFields();
682 0 : aEvent.State.setValue(&aStringSeq,::getCppuType((uno::Sequence<rtl::OUString>*)0));
683 :
684 : }
685 0 : else if ( aURL.Path == C2U("Bib/source"))
686 : {
687 0 : aEvent.IsEnabled = sal_True;
688 0 : aEvent.FeatureDescriptor=pDatMan->getActiveDataTable();
689 :
690 0 : uno::Sequence<rtl::OUString> aStringSeq=pDatMan->getDataSources();
691 0 : aEvent.State.setValue(&aStringSeq,::getCppuType((uno::Sequence<rtl::OUString>*)0));
692 : }
693 0 : else if( aURL.Path == "Bib/sdbsource" ||
694 0 : aURL.Path == "Bib/Mapping" ||
695 0 : aURL.Path == "Bib/autoFilter" ||
696 0 : aURL.Path == "Bib/standardFilter" )
697 : {
698 0 : aEvent.IsEnabled = sal_True;
699 : }
700 0 : else if(aURL.Path == C2U("Bib/query"))
701 : {
702 0 : aEvent.IsEnabled = sal_True;
703 0 : aEvent.State <<= pConfig->getQueryText();
704 : }
705 0 : else if (aURL.Path == C2U("Bib/removeFilter") )
706 : {
707 0 : rtl::OUString aFilterStr=pDatMan->getFilter();
708 0 : aEvent.IsEnabled = !aFilterStr.isEmpty();
709 : }
710 0 : else if(aURL.Path == C2U("Cut"))
711 : {
712 0 : Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
713 0 : Edit* pEdit = dynamic_cast<Edit*>( pChild );
714 0 : if( pEdit )
715 0 : aEvent.IsEnabled = !pEdit->IsReadOnly() && pEdit->GetSelection().Len();
716 : }
717 0 : if(aURL.Path == C2U("Copy"))
718 : {
719 0 : Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
720 0 : Edit* pEdit = dynamic_cast<Edit*>( pChild );
721 0 : if( pEdit )
722 0 : aEvent.IsEnabled = pEdit->GetSelection().Len() > 0;
723 : }
724 0 : else if(aURL.Path == C2U("Paste") )
725 : {
726 0 : aEvent.IsEnabled = sal_False;
727 0 : Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
728 0 : if(pChild)
729 : {
730 0 : uno::Reference< datatransfer::clipboard::XClipboard > xClip = pChild->GetClipboard();
731 0 : if(xClip.is())
732 : {
733 0 : uno::Reference< datatransfer::XTransferable > xDataObj;
734 0 : const sal_uInt32 nRef = Application::ReleaseSolarMutex();
735 : try
736 : {
737 0 : xDataObj = xClip->getContents();
738 : }
739 0 : catch( const uno::Exception& )
740 : {
741 : }
742 0 : Application::AcquireSolarMutex( nRef );
743 :
744 0 : if ( xDataObj.is() )
745 : {
746 0 : datatransfer::DataFlavor aFlavor;
747 0 : SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aFlavor );
748 : try
749 : {
750 0 : uno::Any aData = xDataObj->getTransferData( aFlavor );
751 0 : ::rtl::OUString aText;
752 0 : aData >>= aText;
753 0 : aEvent.IsEnabled = !aText.isEmpty();
754 : }
755 0 : catch( const uno::Exception& )
756 : {
757 0 : }
758 0 : }
759 : }
760 0 : uno::Reference< datatransfer::XTransferable > xContents = xClip->getContents( );
761 : }
762 : }
763 0 : else if(aURL.Path == C2U("Bib/DeleteRecord"))
764 : {
765 0 : Reference< ::com::sun::star::sdbc::XResultSet > xCursor(pDatMan->getForm(), UNO_QUERY);
766 0 : Reference< XResultSetUpdate > xUpdateCursor(xCursor, UNO_QUERY);
767 0 : Reference< beans::XPropertySet > xSet(pDatMan->getForm(), UNO_QUERY);
768 0 : sal_Bool bIsNew = ::comphelper::getBOOL(xSet->getPropertyValue(C2U("IsNew")));
769 0 : if(!bIsNew)
770 : {
771 0 : sal_uInt32 nCount = 0;
772 0 : xSet->getPropertyValue(C2U("RowCount")) >>= nCount;
773 0 : aEvent.IsEnabled = nCount > 0;
774 0 : }
775 : }
776 0 : else if (aURL.Path == C2U("Bib/InsertRecord"))
777 : {
778 0 : Reference< beans::XPropertySet > xSet(pDatMan->getForm(), UNO_QUERY);
779 0 : aEvent.IsEnabled = canInsertRecords(xSet);
780 : }
781 0 : aListener->statusChanged( aEvent );
782 0 : }
783 : //-----------------------------------------------------------------------------
784 0 : void BibFrameController_Impl::removeStatusListener(
785 : const uno::Reference< frame::XStatusListener > & aObject, const util::URL& aURL)
786 : throw (::com::sun::star::uno::RuntimeException)
787 : {
788 : // search listener array for given listener
789 : // for checking equality always "cast" to XInterface
790 0 : if ( !bDisposing )
791 : {
792 0 : sal_uInt16 nCount = aStatusListeners.size();
793 0 : for ( sal_uInt16 n=0; n<nCount; n++ )
794 : {
795 0 : BibStatusDispatch *pObj = &aStatusListeners[n];
796 0 : sal_Bool bFlag=pObj->xListener.is();
797 0 : if (!bFlag || (pObj->xListener == aObject &&
798 0 : ( aURL.Complete.isEmpty() || pObj->aURL.Path == aURL.Path )))
799 : {
800 0 : aStatusListeners.erase( aStatusListeners.begin() + n );
801 0 : break;
802 : }
803 : }
804 : }
805 0 : }
806 : //-----------------------------------------------------------------------------
807 0 : void BibFrameController_Impl::RemoveFilter()
808 : {
809 0 : rtl::OUString aQuery;
810 0 : pDatMan->startQueryWith(aQuery);
811 :
812 0 : sal_uInt16 nCount = aStatusListeners.size();
813 :
814 0 : sal_Bool bRemoveFilter=sal_False;
815 0 : sal_Bool bQueryText=sal_False;
816 :
817 0 : for ( sal_uInt16 n=0; n<nCount; n++ )
818 : {
819 0 : BibStatusDispatch *pObj = &aStatusListeners[n];
820 0 : if ( pObj->aURL.Path == C2U("Bib/removeFilter") )
821 : {
822 0 : FeatureStateEvent aEvent;
823 0 : aEvent.FeatureURL = pObj->aURL;
824 0 : aEvent.IsEnabled = sal_False;
825 0 : aEvent.Requery = sal_False;
826 0 : aEvent.Source = (XDispatch *) this;
827 0 : pObj->xListener->statusChanged( aEvent );
828 0 : bRemoveFilter=sal_True;
829 : }
830 0 : else if(pObj->aURL.Path == C2U("Bib/query"))
831 : {
832 0 : FeatureStateEvent aEvent;
833 0 : aEvent.FeatureURL = pObj->aURL;
834 0 : aEvent.IsEnabled = sal_True;
835 0 : aEvent.Requery = sal_False;
836 0 : aEvent.Source = (XDispatch *) this;
837 0 : aEvent.State <<= aQuery;
838 0 : pObj->xListener->statusChanged( aEvent );
839 0 : bQueryText=sal_True;
840 : }
841 :
842 0 : if(bRemoveFilter && bQueryText)
843 0 : break;
844 :
845 0 : }
846 0 : }
847 : //-----------------------------------------------------------------------------
848 0 : void BibFrameController_Impl::ChangeDataSource(const uno::Sequence< beans::PropertyValue >& aArgs)
849 : {
850 0 : const beans::PropertyValue* pPropertyValue = aArgs.getConstArray();
851 0 : uno::Any aValue=pPropertyValue[0].Value;
852 0 : rtl::OUString aDBTableName;
853 0 : aValue >>= aDBTableName;
854 :
855 :
856 0 : if(aArgs.getLength() > 1)
857 : {
858 0 : uno::Any aDB = pPropertyValue[1].Value;
859 0 : rtl::OUString aURL;
860 0 : aDB >>= aURL;
861 0 : pDatMan->setActiveDataSource(aURL);
862 0 : aDBTableName = pDatMan->getActiveDataTable();
863 : }
864 : else
865 : {
866 0 : m_xDatMan->unload();
867 0 : pDatMan->setActiveDataTable(aDBTableName);
868 0 : pDatMan->updateGridModel();
869 0 : m_xDatMan->load();
870 : }
871 :
872 :
873 0 : sal_uInt16 nCount = aStatusListeners.size();
874 :
875 0 : sal_Bool bMenuFilter=sal_False;
876 0 : sal_Bool bQueryText=sal_False;
877 0 : for ( sal_uInt16 n=0; n<nCount; n++ )
878 : {
879 0 : BibStatusDispatch *pObj = &aStatusListeners[n];
880 0 : if(COMPARE_EQUAL == pObj->aURL.Path.compareToAscii("Bib/MenuFilter"))
881 : {
882 0 : FeatureStateEvent aEvent;
883 0 : aEvent.FeatureURL = pObj->aURL;
884 0 : aEvent.IsEnabled = sal_True;
885 0 : aEvent.Requery = sal_False;
886 0 : aEvent.Source = (XDispatch *) this;
887 0 : aEvent.FeatureDescriptor=pDatMan->getQueryField();
888 :
889 0 : uno::Sequence<rtl::OUString> aStringSeq=pDatMan->getQueryFields();
890 0 : aEvent.State = makeAny( aStringSeq );
891 :
892 0 : pObj->xListener->statusChanged( aEvent );
893 0 : bMenuFilter=sal_True;
894 : }
895 0 : else if(COMPARE_EQUAL == pObj->aURL.Path.compareToAscii("Bib/query"))
896 : {
897 0 : FeatureStateEvent aEvent;
898 0 : aEvent.FeatureURL = pObj->aURL;
899 0 : aEvent.IsEnabled = sal_True;
900 0 : aEvent.Requery = sal_False;
901 0 : aEvent.Source = (XDispatch *) this;
902 0 : BibConfig* pConfig = BibModul::GetConfig();
903 0 : aEvent.State <<= pConfig->getQueryText();
904 0 : pObj->xListener->statusChanged( aEvent );
905 0 : bQueryText=sal_True;
906 : }
907 :
908 0 : if (bMenuFilter && bQueryText)
909 0 : break;
910 :
911 0 : }
912 0 : }
913 :
914 0 : void BibFrameController_Impl::activate()
915 : {
916 0 : }
917 0 : void BibFrameController_Impl::deactivate()
918 : {
919 0 : }
920 :
921 :
922 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|