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 "condformatdlg.hxx"
11 : #include "condformatdlg.hrc"
12 :
13 : #include <vcl/vclevent.hxx>
14 : #include <svl/style.hxx>
15 : #include <sfx2/dispatch.hxx>
16 : #include <svl/stritem.hxx>
17 : #include <svl/intitem.hxx>
18 : #include <svx/xtable.hxx>
19 : #include <svx/drawitem.hxx>
20 : #include <vcl/msgbox.hxx>
21 :
22 : #include "anyrefdg.hxx"
23 : #include "document.hxx"
24 : #include "conditio.hxx"
25 : #include "stlpool.hxx"
26 : #include "tabvwsh.hxx"
27 : #include "colorscale.hxx"
28 : #include "colorformat.hxx"
29 : #include "reffact.hxx"
30 : #include "docsh.hxx"
31 : #include "docfunc.hxx"
32 : #include "condformatdlgentry.hxx"
33 :
34 : #include "globstr.hrc"
35 :
36 0 : ScCondFormatList::ScCondFormatList(Window* pParent, const ResId& rResId, ScDocument* pDoc, const ScConditionalFormat* pFormat,
37 : const ScRangeList& rRanges, const ScAddress& rPos, condformat::dialog::ScCondFormatDialogType eType):
38 : Control(pParent, rResId),
39 : mbHasScrollBar(false),
40 0 : mpScrollBar(new ScrollBar(this, WB_VERT )),
41 : mpDoc(pDoc),
42 : maPos(rPos),
43 0 : maRanges(rRanges)
44 : {
45 0 : mpScrollBar->SetScrollHdl( LINK( this, ScCondFormatList, ScrollHdl ) );
46 0 : mpScrollBar->EnableDrag();
47 :
48 0 : if(pFormat)
49 : {
50 0 : size_t nCount = pFormat->size();
51 0 : for (size_t nIndex = 0; nIndex < nCount; ++nIndex)
52 : {
53 0 : const ScFormatEntry* pEntry = pFormat->GetEntry(nIndex);
54 0 : switch(pEntry->GetType())
55 : {
56 : case condformat::CONDITION:
57 : {
58 0 : const ScCondFormatEntry* pConditionEntry = static_cast<const ScCondFormatEntry*>( pEntry );
59 0 : if(pConditionEntry->GetOperation() != SC_COND_DIRECT)
60 0 : maEntries.push_back(new ScConditionFrmtEntry( this, mpDoc, maPos, pConditionEntry ) );
61 : else
62 0 : maEntries.push_back(new ScFormulaFrmtEntry( this, mpDoc, maPos, pConditionEntry ) );
63 :
64 : }
65 0 : break;
66 : case condformat::COLORSCALE:
67 : {
68 0 : const ScColorScaleFormat* pColorScale = static_cast<const ScColorScaleFormat*>( pEntry );
69 0 : if( pColorScale->size() == 2 )
70 0 : maEntries.push_back(new ScColorScale2FrmtEntry( this, mpDoc, maPos, pColorScale ) );
71 : else
72 0 : maEntries.push_back(new ScColorScale3FrmtEntry( this, mpDoc, maPos, pColorScale ) );
73 : }
74 0 : break;
75 : case condformat::DATABAR:
76 0 : maEntries.push_back(new ScDataBarFrmtEntry( this, mpDoc, maPos, static_cast<const ScDataBarFormat*>( pEntry ) ) );
77 0 : break;
78 : case condformat::ICONSET:
79 0 : maEntries.push_back(new ScIconSetFrmtEntry( this, mpDoc, maPos, static_cast<const ScIconSetFormat*>( pEntry ) ) );
80 0 : break;
81 : case condformat::DATE:
82 0 : maEntries.push_back(new ScDateFrmtEntry( this, mpDoc, static_cast<const ScCondDateFormatEntry*>( pEntry ) ) );
83 0 : break;
84 : }
85 : }
86 0 : if(nCount)
87 0 : EntrySelectHdl(&maEntries[0]);
88 : }
89 : else
90 : {
91 0 : switch(eType)
92 : {
93 : case condformat::dialog::CONDITION:
94 0 : maEntries.push_back(new ScConditionFrmtEntry( this, mpDoc, maPos ));
95 0 : break;
96 : case condformat::dialog::COLORSCALE:
97 0 : maEntries.push_back(new ScColorScale3FrmtEntry( this, mpDoc, maPos ));
98 0 : break;
99 : case condformat::dialog::DATABAR:
100 0 : maEntries.push_back(new ScDataBarFrmtEntry( this, mpDoc, maPos ));
101 0 : break;
102 : case condformat::dialog::ICONSET:
103 0 : maEntries.push_back(new ScIconSetFrmtEntry( this, mpDoc, maPos ));
104 0 : break;
105 : case condformat::dialog::DATE:
106 0 : maEntries.push_back(new ScDateFrmtEntry( this, mpDoc ));
107 0 : break;
108 : case condformat::dialog::NONE:
109 0 : break;
110 : }
111 : }
112 0 : RecalcAll();
113 0 : if (!maEntries.empty())
114 0 : maEntries.begin()->SetActive();
115 :
116 0 : RecalcAll();
117 0 : }
118 :
119 0 : ScConditionalFormat* ScCondFormatList::GetConditionalFormat() const
120 : {
121 0 : if(maEntries.empty())
122 0 : return NULL;
123 :
124 0 : ScConditionalFormat* pFormat = new ScConditionalFormat(0, mpDoc);
125 0 : for(EntryContainer::const_iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
126 : {
127 0 : ScFormatEntry* pEntry = itr->GetEntry();
128 0 : if(pEntry)
129 0 : pFormat->AddEntry(pEntry);
130 : }
131 :
132 0 : pFormat->AddRange(maRanges);
133 :
134 0 : return pFormat;
135 : }
136 :
137 0 : void ScCondFormatList::RecalcAll()
138 : {
139 0 : sal_Int32 nTotalHeight = 0;
140 0 : sal_Int32 nIndex = 1;
141 0 : for(EntryContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
142 : {
143 0 : nTotalHeight += itr->GetSizePixel().Height();
144 0 : itr->SetIndex( nIndex );
145 0 : ++nIndex;
146 : }
147 :
148 0 : Size aCtrlSize = GetOutputSize();
149 0 : long nSrcBarSize = GetSettings().GetStyleSettings().GetScrollBarSize();
150 0 : if(nTotalHeight > GetSizePixel().Height())
151 : {
152 0 : mbHasScrollBar = true;
153 0 : mpScrollBar->SetPosSizePixel(Point(aCtrlSize.Width() -nSrcBarSize, 0),
154 0 : Size(nSrcBarSize, aCtrlSize.Height()) );
155 0 : mpScrollBar->SetRangeMax(nTotalHeight);
156 0 : mpScrollBar->SetVisibleSize(aCtrlSize.Height());
157 0 : mpScrollBar->Show();
158 : }
159 : else
160 : {
161 0 : mbHasScrollBar = false;
162 0 : mpScrollBar->Hide();
163 : }
164 :
165 0 : Point aPoint(0,-1*mpScrollBar->GetThumbPos());
166 0 : for(EntryContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
167 : {
168 0 : itr->SetPosPixel(aPoint);
169 0 : Size aSize = itr->GetSizePixel();
170 0 : if(mbHasScrollBar)
171 0 : aSize.Width() = aCtrlSize.Width() - nSrcBarSize;
172 : else
173 0 : aSize.Width() = aCtrlSize.Width();
174 0 : itr->SetSizePixel(aSize);
175 :
176 0 : aPoint.Y() += itr->GetSizePixel().Height();
177 : }
178 0 : }
179 :
180 0 : void ScCondFormatList::DoScroll(long nDelta)
181 : {
182 0 : Point aNewPoint = mpScrollBar->GetPosPixel();
183 0 : Rectangle aRect(Point(), GetOutputSize());
184 0 : aRect.Right() -= mpScrollBar->GetSizePixel().Width();
185 0 : Scroll( 0, -nDelta, aRect );
186 0 : mpScrollBar->SetPosPixel(aNewPoint);
187 0 : }
188 :
189 0 : IMPL_LINK(ScCondFormatList, ColFormatTypeHdl, ListBox*, pBox)
190 : {
191 0 : EntryContainer::iterator itr = maEntries.begin();
192 0 : for(; itr != maEntries.end(); ++itr)
193 : {
194 0 : if(itr->IsSelected())
195 0 : break;
196 : }
197 0 : if(itr == maEntries.end())
198 0 : return 0;
199 :
200 0 : sal_Int32 nPos = pBox->GetSelectEntryPos();
201 0 : switch(nPos)
202 : {
203 : case 0:
204 0 : if(itr->GetType() == condformat::entry::COLORSCALE2)
205 0 : return 0;
206 :
207 0 : maEntries.replace( itr, new ScColorScale2FrmtEntry( this, mpDoc, maPos ) );
208 0 : break;
209 : case 1:
210 0 : if(itr->GetType() == condformat::entry::COLORSCALE3)
211 0 : return 0;
212 :
213 0 : maEntries.replace( itr, new ScColorScale3FrmtEntry( this, mpDoc, maPos ) );
214 0 : break;
215 : case 2:
216 0 : if(itr->GetType() == condformat::entry::DATABAR)
217 0 : return 0;
218 :
219 0 : maEntries.replace( itr, new ScDataBarFrmtEntry( this, mpDoc, maPos ) );
220 0 : break;
221 : case 3:
222 0 : if(itr->GetType() == condformat::entry::ICONSET)
223 0 : return 0;
224 :
225 0 : maEntries.replace( itr, new ScIconSetFrmtEntry( this, mpDoc, maPos ) );
226 0 : break;
227 : default:
228 0 : break;
229 : }
230 0 : static_cast<ScCondFormatDlg*>(GetParent())->InvalidateRefData();
231 0 : itr->SetActive();
232 0 : RecalcAll();
233 0 : return 0;
234 : }
235 :
236 0 : IMPL_LINK(ScCondFormatList, TypeListHdl, ListBox*, pBox)
237 : {
238 0 : EntryContainer::iterator itr = maEntries.begin();
239 0 : for(; itr != maEntries.end(); ++itr)
240 : {
241 0 : if(itr->IsSelected())
242 0 : break;
243 : }
244 0 : if(itr == maEntries.end())
245 0 : return 0;;
246 :
247 0 : sal_Int32 nPos = pBox->GetSelectEntryPos();
248 0 : switch(nPos)
249 : {
250 : case 0:
251 0 : switch(itr->GetType())
252 : {
253 : case condformat::entry::FORMULA:
254 : case condformat::entry::CONDITION:
255 : case condformat::entry::DATE:
256 0 : break;
257 : case condformat::entry::COLORSCALE2:
258 : case condformat::entry::COLORSCALE3:
259 : case condformat::entry::DATABAR:
260 : case condformat::entry::ICONSET:
261 0 : return 0;
262 : }
263 0 : maEntries.replace( itr, new ScColorScale3FrmtEntry(this, mpDoc, maPos));
264 0 : static_cast<ScCondFormatDlg*>(GetParent())->InvalidateRefData();
265 0 : itr->SetActive();
266 0 : break;
267 : case 1:
268 0 : if(itr->GetType() == condformat::entry::CONDITION)
269 0 : return 0;
270 :
271 0 : maEntries.replace( itr, new ScConditionFrmtEntry(this, mpDoc, maPos));
272 0 : static_cast<ScCondFormatDlg*>(GetParent())->InvalidateRefData();
273 0 : itr->SetActive();
274 0 : break;
275 : case 2:
276 0 : if(itr->GetType() == condformat::entry::FORMULA)
277 0 : return 0;
278 :
279 0 : maEntries.replace( itr, new ScFormulaFrmtEntry(this, mpDoc, maPos));
280 0 : static_cast<ScCondFormatDlg*>(GetParent())->InvalidateRefData();
281 0 : itr->SetActive();
282 0 : break;
283 : case 3:
284 0 : if(itr->GetType() == condformat::entry::DATE)
285 0 : return 0;
286 :
287 0 : maEntries.replace( itr, new ScDateFrmtEntry( this, mpDoc ));
288 0 : static_cast<ScCondFormatDlg*>(GetParent())->InvalidateRefData();
289 0 : itr->SetActive();
290 0 : break;
291 :
292 : }
293 0 : RecalcAll();
294 0 : return 0;
295 : }
296 :
297 0 : IMPL_LINK_NOARG( ScCondFormatList, AddBtnHdl )
298 : {
299 0 : ScCondFrmtEntry* pNewEntry = new ScConditionFrmtEntry(this, mpDoc, maPos);
300 0 : maEntries.push_back( pNewEntry );
301 0 : for(EntryContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
302 : {
303 0 : itr->SetInactive();
304 : }
305 0 : static_cast<ScCondFormatDlg*>(GetParent())->InvalidateRefData();
306 0 : pNewEntry->SetActive();
307 0 : RecalcAll();
308 0 : return 0;
309 : }
310 :
311 0 : IMPL_LINK_NOARG( ScCondFormatList, RemoveBtnHdl )
312 : {
313 0 : for(EntryContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
314 : {
315 0 : if(itr->IsSelected())
316 : {
317 0 : maEntries.erase(itr);
318 0 : break;
319 : }
320 : }
321 0 : static_cast<ScCondFormatDlg*>(GetParent())->InvalidateRefData();
322 0 : RecalcAll();
323 0 : return 0;
324 : }
325 :
326 0 : IMPL_LINK( ScCondFormatList, EntrySelectHdl, ScCondFrmtEntry*, pEntry )
327 : {
328 0 : if(pEntry->IsSelected())
329 0 : return 0;
330 :
331 : //A child has focus, but we will hide that, so regrab to whatever new thing gets
332 : //shown instead of leaving it stuck in the inaccessible hidden element
333 0 : bool bReGrabFocus = HasChildPathFocus();
334 0 : for(EntryContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
335 : {
336 0 : itr->SetInactive();
337 : }
338 0 : static_cast<ScCondFormatDlg*>(GetParent())->InvalidateRefData();
339 0 : pEntry->SetActive();
340 0 : RecalcAll();
341 0 : if (bReGrabFocus)
342 0 : GrabFocus();
343 0 : return 0;
344 : }
345 :
346 0 : IMPL_LINK_NOARG( ScCondFormatList, ScrollHdl )
347 : {
348 0 : DoScroll(mpScrollBar->GetDelta());
349 0 : return 0;
350 : }
351 :
352 : //---------------------------------------------------
353 : //ScCondFormatDlg
354 : //---------------------------------------------------
355 :
356 0 : ScCondFormatDlg::ScCondFormatDlg(Window* pParent, ScDocument* pDoc, const ScConditionalFormat* pFormat, const ScRangeList& rRange,
357 : const ScAddress& rPos, condformat::dialog::ScCondFormatDialogType eType):
358 : ScAnyRefModalDlg(pParent, ScResId(RID_SCDLG_CONDFORMAT) ),
359 : maBtnAdd( this, ScResId( BTN_ADD ) ),
360 : maBtnRemove( this, ScResId( BTN_REMOVE ) ),
361 : maFtRange( this, ScResId( FT_RANGE ) ),
362 : maEdRange( this, this, &maFtRange, ScResId( ED_RANGE ) ),
363 : maRbRange( this, ScResId( RB_RANGE ), &maEdRange, this ),
364 : maBtnOk( this, ScResId( BTN_OK ) ),
365 : maBtnCancel( this, ScResId( BTN_CANCEL ) ),
366 : maCondFormList( this, ScResId( CTRL_LIST ), pDoc, pFormat, rRange, rPos, eType ),
367 : maPos(rPos),
368 : mpDoc(pDoc),
369 0 : mpLastEdit(NULL)
370 : {
371 0 : OUStringBuffer aTitle( GetText() );
372 0 : aTitle.append(OUString(" "));
373 0 : OUString aRangeString;
374 0 : rRange.Format(aRangeString, SCA_VALID, pDoc, pDoc->GetAddressConvention());
375 0 : aTitle.append(aRangeString);
376 0 : SetText(aTitle.makeStringAndClear());
377 0 : maBtnAdd.SetClickHdl( LINK( &maCondFormList, ScCondFormatList, AddBtnHdl ) );
378 0 : maBtnRemove.SetClickHdl( LINK( &maCondFormList, ScCondFormatList, RemoveBtnHdl ) );
379 0 : maEdRange.SetModifyHdl( LINK( this, ScCondFormatDlg, EdRangeModifyHdl ) );
380 0 : maEdRange.SetGetFocusHdl( LINK( this, ScCondFormatDlg, RangeGetFocusHdl ) );
381 0 : maEdRange.SetLoseFocusHdl( LINK( this, ScCondFormatDlg, RangeLoseFocusHdl ) );
382 0 : FreeResource();
383 :
384 0 : maEdRange.SetText(aRangeString);
385 :
386 0 : SC_MOD()->PushNewAnyRefDlg(this);
387 0 : }
388 :
389 0 : ScCondFormatDlg::~ScCondFormatDlg()
390 : {
391 0 : SC_MOD()->PopAnyRefDlg();
392 0 : }
393 :
394 0 : void ScCondFormatDlg::SetActive()
395 : {
396 0 : if(mpLastEdit)
397 0 : mpLastEdit->GrabFocus();
398 : else
399 0 : maEdRange.GrabFocus();
400 :
401 0 : RefInputDone();
402 0 : }
403 :
404 0 : void ScCondFormatDlg::RefInputDone( sal_Bool bForced )
405 : {
406 0 : ScAnyRefModalDlg::RefInputDone(bForced);
407 0 : }
408 :
409 0 : sal_Bool ScCondFormatDlg::IsTableLocked() const
410 : {
411 0 : if(mpLastEdit && mpLastEdit != &maEdRange)
412 0 : return sal_False;
413 :
414 0 : return sal_True;
415 : }
416 :
417 0 : sal_Bool ScCondFormatDlg::IsRefInputMode() const
418 : {
419 0 : return maEdRange.IsEnabled();
420 : }
421 :
422 : #define ABS_SREF SCA_VALID \
423 : | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
424 : #define ABS_DREF ABS_SREF \
425 : | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE | SCA_TAB2_ABSOLUTE
426 : #define ABS_DREF3D ABS_DREF | SCA_TAB_3D
427 :
428 0 : void ScCondFormatDlg::SetReference(const ScRange& rRef, ScDocument*)
429 : {
430 0 : formula::RefEdit* pEdit = mpLastEdit;
431 0 : if(!mpLastEdit)
432 0 : pEdit = &maEdRange;
433 :
434 0 : if( pEdit->IsEnabled() )
435 : {
436 0 : if(rRef.aStart != rRef.aEnd)
437 0 : RefInputStart(pEdit);
438 :
439 0 : OUString aRefStr;
440 0 : sal_uInt16 n = 0;
441 0 : if(mpLastEdit && mpLastEdit != &maEdRange)
442 0 : n = ABS_DREF3D;
443 : else
444 0 : n = ABS_DREF;
445 :
446 0 : rRef.Format( aRefStr, n, mpDoc, ScAddress::Details(mpDoc->GetAddressConvention(), 0, 0) );
447 0 : pEdit->SetRefString( aRefStr );
448 : }
449 0 : }
450 :
451 0 : ScConditionalFormat* ScCondFormatDlg::GetConditionalFormat() const
452 : {
453 0 : OUString aRangeStr = maEdRange.GetText();
454 0 : if(aRangeStr.isEmpty())
455 0 : return NULL;
456 :
457 0 : ScRangeList aRange;
458 0 : sal_uInt16 nFlags = aRange.Parse(aRangeStr, mpDoc, SCA_VALID, mpDoc->GetAddressConvention(), maPos.Tab());
459 0 : ScConditionalFormat* pFormat = maCondFormList.GetConditionalFormat();
460 :
461 0 : if(nFlags & SCA_VALID && !aRange.empty() && pFormat)
462 0 : pFormat->AddRange(aRange);
463 : else
464 : {
465 0 : delete pFormat;
466 0 : pFormat = NULL;
467 : }
468 :
469 0 : return pFormat;
470 : }
471 :
472 0 : void ScCondFormatDlg::InvalidateRefData()
473 : {
474 0 : mpLastEdit = NULL;
475 0 : }
476 :
477 0 : IMPL_LINK( ScCondFormatDlg, EdRangeModifyHdl, Edit*, pEdit )
478 : {
479 0 : OUString aRangeStr = pEdit->GetText();
480 0 : ScRangeList aRange;
481 0 : sal_uInt16 nFlags = aRange.Parse(aRangeStr, mpDoc, SCA_VALID, mpDoc->GetAddressConvention());
482 0 : if(nFlags & SCA_VALID)
483 0 : pEdit->SetControlBackground(GetSettings().GetStyleSettings().GetWindowColor());
484 : else
485 0 : pEdit->SetControlBackground(COL_LIGHTRED);
486 0 : return 0;
487 : }
488 :
489 0 : IMPL_LINK( ScCondFormatDlg, RangeGetFocusHdl, formula::RefEdit*, pEdit )
490 : {
491 0 : mpLastEdit = pEdit;
492 0 : return 0;
493 : }
494 :
495 0 : IMPL_LINK_NOARG( ScCondFormatDlg, RangeLoseFocusHdl )
496 : {
497 : //mpLastEdit = NULL;
498 0 : return 0;
499 93 : }
500 :
501 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|