Mailcommon

favoritecollectionwidget.cpp
1 /*
2 
3  SPDX-FileCopyrightText: 2012-2022 Laurent Montel <[email protected]>
4 
5  SPDX-License-Identifier: GPL-2.0-or-later
6 */
7 
8 #include "favoritecollectionwidget.h"
9 #include "kernel/mailkernel.h"
10 #include "mailcommonsettings_base.h"
11 
12 #include <MessageCore/MessageCoreSettings>
13 
14 #include <Akonadi/CollectionStatisticsDelegate>
15 #include <KActionCollection>
16 #include <KActionMenu>
17 #include <KLocalizedString>
18 #include <KXMLGUIClient>
19 
20 #include <QActionGroup>
21 #include <QApplication>
22 #include <QFontDatabase>
23 #include <QMimeData>
24 #include <QMouseEvent>
25 #include <QPainter>
26 
27 using namespace MailCommon;
28 
29 class Q_DECL_HIDDEN FavoriteCollectionWidget::FavoriteCollectionWidgetPrivate
30 {
31 public:
32  FavoriteCollectionWidgetPrivate() = default;
33 
34  QColor textColor;
35  QAction *listMode = nullptr;
36  QAction *iconMode = nullptr;
37  MailCommonSettings *settings = nullptr;
38  Akonadi::CollectionStatisticsDelegate *delegate = nullptr;
39 };
40 
41 FavoriteCollectionWidget::FavoriteCollectionWidget(MailCommon::MailCommonSettings *settings, KXMLGUIClient *xmlGuiClient, QWidget *parent)
42  : Akonadi::EntityListView(xmlGuiClient, parent)
43  , d(new FavoriteCollectionWidgetPrivate)
44 {
45  d->settings = settings;
46  setFocusPolicy(Qt::NoFocus);
47 
48  d->delegate = new Akonadi::CollectionStatisticsDelegate(this);
49  d->delegate->setProgressAnimationEnabled(true);
50 
51  setItemDelegate(d->delegate);
52 
53  d->delegate->setUnreadCountShown(true);
54 
55  readConfig();
56 
57  createMenu(xmlGuiClient->actionCollection());
58 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
59  connect(qApp, &QApplication::paletteChanged, this, &FavoriteCollectionWidget::updatePalette);
60 #endif
61 }
62 
63 FavoriteCollectionWidget::~FavoriteCollectionWidget() = default;
64 
65 void FavoriteCollectionWidget::updatePalette()
66 {
67  d->delegate->updatePalette();
68 }
69 
70 void FavoriteCollectionWidget::mousePressEvent(QMouseEvent *e)
71 {
72  const bool buttonPressedIsMiddle = (e->button() == Qt::MiddleButton);
73  Q_EMIT newTabRequested(buttonPressedIsMiddle);
75 }
76 
77 void FavoriteCollectionWidget::updateMode()
78 {
79  switch (viewMode()) {
80  case ListMode:
81  d->listMode->setChecked(true);
82  d->iconMode->setChecked(false);
83  break;
84  case IconMode:
85  d->listMode->setChecked(false);
86  d->iconMode->setChecked(true);
87  break;
88  }
89 }
90 
91 void FavoriteCollectionWidget::createMenu(KActionCollection *ac)
92 {
93  auto iconSizeMenu = new KActionMenu(i18n("Icon size"), this);
94  ac->addAction(QStringLiteral("favorite_icon_size"), iconSizeMenu);
95 
96  static const int icon_sizes[] = {16, 22, 32 /*, 48, 64, 128 */};
97 
98  auto grp = new QActionGroup(iconSizeMenu);
99  QAction *act = nullptr;
100  for (int i : icon_sizes) {
101  act = new QAction(QStringLiteral("%1x%2").arg(i).arg(i), iconSizeMenu);
102  iconSizeMenu->addAction(act);
103  act->setCheckable(true);
104  grp->addAction(act);
105  if (iconSize().width() == i) {
106  act->setChecked(true);
107  }
108  act->setData(QVariant(i));
109  connect(act, &QAction::triggered, this, &FavoriteCollectionWidget::slotChangeIconSize);
110  }
111 
112  auto modeFavoriteMenu = new KActionMenu(i18n("Mode"), this);
113  ac->addAction(QStringLiteral("favorite_mode"), modeFavoriteMenu);
114 
115  grp = new QActionGroup(modeFavoriteMenu);
116  d->listMode = new QAction(i18n("List Mode"), modeFavoriteMenu);
117  modeFavoriteMenu->addAction(d->listMode);
118  d->listMode->setCheckable(true);
119  grp->addAction(d->listMode);
120  if (viewMode() == ListMode) {
121  d->listMode->setChecked(true);
122  }
123  d->listMode->setData(QVariant(MailCommon::MailCommonSettings::EnumFavoriteCollectionViewMode::ListMode));
124  connect(d->listMode, &QAction::triggered, this, &FavoriteCollectionWidget::slotChangeMode);
125 
126  d->iconMode = new QAction(i18n("Icon Mode"), modeFavoriteMenu);
127  modeFavoriteMenu->addAction(d->iconMode);
128  grp->addAction(d->iconMode);
129  d->iconMode->setCheckable(true);
130  if (viewMode() == IconMode) {
131  d->iconMode->setChecked(true);
132  }
133  d->iconMode->setData(QVariant(MailCommon::MailCommonSettings::EnumFavoriteCollectionViewMode::IconMode));
134  connect(d->iconMode, &QAction::triggered, this, &FavoriteCollectionWidget::slotChangeMode);
135 }
136 
137 void FavoriteCollectionWidget::slotChangeMode(bool)
138 {
139  auto act = qobject_cast<QAction *>(sender());
140  if (!act) {
141  return;
142  }
143 
144  QVariant data = act->data();
145 
146  bool ok;
147  const int mode = data.toInt(&ok);
148  if (!ok) {
149  return;
150  }
151 
152  switch (mode) {
153  case MailCommon::MailCommonSettings::EnumFavoriteCollectionViewMode::IconMode:
154  changeViewMode(IconMode);
155  break;
156  case MailCommon::MailCommonSettings::EnumFavoriteCollectionViewMode::ListMode:
157  changeViewMode(ListMode);
158  break;
159  }
160 
161  d->settings->setFavoriteCollectionViewMode(mode);
162  d->settings->save();
163 }
164 
165 void FavoriteCollectionWidget::changeViewMode(QListView::ViewMode mode)
166 {
167  setViewMode(mode);
168  setDragEnabled(true);
169  setAcceptDrops(true);
170 }
171 
172 void FavoriteCollectionWidget::slotChangeIconSize(bool)
173 {
174  auto act = qobject_cast<QAction *>(sender());
175  if (!act) {
176  return;
177  }
178 
179  QVariant data = act->data();
180 
181  bool ok;
182  const int size = data.toInt(&ok);
183  if (!ok) {
184  return;
185  }
186 
187  const QSize newIconSize(QSize(size, size));
188  if (newIconSize == iconSize()) {
189  return;
190  }
191  setIconSize(newIconSize);
192  d->settings->setIconSize(iconSize().width());
193  d->settings->save();
194 }
195 
196 void FavoriteCollectionWidget::slotGeneralPaletteChanged()
197 {
198  const QPalette palette = viewport()->palette();
199  QColor color = palette.text().color();
200  color.setAlpha(128);
201  d->textColor = color;
202 }
203 
204 void FavoriteCollectionWidget::slotGeneralFontChanged()
205 {
206  // Custom/System font support
207  if (MessageCore::MessageCoreSettings::self()->useDefaultFonts()) {
209  }
210 }
211 
212 void FavoriteCollectionWidget::readConfig()
213 {
215 
216  int iIconSize = d->settings->iconSize();
217  if (iIconSize < 16 || iIconSize > 32) {
218  iIconSize = 22;
219  }
220  setIconSize(QSize(iIconSize, iIconSize));
221 }
222 
223 void FavoriteCollectionWidget::paintEvent(QPaintEvent *event)
224 {
225  if (!model() || model()->rowCount() == 0) {
226  QPainter p(viewport());
227 
228  QFont font = p.font();
229  font.setItalic(true);
230  p.setFont(font);
231 
232  if (!d->textColor.isValid()) {
233  slotGeneralPaletteChanged();
234  }
235  p.setPen(d->textColor);
236 
237  p.drawText(QRect(0, 0, width(), height()), Qt::AlignCenter, i18n("Drop your favorite folders here..."));
238  } else {
240  }
241 }
242 
243 static bool isCollection(const QMimeData *mimeData)
244 {
245  const QList<QUrl> urls = mimeData->urls();
246  for (const QUrl &url : urls) {
247  const Akonadi::Collection collection = Akonadi::Collection::fromUrl(url);
248  if (collection.isValid()) {
249  return true;
250  }
251  }
252  return false;
253 }
254 
255 bool FavoriteCollectionWidget::acceptEvent(QDropEvent *event) const
256 {
257  const bool draggingCollection = isCollection(event->mimeData());
258  const bool droppingOnCollection = dropIndicatorPosition() == QAbstractItemView::OnItem;
259  if (event->source() == this) {
260  if (draggingCollection && !droppingOnCollection) { // Re-ordering favorites
261  return true;
262  }
263  } else {
264  if ((draggingCollection && !droppingOnCollection) // Adding a new favorite collection
265  || (!draggingCollection && droppingOnCollection)) { // Dropping emails onto a favorite collection
266  return true;
267  }
268  }
269  event->ignore();
270  return false;
271 }
272 
273 void FavoriteCollectionWidget::dragEnterEvent(QDragEnterEvent *event)
274 {
275  if (event->source() == this) {
276  QListView::dragEnterEvent(event); // Re-ordering favourites
277  } else {
278  Akonadi::EntityListView::dragEnterEvent(event); // Dropping emails onto a favorite collection
279  }
280 }
281 
282 void FavoriteCollectionWidget::dragMoveEvent(QDragMoveEvent *event)
283 {
284  // We need to ask QListView to update dropIndicatorPosition() first...
286  if (event->source() == this) {
287  if (acceptEvent(event)) {
288  event->setDropAction(Qt::MoveAction);
289  event->accept(); // Re-ordering favourites
290  }
291  } else {
292  if (acceptEvent(event)) {
293  Akonadi::EntityListView::dragMoveEvent(event); // Dropping emails onto a favorite collection
294  }
295  }
296 }
297 
298 void FavoriteCollectionWidget::dropEvent(QDropEvent *event)
299 {
300  if (event->source() == this) {
301  if (acceptEvent(event)) {
302  QListView::dropEvent(event); // Re-ordering favourites
303  }
304  } else {
305  if (acceptEvent(event)) {
307  Akonadi::EntityListView::dropEvent(event); // Dropping emails onto a favorite collection
308  } else {
309  QListView::dropEvent(event); // Add new favorite
310  }
311  }
312  }
313 }
314 
315 void FavoriteCollectionWidget::startDrag(Qt::DropActions supportedActions)
316 {
317  // skip EntityListView logic (we want to reorder favorites, not trigger moving/copying of actual folders)
318  QListView::startDrag(supportedActions);
319 }
320 
321 bool FavoriteCollectionWidget::event(QEvent *e)
322 {
323 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
325  updatePalette();
326  }
327 #endif
329 }
virtual bool event(QEvent *e) override
void paletteChanged(const QPalette &palette)
QAction * addAction(const QString &name, const QObject *receiver=nullptr, const char *member=nullptr)
AlignCenter
QAbstractItemView::DropIndicatorPosition dropIndicatorPosition() const const
static Collection fromUrl(const QUrl &url)
ApplicationPaletteChange
Q_EMITQ_EMIT
Qt::MouseButton button() const const
QAbstractItemModel * model() const const
void readConfig()
void setFont(const QFont &)
void setDragEnabled(bool enable)
QFont systemFont(QFontDatabase::SystemFont type)
QObject * sender() const const
MiddleButton
virtual void mousePressEvent(QMouseEvent *event) override
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
virtual void dragMoveEvent(QDragMoveEvent *e) override
QString i18n(const char *text, const TYPE &arg...)
virtual void dropEvent(QDropEvent *e) override
virtual void startDrag(Qt::DropActions supportedActions) override
void setAlpha(int alpha)
int toInt(bool *ok) const const
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
void setAcceptDrops(bool on)
virtual void dragEnterEvent(QDragEnterEvent *event) override
void setCheckable(bool)
The FavoriteCollectionWidget class.
QVariant data() const const
void setData(const QVariant &userData)
QList< QUrl > urls() const const
MoveAction
void triggered(bool checked)
virtual KActionCollection * actionCollection() const
QEvent::Type type() const const
virtual void paintEvent(QPaintEvent *e) override
bool isValid() const
void setChecked(bool)
QWidget * viewport() const const
The filter dialog.
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sat Oct 1 2022 04:00:52 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.