summaryrefslogtreecommitdiffstats
path: root/extensions/source/bibliography/framectr.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/source/bibliography/framectr.cxx')
-rw-r--r--extensions/source/bibliography/framectr.cxx874
1 files changed, 874 insertions, 0 deletions
diff --git a/extensions/source/bibliography/framectr.cxx b/extensions/source/bibliography/framectr.cxx
new file mode 100644
index 0000000000..758c8b3484
--- /dev/null
+++ b/extensions/source/bibliography/framectr.cxx
@@ -0,0 +1,874 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <comphelper/types.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/sequence.hxx>
+#include "framectr.hxx"
+#include "datman.hxx"
+#include <toolkit/helper/vclunohelper.hxx>
+#include "bibconfig.hxx"
+#include <cppuhelper/implbase.hxx>
+#include <utility>
+#include <vcl/event.hxx>
+#include <vcl/svapp.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/awt/XTextComponent.hpp>
+#include <com/sun/star/awt/XVclWindowPeer.hpp>
+#include <com/sun/star/form/XConfirmDeleteListener.hpp>
+#include <com/sun/star/form/runtime/XFormController.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/sdbcx/Privilege.hpp>
+#include <com/sun/star/sdbc/XResultSetUpdate.hpp>
+#include <com/sun/star/sdb/FilterDialog.hpp>
+#include <com/sun/star/sdb/RowChangeAction.hpp>
+#include <com/sun/star/frame/CommandGroup.hpp>
+#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
+#include <comphelper/multicontainer2.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <sot/exchange.hxx>
+#include <sot/formats.hxx>
+#include <comphelper/diagnose_ex.hxx>
+#include <vcl/weld.hxx>
+#include <osl/mutex.hxx>
+
+#include <unordered_map>
+
+using namespace osl;
+using namespace cppu;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::uno;
+using namespace com::sun::star;
+
+namespace {
+
+struct DispatchInfo
+{
+ const char* pCommand;
+ sal_Int16 nGroupId;
+ bool bActiveConnection;
+};
+
+struct CacheDispatchInfo
+{
+ sal_Int16 nGroupId;
+ bool bActiveConnection;
+};
+
+}
+
+// Attention: commands must be sorted by command groups. Implementation is dependent
+// on this!!
+const DispatchInfo SupportedCommandsArray[] =
+{
+ { ".uno:Undo" , frame::CommandGroup::EDIT , false },
+ { ".uno:Cut" , frame::CommandGroup::EDIT , false },
+ { ".uno:Copy" , frame::CommandGroup::EDIT , false },
+ { ".uno:Paste" , frame::CommandGroup::EDIT , false },
+ { ".uno:SelectAll" , frame::CommandGroup::EDIT , false },
+ { ".uno:CloseDoc" , frame::CommandGroup::DOCUMENT , false },
+ { ".uno:StatusBarVisible" , frame::CommandGroup::VIEW , false },
+ { ".uno:AvailableToolbars" , frame::CommandGroup::VIEW , false },
+ { ".uno:Bib/standardFilter" , frame::CommandGroup::DATA , true },
+ { ".uno:Bib/DeleteRecord" , frame::CommandGroup::DATA , true },
+ { ".uno:Bib/InsertRecord" , frame::CommandGroup::DATA , true },
+ { ".uno:Bib/query" , frame::CommandGroup::DATA , true },
+ { ".uno:Bib/autoFilter" , frame::CommandGroup::DATA , true },
+ { ".uno:Bib/source" , frame::CommandGroup::DATA , true },
+ { ".uno:Bib/removeFilter" , frame::CommandGroup::DATA , true },
+ { ".uno:Bib/sdbsource" , frame::CommandGroup::DATA , true },
+ { ".uno:Bib/Mapping" , frame::CommandGroup::DATA , true },
+};
+
+typedef std::unordered_map< OUString, CacheDispatchInfo > CmdToInfoCache;
+
+static const CmdToInfoCache& GetCommandToInfoCache()
+{
+ static CmdToInfoCache aCmdToInfoCache = []() {
+ CmdToInfoCache aCache;
+ for (const auto& command : SupportedCommandsArray)
+ {
+ OUString aCommand(OUString::createFromAscii(command.pCommand));
+
+ CacheDispatchInfo aDispatchInfo;
+ aDispatchInfo.nGroupId = command.nGroupId;
+ aDispatchInfo.bActiveConnection = command.bActiveConnection;
+ aCache.emplace(aCommand, aDispatchInfo);
+ }
+ return aCache;
+ }();
+
+ return aCmdToInfoCache;
+}
+
+
+class BibFrameCtrl_Impl : public cppu::WeakImplHelper < XFrameActionListener >
+{
+public:
+ Mutex aMutex;
+ comphelper::OMultiTypeInterfaceContainerHelper2 aLC;
+
+ BibFrameController_Impl* pController;
+
+ BibFrameCtrl_Impl()
+ : aLC( aMutex )
+ , pController(nullptr)
+ {}
+
+ virtual void SAL_CALL frameAction(const FrameActionEvent& aEvent) override;
+ virtual void SAL_CALL disposing( const lang::EventObject& Source ) override;
+};
+
+void BibFrameCtrl_Impl::frameAction(const FrameActionEvent& )
+{
+}
+
+void BibFrameCtrl_Impl::disposing( const lang::EventObject& /*Source*/ )
+{
+ ::SolarMutexGuard aGuard;
+ if ( pController )
+ pController->getFrame()->removeFrameActionListener( this );
+}
+
+BibFrameController_Impl::BibFrameController_Impl( uno::Reference< awt::XWindow > xComponent,
+ BibDataManager* pDataManager)
+ :m_xWindow(std::move( xComponent ))
+ ,m_xDatMan( pDataManager )
+{
+ m_bDisposing = false;
+ m_xImpl = new BibFrameCtrl_Impl;
+ m_xImpl->pController = this;
+}
+
+BibFrameController_Impl::~BibFrameController_Impl()
+{
+ m_xImpl->pController = nullptr;
+ m_xDatMan.clear();
+}
+
+OUString SAL_CALL BibFrameController_Impl::getImplementationName()
+{
+ return "com.sun.star.comp.extensions.Bibliography";
+}
+
+sal_Bool SAL_CALL BibFrameController_Impl::supportsService( const OUString& sServiceName )
+{
+ return cppu::supportsService( this, sServiceName );
+}
+
+css::uno::Sequence< OUString > SAL_CALL BibFrameController_Impl::getSupportedServiceNames()
+{
+ // return only top level services ...
+ // base services are included there and should be asked by uno-rtti.
+ return { "com.sun.star.frame.Bibliography" };
+}
+
+void BibFrameController_Impl::attachFrame( const uno::Reference< XFrame > & xArg )
+{
+ m_xFrame = xArg;
+ m_xFrame->addFrameActionListener( m_xImpl );
+}
+
+sal_Bool BibFrameController_Impl::attachModel( const uno::Reference< XModel > & /*xModel*/ )
+{
+ return false;
+}
+
+sal_Bool BibFrameController_Impl::suspend( sal_Bool bSuspend )
+{
+ if ( bSuspend )
+ getFrame()->removeFrameActionListener( m_xImpl );
+ else
+ getFrame()->addFrameActionListener( m_xImpl );
+ return true;
+}
+
+uno::Any BibFrameController_Impl::getViewData()
+{
+ return uno::Any();
+}
+
+void BibFrameController_Impl::restoreViewData( const uno::Any& /*Value*/ )
+{
+}
+
+uno::Reference< XFrame > BibFrameController_Impl::getFrame()
+{
+ return m_xFrame;
+}
+
+uno::Reference< XModel > BibFrameController_Impl::getModel()
+{
+ return uno::Reference< XModel > ();
+}
+
+void BibFrameController_Impl::dispose()
+{
+ m_bDisposing = true;
+ lang::EventObject aObject;
+ uno::Reference< XFrame > xFrame = getFrame();
+
+ if (xFrame.is())
+ xFrame->removeFrameActionListener( m_xImpl );
+ m_xFrame.clear();
+
+ aObject.Source = static_cast<XController*>(this);
+ m_xImpl->aLC.disposeAndClear(aObject);
+ m_xDatMan.clear();
+ m_aStatusListeners.clear();
+ m_xLastQueriedFocusWin.clear();
+ m_xWindow.clear();
+ m_xImpl.clear();
+}
+
+void BibFrameController_Impl::addEventListener( const uno::Reference< lang::XEventListener > & aListener )
+{
+ m_xImpl->aLC.addInterface( cppu::UnoType<lang::XEventListener>::get(), aListener );
+}
+
+void BibFrameController_Impl::removeEventListener( const uno::Reference< lang::XEventListener > & aListener )
+{
+ m_xImpl->aLC.removeInterface( cppu::UnoType<lang::XEventListener>::get(), aListener );
+}
+
+uno::Reference< frame::XDispatch > BibFrameController_Impl::queryDispatch( const util::URL& aURL, const OUString& /*aTarget*/, sal_Int32 /*nSearchFlags*/ )
+{
+ if ( !m_bDisposing )
+ {
+ const CmdToInfoCache& rCmdCache = GetCommandToInfoCache();
+ CmdToInfoCache::const_iterator pIter = rCmdCache.find( aURL.Complete );
+ if ( pIter != rCmdCache.end() )
+ {
+ if (( m_xDatMan->HasActiveConnection() ) ||
+ ( !pIter->second.bActiveConnection ))
+ return static_cast<frame::XDispatch*>(this);
+ }
+ }
+
+ return uno::Reference< frame::XDispatch > ();
+}
+
+uno::Sequence<uno::Reference< XDispatch > > BibFrameController_Impl::queryDispatches( const uno::Sequence<DispatchDescriptor>& aDescripts )
+{
+ uno::Sequence< uno::Reference< XDispatch > > aDispatches( aDescripts.getLength() );
+ auto aDispatchesRange = asNonConstRange(aDispatches);
+ for ( sal_Int32 i=0; i<aDescripts.getLength(); ++i )
+ aDispatchesRange[i] = queryDispatch( aDescripts[i].FeatureURL, aDescripts[i].FrameName, aDescripts[i].SearchFlags );
+ return aDispatches;
+}
+
+uno::Sequence< ::sal_Int16 > SAL_CALL BibFrameController_Impl::getSupportedCommandGroups()
+{
+ uno::Sequence< ::sal_Int16 > aDispatchInfo{ frame::CommandGroup::EDIT,
+ frame::CommandGroup::DOCUMENT,
+ frame::CommandGroup::DATA,
+ frame::CommandGroup::VIEW };
+
+ return aDispatchInfo;
+}
+
+uno::Sequence< frame::DispatchInformation > SAL_CALL BibFrameController_Impl::getConfigurableDispatchInformation( ::sal_Int16 nCommandGroup )
+{
+ const CmdToInfoCache& rCmdCache = GetCommandToInfoCache();
+
+ frame::DispatchInformation aDispatchInfo;
+ std::vector< frame::DispatchInformation > aDispatchInfoVector;
+
+ if (( nCommandGroup == frame::CommandGroup::EDIT ) ||
+ ( nCommandGroup == frame::CommandGroup::DOCUMENT ) ||
+ ( nCommandGroup == frame::CommandGroup::DATA ) ||
+ ( nCommandGroup == frame::CommandGroup::VIEW ))
+ {
+ bool bGroupFound = false;
+ for (auto const& item : rCmdCache)
+ {
+ if ( item.second.nGroupId == nCommandGroup )
+ {
+ bGroupFound = true;
+ aDispatchInfo.Command = item.first;
+ aDispatchInfo.GroupId = item.second.nGroupId;
+ aDispatchInfoVector.push_back( aDispatchInfo );
+ }
+ else if ( bGroupFound )
+ break;
+ }
+ }
+
+ return comphelper::containerToSequence( aDispatchInfoVector );
+}
+
+static bool canInsertRecords(const Reference< beans::XPropertySet>& _rxCursorSet)
+{
+ sal_Int32 nPriv = 0;
+ _rxCursorSet->getPropertyValue("Privileges") >>= nPriv;
+ return _rxCursorSet.is() && (nPriv & sdbcx::Privilege::INSERT) != 0;
+}
+
+bool BibFrameController_Impl::SaveModified(const Reference< form::runtime::XFormController>& xController)
+{
+ if (!xController.is())
+ return false;
+
+ Reference< XResultSetUpdate> _xCursor(xController->getModel(), UNO_QUERY);
+
+ if (!_xCursor.is())
+ return false;
+
+ Reference< beans::XPropertySet> _xSet(_xCursor, UNO_QUERY);
+ if (!_xSet.is())
+ return false;
+
+ // need to save?
+ bool bIsNew = ::comphelper::getBOOL(_xSet->getPropertyValue("IsNew"));
+ bool bIsModified = ::comphelper::getBOOL(_xSet->getPropertyValue("IsModified"));
+ bool bResult = !bIsModified;
+ if (bIsModified)
+ {
+ try
+ {
+ if (bIsNew)
+ _xCursor->insertRow();
+ else
+ _xCursor->updateRow();
+ bResult = true;
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("extensions.biblio", "");
+ }
+ }
+ return bResult;
+}
+
+static vcl::Window* lcl_GetFocusChild( vcl::Window const * pParent )
+{
+ sal_uInt16 nChildren = pParent->GetChildCount();
+ for( sal_uInt16 nChild = 0; nChild < nChildren; ++nChild)
+ {
+ vcl::Window* pChild = pParent->GetChild( nChild );
+ if(pChild->HasFocus())
+ return pChild;
+ vcl::Window* pSubChild = lcl_GetFocusChild( pChild );
+ if(pSubChild)
+ return pSubChild;
+ }
+ return nullptr;
+}
+
+//class XDispatch
+void BibFrameController_Impl::dispatch(const util::URL& _rURL, const uno::Sequence< beans::PropertyValue >& aArgs)
+{
+ if ( m_bDisposing )
+ return;
+
+ ::SolarMutexGuard aGuard;
+ weld::Window* pParent = Application::GetFrameWeld(m_xWindow);
+ weld::WaitObject aWaitObject(pParent);
+
+ OUString aCommand( _rURL.Path);
+ if(aCommand == "Bib/Mapping")
+ {
+ m_xDatMan->CreateMappingDialog(pParent);
+ }
+ else if(aCommand == "Bib/source")
+ {
+ ChangeDataSource(aArgs);
+ }
+ else if(aCommand == "Bib/sdbsource")
+ {
+ OUString aURL = m_xDatMan->CreateDBChangeDialog(pParent);
+ if(!aURL.isEmpty())
+ {
+ try
+ {
+ uno::Sequence< beans::PropertyValue > aNewDataSource
+ {
+ comphelper::makePropertyValue( {}, OUString() ),
+ comphelper::makePropertyValue( {}, aURL )
+ };
+ ChangeDataSource(aNewDataSource);
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("extensions.biblio",
+ "Exception caught while changing the data source");
+ }
+ }
+ }
+ else if(aCommand == "Bib/autoFilter")
+ {
+ sal_uInt16 nCount = m_aStatusListeners.size();
+ for ( sal_uInt16 n=0; n<nCount; n++ )
+ {
+ BibStatusDispatch *pObj = m_aStatusListeners[n].get();
+ if ( pObj->aURL.Path == "Bib/removeFilter" )
+ {
+ FeatureStateEvent aEvent;
+ aEvent.FeatureURL = pObj->aURL;
+ aEvent.IsEnabled = true;
+ aEvent.Requery = false;
+ aEvent.Source = static_cast<XDispatch *>(this);
+ pObj->xListener->statusChanged( aEvent );
+ //break; because there are more than one
+ }
+ }
+
+ const beans::PropertyValue* pPropertyValue = aArgs.getConstArray();
+ uno::Any aValue=pPropertyValue[0].Value;
+ OUString aQuery;
+ aValue >>= aQuery;
+
+ aValue=pPropertyValue[1].Value;
+ OUString aQueryField;
+ aValue >>= aQueryField;
+ BibConfig* pConfig = BibModul::GetConfig();
+ pConfig->setQueryField(aQueryField);
+ m_xDatMan->startQueryWith(aQuery);
+ }
+ else if(aCommand == "Bib/standardFilter")
+ {
+ try
+ {
+ uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+
+ // create the dialog object
+ uno::Reference< ui::dialogs::XExecutableDialog > xDialog = sdb::FilterDialog::createWithQuery(xContext, m_xDatMan->getParser(),
+ Reference<sdbc::XRowSet>(m_xDatMan->getForm(), uno::UNO_QUERY_THROW), m_xWindow);
+ // execute it
+ if ( xDialog->execute( ) )
+ {
+ // the dialog has been executed successfully, and the filter on the query composer
+ // has been changed
+ OUString sNewFilter = m_xDatMan->getParser()->getFilter();
+ m_xDatMan->setFilter( sNewFilter );
+ }
+ }
+ catch( const uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "extensions.biblio", "BibFrameController_Impl::dispatch" );
+ }
+
+ sal_uInt16 nCount = m_aStatusListeners.size();
+ for ( sal_uInt16 n=0; n<nCount; n++ )
+ {
+ BibStatusDispatch *pObj = m_aStatusListeners[n].get();
+ if ( pObj->aURL.Path == "Bib/removeFilter" && m_xDatMan->getParser().is())
+ {
+ FeatureStateEvent aEvent;
+ aEvent.FeatureURL = pObj->aURL;
+ aEvent.IsEnabled = !m_xDatMan->getParser()->getFilter().isEmpty();
+ aEvent.Requery = false;
+ aEvent.Source = static_cast<XDispatch *>(this);
+ pObj->xListener->statusChanged( aEvent );
+ }
+ }
+ }
+ else if(aCommand == "Bib/removeFilter")
+ {
+ RemoveFilter();
+ }
+ else if( _rURL.Complete == ".uno:CloseDoc" || aCommand == "CloseDoc" )
+ {
+ Application::PostUserEvent( LINK( this, BibFrameController_Impl,
+ DisposeHdl ) );
+
+ }
+ else if(aCommand == "Bib/InsertRecord")
+ {
+ Reference<form::runtime::XFormController > xFormCtrl = m_xDatMan->GetFormController();
+ if(SaveModified(xFormCtrl))
+ {
+ try
+ {
+ Reference< sdbc::XResultSet > xCursor( m_xDatMan->getForm(), UNO_QUERY );
+ xCursor->last();
+
+ Reference< XResultSetUpdate > xUpdateCursor( m_xDatMan->getForm(), UNO_QUERY );
+ xUpdateCursor->moveToInsertRow();
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("extensions.biblio",
+ "Exception in last() or moveToInsertRow()");
+ }
+ }
+ }
+ else if(aCommand == "Bib/DeleteRecord")
+ {
+ Reference< css::sdbc::XResultSet > xCursor(m_xDatMan->getForm(), UNO_QUERY);
+ Reference< XResultSetUpdate > xUpdateCursor(xCursor, UNO_QUERY);
+ Reference< beans::XPropertySet > xSet(m_xDatMan->getForm(), UNO_QUERY);
+ bool bIsNew = ::comphelper::getBOOL(xSet->getPropertyValue("IsNew"));
+ if(!bIsNew)
+ {
+ sal_uInt32 nCount = 0;
+ xSet->getPropertyValue("RowCount") >>= nCount;
+ // determine next position
+ bool bSuccess = false;
+ bool bLeft = false;
+ bool bRight = false;
+ try
+ {
+ bLeft = xCursor->isLast() && nCount > 1;
+ bRight= !xCursor->isLast();
+ // ask for confirmation
+ Reference< form::XConfirmDeleteListener > xConfirm(m_xDatMan->GetFormController(),UNO_QUERY);
+ if (xConfirm.is())
+ {
+ sdb::RowChangeEvent aEvent;
+ aEvent.Source.set(xCursor, UNO_QUERY);
+ aEvent.Action = sdb::RowChangeAction::DELETE;
+ aEvent.Rows = 1;
+ bSuccess = xConfirm->confirmDelete(aEvent);
+ }
+
+ // delete it
+ if (bSuccess)
+ xUpdateCursor->deleteRow();
+ }
+ catch(const Exception&)
+ {
+ bSuccess = false;
+ }
+ if (bSuccess)
+ {
+ if (bLeft || bRight)
+ xCursor->relative(bRight ? 1 : -1);
+ else
+ {
+ bool bCanInsert = canInsertRecords(xSet);
+ // can another entry be inserted?
+ try
+ {
+ if (bCanInsert)
+ xUpdateCursor->moveToInsertRow();
+ else
+ // move data entry to reset state
+ xCursor->first();
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("extensions.biblio",
+ "DeleteRecord: exception caught!");
+ }
+ }
+ }
+ }
+ }
+ else if(aCommand == "Cut")
+ {
+ vcl::Window* pChild = m_xLastQueriedFocusWin.get();
+ if(pChild)
+ {
+ KeyEvent aEvent( 0, KeyFuncType::CUT );
+ pChild->KeyInput( aEvent );
+ }
+ }
+ else if(aCommand == "Copy")
+ {
+ vcl::Window* pChild = m_xLastQueriedFocusWin.get();
+ if(pChild)
+ {
+ KeyEvent aEvent( 0, KeyFuncType::COPY );
+ pChild->KeyInput( aEvent );
+ }
+ }
+ else if(aCommand == "Paste")
+ {
+ vcl::Window* pChild = m_xLastQueriedFocusWin.get();
+ if(pChild)
+ {
+ KeyEvent aEvent( 0, KeyFuncType::PASTE );
+ pChild->KeyInput( aEvent );
+ }
+ }
+}
+IMPL_LINK_NOARG( BibFrameController_Impl, DisposeHdl, void*, void )
+{
+ if (m_xFrame.is())
+ m_xFrame->dispose();
+};
+
+void BibFrameController_Impl::addStatusListener(
+ const uno::Reference< frame::XStatusListener > & aListener,
+ const util::URL& aURL)
+{
+ BibConfig* pConfig = BibModul::GetConfig();
+ // create a new Reference and insert into listener array
+ m_aStatusListeners.push_back( std::make_unique<BibStatusDispatch>( aURL, aListener ) );
+
+ // send first status synchronously
+ FeatureStateEvent aEvent;
+ aEvent.FeatureURL = aURL;
+ aEvent.Requery = false;
+ aEvent.Source = static_cast<XDispatch *>(this);
+ if ( aURL.Path == "StatusBarVisible" )
+ {
+ aEvent.IsEnabled = false;
+ aEvent.State <<= false;
+ }
+ else if ( aURL.Path == "Bib/hierarchical" )
+ {
+ aEvent.IsEnabled = true;
+ aEvent.State <<= OUString();
+ }
+ else if(aURL.Path == "Bib/MenuFilter")
+ {
+ aEvent.IsEnabled = true;
+ aEvent.FeatureDescriptor=m_xDatMan->getQueryField();
+
+ aEvent.State <<= m_xDatMan->getQueryFields();
+
+ }
+ else if ( aURL.Path == "Bib/source")
+ {
+ aEvent.IsEnabled = true;
+ aEvent.FeatureDescriptor=m_xDatMan->getActiveDataTable();
+
+ aEvent.State <<= m_xDatMan->getDataSources();
+ }
+ else if( aURL.Path == "Bib/sdbsource" ||
+ aURL.Path == "Bib/Mapping" ||
+ aURL.Path == "Bib/autoFilter" ||
+ aURL.Path == "Bib/standardFilter" )
+ {
+ aEvent.IsEnabled = true;
+ }
+ else if(aURL.Path == "Bib/query")
+ {
+ aEvent.IsEnabled = true;
+ aEvent.State <<= pConfig->getQueryText();
+ }
+ else if (aURL.Path == "Bib/removeFilter" )
+ {
+ OUString aFilterStr=m_xDatMan->getFilter();
+ aEvent.IsEnabled = !aFilterStr.isEmpty();
+ }
+ else if(aURL.Path == "Cut")
+ {
+ m_xLastQueriedFocusWin = lcl_GetFocusChild( VCLUnoHelper::GetWindow( m_xWindow ) );
+ if (m_xLastQueriedFocusWin)
+ {
+ Reference<css::awt::XTextComponent> xEdit(m_xLastQueriedFocusWin->GetComponentInterface(), css::uno::UNO_QUERY);
+ aEvent.IsEnabled = xEdit && xEdit->isEditable() && !xEdit->getSelectedText().isEmpty();
+ }
+ }
+ if(aURL.Path == "Copy")
+ {
+ m_xLastQueriedFocusWin = lcl_GetFocusChild( VCLUnoHelper::GetWindow( m_xWindow ) );
+ if (m_xLastQueriedFocusWin)
+ {
+ Reference<css::awt::XTextComponent> xEdit(m_xLastQueriedFocusWin->GetComponentInterface(), css::uno::UNO_QUERY);
+ aEvent.IsEnabled = xEdit && !xEdit->getSelectedText().isEmpty();
+ }
+ }
+ else if(aURL.Path == "Paste" )
+ {
+ aEvent.IsEnabled = false;
+ m_xLastQueriedFocusWin = lcl_GetFocusChild( VCLUnoHelper::GetWindow( m_xWindow ) );
+ if (m_xLastQueriedFocusWin)
+ {
+ Reference<css::awt::XTextComponent> xEdit(m_xLastQueriedFocusWin->GetComponentInterface(), css::uno::UNO_QUERY);
+ if (xEdit && !xEdit->isEditable())
+ {
+ uno::Reference< datatransfer::clipboard::XClipboard > xClip = m_xLastQueriedFocusWin->GetClipboard();
+ if(xClip.is())
+ {
+ uno::Reference< datatransfer::XTransferable > xDataObj;
+
+ try
+ {
+ SolarMutexReleaser aReleaser;
+ xDataObj = xClip->getContents();
+ }
+ catch( const uno::Exception& )
+ {
+ }
+
+ if ( xDataObj.is() )
+ {
+ datatransfer::DataFlavor aFlavor;
+ SotExchange::GetFormatDataFlavor( SotClipboardFormatId::STRING, aFlavor );
+ try
+ {
+ uno::Any aData = xDataObj->getTransferData( aFlavor );
+ OUString aText;
+ aData >>= aText;
+ aEvent.IsEnabled = !aText.isEmpty();
+ }
+ catch( const uno::Exception& )
+ {
+ }
+ }
+ }
+ }
+ }
+ }
+ else if(aURL.Path == "Bib/DeleteRecord")
+ {
+ Reference< beans::XPropertySet > xSet(m_xDatMan->getForm(), UNO_QUERY);
+ bool bIsNew = ::comphelper::getBOOL(xSet->getPropertyValue("IsNew"));
+ if(!bIsNew)
+ {
+ sal_uInt32 nCount = 0;
+ xSet->getPropertyValue("RowCount") >>= nCount;
+ aEvent.IsEnabled = nCount > 0;
+ }
+ }
+ else if (aURL.Path == "Bib/InsertRecord")
+ {
+ Reference< beans::XPropertySet > xSet(m_xDatMan->getForm(), UNO_QUERY);
+ aEvent.IsEnabled = canInsertRecords(xSet);
+ }
+ aListener->statusChanged( aEvent );
+}
+
+void BibFrameController_Impl::removeStatusListener(
+ const uno::Reference< frame::XStatusListener > & aObject, const util::URL& aURL)
+{
+ // search listener array for given listener
+ // for checking equality always "cast" to XInterface
+ if ( m_bDisposing )
+ return;
+
+ sal_uInt16 nCount = m_aStatusListeners.size();
+ for ( sal_uInt16 n=0; n<nCount; n++ )
+ {
+ BibStatusDispatch *pObj = m_aStatusListeners[n].get();
+ bool bFlag=pObj->xListener.is();
+ if (!bFlag || (pObj->xListener == aObject &&
+ ( aURL.Complete.isEmpty() || pObj->aURL.Path == aURL.Path )))
+ {
+ m_aStatusListeners.erase( m_aStatusListeners.begin() + n );
+ break;
+ }
+ }
+}
+
+void BibFrameController_Impl::RemoveFilter()
+{
+ OUString aQuery;
+ m_xDatMan->startQueryWith(aQuery);
+
+ sal_uInt16 nCount = m_aStatusListeners.size();
+
+ bool bRemoveFilter=false;
+ bool bQueryText=false;
+
+ for ( sal_uInt16 n=0; n<nCount; n++ )
+ {
+ BibStatusDispatch *pObj = m_aStatusListeners[n].get();
+ if ( pObj->aURL.Path == "Bib/removeFilter" )
+ {
+ FeatureStateEvent aEvent;
+ aEvent.FeatureURL = pObj->aURL;
+ aEvent.IsEnabled = false;
+ aEvent.Requery = false;
+ aEvent.Source = static_cast<XDispatch *>(this);
+ pObj->xListener->statusChanged( aEvent );
+ bRemoveFilter=true;
+ }
+ else if(pObj->aURL.Path == "Bib/query")
+ {
+ FeatureStateEvent aEvent;
+ aEvent.FeatureURL = pObj->aURL;
+ aEvent.IsEnabled = true;
+ aEvent.Requery = false;
+ aEvent.Source = static_cast<XDispatch *>(this);
+ aEvent.State <<= aQuery;
+ pObj->xListener->statusChanged( aEvent );
+ bQueryText=true;
+ }
+
+ if(bRemoveFilter && bQueryText)
+ break;
+
+ }
+}
+
+void BibFrameController_Impl::ChangeDataSource(const uno::Sequence< beans::PropertyValue >& aArgs)
+{
+ const beans::PropertyValue* pPropertyValue = aArgs.getConstArray();
+ uno::Any aValue=pPropertyValue[0].Value;
+ OUString aDBTableName;
+ aValue >>= aDBTableName;
+
+
+ if(aArgs.getLength() > 1)
+ {
+ uno::Any aDB = pPropertyValue[1].Value;
+ OUString aURL;
+ aDB >>= aURL;
+ m_xDatMan->setActiveDataSource(aURL);
+ aDBTableName = m_xDatMan->getActiveDataTable();
+ }
+ else
+ {
+ Reference<css::form::XLoadable> xLoadable(m_xDatMan);
+ xLoadable->unload();
+ m_xDatMan->setActiveDataTable(aDBTableName);
+ m_xDatMan->updateGridModel();
+ xLoadable->load();
+ }
+
+
+ sal_uInt16 nCount = m_aStatusListeners.size();
+
+ bool bMenuFilter=false;
+ bool bQueryText=false;
+ for ( sal_uInt16 n=0; n<nCount; n++ )
+ {
+ BibStatusDispatch *pObj = m_aStatusListeners[n].get();
+ if (pObj->aURL.Path == "Bib/MenuFilter")
+ {
+ FeatureStateEvent aEvent;
+ aEvent.FeatureURL = pObj->aURL;
+ aEvent.IsEnabled = true;
+ aEvent.Requery = false;
+ aEvent.Source = static_cast<XDispatch *>(this);
+ aEvent.FeatureDescriptor=m_xDatMan->getQueryField();
+
+ uno::Sequence<OUString> aStringSeq=m_xDatMan->getQueryFields();
+ aEvent.State <<= aStringSeq;
+
+ pObj->xListener->statusChanged( aEvent );
+ bMenuFilter=true;
+ }
+ else if (pObj->aURL.Path == "Bib/query")
+ {
+ FeatureStateEvent aEvent;
+ aEvent.FeatureURL = pObj->aURL;
+ aEvent.IsEnabled = true;
+ aEvent.Requery = false;
+ aEvent.Source = static_cast<XDispatch *>(this);
+ BibConfig* pConfig = BibModul::GetConfig();
+ aEvent.State <<= pConfig->getQueryText();
+ pObj->xListener->statusChanged( aEvent );
+ bQueryText=true;
+ }
+
+ if (bMenuFilter && bQueryText)
+ break;
+
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */