/* -*- 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 .
*/
void EditBrowseBox::dispose()
{ if (nStartEvent)
Application::RemoveUserEvent(nStartEvent); if (nEndEvent)
Application::RemoveUserEvent(nEndEvent); if (nCellModifiedEvent)
Application::RemoveUserEvent(nCellModifiedEvent);
// This should handle the case that the BrowseBox (or one of its children) // gets the focus from outside by pressing Tab if (IsEditing() && Controller()->GetWindow().IsVisible())
Controller()->GetWindow().GrabFocus();
switch (nCode)
{ case KEY_RETURN: if (!bCtrl && !bShift && IsTabAllowed(true))
{
Dispatch(BrowserDispatchId::CURSORRIGHT);
} else
BrowseBox::KeyInput(rEvt); return; case KEY_TAB: if (!bCtrl && !bShift)
{ if (IsTabAllowed(true))
Dispatch(BrowserDispatchId::CURSORRIGHT); else // do NOT call BrowseBox::KeyInput : this would handle the tab, but we already now // that tab isn't allowed here. So give the Control class a chance
Control::KeyInput(rEvt); return;
} elseif (!bCtrl && bShift)
{ if (IsTabAllowed(false))
Dispatch(BrowserDispatchId::CURSORLEFT); else // do NOT call BrowseBox::KeyInput : this would handle the tab, but we already now // that tab isn't allowed here. So give the Control class a chance
Control::KeyInput(rEvt); return;
}
[[fallthrough]]; default:
BrowseBox::KeyInput(rEvt);
}
}
// we are about to leave the current cell. If there is a "this cell has been modified" notification // pending (asynchronously), this may be deadly -> do it synchronously if ( nCellModifiedEvent )
{
Application::RemoveUserEvent( nCellModifiedEvent );
nCellModifiedEvent = nullptr;
LINK( this, EditBrowseBox, CellModifiedHdl ).Call( nullptr );
}
if (rEvt.GetColumnId() == HandleColumnId)
{ // it was the handle column. save the current cell content if necessary // (clicking on the handle column results in selecting the current row) if (IsEditing() && aController->IsValueChangedFromSaved())
SaveModified();
}
if (m_nBrowserFlags & EditBrowseBoxFlags::ACTIVATE_ON_BUTTONDOWN)
{ // the base class does not travel upon MouseButtonDown, but implActivateCellOnMouseEvent assumes we traveled ...
GoToRowColumnId( rEvt.GetRow(), rEvt.GetColumnId() ); if (rEvt.GetRow() >= 0)
implActivateCellOnMouseEvent(rEvt, false);
}
}
if (!IsEditing() || !aController->GetWindow().IsEnabled()) return;
// forwards the event to the control
aController->ActivatingMouseEvent(_rEvt, _bUp);
}
void EditBrowseBox::Dispatch(BrowserDispatchId eId)
{ if (eId == BrowserDispatchId::ENHANCESELECTION)
{ // this is a workaround for the bug in the base class: // if the row selection is to be extended (which is what BrowserDispatchId::ENHANCESELECTION tells us) // then the base class does not revert any column selections, while, for doing a "simple" // selection (BrowserDispatchId::SELECT), it does. In fact, it does not only revert the col selection then, // but also any current row selections. // This clearly tells me that the both ids are for row selection only - there this behaviour does // make sense. // But here, where we have column selection, too, we take care of this ourself. if ( GetSelectColumnCount( ) )
{ while ( GetSelectColumnCount( ) )
SelectColumnPos(
sal::static_int_cast< sal_uInt16 >(FirstSelectedColumn()), false );
Select();
}
}
BrowseBox::Dispatch(eId);
}
if (!bAlt && !bCtrl && !bShift ) switch ( nCode )
{ case KEY_DOWN:
eId = BrowserDispatchId::CURSORDOWN; break; case KEY_UP:
eId = BrowserDispatchId::CURSORUP; break; case KEY_PAGEDOWN:
eId = BrowserDispatchId::CURSORPAGEDOWN; break; case KEY_PAGEUP:
eId = BrowserDispatchId::CURSORPAGEUP; break; case KEY_HOME:
eId = BrowserDispatchId::CURSORHOME; break; case KEY_END:
eId = BrowserDispatchId::CURSOREND; break;
case KEY_TAB: // ask if traveling to the next cell is allowed if (IsTabAllowed(true))
eId = BrowserDispatchId::CURSORRIGHT; break;
case KEY_RETURN: // save the cell content (if necessary) if (IsEditing() && aController->IsValueChangedFromSaved() && !SaveModified())
{ // maybe we're not visible ...
EnableAndShow();
aController->GetWindow().GrabFocus(); returntrue;
} // ask if traveling to the next cell is allowed if (IsTabAllowed(true))
eId = BrowserDispatchId::CURSORRIGHT;
break; case KEY_RIGHT:
eId = BrowserDispatchId::CURSORRIGHT; break; case KEY_LEFT:
eId = BrowserDispatchId::CURSORLEFT; break; case KEY_SPACE:
eId = BrowserDispatchId::SELECT;
bNonEditOnly = bLocalSelect = true; break;
}
if ( !bAlt && !bCtrl && bShift ) switch ( nCode )
{ case KEY_DOWN:
eId = BrowserDispatchId::SELECTDOWN;
bLocalSelect = true; break; case KEY_UP:
eId = BrowserDispatchId::SELECTUP;
bLocalSelect = true; break; case KEY_HOME:
eId = BrowserDispatchId::SELECTHOME;
bLocalSelect = true; break; case KEY_END:
eId = BrowserDispatchId::SELECTEND;
bLocalSelect = true; break; case KEY_TAB: if (IsTabAllowed(false))
eId = BrowserDispatchId::CURSORLEFT; break;
}
// save the cell content if // a) a selection is being made // b) the row is changing if (IsModified() && (nInfo & (ROWCHANGE | COLSELECT | ROWSELECT)) &&
!pTHIS->SaveRow())
{ if (nInfo & COLSELECT ||
nInfo & ROWSELECT)
{ // cancel selected
pTHIS->SetNoSelection();
}
if (IsEditing())
{ if (!Controller()->GetWindow().IsVisible())
{
EnableAndShow();
}
aController->GetWindow().GrabFocus();
} returnfalse;
}
if (nNewRow != nEditRow)
{
vcl::Window& rWindow = GetDataWindow(); if ((nEditRow >= 0) && !(GetBrowserFlags() & EditBrowseBoxFlags::NO_HANDLE_COLUMN_CONTENT))
{
tools::Rectangle aRect = GetFieldRectPixel(nEditRow, 0, false ); // status cell should be painted if and only if text is displayed
pTHIS->bPaintStatus = ( GetBrowserFlags() & EditBrowseBoxFlags::HANDLE_COLUMN_TEXT ) == EditBrowseBoxFlags::HANDLE_COLUMN_TEXT;
rWindow.Invalidate(aRect);
pTHIS->bPaintStatus = true;
}
// don't paint during row change
rWindow.EnablePaint(false);
// the last veto chance for derived classes if (!pTHIS->CursorMoving(nNewRow, nNewColId))
{
pTHIS->InvalidateStatusCell(nEditRow);
rWindow.EnablePaint(true); returnfalse;
} else
{
rWindow.EnablePaint(true); returntrue;
}
} else return pTHIS->CursorMoving(nNewRow, nNewColId);
}
void EditBrowseBox::CursorMoved()
{
sal_Int32 nNewRow = GetCurRow(); if (nEditRow != nNewRow)
{ if (!(GetBrowserFlags() & EditBrowseBoxFlags::NO_HANDLE_COLUMN_CONTENT))
InvalidateStatusCell(nNewRow);
nEditRow = nNewRow;
}
ActivateCell();
GetDataWindow().EnablePaint(true); // should not be called here because the descant event is not needed here //BrowseBox::CursorMoved();
}
if ( isAccessibleAlive() )
implCreateActiveAccessible();
// activate the cell only of the browser has the focus if ( bHasFocus && bCellFocus )
AsynchGetFocus();
} else
{ // no controller -> we have a new "active descendant" if ( isAccessibleAlive() && HasFocus() )
{
commitTableEvent(
AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
Any( CreateAccessibleCell( nRow, GetColumnPos( nCol -1) ) ),
Any()
);
}
}
}
void EditBrowseBox::DeactivateCell(bool bUpdate)
{ if (!IsEditing()) return;
if (isAccessibleAlive() && m_xActiveCell.is())
{
commitBrowseBoxEvent(AccessibleEventId::CHILD, Any(), Any(m_xActiveCell));
clearActiveCell();
}
// if the window is smaller than "title line height" + "control area", // do nothing if (GetOutputSizePixel().Height() <
(GetControlArea().GetHeight() + GetDataWindow().GetPosPixel().Y())) return;
// the size of the control area
Point aPoint(GetControlArea().TopLeft());
sal_uInt16 nX = static_cast<sal_uInt16>(aPoint.X());
//tdf#97731 if the reserved area changed size, give the controls a //chance to adapt to the new size if (bChanged)
{
nX = static_cast<sal_uInt16>(aPoint.X());
ArrangeControls(nX, static_cast<sal_uInt16>(aPoint.Y()));
}
}
void EditBrowseBox::DoubleClick(const BrowserMouseEvent& rEvt)
{ // when double clicking on the column, the optimum size will be calculated
sal_uInt16 nColId = rEvt.GetColumnId(); if (nColId != HandleColumnId)
SetColumnWidth(nColId, GetAutoColumnWidth(nColId));
}
if (GetTopRow() <= nLastVisRow) // calc the column with using the cell contents
{ for (tools::Long i = GetTopRow(); i <= nLastVisRow; ++i)
nNewColWidth = std::max(nNewColWidth,GetTotalCellWidth(i,nColId) + 12);
if (nNewColWidth == nCurColWidth) // size has not changed
nNewColWidth = GetDefaultColumnWidth(GetColumnTitle(nColId));
} else
nNewColWidth = GetDefaultColumnWidth(GetColumnTitle(nColId)); return nNewColWidth;
}
DBG_ASSERT(pWindow, "CellController::CellController: missing the window!");
DBG_ASSERT(!pWindow->IsVisible(), "CellController::CellController: window should not be visible!");
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.