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