diff options
Diffstat (limited to 'extensions/source/bibliography')
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: */ |