KFile
kurlnavigatorplacesselector.cpp
Go to the documentation of this file.
00001 /*************************************************************************** 00002 * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) * 00003 * Copyright (C) 2007 by Kevin Ottens (ervin@kde.org) * 00004 * * 00005 * This library is free software; you can redistribute it and/or * 00006 * modify it under the terms of the GNU Lesser General Public * 00007 * License as published by the Free Software Foundation; either * 00008 * version 2 of the License, or (at your option) any later version. * 00009 * * 00010 * This library is distributed in the hope that it will be useful, * 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00013 * Lesser General Public License for more details. * 00014 * * 00015 * You should have received a copy of the GNU Lesser General Public * 00016 * License along with this library; if not, write to the * 00017 * Free Software Foundation, Inc., * 00018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * 00019 ***************************************************************************/ 00020 00021 #include "kurlnavigatorplacesselector_p.h" 00022 00023 #include <kiconloader.h> 00024 #include <kglobalsettings.h> 00025 #include <kfileplacesmodel.h> 00026 #include <kmenu.h> 00027 #include <kmimetype.h> 00028 #include <kdebug.h> 00029 00030 #include <QtGui/QDragEnterEvent> 00031 #include <QtGui/QDragLeaveEvent> 00032 #include <QtGui/QDropEvent> 00033 #include <QtGui/QPainter> 00034 #include <QtGui/QPixmap> 00035 #include <kicon.h> 00036 00037 KUrlNavigatorPlacesSelector::KUrlNavigatorPlacesSelector(QWidget* parent, KFilePlacesModel* placesModel) : 00038 KUrlNavigatorButtonBase(parent), 00039 m_selectedItem(-1), 00040 m_placesModel(placesModel) 00041 { 00042 setFocusPolicy(Qt::NoFocus); 00043 00044 m_placesMenu = new KMenu(this); 00045 00046 updateMenu(); 00047 00048 connect(m_placesModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)), 00049 this, SLOT(updateMenu())); 00050 connect(m_placesModel, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), 00051 this, SLOT(updateMenu())); 00052 connect(m_placesModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), 00053 this, SLOT(updateMenu())); 00054 connect(m_placesMenu, SIGNAL(triggered(QAction*)), 00055 this, SLOT(activatePlace(QAction*))); 00056 00057 setMenu(m_placesMenu); 00058 00059 setAcceptDrops(true); 00060 } 00061 00062 KUrlNavigatorPlacesSelector::~KUrlNavigatorPlacesSelector() 00063 { 00064 } 00065 00066 void KUrlNavigatorPlacesSelector::updateMenu() 00067 { 00068 m_placesMenu->clear(); 00069 00070 updateSelection(m_selectedUrl); 00071 const int rowCount = m_placesModel->rowCount(); 00072 for (int i = 0; i < rowCount; ++i) { 00073 QModelIndex index = m_placesModel->index(i, 0); 00074 QAction* action = new QAction(m_placesModel->icon(index), 00075 m_placesModel->text(index), 00076 m_placesMenu); 00077 m_placesMenu->addAction(action); 00078 action->setData(i); 00079 if (i == m_selectedItem) { 00080 setIcon(m_placesModel->icon(index)); 00081 } 00082 } 00083 00084 updateTeardownAction(); 00085 } 00086 00087 void KUrlNavigatorPlacesSelector::updateTeardownAction() 00088 { 00089 const int rowCount = m_placesModel->rowCount(); 00090 if (m_placesMenu->actions().size()==rowCount+2) { 00091 // remove teardown action 00092 QAction *action = m_placesMenu->actions().at(rowCount+1); 00093 m_placesMenu->removeAction(action); 00094 delete action; 00095 00096 // remove separator 00097 action = m_placesMenu->actions().at(rowCount); 00098 m_placesMenu->removeAction(action); 00099 delete action; 00100 } 00101 00102 const QModelIndex index = m_placesModel->index(m_selectedItem, 0); 00103 QAction *teardown = m_placesModel->teardownActionForIndex(index); 00104 if (teardown!=0) { 00105 teardown->setParent(m_placesMenu); 00106 teardown->setData("teardownAction"); 00107 00108 m_placesMenu->addSeparator(); 00109 m_placesMenu->addAction(teardown); 00110 } 00111 } 00112 00113 void KUrlNavigatorPlacesSelector::updateSelection(const KUrl& url) 00114 { 00115 const QModelIndex index = m_placesModel->closestItem(url); 00116 if (index.isValid()) { 00117 m_selectedItem = index.row(); 00118 m_selectedUrl = url; 00119 setIcon(m_placesModel->icon(index)); 00120 } 00121 else { 00122 m_selectedItem = -1; 00123 // No bookmark has been found which matches to the given Url. Show 00124 // a generic folder icon as pixmap for indication: 00125 setIcon(KIcon("folder")); 00126 } 00127 updateTeardownAction(); 00128 } 00129 00130 KUrl KUrlNavigatorPlacesSelector::selectedPlaceUrl() const 00131 { 00132 const QModelIndex index = m_placesModel->index(m_selectedItem, 0); 00133 return index.isValid() ? m_placesModel->url(index) : KUrl(); 00134 } 00135 00136 QString KUrlNavigatorPlacesSelector::selectedPlaceText() const 00137 { 00138 const QModelIndex index = m_placesModel->index(m_selectedItem, 0); 00139 return index.isValid() ? m_placesModel->text(index) : QString(); 00140 } 00141 00142 QSize KUrlNavigatorPlacesSelector::sizeHint() const 00143 { 00144 const int height = KUrlNavigatorButtonBase::sizeHint().height(); 00145 return QSize(height, height); 00146 } 00147 00148 void KUrlNavigatorPlacesSelector::paintEvent(QPaintEvent* event) 00149 { 00150 Q_UNUSED(event); 00151 QPainter painter(this); 00152 drawHoverBackground(&painter); 00153 00154 // draw icon 00155 const QPixmap pixmap = icon().pixmap(QSize(22, 22), QIcon::Normal); 00156 const int x = (width() - pixmap.width()) / 2; 00157 const int y = (height() - pixmap.height()) / 2; 00158 painter.drawPixmap(x, y, pixmap); 00159 } 00160 00161 void KUrlNavigatorPlacesSelector::dragEnterEvent(QDragEnterEvent* event) 00162 { 00163 if (event->mimeData()->hasUrls()) { 00164 setDisplayHintEnabled(DraggedHint, true); 00165 event->acceptProposedAction(); 00166 00167 update(); 00168 } 00169 } 00170 00171 void KUrlNavigatorPlacesSelector::dragLeaveEvent(QDragLeaveEvent* event) 00172 { 00173 KUrlNavigatorButtonBase::dragLeaveEvent(event); 00174 00175 setDisplayHintEnabled(DraggedHint, false); 00176 update(); 00177 } 00178 00179 void KUrlNavigatorPlacesSelector::dropEvent(QDropEvent* event) 00180 { 00181 setDisplayHintEnabled(DraggedHint, false); 00182 update(); 00183 00184 const KUrl::List urlList = KUrl::List::fromMimeData(event->mimeData()); 00185 if (urlList.isEmpty()) { 00186 return; 00187 } 00188 foreach(const KUrl &url, urlList) { 00189 KMimeType::Ptr mimetype = KMimeType::findByUrl(url); 00190 if (mimetype->is("inode/directory")) { 00191 m_placesModel->addPlace(url.fileName(), url); 00192 } 00193 } 00194 } 00195 00196 void KUrlNavigatorPlacesSelector::activatePlace(QAction* action) 00197 { 00198 Q_ASSERT(action != 0); 00199 if (action->data().toString()=="teardownAction") { 00200 QModelIndex index = m_placesModel->index(m_selectedItem, 0); 00201 m_placesModel->requestTeardown(index); 00202 return; 00203 } 00204 00205 QModelIndex index = m_placesModel->index(action->data().toInt(), 0); 00206 00207 m_lastClickedIndex = QPersistentModelIndex(); 00208 00209 if (m_placesModel->setupNeeded(index)) { 00210 connect(m_placesModel, SIGNAL(setupDone(const QModelIndex &, bool)), 00211 this, SLOT(onStorageSetupDone(const QModelIndex &, bool))); 00212 00213 m_lastClickedIndex = index; 00214 m_placesModel->requestSetup(index); 00215 return; 00216 } 00217 else if (index.isValid()) { 00218 m_selectedItem = index.row(); 00219 setIcon(m_placesModel->icon(index)); 00220 updateTeardownAction(); 00221 emit placeActivated(m_placesModel->url(index)); 00222 } 00223 } 00224 00225 void KUrlNavigatorPlacesSelector::onStorageSetupDone(const QModelIndex &index, bool success) 00226 { 00227 if (m_lastClickedIndex==index) { 00228 if (success) { 00229 m_selectedItem = index.row(); 00230 setIcon(m_placesModel->icon(index)); 00231 updateTeardownAction(); 00232 emit placeActivated(m_placesModel->url(index)); 00233 } 00234 m_lastClickedIndex = QPersistentModelIndex(); 00235 } 00236 } 00237 00238 #include "kurlnavigatorplacesselector_p.moc" 00239
KDE 4.6 API Reference