diff options
Diffstat (limited to 'dbaccess/source/ui/dlg/indexfieldscontrol.cxx')
-rw-r--r-- | dbaccess/source/ui/dlg/indexfieldscontrol.cxx | 516 |
1 files changed, 516 insertions, 0 deletions
diff --git a/dbaccess/source/ui/dlg/indexfieldscontrol.cxx b/dbaccess/source/ui/dlg/indexfieldscontrol.cxx new file mode 100644 index 000000000000..55457a36ae64 --- /dev/null +++ b/dbaccess/source/ui/dlg/indexfieldscontrol.cxx @@ -0,0 +1,516 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dbaccess.hxx" + +#ifndef _DBAUI_INDEXFIELDSCONTROL_HXX_ +#include "indexfieldscontrol.hxx" +#endif +#ifndef _DBU_DLG_HRC_ +#include "dbu_dlg.hrc" +#endif +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif +#ifndef _DBA_DBACCESS_HELPID_HRC_ +#include "dbaccess_helpid.hrc" +#endif + +//...................................................................... +namespace dbaui +{ +//...................................................................... + +#define BROWSER_STANDARD_FLAGS BROWSER_COLUMNSELECTION | BROWSER_HLINESFULL | BROWSER_VLINESFULL | \ + BROWSER_HIDECURSOR | BROWSER_HIDESELECT | BROWSER_AUTO_HSCROLL | BROWSER_AUTO_VSCROLL + +#define COLUMN_ID_FIELDNAME 1 +#define COLUMN_ID_ORDER 2 + + using namespace ::com::sun::star::uno; + using namespace ::svt; + + //================================================================== + //= DbaMouseDownListBoxController + //================================================================== + class DbaMouseDownListBoxController : public ListBoxCellController + { + protected: + Link m_aOriginalModifyHdl; + Link m_aAdditionalModifyHdl; + + public: + DbaMouseDownListBoxController(ListBoxControl* _pParent) + :ListBoxCellController(_pParent) + { + } + + void SetAdditionalModifyHdl(const Link& _rHdl); + + protected: + virtual sal_Bool WantMouseEvent() const { return sal_True; } + virtual void SetModifyHdl(const Link& _rHdl); + + private: + void implCheckLinks(); + DECL_LINK( OnMultiplexModify, void* ); + }; + + //------------------------------------------------------------------ + void DbaMouseDownListBoxController::SetAdditionalModifyHdl(const Link& _rHdl) + { + m_aAdditionalModifyHdl = _rHdl; + implCheckLinks(); + } + + //------------------------------------------------------------------ + void DbaMouseDownListBoxController::SetModifyHdl(const Link& _rHdl) + { + m_aOriginalModifyHdl = _rHdl; + implCheckLinks(); + } + + //------------------------------------------------------------------ + IMPL_LINK( DbaMouseDownListBoxController, OnMultiplexModify, void*, _pArg ) + { + if (m_aAdditionalModifyHdl.IsSet()) + m_aAdditionalModifyHdl.Call(_pArg); + if (m_aOriginalModifyHdl.IsSet()) + m_aOriginalModifyHdl.Call(_pArg); + return 0L; + } + + //------------------------------------------------------------------ + void DbaMouseDownListBoxController::implCheckLinks() + { + if (m_aAdditionalModifyHdl.IsSet() || m_aOriginalModifyHdl.IsSet()) + ListBoxCellController::SetModifyHdl(LINK(this, DbaMouseDownListBoxController, OnMultiplexModify)); + else + ListBoxCellController::SetModifyHdl(Link()); + } + + //================================================================== + //= IndexFieldsControl + //================================================================== +DBG_NAME(IndexFieldsControl) +//------------------------------------------------------------------ + IndexFieldsControl::IndexFieldsControl( Window* _pParent, const ResId& _rId ,sal_Int32 _nMaxColumnsInIndex,sal_Bool _bAddIndexAppendix) + :EditBrowseBox(_pParent, _rId, EBBF_SMART_TAB_TRAVEL | EBBF_ACTIVATE_ON_BUTTONDOWN, BROWSER_STANDARD_FLAGS) + ,m_aSeekRow(m_aFields.end()) + ,m_pSortingCell(NULL) + ,m_pFieldNameCell(NULL) + ,m_nMaxColumnsInIndex(_nMaxColumnsInIndex) + ,m_bAddIndexAppendix(_bAddIndexAppendix) + { + DBG_CTOR(IndexFieldsControl,NULL); + + SetUniqueId( UID_DLGINDEX_INDEXDETAILS_BACK ); + GetDataWindow().SetUniqueId( UID_DLGINDEX_INDEXDETAILS_MAIN ); + } + + //------------------------------------------------------------------ + IndexFieldsControl::~IndexFieldsControl() + { + delete m_pSortingCell; + delete m_pFieldNameCell; + + DBG_DTOR(IndexFieldsControl,NULL); + } + + //------------------------------------------------------------------ + sal_Bool IndexFieldsControl::SeekRow(long nRow) + { + if (!EditBrowseBox::SeekRow(nRow)) + return sal_False; + + if (nRow < 0) + { + m_aSeekRow = m_aFields.end(); + } + else + { + m_aSeekRow = m_aFields.begin() + nRow; + OSL_ENSURE(m_aSeekRow <= m_aFields.end(), "IndexFieldsControl::SeekRow: invalid row!"); + } + + return sal_True; + } + + //------------------------------------------------------------------ + void IndexFieldsControl::PaintCell( OutputDevice& _rDev, const Rectangle& _rRect, sal_uInt16 _nColumnId ) const + { + Point aPos(_rRect.TopLeft()); + aPos.X() += 1; + + String aText = GetRowCellText(m_aSeekRow,_nColumnId); + Size TxtSize(GetDataWindow().GetTextWidth(aText), GetDataWindow().GetTextHeight()); + + // clipping + if (aPos.X() < _rRect.Right() || aPos.X() + TxtSize.Width() > _rRect.Right() || + aPos.Y() < _rRect.Top() || aPos.Y() + TxtSize.Height() > _rRect.Bottom()) + _rDev.SetClipRegion( _rRect ); + + // allow for a disabled control ... + sal_Bool bEnabled = IsEnabled(); + Color aOriginalColor = _rDev.GetTextColor(); + if (!bEnabled) + _rDev.SetTextColor(GetSettings().GetStyleSettings().GetDisableColor()); + + // draw the text + _rDev.DrawText(aPos, aText); + + // reset the color (if necessary) + if (!bEnabled) + _rDev.SetTextColor(aOriginalColor); + + if (_rDev.IsClipRegion()) + _rDev.SetClipRegion(); + } + + //------------------------------------------------------------------ + void IndexFieldsControl::initializeFrom(const IndexFields& _rFields) + { + // copy the field descriptions + m_aFields = _rFields; + m_aSeekRow = m_aFields.end(); + + SetUpdateMode(sal_False); + // remove all rows + RowRemoved(1, GetRowCount()); + // insert rows for the the fields + RowInserted(GetRowCount(), m_aFields.size(), sal_False); + // insert an additional row for a new field for that index +// if(!m_nMaxColumnsInIndex || GetRowCount() < m_nMaxColumnsInIndex ) + RowInserted(GetRowCount(), 1, sal_False); + SetUpdateMode(sal_True); + + GoToRowColumnId(0, COLUMN_ID_FIELDNAME); + } + + //------------------------------------------------------------------ + void IndexFieldsControl::commitTo(IndexFields& _rFields) + { + // do not just copy the array, we may have empty field names (which should not be copied) + _rFields.resize(m_aFields.size()); + ConstIndexFieldsIterator aSource = m_aFields.begin(); + ConstIndexFieldsIterator aSourceEnd = m_aFields.end(); + IndexFieldsIterator aDest = _rFields.begin(); + for (; aSource < aSourceEnd; ++aSource) + if (0 != aSource->sFieldName.Len()) + { + *aDest = *aSource; + ++aDest; + } + + _rFields.resize(aDest - _rFields.begin()); + } + + //------------------------------------------------------------------ + sal_uInt32 IndexFieldsControl::GetTotalCellWidth(long _nRow, sal_uInt16 _nColId) + { + if (COLUMN_ID_ORDER == _nColId) + { + sal_Int32 nWidthAsc = GetTextWidth(m_sAscendingText) + GetSettings().GetStyleSettings().GetScrollBarSize(); + sal_Int32 nWidthDesc = GetTextWidth(m_sDescendingText) + GetSettings().GetStyleSettings().GetScrollBarSize(); + // maximum plus some additional space + return (nWidthAsc > nWidthDesc ? nWidthAsc : nWidthDesc) + GetTextWidth('0') * 2; + } + return EditBrowseBox::GetTotalCellWidth(_nRow, _nColId); + } + + //------------------------------------------------------------------ + void IndexFieldsControl::Init(const Sequence< ::rtl::OUString >& _rAvailableFields) + { + RemoveColumns(); + + // for the width: both columns together should be somewhat smaller than the whole window (without the scrollbar) + sal_Int32 nFieldNameWidth = GetSizePixel().Width(); + + if ( m_bAddIndexAppendix ) + { + m_sAscendingText = String(ModuleRes(STR_ORDER_ASCENDING)); + m_sDescendingText = String(ModuleRes(STR_ORDER_DESCENDING)); + + // the "sort order" column + String sColumnName = String(ModuleRes(STR_TAB_INDEX_SORTORDER)); + // the width of the order column is the maximum widths of the texts used + // (the title of the column) + sal_Int32 nSortOrderColumnWidth = GetTextWidth(sColumnName); + // ("ascending" + scrollbar width) + sal_Int32 nOther = GetTextWidth(m_sAscendingText) + GetSettings().GetStyleSettings().GetScrollBarSize(); + nSortOrderColumnWidth = nSortOrderColumnWidth > nOther ? nSortOrderColumnWidth : nOther; + // ("descending" + scrollbar width) + nOther = GetTextWidth(m_sDescendingText) + GetSettings().GetStyleSettings().GetScrollBarSize(); + nSortOrderColumnWidth = nSortOrderColumnWidth > nOther ? nSortOrderColumnWidth : nOther; + // (plus some additional space) + nSortOrderColumnWidth += GetTextWidth('0') * 2; + InsertDataColumn(COLUMN_ID_ORDER, sColumnName, nSortOrderColumnWidth, HIB_STDSTYLE, 1); + + m_pSortingCell = new ListBoxControl(&GetDataWindow()); + m_pSortingCell->InsertEntry(m_sAscendingText); + m_pSortingCell->InsertEntry(m_sDescendingText); + m_pSortingCell->SetHelpId( HID_DLGINDEX_INDEXDETAILS_SORTORDER ); + + nFieldNameWidth -= nSortOrderColumnWidth; + } + StyleSettings aSystemStyle = Application::GetSettings().GetStyleSettings(); + nFieldNameWidth -= aSystemStyle.GetScrollBarSize(); + nFieldNameWidth -= 8; + // the "field name" column + String sColumnName = String(ModuleRes(STR_TAB_INDEX_FIELD)); + InsertDataColumn(COLUMN_ID_FIELDNAME, sColumnName, nFieldNameWidth, HIB_STDSTYLE, 0); + + // create the cell controllers + // for the field name cell + m_pFieldNameCell = new ListBoxControl(&GetDataWindow()); + m_pFieldNameCell->InsertEntry(String()); + m_pFieldNameCell->SetHelpId( HID_DLGINDEX_INDEXDETAILS_FIELD ); + const ::rtl::OUString* pFields = _rAvailableFields.getConstArray(); + const ::rtl::OUString* pFieldsEnd = pFields + _rAvailableFields.getLength(); + for (;pFields < pFieldsEnd; ++pFields) + m_pFieldNameCell->InsertEntry(*pFields); + } + + //------------------------------------------------------------------ + CellController* IndexFieldsControl::GetController(long _nRow, sal_uInt16 _nColumnId) + { + if (!IsEnabled()) + return NULL; + + ConstIndexFieldsIterator aRow; + sal_Bool bNewField = !implGetFieldDesc(_nRow, aRow); + + DbaMouseDownListBoxController* pReturn = NULL; + switch (_nColumnId) + { + case COLUMN_ID_ORDER: + if (!bNewField && m_pSortingCell && 0 != aRow->sFieldName.Len()) + pReturn = new DbaMouseDownListBoxController(m_pSortingCell); + break; + + case COLUMN_ID_FIELDNAME: + pReturn = new DbaMouseDownListBoxController(m_pFieldNameCell); + break; + + default: + OSL_ENSURE(sal_False, "IndexFieldsControl::GetController: invalid column id!"); + } + + if (pReturn) + pReturn->SetAdditionalModifyHdl(LINK(this, IndexFieldsControl, OnListEntrySelected)); + + return pReturn; + } + + //------------------------------------------------------------------ + sal_Bool IndexFieldsControl::implGetFieldDesc(long _nRow, ConstIndexFieldsIterator& _rPos) + { + _rPos = m_aFields.end(); + if ((_nRow < 0) || (_nRow >= (sal_Int32)m_aFields.size())) + return sal_False; + _rPos = m_aFields.begin() + _nRow; + return sal_True; + } + + //------------------------------------------------------------------ + sal_Bool IndexFieldsControl::IsModified() const + { + return EditBrowseBox::IsModified(); + } + + //------------------------------------------------------------------ + sal_Bool IndexFieldsControl::SaveModified() + { + if (!IsModified()) + return sal_True; + + switch (GetCurColumnId()) + { + case COLUMN_ID_FIELDNAME: + { + String sFieldSelected = m_pFieldNameCell->GetSelectEntry(); + sal_Bool bEmptySelected = 0 == sFieldSelected.Len(); + if (isNewField()) + { + if (!bEmptySelected) + { + // add a new field to the collection + OIndexField aNewField; + aNewField.sFieldName = sFieldSelected; + m_aFields.push_back(aNewField); + RowInserted(GetRowCount(), 1, sal_True); + } + } + else + { + sal_Int32 nRow = GetCurRow(); + OSL_ENSURE(nRow < (sal_Int32)m_aFields.size(), "IndexFieldsControl::SaveModified: invalid current row!"); + if (nRow >= 0) // may be -1 in case the control was empty + { + // remove the field from the selection + IndexFieldsIterator aPos = m_aFields.begin() + nRow; + + if (bEmptySelected) + { + aPos->sFieldName = String(); + + // invalidate the row to force repaint + Invalidate(GetRowRectPixel(nRow)); + return sal_True; + } + + if (sFieldSelected == aPos->sFieldName) + // nothing changed + return sal_True; + + aPos->sFieldName = sFieldSelected; + } + } + + Invalidate(GetRowRectPixel(GetCurRow())); + } + break; + case COLUMN_ID_ORDER: + { + OSL_ENSURE(!isNewField(), "IndexFieldsControl::SaveModified: why the hell ...!!!"); + // selected entry + sal_uInt16 nPos = m_pSortingCell->GetSelectEntryPos(); + OSL_ENSURE(LISTBOX_ENTRY_NOTFOUND != nPos, "IndexFieldsControl::SaveModified: how did you get this selection??"); + // adjust the sort flag in the index field description + OIndexField& rCurrentField = m_aFields[GetCurRow()]; + rCurrentField.bSortAscending = (0 == nPos); + + } + break; + default: + OSL_ENSURE(sal_False, "IndexFieldsControl::SaveModified: invalid column id!"); + } + return sal_True; + } + + //------------------------------------------------------------------ + void IndexFieldsControl::InitController(CellControllerRef& /*_rController*/, long _nRow, sal_uInt16 _nColumnId) + { + ConstIndexFieldsIterator aFieldDescription; + sal_Bool bNewField = !implGetFieldDesc(_nRow, aFieldDescription); + + switch (_nColumnId) + { + case COLUMN_ID_FIELDNAME: + m_pFieldNameCell->SelectEntry(bNewField ? String() : aFieldDescription->sFieldName); + m_pFieldNameCell->SaveValue(); + break; + + case COLUMN_ID_ORDER: + m_pSortingCell->SelectEntry(aFieldDescription->bSortAscending ? m_sAscendingText : m_sDescendingText); + m_pSortingCell->SaveValue(); + break; + + default: + OSL_ENSURE(sal_False, "IndexFieldsControl::InitController: invalid column id!"); + } + } + + //------------------------------------------------------------------ + IMPL_LINK( IndexFieldsControl, OnListEntrySelected, ListBox*, _pBox ) + { + if (!_pBox->IsTravelSelect() && m_aModifyHdl.IsSet()) + m_aModifyHdl.Call(this); + + if (_pBox == m_pFieldNameCell) + { // a field has been selected + if (GetCurRow() >= GetRowCount() - 2) + { // and we're in one of the last two rows + String sSelectedEntry = m_pFieldNameCell->GetSelectEntry(); + sal_Int32 nCurrentRow = GetCurRow(); + sal_Int32 rowCount = GetRowCount(); + + OSL_ENSURE(((sal_Int32)(m_aFields.size() + 1)) == rowCount, "IndexFieldsControl::OnListEntrySelected: inconsistence!"); + + if (sSelectedEntry.Len() && (nCurrentRow == rowCount - 1) /*&& (!m_nMaxColumnsInIndex || rowCount < m_nMaxColumnsInIndex )*/ ) + { // in the last row, an non-empty string has been selected + // -> insert a new row + m_aFields.push_back(OIndexField()); + RowInserted(GetRowCount(), 1); + Invalidate(GetRowRectPixel(nCurrentRow)); + } + else if (!sSelectedEntry.Len() && (nCurrentRow == rowCount - 2)) + { // in the (last-1)th row, an empty entry has been selected + // -> remove the last row + m_aFields.erase(m_aFields.end() - 1); + RowRemoved(GetRowCount() - 1, 1); + Invalidate(GetRowRectPixel(nCurrentRow)); + } + } + + SaveModified(); + } + return 0L; + } + //------------------------------------------------------------------ + String IndexFieldsControl::GetCellText(long _nRow,sal_uInt16 nColId) const + { + ConstIndexFieldsIterator aRow = m_aFields.end(); + if ( _nRow >= 0 ) + { + aRow = m_aFields.begin() + _nRow; + OSL_ENSURE(aRow <= m_aFields.end(), "IndexFieldsControl::SeekRow: invalid row!"); + } + return GetRowCellText(aRow,nColId); + } + //------------------------------------------------------------------ + String IndexFieldsControl::GetRowCellText(const ConstIndexFieldsIterator& _rRow,sal_uInt16 nColId) const + { + if (_rRow < m_aFields.end()) + { + switch (nColId) + { + case COLUMN_ID_FIELDNAME: + return _rRow->sFieldName; + case COLUMN_ID_ORDER: + if (0 == _rRow->sFieldName.Len()) + return String(); + else + return _rRow->bSortAscending ? m_sAscendingText : m_sDescendingText; + default: + OSL_ENSURE(sal_False, "IndexFieldsControl::GetCurrentRowCellText: invalid column id!"); + } + } + return String(); + } + //------------------------------------------------------------------ + sal_Bool IndexFieldsControl::IsTabAllowed(sal_Bool /*bForward*/) const + { + return sal_False; + } + //------------------------------------------------------------------ + +//...................................................................... +} // namespace dbaui +//...................................................................... + |