1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_svx.hxx"
24
25 #include <string> // HACK: prevent conflict between STLPORT and Workshop headers
26 #include <sfx2/app.hxx>
27 #include <sfx2/dispatch.hxx>
28 #include <sfx2/objsh.hxx>
29 #include <sfx2/viewsh.hxx>
30 #include <rtl/ustring.hxx>
31 #include <svx/dialogs.hrc>
32
33 #define TMP_STR_BEGIN '['
34 #define TMP_STR_END ']'
35
36 #include "svx/drawitem.hxx"
37 #include "svx/xattr.hxx"
38 #include <svx/xtable.hxx>
39 #include <svx/fillctrl.hxx>
40 #include <svx/itemwin.hxx>
41 #include <svx/dialmgr.hxx>
42 #include "helpid.hrc"
43
44 using namespace ::com::sun::star::uno;
45 using namespace ::com::sun::star::util;
46 using namespace ::com::sun::star::beans;
47 using namespace ::com::sun::star::frame;
48 using namespace ::com::sun::star::lang;
49
50 SFX_IMPL_TOOLBOX_CONTROL( SvxFillToolBoxControl, XFillStyleItem );
51
52 /*************************************************************************
53 |*
54 |* SvxFillToolBoxControl
55 |*
56 \************************************************************************/
57
SvxFillToolBoxControl(sal_uInt16 nSlotId,sal_uInt16 nId,ToolBox & rTbx)58 SvxFillToolBoxControl::SvxFillToolBoxControl(
59 sal_uInt16 nSlotId,
60 sal_uInt16 nId,
61 ToolBox& rTbx )
62 : SfxToolBoxControl( nSlotId, nId, rTbx ),
63 mpStyleItem(0),
64 mpColorItem(0),
65 mpGradientItem(0),
66 mpHatchItem(0),
67 mpBitmapItem(0),
68 mpFillControl(0),
69 mpFillTypeLB(0),
70 mpFillAttrLB(0),
71 meLastXFS(XFILL_NONE),
72 mbUpdate(false)
73 {
74 addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FillColor" )));
75 addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FillGradient" )));
76 addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FillHatch" )));
77 addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FillBitmap" )));
78 addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ColorTableState" )));
79 addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GradientListState" )));
80 addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:HatchListState" )));
81 addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:BitmapListState" )));
82 }
83
84 //========================================================================
85
~SvxFillToolBoxControl()86 SvxFillToolBoxControl::~SvxFillToolBoxControl()
87 {
88 delete mpStyleItem;
89 delete mpColorItem;
90 delete mpGradientItem;
91 delete mpHatchItem;
92 delete mpBitmapItem;
93 }
94
95 //========================================================================
96
StateChanged(sal_uInt16 nSID,SfxItemState eState,const SfxPoolItem * pState)97 void SvxFillToolBoxControl::StateChanged(
98 sal_uInt16 nSID,
99 SfxItemState eState,
100 const SfxPoolItem* pState)
101 {
102 bool bEnableControls(false);
103
104 if(eState == SFX_ITEM_DISABLED)
105 {
106 // slot disable state
107 if(nSID == SID_ATTR_FILL_STYLE)
108 {
109 mpFillTypeLB->Disable();
110 mpFillTypeLB->SetNoSelection();
111 }
112
113 mpFillAttrLB->Disable();
114 mpFillAttrLB->SetNoSelection();
115 }
116 else if(SFX_ITEM_AVAILABLE == eState)
117 {
118 // slot available state
119 if(nSID == SID_ATTR_FILL_STYLE)
120 {
121 delete mpStyleItem;
122 mpStyleItem = static_cast< XFillStyleItem* >(pState->Clone());
123 mpFillTypeLB->Enable();
124 }
125 else if(mpStyleItem)
126 {
127 const XFillStyle eXFS(static_cast< XFillStyle >(mpStyleItem->GetValue()));
128
129 if(nSID == SID_ATTR_FILL_COLOR)
130 {
131 delete mpColorItem;
132 mpColorItem = static_cast< XFillColorItem* >(pState->Clone());
133
134 if(eXFS == XFILL_SOLID)
135 {
136 bEnableControls = true;
137 }
138 }
139 else if(nSID == SID_ATTR_FILL_GRADIENT)
140 {
141 delete mpGradientItem;
142 mpGradientItem = static_cast< XFillGradientItem* >(pState->Clone());
143
144 if(eXFS == XFILL_GRADIENT)
145 {
146 bEnableControls = true;
147 }
148 }
149 else if(nSID == SID_ATTR_FILL_HATCH)
150 {
151 delete mpHatchItem;
152 mpHatchItem = static_cast< XFillHatchItem* >(pState->Clone());
153
154 if(eXFS == XFILL_HATCH)
155 {
156 bEnableControls = true;
157 }
158 }
159 else if(nSID == SID_ATTR_FILL_BITMAP)
160 {
161 delete mpBitmapItem;
162 mpBitmapItem = static_cast< XFillBitmapItem* >(pState->Clone());
163
164 if(eXFS == XFILL_BITMAP)
165 {
166 bEnableControls = true;
167 }
168 }
169 }
170
171 if(mpStyleItem)
172 {
173 // ensure that the correct entry is selected in mpFillTypeLB
174 XFillStyle eXFS(static_cast< XFillStyle >(mpStyleItem->GetValue()));
175 const bool bFillTypeChangedByUser(mpFillControl->mbFillTypeChanged);
176
177 if(bFillTypeChangedByUser)
178 {
179 meLastXFS = static_cast< XFillStyle >(mpFillControl->mnLastFillTypeControlSelectEntryPos);
180 mpFillControl->mbFillTypeChanged = false;
181 }
182
183 if(meLastXFS != eXFS)
184 {
185 mbUpdate = true;
186 mpFillTypeLB->SelectEntryPos(sal::static_int_cast<sal_uInt16>(eXFS));
187 }
188
189 mpFillAttrLB->Enable();
190 }
191
192 if(bEnableControls)
193 {
194 mpFillAttrLB->Enable();
195 mbUpdate = true;
196 }
197
198 Update(pState);
199 }
200 else
201 {
202 // slot empty or ambigous
203 if(nSID == SID_ATTR_FILL_STYLE)
204 {
205 mpFillTypeLB->SetNoSelection();
206 mpFillAttrLB->Disable();
207 mpFillAttrLB->SetNoSelection();
208 delete mpStyleItem;
209 mpStyleItem = 0;
210 mbUpdate = false;
211 }
212 else
213 {
214 XFillStyle eXFS(XFILL_NONE);
215
216 if(mpStyleItem)
217 {
218 eXFS = static_cast< XFillStyle >(mpStyleItem->GetValue());
219 }
220
221 if(!mpStyleItem ||
222 (nSID == SID_ATTR_FILL_COLOR && eXFS == XFILL_SOLID) ||
223 (nSID == SID_ATTR_FILL_GRADIENT && eXFS == XFILL_GRADIENT) ||
224 (nSID == SID_ATTR_FILL_HATCH && eXFS == XFILL_HATCH) ||
225 (nSID == SID_ATTR_FILL_BITMAP && eXFS == XFILL_BITMAP))
226 {
227 mpFillAttrLB->SetNoSelection();
228 }
229 }
230 }
231 }
232
233 //========================================================================
234
Update(const SfxPoolItem * pState)235 void SvxFillToolBoxControl::Update(const SfxPoolItem* pState)
236 {
237 if(mpStyleItem && pState && mbUpdate)
238 {
239 mbUpdate = false;
240 const XFillStyle eXFS(static_cast< XFillStyle >(mpStyleItem->GetValue()));
241
242 // Pruefen, ob Fuellstil schon vorher aktiv war
243 if(meLastXFS != eXFS)
244 {
245 // update mnLastFillTypeControlSelectEntryPos and fill style list
246 mpFillControl->updateLastFillTypeControlSelectEntryPos();
247 mpFillControl->InitializeFillStyleAccordingToGivenFillType(eXFS);
248 meLastXFS = eXFS;
249 }
250
251 switch(eXFS)
252 {
253 case XFILL_NONE:
254 {
255 break;
256 }
257
258 case XFILL_SOLID:
259 {
260 if(mpColorItem)
261 {
262 String aString(mpColorItem->GetName());
263 ::Color aColor = mpColorItem->GetColorValue();
264
265 mpFillAttrLB->SelectEntry(aString);
266
267 if(mpFillAttrLB->GetSelectEntryPos() == LISTBOX_ENTRY_NOTFOUND || mpFillAttrLB->GetSelectEntryColor() != aColor)
268 {
269 mpFillAttrLB->SelectEntry(aColor);
270 }
271
272 // Pruefen, ob Eintrag nicht in der Liste ist
273 if(mpFillAttrLB->GetSelectEntryPos() == LISTBOX_ENTRY_NOTFOUND || mpFillAttrLB->GetSelectEntryColor() != aColor)
274 {
275 sal_uInt16 nCount = mpFillAttrLB->GetEntryCount();
276 String aTmpStr;
277 if(nCount > 0)
278 {
279 //Letzter Eintrag wird auf temporaere Farbe geprueft
280 aTmpStr = mpFillAttrLB->GetEntry(nCount - 1);
281
282 if(aTmpStr.GetChar(0) == TMP_STR_BEGIN && aTmpStr.GetChar(aTmpStr.Len() - 1) == TMP_STR_END)
283 {
284 mpFillAttrLB->RemoveEntry(nCount - 1);
285 }
286 }
287
288 aTmpStr = TMP_STR_BEGIN;
289 aTmpStr += aString;
290 aTmpStr += TMP_STR_END;
291
292 sal_uInt16 nPos = mpFillAttrLB->InsertEntry(aColor,aTmpStr);
293 mpFillAttrLB->SelectEntryPos(nPos);
294 }
295 }
296 else
297 {
298 mpFillAttrLB->SetNoSelection();
299 }
300 break;
301 }
302
303 case XFILL_GRADIENT:
304 {
305 if(mpGradientItem)
306 {
307 String aString(mpGradientItem->GetName());
308 mpFillAttrLB->SelectEntry(aString);
309
310 // Pruefen, ob Eintrag nicht in der Liste ist
311 if(mpFillAttrLB->GetSelectEntry() != aString)
312 {
313 sal_uInt16 nCount = mpFillAttrLB->GetEntryCount();
314 String aTmpStr;
315
316 if(nCount > 0)
317 {
318 //Letzter Eintrag wird auf temporaeren Eintrag geprueft
319 aTmpStr = mpFillAttrLB->GetEntry(nCount - 1);
320
321 if(aTmpStr.GetChar(0) == TMP_STR_BEGIN && aTmpStr.GetChar(aTmpStr.Len() - 1) == TMP_STR_END)
322 {
323 mpFillAttrLB->RemoveEntry(nCount - 1);
324 }
325 }
326
327 aTmpStr = TMP_STR_BEGIN;
328 aTmpStr += aString;
329 aTmpStr += TMP_STR_END;
330
331 XGradientEntry* pEntry = new XGradientEntry(mpGradientItem->GetGradientValue(),aTmpStr);
332 XGradientListSharedPtr aGradientList(XPropertyListFactory::CreateSharedXGradientList(String::CreateFromAscii("TmpList")));
333
334 aGradientList->Insert(pEntry);
335 aGradientList->SetDirty(false);
336 const Bitmap aBmp = aGradientList->GetUiBitmap(0);
337
338 if(!aBmp.IsEmpty())
339 {
340 ((ListBox*)mpFillAttrLB)->InsertEntry(pEntry->GetName(),aBmp);
341 mpFillAttrLB->SelectEntryPos(mpFillAttrLB->GetEntryCount() - 1);
342 }
343 }
344 }
345 else
346 {
347 mpFillAttrLB->SetNoSelection();
348 }
349 break;
350 }
351
352 case XFILL_HATCH:
353 {
354 if(mpHatchItem)
355 {
356 String aString(mpHatchItem->GetName());
357 mpFillAttrLB->SelectEntry(aString);
358
359 // Pruefen, ob Eintrag nicht in der Liste ist
360 if(mpFillAttrLB->GetSelectEntry() != aString)
361 {
362 sal_uInt16 nCount = mpFillAttrLB->GetEntryCount();
363 String aTmpStr;
364 if(nCount > 0)
365 {
366 //Letzter Eintrag wird auf temporaeren Eintrag geprueft
367 aTmpStr = mpFillAttrLB->GetEntry(nCount - 1);
368 if(aTmpStr.GetChar(0) == TMP_STR_BEGIN &&
369 aTmpStr.GetChar(aTmpStr.Len() - 1) == TMP_STR_END)
370 {
371 mpFillAttrLB->RemoveEntry(nCount - 1);
372 }
373 }
374
375 aTmpStr = TMP_STR_BEGIN;
376 aTmpStr += aString;
377 aTmpStr += TMP_STR_END;
378
379 XHatchEntry* pEntry = new XHatchEntry(mpHatchItem->GetHatchValue(),aTmpStr);
380 XHatchListSharedPtr aHatchList(XPropertyListFactory::CreateSharedXHatchList(String::CreateFromAscii("TmpList")));
381
382 aHatchList->Insert(pEntry);
383 aHatchList->SetDirty(sal_False);
384 const Bitmap aBmp = aHatchList->GetUiBitmap(0);
385
386 if(!aBmp.IsEmpty())
387 {
388 ((ListBox*)mpFillAttrLB)->InsertEntry(pEntry->GetName(),aBmp);
389 mpFillAttrLB->SelectEntryPos(mpFillAttrLB->GetEntryCount() - 1);
390 }
391 }
392 }
393 else
394 {
395 mpFillAttrLB->SetNoSelection();
396 }
397 break;
398 }
399
400 case XFILL_BITMAP:
401 {
402 if(mpBitmapItem)
403 {
404 String aString(mpBitmapItem->GetName());
405 mpFillAttrLB->SelectEntry(aString);
406
407 // Pruefen, ob Eintrag nicht in der Liste ist
408 if(mpFillAttrLB->GetSelectEntry() != aString)
409 {
410 sal_uInt16 nCount = mpFillAttrLB->GetEntryCount();
411 String aTmpStr;
412
413 if(nCount > 0)
414 {
415 //Letzter Eintrag wird auf temporaeren Eintrag geprueft
416 aTmpStr = mpFillAttrLB->GetEntry(nCount - 1);
417
418 if(aTmpStr.GetChar(0) == TMP_STR_BEGIN && aTmpStr.GetChar(aTmpStr.Len() - 1) == TMP_STR_END)
419 {
420 mpFillAttrLB->RemoveEntry(nCount - 1);
421 }
422 }
423
424 aTmpStr = TMP_STR_BEGIN;
425 aTmpStr += aString;
426 aTmpStr += TMP_STR_END;
427
428 XBitmapListSharedPtr aNew(XPropertyListFactory::CreateSharedXBitmapList(String::CreateFromAscii("TmpList")));
429 aNew->Insert(new XBitmapEntry(mpBitmapItem->GetGraphicObject(),aTmpStr));
430 aNew->SetDirty(false);
431
432 mpFillAttrLB->Fill(aNew);
433 mpFillAttrLB->SelectEntryPos(mpFillAttrLB->GetEntryCount() - 1);
434 }
435 }
436 else
437 {
438 mpFillAttrLB->SetNoSelection();
439 }
440 break;
441 }
442
443 default:
444 {
445 DBG_ERROR("Nicht unterstuetzter Flaechentyp");
446 break;
447 }
448 }
449
450 // update mnLastFillAttrControlSelectEntryPos
451 mpFillControl->updateLastFillAttrControlSelectEntryPos();
452 }
453
454 if(pState && mpStyleItem)
455 {
456 XFillStyle eXFS = static_cast< XFillStyle >(mpStyleItem->GetValue());
457
458 // Die Listen haben sich geaendert ?
459 switch(eXFS)
460 {
461 case XFILL_SOLID:
462 {
463 const SvxColorTableItem* pItem = dynamic_cast< const SvxColorTableItem* >(pState);
464
465 if(pItem)
466 {
467 ::Color aTmpColor(mpFillAttrLB->GetSelectEntryColor());
468 mpFillAttrLB->Clear();
469 mpFillAttrLB->Fill(pItem->GetColorTable());
470 mpFillAttrLB->SelectEntry(aTmpColor);
471 }
472 break;
473 }
474 case XFILL_GRADIENT:
475 {
476 const SvxGradientListItem* pItem = dynamic_cast< const SvxGradientListItem* >(pState);
477
478 if(pItem)
479 {
480 String aString(mpFillAttrLB->GetSelectEntry());
481 mpFillAttrLB->Clear();
482 mpFillAttrLB->Fill(pItem->GetGradientList());
483 mpFillAttrLB->SelectEntry(aString);
484 }
485 break;
486 }
487 case XFILL_HATCH:
488 {
489 const SvxHatchListItem* pItem = dynamic_cast< const SvxHatchListItem* >(pState);
490
491 if(pItem)
492 {
493 String aString(mpFillAttrLB->GetSelectEntry());
494 mpFillAttrLB->Clear();
495 mpFillAttrLB->Fill(pItem->GetHatchList());
496 mpFillAttrLB->SelectEntry(aString);
497 }
498 break;
499 }
500 case XFILL_BITMAP:
501 {
502 const SvxBitmapListItem* pItem = dynamic_cast< const SvxBitmapListItem* >(pState);
503
504 if(pItem)
505 {
506 String aString(mpFillAttrLB->GetSelectEntry());
507 mpFillAttrLB->Clear();
508 mpFillAttrLB->Fill(pItem->GetBitmapList());
509 mpFillAttrLB->SelectEntry(aString);
510 }
511 break;
512 }
513 default: // XFILL_NONE
514 {
515 break;
516 }
517 }
518 }
519 }
520
521 //========================================================================
522
CreateItemWindow(Window * pParent)523 Window* SvxFillToolBoxControl::CreateItemWindow(Window *pParent)
524 {
525 if(GetSlotId() == SID_ATTR_FILL_STYLE)
526 {
527 mpFillControl = new FillControl(pParent);
528 // Damit dem FillControl das SvxFillToolBoxControl bekannt ist
529 // (und um kompatibel zu bleiben)
530 mpFillControl->SetData(this);
531
532 mpFillAttrLB = (SvxFillAttrBox*)mpFillControl->mpLbFillAttr;
533 mpFillTypeLB = (SvxFillTypeBox*)mpFillControl->mpLbFillType;
534
535 mpFillAttrLB->SetUniqueId(HID_FILL_ATTR_LISTBOX);
536 mpFillTypeLB->SetUniqueId(HID_FILL_TYPE_LISTBOX);
537
538 if(!mpStyleItem)
539 {
540 // for Writer and Calc it's not the same instance of
541 // SvxFillToolBoxControl which gets used after deselecting
542 // and selecting a DrawObject, thhus a useful initialization is
543 // needed to get the FillType and the FillStyle List inited
544 // correctly. This in combination with meLastXFS inited to
545 // XFILL_NONE do the trick
546 mpStyleItem = new XFillStyleItem(XFILL_SOLID);
547 }
548
549 return mpFillControl;
550 }
551 return NULL;
552 }
553
554 /*************************************************************************
555 |*
556 |* FillControl
557 |*
558 \************************************************************************/
559
FillControl(Window * pParent,WinBits nStyle)560 FillControl::FillControl(Window* pParent,WinBits nStyle)
561 : Window(pParent,nStyle | WB_DIALOGCONTROL),
562 mpLbFillType(new SvxFillTypeBox(this)),
563 mpLbFillAttr(new SvxFillAttrBox(this)),
564 maLogicalFillSize(40,80),
565 maLogicalAttrSize(50,80),
566 mnLastFillTypeControlSelectEntryPos(mpLbFillType->GetSelectEntryPos()),
567 mnLastFillAttrControlSelectEntryPos(mpLbFillAttr->GetSelectEntryPos()),
568 mbFillTypeChanged(false)
569 {
570 Size aTypeSize(LogicToPixel(maLogicalFillSize,MAP_APPFONT));
571 Size aAttrSize(LogicToPixel(maLogicalAttrSize,MAP_APPFONT));
572 mpLbFillType->SetSizePixel(aTypeSize);
573 mpLbFillAttr->SetSizePixel(aAttrSize);
574
575 //to get the base height
576 aTypeSize = mpLbFillType->GetSizePixel();
577 aAttrSize = mpLbFillAttr->GetSizePixel();
578 Point aAttrPnt = mpLbFillAttr->GetPosPixel();
579 SetSizePixel(
580 Size(aAttrPnt.X() + aAttrSize.Width(),
581 Max(aAttrSize.Height(),aTypeSize.Height())));
582
583 mpLbFillType->SetSelectHdl(LINK(this,FillControl,SelectFillTypeHdl));
584 mpLbFillAttr->SetSelectHdl(LINK(this,FillControl,SelectFillAttrHdl));
585 }
586
587 //------------------------------------------------------------------------
588
~FillControl()589 FillControl::~FillControl()
590 {
591 delete mpLbFillType;
592 delete mpLbFillAttr;
593 }
594
595 //------------------------------------------------------------------------
596
InitializeFillStyleAccordingToGivenFillType(XFillStyle aFillStyle)597 void FillControl::InitializeFillStyleAccordingToGivenFillType(XFillStyle aFillStyle)
598 {
599 SfxObjectShell* pSh = SfxObjectShell::Current();
600 bool bDone(false);
601
602 if(pSh)
603 {
604 // clear in all cases, else we would risk a mix of FillStyles in the Style list
605 mpLbFillAttr->Clear();
606
607 switch(aFillStyle)
608 {
609 case XFILL_SOLID:
610 {
611 if(pSh->GetItem(SID_COLOR_TABLE))
612 {
613 const SvxColorTableItem* pItem = static_cast< const SvxColorTableItem* >(pSh->GetItem(SID_COLOR_TABLE));
614 mpLbFillAttr->Enable();
615 mpLbFillAttr->Fill(pItem->GetColorTable());
616 bDone = true;
617 }
618 break;
619 }
620
621 case XFILL_GRADIENT:
622 {
623 if(pSh->GetItem(SID_GRADIENT_LIST))
624 {
625 const SvxGradientListItem* pItem = static_cast< const SvxGradientListItem* >(pSh->GetItem(SID_GRADIENT_LIST));
626 mpLbFillAttr->Enable();
627 mpLbFillAttr->Fill(pItem->GetGradientList());
628 bDone = true;
629 }
630 break;
631 }
632
633 case XFILL_HATCH:
634 {
635 if(pSh->GetItem(SID_HATCH_LIST))
636 {
637 const SvxHatchListItem* pItem = static_cast< const SvxHatchListItem* >(pSh->GetItem(SID_HATCH_LIST));
638 mpLbFillAttr->Enable();
639 mpLbFillAttr->Fill(pItem->GetHatchList());
640 bDone = true;
641 }
642 break;
643 }
644
645 case XFILL_BITMAP:
646 {
647 if(pSh->GetItem(SID_BITMAP_LIST))
648 {
649 const SvxBitmapListItem* pItem = static_cast< const SvxBitmapListItem* >(pSh->GetItem(SID_BITMAP_LIST));
650 mpLbFillAttr->Enable();
651 mpLbFillAttr->Fill(pItem->GetBitmapList());
652 bDone = true;
653 }
654 break;
655 }
656 default: // XFILL_NONE
657 {
658 // accept disable (no styles for XFILL_NONE)
659 break;
660 }
661 }
662 }
663
664 if(!bDone)
665 {
666 mpLbFillAttr->Disable();
667 }
668 }
669
updateLastFillTypeControlSelectEntryPos()670 void FillControl::updateLastFillTypeControlSelectEntryPos()
671 {
672 mnLastFillTypeControlSelectEntryPos = mpLbFillType->GetSelectEntryPos();
673 }
674
IMPL_LINK(FillControl,SelectFillTypeHdl,ListBox *,pBox)675 IMPL_LINK(FillControl,SelectFillTypeHdl,ListBox *,pBox)
676 {
677 if(!pBox) // only work with real calls from ListBox, do not accept direct calls with zeros here
678 {
679 return 0;
680 }
681
682 const bool bAction(
683 !mpLbFillType->IsTravelSelect() // keep TravelSelect, this means keyboard up/down in the list
684 && mpLbFillType->GetSelectEntryCount()
685 && mpLbFillType->GetSelectEntryPos() != mnLastFillTypeControlSelectEntryPos);
686
687 updateLastFillTypeControlSelectEntryPos();
688 XFillStyle eXFS = static_cast< XFillStyle >(mpLbFillType->GetSelectEntryPos());
689
690 if(bAction && XFILL_NONE != eXFS)
691 {
692 mbFillTypeChanged = true;
693 }
694
695 // update list of FillStyles in any case
696 InitializeFillStyleAccordingToGivenFillType(eXFS);
697
698 // for XFILL_NONE do no longer call SelectFillAttrHdl (as done before),
699 // trigger needed actions directly. This is the only action this handler
700 // can trigger directly as the user action is finished in this case
701 if(XFILL_NONE == eXFS && bAction)
702 {
703 // for XFILL_NONE do no longer call SelectFillAttrHdl,
704 // trigger needed actions directly
705 Any a;
706 Sequence< PropertyValue > aArgsFillStyle(1);
707 XFillStyleItem aXFillStyleItem(eXFS);
708
709 aArgsFillStyle[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FillStyle"));
710 aXFillStyleItem.QueryValue(a);
711 aArgsFillStyle[0].Value = a;
712 ((SvxFillToolBoxControl*)GetData())->Dispatch(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:FillStyle")), aArgsFillStyle);
713 }
714
715 mpLbFillType->Selected();
716
717 // release focus. Needed to get focus automatically back to EditView
718 if(mpLbFillType->IsRelease())
719 {
720 SfxViewShell* pViewShell = SfxViewShell::Current();
721
722 if(pViewShell && pViewShell->GetWindow())
723 {
724 pViewShell->GetWindow()->GrabFocus();
725 }
726 }
727
728 return 0;
729 }
730
731 //------------------------------------------------------------------------
732
updateLastFillAttrControlSelectEntryPos()733 void FillControl::updateLastFillAttrControlSelectEntryPos()
734 {
735 mnLastFillAttrControlSelectEntryPos = mpLbFillAttr->GetSelectEntryPos();
736 }
737
IMPL_LINK(FillControl,SelectFillAttrHdl,ListBox *,pBox)738 IMPL_LINK(FillControl, SelectFillAttrHdl, ListBox *, pBox)
739 {
740 if(!pBox) // only work with real calls from ListBox, do not accept direct calls with zeros here
741 {
742 return 0;
743 }
744
745 const bool bAction(
746 !mpLbFillAttr->IsTravelSelect() // keep TravelSelect, this means keyboard up/down in the list
747 && mpLbFillAttr->GetSelectEntryCount()
748 && mpLbFillAttr->GetSelectEntryPos() != mnLastFillAttrControlSelectEntryPos);
749
750 updateLastFillAttrControlSelectEntryPos();
751
752 if(bAction)
753 {
754 SfxObjectShell* pSh = SfxObjectShell::Current();
755
756 // Need to prepare the PropertyValue for the FillStyle dispatch action early,
757 // else the call for FillType to Dispatch(".uno:FillStyle") will already destroy the current state
758 // of selection in mpLbFillAttr again by calls to StateChanged which *will* set to no
759 // selection again (e.g. when two objects, same fill style, but different fill attributes)
760 Any a;
761 Sequence< PropertyValue > aArgsFillAttr(1);
762 ::rtl::OUString aFillAttrCommand;
763 XFillStyle eXFS(static_cast< XFillStyle >(mpLbFillType->GetSelectEntryPos()));
764
765 switch(eXFS)
766 {
767 case XFILL_NONE:
768 {
769 // handled in SelectFillTypeHdl, nothing to do here
770 break;
771 }
772
773 case XFILL_SOLID:
774 {
775 //Eintrag wird auf temporaere Farbe geprueft
776 String aTmpStr = mpLbFillAttr->GetSelectEntry();
777
778 if(aTmpStr.GetChar(0) == TMP_STR_BEGIN && aTmpStr.GetChar(aTmpStr.Len() - 1) == TMP_STR_END)
779 {
780 aTmpStr.Erase(aTmpStr.Len() - 1,1);
781 aTmpStr.Erase(0,1);
782 }
783
784 XFillColorItem aXFillColorItem(aTmpStr,mpLbFillAttr->GetSelectEntryColor());
785 aArgsFillAttr[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FillColor"));
786 aXFillColorItem.QueryValue(a);
787 aArgsFillAttr[0].Value = a;
788 aFillAttrCommand = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:FillColor"));
789 break;
790 }
791 case XFILL_GRADIENT:
792 {
793 sal_uInt16 nPos = mpLbFillAttr->GetSelectEntryPos();
794
795 if(nPos != LISTBOX_ENTRY_NOTFOUND && pSh && pSh->GetItem(SID_GRADIENT_LIST))
796 {
797 const SvxGradientListItem* pItem = static_cast< const SvxGradientListItem* >(pSh->GetItem(SID_GRADIENT_LIST));
798
799 if(nPos < pItem->GetGradientList()->Count()) // kein temp. Eintrag ?
800 {
801 XGradient aGradient = pItem->GetGradientList()->GetGradient(nPos)->GetGradient();
802 XFillGradientItem aXFillGradientItem(mpLbFillAttr->GetSelectEntry(),aGradient);
803 aArgsFillAttr[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FillGradient"));
804 aXFillGradientItem.QueryValue(a);
805 aArgsFillAttr[0].Value = a;
806 aFillAttrCommand = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:FillGradient"));
807 }
808 }
809 break;
810 }
811
812 case XFILL_HATCH:
813 {
814 sal_uInt16 nPos = mpLbFillAttr->GetSelectEntryPos();
815
816 if(nPos != LISTBOX_ENTRY_NOTFOUND && pSh && pSh->GetItem(SID_HATCH_LIST))
817 {
818 const SvxHatchListItem* pItem = static_cast< const SvxHatchListItem* >(pSh->GetItem(SID_HATCH_LIST));
819
820 if(nPos < pItem->GetHatchList()->Count()) // kein temp. Eintrag ?
821 {
822 XHatch aHatch = pItem->GetHatchList()->GetHatch(nPos)->GetHatch();
823 XFillHatchItem aXFillHatchItem(mpLbFillAttr->GetSelectEntry(),aHatch);
824
825 aArgsFillAttr[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FillHatch"));
826 aXFillHatchItem.QueryValue(a);
827 aArgsFillAttr[0].Value = a;
828 aFillAttrCommand = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:FillHatch"));
829 }
830 }
831 break;
832 }
833
834 case XFILL_BITMAP:
835 {
836 sal_uInt16 nPos = mpLbFillAttr->GetSelectEntryPos();
837
838 if(nPos != LISTBOX_ENTRY_NOTFOUND && pSh && pSh->GetItem(SID_BITMAP_LIST))
839 {
840 const SvxBitmapListItem* pItem = static_cast< const SvxBitmapListItem* >(pSh->GetItem(SID_BITMAP_LIST));
841
842 if(nPos < pItem->GetBitmapList()->Count()) // kein temp. Eintrag ?
843 {
844 const XBitmapEntry* pXBitmapEntry = pItem->GetBitmapList()->GetBitmap(nPos);
845 const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->GetSelectEntry(),pXBitmapEntry->GetGraphicObject());
846
847 aArgsFillAttr[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FillBitmap"));
848 aXFillBitmapItem.QueryValue(a);
849 aArgsFillAttr[0].Value = a;
850 aFillAttrCommand = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:FillBitmap"));
851 }
852 }
853 break;
854 }
855 }
856
857 // this is the place where evtl. a new slot action may be introduced to avoid the
858 // two undo entries. Reason for this is that indeed two actions are executed, the fill style
859 // and the fill attribute change. The sidebar already handles both separately, so
860 // changing the fill style already changes the object and adds a default fill attribute for
861 // the newly choosen fill style.
862 // This control uses the older user's two-step action to select a fill style and a fill attribute. In
863 // this case a lot of things may go wrong (e.g. the user stops that action and does something
864 // different), thus the solution of the sidebar should be preferred from my POV in the future
865
866 // first set the fill style if changed
867 if(mbFillTypeChanged)
868 {
869 Sequence< PropertyValue > aArgsFillStyle(1);
870 XFillStyleItem aXFillStyleItem(eXFS);
871
872 aArgsFillStyle[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FillStyle"));
873 aXFillStyleItem.QueryValue(a);
874 aArgsFillStyle[0].Value = a;
875 ((SvxFillToolBoxControl*)GetData())->Dispatch(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:FillStyle")), aArgsFillStyle);
876 mbFillTypeChanged = false;
877 }
878
879 // second set fill attribute when a change was detected and prepared
880 if(aFillAttrCommand.getLength())
881 {
882 ((SvxFillToolBoxControl*)GetData())->Dispatch(aFillAttrCommand, aArgsFillAttr);
883 }
884
885 // release focus. Needed to get focus automatically back to EditView
886 if(mpLbFillAttr->IsRelease() && pBox)
887 {
888 SfxViewShell* pViewShell = SfxViewShell::Current();
889
890 if(pViewShell && pViewShell->GetWindow())
891 {
892 pViewShell->GetWindow()->GrabFocus();
893 }
894 }
895 }
896
897 return 0;
898 }
899
900 //------------------------------------------------------------------------
901
Resize()902 void FillControl::Resize()
903 {
904 // Breite der beiden ListBoxen nicht 1/2 : 1/2, sondern 2/5 : 3/5
905 long nW = GetOutputSizePixel().Width() / 5;
906 long nH = 180;
907 long nSep = 0; // war vorher 4
908
909 mpLbFillType->SetSizePixel(Size(nW * 2 - nSep,nH));
910 mpLbFillAttr->SetPosSizePixel(Point(nW * 2 + nSep,0),Size(nW * 3 - nSep,nH));
911 }
912
913 //------------------------------------------------------------------------
914
DataChanged(const DataChangedEvent & rDCEvt)915 void FillControl::DataChanged(const DataChangedEvent& rDCEvt)
916 {
917 if((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
918 (rDCEvt.GetFlags() & SETTINGS_STYLE))
919 {
920 Size aTypeSize(LogicToPixel(maLogicalFillSize,MAP_APPFONT));
921 Size aAttrSize(LogicToPixel(maLogicalAttrSize,MAP_APPFONT));
922 mpLbFillType->SetSizePixel(aTypeSize);
923 mpLbFillAttr->SetSizePixel(aAttrSize);
924
925 //to get the base height
926 aTypeSize = mpLbFillType->GetSizePixel();
927 aAttrSize = mpLbFillAttr->GetSizePixel();
928 Point aAttrPnt = mpLbFillAttr->GetPosPixel();
929
930 SetSizePixel(
931 Size(aAttrPnt.X() + aAttrSize.Width(),
932 Max(aAttrSize.Height(),aTypeSize.Height())));
933 }
934 Window::DataChanged(rDCEvt);
935 }
936
937 //------------------------------------------------------------------------
938 //eof
939