Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / extensions / source / bibliography / framectr.cxx
bloba36efe9b550a3105950695ce1cf88febf846fea1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <com/sun/star/util/URL.hpp>
21 #include <vcl/stdtext.hxx>
22 #include <comphelper/types.hxx>
23 #include <comphelper/sequence.hxx>
24 #include "framectr.hxx"
25 #include "datman.hxx"
26 #include "bibview.hxx"
27 #include "bibresid.hxx"
28 #include <strings.hrc>
29 #include <toolkit/helper/vclunohelper.hxx>
30 #include "bibconfig.hxx"
31 #include <cppuhelper/implbase.hxx>
32 #include <vcl/event.hxx>
33 #include <vcl/svapp.hxx>
34 #include <comphelper/processfactory.hxx>
35 #include <com/sun/star/form/XConfirmDeleteListener.hpp>
36 #include <com/sun/star/form/runtime/XFormController.hpp>
37 #include <com/sun/star/beans/PropertyState.hpp>
38 #include <com/sun/star/beans/PropertyValue.hpp>
39 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
40 #include <com/sun/star/sdbcx/Privilege.hpp>
41 #include <com/sun/star/sdbc/XResultSetUpdate.hpp>
42 #include <com/sun/star/sdb/FilterDialog.hpp>
43 #include <com/sun/star/sdb/RowChangeAction.hpp>
44 #include <com/sun/star/frame/CommandGroup.hpp>
45 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
46 #include <cppuhelper/interfacecontainer.hxx>
47 #include <cppuhelper/supportsservice.hxx>
48 #include <sot/exchange.hxx>
49 #include <sot/formats.hxx>
50 #include <vcl/edit.hxx>
51 #include <vcl/weld.hxx>
52 #include <osl/mutex.hxx>
54 #include <unordered_map>
56 using namespace osl;
57 using namespace cppu;
58 using namespace com::sun::star::sdbc;
59 using namespace com::sun::star::frame;
60 using namespace com::sun::star::uno;
61 using namespace com::sun::star;
64 struct DispatchInfo
66 const char* pCommand;
67 sal_Int16 nGroupId;
68 bool bActiveConnection;
71 struct CacheDispatchInfo
73 sal_Int16 nGroupId;
74 bool bActiveConnection;
77 // Attention: commands must be sorted by command groups. Implementation is dependent
78 // on this!!
79 static const DispatchInfo SupportedCommandsArray[] =
81 { ".uno:Undo" , frame::CommandGroup::EDIT , false },
82 { ".uno:Cut" , frame::CommandGroup::EDIT , false },
83 { ".uno:Copy" , frame::CommandGroup::EDIT , false },
84 { ".uno:Paste" , frame::CommandGroup::EDIT , false },
85 { ".uno:SelectAll" , frame::CommandGroup::EDIT , false },
86 { ".uno:CloseDoc" , frame::CommandGroup::DOCUMENT , false },
87 { ".uno:StatusBarVisible" , frame::CommandGroup::VIEW , false },
88 { ".uno:AvailableToolbars" , frame::CommandGroup::VIEW , false },
89 { ".uno:Bib/standardFilter" , frame::CommandGroup::DATA , true },
90 { ".uno:Bib/DeleteRecord" , frame::CommandGroup::DATA , true },
91 { ".uno:Bib/InsertRecord" , frame::CommandGroup::DATA , true },
92 { ".uno:Bib/query" , frame::CommandGroup::DATA , true },
93 { ".uno:Bib/autoFilter" , frame::CommandGroup::DATA , true },
94 { ".uno:Bib/source" , frame::CommandGroup::DATA , true },
95 { ".uno:Bib/removeFilter" , frame::CommandGroup::DATA , true },
96 { ".uno:Bib/sdbsource" , frame::CommandGroup::DATA , true },
97 { ".uno:Bib/Mapping" , frame::CommandGroup::DATA , true },
100 typedef std::unordered_map< OUString, CacheDispatchInfo > CmdToInfoCache;
102 static const CmdToInfoCache& GetCommandToInfoCache()
104 static CmdToInfoCache aCmdToInfoCache = []() {
105 CmdToInfoCache aCache;
106 for (const auto& command : SupportedCommandsArray)
108 OUString aCommand(OUString::createFromAscii(command.pCommand));
110 CacheDispatchInfo aDispatchInfo;
111 aDispatchInfo.nGroupId = command.nGroupId;
112 aDispatchInfo.bActiveConnection = command.bActiveConnection;
113 aCache.emplace(aCommand, aDispatchInfo);
115 return aCache;
116 }();
118 return aCmdToInfoCache;
122 class BibFrameCtrl_Impl : public cppu::WeakImplHelper < XFrameActionListener >
124 public:
125 Mutex aMutex;
126 OMultiTypeInterfaceContainerHelper aLC;
128 BibFrameController_Impl* pController;
130 BibFrameCtrl_Impl()
131 : aLC( aMutex )
132 , pController(nullptr)
135 virtual void SAL_CALL frameAction(const FrameActionEvent& aEvent) override;
136 virtual void SAL_CALL disposing( const lang::EventObject& Source ) override;
139 void BibFrameCtrl_Impl::frameAction(const FrameActionEvent& )
143 void BibFrameCtrl_Impl::disposing( const lang::EventObject& /*Source*/ )
145 ::SolarMutexGuard aGuard;
146 if ( pController )
147 pController->getFrame()->removeFrameActionListener( this );
150 BibFrameController_Impl::BibFrameController_Impl( const uno::Reference< awt::XWindow > & xComponent,
151 BibDataManager* pDataManager)
152 :xWindow( xComponent )
153 ,m_xDatMan( pDataManager )
155 bDisposing=false;
156 mxImpl = new BibFrameCtrl_Impl;
157 mxImpl->pController = this;
160 BibFrameController_Impl::~BibFrameController_Impl()
162 mxImpl->pController = nullptr;
163 m_xDatMan.clear();
166 OUString SAL_CALL BibFrameController_Impl::getImplementationName()
168 return "com.sun.star.comp.extensions.Bibliography";
171 sal_Bool SAL_CALL BibFrameController_Impl::supportsService( const OUString& sServiceName )
173 return cppu::supportsService( this, sServiceName );
176 css::uno::Sequence< OUString > SAL_CALL BibFrameController_Impl::getSupportedServiceNames()
178 // return only top level services ...
179 // base services are included there and should be asked by uno-rtti.
180 css::uno::Sequence< OUString > lNames { "com.sun.star.frame.Bibliography" };
181 return lNames;
184 void BibFrameController_Impl::attachFrame( const uno::Reference< XFrame > & xArg )
186 xFrame = xArg;
187 xFrame->addFrameActionListener( mxImpl.get() );
190 sal_Bool BibFrameController_Impl::attachModel( const uno::Reference< XModel > & /*xModel*/ )
192 return false;
195 sal_Bool BibFrameController_Impl::suspend( sal_Bool bSuspend )
197 if ( bSuspend )
198 getFrame()->removeFrameActionListener( mxImpl.get() );
199 else
200 getFrame()->addFrameActionListener( mxImpl.get() );
201 return true;
204 uno::Any BibFrameController_Impl::getViewData()
206 return uno::Any();
209 void BibFrameController_Impl::restoreViewData( const uno::Any& /*Value*/ )
213 uno::Reference< XFrame > BibFrameController_Impl::getFrame()
215 return xFrame;
218 uno::Reference< XModel > BibFrameController_Impl::getModel()
220 return uno::Reference< XModel > ();
223 void BibFrameController_Impl::dispose()
225 bDisposing = true;
226 lang::EventObject aObject;
227 aObject.Source = static_cast<XController*>(this);
228 mxImpl->aLC.disposeAndClear(aObject);
229 m_xDatMan.clear();
230 aStatusListeners.clear();
233 void BibFrameController_Impl::addEventListener( const uno::Reference< lang::XEventListener > & aListener )
235 mxImpl->aLC.addInterface( cppu::UnoType<lang::XEventListener>::get(), aListener );
238 void BibFrameController_Impl::removeEventListener( const uno::Reference< lang::XEventListener > & aListener )
240 mxImpl->aLC.removeInterface( cppu::UnoType<lang::XEventListener>::get(), aListener );
243 uno::Reference< frame::XDispatch > BibFrameController_Impl::queryDispatch( const util::URL& aURL, const OUString& /*aTarget*/, sal_Int32 /*nSearchFlags*/ )
245 if ( !bDisposing )
247 const CmdToInfoCache& rCmdCache = GetCommandToInfoCache();
248 CmdToInfoCache::const_iterator pIter = rCmdCache.find( aURL.Complete );
249 if ( pIter != rCmdCache.end() )
251 if (( m_xDatMan->HasActiveConnection() ) ||
252 ( !pIter->second.bActiveConnection ))
253 return static_cast<frame::XDispatch*>(this);
257 return uno::Reference< frame::XDispatch > ();
260 uno::Sequence<uno::Reference< XDispatch > > BibFrameController_Impl::queryDispatches( const uno::Sequence<DispatchDescriptor>& aDescripts )
262 uno::Sequence< uno::Reference< XDispatch > > aDispatches( aDescripts.getLength() );
263 for ( sal_Int32 i=0; i<aDescripts.getLength(); ++i )
264 aDispatches[i] = queryDispatch( aDescripts[i].FeatureURL, aDescripts[i].FrameName, aDescripts[i].SearchFlags );
265 return aDispatches;
268 uno::Sequence< ::sal_Int16 > SAL_CALL BibFrameController_Impl::getSupportedCommandGroups()
270 uno::Sequence< ::sal_Int16 > aDispatchInfo( 4 );
272 aDispatchInfo[0] = frame::CommandGroup::EDIT;
273 aDispatchInfo[1] = frame::CommandGroup::DOCUMENT;
274 aDispatchInfo[2] = frame::CommandGroup::DATA;
275 aDispatchInfo[3] = frame::CommandGroup::VIEW;
277 return aDispatchInfo;
280 uno::Sequence< frame::DispatchInformation > SAL_CALL BibFrameController_Impl::getConfigurableDispatchInformation( ::sal_Int16 nCommandGroup )
282 const CmdToInfoCache& rCmdCache = GetCommandToInfoCache();
284 frame::DispatchInformation aDispatchInfo;
285 std::vector< frame::DispatchInformation > aDispatchInfoVector;
287 if (( nCommandGroup == frame::CommandGroup::EDIT ) ||
288 ( nCommandGroup == frame::CommandGroup::DOCUMENT ) ||
289 ( nCommandGroup == frame::CommandGroup::DATA ) ||
290 ( nCommandGroup == frame::CommandGroup::VIEW ))
292 bool bGroupFound = false;
293 for (auto const& item : rCmdCache)
295 if ( item.second.nGroupId == nCommandGroup )
297 bGroupFound = true;
298 aDispatchInfo.Command = item.first;
299 aDispatchInfo.GroupId = item.second.nGroupId;
300 aDispatchInfoVector.push_back( aDispatchInfo );
302 else if ( bGroupFound )
303 break;
307 return comphelper::containerToSequence( aDispatchInfoVector );
310 static bool canInsertRecords(const Reference< beans::XPropertySet>& _rxCursorSet)
312 sal_Int32 nPriv = 0;
313 _rxCursorSet->getPropertyValue("Privileges") >>= nPriv;
314 return _rxCursorSet.is() && (nPriv & sdbcx::Privilege::INSERT) != 0;
317 bool BibFrameController_Impl::SaveModified(const Reference< form::runtime::XFormController>& xController)
319 if (!xController.is())
320 return false;
322 Reference< XResultSetUpdate> _xCursor(xController->getModel(), UNO_QUERY);
324 if (!_xCursor.is())
325 return false;
327 Reference< beans::XPropertySet> _xSet(_xCursor, UNO_QUERY);
328 if (!_xSet.is())
329 return false;
331 // need to save?
332 bool bIsNew = ::comphelper::getBOOL(_xSet->getPropertyValue("IsNew"));
333 bool bIsModified = ::comphelper::getBOOL(_xSet->getPropertyValue("IsModified"));
334 bool bResult = !bIsModified;
335 if (bIsModified)
339 if (bIsNew)
340 _xCursor->insertRow();
341 else
342 _xCursor->updateRow();
343 bResult = true;
345 catch(const Exception&)
347 OSL_FAIL("SaveModified: Exception occurred!");
350 return bResult;
353 static vcl::Window* lcl_GetFocusChild( vcl::Window const * pParent )
355 sal_uInt16 nChildren = pParent->GetChildCount();
356 for( sal_uInt16 nChild = 0; nChild < nChildren; ++nChild)
358 vcl::Window* pChild = pParent->GetChild( nChild );
359 if(pChild->HasFocus())
360 return pChild;
361 vcl::Window* pSubChild = lcl_GetFocusChild( pChild );
362 if(pSubChild)
363 return pSubChild;
365 return nullptr;
368 //class XDispatch
369 void BibFrameController_Impl::dispatch(const util::URL& _rURL, const uno::Sequence< beans::PropertyValue >& aArgs)
371 if ( !bDisposing )
373 ::SolarMutexGuard aGuard;
374 weld::Window* pParent = Application::GetFrameWeld(xWindow);
375 weld::WaitObject aWaitObject(pParent);
377 OUString aCommand( _rURL.Path);
378 if(aCommand == "Bib/Mapping")
380 m_xDatMan->CreateMappingDialog(pParent);
382 else if(aCommand == "Bib/source")
384 ChangeDataSource(aArgs);
386 else if(aCommand == "Bib/sdbsource")
388 OUString aURL = m_xDatMan->CreateDBChangeDialog(pParent);
389 if(!aURL.isEmpty())
393 uno::Sequence< beans::PropertyValue > aNewDataSource(2);
394 beans::PropertyValue* pProps = aNewDataSource.getArray();
395 pProps[0].Value <<= OUString();
396 pProps[1].Value <<= aURL;
397 ChangeDataSource(aNewDataSource);
399 catch(const Exception&)
401 OSL_FAIL("Exception caught while changing the data source");
405 else if(aCommand == "Bib/autoFilter")
407 sal_uInt16 nCount = aStatusListeners.size();
408 for ( sal_uInt16 n=0; n<nCount; n++ )
410 BibStatusDispatch *pObj = aStatusListeners[n].get();
411 if ( pObj->aURL.Path == "Bib/removeFilter" )
413 FeatureStateEvent aEvent;
414 aEvent.FeatureURL = pObj->aURL;
415 aEvent.IsEnabled = true;
416 aEvent.Requery = false;
417 aEvent.Source = static_cast<XDispatch *>(this);
418 pObj->xListener->statusChanged( aEvent );
419 //break; because there are more than one
423 const beans::PropertyValue* pPropertyValue = aArgs.getConstArray();
424 uno::Any aValue=pPropertyValue[0].Value;
425 OUString aQuery;
426 aValue >>= aQuery;
428 aValue=pPropertyValue[1].Value;
429 OUString aQueryField;
430 aValue >>= aQueryField;
431 BibConfig* pConfig = BibModul::GetConfig();
432 pConfig->setQueryField(aQueryField);
433 m_xDatMan->startQueryWith(aQuery);
435 else if(aCommand == "Bib/standardFilter")
439 uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
441 // create the dialog object
442 uno::Reference< ui::dialogs::XExecutableDialog > xDialog = sdb::FilterDialog::createWithQuery(xContext, m_xDatMan->getParser(),
443 Reference<sdbc::XRowSet>(m_xDatMan->getForm(), uno::UNO_QUERY_THROW), xWindow);
444 // execute it
445 if ( xDialog->execute( ) )
447 // the dialog has been executed successfully, and the filter on the query composer
448 // has been changed
449 OUString sNewFilter = m_xDatMan->getParser()->getFilter();
450 m_xDatMan->setFilter( sNewFilter );
453 catch( const uno::Exception& )
455 OSL_FAIL( "BibFrameController_Impl::dispatch: caught an exception!" );
458 sal_uInt16 nCount = aStatusListeners.size();
459 for ( sal_uInt16 n=0; n<nCount; n++ )
461 BibStatusDispatch *pObj = aStatusListeners[n].get();
462 if ( pObj->aURL.Path == "Bib/removeFilter" && m_xDatMan->getParser().is())
464 FeatureStateEvent aEvent;
465 aEvent.FeatureURL = pObj->aURL;
466 aEvent.IsEnabled = !m_xDatMan->getParser()->getFilter().isEmpty();
467 aEvent.Requery = false;
468 aEvent.Source = static_cast<XDispatch *>(this);
469 pObj->xListener->statusChanged( aEvent );
473 else if(aCommand == "Bib/removeFilter")
475 RemoveFilter();
477 else if( _rURL.Complete == "slot:5503" || aCommand == "CloseDoc" )
479 Application::PostUserEvent( LINK( this, BibFrameController_Impl,
480 DisposeHdl ) );
483 else if(aCommand == "Bib/InsertRecord")
485 Reference<form::runtime::XFormController > xFormCtrl = m_xDatMan->GetFormController();
486 if(SaveModified(xFormCtrl))
490 Reference< sdbc::XResultSet > xCursor( m_xDatMan->getForm(), UNO_QUERY );
491 xCursor->last();
493 Reference< XResultSetUpdate > xUpdateCursor( m_xDatMan->getForm(), UNO_QUERY );
494 xUpdateCursor->moveToInsertRow();
496 catch(const Exception&)
498 OSL_FAIL("Exception in last() or moveToInsertRow()");
502 else if(aCommand == "Bib/DeleteRecord")
504 Reference< css::sdbc::XResultSet > xCursor(m_xDatMan->getForm(), UNO_QUERY);
505 Reference< XResultSetUpdate > xUpdateCursor(xCursor, UNO_QUERY);
506 Reference< beans::XPropertySet > xSet(m_xDatMan->getForm(), UNO_QUERY);
507 bool bIsNew = ::comphelper::getBOOL(xSet->getPropertyValue("IsNew"));
508 if(!bIsNew)
510 sal_uInt32 nCount = 0;
511 xSet->getPropertyValue("RowCount") >>= nCount;
512 // determine next position
513 bool bSuccess = false;
514 bool bLeft = false;
515 bool bRight = false;
518 bLeft = xCursor->isLast() && nCount > 1;
519 bRight= !xCursor->isLast();
520 // ask for confirmation
521 Reference< frame::XController > xCtrl = mxImpl->pController;
522 Reference< form::XConfirmDeleteListener > xConfirm(m_xDatMan->GetFormController(),UNO_QUERY);
523 if (xConfirm.is())
525 sdb::RowChangeEvent aEvent;
526 aEvent.Source.set(xCursor, UNO_QUERY);
527 aEvent.Action = sdb::RowChangeAction::DELETE;
528 aEvent.Rows = 1;
529 bSuccess = xConfirm->confirmDelete(aEvent);
532 // delete it
533 if (bSuccess)
534 xUpdateCursor->deleteRow();
536 catch(const Exception&)
538 bSuccess = false;
540 if (bSuccess)
542 if (bLeft || bRight)
543 xCursor->relative(bRight ? 1 : -1);
544 else
546 bool bCanInsert = canInsertRecords(xSet);
547 // can another entry be inserted?
550 if (bCanInsert)
551 xUpdateCursor->moveToInsertRow();
552 else
553 // move data entry to reset state
554 xCursor->first();
556 catch(const Exception&)
558 OSL_FAIL("DeleteRecord: exception caught!");
564 else if(aCommand == "Cut")
566 vcl::Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
567 if(pChild)
569 KeyEvent aEvent( 0, KeyFuncType::CUT );
570 pChild->KeyInput( aEvent );
573 else if(aCommand == "Copy")
575 vcl::Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
576 if(pChild)
578 KeyEvent aEvent( 0, KeyFuncType::COPY );
579 pChild->KeyInput( aEvent );
582 else if(aCommand == "Paste")
584 vcl::Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
585 if(pChild)
587 KeyEvent aEvent( 0, KeyFuncType::PASTE );
588 pChild->KeyInput( aEvent );
593 IMPL_LINK_NOARG( BibFrameController_Impl, DisposeHdl, void*, void )
595 xFrame->dispose();
598 void BibFrameController_Impl::addStatusListener(
599 const uno::Reference< frame::XStatusListener > & aListener,
600 const util::URL& aURL)
602 BibConfig* pConfig = BibModul::GetConfig();
603 // create a new Reference and insert into listener array
604 aStatusListeners.push_back( std::make_unique<BibStatusDispatch>( aURL, aListener ) );
606 // send first status synchronously
607 FeatureStateEvent aEvent;
608 aEvent.FeatureURL = aURL;
609 aEvent.Requery = false;
610 aEvent.Source = static_cast<XDispatch *>(this);
611 if ( aURL.Path == "StatusBarVisible" )
613 aEvent.IsEnabled = false;
614 aEvent.State <<= false;
616 else if ( aURL.Path == "Bib/hierarchical" )
618 aEvent.IsEnabled = true;
619 aEvent.State <<= OUString();
621 else if(aURL.Path == "Bib/MenuFilter")
623 aEvent.IsEnabled = true;
624 aEvent.FeatureDescriptor=m_xDatMan->getQueryField();
626 aEvent.State <<= m_xDatMan->getQueryFields();
629 else if ( aURL.Path == "Bib/source")
631 aEvent.IsEnabled = true;
632 aEvent.FeatureDescriptor=m_xDatMan->getActiveDataTable();
634 aEvent.State <<= m_xDatMan->getDataSources();
636 else if( aURL.Path == "Bib/sdbsource" ||
637 aURL.Path == "Bib/Mapping" ||
638 aURL.Path == "Bib/autoFilter" ||
639 aURL.Path == "Bib/standardFilter" )
641 aEvent.IsEnabled = true;
643 else if(aURL.Path == "Bib/query")
645 aEvent.IsEnabled = true;
646 aEvent.State <<= pConfig->getQueryText();
648 else if (aURL.Path == "Bib/removeFilter" )
650 OUString aFilterStr=m_xDatMan->getFilter();
651 aEvent.IsEnabled = !aFilterStr.isEmpty();
653 else if(aURL.Path == "Cut")
655 vcl::Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
656 Edit* pEdit = dynamic_cast<Edit*>( pChild );
657 if( pEdit )
658 aEvent.IsEnabled = !pEdit->IsReadOnly() && pEdit->GetSelection().Len();
660 if(aURL.Path == "Copy")
662 vcl::Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
663 Edit* pEdit = dynamic_cast<Edit*>( pChild );
664 if( pEdit )
665 aEvent.IsEnabled = pEdit->GetSelection().Len() > 0;
667 else if(aURL.Path == "Paste" )
669 aEvent.IsEnabled = false;
670 vcl::Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
671 if(pChild)
673 uno::Reference< datatransfer::clipboard::XClipboard > xClip = pChild->GetClipboard();
674 if(xClip.is())
676 uno::Reference< datatransfer::XTransferable > xDataObj;
680 SolarMutexReleaser aReleaser;
681 xDataObj = xClip->getContents();
683 catch( const uno::Exception& )
687 if ( xDataObj.is() )
689 datatransfer::DataFlavor aFlavor;
690 SotExchange::GetFormatDataFlavor( SotClipboardFormatId::STRING, aFlavor );
693 uno::Any aData = xDataObj->getTransferData( aFlavor );
694 OUString aText;
695 aData >>= aText;
696 aEvent.IsEnabled = !aText.isEmpty();
698 catch( const uno::Exception& )
705 else if(aURL.Path == "Bib/DeleteRecord")
707 Reference< beans::XPropertySet > xSet(m_xDatMan->getForm(), UNO_QUERY);
708 bool bIsNew = ::comphelper::getBOOL(xSet->getPropertyValue("IsNew"));
709 if(!bIsNew)
711 sal_uInt32 nCount = 0;
712 xSet->getPropertyValue("RowCount") >>= nCount;
713 aEvent.IsEnabled = nCount > 0;
716 else if (aURL.Path == "Bib/InsertRecord")
718 Reference< beans::XPropertySet > xSet(m_xDatMan->getForm(), UNO_QUERY);
719 aEvent.IsEnabled = canInsertRecords(xSet);
721 aListener->statusChanged( aEvent );
724 void BibFrameController_Impl::removeStatusListener(
725 const uno::Reference< frame::XStatusListener > & aObject, const util::URL& aURL)
727 // search listener array for given listener
728 // for checking equality always "cast" to XInterface
729 if ( !bDisposing )
731 sal_uInt16 nCount = aStatusListeners.size();
732 for ( sal_uInt16 n=0; n<nCount; n++ )
734 BibStatusDispatch *pObj = aStatusListeners[n].get();
735 bool bFlag=pObj->xListener.is();
736 if (!bFlag || (pObj->xListener == aObject &&
737 ( aURL.Complete.isEmpty() || pObj->aURL.Path == aURL.Path )))
739 aStatusListeners.erase( aStatusListeners.begin() + n );
740 break;
746 void BibFrameController_Impl::RemoveFilter()
748 OUString aQuery;
749 m_xDatMan->startQueryWith(aQuery);
751 sal_uInt16 nCount = aStatusListeners.size();
753 bool bRemoveFilter=false;
754 bool bQueryText=false;
756 for ( sal_uInt16 n=0; n<nCount; n++ )
758 BibStatusDispatch *pObj = aStatusListeners[n].get();
759 if ( pObj->aURL.Path == "Bib/removeFilter" )
761 FeatureStateEvent aEvent;
762 aEvent.FeatureURL = pObj->aURL;
763 aEvent.IsEnabled = false;
764 aEvent.Requery = false;
765 aEvent.Source = static_cast<XDispatch *>(this);
766 pObj->xListener->statusChanged( aEvent );
767 bRemoveFilter=true;
769 else if(pObj->aURL.Path == "Bib/query")
771 FeatureStateEvent aEvent;
772 aEvent.FeatureURL = pObj->aURL;
773 aEvent.IsEnabled = true;
774 aEvent.Requery = false;
775 aEvent.Source = static_cast<XDispatch *>(this);
776 aEvent.State <<= aQuery;
777 pObj->xListener->statusChanged( aEvent );
778 bQueryText=true;
781 if(bRemoveFilter && bQueryText)
782 break;
787 void BibFrameController_Impl::ChangeDataSource(const uno::Sequence< beans::PropertyValue >& aArgs)
789 const beans::PropertyValue* pPropertyValue = aArgs.getConstArray();
790 uno::Any aValue=pPropertyValue[0].Value;
791 OUString aDBTableName;
792 aValue >>= aDBTableName;
795 if(aArgs.getLength() > 1)
797 uno::Any aDB = pPropertyValue[1].Value;
798 OUString aURL;
799 aDB >>= aURL;
800 m_xDatMan->setActiveDataSource(aURL);
801 aDBTableName = m_xDatMan->getActiveDataTable();
803 else
805 Reference<css::form::XLoadable> xLoadable(m_xDatMan.get());
806 xLoadable->unload();
807 m_xDatMan->setActiveDataTable(aDBTableName);
808 m_xDatMan->updateGridModel();
809 xLoadable->load();
813 sal_uInt16 nCount = aStatusListeners.size();
815 bool bMenuFilter=false;
816 bool bQueryText=false;
817 for ( sal_uInt16 n=0; n<nCount; n++ )
819 BibStatusDispatch *pObj = aStatusListeners[n].get();
820 if (pObj->aURL.Path == "Bib/MenuFilter")
822 FeatureStateEvent aEvent;
823 aEvent.FeatureURL = pObj->aURL;
824 aEvent.IsEnabled = true;
825 aEvent.Requery = false;
826 aEvent.Source = static_cast<XDispatch *>(this);
827 aEvent.FeatureDescriptor=m_xDatMan->getQueryField();
829 uno::Sequence<OUString> aStringSeq=m_xDatMan->getQueryFields();
830 aEvent.State <<= aStringSeq;
832 pObj->xListener->statusChanged( aEvent );
833 bMenuFilter=true;
835 else if (pObj->aURL.Path == "Bib/query")
837 FeatureStateEvent aEvent;
838 aEvent.FeatureURL = pObj->aURL;
839 aEvent.IsEnabled = true;
840 aEvent.Requery = false;
841 aEvent.Source = static_cast<XDispatch *>(this);
842 BibConfig* pConfig = BibModul::GetConfig();
843 aEvent.State <<= pConfig->getQueryText();
844 pObj->xListener->statusChanged( aEvent );
845 bQueryText=true;
848 if (bMenuFilter && bQueryText)
849 break;
854 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */