sfx2/inc/sfx2/thumbnailview.hxx | 3 sfx2/source/control/templateabstractview.cxx | 2 sfx2/source/control/templatelocalview.cxx | 2 sfx2/source/control/templatesearchview.cxx | 2 sfx2/source/control/thumbnailview.cxx | 301 +++++++++++++++++++++------ sfx2/source/doc/templatedlg.cxx | 4 6 files changed, 253 insertions(+), 61 deletions(-)
New commits: commit 9993d25441e8b4d19b8dc8e818cd311114e74e49 Author: Rafael Dominguez <[email protected]> Date: Fri Apr 5 21:18:49 2013 -0430 fdo#61390 - Thumbnail navigation by shift-click and shift-keyboard. Change-Id: Ia63b2a39df1c2aa76bb288e032b35d95bb0ff439 diff --git a/sfx2/inc/sfx2/thumbnailview.hxx b/sfx2/inc/sfx2/thumbnailview.hxx index dbab91c..14bfd65 100644 --- a/sfx2/inc/sfx2/thumbnailview.hxx +++ b/sfx2/inc/sfx2/thumbnailview.hxx @@ -301,6 +301,7 @@ protected: ValueItemList mItemList; ValueItemList mFilteredItemList; ///< Cache to store the filtered items + ValueItemList::iterator mpStartSelRange; ScrollBar* mpScrBar; Rectangle maItemListRect; long mnHeaderHeight; diff --git a/sfx2/source/control/thumbnailview.cxx b/sfx2/source/control/thumbnailview.cxx index 9203078..f73b364 100644 --- a/sfx2/source/control/thumbnailview.cxx +++ b/sfx2/source/control/thumbnailview.cxx @@ -10,6 +10,8 @@ #include <sfx2/thumbnailview.hxx> #include <sfx2/thumbnailviewitem.hxx> +#include <utility> + #include "thumbnailviewacc.hxx" #include <basegfx/color/bcolortools.hxx> @@ -84,7 +86,20 @@ ThumbnailView::~ThumbnailView() void ThumbnailView::AppendItem(ThumbnailViewItem *pItem) { if (maFilterFunc(pItem)) + { + // Save current start,end range, iterator might get invalidated + size_t nSelStartPos = 0; + ThumbnailViewItem *pSelStartItem = NULL; + + if (mpStartSelRange != mFilteredItemList.end()) + { + pSelStartItem = *mpStartSelRange; + nSelStartPos = mpStartSelRange - mFilteredItemList.begin(); + } + mFilteredItemList.push_back(pItem); + mpStartSelRange = pSelStartItem != NULL ? mFilteredItemList.begin() + nSelStartPos : mFilteredItemList.end(); + } mItemList.push_back(pItem); } @@ -106,6 +121,7 @@ void ThumbnailView::ImplInit() mbHasVisibleItems = false; maFilterFunc = ViewFilterAll(); maColor = GetSettings().GetStyleSettings().GetFieldColor(); + mpStartSelRange = mFilteredItemList.end(); // Create the processor and process the primitives const drawinglayer::geometry::ViewInformation2D aNewViewInfos; @@ -144,6 +160,8 @@ void ThumbnailView::ImplDeleteItems() mItemList.clear(); mFilteredItemList.clear(); + + mpStartSelRange = mFilteredItemList.end(); } void ThumbnailView::ImplInitSettings( bool bFont, bool bForeground, bool bBackground ) @@ -394,9 +412,9 @@ size_t ThumbnailView::ImplGetItem( const Point& rPos, bool bMove ) const if ( maItemListRect.IsInside( rPos ) ) { - for (size_t i = 0; i < mItemList.size(); ++i) + for (size_t i = 0; i < mFilteredItemList.size(); ++i) { - if (mItemList[i]->isVisible() && mItemList[i]->getDrawArea().IsInside(rPos)) + if (mFilteredItemList[i]->isVisible() && mFilteredItemList[i]->getDrawArea().IsInside(rPos)) return i; } @@ -413,7 +431,7 @@ size_t ThumbnailView::ImplGetItem( const Point& rPos, bool bMove ) const ThumbnailViewItem* ThumbnailView::ImplGetItem( size_t nPos ) { - return ( nPos < mItemList.size() ) ? mItemList[nPos] : NULL; + return ( nPos < mFilteredItemList.size() ) ? mFilteredItemList[nPos] : NULL; } sal_uInt16 ThumbnailView::ImplGetVisibleItemCount() const @@ -501,39 +519,66 @@ void ThumbnailView::KeyInput( const KeyEvent& rKEvt ) } } + bool bValidRange = false; + bool bHasSelRange = mpStartSelRange != mFilteredItemList.end(); + size_t nNextPos = nLastPos; KeyCode aKeyCode = rKEvt.GetKeyCode(); ThumbnailViewItem* pNext = NULL; + + if (aKeyCode.IsShift() && bHasSelRange) + { + //If the last elemented selected is the start range position + //search for the first selected item + if (nLastPos == mpStartSelRange - mFilteredItemList.begin()) + { + while (nLastPos && mFilteredItemList[nLastPos-1]->isSelected()) + --nLastPos; + } + } + switch ( aKeyCode.GetCode() ) { case KEY_RIGHT: { - size_t nNextPos = nLastPos; if ( bFoundLast && nLastPos < mFilteredItemList.size( ) - 1 ) + { + bValidRange = true; nNextPos = nLastPos + 1; + } + pNext = mFilteredItemList[nNextPos]; } break; case KEY_LEFT: { - size_t nNextPos = nLastPos; if ( nLastPos > 0 ) + { + bValidRange = true; nNextPos = nLastPos - 1; + } + pNext = mFilteredItemList[nNextPos]; } break; case KEY_DOWN: { - size_t nNextPos = nLastPos; if ( bFoundLast && nLastPos < mFilteredItemList.size( ) - mnCols ) + { + bValidRange = true; nNextPos = nLastPos + mnCols; + } + pNext = mFilteredItemList[nNextPos]; } break; case KEY_UP: { - size_t nNextPos = nLastPos; if ( nLastPos >= mnCols ) + { + bValidRange = true; nNextPos = nLastPos - mnCols; + } + pNext = mFilteredItemList[nNextPos]; } break; @@ -548,8 +593,67 @@ void ThumbnailView::KeyInput( const KeyEvent& rKEvt ) if ( pNext ) { - deselectItems(); - SelectItem(pNext->mnId); + if (aKeyCode.IsShift() && bValidRange) + { + std::pair<size_t,size_t> aRange; + size_t nSelPos = mpStartSelRange - mFilteredItemList.begin(); + + if (nLastPos < nSelPos) + { + if (nNextPos > nLastPos) + { + if ( nNextPos > nSelPos) + aRange = std::make_pair(nLastPos,nNextPos); + else + aRange = std::make_pair(nLastPos,nNextPos-1); + } + else + aRange = std::make_pair(nNextPos,nLastPos-1); + } + else if (nLastPos == nSelPos) + { + if (nNextPos > nLastPos) + aRange = std::make_pair(nLastPos+1,nNextPos); + else + aRange = std::make_pair(nNextPos,nLastPos-1); + } + else + { + if (nNextPos > nLastPos) + aRange = std::make_pair(nLastPos+1,nNextPos); + else + { + if ( nNextPos < nSelPos) + aRange = std::make_pair(nNextPos,nLastPos); + else + aRange = std::make_pair(nNextPos+1,nLastPos); + } + } + + for (size_t i = aRange.first; i <= aRange.second; ++i) + { + if (i != nSelPos) + { + ThumbnailViewItem *pCurItem = mFilteredItemList[i]; + + pCurItem->setSelection(!pCurItem->isSelected()); + + if (pCurItem->isVisible()) + DrawItem(pCurItem); + + maItemStateHdl.Call(pCurItem); + } + } + } + else if (!aKeyCode.IsShift()) + { + deselectItems(); + SelectItem(pNext->mnId); + + //Mark it as the selection range start position + mpStartSelRange = mFilteredItemList.begin() + nNextPos; + } + MakeItemVisible(pNext->mnId); } } @@ -584,7 +688,8 @@ void ThumbnailView::MouseButtonDown( const MouseEvent& rMEvt ) { if ( rMEvt.IsLeft() ) { - ThumbnailViewItem* pItem = ImplGetItem( ImplGetItem( rMEvt.GetPosPixel() ) ); + size_t nPos = ImplGetItem(rMEvt.GetPosPixel()); + ThumbnailViewItem* pItem = ImplGetItem(nPos); if (pItem && pItem->isVisible()) { @@ -594,6 +699,62 @@ void ThumbnailView::MouseButtonDown( const MouseEvent& rMEvt ) { //Keep selected item group state and just invert current desired one state pItem->setSelection(!pItem->isSelected()); + + //This one becomes the selection range start position if it changes its state to selected otherwise resets it + mpStartSelRange = pItem->isSelected() ? mFilteredItemList.begin() + nPos : mFilteredItemList.end(); + } + else if (rMEvt.IsShift() && mpStartSelRange != mFilteredItemList.end()) + { + std::pair<size_t,size_t> aNewRange; + aNewRange.first = mpStartSelRange - mFilteredItemList.begin(); + aNewRange.second = nPos; + + if (aNewRange.first > aNewRange.second) + std::swap(aNewRange.first,aNewRange.second); + + //Deselect the ones outside of it + for (size_t i = 0, n = mFilteredItemList.size(); i < n; ++i) + { + ThumbnailViewItem *pCurItem = mFilteredItemList[i]; + + if (pCurItem->isSelected() && (i < aNewRange.first || i > aNewRange.second)) + { + pCurItem->setSelection(false); + + if (pCurItem->isVisible()) + DrawItem(pCurItem); + + maItemStateHdl.Call(pCurItem); + } + } + + size_t nSelPos = mpStartSelRange - mFilteredItemList.begin(); + + //Select the items between start range and the selected item + if (nSelPos != nPos) + { + int dir = nSelPos < nPos ? 1 : -1; + size_t nCurPos = nSelPos + dir; + + while (nCurPos != nPos) + { + ThumbnailViewItem *pCurItem = mFilteredItemList[nCurPos]; + + if (!pCurItem->isSelected()) + { + pCurItem->setSelection(true); + + if (pCurItem->isVisible()) + DrawItem(pCurItem); + + maItemStateHdl.Call(pCurItem); + } + + nCurPos += dir; + } + } + + pItem->setSelection(true); } else { @@ -602,6 +763,9 @@ void ThumbnailView::MouseButtonDown( const MouseEvent& rMEvt ) pItem->setSelection(false); deselectItems(); pItem->setSelection(true); + + //Mark as initial selection range position and reset end one + mpStartSelRange = mFilteredItemList.begin() + nPos; } if (pItem->isSelected()) @@ -1031,6 +1195,11 @@ void ThumbnailView::filterItems (const boost::function<bool (const ThumbnailView { mnFirstLine = 0; // start at the top of the list instead of the current position maFilterFunc = func; + + size_t nSelPos = 0; + bool bHasSelRange = false; + ThumbnailViewItem *curSel = mpStartSelRange != mFilteredItemList.end() ? *mpStartSelRange : NULL; + mFilteredItemList.clear(); for (size_t i = 0, n = mItemList.size(); i < n; ++i) @@ -1039,6 +1208,12 @@ void ThumbnailView::filterItems (const boost::function<bool (const ThumbnailView if (maFilterFunc(pItem)) { + if (curSel == pItem) + { + nSelPos = i; + bHasSelRange = true; + } + mFilteredItemList.push_back(pItem); } else @@ -1060,6 +1235,7 @@ void ThumbnailView::filterItems (const boost::function<bool (const ThumbnailView } } + mpStartSelRange = bHasSelRange ? mFilteredItemList.begin() + nSelPos : mFilteredItemList.end(); CalculateItemPositions(); Invalidate(); commit 86ba7698e6a117967daec23f9580469943f8afda Author: Rafael Dominguez <[email protected]> Date: Sat Mar 30 17:26:03 2013 -0430 Avoid generating filter list several times. - Only generate the list after applying a new filter function. - Append item directly to the filtered list if its allowed when appending a new item to the thumbnailview. Change-Id: I804533e2a1751abb0cbc3082093aef2cb9093fb0 diff --git a/sfx2/inc/sfx2/thumbnailview.hxx b/sfx2/inc/sfx2/thumbnailview.hxx index 5287605..dbab91c 100644 --- a/sfx2/inc/sfx2/thumbnailview.hxx +++ b/sfx2/inc/sfx2/thumbnailview.hxx @@ -179,6 +179,8 @@ public: virtual ~ThumbnailView (); + void AppendItem (ThumbnailViewItem *pItem); + void RemoveItem( sal_uInt16 nItemId ); void Clear(); diff --git a/sfx2/source/control/templateabstractview.cxx b/sfx2/source/control/templateabstractview.cxx index aae6328..69be29d 100644 --- a/sfx2/source/control/templateabstractview.cxx +++ b/sfx2/source/control/templateabstractview.cxx @@ -162,7 +162,7 @@ void TemplateAbstractView::insertItem(const TemplateItemProperties &rTemplate) pChild->setSelectClickHdl(LINK(this,ThumbnailView,OnItemSelected)); - mItemList.push_back(pChild); + AppendItem(pChild); CalculateItemPositions(); Invalidate(); diff --git a/sfx2/source/control/templatelocalview.cxx b/sfx2/source/control/templatelocalview.cxx index 1f867ea..9ceb128 100644 --- a/sfx2/source/control/templatelocalview.cxx +++ b/sfx2/source/control/templatelocalview.cxx @@ -262,7 +262,7 @@ sal_uInt16 TemplateLocalView::createRegion(const OUString &rName) pItem->maTitle = aRegionName; pItem->setSelectClickHdl(LINK(this,ThumbnailView,OnItemSelected)); - mItemList.push_back(pItem); + AppendItem(pItem); CalculateItemPositions(); Invalidate(); diff --git a/sfx2/source/control/templatesearchview.cxx b/sfx2/source/control/templatesearchview.cxx index eaec8dc..c24c567 100644 --- a/sfx2/source/control/templatesearchview.cxx +++ b/sfx2/source/control/templatesearchview.cxx @@ -36,7 +36,7 @@ void TemplateSearchView::AppendItem(sal_uInt16 nAssocItemId, sal_uInt16 nRegionI pItem->setPath(rPath); pItem->setSelectClickHdl(LINK(this,ThumbnailView,OnItemSelected)); - mItemList.push_back(pItem); + ThumbnailView::AppendItem(pItem); CalculateItemPositions(); } diff --git a/sfx2/source/control/thumbnailview.cxx b/sfx2/source/control/thumbnailview.cxx index 488a50d..9203078 100644 --- a/sfx2/source/control/thumbnailview.cxx +++ b/sfx2/source/control/thumbnailview.cxx @@ -81,6 +81,14 @@ ThumbnailView::~ThumbnailView() ImplDeleteItems(); } +void ThumbnailView::AppendItem(ThumbnailViewItem *pItem) +{ + if (maFilterFunc(pItem)) + mFilteredItemList.push_back(pItem); + + mItemList.push_back(pItem); +} + void ThumbnailView::ImplInit() { mpScrBar = NULL; @@ -220,12 +228,10 @@ void ThumbnailView::CalculateItemPositions () return; Size aWinSize = GetOutputSizePixel(); - size_t nItemCount = mItemList.size(); + size_t nItemCount = mFilteredItemList.size(); WinBits nStyle = GetStyle(); ScrollBar* pDelScrBar = NULL; - mFilteredItemList.clear(); - // consider the scrolling if ( nStyle & WB_VSCROLL ) ImplInitScrollBar(); @@ -300,59 +306,35 @@ void ThumbnailView::CalculateItemPositions () size_t nCurCount = 0; for ( size_t i = 0; i < nItemCount; i++ ) { - ThumbnailViewItem *const pItem = mItemList[i]; + ThumbnailViewItem *const pItem = mFilteredItemList[i]; - if (maFilterFunc(pItem)) + if ((nCurCount >= nFirstItem) && (nCurCount < nLastItem)) { - mFilteredItemList.push_back(pItem); - if ((nCurCount >= nFirstItem) && (nCurCount < nLastItem)) + if( !pItem->isVisible()) { - if( !pItem->isVisible()) + if ( ImplHasAccessibleListeners() ) { - if ( ImplHasAccessibleListeners() ) - { - ::com::sun::star::uno::Any aOldAny, aNewAny; - - aNewAny <<= pItem->GetAccessible( mbIsTransientChildrenDisabled ); - ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny ); - } - - pItem->show(true); + ::com::sun::star::uno::Any aOldAny, aNewAny; - maItemStateHdl.Call(pItem); + aNewAny <<= pItem->GetAccessible( mbIsTransientChildrenDisabled ); + ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny ); } - pItem->setDrawArea(Rectangle( Point(x,y), Size(mnItemWidth, mnItemHeight) )); - pItem->calculateItemsPosition(mnThumbnailHeight,mnDisplayHeight,mnItemPadding,mpItemAttrs->nMaxTextLenght,mpItemAttrs); + pItem->show(true); - if ( !((nCurCount+1) % mnCols) ) - { - x = nStartX; - y += mnItemHeight+nVItemSpace; - } - else - x += mnItemWidth+nHItemSpace; + maItemStateHdl.Call(pItem); } - else - { - if( pItem->isVisible()) - { - if ( ImplHasAccessibleListeners() ) - { - ::com::sun::star::uno::Any aOldAny, aNewAny; - aOldAny <<= pItem->GetAccessible( mbIsTransientChildrenDisabled ); - ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny ); - } - - pItem->show(false); - - maItemStateHdl.Call(pItem); - } + pItem->setDrawArea(Rectangle( Point(x,y), Size(mnItemWidth, mnItemHeight) )); + pItem->calculateItemsPosition(mnThumbnailHeight,mnDisplayHeight,mnItemPadding,mpItemAttrs->nMaxTextLenght,mpItemAttrs); + if ( !((nCurCount+1) % mnCols) ) + { + x = nStartX; + y += mnItemHeight+nVItemSpace; } - - ++nCurCount; + else + x += mnItemWidth+nHItemSpace; } else { @@ -370,7 +352,10 @@ void ThumbnailView::CalculateItemPositions () maItemStateHdl.Call(pItem); } + } + + ++nCurCount; } // arrange ScrollBar, set values and show it @@ -866,9 +851,7 @@ void ThumbnailView::updateItems (const std::vector<ThumbnailViewItem*> &items) mItemList = items; - CalculateItemPositions(); - - Invalidate(); + filterItems(maFilterFunc); } size_t ThumbnailView::GetItemPos( sal_uInt16 nItemId ) const @@ -1048,6 +1031,34 @@ void ThumbnailView::filterItems (const boost::function<bool (const ThumbnailView { mnFirstLine = 0; // start at the top of the list instead of the current position maFilterFunc = func; + mFilteredItemList.clear(); + + for (size_t i = 0, n = mItemList.size(); i < n; ++i) + { + ThumbnailViewItem *const pItem = mItemList[i]; + + if (maFilterFunc(pItem)) + { + mFilteredItemList.push_back(pItem); + } + else + { + if( pItem->isVisible()) + { + if ( ImplHasAccessibleListeners() ) + { + ::com::sun::star::uno::Any aOldAny, aNewAny; + + aOldAny <<= pItem->GetAccessible( mbIsTransientChildrenDisabled ); + ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny ); + } + + pItem->show(false); + + maItemStateHdl.Call(pItem); + } + } + } CalculateItemPositions(); commit 4e4119b2d338b607adff338be01d33d62f3e45f4 Author: Rafael Dominguez <[email protected]> Date: Sat Mar 30 13:28:44 2013 -0430 Dont show import action while in save mode. Change-Id: If6cca322203bf019a732ce6b0b5a9a20bd932557 diff --git a/sfx2/source/doc/templatedlg.cxx b/sfx2/source/doc/templatedlg.cxx index 7ff9159..b53aee3 100644 --- a/sfx2/source/doc/templatedlg.cxx +++ b/sfx2/source/doc/templatedlg.cxx @@ -721,7 +721,9 @@ IMPL_LINK_NOARG(SfxTemplateManagerDlg, OpenRegionHdl) maSelTemplates.clear(); mpViewBar->ShowItem(TBI_TEMPLATE_FOLDER_NEW,mpCurView->isNestedRegionAllowed()); - mpViewBar->ShowItem(TBI_TEMPLATE_IMPORT,mpCurView->isImportAllowed()); + + if (!mbIsSaveMode) + mpViewBar->ShowItem(TBI_TEMPLATE_IMPORT,mpCurView->isImportAllowed()); mpTemplateBar->Hide(); mpViewBar->Show(); _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
