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 namespace KDEPrivate 00038 { 00039 00040 KUrlNavigatorPlacesSelector::KUrlNavigatorPlacesSelector(QWidget* parent, KFilePlacesModel* placesModel) : 00041 KUrlNavigatorButtonBase(parent), 00042 m_selectedItem(-1), 00043 m_placesModel(placesModel) 00044 { 00045 setFocusPolicy(Qt::NoFocus); 00046 00047 m_placesMenu = new KMenu(this); 00048 00049 updateMenu(); 00050 00051 connect(m_placesModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)), 00052 this, SLOT(updateMenu())); 00053 connect(m_placesModel, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), 00054 this, SLOT(updateMenu())); 00055 connect(m_placesModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), 00056 this, SLOT(updateMenu())); 00057 connect(m_placesMenu, SIGNAL(triggered(QAction*)), 00058 this, SLOT(activatePlace(QAction*))); 00059 00060 setMenu(m_placesMenu); 00061 00062 setAcceptDrops(true); 00063 } 00064 00065 KUrlNavigatorPlacesSelector::~KUrlNavigatorPlacesSelector() 00066 { 00067 } 00068 00069 void KUrlNavigatorPlacesSelector::updateMenu() 00070 { 00071 m_placesMenu->clear(); 00072 00073 updateSelection(m_selectedUrl); 00074 const int rowCount = m_placesModel->rowCount(); 00075 for (int i = 0; i < rowCount; ++i) { 00076 QModelIndex index = m_placesModel->index(i, 0); 00077 QAction* action = new QAction(m_placesModel->icon(index), 00078 m_placesModel->text(index), 00079 m_placesMenu); 00080 m_placesMenu->addAction(action); 00081 action->setData(i); 00082 if (i == m_selectedItem) { 00083 setIcon(m_placesModel->icon(index)); 00084 } 00085 } 00086 00087 updateTeardownAction(); 00088 } 00089 00090 void KUrlNavigatorPlacesSelector::updateTeardownAction() 00091 { 00092 const int rowCount = m_placesModel->rowCount(); 00093 if (m_placesMenu->actions().size()==rowCount+2) { 00094 // remove teardown action 00095 QAction *action = m_placesMenu->actions().at(rowCount+1); 00096 m_placesMenu->removeAction(action); 00097 delete action; 00098 00099 // remove separator 00100 action = m_placesMenu->actions().at(rowCount); 00101 m_placesMenu->removeAction(action); 00102 delete action; 00103 } 00104 00105 const QModelIndex index = m_placesModel->index(m_selectedItem, 0); 00106 QAction *teardown = m_placesModel->teardownActionForIndex(index); 00107 if (teardown!=0) { 00108 teardown->setParent(m_placesMenu); 00109 teardown->setData("teardownAction"); 00110 00111 m_placesMenu->addSeparator(); 00112 m_placesMenu->addAction(teardown); 00113 } 00114 } 00115 00116 void KUrlNavigatorPlacesSelector::updateSelection(const KUrl& url) 00117 { 00118 const QModelIndex index = m_placesModel->closestItem(url); 00119 if (index.isValid()) { 00120 m_selectedItem = index.row(); 00121 m_selectedUrl = url; 00122 setIcon(m_placesModel->icon(index)); 00123 } else { 00124 m_selectedItem = -1; 00125 // No bookmark has been found which matches to the given Url. Show 00126 // a generic folder icon as pixmap for indication: 00127 setIcon(KIcon("folder")); 00128 } 00129 updateTeardownAction(); 00130 } 00131 00132 KUrl KUrlNavigatorPlacesSelector::selectedPlaceUrl() const 00133 { 00134 const QModelIndex index = m_placesModel->index(m_selectedItem, 0); 00135 return index.isValid() ? m_placesModel->url(index) : KUrl(); 00136 } 00137 00138 QString KUrlNavigatorPlacesSelector::selectedPlaceText() const 00139 { 00140 const QModelIndex index = m_placesModel->index(m_selectedItem, 0); 00141 return index.isValid() ? m_placesModel->text(index) : QString(); 00142 } 00143 00144 QSize KUrlNavigatorPlacesSelector::sizeHint() const 00145 { 00146 const int height = KUrlNavigatorButtonBase::sizeHint().height(); 00147 return QSize(height, height); 00148 } 00149 00150 void KUrlNavigatorPlacesSelector::paintEvent(QPaintEvent* event) 00151 { 00152 Q_UNUSED(event); 00153 QPainter painter(this); 00154 drawHoverBackground(&painter); 00155 00156 // draw icon 00157 const QPixmap pixmap = icon().pixmap(QSize(22, 22), QIcon::Normal); 00158 const int x = (width() - pixmap.width()) / 2; 00159 const int y = (height() - pixmap.height()) / 2; 00160 painter.drawPixmap(x, y, pixmap); 00161 } 00162 00163 void KUrlNavigatorPlacesSelector::dragEnterEvent(QDragEnterEvent* event) 00164 { 00165 if (event->mimeData()->hasUrls()) { 00166 setDisplayHintEnabled(DraggedHint, true); 00167 event->acceptProposedAction(); 00168 00169 update(); 00170 } 00171 } 00172 00173 void KUrlNavigatorPlacesSelector::dragLeaveEvent(QDragLeaveEvent* event) 00174 { 00175 KUrlNavigatorButtonBase::dragLeaveEvent(event); 00176 00177 setDisplayHintEnabled(DraggedHint, false); 00178 update(); 00179 } 00180 00181 void KUrlNavigatorPlacesSelector::dropEvent(QDropEvent* event) 00182 { 00183 setDisplayHintEnabled(DraggedHint, false); 00184 update(); 00185 00186 const KUrl::List urlList = KUrl::List::fromMimeData(event->mimeData()); 00187 if (urlList.isEmpty()) { 00188 return; 00189 } 00190 foreach(const KUrl &url, urlList) { 00191 KMimeType::Ptr mimetype = KMimeType::findByUrl(url); 00192 if (mimetype->is("inode/directory")) { 00193 m_placesModel->addPlace(url.fileName(), url); 00194 } 00195 } 00196 } 00197 00198 void KUrlNavigatorPlacesSelector::activatePlace(QAction* action) 00199 { 00200 Q_ASSERT(action != 0); 00201 if (action->data().toString()=="teardownAction") { 00202 QModelIndex index = m_placesModel->index(m_selectedItem, 0); 00203 m_placesModel->requestTeardown(index); 00204 return; 00205 } 00206 00207 QModelIndex index = m_placesModel->index(action->data().toInt(), 0); 00208 00209 m_lastClickedIndex = QPersistentModelIndex(); 00210 00211 if (m_placesModel->setupNeeded(index)) { 00212 connect(m_placesModel, SIGNAL(setupDone(const QModelIndex &, bool)), 00213 this, SLOT(onStorageSetupDone(const QModelIndex &, bool))); 00214 00215 m_lastClickedIndex = index; 00216 m_placesModel->requestSetup(index); 00217 return; 00218 } else if (index.isValid()) { 00219 m_selectedItem = index.row(); 00220 setIcon(m_placesModel->icon(index)); 00221 updateTeardownAction(); 00222 emit placeActivated(m_placesModel->url(index)); 00223 } 00224 } 00225 00226 void KUrlNavigatorPlacesSelector::onStorageSetupDone(const QModelIndex &index, bool success) 00227 { 00228 if (m_lastClickedIndex == index) { 00229 if (success) { 00230 m_selectedItem = index.row(); 00231 setIcon(m_placesModel->icon(index)); 00232 updateTeardownAction(); 00233 emit placeActivated(m_placesModel->url(index)); 00234 } 00235 m_lastClickedIndex = QPersistentModelIndex(); 00236 } 00237 } 00238 00239 } // namespace KDEPrivate 00240 00241 #include "kurlnavigatorplacesselector_p.moc" 00242
KDE 4.7 API Reference