kdelibs/kfile/kurlnavigatorplacesselector.cpp

242 lines
7.8 KiB
C++

/***************************************************************************
* Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) *
* Copyright (C) 2007 by Kevin Ottens (ervin@kde.org) *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser 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 *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "kurlnavigatorplacesselector_p.h"
#include <kiconloader.h>
#include <kglobalsettings.h>
#include <kfileplacesmodel.h>
#include <kmenu.h>
#include <kmimetype.h>
#include <kdebug.h>
#include <QtGui/qevent.h>
#include <QtGui/qevent.h>
#include <QtGui/qevent.h>
#include <QtGui/QPainter>
#include <QtGui/QPixmap>
#include <kicon.h>
namespace KDEPrivate
{
KUrlNavigatorPlacesSelector::KUrlNavigatorPlacesSelector(QWidget* parent, KFilePlacesModel* placesModel) :
KUrlNavigatorButtonBase(parent),
m_selectedItem(-1),
m_placesModel(placesModel)
{
setFocusPolicy(Qt::NoFocus);
m_placesMenu = new KMenu(this);
updateMenu();
connect(m_placesModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(updateMenu()));
connect(m_placesModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(updateMenu()));
connect(m_placesModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
this, SLOT(updateMenu()));
connect(m_placesMenu, SIGNAL(triggered(QAction*)),
this, SLOT(activatePlace(QAction*)));
setMenu(m_placesMenu);
setAcceptDrops(true);
}
KUrlNavigatorPlacesSelector::~KUrlNavigatorPlacesSelector()
{
}
void KUrlNavigatorPlacesSelector::updateMenu()
{
m_placesMenu->clear();
updateSelection(m_selectedUrl);
const int rowCount = m_placesModel->rowCount();
for (int i = 0; i < rowCount; ++i) {
QModelIndex index = m_placesModel->index(i, 0);
QAction* action = new QAction(m_placesModel->icon(index),
m_placesModel->text(index),
m_placesMenu);
m_placesMenu->addAction(action);
action->setData(i);
if (i == m_selectedItem) {
setIcon(m_placesModel->icon(index));
}
}
updateTeardownAction();
}
void KUrlNavigatorPlacesSelector::updateTeardownAction()
{
const int rowCount = m_placesModel->rowCount();
if (m_placesMenu->actions().size()==rowCount+2) {
// remove teardown action
QAction *action = m_placesMenu->actions().at(rowCount+1);
m_placesMenu->removeAction(action);
delete action;
// remove separator
action = m_placesMenu->actions().at(rowCount);
m_placesMenu->removeAction(action);
delete action;
}
const QModelIndex index = m_placesModel->index(m_selectedItem, 0);
QAction *teardown = m_placesModel->teardownActionForIndex(index);
if (teardown!=0) {
teardown->setParent(m_placesMenu);
teardown->setData("teardownAction");
m_placesMenu->addSeparator();
m_placesMenu->addAction(teardown);
}
}
void KUrlNavigatorPlacesSelector::updateSelection(const KUrl& url)
{
const QModelIndex index = m_placesModel->closestItem(url);
if (index.isValid()) {
m_selectedItem = index.row();
m_selectedUrl = url;
setIcon(m_placesModel->icon(index));
} else {
m_selectedItem = -1;
// No bookmark has been found which matches to the given Url. Show
// a generic folder icon as pixmap for indication:
setIcon(KIcon("folder"));
}
updateTeardownAction();
}
KUrl KUrlNavigatorPlacesSelector::selectedPlaceUrl() const
{
const QModelIndex index = m_placesModel->index(m_selectedItem, 0);
return index.isValid() ? m_placesModel->url(index) : KUrl();
}
QString KUrlNavigatorPlacesSelector::selectedPlaceText() const
{
const QModelIndex index = m_placesModel->index(m_selectedItem, 0);
return index.isValid() ? m_placesModel->text(index) : QString();
}
QSize KUrlNavigatorPlacesSelector::sizeHint() const
{
const int height = KUrlNavigatorButtonBase::sizeHint().height();
return QSize(height, height);
}
void KUrlNavigatorPlacesSelector::paintEvent(QPaintEvent* event)
{
Q_UNUSED(event);
QPainter painter(this);
drawHoverBackground(&painter);
// draw icon
const QPixmap pixmap = icon().pixmap(QSize(22, 22).expandedTo(iconSize()), QIcon::Normal);
const int x = (width() - pixmap.width()) / 2;
const int y = (height() - pixmap.height()) / 2;
painter.drawPixmap(x, y, pixmap);
}
void KUrlNavigatorPlacesSelector::dragEnterEvent(QDragEnterEvent* event)
{
if (event->mimeData()->hasUrls()) {
setDisplayHintEnabled(DraggedHint, true);
event->acceptProposedAction();
update();
}
}
void KUrlNavigatorPlacesSelector::dragLeaveEvent(QDragLeaveEvent* event)
{
KUrlNavigatorButtonBase::dragLeaveEvent(event);
setDisplayHintEnabled(DraggedHint, false);
update();
}
void KUrlNavigatorPlacesSelector::dropEvent(QDropEvent* event)
{
setDisplayHintEnabled(DraggedHint, false);
update();
const KUrl::List urlList = KUrl::List::fromMimeData(event->mimeData());
if (urlList.isEmpty()) {
return;
}
foreach(const KUrl &url, urlList) {
KMimeType::Ptr mimetype = KMimeType::findByUrl(url);
if (mimetype->is("inode/directory")) {
m_placesModel->addPlace(url.fileName(), url);
}
}
}
void KUrlNavigatorPlacesSelector::activatePlace(QAction* action)
{
Q_ASSERT(action != 0);
if (action->data().toString()=="teardownAction") {
QModelIndex index = m_placesModel->index(m_selectedItem, 0);
m_placesModel->requestTeardown(index);
return;
}
QModelIndex index = m_placesModel->index(action->data().toInt(), 0);
m_lastClickedIndex = QPersistentModelIndex();
if (m_placesModel->setupNeeded(index)) {
connect(m_placesModel, SIGNAL(setupDone(QModelIndex,bool)),
this, SLOT(onStorageSetupDone(QModelIndex,bool)));
m_lastClickedIndex = index;
m_placesModel->requestSetup(index);
return;
} else if (index.isValid()) {
m_selectedItem = index.row();
setIcon(m_placesModel->icon(index));
updateTeardownAction();
emit placeActivated(m_placesModel->url(index));
}
}
void KUrlNavigatorPlacesSelector::onStorageSetupDone(const QModelIndex &index, bool success)
{
if (m_lastClickedIndex == index) {
if (success) {
m_selectedItem = index.row();
setIcon(m_placesModel->icon(index));
updateTeardownAction();
emit placeActivated(m_placesModel->url(index));
}
m_lastClickedIndex = QPersistentModelIndex();
}
}
} // namespace KDEPrivate
#include "moc_kurlnavigatorplacesselector_p.cpp"