summaryrefslogtreecommitdiffstats
path: root/extensions/source/bibliography
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/source/bibliography')
-rw-r--r--extensions/source/bibliography/bib.component27
-rw-r--r--extensions/source/bibliography/bibbeam.cxx267
-rw-r--r--extensions/source/bibliography/bibbeam.hxx71
-rw-r--r--extensions/source/bibliography/bibconfig.cxx297
-rw-r--r--extensions/source/bibliography/bibconfig.hxx153
-rw-r--r--extensions/source/bibliography/bibcont.cxx241
-rw-r--r--extensions/source/bibliography/bibcont.hxx93
-rw-r--r--extensions/source/bibliography/bibload.cxx609
-rw-r--r--extensions/source/bibliography/bibmod.cxx89
-rw-r--r--extensions/source/bibliography/bibmod.hxx50
-rw-r--r--extensions/source/bibliography/bibresid.hxx27
-rw-r--r--extensions/source/bibliography/bibshortcuthandler.hxx66
-rw-r--r--extensions/source/bibliography/bibtools.hxx42
-rw-r--r--extensions/source/bibliography/bibview.cxx189
-rw-r--r--extensions/source/bibliography/bibview.hxx83
-rw-r--r--extensions/source/bibliography/datman.cxx1390
-rw-r--r--extensions/source/bibliography/datman.hxx169
-rw-r--r--extensions/source/bibliography/formcontrolcontainer.cxx136
-rw-r--r--extensions/source/bibliography/formcontrolcontainer.hxx65
-rw-r--r--extensions/source/bibliography/framectr.cxx869
-rw-r--r--extensions/source/bibliography/framectr.hxx117
-rw-r--r--extensions/source/bibliography/general.cxx876
-rw-r--r--extensions/source/bibliography/general.hxx158
-rw-r--r--extensions/source/bibliography/loadlisteneradapter.cxx185
-rw-r--r--extensions/source/bibliography/loadlisteneradapter.hxx151
-rw-r--r--extensions/source/bibliography/toolbar.cxx620
-rw-r--r--extensions/source/bibliography/toolbar.hxx217
27 files changed, 7257 insertions, 0 deletions
diff --git a/extensions/source/bibliography/bib.component b/extensions/source/bibliography/bib.component
new file mode 100644
index 000000000..19841cc9e
--- /dev/null
+++ b/extensions/source/bibliography/bib.component
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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 .
+ -->
+
+<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.extensions.Bibliography"
+ constructor="extensions_BibliographyLoader_get_implementation">
+ <service name="com.sun.star.frame.Bibliography"/>
+ <service name="com.sun.star.frame.FrameLoader"/>
+ </implementation>
+</component>
diff --git a/extensions/source/bibliography/bibbeam.cxx b/extensions/source/bibliography/bibbeam.cxx
new file mode 100644
index 000000000..a38c72385
--- /dev/null
+++ b/extensions/source/bibliography/bibbeam.cxx
@@ -0,0 +1,267 @@
+/* -*- 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 <toolkit/helper/vclunohelper.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <vcl/taskpanelist.hxx>
+#include <tools/debug.hxx>
+#include "bibbeam.hxx"
+#include "datman.hxx"
+#include "bibtools.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+
+
+#define ID_TOOLBAR 1
+#define ID_GRIDWIN 2
+
+namespace bib
+{
+
+ void HandleTaskPaneList( vcl::Window* pWindow, bool bAddToList )
+ {
+ vcl::Window* pParent = pWindow->GetParent();
+
+ DBG_ASSERT( pParent, "-GetTaskPaneList(): everybody here should have a parent!" );
+
+ SystemWindow* pSysWin = pParent->GetSystemWindow();
+ if( pSysWin )
+ {
+ TaskPaneList* pTaskPaneList = pSysWin->GetTaskPaneList();
+ if( pTaskPaneList )
+ {
+ if( bAddToList )
+ pTaskPaneList->AddWindow( pWindow );
+ else
+ pTaskPaneList->RemoveWindow( pWindow );
+ }
+ }
+ }
+
+
+ class BibGridwin
+ :public vcl::Window //DockingWindow
+ {
+ private:
+ Reference< awt::XWindow > m_xGridWin;
+ Reference< awt::XControlModel > m_xGridModel;
+ Reference< awt::XControl > m_xControl;
+ Reference< awt::XControlContainer > m_xControlContainer;
+ Reference< frame::XDispatchProviderInterception> m_xDispatchProviderInterception;
+
+ protected:
+
+ virtual void Resize() override;
+
+ public:
+
+ BibGridwin(vcl::Window* pParent, WinBits nStyle );
+ virtual ~BibGridwin() override;
+ virtual void dispose() override;
+
+ void createGridWin(const Reference< awt::XControlModel > & xDbForm);
+ void disposeGridWin();
+
+ const Reference< awt::XControlContainer >& getControlContainer() const { return m_xControlContainer; }
+ const Reference< frame::XDispatchProviderInterception>& getDispatchProviderInterception() const { return m_xDispatchProviderInterception; }
+
+ virtual void GetFocus() override;
+ };
+
+ BibGridwin::BibGridwin( vcl::Window* _pParent, WinBits _nStyle ) : Window( _pParent, _nStyle )
+ {
+ m_xControlContainer = VCLUnoHelper::CreateControlContainer(this);
+
+ AddToTaskPaneList( this );
+ }
+
+ BibGridwin::~BibGridwin()
+ {
+ disposeOnce();
+ }
+
+ void BibGridwin::dispose()
+ {
+ RemoveFromTaskPaneList( this );
+
+ disposeGridWin();
+ vcl::Window::dispose();
+ }
+
+ void BibGridwin::Resize()
+ {
+ if(m_xGridWin.is())
+ {
+ ::Size aSize = GetOutputSizePixel();
+ m_xGridWin->setPosSize(0, 0, aSize.Width(),aSize.Height(), awt::PosSize::SIZE);
+ }
+ }
+
+ void BibGridwin::createGridWin(const uno::Reference< awt::XControlModel > & xGModel)
+ {
+ m_xGridModel = xGModel;
+
+ if( !m_xControlContainer.is())
+ return;
+
+ uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
+
+ if ( !m_xGridModel.is())
+ return;
+
+ uno::Reference< XPropertySet > xPropSet( m_xGridModel, UNO_QUERY );
+
+ if ( xPropSet.is() && m_xGridModel.is() )
+ {
+ uno::Any aAny = xPropSet->getPropertyValue( "DefaultControl" );
+ OUString aControlName;
+ aAny >>= aControlName;
+
+ m_xControl.set( xContext->getServiceManager()->createInstanceWithContext(aControlName, xContext), UNO_QUERY_THROW );
+ m_xControl->setModel( m_xGridModel );
+ }
+
+ if ( !m_xControl.is() )
+ return;
+
+ // Peer as Child to the FrameWindow
+ m_xControlContainer->addControl("GridControl", m_xControl);
+ m_xGridWin.set(m_xControl, UNO_QUERY );
+ m_xDispatchProviderInterception.set(m_xControl, UNO_QUERY );
+ m_xGridWin->setVisible( true );
+ m_xControl->setDesignMode( true );
+ // initially switch on the design mode - switch it off _after_ loading the form
+
+ ::Size aSize = GetOutputSizePixel();
+ m_xGridWin->setPosSize(0, 0, aSize.Width(),aSize.Height(), awt::PosSize::POSSIZE);
+ }
+
+ void BibGridwin::disposeGridWin()
+ {
+ if ( m_xControl.is() )
+ {
+ Reference< awt::XControl > xDel( m_xControl );
+ m_xControl = nullptr;
+ m_xGridWin = nullptr;
+
+ m_xControlContainer->removeControl( xDel );
+ xDel->dispose();
+ }
+ }
+
+ void BibGridwin::GetFocus()
+ {
+ if(m_xGridWin.is())
+ m_xGridWin->setFocus();
+ }
+
+ BibBeamer::BibBeamer( vcl::Window* _pParent, BibDataManager* _pDM )
+ :BibSplitWindow( _pParent, WB_3DLOOK | WB_NOSPLITDRAW )
+ ,pDatMan( _pDM )
+ ,pToolBar( nullptr )
+ ,pGridWin( nullptr )
+ {
+ createToolBar();
+ createGridWin();
+ pDatMan->SetToolbar(pToolBar);
+ pGridWin->Show();
+ connectForm( pDatMan );
+ }
+
+ BibBeamer::~BibBeamer()
+ {
+ disposeOnce();
+ }
+
+ void BibBeamer::dispose()
+ {
+ if ( isFormConnected() )
+ disconnectForm();
+
+ if ( pToolBar )
+ pDatMan->SetToolbar(nullptr);
+
+ pToolBar.disposeAndClear();
+ pGridWin.disposeAndClear();
+ BibSplitWindow::dispose();
+ }
+
+ void BibBeamer::createToolBar()
+ {
+ pToolBar= VclPtr<BibToolBar>::Create(this, LINK( this, BibBeamer, RecalcLayout_Impl ));
+ ::Size aSize=pToolBar->get_preferred_size();
+ InsertItem(ID_TOOLBAR, pToolBar, aSize.Height(), 0, 0, SplitWindowItemFlags::Fixed );
+ if ( m_xController.is() )
+ pToolBar->SetXController( m_xController );
+ }
+
+ void BibBeamer::createGridWin()
+ {
+ pGridWin = VclPtr<BibGridwin>::Create(this,0);
+
+ InsertItem(ID_GRIDWIN, pGridWin, 40, 1, 0, SplitWindowItemFlags::RelativeSize );
+
+ pGridWin->createGridWin( pDatMan->updateGridModel() );
+ }
+
+ Reference< awt::XControlContainer > BibBeamer::getControlContainer()
+ {
+ Reference< awt::XControlContainer > xReturn;
+ if ( pGridWin )
+ xReturn = pGridWin->getControlContainer();
+ return xReturn;
+ }
+
+ Reference< frame::XDispatchProviderInterception > BibBeamer::getDispatchProviderInterception() const
+ {
+ Reference< frame::XDispatchProviderInterception > xReturn;
+ if ( pGridWin )
+ xReturn = pGridWin->getDispatchProviderInterception();
+ return xReturn;
+ }
+
+ void BibBeamer::SetXController(const uno::Reference< frame::XController > & xCtr)
+ {
+ m_xController = xCtr;
+
+ if ( pToolBar )
+ pToolBar->SetXController( m_xController );
+
+ }
+
+ void BibBeamer::GetFocus()
+ {
+ if( pGridWin )
+ pGridWin->GrabFocus();
+ }
+
+ IMPL_LINK_NOARG( BibBeamer, RecalcLayout_Impl, void*, void )
+ {
+ tools::Long nHeight = pToolBar->get_preferred_size().Height();
+ SetItemSize( ID_TOOLBAR, nHeight );
+ }
+
+} // namespace bib
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/bibbeam.hxx b/extensions/source/bibliography/bibbeam.hxx
new file mode 100644
index 000000000..4cc32d7da
--- /dev/null
+++ b/extensions/source/bibliography/bibbeam.hxx
@@ -0,0 +1,71 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <com/sun/star/awt/XControlContainer.hpp>
+#include <com/sun/star/frame/XDispatchProviderInterception.hpp>
+#include "toolbar.hxx"
+#include "formcontrolcontainer.hxx"
+#include "bibshortcuthandler.hxx"
+
+class BibDataManager;
+
+
+namespace bib
+{
+
+
+ class BibGridwin;
+ class BibBeamer final
+ :public BibSplitWindow
+ ,public FormControlContainer
+ {
+ css::uno::Reference< css::frame::XController > m_xController;
+
+ BibDataManager* pDatMan;
+ VclPtr<BibToolBar> pToolBar;
+ VclPtr<BibGridwin> pGridWin;
+
+ DECL_LINK( RecalcLayout_Impl, void*, void );
+
+ void createToolBar();
+ void createGridWin();
+
+ // FormControlContainer ----------
+ virtual css::uno::Reference< css::awt::XControlContainer >
+ getControlContainer() override;
+ public:
+ css::uno::Reference< css::frame::XDispatchProviderInterception >
+ getDispatchProviderInterception() const;
+
+ BibBeamer(vcl::Window* pParent,BibDataManager* pDatMan );
+ virtual ~BibBeamer() override;
+ virtual void dispose() override;
+
+ void SetXController(const css::uno::Reference< css::frame::XController > &);
+
+ virtual void GetFocus() override;
+ };
+
+
+} // namespace bib
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/bibconfig.cxx b/extensions/source/bibliography/bibconfig.cxx
new file mode 100644
index 000000000..14203ae6c
--- /dev/null
+++ b/extensions/source/bibliography/bibconfig.cxx
@@ -0,0 +1,297 @@
+/* -*- 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 <memory>
+#include "bibconfig.hxx"
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/sdb/DatabaseContext.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <o3tl/any.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdb;
+
+
+constexpr OUStringLiteral cDataSourceHistory = u"DataSourceHistory";
+
+Sequence<OUString> const & BibConfig::GetPropertyNames()
+{
+ static Sequence<OUString> aNames =
+ {
+ "CurrentDataSource/DataSourceName",
+ "CurrentDataSource/Command",
+ "CurrentDataSource/CommandType",
+ "BeamerHeight",
+ "ViewHeight",
+ "QueryText",
+ "QueryField",
+ "ShowColumnAssignmentWarning"
+ };
+ return aNames;
+}
+
+BibConfig::BibConfig()
+ : ConfigItem("Office.DataAccess/Bibliography", ConfigItemMode::NONE)
+ , nTblOrQuery(0)
+ , nBeamerSize(0)
+ , nViewSize(0)
+ , bShowColumnAssignmentWarning(false)
+{
+ //Names of the default columns
+ aColumnDefaults[0] = "Identifier";
+ aColumnDefaults[1] = "BibliographyType";
+ aColumnDefaults[2] = "Author";
+ aColumnDefaults[3] = "Title";
+ aColumnDefaults[4] = "Year";
+ aColumnDefaults[5] = "ISBN";
+ aColumnDefaults[6] = "Booktitle";
+ aColumnDefaults[7] = "Chapter";
+ aColumnDefaults[8] = "Edition";
+ aColumnDefaults[9] = "Editor";
+ aColumnDefaults[10] = "Howpublished";
+ aColumnDefaults[11] = "Institution";
+ aColumnDefaults[12] = "Journal";
+ aColumnDefaults[13] = "Month";
+ aColumnDefaults[14] = "Note";
+ aColumnDefaults[15] = "Annote";
+ aColumnDefaults[16] = "Number";
+ aColumnDefaults[17] = "Organizations";
+ aColumnDefaults[18] = "Pages";
+ aColumnDefaults[19] = "Publisher";
+ aColumnDefaults[20] = "Address";
+ aColumnDefaults[21] = "School";
+ aColumnDefaults[22] = "Series";
+ aColumnDefaults[23] = "ReportType";
+ aColumnDefaults[24] = "Volume";
+ aColumnDefaults[25] = "URL";
+ aColumnDefaults[26] = "Custom1";
+ aColumnDefaults[27] = "Custom2";
+ aColumnDefaults[28] = "Custom3";
+ aColumnDefaults[29] = "Custom4";
+ aColumnDefaults[30] = "Custom5";
+ aColumnDefaults[31] = "LocalURL";
+
+
+ const Sequence< OUString > aPropertyNames = GetPropertyNames();
+ const Sequence<Any> aPropertyValues = GetProperties( aPropertyNames );
+ const Any* pValues = aPropertyValues.getConstArray();
+ if(aPropertyValues.getLength() == aPropertyNames.getLength())
+ {
+ for(int nProp = 0; nProp < aPropertyNames.getLength(); nProp++)
+ {
+ if(pValues[nProp].hasValue())
+ {
+ switch(nProp)
+ {
+ case 0: pValues[nProp] >>= sDataSource; break;
+ case 1: pValues[nProp] >>= sTableOrQuery; break;
+ case 2: pValues[nProp] >>= nTblOrQuery; break;
+ case 3: pValues[nProp] >>= nBeamerSize; break;
+ case 4: pValues[nProp] >>= nViewSize ; break;
+ case 5: pValues[nProp] >>= sQueryText ; break;
+ case 6: pValues[nProp] >>= sQueryField; break;
+ case 7:
+ bShowColumnAssignmentWarning = *o3tl::doAccess<bool>(pValues[nProp]);
+ break;
+ }
+ }
+ }
+ }
+ const Sequence< OUString > aNodeNames = GetNodeNames(cDataSourceHistory);
+ for(OUString const & nodeName : aNodeNames)
+ {
+ Sequence<OUString> aHistoryNames(3);
+ OUString* pHistoryNames = aHistoryNames.getArray();
+
+ OUString sPrefix = OUString::Concat(cDataSourceHistory) + "/" + nodeName + "/";
+ pHistoryNames[0] = sPrefix + "DataSourceName";
+ pHistoryNames[1] = sPrefix + "Command";
+ pHistoryNames[2] = sPrefix + "CommandType";
+
+ Sequence<Any> aHistoryValues = GetProperties( aHistoryNames );
+ const Any* pHistoryValues = aHistoryValues.getConstArray();
+
+ if(aHistoryValues.getLength() == aHistoryNames.getLength())
+ {
+ Mapping* pMapping = new Mapping;
+ pHistoryValues[0] >>= pMapping->sURL;
+ pHistoryValues[1] >>= pMapping->sTableName;
+ pHistoryValues[2] >>= pMapping->nCommandType;
+ //field assignment is contained in another set
+ sPrefix += "Fields";
+ const Sequence< OUString > aAssignmentNodeNames = GetNodeNames(sPrefix);
+ Sequence<OUString> aAssignmentPropertyNames(aAssignmentNodeNames.getLength() * 2);
+ OUString* pAssignmentPropertyNames = aAssignmentPropertyNames.getArray();
+ sal_Int16 nFieldIdx = 0;
+ for(OUString const & assignName : aAssignmentNodeNames)
+ {
+ OUString sSubPrefix = sPrefix + "/" + assignName;
+ pAssignmentPropertyNames[nFieldIdx] = sSubPrefix;
+ pAssignmentPropertyNames[nFieldIdx++] += "/ProgrammaticFieldName";
+ pAssignmentPropertyNames[nFieldIdx] = sSubPrefix;
+ pAssignmentPropertyNames[nFieldIdx++] += "/AssignedFieldName";
+ }
+ Sequence<Any> aAssignmentValues = GetProperties(aAssignmentPropertyNames);
+ const Any* pAssignmentValues = aAssignmentValues.getConstArray();
+ OUString sTempLogical;
+ OUString sTempReal;
+ sal_Int16 nSetMapping = 0;
+ nFieldIdx = 0;
+ for(sal_Int32 nFieldVal = 0; nFieldVal < aAssignmentValues.getLength() / 2; nFieldVal++)
+ {
+ pAssignmentValues[nFieldIdx++] >>= sTempLogical;
+ pAssignmentValues[nFieldIdx++] >>= sTempReal;
+ if(!(sTempLogical.isEmpty() || sTempReal.isEmpty()))
+ {
+ pMapping->aColumnPairs[nSetMapping].sLogicalColumnName = sTempLogical;
+ pMapping->aColumnPairs[nSetMapping++].sRealColumnName = sTempReal;
+ }
+ }
+ mvMappings.push_back(std::unique_ptr<Mapping>(pMapping));
+ }
+ }
+}
+
+BibConfig::~BibConfig()
+{
+ assert(!IsModified()); // should have been committed
+}
+
+BibDBDescriptor BibConfig::GetBibliographyURL()
+{
+ BibDBDescriptor aRet;
+ aRet.sDataSource = sDataSource;
+ aRet.sTableOrQuery = sTableOrQuery;
+ aRet.nCommandType = nTblOrQuery;
+ return aRet;
+};
+
+void BibConfig::SetBibliographyURL(const BibDBDescriptor& rDesc)
+{
+ sDataSource = rDesc.sDataSource;
+ sTableOrQuery = rDesc.sTableOrQuery;
+ nTblOrQuery = rDesc.nCommandType;
+ SetModified();
+};
+
+void BibConfig::Notify( const css::uno::Sequence<OUString>& )
+{
+}
+
+void BibConfig::ImplCommit()
+{
+ PutProperties(
+ GetPropertyNames(),
+ {css::uno::Any(sDataSource), css::uno::Any(sTableOrQuery),
+ css::uno::Any(nTblOrQuery), css::uno::Any(nBeamerSize),
+ css::uno::Any(nViewSize), css::uno::Any(sQueryText),
+ css::uno::Any(sQueryField),
+ css::uno::Any(bShowColumnAssignmentWarning)});
+ ClearNodeSet(cDataSourceHistory);
+ Sequence< PropertyValue > aNodeValues(mvMappings.size() * 3);
+ PropertyValue* pNodeValues = aNodeValues.getArray();
+
+ sal_Int32 nIndex = 0;
+ for(sal_Int32 i = 0; i < static_cast<sal_Int32>(mvMappings.size()); i++)
+ {
+ const Mapping* pMapping = mvMappings[i].get();
+ OUString sPrefix = OUString::Concat(cDataSourceHistory) + "/_" + OUString::number(i) + "/";
+ pNodeValues[nIndex].Name = sPrefix + "DataSourceName";
+ pNodeValues[nIndex++].Value <<= pMapping->sURL;
+ pNodeValues[nIndex].Name = sPrefix + "Command";
+ pNodeValues[nIndex++].Value <<= pMapping->sTableName;
+ pNodeValues[nIndex].Name = sPrefix + "CommandType";
+ pNodeValues[nIndex++].Value <<= pMapping->nCommandType;
+ SetSetProperties(cDataSourceHistory, aNodeValues);
+
+ sPrefix += "Fields";
+ sal_Int32 nFieldAssignment = 0;
+ OUString sFieldName = "/ProgrammaticFieldName";
+ OUString sDatabaseFieldName = "/AssignedFieldName";
+ ClearNodeSet( sPrefix );
+
+ while(nFieldAssignment < COLUMN_COUNT &&
+ !pMapping->aColumnPairs[nFieldAssignment].sLogicalColumnName.isEmpty())
+ {
+ OUString sSubPrefix = sPrefix + "/_" + OUString::number(nFieldAssignment);
+ Sequence< PropertyValue > aAssignmentValues
+ {
+ comphelper::makePropertyValue(sSubPrefix + sFieldName, pMapping->aColumnPairs[nFieldAssignment].sLogicalColumnName),
+ comphelper::makePropertyValue(sSubPrefix + sDatabaseFieldName, pMapping->aColumnPairs[nFieldAssignment].sRealColumnName)
+ };
+ SetSetProperties( sPrefix, aAssignmentValues );
+ nFieldAssignment++;
+ }
+ }
+}
+
+const Mapping* BibConfig::GetMapping(const BibDBDescriptor& rDesc) const
+{
+ for(std::unique_ptr<Mapping> const & i : mvMappings)
+ {
+ Mapping& rMapping = *i;
+ bool bURLEqual = rDesc.sDataSource == rMapping.sURL;
+ if(rDesc.sTableOrQuery == rMapping.sTableName && bURLEqual)
+ return &rMapping;
+ }
+ return nullptr;
+}
+
+void BibConfig::SetMapping(const BibDBDescriptor& rDesc, const Mapping* pSetMapping)
+{
+ for(size_t i = 0; i < mvMappings.size(); i++)
+ {
+ Mapping& rMapping = *mvMappings[i];
+ bool bURLEqual = rDesc.sDataSource == rMapping.sURL;
+ if(rDesc.sTableOrQuery == rMapping.sTableName && bURLEqual)
+ {
+ mvMappings.erase(mvMappings.begin()+i);
+ break;
+ }
+ }
+ mvMappings.push_back(std::make_unique<Mapping>(*pSetMapping));
+ SetModified();
+}
+
+DBChangeDialogConfig_Impl::DBChangeDialogConfig_Impl()
+{
+}
+
+DBChangeDialogConfig_Impl::~DBChangeDialogConfig_Impl()
+{
+}
+
+const Sequence<OUString>& DBChangeDialogConfig_Impl::GetDataSourceNames()
+{
+ if(!aSourceNames.hasElements())
+ {
+ Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ Reference<XDatabaseContext> xDBContext = DatabaseContext::create(xContext);
+ aSourceNames = xDBContext->getElementNames();
+ }
+ return aSourceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/bibconfig.hxx b/extensions/source/bibliography/bibconfig.hxx
new file mode 100644
index 000000000..0d81491ff
--- /dev/null
+++ b/extensions/source/bibliography/bibconfig.hxx
@@ -0,0 +1,153 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <unotools/configitem.hxx>
+#include <tools/long.hxx>
+#include <vector>
+#include <memory>
+
+struct Mapping;
+typedef std::vector<std::unique_ptr<Mapping> > MappingArray;
+
+
+#define COLUMN_COUNT 32
+#define IDENTIFIER_POS 0
+#define AUTHORITYTYPE_POS 1
+#define AUTHOR_POS 2
+#define TITLE_POS 3
+#define YEAR_POS 4
+#define ISBN_POS 5
+#define BOOKTITLE_POS 6
+#define CHAPTER_POS 7
+#define EDITION_POS 8
+#define EDITOR_POS 9
+#define HOWPUBLISHED_POS 10
+#define INSTITUTION_POS 11
+#define JOURNAL_POS 12
+#define MONTH_POS 13
+#define NOTE_POS 14
+#define ANNOTE_POS 15
+#define NUMBER_POS 16
+#define ORGANIZATIONS_POS 17
+#define PAGES_POS 18
+#define PUBLISHER_POS 19
+#define ADDRESS_POS 20
+#define SCHOOL_POS 21
+#define SERIES_POS 22
+#define REPORTTYPE_POS 23
+#define VOLUME_POS 24
+#define URL_POS 25
+#define CUSTOM1_POS 26
+#define CUSTOM2_POS 27
+#define CUSTOM3_POS 28
+#define CUSTOM4_POS 29
+#define CUSTOM5_POS 30
+#define LOCAL_URL_POS 31
+
+struct StringPair
+{
+ OUString sRealColumnName;
+ OUString sLogicalColumnName;
+};
+
+struct Mapping
+{
+ OUString sTableName;
+ OUString sURL;
+ sal_Int16 nCommandType;
+ StringPair aColumnPairs[COLUMN_COUNT];
+
+ Mapping() :
+ nCommandType(0){}
+};
+
+struct BibDBDescriptor
+{
+ OUString sDataSource;
+ OUString sTableOrQuery;
+ sal_Int32 nCommandType;
+};
+
+
+class BibConfig : public utl::ConfigItem
+{
+ OUString sDataSource;
+ OUString sTableOrQuery;
+ sal_Int32 nTblOrQuery;
+
+ OUString sQueryField;
+ OUString sQueryText;
+ MappingArray mvMappings;
+ tools::Long nBeamerSize;
+ tools::Long nViewSize;
+ bool bShowColumnAssignmentWarning;
+
+ OUString aColumnDefaults[COLUMN_COUNT];
+
+ static css::uno::Sequence<OUString> const & GetPropertyNames();
+
+ virtual void ImplCommit() override;
+
+public:
+ BibConfig();
+ virtual ~BibConfig() override;
+
+ virtual void Notify( const css::uno::Sequence<OUString>& aPropertyNames) override;
+
+ BibDBDescriptor GetBibliographyURL();
+ void SetBibliographyURL(const BibDBDescriptor& rDesc);
+
+ const Mapping* GetMapping(const BibDBDescriptor& rDesc) const;
+ void SetMapping(const BibDBDescriptor& rDesc, const Mapping* pMapping);
+
+ const OUString& GetDefColumnName(sal_uInt16 nIndex) const
+ {return aColumnDefaults[nIndex];}
+
+
+ void setBeamerSize(tools::Long nSize) {SetModified(); nBeamerSize = nSize;}
+ tools::Long getBeamerSize()const {return nBeamerSize;}
+ void setViewSize(tools::Long nSize) {SetModified(); nViewSize = nSize;}
+ tools::Long getViewSize() const {return nViewSize;}
+
+ const OUString& getQueryField() const {return sQueryField;}
+ void setQueryField(const OUString& rSet) {SetModified(); sQueryField = rSet;}
+
+ const OUString& getQueryText() const {return sQueryText;}
+ void setQueryText(const OUString& rSet) {SetModified(); sQueryText = rSet;}
+
+ bool IsShowColumnAssignmentWarning() const
+ { return bShowColumnAssignmentWarning;}
+ void SetShowColumnAssignmentWarning(bool bSet)
+ { bShowColumnAssignmentWarning = bSet;}
+};
+
+class DBChangeDialogConfig_Impl
+{
+ css::uno::Sequence<OUString> aSourceNames;
+public:
+ DBChangeDialogConfig_Impl();
+ ~DBChangeDialogConfig_Impl();
+
+ const css::uno::Sequence<OUString>& GetDataSourceNames();
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/bibcont.cxx b/extensions/source/bibliography/bibcont.cxx
new file mode 100644
index 000000000..7c24b0fb3
--- /dev/null
+++ b/extensions/source/bibliography/bibcont.cxx
@@ -0,0 +1,241 @@
+/* -*- 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 <vcl/event.hxx>
+#include "bibconfig.hxx"
+
+
+#include "bibcont.hxx"
+
+
+BibShortCutHandler::~BibShortCutHandler()
+{
+}
+
+bool BibShortCutHandler::HandleShortCutKey( const KeyEvent& )
+{
+ return false;
+}
+
+
+BibWindow::BibWindow( vcl::Window* pParent, WinBits nStyle ) : Window( pParent, nStyle ), BibShortCutHandler( this )
+{
+}
+
+BibWindow::~BibWindow()
+{
+}
+
+
+BibSplitWindow::BibSplitWindow( vcl::Window* pParent, WinBits nStyle ) : SplitWindow( pParent, nStyle ), BibShortCutHandler( this )
+{
+}
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+//split window size is a percent value
+#define WIN_MIN_HEIGHT 10
+#define WIN_STEP_SIZE 5
+
+BibWindowContainer::BibWindowContainer( vcl::Window* pParent, BibShortCutHandler* pChildWin ) :
+ BibWindow( pParent, WB_3DLOOK ),
+ pChild( pChildWin )
+{
+ if(pChild!=nullptr)
+ {
+ vcl::Window* pChildWindow = GetChild();
+ pChildWindow->SetParent(this);
+ pChildWindow->Show();
+ pChildWindow->SetPosPixel(Point(0,0));
+ }
+}
+
+BibWindowContainer::~BibWindowContainer()
+{
+ disposeOnce();
+}
+
+void BibWindowContainer::dispose()
+{
+ if( pChild )
+ {
+ VclPtr<vcl::Window> pDel = GetChild();
+ pChild = nullptr; // prevents GetFocus for child while deleting!
+ pDel.disposeAndClear();
+ }
+ vcl::Window::dispose();
+}
+
+void BibWindowContainer::Resize()
+{
+ if( pChild )
+ GetChild()->SetSizePixel( GetOutputSizePixel() );
+}
+
+void BibWindowContainer::GetFocus()
+{
+ if( pChild )
+ GetChild()->GrabFocus();
+}
+
+bool BibWindowContainer::HandleShortCutKey( const KeyEvent& rKeyEvent )
+{
+ return pChild && pChild->HandleShortCutKey( rKeyEvent );
+}
+
+
+BibBookContainer::BibBookContainer(vcl::Window* pParent):
+ BibSplitWindow(pParent,WB_3DLOOK),
+ pTopWin(nullptr),
+ pBottomWin(nullptr),
+ aIdle("extensions BibBookContainer Split Idle")
+{
+ pBibMod = OpenBibModul();
+ aIdle.SetInvokeHandler(LINK( this, BibBookContainer, SplitHdl));
+ aIdle.SetPriority(TaskPriority::LOWEST);
+}
+
+BibBookContainer::~BibBookContainer()
+{
+ disposeOnce();
+}
+
+void BibBookContainer::dispose()
+{
+ if( pTopWin )
+ {
+ VclPtr<vcl::Window> pDel = pTopWin;
+ pTopWin = nullptr; // prevents GetFocus for child while deleting!
+ pDel.disposeAndClear();
+ }
+
+ if( pBottomWin )
+ {
+ VclPtr<vcl::Window> pDel = pBottomWin;
+ pBottomWin = nullptr; // prevents GetFocus for child while deleting!
+ pDel.disposeAndClear();
+ }
+
+ CloseBibModul( pBibMod );
+ pTopWin.clear();
+ pBottomWin.clear();
+ BibSplitWindow::dispose();
+}
+
+void BibBookContainer::Split()
+{
+ aIdle.Start();
+}
+IMPL_LINK_NOARG( BibBookContainer, SplitHdl, Timer*, void)
+{
+ tools::Long nSize= GetItemSize( TOP_WINDOW);
+ BibConfig* pConfig = BibModul::GetConfig();
+ pConfig->setBeamerSize(nSize);
+ nSize = GetItemSize( BOTTOM_WINDOW);
+ pConfig->setViewSize(nSize);
+}
+
+void BibBookContainer::createTopFrame( BibShortCutHandler* pWin )
+{
+ if(pTopWin)
+ {
+ RemoveItem(TOP_WINDOW);
+ pTopWin.disposeAndClear();
+ }
+ pTopWin=VclPtr<BibWindowContainer>::Create(this,pWin);
+ pTopWin->Show();
+ BibConfig* pConfig = BibModul::GetConfig();
+ tools::Long nSize = pConfig->getBeamerSize();
+ InsertItem(TOP_WINDOW, pTopWin, nSize, 1, 0, SplitWindowItemFlags::PercentSize );
+
+}
+
+void BibBookContainer::createBottomFrame( BibShortCutHandler* pWin )
+{
+ if(pBottomWin)
+ {
+ RemoveItem(BOTTOM_WINDOW);
+ pBottomWin.disposeAndClear();
+ }
+
+ pBottomWin=VclPtr<BibWindowContainer>::Create(this,pWin);
+
+ BibConfig* pConfig = BibModul::GetConfig();
+ tools::Long nSize = pConfig->getViewSize();
+ InsertItem(BOTTOM_WINDOW, pBottomWin, nSize, 1, 0, SplitWindowItemFlags::PercentSize );
+
+}
+
+void BibBookContainer::GetFocus()
+{
+ if( pBottomWin )
+ pBottomWin->GrabFocus();
+}
+
+bool BibBookContainer::PreNotify( NotifyEvent& rNEvt )
+{
+ bool bHandled = false;
+ if( MouseNotifyEvent::KEYINPUT == rNEvt.GetType() )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+ const vcl::KeyCode aKeyCode = pKEvt->GetKeyCode();
+ sal_uInt16 nKey = aKeyCode.GetCode();
+ const sal_uInt16 nModifier = aKeyCode.GetModifier();
+
+ if( KEY_MOD2 == nModifier )
+ {
+ if( KEY_UP == nKey || KEY_DOWN == nKey )
+ {
+ if(pTopWin && pBottomWin)
+ {
+ sal_uInt16 nFirstWinId = KEY_UP == nKey ? TOP_WINDOW : BOTTOM_WINDOW;
+ sal_uInt16 nSecondWinId = KEY_UP == nKey ? BOTTOM_WINDOW : TOP_WINDOW;
+ tools::Long nHeight = GetItemSize( nFirstWinId );
+ nHeight -= WIN_STEP_SIZE;
+ if(nHeight < WIN_MIN_HEIGHT)
+ nHeight = WIN_MIN_HEIGHT;
+ SetItemSize( nFirstWinId, nHeight );
+ SetItemSize( nSecondWinId, 100 - nHeight );
+ }
+ bHandled = true;
+ }
+ else if( pKEvt->GetCharCode() && HandleShortCutKey( *pKEvt ) )
+ bHandled = true;
+ }
+ }
+
+ return bHandled;
+}
+
+bool BibBookContainer::HandleShortCutKey( const KeyEvent& rKeyEvent )
+{
+ bool bRet = false;
+
+ if( pTopWin )
+ bRet = pTopWin->HandleShortCutKey( rKeyEvent );
+
+ if( !bRet && pBottomWin )
+ bRet = pBottomWin->HandleShortCutKey( rKeyEvent );
+
+ return bRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/bibcont.hxx b/extensions/source/bibliography/bibcont.hxx
new file mode 100644
index 000000000..d90952ac3
--- /dev/null
+++ b/extensions/source/bibliography/bibcont.hxx
@@ -0,0 +1,93 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <vcl/timer.hxx>
+#include <vcl/idle.hxx>
+#include "bibshortcuthandler.hxx"
+
+#include "bibmod.hxx"
+
+#define TOP_WINDOW 1
+#define BOTTOM_WINDOW 2
+
+class BibWindowContainer : public BibWindow //Window
+{
+ private:
+ // !BibShortCutHandler is also always a Window!
+ BibShortCutHandler* pChild;
+
+ protected:
+ virtual void Resize() override;
+
+ public:
+ BibWindowContainer( vcl::Window* pParent, BibShortCutHandler* pChild);
+ virtual ~BibWindowContainer() override;
+ virtual void dispose() override;
+
+ inline vcl::Window* GetChild();
+
+ virtual void GetFocus() override;
+
+ virtual bool HandleShortCutKey( const KeyEvent& rKeyEvent ) override; // returns true, if key was handled
+
+ using Window::GetChild;
+};
+
+inline vcl::Window* BibWindowContainer::GetChild()
+{
+ return pChild ? pChild->GetWindow() : nullptr;
+}
+
+
+class BibBookContainer: public BibSplitWindow
+{
+ private:
+
+ VclPtr<BibWindowContainer> pTopWin;
+ VclPtr<BibWindowContainer> pBottomWin;
+ HdlBibModul pBibMod;
+ Idle aIdle;
+
+ DECL_LINK( SplitHdl, Timer*, void );
+
+ protected:
+
+ virtual void Split() override;
+
+ virtual bool PreNotify( NotifyEvent& rNEvt ) override;
+
+ public:
+
+ explicit BibBookContainer(vcl::Window* pParent );
+ virtual ~BibBookContainer() override;
+ virtual void dispose() override;
+
+ // !BibShortCutHandler is also always a Window!
+ void createTopFrame( BibShortCutHandler* pWin );
+
+ void createBottomFrame( BibShortCutHandler* pWin );
+
+ virtual void GetFocus() override;
+
+ virtual bool HandleShortCutKey( const KeyEvent& rKeyEvent ) override; // returns true, if key was handled
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/bibload.cxx b/extensions/source/bibliography/bibload.cxx
new file mode 100644
index 000000000..82c08e007
--- /dev/null
+++ b/extensions/source/bibliography/bibload.cxx
@@ -0,0 +1,609 @@
+/* -*- 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 <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <cppuhelper/supportsservice.hxx>
+#include <svl/itemprop.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/sdbc/ResultSetType.hpp>
+#include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
+#include <com/sun/star/sdbc/SQLException.hpp>
+#include <com/sun/star/sdb/XColumn.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/frame/XFrameLoader.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/text/BibliographyDataField.hpp>
+#include <com/sun/star/form/XLoadable.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <vcl/window.hxx>
+#include <vcl/svapp.hxx>
+
+#include "bibresid.hxx"
+#include <strings.hrc>
+#include "bibcont.hxx"
+#include "bibbeam.hxx"
+#include "bibmod.hxx"
+#include "bibview.hxx"
+#include "framectr.hxx"
+#include "datman.hxx"
+#include "bibconfig.hxx"
+#include <cppuhelper/implbase.hxx>
+#include <rtl/ref.hxx>
+#include <o3tl/string_view.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::form;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::frame;
+
+namespace {
+
+class BibliographyLoader : public cppu::WeakImplHelper
+ < XServiceInfo, XNameAccess, XPropertySet, XFrameLoader >
+{
+ HdlBibModul m_pBibMod;
+ rtl::Reference<BibDataManager> m_xDatMan;
+ Reference< XNameAccess > m_xColumns;
+ Reference< XResultSet > m_xCursor;
+
+private:
+
+ void loadView(const Reference< XFrame > & aFrame,
+ const Reference< XLoadEventListener > & aListener);
+
+ BibDataManager* GetDataManager()const;
+ Reference< XNameAccess > const & GetDataColumns() const;
+ Reference< XResultSet > const & GetDataCursor() const;
+ Reference< sdb::XColumn > GetIdentifierColumn() const;
+
+public:
+ BibliographyLoader();
+ virtual ~BibliographyLoader() override;
+
+ // XServiceInfo
+ OUString SAL_CALL getImplementationName() override;
+ sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
+ Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
+
+ //XNameAccess
+ virtual Any SAL_CALL getByName(const OUString& aName) override;
+ virtual Sequence< OUString > SAL_CALL getElementNames() override;
+ virtual sal_Bool SAL_CALL hasByName(const OUString& aName) override;
+
+ //XElementAccess
+ virtual Type SAL_CALL getElementType() override;
+ virtual sal_Bool SAL_CALL hasElements() override;
+
+ //XPropertySet
+ virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo() override;
+ virtual void SAL_CALL setPropertyValue(const OUString& PropertyName, const Any& aValue) override;
+ virtual Any SAL_CALL getPropertyValue(const OUString& PropertyName) override;
+ virtual void SAL_CALL addPropertyChangeListener(const OUString& PropertyName, const Reference< XPropertyChangeListener > & aListener) override;
+ virtual void SAL_CALL removePropertyChangeListener(const OUString& PropertyName, const Reference< XPropertyChangeListener > & aListener) override;
+ virtual void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const Reference< XVetoableChangeListener > & aListener) override;
+ virtual void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName, const Reference< XVetoableChangeListener > & aListener) override;
+
+ // XLoader
+ virtual void SAL_CALL load(const Reference< XFrame > & aFrame, const OUString& aURL,
+ const Sequence< PropertyValue >& aArgs,
+ const Reference< XLoadEventListener > & aListener) override;
+ virtual void SAL_CALL cancel() override;
+};
+
+}
+
+BibliographyLoader::BibliographyLoader() :
+ m_pBibMod(nullptr)
+{
+}
+
+BibliographyLoader::~BibliographyLoader()
+{
+ Reference< lang::XComponent > xComp(m_xCursor, UNO_QUERY);
+ if (xComp.is())
+ xComp->dispose();
+ if(m_pBibMod)
+ CloseBibModul(m_pBibMod);
+}
+
+
+// XServiceInfo
+OUString BibliographyLoader::getImplementationName()
+{
+ return "com.sun.star.extensions.Bibliography";
+}
+
+// XServiceInfo
+sal_Bool BibliographyLoader::supportsService(const OUString& ServiceName)
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+// XServiceInfo
+Sequence< OUString > BibliographyLoader::getSupportedServiceNames()
+{
+ return { "com.sun.star.frame.FrameLoader", "com.sun.star.frame.Bibliography" };
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+extensions_BibliographyLoader_get_implementation(
+ css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new BibliographyLoader());
+}
+
+void BibliographyLoader::cancel()
+{
+ //!
+ //!
+}
+
+void BibliographyLoader::load(const Reference< XFrame > & rFrame, const OUString& rURL,
+ const Sequence< PropertyValue >& /*rArgs*/,
+ const Reference< XLoadEventListener > & rListener)
+{
+
+ SolarMutexGuard aGuard;
+
+ m_pBibMod = OpenBibModul();
+
+ std::u16string_view aPartName = o3tl::getToken(rURL, 1, '/' );
+ Reference<XPropertySet> xPrSet(rFrame, UNO_QUERY);
+ if(xPrSet.is())
+ {
+ Any aTitle;
+ aTitle <<= BibResId(RID_BIB_STR_FRAME_TITLE);
+ xPrSet->setPropertyValue("Title", aTitle);
+ }
+ if(aPartName == u"View" || aPartName == u"View1")
+ {
+ loadView(rFrame, rListener);
+ }
+}
+
+
+void BibliographyLoader::loadView(const Reference< XFrame > & rFrame,
+ const Reference< XLoadEventListener > & rListener)
+{
+ SolarMutexGuard aGuard;
+ //!
+ if(!m_pBibMod)
+ m_pBibMod = OpenBibModul();
+
+ m_xDatMan = BibModul::createDataManager();
+ BibDBDescriptor aBibDesc = BibModul::GetConfig()->GetBibliographyURL();
+
+ if(aBibDesc.sDataSource.isEmpty())
+ {
+ DBChangeDialogConfig_Impl aConfig;
+ const Sequence<OUString> aSources = aConfig.GetDataSourceNames();
+ if(aSources.hasElements())
+ aBibDesc.sDataSource = aSources.getConstArray()[0];
+ }
+
+ m_xDatMan->createDatabaseForm( aBibDesc );
+
+ Reference<awt::XWindow> aWindow = rFrame->getContainerWindow();
+
+ VclPtr<vcl::Window> pParent = VCLUnoHelper::GetWindow( aWindow );
+
+ VclPtrInstance<BibBookContainer> pMyWindow( pParent );
+ pMyWindow->Show();
+
+ VclPtrInstance< ::bib::BibView> pView( pMyWindow, m_xDatMan.get(), WB_VSCROLL | WB_HSCROLL | WB_3DLOOK );
+ pView->Show();
+ m_xDatMan->SetView( pView );
+
+ VclPtrInstance< ::bib::BibBeamer> pBeamer( pMyWindow, m_xDatMan.get() );
+ pBeamer->Show();
+ pMyWindow->createTopFrame(pBeamer);
+
+ pMyWindow->createBottomFrame(pView);
+
+ Reference< awt::XWindow > xWin ( pMyWindow->GetComponentInterface(), UNO_QUERY );
+
+ Reference< XController > xCtrRef( new BibFrameController_Impl( xWin, m_xDatMan.get() ) );
+
+ xCtrRef->attachFrame(rFrame);
+ rFrame->setComponent( xWin, xCtrRef);
+ pBeamer->SetXController(xCtrRef);
+
+ if (aWindow)
+ {
+ // not earlier because SetFocus() is triggered in setVisible()
+ aWindow->setVisible(true);
+ }
+
+ Reference<XLoadable>(m_xDatMan)->load();
+ m_xDatMan->RegisterInterceptor(pBeamer);
+
+ if ( rListener.is() )
+ rListener->loadFinished( this );
+
+ // attach menu bar
+ Reference< XPropertySet > xPropSet( rFrame, UNO_QUERY );
+ Reference< css::frame::XLayoutManager > xLayoutManager;
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ Any a = xPropSet->getPropertyValue("LayoutManager");
+ a >>= xLayoutManager;
+ }
+ catch ( const uno::Exception& )
+ {
+ }
+ }
+
+ if ( xLayoutManager.is() )
+ xLayoutManager->createElement( "private:resource/menubar/menubar" );
+}
+
+BibDataManager* BibliographyLoader::GetDataManager()const
+{
+ if(!m_xDatMan.is())
+ {
+ if(!m_pBibMod)
+ const_cast< BibliographyLoader* >( this )->m_pBibMod = OpenBibModul();
+ const_cast< BibliographyLoader* >( this )->m_xDatMan = BibModul::createDataManager();
+ }
+ return m_xDatMan.get();
+}
+
+Reference< XNameAccess > const & BibliographyLoader::GetDataColumns() const
+{
+ if (!m_xColumns.is())
+ {
+ Reference< XMultiServiceFactory > xMgr = comphelper::getProcessServiceFactory();
+ Reference< XRowSet > xRowSet(xMgr->createInstance("com.sun.star.sdb.RowSet"), UNO_QUERY);
+ Reference< XPropertySet > xResultSetProps(xRowSet, UNO_QUERY);
+ DBG_ASSERT(xResultSetProps.is() , "BibliographyLoader::GetDataCursor : invalid row set (no XResultSet or no XPropertySet) !");
+
+ BibDBDescriptor aBibDesc = BibModul::GetConfig()->GetBibliographyURL();
+
+ Any aBibUrlAny; aBibUrlAny <<= aBibDesc.sDataSource;
+ xResultSetProps->setPropertyValue("DataSourceName", aBibUrlAny);
+ Any aCommandType; aCommandType <<= aBibDesc.nCommandType;
+ xResultSetProps->setPropertyValue("CommandType", aCommandType);
+ Any aTableName; aTableName <<= aBibDesc.sTableOrQuery;
+ xResultSetProps->setPropertyValue("Command", aTableName);
+ Any aResultSetType; aResultSetType <<= sal_Int32(ResultSetType::SCROLL_INSENSITIVE);
+ xResultSetProps->setPropertyValue("ResultSetType", aResultSetType);
+ Any aResultSetCurrency; aResultSetCurrency <<= sal_Int32(ResultSetConcurrency::UPDATABLE);
+ xResultSetProps->setPropertyValue("ResultSetConcurrency", aResultSetCurrency);
+
+ bool bSuccess = false;
+ try
+ {
+ xRowSet->execute();
+ bSuccess = true;
+ }
+ catch(const SQLException&)
+ {
+ DBG_UNHANDLED_EXCEPTION("extensions.biblio");
+ }
+ catch(const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("extensions.biblio");
+ bSuccess = false;
+ }
+
+ if (!bSuccess)
+ {
+ Reference< XComponent > xSetComp(xRowSet, UNO_QUERY);
+ if (xSetComp.is())
+ xSetComp->dispose();
+ xRowSet = nullptr;
+ }
+ else
+ const_cast<BibliographyLoader*>(this)->m_xCursor = xRowSet.get();
+
+ Reference< sdbcx::XColumnsSupplier > xSupplyCols(m_xCursor, UNO_QUERY);
+ if (xSupplyCols.is())
+ const_cast<BibliographyLoader*>(this)->m_xColumns = xSupplyCols->getColumns();
+ }
+
+ return m_xColumns;
+}
+
+Reference< sdb::XColumn > BibliographyLoader::GetIdentifierColumn() const
+{
+ BibDataManager* pDatMan = GetDataManager();
+ Reference< XNameAccess > xColumns = GetDataColumns();
+ OUString sIdentifierColumnName = pDatMan->GetIdentifierMapping();
+
+ Reference< sdb::XColumn > xReturn;
+ if (xColumns.is() && xColumns->hasByName(sIdentifierColumnName))
+ {
+ xReturn.set(xColumns->getByName(sIdentifierColumnName), UNO_QUERY);
+ }
+ return xReturn;
+}
+
+Reference< XResultSet > const & BibliographyLoader::GetDataCursor() const
+{
+ if (!m_xCursor.is())
+ GetDataColumns();
+ if (m_xCursor.is())
+ m_xCursor->first();
+ return m_xCursor;
+}
+
+static OUString lcl_AddProperty(const Reference< XNameAccess >& xColumns,
+ const Mapping* pMapping, const OUString& rColumnName)
+{
+ OUString sColumnName(rColumnName);
+ if(pMapping)
+ {
+ for(const auto & aColumnPair : pMapping->aColumnPairs)
+ {
+ if(aColumnPair.sLogicalColumnName == rColumnName)
+ {
+ sColumnName = aColumnPair.sRealColumnName;
+ break;
+ }
+ }
+ }
+ OUString uColumnName(sColumnName);
+ OUString uRet;
+ Reference< sdb::XColumn > xCol;
+ if (xColumns->hasByName(uColumnName))
+ xCol.set(xColumns->getByName(uColumnName), UNO_QUERY);
+ if (xCol.is())
+ uRet = xCol->getString();
+ return uRet;
+}
+
+Any BibliographyLoader::getByName(const OUString& rName)
+{
+ Any aRet;
+ try
+ {
+ BibDataManager* pDatMan = GetDataManager();
+ Reference< XResultSet > xCursor = GetDataCursor();
+ Reference< sdbcx::XColumnsSupplier > xSupplyCols(xCursor, UNO_QUERY);
+ Reference< XNameAccess > xColumns;
+ if (!xSupplyCols.is())
+ return aRet;
+ xColumns = xSupplyCols->getColumns();
+ DBG_ASSERT(xSupplyCols.is(), "BibliographyLoader::getByName : invalid columns returned by the data cursor (may be the result set is not alive ?) !");
+ if (!xColumns.is())
+ return aRet;
+
+ const OUString sIdentifierMapping = pDatMan->GetIdentifierMapping();
+ Reference< sdb::XColumn > xColumn;
+ if (xColumns->hasByName(sIdentifierMapping))
+ xColumn.set(xColumns->getByName(sIdentifierMapping), UNO_QUERY);
+ if (xColumn.is())
+ {
+ do
+ {
+ if ((rName == xColumn->getString()) && !xColumn->wasNull())
+ {
+ Sequence<PropertyValue> aPropSequ(COLUMN_COUNT);
+ PropertyValue* pValues = aPropSequ.getArray();
+ BibConfig* pConfig = BibModul::GetConfig();
+ BibDBDescriptor aBibDesc = BibModul::GetConfig()->GetBibliographyURL();
+ const Mapping* pMapping = pConfig->GetMapping(aBibDesc);
+ for(sal_uInt16 nEntry = 0; nEntry < COLUMN_COUNT; nEntry++)
+ {
+ const OUString& sColName = pConfig->GetDefColumnName(
+ nEntry);
+ pValues[nEntry].Name = sColName;
+ pValues[nEntry].Value <<= lcl_AddProperty(xColumns, pMapping, sColName);
+ }
+ aRet <<= aPropSequ;
+
+ break;
+ }
+ }
+ while(xCursor->next());
+ }
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("extensions.biblio");
+ }
+ return aRet;
+}
+
+Sequence< OUString > BibliographyLoader::getElementNames()
+{
+ Sequence< OUString > aRet(10);
+ int nRealNameCount = 0;
+ try
+ {
+ Reference< XResultSet > xCursor(GetDataCursor());
+ Reference< sdb::XColumn > xIdColumn(GetIdentifierColumn());
+ if (xIdColumn.is()) // implies xCursor.is()
+ {
+ do
+ {
+ OUString sTemp = xIdColumn->getString();
+ if (!sTemp.isEmpty() && !xIdColumn->wasNull())
+ {
+ int nLen = aRet.getLength();
+ if(nLen == nRealNameCount)
+ aRet.realloc(nLen + 10);
+ OUString* pArray = aRet.getArray();
+ pArray[nRealNameCount] = sTemp;
+ nRealNameCount++;
+ }
+ }
+ while (xCursor->next());
+ }
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("extensions.biblio");
+ }
+
+ aRet.realloc(nRealNameCount);
+ return aRet;
+}
+
+sal_Bool BibliographyLoader::hasByName(const OUString& rName)
+{
+ bool bRet = false;
+ try
+ {
+ Reference< XResultSet > xCursor = GetDataCursor();
+ Reference< sdb::XColumn > xIdColumn = GetIdentifierColumn();
+
+ if (xIdColumn.is()) // implies xCursor.is()
+ {
+ do
+ {
+ OUString sCurrentId = xIdColumn->getString();
+ if (!xIdColumn->wasNull() && rName.startsWith(sCurrentId))
+ {
+ bRet = true;
+ break;
+ }
+ }
+ while(xCursor->next());
+ }
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("extensions.biblio");
+ }
+ return bRet;
+}
+
+Type BibliographyLoader::getElementType()
+{
+ return cppu::UnoType<Sequence<PropertyValue>>::get();
+}
+
+sal_Bool BibliographyLoader::hasElements()
+{
+ Reference< XNameAccess > xColumns = GetDataColumns();
+ return xColumns.is() && xColumns->getElementNames().hasElements();
+}
+
+Reference< XPropertySetInfo > BibliographyLoader::getPropertySetInfo()
+{
+ static const SfxItemPropertyMapEntry aBibProps_Impl[] =
+ {
+ { u"BibliographyDataFieldNames", 0, cppu::UnoType<Sequence<PropertyValue>>::get(), PropertyAttribute::READONLY, 0},
+ { u"", 0, css::uno::Type(), 0, 0 }
+ };
+ static Reference< XPropertySetInfo > xRet =
+ SfxItemPropertySet(aBibProps_Impl).getPropertySetInfo();
+ return xRet;
+}
+
+void BibliographyLoader::setPropertyValue(const OUString& /*PropertyName*/,
+ const Any& /*aValue*/)
+{
+ throw UnknownPropertyException();
+ //no changeable properties
+}
+
+Any BibliographyLoader::getPropertyValue(const OUString& rPropertyName)
+{
+ Any aRet;
+ static const sal_uInt16 aInternalMapping[] =
+ {
+ IDENTIFIER_POS , // BibliographyDataField_IDENTIFIER
+ AUTHORITYTYPE_POS , // BibliographyDataField_BIBILIOGRAPHIC_TYPE
+ ADDRESS_POS , // BibliographyDataField_ADDRESS
+ ANNOTE_POS , // BibliographyDataField_ANNOTE
+ AUTHOR_POS , // BibliographyDataField_AUTHOR
+ BOOKTITLE_POS , // BibliographyDataField_BOOKTITLE
+ CHAPTER_POS , // BibliographyDataField_CHAPTER
+ EDITION_POS , // BibliographyDataField_EDITION
+ EDITOR_POS , // BibliographyDataField_EDITOR
+ HOWPUBLISHED_POS , // BibliographyDataField_HOWPUBLISHED
+ INSTITUTION_POS , // BibliographyDataField_INSTITUTION
+ JOURNAL_POS , // BibliographyDataField_JOURNAL
+ MONTH_POS , // BibliographyDataField_MONTH
+ NOTE_POS , // BibliographyDataField_NOTE
+ NUMBER_POS , // BibliographyDataField_NUMBER
+ ORGANIZATIONS_POS , // BibliographyDataField_ORGANIZATIONS
+ PAGES_POS , // BibliographyDataField_PAGES
+ PUBLISHER_POS , // BibliographyDataField_PUBLISHER
+ SCHOOL_POS , // BibliographyDataField_SCHOOL
+ SERIES_POS , // BibliographyDataField_SERIES
+ TITLE_POS , // BibliographyDataField_TITLE
+ REPORTTYPE_POS , // BibliographyDataField_REPORT_TYPE
+ VOLUME_POS , // BibliographyDataField_VOLUME
+ YEAR_POS , // BibliographyDataField_YEAR
+ URL_POS , // BibliographyDataField_URL
+ CUSTOM1_POS , // BibliographyDataField_CUSTOM1
+ CUSTOM2_POS , // BibliographyDataField_CUSTOM2
+ CUSTOM3_POS , // BibliographyDataField_CUSTOM3
+ CUSTOM4_POS , // BibliographyDataField_CUSTOM4
+ CUSTOM5_POS , // BibliographyDataField_CUSTOM5
+ ISBN_POS , // BibliographyDataField_ISBN
+ LOCAL_URL_POS // BibliographyDataField_LOCAL_URL
+ };
+ if(rPropertyName != "BibliographyDataFieldNames")
+ throw UnknownPropertyException(rPropertyName);
+ Sequence<PropertyValue> aSeq(COLUMN_COUNT);
+ PropertyValue* pArray = aSeq.getArray();
+ BibConfig* pConfig = BibModul::GetConfig();
+ for(sal_uInt16 i = 0; i <= text::BibliographyDataField::LOCAL_URL ; i++)
+ {
+ pArray[i].Name = pConfig->GetDefColumnName(aInternalMapping[i]);
+ pArray[i].Value <<= static_cast<sal_Int16>(i);
+ }
+ aRet <<= aSeq;
+ return aRet;
+}
+
+void BibliographyLoader::addPropertyChangeListener(
+ const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
+{
+ //no bound properties
+}
+
+void BibliographyLoader::removePropertyChangeListener(
+ const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
+{
+ //no bound properties
+}
+
+void BibliographyLoader::addVetoableChangeListener(
+ const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
+{
+ //no vetoable properties
+}
+
+void BibliographyLoader::removeVetoableChangeListener(
+ const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
+{
+ //no vetoable properties
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/bibmod.cxx b/extensions/source/bibliography/bibmod.cxx
new file mode 100644
index 000000000..3a6d06672
--- /dev/null
+++ b/extensions/source/bibliography/bibmod.cxx
@@ -0,0 +1,89 @@
+/* -*- 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 <unotools/resmgr.hxx>
+
+#include "bibmod.hxx"
+#include "bibresid.hxx"
+#include "datman.hxx"
+#include "bibconfig.hxx"
+#include <ucbhelper/content.hxx>
+
+static BibModul* pBibModul=nullptr;
+static sal_uInt32 nBibModulCount=0;
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ucb;
+
+HdlBibModul OpenBibModul()
+{
+ if(pBibModul==nullptr)
+ {
+ pBibModul=new BibModul();
+ }
+ nBibModulCount++;
+ return &pBibModul;
+}
+
+void CloseBibModul(HdlBibModul ppBibModul)
+{
+ nBibModulCount--;
+ if(nBibModulCount==0 && ppBibModul!=nullptr)
+ {
+ delete pBibModul;
+ pBibModul=nullptr;
+ }
+}
+
+OUString BibResId(TranslateId aId)
+{
+ return Translate::get(aId, pBibModul->GetResLocale());
+}
+
+BibConfig* BibModul::pBibConfig = nullptr;
+
+BibModul::BibModul()
+ : m_aResLocale(Translate::Create("pcr"))
+{
+}
+
+BibModul::~BibModul()
+{
+ if (pBibConfig && pBibConfig->IsModified())
+ pBibConfig->Commit();
+ delete pBibConfig;
+ pBibConfig = nullptr;
+}
+
+rtl::Reference<BibDataManager> BibModul::createDataManager()
+{
+ return new BibDataManager();
+}
+
+BibConfig* BibModul::GetConfig()
+{
+ if(! pBibConfig)
+ pBibConfig = new BibConfig;
+ return pBibConfig;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/bibmod.hxx b/extensions/source/bibliography/bibmod.hxx
new file mode 100644
index 000000000..a695f93d6
--- /dev/null
+++ b/extensions/source/bibliography/bibmod.hxx
@@ -0,0 +1,50 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <locale>
+#include <rtl/ref.hxx>
+
+class BibDataManager;
+class BibConfig;
+
+class BibModul
+{
+ private:
+ std::locale m_aResLocale;
+ static BibConfig* pBibConfig;
+
+ public:
+ BibModul();
+ ~BibModul();
+
+ const std::locale& GetResLocale() const { return m_aResLocale; }
+ static BibConfig* GetConfig();
+
+ static rtl::Reference<BibDataManager> createDataManager();
+
+};
+
+typedef BibModul** HdlBibModul;
+
+HdlBibModul OpenBibModul();
+void CloseBibModul(HdlBibModul ppBibModul);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/bibresid.hxx b/extensions/source/bibliography/bibresid.hxx
new file mode 100644
index 000000000..6e17e76f2
--- /dev/null
+++ b/extensions/source/bibliography/bibresid.hxx
@@ -0,0 +1,27 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <rtl/ustring.hxx>
+#include <unotools/resmgr.hxx>
+
+OUString BibResId(TranslateId aId);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/bibshortcuthandler.hxx b/extensions/source/bibliography/bibshortcuthandler.hxx
new file mode 100644
index 000000000..79563543b
--- /dev/null
+++ b/extensions/source/bibliography/bibshortcuthandler.hxx
@@ -0,0 +1,66 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <vcl/window.hxx>
+#include <vcl/splitwin.hxx>
+
+// additional classes to handle shortcuts
+// code in bibcont.cxx
+
+
+class BibShortCutHandler
+{
+private:
+ VclPtr<vcl::Window> pBaseClass; // in cases, where BibShortCutHandler also has to be a window
+
+protected:
+ explicit BibShortCutHandler( vcl::Window* pBaseClass );
+
+public:
+ virtual ~BibShortCutHandler();
+ virtual bool HandleShortCutKey( const KeyEvent& rKeyEvent ); // returns true, if key was handled
+
+ inline vcl::Window* GetWindow();
+};
+
+inline BibShortCutHandler::BibShortCutHandler( vcl::Window* _pBaseClass ) : pBaseClass( _pBaseClass )
+{
+}
+
+inline vcl::Window* BibShortCutHandler::GetWindow()
+{
+ return pBaseClass;
+}
+
+class BibWindow : public vcl::Window, public BibShortCutHandler
+{
+public:
+ BibWindow( vcl::Window* pParent, WinBits nStyle);
+ virtual ~BibWindow() override;
+};
+
+class BibSplitWindow : public SplitWindow, public BibShortCutHandler
+{
+public:
+ BibSplitWindow( vcl::Window* pParent, WinBits nStyle);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/bibtools.hxx b/extensions/source/bibliography/bibtools.hxx
new file mode 100644
index 000000000..9b0d388fa
--- /dev/null
+++ b/extensions/source/bibliography/bibtools.hxx
@@ -0,0 +1,42 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <vcl/window.hxx>
+
+namespace bib
+{
+ // source in bibbeam.cxx
+
+ void HandleTaskPaneList( vcl::Window* pWindow, bool bAddToList );
+ // pWindow: just an system window or something which is child of a system window
+
+ inline void AddToTaskPaneList( vcl::Window* pWindowToBeHandled )
+ {
+ HandleTaskPaneList( pWindowToBeHandled, true );
+ }
+
+ inline void RemoveFromTaskPaneList( vcl::Window* pWindowToBeHandled )
+ {
+ HandleTaskPaneList( pWindowToBeHandled, false );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/bibview.cxx b/extensions/source/bibliography/bibview.cxx
new file mode 100644
index 000000000..b175fb78a
--- /dev/null
+++ b/extensions/source/bibliography/bibview.cxx
@@ -0,0 +1,189 @@
+/* -*- 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 <strings.hrc>
+#include "general.hxx"
+#include "bibview.hxx"
+#include "datman.hxx"
+#include "bibresid.hxx"
+#include "bibmod.hxx"
+#include "bibconfig.hxx"
+
+
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::form;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+ class MessageWithCheck : public weld::MessageDialogController
+ {
+ private:
+ std::unique_ptr<weld::CheckButton> m_xWarningOnBox;
+ public:
+ MessageWithCheck(weld::Window *pParent)
+ : MessageDialogController(pParent, "modules/sbibliography/ui/querydialog.ui", "QueryDialog", "ask")
+ , m_xWarningOnBox(m_xBuilder->weld_check_button("ask"))
+ {
+ }
+ bool get_active() const { return m_xWarningOnBox->get_active(); }
+ };
+}
+
+namespace bib
+{
+
+
+ BibView::BibView( vcl::Window* _pParent, BibDataManager* _pManager, WinBits _nStyle )
+ :BibWindow( _pParent, _nStyle )
+ ,m_pDatMan( _pManager )
+ ,m_xDatMan( _pManager )
+ ,m_pGeneralPage( nullptr )
+ ,m_aFormControlContainer(this)
+ {
+ if ( m_xDatMan.is() )
+ m_aFormControlContainer.connectForm( m_xDatMan );
+ }
+
+
+ BibView::~BibView()
+ {
+ disposeOnce();
+ }
+
+ void BibView::dispose()
+ {
+ VclPtr<BibGeneralPage> pGeneralPage = m_pGeneralPage;
+ m_pGeneralPage.clear();
+ pGeneralPage.disposeAndClear(); // dispose will commit any uncommitted weld::Entry changes
+
+ if ( m_aFormControlContainer.isFormConnected() )
+ m_aFormControlContainer.disconnectForm();
+
+ BibWindow::dispose();
+ }
+
+ void BibView::UpdatePages()
+ {
+ // TODO:
+ // this is _strange_: Why not updating the existent general page?
+ // I consider the current behaviour a HACK.
+ if ( m_pGeneralPage )
+ {
+ m_pGeneralPage->Hide();
+ m_pGeneralPage.disposeAndClear();
+ }
+
+ m_pGeneralPage = VclPtr<BibGeneralPage>::Create( this, m_pDatMan );
+ m_pGeneralPage->Show();
+
+ if( HasFocus() )
+ // "delayed" GetFocus() because GetFocus() is initially called before GeneralPage is created
+ m_pGeneralPage->GrabFocus();
+
+ OUString sErrorString( m_pGeneralPage->GetErrorString() );
+ if ( sErrorString.isEmpty() )
+ return;
+
+ bool bExecute = BibModul::GetConfig()->IsShowColumnAssignmentWarning();
+ if(!m_pDatMan->HasActiveConnection())
+ {
+ //no connection is available -> the data base has to be assigned
+ m_pDatMan->DispatchDBChangeDialog();
+ bExecute = false;
+ }
+ else if(bExecute)
+ {
+ sErrorString += "\n" + BibResId(RID_MAP_QUESTION);
+
+ MessageWithCheck aQueryBox(GetFrameWeld());
+ aQueryBox.set_primary_text(sErrorString);
+
+ short nResult = aQueryBox.run();
+ BibModul::GetConfig()->SetShowColumnAssignmentWarning(!aQueryBox.get_active());
+
+ if( RET_YES != nResult )
+ {
+ bExecute = false;
+ }
+ }
+ if(bExecute)
+ {
+ Application::PostUserEvent( LINK( this, BibView, CallMappingHdl ), nullptr, true );
+ }
+ }
+
+ BibViewFormControlContainer::BibViewFormControlContainer(BibView *pBibView) : mpBibView(pBibView) {}
+
+ void BibViewFormControlContainer::_loaded( const EventObject& _rEvent )
+ {
+ mpBibView->UpdatePages();
+ FormControlContainer::_loaded( _rEvent );
+ mpBibView->Resize();
+ }
+
+ void BibViewFormControlContainer::_reloaded( const EventObject& _rEvent )
+ {
+ mpBibView->UpdatePages();
+ FormControlContainer::_loaded( _rEvent );
+ mpBibView->Resize();
+ }
+
+ IMPL_LINK_NOARG( BibView, CallMappingHdl, void*, void)
+ {
+ m_pDatMan->CreateMappingDialog(GetFrameWeld());
+ }
+
+ void BibView::Resize()
+ {
+ if ( m_pGeneralPage )
+ {
+ ::Size aSz( GetOutputSizePixel() );
+ m_pGeneralPage->SetSizePixel( aSz );
+ }
+ Window::Resize();
+ }
+
+ Reference< awt::XControlContainer > BibViewFormControlContainer::getControlContainer()
+ {
+ return nullptr;
+ }
+
+ void BibView::GetFocus()
+ {
+ if( m_pGeneralPage )
+ m_pGeneralPage->GrabFocus();
+ }
+
+ bool BibView::HandleShortCutKey( const KeyEvent& rKeyEvent )
+ {
+ return m_pGeneralPage && m_pGeneralPage->HandleShortCutKey( rKeyEvent );
+ }
+
+
+} // namespace bib
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/bibview.hxx b/extensions/source/bibliography/bibview.hxx
new file mode 100644
index 000000000..3bed8ed13
--- /dev/null
+++ b/extensions/source/bibliography/bibview.hxx
@@ -0,0 +1,83 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <com/sun/star/awt/XControlContainer.hpp>
+#include "formcontrolcontainer.hxx"
+#include "bibshortcuthandler.hxx"
+
+class BibGeneralPage;
+class BibDataManager;
+
+namespace com::sun::star::awt{ class XFocusListener;}
+
+namespace bib
+{
+ class BibView;
+ class BibViewFormControlContainer : public FormControlContainer
+ {
+ private:
+ VclPtr<BibView> mpBibView;
+ protected:
+ // FormControlContainer
+ virtual css::uno::Reference< css::awt::XControlContainer >
+ getControlContainer() override;
+ // XLoadListener equivalents
+ virtual void _loaded( const css::lang::EventObject& _rEvent ) override;
+ virtual void _reloaded( const css::lang::EventObject& _rEvent ) override;
+ public:
+ using FormControlContainer::connectForm;
+ using FormControlContainer::disconnectForm;
+ using FormControlContainer::isFormConnected;
+ explicit BibViewFormControlContainer(BibView *pBibView);
+ };
+
+ class BibView : public BibWindow
+ {
+ private:
+ BibDataManager* m_pDatMan;
+ css::uno::Reference< css::form::XLoadable> m_xDatMan;
+ VclPtr<BibGeneralPage> m_pGeneralPage;
+ BibViewFormControlContainer m_aFormControlContainer;
+
+ private:
+ DECL_LINK(CallMappingHdl, void*, void);
+
+ public:
+ // Window overridables
+ virtual void Resize() override;
+
+ public:
+ BibView( vcl::Window* _pParent, BibDataManager* _pDatMan, WinBits nStyle );
+ virtual ~BibView() override;
+ virtual void dispose() override;
+
+ void UpdatePages();
+
+ virtual void GetFocus() override;
+
+ virtual bool HandleShortCutKey( const KeyEvent& rKeyEvent ) override; // returns true, if key was handled
+ };
+
+
+} // namespace bib
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/datman.cxx b/extensions/source/bibliography/datman.cxx
new file mode 100644
index 000000000..e010f8185
--- /dev/null
+++ b/extensions/source/bibliography/datman.cxx
@@ -0,0 +1,1390 @@
+/* -*- 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 <sal/config.h>
+
+#include <o3tl/any.hxx>
+#include <sal/log.hxx>
+#include <tools/diagnose_ex.h>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/sdbc/ResultSetType.hpp>
+#include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
+#include <com/sun/star/sdbcx/XRowLocate.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
+#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
+#include <com/sun/star/sdbc/XDataSource.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdb/DatabaseContext.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdb/XCompletedConnection.hpp>
+#include <com/sun/star/sdbc/SQLException.hpp>
+#include <com/sun/star/task/InteractionHandler.hpp>
+#include <com/sun/star/form/ListSourceType.hpp>
+#include <com/sun/star/form/XLoadable.hpp>
+#include <com/sun/star/form/runtime/FormController.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/form/XGridColumnFactory.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <tools/debug.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/weld.hxx>
+#include "datman.hxx"
+#include "bibresid.hxx"
+#include "bibmod.hxx"
+#include "bibview.hxx"
+#include "toolbar.hxx"
+#include "bibconfig.hxx"
+#include "bibbeam.hxx"
+#include "general.hxx"
+#include <strings.hrc>
+#include <helpids.h>
+#include <connectivity/dbtools.hxx>
+#include <memory>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::form;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+
+// PropertyNames
+constexpr OUStringLiteral FM_PROP_LABEL = u"Label";
+constexpr OUStringLiteral FM_PROP_CONTROLSOURCE = u"DataField";
+constexpr OUStringLiteral FM_PROP_NAME = u"Name";
+
+static Reference< XConnection > getConnection(const OUString& _rURL)
+{
+ // first get the sdb::DataSource corresponding to the url
+ Reference< XDataSource > xDataSource;
+ // is it a favorite title ?
+ Reference<XComponentContext> xContext = comphelper::getProcessComponentContext();
+ Reference< XDatabaseContext > xNamingContext = DatabaseContext::create(xContext);
+ if (xNamingContext->hasByName(_rURL))
+ {
+ DBG_ASSERT(xNamingContext.is(), "::getDataSource : no NamingService interface on the sdb::DatabaseAccessContext !");
+ try
+ {
+ xDataSource.set(xNamingContext->getRegisteredObject(_rURL), UNO_QUERY);
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("extensions.biblio", "");
+ }
+ }
+ // build the connection from the data source
+ Reference< XConnection > xConn;
+ if (xDataSource.is())
+ {
+ // need user/pwd for this
+ Reference< XCompletedConnection > xComplConn(xDataSource, UNO_QUERY);
+ try
+ {
+ Reference<task::XInteractionHandler> xIHdl( task::InteractionHandler::createWithParent(xContext, nullptr), UNO_QUERY_THROW);
+ xConn = xComplConn->connectWithCompletion(xIHdl);
+ }
+ catch (const SQLException&)
+ {
+ // TODO : a real error handling
+ }
+ catch (const Exception&)
+ {
+ }
+ }
+ return xConn;
+}
+
+static Reference< XConnection > getConnection(const Reference< XInterface > & xRowSet)
+{
+ Reference< XConnection > xConn;
+ try
+ {
+ Reference< XPropertySet > xFormProps(xRowSet, UNO_QUERY);
+ if (!xFormProps.is())
+ return xConn;
+
+ xConn.set(xFormProps->getPropertyValue("ActiveConnection"), UNO_QUERY);
+ if (!xConn.is())
+ {
+ SAL_INFO("extensions.biblio", "no active connection");
+ }
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("extensions.biblio", "");
+ }
+
+ return xConn;
+}
+
+static Reference< XNameAccess > getColumns(const Reference< XForm > & _rxForm)
+{
+ Reference< XNameAccess > xReturn;
+ // check if the form is alive
+ Reference< XColumnsSupplier > xSupplyCols( _rxForm, UNO_QUERY );
+ if (xSupplyCols.is())
+ xReturn = xSupplyCols->getColumns();
+
+ if (!xReturn.is() || !xReturn->getElementNames().hasElements())
+ { // no...
+ xReturn = nullptr;
+ // -> get the table the form is bound to and ask it for their columns
+ Reference< XTablesSupplier > xSupplyTables( getConnection( _rxForm ), UNO_QUERY );
+ Reference< XPropertySet > xFormProps( _rxForm, UNO_QUERY );
+ if (xFormProps.is() && xSupplyTables.is())
+ {
+ try
+ {
+ DBG_ASSERT(*o3tl::forceAccess<sal_Int32>(xFormProps->getPropertyValue("CommandType")) == CommandType::TABLE,
+ "::getColumns : invalid form (has no table as data source) !");
+ OUString sTable;
+ xFormProps->getPropertyValue("Command") >>= sTable;
+ Reference< XNameAccess > xTables = xSupplyTables->getTables();
+ if (xTables.is() && xTables->hasByName(sTable))
+ xSupplyCols.set(xTables->getByName(sTable), UNO_QUERY);
+ if (xSupplyCols.is())
+ xReturn = xSupplyCols->getColumns();
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "extensions.biblio", "::getColumns");
+ }
+
+ }
+ }
+ return xReturn;
+}
+
+namespace {
+
+class MappingDialog_Impl : public weld::GenericDialogController
+{
+ BibDataManager* pDatMan;
+
+ OUString sNone;
+ bool bModified;
+
+ std::unique_ptr<weld::Button> m_xOKBT;
+ std::unique_ptr<weld::ComboBox> m_xIdentifierLB;
+ std::unique_ptr<weld::ComboBox> m_xAuthorityTypeLB;
+ std::unique_ptr<weld::ComboBox> m_xAuthorLB;
+ std::unique_ptr<weld::ComboBox> m_xTitleLB;
+ std::unique_ptr<weld::ComboBox> m_xMonthLB;
+ std::unique_ptr<weld::ComboBox> m_xYearLB;
+ std::unique_ptr<weld::ComboBox> m_xISBNLB;
+ std::unique_ptr<weld::ComboBox> m_xBooktitleLB;
+ std::unique_ptr<weld::ComboBox> m_xChapterLB;
+ std::unique_ptr<weld::ComboBox> m_xEditionLB;
+ std::unique_ptr<weld::ComboBox> m_xEditorLB;
+ std::unique_ptr<weld::ComboBox> m_xHowpublishedLB;
+ std::unique_ptr<weld::ComboBox> m_xInstitutionLB;
+ std::unique_ptr<weld::ComboBox> m_xJournalLB;
+ std::unique_ptr<weld::ComboBox> m_xNoteLB;
+ std::unique_ptr<weld::ComboBox> m_xAnnoteLB;
+ std::unique_ptr<weld::ComboBox> m_xNumberLB;
+ std::unique_ptr<weld::ComboBox> m_xOrganizationsLB;
+ std::unique_ptr<weld::ComboBox> m_xPagesLB;
+ std::unique_ptr<weld::ComboBox> m_xPublisherLB;
+ std::unique_ptr<weld::ComboBox> m_xAddressLB;
+ std::unique_ptr<weld::ComboBox> m_xSchoolLB;
+ std::unique_ptr<weld::ComboBox> m_xSeriesLB;
+ std::unique_ptr<weld::ComboBox> m_xReportTypeLB;
+ std::unique_ptr<weld::ComboBox> m_xVolumeLB;
+ std::unique_ptr<weld::ComboBox> m_xURLLB;
+ std::unique_ptr<weld::ComboBox> m_xCustom1LB;
+ std::unique_ptr<weld::ComboBox> m_xCustom2LB;
+ std::unique_ptr<weld::ComboBox> m_xCustom3LB;
+ std::unique_ptr<weld::ComboBox> m_xCustom4LB;
+ std::unique_ptr<weld::ComboBox> m_xCustom5LB;
+ std::unique_ptr<weld::ComboBox> m_xLocalURLLB;
+ weld::ComboBox* aListBoxes[COLUMN_COUNT];
+
+ DECL_LINK(OkHdl, weld::Button&, void);
+ DECL_LINK(ListBoxSelectHdl, weld::ComboBox&, void);
+
+public:
+ MappingDialog_Impl(weld::Window* pParent, BibDataManager* pDatMan);
+};
+
+}
+
+static sal_uInt16 lcl_FindLogicalName(BibConfig const * pConfig ,
+ std::u16string_view rLogicalColumnName)
+{
+ for(sal_uInt16 i = 0; i < COLUMN_COUNT; i++)
+ {
+ if(rLogicalColumnName == pConfig->GetDefColumnName(i))
+ return i;
+ }
+ return USHRT_MAX;
+}
+
+MappingDialog_Impl::MappingDialog_Impl(weld::Window* pParent, BibDataManager* pMan)
+ : GenericDialogController(pParent, "modules/sbibliography/ui/mappingdialog.ui", "MappingDialog")
+ , pDatMan(pMan)
+ , sNone(BibResId(RID_BIB_STR_NONE))
+ , bModified(false)
+ , m_xOKBT(m_xBuilder->weld_button("ok"))
+ , m_xIdentifierLB(m_xBuilder->weld_combo_box("identifierCombobox"))
+ , m_xAuthorityTypeLB(m_xBuilder->weld_combo_box("authorityTypeCombobox"))
+ , m_xAuthorLB(m_xBuilder->weld_combo_box("authorCombobox"))
+ , m_xTitleLB(m_xBuilder->weld_combo_box("titleCombobox"))
+ , m_xMonthLB(m_xBuilder->weld_combo_box("monthCombobox"))
+ , m_xYearLB(m_xBuilder->weld_combo_box("yearCombobox"))
+ , m_xISBNLB(m_xBuilder->weld_combo_box("ISBNCombobox"))
+ , m_xBooktitleLB(m_xBuilder->weld_combo_box("bookTitleCombobox"))
+ , m_xChapterLB(m_xBuilder->weld_combo_box("chapterCombobox"))
+ , m_xEditionLB(m_xBuilder->weld_combo_box("editionCombobox"))
+ , m_xEditorLB(m_xBuilder->weld_combo_box("editorCombobox"))
+ , m_xHowpublishedLB(m_xBuilder->weld_combo_box("howPublishedCombobox"))
+ , m_xInstitutionLB(m_xBuilder->weld_combo_box("institutionCombobox"))
+ , m_xJournalLB(m_xBuilder->weld_combo_box("journalCombobox"))
+ , m_xNoteLB(m_xBuilder->weld_combo_box("noteCombobox"))
+ , m_xAnnoteLB(m_xBuilder->weld_combo_box("annoteCombobox"))
+ , m_xNumberLB(m_xBuilder->weld_combo_box("numberCombobox"))
+ , m_xOrganizationsLB(m_xBuilder->weld_combo_box("organizationCombobox"))
+ , m_xPagesLB(m_xBuilder->weld_combo_box("pagesCombobox"))
+ , m_xPublisherLB(m_xBuilder->weld_combo_box("publisherCombobox"))
+ , m_xAddressLB(m_xBuilder->weld_combo_box("addressCombobox"))
+ , m_xSchoolLB(m_xBuilder->weld_combo_box("schoolCombobox"))
+ , m_xSeriesLB(m_xBuilder->weld_combo_box("seriesCombobox"))
+ , m_xReportTypeLB(m_xBuilder->weld_combo_box("reportTypeCombobox"))
+ , m_xVolumeLB(m_xBuilder->weld_combo_box("volumeCombobox"))
+ , m_xURLLB(m_xBuilder->weld_combo_box("URLCombobox"))
+ , m_xCustom1LB(m_xBuilder->weld_combo_box("custom1Combobox"))
+ , m_xCustom2LB(m_xBuilder->weld_combo_box("custom2Combobox"))
+ , m_xCustom3LB(m_xBuilder->weld_combo_box("custom3Combobox"))
+ , m_xCustom4LB(m_xBuilder->weld_combo_box("custom4Combobox"))
+ , m_xCustom5LB(m_xBuilder->weld_combo_box("custom5Combobox"))
+ , m_xLocalURLLB(m_xBuilder->weld_combo_box("LocalURLCombobox"))
+{
+ m_xOKBT->connect_clicked(LINK(this, MappingDialog_Impl, OkHdl));
+ OUString sTitle = m_xDialog->get_title();
+ sTitle = sTitle.replaceFirst("%1", pDatMan->getActiveDataTable());
+ m_xDialog->set_title(sTitle);
+
+ aListBoxes[0] = m_xIdentifierLB.get();
+ aListBoxes[1] = m_xAuthorityTypeLB.get();
+ aListBoxes[2] = m_xAuthorLB.get();
+ aListBoxes[3] = m_xTitleLB.get();
+ aListBoxes[4] = m_xYearLB.get();
+ aListBoxes[5] = m_xISBNLB.get();
+ aListBoxes[6] = m_xBooktitleLB.get();
+ aListBoxes[7] = m_xChapterLB.get();
+ aListBoxes[8] = m_xEditionLB.get();
+ aListBoxes[9] = m_xEditorLB.get();
+ aListBoxes[10] = m_xHowpublishedLB.get();
+ aListBoxes[11] = m_xInstitutionLB.get();
+ aListBoxes[12] = m_xJournalLB.get();
+ aListBoxes[13] = m_xMonthLB.get();
+ aListBoxes[14] = m_xNoteLB.get();
+ aListBoxes[15] = m_xAnnoteLB.get();
+ aListBoxes[16] = m_xNumberLB.get();
+ aListBoxes[17] = m_xOrganizationsLB.get();
+ aListBoxes[18] = m_xPagesLB.get();
+ aListBoxes[19] = m_xPublisherLB.get();
+ aListBoxes[20] = m_xAddressLB.get();
+ aListBoxes[21] = m_xSchoolLB.get();
+ aListBoxes[22] = m_xSeriesLB.get();
+ aListBoxes[23] = m_xReportTypeLB.get();
+ aListBoxes[24] = m_xVolumeLB.get();
+ aListBoxes[25] = m_xURLLB.get();
+ aListBoxes[26] = m_xCustom1LB.get();
+ aListBoxes[27] = m_xCustom2LB.get();
+ aListBoxes[28] = m_xCustom3LB.get();
+ aListBoxes[29] = m_xCustom4LB.get();
+ aListBoxes[30] = m_xCustom5LB.get();
+ aListBoxes[31] = m_xLocalURLLB.get();
+
+ aListBoxes[0]->append_text(sNone);
+ Reference< XNameAccess > xFields = getColumns( pDatMan->getForm() );
+ DBG_ASSERT(xFields.is(), "MappingDialog_Impl::MappingDialog_Impl : gave me an invalid form !");
+ if (xFields.is())
+ {
+ const Sequence<OUString> aFieldNames = xFields->getElementNames();
+ for(const OUString& rName : aFieldNames)
+ aListBoxes[0]->append_text(rName);
+ }
+
+ Link<weld::ComboBox&,void> aLnk = LINK(this, MappingDialog_Impl, ListBoxSelectHdl);
+
+ aListBoxes[0]->set_active(0);
+ aListBoxes[0]->connect_changed(aLnk);
+ for(sal_uInt16 i = 1; i < COLUMN_COUNT; i++)
+ {
+ for(sal_Int32 j = 0, nEntryCount = aListBoxes[0]->get_count(); j < nEntryCount; ++j)
+ aListBoxes[i]->append_text(aListBoxes[0]->get_text(j));
+ aListBoxes[i]->set_active(0);
+ aListBoxes[i]->connect_changed(aLnk);
+ }
+ BibConfig* pConfig = BibModul::GetConfig();
+ BibDBDescriptor aDesc;
+ aDesc.sDataSource = pDatMan->getActiveDataSource();
+ aDesc.sTableOrQuery = pDatMan->getActiveDataTable();
+ aDesc.nCommandType = CommandType::TABLE;
+ const Mapping* pMapping = pConfig->GetMapping(aDesc);
+ if(pMapping)
+ {
+ for(const auto & aColumnPair : pMapping->aColumnPairs)
+ {
+ sal_uInt16 nListBoxIndex = lcl_FindLogicalName( pConfig, aColumnPair.sLogicalColumnName);
+ if(nListBoxIndex < COLUMN_COUNT)
+ {
+ aListBoxes[nListBoxIndex]->set_active_text(aColumnPair.sRealColumnName);
+ }
+ }
+ }
+}
+
+IMPL_LINK(MappingDialog_Impl, ListBoxSelectHdl, weld::ComboBox&, rListBox, void)
+{
+ const sal_Int32 nEntryPos = rListBox.get_active();
+ if (0 < nEntryPos)
+ {
+ for(auto & pListBoxe : aListBoxes)
+ {
+ if (&rListBox != pListBoxe && pListBoxe->get_active() == nEntryPos)
+ pListBoxe->set_active(0);
+ }
+ }
+ bModified = true;
+}
+
+IMPL_LINK_NOARG(MappingDialog_Impl, OkHdl, weld::Button&, void)
+{
+ if(bModified)
+ {
+ Mapping aNew;
+ aNew.sTableName = pDatMan->getActiveDataTable();
+ aNew.sURL = pDatMan->getActiveDataSource();
+
+ sal_uInt16 nWriteIndex = 0;
+ BibConfig* pConfig = BibModul::GetConfig();
+ for(sal_uInt16 nEntry = 0; nEntry < COLUMN_COUNT; nEntry++)
+ {
+ OUString sSel = aListBoxes[nEntry]->get_active_text();
+ if(sSel != sNone)
+ {
+ aNew.aColumnPairs[nWriteIndex].sRealColumnName = sSel;
+ aNew.aColumnPairs[nWriteIndex].sLogicalColumnName = pConfig->GetDefColumnName(nEntry);
+ nWriteIndex++;
+ }
+ }
+ BibDBDescriptor aDesc;
+ aDesc.sDataSource = pDatMan->getActiveDataSource();
+ aDesc.sTableOrQuery = pDatMan->getActiveDataTable();
+ aDesc.nCommandType = CommandType::TABLE;
+ pDatMan->ResetIdentifierMapping();
+ pConfig->SetMapping(aDesc, &aNew);
+ }
+ m_xDialog->response(bModified ? RET_OK : RET_CANCEL);
+}
+
+namespace {
+
+class DBChangeDialog_Impl : public weld::GenericDialogController
+{
+ DBChangeDialogConfig_Impl aConfig;
+
+ std::unique_ptr<weld::TreeView> m_xSelectionLB;
+
+ DECL_LINK(DoubleClickHdl, weld::TreeView&, bool);
+public:
+ DBChangeDialog_Impl(weld::Window* pParent, const BibDataManager* pMan);
+
+ OUString GetCurrentURL()const;
+};
+
+}
+
+DBChangeDialog_Impl::DBChangeDialog_Impl(weld::Window* pParent, const BibDataManager* pDatMan )
+ : GenericDialogController(pParent, "modules/sbibliography/ui/choosedatasourcedialog.ui", "ChooseDataSourceDialog")
+ , m_xSelectionLB(m_xBuilder->weld_tree_view("treeview"))
+{
+ m_xSelectionLB->set_size_request(-1, m_xSelectionLB->get_height_rows(6));
+ m_xSelectionLB->connect_row_activated(LINK(this, DBChangeDialog_Impl, DoubleClickHdl));
+ m_xSelectionLB->make_sorted();
+
+ try
+ {
+ OUString sActiveSource = pDatMan->getActiveDataSource();
+ for (const OUString& rSourceName : aConfig.GetDataSourceNames())
+ m_xSelectionLB->append_text(rSourceName);
+ m_xSelectionLB->select_text(sActiveSource);
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("extensions.biblio", "");
+ }
+}
+
+IMPL_LINK_NOARG(DBChangeDialog_Impl, DoubleClickHdl, weld::TreeView&, bool)
+{
+ m_xDialog->response(RET_OK);
+ return true;
+}
+
+OUString DBChangeDialog_Impl::GetCurrentURL()const
+{
+ return m_xSelectionLB->get_selected_text();
+}
+
+// XDispatchProvider
+BibInterceptorHelper::BibInterceptorHelper( const ::bib::BibBeamer* pBibBeamer, css::uno::Reference< css::frame::XDispatch > const & xDispatch)
+{
+ if( pBibBeamer )
+ {
+ xInterception = pBibBeamer->getDispatchProviderInterception();
+ if( xInterception.is() )
+ xInterception->registerDispatchProviderInterceptor( this );
+ }
+ if( xDispatch.is() )
+ xFormDispatch = xDispatch;
+}
+
+BibInterceptorHelper::~BibInterceptorHelper( )
+{
+}
+
+void BibInterceptorHelper::ReleaseInterceptor()
+{
+ if ( xInterception.is() )
+ xInterception->releaseDispatchProviderInterceptor( this );
+ xInterception.clear();
+}
+
+css::uno::Reference< css::frame::XDispatch > SAL_CALL
+ BibInterceptorHelper::queryDispatch( const css::util::URL& aURL, const OUString& aTargetFrameName, sal_Int32 nSearchFlags )
+{
+ Reference< XDispatch > xReturn;
+
+ OUString aCommand( aURL.Path );
+ if ( aCommand == "FormSlots/ConfirmDeletion" )
+ xReturn = xFormDispatch;
+ else
+ if ( xSlaveDispatchProvider.is() )
+ xReturn = xSlaveDispatchProvider->queryDispatch( aURL, aTargetFrameName, nSearchFlags);
+
+ return xReturn;
+}
+
+css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL
+ BibInterceptorHelper::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& aDescripts )
+{
+ Sequence< Reference< XDispatch> > aReturn( aDescripts.getLength() );
+ Reference< XDispatch >* pReturn = aReturn.getArray();
+ for ( const DispatchDescriptor& rDescript : aDescripts )
+ {
+ *pReturn++ = queryDispatch( rDescript.FeatureURL, rDescript.FrameName, rDescript.SearchFlags );
+ }
+ return aReturn;
+}
+
+// XDispatchProviderInterceptor
+css::uno::Reference< css::frame::XDispatchProvider > SAL_CALL
+ BibInterceptorHelper::getSlaveDispatchProvider( )
+{
+ return xSlaveDispatchProvider;
+}
+
+void SAL_CALL BibInterceptorHelper::setSlaveDispatchProvider( const css::uno::Reference< css::frame::XDispatchProvider >& xNewSlaveDispatchProvider )
+{
+ xSlaveDispatchProvider = xNewSlaveDispatchProvider;
+}
+
+css::uno::Reference< css::frame::XDispatchProvider > SAL_CALL
+ BibInterceptorHelper::getMasterDispatchProvider( )
+{
+ return xMasterDispatchProvider;
+}
+
+void SAL_CALL BibInterceptorHelper::setMasterDispatchProvider( const css::uno::Reference< css::frame::XDispatchProvider >& xNewMasterDispatchProvider )
+{
+ xMasterDispatchProvider = xNewMasterDispatchProvider;
+}
+
+
+constexpr OUStringLiteral gGridName(u"theGrid");
+
+BibDataManager::BibDataManager()
+ :BibDataManager_Base( GetMutex() )
+ ,m_aLoadListeners(m_aMutex)
+ ,pBibView( nullptr )
+ ,pToolbar(nullptr)
+{
+}
+
+
+BibDataManager::~BibDataManager()
+{
+ Reference< XLoadable > xLoad( m_xForm, UNO_QUERY );
+ Reference< XPropertySet > xPrSet( m_xForm, UNO_QUERY );
+ Reference< XComponent > xComp( m_xForm, UNO_QUERY );
+ if ( m_xForm.is() )
+ {
+ Reference< XComponent > xConnection;
+ xPrSet->getPropertyValue("ActiveConnection") >>= xConnection;
+ if (xLoad.is())
+ xLoad->unload();
+ if (xComp.is())
+ xComp->dispose();
+ if(xConnection.is())
+ xConnection->dispose();
+ m_xForm = nullptr;
+ }
+ if( m_xInterceptorHelper.is() )
+ {
+ m_xInterceptorHelper->ReleaseInterceptor();
+ m_xInterceptorHelper.clear();
+ }
+}
+
+void BibDataManager::InsertFields(const Reference< XFormComponent > & _rxGrid)
+{
+ if ( !_rxGrid.is() )
+ return;
+
+ try
+ {
+ Reference< XNameContainer > xColContainer( _rxGrid, UNO_QUERY );
+ // remove the old fields
+ if ( xColContainer->hasElements() )
+ {
+ const Sequence<OUString> aOldNames = xColContainer->getElementNames();
+ for ( const OUString& rName : aOldNames )
+ xColContainer->removeByName( rName );
+ }
+
+ Reference< XNameAccess > xFields = getColumns( m_xForm );
+ if (!xFields.is())
+ return;
+
+ Reference< XGridColumnFactory > xColFactory( _rxGrid, UNO_QUERY );
+
+ Reference< XPropertySet > xField;
+
+ const Sequence<OUString> aFieldNames = xFields->getElementNames();
+ for ( const OUString& rField : aFieldNames )
+ {
+ xFields->getByName( rField ) >>= xField;
+
+ OUString sCurrentModelType;
+ sal_Int32 nType = 0;
+ bool bIsFormatted = false;
+ bool bFormattedIsNumeric = true;
+ xField->getPropertyValue("Type") >>= nType;
+ switch(nType)
+ {
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ sCurrentModelType = "CheckBox";
+ break;
+
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ case DataType::BLOB:
+ sCurrentModelType = "TextField";
+ break;
+
+ case DataType::VARCHAR:
+ case DataType::LONGVARCHAR:
+ case DataType::CHAR:
+ case DataType::CLOB:
+ bFormattedIsNumeric = false;
+ [[fallthrough]];
+ default:
+ sCurrentModelType = "FormattedField";
+ bIsFormatted = true;
+ break;
+ }
+
+ Reference< XPropertySet > xCurrentCol = xColFactory->createColumn(sCurrentModelType);
+ if (bIsFormatted)
+ {
+ OUString sFormatKey("FormatKey");
+ xCurrentCol->setPropertyValue(sFormatKey, xField->getPropertyValue(sFormatKey));
+ Any aFormatted(bFormattedIsNumeric);
+ xCurrentCol->setPropertyValue("TreatAsNumber", aFormatted);
+ }
+ Any aColName( rField );
+ xCurrentCol->setPropertyValue(FM_PROP_CONTROLSOURCE, aColName);
+ xCurrentCol->setPropertyValue(FM_PROP_LABEL, aColName);
+
+ xColContainer->insertByName( rField, Any( xCurrentCol ) );
+ }
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("extensions.biblio", "");
+ }
+}
+
+Reference< awt::XControlModel > BibDataManager::updateGridModel()
+{
+ return updateGridModel( m_xForm );
+}
+
+Reference< awt::XControlModel > const & BibDataManager::updateGridModel(const Reference< XForm > & xDbForm)
+{
+ try
+ {
+ Reference< XPropertySet > aFormPropSet( xDbForm, UNO_QUERY );
+ OUString sName;
+ aFormPropSet->getPropertyValue("Command") >>= sName;
+
+ if ( !m_xGridModel.is() )
+ {
+ m_xGridModel = createGridModel( gGridName );
+
+ Reference< XNameContainer > xNameCont(xDbForm, UNO_QUERY);
+ xNameCont->insertByName( sName, Any( m_xGridModel ) );
+ }
+
+ // insert the fields
+ Reference< XFormComponent > xFormComp( m_xGridModel, UNO_QUERY );
+ InsertFields( xFormComp );
+ }
+ catch (const Exception&)
+ {
+ OSL_FAIL("::updateGridModel: something went wrong !");
+ }
+
+ return m_xGridModel;
+}
+
+Reference< XForm > BibDataManager::createDatabaseForm(BibDBDescriptor& rDesc)
+{
+ Reference< XForm > xResult;
+ try
+ {
+ Reference< XMultiServiceFactory > xMgr = comphelper::getProcessServiceFactory();
+ m_xForm.set( xMgr->createInstance( "com.sun.star.form.component.Form" ), UNO_QUERY );
+
+ Reference< XPropertySet > aPropertySet( m_xForm, UNO_QUERY );
+
+ aDataSourceURL = rDesc.sDataSource;
+ if(aPropertySet.is())
+ {
+ Any aVal;
+ aVal <<= sal_Int32(ResultSetType::SCROLL_INSENSITIVE);
+ aPropertySet->setPropertyValue("ResultSetType",aVal );
+ aVal <<= sal_Int32(ResultSetConcurrency::READ_ONLY);
+ aPropertySet->setPropertyValue("ResultSetConcurrency", aVal);
+
+ //Caching for Performance
+ aVal <<= sal_Int32(50);
+ aPropertySet->setPropertyValue("FetchSize", aVal);
+
+ Reference< XConnection > xConnection = getConnection(rDesc.sDataSource);
+ aVal <<= xConnection;
+ aPropertySet->setPropertyValue("ActiveConnection", aVal);
+
+ Reference< XTablesSupplier > xSupplyTables(xConnection, UNO_QUERY);
+ Reference< XNameAccess > xTables = xSupplyTables.is() ?
+ xSupplyTables->getTables() : Reference< XNameAccess > ();
+
+ Sequence< OUString > aTableNameSeq;
+ if (xTables.is())
+ aTableNameSeq = xTables->getElementNames();
+
+ if(aTableNameSeq.hasElements())
+ {
+ if(!rDesc.sTableOrQuery.isEmpty())
+ aActiveDataTable = rDesc.sTableOrQuery;
+ else
+ {
+ rDesc.sTableOrQuery = aActiveDataTable = aTableNameSeq[0];
+ rDesc.nCommandType = CommandType::TABLE;
+ }
+
+ aVal <<= aActiveDataTable;
+ aPropertySet->setPropertyValue("Command", aVal);
+ aVal <<= rDesc.nCommandType;
+ aPropertySet->setPropertyValue("CommandType", aVal);
+
+
+ Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData();
+ aQuoteChar = xMetaData->getIdentifierQuoteString();
+
+ Reference< XMultiServiceFactory > xFactory(xConnection, UNO_QUERY);
+ if ( xFactory.is() )
+ m_xParser.set( xFactory->createInstance("com.sun.star.sdb.SingleSelectQueryComposer"), UNO_QUERY );
+
+ OUString aString("SELECT * FROM ");
+
+ OUString sCatalog, sSchema, sName;
+ ::dbtools::qualifiedNameComponents( xMetaData, aActiveDataTable, sCatalog, sSchema, sName, ::dbtools::EComposeRule::InDataManipulation );
+ aString += ::dbtools::composeTableNameForSelect( xConnection, sCatalog, sSchema, sName );
+
+ m_xParser->setElementaryQuery(aString);
+ BibConfig* pConfig = BibModul::GetConfig();
+ pConfig->setQueryField(getQueryField());
+ startQueryWith(pConfig->getQueryText());
+
+ xResult = m_xForm;
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ OSL_FAIL("::createDatabaseForm: something went wrong !");
+ }
+
+ return xResult;
+}
+
+Sequence< OUString > BibDataManager::getDataSources() const
+{
+ Sequence< OUString > aTableNameSeq;
+
+ try
+ {
+ Reference< XTablesSupplier > xSupplyTables( getConnection( m_xForm ), UNO_QUERY );
+ Reference< XNameAccess > xTables;
+ if (xSupplyTables.is())
+ xTables = xSupplyTables->getTables();
+ if (xTables.is())
+ aTableNameSeq = xTables->getElementNames();
+ }
+ catch (const Exception&)
+ {
+ OSL_FAIL("::getDataSources: something went wrong !");
+ }
+
+ return aTableNameSeq;
+}
+
+
+void BibDataManager::setFilter(const OUString& rQuery)
+{
+ if(!m_xParser.is())
+ return;
+ try
+ {
+ m_xParser->setFilter( rQuery );
+ OUString aQuery = m_xParser->getFilter();
+ Reference< XPropertySet > xFormProps( m_xForm, UNO_QUERY_THROW );
+ xFormProps->setPropertyValue( "Filter", Any( aQuery ) );
+ xFormProps->setPropertyValue( "ApplyFilter", Any( true ) );
+ reload();
+ }
+ catch (const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("extensions.biblio");
+ }
+
+
+}
+
+OUString BibDataManager::getFilter() const
+{
+
+ OUString aQueryString;
+ try
+ {
+ Reference< XPropertySet > xFormProps( m_xForm, UNO_QUERY_THROW );
+ OSL_VERIFY( xFormProps->getPropertyValue( "Filter" ) >>= aQueryString );
+ }
+ catch (const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("extensions.biblio");
+ }
+
+
+ return aQueryString;
+
+}
+
+Sequence< OUString > BibDataManager::getQueryFields() const
+{
+ Sequence< OUString > aFieldSeq;
+ Reference< XNameAccess > xFields = getColumns( m_xForm );
+ if (xFields.is())
+ aFieldSeq = xFields->getElementNames();
+ return aFieldSeq;
+}
+
+OUString BibDataManager::getQueryField() const
+{
+ BibConfig* pConfig = BibModul::GetConfig();
+ OUString aFieldString = pConfig->getQueryField();
+ if(aFieldString.isEmpty())
+ {
+ const Sequence< OUString > aSeq = getQueryFields();
+ if(aSeq.hasElements())
+ {
+ aFieldString=aSeq[0];
+ }
+ }
+ return aFieldString;
+}
+
+void BibDataManager::startQueryWith(const OUString& rQuery)
+{
+ BibConfig* pConfig = BibModul::GetConfig();
+ pConfig->setQueryText( rQuery );
+
+ OUString aQueryString;
+ if(!rQuery.isEmpty())
+ {
+ aQueryString=aQuoteChar + getQueryField() + aQuoteChar + " like '";
+ OUString sQuery = rQuery.replaceAll("?","_").replaceAll("*","%");
+ aQueryString += sQuery + "%'";
+ }
+ setFilter(aQueryString);
+}
+
+void BibDataManager::setActiveDataSource(const OUString& rURL)
+{
+ OUString sTmp(aDataSourceURL);
+ aDataSourceURL = rURL;
+
+ Reference< XPropertySet > aPropertySet( m_xForm, UNO_QUERY );
+ if(!aPropertySet.is())
+ return;
+
+ unload();
+
+ Reference< XComponent > xOldConnection;
+ aPropertySet->getPropertyValue("ActiveConnection") >>= xOldConnection;
+
+ Reference< XConnection > xConnection = getConnection(rURL);
+ if(!xConnection.is())
+ {
+ aDataSourceURL = sTmp;
+ return;
+ }
+ Any aVal; aVal <<= xConnection;
+ aPropertySet->setPropertyValue("ActiveConnection", aVal);
+ Reference< XMultiServiceFactory > xFactory(xConnection, UNO_QUERY);
+ if ( xFactory.is() )
+ m_xParser.set( xFactory->createInstance("com.sun.star.sdb.SingleSelectQueryComposer"), UNO_QUERY );
+
+ if(xOldConnection.is())
+ xOldConnection->dispose();
+
+ Sequence< OUString > aTableNameSeq;
+ Reference< XTablesSupplier > xSupplyTables(xConnection, UNO_QUERY);
+ if(xSupplyTables.is())
+ {
+ Reference< XNameAccess > xAccess = xSupplyTables->getTables();
+ aTableNameSeq = xAccess->getElementNames();
+ }
+ if(aTableNameSeq.hasElements())
+ {
+ aActiveDataTable = aTableNameSeq[0];
+ aVal <<= aActiveDataTable;
+ aPropertySet->setPropertyValue("Command", aVal);
+ aPropertySet->setPropertyValue("CommandType", Any(CommandType::TABLE));
+ //Caching for Performance
+ aVal <<= sal_Int32(50);
+ aPropertySet->setPropertyValue("FetchSize", aVal);
+ OUString aString("SELECT * FROM ");
+ // quote the table name which may contain catalog.schema.table
+ Reference<XDatabaseMetaData> xMetaData = xConnection->getMetaData();
+ aQuoteChar = xMetaData->getIdentifierQuoteString();
+
+ OUString sCatalog, sSchema, sName;
+ ::dbtools::qualifiedNameComponents( xMetaData, aActiveDataTable, sCatalog, sSchema, sName, ::dbtools::EComposeRule::InDataManipulation );
+ aString += ::dbtools::composeTableNameForSelect( xConnection, sCatalog, sSchema, sName );
+
+ m_xParser->setElementaryQuery(aString);
+ BibConfig* pConfig = BibModul::GetConfig();
+ pConfig->setQueryField(getQueryField());
+ startQueryWith(pConfig->getQueryText());
+ setActiveDataTable(aActiveDataTable);
+ }
+ FeatureStateEvent aEvent;
+ util::URL aURL;
+ aEvent.IsEnabled = true;
+ aEvent.Requery = false;
+ aEvent.FeatureDescriptor = getActiveDataTable();
+
+ aEvent.State <<= getDataSources();
+
+ if(pToolbar)
+ {
+ aURL.Complete =".uno:Bib/source";
+ aEvent.FeatureURL = aURL;
+ pToolbar->statusChanged( aEvent );
+ }
+
+ updateGridModel();
+ load();
+}
+
+
+void BibDataManager::setActiveDataTable(const OUString& rTable)
+{
+ ResetIdentifierMapping();
+ try
+ {
+ Reference< XPropertySet > aPropertySet( m_xForm, UNO_QUERY );
+
+ if(aPropertySet.is())
+ {
+ Reference< XConnection > xConnection = getConnection( m_xForm );
+ Reference< XTablesSupplier > xSupplyTables(xConnection, UNO_QUERY);
+ Reference< XNameAccess > xAccess = xSupplyTables->getTables();
+ Sequence< OUString > aTableNameSeq = xAccess->getElementNames();
+ sal_uInt32 nCount = aTableNameSeq.getLength();
+
+ const OUString* pTableNames = aTableNameSeq.getConstArray();
+ const OUString* pTableNamesEnd = pTableNames + nCount;
+
+ for ( ; pTableNames != pTableNamesEnd; ++pTableNames )
+ {
+ if ( rTable == *pTableNames )
+ {
+ aActiveDataTable = rTable;
+ Any aVal; aVal <<= rTable;
+ aPropertySet->setPropertyValue( "Command", aVal );
+ break;
+ }
+ }
+ if (pTableNames != pTableNamesEnd)
+ {
+ Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData();
+ aQuoteChar = xMetaData->getIdentifierQuoteString();
+
+ Reference< XMultiServiceFactory > xFactory(xConnection, UNO_QUERY);
+ if ( xFactory.is() )
+ m_xParser.set( xFactory->createInstance("com.sun.star.sdb.SingleSelectQueryComposer"), UNO_QUERY );
+
+ OUString aString("SELECT * FROM ");
+
+ OUString sCatalog, sSchema, sName;
+ ::dbtools::qualifiedNameComponents( xMetaData, aActiveDataTable, sCatalog, sSchema, sName, ::dbtools::EComposeRule::InDataManipulation );
+ aString += ::dbtools::composeTableNameForSelect( xConnection, sCatalog, sSchema, sName );
+
+ m_xParser->setElementaryQuery(aString);
+
+ BibConfig* pConfig = BibModul::GetConfig();
+ pConfig->setQueryField(getQueryField());
+ startQueryWith(pConfig->getQueryText());
+
+ BibDBDescriptor aDesc;
+ aDesc.sDataSource = aDataSourceURL;
+ aDesc.sTableOrQuery = aActiveDataTable;
+ aDesc.nCommandType = CommandType::TABLE;
+ BibModul::GetConfig()->SetBibliographyURL(aDesc);
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ OSL_FAIL("::setActiveDataTable: something went wrong !");
+ }
+}
+
+
+void SAL_CALL BibDataManager::load( )
+{
+ if ( isLoaded() )
+ // nothing to do
+ return;
+
+ Reference< XLoadable > xFormAsLoadable( m_xForm, UNO_QUERY );
+ DBG_ASSERT( xFormAsLoadable.is() || !m_xForm.is(), "BibDataManager::load: invalid form!");
+ if ( xFormAsLoadable.is() )
+ {
+ xFormAsLoadable->load();
+
+ EventObject aEvt( static_cast< XWeak* >( this ) );
+ m_aLoadListeners.notifyEach( &XLoadListener::loaded, aEvt );
+ }
+}
+
+
+void SAL_CALL BibDataManager::unload( )
+{
+ if ( !isLoaded() )
+ // nothing to do
+ return;
+
+ Reference< XLoadable >xFormAsLoadable( m_xForm, UNO_QUERY );
+ DBG_ASSERT( xFormAsLoadable.is() || !m_xForm.is(), "BibDataManager::unload: invalid form!");
+ if ( !xFormAsLoadable.is() )
+ return;
+
+ EventObject aEvt( static_cast< XWeak* >( this ) );
+
+ {
+ m_aLoadListeners.notifyEach( &XLoadListener::unloading, aEvt );
+ }
+
+ xFormAsLoadable->unload();
+
+ {
+ m_aLoadListeners.notifyEach( &XLoadListener::unloaded, aEvt );
+ }
+}
+
+
+void SAL_CALL BibDataManager::reload( )
+{
+ if ( !isLoaded() )
+ // nothing to do
+ return;
+
+ Reference< XLoadable >xFormAsLoadable( m_xForm, UNO_QUERY );
+ DBG_ASSERT( xFormAsLoadable.is() || !m_xForm.is(), "BibDataManager::unload: invalid form!");
+ if ( !xFormAsLoadable.is() )
+ return;
+
+ EventObject aEvt( static_cast< XWeak* >( this ) );
+
+ {
+ m_aLoadListeners.notifyEach( &XLoadListener::reloading, aEvt );
+ }
+
+ xFormAsLoadable->reload();
+
+ {
+ m_aLoadListeners.notifyEach( &XLoadListener::reloaded, aEvt );
+ }
+}
+
+
+sal_Bool SAL_CALL BibDataManager::isLoaded( )
+{
+ Reference< XLoadable >xFormAsLoadable( m_xForm, UNO_QUERY );
+ DBG_ASSERT( xFormAsLoadable.is() || !m_xForm.is(), "BibDataManager::isLoaded: invalid form!");
+
+ bool bLoaded = false;
+ if ( xFormAsLoadable.is() )
+ bLoaded = xFormAsLoadable->isLoaded();
+ return bLoaded;
+}
+
+
+void SAL_CALL BibDataManager::addLoadListener( const Reference< XLoadListener >& aListener )
+{
+ m_aLoadListeners.addInterface( aListener );
+}
+
+
+void SAL_CALL BibDataManager::removeLoadListener( const Reference< XLoadListener >& aListener )
+{
+ m_aLoadListeners.removeInterface( aListener );
+}
+
+
+Reference< awt::XControlModel > BibDataManager::createGridModel(const OUString& rName)
+{
+ Reference< awt::XControlModel > xModel;
+
+ try
+ {
+ // create the control model
+ Reference< XMultiServiceFactory > xMgr = ::comphelper::getProcessServiceFactory();
+ Reference< XInterface > xObject = xMgr->createInstance("com.sun.star.form.component.GridControl");
+ xModel.set( xObject, UNO_QUERY );
+
+ // set the
+ Reference< XPropertySet > xPropSet( xModel, UNO_QUERY );
+ xPropSet->setPropertyValue( "Name", Any( rName ) );
+
+ // set the name of the to-be-created control
+ Any aAny(OUString("com.sun.star.form.control.InteractionGridControl"));
+ xPropSet->setPropertyValue( "DefaultControl",aAny );
+
+ // the helpURL
+ OUString uProp("HelpURL");
+ Reference< XPropertySetInfo > xPropInfo = xPropSet->getPropertySetInfo();
+ if (xPropInfo->hasPropertyByName(uProp))
+ {
+ xPropSet->setPropertyValue(
+ uProp, Any(OUString(INET_HID_SCHEME + HID_BIB_DB_GRIDCTRL)));
+ }
+ }
+ catch (const Exception&)
+ {
+ OSL_FAIL("::createGridModel: something went wrong !");
+ }
+
+ return xModel;
+}
+
+OUString BibDataManager::getControlName(sal_Int32 nFormatKey )
+{
+ OUString aResStr;
+ switch (nFormatKey)
+ {
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ aResStr="CheckBox";
+ break;
+ case DataType::TINYINT:
+ case DataType::SMALLINT:
+ case DataType::INTEGER:
+ aResStr="NumericField";
+ break;
+ case DataType::REAL:
+ case DataType::DOUBLE:
+ case DataType::NUMERIC:
+ case DataType::DECIMAL:
+ aResStr="FormattedField";
+ break;
+ case DataType::TIMESTAMP:
+ aResStr="FormattedField";
+ break;
+ case DataType::DATE:
+ aResStr="DateField";
+ break;
+ case DataType::TIME:
+ aResStr="TimeField";
+ break;
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::LONGVARCHAR:
+ default:
+ aResStr="TextField";
+ break;
+ }
+ return aResStr;
+}
+
+Reference< awt::XControlModel > BibDataManager::loadControlModel(
+ const OUString& rName, bool bForceListBox)
+{
+ Reference< awt::XControlModel > xModel;
+ OUString aName = "View_" + rName;
+
+ try
+ {
+ Reference< XNameAccess > xFields = getColumns( m_xForm );
+ if (!xFields.is())
+ return xModel;
+ Reference< XPropertySet > xField;
+
+ Any aElement;
+
+ if(xFields->hasByName(rName))
+ {
+ aElement = xFields->getByName(rName);
+ aElement >>= xField;
+
+ sal_Int32 nFormatKey = 0;
+ xField->getPropertyValue("Type") >>= nFormatKey;
+
+ OUString aInstanceName("com.sun.star.form.component.");
+
+ if (bForceListBox)
+ aInstanceName += "ListBox";
+ else
+ aInstanceName += getControlName(nFormatKey);
+
+ Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
+ Reference< XInterface > xObject = xContext->getServiceManager()->createInstanceWithContext(aInstanceName, xContext);
+ xModel.set( xObject, UNO_QUERY );
+ Reference< XPropertySet > xPropSet( xModel, UNO_QUERY );
+ Any aFieldName; aFieldName <<= aName;
+
+ xPropSet->setPropertyValue( FM_PROP_NAME,aFieldName);
+ xPropSet->setPropertyValue( FM_PROP_CONTROLSOURCE, Any( rName ) );
+ xPropSet->setPropertyValue("NativeWidgetLook", Any( true ) );
+
+ if (bForceListBox)
+ {
+ uno::Any aAny;
+
+ //uno::Reference< beans::XPropertySet > xPropSet(xControl, UNO_QUERY);
+ aAny <<= sal_Int16(1);
+ xPropSet->setPropertyValue("BoundColumn", aAny);
+ aAny <<= ListSourceType_VALUELIST;
+ xPropSet->setPropertyValue("ListSourceType", aAny);
+
+ uno::Sequence<OUString> aListSource(TYPE_COUNT);
+ OUString* pListSourceArr = aListSource.getArray();
+ //pListSourceArr[0] = "select TypeName, TypeIndex from TypeNms";
+ for(sal_Int32 i = 0; i < TYPE_COUNT; ++i)
+ pListSourceArr[i] = OUString::number(i);
+ aAny <<= aListSource;
+
+ xPropSet->setPropertyValue("ListSource", aAny);
+
+ uno::Sequence<OUString> aValues(TYPE_COUNT + 1);
+ OUString* pValuesArr = aValues.getArray();
+ pValuesArr[0] = BibResId(ST_TYPE_ARTICLE);
+ pValuesArr[1] = BibResId(ST_TYPE_BOOK);
+ pValuesArr[2] = BibResId(ST_TYPE_BOOKLET);
+ pValuesArr[3] = BibResId(ST_TYPE_CONFERENCE);
+ pValuesArr[4] = BibResId(ST_TYPE_INBOOK );
+ pValuesArr[5] = BibResId(ST_TYPE_INCOLLECTION);
+ pValuesArr[6] = BibResId(ST_TYPE_INPROCEEDINGS);
+ pValuesArr[7] = BibResId(ST_TYPE_JOURNAL );
+ pValuesArr[8] = BibResId(ST_TYPE_MANUAL );
+ pValuesArr[9] = BibResId(ST_TYPE_MASTERSTHESIS);
+ pValuesArr[10] = BibResId(ST_TYPE_MISC );
+ pValuesArr[11] = BibResId(ST_TYPE_PHDTHESIS );
+ pValuesArr[12] = BibResId(ST_TYPE_PROCEEDINGS );
+ pValuesArr[13] = BibResId(ST_TYPE_TECHREPORT );
+ pValuesArr[14] = BibResId(ST_TYPE_UNPUBLISHED );
+ pValuesArr[15] = BibResId(ST_TYPE_EMAIL );
+ pValuesArr[16] = BibResId(ST_TYPE_WWW );
+ pValuesArr[17] = BibResId(ST_TYPE_CUSTOM1 );
+ pValuesArr[18] = BibResId(ST_TYPE_CUSTOM2 );
+ pValuesArr[19] = BibResId(ST_TYPE_CUSTOM3 );
+ pValuesArr[20] = BibResId(ST_TYPE_CUSTOM4 );
+ pValuesArr[21] = BibResId(ST_TYPE_CUSTOM5 );
+ // empty string if an invalid value no values is set
+ pValuesArr[TYPE_COUNT].clear();
+
+ aAny <<= aValues;
+
+ xPropSet->setPropertyValue("StringItemList", aAny);
+
+ xPropSet->setPropertyValue( "Dropdown", Any(true) );
+ }
+
+ Reference< XFormComponent > aFormComp(xModel,UNO_QUERY );
+
+ Reference< XNameContainer > xNameCont( m_xForm, UNO_QUERY );
+ xNameCont->insertByName(aName, Any( aFormComp ) );
+
+ // now if the form where we inserted the new model is already loaded, notify the model of this
+ // Note that this implementation below is a HACK as it relies on the fact that the model adds itself
+ // as load listener to its parent, which is an implementation detail of the model.
+ //
+ // the better solution would be the following:
+ // in the current scenario, we insert a control model into a form. This results in the control model
+ // adding itself as load listener to the form. Now, the form should realize that it's already loaded
+ // and notify the model (which it knows as XLoadListener only) immediately. This seems to make sense.
+ // (as an analogon to the XStatusListener semantics).
+ //
+ // But this would be way too risky for this last-day fix here.
+ Reference< XLoadable > xLoad( m_xForm, UNO_QUERY );
+ if ( xLoad.is() && xLoad->isLoaded() )
+ {
+ Reference< XLoadListener > xListener( aFormComp, UNO_QUERY );
+ if ( xListener.is() )
+ {
+ EventObject aLoadSource;
+ aLoadSource.Source = xLoad;
+ xListener->loaded( aLoadSource );
+ }
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ OSL_FAIL("::loadControlModel: something went wrong !");
+ }
+ return xModel;
+}
+
+void BibDataManager::CreateMappingDialog(weld::Window* pParent)
+{
+ MappingDialog_Impl aDlg(pParent, this);
+ if (RET_OK == aDlg.run() && pBibView)
+ {
+ reload();
+ }
+}
+
+OUString BibDataManager::CreateDBChangeDialog(weld::Window* pParent)
+{
+ OUString uRet;
+ DBChangeDialog_Impl aDlg(pParent, this);
+ if (aDlg.run() == RET_OK)
+ {
+ OUString sNewURL = aDlg.GetCurrentURL();
+ if(sNewURL != getActiveDataSource())
+ {
+ uRet = sNewURL;
+ }
+ }
+ return uRet;
+}
+
+void BibDataManager::DispatchDBChangeDialog()
+{
+ if (pToolbar)
+ pToolbar->SendDispatch(pToolbar->GetChangeSourceId(), Sequence< PropertyValue >());
+}
+
+const OUString& BibDataManager::GetIdentifierMapping()
+{
+ if(sIdentifierMapping.isEmpty())
+ {
+ BibConfig* pConfig = BibModul::GetConfig();
+ BibDBDescriptor aDesc;
+ aDesc.sDataSource = getActiveDataSource();
+ aDesc.sTableOrQuery = getActiveDataTable();
+ aDesc.nCommandType = CommandType::TABLE;
+ const Mapping* pMapping = pConfig->GetMapping(aDesc);
+ sIdentifierMapping = pConfig->GetDefColumnName(IDENTIFIER_POS);
+ if(pMapping)
+ {
+ for(const auto & aColumnPair : pMapping->aColumnPairs)
+ {
+ if(aColumnPair.sLogicalColumnName == sIdentifierMapping)
+ {
+ sIdentifierMapping = aColumnPair.sRealColumnName;
+ break;
+ }
+ }
+ }
+ }
+ return sIdentifierMapping;
+}
+
+void BibDataManager::SetToolbar(BibToolBar* pSet)
+{
+ pToolbar = pSet;
+ if(pToolbar)
+ pToolbar->SetDatMan(*this);
+}
+
+uno::Reference< form::runtime::XFormController > const & BibDataManager::GetFormController()
+{
+ if(!m_xFormCtrl.is())
+ {
+ Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
+ m_xFormCtrl = form::runtime::FormController::create(xContext);
+ m_xFormCtrl->setModel(uno::Reference< awt::XTabControllerModel > (getForm(), UNO_QUERY));
+ m_xFormDispatch.set( m_xFormCtrl, UNO_QUERY);
+ }
+ return m_xFormCtrl;
+}
+
+void BibDataManager::RegisterInterceptor( const ::bib::BibBeamer* pBibBeamer)
+{
+ DBG_ASSERT( !m_xInterceptorHelper.is(), "BibDataManager::RegisterInterceptor: called twice!" );
+
+ if( pBibBeamer )
+ m_xInterceptorHelper = new BibInterceptorHelper( pBibBeamer, m_xFormDispatch);
+}
+
+
+bool BibDataManager::HasActiveConnection() const
+{
+ return getConnection( m_xForm ).is();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/datman.hxx b/extensions/source/bibliography/datman.hxx
new file mode 100644
index 000000000..36cbdcd59
--- /dev/null
+++ b/extensions/source/bibliography/datman.hxx
@@ -0,0 +1,169 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include "bibview.hxx"
+
+#include <com/sun/star/awt/XControlModel.hpp>
+#include <com/sun/star/form/XForm.hpp>
+#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
+#include <com/sun/star/form/runtime/XFormController.hpp>
+#include <cppuhelper/compbase.hxx>
+#include <comphelper/interfacecontainer2.hxx>
+#include <com/sun/star/form/XLoadable.hpp>
+#include <comphelper/broadcasthelper.hxx>
+#include <com/sun/star/frame/XDispatchProviderInterceptor.hpp>
+#include <com/sun/star/frame/XDispatchProviderInterception.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <vcl/vclptr.hxx>
+
+namespace weld { class Window; }
+
+namespace bib
+{
+ class BibView;
+ class BibBeamer;
+}
+
+class BibToolBar;
+struct BibDBDescriptor;
+
+class BibInterceptorHelper
+ :public cppu::WeakImplHelper< css::frame::XDispatchProviderInterceptor >
+{
+private:
+ css::uno::Reference< css::frame::XDispatchProvider > xMasterDispatchProvider;
+ css::uno::Reference< css::frame::XDispatchProvider > xSlaveDispatchProvider;
+ css::uno::Reference< css::frame::XDispatch > xFormDispatch;
+ css::uno::Reference< css::frame::XDispatchProviderInterception > xInterception;
+
+protected:
+ virtual ~BibInterceptorHelper( ) override;
+
+public:
+ BibInterceptorHelper( const ::bib::BibBeamer* pBibBeamer, css::uno::Reference< css::frame::XDispatch > const & xDispatch);
+
+ void ReleaseInterceptor();
+
+ // XDispatchProvider
+ virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch( const css::util::URL& aURL, const OUString& aTargetFrameName, sal_Int32 nSearchFlags ) override;
+ virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& aDescripts ) override;
+ // XDispatchProviderInterceptor
+ virtual css::uno::Reference< css::frame::XDispatchProvider > SAL_CALL getSlaveDispatchProvider( ) override;
+ virtual void SAL_CALL setSlaveDispatchProvider( const css::uno::Reference< css::frame::XDispatchProvider >& xNewSlaveDispatchProvider ) override;
+ virtual css::uno::Reference< css::frame::XDispatchProvider > SAL_CALL getMasterDispatchProvider( ) override;
+ virtual void SAL_CALL setMasterDispatchProvider( const css::uno::Reference< css::frame::XDispatchProvider >& xNewMasterDispatchProvider ) override;
+};
+
+typedef cppu::WeakComponentImplHelper < css::form::XLoadable
+ > BibDataManager_Base;
+class BibDataManager final
+ :public ::comphelper::OMutexAndBroadcastHelper
+ ,public BibDataManager_Base
+{
+private:
+ css::uno::Reference< css::form::XForm > m_xForm;
+ css::uno::Reference< css::awt::XControlModel > m_xGridModel;
+ css::uno::Reference< css::sdb::XSingleSelectQueryComposer > m_xParser;
+ css::uno::Reference< css::form::runtime::XFormController > m_xFormCtrl;
+ css::uno::Reference< css::frame::XDispatch > m_xFormDispatch;
+ rtl::Reference<BibInterceptorHelper> m_xInterceptorHelper;
+
+ OUString aActiveDataTable;
+ OUString aDataSourceURL;
+ OUString aQuoteChar;
+
+ ::comphelper::OInterfaceContainerHelper2 m_aLoadListeners;
+
+ VclPtr< ::bib::BibView> pBibView;
+ VclPtr<BibToolBar> pToolbar;
+
+ OUString sIdentifierMapping;
+
+ void InsertFields(const css::uno::Reference< css::form::XFormComponent > & xGrid);
+
+ css::uno::Reference< css::awt::XControlModel > const &
+ updateGridModel(const css::uno::Reference< css::form::XForm > & xDbForm);
+ static css::uno::Reference< css::awt::XControlModel >
+ createGridModel( const OUString& rName );
+
+ // XLoadable
+ virtual void SAL_CALL load( ) override;
+ virtual void SAL_CALL unload( ) override;
+ virtual void SAL_CALL reload( ) override;
+ virtual sal_Bool SAL_CALL isLoaded( ) override;
+ virtual void SAL_CALL addLoadListener( const css::uno::Reference< css::form::XLoadListener >& aListener ) override;
+ virtual void SAL_CALL removeLoadListener( const css::uno::Reference< css::form::XLoadListener >& aListener ) override;
+
+ using WeakComponentImplHelperBase::disposing;
+
+public:
+
+ BibDataManager();
+ virtual ~BibDataManager() override;
+
+ css::uno::Reference< css::form::XForm > createDatabaseForm( BibDBDescriptor& aDesc);
+
+ css::uno::Reference< css::awt::XControlModel > updateGridModel();
+
+ css::uno::Sequence< OUString> getDataSources() const;
+
+ const OUString& getActiveDataSource() const {return aDataSourceURL;}
+ void setActiveDataSource(const OUString& rURL);
+
+ const OUString& getActiveDataTable() const { return aActiveDataTable;}
+ void setActiveDataTable(const OUString& rTable);
+
+ void setFilter(const OUString& rQuery);
+ OUString getFilter() const;
+
+ css::uno::Sequence< OUString> getQueryFields() const;
+ OUString getQueryField() const;
+ void startQueryWith(const OUString& rQuery);
+
+ const css::uno::Reference< css::sdb::XSingleSelectQueryComposer >& getParser() const { return m_xParser; }
+ const css::uno::Reference< css::form::XForm >& getForm() const { return m_xForm; }
+
+
+ static OUString getControlName(sal_Int32 nFormatKey );
+
+ css::uno::Reference< css::awt::XControlModel > loadControlModel(const OUString& rName,
+ bool bForceListBox);
+
+ void CreateMappingDialog(weld::Window* pParent);
+ OUString CreateDBChangeDialog(weld::Window* pParent);
+
+ void DispatchDBChangeDialog();
+
+ void SetView( ::bib::BibView* pView ) { pBibView = pView; }
+
+ void SetToolbar(BibToolBar* pSet);
+
+ const OUString& GetIdentifierMapping();
+ void ResetIdentifierMapping() {sIdentifierMapping.clear();}
+
+ css::uno::Reference< css::form::runtime::XFormController > const & GetFormController();
+ void RegisterInterceptor( const ::bib::BibBeamer* pBibBeamer);
+
+ bool HasActiveConnection() const;
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/formcontrolcontainer.cxx b/extensions/source/bibliography/formcontrolcontainer.cxx
new file mode 100644
index 000000000..c6ec73700
--- /dev/null
+++ b/extensions/source/bibliography/formcontrolcontainer.cxx
@@ -0,0 +1,136 @@
+/* -*- 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 "formcontrolcontainer.hxx"
+#include <sal/log.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <algorithm>
+
+namespace bib
+{
+
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::form;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::awt;
+
+ FormControlContainer::FormControlContainer( )
+ :OLoadListener( m_aMutex )
+ {
+ }
+
+ FormControlContainer::~FormControlContainer( )
+ {
+ SAL_WARN_IF( isFormConnected(), "extensions.biblio", "FormControlContainer::~FormControlContainer: you should disconnect in your derived class!" );
+ if ( isFormConnected() )
+ disconnectForm();
+ }
+
+ void FormControlContainer::disconnectForm()
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ SAL_WARN_IF( !isFormConnected(), "extensions.biblio", "FormControlContainer::connectForm: not connected!" );
+ if ( isFormConnected() )
+ {
+ m_xFormAdapter->dispose();
+ m_xFormAdapter.clear();
+ }
+ }
+
+ void FormControlContainer::connectForm( const Reference< XLoadable >& _rxForm )
+ {
+ SAL_WARN_IF( isFormConnected(), "extensions.biblio", "FormControlContainer::connectForm: already connected!" );
+
+ SAL_WARN_IF( !_rxForm.is(), "extensions.biblio", "FormControlContainer::connectForm: invalid form!" );
+ if ( !isFormConnected() && _rxForm.is() )
+ {
+ m_xFormAdapter = new OLoadListenerAdapter( _rxForm );
+ m_xFormAdapter->Init( this );
+
+ implSetDesignMode( !m_xForm.is() || !m_xForm->isLoaded() );
+ }
+
+ m_xForm = _rxForm;
+ }
+
+ namespace {
+
+ struct ControlModeSwitch
+ {
+ bool bDesign;
+ explicit ControlModeSwitch( bool _bDesign ) : bDesign( _bDesign ) { }
+
+ void operator() ( const Reference< XControl >& _rxControl ) const
+ {
+ if ( _rxControl.is() )
+ _rxControl->setDesignMode( bDesign );
+ }
+ };
+
+ }
+
+ void FormControlContainer::implSetDesignMode( bool _bDesign )
+ {
+ try
+ {
+ Reference< XControlContainer > xControlCont = getControlContainer();
+ if ( xControlCont.is() )
+ {
+ const Sequence<Reference<XControl>> aControls = xControlCont->getControls();
+
+ std::for_each(
+ aControls.begin(),
+ aControls.end(),
+ ControlModeSwitch( _bDesign )
+ );
+ }
+ }
+ catch( const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "extensions.biblio", "FormControlContainer::implSetDesignMode" );
+ }
+ }
+
+ void FormControlContainer::_loaded( const css::lang::EventObject& /*_rEvent*/ )
+ {
+ implSetDesignMode( false );
+ }
+
+ void FormControlContainer::_unloading( const css::lang::EventObject& /*_rEvent*/ )
+ {
+ implSetDesignMode( true );
+ }
+
+ void FormControlContainer::_reloading( const css::lang::EventObject& /*_rEvent*/ )
+ {
+ implSetDesignMode( true );
+ }
+
+ void FormControlContainer::_reloaded( const css::lang::EventObject& /*_rEvent*/ )
+ {
+ implSetDesignMode( false );
+ }
+
+
+} // namespace bib
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/formcontrolcontainer.hxx b/extensions/source/bibliography/formcontrolcontainer.hxx
new file mode 100644
index 000000000..b15105ad0
--- /dev/null
+++ b/extensions/source/bibliography/formcontrolcontainer.hxx
@@ -0,0 +1,65 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <cppuhelper/basemutex.hxx>
+#include "loadlisteneradapter.hxx"
+#include <com/sun/star/awt/XControlContainer.hpp>
+#include <rtl/ref.hxx>
+
+
+namespace bib
+{
+
+ class FormControlContainer
+ :public ::cppu::BaseMutex
+ ,public ::bib::OLoadListener
+ {
+ private:
+ rtl::Reference<OLoadListenerAdapter> m_xFormAdapter;
+ css::uno::Reference< css::form::XLoadable > m_xForm;
+ private:
+ void implSetDesignMode( bool _bDesign );
+
+ protected:
+ FormControlContainer( );
+ virtual ~FormControlContainer( ) override;
+
+ bool isFormConnected() const { return m_xFormAdapter.is(); }
+ void connectForm( const css::uno::Reference< css::form::XLoadable >& _rxForm );
+ void disconnectForm();
+
+ virtual css::uno::Reference< css::awt::XControlContainer >
+ getControlContainer() = 0;
+
+ protected:
+ // XLoadListener equivalents
+ virtual void _loaded( const css::lang::EventObject& _rEvent ) override;
+ virtual void _unloading( const css::lang::EventObject& _rEvent ) override;
+ virtual void _reloading( const css::lang::EventObject& _rEvent ) override;
+ virtual void _reloaded( const css::lang::EventObject& _rEvent ) override;
+
+ };
+
+
+} // namespace bib
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/framectr.cxx b/extensions/source/bibliography/framectr.cxx
new file mode 100644
index 000000000..a273635d9
--- /dev/null
+++ b/extensions/source/bibliography/framectr.cxx
@@ -0,0 +1,869 @@
+/* -*- 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 <vcl/event.hxx>
+#include <vcl/svapp.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/awt/XTextComponent.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 <tools/diagnose_ex.h>
+#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( const uno::Reference< awt::XWindow > & xComponent,
+ BibDataManager* pDataManager)
+ :m_xWindow( 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 );
+
+ aObject.Source = static_cast<XController*>(this);
+ m_xImpl->aLC.disposeAndClear(aObject);
+ m_xDatMan.clear();
+ m_aStatusListeners.clear();
+ m_xLastQueriedFocusWin.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 == "slot:5503" || 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: */
diff --git a/extensions/source/bibliography/framectr.hxx b/extensions/source/bibliography/framectr.hxx
new file mode 100644
index 000000000..be91982cc
--- /dev/null
+++ b/extensions/source/bibliography/framectr.hxx
@@ -0,0 +1,117 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/frame/XDispatchInformationProvider.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <rtl/ref.hxx>
+#include <tools/link.hxx>
+#include <vcl/window.hxx>
+#include <vector>
+#include <memory>
+
+#include "bibmod.hxx"
+class BibDataManager;
+class BibFrameCtrl_Impl;
+namespace com::sun::star{
+ namespace form::runtime {
+ class XFormController;
+ }
+}
+class BibStatusDispatch
+{
+public:
+ css::util::URL aURL;
+ css::uno::Reference< css::frame::XStatusListener > xListener;
+ BibStatusDispatch( const css::util::URL& rURL, const css::uno::Reference< css::frame::XStatusListener >& rRef )
+ : aURL( rURL )
+ , xListener( rRef )
+ {}
+};
+
+typedef std::vector<std::unique_ptr<BibStatusDispatch> > BibStatusDispatchArr;
+
+class BibFrameController_Impl : public cppu::WeakImplHelper <
+ css::lang::XServiceInfo,
+ css::frame::XController,
+ css::frame::XDispatch,
+ css::frame::XDispatchProvider,
+ css::frame::XDispatchInformationProvider
+>
+{
+friend class BibFrameCtrl_Impl;
+ rtl::Reference<BibFrameCtrl_Impl> m_xImpl;
+ BibStatusDispatchArr m_aStatusListeners;
+ css::uno::Reference< css::awt::XWindow > m_xWindow;
+ css::uno::Reference< css::frame::XFrame > m_xFrame;
+ bool m_bDisposing;
+ rtl::Reference<BibDataManager> m_xDatMan;
+ VclPtr<vcl::Window> m_xLastQueriedFocusWin;
+
+ DECL_LINK( DisposeHdl, void*, void );
+
+ static bool SaveModified(const css::uno::Reference< css::form::runtime::XFormController>& xController);
+public:
+ BibFrameController_Impl( const css::uno::Reference< css::awt::XWindow > & xComponent,
+ BibDataManager* pDatMan);
+ virtual ~BibFrameController_Impl() override;
+
+
+ void ChangeDataSource(const css::uno::Sequence< css::beans::PropertyValue >& aArgs);
+ void RemoveFilter();
+
+ // css::lang::XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual sal_Bool SAL_CALL supportsService( const OUString& sServiceName ) override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
+
+ // css::frame::XController
+ virtual void SAL_CALL attachFrame( const css::uno::Reference< css::frame::XFrame > & xFrame ) override;
+ virtual sal_Bool SAL_CALL attachModel( const css::uno::Reference< css::frame::XModel > & xModel ) override;
+ virtual sal_Bool SAL_CALL suspend( sal_Bool bSuspend ) override;
+ virtual css::uno::Any SAL_CALL getViewData() override;
+ virtual void SAL_CALL restoreViewData( const css::uno::Any& Value ) override;
+ virtual css::uno::Reference< css::frame::XFrame > SAL_CALL getFrame() override;
+ virtual css::uno::Reference< css::frame::XModel > SAL_CALL getModel() override;
+
+ // css::lang::XComponent
+ virtual void SAL_CALL dispose() override;
+ virtual void SAL_CALL addEventListener( const css::uno::Reference< css::lang::XEventListener > & aListener ) override;
+ virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener > & aListener ) override;
+
+ // css::frame::XDispatchProvider
+ virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch( const css::util::URL& aURL, const OUString& aTargetFrameName, sal_Int32 nSearchFlags) override;
+ virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& aDescripts) override;
+
+ //class css::frame::XDispatch
+ virtual void SAL_CALL dispatch(const css::util::URL& aURL, const css::uno::Sequence< css::beans::PropertyValue >& aArgs) override;
+ virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener > & xControl, const css::util::URL& aURL) override;
+ virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener > & xControl, const css::util::URL& aURL) override;
+
+ // css::frame::XDispatchInformationProvider
+ virtual css::uno::Sequence< ::sal_Int16 > SAL_CALL getSupportedCommandGroups( ) override;
+ virtual css::uno::Sequence< css::frame::DispatchInformation > SAL_CALL getConfigurableDispatchInformation( ::sal_Int16 CommandGroup ) override;
+ };
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/general.cxx b/extensions/source/bibliography/general.cxx
new file mode 100644
index 000000000..ff3625d30
--- /dev/null
+++ b/extensions/source/bibliography/general.cxx
@@ -0,0 +1,876 @@
+/* -*- 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/processfactory.hxx>
+#include <com/sun/star/beans/XPropertyChangeListener.hpp>
+#include <com/sun/star/form/XBoundComponent.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/sdb/XColumn.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/uri/UriReferenceFactory.hpp>
+
+#include <o3tl/safeint.hxx>
+#include <o3tl/string_view.hxx>
+#include <sal/log.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <vcl/event.hxx>
+#include <vcl/mnemonic.hxx>
+#include "general.hxx"
+#include "bibresid.hxx"
+#include "datman.hxx"
+#include "bibconfig.hxx"
+#include <strings.hrc>
+#include "bibmod.hxx"
+#include <helpids.h>
+#include <algorithm>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/objsh.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::form;
+using namespace ::com::sun::star::sdb;
+
+namespace
+{
+/// Tries to split rText into rURL and nPageNumber.
+bool SplitUrlAndPage(const OUString& rText, OUString& rUrl, int& nPageNumber)
+{
+ uno::Reference<uri::XUriReferenceFactory> xUriReferenceFactory
+ = uri::UriReferenceFactory::create(comphelper::getProcessComponentContext());
+ uno::Reference<uri::XUriReference> xUriRef;
+ try
+ {
+ xUriRef = xUriReferenceFactory->parse(rText);
+ }
+ catch (const uno::Exception& rException)
+ {
+ SAL_WARN("extensions.biblio",
+ "SplitUrlAndPage: failed to parse url: " << rException.Message);
+ return false;
+ }
+
+ OUString aPagePrefix("page=");
+ if (!xUriRef->getFragment().startsWith(aPagePrefix))
+ {
+ return false;
+ }
+
+ nPageNumber = o3tl::toInt32(xUriRef->getFragment().subView(aPagePrefix.getLength()));
+ xUriRef->clearFragment();
+ rUrl = xUriRef->getUriReference();
+ return true;
+}
+
+/// Merges rUrl and rPageSB to a URL string.
+OUString MergeUrlAndPage(const OUString& rUrl, const weld::SpinButton& rPageSB)
+{
+ if (!rPageSB.get_sensitive())
+ {
+ return rUrl;
+ }
+
+ uno::Reference<uri::XUriReferenceFactory> xUriReferenceFactory
+ = uri::UriReferenceFactory::create(comphelper::getProcessComponentContext());
+ uno::Reference<uri::XUriReference> xUriRef;
+ try
+ {
+ xUriRef = xUriReferenceFactory->parse(rUrl);
+ }
+ catch (const uno::Exception& rException)
+ {
+ SAL_WARN("extensions.biblio",
+ "MergeUrlAndPage: failed to parse url: " << rException.Message);
+ return rUrl;
+ }
+
+ OUString aFragment("page=" + OUString::number(rPageSB.get_value()));
+ xUriRef->setFragment(aFragment);
+ return xUriRef->getUriReference();
+}
+}
+
+static OUString lcl_GetColumnName( const Mapping* pMapping, sal_uInt16 nIndexPos )
+{
+ BibConfig* pBibConfig = BibModul::GetConfig();
+ OUString sRet = pBibConfig->GetDefColumnName(nIndexPos);
+ if(pMapping)
+ for(const auto & aColumnPair : pMapping->aColumnPairs)
+ {
+ if(aColumnPair.sLogicalColumnName == sRet)
+ {
+ sRet = aColumnPair.sRealColumnName;
+ break;
+ }
+ }
+ return sRet;
+}
+
+BibGeneralPage::BibGeneralPage(vcl::Window* pParent, BibDataManager* pMan)
+ : InterimItemWindow(pParent, "modules/sbibliography/ui/generalpage.ui", "GeneralPage")
+ , BibShortCutHandler(this)
+ , xScrolledWindow(m_xBuilder->weld_scrolled_window("scrolledwindow"))
+ , xGrid(m_xBuilder->weld_widget("grid"))
+ , xIdentifierFT(m_xBuilder->weld_label("shortname"))
+ , xIdentifierED(m_xBuilder->weld_entry("shortnamecontrol"))
+ , xAuthTypeFT(m_xBuilder->weld_label("authtype"))
+ , xAuthTypeLB(m_xBuilder->weld_combo_box("authtypecontrol"))
+ , xYearFT(m_xBuilder->weld_label("year"))
+ , xYearED(m_xBuilder->weld_entry("yearcontrol"))
+ , xAuthorFT(m_xBuilder->weld_label("authors"))
+ , xAuthorED(m_xBuilder->weld_entry("authorscontrol"))
+ , xTitleFT(m_xBuilder->weld_label("title"))
+ , xTitleED(m_xBuilder->weld_entry("titlecontrol"))
+ , xPublisherFT(m_xBuilder->weld_label("publisher"))
+ , xPublisherED(m_xBuilder->weld_entry("publishercontrol"))
+ , xAddressFT(m_xBuilder->weld_label("address"))
+ , xAddressED(m_xBuilder->weld_entry("addresscontrol"))
+ , xISBNFT(m_xBuilder->weld_label("isbn"))
+ , xISBNED(m_xBuilder->weld_entry("isbncontrol"))
+ , xChapterFT(m_xBuilder->weld_label("chapter"))
+ , xChapterED(m_xBuilder->weld_entry("chaptercontrol"))
+ , xPagesFT(m_xBuilder->weld_label("pages"))
+ , xPagesED(m_xBuilder->weld_entry("pagescontrol"))
+ , xEditorFT(m_xBuilder->weld_label("editor"))
+ , xEditorED(m_xBuilder->weld_entry("editorcontrol"))
+ , xEditionFT(m_xBuilder->weld_label("edition"))
+ , xEditionED(m_xBuilder->weld_entry("editioncontrol"))
+ , xBooktitleFT(m_xBuilder->weld_label("booktitle"))
+ , xBooktitleED(m_xBuilder->weld_entry("booktitlecontrol"))
+ , xVolumeFT(m_xBuilder->weld_label("volume"))
+ , xVolumeED(m_xBuilder->weld_entry("volumecontrol"))
+ , xHowpublishedFT(m_xBuilder->weld_label("publicationtype"))
+ , xHowpublishedED(m_xBuilder->weld_entry("publicationtypecontrol"))
+ , xOrganizationsFT(m_xBuilder->weld_label("organization"))
+ , xOrganizationsED(m_xBuilder->weld_entry("organizationcontrol"))
+ , xInstitutionFT(m_xBuilder->weld_label("institution"))
+ , xInstitutionED(m_xBuilder->weld_entry("institutioncontrol"))
+ , xSchoolFT(m_xBuilder->weld_label("university"))
+ , xSchoolED(m_xBuilder->weld_entry("universitycontrol"))
+ , xReportTypeFT(m_xBuilder->weld_label("reporttype"))
+ , xReportTypeED(m_xBuilder->weld_entry("reporttypecontrol"))
+ , xMonthFT(m_xBuilder->weld_label("month"))
+ , xMonthED(m_xBuilder->weld_entry("monthcontrol"))
+ , xJournalFT(m_xBuilder->weld_label("journal"))
+ , xJournalED(m_xBuilder->weld_entry("journalcontrol"))
+ , xNumberFT(m_xBuilder->weld_label("number"))
+ , xNumberED(m_xBuilder->weld_entry("numbercontrol"))
+ , xSeriesFT(m_xBuilder->weld_label("series"))
+ , xSeriesED(m_xBuilder->weld_entry("seriescontrol"))
+ , xAnnoteFT(m_xBuilder->weld_label("annotation"))
+ , xAnnoteED(m_xBuilder->weld_entry("annotationcontrol"))
+ , xNoteFT(m_xBuilder->weld_label("note"))
+ , xNoteED(m_xBuilder->weld_entry("notecontrol"))
+ , xURLFT(m_xBuilder->weld_label("url"))
+ , xURLED(m_xBuilder->weld_entry("urlcontrol"))
+ , xCustom1FT(m_xBuilder->weld_label("custom1"))
+ , xCustom1ED(m_xBuilder->weld_entry("custom1control"))
+ , xCustom2FT(m_xBuilder->weld_label("custom2"))
+ , xCustom2ED(m_xBuilder->weld_entry("custom2control"))
+ , xCustom3FT(m_xBuilder->weld_label("custom3"))
+ , xCustom3ED(m_xBuilder->weld_entry("custom3control"))
+ , xCustom4FT(m_xBuilder->weld_label("custom4"))
+ , xCustom4ED(m_xBuilder->weld_entry("custom4control"))
+ , xCustom5FT(m_xBuilder->weld_label("custom5"))
+ , xCustom5ED(m_xBuilder->weld_entry("custom5control"))
+ , m_xLocalURLFT(m_xBuilder->weld_label("localurl"))
+ , m_xLocalURLED(m_xBuilder->weld_entry("localurlcontrol"))
+ , m_xLocalBrowseButton(m_xBuilder->weld_button("localbrowse"))
+ , m_xLocalPageCB(m_xBuilder->weld_check_button("localpagecb"))
+ , m_xLocalPageSB(m_xBuilder->weld_spin_button("localpagesb"))
+ , pDatMan(pMan)
+{
+ SetStyle(GetStyle() | WB_DIALOGCONTROL);
+
+ BibConfig* pBibConfig = BibModul::GetConfig();
+ BibDBDescriptor aDesc;
+ aDesc.sDataSource = pDatMan->getActiveDataSource();
+ aDesc.sTableOrQuery = pDatMan->getActiveDataTable();
+ aDesc.nCommandType = CommandType::TABLE;
+ const Mapping* pMapping = pBibConfig->GetMapping(aDesc);
+
+ xIdentifierED->connect_key_press(LINK(this, BibGeneralPage, FirstElementKeyInputHdl));
+
+ AddControlWithError(lcl_GetColumnName(pMapping, IDENTIFIER_POS),
+ xIdentifierFT->get_label(), *xIdentifierED,
+ sTableErrorString, HID_BIB_IDENTIFIER_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, AUTHORITYTYPE_POS),
+ xAuthTypeFT->get_label(), *xAuthTypeLB,
+ sTableErrorString, HID_BIB_AUTHORITYTYPE_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, YEAR_POS),
+ xYearFT->get_label(), *xYearED,
+ sTableErrorString, HID_BIB_YEAR_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, AUTHOR_POS),
+ xAuthorFT->get_label(), *xAuthorED,
+ sTableErrorString, HID_BIB_AUTHOR_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, TITLE_POS),
+ xTitleFT->get_label(), *xTitleED,
+ sTableErrorString, HID_BIB_TITLE_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, PUBLISHER_POS),
+ xPublisherFT->get_label(), *xPublisherED,
+ sTableErrorString, HID_BIB_PUBLISHER_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, ADDRESS_POS),
+ xAddressFT->get_label(), *xAddressED,
+ sTableErrorString, HID_BIB_ADDRESS_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, ISBN_POS),
+ xISBNFT->get_label(), *xISBNED,
+ sTableErrorString, HID_BIB_ISBN_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, CHAPTER_POS),
+ xChapterFT->get_label(), *xChapterED,
+ sTableErrorString, HID_BIB_CHAPTER_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, PAGES_POS),
+ xPagesFT->get_label(), *xPagesED,
+ sTableErrorString, HID_BIB_PAGES_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, EDITOR_POS),
+ xEditorFT->get_label(), *xEditorED,
+ sTableErrorString, HID_BIB_EDITOR_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, EDITION_POS),
+ xEditionFT->get_label(), *xEditionED,
+ sTableErrorString, HID_BIB_EDITION_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, BOOKTITLE_POS),
+ xBooktitleFT->get_label(), *xBooktitleED,
+ sTableErrorString, HID_BIB_BOOKTITLE_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, VOLUME_POS),
+ xVolumeFT->get_label(), *xVolumeED,
+ sTableErrorString, HID_BIB_VOLUME_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, HOWPUBLISHED_POS),
+ xHowpublishedFT->get_label(), *xHowpublishedED,
+ sTableErrorString, HID_BIB_HOWPUBLISHED_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, ORGANIZATIONS_POS),
+ xOrganizationsFT->get_label(), *xOrganizationsED,
+ sTableErrorString, HID_BIB_ORGANIZATIONS_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, INSTITUTION_POS),
+ xInstitutionFT->get_label(), *xInstitutionED,
+ sTableErrorString, HID_BIB_INSTITUTION_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, SCHOOL_POS),
+ xSchoolFT->get_label(), *xSchoolED,
+ sTableErrorString, HID_BIB_SCHOOL_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, REPORTTYPE_POS),
+ xReportTypeFT->get_label(), *xReportTypeED,
+ sTableErrorString, HID_BIB_REPORTTYPE_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, MONTH_POS),
+ xMonthFT->get_label(), *xMonthED,
+ sTableErrorString, HID_BIB_MONTH_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, JOURNAL_POS),
+ xJournalFT->get_label(), *xJournalED,
+ sTableErrorString, HID_BIB_JOURNAL_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, NUMBER_POS),
+ xNumberFT->get_label(), *xNumberED,
+ sTableErrorString, HID_BIB_NUMBER_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, SERIES_POS),
+ xSeriesFT->get_label(), *xSeriesED,
+ sTableErrorString, HID_BIB_SERIES_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, ANNOTE_POS),
+ xAnnoteFT->get_label(), *xAnnoteED,
+ sTableErrorString, HID_BIB_ANNOTE_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, NOTE_POS),
+ xNoteFT->get_label(), *xNoteED,
+ sTableErrorString, HID_BIB_NOTE_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, URL_POS),
+ xURLFT->get_label(), *xURLED,
+ sTableErrorString, HID_BIB_URL_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, CUSTOM1_POS),
+ xCustom1FT->get_label(), *xCustom1ED,
+ sTableErrorString, HID_BIB_CUSTOM1_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, CUSTOM2_POS),
+ xCustom2FT->get_label(), *xCustom2ED,
+ sTableErrorString, HID_BIB_CUSTOM2_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, CUSTOM3_POS),
+ xCustom3FT->get_label(), *xCustom3ED,
+ sTableErrorString, HID_BIB_CUSTOM3_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, CUSTOM4_POS),
+ xCustom4FT->get_label(), *xCustom4ED,
+ sTableErrorString, HID_BIB_CUSTOM4_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, CUSTOM5_POS),
+ xCustom5FT->get_label(), *xCustom5ED,
+ sTableErrorString, HID_BIB_CUSTOM5_POS);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, LOCAL_URL_POS),
+ m_xLocalURLFT->get_label(), *m_xLocalURLED,
+ sTableErrorString, HID_BIB_LOCAL_URL_POS);
+
+ m_xLocalBrowseButton->connect_clicked(LINK(this, BibGeneralPage, BrowseHdl));
+ m_xLocalPageCB->connect_toggled(LINK(this, BibGeneralPage, PageNumHdl));
+
+ m_xLocalURLED->connect_key_press(LINK(this, BibGeneralPage, LastElementKeyInputHdl));
+
+ if(!sTableErrorString.isEmpty())
+ sTableErrorString = BibResId(ST_ERROR_PREFIX) + sTableErrorString;
+
+ SetText(BibResId(ST_TYPE_TITLE));
+
+ Size aSize(LogicToPixel(Size(0, 209), MapMode(MapUnit::MapAppFont)));
+ set_height_request(aSize.Height());
+}
+
+IMPL_LINK_NOARG(BibGeneralPage, BrowseHdl, weld::Button&, void)
+{
+ sfx2::FileDialogHelper aFileDlg(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
+ FileDialogFlags::NONE, GetFrameWeld());
+ OUString aPath = m_xLocalURLED->get_text();
+ if (!aPath.isEmpty())
+ {
+ aFileDlg.SetDisplayDirectory(aPath);
+ }
+ else
+ {
+ OUString aBaseURL;
+ if (SfxObjectShell* pShell = SfxObjectShell::Current())
+ {
+ aBaseURL = pShell->getDocumentBaseURL();
+ }
+ if (!aBaseURL.isEmpty())
+ {
+ aFileDlg.SetDisplayDirectory(aBaseURL);
+ }
+ }
+
+ if (aFileDlg.Execute() != ERRCODE_NONE)
+ {
+ return;
+ }
+
+ weld::Entry& rEntry = *m_xLocalURLED;
+ rEntry.set_text(aFileDlg.GetPath());
+};
+
+IMPL_LINK(BibGeneralPage, PageNumHdl, weld::Toggleable&, rPageCB, void)
+{
+ weld::SpinButton& rPageSB = *m_xLocalPageSB;
+ if (rPageCB.get_active())
+ {
+ rPageSB.set_sensitive(true);
+ rPageSB.set_value(1);
+ }
+ else
+ {
+ rPageSB.set_sensitive(false);
+ }
+}
+
+IMPL_LINK(BibGeneralPage, FirstElementKeyInputHdl, const KeyEvent&, rKeyEvent, bool)
+{
+ sal_uInt16 nCode = rKeyEvent.GetKeyCode().GetCode();
+ bool bShift = rKeyEvent.GetKeyCode().IsShift();
+ bool bCtrl = rKeyEvent.GetKeyCode().IsMod1();
+ bool bAlt = rKeyEvent.GetKeyCode().IsMod2();
+ if (KEY_TAB == nCode && bShift && !bCtrl && !bAlt)
+ {
+ SaveChanges();
+ uno::Reference<sdbc::XRowSet> xRowSet(pDatMan->getForm(), UNO_QUERY);
+ if (xRowSet.is() && !xRowSet->isFirst())
+ xRowSet->previous();
+ m_xLocalURLED->grab_focus();
+ m_xLocalURLED->select_region(0, -1);
+ GainFocusHdl(*m_xLocalURLED);
+ return true;
+ }
+ return false;
+}
+
+void BibGeneralPage::SaveChanges()
+{
+ Reference< XForm > xForm = pDatMan->getForm();
+ Reference< beans::XPropertySet > xProps( xForm, UNO_QUERY );
+ Reference< sdbc::XResultSetUpdate > xResUpd( xProps, UNO_QUERY );
+ if (!xResUpd.is() )
+ return;
+
+ Any aModified = xProps->getPropertyValue( "IsModified" );
+ bool bFlag = false;
+ if ( !( aModified >>= bFlag ) || !bFlag )
+ return;
+
+ try
+ {
+ Any aNew = xProps->getPropertyValue( "IsNew" );
+ aNew >>= bFlag;
+ if ( bFlag )
+ xResUpd->insertRow();
+ else
+ xResUpd->updateRow();
+ }
+ catch( const uno::Exception&) {}
+}
+
+IMPL_LINK(BibGeneralPage, LastElementKeyInputHdl, const KeyEvent&, rKeyEvent, bool)
+{
+ sal_uInt16 nCode = rKeyEvent.GetKeyCode().GetCode();
+ bool bShift = rKeyEvent.GetKeyCode().IsShift();
+ bool bCtrl = rKeyEvent.GetKeyCode().IsMod1();
+ bool bAlt = rKeyEvent.GetKeyCode().IsMod2();
+ if (KEY_TAB != nCode || bShift || bCtrl || bAlt)
+ return false;
+ SaveChanges();
+ uno::Reference<sdbc::XRowSet> xRowSet(pDatMan->getForm(), UNO_QUERY);
+ if (xRowSet.is())
+ {
+ if (xRowSet->isLast())
+ {
+ uno::Reference<sdbc::XResultSetUpdate> xUpdateCursor(xRowSet, UNO_QUERY);
+ if (xUpdateCursor.is())
+ xUpdateCursor->moveToInsertRow();
+ }
+ else
+ (void)xRowSet->next();
+ }
+ xIdentifierED->grab_focus();
+ xIdentifierED->select_region(0, -1);
+ GainFocusHdl(*xIdentifierED);
+ return true;
+}
+
+BibGeneralPage::~BibGeneralPage()
+{
+ disposeOnce();
+}
+
+class ChangeListener : public cppu::WeakImplHelper<css::beans::XPropertyChangeListener>
+{
+public:
+ explicit ChangeListener(const css::uno::Reference<css::beans::XPropertySet>& rPropSet)
+ : m_xPropSet(rPropSet)
+ , m_bSelfChanging(false)
+ {
+ }
+
+ virtual void SAL_CALL disposing(lang::EventObject const &) override
+ {
+ }
+
+ virtual void start() = 0;
+ virtual void stop()
+ {
+ WriteBack();
+ }
+
+ virtual void WriteBack() = 0;
+
+protected:
+ css::uno::Reference<css::beans::XPropertySet> m_xPropSet;
+ bool m_bSelfChanging;
+};
+
+namespace
+{
+ class EntryChangeListener : public ChangeListener
+ {
+ public:
+ explicit EntryChangeListener(weld::Entry& rEntry, const css::uno::Reference<css::beans::XPropertySet>& rPropSet,
+ BibGeneralPage& rPage)
+ : ChangeListener(rPropSet)
+ , m_rEntry(rEntry)
+ , m_rPage(rPage)
+ {
+ rEntry.connect_focus_out(LINK(this, EntryChangeListener, LoseFocusHdl));
+ setValue(rPropSet->getPropertyValue("Text"));
+ }
+
+ virtual void SAL_CALL propertyChange(const css::beans::PropertyChangeEvent& evt) override
+ {
+ if (m_bSelfChanging)
+ return;
+ setValue(evt.NewValue);
+ }
+
+ virtual void start() override
+ {
+ m_xPropSet->addPropertyChangeListener("Text", this);
+ }
+
+ virtual void stop() override
+ {
+ m_xPropSet->removePropertyChangeListener("Text", this);
+ ChangeListener::stop();
+ }
+
+ private:
+ weld::Entry& m_rEntry;
+ BibGeneralPage& m_rPage;
+
+ DECL_LINK(LoseFocusHdl, weld::Widget&, void);
+
+ /// Updates the UI widget(s) based on rValue.
+ void setValue(const css::uno::Any& rValue)
+ {
+ OUString sNewName;
+ rValue >>= sNewName;
+ if (&m_rEntry == &m_rPage.GetLocalURLED())
+ {
+ OUString aUrl;
+ int nPageNumber;
+ if (SplitUrlAndPage(sNewName, aUrl, nPageNumber))
+ {
+ m_rEntry.set_text(aUrl);
+ m_rPage.GetLocalPageCB().set_active(true);
+ m_rPage.GetLocalPageSB().set_sensitive(true);
+ m_rPage.GetLocalPageSB().set_value(nPageNumber);
+ }
+ else
+ {
+ m_rEntry.set_text(sNewName);
+ m_rPage.GetLocalPageCB().set_active(false);
+ m_rPage.GetLocalPageSB().set_sensitive(false);
+ m_rPage.GetLocalPageSB().set_value(0);
+ }
+ }
+ else
+ {
+ m_rEntry.set_text(sNewName);
+ }
+
+ m_rEntry.save_value();
+ if (&m_rEntry == &m_rPage.GetLocalURLED())
+ {
+ m_rPage.GetLocalPageSB().save_value();
+ }
+ }
+
+ /// Updates m_xPropSet based on the UI widget(s).
+ virtual void WriteBack() override
+ {
+ bool bLocalURL = &m_rEntry == &m_rPage.GetLocalURLED()
+ && m_rPage.GetLocalPageSB().get_value_changed_from_saved();
+ if (!m_rEntry.get_value_changed_from_saved() && !bLocalURL)
+ return;
+
+ m_bSelfChanging = true;
+
+ OUString aText;
+ if (&m_rEntry == &m_rPage.GetLocalURLED())
+ {
+ aText = MergeUrlAndPage(m_rEntry.get_text(), m_rPage.GetLocalPageSB());
+ }
+ else
+ {
+ aText = m_rEntry.get_text();
+ }
+ m_xPropSet->setPropertyValue("Text", Any(aText));
+
+ css::uno::Reference<css::form::XBoundComponent> xBound(m_xPropSet, css::uno::UNO_QUERY);
+ if (xBound.is())
+ xBound->commit();
+
+ m_bSelfChanging = false;
+ m_rEntry.save_value();
+ if (&m_rEntry == &m_rPage.GetLocalURLED())
+ {
+ m_rPage.GetLocalPageSB().save_value();
+ }
+ }
+
+ };
+
+ IMPL_LINK_NOARG(EntryChangeListener, LoseFocusHdl, weld::Widget&, void)
+ {
+ WriteBack();
+ }
+
+ class ComboBoxChangeListener : public ChangeListener
+ {
+ public:
+ explicit ComboBoxChangeListener(weld::ComboBox& rComboBox, const css::uno::Reference<css::beans::XPropertySet>& rPropSet)
+ : ChangeListener(rPropSet)
+ , m_rComboBox(rComboBox)
+ {
+ rComboBox.connect_changed(LINK(this, ComboBoxChangeListener, ChangeHdl));
+ setValue(rPropSet->getPropertyValue("SelectedItems"));
+ }
+
+ virtual void SAL_CALL propertyChange(const css::beans::PropertyChangeEvent& evt) override
+ {
+ if (m_bSelfChanging)
+ return;
+ setValue(evt.NewValue);
+ }
+
+ virtual void start() override
+ {
+ m_xPropSet->addPropertyChangeListener("SelectedItems", this);
+ }
+
+ virtual void stop() override
+ {
+ m_xPropSet->removePropertyChangeListener("SelectedItems", this);
+ ChangeListener::stop();
+ }
+
+ private:
+ weld::ComboBox& m_rComboBox;
+
+ DECL_LINK(ChangeHdl, weld::ComboBox&, void);
+
+ void setValue(const css::uno::Any& rValue)
+ {
+ sal_Int16 nSelection = -1;
+ Sequence<sal_Int16> aSelection;
+ rValue >>= aSelection;
+ if (aSelection.hasElements())
+ nSelection = aSelection[0];
+
+ m_rComboBox.set_active(nSelection);
+ m_rComboBox.save_value();
+ }
+
+ virtual void WriteBack() override
+ {
+ if (!m_rComboBox.get_value_changed_from_saved())
+ return;
+ m_bSelfChanging = true;
+
+ Sequence<sal_Int16> aSelection{ o3tl::narrowing<sal_Int16>(m_rComboBox.get_active()) };
+ m_xPropSet->setPropertyValue("SelectedItems", Any(aSelection));
+
+ css::uno::Reference<css::form::XBoundComponent> xBound(m_xPropSet, css::uno::UNO_QUERY);
+ if (xBound.is())
+ xBound->commit();
+
+ m_bSelfChanging = false;
+ m_rComboBox.save_value();
+ }
+ };
+
+ IMPL_LINK_NOARG(ComboBoxChangeListener, ChangeHdl, weld::ComboBox&, void)
+ {
+ WriteBack();
+ }
+}
+
+void BibGeneralPage::dispose()
+{
+ for (auto& listener : maChangeListeners)
+ listener->stop();
+ maChangeListeners.clear();
+
+ SaveChanges();
+
+ xScrolledWindow.reset();
+ xGrid.reset();
+ xIdentifierFT.reset();
+ xIdentifierED.reset();
+ xAuthTypeFT.reset();
+ xAuthTypeLB.reset();
+ xYearFT.reset();
+ xYearED.reset();
+ xAuthorFT.reset();
+ xAuthorED.reset();
+ xTitleFT.reset();
+ xTitleED.reset();
+ xPublisherFT.reset();
+ xPublisherED.reset();
+ xAddressFT.reset();
+ xAddressED.reset();
+ xISBNFT.reset();
+ xISBNED.reset();
+ xChapterFT.reset();
+ xChapterED.reset();
+ xPagesFT.reset();
+ xPagesED.reset();
+ xEditorFT.reset();
+ xEditorED.reset();
+ xEditionFT.reset();
+ xEditionED.reset();
+ xBooktitleFT.reset();
+ xBooktitleED.reset();
+ xVolumeFT.reset();
+ xVolumeED.reset();
+ xHowpublishedFT.reset();
+ xHowpublishedED.reset();
+ xOrganizationsFT.reset();
+ xOrganizationsED.reset();
+ xInstitutionFT.reset();
+ xInstitutionED.reset();
+ xSchoolFT.reset();
+ xSchoolED.reset();
+ xReportTypeFT.reset();
+ xReportTypeED.reset();
+ xMonthFT.reset();
+ xMonthED.reset();
+ xJournalFT.reset();
+ xJournalED.reset();
+ xNumberFT.reset();
+ xNumberED.reset();
+ xSeriesFT.reset();
+ xSeriesED.reset();
+ xAnnoteFT.reset();
+ xAnnoteED.reset();
+ xNoteFT.reset();
+ xNoteED.reset();
+ xURLFT.reset();
+ xURLED.reset();
+ xCustom1FT.reset();
+ xCustom1ED.reset();
+ xCustom2FT.reset();
+ xCustom2ED.reset();
+ xCustom3FT.reset();
+ xCustom3ED.reset();
+ xCustom4FT.reset();
+ xCustom4ED.reset();
+ xCustom5FT.reset();
+ xCustom5ED.reset();
+ m_xLocalURLFT.reset();
+ m_xLocalURLED.reset();
+ m_xLocalBrowseButton.reset();
+ m_xLocalPageCB.reset();
+ m_xLocalPageSB.reset();
+ InterimItemWindow::dispose();
+}
+
+weld::Entry& BibGeneralPage::GetLocalURLED() { return *m_xLocalURLED; }
+
+weld::CheckButton& BibGeneralPage::GetLocalPageCB() { return *m_xLocalPageCB; }
+
+weld::SpinButton& BibGeneralPage::GetLocalPageSB() { return *m_xLocalPageSB; }
+
+bool BibGeneralPage::AddXControl(const OUString& rName, weld::Entry& rEntry)
+{
+ uno::Reference< awt::XControlModel > xCtrModel;
+ try
+ {
+ xCtrModel = pDatMan->loadControlModel(rName, false);
+ if ( xCtrModel.is() )
+ {
+ uno::Reference< beans::XPropertySet > xPropSet( xCtrModel, UNO_QUERY );
+
+ if( xPropSet.is())
+ {
+ maChangeListeners.emplace_back(new EntryChangeListener(rEntry, xPropSet, *this));
+ maChangeListeners.back()->start();
+ if (&rEntry == m_xLocalURLED.get())
+ {
+ m_aURLListener = maChangeListeners.back();
+ m_xLocalPageSB->connect_focus_out(LINK(this, BibGeneralPage, LosePageFocusHdl));
+ }
+ }
+ }
+ }
+ catch(const Exception&)
+ {
+ OSL_FAIL("BibGeneralPage::AddXControl: something went wrong!");
+ }
+ return xCtrModel.is();
+}
+
+IMPL_LINK_NOARG(BibGeneralPage, LosePageFocusHdl, weld::Widget&, void)
+{
+ m_aURLListener->WriteBack();
+}
+
+IMPL_LINK(BibGeneralPage, GainFocusHdl, weld::Widget&, rWidget, void)
+{
+ int x, y, width, height;
+ if (!rWidget.get_extents_relative_to(*xGrid, x, y, width, height))
+ return;
+
+ int bottom = y + height;
+ int nVScrollPos = xScrolledWindow->vadjustment_get_value();
+ if (y < nVScrollPos || bottom > nVScrollPos + xScrolledWindow->vadjustment_get_page_size())
+ xScrolledWindow->vadjustment_set_value(y);
+
+ int right = x + width;
+ int nHScrollPos = xScrolledWindow->hadjustment_get_value();
+ if (x < nHScrollPos || right > nHScrollPos + xScrolledWindow->hadjustment_get_page_size())
+ xScrolledWindow->hadjustment_set_value(x);
+}
+
+template<class Target> void BibGeneralPage::AddControlWithError(const OUString& rColumnName, const OUString& rColumnUIName,
+ Target& rWidget, OUString& rErrorString, const OString& rHelpId)
+{
+ rWidget.set_help_id(rHelpId);
+ rWidget.connect_focus_in(LINK(this, BibGeneralPage, GainFocusHdl));
+ bool bSuccess = AddXControl(rColumnName, rWidget);
+ if (!bSuccess)
+ {
+ if( !rErrorString.isEmpty() )
+ rErrorString += "\n";
+
+ rErrorString += MnemonicGenerator::EraseAllMnemonicChars(rColumnUIName);
+ }
+}
+
+bool BibGeneralPage::AddXControl(const OUString& rName, weld::ComboBox& rList)
+{
+ uno::Reference< awt::XControlModel > xCtrModel;
+ try
+ {
+ xCtrModel = pDatMan->loadControlModel(rName, true);
+ if ( xCtrModel.is() )
+ {
+ uno::Reference< beans::XPropertySet > xPropSet( xCtrModel, UNO_QUERY );
+
+ if( xPropSet.is())
+ {
+ css::uno::Sequence<OUString> aEntries;
+ xPropSet->getPropertyValue("StringItemList") >>= aEntries;
+ for (const OUString& rString : std::as_const(aEntries))
+ rList.append_text(rString);
+
+ sal_Int16 nSelection = -1;
+ Sequence<sal_Int16> aSelection;
+ xPropSet->getPropertyValue("SelectedItems") >>= aSelection;
+ if (aSelection.hasElements())
+ nSelection = aSelection[0];
+
+ rList.set_active(nSelection);
+ rList.save_value();
+
+ maChangeListeners.emplace_back(new ComboBoxChangeListener(rList, xPropSet));
+ maChangeListeners.back()->start();
+ }
+ }
+ }
+ catch(const Exception&)
+ {
+ OSL_FAIL("BibGeneralPage::AddXControl: something went wrong!");
+ }
+ return xCtrModel.is();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/general.hxx b/extensions/source/bibliography/general.hxx
new file mode 100644
index 000000000..b4d981955
--- /dev/null
+++ b/extensions/source/bibliography/general.hxx
@@ -0,0 +1,158 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <vcl/InterimItemWindow.hxx>
+#include "bibshortcuthandler.hxx"
+
+
+class BibDataManager;
+#define TYPE_COUNT 22
+#define FIELD_COUNT 31
+
+class ChangeListener;
+
+class BibGeneralPage : public InterimItemWindow
+ , public BibShortCutHandler
+{
+ std::unique_ptr<weld::ScrolledWindow> xScrolledWindow;
+ std::unique_ptr<weld::Widget> xGrid;
+
+ std::unique_ptr<weld::Label> xIdentifierFT;
+ std::unique_ptr<weld::Entry> xIdentifierED;
+
+ std::unique_ptr<weld::Label> xAuthTypeFT;
+ std::unique_ptr<weld::ComboBox> xAuthTypeLB;
+ std::unique_ptr<weld::Label> xYearFT;
+ std::unique_ptr<weld::Entry> xYearED;
+
+ std::unique_ptr<weld::Label> xAuthorFT;
+ std::unique_ptr<weld::Entry> xAuthorED;
+ std::unique_ptr<weld::Label> xTitleFT;
+ std::unique_ptr<weld::Entry> xTitleED;
+
+ std::unique_ptr<weld::Label> xPublisherFT;
+ std::unique_ptr<weld::Entry> xPublisherED;
+ std::unique_ptr<weld::Label> xAddressFT;
+ std::unique_ptr<weld::Entry> xAddressED;
+ std::unique_ptr<weld::Label> xISBNFT;
+ std::unique_ptr<weld::Entry> xISBNED;
+
+ std::unique_ptr<weld::Label> xChapterFT;
+ std::unique_ptr<weld::Entry> xChapterED;
+ std::unique_ptr<weld::Label> xPagesFT;
+ std::unique_ptr<weld::Entry> xPagesED;
+
+ std::unique_ptr<weld::Label> xEditorFT;
+ std::unique_ptr<weld::Entry> xEditorED;
+ std::unique_ptr<weld::Label> xEditionFT;
+ std::unique_ptr<weld::Entry> xEditionED;
+
+ std::unique_ptr<weld::Label> xBooktitleFT;
+ std::unique_ptr<weld::Entry> xBooktitleED;
+ std::unique_ptr<weld::Label> xVolumeFT;
+ std::unique_ptr<weld::Entry> xVolumeED;
+ std::unique_ptr<weld::Label> xHowpublishedFT;
+ std::unique_ptr<weld::Entry> xHowpublishedED;
+
+ std::unique_ptr<weld::Label> xOrganizationsFT;
+ std::unique_ptr<weld::Entry> xOrganizationsED;
+ std::unique_ptr<weld::Label> xInstitutionFT;
+ std::unique_ptr<weld::Entry> xInstitutionED;
+ std::unique_ptr<weld::Label> xSchoolFT;
+ std::unique_ptr<weld::Entry> xSchoolED;
+
+ std::unique_ptr<weld::Label> xReportTypeFT;
+ std::unique_ptr<weld::Entry> xReportTypeED;
+ std::unique_ptr<weld::Label> xMonthFT;
+ std::unique_ptr<weld::Entry> xMonthED;
+
+ std::unique_ptr<weld::Label> xJournalFT;
+ std::unique_ptr<weld::Entry> xJournalED;
+ std::unique_ptr<weld::Label> xNumberFT;
+ std::unique_ptr<weld::Entry> xNumberED;
+ std::unique_ptr<weld::Label> xSeriesFT;
+ std::unique_ptr<weld::Entry> xSeriesED;
+
+ std::unique_ptr<weld::Label> xAnnoteFT;
+ std::unique_ptr<weld::Entry> xAnnoteED;
+ std::unique_ptr<weld::Label> xNoteFT;
+ std::unique_ptr<weld::Entry> xNoteED;
+ std::unique_ptr<weld::Label> xURLFT;
+ std::unique_ptr<weld::Entry> xURLED;
+
+ std::unique_ptr<weld::Label> xCustom1FT;
+ std::unique_ptr<weld::Entry> xCustom1ED;
+ std::unique_ptr<weld::Label> xCustom2FT;
+ std::unique_ptr<weld::Entry> xCustom2ED;
+ std::unique_ptr<weld::Label> xCustom3FT;
+ std::unique_ptr<weld::Entry> xCustom3ED;
+ std::unique_ptr<weld::Label> xCustom4FT;
+ std::unique_ptr<weld::Entry> xCustom4ED;
+ std::unique_ptr<weld::Label> xCustom5FT;
+ std::unique_ptr<weld::Entry> xCustom5ED;
+ std::unique_ptr<weld::Label> m_xLocalURLFT;
+ std::unique_ptr<weld::Entry> m_xLocalURLED;
+ std::unique_ptr<weld::Button> m_xLocalBrowseButton;
+ std::unique_ptr<weld::CheckButton> m_xLocalPageCB;
+ std::unique_ptr<weld::SpinButton> m_xLocalPageSB;
+
+ OUString sTableErrorString;
+
+ std::vector<rtl::Reference<ChangeListener>> maChangeListeners;
+ rtl::Reference<ChangeListener> m_aURLListener;
+
+ BibDataManager* pDatMan;
+
+ bool AddXControl(const OUString& rName, weld::Entry& rEntry);
+ bool AddXControl(const OUString& rName, weld::ComboBox& rList);
+
+ template<class Target> void AddControlWithError(const OUString& rColumnName, const OUString& rColumnUIName,
+ Target& rWidget, OUString& rErrorString, const OString& rHelpId);
+
+ void SaveChanges();
+
+ DECL_LINK(GainFocusHdl, weld::Widget&, void);
+
+ DECL_LINK(FirstElementKeyInputHdl, const KeyEvent&, bool);
+ DECL_LINK(LastElementKeyInputHdl, const KeyEvent&, bool);
+ DECL_LINK(BrowseHdl, weld::Button&, void);
+ DECL_LINK(PageNumHdl, weld::Toggleable&, void);
+ DECL_LINK(LosePageFocusHdl, weld::Widget&, void);
+
+public:
+ BibGeneralPage(vcl::Window* pParent, BibDataManager* pDatMan);
+ virtual ~BibGeneralPage() override;
+ virtual void dispose() override;
+
+ const OUString& GetErrorString() const
+ {
+ return sTableErrorString;
+ }
+
+ weld::Entry& GetLocalURLED();
+ weld::CheckButton& GetLocalPageCB();
+ weld::SpinButton& GetLocalPageSB();
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/loadlisteneradapter.cxx b/extensions/source/bibliography/loadlisteneradapter.cxx
new file mode 100644
index 000000000..27f4ea2e5
--- /dev/null
+++ b/extensions/source/bibliography/loadlisteneradapter.cxx
@@ -0,0 +1,185 @@
+/* -*- 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 "loadlisteneradapter.hxx"
+#include <osl/diagnose.h>
+#include <rtl/ref.hxx>
+
+
+namespace bib
+{
+
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::form;
+
+ OComponentListener::~OComponentListener()
+ {
+ ::osl::MutexGuard aGuard( m_rMutex );
+ if ( m_xAdapter.is() )
+ m_xAdapter->dispose();
+ }
+
+
+ void OComponentListener::setAdapter( OComponentAdapterBase* pAdapter )
+ {
+ ::osl::MutexGuard aGuard( m_rMutex );
+ m_xAdapter = pAdapter;
+ }
+
+ OComponentAdapterBase::OComponentAdapterBase( const Reference< XComponent >& _rxComp )
+ :m_xComponent( _rxComp )
+ ,m_pListener( nullptr )
+ ,m_bListening( false )
+ {
+ OSL_ENSURE( m_xComponent.is(), "OComponentAdapterBase::OComponentAdapterBase: invalid component!" );
+ }
+
+
+ void OComponentAdapterBase::Init( OComponentListener* _pListener )
+ {
+ OSL_ENSURE( !m_pListener, "OComponentAdapterBase::Init: already initialized!" );
+ OSL_ENSURE( _pListener, "OComponentAdapterBase::Init: invalid listener!" );
+
+ m_pListener = _pListener;
+ if ( m_pListener )
+ m_pListener->setAdapter( this );
+
+ startComponentListening( );
+ m_bListening = true;
+ }
+
+
+ OComponentAdapterBase::~OComponentAdapterBase()
+ {
+ }
+
+
+ void OComponentAdapterBase::dispose()
+ {
+ if ( !m_bListening )
+ return;
+
+ ::rtl::Reference< OComponentAdapterBase > xPreventDelete(this);
+
+ disposing();
+
+ m_pListener->setAdapter(nullptr);
+
+ m_pListener = nullptr;
+ m_bListening = false;
+
+ m_xComponent = nullptr;
+ }
+
+ // XEventListener
+
+
+ void SAL_CALL OComponentAdapterBase::disposing( const EventObject& )
+ {
+ if (m_pListener)
+ {
+ // disconnect the listener
+ m_pListener->setAdapter( nullptr );
+ m_pListener = nullptr;
+ }
+
+ m_bListening = false;
+ m_xComponent = nullptr;
+ }
+
+ OLoadListenerAdapter::OLoadListenerAdapter( const Reference< XLoadable >& _rxLoadable )
+ :OComponentAdapterBase( Reference< XComponent >( _rxLoadable, UNO_QUERY ) )
+ {
+ }
+
+
+ void OLoadListenerAdapter::startComponentListening()
+ {
+ Reference< XLoadable > xLoadable( getComponent(), UNO_QUERY );
+ OSL_ENSURE( xLoadable.is(), "OLoadListenerAdapter::OLoadListenerAdapter: invalid object!" );
+ if ( xLoadable.is() )
+ xLoadable->addLoadListener( this );
+ }
+
+
+ void SAL_CALL OLoadListenerAdapter::acquire( ) noexcept
+ {
+ OLoadListenerAdapter_Base::acquire();
+ }
+
+
+ void SAL_CALL OLoadListenerAdapter::release( ) noexcept
+ {
+ OLoadListenerAdapter_Base::release();
+ }
+
+
+ void SAL_CALL OLoadListenerAdapter::disposing( const EventObject& _rSource )
+ {
+ OComponentAdapterBase::disposing( _rSource );
+ }
+
+
+ void OLoadListenerAdapter::disposing()
+ {
+ Reference< XLoadable > xLoadable( getComponent(), UNO_QUERY );
+ if ( xLoadable.is() )
+ xLoadable->removeLoadListener( this );
+ }
+
+
+ void SAL_CALL OLoadListenerAdapter::loaded( const EventObject& _rEvent )
+ {
+ if ( getLoadListener( ) )
+ getLoadListener( )->_loaded( _rEvent );
+ }
+
+
+ void SAL_CALL OLoadListenerAdapter::unloading( const EventObject& _rEvent )
+ {
+ if ( getLoadListener( ) )
+ getLoadListener( )->_unloading( _rEvent );
+ }
+
+
+ void SAL_CALL OLoadListenerAdapter::unloaded( const EventObject& )
+ {
+ }
+
+
+ void SAL_CALL OLoadListenerAdapter::reloading( const EventObject& _rEvent )
+ {
+ if ( getLoadListener( ) )
+ getLoadListener( )->_reloading( _rEvent );
+ }
+
+
+ void SAL_CALL OLoadListenerAdapter::reloaded( const EventObject& _rEvent )
+ {
+ if ( getLoadListener( ) )
+ getLoadListener( )->_reloaded( _rEvent );
+ }
+
+
+} // namespace bib
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/loadlisteneradapter.hxx b/extensions/source/bibliography/loadlisteneradapter.hxx
new file mode 100644
index 000000000..1031dedca
--- /dev/null
+++ b/extensions/source/bibliography/loadlisteneradapter.hxx
@@ -0,0 +1,151 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <osl/mutex.hxx>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <com/sun/star/form/XLoadable.hpp>
+#include <rtl/ref.hxx>
+
+
+namespace bib
+{
+
+
+ class OComponentAdapterBase;
+
+ class OComponentListener
+ {
+ friend class OComponentAdapterBase;
+
+ private:
+ rtl::Reference<OComponentAdapterBase> m_xAdapter;
+ ::osl::Mutex& m_rMutex;
+ protected:
+ explicit OComponentListener( ::osl::Mutex& _rMutex )
+ :m_rMutex( _rMutex )
+ {
+ }
+
+ virtual ~OComponentListener();
+
+ protected:
+ void setAdapter( OComponentAdapterBase* _pAdapter );
+ };
+
+ class OComponentAdapterBase
+ {
+ friend class OComponentListener;
+
+ private:
+ css::uno::Reference< css::lang::XComponent > m_xComponent;
+ OComponentListener* m_pListener;
+ bool m_bListening : 1;
+
+ // impl method for dispose - virtual, 'cause you at least need to remove the listener from the broadcaster
+ virtual void disposing() = 0;
+
+ protected:
+ // attribute access for derivees
+ const css::uno::Reference< css::lang::XComponent >&
+ getComponent() const { return m_xComponent; }
+ OComponentListener* getListener() { return m_pListener; }
+
+ // to be called by derivees which started listening at the component
+ virtual void startComponentListening() = 0;
+
+ virtual ~OComponentAdapterBase();
+
+ public:
+ explicit OComponentAdapterBase(
+ const css::uno::Reference< css::lang::XComponent >& _rxComp
+ );
+
+ // late construction
+ // can be called from within you ctor, to have you're object fully initialized at the moment of
+ // the call (which would not be the case when calling this ctor)
+ void Init( OComponentListener* _pListener );
+
+ // base for ref-counting, implemented by OComponentAdapter
+ virtual void SAL_CALL acquire( ) noexcept = 0;
+ virtual void SAL_CALL release( ) noexcept = 0;
+
+ /// dispose the object - stop listening and such
+ void dispose();
+
+ protected:
+ // XEventListener
+ /// @throws css::uno::RuntimeException
+ virtual void SAL_CALL disposing( const css::lang::EventObject& Source );
+ };
+
+ class OLoadListener : public OComponentListener
+ {
+ friend class OLoadListenerAdapter;
+
+ protected:
+ explicit OLoadListener( ::osl::Mutex& _rMutex ) : OComponentListener( _rMutex ) { }
+
+ // XLoadListener equivalents
+ virtual void _loaded( const css::lang::EventObject& aEvent ) = 0;
+ virtual void _unloading( const css::lang::EventObject& aEvent ) = 0;
+ virtual void _reloading( const css::lang::EventObject& aEvent ) = 0;
+ virtual void _reloaded( const css::lang::EventObject& aEvent ) = 0;
+ };
+
+ typedef ::cppu::WeakImplHelper< css::form::XLoadListener > OLoadListenerAdapter_Base;
+ class OLoadListenerAdapter
+ :public OLoadListenerAdapter_Base
+ ,public OComponentAdapterBase
+ {
+ protected:
+ OLoadListener* getLoadListener( ) { return static_cast< OLoadListener* >( getListener() ); }
+
+ protected:
+ virtual void disposing() override;
+ virtual void startComponentListening() override;
+
+ public:
+ explicit OLoadListenerAdapter(
+ const css::uno::Reference< css::form::XLoadable >& _rxLoadable
+ );
+
+
+ virtual void SAL_CALL acquire( ) noexcept override;
+ virtual void SAL_CALL release( ) noexcept override;
+
+ protected:
+ // XEventListener
+ virtual void SAL_CALL disposing( const css::lang::EventObject& _rSource ) override;
+
+ // XLoadListener
+ virtual void SAL_CALL loaded( const css::lang::EventObject& aEvent ) override;
+ virtual void SAL_CALL unloading( const css::lang::EventObject& aEvent ) override;
+ virtual void SAL_CALL unloaded( const css::lang::EventObject& aEvent ) override;
+ virtual void SAL_CALL reloading( const css::lang::EventObject& aEvent ) override;
+ virtual void SAL_CALL reloaded( const css::lang::EventObject& aEvent ) override;
+ };
+
+
+} // namespace bib
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/toolbar.cxx b/extensions/source/bibliography/toolbar.cxx
new file mode 100644
index 000000000..fd74a04e6
--- /dev/null
+++ b/extensions/source/bibliography/toolbar.cxx
@@ -0,0 +1,620 @@
+/* -*- 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 <sal/config.h>
+
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/util/URLTransformer.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include "datman.hxx"
+#include "toolbar.hxx"
+#include <o3tl/any.hxx>
+#include <svtools/miscopt.hxx>
+#include <svtools/imgdef.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/mnemonic.hxx>
+#include <vcl/event.hxx>
+#include <vcl/weldutils.hxx>
+#include <bitmaps.hlst>
+
+#include "bibtools.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+
+
+// Constants --------------------------------------------------------------
+
+
+BibToolBarListener::BibToolBarListener(BibToolBar *pTB, const OUString& aStr, ToolBoxItemId nId):
+ nIndex(nId),
+ aCommand(aStr),
+ pToolBar(pTB)
+{
+}
+
+BibToolBarListener::~BibToolBarListener()
+{
+}
+
+void BibToolBarListener::statusChanged(const css::frame::FeatureStateEvent& rEvt)
+{
+ if(rEvt.FeatureURL.Complete == aCommand)
+ {
+ SolarMutexGuard aGuard;
+ pToolBar->EnableItem(nIndex,rEvt.IsEnabled);
+
+ css::uno::Any aState=rEvt.State;
+ if(auto bChecked = o3tl::tryAccess<bool>(aState))
+ {
+ pToolBar->CheckItem(nIndex, *bChecked);
+ }
+
+ }
+};
+
+
+BibTBListBoxListener::BibTBListBoxListener(BibToolBar *pTB, const OUString& aStr, ToolBoxItemId nId):
+ BibToolBarListener(pTB,aStr,nId)
+{
+}
+
+BibTBListBoxListener::~BibTBListBoxListener()
+{
+}
+
+void BibTBListBoxListener::statusChanged(const css::frame::FeatureStateEvent& rEvt)
+{
+ if(rEvt.FeatureURL.Complete != GetCommand())
+ return;
+
+ SolarMutexGuard aGuard;
+ pToolBar->EnableSourceList(rEvt.IsEnabled);
+
+ Any aState = rEvt.State;
+ if(auto pStringSeq = o3tl::tryAccess<Sequence<OUString>>(aState))
+ {
+ pToolBar->UpdateSourceList(false);
+ pToolBar->ClearSourceList();
+
+ const OUString* pStringArray = pStringSeq->getConstArray();
+
+ sal_uInt32 nCount = pStringSeq->getLength();
+ OUString aEntry;
+ for( sal_uInt32 i=0; i<nCount; i++ )
+ {
+ aEntry = pStringArray[i];
+ pToolBar->InsertSourceEntry(aEntry);
+ }
+ pToolBar->UpdateSourceList(true);
+ }
+
+ pToolBar->SelectSourceEntry(rEvt.FeatureDescriptor);
+};
+
+BibTBQueryMenuListener::BibTBQueryMenuListener(BibToolBar *pTB, const OUString& aStr, ToolBoxItemId nId):
+ BibToolBarListener(pTB,aStr,nId)
+{
+}
+
+BibTBQueryMenuListener::~BibTBQueryMenuListener()
+{
+}
+
+void BibTBQueryMenuListener::statusChanged(const frame::FeatureStateEvent& rEvt)
+{
+ if(rEvt.FeatureURL.Complete != GetCommand())
+ return;
+
+ SolarMutexGuard aGuard;
+ pToolBar->EnableSourceList(rEvt.IsEnabled);
+
+ uno::Any aState=rEvt.State;
+ auto pStringSeq = o3tl::tryAccess<Sequence<OUString>>(aState);
+ if(!pStringSeq)
+ return;
+
+ pToolBar->ClearFilterMenu();
+
+ const OUString* pStringArray = pStringSeq->getConstArray();
+
+ sal_uInt32 nCount = pStringSeq->getLength();
+ for( sal_uInt32 i=0; i<nCount; i++ )
+ {
+ sal_uInt16 nID = pToolBar->InsertFilterItem(pStringArray[i]);
+ if(pStringArray[i]==rEvt.FeatureDescriptor)
+ {
+ pToolBar->SelectFilterItem(nID);
+ }
+ }
+};
+
+BibTBEditListener::BibTBEditListener(BibToolBar *pTB, const OUString& aStr, ToolBoxItemId nId):
+ BibToolBarListener(pTB,aStr,nId)
+{
+}
+
+BibTBEditListener::~BibTBEditListener()
+{
+}
+
+void BibTBEditListener::statusChanged(const frame::FeatureStateEvent& rEvt)
+{
+ if(rEvt.FeatureURL.Complete == GetCommand())
+ {
+ SolarMutexGuard aGuard;
+ pToolBar->EnableQuery(rEvt.IsEnabled);
+
+ uno::Any aState=rEvt.State;
+ if(auto aStr = o3tl::tryAccess<OUString>(aState))
+ {
+ pToolBar->SetQueryString(*aStr);
+ }
+ }
+}
+
+ComboBoxControl::ComboBoxControl(vcl::Window* pParent)
+ : InterimItemWindow(pParent, "modules/sbibliography/ui/combobox.ui", "ComboBox")
+ , m_xFtSource(m_xBuilder->weld_label("label"))
+ , m_xLBSource(m_xBuilder->weld_combo_box("combobox"))
+{
+ m_xFtSource->set_toolbar_background();
+ m_xLBSource->set_toolbar_background();
+ m_xLBSource->set_size_request(100, -1);
+ SetSizePixel(get_preferred_size());
+}
+
+void ComboBoxControl::dispose()
+{
+ m_xLBSource.reset();
+ m_xFtSource.reset();
+ InterimItemWindow::dispose();
+}
+
+ComboBoxControl::~ComboBoxControl()
+{
+ disposeOnce();
+}
+
+EditControl::EditControl(vcl::Window* pParent)
+ : InterimItemWindow(pParent, "modules/sbibliography/ui/editbox.ui", "EditBox")
+ , m_xFtQuery(m_xBuilder->weld_label("label"))
+ , m_xEdQuery(m_xBuilder->weld_entry("entry"))
+{
+ m_xFtQuery->set_toolbar_background();
+ m_xEdQuery->set_toolbar_background();
+ m_xEdQuery->set_size_request(100, -1);
+ SetSizePixel(get_preferred_size());
+}
+
+void EditControl::dispose()
+{
+ m_xEdQuery.reset();
+ m_xFtQuery.reset();
+ InterimItemWindow::dispose();
+}
+
+EditControl::~EditControl()
+{
+ disposeOnce();
+}
+
+BibToolBar::BibToolBar(vcl::Window* pParent, Link<void*,void> aLink)
+ : ToolBox(pParent, "toolbar", "modules/sbibliography/ui/toolbar.ui")
+ , aIdle("BibToolBar")
+ , xSource(VclPtr<ComboBoxControl>::Create(this))
+ , pLbSource(xSource->get_widget())
+ , xQuery(VclPtr<EditControl>::Create(this))
+ , pEdQuery(xQuery->get_widget())
+ , xBuilder(Application::CreateBuilder(nullptr, "modules/sbibliography/ui/autofiltermenu.ui"))
+ , xPopupMenu(xBuilder->weld_menu("menu"))
+ , nMenuId(0)
+ , aLayoutManager(aLink)
+ , nSymbolsSize(SFX_SYMBOLS_SIZE_SMALL)
+{
+ SvtMiscOptions aSvtMiscOptions;
+ nSymbolsSize = aSvtMiscOptions.GetCurrentSymbolsSize();
+
+ xSource->Show();
+ pLbSource->connect_changed(LINK( this, BibToolBar, SelHdl));
+
+ SvtMiscOptions().AddListenerLink( LINK( this, BibToolBar, OptionsChanged_Impl ) );
+ Application::AddEventListener( LINK( this, BibToolBar, SettingsChanged_Impl ) );
+
+ aIdle.SetInvokeHandler(LINK( this, BibToolBar, SendSelHdl));
+ aIdle.SetPriority(TaskPriority::LOWEST);
+
+ SetDropdownClickHdl( LINK( this, BibToolBar, MenuHdl));
+
+ xQuery->Show();
+
+ nTBC_SOURCE = GetItemId(".uno:Bib/source");
+ nTBC_QUERY = GetItemId(".uno:Bib/query");
+ nTBC_BT_AUTOFILTER = GetItemId(".uno:Bib/autoFilter");
+ nTBC_BT_COL_ASSIGN = GetItemId("TBC_BT_COL_ASSIGN");
+ nTBC_BT_CHANGESOURCE = GetItemId(".uno:Bib/sdbsource");
+ nTBC_BT_FILTERCRIT = GetItemId(".uno:Bib/standardFilter");
+ nTBC_BT_REMOVEFILTER = GetItemId(".uno:Bib/removeFilter");
+
+ SetItemWindow(nTBC_SOURCE, xSource.get());
+ SetItemWindow(nTBC_QUERY , xQuery.get());
+
+ ApplyImageList();
+
+ ::bib::AddToTaskPaneList( this );
+}
+
+BibToolBar::~BibToolBar()
+{
+ disposeOnce();
+}
+
+void BibToolBar::dispose()
+{
+ SvtMiscOptions().RemoveListenerLink( LINK( this, BibToolBar, OptionsChanged_Impl ) );
+ Application::RemoveEventListener( LINK( this, BibToolBar, SettingsChanged_Impl ) );
+ ::bib::RemoveFromTaskPaneList( this );
+ pEdQuery = nullptr;
+ xQuery.disposeAndClear();
+ pLbSource = nullptr;
+ xSource.disposeAndClear();
+ xPopupMenu.reset();
+ xBuilder.reset();
+ ToolBox::dispose();
+}
+
+void BibToolBar::InitListener()
+{
+ ToolBox::ImplToolItems::size_type nCount=GetItemCount();
+
+ uno::Reference< frame::XDispatch > xDisp(xController,UNO_QUERY);
+ uno::Reference< util::XURLTransformer > xTrans( util::URLTransformer::create(comphelper::getProcessComponentContext()) );
+ if( !xTrans.is() )
+ return;
+
+ util::URL aQueryURL;
+ aQueryURL.Complete = ".uno:Bib/MenuFilter";
+ xTrans->parseStrict( aQueryURL);
+ rtl::Reference<BibToolBarListener> pQuery=new BibTBQueryMenuListener(this, aQueryURL.Complete, nTBC_BT_AUTOFILTER);
+ xDisp->addStatusListener(pQuery, aQueryURL);
+
+ for(ToolBox::ImplToolItems::size_type nPos=0;nPos<nCount;nPos++)
+ {
+ ToolBoxItemId nId=GetItemId(nPos);
+ if (!nId)
+ continue;
+
+ util::URL aURL;
+ aURL.Complete = GetItemCommand(nId);
+ if(aURL.Complete.isEmpty())
+ continue;
+
+ xTrans->parseStrict( aURL );
+
+ css::uno::Reference< css::frame::XStatusListener> xListener;
+ if (nId == nTBC_SOURCE)
+ {
+ xListener=new BibTBListBoxListener(this,aURL.Complete,nId);
+ }
+ else if (nId == nTBC_QUERY)
+ {
+ xListener=new BibTBEditListener(this,aURL.Complete,nId);
+ }
+ else
+ {
+ xListener=new BibToolBarListener(this,aURL.Complete,nId);
+ }
+
+ aListenerArr.push_back( xListener );
+ xDisp->addStatusListener(xListener,aURL);
+ }
+}
+
+void BibToolBar::SetXController(const uno::Reference< frame::XController > & xCtr)
+{
+ xController=xCtr;
+ InitListener();
+
+}
+
+void BibToolBar::Select()
+{
+ ToolBoxItemId nId=GetCurItemId();
+
+ if (nId != nTBC_BT_AUTOFILTER)
+ {
+ SendDispatch(nId,Sequence<PropertyValue>() );
+ }
+ else
+ {
+ Sequence<PropertyValue> aPropVal
+ {
+ comphelper::makePropertyValue("QueryText", pEdQuery->get_text()),
+ comphelper::makePropertyValue("QueryField", aQueryField)
+ };
+ SendDispatch(nId,aPropVal);
+ }
+}
+
+void BibToolBar::SendDispatch(ToolBoxItemId nId, const Sequence< PropertyValue >& rArgs)
+{
+ OUString aCommand = GetItemCommand(nId);
+
+ uno::Reference< frame::XDispatchProvider > xDSP( xController, UNO_QUERY );
+
+ if( !xDSP.is() || aCommand.isEmpty() )
+ return;
+
+ uno::Reference< util::XURLTransformer > xTrans( util::URLTransformer::create(comphelper::getProcessComponentContext()) );
+ if( !xTrans.is() )
+ return;
+
+ // load the file
+ util::URL aURL;
+ aURL.Complete = aCommand;
+
+ xTrans->parseStrict( aURL );
+
+ uno::Reference< frame::XDispatch > xDisp = xDSP->queryDispatch( aURL, OUString(), frame::FrameSearchFlag::SELF );
+
+ if ( xDisp.is() )
+ xDisp->dispatch( aURL, rArgs);
+
+}
+
+void BibToolBar::Click()
+{
+ ToolBoxItemId nId = GetCurItemId();
+
+ vcl::Window* pWin = GetParent();
+
+ if (nId == nTBC_BT_COL_ASSIGN )
+ {
+ if (pDatMan)
+ pDatMan->CreateMappingDialog(pWin ? pWin->GetFrameWeld() : nullptr);
+ CheckItem( nId, false );
+ }
+ else if (nId == nTBC_BT_CHANGESOURCE)
+ {
+ if (pDatMan)
+ {
+ OUString sNew = pDatMan->CreateDBChangeDialog(pWin ? pWin->GetFrameWeld() : nullptr);
+ if (!sNew.isEmpty())
+ pDatMan->setActiveDataSource(sNew);
+ }
+ CheckItem( nId, false );
+ }
+}
+
+void BibToolBar::ClearFilterMenu()
+{
+ xPopupMenu->clear();
+ nMenuId=0;
+}
+
+sal_uInt16 BibToolBar::InsertFilterItem(const OUString& rMenuEntry)
+{
+ nMenuId++;
+ xPopupMenu->append_check(OUString::number(nMenuId), rMenuEntry);
+ return nMenuId;
+}
+
+void BibToolBar::SelectFilterItem(sal_uInt16 nId)
+{
+ OString sId = OString::number(nId);
+ xPopupMenu->set_active(sId, true);
+ sSelMenuItem = sId;
+ aQueryField = MnemonicGenerator::EraseAllMnemonicChars(xPopupMenu->get_label(sId));
+}
+
+void BibToolBar::EnableSourceList(bool bFlag)
+{
+ xSource->set_sensitive(bFlag);
+}
+
+void BibToolBar::ClearSourceList()
+{
+ pLbSource->clear();
+}
+
+void BibToolBar::UpdateSourceList(bool bFlag)
+{
+ if (bFlag)
+ pLbSource->thaw();
+ else
+ pLbSource->freeze();
+}
+
+void BibToolBar::InsertSourceEntry(const OUString& aEntry)
+{
+ pLbSource->append_text(aEntry);
+}
+
+void BibToolBar::SelectSourceEntry(const OUString& aStr)
+{
+ pLbSource->set_active_text(aStr);
+}
+
+void BibToolBar::EnableQuery(bool bFlag)
+{
+ xQuery->set_sensitive(bFlag);
+}
+
+void BibToolBar::SetQueryString(const OUString& aStr)
+{
+ pEdQuery->set_text(aStr);
+}
+
+bool BibToolBar::PreNotify( NotifyEvent& rNEvt )
+{
+ bool bResult = true;
+
+ MouseNotifyEvent nSwitch=rNEvt.GetType();
+ if (pEdQuery && pEdQuery->has_focus() && nSwitch == MouseNotifyEvent::KEYINPUT)
+ {
+ const vcl::KeyCode& aKeyCode=rNEvt.GetKeyEvent()->GetKeyCode();
+ sal_uInt16 nKey = aKeyCode.GetCode();
+ if(nKey == KEY_RETURN)
+ {
+ Sequence<PropertyValue> aPropVal
+ {
+ comphelper::makePropertyValue("QueryText", pEdQuery->get_text()),
+ comphelper::makePropertyValue("QueryField", aQueryField)
+ };
+ SendDispatch(nTBC_BT_AUTOFILTER, aPropVal);
+ return bResult;
+ }
+
+ }
+
+ bResult=ToolBox::PreNotify(rNEvt);
+
+ return bResult;
+}
+
+IMPL_LINK_NOARG( BibToolBar, SelHdl, weld::ComboBox&, void )
+{
+ aIdle.Start();
+}
+
+IMPL_LINK_NOARG( BibToolBar, SendSelHdl, Timer*, void )
+{
+ Sequence<PropertyValue> aPropVal
+ {
+ comphelper::makePropertyValue("DataSourceName", MnemonicGenerator::EraseAllMnemonicChars( pLbSource->get_active_text() ))
+ };
+ SendDispatch(nTBC_SOURCE, aPropVal);
+}
+
+IMPL_LINK_NOARG(BibToolBar, MenuHdl, ToolBox*, void)
+{
+ ToolBoxItemId nId = GetCurItemId();
+ if (nId != nTBC_BT_AUTOFILTER)
+ return;
+
+ EndSelection(); // before SetDropMode (SetDropMode calls SetItemImage)
+
+ SetItemDown(nTBC_BT_AUTOFILTER, true);
+
+ tools::Rectangle aRect(GetItemRect(nTBC_BT_AUTOFILTER));
+ weld::Window* pParent = weld::GetPopupParent(*this, aRect);
+ OString sId = xPopupMenu->popup_at_rect(pParent, aRect);
+
+ if (!sId.isEmpty())
+ {
+ xPopupMenu->set_active(sSelMenuItem, false);
+ xPopupMenu->set_active(sId, true);
+ sSelMenuItem = sId;
+ aQueryField = MnemonicGenerator::EraseAllMnemonicChars(xPopupMenu->get_label(sId));
+ Sequence<PropertyValue> aPropVal
+ {
+ comphelper::makePropertyValue("QueryText", pEdQuery->get_text()),
+ comphelper::makePropertyValue("QueryField", aQueryField)
+ };
+ SendDispatch(nTBC_BT_AUTOFILTER, aPropVal);
+ }
+
+ MouseEvent aLeave( Point(), 0, MouseEventModifiers::LEAVEWINDOW | MouseEventModifiers::SYNTHETIC );
+ MouseMove( aLeave );
+ SetItemDown(nTBC_BT_AUTOFILTER, false);
+}
+
+void BibToolBar::statusChanged(const frame::FeatureStateEvent& rEvent)
+{
+ for(uno::Reference<frame::XStatusListener> & rListener : aListenerArr)
+ {
+ rListener->statusChanged(rEvent);
+ }
+}
+
+void BibToolBar::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
+ (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
+ ApplyImageList();
+ ToolBox::DataChanged( rDCEvt );
+}
+
+IMPL_LINK_NOARG( BibToolBar, OptionsChanged_Impl, LinkParamNone*, void )
+{
+ bool bRebuildToolBar = false;
+ sal_Int16 eSymbolsSize = SvtMiscOptions().GetCurrentSymbolsSize();
+ if ( nSymbolsSize != eSymbolsSize )
+ {
+ nSymbolsSize = eSymbolsSize;
+ bRebuildToolBar = true;
+ }
+
+ if ( bRebuildToolBar )
+ RebuildToolbar();
+}
+
+IMPL_LINK_NOARG( BibToolBar, SettingsChanged_Impl, VclSimpleEvent&, void )
+{
+ // Check if toolbar button size have changed and we have to use system settings
+ sal_Int16 eSymbolsSize = SvtMiscOptions().GetCurrentSymbolsSize();
+ if ( eSymbolsSize != nSymbolsSize )
+ {
+ nSymbolsSize = eSymbolsSize;
+ RebuildToolbar();
+ }
+}
+
+void BibToolBar::RebuildToolbar()
+{
+ ApplyImageList();
+ // We have to call parent asynchronously as SetSize works also asynchronously!
+ Application::PostUserEvent( aLayoutManager );
+}
+
+void BibToolBar::ApplyImageList()
+{
+ SetItemImage(nTBC_BT_AUTOFILTER, Image(StockImage::Yes, nSymbolsSize == SFX_SYMBOLS_SIZE_SMALL ? OUString(RID_EXTBMP_AUTOFILTER_SC) : OUString(RID_EXTBMP_AUTOFILTER_LC)));
+ SetItemImage(nTBC_BT_FILTERCRIT, Image(StockImage::Yes, nSymbolsSize == SFX_SYMBOLS_SIZE_SMALL ? OUString(RID_EXTBMP_FILTERCRIT_SC) : OUString(RID_EXTBMP_FILTERCRIT_LC)));
+ SetItemImage(nTBC_BT_REMOVEFILTER, Image(StockImage::Yes, nSymbolsSize == SFX_SYMBOLS_SIZE_SMALL ? OUString(RID_EXTBMP_REMOVE_FILTER_SORT_SC) : OUString(RID_EXTBMP_REMOVE_FILTER_SORT_LC)));
+ AdjustToolBox();
+}
+
+void BibToolBar::AdjustToolBox()
+{
+ Size aOldSize = GetSizePixel();
+ Size aSize = CalcWindowSizePixel();
+ if ( !aSize.Width() )
+ aSize.setWidth( aOldSize.Width() );
+ else if ( !aSize.Height() )
+ aSize.setHeight( aOldSize.Height() );
+
+ Size aTbSize = GetSizePixel();
+ if (
+ (aSize.Width() && aSize.Width() != aTbSize.Width()) ||
+ (aSize.Height() && aSize.Height() != aTbSize.Height())
+ )
+ {
+ SetPosSizePixel( GetPosPixel(), aSize );
+ Invalidate();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/toolbar.hxx b/extensions/source/bibliography/toolbar.hxx
new file mode 100644
index 000000000..4f800f050
--- /dev/null
+++ b/extensions/source/bibliography/toolbar.hxx
@@ -0,0 +1,217 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/XStatusListener.hpp>
+
+#include <vcl/InterimItemWindow.hxx>
+#include <vcl/toolbox.hxx>
+#include <vcl/timer.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <vector>
+
+class BibDataManager;
+class BibToolBar;
+
+class BibToolBarListener: public cppu::WeakImplHelper < css::frame::XStatusListener>
+{
+private:
+
+ ToolBoxItemId nIndex;
+ OUString aCommand;
+
+protected:
+
+ VclPtr<BibToolBar> pToolBar;
+
+public:
+
+ BibToolBarListener(BibToolBar *pTB, const OUString& aStr, ToolBoxItemId nId);
+ virtual ~BibToolBarListener() override;
+
+ const OUString& GetCommand() const { return aCommand;}
+
+ // css::lang::XEventListener
+ // we do not hold References to dispatches, so there is nothing to do on disposal
+ virtual void SAL_CALL disposing(const css::lang::EventObject& /*Source*/) override {};
+
+ // css::frame::XStatusListener
+ virtual void SAL_CALL statusChanged(const css::frame::FeatureStateEvent& Event) override;
+
+};
+
+class BibTBListBoxListener: public BibToolBarListener
+{
+public:
+
+ BibTBListBoxListener(BibToolBar *pTB, const OUString& aStr, ToolBoxItemId nId);
+ virtual ~BibTBListBoxListener() override;
+
+ virtual void SAL_CALL statusChanged(const css::frame::FeatureStateEvent& Event) override;
+
+};
+
+class BibTBEditListener: public BibToolBarListener
+{
+public:
+
+ BibTBEditListener(BibToolBar *pTB, const OUString& aStr, ToolBoxItemId nId);
+ virtual ~BibTBEditListener() override;
+
+ virtual void SAL_CALL statusChanged(const css::frame::FeatureStateEvent& Event) override;
+
+};
+
+class BibTBQueryMenuListener: public BibToolBarListener
+{
+public:
+
+ BibTBQueryMenuListener(BibToolBar *pTB, const OUString& aStr, ToolBoxItemId nId);
+ virtual ~BibTBQueryMenuListener() override;
+
+ virtual void SAL_CALL statusChanged(const css::frame::FeatureStateEvent& Event) override;
+
+};
+
+
+typedef std::vector< css::uno::Reference< css::frame::XStatusListener> > BibToolBarListenerArr;
+
+class ComboBoxControl final : public InterimItemWindow
+{
+public:
+ ComboBoxControl(vcl::Window* pParent);
+ virtual ~ComboBoxControl() override;
+ virtual void dispose() override;
+
+ weld::ComboBox* get_widget() { return m_xLBSource.get(); }
+
+ void set_sensitive(bool bSensitive)
+ {
+ m_xFtSource->set_sensitive(bSensitive);
+ m_xLBSource->set_sensitive(bSensitive);
+ Enable(bSensitive);
+ }
+
+private:
+ std::unique_ptr<weld::Label> m_xFtSource;
+ std::unique_ptr<weld::ComboBox> m_xLBSource;
+};
+
+class EditControl final : public InterimItemWindow
+{
+public:
+ EditControl(vcl::Window* pParent);
+ virtual ~EditControl() override;
+ virtual void dispose() override;
+
+ weld::Entry* get_widget() { return m_xEdQuery.get(); }
+
+ void set_sensitive(bool bSensitive)
+ {
+ m_xFtQuery->set_sensitive(bSensitive);
+ m_xEdQuery->set_sensitive(bSensitive);
+ Enable(bSensitive);
+ }
+
+private:
+ std::unique_ptr<weld::Label> m_xFtQuery;
+ std::unique_ptr<weld::Entry> m_xEdQuery;
+};
+
+class BibToolBar: public ToolBox
+{
+ private:
+
+ BibToolBarListenerArr aListenerArr;
+ css::uno::Reference< css::frame::XController > xController;
+ Idle aIdle;
+ VclPtr<ComboBoxControl> xSource;
+ weld::ComboBox* pLbSource;
+ VclPtr<EditControl> xQuery;
+ weld::Entry* pEdQuery;
+ std::unique_ptr<weld::Builder> xBuilder;
+ std::unique_ptr<weld::Menu> xPopupMenu;
+ sal_uInt16 nMenuId;
+ OString sSelMenuItem;
+ OUString aQueryField;
+ Link<void*,void> aLayoutManager;
+ sal_Int16 nSymbolsSize;
+
+ ToolBoxItemId nTBC_SOURCE;
+ ToolBoxItemId nTBC_QUERY;
+ ToolBoxItemId nTBC_BT_AUTOFILTER;
+ ToolBoxItemId nTBC_BT_COL_ASSIGN;
+ ToolBoxItemId nTBC_BT_CHANGESOURCE;
+ ToolBoxItemId nTBC_BT_FILTERCRIT;
+ ToolBoxItemId nTBC_BT_REMOVEFILTER;
+
+ BibDataManager* pDatMan;
+ DECL_LINK( SelHdl, weld::ComboBox&, void );
+ DECL_LINK( SendSelHdl, Timer*, void );
+ DECL_LINK( MenuHdl, ToolBox*, void );
+ DECL_LINK( OptionsChanged_Impl, LinkParamNone*, void );
+ DECL_LINK( SettingsChanged_Impl, VclSimpleEvent&, void );
+
+ void ApplyImageList();
+ void RebuildToolbar();
+
+ protected:
+
+ void DataChanged( const DataChangedEvent& rDCEvt ) override;
+ void InitListener();
+ virtual void Select() override;
+ virtual void Click() override;
+ virtual bool PreNotify( NotifyEvent& rNEvt ) override;
+
+
+ public:
+
+ BibToolBar(vcl::Window* pParent, Link<void*,void> aLink);
+ virtual ~BibToolBar() override;
+ virtual void dispose() override;
+
+ ToolBoxItemId GetChangeSourceId() const { return nTBC_BT_CHANGESOURCE; }
+
+ void SetXController(const css::uno::Reference< css::frame::XController > &);
+
+ void ClearSourceList();
+ void UpdateSourceList(bool bFlag);
+ void EnableSourceList(bool bFlag);
+ void InsertSourceEntry(const OUString& );
+ void SelectSourceEntry(const OUString& );
+
+ void EnableQuery(bool bFlag);
+ void SetQueryString(const OUString& );
+ void AdjustToolBox();
+
+ void ClearFilterMenu();
+ sal_uInt16 InsertFilterItem(const OUString& );
+ void SelectFilterItem(sal_uInt16 nId);
+
+ /// @throws css::uno::RuntimeException
+ void statusChanged(const css::frame::FeatureStateEvent& Event);
+
+ void SetDatMan(BibDataManager& rDatMan) {pDatMan = &rDatMan;}
+ void SendDispatch(ToolBoxItemId nId, const css::uno::Sequence< css::beans::PropertyValue >& rArgs);
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */