summaryrefslogtreecommitdiffstats
path: root/dbaccess/source/ui/tabledesign
diff options
context:
space:
mode:
Diffstat (limited to 'dbaccess/source/ui/tabledesign')
-rw-r--r--dbaccess/source/ui/tabledesign/FieldDescGenWin.cxx149
-rw-r--r--dbaccess/source/ui/tabledesign/FieldDescGenWin.hxx74
-rw-r--r--dbaccess/source/ui/tabledesign/FieldDescriptions.cxx641
-rw-r--r--dbaccess/source/ui/tabledesign/TEditControl.cxx1633
-rw-r--r--dbaccess/source/ui/tabledesign/TEditControl.hxx205
-rw-r--r--dbaccess/source/ui/tabledesign/TableController.cxx1511
-rw-r--r--dbaccess/source/ui/tabledesign/TableDesignControl.cxx181
-rw-r--r--dbaccess/source/ui/tabledesign/TableDesignHelpBar.cxx105
-rw-r--r--dbaccess/source/ui/tabledesign/TableDesignView.cxx302
-rw-r--r--dbaccess/source/ui/tabledesign/TableFieldControl.cxx144
-rw-r--r--dbaccess/source/ui/tabledesign/TableFieldControl.hxx60
-rw-r--r--dbaccess/source/ui/tabledesign/TableFieldDescWin.cxx275
-rw-r--r--dbaccess/source/ui/tabledesign/TableFieldDescWin.hxx95
-rw-r--r--dbaccess/source/ui/tabledesign/TableRow.cxx193
-rw-r--r--dbaccess/source/ui/tabledesign/TableRowExchange.cxx68
-rw-r--r--dbaccess/source/ui/tabledesign/TableUndo.cxx352
-rw-r--r--dbaccess/source/ui/tabledesign/TableUndo.hxx138
17 files changed, 6126 insertions, 0 deletions
diff --git a/dbaccess/source/ui/tabledesign/FieldDescGenWin.cxx b/dbaccess/source/ui/tabledesign/FieldDescGenWin.cxx
new file mode 100644
index 000000000..1a052c190
--- /dev/null
+++ b/dbaccess/source/ui/tabledesign/FieldDescGenWin.cxx
@@ -0,0 +1,149 @@
+/* -*- 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 "FieldDescGenWin.hxx"
+#include <osl/diagnose.h>
+#include <helpids.h>
+#include <TableDesignHelpBar.hxx>
+#include "TableFieldControl.hxx"
+#include <TableDesignView.hxx>
+#include "TEditControl.hxx"
+
+using namespace dbaui;
+
+OFieldDescGenWin::OFieldDescGenWin( vcl::Window* pParent, OTableDesignHelpBar* pHelp ) :
+ TabPage( pParent, WB_3DLOOK | WB_DIALOGCONTROL )
+{
+ m_pFieldControl = VclPtr<OTableFieldControl>::Create(this,pHelp);
+ m_pFieldControl->SetHelpId(HID_TAB_DESIGN_FIELDCONTROL);
+ m_pFieldControl->Show();
+}
+
+OFieldDescGenWin::~OFieldDescGenWin()
+{
+ disposeOnce();
+}
+
+void OFieldDescGenWin::dispose()
+{
+ m_pFieldControl.disposeAndClear();
+ TabPage::dispose();
+}
+
+void OFieldDescGenWin::Init()
+{
+ OSL_ENSURE(GetEditorCtrl() != nullptr, "OFieldDescGenWin::Init : have no editor control !");
+
+ m_pFieldControl->Init();
+}
+
+void OFieldDescGenWin::Resize()
+{
+ m_pFieldControl->SetPosSizePixel(Point(0,0),GetSizePixel());
+ m_pFieldControl->Resize();
+}
+
+void OFieldDescGenWin::SetReadOnly( bool bReadOnly )
+{
+
+ m_pFieldControl->SetReadOnly(bReadOnly);
+}
+
+void OFieldDescGenWin::SetControlText( sal_uInt16 nControlId, const OUString& rText )
+{
+ // set texts of the controls
+ m_pFieldControl->SetControlText(nControlId,rText);
+}
+
+void OFieldDescGenWin::DisplayData( OFieldDescription* pFieldDescr )
+{
+ m_pFieldControl->DisplayData(pFieldDescr);
+}
+
+OTableEditorCtrl* OFieldDescGenWin::GetEditorCtrl()
+{
+ OTableDesignView* pDesignWin = static_cast<OTableDesignView*>(GetParent()->GetParent()->GetParent());
+ return pDesignWin->GetEditorCtrl();
+}
+
+void OFieldDescGenWin::SaveData( OFieldDescription* pFieldDescr )
+{
+ m_pFieldControl->SaveData(pFieldDescr);
+}
+
+void OFieldDescGenWin::GetFocus()
+{
+ // sets the focus to the control that was active last
+ TabPage::GetFocus();
+ if(m_pFieldControl)
+ m_pFieldControl->GetFocus();
+
+}
+
+void OFieldDescGenWin::LoseFocus()
+{
+ if (m_pFieldControl)
+ m_pFieldControl->LoseFocus();
+ TabPage::LoseFocus();
+}
+
+OUString OFieldDescGenWin::BoolStringPersistent(const OUString& rUIString) const
+{
+ return m_pFieldControl->BoolStringPersistent(rUIString);
+}
+
+OUString OFieldDescGenWin::BoolStringUI(const OUString& rPersistentString) const
+{
+ return m_pFieldControl->BoolStringUI(rPersistentString);
+}
+
+bool OFieldDescGenWin::isCopyAllowed()
+{
+ return (m_pFieldControl && m_pFieldControl->isCutAllowed());
+}
+
+bool OFieldDescGenWin::isCutAllowed()
+{
+ return (m_pFieldControl && m_pFieldControl->isCutAllowed());
+}
+
+bool OFieldDescGenWin::isPasteAllowed()
+{
+ return (m_pFieldControl && m_pFieldControl->isPasteAllowed());
+}
+
+void OFieldDescGenWin::cut()
+{
+ if(m_pFieldControl)
+ m_pFieldControl->cut();
+}
+
+void OFieldDescGenWin::copy()
+{
+ if(m_pFieldControl)
+ m_pFieldControl->copy();
+}
+
+void OFieldDescGenWin::paste()
+{
+ if(m_pFieldControl)
+ m_pFieldControl->paste();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/tabledesign/FieldDescGenWin.hxx b/dbaccess/source/ui/tabledesign/FieldDescGenWin.hxx
new file mode 100644
index 000000000..b43f8d1fa
--- /dev/null
+++ b/dbaccess/source/ui/tabledesign/FieldDescGenWin.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_DBACCESS_SOURCE_UI_TABLEDESIGN_FIELDDESCGENWIN_HXX
+#define INCLUDED_DBACCESS_SOURCE_UI_TABLEDESIGN_FIELDDESCGENWIN_HXX
+
+#include <vcl/tabpage.hxx>
+#include <IClipBoardTest.hxx>
+
+namespace dbaui
+{
+ class OTableDesignHelpBar;
+ class OFieldDescription;
+ class OTableFieldControl;
+ class OTableEditorCtrl;
+ class OFieldDescGenWin : public TabPage
+ ,public IClipboardTest
+ {
+
+ VclPtr<OTableFieldControl> m_pFieldControl;
+ protected:
+ virtual void Resize() override;
+
+ public:
+ OFieldDescGenWin( vcl::Window* pParent, OTableDesignHelpBar* pHelpBar );
+ virtual ~OFieldDescGenWin() override;
+ virtual void dispose() override;
+
+ virtual void GetFocus() override;
+ virtual void LoseFocus() override;
+ void Init();
+
+ void DisplayData( OFieldDescription* pFieldDescr );
+ void SaveData( OFieldDescription* pFieldDescr );
+ void SetControlText( sal_uInt16 nControlId, const OUString& rText );
+ void SetReadOnly( bool bReadOnly );
+ OTableEditorCtrl* GetEditorCtrl();
+
+ // short GetFormatCategory(OFieldDescription* pFieldDescr);
+ // gives you one of the CAT_xxx-values (CAT_NUMBER, CAT_DATE ...) belonging to the format specified by the field
+
+ OUString BoolStringPersistent(const OUString& rUIString) const;
+ OUString BoolStringUI(const OUString& rPersistentString) const;
+
+ // IClipboardTest
+ virtual bool isCutAllowed() override;
+ virtual bool isCopyAllowed() override;
+ virtual bool isPasteAllowed() override;
+
+ virtual void copy() override;
+ virtual void cut() override;
+ virtual void paste() override;
+
+ OTableFieldControl* getFieldControl() const { return m_pFieldControl; }
+ };
+}
+#endif // INCLUDED_DBACCESS_SOURCE_UI_TABLEDESIGN_FIELDDESCGENWIN_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/tabledesign/FieldDescriptions.cxx b/dbaccess/source/ui/tabledesign/FieldDescriptions.cxx
new file mode 100644
index 000000000..6882f1216
--- /dev/null
+++ b/dbaccess/source/ui/tabledesign/FieldDescriptions.cxx
@@ -0,0 +1,641 @@
+/* -*- 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 <FieldDescriptions.hxx>
+#include <tools/diagnose_ex.h>
+#include <strings.hxx>
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#include <comphelper/types.hxx>
+#include <comphelper/extract.hxx>
+#include <UITools.hxx>
+#include <com/sun/star/util/NumberFormat.hpp>
+
+#define DEFAULT_VARCHAR_PRECISION 100
+#define DEFAULT_OTHER_PRECISION 16
+#define DEFAULT_NUMERIC_PRECISION 5
+#define DEFAULT_NUMERIC_SCALE 0
+
+using namespace dbaui;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::util;
+
+OFieldDescription::OFieldDescription()
+ :m_pType()
+ ,m_nType(DataType::VARCHAR)
+ ,m_nPrecision(0)
+ ,m_nScale(0)
+ ,m_nIsNullable(ColumnValue::NULLABLE)
+ ,m_nFormatKey(0)
+ ,m_eHorJustify(SvxCellHorJustify::Standard)
+ ,m_bIsAutoIncrement(false)
+ ,m_bIsPrimaryKey(false)
+ ,m_bIsCurrency(false)
+ ,m_bHidden(false)
+{
+}
+
+OFieldDescription::OFieldDescription( const OFieldDescription& rDescr )
+ :m_aControlDefault(rDescr.m_aControlDefault)
+ ,m_aWidth(rDescr.m_aWidth)
+ ,m_aRelativePosition(rDescr.m_aRelativePosition)
+ ,m_pType(rDescr.m_pType)
+ ,m_xDest(rDescr.m_xDest)
+ ,m_xDestInfo(rDescr.m_xDestInfo)
+ ,m_sName(rDescr.m_sName)
+ ,m_sTypeName(rDescr.m_sTypeName)
+ ,m_sDescription(rDescr.m_sDescription)
+ ,m_sAutoIncrementValue(rDescr.m_sAutoIncrementValue)
+ ,m_nType(rDescr.m_nType)
+ ,m_nPrecision(rDescr.m_nPrecision)
+ ,m_nScale(rDescr.m_nScale)
+ ,m_nIsNullable(rDescr.m_nIsNullable)
+ ,m_nFormatKey(rDescr.m_nFormatKey)
+ ,m_eHorJustify(rDescr.m_eHorJustify)
+ ,m_bIsAutoIncrement(rDescr.m_bIsAutoIncrement)
+ ,m_bIsPrimaryKey(rDescr.m_bIsPrimaryKey)
+ ,m_bIsCurrency(rDescr.m_bIsCurrency)
+ ,m_bHidden(rDescr.m_bHidden)
+{
+}
+
+OFieldDescription::~OFieldDescription()
+{
+}
+
+OFieldDescription::OFieldDescription(const Reference< XPropertySet >& xAffectedCol,bool _bUseAsDest)
+ :m_pType()
+ ,m_nType(DataType::VARCHAR)
+ ,m_nPrecision(0)
+ ,m_nScale(0)
+ ,m_nIsNullable(ColumnValue::NULLABLE)
+ ,m_nFormatKey(0)
+ ,m_eHorJustify(SvxCellHorJustify::Standard)
+ ,m_bIsAutoIncrement(false)
+ ,m_bIsPrimaryKey(false)
+ ,m_bIsCurrency(false)
+ ,m_bHidden(false)
+{
+ OSL_ENSURE(xAffectedCol.is(),"PropertySet can not be null!");
+ if ( !xAffectedCol.is() )
+ return;
+
+ if ( _bUseAsDest )
+ {
+ m_xDest = xAffectedCol;
+ m_xDestInfo = xAffectedCol->getPropertySetInfo();
+ }
+ else
+ {
+ try
+ {
+ Reference<XPropertySetInfo> xPropSetInfo = xAffectedCol->getPropertySetInfo();
+ if(xPropSetInfo->hasPropertyByName(PROPERTY_NAME))
+ SetName(::comphelper::getString(xAffectedCol->getPropertyValue(PROPERTY_NAME)));
+ if(xPropSetInfo->hasPropertyByName(PROPERTY_DESCRIPTION))
+ SetDescription(::comphelper::getString(xAffectedCol->getPropertyValue(PROPERTY_DESCRIPTION)));
+ if(xPropSetInfo->hasPropertyByName(PROPERTY_HELPTEXT))
+ {
+ OUString sHelpText;
+ xAffectedCol->getPropertyValue(PROPERTY_HELPTEXT) >>= sHelpText;
+ SetHelpText(sHelpText);
+ }
+ if(xPropSetInfo->hasPropertyByName(PROPERTY_DEFAULTVALUE))
+ SetDefaultValue( xAffectedCol->getPropertyValue(PROPERTY_DEFAULTVALUE) );
+
+ if(xPropSetInfo->hasPropertyByName(PROPERTY_CONTROLDEFAULT))
+ SetControlDefault( xAffectedCol->getPropertyValue(PROPERTY_CONTROLDEFAULT) );
+
+ if(xPropSetInfo->hasPropertyByName(PROPERTY_AUTOINCREMENTCREATION))
+ SetAutoIncrementValue(::comphelper::getString(xAffectedCol->getPropertyValue(PROPERTY_AUTOINCREMENTCREATION)));
+ if(xPropSetInfo->hasPropertyByName(PROPERTY_TYPE))
+ SetTypeValue(::comphelper::getINT32(xAffectedCol->getPropertyValue(PROPERTY_TYPE)));
+ if (xPropSetInfo->hasPropertyByName(PROPERTY_TYPENAME))
+ SetTypeName(::comphelper::getString(xAffectedCol->getPropertyValue(PROPERTY_TYPENAME)));
+ if(xPropSetInfo->hasPropertyByName(PROPERTY_PRECISION))
+ SetPrecision(::comphelper::getINT32(xAffectedCol->getPropertyValue(PROPERTY_PRECISION)));
+ if(xPropSetInfo->hasPropertyByName(PROPERTY_SCALE))
+ SetScale(::comphelper::getINT32(xAffectedCol->getPropertyValue(PROPERTY_SCALE)));
+ if(xPropSetInfo->hasPropertyByName(PROPERTY_ISNULLABLE))
+ SetIsNullable(::comphelper::getINT32(xAffectedCol->getPropertyValue(PROPERTY_ISNULLABLE)));
+ if(xPropSetInfo->hasPropertyByName(PROPERTY_FORMATKEY))
+ {
+ const Any aValue = xAffectedCol->getPropertyValue(PROPERTY_FORMATKEY);
+ if ( aValue.hasValue() )
+ SetFormatKey(::comphelper::getINT32(aValue));
+ }
+ if(xPropSetInfo->hasPropertyByName(PROPERTY_RELATIVEPOSITION))
+ m_aRelativePosition = xAffectedCol->getPropertyValue(PROPERTY_RELATIVEPOSITION);
+ if(xPropSetInfo->hasPropertyByName(PROPERTY_WIDTH))
+ m_aWidth = xAffectedCol->getPropertyValue(PROPERTY_WIDTH);
+ if(xPropSetInfo->hasPropertyByName(PROPERTY_HIDDEN))
+ xAffectedCol->getPropertyValue(PROPERTY_HIDDEN) >>= m_bHidden;
+ if(xPropSetInfo->hasPropertyByName(PROPERTY_ALIGN))
+ {
+ const Any aValue = xAffectedCol->getPropertyValue(PROPERTY_ALIGN);
+ if ( aValue.hasValue() )
+ SetHorJustify( ::dbaui::mapTextJustify(::comphelper::getINT32(aValue)));
+ }
+ if(xPropSetInfo->hasPropertyByName(PROPERTY_ISAUTOINCREMENT))
+ SetAutoIncrement(::cppu::any2bool(xAffectedCol->getPropertyValue(PROPERTY_ISAUTOINCREMENT)));
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+ }
+}
+
+void OFieldDescription::FillFromTypeInfo(const TOTypeInfoSP& _pType,bool _bForce,bool _bReset)
+{
+ TOTypeInfoSP pOldType = getTypeInfo();
+ if ( _pType == pOldType )
+ return;
+
+ // reset type depending information
+ if ( _bReset )
+ {
+ SetFormatKey(0);
+ SetControlDefault(Any());
+ }
+
+ bool bForce = _bForce || pOldType.get() == nullptr || pOldType->nType != _pType->nType;
+ switch ( _pType->nType )
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ if ( bForce )
+ {
+ sal_Int32 nPrec = DEFAULT_VARCHAR_PRECISION;
+ if ( GetPrecision() )
+ nPrec = GetPrecision();
+ SetPrecision(std::min<sal_Int32>(nPrec,_pType->nPrecision));
+ }
+ break;
+ case DataType::TIMESTAMP:
+ if ( bForce && _pType->nMaximumScale)
+ {
+ SetScale(std::min<sal_Int32>(GetScale() ? GetScale() : DEFAULT_NUMERIC_SCALE,_pType->nMaximumScale));
+ }
+ break;
+ default:
+ if ( bForce )
+ {
+ sal_Int32 nPrec = DEFAULT_OTHER_PRECISION;
+ switch ( _pType->nType )
+ {
+ case DataType::BIT:
+ case DataType::BLOB:
+ case DataType::CLOB:
+ nPrec = _pType->nPrecision;
+ break;
+ default:
+ if ( GetPrecision() )
+ nPrec = GetPrecision();
+ break;
+ }
+
+ if ( _pType->nPrecision )
+ SetPrecision(std::min<sal_Int32>(nPrec ? nPrec : DEFAULT_NUMERIC_PRECISION,_pType->nPrecision));
+ if ( _pType->nMaximumScale )
+ SetScale(std::min<sal_Int32>(GetScale() ? GetScale() : DEFAULT_NUMERIC_SCALE,_pType->nMaximumScale));
+ }
+ }
+ if ( _pType->aCreateParams.isEmpty() )
+ {
+ SetPrecision(_pType->nPrecision);
+ SetScale(_pType->nMinimumScale);
+ }
+ if ( !_pType->bNullable && IsNullable() )
+ SetIsNullable(ColumnValue::NO_NULLS);
+ if ( !_pType->bAutoIncrement && IsAutoIncrement() )
+ SetAutoIncrement(false);
+ SetCurrency( _pType->bCurrency );
+ SetType(_pType);
+ SetTypeName(_pType->aTypeName);
+}
+
+void OFieldDescription::SetName(const OUString& _rName)
+{
+ try
+ {
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_NAME) )
+ m_xDest->setPropertyValue(PROPERTY_NAME,makeAny(_rName));
+ else
+ m_sName = _rName;
+ }
+ catch(const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+void OFieldDescription::SetHelpText(const OUString& _sHelpText)
+{
+ try
+ {
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_HELPTEXT) )
+ m_xDest->setPropertyValue(PROPERTY_HELPTEXT,makeAny(_sHelpText));
+ else
+ m_sHelpText = _sHelpText;
+ }
+ catch(const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+void OFieldDescription::SetDescription(const OUString& _rDescription)
+{
+ try
+ {
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_DESCRIPTION) )
+ m_xDest->setPropertyValue(PROPERTY_DESCRIPTION,makeAny(_rDescription));
+ else
+ m_sDescription = _rDescription;
+ }
+ catch(const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+void OFieldDescription::SetDefaultValue(const Any& _rDefaultValue)
+{
+ try
+ {
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_DEFAULTVALUE) )
+ m_xDest->setPropertyValue(PROPERTY_DEFAULTVALUE, _rDefaultValue);
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+void OFieldDescription::SetControlDefault(const Any& _rControlDefault)
+{
+ try
+ {
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_CONTROLDEFAULT) )
+ m_xDest->setPropertyValue(PROPERTY_CONTROLDEFAULT, _rControlDefault);
+ else
+ m_aControlDefault = _rControlDefault;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+void OFieldDescription::SetAutoIncrementValue(const OUString& _sAutoIncValue)
+{
+ try
+ {
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_AUTOINCREMENTCREATION) )
+ m_xDest->setPropertyValue(PROPERTY_AUTOINCREMENTCREATION,makeAny(_sAutoIncValue));
+ else
+ m_sAutoIncrementValue = _sAutoIncValue;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+void OFieldDescription::SetType(const TOTypeInfoSP& _pType)
+{
+ m_pType = _pType;
+ if ( !m_pType )
+ return;
+
+ try
+ {
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_TYPE) )
+ m_xDest->setPropertyValue(PROPERTY_TYPE,makeAny(m_pType->nType));
+ else
+ m_nType = m_pType->nType;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+void OFieldDescription::SetTypeValue(sal_Int32 _nType)
+{
+ try
+ {
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_TYPE) )
+ m_xDest->setPropertyValue(PROPERTY_TYPE,makeAny(_nType));
+ else
+ {
+ m_nType = _nType;
+ OSL_ENSURE(!m_pType,"Invalid call here!");
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+void OFieldDescription::SetPrecision(sal_Int32 _rPrecision)
+{
+ try
+ {
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_PRECISION) )
+ m_xDest->setPropertyValue(PROPERTY_PRECISION,makeAny(_rPrecision));
+ else
+ m_nPrecision = _rPrecision;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+void OFieldDescription::SetScale(sal_Int32 _rScale)
+{
+ try
+ {
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_SCALE) )
+ m_xDest->setPropertyValue(PROPERTY_SCALE,makeAny(_rScale));
+ else
+ m_nScale = _rScale;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+void OFieldDescription::SetIsNullable(sal_Int32 _rIsNullable)
+{
+ try
+ {
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_ISNULLABLE) )
+ m_xDest->setPropertyValue(PROPERTY_ISNULLABLE,makeAny(_rIsNullable));
+ else
+ m_nIsNullable = _rIsNullable;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+void OFieldDescription::SetFormatKey(sal_Int32 _rFormatKey)
+{
+ try
+ {
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_FORMATKEY) )
+ m_xDest->setPropertyValue(PROPERTY_FORMATKEY,makeAny(_rFormatKey));
+ else
+ m_nFormatKey = _rFormatKey;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+void OFieldDescription::SetHorJustify(const SvxCellHorJustify& _rHorJustify)
+{
+ try
+ {
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_ALIGN) )
+ m_xDest->setPropertyValue(PROPERTY_ALIGN,makeAny( dbaui::mapTextAllign(_rHorJustify)));
+ else
+ m_eHorJustify = _rHorJustify;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+void OFieldDescription::SetAutoIncrement(bool _bAuto)
+{
+ try
+ {
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_ISAUTOINCREMENT) )
+ m_xDest->setPropertyValue(PROPERTY_ISAUTOINCREMENT,makeAny(_bAuto));
+ else
+ m_bIsAutoIncrement = _bAuto;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+void OFieldDescription::SetPrimaryKey(bool _bPKey)
+{
+ m_bIsPrimaryKey = _bPKey;
+ if ( _bPKey )
+ SetIsNullable(css::sdbc::ColumnValue::NO_NULLS);
+}
+
+void OFieldDescription::SetCurrency(bool _bIsCurrency)
+{
+ m_bIsCurrency = _bIsCurrency;
+}
+
+OUString OFieldDescription::GetName() const
+{
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_NAME) )
+ return ::comphelper::getString(m_xDest->getPropertyValue(PROPERTY_NAME));
+ else
+ return m_sName;
+}
+
+OUString OFieldDescription::GetDescription() const
+{
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_DESCRIPTION) )
+ return ::comphelper::getString(m_xDest->getPropertyValue(PROPERTY_DESCRIPTION));
+ else
+ return m_sDescription;
+}
+
+OUString OFieldDescription::GetHelpText() const
+{
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_HELPTEXT) )
+ return ::comphelper::getString(m_xDest->getPropertyValue(PROPERTY_HELPTEXT));
+ else
+ return m_sHelpText;
+}
+
+css::uno::Any OFieldDescription::GetControlDefault() const
+{
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_CONTROLDEFAULT) )
+ return m_xDest->getPropertyValue(PROPERTY_CONTROLDEFAULT);
+ else
+ return m_aControlDefault;
+}
+
+OUString OFieldDescription::GetAutoIncrementValue() const
+{
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_AUTOINCREMENTCREATION) )
+ return ::comphelper::getString(m_xDest->getPropertyValue(PROPERTY_AUTOINCREMENTCREATION));
+ else
+ return m_sAutoIncrementValue;
+}
+
+sal_Int32 OFieldDescription::GetType() const
+{
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_TYPE) )
+ return ::comphelper::getINT32(m_xDest->getPropertyValue(PROPERTY_TYPE));
+ else
+ return m_pType ? m_pType->nType : m_nType;
+}
+
+OUString OFieldDescription::GetTypeName() const
+{
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_TYPENAME) )
+ return ::comphelper::getString(m_xDest->getPropertyValue(PROPERTY_TYPENAME));
+ else
+ return m_pType ? m_pType->aTypeName : m_sTypeName;
+}
+
+sal_Int32 OFieldDescription::GetPrecision() const
+{
+ sal_Int32 nPrec = m_nPrecision;
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_PRECISION) )
+ nPrec = ::comphelper::getINT32(m_xDest->getPropertyValue(PROPERTY_PRECISION));
+
+ TOTypeInfoSP pTypeInfo = getTypeInfo();
+ if ( pTypeInfo )
+ {
+ switch ( pTypeInfo->nType )
+ {
+ case DataType::TINYINT:
+ case DataType::SMALLINT:
+ case DataType::INTEGER:
+ case DataType::BIGINT:
+ if ( !nPrec )
+ nPrec = pTypeInfo->nPrecision;
+ break;
+ }
+ }
+
+ return nPrec;
+}
+
+sal_Int32 OFieldDescription::GetScale() const
+{
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_SCALE) )
+ return ::comphelper::getINT32(m_xDest->getPropertyValue(PROPERTY_SCALE));
+ else
+ return m_nScale;
+}
+
+sal_Int32 OFieldDescription::GetIsNullable() const
+{
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_ISNULLABLE) )
+ return ::comphelper::getINT32(m_xDest->getPropertyValue(PROPERTY_ISNULLABLE));
+ else
+ return m_nIsNullable;
+}
+
+sal_Int32 OFieldDescription::GetFormatKey() const
+{
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_FORMATKEY) )
+ return ::comphelper::getINT32(m_xDest->getPropertyValue(PROPERTY_FORMATKEY));
+ else
+ return m_nFormatKey;
+}
+
+SvxCellHorJustify OFieldDescription::GetHorJustify() const
+{
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_ALIGN) )
+ return ::dbaui::mapTextJustify(::comphelper::getINT32(m_xDest->getPropertyValue(PROPERTY_ALIGN)));
+ else
+ return m_eHorJustify;
+}
+
+
+TOTypeInfoSP OFieldDescription::getSpecialTypeInfo() const
+{
+ TOTypeInfoSP pSpecialType = std::make_shared<OTypeInfo>();
+ *pSpecialType = *m_pType;
+ pSpecialType->nPrecision = GetPrecision();
+ pSpecialType->nMaximumScale = static_cast<sal_Int16>(GetScale());
+ pSpecialType->bAutoIncrement = IsAutoIncrement(); // http://dba.openoffice.org/issues/show_bug.cgi?id=115398 fixed by ludob
+ return pSpecialType;
+}
+
+bool OFieldDescription::IsAutoIncrement() const
+{
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_ISAUTOINCREMENT) )
+ return ::cppu::any2bool(m_xDest->getPropertyValue(PROPERTY_ISAUTOINCREMENT));
+ else
+ return m_bIsAutoIncrement;
+}
+
+
+bool OFieldDescription::IsNullable() const
+{
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_ISNULLABLE) )
+ return ::comphelper::getINT32(m_xDest->getPropertyValue(PROPERTY_ISNULLABLE)) == css::sdbc::ColumnValue::NULLABLE;
+ else
+ return m_nIsNullable == css::sdbc::ColumnValue::NULLABLE;
+}
+
+void OFieldDescription::SetTypeName(const OUString& _sTypeName)
+{
+ try
+ {
+ if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_TYPENAME) )
+ m_xDest->setPropertyValue(PROPERTY_TYPENAME,makeAny(_sTypeName));
+ else
+ m_sTypeName = _sTypeName;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+void OFieldDescription::copyColumnSettingsTo(const Reference< XPropertySet >& _rxColumn)
+{
+ if ( !_rxColumn.is() )
+ return;
+
+ Reference<XPropertySetInfo> xInfo = _rxColumn->getPropertySetInfo();
+
+ if ( GetFormatKey() != NumberFormat::ALL && xInfo->hasPropertyByName(PROPERTY_FORMATKEY) )
+ _rxColumn->setPropertyValue(PROPERTY_FORMATKEY,makeAny(GetFormatKey()));
+ if ( GetHorJustify() != SvxCellHorJustify::Standard && xInfo->hasPropertyByName(PROPERTY_ALIGN) )
+ _rxColumn->setPropertyValue(PROPERTY_ALIGN,makeAny(dbaui::mapTextAllign(GetHorJustify())));
+ if ( !GetHelpText().isEmpty() && xInfo->hasPropertyByName(PROPERTY_HELPTEXT) )
+ _rxColumn->setPropertyValue(PROPERTY_HELPTEXT,makeAny(GetHelpText()));
+ if ( GetControlDefault().hasValue() && xInfo->hasPropertyByName(PROPERTY_CONTROLDEFAULT) )
+ _rxColumn->setPropertyValue(PROPERTY_CONTROLDEFAULT,GetControlDefault());
+
+ if(xInfo->hasPropertyByName(PROPERTY_RELATIVEPOSITION))
+ _rxColumn->setPropertyValue(PROPERTY_RELATIVEPOSITION,m_aRelativePosition);
+ if(xInfo->hasPropertyByName(PROPERTY_WIDTH))
+ _rxColumn->setPropertyValue(PROPERTY_WIDTH,m_aWidth);
+ if(xInfo->hasPropertyByName(PROPERTY_HIDDEN))
+ _rxColumn->setPropertyValue(PROPERTY_HIDDEN,makeAny(m_bHidden));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/tabledesign/TEditControl.cxx b/dbaccess/source/ui/tabledesign/TEditControl.cxx
new file mode 100644
index 000000000..6f5128faa
--- /dev/null
+++ b/dbaccess/source/ui/tabledesign/TEditControl.cxx
@@ -0,0 +1,1633 @@
+/* -*- 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 "TEditControl.hxx"
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#include <com/sun/star/sdbc/SQLException.hpp>
+#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <core_resource.hxx>
+#include <strings.hrc>
+#include <strings.hxx>
+#include <helpids.h>
+#include <comphelper/types.hxx>
+#include <FieldDescControl.hxx>
+#include <FieldDescriptions.hxx>
+#include "TableUndo.hxx"
+#include <TableController.hxx>
+#include <connectivity/dbmetadata.hxx>
+#include <connectivity/dbtools.hxx>
+#include <SqlNameEdit.hxx>
+#include <TableRowExchange.hxx>
+#include <sot/storage.hxx>
+#include <svx/svxids.hrc>
+#include <UITools.hxx>
+#include "TableFieldControl.hxx"
+#include <dsntypes.hxx>
+#include <vcl/commandevent.hxx>
+#include <vcl/svapp.hxx>
+
+using namespace ::dbaui;
+using namespace ::comphelper;
+using namespace ::svt;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::sdb;
+
+
+#define HANDLE_ID 0
+
+// default field widths
+#define FIELDNAME_WIDTH 100
+#define FIELDTYPE_WIDTH 150
+#define FIELDDESCR_WIDTH 300
+
+// Maximum length in description field
+#define MAX_DESCR_LEN 256
+
+OTableEditorCtrl::ClipboardInvalidator::ClipboardInvalidator(OTableEditorCtrl* _pOwner)
+: m_pOwner(_pOwner)
+{
+
+ m_aInvalidateTimer.SetTimeout(500);
+ m_aInvalidateTimer.SetInvokeHandler(LINK(this, OTableEditorCtrl::ClipboardInvalidator, OnInvalidate));
+ m_aInvalidateTimer.Start();
+}
+
+OTableEditorCtrl::ClipboardInvalidator::~ClipboardInvalidator()
+{
+ m_aInvalidateTimer.Stop();
+}
+
+void OTableEditorCtrl::ClipboardInvalidator::Stop()
+{
+ m_aInvalidateTimer.Stop();
+}
+
+IMPL_LINK_NOARG(OTableEditorCtrl::ClipboardInvalidator, OnInvalidate, Timer *, void)
+{
+ m_pOwner->GetView()->getController().InvalidateFeature(SID_CUT);
+ m_pOwner->GetView()->getController().InvalidateFeature(SID_COPY);
+ m_pOwner->GetView()->getController().InvalidateFeature(SID_PASTE);
+}
+
+void OTableEditorCtrl::Init()
+{
+ OTableRowView::Init();
+
+ // Should it be opened ReadOnly?
+ bool bRead(GetView()->getController().isReadOnly());
+
+ SetReadOnly( bRead );
+
+ // Insert the columns
+ InsertDataColumn( FIELD_NAME, DBA_RES(STR_TAB_FIELD_COLUMN_NAME), FIELDNAME_WIDTH );
+
+ InsertDataColumn( FIELD_TYPE, DBA_RES(STR_TAB_FIELD_COLUMN_DATATYPE), FIELDTYPE_WIDTH );
+
+ ::dbaccess::ODsnTypeCollection aDsnTypes(GetView()->getController().getORB());
+ bool bShowColumnDescription = aDsnTypes.supportsColumnDescription(::comphelper::getString(GetView()->getController().getDataSource()->getPropertyValue(PROPERTY_URL)));
+ InsertDataColumn( HELP_TEXT, DBA_RES(STR_TAB_HELP_TEXT), bShowColumnDescription ? FIELDTYPE_WIDTH : FIELDDESCR_WIDTH );
+
+ if ( bShowColumnDescription )
+ {
+ InsertDataColumn( COLUMN_DESCRIPTION, DBA_RES(STR_COLUMN_DESCRIPTION), FIELDTYPE_WIDTH );
+ }
+
+ InitCellController();
+
+ // Insert the rows
+ RowInserted(0, m_pRowList->size());
+}
+
+OTableEditorCtrl::OTableEditorCtrl(vcl::Window* pWindow)
+ :OTableRowView(pWindow)
+ ,pNameCell(nullptr)
+ ,pTypeCell(nullptr)
+ ,pHelpTextCell(nullptr)
+ ,pDescrCell(nullptr)
+ ,pDescrWin(nullptr)
+ ,nCutEvent(nullptr)
+ ,nPasteEvent(nullptr)
+ ,nDeleteEvent(nullptr)
+ ,nInsNewRowsEvent(nullptr)
+ ,nInvalidateTypeEvent(nullptr)
+ ,m_eChildFocus(NONE)
+ ,nOldDataPos(-1)
+ ,bReadOnly(true)
+ ,m_aInvalidate(this)
+{
+
+ SetHelpId(HID_TABDESIGN_BACKGROUND);
+ GetDataWindow().SetHelpId(HID_CTL_TABLEEDIT);
+
+ m_pRowList = &GetView()->getController().getRows();
+ m_nDataPos = 0;
+}
+
+SfxUndoManager& OTableEditorCtrl::GetUndoManager() const
+{
+ return GetView()->getController().GetUndoManager();
+}
+
+
+void OTableEditorCtrl::SetReadOnly( bool bRead )
+{
+ // nothing to do?
+ if (bRead == IsReadOnly())
+ // This check is important, as the underlying Def may be unnecessarily locked or unlocked
+ // or worse, this action may not be reversed afterwards
+ return;
+
+ bReadOnly = bRead;
+
+ // Disable active cells
+ long nRow(GetCurRow());
+ sal_uInt16 nCol(GetCurColumnId());
+ DeactivateCell();
+
+ // Select the correct Browsers cursor
+ BrowserMode nMode(BrowserMode::COLUMNSELECTION | BrowserMode::MULTISELECTION | BrowserMode::KEEPHIGHLIGHT |
+ BrowserMode::HLINES | BrowserMode::VLINES|BrowserMode::AUTOSIZE_LASTCOL);
+ if( !bReadOnly )
+ nMode |= BrowserMode::HIDECURSOR;
+ SetMode(nMode);
+
+ if( !bReadOnly )
+ ActivateCell( nRow, nCol );
+}
+
+void OTableEditorCtrl::InitCellController()
+{
+ // Cell Field name
+ sal_Int32 nMaxTextLen = EDIT_NOLIMIT;
+ OUString sExtraNameChars;
+ Reference<XConnection> xCon;
+ try
+ {
+ xCon = GetView()->getController().getConnection();
+ Reference< XDatabaseMetaData> xMetaData = xCon.is() ? xCon->getMetaData() : Reference< XDatabaseMetaData>();
+
+ nMaxTextLen = xMetaData.is() ? xMetaData->getMaxColumnNameLength() : 0;
+
+ if( nMaxTextLen == 0 )
+ nMaxTextLen = EDIT_NOLIMIT;
+ sExtraNameChars = xMetaData.is() ? xMetaData->getExtraNameCharacters() : OUString();
+
+ }
+ catch(SQLException&)
+ {
+ OSL_FAIL("getMaxColumnNameLength");
+ }
+
+ pNameCell = VclPtr<OSQLNameEdit>::Create(&GetDataWindow(), WB_LEFT, sExtraNameChars);
+ pNameCell->SetMaxTextLen( nMaxTextLen );
+ pNameCell->setCheck( isSQL92CheckEnabled(xCon) );
+
+ // Cell type
+ pTypeCell = VclPtr<ListBoxControl>::Create( &GetDataWindow() );
+
+ // Cell description
+ pDescrCell = VclPtr<Edit>::Create( &GetDataWindow(), WB_LEFT );
+ pDescrCell->SetMaxTextLen( MAX_DESCR_LEN );
+
+ pHelpTextCell = VclPtr<Edit>::Create( &GetDataWindow(), WB_LEFT );
+ pHelpTextCell->SetMaxTextLen( MAX_DESCR_LEN );
+
+ pNameCell->SetHelpId(HID_TABDESIGN_NAMECELL);
+ pTypeCell->SetHelpId(HID_TABDESIGN_TYPECELL);
+ pDescrCell->SetHelpId(HID_TABDESIGN_COMMENTCELL);
+ pHelpTextCell->SetHelpId(HID_TABDESIGN_HELPTEXT);
+
+ Size aHeight;
+ const Control* pControls[] = { pTypeCell,pDescrCell,pNameCell,pHelpTextCell};
+ for(const Control* pControl : pControls)
+ {
+ const Size aTemp(pControl->GetOptimalSize());
+ if ( aTemp.Height() > aHeight.Height() )
+ aHeight.setHeight( aTemp.Height() );
+ }
+ SetDataRowHeight(aHeight.Height());
+
+ ClearModified();
+}
+
+void OTableEditorCtrl::ClearModified()
+{
+ pNameCell->ClearModifyFlag();
+ pDescrCell->ClearModifyFlag();
+ pHelpTextCell->ClearModifyFlag();
+ pTypeCell->get_widget().save_value();
+}
+
+OTableEditorCtrl::~OTableEditorCtrl()
+{
+ disposeOnce();
+}
+
+void OTableEditorCtrl::dispose()
+{
+ // Reset the Undo-Manager
+ GetUndoManager().Clear();
+
+ m_aInvalidate.Stop();
+
+ // Take possible Events from the queue
+ if( nCutEvent )
+ Application::RemoveUserEvent( nCutEvent );
+ if( nPasteEvent )
+ Application::RemoveUserEvent( nPasteEvent );
+ if( nDeleteEvent )
+ Application::RemoveUserEvent( nDeleteEvent );
+ if( nInsNewRowsEvent )
+ Application::RemoveUserEvent( nInsNewRowsEvent );
+ if( nInvalidateTypeEvent )
+ Application::RemoveUserEvent( nInvalidateTypeEvent );
+
+ // Delete the control types
+ pNameCell.disposeAndClear();
+ pTypeCell.disposeAndClear();
+ pDescrCell.disposeAndClear();
+ pHelpTextCell.disposeAndClear();
+ pDescrWin.clear();
+ OTableRowView::dispose();
+}
+
+bool OTableEditorCtrl::SetDataPtr( long nRow )
+{
+ if(nRow == -1)
+ return false;
+
+ OSL_ENSURE(nRow < static_cast<long>(m_pRowList->size()),"Row is greater than size!");
+ if(nRow >= static_cast<long>(m_pRowList->size()))
+ return false;
+ pActRow = (*m_pRowList)[nRow];
+ return pActRow != nullptr;
+}
+
+bool OTableEditorCtrl::SeekRow(long _nRow)
+{
+ // Call the Base class to remember which row must be repainted
+ EditBrowseBox::SeekRow(_nRow);
+
+ m_nCurrentPos = _nRow;
+ return SetDataPtr(_nRow);
+}
+
+void OTableEditorCtrl::PaintCell(OutputDevice& rDev, const tools::Rectangle& rRect,
+ sal_uInt16 nColumnId ) const
+{
+ const OUString aText( GetCellText( m_nCurrentPos, nColumnId ));
+
+ rDev.Push( PushFlags::CLIPREGION );
+ rDev.SetClipRegion(vcl::Region(rRect));
+ rDev.DrawText( rRect, aText, DrawTextFlags::Left | DrawTextFlags::VCenter );
+ rDev.Pop();
+}
+
+CellController* OTableEditorCtrl::GetController(long nRow, sal_uInt16 nColumnId)
+{
+ // If EditorCtrl is ReadOnly, editing is forbidden
+ Reference<XPropertySet> xTable = GetView()->getController().getTable();
+ if (IsReadOnly() || ( xTable.is() &&
+ xTable->getPropertySetInfo()->hasPropertyByName(PROPERTY_TYPE) &&
+ ::comphelper::getString(xTable->getPropertyValue(PROPERTY_TYPE)) == "VIEW"))
+ return nullptr;
+
+ // If the row is ReadOnly, editing is forbidden
+ SetDataPtr( nRow );
+ if( pActRow->IsReadOnly() )
+ return nullptr;
+
+ OFieldDescription* pActFieldDescr = pActRow->GetActFieldDescr();
+ switch (nColumnId)
+ {
+ case FIELD_NAME:
+ return new EditCellController( pNameCell );
+ case FIELD_TYPE:
+ if (pActFieldDescr && !pActFieldDescr->GetName().isEmpty())
+ return new ListBoxCellController( pTypeCell );
+ else return nullptr;
+ case HELP_TEXT:
+ if (pActFieldDescr && !pActFieldDescr->GetName().isEmpty())
+ return new EditCellController( pHelpTextCell );
+ else
+ return nullptr;
+ case COLUMN_DESCRIPTION:
+ if (pActFieldDescr && !pActFieldDescr->GetName().isEmpty())
+ return new EditCellController( pDescrCell );
+ else
+ return nullptr;
+ default:
+ return nullptr;
+ }
+}
+
+void OTableEditorCtrl::InitController(CellControllerRef&, long nRow, sal_uInt16 nColumnId)
+{
+ SeekRow( nRow == -1 ? GetCurRow() : nRow);
+ OFieldDescription* pActFieldDescr = pActRow->GetActFieldDescr();
+ OUString aInitString;
+
+ switch (nColumnId)
+ {
+ case FIELD_NAME:
+ if( pActFieldDescr )
+ aInitString = pActFieldDescr->GetName();
+ pNameCell->SetText( aInitString );
+ pNameCell->SaveValue();
+ break;
+ case FIELD_TYPE:
+ {
+ if ( pActFieldDescr && pActFieldDescr->getTypeInfo() )
+ aInitString = pActFieldDescr->getTypeInfo()->aUIName;
+
+ // Set the ComboBox contents
+ weld::ComboBox& rTypeList = pTypeCell->get_widget();
+ rTypeList.clear();
+ if( !pActFieldDescr )
+ break;
+
+ const OTypeInfoMap& rTypeInfo = GetView()->getController().getTypeInfo();
+ for (auto const& elem : rTypeInfo)
+ rTypeList.append_text(elem.second->aUIName);
+ rTypeList.set_active_text(aInitString);
+ }
+
+ break;
+ case HELP_TEXT:
+ if( pActFieldDescr )
+ aInitString = pActFieldDescr->GetHelpText();
+ pHelpTextCell->SetText( aInitString );
+ pHelpTextCell->SaveValue();
+ break;
+ case COLUMN_DESCRIPTION:
+ if( pActFieldDescr )
+ aInitString = pActFieldDescr->GetDescription();
+ pDescrCell->SetText( aInitString );
+ pDescrCell->SaveValue();
+ break;
+
+ }
+}
+
+EditBrowseBox::RowStatus OTableEditorCtrl::GetRowStatus(long nRow) const
+{
+ const_cast<OTableEditorCtrl*>(this)->SetDataPtr( nRow );
+ if( !pActRow )
+ return EditBrowseBox::CLEAN;
+ if (nRow >= 0 && nRow == m_nDataPos)
+ {
+ if( pActRow->IsPrimaryKey() )
+ return EditBrowseBox::CURRENT_PRIMARYKEY;
+ return EditBrowseBox::CURRENT;
+ }
+ else
+ {
+ if( pActRow->IsPrimaryKey() )
+ return EditBrowseBox::PRIMARYKEY;
+ return EditBrowseBox::CLEAN;
+ }
+}
+
+void OTableEditorCtrl::SaveCurRow()
+{
+ if (GetFieldDescr(GetCurRow()) == nullptr)
+ // there is no data in the current row
+ return;
+ if (!SaveModified())
+ return;
+
+ SetDataPtr(GetCurRow());
+ pDescrWin->SaveData( pActRow->GetActFieldDescr() );
+}
+
+void OTableEditorCtrl::DisplayData(long nRow)
+{
+ // go to the correct cell
+ SetDataPtr(nRow);
+
+ // Disable Edit-Mode temporarily
+ bool bWasEditing = IsEditing();
+ if (bWasEditing)
+ DeactivateCell();
+
+ CellControllerRef aTemp;
+ InitController(aTemp, nRow, FIELD_NAME);
+ InitController(aTemp, nRow, FIELD_TYPE);
+ InitController(aTemp, nRow, COLUMN_DESCRIPTION);
+ InitController(aTemp, nRow, HELP_TEXT);
+
+ GoToRow(nRow);
+ // Update the Description-Window
+ GetView()->GetDescWin()->DisplayData(GetFieldDescr(nRow));
+ // redraw the row
+ RowModified(nRow);
+
+ // and re-enable edit mode
+ ActivateCell(nRow, GetCurColumnId());
+}
+
+void OTableEditorCtrl::CursorMoved()
+{
+ // New line?
+ m_nDataPos = GetCurRow();
+ if( m_nDataPos != nOldDataPos && m_nDataPos != -1)
+ {
+ CellControllerRef aTemp;
+ InitController(aTemp,m_nDataPos,FIELD_NAME);
+ InitController(aTemp,m_nDataPos,FIELD_TYPE);
+ InitController(aTemp,m_nDataPos,COLUMN_DESCRIPTION);
+ InitController(aTemp,m_nDataPos,HELP_TEXT);
+ }
+
+ OTableRowView::CursorMoved();
+}
+
+sal_Int32 OTableEditorCtrl::HasFieldName( const OUString& rFieldName )
+{
+
+ Reference<XConnection> xCon = GetView()->getController().getConnection();
+ Reference< XDatabaseMetaData> xMetaData = xCon.is() ? xCon->getMetaData() : Reference< XDatabaseMetaData>();
+
+ ::comphelper::UStringMixEqual bCase(!xMetaData.is() || xMetaData->supportsMixedCaseQuotedIdentifiers());
+
+ sal_Int32 nCount(0);
+ for (auto const& row : *m_pRowList)
+ {
+ OFieldDescription* pFieldDescr = row->GetActFieldDescr();
+ if( pFieldDescr && bCase(rFieldName,pFieldDescr->GetName()))
+ nCount++;
+ }
+ return nCount;
+}
+
+void OTableEditorCtrl::SaveData(long nRow, sal_uInt16 nColId)
+{
+ // Store the cell content
+ SetDataPtr( nRow == -1 ? GetCurRow() : nRow);
+ OFieldDescription* pActFieldDescr = pActRow->GetActFieldDescr();
+
+ switch( nColId)
+ {
+ // Store NameCell
+ case FIELD_NAME:
+ {
+ // If there is no name, do nothing
+ const OUString aName(pNameCell->GetText());
+
+ if( aName.isEmpty() )
+ {
+ // If FieldDescr exists, the field is deleted and the old content restored
+ if (pActFieldDescr)
+ {
+ GetUndoManager().AddUndoAction(std::make_unique<OTableEditorTypeSelUndoAct>(this, nRow, FIELD_TYPE, pActFieldDescr->getTypeInfo()));
+ SwitchType(TOTypeInfoSP());
+ pActFieldDescr = pActRow->GetActFieldDescr();
+ }
+ else
+ return;
+ }
+ if(pActFieldDescr)
+ pActFieldDescr->SetName( aName );
+ pNameCell->ClearModifyFlag();
+
+ break;
+ }
+
+ // Store the field type
+ case FIELD_TYPE:
+ break;
+
+ // Store DescrCell
+ case HELP_TEXT:
+ {
+ // if the current field description is NULL, set Default
+ if( !pActFieldDescr )
+ {
+ pHelpTextCell->SetText(OUString());
+ pHelpTextCell->ClearModifyFlag();
+ }
+ else
+ pActFieldDescr->SetHelpText( pHelpTextCell->GetText() );
+ break;
+ }
+ case COLUMN_DESCRIPTION:
+ {
+ // Set the default if the field description is null
+ if( !pActFieldDescr )
+ {
+ pDescrCell->SetText(OUString());
+ pDescrCell->ClearModifyFlag();
+ }
+ else
+ pActFieldDescr->SetDescription( pDescrCell->GetText() );
+ break;
+ }
+ case FIELD_PROPERTY_DEFAULT:
+ case FIELD_PROPERTY_REQUIRED:
+ case FIELD_PROPERTY_TEXTLEN:
+ case FIELD_PROPERTY_NUMTYPE:
+ case FIELD_PROPERTY_AUTOINC:
+ case FIELD_PROPERTY_LENGTH:
+ case FIELD_PROPERTY_SCALE:
+ case FIELD_PROPERTY_BOOL_DEFAULT:
+ pDescrWin->SaveData(pActFieldDescr);
+
+ if ( FIELD_PROPERTY_AUTOINC == nColId && pActFieldDescr->IsAutoIncrement() )
+ {
+ OTableController& rController = GetView()->getController();
+ if ( rController.isAutoIncrementPrimaryKey() )
+ {
+ pActFieldDescr->SetPrimaryKey( true );
+ InvalidateHandleColumn();
+ Invalidate();
+ }
+ }
+ break;
+ }
+}
+
+bool OTableEditorCtrl::SaveModified()
+{
+ sal_uInt16 nColId = GetCurColumnId();
+
+ switch( nColId )
+ {
+ // Field type
+ case FIELD_TYPE:
+ {
+ // Reset the type
+ resetType();
+ } break;
+ }
+
+ return true;
+}
+
+bool OTableEditorCtrl::CursorMoving(long nNewRow, sal_uInt16 nNewCol)
+{
+
+ if (!EditBrowseBox::CursorMoving(nNewRow, nNewCol))
+ return false;
+
+ // Called after SaveModified(), current row is still the old one
+ m_nDataPos = nNewRow;
+ nOldDataPos = GetCurRow();
+
+ // Reset the markers
+ InvalidateStatusCell( nOldDataPos );
+ InvalidateStatusCell( m_nDataPos );
+
+ // Store the data from the Property window
+ if( SetDataPtr(nOldDataPos) && pDescrWin)
+ pDescrWin->SaveData( pActRow->GetActFieldDescr() );
+
+ // Show new data in the Property window
+ if( SetDataPtr(m_nDataPos) && pDescrWin)
+ pDescrWin->DisplayData( pActRow->GetActFieldDescr() );
+
+ return true;
+}
+
+IMPL_LINK_NOARG( OTableEditorCtrl, InvalidateFieldType, void*, void )
+{
+ nInvalidateTypeEvent = nullptr;
+ Invalidate( GetFieldRectPixel(nOldDataPos, FIELD_TYPE) );
+}
+
+void OTableEditorCtrl::CellModified( long nRow, sal_uInt16 nColId )
+{
+
+ // If the description is null, use the default
+ if(nRow == -1)
+ nRow = GetCurRow();
+ SetDataPtr( nRow );
+ OFieldDescription* pActFieldDescr = pActRow->GetActFieldDescr();
+
+ OUString sActionDescription;
+ switch ( nColId )
+ {
+ case FIELD_NAME: sActionDescription = DBA_RES( STR_CHANGE_COLUMN_NAME ); break;
+ case FIELD_TYPE: sActionDescription = DBA_RES( STR_CHANGE_COLUMN_TYPE ); break;
+ case HELP_TEXT:
+ case COLUMN_DESCRIPTION: sActionDescription = DBA_RES( STR_CHANGE_COLUMN_DESCRIPTION ); break;
+ default: sActionDescription = DBA_RES( STR_CHANGE_COLUMN_ATTRIBUTE ); break;
+ }
+
+ GetUndoManager().EnterListAction( sActionDescription, OUString(), 0, ViewShellId(-1) );
+ if (!pActFieldDescr)
+ {
+ const OTypeInfoMap& rTypeInfoMap = GetView()->getController().getTypeInfo();
+ if ( !rTypeInfoMap.empty() )
+ {
+ OTypeInfoMap::const_iterator aTypeIter = rTypeInfoMap.find(DataType::VARCHAR);
+ if ( aTypeIter == rTypeInfoMap.end() )
+ aTypeIter = rTypeInfoMap.begin();
+ pActRow->SetFieldType( aTypeIter->second );
+ }
+ else
+ pActRow->SetFieldType( GetView()->getController().getTypeInfoFallBack() );
+
+ nInvalidateTypeEvent = Application::PostUserEvent( LINK(this, OTableEditorCtrl, InvalidateFieldType), nullptr, true );
+ pActFieldDescr = pActRow->GetActFieldDescr();
+ pDescrWin->DisplayData( pActFieldDescr );
+ GetUndoManager().AddUndoAction( std::make_unique<OTableEditorTypeSelUndoAct>(this, nRow, nColId+1, TOTypeInfoSP()) );
+ }
+
+ if( nColId != FIELD_TYPE )
+ GetUndoManager().AddUndoAction( std::make_unique<OTableDesignCellUndoAct>(this, nRow, nColId) );
+ else
+ {
+ GetUndoManager().AddUndoAction(std::make_unique<OTableEditorTypeSelUndoAct>(this, GetCurRow(), nColId, GetFieldDescr(GetCurRow())->getTypeInfo()));
+ resetType();
+ }
+
+ SaveData(nRow,nColId);
+ // SaveData could create an undo action as well
+ GetUndoManager().LeaveListAction();
+ RowModified(nRow);
+ CellControllerRef xController(Controller());
+ if(xController.is())
+ xController->SetModified();
+
+ // Set the Modify flag
+ GetView()->getController().setModified( true );
+ InvalidateFeatures();
+}
+
+void OTableEditorCtrl::resetType()
+{
+ sal_Int32 nPos = pTypeCell->get_widget().get_active();
+ if(nPos != -1)
+ SwitchType( GetView()->getController().getTypeInfo(nPos) );
+ else
+ SwitchType(TOTypeInfoSP());
+}
+
+void OTableEditorCtrl::CellModified()
+{
+ CellModified( GetCurRow(), GetCurColumnId() );
+}
+
+void OTableEditorCtrl::InvalidateFeatures()
+{
+ GetView()->getController().InvalidateFeature(SID_UNDO);
+ GetView()->getController().InvalidateFeature(SID_REDO);
+ GetView()->getController().InvalidateFeature(SID_SAVEDOC);
+}
+
+void OTableEditorCtrl::CopyRows()
+{
+ // set to the right row and save it
+ if( SetDataPtr(m_nDataPos) )
+ pDescrWin->SaveData( pActRow->GetActFieldDescr() );
+
+ // Copy selected rows to the ClipboardList
+ std::shared_ptr<OTableRow> pClipboardRow;
+ std::shared_ptr<OTableRow> pRow;
+ std::vector< std::shared_ptr<OTableRow> > vClipboardList;
+ vClipboardList.reserve(GetSelectRowCount());
+
+ for( long nIndex=FirstSelectedRow(); nIndex != SFX_ENDOFSELECTION; nIndex=NextSelectedRow() )
+ {
+ pRow = (*m_pRowList)[nIndex];
+ OSL_ENSURE(pRow,"OTableEditorCtrl::CopyRows: Row is NULL!");
+ if ( pRow && pRow->GetActFieldDescr() )
+ {
+ pClipboardRow = std::make_shared<OTableRow>( *pRow );
+ vClipboardList.push_back( pClipboardRow);
+ }
+ }
+ if(!vClipboardList.empty())
+ {
+ rtl::Reference<OTableRowExchange> pData = new OTableRowExchange(vClipboardList);
+ pData->CopyToClipboard(GetParent());
+ }
+}
+
+OUString OTableEditorCtrl::GenerateName( const OUString& rName )
+{
+ // Create a base name for appending numbers to
+ OUString aBaseName;
+ Reference<XConnection> xCon = GetView()->getController().getConnection();
+ Reference< XDatabaseMetaData> xMetaData = xCon.is() ? xCon->getMetaData() : Reference< XDatabaseMetaData>();
+
+ sal_Int32 nMaxTextLen(xMetaData.is() ? xMetaData->getMaxColumnNameLength() : 0);
+
+ if( (rName.getLength()+2) >nMaxTextLen )
+ aBaseName = rName.copy( 0, nMaxTextLen-2 );
+ else
+ aBaseName = rName;
+
+ // append a sequential number to the base name (up to 99)
+ OUString aFieldName( rName);
+ sal_Int32 i=1;
+ while( HasFieldName(aFieldName) )
+ {
+ aFieldName = aBaseName + OUString::number(i);
+ i++;
+ }
+
+ return aFieldName;
+}
+
+void OTableEditorCtrl::InsertRows( long nRow )
+{
+
+ std::vector< std::shared_ptr<OTableRow> > vInsertedUndoRedoRows; // need for undo/redo handling
+ // get rows from clipboard
+ TransferableDataHelper aTransferData(TransferableDataHelper::CreateFromSystemClipboard(GetParent()));
+ if(aTransferData.HasFormat(SotClipboardFormatId::SBA_TABED))
+ {
+ ::tools::SvRef<SotStorageStream> aStreamRef;
+ bool bOk = aTransferData.GetSotStorageStream(SotClipboardFormatId::SBA_TABED,aStreamRef);
+ if (bOk && aStreamRef.is())
+ {
+ aStreamRef->Seek(STREAM_SEEK_TO_BEGIN);
+ aStreamRef->ResetError();
+ long nInsertRow = nRow;
+ std::shared_ptr<OTableRow> pRow;
+ sal_Int32 nSize = 0;
+ (*aStreamRef).ReadInt32( nSize );
+ vInsertedUndoRedoRows.reserve(nSize);
+ for(sal_Int32 i=0;i < nSize;++i)
+ {
+ pRow = std::make_shared<OTableRow>();
+ ReadOTableRow( *aStreamRef, *pRow );
+ pRow->SetReadOnly( false );
+ sal_Int32 nType = pRow->GetActFieldDescr()->GetType();
+ if ( pRow->GetActFieldDescr() )
+ pRow->GetActFieldDescr()->SetType(GetView()->getController().getTypeInfoByType(nType));
+ // Adjust the field names
+ pRow->GetActFieldDescr()->SetName( GenerateName( pRow->GetActFieldDescr()->GetName() ) );
+ pRow->SetPos(nInsertRow);
+ m_pRowList->insert( m_pRowList->begin()+nInsertRow,pRow );
+ vInsertedUndoRedoRows.push_back(std::make_shared<OTableRow>(*pRow));
+ nInsertRow++;
+ }
+ }
+ }
+ // RowInserted calls CursorMoved.
+ // The UI data should not be stored here.
+ RowInserted( nRow,vInsertedUndoRedoRows.size() );
+
+ // Create the Undo-Action
+ GetUndoManager().AddUndoAction( std::make_unique<OTableEditorInsUndoAct>(this, nRow,vInsertedUndoRedoRows) );
+ GetView()->getController().setModified( true );
+ InvalidateFeatures();
+}
+
+void OTableEditorCtrl::DeleteRows()
+{
+ OSL_ENSURE(GetView()->getController().isDropAllowed(),"Call of DeleteRows not valid here. Please check isDropAllowed!");
+ // Create the Undo-Action
+ GetUndoManager().AddUndoAction( std::make_unique<OTableEditorDelUndoAct>(this) );
+
+ // Delete all marked rows
+ long nIndex = FirstSelectedRow();
+ nOldDataPos = nIndex;
+
+ while( nIndex != SFX_ENDOFSELECTION )
+ {
+ // Remove rows
+ m_pRowList->erase( m_pRowList->begin()+nIndex );
+ RowRemoved( nIndex );
+
+ // Insert the empty row at the end
+ m_pRowList->push_back( std::make_shared<OTableRow>());
+ RowInserted( GetRowCount()-1 );
+
+ nIndex = FirstSelectedRow();
+ }
+
+ // Force the current record to be displayed
+ m_nDataPos = GetCurRow();
+ InvalidateStatusCell( nOldDataPos );
+ InvalidateStatusCell( m_nDataPos );
+ SetDataPtr( m_nDataPos );
+ ActivateCell();
+ pDescrWin->DisplayData( pActRow->GetActFieldDescr() );
+ GetView()->getController().setModified( true );
+ InvalidateFeatures();
+}
+
+void OTableEditorCtrl::InsertNewRows( long nRow )
+{
+ OSL_ENSURE(GetView()->getController().isAddAllowed(),"Call of InsertNewRows not valid here. Please check isAppendAllowed!");
+ // Create Undo-Action
+ long nInsertRows = GetSelectRowCount();
+ if( !nInsertRows )
+ nInsertRows = 1;
+ GetUndoManager().AddUndoAction( std::make_unique<OTableEditorInsNewUndoAct>(this, nRow, nInsertRows) );
+ // Insert the number of selected rows
+ for( long i=nRow; i<(nRow+nInsertRows); i++ )
+ m_pRowList->insert( m_pRowList->begin()+i ,std::make_shared<OTableRow>());
+ RowInserted( nRow, nInsertRows );
+
+ GetView()->getController().setModified( true );
+ InvalidateFeatures();
+}
+
+void OTableEditorCtrl::SetControlText( long nRow, sal_uInt16 nColId, const OUString& rText )
+{
+ // Set the Browser Controls
+ if( nColId < FIELD_FIRST_VIRTUAL_COLUMN )
+ {
+ GoToRow( nRow );
+ GoToColumnId( nColId );
+ CellControllerRef xController = Controller();
+ if(xController.is())
+ xController->GetWindow().SetText( rText );
+ else
+ RowModified(nRow,nColId);
+ }
+
+ // Set the Tabpage controls
+ else
+ {
+ pDescrWin->SetControlText( nColId, rText );
+ }
+}
+
+void OTableEditorCtrl::SetCellData( long nRow, sal_uInt16 nColId, const TOTypeInfoSP& _pTypeInfo )
+{
+ // Relocate the current pointer
+ if( nRow == -1 )
+ nRow = GetCurRow();
+ OFieldDescription* pFieldDescr = GetFieldDescr( nRow );
+ if( !pFieldDescr && nColId != FIELD_TYPE)
+ return;
+
+ // Set individual fields
+ switch( nColId )
+ {
+ case FIELD_TYPE:
+ SwitchType( _pTypeInfo );
+ break;
+ default:
+ OSL_FAIL("OTableEditorCtrl::SetCellData: invalid column!");
+ }
+ SetControlText(nRow,nColId,_pTypeInfo ? _pTypeInfo->aUIName : OUString());
+}
+
+void OTableEditorCtrl::SetCellData( long nRow, sal_uInt16 nColId, const css::uno::Any& _rNewData )
+{
+ // Relocate the current pointer
+ if( nRow == -1 )
+ nRow = GetCurRow();
+ OFieldDescription* pFieldDescr = GetFieldDescr( nRow );
+ if( !pFieldDescr && nColId != FIELD_TYPE)
+ return;
+
+ OUString sValue;
+ // Set individual fields
+ switch( nColId )
+ {
+ case FIELD_NAME:
+ sValue = ::comphelper::getString(_rNewData);
+ pFieldDescr->SetName( sValue );
+ break;
+
+ case FIELD_TYPE:
+ OSL_FAIL("OTableEditorCtrl::SetCellData: invalid column!");
+ break;
+
+ case COLUMN_DESCRIPTION:
+ sValue = ::comphelper::getString(_rNewData);
+ pFieldDescr->SetDescription( sValue );
+ break;
+
+ case FIELD_PROPERTY_DEFAULT:
+ pFieldDescr->SetControlDefault( _rNewData );
+ sValue = GetView()->GetDescWin()->getGenPage()->getFieldControl()->getControlDefault(pFieldDescr);
+ break;
+
+ case FIELD_PROPERTY_REQUIRED:
+ {
+ sValue = ::comphelper::getString(_rNewData);
+ pFieldDescr->SetIsNullable( sValue.toInt32() );
+ }
+ break;
+
+ case FIELD_PROPERTY_TEXTLEN:
+ case FIELD_PROPERTY_LENGTH:
+ {
+ sValue = ::comphelper::getString(_rNewData);
+ pFieldDescr->SetPrecision( sValue.toInt32() );
+ }
+ break;
+
+ case FIELD_PROPERTY_NUMTYPE:
+ OSL_FAIL("OTableEditorCtrl::SetCellData: invalid column!");
+ break;
+
+ case FIELD_PROPERTY_AUTOINC:
+ {
+ sValue = ::comphelper::getString(_rNewData);
+ pFieldDescr->SetAutoIncrement(sValue == DBA_RES(STR_VALUE_YES));
+ }
+ break;
+ case FIELD_PROPERTY_SCALE:
+ {
+ sValue = ::comphelper::getString(_rNewData);
+ pFieldDescr->SetScale(sValue.toInt32());
+ }
+ break;
+
+ case FIELD_PROPERTY_BOOL_DEFAULT:
+ sValue = GetView()->GetDescWin()->BoolStringPersistent(::comphelper::getString(_rNewData));
+ pFieldDescr->SetControlDefault(makeAny(sValue));
+ break;
+
+ case FIELD_PROPERTY_FORMAT:
+ {
+ sValue = ::comphelper::getString(_rNewData);
+ pFieldDescr->SetFormatKey(sValue.toInt32());
+ }
+ break;
+ }
+
+ SetControlText(nRow,nColId,sValue);
+}
+
+Any OTableEditorCtrl::GetCellData( long nRow, sal_uInt16 nColId )
+{
+ OFieldDescription* pFieldDescr = GetFieldDescr( nRow );
+ if( !pFieldDescr )
+ return Any();
+
+ // Relocate the current pointer
+ if( nRow==-1 )
+ nRow = GetCurRow();
+ SetDataPtr( nRow );
+
+ static const OUString strYes(DBA_RES(STR_VALUE_YES));
+ static const OUString strNo(DBA_RES(STR_VALUE_NO));
+ OUString sValue;
+ // Read out the fields
+ switch( nColId )
+ {
+ case FIELD_NAME:
+ sValue = pFieldDescr->GetName();
+ break;
+
+ case FIELD_TYPE:
+ if ( pFieldDescr->getTypeInfo() )
+ sValue = pFieldDescr->getTypeInfo()->aUIName;
+ break;
+
+ case COLUMN_DESCRIPTION:
+ sValue = pFieldDescr->GetDescription();
+ break;
+ case HELP_TEXT:
+ sValue = pFieldDescr->GetHelpText();
+ break;
+
+ case FIELD_PROPERTY_DEFAULT:
+ return pFieldDescr->GetControlDefault();
+
+ case FIELD_PROPERTY_REQUIRED:
+ sValue = pFieldDescr->GetIsNullable() == ColumnValue::NULLABLE ? strYes : strNo;
+ break;
+
+ case FIELD_PROPERTY_TEXTLEN:
+ case FIELD_PROPERTY_LENGTH:
+ sValue = OUString::number(pFieldDescr->GetPrecision());
+ break;
+
+ case FIELD_PROPERTY_NUMTYPE:
+ OSL_FAIL("OTableEditorCtrl::GetCellData: invalid column!");
+ break;
+
+ case FIELD_PROPERTY_AUTOINC:
+ sValue = pFieldDescr->IsAutoIncrement() ? strYes : strNo;
+ break;
+
+ case FIELD_PROPERTY_SCALE:
+ sValue = OUString::number(pFieldDescr->GetScale());
+ break;
+
+ case FIELD_PROPERTY_BOOL_DEFAULT:
+ sValue = GetView()->GetDescWin()->BoolStringUI(::comphelper::getString(pFieldDescr->GetControlDefault()));
+ break;
+
+ case FIELD_PROPERTY_FORMAT:
+ sValue = OUString::number(pFieldDescr->GetFormatKey());
+ break;
+ }
+
+ return makeAny(sValue);
+}
+
+OUString OTableEditorCtrl::GetCellText( long nRow, sal_uInt16 nColId ) const
+{
+ OUString sCellText;
+ const_cast< OTableEditorCtrl* >( this )->GetCellData( nRow, nColId ) >>= sCellText;
+ return sCellText;
+}
+
+sal_uInt32 OTableEditorCtrl::GetTotalCellWidth(long nRow, sal_uInt16 nColId)
+{
+ return GetTextWidth(GetCellText(nRow, nColId)) + 2 * GetTextWidth("0");
+}
+
+OFieldDescription* OTableEditorCtrl::GetFieldDescr( long nRow )
+{
+ std::vector< std::shared_ptr<OTableRow> >::size_type nListCount(
+ m_pRowList->size());
+ if( (nRow<0) || (sal::static_int_cast< unsigned long >(nRow)>=nListCount) )
+ {
+ OSL_FAIL("(nRow<0) || (nRow>=nListCount)");
+ return nullptr;
+ }
+ std::shared_ptr<OTableRow> pRow = (*m_pRowList)[ nRow ];
+ if( !pRow )
+ return nullptr;
+ return pRow->GetActFieldDescr();
+}
+
+bool OTableEditorCtrl::IsCutAllowed()
+{
+ bool bIsCutAllowed = (GetView()->getController().isAddAllowed() && GetView()->getController().isDropAllowed()) ||
+ GetView()->getController().isAlterAllowed();
+
+ if(bIsCutAllowed)
+ {
+ switch(m_eChildFocus)
+ {
+ case DESCRIPTION:
+ bIsCutAllowed = !pDescrCell->GetSelected().isEmpty();
+ break;
+ case HELPTEXT:
+ bIsCutAllowed = !pHelpTextCell->GetSelected().isEmpty();
+ break;
+ case NAME:
+ bIsCutAllowed = !pNameCell->GetSelected().isEmpty();
+ break;
+ case ROW:
+ bIsCutAllowed = IsCopyAllowed();
+ break;
+ default:
+ bIsCutAllowed = false;
+ break;
+ }
+ }
+
+ return bIsCutAllowed;
+}
+
+bool OTableEditorCtrl::IsCopyAllowed()
+{
+ bool bIsCopyAllowed = false;
+ if(m_eChildFocus == DESCRIPTION )
+ bIsCopyAllowed = !pDescrCell->GetSelected().isEmpty();
+ else if(HELPTEXT == m_eChildFocus )
+ bIsCopyAllowed = !pHelpTextCell->GetSelected().isEmpty();
+ else if(m_eChildFocus == NAME)
+ bIsCopyAllowed = !pNameCell->GetSelected().isEmpty();
+ else if(m_eChildFocus == ROW)
+ {
+ Reference<XPropertySet> xTable = GetView()->getController().getTable();
+ if( !GetSelectRowCount() || (xTable.is() && ::comphelper::getString(xTable->getPropertyValue(PROPERTY_TYPE)) == "VIEW"))
+ return false;
+
+ // If one of the selected rows is empty, Copy is not possible
+ std::shared_ptr<OTableRow> pRow;
+ long nIndex = FirstSelectedRow();
+ while( nIndex != SFX_ENDOFSELECTION )
+ {
+ pRow = (*m_pRowList)[nIndex];
+ if( !pRow->GetActFieldDescr() )
+ return false;
+
+ nIndex = NextSelectedRow();
+ }
+
+ bIsCopyAllowed = true;
+ }
+
+ return bIsCopyAllowed;
+}
+
+bool OTableEditorCtrl::IsPasteAllowed() const
+{
+ bool bAllowed = GetView()->getController().isAddAllowed();
+ if ( bAllowed )
+ {
+ TransferableDataHelper aTransferData(TransferableDataHelper::CreateFromSystemClipboard(GetParent()));
+ bool bRowFormat = aTransferData.HasFormat(SotClipboardFormatId::SBA_TABED);
+ if ( m_eChildFocus == ROW )
+ bAllowed = bRowFormat;
+ else
+ bAllowed = !bRowFormat && aTransferData.HasFormat(SotClipboardFormatId::STRING);
+ }
+
+ return bAllowed;
+}
+
+void OTableEditorCtrl::cut()
+{
+ if(m_eChildFocus == NAME)
+ {
+ if(GetView()->getController().isAlterAllowed())
+ {
+ SaveData(-1,FIELD_NAME);
+ pNameCell->Cut();
+ CellModified(-1,FIELD_NAME);
+ }
+ }
+ else if(m_eChildFocus == DESCRIPTION)
+ {
+ if(GetView()->getController().isAlterAllowed())
+ {
+ SaveData(-1,COLUMN_DESCRIPTION);
+ pDescrCell->Cut();
+ CellModified(-1,COLUMN_DESCRIPTION);
+ }
+ }
+ else if(HELPTEXT == m_eChildFocus )
+ {
+ if(GetView()->getController().isAlterAllowed())
+ {
+ SaveData(-1,HELP_TEXT);
+ pHelpTextCell->Cut();
+ CellModified(-1,HELP_TEXT);
+ }
+ }
+ else if(m_eChildFocus == ROW)
+ {
+ if (nCutEvent)
+ Application::RemoveUserEvent(nCutEvent);
+ nCutEvent = Application::PostUserEvent(LINK(this, OTableEditorCtrl, DelayedCut), nullptr, true);
+ }
+}
+
+void OTableEditorCtrl::copy()
+{
+ if(GetSelectRowCount())
+ OTableRowView::copy();
+ else if(m_eChildFocus == NAME)
+ pNameCell->Copy();
+ else if(HELPTEXT == m_eChildFocus )
+ pHelpTextCell->Copy();
+ else if(m_eChildFocus == DESCRIPTION )
+ pDescrCell->Copy();
+}
+
+void OTableEditorCtrl::paste()
+{
+ TransferableDataHelper aTransferData(TransferableDataHelper::CreateFromSystemClipboard(GetParent()));
+ if(aTransferData.HasFormat(SotClipboardFormatId::SBA_TABED))
+ {
+ if( nPasteEvent )
+ Application::RemoveUserEvent( nPasteEvent );
+ nPasteEvent = Application::PostUserEvent( LINK(this, OTableEditorCtrl, DelayedPaste), nullptr, true );
+ }
+ else if(m_eChildFocus == NAME)
+ {
+ if(GetView()->getController().isAlterAllowed())
+ {
+ pNameCell->Paste();
+ CellModified();
+ }
+ }
+ else if(HELPTEXT == m_eChildFocus )
+ {
+ if(GetView()->getController().isAlterAllowed())
+ {
+ pHelpTextCell->Paste();
+ CellModified();
+ }
+ }
+ else if(m_eChildFocus == DESCRIPTION)
+ {
+ if(GetView()->getController().isAlterAllowed())
+ {
+ pDescrCell->Paste();
+ CellModified();
+ }
+ }
+}
+
+bool OTableEditorCtrl::IsDeleteAllowed()
+{
+
+ return GetSelectRowCount() != 0 && GetView()->getController().isDropAllowed();
+}
+
+bool OTableEditorCtrl::IsInsertNewAllowed( long nRow )
+{
+
+ bool bInsertNewAllowed = GetView()->getController().isAddAllowed();
+ // If fields can be added, Paste in the new fields
+ if (bInsertNewAllowed && !GetView()->getController().isDropAllowed())
+ {
+ SetDataPtr(nRow);
+ if( GetActRow()->IsReadOnly() )
+ return false;
+ }
+
+ return bInsertNewAllowed;
+}
+
+bool OTableEditorCtrl::IsPrimaryKeyAllowed()
+{
+ if( !GetSelectRowCount() )
+ return false;
+
+ OTableController& rController = GetView()->getController();
+ if ( !rController.getSdbMetaData().supportsPrimaryKeys() )
+ return false;
+
+ Reference<XPropertySet> xTable = rController.getTable();
+ // Key must not be changed
+ // This applies only if the table is not new and not a css::sdbcx::View. Otherwise no DROP is executed
+
+ if(xTable.is() && ::comphelper::getString(xTable->getPropertyValue(PROPERTY_TYPE)) == "VIEW")
+ return false;
+ // If there is an empty field, no primary key
+ // The entry is only permitted if
+ // - there are no empty entries in the selection
+ // - No Memo or Image entries
+ // - DROP is not permitted (see above) and the column is not Required (not null flag is not set).
+ long nIndex = FirstSelectedRow();
+ std::shared_ptr<OTableRow> pRow;
+ while( nIndex != SFX_ENDOFSELECTION )
+ {
+ pRow = (*m_pRowList)[nIndex];
+ OFieldDescription* pFieldDescr = pRow->GetActFieldDescr();
+ if(!pFieldDescr)
+ return false;
+ else
+ {
+ // Memo and Image fields cannot be primary keys
+ // or if the column cannot be dropped and the Required flag is not set
+ // or if a css::sdbcx::View is available and the Required flag is not set
+ const TOTypeInfoSP& pTypeInfo = pFieldDescr->getTypeInfo();
+ if( pTypeInfo->nSearchType == ColumnSearch::NONE
+ || (pFieldDescr->IsNullable() && pRow->IsReadOnly())
+ )
+ return false;
+ }
+
+ nIndex = NextSelectedRow();
+ }
+
+ return true;
+}
+
+void OTableEditorCtrl::Command(const CommandEvent& rEvt)
+{
+ switch (rEvt.GetCommand())
+ {
+ case CommandEventId::ContextMenu:
+ {
+ Point aMenuPos( rEvt.GetMousePosPixel() );
+ if (!rEvt.IsMouseEvent())
+ {
+ if ( 1 == GetSelectColumnCount() )
+ {
+ sal_uInt16 nSelId = GetColumnId(
+ sal::static_int_cast< sal_uInt16 >(
+ FirstSelectedColumn() ) );
+ ::tools::Rectangle aColRect( GetFieldRectPixel( 0, nSelId, false ) );
+
+ aMenuPos = aColRect.TopCenter();
+ }
+ else if ( GetSelectRowCount() > 0 )
+ {
+ ::tools::Rectangle aColRect( GetFieldRectPixel( FirstSelectedRow(), HANDLE_ID ) );
+
+ aMenuPos = aColRect.TopCenter();
+ }
+ else
+ {
+ OTableRowView::Command(rEvt);
+ return;
+ }
+ }
+
+ // Show the Context menu
+ if( !IsReadOnly() )
+ {
+ sal_uInt16 nColId = GetColumnId(GetColumnAtXPosPixel(aMenuPos.X()));
+ long nRow = GetRowAtYPosPixel(aMenuPos.Y());
+
+ if ( HANDLE_ID != nColId )
+ {
+ if ( nRow < 0 && nColId != BROWSER_INVALIDID )
+ { // hit the header
+ if ( 3 != nColId )
+ { // 3 would mean the last column, and this last column is auto-sized
+ if ( !IsColumnSelected( nColId ) )
+ SelectColumnId( nColId );
+
+ VclBuilder aBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "dbaccess/ui/querycolmenu.ui", "");
+ VclPtr<PopupMenu> aContextMenu(aBuilder.get_menu("menu"));
+ aContextMenu->EnableItem(aContextMenu->GetItemId("delete"), false);
+ aContextMenu->RemoveDisabledEntries(true, true);
+ if (aContextMenu->Execute(this, aMenuPos) == aContextMenu->GetItemId("width"))
+ adjustBrowseBoxColumnWidth( this, nColId );
+ }
+ }
+ }
+ else
+ {
+ VclBuilder aBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "dbaccess/ui/tabledesignrowmenu.ui", "");
+ VclPtr<PopupMenu> aContextMenu(aBuilder.get_menu("menu"));
+
+ aContextMenu->EnableItem(aContextMenu->GetItemId("cut"), IsCutAllowed());
+ aContextMenu->EnableItem(aContextMenu->GetItemId("copy"), IsCopyAllowed());
+ aContextMenu->EnableItem(aContextMenu->GetItemId("paste"), IsPasteAllowed());
+ aContextMenu->EnableItem(aContextMenu->GetItemId("delete"), IsDeleteAllowed());
+ aContextMenu->EnableItem(aContextMenu->GetItemId("primarykey"), IsPrimaryKeyAllowed());
+ aContextMenu->EnableItem(aContextMenu->GetItemId("insert"), IsInsertNewAllowed(nRow));
+ aContextMenu->CheckItem("primarykey", IsRowSelected(GetCurRow()) && IsPrimaryKey());
+
+ // remove all the disable entries
+ aContextMenu->RemoveDisabledEntries(true, true);
+
+ if( SetDataPtr(m_nDataPos) )
+ pDescrWin->SaveData( pActRow->GetActFieldDescr() );
+
+ // All actions which change the number of rows must be run asynchronously
+ // otherwise there may be problems between the Context menu and the Browser
+ m_nDataPos = GetCurRow();
+ aContextMenu->Execute(this, aMenuPos);
+ OString sIdent = aContextMenu->GetCurItemIdent();
+ if (sIdent == "cut")
+ cut();
+ else if (sIdent == "copy")
+ copy();
+ else if (sIdent == "paste")
+ paste();
+ else if (sIdent == "delete")
+ {
+ if( nDeleteEvent )
+ Application::RemoveUserEvent( nDeleteEvent );
+ nDeleteEvent = Application::PostUserEvent( LINK(this, OTableEditorCtrl, DelayedDelete), nullptr, true );
+ }
+ else if (sIdent == "insert")
+ {
+ if( nInsNewRowsEvent )
+ Application::RemoveUserEvent( nInsNewRowsEvent );
+ nInsNewRowsEvent = Application::PostUserEvent( LINK(this, OTableEditorCtrl, DelayedInsNewRows), nullptr, true );
+ }
+ else if (sIdent == "primarykey")
+ {
+ SetPrimaryKey( !IsPrimaryKey() );
+ }
+ }
+ }
+ }
+ break;
+ default:
+ OTableRowView::Command(rEvt);
+ }
+
+}
+
+IMPL_LINK_NOARG( OTableEditorCtrl, DelayedCut, void*, void )
+{
+ nCutEvent = nullptr;
+ OTableRowView::cut();
+}
+
+IMPL_LINK_NOARG( OTableEditorCtrl, DelayedPaste, void*, void )
+{
+ nPasteEvent = nullptr;
+
+ sal_Int32 nPastePosition = GetView()->getController().getFirstEmptyRowPosition();
+ if ( !GetView()->getController().getTable().is() )
+ nPastePosition = GetSelectRowCount() ? FirstSelectedRow() : GetCurRow();
+
+ if (!IsInsertNewAllowed(nPastePosition))
+ { // Insertion is not allowed, only appending, so test if there are full cells after the PastePosition
+
+ auto aIter = std::find_if(m_pRowList->rbegin(), m_pRowList->rend(), [](const std::shared_ptr<OTableRow>& rxRow) {
+ return rxRow && rxRow->GetActFieldDescr() && !rxRow->GetActFieldDescr()->GetName().isEmpty(); });
+ auto nFreeFromPos = static_cast<sal_Int32>(std::distance(aIter, m_pRowList->rend())); // from here on there are only empty rows
+ if (nPastePosition < nFreeFromPos) // if at least one PastePosition is full, go right to the end
+ nPastePosition = nFreeFromPos;
+ }
+
+ OTableRowView::Paste( nPastePosition );
+ SetNoSelection();
+ GoToRow( nPastePosition );
+}
+
+IMPL_LINK_NOARG( OTableEditorCtrl, DelayedDelete, void*, void )
+{
+ nDeleteEvent = nullptr;
+ DeleteRows();
+}
+
+IMPL_LINK_NOARG( OTableEditorCtrl, DelayedInsNewRows, void*, void )
+{
+ nInsNewRowsEvent = nullptr;
+ sal_Int32 nPastePosition = GetView()->getController().getFirstEmptyRowPosition();
+ if ( !GetView()->getController().getTable().is() )
+ nPastePosition = GetSelectRowCount() ? FirstSelectedRow() : m_nDataPos;
+
+ InsertNewRows( nPastePosition );
+ SetNoSelection();
+ GoToRow( nPastePosition );
+}
+
+void OTableEditorCtrl::AdjustFieldDescription(OFieldDescription* _pFieldDesc,
+ MultiSelection& _rMultiSel,
+ sal_Int32 _nPos,
+ bool _bSet,
+ bool _bPrimaryKey)
+{
+ _pFieldDesc->SetPrimaryKey( _bPrimaryKey );
+ if(!_bSet && _pFieldDesc->getTypeInfo()->bNullable)
+ {
+ _pFieldDesc->SetIsNullable(ColumnValue::NO_NULLS);
+ _pFieldDesc->SetControlDefault(Any());
+ }
+ if ( _pFieldDesc->IsAutoIncrement() && !_bPrimaryKey )
+ {
+ OTableController& rController = GetView()->getController();
+ if ( rController.isAutoIncrementPrimaryKey() )
+ {
+ _pFieldDesc->SetAutoIncrement(false);
+ }
+ }
+ // update field description
+ pDescrWin->DisplayData(_pFieldDesc);
+
+ _rMultiSel.Insert( _nPos );
+ _rMultiSel.Select( _nPos );
+}
+
+void OTableEditorCtrl::SetPrimaryKey( bool bSet )
+{
+ // Delete any existing Primary Keys
+ MultiSelection aDeletedPrimKeys;
+ aDeletedPrimKeys.SetTotalRange( Range(0,GetRowCount()) );
+
+ sal_Int32 nRow = 0;
+ for (auto const& row : *m_pRowList)
+ {
+ OFieldDescription* pFieldDescr = row->GetActFieldDescr();
+ if( pFieldDescr && row->IsPrimaryKey() && (!bSet || !IsRowSelected(nRow)) )
+ {
+ AdjustFieldDescription(pFieldDescr,aDeletedPrimKeys,nRow,bSet,false);
+ }
+ ++nRow;
+ }
+
+ // Set the primary keys of the marked rows
+ MultiSelection aInsertedPrimKeys;
+ aInsertedPrimKeys.SetTotalRange( Range(0,GetRowCount()) );
+ if( bSet )
+ {
+ long nIndex = FirstSelectedRow();
+ while( nIndex != SFX_ENDOFSELECTION )
+ {
+ // Set the key
+ std::shared_ptr<OTableRow> pRow = (*m_pRowList)[nIndex];
+ OFieldDescription* pFieldDescr = pRow->GetActFieldDescr();
+ if(pFieldDescr)
+ AdjustFieldDescription(pFieldDescr,aInsertedPrimKeys,nIndex,false,true);
+
+ nIndex = NextSelectedRow();
+ }
+ }
+
+ GetUndoManager().AddUndoAction( std::make_unique<OPrimKeyUndoAct>(this, aDeletedPrimKeys, aInsertedPrimKeys) );
+
+ // Invalidate the handle-columns
+ InvalidateHandleColumn();
+
+ // Set the TableDocSh's ModifyFlag
+ GetView()->getController().setModified( true );
+ InvalidateFeatures();
+}
+
+bool OTableEditorCtrl::IsPrimaryKey()
+{
+ // Are all marked fields part of the Primary Key ?
+ long nPrimaryKeys = 0;
+ sal_Int32 nRow=0;
+ for (auto const& row : *m_pRowList)
+ {
+ if( IsRowSelected(nRow) && !row->IsPrimaryKey() )
+ return false;
+ if( row->IsPrimaryKey() )
+ ++nPrimaryKeys;
+ ++nRow;
+ }
+
+ // Are there any unselected fields that are part of the Key ?
+ return GetSelectRowCount() == nPrimaryKeys;
+}
+
+void OTableEditorCtrl::SwitchType( const TOTypeInfoSP& _pType )
+{
+ // if there is no assigned field name
+ long nRow(GetCurRow());
+ OFieldDescription* pActFieldDescr = GetFieldDescr( nRow );
+ if( pActFieldDescr )
+ // Store the old description
+ pDescrWin->SaveData( pActFieldDescr );
+
+ if ( nRow < 0 || nRow > static_cast<long>(m_pRowList->size()) )
+ return;
+ // Show the new description
+ std::shared_ptr<OTableRow> pRow = (*m_pRowList)[nRow];
+ pRow->SetFieldType( _pType, true );
+ if ( _pType )
+ {
+ weld::ComboBox& rTypeList = pTypeCell->get_widget();
+ const sal_Int32 nCurrentlySelected = rTypeList.get_active();
+
+ if ( ( nCurrentlySelected == -1 )
+ || ( GetView()->getController().getTypeInfo( nCurrentlySelected ) != _pType )
+ )
+ {
+ sal_Int32 nEntryPos = 0;
+ const OTypeInfoMap& rTypeInfo = GetView()->getController().getTypeInfo();
+ for (auto const& elem : rTypeInfo)
+ {
+ if(elem.second == _pType)
+ break;
+ ++nEntryPos;
+ }
+ if (nEntryPos < rTypeList.get_count())
+ rTypeList.set_active(nEntryPos);
+ }
+ }
+
+ pActFieldDescr = pRow->GetActFieldDescr();
+ if (pActFieldDescr != nullptr && !pActFieldDescr->GetFormatKey())
+ {
+ sal_Int32 nFormatKey = ::dbtools::getDefaultNumberFormat( pActFieldDescr->GetType(),
+ pActFieldDescr->GetScale(),
+ pActFieldDescr->IsCurrency(),
+ Reference< XNumberFormatTypes>(GetView()->getController().getNumberFormatter()->getNumberFormatsSupplier()->getNumberFormats(),UNO_QUERY),
+ GetView()->getLocale());
+
+ pActFieldDescr->SetFormatKey(nFormatKey);
+ }
+
+ pDescrWin->DisplayData( pActFieldDescr );
+}
+
+OTableDesignView* OTableEditorCtrl::GetView() const
+{
+ return static_cast<OTableDesignView*>(GetParent()->GetParent());
+}
+
+void OTableEditorCtrl::DeactivateCell(bool bUpdate)
+{
+ OTableRowView::DeactivateCell(bUpdate);
+ // now we have to deactivate the field description
+ long nRow(GetCurRow());
+ if (pDescrWin)
+ pDescrWin->SetReadOnly(bReadOnly || !SetDataPtr(nRow) || GetActRow()->IsReadOnly());
+}
+
+bool OTableEditorCtrl::PreNotify( NotifyEvent& rNEvt )
+{
+ if (rNEvt.GetType() == MouseNotifyEvent::GETFOCUS)
+ {
+ if( pHelpTextCell && pHelpTextCell->HasChildPathFocus() )
+ m_eChildFocus = HELPTEXT;
+ else if( pDescrCell && pDescrCell->HasChildPathFocus() )
+ m_eChildFocus = DESCRIPTION;
+ else if(pNameCell && pNameCell->HasChildPathFocus() )
+ m_eChildFocus = NAME;
+ else
+ m_eChildFocus = ROW;
+ }
+
+ return OTableRowView::PreNotify(rNEvt);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/tabledesign/TEditControl.hxx b/dbaccess/source/ui/tabledesign/TEditControl.hxx
new file mode 100644
index 000000000..44469bf29
--- /dev/null
+++ b/dbaccess/source/ui/tabledesign/TEditControl.hxx
@@ -0,0 +1,205 @@
+/* -*- 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_DBACCESS_SOURCE_UI_TABLEDESIGN_TEDITCONTROL_HXX
+#define INCLUDED_DBACCESS_SOURCE_UI_TABLEDESIGN_TEDITCONTROL_HXX
+
+#include <TableDesignControl.hxx>
+#include <TableDesignView.hxx>
+#include "TableFieldDescWin.hxx"
+#include <TableRow.hxx>
+#include <TypeInfo.hxx>
+
+class Edit;
+class SfxUndoManager;
+namespace dbaui
+{
+ class OSQLNameEdit;
+
+ class OTableEditorCtrl : public OTableRowView
+ {
+ enum ChildFocusState
+ {
+ HELPTEXT,
+ DESCRIPTION,
+ NAME,
+ ROW,
+ NONE
+ };
+
+ std::vector< std::shared_ptr<OTableRow> >* m_pRowList;
+
+ VclPtr<OSQLNameEdit> pNameCell;
+ VclPtr< ::svt::ListBoxControl> pTypeCell;
+ VclPtr<Edit> pHelpTextCell;
+ VclPtr<Edit> pDescrCell;
+ VclPtr<OTableFieldDescWin> pDescrWin; // properties of one column
+
+ std::shared_ptr<OTableRow> pActRow;
+
+ ImplSVEvent * nCutEvent;
+ ImplSVEvent * nPasteEvent;
+ ImplSVEvent * nDeleteEvent;
+ ImplSVEvent * nInsNewRowsEvent;
+ ImplSVEvent * nInvalidateTypeEvent;
+ ChildFocusState m_eChildFocus;
+
+ long nOldDataPos;
+
+ bool bReadOnly;
+
+ // helper class
+ class ClipboardInvalidator final
+ {
+ private:
+ AutoTimer m_aInvalidateTimer;
+ VclPtr<OTableEditorCtrl> m_pOwner;
+
+ public:
+ explicit ClipboardInvalidator(OTableEditorCtrl*);
+ ~ClipboardInvalidator();
+ void Stop();
+
+ private:
+ DECL_LINK(OnInvalidate, Timer*, void);
+ };
+
+ friend class OTableEditorCtrl::ClipboardInvalidator;
+
+ ClipboardInvalidator m_aInvalidate;
+
+ protected:
+ virtual void Command( const CommandEvent& rEvt ) override;
+ virtual bool SeekRow(long nRow) override;
+ virtual void PaintCell(OutputDevice& rDev, const tools::Rectangle& rRect,
+ sal_uInt16 nColumnId ) const override;
+
+ virtual void CursorMoved() override;
+ virtual RowStatus GetRowStatus(long nRow) const override;
+
+ virtual ::svt::CellController* GetController(long nRow, sal_uInt16 nCol) override;
+ virtual void InitController(::svt::CellControllerRef& rController, long nRow, sal_uInt16 nCol) override;
+
+ virtual void CellModified() override;
+ virtual bool SaveModified() override; // is called before changing a cell (false prevents change)
+
+ virtual OUString GetCellText(long nRow, sal_uInt16 nColId) const override;
+ virtual sal_uInt32 GetTotalCellWidth(long nRow, sal_uInt16 nColId) override;
+
+ virtual void CopyRows() override;
+ virtual void InsertRows( long nRow ) override;
+ virtual void DeleteRows() override;
+ virtual void InsertNewRows( long nRow ) override;
+
+ virtual bool IsPrimaryKeyAllowed() override;
+ virtual bool IsInsertNewAllowed( long nRow ) override;
+ virtual bool IsDeleteAllowed() override;
+
+ void ClearModified();
+
+ void SetPrimaryKey( bool bSet );
+ bool IsPrimaryKey();
+
+ public:
+ explicit OTableEditorCtrl(vcl::Window* pParentWin);
+ virtual ~OTableEditorCtrl() override;
+ virtual void dispose() override;
+ virtual bool CursorMoving(long nNewRow, sal_uInt16 nNewCol) override;
+ SfxUndoManager& GetUndoManager() const;
+
+ void SetDescrWin( OTableFieldDescWin* pWin )
+ {
+ pDescrWin = pWin;
+ if (pDescrWin && pActRow)
+ pDescrWin->DisplayData(pActRow->GetActFieldDescr());
+ }
+ void SaveCurRow();
+ void SwitchType( const TOTypeInfoSP& _pType );
+
+ /// force displaying of the given row
+ void DisplayData( long nRow );
+
+ virtual void SetCellData( long nRow, sal_uInt16 nColId, const TOTypeInfoSP& _pTypeInfo ) override;
+ virtual void SetCellData( long nRow, sal_uInt16 nColId, const css::uno::Any& _rSaveData ) override;
+ virtual css::uno::Any GetCellData( long nRow, sal_uInt16 nColId ) override;
+ virtual void SetControlText( long nRow, sal_uInt16 nColId, const OUString& rText ) override;
+
+ virtual OTableDesignView* GetView() const override;
+
+ std::vector< std::shared_ptr<OTableRow> >* GetRowList(){ return m_pRowList; }
+
+ const std::shared_ptr<OTableRow>& GetActRow() const { return pActRow; }
+ void CellModified( long nRow, sal_uInt16 nColId );
+ void SetReadOnly( bool bRead );
+
+ virtual void Init() override;
+ virtual void DeactivateCell(bool bUpdate = true) override;
+
+ bool IsCutAllowed();
+ bool IsCopyAllowed();
+ bool IsPasteAllowed() const;
+ bool IsReadOnly() const { return bReadOnly;}
+ OFieldDescription* GetFieldDescr( long nRow );
+
+ // Window overrides
+ virtual bool PreNotify( NotifyEvent& rNEvt ) override;
+
+ // IClipboardTest
+ virtual bool isCutAllowed() override { return IsCutAllowed(); }
+ virtual bool isCopyAllowed() override { return IsCopyAllowed(); }
+ virtual bool isPasteAllowed() override { return IsPasteAllowed(); }
+
+ virtual void cut() override;
+ virtual void copy() override;
+ virtual void paste() override;
+
+ private:
+ DECL_LINK( DelayedCut, void*, void );
+ DECL_LINK( DelayedPaste, void*, void );
+ DECL_LINK( DelayedDelete, void*, void );
+ DECL_LINK( DelayedInsNewRows, void*, void );
+ DECL_LINK( InvalidateFieldType, void*, void );
+
+ void InitCellController();
+ sal_Int32 HasFieldName( const OUString& rFieldName );
+ OUString GenerateName( const OUString& rName );
+ bool SetDataPtr( long nRow );
+
+ void SaveData(long nRow, sal_uInt16 nColumnId);
+ /** AdjustFieldDescription set the needed values for the description
+ @param _pFieldDesc the field description where to set the values
+ @param _rMultiSel contains the positions which changed for undo/redo
+ @param _nPos the current position
+ @param _bSet should a key be set
+ @param _bPrimaryKey which value should the pkey have
+ */
+ void AdjustFieldDescription( OFieldDescription* _pFieldDesc,
+ MultiSelection& _rMultiSel,
+ sal_Int32 _nPos,
+ bool _bSet,
+ bool _bPrimaryKey);
+ /** InvalidateFeatures invalidates the slots SID_UNDO | SID_REDO | SID_SAVEDOC
+ */
+ void InvalidateFeatures();
+
+ void resetType();
+ };
+}
+#endif // INCLUDED_DBACCESS_SOURCE_UI_TABLEDESIGN_TEDITCONTROL_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/tabledesign/TableController.cxx b/dbaccess/source/ui/tabledesign/TableController.cxx
new file mode 100644
index 000000000..f88110b48
--- /dev/null
+++ b/dbaccess/source/ui/tabledesign/TableController.cxx
@@ -0,0 +1,1511 @@
+/* -*- 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 <FieldDescriptions.hxx>
+#include "TEditControl.hxx"
+#include <TableController.hxx>
+#include <TableDesignView.hxx>
+#include <TableRow.hxx>
+#include <TypeInfo.hxx>
+#include <UITools.hxx>
+#include <browserids.hxx>
+#include <core_resource.hxx>
+#include <dbu_reghelper.hxx>
+#include <strings.hrc>
+#include <strings.hxx>
+#include <defaultobjectnamecheck.hxx>
+#include <dlgsave.hxx>
+#include <indexdialog.hxx>
+#include <sqlmessage.hxx>
+#include <uiservices.hxx>
+
+#include <com/sun/star/frame/XTitleChangeListener.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#include <com/sun/star/sdbc/SQLWarning.hpp>
+#include <com/sun/star/sdbcx/KeyType.hpp>
+#include <com/sun/star/sdbcx/XAlterTable.hpp>
+#include <com/sun/star/sdbcx/XAppend.hpp>
+#include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
+#include <com/sun/star/sdbcx/XDrop.hpp>
+#include <com/sun/star/sdbcx/XIndexesSupplier.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <connectivity/dbexception.hxx>
+#include <connectivity/dbtools.hxx>
+#include <connectivity/dbmetadata.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <tools/diagnose_ex.h>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+
+#include <algorithm>
+#include <functional>
+
+extern "C" void createRegistryInfo_OTableControl()
+{
+ static ::dbaui::OMultiInstanceAutoRegistration< ::dbaui::OTableController > aAutoRegistration;
+}
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::ui;
+using namespace ::com::sun::star::util;
+using namespace ::dbtools;
+using namespace ::dbaui;
+using namespace ::comphelper;
+
+// number of columns when creating it from scratch
+#define NEWCOLS 128
+
+namespace
+{
+ void dropTable(const Reference<XNameAccess>& _rxTable,const OUString& _sTableName)
+ {
+ if ( _rxTable->hasByName(_sTableName) )
+ {
+ Reference<XDrop> xNameCont(_rxTable,UNO_QUERY);
+ OSL_ENSURE(xNameCont.is(),"No drop interface for tables!");
+ if ( xNameCont.is() )
+ xNameCont->dropByName(_sTableName);
+ }
+ }
+}
+
+OUString SAL_CALL OTableController::getImplementationName()
+{
+ return getImplementationName_Static();
+}
+
+OUString OTableController::getImplementationName_Static()
+{
+ return "org.openoffice.comp.dbu.OTableDesign";
+}
+
+Sequence< OUString> OTableController::getSupportedServiceNames_Static()
+{
+ return { "com.sun.star.sdb.TableDesign" };
+}
+
+Sequence< OUString> SAL_CALL OTableController::getSupportedServiceNames()
+{
+ return getSupportedServiceNames_Static();
+}
+
+Reference< XInterface > OTableController::Create(const Reference<XMultiServiceFactory >& _rxFactory)
+{
+ return *(new OTableController(comphelper::getComponentContext(_rxFactory)));
+}
+
+OTableController::OTableController(const Reference< XComponentContext >& _rM) : OTableController_BASE(_rM)
+ ,m_sTypeNames(DBA_RES(STR_TABLEDESIGN_DBFIELDTYPES))
+ ,m_pTypeInfo()
+ ,m_bAllowAutoIncrementValue(false)
+ ,m_bNew(true)
+{
+
+ InvalidateAll();
+ m_pTypeInfo = std::make_shared<OTypeInfo>();
+ m_pTypeInfo->aUIName = m_sTypeNames.getToken(TYPE_OTHER, ';');
+}
+
+OTableController::~OTableController()
+{
+ m_aTypeInfoIndex.clear();
+ m_aTypeInfo.clear();
+
+}
+
+void OTableController::startTableListening()
+{
+ Reference< XComponent > xComponent(m_xTable, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->addEventListener(static_cast<XModifyListener*>(this));
+}
+
+void OTableController::stopTableListening()
+{
+ Reference< XComponent > xComponent(m_xTable, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->removeEventListener(static_cast<XModifyListener*>(this));
+}
+
+void OTableController::disposing()
+{
+ OTableController_BASE::disposing();
+ clearView();
+
+ m_vRowList.clear();
+}
+
+FeatureState OTableController::GetState(sal_uInt16 _nId) const
+{
+ FeatureState aReturn;
+ // disabled automatically
+
+ switch (_nId)
+ {
+ case ID_BROWSER_CLOSE:
+ aReturn.bEnabled = true;
+ break;
+ case ID_BROWSER_EDITDOC:
+ aReturn.bChecked = isEditable();
+ aReturn.bEnabled = true;
+ break;
+ case ID_BROWSER_SAVEDOC:
+ aReturn.bEnabled = isEditable() && std::any_of(m_vRowList.begin(),m_vRowList.end(),std::mem_fn(&OTableRow::isValid));
+ break;
+ case ID_BROWSER_SAVEASDOC:
+ aReturn.bEnabled = isConnected() && isEditable();
+ if ( aReturn.bEnabled )
+ {
+ aReturn.bEnabled = std::any_of(m_vRowList.begin(),m_vRowList.end(),
+ std::mem_fn(&OTableRow::isValid));
+ }
+ break;
+
+ case ID_BROWSER_CUT:
+ aReturn.bEnabled = isEditable() && m_aCurrentFrame.isActive() && getView() && static_cast<OTableDesignView*>(getView())->isCutAllowed();
+ break;
+ case ID_BROWSER_COPY:
+ aReturn.bEnabled = m_aCurrentFrame.isActive() && getView() && static_cast<OTableDesignView*>(getView())->isCopyAllowed();
+ break;
+ case ID_BROWSER_PASTE:
+ aReturn.bEnabled = isEditable() && m_aCurrentFrame.isActive() && getView() && static_cast<OTableDesignView*>(getView())->isPasteAllowed();
+ break;
+ case SID_INDEXDESIGN:
+ aReturn.bEnabled =
+ ( ( ((!m_bNew && impl_isModified()) || impl_isModified())
+ || Reference< XIndexesSupplier >(m_xTable, UNO_QUERY).is()
+ )
+ && isConnected()
+ );
+ if ( aReturn.bEnabled )
+ {
+ aReturn.bEnabled = std::any_of(m_vRowList.begin(),m_vRowList.end(),
+ std::mem_fn(&OTableRow::isValid));
+ }
+ break;
+ default:
+ aReturn = OTableController_BASE::GetState(_nId);
+ }
+ return aReturn;
+}
+
+void OTableController::Execute(sal_uInt16 _nId, const Sequence< PropertyValue >& aArgs)
+{
+ switch(_nId)
+ {
+ case ID_BROWSER_EDITDOC:
+ setEditable(!isEditable());
+ static_cast<OTableDesignView*>(getView())->setReadOnly(!isEditable());
+ InvalidateFeature(ID_BROWSER_SAVEDOC);
+ InvalidateFeature(ID_BROWSER_PASTE);
+ InvalidateFeature(SID_BROWSER_CLEAR_QUERY);
+ break;
+ case ID_BROWSER_SAVEASDOC:
+ doSaveDoc(true);
+ break;
+ case ID_BROWSER_SAVEDOC:
+ static_cast<OTableDesignView*>(getView())->GetEditorCtrl()->SaveCurRow();
+ doSaveDoc(false);
+ break;
+ case ID_BROWSER_CUT:
+ static_cast<OTableDesignView*>(getView())->cut();
+ break;
+ case ID_BROWSER_COPY:
+ static_cast<OTableDesignView*>(getView())->copy();
+ break;
+ case ID_BROWSER_PASTE:
+ static_cast<OTableDesignView*>(getView())->paste();
+ break;
+ case SID_INDEXDESIGN:
+ doEditIndexes();
+ break;
+ default:
+ OTableController_BASE::Execute(_nId,aArgs);
+ }
+ InvalidateFeature(_nId);
+}
+
+bool OTableController::doSaveDoc(bool _bSaveAs)
+{
+ if (!isConnected())
+ reconnect(true); // ask the user for a new connection
+ Reference<XTablesSupplier> xTablesSup(getConnection(),UNO_QUERY);
+
+ if (!xTablesSup.is())
+ {
+ OUString aMessage(DBA_RES(STR_TABLEDESIGN_CONNECTION_MISSING));
+ OSQLWarningBox aWarning(getFrameWeld(), aMessage);
+ aWarning.run();
+ return false;
+ }
+
+ // check if a column exists
+ // TODO
+
+ Reference<XNameAccess> xTables;
+ OUString sCatalog, sSchema;
+
+ bool bNew = m_sName.isEmpty();
+ bNew = bNew || m_bNew || _bSaveAs;
+
+ try
+ {
+ xTables = xTablesSup->getTables();
+ OSL_ENSURE(xTables.is(),"The tables can't be null!");
+ bNew = bNew || (xTables.is() && !xTables->hasByName(m_sName));
+
+ // first we need a name for our query so ask the user
+ if(bNew)
+ {
+ OUString aName = DBA_RES(STR_TBL_TITLE);
+ OUString aDefaultName = aName.getToken(0,' ');
+ aDefaultName = ::dbtools::createUniqueName(xTables,aDefaultName);
+
+ DynamicTableOrQueryNameCheck aNameChecker( getConnection(), CommandType::TABLE );
+ OSaveAsDlg aDlg(getFrameWeld(), CommandType::TABLE, getORB(), getConnection(), aDefaultName, aNameChecker, SADFlags::NONE);
+ if (aDlg.run() != RET_OK)
+ return false;
+
+ m_sName = aDlg.getName();
+ sCatalog = aDlg.getCatalog();
+ sSchema = aDlg.getSchema();
+ }
+
+ // did we get a name
+ if(m_sName.isEmpty())
+ return false;
+ }
+ catch(Exception&)
+ {
+ OSL_FAIL("OTableController::doSaveDoc: nothing is expected to happen here!");
+ }
+
+ bool bAlter = false;
+ bool bError = false;
+ SQLExceptionInfo aInfo;
+ try
+ {
+ // check the columns for double names
+ if(!checkColumns(bNew || !xTables->hasByName(m_sName)))
+ {
+ return false;
+ }
+
+ Reference<XPropertySet> xTable;
+ if(bNew || !xTables->hasByName(m_sName)) // just to make sure the table already exists
+ {
+ dropTable(xTables,m_sName);
+
+ Reference<XDataDescriptorFactory> xFact(xTables,UNO_QUERY);
+ OSL_ENSURE(xFact.is(),"OTableController::doSaveDoc: No XDataDescriptorFactory available!");
+ xTable = xFact->createDataDescriptor();
+ OSL_ENSURE(xTable.is(),"OTableController::doSaveDoc: Create query failed!");
+ // to set the name is only allowed when the query is new
+ xTable->setPropertyValue(PROPERTY_CATALOGNAME,makeAny(sCatalog));
+ xTable->setPropertyValue(PROPERTY_SCHEMANAME,makeAny(sSchema));
+ xTable->setPropertyValue(PROPERTY_NAME,makeAny(m_sName));
+
+ // now append the columns
+ Reference<XColumnsSupplier> xColSup(xTable,UNO_QUERY);
+ appendColumns(xColSup,bNew);
+ // now append the primary key
+ Reference<XKeysSupplier> xKeySup(xTable,UNO_QUERY);
+ appendPrimaryKey(xKeySup,bNew);
+ }
+ // now set the properties
+ if(bNew)
+ {
+ Reference<XAppend> xAppend(xTables,UNO_QUERY);
+ OSL_ENSURE(xAppend.is(),"OTableController::doSaveDoc: No XAppend Interface!");
+ xAppend->appendByDescriptor(xTable);
+
+ assignTable();
+ if(!m_xTable.is()) // correct name and try again
+ {
+ // it can be that someone inserted new data for us
+ m_sName = ::dbtools::composeTableName( getConnection()->getMetaData(), xTable, ::dbtools::EComposeRule::InDataManipulation, false );
+ assignTable();
+ }
+ // now check if our datasource has set a tablefilter and if append the new table name to it
+ ::dbaui::appendToFilter(getConnection(), m_sName, getORB(), getFrameWeld()); // we are not interested in the return value
+ Reference< frame::XTitleChangeListener> xEventListener(impl_getTitleHelper_throw(),UNO_QUERY);
+ if ( xEventListener.is() )
+ {
+ frame::TitleChangedEvent aEvent;
+ xEventListener->titleChanged(aEvent);
+ }
+ releaseNumberForComponent();
+ }
+ else if(m_xTable.is())
+ {
+ bAlter = true;
+ alterColumns();
+ }
+ reSyncRows();
+ }
+ catch(const SQLContext& e)
+ {
+ aInfo = SQLExceptionInfo(e);
+ }
+ catch(const SQLWarning& e)
+ {
+ aInfo = SQLExceptionInfo(e);
+ }
+ catch(const SQLException& e)
+ {
+ aInfo = SQLExceptionInfo(e);
+ }
+ catch(const ElementExistException& )
+ {
+ OUString sText( DBA_RES( STR_NAME_ALREADY_EXISTS ) );
+ sText = sText.replaceFirst( "#" , m_sName);
+ OSQLMessageBox aDlg(getFrameWeld(), DBA_RES( STR_ERROR_DURING_CREATION ), sText, MessBoxStyle::Ok, MessageType::Error);
+ aDlg.run();
+ bError = true;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ bError = true;
+ }
+
+ if ( aInfo.isValid() )
+ aInfo.prepend( DBA_RES( STR_TABLEDESIGN_SAVE_ERROR ) );
+ showError(aInfo);
+
+ if (aInfo.isValid() || bError)
+ {
+ if(!bAlter || bNew)
+ {
+ m_sName.clear();
+ stopTableListening();
+ m_xTable = nullptr;
+ }
+ }
+ return ! (aInfo.isValid() || bError);
+}
+
+void OTableController::doEditIndexes()
+{
+ // table needs to be saved before editing indexes
+ if (m_bNew || isModified())
+ {
+ std::unique_ptr<weld::MessageDialog> xAsk(Application::CreateMessageDialog(getFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ DBA_RES(STR_QUERY_SAVE_TABLE_EDIT_INDEXES)));
+ if (RET_YES != xAsk->run())
+ return;
+
+ if (!doSaveDoc(false))
+ return;
+
+ OSL_ENSURE(!m_bNew && !isModified(), "OTableController::doEditIndexes: what the hell did doSaveDoc do?");
+ }
+
+ Reference< XNameAccess > xIndexes; // will be the keys of the table
+ Sequence< OUString > aFieldNames; // will be the column names of the table
+ try
+ {
+ // get the keys
+ Reference< XIndexesSupplier > xIndexesSupp(m_xTable, UNO_QUERY);
+ if (xIndexesSupp.is())
+ {
+ xIndexes = xIndexesSupp->getIndexes();
+ OSL_ENSURE(xIndexes.is(), "OTableController::doEditIndexes: no keys got from the indexes supplier!");
+ }
+ else
+ OSL_FAIL("OTableController::doEditIndexes: should never have reached this (no indexes supplier)!");
+
+ // get the field names
+ Reference< XColumnsSupplier > xColSupp(m_xTable, UNO_QUERY);
+ OSL_ENSURE(xColSupp.is(), "OTableController::doEditIndexes: no columns supplier!");
+ if (xColSupp.is())
+ {
+ Reference< XNameAccess > xCols = xColSupp->getColumns();
+ OSL_ENSURE(xCols.is(), "OTableController::doEditIndexes: no columns!");
+ if (xCols.is())
+ aFieldNames = xCols->getElementNames();
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+
+ if (!xIndexes.is())
+ return;
+
+ DbaIndexDialog aDialog(getFrameWeld(), aFieldNames, xIndexes, getConnection(), getORB());
+ if (RET_OK != aDialog.run())
+ return;
+
+}
+
+void OTableController::impl_initialize()
+{
+ try
+ {
+ OTableController_BASE::impl_initialize();
+
+ const NamedValueCollection& rArguments( getInitParams() );
+
+ rArguments.get_ensureType( PROPERTY_CURRENTTABLE, m_sName );
+
+ // read autoincrement value set in the datasource
+ ::dbaui::fillAutoIncrementValue(getDataSource(),m_bAllowAutoIncrementValue,m_sAutoIncrementValue);
+
+ assignTable();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+
+ try
+ {
+ ::dbaui::fillTypeInfo(getConnection(),m_sTypeNames,m_aTypeInfo,m_aTypeInfoIndex); // fill the needed type information
+ }
+ catch(const SQLException&)
+ {
+ OSQLWarningBox aWarning(getFrameWeld(), DBA_RES( STR_NO_TYPE_INFO_AVAILABLE));
+ aWarning.run();
+ throw;
+ }
+ try
+ {
+ loadData(); // fill the column information from the table
+ getView()->initialize(); // show the windows and fill with our information
+ ClearUndoManager();
+ setModified(false); // and we are not modified yet
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+bool OTableController::Construct(vcl::Window* pParent)
+{
+ setView( VclPtr<OTableDesignView>::Create( pParent, getORB(), *this ) );
+ OTableController_BASE::Construct(pParent);
+ return true;
+}
+
+sal_Bool SAL_CALL OTableController::suspend(sal_Bool /*_bSuspend*/)
+{
+ if ( getBroadcastHelper().bInDispose || getBroadcastHelper().bDisposed )
+ return true;
+
+ SolarMutexGuard aSolarGuard;
+ ::osl::MutexGuard aGuard( getMutex() );
+ if ( getView() && getView()->IsInModalMode() )
+ return false;
+ if ( getView() )
+ static_cast<OTableDesignView*>(getView())->GrabFocus();
+ bool bCheck = true;
+ if ( isModified() )
+ {
+ if ( std::any_of(m_vRowList.begin(),m_vRowList.end(),
+ std::mem_fn(&OTableRow::isValid)) )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(getFrameWeld(), "dbaccess/ui/tabledesignsavemodifieddialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("TableDesignSaveModifiedDialog"));
+ switch (xQuery->run())
+ {
+ case RET_YES:
+ Execute(ID_BROWSER_SAVEDOC,Sequence<PropertyValue>());
+ if ( isModified() )
+ bCheck = false; // when we save the table this must be false else some press cancel
+ break;
+ case RET_CANCEL:
+ bCheck = false;
+ break;
+ default:
+ break;
+ }
+ }
+ else if ( !m_bNew )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(getFrameWeld(), "dbaccess/ui/deleteallrowsdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("DeleteAllRowsDialog"));
+ switch (xQuery->run())
+ {
+ case RET_YES:
+ {
+ try
+ {
+ Reference<XTablesSupplier> xTablesSup(getConnection(),UNO_QUERY);
+ Reference<XNameAccess> xTables = xTablesSup->getTables();
+ dropTable(xTables,m_sName);
+ }
+ catch(const Exception&)
+ {
+ OSL_FAIL("OTableController::suspend: nothing is expected to happen here!");
+ }
+
+ }
+ break;
+ case RET_CANCEL:
+ bCheck = false;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return bCheck;
+}
+
+void OTableController::describeSupportedFeatures()
+{
+ OSingleDocumentController::describeSupportedFeatures();
+
+ implDescribeSupportedFeature( ".uno:Redo", ID_BROWSER_REDO, CommandGroup::EDIT );
+ implDescribeSupportedFeature( ".uno:Save", ID_BROWSER_SAVEDOC, CommandGroup::EDIT );
+ implDescribeSupportedFeature( ".uno:Undo", ID_BROWSER_UNDO, CommandGroup::EDIT );
+ implDescribeSupportedFeature( ".uno:NewDoc", SID_NEWDOC, CommandGroup::DOCUMENT );
+ implDescribeSupportedFeature( ".uno:SaveAs", ID_BROWSER_SAVEASDOC, CommandGroup::DOCUMENT );
+ implDescribeSupportedFeature( ".uno:DBIndexDesign", SID_INDEXDESIGN, CommandGroup::APPLICATION );
+ implDescribeSupportedFeature( ".uno:EditDoc", ID_BROWSER_EDITDOC, CommandGroup::EDIT );
+ implDescribeSupportedFeature( ".uno:GetUndoStrings", SID_GETUNDOSTRINGS );
+ implDescribeSupportedFeature( ".uno:GetRedoStrings", SID_GETREDOSTRINGS );
+}
+
+void OTableController::impl_onModifyChanged()
+{
+ OSingleDocumentController::impl_onModifyChanged();
+ InvalidateFeature( SID_INDEXDESIGN );
+}
+
+void SAL_CALL OTableController::disposing( const EventObject& _rSource )
+{
+ if ( _rSource.Source == m_xTable )
+ { // some deleted our table so we have a new one
+ stopTableListening();
+ m_xTable = nullptr;
+ m_bNew = true;
+ setModified(true);
+ }
+ else
+ OTableController_BASE::disposing( _rSource );
+}
+
+void OTableController::losingConnection( )
+{
+ // let the base class do its reconnect
+ OTableController_BASE::losingConnection( );
+
+ // remove from the table
+ Reference< XComponent > xComponent(m_xTable, UNO_QUERY);
+ if (xComponent.is())
+ {
+ Reference<XEventListener> xEvtL( static_cast< ::cppu::OWeakObject*>(this), UNO_QUERY);
+ xComponent->removeEventListener(xEvtL);
+ }
+ stopTableListening();
+ m_xTable = nullptr;
+ assignTable();
+ if(!m_xTable.is())
+ {
+ m_bNew = true;
+ setModified(true);
+ }
+ InvalidateAll();
+}
+
+TOTypeInfoSP OTableController::getTypeInfoByType(sal_Int32 _nDataType) const
+{
+ return queryTypeInfoByType(_nDataType,m_aTypeInfo);
+}
+
+void OTableController::appendColumns(Reference<XColumnsSupplier> const & _rxColSup, bool _bNew, bool _bKeyColumns)
+{
+ try
+ {
+ // now append the columns
+ OSL_ENSURE(_rxColSup.is(),"No columns supplier");
+ if(!_rxColSup.is())
+ return;
+ Reference<XNameAccess> xColumns = _rxColSup->getColumns();
+ OSL_ENSURE(xColumns.is(),"No columns");
+ Reference<XDataDescriptorFactory> xColumnFactory(xColumns,UNO_QUERY);
+
+ Reference<XAppend> xAppend(xColumns,UNO_QUERY);
+ OSL_ENSURE(xAppend.is(),"No XAppend Interface!");
+
+ for (auto const& row : m_vRowList)
+ {
+ OSL_ENSURE(row,"OTableRow is null!");
+ OFieldDescription* pField = row->GetActFieldDescr();
+ if ( !pField || (!_bNew && row->IsReadOnly() && !_bKeyColumns) )
+ continue;
+
+ Reference<XPropertySet> xColumn;
+ if(pField->IsPrimaryKey() || !_bKeyColumns)
+ xColumn = xColumnFactory->createDataDescriptor();
+ if(xColumn.is())
+ {
+ if(!_bKeyColumns)
+ ::dbaui::setColumnProperties(xColumn,pField);
+ else
+ xColumn->setPropertyValue(PROPERTY_NAME,makeAny(pField->GetName()));
+
+ xAppend->appendByDescriptor(xColumn);
+ xColumn = nullptr;
+ // now only the settings are missing
+ if(xColumns->hasByName(pField->GetName()))
+ {
+ xColumns->getByName(pField->GetName()) >>= xColumn;
+ if(xColumn.is())
+ pField->copyColumnSettingsTo(xColumn);
+ }
+ else
+ {
+ OSL_FAIL("OTableController::appendColumns: invalid field name!");
+ }
+
+ }
+ }
+ }
+ catch(const SQLException& )
+ {
+ showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+}
+
+void OTableController::appendPrimaryKey(Reference<XKeysSupplier> const & _rxSup, bool _bNew)
+{
+ if(!_rxSup.is())
+ return; // the database doesn't support keys
+
+ OSL_ENSURE(_rxSup.is(),"No XKeysSupplier!");
+ Reference<XIndexAccess> xKeys = _rxSup->getKeys();
+ Reference<XPropertySet> xProp;
+ if (!xKeys.is())
+ return;
+ const sal_Int32 nCount = xKeys->getCount();
+ for(sal_Int32 i=0;i< nCount ;++i)
+ {
+ xKeys->getByIndex(i) >>= xProp;
+ sal_Int32 nKeyType = 0;
+ xProp->getPropertyValue(PROPERTY_TYPE) >>= nKeyType;
+ if(KeyType::PRIMARY == nKeyType)
+ {
+ return; // primary key already exists after appending a column
+ }
+ }
+ Reference<XDataDescriptorFactory> xKeyFactory(xKeys,UNO_QUERY);
+ OSL_ENSURE(xKeyFactory.is(),"No XDataDescriptorFactory Interface!");
+ if ( !xKeyFactory.is() )
+ return;
+ Reference<XAppend> xAppend(xKeyFactory,UNO_QUERY);
+ OSL_ENSURE(xAppend.is(),"No XAppend Interface!");
+
+ Reference<XPropertySet> xKey = xKeyFactory->createDataDescriptor();
+ OSL_ENSURE(xKey.is(),"Key is null!");
+ xKey->setPropertyValue(PROPERTY_TYPE,makeAny(KeyType::PRIMARY));
+
+ Reference<XColumnsSupplier> xColSup(xKey,UNO_QUERY);
+ if(xColSup.is())
+ {
+ appendColumns(xColSup,_bNew,true);
+ Reference<XNameAccess> xColumns = xColSup->getColumns();
+ if(xColumns->hasElements())
+ xAppend->appendByDescriptor(xKey);
+ }
+}
+
+void OTableController::loadData()
+{
+ // if the data structure already exists, empty it
+ m_vRowList.clear();
+
+ std::shared_ptr<OTableRow> pTabEdRow;
+ Reference< XDatabaseMetaData> xMetaData = getMetaData( );
+ // fill data structure with data from DataDefinitionObject
+ if(m_xTable.is() && xMetaData.is())
+ {
+ Reference<XColumnsSupplier> xColSup(m_xTable,UNO_QUERY);
+ OSL_ENSURE(xColSup.is(),"No XColumnsSupplier!");
+ Reference<XNameAccess> xColumns = xColSup->getColumns();
+ // ReadOnly-Flag
+ // For Drop no row may be editable
+ // For Add only the empty rows may be editable
+ // For Add and Drop all rows can be edited
+ // sal_Bool bReadOldRow = xMetaData->supportsAlterTableWithAddColumn() && xMetaData->supportsAlterTableWithDropColumn();
+ bool bIsAlterAllowed = isAlterAllowed();
+
+ const Sequence<OUString> aColNames = xColumns->getElementNames();
+ for(const OUString& rColumn : aColNames)
+ {
+ Reference<XPropertySet> xColumn;
+ xColumns->getByName(rColumn) >>= xColumn;
+ sal_Int32 nType = 0;
+ sal_Int32 nScale = 0;
+ sal_Int32 nPrecision = 0;
+ sal_Int32 nNullable = 0;
+ sal_Int32 nFormatKey = 0;
+ sal_Int32 nAlign = 0;
+
+ bool bIsAutoIncrement = false, bIsCurrency = false;
+ OUString sName,sDescription,sTypeName,sHelpText;
+ Any aControlDefault;
+
+ // get the properties from the column
+ xColumn->getPropertyValue(PROPERTY_NAME) >>= sName;
+ xColumn->getPropertyValue(PROPERTY_TYPENAME) >>= sTypeName;
+ xColumn->getPropertyValue(PROPERTY_ISNULLABLE) >>= nNullable;
+ xColumn->getPropertyValue(PROPERTY_ISAUTOINCREMENT) >>= bIsAutoIncrement;
+ xColumn->getPropertyValue(PROPERTY_ISCURRENCY) >>= bIsCurrency;
+ xColumn->getPropertyValue(PROPERTY_TYPE) >>= nType;
+ xColumn->getPropertyValue(PROPERTY_SCALE) >>= nScale;
+ xColumn->getPropertyValue(PROPERTY_PRECISION) >>= nPrecision;
+ xColumn->getPropertyValue(PROPERTY_DESCRIPTION) >>= sDescription;
+
+ if(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_HELPTEXT))
+ xColumn->getPropertyValue(PROPERTY_HELPTEXT) >>= sHelpText;
+
+ if(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_CONTROLDEFAULT))
+ aControlDefault = xColumn->getPropertyValue(PROPERTY_CONTROLDEFAULT);
+ if(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_FORMATKEY))
+ xColumn->getPropertyValue(PROPERTY_FORMATKEY) >>= nFormatKey;
+ if(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_ALIGN))
+ xColumn->getPropertyValue(PROPERTY_ALIGN) >>= nAlign;
+
+ pTabEdRow = std::make_shared<OTableRow>();
+ pTabEdRow->SetReadOnly(!bIsAlterAllowed);
+ // search for type
+ bool bForce;
+ OUString const sCreate("x");
+ TOTypeInfoSP pTypeInfo = ::dbaui::getTypeInfoFromType(m_aTypeInfo,nType,sTypeName,sCreate,nPrecision,nScale,bIsAutoIncrement,bForce);
+ if ( !pTypeInfo )
+ pTypeInfo = m_pTypeInfo;
+ pTabEdRow->SetFieldType( pTypeInfo, bForce );
+
+ OFieldDescription* pActFieldDescr = pTabEdRow->GetActFieldDescr();
+ OSL_ENSURE(pActFieldDescr, "OTableController::loadData: invalid field description generated by the table row!");
+ if ( pActFieldDescr )
+ {
+ pActFieldDescr->SetName(sName);
+ pActFieldDescr->SetFormatKey(nFormatKey);
+ pActFieldDescr->SetDescription(sDescription);
+ pActFieldDescr->SetHelpText(sHelpText);
+ pActFieldDescr->SetAutoIncrement(bIsAutoIncrement);
+ pActFieldDescr->SetHorJustify(dbaui::mapTextJustify(nAlign));
+ pActFieldDescr->SetCurrency(bIsCurrency);
+
+ // special data
+ pActFieldDescr->SetIsNullable(nNullable);
+ pActFieldDescr->SetControlDefault(aControlDefault);
+ pActFieldDescr->SetPrecision(nPrecision);
+ pActFieldDescr->SetScale(nScale);
+ }
+ m_vRowList.push_back( pTabEdRow);
+ }
+ // fill the primary key information
+ Reference<XNameAccess> xKeyColumns = getKeyColumns();
+ if(xKeyColumns.is())
+ {
+ const Sequence<OUString> aKeyColumnNames = xKeyColumns->getElementNames();
+ for(const OUString& rKeyColumn : aKeyColumnNames)
+ {
+ for(std::shared_ptr<OTableRow> const& pRow : m_vRowList)
+ {
+ if(pRow->GetActFieldDescr()->GetName() == rKeyColumn)
+ {
+ pRow->SetPrimaryKey(true);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // fill empty rows
+
+ OTypeInfoMap::const_iterator aTypeIter = m_aTypeInfo.find(DataType::VARCHAR);
+ if(aTypeIter == m_aTypeInfo.end())
+ aTypeIter = m_aTypeInfo.begin();
+
+ OSL_ENSURE(aTypeIter != m_aTypeInfo.end(),"We have no type information!");
+
+ bool bReadRow = !isAddAllowed();
+ for(sal_Int32 i=m_vRowList.size(); i < NEWCOLS; i++ )
+ {
+ pTabEdRow = std::make_shared<OTableRow>();
+ pTabEdRow->SetReadOnly(bReadRow);
+ m_vRowList.push_back( pTabEdRow);
+ }
+}
+
+Reference<XNameAccess> OTableController::getKeyColumns() const
+{
+ return getPrimaryKeyColumns_throw(m_xTable);
+}
+
+bool OTableController::checkColumns(bool _bNew)
+{
+ bool bOk = true;
+ bool bFoundPKey = false;
+ Reference< XDatabaseMetaData > xMetaData = getMetaData( );
+ DatabaseMetaData aMetaData( getConnection() );
+
+ ::comphelper::UStringMixEqual bCase(!xMetaData.is() || xMetaData->supportsMixedCaseQuotedIdentifiers());
+ std::vector< std::shared_ptr<OTableRow> >::const_iterator aIter = m_vRowList.begin();
+ std::vector< std::shared_ptr<OTableRow> >::const_iterator aEnd = m_vRowList.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ OFieldDescription* pFieldDesc = (*aIter)->GetActFieldDescr();
+ if (pFieldDesc && !pFieldDesc->GetName().isEmpty())
+ {
+ bFoundPKey |= (*aIter)->IsPrimaryKey();
+ // first check for duplicate names
+ bool bDuplicateNameFound = std::any_of(aIter+1, aEnd,
+ [&bCase, &pFieldDesc](const std::shared_ptr<OTableRow>& rxRow) {
+ OFieldDescription* pCompareDesc = rxRow->GetActFieldDescr();
+ return pCompareDesc && bCase(pCompareDesc->GetName(),pFieldDesc->GetName());
+ });
+ if (bDuplicateNameFound)
+ {
+ OUString strMessage = DBA_RES(STR_TABLEDESIGN_DUPLICATE_NAME);
+ strMessage = strMessage.replaceFirst("$column$", pFieldDesc->GetName());
+ OSQLWarningBox aWarning(getFrameWeld(), strMessage);
+ aWarning.run();
+ return false;
+ }
+ }
+ }
+ if ( _bNew && !bFoundPKey && aMetaData.supportsPrimaryKeys() )
+ {
+ OUString sTitle(DBA_RES(STR_TABLEDESIGN_NO_PRIM_KEY_HEAD));
+ OUString sMsg(DBA_RES(STR_TABLEDESIGN_NO_PRIM_KEY));
+ OSQLMessageBox aBox(getFrameWeld(), sTitle,sMsg, MessBoxStyle::YesNoCancel | MessBoxStyle::DefaultYes);
+
+ switch (aBox.run())
+ {
+ case RET_YES:
+ {
+ auto pNewRow = std::make_shared<OTableRow>();
+ TOTypeInfoSP pTypeInfo = ::dbaui::queryPrimaryKeyType(m_aTypeInfo);
+ if ( !pTypeInfo )
+ break;
+
+ pNewRow->SetFieldType( pTypeInfo );
+ OFieldDescription* pActFieldDescr = pNewRow->GetActFieldDescr();
+
+ pActFieldDescr->SetAutoIncrement(false);
+ pActFieldDescr->SetIsNullable(ColumnValue::NO_NULLS);
+
+ pActFieldDescr->SetName( createUniqueName("ID" ));
+ pActFieldDescr->SetPrimaryKey( true );
+ m_vRowList.insert(m_vRowList.begin(),pNewRow);
+
+ static_cast<OTableDesignView*>(getView())->GetEditorCtrl()->Invalidate();
+ static_cast<OTableDesignView*>(getView())->GetEditorCtrl()->RowInserted(0);
+ }
+ break;
+ case RET_CANCEL:
+ bOk = false;
+ break;
+ }
+ }
+ return bOk;
+}
+
+void OTableController::alterColumns()
+{
+ Reference<XColumnsSupplier> xColSup(m_xTable,UNO_QUERY_THROW);
+
+ Reference<XNameAccess> xColumns = xColSup->getColumns();
+ Reference<XIndexAccess> xIdxColumns(xColumns,UNO_QUERY_THROW);
+ OSL_ENSURE(xColumns.is(),"No columns");
+ if ( !xColumns.is() )
+ return;
+ Reference<XAlterTable> xAlter(m_xTable,UNO_QUERY); // can be null
+
+ sal_Int32 nColumnCount = xIdxColumns->getCount();
+ Reference<XDrop> xDrop(xColumns,UNO_QUERY); // can be null
+ Reference<XAppend> xAppend(xColumns,UNO_QUERY); // can be null
+ Reference<XDataDescriptorFactory> xColumnFactory(xColumns,UNO_QUERY); // can be null
+
+ bool bReload = false; // refresh the data
+
+ // contains all columns names which are already handled those which are not in the list will be deleted
+ Reference< XDatabaseMetaData> xMetaData = getMetaData( );
+
+ std::set<OUString, comphelper::UStringMixLess> aColumns(
+ comphelper::UStringMixLess(
+ !xMetaData.is()
+ || xMetaData->supportsMixedCaseQuotedIdentifiers()));
+ std::vector< std::shared_ptr<OTableRow> >::const_iterator aIter = m_vRowList.begin();
+ std::vector< std::shared_ptr<OTableRow> >::const_iterator aEnd = m_vRowList.end();
+ // first look for columns where something other than the name changed
+ for(sal_Int32 nPos = 0;aIter != aEnd;++aIter,++nPos)
+ {
+ OSL_ENSURE(*aIter,"OTableRow is null!");
+ OFieldDescription* pField = (*aIter)->GetActFieldDescr();
+ if ( !pField )
+ continue;
+ if ( (*aIter)->IsReadOnly() )
+ {
+ aColumns.insert(pField->GetName());
+ continue;
+ }
+
+ Reference<XPropertySet> xColumn;
+ if ( xColumns->hasByName(pField->GetName()) )
+ {
+ aColumns.insert(pField->GetName());
+ xColumns->getByName(pField->GetName()) >>= xColumn;
+ OSL_ENSURE(xColumn.is(),"Column is null!");
+
+ sal_Int32 nType=0,nPrecision=0,nScale=0,nNullable=0;
+ bool bAutoIncrement = false;
+ OUString sTypeName,sDescription;
+
+ xColumn->getPropertyValue(PROPERTY_TYPE) >>= nType;
+ xColumn->getPropertyValue(PROPERTY_PRECISION) >>= nPrecision;
+ xColumn->getPropertyValue(PROPERTY_SCALE) >>= nScale;
+ xColumn->getPropertyValue(PROPERTY_ISNULLABLE) >>= nNullable;
+ xColumn->getPropertyValue(PROPERTY_ISAUTOINCREMENT) >>= bAutoIncrement;
+ xColumn->getPropertyValue(PROPERTY_DESCRIPTION) >>= sDescription;
+
+ try { xColumn->getPropertyValue(PROPERTY_TYPENAME) >>= sTypeName; }
+ catch( const Exception& )
+ {
+ OSL_FAIL( "no TypeName property?!" );
+ // since this is a last minute fix for #i41785#, I want to be on the safe side,
+ // and catch errors here as early as possible (instead of the whole process of altering
+ // the columns failing)
+ // Normally, sdbcx::Column objects are expected to have a TypeName property
+ }
+
+ // check if something changed
+ if((nType != pField->GetType() ||
+ sTypeName != pField->GetTypeName() ||
+ (nPrecision != pField->GetPrecision() && nPrecision ) ||
+ nScale != pField->GetScale() ||
+ nNullable != pField->GetIsNullable() ||
+ sDescription != pField->GetDescription() ||
+ bAutoIncrement != pField->IsAutoIncrement())&&
+ xColumnFactory.is())
+ {
+ Reference<XPropertySet> xNewColumn = xColumnFactory->createDataDescriptor();
+ ::dbaui::setColumnProperties(xNewColumn,pField);
+ // first try to alter the column
+ bool bNotOk = false;
+ try
+ {
+ // first try if we can alter the column
+ if(xAlter.is())
+ xAlter->alterColumnByName(pField->GetName(),xNewColumn);
+ }
+ catch(const SQLException&)
+ {
+ if(xDrop.is() && xAppend.is())
+ {
+ OUString aMessage( DBA_RES( STR_TABLEDESIGN_ALTER_ERROR ) );
+ aMessage = aMessage.replaceFirst( "$column$", pField->GetName() );
+
+ SQLExceptionInfo aError( ::cppu::getCaughtException() );
+ OSQLWarningBox aMsg(getFrameWeld(), aMessage, MessBoxStyle::YesNo | MessBoxStyle::DefaultYes , &aError);
+ bNotOk = aMsg.run() == RET_YES;
+ }
+ else
+ throw;
+ }
+ // if something went wrong or we can't alter columns
+ // drop and append a new one
+ if((!xAlter.is() || bNotOk) && xDrop.is() && xAppend.is())
+ {
+ xDrop->dropByName(pField->GetName());
+ try
+ {
+ xAppend->appendByDescriptor(xNewColumn);
+ }
+ catch(const SQLException&)
+ { // an error occurred so we try to reactivate the old one
+ xAppend->appendByDescriptor(xColumn);
+ throw;
+ }
+ }
+ // exceptions are caught outside
+ xNewColumn = nullptr;
+ if(xColumns->hasByName(pField->GetName()))
+ xColumns->getByName(pField->GetName()) >>= xColumn;
+ bReload = true;
+ }
+
+ }
+ else if(xColumnFactory.is() && xAlter.is() && nPos < nColumnCount)
+ { // we can't find the column so we could try it with the index before we drop and append a new column
+ try
+ {
+ Reference<XPropertySet> xNewColumn = xColumnFactory->createDataDescriptor();
+ ::dbaui::setColumnProperties(xNewColumn,pField);
+ xAlter->alterColumnByIndex(nPos,xNewColumn);
+ if(xColumns->hasByName(pField->GetName()))
+ { // ask for the append by name
+ aColumns.insert(pField->GetName());
+ xColumns->getByName(pField->GetName()) >>= xColumn;
+ if(xColumn.is())
+ pField->copyColumnSettingsTo(xColumn);
+ }
+ else
+ {
+ OSL_FAIL("OTableController::alterColumns: invalid column (2)!");
+ }
+ }
+ catch(const SQLException&)
+ { // we couldn't alter the column so we have to add new columns
+ SQLExceptionInfo aError( ::cppu::getCaughtException() );
+ bReload = true;
+ if(xDrop.is() && xAppend.is())
+ {
+ OUString aMessage(DBA_RES(STR_TABLEDESIGN_ALTER_ERROR));
+ aMessage = aMessage.replaceFirst("$column$",pField->GetName());
+ OSQLWarningBox aMsg(getFrameWeld(), aMessage, MessBoxStyle::YesNo | MessBoxStyle::DefaultYes, &aError);
+ if (aMsg.run() != RET_YES)
+ {
+ Reference<XPropertySet> xNewColumn(xIdxColumns->getByIndex(nPos),UNO_QUERY_THROW);
+ OUString sName;
+ xNewColumn->getPropertyValue(PROPERTY_NAME) >>= sName;
+ aColumns.insert(sName);
+ aColumns.insert(pField->GetName());
+ continue;
+ }
+ }
+ else
+ throw;
+ }
+ }
+ else
+ bReload = true;
+ }
+ // alter column settings
+
+ // first look for columns where something other than the name changed
+ for (auto const& row : m_vRowList)
+ {
+ OSL_ENSURE(row,"OTableRow is null!");
+ OFieldDescription* pField = row->GetActFieldDescr();
+ if ( !pField )
+ continue;
+ if ( row->IsReadOnly() )
+ {
+ aColumns.insert(pField->GetName());
+ continue;
+ }
+
+ Reference<XPropertySet> xColumn;
+ if ( xColumns->hasByName(pField->GetName()) )
+ {
+ xColumns->getByName(pField->GetName()) >>= xColumn;
+ Reference<XPropertySetInfo> xInfo = xColumn->getPropertySetInfo();
+ if ( xInfo->hasPropertyByName(PROPERTY_HELPTEXT) )
+ xColumn->setPropertyValue(PROPERTY_HELPTEXT,makeAny(pField->GetHelpText()));
+
+ if(xInfo->hasPropertyByName(PROPERTY_CONTROLDEFAULT))
+ xColumn->setPropertyValue(PROPERTY_CONTROLDEFAULT,pField->GetControlDefault());
+ if(xInfo->hasPropertyByName(PROPERTY_FORMATKEY))
+ xColumn->setPropertyValue(PROPERTY_FORMATKEY,makeAny(pField->GetFormatKey()));
+ if(xInfo->hasPropertyByName(PROPERTY_ALIGN))
+ xColumn->setPropertyValue(PROPERTY_ALIGN,makeAny(dbaui::mapTextAllign(pField->GetHorJustify())));
+ }
+ }
+ // second drop all columns which could be found by name
+ Reference<XNameAccess> xKeyColumns = getKeyColumns();
+ // now we have to look for the columns who could be deleted
+ if ( xDrop.is() )
+ {
+ const Sequence<OUString> aColNames = xColumns->getElementNames();
+ for(const OUString& rColumnName : aColNames)
+ {
+ if(aColumns.find(rColumnName) == aColumns.end()) // found a column to delete
+ {
+ if(xKeyColumns.is() && xKeyColumns->hasByName(rColumnName)) // check if this column is a member of the primary key
+ {
+ OUString aMsgT(DBA_RES(STR_TBL_COLUMN_IS_KEYCOLUMN));
+ aMsgT = aMsgT.replaceFirst("$column$",rColumnName);
+ OUString aTitle(DBA_RES(STR_TBL_COLUMN_IS_KEYCOLUMN_TITLE));
+ OSQLMessageBox aMsg(getFrameWeld(), aTitle, aMsgT, MessBoxStyle::YesNo| MessBoxStyle::DefaultYes);
+ if (aMsg.run() == RET_YES)
+ {
+ xKeyColumns = nullptr;
+ dropPrimaryKey();
+ }
+ else
+ {
+ bReload = true;
+ continue;
+ }
+ }
+ try
+ {
+ xDrop->dropByName(rColumnName);
+ }
+ catch (const SQLException&)
+ {
+ OUString sError( DBA_RES( STR_TABLEDESIGN_COULD_NOT_DROP_COL ) );
+ sError = sError.replaceFirst( "$column$", rColumnName );
+
+ SQLException aNewException;
+ aNewException.Message = sError;
+ aNewException.SQLState = "S1000";
+ aNewException.NextException = ::cppu::getCaughtException();
+
+ throw aNewException;
+ }
+ }
+ }
+ }
+
+ // third append the new columns
+ for(const auto& rxRow : m_vRowList)
+ {
+ OSL_ENSURE(rxRow,"OTableRow is null!");
+ OFieldDescription* pField = rxRow->GetActFieldDescr();
+ if ( !pField || rxRow->IsReadOnly() || aColumns.find(pField->GetName()) != aColumns.end() )
+ continue;
+
+ Reference<XPropertySet> xColumn;
+ if(!xColumns->hasByName(pField->GetName()))
+ {
+ if(xColumnFactory.is() && xAppend.is())
+ {// column not found by its name so we assume it is new
+ // Column is new
+ xColumn = xColumnFactory->createDataDescriptor();
+ ::dbaui::setColumnProperties(xColumn,pField);
+ xAppend->appendByDescriptor(xColumn);
+ if(xColumns->hasByName(pField->GetName()))
+ { // ask for the append by name
+ aColumns.insert(pField->GetName());
+ xColumns->getByName(pField->GetName()) >>= xColumn;
+ if(xColumn.is())
+ pField->copyColumnSettingsTo(xColumn);
+ }
+ else
+ {
+ OSL_FAIL("OTableController::alterColumns: invalid column!");
+ }
+ }
+ }
+ }
+
+ // check if we have to do something with the primary key
+ bool bNeedDropKey = false;
+ bool bNeedAppendKey = false;
+ if ( xKeyColumns.is() )
+ {
+ for(const auto& rxRow : m_vRowList)
+ {
+ OSL_ENSURE(rxRow,"OTableRow is null!");
+ OFieldDescription* pField = rxRow->GetActFieldDescr();
+ if ( !pField )
+ continue;
+
+ if ( pField->IsPrimaryKey()
+ && !xKeyColumns->hasByName( pField->GetName() )
+ )
+ { // new primary key column inserted which isn't already in the columns selection
+ bNeedDropKey = bNeedAppendKey = true;
+ break;
+ }
+ else if ( !pField->IsPrimaryKey()
+ && xKeyColumns->hasByName( pField->GetName() )
+ )
+ { // found a column which currently is in the primary key, but is marked not to be anymore
+ bNeedDropKey = bNeedAppendKey = true;
+ break;
+ }
+ }
+ }
+ else
+ { // no primary key available so we check if we should create one
+ bNeedAppendKey = true;
+ }
+
+ if ( bNeedDropKey && xKeyColumns.is() && xKeyColumns->getElementNames().hasElements() )
+ dropPrimaryKey();
+
+ if ( bNeedAppendKey )
+ {
+ Reference< XKeysSupplier > xKeySup( m_xTable, UNO_QUERY );
+ appendPrimaryKey( xKeySup ,false);
+ }
+
+ reSyncRows();
+
+ if ( bReload )
+ reload();
+}
+
+void OTableController::dropPrimaryKey()
+{
+ SQLExceptionInfo aInfo;
+ try
+ {
+ Reference<XKeysSupplier> xKeySup(m_xTable,UNO_QUERY);
+ Reference<XIndexAccess> xKeys;
+ if(xKeySup.is())
+ xKeys = xKeySup->getKeys();
+
+ if(xKeys.is())
+ {
+ Reference<XPropertySet> xProp;
+ for(sal_Int32 i=0;i< xKeys->getCount();++i)
+ {
+ xProp.set(xKeys->getByIndex(i),UNO_QUERY);
+ sal_Int32 nKeyType = 0;
+ xProp->getPropertyValue(PROPERTY_TYPE) >>= nKeyType;
+ if(KeyType::PRIMARY == nKeyType)
+ {
+ Reference<XDrop> xDrop(xKeys,UNO_QUERY);
+ xDrop->dropByIndex(i); // delete the key
+ break;
+ }
+ }
+ }
+ }
+ catch(const SQLContext& e)
+ {
+ aInfo = SQLExceptionInfo(e);
+ }
+ catch(const SQLWarning& e)
+ {
+ aInfo = SQLExceptionInfo(e);
+ }
+ catch(const SQLException& e)
+ {
+ aInfo = SQLExceptionInfo(e);
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+
+ showError(aInfo);
+}
+
+void OTableController::assignTable()
+{
+ // get the table
+ if(m_sName.isEmpty())
+ return;
+
+ Reference<XNameAccess> xNameAccess;
+ Reference<XTablesSupplier> xSup(getConnection(),UNO_QUERY);
+ if(!xSup.is())
+ return;
+
+ xNameAccess = xSup->getTables();
+ OSL_ENSURE(xNameAccess.is(),"no nameaccess for the queries!");
+
+ if(!xNameAccess->hasByName(m_sName))
+ return;
+
+ Reference<XPropertySet> xProp(xNameAccess->getByName(m_sName), css::uno::UNO_QUERY);
+ if (!xProp.is())
+ return;
+
+ m_xTable = xProp;
+ startTableListening();
+
+ // check if we set the table editable
+ Reference<XDatabaseMetaData> xMeta = getConnection()->getMetaData();
+ setEditable( xMeta.is() && !xMeta->isReadOnly() && (isAlterAllowed() || isDropAllowed() || isAddAllowed()) );
+ if(!isEditable())
+ {
+ for( const auto& rTableRow : m_vRowList )
+ {
+ rTableRow->SetReadOnly();
+ }
+ }
+ m_bNew = false;
+ // be notified when the table is in disposing
+ InvalidateAll();
+}
+
+bool OTableController::isAddAllowed() const
+{
+ Reference<XColumnsSupplier> xColsSup(m_xTable,UNO_QUERY);
+ bool bAddAllowed = !m_xTable.is();
+ if(xColsSup.is())
+ bAddAllowed = Reference<XAppend>(xColsSup->getColumns(),UNO_QUERY).is();
+
+ try
+ {
+ Reference< XDatabaseMetaData > xMetaData = getMetaData( );
+ bAddAllowed = bAddAllowed || ( xMetaData.is() && xMetaData->supportsAlterTableWithAddColumn());
+ }
+ catch(Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ bAddAllowed = false;
+ }
+
+ return bAddAllowed;
+}
+
+bool OTableController::isDropAllowed() const
+{
+ Reference<XColumnsSupplier> xColsSup(m_xTable,UNO_QUERY);
+ bool bDropAllowed = !m_xTable.is();
+ if(xColsSup.is())
+ {
+ Reference<XNameAccess> xNameAccess = xColsSup->getColumns();
+ bDropAllowed = Reference<XDrop>(xNameAccess,UNO_QUERY).is() && xNameAccess->hasElements();
+ }
+
+ Reference< XDatabaseMetaData> xMetaData = getMetaData( );
+ bDropAllowed = bDropAllowed || ( xMetaData.is() && xMetaData->supportsAlterTableWithDropColumn());
+
+ return bDropAllowed;
+}
+
+bool OTableController::isAlterAllowed() const
+{
+ bool bAllowed(!m_xTable.is() || Reference<XAlterTable>(m_xTable,UNO_QUERY).is());
+ return bAllowed;
+}
+
+void OTableController::reSyncRows()
+{
+ bool bAlterAllowed = isAlterAllowed();
+ bool bAddAllowed = isAddAllowed();
+ for (auto const& row : m_vRowList)
+ {
+ OSL_ENSURE(row,"OTableRow is null!");
+ OFieldDescription* pField = row->GetActFieldDescr();
+ if ( pField )
+ row->SetReadOnly(!bAlterAllowed);
+ else
+ row->SetReadOnly(!bAddAllowed);
+
+ }
+ static_cast<OTableDesignView*>(getView())->reSync(); // show the windows and fill with our information
+
+ ClearUndoManager();
+ setModified(false); // and we are not modified yet
+}
+
+OUString OTableController::createUniqueName(const OUString& _rName)
+{
+ OUString sName = _rName;
+ Reference< XDatabaseMetaData> xMetaData = getMetaData( );
+
+ ::comphelper::UStringMixEqual bCase(!xMetaData.is() || xMetaData->supportsMixedCaseQuotedIdentifiers());
+
+ auto lHasName = [&bCase, &sName](const std::shared_ptr<OTableRow>& rxRow) {
+ OFieldDescription* pFieldDesc = rxRow->GetActFieldDescr();
+ return pFieldDesc && !pFieldDesc->GetName().isEmpty() && bCase(sName, pFieldDesc->GetName());
+ };
+
+ sal_Int32 i = 0;
+ while(std::any_of(m_vRowList.begin(), m_vRowList.end(), lHasName))
+ {
+ // found a second name of _rName so we need another
+ sName = _rName + OUString::number(++i);
+ }
+ return sName;
+}
+
+OUString OTableController::getPrivateTitle() const
+{
+ OUString sTitle;
+ try
+ {
+ // get the table
+ if ( !m_sName.isEmpty() && getConnection().is() )
+ {
+ if ( m_xTable.is() )
+ sTitle = ::dbtools::composeTableName( getConnection()->getMetaData(), m_xTable, ::dbtools::EComposeRule::InDataManipulation, false );
+ else
+ sTitle = m_sName;
+ }
+ if ( sTitle.isEmpty() )
+ {
+ OUString aName = DBA_RES(STR_TBL_TITLE);
+ sTitle = aName.getToken(0,' ') + OUString::number(getCurrentStartNumber());
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("dbaccess");
+ }
+ return sTitle;
+}
+
+void OTableController::reload()
+{
+ loadData(); // fill the column information from the table
+ static_cast<OTableDesignView*>(getView())->reSync(); // show the windows and fill with our information
+ ClearUndoManager();
+ setModified(false); // and we are not modified yet
+ static_cast<OTableDesignView*>(getView())->Invalidate();
+}
+
+sal_Int32 OTableController::getFirstEmptyRowPosition()
+{
+ sal_Int32 nRet = 0;
+ bool bFoundElem = false;
+ for (auto const& row : m_vRowList)
+ {
+ if ( !row || !row->GetActFieldDescr() || row->GetActFieldDescr()->GetName().isEmpty() )
+ {
+ bFoundElem = true;
+ break;
+ }
+ ++nRet;
+ }
+ if (!bFoundElem)
+ {
+ bool bReadRow = !isAddAllowed();
+ auto pTabEdRow = std::make_shared<OTableRow>();
+ pTabEdRow->SetReadOnly(bReadRow);
+ nRet = m_vRowList.size();
+ m_vRowList.push_back( pTabEdRow);
+ }
+ return nRet;
+}
+
+bool OTableController::isAutoIncrementPrimaryKey() const
+{
+ return getSdbMetaData().isAutoIncrementPrimaryKey();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/tabledesign/TableDesignControl.cxx b/dbaccess/source/ui/tabledesign/TableDesignControl.cxx
new file mode 100644
index 000000000..2fe3e5ec9
--- /dev/null
+++ b/dbaccess/source/ui/tabledesign/TableDesignControl.cxx
@@ -0,0 +1,181 @@
+/* -*- 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 <TableDesignControl.hxx>
+#include <TableDesignView.hxx>
+#include <TableController.hxx>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <vcl/builder.hxx>
+#include <vcl/commandevent.hxx>
+#include <helpids.h>
+
+using namespace ::dbaui;
+using namespace ::svt;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::util;
+// Defines
+#define HANDLE_ID 0
+
+OTableRowView::OTableRowView(vcl::Window* pParent)
+ : EditBrowseBox(pParent, EditBrowseBoxFlags::NONE, WB_TABSTOP|WB_HIDE|WB_3DLOOK,
+ BrowserMode::COLUMNSELECTION | BrowserMode::MULTISELECTION |
+ BrowserMode::AUTOSIZE_LASTCOL | BrowserMode::KEEPHIGHLIGHT |
+ BrowserMode::HLINES | BrowserMode::VLINES)
+ , m_nDataPos(-1)
+ , m_nCurrentPos(-1)
+ , m_nCurUndoActId(0)
+{
+ SetHelpId(HID_TABDESIGN_BACKGROUND);
+ SetSizePixel(LogicToPixel(Size(40, 12), MapMode(MapUnit::MapAppFont)));
+}
+
+void OTableRowView::Init()
+{
+ EditBrowseBox::Init();
+
+ vcl::Font aFont( GetDataWindow().GetFont() );
+ aFont.SetWeight( WEIGHT_NORMAL );
+ GetDataWindow().SetFont( aFont );
+
+ // set font for the headings to light
+ aFont = GetFont();
+ aFont.SetWeight( WEIGHT_LIGHT );
+ SetFont(aFont);
+
+ // set up HandleColumn for at maximum 5 digits
+ InsertHandleColumn(static_cast<sal_uInt16>(GetTextWidth(OUString('0')) * 4)/*, sal_True */);
+
+ BrowserMode const nMode = BrowserMode::COLUMNSELECTION | BrowserMode::MULTISELECTION | BrowserMode::KEEPHIGHLIGHT |
+ BrowserMode::HLINES | BrowserMode::VLINES | BrowserMode::AUTOSIZE_LASTCOL;
+
+ SetMode(nMode);
+}
+
+void OTableRowView::KeyInput( const KeyEvent& rEvt )
+{
+ if (IsDeleteAllowed())
+ {
+ if (rEvt.GetKeyCode().GetCode() == KEY_DELETE && // Delete rows
+ !rEvt.GetKeyCode().IsShift() &&
+ !rEvt.GetKeyCode().IsMod1())
+ {
+ DeleteRows();
+ return;
+ }
+ if( rEvt.GetKeyCode().GetCode() == KEY_F2 )
+ {
+ css::util::URL aUrl;
+ aUrl.Complete = ".uno:DSBEditDoc";
+ GetView()->getController().dispatch( aUrl,Sequence< PropertyValue >() );
+ }
+ }
+ EditBrowseBox::KeyInput(rEvt);
+}
+
+void OTableRowView::Command(const CommandEvent& rEvt)
+{
+
+ switch (rEvt.GetCommand())
+ {
+ case CommandEventId::ContextMenu:
+ {
+ if (!rEvt.IsMouseEvent())
+ {
+ EditBrowseBox::Command(rEvt);
+ return;
+ }
+
+ sal_uInt16 nColId = GetColumnId(GetColumnAtXPosPixel(rEvt.GetMousePosPixel().X()));
+ long nRow = GetRowAtYPosPixel(rEvt.GetMousePosPixel().Y());
+
+ if ( nColId == HANDLE_ID )
+ {
+ VclBuilder aBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "dbaccess/ui/querycolmenu.ui", "");
+ VclPtr<PopupMenu> aContextMenu(aBuilder.get_menu("menu"));
+ long nSelectRowCount = GetSelectRowCount();
+ aContextMenu->EnableItem(aContextMenu->GetItemId("cut"), nSelectRowCount != 0);
+ aContextMenu->EnableItem(aContextMenu->GetItemId("copy"), nSelectRowCount != 0);
+ aContextMenu->EnableItem(aContextMenu->GetItemId("paste"), false);
+ aContextMenu->EnableItem(aContextMenu->GetItemId("delete"), false);
+ aContextMenu->Execute(this, rEvt.GetMousePosPixel());
+ OString sIdent = aContextMenu->GetCurItemIdent();
+ if (sIdent == "cut")
+ cut();
+ else if (sIdent == "copy")
+ copy();
+ else if (sIdent == "paste")
+ {
+ Paste( nRow );
+ SetNoSelection();
+ GoToRow( nRow );
+ SeekRow( nRow );
+ }
+ else if (sIdent == "delete")
+ DeleteRows();
+ else if (sIdent == "insert")
+ {
+ InsertNewRows( nRow );
+ SetNoSelection();
+ GoToRow( nRow );
+ SeekRow( nRow );
+ }
+
+ return;
+ }
+
+ [[fallthrough]];
+ }
+ default:
+ EditBrowseBox::Command(rEvt);
+ }
+
+}
+
+void OTableRowView::cut()
+{
+ CopyRows();
+ DeleteRows();
+}
+
+void OTableRowView::copy()
+{
+ CopyRows();
+}
+
+void OTableRowView::paste()
+{
+ OSL_FAIL("OTableRowView::Paste : (pseudo-) abstract method called !");
+}
+
+void OTableRowView::Paste( long nRow )
+{
+ InsertRows( nRow );
+}
+
+EditBrowseBox::RowStatus OTableRowView::GetRowStatus(long nRow) const
+{
+ if (nRow >= 0 && m_nDataPos == nRow)
+ return CURRENT;
+ else
+ return CLEAN;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/tabledesign/TableDesignHelpBar.cxx b/dbaccess/source/ui/tabledesign/TableDesignHelpBar.cxx
new file mode 100644
index 000000000..3d73ff0e6
--- /dev/null
+++ b/dbaccess/source/ui/tabledesign/TableDesignHelpBar.cxx
@@ -0,0 +1,105 @@
+/* -*- 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 <TableDesignHelpBar.hxx>
+#include <vcl/event.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/vclmedit.hxx>
+#include <helpids.h>
+
+using namespace dbaui;
+#define STANDARD_MARGIN 6
+OTableDesignHelpBar::OTableDesignHelpBar( vcl::Window* pParent ) :
+ TabPage( pParent, WB_3DLOOK )
+{
+ m_pTextWin = VclPtr<VclMultiLineEdit>::Create( this, WB_VSCROLL | WB_LEFT | WB_BORDER | WB_NOTABSTOP | WB_READONLY);
+ m_pTextWin->SetHelpId(HID_TABLE_DESIGN_HELP_WINDOW);
+ m_pTextWin->SetReadOnly();
+ m_pTextWin->SetControlBackground( GetSettings().GetStyleSettings().GetFaceColor() );
+ m_pTextWin->Show();
+}
+
+OTableDesignHelpBar::~OTableDesignHelpBar()
+{
+ disposeOnce();
+}
+
+void OTableDesignHelpBar::dispose()
+{
+ m_pTextWin.disposeAndClear();
+ TabPage::dispose();
+}
+
+void OTableDesignHelpBar::SetHelpText( const OUString& rText )
+{
+ if(m_pTextWin)
+ m_pTextWin->SetText( rText );
+ Invalidate();
+}
+
+void OTableDesignHelpBar::Resize()
+{
+ // parent window dimensions
+ Size aOutputSize( GetOutputSizePixel() );
+
+ // adapt the TextWin
+ if(m_pTextWin)
+ m_pTextWin->SetPosSizePixel( Point(STANDARD_MARGIN+1, STANDARD_MARGIN+1),
+ Size(aOutputSize.Width()-(2*STANDARD_MARGIN)-2,
+ aOutputSize.Height()-(2*STANDARD_MARGIN)-2) );
+
+}
+
+bool OTableDesignHelpBar::PreNotify( NotifyEvent& rNEvt )
+{
+ if (rNEvt.GetType() == MouseNotifyEvent::LOSEFOCUS)
+ SetHelpText(OUString());
+ return TabPage::PreNotify(rNEvt);
+}
+
+bool OTableDesignHelpBar::isCopyAllowed()
+{
+ return m_pTextWin && !m_pTextWin->GetSelected().isEmpty();
+}
+
+bool OTableDesignHelpBar::isCutAllowed()
+{
+ return false;
+}
+
+bool OTableDesignHelpBar::isPasteAllowed()
+{
+ return false;
+}
+
+void OTableDesignHelpBar::cut()
+{
+}
+
+void OTableDesignHelpBar::copy()
+{
+ if ( m_pTextWin )
+ m_pTextWin->Copy();
+}
+
+void OTableDesignHelpBar::paste()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/tabledesign/TableDesignView.cxx b/dbaccess/source/ui/tabledesign/TableDesignView.cxx
new file mode 100644
index 000000000..af223a287
--- /dev/null
+++ b/dbaccess/source/ui/tabledesign/TableDesignView.cxx
@@ -0,0 +1,302 @@
+/* -*- 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 <TableDesignView.hxx>
+#include <TableController.hxx>
+#include <helpids.h>
+#include <FieldDescriptions.hxx>
+#include "TEditControl.hxx"
+#include "TableFieldDescWin.hxx"
+#include <TableRow.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <unotools/syslocale.hxx>
+#include <vcl/settings.hxx>
+#include <memory>
+
+using namespace ::dbaui;
+using namespace ::utl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::datatransfer::clipboard;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+
+OTableBorderWindow::OTableBorderWindow(vcl::Window* pParent) : Window(pParent,WB_BORDER)
+ ,m_aHorzSplitter( VclPtr<Splitter>::Create(this) )
+{
+
+ ImplInitSettings();
+ // create children
+ m_pEditorCtrl = VclPtr<OTableEditorCtrl>::Create( this);
+ m_pFieldDescWin = VclPtr<OTableFieldDescWin>::Create( this );
+
+ m_pFieldDescWin->SetHelpId(HID_TAB_DESIGN_DESCWIN);
+
+ // set depending windows and controls
+ m_pEditorCtrl->SetDescrWin(m_pFieldDescWin);
+
+ // set up splitter
+ m_aHorzSplitter->SetSplitHdl( LINK(this, OTableBorderWindow, SplitHdl) );
+ m_aHorzSplitter->Show();
+}
+
+OTableBorderWindow::~OTableBorderWindow()
+{
+ disposeOnce();
+}
+
+void OTableBorderWindow::dispose()
+{
+ // destroy children
+ // ::dbaui::notifySystemWindow(this,m_pFieldDescWin,::comphelper::mem_fun(&TaskPaneList::RemoveWindow));
+ m_pEditorCtrl->Hide();
+ m_pFieldDescWin->Hide();
+ m_pEditorCtrl.disposeAndClear();
+ m_pFieldDescWin.disposeAndClear();
+ m_aHorzSplitter.disposeAndClear();
+ vcl::Window::dispose();
+}
+
+void OTableBorderWindow::Resize()
+{
+ const long nSplitterHeight(3);
+
+ // dimensions of parent window
+ Size aOutputSize( GetOutputSize() );
+ long nOutputWidth = aOutputSize.Width();
+ long nOutputHeight = aOutputSize.Height();
+ long nSplitPos = m_aHorzSplitter->GetSplitPosPixel();
+
+ // shift range of the splitter is the middle third of the output
+ long nDragPosY = nOutputHeight/3;
+ long nDragSizeHeight = nOutputHeight/3;
+ m_aHorzSplitter->SetDragRectPixel( tools::Rectangle(Point(0,nDragPosY), Size(nOutputWidth,nDragSizeHeight) ), this );
+ if( (nSplitPos < nDragPosY) || (nSplitPos > (nDragPosY+nDragSizeHeight)) )
+ nSplitPos = nDragPosY+nDragSizeHeight-5;
+
+ // set splitter
+ m_aHorzSplitter->SetPosSizePixel( Point( 0, nSplitPos ), Size(nOutputWidth, nSplitterHeight));
+ m_aHorzSplitter->SetSplitPosPixel( nSplitPos );
+
+ // set window
+ m_pEditorCtrl->SetPosSizePixel( Point(0, 0), Size(nOutputWidth , nSplitPos) );
+
+ m_pFieldDescWin->SetPosSizePixel( Point(0, nSplitPos+nSplitterHeight),
+ Size(nOutputWidth, nOutputHeight-nSplitPos-nSplitterHeight) );
+}
+
+IMPL_LINK( OTableBorderWindow, SplitHdl, Splitter*, pSplit, void )
+{
+ if(pSplit == m_aHorzSplitter.get())
+ {
+ m_aHorzSplitter->SetPosPixel( Point( m_aHorzSplitter->GetPosPixel().X(),m_aHorzSplitter->GetSplitPosPixel() ) );
+ Resize();
+ }
+}
+
+void OTableBorderWindow::ImplInitSettings()
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ // FIXME RenderContext
+
+ vcl::Font aFont = rStyleSettings.GetAppFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetPointFont(*this, aFont);
+
+ Color aTextColor = rStyleSettings.GetButtonTextColor();
+ if ( IsControlForeground() )
+ aTextColor = GetControlForeground();
+ SetTextColor( aTextColor );
+
+ if( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( rStyleSettings.GetFaceColor() );
+}
+
+void OTableBorderWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
+ (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+void OTableBorderWindow::GetFocus()
+{
+ Window::GetFocus();
+
+ // forward the focus to the current cell of the editor control
+ if (m_pEditorCtrl)
+ m_pEditorCtrl->GrabFocus();
+}
+
+OTableDesignView::OTableDesignView( vcl::Window* pParent,
+ const Reference< XComponentContext >& _rxOrb,
+ OTableController& _rController
+ ) :
+ ODataView( pParent, _rController,_rxOrb )
+ ,m_rController( _rController )
+ ,m_eChildFocus(NONE)
+{
+
+ try
+ {
+ m_aLocale = SvtSysLocale().GetLanguageTag().getLocale();
+ }
+ catch(Exception&)
+ {
+ }
+
+ m_pWin = VclPtr<OTableBorderWindow>::Create(this);
+ m_pWin->Show();
+}
+
+OTableDesignView::~OTableDesignView()
+{
+ disposeOnce();
+}
+
+void OTableDesignView::dispose()
+{
+ m_pWin->Hide();
+ m_pWin.disposeAndClear();
+ ODataView::dispose();
+}
+
+void OTableDesignView::initialize()
+{
+ GetEditorCtrl()->Init();
+ GetDescWin()->Init();
+ // first call after the editctrl has been set
+
+ GetEditorCtrl()->Show();
+ GetDescWin()->Show();
+
+ GetEditorCtrl()->DisplayData(0);
+}
+
+void OTableDesignView::resizeDocumentView(tools::Rectangle& _rPlayground)
+{
+ m_pWin->SetPosSizePixel( _rPlayground.TopLeft(), _rPlayground.GetSize() );
+
+ // just for completeness: there is no space left, we occupied it all ...
+ _rPlayground.SetPos( _rPlayground.BottomRight() );
+ _rPlayground.SetSize( Size( 0, 0 ) );
+}
+
+bool OTableDesignView::PreNotify( NotifyEvent& rNEvt )
+{
+ if (rNEvt.GetType() == MouseNotifyEvent::GETFOCUS)
+ {
+ if( GetDescWin() && GetDescWin()->HasChildPathFocus() )
+ m_eChildFocus = DESCRIPTION;
+ else if ( GetEditorCtrl() && GetEditorCtrl()->HasChildPathFocus() )
+ m_eChildFocus = EDITOR;
+ else
+ m_eChildFocus = NONE;
+ }
+
+ return ODataView::PreNotify(rNEvt);
+}
+
+IClipboardTest* OTableDesignView::getActiveChild() const
+{
+ IClipboardTest* pTest = nullptr;
+ switch(m_eChildFocus)
+ {
+ case DESCRIPTION:
+ pTest = GetDescWin();
+ break;
+ case EDITOR:
+ pTest = GetEditorCtrl();
+ break;
+ case NONE:
+ break;
+ }
+ return pTest;
+}
+
+bool OTableDesignView::isCopyAllowed()
+{
+ IClipboardTest* pTest = getActiveChild();
+ return pTest && pTest->isCopyAllowed();
+}
+
+bool OTableDesignView::isCutAllowed()
+{
+ IClipboardTest* pTest = getActiveChild();
+ return pTest && pTest->isCutAllowed();
+}
+
+bool OTableDesignView::isPasteAllowed()
+{
+ IClipboardTest* pTest = getActiveChild();
+ return pTest && pTest->isPasteAllowed();
+}
+
+void OTableDesignView::copy()
+{
+ IClipboardTest* pTest = getActiveChild();
+ if ( pTest )
+ pTest->copy();
+}
+
+void OTableDesignView::cut()
+{
+ IClipboardTest* pTest = getActiveChild();
+ if ( pTest )
+ pTest->cut();
+}
+
+void OTableDesignView::paste()
+{
+ IClipboardTest* pTest = getActiveChild();
+ if ( pTest )
+ pTest->paste();
+}
+
+// set the view readonly or not
+void OTableDesignView::setReadOnly(bool _bReadOnly)
+{
+ GetDescWin()->SetReadOnly(_bReadOnly);
+ GetEditorCtrl()->SetReadOnly(_bReadOnly);
+}
+
+void OTableDesignView::reSync()
+{
+ GetEditorCtrl()->DeactivateCell();
+ std::shared_ptr<OTableRow> pRow = (*GetEditorCtrl()->GetRowList())[GetEditorCtrl()->GetCurRow()];
+ OFieldDescription* pFieldDescr = pRow ? pRow->GetActFieldDescr() : nullptr;
+ if ( pFieldDescr )
+ GetDescWin()->DisplayData(pFieldDescr);
+}
+
+void OTableDesignView::GetFocus()
+{
+ if ( GetEditorCtrl() )
+ GetEditorCtrl()->GrabFocus();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/tabledesign/TableFieldControl.cxx b/dbaccess/source/ui/tabledesign/TableFieldControl.cxx
new file mode 100644
index 000000000..cbd99179c
--- /dev/null
+++ b/dbaccess/source/ui/tabledesign/TableFieldControl.cxx
@@ -0,0 +1,144 @@
+/* -*- 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 "TableFieldControl.hxx"
+#include <TableController.hxx>
+#include <TableDesignView.hxx>
+#include "TEditControl.hxx"
+#include <strings.hxx>
+#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
+#include <comphelper/types.hxx>
+#include <TypeInfo.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdbc;
+using namespace dbaui;
+
+OTableFieldControl::OTableFieldControl(vcl::Window* pParent, OTableDesignHelpBar* pHelpBar)
+ : OFieldDescControl(nullptr, pParent, pHelpBar)
+{
+}
+
+void OTableFieldControl::CellModified(long nRow, sal_uInt16 nColId )
+{
+ GetCtrl()->CellModified(nRow,nColId);
+}
+
+OTableEditorCtrl* OTableFieldControl::GetCtrl() const
+{
+ OTableDesignView* pDesignWin = static_cast<OTableDesignView*>(GetParent()->GetParent()->GetParent()->GetParent());
+ OSL_ENSURE(pDesignWin,"no view!");
+ return pDesignWin->GetEditorCtrl();
+}
+
+bool OTableFieldControl::IsReadOnly()
+{
+ bool bRead(GetCtrl()->IsReadOnly());
+ if( !bRead )
+ {
+ // The columns of a css::sdbcx::View could not be locked
+ Reference<XPropertySet> xTable = GetCtrl()->GetView()->getController().getTable();
+ if(xTable.is() && ::comphelper::getString(xTable->getPropertyValue(PROPERTY_TYPE)) == "VIEW")
+ bRead = true;
+ else
+ {
+ std::shared_ptr<OTableRow> pCurRow = GetCtrl()->GetActRow();
+ if( pCurRow )
+ bRead = pCurRow->IsReadOnly();
+ }
+ }
+ return bRead;
+}
+
+void OTableFieldControl::ActivateAggregate( EControlType eType )
+{
+ switch(eType)
+ {
+ case tpColumnName:
+ case tpType:
+ break;
+ default:
+ OFieldDescControl::ActivateAggregate(eType);
+ }
+}
+
+void OTableFieldControl::DeactivateAggregate( EControlType eType )
+{
+ switch(eType)
+ {
+ case tpColumnName:
+ case tpType:
+ break;
+ default:
+ OFieldDescControl::DeactivateAggregate(eType);
+ }
+}
+
+void OTableFieldControl::SetModified(bool bModified)
+{
+ GetCtrl()->GetView()->getController().setModified(bModified);
+}
+
+css::uno::Reference< css::sdbc::XConnection> OTableFieldControl::getConnection()
+{
+ return GetCtrl()->GetView()->getController().getConnection();
+}
+
+css::uno::Reference< css::sdbc::XDatabaseMetaData> OTableFieldControl::getMetaData()
+{
+ Reference<XConnection> xCon = GetCtrl()->GetView()->getController().getConnection();
+ if(!xCon.is())
+ return nullptr;
+ return xCon->getMetaData();
+}
+
+Reference< XNumberFormatter > OTableFieldControl::GetFormatter() const
+{
+ return GetCtrl()->GetView()->getController().getNumberFormatter();
+}
+
+TOTypeInfoSP OTableFieldControl::getTypeInfo(sal_Int32 _nPos)
+{
+ return GetCtrl()->GetView()->getController().getTypeInfo(_nPos);
+}
+
+const OTypeInfoMap* OTableFieldControl::getTypeInfo() const
+{
+ return &GetCtrl()->GetView()->getController().getTypeInfo();
+}
+
+Locale OTableFieldControl::GetLocale() const
+{
+ return GetCtrl()->GetView()->getLocale();
+}
+
+bool OTableFieldControl::isAutoIncrementValueEnabled() const
+{
+ return GetCtrl()->GetView()->getController().isAutoIncrementValueEnabled();
+}
+
+OUString OTableFieldControl::getAutoIncrementValue() const
+{
+ return GetCtrl()->GetView()->getController().getAutoIncrementValue();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/tabledesign/TableFieldControl.hxx b/dbaccess/source/ui/tabledesign/TableFieldControl.hxx
new file mode 100644
index 000000000..42697bdb7
--- /dev/null
+++ b/dbaccess/source/ui/tabledesign/TableFieldControl.hxx
@@ -0,0 +1,60 @@
+/* -*- 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_DBACCESS_SOURCE_UI_TABLEDESIGN_TABLEFIELDCONTROL_HXX
+#define INCLUDED_DBACCESS_SOURCE_UI_TABLEDESIGN_TABLEFIELDCONTROL_HXX
+
+#include <FieldDescControl.hxx>
+
+namespace dbaui
+{
+ class OTableEditorCtrl;
+ class OTableDesignHelpBar;
+ // OTableFieldControl
+ class OTableFieldControl : public OFieldDescControl
+ {
+ OTableEditorCtrl* GetCtrl() const;
+ protected:
+ virtual void ActivateAggregate( EControlType eType ) override;
+ virtual void DeactivateAggregate( EControlType eType ) override;
+ // are to be implemented by the derived classes
+ virtual void CellModified(long nRow, sal_uInt16 nColId ) override;
+ virtual bool IsReadOnly() override;
+ virtual void SetModified(bool bModified) override;
+ virtual css::uno::Reference< css::util::XNumberFormatter > GetFormatter() const override;
+
+ virtual css::lang::Locale GetLocale() const override;
+
+ virtual TOTypeInfoSP getTypeInfo(sal_Int32 _nPos) override;
+ virtual const OTypeInfoMap* getTypeInfo() const override;
+ virtual bool isAutoIncrementValueEnabled() const override;
+ virtual OUString getAutoIncrementValue() const override;
+
+ public:
+ OTableFieldControl( vcl::Window* pParent, OTableDesignHelpBar* pHelpBar);
+
+ using OFieldDescControl::BoolStringPersistent;
+ using OFieldDescControl::BoolStringUI;
+
+ virtual css::uno::Reference< css::sdbc::XDatabaseMetaData> getMetaData() override;
+ virtual css::uno::Reference< css::sdbc::XConnection> getConnection() override;
+ };
+}
+#endif // INCLUDED_DBACCESS_SOURCE_UI_TABLEDESIGN_TABLEFIELDCONTROL_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/tabledesign/TableFieldDescWin.cxx b/dbaccess/source/ui/tabledesign/TableFieldDescWin.cxx
new file mode 100644
index 000000000..950750794
--- /dev/null
+++ b/dbaccess/source/ui/tabledesign/TableFieldDescWin.cxx
@@ -0,0 +1,275 @@
+/* -*- 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 "TableFieldDescWin.hxx"
+#include <osl/diagnose.h>
+#include <FieldDescriptions.hxx>
+#include <strings.hrc>
+#include <TableDesignHelpBar.hxx>
+#include <vcl/event.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/settings.hxx>
+#include <helpids.h>
+#include <core_resource.hxx>
+
+#define STANDARD_MARGIN 6
+#define DETAILS_HEADER_HEIGHT 25
+#define CONTROL_SPACING_X 18 // 6
+#define CONTROL_SPACING_Y 5
+#define CONTROL_HEIGHT 20
+#define CONTROL_WIDTH_1 140 // 100
+#define CONTROL_WIDTH_3 250
+#define CONTROL_WIDTH_4 (CONTROL_WIDTH_3 - CONTROL_HEIGHT - 5)
+#define DETAILS_OPT_PAGE_WIDTH (CONTROL_WIDTH_1 + CONTROL_SPACING_X + CONTROL_WIDTH_4 + 50)
+#define DETAILS_OPT_PAGE_HEIGHT ((CONTROL_HEIGHT + CONTROL_SPACING_Y) * 5)
+#define DETAILS_MIN_HELP_WIDTH 100
+#define DETAILS_OPT_HELP_WIDTH 200
+#define DETAILS_MIN_HELP_HEIGHT 50
+#define DETAILS_OPT_HELP_HEIGHT 100
+
+using namespace dbaui;
+OTableFieldDescWin::OTableFieldDescWin( vcl::Window* pParent)
+ : TabPage(pParent, WB_3DLOOK)
+ , m_eChildFocus(NONE)
+{
+ // Header
+ m_pHeader = VclPtr<FixedText>::Create( this, WB_CENTER );
+ m_pHeader->SetText(DBA_RES(STR_TAB_PROPERTIES));
+ m_pHeader->Show();
+
+ // HelpBar
+ m_pHelpBar = VclPtr<OTableDesignHelpBar>::Create( this );
+ m_pHelpBar->SetHelpId(HID_TAB_DESIGN_HELP_TEXT_FRAME);
+ m_pHelpBar->Show();
+
+ m_pGenPage = VclPtr<OFieldDescGenWin>::Create( this, m_pHelpBar );
+ getGenPage()->SetHelpId( HID_TABLE_DESIGN_TABPAGE_GENERAL );
+ getGenPage()->Show();
+}
+
+OTableFieldDescWin::~OTableFieldDescWin()
+{
+ disposeOnce();
+}
+
+void OTableFieldDescWin::dispose()
+{
+ // destroy children
+ m_pHelpBar->Hide();
+ getGenPage()->Hide();
+ m_pHeader->Hide();
+
+ m_pGenPage.disposeAndClear();
+ m_pHeader.disposeAndClear();
+ m_pHelpBar.disposeAndClear();
+ TabPage::dispose();
+}
+
+void OTableFieldDescWin::Init()
+{
+ OSL_ENSURE(getGenPage() != nullptr, "OTableFieldDescWin::Init : ups ... no GenericPage ... this will crash ...");
+ getGenPage()->Init();
+}
+
+void OTableFieldDescWin::SetReadOnly( bool bRead )
+{
+ getGenPage()->SetReadOnly( bRead );
+}
+
+void OTableFieldDescWin::DisplayData( OFieldDescription* pFieldDescr )
+{
+ getGenPage()->DisplayData( pFieldDescr );
+}
+
+void OTableFieldDescWin::SaveData( OFieldDescription* pFieldDescr )
+{
+ getGenPage()->SaveData( pFieldDescr );
+}
+
+void OTableFieldDescWin::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rRect*/)
+{
+ // 3D-line at the top window border
+ const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
+
+ rRenderContext.SetLineColor(rStyleSettings.GetLightColor());
+ rRenderContext.DrawLine(Point(0,0), Point(GetSizePixel().Width(), 0));
+
+ // 3D-line for the separation of the header
+ rRenderContext.DrawLine(Point(3, DETAILS_HEADER_HEIGHT), Point(GetSizePixel().Width() - 6, DETAILS_HEADER_HEIGHT));
+ rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
+ rRenderContext.DrawLine(Point(3, DETAILS_HEADER_HEIGHT - 1), Point(GetSizePixel().Width() - 6, DETAILS_HEADER_HEIGHT - 1));
+}
+
+void OTableFieldDescWin::Resize()
+{
+ // dimensions of the parent window
+ Size aOutputSize( GetOutputSizePixel() );
+ long nOutputWidth = aOutputSize.Width();
+ long nOutputHeight = aOutputSize.Height();
+
+ // since the GenPage can scroll, but I can't, I position the HelpWindow, in case I become too slim,
+ // _below_ the Genpage, not on the right side. But before that I try to make it a bit smaller
+
+ long nHelpX, nHelpY;
+ long nHelpWidth, nHelpHeight;
+ long nPageWidth, nPageHeight;
+
+ // do both fit next to each other (margin + page + margin + help)?
+ if (STANDARD_MARGIN + DETAILS_OPT_PAGE_WIDTH + STANDARD_MARGIN + DETAILS_MIN_HELP_WIDTH <= nOutputWidth)
+ { // yes -> then we wonder if can give the help its optimum width
+ nHelpWidth = DETAILS_OPT_HELP_WIDTH;
+ nPageWidth = nOutputWidth - nHelpWidth - STANDARD_MARGIN - STANDARD_MARGIN;
+ if (nPageWidth < DETAILS_OPT_PAGE_WIDTH)
+ { // rather resize the help from its optimal width to its minimum width
+ long nTransfer = DETAILS_OPT_PAGE_WIDTH - nPageWidth;
+ nPageWidth += nTransfer;
+ nHelpWidth -= nTransfer;
+ }
+ nHelpX = nOutputWidth - nHelpWidth;
+ // the heights are simple in that case...
+ nHelpY = DETAILS_HEADER_HEIGHT + 1;
+ nHelpHeight = nOutputHeight - nHelpY;
+ nPageHeight = nOutputHeight - STANDARD_MARGIN - DETAILS_HEADER_HEIGHT - STANDARD_MARGIN;
+ }
+ else
+ { // doesn't work next to each other, thus below each other (margin + header + page + help)
+ if (STANDARD_MARGIN + DETAILS_HEADER_HEIGHT + DETAILS_OPT_PAGE_HEIGHT + DETAILS_MIN_HELP_HEIGHT <= nOutputHeight)
+ { // it's at least enough, to fit both below each other (page optimal, help minimal)
+ nHelpHeight = DETAILS_OPT_HELP_HEIGHT;
+ nPageHeight = nOutputHeight - nHelpHeight - DETAILS_HEADER_HEIGHT - STANDARD_MARGIN;
+ if (nPageHeight < DETAILS_OPT_PAGE_HEIGHT)
+ { // like above: page optimal, help gets whatever is left (which is bigger/equal to its minimum)
+ long nTransfer = DETAILS_OPT_PAGE_HEIGHT - nPageHeight;
+ nPageHeight += nTransfer;
+ nHelpHeight -= nTransfer;
+ }
+ nHelpY = nOutputHeight - nHelpHeight;
+ // and across the entire width
+ nHelpX = 0; // without margin, since the HelpCtrl has its own one
+ nHelpWidth = nOutputWidth; // dito
+ nPageWidth = nOutputWidth - STANDARD_MARGIN - STANDARD_MARGIN;
+ }
+ else
+ { // unfortunately that's not even enough, to show page at its optimum and help with minimum width
+ nHelpX = nHelpY = nHelpWidth = nHelpHeight = 0; // thus no help window
+ nPageWidth = nOutputWidth - STANDARD_MARGIN - STANDARD_MARGIN;
+ nPageHeight = nOutputHeight - STANDARD_MARGIN - DETAILS_HEADER_HEIGHT - STANDARD_MARGIN;
+ }
+ }
+
+ m_pHeader->SetPosSizePixel( Point(0, STANDARD_MARGIN), Size(nOutputWidth, 15) );
+
+ getGenPage()->SetPosSizePixel(Point ( STANDARD_MARGIN,
+ STANDARD_MARGIN + DETAILS_HEADER_HEIGHT
+ ),
+ Size ( nPageWidth,
+ nPageHeight
+ )
+ );
+ if (nHelpHeight)
+ {
+ m_pHelpBar->Show();
+ m_pHelpBar->SetPosSizePixel(Point ( nHelpX,
+ nHelpY
+ ),
+ Size ( nHelpWidth,
+ nHelpHeight
+ )
+ );
+ }
+ else
+ {
+ m_pHelpBar->Hide();
+ }
+ Invalidate();
+}
+
+IClipboardTest* OTableFieldDescWin::getActiveChild() const
+{
+ IClipboardTest* pTest = nullptr;
+ switch(m_eChildFocus)
+ {
+ case DESCRIPTION:
+ pTest = getGenPage();
+ break;
+ default:
+ pTest = m_pHelpBar;
+ break;
+ }
+ return pTest;
+}
+
+bool OTableFieldDescWin::isCopyAllowed()
+{
+ return getActiveChild() && getActiveChild()->isCopyAllowed();
+}
+
+bool OTableFieldDescWin::isCutAllowed()
+{
+ return (getGenPage() && getGenPage()->HasChildPathFocus() && getGenPage()->isCutAllowed());
+}
+
+bool OTableFieldDescWin::isPasteAllowed()
+{
+ return (getGenPage() && getGenPage()->HasChildPathFocus() && getGenPage()->isPasteAllowed());
+}
+
+void OTableFieldDescWin::cut()
+{
+ if ( getGenPage() && getGenPage()->HasChildPathFocus() )
+ getGenPage()->cut();
+}
+
+void OTableFieldDescWin::copy()
+{
+ if ( getActiveChild() )
+ getActiveChild()->copy();
+}
+
+void OTableFieldDescWin::paste()
+{
+ if ( getGenPage() && getGenPage()->HasChildPathFocus() )
+ getGenPage()->paste();
+}
+
+void OTableFieldDescWin::GetFocus()
+{
+ if ( getGenPage() )
+ getGenPage()->GetFocus();
+}
+
+void OTableFieldDescWin::LoseFocus()
+{
+ if ( getGenPage() )
+ getGenPage()->LoseFocus();
+}
+
+bool OTableFieldDescWin::PreNotify( NotifyEvent& rNEvt )
+{
+ if (rNEvt.GetType() == MouseNotifyEvent::GETFOCUS)
+ {
+ if( getGenPage() && getGenPage()->HasChildPathFocus() )
+ m_eChildFocus = DESCRIPTION;
+ else
+ m_eChildFocus = HELP;
+ }
+ return TabPage::PreNotify(rNEvt);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/tabledesign/TableFieldDescWin.hxx b/dbaccess/source/ui/tabledesign/TableFieldDescWin.hxx
new file mode 100644
index 000000000..e85557f24
--- /dev/null
+++ b/dbaccess/source/ui/tabledesign/TableFieldDescWin.hxx
@@ -0,0 +1,95 @@
+/* -*- 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_DBACCESS_SOURCE_UI_TABLEDESIGN_TABLEFIELDDESCWIN_HXX
+#define INCLUDED_DBACCESS_SOURCE_UI_TABLEDESIGN_TABLEFIELDDESCWIN_HXX
+
+#include <vcl/tabpage.hxx>
+#include "FieldDescGenWin.hxx"
+#include <IClipBoardTest.hxx>
+
+class FixedText;
+namespace dbaui
+{
+ class OFieldDescGenWin;
+ class OTableDesignHelpBar;
+ class OFieldDescription;
+ // derivative of TabPage is a trick of TH,
+ // to notice a change in system colours
+ class OTableFieldDescWin : public TabPage
+ ,public IClipboardTest
+ {
+ enum ChildFocusState
+ {
+ DESCRIPTION,
+ HELP,
+ NONE
+ };
+ private:
+ VclPtr<OTableDesignHelpBar> m_pHelpBar;
+ VclPtr<OFieldDescGenWin> m_pGenPage;
+ VclPtr<FixedText> m_pHeader;
+ ChildFocusState m_eChildFocus;
+
+ IClipboardTest* getActiveChild() const;
+
+ protected:
+ virtual void Resize() override;
+ virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
+
+ public:
+ explicit OTableFieldDescWin( vcl::Window* pParent);
+ virtual ~OTableFieldDescWin() override;
+ virtual void dispose() override;
+
+ void Init();
+
+ void DisplayData( OFieldDescription* pFieldDescr );
+ void SaveData( OFieldDescription* pFieldDescr );
+ void SetReadOnly( bool bReadOnly );
+
+ // Window overrides
+ virtual bool PreNotify( NotifyEvent& rNEvt ) override;
+ virtual void GetFocus() override;
+ virtual void LoseFocus() override;
+
+ void SetControlText( sal_uInt16 nControlId, const OUString& rText )
+ { m_pGenPage->SetControlText(nControlId,rText); }
+
+ // short GetFormatCategory(OFieldDescription* pFieldDescr) { return m_pGenPage ? m_pGenPage->GetFormatCategory(pFieldDescr) : -1; }
+ // delivers a CAT_xxx (CAT_NUMBER, CAT_DATE ...) value to a Format set in the field
+
+ OUString BoolStringPersistent(const OUString& rUIString) const { return m_pGenPage->BoolStringPersistent(rUIString); }
+ OUString BoolStringUI(const OUString& rPersistentString) const { return m_pGenPage->BoolStringUI(rPersistentString); }
+
+ // IClipboardTest
+ virtual bool isCutAllowed() override;
+ virtual bool isCopyAllowed() override;
+ virtual bool isPasteAllowed() override;
+
+ virtual void copy() override;
+ virtual void cut() override;
+ virtual void paste() override;
+
+ OFieldDescGenWin* getGenPage() const { return m_pGenPage; }
+
+ };
+}
+#endif // INCLUDED_DBACCESS_SOURCE_UI_TABLEDESIGN_TABLEFIELDDESCWIN_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/tabledesign/TableRow.cxx b/dbaccess/source/ui/tabledesign/TableRow.cxx
new file mode 100644
index 000000000..c84ebc834
--- /dev/null
+++ b/dbaccess/source/ui/tabledesign/TableRow.cxx
@@ -0,0 +1,193 @@
+/* -*- 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 <TableRow.hxx>
+#include <tools/stream.hxx>
+#include <FieldDescriptions.hxx>
+#include <comphelper/types.hxx>
+
+using namespace dbaui;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+
+OTableRow::OTableRow()
+ :m_pActFieldDescr( nullptr )
+ ,m_nPos( -1 )
+ ,m_bReadOnly( false )
+ ,m_bOwnsDescriptions(false)
+{
+}
+
+OTableRow::OTableRow(const Reference< XPropertySet >& xAffectedCol)
+ :m_pActFieldDescr( nullptr )
+ ,m_nPos( -1 )
+ ,m_bReadOnly( false )
+ ,m_bOwnsDescriptions(true)
+{
+ m_pActFieldDescr = new OFieldDescription(xAffectedCol);
+}
+
+OTableRow::OTableRow( const OTableRow& rRow, long nPosition )
+ :m_pActFieldDescr(nullptr)
+ ,m_nPos( nPosition )
+ ,m_bReadOnly(rRow.IsReadOnly())
+ ,m_bOwnsDescriptions(false)
+{
+
+ OFieldDescription* pSrcField = rRow.GetActFieldDescr();
+ if(pSrcField)
+ {
+ m_pActFieldDescr = new OFieldDescription(*pSrcField);
+ m_bOwnsDescriptions = true;
+ }
+}
+
+OTableRow::~OTableRow()
+{
+ if(m_bOwnsDescriptions)
+ delete m_pActFieldDescr;
+}
+
+void OTableRow::SetPrimaryKey( bool bSet )
+{
+ if(m_pActFieldDescr)
+ m_pActFieldDescr->SetPrimaryKey(bSet);
+}
+
+bool OTableRow::IsPrimaryKey() const
+{
+ return m_pActFieldDescr && m_pActFieldDescr->IsPrimaryKey();
+}
+
+void OTableRow::SetFieldType( const TOTypeInfoSP& _pType, bool _bForce )
+{
+ if ( _pType )
+ {
+ if( !m_pActFieldDescr )
+ {
+ m_pActFieldDescr = new OFieldDescription();
+ m_bOwnsDescriptions = true;
+ }
+ m_pActFieldDescr->FillFromTypeInfo(_pType,_bForce,true);
+ }
+ else
+ {
+ delete m_pActFieldDescr;
+ m_pActFieldDescr = nullptr;
+ }
+}
+
+namespace dbaui
+{
+ SvStream& WriteOTableRow( SvStream& _rStr, const OTableRow& _rRow )
+ {
+ _rStr.WriteInt32( _rRow.m_nPos );
+ OFieldDescription* pFieldDesc = _rRow.GetActFieldDescr();
+ if(pFieldDesc)
+ {
+ _rStr.WriteInt32( 1 );
+ _rStr.WriteUniOrByteString(pFieldDesc->GetName(), _rStr.GetStreamCharSet());
+ _rStr.WriteUniOrByteString(pFieldDesc->GetDescription(), _rStr.GetStreamCharSet());
+ _rStr.WriteUniOrByteString(pFieldDesc->GetHelpText(), _rStr.GetStreamCharSet());
+ double nValue = 0.0;
+ Any aValue = pFieldDesc->GetControlDefault();
+ if ( aValue >>= nValue )
+ {
+ _rStr.WriteInt32( 1 );
+ _rStr.WriteDouble( nValue );
+ }
+ else
+ {
+ _rStr.WriteInt32( 2 );
+ _rStr.WriteUniOrByteString(::comphelper::getString(aValue), _rStr.GetStreamCharSet());
+ }
+
+ _rStr.WriteInt32( pFieldDesc->GetType() );
+
+ _rStr.WriteInt32( pFieldDesc->GetPrecision() );
+ _rStr.WriteInt32( pFieldDesc->GetScale() );
+ _rStr.WriteInt32( pFieldDesc->GetIsNullable() );
+ _rStr.WriteInt32( pFieldDesc->GetFormatKey() );
+ _rStr.WriteInt32( static_cast<sal_Int32>(pFieldDesc->GetHorJustify()) );
+ _rStr.WriteInt32( pFieldDesc->IsAutoIncrement() ? 1 : 0 );
+ _rStr.WriteInt32( pFieldDesc->IsPrimaryKey() ? 1 : 0 );
+ _rStr.WriteInt32( pFieldDesc->IsCurrency() ? 1 : 0 );
+ }
+ else
+ _rStr.WriteInt32( 0 );
+ return _rStr;
+ }
+ SvStream& ReadOTableRow( SvStream& _rStr, OTableRow& _rRow )
+ {
+ _rStr.ReadInt32( _rRow.m_nPos );
+ sal_Int32 nValue = 0;
+ _rStr.ReadInt32( nValue );
+ if ( nValue )
+ {
+ OFieldDescription* pFieldDesc = new OFieldDescription();
+ _rRow.m_pActFieldDescr = pFieldDesc;
+ pFieldDesc->SetName(_rStr.ReadUniOrByteString(_rStr.GetStreamCharSet()));
+ pFieldDesc->SetDescription(_rStr.ReadUniOrByteString(_rStr.GetStreamCharSet()));
+ pFieldDesc->SetHelpText(_rStr.ReadUniOrByteString(_rStr.GetStreamCharSet()));
+
+ _rStr.ReadInt32( nValue );
+ Any aControlDefault;
+ switch ( nValue )
+ {
+ case 1:
+ {
+ double nControlDefault;
+ _rStr.ReadDouble( nControlDefault );
+ aControlDefault <<= nControlDefault;
+ break;
+ }
+ case 2:
+ aControlDefault <<= _rStr.ReadUniOrByteString(_rStr.GetStreamCharSet());
+ break;
+ }
+
+ pFieldDesc->SetControlDefault(aControlDefault);
+
+ _rStr.ReadInt32( nValue );
+ pFieldDesc->SetTypeValue(nValue);
+
+ _rStr.ReadInt32( nValue );
+ pFieldDesc->SetPrecision(nValue);
+ _rStr.ReadInt32( nValue );
+ pFieldDesc->SetScale(nValue);
+ _rStr.ReadInt32( nValue );
+ pFieldDesc->SetIsNullable(nValue);
+ _rStr.ReadInt32( nValue );
+ pFieldDesc->SetFormatKey(nValue);
+ _rStr.ReadInt32( nValue );
+ pFieldDesc->SetHorJustify(static_cast<SvxCellHorJustify>(nValue));
+
+ _rStr.ReadInt32( nValue );
+ pFieldDesc->SetAutoIncrement(nValue != 0);
+ _rStr.ReadInt32( nValue );
+ pFieldDesc->SetPrimaryKey(nValue != 0);
+ _rStr.ReadInt32( nValue );
+ pFieldDesc->SetCurrency(nValue != 0);
+ }
+ return _rStr;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/tabledesign/TableRowExchange.cxx b/dbaccess/source/ui/tabledesign/TableRowExchange.cxx
new file mode 100644
index 000000000..53b54cef4
--- /dev/null
+++ b/dbaccess/source/ui/tabledesign/TableRowExchange.cxx
@@ -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 .
+ */
+
+#include <TableRowExchange.hxx>
+#include <sot/formats.hxx>
+#include <sot/storage.hxx>
+#include <TableRow.hxx>
+
+namespace dbaui
+{
+ constexpr sal_uInt32 FORMAT_OBJECT_ID_SBA_TABED = 1;
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::beans;
+ OTableRowExchange::OTableRowExchange(const std::vector< std::shared_ptr<OTableRow> >& _rvTableRow)
+ : m_vTableRow(_rvTableRow)
+ {
+ }
+ bool OTableRowExchange::WriteObject( tools::SvRef<SotStorageStream>& rxOStm, void* pUserObject, sal_uInt32 nUserObjectId, const css::datatransfer::DataFlavor& /*rFlavor*/ )
+ {
+ if(nUserObjectId == FORMAT_OBJECT_ID_SBA_TABED)
+ {
+ std::vector< std::shared_ptr<OTableRow> >* pRows = static_cast< std::vector< std::shared_ptr<OTableRow> >* >(pUserObject);
+ if(pRows)
+ {
+ (*rxOStm).WriteInt32( pRows->size() ); // first stream the size
+ for (auto const& row : *pRows)
+ WriteOTableRow(*rxOStm, *row);
+ return true;
+ }
+ }
+ return false;
+ }
+ void OTableRowExchange::AddSupportedFormats()
+ {
+ if ( !m_vTableRow.empty() )
+ AddFormat(SotClipboardFormatId::SBA_TABED);
+ }
+ bool OTableRowExchange::GetData( const css::datatransfer::DataFlavor& rFlavor, const OUString& /*rDestDoc*/ )
+ {
+ SotClipboardFormatId nFormat = SotExchange::GetFormat(rFlavor);
+ if(nFormat == SotClipboardFormatId::SBA_TABED)
+ return SetObject(&m_vTableRow,FORMAT_OBJECT_ID_SBA_TABED,rFlavor);
+ return false;
+ }
+ void OTableRowExchange::ObjectReleased()
+ {
+ m_vTableRow.clear();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/tabledesign/TableUndo.cxx b/dbaccess/source/ui/tabledesign/TableUndo.cxx
new file mode 100644
index 000000000..3824880de
--- /dev/null
+++ b/dbaccess/source/ui/tabledesign/TableUndo.cxx
@@ -0,0 +1,352 @@
+/* -*- 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 "TableUndo.hxx"
+#include <strings.hrc>
+#include "TEditControl.hxx"
+#include <TableRow.hxx>
+#include <TableController.hxx>
+#include <TableDesignView.hxx>
+#include <FieldDescriptions.hxx>
+#include <svx/svxids.hrc>
+
+using namespace dbaui;
+using namespace ::svt;
+
+
+OTableDesignUndoAct::OTableDesignUndoAct(OTableRowView* pOwner, const char* pCommentID)
+ : OCommentUndoAction(pCommentID)
+ , m_pTabDgnCtrl(pOwner)
+{
+ m_pTabDgnCtrl->m_nCurUndoActId++;
+}
+
+OTableDesignUndoAct::~OTableDesignUndoAct()
+{
+}
+
+void OTableDesignUndoAct::Undo()
+{
+ m_pTabDgnCtrl->m_nCurUndoActId--;
+
+ // doc has not been modified if first undo was reverted
+ if( m_pTabDgnCtrl->m_nCurUndoActId == 0 )
+ {
+ m_pTabDgnCtrl->GetView()->getController().setModified(false);
+ m_pTabDgnCtrl->GetView()->getController().InvalidateFeature(SID_SAVEDOC);
+ }
+}
+
+void OTableDesignUndoAct::Redo()
+{
+ m_pTabDgnCtrl->m_nCurUndoActId++;
+
+ // restore Modified-flag after Redo of first Undo-action
+ if( m_pTabDgnCtrl->m_nCurUndoActId > 0 )
+ {
+ m_pTabDgnCtrl->GetView()->getController().setModified(true);
+ m_pTabDgnCtrl->GetView()->getController().InvalidateFeature(SID_SAVEDOC);
+ }
+}
+
+OTableDesignCellUndoAct::OTableDesignCellUndoAct( OTableRowView* pOwner, long nRowID, sal_uInt16 nColumn ) :
+ OTableDesignUndoAct( pOwner ,STR_TABED_UNDO_CELLMODIFIED)
+ ,m_nCol( nColumn )
+ ,m_nRow( nRowID )
+{
+ // read text at position (m_nRow, m_nCol)
+ m_sOldText = m_pTabDgnCtrl->GetCellData( m_nRow, m_nCol );
+}
+
+OTableDesignCellUndoAct::~OTableDesignCellUndoAct()
+{
+}
+
+void OTableDesignCellUndoAct::Undo()
+{
+ // store text at old line and restore the old one
+ m_pTabDgnCtrl->ActivateCell( m_nRow, m_nCol );
+ m_sNewText = m_pTabDgnCtrl->GetCellData( m_nRow, m_nCol );
+ m_pTabDgnCtrl->SetCellData( m_nRow, m_nCol, m_sOldText );
+ // line has not been modified if the first Undo was reverted
+ if (m_pTabDgnCtrl->GetCurUndoActId() == 1)
+ {
+ CellControllerRef xController = m_pTabDgnCtrl->Controller();
+ if ( xController.is() )
+ xController->ClearModified();
+ m_pTabDgnCtrl->GetView()->getController().setModified(false);
+
+ }
+
+ OTableDesignUndoAct::Undo();
+}
+
+void OTableDesignCellUndoAct::Redo()
+{
+ // restore new text
+ m_pTabDgnCtrl->ActivateCell( m_nRow, m_nCol );
+ m_pTabDgnCtrl->SetCellData( m_nRow, m_nCol, m_sNewText );
+
+ OTableDesignUndoAct::Redo();
+}
+
+OTableEditorUndoAct::OTableEditorUndoAct(OTableEditorCtrl* pOwner, const char* pCommentID)
+ : OTableDesignUndoAct(pOwner, pCommentID)
+ , pTabEdCtrl(pOwner)
+{
+}
+
+OTableEditorUndoAct::~OTableEditorUndoAct()
+{
+}
+
+OTableEditorTypeSelUndoAct::OTableEditorTypeSelUndoAct( OTableEditorCtrl* pOwner, long nRowID, sal_uInt16 nColumn, const TOTypeInfoSP& _pOldType )
+ :OTableEditorUndoAct( pOwner ,STR_TABED_UNDO_TYPE_CHANGED)
+ ,m_nCol( nColumn )
+ ,m_nRow( nRowID )
+ ,m_pOldType( _pOldType )
+{
+}
+
+OTableEditorTypeSelUndoAct::~OTableEditorTypeSelUndoAct()
+{
+}
+
+void OTableEditorTypeSelUndoAct::Undo()
+{
+ // restore type
+ OFieldDescription* pFieldDesc = pTabEdCtrl->GetFieldDescr(m_nRow);
+ if(pFieldDesc)
+ m_pNewType = pFieldDesc->getTypeInfo();
+ else
+ m_pNewType = TOTypeInfoSP();
+ pTabEdCtrl->SetCellData(m_nRow,m_nCol,m_pOldType);
+ pTabEdCtrl->SwitchType( m_pOldType );
+
+ OTableEditorUndoAct::Undo();
+}
+
+void OTableEditorTypeSelUndoAct::Redo()
+{
+ // new type
+ pTabEdCtrl->GoToRowColumnId( m_nRow ,m_nCol);
+ pTabEdCtrl->SetCellData(m_nRow,m_nCol,m_pNewType);
+
+ OTableEditorUndoAct::Redo();
+}
+
+OTableEditorDelUndoAct::OTableEditorDelUndoAct( OTableEditorCtrl* pOwner) :
+ OTableEditorUndoAct( pOwner ,STR_TABED_UNDO_ROWDELETED)
+{
+ // fill DeletedRowList
+ std::vector< std::shared_ptr<OTableRow> >* pOriginalRows = pOwner->GetRowList();
+ sal_Int32 nIndex = pOwner->FirstSelectedRow();
+ std::shared_ptr<OTableRow> pOriginalRow;
+ std::shared_ptr<OTableRow> pNewRow;
+
+ while( nIndex != SFX_ENDOFSELECTION )
+ {
+ pOriginalRow = (*pOriginalRows)[nIndex];
+ pNewRow = std::make_shared<OTableRow>( *pOriginalRow, nIndex );
+ m_aDeletedRows.push_back( pNewRow);
+
+ nIndex = pOwner->NextSelectedRow();
+ }
+}
+
+OTableEditorDelUndoAct::~OTableEditorDelUndoAct()
+{
+ m_aDeletedRows.clear();
+}
+
+void OTableEditorDelUndoAct::Undo()
+{
+ // Insert the deleted line
+ sal_uLong nPos;
+
+ std::shared_ptr<OTableRow> pNewOrigRow;
+ std::vector< std::shared_ptr<OTableRow> >* pOriginalRows = pTabEdCtrl->GetRowList();
+
+ for (auto const& deletedRow : m_aDeletedRows)
+ {
+ pNewOrigRow = std::make_shared<OTableRow>( *deletedRow );
+ nPos = deletedRow->GetPos();
+ pOriginalRows->insert( pOriginalRows->begin()+nPos,pNewOrigRow);
+ }
+
+ pTabEdCtrl->DisplayData(pTabEdCtrl->GetCurRow());
+ pTabEdCtrl->Invalidate();
+ OTableEditorUndoAct::Undo();
+}
+
+void OTableEditorDelUndoAct::Redo()
+{
+ // delete line again
+ std::vector< std::shared_ptr<OTableRow> >* pOriginalRows = pTabEdCtrl->GetRowList();
+
+ for (auto const& deletedRow : m_aDeletedRows)
+ {
+ auto it = pOriginalRows->begin() + deletedRow->GetPos();
+ pOriginalRows->erase(it);
+ }
+
+ pTabEdCtrl->DisplayData(pTabEdCtrl->GetCurRow());
+ pTabEdCtrl->Invalidate();
+ OTableEditorUndoAct::Redo();
+}
+
+OTableEditorInsUndoAct::OTableEditorInsUndoAct( OTableEditorCtrl* pOwner,
+ long nInsertPosition ,
+ const std::vector< std::shared_ptr<OTableRow> >& _vInsertedRows)
+ :OTableEditorUndoAct( pOwner,STR_TABED_UNDO_ROWINSERTED )
+ ,m_vInsertedRows(_vInsertedRows)
+ ,m_nInsPos( nInsertPosition )
+{
+}
+
+OTableEditorInsUndoAct::~OTableEditorInsUndoAct()
+{
+ m_vInsertedRows.clear();
+}
+
+void OTableEditorInsUndoAct::Undo()
+{
+ // delete lines again
+ std::vector< std::shared_ptr<OTableRow> >* pOriginalRows = pTabEdCtrl->GetRowList();
+ pOriginalRows->erase(pOriginalRows->begin() + m_nInsPos, pOriginalRows->begin() + m_nInsPos + m_vInsertedRows.size());
+
+ pTabEdCtrl->RowRemoved( m_nInsPos, m_vInsertedRows.size() );
+ pTabEdCtrl->InvalidateHandleColumn();
+
+ OTableEditorUndoAct::Undo();
+}
+
+void OTableEditorInsUndoAct::Redo()
+{
+ // insert lines again
+ long nInsertRow = m_nInsPos;
+ std::shared_ptr<OTableRow> pRow;
+ std::vector< std::shared_ptr<OTableRow> >* pRowList = pTabEdCtrl->GetRowList();
+ for (auto const& insertedRow : m_vInsertedRows)
+ {
+ pRow = std::make_shared<OTableRow>( *insertedRow );
+ pRowList->insert( pRowList->begin()+nInsertRow ,pRow );
+ nInsertRow++;
+ }
+
+ pTabEdCtrl->RowInserted( m_nInsPos, m_vInsertedRows.size() );
+ pTabEdCtrl->InvalidateHandleColumn();
+
+ OTableEditorUndoAct::Redo();
+}
+
+OTableEditorInsNewUndoAct::OTableEditorInsNewUndoAct( OTableEditorCtrl* pOwner, long nInsertPosition, long nInsertedRows ) :
+ OTableEditorUndoAct( pOwner ,STR_TABED_UNDO_NEWROWINSERTED)
+ ,m_nInsPos( nInsertPosition )
+ ,m_nInsRows( nInsertedRows )
+{
+}
+
+OTableEditorInsNewUndoAct::~OTableEditorInsNewUndoAct()
+{
+}
+
+void OTableEditorInsNewUndoAct::Undo()
+{
+ // delete inserted lines
+ std::vector< std::shared_ptr<OTableRow> >* pOriginalRows = pTabEdCtrl->GetRowList();
+
+ pOriginalRows->erase(pOriginalRows->begin() + m_nInsPos, pOriginalRows->begin() + m_nInsPos + m_nInsRows);
+
+ pTabEdCtrl->RowRemoved( m_nInsPos, m_nInsRows );
+ pTabEdCtrl->InvalidateHandleColumn();
+
+ OTableEditorUndoAct::Undo();
+}
+
+void OTableEditorInsNewUndoAct::Redo()
+{
+ // insert lines again
+ std::vector< std::shared_ptr<OTableRow> >* pRowList = pTabEdCtrl->GetRowList();
+
+ for( long i=m_nInsPos; i<(m_nInsPos+m_nInsRows); i++ )
+ pRowList->insert( pRowList->begin()+i,std::make_shared<OTableRow>() );
+
+ pTabEdCtrl->RowInserted( m_nInsPos, m_nInsRows );
+ pTabEdCtrl->InvalidateHandleColumn();
+
+ OTableEditorUndoAct::Redo();
+}
+
+OPrimKeyUndoAct::OPrimKeyUndoAct( OTableEditorCtrl* pOwner, const MultiSelection& aDeletedKeys, const MultiSelection& aInsertedKeys) :
+ OTableEditorUndoAct( pOwner ,STR_TABLEDESIGN_UNDO_PRIMKEY)
+ ,m_aDelKeys( aDeletedKeys )
+ ,m_aInsKeys( aInsertedKeys )
+ ,m_pEditorCtrl( pOwner )
+{
+}
+
+OPrimKeyUndoAct::~OPrimKeyUndoAct()
+{
+}
+
+void OPrimKeyUndoAct::Undo()
+{
+ std::vector< std::shared_ptr<OTableRow> >* pRowList = pTabEdCtrl->GetRowList();
+ std::shared_ptr<OTableRow> pRow;
+ long nIndex;
+
+ // delete inserted keys
+ for( nIndex = m_aInsKeys.FirstSelected(); nIndex != long(SFX_ENDOFSELECTION); nIndex=m_aInsKeys.NextSelected() )
+ {
+ OSL_ENSURE(nIndex <= static_cast<long>(pRowList->size()),"Index for undo isn't valid!");
+ pRow = (*pRowList)[nIndex];
+ pRow->SetPrimaryKey( false );
+ }
+
+ // restore deleted keys
+ for( nIndex = m_aDelKeys.FirstSelected(); nIndex != long(SFX_ENDOFSELECTION); nIndex=m_aDelKeys.NextSelected() )
+ {
+ OSL_ENSURE(nIndex <= static_cast<long>(pRowList->size()),"Index for undo isn't valid!");
+ pRow = (*pRowList)[nIndex];
+ pRow->SetPrimaryKey( true );
+ }
+
+ m_pEditorCtrl->InvalidateHandleColumn();
+ OTableEditorUndoAct::Undo();
+}
+
+void OPrimKeyUndoAct::Redo()
+{
+ std::vector< std::shared_ptr<OTableRow> >* pRowList = pTabEdCtrl->GetRowList();
+ long nIndex;
+
+ // delete the deleted keys
+ for( nIndex = m_aDelKeys.FirstSelected(); nIndex != long(SFX_ENDOFSELECTION); nIndex=m_aDelKeys.NextSelected() )
+ (*pRowList)[nIndex]->SetPrimaryKey( false );
+
+ // restore the inserted keys
+ for( nIndex = m_aInsKeys.FirstSelected(); nIndex != long(SFX_ENDOFSELECTION); nIndex=m_aInsKeys.NextSelected() )
+ (*pRowList)[nIndex]->SetPrimaryKey( true );
+
+ m_pEditorCtrl->InvalidateHandleColumn();
+ OTableEditorUndoAct::Redo();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/tabledesign/TableUndo.hxx b/dbaccess/source/ui/tabledesign/TableUndo.hxx
new file mode 100644
index 000000000..d4beb0f53
--- /dev/null
+++ b/dbaccess/source/ui/tabledesign/TableUndo.hxx
@@ -0,0 +1,138 @@
+/* -*- 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_DBACCESS_SOURCE_UI_TABLEDESIGN_TABLEUNDO_HXX
+#define INCLUDED_DBACCESS_SOURCE_UI_TABLEDESIGN_TABLEUNDO_HXX
+
+#include <GeneralUndo.hxx>
+#include <tools/multisel.hxx>
+
+#include <vector>
+
+#include <com/sun/star/uno/Any.h>
+#include <TypeInfo.hxx>
+#include <vcl/vclptr.hxx>
+
+namespace dbaui
+{
+ class OTableRowView;
+ class OTableRow;
+ class OTableDesignUndoAct : public OCommentUndoAction
+ {
+ protected:
+ VclPtr<OTableRowView> m_pTabDgnCtrl;
+
+ virtual void Undo() override;
+ virtual void Redo() override;
+ public:
+ OTableDesignUndoAct(OTableRowView* pOwner, const char* pCommentID);
+ virtual ~OTableDesignUndoAct() override;
+ };
+
+ class OTableEditorCtrl;
+ class OTableEditorUndoAct : public OTableDesignUndoAct
+ {
+ protected:
+ VclPtr<OTableEditorCtrl> pTabEdCtrl;
+
+ public:
+ OTableEditorUndoAct(OTableEditorCtrl* pOwner, const char* pCommentID);
+ virtual ~OTableEditorUndoAct() override;
+ };
+
+ class OTableDesignCellUndoAct final : public OTableDesignUndoAct
+ {
+ sal_uInt16 m_nCol;
+ long m_nRow;
+ css::uno::Any m_sOldText;
+ css::uno::Any m_sNewText;
+
+ virtual void Undo() override;
+ virtual void Redo() override;
+ public:
+ OTableDesignCellUndoAct( OTableRowView* pOwner, long nRowID, sal_uInt16 nColumn );
+ virtual ~OTableDesignCellUndoAct() override;
+ };
+
+ class OTableEditorTypeSelUndoAct final : public OTableEditorUndoAct
+ {
+ sal_uInt16 m_nCol;
+ long m_nRow;
+ TOTypeInfoSP m_pOldType;
+ TOTypeInfoSP m_pNewType;
+
+ virtual void Undo() override;
+ virtual void Redo() override;
+ public:
+ OTableEditorTypeSelUndoAct( OTableEditorCtrl* pOwner, long nRowID, sal_uInt16 nColumn, const TOTypeInfoSP& _pOldType );
+ virtual ~OTableEditorTypeSelUndoAct() override;
+ };
+
+ class OTableEditorDelUndoAct final : public OTableEditorUndoAct
+ {
+ std::vector< std::shared_ptr<OTableRow> > m_aDeletedRows;
+
+ virtual void Undo() override;
+ virtual void Redo() override;
+ public:
+ explicit OTableEditorDelUndoAct( OTableEditorCtrl* pOwner );
+ virtual ~OTableEditorDelUndoAct() override;
+ };
+
+ class OTableEditorInsUndoAct final : public OTableEditorUndoAct
+ {
+ std::vector< std::shared_ptr<OTableRow> > m_vInsertedRows;
+ long m_nInsPos;
+
+ virtual void Undo() override;
+ virtual void Redo() override;
+ public:
+ OTableEditorInsUndoAct( OTableEditorCtrl* pOwner,
+ long nInsertPosition,
+ const std::vector< std::shared_ptr<OTableRow> >& _vInsertedRows);
+ virtual ~OTableEditorInsUndoAct() override;
+ };
+
+ class OTableEditorInsNewUndoAct final : public OTableEditorUndoAct
+ {
+ long m_nInsPos;
+ long m_nInsRows;
+
+ virtual void Undo() override;
+ virtual void Redo() override;
+ public:
+ OTableEditorInsNewUndoAct( OTableEditorCtrl* pOwner, long nInsertPosition, long nInsertedRows );
+ virtual ~OTableEditorInsNewUndoAct() override;
+ };
+
+ class OPrimKeyUndoAct final : public OTableEditorUndoAct
+ {
+ MultiSelection m_aDelKeys,
+ m_aInsKeys;
+ VclPtr<OTableEditorCtrl> m_pEditorCtrl;
+
+ virtual void Undo() override;
+ virtual void Redo() override;
+ public:
+ OPrimKeyUndoAct( OTableEditorCtrl* pOwner, const MultiSelection& aDeletedKeys, const MultiSelection& aInsertedKeys );
+ virtual ~OPrimKeyUndoAct() override;
+ };
+}
+#endif // INCLUDED_DBACCESS_SOURCE_UI_TABLEDESIGN_TABLEUNDO_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */