File indexing completed on 2024-12-29 04:47:03
0001 /* 0002 This file is part of KAddressBook. 0003 SPDX-FileCopyrightText: 1996-2002 Mirko Boehm <mirko@kde.org> 0004 SPDX-FileCopyrightText: 2009 Tobias Koenig <tokoe@kde.org> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0 0007 */ 0008 0009 #include "detailledstyle.h" 0010 0011 #include "printingwizard.h" 0012 #include "printprogress.h" 0013 #include "printstyle.h" 0014 #include "ui_ds_appearance.h" 0015 0016 #include <KConfig> 0017 #include <KConfigGroup> 0018 #include <KLocalizedString> 0019 #include <KSharedConfig> 0020 #include <QCheckBox> 0021 #include <QLocale> 0022 #include <QPrinter> 0023 #include <QTextDocument> 0024 0025 using namespace KABPrinting; 0026 0027 static const char ConfigSectionName[] = "DetailedPrintStyle"; 0028 static const char ContactHeaderForeColor[] = "ContactHeaderForeColor"; 0029 static const char ContactHeaderBGColor[] = "ContactHeaderBGColor"; 0030 0031 struct ContactBlock { 0032 using List = QList<ContactBlock>; 0033 0034 QString header; 0035 QStringList entries; 0036 }; 0037 0038 struct ColorSettings { 0039 QString headerTextColor; 0040 QString headerBackgroundColor; 0041 }; 0042 0043 QString contactsToHtml(const KContacts::Addressee::List &contacts, const ColorSettings &settings) 0044 { 0045 QString content = QStringLiteral("<html>\n"); 0046 content += QLatin1StringView(" <head>\n"); 0047 content += QLatin1StringView(" <style type=\"text/css\">\n"); 0048 content += QLatin1StringView(" td.indented {\n"); 0049 content += QLatin1StringView(" padding-left: 20px;\n"); 0050 content += QLatin1StringView(" font-family: Fixed, monospace;\n"); 0051 content += QLatin1StringView(" }\n"); 0052 content += QLatin1StringView(" </style>\n"); 0053 content += QLatin1StringView(" </head>\n"); 0054 content += QLatin1StringView(" <body>\n"); 0055 ContactBlock::List blocks; 0056 for (const KContacts::Addressee &contact : contacts) { 0057 blocks.clear(); 0058 QString name = contact.realName(); 0059 if (!contact.title().isEmpty() || !contact.role().isEmpty()) { 0060 QStringList contentAddress; 0061 if (!contact.title().isEmpty()) { 0062 contentAddress << contact.title(); 0063 } 0064 if (!contact.role().isEmpty()) { 0065 contentAddress << contact.role(); 0066 } 0067 name += QStringLiteral(" (%1)").arg(contentAddress.join(QStringLiteral(", "))); 0068 } 0069 0070 const QString birthday = QLocale().toString(contact.birthday().date(), QLocale::ShortFormat); 0071 0072 if (!contact.organization().isEmpty()) { 0073 ContactBlock block; 0074 block.header = i18n("Organization:"); 0075 block.entries.append(contact.organization()); 0076 0077 blocks.append(block); 0078 } 0079 0080 if (!contact.emails().isEmpty()) { 0081 ContactBlock block; 0082 block.header = (contact.emails().count() == 1 ? i18n("Email address:") : i18n("Email addresses:")); 0083 block.entries = contact.emails(); 0084 0085 blocks.append(block); 0086 } 0087 0088 if (!contact.phoneNumbers().isEmpty()) { 0089 const KContacts::PhoneNumber::List numbers = contact.phoneNumbers(); 0090 0091 ContactBlock block; 0092 block.header = (numbers.count() == 1 ? i18n("Telephone:") : i18n("Telephones:")); 0093 0094 for (const KContacts::PhoneNumber &number : numbers) { 0095 const QString line = number.typeLabel() + QLatin1StringView(": ") + number.number(); 0096 block.entries.append(line); 0097 } 0098 0099 blocks.append(block); 0100 } 0101 0102 if (contact.url().isValid()) { 0103 ContactBlock block; 0104 block.header = i18n("Web page:"); 0105 block.entries.append(contact.url().url().toDisplayString()); 0106 0107 blocks.append(block); 0108 } 0109 0110 if (!contact.addresses().isEmpty()) { 0111 const KContacts::Address::List addresses = contact.addresses(); 0112 0113 for (const KContacts::Address &address : addresses) { 0114 ContactBlock block; 0115 0116 switch (address.type()) { 0117 case KContacts::Address::Dom: 0118 block.header = i18n("Domestic Address"); 0119 break; 0120 case KContacts::Address::Intl: 0121 block.header = i18n("International Address"); 0122 break; 0123 case KContacts::Address::Postal: 0124 block.header = i18n("Postal Address"); 0125 break; 0126 case KContacts::Address::Parcel: 0127 block.header = i18n("Parcel Address"); 0128 break; 0129 case KContacts::Address::Home: 0130 block.header = i18n("Home Address"); 0131 break; 0132 case KContacts::Address::Work: 0133 block.header = i18n("Work Address"); 0134 break; 0135 case KContacts::Address::Pref: 0136 default: 0137 block.header = i18n("Preferred Address"); 0138 } 0139 block.header += QLatin1Char(':'); 0140 0141 block.entries = address.formatted(KContacts::AddressFormatStyle::Postal).split(QLatin1Char('\n'), Qt::KeepEmptyParts); 0142 blocks.append(block); 0143 } 0144 } 0145 0146 if (!contact.note().isEmpty()) { 0147 ContactBlock block; 0148 block.header = i18n("Notes:"); 0149 block.entries = contact.note().split(QLatin1Char('\n'), Qt::KeepEmptyParts); 0150 0151 blocks.append(block); 0152 } 0153 0154 // add header 0155 content += QLatin1StringView( 0156 " <table style=\"border-width: 0px; border-spacing: 0px; " 0157 "page-break-inside: avoid\" cellspacing=\"0\" cellpadding=\"0\" width=\"100%\">\n"); 0158 content += QLatin1StringView(" <tr>\n"); 0159 content += QLatin1StringView(" <td style=\"color: ") + settings.headerTextColor + QLatin1StringView(";\" bgcolor=\"") 0160 + settings.headerBackgroundColor + QLatin1StringView(R"(" style="padding-left: 20px">)") + name + QLatin1StringView("</td>\n"); 0161 content += QLatin1StringView(" <td style=\"color: ") + settings.headerTextColor + QLatin1StringView(R"(;" align="right" bgcolor=")") 0162 + settings.headerBackgroundColor + QLatin1StringView(R"(" style="padding-right: 20px">)") + birthday + QLatin1StringView("</td>\n"); 0163 content += QLatin1StringView(" </tr>\n"); 0164 0165 for (int i = 0; i < blocks.count(); i += 2) { 0166 // add empty line for spacing 0167 content += QLatin1StringView(" <tr>\n"); 0168 content += QLatin1StringView(" <td> </td>\n"); 0169 content += QLatin1StringView(" <td> </td>\n"); 0170 content += QLatin1StringView(" </tr>\n"); 0171 0172 // add real block data 0173 const ContactBlock leftBlock = blocks.at(i); 0174 const ContactBlock rightBlock = ((i + 1 < blocks.count()) ? blocks.at(i + 1) : ContactBlock()); 0175 0176 content += QLatin1StringView(" <tr>\n"); 0177 content += QLatin1StringView(" <td>") + leftBlock.header + QLatin1StringView("</td>\n"); 0178 content += QLatin1StringView(" <td>") + rightBlock.header + QLatin1StringView("</td>\n"); 0179 content += QLatin1StringView(" </tr>\n"); 0180 0181 const int maxLines = qMax(leftBlock.entries.count(), rightBlock.entries.count()); 0182 for (int j = 0; j < maxLines; ++j) { 0183 QString leftLine; 0184 QString rightLine; 0185 0186 if (j < leftBlock.entries.count()) { 0187 leftLine = leftBlock.entries.at(j); 0188 } 0189 0190 if (j < rightBlock.entries.count()) { 0191 rightLine = rightBlock.entries.at(j); 0192 } 0193 0194 content += QLatin1StringView(" <tr>\n"); 0195 content += QLatin1StringView(" <td class=\"indented\">") + leftLine + QLatin1StringView("</td>\n"); 0196 content += QLatin1StringView(" <td class=\"indented\">") + rightLine + QLatin1StringView("</td>\n"); 0197 content += QLatin1StringView(" </tr>\n"); 0198 } 0199 } 0200 0201 // add empty line for spacing 0202 content += QLatin1StringView(" <tr>\n"); 0203 content += QLatin1StringView(" <td> </td>\n"); 0204 content += QLatin1StringView(" <td> </td>\n"); 0205 content += QLatin1StringView(" </tr>\n"); 0206 content += QLatin1StringView(" </table>\n"); 0207 } 0208 content += QLatin1StringView(" </body>\n"); 0209 content += QLatin1StringView("</html>\n"); 0210 0211 return content; 0212 } 0213 0214 class KABPrinting::AppearancePage : public QWidget, public Ui::AppearancePage_Base 0215 { 0216 public: 0217 explicit AppearancePage(QWidget *parent) 0218 : QWidget(parent) 0219 { 0220 setupUi(this); 0221 setObjectName(QLatin1StringView("AppearancePage")); 0222 } 0223 }; 0224 0225 DetailledPrintStyle::DetailledPrintStyle(PrintingWizard *parent) 0226 : PrintStyle(parent) 0227 , mPageAppearance(new AppearancePage(parent)) 0228 { 0229 setPreview(QStringLiteral("detailed-style.png")); 0230 setPreferredSortOptions(KAddressBookImportExport::ContactFields::FormattedName, Qt::AscendingOrder); 0231 0232 addPage(mPageAppearance, i18n("Detailed Print Style - Appearance")); 0233 0234 KConfigGroup config(KSharedConfig::openConfig(), QLatin1StringView(ConfigSectionName)); 0235 0236 mPageAppearance->kcbHeaderBGColor->setColor(config.readEntry(ContactHeaderBGColor, QColor(Qt::black))); 0237 0238 mPageAppearance->kcbHeaderTextColor->setColor(config.readEntry(ContactHeaderForeColor, QColor(Qt::white))); 0239 } 0240 0241 DetailledPrintStyle::~DetailledPrintStyle() = default; 0242 0243 void DetailledPrintStyle::print(const KContacts::Addressee::List &contacts, PrintProgress *progress) 0244 { 0245 progress->addMessage(i18n("Setting up colors")); 0246 progress->setProgress(0); 0247 0248 const QColor headerBackgroundColor = mPageAppearance->kcbHeaderBGColor->color(); 0249 const QColor headerForegroundColor = mPageAppearance->kcbHeaderTextColor->color(); 0250 0251 KConfigGroup config(KSharedConfig::openConfig(), QLatin1StringView(ConfigSectionName)); 0252 config.writeEntry(ContactHeaderForeColor, headerForegroundColor); 0253 config.writeEntry(ContactHeaderBGColor, headerBackgroundColor); 0254 config.sync(); 0255 0256 ColorSettings settings; 0257 settings.headerBackgroundColor = headerBackgroundColor.name(); 0258 settings.headerTextColor = headerForegroundColor.name(); 0259 0260 QPrinter *printer = wizard()->printer(); 0261 0262 progress->addMessage(i18n("Setting up document")); 0263 0264 const QString html = contactsToHtml(contacts, settings); 0265 0266 QTextDocument document; 0267 document.setHtml(html); 0268 0269 progress->addMessage(i18n("Printing")); 0270 0271 document.print(printer); 0272 0273 progress->addMessage(i18nc("Finished printing", "Done")); 0274 } 0275 0276 DetailledPrintStyleFactory::DetailledPrintStyleFactory(PrintingWizard *parent) 0277 : PrintStyleFactory(parent) 0278 { 0279 } 0280 0281 PrintStyle *DetailledPrintStyleFactory::create() const 0282 { 0283 return new DetailledPrintStyle(mParent); 0284 } 0285 0286 QString DetailledPrintStyleFactory::description() const 0287 { 0288 return i18n("Detailed Style"); 0289 } 0290 0291 #include "moc_detailledstyle.cpp"