File indexing completed on 2024-05-19 04:07:52
0001 /* 0002 SPDX-FileCopyrightText: 2009 Stefan Majewsky <majewsky@gmx.net> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "collection-view.h" 0008 #include "collection.h" 0009 #include "collection-delegate.h" 0010 #include "puzzle.h" 0011 0012 #include <QApplication> 0013 #include <QGridLayout> 0014 #include <QLineEdit> 0015 #include <QMenu> 0016 #include <QPushButton> 0017 #include <QSortFilterProxyModel> 0018 #include <QAction> 0019 #include <KLocalizedString> 0020 0021 Palapeli::CollectionView::CollectionView(QWidget* parent) 0022 : QWidget(parent) 0023 , m_view(new QListView(this)) 0024 , m_delegate(new Palapeli::CollectionDelegate(m_view)) 0025 , m_proxyModel(new QSortFilterProxyModel(this)) 0026 { 0027 //setup view 0028 connect(m_view, &QListView::activated, this, &CollectionView::handleActivated); 0029 0030 // Set up for multi-column display of the Puzzle Collection, which 0031 // allows the user to see more of the collection at one time. 0032 m_view->setWrapping(true); 0033 m_view->setResizeMode(QListView::Adjust); 0034 m_view->setUniformItemSizes(true); 0035 m_view->setFlow(QListView::LeftToRight); 0036 0037 // Avoid a resize loop (with the scrollbar appearing and disappearing) 0038 // when the number of items and display-columns hits a bad combination. 0039 m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); 0040 0041 m_view->setMouseTracking(true); 0042 m_view->setSelectionMode(QAbstractItemView::ExtendedSelection); 0043 m_view->setVerticalScrollMode(QListView::ScrollPerPixel); // Smooth. 0044 //setup proxy model 0045 m_view->setModel(m_proxyModel); 0046 connect(m_view->selectionModel(), &QItemSelectionModel::selectionChanged, this, &CollectionView::handleSelectionChanged); 0047 m_proxyModel->setDynamicSortFilter(true); 0048 m_proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); 0049 m_proxyModel->setSortLocaleAware(true); 0050 m_proxyModel->setSortRole(Qt::DisplayRole); 0051 m_proxyModel->sort(0, Qt::AscendingOrder); 0052 //TODO: save sorting role between sessions 0053 //setup filter search line 0054 QLineEdit* searchLine = new QLineEdit(this); 0055 searchLine->setClearButtonEnabled(true); 0056 connect(searchLine, &QLineEdit::textChanged, this, &Palapeli::CollectionView::slotTextChanged); 0057 //setup sort button 0058 QPushButton* sortButton = new QPushButton(i18nc("@action:button that pops up sorting strategy selection menu", "Sort List..."), this); 0059 QMenu* sortMenu = new QMenu(sortButton); 0060 sortButton->setMenu(sortMenu); 0061 m_sortByTitle = sortMenu->addAction(i18nc("@action:inmenu selects sorting strategy for collection list", "By Title")); 0062 m_sortByPieceCount = sortMenu->addAction(i18nc("@action:inmenu selects sorting strategy for collection list", "By Piece Count")); 0063 m_sortByTitle->setCheckable(true); 0064 m_sortByPieceCount->setCheckable(true); 0065 m_sortByTitle->setChecked(true); 0066 m_sortByPieceCount->setChecked(false); 0067 connect(sortMenu, &QMenu::triggered, this, &CollectionView::sortMenuTriggered); 0068 //construct layout 0069 QGridLayout* layout = new QGridLayout(this); 0070 layout->addWidget(sortButton, 0, 0); 0071 layout->addWidget(searchLine, 0, 1); 0072 layout->addWidget(m_view, 1, 0, 1, 2); 0073 // Removed this because setMargin is obsolete and (0) cuts off the right 0074 // hand and bottom edges of the search and ListView widgets --- on Apple 0075 // OSX at least. The default margin is 11 pixels all round and looks OK. 0076 // layout->setContentsMargins(0, 0, 0, 0); 0077 } 0078 0079 void Palapeli::CollectionView::slotTextChanged(const QString &str) 0080 { 0081 m_proxyModel->setFilterFixedString(str); 0082 } 0083 0084 void Palapeli::CollectionView::setModel(QAbstractItemModel* model) 0085 { 0086 m_proxyModel->setSourceModel(model); 0087 } 0088 0089 QModelIndexList Palapeli::CollectionView::selectedIndexes() const 0090 { 0091 return m_view->selectionModel()->selectedIndexes(); 0092 } 0093 0094 //NOTE The QAbstractItemView::activated signal honors the mouseclick selection behavior defined by the user (e.g. one-click is default on Linux, while two-click is default on Windows). 0095 void Palapeli::CollectionView::handleActivated(const QModelIndex& index) 0096 { 0097 //do not emit a play request when the Control modifier is pressed (without this rule, users with one-click activation could not ever select multiple puzzles at once) 0098 if (QApplication::keyboardModifiers() & Qt::ControlModifier) 0099 return; 0100 //change selection to indicate that the given puzzle has been chosen 0101 m_view->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect); 0102 Q_EMIT playRequest(Palapeli::Collection::instance()->puzzleFromIndex(index)); 0103 } 0104 0105 void Palapeli::CollectionView::handleSelectionChanged() 0106 { 0107 const QModelIndexList indexes = m_view->selectionModel()->selectedIndexes(); 0108 const bool someSelection = !indexes.isEmpty(); 0109 Q_EMIT canExportChanged(someSelection); 0110 for (const QModelIndex& index : indexes) 0111 if (!index.data(Palapeli::Collection::IsDeleteableRole).toBool()) 0112 { 0113 Q_EMIT canDeleteChanged(false); 0114 return; 0115 } 0116 Q_EMIT canDeleteChanged(someSelection); 0117 } 0118 0119 void Palapeli::CollectionView::sortMenuTriggered(QAction* action) 0120 { 0121 //find out what was requested 0122 int sortRole = Qt::DisplayRole; //corresponds to action == m_sortByTitle 0123 if (action == m_sortByPieceCount) 0124 sortRole = Palapeli::Collection::PieceCountRole; 0125 //update sorting and menu 0126 m_proxyModel->setSortRole(sortRole); 0127 m_sortByTitle->setChecked(sortRole == Qt::DisplayRole); 0128 m_sortByPieceCount->setChecked(sortRole == Palapeli::Collection::PieceCountRole); 0129 } 0130 0131 #include "moc_collection-view.cpp"