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