/************************************************************************* * * $RCSfile: editbrowsebox.cxx,v $ * * $Revision: 1.3 $ * * last change: $Author: hr $ $Date: 2001-10-12 16:57:26 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses * * - GNU Lesser General Public License Version 2.1 * - Sun Industry Standards Source License Version 1.1 * * Sun Microsystems Inc., October, 2000 * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2000 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library 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 for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * * Sun Industry Standards Source License Version 1.1 * ================================================= * The contents of this file are subject to the Sun Industry Standards * Source License Version 1.1 (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.openoffice.org/license.html. * * Software provided under this License is provided on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. * See the License for the specific provisions governing your rights and * obligations concerning the Software. * * The Initial Developer of the Original Code is: Sun Microsystems, Inc.. * * Copyright: 2000 by Sun Microsystems, Inc. * * All Rights Reserved. * * Contributor(s): _______________________________________ * * ************************************************************************/ #ifndef _SVTOOLS_EDITBROWSEBOX_HXX_ #include "editbrowsebox.hxx" #endif #ifndef _SVTOOLS_EDITBROWSEBOX_HRC_ #include "editbrowsebox.hrc" #endif #ifndef _APP_HXX //autogen #include #endif #ifndef _DEBUG_HXX #include #endif #ifndef _WINDOW_HXX //autogen #include #endif #ifndef _EDIT_HXX //autogen #include #endif #ifndef _TOOLS_RESID_HXX //autogen #include #endif #ifndef _SV_SPINFLD_HXX //autogen #include #endif #ifndef _SVTOOLS_SVTDATA_HXX #include "svtdata.hxx" #endif #ifndef _SVTOOLS_HRC #include "svtools.hrc" #endif #include // ....................................................................... namespace svt { // ....................................................................... //================================================================== #define HANDLE_ID 0 //================================================================== //= EditBrowserHeader //================================================================== //------------------------------------------------------------------------------ void EditBrowserHeader::DoubleClick() { sal_uInt16 nColId = GetCurItemId(); if (nColId) { sal_uInt32 nAutoWidth = ((EditBrowseBox*)GetParent())->GetAutoColumnWidth(nColId); if (nAutoWidth != ((EditBrowseBox*)GetParent())->GetColumnWidth(nColId)) { ((EditBrowseBox*)GetParent())->SetColumnWidth(nColId, nAutoWidth); ((EditBrowseBox*)GetParent())->ColumnResized(nColId); } } } //================================================================== //= EditBrowseBox //================================================================== //------------------------------------------------------------------------------ void EditBrowseBox::BrowserMouseEventPtr::Clear() { DELETEZ(pEvent); } //------------------------------------------------------------------------------ void EditBrowseBox::BrowserMouseEventPtr::Set(const BrowserMouseEvent* pEvt, sal_Bool bIsDown) { if (pEvt == pEvent) { bDown = bIsDown; return; } Clear(); if (pEvt) { pEvent = new BrowserMouseEvent(pEvt->GetWindow(), *pEvt, pEvt->GetRow(), pEvt->GetColumn(), pEvt->GetColumnId(), pEvt->GetRect()); bDown = bIsDown; } } DBG_NAME(EditBrowseBox); //------------------------------------------------------------------------------ EditBrowseBox::EditBrowseBox(Window* pParent, const ResId& rId, sal_Int32 nBrowserFlags, BrowserMode nMode) :BrowseBox(pParent, rId, nMode) ,nEditRow(-1) ,nPaintRow(-1) ,nOldEditRow(-1) ,nEditCol(0) ,nOldEditCol(0) ,bHasFocus(sal_False) ,bPaintStatus(sal_True) ,nStartEvent(0) ,nEndEvent(0) ,nCellModifiedEvent(0) ,m_nBrowserFlags(nBrowserFlags) { DBG_CTOR(EditBrowseBox,NULL); SetCompoundControl(sal_True); SetLineColor(Color(COL_LIGHTGRAY)); // HACK: the BrowseBox does not invalidate it's children (as it should be) // Thus we reset WB_CLIPCHILDREN, which forces the invalidation of the children WinBits aStyle = GetStyle(); if( aStyle & WB_CLIPCHILDREN ) { aStyle &= ~WB_CLIPCHILDREN; SetStyle( aStyle ); } ImplInitSettings(sal_True, sal_True, sal_True); pCheckBoxPaint = new CheckBoxControl(&GetDataWindow()); pCheckBoxPaint->SetPaintTransparent( sal_True ); pCheckBoxPaint->SetBackground(); } //================================================================== EditBrowseBox::EditBrowseBox(Window* pParent, sal_Int32 nBrowserFlags, WinBits nBits, BrowserMode nMode) :BrowseBox(pParent, nBits, nMode) ,nEditRow(-1) ,nPaintRow(-1) ,nOldEditRow(-1) ,nEditCol(0) ,nOldEditCol(0) ,bHasFocus(sal_False) ,bPaintStatus(sal_True) ,nStartEvent(0) ,nEndEvent(0) ,nCellModifiedEvent(0) ,pHeader(NULL) ,m_nBrowserFlags(nBrowserFlags) { DBG_CTOR(EditBrowseBox,NULL); SetCompoundControl(sal_True); SetLineColor(Color(COL_LIGHTGRAY)); // HACK: the BrowseBox does not invalidate it's children (as it should be) // Thus we reset WB_CLIPCHILDREN, which forces the invalidation of the children WinBits aStyle = GetStyle(); if( aStyle & WB_CLIPCHILDREN ) { aStyle &= ~WB_CLIPCHILDREN; SetStyle( aStyle ); } ImplInitSettings(sal_True, sal_True, sal_True); pCheckBoxPaint = new CheckBoxControl(&GetDataWindow()); pCheckBoxPaint->SetPaintTransparent( sal_True ); pCheckBoxPaint->SetBackground(); } //------------------------------------------------------------------------------ void EditBrowseBox::Init() { // spaetes Construieren, } //------------------------------------------------------------------------------ EditBrowseBox::~EditBrowseBox() { if (nStartEvent) Application::RemoveUserEvent(nStartEvent); if (nEndEvent) Application::RemoveUserEvent(nEndEvent); if (nCellModifiedEvent) Application::RemoveUserEvent(nCellModifiedEvent); delete pCheckBoxPaint; DBG_DTOR(EditBrowseBox,NULL); } //------------------------------------------------------------------------------ void EditBrowseBox::RemoveRows() { BrowseBox::Clear(); nOldEditRow = nEditRow = nPaintRow = -1; nEditCol = nOldEditCol = 0; } //------------------------------------------------------------------------------ BrowserHeader* EditBrowseBox::CreateHeaderBar(BrowseBox* pParent) { pHeader = imp_CreateHeaderBar(pParent); if (!IsUpdateMode()) pHeader->SetUpdateMode(sal_False); return pHeader; } //------------------------------------------------------------------------------ BrowserHeader* EditBrowseBox::imp_CreateHeaderBar(BrowseBox* pParent) { return new EditBrowserHeader(pParent); } //------------------------------------------------------------------------------ void EditBrowseBox::LoseFocus() { BrowseBox::LoseFocus(); DetermineFocus(); } //------------------------------------------------------------------------------ void EditBrowseBox::GetFocus() { BrowseBox::GetFocus(); // This should handle the case that the BrowseBox (or one of it's children) // gets the focus from outside by pressing Tab if (IsEditing() && Controller()->GetWindow().IsVisible()) Controller()->GetWindow().GrabFocus(); DetermineFocus(); } //------------------------------------------------------------------------------ sal_Bool EditBrowseBox::SeekRow(long nRow) { nPaintRow = nRow; return sal_True; } //------------------------------------------------------------------------------ void EditBrowseBox::DetermineFocus() { sal_Bool bFocus = sal_False; for (Window* pWindow = Application::GetFocusWindow(); pWindow && !bFocus; pWindow = pWindow->GetParent()) bFocus = pWindow == this; if (bFocus != bHasFocus) bHasFocus = bFocus; } //------------------------------------------------------------------------------ IMPL_LINK(EditBrowseBox, StartEditHdl, void*, EMPTYTAG) { nStartEvent = 0; if (IsEditing()) { aController->GetWindow().Show(); if (!aController->GetWindow().HasFocus() && (m_pFocusWhileRequest == Application::GetFocusWindow())) aController->GetWindow().GrabFocus(); } return 0; } //------------------------------------------------------------------------------ void EditBrowseBox::PaintField( OutputDevice& rDev, const Rectangle& rRect, sal_uInt16 nColumnId ) const { if (nColumnId == HANDLE_ID) { if (bPaintStatus) PaintStatusCell(rDev, rRect); } else { // don't paint the current cell if (&rDev == &GetDataWindow()) // but only if we're painting onto our data win (which is the usual painting) if (nPaintRow == nEditRow) { if (IsEditing() && nEditCol == nColumnId && aController->GetWindow().IsVisible()) return; } PaintCell(rDev, rRect, nColumnId); } } //------------------------------------------------------------------------------ Image EditBrowseBox::GetImage(RowStatus eStatus) const { if (!m_aStatusImages.GetImageCount()) const_cast(this)->m_aStatusImages = ImageList(SvtResId(RID_SVTOOLS_IMAGELIST_EDITBROWSEBOX)); Image aImage; switch (eStatus) { case CURRENT: aImage = m_aStatusImages.GetImage(IMG_EBB_CURRENT); break; case CURRENTNEW: aImage = m_aStatusImages.GetImage(IMG_EBB_CURRENTNEW); break; case MODIFIED: aImage = m_aStatusImages.GetImage(IMG_EBB_MODIFIED); break; case NEW: aImage = m_aStatusImages.GetImage(IMG_EBB_NEW); break; case DELETED: aImage = m_aStatusImages.GetImage(IMG_EBB_DELETED); break; case PRIMARYKEY: aImage = m_aStatusImages.GetImage(IMG_EBB_PRIMARYKEY); break; case CURRENT_PRIMARYKEY: aImage = m_aStatusImages.GetImage(IMG_EBB_CURRENT_PRIMARYKEY); break; case FILTER: aImage = m_aStatusImages.GetImage(IMG_EBB_FILTER); break; } return aImage; } //------------------------------------------------------------------------------ void EditBrowseBox::PaintStatusCell(OutputDevice& rDev, const Rectangle& rRect) const { if (nPaintRow < 0) return; RowStatus eStatus = GetRowStatus( nPaintRow ); if ( eStatus == CLEAN ) return; if (GetBrowserFlags() & EBBF_NOROWPICTURE) return; if (rDev.GetOutDevType() == OUTDEV_WINDOW) { Image aImage(GetImage(eStatus)); // calc the image position Size aImageSize(aImage.GetSizePixel()); aImageSize.Width() = CalcZoom(aImageSize.Width()); aImageSize.Height() = CalcZoom(aImageSize.Height()); Point aPos(rRect.TopLeft()); if (aImageSize.Width() > rRect.GetWidth() || aImageSize.Height() > rRect.GetHeight()) rDev.SetClipRegion(rRect); if (aImageSize.Width() < rRect.GetWidth()) aPos.X() += (rRect.GetWidth() - aImageSize.Width()) / 2; if (IsZoom()) rDev.DrawImage(aPos, aImageSize, aImage, 0); else rDev.DrawImage(aPos, aImage, 0); if (rDev.IsClipRegion()) rDev.SetClipRegion(); } } //------------------------------------------------------------------------------ EditBrowseBox::RowStatus EditBrowseBox::GetRowStatus(long nRow) const { return CLEAN; } //------------------------------------------------------------------------------ void EditBrowseBox::KeyInput( const KeyEvent& rEvt ) { sal_uInt16 nCode = rEvt.GetKeyCode().GetCode(); sal_Bool bShift = rEvt.GetKeyCode().IsShift(); sal_Bool bCtrl = rEvt.GetKeyCode().IsMod1(); switch (nCode) { case KEY_RETURN: if (!bCtrl && !bShift && IsTabAllowed(sal_True)) { Dispatch(BROWSER_CURSORRIGHT); } else BrowseBox::KeyInput(rEvt); return; case KEY_TAB: if (!bCtrl && !bShift) { if (IsTabAllowed(sal_True)) Dispatch(BROWSER_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; } else if (!bCtrl && bShift) { if (IsTabAllowed(sal_False)) Dispatch(BROWSER_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; } default: BrowseBox::KeyInput(rEvt); } } //------------------------------------------------------------------------------ void EditBrowseBox::MouseButtonDown(const BrowserMouseEvent& rEvt) { sal_uInt16 nColPos = GetColumnPos( rEvt.GetColumnId() ); long nRow = rEvt.GetRow(); // absorb double clicks if (rEvt.GetClicks() > 1 && rEvt.GetRow() >= 0) return; // change to a new position if (IsEditing() && (nColPos != nEditCol || nRow != nEditRow) && (nColPos != BROWSER_INVALIDID) && (nRow < GetRowCount())) { CellControllerRef aController(Controller()); HideAndDisable(aController); } if (0 == rEvt.GetColumnId()) { // it was the handle column. save the current cell content if necessary // (clicking on the handle column results in selecting the current row) // 23.01.2001 - 82797 - FS if (IsEditing() && aController->IsModified()) SaveModified(); } aMouseEvent.Set(&rEvt,sal_True); BrowseBox::MouseButtonDown(rEvt); aMouseEvent.Clear(); if (0 != (m_nBrowserFlags & EBBF_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, sal_False); } } //------------------------------------------------------------------------------ void EditBrowseBox::MouseButtonUp( const BrowserMouseEvent& rEvt ) { sal_uInt16 nColPos = GetColumnPos( rEvt.GetColumnId() ); long nRow = rEvt.GetRow(); // absorb double clicks if (rEvt.GetClicks() > 1 && rEvt.GetRow() >= 0) return; aMouseEvent.Set(&rEvt,sal_False); BrowseBox::MouseButtonUp(rEvt); aMouseEvent.Clear(); if (0 == (m_nBrowserFlags & EBBF_ACTIVATE_ON_BUTTONDOWN)) if (rEvt.GetRow() >= 0) implActivateCellOnMouseEvent(rEvt, sal_True); } //------------------------------------------------------------------------------ void EditBrowseBox::implActivateCellOnMouseEvent(const BrowserMouseEvent& _rEvt, sal_Bool _bUp) { if (!IsEditing()) ActivateCell(); else if (IsEditing() && !aController->GetWindow().IsEnabled()) DeactivateCell(); else if (IsEditing() && !aController->GetWindow().HasChildPathFocus()) AsynchGetFocus(); if (IsEditing() && aController->GetWindow().IsEnabled() && aController->WantMouseEvent()) { // forwards the event to the control // If the field has been moved previously, we have to adjust the position aController->GetWindow().GrabFocus(); // the position of the event relative to the controller's window Point aPos = _rEvt.GetPosPixel() - _rEvt.GetRect().TopLeft(); // the (child) window which should really get the event Window* pRealHandler = aController->GetWindow().FindWindow(aPos); if (pRealHandler) // the coords relative to this real handler aPos -= pRealHandler->GetPosPixel(); else pRealHandler = &aController->GetWindow(); // the faked event MouseEvent aEvent(aPos, _rEvt.GetClicks(), _rEvt.GetMode(), _rEvt.GetButtons(), _rEvt.GetModifier()); pRealHandler->MouseButtonDown(aEvent); if (_bUp) pRealHandler->MouseButtonUp(aEvent); Window *pWin = &aController->GetWindow(); if (!pWin->IsTracking()) { for (pWin = pWin->GetWindow(WINDOW_FIRSTCHILD); pWin && !pWin->IsTracking(); pWin = pWin->GetWindow(WINDOW_NEXT)) { } } if (pWin && pWin->IsTracking()) pWin->EndTracking(); } } //------------------------------------------------------------------------------ void EditBrowseBox::Dispatch(sal_uInt16 nId) { BrowseBox::Dispatch(nId); } //------------------------------------------------------------------------------ long EditBrowseBox::PreNotify(NotifyEvent& rEvt) { switch (rEvt.GetType()) { case EVENT_KEYINPUT: if ( (IsEditing() && Controller()->GetWindow().HasChildPathFocus()) || rEvt.GetWindow() == &GetDataWindow() || (!IsEditing() && HasChildPathFocus()) ) { const KeyEvent* pKeyEvent = rEvt.GetKeyEvent(); sal_uInt16 nCode = pKeyEvent->GetKeyCode().GetCode(); sal_Bool bShift = pKeyEvent->GetKeyCode().IsShift(); sal_Bool bCtrl = pKeyEvent->GetKeyCode().IsMod1(); sal_Bool bAlt = pKeyEvent->GetKeyCode().IsMod2(); sal_Bool bSelect= sal_False; sal_Bool bModify= sal_False; sal_uInt16 nId = BROWSER_NONE; if (!bAlt && !bCtrl && !bShift ) switch ( nCode ) { case KEY_DOWN: nId = BROWSER_CURSORDOWN; break; case KEY_UP: nId = BROWSER_CURSORUP; break; case KEY_PAGEDOWN: nId = BROWSER_CURSORPAGEDOWN; break; case KEY_PAGEUP: nId = BROWSER_CURSORPAGEUP; break; case KEY_HOME: nId = BROWSER_CURSORHOME; break; case KEY_END: nId = BROWSER_CURSOREND; break; case KEY_TAB: // ask if traveling to the next cell is allowed if (IsTabAllowed(sal_True)) nId = BROWSER_CURSORRIGHT; break; case KEY_RETURN: // save the cell content (if necessary) if (IsEditing() && aController->IsModified() && !((EditBrowseBox *) this)->SaveModified()) { // maybe we're not visible ... EnableAndShow(); aController->GetWindow().GrabFocus(); return 1; } // ask if traveling to the next cell is allowed if (IsTabAllowed(sal_True)) nId = BROWSER_CURSORRIGHT; break; case KEY_RIGHT: nId = BROWSER_CURSORRIGHT; break; case KEY_LEFT: nId = BROWSER_CURSORLEFT; break; case KEY_SPACE: nId = BROWSER_SELECT; bModify = bSelect = sal_True;break; } if ( !bAlt && !bCtrl && bShift ) switch ( nCode ) { case KEY_DOWN: nId = BROWSER_SELECTDOWN; bSelect = sal_True;break; case KEY_UP: nId = BROWSER_SELECTUP; bSelect = sal_True;break; case KEY_HOME: nId = BROWSER_SELECTHOME; bSelect = sal_True;break; case KEY_END: nId = BROWSER_SELECTEND; bSelect = sal_True;break; case KEY_TAB: if (IsTabAllowed(sal_False)) nId = BROWSER_CURSORLEFT; break; } if ( !bAlt && bCtrl && !bShift ) switch ( nCode ) { case KEY_DOWN: nId = BROWSER_SCROLLUP; break; case KEY_UP: nId = BROWSER_SCROLLDOWN; break; case KEY_PAGEDOWN: nId = BROWSER_CURSORENDOFFILE; break; case KEY_PAGEUP: nId = BROWSER_CURSORTOPOFFILE; break; case KEY_HOME: nId = BROWSER_CURSORTOPOFSCREEN; break; case KEY_END: nId = BROWSER_CURSORENDOFSCREEN; break; case KEY_SPACE: nId = BROWSER_SELECT; bModify = bSelect = sal_True;break; } if (nId != BROWSER_NONE && (!IsEditing() || (!bModify && aController->MoveAllowed(*pKeyEvent)))) { if (nId == BROWSER_SELECT) { // save the cell content (if necessary) if (IsEditing() && aController->IsModified() && !((EditBrowseBox *) this)->SaveModified()) { // maybe we're not visible ... EnableAndShow(); aController->GetWindow().GrabFocus(); return 1; } } Dispatch(nId); if (bSelect && (!GetSelectRowCount() || GetSelection() != NULL)) ActivateCell(); return 1; } } } return BrowseBox::PreNotify(rEvt); } //------------------------------------------------------------------------------ sal_Bool EditBrowseBox::IsTabAllowed(sal_Bool bRight) const { return sal_True; } //------------------------------------------------------------------------------ long EditBrowseBox::Notify(NotifyEvent& rEvt) { switch (rEvt.GetType()) { case EVENT_GETFOCUS: case EVENT_LOSEFOCUS: DetermineFocus(); } return BrowseBox::Notify(rEvt); } //------------------------------------------------------------------------------ void EditBrowseBox::StateChanged( StateChangedType nType ) { BrowseBox::StateChanged( nType ); if ( nType == STATE_CHANGE_ZOOM ) { ImplInitSettings( sal_True, sal_False, sal_False ); if (IsEditing()) { DeactivateCell(); ActivateCell(); } } else if ( nType == STATE_CHANGE_CONTROLFONT ) { ImplInitSettings( sal_True, sal_False, sal_False ); Invalidate(); } else if ( nType == STATE_CHANGE_CONTROLFOREGROUND ) { ImplInitSettings( sal_False, sal_True, sal_False ); Invalidate(); } else if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) { ImplInitSettings( sal_False, sal_False, sal_True ); Invalidate(); } else if (nType == STATE_CHANGE_STYLE) { WinBits nStyle = GetStyle(); if (!(nStyle & WB_NOTABSTOP) ) nStyle |= WB_TABSTOP; SetStyle(nStyle); } } //------------------------------------------------------------------------------ void EditBrowseBox::DataChanged( const DataChangedEvent& rDCEvt ) { BrowseBox::DataChanged( rDCEvt ); if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS ) && (rDCEvt.GetFlags() & SETTINGS_STYLE) ) { ImplInitSettings( sal_True, sal_True, sal_True ); Invalidate(); } } //------------------------------------------------------------------------------ void EditBrowseBox::ImplInitSettings( sal_Bool bFont, sal_Bool bForeground, sal_Bool bBackground ) { const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); if (bFont) { Font aFont = rStyleSettings.GetFieldFont(); if (IsControlFont()) { GetDataWindow().SetControlFont(GetControlFont()); aFont.Merge(GetControlFont()); } else GetDataWindow().SetControlFont(); GetDataWindow().SetZoomedPointFont(aFont); } if ( bFont || bForeground ) { Color aTextColor = rStyleSettings.GetFieldTextColor(); if (IsControlForeground()) { aTextColor = GetControlForeground(); GetDataWindow().SetControlForeground(aTextColor); } else GetDataWindow().SetControlForeground(); GetDataWindow().SetTextColor( aTextColor ); } if ( bBackground ) { if (GetDataWindow().IsControlBackground()) { GetDataWindow().SetControlBackground(GetControlBackground()); GetDataWindow().SetBackground(GetDataWindow().GetControlBackground()); GetDataWindow().SetFillColor(GetDataWindow().GetControlBackground()); } else { GetDataWindow().SetControlBackground(); GetDataWindow().SetBackground( rStyleSettings.GetFieldColor() ); GetDataWindow().SetFillColor( rStyleSettings.GetFieldColor() ); } } } //------------------------------------------------------------------------------ sal_Bool EditBrowseBox::IsCursorMoveAllowed(long nNewRow, sal_uInt16 nNewColId) const { sal_uInt16 nInfo = 0; if (GetSelectColumnCount() || (aMouseEvent.Is() && aMouseEvent->GetRow() < 0)) nInfo |= COLSELECT; if ((GetSelection() != NULL && GetSelectRowCount()) || (aMouseEvent.Is() && aMouseEvent->GetColumnId() == HANDLE_ID)) nInfo |= ROWSELECT; if (!nInfo && nNewRow != nEditRow) nInfo |= ROWCHANGE; if (!nInfo && nNewColId != nEditCol) nInfo |= COLCHANGE; if (nInfo == 0) // nothing happened return sal_True; // save the cell content if (IsEditing() && aController->IsModified() && !((EditBrowseBox *) this)->SaveModified()) { // maybe we're not visible ... EnableAndShow(); aController->GetWindow().GrabFocus(); return sal_False; } EditBrowseBox * pTHIS = (EditBrowseBox *) this; // save the cell content if // a) a selection is beeing 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(); } return sal_False; } if (nNewRow != nEditRow) { Window& rWindow = GetDataWindow(); // don't paint too much // update the status immediatly if possible if ((nEditRow >= 0) && (GetBrowserFlags() & EBBF_NOROWPICTURE) == 0) { Rectangle aRect = GetFieldRectPixel(nEditRow, 0, sal_False ); pTHIS->bPaintStatus = sal_False; rWindow.Paint(aRect); pTHIS->bPaintStatus = sal_True; } // don't paint during row change rWindow.EnablePaint(sal_False); // the last veto chance for derived classes if (!pTHIS->CursorMoving(nNewRow, nNewColId)) { pTHIS->InvalidateStatusCell(nEditRow); rWindow.EnablePaint(sal_True); return sal_False; } else return sal_True; } else return pTHIS->CursorMoving(nNewRow, nNewColId); } //------------------------------------------------------------------------------ void EditBrowseBox::ColumnMoved(sal_uInt16 nId) { BrowseBox::ColumnMoved(nId); if (IsEditing()) { Rectangle aRect( GetCellRect(nEditRow, nEditCol, sal_False)); CellControllerRef aControllerRef = Controller(); ResizeController(aControllerRef, aRect); Controller()->GetWindow().GrabFocus(); } } //------------------------------------------------------------------------------ sal_Bool EditBrowseBox::SaveRow() { return sal_True; } //------------------------------------------------------------------------------ sal_Bool EditBrowseBox::CursorMoving(long nNewRow, sal_uInt16 nNewCol) { ((EditBrowseBox *) this)->DeactivateCell(sal_False); return sal_True; } //------------------------------------------------------------------------------ void EditBrowseBox::CursorMoved() { long nNewRow = GetCurRow(); if (nEditRow != nNewRow) { if ((GetBrowserFlags() & EBBF_NOROWPICTURE) == 0) InvalidateStatusCell(nNewRow); nEditRow = nNewRow; } ActivateCell(); GetDataWindow().EnablePaint(sal_True); } //------------------------------------------------------------------------------ void EditBrowseBox::EndScroll() { if (IsEditing()) { Rectangle aRect = GetCellRect(nEditRow, nEditCol, sal_False); ResizeController(aController,aRect); AsynchGetFocus(); } BrowseBox::EndScroll(); } //------------------------------------------------------------------------------ void EditBrowseBox::ActivateCell(long nRow, sal_uInt16 nCol, sal_Bool bCellFocus) { if (IsEditing()) return; nEditCol = nCol; if ((GetSelectRowCount() && GetSelection() != NULL) || GetSelectColumnCount() || (aMouseEvent.Is() && (aMouseEvent.IsDown() || aMouseEvent->GetClicks() > 1))) // bei MouseDown passiert noch nichts { return; } if (nEditRow >= 0 && nEditCol > HANDLE_ID) { aController = GetController(nRow, nCol); if (aController.Is()) { Rectangle aRect( GetCellRect(nEditRow, nEditCol, sal_False)); ResizeController(aController, aRect); InitController(aController, nEditRow, nEditCol); aController->ClearModified(); aController->SetModifyHdl(LINK(this,EditBrowseBox,ModifyHdl)); EnableAndShow(); // activate the cell only of the browser has the focus if (bHasFocus && bCellFocus) AsynchGetFocus(); } } } //------------------------------------------------------------------------------ void EditBrowseBox::DeactivateCell(sal_Bool bUpdate) { if (IsEditing()) { aOldController = aController; aController.Clear(); // reset the modify handler aOldController->SetModifyHdl(Link()); if (bHasFocus) GrabFocus(); // ensure that we have (and keep) the focus HideAndDisable(aOldController); // update if requested if (bUpdate) Update(); nOldEditCol = nEditCol; nOldEditRow = nEditRow; // release the controller (asynchronously) if (nEndEvent) Application::RemoveUserEvent(nEndEvent); nEndEvent = Application::PostUserEvent(LINK(this,EditBrowseBox,EndEditHdl)); } } //------------------------------------------------------------------------------ Rectangle EditBrowseBox::GetCellRect(long nRow, sal_uInt16 nColId, sal_Bool bRel) const { Rectangle aRect( GetFieldRectPixel(nRow, nColId, bRel)); if ((GetMode() & BROWSER_CURSOR_WO_FOCUS) == BROWSER_CURSOR_WO_FOCUS) { aRect.Top() += 1; aRect.Bottom() -= 1; } return aRect; } //------------------------------------------------------------------------------ IMPL_LINK(EditBrowseBox, EndEditHdl, void*, EMPTYTAG) { nEndEvent = 0; ReleaseController(aOldController, nOldEditRow, nOldEditCol); aOldController = CellControllerRef(); nOldEditRow = -1; nOldEditCol = 0; return 0; } //------------------------------------------------------------------------------ IMPL_LINK(EditBrowseBox, ModifyHdl, void*, EMPTYTAG) { if (nCellModifiedEvent) Application::RemoveUserEvent(nCellModifiedEvent); nCellModifiedEvent = Application::PostUserEvent(LINK(this,EditBrowseBox,CellModifiedHdl)); return 0; } //------------------------------------------------------------------------------ IMPL_LINK(EditBrowseBox, CellModifiedHdl, void*, EMPTYTAG) { nCellModifiedEvent = 0; CellModified(); return 0; } //------------------------------------------------------------------------------ void EditBrowseBox::ColumnResized( sal_uInt16 nColId ) { if (IsEditing()) { Rectangle aRect( GetCellRect(nEditRow, nEditCol, sal_False)); CellControllerRef aControllerRef = Controller(); ResizeController(aControllerRef, aRect); Controller()->GetWindow().GrabFocus(); } } //------------------------------------------------------------------------------ sal_uInt16 EditBrowseBox::GetDefaultColumnWidth(const String& rName) const { return GetDataWindow().GetTextWidth(rName) + GetDataWindow().GetTextWidth('0') * 4; } //------------------------------------------------------------------------------ void EditBrowseBox::InsertHandleColumn(sal_uInt16 nWidth) { if (!nWidth) nWidth = GetDefaultColumnWidth(String()); BrowseBox::InsertHandleColumn(nWidth, sal_True); } //------------------------------------------------------------------------------ sal_uInt16 EditBrowseBox::AppendColumn(const String& rName, sal_uInt16 nWidth, sal_uInt16 nPos, sal_uInt16 nId) { if (nId == (sal_uInt16)-1) { // look for the next free id for (nId = ColCount(); nId > 0 && GetColumnPos(nId) != BROWSER_INVALIDID; nId--) ; if (!nId) { // if there is no handle column // increment the id if (!ColCount() || GetColumnId(0)) nId = ColCount() + 1; } } DBG_ASSERT(nId, "EditBrowseBox::AppendColumn: invalid id!"); if (!nWidth) nWidth = GetDefaultColumnWidth(rName); InsertDataColumn(nId, rName, nWidth, (HIB_CENTER | HIB_VCENTER | HIB_CLICKABLE), nPos); return nId; } //------------------------------------------------------------------------------ void EditBrowseBox::Resize() { BrowseBox::Resize(); // 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 = (sal_uInt16)aPoint.X(); ArrangeControls(nX, (sal_uInt16)aPoint.Y()); if (!nX) nX = 0; ReserveControlArea((sal_uInt16)nX); } //------------------------------------------------------------------------------ void EditBrowseBox::ArrangeControls(sal_uInt16& nX, sal_uInt16 nY) { } //------------------------------------------------------------------------------ CellController* EditBrowseBox::GetController(long, sal_uInt16) { return NULL; } //----------------------------------------------------------------------------- void EditBrowseBox::ResizeController(CellControllerRef& rController, const Rectangle& rRect) { rController->GetWindow().SetPosSizePixel(rRect.TopLeft(), rRect.GetSize()); } //------------------------------------------------------------------------------ void EditBrowseBox::InitController(CellControllerRef& rController, long nRow, sal_uInt16 nCol) { } //------------------------------------------------------------------------------ void EditBrowseBox::ReleaseController(CellControllerRef& rController, long nRow, sal_uInt16 nCol) { } //------------------------------------------------------------------------------ void EditBrowseBox::CellModified() { } //------------------------------------------------------------------------------ sal_Bool EditBrowseBox::SaveModified() { return sal_True; } //------------------------------------------------------------------------------ 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 != HANDLE_ID) SetColumnWidth(nColId, GetAutoColumnWidth(nColId)); } //------------------------------------------------------------------------------ sal_uInt32 EditBrowseBox::GetAutoColumnWidth(sal_uInt16 nColId) { sal_uInt32 nCurColWidth = GetColumnWidth(nColId); sal_uInt32 nMinColWidth = CalcZoom(20); // minimum sal_uInt32 nNewColWidth = nMinColWidth; long nMaxRows = Min(long(GetVisibleRows()), GetRowCount()); long nLastVisRow = GetTopRow() + nMaxRows - 1; if (GetTopRow() <= nLastVisRow) // calc the column with using the cell contents { for (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; } //------------------------------------------------------------------------------ sal_uInt32 EditBrowseBox::GetTotalCellWidth(long nRow, sal_uInt16 nColId) { return 0; } //------------------------------------------------------------------------------ void EditBrowseBox::InvalidateHandleColumn() { Rectangle aHdlFieldRect( GetFieldRectPixel( 0, 0 )); Rectangle aInvalidRect( Point(0,0), GetOutputSizePixel() ); aInvalidRect.Right() = aHdlFieldRect.Right(); Invalidate( aInvalidRect ); } //------------------------------------------------------------------------------ void EditBrowseBox::PaintTristate(OutputDevice& rDev, const Rectangle& rRect,const TriState& eState,sal_Bool _bEnabled) const { pCheckBoxPaint->GetBox().SetState(eState); pCheckBoxPaint->SetPosSizePixel(rRect.TopLeft(), rRect.GetSize()); // First update the parent, preventing that while painting this window // an update for the parent is done (because it's in the queue already) // which may lead to hiding this window immediately if (pCheckBoxPaint->GetParent()) pCheckBoxPaint->GetParent()->Update(); pCheckBoxPaint->GetBox().Enable(_bEnabled); pCheckBoxPaint->Show(); pCheckBoxPaint->Update(); pCheckBoxPaint->SetParentUpdateMode( sal_False ); pCheckBoxPaint->Hide(); pCheckBoxPaint->SetParentUpdateMode( sal_True ); } //------------------------------------------------------------------------------ void EditBrowseBox::AsynchGetFocus() { if (nStartEvent) Application::RemoveUserEvent(nStartEvent); m_pFocusWhileRequest = Application::GetFocusWindow(); nStartEvent = Application::PostUserEvent(LINK(this,EditBrowseBox,StartEditHdl)); } //------------------------------------------------------------------------------ void EditBrowseBox::SetBrowserFlags(sal_Int32 nFlags) { if (m_nBrowserFlags == nFlags) return; sal_Bool RowPicturesChanges = ((m_nBrowserFlags & EBBF_NOROWPICTURE) != (nFlags & EBBF_NOROWPICTURE)); m_nBrowserFlags = nFlags; if (RowPicturesChanges) InvalidateStatusCell(GetCurRow()); } //------------------------------------------------------------------------------ inline void EditBrowseBox::HideAndDisable(CellControllerRef& rController) { rController->GetWindow().Hide(); rController->GetWindow().Disable(); } //------------------------------------------------------------------------------ inline void EditBrowseBox::EnableAndShow() const { Controller()->GetWindow().Enable(); Controller()->GetWindow().Show(); } //=============================================================================== DBG_NAME(CellController); //------------------------------------------------------------------------------ CellController::CellController(Window* pW) :pWindow(pW) { DBG_CTOR(CellController,NULL); DBG_ASSERT(pWindow, "CellController::CellController: missing the window!"); DBG_ASSERT(!pWindow->IsVisible(), "CellController::CellController: window should not be visible!"); } //----------------------------------------------------------------------------- CellController::~CellController() { DBG_DTOR(CellController,NULL); } //----------------------------------------------------------------------------- sal_Bool CellController::WantMouseEvent() const { return sal_False; } //----------------------------------------------------------------------------- void CellController::SetModified() { } //----------------------------------------------------------------------------- sal_Bool CellController::MoveAllowed(const KeyEvent& rEvt) const { return sal_True; } //------------------------------------------------------------------------------ EditCellController::EditCellController(Edit* pWin) :CellController(pWin) { } //----------------------------------------------------------------------------- void EditCellController::SetModified() { GetEditWindow().SetModifyFlag(); } //----------------------------------------------------------------------------- void EditCellController::ClearModified() { GetEditWindow().ClearModifyFlag(); } //------------------------------------------------------------------------------ sal_Bool EditCellController::MoveAllowed(const KeyEvent& rEvt) const { sal_Bool bResult; switch (rEvt.GetKeyCode().GetCode()) { case KEY_END: case KEY_RIGHT: { Selection aSel = GetEditWindow().GetSelection(); bResult = !aSel && aSel.Max() == GetEditWindow().GetText().Len(); } break; case KEY_HOME: case KEY_LEFT: { Selection aSel = GetEditWindow().GetSelection(); bResult = !aSel && aSel.Min() == 0; } break; default: bResult = sal_True; } return bResult; } //------------------------------------------------------------------------------ sal_Bool EditCellController::IsModified() const { return GetEditWindow().IsModified(); } //------------------------------------------------------------------------------ void EditCellController::SetModifyHdl(const Link& rLink) { GetEditWindow().SetModifyHdl(rLink); } //------------------------------------------------------------------------------ SpinCellController::SpinCellController(SpinField* pWin) :CellController(pWin) { } //----------------------------------------------------------------------------- void SpinCellController::SetModified() { GetSpinWindow().SetModifyFlag(); } //----------------------------------------------------------------------------- void SpinCellController::ClearModified() { GetSpinWindow().ClearModifyFlag(); } //------------------------------------------------------------------------------ sal_Bool SpinCellController::MoveAllowed(const KeyEvent& rEvt) const { sal_Bool bResult; switch (rEvt.GetKeyCode().GetCode()) { case KEY_END: case KEY_RIGHT: { Selection aSel = GetSpinWindow().GetSelection(); bResult = !aSel && aSel.Max() == GetSpinWindow().GetText().Len(); } break; case KEY_HOME: case KEY_LEFT: { Selection aSel = GetSpinWindow().GetSelection(); bResult = !aSel && aSel.Min() == 0; } break; default: bResult = sal_True; } return bResult; } //------------------------------------------------------------------------------ sal_Bool SpinCellController::IsModified() const { return GetSpinWindow().IsModified(); } //------------------------------------------------------------------------------ void SpinCellController::SetModifyHdl(const Link& rLink) { GetSpinWindow().SetModifyHdl(rLink); } // ....................................................................... } // namespace svt // ....................................................................... /************************************************************************* * history: * $Log: not supported by cvs2svn $ * Revision 1.2 2001/09/28 13:00:28 hr * #65293#: gcc-3.0.1. needs lvalue * * Revision 1.1 2001/06/15 12:49:19 fs * initial checkin - moved this herein from svx/source/fmcomp/dbbrowse* * * * Revision 1.0 15.06.01 12:45:03 fs ************************************************************************/