File indexing completed on 2024-04-28 16:31:57
0001 /*************************************************************************** 0002 Copyright (C) 2002-2009 Robby Stephenson <robby@periapsis.org> 0003 ***************************************************************************/ 0004 0005 /*************************************************************************** 0006 * * 0007 * This program is free software; you can redistribute it and/or * 0008 * modify it under the terms of the GNU General Public License as * 0009 * published by the Free Software Foundation; either version 2 of * 0010 * the License or (at your option) version 3 or any later version * 0011 * accepted by the membership of KDE e.V. (or its successor approved * 0012 * by the membership of KDE e.V.), which shall act as a proxy * 0013 * defined in Section 14 of version 3 of the license. * 0014 * * 0015 * This program is distributed in the hope that it will be useful, * 0016 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0018 * GNU General Public License for more details. * 0019 * * 0020 * You should have received a copy of the GNU General Public License * 0021 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 0022 * * 0023 ***************************************************************************/ 0024 0025 #include "entryiconview.h" 0026 #include "collection.h" 0027 #include "collectionfactory.h" 0028 #include "images/imagefactory.h" 0029 #include "controller.h" 0030 #include "entry.h" 0031 #include "field.h" 0032 #include "document.h" 0033 #include "utils/tellico_utils.h" 0034 #include "models/entrymodel.h" 0035 #include "models/entrysortmodel.h" 0036 #include "tellico_kernel.h" 0037 #include "tellico_debug.h" 0038 0039 #include <KLocalizedString> 0040 0041 #include <QMenu> 0042 #include <QIcon> 0043 #include <QContextMenuEvent> 0044 #include <QDesktopServices> 0045 0046 namespace { 0047 static const int ENTRY_ICON_SIZE_PAD = 2; 0048 } 0049 0050 using Tellico::EntryIconView; 0051 0052 EntryIconView::EntryIconView(QWidget* parent_) 0053 : QListView(parent_), m_maxAllowedIconWidth(MAX_ENTRY_ICON_SIZE) { 0054 setViewMode(QListView::IconMode); 0055 setMovement(QListView::Static); 0056 setDragEnabled(false); 0057 setSelectionMode(QAbstractItemView::ExtendedSelection); 0058 setResizeMode(QListView::Adjust); 0059 setWordWrap(true); 0060 setSpacing(ENTRY_ICON_SIZE_PAD); 0061 setLayoutMode(QListView::Batched); 0062 0063 connect(this, &EntryIconView::doubleClicked, this, &EntryIconView::slotDoubleClicked); 0064 0065 setWhatsThis(i18n("<qt>The <i>Icon View</i> shows each entry in the collection or group using " 0066 "an icon, which may be an image in the entry.</qt>")); 0067 } 0068 0069 EntryIconView::~EntryIconView() { 0070 } 0071 0072 void EntryIconView::setModel(QAbstractItemModel* model_) { 0073 QListView::setModel(model_); 0074 if(!model_) { 0075 return; 0076 } 0077 connect(model_, &QAbstractItemModel::columnsInserted, this, &EntryIconView::updateModelColumn); 0078 } 0079 0080 void EntryIconView::setMaxAllowedIconWidth(int width_) { 0081 m_maxAllowedIconWidth = qBound(MIN_ENTRY_ICON_SIZE, width_, MAX_ENTRY_ICON_SIZE); 0082 QSize iconSize(m_maxAllowedIconWidth, m_maxAllowedIconWidth); 0083 setIconSize(iconSize); 0084 0085 QSize gridSize(m_maxAllowedIconWidth + 2*ENTRY_ICON_SIZE_PAD, 0086 m_maxAllowedIconWidth + 3*(fontMetrics().lineSpacing() + ENTRY_ICON_SIZE_PAD)); 0087 setGridSize(gridSize); 0088 } 0089 0090 void EntryIconView::slotDoubleClicked(const QModelIndex& index_) { 0091 Data::EntryPtr entry = index_.data(EntryPtrRole).value<Data::EntryPtr>(); 0092 if(entry) { 0093 Controller::self()->editEntry(entry); 0094 } 0095 } 0096 0097 void EntryIconView::contextMenuEvent(QContextMenuEvent* ev_) { 0098 QMenu menu(this); 0099 0100 // only insert entry items if one is selected 0101 QModelIndex index = indexAt(ev_->pos()); 0102 if(index.isValid()) { 0103 Controller::self()->plugEntryActions(&menu); 0104 0105 // add a menu item to open each URL field 0106 Data::EntryPtr entry = index.data(EntryPtrRole).value<Data::EntryPtr>(); 0107 Data::FieldList urlFields; 0108 foreach(Data::FieldPtr field, Data::Document::self()->collection()->fields()) { 0109 if(field->type() == Data::Field::URL) { 0110 urlFields += field; 0111 } 0112 } 0113 foreach(Data::FieldPtr urlField, urlFields) { 0114 QAction* act = menu.addAction(QIcon::fromTheme(QStringLiteral("bookmarks")), 0115 i18nc("Open URL", "Open %1", urlField->title())); 0116 const QString value = entry->field(urlField); 0117 act->setData(value); 0118 act->setWhatsThis(value); 0119 act->setEnabled(!value.isEmpty()); 0120 menu.addAction(act); 0121 } 0122 if(!urlFields.isEmpty()) { 0123 connect(&menu, &QMenu::triggered, this, &EntryIconView::slotOpenUrlMenuActivated); 0124 } 0125 0126 menu.addSeparator(); 0127 } 0128 0129 QMenu* sortMenu = Controller::self()->plugSortActions(&menu); 0130 connect(sortMenu, &QMenu::triggered, this, &EntryIconView::slotSortMenuActivated); 0131 0132 menu.exec(ev_->globalPos()); 0133 } 0134 0135 void EntryIconView::slotSortMenuActivated(QAction* action_) { 0136 Data::FieldPtr field = action_->data().value<Data::FieldPtr>(); 0137 Q_ASSERT(field); 0138 if(!field) { 0139 return; 0140 } 0141 // EntryIconModel is a proxy to EntryModel which uses the field list as the full set of columns 0142 // find which columns matches the field and sort on that column 0143 for(int i = 0; i < model()->columnCount(); ++i) { 0144 if(model()->headerData(i, Qt::Horizontal, FieldPtrRole).value<Data::FieldPtr>() == field) { 0145 model()->sort(i); 0146 break; 0147 } 0148 } 0149 } 0150 0151 void EntryIconView::slotOpenUrlMenuActivated(QAction* action_/*=0*/) { 0152 if(!action_) { 0153 return; 0154 } 0155 const QString link = action_->data().toString(); 0156 if(!link.isEmpty()) { 0157 QDesktopServices::openUrl(Kernel::self()->URL().resolved(QUrl::fromUserInput(link))); 0158 } 0159 } 0160 0161 void EntryIconView::updateModelColumn() { 0162 //default model column is 0 0163 int modelColumn = 0; 0164 // iterate over model columns, find the one whose name is "title" 0165 for(int ncol = 0; ncol < model()->columnCount(); ++ncol) { 0166 Data::FieldPtr field = model()->headerData(ncol, Qt::Horizontal, FieldPtrRole).value<Data::FieldPtr>(); 0167 if(field && field->name() == QLatin1String("title")) { 0168 modelColumn = ncol; 0169 break; 0170 } 0171 } 0172 setModelColumn(modelColumn); 0173 }