Warning, file /pim/mailcommon/src/widgets/favoritecollectionwidget.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 0003 SPDX-FileCopyrightText: 2012-2024 Laurent Montel <montel@kde.org> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "favoritecollectionwidget.h" 0009 #include "kernel/mailkernel.h" 0010 #include "mailcommonsettings_base.h" 0011 0012 #include <MessageCore/MessageCoreSettings> 0013 0014 #include <Akonadi/CollectionStatisticsDelegate> 0015 #include <KActionCollection> 0016 #include <KActionMenu> 0017 #include <KLocalizedString> 0018 #include <KXMLGUIClient> 0019 0020 #include <QActionGroup> 0021 #include <QApplication> 0022 #include <QFontDatabase> 0023 #include <QMimeData> 0024 #include <QMouseEvent> 0025 #include <QPainter> 0026 0027 using namespace MailCommon; 0028 0029 class Q_DECL_HIDDEN FavoriteCollectionWidget::FavoriteCollectionWidgetPrivate 0030 { 0031 public: 0032 FavoriteCollectionWidgetPrivate() = default; 0033 0034 QColor textColor; 0035 QAction *listMode = nullptr; 0036 QAction *iconMode = nullptr; 0037 MailCommonSettings *settings = nullptr; 0038 Akonadi::CollectionStatisticsDelegate *delegate = nullptr; 0039 }; 0040 0041 FavoriteCollectionWidget::FavoriteCollectionWidget(MailCommon::MailCommonSettings *settings, KXMLGUIClient *xmlGuiClient, QWidget *parent) 0042 : Akonadi::EntityListView(xmlGuiClient, parent) 0043 , d(new FavoriteCollectionWidgetPrivate) 0044 { 0045 d->settings = settings; 0046 setFocusPolicy(Qt::NoFocus); 0047 0048 d->delegate = new Akonadi::CollectionStatisticsDelegate(this); 0049 d->delegate->setProgressAnimationEnabled(true); 0050 0051 setItemDelegate(d->delegate); 0052 0053 d->delegate->setUnreadCountShown(true); 0054 0055 readConfig(); 0056 0057 createMenu(xmlGuiClient->actionCollection()); 0058 } 0059 0060 FavoriteCollectionWidget::~FavoriteCollectionWidget() = default; 0061 0062 void FavoriteCollectionWidget::updatePalette() 0063 { 0064 d->delegate->updatePalette(); 0065 } 0066 0067 void FavoriteCollectionWidget::mousePressEvent(QMouseEvent *e) 0068 { 0069 const bool buttonPressedIsMiddle = (e->button() == Qt::MiddleButton); 0070 Q_EMIT newTabRequested(buttonPressedIsMiddle); 0071 Akonadi::EntityListView::mousePressEvent(e); 0072 } 0073 0074 void FavoriteCollectionWidget::updateMode() 0075 { 0076 switch (viewMode()) { 0077 case ListMode: 0078 d->listMode->setChecked(true); 0079 d->iconMode->setChecked(false); 0080 break; 0081 case IconMode: 0082 d->listMode->setChecked(false); 0083 d->iconMode->setChecked(true); 0084 break; 0085 } 0086 } 0087 0088 void FavoriteCollectionWidget::createMenu(KActionCollection *ac) 0089 { 0090 auto iconSizeMenu = new KActionMenu(i18n("Icon size"), this); 0091 ac->addAction(QStringLiteral("favorite_icon_size"), iconSizeMenu); 0092 0093 static const int icon_sizes[] = {16, 22, 32 /*, 48, 64, 128 */}; 0094 0095 auto grp = new QActionGroup(iconSizeMenu); 0096 QAction *act = nullptr; 0097 for (int i : icon_sizes) { 0098 act = new QAction(QStringLiteral("%1x%2").arg(i).arg(i), iconSizeMenu); 0099 iconSizeMenu->addAction(act); 0100 act->setCheckable(true); 0101 grp->addAction(act); 0102 if (iconSize().width() == i) { 0103 act->setChecked(true); 0104 } 0105 act->setData(QVariant(i)); 0106 connect(act, &QAction::triggered, this, &FavoriteCollectionWidget::slotChangeIconSize); 0107 } 0108 0109 auto modeFavoriteMenu = new KActionMenu(i18n("Mode"), this); 0110 ac->addAction(QStringLiteral("favorite_mode"), modeFavoriteMenu); 0111 0112 grp = new QActionGroup(modeFavoriteMenu); 0113 d->listMode = new QAction(i18n("List Mode"), modeFavoriteMenu); 0114 modeFavoriteMenu->addAction(d->listMode); 0115 d->listMode->setCheckable(true); 0116 grp->addAction(d->listMode); 0117 if (viewMode() == ListMode) { 0118 d->listMode->setChecked(true); 0119 } 0120 d->listMode->setData(QVariant(MailCommon::MailCommonSettings::EnumFavoriteCollectionViewMode::ListMode)); 0121 connect(d->listMode, &QAction::triggered, this, &FavoriteCollectionWidget::slotChangeMode); 0122 0123 d->iconMode = new QAction(i18n("Icon Mode"), modeFavoriteMenu); 0124 modeFavoriteMenu->addAction(d->iconMode); 0125 grp->addAction(d->iconMode); 0126 d->iconMode->setCheckable(true); 0127 if (viewMode() == IconMode) { 0128 d->iconMode->setChecked(true); 0129 } 0130 d->iconMode->setData(QVariant(MailCommon::MailCommonSettings::EnumFavoriteCollectionViewMode::IconMode)); 0131 connect(d->iconMode, &QAction::triggered, this, &FavoriteCollectionWidget::slotChangeMode); 0132 } 0133 0134 void FavoriteCollectionWidget::slotChangeMode(bool) 0135 { 0136 auto act = qobject_cast<QAction *>(sender()); 0137 if (!act) { 0138 return; 0139 } 0140 0141 QVariant data = act->data(); 0142 0143 bool ok; 0144 const int mode = data.toInt(&ok); 0145 if (!ok) { 0146 return; 0147 } 0148 0149 switch (mode) { 0150 case MailCommon::MailCommonSettings::EnumFavoriteCollectionViewMode::IconMode: 0151 changeViewMode(IconMode); 0152 break; 0153 case MailCommon::MailCommonSettings::EnumFavoriteCollectionViewMode::ListMode: 0154 changeViewMode(ListMode); 0155 break; 0156 } 0157 0158 d->settings->setFavoriteCollectionViewMode(mode); 0159 d->settings->save(); 0160 } 0161 0162 void FavoriteCollectionWidget::changeViewMode(QListView::ViewMode mode) 0163 { 0164 setViewMode(mode); 0165 setDragEnabled(true); 0166 setAcceptDrops(true); 0167 } 0168 0169 void FavoriteCollectionWidget::slotChangeIconSize(bool) 0170 { 0171 auto act = qobject_cast<QAction *>(sender()); 0172 if (!act) { 0173 return; 0174 } 0175 0176 QVariant data = act->data(); 0177 0178 bool ok; 0179 const int size = data.toInt(&ok); 0180 if (!ok) { 0181 return; 0182 } 0183 0184 const QSize newIconSize(QSize(size, size)); 0185 if (newIconSize == iconSize()) { 0186 return; 0187 } 0188 setIconSize(newIconSize); 0189 d->settings->setIconSize(iconSize().width()); 0190 d->settings->save(); 0191 } 0192 0193 void FavoriteCollectionWidget::slotGeneralPaletteChanged() 0194 { 0195 const QPalette palette = viewport()->palette(); 0196 QColor color = palette.text().color(); 0197 color.setAlpha(128); 0198 d->textColor = color; 0199 } 0200 0201 void FavoriteCollectionWidget::slotGeneralFontChanged() 0202 { 0203 // Custom/System font support 0204 if (MessageCore::MessageCoreSettings::self()->useDefaultFonts()) { 0205 setFont(QFontDatabase::systemFont(QFontDatabase::GeneralFont)); 0206 } 0207 } 0208 0209 void FavoriteCollectionWidget::readConfig() 0210 { 0211 setFont(QFontDatabase::systemFont(QFontDatabase::GeneralFont)); 0212 0213 int iIconSize = d->settings->iconSize(); 0214 if (iIconSize < 16 || iIconSize > 32) { 0215 iIconSize = 22; 0216 } 0217 setIconSize(QSize(iIconSize, iIconSize)); 0218 } 0219 0220 void FavoriteCollectionWidget::paintEvent(QPaintEvent *event) 0221 { 0222 if (!model() || model()->rowCount() == 0) { 0223 QPainter p(viewport()); 0224 0225 QFont font = p.font(); 0226 font.setItalic(true); 0227 p.setFont(font); 0228 0229 if (!d->textColor.isValid()) { 0230 slotGeneralPaletteChanged(); 0231 } 0232 p.setPen(d->textColor); 0233 0234 p.drawText(QRect(0, 0, width(), height()), Qt::AlignCenter, i18n("Drop your favorite folders here...")); 0235 } else { 0236 Akonadi::EntityListView::paintEvent(event); 0237 } 0238 } 0239 0240 static bool isCollection(const QMimeData *mimeData) 0241 { 0242 const QList<QUrl> urls = mimeData->urls(); 0243 for (const QUrl &url : urls) { 0244 const Akonadi::Collection collection = Akonadi::Collection::fromUrl(url); 0245 if (collection.isValid()) { 0246 return true; 0247 } 0248 } 0249 return false; 0250 } 0251 0252 bool FavoriteCollectionWidget::acceptEvent(QDropEvent *event) const 0253 { 0254 const bool draggingCollection = isCollection(event->mimeData()); 0255 const bool droppingOnCollection = dropIndicatorPosition() == QAbstractItemView::OnItem; 0256 if (event->source() == this) { 0257 if (draggingCollection && !droppingOnCollection) { // Re-ordering favorites 0258 return true; 0259 } 0260 } else { 0261 if ((draggingCollection && !droppingOnCollection) // Adding a new favorite collection 0262 || (!draggingCollection && droppingOnCollection)) { // Dropping emails onto a favorite collection 0263 return true; 0264 } 0265 } 0266 event->ignore(); 0267 return false; 0268 } 0269 0270 void FavoriteCollectionWidget::dragEnterEvent(QDragEnterEvent *event) 0271 { 0272 if (event->source() == this) { 0273 QListView::dragEnterEvent(event); // Re-ordering favourites 0274 } else { 0275 Akonadi::EntityListView::dragEnterEvent(event); // Dropping emails onto a favorite collection 0276 } 0277 } 0278 0279 void FavoriteCollectionWidget::dragMoveEvent(QDragMoveEvent *event) 0280 { 0281 // We need to ask QListView to update dropIndicatorPosition() first... 0282 QListView::dragMoveEvent(event); 0283 if (event->source() == this) { 0284 if (acceptEvent(event)) { 0285 event->setDropAction(Qt::MoveAction); 0286 event->accept(); // Re-ordering favourites 0287 } 0288 } else { 0289 if (acceptEvent(event)) { 0290 Akonadi::EntityListView::dragMoveEvent(event); // Dropping emails onto a favorite collection 0291 } 0292 } 0293 } 0294 0295 void FavoriteCollectionWidget::dropEvent(QDropEvent *event) 0296 { 0297 if (event->source() == this) { 0298 if (acceptEvent(event)) { 0299 QListView::dropEvent(event); // Re-ordering favourites 0300 } 0301 } else { 0302 if (acceptEvent(event)) { 0303 if (dropIndicatorPosition() == QAbstractItemView::OnItem) { 0304 Akonadi::EntityListView::dropEvent(event); // Dropping emails onto a favorite collection 0305 } else { 0306 QListView::dropEvent(event); // Add new favorite 0307 } 0308 } 0309 } 0310 } 0311 0312 void FavoriteCollectionWidget::startDrag(Qt::DropActions supportedActions) 0313 { 0314 // skip EntityListView logic (we want to reorder favorites, not trigger moving/copying of actual folders) 0315 QListView::startDrag(supportedActions); 0316 } 0317 0318 bool FavoriteCollectionWidget::event(QEvent *e) 0319 { 0320 if (e->type() == QEvent::ApplicationPaletteChange) { 0321 updatePalette(); 0322 } 0323 return Akonadi::EntityListView::event(e); 0324 } 0325 0326 #include "moc_favoritecollectionwidget.cpp"