Warning, /graphics/peruse/src/app/qml/Bookshelf.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 * Copyright (C) 2015 Dan Leinir Turthra Jensen <admin@leinir.dk> 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Lesser General Public 0006 * License as published by the Free Software Foundation; either 0007 * version 2.1 of the License, or (at your option) version 3, or any 0008 * later version accepted by the membership of KDE e.V. (or its 0009 * successor approved by the membership of KDE e.V.), which shall 0010 * act as a proxy defined in Section 6 of version 3 of the license. 0011 * 0012 * This library is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 * Lesser General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU Lesser General Public 0018 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 0019 * 0020 */ 0021 0022 import QtQuick 2.12 0023 import QtQuick.Controls 2.15 as QtControls 0024 import QtQuick.Layouts 1.2 0025 0026 import org.kde.kirigami 2.14 as Kirigami 0027 0028 import org.kde.peruse 0.1 as Peruse 0029 import "listcomponents" as ListComponents 0030 0031 /** 0032 * @brief This lays out the books and categories. 0033 * 0034 * It uses BookTileTall for the books and CategoryTileTall 0035 * for showing the categories. Categories can be selected to open 0036 * a new bookshelf from the right, showing the entries in that 0037 * subcategory. This is particularly in use with the folder category. 0038 * 0039 * There is also access to the SearchBox, and it is possible to access 0040 * a BookTile by press+holding the thumbnail. 0041 * This holds information about the book. 0042 */ 0043 Kirigami.ScrollablePage { 0044 id: root; 0045 property alias pageHeader: shelfList.header; 0046 title: headerText; 0047 property string categoryName: "bookshelf"; 0048 objectName: "bookshelf"; 0049 property QtObject model; 0050 /** 0051 * Allows you to override the default behaviour of searching inside the shelf (such as 0052 * for the welcome page where we want to search the global list) 0053 */ 0054 property alias searchModel: searchFilterProxy.sourceModel; 0055 property string sectionRole: "title"; 0056 property int sectionCriteria: ViewSection.FirstCharacter; 0057 signal bookSelected(string filename, int currentPage); 0058 property string headerText; 0059 property string searchText: "" 0060 property bool searching: searchText.length > 0 0061 property bool isSearching: searchFilterProxy.filterString.length > 0; 0062 0063 function openBook(index) { 0064 applicationWindow().contextDrawer.close(); 0065 var whatModel = isSearching ? searchFilterProxy.sourceModel : shelfList.model; 0066 var whatIndex = isSearching ? searchFilterProxy.sourceIndex(index) : index; 0067 if (whatModel) { 0068 if(whatModel.indexIsBook(whatIndex)) { 0069 var book = whatModel.get(whatIndex); 0070 root.bookSelected(book.readProperty("filename"), book.readProperty("currentPage")); 0071 } 0072 else { 0073 var catEntry = whatModel.getEntry(whatIndex); 0074 applicationWindow().pageStack.push(bookshelf, { focus: true, headerText: catEntry.readProperty("title"), model: catEntry.readProperty("entriesModel") }); 0075 } 0076 } 0077 } 0078 0079 function closeShelf() { 0080 applicationWindow().contextDrawer.close(); 0081 applicationWindow().pageStack.pop(); 0082 } 0083 property bool isCurrentContext: isCurrentPage && !applicationWindow().bookOpen 0084 property list<QtObject> mobileActions; 0085 property list<QtObject> desktopActions: [ 0086 Kirigami.Action { 0087 text: i18nc("Navigate one page back", "Back"); 0088 shortcut: bookDetails.sheetOpen ? "" : "Esc"; 0089 iconName: "dialog-close"; 0090 onTriggered: closeShelf(); 0091 enabled: root.isCurrentContext && !Kirigami.Settings.isMobile && applicationWindow().pageStack.currentIndex > 0; 0092 }, 0093 Kirigami.Action { 0094 text: i18nc("Open the book which is currently selected in the list", "Open Selected Book"); 0095 shortcut: bookDetails.sheetOpen? "" : "Return"; 0096 iconName: "document-open"; 0097 onTriggered: openBook(shelfList.currentIndex); 0098 enabled: root.isCurrentContext && !Kirigami.Settings.isMobile; 0099 } 0100 ] 0101 actions { 0102 contextualActions: Kirigami.Settings.isMobile ? mobileActions : desktopActions; 0103 main: bookDetails.sheetOpen ? bookDetailsAction : mainShelfAction; 0104 } 0105 Kirigami.Action { 0106 id: mainShelfAction; 0107 text: i18nc("search in the list of books (not inside the books)", "Search Books"); 0108 iconName: "system-search"; 0109 onTriggered: searchBox.activate(); 0110 enabled: root.isCurrentContext; 0111 displayComponent: Kirigami.SearchField { 0112 id: searchField 0113 focus: true 0114 placeholderText: i18nc("placeholder text for the search field", "Tap and type to search"); 0115 onTextChanged: { 0116 searchText = text 0117 if(text.length > 0) { 0118 searchTimer.start(); 0119 } else { 0120 searchTimer.stop(); 0121 searchFilterProxy.filterString = ""; 0122 } 0123 } 0124 Timer { 0125 id: searchTimer; 0126 interval: 250; 0127 repeat: false; 0128 running: false; 0129 onTriggered: searchFilterProxy.filterString = searchField.text; 0130 } 0131 } 0132 } 0133 Kirigami.Action { 0134 id: bookDetailsAction; 0135 text: i18nc("Closes the book details drawer", "Close"); 0136 shortcut: bookDetails.sheetOpen ? "Esc" : ""; 0137 iconName: "dialog-cancel"; 0138 onTriggered: bookDetails.close(); 0139 enabled: root.isCurrentContext; 0140 } 0141 0142 GridView { 0143 id: shelfList; 0144 model: isSearching ? searchFilterProxy : root.model; 0145 Peruse.FilterProxy { 0146 id: searchFilterProxy; 0147 sourceModel: root.model; 0148 } 0149 keyNavigationEnabled: true; 0150 clip: true; 0151 0152 Kirigami.PlaceholderMessage { 0153 id: placeholderMessage 0154 width: parent.width - (Kirigami.Units.gridUnit * 4) 0155 visible: shelfList.count === 0 0156 anchors.centerIn: parent 0157 text: i18nc("Placeholder Text when there are no comics in the library that match the filter", "No matches") 0158 } 0159 0160 readonly property int scrollBarSpace: root.flickable.QtControls.ScrollBar.vertical ? root.flickable.QtControls.ScrollBar.vertical.width : 0 0161 readonly property int availableWidth: shelfList.width - scrollBarSpace - 4 0162 readonly property int implicitCellWidth: Kirigami.Units.gridUnit * 15 0163 cellWidth: Math.floor(availableWidth / Math.max(Math.floor(availableWidth / (implicitCellWidth + Kirigami.Units.gridUnit)), 2)) 0164 cellHeight: Kirigami.Units.gridUnit * 13; 0165 0166 currentIndex: -1; 0167 0168 delegate: Item { 0169 height: shelfList.cellHeight; 0170 width: shelfList.cellWidth; 0171 ListComponents.CategoryTileTall { 0172 id: categoryTile; 0173 visible: height > 0; 0174 height: model.categoryEntriesCount > 0 ? shelfList.cellHeight : 0; 0175 width: parent.width; 0176 count: model.categoryEntriesCount; 0177 title: model.title; 0178 entriesModel: model.categoryEntriesModel ? model.categoryEntriesModel : null; 0179 selected: shelfList.currentIndex === index; 0180 } 0181 ListComponents.BookTileTall { 0182 id: bookTile; 0183 visible: height > 0; 0184 height: model.categoryEntriesCount < 1 ? shelfList.cellHeight : 0; 0185 width: parent.width; 0186 author: model.author ? model.author : i18nc("used for the author data in book lists if author is empty", "(unknown)"); 0187 title: model.title; 0188 filename: model.filename; 0189 thumbnail: model.categoryEntriesCount < 1 ? model.thumbnail : ""; 0190 categoryEntriesCount: model.categoryEntriesCount; 0191 currentPage: model.currentPage; 0192 totalPages: model.totalPages; 0193 onBookSelected: root.bookSelected(filename, currentPage); 0194 selected: shelfList.currentIndex === index; 0195 onPressAndHold: bookDetails.showBookInfo(model.index); 0196 pressIndicator: true; 0197 } 0198 } 0199 0200 Kirigami.OverlaySheet { 0201 id: bookDetails; 0202 function showBookInfo(index) { 0203 var whatModel = isSearching ? searchFilterProxy.sourceModel : shelfList.model; 0204 var whatIndex = isSearching ? searchFilterProxy.sourceIndex(index) : index; 0205 currentBook = whatModel.getEntry(whatIndex); 0206 open(); 0207 } 0208 property QtObject currentBook: fakeBook; 0209 property QtObject fakeBook: Peruse.PropertyContainer { 0210 property string author: ""; 0211 property string title: ""; 0212 property string filename: ""; 0213 property string publisher: ""; 0214 property string thumbnail: ""; 0215 property string currentPage: "0"; 0216 property string totalPages: "0"; 0217 property string comment: ""; 0218 } 0219 ListComponents.BookTile { 0220 id: detailsTile; 0221 height: neededHeight; 0222 width: shelfList.width - Kirigami.Units.largeSpacing * 2; 0223 author: bookDetails.currentBook.readProperty("author"); 0224 publisher: bookDetails.currentBook.readProperty("publisher"); 0225 title: bookDetails.currentBook.readProperty("title"); 0226 filename: bookDetails.currentBook.readProperty("filename"); 0227 thumbnail: bookDetails.currentBook.readProperty("thumbnail"); 0228 categoryEntriesCount: 0; 0229 currentPage: bookDetails.currentBook.readProperty("currentPage"); 0230 totalPages: bookDetails.currentBook.readProperty("totalPages"); 0231 description: bookDetails.currentBook.readProperty("description"); 0232 onBookSelected: { 0233 bookDetails.close(); 0234 applicationWindow().showBook(fileSelected, currentPage); 0235 } 0236 onBookDeleteRequested: { 0237 contentList.removeBook(fileSelected, true); 0238 close(); 0239 } 0240 } 0241 } 0242 } 0243 }