summaryrefslogtreecommitdiffstats
path: root/extensions/source/bibliography
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--extensions/source/bibliography/bib.component26
-rw-r--r--extensions/source/bibliography/bibbeam.cxx267
-rw-r--r--extensions/source/bibliography/bibbeam.hxx74
-rw-r--r--extensions/source/bibliography/bibconfig.cxx298
-rw-r--r--extensions/source/bibliography/bibconfig.hxx153
-rw-r--r--extensions/source/bibliography/bibcont.cxx241
-rw-r--r--extensions/source/bibliography/bibcont.hxx96
-rw-r--r--extensions/source/bibliography/bibload.cxx656
-rw-r--r--extensions/source/bibliography/bibmod.cxx104
-rw-r--r--extensions/source/bibliography/bibmod.hxx52
-rw-r--r--extensions/source/bibliography/bibprop.hxx37
-rw-r--r--extensions/source/bibliography/bibresid.hxx29
-rw-r--r--extensions/source/bibliography/bibshortcuthandler.hxx69
-rw-r--r--extensions/source/bibliography/bibtools.hxx45
-rw-r--r--extensions/source/bibliography/bibview.cxx227
-rw-r--r--extensions/source/bibliography/bibview.hxx90
-rw-r--r--extensions/source/bibliography/datman.cxx1391
-rw-r--r--extensions/source/bibliography/datman.hxx173
-rw-r--r--extensions/source/bibliography/formcontrolcontainer.cxx135
-rw-r--r--extensions/source/bibliography/formcontrolcontainer.hxx68
-rw-r--r--extensions/source/bibliography/framectr.cxx850
-rw-r--r--extensions/source/bibliography/framectr.hxx118
-rw-r--r--extensions/source/bibliography/general.cxx707
-rw-r--r--extensions/source/bibliography/general.hxx190
-rw-r--r--extensions/source/bibliography/loadlisteneradapter.cxx185
-rw-r--r--extensions/source/bibliography/loadlisteneradapter.hxx154
-rw-r--r--extensions/source/bibliography/toolbar.cxx626
-rw-r--r--extensions/source/bibliography/toolbar.hxx220
28 files changed, 7281 insertions, 0 deletions
diff --git a/extensions/source/bibliography/bib.component b/extensions/source/bibliography/bib.component
new file mode 100644
index 000000000..37963bb90
--- /dev/null
+++ b/extensions/source/bibliography/bib.component
@@ -0,0 +1,26 @@
+<?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@"
+ prefix="bib" xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.extensions.Bibliography">
+ <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..e31c21ee9
--- /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 )
+ {
+ 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..57216922b
--- /dev/null
+++ b/extensions/source/bibliography/bibbeam.hxx
@@ -0,0 +1,74 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_BIBBEAM_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_BIBBEAM_HXX
+
+#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
+
+
+#endif
+
+/* 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..a9c2d74f2
--- /dev/null
+++ b/extensions/source/bibliography/bibconfig.cxx
@@ -0,0 +1,298 @@
+/* -*- 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 <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;
+
+
+static const char cDataSourceHistory[] = "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";
+
+
+ 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 = OUStringLiteral(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 = OUStringLiteral(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(2);
+ PropertyValue* pAssignmentValues = aAssignmentValues.getArray();
+ pAssignmentValues[0].Name = sSubPrefix;
+ pAssignmentValues[0].Name += sFieldName;
+ pAssignmentValues[0].Value <<= pMapping->aColumnPairs[nFieldAssignment].sLogicalColumnName;
+ pAssignmentValues[1].Name = sSubPrefix;
+ pAssignmentValues[1].Name += sDatabaseFieldName;
+ pAssignmentValues[1].Value <<= 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..0240b69c0
--- /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 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_BIBCONFIG_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_BIBCONFIG_HXX
+
+#include <unotools/configitem.hxx>
+#include <vector>
+#include <memory>
+
+struct Mapping;
+typedef std::vector<std::unique_ptr<Mapping> > MappingArray;
+
+
+#define COLUMN_COUNT 31
+#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
+
+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;
+ long nBeamerSize;
+ 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(long nSize) {SetModified(); nBeamerSize = nSize;}
+ long getBeamerSize()const {return nBeamerSize;}
+ void setViewSize(long nSize) {SetModified(); nViewSize = nSize;}
+ 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();
+
+};
+#endif
+
+/* 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..562d720a3
--- /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)
+{
+ 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();
+ 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();
+ 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;
+ 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..aca9f0e68
--- /dev/null
+++ b/extensions/source/bibliography/bibcont.hxx
@@ -0,0 +1,96 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_BIBCONT_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_BIBCONT_HXX
+
+#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
+};
+
+#endif
+
+/* 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..10067f17b
--- /dev/null
+++ b/extensions/source/bibliography/bibload.cxx
@@ -0,0 +1,656 @@
+/* -*- 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 <cppuhelper/factory.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/XSingleServiceFactory.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/XLoadListener.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <toolkit/awt/vclxwindow.hxx>
+#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>
+
+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;
+
+static Reference< XInterface > BibliographyLoader_CreateInstance( const Reference< XMultiServiceFactory > & rSMgr );
+
+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;
+ static OUString getImplementationName_Static() throw( )
+
+ {
+ //!
+ return "com.sun.star.extensions.Bibliography";
+ //!
+ }
+
+ //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;
+
+ static Sequence<OUString> getSupportedServiceNames_Static() throw( );
+
+ /// @throws Exception
+ friend Reference< XInterface > (::BibliographyLoader_CreateInstance)( const Reference< XMultiServiceFactory > & rSMgr );
+
+ // 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);
+}
+
+
+Reference< XInterface > BibliographyLoader_CreateInstance( const Reference< XMultiServiceFactory > & /*rSMgr*/ )
+{
+ return *(new BibliographyLoader);
+}
+
+
+// XServiceInfo
+OUString BibliographyLoader::getImplementationName()
+
+{
+ return getImplementationName_Static();
+}
+
+// XServiceInfo
+sal_Bool BibliographyLoader::supportsService(const OUString& ServiceName)
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+// XServiceInfo
+Sequence< OUString > BibliographyLoader::getSupportedServiceNames()
+{
+ return getSupportedServiceNames_Static();
+}
+
+// ORegistryServiceManager_Static
+Sequence< OUString > BibliographyLoader::getSupportedServiceNames_Static() throw( )
+{
+ return { "com.sun.star.frame.FrameLoader", "com.sun.star.frame.Bibliography" };
+}
+
+extern "C"
+{
+ SAL_DLLPUBLIC_EXPORT void * bib_component_getFactory(
+ const char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
+ {
+ void * pRet = nullptr;
+ if (BibliographyLoader::getImplementationName_Static().equalsAscii( pImplName ) )
+ {
+ // create the factory
+ Reference< XSingleServiceFactory > xFactory =
+ cppu::createSingleFactory(
+ static_cast<css::lang::XMultiServiceFactory *>(pServiceManager),
+ BibliographyLoader::getImplementationName_Static(),
+ BibliographyLoader_CreateInstance,
+ BibliographyLoader::getSupportedServiceNames_Static() );
+ // acquire, because we return an interface pointer instead of a reference
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+ return pRet;
+ }
+
+}
+
+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();
+
+ OUString aPartName = rURL.getToken( 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 == "View" || aPartName == "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();
+ VCLXWindow* pParentComponent = comphelper::getUnoTunnelImplementation<VCLXWindow>(aWindow);
+ assert(pParentComponent);
+
+ 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 (pParentComponent)
+ {
+ // not earlier because SetFocus() is triggered in setVisible()
+ pParentComponent->setVisible(true);
+ }
+
+ Reference<XLoadable>(m_xDatMan.get())->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[] =
+ {
+ { OUString("BibliographyDataFieldNames"), 0, cppu::UnoType<Sequence<PropertyValue>>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(), 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
+ };
+ 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::ISBN ; 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..3e2cd829c
--- /dev/null
+++ b/extensions/source/bibliography/bibmod.cxx
@@ -0,0 +1,104 @@
+/* -*- 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 "bibprop.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(const char* pId)
+{
+ return Translate::get(pId, 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;
+}
+
+BibDataManager* BibModul::createDataManager()
+{
+ return new BibDataManager();
+}
+
+BibConfig* BibModul::GetConfig()
+{
+ if(! pBibConfig)
+ pBibConfig = new BibConfig;
+ return pBibConfig;
+}
+
+
+// PropertyNames
+#define STATIC_USTRING(a,b) const OUString a(b)
+STATIC_USTRING(FM_PROP_LABEL,"Label");
+STATIC_USTRING(FM_PROP_CONTROLSOURCE,"DataField");
+STATIC_USTRING(FM_PROP_NAME,"Name");
+STATIC_USTRING(FM_PROP_FORMATKEY,"FormatKey");
+STATIC_USTRING(FM_PROP_EDITMODE,"RecordMode");
+STATIC_USTRING(FM_PROP_CURSORSOURCETYPE,"DataSelectionType");
+STATIC_USTRING(FM_PROP_CURSORSOURCE,"DataSelection");
+STATIC_USTRING(FM_PROP_DATASOURCE, "DataSource");
+STATIC_USTRING(FM_PROP_VALUE,"Value");
+STATIC_USTRING(FM_PROP_TEXT,"Text");
+
+/* 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..e651f720e
--- /dev/null
+++ b/extensions/source/bibliography/bibmod.hxx
@@ -0,0 +1,52 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_BIBMOD_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_BIBMOD_HXX
+
+#include <locale>
+
+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 BibDataManager* createDataManager();
+
+};
+
+typedef BibModul** HdlBibModul;
+
+HdlBibModul OpenBibModul();
+void CloseBibModul(HdlBibModul ppBibModul);
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/bibliography/bibprop.hxx b/extensions/source/bibliography/bibprop.hxx
new file mode 100644
index 000000000..85ba484d6
--- /dev/null
+++ b/extensions/source/bibliography/bibprop.hxx
@@ -0,0 +1,37 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_BIBPROP_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_BIBPROP_HXX
+
+#include <rtl/ustring.hxx>
+
+extern const OUString FM_PROP_LABEL;
+extern const OUString FM_PROP_NAME;
+extern const OUString FM_PROP_CONTROLSOURCE;
+extern const OUString FM_PROP_FORMATKEY;
+extern const OUString FM_PROP_VALUE;
+extern const OUString FM_PROP_EDITMODE;
+extern const OUString FM_PROP_DATASOURCE;
+extern const OUString FM_PROP_CURSORSOURCE;
+extern const OUString FM_PROP_CURSORSOURCETYPE;
+extern const OUString FM_PROP_TEXT;
+
+#endif
+
+/* 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..b555e632d
--- /dev/null
+++ b/extensions/source/bibliography/bibresid.hxx
@@ -0,0 +1,29 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_BIBRESID_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_BIBRESID_HXX
+
+#include <rtl/ustring.hxx>
+
+OUString BibResId(const char* pId);
+
+#endif // INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_BIBRESID_HXX
+
+/* 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..e9e397cd5
--- /dev/null
+++ b/extensions/source/bibliography/bibshortcuthandler.hxx
@@ -0,0 +1,69 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_BIBSHORTCUTHANDLER_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_BIBSHORTCUTHANDLER_HXX
+
+#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);
+};
+
+#endif
+
+/* 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..1fc9f0a35
--- /dev/null
+++ b/extensions/source/bibliography/bibtools.hxx
@@ -0,0 +1,45 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_BIBTOOLS_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_BIBTOOLS_HXX
+
+#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 );
+ }
+}
+
+#endif // INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_BIBTOOLS_HXX
+
+/* 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..e4eca4596
--- /dev/null
+++ b/extensions/source/bibliography/bibview.cxx
@@ -0,0 +1,227 @@
+/* -*- 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 <com/sun/star/sdbc/XResultSetUpdate.hpp>
+#include <vcl/weld.hxx>
+#include <tools/debug.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->CommitActiveControl();
+ Reference< XForm > xForm = m_pDatMan->getForm();
+ Reference< XPropertySet > xProps( xForm, UNO_QUERY );
+ Reference< sdbc::XResultSetUpdate > xResUpd( xProps, UNO_QUERY );
+ DBG_ASSERT( xResUpd.is(), "BibView::~BibView: invalid form!" );
+
+ if ( xResUpd.is() )
+ {
+ Any aModified = xProps->getPropertyValue( "IsModified" );
+ bool bFlag = false;
+ if ( ( aModified >>= bFlag ) && bFlag )
+ {
+
+ try
+ {
+ Any aNew = xProps->getPropertyValue( "IsNew" );
+ aNew >>= bFlag;
+ if ( bFlag )
+ xResUpd->insertRow();
+ else
+ xResUpd->updateRow();
+ }
+ catch( const uno::Exception&) {}
+ }
+ }
+
+ if ( m_aFormControlContainer.isFormConnected() )
+ m_aFormControlContainer.disconnectForm();
+
+ pGeneralPage->RemoveListeners();
+ pGeneralPage.disposeAndClear();
+ 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->RemoveListeners();
+ 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 mpBibView->getControlContainer();
+ }
+
+ Reference< awt::XControlContainer > BibView::getControlContainer() const
+ {
+ Reference< awt::XControlContainer > xReturn;
+ if ( m_pGeneralPage )
+ xReturn = m_pGeneralPage->GetControlContainer();
+ return xReturn;
+ }
+
+ 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..4198dac03
--- /dev/null
+++ b/extensions/source/bibliography/bibview.hxx
@@ -0,0 +1,90 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_BIBVIEW_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_BIBVIEW_HXX
+
+#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();
+ css::uno::Reference< css::awt::XControlContainer > getControlContainer() const;
+
+ virtual void GetFocus() override;
+
+ virtual bool HandleShortCutKey( const KeyEvent& rKeyEvent ) override; // returns true, if key was handled
+ };
+
+
+} // namespace bib
+
+
+#endif
+
+
+/* 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..0b16d3fa0
--- /dev/null
+++ b/extensions/source/bibliography/datman.cxx
@@ -0,0 +1,1391 @@
+/* -*- 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 "bibprop.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;
+
+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&)
+ {
+ OSL_FAIL("Exception caught in ODatabaseContext::getRegisteredObject()");
+ }
+ }
+ // 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&)
+ {
+ OSL_FAIL("exception in getConnection");
+ }
+
+ 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;
+ 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 ,
+ const OUString& 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_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[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, BibDataManager* pMan);
+
+ OUString GetCurrentURL()const;
+};
+
+}
+
+DBChangeDialog_Impl::DBChangeDialog_Impl(weld::Window* pParent, 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;
+}
+
+
+OUString const gGridName("theGrid");
+OUString const gViewName("theView");
+OUString const gGlobalName("theGlobals");
+OUString const gBeamerSize("theBeamerSize");
+OUString const gViewSize("theViewSize");
+
+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;
+ const OUString sType("Type");
+ sal_Int32 nType = 0;
+ bool bIsFormatted = false;
+ bool bFormattedIsNumeric = true;
+ xField->getPropertyValue(sType) >>= 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 = makeAny( rField );
+ xCurrentCol->setPropertyValue(FM_PROP_CONTROLSOURCE, aColName);
+ xCurrentCol->setPropertyValue(FM_PROP_LABEL, aColName);
+
+ xColContainer->insertByName( rField, makeAny( xCurrentCol ) );
+ }
+ }
+ catch (const Exception&)
+ {
+ OSL_FAIL("Exception in BibDataManager::InsertFields");
+ }
+}
+
+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, makeAny( 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", makeAny( aQuery ) );
+ xFormProps->setPropertyValue( "ApplyFilter", makeAny( 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;
+ aQueryString+=getQueryField();
+ aQueryString+=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", makeAny(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", makeAny( 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, makeAny<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;
+
+ const OUString sType("Type");
+ sal_Int32 nFormatKey = 0;
+ xField->getPropertyValue(sType) >>= 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, makeAny( rName ) );
+ xPropSet->setPropertyValue("NativeWidgetLook", makeAny( 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, makeAny( 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..3be03aaa9
--- /dev/null
+++ b/extensions/source/bibliography/datman.hxx
@@ -0,0 +1,173 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_DATMAN_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_DATMAN_HXX
+
+#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 vcl { class Window; }
+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;
+};
+
+
+#endif
+
+/* 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..5e9f7d37a
--- /dev/null
+++ b/extensions/source/bibliography/formcontrolcontainer.cxx
@@ -0,0 +1,135 @@
+/* -*- 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();
+ Sequence< Reference< XControl > > aControls;
+ if ( xControlCont.is() )
+ 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..fc119a7eb
--- /dev/null
+++ b/extensions/source/bibliography/formcontrolcontainer.hxx
@@ -0,0 +1,68 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_FORMCONTROLCONTAINER_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_FORMCONTROLCONTAINER_HXX
+
+#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
+
+
+#endif // INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_FORMCONTROLCONTAINER_HXX
+
+/* 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..9aa912a93
--- /dev/null
+++ b/extensions/source/bibliography/framectr.cxx
@@ -0,0 +1,850 @@
+/* -*- 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/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/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 <cppuhelper/interfacecontainer.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <sot/exchange.hxx>
+#include <sot/formats.hxx>
+#include <tools/diagnose_ex.h>
+#include <vcl/edit.hxx>
+#include <vcl/weld.hxx>
+#include <osl/mutex.hxx>
+
+#include <unordered_map>
+
+using namespace osl;
+using namespace cppu;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::uno;
+using namespace com::sun::star;
+
+namespace {
+
+struct DispatchInfo
+{
+ const char* pCommand;
+ sal_Int16 nGroupId;
+ bool bActiveConnection;
+};
+
+struct CacheDispatchInfo
+{
+ sal_Int16 nGroupId;
+ bool bActiveConnection;
+};
+
+}
+
+// Attention: commands must be sorted by command groups. Implementation is dependent
+// on this!!
+static 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;
+ OMultiTypeInterfaceContainerHelper 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)
+ :xWindow( xComponent )
+ ,m_xDatMan( pDataManager )
+{
+ bDisposing=false;
+ mxImpl = new BibFrameCtrl_Impl;
+ mxImpl->pController = this;
+}
+
+BibFrameController_Impl::~BibFrameController_Impl()
+{
+ mxImpl->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 )
+{
+ xFrame = xArg;
+ xFrame->addFrameActionListener( mxImpl.get() );
+}
+
+sal_Bool BibFrameController_Impl::attachModel( const uno::Reference< XModel > & /*xModel*/ )
+{
+ return false;
+}
+
+sal_Bool BibFrameController_Impl::suspend( sal_Bool bSuspend )
+{
+ if ( bSuspend )
+ getFrame()->removeFrameActionListener( mxImpl.get() );
+ else
+ getFrame()->addFrameActionListener( mxImpl.get() );
+ 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 xFrame;
+}
+
+uno::Reference< XModel > BibFrameController_Impl::getModel()
+{
+ return uno::Reference< XModel > ();
+}
+
+void BibFrameController_Impl::dispose()
+{
+ bDisposing = true;
+ lang::EventObject aObject;
+ aObject.Source = static_cast<XController*>(this);
+ mxImpl->aLC.disposeAndClear(aObject);
+ m_xDatMan.clear();
+ aStatusListeners.clear();
+ }
+
+void BibFrameController_Impl::addEventListener( const uno::Reference< lang::XEventListener > & aListener )
+{
+ mxImpl->aLC.addInterface( cppu::UnoType<lang::XEventListener>::get(), aListener );
+}
+
+void BibFrameController_Impl::removeEventListener( const uno::Reference< lang::XEventListener > & aListener )
+{
+ mxImpl->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 ( !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() );
+ for ( sal_Int32 i=0; i<aDescripts.getLength(); ++i )
+ aDispatches[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( 4 );
+
+ aDispatchInfo[0] = frame::CommandGroup::EDIT;
+ aDispatchInfo[1] = frame::CommandGroup::DOCUMENT;
+ aDispatchInfo[2] = frame::CommandGroup::DATA;
+ aDispatchInfo[3] = 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&)
+ {
+ OSL_FAIL("SaveModified: Exception occurred!");
+ }
+ }
+ 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 ( bDisposing )
+ return;
+
+ ::SolarMutexGuard aGuard;
+ weld::Window* pParent = Application::GetFrameWeld(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(2);
+ beans::PropertyValue* pProps = aNewDataSource.getArray();
+ pProps[0].Value <<= OUString();
+ pProps[1].Value <<= aURL;
+ ChangeDataSource(aNewDataSource);
+ }
+ catch(const Exception&)
+ {
+ OSL_FAIL("Exception caught while changing the data source");
+ }
+ }
+ }
+ else if(aCommand == "Bib/autoFilter")
+ {
+ sal_uInt16 nCount = aStatusListeners.size();
+ for ( sal_uInt16 n=0; n<nCount; n++ )
+ {
+ BibStatusDispatch *pObj = 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), 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 = aStatusListeners.size();
+ for ( sal_uInt16 n=0; n<nCount; n++ )
+ {
+ BibStatusDispatch *pObj = 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&)
+ {
+ OSL_FAIL("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&)
+ {
+ OSL_FAIL("DeleteRecord: exception caught!");
+ }
+ }
+ }
+ }
+ }
+ else if(aCommand == "Cut")
+ {
+ vcl::Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
+ if(pChild)
+ {
+ KeyEvent aEvent( 0, KeyFuncType::CUT );
+ pChild->KeyInput( aEvent );
+ }
+ }
+ else if(aCommand == "Copy")
+ {
+ vcl::Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
+ if(pChild)
+ {
+ KeyEvent aEvent( 0, KeyFuncType::COPY );
+ pChild->KeyInput( aEvent );
+ }
+ }
+ else if(aCommand == "Paste")
+ {
+ vcl::Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
+ if(pChild)
+ {
+ KeyEvent aEvent( 0, KeyFuncType::PASTE );
+ pChild->KeyInput( aEvent );
+ }
+ }
+}
+IMPL_LINK_NOARG( BibFrameController_Impl, DisposeHdl, void*, void )
+{
+ 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
+ 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")
+ {
+ vcl::Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
+ Edit* pEdit = dynamic_cast<Edit*>( pChild );
+ if( pEdit )
+ aEvent.IsEnabled = !pEdit->IsReadOnly() && pEdit->GetSelection().Len();
+ }
+ if(aURL.Path == "Copy")
+ {
+ vcl::Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
+ Edit* pEdit = dynamic_cast<Edit*>( pChild );
+ if( pEdit )
+ aEvent.IsEnabled = pEdit->GetSelection().Len() > 0;
+ }
+ else if(aURL.Path == "Paste" )
+ {
+ aEvent.IsEnabled = false;
+ vcl::Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
+ if(pChild)
+ {
+ uno::Reference< datatransfer::clipboard::XClipboard > xClip = pChild->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 ( bDisposing )
+ return;
+
+ sal_uInt16 nCount = aStatusListeners.size();
+ for ( sal_uInt16 n=0; n<nCount; n++ )
+ {
+ BibStatusDispatch *pObj = aStatusListeners[n].get();
+ bool bFlag=pObj->xListener.is();
+ if (!bFlag || (pObj->xListener == aObject &&
+ ( aURL.Complete.isEmpty() || pObj->aURL.Path == aURL.Path )))
+ {
+ aStatusListeners.erase( aStatusListeners.begin() + n );
+ break;
+ }
+ }
+}
+
+void BibFrameController_Impl::RemoveFilter()
+{
+ OUString aQuery;
+ m_xDatMan->startQueryWith(aQuery);
+
+ sal_uInt16 nCount = aStatusListeners.size();
+
+ bool bRemoveFilter=false;
+ bool bQueryText=false;
+
+ for ( sal_uInt16 n=0; n<nCount; n++ )
+ {
+ BibStatusDispatch *pObj = 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.get());
+ xLoadable->unload();
+ m_xDatMan->setActiveDataTable(aDBTableName);
+ m_xDatMan->updateGridModel();
+ xLoadable->load();
+ }
+
+
+ sal_uInt16 nCount = aStatusListeners.size();
+
+ bool bMenuFilter=false;
+ bool bQueryText=false;
+ for ( sal_uInt16 n=0; n<nCount; n++ )
+ {
+ BibStatusDispatch *pObj = 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..50bf20cfd
--- /dev/null
+++ b/extensions/source/bibliography/framectr.hxx
@@ -0,0 +1,118 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_FRAMECTR_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_FRAMECTR_HXX
+
+#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 <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> mxImpl;
+ BibStatusDispatchArr aStatusListeners;
+ css::uno::Reference< css::awt::XWindow > xWindow;
+ css::uno::Reference< css::frame::XFrame > xFrame;
+ bool bDisposing;
+ rtl::Reference<BibDataManager> m_xDatMan;
+
+ 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;
+ };
+
+#endif
+
+/* 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..c1963ae32
--- /dev/null
+++ b/extensions/source/bibliography/general.cxx
@@ -0,0 +1,707 @@
+/* -*- 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/sdbc/XRowSet.hpp>
+#include <com/sun/star/sdb/XColumn.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <vcl/builder.hxx>
+#include <vcl/scrbar.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/fixed.hxx>
+#include "general.hxx"
+#include "bibresid.hxx"
+#include "datman.hxx"
+#include "bibconfig.hxx"
+#include <strings.hrc>
+#include "bibmod.hxx"
+#include <helpids.h>
+#include <tools/debug.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/i18nhelp.hxx>
+#include <vcl/mnemonic.hxx>
+#include <algorithm>
+#include <tools/urlobj.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::form;
+using namespace ::com::sun::star::sdb;
+
+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;
+}
+
+namespace {
+
+class BibPosListener :public cppu::WeakImplHelper <sdbc::XRowSetListener>
+{
+ VclPtr<BibGeneralPage> pParentPage;
+public:
+ explicit BibPosListener(BibGeneralPage* pParent);
+
+ //XPositioningListener
+ virtual void SAL_CALL cursorMoved(const lang::EventObject& event) override;
+ virtual void SAL_CALL rowChanged(const lang::EventObject& /*event*/) override { /* not interested in */ }
+ virtual void SAL_CALL rowSetChanged(const lang::EventObject& /*event*/) override { /* not interested in */ }
+
+ //XEventListener
+ virtual void SAL_CALL disposing(const lang::EventObject& Source) override;
+
+};
+
+}
+
+BibPosListener::BibPosListener(BibGeneralPage* pParent) :
+ pParentPage(pParent)
+{
+}
+
+void BibPosListener::cursorMoved(const lang::EventObject& /*aEvent*/)
+{
+ try
+ {
+ uno::Reference< form::XBoundComponent > xLstBox = pParentPage->GetTypeListBoxModel();
+ uno::Reference< beans::XPropertySet > xPropSet(xLstBox, UNO_QUERY);
+ if(xPropSet.is())
+ {
+ BibConfig* pBibConfig = BibModul::GetConfig();
+ BibDataManager* pDatMan = pParentPage->GetDataManager();
+ BibDBDescriptor aDesc;
+ aDesc.sDataSource = pDatMan->getActiveDataSource();
+ aDesc.sTableOrQuery = pDatMan->getActiveDataTable();
+ aDesc.nCommandType = CommandType::TABLE;
+
+ const Mapping* pMapping = pBibConfig->GetMapping(aDesc);
+ OUString sTypeMapping = pBibConfig->GetDefColumnName(AUTHORITYTYPE_POS);
+ if(pMapping)
+ {
+ for(const auto & aColumnPair : pMapping->aColumnPairs)
+ {
+ if(aColumnPair.sLogicalColumnName == sTypeMapping)
+ {
+ sTypeMapping = aColumnPair.sRealColumnName;
+ break;
+ }
+ }
+ }
+ OUString uTypeMapping = sTypeMapping;
+
+ uno::Reference< form::XForm > xForm = pDatMan->getForm();
+ uno::Reference< sdbcx::XColumnsSupplier > xSupplyCols(xForm, UNO_QUERY);
+ uno::Reference< container::XNameAccess > xValueAcc;
+ if (xSupplyCols.is())
+ xValueAcc = xSupplyCols->getColumns();
+
+ sal_Int16 nTempVal = -1;
+ if(xValueAcc.is() && xValueAcc->hasByName(uTypeMapping))
+ {
+ uno::Any aVal = xValueAcc->getByName(uTypeMapping);
+ uno::Reference< sdb::XColumn > xCol(aVal, UNO_QUERY);
+ DBG_ASSERT(xCol.is(), "BibPosListener::cursorMoved : invalid column (no sdb::XColumn) !");
+ if (xCol.is())
+ {
+ nTempVal = xCol->getShort();
+ // getShort returns zero if the value is not a number
+ if (!nTempVal || xCol->wasNull())
+ {
+ OUString sTempVal = xCol->getString();
+ if(sTempVal != "0")
+ nTempVal = -1;
+ }
+ }
+ }
+ if(nTempVal < 0 || nTempVal >= TYPE_COUNT)
+ {
+ uno::Any aSel;
+ uno::Sequence<sal_Int16> aSelSeq(1);
+ sal_Int16* pArr = aSelSeq.getArray();
+ pArr[0] = TYPE_COUNT;
+ aSel <<= aSelSeq;
+ xPropSet->setPropertyValue("SelectedItems", aSel);
+ }
+ }
+ }
+ catch(const Exception&)
+ {
+ OSL_FAIL("BibPosListener::cursorMoved: something went wrong !");
+ }
+}
+
+void BibPosListener::disposing(const lang::EventObject& /*Source*/)
+{
+}
+
+BibGeneralPage::BibGeneralPage(vcl::Window* pParent, BibDataManager* pMan):
+ TabPage(pParent, "GeneralPage", "modules/sbibliography/ui/generalpage.ui"),
+ BibShortCutHandler( this ),
+ mxBibGeneralPageFocusListener(new BibGeneralPageFocusListener(this)),
+ pDatMan(pMan)
+{
+ get(pIdentifierFT, "shortname");
+ get(pAuthTypeFT, "authtype");
+ get(pGrid, "grid");
+ get(pScrolledWindow, "scrolledwindow");
+ get(pYearFT, "year");
+ get(pAuthorFT, "authors");
+ get(pTitleFT, "title");
+ get(pPublisherFT, "publisher");
+ get(pAddressFT, "address");
+ get(pISBNFT, "isbn");
+ get(pChapterFT, "chapter");
+ get(pPagesFT, "pages");
+ get(pEditorFT, "editor");
+ get(pEditionFT, "edition");
+ get(pBooktitleFT, "booktitle");
+ get(pVolumeFT, "volume");
+ get(pHowpublishedFT, "publicationtype");
+ get(pOrganizationsFT, "organization");
+ get(pInstitutionFT, "institution");
+ get(pSchoolFT, "university");
+ get(pReportTypeFT, "reporttype");
+ get(pMonthFT, "month");
+ get(pJournalFT, "journal");
+ get(pNumberFT, "number");
+ get(pSeriesFT, "series");
+ get(pAnnoteFT, "annotation");
+ get(pNoteFT, "note");
+ get(pURLFT, "url");
+ get(pCustom1FT, "custom1");
+ get(pCustom2FT, "custom2");
+ get(pCustom3FT, "custom3");
+ get(pCustom4FT, "custom4");
+ get(pCustom5FT, "custom5");
+
+ InitFixedTexts();
+
+ sal_Int16* pMap = nFT2CtrlMap;
+ for( sal_uInt16 i = 0 ; i < FIELD_COUNT ; ++i, ++pMap )
+ {
+ aControls[ i ] = nullptr;
+ *pMap = -1;
+ }
+
+ BibConfig* pBibConfig = BibModul::GetConfig();
+ BibDBDescriptor aDesc;
+ aDesc.sDataSource = pDatMan->getActiveDataSource();
+ aDesc.sTableOrQuery = pDatMan->getActiveDataTable();
+ aDesc.nCommandType = CommandType::TABLE;
+ const Mapping* pMapping = pBibConfig->GetMapping(aDesc);
+
+ xCtrlContnr = VCLUnoHelper::CreateControlContainer(pGrid);
+
+ std::vector<vcl::Window*> aChildren;
+
+ AddControlWithError(lcl_GetColumnName(pMapping, IDENTIFIER_POS), *pIdentifierFT,
+ sTableErrorString,
+ HID_BIB_IDENTIFIER_POS, 0, aChildren);
+
+ sTypeColumnName = lcl_GetColumnName(pMapping, AUTHORITYTYPE_POS);
+
+ AddControlWithError(sTypeColumnName, *pAuthTypeFT, sTableErrorString,
+ HID_BIB_AUTHORITYTYPE_POS, 1, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, YEAR_POS), *pYearFT,
+ sTableErrorString, HID_BIB_YEAR_POS, 2, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, AUTHOR_POS), *pAuthorFT,
+ sTableErrorString, HID_BIB_AUTHOR_POS, 3, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, TITLE_POS), *pTitleFT, sTableErrorString,
+ HID_BIB_TITLE_POS, 4, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, PUBLISHER_POS), *pPublisherFT,
+ sTableErrorString, HID_BIB_PUBLISHER_POS, 5, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, ADDRESS_POS), *pAddressFT,
+ sTableErrorString, HID_BIB_ADDRESS_POS, 6, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, ISBN_POS), *pISBNFT,
+ sTableErrorString, HID_BIB_ISBN_POS, 7, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, CHAPTER_POS), *pChapterFT,
+ sTableErrorString, HID_BIB_CHAPTER_POS, 8, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, PAGES_POS), *pPagesFT,
+ sTableErrorString, HID_BIB_PAGES_POS, 9, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, EDITOR_POS), *pEditorFT,
+ sTableErrorString, HID_BIB_EDITOR_POS, 10, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, EDITION_POS), *pEditionFT,
+ sTableErrorString, HID_BIB_EDITION_POS, 11, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, BOOKTITLE_POS), *pBooktitleFT,
+ sTableErrorString, HID_BIB_BOOKTITLE_POS, 12, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, VOLUME_POS), *pVolumeFT,
+ sTableErrorString, HID_BIB_VOLUME_POS, 13, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, HOWPUBLISHED_POS), *pHowpublishedFT,
+ sTableErrorString, HID_BIB_HOWPUBLISHED_POS, 14, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, ORGANIZATIONS_POS), *pOrganizationsFT,
+ sTableErrorString, HID_BIB_ORGANIZATIONS_POS, 15, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, INSTITUTION_POS), *pInstitutionFT,
+ sTableErrorString, HID_BIB_INSTITUTION_POS, 16, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, SCHOOL_POS), *pSchoolFT,
+ sTableErrorString, HID_BIB_SCHOOL_POS, 17, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, REPORTTYPE_POS), *pReportTypeFT,
+ sTableErrorString, HID_BIB_REPORTTYPE_POS, 18, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, MONTH_POS), *pMonthFT,
+ sTableErrorString, HID_BIB_MONTH_POS, 19, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, JOURNAL_POS), *pJournalFT,
+ sTableErrorString, HID_BIB_JOURNAL_POS, 20, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, NUMBER_POS), *pNumberFT,
+ sTableErrorString, HID_BIB_NUMBER_POS, 21, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, SERIES_POS), *pSeriesFT,
+ sTableErrorString, HID_BIB_SERIES_POS, 22, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, ANNOTE_POS), *pAnnoteFT,
+ sTableErrorString, HID_BIB_ANNOTE_POS, 23, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, NOTE_POS),*pNoteFT,
+ sTableErrorString, HID_BIB_NOTE_POS, 24, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, URL_POS), *pURLFT,
+ sTableErrorString, HID_BIB_URL_POS, 25, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, CUSTOM1_POS), *pCustom1FT,
+ sTableErrorString, HID_BIB_CUSTOM1_POS, 26, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, CUSTOM2_POS), *pCustom2FT,
+ sTableErrorString, HID_BIB_CUSTOM2_POS, 27, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, CUSTOM3_POS), *pCustom3FT,
+ sTableErrorString, HID_BIB_CUSTOM3_POS, 28, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, CUSTOM4_POS), *pCustom4FT,
+ sTableErrorString, HID_BIB_CUSTOM4_POS, 29, aChildren);
+
+ AddControlWithError(lcl_GetColumnName(pMapping, CUSTOM5_POS), *pCustom5FT,
+ sTableErrorString, HID_BIB_CUSTOM5_POS, 30, aChildren);
+
+ BuilderUtils::reorderWithinParent(aChildren, false);
+
+ xPosListener = new BibPosListener(this);
+ uno::Reference< sdbc::XRowSet > xRowSet(pDatMan->getForm(), UNO_QUERY);
+ if(xRowSet.is())
+ xRowSet->addRowSetListener(xPosListener);
+ uno::Reference< form::runtime::XFormController > xFormCtrl = pDatMan->GetFormController();
+ xFormCtrl->setContainer(xCtrlContnr);
+ xFormCtrl->activateTabOrder();
+
+ 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());
+}
+
+BibGeneralPage::~BibGeneralPage()
+{
+ disposeOnce();
+}
+
+void BibGeneralPage::dispose()
+{
+ if (pDatMan && xPosListener.is())
+ {
+ uno::Reference< sdbc::XRowSet > xRowSet(pDatMan->getForm(), UNO_QUERY);
+ if(xRowSet.is())
+ xRowSet->removeRowSetListener(xPosListener);
+ }
+ pGrid.clear();
+ pScrolledWindow.clear();
+ pIdentifierFT.clear();
+ pAuthTypeFT.clear();
+ pYearFT.clear();
+ pAuthorFT.clear();
+ pTitleFT.clear();
+ pPublisherFT.clear();
+ pAddressFT.clear();
+ pISBNFT.clear();
+ pChapterFT.clear();
+ pPagesFT.clear();
+ pEditorFT.clear();
+ pEditionFT.clear();
+ pBooktitleFT.clear();
+ pVolumeFT.clear();
+ pHowpublishedFT.clear();
+ pOrganizationsFT.clear();
+ pInstitutionFT.clear();
+ pSchoolFT.clear();
+ pReportTypeFT.clear();
+ pMonthFT.clear();
+ pJournalFT.clear();
+ pNumberFT.clear();
+ pSeriesFT.clear();
+ pAnnoteFT.clear();
+ pNoteFT.clear();
+ pURLFT.clear();
+ pCustom1FT.clear();
+ pCustom2FT.clear();
+ pCustom3FT.clear();
+ pCustom4FT.clear();
+ pCustom5FT.clear();
+ for (auto & a: aFixedTexts) a.clear();
+ mxBibGeneralPageFocusListener.clear();
+ TabPage::dispose();
+}
+
+void BibGeneralPage::RemoveListeners()
+{
+ for(uno::Reference<awt::XWindow> & aControl : aControls)
+ {
+ if(aControl.is())
+ {
+ aControl->removeFocusListener( mxBibGeneralPageFocusListener.get() );
+ aControl = nullptr;
+ }
+ }
+}
+
+void BibGeneralPage::CommitActiveControl()
+{
+ uno::Reference< form::runtime::XFormController > xFormCtrl = pDatMan->GetFormController();
+ uno::Reference< awt::XControl > xCurr = xFormCtrl->getCurrentControl();
+ if(xCurr.is())
+ {
+ uno::Reference< awt::XControlModel > xModel = xCurr->getModel();
+ uno::Reference< form::XBoundComponent > xBound(xModel, UNO_QUERY);
+ if(xBound.is())
+ xBound->commit();
+ }
+}
+
+void BibGeneralPage::AddControlWithError( const OUString& rColumnName, FixedText &rLabel,
+ OUString& rErrorString, const OString& sHelpId, sal_uInt16 nIndexInFTArray, std::vector<vcl::Window*> &rChildren)
+{
+ const OUString aColumnUIName(rLabel.GetText());
+ // adds also the XControl and creates a map entry in nFT2CtrlMap[] for mapping between control and FT
+
+ sal_Int16 nIndex = -1;
+ bool bSuccess = AddXControl(rColumnName, rLabel, sHelpId, nIndex, rChildren);
+ if (bSuccess)
+ {
+ DBG_ASSERT( nIndexInFTArray < FIELD_COUNT, "*BibGeneralPage::AddControlWithError(): wrong array index!" );
+ DBG_ASSERT( nFT2CtrlMap[ nIndexInFTArray ] < 0, "+BibGeneralPage::AddControlWithError(): index already in use!" );
+
+ nFT2CtrlMap[ nIndexInFTArray ] = nIndex;
+ }
+ else
+ {
+ if( !rErrorString.isEmpty() )
+ rErrorString += "\n";
+
+ rErrorString += MnemonicGenerator::EraseAllMnemonicChars( aColumnUIName );
+ }
+}
+
+bool BibGeneralPage::AddXControl(
+ const OUString& rName,
+ FixedText& rLabel, const OString& sHelpId, sal_Int16& rIndex,
+ std::vector<vcl::Window*>& rChildren)
+{
+ uno::Reference< awt::XControlModel > xCtrModel;
+ try
+ {
+ const bool bTypeListBox = sTypeColumnName == rName;
+ xCtrModel = pDatMan->loadControlModel(rName, bTypeListBox);
+ if ( xCtrModel.is() )
+ {
+ uno::Reference< beans::XPropertySet > xPropSet( xCtrModel, UNO_QUERY );
+
+ if( xPropSet.is())
+ {
+ uno::Reference< beans::XPropertySetInfo > xPropInfo = xPropSet->getPropertySetInfo();
+
+ OUString aControlName;
+ if (bTypeListBox)
+ {
+ aControlName = "com.sun.star.form.control.ListBox";
+ xLBModel.set(xCtrModel, UNO_QUERY);
+ }
+ else
+ {
+ uno::Any aAny = xPropSet->getPropertyValue( "DefaultControl" );
+ aAny >>= aControlName;
+ }
+
+ OUString uProp("HelpURL");
+ if(xPropInfo->hasPropertyByName(uProp))
+ {
+ OUString sId( INET_HID_SCHEME );
+ DBG_ASSERT( INetURLObject( OStringToOUString( sHelpId, RTL_TEXTENCODING_UTF8 ) ).GetProtocol() == INetProtocol::NotValid, "Wrong HelpId!" );
+ sId += OStringToOUString( sHelpId, RTL_TEXTENCODING_UTF8 );
+ xPropSet->setPropertyValue( uProp, makeAny( sId ) );
+ }
+
+ uno::Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
+ uno::Reference< awt::XControl > xControl( xContext->getServiceManager()->createInstanceWithContext(aControlName, xContext), UNO_QUERY);
+ if ( xControl.is() )
+ {
+ xControl->setModel( xCtrModel);
+
+ // Peer as Child to the FrameWindow
+ xCtrlContnr->addControl(rName, xControl);
+ uno::Reference< awt::XWindow > xCtrWin(xControl, UNO_QUERY );
+ xCtrWin->addFocusListener( mxBibGeneralPageFocusListener.get() );
+ rIndex = -1; // -> implies, that not found
+ for(sal_uInt16 i = 0; i < FIELD_COUNT; i++)
+ if(!aControls[i].is())
+ {
+ aControls[i] = xCtrWin;
+ rIndex = sal_Int16( i );
+ break;
+ }
+ // initially switch on the design mode - switch it off _after_ loading the form
+ xCtrWin->setVisible( true );
+ xControl->setDesignMode( true );
+
+ VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xControl->getPeer());
+ pWindow->set_grid_top_attach(rLabel.get_grid_top_attach());
+ pWindow->set_grid_left_attach(rLabel.get_grid_left_attach()+1);
+ pWindow->set_valign(VclAlign::Center);
+ rLabel.set_mnemonic_widget(pWindow);
+ if (&rLabel == pTitleFT)
+ pWindow->set_grid_width(3);
+ else
+ pWindow->set_hexpand(true);
+ rChildren.push_back(&rLabel);
+ rChildren.push_back(pWindow);
+ }
+ }
+ }
+ }
+ catch(const Exception&)
+ {
+ OSL_FAIL("BibGeneralPage::AddXControl: something went wrong!");
+ }
+ return xCtrModel.is();
+}
+
+void BibGeneralPage::InitFixedTexts()
+{
+ aFixedTexts[0] = pIdentifierFT;
+ aFixedTexts[1] = pAuthTypeFT;
+ aFixedTexts[2] = pYearFT;
+ aFixedTexts[3] = pAuthorFT;
+ aFixedTexts[4] = pTitleFT;
+ aFixedTexts[5] = pPublisherFT;
+ aFixedTexts[6] = pAddressFT;
+ aFixedTexts[7] = pISBNFT;
+ aFixedTexts[8] = pChapterFT;
+ aFixedTexts[9] = pPagesFT;
+
+ aFixedTexts[10] = pEditorFT;
+ aFixedTexts[11] = pEditionFT;
+ aFixedTexts[12] = pBooktitleFT;
+ aFixedTexts[13] = pVolumeFT;
+ aFixedTexts[14] = pHowpublishedFT;
+ aFixedTexts[15] = pOrganizationsFT;
+ aFixedTexts[16] = pInstitutionFT;
+ aFixedTexts[17] = pSchoolFT;
+ aFixedTexts[18] = pReportTypeFT;
+ aFixedTexts[19] = pMonthFT;
+
+ aFixedTexts[20] = pJournalFT;
+ aFixedTexts[21] = pNumberFT;
+ aFixedTexts[22] = pSeriesFT;
+ aFixedTexts[23] = pAnnoteFT;
+ aFixedTexts[24] = pNoteFT;
+ aFixedTexts[25] = pURLFT;
+
+ aFixedTexts[26] = pCustom1FT;
+ aFixedTexts[27] = pCustom2FT;
+ aFixedTexts[28] = pCustom3FT;
+ aFixedTexts[29] = pCustom4FT;
+ aFixedTexts[30] = pCustom5FT;
+
+ int i;
+
+ MnemonicGenerator aMnemonicGenerator;
+
+ OUString aFixedStrings[ FIELD_COUNT ];
+ for( i = 0 ; i < FIELD_COUNT ; ++i )
+ aFixedStrings[i] = aFixedTexts[i]->GetText();
+
+ // init mnemonics, first register all strings
+ for( i = 0 ; i < FIELD_COUNT ; ++i )
+ aMnemonicGenerator.RegisterMnemonic( aFixedStrings[ i ] );
+
+ // ... then get all strings
+ for( i = 0 ; i < FIELD_COUNT ; ++i )
+ aMnemonicGenerator.CreateMnemonic( aFixedStrings[ i ] );
+
+ // set texts
+ for( i = 0 ; i < FIELD_COUNT ; ++i )
+ aFixedTexts[ i ]->SetText( aFixedStrings[ i ] );
+}
+
+void BibGeneralPage::focusGained(const awt::FocusEvent& rEvent)
+{
+ Reference<awt::XWindow> xCtrWin(rEvent.Source, UNO_QUERY );
+ if(!xCtrWin.is())
+ return;
+
+ ::Size aOutSize = pScrolledWindow->getVisibleChildSize();
+ awt::Rectangle aRect = xCtrWin->getPosSize();
+ Point aOffset(pGrid->GetPosPixel());
+ long nX = aRect.X + aOffset.X();
+ if (nX < 0 || nX > aOutSize.Width())
+ {
+ pScrolledWindow->getHorzScrollBar().DoScroll(aRect.X);
+ }
+
+ long nY = aRect.Y + aOffset.Y();
+ if (nY < 0 || nY > aOutSize.Height())
+ {
+ pScrolledWindow->getVertScrollBar().DoScroll(aRect.Y);
+ }
+}
+
+void BibGeneralPage::focusLost()
+{
+ CommitActiveControl();
+}
+
+void BibGeneralPage::GetFocus()
+{
+ Reference< awt::XWindow >* pxControl = aControls;
+
+ for( int i = FIELD_COUNT ; i ; --i, ++pxControl )
+ {
+ if( pxControl->is() )
+ {
+ ( *pxControl )->setFocus();
+ return;
+ }
+ }
+
+ // fallback
+ GrabFocus();
+}
+
+bool BibGeneralPage::HandleShortCutKey( const KeyEvent& rKeyEvent )
+{
+ DBG_ASSERT( KEY_MOD2 == rKeyEvent.GetKeyCode().GetModifier(), "+BibGeneralPage::HandleShortCutKey(): this is not for me!" );
+
+ const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
+ const sal_Unicode c = rKeyEvent.GetCharCode();
+ bool bHandled = false;
+
+ sal_Int16 i;
+
+ std::vector<sal_Int16>::size_type nFocused = 0xFFFF; // index of focused in vector, no one focused initial
+ DBG_ASSERT( nFocused > 0, "*BibGeneralPage::HandleShortCutKey(): size_type works not as expected!" );
+
+ std::vector<sal_Int16> aMatchList;
+
+ for( i = 0 ; i < FIELD_COUNT ; ++i )
+ {
+ if( rI18nHelper.MatchMnemonic( aFixedTexts[ i ]->GetText(), c ) )
+ {
+ bHandled = true;
+ sal_Int16 nCtrlIndex = nFT2CtrlMap[ i ];
+
+ if( nCtrlIndex >= 0 )
+ { // store index of control
+ DBG_ASSERT( aControls[ nCtrlIndex ].is(), "-BibGeneralPage::HandleShortCutKey(): valid index and no control?" );
+
+ uno::Reference< awt::XControl > xControl( aControls[ nCtrlIndex ], UNO_QUERY );
+ DBG_ASSERT( xControl.is(), "-BibGeneralPage::HandleShortCutKey(): a control which is not a control!" );
+
+ VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xControl->getPeer() );
+
+ if( pWindow )
+ {
+ aMatchList.push_back( nCtrlIndex );
+ if( pWindow->HasChildPathFocus() )
+ { // save focused control
+ DBG_ASSERT( nFocused == 0xFFFF, "+BibGeneralPage::HandleShortCutKey(): more than one with focus?!" );
+ DBG_ASSERT( !aMatchList.empty(), "+BibGeneralPage::HandleShortCutKey(): push_back and no content?!" );
+ nFocused = aMatchList.size() - 1;
+ }
+ }
+ }
+ }
+ }
+
+ if( bHandled )
+ {
+ DBG_ASSERT( !aMatchList.empty(), "*BibGeneralPage::HandleShortCutKey(): be prepared to crash..." );
+
+ if( nFocused >= ( aMatchList.size() - 1 ) )
+ // >=... includes 0xFFFF
+ // no one or last focused, take first
+ nFocused = 0;
+ else
+ // take next one
+ nFocused++;
+
+ aControls[ aMatchList[ nFocused ] ]->setFocus();
+ }
+
+ return bHandled;
+}
+
+BibGeneralPageFocusListener::BibGeneralPageFocusListener(BibGeneralPage *pBibGeneralPage): mpBibGeneralPage(pBibGeneralPage)
+{}
+
+void BibGeneralPageFocusListener::focusGained( const css::awt::FocusEvent& e )
+{
+ mpBibGeneralPage->focusGained(e);
+}
+
+void BibGeneralPageFocusListener::focusLost( const css::awt::FocusEvent& )
+{
+ mpBibGeneralPage->focusLost();
+}
+
+void BibGeneralPageFocusListener::disposing( const css::lang::EventObject& )
+{}
+
+/* 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..8c95e6dad
--- /dev/null
+++ b/extensions/source/bibliography/general.hxx
@@ -0,0 +1,190 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_GENERAL_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_GENERAL_HXX
+
+#include <com/sun/star/awt/XFocusListener.hpp>
+#include <com/sun/star/awt/XControlContainer.hpp>
+#include <com/sun/star/form/XBoundComponent.hpp>
+#include <com/sun/star/sdbc/XRowSetListener.hpp>
+
+#include <vcl/layout.hxx>
+#include <vcl/tabpage.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include "bibshortcuthandler.hxx"
+
+
+class BibDataManager;
+#define TYPE_COUNT 22
+#define FIELD_COUNT 31
+
+/**
+ * We need to split off the listener because both it and the vcl::Window baseclass are ref-counted
+ */
+class BibGeneralPage;
+class BibGeneralPageFocusListener : public cppu::WeakAggImplHelper1 < css::awt::XFocusListener >
+{
+private:
+ VclPtr<BibGeneralPage> mpBibGeneralPage;
+public:
+ explicit BibGeneralPageFocusListener(BibGeneralPage *pBibGeneralPage);
+ virtual void SAL_CALL focusGained( const css::awt::FocusEvent& e ) override;
+ virtual void SAL_CALL focusLost( const css::awt::FocusEvent& e ) override;
+ virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override;
+
+};
+
+class BibGeneralPage : public TabPage, public BibShortCutHandler
+{
+ VclPtr<VclGrid> pGrid;
+ VclPtr<VclScrolledWindow> pScrolledWindow;
+
+ VclPtr<FixedText> pIdentifierFT;
+ VclPtr<FixedText> pAuthTypeFT;
+ VclPtr<FixedText> pYearFT;
+
+ VclPtr<FixedText> pAuthorFT;
+ VclPtr<FixedText> pTitleFT;
+
+ VclPtr<FixedText> pPublisherFT;
+ VclPtr<FixedText> pAddressFT;
+ VclPtr<FixedText> pISBNFT;
+
+ VclPtr<FixedText> pChapterFT;
+ VclPtr<FixedText> pPagesFT;
+
+ VclPtr<FixedText> pEditorFT;
+ VclPtr<FixedText> pEditionFT;
+
+ VclPtr<FixedText> pBooktitleFT;
+ VclPtr<FixedText> pVolumeFT;
+ VclPtr<FixedText> pHowpublishedFT;
+
+ VclPtr<FixedText> pOrganizationsFT;
+ VclPtr<FixedText> pInstitutionFT;
+ VclPtr<FixedText> pSchoolFT;
+
+ VclPtr<FixedText> pReportTypeFT;
+ VclPtr<FixedText> pMonthFT;
+
+ VclPtr<FixedText> pJournalFT;
+ VclPtr<FixedText> pNumberFT;
+ VclPtr<FixedText> pSeriesFT;
+
+ VclPtr<FixedText> pAnnoteFT;
+ VclPtr<FixedText> pNoteFT;
+ VclPtr<FixedText> pURLFT;
+
+ VclPtr<FixedText> pCustom1FT;
+ VclPtr<FixedText> pCustom2FT;
+ VclPtr<FixedText> pCustom3FT;
+ VclPtr<FixedText> pCustom4FT;
+ VclPtr<FixedText> pCustom5FT;
+
+ VclPtr<FixedText> aFixedTexts[ FIELD_COUNT ];
+ sal_Int16 nFT2CtrlMap[ FIELD_COUNT ];
+
+ css::uno::Reference< css::awt::XWindow >
+ aControls[ FIELD_COUNT ];
+
+ OUString sTableErrorString;
+
+ OUString sTypeColumnName;
+
+ css::uno::Reference< css::awt::XControlContainer >
+ xCtrlContnr;
+
+ css::uno::Reference< css::form::XBoundComponent >
+ xLBModel;
+
+ css::uno::Reference< css::sdbc::XRowSetListener >
+ xPosListener;
+
+ rtl::Reference<BibGeneralPageFocusListener> mxBibGeneralPageFocusListener;
+
+ BibDataManager* pDatMan;
+
+ bool
+ AddXControl( const OUString& rName, FixedText& rLabel, const OString& sHelpId,
+ sal_Int16& rIndex, std::vector<vcl::Window*>& rChildren );
+
+ void AddControlWithError( const OUString& rColumnName, FixedText& rLabel,
+ OUString& rErrorString,
+ const OString& sHelpId, sal_uInt16 nIndexInFTArray, std::vector<vcl::Window*>& rChildren );
+
+protected:
+ void InitFixedTexts(); // create mnemonics and set text an all fixed texts
+
+public:
+ BibGeneralPage(vcl::Window* pParent, BibDataManager* pDatMan);
+ virtual ~BibGeneralPage() override;
+ virtual void dispose() override;
+
+ inline const OUString& GetErrorString() const;
+
+ inline const css::uno::Reference< css::form::XBoundComponent >&
+ GetTypeListBoxModel() const;
+ inline const css::uno::Reference< css::awt::XControlContainer >&
+ GetControlContainer() const;
+
+ inline BibDataManager* GetDataManager();
+
+ void CommitActiveControl();
+
+ void RemoveListeners();
+
+ virtual void GetFocus() override;
+
+ virtual bool HandleShortCutKey( const KeyEvent& rKeyEvent ) override; // returns true, if key was handled
+
+ /// @throws css::uno::RuntimeException
+ void focusGained(const css::awt::FocusEvent& rEvent);
+ /// @throws css::uno::RuntimeException
+ void focusLost();
+
+};
+
+
+inline const OUString& BibGeneralPage::GetErrorString() const
+{
+ return sTableErrorString;
+}
+
+inline const css::uno::Reference< css::form::XBoundComponent >&
+ BibGeneralPage::GetTypeListBoxModel() const
+{
+ return xLBModel;
+}
+
+inline const css::uno::Reference< css::awt::XControlContainer >&
+ BibGeneralPage::GetControlContainer() const
+{
+ return xCtrlContnr;
+}
+
+inline BibDataManager* BibGeneralPage::GetDataManager()
+{
+ return pDatMan;
+}
+
+#endif
+
+
+/* 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..fecce24ae
--- /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( ) throw ()
+ {
+ OLoadListenerAdapter_Base::acquire();
+ }
+
+
+ void SAL_CALL OLoadListenerAdapter::release( ) throw ()
+ {
+ 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..6cb578063
--- /dev/null
+++ b/extensions/source/bibliography/loadlisteneradapter.hxx
@@ -0,0 +1,154 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_LOADLISTENERADAPTER_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_LOADLISTENERADAPTER_HXX
+
+#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( ) throw () = 0;
+ virtual void SAL_CALL release( ) throw () = 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( ) throw () override;
+ virtual void SAL_CALL release( ) throw () 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
+
+
+#endif // INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_LOADLISTENERADAPTER_HXX
+
+/* 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..d7726cbf9
--- /dev/null
+++ b/extensions/source/bibliography/toolbar.cxx
@@ -0,0 +1,626 @@
+/* -*- 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/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 <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, sal_uInt16 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, sal_uInt16 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, sal_uInt16 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, sal_uInt16 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")
+ , xSource(VclPtr<ComboBoxControl>::Create(this))
+ , pLbSource(xSource->get_widget())
+ , xQuery(VclPtr<EditControl>::Create(this))
+ , pEdQuery(xQuery->get_widget())
+ , pPopupMenu(VclPtr<PopupMenu>::Create())
+ , nMenuId(0)
+ , nSelMenuItem(0)
+ , aLayoutManager(aLink)
+ , nSymbolsSize(SFX_SYMBOLS_SIZE_SMALL)
+ , nOutStyle(0)
+{
+ SvtMiscOptions aSvtMiscOptions;
+ nSymbolsSize = aSvtMiscOptions.GetCurrentSymbolsSize();
+ nOutStyle = aSvtMiscOptions.GetToolboxStyle();
+
+ SetOutStyle(TOOLBOX_STYLE_FLAT);
+ 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();
+ 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);
+ BibToolBarListener* pQuery=new BibTBQueryMenuListener(this, aQueryURL.Complete, nTBC_BT_AUTOFILTER);
+ xDisp->addStatusListener(uno::Reference< frame::XStatusListener > (pQuery),aQueryURL);
+
+ for(ToolBox::ImplToolItems::size_type nPos=0;nPos<nCount;nPos++)
+ {
+ sal_uInt16 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()
+{
+ sal_uInt16 nId=GetCurItemId();
+
+ if (nId != nTBC_BT_AUTOFILTER)
+ {
+ SendDispatch(nId,Sequence<PropertyValue>() );
+ }
+ else
+ {
+ Sequence<PropertyValue> aPropVal(2);
+ PropertyValue* pPropertyVal = const_cast<PropertyValue*>(aPropVal.getConstArray());
+ pPropertyVal[0].Name="QueryText";
+ OUString aSelection = pEdQuery->get_text();
+ pPropertyVal[0].Value <<= aSelection;
+
+ pPropertyVal[1].Name="QueryField";
+ pPropertyVal[1].Value <<= aQueryField;
+ SendDispatch(nId,aPropVal);
+ }
+}
+
+void BibToolBar::SendDispatch(sal_uInt16 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()
+{
+ sal_uInt16 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()
+{
+ pPopupMenu->Clear();
+ nMenuId=0;
+}
+sal_uInt16 BibToolBar::InsertFilterItem(const OUString& aMenuEntry)
+{
+ nMenuId++;
+ pPopupMenu->InsertItem(nMenuId,aMenuEntry);
+
+ return nMenuId;
+}
+void BibToolBar::SelectFilterItem(sal_uInt16 nId)
+{
+ pPopupMenu->CheckItem(nId);
+ nSelMenuItem=nId;
+ aQueryField = MnemonicGenerator::EraseAllMnemonicChars( pPopupMenu->GetItemText(nId) );
+}
+
+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(2);
+ PropertyValue* pPropertyVal = const_cast<PropertyValue*>(aPropVal.getConstArray());
+ pPropertyVal[0].Name = "QueryText";
+ OUString aSelection = pEdQuery->get_text();
+ pPropertyVal[0].Value <<= aSelection;
+ pPropertyVal[1].Name="QueryField";
+ pPropertyVal[1].Value <<= 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(1);
+ PropertyValue* pPropertyVal = const_cast<PropertyValue*>(aPropVal.getConstArray());
+ pPropertyVal[0].Name = "DataSourceName";
+ OUString aEntry( MnemonicGenerator::EraseAllMnemonicChars( pLbSource->get_active_text() ) );
+ pPropertyVal[0].Value <<= aEntry;
+ SendDispatch(nTBC_SOURCE, aPropVal);
+}
+
+IMPL_LINK_NOARG( BibToolBar, MenuHdl, ToolBox*, void)
+{
+ sal_uInt16 nId=GetCurItemId();
+ if (nId != nTBC_BT_AUTOFILTER)
+ return;
+
+ EndSelection(); // before SetDropMode (SetDropMode calls SetItemImage)
+
+ SetItemDown(nTBC_BT_AUTOFILTER, true);
+ nId = pPopupMenu->Execute(this, GetItemRect(nTBC_BT_AUTOFILTER));
+
+
+ if(nId>0)
+ {
+ pPopupMenu->CheckItem(nSelMenuItem,false);
+ pPopupMenu->CheckItem(nId);
+ nSelMenuItem=nId;
+ aQueryField = MnemonicGenerator::EraseAllMnemonicChars( pPopupMenu->GetItemText(nId) );
+ Sequence<PropertyValue> aPropVal(2);
+ PropertyValue* pPropertyVal = const_cast<PropertyValue*>(aPropVal.getConstArray());
+ pPropertyVal[0].Name = "QueryText";
+ OUString aSelection = pEdQuery->get_text();
+ pPropertyVal[0].Value <<= aSelection;
+ pPropertyVal[1].Name="QueryField";
+ pPropertyVal[1].Value <<= 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;
+ }
+ else if ( nOutStyle != SvtMiscOptions().GetToolboxStyle() )
+ {
+ nOutStyle = SvtMiscOptions().GetToolboxStyle();
+ SetOutStyle( nOutStyle );
+ 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 ? OUStringLiteral(RID_EXTBMP_AUTOFILTER_SC) : OUStringLiteral(RID_EXTBMP_AUTOFILTER_LC)));
+ SetItemImage(nTBC_BT_FILTERCRIT, Image(StockImage::Yes, nSymbolsSize == SFX_SYMBOLS_SIZE_SMALL ? OUStringLiteral(RID_EXTBMP_FILTERCRIT_SC) : OUStringLiteral(RID_EXTBMP_FILTERCRIT_LC)));
+ SetItemImage(nTBC_BT_REMOVEFILTER, Image(StockImage::Yes, nSymbolsSize == SFX_SYMBOLS_SIZE_SMALL ? OUStringLiteral(RID_EXTBMP_REMOVE_FILTER_SORT_SC) : OUStringLiteral(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..e4aa8b852
--- /dev/null
+++ b/extensions/source/bibliography/toolbar.hxx
@@ -0,0 +1,220 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_TOOLBAR_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_BIBLIOGRAPHY_TOOLBAR_HXX
+
+#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:
+
+ sal_uInt16 nIndex;
+ OUString aCommand;
+
+protected:
+
+ VclPtr<BibToolBar> pToolBar;
+
+public:
+
+ BibToolBarListener(BibToolBar *pTB, const OUString& aStr, sal_uInt16 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, sal_uInt16 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, sal_uInt16 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, sal_uInt16 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;
+ ScopedVclPtr<PopupMenu> pPopupMenu;
+ sal_uInt16 nMenuId;
+ sal_uInt16 nSelMenuItem;
+ OUString aQueryField;
+ Link<void*,void> aLayoutManager;
+ sal_Int16 nSymbolsSize;
+ sal_Int16 nOutStyle;
+
+ sal_uInt16 nTBC_SOURCE;
+ sal_uInt16 nTBC_QUERY;
+ sal_uInt16 nTBC_BT_AUTOFILTER;
+ sal_uInt16 nTBC_BT_COL_ASSIGN;
+ sal_uInt16 nTBC_BT_CHANGESOURCE;
+ sal_uInt16 nTBC_BT_FILTERCRIT;
+ sal_uInt16 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;
+
+ sal_uInt16 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(sal_uInt16 nId, const css::uno::Sequence< css::beans::PropertyValue >& rArgs);
+};
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */