2 Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>
3 Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 As a special exception, permission is given to link this program
20 with any edition of Qt, and distribute the resulting executable,
21 without including the source code for Qt in the source distribution.
24 // ArchiveDialog -- archive/delete past events.
26 #include "archivedialog.h"
27 #include "eventarchiver.h"
28 #include "kcalprefs.h"
30 #include <Akonadi/Calendar/IncidenceChanger>
33 #include <KDateComboBox>
35 #include <KLocalizedString>
36 #include <KMessageBox>
38 #include <KUrlRequester>
39 #include <QHBoxLayout>
42 #include <QButtonGroup>
47 #include <QRadioButton>
48 #include <QVBoxLayout>
50 #include <KConfigGroup>
51 #include <QDialogButtonBox>
52 #include <QPushButton>
54 using namespace CalendarSupport
;
56 ArchiveDialog::ArchiveDialog(const Akonadi::ETMCalendar::Ptr
&cal
,
57 Akonadi::IncidenceChanger
*changer
,
61 setWindowTitle(i18nc("@title:window", "Archive/Delete Past Events and To-dos"));
62 QDialogButtonBox
*buttonBox
= new QDialogButtonBox(QDialogButtonBox::Cancel
);
63 QVBoxLayout
*mainLayout
= new QVBoxLayout
;
64 setLayout(mainLayout
);
65 mUser1Button
= new QPushButton
;
66 buttonBox
->addButton(mUser1Button
, QDialogButtonBox::ActionRole
);
67 connect(buttonBox
, &QDialogButtonBox::rejected
, this, &ArchiveDialog::reject
);
68 mUser1Button
->setDefault(true);
70 mUser1Button
->setText(i18nc("@action:button", "&Archive"));
74 QFrame
*topFrame
= new QFrame(this);
75 mainLayout
->addWidget(topFrame
);
76 mainLayout
->addWidget(buttonBox
);
78 QVBoxLayout
*topLayout
= new QVBoxLayout(topFrame
);
79 #ifndef KDEPIM_MOBILE_UI
80 QLabel
*descLabel
= new QLabel(topFrame
);
82 xi18nc("@info:whatsthis",
83 "Archiving saves old items into the given file and "
84 "then deletes them in the current calendar. If the archive file "
85 "already exists they will be added. "
86 "(<link url=\"#\">How to restore</link>)"));
87 descLabel
->setWhatsThis(
88 i18nc("@info:whatsthis",
89 "In order to add an archive to your calendar, use the Merge Calendar "
90 "function. You can view an archive by opening it like you would any "
91 "other calendar. It is not saved in a special format, but as "
93 descLabel
->setTextInteractionFlags(
94 Qt::TextSelectableByMouse
| Qt::TextSelectableByKeyboard
|
95 Qt::LinksAccessibleByMouse
| Qt::LinksAccessibleByKeyboard
);
96 descLabel
->setWordWrap(true);
97 descLabel
->setContextMenuPolicy(Qt::NoContextMenu
);
98 topLayout
->addWidget(descLabel
);
99 connect(descLabel
, &QLabel::linkActivated
, this, &ArchiveDialog::showWhatsThis
);
102 QButtonGroup
*radioBG
= new QButtonGroup(this);
103 connect(radioBG
, static_cast<void (QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked
), this, &ArchiveDialog::slotActionChanged
);
105 QHBoxLayout
*dateLayout
= new QHBoxLayout();
106 dateLayout
->setMargin(0);
107 mArchiveOnceRB
= new QRadioButton(i18nc("@option:radio",
108 "Archive now items older than:"),
110 mArchiveOnceRB
->setToolTip(
111 i18nc("@info:tooltip",
112 "Enable one time archiving or purging of older items"));
113 mArchiveOnceRB
->setWhatsThis(
114 i18nc("@info:whatsthis",
115 "If you check this box, events and to-dos older than the specified age "
116 "will be archived or purged. The items will be archived unless the "
117 "\"Delete only\" option is enabled; else the items will be purged "
120 dateLayout
->addWidget(mArchiveOnceRB
);
121 radioBG
->addButton(mArchiveOnceRB
);
122 mDateEdit
= new KDateComboBox(topFrame
);
123 mDateEdit
->setToolTip(
124 i18nc("@info:tooltip",
125 "Set the one time archiving cut-off date"));
126 mDateEdit
->setWhatsThis(
127 i18nc("@info:whatsthis",
128 "The date before which items should be archived. All older events "
129 "and to-dos will be saved and deleted, the newer (and events "
130 "exactly on that date) will be kept."));
131 dateLayout
->addWidget(mDateEdit
);
132 topLayout
->addLayout(dateLayout
);
134 // Checkbox, numinput and combo for auto-archiving (similar to kmail's
135 // mExpireFolderCheckBox/mReadExpiryTimeNumInput in kmfolderdia.cpp)
136 QWidget
*autoArchiveHBox
= new QWidget(topFrame
);
137 QHBoxLayout
*autoArchiveHBoxHBoxLayout
= new QHBoxLayout(autoArchiveHBox
);
138 autoArchiveHBoxHBoxLayout
->setMargin(0);
139 topLayout
->addWidget(autoArchiveHBox
);
140 mAutoArchiveRB
= new QRadioButton(i18nc("@option:radio",
141 "Automaticall&y archive items older than:"),
143 mAutoArchiveRB
->setToolTip(
144 i18nc("@info:tooltip",
145 "Enable automatic archiving or purging of older items"));
146 mAutoArchiveRB
->setWhatsThis(
147 i18nc("@info:whatsthis",
148 "If this feature is enabled, the application will regularly check if "
149 "events and to-dos have to be archived; this means you will not "
150 "need to use this dialog box again, except to change the settings."));
151 radioBG
->addButton(mAutoArchiveRB
);
152 autoArchiveHBoxHBoxLayout
->addWidget(mAutoArchiveRB
);
154 mExpiryTimeNumInput
= new QSpinBox(autoArchiveHBox
);
155 autoArchiveHBoxHBoxLayout
->addWidget(mExpiryTimeNumInput
);
156 mExpiryTimeNumInput
->setRange(1, 500);
157 mExpiryTimeNumInput
->setSingleStep(1);
159 mExpiryTimeNumInput
->setEnabled(false);
160 mExpiryTimeNumInput
->setValue(7);
161 mExpiryTimeNumInput
->setToolTip(
162 i18nc("@info:tooltip",
163 "Set the archival age in days, weeks or months"));
164 mExpiryTimeNumInput
->setWhatsThis(
165 i18nc("@info:whatsthis",
166 "The age of the events and to-dos to archive. All older items "
167 "will be saved and deleted, the newer will be kept."));
169 mExpiryUnitsComboBox
= new KComboBox(autoArchiveHBox
);
170 autoArchiveHBoxHBoxLayout
->addWidget(mExpiryUnitsComboBox
);
171 mExpiryUnitsComboBox
->setToolTip(
172 i18nc("@info:tooltip",
173 "Set the units for the automatic archive age"));
174 mExpiryUnitsComboBox
->setWhatsThis(
175 i18nc("@info:whatsthis",
176 "Select the time units (days, weeks or months) for automatic archiving."));
177 // Those items must match the "Expiry Unit" enum in the kcfg file!
178 mExpiryUnitsComboBox
->addItem(
179 i18nc("@item:inlistbox expires in daily units", "Day(s)"));
180 mExpiryUnitsComboBox
->addItem(
181 i18nc("@item:inlistbox expiration in weekly units", "Week(s)"));
182 mExpiryUnitsComboBox
->addItem(
183 i18nc("@item:inlistbox expiration in monthly units", "Month(s)"));
184 mExpiryUnitsComboBox
->setEnabled(false);
186 QHBoxLayout
*fileLayout
= new QHBoxLayout();
187 fileLayout
->setMargin(0);
188 QLabel
*l
= new QLabel(i18nc("@label", "Archive &file:"), topFrame
);
189 fileLayout
->addWidget(l
);
190 mArchiveFile
= new KUrlRequester(KCalPrefs::instance()->mArchiveFile
, topFrame
);
191 mArchiveFile
->setMode(KFile::File
);
192 mArchiveFile
->setFilter(i18nc("@label filter for KUrlRequester", "*.ics|iCalendar Files"));
193 mArchiveFile
->setToolTip(
194 i18nc("@info:tooltip",
195 "Set the location of the archive"));
196 mArchiveFile
->setWhatsThis(
197 i18nc("@info:whatsthis",
198 "The path of the archive file. The events and to-dos will be appended "
199 "to the specified file, so any events that are already in the file "
200 "will not be modified or deleted. You can later load or merge the "
201 "file like any other calendar. It is not saved in a special "
202 "format, it uses the iCalendar format."));
203 l
->setBuddy(mArchiveFile
->lineEdit());
204 fileLayout
->addWidget(mArchiveFile
);
205 topLayout
->addLayout(fileLayout
);
207 #ifndef KDEPIM_MOBILE_UI
208 QGroupBox
*typeBox
= new QGroupBox(i18nc("@title:group", "Type of Items to Archive"));
209 typeBox
->setWhatsThis(
210 i18nc("@info:whatsthis",
211 "Here you can select which items "
212 "should be archived. Events are archived if they "
213 "ended before the date given above; to-dos are archived if "
214 "they were finished before the date."));
216 topLayout
->addWidget(typeBox
);
217 QBoxLayout
*typeLayout
= new QVBoxLayout(typeBox
);
219 QBoxLayout
*typeLayout
= new QHBoxLayout();
220 topLayout
->addLayout(typeLayout
);
223 mEvents
= new QCheckBox(i18nc("@option:check", "Archive &Events"));
225 i18nc("@option:check", "Archive or purge events"));
226 mEvents
->setWhatsThis(
227 i18nc("@info:whatsthis",
228 "Select this option to archive events if they ended before the date given above."));
229 typeLayout
->addWidget(mEvents
);
231 mTodos
= new QCheckBox(i18nc("@option:check", "Archive Completed &To-dos"));
233 i18nc("@option:check", "Archive or purge completed to-dos"));
234 mTodos
->setWhatsThis(
235 i18nc("@info:whatsthis",
236 "Select this option to archive to-dos if they were completed "
237 "before the date given above."));
238 typeLayout
->addWidget(mTodos
);
240 mDeleteCb
= new QCheckBox(i18nc("@option:check", "&Delete only, do not save"), topFrame
);
241 mDeleteCb
->setToolTip(
242 i18nc("@info:tooltip",
243 "Purge the old items without saving them"));
244 mDeleteCb
->setWhatsThis(
245 i18nc("@info:whatsthis",
246 "Select this option to delete old events and to-dos without saving "
247 "them. It is not possible to recover the events later."));
248 topLayout
->addWidget(mDeleteCb
);
249 connect(mDeleteCb
, &QCheckBox::toggled
, mArchiveFile
, &KUrlRequester::setDisabled
);
250 connect(mDeleteCb
, &QCheckBox::toggled
, this, &ArchiveDialog::slotEnableUser1
);
251 connect(mArchiveFile
->lineEdit(), &QLineEdit::textChanged
, this, &ArchiveDialog::slotEnableUser1
);
253 // Load settings from KCalPrefs
254 mExpiryTimeNumInput
->setValue(KCalPrefs::instance()->mExpiryTime
);
255 mExpiryUnitsComboBox
->setCurrentIndex(KCalPrefs::instance()->mExpiryUnit
);
256 mDeleteCb
->setChecked(KCalPrefs::instance()->mArchiveAction
== KCalPrefs::actionDelete
);
257 mEvents
->setChecked(KCalPrefs::instance()->mArchiveEvents
);
258 mTodos
->setChecked(KCalPrefs::instance()->mArchiveTodos
);
262 // The focus should go to a useful field by default, not to the top richtext-label
263 if (KCalPrefs::instance()->mAutoArchive
) {
264 mAutoArchiveRB
->setChecked(true);
265 mAutoArchiveRB
->setFocus();
267 mArchiveOnceRB
->setChecked(true);
268 mArchiveOnceRB
->setFocus();
271 connect(mUser1Button
, &QPushButton::clicked
, this, &ArchiveDialog::slotUser1
);
274 ArchiveDialog::~ArchiveDialog()
278 void ArchiveDialog::slotEnableUser1()
280 const bool state
= (mDeleteCb
->isChecked() || !mArchiveFile
->lineEdit()->text().trimmed().isEmpty());
281 mUser1Button
->setEnabled(state
);
284 void ArchiveDialog::slotActionChanged()
286 mDateEdit
->setEnabled(mArchiveOnceRB
->isChecked());
287 mExpiryTimeNumInput
->setEnabled(mAutoArchiveRB
->isChecked());
288 mExpiryUnitsComboBox
->setEnabled(mAutoArchiveRB
->isChecked());
291 // Archive old events
292 void ArchiveDialog::slotUser1()
294 EventArchiver archiver
;
295 connect(&archiver
, &EventArchiver::eventsDeleted
, this, &ArchiveDialog::slotEventsDeleted
);
297 KCalPrefs::instance()->mAutoArchive
= mAutoArchiveRB
->isChecked();
298 KCalPrefs::instance()->mExpiryTime
= mExpiryTimeNumInput
->value();
299 KCalPrefs::instance()->mExpiryUnit
= mExpiryUnitsComboBox
->currentIndex();
301 if (mDeleteCb
->isChecked()) {
302 KCalPrefs::instance()->mArchiveAction
= KCalPrefs::actionDelete
;
304 KCalPrefs::instance()->mArchiveAction
= KCalPrefs::actionArchive
;
306 // Get destination URL
307 QUrl
destUrl(mArchiveFile
->url());
308 if (!destUrl
.isValid()) {
309 KMessageBox::sorry(this, i18nc("@info", "The archive file name is not valid."));
312 // Force filename to be ending with vCalendar extension
313 QString filename
= destUrl
.fileName();
314 if (!filename
.endsWith(QStringLiteral(".vcs")) &&
315 !filename
.endsWith(QStringLiteral(".ics"))) {
316 filename
.append(QStringLiteral(".ics"));
317 destUrl
= destUrl
.adjusted(QUrl::RemoveFilename
);
318 destUrl
.setPath(destUrl
.path() + filename
);
321 KCalPrefs::instance()->mArchiveFile
= destUrl
.url();
323 if (KCalPrefs::instance()->mAutoArchive
) {
324 archiver
.runAuto(mCalendar
, mChanger
, this, true /*with gui*/);
325 Q_EMIT
autoArchivingSettingsModified();
328 archiver
.runOnce(mCalendar
, mChanger
, mDateEdit
->date(), this);
333 void ArchiveDialog::slotEventsDeleted()
335 Q_EMIT
eventsDeleted();
336 if (!KCalPrefs::instance()->mAutoArchive
) {
341 void ArchiveDialog::showWhatsThis()
343 QWidget
*widget
= qobject_cast
< QWidget
* >(sender());
344 if (widget
&& !widget
->whatsThis().isEmpty()) {
345 QWhatsThis::showText(QCursor::pos(), widget
->whatsThis());