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 <com/sun/star/util/URL.hpp>
22 : #include <vcl/msgbox.hxx>
23 : #include <tools/debug.hxx>
24 : #include <vcl/stdtext.hxx>
25 : #include <comphelper/types.hxx>
26 : #include <comphelper/sequence.hxx>
27 : #include "framectr.hxx"
28 : #include "datman.hxx"
29 : #include "bibresid.hxx"
30 : #include "bib.hrc"
31 : #include <toolkit/helper/vclunohelper.hxx>
32 : #include "bibconfig.hxx"
33 : #include <cppuhelper/implbase1.hxx>
34 : #include <vcl/svapp.hxx>
35 : #include "bibliography.hrc"
36 : #include <comphelper/processfactory.hxx>
37 : #include <com/sun/star/form/XConfirmDeleteListener.hpp>
38 : #include <com/sun/star/form/runtime/XFormController.hpp>
39 : #include <com/sun/star/beans/PropertyState.hpp>
40 : #include <com/sun/star/beans/PropertyValue.hpp>
41 : #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
42 : #include <com/sun/star/sdbcx/Privilege.hpp>
43 : #include <com/sun/star/sdbc/XResultSetUpdate.hpp>
44 : #include <com/sun/star/sdb/FilterDialog.hpp>
45 : #include <com/sun/star/sdb/RowChangeAction.hpp>
46 : #include <com/sun/star/frame/CommandGroup.hpp>
47 : #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
48 : #include <cppuhelper/interfacecontainer.hxx>
49 : #include <cppuhelper/supportsservice.hxx>
50 : #include <sot/exchange.hxx>
51 : #include <sot/formats.hxx>
52 : #include <vcl/edit.hxx>
53 : #include <osl/mutex.hxx>
54 :
55 : #include <boost/unordered_map.hpp>
56 :
57 : using namespace osl;
58 : using namespace cppu;
59 : using namespace com::sun::star::sdbc;
60 : using namespace com::sun::star::frame;
61 : using namespace com::sun::star::uno;
62 : using namespace com::sun::star;
63 :
64 :
65 : struct DispatchInfo
66 : {
67 : const char* pCommand;
68 : sal_Int16 nGroupId;
69 : sal_Bool bActiveConnection;
70 : };
71 :
72 : struct CacheDispatchInfo
73 : {
74 : sal_Int16 nGroupId;
75 : sal_Bool bActiveConnection;
76 : };
77 :
78 : // Attention: commands must be sorted by command groups. Implementation is dependent
79 : // on this!!
80 : static const DispatchInfo SupportedCommandsArray[] =
81 : {
82 : { ".uno:Undo" , frame::CommandGroup::EDIT , sal_False },
83 : { ".uno:Cut" , frame::CommandGroup::EDIT , sal_False },
84 : { ".uno:Copy" , frame::CommandGroup::EDIT , sal_False },
85 : { ".uno:Paste" , frame::CommandGroup::EDIT , sal_False },
86 : { ".uno:SelectAll" , frame::CommandGroup::EDIT , sal_False },
87 : { ".uno:CloseDoc" , frame::CommandGroup::DOCUMENT , sal_False },
88 : { ".uno:StatusBarVisible" , frame::CommandGroup::VIEW , sal_False },
89 : { ".uno:AvailableToolbars" , frame::CommandGroup::VIEW , sal_False },
90 : { ".uno:Bib/standardFilter" , frame::CommandGroup::DATA , sal_True },
91 : { ".uno:Bib/DeleteRecord" , frame::CommandGroup::DATA , sal_True },
92 : { ".uno:Bib/InsertRecord" , frame::CommandGroup::DATA , sal_True },
93 : { ".uno:Bib/query" , frame::CommandGroup::DATA , sal_True },
94 : { ".uno:Bib/autoFilter" , frame::CommandGroup::DATA , sal_True },
95 : { ".uno:Bib/source" , frame::CommandGroup::DATA , sal_True },
96 : { ".uno:Bib/removeFilter" , frame::CommandGroup::DATA , sal_True },
97 : { ".uno:Bib/sdbsource" , frame::CommandGroup::DATA , sal_True },
98 : { ".uno:Bib/Mapping" , frame::CommandGroup::DATA , sal_True },
99 : { 0 , 0 , sal_False }
100 : };
101 :
102 : typedef ::boost::unordered_map< OUString, CacheDispatchInfo, OUStringHash, ::std::equal_to< OUString > > CmdToInfoCache;
103 :
104 0 : const CmdToInfoCache& GetCommandToInfoCache()
105 : {
106 : static sal_Bool bCacheInitialized = sal_False;
107 0 : static CmdToInfoCache aCmdToInfoCache;
108 :
109 0 : if ( !bCacheInitialized )
110 : {
111 0 : ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
112 0 : if ( !bCacheInitialized )
113 : {
114 0 : sal_Int32 i( 0 );
115 0 : while ( SupportedCommandsArray[i].pCommand != 0 )
116 : {
117 0 : OUString aCommand( OUString::createFromAscii( SupportedCommandsArray[i].pCommand ));
118 :
119 : CacheDispatchInfo aDispatchInfo;
120 0 : aDispatchInfo.nGroupId = SupportedCommandsArray[i].nGroupId;
121 0 : aDispatchInfo.bActiveConnection = SupportedCommandsArray[i].bActiveConnection;
122 0 : aCmdToInfoCache.insert( CmdToInfoCache::value_type( aCommand, aDispatchInfo ));
123 0 : ++i;
124 0 : }
125 0 : bCacheInitialized = sal_True;
126 0 : }
127 : }
128 :
129 0 : return aCmdToInfoCache;
130 : }
131 :
132 :
133 : class BibFrameCtrl_Impl : public cppu::WeakImplHelper1 < XFrameActionListener >
134 : {
135 : public:
136 : Mutex aMutex;
137 : OMultiTypeInterfaceContainerHelper aLC;
138 :
139 : BibFrameController_Impl* pController;
140 :
141 0 : BibFrameCtrl_Impl()
142 : : aLC( aMutex )
143 0 : , pController(0)
144 0 : {}
145 :
146 : virtual ~BibFrameCtrl_Impl();
147 :
148 : virtual void SAL_CALL frameAction(const FrameActionEvent& aEvent) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
149 : virtual void SAL_CALL disposing( const lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
150 : };
151 :
152 :
153 0 : BibFrameCtrl_Impl::~BibFrameCtrl_Impl()
154 : {
155 0 : }
156 :
157 0 : void BibFrameCtrl_Impl::frameAction(const FrameActionEvent& aEvent) throw( uno::RuntimeException, std::exception )
158 : {
159 0 : if ( pController && aEvent.Frame == pController->getFrame())
160 : {
161 0 : if(aEvent.Action == FrameAction_FRAME_ACTIVATED)
162 : {
163 0 : pController->activate();
164 : }
165 0 : else if(aEvent.Action == FrameAction_FRAME_DEACTIVATING)
166 : {
167 0 : pController->deactivate();
168 : }
169 : }
170 0 : }
171 :
172 0 : void BibFrameCtrl_Impl::disposing( const lang::EventObject& /*Source*/ )
173 : throw (::com::sun::star::uno::RuntimeException, std::exception)
174 : {
175 0 : ::SolarMutexGuard aGuard;
176 0 : if ( pController )
177 0 : pController->getFrame()->removeFrameActionListener( this );
178 0 : }
179 :
180 0 : BibFrameController_Impl::BibFrameController_Impl( const uno::Reference< awt::XWindow > & xComponent,
181 : BibDataManager* pDataManager)
182 : :xWindow( xComponent )
183 : ,m_xDatMan( pDataManager )
184 : ,pDatMan( pDataManager )
185 0 : ,pBibMod(NULL)
186 : {
187 0 : Window* pParent = VCLUnoHelper::GetWindow( xWindow );
188 0 : pParent->SetUniqueId(UID_BIB_FRAME_WINDOW);
189 0 : bDisposing=sal_False;
190 0 : bHierarchical=sal_True;
191 0 : pImp = new BibFrameCtrl_Impl;
192 0 : pImp->pController = this;
193 0 : pImp->acquire();
194 0 : }
195 :
196 0 : BibFrameController_Impl::~BibFrameController_Impl()
197 : {
198 0 : pImp->pController = NULL;
199 0 : pImp->release();
200 0 : delete pDatMan;
201 0 : if(pBibMod)
202 0 : CloseBibModul(pBibMod);
203 0 : }
204 :
205 0 : OUString SAL_CALL BibFrameController_Impl::getImplementationName() throw (::com::sun::star::uno::RuntimeException, std::exception)
206 : {
207 0 : return OUString("com.sun.star.comp.extensions.Bibliography");
208 : }
209 :
210 0 : sal_Bool SAL_CALL BibFrameController_Impl::supportsService( const OUString& sServiceName ) throw (::com::sun::star::uno::RuntimeException, std::exception)
211 : {
212 0 : return cppu::supportsService( this, sServiceName );
213 : }
214 :
215 0 : ::com::sun::star::uno::Sequence< OUString > SAL_CALL BibFrameController_Impl::getSupportedServiceNames() throw (::com::sun::star::uno::RuntimeException, std::exception)
216 : {
217 : // return only top level services ...
218 : // base services are included there and should be asked by uno-rtti.
219 0 : ::com::sun::star::uno::Sequence< OUString > lNames(1);
220 0 : lNames[0] = "com.sun.star.frame.Bibliography";
221 0 : return lNames;
222 : }
223 :
224 0 : void BibFrameController_Impl::attachFrame( const uno::Reference< XFrame > & xArg ) throw (::com::sun::star::uno::RuntimeException, std::exception)
225 : {
226 0 : xFrame = xArg;
227 0 : xFrame->addFrameActionListener( pImp );
228 0 : }
229 :
230 0 : sal_Bool BibFrameController_Impl::attachModel( const uno::Reference< XModel > & /*xModel*/ ) throw (::com::sun::star::uno::RuntimeException, std::exception)
231 : {
232 0 : return sal_False;
233 : }
234 :
235 0 : sal_Bool BibFrameController_Impl::suspend( sal_Bool bSuspend ) throw (::com::sun::star::uno::RuntimeException, std::exception)
236 : {
237 0 : if ( bSuspend )
238 0 : getFrame()->removeFrameActionListener( pImp );
239 : else
240 0 : getFrame()->addFrameActionListener( pImp );
241 0 : return sal_True;
242 : }
243 :
244 0 : uno::Any BibFrameController_Impl::getViewData() throw (::com::sun::star::uno::RuntimeException, std::exception)
245 : {
246 0 : return uno::Any();
247 : }
248 :
249 0 : void BibFrameController_Impl::restoreViewData( const uno::Any& /*Value*/ ) throw (::com::sun::star::uno::RuntimeException, std::exception)
250 : {
251 0 : }
252 :
253 0 : uno::Reference< XFrame > BibFrameController_Impl::getFrame() throw (::com::sun::star::uno::RuntimeException, std::exception)
254 : {
255 0 : return xFrame;
256 : }
257 :
258 0 : uno::Reference< XModel > BibFrameController_Impl::getModel() throw (::com::sun::star::uno::RuntimeException, std::exception)
259 : {
260 0 : return uno::Reference< XModel > ();
261 : }
262 :
263 0 : void BibFrameController_Impl::dispose() throw (::com::sun::star::uno::RuntimeException, std::exception)
264 : {
265 0 : bDisposing = sal_True;
266 0 : lang::EventObject aObject;
267 0 : aObject.Source = (XController*)this;
268 0 : pImp->aLC.disposeAndClear(aObject);
269 0 : m_xDatMan = 0;
270 0 : pDatMan = 0;
271 0 : aStatusListeners.clear();
272 0 : }
273 :
274 0 : void BibFrameController_Impl::addEventListener( const uno::Reference< lang::XEventListener > & aListener ) throw (::com::sun::star::uno::RuntimeException, std::exception)
275 : {
276 0 : pImp->aLC.addInterface( ::getCppuType((const Reference< lang::XEventListener >*)0), aListener );
277 0 : }
278 :
279 0 : void BibFrameController_Impl::removeEventListener( const uno::Reference< lang::XEventListener > & aListener ) throw (::com::sun::star::uno::RuntimeException, std::exception)
280 : {
281 0 : pImp->aLC.removeInterface( ::getCppuType((const Reference< lang::XEventListener >*)0), aListener );
282 0 : }
283 :
284 0 : uno::Reference< frame::XDispatch > BibFrameController_Impl::queryDispatch( const util::URL& aURL, const OUString& /*aTarget*/, sal_Int32 /*nSearchFlags*/ ) throw (::com::sun::star::uno::RuntimeException, std::exception)
285 : {
286 0 : if ( !bDisposing )
287 : {
288 0 : const CmdToInfoCache& rCmdCache = GetCommandToInfoCache();
289 0 : CmdToInfoCache::const_iterator pIter = rCmdCache.find( aURL.Complete );
290 0 : if ( pIter != rCmdCache.end() )
291 : {
292 0 : if (( pDatMan->HasActiveConnection() ) ||
293 0 : ( !pIter->second.bActiveConnection ))
294 0 : return (frame::XDispatch*) this;
295 : }
296 : }
297 :
298 0 : return uno::Reference< frame::XDispatch > ();
299 : }
300 :
301 0 : uno::Sequence<uno::Reference< XDispatch > > BibFrameController_Impl::queryDispatches( const uno::Sequence<DispatchDescriptor>& aDescripts ) throw (::com::sun::star::uno::RuntimeException, std::exception)
302 : {
303 0 : uno::Sequence< uno::Reference< XDispatch > > aDispatches( aDescripts.getLength() );
304 0 : for ( sal_Int32 i=0; i<aDescripts.getLength(); ++i )
305 0 : aDispatches[i] = queryDispatch( aDescripts[i].FeatureURL, aDescripts[i].FrameName, aDescripts[i].SearchFlags );
306 0 : return aDispatches;
307 : }
308 :
309 0 : uno::Sequence< ::sal_Int16 > SAL_CALL BibFrameController_Impl::getSupportedCommandGroups()
310 : throw (::com::sun::star::uno::RuntimeException, std::exception)
311 : {
312 0 : uno::Sequence< ::sal_Int16 > aDispatchInfo( 4 );
313 :
314 0 : aDispatchInfo[0] = frame::CommandGroup::EDIT;
315 0 : aDispatchInfo[1] = frame::CommandGroup::DOCUMENT;
316 0 : aDispatchInfo[2] = frame::CommandGroup::DATA;
317 0 : aDispatchInfo[3] = frame::CommandGroup::VIEW;
318 :
319 0 : return aDispatchInfo;
320 : }
321 :
322 0 : uno::Sequence< frame::DispatchInformation > SAL_CALL BibFrameController_Impl::getConfigurableDispatchInformation( ::sal_Int16 nCommandGroup )
323 : throw (::com::sun::star::uno::RuntimeException, std::exception)
324 : {
325 0 : const CmdToInfoCache& rCmdCache = GetCommandToInfoCache();
326 :
327 0 : sal_Bool bGroupFound( sal_False );
328 0 : frame::DispatchInformation aDispatchInfo;
329 0 : std::list< frame::DispatchInformation > aDispatchInfoList;
330 :
331 0 : if (( nCommandGroup == frame::CommandGroup::EDIT ) ||
332 0 : ( nCommandGroup == frame::CommandGroup::DOCUMENT ) ||
333 0 : ( nCommandGroup == frame::CommandGroup::DATA ) ||
334 : ( nCommandGroup == frame::CommandGroup::VIEW ))
335 : {
336 0 : CmdToInfoCache::const_iterator pIter = rCmdCache.begin();
337 0 : while ( pIter != rCmdCache.end() )
338 : {
339 0 : if ( pIter->second.nGroupId == nCommandGroup )
340 : {
341 0 : bGroupFound = sal_True;
342 0 : aDispatchInfo.Command = pIter->first;
343 0 : aDispatchInfo.GroupId = pIter->second.nGroupId;
344 0 : aDispatchInfoList.push_back( aDispatchInfo );
345 : }
346 0 : else if ( bGroupFound )
347 0 : break;
348 :
349 0 : ++pIter;
350 : }
351 : }
352 :
353 : ::com::sun::star::uno::Sequence< ::com::sun::star::frame::DispatchInformation > aSeq =
354 0 : comphelper::containerToSequence< ::com::sun::star::frame::DispatchInformation, std::list< ::com::sun::star::frame::DispatchInformation > >( aDispatchInfoList );
355 :
356 0 : return aSeq;
357 : }
358 :
359 0 : sal_Bool canInsertRecords(const Reference< beans::XPropertySet>& _rxCursorSet)
360 : {
361 0 : sal_Int32 nPriv = 0;
362 0 : _rxCursorSet->getPropertyValue("Privileges") >>= nPriv;
363 0 : return ((_rxCursorSet.is() && (nPriv & sdbcx::Privilege::INSERT) != 0));
364 : }
365 :
366 0 : sal_Bool BibFrameController_Impl::SaveModified(const Reference< form::runtime::XFormController>& xController)
367 : {
368 0 : if (!xController.is())
369 0 : return sal_False;
370 :
371 0 : Reference< XResultSetUpdate> _xCursor = Reference< XResultSetUpdate>(xController->getModel(), UNO_QUERY);
372 :
373 0 : if (!_xCursor.is())
374 0 : return sal_False;
375 :
376 0 : Reference< beans::XPropertySet> _xSet = Reference< beans::XPropertySet>(_xCursor, UNO_QUERY);
377 0 : if (!_xSet.is())
378 0 : return sal_False;
379 :
380 : // need to save?
381 0 : sal_Bool bIsNew = ::comphelper::getBOOL(_xSet->getPropertyValue("IsNew"));
382 0 : sal_Bool bIsModified = ::comphelper::getBOOL(_xSet->getPropertyValue("IsModified"));
383 0 : sal_Bool bResult = !bIsModified;
384 0 : if (bIsModified)
385 : {
386 : try
387 : {
388 0 : if (bIsNew)
389 0 : _xCursor->insertRow();
390 : else
391 0 : _xCursor->updateRow();
392 0 : bResult = sal_True;
393 : }
394 0 : catch(const Exception&)
395 : {
396 : OSL_FAIL("SaveModified: Exception occurred!");
397 : }
398 : }
399 0 : return bResult;
400 : }
401 :
402 0 : static Window* lcl_GetFocusChild( Window* pParent )
403 : {
404 0 : sal_uInt16 nChildren = pParent->GetChildCount();
405 0 : for( sal_uInt16 nChild = 0; nChild < nChildren; ++nChild)
406 : {
407 0 : Window* pChild = pParent->GetChild( nChild );
408 0 : if(pChild->HasFocus())
409 0 : return pChild;
410 0 : Window* pSubChild = lcl_GetFocusChild( pChild );
411 0 : if(pSubChild)
412 0 : return pSubChild;
413 : }
414 0 : return 0;
415 : }
416 :
417 : //class XDispatch
418 0 : void BibFrameController_Impl::dispatch(const util::URL& _rURL, const uno::Sequence< beans::PropertyValue >& aArgs)
419 : throw (::com::sun::star::uno::RuntimeException,
420 : std::exception)
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 : OUString aCommand( _rURL.Path);
429 0 : if(aCommand == "Bib/Mapping")
430 : {
431 0 : pDatMan->CreateMappingDialog(pParent);
432 : }
433 0 : else if(aCommand == "Bib/source")
434 : {
435 0 : ChangeDataSource(aArgs);
436 : }
437 0 : else if(aCommand == "Bib/sdbsource")
438 : {
439 0 : 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 <<= 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 == "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 == "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 : OUString aQuery;
477 0 : aValue >>= aQuery;
478 :
479 0 : aValue=pPropertyValue[1].Value;
480 0 : 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 == "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 : 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 == "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 == "Bib/removeFilter")
525 : {
526 0 : RemoveFilter();
527 : }
528 0 : else if( _rURL.Complete == "slot:5503" || aCommand == "CloseDoc" )
529 : {
530 : Application::PostUserEvent( STATIC_LINK( this, BibFrameController_Impl,
531 0 : DisposeHdl ), 0 );
532 :
533 : }
534 0 : else if(aCommand == "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 == "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("IsNew"));
559 0 : if(!bIsNew)
560 : {
561 0 : sal_uInt32 nCount = 0;
562 0 : xSet->getPropertyValue("RowCount") >>= nCount;
563 : // determine next position
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 : // delete it
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 : // can another entry be inserted?
599 : try
600 : {
601 0 : if (bCanInsert)
602 0 : xUpdateCursor->moveToInsertRow();
603 : else
604 : // move data entry to reset state
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 == "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 == "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 == "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 0 : void BibFrameController_Impl::addStatusListener(
651 : const uno::Reference< frame::XStatusListener > & aListener,
652 : const util::URL& aURL)
653 : throw (::com::sun::star::uno::RuntimeException,
654 : std::exception)
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 : // send first status synchronously
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 == "StatusBarVisible" )
666 : {
667 0 : aEvent.IsEnabled = sal_False;
668 0 : aEvent.State <<= sal_Bool( sal_False );
669 : }
670 0 : else if ( aURL.Path == "Bib/hierarchical" )
671 : {
672 0 : aEvent.IsEnabled = sal_True;
673 0 : const char* pHier = bHierarchical? "" : "*" ;
674 0 : aEvent.State <<= OUString::createFromAscii(pHier);
675 : }
676 0 : else if(aURL.Path == "Bib/MenuFilter")
677 : {
678 0 : aEvent.IsEnabled = sal_True;
679 0 : aEvent.FeatureDescriptor=pDatMan->getQueryField();
680 :
681 0 : uno::Sequence<OUString> aStringSeq=pDatMan->getQueryFields();
682 0 : aEvent.State.setValue(&aStringSeq,::getCppuType((uno::Sequence<OUString>*)0));
683 :
684 : }
685 0 : else if ( aURL.Path == "Bib/source")
686 : {
687 0 : aEvent.IsEnabled = sal_True;
688 0 : aEvent.FeatureDescriptor=pDatMan->getActiveDataTable();
689 :
690 0 : uno::Sequence<OUString> aStringSeq=pDatMan->getDataSources();
691 0 : aEvent.State.setValue(&aStringSeq,::getCppuType((uno::Sequence<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 == "Bib/query")
701 : {
702 0 : aEvent.IsEnabled = sal_True;
703 0 : aEvent.State <<= pConfig->getQueryText();
704 : }
705 0 : else if (aURL.Path == "Bib/removeFilter" )
706 : {
707 0 : OUString aFilterStr=pDatMan->getFilter();
708 0 : aEvent.IsEnabled = !aFilterStr.isEmpty();
709 : }
710 0 : else if(aURL.Path == "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 == "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 == "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 : 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 == "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("IsNew"));
769 0 : if(!bIsNew)
770 : {
771 0 : sal_uInt32 nCount = 0;
772 0 : xSet->getPropertyValue("RowCount") >>= nCount;
773 0 : aEvent.IsEnabled = nCount > 0;
774 0 : }
775 : }
776 0 : else if (aURL.Path == "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, std::exception)
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 : 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 == "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 == "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 : 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 : 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 (pObj->aURL.Path == "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<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 (pObj->aURL.Path == "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: */
|