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