Files
loongoffice/sfx2/source/control/recentdocsviewitem.cxx
Maxim Monastirsky 4a902e0c59 Revert "startcenter: react on mouse down instead"
This reverts commit 1a2a961c1e7cdef648c28e211433e8de6e8a831b.

As suggested by Kendy, opening with a single click
by mouse up is more natural. We need to find a better
solution for the bug mentioned in the above commit.
2014-05-14 16:30:49 +03:00

248 lines
8.1 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <sfx2/recentdocsviewitem.hxx>
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/util/URLTransformer.hpp>
#include <drawinglayer/primitive2d/baseprimitive2d.hxx>
#include <drawinglayer/primitive2d/discretebitmapprimitive2d.hxx>
#include <drawinglayer/processor2d/baseprocessor2d.hxx>
#include <i18nutil/paper.hxx>
#include <sfx2/recentdocsview.hxx>
#include <sfx2/sfxresid.hxx>
#include <sfx2/templateabstractview.hxx>
#include <tools/urlobj.hxx>
#include <unotools/historyoptions.hxx>
#include <vcl/svapp.hxx>
#include <templateview.hrc>
using namespace basegfx;
using namespace com::sun::star;
using namespace com::sun::star::uno;
using namespace drawinglayer::primitive2d;
using namespace drawinglayer::processor2d;
/// Icon that the user can click to remove the document from the recent documents.
struct theRemoveRecentBitmap : public rtl::StaticWithInit<BitmapEx, theRemoveRecentBitmap>
{
BitmapEx operator()()
{
return SfxResId(IMG_RECENTDOC_REMOVE);
}
};
/// Highlighted version of icon that the user can click to remove the document from the recent documents.
struct theRemoveRecentBitmapHighlighted : public rtl::StaticWithInit<BitmapEx, theRemoveRecentBitmapHighlighted>
{
BitmapEx operator()()
{
return SfxResId(IMG_RECENTDOC_REMOVE_HIGHLIGHTED);
}
};
RecentDocsViewItem::RecentDocsViewItem(ThumbnailView &rView, const OUString &rURL,
const OUString &rTitle, const BitmapEx &rThumbnail, sal_uInt16 nId)
: ThumbnailViewItem(rView, nId),
maURL(rURL),
m_bRemoveIconHighlighted(false)
{
OUString aTitle(rTitle);
INetURLObject aURLObj(rURL);
if( aURLObj.GetProtocol() == INET_PROT_FILE )
m_sHelpText = aURLObj.getFSysPath(INetURLObject::FSYS_DETECT);
if( m_sHelpText.isEmpty() )
m_sHelpText = aURLObj.GetURLNoPass();
RecentDocsView& rRecentView = dynamic_cast<RecentDocsView&>(rView);
long nThumbnailSize = rRecentView.GetThumbnailSize();
if (aTitle.isEmpty())
aTitle = aURLObj.GetName(INetURLObject::DECODE_WITH_CHARSET);
BitmapEx aThumbnail(rThumbnail);
if (aThumbnail.IsEmpty() && aURLObj.GetProtocol() == INET_PROT_FILE)
aThumbnail = ThumbnailView::readThumbnail(rURL);
if (aThumbnail.IsEmpty())
{
// Use the default thumbnail if we have nothing else
BitmapEx aExt(RecentDocsView::getDefaultThumbnail(rURL));
Size aExtSize(aExt.GetSizePixel());
// attempt to make it appear as if it is on a piece of paper
long nPaperHeight;
long nPaperWidth;
if( RecentDocsView::typeMatchesExtension(TYPE_IMPRESS, aURLObj.getExtension()) )
{
// Swap width and height (PAPER_SCREEN_4_3 definition make it needed)
PaperInfo aInfo(PAPER_SCREEN_4_3);
nPaperHeight = aInfo.getWidth();
nPaperWidth = aInfo.getHeight();
}
else
{
PaperInfo aInfo(PaperInfo::getSystemDefaultPaper());
nPaperHeight = aInfo.getHeight();
nPaperWidth = aInfo.getWidth();
}
double ratio = double(nThumbnailSize) / double(std::max(nPaperHeight, nPaperWidth));
Size aThumbnailSize(nPaperWidth * ratio, nPaperHeight * ratio);
if (aExtSize.Width() > aThumbnailSize.Width() || aExtSize.Height() > aThumbnailSize.Height())
{
aExt = TemplateAbstractView::scaleImg(aExt, aThumbnailSize.Width(), aThumbnailSize.Height());
aExtSize = aExt.GetSizePixel();
}
// create empty, and copy the default thumbnail in
sal_uInt8 nAlpha = 255;
aThumbnail = BitmapEx(Bitmap(aThumbnailSize, 24), AlphaMask(aThumbnailSize, &nAlpha));
aThumbnail.CopyPixel(
Rectangle(Point((aThumbnailSize.Width() - aExtSize.Width()) / 2, (aThumbnailSize.Height() - aExtSize.Height()) / 2), aExtSize),
Rectangle(Point(0, 0), aExtSize),
&aExt);
}
maTitle = aTitle;
maPreview1 = TemplateAbstractView::scaleImg(aThumbnail, nThumbnailSize, nThumbnailSize);
}
void RecentDocsViewItem::setEditTitle (bool edit, bool bChangeFocus)
{
// Unused parameters.
(void)edit;
(void)bChangeFocus;
}
Rectangle RecentDocsViewItem::updateHighlight(bool bVisible, const Point& rPoint)
{
Rectangle aRect(ThumbnailViewItem::updateHighlight(bVisible, rPoint));
if (bVisible && getRemoveIconArea().IsInside(rPoint))
{
if (!m_bRemoveIconHighlighted)
aRect.Union(getRemoveIconArea());
m_bRemoveIconHighlighted = true;
}
else
{
if (m_bRemoveIconHighlighted)
aRect.Union(getRemoveIconArea());
m_bRemoveIconHighlighted = false;
}
return aRect;
}
Rectangle RecentDocsViewItem::getRemoveIconArea() const
{
Rectangle aArea(getDrawArea());
Size aSize(theRemoveRecentBitmap::get().GetSizePixel());
return Rectangle(
Point(aArea.Right() - aSize.Width() - THUMBNAILVIEW_ITEM_CORNER, aArea.Top() + THUMBNAILVIEW_ITEM_CORNER),
aSize);
}
OUString RecentDocsViewItem::getHelpText() const
{
return m_sHelpText;
}
void RecentDocsViewItem::Paint(drawinglayer::processor2d::BaseProcessor2D *pProcessor, const ThumbnailItemAttributes *pAttrs)
{
ThumbnailViewItem::Paint(pProcessor, pAttrs);
// paint the remove icon when highlighted
if (isHighlighted())
{
drawinglayer::primitive2d::Primitive2DSequence aSeq(1);
Point aIconPos(getRemoveIconArea().TopLeft());
aSeq[0] = drawinglayer::primitive2d::Primitive2DReference(new DiscreteBitmapPrimitive2D(
m_bRemoveIconHighlighted? theRemoveRecentBitmapHighlighted::get(): theRemoveRecentBitmap::get(),
B2DPoint(aIconPos.X(), aIconPos.Y())));
pProcessor->process(aSeq);
}
}
void RecentDocsViewItem::MouseButtonUp(const MouseEvent& rMEvt)
{
if (rMEvt.IsLeft())
{
if (getRemoveIconArea().IsInside(rMEvt.GetPosPixel()))
{
SvtHistoryOptions().DeleteItem(ePICKLIST, maURL);
mrParent.Reload();
return;
}
OpenDocument();
return;
}
}
void RecentDocsViewItem::OpenDocument()
{
// show busy mouse pointer
mrParent.SetPointer(Pointer(POINTER_WAIT));
Reference<frame::XDispatch> xDispatch;
Reference<frame::XDispatchProvider> xDispatchProvider;
css::util::URL aTargetURL;
Sequence<beans::PropertyValue> aArgsList;
uno::Reference<frame::XDesktop2> xDesktop = frame::Desktop::create(::comphelper::getProcessComponentContext());
uno::Reference<frame::XFrame> xActiveFrame = xDesktop->getActiveFrame();
//osl::ClearableMutexGuard aLock(m_aMutex);
xDispatchProvider = Reference<frame::XDispatchProvider>(xActiveFrame, UNO_QUERY);
//aLock.clear();
aTargetURL.Complete = maURL;
Reference<util::XURLTransformer> xTrans(util::URLTransformer::create(::comphelper::getProcessComponentContext()));
xTrans->parseStrict(aTargetURL);
sal_Int32 nSize = 2;
aArgsList.realloc(nSize);
aArgsList[0].Name = "Referer";
aArgsList[0].Value = makeAny(OUString("private:user"));
// documents will never be opened as templates
aArgsList[1].Name = "AsTemplate";
aArgsList[1].Value = makeAny(false);
xDispatch = xDispatchProvider->queryDispatch(aTargetURL, "_default", 0);
if (xDispatch.is())
{
// Call dispatch asychronously as we can be destroyed while dispatch is
// executed. VCL is not able to survive this as it wants to call listeners
// after select!!!
LoadRecentFile* pLoadRecentFile = new LoadRecentFile;
pLoadRecentFile->xDispatch = xDispatch;
pLoadRecentFile->aTargetURL = aTargetURL;
pLoadRecentFile->aArgSeq = aArgsList;
Application::PostUserEvent(STATIC_LINK(0, RecentDocsView, ExecuteHdl_Impl), pLoadRecentFile);
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */