bump product version to 4.2.0.1
[LibreOffice.git] / sfx2 / source / control / thumbnailviewitem.cxx
blob7fdf428c1b199595ab22b25f448c133a8be35148
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 <sfx2/thumbnailviewitem.hxx>
22 #include <sfx2/thumbnailview.hxx>
23 #include "thumbnailviewacc.hxx"
25 #include <basegfx/matrix/b2dhommatrixtools.hxx>
26 #include <basegfx/range/b2drectangle.hxx>
27 #include <basegfx/vector/b2dsize.hxx>
28 #include <basegfx/polygon/b2dpolygon.hxx>
29 #include <drawinglayer/attribute/fillgraphicattribute.hxx>
30 #include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx>
31 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
32 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
33 #include <drawinglayer/primitive2d/textlayoutdevice.hxx>
34 #include <drawinglayer/primitive2d/textprimitive2d.hxx>
35 #include <drawinglayer/processor2d/baseprocessor2d.hxx>
36 #include <vcl/button.hxx>
37 #include <vcl/graph.hxx>
38 #include <vcl/svapp.hxx>
39 #include <vcl/texteng.hxx>
40 #include <svtools/optionsdrawinglayer.hxx>
42 using namespace basegfx;
43 using namespace basegfx::tools;
44 using namespace ::com::sun::star;
45 using namespace drawinglayer::attribute;
46 using namespace drawinglayer::primitive2d;
48 class ResizableMultiLineEdit : public VclMultiLineEdit
50 private:
51 ThumbnailViewItem* mpItem;
52 bool mbIsInGrabFocus;
54 public:
55 ResizableMultiLineEdit (Window* pParent, ThumbnailViewItem* pItem);
56 ~ResizableMultiLineEdit ();
58 void SetInGrabFocus(bool bInGrabFocus) { mbIsInGrabFocus = bInGrabFocus; }
60 virtual long PreNotify(NotifyEvent& rNEvt);
61 virtual void Modify();
64 ResizableMultiLineEdit::ResizableMultiLineEdit (Window* pParent, ThumbnailViewItem* pItem) :
65 VclMultiLineEdit (pParent, WB_CENTER | WB_BORDER),
66 mpItem(pItem),
67 mbIsInGrabFocus(false)
71 ResizableMultiLineEdit::~ResizableMultiLineEdit ()
75 long ResizableMultiLineEdit::PreNotify(NotifyEvent& rNEvt)
77 long nDone = 0;
78 if( rNEvt.GetType() == EVENT_KEYINPUT )
80 const KeyEvent& rKEvt = *rNEvt.GetKeyEvent();
81 KeyCode aCode = rKEvt.GetKeyCode();
82 switch (aCode.GetCode())
84 case KEY_RETURN:
85 mpItem->setTitle( GetText() );
86 case KEY_ESCAPE:
87 mpItem->setEditTitle(false);
88 nDone = 1;
89 break;
90 default:
91 break;
94 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS && !mbIsInGrabFocus )
96 mpItem->setTitle( GetText() );
97 mpItem->setEditTitle(false, false);
99 return nDone ? nDone : VclMultiLineEdit::PreNotify(rNEvt);
102 void ResizableMultiLineEdit::Modify()
104 VclMultiLineEdit::Modify();
105 mpItem->updateTitleEditSize();
108 ThumbnailViewItem::ThumbnailViewItem(ThumbnailView &rView, sal_uInt16 nId)
109 : mrParent(rView)
110 , mnId(nId)
111 , mbVisible(true)
112 , mbSelected(false)
113 , mbHover(false)
114 , mpxAcc(NULL)
115 , mbEditTitle(false)
116 , mpTitleED(NULL)
117 , maTextEditMaxArea()
119 mpTitleED = new ResizableMultiLineEdit(&rView, this);
122 ThumbnailViewItem::~ThumbnailViewItem()
124 delete mpTitleED;
125 if( mpxAcc )
127 static_cast< ThumbnailViewItemAcc* >( mpxAcc->get() )->ParentDestroyed();
128 delete mpxAcc;
132 void ThumbnailViewItem::show (bool bVisible)
134 mbVisible = bVisible;
135 if (!mbVisible)
136 mpTitleED->Show(false);
139 void ThumbnailViewItem::setSelection (bool state)
141 mbSelected = state;
144 void ThumbnailViewItem::setHighlight (bool state)
146 mbHover = state;
149 OUString ThumbnailViewItem::getHelpText() const
151 return maTitle;
154 void ThumbnailViewItem::setEditTitle (bool edit, bool bChangeFocus)
156 mbEditTitle = edit;
157 mpTitleED->Show(edit);
158 if (edit)
160 mpTitleED->SetText(maTitle);
161 updateTitleEditSize();
162 static_cast<ResizableMultiLineEdit*>(mpTitleED)->SetInGrabFocus(true);
163 mpTitleED->GrabFocus();
164 static_cast<ResizableMultiLineEdit*>(mpTitleED)->SetInGrabFocus(false);
166 else if (bChangeFocus)
168 mrParent.GrabFocus();
172 Rectangle ThumbnailViewItem::getTextArea() const
174 Rectangle aTextArea(maTextEditMaxArea);
176 TextEngine aTextEngine;
177 aTextEngine.SetMaxTextWidth(maDrawArea.getWidth());
178 aTextEngine.SetText(maTitle);
180 long nTxtHeight = aTextEngine.GetTextHeight() + 6;
181 if (nTxtHeight < aTextArea.GetHeight())
182 aTextArea.SetSize(Size(aTextArea.GetWidth(), nTxtHeight));
184 return aTextArea;
187 void ThumbnailViewItem::updateTitleEditSize()
189 Rectangle aTextArea = getTextArea();
190 Point aPos = aTextArea.TopLeft();
191 Size aSize = aTextArea.GetSize();
192 mpTitleED->SetPosSizePixel(aPos, aSize);
195 void ThumbnailViewItem::setTitle (const OUString& rTitle)
197 if (mrParent.renameItem(this, rTitle))
198 maTitle = rTitle;
201 uno::Reference< accessibility::XAccessible > ThumbnailViewItem::GetAccessible( bool bIsTransientChildrenDisabled )
203 if( !mpxAcc )
204 mpxAcc = new uno::Reference< accessibility::XAccessible >( new ThumbnailViewItemAcc( this, bIsTransientChildrenDisabled ) );
206 return *mpxAcc;
209 void ThumbnailViewItem::setDrawArea (const Rectangle &area)
211 maDrawArea = area;
214 void ThumbnailViewItem::calculateItemsPosition (const long nThumbnailHeight, const long,
215 const long nPadding, sal_uInt32 nMaxTextLenght,
216 const ThumbnailItemAttributes *pAttrs)
218 drawinglayer::primitive2d::TextLayouterDevice aTextDev;
219 aTextDev.setFontAttribute(pAttrs->aFontAttr,
220 pAttrs->aFontSize.getX(), pAttrs->aFontSize.getY(),
221 com::sun::star::lang::Locale() );
223 Size aRectSize = maDrawArea.GetSize();
224 Size aImageSize = maPreview1.GetSizePixel();
226 // Calculate thumbnail position
227 Point aPos = maDrawArea.TopLeft();
228 aPos.X() = maDrawArea.getX() + (aRectSize.Width()-aImageSize.Width())/2;
229 aPos.Y() = maDrawArea.getY() + nPadding + (nThumbnailHeight-aImageSize.Height())/2;
230 maPrev1Pos = aPos;
232 // Calculate text position
233 aPos.Y() = maDrawArea.getY() + nThumbnailHeight + nPadding * 2;
234 aPos.X() = maDrawArea.Left() + (aRectSize.Width() - aTextDev.getTextWidth(maTitle,0,nMaxTextLenght))/2;
235 maTextPos = aPos;
237 // Calculate the text edit max area
238 aPos = Point(maDrawArea.getX() + nPadding, maTextPos.getY());
239 Size aEditSize(maDrawArea.GetWidth() - nPadding * 2,
240 maDrawArea.Bottom() - maTextPos.Y());
241 maTextEditMaxArea = Rectangle( aPos, aEditSize );
244 void ThumbnailViewItem::setSelectClickHdl (const Link &link)
246 maClickHdl = link;
249 void ThumbnailViewItem::Paint (drawinglayer::processor2d::BaseProcessor2D *pProcessor,
250 const ThumbnailItemAttributes *pAttrs)
252 BColor aFillColor = pAttrs->aFillColor;
253 drawinglayer::primitive2d::Primitive2DSequence aSeq(4);
254 double fTransparence = 0.0;
256 // Draw background
257 if (mbSelected || mbHover)
258 aFillColor = pAttrs->aHighlightColor;
260 if (mbHover)
262 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
263 fTransparence = aSvtOptionsDrawinglayer.GetTransparentSelectionPercent() * 0.01;
266 sal_uInt32 nPrimitive = 0;
267 aSeq[nPrimitive++] = drawinglayer::primitive2d::Primitive2DReference( new PolyPolygonSelectionPrimitive2D(
268 B2DPolyPolygon(Polygon(maDrawArea,5,5).getB2DPolygon()),
269 aFillColor,
270 fTransparence,
271 0.0,
272 true));
274 // Draw thumbnail
275 Point aPos = maPrev1Pos;
276 Size aImageSize = maPreview1.GetSizePixel();
278 aSeq[nPrimitive++] = drawinglayer::primitive2d::Primitive2DReference( new FillGraphicPrimitive2D(
279 createTranslateB2DHomMatrix(aPos.X(),aPos.Y()),
280 FillGraphicAttribute(Graphic(maPreview1),
281 B2DRange(
282 B2DPoint(0,0),
283 B2DPoint(aImageSize.Width(),aImageSize.Height())),
284 false)
287 // draw thumbnail borders
288 float fWidth = aImageSize.Width();
289 float fHeight = aImageSize.Height();
290 float fPosX = maPrev1Pos.getX();
291 float fPosY = maPrev1Pos.getY();
293 B2DPolygon aBounds;
294 aBounds.append(B2DPoint(fPosX,fPosY));
295 aBounds.append(B2DPoint(fPosX+fWidth,fPosY));
296 aBounds.append(B2DPoint(fPosX+fWidth,fPosY+fHeight));
297 aBounds.append(B2DPoint(fPosX,fPosY+fHeight));
298 aBounds.setClosed(true);
300 aSeq[nPrimitive++] = drawinglayer::primitive2d::Primitive2DReference(createBorderLine(aBounds));
302 // Draw text below thumbnail
303 aPos = maTextPos;
304 addTextPrimitives( maTitle, pAttrs, aPos, aSeq );
306 pProcessor->process(aSeq);
309 void ThumbnailViewItem::addTextPrimitives (const OUString& rText, const ThumbnailItemAttributes *pAttrs, Point aPos, drawinglayer::primitive2d::Primitive2DSequence& rSeq)
311 drawinglayer::primitive2d::TextLayouterDevice aTextDev;
313 aPos.setY(aPos.getY() + aTextDev.getTextHeight());
315 OUString aText (rText);
317 TextEngine aTextEngine;
318 aTextEngine.SetMaxTextWidth(maDrawArea.getWidth());
319 aTextEngine.SetText(rText);
321 sal_Int32 nPrimitives = rSeq.getLength();
322 rSeq.realloc(nPrimitives + aTextEngine.GetLineCount(0));
324 // Create the text primitives
325 sal_uInt16 nLineStart = 0;
326 for (sal_uInt16 i=0; i<aTextEngine.GetLineCount(0); ++i)
328 sal_uInt16 nLineLength = aTextEngine.GetLineLen(0, i);
329 double nLineWidth = aTextDev.getTextWidth (aText, nLineStart, nLineLength);
331 bool bTooLong = (aPos.getY() + aTextEngine.GetCharHeight()) > maDrawArea.Bottom();
332 if (bTooLong && (nLineLength + nLineStart) < rText.getLength())
334 // Add the '...' to the last line to show, even though it may require to shorten the line
335 double nDotsWidth = aTextDev.getTextWidth(OUString("..."),0,3);
337 sal_uInt16 nLength = nLineLength - 1;
338 while ( nDotsWidth + aTextDev.getTextWidth(aText, nLineStart, nLength) > maDrawArea.getWidth() && nLength > 0)
340 --nLength;
343 aText = aText.copy(0, nLineStart+nLength);
344 aText += "...";
345 nLineLength = nLength + 3;
348 double nLineX = maDrawArea.Left() + (maDrawArea.getWidth() - nLineWidth) / 2.0;
350 basegfx::B2DHomMatrix aTextMatrix( createScaleTranslateB2DHomMatrix(
351 pAttrs->aFontSize.getX(), pAttrs->aFontSize.getY(),
352 nLineX, double( aPos.Y() ) ) );
354 rSeq[nPrimitives++] = drawinglayer::primitive2d::Primitive2DReference(
355 new TextSimplePortionPrimitive2D(aTextMatrix,
356 aText,nLineStart,nLineLength,
357 std::vector< double >( ),
358 pAttrs->aFontAttr,
359 com::sun::star::lang::Locale(),
360 Color(COL_BLACK).getBColor() ) );
361 nLineStart += nLineLength;
362 aPos.setY(aPos.getY() + aTextEngine.GetCharHeight());
364 if (bTooLong)
365 break;
369 drawinglayer::primitive2d::PolygonHairlinePrimitive2D*
370 ThumbnailViewItem::createBorderLine (const basegfx::B2DPolygon& rPolygon)
372 return new PolygonHairlinePrimitive2D(rPolygon, Color(186,186,186).getBColor());
375 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */