• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • pim API Reference
  • KDE Home
  • Contact Us
 

kmail/src

  • kde-4.x
  • pim
  • kmail
  • src
  • configuredialog
configureappearancepage.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2013-2019 Montel Laurent <[email protected]>
3 
4  This program is free software; you can redistribute it and/or modify it
5  under the terms of the GNU General Public License, version 2, as
6  published by the Free Software Foundation.
7 
8  This program is distributed in the hope that it will be useful, but
9  WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License along
14  with this program; if not, write to the Free Software Foundation, Inc.,
15  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #include "configureappearancepage.h"
19 #include "PimCommon/ConfigureImmutableWidgetUtils"
20 using namespace PimCommon::ConfigureImmutableWidgetUtils;
21 #include "configuredialog/colorlistbox.h"
22 #include "messagelist/aggregationcombobox.h"
23 #include "messagelist/aggregationconfigbutton.h"
24 #include "messagelist/themecombobox.h"
25 #include "messagelist/themeconfigbutton.h"
26 #include "messagelistsettings.h"
27 #include "MailCommon/TagWidget"
28 #include "MailCommon/Tag"
29 #include "kmkernel.h"
30 
31 #include "util.h"
32 #include "MailCommon/FolderTreeWidget"
33 
34 #include "kmmainwidget.h"
35 
36 #include "mailcommonsettings_base.h"
37 
38 #include "MessageViewer/ConfigureWidget"
39 #include "messageviewer/messageviewersettings.h"
40 
41 #include "messagelist/messagelistutil.h"
42 #include <MessageCore/MessageCoreSettings>
43 #include "MessageCore/MessageCoreUtil"
44 #include "settings/kmailsettings.h"
45 
46 #include "MailCommon/MailUtil"
47 
48 #include <AkonadiCore/Tag>
49 #include <AkonadiCore/TagFetchJob>
50 #include <AkonadiCore/TagFetchScope>
51 #include <AkonadiCore/TagDeleteJob>
52 #include <AkonadiCore/TagCreateJob>
53 #include <AkonadiCore/TagAttribute>
54 #include <AkonadiCore/TagModifyJob>
55 
56 #include <KIconButton>
57 #include <KLocalizedString>
58 #include <KColorScheme>
59 #include <KSeparator>
60 #include <KFontChooser>
61 #include <QHBoxLayout>
62 #include <KMessageBox>
63 #include <KKeySequenceWidget>
64 #include <KLineEdit>
65 #include <QIcon>
66 #include "kmail_debug.h"
67 
68 #include <kmime/kmime_dateformatter.h>
69 using KMime::DateFormatter;
70 
71 #include <QWhatsThis>
72 #include <QButtonGroup>
73 #include <QSpinBox>
74 #include <QLabel>
75 #include <QFontDatabase>
76 #include <QGroupBox>
77 #include <QVBoxLayout>
78 #include <QRadioButton>
79 #include <QCheckBox>
80 using namespace MailCommon;
81 
82 QString AppearancePage::helpAnchor() const
83 {
84  return QStringLiteral("configure-appearance");
85 }
86 
87 AppearancePage::AppearancePage(QWidget *parent)
88  : ConfigModuleWithTabs(parent)
89 {
90  //
91  // "General" tab:
92  //
93  ReaderTab *readerTab = new ReaderTab();
94  addTab(readerTab, i18n("General"));
95  addConfig(MessageViewer::MessageViewerSettings::self(), readerTab);
96 
97  //
98  // "Fonts" tab:
99  //
100  FontsTab *fontsTab = new FontsTab();
101  addTab(fontsTab, i18n("Fonts"));
102 
103  //
104  // "Colors" tab:
105  //
106  ColorsTab *colorsTab = new ColorsTab();
107  addTab(colorsTab, i18n("Colors"));
108 
109  //
110  // "Layout" tab:
111  //
112  LayoutTab *layoutTab = new LayoutTab();
113  addTab(layoutTab, i18n("Layout"));
114 
115  //
116  // "Headers" tab:
117  //
118  HeadersTab *headersTab = new HeadersTab();
119  addTab(headersTab, i18n("Message List"));
120 
121  //
122  // "Message Tag" tab:
123  //
124  MessageTagTab *messageTagTab = new MessageTagTab();
125  addTab(messageTagTab, i18n("Message Tags"));
126 }
127 
128 QString AppearancePage::FontsTab::helpAnchor() const
129 {
130  return QStringLiteral("configure-appearance-fonts");
131 }
132 
133 static const struct {
134  const char *configName;
135  const char *displayName;
136  bool enableFamilyAndSize;
137  bool onlyFixed;
138 } fontNames[] = {
139  { "body-font", I18N_NOOP("Message Body"), true, false },
140  { "MessageListFont", I18N_NOOP("Message List"), true, false },
141  { "UnreadMessageFont", I18N_NOOP("Message List - Unread Messages"), false, false },
142  { "ImportantMessageFont", I18N_NOOP("Message List - Important Messages"), false, false },
143  { "TodoMessageFont", I18N_NOOP("Message List - Action Item Messages"), false, false },
144  { "fixed-font", I18N_NOOP("Fixed Width Font"), true, true },
145  { "composer-font", I18N_NOOP("Composer"), true, false },
146  { "print-font", I18N_NOOP("Printing Output"), true, false },
147 };
148 static const int numFontNames = sizeof fontNames / sizeof *fontNames;
149 
150 AppearancePageFontsTab::AppearancePageFontsTab(QWidget *parent)
151  : ConfigModuleTab(parent)
152  , mActiveFontIndex(-1)
153 {
154  assert(numFontNames == sizeof mFont / sizeof *mFont);
155 
156  // "Use custom fonts" checkbox, followed by <hr>
157  QVBoxLayout *vlay = new QVBoxLayout(this);
158  mCustomFontCheck = new QCheckBox(i18n("&Use custom fonts"), this);
159  vlay->addWidget(mCustomFontCheck);
160  vlay->addWidget(new KSeparator(Qt::Horizontal, this));
161  connect(mCustomFontCheck, &QCheckBox::stateChanged,
162  this, &ConfigModuleTab::slotEmitChanged);
163 
164  // "font location" combo box and label:
165  QHBoxLayout *hlay = new QHBoxLayout(); // inherites spacing
166  vlay->addLayout(hlay);
167  mFontLocationCombo = new QComboBox(this);
168  mFontLocationCombo->setEnabled(false); // !mCustomFontCheck->isChecked()
169 
170  QStringList fontDescriptions;
171  fontDescriptions.reserve(numFontNames);
172  for (int i = 0; i < numFontNames; ++i) {
173  fontDescriptions << i18n(fontNames[i].displayName);
174  }
175  mFontLocationCombo->addItems(fontDescriptions);
176 
177  QLabel *label = new QLabel(i18n("Apply &to:"), this);
178  label->setBuddy(mFontLocationCombo);
179  label->setEnabled(false); // since !mCustomFontCheck->isChecked()
180  hlay->addWidget(label);
181 
182  hlay->addWidget(mFontLocationCombo);
183  hlay->addStretch(10);
184  mFontChooser = new KFontChooser(this, KFontChooser::DisplayFrame,
185  QStringList(), 4);
186  mFontChooser->setEnabled(false); // since !mCustomFontCheck->isChecked()
187  vlay->addWidget(mFontChooser);
188  connect(mFontChooser, &KFontChooser::fontSelected,
189  this, &ConfigModuleTab::slotEmitChanged);
190 
191  // {en,dis}able widgets depending on the state of mCustomFontCheck:
192  connect(mCustomFontCheck, &QAbstractButton::toggled,
193  label, &QWidget::setEnabled);
194  connect(mCustomFontCheck, &QAbstractButton::toggled,
195  mFontLocationCombo, &QWidget::setEnabled);
196  connect(mCustomFontCheck, &QAbstractButton::toggled,
197  mFontChooser, &QWidget::setEnabled);
198  // load the right font settings into mFontChooser:
199  connect(mFontLocationCombo, qOverload<int>(&QComboBox::activated),
200  this, &AppearancePage::FontsTab::slotFontSelectorChanged);
201 }
202 
203 void AppearancePage::FontsTab::slotFontSelectorChanged(int index)
204 {
205  qCDebug(KMAIL_LOG) << "slotFontSelectorChanged() called";
206  if (index < 0 || index >= mFontLocationCombo->count()) {
207  return; // Should never happen, but it is better to check.
208  }
209 
210  // Save current fontselector setting before we install the new:
211  if (mActiveFontIndex == 0) {
212  mFont[0] = mFontChooser->font();
213  // hardcode the family and size of "message body" dependent fonts:
214  for (int i = 0; i < numFontNames; ++i) {
215  if (!fontNames[i].enableFamilyAndSize) {
216  // ### shall we copy the font and set the save and re-set
217  // {regular,italic,bold,bold italic} property or should we
218  // copy only family and pointSize?
219  mFont[i].setFamily(mFont[0].family());
220  mFont[i].setPointSize/*Float?*/ (mFont[0].pointSize/*Float?*/ ());
221  }
222  }
223  } else if (mActiveFontIndex > 0) {
224  mFont[ mActiveFontIndex ] = mFontChooser->font();
225  }
226  mActiveFontIndex = index;
227 
228  // Disonnect so the "Apply" button is not activated by the change
229  disconnect(mFontChooser, &KFontChooser::fontSelected,
230  this, &ConfigModuleTab::slotEmitChanged);
231 
232  // Display the new setting:
233  mFontChooser->setFont(mFont[index], fontNames[index].onlyFixed);
234 
235  connect(mFontChooser, &KFontChooser::fontSelected,
236  this, &ConfigModuleTab::slotEmitChanged);
237 
238  // Disable Family and Size list if we have selected a quote font:
239  mFontChooser->enableColumn(KFontChooser::FamilyList | KFontChooser::SizeList,
240  fontNames[ index ].enableFamilyAndSize);
241 }
242 
243 void AppearancePage::FontsTab::doLoadOther()
244 {
245  if (KMKernel::self()) {
246  KConfigGroup fonts(KMKernel::self()->config(), "Fonts");
247 
248  mFont[0] = QFontDatabase::systemFont(QFontDatabase::GeneralFont);
249  QFont fixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
250 
251  for (int i = 0; i < numFontNames; ++i) {
252  const QString configName = QLatin1String(fontNames[i].configName);
253  if (configName == QLatin1String("MessageListFont")) {
254  mFont[i] = MessageList::MessageListSettings::self()->messageListFont();
255  } else if (configName == QLatin1String("UnreadMessageFont")) {
256  mFont[i] = MessageList::MessageListSettings::self()->unreadMessageFont();
257  } else if (configName == QLatin1String("ImportantMessageFont")) {
258  mFont[i] = MessageList::MessageListSettings::self()->importantMessageFont();
259  } else if (configName == QLatin1String("TodoMessageFont")) {
260  mFont[i] = MessageList::MessageListSettings::self()->todoMessageFont();
261  } else {
262  mFont[i] = fonts.readEntry(configName,
263  (fontNames[i].onlyFixed) ? fixedFont : mFont[0]);
264  }
265  }
266  mCustomFontCheck->setChecked(!MessageCore::MessageCoreSettings::self()->useDefaultFonts());
267  mFontLocationCombo->setCurrentIndex(0);
268  slotFontSelectorChanged(0);
269  } else {
270  setEnabled(false);
271  }
272 }
273 
274 void AppearancePage::FontsTab::save()
275 {
276  if (KMKernel::self()) {
277  KConfigGroup fonts(KMKernel::self()->config(), "Fonts");
278 
279  // read the current font (might have been modified)
280  if (mActiveFontIndex >= 0) {
281  mFont[ mActiveFontIndex ] = mFontChooser->font();
282  }
283 
284  const bool customFonts = mCustomFontCheck->isChecked();
285  MessageCore::MessageCoreSettings::self()->setUseDefaultFonts(!customFonts);
286 
287  for (int i = 0; i < numFontNames; ++i) {
288  const QString configName = QLatin1String(fontNames[i].configName);
289  if (customFonts && configName == QLatin1String("MessageListFont")) {
290  MessageList::MessageListSettings::self()->setMessageListFont(mFont[i]);
291  } else if (customFonts && configName == QLatin1String("UnreadMessageFont")) {
292  MessageList::MessageListSettings::self()->setUnreadMessageFont(mFont[i]);
293  } else if (customFonts && configName == QLatin1String("ImportantMessageFont")) {
294  MessageList::MessageListSettings::self()->setImportantMessageFont(mFont[i]);
295  } else if (customFonts && configName == QLatin1String("TodoMessageFont")) {
296  MessageList::MessageListSettings::self()->setTodoMessageFont(mFont[i]);
297  } else {
298  if (customFonts || fonts.hasKey(configName)) {
299  // Don't write font info when we use default fonts, but write
300  // if it's already there:
301  fonts.writeEntry(configName, mFont[i]);
302  }
303  }
304  }
305  }
306 }
307 
308 void AppearancePage::FontsTab::doResetToDefaultsOther()
309 {
310  mCustomFontCheck->setChecked(false);
311 }
312 
313 QString AppearancePage::ColorsTab::helpAnchor() const
314 {
315  return QStringLiteral("configure-appearance-colors");
316 }
317 
318 static const struct {
319  const char *configName;
320  const char *displayName;
321 } colorNames[] = { // adjust doLoadOther if you change this:
322  { "QuotedText1", I18N_NOOP("Quoted Text - First Level") },
323  { "QuotedText2", I18N_NOOP("Quoted Text - Second Level") },
324  { "QuotedText3", I18N_NOOP("Quoted Text - Third Level") },
325  { "LinkColor", I18N_NOOP("Link") },
326  { "UnreadMessageColor", I18N_NOOP("Unread Message") },
327  { "ImportantMessageColor", I18N_NOOP("Important Message") },
328  { "TodoMessageColor", I18N_NOOP("Action Item Message") },
329  { "ColorbarBackgroundPlain", I18N_NOOP("HTML Status Bar Background - No HTML Message") },
330  { "ColorbarForegroundPlain", I18N_NOOP("HTML Status Bar Foreground - No HTML Message") },
331  { "ColorbarBackgroundHTML", I18N_NOOP("HTML Status Bar Background - HTML Message") },
332  { "ColorbarForegroundHTML", I18N_NOOP("HTML Status Bar Foreground - HTML Message") }
333 };
334 static const int numColorNames = sizeof colorNames / sizeof *colorNames;
335 
336 AppearancePageColorsTab::AppearancePageColorsTab(QWidget *parent)
337  : ConfigModuleTab(parent)
338 {
339  // "use custom colors" check box
340  QVBoxLayout *vlay = new QVBoxLayout(this);
341  mCustomColorCheck = new QCheckBox(i18n("&Use custom colors"), this);
342  vlay->addWidget(mCustomColorCheck);
343  connect(mCustomColorCheck, &QCheckBox::stateChanged,
344  this, &ConfigModuleTab::slotEmitChanged);
345 
346  mUseInlineStyle = new QCheckBox(i18n("&Do not change color from original HTML mail"), this);
347  vlay->addWidget(mUseInlineStyle);
348  connect(mUseInlineStyle, &QCheckBox::stateChanged,
349  this, &ConfigModuleTab::slotEmitChanged);
350 
351  // color list box:
352  mColorList = new ColorListBox(this);
353  mColorList->setEnabled(false); // since !mCustomColorCheck->isChecked()
354  for (int i = 0; i < numColorNames; ++i) {
355  mColorList->addColor(i18n(colorNames[i].displayName));
356  }
357  vlay->addWidget(mColorList, 1);
358 
359  // "recycle colors" check box:
360  mRecycleColorCheck
361  = new QCheckBox(i18n("Recycle colors on deep &quoting"), this);
362  mRecycleColorCheck->setEnabled(false);
363  vlay->addWidget(mRecycleColorCheck);
364  connect(mRecycleColorCheck, &QCheckBox::stateChanged,
365  this, &ConfigModuleTab::slotEmitChanged);
366 
367  // close to quota threshold
368  QHBoxLayout *hbox = new QHBoxLayout();
369  vlay->addLayout(hbox);
370  QLabel *l = new QLabel(i18n("Close to quota threshold:"), this);
371  hbox->addWidget(l);
372  mCloseToQuotaThreshold = new QSpinBox(this);
373  mCloseToQuotaThreshold->setRange(0, 100);
374  mCloseToQuotaThreshold->setSingleStep(1);
375  connect(mCloseToQuotaThreshold, qOverload<int>(&QSpinBox::valueChanged),
376  this, &ConfigModuleTab::slotEmitChanged);
377  mCloseToQuotaThreshold->setSuffix(i18n("%"));
378 
379  hbox->addWidget(mCloseToQuotaThreshold);
380  hbox->addWidget(new QWidget(this), 2);
381 
382  // {en,dir}able widgets depending on the state of mCustomColorCheck:
383  connect(mCustomColorCheck, &QAbstractButton::toggled,
384  mColorList, &QWidget::setEnabled);
385  connect(mCustomColorCheck, &QAbstractButton::toggled,
386  mRecycleColorCheck, &QWidget::setEnabled);
387  connect(mCustomColorCheck, &QCheckBox::stateChanged,
388  this, &ConfigModuleTab::slotEmitChanged);
389  connect(mColorList, &ColorListBox::changed,
390  this, &ConfigModuleTab::slotEmitChanged);
391 }
392 
393 void AppearancePage::ColorsTab::doLoadOther()
394 {
395  mCustomColorCheck->setChecked(!MessageCore::MessageCoreSettings::self()->useDefaultColors());
396  mUseInlineStyle->setChecked(MessageCore::MessageCoreSettings::self()->useRealHtmlMailColor());
397  mRecycleColorCheck->setChecked(MessageViewer::MessageViewerSettings::self()->recycleQuoteColors());
398  mCloseToQuotaThreshold->setValue(KMailSettings::self()->closeToQuotaThreshold());
399  loadColor(true);
400 }
401 
402 void AppearancePage::ColorsTab::loadColor(bool loadFromConfig)
403 {
404  if (KMKernel::self()) {
405  KConfigGroup reader(KMKernel::self()->config(), "Reader");
406 
407  static const QColor defaultColor[ numColorNames ] = {
408  MessageCore::ColorUtil::self()->quoteLevel1DefaultTextColor(),
409  MessageCore::ColorUtil::self()->quoteLevel2DefaultTextColor(),
410  MessageCore::ColorUtil::self()->quoteLevel3DefaultTextColor(),
411  MessageCore::ColorUtil::self()->linkColor(), // link
412  MessageList::Util::unreadDefaultMessageColor(), // unread mgs
413  MessageList::Util::importantDefaultMessageColor(), // important msg
414  MessageList::Util::todoDefaultMessageColor(), // action item mgs
415  Qt::lightGray, // colorbar plain bg
416  Qt::black, // colorbar plain fg
417  Qt::black, // colorbar html bg
418  Qt::white // colorbar html fg
419  };
420 
421  for (int i = 0; i < numColorNames; ++i) {
422  if (loadFromConfig) {
423  const QString configName = QLatin1String(colorNames[i].configName);
424  if (configName == QLatin1String("UnreadMessageColor")) {
425  mColorList->setColorSilently(i, MessageList::MessageListSettings::self()->unreadMessageColor());
426  } else if (configName == QLatin1String("ImportantMessageColor")) {
427  mColorList->setColorSilently(i, MessageList::MessageListSettings::self()->importantMessageColor());
428  } else if (configName == QLatin1String("TodoMessageColor")) {
429  mColorList->setColorSilently(i, MessageList::MessageListSettings::self()->todoMessageColor());
430  } else {
431  mColorList->setColorSilently(i, reader.readEntry(configName, defaultColor[i]));
432  }
433  } else {
434  mColorList->setColorSilently(i, defaultColor[i]);
435  }
436  }
437  } else {
438  setEnabled(false);
439  }
440 }
441 
442 void AppearancePage::ColorsTab::doResetToDefaultsOther()
443 {
444  mCustomColorCheck->setChecked(false);
445  mUseInlineStyle->setChecked(false);
446  mRecycleColorCheck->setChecked(false);
447  mCloseToQuotaThreshold->setValue(80);
448  loadColor(false);
449 }
450 
451 void AppearancePage::ColorsTab::save()
452 {
453  if (!KMKernel::self()) {
454  return;
455  }
456  KConfigGroup reader(KMKernel::self()->config(), "Reader");
457  bool customColors = mCustomColorCheck->isChecked();
458  MessageCore::MessageCoreSettings::self()->setUseDefaultColors(!customColors);
459  MessageCore::MessageCoreSettings::self()->setUseRealHtmlMailColor(mUseInlineStyle->isChecked());
460 
461  for (int i = 0; i < numColorNames; ++i) {
462  const QString configName = QLatin1String(colorNames[i].configName);
463  if (customColors && configName == QLatin1String("UnreadMessageColor")) {
464  MessageList::MessageListSettings::self()->setUnreadMessageColor(mColorList->color(i));
465  } else if (customColors && configName == QLatin1String("ImportantMessageColor")) {
466  MessageList::MessageListSettings::self()->setImportantMessageColor(mColorList->color(i));
467  } else if (customColors && configName == QLatin1String("TodoMessageColor")) {
468  MessageList::MessageListSettings::self()->setTodoMessageColor(mColorList->color(i));
469  } else {
470  if (customColors || reader.hasKey(configName)) {
471  reader.writeEntry(configName, mColorList->color(i));
472  }
473  }
474  }
475  MessageViewer::MessageViewerSettings::self()->setRecycleQuoteColors(mRecycleColorCheck->isChecked());
476  KMailSettings::self()->setCloseToQuotaThreshold(mCloseToQuotaThreshold->value());
477 }
478 
479 QString AppearancePage::LayoutTab::helpAnchor() const
480 {
481  return QStringLiteral("configure-appearance-layout");
482 }
483 
484 AppearancePageLayoutTab::AppearancePageLayoutTab(QWidget *parent)
485  : ConfigModuleTab(parent)
486 {
487  QVBoxLayout *vlay = new QVBoxLayout(this);
488 
489  // "folder list" radio buttons:
490  populateButtonGroup(mFolderListGroupBox = new QGroupBox(this),
491  mFolderListGroup = new QButtonGroup(this),
492  Qt::Vertical, KMailSettings::self()->folderListItem());
493  vlay->addWidget(mFolderListGroupBox);
494  connect(mFolderListGroup, qOverload<int>(&QButtonGroup::buttonClicked), this, &ConfigModuleTab::slotEmitChanged);
495 
496  QHBoxLayout *folderCBHLayout = new QHBoxLayout;
497  mFolderQuickSearchCB = new QCheckBox(i18n("Show folder quick search field"), this);
498  connect(mFolderQuickSearchCB, &QAbstractButton::toggled, this, &ConfigModuleTab::slotEmitChanged);
499  folderCBHLayout->addWidget(mFolderQuickSearchCB);
500  vlay->addLayout(folderCBHLayout);
501 
502  // "favorite folders view mode" radio buttons:
503  mFavoriteFoldersViewGroupBox = new QGroupBox(this);
504  mFavoriteFoldersViewGroupBox->setTitle(i18n("Show Favorite Folders View"));
505  mFavoriteFoldersViewGroupBox->setLayout(new QVBoxLayout());
506  mFavoriteFoldersViewGroup = new QButtonGroup(this);
507  connect(mFavoriteFoldersViewGroup, qOverload<int>(&QButtonGroup::buttonClicked), this, &ConfigModuleTab::slotEmitChanged);
508 
509  QRadioButton *favoriteFoldersViewHiddenRadio = new QRadioButton(i18n("Never"), mFavoriteFoldersViewGroupBox);
510  mFavoriteFoldersViewGroup->addButton(favoriteFoldersViewHiddenRadio, static_cast<int>(MailCommon::MailCommonSettings::EnumFavoriteCollectionViewMode::HiddenMode));
511  mFavoriteFoldersViewGroupBox->layout()->addWidget(favoriteFoldersViewHiddenRadio);
512 
513  QRadioButton *favoriteFoldersViewIconsRadio = new QRadioButton(i18n("As icons"), mFavoriteFoldersViewGroupBox);
514  mFavoriteFoldersViewGroup->addButton(favoriteFoldersViewIconsRadio, static_cast<int>(MailCommon::MailCommonSettings::EnumFavoriteCollectionViewMode::IconMode));
515  mFavoriteFoldersViewGroupBox->layout()->addWidget(favoriteFoldersViewIconsRadio);
516 
517  QRadioButton *favoriteFoldersViewListRadio = new QRadioButton(i18n("As list"), mFavoriteFoldersViewGroupBox);
518  mFavoriteFoldersViewGroup->addButton(favoriteFoldersViewListRadio, static_cast<int>(MailCommon::MailCommonSettings::EnumFavoriteCollectionViewMode::ListMode));
519  mFavoriteFoldersViewGroupBox->layout()->addWidget(favoriteFoldersViewListRadio);
520 
521  vlay->addWidget(mFavoriteFoldersViewGroupBox);
522 
523  // "folder tooltips" radio buttons:
524  mFolderToolTipsGroupBox = new QGroupBox(this);
525  mFolderToolTipsGroupBox->setTitle(i18n("Folder Tooltips"));
526  mFolderToolTipsGroupBox->setLayout(new QVBoxLayout());
527  mFolderToolTipsGroup = new QButtonGroup(this);
528  connect(mFolderToolTipsGroup, qOverload<int>(&QButtonGroup::buttonClicked), this, &ConfigModuleTab::slotEmitChanged);
529 
530  QRadioButton *folderToolTipsAlwaysRadio = new QRadioButton(i18n("Always"), mFolderToolTipsGroupBox);
531  mFolderToolTipsGroup->addButton(folderToolTipsAlwaysRadio, static_cast< int >(FolderTreeWidget::DisplayAlways));
532  mFolderToolTipsGroupBox->layout()->addWidget(folderToolTipsAlwaysRadio);
533 
534  QRadioButton *folderToolTipsNeverRadio = new QRadioButton(i18n("Never"), mFolderToolTipsGroupBox);
535  mFolderToolTipsGroup->addButton(folderToolTipsNeverRadio, static_cast< int >(FolderTreeWidget::DisplayNever));
536  mFolderToolTipsGroupBox->layout()->addWidget(folderToolTipsNeverRadio);
537 
538  vlay->addWidget(mFolderToolTipsGroupBox);
539 
540  // "show reader window" radio buttons:
541  populateButtonGroup(mReaderWindowModeGroupBox = new QGroupBox(this),
542  mReaderWindowModeGroup = new QButtonGroup(this),
543  Qt::Vertical, KMailSettings::self()->readerWindowModeItem());
544  vlay->addWidget(mReaderWindowModeGroupBox);
545 
546  connect(mReaderWindowModeGroup, qOverload<int>(&QButtonGroup::buttonClicked), this, &ConfigModuleTab::slotEmitChanged);
547 
548  vlay->addStretch(10); // spacer
549 }
550 
551 void AppearancePage::LayoutTab::doLoadOther()
552 {
553  loadWidget(mFolderListGroupBox, mFolderListGroup, KMailSettings::self()->folderListItem());
554  loadWidget(mReaderWindowModeGroupBox, mReaderWindowModeGroup, KMailSettings::self()->readerWindowModeItem());
555  if (KMKernel::self()) {
556  loadWidget(mFavoriteFoldersViewGroupBox, mFavoriteFoldersViewGroup, KMKernel::self()->mailCommonSettings()->favoriteCollectionViewModeItem());
557  }
558  loadWidget(mFolderQuickSearchCB, KMailSettings::self()->enableFolderQuickSearchItem());
559  const int checkedFolderToolTipsPolicy = KMailSettings::self()->toolTipDisplayPolicy();
560  if (checkedFolderToolTipsPolicy >= 0) {
561  mFolderToolTipsGroup->button(checkedFolderToolTipsPolicy)->setChecked(true);
562  }
563 }
564 
565 void AppearancePage::LayoutTab::save()
566 {
567  saveButtonGroup(mFolderListGroup, KMailSettings::self()->folderListItem());
568  saveButtonGroup(mReaderWindowModeGroup, KMailSettings::self()->readerWindowModeItem());
569  if (KMKernel::self()) {
570  saveButtonGroup(mFavoriteFoldersViewGroup, KMKernel::self()->mailCommonSettings()->favoriteCollectionViewModeItem());
571  }
572  saveCheckBox(mFolderQuickSearchCB, KMailSettings::self()->enableFolderQuickSearchItem());
573  KMailSettings::self()->setToolTipDisplayPolicy(mFolderToolTipsGroup->checkedId());
574 }
575 
576 //
577 // Appearance Message List
578 //
579 
580 QString AppearancePage::HeadersTab::helpAnchor() const
581 {
582  return QStringLiteral("configure-appearance-headers");
583 }
584 
585 static const struct {
586  const char *displayName;
587  DateFormatter::FormatType dateDisplay;
588 } dateDisplayConfig[] = {
589  { I18N_NOOP("Sta&ndard format (%1)"), KMime::DateFormatter::CTime },
590  { I18N_NOOP("Locali&zed format (%1)"), KMime::DateFormatter::Localized },
591  { I18N_NOOP("Smart for&mat (%1)"), KMime::DateFormatter::Fancy },
592  { I18N_NOOP("C&ustom format:"), KMime::DateFormatter::Custom }
593 };
594 static const int numDateDisplayConfig
595  = sizeof dateDisplayConfig / sizeof *dateDisplayConfig;
596 
597 AppearancePageHeadersTab::AppearancePageHeadersTab(QWidget *parent)
598  : ConfigModuleTab(parent)
599  , mCustomDateFormatEdit(nullptr)
600 {
601  QVBoxLayout *vlay = new QVBoxLayout(this);
602 
603  // "General Options" group:
604  QGroupBox *group = new QGroupBox(i18nc("General options for the message list.", "General"), this);
605  QVBoxLayout *gvlay = new QVBoxLayout(group);
606 
607  mDisplayMessageToolTips = new QCheckBox(
608  MessageList::MessageListSettings::self()->messageToolTipEnabledItem()->label(), group);
609  gvlay->addWidget(mDisplayMessageToolTips);
610 
611  connect(mDisplayMessageToolTips, &QCheckBox::stateChanged,
612  this, &ConfigModuleTab::slotEmitChanged);
613 
614  // "Aggregation"
615  using MessageList::Utils::AggregationComboBox;
616  mAggregationComboBox = new AggregationComboBox(group);
617 
618  QLabel *aggregationLabel = new QLabel(i18n("Default aggregation:"), group);
619  aggregationLabel->setBuddy(mAggregationComboBox);
620 
621  using MessageList::Utils::AggregationConfigButton;
622  AggregationConfigButton *aggregationConfigButton = new AggregationConfigButton(group, mAggregationComboBox);
623 
624  QHBoxLayout *aggregationLayout = new QHBoxLayout();
625  aggregationLayout->addWidget(aggregationLabel, 1);
626  aggregationLayout->addWidget(mAggregationComboBox, 1);
627  aggregationLayout->addWidget(aggregationConfigButton, 0);
628  gvlay->addLayout(aggregationLayout);
629 
630  connect(aggregationConfigButton, &MessageList::Utils::AggregationConfigButton::configureDialogCompleted,
631  this, &AppearancePageHeadersTab::slotSelectDefaultAggregation);
632  connect(mAggregationComboBox, qOverload<int>(&MessageList::Utils::AggregationComboBox::activated),
633  this, &ConfigModuleTab::slotEmitChanged);
634 
635  // "Theme"
636  using MessageList::Utils::ThemeComboBox;
637  mThemeComboBox = new ThemeComboBox(group);
638 
639  QLabel *themeLabel = new QLabel(i18n("Default theme:"), group);
640  themeLabel->setBuddy(mThemeComboBox);
641 
642  using MessageList::Utils::ThemeConfigButton;
643  ThemeConfigButton *themeConfigButton = new ThemeConfigButton(group, mThemeComboBox);
644 
645  QHBoxLayout *themeLayout = new QHBoxLayout();
646  themeLayout->addWidget(themeLabel, 1);
647  themeLayout->addWidget(mThemeComboBox, 1);
648  themeLayout->addWidget(themeConfigButton, 0);
649  gvlay->addLayout(themeLayout);
650 
651  connect(themeConfigButton, &MessageList::Utils::ThemeConfigButton::configureDialogCompleted,
652  this, &AppearancePageHeadersTab::slotSelectDefaultTheme);
653  connect(mThemeComboBox, qOverload<int>(&MessageList::Utils::ThemeComboBox::activated),
654  this, &ConfigModuleTab::slotEmitChanged);
655 
656  vlay->addWidget(group);
657 
658  // "Date Display" group:
659  mDateDisplayBox = new QGroupBox(this);
660  mDateDisplayBox->setTitle(i18n("Date Display"));
661  mDateDisplay = new QButtonGroup(this);
662  mDateDisplay->setExclusive(true);
663  gvlay = new QVBoxLayout(mDateDisplayBox);
664 
665  for (int i = 0; i < numDateDisplayConfig; ++i) {
666  const char *label = dateDisplayConfig[i].displayName;
667  QString buttonLabel;
668  if (QString::fromLatin1(label).contains(QLatin1String("%1"))) {
669  buttonLabel = i18n(label, DateFormatter::formatCurrentDate(dateDisplayConfig[i].dateDisplay));
670  } else {
671  buttonLabel = i18n(label);
672  }
673  if (dateDisplayConfig[i].dateDisplay == DateFormatter::Custom) {
674  QWidget *hbox = new QWidget(mDateDisplayBox);
675  QHBoxLayout *hboxHBoxLayout = new QHBoxLayout(hbox);
676  hboxHBoxLayout->setContentsMargins(0, 0, 0, 0);
677  QRadioButton *radio = new QRadioButton(buttonLabel, hbox);
678  hboxHBoxLayout->addWidget(radio);
679  mDateDisplay->addButton(radio, dateDisplayConfig[i].dateDisplay);
680 
681  mCustomDateFormatEdit = new KLineEdit(hbox);
682  hboxHBoxLayout->addWidget(mCustomDateFormatEdit);
683  mCustomDateFormatEdit->setEnabled(false);
684  hboxHBoxLayout->setStretchFactor(mCustomDateFormatEdit, 1);
685 
686  connect(radio, &QAbstractButton::toggled,
687  mCustomDateFormatEdit, &QWidget::setEnabled);
688  connect(mCustomDateFormatEdit, &QLineEdit::textChanged,
689  this, &ConfigModuleTab::slotEmitChanged);
690 
691  QLabel *formatHelp = new QLabel(
692  i18n("<qt><a href=\"whatsthis1\">Custom format information...</a></qt>"), hbox);
693  formatHelp->setContextMenuPolicy(Qt::NoContextMenu);
694  connect(formatHelp, &QLabel::linkActivated,
695  this, &AppearancePageHeadersTab::slotLinkClicked);
696  hboxHBoxLayout->addWidget(formatHelp);
697 
698  mCustomDateWhatsThis
699  = i18n("<qt><p><strong>These expressions may be used for the date:"
700  "</strong></p>"
701  "<ul>"
702  "<li>d - the day as a number without a leading zero (1-31)</li>"
703  "<li>dd - the day as a number with a leading zero (01-31)</li>"
704  "<li>ddd - the abbreviated day name (Mon - Sun)</li>"
705  "<li>dddd - the long day name (Monday - Sunday)</li>"
706  "<li>M - the month as a number without a leading zero (1-12)</li>"
707  "<li>MM - the month as a number with a leading zero (01-12)</li>"
708  "<li>MMM - the abbreviated month name (Jan - Dec)</li>"
709  "<li>MMMM - the long month name (January - December)</li>"
710  "<li>yy - the year as a two digit number (00-99)</li>"
711  "<li>yyyy - the year as a four digit number (0000-9999)</li>"
712  "</ul>"
713  "<p><strong>These expressions may be used for the time:"
714  "</strong></p> "
715  "<ul>"
716  "<li>h - the hour without a leading zero (0-23 or 1-12 if AM/PM display)</li>"
717  "<li>hh - the hour with a leading zero (00-23 or 01-12 if AM/PM display)</li>"
718  "<li>m - the minutes without a leading zero (0-59)</li>"
719  "<li>mm - the minutes with a leading zero (00-59)</li>"
720  "<li>s - the seconds without a leading zero (0-59)</li>"
721  "<li>ss - the seconds with a leading zero (00-59)</li>"
722  "<li>z - the milliseconds without leading zeroes (0-999)</li>"
723  "<li>zzz - the milliseconds with leading zeroes (000-999)</li>"
724  "<li>AP - switch to AM/PM display. AP will be replaced by either \"AM\" or \"PM\".</li>"
725  "<li>ap - switch to AM/PM display. ap will be replaced by either \"am\" or \"pm\".</li>"
726  "<li>Z - time zone in numeric form (-0500)</li>"
727  "</ul>"
728  "<p><strong>All other input characters will be ignored."
729  "</strong></p></qt>");
730  mCustomDateFormatEdit->setWhatsThis(mCustomDateWhatsThis);
731  radio->setWhatsThis(mCustomDateWhatsThis);
732  gvlay->addWidget(hbox);
733  } else {
734  QRadioButton *radio = new QRadioButton(buttonLabel, mDateDisplayBox);
735  gvlay->addWidget(radio);
736  mDateDisplay->addButton(radio, dateDisplayConfig[i].dateDisplay);
737  }
738  } // end for loop populating mDateDisplay
739 
740  vlay->addWidget(mDateDisplayBox);
741  connect(mDateDisplay, qOverload<int>(&QButtonGroup::buttonClicked), this, &ConfigModuleTab::slotEmitChanged);
742 
743  vlay->addStretch(10); // spacer
744 }
745 
746 void AppearancePageHeadersTab::slotLinkClicked(const QString &link)
747 {
748  if (link == QLatin1String("whatsthis1")) {
749  QWhatsThis::showText(QCursor::pos(), mCustomDateWhatsThis);
750  }
751 }
752 
753 void AppearancePage::HeadersTab::slotSelectDefaultAggregation()
754 {
755  // Select current default aggregation.
756  mAggregationComboBox->selectDefault();
757 }
758 
759 void AppearancePage::HeadersTab::slotSelectDefaultTheme()
760 {
761  // Select current default theme.
762  mThemeComboBox->selectDefault();
763 }
764 
765 void AppearancePage::HeadersTab::doLoadOther()
766 {
767  // "General Options":
768  loadWidget(mDisplayMessageToolTips, MessageList::MessageListSettings::self()->messageToolTipEnabledItem());
769 
770  // "Aggregation":
771  slotSelectDefaultAggregation();
772 
773  // "Theme":
774  slotSelectDefaultTheme();
775 
776  // "Date Display":
777  setDateDisplay(MessageCore::MessageCoreSettings::self()->dateFormat(),
778  MessageCore::MessageCoreSettings::self()->customDateFormat());
779 }
780 
781 void AppearancePage::HeadersTab::doLoadFromGlobalSettings()
782 {
783  loadWidget(mDisplayMessageToolTips, MessageList::MessageListSettings::self()->messageToolTipEnabledItem());
784  // "Aggregation":
785  slotSelectDefaultAggregation();
786 
787  // "Theme":
788  slotSelectDefaultTheme();
789 
790  setDateDisplay(MessageCore::MessageCoreSettings::self()->dateFormat(),
791  MessageCore::MessageCoreSettings::self()->customDateFormat());
792 }
793 
794 void AppearancePage::HeadersTab::setDateDisplay(int num, const QString &format)
795 {
796  DateFormatter::FormatType dateDisplay
797  = static_cast<DateFormatter::FormatType>(num);
798 
799  // special case: needs text for the line edit:
800  if (dateDisplay == DateFormatter::Custom) {
801  mCustomDateFormatEdit->setText(format);
802  }
803 
804  for (int i = 0; i < numDateDisplayConfig; ++i) {
805  if (dateDisplay == dateDisplayConfig[i].dateDisplay) {
806  mDateDisplay->button(dateDisplay)->setChecked(true);
807  return;
808  }
809  }
810  // fell through since none found:
811  mDateDisplay->button(numDateDisplayConfig - 2)->setChecked(true); // default
812 }
813 
814 void AppearancePage::HeadersTab::save()
815 {
816  saveCheckBox(mDisplayMessageToolTips, MessageList::MessageListSettings::self()->messageToolTipEnabledItem());
817 
818  if (KMKernel::self()) {
819  KMKernel::self()->savePaneSelection();
820  }
821  // "Aggregation"
822  mAggregationComboBox->writeDefaultConfig();
823 
824  // "Theme"
825  mThemeComboBox->writeDefaultConfig();
826 
827  const int dateDisplayID = mDateDisplay->checkedId();
828  MessageCore::MessageCoreSettings::self()->setDateFormat(dateDisplayID);
829  MessageCore::MessageCoreSettings::self()->setCustomDateFormat(mCustomDateFormatEdit->text());
830 }
831 
832 //
833 // Message Window
834 //
835 
836 QString AppearancePage::ReaderTab::helpAnchor() const
837 {
838  return QStringLiteral("configure-appearance-reader");
839 }
840 
841 AppearancePageGeneralTab::AppearancePageGeneralTab(QWidget *parent)
842  : ConfigModuleTab(parent)
843 {
844  QVBoxLayout *topLayout = new QVBoxLayout(this);
845 
846  QGroupBox *readerBox = new QGroupBox(i18n("Message Window"), this);
847  topLayout->addWidget(readerBox);
848 
849  QVBoxLayout *readerBoxLayout = new QVBoxLayout(readerBox);
850 
851  // "Close message window after replying or forwarding" check box:
852  populateCheckBox(mCloseAfterReplyOrForwardCheck = new QCheckBox(this),
853  MessageViewer::MessageViewerSettings::self()->closeAfterReplyOrForwardItem());
854  mCloseAfterReplyOrForwardCheck->setToolTip(
855  i18n("Close the standalone message window after replying or forwarding the message"));
856  readerBoxLayout->addWidget(mCloseAfterReplyOrForwardCheck);
857  connect(mCloseAfterReplyOrForwardCheck, &QCheckBox::stateChanged,
858  this, &ConfigModuleTab::slotEmitChanged);
859 
860  mViewerSettings = new MessageViewer::ConfigureWidget;
861  connect(mViewerSettings, &MessageViewer::ConfigureWidget::settingsChanged,
862  this, &ConfigModuleTab::slotEmitChanged);
863  readerBoxLayout->addWidget(mViewerSettings);
864 
865  QGroupBox *systrayBox = new QGroupBox(i18n("System Tray"), this);
866  topLayout->addWidget(systrayBox);
867 
868  QVBoxLayout *systrayBoxlayout = new QVBoxLayout(systrayBox);
869 
870  // "Enable system tray applet" check box
871  mSystemTrayCheck = new QCheckBox(i18n("Enable system tray icon"), this);
872  systrayBoxlayout->addWidget(mSystemTrayCheck);
873 
874  // "Enable start in system tray" check box
875  mStartInTrayCheck = new QCheckBox(i18n("Start minimized to tray"));
876  systrayBoxlayout->addWidget(mStartInTrayCheck);
877 
878  // Dependencies between the two checkboxes
879  connect(mStartInTrayCheck, &QCheckBox::stateChanged, this, [this](int state) {
880  if (state == Qt::Checked) {
881  mSystemTrayCheck->setCheckState(Qt::Checked);
882  }
883  slotEmitChanged();
884  });
885  connect(mSystemTrayCheck, &QCheckBox::stateChanged, this, [this](int state) {
886  if (state == Qt::Unchecked) {
887  mStartInTrayCheck->setCheckState(Qt::Unchecked);
888  }
889  slotEmitChanged();
890  });
891 
892  // "Enable system tray applet" check box
893  mShowNumberInTaskBar = new QCheckBox(i18n("Show unread email in Taskbar"), this);
894  systrayBoxlayout->addWidget(mShowNumberInTaskBar);
895  connect(mShowNumberInTaskBar, &QCheckBox::stateChanged,
896  this, &ConfigModuleTab::slotEmitChanged);
897 
898  topLayout->addStretch(100); // spacer
899 }
900 
901 void AppearancePage::ReaderTab::doResetToDefaultsOther()
902 {
903 }
904 
905 void AppearancePage::ReaderTab::doLoadOther()
906 {
907  loadWidget(mSystemTrayCheck, KMailSettings::self()->systemTrayEnabledItem());
908  loadWidget(mStartInTrayCheck, KMailSettings::self()->startInTrayItem());
909  loadWidget(mShowNumberInTaskBar, KMailSettings::self()->showUnreadInTaskbarItem());
910  loadWidget(mCloseAfterReplyOrForwardCheck, MessageViewer::MessageViewerSettings::self()->closeAfterReplyOrForwardItem());
911  mViewerSettings->readConfig();
912 }
913 
914 void AppearancePage::ReaderTab::save()
915 {
916  saveCheckBox(mSystemTrayCheck, KMailSettings::self()->systemTrayEnabledItem());
917  saveCheckBox(mStartInTrayCheck, KMailSettings::self()->startInTrayItem());
918  saveCheckBox(mShowNumberInTaskBar, KMailSettings::self()->showUnreadInTaskbarItem());
919  KMailSettings::self()->save();
920  saveCheckBox(mCloseAfterReplyOrForwardCheck, MessageViewer::MessageViewerSettings::self()->closeAfterReplyOrForwardItem());
921  mViewerSettings->writeConfig();
922 }
923 
924 QString AppearancePage::MessageTagTab::helpAnchor() const
925 {
926  return QStringLiteral("configure-appearance-messagetag");
927 }
928 
929 TagListWidgetItem::TagListWidgetItem(QListWidget *parent)
930  : QListWidgetItem(parent)
931  , mTag(nullptr)
932 {
933 }
934 
935 TagListWidgetItem::TagListWidgetItem(const QIcon &icon, const QString &text, QListWidget *parent)
936  : QListWidgetItem(icon, text, parent)
937  , mTag(nullptr)
938 {
939 }
940 
941 TagListWidgetItem::~TagListWidgetItem()
942 {
943 }
944 
945 void TagListWidgetItem::setKMailTag(const MailCommon::Tag::Ptr &tag)
946 {
947  mTag = tag;
948 }
949 
950 MailCommon::Tag::Ptr TagListWidgetItem::kmailTag() const
951 {
952  return mTag;
953 }
954 
955 AppearancePageMessageTagTab::AppearancePageMessageTagTab(QWidget *parent)
956  : ConfigModuleTab(parent)
957 {
958  mPreviousTag = -1;
959  QHBoxLayout *maingrid = new QHBoxLayout(this);
960 
961  //Lefthand side Listbox and friends
962 
963  //Groupbox frame
964  mTagsGroupBox = new QGroupBox(i18n("A&vailable Tags"), this);
965  maingrid->addWidget(mTagsGroupBox);
966  QVBoxLayout *tageditgrid = new QVBoxLayout(mTagsGroupBox);
967 
968  //Listbox, add, remove row
969  QHBoxLayout *addremovegrid = new QHBoxLayout();
970  tageditgrid->addLayout(addremovegrid);
971 
972  mTagAddLineEdit = new KLineEdit(mTagsGroupBox);
973  mTagAddLineEdit->setTrapReturnKey(true);
974  addremovegrid->addWidget(mTagAddLineEdit);
975 
976  mTagAddButton = new QPushButton(mTagsGroupBox);
977  mTagAddButton->setToolTip(i18n("Add new tag"));
978  mTagAddButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
979  addremovegrid->addWidget(mTagAddButton);
980 
981  mTagRemoveButton = new QPushButton(mTagsGroupBox);
982  mTagRemoveButton->setToolTip(i18n("Remove selected tag"));
983  mTagRemoveButton->setIcon(QIcon::fromTheme(QStringLiteral("list-remove")));
984  addremovegrid->addWidget(mTagRemoveButton);
985 
986  //Up and down buttons
987  QHBoxLayout *updowngrid = new QHBoxLayout();
988  tageditgrid->addLayout(updowngrid);
989 
990  mTagUpButton = new QPushButton(mTagsGroupBox);
991  mTagUpButton->setToolTip(i18n("Increase tag priority"));
992  mTagUpButton->setIcon(QIcon::fromTheme(QStringLiteral("arrow-up")));
993  mTagUpButton->setAutoRepeat(true);
994  updowngrid->addWidget(mTagUpButton);
995 
996  mTagDownButton = new QPushButton(mTagsGroupBox);
997  mTagDownButton->setToolTip(i18n("Decrease tag priority"));
998  mTagDownButton->setIcon(QIcon::fromTheme(QStringLiteral("arrow-down")));
999  mTagDownButton->setAutoRepeat(true);
1000  updowngrid->addWidget(mTagDownButton);
1001 
1002  //Listbox for tag names
1003  QHBoxLayout *listboxgrid = new QHBoxLayout();
1004  tageditgrid->addLayout(listboxgrid);
1005  mTagListBox = new QListWidget(mTagsGroupBox);
1006  mTagListBox->setDragDropMode(QAbstractItemView::InternalMove);
1007  connect(mTagListBox->model(), &QAbstractItemModel::rowsMoved, this, &AppearancePageMessageTagTab::slotRowsMoved);
1008 
1009  mTagListBox->setMinimumWidth(150);
1010  listboxgrid->addWidget(mTagListBox);
1011 
1012  //RHS for individual tag settings
1013 
1014  //Extra VBoxLayout for stretchers around settings
1015  QVBoxLayout *tagsettinggrid = new QVBoxLayout();
1016  maingrid->addLayout(tagsettinggrid);
1017 
1018  //Groupbox frame
1019  mTagSettingGroupBox = new QGroupBox(i18n("Ta&g Settings"),
1020  this);
1021  tagsettinggrid->addWidget(mTagSettingGroupBox);
1022  QList<KActionCollection *> actionCollections;
1023  if (kmkernel->getKMMainWidget()) {
1024  actionCollections = kmkernel->getKMMainWidget()->actionCollections();
1025  }
1026 
1027  QHBoxLayout *lay = new QHBoxLayout(mTagSettingGroupBox);
1028  mTagWidget = new MailCommon::TagWidget(actionCollections, this);
1029  lay->addWidget(mTagWidget);
1030 
1031  connect(mTagWidget, &TagWidget::changed, this, &AppearancePageMessageTagTab::slotEmitChangeCheck);
1032 
1033  //For enabling the add button in case box is non-empty
1034  connect(mTagAddLineEdit, &KLineEdit::textChanged,
1035  this, &AppearancePage::MessageTagTab::slotAddLineTextChanged);
1036 
1037  //For on-the-fly updating of tag name in editbox
1038  connect(mTagWidget->tagNameLineEdit(), &QLineEdit::textChanged,
1039  this, &AppearancePageMessageTagTab::slotNameLineTextChanged);
1040 
1041  connect(mTagWidget, &TagWidget::iconNameChanged, this, &AppearancePageMessageTagTab::slotIconNameChanged);
1042 
1043  connect(mTagAddLineEdit, &KLineEdit::returnPressed,
1044  this, &AppearancePageMessageTagTab::slotAddNewTag);
1045 
1046  connect(mTagAddButton, &QAbstractButton::clicked,
1047  this, &AppearancePageMessageTagTab::slotAddNewTag);
1048 
1049  connect(mTagRemoveButton, &QAbstractButton::clicked,
1050  this, &AppearancePageMessageTagTab::slotRemoveTag);
1051 
1052  connect(mTagUpButton, &QAbstractButton::clicked,
1053  this, &AppearancePageMessageTagTab::slotMoveTagUp);
1054 
1055  connect(mTagDownButton, &QAbstractButton::clicked,
1056  this, &AppearancePageMessageTagTab::slotMoveTagDown);
1057 
1058  connect(mTagListBox, &QListWidget::currentItemChanged,
1059  this, &AppearancePageMessageTagTab::slotSelectionChanged);
1060  //Adjust widths for columns
1061  maingrid->setStretchFactor(mTagsGroupBox, 1);
1062  maingrid->setStretchFactor(lay, 1);
1063  tagsettinggrid->addStretch(10);
1064 }
1065 
1066 AppearancePageMessageTagTab::~AppearancePageMessageTagTab()
1067 {
1068 }
1069 
1070 void AppearancePage::MessageTagTab::slotEmitChangeCheck()
1071 {
1072  slotEmitChanged();
1073 }
1074 
1075 void AppearancePage::MessageTagTab::slotRowsMoved(const QModelIndex &, int sourcestart, int sourceEnd, const QModelIndex &, int destinationRow)
1076 {
1077  Q_UNUSED(sourceEnd);
1078  Q_UNUSED(sourcestart);
1079  Q_UNUSED(destinationRow);
1080  updateButtons();
1081  slotEmitChangeCheck();
1082 }
1083 
1084 void AppearancePage::MessageTagTab::updateButtons()
1085 {
1086  const int currentIndex = mTagListBox->currentRow();
1087 
1088  const bool theFirst = (currentIndex == 0);
1089  const bool theLast = (currentIndex >= (int)mTagListBox->count() - 1);
1090  const bool aFilterIsSelected = (currentIndex >= 0);
1091 
1092  mTagUpButton->setEnabled(aFilterIsSelected && !theFirst);
1093  mTagDownButton->setEnabled(aFilterIsSelected && !theLast);
1094 }
1095 
1096 void AppearancePage::MessageTagTab::slotMoveTagUp()
1097 {
1098  const int tmp_index = mTagListBox->currentRow();
1099  if (tmp_index <= 0) {
1100  return;
1101  }
1102  swapTagsInListBox(tmp_index, tmp_index - 1);
1103  updateButtons();
1104 }
1105 
1106 void AppearancePage::MessageTagTab::slotMoveTagDown()
1107 {
1108  const int tmp_index = mTagListBox->currentRow();
1109  if ((tmp_index < 0)
1110  || (tmp_index >= int(mTagListBox->count()) - 1)) {
1111  return;
1112  }
1113  swapTagsInListBox(tmp_index, tmp_index + 1);
1114  updateButtons();
1115 }
1116 
1117 void AppearancePage::MessageTagTab::swapTagsInListBox(const int first, const int second)
1118 {
1119  disconnect(mTagListBox, &QListWidget::currentItemChanged,
1120  this, &AppearancePageMessageTagTab::slotSelectionChanged);
1121  QListWidgetItem *item = mTagListBox->takeItem(first);
1122  // now selected item is at idx(idx-1), so
1123  // insert the other item at idx, ie. above(below).
1124  mPreviousTag = second;
1125  mTagListBox->insertItem(second, item);
1126  mTagListBox->setCurrentRow(second);
1127  connect(mTagListBox, &QListWidget::currentItemChanged,
1128  this, &AppearancePageMessageTagTab::slotSelectionChanged);
1129  slotEmitChangeCheck();
1130 }
1131 
1132 void AppearancePage::MessageTagTab::slotRecordTagSettings(int aIndex)
1133 {
1134  if ((aIndex < 0) || (aIndex >= int(mTagListBox->count()))) {
1135  return;
1136  }
1137  QListWidgetItem *item = mTagListBox->item(aIndex);
1138  TagListWidgetItem *tagItem = static_cast<TagListWidgetItem *>(item);
1139 
1140  MailCommon::Tag::Ptr tmp_desc = tagItem->kmailTag();
1141 
1142  tmp_desc->tagName = tagItem->text();
1143  mTagWidget->recordTagSettings(tmp_desc);
1144 }
1145 
1146 void AppearancePage::MessageTagTab::slotUpdateTagSettingWidgets(int aIndex)
1147 {
1148  //Check if selection is valid
1149  if ((aIndex < 0) || (mTagListBox->currentRow() < 0)) {
1150  mTagRemoveButton->setEnabled(false);
1151  mTagUpButton->setEnabled(false);
1152  mTagDownButton->setEnabled(false);
1153 
1154  mTagWidget->setEnabled(false);
1155  return;
1156  }
1157  mTagWidget->setEnabled(true);
1158 
1159  mTagRemoveButton->setEnabled(true);
1160  mTagUpButton->setEnabled((0 != aIndex));
1161  mTagDownButton->setEnabled(((int(mTagListBox->count()) - 1) != aIndex));
1162  QListWidgetItem *item = mTagListBox->currentItem();
1163  TagListWidgetItem *tagItem = static_cast<TagListWidgetItem *>(item);
1164  MailCommon::Tag::Ptr tmp_desc = tagItem->kmailTag();
1165 
1166  disconnect(mTagWidget->tagNameLineEdit(), &KLineEdit::textChanged,
1167  this, &AppearancePage::MessageTagTab::slotNameLineTextChanged);
1168 
1169  mTagWidget->tagNameLineEdit()->setEnabled(!tmp_desc->isImmutable);
1170  mTagWidget->tagNameLineEdit()->setText(tmp_desc->tagName);
1171  connect(mTagWidget->tagNameLineEdit(), &KLineEdit::textChanged,
1172  this, &AppearancePage::MessageTagTab::slotNameLineTextChanged);
1173 
1174  mTagWidget->setTagTextColor(tmp_desc->textColor);
1175 
1176  mTagWidget->setTagBackgroundColor(tmp_desc->backgroundColor);
1177 
1178  mTagWidget->setTagTextFormat(tmp_desc->isBold, tmp_desc->isItalic);
1179 
1180  mTagWidget->iconButton()->setEnabled(!tmp_desc->isImmutable);
1181  mTagWidget->iconButton()->setIcon(tmp_desc->iconName);
1182 
1183  mTagWidget->keySequenceWidget()->setEnabled(true);
1184  mTagWidget->keySequenceWidget()->setKeySequence(tmp_desc->shortcut,
1185  KKeySequenceWidget::NoValidate);
1186 
1187  mTagWidget->inToolBarCheck()->setEnabled(true);
1188  mTagWidget->inToolBarCheck()->setChecked(tmp_desc->inToolbar);
1189 }
1190 
1191 void AppearancePage::MessageTagTab::slotSelectionChanged()
1192 {
1193  mEmitChanges = false;
1194  slotRecordTagSettings(mPreviousTag);
1195  slotUpdateTagSettingWidgets(mTagListBox->currentRow());
1196  mPreviousTag = mTagListBox->currentRow();
1197  mEmitChanges = true;
1198 }
1199 
1200 void AppearancePage::MessageTagTab::slotRemoveTag()
1201 {
1202  const int tmp_index = mTagListBox->currentRow();
1203  if (tmp_index >= 0) {
1204  if (KMessageBox::Yes == KMessageBox::questionYesNo(this, i18n("Do you want to remove tag \'%1\'?", mTagListBox->item(mTagListBox->currentRow())->text()))) {
1205  QListWidgetItem *item = mTagListBox->takeItem(mTagListBox->currentRow());
1206  TagListWidgetItem *tagItem = static_cast<TagListWidgetItem *>(item);
1207  MailCommon::Tag::Ptr tmp_desc = tagItem->kmailTag();
1208  if (tmp_desc->tag().isValid()) {
1209  new Akonadi::TagDeleteJob(tmp_desc->tag());
1210  } else {
1211  qCWarning(KMAIL_LOG) << "Can't remove tag with invalid akonadi tag";
1212  }
1213  mPreviousTag = -1;
1214 
1215  //Before deleting the current item, make sure the selectionChanged signal
1216  //is disconnected, so that the widgets will not get updated while the
1217  //deletion takes place.
1218  disconnect(mTagListBox, &QListWidget::currentItemChanged,
1219  this, &AppearancePageMessageTagTab::slotSelectionChanged);
1220 
1221  delete item;
1222  connect(mTagListBox, &QListWidget::currentItemChanged,
1223  this, &AppearancePageMessageTagTab::slotSelectionChanged);
1224 
1225  slotSelectionChanged();
1226  slotEmitChangeCheck();
1227  }
1228  }
1229 }
1230 
1231 void AppearancePage::MessageTagTab::slotDeleteTagJob(KJob *job)
1232 {
1233  if (job->error()) {
1234  qCWarning(KMAIL_LOG) << "Failed to delete tag " << job->errorString();
1235  }
1236 }
1237 
1238 void AppearancePage::MessageTagTab::slotNameLineTextChanged(const QString &aText)
1239 {
1240  //If deleted all, leave the first character for the sake of not having an
1241  //empty tag name
1242  if (aText.isEmpty() && !mTagListBox->currentItem()) {
1243  return;
1244  }
1245 
1246  const int count = mTagListBox->count();
1247  for (int i = 0; i < count; ++i) {
1248  if (mTagListBox->item(i)->text() == aText) {
1249  KMessageBox::error(this, i18n("We cannot create tag. A tag with same name already exists."));
1250  disconnect(mTagWidget->tagNameLineEdit(), &QLineEdit::textChanged,
1251  this, &AppearancePageMessageTagTab::slotNameLineTextChanged);
1252  mTagWidget->tagNameLineEdit()->setText(mTagListBox->currentItem()->text());
1253  connect(mTagWidget->tagNameLineEdit(), &QLineEdit::textChanged,
1254  this, &AppearancePageMessageTagTab::slotNameLineTextChanged);
1255  return;
1256  }
1257  }
1258 
1259  //Disconnect so the tag information is not saved and reloaded with every
1260  //letter
1261  disconnect(mTagListBox, &QListWidget::currentItemChanged,
1262  this, &AppearancePageMessageTagTab::slotSelectionChanged);
1263 
1264  mTagListBox->currentItem()->setText(aText);
1265  connect(mTagListBox, &QListWidget::currentItemChanged,
1266  this, &AppearancePageMessageTagTab::slotSelectionChanged);
1267 }
1268 
1269 void AppearancePage::MessageTagTab::slotIconNameChanged(const QString &iconName)
1270 {
1271  mTagListBox->currentItem()->setIcon(QIcon::fromTheme(iconName));
1272 }
1273 
1274 void AppearancePage::MessageTagTab::slotAddLineTextChanged(const QString &aText)
1275 {
1276  mTagAddButton->setEnabled(!aText.trimmed().isEmpty());
1277 }
1278 
1279 void AppearancePage::MessageTagTab::slotAddNewTag()
1280 {
1281  const QString newTagName = mTagAddLineEdit->text().trimmed();
1282  if (newTagName.isEmpty()) {
1283  return;
1284  }
1285  const int count = mTagListBox->count();
1286  for (int i = 0; i < count; ++i) {
1287  if (mTagListBox->item(i)->text() == newTagName) {
1288  KMessageBox::error(this, i18n("We cannot create tag. A tag with same name already exists."));
1289  return;
1290  }
1291  }
1292 
1293  const int tmp_priority = mTagListBox->count();
1294 
1295  MailCommon::Tag::Ptr tag(Tag::createDefaultTag(newTagName));
1296  tag->priority = tmp_priority;
1297 
1298  slotEmitChangeCheck();
1299  TagListWidgetItem *newItem = new TagListWidgetItem(QIcon::fromTheme(tag->iconName), newTagName, mTagListBox);
1300  newItem->setKMailTag(tag);
1301  mTagListBox->addItem(newItem);
1302  mTagListBox->setCurrentItem(newItem);
1303  mTagAddLineEdit->clear();
1304 }
1305 
1306 void AppearancePage::MessageTagTab::doLoadFromGlobalSettings()
1307 {
1308  mTagListBox->clear();
1309 
1310  Akonadi::TagFetchJob *fetchJob = new Akonadi::TagFetchJob(this);
1311  fetchJob->fetchScope().fetchAttribute<Akonadi::TagAttribute>();
1312  connect(fetchJob, &KJob::result, this, &AppearancePageMessageTagTab::slotTagsFetched);
1313 }
1314 
1315 void AppearancePage::MessageTagTab::slotTagsFetched(KJob *job)
1316 {
1317  if (job->error()) {
1318  qCWarning(KMAIL_LOG) << "Failed to load tags " << job->errorString();
1319  return;
1320  }
1321  Akonadi::TagFetchJob *fetchJob = static_cast<Akonadi::TagFetchJob *>(job);
1322 
1323  QList<MailCommon::TagPtr> msgTagList;
1324  const Akonadi::Tag::List tagList = fetchJob->tags();
1325  msgTagList.reserve(tagList.count());
1326  for (const Akonadi::Tag &akonadiTag : tagList) {
1327  MailCommon::Tag::Ptr tag = MailCommon::Tag::fromAkonadi(akonadiTag);
1328  msgTagList.append(tag);
1329  }
1330 
1331  std::sort(msgTagList.begin(), msgTagList.end(), MailCommon::Tag::compare);
1332 
1333  for (const MailCommon::Tag::Ptr &tag : qAsConst(msgTagList)) {
1334  TagListWidgetItem *newItem = new TagListWidgetItem(QIcon::fromTheme(tag->iconName), tag->tagName, mTagListBox);
1335  newItem->setKMailTag(tag);
1336  if (tag->priority == -1) {
1337  tag->priority = mTagListBox->count() - 1;
1338  }
1339  }
1340 
1341  //Disconnect so that insertItem's do not trigger an update procedure
1342  disconnect(mTagListBox, &QListWidget::currentItemChanged,
1343  this, &AppearancePageMessageTagTab::slotSelectionChanged);
1344 
1345  connect(mTagListBox, &QListWidget::currentItemChanged,
1346  this, &AppearancePageMessageTagTab::slotSelectionChanged);
1347 
1348  slotUpdateTagSettingWidgets(-1);
1349  //Needed since the previous function doesn't affect add button
1350  mTagAddButton->setEnabled(false);
1351 
1352  // Save the original list
1353  mOriginalMsgTagList.clear();
1354  for (const MailCommon::TagPtr &tag : qAsConst(msgTagList)) {
1355  mOriginalMsgTagList.append(MailCommon::TagPtr(new MailCommon::Tag(*tag)));
1356  }
1357 }
1358 
1359 void AppearancePage::MessageTagTab::save()
1360 {
1361  const int currentRow = mTagListBox->currentRow();
1362  if (currentRow < 0) {
1363  return;
1364  }
1365 
1366  const int count = mTagListBox->count();
1367  if (!count) {
1368  return;
1369  }
1370 
1371  QListWidgetItem *item = mTagListBox->currentItem();
1372  if (!item) {
1373  return;
1374  }
1375  slotRecordTagSettings(currentRow);
1376  const int numberOfMsgTagList = count;
1377  for (int i = 0; i < numberOfMsgTagList; ++i) {
1378  TagListWidgetItem *tagItem = static_cast<TagListWidgetItem *>(mTagListBox->item(i));
1379  if ((i >= mOriginalMsgTagList.count()) || *(tagItem->kmailTag()) != *(mOriginalMsgTagList[i])) {
1380  MailCommon::Tag::Ptr tag = tagItem->kmailTag();
1381  tag->priority = i;
1382  Akonadi::Tag akonadiTag = tag->saveToAkonadi();
1383  if ((*tag).id() > 0) {
1384  akonadiTag.setId((*tag).id());
1385  }
1386  if (akonadiTag.isValid()) {
1387  new Akonadi::TagModifyJob(akonadiTag);
1388  } else {
1389  new Akonadi::TagCreateJob(akonadiTag);
1390  }
1391  }
1392  }
1393 }
QWidget::layout
QLayout * layout() const
QAbstractButton::setAutoRepeat
void setAutoRepeat(bool)
AppearancePageMessageTagTab::slotRemoveTag
void slotRemoveTag()
Removes the currently selected text in the list box.
Definition: configureappearancepage.cpp:1200
AppearancePageGeneralTab::AppearancePageGeneralTab
AppearancePageGeneralTab(QWidget *parent=nullptr)
Definition: configureappearancepage.cpp:841
QList::clear
void clear()
QWhatsThis::showText
void showText(const QPoint &pos, const QString &text, QWidget *w)
dateDisplay
DateFormatter::FormatType dateDisplay
Definition: configureappearancepage.cpp:587
QModelIndex
numFontNames
static const int numFontNames
Definition: configureappearancepage.cpp:148
AppearancePageLayoutTab::helpAnchor
Q_REQUIRED_RESULT QString helpAnchor() const
Definition: configureappearancepage.cpp:479
AppearancePage::LayoutTab
AppearancePageLayoutTab LayoutTab
Definition: configureappearancepage.h:281
QWidget
QFont::setPointSize
void setPointSize(int pointSize)
QLayout::setContentsMargins
void setContentsMargins(int left, int top, int right, int bottom)
QListWidget::currentItem
QListWidgetItem * currentItem() const
AppearancePageGeneralTab::save
void save() override
Definition: configureappearancepage.cpp:914
AppearancePage::ColorsTab
AppearancePageColorsTab ColorsTab
Definition: configureappearancepage.h:280
AppearancePageLayoutTab::save
void save() override
Definition: configureappearancepage.cpp:565
kmmainwidget.h
ConfigModuleTab
Definition: configuredialog_p.h:17
colorNames
static const struct @1 colorNames[]
AppearancePageHeadersTab
Definition: configureappearancepage.h:124
QSpinBox::setSuffix
void setSuffix(const QString &suffix)
numDateDisplayConfig
static const int numDateDisplayConfig
Definition: configureappearancepage.cpp:595
AppearancePageFontsTab::save
void save() override
Definition: configureappearancepage.cpp:274
QButtonGroup::addButton
void addButton(QAbstractButton *button)
QButtonGroup::buttonClicked
void buttonClicked(QAbstractButton *button)
TagListWidgetItem::setKMailTag
void setKMailTag(const MailCommon::Tag::Ptr &tag)
Definition: configureappearancepage.cpp:945
onlyFixed
bool onlyFixed
Definition: configureappearancepage.cpp:137
AppearancePageLayoutTab::AppearancePageLayoutTab
AppearancePageLayoutTab(QWidget *parent=nullptr)
Definition: configureappearancepage.cpp:484
AppearancePage::AppearancePage
AppearancePage(QWidget *parent=nullptr)
Definition: configureappearancepage.cpp:87
QList::reserve
void reserve(int alloc)
displayName
const char * displayName
Definition: configureappearancepage.cpp:135
QFont
AppearancePageMessageTagTab::slotAddLineTextChanged
void slotAddLineTextChanged(const QString &aText)
Enables/disables Add button according to whether aText is empty.
Definition: configureappearancepage.cpp:1274
QWidget::setMinimumWidth
void setMinimumWidth(int minw)
AppearancePage::FontsTab
AppearancePageFontsTab FontsTab
Definition: configureappearancepage.h:279
QAbstractItemView::setDragDropMode
void setDragDropMode(DragDropMode behavior)
QListWidgetItem
QHBoxLayout
QLineEdit::textChanged
void textChanged(const QString &text)
AppearancePageMessageTagTab::save
void save() override
Definition: configureappearancepage.cpp:1359
QListWidget::insertItem
void insertItem(int row, QListWidgetItem *item)
QButtonGroup::button
QAbstractButton * button(int id) const
TagListWidgetItem::kmailTag
MailCommon::Tag::Ptr kmailTag() const
Definition: configureappearancepage.cpp:950
QListWidget
TagListWidgetItem::~TagListWidgetItem
~TagListWidgetItem()
Definition: configureappearancepage.cpp:941
QObject::disconnect
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QAbstractButton::setIcon
void setIcon(const QIcon &icon)
numColorNames
static const int numColorNames
Definition: configureappearancepage.cpp:334
QListWidget::addItem
void addItem(const QString &label)
AppearancePageHeadersTab::helpAnchor
Q_REQUIRED_RESULT QString helpAnchor() const
Definition: configureappearancepage.cpp:580
KMKernel::self
static KMKernel * self()
normal control stuff
Definition: kmkernel.cpp:1314
QSpinBox::setRange
void setRange(int minimum, int maximum)
QButtonGroup
AppearancePageMessageTagTab
Configuration tab in the appearance page for modifying the available set of +message tags...
Definition: configureappearancepage.h:190
KMKernel::savePaneSelection
void savePaneSelection()
Definition: kmkernel.cpp:1850
QSpinBox::valueChanged
void valueChanged(int i)
QLabel::setBuddy
void setBuddy(QWidget *buddy)
enableFamilyAndSize
bool enableFamilyAndSize
Definition: configureappearancepage.cpp:136
QWidget::setEnabled
void setEnabled(bool)
QBoxLayout::addWidget
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
AppearancePageHeadersTab::AppearancePageHeadersTab
AppearancePageHeadersTab(QWidget *parent=nullptr)
Definition: configureappearancepage.cpp:597
QList::count
int count(const T &value) const
QComboBox::count
count
QAbstractItemModel::rowsMoved
void rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
QList::append
void append(const T &value)
TagListWidgetItem::TagListWidgetItem
TagListWidgetItem(QListWidget *parent=nullptr)
Definition: configureappearancepage.cpp:929
QWidget::setLayout
void setLayout(QLayout *layout)
QGroupBox
QListWidget::clear
void clear()
QSharedPointer
Definition: collectionmailinglistpage.h:33
QListWidget::takeItem
QListWidgetItem * takeItem(int row)
QCheckBox
QButtonGroup::setExclusive
void setExclusive(bool)
AppearancePageLayoutTab
Definition: configureappearancepage.h:100
QString::isEmpty
bool isEmpty() const
QString::trimmed
QString trimmed() const
QAbstractButton::clicked
void clicked(bool checked)
TagListWidgetItem
Definition: configureappearancepage.h:175
QComboBox::activated
void activated(int index)
AppearancePageMessageTagTab::slotMoveTagUp
void slotMoveTagUp()
Increases the currently selected tag's priority and handles related visual changes.
Definition: configureappearancepage.cpp:1096
ConfigModuleTab::slotEmitChanged
void slotEmitChanged()
AppearancePageMessageTagTab::AppearancePageMessageTagTab
AppearancePageMessageTagTab(QWidget *parent=nullptr)
Definition: configureappearancepage.cpp:955
QVBoxLayout
QLabel::linkActivated
void linkActivated(const QString &link)
ConfigModuleWithTabs::addTab
void addTab(ConfigModuleTab *tab, const QString &title)
QListWidget::setCurrentItem
void setCurrentItem(QListWidgetItem *item)
QString
QList< KActionCollection * >
QColor
QListWidget::item
QListWidgetItem * item(int row) const
QListWidget::count
count
util.h
AppearancePage::HeadersTab
AppearancePageHeadersTab HeadersTab
Definition: configureappearancepage.h:282
AppearancePageMessageTagTab::slotAddNewTag
void slotAddNewTag()
Creates a generic tag with the visible name from the line edit widget for adding tags.
Definition: configureappearancepage.cpp:1279
AppearancePage::MessageTagTab
AppearancePageMessageTagTab MessageTagTab
Definition: configureappearancepage.h:284
QLayout::addWidget
void addWidget(QWidget *w)
QListWidget::currentRow
currentRow
kmkernel
#define kmkernel
Definition: kmkernel.h:21
QStringList
QSpinBox::setSingleStep
void setSingleStep(int val)
AppearancePage::ReaderTab
AppearancePageGeneralTab ReaderTab
Definition: configureappearancepage.h:283
QSpinBox
QList::end
iterator end()
AppearancePageFontsTab::AppearancePageFontsTab
AppearancePageFontsTab(QWidget *parent=nullptr)
Definition: configureappearancepage.cpp:150
fontNames
static const struct @0 fontNames[]
ColorListBox::color
Q_REQUIRED_RESULT QColor color(int index) const
Definition: colorlistbox.cpp:67
QListWidgetItem::setIcon
void setIcon(const QIcon &icon)
colorlistbox.h
QWidget::setContextMenuPolicy
void setContextMenuPolicy(Qt::ContextMenuPolicy policy)
AppearancePageColorsTab::helpAnchor
Q_REQUIRED_RESULT QString helpAnchor() const
Definition: configureappearancepage.cpp:313
ColorListBox::setColorSilently
void setColorSilently(int index, const QColor &color)
Definition: colorlistbox.cpp:52
AppearancePageFontsTab
Definition: configureappearancepage.h:56
AppearancePageGeneralTab
Definition: configureappearancepage.h:153
KMailSettings::self
static KMailSettings * self()
Definition: kmailsettings.cpp:29
QAbstractButton::setChecked
void setChecked(bool)
AppearancePageColorsTab::AppearancePageColorsTab
AppearancePageColorsTab(QWidget *parent=nullptr)
Definition: configureappearancepage.cpp:336
configName
const char * configName
Definition: configureappearancepage.cpp:134
AppearancePageGeneralTab::helpAnchor
QString helpAnchor() const
Definition: configureappearancepage.cpp:836
QButtonGroup::checkedId
int checkedId() const
kmkernel.h
QWidget::setWhatsThis
void setWhatsThis(const QString &)
ConfigModuleTab::mEmitChanges
bool mEmitChanges
Definition: configuredialog_p.h:40
QCursor::pos
QPoint pos()
kmailsettings.h
QCheckBox::stateChanged
void stateChanged(int state)
QLatin1String
QBoxLayout::addStretch
void addStretch(int stretch)
QRadioButton
QGroupBox::setTitle
void setTitle(const QString &title)
QSpinBox::setValue
void setValue(int val)
AppearancePage::helpAnchor
QString helpAnchor() const override
Should return the help anchor for this page or tab.
Definition: configureappearancepage.cpp:82
QAbstractButton::toggled
void toggled(bool checked)
QFont::setFamily
void setFamily(const QString &family)
configureappearancepage.h
QWidget::QWidget
QWidget(QWidget *parent, QFlags< Qt::WindowType > f)
AppearancePageHeadersTab::save
void save() override
Definition: configureappearancepage.cpp:814
QComboBox::setCurrentIndex
void setCurrentIndex(int index)
AppearancePageColorsTab
Definition: configureappearancepage.h:79
ColorListBox::changed
void changed()
dateDisplayConfig
static const struct @2 dateDisplayConfig[]
QString::fromLatin1
QString fromLatin1(const char *str, int size)
QPushButton
QIcon::fromTheme
QIcon fromTheme(const QString &name, const QIcon &fallback)
QComboBox::addItems
void addItems(const QStringList &texts)
ConfigModuleWithTabs
Definition: configuredialog_p.h:65
QWidget::setToolTip
void setToolTip(const QString &)
AppearancePageMessageTagTab::slotMoveTagDown
void slotMoveTagDown()
Decreases the currently selected tag's priority and handles related visual changes.
Definition: configureappearancepage.cpp:1106
ColorListBox
Definition: colorlistbox.h:33
QAbstractItemView::model
QAbstractItemModel * model() const
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QLabel
ColorListBox::addColor
void addColor(const QString &text, const QColor &color=Qt::black)
Definition: colorlistbox.cpp:45
AppearancePageFontsTab::helpAnchor
Q_REQUIRED_RESULT QString helpAnchor() const
Definition: configureappearancepage.cpp:128
QListWidget::currentItemChanged
void currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
KJob
AppearancePageMessageTagTab::helpAnchor
QString helpAnchor() const
Definition: configureappearancepage.cpp:924
QList::begin
iterator begin()
AppearancePageMessageTagTab::~AppearancePageMessageTagTab
~AppearancePageMessageTagTab() override
Definition: configureappearancepage.cpp:1066
QBoxLayout::setStretchFactor
bool setStretchFactor(QWidget *widget, int stretch)
QListWidgetItem::text
QString text() const
QFont::pointSize
int pointSize() const
QIcon
QCheckBox::setCheckState
void setCheckState(Qt::CheckState state)
QListWidgetItem::setText
void setText(const QString &text)
QBoxLayout::addLayout
void addLayout(QLayout *layout, int stretch)
AppearancePageColorsTab::save
void save() override
Definition: configureappearancepage.cpp:451
QComboBox
This file is part of the KDE documentation.
Documentation copyright © 1996-2019 The KDE developers.
Generated on Thu Dec 12 2019 02:30:42 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kmail/src

Skip menu "kmail/src"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

pim API Reference

Skip menu "pim API Reference"
  • akonadi-calendar-tools
  •   konsolekalendar
  • akregator
  •   src
  • kalarmcal
  •   src
  •     lib
  • kdepim-runtime
  •   agents
  •   src
  • kleopatra
  •   src
  • kmailtransport
  • knotes
  • kontact
  • kontactinterface
  • kpimtextedit
  • ksmtp
  • ktnef
  • libkgapi
  • libkleo
  •   src
  •     src
  •     src

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal