File indexing completed on 2024-04-14 03:40:35

0001 /*************************************************************************************
0002  *  Copyright (C) 2012-2013 by Percy Camilo T. Aucahuasi <percy.camilo.ta@gmail.com> *
0003  *                                                                                   *
0004  *  This program is free software; you can redistribute it and/or                    *
0005  *  modify it under the terms of the GNU General Public License                      *
0006  *  as published by the Free Software Foundation; either version 2                   *
0007  *  of the License, or (at your option) any later version.                           *
0008  *                                                                                   *
0009  *  This program is distributed in the hope that it will be useful,                  *
0010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of                   *
0011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                    *
0012  *  GNU General Public License for more details.                                     *
0013  *                                                                                   *
0014  *  You should have received a copy of the GNU General Public License                *
0015  *  along with this program; if not, write to the Free Software                      *
0016  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA   *
0017  *************************************************************************************/
0018 
0019 #include "spacesdelegate.h"
0020 
0021 #include "analitzaplot/plotsdictionarymodel.h"
0022 
0023 #include <QPainter>
0024 #include <QPaintEvent>
0025 #include <QToolButton>
0026 #include <QHBoxLayout>
0027 #include <QListView>
0028 #include <QDebug>
0029 #include <QApplication>
0030 #include <KLocalizedString>
0031 
0032 //local includes
0033 #include "spacesmodel.h"
0034 #include "datastore.h"
0035 #include "spaceplotsproxymodel.h"
0036 #include "spaceitem.h"
0037 
0038 LineEdit::LineEdit(QWidget* parent): QLineEdit(parent)
0039 {
0040     connect(this, SIGNAL(editingFinished()), SLOT(procsSditingFinished()));
0041 }
0042 
0043 void LineEdit::procsSditingFinished()
0044 {
0045     emit editingFinished(text());
0046 }
0047 
0048 SpacesDelegate::SpacesDelegate(SpacesView *itemView, QObject *parent)
0049     : QStyledItemDelegate(parent)
0050     , m_itemView(itemView)
0051     , m_isEditing(false)
0052     , m_operationBar(nullptr)
0053     , m_titleEditor(nullptr)
0054 {
0055     itemView->viewport()->installEventFilter(this);
0056     
0057     setupOperationBar();
0058     
0059     connect(this, SIGNAL(showSpace(QModelIndex)), itemView, SIGNAL(doubleClicked(QModelIndex)));
0060 }
0061 
0062 SpacesDelegate::~SpacesDelegate()
0063 {
0064 }
0065 
0066 void SpacesDelegate::setupOperationBar()
0067 {
0068     //BEGIN btns
0069     m_operationBar = new QWidget(m_itemView->viewport());
0070 
0071     QToolButton *m_removeButton = new QToolButton(m_operationBar);
0072     m_removeButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
0073     m_removeButton->setAutoRepeat(false);
0074     m_removeButton->setToolTip(i18n("Remove"));
0075     m_removeButton->setIcon(QIcon::fromTheme("list-remove"));
0076     connect(m_removeButton, SIGNAL(pressed()), SLOT(removeCurrentSpace()));
0077 
0078     QToolButton *m_editButton = new QToolButton(m_operationBar);
0079     m_editButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
0080     m_editButton->setAutoRepeat(false);
0081     m_editButton->setToolTip(i18n("Rename"));
0082     m_editButton->setIcon(QIcon::fromTheme("document-edit"));
0083     connect(m_editButton, SIGNAL(pressed()), SLOT(editCurrentSpace()));
0084 
0085     QToolButton *m_showButton = new QToolButton(m_operationBar);
0086     m_showButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
0087     m_showButton->setAutoRepeat(false);
0088     m_showButton->setToolTip(i18n("Export as dictionary"));
0089     m_showButton->setIcon(QIcon::fromTheme("document-export"));
0090     connect(m_showButton, SIGNAL(pressed()), SLOT(exportSpace()));
0091 
0092     QHBoxLayout* layout = new QHBoxLayout(m_operationBar);
0093 
0094     layout->setSpacing(1);
0095     layout->addWidget(m_removeButton);
0096     layout->addWidget(m_editButton);
0097     layout->addWidget(m_showButton);
0098 
0099     m_operationBar->adjustSize();
0100     m_operationBar->hide();
0101     //END btns
0102 
0103     m_titleEditor = new LineEdit(m_itemView->viewport());
0104     m_titleEditor->setClearButtonEnabled(true);
0105     m_titleEditor->hide();
0106 
0107     connect(m_titleEditor, SIGNAL(editingFinished(QString)), SLOT(finishEditingTitle(QString)));
0108 }
0109 
0110 void SpacesDelegate::exportSpace()
0111 {
0112     emit saveDictionary(m_itemView->currentIndex());
0113 }
0114 
0115 QWidget* SpacesDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem&, const QModelIndex& index) const
0116 {
0117     m_currentEditingIndex = index;
0118     m_isEditing = true;
0119     LineEdit *editor = new LineEdit(parent);
0120 
0121     QRect rect = m_itemView->visualRect(m_itemView->currentIndex());
0122 
0123     editor->resize(rect.width(), m_titleEditor->height());
0124     editor->move(rect.left()/*+(PreviewWidth-m_operationBar->width())/2*/,rect.top() + rect.height() - m_operationBar->height() - .8*m_titleEditor->height());
0125     editor->selectAll();
0126     editor->setFocus();
0127     editor->setClearButtonEnabled(true);
0128 
0129     return editor;
0130 }
0131 
0132 void SpacesDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
0133 {
0134     if (!index.isValid())
0135         return ;
0136 
0137     static_cast<LineEdit*>(editor)->setText(m_itemView->currentIndex().data().toString());
0138 }
0139 
0140 void SpacesDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
0141 {
0142     if (!index.isValid())
0143         return ;
0144 
0145     m_currentEditingIndex = QModelIndex();
0146     m_isEditing = false;
0147 
0148     static_cast<SpacesFilterProxyModel*>(model)->sourceModel()->setData(index, static_cast<LineEdit*>(editor)->text());
0149 }
0150 
0151 QSize SpacesDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
0152 {
0153     Q_UNUSED(option);
0154     Q_UNUSED(index);
0155 
0156     QSize size;
0157 
0158     size.setWidth(PreviewWidth+2*ItemMargin);
0159     size.setHeight(PreviewHeight+4*option.fontMetrics.height()+2*ItemMargin); // up to 6 lines of text, and two margins
0160     return size;
0161 }
0162 
0163 void SpacesDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
0164 {
0165     if (!index.isValid() || !m_itemView->model()) return QStyledItemDelegate::paint(painter, option, index);
0166 
0167     painter->save();
0168 
0169     if (option.state & QStyle::State_Selected)
0170     {
0171         //focus
0172         QStyle *style = QApplication::style();
0173         style->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, nullptr);
0174         //endfocus
0175 
0176         painter->setPen(QPen(option.palette.highlightedText().color()));
0177     } 
0178     else 
0179         painter->setPen(QPen(option.palette.text().color()));
0180 
0181     painter->drawPixmap(option.rect.topLeft()+QPoint(ItemMargin,ItemMargin), index.data(Qt::DecorationRole).value<QPixmap>());
0182 
0183     QString text = painter->fontMetrics().elidedText(index.data().toString(), Qt::ElideRight, option.rect.width(), Qt::TextSingleLine);
0184 
0185     QFont p = painter->font();
0186     p.setBold(true);
0187     painter->setFont(p);
0188     painter->drawText(option.rect.topLeft()+QPoint((option.rect.width() - painter->fontMetrics().width(text))/2,
0189                       PreviewHeight + 3.8*ItemMargin + FrameThickness*2), text);
0190 
0191     painter->restore();
0192 }
0193 
0194 bool SpacesDelegate::eventFilter(QObject *watched, QEvent *event)
0195 {
0196     if (m_itemView->model())
0197     {
0198         if (event->type() == QEvent::MouseMove)
0199         {
0200             QMouseEvent *e = static_cast<QMouseEvent*>(event);
0201 
0202             m_currentCurPos = e->pos();
0203             QModelIndex index = m_itemView->indexAt(e->pos());
0204 
0205             if (!index.isValid() && !m_isEditing)
0206             {
0207                 if (m_operationBar && m_titleEditor && !m_itemView->currentIndex().isValid()
0208                         && m_itemView->currentIndex() != m_currentEditingIndex )
0209                 {
0210                     m_operationBar->hide();
0211                     m_titleEditor->hide();
0212                 }
0213 
0214 //                 m_itemView->setCurrentIndex(QModelIndex());
0215             } 
0216             else 
0217                 if (index.isValid())
0218                 {
0219                     //NOTE es importante que el viewport tenga el foco para que funcione correctamte la seleccion de items con el movimieto del mouse
0220                     if (m_currentEditingIndex != index && !m_isEditing)
0221                         m_itemView->viewport()->setFocus();
0222 
0223                     setCurrentSpace(index);
0224                 }
0225 
0226             return true;
0227         }
0228         else if (event->type() == QEvent::MouseButtonPress)
0229         {
0230 
0231             QMouseEvent *e = static_cast<QMouseEvent*>(event);
0232 
0233             QModelIndex index = m_itemView->indexAt(e->pos());
0234 
0235             if (!index.isValid())
0236             {
0237                 m_itemView->setCurrentIndex(QModelIndex());
0238 
0239                 m_isEditing = false;
0240 
0241                 if (m_operationBar && m_titleEditor)
0242                 {
0243                     m_operationBar->hide();
0244                     m_titleEditor->hide();
0245                     m_titleEditor->clear();
0246                 }
0247             }
0248             else
0249             {
0250                 invalidClick(index);
0251             }
0252 
0253             return true;
0254         }
0255         else if (event->type() == QEvent::MouseButtonDblClick)
0256         {
0257             QMouseEvent *e = static_cast<QMouseEvent*>(event);
0258 
0259             QModelIndex index = m_itemView->indexAt(e->pos());
0260 
0261             if (index.isValid())
0262                 emit showSpace(index);
0263         }
0264     }
0265 
0266     return QStyledItemDelegate::eventFilter(watched, event);
0267 }
0268 
0269 void SpacesDelegate::setCurrentSpace(const QModelIndex& index)
0270 {
0271     if (m_isEditing)
0272         return;
0273 
0274     m_itemView->setCurrentIndex(index);
0275 
0276     updateOperationBarPos(index);
0277     
0278     if (m_operationBar && m_titleEditor)
0279         m_operationBar->show();
0280 }
0281 
0282 void SpacesDelegate::editCurrentSpace()
0283 {
0284     if (!m_itemView->currentIndex().isValid())
0285         return;
0286 
0287     m_currentEditingIndex = m_itemView->currentIndex();
0288 
0289     m_isEditing = true;
0290 
0291     QRect rect = m_itemView->visualRect(m_itemView->currentIndex());
0292 
0293     m_titleEditor->setText(m_itemView->currentIndex().data().toString());
0294     m_titleEditor->resize(rect.width(), m_titleEditor->height());
0295     m_titleEditor->move(rect.left()/*+(PreviewWidth-m_operationBar->width())/2*/,rect.top() + rect.height() - m_operationBar->height() - .8*m_titleEditor->height());
0296     m_titleEditor->selectAll();
0297     m_titleEditor->setFocus();
0298     m_titleEditor->show();
0299 }
0300 
0301 void SpacesDelegate::removeCurrentSpace()
0302 {
0303     if (!m_itemView->currentIndex().isValid())
0304         return;
0305 
0306     m_document->removeSpace(m_itemView->currentIndex().row());
0307 
0308     m_isEditing = false;
0309 
0310     m_operationBar->hide();
0311     m_titleEditor->hide();
0312 
0313     filterEvent();
0314 }
0315 
0316 void SpacesDelegate::setDocument(DataStore *doc)
0317 {
0318     Q_ASSERT(doc);
0319 
0320     m_document=doc;
0321 }
0322 
0323 void SpacesDelegate::hideOperatorBar()
0324 {
0325     m_operationBar->hide();
0326 }
0327 
0328 void SpacesDelegate::finishEditingTitle(const QString &newtitle )
0329 {
0330     if (!m_itemView->currentIndex().isValid())
0331         return;
0332 
0333     m_isEditing = false;
0334 
0335     m_itemView->model()->setData(m_itemView->currentIndex(), m_titleEditor->text());
0336 
0337     m_titleEditor->hide();
0338 
0339     QModelIndex posi = m_itemView->indexAt(m_currentCurPos);
0340 
0341     if (posi.isValid())
0342     {
0343         if (posi != m_currentEditingIndex)
0344             setCurrentSpace(posi);
0345     }
0346     else
0347     {
0348         m_operationBar->hide();
0349     }
0350 }
0351 
0352 void SpacesDelegate::invalidClick(const QModelIndex& index)
0353 {
0354     if (index != m_currentEditingIndex)
0355     {
0356         m_isEditing = false;
0357         if (m_operationBar && m_titleEditor)
0358         {
0359             m_titleEditor->hide();
0360             m_titleEditor->clear();
0361 
0362         }
0363 
0364         setCurrentSpace(index);
0365     }
0366 }
0367 
0368 // this will be call always from aoutside of this class
0369 void SpacesDelegate::filterEvent()
0370 {
0371     m_isEditing = false;
0372 
0373     if (m_operationBar)
0374         m_operationBar->hide();
0375 
0376     if (m_titleEditor)
0377     {
0378         m_titleEditor->clear();
0379         m_titleEditor->hide();
0380     }
0381 
0382     m_itemView->clearSelection();
0383     m_itemView->setCurrentIndex(QModelIndex());
0384 
0385     setCurrentSpace(QModelIndex());
0386     invalidClick(QModelIndex());
0387 }
0388 
0389 void SpacesDelegate::updateOperationBarPos(const QModelIndex& index)
0390 {
0391     if (m_operationBar && m_titleEditor)
0392     {
0393         QRect rect = m_itemView->visualRect(index);
0394 
0395         m_operationBar->move(rect.left()+(PreviewWidth-m_operationBar->width())/2,rect.top() + rect.height() - m_operationBar->height());
0396     }
0397 }
0398 
0399 ///The view
0400 
0401 SpacesView::SpacesView(QWidget* parent): QListView(parent)
0402 {
0403     setAlternatingRowColors(true);
0404     setViewMode(IconMode);
0405     setUniformItemSizes(true);
0406     setEditTriggers(NoEditTriggers);
0407     setFlow(LeftToRight);
0408     setWrapping(true);
0409     setResizeMode(Adjust);
0410     setSelectionRectVisible(true);
0411     setVerticalScrollMode(ScrollPerPixel);
0412     setHorizontalScrollMode(ScrollPerPixel);
0413     setMouseTracking(true);
0414     setSelectionMode(QListView::SingleSelection);
0415     setSelectionBehavior(QAbstractItemView::SelectItems);
0416 }
0417 
0418 void SpacesView::resizeEvent(QResizeEvent* e)
0419 {
0420     static_cast<SpacesDelegate*>(itemDelegate())->updateOperationBarPos(currentIndex());
0421     
0422     QListView::resizeEvent(e);
0423 }
0424 
0425 #include "moc_spacesdelegate.cpp"