Warning, file /office/calligra/libs/widgets/KoViewItemContextBar.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE project 0002 * 0003 * Copyright (C) 2008 Peter Penz <peter.penz19@gmail.com> 0004 * Copyright (C) 2011 Paul Mendez <paulestebanms@gmail.com> 0005 * 0006 * This library is free software; you can redistribute it and/or 0007 * modify it under the terms of the GNU Library General Public 0008 * License as published by the Free Software Foundation; either 0009 * version 2 of the License, or (at your option) any later version. 0010 * 0011 * This library is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 * Library General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU Library General Public License 0017 * along with this library; see the file COPYING.LIB. If not, write to 0018 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 * Boston, MA 02110-1301, USA. 0020 */ 0021 0022 #include "KoViewItemContextBar.h" 0023 0024 //Calligra headers 0025 #include "KoContextBarButton.h" 0026 #include <KoIcon.h> 0027 0028 // KF5 0029 #include <klocalizedstring.h> 0030 0031 //Qt Headers 0032 #include <QAbstractItemView> 0033 #include <QModelIndex> 0034 #include <QApplication> 0035 #include <QHBoxLayout> 0036 #include <QHoverEvent> 0037 0038 /** Space between the item outer rect and the context bar */ 0039 const int CONTEXTBAR_MARGIN = 4; 0040 const int MIN_BUTTON_WIDTH = 24; 0041 0042 KoViewItemContextBar::KoViewItemContextBar(QAbstractItemView *parent) 0043 : QObject(parent) 0044 , m_view(parent) 0045 , m_enabled(true) 0046 , m_showToggleButton(true) 0047 { 0048 connect(parent, SIGNAL(entered(QModelIndex)), 0049 this, SLOT(slotEntered(QModelIndex))); 0050 connect(parent, SIGNAL(viewportEntered()), 0051 this, SLOT(slotViewportEntered())); 0052 0053 m_ContextBar = new QWidget(m_view->viewport()); 0054 m_ContextBar->hide(); 0055 m_ToggleSelectionButton = new KoContextBarButton(koIconName("list-add")); 0056 0057 m_Layout = new QHBoxLayout(m_ContextBar); 0058 m_Layout->setMargin(2); 0059 m_Layout->setSpacing(2); 0060 m_Layout->addWidget(m_ToggleSelectionButton); 0061 0062 connect(m_ToggleSelectionButton, SIGNAL(clicked()), 0063 this, SLOT(setItemSelected())); 0064 // Hides context bar if item removed 0065 connect(m_view->model(), SIGNAL(rowsRemoved(QModelIndex,int,int)), 0066 this, SLOT(slotRowsRemoved(QModelIndex,int,int))); 0067 0068 connect(m_view->model(), SIGNAL(modelReset()), this, SLOT(slotModelReset())); 0069 0070 m_ContextBar->installEventFilter(this); 0071 m_view->viewport()->installEventFilter(this); 0072 m_view->setMouseTracking(true); 0073 } 0074 0075 bool KoViewItemContextBar::eventFilter(QObject *watched, QEvent *event) 0076 { 0077 if (watched == m_view->viewport()) { 0078 switch (event->type()) { 0079 case QEvent::Leave: 0080 if (m_ContextBar->isVisible()) { 0081 m_ContextBar->hide(); 0082 } 0083 break; 0084 default: 0085 break; 0086 } 0087 } 0088 return QObject::eventFilter(watched, event); 0089 } 0090 0091 void KoViewItemContextBar::slotEntered(const QModelIndex &index) 0092 { 0093 const bool isSelectionCandidate = index.isValid() && 0094 (QApplication::mouseButtons() == Qt::NoButton); 0095 0096 if (!m_ContextBar || !m_enabled) { 0097 return; 0098 } 0099 0100 m_ContextBar->hide(); 0101 if (isSelectionCandidate) { 0102 updateHoverUi(index); 0103 } 0104 else { 0105 updateHoverUi(QModelIndex()); 0106 } 0107 } 0108 0109 void KoViewItemContextBar::updateHoverUi(const QModelIndex &index) 0110 { 0111 QModelIndex oldIndex = m_IndexUnderCursor; 0112 m_IndexUnderCursor = index; 0113 m_view->update(oldIndex); 0114 0115 const bool isSelectionCandidate = index.isValid(); 0116 0117 m_ContextBar->hide(); 0118 if (isSelectionCandidate) { 0119 updateToggleSelectionButton(); 0120 const QRect rect = m_view->visualRect(m_IndexUnderCursor); 0121 showContextBar(rect); 0122 m_view->update(m_IndexUnderCursor); 0123 } else { 0124 m_ContextBar->hide(); 0125 } 0126 } 0127 0128 void KoViewItemContextBar::showContextBar(const QRect &rect) 0129 { 0130 // Center bar in FullContextBar mode, left align in 0131 // SelectionOnlyContextBar mode 0132 const int posX = 0; 0133 const int posY = CONTEXTBAR_MARGIN / 4; 0134 int numButtons = 0; 0135 m_ContextBar->move(rect.topLeft() + QPoint(posX, posY)); 0136 //Hide buttons if item is too small 0137 int width = m_ToggleSelectionButton->width(); 0138 if (!m_showToggleButton) { 0139 m_ToggleSelectionButton->setVisible(false); 0140 width = qMin(m_contextBarButtons.at(0)->width(), MIN_BUTTON_WIDTH); 0141 } 0142 for (int i=m_contextBarButtons.size()-1; i>=0; --i) { 0143 if ((rect.width() - 2 * CONTEXTBAR_MARGIN) > ((i + 1) * width)) { 0144 m_contextBarButtons.at(i)->setVisible(true); 0145 numButtons++; 0146 continue; 0147 } 0148 m_contextBarButtons.at(i)->setVisible(false); 0149 } 0150 m_ContextBar->adjustSize(); 0151 if (numButtons > 0) { 0152 const int centerX = (rect.width() - m_ContextBar->rect().width()) / 2; 0153 m_ContextBar->move(rect.topLeft() + QPoint(centerX, posY)); 0154 } 0155 m_ContextBar->show(); 0156 } 0157 0158 void KoViewItemContextBar::slotViewportEntered() 0159 { 0160 m_ContextBar->hide(); 0161 } 0162 0163 void KoViewItemContextBar::setItemSelected() 0164 { 0165 emit selectionChanged(); 0166 0167 if (m_IndexUnderCursor.isValid()) { 0168 QItemSelectionModel *selModel = m_view->selectionModel(); 0169 if (!selModel->isSelected(m_IndexUnderCursor)) { 0170 selModel->select(m_IndexUnderCursor, QItemSelectionModel::Select); 0171 } 0172 else { 0173 selModel->select(m_IndexUnderCursor, QItemSelectionModel::Deselect); 0174 } 0175 selModel->setCurrentIndex(m_IndexUnderCursor, QItemSelectionModel::Current); 0176 } 0177 updateHoverUi(m_IndexUnderCursor); 0178 } 0179 0180 void KoViewItemContextBar::slotRowsRemoved(const QModelIndex &parent, int start, int end) 0181 { 0182 Q_UNUSED(parent); 0183 Q_UNUSED(start); 0184 Q_UNUSED(end); 0185 if (m_ContextBar) { 0186 m_ContextBar->hide(); 0187 } 0188 } 0189 0190 void KoViewItemContextBar::updateToggleSelectionButton() 0191 { 0192 const bool isHoveredIndexSelected = m_view->selectionModel()->isSelected(m_IndexUnderCursor); 0193 const char *const iconName = (isHoveredIndexSelected ? koIconNameCStr("list-remove") : koIconNameCStr("list-add")); 0194 0195 m_ToggleSelectionButton->setIcon(QIcon::fromTheme(QLatin1String(iconName))); 0196 m_ToggleSelectionButton->setToolTip(isHoveredIndexSelected ? i18n("deselect item") : i18n("select item")); 0197 } 0198 0199 void KoViewItemContextBar::update() 0200 { 0201 // Check if the current index is still valid and then update the context bar 0202 if (m_view->model()->index(currentIndex().row(), currentIndex().column(), currentIndex().parent()).isValid()) { 0203 updateHoverUi(currentIndex()); 0204 } 0205 else { 0206 updateHoverUi(QModelIndex()); 0207 } 0208 } 0209 0210 QToolButton * KoViewItemContextBar::addContextButton(const QString &text, const QString &iconName) 0211 { 0212 KoContextBarButton *newContexButton = new KoContextBarButton(iconName); 0213 newContexButton->setToolTip(text); 0214 m_Layout->addWidget(newContexButton); 0215 m_contextBarButtons.append(newContexButton); 0216 return newContexButton; 0217 } 0218 0219 QModelIndex KoViewItemContextBar::currentIndex() 0220 { 0221 return m_IndexUnderCursor; 0222 } 0223 0224 int KoViewItemContextBar::preferredWidth() 0225 { 0226 return ((m_contextBarButtons.count()+1)*m_ToggleSelectionButton->sizeHint().width() + 2*CONTEXTBAR_MARGIN); 0227 } 0228 0229 void KoViewItemContextBar::setShowSelectionToggleButton(bool enabled) 0230 { 0231 m_showToggleButton = enabled; 0232 } 0233 0234 void KoViewItemContextBar::reset() 0235 { 0236 if (m_ContextBar) { 0237 m_ContextBar->hide(); 0238 } 0239 } 0240 0241 void KoViewItemContextBar::slotModelReset() 0242 { 0243 // reset the model index so it does no longer point to suff no longer available. 0244 m_IndexUnderCursor = QModelIndex(); 0245 } 0246 0247 void KoViewItemContextBar::enableContextBar() 0248 { 0249 m_enabled = true; 0250 } 0251 0252 void KoViewItemContextBar::disableContextBar() 0253 { 0254 m_enabled = false; 0255 }