diff options
author | Szymon Kłos <eszkadev@gmail.com> | 2016-02-16 16:03:30 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2016-03-09 16:42:54 +0000 |
commit | 5813660e7bfe128ac076e592fe31de64a6863780 (patch) | |
tree | c61a2a0ac0f8b5420ee0e53260423b5b812c4eed | |
parent | 1de73e4ddfff3a67c9470e8434c2bb2cb3f43dd5 (diff) |
icon view for RemoteFilesDialog
New view type can be accessed in:
Start Center > Remote Files > Icon View
Cloud service for testing purposes:
1. Start Center > Remote Files > Add service
2. Set type to: Alfresco 4
3. Set host to: http://cmis.alfresco.com/cmisatom
4. Click refresh icon and enter login:admin pass:admin
5. Click OK and open this service
Change-Id: I3d4674bb84d1df1b678111adffe2f835d2bb2356
Reviewed-on: https://gerrit.libreoffice.org/22437
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r-- | fpicker/source/office/RemoteFilesDialog.cxx | 17 | ||||
-rw-r--r-- | fpicker/source/office/RemoteFilesDialog.hxx | 6 | ||||
-rw-r--r-- | fpicker/uiconfig/ui/remotefilesdialog.ui | 32 | ||||
-rw-r--r-- | include/svtools/fileview.hxx | 8 | ||||
-rw-r--r-- | include/svtools/iconview.hxx | 42 | ||||
-rw-r--r-- | include/svtools/treelistbox.hxx | 14 | ||||
-rw-r--r-- | svtools/Library_svt.mk | 2 | ||||
-rw-r--r-- | svtools/source/contnr/fileview.cxx | 99 | ||||
-rw-r--r-- | svtools/source/contnr/iconview.cxx | 239 | ||||
-rw-r--r-- | svtools/source/contnr/iconviewimpl.cxx | 676 | ||||
-rw-r--r-- | svtools/source/contnr/svimpbox.cxx | 17 | ||||
-rw-r--r-- | svtools/source/contnr/svlbitm.cxx | 8 | ||||
-rw-r--r-- | svtools/source/contnr/treelistbox.cxx | 10 | ||||
-rw-r--r-- | svtools/source/inc/iconviewimpl.hxx | 69 | ||||
-rw-r--r-- | svtools/source/inc/svimpbox.hxx | 100 |
15 files changed, 1258 insertions, 81 deletions
diff --git a/fpicker/source/office/RemoteFilesDialog.cxx b/fpicker/source/office/RemoteFilesDialog.cxx index cf012952baa2..1bc4fc18b0c4 100644 --- a/fpicker/source/office/RemoteFilesDialog.cxx +++ b/fpicker/source/office/RemoteFilesDialog.cxx @@ -186,6 +186,8 @@ RemoteFilesDialog::RemoteFilesDialog( vcl::Window* pParent, WinBits nBits ) get( m_pServices_lb, "services_lb" ); get( m_pFilter_lb, "filter_lb" ); get( m_pNewFolder, "new_folder" ); + get( m_pListView_btn, "list_view" ); + get( m_pIconView_btn, "icon_view" ); m_eMode = ( nBits & WB_SAVEAS ) ? REMOTEDLG_MODE_SAVE : REMOTEDLG_MODE_OPEN; m_eType = ( nBits & WB_PATH ) ? REMOTEDLG_TYPE_PATHDLG : REMOTEDLG_TYPE_FILEDLG; @@ -216,6 +218,9 @@ RemoteFilesDialog::RemoteFilesDialog( vcl::Window* pParent, WinBits nBits ) m_pNewFolder->SetClickHdl( LINK( this, RemoteFilesDialog, NewFolderHdl ) ); } + m_pIconView_btn->SetClickHdl( LINK( this, RemoteFilesDialog, IconViewHdl ) ); + m_pListView_btn->SetClickHdl( LINK( this, RemoteFilesDialog, ListViewHdl ) ); + m_pOk_btn->Show(); m_pOk_btn->Enable( false ); @@ -347,6 +352,8 @@ void RemoteFilesDialog::dispose() m_pFilter_lb.clear(); m_pName_ed.disposeAndClear(); m_pNewFolder.clear(); + m_pIconView_btn.clear(); + m_pListView_btn.clear(); ModalDialog::dispose(); } @@ -720,6 +727,16 @@ void RemoteFilesDialog::SavePassword( const OUString& rURL, const OUString& rUse {} } +IMPL_LINK_NOARG_TYPED ( RemoteFilesDialog, IconViewHdl, Button*, void ) +{ + m_pFileView->SetViewMode( eIcon ); +} + +IMPL_LINK_NOARG_TYPED ( RemoteFilesDialog, ListViewHdl, Button*, void ) +{ + m_pFileView->SetViewMode( eDetailedList ); +} + IMPL_LINK_NOARG_TYPED ( RemoteFilesDialog, AddServiceHdl, Button*, void ) { ScopedVclPtrInstance< PlaceEditDialog > aDlg( this ); diff --git a/fpicker/source/office/RemoteFilesDialog.hxx b/fpicker/source/office/RemoteFilesDialog.hxx index b05399d5e1a6..4bc7a7389e40 100644 --- a/fpicker/source/office/RemoteFilesDialog.hxx +++ b/fpicker/source/office/RemoteFilesDialog.hxx @@ -153,7 +153,9 @@ private: VclPtr< MenuButton > m_pAddService_btn; VclPtr< ListBox > m_pServices_lb; VclPtr< Breadcrumb > m_pPath; - VclPtr<PushButton> m_pNewFolder; + VclPtr< PushButton > m_pNewFolder; + VclPtr< PushButton > m_pListView_btn; + VclPtr< PushButton > m_pIconView_btn; VclPtr< Splitter > m_pSplitter; VclPtr< FolderTree > m_pTreeView; VclPtr< SvtFileView > m_pFileView; @@ -203,6 +205,8 @@ private: DECL_LINK_TYPED( SelectBreadcrumbHdl, Breadcrumb *, void ); DECL_LINK_TYPED( NewFolderHdl, Button*, void ); + DECL_LINK_TYPED( IconViewHdl, Button*, void ); + DECL_LINK_TYPED( ListViewHdl, Button*, void ); DECL_LINK_TYPED( OkHdl, Button*, void ); DECL_LINK_TYPED( CancelHdl, Button*, void ); diff --git a/fpicker/uiconfig/ui/remotefilesdialog.ui b/fpicker/uiconfig/ui/remotefilesdialog.ui index 00e14da9cd02..16f87d68fe7f 100644 --- a/fpicker/uiconfig/ui/remotefilesdialog.ui +++ b/fpicker/uiconfig/ui/remotefilesdialog.ui @@ -159,6 +159,32 @@ </packing> </child> <child> + <object class="GtkButton" id="list_view"> + <property name="label" translatable="yes">List view</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="icon_view"> + <property name="label" translatable="yes">Icon view</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + <child> <object class="GtkButton" id="new_folder"> <property name="use_action_appearance">False</property> <property name="width_request">25</property> @@ -174,7 +200,7 @@ <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">1</property> + <property name="position">3</property> </packing> </child> </object> @@ -213,8 +239,8 @@ <object class="GtkLabel" id="filterLabel"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="xalign">0</property> <property name="label" translatable="yes">Filter</property> + <property name="xalign">0</property> </object> <packing> <property name="left_attach">0</property> @@ -225,8 +251,8 @@ <object class="GtkLabel" id="nameLabel"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="xalign">0</property> <property name="label" translatable="yes">File name</property> + <property name="xalign">0</property> </object> <packing> <property name="left_attach">0</property> diff --git a/include/svtools/fileview.hxx b/include/svtools/fileview.hxx index fb36255e2be5..eb570cef88ef 100644 --- a/include/svtools/fileview.hxx +++ b/include/svtools/fileview.hxx @@ -48,6 +48,12 @@ enum FileViewResult eStillRunning }; +enum FileViewMode +{ + eDetailedList, + eIcon +}; + /// describes parameters for doing an action on the FileView asynchronously struct FileViewAsyncAction { @@ -81,6 +87,8 @@ public: virtual Size GetOptimalSize() const override; + void SetViewMode( FileViewMode eMode ); + const OUString& GetViewURL() const; static OUString GetURL( SvTreeListEntry* pEntry ); OUString GetCurrentURL() const; diff --git a/include/svtools/iconview.hxx b/include/svtools/iconview.hxx new file mode 100644 index 000000000000..28dc92255c02 --- /dev/null +++ b/include/svtools/iconview.hxx @@ -0,0 +1,42 @@ +/* -*- 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_SVTOOLS_ICONVIEW_HXX +#define INCLUDED_SVTOOLS_ICONVIEW_HXX + +#include <svtools/svtdllapi.h> +#include <svtools/treelistbox.hxx> + +class IconView : public SvTreeListBox +{ +public: + IconView( vcl::Window* pParent, WinBits nBits ); + + virtual void Resize() SAL_OVERRIDE; + + virtual Rectangle GetFocusRect( SvTreeListEntry*, long nEntryPos ) SAL_OVERRIDE; + + void ClearAll(); + + void PaintEntry( SvTreeListEntry&, long nX, long nY, vcl::RenderContext& rRenderContext); +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/svtools/treelistbox.hxx b/include/svtools/treelistbox.hxx index 4671cadf8f3f..5e75a2f53fae 100644 --- a/include/svtools/treelistbox.hxx +++ b/include/svtools/treelistbox.hxx @@ -228,10 +228,10 @@ class SVT_DLLPUBLIC SvTreeListBox ,public vcl::ISearchableStringList { friend class SvImpLBox; + friend class IconViewImpl; friend class TreeControlPeer; SvTreeListBoxImpl* mpImpl; - SvImpLBox* pImp; Link<SvTreeListBox*,void> aCheckButtonHdl; Link<SvTreeListBox*,void> aScrolledHdl; Link<SvTreeListBox*,void> aExpandedHdl; @@ -245,7 +245,6 @@ class SVT_DLLPUBLIC SvTreeListBox Image aCurInsertedColBmp; short nContextBmpWidthMax; - short nEntryHeight; short nEntryHeightOffs; short nIndent; short nFocusWidth; @@ -269,6 +268,12 @@ class SVT_DLLPUBLIC SvTreeListBox SvLBoxItem* pEdItem; protected: + SvImpLBox* pImp; + short nColumns; + short nEntryHeight; + short nEntryWidth; + bool mbCenterAndClipText; + Link<SvTreeListBox*,bool> aDoubleClickHdl; SvTreeListEntry* pTargetEntry; SvLBoxButtonData* pCheckButtonData; @@ -443,6 +448,8 @@ public: void EnableEntryMnemonics(); bool IsEntryMnemonicsEnabled() const; + bool TextCenterAndClipEnabled() const { return mbCenterAndClipText; } + /** Handles the given key event. At the moment this merely checks for accelerator keys, if entry mnemonics @@ -710,8 +717,11 @@ public: void ShowTargetEmphasis( SvTreeListEntry*, bool bShow ); void ScrollOutputArea( short nDeltaEntries ); + short GetColumnsCount() const { return nColumns; } short GetEntryHeight() const { return nEntryHeight; } void SetEntryHeight( short nHeight ); + short GetEntryWidth() const { return nEntryWidth; } + void SetEntryWidth( short nWidth ); Size GetOutputSizePixel() const; short GetIndent() const { return nIndent; } void SetIndent( short nIndent ); diff --git a/svtools/Library_svt.mk b/svtools/Library_svt.mk index 363af255df14..fd85c9d53ee6 100644 --- a/svtools/Library_svt.mk +++ b/svtools/Library_svt.mk @@ -93,6 +93,8 @@ $(eval $(call gb_Library_add_exception_objects,svt,\ svtools/source/contnr/contentenumeration \ svtools/source/contnr/fileview \ svtools/source/contnr/foldertree \ + svtools/source/contnr/iconview \ + svtools/source/contnr/iconviewimpl \ svtools/source/contnr/imivctl1 \ svtools/source/contnr/imivctl2 \ svtools/source/contnr/ivctrl \ diff --git a/svtools/source/contnr/fileview.cxx b/svtools/source/contnr/fileview.cxx index a28135884180..8f8596aeef6a 100644 --- a/svtools/source/contnr/fileview.cxx +++ b/svtools/source/contnr/fileview.cxx @@ -17,6 +17,8 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <svtools/treelistbox.hxx> +#include <svtools/iconview.hxx> #include "fileview.hxx" #include <sal/config.h> #include <svtools/treelistentry.hxx> @@ -322,13 +324,17 @@ protected: bool m_bRunningAsyncAction; bool m_bAsyncActionCancelled; + FileViewMode m_eViewMode; + public: ::std::vector< SortingData_Impl* > maContent; ::osl::Mutex maMutex; + SvTreeListBox* mpCurView; VclPtr<ViewTabListBox_Impl> mpView; + VclPtr<IconView> mpIconView; NameTranslator_Impl* mpNameTrans; sal_uInt16 mnSortColumn; bool mbAscending : 1; @@ -378,6 +384,8 @@ public: sal_uLong GetEntryPos( const OUString& rURL ); + void SetViewMode( FileViewMode eMode ); + inline void EnableDelete( bool bEnable ); void Resort_Impl( sal_Int16 nColumn, bool bAscending ); @@ -413,8 +421,8 @@ inline void SvtFileView_Impl::EnableDelete( bool bEnable ) inline void SvtFileView_Impl::EndEditing( bool _bCancel ) { - if ( mpView->IsEditingActive() ) - mpView->EndEditing(_bCancel); + if ( mpCurView->IsEditingActive() ) + mpCurView->EndEditing(_bCancel); } // functions ------------------------------------------------------------- @@ -1012,6 +1020,11 @@ Size SvtFileView::GetOptimalSize() const return LogicToPixel(Size(208, 50), MAP_APPFONT); } +void SvtFileView::SetViewMode( FileViewMode eMode ) +{ + mpImp->SetViewMode( eMode ); +} + OUString SvtFileView::GetURL( SvTreeListEntry* pEntry ) { OUString aURL; @@ -1024,7 +1037,7 @@ OUString SvtFileView::GetURL( SvTreeListEntry* pEntry ) OUString SvtFileView::GetCurrentURL() const { OUString aURL; - SvTreeListEntry* pEntry = mpImp->mpView->FirstSelected(); + SvTreeListEntry* pEntry = mpImp->mpCurView->FirstSelected(); if ( pEntry && pEntry->GetUserData() ) aURL = static_cast<SvtContentEntry*>(pEntry->GetUserData())->maURL; return aURL; @@ -1034,10 +1047,16 @@ OUString SvtFileView::GetCurrentURL() const void SvtFileView::CreatedFolder( const OUString& rUrl, const OUString& rNewFolder ) { OUString sEntry = mpImp->FolderInserted( rUrl, rNewFolder ); + SvTreeListEntry* pEntry = mpImp->mpView->InsertEntry( sEntry, mpImp->maFolderImage, mpImp->maFolderImage ); SvtContentEntry* pUserData = new SvtContentEntry( rUrl, true ); pEntry->SetUserData( pUserData ); mpImp->mpView->MakeVisible( pEntry ); + + SvTreeListEntry* pEntry2 = mpImp->mpIconView->InsertEntry( sEntry.getToken( 0, '\t' ), mpImp->maFolderImage, mpImp->maFolderImage ); + SvtContentEntry* pUserData2 = new SvtContentEntry( rUrl, true ); + pEntry2->SetUserData( pUserData2 ); + mpImp->mpIconView->MakeVisible( pEntry2 ); } @@ -1096,6 +1115,7 @@ void SvtFileView::SetSizePixel( const Size& rNewSize ) { Control::SetSizePixel( rNewSize ); mpImp->mpView->SetSizePixel( rNewSize ); + mpImp->mpIconView->SetSizePixel( rNewSize ); } @@ -1175,15 +1195,15 @@ void SvtFileView::CancelRunningAsyncAction() void SvtFileView::SetNoSelection() { - mpImp->mpView->SelectAll( false ); + mpImp->mpCurView->SelectAll( false ); } void SvtFileView::GetFocus() { Control::GetFocus(); - if ( mpImp && mpImp->mpView ) - mpImp->mpView->GrabFocus(); + if ( mpImp && mpImp->mpCurView ) + mpImp->mpCurView->GrabFocus(); } @@ -1196,24 +1216,25 @@ void SvtFileView::SetSelectHdl( const Link<SvTreeListBox*,void>& rHdl ) void SvtFileView::SetDoubleClickHdl( const Link<SvTreeListBox*,bool>& rHdl ) { mpImp->mpView->SetDoubleClickHdl( rHdl ); + mpImp->mpIconView->SetDoubleClickHdl( rHdl ); } sal_uLong SvtFileView::GetSelectionCount() const { - return mpImp->mpView->GetSelectionCount(); + return mpImp->mpCurView->GetSelectionCount(); } SvTreeListEntry* SvtFileView::FirstSelected() const { - return mpImp->mpView->FirstSelected(); + return mpImp->mpCurView->FirstSelected(); } SvTreeListEntry* SvtFileView::NextSelected( SvTreeListEntry* pEntry ) const { - return mpImp->mpView->NextSelected( pEntry ); + return mpImp->mpCurView->NextSelected( pEntry ); } void SvtFileView::EnableAutoResize() @@ -1443,6 +1464,7 @@ SvtFileView_Impl::SvtFileView_Impl( SvtFileView* pAntiImpl, Reference < XCommand ,m_eAsyncActionResult ( ::svt::ERROR ) ,m_bRunningAsyncAction ( false ) ,m_bAsyncActionCancelled ( false ) + ,m_eViewMode ( eDetailedList ) ,mpNameTrans ( nullptr ) ,mnSortColumn ( COLUMN_TITLE ) ,mbAscending ( true ) @@ -1457,6 +1479,9 @@ SvtFileView_Impl::SvtFileView_Impl( SvtFileView* pAntiImpl, Reference < XCommand { maAllFilter = "*.*"; mpView = VclPtr<ViewTabListBox_Impl>::Create( mpAntiImpl, this, nFlags ); + mpCurView = mpView; + mpIconView = VclPtr<IconView>::Create( mpAntiImpl, WB_TABSTOP ); + mpIconView->Hide(); mpView->EnableCellFocus(); } @@ -1465,6 +1490,7 @@ SvtFileView_Impl::~SvtFileView_Impl() { Clear(); mpView.disposeAndClear(); + mpIconView.disposeAndClear(); } @@ -1583,6 +1609,7 @@ FileViewResult SvtFileView_Impl::GetFolderContent_Impl( m_aCurrentAsyncActionHandler = pAsyncDescriptor->aFinishHandler; DBG_ASSERT( m_aCurrentAsyncActionHandler.IsSet(), "SvtFileView_Impl::GetFolderContent_Impl: nobody interested when it's finished?" ); mpView->ClearAll(); + mpIconView->ClearAll(); return eStillRunning; } @@ -1708,15 +1735,16 @@ void SvtFileView_Impl::SetSelectHandler( const Link<SvTreeListBox*,void>& _rHdl aMasterHandler = LINK( this, SvtFileView_Impl, SelectionMultiplexer ); mpView->SetSelectHdl( aMasterHandler ); + mpIconView->SetSelectHdl( aMasterHandler ); } void SvtFileView_Impl::InitSelection() { - mpView->SelectAll( false ); - SvTreeListEntry* pFirst = mpView->First(); + mpCurView->SelectAll( false ); + SvTreeListEntry* pFirst = mpCurView->First(); if ( pFirst ) - mpView->SetCursor( pFirst, true ); + mpCurView->SetCursor( pFirst, true ); } @@ -1725,7 +1753,9 @@ void SvtFileView_Impl::OpenFolder_Impl() ::osl::MutexGuard aGuard( maMutex ); mpView->SetUpdateMode( false ); + mpIconView->SetUpdateMode( false ); mpView->ClearAll(); + mpIconView->ClearAll(); std::vector< SortingData_Impl* >::iterator aIt; @@ -1739,15 +1769,23 @@ void SvtFileView_Impl::OpenFolder_Impl() (*aIt)->maImage, (*aIt)->maImage ); + SvTreeListEntry* pEntry2 = mpIconView->InsertEntry( (*aIt)->maDisplayText.getToken( 0, '\t' ), + (*aIt)->maImage, (*aIt)->maImage ); + SvtContentEntry* pUserData = new SvtContentEntry( (*aIt)->maTargetURL, (*aIt)->mbIsFolder ); + SvtContentEntry* pUserData2 = new SvtContentEntry( (*aIt)->maTargetURL, + (*aIt)->mbIsFolder ); + pEntry->SetUserData( pUserData ); + pEntry2->SetUserData( pUserData2 ); } InitSelection(); ++mnSuspendSelectCallback; mpView->SetUpdateMode( true ); + mpIconView->SetUpdateMode( true ); --mnSuspendSelectCallback; ResetCursor(); @@ -1757,12 +1795,12 @@ void SvtFileView_Impl::OpenFolder_Impl() void SvtFileView_Impl::ResetCursor() { // deselect - SvTreeListEntry* pEntry = mpView->FirstSelected(); + SvTreeListEntry* pEntry = mpCurView->FirstSelected(); if ( pEntry ) - mpView->Select( pEntry, false ); + mpCurView->Select( pEntry, false ); // set cursor to the first entry - mpView->SetCursor( mpView->First(), true ); - mpView->Update(); + mpCurView->SetCursor( mpCurView->First(), true ); + mpCurView->Update(); } @@ -1901,6 +1939,7 @@ void SvtFileView_Impl::CreateDisplayText_Impl() void SvtFileView_Impl::Resort_Impl( sal_Int16 nColumn, bool bAscending ) { + // TODO: IconView () ::osl::MutexGuard aGuard( maMutex ); if ( ( nColumn == mnSortColumn ) && @@ -2146,6 +2185,34 @@ sal_uLong SvtFileView_Impl::GetEntryPos( const OUString& rURL ) } +void SvtFileView_Impl::SetViewMode( FileViewMode eMode ) +{ + m_eViewMode = eMode; + switch ( eMode ) + { + case eDetailedList: + mpCurView = mpView; + mpView->Show(); + mpView->GetHeaderBar()->Show(); + mpIconView->Hide(); + break; + + case eIcon: + mpCurView = mpIconView; + mpView->Hide(); + mpView->GetHeaderBar()->Hide(); + mpIconView->Show(); + break; + + default: + mpCurView = mpView; + mpView->Show(); + mpView->GetHeaderBar()->Show(); + mpIconView->Hide(); + }; +} + + bool SvtFileView_Impl::SearchNextEntry( sal_uInt32& nIndex, const OUString& rTitle, bool bWrapAround ) { ::osl::MutexGuard aGuard( maMutex ); diff --git a/svtools/source/contnr/iconview.cxx b/svtools/source/contnr/iconview.cxx new file mode 100644 index 000000000000..b50f9e41cf73 --- /dev/null +++ b/svtools/source/contnr/iconview.cxx @@ -0,0 +1,239 @@ +/* -*- 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 <svtools/iconview.hxx> +#include <svtools/treelistentry.hxx> +#include <svtools/fileview.hxx> +#include "iconviewimpl.hxx" + +IconView::IconView( vcl::Window* pParent, WinBits nBits ) +: SvTreeListBox( pParent, nBits ) +{ + nColumns = 1; + mbCenterAndClipText = true; + SetEntryHeight( 100 ); + SetEntryWidth( 100 ); + + if(pImp) + delete pImp; + + pImp = new IconViewImpl( this, GetModel(), GetStyle() ); +} + +void IconView::Resize() +{ + Size aBoxSize = Control::GetParent()->GetOutputSizePixel(); + + if ( !aBoxSize.Width() ) + return; + + SetSizePixel( aBoxSize ); + + nColumns = aBoxSize.Width() / nEntryWidth; + + SvTreeListBox::Resize(); +} + +Rectangle IconView::GetFocusRect( SvTreeListEntry*, long nEntryPos ) +{ + Size aSize; + aSize.Height() = nEntryHeight; + aSize.Width() = nEntryWidth; + + Point aPos; + aPos.X() = 0; + aPos.Y() = 0; + + Rectangle aRect; + + short nCols = GetColumnsCount(); + + if(nCols) + { + aPos.Y() = ( nEntryPos / nCols ) * nEntryHeight; + aPos.X() = ( nEntryPos % nCols ) * nEntryWidth; + } + + aRect.SetPos( aPos ); + aRect.SetSize( aSize ); + + return aRect; +} + +void IconView::ClearAll() +{ + for ( sal_uLong i = 0; i < GetEntryCount(); ++i ) + delete static_cast<SvtContentEntry*>(GetEntry(i)->GetUserData()); + + Clear(); +} + +void IconView::PaintEntry(SvTreeListEntry& rEntry, long nX, long nY, + vcl::RenderContext& rRenderContext) +{ + + Rectangle aRect; // multi purpose + + PreparePaint(rRenderContext, rEntry); + + pImp->UpdateContextBmpWidthMax(&rEntry); + + short nTempEntryHeight = GetEntryHeight(); + short nTempEntryWidth = GetEntryWidth(); + + Point aEntryPos; + + Color aBackupTextColor(rRenderContext.GetTextColor()); + vcl::Font aBackupFont(rRenderContext.GetFont()); + Color aBackupColor = rRenderContext.GetFillColor(); + + bool bCurFontIsSel = false; + bool bInUse = rEntry.HasInUseEmphasis(); + const WinBits nWindowStyle = GetStyle(); + const bool bHideSelection = (nWindowStyle & WB_HIDESELECTION) !=0 && !HasFocus(); + const StyleSettings& rSettings = rRenderContext.GetSettings().GetStyleSettings(); + + vcl::Font aHighlightFont(rRenderContext.GetFont()); + const Color aHighlightTextColor(rSettings.GetHighlightTextColor()); + aHighlightFont.SetColor(aHighlightTextColor); + + Size aRectSize(nTempEntryWidth, nTempEntryHeight); + + SvViewDataEntry* pViewDataEntry = GetViewDataEntry( &rEntry ); + + sal_uInt16 nItemCount = rEntry.ItemCount(); + sal_uInt16 nCurItem = 0; + sal_uInt16 nIconItem = nItemCount; + + while (nCurItem < nItemCount) + { + SvLBoxItem* pItem = nCurItem < nItemCount ? &rEntry.GetItem(nCurItem) : nullptr; + sal_uInt16 nItemType = pItem->GetType(); + + if(nItemType == SV_ITEM_ID_LBOXCONTEXTBMP) + { + nIconItem = nCurItem; + nCurItem++; + continue; + } + + Size aSize(SvLBoxItem::GetSize(pViewDataEntry, nCurItem)); + + aEntryPos.X() = nX; + aEntryPos.Y() = nY; + + // set background pattern/color + + Wallpaper aWallpaper = rRenderContext.GetBackground(); + + if (pViewDataEntry->IsHighlighted() && !pViewDataEntry->IsCursored()) + { + Color aNewWallColor = rSettings.GetHighlightColor(); + if (!bInUse) + { + // if the face color is bright then the deactive color is also bright + // -> so you can't see any deactive selection + if (bHideSelection && !rSettings.GetFaceColor().IsBright() + && aWallpaper.GetColor().IsBright() != rSettings.GetDeactiveColor().IsBright()) + { + aNewWallColor = rSettings.GetDeactiveColor(); + } + // set font color to highlight + if (!bCurFontIsSel) + { + rRenderContext.SetTextColor(aHighlightTextColor); + rRenderContext.SetFont(aHighlightFont); + bCurFontIsSel = true; + } + } + aWallpaper.SetColor(aNewWallColor); + } + else // no selection + { + if (bCurFontIsSel) + { + bCurFontIsSel = false; + rRenderContext.SetTextColor(aBackupTextColor); + rRenderContext.SetFont(aBackupFont); + } + else + { + aWallpaper.SetColor(rEntry.GetBackColor()); + } + } + + // draw background + if (!(nTreeFlags & SvTreeFlags::USESEL)) + { + aRect.SetPos(aEntryPos); + aRect.SetSize(aRectSize); + + Color aBackgroundColor = aWallpaper.GetColor(); + if (aBackgroundColor != Color(COL_TRANSPARENT)) + { + rRenderContext.SetFillColor(aBackgroundColor); + // this case may occur for smaller horizontal resizes + if (aRect.Left() < aRect.Right()) + rRenderContext.DrawRect(aRect); + } + } + + // center vertically + aEntryPos.Y() += (nTempEntryHeight - aSize.Height()) / 2; + + // draw item + pViewDataEntry->SetPaintRectangle(aRect); + + aEntryPos.Y() += 15; + + pItem->Paint(aEntryPos, *this, rRenderContext, pViewDataEntry, rEntry); + + rRenderContext.SetFillColor(aBackupColor); + + nCurItem++; + } + + // draw icon + if(nIconItem != nItemCount && nIconItem < nItemCount) + { + Size aSize(SvLBoxItem::GetSize(pViewDataEntry, nIconItem)); + + aEntryPos.X() = nX; + aEntryPos.Y() = nY; + + // center horizontally + aEntryPos.X() += (nTempEntryWidth - aSize.Width()) / 2; + // center vertically + aEntryPos.Y() += (nTempEntryHeight - aSize.Height()) / 2; + + aEntryPos.Y() -= 10; + + SvLBoxItem* pItem = &rEntry.GetItem(nIconItem); + + pItem->Paint(aEntryPos, *this, rRenderContext, pViewDataEntry, rEntry); + } + + if (bCurFontIsSel) + { + rRenderContext.SetTextColor(aBackupTextColor); + rRenderContext.SetFont(aBackupFont); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/contnr/iconviewimpl.cxx b/svtools/source/contnr/iconviewimpl.cxx new file mode 100644 index 000000000000..ca6696ae3b58 --- /dev/null +++ b/svtools/source/contnr/iconviewimpl.cxx @@ -0,0 +1,676 @@ +/* -*- 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 <vcl/svapp.hxx> +#include <svtools/iconview.hxx> +#include <iconviewimpl.hxx> + +IconViewImpl::IconViewImpl( SvTreeListBox* pTreeListBox, SvTreeList* pTreeList, WinBits nWinStyle ) +: SvImpLBox( pTreeListBox, pTreeList, nWinStyle ) +{ +} + +void IconViewImpl::CursorUp() +{ + if (!pStartEntry) + return; + + SvTreeListEntry* pPrevFirstToDraw = pStartEntry; + + for(short i = 0; i < pView->GetColumnsCount() && pPrevFirstToDraw; i++) + pPrevFirstToDraw = pView->PrevVisible(pPrevFirstToDraw); + + if( pPrevFirstToDraw ) + { + nFlags &= (~F_FILLING); + long nEntryHeight = pView->GetEntryHeight(); + ShowCursor( false ); + pView->Update(); + pStartEntry = pPrevFirstToDraw; + Rectangle aArea( GetVisibleArea() ); + aArea.Bottom() -= nEntryHeight; + pView->Scroll( 0, nEntryHeight, aArea, ScrollFlags::NoChildren ); + pView->Update(); + ShowCursor( true ); + pView->NotifyScrolled(); + } +} + +void IconViewImpl::CursorDown() +{ + if (!pStartEntry) + return; + + SvTreeListEntry* pNextFirstToDraw = pStartEntry; + + for(short i = 0; i < pView->GetColumnsCount(); i++) + pNextFirstToDraw = pView->NextVisible(pNextFirstToDraw); + + if( pNextFirstToDraw ) + { + nFlags &= (~F_FILLING); + ShowCursor( false ); + pView->Update(); + pStartEntry = pNextFirstToDraw; + Rectangle aArea( GetVisibleArea() ); + pView->Scroll( 0, -(pView->GetEntryHeight()), aArea, ScrollFlags::NoChildren ); + pView->Update(); + ShowCursor( true ); + pView->NotifyScrolled(); + } +} + +void IconViewImpl::PageDown( sal_uInt16 nDelta ) +{ + sal_uInt16 nRealDelta = nDelta * pView->GetColumnsCount(); + + if( !nDelta ) + return; + + if (!pStartEntry) + return; + + SvTreeListEntry* pNext = pView->NextVisible(pStartEntry, nRealDelta); + if( pNext == pStartEntry ) + return; + + ShowCursor( false ); + + nFlags &= (~F_FILLING); + pView->Update(); + pStartEntry = pNext; + + if( nRealDelta >= nVisibleCount ) + { + pView->Invalidate( GetVisibleArea() ); + pView->Update(); + } + else + { + Rectangle aArea( GetVisibleArea() ); + long nScroll = pView->GetEntryHeight() * static_cast<long>(nRealDelta); + nScroll = -nScroll; + pView->Update(); + pView->Scroll( 0, nScroll, aArea, ScrollFlags::NoChildren ); + pView->Update(); + pView->NotifyScrolled(); + } + + ShowCursor( true ); +} + +void IconViewImpl::PageUp( sal_uInt16 nDelta ) +{ + sal_uInt16 nRealDelta = nDelta * pView->GetColumnsCount(); + if( !nDelta ) + return; + + if (!pStartEntry) + return; + + SvTreeListEntry* pPrev = pView->PrevVisible(pStartEntry, nRealDelta); + if( pPrev == pStartEntry ) + return; + + nFlags &= (~F_FILLING); + ShowCursor( false ); + + pView->Update(); + pStartEntry = pPrev; + if( nRealDelta >= nVisibleCount ) + { + pView->Invalidate( GetVisibleArea() ); + pView->Update(); + } + else + { + long nEntryHeight = pView->GetEntryHeight(); + Rectangle aArea( GetVisibleArea() ); + pView->Update(); + pView->Scroll( 0, nEntryHeight*nRealDelta, aArea, ScrollFlags::NoChildren ); + pView->Update(); + pView->NotifyScrolled(); + } + + ShowCursor( true ); +} + +void IconViewImpl::KeyDown( bool bPageDown ) +{ + if( !aVerSBar->IsVisible() ) + return; + + long nDelta; + if( bPageDown ) + nDelta = aVerSBar->GetPageSize(); + else + nDelta = 1; + + long nThumbPos = aVerSBar->GetThumbPos(); + + if( nDelta <= 0 ) + return; + + nFlags &= (~F_FILLING); + BeginScroll(); + + aVerSBar->SetThumbPos( nThumbPos+nDelta ); + if( bPageDown ) + PageDown( (short)nDelta ); + else + CursorDown(); + + EndScroll(); +} + +void IconViewImpl::KeyUp( bool bPageUp ) +{ + if( !aVerSBar->IsVisible() ) + return; + + long nDelta; + if( bPageUp ) + nDelta = aVerSBar->GetPageSize(); + else + nDelta = 1; + + long nThumbPos = aVerSBar->GetThumbPos(); + + if( nThumbPos < nDelta ) + nDelta = nThumbPos; + + if( nDelta < 0 ) + return; + + nFlags &= (~F_FILLING); + BeginScroll(); + + aVerSBar->SetThumbPos( nThumbPos - nDelta ); + if( bPageUp ) + PageUp( (short)nDelta ); + else + CursorUp(); + + EndScroll(); +} + +long IconViewImpl::GetEntryLine( SvTreeListEntry* pEntry ) const +{ + if(!pStartEntry ) + return -1; // invisible position + + long nFirstVisPos = pView->GetVisiblePos( pStartEntry ); + long nEntryVisPos = pView->GetVisiblePos( pEntry ); + nFirstVisPos = nEntryVisPos - nFirstVisPos; + + return nFirstVisPos; +} + +Point IconViewImpl::GetEntryPosition( SvTreeListEntry* pEntry ) const +{ + const int pos = pView->GetAbsPos( pEntry ); + + return Point( ( pos % pView->GetColumnsCount() ) * pView->GetEntryWidth(), + ( pos / pView->GetColumnsCount() ) * pView->GetEntryHeight() ); +} + +SvTreeListEntry* IconViewImpl::GetClickedEntry( const Point& rPoint ) const +{ + DBG_ASSERT( pView->GetModel(), "IconViewImpl::GetClickedEntry: how can this ever happen?" ); + if ( !pView->GetModel() ) + return nullptr; + if( pView->GetEntryCount() == 0 || !pStartEntry || !pView->GetEntryHeight() || !pView->GetEntryWidth()) + return nullptr; + + sal_uInt16 nY = (sal_uInt16)(rPoint.Y() / pView->GetEntryHeight() ); + sal_uInt16 nX = (sal_uInt16)(rPoint.X() / pView->GetEntryWidth() ); + sal_uInt16 nTemp = nY * pView->GetColumnsCount() + nX; + + SvTreeListEntry* pEntry = pView->NextVisible(pStartEntry, nTemp); + + return pEntry; +} + +bool IconViewImpl::IsEntryInView( SvTreeListEntry* pEntry ) const +{ + // parent collapsed + if( !pView->IsEntryVisible(pEntry) ) + return false; + + long nY = GetEntryLine( pEntry ) / pView->GetColumnsCount() * pView->GetEntryHeight(); + if( nY < 0 ) + return false; + + long nMax = nVisibleCount / pView->GetColumnsCount() * pView->GetEntryHeight(); + if( nY >= nMax ) + return false; + + long nStart = GetEntryLine( pEntry ) - GetEntryLine( pStartEntry ); + if( nStart < 0 ) + return false; + + return true; +} + +void IconViewImpl::AdjustScrollBars( Size& rSize ) +{ + long nEntryHeight = pView->GetEntryHeight(); + if( !nEntryHeight ) + return; + + sal_uInt16 nResult = 0; + + Size aOSize( pView->Control::GetOutputSizePixel() ); + + const WinBits nWindowStyle = pView->GetStyle(); + bool bVerSBar = ( nWindowStyle & WB_VSCROLL ) != 0; + + // number of entries that are not collapsed + sal_uLong nTotalCount = pView->GetVisibleCount(); + + // number of entries visible within the view + nVisibleCount = aOSize.Height() / nEntryHeight * pView->GetColumnsCount(); + + long nRows = ( nTotalCount / pView->GetColumnsCount() ) + 1; + + // do we need a vertical scrollbar? + if( bVerSBar || nTotalCount > nVisibleCount ) + { + nResult = 1; + nFlags |= F_HOR_SBARSIZE_WITH_VBAR; + } + + PositionScrollBars( aOSize, nResult ); + + // adapt Range, VisibleRange etc. + + // refresh output size, in case we have to scroll + Rectangle aRect; + aRect.SetSize( aOSize ); + aSelEng.SetVisibleArea( aRect ); + + // vertical scrollbar + if( !bInVScrollHdl ) + { + aVerSBar->SetPageSize( nTotalCount ); + aVerSBar->SetVisibleSize( nTotalCount - nRows ); + } + else + { + nFlags |= F_ENDSCROLL_SET_VIS_SIZE; + } + + if( nResult & 0x0001 ) + aVerSBar->Show(); + else + aVerSBar->Hide(); + + rSize = aOSize; +} + +// returns 0 if position is just past the last entry +SvTreeListEntry* IconViewImpl::GetEntry( const Point& rPoint ) const +{ + if( (pView->GetEntryCount() == 0) || !pStartEntry || + (rPoint.Y() > aOutputSize.Height()) + || !pView->GetEntryHeight() + || !pView->GetEntryWidth()) + return nullptr; + + sal_uInt16 nClickedEntry = (sal_uInt16)(rPoint.Y() / pView->GetEntryHeight() * pView->GetColumnsCount() + rPoint.X() / pView->GetEntryWidth() ); + sal_uInt16 nTemp = nClickedEntry; + SvTreeListEntry* pEntry = pView->NextVisible(pStartEntry, nTemp); + if( nTemp != nClickedEntry ) + pEntry = nullptr; + return pEntry; +} + +void IconViewImpl::SyncVerThumb() +{ + if( pStartEntry ) + { + long nEntryPos = pView->GetVisiblePos( pStartEntry ); + aVerSBar->SetThumbPos( nEntryPos ); + } + else + aVerSBar->SetThumbPos( 0 ); +} + +void IconViewImpl::UpdateAll( bool bInvalidateCompleteView, + bool bUpdateVerScrollBar ) +{ + if( bUpdateVerScrollBar ) + FindMostRight( nullptr ); + aVerSBar->SetRange( Range( 0, pView->GetVisibleCount() ) ); + SyncVerThumb(); + FillView(); + ShowVerSBar(); + if( bSimpleTravel && pCursor && pView->HasFocus() ) + pView->Select( pCursor ); + ShowCursor( true ); + if( bInvalidateCompleteView ) + pView->Invalidate(); + else + pView->Invalidate( GetVisibleArea() ); +} + +void IconViewImpl::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect) +{ + if (!pView->GetVisibleCount()) + return; + + nFlags |= F_IN_PAINT; + + if (nFlags & F_FILLING) + { + SvTreeListEntry* pFirst = pView->First(); + if (pFirst != pStartEntry) + { + ShowCursor(false); + pStartEntry = pView->First(); + aVerSBar->SetThumbPos( 0 ); + StopUserEvent(); + ShowCursor(true); + nCurUserEvent = Application::PostUserEvent(LINK(this, SvImpLBox, MyUserEvent), + reinterpret_cast<void*>(1)); + return; + } + } + + if (!pStartEntry) + { + pStartEntry = pView->First(); + } + + long nRectHeight = rRect.GetHeight(); + long nRectWidth = rRect.GetWidth(); + long nEntryHeight = pView->GetEntryHeight(); + long nEntryWidth = pView->GetEntryWidth(); + + // calculate area for the entries we want to draw + sal_uInt16 nStartId = static_cast<sal_uInt16>(rRect.Top() / nEntryHeight * pView->GetColumnsCount() + (rRect.Left() / nEntryWidth)); + sal_uInt16 nCount = static_cast<sal_uInt16>(( nRectHeight / nEntryHeight + 1 ) * nRectWidth / nEntryWidth); + nCount += 2; // don't miss an entry + + long nY = nStartId / pView->GetColumnsCount() * nEntryHeight; + long nX = 0; + SvTreeListEntry* pEntry = pStartEntry; + while (nStartId && pEntry) + { + pEntry = pView->NextVisible(pEntry); + nStartId--; + } + + vcl::Region aClipRegion(GetClipRegionRect()); + + if (!pCursor && ((nExtendedWinBits & EWB_NO_AUTO_CURENTRY) == 0)) + { + // do not select if multiselection or explicit set + bool bNotSelect = (aSelEng.GetSelectionMode() == MULTIPLE_SELECTION ) || ((m_nStyle & WB_NOINITIALSELECTION) == WB_NOINITIALSELECTION); + SetCursor(pStartEntry, bNotSelect); + } + + for(sal_uInt16 n = 0; n< nCount && pEntry; n++) + { + static_cast<IconView*>(pView.get())->PaintEntry(*pEntry, nX, nY, rRenderContext); + nX += nEntryWidth; + + if(nX + pView->GetEntryWidth() > nEntryWidth * pView->GetColumnsCount()) + { + nY += nEntryHeight; + nX = 0; + } + pEntry = pView->NextVisible(pEntry); + } + + nFlags &= (~F_DESEL_ALL); + rRenderContext.SetClipRegion(); + if (!(nFlags & F_PAINTED)) + { + nFlags |= F_PAINTED; + } + nFlags &= (~F_IN_PAINT); +} + +void IconViewImpl::InvalidateEntry( long nId ) const +{ + if( !(nFlags & F_IN_PAINT )) + { + Rectangle aRect( GetVisibleArea() ); + long nMaxBottom = aRect.Bottom(); + aRect.Top() = nId / pView->GetColumnsCount() * pView->GetEntryHeight(); + aRect.Bottom() = aRect.Top(); aRect.Bottom() += pView->GetEntryHeight(); + + if( aRect.Top() > nMaxBottom ) + return; + if( aRect.Bottom() > nMaxBottom ) + aRect.Bottom() = nMaxBottom; + pView->Invalidate( aRect ); + } +} + +bool IconViewImpl::KeyInput( const KeyEvent& rKEvt ) +{ + const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode(); + + if( rKeyCode.IsMod2() ) + return false; // don't evaluate Alt key + + nFlags &= (~F_FILLING); + + if( !pCursor ) + pCursor = pStartEntry; + if( !pCursor ) + return false; + + bool bKeyUsed = true; + + sal_uInt16 aCode = rKeyCode.GetCode(); + + bool bShift = rKeyCode.IsShift(); + bool bMod1 = rKeyCode.IsMod1(); + + SvTreeListEntry* pNewCursor; + + bool bHandled = true; + + long i; + long nColumns = pView->GetColumnsCount(); + + switch( aCode ) + { + case KEY_LEFT: + if( !IsEntryInView( pCursor ) ) + MakeVisible( pCursor ); + + pNewCursor = pCursor; + do + { + pNewCursor = pView->PrevVisible(pNewCursor); + } while( pNewCursor && !IsSelectable(pNewCursor) ); + + // if there is no next entry, take the current one + // this ensures that in case of _one_ entry in the list, this entry is selected when pressing + // the cursor key + if ( !pNewCursor && pCursor ) + pNewCursor = pCursor; + + if( pNewCursor ) + { + aSelEng.CursorPosChanging( bShift, bMod1 ); + SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on + if( !IsEntryInView( pNewCursor ) ) + KeyUp( false ); + } + break; + + case KEY_RIGHT: + if( !IsEntryInView( pCursor ) ) + MakeVisible( pCursor ); + + pNewCursor = pCursor; + do + { + pNewCursor = pView->NextVisible(pNewCursor); + } while( pNewCursor && !IsSelectable(pNewCursor) ); + + // if there is no next entry, take the current one + // this ensures that in case of _one_ entry in the list, this entry is selected when pressing + // the cursor key + if ( !pNewCursor && pCursor ) + pNewCursor = pCursor; + + if( pNewCursor ) + { + aSelEng.CursorPosChanging( bShift, bMod1 ); + if( IsEntryInView( pNewCursor ) ) + SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on + else + { + if( pCursor ) + pView->Select( pCursor, false ); + KeyDown( false ); + SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on + } + } + else + KeyDown( false ); // because scrollbar range might still + // allow scrolling + break; + + case KEY_UP: + { + if( !IsEntryInView( pCursor ) ) + MakeVisible( pCursor ); + + pNewCursor = pCursor; + for( i = 0; i < nColumns && pNewCursor; i++) + { + do + { + pNewCursor = pView->PrevVisible(pNewCursor); + } while( pNewCursor && !IsSelectable(pNewCursor) ); + } + + // if there is no next entry, take the current one + // this ensures that in case of _one_ entry in the list, this entry is selected when pressing + // the cursor key + if ( !pNewCursor && pCursor ) + pNewCursor = pCursor; + + if( pNewCursor ) + { + aSelEng.CursorPosChanging( bShift, bMod1 ); + SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on + if( !IsEntryInView( pNewCursor ) ) + KeyUp( false ); + } + break; + } + + case KEY_DOWN: + { + if( !IsEntryInView( pCursor ) ) + MakeVisible( pCursor ); + + pNewCursor = pCursor; + for( i = 0; i < nColumns && pNewCursor; i++) + { + do + { + pNewCursor = pView->NextVisible(pNewCursor); + } while( pNewCursor && !IsSelectable(pNewCursor) ); + } + + // if there is no next entry, take the current one + // this ensures that in case of _one_ entry in the list, this entry is selected when pressing + // the cursor key + if ( !pNewCursor && pCursor ) + pNewCursor = pCursor; + + if( pNewCursor ) + { + aSelEng.CursorPosChanging( bShift, bMod1 ); + if( IsEntryInView( pNewCursor ) ) + SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on + else + { + if( pCursor ) + pView->Select( pCursor, false ); + KeyDown( false ); + SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on + } + } + else + KeyDown( false ); // because scrollbar range might still + // allow scrolling + break; + } + + case KEY_RETURN: + { + pView->aDoubleClickHdl.Call( pView ); + bHandled = true; + + break; + } + + case KEY_END: + { + pNewCursor = pView->GetModel()->Last(); + + while( pNewCursor && !IsSelectable(pNewCursor) ) + { + pNewCursor = pView->PrevVisible(pNewCursor); + } + + pStartEntry = pNewCursor; + + while( pStartEntry && pView->GetAbsPos( pStartEntry ) % pView->GetColumnsCount() != 0 ) + { + pStartEntry = pView->PrevVisible(pStartEntry); + } + + if( pNewCursor && pNewCursor != pCursor) + { +// SelAllDestrAnch( false ); + aSelEng.CursorPosChanging( bShift, bMod1 ); + SetCursor( pNewCursor ); + SyncVerThumb(); + } + + bHandled = true; + + break; + } + + default: + { + bHandled = false; + break; + } + } + + if(!bHandled) + return SvImpLBox::KeyInput( rKEvt ); + + return bKeyUsed; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/contnr/svimpbox.cxx b/svtools/source/contnr/svimpbox.cxx index c808572dc031..d48f1125b80d 100644 --- a/svtools/source/contnr/svimpbox.cxx +++ b/svtools/source/contnr/svimpbox.cxx @@ -27,8 +27,10 @@ #include <stack> #include <svtools/treelistbox.hxx> +#include <svtools/iconview.hxx> #include <svtools/svlbitm.hxx> #include <svimpbox.hxx> +#include <iconviewimpl.hxx> #include <rtl/instance.hxx> #include <svtools/svtresid.hxx> #include <tools/wintypes.hxx> @@ -39,25 +41,22 @@ #include <svtools/treelistentry.hxx> #include <svtools/viewdataentry.hxx> -#define NODE_BMP_TABDIST_NOTVALID -2000000 -#define FIRST_ENTRY_TAB 1 - // #i27063# (pl), #i32300# (pb) never access VCL after DeInitVCL - also no destructors Image* SvImpLBox::s_pDefCollapsed = nullptr; Image* SvImpLBox::s_pDefExpanded = nullptr; sal_Int32 SvImpLBox::s_nImageRefCount = 0; SvImpLBox::SvImpLBox( SvTreeListBox* pLBView, SvTreeList* pLBTree, WinBits nWinStyle) - : aVerSBar(VclPtr<ScrollBar>::Create(pLBView, WB_DRAG | WB_VSCROLL)) - , aHorSBar(VclPtr<ScrollBar>::Create(pLBView, WB_DRAG | WB_HSCROLL)) + : aHorSBar(VclPtr<ScrollBar>::Create(pLBView, WB_DRAG | WB_HSCROLL)) , aScrBarBox(VclPtr<ScrollBarBox>::Create(pLBView)) - , aOutputSize(0, 0) - , aSelEng(pLBView, nullptr) , aFctSet(this, &aSelEng, pLBView) - , nNextVerVisSize(0) - , nExtendedWinBits(0) , bAreChildrenTransient(true) , m_pStringSorter(nullptr) + , aVerSBar(VclPtr<ScrollBar>::Create(pLBView, WB_DRAG | WB_VSCROLL)) + , aOutputSize(0, 0) + , nExtendedWinBits(0) + , aSelEng(pLBView, nullptr) + , nNextVerVisSize(0) { osl_atomic_increment(&s_nImageRefCount); pView = pLBView; diff --git a/svtools/source/contnr/svlbitm.cxx b/svtools/source/contnr/svlbitm.cxx index 50767f8534a0..67192f6664a4 100644 --- a/svtools/source/contnr/svlbitm.cxx +++ b/svtools/source/contnr/svlbitm.cxx @@ -190,10 +190,16 @@ void SvLBoxString::Paint( const Point& rPos, SvTreeListBox& rDev, vcl::RenderContext& rRenderContext, const SvViewDataEntry* /*pView*/, const SvTreeListEntry& rEntry) { + Size aSize = GetSize(&rDev, &rEntry); DrawTextFlags nStyle = rDev.IsEnabled() ? DrawTextFlags::NONE : DrawTextFlags::Disable; if (rDev.IsEntryMnemonicsEnabled()) nStyle |= DrawTextFlags::Mnemonic; - rRenderContext.DrawText(Rectangle(rPos, GetSize(&rDev, &rEntry)), maText, nStyle); + if (rDev.TextCenterAndClipEnabled()) + { + nStyle |= DrawTextFlags::PathEllipsis | DrawTextFlags::Center; + aSize.Width() = rDev.GetEntryWidth(); + } + rRenderContext.DrawText(Rectangle(rPos, aSize), maText, nStyle); } SvLBoxItem* SvLBoxString::Create() const diff --git a/svtools/source/contnr/treelistbox.cxx b/svtools/source/contnr/treelistbox.cxx index 695fd424e898..d63925775588 100644 --- a/svtools/source/contnr/treelistbox.cxx +++ b/svtools/source/contnr/treelistbox.cxx @@ -378,7 +378,8 @@ SvTreeListBox::SvTreeListBox(vcl::Window* pParent, WinBits nWinStyle) : mbAlternatingRowColors(false), mbUpdateAlternatingRows(false), eSelMode(NO_SELECTION), - nMinWidthInChars(0) + nMinWidthInChars(0), + mbCenterAndClipText(false) { nDragOptions = DND_ACTION_COPYMOVE | DND_ACTION_LINK; nImpFlags = SvTreeListBoxFlags::NONE; @@ -409,7 +410,8 @@ SvTreeListBox::SvTreeListBox(vcl::Window* pParent, const ResId& rResId) : mbAlternatingRowColors(false), mbUpdateAlternatingRows(false), eSelMode(NO_SELECTION), - nMinWidthInChars(0) + nMinWidthInChars(0), + mbCenterAndClipText(false) { pTargetEntry = nullptr; nImpFlags = SvTreeListBoxFlags::NONE; @@ -2287,6 +2289,10 @@ void SvTreeListBox::SetEntryHeight( short nHeight ) } } +void SvTreeListBox::SetEntryWidth( short nWidth ) +{ + nEntryWidth = nWidth; +} void SvTreeListBox::AdjustEntryHeight( const Image& rBmp ) { diff --git a/svtools/source/inc/iconviewimpl.hxx b/svtools/source/inc/iconviewimpl.hxx new file mode 100644 index 000000000000..1aa797c578d3 --- /dev/null +++ b/svtools/source/inc/iconviewimpl.hxx @@ -0,0 +1,69 @@ +/* -*- 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_SVTOOLS_SOURCE_INC_ICONVIEWIMPL_HXX +#define INCLUDED_SVTOOLS_SOURCE_INC_ICONVIEWIMPL_HXX + +#include <svimpbox.hxx> + +class SvTreeListBox; +class Point; + +class IconViewImpl : public SvImpLBox +{ +public: + IconViewImpl( SvTreeListBox* pTreeListBox, SvTreeList* pTreeList, WinBits nWinStyle ); + + void KeyDown( bool bPageDown ) SAL_OVERRIDE; + + void KeyUp( bool bPageUp ) SAL_OVERRIDE; + + Point GetEntryPosition( SvTreeListEntry* pEntry ) const SAL_OVERRIDE; + + SvTreeListEntry* GetClickedEntry( const Point& rPoint ) const SAL_OVERRIDE; + + bool IsEntryInView( SvTreeListEntry* pEntry ) const SAL_OVERRIDE; + + void Paint( vcl::RenderContext& rRenderContext, const Rectangle& rRect ) SAL_OVERRIDE; + + // returns 0 if position is just past the last entry + SvTreeListEntry* GetEntry( const Point& rPoint ) const SAL_OVERRIDE; + + void UpdateAll( bool bInvalidateCompleteView = true, + bool bUpdateVerScrollBar = true ) SAL_OVERRIDE; + + bool KeyInput( const KeyEvent& ) SAL_OVERRIDE; + + void InvalidateEntry( long nId ) const SAL_OVERRIDE; + +protected: + long GetEntryLine( SvTreeListEntry* pEntry ) const SAL_OVERRIDE; + + void CursorUp() SAL_OVERRIDE; + void CursorDown() SAL_OVERRIDE; + void PageDown( sal_uInt16 nDelta ) SAL_OVERRIDE; + void PageUp( sal_uInt16 nDelta ) SAL_OVERRIDE; + + void SyncVerThumb() SAL_OVERRIDE; + void AdjustScrollBars( Size& rSize ) SAL_OVERRIDE; +}; + +#endif // INCLUDED_SVTOOLS_SOURCE_INC_ICONVIEWIMPL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/inc/svimpbox.hxx b/svtools/source/inc/svimpbox.hxx index 926bf1a3ada4..5edad7bcb7e2 100644 --- a/svtools/source/inc/svimpbox.hxx +++ b/svtools/source/inc/svimpbox.hxx @@ -78,23 +78,22 @@ public: #define F_ENDSCROLL_SET_VIS_SIZE 0x2000 #define F_FILLING 0x4000 +#define NODE_BMP_TABDIST_NOTVALID -2000000 +#define FIRST_ENTRY_TAB 1 class SvImpLBox { friend class ImpLBSelEng; friend class SvTreeListBox; +friend class IconView; private: - VclPtr<SvTreeListBox> pView; SvTreeList* pTree; - SvTreeListEntry* pCursor; - SvTreeListEntry* pStartEntry; SvTreeListEntry* pAnchor; SvTreeListEntry* pMostRightEntry; SvLBoxButton* pActiveButton; SvTreeListEntry* pActiveEntry; SvLBoxTab* pActiveTab; - VclPtr<ScrollBar> aVerSBar; VclPtr<ScrollBar> aHorSBar; VclPtr<ScrollBarBox> aScrBarBox; @@ -120,28 +119,17 @@ private: // all our images Image m_aNodeAndEntryImages[ IT_IMAGE_COUNT ]; - Size aOutputSize; - SelectionEngine aSelEng; ImpLBSelEng aFctSet; Idle aAsyncBeginDragIdle; Point aAsyncBeginDragPos; long nYoffsNodeBmp; - long nNodeBmpTabDistance; // typical smaller than 0 long nNodeBmpWidth; - long nNextVerVisSize; long nMostRight; - sal_uLong nVisibleCount; // Number of lines in control - ImplSVEvent * nCurUserEvent; short nHorSBarHeight, nVerSBarWidth; - sal_uInt16 nFlags; sal_uInt16 nCurTabPos; - WinBits m_nStyle; - ExtendedWinBits nExtendedWinBits; - bool bSimpleTravel : 1; // ist true bei SINGLE_SELECTION bool bUpdateMode : 1; - bool bInVScrollHdl : 1; bool bAsyncBeginDrag : 1; bool bSubLstOpRet : 1; // open/close sublist with return/enter, defaulted with false bool bSubLstOpLR : 1; // open/close sublist with cursor left/right, defaulted with false @@ -160,24 +148,10 @@ private: DECL_LINK_TYPED(EditTimerCall, Idle *, void); DECL_LINK_TYPED( BeginDragHdl, Idle*, void ); - DECL_LINK_TYPED( MyUserEvent, void*, void); - void StopUserEvent(); void InvalidateEntriesFrom( long nY ) const; - void InvalidateEntry( long nY ) const; - void ShowVerSBar(); - // setzt Thumb auf FirstEntryToDraw - void SyncVerThumb(); bool IsLineVisible( long nY ) const; - long GetEntryLine( SvTreeListEntry* pEntry ) const; - void FillView(); - void CursorDown(); - void CursorUp(); void KeyLeftRight( long nDiff ); - void PageDown( sal_uInt16 nDelta ); - void PageUp( sal_uInt16 nDelta ); - - void SetCursor( SvTreeListEntry* pEntry, bool bForceNoSelect = false ); void DrawNet(vcl::RenderContext& rRenderContext); @@ -200,18 +174,11 @@ private: bool ButtonUpCheckCtrl( const MouseEvent& rMEvt ); bool ButtonDownCheckExpand( const MouseEvent&, SvTreeListEntry*,long nY ); - void PositionScrollBars( Size& rOSize, sal_uInt16 nMask ); - void AdjustScrollBars( Size& rSize ); - - void BeginScroll(); - void EndScroll(); - Rectangle GetVisibleArea() const; bool EntryReallyHit(SvTreeListEntry* pEntry, const Point& rPos, long nLine); void InitScrollBarBox(); SvLBoxTab* NextTab( SvLBoxTab* ); bool SetMostRight( SvTreeListEntry* pEntry ); - void FindMostRight( SvTreeListEntry* EntryToIgnore ); void FindMostRight( SvTreeListEntry* pParent, SvTreeListEntry* EntryToIgnore ); void FindMostRight_Impl( SvTreeListEntry* pParent,SvTreeListEntry* EntryToIgnore ); void NotifyTabsChanged(); @@ -235,9 +202,48 @@ private: bool AreChildrenTransient() const { return bAreChildrenTransient; } inline void SetChildrenNotTransient() { bAreChildrenTransient = false; } +protected: + VclPtr<SvTreeListBox> pView; + VclPtr<ScrollBar> aVerSBar; + SvTreeListEntry* pCursor; + SvTreeListEntry* pStartEntry; + ImplSVEvent* nCurUserEvent; + Size aOutputSize; + sal_uInt16 nFlags; + WinBits m_nStyle; + ExtendedWinBits nExtendedWinBits; + SelectionEngine aSelEng; + sal_uLong nVisibleCount; // Number of lines in control + bool bInVScrollHdl : 1; + bool bSimpleTravel : 1; // ist true bei SINGLE_SELECTION + long nNextVerVisSize; + long nNodeBmpTabDistance; // typical smaller than 0 + + virtual long GetEntryLine( SvTreeListEntry* pEntry ) const; + virtual void CursorDown(); + virtual void CursorUp(); + virtual void PageDown( sal_uInt16 nDelta ); + virtual void PageUp( sal_uInt16 nDelta ); + // setzt Thumb auf FirstEntryToDraw + virtual void SyncVerThumb(); + virtual void AdjustScrollBars( Size& rSize ); + virtual void InvalidateEntry( long nY ) const; + + Rectangle GetVisibleArea() const; + void SetCursor( SvTreeListEntry* pEntry, bool bForceNoSelect = false ); + void BeginScroll(); + void EndScroll(); + void PositionScrollBars( Size& rOSize, sal_uInt16 nMask ); + void FindMostRight( SvTreeListEntry* EntryToIgnore ); + void FillView(); + void ShowVerSBar(); + void StopUserEvent(); + + DECL_LINK_TYPED( MyUserEvent, void*, void); + public: SvImpLBox( SvTreeListBox* pView, SvTreeList*, WinBits nWinStyle ); - ~SvImpLBox(); + virtual ~SvImpLBox(); void Clear(); void SetStyle( WinBits i_nWinStyle ); @@ -256,31 +262,31 @@ public: void CollapsingEntry( SvTreeListEntry* pEntry ); void EntrySelected( SvTreeListEntry* pEntry, bool bSelect ); - void Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect); + virtual void Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect); void MouseButtonDown( const MouseEvent& ); void MouseButtonUp( const MouseEvent& ); void MouseMove( const MouseEvent&); - bool KeyInput( const KeyEvent& ); + virtual bool KeyInput( const KeyEvent& ); void Resize(); void GetFocus(); void LoseFocus(); - void UpdateAll( bool bInvalidateCompleteView= true, bool bUpdateVerSBar = true ); + virtual void UpdateAll( bool bInvalidateCompleteView= true, bool bUpdateVerSBar = true ); void SetEntryHeight( short nHeight ); void InvalidateEntry( SvTreeListEntry* ); - void RecalcFocusRect(); + virtual void RecalcFocusRect(); void SelectEntry( SvTreeListEntry* pEntry, bool bSelect ); void SetDragDropMode( DragDropMode eDDMode ); void SetSelectionMode( SelectionMode eSelMode ); SvTreeListEntry* GetCurrentEntry() const { return pCursor; } - bool IsEntryInView( SvTreeListEntry* pEntry ) const; - SvTreeListEntry* GetEntry( const Point& rPos ) const; + virtual bool IsEntryInView( SvTreeListEntry* pEntry ) const; + virtual SvTreeListEntry* GetEntry( const Point& rPos ) const; // returns last entry, if Pos below last entry - SvTreeListEntry* GetClickedEntry( const Point& ) const; + virtual SvTreeListEntry* GetClickedEntry( const Point& ) const; SvTreeListEntry* GetCurEntry() const { return pCursor; } void SetCurEntry( SvTreeListEntry* ); - Point GetEntryPosition( SvTreeListEntry* ) const; + virtual Point GetEntryPosition( SvTreeListEntry* ) const; void MakeVisible( SvTreeListEntry* pEntry, bool bMoveToTop = false ); void ScrollToAbsPos( long nPos ); @@ -305,8 +311,8 @@ public: static const Image& GetDefaultCollapsedNodeImage( ); const Size& GetOutputSize() const { return aOutputSize;} - void KeyUp( bool bPageUp ); - void KeyDown( bool bPageDown ); + virtual void KeyUp( bool bPageUp ); + virtual void KeyDown( bool bPageDown ); void Command( const CommandEvent& rCEvt ); void Invalidate(); |