LCOV - code coverage report
Current view: top level - svx/source/tbxctrls - fillctrl.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 154 415 37.1 %
Date: 2014-11-03 Functions: 17 22 77.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <string>
      21             : #include <sfx2/app.hxx>
      22             : #include <sfx2/dispatch.hxx>
      23             : #include <sfx2/objsh.hxx>
      24             : #include <sfx2/viewsh.hxx>
      25             : #include <rtl/ustring.hxx>
      26             : #include <vcl/settings.hxx>
      27             : #include <vcl/toolbox.hxx>
      28             : #include <svx/dialogs.hrc>
      29             : 
      30             : #define TMP_STR_BEGIN   "["
      31             : #define TMP_STR_END     "]"
      32             : 
      33             : #include "svx/drawitem.hxx"
      34             : #include "svx/xattr.hxx"
      35             : #include <svx/xtable.hxx>
      36             : #include <svx/fillctrl.hxx>
      37             : #include <svx/itemwin.hxx>
      38             : #include <svx/dialmgr.hxx>
      39             : #include "helpid.hrc"
      40             : #include <boost/scoped_ptr.hpp>
      41             : 
      42             : using namespace ::com::sun::star;
      43             : using namespace ::com::sun::star::uno;
      44             : using namespace ::com::sun::star::util;
      45             : using namespace ::com::sun::star::beans;
      46             : using namespace ::com::sun::star::frame;
      47             : using namespace ::com::sun::star::lang;
      48             : 
      49         326 : SFX_IMPL_TOOLBOX_CONTROL( SvxFillToolBoxControl, XFillStyleItem );
      50             : 
      51         126 : SvxFillToolBoxControl::SvxFillToolBoxControl(
      52             :     sal_uInt16 nSlotId,
      53             :     sal_uInt16 nId,
      54             :     ToolBox& rTbx )
      55             :     : SfxToolBoxControl( nSlotId, nId, rTbx )
      56             :     , mpStyleItem(0)
      57             :     , mpColorItem(0)
      58             :     , mpGradientItem(0)
      59             :     , mpHatchItem(0)
      60             :     , mpBitmapItem(0)
      61             :     , mpFillControl(0)
      62             :     , mpFillTypeLB(0)
      63             :     , mpFillAttrLB(0)
      64             :     , meLastXFS(drawing::FillStyle_NONE)
      65         126 :     , mbUpdate(false)
      66             : {
      67         126 :     addStatusListener( OUString( ".uno:FillColor" ));
      68         126 :     addStatusListener( OUString( ".uno:FillGradient" ));
      69         126 :     addStatusListener( OUString( ".uno:FillHatch" ));
      70         126 :     addStatusListener( OUString( ".uno:FillBitmap" ));
      71         126 :     addStatusListener( OUString( ".uno:ColorTableState" ));
      72         126 :     addStatusListener( OUString( ".uno:GradientListState" ));
      73         126 :     addStatusListener( OUString( ".uno:HatchListState" ));
      74         126 :     addStatusListener( OUString( ".uno:BitmapListState" ));
      75         126 : }
      76             : 
      77             : 
      78             : 
      79         378 : SvxFillToolBoxControl::~SvxFillToolBoxControl()
      80             : {
      81         126 :     delete mpStyleItem;
      82         126 :     delete mpColorItem;
      83         126 :     delete mpGradientItem;
      84         126 :     delete mpHatchItem;
      85         126 :     delete mpBitmapItem;
      86         252 : }
      87             : 
      88             : 
      89             : 
      90         594 : void SvxFillToolBoxControl::StateChanged(
      91             :     sal_uInt16 nSID,
      92             :     SfxItemState eState,
      93             :     const SfxPoolItem* pState)
      94             : {
      95         594 :     if(eState == SfxItemState::DISABLED)
      96             :     {
      97             :         // slot disable state
      98           0 :         if(nSID == SID_ATTR_FILL_STYLE)
      99             :         {
     100           0 :             mpFillTypeLB->Disable();
     101           0 :             mpFillTypeLB->SetNoSelection();
     102             :         }
     103             : 
     104           0 :         mpFillAttrLB->Disable();
     105           0 :         mpFillAttrLB->SetNoSelection();
     106             :     }
     107         594 :     else if(SfxItemState::DEFAULT == eState)
     108             :     {
     109         330 :         bool bEnableControls(false);
     110             : 
     111             :         // slot available state
     112         330 :         if(nSID == SID_ATTR_FILL_STYLE)
     113             :         {
     114          66 :             delete mpStyleItem;
     115          66 :             mpStyleItem = static_cast< XFillStyleItem* >(pState->Clone());
     116          66 :             mpFillTypeLB->Enable();
     117             :         }
     118         264 :         else if(mpStyleItem)
     119             :         {
     120         264 :             const drawing::FillStyle eXFS(static_cast< drawing::FillStyle >(mpStyleItem->GetValue()));
     121             : 
     122         264 :             if(nSID == SID_ATTR_FILL_COLOR)
     123             :             {
     124          66 :                 delete mpColorItem;
     125          66 :                 mpColorItem = static_cast< XFillColorItem* >(pState->Clone());
     126             : 
     127          66 :                 if(eXFS == drawing::FillStyle_SOLID)
     128             :                 {
     129          66 :                     bEnableControls = true;
     130             :                 }
     131             :             }
     132         198 :             else if(nSID == SID_ATTR_FILL_GRADIENT)
     133             :             {
     134          66 :                 delete mpGradientItem;
     135          66 :                 mpGradientItem = static_cast< XFillGradientItem* >(pState->Clone());
     136             : 
     137          66 :                 if(eXFS == drawing::FillStyle_GRADIENT)
     138             :                 {
     139           0 :                     bEnableControls = true;
     140             :                 }
     141             :             }
     142         132 :             else if(nSID == SID_ATTR_FILL_HATCH)
     143             :             {
     144          66 :                 delete mpHatchItem;
     145          66 :                 mpHatchItem = static_cast< XFillHatchItem* >(pState->Clone());
     146             : 
     147          66 :                 if(eXFS == drawing::FillStyle_HATCH)
     148             :                 {
     149           0 :                     bEnableControls = true;
     150             :                 }
     151             :             }
     152          66 :             else if(nSID == SID_ATTR_FILL_BITMAP)
     153             :             {
     154          66 :                 delete mpBitmapItem;
     155          66 :                 mpBitmapItem = static_cast< XFillBitmapItem* >(pState->Clone());
     156             : 
     157          66 :                 if(eXFS == drawing::FillStyle_BITMAP)
     158             :                 {
     159           0 :                     bEnableControls = true;
     160             :                 }
     161             :             }
     162             :         }
     163             : 
     164         330 :         if(mpStyleItem)
     165             :         {
     166             :             // ensure that the correct entry is selected in mpFillTypeLB
     167         330 :             drawing::FillStyle eXFS(static_cast< drawing::FillStyle >(mpStyleItem->GetValue()));
     168         330 :             const bool bFillTypeChangedByUser(mpFillControl->mbFillTypeChanged);
     169             : 
     170         330 :             if(bFillTypeChangedByUser)
     171             :             {
     172           0 :                 meLastXFS = static_cast< drawing::FillStyle >(mpFillControl->mnLastFillTypeControlSelectEntryPos);
     173           0 :                 mpFillControl->mbFillTypeChanged = false;
     174             :             }
     175             : 
     176         330 :             if(meLastXFS != eXFS)
     177             :             {
     178          57 :                 mbUpdate = true;
     179          57 :                 mpFillTypeLB->SelectEntryPos(sal::static_int_cast<sal_uInt16>(eXFS));
     180             :             }
     181             : 
     182         330 :             mpFillAttrLB->Enable();
     183             :         }
     184             : 
     185         330 :         if(bEnableControls)
     186             :         {
     187          66 :             mpFillAttrLB->Enable();
     188          66 :             mbUpdate = true;
     189             :         }
     190             : 
     191         330 :         Update(pState);
     192             :     }
     193             :     else
     194             :     {
     195             :         // slot empty or ambigous
     196         264 :         if(nSID == SID_ATTR_FILL_STYLE)
     197             :         {
     198           0 :             mpFillTypeLB->SetNoSelection();
     199           0 :             mpFillAttrLB->Disable();
     200           0 :             mpFillAttrLB->SetNoSelection();
     201           0 :             delete mpStyleItem;
     202           0 :             mpStyleItem = 0;
     203           0 :             mbUpdate = false;
     204             :         }
     205             :         else
     206             :         {
     207         264 :             drawing::FillStyle eXFS(drawing::FillStyle_NONE);
     208             : 
     209         264 :             if(mpStyleItem)
     210             :             {
     211         264 :                 eXFS = static_cast< drawing::FillStyle >(mpStyleItem->GetValue());
     212             :             }
     213             : 
     214         264 :             if(!mpStyleItem ||
     215           0 :                 (nSID == SID_ATTR_FILL_COLOR && eXFS == drawing::FillStyle_SOLID) ||
     216           0 :                 (nSID == SID_ATTR_FILL_GRADIENT && eXFS == drawing::FillStyle_GRADIENT) ||
     217           0 :                 (nSID == SID_ATTR_FILL_HATCH && eXFS == drawing::FillStyle_HATCH) ||
     218           0 :                 (nSID == SID_ATTR_FILL_BITMAP && eXFS == drawing::FillStyle_BITMAP))
     219             :             {
     220           0 :                 mpFillAttrLB->SetNoSelection();
     221             :             }
     222             :         }
     223             :     }
     224         594 : }
     225             : 
     226             : 
     227             : 
     228         330 : void SvxFillToolBoxControl::Update(const SfxPoolItem* pState)
     229             : {
     230         330 :     if(mpStyleItem && pState && mbUpdate)
     231             :     {
     232         123 :         mbUpdate = false;
     233         123 :         const drawing::FillStyle eXFS(static_cast< drawing::FillStyle >(mpStyleItem->GetValue()));
     234             : 
     235             :         // Check if the fill style was already active
     236         123 :         if(meLastXFS != eXFS)
     237             :         {
     238             :             // update mnLastFillTypeControlSelectEntryPos and fill style list
     239          57 :             mpFillControl->updateLastFillTypeControlSelectEntryPos();
     240          57 :             mpFillControl->InitializeFillStyleAccordingToGivenFillType(eXFS);
     241          57 :             meLastXFS = eXFS;
     242             :         }
     243             : 
     244         123 :         switch(eXFS)
     245             :         {
     246             :             case drawing::FillStyle_NONE:
     247             :             {
     248           0 :                 break;
     249             :             }
     250             : 
     251             :             case drawing::FillStyle_SOLID:
     252             :             {
     253         123 :                 if(mpColorItem)
     254             :                 {
     255          66 :                     OUString aString(mpColorItem->GetName());
     256          66 :                     ::Color aColor = mpColorItem->GetColorValue();
     257             : 
     258          66 :                     mpFillAttrLB->SelectEntry(aString);
     259             : 
     260          66 :                     if(mpFillAttrLB->GetSelectEntryPos() == LISTBOX_ENTRY_NOTFOUND || mpFillAttrLB->GetSelectEntryColor() != aColor)
     261             :                     {
     262          57 :                         mpFillAttrLB->SelectEntry(aColor);
     263             :                     }
     264             : 
     265             :                     // Check if the entry is not in the list
     266         198 :                     if( mpFillAttrLB->GetSelectEntryPos() ==
     267         264 :                         LISTBOX_ENTRY_NOTFOUND ||
     268         264 :                         mpFillAttrLB->GetSelectEntryColor() != aColor )
     269             :                     {
     270           0 :                         sal_Int32 nCount = mpFillAttrLB->GetEntryCount();
     271           0 :                         OUString aTmpStr;
     272           0 :                         if( nCount > 0 )
     273             :                         {
     274             :                             // Last entry gets tested against temporary color
     275           0 :                             aTmpStr = mpFillAttrLB->GetEntry( nCount - 1 );
     276           0 :                             if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
     277           0 :                                 aTmpStr.endsWith(TMP_STR_END) )
     278             :                             {
     279           0 :                                 mpFillAttrLB->RemoveEntry(nCount - 1);
     280             :                             }
     281             :                         }
     282           0 :                         aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
     283             : 
     284           0 :                         sal_Int32 nPos = mpFillAttrLB->InsertEntry(aColor, aTmpStr);
     285           0 :                         mpFillAttrLB->SelectEntryPos(nPos);
     286          66 :                     }
     287             :                 }
     288             :                 else
     289             :                 {
     290          57 :                     mpFillAttrLB->SetNoSelection();
     291             :                 }
     292         123 :                 break;
     293             :             }
     294             : 
     295             :             case drawing::FillStyle_GRADIENT:
     296             :             {
     297           0 :                 if(mpGradientItem)
     298             :                 {
     299           0 :                     OUString aString(mpGradientItem->GetName());
     300           0 :                     mpFillAttrLB->SelectEntry( aString );
     301             :                     // Check if the entry is not in the list
     302           0 :                     if (mpFillAttrLB->GetSelectEntry() != aString)
     303             :                     {
     304           0 :                         sal_Int32 nCount = mpFillAttrLB->GetEntryCount();
     305           0 :                         OUString aTmpStr;
     306           0 :                         if( nCount > 0 )
     307             :                         {
     308             :                             // Last entry gets tested against temporary entry
     309           0 :                             aTmpStr = mpFillAttrLB->GetEntry( nCount - 1 );
     310           0 :                             if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
     311           0 :                                 aTmpStr.endsWith(TMP_STR_END) )
     312             :                             {
     313           0 :                                 mpFillAttrLB->RemoveEntry(nCount - 1);
     314             :                             }
     315             :                         }
     316           0 :                         aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
     317             : 
     318           0 :                         boost::scoped_ptr<XGradientEntry> pEntry(new XGradientEntry(mpGradientItem->GetGradientValue(), aTmpStr));
     319           0 :                         XGradientList aGradientList( "", ""/*TODO?*/ );
     320           0 :                         aGradientList.Insert( pEntry.get() );
     321           0 :                         aGradientList.SetDirty( false );
     322           0 :                         const Bitmap aBmp = aGradientList.GetUiBitmap( 0 );
     323             : 
     324           0 :                         if(!aBmp.IsEmpty())
     325             :                         {
     326           0 :                             mpFillAttrLB->InsertEntry(pEntry->GetName(), Image(aBmp));
     327           0 :                             mpFillAttrLB->SelectEntryPos(mpFillAttrLB->GetEntryCount() - 1);
     328             :                         }
     329             : 
     330           0 :                         aGradientList.Remove( 0 );
     331           0 :                     }
     332             :                 }
     333             :                 else
     334             :                 {
     335           0 :                     mpFillAttrLB->SetNoSelection();
     336             :                 }
     337           0 :                 break;
     338             :             }
     339             : 
     340             :             case drawing::FillStyle_HATCH:
     341             :             {
     342           0 :                 if(mpHatchItem)
     343             :                 {
     344           0 :                     OUString aString(mpHatchItem->GetName());
     345           0 :                     mpFillAttrLB->SelectEntry( aString );
     346             :                     // Check if the entry is not in the list
     347           0 :                     if (mpFillAttrLB->GetSelectEntry() != aString)
     348             :                     {
     349           0 :                         sal_Int32 nCount = mpFillAttrLB->GetEntryCount();
     350           0 :                         OUString aTmpStr;
     351           0 :                         if( nCount > 0 )
     352             :                         {
     353             :                             // Last entry gets tested against temporary entry
     354           0 :                             aTmpStr = mpFillAttrLB->GetEntry( nCount - 1 );
     355           0 :                             if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
     356           0 :                                 aTmpStr.endsWith(TMP_STR_END) )
     357             :                             {
     358           0 :                                 mpFillAttrLB->RemoveEntry(nCount - 1);
     359             :                             }
     360             :                         }
     361           0 :                         aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
     362             : 
     363           0 :                         boost::scoped_ptr<XHatchEntry> pEntry(new XHatchEntry(mpHatchItem->GetHatchValue(), aTmpStr));
     364           0 :                         XHatchList aHatchList( "", ""/*TODO?*/ );
     365           0 :                         aHatchList.Insert( pEntry.get() );
     366           0 :                         aHatchList.SetDirty( false );
     367           0 :                         const Bitmap aBmp = aHatchList.GetUiBitmap( 0 );
     368             : 
     369           0 :                         if(!aBmp.IsEmpty())
     370             :                         {
     371           0 :                             mpFillAttrLB->InsertEntry(pEntry->GetName(), Image(aBmp));
     372           0 :                             mpFillAttrLB->SelectEntryPos(mpFillAttrLB->GetEntryCount() - 1);
     373             :                         }
     374             : 
     375           0 :                         aHatchList.Remove( 0 );
     376           0 :                     }
     377             :                 }
     378             :                 else
     379             :                 {
     380           0 :                     mpFillAttrLB->SetNoSelection();
     381             :                 }
     382           0 :                 break;
     383             :             }
     384             : 
     385             :             case drawing::FillStyle_BITMAP:
     386             :             {
     387           0 :                 if(mpBitmapItem)
     388             :                 {
     389           0 :                     OUString aString(mpBitmapItem->GetName());
     390           0 :                     mpFillAttrLB->SelectEntry( aString );
     391             :                     // Check if the entry is not in the list
     392           0 :                     if (mpFillAttrLB->GetSelectEntry() != aString)
     393             :                     {
     394           0 :                         sal_Int32 nCount = mpFillAttrLB->GetEntryCount();
     395           0 :                         OUString aTmpStr;
     396           0 :                         if( nCount > 0 )
     397             :                         {
     398             :                             // Last entry gets tested against temporary entry
     399           0 :                             aTmpStr = mpFillAttrLB->GetEntry(nCount - 1);
     400           0 :                             if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
     401           0 :                                 aTmpStr.endsWith(TMP_STR_END) )
     402             :                             {
     403           0 :                                 mpFillAttrLB->RemoveEntry(nCount - 1);
     404             :                             }
     405             :                         }
     406           0 :                         aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
     407             : 
     408           0 :                         boost::scoped_ptr<XBitmapEntry> pEntry(new XBitmapEntry(mpBitmapItem->GetGraphicObject(), aTmpStr));
     409             :                         XBitmapListRef xBitmapList =
     410             :                             XPropertyList::AsBitmapList(
     411             :                                 XPropertyList::CreatePropertyList(
     412           0 :                                     XBITMAP_LIST, "TmpList", ""/*TODO?*/));
     413           0 :                         xBitmapList->Insert( pEntry.get() );
     414           0 :                         xBitmapList->SetDirty( false );
     415           0 :                         mpFillAttrLB->Fill( xBitmapList );
     416           0 :                         mpFillAttrLB->SelectEntryPos(mpFillAttrLB->GetEntryCount() - 1);
     417           0 :                         xBitmapList->Remove( 0 );
     418           0 :                     }
     419             :                 }
     420             :                 else
     421             :                 {
     422           0 :                     mpFillAttrLB->SetNoSelection();
     423             :                 }
     424           0 :                 break;
     425             :             }
     426             : 
     427             :             default:
     428             :             {
     429             :                 OSL_FAIL( "Unsupported fill type" );
     430           0 :                 break;
     431             :             }
     432             :         }
     433             : 
     434             :         // update mnLastFillAttrControlSelectEntryPos
     435         123 :         mpFillControl->updateLastFillAttrControlSelectEntryPos();
     436             :     }
     437             : 
     438         330 :     if(pState && mpStyleItem)
     439             :     {
     440         330 :         drawing::FillStyle eXFS = static_cast< drawing::FillStyle >(mpStyleItem->GetValue());
     441             : 
     442             :         // Does the lists have changed?
     443         330 :         switch(eXFS)
     444             :         {
     445             :             case drawing::FillStyle_SOLID:
     446             :             {
     447         330 :                 const SvxColorListItem* pItem = dynamic_cast< const SvxColorListItem* >(pState);
     448             : 
     449         330 :                 if(pItem)
     450             :                 {
     451           0 :                     ::Color aTmpColor(mpFillAttrLB->GetSelectEntryColor());
     452           0 :                     mpFillAttrLB->Clear();
     453           0 :                     mpFillAttrLB->Fill(pItem->GetColorList());
     454           0 :                     mpFillAttrLB->SelectEntry(aTmpColor);
     455             :                 }
     456         330 :                 break;
     457             :             }
     458             :             case drawing::FillStyle_GRADIENT:
     459             :             {
     460           0 :                 const SvxGradientListItem* pItem = dynamic_cast< const SvxGradientListItem* >(pState);
     461             : 
     462           0 :                 if(pItem)
     463             :                 {
     464           0 :                     OUString aString(mpFillAttrLB->GetSelectEntry());
     465           0 :                     mpFillAttrLB->Clear();
     466           0 :                     mpFillAttrLB->Fill(pItem->GetGradientList());
     467           0 :                     mpFillAttrLB->SelectEntry(aString);
     468             :                 }
     469           0 :                 break;
     470             :             }
     471             :             case drawing::FillStyle_HATCH:
     472             :             {
     473           0 :                 const SvxHatchListItem* pItem = dynamic_cast< const SvxHatchListItem* >(pState);
     474             : 
     475           0 :                 if(pItem)
     476             :                 {
     477           0 :                     OUString aString(mpFillAttrLB->GetSelectEntry());
     478           0 :                     mpFillAttrLB->Clear();
     479           0 :                     mpFillAttrLB->Fill(pItem->GetHatchList());
     480           0 :                     mpFillAttrLB->SelectEntry(aString);
     481             :                 }
     482           0 :                 break;
     483             :             }
     484             :             case drawing::FillStyle_BITMAP:
     485             :             {
     486           0 :                 const SvxBitmapListItem* pItem = dynamic_cast< const SvxBitmapListItem* >(pState);
     487             : 
     488           0 :                 if(pItem)
     489             :                 {
     490           0 :                     OUString aString(mpFillAttrLB->GetSelectEntry());
     491           0 :                     mpFillAttrLB->Clear();
     492           0 :                     mpFillAttrLB->Fill(pItem->GetBitmapList());
     493           0 :                     mpFillAttrLB->SelectEntry(aString);
     494             :                 }
     495           0 :                 break;
     496             :             }
     497             :             default: // drawing::FillStyle_NONE
     498             :             {
     499           0 :                 break;
     500             :             }
     501             :         }
     502             :     }
     503         330 : }
     504             : 
     505         126 : vcl::Window* SvxFillToolBoxControl::CreateItemWindow(vcl::Window *pParent)
     506             : {
     507         126 :     if(GetSlotId() == SID_ATTR_FILL_STYLE)
     508             :     {
     509         126 :         mpFillControl = new FillControl(pParent);
     510             :         // Thus the FillControl is known by SvxFillToolBoxControl
     511             :         // (and in order to remain compatible)
     512         126 :         mpFillControl->SetData(this);
     513             : 
     514         126 :         mpFillAttrLB = (SvxFillAttrBox*)mpFillControl->mpLbFillAttr;
     515         126 :         mpFillTypeLB = (SvxFillTypeBox*)mpFillControl->mpLbFillType;
     516             : 
     517         126 :         mpFillAttrLB->SetUniqueId(HID_FILL_ATTR_LISTBOX);
     518         126 :         mpFillTypeLB->SetUniqueId(HID_FILL_TYPE_LISTBOX);
     519             : 
     520         126 :         if(!mpStyleItem)
     521             :         {
     522             :             // for Writer and Calc it's not the same instance of
     523             :             // SvxFillToolBoxControl which gets used after deselecting
     524             :             // and selecting a DrawObject, thhus a useful initialization is
     525             :             // needed to get the FillType and the FillStyle List inited
     526             :             // correctly. This in combination with meLastXFS inited to
     527             :             // drawing::FillStyle_NONE do the trick
     528         126 :             mpStyleItem = new XFillStyleItem(drawing::FillStyle_SOLID);
     529             :         }
     530             : 
     531         126 :         return mpFillControl;
     532             :     }
     533           0 :     return NULL;
     534             : }
     535             : 
     536         126 : FillControl::FillControl(vcl::Window* pParent,WinBits nStyle)
     537             : :   Window(pParent,nStyle | WB_DIALOGCONTROL),
     538         126 :     mpLbFillType(new SvxFillTypeBox(this)),
     539         126 :     mpLbFillAttr(new SvxFillAttrBox(this)),
     540             :     maLogicalFillSize(40,80),
     541             :     maLogicalAttrSize(50,80),
     542         126 :     mnLastFillTypeControlSelectEntryPos(mpLbFillType->GetSelectEntryPos()),
     543         126 :     mnLastFillAttrControlSelectEntryPos(mpLbFillAttr->GetSelectEntryPos()),
     544         630 :     mbFillTypeChanged(false)
     545             : {
     546         126 :     Size aTypeSize(LogicToPixel(maLogicalFillSize,MAP_APPFONT));
     547         126 :     Size aAttrSize(LogicToPixel(maLogicalAttrSize,MAP_APPFONT));
     548         126 :     mpLbFillType->SetSizePixel(aTypeSize);
     549         126 :     mpLbFillAttr->SetSizePixel(aAttrSize);
     550             : 
     551             :     //to get the base height
     552         126 :     aTypeSize = mpLbFillType->GetSizePixel();
     553         126 :     aAttrSize = mpLbFillAttr->GetSizePixel();
     554         126 :     Point aAttrPnt = mpLbFillAttr->GetPosPixel();
     555             :     SetSizePixel(
     556         252 :         Size(aAttrPnt.X() + aAttrSize.Width(),
     557         378 :             std::max(aAttrSize.Height(),aTypeSize.Height())));
     558             : 
     559         126 :     mpLbFillType->SetSelectHdl(LINK(this,FillControl,SelectFillTypeHdl));
     560         126 :     mpLbFillAttr->SetSelectHdl(LINK(this,FillControl,SelectFillAttrHdl));
     561         126 : }
     562             : 
     563         378 : FillControl::~FillControl()
     564             : {
     565         126 :     delete mpLbFillType;
     566         126 :     delete mpLbFillAttr;
     567         252 : }
     568             : 
     569          57 : void FillControl::InitializeFillStyleAccordingToGivenFillType(drawing::FillStyle aFillStyle)
     570             : {
     571          57 :     SfxObjectShell* pSh = SfxObjectShell::Current();
     572          57 :     bool bDone(false);
     573             : 
     574          57 :     if(pSh)
     575             :     {
     576             :         // clear in all cases, else we would risk a mix of FillStyles in the Style list
     577          57 :         mpLbFillAttr->Clear();
     578             : 
     579          57 :         switch (aFillStyle)
     580             :         {
     581             :             case drawing::FillStyle_SOLID:
     582             :             {
     583          57 :                 if(pSh->GetItem(SID_COLOR_TABLE))
     584             :                 {
     585          57 :                     const SvxColorListItem* pItem = static_cast<const SvxColorListItem*>(pSh->GetItem(SID_COLOR_TABLE));
     586          57 :                     mpLbFillAttr->Enable();
     587          57 :                     mpLbFillAttr->Fill(pItem->GetColorList());
     588          57 :                     bDone = true;
     589             :                 }
     590          57 :                 break;
     591             :             }
     592             : 
     593             :             case drawing::FillStyle_GRADIENT:
     594             :             {
     595           0 :                 if(pSh->GetItem(SID_GRADIENT_LIST))
     596             :                 {
     597           0 :                     const SvxGradientListItem* pItem = static_cast< const SvxGradientListItem* >(pSh->GetItem(SID_GRADIENT_LIST));
     598           0 :                     mpLbFillAttr->Enable();
     599           0 :                     mpLbFillAttr->Fill(pItem->GetGradientList());
     600           0 :                     bDone = true;
     601             :                 }
     602           0 :                 break;
     603             :             }
     604             : 
     605             :             case drawing::FillStyle_HATCH:
     606             :             {
     607           0 :                 if(pSh->GetItem(SID_HATCH_LIST))
     608             :                 {
     609           0 :                     const SvxHatchListItem* pItem = static_cast< const SvxHatchListItem* >(pSh->GetItem(SID_HATCH_LIST));
     610           0 :                     mpLbFillAttr->Enable();
     611           0 :                     mpLbFillAttr->Fill(pItem->GetHatchList());
     612           0 :                     bDone = true;
     613             :                 }
     614           0 :                 break;
     615             :             }
     616             : 
     617             :             case drawing::FillStyle_BITMAP:
     618             :             {
     619           0 :                 if(pSh->GetItem(SID_BITMAP_LIST))
     620             :                 {
     621           0 :                     const SvxBitmapListItem* pItem = static_cast< const SvxBitmapListItem* >(pSh->GetItem(SID_BITMAP_LIST));
     622           0 :                     mpLbFillAttr->Enable();
     623           0 :                     mpLbFillAttr->Fill(pItem->GetBitmapList());
     624           0 :                     bDone = true;
     625             :                 }
     626           0 :                 break;
     627             :             }
     628             :             default: // drawing::FillStyle_NONE
     629             :             {
     630             :                 // accept disable (no styles for drawing::FillStyle_NONE)
     631           0 :                 break;
     632             :             }
     633             :         }
     634             :     }
     635             : 
     636          57 :     if (!bDone)
     637             :     {
     638           0 :         mpLbFillAttr->Disable();
     639             :     }
     640          57 : }
     641             : 
     642          57 : void FillControl::updateLastFillTypeControlSelectEntryPos()
     643             : {
     644          57 :     mnLastFillTypeControlSelectEntryPos = mpLbFillType->GetSelectEntryPos();
     645          57 : }
     646             : 
     647           0 : IMPL_LINK(FillControl,SelectFillTypeHdl,ListBox *,pBox)
     648             : {
     649           0 :     if(!pBox) // only work with real calls from ListBox, do not accept direct calls with zeros here
     650             :     {
     651           0 :         return 0;
     652             :     }
     653             : 
     654             :     const bool bAction(
     655           0 :            !mpLbFillType->IsTravelSelect() // keep TravelSelect, this means keyboard up/down in the list
     656           0 :         && mpLbFillType->GetSelectEntryCount()
     657           0 :         && mpLbFillType->GetSelectEntryPos() != mnLastFillTypeControlSelectEntryPos);
     658             : 
     659           0 :     updateLastFillTypeControlSelectEntryPos();
     660           0 :     drawing::FillStyle eXFS = static_cast< drawing::FillStyle >(mpLbFillType->GetSelectEntryPos());
     661             : 
     662           0 :     if(bAction && drawing::FillStyle_NONE != eXFS)
     663             :     {
     664           0 :         mbFillTypeChanged = true;
     665             :     }
     666             : 
     667             :     // update list of FillStyles in any case
     668           0 :     InitializeFillStyleAccordingToGivenFillType(eXFS);
     669             : 
     670             :     // for drawing::FillStyle_NONE do no longer call SelectFillAttrHdl (as done before),
     671             :     // trigger needed actions directly. This is the only action this handler
     672             :     // can trigger directly as the user action is finished in this case
     673           0 :     if(drawing::FillStyle_NONE == eXFS && bAction)
     674             :     {
     675             :         // for drawing::FillStyle_NONE do no longer call SelectFillAttrHdl,
     676             :         // trigger needed actions directly
     677           0 :         Any a;
     678           0 :         Sequence< PropertyValue > aArgsFillStyle(1);
     679           0 :         XFillStyleItem aXFillStyleItem(eXFS);
     680             : 
     681           0 :         aArgsFillStyle[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FillStyle"));
     682           0 :         aXFillStyleItem.QueryValue(a);
     683           0 :         aArgsFillStyle[0].Value = a;
     684           0 :         ((SvxFillToolBoxControl*)GetData())->Dispatch(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:FillStyle")), aArgsFillStyle);
     685             :     }
     686             : 
     687           0 :     mpLbFillType->Selected();
     688             : 
     689             :     // release focus. Needed to get focus automatically back to EditView
     690           0 :     if(mpLbFillType->IsRelease())
     691             :     {
     692           0 :         SfxViewShell* pViewShell = SfxViewShell::Current();
     693             : 
     694           0 :         if(pViewShell && pViewShell->GetWindow())
     695             :         {
     696           0 :             pViewShell->GetWindow()->GrabFocus();
     697             :         }
     698             :     }
     699             : 
     700           0 :     return 0;
     701             : }
     702             : 
     703             : 
     704             : 
     705         123 : void FillControl::updateLastFillAttrControlSelectEntryPos()
     706             : {
     707         123 :     mnLastFillAttrControlSelectEntryPos = mpLbFillAttr->GetSelectEntryPos();
     708         123 : }
     709             : 
     710           0 : IMPL_LINK(FillControl, SelectFillAttrHdl, ListBox *, pBox)
     711             : {
     712           0 :     if(!pBox) // only work with real calls from ListBox, do not accept direct calls with zeros here
     713             :     {
     714           0 :         return 0;
     715             :     }
     716             : 
     717             :     const bool bAction(
     718           0 :            !mpLbFillAttr->IsTravelSelect() // keep TravelSelect, this means keyboard up/down in the list
     719           0 :         && mpLbFillAttr->GetSelectEntryCount()
     720           0 :         && mpLbFillAttr->GetSelectEntryPos() != mnLastFillAttrControlSelectEntryPos);
     721             : 
     722           0 :     updateLastFillAttrControlSelectEntryPos();
     723             : 
     724           0 :     if(bAction)
     725             :     {
     726           0 :         SfxObjectShell* pSh = SfxObjectShell::Current();
     727             : 
     728             :         // Need to prepare the PropertyValue for the FillStyle dispatch action early,
     729             :         // else the call for FillType to Dispatch(".uno:FillStyle") will already destroy the current state
     730             :         // of selection in mpLbFillAttr again by calls to StateChanged which *will* set to no
     731             :         // selection again (e.g. when two objects, same fill style, but different fill attributes)
     732           0 :         Any a;
     733           0 :         Sequence< PropertyValue > aArgsFillAttr(1);
     734           0 :         OUString aFillAttrCommand;
     735           0 :         drawing::FillStyle eXFS(static_cast< drawing::FillStyle >(mpLbFillType->GetSelectEntryPos()));
     736             : 
     737           0 :         switch(eXFS)
     738             :         {
     739             :             default:
     740             :             case drawing::FillStyle_NONE:
     741             :             {
     742             :                 // handled in SelectFillTypeHdl, nothing to do here
     743           0 :                 break;
     744             :             }
     745             : 
     746             :             case drawing::FillStyle_SOLID:
     747             :             {
     748             :                 // Entry gets tested against temporary color
     749           0 :                 OUString aTmpStr = mpLbFillAttr->GetSelectEntry();
     750           0 :                 if( aTmpStr.startsWith(TMP_STR_BEGIN) && aTmpStr.endsWith(TMP_STR_END) )
     751             :                 {
     752           0 :                     aTmpStr = aTmpStr.copy(1, aTmpStr.getLength()-2);
     753             :                 }
     754             : 
     755           0 :                 XFillColorItem aXFillColorItem(aTmpStr, mpLbFillAttr->GetSelectEntryColor());
     756           0 :                 aArgsFillAttr[0].Name = "FillColor";
     757           0 :                 aXFillColorItem.QueryValue(a);
     758           0 :                 aArgsFillAttr[0].Value = a;
     759           0 :                 aFillAttrCommand = ".uno:FillColor";
     760           0 :                 break;
     761             :             }
     762             :             case drawing::FillStyle_GRADIENT:
     763             :             {
     764           0 :                 sal_Int32 nPos = mpLbFillAttr->GetSelectEntryPos();
     765           0 :                 if (nPos != LISTBOX_ENTRY_NOTFOUND && pSh && pSh->GetItem(SID_GRADIENT_LIST))
     766             :                 {
     767           0 :                     const SvxGradientListItem* pItem = static_cast< const SvxGradientListItem* >(pSh->GetItem(SID_GRADIENT_LIST));
     768             : 
     769           0 :                     if (nPos < pItem->GetGradientList()->Count())  // no temporary entry?
     770             :                     {
     771           0 :                         XGradient aGradient = pItem->GetGradientList()->GetGradient(nPos)->GetGradient();
     772           0 :                         XFillGradientItem aXFillGradientItem(mpLbFillAttr->GetSelectEntry(),aGradient);
     773           0 :                         aArgsFillAttr[0].Name = "FillGradient";
     774           0 :                         aXFillGradientItem.QueryValue(a);
     775           0 :                         aArgsFillAttr[0].Value = a;
     776           0 :                         aFillAttrCommand = ".uno:FillGradient";
     777             :                     }
     778             :                 }
     779           0 :                 break;
     780             :             }
     781             : 
     782             :             case drawing::FillStyle_HATCH:
     783             :             {
     784           0 :                 sal_Int32 nPos = mpLbFillAttr->GetSelectEntryPos();
     785           0 :                 if (nPos != LISTBOX_ENTRY_NOTFOUND && pSh && pSh->GetItem(SID_HATCH_LIST))
     786             :                 {
     787           0 :                     const SvxHatchListItem* pItem = static_cast< const SvxHatchListItem* >(pSh->GetItem(SID_HATCH_LIST));
     788             : 
     789           0 :                     if (nPos < pItem->GetHatchList()->Count())  // no temporary entry?
     790             :                     {
     791           0 :                         XHatch aHatch = pItem->GetHatchList()->GetHatch(nPos)->GetHatch();
     792           0 :                         XFillHatchItem aXFillHatchItem(mpLbFillAttr->GetSelectEntry(), aHatch);
     793             : 
     794           0 :                         aArgsFillAttr[0].Name = "FillHatch";
     795           0 :                         aXFillHatchItem.QueryValue(a);
     796           0 :                         aArgsFillAttr[0].Value = a;
     797           0 :                         aFillAttrCommand = ".uno:FillHatch";
     798             :                     }
     799             :                 }
     800           0 :                 break;
     801             :             }
     802             : 
     803             :             case drawing::FillStyle_BITMAP:
     804             :             {
     805           0 :                 sal_Int32 nPos = mpLbFillAttr->GetSelectEntryPos();
     806           0 :                 if (nPos != LISTBOX_ENTRY_NOTFOUND && pSh && pSh->GetItem(SID_BITMAP_LIST))
     807             :                 {
     808           0 :                     const SvxBitmapListItem* pItem = static_cast< const SvxBitmapListItem* >(pSh->GetItem(SID_BITMAP_LIST));
     809             : 
     810           0 :                     if (nPos < pItem->GetBitmapList()->Count())  // no temporary entry?
     811             :                     {
     812           0 :                         const XBitmapEntry* pXBitmapEntry = pItem->GetBitmapList()->GetBitmap(nPos);
     813           0 :                         const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->GetSelectEntry(),pXBitmapEntry->GetGraphicObject());
     814             : 
     815           0 :                         aArgsFillAttr[0].Name = "FillBitmap";
     816           0 :                         aXFillBitmapItem.QueryValue(a);
     817           0 :                         aArgsFillAttr[0].Value = a;
     818           0 :                         aFillAttrCommand = ".uno:FillBitmap";
     819             :                     }
     820             :                 }
     821           0 :                 break;
     822             :             }
     823             :         }
     824             : 
     825             :         // this is the place where evtl. a new slot action may be introduced to avoid the
     826             :         // two undo entries. Reason for this is that indeed two actions are executed, the fill style
     827             :         // and the fill attribute change. The sidebar already handles both separately, so
     828             :         // changing the fill style already changes the object and adds a default fill attribute for
     829             :         // the newly choosen fill style.
     830             :         // This control uses the older user's two-step action to select a fill style and a fill attribute. In
     831             :         // this case a lot of things may go wrong (e.g. the user stops that action and does something
     832             :         // different), thus the solution of the sidebar should be preferred from my POV in the future
     833             : 
     834             :         // first set the fill style if changed
     835           0 :         if(mbFillTypeChanged)
     836             :         {
     837           0 :             Sequence< PropertyValue > aArgsFillStyle(1);
     838           0 :             XFillStyleItem aXFillStyleItem(eXFS);
     839             : 
     840           0 :             aArgsFillStyle[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FillStyle"));
     841           0 :             aXFillStyleItem.QueryValue(a);
     842           0 :             aArgsFillStyle[0].Value = a;
     843           0 :             ((SvxFillToolBoxControl*)GetData())->Dispatch(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:FillStyle")), aArgsFillStyle);
     844           0 :             mbFillTypeChanged = false;
     845             :         }
     846             : 
     847             :         // second set fill attribute when a change was detected and prepared
     848           0 :         if(aFillAttrCommand.getLength())
     849             :         {
     850           0 :             ((SvxFillToolBoxControl*)GetData())->Dispatch(aFillAttrCommand, aArgsFillAttr);
     851             :         }
     852             : 
     853             :         // release focus. Needed to get focus automatically back to EditView
     854           0 :         if(mpLbFillAttr->IsRelease() && pBox)
     855             :         {
     856           0 :             SfxViewShell* pViewShell = SfxViewShell::Current();
     857             : 
     858           0 :             if(pViewShell && pViewShell->GetWindow())
     859             :             {
     860           0 :                 pViewShell->GetWindow()->GrabFocus();
     861             :             }
     862           0 :         }
     863             :     }
     864             : 
     865           0 :     return 0;
     866             : }
     867             : 
     868             : 
     869             : 
     870         126 : void FillControl::Resize()
     871             : {
     872             :     // Width of the two list boxes not 1/2 : 1/2, but 2/5 : 3/5
     873         126 :     long nW = GetOutputSizePixel().Width() / 5;
     874         126 :     long nH = 180;
     875         126 :     long nSep = 0; // was previously 4
     876             : 
     877         126 :     mpLbFillType->SetSizePixel(Size(nW * 2 - nSep,nH));
     878         126 :     mpLbFillAttr->SetPosSizePixel(Point(nW * 2 + nSep,0),Size(nW * 3 - nSep,nH));
     879         126 : }
     880             : 
     881           0 : void FillControl::DataChanged(const DataChangedEvent& rDCEvt)
     882             : {
     883           0 :     if((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
     884           0 :         (rDCEvt.GetFlags() & SETTINGS_STYLE))
     885             :     {
     886           0 :         Size aTypeSize(LogicToPixel(maLogicalFillSize,MAP_APPFONT));
     887           0 :         Size aAttrSize(LogicToPixel(maLogicalAttrSize,MAP_APPFONT));
     888           0 :         mpLbFillType->SetSizePixel(aTypeSize);
     889           0 :         mpLbFillAttr->SetSizePixel(aAttrSize);
     890             : 
     891             :         //to get the base height
     892           0 :         aTypeSize = mpLbFillType->GetSizePixel();
     893           0 :         aAttrSize = mpLbFillAttr->GetSizePixel();
     894           0 :         Point aAttrPnt = mpLbFillAttr->GetPosPixel();
     895             : 
     896             :         SetSizePixel(
     897           0 :             Size(aAttrPnt.X() + aAttrSize.Width(),
     898           0 :                 std::max(aAttrSize.Height(), aTypeSize.Height())));
     899             :     }
     900           0 :     Window::DataChanged(rDCEvt);
     901         594 : }
     902             : 
     903             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10