/* -*- 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 "taborder.hxx" #include "modulepcr.hxx" #include "formresid.hrc" #include "formstrings.hxx" #include #include #include #include #include #include #include #include namespace pcr { using namespace ::com::sun::star::uno; using namespace ::com::sun::star::awt; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::form; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::datatransfer; //= OSimpleTabModel class OSimpleTabModel : public ::cppu::WeakImplHelper< XTabControllerModel> { Sequence< Reference< XControlModel > > m_aModels; public: OSimpleTabModel( const Sequence< Reference< XControlModel > >& _rModels ) :m_aModels( _rModels ) { } // XTabControllerModel virtual void SAL_CALL setControlModels(const Sequence< Reference< XControlModel > >& rModels) throw( RuntimeException, std::exception ) SAL_OVERRIDE {m_aModels = rModels;} virtual Sequence< Reference< XControlModel > > SAL_CALL getControlModels() throw( RuntimeException, std::exception ) SAL_OVERRIDE {return m_aModels;} virtual void SAL_CALL setGroup(const Sequence< Reference< XControlModel > >& /*Group*/, const OUString& /*GroupName*/) throw( RuntimeException, std::exception ) SAL_OVERRIDE {} virtual sal_Int32 SAL_CALL getGroupCount() throw( RuntimeException, std::exception ) SAL_OVERRIDE {return 0;} virtual void SAL_CALL getGroup(sal_Int32 /*nGroup*/, Sequence< Reference< XControlModel > >& /*Group*/, OUString& /*Name*/) throw( RuntimeException, std::exception ) SAL_OVERRIDE {} virtual void SAL_CALL getGroupByName(const OUString& /*Name*/, Sequence< Reference< XControlModel > >& /*Group*/) throw( RuntimeException, std::exception ) SAL_OVERRIDE {} virtual sal_Bool SAL_CALL getGroupControl() throw( RuntimeException, std::exception ) SAL_OVERRIDE {return sal_False;} ; virtual void SAL_CALL setGroupControl(sal_Bool /*GroupControl*/) throw( RuntimeException, std::exception ) SAL_OVERRIDE {}; }; //= TabOrderDialog TabOrderDialog::TabOrderDialog( vcl::Window* _pParent, const Reference< XTabControllerModel >& _rxTabModel, const Reference< XControlContainer >& _rxControlCont, const Reference< XComponentContext >& _rxORB ) :ModalDialog( _pParent, "TabOrderDialog", "modules/spropctrlr/ui/taborder.ui") ,m_xModel( _rxTabModel ) ,m_xControlContainer( _rxControlCont ) ,m_xORB( _rxORB ) ,pImageList( NULL ) { get(m_pLB_Controls, "CTRLtree"); get(m_pPB_OK, "ok"); get(m_pPB_MoveUp, "upB"); get(m_pPB_MoveDown, "downB"); get(m_pPB_AutoOrder, "autoB"); m_pPB_MoveUp->SetClickHdl( LINK( this, TabOrderDialog, MoveUpClickHdl ) ); m_pPB_MoveDown->SetClickHdl( LINK( this, TabOrderDialog, MoveDownClickHdl ) ); m_pPB_AutoOrder->SetClickHdl( LINK( this, TabOrderDialog, AutoOrderClickHdl ) ); m_pPB_OK->SetClickHdl( LINK( this, TabOrderDialog, OKClickHdl ) ); m_pPB_OK->Disable(); pImageList = new ImageList( PcrRes( RID_IL_FORMEXPLORER ) ); if ( m_xModel.is() ) m_xTempModel = new OSimpleTabModel( m_xModel->getControlModels() ); if ( m_xTempModel.is() && m_xControlContainer.is() ) FillList(); if ( m_pLB_Controls->GetEntryCount() < 2 ) { m_pPB_MoveUp->Disable(); m_pPB_MoveDown->Disable(); m_pPB_AutoOrder->Disable(); } } void TabOrderDialog::SetModified() { m_pPB_OK->Enable(); } TabOrderDialog::~TabOrderDialog() { disposeOnce(); } void TabOrderDialog::dispose() { m_pLB_Controls->Hide(); // delete pLB_Controls; delete pImageList; m_pLB_Controls.clear(); m_pPB_OK.clear(); m_pPB_MoveUp.clear(); m_pPB_MoveDown.clear(); m_pPB_AutoOrder.clear(); ModalDialog::dispose(); } Image TabOrderDialog::GetImage( const Reference< XPropertySet >& _rxSet ) const { sal_uInt16 nImageId = RID_SVXIMG_CONTROL; // TODO: classify controls also in Basic propbrw if ( _rxSet.is() && ::comphelper::hasProperty( PROPERTY_CLASSID, _rxSet ) ) { switch( ::comphelper::getINT16( _rxSet->getPropertyValue( PROPERTY_CLASSID ) ) ) { case FormComponentType::COMMANDBUTTON: nImageId = RID_SVXIMG_BUTTON; break; case FormComponentType::FIXEDTEXT: nImageId = RID_SVXIMG_FIXEDTEXT; break; case FormComponentType::TEXTFIELD: nImageId = RID_SVXIMG_EDIT; break; case FormComponentType::RADIOBUTTON: nImageId = RID_SVXIMG_RADIOBUTTON; break; case FormComponentType::CHECKBOX: nImageId = RID_SVXIMG_CHECKBOX; break; case FormComponentType::LISTBOX: nImageId = RID_SVXIMG_LISTBOX; break; case FormComponentType::COMBOBOX: nImageId = RID_SVXIMG_COMBOBOX; break; case FormComponentType::GROUPBOX: nImageId = RID_SVXIMG_GROUPBOX; break; case FormComponentType::IMAGEBUTTON: nImageId = RID_SVXIMG_IMAGEBUTTON; break; case FormComponentType::FILECONTROL: nImageId = RID_SVXIMG_FILECONTROL; break; case FormComponentType::HIDDENCONTROL: nImageId = RID_SVXIMG_HIDDEN; break; case FormComponentType::DATEFIELD: nImageId = RID_SVXIMG_DATEFIELD; break; case FormComponentType::TIMEFIELD: nImageId = RID_SVXIMG_TIMEFIELD; break; case FormComponentType::NUMERICFIELD: nImageId = RID_SVXIMG_NUMERICFIELD; break; case FormComponentType::CURRENCYFIELD: nImageId = RID_SVXIMG_CURRENCYFIELD; break; case FormComponentType::PATTERNFIELD: nImageId = RID_SVXIMG_PATTERNFIELD; break; case FormComponentType::IMAGECONTROL: nImageId = RID_SVXIMG_IMAGECONTROL; break; case FormComponentType::GRIDCONTROL: nImageId = RID_SVXIMG_GRID; break; case FormComponentType::SCROLLBAR: nImageId = RID_SVXIMG_SCROLLBAR; break; case FormComponentType::SPINBUTTON: nImageId = RID_SVXIMG_SPINBUTTON; break; case FormComponentType::NAVIGATIONBAR: nImageId = RID_SVXIMG_NAVIGATIONBAR; break; default: OSL_FAIL( "TabOrderDialog::GetImage: unknown control type" ); } } return pImageList->GetImage( nImageId ); } void TabOrderDialog::FillList() { DBG_ASSERT( m_xTempModel.is() && m_xControlContainer.is(), "TabOrderDialog::FillList: invalid call!" ); if ( !m_xTempModel.is() || !m_xControlContainer.is() ) return; m_pLB_Controls->Clear(); try { Sequence< Reference< XControlModel > > aControlModels( m_xTempModel->getControlModels() ); const Reference< XControlModel >* pControlModels = aControlModels.getConstArray(); OUString aName; Image aImage; for ( sal_Int32 i=0; i < aControlModels.getLength(); ++i, ++pControlModels ) { Reference< XPropertySet > xControl( *pControlModels, UNO_QUERY ); Reference< XPropertySetInfo > xPI; if ( xControl.is() ) xPI = xControl->getPropertySetInfo(); if ( xPI.is() ) { if ( xPI->hasPropertyByName( PROPERTY_TABSTOP ) ) { aName = ::comphelper::getString( xControl->getPropertyValue( PROPERTY_NAME ) ); // TODO: do Basic controls have a name? aImage = GetImage( xControl ); m_pLB_Controls->InsertEntry( aName, aImage, aImage, 0, false, TREELIST_APPEND, xControl.get() ); } } else { // no property set -> no tab order OSL_FAIL( "TabOrderDialog::FillList: invalid control encountered!" ); m_pLB_Controls->Clear(); break; } } } catch( const Exception& ) { OSL_FAIL( "TabOrderDialog::FillList: caught an exception!" ); } // select first entry SvTreeListEntry* pFirstEntry = m_pLB_Controls->GetEntry( 0 ); if ( pFirstEntry ) m_pLB_Controls->Select( pFirstEntry ); } IMPL_LINK_NOARG_TYPED( TabOrderDialog, MoveUpClickHdl, Button*, void ) { m_pLB_Controls->MoveSelection( -1 ); } IMPL_LINK_NOARG_TYPED( TabOrderDialog, MoveDownClickHdl, Button*, void ) { m_pLB_Controls->MoveSelection( 1 ); } IMPL_LINK_NOARG_TYPED( TabOrderDialog, AutoOrderClickHdl, Button*, void ) { try { Reference< css::form::runtime::XFormController > xTabController = css::form::runtime::FormController::create( m_xORB ); xTabController->setModel( m_xTempModel ); xTabController->setContainer( m_xControlContainer ); xTabController->autoTabOrder(); SetModified(); FillList(); ::comphelper::disposeComponent( xTabController ); } catch( const Exception& ) { OSL_FAIL( "TabOrderDialog::AutoOrderClickHdl: caught an exception!" ); } } IMPL_LINK_NOARG_TYPED( TabOrderDialog, OKClickHdl, Button*, void ) { sal_uLong nEntryCount = m_pLB_Controls->GetEntryCount(); Sequence< Reference< XControlModel > > aSortedControlModelSeq( nEntryCount ); Sequence< Reference< XControlModel > > aControlModels( m_xTempModel->getControlModels()); Reference< XControlModel > * pSortedControlModels = aSortedControlModelSeq.getArray(); const Reference< XControlModel > * pControlModels = aControlModels.getConstArray(); for (sal_uLong i=0; i < nEntryCount; i++) { SvTreeListEntry* pEntry = m_pLB_Controls->GetEntry(i); for( sal_Int32 j=0; j xSet(pControlModels[j], UNO_QUERY); if (xSet.get() == static_cast(pEntry->GetUserData())) { pSortedControlModels[i] = pControlModels[j]; break; } } } // TODO: UNO action (to bracket all the single actions which are being created) m_xModel->setControlModels( aSortedControlModelSeq ); EndDialog( RET_OK ); } //= TabOrderListBox TabOrderListBox::TabOrderListBox( vcl::Window* pParent, WinBits nBits ) :SvTreeListBox( pParent, nBits ) { SetDragDropMode(DragDropMode::ALL/*DragDropMode::CTRL_MOVE*/); // Hmm. The flag alone is not enough, so to be on the safe side ... SetSelectionMode( MULTIPLE_SELECTION ); } VCL_BUILDER_DECL_FACTORY(TabOrderListBox) { WinBits nWinStyle = WB_TABSTOP; OString sBorder = VclBuilder::extractCustomProperty(rMap); if (!sBorder.isEmpty()) nWinStyle |= WB_BORDER; rRet = VclPtr::Create(pParent, nWinStyle); } TabOrderListBox::~TabOrderListBox() { } void TabOrderListBox::ModelHasMoved( SvTreeListEntry* _pSource ) { SvTreeListBox::ModelHasMoved( _pSource ); static_cast(GetParentDialog())->SetModified(); } void TabOrderListBox::MoveSelection( long nRelPos ) { OUString aSelEntryPrevText, aSelEntryNextText; Image aImage; for (long i=0; i(GetParentDialog())->SetModified(); // move entries if( nRelPos < 0 ) { SvTreeListEntry* pFirstSelected = FirstSelected(); if( !pFirstSelected ) return; sal_uLong nFirstSelPos = GetModel()->GetAbsPos( pFirstSelected ); if( nFirstSelPos == 0 ) return; SvTreeListEntry* pSelEntry = pFirstSelected; while( pSelEntry ) { sal_uLong nSelEntryPos = GetModel()->GetAbsPos( pSelEntry ); SvTreeListEntry* pSelEntryPrev = GetEntry( nSelEntryPos-1 ); aSelEntryPrevText = GetEntryText( pSelEntryPrev ); aImage = GetExpandedEntryBmp(pSelEntryPrev); void* pData = pSelEntryPrev->GetUserData(); GetModel()->Remove( pSelEntryPrev ); InsertEntry( aSelEntryPrevText, aImage, aImage, 0, false, nSelEntryPos, pData ); pSelEntry = NextSelected( pSelEntry ); } } else if( nRelPos > 0 ) { SvTreeListEntry* pLastSelected = LastSelected(); if( !pLastSelected ) return; sal_uLong nLastSelPos = GetModel()->GetAbsPos( pLastSelected ); if( (nLastSelPos + nRelPos - i) > (GetEntryCount()-1) ) return; #if OSL_DEBUG_LEVEL > 0 sal_uLong nSelCount = GetSelectionCount(); (void)nSelCount; #endif SvTreeListEntry* pSelEntry = pLastSelected; while( pSelEntry ) { sal_uLong nSelEntryPos = GetModel()->GetAbsPos( pSelEntry ); SvTreeListEntry* pSelEntryNext = GetEntry( nSelEntryPos+1 ); void* pData = pSelEntryNext->GetUserData(); aSelEntryNextText = GetEntryText( pSelEntryNext ); aImage = GetExpandedEntryBmp(pSelEntryNext); GetModel()->Remove( pSelEntryNext ); InsertEntry( aSelEntryNextText, aImage, aImage, 0, false, nSelEntryPos, pData ); pSelEntry = PrevSelected( pSelEntry ); } long nThumbPos = GetVScroll()->GetThumbPos(); long nVisibleSize = GetVScroll()->GetVisibleSize(); long nFirstVisible = GetModel()->GetAbsPos( FirstVisible()); if ( ( nThumbPos + nVisibleSize + 1 ) < (long)( nLastSelPos + 3 ) ) GetVScroll()->DoScrollAction(SCROLL_LINEDOWN); else if((nThumbPos+nVisibleSize+1) >= (nFirstVisible)) GetVScroll()->DoScrollAction(SCROLL_LINEUP); } } } } // namespace pcr /* vim:set shiftwidth=4 softtabstop=4 expandtab: */