bump product version to 5.0.4.1
[LibreOffice.git] / svx / source / tbxctrls / colrctrl.cxx
blob37ad939e584a532a556177dbaa4487e7de468d2b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
22 #include <sot/exchange.hxx>
23 #include <sot/storage.hxx>
24 #include <svx/dialogs.hrc>
26 #include <sfx2/viewsh.hxx>
27 #include <sfx2/objsh.hxx>
28 #include <sfx2/dispatch.hxx>
29 #include <vcl/image.hxx>
31 #include <svx/colrctrl.hxx>
33 #include <svx/svdview.hxx>
34 #include "svx/drawitem.hxx"
35 #include <editeng/colritem.hxx>
36 #include "svx/xattr.hxx"
37 #include <svx/xtable.hxx>
38 #include <svx/dialmgr.hxx>
39 #include "svx/xexch.hxx"
40 #include "helpid.hrc"
41 #include <vcl/svapp.hxx>
43 using namespace com::sun::star;
45 // - SvxColorValueSetData -
48 class SvxColorValueSetData : public TransferableHelper
50 private:
52 XFillExchangeData maData;
54 protected:
56 virtual void AddSupportedFormats() SAL_OVERRIDE;
57 virtual bool GetData( const css::datatransfer::DataFlavor& rFlavor, const OUString& rDestDoc ) SAL_OVERRIDE;
58 virtual bool WriteObject( tools::SvRef<SotStorageStream>& rxOStm, void* pUserObject, SotClipboardFormatId nUserObjectId, const ::com::sun::star::datatransfer::DataFlavor& rFlavor ) SAL_OVERRIDE;
60 public:
62 SvxColorValueSetData( const XFillAttrSetItem& rSetItem ) :
63 maData( rSetItem ) {}
68 void SvxColorValueSetData::AddSupportedFormats()
70 AddFormat( SotClipboardFormatId::XFA );
75 bool SvxColorValueSetData::GetData( const css::datatransfer::DataFlavor& rFlavor, const OUString& /*rDestDoc*/ )
77 bool bRet = false;
79 if( SotExchange::GetFormat( rFlavor ) == SotClipboardFormatId::XFA )
81 SetObject( &maData, SotClipboardFormatId::NONE, rFlavor );
82 bRet = true;
85 return bRet;
88 bool SvxColorValueSetData::WriteObject( tools::SvRef<SotStorageStream>& rxOStm, void*, SotClipboardFormatId, const ::com::sun::star::datatransfer::DataFlavor& )
90 WriteXFillExchangeData( *rxOStm, maData );
91 return( rxOStm->GetError() == ERRCODE_NONE );
94 SvxColorValueSet_docking::SvxColorValueSet_docking( vcl::Window* _pParent, WinBits nWinStyle ) :
95 SvxColorValueSet( _pParent, nWinStyle ),
96 DragSourceHelper( this ),
97 mbLeftButton(true)
99 SetAccessibleName(SVX_RESSTR(STR_COLORTABLE));
102 void SvxColorValueSet_docking::MouseButtonDown( const MouseEvent& rMEvt )
104 // Fuer Mac noch anders handlen !
105 if( rMEvt.IsLeft() )
107 mbLeftButton = true;
108 SvxColorValueSet::MouseButtonDown( rMEvt );
110 else
112 mbLeftButton = false;
113 MouseEvent aMEvt( rMEvt.GetPosPixel(),
114 rMEvt.GetClicks(),
115 rMEvt.GetMode(),
116 MOUSE_LEFT,
117 rMEvt.GetModifier() );
118 SvxColorValueSet::MouseButtonDown( aMEvt );
121 aDragPosPixel = GetPointerPosPixel();
124 void SvxColorValueSet_docking::MouseButtonUp( const MouseEvent& rMEvt )
126 // Fuer Mac noch anders handlen !
127 if( rMEvt.IsLeft() )
129 mbLeftButton = true;
130 SvxColorValueSet::MouseButtonUp( rMEvt );
132 else
134 mbLeftButton = false;
135 MouseEvent aMEvt( rMEvt.GetPosPixel(),
136 rMEvt.GetClicks(),
137 rMEvt.GetMode(),
138 MOUSE_LEFT,
139 rMEvt.GetModifier() );
140 SvxColorValueSet::MouseButtonUp( aMEvt );
142 SetNoSelection();
145 void SvxColorValueSet_docking::Command(const CommandEvent& rCEvt)
147 // Basisklasse
148 SvxColorValueSet::Command(rCEvt);
151 void SvxColorValueSet_docking::StartDrag( sal_Int8 , const Point& )
153 Application::PostUserEvent(LINK(this, SvxColorValueSet_docking, ExecDragHdl), NULL, true);
156 void SvxColorValueSet_docking::DoDrag()
158 SfxObjectShell* pDocSh = SfxObjectShell::Current();
159 sal_uInt16 nItemId = GetItemId( aDragPosPixel );
161 if( pDocSh && nItemId )
163 XFillAttrSetItem aXFillSetItem( &pDocSh->GetPool() );
164 SfxItemSet& rSet = aXFillSetItem.GetItemSet();
166 rSet.Put( XFillColorItem( GetItemText( nItemId ), GetItemColor( nItemId ) ) );
167 rSet.Put(XFillStyleItem( ( 1 == nItemId ) ? drawing::FillStyle_NONE : drawing::FillStyle_SOLID ) );
169 EndSelection();
170 ( new SvxColorValueSetData( aXFillSetItem ) )->StartDrag( this, DND_ACTION_COPY );
171 ReleaseMouse();
175 IMPL_LINK_NOARG(SvxColorValueSet_docking, ExecDragHdl)
177 // Als Link, damit asynchron ohne ImpMouseMoveMsg auf dem Stack auch die
178 // Farbleiste geloescht werden darf
179 DoDrag();
180 return 0;
183 SvxColorDockingWindow::SvxColorDockingWindow
185 SfxBindings* _pBindings,
186 SfxChildWindow* pCW,
187 vcl::Window* _pParent
190 SfxDockingWindow( _pBindings, pCW, _pParent, WB_MOVEABLE|WB_CLOSEABLE|WB_SIZEABLE|WB_DOCKABLE ),
191 pColorList (),
192 aColorSet ( VclPtr<SvxColorValueSet_docking>::Create(this) ),
193 nLeftSlot ( SID_ATTR_FILL_COLOR ),
194 nRightSlot ( SID_ATTR_LINE_COLOR ),
195 nCols ( 20 ),
196 nLines ( 1 ),
197 nCount ( 0 )
199 SetText(SVX_RESSTR(STR_COLORTABLE));
200 SetSizePixel(LogicToPixel(Size(150, 22), MapMode(MAP_APPFONT)));
201 SetHelpId(HID_CTRL_COLOR);
203 aColorSet->SetSelectHdl( LINK( this, SvxColorDockingWindow, SelectHdl ) );
204 aColorSet->SetHelpId(HID_COLOR_CTL_COLORS);
205 aColorSet->SetPosSizePixel(LogicToPixel(Point(2, 2), MapMode(MAP_APPFONT)),
206 LogicToPixel(Size(146, 18), MapMode(MAP_APPFONT)));
208 // Get the model from the view shell. Using SfxObjectShell::Current()
209 // is unreliable when called at the wrong times.
210 SfxObjectShell* pDocSh = NULL;
211 if (_pBindings != NULL)
213 SfxDispatcher* pDispatcher = _pBindings->GetDispatcher();
214 if (pDispatcher != NULL)
216 SfxViewFrame* pFrame = pDispatcher->GetFrame();
217 if (pFrame != NULL)
219 SfxViewShell* pViewShell = pFrame->GetViewShell();
220 if (pViewShell != NULL)
221 pDocSh = pViewShell->GetObjectShell();
226 if ( pDocSh )
228 const SfxPoolItem* pItem = pDocSh->GetItem( SID_COLOR_TABLE );
229 if( pItem )
231 pColorList = static_cast<const SvxColorListItem*>(pItem)->GetColorList();
232 FillValueSet();
236 aItemSize = aColorSet->CalcItemSizePixel(Size(SvxColorValueSet::getEntryEdgeLength(), SvxColorValueSet::getEntryEdgeLength()));
237 aItemSize.Width() = aItemSize.Width() + SvxColorValueSet::getEntryEdgeLength();
238 aItemSize.Width() /= 2;
239 aItemSize.Height() = aItemSize.Height() + SvxColorValueSet::getEntryEdgeLength();
240 aItemSize.Height() /= 2;
242 SetSize();
243 aColorSet->Show();
244 if (_pBindings != NULL)
245 StartListening( *_pBindings, true );
248 SvxColorDockingWindow::~SvxColorDockingWindow()
250 disposeOnce();
253 void SvxColorDockingWindow::dispose()
255 EndListening( GetBindings() );
256 aColorSet.disposeAndClear();
257 SfxDockingWindow::dispose();
260 void SvxColorDockingWindow::Notify( SfxBroadcaster& , const SfxHint& rHint )
262 const SfxPoolItemHint* pPoolItemHint = dynamic_cast<const SfxPoolItemHint*>(&rHint);
263 if ( pPoolItemHint
264 && ( pPoolItemHint->GetObject()->ISA( SvxColorListItem ) ) )
266 // Die Liste der Farben hat sich geaendert
267 pColorList = static_cast<SvxColorListItem*>( pPoolItemHint->GetObject() )->GetColorList();
268 FillValueSet();
272 void SvxColorDockingWindow::FillValueSet()
274 if( pColorList.is() )
276 nCount = pColorList->Count();
277 aColorSet->Clear();
279 // create the first entry for 'invisible/none'
280 const Size aColorSize(SvxColorValueSet::getEntryEdgeLength(), SvxColorValueSet::getEntryEdgeLength());
281 long nPtX = aColorSize.Width() - 1;
282 long nPtY = aColorSize.Height() - 1;
283 ScopedVclPtrInstance< VirtualDevice > pVD;
285 pVD->SetOutputSizePixel( aColorSize );
286 pVD->SetLineColor( Color( COL_BLACK ) );
287 pVD->SetBackground( Wallpaper( Color( COL_WHITE ) ) );
288 pVD->DrawLine( Point(), Point( nPtX, nPtY ) );
289 pVD->DrawLine( Point( 0, nPtY ), Point( nPtX, 0 ) );
291 Bitmap aBmp( pVD->GetBitmap( Point(), aColorSize ) );
293 aColorSet->InsertItem( (sal_uInt16)1, Image(aBmp), SVX_RESSTR( RID_SVXSTR_INVISIBLE ) );
295 aColorSet->addEntriesForXColorList(*pColorList, 2);
299 void SvxColorDockingWindow::SetSize()
301 // Groesse fuer ValueSet berechnen
302 Size aSize = GetOutputSizePixel();
303 aSize.Width() -= 4;
304 aSize.Height() -= 4;
306 // Zeilen und Spalten berechnen
307 nCols = (sal_uInt16) ( aSize.Width() / aItemSize.Width() );
308 nLines = (sal_uInt16) ( (float) aSize.Height() / (float) aItemSize.Height() /*+ 0.35*/ );
309 if( nLines == 0 )
310 nLines++;
312 // Scrollbar setzen/entfernen
313 WinBits nBits = aColorSet->GetStyle();
314 if ( static_cast<long>(nLines) * nCols >= nCount )
315 nBits &= ~WB_VSCROLL;
316 else
317 nBits |= WB_VSCROLL;
318 aColorSet->SetStyle( nBits );
320 // ScrollBar ?
321 long nScrollWidth = aColorSet->GetScrollWidth();
322 if( nScrollWidth > 0 )
324 // Spalten mit ScrollBar berechnen
325 nCols = (sal_uInt16) ( ( aSize.Width() - nScrollWidth ) / aItemSize.Width() );
327 aColorSet->SetColCount( nCols );
329 if( IsFloatingMode() )
330 aColorSet->SetLineCount( nLines );
331 else
333 aColorSet->SetLineCount( 0 ); // sonst wird LineHeight ignoriert
334 aColorSet->SetItemHeight( aItemSize.Height() );
337 aColorSet->SetPosSizePixel( Point( 2, 2 ), aSize );
340 bool SvxColorDockingWindow::Close()
342 SfxBoolItem aItem( SID_COLOR_CONTROL, false );
343 GetBindings().GetDispatcher()->Execute(
344 SID_COLOR_CONTROL, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, &aItem, 0L );
345 SfxDockingWindow::Close();
346 return true;
349 IMPL_LINK_NOARG(SvxColorDockingWindow, SelectHdl)
351 SfxDispatcher* pDispatcher = GetBindings().GetDispatcher();
352 sal_uInt16 nPos = aColorSet->GetSelectItemId();
353 Color aColor( aColorSet->GetItemColor( nPos ) );
354 OUString aStr( aColorSet->GetItemText( nPos ) );
356 if (aColorSet->IsLeftButton())
358 if ( nLeftSlot == SID_ATTR_FILL_COLOR )
360 if ( nPos == 1 ) // unsichtbar
362 XFillStyleItem aXFillStyleItem( drawing::FillStyle_NONE );
363 pDispatcher->Execute( nLeftSlot, SfxCallMode::RECORD, &aXFillStyleItem, 0L );
365 else
367 bool bDone = false;
369 // Wenn wir eine DrawView haben und uns im TextEdit-Modus befinden,
370 // wird nicht die Flaechen-, sondern die Textfarbe zugewiesen
371 SfxViewShell* pViewSh = SfxViewShell::Current();
372 if ( pViewSh )
374 SdrView* pView = pViewSh->GetDrawView();
375 if ( pView && pView->IsTextEdit() )
377 SvxColorItem aTextColorItem( aColor, SID_ATTR_CHAR_COLOR );
378 pDispatcher->Execute(
379 SID_ATTR_CHAR_COLOR, SfxCallMode::RECORD, &aTextColorItem, 0L );
380 bDone = true;
383 if ( !bDone )
385 XFillStyleItem aXFillStyleItem( drawing::FillStyle_SOLID );
386 XFillColorItem aXFillColorItem( aStr, aColor );
387 pDispatcher->Execute(
388 nLeftSlot, SfxCallMode::RECORD, &aXFillColorItem, &aXFillStyleItem, 0L );
392 else if ( nPos != 1 ) // unsichtbar
394 SvxColorItem aLeftColorItem( aColor, nLeftSlot );
395 pDispatcher->Execute( nLeftSlot, SfxCallMode::RECORD, &aLeftColorItem, 0L );
398 else
400 if ( nRightSlot == SID_ATTR_LINE_COLOR )
402 if( nPos == 1 ) // unsichtbar
404 XLineStyleItem aXLineStyleItem( drawing::LineStyle_NONE );
405 pDispatcher->Execute( nRightSlot, SfxCallMode::RECORD, &aXLineStyleItem, 0L );
407 else
409 // Sollte der LineStyle unsichtbar sein, so wird er auf SOLID gesetzt
410 SfxViewShell* pViewSh = SfxViewShell::Current();
411 if ( pViewSh )
413 SdrView* pView = pViewSh->GetDrawView();
414 if ( pView )
416 SfxItemSet aAttrSet( pView->GetModel()->GetItemPool() );
417 pView->GetAttributes( aAttrSet );
418 if ( aAttrSet.GetItemState( XATTR_LINESTYLE ) != SfxItemState::DONTCARE )
420 drawing::LineStyle eXLS = (drawing::LineStyle)
421 static_cast<const XLineStyleItem&>(aAttrSet.Get( XATTR_LINESTYLE ) ).GetValue();
422 if ( eXLS == drawing::LineStyle_NONE )
424 XLineStyleItem aXLineStyleItem( drawing::LineStyle_SOLID );
425 pDispatcher->Execute( nRightSlot, SfxCallMode::RECORD, &aXLineStyleItem, 0L );
431 XLineColorItem aXLineColorItem( aStr, aColor );
432 pDispatcher->Execute( nRightSlot, SfxCallMode::RECORD, &aXLineColorItem, 0L );
435 else if ( nPos != 1 ) // unsichtbar
437 SvxColorItem aRightColorItem( aColor, nRightSlot );
438 pDispatcher->Execute( nRightSlot, SfxCallMode::RECORD, &aRightColorItem, 0L );
442 return 0;
445 void SvxColorDockingWindow::Resizing( Size& rNewSize )
447 rNewSize.Width() -= 4;
448 rNewSize.Height() -= 4;
450 // Spalten und Reihen ermitteln
451 nCols = (sal_uInt16) ( (float) rNewSize.Width() / (float) aItemSize.Width() + 0.5 );
452 nLines = (sal_uInt16) ( (float) rNewSize.Height() / (float) aItemSize.Height() + 0.5 );
453 if( nLines == 0 )
454 nLines = 1;
456 // Scrollbar setzen/entfernen
457 WinBits nBits = aColorSet->GetStyle();
458 if ( static_cast<long>(nLines) * nCols >= nCount )
459 nBits &= ~WB_VSCROLL;
460 else
461 nBits |= WB_VSCROLL;
462 aColorSet->SetStyle( nBits );
464 // ScrollBar ?
465 long nScrollWidth = aColorSet->GetScrollWidth();
466 if( nScrollWidth > 0 )
468 // Spalten mit ScrollBar berechnen
469 nCols = (sal_uInt16) ( ( ( (float) rNewSize.Width() - (float) nScrollWidth ) )
470 / (float) aItemSize.Width() + 0.5 );
472 if( nCols <= 1 )
473 nCols = 2;
475 // Max. Reihen anhand der gegebenen Spalten berechnen
476 long nMaxLines = nCount / nCols;
477 if( nCount % nCols )
478 nMaxLines++;
480 nLines = sal::static_int_cast< sal_uInt16 >(
481 std::min< long >( nLines, nMaxLines ) );
483 // Groesse des Windows setzen
484 rNewSize.Width() = nCols * aItemSize.Width() + nScrollWidth + 4;
485 rNewSize.Height() = nLines * aItemSize.Height() + 4;
488 void SvxColorDockingWindow::Resize()
490 if ( !IsFloatingMode() || !GetFloatingWindow()->IsRollUp() )
491 SetSize();
492 SfxDockingWindow::Resize();
495 void SvxColorDockingWindow::GetFocus()
497 SfxDockingWindow::GetFocus();
498 if (aColorSet)
500 // Grab the focus to the color value set so that it can be controlled
501 // with the keyboard.
502 aColorSet->GrabFocus();
506 bool SvxColorDockingWindow::Notify( NotifyEvent& rNEvt )
508 bool nRet = false;
509 if( ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT ) )
511 KeyEvent aKeyEvt = *rNEvt.GetKeyEvent();
512 sal_uInt16 nKeyCode = aKeyEvt.GetKeyCode().GetCode();
513 switch( nKeyCode )
515 case KEY_ESCAPE:
516 GrabFocusToDocument();
517 nRet = true;
518 break;
522 return nRet || SfxDockingWindow::Notify( rNEvt );
525 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */