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