File indexing completed on 2024-05-19 04:29:32
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 } else { 0252 delete aUi; 0253 delete w; 0254 } 0255 0256 0257 // Connect slots 0258 connect(d->cmbAuthorProfiles, SIGNAL(currentIndexChanged(int)), this, SLOT(profileChanged(int))); 0259 connect(newUser, SIGNAL(clicked(bool)), this, SLOT(addUser())); 0260 connect(d->bnDeleteUser, SIGNAL(clicked(bool)), this, SLOT(deleteUser())); 0261 0262 d->cmbAuthorProfiles->setCurrentIndex(0); 0263 profileChanged(0); 0264 } 0265 0266 KoConfigAuthorPage::~KoConfigAuthorPage() 0267 { 0268 delete d; 0269 } 0270 0271 void KoConfigAuthorPage::profileChanged(int i) 0272 { 0273 d->stack->setCurrentIndex(i); 0274 // Profile 0 should never be deleted: it's the anonymous profile. 0275 d->bnDeleteUser->setEnabled(i > 0); 0276 } 0277 0278 void KoConfigAuthorPage::addUser() 0279 { 0280 bool ok; 0281 QString profileName = QInputDialog::getText(this, i18n("Name of Profile"), i18n("Name (not duplicate or blank name):"), QLineEdit::Normal, "", &ok); 0282 0283 if (!ok) { 0284 return; 0285 } 0286 0287 Ui::KoConfigAuthorPage *curUi = d->profileUiList[d->cmbAuthorProfiles->currentIndex()]; 0288 Ui::KoConfigAuthorPage *aUi = new Ui::KoConfigAuthorPage(); 0289 QWidget *w = new QWidget; 0290 aUi->setupUi(w); 0291 0292 aUi->leNickName->setText(curUi->leNickName->text()); 0293 aUi->leInitials->setText(curUi->leInitials->text()); 0294 aUi->leTitle->setText(curUi->leTitle->text()); 0295 aUi->leCompany->setText(curUi->leCompany->text()); 0296 aUi->leFirstName->setText(curUi->leFirstName->text()); 0297 aUi->leLastName->setText(curUi->leLastName->text()); 0298 aUi->lePosition->setText(curUi->lePosition->text()); 0299 QCompleter *positionSuggestions = new QCompleter(d->positions); 0300 positionSuggestions->setCaseSensitivity(Qt::CaseInsensitive); 0301 aUi->lePosition->setCompleter(positionSuggestions); 0302 aUi->tblContactInfo->setItemDelegate(new KoContactInfoDelegate(this, d->contactModes)); 0303 QStandardItemModel *modes = new QStandardItemModel(); 0304 aUi->tblContactInfo->setModel(modes); 0305 0306 connect(aUi->btnAdd, SIGNAL(clicked()), this, SLOT(addContactEntry())); 0307 connect(aUi->btnRemove, SIGNAL(clicked()), this, SLOT(removeContactEntry())); 0308 0309 int index = d->cmbAuthorProfiles->currentIndex() + 1; 0310 d->cmbAuthorProfiles->insertItem(index, profileName); 0311 d->profileUiList.insert(index, aUi); 0312 d->stack->insertWidget(index, w); 0313 d->cmbAuthorProfiles->setCurrentIndex(index); 0314 } 0315 0316 void KoConfigAuthorPage::deleteUser() 0317 { 0318 int index = d->cmbAuthorProfiles->currentIndex(); 0319 QWidget *w = d->stack->currentWidget(); 0320 0321 d->stack->removeWidget(w); 0322 d->profileUiList.removeAt(index); 0323 d->cmbAuthorProfiles->removeItem(index); 0324 delete w; 0325 } 0326 0327 void KoConfigAuthorPage::addContactEntry() 0328 { 0329 int i = d->cmbAuthorProfiles->currentIndex(); 0330 Ui::KoConfigAuthorPage *aUi = d->profileUiList[i]; 0331 QStandardItemModel *contact = static_cast<QStandardItemModel*>(aUi->tblContactInfo->model()); 0332 QList<QStandardItem*>list; 0333 list.append(new QStandardItem(d->contactModes.at(0))); 0334 list.append(new QStandardItem(i18n("New Contact Info"))); 0335 contact->appendRow(list); 0336 aUi->tblContactInfo->setModel(contact); 0337 } 0338 0339 void KoConfigAuthorPage::removeContactEntry() 0340 { 0341 int i = d->cmbAuthorProfiles->currentIndex(); 0342 Ui::KoConfigAuthorPage *aUi = d->profileUiList[i]; 0343 QModelIndex index = aUi->tblContactInfo->selectionModel()->currentIndex(); 0344 aUi->tblContactInfo->model()->removeRow(index.row()); 0345 } 0346 0347 void KoConfigAuthorPage::apply() 0348 { 0349 QString authorInfo = KoResourcePaths::getAppDataLocation() + "/authorinfo/"; 0350 QDir dir(authorInfo); 0351 if (!dir.mkpath(authorInfo)) { 0352 qWarning()<<"We can't make an author info directory, and therefore not save!"; 0353 return; 0354 } 0355 for (int i = 0; i < d->profileUiList.size(); i++) { 0356 if (d->cmbAuthorProfiles->itemText(i)!= d->defaultAuthor) { 0357 QByteArray ba; 0358 QDomDocument doc = QDomDocument(); 0359 Ui::KoConfigAuthorPage *aUi = d->profileUiList[i]; 0360 0361 QDomElement root = doc.createElement("author"); 0362 root.setAttribute("name", d->cmbAuthorProfiles->itemText(i)); 0363 0364 QDomElement nickname = doc.createElement("nickname"); 0365 nickname.appendChild(doc.createTextNode(aUi->leNickName->text())); 0366 root.appendChild(nickname); 0367 QDomElement givenname = doc.createElement("givenname"); 0368 givenname.appendChild(doc.createTextNode(aUi->leFirstName->text())); 0369 root.appendChild(givenname); 0370 QDomElement familyname = doc.createElement("familyname"); 0371 familyname.appendChild(doc.createTextNode(aUi->leLastName->text())); 0372 root.appendChild(familyname); 0373 QDomElement middlename = doc.createElement("middlename"); 0374 middlename.appendChild(doc.createTextNode(aUi->leInitials->text())); 0375 root.appendChild(middlename); 0376 QDomElement title = doc.createElement("title"); 0377 title.appendChild(doc.createTextNode(aUi->leTitle->text())); 0378 root.appendChild(title); 0379 QDomElement company = doc.createElement("company"); 0380 company.appendChild(doc.createTextNode(aUi->leCompany->text())); 0381 root.appendChild(company); 0382 QDomElement position = doc.createElement("position"); 0383 position.appendChild(doc.createTextNode(aUi->lePosition->text())); 0384 root.appendChild(position); 0385 if (aUi->tblContactInfo) { 0386 if (aUi->tblContactInfo->model()) { 0387 for (int i=0; i<aUi->tblContactInfo->model()->rowCount(); i++) { 0388 QModelIndex index = aUi->tblContactInfo->model()->index(i, 1); 0389 QModelIndex typeIndex = aUi->tblContactInfo->model()->index(i, 0); 0390 QDomElement contactEl = doc.createElement("contact"); 0391 QString content = QVariant(aUi->tblContactInfo->model()->data(index)).toString(); 0392 contactEl.appendChild(doc.createTextNode(content)); 0393 QString type = QVariant(aUi->tblContactInfo->model()->data(typeIndex)).toString(); 0394 contactEl.setAttribute("type", d->contactKeys.at(d->contactModes.indexOf(type))); 0395 root.appendChild(contactEl); 0396 } 0397 } 0398 } 0399 doc.appendChild(root); 0400 ba = doc.toByteArray(); 0401 0402 QFile f(authorInfo + d->cmbAuthorProfiles->itemText(i) +".authorinfo"); 0403 f.open(QFile::WriteOnly); 0404 if (f.write(ba) < 0) { 0405 qWarning()<<"Writing author info went wrong:"<<f.errorString(); 0406 } 0407 f.close(); 0408 } 0409 } 0410 } 0411 0412 KoContactInfoDelegate::KoContactInfoDelegate(QWidget *parent, QStringList contactModes): QStyledItemDelegate(parent), m_contactModes(contactModes) 0413 { 0414 } 0415 0416 KoContactInfoDelegate::~KoContactInfoDelegate() 0417 { 0418 0419 } 0420 0421 QWidget* KoContactInfoDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/*option*/, const QModelIndex &index) const 0422 { 0423 0424 if (index.column() > 0) { 0425 return new QLineEdit(parent); 0426 } else { 0427 QComboBox *box = new QComboBox(parent); 0428 box->addItems(m_contactModes); 0429 return box; 0430 } 0431 }