File indexing completed on 2024-04-28 05:47:43

0001 /*
0002     SPDX-FileCopyrightText: 2008-2009 Harald Hvaal <haraldhv (at@at) stud.ntnu.no>
0003     SPDX-FileCopyrightText: 2016 Vladyslav Batyrenko <mvlabat@gmail.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "archiveview.h"
0009 #include "ark_debug.h"
0010 
0011 #include <QDragEnterEvent>
0012 #include <QDragMoveEvent>
0013 #include <QHeaderView>
0014 #include <QLineEdit>
0015 #include <QMimeData>
0016 #include <QMouseEvent>
0017 
0018 ArchiveView::ArchiveView(QWidget *parent)
0019     : QTreeView(parent)
0020 {
0021     setSelectionMode(QAbstractItemView::ExtendedSelection);
0022     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
0023     setAlternatingRowColors(true);
0024     setAnimated(true);
0025     setAllColumnsShowFocus(true);
0026     setSortingEnabled(true);
0027     setDragEnabled(true);
0028     setDropIndicatorShown(true);
0029     // #368807: drops must be initially disabled, otherwise they will override the MainWindow's ones.
0030     // They will be enabled in Part::slotLoadingFinished().
0031     setDropsEnabled(false);
0032     header()->setSectionResizeMode(QHeaderView::ResizeToContents);
0033 }
0034 
0035 void ArchiveView::startDrag(Qt::DropActions supportedActions)
0036 {
0037     // only start the drag if it's over the filename column. this allows dragging selection in
0038     // tree/detail view
0039     if (currentIndex().column() != 0) {
0040         return;
0041     }
0042 
0043     QTreeView::startDrag(supportedActions);
0044 }
0045 
0046 void ArchiveView::expandIfSingleFolder()
0047 {
0048     if (model()->rowCount() == 1) {
0049         expandToDepth(0);
0050     }
0051 }
0052 
0053 void ArchiveView::setDropsEnabled(bool enabled)
0054 {
0055     setAcceptDrops(enabled);
0056     setDragDropMode(enabled ? QAbstractItemView::DragDrop : QAbstractItemView::DragOnly);
0057 }
0058 
0059 void ArchiveView::dragEnterEvent(QDragEnterEvent *event)
0060 {
0061     // TODO: if no model, trigger some mechanism to create one automatically!
0062     qCDebug(ARK) << event;
0063 
0064     if (event->source() == this) {
0065         // we don't support internal drops yet.
0066         return;
0067     }
0068 
0069     QTreeView::dragEnterEvent(event);
0070 }
0071 
0072 void ArchiveView::dropEvent(QDropEvent *event)
0073 {
0074     qCDebug(ARK) << event;
0075 
0076     if (event->source() == this) {
0077         // we don't support internal drops yet.
0078         return;
0079     }
0080 
0081     QTreeView::dropEvent(event);
0082 }
0083 
0084 void ArchiveView::dragMoveEvent(QDragMoveEvent *event)
0085 {
0086     qCDebug(ARK) << event;
0087 
0088     if (event->source() == this) {
0089         // we don't support internal drops yet.
0090         return;
0091     }
0092 
0093     QTreeView::dragMoveEvent(event);
0094     if (event->mimeData()->hasUrls()) {
0095         event->acceptProposedAction();
0096     }
0097 }
0098 
0099 bool ArchiveView::eventFilter(QObject *object, QEvent *event)
0100 {
0101     if (object == m_entryEditor && event->type() == QEvent::KeyPress) {
0102         QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
0103         if (keyEvent->key() == Qt::Key_Escape) {
0104             closeEntryEditor();
0105             return true;
0106         }
0107     }
0108     return false;
0109 }
0110 
0111 void ArchiveView::mouseReleaseEvent(QMouseEvent *event)
0112 {
0113     if (m_editorIndex.isValid()) {
0114         closeEntryEditor();
0115     } else {
0116         QTreeView::mouseReleaseEvent(event);
0117     }
0118 }
0119 
0120 void ArchiveView::keyPressEvent(QKeyEvent *event)
0121 {
0122     if (m_editorIndex.isValid()) {
0123         switch (event->key()) {
0124         case Qt::Key_Return:
0125         case Qt::Key_Enter: {
0126             QLineEdit *editor = static_cast<QLineEdit *>(indexWidget(m_editorIndex));
0127             Q_EMIT entryChanged(editor->text());
0128             closeEntryEditor();
0129             break;
0130         }
0131         default:
0132             QTreeView::keyPressEvent(event);
0133         }
0134     } else {
0135         QTreeView::keyPressEvent(event);
0136     }
0137 }
0138 
0139 void ArchiveView::renameSelectedEntry()
0140 {
0141     QModelIndex currentIndex = selectionModel()->currentIndex();
0142     currentIndex = (currentIndex.parent().isValid()) ? currentIndex.parent().model()->index(currentIndex.row(), 0, currentIndex.parent())
0143                                                      : model()->index(currentIndex.row(), 0);
0144     openEntryEditor(currentIndex);
0145 }
0146 
0147 void ArchiveView::openEntryEditor(const QModelIndex &index)
0148 {
0149     m_editorIndex = index;
0150     openPersistentEditor(index);
0151     m_entryEditor = static_cast<QLineEdit *>(indexWidget(m_editorIndex));
0152     m_entryEditor->installEventFilter(this);
0153     m_entryEditor->setText(index.data().toString());
0154     m_entryEditor->setFocus(Qt::OtherFocusReason);
0155     m_entryEditor->selectAll();
0156 }
0157 
0158 void ArchiveView::closeEntryEditor()
0159 {
0160     m_entryEditor->removeEventFilter(this);
0161     closePersistentEditor(m_editorIndex);
0162     m_editorIndex = QModelIndex();
0163 }
0164 
0165 void NoHighlightSelectionDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
0166 {
0167     if (index.column() && option.state.testFlag(QStyle::State_Selected)) {
0168         QStyleOptionViewItem myOption = option;
0169         myOption.state |= QStyle::State_MouseOver;
0170         myOption.state &= ~QStyle::State_Selected;
0171 
0172         QStyledItemDelegate::paint(painter, myOption, index);
0173     } else {
0174         QStyledItemDelegate::paint(painter, option, index);
0175     }
0176 }
0177 
0178 #include "moc_archiveview.cpp"