Mailcommon

favoritecollectionwidget.cpp
1 /*
2 
3  SPDX-FileCopyrightText: 2012-2023 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 }
59 
60 FavoriteCollectionWidget::~FavoriteCollectionWidget() = default;
61 
62 void FavoriteCollectionWidget::updatePalette()
63 {
64  d->delegate->updatePalette();
65 }
66 
67 void FavoriteCollectionWidget::mousePressEvent(QMouseEvent *e)
68 {
69  const bool buttonPressedIsMiddle = (e->button() == Qt::MiddleButton);
70  Q_EMIT newTabRequested(buttonPressedIsMiddle);
72 }
73 
74 void FavoriteCollectionWidget::updateMode()
75 {
76  switch (viewMode()) {
77  case ListMode:
78  d->listMode->setChecked(true);
79  d->iconMode->setChecked(false);
80  break;
81  case IconMode:
82  d->listMode->setChecked(false);
83  d->iconMode->setChecked(true);
84  break;
85  }
86 }
87 
88 void FavoriteCollectionWidget::createMenu(KActionCollection *ac)
89 {
90  auto iconSizeMenu = new KActionMenu(i18n("Icon size"), this);
91  ac->addAction(QStringLiteral("favorite_icon_size"), iconSizeMenu);
92 
93  static const int icon_sizes[] = {16, 22, 32 /*, 48, 64, 128 */};
94 
95  auto grp = new QActionGroup(iconSizeMenu);
96  QAction *act = nullptr;
97  for (int i : icon_sizes) {
98  act = new QAction(QStringLiteral("%1x%2").arg(i).arg(i), iconSizeMenu);
99  iconSizeMenu->addAction(act);
100  act->setCheckable(true);
101  grp->addAction(act);
102  if (iconSize().width() == i) {
103  act->setChecked(true);
104  }
105  act->setData(QVariant(i));
106  connect(act, &QAction::triggered, this, &FavoriteCollectionWidget::slotChangeIconSize);
107  }
108 
109  auto modeFavoriteMenu = new KActionMenu(i18n("Mode"), this);
110  ac->addAction(QStringLiteral("favorite_mode"), modeFavoriteMenu);
111 
112  grp = new QActionGroup(modeFavoriteMenu);
113  d->listMode = new QAction(i18n("List Mode"), modeFavoriteMenu);
114  modeFavoriteMenu->addAction(d->listMode);
115  d->listMode->setCheckable(true);
116  grp->addAction(d->listMode);
117  if (viewMode() == ListMode) {
118  d->listMode->setChecked(true);
119  }
120  d->listMode->setData(QVariant(MailCommon::MailCommonSettings::EnumFavoriteCollectionViewMode::ListMode));
121  connect(d->listMode, &QAction::triggered, this, &FavoriteCollectionWidget::slotChangeMode);
122 
123  d->iconMode = new QAction(i18n("Icon Mode"), modeFavoriteMenu);
124  modeFavoriteMenu->addAction(d->iconMode);
125  grp->addAction(d->iconMode);
126  d->iconMode->setCheckable(true);
127  if (viewMode() == IconMode) {
128  d->iconMode->setChecked(true);
129  }
130  d->iconMode->setData(QVariant(MailCommon::MailCommonSettings::EnumFavoriteCollectionViewMode::IconMode));
131  connect(d->iconMode, &QAction::triggered, this, &FavoriteCollectionWidget::slotChangeMode);
132 }
133 
134 void FavoriteCollectionWidget::slotChangeMode(bool)
135 {
136  auto act = qobject_cast<QAction *>(sender());
137  if (!act) {
138  return;
139  }
140 
141  QVariant data = act->data();
142 
143  bool ok;
144  const int mode = data.toInt(&ok);
145  if (!ok) {
146  return;
147  }
148 
149  switch (mode) {
150  case MailCommon::MailCommonSettings::EnumFavoriteCollectionViewMode::IconMode:
151  changeViewMode(IconMode);
152  break;
153  case MailCommon::MailCommonSettings::EnumFavoriteCollectionViewMode::ListMode:
154  changeViewMode(ListMode);
155  break;
156  }
157 
158  d->settings->setFavoriteCollectionViewMode(mode);
159  d->settings->save();
160 }
161 
162 void FavoriteCollectionWidget::changeViewMode(QListView::ViewMode mode)
163 {
164  setViewMode(mode);
165  setDragEnabled(true);
166  setAcceptDrops(true);
167 }
168 
169 void FavoriteCollectionWidget::slotChangeIconSize(bool)
170 {
171  auto act = qobject_cast<QAction *>(sender());
172  if (!act) {
173  return;
174  }
175 
176  QVariant data = act->data();
177 
178  bool ok;
179  const int size = data.toInt(&ok);
180  if (!ok) {
181  return;
182  }
183 
184  const QSize newIconSize(QSize(size, size));
185  if (newIconSize == iconSize()) {
186  return;
187  }
188  setIconSize(newIconSize);
189  d->settings->setIconSize(iconSize().width());
190  d->settings->save();
191 }
192 
193 void FavoriteCollectionWidget::slotGeneralPaletteChanged()
194 {
195  const QPalette palette = viewport()->palette();
196  QColor color = palette.text().color();
197  color.setAlpha(128);
198  d->textColor = color;
199 }
200 
201 void FavoriteCollectionWidget::slotGeneralFontChanged()
202 {
203  // Custom/System font support
204  if (MessageCore::MessageCoreSettings::self()->useDefaultFonts()) {
206  }
207 }
208 
209 void FavoriteCollectionWidget::readConfig()
210 {
212 
213  int iIconSize = d->settings->iconSize();
214  if (iIconSize < 16 || iIconSize > 32) {
215  iIconSize = 22;
216  }
217  setIconSize(QSize(iIconSize, iIconSize));
218 }
219 
220 void FavoriteCollectionWidget::paintEvent(QPaintEvent *event)
221 {
222  if (!model() || model()->rowCount() == 0) {
223  QPainter p(viewport());
224 
225  QFont font = p.font();
226  font.setItalic(true);
227  p.setFont(font);
228 
229  if (!d->textColor.isValid()) {
230  slotGeneralPaletteChanged();
231  }
232  p.setPen(d->textColor);
233 
234  p.drawText(QRect(0, 0, width(), height()), Qt::AlignCenter, i18n("Drop your favorite folders here..."));
235  } else {
237  }
238 }
239 
240 static bool isCollection(const QMimeData *mimeData)
241 {
242  const QList<QUrl> urls = mimeData->urls();
243  for (const QUrl &url : urls) {
244  const Akonadi::Collection collection = Akonadi::Collection::fromUrl(url);
245  if (collection.isValid()) {
246  return true;
247  }
248  }
249  return false;
250 }
251 
252 bool FavoriteCollectionWidget::acceptEvent(QDropEvent *event) const
253 {
254  const bool draggingCollection = isCollection(event->mimeData());
255  const bool droppingOnCollection = dropIndicatorPosition() == QAbstractItemView::OnItem;
256  if (event->source() == this) {
257  if (draggingCollection && !droppingOnCollection) { // Re-ordering favorites
258  return true;
259  }
260  } else {
261  if ((draggingCollection && !droppingOnCollection) // Adding a new favorite collection
262  || (!draggingCollection && droppingOnCollection)) { // Dropping emails onto a favorite collection
263  return true;
264  }
265  }
266  event->ignore();
267  return false;
268 }
269 
270 void FavoriteCollectionWidget::dragEnterEvent(QDragEnterEvent *event)
271 {
272  if (event->source() == this) {
273  QListView::dragEnterEvent(event); // Re-ordering favourites
274  } else {
275  Akonadi::EntityListView::dragEnterEvent(event); // Dropping emails onto a favorite collection
276  }
277 }
278 
279 void FavoriteCollectionWidget::dragMoveEvent(QDragMoveEvent *event)
280 {
281  // We need to ask QListView to update dropIndicatorPosition() first...
283  if (event->source() == this) {
284  if (acceptEvent(event)) {
285  event->setDropAction(Qt::MoveAction);
286  event->accept(); // Re-ordering favourites
287  }
288  } else {
289  if (acceptEvent(event)) {
290  Akonadi::EntityListView::dragMoveEvent(event); // Dropping emails onto a favorite collection
291  }
292  }
293 }
294 
295 void FavoriteCollectionWidget::dropEvent(QDropEvent *event)
296 {
297  if (event->source() == this) {
298  if (acceptEvent(event)) {
299  QListView::dropEvent(event); // Re-ordering favourites
300  }
301  } else {
302  if (acceptEvent(event)) {
304  Akonadi::EntityListView::dropEvent(event); // Dropping emails onto a favorite collection
305  } else {
306  QListView::dropEvent(event); // Add new favorite
307  }
308  }
309  }
310 }
311 
312 void FavoriteCollectionWidget::startDrag(Qt::DropActions supportedActions)
313 {
314  // skip EntityListView logic (we want to reorder favorites, not trigger moving/copying of actual folders)
315  QListView::startDrag(supportedActions);
316 }
317 
318 bool FavoriteCollectionWidget::event(QEvent *e)
319 {
321  updatePalette();
322  }
324 }
325 
326 #include "moc_favoritecollectionwidget.cpp"
virtual bool event(QEvent *e) override
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)
KActionMenu * createMenu(KColorSchemeManager *manager, QObject *parent=nullptr)
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-2023 The KDE developers.
Generated on Tue Oct 3 2023 04:00:32 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.