mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-24 10:52:51 +00:00
plasma: import folderview plugin from kde-baseapps
This commit is contained in:
parent
eac99cb4c4
commit
988ffd4fb4
48 changed files with 12648 additions and 0 deletions
|
@ -1,6 +1,7 @@
|
|||
add_subdirectory(homerun)
|
||||
add_subdirectory(kickoff)
|
||||
add_subdirectory(trash)
|
||||
add_subdirectory(folderview)
|
||||
|
||||
#task and windowlist depend on libs/taskmanager
|
||||
add_subdirectory(tasks)
|
||||
|
|
43
plasma/desktop/applets/folderview/CMakeLists.txt
Normal file
43
plasma/desktop/applets/folderview/CMakeLists.txt
Normal file
|
@ -0,0 +1,43 @@
|
|||
project(plasma-folderview)
|
||||
|
||||
include_directories(${LIBKONQ_INCLUDE_DIR})
|
||||
|
||||
if(Q_WS_X11)
|
||||
find_package(X11 REQUIRED)
|
||||
endif(Q_WS_X11)
|
||||
|
||||
set(folderview_SRCS
|
||||
folderview.cpp
|
||||
abstractitemview.cpp
|
||||
listview.cpp
|
||||
dialog.cpp
|
||||
dialogshadows.cpp
|
||||
label.cpp
|
||||
iconview.cpp
|
||||
popupview.cpp
|
||||
iconwidget.cpp
|
||||
dirlister.cpp
|
||||
proxymodel.cpp
|
||||
folderviewadapter.cpp
|
||||
previewpluginsmodel.cpp
|
||||
tooltipwidget.cpp
|
||||
style.cpp
|
||||
itemeditor.cpp
|
||||
animator.cpp
|
||||
actionoverlay.cpp
|
||||
asyncfiletester.cpp)
|
||||
|
||||
kde4_add_ui_files(folderview_SRCS
|
||||
folderviewFilterConfig.ui
|
||||
folderviewDisplayConfig.ui
|
||||
folderviewLocationConfig.ui
|
||||
folderviewPreviewConfig.ui)
|
||||
|
||||
kde4_add_plugin(plasma_applet_folderview ${folderview_SRCS})
|
||||
|
||||
target_link_libraries(plasma_applet_folderview ${KDE4_PLASMA_LIBS} ${LIBKONQ_LIBRARY}
|
||||
${KDE4_KIO_LIBS} ${KDE4_KFILE_LIBS} ${KDE4_SOLID_LIBS} ${X11_LIBRARIES})
|
||||
|
||||
install(TARGETS plasma_applet_folderview DESTINATION ${PLUGIN_INSTALL_DIR})
|
||||
install(FILES plasma-applet-folderview.desktop DESTINATION ${SERVICES_INSTALL_DIR})
|
||||
|
2
plasma/desktop/applets/folderview/ConfigureChecks.cmake
Normal file
2
plasma/desktop/applets/folderview/ConfigureChecks.cmake
Normal file
|
@ -0,0 +1,2 @@
|
|||
macro_bool_to_01(KDE4WORKSPACE_FOUND HAVE_KWORKSPACE)
|
||||
|
3
plasma/desktop/applets/folderview/Messages.sh
Executable file
3
plasma/desktop/applets/folderview/Messages.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#! /usr/bin/env bash
|
||||
$EXTRACTRC *.ui >> rc.cpp
|
||||
$XGETTEXT *.cpp -o $podir/plasma_applet_folderview.pot
|
744
plasma/desktop/applets/folderview/abstractitemview.cpp
Normal file
744
plasma/desktop/applets/folderview/abstractitemview.cpp
Normal file
|
@ -0,0 +1,744 @@
|
|||
/*
|
||||
* Copyright © 2008, 2009 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* The smooth scrolling code is based on the code in KHTMLView,
|
||||
* Copyright © 2006-2008 Germain Garand <germain@ebooksfrance.org>
|
||||
* Copyright © 2008 Allan Sandfeld Jensen <kde@carewolf.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "abstractitemview.h"
|
||||
#include "proxymodel.h"
|
||||
#include "style.h"
|
||||
|
||||
#include <QItemSelectionModel>
|
||||
#include <QPaintEngine>
|
||||
|
||||
#include <KDirModel>
|
||||
#include <KFileItemDelegate>
|
||||
#include <KGlobalSettings>
|
||||
|
||||
#include <Plasma/PaintUtils>
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
# include <QX11Info>
|
||||
# include <X11/Xlib.h>
|
||||
#endif
|
||||
|
||||
|
||||
static const int sSmoothScrollTime = 140;
|
||||
static const int sSmoothScrollTick = 14;
|
||||
|
||||
|
||||
AbstractItemView::AbstractItemView(QGraphicsWidget *parent)
|
||||
: QGraphicsWidget(parent),
|
||||
m_itemFrame(0),
|
||||
m_delegate(0),
|
||||
m_lastScrollValue(0),
|
||||
m_viewScrolled(false),
|
||||
m_dx(0),
|
||||
m_ddx(0),
|
||||
m_dddx(0),
|
||||
m_rdx(0),
|
||||
m_dy(0),
|
||||
m_ddy(0),
|
||||
m_dddy(0),
|
||||
m_rdy(0),
|
||||
m_smoothScrolling(false),
|
||||
m_autoScrollSpeed(0),
|
||||
m_drawShadows(true)
|
||||
{
|
||||
m_scrollBar = new Plasma::ScrollBar(this);
|
||||
connect(m_scrollBar, SIGNAL(valueChanged(int)), SLOT(scrollBarValueChanged(int)));
|
||||
connect(m_scrollBar->nativeWidget(), SIGNAL(actionTriggered(int)), SLOT(scrollBarActionTriggered(int)));
|
||||
connect(m_scrollBar->nativeWidget(), SIGNAL(sliderReleased()), SLOT(scrollBarSliderReleased()));
|
||||
|
||||
m_itemFrame = new Plasma::FrameSvg(this);
|
||||
m_itemFrame->setImagePath("widgets/viewitem");
|
||||
m_itemFrame->setCacheAllRenderedFrames(true);
|
||||
m_itemFrame->setElementPrefix("normal");
|
||||
connect(m_itemFrame, SIGNAL(repaintNeeded()), this, SLOT(svgChanged()));
|
||||
|
||||
// This is a dummy widget that's never shown - it's just passed to
|
||||
// KFileItemDelegate in the style options, so it will use the widget's
|
||||
// style to draw the view item backgrounds.
|
||||
m_styleWidget = new QWidget;
|
||||
m_style = new FolderViewStyle;
|
||||
m_styleWidget->setStyle(m_style);
|
||||
|
||||
const int size = style()->pixelMetric(QStyle::PM_LargeIconSize);
|
||||
m_iconSize = QSize(size, size);
|
||||
|
||||
}
|
||||
|
||||
AbstractItemView::~AbstractItemView()
|
||||
{
|
||||
delete m_styleWidget;
|
||||
delete m_style;
|
||||
}
|
||||
|
||||
void AbstractItemView::setModel(QAbstractItemModel *model)
|
||||
{
|
||||
m_model = static_cast<ProxyModel*>(model);
|
||||
m_dirModel = static_cast<KDirModel*>(m_model->sourceModel());
|
||||
|
||||
connect(m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(rowsInserted(QModelIndex,int,int)));
|
||||
connect(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), SLOT(rowsRemoved(QModelIndex,int,int)));
|
||||
connect(m_model, SIGNAL(modelReset()), SLOT(modelReset()));
|
||||
connect(m_model, SIGNAL(layoutChanged()), SLOT(layoutChanged()));
|
||||
connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(dataChanged(QModelIndex,QModelIndex)));
|
||||
}
|
||||
|
||||
QAbstractItemModel *AbstractItemView::model() const
|
||||
{
|
||||
return m_model;
|
||||
}
|
||||
|
||||
void AbstractItemView::setSelectionModel(QItemSelectionModel *model)
|
||||
{
|
||||
m_selectionModel = model;
|
||||
}
|
||||
|
||||
QItemSelectionModel *AbstractItemView::selectionModel() const
|
||||
{
|
||||
return m_selectionModel;
|
||||
}
|
||||
|
||||
void AbstractItemView::setItemDelegate(KFileItemDelegate *delegate)
|
||||
{
|
||||
m_delegate = static_cast<KFileItemDelegate*>(delegate);
|
||||
|
||||
connect(m_delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
|
||||
SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
|
||||
connect(m_delegate, SIGNAL(commitData(QWidget*)), SLOT(commitData(QWidget*)));
|
||||
}
|
||||
|
||||
KFileItemDelegate *AbstractItemView::itemDelegate() const
|
||||
{
|
||||
return m_delegate;
|
||||
}
|
||||
|
||||
void AbstractItemView::setIconSize(const QSize &iconSize)
|
||||
{
|
||||
m_iconSize = iconSize;
|
||||
}
|
||||
|
||||
QSize AbstractItemView::iconSize() const
|
||||
{
|
||||
return m_iconSize;
|
||||
}
|
||||
|
||||
void AbstractItemView::setDrawShadows(bool on)
|
||||
{
|
||||
if (m_drawShadows != on) {
|
||||
m_drawShadows = on;
|
||||
markAreaDirty(visibleArea());
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
bool AbstractItemView::drawShadows() const
|
||||
{
|
||||
return m_drawShadows;
|
||||
}
|
||||
|
||||
QScrollBar *AbstractItemView::verticalScrollBar() const
|
||||
{
|
||||
return m_scrollBar->nativeWidget();
|
||||
}
|
||||
|
||||
QRect AbstractItemView::visibleArea() const
|
||||
{
|
||||
return mapToViewport(contentsRect()).toAlignedRect();
|
||||
}
|
||||
|
||||
// Marks the given rect in viewport coordinates, as dirty and schedules a repaint.
|
||||
void AbstractItemView::markAreaDirty(const QRect &rect)
|
||||
{
|
||||
if (!rect.isEmpty() && rect.intersects(visibleArea())) {
|
||||
m_dirtyRegion += rect;
|
||||
update(mapFromViewport(rect));
|
||||
}
|
||||
}
|
||||
|
||||
// This function scrolls the contents of the backbuffer the distance the scrollbar
|
||||
// has moved since the last time this function was called.
|
||||
QRect AbstractItemView::scrollBackBuffer()
|
||||
{
|
||||
const int value = m_scrollBar->value();
|
||||
const int delta = m_lastScrollValue - value;
|
||||
m_lastScrollValue = value;
|
||||
|
||||
if (qAbs(delta) >= m_pixmap.height()) {
|
||||
return visibleArea();
|
||||
}
|
||||
|
||||
int sy, dy, h;
|
||||
QRect dirty;
|
||||
if (delta < 0) {
|
||||
dy = 0;
|
||||
sy = -delta;
|
||||
h = m_pixmap.height() - sy;
|
||||
dirty = QRect(0, m_pixmap.height() - sy, m_pixmap.width(), sy);
|
||||
} else {
|
||||
dy = delta;
|
||||
sy = 0;
|
||||
h = m_pixmap.height() - dy;
|
||||
dirty = QRect(0, 0, m_pixmap.width(), dy);
|
||||
}
|
||||
|
||||
#if defined(Q_WS_X11)
|
||||
const QPaintEngine::Type type = m_pixmap.paintEngine()->type();
|
||||
if (type == QPaintEngine::X11) {
|
||||
Display *dpy = QX11Info::display();
|
||||
GC gc = XCreateGC(dpy, m_pixmap.handle(), 0, 0);
|
||||
XCopyArea(dpy, m_pixmap.handle(), m_pixmap.handle(), gc, 0, sy, m_pixmap.width(), h, 0, dy);
|
||||
XFreeGC(dpy, gc);
|
||||
} else if (type == QPaintEngine::Raster) {
|
||||
// Hack to prevent the image from detaching
|
||||
const QImage image = m_pixmap.toImage();
|
||||
const uchar *src = image.scanLine(sy);
|
||||
uchar *dst = const_cast<uchar*>(image.scanLine(dy));
|
||||
memmove((void*)dst, (const void*)src, h * image.bytesPerLine());
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
dirty = m_pixmap.rect();
|
||||
}
|
||||
|
||||
return mapToViewport(dirty.translated(contentsRect().topLeft().toPoint())).toAlignedRect();
|
||||
}
|
||||
|
||||
void AbstractItemView::prepareBackBuffer()
|
||||
{
|
||||
const QRect cr = contentsRect().toRect();
|
||||
|
||||
// Make sure the backbuffer pixmap has the same size as the content rect
|
||||
if (m_pixmap.size() != cr.size()) {
|
||||
QPixmap pixmap(cr.size());
|
||||
pixmap.fill(Qt::transparent);
|
||||
if (!m_pixmap.isNull()) {
|
||||
// Static content optimization
|
||||
#ifdef Q_WS_X11
|
||||
if (m_pixmap.paintEngine()->type() == QPaintEngine::X11) {
|
||||
GC gc = XCreateGC(QX11Info::display(), pixmap.handle(), 0, NULL);
|
||||
XCopyArea(QX11Info::display(), m_pixmap.handle(), pixmap.handle(), gc, 0, 0,
|
||||
m_pixmap.width(), m_pixmap.height(), 0, 0);
|
||||
XFreeGC(QX11Info::display(), gc);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
QPainter p(&pixmap);
|
||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
p.drawPixmap(0, 0, m_pixmap);
|
||||
}
|
||||
QRegion region(pixmap.rect());
|
||||
region -= m_pixmap.rect();
|
||||
region.translate(0, m_scrollBar->value());
|
||||
m_dirtyRegion |= region;
|
||||
} else {
|
||||
m_dirtyRegion = QRegion(visibleArea());
|
||||
}
|
||||
m_pixmap = pixmap;
|
||||
}
|
||||
|
||||
if (m_viewScrolled) {
|
||||
m_dirtyRegion += scrollBackBuffer();
|
||||
m_viewScrolled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// This function draws the backbuffer pixmap on the widget, and fades out the top
|
||||
// and bottom if as needed.
|
||||
void AbstractItemView::syncBackBuffer(QPainter *painter, const QRect &clipRect)
|
||||
{
|
||||
const QRect cr = contentsRect().toRect();
|
||||
|
||||
const int fadeHeight = 16;
|
||||
const QRect topFadeRect(cr.x(), cr.y(), cr.width(), fadeHeight);
|
||||
const QRect bottomFadeRect(cr.bottomLeft() - QPoint(0, fadeHeight), QSize(cr.width(), fadeHeight));
|
||||
int scrollValue = m_scrollBar->value();
|
||||
int maxValue = m_scrollBar->maximum();
|
||||
|
||||
// Draw the backbuffer on the widget
|
||||
// =================================
|
||||
if ((scrollValue > 0 && topFadeRect.intersects(clipRect)) ||
|
||||
(scrollValue < maxValue && bottomFadeRect.intersects(clipRect)))
|
||||
{
|
||||
QPixmap pixmap = m_pixmap;
|
||||
QPainter p(&pixmap);
|
||||
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||
|
||||
// Fade out the top section of the pixmap if the scrollbar slider isn't at the top
|
||||
if (scrollValue > 0 && topFadeRect.intersects(clipRect))
|
||||
{
|
||||
if (m_topFadeTile.isNull())
|
||||
{
|
||||
m_topFadeTile = QPixmap(256, fadeHeight);
|
||||
m_topFadeTile.fill(Qt::transparent);
|
||||
QLinearGradient g(0, 0, 0, fadeHeight);
|
||||
g.setColorAt(0, Qt::transparent);
|
||||
g.setColorAt(1, Qt::black);
|
||||
QPainter p(&m_topFadeTile);
|
||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
p.fillRect(0, 0, 256, fadeHeight, g);
|
||||
p.end();
|
||||
}
|
||||
p.drawTiledPixmap(0, 0, m_pixmap.width(), fadeHeight, m_topFadeTile);
|
||||
}
|
||||
|
||||
// Fade out the bottom part of the pixmap if the scrollbar slider isn't at the bottom
|
||||
if (scrollValue < maxValue && bottomFadeRect.intersects(clipRect))
|
||||
{
|
||||
if (m_topFadeTile.isNull())
|
||||
{
|
||||
m_bottomFadeTile = QPixmap(256, fadeHeight);
|
||||
m_bottomFadeTile.fill(Qt::transparent);
|
||||
QLinearGradient g(0, 0, 0, fadeHeight);
|
||||
g.setColorAt(0, Qt::black);
|
||||
g.setColorAt(1, Qt::transparent);
|
||||
QPainter p(&m_bottomFadeTile);
|
||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
p.fillRect(0, 0, 256, fadeHeight, g);
|
||||
p.end();
|
||||
}
|
||||
p.drawTiledPixmap(0, m_pixmap.height() - fadeHeight, m_pixmap.width(), fadeHeight, m_bottomFadeTile);
|
||||
}
|
||||
p.end();
|
||||
|
||||
painter->drawPixmap(cr.topLeft(), pixmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
painter->drawPixmap(cr.topLeft(), m_pixmap);
|
||||
}
|
||||
}
|
||||
|
||||
QSize AbstractItemView::doTextLayout(QTextLayout &layout, const QSize &constraints, Qt::Alignment alignment,
|
||||
QTextOption::WrapMode wrapMode) const
|
||||
{
|
||||
QTextOption to;
|
||||
to.setAlignment(alignment);
|
||||
to.setTextDirection(layoutDirection());
|
||||
to.setWrapMode(wrapMode);
|
||||
layout.setTextOption(to);
|
||||
|
||||
QFontMetricsF fm = QFontMetricsF(layout.font());
|
||||
|
||||
QTextLine line;
|
||||
qreal leading = fm.leading();
|
||||
qreal widthUsed = 0;
|
||||
qreal height = 0;
|
||||
|
||||
layout.beginLayout();
|
||||
while ((line = layout.createLine()).isValid()) {
|
||||
// Make the last line that will fit infinitely long.
|
||||
// drawTextLayout() will handle this by fading the line out
|
||||
// if it won't fit inside the constraints.
|
||||
if (height + 2 * fm.lineSpacing() > constraints.height()) {
|
||||
line.setLineWidth(INT_MAX);
|
||||
if (line.naturalTextWidth() < constraints.width()) {
|
||||
line.setLineWidth(constraints.width());
|
||||
widthUsed = qMax(widthUsed, line.naturalTextWidth());
|
||||
} else {
|
||||
widthUsed = constraints.width();
|
||||
}
|
||||
} else {
|
||||
line.setLineWidth(constraints.width());
|
||||
widthUsed = qMax(widthUsed, line.naturalTextWidth());
|
||||
}
|
||||
line.setPosition(QPointF(0, height));
|
||||
height += line.height() + leading;
|
||||
}
|
||||
layout.endLayout();
|
||||
|
||||
return QSize(widthUsed, height);
|
||||
}
|
||||
|
||||
void AbstractItemView::drawTextLayout(QPainter *painter, const QTextLayout &layout, const QRect &rect) const
|
||||
{
|
||||
// Create the alpha gradient for the fade out effect
|
||||
QLinearGradient alphaGradient(0, 0, 1, 0);
|
||||
alphaGradient.setCoordinateMode(QGradient::ObjectBoundingMode);
|
||||
if (layout.textOption().textDirection() == Qt::LeftToRight) {
|
||||
alphaGradient.setColorAt(0, QColor(0, 0, 0, 255));
|
||||
alphaGradient.setColorAt(1, QColor(0, 0, 0, 0));
|
||||
} else {
|
||||
alphaGradient.setColorAt(0, QColor(0, 0, 0, 0));
|
||||
alphaGradient.setColorAt(1, QColor(0, 0, 0, 255));
|
||||
}
|
||||
|
||||
QFontMetrics fm(layout.font());
|
||||
|
||||
QList<QRect> fadeRects;
|
||||
QList<QRect> haloRects;
|
||||
int fadeWidth = 30;
|
||||
|
||||
// Compute halo and fade rects
|
||||
for (int i = 0; i < layout.lineCount(); i++) {
|
||||
const QTextLine line = layout.lineAt(i);
|
||||
const QRectF lr = line.naturalTextRect();
|
||||
|
||||
// Add a fade out rect to the list if the line is too long
|
||||
if (lr.width() > rect.width()) {
|
||||
int x = rect.width() - fadeWidth;
|
||||
int y = lr.y();
|
||||
QRect r = QStyle::visualRect(layout.textOption().textDirection(), QRect(QPoint(), rect.size()),
|
||||
QRect(x, y, fadeWidth, int(lr.height())));
|
||||
fadeRects.append(r);
|
||||
}
|
||||
|
||||
haloRects.append((lr & rect.translated(-rect.topLeft())).toAlignedRect());
|
||||
}
|
||||
|
||||
// Create a pixmap for the text
|
||||
QPixmap pixmap(rect.size());
|
||||
pixmap.fill(Qt::transparent);
|
||||
|
||||
QPainter p(&pixmap);
|
||||
p.setPen(painter->pen());
|
||||
|
||||
int y = 0;
|
||||
if (layout.textOption().alignment() & Qt::AlignVCenter) {
|
||||
const int h = fm.height() * layout.lineCount();
|
||||
if (h < pixmap.height()) {
|
||||
y = (pixmap.height() - h) / 2;
|
||||
}
|
||||
}
|
||||
p.translate(0, y);
|
||||
|
||||
// Draw each line in the layout
|
||||
for (int i = 0; i < layout.lineCount(); i++)
|
||||
{
|
||||
const QTextLine line = layout.lineAt(i);
|
||||
const QRectF tr = line.naturalTextRect();
|
||||
|
||||
if (tr.width() > rect.width()) {
|
||||
if (layoutDirection() == Qt::LeftToRight) {
|
||||
line.draw(&p, QPointF(-tr.x(), 0));
|
||||
} else {
|
||||
line.draw(&p, QPointF(rect.width() - tr.right(), 0));
|
||||
}
|
||||
} else {
|
||||
line.draw(&p, QPointF());
|
||||
}
|
||||
}
|
||||
|
||||
// Reduce the alpha in each fade out rect using the alpha gradient
|
||||
if (!fadeRects.isEmpty()) {
|
||||
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||
foreach (const QRect &rect, fadeRects) {
|
||||
p.fillRect(rect, alphaGradient);
|
||||
}
|
||||
}
|
||||
p.end();
|
||||
|
||||
if (drawShadows()) {
|
||||
const QColor color = painter->pen().color();
|
||||
if (qGray(color.rgb()) < 192) {
|
||||
// Draw halos
|
||||
painter->translate(0, y);
|
||||
foreach (const QRect &haloRect, haloRects) {
|
||||
Plasma::PaintUtils::drawHalo(painter, haloRect.translated(rect.topLeft()));
|
||||
}
|
||||
painter->translate(0, -y);
|
||||
} else {
|
||||
// Draw shadow
|
||||
QImage shadow = pixmap.toImage();
|
||||
Plasma::PaintUtils::shadowBlur(shadow, 2, Qt::black);
|
||||
|
||||
// Make the shadow twice as dark
|
||||
quint32 * const pixels = reinterpret_cast<quint32*>(shadow.bits());
|
||||
for (int i = 0; i < shadow.width() * shadow.height(); i++) {
|
||||
pixels[i] = qMin(255, qAlpha(pixels[i]) * 2) << 24;
|
||||
}
|
||||
|
||||
painter->drawImage(rect.topLeft() + QPoint(1, 1), shadow);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the text pixmap
|
||||
painter->drawPixmap(rect.topLeft(), pixmap);
|
||||
}
|
||||
|
||||
void AbstractItemView::rowsInserted(const QModelIndex &parent, int first, int last)
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
Q_UNUSED(first)
|
||||
Q_UNUSED(last)
|
||||
}
|
||||
|
||||
void AbstractItemView::rowsRemoved(const QModelIndex &parent, int first, int last)
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
Q_UNUSED(first)
|
||||
Q_UNUSED(last)
|
||||
}
|
||||
|
||||
void AbstractItemView::modelReset()
|
||||
{
|
||||
}
|
||||
|
||||
void AbstractItemView::layoutChanged()
|
||||
{
|
||||
}
|
||||
|
||||
void AbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
|
||||
{
|
||||
Q_UNUSED(topLeft)
|
||||
Q_UNUSED(bottomRight)
|
||||
}
|
||||
|
||||
void AbstractItemView::commitData(QWidget *editor)
|
||||
{
|
||||
Q_UNUSED(editor)
|
||||
}
|
||||
|
||||
void AbstractItemView::closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint)
|
||||
{
|
||||
Q_UNUSED(editor)
|
||||
Q_UNUSED(hint)
|
||||
}
|
||||
|
||||
void AbstractItemView::svgChanged()
|
||||
{
|
||||
}
|
||||
|
||||
void AbstractItemView::scrollTo(const QModelIndex &index, QAbstractItemView::ScrollHint hint)
|
||||
{
|
||||
Q_UNUSED(hint)
|
||||
|
||||
const QRectF r = mapFromViewport(visualRect(index));
|
||||
|
||||
if (r.top() < 0) {
|
||||
smoothScroll(0, r.top());
|
||||
} else if (r.bottom() > geometry().height()) {
|
||||
smoothScroll(0, r.bottom() - geometry().height());
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractItemView::autoScroll(ScrollDirection direction, int pixelsPerSecond)
|
||||
{
|
||||
m_scrollDirection = direction;
|
||||
m_autoScrollSetSpeed = direction == ScrollUp ? -pixelsPerSecond : pixelsPerSecond;
|
||||
|
||||
if (!m_autoScrollTimer.isActive()) {
|
||||
m_autoScrollSpeed = 1;
|
||||
m_autoScrollTime.restart();
|
||||
m_autoScrollTimer.start(1000 / 30, this);
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractItemView::stopAutoScrolling()
|
||||
{
|
||||
m_autoScrollSetSpeed = 0;
|
||||
m_autoScrollTimer.stop();
|
||||
}
|
||||
|
||||
void AbstractItemView::scrollBarValueChanged(int value)
|
||||
{
|
||||
Q_UNUSED(value)
|
||||
|
||||
m_viewScrolled = true;
|
||||
update();
|
||||
}
|
||||
|
||||
void AbstractItemView::scrollBarActionTriggered(int action)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case QAbstractSlider::SliderSingleStepAdd:
|
||||
case QAbstractSlider::SliderSingleStepSub:
|
||||
case QAbstractSlider::SliderPageStepAdd:
|
||||
case QAbstractSlider::SliderPageStepSub:
|
||||
stopAutoScrolling();
|
||||
smoothScroll(0, m_scrollBar->nativeWidget()->sliderPosition() - m_scrollBar->value());
|
||||
break;
|
||||
|
||||
case QAbstractSlider::SliderToMinimum:
|
||||
case QAbstractSlider::SliderToMaximum:
|
||||
stopAutoScrolling();
|
||||
// Use a delayed call since the value won't propagate until after this function returns
|
||||
QMetaObject::invokeMethod(this, "finishedScrolling", Qt::QueuedConnection);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractItemView::scrollBarSliderReleased()
|
||||
{
|
||||
finishedScrolling();
|
||||
}
|
||||
|
||||
void AbstractItemView::finishedScrolling()
|
||||
{
|
||||
}
|
||||
|
||||
void AbstractItemView::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
if (event->timerId() == m_smoothScrollTimer.timerId()) {
|
||||
scrollTick();
|
||||
} else if (event->timerId() == m_autoScrollTimer.timerId()) {
|
||||
int step = qRound(m_autoScrollTime.elapsed() * (m_autoScrollSpeed / 1000.));
|
||||
m_autoScrollTime.restart();
|
||||
|
||||
if (m_scrollDirection == ScrollUp && m_scrollBar->value() > m_scrollBar->minimum()) {
|
||||
m_scrollBar->setValue(qMax(m_scrollBar->minimum(), m_scrollBar->value() + step));
|
||||
} else if (m_scrollDirection == ScrollDown && m_scrollBar->value() < m_scrollBar->maximum()) {
|
||||
m_scrollBar->setValue(qMin(m_scrollBar->maximum(), m_scrollBar->value() + step));
|
||||
} else {
|
||||
m_autoScrollSetSpeed = 0;
|
||||
m_autoScrollSpeed = 0;
|
||||
}
|
||||
|
||||
if (m_autoScrollSetSpeed > m_autoScrollSpeed) {
|
||||
int delta;
|
||||
if (m_autoScrollSpeed >= 0) {
|
||||
delta = qBound(2, m_autoScrollSpeed * 2, 30);
|
||||
} else {
|
||||
delta = qBound(2, qAbs(m_autoScrollSpeed) / 2, 30);
|
||||
}
|
||||
m_autoScrollSpeed = qMin(m_autoScrollSpeed + delta, m_autoScrollSetSpeed);
|
||||
} else if (m_autoScrollSetSpeed < m_autoScrollSpeed) {
|
||||
int delta;
|
||||
if (m_autoScrollSpeed >= 0) {
|
||||
delta = qBound(2, m_autoScrollSpeed / 2, 30);
|
||||
} else {
|
||||
delta = qBound(2, qAbs(m_autoScrollSpeed * 2), 30);
|
||||
}
|
||||
m_autoScrollSpeed = qMax(m_autoScrollSetSpeed, m_autoScrollSpeed - delta);
|
||||
}
|
||||
|
||||
if (m_autoScrollSpeed == 0 && m_autoScrollSetSpeed == 0) {
|
||||
m_autoScrollTimer.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractItemView::startScrolling()
|
||||
{
|
||||
m_smoothScrolling = true;
|
||||
m_smoothScrollTimer.start(sSmoothScrollTick, this);
|
||||
}
|
||||
|
||||
void AbstractItemView::stopScrolling()
|
||||
{
|
||||
m_smoothScrollTimer.stop();
|
||||
m_dx = m_dy = 0;
|
||||
m_ddx = m_ddy = 0;
|
||||
m_rdx = m_rdy = 0;
|
||||
m_dddx = m_dddy = 0;
|
||||
m_smoothScrolling = false;
|
||||
finishedScrolling();
|
||||
}
|
||||
|
||||
void AbstractItemView::smoothScroll(int dx, int dy)
|
||||
{
|
||||
// full scroll is remaining scroll plus new scroll
|
||||
m_dx = m_dx + dx;
|
||||
m_dy = m_dy + dy;
|
||||
|
||||
if (m_dx == 0 && m_dy == 0) return;
|
||||
|
||||
int steps = sSmoothScrollTime/sSmoothScrollTick;
|
||||
|
||||
// average step size (stored in 1/16 px/step)
|
||||
m_ddx = (m_dx*16)/(steps+1);
|
||||
m_ddy = (m_dy*16)/(steps+1);
|
||||
|
||||
if (qAbs(m_ddx) < 64 && qAbs(m_ddy) < 64) {
|
||||
// Don't move slower than average 4px/step in minimum one direction
|
||||
if (m_ddx > 0) m_ddx = qMax(m_ddx, 64);
|
||||
if (m_ddy > 0) m_ddy = qMax(m_ddy, 64);
|
||||
if (m_ddx < 0) m_ddx = qMin(m_ddx, -64);
|
||||
if (m_ddy < 0) m_ddy = qMin(m_ddy, -64);
|
||||
// This means fewer than normal steps
|
||||
steps = qMax(m_ddx ? (m_dx*16)/m_ddx : 0, m_ddy ? (m_dy*16)/m_ddy : 0);
|
||||
if (steps < 1) steps = 1;
|
||||
m_ddx = (m_dx*16)/(steps+1);
|
||||
m_ddy = (m_dy*16)/(steps+1);
|
||||
}
|
||||
|
||||
// step size starts at double average speed and ends at 0
|
||||
m_ddx *= 2;
|
||||
m_ddy *= 2;
|
||||
|
||||
// deacceleration speed
|
||||
m_dddx = (m_ddx+1)/steps;
|
||||
m_dddy = (m_ddy+1)/steps;
|
||||
|
||||
if (!m_smoothScrolling) {
|
||||
startScrolling();
|
||||
scrollTick();
|
||||
}
|
||||
m_smoothScrollStopwatch.start();
|
||||
}
|
||||
|
||||
void AbstractItemView::scrollTick() {
|
||||
if (m_dx == 0 && m_dy == 0) {
|
||||
stopScrolling();
|
||||
return;
|
||||
}
|
||||
|
||||
// step size + remaining partial step
|
||||
int tddx = m_ddx + m_rdx;
|
||||
int tddy = m_ddy + m_rdy;
|
||||
|
||||
// don't go under 1px/step
|
||||
if (tddx > 0 && tddx < 16) tddx = 16;
|
||||
if (tddy > 0 && tddy < 16) tddy = 16;
|
||||
if (tddx < 0 && tddx > -16) tddx = -16;
|
||||
if (tddy < 0 && tddy > -16) tddy = -16;
|
||||
|
||||
// full pixel steps to scroll in this step
|
||||
int ddx = tddx / 16;
|
||||
int ddy = tddy / 16;
|
||||
// remaining partial step (this is especially needed for 1.x sized steps)
|
||||
m_rdx = tddx % 16;
|
||||
m_rdy = tddy % 16;
|
||||
|
||||
// limit step to requested scrolling distance
|
||||
if (qAbs(ddx) > qAbs(m_dx)) ddx = m_dx;
|
||||
if (qAbs(ddy) > qAbs(m_dy)) ddy = m_dy;
|
||||
|
||||
// Don't stop if deaccelerated too fast
|
||||
if (!ddx) ddx = m_dx;
|
||||
if (!ddy) ddy = m_dy;
|
||||
|
||||
// update remaining scroll
|
||||
m_dx -= ddx;
|
||||
m_dy -= ddy;
|
||||
|
||||
m_scrollBar->setValue(m_scrollBar->value() + ddy);
|
||||
|
||||
// only consider decelerating if we aren't too far behind schedule
|
||||
if (m_smoothScrollStopwatch.elapsed() < 2 * sSmoothScrollTick) {
|
||||
// update scrolling speed
|
||||
int dddx = m_dddx;
|
||||
int dddy = m_dddy;
|
||||
// don't change direction
|
||||
if (abs(dddx) > abs(m_ddx)) dddx = m_ddx;
|
||||
if (abs(dddy) > abs(m_ddy)) dddy = m_ddy;
|
||||
|
||||
m_ddx -= dddx;
|
||||
m_ddy -= dddy;
|
||||
}
|
||||
m_smoothScrollStopwatch.start();
|
||||
}
|
||||
|
||||
#include "moc_abstractitemview.cpp"
|
187
plasma/desktop/applets/folderview/abstractitemview.h
Normal file
187
plasma/desktop/applets/folderview/abstractitemview.h
Normal file
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Copyright © 2008, 2009 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef ABSTRACTITEMVIEW_H
|
||||
#define ABSTRACTITEMVIEW_H
|
||||
|
||||
#include <QGraphicsWidget>
|
||||
#include <QAbstractItemDelegate>
|
||||
#include <QAbstractItemView>
|
||||
#include <QPointer>
|
||||
#include <QCache>
|
||||
#include <QTextLayout>
|
||||
#include <QTime>
|
||||
#include <QBasicTimer>
|
||||
|
||||
#include <plasma/widgets/scrollbar.h>
|
||||
#include <plasma/framesvg.h>
|
||||
|
||||
|
||||
class KDirModel;
|
||||
class KFileItemDelegate;
|
||||
class QItemSelectionModel;
|
||||
class ProxyModel;
|
||||
class QScrollBar;
|
||||
|
||||
|
||||
// The abstract base class for IconView and ListView
|
||||
class AbstractItemView : public QGraphicsWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize)
|
||||
Q_PROPERTY(bool drawShadows READ drawShadows WRITE setDrawShadows)
|
||||
|
||||
public:
|
||||
enum ScrollDirection { ScrollUp, ScrollDown };
|
||||
|
||||
AbstractItemView(QGraphicsWidget *parent = 0);
|
||||
~AbstractItemView();
|
||||
|
||||
virtual void setModel(QAbstractItemModel *model);
|
||||
QAbstractItemModel *model() const;
|
||||
|
||||
void setSelectionModel(QItemSelectionModel *model);
|
||||
QItemSelectionModel *selectionModel() const;
|
||||
|
||||
void setItemDelegate(KFileItemDelegate *delegate);
|
||||
KFileItemDelegate *itemDelegate() const;
|
||||
|
||||
virtual void setIconSize(const QSize &iconSize);
|
||||
QSize iconSize() const;
|
||||
|
||||
void setDrawShadows(bool on);
|
||||
bool drawShadows() const;
|
||||
|
||||
QScrollBar *verticalScrollBar() const;
|
||||
|
||||
QRect visibleArea() const;
|
||||
virtual QModelIndex indexAt(const QPointF &point) const = 0;
|
||||
virtual QRect visualRect(const QModelIndex &index) const = 0;
|
||||
|
||||
QPointF mapToViewport(const QPointF &point) const;
|
||||
QRectF mapToViewport(const QRectF &rect) const;
|
||||
QPointF mapFromViewport(const QPointF &point) const;
|
||||
QRectF mapFromViewport(const QRectF &rect) const;
|
||||
|
||||
void markAreaDirty(const QRect &rect);
|
||||
void markAreaDirty(const QRectF &rect) { markAreaDirty(rect.toAlignedRect()); }
|
||||
|
||||
void scrollTo(const QModelIndex &index, QAbstractItemView::ScrollHint hint = QAbstractItemView::EnsureVisible);
|
||||
void autoScroll(ScrollDirection direction, int pixelsPerSecond);
|
||||
void stopAutoScrolling();
|
||||
|
||||
signals:
|
||||
void activated(const QModelIndex &index);
|
||||
void entered(const QModelIndex &index);
|
||||
void left(const QModelIndex &index);
|
||||
void contextMenuRequest(QWidget *widget, const QPoint &screenPos);
|
||||
|
||||
protected:
|
||||
QRect scrollBackBuffer();
|
||||
void prepareBackBuffer();
|
||||
void syncBackBuffer(QPainter *painter, const QRect &clipRect);
|
||||
|
||||
QSize doTextLayout(QTextLayout &layout, const QSize &constraints, Qt::Alignment alignment,
|
||||
QTextOption::WrapMode wrapMode) const;
|
||||
void drawTextLayout(QPainter *painter, const QTextLayout &layout, const QRect &rect) const;
|
||||
|
||||
void timerEvent(QTimerEvent *event);
|
||||
|
||||
void smoothScroll(int dx, int dy);
|
||||
void startScrolling();
|
||||
void stopScrolling();
|
||||
void scrollTick();
|
||||
|
||||
protected slots:
|
||||
virtual void rowsInserted(const QModelIndex &parent, int first, int last);
|
||||
virtual void rowsRemoved(const QModelIndex &parent, int first, int last);
|
||||
virtual void modelReset();
|
||||
virtual void layoutChanged();
|
||||
virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
|
||||
virtual void commitData(QWidget *editor);
|
||||
virtual void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint);
|
||||
|
||||
virtual void finishedScrolling();
|
||||
virtual void svgChanged();
|
||||
|
||||
private slots:
|
||||
void scrollBarValueChanged(int value);
|
||||
void scrollBarActionTriggered(int action);
|
||||
void scrollBarSliderReleased();
|
||||
|
||||
protected:
|
||||
Plasma::FrameSvg *m_itemFrame;
|
||||
KFileItemDelegate *m_delegate;
|
||||
QPointer<KDirModel> m_dirModel;
|
||||
QPointer<ProxyModel> m_model;
|
||||
QPointer<QItemSelectionModel> m_selectionModel;
|
||||
QSize m_iconSize;
|
||||
QRegion m_dirtyRegion;
|
||||
QPixmap m_pixmap;
|
||||
QPixmap m_topFadeTile;
|
||||
QPixmap m_bottomFadeTile;
|
||||
Plasma::ScrollBar *m_scrollBar;
|
||||
QStyle *m_style;
|
||||
QWidget *m_styleWidget;
|
||||
int m_lastScrollValue;
|
||||
bool m_viewScrolled;
|
||||
|
||||
// These variables are for the smooth scrolling code
|
||||
int m_dx;
|
||||
int m_ddx;
|
||||
int m_dddx;
|
||||
int m_rdx;
|
||||
int m_dy;
|
||||
int m_ddy;
|
||||
int m_dddy;
|
||||
int m_rdy;
|
||||
bool m_smoothScrolling;
|
||||
QBasicTimer m_smoothScrollTimer;
|
||||
QBasicTimer m_autoScrollTimer;
|
||||
QTime m_smoothScrollStopwatch;
|
||||
QTime m_autoScrollTime;
|
||||
ScrollDirection m_scrollDirection;
|
||||
int m_autoScrollSpeed;
|
||||
int m_autoScrollSetSpeed;
|
||||
bool m_drawShadows;
|
||||
};
|
||||
|
||||
inline QPointF AbstractItemView::mapToViewport(const QPointF &point) const
|
||||
{
|
||||
return point + QPointF(0, m_scrollBar->value());
|
||||
}
|
||||
|
||||
inline QRectF AbstractItemView::mapToViewport(const QRectF &rect) const
|
||||
{
|
||||
return rect.translated(0, m_scrollBar->value());
|
||||
}
|
||||
|
||||
inline QPointF AbstractItemView::mapFromViewport(const QPointF &point) const
|
||||
{
|
||||
return point - QPointF(0, m_scrollBar->value());
|
||||
}
|
||||
|
||||
inline QRectF AbstractItemView::mapFromViewport(const QRectF &rect) const
|
||||
{
|
||||
return rect.translated(0, -m_scrollBar->value());
|
||||
}
|
||||
|
||||
#endif // ABSTRACTITEMVIEW_H
|
||||
|
321
plasma/desktop/applets/folderview/actionoverlay.cpp
Normal file
321
plasma/desktop/applets/folderview/actionoverlay.cpp
Normal file
|
@ -0,0 +1,321 @@
|
|||
/*
|
||||
* Copyright © 2009, 2010 Fredrik Höglund <fredrik@kde.org>
|
||||
* Copyright © 2009 Bruno Bigras <bigras.bruno@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "actionoverlay.h"
|
||||
#include "asyncfiletester.h"
|
||||
#include "iconview.h"
|
||||
|
||||
#include <Plasma/PaintUtils>
|
||||
#include <Plasma/Animator>
|
||||
#include <Plasma/Svg>
|
||||
|
||||
#include <QPainter>
|
||||
#include <QGraphicsGridLayout>
|
||||
|
||||
ActionIcon::ActionIcon(QGraphicsItem* parent)
|
||||
: QGraphicsWidget(parent),
|
||||
m_pressed(false),
|
||||
m_sunken(false)
|
||||
{
|
||||
setAcceptHoverEvents(true);
|
||||
setCacheMode(DeviceCoordinateCache);
|
||||
|
||||
m_icon = new Plasma::Svg(this);
|
||||
m_icon->setImagePath("widgets/action-overlays");
|
||||
m_icon->setContainsMultipleImages(true);
|
||||
|
||||
setMinimumSize(m_icon->elementSize("add-normal"));
|
||||
setMaximumSize(minimumSize());
|
||||
|
||||
show();
|
||||
}
|
||||
|
||||
void ActionIcon::setElement(const QString &element)
|
||||
{
|
||||
m_element = element;
|
||||
}
|
||||
|
||||
void ActionIcon::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
|
||||
{
|
||||
Q_UNUSED(option)
|
||||
Q_UNUSED(widget)
|
||||
|
||||
QString element = m_element;
|
||||
|
||||
if (m_sunken) {
|
||||
element += "-pressed";
|
||||
} else if (isUnderMouse()) {
|
||||
element += "-hover";
|
||||
} else {
|
||||
element += "-normal";
|
||||
}
|
||||
|
||||
m_icon->paint(painter, rect(), element);
|
||||
}
|
||||
|
||||
void ActionIcon::mousePressEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
m_pressed = true;
|
||||
m_sunken = true;
|
||||
update();
|
||||
}
|
||||
|
||||
void ActionIcon::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
m_pressed = false;
|
||||
m_sunken = false;
|
||||
if (isUnderMouse()) {
|
||||
emit clicked();
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
void ActionIcon::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
if (m_sunken != isUnderMouse()) {
|
||||
m_sunken = isUnderMouse();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void ActionIcon::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
emit iconHoverEnter();
|
||||
update();
|
||||
}
|
||||
|
||||
void ActionIcon::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
emit iconHoverLeave();
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
|
||||
ActionOverlay::ActionOverlay(AbstractItemView* parent)
|
||||
: QGraphicsWidget(parent)
|
||||
{
|
||||
m_toggleButton = new ActionIcon(this);
|
||||
m_openButton = new ActionIcon(this);
|
||||
m_openButton->setElement("open");
|
||||
|
||||
m_showFolderButton = true;
|
||||
m_showSelectionButton = true;
|
||||
|
||||
m_layout = new QGraphicsGridLayout(this);
|
||||
m_layout->setContentsMargins(4, 4, 4, 4);
|
||||
m_layout->setSpacing(1);
|
||||
m_layout->addItem(m_toggleButton, 0, 0);
|
||||
m_layout->addItem(m_openButton, 1, 0);
|
||||
|
||||
connect(parentWidget(), SIGNAL(entered(QModelIndex)), this, SLOT(entered(QModelIndex)));
|
||||
connect(parentWidget(), SIGNAL(left(QModelIndex)), this, SLOT(left(QModelIndex)));
|
||||
connect(parentWidget(), SIGNAL(modelChanged()), this, SLOT(modelChanged()));
|
||||
|
||||
connect(m_toggleButton, SIGNAL(clicked()), this, SLOT(toggleSelection()));
|
||||
connect(m_openButton, SIGNAL(clicked()), this, SLOT(openPopup()));
|
||||
|
||||
m_hideActionOverlayIconTimer = new QTimer(this);
|
||||
connect(m_hideActionOverlayIconTimer, SIGNAL(timeout()), this, SLOT(timeout()));
|
||||
|
||||
connect(m_toggleButton, SIGNAL(iconHoverEnter()), m_hideActionOverlayIconTimer, SLOT(stop()));
|
||||
connect(m_toggleButton, SIGNAL(iconHoverLeave()), m_hideActionOverlayIconTimer, SLOT(start()));
|
||||
connect(m_openButton, SIGNAL(iconHoverEnter()), m_hideActionOverlayIconTimer, SLOT(stop()));
|
||||
connect(m_openButton, SIGNAL(iconHoverLeave()), m_hideActionOverlayIconTimer, SLOT(start()));
|
||||
|
||||
connect(parent->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(close()));
|
||||
|
||||
m_hideActionOverlayIconTimer->setInterval(500);
|
||||
m_hideActionOverlayIconTimer->setSingleShot(true);
|
||||
|
||||
fadeIn = Plasma::Animator::create(Plasma::Animator::FadeAnimation, this);
|
||||
fadeIn->setProperty("startOpacity", 0);
|
||||
fadeIn->setProperty("targetOpacity", 1);
|
||||
fadeIn->setTargetWidget(this);
|
||||
|
||||
fadeOut = Plasma::Animator::create(Plasma::Animator::FadeAnimation, this);
|
||||
fadeOut->setProperty("startOpacity", 1);
|
||||
fadeOut->setProperty("targetOpacity", 0);
|
||||
fadeOut->setTargetWidget(this);
|
||||
connect(fadeOut, SIGNAL(finished()), SLOT(close()));
|
||||
|
||||
hide();
|
||||
}
|
||||
|
||||
void ActionOverlay::toggleSelection()
|
||||
{
|
||||
AbstractItemView *view = static_cast<AbstractItemView*>(parentWidget());
|
||||
QItemSelectionModel *m_selectionModel = view->selectionModel();
|
||||
|
||||
if (m_hoverIndex.isValid()) {
|
||||
const QModelIndex oldCurrent = m_selectionModel->currentIndex();
|
||||
m_selectionModel->select(m_hoverIndex, QItemSelectionModel::Toggle);
|
||||
m_selectionModel->setCurrentIndex(m_hoverIndex, QItemSelectionModel::NoUpdate);
|
||||
m_toggleButton->setElement(m_selectionModel->isSelected(m_hoverIndex) ? "remove" : "add");
|
||||
view->markAreaDirty(view->visualRect(m_hoverIndex));
|
||||
if (oldCurrent.isValid() && oldCurrent != m_hoverIndex) {
|
||||
view->markAreaDirty(view->visualRect(oldCurrent));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActionOverlay::openPopup()
|
||||
{
|
||||
if (IconView *view = qobject_cast<IconView*>(parentWidget())) {
|
||||
view->openPopup(m_hoverIndex);
|
||||
}
|
||||
}
|
||||
|
||||
QPersistentModelIndex ActionOverlay::hoverIndex()
|
||||
{
|
||||
return m_hoverIndex;
|
||||
}
|
||||
|
||||
void ActionOverlay::entered(const QModelIndex &index)
|
||||
{
|
||||
m_hideActionOverlayIconTimer->stop();
|
||||
|
||||
if (index.isValid()) {
|
||||
AbstractItemView *view = static_cast<AbstractItemView*>(parentWidget());
|
||||
QItemSelectionModel *m_selectionModel = view->selectionModel();
|
||||
m_toggleButton->setElement(m_selectionModel->isSelected(index) ? "remove" : "add");
|
||||
setPos(view->mapFromViewport(view->visualRect(index)).topLeft());
|
||||
show();
|
||||
if (m_hoverIndex != index) {
|
||||
m_toggleButton->update();
|
||||
fadeOut->stop();
|
||||
fadeIn->start();
|
||||
}
|
||||
m_hoverIndex = index;
|
||||
IconView *iview = qobject_cast<IconView*>(view);
|
||||
if (iview && iview->clickToViewFolders()) {
|
||||
AsyncFileTester::checkIfFolder(index, this, "checkIfFolderResult");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActionOverlay::checkIfFolderResult(const QModelIndex &index, bool isFolder)
|
||||
{
|
||||
if (index == m_hoverIndex) {
|
||||
m_openButton->setVisible(isFolder);
|
||||
}
|
||||
}
|
||||
|
||||
void ActionOverlay::left(const QModelIndex &index)
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
|
||||
if (!m_hideActionOverlayIconTimer->isActive()) {
|
||||
m_hideActionOverlayIconTimer->start();
|
||||
}
|
||||
}
|
||||
|
||||
void ActionOverlay::timeout()
|
||||
{
|
||||
// allow the animation to restart after hiding the ActionOverlayIcon even if m_hoverIndex didn't change
|
||||
m_hoverIndex = QPersistentModelIndex();
|
||||
|
||||
if (isVisible() && (fadeOut->state() != QAbstractAnimation::Running)) {
|
||||
fadeIn->stop();
|
||||
fadeOut->start();
|
||||
}
|
||||
}
|
||||
|
||||
void ActionOverlay::forceHide(HideHint hint)
|
||||
{
|
||||
m_hideActionOverlayIconTimer->stop();
|
||||
if (hint == FadeOut) {
|
||||
timeout();
|
||||
} else {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
void ActionOverlay::rowsRemoved(const QModelIndex & parent, int start, int end)
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
Q_UNUSED(start);
|
||||
Q_UNUSED(end);
|
||||
|
||||
if (!m_hoverIndex.isValid()) {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
void ActionOverlay::modelChanged()
|
||||
{
|
||||
AbstractItemView *view = static_cast<AbstractItemView*>(parentWidget());
|
||||
|
||||
QAbstractItemModel *mod = view->model();
|
||||
connect(mod, SIGNAL(rowsRemoved(QModelIndex,int,int)), SLOT(rowsRemoved(QModelIndex,int,int)));
|
||||
}
|
||||
|
||||
void ActionOverlay::setShowFolderButton(bool show)
|
||||
{
|
||||
if (m_showFolderButton != show) {
|
||||
m_showFolderButton = show;
|
||||
toggleShowActionButton(show, m_openButton, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ActionOverlay::setShowSelectionButton(bool show)
|
||||
{
|
||||
if (m_showSelectionButton!= show) {
|
||||
m_showSelectionButton = show;
|
||||
toggleShowActionButton(show, m_toggleButton, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool ActionOverlay::showFolderButton() const
|
||||
{
|
||||
return m_showFolderButton;
|
||||
}
|
||||
bool ActionOverlay::showSelectionButton() const
|
||||
{
|
||||
return m_showSelectionButton;
|
||||
}
|
||||
|
||||
QSizeF ActionOverlay::iconSize() const
|
||||
{
|
||||
return m_openButton->geometry().size();
|
||||
}
|
||||
|
||||
void ActionOverlay::toggleShowActionButton(bool show, ActionIcon* button, unsigned int pos)
|
||||
{
|
||||
if (show && m_layout->itemAt(pos, 0) != button) {
|
||||
m_layout->addItem(button, pos, 0);
|
||||
button->show();
|
||||
} else if (m_layout->itemAt(pos, 0) == button) {
|
||||
button->hide();
|
||||
m_layout->removeItem(button);
|
||||
}
|
||||
}
|
108
plasma/desktop/applets/folderview/actionoverlay.h
Normal file
108
plasma/desktop/applets/folderview/actionoverlay.h
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright © 2009, 2010 Fredrik Höglund <fredrik@kde.org>
|
||||
* Copyright © 2009 Bruno Bigras <bigras.bruno@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef ACTIONOVERLAY_H
|
||||
#define ACTIONOVERLAY_H
|
||||
|
||||
#include "abstractitemview.h"
|
||||
|
||||
#include <Plasma/Animation>
|
||||
|
||||
#include <QTimer>
|
||||
#include <QGraphicsWidget>
|
||||
#include <QPersistentModelIndex>
|
||||
#include <QGraphicsGridLayout>
|
||||
|
||||
namespace Plasma {
|
||||
class Svg;
|
||||
}
|
||||
|
||||
class ActionIcon : public QGraphicsWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ActionIcon(QGraphicsItem* parent = 0);
|
||||
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0);
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
|
||||
void setElement(const QString &element);
|
||||
|
||||
signals:
|
||||
void clicked();
|
||||
void iconHoverEnter();
|
||||
void iconHoverLeave();
|
||||
|
||||
private:
|
||||
Plasma::Svg *m_icon;
|
||||
QString m_element;
|
||||
bool m_pressed;
|
||||
bool m_sunken;
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
class ActionOverlay : public QGraphicsWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum HideHint { HideNow, FadeOut };
|
||||
|
||||
ActionOverlay(AbstractItemView *parent = 0);
|
||||
QPersistentModelIndex hoverIndex();
|
||||
void forceHide(HideHint hint);
|
||||
|
||||
void setShowFolderButton(bool show);
|
||||
void setShowSelectionButton(bool show);
|
||||
bool showFolderButton() const;
|
||||
bool showSelectionButton() const;
|
||||
|
||||
QSizeF iconSize() const;
|
||||
|
||||
private slots:
|
||||
void toggleSelection();
|
||||
void openPopup();
|
||||
void entered(const QModelIndex &index);
|
||||
void left(const QModelIndex &index);
|
||||
void timeout();
|
||||
void modelChanged();
|
||||
void rowsRemoved(const QModelIndex& indexes, int start, int end);
|
||||
void checkIfFolderResult(const QModelIndex &index, bool isFolder);
|
||||
void toggleShowActionButton(bool show, ActionIcon *button, unsigned int pos);
|
||||
|
||||
private:
|
||||
ActionIcon *m_toggleButton;
|
||||
ActionIcon *m_openButton;
|
||||
QPersistentModelIndex m_hoverIndex;
|
||||
QTimer *m_hideActionOverlayIconTimer;
|
||||
Plasma::Animation *fadeIn;
|
||||
Plasma::Animation *fadeOut;
|
||||
bool m_showFolderButton;
|
||||
bool m_showSelectionButton;
|
||||
QGraphicsGridLayout * m_layout;
|
||||
};
|
||||
|
||||
#endif // ACTIONOVERLAY_H
|
139
plasma/desktop/applets/folderview/animator.cpp
Normal file
139
plasma/desktop/applets/folderview/animator.cpp
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright © 2009 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "animator.h"
|
||||
#include "abstractitemview.h"
|
||||
|
||||
|
||||
HoverAnimation::HoverAnimation(AbstractItemView *view, const QModelIndex &index)
|
||||
: QAbstractAnimation(view), m_index(index), m_curve(QEasingCurve::InQuad)
|
||||
{
|
||||
}
|
||||
|
||||
void HoverAnimation::setEasingCurve(QEasingCurve::Type type)
|
||||
{
|
||||
m_curve.setType(type);
|
||||
}
|
||||
|
||||
qreal HoverAnimation::progress() const
|
||||
{
|
||||
return m_curve.valueForProgress(m_progress);
|
||||
}
|
||||
|
||||
void HoverAnimation::updateCurrentTime(int currentTime)
|
||||
{
|
||||
m_progress = qreal(currentTime) / duration();
|
||||
|
||||
AbstractItemView *view = static_cast<AbstractItemView*>(parent());
|
||||
view->markAreaDirty(view->visualRect(m_index));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
Animator::Animator(AbstractItemView *view)
|
||||
: QObject(view)
|
||||
{
|
||||
m_effectsOn = (KGlobalSettings::graphicEffectsLevel() >= KGlobalSettings::SimpleAnimationEffects); //do not animate if the graphics effects are set to Low CPU
|
||||
connect(KGlobalSettings::self(), SIGNAL(settingsChanged(int)), SLOT(graphicsEffectsToggled(int)));
|
||||
connect(view, SIGNAL(entered(QModelIndex)), SLOT(entered(QModelIndex)));
|
||||
connect(view, SIGNAL(left(QModelIndex)), SLOT(left(QModelIndex)));
|
||||
}
|
||||
|
||||
Animator::~Animator()
|
||||
{
|
||||
}
|
||||
|
||||
HoverAnimation *Animator::findHoverAnimation(const QModelIndex &index) const
|
||||
{
|
||||
foreach (HoverAnimation *animation, m_list) {
|
||||
if (animation->index() == index) {
|
||||
return animation;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Animator::animate(Type type, const QModelIndex &index)
|
||||
{
|
||||
AbstractItemView *view = static_cast<AbstractItemView*>(parent());
|
||||
HoverAnimation *animation = findHoverAnimation(index);
|
||||
|
||||
if (!animation) {
|
||||
animation = new HoverAnimation(view, index);
|
||||
connect(animation, SIGNAL(destroyed(QObject*)), SLOT(animationDestroyed(QObject*)));
|
||||
m_list.append(animation);
|
||||
}
|
||||
|
||||
if (type == HoverEnter) {
|
||||
animation->setDirection(QAbstractAnimation::Forward);
|
||||
} else {
|
||||
animation->setDirection(QAbstractAnimation::Backward);
|
||||
}
|
||||
|
||||
if (animation->state() != QAbstractAnimation::Running) {
|
||||
animation->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
}
|
||||
}
|
||||
|
||||
qreal Animator::hoverProgress(const QModelIndex &index) const
|
||||
{
|
||||
if (HoverAnimation *animation = findHoverAnimation(index)) {
|
||||
return animation->progress();
|
||||
}
|
||||
|
||||
return (index == m_hoveredIndex) ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
void Animator::animationDestroyed(QObject *obj)
|
||||
{
|
||||
m_list.removeOne(static_cast<HoverAnimation*>(obj));
|
||||
}
|
||||
|
||||
void Animator::entered(const QModelIndex &index)
|
||||
{
|
||||
m_hoveredIndex = index;
|
||||
if (m_effectsOn) {
|
||||
animate(HoverEnter, index);
|
||||
}
|
||||
}
|
||||
|
||||
void Animator::left(const QModelIndex &index)
|
||||
{
|
||||
m_hoveredIndex = QModelIndex();
|
||||
if (m_effectsOn) {
|
||||
animate(HoverLeave, index);
|
||||
}
|
||||
}
|
||||
|
||||
void Animator::graphicsEffectsToggled(int category)
|
||||
{
|
||||
if ( (category == KGlobalSettings::SETTINGS_STYLE) && (KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) ) {
|
||||
m_effectsOn = true;
|
||||
} else {
|
||||
m_effectsOn = false;
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_animator.cpp"
|
||||
|
82
plasma/desktop/applets/folderview/animator.h
Normal file
82
plasma/desktop/applets/folderview/animator.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright © 2009 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef ANIMATOR_H
|
||||
#define ANIMATOR_H
|
||||
|
||||
#include <QAbstractAnimation>
|
||||
#include <QEasingCurve>
|
||||
#include <QModelIndex>
|
||||
|
||||
#include <kglobalsettings.h>
|
||||
|
||||
class AbstractItemView;
|
||||
|
||||
class HoverAnimation : public QAbstractAnimation
|
||||
{
|
||||
public:
|
||||
HoverAnimation(AbstractItemView *view, const QModelIndex &index);
|
||||
|
||||
QModelIndex index() const { return m_index; }
|
||||
qreal progress() const;
|
||||
|
||||
void setEasingCurve(QEasingCurve::Type type);
|
||||
int duration() const { return 250; }
|
||||
|
||||
protected:
|
||||
void updateCurrentTime(int currentTime);
|
||||
|
||||
private:
|
||||
QModelIndex m_index;
|
||||
QEasingCurve m_curve;
|
||||
qreal m_progress;
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
class Animator : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Type { HoverEnter, HoverLeave };
|
||||
|
||||
Animator(AbstractItemView *view);
|
||||
~Animator();
|
||||
|
||||
HoverAnimation *findHoverAnimation(const QModelIndex &index) const;
|
||||
void animate(Type type, const QModelIndex &index);
|
||||
qreal hoverProgress(const QModelIndex &index) const;
|
||||
|
||||
private slots:
|
||||
void entered(const QModelIndex &index);
|
||||
void left(const QModelIndex &index);
|
||||
void animationDestroyed(QObject *object);
|
||||
void graphicsEffectsToggled(int category);
|
||||
|
||||
private:
|
||||
QList<HoverAnimation*> m_list;
|
||||
QPersistentModelIndex m_hoveredIndex;
|
||||
bool m_effectsOn;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
95
plasma/desktop/applets/folderview/asyncfiletester.cpp
Normal file
95
plasma/desktop/applets/folderview/asyncfiletester.cpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright © 2010 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "asyncfiletester.h"
|
||||
#include "proxymodel.h"
|
||||
|
||||
#include <KDesktopFile>
|
||||
#include <KFileItem>
|
||||
#include <KProtocolInfo>
|
||||
#include <KUrl>
|
||||
#include <KIO/StatJob>
|
||||
#include <KIO/Scheduler>
|
||||
|
||||
|
||||
AsyncFileTester::AsyncFileTester(const QModelIndex &index, QObject *object, const char *member)
|
||||
: index(index), object(object), member(member)
|
||||
{
|
||||
}
|
||||
|
||||
void AsyncFileTester::checkIfFolder(const QModelIndex &index, QObject *object, const char *method)
|
||||
{
|
||||
if (!index.isValid()) {
|
||||
callResultMethod(object, method, index, false);
|
||||
return;
|
||||
}
|
||||
|
||||
KFileItem item = static_cast<const ProxyModel*>(index.model())->itemForIndex(index);
|
||||
KUrl url = item.targetUrl();
|
||||
|
||||
if (item.isDir()) {
|
||||
callResultMethod(object, method, index, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.isDesktopFile()) {
|
||||
// Check if the desktop file is a link to a local folder
|
||||
KDesktopFile file(url.path());
|
||||
if (file.readType() == "Link") {
|
||||
url = file.readUrl();
|
||||
if (url.isLocalFile()) {
|
||||
KFileItem destItem(KFileItem::Unknown, KFileItem::Unknown, url);
|
||||
callResultMethod(object, method, index, destItem.isDir());
|
||||
return;
|
||||
}
|
||||
|
||||
if (KProtocolInfo::protocolClass(url.protocol()) == QString(":local")) {
|
||||
AsyncFileTester *tester = new AsyncFileTester(index, object, method);
|
||||
tester->delayedFolderCheck(url);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
callResultMethod(object, method, index, false);
|
||||
}
|
||||
|
||||
void AsyncFileTester::delayedFolderCheck(const KUrl &url)
|
||||
{
|
||||
KIO::StatJob *job = KIO::stat(url, KIO::HideProgressInfo);
|
||||
job->setSide(KIO::StatJob::SourceSide); // We will only read the file
|
||||
connect(job, SIGNAL(result(KJob*)), SLOT(statResult(KJob*)));
|
||||
}
|
||||
|
||||
void AsyncFileTester::callResultMethod(QObject *object, const char *member, const QModelIndex &index, bool result)
|
||||
{
|
||||
QMetaObject::invokeMethod(object, member, Q_ARG(QModelIndex, index),
|
||||
Q_ARG(bool, result));
|
||||
}
|
||||
|
||||
void AsyncFileTester::statResult(KJob *job)
|
||||
{
|
||||
if (object && !job->error()) {
|
||||
KIO::StatJob *statJob = static_cast<KIO::StatJob*>(job);
|
||||
callResultMethod(object.data(), member, index, statJob->statResult().isDir());
|
||||
}
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
#include "moc_asyncfiletester.cpp"
|
||||
|
62
plasma/desktop/applets/folderview/asyncfiletester.h
Normal file
62
plasma/desktop/applets/folderview/asyncfiletester.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright © 2010 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef ASYNCFILETESTER_H
|
||||
#define ASYNCFILETESTER_H
|
||||
|
||||
|
||||
#include <QObject>
|
||||
#include <QModelIndex>
|
||||
#include <QWeakPointer>
|
||||
|
||||
class KJob;
|
||||
class KUrl;
|
||||
|
||||
|
||||
class AsyncFileTester : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/* Checks if the file the index refers to is a folder and calls the given member in
|
||||
* the object with the result.
|
||||
*
|
||||
* The index must belong to a ProxyModel, and the member function must be a slot
|
||||
* with the following signature:
|
||||
*
|
||||
* checkIfFolderResult(const QModelIndex &index, bool result)
|
||||
*/
|
||||
static void checkIfFolder(const QModelIndex &index, QObject *object, const char *method);
|
||||
|
||||
private:
|
||||
AsyncFileTester(const QModelIndex &index, QObject *object, const char *member);
|
||||
void delayedFolderCheck(const KUrl &url);
|
||||
static void callResultMethod(QObject *object, const char *member, const QModelIndex &index, bool result);
|
||||
|
||||
private slots:
|
||||
void statResult(KJob *job);
|
||||
|
||||
private:
|
||||
QModelIndex index;
|
||||
QWeakPointer<QObject> object;
|
||||
const char *member;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
183
plasma/desktop/applets/folderview/dialog.cpp
Normal file
183
plasma/desktop/applets/folderview/dialog.cpp
Normal file
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* Copyright © 2008, 2009 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "dialog.h"
|
||||
#include "dialogshadows_p.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsWidget>
|
||||
#include <QGraphicsScene>
|
||||
|
||||
#include <KWindowSystem>
|
||||
|
||||
#include <Plasma/Applet>
|
||||
#include <Plasma/FrameSvg>
|
||||
#include <Plasma/WindowEffects>
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
# include <QX11Info>
|
||||
# include <X11/Xlib.h>
|
||||
#endif
|
||||
|
||||
|
||||
Dialog::Dialog(QWidget *parent)
|
||||
: QWidget(parent, Qt::Popup), m_widget(0)
|
||||
{
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
setAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu);
|
||||
|
||||
if (KWindowSystem::compositingActive()) {
|
||||
setAttribute(Qt::WA_NoSystemBackground, false);
|
||||
Plasma::WindowEffects::overrideShadow(winId(), true);
|
||||
} else {
|
||||
setAttribute(Qt::WA_NoSystemBackground);
|
||||
}
|
||||
#endif
|
||||
|
||||
KWindowSystem::setState(effectiveWinId(), NET::SkipTaskbar | NET::SkipPager);
|
||||
|
||||
QPalette pal = palette();
|
||||
pal.setColor(backgroundRole(), Qt::transparent);
|
||||
setPalette(pal);
|
||||
|
||||
m_background = new Plasma::FrameSvg(this);
|
||||
m_background->setImagePath("dialogs/background");
|
||||
|
||||
m_scene = new QGraphicsScene(this);
|
||||
m_view = new QGraphicsView(m_scene, this);
|
||||
m_view->setFrameShape(QFrame::NoFrame);
|
||||
m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_view->viewport()->setAutoFillBackground(false);
|
||||
}
|
||||
|
||||
Dialog::~Dialog()
|
||||
{
|
||||
}
|
||||
|
||||
void Dialog::setGraphicsWidget(QGraphicsWidget *widget)
|
||||
{
|
||||
m_widget = widget;
|
||||
m_scene->addItem(widget);
|
||||
}
|
||||
|
||||
void Dialog::show(Plasma::Applet *applet)
|
||||
{
|
||||
Plasma::FrameSvg::EnabledBorders borders = Plasma::FrameSvg::AllBorders;
|
||||
m_background->setEnabledBorders(borders);
|
||||
|
||||
int left = m_background->marginSize(Plasma::LeftMargin);
|
||||
int top = m_background->marginSize(Plasma::TopMargin);
|
||||
int right = m_background->marginSize(Plasma::RightMargin);
|
||||
int bottom = m_background->marginSize(Plasma::BottomMargin);
|
||||
|
||||
switch (applet->location())
|
||||
{
|
||||
case Plasma::BottomEdge:
|
||||
borders &= ~Plasma::FrameSvg::BottomBorder;
|
||||
bottom = qMin(bottom, 2);
|
||||
break;
|
||||
|
||||
case Plasma::TopEdge:
|
||||
borders &= ~Plasma::FrameSvg::TopBorder;
|
||||
top = qMin(top, 2);
|
||||
break;
|
||||
|
||||
case Plasma::LeftEdge:
|
||||
borders &= ~Plasma::FrameSvg::LeftBorder;
|
||||
left = qMin(left, 2);
|
||||
break;
|
||||
|
||||
case Plasma::RightEdge:
|
||||
borders &= ~Plasma::FrameSvg::RightBorder;
|
||||
right = qMin(right, 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const QSize margin(left + right, top + bottom);
|
||||
QSize size = m_widget->preferredSize().toSize() + margin;
|
||||
QPoint pos = applet->popupPosition(size);
|
||||
const QRect availableGeometry = QApplication::desktop()->availableGeometry(pos);
|
||||
|
||||
if (pos.y() < 0) {
|
||||
size.rheight() += pos.y();
|
||||
pos.ry() = 0;
|
||||
} else if (applet->location() == Plasma::TopEdge &&
|
||||
pos.y() + size.height() > availableGeometry.bottom()) {
|
||||
size.rheight() -= pos.y() + size.height() - availableGeometry.bottom();
|
||||
}
|
||||
|
||||
if (pos.x() < 0) {
|
||||
size.rwidth() += pos.x();
|
||||
pos.rx() = 0;
|
||||
} else if (applet->location() == Plasma::LeftEdge &&
|
||||
pos.x() + size.width() > availableGeometry.right()) {
|
||||
size.rwidth() -= pos.x() + size.width() - availableGeometry.right();
|
||||
}
|
||||
|
||||
m_background->setEnabledBorders(borders);
|
||||
setContentsMargins(left, top, right, bottom);
|
||||
|
||||
m_widget->resize(size - margin);
|
||||
resize(size);
|
||||
move(pos);
|
||||
|
||||
QWidget::show();
|
||||
DialogShadows::self()->addWindow(this, borders);
|
||||
}
|
||||
|
||||
void Dialog::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
m_background->resizeFrame(rect().size());
|
||||
m_view->setGeometry(contentsRect());
|
||||
|
||||
if (KWindowSystem::compositingActive()) {
|
||||
Plasma::WindowEffects::enableBlurBehind(winId(), true, m_background->mask());
|
||||
} else {
|
||||
setMask(m_background->mask());
|
||||
}
|
||||
}
|
||||
|
||||
void Dialog::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
QPainter p(this);
|
||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
p.fillRect(rect(), Qt::transparent);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
m_background->paintFrame(&p);
|
||||
}
|
||||
|
||||
void Dialog::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (!rect().contains(event->pos())) {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
57
plasma/desktop/applets/folderview/dialog.h
Normal file
57
plasma/desktop/applets/folderview/dialog.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright © 2008 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef DIALOG_H
|
||||
#define DIALOG_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Plasma {
|
||||
class Applet;
|
||||
class FrameSvg;
|
||||
}
|
||||
|
||||
class QGraphicsView;
|
||||
class QGraphicsWidget;
|
||||
class QGraphicsScene;
|
||||
|
||||
|
||||
class Dialog : public QWidget
|
||||
{
|
||||
public:
|
||||
Dialog(QWidget *parent = 0);
|
||||
~Dialog();
|
||||
|
||||
void setGraphicsWidget(QGraphicsWidget *widget);
|
||||
void show(Plasma::Applet *applet);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
void paintEvent(QPaintEvent *event);
|
||||
|
||||
private:
|
||||
Plasma::FrameSvg *m_background;
|
||||
QGraphicsScene *m_scene;
|
||||
QGraphicsView *m_view;
|
||||
QGraphicsWidget *m_widget;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
385
plasma/desktop/applets/folderview/dialogshadows.cpp
Normal file
385
plasma/desktop/applets/folderview/dialogshadows.cpp
Normal file
|
@ -0,0 +1,385 @@
|
|||
/*
|
||||
* Copyright 2011 by Aaron Seigo <aseigo@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License version 2,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "dialogshadows_p.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QPainter>
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
#include <QX11Info>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <fixx11h.h>
|
||||
#endif
|
||||
|
||||
#include <kdebug.h>
|
||||
#include <kglobal.h>
|
||||
|
||||
class DialogShadows::Private
|
||||
{
|
||||
public:
|
||||
Private(DialogShadows *shadows)
|
||||
: q(shadows),
|
||||
m_managePixmaps(false)
|
||||
{
|
||||
}
|
||||
|
||||
~Private()
|
||||
{
|
||||
clearPixmaps();
|
||||
}
|
||||
|
||||
void clearPixmaps();
|
||||
void setupPixmaps();
|
||||
void initPixmap(const QString &element);
|
||||
QPixmap initEmptyPixmap(const QSize &size);
|
||||
void updateShadow(const QWidget *window, Plasma::FrameSvg::EnabledBorders);
|
||||
void clearShadow(const QWidget *window);
|
||||
void updateShadows();
|
||||
void windowDestroyed(QObject *deletedObject);
|
||||
void setupData(Plasma::FrameSvg::EnabledBorders enabledBorders);
|
||||
|
||||
DialogShadows *q;
|
||||
QList<QPixmap> m_shadowPixmaps;
|
||||
|
||||
QPixmap m_emptyCornerPix;
|
||||
QPixmap m_emptyCornerLeftPix;
|
||||
QPixmap m_emptyCornerTopPix;
|
||||
QPixmap m_emptyCornerRightPix;
|
||||
QPixmap m_emptyCornerBottomPix;
|
||||
QPixmap m_emptyVerticalPix;
|
||||
QPixmap m_emptyHorizontalPix;
|
||||
|
||||
QHash<Plasma::FrameSvg::EnabledBorders, QVector<unsigned long> > data;
|
||||
QHash<const QWidget *, Plasma::FrameSvg::EnabledBorders> m_windows;
|
||||
bool m_managePixmaps;
|
||||
};
|
||||
|
||||
class DialogShadowsSingleton
|
||||
{
|
||||
public:
|
||||
DialogShadowsSingleton()
|
||||
{
|
||||
}
|
||||
|
||||
DialogShadows self;
|
||||
};
|
||||
|
||||
K_GLOBAL_STATIC(DialogShadowsSingleton, privateDialogShadowsSelf)
|
||||
|
||||
DialogShadows::DialogShadows(QObject *parent, const QString &prefix)
|
||||
: Plasma::Svg(parent),
|
||||
d(new Private(this))
|
||||
{
|
||||
setImagePath(prefix);
|
||||
connect(this, SIGNAL(repaintNeeded()), this, SLOT(updateShadows()));
|
||||
}
|
||||
|
||||
DialogShadows *DialogShadows::self()
|
||||
{
|
||||
return &privateDialogShadowsSelf->self;
|
||||
}
|
||||
|
||||
void DialogShadows::addWindow(const QWidget *window, Plasma::FrameSvg::EnabledBorders enabledBorders)
|
||||
{
|
||||
if (!window || !window->isWindow()) {
|
||||
return;
|
||||
}
|
||||
|
||||
d->m_windows[window] = enabledBorders;
|
||||
d->updateShadow(window, enabledBorders);
|
||||
connect(window, SIGNAL(destroyed(QObject*)),
|
||||
this, SLOT(windowDestroyed(QObject*)), Qt::UniqueConnection);
|
||||
}
|
||||
|
||||
void DialogShadows::removeWindow(const QWidget *window)
|
||||
{
|
||||
if (!d->m_windows.contains(window)) {
|
||||
return;
|
||||
}
|
||||
|
||||
d->m_windows.remove(window);
|
||||
disconnect(window, 0, this, 0);
|
||||
d->clearShadow(window);
|
||||
|
||||
if (d->m_windows.isEmpty()) {
|
||||
d->clearPixmaps();
|
||||
}
|
||||
}
|
||||
|
||||
void DialogShadows::Private::windowDestroyed(QObject *deletedObject)
|
||||
{
|
||||
m_windows.remove(static_cast<QWidget *>(deletedObject));
|
||||
|
||||
if (m_windows.isEmpty()) {
|
||||
clearPixmaps();
|
||||
}
|
||||
}
|
||||
|
||||
void DialogShadows::Private::updateShadows()
|
||||
{
|
||||
setupPixmaps();
|
||||
QHash<const QWidget *, Plasma::FrameSvg::EnabledBorders>::const_iterator i;
|
||||
for (i = m_windows.constBegin(); i != m_windows.constEnd(); ++i) {
|
||||
updateShadow(i.key(), i.value());
|
||||
}
|
||||
}
|
||||
|
||||
void DialogShadows::Private::initPixmap(const QString &element)
|
||||
{
|
||||
#ifdef Q_WS_X11
|
||||
QPixmap pix = q->pixmap(element);
|
||||
if (!pix.isNull() && pix.handle() == 0) {
|
||||
Pixmap xPix = XCreatePixmap(QX11Info::display(), QX11Info::appRootWindow(), pix.width(), pix.height(), 32);
|
||||
QPixmap tempPix = QPixmap::fromX11Pixmap(xPix, QPixmap::ExplicitlyShared);
|
||||
tempPix.fill(Qt::transparent);
|
||||
QPainter p(&tempPix);
|
||||
p.drawPixmap(QPoint(0, 0), pix);
|
||||
m_shadowPixmaps << tempPix;
|
||||
m_managePixmaps = true;
|
||||
} else {
|
||||
m_shadowPixmaps << pix;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
QPixmap DialogShadows::Private::initEmptyPixmap(const QSize &size)
|
||||
{
|
||||
#ifdef Q_WS_X11
|
||||
Pixmap emptyXPix = XCreatePixmap(QX11Info::display(), QX11Info::appRootWindow(), size.width(), size.height(), 32);
|
||||
QPixmap tempEmptyPix = QPixmap::fromX11Pixmap(emptyXPix, QPixmap::ExplicitlyShared);
|
||||
#else
|
||||
QPixmap tempEmptyPix(size.width(), size.height());
|
||||
#endif
|
||||
tempEmptyPix.fill(Qt::transparent);
|
||||
return tempEmptyPix;
|
||||
}
|
||||
|
||||
void DialogShadows::Private::setupPixmaps()
|
||||
{
|
||||
clearPixmaps();
|
||||
initPixmap("shadow-top");
|
||||
initPixmap("shadow-topright");
|
||||
initPixmap("shadow-right");
|
||||
initPixmap("shadow-bottomright");
|
||||
initPixmap("shadow-bottom");
|
||||
initPixmap("shadow-bottomleft");
|
||||
initPixmap("shadow-left");
|
||||
initPixmap("shadow-topleft");
|
||||
|
||||
m_emptyCornerPix = initEmptyPixmap(QSize(1,1));
|
||||
m_emptyCornerLeftPix = initEmptyPixmap(QSize(q->elementSize("shadow-topleft").width(), 1));
|
||||
m_emptyCornerTopPix = initEmptyPixmap(QSize(1, q->elementSize("shadow-topleft").height()));
|
||||
m_emptyCornerRightPix = initEmptyPixmap(QSize(q->elementSize("shadow-bottomright").width(), 1));
|
||||
m_emptyCornerBottomPix = initEmptyPixmap(QSize(1, q->elementSize("shadow-bottomright").height()));
|
||||
m_emptyVerticalPix = initEmptyPixmap(QSize(1, q->elementSize("shadow-left").height()));
|
||||
m_emptyHorizontalPix = initEmptyPixmap(QSize(q->elementSize("shadow-top").width(), 1));
|
||||
|
||||
}
|
||||
|
||||
|
||||
void DialogShadows::Private::setupData(Plasma::FrameSvg::EnabledBorders enabledBorders)
|
||||
{
|
||||
#ifdef Q_WS_X11
|
||||
//shadow-top
|
||||
if (enabledBorders & Plasma::FrameSvg::TopBorder) {
|
||||
data[enabledBorders] << m_shadowPixmaps[0].handle();
|
||||
} else {
|
||||
data[enabledBorders] << m_emptyHorizontalPix.handle();
|
||||
}
|
||||
|
||||
//shadow-topright
|
||||
if (enabledBorders & Plasma::FrameSvg::TopBorder &&
|
||||
enabledBorders & Plasma::FrameSvg::RightBorder) {
|
||||
data[enabledBorders] << m_shadowPixmaps[1].handle();
|
||||
} else if (enabledBorders & Plasma::FrameSvg::TopBorder) {
|
||||
data[enabledBorders] << m_emptyCornerTopPix.handle();
|
||||
} else if (enabledBorders & Plasma::FrameSvg::RightBorder) {
|
||||
data[enabledBorders] << m_emptyCornerRightPix.handle();
|
||||
} else {
|
||||
data[enabledBorders] << m_emptyCornerPix.handle();
|
||||
}
|
||||
|
||||
//shadow-right
|
||||
if (enabledBorders & Plasma::FrameSvg::RightBorder) {
|
||||
data[enabledBorders] << m_shadowPixmaps[2].handle();
|
||||
} else {
|
||||
data[enabledBorders] << m_emptyVerticalPix.handle();
|
||||
}
|
||||
|
||||
//shadow-bottomright
|
||||
if (enabledBorders & Plasma::FrameSvg::BottomBorder &&
|
||||
enabledBorders & Plasma::FrameSvg::RightBorder) {
|
||||
data[enabledBorders] << m_shadowPixmaps[3].handle();
|
||||
} else if (enabledBorders & Plasma::FrameSvg::BottomBorder) {
|
||||
data[enabledBorders] << m_emptyCornerBottomPix.handle();
|
||||
} else if (enabledBorders & Plasma::FrameSvg::RightBorder) {
|
||||
data[enabledBorders] << m_emptyCornerRightPix.handle();
|
||||
} else {
|
||||
data[enabledBorders] << m_emptyCornerPix.handle();
|
||||
}
|
||||
|
||||
//shadow-bottom
|
||||
if (enabledBorders & Plasma::FrameSvg::BottomBorder) {
|
||||
data[enabledBorders] << m_shadowPixmaps[4].handle();
|
||||
} else {
|
||||
data[enabledBorders] << m_emptyHorizontalPix.handle();
|
||||
}
|
||||
|
||||
//shadow-bottomleft
|
||||
if (enabledBorders & Plasma::FrameSvg::BottomBorder &&
|
||||
enabledBorders & Plasma::FrameSvg::LeftBorder) {
|
||||
data[enabledBorders] << m_shadowPixmaps[5].handle();
|
||||
} else if (enabledBorders & Plasma::FrameSvg::BottomBorder) {
|
||||
data[enabledBorders] << m_emptyCornerBottomPix.handle();
|
||||
} else if (enabledBorders & Plasma::FrameSvg::LeftBorder) {
|
||||
data[enabledBorders] << m_emptyCornerLeftPix.handle();
|
||||
} else {
|
||||
data[enabledBorders] << m_emptyCornerPix.handle();
|
||||
}
|
||||
|
||||
//shadow-left
|
||||
if (enabledBorders & Plasma::FrameSvg::LeftBorder) {
|
||||
data[enabledBorders] << m_shadowPixmaps[6].handle();
|
||||
} else {
|
||||
data[enabledBorders] << m_emptyVerticalPix.handle();
|
||||
}
|
||||
|
||||
//shadow-topleft
|
||||
if (enabledBorders & Plasma::FrameSvg::TopBorder &&
|
||||
enabledBorders & Plasma::FrameSvg::LeftBorder) {
|
||||
data[enabledBorders] << m_shadowPixmaps[7].handle();
|
||||
} else if (enabledBorders & Plasma::FrameSvg::TopBorder) {
|
||||
data[enabledBorders] << m_emptyCornerTopPix.handle();
|
||||
} else if (enabledBorders & Plasma::FrameSvg::LeftBorder) {
|
||||
data[enabledBorders] << m_emptyCornerLeftPix.handle();
|
||||
} else {
|
||||
data[enabledBorders] << m_emptyCornerPix.handle();
|
||||
}
|
||||
#endif
|
||||
|
||||
int left, top, right, bottom = 0;
|
||||
|
||||
QSize marginHint;
|
||||
if (enabledBorders & Plasma::FrameSvg::TopBorder) {
|
||||
marginHint = q->elementSize("shadow-hint-top-margin");
|
||||
if (marginHint.isValid()) {
|
||||
top = marginHint.height();
|
||||
} else {
|
||||
top = m_shadowPixmaps[0].height(); // top
|
||||
}
|
||||
} else {
|
||||
top = 1;
|
||||
}
|
||||
|
||||
if (enabledBorders & Plasma::FrameSvg::RightBorder) {
|
||||
marginHint = q->elementSize("shadow-hint-right-margin");
|
||||
if (marginHint.isValid()) {
|
||||
right = marginHint.width();
|
||||
} else {
|
||||
right = m_shadowPixmaps[2].width(); // right
|
||||
}
|
||||
} else {
|
||||
right = 1;
|
||||
}
|
||||
|
||||
if (enabledBorders & Plasma::FrameSvg::BottomBorder) {
|
||||
marginHint = q->elementSize("shadow-hint-bottom-margin");
|
||||
if (marginHint.isValid()) {
|
||||
bottom = marginHint.height();
|
||||
} else {
|
||||
bottom = m_shadowPixmaps[4].height(); // bottom
|
||||
}
|
||||
} else {
|
||||
bottom = 1;
|
||||
}
|
||||
|
||||
if (enabledBorders & Plasma::FrameSvg::LeftBorder) {
|
||||
marginHint = q->elementSize("shadow-hint-left-margin");
|
||||
if (marginHint.isValid()) {
|
||||
left = marginHint.width();
|
||||
} else {
|
||||
left = m_shadowPixmaps[6].width(); // left
|
||||
}
|
||||
} else {
|
||||
left = 1;
|
||||
}
|
||||
|
||||
data[enabledBorders] << top << right << bottom << left;
|
||||
}
|
||||
|
||||
void DialogShadows::Private::clearPixmaps()
|
||||
{
|
||||
#ifdef Q_WS_X11
|
||||
if (m_managePixmaps) {
|
||||
foreach (const QPixmap &pixmap, m_shadowPixmaps) {
|
||||
XFreePixmap(QX11Info::display(), pixmap.handle());
|
||||
}
|
||||
|
||||
XFreePixmap(QX11Info::display(), m_emptyCornerPix.handle());
|
||||
XFreePixmap(QX11Info::display(), m_emptyCornerBottomPix.handle());
|
||||
XFreePixmap(QX11Info::display(), m_emptyCornerLeftPix.handle());
|
||||
XFreePixmap(QX11Info::display(), m_emptyCornerRightPix.handle());
|
||||
XFreePixmap(QX11Info::display(), m_emptyCornerTopPix.handle());
|
||||
XFreePixmap(QX11Info::display(), m_emptyVerticalPix.handle());
|
||||
XFreePixmap(QX11Info::display(), m_emptyHorizontalPix.handle());
|
||||
|
||||
m_managePixmaps = false;
|
||||
}
|
||||
#endif
|
||||
m_shadowPixmaps.clear();
|
||||
data.clear();
|
||||
}
|
||||
|
||||
void DialogShadows::Private::updateShadow(const QWidget *window, Plasma::FrameSvg::EnabledBorders enabledBorders)
|
||||
{
|
||||
#ifdef Q_WS_X11
|
||||
if (m_shadowPixmaps.isEmpty()) {
|
||||
setupPixmaps();
|
||||
}
|
||||
|
||||
if (!data.contains(enabledBorders)) {
|
||||
setupData(enabledBorders);
|
||||
}
|
||||
|
||||
Display *dpy = QX11Info::display();
|
||||
Atom atom = XInternAtom(dpy, "_KDE_NET_WM_SHADOW", False);
|
||||
|
||||
//kDebug() << "going to set the shadow of" << winId() << "to" << data;
|
||||
XChangeProperty(dpy, window->winId(), atom, XA_CARDINAL, 32, PropModeReplace,
|
||||
reinterpret_cast<const unsigned char *>(data[enabledBorders].constData()), data[enabledBorders].size());
|
||||
#endif
|
||||
}
|
||||
|
||||
void DialogShadows::Private::clearShadow(const QWidget *window)
|
||||
{
|
||||
#ifdef Q_WS_X11
|
||||
Display *dpy = QX11Info::display();
|
||||
Atom atom = XInternAtom(dpy, "_KDE_NET_WM_SHADOW", False);
|
||||
XDeleteProperty(dpy, window->winId(), atom);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool DialogShadows::enabled() const
|
||||
{
|
||||
return hasElement("shadow-left");
|
||||
}
|
||||
|
||||
#include "moc_dialogshadows_p.cpp"
|
||||
|
51
plasma/desktop/applets/folderview/dialogshadows_p.h
Normal file
51
plasma/desktop/applets/folderview/dialogshadows_p.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2011 by Aaron Seigo <aseigo@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License version 2,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef PLASMA_DIALOGSHADOWS_H
|
||||
#define PLASMA_DIALOGSHADOWS_H
|
||||
|
||||
#include <QSet>
|
||||
|
||||
#include "plasma/framesvg.h"
|
||||
#include "plasma/svg.h"
|
||||
|
||||
|
||||
class DialogShadows : public Plasma::Svg
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DialogShadows(QObject *parent = 0, const QString &prefix = "dialogs/background");
|
||||
|
||||
static DialogShadows *self();
|
||||
|
||||
void addWindow(const QWidget *window, Plasma::FrameSvg::EnabledBorders enabledBorders = Plasma::FrameSvg::AllBorders);
|
||||
void removeWindow(const QWidget *window);
|
||||
|
||||
bool enabled() const;
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private * const d;
|
||||
|
||||
Q_PRIVATE_SLOT(d, void updateShadows())
|
||||
Q_PRIVATE_SLOT(d, void windowDestroyed(QObject *deletedObject))
|
||||
};
|
||||
|
||||
#endif
|
||||
|
42
plasma/desktop/applets/folderview/dirlister.cpp
Normal file
42
plasma/desktop/applets/folderview/dirlister.cpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright © 2008 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "dirlister.h"
|
||||
|
||||
#include <KIO/Job>
|
||||
|
||||
DirLister::DirLister(QObject *parent)
|
||||
: KDirLister(parent)
|
||||
{
|
||||
}
|
||||
|
||||
DirLister:: ~DirLister()
|
||||
{
|
||||
}
|
||||
|
||||
void DirLister::handleError(KIO::Job *job)
|
||||
{
|
||||
if (!autoErrorHandlingEnabled()) {
|
||||
emit showErrorMessage(job->errorString());
|
||||
return;
|
||||
}
|
||||
|
||||
KDirLister::handleError(job);
|
||||
}
|
||||
|
42
plasma/desktop/applets/folderview/dirlister.h
Normal file
42
plasma/desktop/applets/folderview/dirlister.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright © 2008 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef DIRLISTER_H
|
||||
#define DIRLISTER_H
|
||||
|
||||
#include <KDirLister>
|
||||
|
||||
// Reimplemented to provide custom error handling
|
||||
class DirLister : public KDirLister
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DirLister(QObject *parent = 0);
|
||||
~DirLister();
|
||||
|
||||
signals:
|
||||
void showErrorMessage(const QString &string);
|
||||
|
||||
protected:
|
||||
void handleError(KIO::Job *job);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
2289
plasma/desktop/applets/folderview/folderview.cpp
Normal file
2289
plasma/desktop/applets/folderview/folderview.cpp
Normal file
File diff suppressed because it is too large
Load diff
285
plasma/desktop/applets/folderview/folderview.h
Normal file
285
plasma/desktop/applets/folderview/folderview.h
Normal file
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
* Copyright © 2008, 2009 Fredrik Höglund <fredrik@kde.org>
|
||||
* Copyright © 2008 Rafael Fernández López <ereslibre@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef FOLDERVIEW_H
|
||||
#define FOLDERVIEW_H
|
||||
|
||||
#include <QCache>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QStyleOption>
|
||||
#include <QPointer>
|
||||
#include <QBasicTimer>
|
||||
|
||||
#include <KActionCollection>
|
||||
#include <KMimeType>
|
||||
|
||||
#include <Solid/Networking>
|
||||
|
||||
#include <plasma/containment.h>
|
||||
|
||||
#include "iconview.h"
|
||||
#include "dirlister.h"
|
||||
#include "proxymodel.h"
|
||||
|
||||
#include "ui_folderviewFilterConfig.h"
|
||||
#include "ui_folderviewDisplayConfig.h"
|
||||
#include "ui_folderviewLocationConfig.h"
|
||||
#include "ui_folderviewPreviewConfig.h"
|
||||
|
||||
class KDirModel;
|
||||
class KFileItemDelegate;
|
||||
class KFilePlacesModel;
|
||||
class KFilePreviewGenerator;
|
||||
class KNewFileMenu;
|
||||
class KFileItemActions;
|
||||
class KJob;
|
||||
class QItemSelectionModel;
|
||||
class FolderView;
|
||||
class ProxyModel;
|
||||
class IconView;
|
||||
class IconWidget;
|
||||
class ListView;
|
||||
class Label;
|
||||
class Dialog;
|
||||
|
||||
|
||||
/**
|
||||
* Helper class that downloads a wallpaper image asynchronously to a suitable
|
||||
* temporary directory in the user's home folder, and applies it to the given
|
||||
* folderview containment when the download finishes.
|
||||
*
|
||||
* The class deletes itself automatically when the operation is completed.
|
||||
*/
|
||||
class RemoteWallpaperSetter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RemoteWallpaperSetter(const KUrl &url, FolderView *containment);
|
||||
|
||||
private slots:
|
||||
void result(KJob *job);
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
class FolderView : public Plasma::Containment
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum LabelType { None = 0, PlaceName, FullPath, Custom };
|
||||
enum { Unsorted = -1 };
|
||||
|
||||
public:
|
||||
FolderView(QObject *parent, const QVariantList &args);
|
||||
~FolderView();
|
||||
|
||||
void init();
|
||||
void saveState(KConfigGroup &config) const;
|
||||
void paintInterface(QPainter *painter, const QStyleOptionGraphicsItem *option, const QRect &contentsRect);
|
||||
void setPath(const QString&);
|
||||
void setWallpaper(const KUrl &url);
|
||||
|
||||
void configChanged();
|
||||
|
||||
public slots:
|
||||
// Move to Plasma::Containment in 4.9
|
||||
void addUrls(const KUrl::List& urls);
|
||||
|
||||
protected:
|
||||
void createConfigurationInterface(KConfigDialog *parent);
|
||||
QList<QAction*> contextualActions();
|
||||
void constraintsEvent(Plasma::Constraints);
|
||||
void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
|
||||
void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
|
||||
void dropEvent(QGraphicsSceneDragDropEvent *event);
|
||||
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const;
|
||||
|
||||
protected slots:
|
||||
// These slots are for KonqPopupMenu
|
||||
void copy();
|
||||
void cut();
|
||||
void paste();
|
||||
void pasteTo();
|
||||
void refreshIcons();
|
||||
void moveToTrash(Qt::MouseButtons, Qt::KeyboardModifiers);
|
||||
void deleteSelectedIcons();
|
||||
void renameSelectedIcon();
|
||||
|
||||
void emptyTrashBin();
|
||||
void undoTextChanged(const QString &text);
|
||||
void toggleIconsLocked(bool locked);
|
||||
void toggleAlignToGrid(bool align);
|
||||
void toggleClickToViewFolders(bool enable);
|
||||
void toggleSortDescending(bool enable);
|
||||
void toggleDirectoriesFirst(bool enable);
|
||||
void layoutChanged(QAction *action);
|
||||
void alignmentChanged(QAction *action);
|
||||
void sortingChanged(QAction *action);
|
||||
void aboutToShowCreateNew();
|
||||
void updateIconWidget();
|
||||
void iconWidgetClicked();
|
||||
|
||||
void activated(const QModelIndex &index);
|
||||
void indexesMoved(const QModelIndexList &indexes);
|
||||
void contextMenuRequest(QWidget *widget, const QPoint &screenPos);
|
||||
|
||||
void configAccepted();
|
||||
void filterChanged(int index);
|
||||
void selectAllMimetypes();
|
||||
void deselectAllMimeTypes();
|
||||
void fontSettingsChanged();
|
||||
void iconSettingsChanged(int group);
|
||||
void clickSettingsChanged(int category);
|
||||
void plasmaThemeChanged();
|
||||
//void clipboardDataChanged();
|
||||
void updateScreenRegion();
|
||||
void showPreviewConfigDialog();
|
||||
|
||||
private slots:
|
||||
void networkAvailable();
|
||||
void setTitleEditEnabled(int);
|
||||
|
||||
private:
|
||||
void updatePasteAction();
|
||||
void addActions(AbstractItemView *view);
|
||||
void addActionGroupToCombo(QActionGroup *group, QComboBox *combo);
|
||||
template <typename T>
|
||||
void setCurrentItem(QComboBox *combo, T current);
|
||||
QColor textColor() const;
|
||||
void setupIconView();
|
||||
void setUrl(const KUrl &url);
|
||||
QSize iconSize() const;
|
||||
void createActions();
|
||||
void updateFlowActionsState();
|
||||
void updateSortActionsState();
|
||||
void updateListViewState();
|
||||
void updateIconViewState();
|
||||
void saveIconPositions() const;
|
||||
KUrl::List selectedUrls(bool forTrash) const;
|
||||
void showContextMenu(QWidget *widget, const QPoint &pos, const QModelIndexList &indexes);
|
||||
void timerEvent(QTimerEvent *event);
|
||||
void recreateLayout();
|
||||
void setAppletTitle();
|
||||
void toggleAllMimetypes(Qt::CheckState);
|
||||
|
||||
private:
|
||||
KFileItemDelegate *m_delegate;
|
||||
QPointer<KFilePreviewGenerator> m_previewGenerator;
|
||||
QItemSelectionModel *m_selectionModel;
|
||||
ProxyModel *m_model;
|
||||
KDirModel *m_dirModel;
|
||||
KFilePlacesModel *m_placesModel;
|
||||
KFileItemActions *m_itemActions;
|
||||
KAction *m_openWithAction;
|
||||
IconView *m_iconView;
|
||||
ListView *m_listView;
|
||||
Label *m_label;
|
||||
IconWidget *m_iconWidget;
|
||||
Dialog *m_dialog;
|
||||
QIcon m_icon;
|
||||
KUrl m_url;
|
||||
QColor m_textColor;
|
||||
QString m_titleText;
|
||||
ProxyModel::FilterMode m_filterType;
|
||||
QString m_filterFiles;
|
||||
QStringList m_filterFilesMimeList;
|
||||
QPointer<KNewFileMenu> m_newMenu;
|
||||
KActionCollection m_actionCollection;
|
||||
QActionGroup *m_layoutGroup;
|
||||
QActionGroup *m_alignmentGroup;
|
||||
QActionGroup *m_sortingGroup;
|
||||
int m_sortColumn;
|
||||
Qt::SortOrder m_sortOrder;
|
||||
Ui::folderviewFilterConfig uiFilter;
|
||||
Ui::folderviewDisplayConfig uiDisplay;
|
||||
Ui::folderviewLocationConfig uiLocation;
|
||||
Ui::folderviewPreviewConfig uiPreviewConfig;
|
||||
bool m_sortDirsFirst;
|
||||
bool m_showPreviews;
|
||||
bool m_drawShadows;
|
||||
bool m_iconsLocked;
|
||||
bool m_alignToGrid;
|
||||
bool m_clickToView;
|
||||
bool m_showSelectionMarker;
|
||||
LabelType m_labelType;
|
||||
QString m_customLabel;
|
||||
QStringList m_previewPlugins;
|
||||
int m_customIconSize;
|
||||
int m_numTextLines;
|
||||
IconView::Layout m_layout;
|
||||
IconView::Alignment m_alignment;
|
||||
QBasicTimer m_delayedSaveTimer;
|
||||
DirLister *m_dirLister;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
class MimeModel : public QStringListModel
|
||||
{
|
||||
public:
|
||||
MimeModel(QObject *parent = 0);
|
||||
|
||||
virtual QVariant data(const QModelIndex &index, int role) const;
|
||||
virtual Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
virtual QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
|
||||
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
|
||||
|
||||
private:
|
||||
KMimeType::List m_mimetypes;
|
||||
QMap<KMimeType*, Qt::CheckState> m_state;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
class ProxyMimeModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ProxyMimeModel(QObject *parent = 0);
|
||||
|
||||
virtual void setSourceModel(QAbstractItemModel *sourceModel);
|
||||
|
||||
public slots:
|
||||
void setFilter(const QString &filter);
|
||||
|
||||
protected:
|
||||
virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
|
||||
virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
|
||||
|
||||
private:
|
||||
QString m_filter;
|
||||
};
|
||||
|
||||
#endif
|
490
plasma/desktop/applets/folderview/folderviewDisplayConfig.ui
Normal file
490
plasma/desktop/applets/folderview/folderviewDisplayConfig.ui
Normal file
|
@ -0,0 +1,490 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>folderviewDisplayConfig</class>
|
||||
<widget class="QWidget" name="folderviewDisplayConfig">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>570</width>
|
||||
<height>703</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="iconsTitle">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Sorting</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="sortLabel">
|
||||
<property name="text">
|
||||
<string>Sort By:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>sortCombo</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="KComboBox" name="sortCombo">
|
||||
<property name="whatsThis">
|
||||
<string>Use this control to choose the criteria by which the icons will be sorted in the view.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>38</width>
|
||||
<height>18</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="sortDescendingLabel">
|
||||
<property name="text">
|
||||
<string>Descending:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="foldersFirstLabel">
|
||||
<property name="text">
|
||||
<string>Folders first:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QCheckBox" name="foldersFirst">
|
||||
<property name="whatsThis">
|
||||
<string>Check this option if you want folders to have sorting precedence. When this option is turned off, folders will be treated like regular files with respect to sorting.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Arrangement</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="layoutLabel">
|
||||
<property name="text">
|
||||
<string>Arrange In:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QComboBox" name="layoutCombo">
|
||||
<property name="whatsThis">
|
||||
<string>Use this control to choose whether the icons will be arranged horizontally (in rows) or vertically (in columns).</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLabel" name="alignmentLabel">
|
||||
<property name="text">
|
||||
<string>Align:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<widget class="QComboBox" name="alignmentCombo">
|
||||
<property name="whatsThis">
|
||||
<string>Use this control to choose whether the icons will be aligned to the left or to the right side of the screen.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLabel" name="lockInPlaceLabel">
|
||||
<property name="text">
|
||||
<string>Lock in place:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<widget class="QCheckBox" name="lockInPlace">
|
||||
<property name="whatsThis">
|
||||
<string>Check this option if you do not want the icons to be moveable in the view.
|
||||
|
||||
This option is useful if you want to avoid accidentally moving the icons while interacting with them.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLabel" name="alignToGridLabel">
|
||||
<property name="text">
|
||||
<string>Align to grid:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QCheckBox" name="alignToGrid">
|
||||
<property name="whatsThis">
|
||||
<string>Check this option if you want the icons to be arranged in a grid.
|
||||
|
||||
When this option is checked, icons will automatically snap to the nearest grid cell when you move them around in the view.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QLabel" name="sizeSliderLabel">
|
||||
<property name="text">
|
||||
<string>Size:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>sizeSlider</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="2" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Small</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="sizeSlider">
|
||||
<property name="whatsThis">
|
||||
<string>Use this slider to increase or decrease the size of the icons in the view.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Large</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Behavior</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QLabel" name="previewsAdvancedLabel">
|
||||
<property name="text">
|
||||
<string>Previews:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="2" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="showPreviews">
|
||||
<property name="whatsThis">
|
||||
<string>Check this option if you want to see previews of the file contents in the icons.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="previewsAdvanced">
|
||||
<property name="whatsThis">
|
||||
<string>Click this button to choose for which types of files previews will be shown.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>More Preview Options...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="12" column="1">
|
||||
<widget class="QLabel" name="clickToViewLabel">
|
||||
<property name="text">
|
||||
<string>Click to view folder:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="2">
|
||||
<widget class="QCheckBox" name="clickToView">
|
||||
<property name="whatsThis">
|
||||
<string>Check this option if you want folder previews to appear only when clicked. When this option is turned off, folder previews will appear automatically when the mouse hovers over a folder.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0">
|
||||
<widget class="QLabel" name="iconTextTitle">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Icon Text</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="1">
|
||||
<widget class="QLabel" name="numLinesEditLabel">
|
||||
<property name="text">
|
||||
<string>Lines:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>numLinesEdit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="2">
|
||||
<widget class="KIntSpinBox" name="numLinesEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>Use this control to choose how many lines of text will be shown below the icons.</string>
|
||||
</property>
|
||||
<property name="specialValueText">
|
||||
<string>1 line</string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> lines</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="1">
|
||||
<widget class="QLabel" name="colorButtonLabel">
|
||||
<property name="text">
|
||||
<string>Color:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>colorButton</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="2">
|
||||
<widget class="KColorButton" name="colorButton">
|
||||
<property name="whatsThis">
|
||||
<string>Click this button to choose the color which is used for the text labels in the view.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="1">
|
||||
<widget class="QLabel" name="drawShadowsLabel">
|
||||
<property name="text">
|
||||
<string>Shadows:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>numLinesEdit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="2">
|
||||
<widget class="QCheckBox" name="drawShadows">
|
||||
<property name="whatsThis">
|
||||
<string><html><body><p>Check this option if you want the text labels to cast a shadow on the background.</p>
|
||||
<p></p>
|
||||
<p>Shadows help make the text easier to read by making it stand out more from the background.</p>
|
||||
<p></p>
|
||||
<p><i>Note that with dark text colors, this option will cause the text to glow with a bright halo, instead of casting a shadow.</i></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="4">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>44</width>
|
||||
<height>216</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QCheckBox" name="sortDescending">
|
||||
<property name="whatsThis">
|
||||
<string>Check this option if you want the icons to be sorted in a descending order.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>KColorButton</class>
|
||||
<extends>QPushButton</extends>
|
||||
<header>kcolorbutton.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>KComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>kcombobox.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>KIntSpinBox</class>
|
||||
<extends>QSpinBox</extends>
|
||||
<header>knuminput.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>sortCombo</tabstop>
|
||||
<tabstop>sortDescending</tabstop>
|
||||
<tabstop>foldersFirst</tabstop>
|
||||
<tabstop>layoutCombo</tabstop>
|
||||
<tabstop>alignmentCombo</tabstop>
|
||||
<tabstop>lockInPlace</tabstop>
|
||||
<tabstop>alignToGrid</tabstop>
|
||||
<tabstop>sizeSlider</tabstop>
|
||||
<tabstop>showPreviews</tabstop>
|
||||
<tabstop>previewsAdvanced</tabstop>
|
||||
<tabstop>clickToView</tabstop>
|
||||
<tabstop>numLinesEdit</tabstop>
|
||||
<tabstop>colorButton</tabstop>
|
||||
<tabstop>drawShadows</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
195
plasma/desktop/applets/folderview/folderviewFilterConfig.ui
Normal file
195
plasma/desktop/applets/folderview/folderviewFilterConfig.ui
Normal file
|
@ -0,0 +1,195 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>folderviewFilterConfig</class>
|
||||
<widget class="QWidget" name="folderviewFilterConfig">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>509</width>
|
||||
<height>375</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>500</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QComboBox" name="filterCombo">
|
||||
<property name="toolTip">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">If you have selected "Show Files Matching" or "Hide Files Matching", only the files matching BOTH the conditions will be shown or hidden respectively.</p>
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">For example, if you have "*" as your pattern, but have nothing selected in the MIME types, no files will be shown.</p></body></html></string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="fileFilters">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>10</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<layout class="QGridLayout" name="mimeTypeLayout">
|
||||
<item row="5" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0">
|
||||
<item>
|
||||
<widget class="QListView" name="filterFilesList">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
<property name="flow">
|
||||
<enum>QListView::TopToBottom</enum>
|
||||
</property>
|
||||
<property name="uniformItemSizes">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="selectAll">
|
||||
<property name="text">
|
||||
<string>Select All</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="deselectAll">
|
||||
<property name="text">
|
||||
<string>Deselect All</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="toolTip">
|
||||
<string>Note that if you have selected "Show Files Matching" or "Hide Files Matching",
|
||||
only the files matching BOTH the conditions will be shown or hidden respectively.
|
||||
For example, if you have "*" as your pattern, but have nothing selected in the MIME types, no files will be shown.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><a href="null">Cannot See Any Files?</a></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="KLineEdit" name="searchMimetype">
|
||||
<property name="clickMessage">
|
||||
<string>Search file type</string>
|
||||
</property>
|
||||
<property name="showClearButton" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="fileTypesLabel">
|
||||
<property name="text">
|
||||
<string>File types:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="fileNameLabel">
|
||||
<property name="text">
|
||||
<string>File name pattern:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="KLineEdit" name="filterFilesPattern">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Space-separated list of extensions, e.g. *.txt *.od*</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>Space-separated list of extensions, e.g. *.txt *.od* to display only office- and text-files</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
|
||||
</property>
|
||||
<property name="urlDropsEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="clickMessage">
|
||||
<string>Pattern filter</string>
|
||||
</property>
|
||||
<property name="showClearButton" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>KLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>klineedit.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<includes>
|
||||
<include location="global">KUrlRequester</include>
|
||||
</includes>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
226
plasma/desktop/applets/folderview/folderviewLocationConfig.ui
Normal file
226
plasma/desktop/applets/folderview/folderviewLocationConfig.ui
Normal file
|
@ -0,0 +1,226 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>folderviewLocationConfig</class>
|
||||
<widget class="QWidget" name="folderviewLocationConfig">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>577</width>
|
||||
<height>408</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="locationLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>13</width>
|
||||
<height>138</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="showDesktopFolder">
|
||||
<property name="text">
|
||||
<string>Show the Desktop folder</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">locatgionButtonGroup</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="showPlace">
|
||||
<property name="text">
|
||||
<string>Show a place:</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">locatgionButtonGroup</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>25</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="KComboBox" name="placesCombo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="showCustomFolder">
|
||||
<property name="text">
|
||||
<string>Specify a folder:</string>
|
||||
</property>
|
||||
<property name="autoExclusive">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">locatgionButtonGroup</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>25</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="KUrlRequester" name="lineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="clickMessage">
|
||||
<string>Type a path or a URL here</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="titleLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><span style=" font-weight:400;">Title:</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>titleCombo</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="KComboBox" name="titleCombo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="autoCompletion">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="KLineEdit" name="titleEdit">
|
||||
<property name="clickMessage">
|
||||
<string>Enter custom title here</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>90</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>KComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>kcombobox.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>KLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>klineedit.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>KUrlRequester</class>
|
||||
<extends>QFrame</extends>
|
||||
<header>kurlrequester.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>showDesktopFolder</tabstop>
|
||||
<tabstop>showPlace</tabstop>
|
||||
<tabstop>placesCombo</tabstop>
|
||||
<tabstop>showCustomFolder</tabstop>
|
||||
<tabstop>lineEdit</tabstop>
|
||||
<tabstop>titleCombo</tabstop>
|
||||
<tabstop>titleEdit</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<buttongroups>
|
||||
<buttongroup name="locatgionButtonGroup"/>
|
||||
</buttongroups>
|
||||
</ui>
|
31
plasma/desktop/applets/folderview/folderviewPreviewConfig.ui
Normal file
31
plasma/desktop/applets/folderview/folderviewPreviewConfig.ui
Normal file
|
@ -0,0 +1,31 @@
|
|||
<ui version="4.0" >
|
||||
<class>folderviewPreviewConfig</class>
|
||||
<widget class="QWidget" name="folderviewPreviewConfig" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" >
|
||||
<item>
|
||||
<widget class="QLabel" name="label" >
|
||||
<property name="text" >
|
||||
<string>Check the file types you want icon previews for:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListView" name="listView" >
|
||||
<property name="alternatingRowColors" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
58
plasma/desktop/applets/folderview/folderviewadapter.cpp
Normal file
58
plasma/desktop/applets/folderview/folderviewadapter.cpp
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright © 2008 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "folderviewadapter.h"
|
||||
|
||||
FolderViewAdapter::FolderViewAdapter(AbstractItemView *view)
|
||||
: KAbstractViewAdapter(view), m_view(view)
|
||||
{
|
||||
}
|
||||
|
||||
QAbstractItemModel *FolderViewAdapter::model() const
|
||||
{
|
||||
return m_view->model();
|
||||
}
|
||||
|
||||
QSize FolderViewAdapter::iconSize() const
|
||||
{
|
||||
return m_view->iconSize();
|
||||
}
|
||||
|
||||
QPalette FolderViewAdapter::palette() const
|
||||
{
|
||||
return m_view->palette();
|
||||
}
|
||||
|
||||
QRect FolderViewAdapter::visibleArea() const
|
||||
{
|
||||
return m_view->visibleArea();
|
||||
}
|
||||
|
||||
QRect FolderViewAdapter::visualRect(const QModelIndex &index) const
|
||||
{
|
||||
return m_view->visualRect(index);
|
||||
}
|
||||
|
||||
void FolderViewAdapter::connect(Signal signal, QObject *receiver, const char *slot)
|
||||
{
|
||||
if (signal == ScrollBarValueChanged) {
|
||||
QObject::connect(m_view->verticalScrollBar(), SIGNAL(valueChanged(int)), receiver, slot);
|
||||
}
|
||||
}
|
||||
|
43
plasma/desktop/applets/folderview/folderviewadapter.h
Normal file
43
plasma/desktop/applets/folderview/folderviewadapter.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright © 2008 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef FOLDERVIEWADAPTER_H
|
||||
#define FOLDERVIEWADAPTER_H
|
||||
|
||||
#include "kabstractviewadapter_p.h"
|
||||
#include "abstractitemview.h"
|
||||
|
||||
|
||||
class FolderViewAdapter : public KAbstractViewAdapter
|
||||
{
|
||||
public:
|
||||
FolderViewAdapter(AbstractItemView *view);
|
||||
QAbstractItemModel *model() const;
|
||||
QSize iconSize() const;
|
||||
QPalette palette() const;
|
||||
QRect visibleArea() const;
|
||||
QRect visualRect(const QModelIndex &index) const;
|
||||
void connect(Signal signal, QObject *receiver, const char *slot);
|
||||
|
||||
private:
|
||||
AbstractItemView *m_view;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
2897
plasma/desktop/applets/folderview/iconview.cpp
Normal file
2897
plasma/desktop/applets/folderview/iconview.cpp
Normal file
File diff suppressed because it is too large
Load diff
295
plasma/desktop/applets/folderview/iconview.h
Normal file
295
plasma/desktop/applets/folderview/iconview.h
Normal file
|
@ -0,0 +1,295 @@
|
|||
/*
|
||||
* Copyright © 2008, 2009, 2010 Fredrik Höglund <fredrik@kde.org>
|
||||
* Copyright © 2008 Rafael Fernández López <ereslibre@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef ICONVIEW_H
|
||||
#define ICONVIEW_H
|
||||
|
||||
#include "abstractitemview.h"
|
||||
#include "popupview.h"
|
||||
#include "itemeditor.h"
|
||||
#include "actionoverlay.h"
|
||||
|
||||
#include <QAbstractItemDelegate>
|
||||
#include <QPointer>
|
||||
#include <QCache>
|
||||
#include <QTime>
|
||||
#include <QBasicTimer>
|
||||
|
||||
|
||||
class KUrl;
|
||||
class KFileItemList;
|
||||
class KonqOperations;
|
||||
class QActionGroup;
|
||||
class QStyleOptionViewItemV4;
|
||||
class ToolTipWidget;
|
||||
class Animator;
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
class ScrollBar;
|
||||
}
|
||||
|
||||
struct ViewItem
|
||||
{
|
||||
ViewItem() : rect(QRect()), layouted(false), needSizeAdjust(true) {}
|
||||
QRect rect;
|
||||
bool layouted:1;
|
||||
bool needSizeAdjust:1;
|
||||
};
|
||||
|
||||
class IconView : public AbstractItemView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Flow { HorLeftToRight, VerLeftToRight, HorRightToLeft, VerRightToLeft };
|
||||
enum Layout { Rows, Columns };
|
||||
enum Alignment { Left, Right };
|
||||
|
||||
Q_PROPERTY(QSize gridSize READ gridSize WRITE setGridSize)
|
||||
Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap)
|
||||
Q_PROPERTY(bool alignToGrid READ alignToGrid WRITE setAlignToGrid)
|
||||
Q_PROPERTY(bool clickToViewFolders READ clickToViewFolders WRITE setClickToViewFolders)
|
||||
Q_PROPERTY(bool showSelectionMarker READ showSelectionMarker WRITE setShowSelectionMarker)
|
||||
Q_PROPERTY(bool iconsMoveable READ iconsMoveable WRITE setIconsMoveable)
|
||||
Q_PROPERTY(bool customLayout READ customLayout WRITE setCustomLayout)
|
||||
Q_PROPERTY(Layout layout READ layout WRITE setLayout)
|
||||
Q_PROPERTY(Alignment alignment READ alignment WRITE setAlignment)
|
||||
|
||||
public:
|
||||
IconView(QGraphicsWidget *parent);
|
||||
~IconView();
|
||||
|
||||
void setModel(QAbstractItemModel *model);
|
||||
|
||||
void setGridSize(const QSize &gridSize);
|
||||
QSize gridSize() const;
|
||||
|
||||
void setIconSize(const QSize &gridSize);
|
||||
|
||||
void setWordWrap(bool on);
|
||||
bool wordWrap() const;
|
||||
|
||||
void setTextLineCount(int rows);
|
||||
int textLineCount() const;
|
||||
|
||||
void setLayout(Layout layout);
|
||||
Layout layout() const;
|
||||
|
||||
void setAlignment(Alignment alignment);
|
||||
Alignment alignment() const;
|
||||
|
||||
void setAlignToGrid(bool on);
|
||||
bool alignToGrid() const;
|
||||
|
||||
void setIconsMoveable(bool on);
|
||||
bool iconsMoveable() const;
|
||||
|
||||
void setCustomLayout(bool value);
|
||||
bool customLayout() const;
|
||||
|
||||
/**
|
||||
* The icon position data is encoded in a QStringList as follows:
|
||||
*
|
||||
* 1 string for version number
|
||||
* 1 string for icon count
|
||||
* 3 strings for every icon:
|
||||
* 1 string for icon name
|
||||
* 1 string for icon x position (relative to contentsRect().left())
|
||||
* 1 string for icon y position (relative to contentsRect().top())
|
||||
*/
|
||||
void setIconPositionsData(const QStringList &data);
|
||||
QStringList iconPositionsData() const;
|
||||
|
||||
void setPopupPreviewSettings(const bool &showPreview, const QStringList &plugins);
|
||||
bool popupShowPreview() const;
|
||||
QStringList popupPreviewPlugins() const;
|
||||
|
||||
void updateGridSize();
|
||||
|
||||
bool listingInProgress() const;
|
||||
bool renameInProgress() const;
|
||||
bool dragInProgress() const;
|
||||
bool popupVisible() const;
|
||||
|
||||
int scrollBarExtent() const;
|
||||
QSize sizeForRowsColumns(int rows, int columns) const;
|
||||
|
||||
QRect visualRect(const QModelIndex &index) const;
|
||||
QRegion visualRegion(const QModelIndex &index) const;
|
||||
QModelIndex indexAt(const QPointF &point) const;
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
|
||||
|
||||
void setClickToViewFolders(bool click);
|
||||
bool clickToViewFolders() const;
|
||||
void openPopup(const QModelIndex &index);
|
||||
|
||||
void setShowSelectionMarker(bool show);
|
||||
bool showSelectionMarker() const;
|
||||
|
||||
bool overlayEnabled() const;
|
||||
|
||||
signals:
|
||||
void indexesMoved(const QModelIndexList &indexes);
|
||||
void popupViewClosed();
|
||||
void busy(bool);
|
||||
void modelChanged();
|
||||
|
||||
protected:
|
||||
bool indexIntersectsRect(const QModelIndex &index, const QRect &rect) const;
|
||||
void startDrag(const QPointF &pos, QWidget *widget);
|
||||
void focusInEvent(QFocusEvent *event);
|
||||
void focusOutEvent(QFocusEvent *event);
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
|
||||
void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||
void keyPressEvent(QKeyEvent *event);
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
||||
void wheelEvent(QGraphicsSceneWheelEvent *event);
|
||||
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
|
||||
void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
|
||||
void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
|
||||
void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
|
||||
void dropEvent(QGraphicsSceneDragDropEvent *event);
|
||||
void timerEvent(QTimerEvent *event);
|
||||
void changeEvent(QEvent *event);
|
||||
void resizeEvent(QGraphicsSceneResizeEvent *event);
|
||||
|
||||
void rowsInserted(const QModelIndex &parent, int first, int last);
|
||||
void rowsRemoved(const QModelIndex &parent, int first, int last);
|
||||
void modelReset();
|
||||
void layoutChanged();
|
||||
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
|
||||
void commitData(QWidget *editor);
|
||||
void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint);
|
||||
|
||||
void finishedScrolling();
|
||||
|
||||
QSize itemSize(const QStyleOptionViewItemV4 &option, const QModelIndex &index) const;
|
||||
void paintItem(QPainter *painter, const QStyleOptionViewItemV4 &option, const QModelIndex &index) const;
|
||||
|
||||
public slots:
|
||||
void renameSelectedIcon();
|
||||
void selectFirstIcon();
|
||||
void selectLastIcon();
|
||||
|
||||
private slots:
|
||||
void listingStarted(const KUrl &url);
|
||||
void listingClear();
|
||||
void listingCompleted();
|
||||
void listingCanceled();
|
||||
void listingError(const QString &message);
|
||||
void itemsDeleted(const KFileItemList &items);
|
||||
void popupCloseRequested();
|
||||
void dropActionTriggered(QAction *action);
|
||||
void dropCompleted();
|
||||
void repositionWidgetsManually();
|
||||
void closeEditor(QGraphicsWidget *editor, QAbstractItemDelegate::EndEditHint hint);
|
||||
void checkIfFolderResult(const QModelIndex &index, bool isFolder);
|
||||
void svgChanged();
|
||||
void viewScrolled();
|
||||
|
||||
private:
|
||||
void paintMessage(QPainter *painter, const QRect &rect, const QString &message,
|
||||
const QIcon &icon = QIcon()) const;
|
||||
int columnsForWidth(qreal width) const;
|
||||
int rowsForHeight(qreal height) const;
|
||||
QPoint nextGridPosition(const QPoint &prevPos, const QSize &gridSize, const QRect &contentRect) const;
|
||||
QPoint findNextEmptyPosition(const QPoint &prevPos, const QSize &gridSize, const QRect &contentRect) const;
|
||||
void layoutItems();
|
||||
void alignIconsToGrid();
|
||||
QRect itemsBoundingRect() const;
|
||||
QRect adjustedContentsRect(const QSize &gridSize, int *rowCount, int *colCount) const;
|
||||
bool doLayoutSanityCheck();
|
||||
void updateScrollBar();
|
||||
void updateScrollBarGeometry();
|
||||
void updateEditorGeometry();
|
||||
void updateToolTip();
|
||||
void updateRubberband();
|
||||
void updateActionButtons();
|
||||
void createDropActions(const KUrl::List &urls, QActionGroup *actions);
|
||||
QStyleOptionViewItemV4 viewOptions() const;
|
||||
void selectIcon(QModelIndex index);
|
||||
void selectFirstOrLastIcon(bool firstIcon); //Useful to select first or last icon when view is unsorted
|
||||
void selectIconsInArea(const QRect &area, const QPoint &finalPos); //Selects all icons in the specified rectangular area
|
||||
void selectIconRange(const QModelIndex &begin, const QModelIndex &end);
|
||||
void repaintSelectedIcons();
|
||||
QRect selectedItemsBoundingRect() const;
|
||||
|
||||
private:
|
||||
QVector<ViewItem> m_items;
|
||||
QHash<QString, QPoint> m_savedPositions;
|
||||
mutable QCache<quint64, QRegion> m_regionCache;
|
||||
qreal m_margins[4];
|
||||
int m_columns;
|
||||
int m_rows;
|
||||
int m_validRows;
|
||||
int m_numTextLines;
|
||||
bool m_layoutBroken;
|
||||
bool m_needPostLayoutPass;
|
||||
bool m_positionsLoaded;
|
||||
bool m_doubleClick;
|
||||
bool m_dragInProgress;
|
||||
bool m_hoverDrag;
|
||||
bool m_iconsLocked;
|
||||
bool m_alignToGrid;
|
||||
bool m_wordWrap;
|
||||
bool m_popupShowPreview;
|
||||
bool m_folderIsEmpty;
|
||||
bool m_clickToViewFolders;
|
||||
bool m_showSelectionMarker;
|
||||
bool m_drawIconShrinked;
|
||||
QPersistentModelIndex m_hoveredIndex;
|
||||
QPersistentModelIndex m_pressedIndex;
|
||||
QPersistentModelIndex m_editorIndex;
|
||||
QRect m_rubberBand;
|
||||
QPointF m_buttonDownPos;
|
||||
QPointF m_mouseMovedPos;
|
||||
QTime m_pressTime;
|
||||
Layout m_layout;
|
||||
Alignment m_alignment;
|
||||
QString m_errorMessage;
|
||||
QPoint m_lastDeletedPos;
|
||||
QPoint m_currentLayoutPos;
|
||||
QSize m_gridSize;
|
||||
QBasicTimer m_delayedLayoutTimer;
|
||||
QBasicTimer m_delayedRelayoutTimer;
|
||||
QBasicTimer m_delayedCacheClearTimer;
|
||||
QBasicTimer m_toolTipShowTimer;
|
||||
QBasicTimer m_searchQueryTimer;
|
||||
ToolTipWidget *m_toolTipWidget;
|
||||
QPointer<PopupView> m_popupView;
|
||||
QPointer<QWidget> m_popupCausedWidget;
|
||||
KonqOperations *m_dropOperation;
|
||||
QActionGroup *m_dropActions;
|
||||
QPersistentModelIndex m_popupIndex;
|
||||
QPointer<ItemEditor> m_editor;
|
||||
Animator *m_animator;
|
||||
ActionOverlay *m_actionOverlay;
|
||||
QStringList m_popupPreviewPlugins;
|
||||
QString m_searchQuery;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
79
plasma/desktop/applets/folderview/iconwidget.cpp
Normal file
79
plasma/desktop/applets/folderview/iconwidget.cpp
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright © 2008 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "iconwidget.h"
|
||||
|
||||
#include <KDirModel>
|
||||
#include <KDirLister>
|
||||
|
||||
#include <konq_operations.h>
|
||||
|
||||
#include <Plasma/Corona>
|
||||
#include <QGraphicsSceneDragDropEvent>
|
||||
|
||||
|
||||
IconWidget::IconWidget(QGraphicsItem *parent)
|
||||
: Plasma::IconWidget(parent), m_model(0)
|
||||
{
|
||||
setAcceptDrops(true);
|
||||
}
|
||||
|
||||
IconWidget::~IconWidget()
|
||||
{
|
||||
}
|
||||
|
||||
void IconWidget::setModel(KDirModel *model)
|
||||
{
|
||||
m_model = model;
|
||||
}
|
||||
|
||||
void IconWidget::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
|
||||
{
|
||||
if (KUrl::List::canDecode(event->mimeData())){
|
||||
Plasma::IconWidget::sceneEventFilter(this, event);
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
|
||||
void IconWidget::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
|
||||
{
|
||||
Plasma::IconWidget::sceneEventFilter(this, event);
|
||||
}
|
||||
|
||||
void IconWidget::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
|
||||
{
|
||||
const QString appletMimeType = static_cast<Plasma::Corona*>(scene())->appletMimeType();
|
||||
event->setAccepted(!event->mimeData()->hasFormat(appletMimeType));
|
||||
}
|
||||
|
||||
void IconWidget::dropEvent(QGraphicsSceneDragDropEvent *event)
|
||||
{
|
||||
// If the dropped item is an applet, let the parent widget handle it
|
||||
const QString appletMimeType = static_cast<Plasma::Corona*>(scene())->appletMimeType();
|
||||
if (event->mimeData()->hasFormat(appletMimeType)) {
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
QDropEvent ev(event->screenPos(), event->dropAction(), event->mimeData(),
|
||||
event->buttons(), event->modifiers());
|
||||
KonqOperations::doDrop(m_model->dirLister()->rootItem(), m_model->dirLister()->url(),
|
||||
&ev, event->widget());
|
||||
}
|
||||
|
48
plasma/desktop/applets/folderview/iconwidget.h
Normal file
48
plasma/desktop/applets/folderview/iconwidget.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright © 2008 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef ICONWIDGET_H
|
||||
#define ICONWIDGET_H
|
||||
|
||||
#include <Plasma/IconWidget>
|
||||
|
||||
class KDirModel;
|
||||
|
||||
|
||||
// Reimplemented to add drag and drop support
|
||||
class IconWidget : public Plasma::IconWidget
|
||||
{
|
||||
public:
|
||||
IconWidget(QGraphicsItem *parent = 0);
|
||||
~IconWidget();
|
||||
|
||||
void setModel(KDirModel *model);
|
||||
|
||||
protected:
|
||||
void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
|
||||
void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
|
||||
void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
|
||||
void dropEvent(QGraphicsSceneDragDropEvent *event);
|
||||
|
||||
private:
|
||||
KDirModel *m_model;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
128
plasma/desktop/applets/folderview/itemeditor.cpp
Normal file
128
plasma/desktop/applets/folderview/itemeditor.cpp
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Copyright © 2009 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "itemeditor.h"
|
||||
|
||||
#include <KTextEdit>
|
||||
#include <QAbstractItemModel>
|
||||
#include <QAbstractItemDelegate>
|
||||
|
||||
#include <KMimeType>
|
||||
|
||||
|
||||
ItemEditor::ItemEditor(QGraphicsWidget *parent, const QStyleOptionViewItemV4 &option,
|
||||
const QModelIndex &index)
|
||||
: QGraphicsProxyWidget(parent),
|
||||
m_index(index),
|
||||
m_uncommitted(true)
|
||||
{
|
||||
// Create the editor
|
||||
m_editor = new KTextEdit();
|
||||
m_editor->setAttribute(Qt::WA_NoSystemBackground);
|
||||
m_editor->setAcceptRichText(false);
|
||||
m_editor->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_editor->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_editor->setAlignment(option.displayAlignment);
|
||||
m_editor->installEventFilter(this);
|
||||
|
||||
// Set the editor data
|
||||
const QVariant value = index.data(Qt::EditRole);
|
||||
const QString text = value.toString();
|
||||
m_editor->insertPlainText(text);
|
||||
m_editor->selectAll();
|
||||
|
||||
const QString extension = KMimeType::extractKnownExtension(text);
|
||||
if (!extension.isEmpty()) {
|
||||
// The filename contains an extension. Assure that only the filename
|
||||
// gets selected.
|
||||
const int selectionLength = text.length() - extension.length() - 1;
|
||||
QTextCursor cursor = m_editor->textCursor();
|
||||
cursor.movePosition(QTextCursor::StartOfBlock);
|
||||
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, selectionLength);
|
||||
m_editor->setTextCursor(cursor);
|
||||
}
|
||||
|
||||
setWidget(m_editor);
|
||||
}
|
||||
|
||||
ItemEditor::~ItemEditor()
|
||||
{
|
||||
}
|
||||
|
||||
void ItemEditor::commitData()
|
||||
{
|
||||
if (m_uncommitted) {
|
||||
const_cast<QAbstractItemModel*>(m_index.model())->setData(m_index, m_editor->toPlainText(), Qt::EditRole);
|
||||
m_uncommitted = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ItemEditor::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
KTextEdit *editor = qobject_cast<KTextEdit*>(watched);
|
||||
if (!editor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (event->type())
|
||||
{
|
||||
case QEvent::KeyPress:
|
||||
{
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
|
||||
switch (keyEvent->key())
|
||||
{
|
||||
case Qt::Key_Tab:
|
||||
case Qt::Key_Backtab:
|
||||
commitData();
|
||||
emit closeEditor(this, QAbstractItemDelegate::NoHint);
|
||||
return true;
|
||||
|
||||
case Qt::Key_Enter:
|
||||
case Qt::Key_Return:
|
||||
if (!editor->toPlainText().isEmpty()) {
|
||||
commitData();
|
||||
emit closeEditor(this, QAbstractItemDelegate::SubmitModelCache);
|
||||
}
|
||||
return true;
|
||||
|
||||
case Qt::Key_Escape:
|
||||
emit closeEditor(this, QAbstractItemDelegate::RevertModelCache);
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
} // switch (keyEvent->key())
|
||||
} // case QEvent::KeyPress
|
||||
|
||||
case QEvent::FocusOut:
|
||||
{
|
||||
if (m_uncommitted) {
|
||||
commitData();
|
||||
emit closeEditor(this, QAbstractItemDelegate::NoHint);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
} // switch (event->type())
|
||||
}
|
||||
|
||||
#include "moc_itemeditor.cpp"
|
||||
|
56
plasma/desktop/applets/folderview/itemeditor.h
Normal file
56
plasma/desktop/applets/folderview/itemeditor.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright © 2009 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef EDITOR_H
|
||||
#define EDITOR_H
|
||||
|
||||
#include <QGraphicsProxyWidget>
|
||||
#include <QAbstractItemDelegate>
|
||||
#include <QModelIndex>
|
||||
#include <KTextEdit>
|
||||
|
||||
class QStyleOptionViewItemV4;
|
||||
|
||||
|
||||
class ItemEditor : public QGraphicsProxyWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ItemEditor(QGraphicsWidget *parent, const QStyleOptionViewItemV4 &option,
|
||||
const QModelIndex &index);
|
||||
~ItemEditor();
|
||||
|
||||
KTextEdit *nativeWidget() const { return m_editor; }
|
||||
|
||||
signals:
|
||||
void closeEditor(QGraphicsWidget *editor, QAbstractItemDelegate::EndEditHint hint = QAbstractItemDelegate::NoHint);
|
||||
|
||||
protected:
|
||||
void commitData();
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
KTextEdit *m_editor;
|
||||
QModelIndex m_index;
|
||||
bool m_uncommitted;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
52
plasma/desktop/applets/folderview/kabstractviewadapter_p.h
Normal file
52
plasma/desktop/applets/folderview/kabstractviewadapter_p.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2008 by Fredrik Höglund <fredrik@kde.org> *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public License *
|
||||
* along with this library; see the file COPYING.LIB. If not, write to *
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
|
||||
* Boston, MA 02110-1301, USA. *
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef KABSTRACTVIEWADAPTER_H
|
||||
#define KABSTRACTVIEWADAPTER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QAbstractItemModel;
|
||||
class QModelIndex;
|
||||
class QPalette;
|
||||
class QRect;
|
||||
class QSize;
|
||||
|
||||
/*
|
||||
* Interface used by KFilePreviewGenerator to generate previews
|
||||
* for files. The interface allows KFilePreviewGenerator to be
|
||||
* independent from the view implementation.
|
||||
*/
|
||||
class KAbstractViewAdapter : public QObject
|
||||
{
|
||||
public:
|
||||
enum Signal { ScrollBarValueChanged };
|
||||
|
||||
KAbstractViewAdapter(QObject *parent) : QObject(parent) {}
|
||||
virtual ~KAbstractViewAdapter() {}
|
||||
virtual QAbstractItemModel *model() const = 0;
|
||||
virtual QSize iconSize() const = 0;
|
||||
virtual QPalette palette() const = 0;
|
||||
virtual QRect visibleArea() const = 0;
|
||||
virtual QRect visualRect(const QModelIndex &index) const = 0;
|
||||
virtual void connect(Signal signal, QObject *receiver, const char *slot) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
82
plasma/desktop/applets/folderview/label.cpp
Normal file
82
plasma/desktop/applets/folderview/label.cpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright © 2008, 2009 Fredrik Höglund <fredrik@kde.org>
|
||||
* Copyright © 2008 Andrew Lake <jamboarder@yahoo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "label.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QPainter>
|
||||
|
||||
#include "plasma/paintutils.h"
|
||||
|
||||
Label::Label(QGraphicsWidget *parent)
|
||||
: QGraphicsWidget(parent)
|
||||
{
|
||||
QFontMetrics fm(font());
|
||||
setMinimumHeight(fm.height() + 4);
|
||||
setMaximumHeight(fm.height() + 4);
|
||||
setCacheMode(DeviceCoordinateCache);
|
||||
}
|
||||
|
||||
Label::~Label()
|
||||
{
|
||||
}
|
||||
|
||||
void Label::setText(const QString &text)
|
||||
{
|
||||
m_text = text;
|
||||
update();
|
||||
}
|
||||
|
||||
QString Label::text() const
|
||||
{
|
||||
return m_text;
|
||||
}
|
||||
|
||||
void Label::setDrawShadow(bool on)
|
||||
{
|
||||
m_drawShadow = on;
|
||||
update();
|
||||
}
|
||||
|
||||
bool Label::drawShadow() const
|
||||
{
|
||||
return m_drawShadow;
|
||||
}
|
||||
|
||||
void Label::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option)
|
||||
Q_UNUSED(widget)
|
||||
|
||||
QColor color = palette().color(QPalette::Text);
|
||||
color.setAlphaF(.75);
|
||||
|
||||
QFontMetrics fm(font());
|
||||
const QString text = fm.elidedText(m_text, Qt::ElideMiddle, contentsRect().width());
|
||||
|
||||
painter->save();
|
||||
painter->setFont(font());
|
||||
painter->setPen(color);
|
||||
painter->drawText(contentsRect(), Qt::AlignCenter, text);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
#include "moc_label.cpp"
|
||||
|
53
plasma/desktop/applets/folderview/label.h
Normal file
53
plasma/desktop/applets/folderview/label.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright © 2008 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef LABEL_H
|
||||
#define LABEL_H
|
||||
|
||||
#include <QGraphicsWidget>
|
||||
|
||||
class QString;
|
||||
class QPainter;
|
||||
|
||||
class Label : public QGraphicsWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString text READ text WRITE setText)
|
||||
Q_PROPERTY(bool drawShadow READ drawShadow WRITE setDrawShadow)
|
||||
|
||||
public:
|
||||
Label(QGraphicsWidget *parent);
|
||||
~Label();
|
||||
|
||||
void setText(const QString &text);
|
||||
QString text() const;
|
||||
|
||||
void setDrawShadow(bool on);
|
||||
bool drawShadow() const;
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
|
||||
|
||||
private:
|
||||
QString m_text;
|
||||
QPixmap m_divider;
|
||||
bool m_drawShadow;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
648
plasma/desktop/applets/folderview/listview.cpp
Normal file
648
plasma/desktop/applets/folderview/listview.cpp
Normal file
|
@ -0,0 +1,648 @@
|
|||
/*
|
||||
* Copyright © 2008, 2009 Fredrik Höglund <fredrik@kde.org>
|
||||
* Copyright © 2008 Rafael Fernández López <ereslibre@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "listview.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsSceneHoverEvent>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QItemSelectionModel>
|
||||
#include <QPainter>
|
||||
#include <QStyleOptionGraphicsItem>
|
||||
|
||||
#include <KDirModel>
|
||||
#include <KStringHandler>
|
||||
|
||||
#include "animator.h"
|
||||
#include "proxymodel.h"
|
||||
|
||||
#include "plasma/containment.h"
|
||||
#include "plasma/corona.h"
|
||||
#include "plasma/paintutils.h"
|
||||
#include "plasma/theme.h"
|
||||
|
||||
|
||||
ListView::ListView(QGraphicsWidget *parent)
|
||||
: AbstractItemView(parent),
|
||||
m_rowHeight(-1),
|
||||
m_numTextLines(2),
|
||||
m_dragInProgress(false),
|
||||
m_wordWrap(true)
|
||||
{
|
||||
setAcceptHoverEvents(true);
|
||||
setAcceptDrops(true);
|
||||
setCacheMode(NoCache);
|
||||
|
||||
m_animator = new Animator(this);
|
||||
}
|
||||
|
||||
ListView::~ListView()
|
||||
{
|
||||
}
|
||||
|
||||
void ListView::setModel(QAbstractItemModel *model)
|
||||
{
|
||||
AbstractItemView::setModel(model);
|
||||
updateSizeHint();
|
||||
}
|
||||
|
||||
void ListView::setIconSize(const QSize &size)
|
||||
{
|
||||
if (size != m_iconSize) {
|
||||
m_iconSize = size;
|
||||
m_rowHeight = -1;
|
||||
updateSizeHint();
|
||||
}
|
||||
}
|
||||
|
||||
void ListView::setWordWrap(bool on)
|
||||
{
|
||||
if (m_wordWrap != on) {
|
||||
m_wordWrap = on;
|
||||
m_rowHeight = -1;
|
||||
updateSizeHint();
|
||||
}
|
||||
}
|
||||
|
||||
bool ListView::wordWrap() const
|
||||
{
|
||||
return m_wordWrap;
|
||||
}
|
||||
|
||||
void ListView::setTextLineCount(int count)
|
||||
{
|
||||
if (count != m_numTextLines) {
|
||||
m_numTextLines = count;
|
||||
m_rowHeight = -1;
|
||||
updateSizeHint();
|
||||
}
|
||||
}
|
||||
|
||||
int ListView::textLineCount() const
|
||||
{
|
||||
return m_numTextLines;
|
||||
}
|
||||
|
||||
void ListView::rowsInserted(const QModelIndex &parent, int first, int last)
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
Q_UNUSED(first)
|
||||
Q_UNUSED(last)
|
||||
|
||||
markAreaDirty(visibleArea());
|
||||
updateScrollBar();
|
||||
updateSizeHint();
|
||||
}
|
||||
|
||||
void ListView::rowsRemoved(const QModelIndex &parent, int first, int last)
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
Q_UNUSED(first)
|
||||
Q_UNUSED(last)
|
||||
|
||||
markAreaDirty(visibleArea());
|
||||
updateScrollBar();
|
||||
updateSizeHint();
|
||||
}
|
||||
|
||||
void ListView::modelReset()
|
||||
{
|
||||
markAreaDirty(visibleArea());
|
||||
updateScrollBar();
|
||||
updateSizeHint();
|
||||
}
|
||||
|
||||
void ListView::layoutChanged()
|
||||
{
|
||||
markAreaDirty(visibleArea());
|
||||
updateScrollBar();
|
||||
updateSizeHint();
|
||||
}
|
||||
|
||||
void ListView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
|
||||
{
|
||||
markAreaDirty(visualRect(topLeft) | visualRect(bottomRight));
|
||||
}
|
||||
|
||||
void ListView::svgChanged()
|
||||
{
|
||||
m_rowHeight = -1;
|
||||
updateSizeHint();
|
||||
}
|
||||
|
||||
void ListView::updateScrollBar()
|
||||
{
|
||||
if (!m_model) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_rowHeight == -1 && m_model->rowCount() > 0) {
|
||||
// Use the height of the first item for all items
|
||||
const QSize size = itemSize(viewOptions(), m_model->index(0, 0));
|
||||
m_rowHeight = size.height();
|
||||
}
|
||||
|
||||
int max = int(m_rowHeight * m_model->rowCount() - contentsRect().height());
|
||||
|
||||
// Keep the scrollbar handle at the bottom if it was at the bottom and the viewport
|
||||
// has grown vertically
|
||||
bool updateValue = (m_scrollBar->minimum() != m_scrollBar->maximum()) &&
|
||||
(max > m_scrollBar->maximum()) && (m_scrollBar->value() == m_scrollBar->maximum());
|
||||
|
||||
m_scrollBar->setRange(0, max);
|
||||
m_scrollBar->setPageStep(contentsRect().height());
|
||||
m_scrollBar->setSingleStep(m_rowHeight);
|
||||
|
||||
if (updateValue) {
|
||||
m_scrollBar->setValue(max);
|
||||
}
|
||||
|
||||
if (max > 0) {
|
||||
m_scrollBar->show();
|
||||
} else {
|
||||
m_scrollBar->hide();
|
||||
}
|
||||
}
|
||||
|
||||
QSize ListView::itemSize(const QStyleOptionViewItemV4 &option, const QModelIndex &index) const
|
||||
{
|
||||
qreal left, top, right, bottom;
|
||||
m_itemFrame->getMargins(left, top, right, bottom);
|
||||
|
||||
QFont font = option.font;
|
||||
|
||||
KFileItem item = qvariant_cast<KFileItem>(index.data(KDirModel::FileItemRole));
|
||||
if (item.isLink()) {
|
||||
font.setItalic(true);
|
||||
}
|
||||
|
||||
QFontMetrics fm(font);
|
||||
|
||||
QSize size;
|
||||
size.rwidth() += contentsRect().width();
|
||||
size.rheight() = qMax(option.decorationSize.height(), m_numTextLines * fm.height());
|
||||
size.rheight() += top + bottom;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void ListView::updateSizeHint()
|
||||
{
|
||||
if (m_rowHeight == -1 && m_model->rowCount() > 0) {
|
||||
// Use the height of the first item for all items
|
||||
const QSize size = itemSize(viewOptions(), m_model->index(0, 0));
|
||||
m_rowHeight = size.height();
|
||||
}
|
||||
|
||||
QFontMetrics fm(font());
|
||||
setPreferredSize(m_iconSize.width() + fm.lineSpacing() * 18, m_rowHeight * m_model->rowCount());
|
||||
}
|
||||
|
||||
QRect ListView::visualRect(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid() || index.row() >= m_model->rowCount()) {
|
||||
return QRect();
|
||||
}
|
||||
|
||||
QRectF cr = contentsRect();
|
||||
return QRect(cr.left(), cr.top() + index.row() * m_rowHeight, cr.width(), m_rowHeight);
|
||||
}
|
||||
|
||||
void ListView::paintItem(QPainter *painter, const QStyleOptionViewItemV4 &option, const QModelIndex &index) const
|
||||
{
|
||||
// Draw the item background
|
||||
// ========================
|
||||
const bool selected = (option.state & QStyle::State_Selected);
|
||||
const qreal hoverProgress = m_animator->hoverProgress(index);
|
||||
|
||||
QPixmap from(option.rect.size());
|
||||
QPixmap to(option.rect.size());
|
||||
from.fill(Qt::transparent);
|
||||
to.fill(Qt::transparent);
|
||||
|
||||
if (selected) {
|
||||
QPainter p(&from);
|
||||
m_itemFrame->setElementPrefix("selected");
|
||||
m_itemFrame->resizeFrame(option.rect.size());
|
||||
m_itemFrame->paintFrame(&p, QPoint());
|
||||
}
|
||||
|
||||
if (hoverProgress > 0.0) {
|
||||
QPainter p(&to);
|
||||
m_itemFrame->setElementPrefix(selected ? "selected+hover" : "hover");
|
||||
m_itemFrame->resizeFrame(option.rect.size());
|
||||
m_itemFrame->paintFrame(&p, QPoint());
|
||||
p.end();
|
||||
|
||||
QPixmap result = Plasma::PaintUtils::transition(from, to, hoverProgress);
|
||||
painter->drawPixmap(option.rect.topLeft(), result);
|
||||
} else if (selected) {
|
||||
painter->drawPixmap(option.rect.topLeft(), from);
|
||||
}
|
||||
|
||||
qreal left, top, right, bottom;
|
||||
m_itemFrame->getMargins(left, top, right, bottom);
|
||||
const QRect r = option.rect.adjusted(left, top, -right, -bottom);
|
||||
|
||||
|
||||
const QRect ir = QStyle::alignedRect(option.direction, Qt::AlignLeft | Qt::AlignVCenter,
|
||||
option.decorationSize, r);
|
||||
|
||||
const QRect tr = QStyle::alignedRect(option.direction, Qt::AlignRight | Qt::AlignVCenter,
|
||||
QSize(r.width() - ir.width() - 4, r.height()), r);
|
||||
|
||||
|
||||
// Draw the text label
|
||||
// ===================
|
||||
QFont font = option.font;
|
||||
|
||||
KFileItem item = qvariant_cast<KFileItem>(index.data(KDirModel::FileItemRole));
|
||||
if (item.isLink()) {
|
||||
font.setItalic(true);
|
||||
}
|
||||
|
||||
const QString text = index.data(Qt::DisplayRole).toString();
|
||||
|
||||
QTextLayout layout;
|
||||
layout.setText(KStringHandler::preProcessWrap(text));
|
||||
layout.setFont(font);
|
||||
const QSize size = doTextLayout(layout, tr.size(), Qt::AlignLeft | Qt::AlignVCenter,
|
||||
QTextOption::WrapAtWordBoundaryOrAnywhere);
|
||||
|
||||
painter->setPen(option.palette.color(QPalette::Text));
|
||||
drawTextLayout(painter, layout, tr);
|
||||
|
||||
|
||||
// Draw the icon
|
||||
// =============
|
||||
const QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
|
||||
icon.paint(painter, ir);
|
||||
|
||||
|
||||
// Draw the focus rect
|
||||
// ===================
|
||||
if (option.state & QStyle::State_HasFocus) {
|
||||
QRect fr = QStyle::alignedRect(layoutDirection(), Qt::AlignCenter, size, tr);
|
||||
fr.adjust(-2, -2, 2, 2);
|
||||
|
||||
QColor color = Qt::white;
|
||||
color.setAlphaF(.33);
|
||||
|
||||
QColor transparent = color;
|
||||
transparent.setAlphaF(0);
|
||||
|
||||
QLinearGradient g1(0, fr.top(), 0, fr.bottom());
|
||||
g1.setColorAt(0, color);
|
||||
g1.setColorAt(1, transparent);
|
||||
|
||||
QLinearGradient g2(fr.left(), 0, fr.right(), 0);
|
||||
g2.setColorAt(0, transparent);
|
||||
g2.setColorAt(.5, color);
|
||||
g2.setColorAt(1, transparent);
|
||||
|
||||
painter->save();
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
painter->setPen(QPen(g1, 0));
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->drawRoundedRect(QRectF(fr).adjusted(.5, .5, -.5, -.5), 2, 2);
|
||||
painter->setPen(QPen(g2, 0));
|
||||
painter->drawLine(QLineF(fr.left() + 2, fr.bottom() + .5,
|
||||
fr.right() - 2, fr.bottom() + .5));
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
|
||||
void ListView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(widget)
|
||||
|
||||
const QRect cr = contentsRect().toRect();
|
||||
if (!cr.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
QRect clipRect = cr & option->exposedRect.toAlignedRect();
|
||||
if (clipRect.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
int offset = m_scrollBar->value();
|
||||
|
||||
prepareBackBuffer();
|
||||
|
||||
painter->setClipRect(clipRect);
|
||||
|
||||
|
||||
// Update the dirty region in the backbuffer
|
||||
// =========================================
|
||||
if (!m_dirtyRegion.isEmpty()) {
|
||||
QStyleOptionViewItemV4 opt = viewOptions();
|
||||
int width = m_scrollBar->isVisible() ? cr.width() - m_scrollBar->geometry().width() : cr.width();
|
||||
|
||||
if (m_rowHeight == -1 && m_model->rowCount() > 0) {
|
||||
// Use the height of the first item for all items
|
||||
const QSize size = itemSize(opt, m_model->index(0, 0));
|
||||
m_rowHeight = size.height();
|
||||
}
|
||||
|
||||
QPainter p(&m_pixmap);
|
||||
p.translate(-cr.topLeft() - QPoint(0, offset));
|
||||
p.setClipRegion(m_dirtyRegion);
|
||||
|
||||
// Clear the dirty region
|
||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
p.fillRect(mapToViewport(cr).toAlignedRect(), Qt::transparent);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
|
||||
for (int i = 0; i < m_model->rowCount(); i++) {
|
||||
opt.rect = QRect(cr.left(), cr.top() + i * m_rowHeight, width, m_rowHeight);
|
||||
|
||||
if (!m_dirtyRegion.intersects(opt.rect)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const QModelIndex index = m_model->index(i, 0);
|
||||
opt.state &= ~(QStyle::State_HasFocus | QStyle::State_MouseOver | QStyle::State_Selected);
|
||||
|
||||
if (m_selectionModel->isSelected(index)) {
|
||||
if (m_dragInProgress) {
|
||||
continue;
|
||||
}
|
||||
opt.state |= QStyle::State_Selected | QStyle::State_MouseOver;
|
||||
}
|
||||
|
||||
if (hasFocus() && index == m_selectionModel->currentIndex()) {
|
||||
opt.state |= QStyle::State_HasFocus;
|
||||
}
|
||||
|
||||
paintItem(&p, opt, index);
|
||||
}
|
||||
|
||||
m_dirtyRegion = QRegion();
|
||||
}
|
||||
|
||||
syncBackBuffer(painter, clipRect);
|
||||
}
|
||||
|
||||
QModelIndex ListView::indexAt(const QPointF &pos) const
|
||||
{
|
||||
int row = pos.y() / m_rowHeight;
|
||||
return row < m_model->rowCount() ? m_model->index(row, 0) : QModelIndex();
|
||||
}
|
||||
|
||||
void ListView::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
const QPoint pos = mapToViewport(event->pos()).toPoint();
|
||||
const QModelIndex index = indexAt(pos);
|
||||
|
||||
if (m_selectionModel->currentIndex().isValid()) {
|
||||
markAreaDirty(visualRect(m_selectionModel->currentIndex()));
|
||||
}
|
||||
|
||||
if (index.isValid()) {
|
||||
emit entered(index);
|
||||
m_selectionModel->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect);
|
||||
markAreaDirty(visualRect(index));
|
||||
}
|
||||
}
|
||||
|
||||
void ListView::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
const QPoint pos = mapToViewport(event->pos()).toPoint();
|
||||
const QModelIndex index = indexAt(pos);
|
||||
|
||||
if (index != m_selectionModel->currentIndex()) {
|
||||
if (m_selectionModel->currentIndex().isValid()) {
|
||||
emit left(m_selectionModel->currentIndex());
|
||||
}
|
||||
if (index.isValid()) {
|
||||
emit entered(index);
|
||||
}
|
||||
markAreaDirty(visualRect(index));
|
||||
markAreaDirty(visualRect(m_selectionModel->currentIndex()));
|
||||
m_selectionModel->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect);
|
||||
}
|
||||
}
|
||||
|
||||
void ListView::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
if (!m_pressedIndex.isValid() && m_selectionModel->currentIndex().isValid()) {
|
||||
emit left(m_selectionModel->currentIndex());
|
||||
markAreaDirty(visualRect(m_selectionModel->currentIndex()));
|
||||
m_selectionModel->clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ListView::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
const QPointF pos = mapToViewport(event->pos());
|
||||
//setFocus(Qt::MouseFocusReason);
|
||||
|
||||
if (event->button() == Qt::RightButton) {
|
||||
const QModelIndex index = indexAt(pos);
|
||||
if (index.isValid()) {
|
||||
if (!m_selectionModel->isSelected(index)) {
|
||||
m_selectionModel->select(index, QItemSelectionModel::ClearAndSelect);
|
||||
m_selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
|
||||
markAreaDirty(visibleArea());
|
||||
}
|
||||
event->ignore(); // Causes contextMenuEvent() to get called
|
||||
} else if (m_selectionModel->hasSelection()) {
|
||||
m_selectionModel->clearSelection();
|
||||
markAreaDirty(visibleArea());
|
||||
}
|
||||
m_pressedIndex = index;
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
const QModelIndex index = indexAt(pos);
|
||||
|
||||
// If an icon was pressed
|
||||
if (index.isValid())
|
||||
{
|
||||
if (event->modifiers() & Qt::ControlModifier) {
|
||||
m_selectionModel->select(index, QItemSelectionModel::Toggle);
|
||||
m_selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
|
||||
markAreaDirty(visualRect(index));
|
||||
} else if (!m_selectionModel->isSelected(index)) {
|
||||
m_selectionModel->select(index, QItemSelectionModel::ClearAndSelect);
|
||||
m_selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
|
||||
markAreaDirty(visibleArea());
|
||||
}
|
||||
m_pressedIndex = index;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ListView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
const QPointF pos = mapToViewport(event->pos());
|
||||
const QModelIndex index = indexAt(pos);
|
||||
|
||||
if (index.isValid() && index == m_pressedIndex && !(event->modifiers() & Qt::ControlModifier)) {
|
||||
emit activated(index);
|
||||
m_selectionModel->clearSelection();
|
||||
markAreaDirty(visibleArea());
|
||||
}
|
||||
}
|
||||
|
||||
m_pressedIndex = QModelIndex();
|
||||
}
|
||||
|
||||
void ListView::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (!(event->buttons() & Qt::LeftButton)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If an item is pressed
|
||||
if (m_pressedIndex.isValid())
|
||||
{
|
||||
const QPointF buttonDownPos = event->buttonDownPos(Qt::LeftButton);
|
||||
const QPointF point = event->pos() - buttonDownPos;
|
||||
if (point.toPoint().manhattanLength() >= QApplication::startDragDistance())
|
||||
{
|
||||
startDrag(mapToViewport(buttonDownPos), event->widget());
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ListView::wheelEvent(QGraphicsSceneWheelEvent *event)
|
||||
{
|
||||
if ((event->modifiers() & Qt::CTRL) || (event->orientation() == Qt::Horizontal)) {
|
||||
// Let the event propagate to the parent widget
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
const int pixels = 96 * event->delta() / 120;
|
||||
smoothScroll(0, -pixels);
|
||||
}
|
||||
|
||||
void ListView::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
|
||||
{
|
||||
const QPointF pos = mapToViewport(event->pos());
|
||||
const QModelIndex index = indexAt(pos);
|
||||
|
||||
if (index.isValid()) {
|
||||
emit contextMenuRequest(event->widget(), event->screenPos());
|
||||
} else {
|
||||
// Let the event propagate to the parent widget
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
void ListView::dropEvent(QGraphicsSceneDragDropEvent *)
|
||||
{
|
||||
m_pressedIndex = QModelIndex();
|
||||
}
|
||||
|
||||
void ListView::resizeEvent(QGraphicsSceneResizeEvent *)
|
||||
{
|
||||
const QRectF cr = contentsRect();
|
||||
const QRectF r = QRectF(cr.right() - m_scrollBar->geometry().width(), cr.top(),
|
||||
m_scrollBar->geometry().width(), cr.height());
|
||||
|
||||
if (m_scrollBar->geometry() != r) {
|
||||
m_scrollBar->setGeometry(r);
|
||||
}
|
||||
|
||||
updateScrollBar();
|
||||
markAreaDirty(visibleArea());
|
||||
}
|
||||
|
||||
// pos is the position where the mouse was clicked in the applet.
|
||||
// widget is the widget that sent the mouse event that triggered the drag.
|
||||
void ListView::startDrag(const QPointF &pos, QWidget *widget)
|
||||
{
|
||||
QModelIndexList indexes = m_selectionModel->selectedIndexes();
|
||||
QRect boundingRect;
|
||||
foreach (const QModelIndex &index, indexes) {
|
||||
boundingRect |= visualRect(index);
|
||||
}
|
||||
|
||||
QPixmap pixmap(boundingRect.size());
|
||||
pixmap.fill(Qt::transparent);
|
||||
|
||||
QStyleOptionViewItemV4 option = viewOptions();
|
||||
// ### We can't draw the items as selected or hovered since Qt doesn't
|
||||
// use an ARGB window for the drag pixmap.
|
||||
//option.state |= QStyle::State_Selected | QStyle::State_MouseOver;
|
||||
option.state &= ~(QStyle::State_Selected | QStyle::State_MouseOver);
|
||||
|
||||
QPainter p(&pixmap);
|
||||
foreach (const QModelIndex &index, indexes)
|
||||
{
|
||||
option.rect = visualRect(index).translated(-boundingRect.topLeft());
|
||||
paintItem(&p, option, index);
|
||||
}
|
||||
p.end();
|
||||
|
||||
// Mark the area containing the about-to-be-dragged items as dirty, so they
|
||||
// will be erased from the view on the next repaint. We have to do this
|
||||
// before calling QDrag::exec(), since it's a blocking call.
|
||||
markAreaDirty(boundingRect);
|
||||
|
||||
m_dragInProgress = true;
|
||||
|
||||
QDrag *drag = new QDrag(widget);
|
||||
drag->setMimeData(m_model->mimeData(indexes));
|
||||
drag->setPixmap(pixmap);
|
||||
drag->setHotSpot((pos - boundingRect.topLeft()).toPoint());
|
||||
drag->exec(m_model->supportedDragActions());
|
||||
|
||||
m_dragInProgress = false;
|
||||
|
||||
// Repaint the dragged icons in case the drag did not remove the file
|
||||
markAreaDirty(boundingRect);
|
||||
}
|
||||
|
||||
QStyleOptionViewItemV4 ListView::viewOptions() const
|
||||
{
|
||||
QStyleOptionViewItemV4 option;
|
||||
initStyleOption(&option);
|
||||
|
||||
option.font = font();
|
||||
option.decorationAlignment = Qt::AlignCenter;
|
||||
option.decorationPosition = QStyleOptionViewItem::Left;
|
||||
option.decorationSize = iconSize();
|
||||
option.displayAlignment = Qt::AlignLeft | Qt::AlignVCenter;
|
||||
option.textElideMode = Qt::ElideMiddle;
|
||||
option.locale = QLocale::system();
|
||||
option.widget = m_styleWidget;
|
||||
option.viewItemPosition = QStyleOptionViewItemV4::OnlyOne;
|
||||
|
||||
if (m_wordWrap) {
|
||||
option.features = QStyleOptionViewItemV2::WrapText;
|
||||
}
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
#include "moc_listview.cpp"
|
98
plasma/desktop/applets/folderview/listview.h
Normal file
98
plasma/desktop/applets/folderview/listview.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright © 2008, 2009 Fredrik Höglund <fredrik@kde.org>
|
||||
* Copyright © 2008 Rafael Fernández López <ereslibre@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef LISTVIEW_H
|
||||
#define LISTVIEW_H
|
||||
|
||||
#include "abstractitemview.h"
|
||||
|
||||
#include <QCache>
|
||||
|
||||
|
||||
class QStyleOptionViewItemV4;
|
||||
class Animator;
|
||||
|
||||
namespace Plasma {
|
||||
class FrameSvg;
|
||||
}
|
||||
|
||||
class ListView : public AbstractItemView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ListView(QGraphicsWidget *parent = 0);
|
||||
~ListView();
|
||||
|
||||
void setModel(QAbstractItemModel *model);
|
||||
|
||||
void setIconSize(const QSize &iconSize);
|
||||
|
||||
void setWordWrap(bool on);
|
||||
bool wordWrap() const;
|
||||
|
||||
void setTextLineCount(int rows);
|
||||
int textLineCount() const;
|
||||
|
||||
QModelIndex indexAt(const QPointF &point) const;
|
||||
QRect visualRect(const QModelIndex &index) const;
|
||||
|
||||
protected:
|
||||
void startDrag(const QPointF &pos, QWidget *widget);
|
||||
void updateScrollBar();
|
||||
void updateSizeHint();
|
||||
QStyleOptionViewItemV4 viewOptions() const;
|
||||
|
||||
QSize itemSize(const QStyleOptionViewItemV4 &option, const QModelIndex &index) const;
|
||||
void paintItem(QPainter *painter, const QStyleOptionViewItemV4 &option, const QModelIndex &index) const;
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
|
||||
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
|
||||
void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
||||
void wheelEvent(QGraphicsSceneWheelEvent *event);
|
||||
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
|
||||
void dropEvent(QGraphicsSceneDragDropEvent *event);
|
||||
void resizeEvent(QGraphicsSceneResizeEvent *event);
|
||||
|
||||
void rowsInserted(const QModelIndex &parent, int first, int last);
|
||||
void rowsRemoved(const QModelIndex &parent, int first, int last);
|
||||
void modelReset();
|
||||
void layoutChanged();
|
||||
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
|
||||
|
||||
private slots:
|
||||
void svgChanged();
|
||||
|
||||
private:
|
||||
Animator *m_animator;
|
||||
int m_rowHeight;
|
||||
int m_numTextLines;
|
||||
QPersistentModelIndex m_pressedIndex;
|
||||
bool m_dragInProgress;
|
||||
bool m_wordWrap;
|
||||
bool m_drawShadows;
|
||||
};
|
||||
|
||||
#endif // LISTVIEW_H
|
|
@ -0,0 +1,164 @@
|
|||
[Desktop Entry]
|
||||
Name=Folder
|
||||
Name[af]=Gids
|
||||
Name[ar]=مجلد
|
||||
Name[as]=ফোল্ডাৰ
|
||||
Name[ast]=Carpeta
|
||||
Name[be]=Тэчка
|
||||
Name[be@latin]=Kataloh
|
||||
Name[bg]=Папка
|
||||
Name[bn]=ফোল্ডার
|
||||
Name[bn_IN]=ফোল্ডার
|
||||
Name[br]=Renkell
|
||||
Name[bs]=Fascikla
|
||||
Name[ca]=Carpeta
|
||||
Name[ca@valencia]=Carpeta
|
||||
Name[cs]=Složka
|
||||
Name[csb]=Katalog
|
||||
Name[cy]=Plygell
|
||||
Name[da]=Mappe
|
||||
Name[de]=Ordner
|
||||
Name[el]=Φάκελος
|
||||
Name[en_GB]=Folder
|
||||
Name[eo]=Dosierujo
|
||||
Name[es]=Carpeta
|
||||
Name[et]=Kataloog
|
||||
Name[eu]=Karpeta
|
||||
Name[fa]=پوشه
|
||||
Name[fi]=Kansio
|
||||
Name[fr]=Dossier
|
||||
Name[fy]=Map
|
||||
Name[ga]=Fillteán
|
||||
Name[gl]=Cartafol
|
||||
Name[gu]=ફોલ્ડર
|
||||
Name[he]=תיקייה
|
||||
Name[hi]=फ़ोल्डर
|
||||
Name[hne]=फोल्डर
|
||||
Name[hr]=Mapa
|
||||
Name[hsb]=Zapisk
|
||||
Name[hu]=Mappa
|
||||
Name[ia]=Dossier
|
||||
Name[id]=Folder
|
||||
Name[is]=Mappa
|
||||
Name[it]=Cartella
|
||||
Name[ja]=フォルダ
|
||||
Name[ka]=საქაღალდე
|
||||
Name[kk]=Қапшық
|
||||
Name[km]=ថត
|
||||
Name[kn]=ಕಡತಕೋಶ
|
||||
Name[ko]=폴더
|
||||
Name[ku]=Peldank
|
||||
Name[lt]=Aplankas
|
||||
Name[lv]=Mape
|
||||
Name[mai]=फोल्डर
|
||||
Name[mk]=Папка
|
||||
Name[ml]=കൂട
|
||||
Name[mr]=संचयीका
|
||||
Name[ms]=Folder
|
||||
Name[nb]=Mappe
|
||||
Name[nds]=Orner
|
||||
Name[ne]=फोल्डर
|
||||
Name[nl]=Map
|
||||
Name[nn]=Mappe
|
||||
Name[oc]=Repertòri
|
||||
Name[or]=ଫୋଲଡର
|
||||
Name[pa]=ਫੋਲਡਰ
|
||||
Name[pl]=Katalog
|
||||
Name[pt]=Pasta
|
||||
Name[pt_BR]=Pasta
|
||||
Name[ro]=Dosar
|
||||
Name[ru]=Папка
|
||||
Name[se]=Máhppa
|
||||
Name[si]=බහලුම
|
||||
Name[sk]=Priečinok
|
||||
Name[sl]=Mapa
|
||||
Name[sr]=Фасцикла
|
||||
Name[sr@ijekavian]=Фасцикла
|
||||
Name[sr@ijekavianlatin]=Fascikla
|
||||
Name[sr@latin]=Fascikla
|
||||
Name[sv]=Katalog
|
||||
Name[ta]=அடைவு
|
||||
Name[te]=ఫొల్డర్
|
||||
Name[tg]=Феҳрист
|
||||
Name[th]=โฟลเดอร์
|
||||
Name[tr]=Dizin
|
||||
Name[ug]=قىسقۇچ
|
||||
Name[uk]=Тека
|
||||
Name[uz]=Jild
|
||||
Name[uz@cyrillic]=Жилд
|
||||
Name[vi]=Thư mục
|
||||
Name[wa]=Ridant
|
||||
Name[x-test]=xxFolderxx
|
||||
Name[zh_CN]=文件夹
|
||||
Name[zh_TW]=資料夾
|
||||
Comment=Display the contents of folders
|
||||
Comment[ar]=اعرض محتوى المجلدات
|
||||
Comment[bg]=Показва съдържанието на папки
|
||||
Comment[bs]=Prikaži sadržaj direktorija
|
||||
Comment[ca]=Mostra el contingut de les carpetes
|
||||
Comment[ca@valencia]=Mostra el contingut de les carpetes
|
||||
Comment[cs]=Zobrazit obsah složek
|
||||
Comment[da]=Vis indholdet af mapper
|
||||
Comment[de]=Ordnerinhalte anzeigen
|
||||
Comment[el]=Εμφάνιση περιεχομένων των φακέλων
|
||||
Comment[en_GB]=Display the contents of folders
|
||||
Comment[es]=Mostrar el contenido de las carpetas
|
||||
Comment[et]=Kataloogide sisu näitamine
|
||||
Comment[eu]=Bistaratu karpeten edukia
|
||||
Comment[fi]=Näyttää kansion sisällön
|
||||
Comment[fr]=Afficher les contenus de dossiers
|
||||
Comment[ga]=Taispeáin inneachar d'fhillteáin
|
||||
Comment[gl]=Mostra o contido dos cartafoles
|
||||
Comment[he]=הצגת התוכן של תיקייה
|
||||
Comment[hu]=Megjeleníti a mappák tartalmát
|
||||
Comment[ia]=Monstra le contentos de dossieres
|
||||
Comment[id]=Tampilkan isi folder
|
||||
Comment[is]=Sýna innihald mappa
|
||||
Comment[it]=Mostra il contenuto delle cartelle
|
||||
Comment[kk]=Қапшықтардағыны көрсету
|
||||
Comment[km]=បង្ហាញមាតិការបស់ថត
|
||||
Comment[ko]=폴더 내용 보여주기
|
||||
Comment[lt]=Rodyti aplankų turinį
|
||||
Comment[lv]=Rādīt mapju saturu
|
||||
Comment[mr]=संचयीकाचा मजकूर दर्शवा
|
||||
Comment[nb]=Vis pampers innhold
|
||||
Comment[nds]=Den Inholt vun Ornern wiesen
|
||||
Comment[nl]=Toon de inhoud van mappen
|
||||
Comment[pa]=ਫੋਲਡਰਾਂ ਦੀ ਸਮੱਗਰੀ ਵੇਖਾਓ
|
||||
Comment[pl]=Wyświetl zawartość katalogów
|
||||
Comment[pt]=Mostrar o conteúdo das pastas
|
||||
Comment[pt_BR]=Mostra o conteúdo das pastas
|
||||
Comment[ro]=Afișează conținutul dosarelor
|
||||
Comment[ru]=Вывод содержимого папки
|
||||
Comment[sk]=Zobraziť obsah priečinkov
|
||||
Comment[sl]=Pokaži vsebino map
|
||||
Comment[sr]=Приказује садржај фасцикли
|
||||
Comment[sr@ijekavian]=Приказује садржај фасцикли
|
||||
Comment[sr@ijekavianlatin]=Prikazuje sadržaj fascikli
|
||||
Comment[sr@latin]=Prikazuje sadržaj fascikli
|
||||
Comment[sv]=Visa innehåll i kataloger
|
||||
Comment[tg]=Намоиши мазмуни феҳристҳо
|
||||
Comment[tr]=Dizinlerin içeriğini göster
|
||||
Comment[ug]=قىسقۇچلارنىڭ مەزمۇنلىرىنى كۆرسىتىدۇ
|
||||
Comment[uk]=Показ вмісту тек
|
||||
Comment[wa]=Håynêye çou k' i gn a dins des ridants
|
||||
Comment[x-test]=xxDisplay the contents of foldersxx
|
||||
Comment[zh_CN]=显示文件夹的内容
|
||||
Comment[zh_TW]=顯示資料夾內容
|
||||
Type=Service
|
||||
Icon=folder
|
||||
X-KDE-ServiceTypes=Plasma/Applet,Plasma/Containment
|
||||
X-Plasma-ContainmentCategories=desktop
|
||||
X-Plasma-DropMimeTypes=inode/directory
|
||||
|
||||
X-KDE-Library=plasma_applet_folderview
|
||||
X-KDE-PluginInfo-Author=Fredrik Höglund
|
||||
X-KDE-PluginInfo-Email=fredrik@kde.org
|
||||
X-KDE-PluginInfo-Name=folderview
|
||||
X-KDE-PluginInfo-Version=1.0
|
||||
X-KDE-PluginInfo-Website=
|
||||
X-KDE-PluginInfo-Category=File System
|
||||
X-KDE-PluginInfo-Depends=
|
||||
X-KDE-PluginInfo-License=LGPL
|
||||
X-KDE-PluginInfo-EnabledByDefault=true
|
||||
|
705
plasma/desktop/applets/folderview/popupview.cpp
Normal file
705
plasma/desktop/applets/folderview/popupview.cpp
Normal file
|
@ -0,0 +1,705 @@
|
|||
/*
|
||||
* Copyright © 2009 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "popupview.h"
|
||||
#include "dialogshadows_p.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QDesktopWidget>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsWidget>
|
||||
#include <QItemSelectionModel>
|
||||
#include <QStyle>
|
||||
|
||||
#include <KAction>
|
||||
#include <KBookmarkManager>
|
||||
#include <KDesktopFile>
|
||||
#include <KDirModel>
|
||||
#include <kfileitemactions.h>
|
||||
#include <KFileItemDelegate>
|
||||
#include <kfileitemlistproperties.h>
|
||||
#include <kfilepreviewgenerator.h>
|
||||
#include <knewfilemenu.h>
|
||||
#include <KWindowSystem>
|
||||
#include <KMenu>
|
||||
|
||||
#include <kio/fileundomanager.h>
|
||||
#include <kio/paste.h>
|
||||
|
||||
#include <konqmimedata.h>
|
||||
#include <konq_operations.h>
|
||||
#include <konq_popupmenu.h>
|
||||
|
||||
#include "dirlister.h"
|
||||
#include "folderviewadapter.h"
|
||||
#include "iconview.h"
|
||||
#include "proxymodel.h"
|
||||
|
||||
#include <Plasma/Applet>
|
||||
#include <Plasma/BusyWidget>
|
||||
#include <Plasma/FrameSvg>
|
||||
#include <Plasma/Theme>
|
||||
#include <Plasma/WindowEffects>
|
||||
|
||||
|
||||
QTime PopupView::s_lastOpenClose;
|
||||
|
||||
PopupView::PopupView(const QModelIndex &index, const QPoint &pos,
|
||||
const bool &showPreview, const QStringList &previewPlugins,
|
||||
const IconView *parentView)
|
||||
: QWidget(0, Qt::X11BypassWindowManagerHint),
|
||||
m_view(0),
|
||||
m_parentView(parentView),
|
||||
m_busyWidget(0),
|
||||
m_iconView(0),
|
||||
m_parentViewModel(0),
|
||||
m_dirModel(0),
|
||||
m_model(0),
|
||||
m_actionCollection(this),
|
||||
m_newMenu(0),
|
||||
m_itemActions(0),
|
||||
m_showingMenu(false),
|
||||
m_showPreview(showPreview),
|
||||
m_delayedClose(false),
|
||||
m_previewPlugins(previewPlugins)
|
||||
{
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
#ifdef Q_WS_X11
|
||||
if (KWindowSystem::compositingActive()) {
|
||||
setAttribute(Qt::WA_NoSystemBackground, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
KWindowSystem::setState(effectiveWinId(), NET::SkipTaskbar | NET::SkipPager);
|
||||
|
||||
setAcceptDrops(true);
|
||||
|
||||
QPalette pal = palette();
|
||||
pal.setColor(backgroundRole(), Qt::transparent);
|
||||
pal.setColor(QPalette::Text, Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor));
|
||||
setPalette(pal);
|
||||
|
||||
m_parentViewModel = static_cast<const ProxyModel*>(index.model());
|
||||
|
||||
KFileItem item = m_parentViewModel->itemForIndex(index);
|
||||
if (item.isDesktopFile()) {
|
||||
KDesktopFile file(item.localPath());
|
||||
m_url = file.readUrl();
|
||||
} else {
|
||||
m_url = item.targetUrl();
|
||||
}
|
||||
|
||||
m_background = new Plasma::FrameSvg(this);
|
||||
m_background->setImagePath("dialogs/background");
|
||||
|
||||
int left = m_background->marginSize(Plasma::LeftMargin);
|
||||
int top = m_background->marginSize(Plasma::TopMargin);
|
||||
int right = m_background->marginSize(Plasma::RightMargin);
|
||||
int bottom = m_background->marginSize(Plasma::BottomMargin);
|
||||
|
||||
setContentsMargins(left, top, right, bottom);
|
||||
|
||||
resize(parentView->sizeForRowsColumns(2, 3) + QSize(left + right, top + bottom));
|
||||
|
||||
const QRect available = QApplication::desktop()->availableGeometry(pos);
|
||||
QPoint pt = pos;
|
||||
|
||||
if (pt.x() + width() > available.right()) {
|
||||
pt.rx() -= width();
|
||||
}
|
||||
if (pt.x() < available.left()) {
|
||||
pt.rx() = available.left();
|
||||
}
|
||||
|
||||
if (pt.y() + height() > available.bottom()) {
|
||||
pt.ry() -= height();
|
||||
}
|
||||
if (pt.y() < available.top()) {
|
||||
pt.ry() = available.top();
|
||||
}
|
||||
|
||||
Plasma::WindowEffects::overrideShadow(winId(), true);
|
||||
|
||||
move(pt);
|
||||
show();
|
||||
|
||||
QTimer::singleShot(10, this, SLOT(init()));
|
||||
s_lastOpenClose.restart();
|
||||
}
|
||||
|
||||
PopupView::~PopupView()
|
||||
{
|
||||
delete m_newMenu;
|
||||
s_lastOpenClose.restart();
|
||||
}
|
||||
|
||||
void PopupView::delayedHide()
|
||||
{
|
||||
if (!m_iconView || !m_iconView->dragInProgress()) {
|
||||
m_hideTimer.start(400, this);
|
||||
}
|
||||
}
|
||||
|
||||
bool PopupView::dragInProgress()
|
||||
{
|
||||
return m_iconView && m_iconView->dragInProgress();
|
||||
}
|
||||
|
||||
void PopupView::init()
|
||||
{
|
||||
if (m_model) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_scene = new QGraphicsScene(this);
|
||||
m_view = new QGraphicsView(m_scene, this);
|
||||
m_view->setFrameShape(QFrame::NoFrame);
|
||||
m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_view->viewport()->setAutoFillBackground(false);
|
||||
m_view->setGeometry(contentsRect());
|
||||
m_view->show();
|
||||
|
||||
DirLister *lister = new DirLister(this);
|
||||
lister->setDelayedMimeTypes(true);
|
||||
lister->setAutoErrorHandlingEnabled(false, 0);
|
||||
lister->openUrl(m_url);
|
||||
|
||||
m_dirModel = new KDirModel(this);
|
||||
m_dirModel->setDropsAllowed(KDirModel::DropOnDirectory | KDirModel::DropOnLocalExecutable);
|
||||
m_dirModel->setDirLister(lister);
|
||||
|
||||
m_model = new ProxyModel(this);
|
||||
m_model->setSourceModel(m_dirModel);
|
||||
m_model->setSortLocaleAware(m_parentViewModel->isSortLocaleAware());
|
||||
m_model->setParseDesktopFiles(m_parentViewModel->parseDesktopFiles());
|
||||
m_model->setFilterMode(m_parentViewModel->ProxyModel::NoFilter);
|
||||
m_model->setDynamicSortFilter(true);
|
||||
|
||||
if (!m_parentViewModel->dynamicSortFilter()) {
|
||||
m_model->setSortDirectoriesFirst(true);
|
||||
m_model->sort(int(KDirModel::Name), Qt::AscendingOrder);
|
||||
} else {
|
||||
m_model->setSortDirectoriesFirst(m_parentViewModel->sortDirectoriesFirst());
|
||||
m_model->sort(m_parentViewModel->sortColumn(), m_parentViewModel->sortOrder());
|
||||
}
|
||||
|
||||
m_delegate = new KFileItemDelegate(this);
|
||||
m_selectionModel = new QItemSelectionModel(m_model, this);
|
||||
|
||||
m_iconView = new IconView(0);
|
||||
m_iconView->setModel(m_model);
|
||||
m_iconView->setItemDelegate(m_delegate);
|
||||
m_iconView->setSelectionModel(m_selectionModel);
|
||||
m_iconView->setFont(m_parentView->font());
|
||||
m_iconView->setPalette(palette());
|
||||
m_iconView->setDrawShadows(m_parentView->drawShadows());
|
||||
m_iconView->setIconSize(m_parentView->iconSize());
|
||||
m_iconView->setGridSize(m_parentView->gridSize());
|
||||
m_iconView->setTextLineCount(m_parentView->textLineCount());
|
||||
m_iconView->setWordWrap(m_parentView->wordWrap());
|
||||
m_iconView->setIconsMoveable(false);
|
||||
m_iconView->setClickToViewFolders(false);
|
||||
m_iconView->setShowSelectionMarker(m_parentView->showSelectionMarker());
|
||||
|
||||
connect(m_iconView, SIGNAL(activated(QModelIndex)), SLOT(activated(QModelIndex)));
|
||||
connect(m_iconView, SIGNAL(contextMenuRequest(QWidget*,QPoint)), SLOT(contextMenuRequest(QWidget*,QPoint)));
|
||||
connect(m_iconView, SIGNAL(busy(bool)), SLOT(setBusy(bool)));
|
||||
connect(m_iconView, SIGNAL(popupViewClosed()), SLOT(maybeClose()));
|
||||
|
||||
FolderViewAdapter *adapter = new FolderViewAdapter(m_iconView);
|
||||
m_previewGenerator = new KFilePreviewGenerator(adapter, m_model);
|
||||
m_previewGenerator->setPreviewShown(m_showPreview);
|
||||
m_previewGenerator->setEnabledPlugins(m_previewPlugins);
|
||||
|
||||
m_iconView->setGeometry(contentsRect());
|
||||
m_iconView->show();
|
||||
|
||||
m_scene->addItem(m_iconView);
|
||||
setBusy(true);
|
||||
}
|
||||
|
||||
void PopupView::createActions()
|
||||
{
|
||||
// Remove the Shift+Delete shortcut from the cut action, since it's used for deleting files
|
||||
KAction *cut = KStandardAction::cut(this, SLOT(cut()), this);
|
||||
KShortcut cutShortCut = cut->shortcut();
|
||||
cutShortCut.remove(Qt::SHIFT + Qt::Key_Delete);
|
||||
cut->setShortcut(cutShortCut);
|
||||
|
||||
KAction *copy = KStandardAction::copy(this, SLOT(copy()), this);
|
||||
|
||||
KIO::FileUndoManager *manager = KIO::FileUndoManager::self();
|
||||
|
||||
KAction *undo = KStandardAction::undo(manager, SLOT(undo()), this);
|
||||
connect(manager, SIGNAL(undoAvailable(bool)), undo, SLOT(setEnabled(bool)));
|
||||
connect(manager, SIGNAL(undoTextChanged(QString)), SLOT(undoTextChanged(QString)));
|
||||
undo->setEnabled(manager->undoAvailable());
|
||||
|
||||
KAction *paste = KStandardAction::paste(this, SLOT(paste()), this);
|
||||
KAction *pasteTo = KStandardAction::paste(this, SLOT(pasteTo()), this);
|
||||
pasteTo->setEnabled(false); // Only enabled during popupMenu()
|
||||
|
||||
QString actionText = KIO::pasteActionText();
|
||||
if (!actionText.isEmpty()) {
|
||||
paste->setText(actionText);
|
||||
} else {
|
||||
paste->setEnabled(false);
|
||||
}
|
||||
|
||||
KAction *rename = new KAction(KIcon("edit-rename"), i18n("&Rename"), this);
|
||||
rename->setShortcut(Qt::Key_F2);
|
||||
connect(rename, SIGNAL(triggered()), SLOT(renameSelectedIcon()));
|
||||
|
||||
KAction *trash = new KAction(KIcon("user-trash"), i18n("&Move to Trash"), this);
|
||||
trash->setShortcut(Qt::Key_Delete);
|
||||
connect(trash, SIGNAL(triggered(Qt::MouseButtons,Qt::KeyboardModifiers)),
|
||||
SLOT(moveToTrash(Qt::MouseButtons,Qt::KeyboardModifiers)));
|
||||
|
||||
KAction *emptyTrash = new KAction(KIcon("trash-empty"), i18n("&Empty Trash Bin"), this);
|
||||
KConfig trashConfig("trashrc", KConfig::SimpleConfig);
|
||||
emptyTrash->setEnabled(!trashConfig.group("Status").readEntry("Empty", true));
|
||||
connect(emptyTrash, SIGNAL(triggered()), SLOT(emptyTrashBin()));
|
||||
|
||||
KAction *del = new KAction(i18n("&Delete"), this);
|
||||
del->setIcon(KIcon("edit-delete"));
|
||||
del->setShortcut(Qt::SHIFT + Qt::Key_Delete);
|
||||
connect(del, SIGNAL(triggered()), SLOT(deleteSelectedIcons()));
|
||||
|
||||
// Create the new menu
|
||||
m_newMenu = new KNewFileMenu(&m_actionCollection, "new_menu", this);
|
||||
connect(m_newMenu->menu(), SIGNAL(aboutToShow()), this, SLOT(aboutToShowCreateNew()));
|
||||
|
||||
m_actionCollection.addAction("undo", undo);
|
||||
m_actionCollection.addAction("cut", cut);
|
||||
m_actionCollection.addAction("copy", copy);
|
||||
m_actionCollection.addAction("paste", paste);
|
||||
m_actionCollection.addAction("pasteto", pasteTo);
|
||||
m_actionCollection.addAction("rename", rename);
|
||||
m_actionCollection.addAction("trash", trash);
|
||||
m_actionCollection.addAction("del", del);
|
||||
m_actionCollection.addAction("empty_trash", emptyTrash);
|
||||
}
|
||||
|
||||
void PopupView::contextMenuRequest(QWidget *widget, const QPoint& screenPos)
|
||||
{
|
||||
showContextMenu(widget, screenPos, m_selectionModel->selectedIndexes());
|
||||
}
|
||||
|
||||
void PopupView::showContextMenu(QWidget *widget, const QPoint &screenPos, const QList<QModelIndex> &indexes)
|
||||
{
|
||||
Q_UNUSED(widget)
|
||||
// contextMenuRequest is only called from the icon view, which is created in init()
|
||||
// which mean m_model should always be initialized
|
||||
Q_ASSERT(m_model);
|
||||
|
||||
if (indexes.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_actionCollection.isEmpty()) {
|
||||
createActions();
|
||||
}
|
||||
|
||||
KFileItemList items;
|
||||
bool hasRemoteFiles = false;
|
||||
bool isTrashLink = false;
|
||||
|
||||
foreach (const QModelIndex &index, m_selectionModel->selectedIndexes()) {
|
||||
KFileItem item = m_model->itemForIndex(index);
|
||||
if (!item.isNull()) {
|
||||
hasRemoteFiles |= item.localPath().isEmpty();
|
||||
items.append(item);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we're showing the menu for the trash link
|
||||
if (items.count() == 1 && items.at(0).isDesktopFile()) {
|
||||
KDesktopFile file(items.at(0).localPath());
|
||||
if (file.readType() == "Link" && file.readUrl() == "trash:/") {
|
||||
isTrashLink = true;
|
||||
}
|
||||
}
|
||||
|
||||
QAction *pasteTo = m_actionCollection.action("pasteto");
|
||||
if (pasteTo) {
|
||||
if (QAction *paste = m_actionCollection.action("paste")) {
|
||||
pasteTo->setEnabled(paste->isEnabled());
|
||||
pasteTo->setText(paste->text());
|
||||
}
|
||||
}
|
||||
|
||||
QList<QAction*> editActions;
|
||||
editActions.append(m_actionCollection.action("rename"));
|
||||
|
||||
KConfigGroup configGroup(KGlobal::config(), "KDE");
|
||||
bool showDeleteCommand = configGroup.readEntry("ShowDeleteCommand", false);
|
||||
|
||||
// Don't add the "Move to Trash" action if we're showing the menu for the trash link
|
||||
if (!isTrashLink) {
|
||||
if (!hasRemoteFiles) {
|
||||
editActions.append(m_actionCollection.action("trash"));
|
||||
} else {
|
||||
showDeleteCommand = true;
|
||||
}
|
||||
}
|
||||
if (showDeleteCommand) {
|
||||
editActions.append(m_actionCollection.action("del"));
|
||||
}
|
||||
|
||||
KParts::BrowserExtension::ActionGroupMap actionGroups;
|
||||
actionGroups.insert("editactions", editActions);
|
||||
|
||||
KParts::BrowserExtension::PopupFlags flags = KParts::BrowserExtension::ShowProperties;
|
||||
flags |= KParts::BrowserExtension::ShowUrlOperations;
|
||||
|
||||
// m_newMenu can be NULL here but KonqPopupMenu does handle this.
|
||||
KonqPopupMenu *contextMenu = new KonqPopupMenu(items, m_url, m_actionCollection, m_newMenu,
|
||||
KonqPopupMenu::ShowNewWindow, flags,
|
||||
QApplication::desktop(),
|
||||
KBookmarkManager::userBookmarksManager(),
|
||||
actionGroups);
|
||||
|
||||
connect(contextMenu->fileItemActions(), SIGNAL(openWithDialogAboutToBeShown()), this, SLOT(openWithDialogAboutToShow()));
|
||||
|
||||
m_showingMenu = true;
|
||||
contextMenu->exec(screenPos);
|
||||
delete contextMenu;
|
||||
m_showingMenu = false;
|
||||
|
||||
if (pasteTo) {
|
||||
pasteTo->setEnabled(false);
|
||||
}
|
||||
|
||||
if (m_delayedClose) {
|
||||
m_delayedClose = false;
|
||||
closeThisAndParentPopup();
|
||||
}
|
||||
}
|
||||
|
||||
KUrl::List PopupView::selectedUrls() const
|
||||
{
|
||||
Q_ASSERT(m_model);
|
||||
|
||||
KUrl::List urls;
|
||||
foreach (const QModelIndex &index, m_selectionModel->selectedIndexes())
|
||||
{
|
||||
KFileItem item = m_model->itemForIndex(index);
|
||||
// Prefer the local URL if there is one, since we can't trash remote URL's
|
||||
const QString path = item.localPath();
|
||||
if (!path.isEmpty()) {
|
||||
urls.append(path);
|
||||
} else {
|
||||
urls.append(item.url());
|
||||
}
|
||||
}
|
||||
return urls;
|
||||
}
|
||||
|
||||
void PopupView::cut()
|
||||
{
|
||||
QMimeData *mimeData = m_model->mimeData(m_selectionModel->selectedIndexes());
|
||||
KonqMimeData::addIsCutSelection(mimeData, true);
|
||||
QApplication::clipboard()->setMimeData(mimeData);
|
||||
}
|
||||
|
||||
void PopupView::copy()
|
||||
{
|
||||
QMimeData *mimeData = m_model->mimeData(m_selectionModel->selectedIndexes());
|
||||
QApplication::clipboard()->setMimeData(mimeData);
|
||||
}
|
||||
|
||||
void PopupView::paste()
|
||||
{
|
||||
KonqOperations::doPaste(QApplication::desktop(), m_url);
|
||||
}
|
||||
|
||||
void PopupView::pasteTo()
|
||||
{
|
||||
KUrl::List urls = selectedUrls();
|
||||
Q_ASSERT(urls.count() == 1);
|
||||
KonqOperations::doPaste(QApplication::desktop(), urls.first());
|
||||
}
|
||||
|
||||
void PopupView::moveToTrash(Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
|
||||
{
|
||||
Q_UNUSED(buttons)
|
||||
if (!m_iconView->renameInProgress()) {
|
||||
KonqOperations::Operation op = (modifiers & Qt::ShiftModifier) ?
|
||||
KonqOperations::DEL : KonqOperations::TRASH;
|
||||
|
||||
KonqOperations::del(QApplication::desktop(), op, selectedUrls());
|
||||
}
|
||||
}
|
||||
|
||||
void PopupView::deleteSelectedIcons()
|
||||
{
|
||||
if (!m_iconView->renameInProgress()) {
|
||||
KonqOperations::del(QApplication::desktop(), KonqOperations::DEL, selectedUrls());
|
||||
}
|
||||
}
|
||||
|
||||
void PopupView::renameSelectedIcon()
|
||||
{
|
||||
activateWindow();
|
||||
m_iconView->renameSelectedIcon();
|
||||
}
|
||||
|
||||
void PopupView::activated(const QModelIndex &index)
|
||||
{
|
||||
const KFileItem item = m_model->itemForIndex(index);
|
||||
item.run();
|
||||
|
||||
closeThisAndParentPopup();
|
||||
}
|
||||
|
||||
void PopupView::openWithDialogAboutToShow()
|
||||
{
|
||||
m_delayedClose = true;
|
||||
hideThisAndParentPopup();
|
||||
}
|
||||
|
||||
void PopupView::setBusy(bool busy)
|
||||
{
|
||||
m_busy = busy;
|
||||
if (busy && !m_busyWidget) {
|
||||
QTimer::singleShot(100, this, SLOT(createBusyWidgetIfNeeded()));
|
||||
} else {
|
||||
delete m_busyWidget;
|
||||
m_busyWidget = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void PopupView::createBusyWidgetIfNeeded()
|
||||
{
|
||||
if (m_busy && !m_busyWidget) {
|
||||
const int size = qMin(width(), height()) * .3;
|
||||
m_busyWidget = new Plasma::BusyWidget;
|
||||
m_busyWidget->setGeometry(QStyle::alignedRect(layoutDirection(), Qt::AlignCenter, QSize(size, size), contentsRect()));
|
||||
m_scene->addItem(m_busyWidget);
|
||||
}
|
||||
}
|
||||
|
||||
void PopupView::emptyTrashBin()
|
||||
{
|
||||
KonqOperations::emptyTrash(QApplication::desktop());
|
||||
}
|
||||
|
||||
void PopupView::undoTextChanged(const QString &text)
|
||||
{
|
||||
if (QAction *action = m_actionCollection.action("undo")) {
|
||||
action->setText(text);
|
||||
}
|
||||
}
|
||||
|
||||
void PopupView::aboutToShowCreateNew()
|
||||
{
|
||||
if (m_newMenu) {
|
||||
m_newMenu->checkUpToDate();
|
||||
m_newMenu->setPopupFiles(m_url);
|
||||
}
|
||||
}
|
||||
|
||||
void PopupView::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
m_background->resizeFrame(rect().size());
|
||||
|
||||
if (m_view) {
|
||||
m_view->setGeometry(contentsRect());
|
||||
}
|
||||
|
||||
if (KWindowSystem::compositingActive()) {
|
||||
Plasma::WindowEffects::enableBlurBehind(winId(), true, m_background->mask());
|
||||
} else {
|
||||
setMask(m_background->mask());
|
||||
}
|
||||
}
|
||||
|
||||
void PopupView::showEvent(QShowEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
DialogShadows::self()->addWindow(this);
|
||||
}
|
||||
|
||||
void PopupView::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
QPainter p(this);
|
||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
p.fillRect(rect(), Qt::transparent);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
m_background->paintFrame(&p);
|
||||
}
|
||||
|
||||
void PopupView::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
if (!m_model) {
|
||||
init();
|
||||
}
|
||||
|
||||
if (m_actionCollection.isEmpty()) {
|
||||
createActions();
|
||||
}
|
||||
|
||||
KFileItem rootItem = m_model->itemForIndex(QModelIndex());
|
||||
//The root item is invalid (non-existent)
|
||||
if (rootItem.isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QMenu menu;
|
||||
menu.addAction(m_actionCollection.action("new_menu"));
|
||||
menu.addSeparator();
|
||||
menu.addAction(m_actionCollection.action("undo"));
|
||||
menu.addAction(m_actionCollection.action("paste"));
|
||||
menu.addSeparator();
|
||||
|
||||
// Add an action for opening the folder in the preferred application.
|
||||
if (!m_itemActions) {
|
||||
// Create a new KFileItem to prevent the target URL in the root item
|
||||
// from being used. In this case we want the configured URL instead.
|
||||
KFileItem item(rootItem.mode(), rootItem.permissions(), m_url);
|
||||
|
||||
KFileItemListProperties itemList(KFileItemList() << item);
|
||||
|
||||
m_itemActions = new KFileItemActions(this);
|
||||
m_itemActions->setItemListProperties(itemList);
|
||||
}
|
||||
menu.addAction(m_itemActions->preferredOpenWithAction(QString()));
|
||||
|
||||
if (m_url.protocol() == "trash") {
|
||||
menu.addAction(m_actionCollection.action("empty_trash"));
|
||||
}
|
||||
|
||||
m_showingMenu = true;
|
||||
menu.exec(event->globalPos());
|
||||
m_showingMenu = false;
|
||||
}
|
||||
|
||||
// This function calls a given method in the parent PopupView, and returns true
|
||||
// if successful or false otherwise.
|
||||
bool PopupView::callOnParent(const char *method)
|
||||
{
|
||||
// Since the scene is a child of the popup view, we can get to the parent view easily
|
||||
PopupView *parentView = qobject_cast<PopupView*>(m_parentView->scene()->parent());
|
||||
|
||||
if (parentView) {
|
||||
// We use a delayed call to give enter and leave events time be delivered
|
||||
QMetaObject::invokeMethod(parentView, method, Qt::QueuedConnection);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PopupView::maybeClose()
|
||||
{
|
||||
if (!underMouse() && !m_showingMenu &&
|
||||
(!m_iconView || (!m_iconView->isUnderMouse() && !m_iconView->dragInProgress())) &&
|
||||
!callOnParent("maybeClose") && !m_hideTimer.isActive()) {
|
||||
m_hideTimer.start(400, this);
|
||||
}
|
||||
}
|
||||
|
||||
void PopupView::closeThisAndParentPopup() {
|
||||
hide();
|
||||
deleteLater();
|
||||
callOnParent("closeThisAndParentPopup");
|
||||
}
|
||||
|
||||
void PopupView::hideThisAndParentPopup()
|
||||
{
|
||||
hide();
|
||||
callOnParent("hideThisAndParentPopup");
|
||||
}
|
||||
|
||||
void PopupView::cancelHideTimer()
|
||||
{
|
||||
m_hideTimer.stop();
|
||||
|
||||
// Propagate the call down the chain of popups
|
||||
callOnParent("cancelHideTimer");
|
||||
}
|
||||
|
||||
void PopupView::enterEvent(QEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
// Make sure that any hide timer down the popup chain is stopped
|
||||
cancelHideTimer();
|
||||
}
|
||||
|
||||
void PopupView::leaveEvent(QEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
// The popups are normally closed by the icon views that created them
|
||||
// in response to hover events, but when the cursor leaves a popup and
|
||||
// enters a widget that isn't an icon view in the popup chain, that
|
||||
// mechanism doesn't work.
|
||||
//
|
||||
// To make sure that the popups are closed when this happens, we call
|
||||
// maybeClose() which checks if the popup is under the mouse cursor,
|
||||
// and if it isn't it calls maybeClose() in the next popup in the chain
|
||||
// and so on. If no popups in the chain is under the mouse cursor,
|
||||
// the root popup will start the hide timer which will close the whole
|
||||
// chain when it fires.
|
||||
if (!m_iconView || !m_iconView->popupVisible()) {
|
||||
maybeClose();
|
||||
}
|
||||
}
|
||||
|
||||
void PopupView::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
m_hideTimer.stop();
|
||||
callOnParent("cancelHideTimer");
|
||||
|
||||
// If the popup is open during a drag and drop operation,
|
||||
// assume that we accept the mimetype.
|
||||
event->setAccepted(true);
|
||||
}
|
||||
|
||||
void PopupView::dragLeaveEvent(QDragLeaveEvent *event)
|
||||
{
|
||||
if (!m_iconView || !m_iconView->popupVisible()) {
|
||||
maybeClose();
|
||||
}
|
||||
|
||||
// If the popup is open during a drag and drop operation,
|
||||
// assume that we accept the mimetype.
|
||||
event->setAccepted(true);
|
||||
}
|
||||
|
||||
void PopupView::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
if (event->timerId() == m_hideTimer.timerId()) {
|
||||
m_hideTimer.stop();
|
||||
emit requestClose();
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_popupview.cpp"
|
||||
|
133
plasma/desktop/applets/folderview/popupview.h
Normal file
133
plasma/desktop/applets/folderview/popupview.h
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright © 2009 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef POPUPVIEW_H
|
||||
#define POPUPVIEW_H
|
||||
|
||||
#include <QBasicTimer>
|
||||
#include <QWidget>
|
||||
#include <QTime>
|
||||
|
||||
#include <KActionCollection>
|
||||
#include <KUrl>
|
||||
|
||||
namespace Plasma {
|
||||
class FrameSvg;
|
||||
class BusyWidget;
|
||||
}
|
||||
|
||||
class QGraphicsView;
|
||||
class QGraphicsScene;
|
||||
class KDirModel;
|
||||
class KFileItemDelegate;
|
||||
class KFilePreviewGenerator;
|
||||
class KNewFileMenu;
|
||||
class KFileItemActions;
|
||||
class QItemSelectionModel;
|
||||
class QModelIndex;
|
||||
class ProxyModel;
|
||||
class IconView;
|
||||
|
||||
class PopupView : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PopupView(const QModelIndex &index, const QPoint &pos,
|
||||
const bool &showPreview, const QStringList &previewPlugins,
|
||||
const IconView *parentView);
|
||||
~PopupView();
|
||||
|
||||
void delayedHide();
|
||||
bool dragInProgress();
|
||||
|
||||
static QTime lastOpenCloseTime() { return s_lastOpenClose; }
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *event);
|
||||
void paintEvent(QPaintEvent *event);
|
||||
void contextMenuEvent(QContextMenuEvent *event);
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
void enterEvent(QEvent *event);
|
||||
void leaveEvent(QEvent *event);
|
||||
void timerEvent(QTimerEvent *event);
|
||||
void dragEnterEvent(QDragEnterEvent *event);
|
||||
void dragLeaveEvent(QDragLeaveEvent *event);
|
||||
|
||||
signals:
|
||||
void requestClose();
|
||||
|
||||
private:
|
||||
void createActions();
|
||||
bool callOnParent(const char *method);
|
||||
KUrl::List selectedUrls() const;
|
||||
void showContextMenu(QWidget *widget, const QPoint &pos, const QList<QModelIndex> &indexes);
|
||||
|
||||
private slots:
|
||||
void init();
|
||||
void activated(const QModelIndex &index);
|
||||
void openWithDialogAboutToShow();
|
||||
void setBusy(bool);
|
||||
void createBusyWidgetIfNeeded();
|
||||
void contextMenuRequest(QWidget *widget, const QPoint &screenPos);
|
||||
void maybeClose();
|
||||
void closeThisAndParentPopup();
|
||||
void hideThisAndParentPopup();
|
||||
void cancelHideTimer();
|
||||
void aboutToShowCreateNew();
|
||||
void emptyTrashBin();
|
||||
void undoTextChanged(const QString &text);
|
||||
|
||||
// These slots are for KonqPopupMenu
|
||||
void cut();
|
||||
void copy();
|
||||
void paste();
|
||||
void pasteTo();
|
||||
void moveToTrash(Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers);
|
||||
void deleteSelectedIcons();
|
||||
void renameSelectedIcon();
|
||||
|
||||
private:
|
||||
Plasma::FrameSvg *m_background;
|
||||
QGraphicsScene *m_scene;
|
||||
QGraphicsView *m_view;
|
||||
const IconView *m_parentView;
|
||||
Plasma::BusyWidget *m_busyWidget;
|
||||
IconView *m_iconView;
|
||||
const ProxyModel *m_parentViewModel;
|
||||
KDirModel *m_dirModel;
|
||||
ProxyModel *m_model;
|
||||
KFileItemDelegate *m_delegate;
|
||||
QItemSelectionModel *m_selectionModel;
|
||||
KFilePreviewGenerator *m_previewGenerator;
|
||||
KUrl m_url;
|
||||
KActionCollection m_actionCollection;
|
||||
KNewFileMenu *m_newMenu;
|
||||
KFileItemActions *m_itemActions;
|
||||
QBasicTimer m_hideTimer;
|
||||
bool m_showingMenu;
|
||||
bool m_showPreview;
|
||||
bool m_busy;
|
||||
bool m_delayedClose;
|
||||
QStringList m_previewPlugins;
|
||||
static QTime s_lastOpenClose;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
118
plasma/desktop/applets/folderview/previewpluginsmodel.cpp
Normal file
118
plasma/desktop/applets/folderview/previewpluginsmodel.cpp
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright © 2008 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "previewpluginsmodel.h"
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
#include <KServiceTypeTrader>
|
||||
|
||||
static bool lessThan(const KService::Ptr &a, const KService::Ptr &b)
|
||||
{
|
||||
return QString::localeAwareCompare(a->name(), b->name()) < 0;
|
||||
}
|
||||
|
||||
PreviewPluginsModel::PreviewPluginsModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
plugins = KServiceTypeTrader::self()->query("ThumbCreator");
|
||||
checkedRows = QVector<bool>(plugins.size(), false);
|
||||
|
||||
// Sort the list alphabetially
|
||||
qStableSort(plugins.begin(), plugins.end(), lessThan);
|
||||
}
|
||||
|
||||
PreviewPluginsModel::~PreviewPluginsModel()
|
||||
{
|
||||
}
|
||||
|
||||
Qt::ItemFlags PreviewPluginsModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
Q_UNUSED(index)
|
||||
|
||||
return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
|
||||
}
|
||||
|
||||
QVariant PreviewPluginsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (index.row() < 0 || index.row() >= plugins.size()) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
return plugins.at(index.row())->name();
|
||||
|
||||
case Qt::CheckStateRole:
|
||||
return checkedRows.at(index.row()) ? Qt::Checked : Qt::Unchecked;
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool PreviewPluginsModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (role != Qt::CheckStateRole) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt());
|
||||
if (state == Qt::Checked) {
|
||||
checkedRows[(index.row())] = true;
|
||||
} else {
|
||||
checkedRows[(index.row())] = false;
|
||||
}
|
||||
|
||||
emit dataChanged(index, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
int PreviewPluginsModel::indexOfPlugin(const QString &name) const
|
||||
{
|
||||
for (int i = 0; i < plugins.size(); i++) {
|
||||
if (plugins.at(i)->desktopEntryName() == name) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void PreviewPluginsModel::setCheckedPlugins(const QStringList &list)
|
||||
{
|
||||
foreach (const QString &name, list) {
|
||||
const int row = indexOfPlugin(name);
|
||||
if (row != -1) {
|
||||
checkedRows[row] = true;
|
||||
emit dataChanged(index(row, 0), index(row, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QStringList PreviewPluginsModel::checkedPlugins() const
|
||||
{
|
||||
QStringList list;
|
||||
for (int i =0; i < checkedRows.size(); ++i) {
|
||||
if (checkedRows.at(i)) {
|
||||
list.append(plugins.at(i)->desktopEntryName());
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
49
plasma/desktop/applets/folderview/previewpluginsmodel.h
Normal file
49
plasma/desktop/applets/folderview/previewpluginsmodel.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright © 2008 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef PREVIEWPLUGINSMODEL_H
|
||||
#define PREVIEWPLUGINSMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <KService>
|
||||
#include <QVector>
|
||||
|
||||
class QStringList;
|
||||
|
||||
class PreviewPluginsModel : public QAbstractListModel
|
||||
{
|
||||
public:
|
||||
PreviewPluginsModel(QObject *parent = 0);
|
||||
virtual ~PreviewPluginsModel();
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const { Q_UNUSED(parent) return plugins.size(); }
|
||||
void setCheckedPlugins(const QStringList &list);
|
||||
QStringList checkedPlugins() const;
|
||||
|
||||
private:
|
||||
int indexOfPlugin(const QString &name) const;
|
||||
|
||||
private:
|
||||
KService::List plugins;
|
||||
QVector<bool> checkedRows;
|
||||
};
|
||||
|
||||
#endif
|
271
plasma/desktop/applets/folderview/proxymodel.cpp
Normal file
271
plasma/desktop/applets/folderview/proxymodel.cpp
Normal file
|
@ -0,0 +1,271 @@
|
|||
/*
|
||||
* Copyright © 2008 Fredrik Höglund <fredrik@kde.org>
|
||||
* Copyright © 2008 Rafael Fernández López <ereslibre@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "proxymodel.h"
|
||||
|
||||
#include <KDesktopFile>
|
||||
#include <KDirModel>
|
||||
#include <KStringHandler>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <kde_file.h>
|
||||
|
||||
|
||||
ProxyModel::ProxyModel(QObject *parent)
|
||||
: QSortFilterProxyModel(parent),
|
||||
m_filterMode(NoFilter),
|
||||
m_sortDirsFirst(true),
|
||||
m_parseDesktopFiles(false),
|
||||
m_patternMatchAll(true)
|
||||
{
|
||||
setSupportedDragActions(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction);
|
||||
}
|
||||
|
||||
ProxyModel::~ProxyModel()
|
||||
{
|
||||
}
|
||||
|
||||
void ProxyModel::setFilterMode(FilterMode filterMode)
|
||||
{
|
||||
m_filterMode = filterMode;
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
ProxyModel::FilterMode ProxyModel::filterMode() const
|
||||
{
|
||||
return m_filterMode;
|
||||
}
|
||||
|
||||
void ProxyModel::setMimeTypeFilterList(const QStringList &mimeList)
|
||||
{
|
||||
m_mimeSet = QSet<QString>::fromList(mimeList);
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
QStringList ProxyModel::mimeTypeFilterList() const
|
||||
{
|
||||
return m_mimeSet.toList();
|
||||
}
|
||||
|
||||
void ProxyModel::setFileNameFilter(const QString &pattern)
|
||||
{
|
||||
m_pattern = pattern;
|
||||
m_patternMatchAll = (pattern == "*");
|
||||
|
||||
const QStringList patterns = pattern.split(' ');
|
||||
m_regExps.clear();
|
||||
|
||||
foreach (const QString &pattern, patterns) {
|
||||
QRegExp rx(pattern);
|
||||
rx.setPatternSyntax(QRegExp::Wildcard);
|
||||
rx.setCaseSensitivity(Qt::CaseInsensitive);
|
||||
m_regExps.append(rx);
|
||||
}
|
||||
}
|
||||
|
||||
QString ProxyModel::fileNameFilter() const
|
||||
{
|
||||
return m_pattern;
|
||||
}
|
||||
|
||||
void ProxyModel::setSortDirectoriesFirst(bool enable)
|
||||
{
|
||||
m_sortDirsFirst = enable;
|
||||
}
|
||||
|
||||
bool ProxyModel::sortDirectoriesFirst() const
|
||||
{
|
||||
return m_sortDirsFirst;
|
||||
}
|
||||
|
||||
void ProxyModel::setParseDesktopFiles(bool enable)
|
||||
{
|
||||
m_parseDesktopFiles = enable;
|
||||
}
|
||||
|
||||
bool ProxyModel::parseDesktopFiles() const
|
||||
{
|
||||
return m_parseDesktopFiles;
|
||||
}
|
||||
|
||||
QModelIndex ProxyModel::indexForUrl(const KUrl &url) const
|
||||
{
|
||||
const KDirModel *dirModel = static_cast<KDirModel*>(sourceModel());
|
||||
return mapFromSource(dirModel->indexForUrl(url));
|
||||
}
|
||||
|
||||
KFileItem ProxyModel::itemForIndex(const QModelIndex &index) const
|
||||
{
|
||||
const KDirModel *dirModel = static_cast<KDirModel*>(sourceModel());
|
||||
return dirModel->itemForIndex(mapToSource(index));
|
||||
}
|
||||
|
||||
bool ProxyModel::isDir(const QModelIndex &index, const KDirModel *dirModel) const
|
||||
{
|
||||
KFileItem item = dirModel->itemForIndex(index);
|
||||
if (item.isDir()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_parseDesktopFiles && item.isDesktopFile()) {
|
||||
// Check if the desktop file is a link to a directory
|
||||
KDesktopFile file(item.targetUrl().path());
|
||||
if (file.readType() == "Link") {
|
||||
const KUrl url(file.readUrl());
|
||||
if (url.isLocalFile()) {
|
||||
KDE_struct_stat buf;
|
||||
const QString path = url.toLocalFile(KUrl::RemoveTrailingSlash);
|
||||
if (KDE::stat(path, &buf) == 0) {
|
||||
return S_ISDIR(buf.st_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#include <KDebug>
|
||||
bool ProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||
{
|
||||
const KDirModel *dirModel = static_cast<KDirModel*>(sourceModel());
|
||||
|
||||
// When sorting by size, folders are compared using the number of items in them,
|
||||
// so they need to be given precedence over regular files as the comparison criteria is different
|
||||
if (m_sortDirsFirst || left.column() == KDirModel::Size) {
|
||||
bool leftIsDir = isDir(left, dirModel);
|
||||
bool rightIsDir = isDir(right, dirModel);
|
||||
if (leftIsDir && !rightIsDir) {
|
||||
return (sortOrder() == Qt::AscendingOrder); // folders > files independent of the sorting order
|
||||
}
|
||||
if (!leftIsDir && rightIsDir) {
|
||||
return (sortOrder() == Qt::DescendingOrder); // same here
|
||||
}
|
||||
}
|
||||
|
||||
const KFileItem leftItem = dirModel->data(left, KDirModel::FileItemRole).value<KFileItem>();
|
||||
const KFileItem rightItem = dirModel->data(right, KDirModel::FileItemRole).value<KFileItem>();
|
||||
const int column = left.column();
|
||||
int result = 0;
|
||||
|
||||
switch (column) {
|
||||
case KDirModel::Name:
|
||||
// fall through to the naturalCompare call
|
||||
break;
|
||||
case KDirModel::ModifiedTime: {
|
||||
const KDateTime leftTime = leftItem.time(KFileItem::ModificationTime);
|
||||
const KDateTime rightTime = rightItem.time(KFileItem::ModificationTime);
|
||||
if (leftTime < rightTime)
|
||||
result = -1;
|
||||
else if (leftTime > rightTime)
|
||||
result = +1;
|
||||
break;
|
||||
}
|
||||
case KDirModel::Size: {
|
||||
if (isDir(left, dirModel) && isDir(right, dirModel)) {
|
||||
const int leftChildCount = dirModel->data(left, KDirModel::ChildCountRole).toInt();
|
||||
const int rightChildCount = dirModel->data(right, KDirModel::ChildCountRole).toInt();
|
||||
if (leftChildCount < rightChildCount)
|
||||
result = -1;
|
||||
else if (leftChildCount > rightChildCount)
|
||||
result = +1;
|
||||
} else {
|
||||
const KIO::filesize_t leftSize = leftItem.size();
|
||||
const KIO::filesize_t rightSize = rightItem.size();
|
||||
if (leftSize < rightSize)
|
||||
result = -1;
|
||||
else if (leftSize > rightSize)
|
||||
result = +1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KDirModel::Type:
|
||||
// add other sorting modes here
|
||||
// KDirModel::data(index, Qt::DisplayRole) returns the data in index.column()
|
||||
result = QString::compare(dirModel->data(left, Qt::DisplayRole).toString(),
|
||||
dirModel->data(right, Qt::DisplayRole).toString());
|
||||
break;
|
||||
}
|
||||
|
||||
if (result != 0)
|
||||
return result < 0;
|
||||
|
||||
// The following code is taken from dolphin/src/kfileitemmodel.cpp
|
||||
// and ensures that the sorting order is always determined
|
||||
// Copyright (C) 2011 by Peter Penz <peter.penz91@gmail.com>
|
||||
result = KStringHandler::naturalCompare(leftItem.text(), rightItem.text(), Qt::CaseSensitive);
|
||||
|
||||
if (result != 0)
|
||||
return result < 0;
|
||||
|
||||
result = KStringHandler::naturalCompare(leftItem.name(), rightItem.name(), Qt::CaseSensitive);
|
||||
|
||||
if (result != 0)
|
||||
return result < 0;
|
||||
|
||||
return QString::compare(leftItem.url().url(), rightItem.url().url(), Qt::CaseSensitive);
|
||||
}
|
||||
|
||||
inline bool ProxyModel::matchMimeType(const KFileItem &item) const
|
||||
{
|
||||
if (m_mimeSet.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString mimeType = item.determineMimeType()->name();
|
||||
return m_mimeSet.contains(mimeType);
|
||||
}
|
||||
|
||||
inline bool ProxyModel::matchPattern(const KFileItem &item) const
|
||||
{
|
||||
if (m_patternMatchAll) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const QString name = item.name();
|
||||
QListIterator<QRegExp> i(m_regExps);
|
||||
while (i.hasNext()) {
|
||||
if (i.next().exactMatch(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
||||
{
|
||||
if (m_filterMode == NoFilter) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const KDirModel *dirModel = static_cast<KDirModel*>(sourceModel());
|
||||
const KFileItem item = dirModel->itemForIndex(dirModel->index(sourceRow, KDirModel::Name, sourceParent));
|
||||
|
||||
if (m_filterMode == FilterShowMatches) {
|
||||
return (matchPattern(item) && matchMimeType(item));
|
||||
} else {
|
||||
return !(matchPattern(item) && matchMimeType(item));
|
||||
}
|
||||
}
|
||||
|
79
plasma/desktop/applets/folderview/proxymodel.h
Normal file
79
plasma/desktop/applets/folderview/proxymodel.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright © 2008 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef PROXYMODEL_H
|
||||
#define PROXYMODEL_H
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QStringList>
|
||||
#include <QSet>
|
||||
#include <QRegExp>
|
||||
|
||||
class KDirModel;
|
||||
class KFileItem;
|
||||
class KUrl;
|
||||
|
||||
class ProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
public:
|
||||
enum FilterMode {
|
||||
NoFilter = 0,
|
||||
FilterShowMatches,
|
||||
FilterHideMatches
|
||||
};
|
||||
|
||||
ProxyModel(QObject *parent = 0);
|
||||
~ProxyModel();
|
||||
|
||||
void setFilterMode(FilterMode filterMode);
|
||||
FilterMode filterMode() const;
|
||||
|
||||
void setMimeTypeFilterList(const QStringList &mimeList);
|
||||
QStringList mimeTypeFilterList() const;
|
||||
|
||||
void setFileNameFilter(const QString &pattern);
|
||||
QString fileNameFilter() const;
|
||||
|
||||
void setSortDirectoriesFirst(bool enable);
|
||||
bool sortDirectoriesFirst() const;
|
||||
|
||||
void setParseDesktopFiles(bool enable);
|
||||
bool parseDesktopFiles() const;
|
||||
|
||||
QModelIndex indexForUrl(const KUrl &url) const;
|
||||
KFileItem itemForIndex(const QModelIndex &index) const;
|
||||
bool isDir(const QModelIndex &index, const KDirModel *dirModel) const;
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
|
||||
bool matchMimeType(const KFileItem &item) const;
|
||||
bool matchPattern(const KFileItem &item) const;
|
||||
|
||||
private:
|
||||
FilterMode m_filterMode;
|
||||
QSet<QString> m_mimeSet;
|
||||
QList<QRegExp> m_regExps;
|
||||
QString m_pattern;
|
||||
bool m_sortDirsFirst;
|
||||
bool m_parseDesktopFiles;
|
||||
bool m_patternMatchAll;
|
||||
};
|
||||
|
||||
#endif
|
101
plasma/desktop/applets/folderview/style.cpp
Normal file
101
plasma/desktop/applets/folderview/style.cpp
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright © 2008, 2009 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "style.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QStyleOption>
|
||||
|
||||
#include <plasma/framesvg.h>
|
||||
|
||||
FolderViewStyle::FolderViewStyle()
|
||||
: QCommonStyle()
|
||||
{
|
||||
m_frame = new Plasma::FrameSvg(this);
|
||||
m_frame->setImagePath("widgets/viewitem");
|
||||
m_frame->setCacheAllRenderedFrames(true);
|
||||
m_frame->setElementPrefix("normal");
|
||||
}
|
||||
|
||||
FolderViewStyle::~FolderViewStyle()
|
||||
{
|
||||
}
|
||||
|
||||
void FolderViewStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
|
||||
QPainter *painter, const QWidget *widget) const
|
||||
{
|
||||
switch (element)
|
||||
{
|
||||
case PE_PanelItemViewItem:
|
||||
{
|
||||
const bool hover = (option->state & State_MouseOver);
|
||||
const bool selected = (option->state & State_Selected);
|
||||
|
||||
if (selected && hover) {
|
||||
m_frame->setElementPrefix("selected+hover");
|
||||
} else if (selected) {
|
||||
m_frame->setElementPrefix("selected");
|
||||
} else if (hover) {
|
||||
m_frame->setElementPrefix("hover");
|
||||
} else {
|
||||
m_frame->setElementPrefix("normal");
|
||||
}
|
||||
|
||||
if (selected || hover) {
|
||||
m_frame->resizeFrame(option->rect.size());
|
||||
m_frame->paintFrame(painter, option->rect.topLeft());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PE_FrameFocusRect:
|
||||
{
|
||||
//QColor color = option->palette.color(QPalette::Text);
|
||||
QColor color = Qt::white;
|
||||
color.setAlphaF(.33);
|
||||
|
||||
QColor transparent = color;
|
||||
transparent.setAlphaF(0);
|
||||
|
||||
QLinearGradient g1(0, option->rect.top(), 0, option->rect.bottom());
|
||||
g1.setColorAt(0, color);
|
||||
g1.setColorAt(1, transparent);
|
||||
|
||||
QLinearGradient g2(option->rect.left(), 0, option->rect.right(), 0);
|
||||
g2.setColorAt(0, transparent);
|
||||
g2.setColorAt(.5, color);
|
||||
g2.setColorAt(1, transparent);
|
||||
|
||||
painter->save();
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
painter->setPen(QPen(g1, 0));
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->drawRoundedRect(QRectF(option->rect).adjusted(.5, .5, -.5, -.5), 2, 2);
|
||||
painter->setPen(QPen(g2, 0));
|
||||
painter->drawLine(QLineF(option->rect.left() + 2, option->rect.bottom() + .5,
|
||||
option->rect.right() - 2, option->rect.bottom() + .5));
|
||||
painter->restore();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return QCommonStyle::drawPrimitive(element, option, painter, widget);
|
||||
}
|
||||
}
|
||||
|
44
plasma/desktop/applets/folderview/style.h
Normal file
44
plasma/desktop/applets/folderview/style.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright © 2008 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef STYLE_H
|
||||
#define STYLE_H
|
||||
|
||||
#include <QCommonStyle>
|
||||
|
||||
namespace Plasma {
|
||||
class FrameSvg;
|
||||
}
|
||||
|
||||
|
||||
// This widget style is used to draw the view item backgrounds
|
||||
class FolderViewStyle : public QCommonStyle
|
||||
{
|
||||
public:
|
||||
FolderViewStyle();
|
||||
~FolderViewStyle();
|
||||
|
||||
void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
|
||||
|
||||
private:
|
||||
mutable Plasma::FrameSvg *m_frame;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
308
plasma/desktop/applets/folderview/tooltipwidget.cpp
Normal file
308
plasma/desktop/applets/folderview/tooltipwidget.cpp
Normal file
|
@ -0,0 +1,308 @@
|
|||
/*
|
||||
* Copyright © 2009 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "tooltipwidget.h"
|
||||
#include "abstractitemview.h"
|
||||
#include "proxymodel.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QGraphicsSceneHoverEvent>
|
||||
#include <QModelIndex>
|
||||
|
||||
#include <KDesktopFile>
|
||||
#include <KDirModel>
|
||||
#include <KLocale>
|
||||
#include <KIO/PreviewJob>
|
||||
|
||||
#include <Plasma/ToolTipManager>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
|
||||
ToolTipWidget::ToolTipWidget(AbstractItemView *parent)
|
||||
: QGraphicsWidget(parent), m_view(parent), m_previewJob(0)
|
||||
{
|
||||
Plasma::ToolTipManager::self()->registerWidget(this);
|
||||
}
|
||||
|
||||
void ToolTipWidget::updateToolTip(const QModelIndex &index, const QRectF &rect)
|
||||
{
|
||||
if (!index.isValid()) {
|
||||
// Send a fake hover leave event to the widget to trick the tooltip
|
||||
// manager into doing a delayed hide.
|
||||
QGraphicsSceneHoverEvent event(QEvent::GraphicsSceneHoverLeave);
|
||||
QApplication::sendEvent(this, &event);
|
||||
|
||||
m_preview = QPixmap();
|
||||
m_item = KFileItem();
|
||||
m_index = QModelIndex();
|
||||
return;
|
||||
}
|
||||
|
||||
setGeometry(rect);
|
||||
m_item = static_cast<ProxyModel*>(m_view->model())->itemForIndex(index);
|
||||
m_index = index;
|
||||
m_preview = QPixmap();
|
||||
|
||||
// If a preview job is still running (from a previously hovered item),
|
||||
// wait 200 ms before starting a new one. This is done to throttle
|
||||
// the number of preview jobs that are started when the user moves
|
||||
// the cursor over the icon view.
|
||||
if (m_previewJob) {
|
||||
m_previewTimer.start(200, this);
|
||||
} else {
|
||||
if (m_previewTimer.isActive()) {
|
||||
m_previewTimer.stop();
|
||||
}
|
||||
startPreviewJob();
|
||||
}
|
||||
|
||||
Plasma::ToolTipManager::self()->show(this);
|
||||
}
|
||||
|
||||
static qreal convertToReal(const QString &string)
|
||||
{
|
||||
const int pos = string.indexOf('/');
|
||||
if (pos != -1) {
|
||||
const int left = string.left(pos).toInt();
|
||||
const int right = string.mid(pos + 1).toInt();
|
||||
return right > 0 ? qreal(left) / qreal(right) : 0.0;
|
||||
}
|
||||
|
||||
return qreal(string.toInt());
|
||||
}
|
||||
|
||||
QString ToolTipWidget::metaInfo() const
|
||||
{
|
||||
const QString mimetype = m_item.mimetype();
|
||||
if (!mimetype.startsWith(QLatin1String("audio/")) &&
|
||||
!mimetype.startsWith(QLatin1String("image/")) &&
|
||||
!m_item.mimeTypePtr()->is("application/vnd.oasis.opendocument.text"))
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
KFileMetaInfo info = m_item.metaInfo(true, KFileMetaInfo::TechnicalInfo | KFileMetaInfo::ContentInfo);
|
||||
QString text;
|
||||
|
||||
if (mimetype.startsWith(QLatin1String("audio/"))) {
|
||||
// ### Disabled because the strigi ID3 analyzer is broken
|
||||
#if 0
|
||||
const QString title = info.item("http://www.semanticdesktop.org/ontologies/2007/01/19/nie#title").value().toString();
|
||||
const QString artist = info.item("http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#performer").value().toString();
|
||||
const QString album = info.item("http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#musicAlbum").value().toString();
|
||||
|
||||
if (!artist.isEmpty() || !title.isEmpty() || !album.isEmpty()) {
|
||||
text += "<p><table border='0' cellspacing='0' cellpadding='0'>";
|
||||
if (!artist.isEmpty()) {
|
||||
text += QString("<tr><td>") + i18nc("Music", "Artist:") + QString(" </td><td>") + artist + QString("</td></tr>");
|
||||
}
|
||||
if (!title.isEmpty()) {
|
||||
text += QString("<tr><td>") + i18nc("Music", "Title:") + QString(" </td><td>") + title + QString("</td></tr>");
|
||||
}
|
||||
if (!album.isEmpty()) {
|
||||
text += QString("<tr><td>") + i18nc("Music", "Album:") + QString(" </td><td>") + album + QString("</td></tr>");
|
||||
}
|
||||
text += "</table>";
|
||||
}
|
||||
#endif
|
||||
} else if (mimetype.startsWith(QLatin1String("image/"))) {
|
||||
int width = info.item("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#width").value().toInt();
|
||||
int height = info.item("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#height").value().toInt();
|
||||
const QString camera = info.item("http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#model").value().toString();
|
||||
const QString type = info.item("http://www.w3.org/1999/02/22-rdf-syntax-ns#type").value().toString();
|
||||
QString exposureTime = info.item("http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#exposureTime").value().toString();
|
||||
QString focalLength = info.item("http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#focalLength").value().toString();
|
||||
QString focal35mm = info.item("http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#focalLengthIn35mmFilm").value().toString();
|
||||
QString aperture = info.item("http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#apertureValue").value().toString();
|
||||
QString iso = info.item("http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#isoSpeedRatings").value().toString();
|
||||
QString created = info.item("http://www.semanticdesktop.org/ontologies/2007/01/19/nie#contentCreated").value().toString();
|
||||
|
||||
text += "<p><table border='0' cellspacing='0' cellpadding='0'>";
|
||||
if (width > 0 && height > 0) {
|
||||
QString size = QString::number(width) + 'x' + QString::number(height);
|
||||
// Add the megapixel count for photos
|
||||
if (type == "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#Photo") {
|
||||
const qreal pixels = qreal(width * height) / 1e6;
|
||||
size += QString(" (") + ki18n("%1 MPixels").subs(pixels, 0, 'f', 1).toString() + QString(")");
|
||||
}
|
||||
text += QString("<tr><td>") + i18n("Size:") + QString(" </td><td>") + size + QString("</td></tr>");
|
||||
}
|
||||
if (!camera.isEmpty()) {
|
||||
text += QString("<tr><td>") + i18n("Camera:") + QString(" </td><td>") + camera + QString("</td></tr>");
|
||||
}
|
||||
if (!focalLength.isEmpty()) {
|
||||
const qreal length = convertToReal(focalLength);
|
||||
focalLength = i18nc("Length in millimeters", "%1 mm", qRound(length));
|
||||
if (!focal35mm.isEmpty()) {
|
||||
const qreal length = convertToReal(focal35mm);
|
||||
focalLength += QString(" (") + i18nc("In photography", "35 mm equivalent: %1 mm", qRound(length)) + QString(")");
|
||||
}
|
||||
text += QString("<tr><td>") + i18nc("On a camera", "Focal Length:") +
|
||||
QString(" </td><td>") + focalLength + QString("</td></tr>");
|
||||
}
|
||||
if (!exposureTime.isEmpty()) {
|
||||
const qreal time = convertToReal(exposureTime);
|
||||
if (time < 1.0) {
|
||||
exposureTime = QString("1/") + QString::number(qRound((1.0 / time)));
|
||||
} else {
|
||||
exposureTime = QString::number(time, 'f', 1);
|
||||
}
|
||||
text += QString("<tr><td>") + i18nc("On a camera", "Exposure Time:") + QString(" </td><td>") +
|
||||
i18nc("Fraction of a second, or number of seconds", "%1 s", exposureTime) + QString("</td></tr>");
|
||||
}
|
||||
if (!aperture.isEmpty()) {
|
||||
// Convert the APEX value to the F number
|
||||
const qreal fnumber = std::sqrt(std::pow(2, convertToReal(aperture)));
|
||||
aperture = QString("f/") + QString::number(fnumber, 'f', 1);
|
||||
if (aperture.endsWith(QLatin1String(".0"))) {
|
||||
aperture = aperture.left(aperture.length() - 2);
|
||||
}
|
||||
text += QString("<tr><td>") + i18nc("On a camera", "Aperture:") +
|
||||
QString(" </td><td>") + aperture + QString("</td></tr>");
|
||||
}
|
||||
if (!iso.isEmpty()) {
|
||||
text += QString("<tr><td>") + i18nc("On a camera", "ISO Speed:") +
|
||||
QString(" </td><td>") + iso + QString("</td></tr>");
|
||||
}
|
||||
if (!created.isEmpty()) {
|
||||
const QDateTime dateTime = QDateTime::fromString(created, "yyyy:MM:dd HH:mm:ss");
|
||||
text += QString("<tr><td>") + i18n("Time:") + QString(" </td><td>") +
|
||||
KGlobal::locale()->formatDateTime(dateTime, KLocale::ShortDate, true) + QString("</td></tr>");
|
||||
}
|
||||
text += "</table>";
|
||||
} else if (m_item.mimeTypePtr()->is("application/vnd.oasis.opendocument.text")) {
|
||||
int wordCount = info.item("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#wordCount").value().toInt();
|
||||
int pageCount = info.item("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#pageCount").value().toInt();
|
||||
|
||||
const QString str1 = i18ncp("Inserted as %1 in the message below.", "1 page", "%1 pages", pageCount);
|
||||
const QString str2 = i18ncp("Inserted as %2 in the message below.", "1 word", "%1 words", wordCount);
|
||||
if (pageCount > 0) {
|
||||
text += QString("<p>") + i18nc("%1 and %2 are the messages translated above.", "%1, %2.", str1, str2);
|
||||
}
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
void ToolTipWidget::setContent()
|
||||
{
|
||||
Plasma::ToolTipContent content;
|
||||
content.setMainText(m_index.data(Qt::DisplayRole).toString());
|
||||
|
||||
if (m_preview.isNull()) {
|
||||
content.setImage(qvariant_cast<QIcon>(m_index.data(Qt::DecorationRole)));
|
||||
} else {
|
||||
content.setImage(m_preview);
|
||||
}
|
||||
|
||||
QString subText;
|
||||
|
||||
if (m_item.isDesktopFile()) {
|
||||
// Add the comment in the .desktop file to the subtext.
|
||||
// Note that we don't include the mime type for .desktop files,
|
||||
// since users will likely be confused about what will happen when
|
||||
// they click a "Desktop configuration file" on their desktop.
|
||||
KDesktopFile file(m_item.localPath());
|
||||
subText = file.readComment();
|
||||
} else {
|
||||
if (m_item.isMimeTypeKnown()) {
|
||||
subText = m_item.mimeComment();
|
||||
}
|
||||
|
||||
if (m_item.isDir()) {
|
||||
// Include information about the number of files and folders in the directory.
|
||||
const QVariant value = m_index.data(KDirModel::ChildCountRole);
|
||||
const int count = value.type() == QVariant::Int ? value.toInt() : KDirModel::ChildCountUnknown;
|
||||
|
||||
if (count != KDirModel::ChildCountUnknown) {
|
||||
subText += QString("<br>") + i18ncp("Items in a folder", "1 item", "%1 items", count);
|
||||
}
|
||||
} else {
|
||||
// File size
|
||||
if (m_item.isFile()) {
|
||||
subText += QString("<br>") + KGlobal::locale()->formatByteSize(m_item.size());
|
||||
}
|
||||
|
||||
// Add meta info from the strigi analyzers
|
||||
subText += metaInfo();
|
||||
}
|
||||
}
|
||||
|
||||
content.setSubText(subText);
|
||||
content.setAutohide(false);
|
||||
|
||||
Plasma::ToolTipManager::self()->setContent(this, content);
|
||||
}
|
||||
|
||||
void ToolTipWidget::startPreviewJob()
|
||||
{
|
||||
QStringList plugins;
|
||||
plugins << "imagethumbnail" << "jpegthumbnail";
|
||||
|
||||
m_previewJob = KIO::filePreview(KFileItemList() << m_item, QSize(256, 256), &plugins);
|
||||
connect(m_previewJob, SIGNAL(gotPreview(KFileItem,QPixmap)), SLOT(gotPreview(KFileItem,QPixmap)));
|
||||
connect(m_previewJob, SIGNAL(finished(KJob*)), SLOT(previewJobFinished(KJob*)));
|
||||
}
|
||||
|
||||
void ToolTipWidget::gotPreview(const KFileItem &item, const QPixmap &pixmap)
|
||||
{
|
||||
if (item == m_item) {
|
||||
m_preview = pixmap;
|
||||
setContent();
|
||||
} else if (m_item.isNull()) {
|
||||
m_preview = QPixmap();
|
||||
}
|
||||
}
|
||||
|
||||
void ToolTipWidget::previewJobFinished(KJob *job)
|
||||
{
|
||||
if (job == m_previewJob) {
|
||||
m_previewJob = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ToolTipWidget::toolTipAboutToShow()
|
||||
{
|
||||
if (m_index.isValid()) {
|
||||
setContent();
|
||||
m_hideTimer.start(10000, this);
|
||||
} else {
|
||||
Plasma::ToolTipManager::self()->clearContent(this);
|
||||
}
|
||||
}
|
||||
|
||||
void ToolTipWidget::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
if (event->timerId() == m_previewTimer.timerId()) {
|
||||
m_previewTimer.stop();
|
||||
|
||||
if (m_index.isValid()) {
|
||||
startPreviewJob();
|
||||
}
|
||||
}
|
||||
|
||||
if (event->timerId() == m_hideTimer.timerId()) {
|
||||
m_hideTimer.stop();
|
||||
Plasma::ToolTipManager::self()->hide(this);
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_tooltipwidget.cpp"
|
||||
|
76
plasma/desktop/applets/folderview/tooltipwidget.h
Normal file
76
plasma/desktop/applets/folderview/tooltipwidget.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright © 2009 Fredrik Höglund <fredrik@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TOOLTIPWIDGET_H
|
||||
#define TOOLTIPWIDGET_H
|
||||
|
||||
#include <QModelIndex>
|
||||
#include <QBasicTimer>
|
||||
#include <QGraphicsWidget>
|
||||
#include <KFileItem>
|
||||
#include <QPixmap>
|
||||
|
||||
namespace KIO {
|
||||
class PreviewJob;
|
||||
}
|
||||
|
||||
class QModelIndex;
|
||||
class AbstractItemView;
|
||||
|
||||
/**
|
||||
* This widget registers with the plasma tooltip manager, and is moved around
|
||||
* in the view and resized to the size of the hovered item, so that the tooltip
|
||||
* will be positioned correctly when it's shown.
|
||||
*
|
||||
* It is also responsible for starting preview jobs and updating the the tooltip
|
||||
* contents when a preview has been generated.
|
||||
*
|
||||
* While the widget is created as a child widget of the view, it is always hidden.
|
||||
*/
|
||||
class ToolTipWidget : public QGraphicsWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ToolTipWidget(AbstractItemView *parent);
|
||||
void updateToolTip(const QModelIndex &index, const QRectF &rect);
|
||||
|
||||
private:
|
||||
QString metaInfo() const;
|
||||
void setContent();
|
||||
void startPreviewJob();
|
||||
void timerEvent(QTimerEvent *);
|
||||
|
||||
private slots:
|
||||
void gotPreview(const KFileItem &item, const QPixmap &pixmap);
|
||||
void previewJobFinished(KJob *job);
|
||||
void toolTipAboutToShow();
|
||||
|
||||
private:
|
||||
AbstractItemView * const m_view;
|
||||
KIO::PreviewJob *m_previewJob;
|
||||
KFileItem m_item;
|
||||
QModelIndex m_index;
|
||||
QPixmap m_preview;
|
||||
QBasicTimer m_previewTimer;
|
||||
QBasicTimer m_hideTimer;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Add table
Reference in a new issue