LCOV - code coverage report
Current view: top level - sfx2/source/dialog - infobar.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 155 186 83.3 %
Date: 2015-06-13 12:38:46 Functions: 27 32 84.4 %
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             : 
      10             : #include <basegfx/polygon/b2dpolygon.hxx>
      11             : #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
      12             : #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
      13             : #include <drawinglayer/processor2d/baseprocessor2d.hxx>
      14             : #include <drawinglayer/processor2d/processorfromoutputdevice.hxx>
      15             : #include <sfx2/bindings.hxx>
      16             : #include <sfx2/dispatch.hxx>
      17             : #include <sfx2/infobar.hxx>
      18             : #include <sfx2/objsh.hxx>
      19             : #include <sfx2/sfx.hrc>
      20             : #include <sfx2/viewsh.hxx>
      21             : #include <vcl/svapp.hxx>
      22             : #include <vcl/settings.hxx>
      23             : 
      24             : using namespace std;
      25             : using namespace drawinglayer::geometry;
      26             : using namespace drawinglayer::processor2d;
      27             : using namespace drawinglayer::primitive2d;
      28             : using namespace drawinglayer::attribute;
      29             : using namespace drawinglayer::geometry;
      30             : using namespace basegfx;
      31             : 
      32             : namespace
      33             : {
      34             : 
      35             : const long INFO_BAR_BASE_HEIGHT = 40;
      36             : 
      37         216 : const BColor constLightColor(1.0, 1.0, 191.0 / 255.0);
      38         216 : const BColor constDarkColor(217.0 / 255.0, 217.0 / 255.0, 78.0 / 255.0);
      39             : 
      40           6 : void lclDetermineLightDarkColor(BColor& rLightColor, BColor& rDarkColor)
      41             : {
      42           6 :     const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
      43           6 :     if (rSettings.GetHighContrastMode())
      44             :     {
      45           0 :         rLightColor = rSettings.GetLightColor().getBColor();
      46           0 :         rDarkColor = rSettings.GetDialogTextColor().getBColor();
      47             :     }
      48             :     else
      49             :     {
      50           6 :         rLightColor = constLightColor;
      51           6 :         rDarkColor = constDarkColor;
      52             :     }
      53           6 : }
      54             : 
      55             : class SfxCloseButton : public PushButton
      56             : {
      57             : public:
      58           1 :     SfxCloseButton(vcl::Window* pParent) : PushButton(pParent, 0)
      59           1 :     {}
      60             : 
      61           2 :     virtual ~SfxCloseButton() {}
      62             : 
      63             :     virtual void Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect) SAL_OVERRIDE;
      64             : };
      65             : 
      66           3 : void SfxCloseButton::Paint(vcl::RenderContext& rRenderContext, const Rectangle&)
      67             : {
      68           3 :     const ViewInformation2D aNewViewInfos;
      69             :     const unique_ptr<BaseProcessor2D> pProcessor(
      70           6 :                 createBaseProcessor2DFromOutputDevice(rRenderContext, aNewViewInfos));
      71             : 
      72           3 :     const Rectangle aRect(Point(0, 0), PixelToLogic(GetSizePixel()));
      73             : 
      74           6 :     drawinglayer::primitive2d::Primitive2DSequence aSeq(2);
      75             : 
      76           6 :     BColor aLightColor;
      77           6 :     BColor aDarkColor;
      78           3 :     lclDetermineLightDarkColor(aLightColor, aDarkColor);
      79             : 
      80             :     // Light background
      81           6 :     B2DPolygon aPolygon;
      82           3 :     aPolygon.append(B2DPoint(aRect.Left(), aRect.Top()));
      83           3 :     aPolygon.append(B2DPoint(aRect.Right(), aRect.Top()));
      84           3 :     aPolygon.append(B2DPoint(aRect.Right(), aRect.Bottom()));
      85           3 :     aPolygon.append(B2DPoint(aRect.Left(), aRect.Bottom()));
      86           3 :     aPolygon.setClosed(true);
      87             : 
      88             :     PolyPolygonColorPrimitive2D* pBack =
      89           3 :         new PolyPolygonColorPrimitive2D(B2DPolyPolygon(aPolygon), aLightColor);
      90           3 :     aSeq[0] = pBack;
      91             : 
      92           6 :     LineAttribute aLineAttribute(aDarkColor, 2.0);
      93             : 
      94             :     // Cross
      95           6 :     B2DPolyPolygon aCross;
      96             : 
      97           6 :     B2DPolygon aLine1;
      98           3 :     aLine1.append(B2DPoint(aRect.Left(), aRect.Top()));
      99           3 :     aLine1.append(B2DPoint(aRect.Right(), aRect.Bottom()));
     100           3 :     aCross.append(aLine1);
     101             : 
     102           6 :     B2DPolygon aLine2;
     103           3 :     aLine2.append(B2DPoint(aRect.Right(), aRect.Top()));
     104           3 :     aLine2.append(B2DPoint(aRect.Left(), aRect.Bottom()));
     105           3 :     aCross.append(aLine2);
     106             : 
     107             :     PolyPolygonStrokePrimitive2D* pCross =
     108           3 :         new PolyPolygonStrokePrimitive2D(aCross, aLineAttribute, StrokeAttribute());
     109             : 
     110           3 :     aSeq[1] = pCross;
     111             : 
     112           6 :     pProcessor->process(aSeq);
     113           3 : }
     114             : 
     115             : } // anonymous namespace
     116             : 
     117           1 : SfxInfoBarWindow::SfxInfoBarWindow(vcl::Window* pParent, const OUString& sId,
     118             :        const OUString& sMessage) :
     119             :     Window(pParent, 0),
     120             :     m_sId(sId),
     121             :     m_pMessage(VclPtr<FixedText>::Create(this, 0)),
     122             :     m_pCloseBtn(VclPtr<SfxCloseButton>::Create(this)),
     123           1 :     m_aActionBtns()
     124             : {
     125           1 :     sal_Int32 nScaleFactor = GetDPIScaleFactor();
     126           1 :     long nWidth = pParent->GetSizePixel().getWidth();
     127           1 :     SetPosSizePixel(Point(0, 0), Size(nWidth, INFO_BAR_BASE_HEIGHT * nScaleFactor));
     128             : 
     129           1 :     m_pMessage->SetText(sMessage);
     130           1 :     m_pMessage->SetBackground(Wallpaper(Color(constLightColor)));
     131           1 :     m_pMessage->Show();
     132             : 
     133           1 :     m_pCloseBtn->SetClickHdl(LINK(this, SfxInfoBarWindow, CloseHandler));
     134           1 :     m_pCloseBtn->Show();
     135             : 
     136           1 :     Resize();
     137           1 : }
     138             : 
     139           1 : void SfxInfoBarWindow::addButton(PushButton* pButton) {
     140           1 :     pButton->SetParent(this);
     141           1 :     pButton->Show();
     142           1 :     m_aActionBtns.push_back(pButton);
     143           1 :     Resize();
     144           1 : }
     145             : 
     146           3 : SfxInfoBarWindow::~SfxInfoBarWindow()
     147             : {
     148           1 :     disposeOnce();
     149           2 : }
     150             : 
     151           1 : void SfxInfoBarWindow::dispose()
     152             : {
     153           2 :     for ( auto it = m_aActionBtns.begin( ); it != m_aActionBtns.end( ); ++it )
     154           1 :         it->disposeAndClear();
     155             : 
     156           1 :     m_pMessage.disposeAndClear();
     157           1 :     m_pCloseBtn.disposeAndClear();
     158           1 :     m_aActionBtns.clear( );
     159           1 :     vcl::Window::dispose();
     160           1 : }
     161             : 
     162           3 : void SfxInfoBarWindow::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rPaintRect)
     163             : {
     164           3 :     const ViewInformation2D aNewViewInfos;
     165             :     const unique_ptr<BaseProcessor2D> pProcessor(
     166           6 :                 createBaseProcessor2DFromOutputDevice(rRenderContext, aNewViewInfos));
     167             : 
     168           3 :     const Rectangle aRect(Point(0, 0), PixelToLogic(GetSizePixel()));
     169             : 
     170           6 :     drawinglayer::primitive2d::Primitive2DSequence aSeq(2);
     171             : 
     172           6 :     BColor aLightColor;
     173           6 :     BColor aDarkColor;
     174           3 :     lclDetermineLightDarkColor(aLightColor, aDarkColor);
     175             : 
     176             :     // Update the label background color
     177           3 :     m_pMessage->SetBackground(Wallpaper(Color(aLightColor)));
     178             : 
     179             :     // Light background
     180           6 :     B2DPolygon aPolygon;
     181           3 :     aPolygon.append(B2DPoint(aRect.Left(), aRect.Top()));
     182           3 :     aPolygon.append(B2DPoint(aRect.Right(), aRect.Top()));
     183           3 :     aPolygon.append(B2DPoint(aRect.Right(), aRect.Bottom()));
     184           3 :     aPolygon.append(B2DPoint(aRect.Left(), aRect.Bottom()));
     185           3 :     aPolygon.setClosed(true);
     186             : 
     187             :     PolyPolygonColorPrimitive2D* pBack =
     188           3 :         new PolyPolygonColorPrimitive2D(B2DPolyPolygon(aPolygon), aLightColor);
     189           3 :     aSeq[0] = pBack;
     190             : 
     191           6 :     LineAttribute aLineAttribute(aDarkColor, 1.0);
     192             : 
     193             :     // Bottom dark line
     194           6 :     B2DPolygon aPolygonBottom;
     195           3 :     aPolygonBottom.append(B2DPoint(aRect.Left(), aRect.Bottom()));
     196           3 :     aPolygonBottom.append(B2DPoint(aRect.Right(), aRect.Bottom()));
     197             : 
     198             :     PolygonStrokePrimitive2D* pLineBottom =
     199           3 :             new PolygonStrokePrimitive2D (aPolygonBottom, aLineAttribute);
     200             : 
     201           3 :     aSeq[1] = pLineBottom;
     202             : 
     203           3 :     pProcessor->process(aSeq);
     204             : 
     205           6 :     Window::Paint(rRenderContext, rPaintRect);
     206           3 : }
     207             : 
     208           4 : void SfxInfoBarWindow::Resize()
     209             : {
     210           4 :     sal_Int32 nScaleFactor = GetDPIScaleFactor();
     211             : 
     212           4 :     long nWidth = GetSizePixel().getWidth();
     213           4 :     m_pCloseBtn->SetPosSizePixel(Point(nWidth - 25 * nScaleFactor, 15 * nScaleFactor), Size(10 * nScaleFactor, 10 * nScaleFactor));
     214             : 
     215             :     // Reparent the buttons and place them on the right of the bar
     216           4 :     long nX = m_pCloseBtn->GetPosPixel().getX() - 15 * nScaleFactor;
     217           4 :     long nButtonGap = 5 * nScaleFactor;
     218             : 
     219           5 :     for (auto it = m_aActionBtns.begin(); it != m_aActionBtns.end(); ++it)
     220             :     {
     221           1 :         long nButtonWidth = (*it)->GetSizePixel().getWidth();
     222           1 :         nX -= nButtonWidth;
     223           1 :         (*it)->SetPosSizePixel(Point(nX, 5 * nScaleFactor), Size(nButtonWidth, 30 * nScaleFactor));
     224           1 :         nX -= nButtonGap;
     225             :     }
     226             : 
     227           4 :     Point aMessagePosition(10 * nScaleFactor, 10 * nScaleFactor);
     228           4 :     Size aMessageSize(nX - 20 * nScaleFactor, 20 * nScaleFactor);
     229             : 
     230           4 :     m_pMessage->SetPosSizePixel(aMessagePosition, aMessageSize);
     231           4 : }
     232             : 
     233           0 : IMPL_LINK_NOARG(SfxInfoBarWindow, CloseHandler)
     234             : {
     235           0 :     static_cast<SfxInfoBarContainerWindow*>(GetParent())->removeInfoBar(this);
     236           0 :     return 0;
     237             : }
     238             : 
     239        3157 : SfxInfoBarContainerWindow::SfxInfoBarContainerWindow(SfxInfoBarContainerChild* pChildWin ) :
     240             :     Window(pChildWin->GetParent(), 0),
     241             :     m_pChildWin(pChildWin),
     242        3157 :     m_pInfoBars()
     243             : {
     244        3157 : }
     245             : 
     246        9459 : SfxInfoBarContainerWindow::~SfxInfoBarContainerWindow()
     247             : {
     248        3153 :     disposeOnce();
     249        6306 : }
     250             : 
     251        3153 : void SfxInfoBarContainerWindow::dispose()
     252             : {
     253        3154 :     for ( auto it = m_pInfoBars.begin( ); it != m_pInfoBars.end( ); ++it )
     254           1 :         it->disposeAndClear();
     255        3153 :     m_pInfoBars.clear( );
     256        3153 :     Window::dispose();
     257        3153 : }
     258             : 
     259           1 : SfxInfoBarWindow* SfxInfoBarContainerWindow::appendInfoBar(const OUString& sId, const OUString& sMessage)
     260             : {
     261           1 :     Size aSize = GetSizePixel();
     262             : 
     263           1 :     VclPtrInstance<SfxInfoBarWindow> pInfoBar(this, sId, sMessage);
     264           1 :     pInfoBar->SetPosPixel(Point(0, aSize.getHeight()));
     265           1 :     pInfoBar->Show();
     266           1 :     m_pInfoBars.push_back(pInfoBar);
     267             : 
     268           1 :     long nHeight = pInfoBar->GetSizePixel().getHeight();
     269           1 :     aSize.setHeight(aSize.getHeight() + nHeight);
     270           1 :     SetSizePixel(aSize);
     271           1 :     return pInfoBar;
     272             : }
     273             : 
     274           0 : SfxInfoBarWindow* SfxInfoBarContainerWindow::getInfoBar(const OUString& sId)
     275             : {
     276           0 :     for (auto it = m_pInfoBars.begin(); it != m_pInfoBars.end(); ++it)
     277             :     {
     278           0 :         if ((*it)->getId() == sId)
     279           0 :             return it->get();
     280             :     }
     281           0 :     return NULL;
     282             : }
     283             : 
     284           0 : void SfxInfoBarContainerWindow::removeInfoBar(SfxInfoBarWindow* pInfoBar)
     285             : {
     286             :     // Store a VclPtr to the pInfoBar while we remove it from m_pInfoBars
     287           0 :     ScopedVclPtr<SfxInfoBarWindow> pTmp(pInfoBar);
     288             : 
     289             :     // Remove
     290           0 :     for (auto it = m_pInfoBars.begin(); it != m_pInfoBars.end(); ++it)
     291             :     {
     292           0 :         if (pInfoBar == it->get())
     293             :         {
     294           0 :             it->disposeAndClear();
     295           0 :             m_pInfoBars.erase(it);
     296           0 :             break;
     297             :         }
     298             :     }
     299             : 
     300             :     // Resize
     301           0 :     long nY = 0;
     302           0 :     for (auto it = m_pInfoBars.begin(); it != m_pInfoBars.end(); ++it)
     303             :     {
     304           0 :         (*it)->SetPosPixel(Point(0, nY));
     305           0 :         nY += (*it)->GetSizePixel().getHeight();
     306             :     }
     307             : 
     308           0 :     Size aSize = GetSizePixel();
     309           0 :     aSize.setHeight(nY);
     310           0 :     SetSizePixel(aSize);
     311             : 
     312           0 :     m_pChildWin->Update();
     313           0 : }
     314             : 
     315        6522 : void SfxInfoBarContainerWindow::Resize()
     316             : {
     317             :     // Only need to change the width of the infobars
     318        6522 :     long nWidth = GetSizePixel().getWidth();
     319             : 
     320        6523 :     for (auto it = m_pInfoBars.begin(); it != m_pInfoBars.end(); ++it)
     321             :     {
     322           1 :         Size aSize = (*it)->GetSizePixel();
     323           1 :         aSize.setWidth(nWidth);
     324           1 :         (*it)->SetSizePixel(aSize);
     325           1 :         (*it)->Resize();
     326             :     }
     327        6522 : }
     328             : 
     329        3599 : SFX_IMPL_POS_CHILDWINDOW_WITHID(SfxInfoBarContainerChild, SID_INFOBAR, SFX_OBJECTBAR_OBJECT);
     330             : 
     331        3157 : SfxInfoBarContainerChild::SfxInfoBarContainerChild( vcl::Window* _pParent, sal_uInt16 nId, SfxBindings* pBindings, SfxChildWinInfo* ) :
     332             :     SfxChildWindow(_pParent, nId),
     333        3157 :     m_pBindings(pBindings)
     334             : {
     335        3157 :     pWindow = VclPtr<SfxInfoBarContainerWindow>::Create(this);
     336        3157 :     pWindow->SetPosSizePixel(Point(0, 0), Size(_pParent->GetSizePixel().getWidth(), 0));
     337        3157 :     pWindow->Show();
     338             : 
     339        3157 :     eChildAlignment = SfxChildAlignment::LOWESTTOP;
     340        3157 : }
     341             : 
     342        6306 : SfxInfoBarContainerChild::~SfxInfoBarContainerChild()
     343             : {
     344        6306 : }
     345             : 
     346        3166 : SfxChildWinInfo SfxInfoBarContainerChild::GetInfo() const
     347             : {
     348        3166 :     SfxChildWinInfo aInfo = SfxChildWindow::GetInfo();
     349        3166 :     return aInfo;
     350             : }
     351             : 
     352           0 : void SfxInfoBarContainerChild::Update()
     353             : {
     354             :     // Refresh the frame to take the infobars container height change into account
     355           0 :     const sal_uInt16 nId = GetChildWindowId();
     356           0 :     SfxViewFrame* pVFrame = m_pBindings->GetDispatcher()->GetFrame();
     357           0 :     pVFrame->ShowChildWindow(nId);
     358             : 
     359             :     // Give the focus to the document view
     360           0 :     pVFrame->GetWindow().GrabFocusToDocument();
     361         648 : }
     362             : 
     363             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11