File indexing completed on 2024-05-12 16:02:08
0001 /* This file is part of the KDE project 0002 SPDX-FileCopyrightText: 2000 Simon Hausmann <hausmann@kde.org> 0003 SPDX-FileCopyrightText: 2006 Martin Pfeiffer <hubipete@gmx.net> 0004 SPDX-FileCopyrightText: 2012 C. Boemann <cbo@boemann.dk> 0005 SPDX-FileCopyrightText: 2017 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com> 0006 0007 SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 0010 #include "KoConfigAuthorPage.h" 0011 0012 #include "ui_KoConfigAuthorPage.h" 0013 0014 #include <KoIcon.h> 0015 #include <QDebug> 0016 0017 #include <klocalizedstring.h> 0018 #include <kuser.h> 0019 #include <kemailsettings.h> 0020 #include <kconfiggroup.h> 0021 #include <ksharedconfig.h> 0022 #include <KoResourcePaths.h> 0023 0024 #include <QLineEdit> 0025 #include <QCompleter> 0026 #include <QStackedWidget> 0027 #include <QList> 0028 #include <QComboBox> 0029 #include <QGridLayout> 0030 #include <QString> 0031 #include <QStringList> 0032 #include <QToolButton> 0033 #include <QInputDialog> 0034 #include <QTableView> 0035 #include <QStandardItem> 0036 #include <QLabel> 0037 #include <QDomDocument> 0038 #include <QDomElement> 0039 #include <QFile> 0040 #include <QDir> 0041 #include <QByteArray> 0042 0043 class Q_DECL_HIDDEN KoConfigAuthorPage::Private 0044 { 0045 public: 0046 QList<Ui::KoConfigAuthorPage *> profileUiList; 0047 QStackedWidget *stack; 0048 QComboBox *cmbAuthorProfiles; 0049 QToolButton *bnDeleteUser; 0050 QStringList positions; 0051 QStringList contactModes; 0052 QStringList contactKeys; 0053 QString defaultAuthor; 0054 }; 0055 0056 0057 KoConfigAuthorPage::KoConfigAuthorPage() 0058 : d(new Private) 0059 { 0060 QGridLayout *layout = new QGridLayout(this); 0061 0062 d->cmbAuthorProfiles = new QComboBox(); 0063 layout->addWidget(d->cmbAuthorProfiles, 0, 0); 0064 QToolButton *newUser = new QToolButton(); 0065 newUser->setIcon(koIcon("list-add")); 0066 newUser->setToolTip(i18n("Add new author profile (starts out as a copy of current)")); 0067 layout->addWidget(newUser, 0, 1); 0068 d->bnDeleteUser = new QToolButton(); 0069 d->bnDeleteUser->setIcon(koIcon("edit-delete")); 0070 d->bnDeleteUser->setToolTip(i18n("Delete the author profile")); 0071 layout->addWidget(d->bnDeleteUser, 0, 2); 0072 QFrame *f = new QFrame(); 0073 f->setFrameStyle(QFrame::HLine | QFrame::Sunken); 0074 layout->addWidget(f, 1, 0); 0075 d->stack = new QStackedWidget(); 0076 layout->addWidget(d->stack, 2, 0, 1, 3); 0077 0078 //list of positions that we can use to provide useful autocompletion. 0079 d->positions << QString(i18nc("This is a list of suggestions for positions an artist can take, comma-separated","Adapter,Animator,Artist,Art Director,Author,Assistant," 0080 "Editor,Background,Cartoonist,Colorist,Concept Artist," 0081 "Corrector,Cover Artist,Creator,Designer,Inker," 0082 "Letterer,Matte Painter,Painter,Penciller,Proofreader," 0083 "Pixel Artist,Redliner,Sprite Artist,Typographer,Texture Artist," 0084 "Translator,Writer,Other")).split(","); 0085 0086 //Keep these two in sync! 0087 d->contactModes << i18n("Homepage") << i18n("Email") << i18n("Post Address") << i18n("Telephone") << i18n("Fax"); 0088 d->contactKeys << "homepage" << "email" << "address" << "telephone" << "fax"; 0089 QStringList headerlabels; 0090 headerlabels<< i18n("Type") << i18n("Entry"); 0091 0092 Ui::KoConfigAuthorPage *aUi = 0; 0093 QWidget *w = new QWidget; 0094 d->defaultAuthor = i18n("Anonymous"); 0095 0096 QStringList profilesNew; 0097 QDir dir(KoResourcePaths::getAppDataLocation() + "/authorinfo/"); 0098 QStringList filters = QStringList() << "*.authorinfo"; 0099 Q_FOREACH(const QString &entry, dir.entryList(filters)) { 0100 QFile file(dir.absoluteFilePath(entry)); 0101 if (file.exists()) { 0102 file.open(QFile::ReadOnly); 0103 QByteArray ba = file.readAll(); 0104 file.close(); 0105 QDomDocument doc = QDomDocument(); 0106 doc.setContent(ba); 0107 QDomElement root = doc.firstChildElement(); 0108 aUi = new Ui::KoConfigAuthorPage(); 0109 w = new QWidget; 0110 aUi->setupUi(w); 0111 QString profile = root.attribute("name"); 0112 0113 QDomElement el = root.firstChildElement("nickname"); 0114 if (!el.isNull()) { 0115 aUi->leNickName->setText(el.text()); 0116 } 0117 el = root.firstChildElement("givenname"); 0118 if (!el.isNull()) { 0119 aUi->leFirstName->setText(el.text()); 0120 } 0121 el = root.firstChildElement("middlename"); 0122 if (!el.isNull()) { 0123 aUi->leInitials->setText(el.text()); 0124 } 0125 el = root.firstChildElement("familyname"); 0126 if (!el.isNull()) { 0127 aUi->leLastName->setText(el.text()); 0128 } 0129 el = root.firstChildElement("title"); 0130 if (!el.isNull()) { 0131 aUi->leTitle->setText(el.text()); 0132 } 0133 el = root.firstChildElement("position"); 0134 if (!el.isNull()) { 0135 aUi->lePosition->setText(el.text()); 0136 } 0137 el = root.firstChildElement("company"); 0138 if (!el.isNull()) { 0139 aUi->leCompany->setText(el.text()); 0140 } 0141 0142 aUi->tblContactInfo->setItemDelegate(new KoContactInfoDelegate(this, d->contactModes)); 0143 QStandardItemModel *modes = new QStandardItemModel(); 0144 aUi->tblContactInfo->setModel(modes); 0145 el = root.firstChildElement("contact"); 0146 while (!el.isNull()) { 0147 QList<QStandardItem *> list; 0148 QString type = d->contactModes.at(d->contactKeys.indexOf(el.attribute("type"))); 0149 list.append(new QStandardItem(type)); 0150 list.append(new QStandardItem(el.text())); 0151 modes->appendRow(list); 0152 el = el.nextSiblingElement("contact"); 0153 } 0154 modes->setHorizontalHeaderLabels(headerlabels); 0155 QCompleter *positionSuggestions = new QCompleter(d->positions); 0156 positionSuggestions->setCaseSensitivity(Qt::CaseInsensitive); 0157 aUi->lePosition->setCompleter(positionSuggestions); 0158 0159 connect(aUi->btnAdd, SIGNAL(clicked()), this, SLOT(addContactEntry())); 0160 connect(aUi->btnRemove, SIGNAL(clicked()), this, SLOT(removeContactEntry())); 0161 0162 d->cmbAuthorProfiles->addItem(profile); 0163 profilesNew.append(profile); 0164 d->profileUiList.append(aUi); 0165 d->stack->addWidget(w); 0166 } 0167 } 0168 0169 // Add all the user defined profiles (old type) 0170 KConfigGroup authorGroup(KSharedConfig::openConfig(), "Author"); 0171 QStringList profiles = authorGroup.readEntry("profile-names", QStringList()); 0172 0173 0174 foreach (const QString &profile , profiles) { 0175 if (!profilesNew.contains(profile)) { 0176 KConfigGroup cgs(&authorGroup, "Author-" + profile); 0177 aUi = new Ui::KoConfigAuthorPage(); 0178 w = new QWidget; 0179 aUi->setupUi(w); 0180 aUi->leNickName->setText(cgs.readEntry("creator")); 0181 aUi->leFirstName->setText(cgs.readEntry("creator-first-name")); 0182 aUi->leLastName->setText(cgs.readEntry("creator-last-name")); 0183 aUi->leInitials->setText(cgs.readEntry("initial")); 0184 aUi->leTitle->setText(cgs.readEntry("author-title")); 0185 aUi->lePosition->setText(cgs.readEntry("position")); 0186 QCompleter *positionSuggestions = new QCompleter(d->positions); 0187 positionSuggestions->setCaseSensitivity(Qt::CaseInsensitive); 0188 aUi->lePosition->setCompleter(positionSuggestions); 0189 aUi->leCompany->setText(cgs.readEntry("company")); 0190 0191 aUi->tblContactInfo->setItemDelegate(new KoContactInfoDelegate(this, d->contactModes)); 0192 QStandardItemModel *modes = new QStandardItemModel(); 0193 aUi->tblContactInfo->setModel(modes); 0194 if (cgs.hasKey("email")) { 0195 QList<QStandardItem *> list; 0196 QString email = d->contactModes.at(d->contactKeys.indexOf("email")); 0197 list.append(new QStandardItem(email)); 0198 list.append(new QStandardItem(cgs.readEntry("email"))); 0199 modes->appendRow(list); 0200 } 0201 if (cgs.hasKey("telephone-work")) { 0202 QList<QStandardItem *> list; 0203 QString tel = d->contactModes.at(d->contactKeys.indexOf("telephone")); 0204 list.append(new QStandardItem(tel)); 0205 list.append(new QStandardItem(cgs.readEntry("telephone-work"))); 0206 modes->appendRow(list); 0207 } 0208 if (cgs.hasKey("fax")) { 0209 QList<QStandardItem *> list; 0210 QString fax = d->contactModes.at(d->contactKeys.indexOf("fax")); 0211 list.append(new QStandardItem(fax)); 0212 list.append(new QStandardItem(cgs.readEntry("fax"))); 0213 modes->appendRow(list); 0214 } 0215 QStringList postal; 0216 postal << cgs.readEntry("street") << cgs.readEntry("postal-code") << cgs.readEntry("city") << cgs.readEntry("country"); 0217 QString address; 0218 Q_FOREACH(QString part, postal) { 0219 if (!part.isEmpty()) { 0220 address+= part + "\n"; 0221 } 0222 } 0223 if (!address.isEmpty()) { 0224 QList<QStandardItem *> list; 0225 QString add = d->contactModes.at(d->contactKeys.indexOf("address")); 0226 list.append(new QStandardItem(add)); 0227 list.append(new QStandardItem(address)); 0228 modes->appendRow(list); 0229 } 0230 modes->setHorizontalHeaderLabels(headerlabels); 0231 connect(aUi->btnAdd, SIGNAL(clicked()), this, SLOT(addContactEntry())); 0232 connect(aUi->btnRemove, SIGNAL(clicked()), this, SLOT(removeContactEntry())); 0233 0234 d->cmbAuthorProfiles->addItem(profile); 0235 d->profileUiList.append(aUi); 0236 d->stack->addWidget(w); 0237 } 0238 } 0239 0240 0241 // Add a default profile 0242 aUi = new Ui::KoConfigAuthorPage(); 0243 w = new QWidget; 0244 if (!profiles.contains(d->defaultAuthor) || profilesNew.contains(d->defaultAuthor)) { 0245 //w->setEnabled(false); 0246 aUi->setupUi(w); 0247 w->setEnabled(false); 0248 d->cmbAuthorProfiles->insertItem(0, d->defaultAuthor); 0249 d->stack->insertWidget(0, w); 0250 d->profileUiList.insert(0, aUi); 0251 } 0252 0253 0254 // Connect slots 0255 connect(d->cmbAuthorProfiles, SIGNAL(currentIndexChanged(int)), this, SLOT(profileChanged(int))); 0256 connect(newUser, SIGNAL(clicked(bool)), this, SLOT(addUser())); 0257 connect(d->bnDeleteUser, SIGNAL(clicked(bool)), this, SLOT(deleteUser())); 0258 0259 d->cmbAuthorProfiles->setCurrentIndex(0); 0260 profileChanged(0); 0261 } 0262 0263 KoConfigAuthorPage::~KoConfigAuthorPage() 0264 { 0265 delete d; 0266 } 0267 0268 void KoConfigAuthorPage::profileChanged(int i) 0269 { 0270 d->stack->setCurrentIndex(i); 0271 // Profile 0 should never be deleted: it's the anonymous profile. 0272 d->bnDeleteUser->setEnabled(i > 0); 0273 } 0274 0275 void KoConfigAuthorPage::addUser() 0276 { 0277 bool ok; 0278 QString profileName = QInputDialog::getText(this, i18n("Name of Profile"), i18n("Name (not duplicate or blank name):"), QLineEdit::Normal, "", &ok); 0279 0280 if (!ok) { 0281 return; 0282 } 0283 0284 Ui::KoConfigAuthorPage *curUi = d->profileUiList[d->cmbAuthorProfiles->currentIndex()]; 0285 Ui::KoConfigAuthorPage *aUi = new Ui::KoConfigAuthorPage(); 0286 QWidget *w = new QWidget; 0287 aUi->setupUi(w); 0288 0289 aUi->leNickName->setText(curUi->leNickName->text()); 0290 aUi->leInitials->setText(curUi->leInitials->text()); 0291 aUi->leTitle->setText(curUi->leTitle->text()); 0292 aUi->leCompany->setText(curUi->leCompany->text()); 0293 aUi->leFirstName->setText(curUi->leFirstName->text()); 0294 aUi->leLastName->setText(curUi->leLastName->text()); 0295 aUi->lePosition->setText(curUi->lePosition->text()); 0296 QCompleter *positionSuggestions = new QCompleter(d->positions); 0297 positionSuggestions->setCaseSensitivity(Qt::CaseInsensitive); 0298 aUi->lePosition->setCompleter(positionSuggestions); 0299 aUi->tblContactInfo->setItemDelegate(new KoContactInfoDelegate(this, d->contactModes)); 0300 QStandardItemModel *modes = new QStandardItemModel(); 0301 aUi->tblContactInfo->setModel(modes); 0302 0303 connect(aUi->btnAdd, SIGNAL(clicked()), this, SLOT(addContactEntry())); 0304 connect(aUi->btnRemove, SIGNAL(clicked()), this, SLOT(removeContactEntry())); 0305 0306 int index = d->cmbAuthorProfiles->currentIndex() + 1; 0307 d->cmbAuthorProfiles->insertItem(index, profileName); 0308 d->profileUiList.insert(index, aUi); 0309 d->stack->insertWidget(index, w); 0310 d->cmbAuthorProfiles->setCurrentIndex(index); 0311 } 0312 0313 void KoConfigAuthorPage::deleteUser() 0314 { 0315 int index = d->cmbAuthorProfiles->currentIndex(); 0316 QWidget *w = d->stack->currentWidget(); 0317 0318 d->stack->removeWidget(w); 0319 d->profileUiList.removeAt(index); 0320 d->cmbAuthorProfiles->removeItem(index); 0321 delete w; 0322 } 0323 0324 void KoConfigAuthorPage::addContactEntry() 0325 { 0326 int i = d->cmbAuthorProfiles->currentIndex(); 0327 Ui::KoConfigAuthorPage *aUi = d->profileUiList[i]; 0328 QStandardItemModel *contact = static_cast<QStandardItemModel*>(aUi->tblContactInfo->model()); 0329 QList<QStandardItem*>list; 0330 list.append(new QStandardItem(d->contactModes.at(0))); 0331 list.append(new QStandardItem(i18n("New Contact Info"))); 0332 contact->appendRow(list); 0333 aUi->tblContactInfo->setModel(contact); 0334 } 0335 0336 void KoConfigAuthorPage::removeContactEntry() 0337 { 0338 int i = d->cmbAuthorProfiles->currentIndex(); 0339 Ui::KoConfigAuthorPage *aUi = d->profileUiList[i]; 0340 QModelIndex index = aUi->tblContactInfo->selectionModel()->currentIndex(); 0341 aUi->tblContactInfo->model()->removeRow(index.row()); 0342 } 0343 0344 void KoConfigAuthorPage::apply() 0345 { 0346 QString authorInfo = KoResourcePaths::getAppDataLocation() + "/authorinfo/"; 0347 QDir dir(authorInfo); 0348 if (!dir.mkpath(authorInfo)) { 0349 qWarning()<<"We can't make an author info directory, and therefore not save!"; 0350 return; 0351 } 0352 for (int i = 0; i < d->profileUiList.size(); i++) { 0353 if (d->cmbAuthorProfiles->itemText(i)!= d->defaultAuthor) { 0354 QByteArray ba; 0355 QDomDocument doc = QDomDocument(); 0356 Ui::KoConfigAuthorPage *aUi = d->profileUiList[i]; 0357 0358 QDomElement root = doc.createElement("author"); 0359 root.setAttribute("name", d->cmbAuthorProfiles->itemText(i)); 0360 0361 QDomElement nickname = doc.createElement("nickname"); 0362 nickname.appendChild(doc.createTextNode(aUi->leNickName->text())); 0363 root.appendChild(nickname); 0364 QDomElement givenname = doc.createElement("givenname"); 0365 givenname.appendChild(doc.createTextNode(aUi->leFirstName->text())); 0366 root.appendChild(givenname); 0367 QDomElement familyname = doc.createElement("familyname"); 0368 familyname.appendChild(doc.createTextNode(aUi->leLastName->text())); 0369 root.appendChild(familyname); 0370 QDomElement middlename = doc.createElement("middlename"); 0371 middlename.appendChild(doc.createTextNode(aUi->leInitials->text())); 0372 root.appendChild(middlename); 0373 QDomElement title = doc.createElement("title"); 0374 title.appendChild(doc.createTextNode(aUi->leTitle->text())); 0375 root.appendChild(title); 0376 QDomElement company = doc.createElement("company"); 0377 company.appendChild(doc.createTextNode(aUi->leCompany->text())); 0378 root.appendChild(company); 0379 QDomElement position = doc.createElement("position"); 0380 position.appendChild(doc.createTextNode(aUi->lePosition->text())); 0381 root.appendChild(position); 0382 if (aUi->tblContactInfo) { 0383 if (aUi->tblContactInfo->model()) { 0384 for (int i=0; i<aUi->tblContactInfo->model()->rowCount(); i++) { 0385 QModelIndex index = aUi->tblContactInfo->model()->index(i, 1); 0386 QModelIndex typeIndex = aUi->tblContactInfo->model()->index(i, 0); 0387 QDomElement contactEl = doc.createElement("contact"); 0388 QString content = QVariant(aUi->tblContactInfo->model()->data(index)).toString(); 0389 contactEl.appendChild(doc.createTextNode(content)); 0390 QString type = QVariant(aUi->tblContactInfo->model()->data(typeIndex)).toString(); 0391 contactEl.setAttribute("type", d->contactKeys.at(d->contactModes.indexOf(type))); 0392 root.appendChild(contactEl); 0393 } 0394 } 0395 } 0396 doc.appendChild(root); 0397 ba = doc.toByteArray(); 0398 0399 QFile f(authorInfo + d->cmbAuthorProfiles->itemText(i) +".authorinfo"); 0400 f.open(QFile::WriteOnly); 0401 if (f.write(ba) < 0) { 0402 qWarning()<<"Writing author info went wrong:"<<f.errorString(); 0403 } 0404 f.close(); 0405 } 0406 } 0407 } 0408 0409 KoContactInfoDelegate::KoContactInfoDelegate(QWidget *parent, QStringList contactModes): QStyledItemDelegate(parent), m_contactModes(contactModes) 0410 { 0411 } 0412 0413 KoContactInfoDelegate::~KoContactInfoDelegate() 0414 { 0415 0416 } 0417 0418 QWidget* KoContactInfoDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/*option*/, const QModelIndex &index) const 0419 { 0420 0421 if (index.column() > 0) { 0422 return new QLineEdit(parent); 0423 } else { 0424 QComboBox *box = new QComboBox(parent); 0425 box->addItems(m_contactModes); 0426 return box; 0427 } 0428 }