1 /*
2 SPDX-FileCopyrightText: 1998 Preston Brown <pbrown@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 #include "calprinter.h"
9 #include "calprintdefaultplugins.h"
10 #include "journalprint.h"
11 #include "yearprint.h"
12
13 #include <KMessageBox>
14 #include <KStandardGuiItem>
15 #include <QVBoxLayout>
16
17 #include <KConfigGroup>
18 #include <QButtonGroup>
19 #include <QDialogButtonBox>
20 #include <QGridLayout>
21 #include <QGroupBox>
22 #include <QPrintDialog>
23 #include <QPrintPreviewDialog>
24 #include <QSplitter>
25 #include <QStackedWidget>
26
27 #include <PimCommon/KPimPrintPreviewDialog>
28
29 using namespace CalendarSupport;
30
CalPrinter(QWidget * parent,const Akonadi::ETMCalendar::Ptr & calendar,bool uniqItem)31 CalPrinter::CalPrinter(QWidget *parent, const Akonadi::ETMCalendar::Ptr &calendar, bool uniqItem)
32 : QObject(parent)
33 , mParent(parent)
34 , mConfig(new KConfig(QStringLiteral("calendar_printing.rc"), KConfig::SimpleConfig))
35 , mUniqItem(uniqItem)
36 {
37
38 init(calendar);
39 }
40
~CalPrinter()41 CalPrinter::~CalPrinter()
42 {
43 qDeleteAll(mPrintPlugins);
44 delete mConfig;
45 }
46
init(const Akonadi::ETMCalendar::Ptr & calendar)47 void CalPrinter::init(const Akonadi::ETMCalendar::Ptr &calendar)
48 {
49 mCalendar = calendar;
50
51 qDeleteAll(mPrintPlugins);
52 mPrintPlugins.clear();
53
54 if (!mUniqItem) {
55 mPrintPlugins.prepend(new CalPrintYear());
56 mPrintPlugins.prepend(new CalPrintJournal());
57 mPrintPlugins.prepend(new CalPrintTodos());
58 mPrintPlugins.prepend(new CalPrintMonth());
59 mPrintPlugins.prepend(new CalPrintWeek());
60 mPrintPlugins.prepend(new CalPrintDay());
61 }
62 mPrintPlugins.prepend(new CalPrintIncidence());
63
64 PrintPlugin::List::Iterator it = mPrintPlugins.begin();
65 PrintPlugin::List::Iterator end = mPrintPlugins.end();
66 for (; it != end; ++it) {
67 if (*it) {
68 (*it)->setConfig(mConfig);
69 (*it)->setCalendar(mCalendar);
70 (*it)->doLoadConfig();
71 }
72 }
73 }
74
setDateRange(QDate fd,QDate td)75 void CalPrinter::setDateRange(QDate fd, QDate td)
76 {
77 for (const auto plugin : std::as_const(mPrintPlugins)) {
78 plugin->setDateRange(fd, td);
79 }
80 }
81
print(int type,QDate fd,QDate td,const KCalendarCore::Incidence::List & selectedIncidences,bool preview)82 void CalPrinter::print(int type, QDate fd, QDate td, const KCalendarCore::Incidence::List &selectedIncidences, bool preview)
83 {
84 PrintPlugin::List::Iterator it;
85 const PrintPlugin::List::Iterator end = mPrintPlugins.end();
86 for (it = mPrintPlugins.begin(); it != end; ++it) {
87 (*it)->setSelectedIncidences(selectedIncidences);
88 }
89 QPointer<CalPrintDialog> printDialog = new CalPrintDialog(type, mPrintPlugins, mParent, mUniqItem);
90
91 KConfigGroup grp(mConfig, ""); // orientation setting isn't in a group
92 printDialog->setOrientation(CalPrinter::ePrintOrientation(grp.readEntry("Orientation", 1)));
93 printDialog->setPreview(preview);
94 setDateRange(fd, td);
95
96 if (printDialog->exec() == QDialog::Accepted) {
97 grp.writeEntry("Orientation", static_cast<int>(printDialog->orientation()));
98
99 // Save all changes in the dialog
100 for (it = mPrintPlugins.begin(); it != mPrintPlugins.end(); ++it) {
101 (*it)->doSaveConfig();
102 }
103 doPrint(printDialog->selectedPlugin(), printDialog->orientation(), preview);
104 }
105 delete printDialog;
106
107 for (it = mPrintPlugins.begin(); it != mPrintPlugins.end(); ++it) {
108 (*it)->setSelectedIncidences(KCalendarCore::Incidence::List());
109 }
110 }
111
doPrint(PrintPlugin * selectedStyle,CalPrinter::ePrintOrientation dlgorientation,bool preview)112 void CalPrinter::doPrint(PrintPlugin *selectedStyle, CalPrinter::ePrintOrientation dlgorientation, bool preview)
113 {
114 if (!selectedStyle) {
115 KMessageBox::error(mParent, i18nc("@info", "Unable to print, an invalid print style was specified."), i18nc("@title:window", "Printing error"));
116 return;
117 }
118
119 QPrinter printer;
120 switch (dlgorientation) {
121 case eOrientPlugin:
122 printer.setPageOrientation(selectedStyle->defaultOrientation());
123 break;
124 case eOrientPortrait:
125 printer.setPageOrientation(QPageLayout::Portrait);
126 break;
127 case eOrientLandscape:
128 printer.setPageOrientation(QPageLayout::Landscape);
129 break;
130 case eOrientPrinter:
131 break;
132 }
133
134 if (preview) {
135 QPointer<PimCommon::KPimPrintPreviewDialog> printPreview = new PimCommon::KPimPrintPreviewDialog(&printer);
136 connect(printPreview.data(), &QPrintPreviewDialog::paintRequested, this, [selectedStyle, &printer]() {
137 selectedStyle->doPrint(&printer);
138 });
139 printPreview->exec();
140 delete printPreview;
141 } else {
142 QPointer<QPrintDialog> printDialog = new QPrintDialog(&printer, mParent);
143 if (printDialog->exec() == QDialog::Accepted) {
144 selectedStyle->doPrint(&printer);
145 }
146 delete printDialog;
147 }
148 }
149
updateConfig()150 void CalPrinter::updateConfig()
151 {
152 }
153
CalPrintDialog(int initialPrintType,const PrintPlugin::List & plugins,QWidget * parent,bool uniqItem)154 CalPrintDialog::CalPrintDialog(int initialPrintType, const PrintPlugin::List &plugins, QWidget *parent, bool uniqItem)
155 : QDialog(parent)
156 {
157 setWindowTitle(i18nc("@title:window", "Print"));
158 auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
159 auto mainLayout = new QVBoxLayout(this);
160 mOkButton = buttonBox->button(QDialogButtonBox::Ok);
161 mOkButton->setDefault(true);
162 mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return);
163 connect(buttonBox, &QDialogButtonBox::accepted, this, &CalPrintDialog::slotOk);
164 connect(buttonBox, &QDialogButtonBox::rejected, this, &CalPrintDialog::reject);
165 setModal(true);
166 auto page = new QWidget(this);
167 auto pageVBoxLayout = new QVBoxLayout(page);
168 pageVBoxLayout->setContentsMargins(0, 0, 0, 0);
169 mainLayout->addWidget(page);
170 mainLayout->addWidget(buttonBox);
171
172 auto splitter = new QSplitter(page);
173 pageVBoxLayout->addWidget(splitter);
174 splitter->setOrientation(Qt::Horizontal);
175 splitter->setChildrenCollapsible(false);
176 auto typeBox = new QGroupBox(i18nc("@title:group", "Print Style"), splitter);
177 QBoxLayout *typeLayout = new QVBoxLayout(typeBox);
178 mTypeGroup = new QButtonGroup(typeBox);
179
180 auto splitterRight = new QWidget(splitter);
181 auto splitterRightLayout = new QGridLayout(splitterRight);
182 splitterRightLayout->setContentsMargins(0, 0, 0, 0);
183 // splitterRightLayout->setMargin( marginHint() );
184 // splitterRightLayout->setSpacing( spacingHint() );
185
186 mConfigArea = new QStackedWidget(splitterRight);
187 splitterRightLayout->addWidget(mConfigArea, 0, 0, 1, 2);
188 auto orientationLabel = new QLabel(i18nc("@label", "Page &orientation:"), splitterRight);
189 orientationLabel->setAlignment(Qt::AlignRight);
190 splitterRightLayout->addWidget(orientationLabel, 1, 0);
191
192 mOrientationSelection = new QComboBox(splitterRight);
193 mOrientationSelection->setToolTip(i18nc("@info:tooltip", "Set the print orientation"));
194 mOrientationSelection->setWhatsThis(i18nc("@info:whatsthis",
195 "Choose if you want your output to be printed in \"portrait\" or "
196 "\"landscape\". You can also default to the orientation best suited to "
197 "the selected style or to your printer's default setting."));
198 mOrientationSelection->addItem(i18nc("@item:inlistbox", "Use Default Orientation of Selected Style"));
199 mOrientationSelection->addItem(i18nc("@item:inlistbox", "Use Printer Default"));
200 mOrientationSelection->addItem(i18nc("@item:inlistbox", "Portrait"));
201 mOrientationSelection->addItem(i18nc("@item:inlistbox", "Landscape"));
202 splitterRightLayout->addWidget(mOrientationSelection, 1, 1);
203
204 // signals and slots connections
205 connect(mTypeGroup, &QButtonGroup::buttonClicked, this, &CalPrintDialog::setPrintType);
206 orientationLabel->setBuddy(mOrientationSelection);
207
208 // First insert the config widgets into the widget stack. This possibly assigns
209 // proper ids (when two plugins have the same sortID), so store them in a map
210 // and use these new IDs to later sort the plugins for the type selection.
211 for (PrintPlugin::List::ConstIterator it = plugins.constBegin(), total = plugins.constEnd(); it != total; ++it) {
212 int newid = mConfigArea->insertWidget((*it)->sortID(), (*it)->configWidget(mConfigArea));
213 mPluginIDs[newid] = (*it);
214 }
215 // Insert all plugins in sorted order; plugins with clashing IDs will be first
216 QMap<int, PrintPlugin *>::ConstIterator mapit;
217 bool firstButton = true;
218 int id = 0;
219 for (mapit = mPluginIDs.constBegin(); mapit != mPluginIDs.constEnd(); ++mapit) {
220 PrintPlugin *p = mapit.value();
221 auto radioButton = new QRadioButton(p->description());
222 radioButton->setEnabled(p->enabled());
223 radioButton->setToolTip(i18nc("@info:tooltip", "Select the type of print"));
224 radioButton->setWhatsThis(i18nc("@info:whatsthis",
225 "Select one of the following types of prints you want to make. "
226 "You may want to print an individual item, or all the items for a "
227 "specific time range (like a day, week or month), or you may want "
228 "to print your to-do list."));
229 // Check the first available button (to ensure one is selected initially) and then
230 // the button matching the desired print type -- if such is available!
231 if ((firstButton || p->sortID() == initialPrintType) && p->enabled()) {
232 firstButton = false;
233 radioButton->setChecked(true);
234 changePrintType(id);
235 }
236 mTypeGroup->addButton(radioButton, mapit.key());
237 typeLayout->addWidget(radioButton);
238 id++;
239 }
240 if (uniqItem) {
241 typeBox->hide();
242 }
243 typeLayout->insertStretch(-1, 100);
244 setMinimumSize(minimumSizeHint());
245 resize(minimumSizeHint());
246 }
247
~CalPrintDialog()248 CalPrintDialog::~CalPrintDialog()
249 {
250 }
251
setPreview(bool preview)252 void CalPrintDialog::setPreview(bool preview)
253 {
254 if (preview) {
255 mOkButton->setText(i18nc("@action:button", "&Preview"));
256 } else {
257 mOkButton->setText(KStandardGuiItem::print().text());
258 }
259 }
260
changePrintType(int i)261 void CalPrintDialog::changePrintType(int i)
262 {
263 mConfigArea->setCurrentIndex(i);
264 mConfigArea->currentWidget()->raise();
265 QAbstractButton *btn = mTypeGroup->button(i);
266 if (btn) {
267 btn->setChecked(true);
268 }
269 }
270
setPrintType(QAbstractButton * button)271 void CalPrintDialog::setPrintType(QAbstractButton *button)
272 {
273 if (button) {
274 const int i = mTypeGroup->id(button);
275 mConfigArea->setCurrentIndex(i);
276 mConfigArea->currentWidget()->raise();
277 button->setChecked(true);
278 }
279 }
280
setOrientation(CalPrinter::ePrintOrientation orientation)281 void CalPrintDialog::setOrientation(CalPrinter::ePrintOrientation orientation)
282 {
283 mOrientation = orientation;
284 mOrientationSelection->setCurrentIndex(mOrientation);
285 }
286
orientation() const287 CalPrinter::ePrintOrientation CalPrintDialog::orientation() const
288 {
289 return mOrientation;
290 }
291
selectedPlugin()292 PrintPlugin *CalPrintDialog::selectedPlugin()
293 {
294 int id = mConfigArea->currentIndex();
295 if (mPluginIDs.contains(id)) {
296 return mPluginIDs[id];
297 } else {
298 return nullptr;
299 }
300 }
301
slotOk()302 void CalPrintDialog::slotOk()
303 {
304 mOrientation = static_cast<CalPrinter::ePrintOrientation>(mOrientationSelection->currentIndex());
305
306 QMap<int, PrintPlugin *>::ConstIterator it = mPluginIDs.constBegin();
307 for (; it != mPluginIDs.constEnd(); ++it) {
308 if (it.value()) {
309 it.value()->readSettingsWidget();
310 }
311 }
312 accept();
313 }
314