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