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 <unotools/localedatawrapper.hxx>
21 #include <vcl/field.hxx>
22 
23 #include <colrowba.hxx>
24 #include <document.hxx>
25 #include <scmod.hxx>
26 #include <tabvwsh.hxx>
27 #include <appoptio.hxx>
28 #include <globstr.hrc>
29 #include <scresid.hxx>
30 #include <markdata.hxx>
31 #include <tabview.hxx>
32 #include <columnspanset.hxx>
33 
lcl_MetricString(long nTwips,const OUString & rText)34 static OUString lcl_MetricString( long nTwips, const OUString& rText )
35 {
36     if ( nTwips <= 0 )
37         return ScResId(STR_TIP_HIDE);
38     else
39     {
40         FieldUnit eUserMet = SC_MOD()->GetAppOptions().GetAppMetric();
41 
42         sal_Int64 nUserVal = MetricField::ConvertValue( nTwips*100, 1, 2, FieldUnit::TWIP, eUserMet );
43 
44         OUString aStr = rText + " "
45                         + ScGlobal::pLocaleData->getNum( nUserVal, 2 )
46                         + " " + SdrFormatter::GetUnitStr(eUserMet);
47         return aStr;
48     }
49 }
50 
ScColBar(vcl::Window * pParent,ScHSplitPos eWhich,ScHeaderFunctionSet * pFuncSet,ScHeaderSelectionEngine * pEng,ScTabView * pTab)51 ScColBar::ScColBar( vcl::Window* pParent, ScHSplitPos eWhich,
52                     ScHeaderFunctionSet* pFuncSet, ScHeaderSelectionEngine* pEng,
53                     ScTabView* pTab ) :
54             ScHeaderControl( pParent, pEng, pTab->GetViewData().GetDocument()->MaxCol()+1, false, pTab ),
55             meWhich( eWhich ),
56             mpFuncSet( pFuncSet )
57 {
58     Show();
59 }
60 
~ScColBar()61 ScColBar::~ScColBar()
62 {
63 }
64 
GetPos() const65 SCCOLROW ScColBar::GetPos() const
66 {
67     return pTabView->GetViewData().GetPosX(meWhich);
68 }
69 
GetEntrySize(SCCOLROW nEntryNo) const70 sal_uInt16 ScColBar::GetEntrySize( SCCOLROW nEntryNo ) const
71 {
72     const ScViewData& rViewData = pTabView->GetViewData();
73     ScDocument* pDoc = rViewData.GetDocument();
74     SCTAB nTab = rViewData.GetTabNo();
75     if (pDoc->ColHidden(static_cast<SCCOL>(nEntryNo), nTab))
76         return 0;
77     else
78         return static_cast<sal_uInt16>(ScViewData::ToPixel( pDoc->GetColWidth( static_cast<SCCOL>(nEntryNo), nTab ), rViewData.GetPPTX() ));
79 }
80 
GetEntryText(SCCOLROW nEntryNo) const81 OUString ScColBar::GetEntryText( SCCOLROW nEntryNo ) const
82 {
83     return pTabView->GetViewData().GetDocument()->GetAddressConvention() == formula::FormulaGrammar::CONV_XL_R1C1
84         ? OUString::number(nEntryNo + 1)
85         : ScColToAlpha( static_cast<SCCOL>(nEntryNo) );
86 }
87 
SetEntrySize(SCCOLROW nPos,sal_uInt16 nNewSize)88 void ScColBar::SetEntrySize( SCCOLROW nPos, sal_uInt16 nNewSize )
89 {
90     const ScViewData& rViewData = pTabView->GetViewData();
91     sal_uInt16 nSizeTwips;
92     ScSizeMode eMode = SC_SIZE_DIRECT;
93     if (nNewSize < 10) nNewSize = 10; // pixels
94 
95     if ( nNewSize == HDR_SIZE_OPTIMUM )
96     {
97         nSizeTwips = STD_EXTRA_WIDTH;
98         eMode = SC_SIZE_OPTIMAL;
99     }
100     else
101         nSizeTwips = static_cast<sal_uInt16>( nNewSize / rViewData.GetPPTX() );
102 
103     const ScMarkData& rMark = rViewData.GetMarkData();
104 
105     std::vector<sc::ColRowSpan> aRanges;
106     if ( rMark.IsColumnMarked( static_cast<SCCOL>(nPos) ) )
107     {
108         ScDocument* pDoc = rViewData.GetDocument();
109         SCCOL nStart = 0;
110         while (nStart<=pDoc->MaxCol())
111         {
112             while (nStart<pDoc->MaxCol() && !rMark.IsColumnMarked(nStart))
113                 ++nStart;
114             if (rMark.IsColumnMarked(nStart))
115             {
116                 SCCOL nEnd = nStart;
117                 while (nEnd<pDoc->MaxCol() && rMark.IsColumnMarked(nEnd))
118                     ++nEnd;
119                 if (!rMark.IsColumnMarked(nEnd))
120                     --nEnd;
121                 aRanges.emplace_back(nStart,nEnd);
122                 nStart = nEnd+1;
123             }
124             else
125                 nStart = pDoc->MaxCol()+1;
126         }
127     }
128     else
129     {
130         aRanges.emplace_back(nPos,nPos);
131     }
132 
133     rViewData.GetView()->SetWidthOrHeight(true, aRanges, eMode, nSizeTwips);
134 }
135 
HideEntries(SCCOLROW nStart,SCCOLROW nEnd)136 void ScColBar::HideEntries( SCCOLROW nStart, SCCOLROW nEnd )
137 {
138     std::vector<sc::ColRowSpan> aRanges(1, sc::ColRowSpan(nStart,nEnd));
139     pTabView->GetViewData().GetView()->SetWidthOrHeight(true, aRanges, SC_SIZE_DIRECT, 0);
140 }
141 
SetMarking(bool bSet)142 void ScColBar::SetMarking( bool bSet )
143 {
144     pTabView->GetViewData().GetMarkData().SetMarking( bSet );
145     if (!bSet)
146     {
147         pTabView->GetViewData().GetView()->UpdateAutoFillMark();
148     }
149 }
150 
SelectWindow()151 void ScColBar::SelectWindow()
152 {
153     const ScViewData& rViewData = pTabView->GetViewData();
154     ScTabViewShell* pViewSh = rViewData.GetViewShell();
155 
156     pViewSh->SetActive();           // Appear and SetViewFrame
157     pViewSh->DrawDeselectAll();
158 
159     ScSplitPos eActive = rViewData.GetActivePart();
160     if (meWhich==SC_SPLIT_LEFT)
161     {
162         if (eActive==SC_SPLIT_TOPRIGHT)     eActive=SC_SPLIT_TOPLEFT;
163         if (eActive==SC_SPLIT_BOTTOMRIGHT)  eActive=SC_SPLIT_BOTTOMLEFT;
164     }
165     else
166     {
167         if (eActive==SC_SPLIT_TOPLEFT)      eActive=SC_SPLIT_TOPRIGHT;
168         if (eActive==SC_SPLIT_BOTTOMLEFT)   eActive=SC_SPLIT_BOTTOMRIGHT;
169     }
170     pViewSh->ActivatePart( eActive );
171 
172     mpFuncSet->SetColumn( true );
173     mpFuncSet->SetWhich( eActive );
174 
175     pViewSh->ActiveGrabFocus();
176 }
177 
IsDisabled() const178 bool ScColBar::IsDisabled() const
179 {
180     ScModule* pScMod = SC_MOD();
181     return pScMod->IsModalMode();
182 }
183 
ResizeAllowed() const184 bool ScColBar::ResizeAllowed() const
185 {
186     const ScViewData& rViewData = pTabView->GetViewData();
187     return !rViewData.HasEditView( rViewData.GetActivePart() );
188 }
189 
DrawInvert(long nDragPosP)190 void ScColBar::DrawInvert( long nDragPosP )
191 {
192     tools::Rectangle aRect( nDragPosP,0, nDragPosP+HDR_SLIDERSIZE-1,GetOutputSizePixel().Width()-1 );
193     Update();
194     Invert(aRect);
195 
196     pTabView->GetViewData().GetView()->InvertVertical(meWhich,nDragPosP);
197 }
198 
GetDragHelp(long nVal)199 OUString ScColBar::GetDragHelp( long nVal )
200 {
201     long nTwips = static_cast<long>( nVal / pTabView->GetViewData().GetPPTX() );
202     return lcl_MetricString( nTwips, ScResId(STR_TIP_WIDTH) );
203 }
204 
IsLayoutRTL() const205 bool ScColBar::IsLayoutRTL() const        // override only for columns
206 {
207     const ScViewData& rViewData = pTabView->GetViewData();
208     return rViewData.GetDocument()->IsLayoutRTL( rViewData.GetTabNo() );
209 }
210 
ScRowBar(vcl::Window * pParent,ScVSplitPos eWhich,ScHeaderFunctionSet * pFuncSet,ScHeaderSelectionEngine * pEng,ScTabView * pTab)211 ScRowBar::ScRowBar( vcl::Window* pParent, ScVSplitPos eWhich,
212                     ScHeaderFunctionSet* pFuncSet, ScHeaderSelectionEngine* pEng,
213                     ScTabView* pTab ) :
214             ScHeaderControl( pParent, pEng, pTab->GetViewData().GetDocument()->MaxRow()+1, true, pTab ),
215             meWhich( eWhich ),
216             mpFuncSet( pFuncSet )
217 {
218     Show();
219 }
220 
~ScRowBar()221 ScRowBar::~ScRowBar()
222 {
223 }
224 
GetPos() const225 SCCOLROW ScRowBar::GetPos() const
226 {
227     return pTabView->GetViewData().GetPosY(meWhich);
228 }
229 
GetEntrySize(SCCOLROW nEntryNo) const230 sal_uInt16 ScRowBar::GetEntrySize( SCCOLROW nEntryNo ) const
231 {
232     const ScViewData& rViewData = pTabView->GetViewData();
233     ScDocument* pDoc = rViewData.GetDocument();
234     SCTAB nTab = rViewData.GetTabNo();
235     SCROW nLastRow = -1;
236     if (pDoc->RowHidden(nEntryNo, nTab, nullptr, &nLastRow))
237         return 0;
238     else
239         return static_cast<sal_uInt16>(ScViewData::ToPixel( pDoc->GetOriginalHeight( nEntryNo,
240                     nTab ), rViewData.GetPPTY() ));
241 }
242 
GetEntryText(SCCOLROW nEntryNo) const243 OUString ScRowBar::GetEntryText( SCCOLROW nEntryNo ) const
244 {
245     return OUString::number( nEntryNo + 1 );
246 }
247 
SetEntrySize(SCCOLROW nPos,sal_uInt16 nNewSize)248 void ScRowBar::SetEntrySize( SCCOLROW nPos, sal_uInt16 nNewSize )
249 {
250     const ScViewData& rViewData = pTabView->GetViewData();
251     sal_uInt16 nSizeTwips;
252     ScSizeMode eMode = SC_SIZE_DIRECT;
253     if (nNewSize < 10) nNewSize = 10; // pixels
254 
255     if ( nNewSize == HDR_SIZE_OPTIMUM )
256     {
257         nSizeTwips = 0;
258         eMode = SC_SIZE_OPTIMAL;
259     }
260     else
261         nSizeTwips = static_cast<sal_uInt16>( nNewSize / rViewData.GetPPTY() );
262 
263     const ScMarkData& rMark = rViewData.GetMarkData();
264 
265     std::vector<sc::ColRowSpan> aRanges;
266     if ( rMark.IsRowMarked( nPos ) )
267     {
268         ScDocument* pDoc = rViewData.GetDocument();
269         SCROW nStart = 0;
270         while (nStart<=pDoc->MaxRow())
271         {
272             while (nStart<pDoc->MaxRow() && !rMark.IsRowMarked(nStart))
273                 ++nStart;
274             if (rMark.IsRowMarked(nStart))
275             {
276                 SCROW nEnd = nStart;
277                 while (nEnd<pDoc->MaxRow() && rMark.IsRowMarked(nEnd))
278                     ++nEnd;
279                 if (!rMark.IsRowMarked(nEnd))
280                     --nEnd;
281                 aRanges.emplace_back(nStart,nEnd);
282                 nStart = nEnd+1;
283             }
284             else
285                 nStart = pDoc->MaxRow()+1;
286         }
287     }
288     else
289     {
290         aRanges.emplace_back(nPos,nPos);
291     }
292 
293     rViewData.GetView()->SetWidthOrHeight(false, aRanges, eMode, nSizeTwips);
294 }
295 
HideEntries(SCCOLROW nStart,SCCOLROW nEnd)296 void ScRowBar::HideEntries( SCCOLROW nStart, SCCOLROW nEnd )
297 {
298     std::vector<sc::ColRowSpan> aRange(1, sc::ColRowSpan(nStart,nEnd));
299     pTabView->GetViewData().GetView()->SetWidthOrHeight(false, aRange, SC_SIZE_DIRECT, 0);
300 }
301 
SetMarking(bool bSet)302 void ScRowBar::SetMarking( bool bSet )
303 {
304     pTabView->GetViewData().GetMarkData().SetMarking( bSet );
305     if (!bSet)
306     {
307         pTabView->GetViewData().GetView()->UpdateAutoFillMark();
308     }
309 }
310 
SelectWindow()311 void ScRowBar::SelectWindow()
312 {
313     const ScViewData& rViewData = pTabView->GetViewData();
314     ScTabViewShell* pViewSh = rViewData.GetViewShell();
315 
316     pViewSh->SetActive();           // Appear and SetViewFrame
317     pViewSh->DrawDeselectAll();
318 
319     ScSplitPos eActive = rViewData.GetActivePart();
320     if (meWhich==SC_SPLIT_TOP)
321     {
322         if (eActive==SC_SPLIT_BOTTOMLEFT)   eActive=SC_SPLIT_TOPLEFT;
323         if (eActive==SC_SPLIT_BOTTOMRIGHT)  eActive=SC_SPLIT_TOPRIGHT;
324     }
325     else
326     {
327         if (eActive==SC_SPLIT_TOPLEFT)      eActive=SC_SPLIT_BOTTOMLEFT;
328         if (eActive==SC_SPLIT_TOPRIGHT)     eActive=SC_SPLIT_BOTTOMRIGHT;
329     }
330     pViewSh->ActivatePart( eActive );
331 
332     mpFuncSet->SetColumn( false );
333     mpFuncSet->SetWhich( eActive );
334 
335     pViewSh->ActiveGrabFocus();
336 }
337 
IsDisabled() const338 bool ScRowBar::IsDisabled() const
339 {
340     ScModule* pScMod = SC_MOD();
341     return pScMod->IsModalMode();
342 }
343 
ResizeAllowed() const344 bool ScRowBar::ResizeAllowed() const
345 {
346     const ScViewData& rViewData = pTabView->GetViewData();
347     return !rViewData.HasEditView( rViewData.GetActivePart() );
348 }
349 
DrawInvert(long nDragPosP)350 void ScRowBar::DrawInvert( long nDragPosP )
351 {
352     tools::Rectangle aRect( 0,nDragPosP, GetOutputSizePixel().Width()-1,nDragPosP+HDR_SLIDERSIZE-1 );
353     Update();
354     Invert(aRect);
355 
356     pTabView->GetViewData().GetView()->InvertHorizontal(meWhich,nDragPosP);
357 }
358 
GetDragHelp(long nVal)359 OUString ScRowBar::GetDragHelp( long nVal )
360 {
361     long nTwips = static_cast<long>( nVal / pTabView->GetViewData().GetPPTY() );
362     return lcl_MetricString( nTwips, ScResId(STR_TIP_HEIGHT) );
363 }
364 
GetHiddenCount(SCCOLROW nEntryNo) const365 SCCOLROW ScRowBar::GetHiddenCount( SCCOLROW nEntryNo ) const // override only for rows
366 {
367     const ScViewData& rViewData = pTabView->GetViewData();
368     ScDocument* pDoc = rViewData.GetDocument();
369     SCTAB nTab = rViewData.GetTabNo();
370     return pDoc->GetHiddenRowCount( nEntryNo, nTab );
371 }
372 
IsMirrored() const373 bool ScRowBar::IsMirrored() const // override only for rows
374 {
375     const ScViewData& rViewData = pTabView->GetViewData();
376     return rViewData.GetDocument()->IsLayoutRTL( rViewData.GetTabNo() );
377 }
378 
379 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
380