CalendarSupport

archivedialog.cpp
1/*
2 SPDX-FileCopyrightText: 2000, 2001 Cornelius Schumacher <schumacher@kde.org>
3 SPDX-FileCopyrightText: 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
4
5 SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0
6*/
7
8// ArchiveDialog -- archive/delete past events.
9
10#include "archivedialog.h"
11#include "eventarchiver.h"
12#include "kcalprefs.h"
13
14#include <Akonadi/IncidenceChanger>
15
16#include <KDateComboBox>
17#include <KLineEdit>
18#include <KLocalizedString>
19#include <KMessageBox>
20#include <KUrlRequester>
21#include <QComboBox>
22#include <QHBoxLayout>
23#include <QUrl>
24
25#include <QButtonGroup>
26#include <QCheckBox>
27#include <QDialogButtonBox>
28#include <QFrame>
29#include <QGroupBox>
30#include <QLabel>
31#include <QPushButton>
32#include <QRadioButton>
33#include <QSpinBox>
34#include <QVBoxLayout>
35#include <QWhatsThis>
36
37using namespace CalendarSupport;
38
39ArchiveDialog::ArchiveDialog(const Akonadi::ETMCalendar::Ptr &cal, Akonadi::IncidenceChanger *changer, QWidget *parent)
40 : QDialog(parent)
41 , mUser1Button(new QPushButton(this))
42{
43 setWindowTitle(i18nc("@title:window", "Archive/Delete Past Events and To-dos"));
44 auto mainLayout = new QVBoxLayout(this);
45 auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel, this);
46 buttonBox->addButton(mUser1Button, QDialogButtonBox::ActionRole);
47 connect(buttonBox, &QDialogButtonBox::rejected, this, &ArchiveDialog::reject);
48 mUser1Button->setDefault(true);
49 setModal(false);
50 mUser1Button->setText(i18nc("@action:button", "&Archive"));
51 mCalendar = cal;
52 mChanger = changer;
53
54 auto topFrame = new QFrame(this);
55 mainLayout->addWidget(topFrame);
56 mainLayout->addWidget(buttonBox);
57
58 auto topLayout = new QVBoxLayout(topFrame);
59 topLayout->setContentsMargins(0, 0, 0, 0);
60 auto descLabel = new QLabel(topFrame);
61 descLabel->setText(xi18nc("@info:whatsthis",
62 "Archiving saves old items into the given file and "
63 "then deletes them in the current calendar. If the archive file "
64 "already exists they will be added. "
65 "(<link url=\"#\">How to restore</link>)"));
66 descLabel->setWhatsThis(i18nc("@info:whatsthis",
67 "In order to add an archive to your calendar, use the Merge Calendar "
68 "function. You can view an archive by opening it like you would any "
69 "other calendar. It is not saved in a special format, but as "
70 "vCalendar."));
72 descLabel->setWordWrap(true);
73 descLabel->setContextMenuPolicy(Qt::NoContextMenu);
74 topLayout->addWidget(descLabel);
75 connect(descLabel, &QLabel::linkActivated, this, &ArchiveDialog::showWhatsThis);
76
77 auto radioBG = new QButtonGroup(this);
78 connect(radioBG, &QButtonGroup::buttonClicked, this, &ArchiveDialog::slotActionChanged);
79
80 auto dateLayout = new QHBoxLayout();
81 dateLayout->setContentsMargins(0, 0, 0, 0);
82 mArchiveOnceRB = new QRadioButton(i18nc("@option:radio", "Archive now items older than:"), topFrame);
83 mArchiveOnceRB->setToolTip(i18nc("@info:tooltip", "Enable one time archiving or purging of older items"));
84 mArchiveOnceRB->setWhatsThis(i18nc("@info:whatsthis",
85 "If you check this box, events and to-dos older than the specified age "
86 "will be archived or purged. The items will be archived unless the "
87 "\"Delete only\" option is enabled; else the items will be purged "
88 "and not saved."));
89
90 dateLayout->addWidget(mArchiveOnceRB);
91 radioBG->addButton(mArchiveOnceRB);
92 mDateEdit = new KDateComboBox(topFrame);
93 mDateEdit->setToolTip(i18nc("@info:tooltip", "Set the one time archiving cut-off date"));
94 mDateEdit->setWhatsThis(i18nc("@info:whatsthis",
95 "The date before which items should be archived. All older events "
96 "and to-dos will be saved and deleted, the newer (and events "
97 "exactly on that date) will be kept."));
98 dateLayout->addWidget(mDateEdit);
99 topLayout->addLayout(dateLayout);
100
101 // Checkbox, numinput and combo for auto-archiving (similar to kmail's
102 // mExpireFolderCheckBox/mReadExpiryTimeNumInput in kmfolderdia.cpp)
103 auto autoArchiveHBox = new QWidget(topFrame);
104 auto autoArchiveHBoxHBoxLayout = new QHBoxLayout(autoArchiveHBox);
105 autoArchiveHBoxHBoxLayout->setContentsMargins(0, 0, 0, 0);
106 topLayout->addWidget(autoArchiveHBox);
107 mAutoArchiveRB = new QRadioButton(i18nc("@option:radio", "Automaticall&y archive items older than:"), autoArchiveHBox);
108 mAutoArchiveRB->setToolTip(i18nc("@info:tooltip", "Enable automatic archiving or purging of older items"));
109 mAutoArchiveRB->setWhatsThis(i18nc("@info:whatsthis",
110 "If this feature is enabled, the application will regularly check if "
111 "events and to-dos have to be archived; this means you will not "
112 "need to use this dialog box again, except to change the settings."));
113 radioBG->addButton(mAutoArchiveRB);
114 autoArchiveHBoxHBoxLayout->addWidget(mAutoArchiveRB);
115
116 mExpiryTimeNumInput = new QSpinBox(autoArchiveHBox);
117 autoArchiveHBoxHBoxLayout->addWidget(mExpiryTimeNumInput);
118 mExpiryTimeNumInput->setRange(1, 500);
119 mExpiryTimeNumInput->setSingleStep(1);
120
121 mExpiryTimeNumInput->setEnabled(false);
122 mExpiryTimeNumInput->setValue(7);
123 mExpiryTimeNumInput->setToolTip(i18nc("@info:tooltip", "Set the archival age in days, weeks or months"));
124 mExpiryTimeNumInput->setWhatsThis(i18nc("@info:whatsthis",
125 "The age of the events and to-dos to archive. All older items "
126 "will be saved and deleted, the newer will be kept."));
127
128 mExpiryUnitsComboBox = new QComboBox(autoArchiveHBox);
129 autoArchiveHBoxHBoxLayout->addWidget(mExpiryUnitsComboBox);
130 mExpiryUnitsComboBox->setToolTip(i18nc("@info:tooltip", "Set the units for the automatic archive age"));
131 mExpiryUnitsComboBox->setWhatsThis(i18nc("@info:whatsthis", "Select the time units (days, weeks or months) for automatic archiving."));
132 // Those items must match the "Expiry Unit" enum in the kcfg file!
133 mExpiryUnitsComboBox->addItem(i18nc("@item:inlistbox expires in daily units", "Day(s)"));
134 mExpiryUnitsComboBox->addItem(i18nc("@item:inlistbox expiration in weekly units", "Week(s)"));
135 mExpiryUnitsComboBox->addItem(i18nc("@item:inlistbox expiration in monthly units", "Month(s)"));
136 mExpiryUnitsComboBox->setEnabled(false);
137
138 auto fileLayout = new QHBoxLayout();
139 fileLayout->setContentsMargins(0, 0, 0, 0);
140 auto l = new QLabel(i18nc("@label", "Archive &file:"), topFrame);
141 fileLayout->addWidget(l);
142 mArchiveFile = new KUrlRequester(QUrl::fromLocalFile(KCalPrefs::instance()->mArchiveFile), topFrame);
143 mArchiveFile->setMode(KFile::File);
144 mArchiveFile->setNameFilter(i18nc("@label filter for KUrlRequester", "iCalendar Files (*.ics)"));
145 mArchiveFile->setToolTip(i18nc("@info:tooltip", "Set the location of the archive"));
146 mArchiveFile->setWhatsThis(i18nc("@info:whatsthis",
147 "The path of the archive file. The events and to-dos will be appended "
148 "to the specified file, so any events that are already in the file "
149 "will not be modified or deleted. You can later load or merge the "
150 "file like any other calendar. It is not saved in a special "
151 "format, it uses the iCalendar format."));
152 l->setBuddy(mArchiveFile->lineEdit());
153 fileLayout->addWidget(mArchiveFile);
154 topLayout->addLayout(fileLayout);
155
156 auto typeBox = new QGroupBox(i18nc("@title:group", "Type of Items to Archive"));
157 typeBox->setWhatsThis(i18nc("@info:whatsthis",
158 "Here you can select which items "
159 "should be archived. Events are archived if they "
160 "ended before the date given above; to-dos are archived if "
161 "they were finished before the date."));
162
163 topLayout->addWidget(typeBox);
164 QBoxLayout *typeLayout = new QVBoxLayout(typeBox);
165
166 mEvents = new QCheckBox(i18nc("@option:check", "Archive &Events"));
167 mEvents->setToolTip(i18nc("@option:check", "Archive or purge events"));
168 mEvents->setWhatsThis(i18nc("@info:whatsthis", "Select this option to archive events if they ended before the date given above."));
169 typeLayout->addWidget(mEvents);
170
171 mTodos = new QCheckBox(i18nc("@option:check", "Archive Completed &To-dos"));
172 mTodos->setToolTip(i18nc("@option:check", "Archive or purge completed to-dos"));
173 mTodos->setWhatsThis(i18nc("@info:whatsthis",
174 "Select this option to archive to-dos if they were completed "
175 "before the date given above."));
176 typeLayout->addWidget(mTodos);
177
178 mDeleteCb = new QCheckBox(i18nc("@option:check", "&Delete only, do not save"), topFrame);
179 mDeleteCb->setToolTip(i18nc("@info:tooltip", "Purge the old items without saving them"));
180 mDeleteCb->setWhatsThis(i18nc("@info:whatsthis",
181 "Select this option to delete old events and to-dos without saving "
182 "them. It is not possible to recover the events later."));
183 topLayout->addWidget(mDeleteCb);
184 connect(mDeleteCb, &QCheckBox::toggled, mArchiveFile, &KUrlRequester::setDisabled);
185 connect(mDeleteCb, &QCheckBox::toggled, this, &ArchiveDialog::slotEnableUser1);
186 connect(mArchiveFile->lineEdit(), &QLineEdit::textChanged, this, &ArchiveDialog::slotEnableUser1);
187
188 // Load settings from KCalPrefs
189 mExpiryTimeNumInput->setValue(KCalPrefs::instance()->mExpiryTime);
190 mExpiryUnitsComboBox->setCurrentIndex(KCalPrefs::instance()->mExpiryUnit);
191 mDeleteCb->setChecked(KCalPrefs::instance()->mArchiveAction == KCalPrefs::actionDelete);
192 mEvents->setChecked(KCalPrefs::instance()->mArchiveEvents);
193 mTodos->setChecked(KCalPrefs::instance()->mArchiveTodos);
194
195 slotEnableUser1();
196
197 // The focus should go to a useful field by default, not to the top richtext-label
198 if (KCalPrefs::instance()->mAutoArchive) {
199 mAutoArchiveRB->setChecked(true);
200 mAutoArchiveRB->setFocus();
201 } else {
202 mArchiveOnceRB->setChecked(true);
203 mArchiveOnceRB->setFocus();
204 }
205 slotActionChanged();
206 connect(mUser1Button, &QPushButton::clicked, this, &ArchiveDialog::slotUser1);
207}
208
209ArchiveDialog::~ArchiveDialog() = default;
210
211void ArchiveDialog::slotEnableUser1()
212{
213 const bool state = (mDeleteCb->isChecked() || !mArchiveFile->lineEdit()->text().trimmed().isEmpty());
214 mUser1Button->setEnabled(state);
215}
216
217void ArchiveDialog::slotActionChanged()
218{
219 mDateEdit->setEnabled(mArchiveOnceRB->isChecked());
220 mExpiryTimeNumInput->setEnabled(mAutoArchiveRB->isChecked());
221 mExpiryUnitsComboBox->setEnabled(mAutoArchiveRB->isChecked());
222}
223
224// Archive old events
225void ArchiveDialog::slotUser1()
226{
227 EventArchiver archiver;
228 connect(&archiver, &EventArchiver::eventsDeleted, this, &ArchiveDialog::slotEventsDeleted);
229
230 KCalPrefs::instance()->mAutoArchive = mAutoArchiveRB->isChecked();
231 KCalPrefs::instance()->mExpiryTime = mExpiryTimeNumInput->value();
232 KCalPrefs::instance()->mExpiryUnit = mExpiryUnitsComboBox->currentIndex();
233
234 if (mDeleteCb->isChecked()) {
235 KCalPrefs::instance()->mArchiveAction = KCalPrefs::actionDelete;
236 } else {
237 KCalPrefs::instance()->mArchiveAction = KCalPrefs::actionArchive;
238
239 // Get destination URL
240 QUrl destUrl(mArchiveFile->url());
241 if (!destUrl.isValid()) {
242 KMessageBox::error(this, i18nc("@info", "The archive file name is not valid."));
243 return;
244 }
245 // Force filename to be ending with vCalendar extension
246 QString filename = destUrl.fileName();
247 if (!filename.endsWith(QLatin1StringView(".vcs")) && !filename.endsWith(QLatin1StringView(".ics"))) {
248 filename.append(QLatin1StringView(".ics"));
249 destUrl = destUrl.adjusted(QUrl::RemoveFilename);
250 destUrl.setPath(destUrl.path() + filename);
251 }
252
253 KCalPrefs::instance()->mArchiveFile = destUrl.url();
254 }
255 if (KCalPrefs::instance()->mAutoArchive) {
256 archiver.runAuto(mCalendar, mChanger, this, true /*with gui*/);
257 Q_EMIT autoArchivingSettingsModified();
258 accept();
259 } else {
260 archiver.runOnce(mCalendar, mChanger, mDateEdit->date(), this);
261 accept();
262 }
263}
264
265void ArchiveDialog::slotEventsDeleted()
266{
267 Q_EMIT eventsDeleted();
268 if (!KCalPrefs::instance()->mAutoArchive) {
269 accept();
270 }
271}
272
273void ArchiveDialog::showWhatsThis()
274{
276 if (widget && !widget->whatsThis().isEmpty()) {
278 }
279}
280
281#include "moc_archivedialog.cpp"
This class handles expiring and archiving of events.
void runOnce(const Akonadi::ETMCalendar::Ptr &calendar, Akonadi::IncidenceChanger *changer, QDate limitDate, QWidget *widget)
Delete or archive events once.
void runAuto(const Akonadi::ETMCalendar::Ptr &calendar, Akonadi::IncidenceChanger *changer, QWidget *widget, bool withGUI)
Delete or archive events.
QDate date() const
KLineEdit * lineEdit() const
QUrl url() const
QString xi18nc(const char *context, const char *text, const TYPE &arg...)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
bool isChecked() const const
void clicked(bool checked)
void toggled(bool checked)
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
void buttonClicked(QAbstractButton *button)
QPoint pos()
virtual void accept()
void linkActivated(const QString &link)
void textChanged(const QString &text)
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
T qobject_cast(QObject *object)
QObject * sender() const const
QString & append(QChar ch)
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
NoContextMenu
TextSelectableByMouse
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
RemoveFilename
QUrl fromLocalFile(const QString &localFile)
void showText(const QPoint &pos, const QString &text, QWidget *w)
void setEnabled(bool)
void setDisabled(bool disable)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:16:31 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.