diff --git a/src/libkdepim/ldap/addhostdialog.cpp b/src/libkdepim/ldap/addhostdialog.cpp index e3a5e45..9f28cf6 100644 --- a/src/libkdepim/ldap/addhostdialog.cpp +++ b/src/libkdepim/ldap/addhostdialog.cpp @@ -1,201 +1,201 @@ /* This file is part of libkldap. Copyright (c) 2002-2010 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "addhostdialog.h" #include #include #include #include #include #include #include #include #include #include using namespace KLDAP; class KLDAP::AddHostDialogPrivate { public: AddHostDialogPrivate(AddHostDialog *qq) : q(qq) { } ~AddHostDialogPrivate() { writeConfig(); } void readConfig(); void writeConfig(); KLDAP::LdapConfigWidget *mCfg = nullptr; KLDAP::LdapServer *mServer = nullptr; QPushButton *mOkButton = nullptr; AddHostDialog *q = nullptr; }; void AddHostDialogPrivate::readConfig() { KConfigGroup group(KSharedConfig::openConfig(), "AddHostDialog"); const QSize size = group.readEntry("Size", QSize(600, 400)); if (size.isValid()) { q->resize(size); } } void AddHostDialogPrivate::writeConfig() { KConfigGroup group(KSharedConfig::openConfig(), "AddHostDialog"); group.writeEntry("Size", q->size()); group.sync(); } AddHostDialog::AddHostDialog(KLDAP::LdapServer *server, QWidget *parent) : QDialog(parent) , d(new KLDAP::AddHostDialogPrivate(this)) { - setWindowTitle(i18n("Add Host")); + setWindowTitle(i18nc("@title:window", "Add Host")); QVBoxLayout *mainLayout = new QVBoxLayout(this); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); d->mOkButton = buttonBox->button(QDialogButtonBox::Ok); d->mOkButton->setDefault(true); d->mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox, &QDialogButtonBox::rejected, this, &AddHostDialog::reject); setModal(true); d->mServer = server; QWidget *page = new QWidget(this); mainLayout->addWidget(page); mainLayout->addWidget(buttonBox); QHBoxLayout *layout = new QHBoxLayout(page); layout->setContentsMargins(0, 0, 0, 0); d->mCfg = new KLDAP::LdapConfigWidget( KLDAP::LdapConfigWidget::W_USER |KLDAP::LdapConfigWidget::W_PASS |KLDAP::LdapConfigWidget::W_BINDDN |KLDAP::LdapConfigWidget::W_REALM |KLDAP::LdapConfigWidget::W_HOST |KLDAP::LdapConfigWidget::W_PORT |KLDAP::LdapConfigWidget::W_VER |KLDAP::LdapConfigWidget::W_TIMELIMIT |KLDAP::LdapConfigWidget::W_SIZELIMIT |KLDAP::LdapConfigWidget::W_PAGESIZE |KLDAP::LdapConfigWidget::W_DN |KLDAP::LdapConfigWidget::W_FILTER |KLDAP::LdapConfigWidget::W_SECBOX |KLDAP::LdapConfigWidget::W_AUTHBOX, page); layout->addWidget(d->mCfg); d->mCfg->setHost(d->mServer->host()); d->mCfg->setPort(d->mServer->port()); d->mCfg->setDn(d->mServer->baseDn()); d->mCfg->setUser(d->mServer->user()); d->mCfg->setBindDn(d->mServer->bindDn()); d->mCfg->setPassword(d->mServer->password()); d->mCfg->setTimeLimit(d->mServer->timeLimit()); d->mCfg->setSizeLimit(d->mServer->sizeLimit()); d->mCfg->setPageSize(d->mServer->pageSize()); d->mCfg->setVersion(d->mServer->version()); d->mCfg->setFilter(d->mServer->filter()); switch (d->mServer->security()) { case KLDAP::LdapServer::TLS: d->mCfg->setSecurity(KLDAP::LdapConfigWidget::TLS); break; case KLDAP::LdapServer::SSL: d->mCfg->setSecurity(KLDAP::LdapConfigWidget::SSL); break; default: d->mCfg->setSecurity(KLDAP::LdapConfigWidget::None); } switch (d->mServer->auth()) { case KLDAP::LdapServer::Simple: d->mCfg->setAuth(KLDAP::LdapConfigWidget::Simple); break; case KLDAP::LdapServer::SASL: d->mCfg->setAuth(KLDAP::LdapConfigWidget::SASL); break; default: d->mCfg->setAuth(KLDAP::LdapConfigWidget::Anonymous); } d->mCfg->setMech(d->mServer->mech()); KAcceleratorManager::manage(this); connect(d->mCfg, &KLDAP::LdapConfigWidget::hostNameChanged, this, &AddHostDialog::slotHostEditChanged); connect(d->mOkButton, &QPushButton::clicked, this, &AddHostDialog::slotOk); d->mOkButton->setEnabled(!d->mServer->host().isEmpty()); d->readConfig(); } AddHostDialog::~AddHostDialog() { delete d; } void AddHostDialog::slotHostEditChanged(const QString &text) { d->mOkButton->setEnabled(!text.isEmpty()); } void AddHostDialog::slotOk() { d->mServer->setHost(d->mCfg->host()); d->mServer->setPort(d->mCfg->port()); d->mServer->setBaseDn(d->mCfg->dn()); d->mServer->setUser(d->mCfg->user()); d->mServer->setBindDn(d->mCfg->bindDn()); d->mServer->setPassword(d->mCfg->password()); d->mServer->setTimeLimit(d->mCfg->timeLimit()); d->mServer->setSizeLimit(d->mCfg->sizeLimit()); d->mServer->setPageSize(d->mCfg->pageSize()); d->mServer->setVersion(d->mCfg->version()); d->mServer->setFilter(d->mCfg->filter()); switch (d->mCfg->security()) { case KLDAP::LdapConfigWidget::TLS: d->mServer->setSecurity(KLDAP::LdapServer::TLS); break; case KLDAP::LdapConfigWidget::SSL: d->mServer->setSecurity(KLDAP::LdapServer::SSL); break; default: d->mServer->setSecurity(KLDAP::LdapServer::None); } switch (d->mCfg->auth()) { case KLDAP::LdapConfigWidget::Simple: d->mServer->setAuth(KLDAP::LdapServer::Simple); break; case KLDAP::LdapConfigWidget::SASL: d->mServer->setAuth(KLDAP::LdapServer::SASL); break; default: d->mServer->setAuth(KLDAP::LdapServer::Anonymous); } d->mServer->setMech(d->mCfg->mech()); QDialog::accept(); } #include "moc_addhostdialog.cpp" diff --git a/src/libkdepim/ldap/ldapconfigurewidget.cpp b/src/libkdepim/ldap/ldapconfigurewidget.cpp index 6b4392b..22d92aa 100644 --- a/src/libkdepim/ldap/ldapconfigurewidget.cpp +++ b/src/libkdepim/ldap/ldapconfigurewidget.cpp @@ -1,356 +1,356 @@ /* * Copyright (C) 2019 Laurent Montel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ldapconfigurewidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ldapclientsearch.h" #include "ldapclientsearchconfig.h" #include #include "addhostdialog.h" using namespace KLDAP; class LDAPItem : public QListWidgetItem { public: LDAPItem(QListWidget *parent, const KLDAP::LdapServer &server, bool isActive = false) : QListWidgetItem(parent, QListWidgetItem::UserType) , mIsActive(isActive) { setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable); setCheckState(isActive ? Qt::Checked : Qt::Unchecked); setServer(server); } void setServer(const KLDAP::LdapServer &server) { mServer = server; setText(mServer.host()); } const KLDAP::LdapServer &server() const { return mServer; } void setIsActive(bool isActive) { mIsActive = isActive; } bool isActive() const { return mIsActive; } private: KLDAP::LdapServer mServer; bool mIsActive = false; }; LdapConfigureWidget::LdapConfigureWidget(QWidget *parent) : QWidget(parent) { mClientSearchConfig = new KLDAP::LdapClientSearchConfig; initGUI(); connect(mHostListView, &QListWidget::currentItemChanged, this, &LdapConfigureWidget::slotSelectionChanged); connect(mHostListView, &QListWidget::itemDoubleClicked, this, &LdapConfigureWidget::slotEditHost); connect(mHostListView, &QListWidget::itemClicked, this, &LdapConfigureWidget::slotItemClicked); connect(mUpButton, &QToolButton::clicked, this, &LdapConfigureWidget::slotMoveUp); connect(mDownButton, &QToolButton::clicked, this, &LdapConfigureWidget::slotMoveDown); } LdapConfigureWidget::~LdapConfigureWidget() { delete mClientSearchConfig; } void LdapConfigureWidget::slotSelectionChanged(QListWidgetItem *item) { bool state = (item != nullptr); mEditButton->setEnabled(state); mRemoveButton->setEnabled(state); mDownButton->setEnabled(item && (mHostListView->row(item) != (mHostListView->count() - 1))); mUpButton->setEnabled(item && (mHostListView->row(item) != 0)); } void LdapConfigureWidget::slotItemClicked(QListWidgetItem *item) { LDAPItem *ldapItem = dynamic_cast(item); if (!ldapItem) { return; } if ((ldapItem->checkState() == Qt::Checked) != ldapItem->isActive()) { Q_EMIT changed(true); ldapItem->setIsActive(ldapItem->checkState() == Qt::Checked); } } void LdapConfigureWidget::slotAddHost() { KLDAP::LdapServer server; KLDAP::AddHostDialog dlg(&server, this); if (dlg.exec() && !server.host().trimmed().isEmpty()) { //krazy:exclude=crashy new LDAPItem(mHostListView, server); Q_EMIT changed(true); } } void LdapConfigureWidget::slotEditHost() { LDAPItem *item = dynamic_cast(mHostListView->currentItem()); if (!item) { return; } KLDAP::LdapServer server = item->server(); KLDAP::AddHostDialog dlg(&server, this); - dlg.setWindowTitle(i18n("Edit Host")); + dlg.setWindowTitle(i18nc("@title:window", "Edit Host")); if (dlg.exec() && !server.host().isEmpty()) { //krazy:exclude=crashy item->setServer(server); Q_EMIT changed(true); } } void LdapConfigureWidget::slotRemoveHost() { QListWidgetItem *item = mHostListView->currentItem(); if (!item) { return; } LDAPItem *ldapItem = dynamic_cast(item); if (KMessageBox::No == KMessageBox::questionYesNo(this, i18n("Do you want to remove setting for host \"%1\"?", ldapItem->server().host()), i18n("Remove Host"))) { return; } delete mHostListView->takeItem(mHostListView->currentRow()); slotSelectionChanged(mHostListView->currentItem()); Q_EMIT changed(true); } static void swapItems(LDAPItem *item, LDAPItem *other) { KLDAP::LdapServer server = item->server(); bool isActive = item->isActive(); item->setServer(other->server()); item->setIsActive(other->isActive()); item->setCheckState(other->isActive() ? Qt::Checked : Qt::Unchecked); other->setServer(server); other->setIsActive(isActive); other->setCheckState(isActive ? Qt::Checked : Qt::Unchecked); } void LdapConfigureWidget::slotMoveUp() { const QList selectedItems = mHostListView->selectedItems(); if (selectedItems.isEmpty()) { return; } LDAPItem *item = static_cast(mHostListView->selectedItems().first()); if (!item) { return; } LDAPItem *above = static_cast(mHostListView->item(mHostListView->row(item) - 1)); if (!above) { return; } swapItems(item, above); mHostListView->setCurrentItem(above); above->setSelected(true); Q_EMIT changed(true); } void LdapConfigureWidget::slotMoveDown() { const QList selectedItems = mHostListView->selectedItems(); if (selectedItems.isEmpty()) { return; } LDAPItem *item = static_cast(mHostListView->selectedItems().first()); if (!item) { return; } LDAPItem *below = static_cast(mHostListView->item(mHostListView->row(item) + 1)); if (!below) { return; } swapItems(item, below); mHostListView->setCurrentItem(below); below->setSelected(true); Q_EMIT changed(true); } void LdapConfigureWidget::load() { mHostListView->clear(); KConfig *config = KLDAP::LdapClientSearchConfig::config(); KConfigGroup group(config, "LDAP"); int count = group.readEntry("NumSelectedHosts", 0); for (int i = 0; i < count; ++i) { KLDAP::LdapServer server; mClientSearchConfig->readConfig(server, group, i, true); LDAPItem *item = new LDAPItem(mHostListView, server, true); item->setCheckState(Qt::Checked); } count = group.readEntry("NumHosts", 0); for (int i = 0; i < count; ++i) { KLDAP::LdapServer server; mClientSearchConfig->readConfig(server, group, i, false); new LDAPItem(mHostListView, server); } Q_EMIT changed(false); } void LdapConfigureWidget::save() { mClientSearchConfig->clearWalletPassword(); KConfig *config = KLDAP::LdapClientSearchConfig::config(); config->deleteGroup("LDAP"); KConfigGroup group(config, "LDAP"); int selected = 0; int unselected = 0; for (int i = 0; i < mHostListView->count(); ++i) { LDAPItem *item = dynamic_cast(mHostListView->item(i)); if (!item) { continue; } KLDAP::LdapServer server = item->server(); if (item->checkState() == Qt::Checked) { mClientSearchConfig->writeConfig(server, group, selected, true); selected++; } else { mClientSearchConfig->writeConfig(server, group, unselected, false); unselected++; } } group.writeEntry("NumSelectedHosts", selected); group.writeEntry("NumHosts", unselected); config->sync(); Q_EMIT changed(false); } void LdapConfigureWidget::initGUI() { QVBoxLayout *layout = new QVBoxLayout(this); layout->setObjectName(QStringLiteral("layout")); layout->setContentsMargins(0, 0, 0, 0); QGroupBox *groupBox = new QGroupBox(i18n("LDAP Servers")); layout->addWidget(groupBox); QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->setObjectName(QStringLiteral("mainlayout")); groupBox->setLayout(mainLayout); // Contents of the QVGroupBox: label and hbox QLabel *label = new QLabel(i18n("Check all servers that should be used:")); mainLayout->addWidget(label); QWidget *hBox = new QWidget(this); mainLayout->addWidget(hBox); QHBoxLayout *hBoxHBoxLayout = new QHBoxLayout(hBox); hBoxHBoxLayout->setContentsMargins(0, 0, 0, 0); hBoxHBoxLayout->setSpacing(6); // Contents of the hbox: listview and up/down buttons on the right (vbox) mHostListView = new QListWidget(hBox); hBoxHBoxLayout->addWidget(mHostListView); mHostListView->setSortingEnabled(false); QWidget *upDownBox = new QWidget(hBox); QVBoxLayout *upDownBoxVBoxLayout = new QVBoxLayout(upDownBox); upDownBoxVBoxLayout->setContentsMargins(0, 0, 0, 0); hBoxHBoxLayout->addWidget(upDownBox); upDownBoxVBoxLayout->setSpacing(6); mUpButton = new QToolButton(upDownBox); upDownBoxVBoxLayout->addWidget(mUpButton); mUpButton->setIcon(QIcon::fromTheme(QStringLiteral("go-up"))); mUpButton->setIconSize(QSize(KIconLoader::SizeSmall, KIconLoader::SizeSmall)); mUpButton->setEnabled(false); // b/c no item is selected yet mDownButton = new QToolButton(upDownBox); upDownBoxVBoxLayout->addWidget(mDownButton); mDownButton->setIcon(QIcon::fromTheme(QStringLiteral("go-down"))); mDownButton->setIconSize(QSize(KIconLoader::SizeSmall, KIconLoader::SizeSmall)); mDownButton->setEnabled(false); // b/c no item is selected yet QWidget *spacer = new QWidget(upDownBox); upDownBoxVBoxLayout->addWidget(spacer); upDownBoxVBoxLayout->setStretchFactor(spacer, 100); QDialogButtonBox *buttons = new QDialogButtonBox(this); QPushButton *add = buttons->addButton(i18n("&Add Host..."), QDialogButtonBox::ActionRole); connect(add, &QPushButton::clicked, this, &LdapConfigureWidget::slotAddHost); mEditButton = buttons->addButton(i18n("&Edit Host..."), QDialogButtonBox::ActionRole); connect(mEditButton, &QPushButton::clicked, this, &LdapConfigureWidget::slotEditHost); mEditButton->setEnabled(false); mRemoveButton = buttons->addButton(i18n("&Remove Host"), QDialogButtonBox::ActionRole); connect(mRemoveButton, &QPushButton::clicked, this, &LdapConfigureWidget::slotRemoveHost); mRemoveButton->setEnabled(false); buttons->layout(); layout->addWidget(buttons); } diff --git a/src/libkdepim/ldap/ldapsearchdialog.cpp b/src/libkdepim/ldap/ldapsearchdialog.cpp index bed8bcd..3a4a6ad 100644 --- a/src/libkdepim/ldap/ldapsearchdialog.cpp +++ b/src/libkdepim/ldap/ldapsearchdialog.cpp @@ -1,895 +1,895 @@ /* * This file is part of libkldap. * * Copyright (C) 2002 Klarälvdalens Datakonsult AB * * Author: Steffen Hansen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ldapsearchdialog.h" #include "ldapclient.h" #include "ldapclientsearchconfig.h" #include "widgets/progressindicatorlabel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace KLDAP; static QString asUtf8(const QByteArray &val) { if (val.isEmpty()) { return QString(); } const char *data = val.data(); //QString::fromUtf8() bug workaround if (data[ val.size() - 1 ] == '\0') { return QString::fromUtf8(data, val.size() - 1); } else { return QString::fromUtf8(data, val.size()); } } static QString join(const KLDAP::LdapAttrValue &lst, const QString &sep) { QString res; bool alredy = false; KLDAP::LdapAttrValue::ConstIterator end(lst.constEnd()); for (KLDAP::LdapAttrValue::ConstIterator it = lst.constBegin(); it != end; ++it) { if (alredy) { res += sep; } alredy = true; res += asUtf8(*it); } return res; } static QMap &adrbookattr2ldap() { static QMap keys; if (keys.isEmpty()) { keys[ i18nc("@item LDAP search key", "Title") ] = QStringLiteral("title"); keys[ i18n("Full Name") ] = QStringLiteral("cn"); keys[ i18nc("@item LDAP search key", "Email") ] = QStringLiteral("mail"); keys[ i18n("Home Number") ] = QStringLiteral("homePhone"); keys[ i18n("Work Number") ] = QStringLiteral("telephoneNumber"); keys[ i18n("Mobile Number") ] = QStringLiteral("mobile"); keys[ i18n("Fax Number") ] = QStringLiteral("facsimileTelephoneNumber"); keys[ i18n("Pager") ] = QStringLiteral("pager"); keys[ i18n("Street") ] = QStringLiteral("street"); keys[ i18nc("@item LDAP search key", "State") ] = QStringLiteral("st"); keys[ i18n("Country") ] = QStringLiteral("co"); keys[ i18n("City") ] = QStringLiteral("l"); //krazy:exclude=doublequote_chars keys[ i18n("Organization") ] = QStringLiteral("o"); //krazy:exclude=doublequote_chars keys[ i18n("Company") ] = QStringLiteral("Company"); keys[ i18n("Department") ] = QStringLiteral("department"); keys[ i18n("Zip Code") ] = QStringLiteral("postalCode"); keys[ i18n("Postal Address") ] = QStringLiteral("postalAddress"); keys[ i18n("Description") ] = QStringLiteral("description"); keys[ i18n("User ID") ] = QStringLiteral("uid"); } return keys; } static QString makeFilter(const QString &query, LdapSearchDialog::FilterType attr, bool startsWith) { /* The reasoning behind this filter is: * If it's a person, or a distlist, show it, even if it doesn't have an email address. * If it's not a person, or a distlist, only show it if it has an email attribute. * This allows both resource accounts with an email address which are not a person and * person entries without an email address to show up, while still not showing things * like structural entries in the ldap tree. */ QString result(QStringLiteral("&(|(objectclass=person)(objectclass=groupofnames)(mail=*))(")); if (query.isEmpty()) { // Return a filter that matches everything return result + QStringLiteral("|(cn=*)(sn=*)") + QLatin1Char(')'); } if (attr == LdapSearchDialog::Name) { result += startsWith ? QStringLiteral("|(cn=%1*)(sn=%2*)") : QStringLiteral("|(cn=*%1*)(sn=*%2*)"); result = result.arg(query, query); } else { result += startsWith ? QStringLiteral("%1=%2*") : QStringLiteral("%1=*%2*"); if (attr == LdapSearchDialog::Email) { result = result.arg(QStringLiteral("mail"), query); } else if (attr == LdapSearchDialog::HomeNumber) { result = result.arg(QStringLiteral("homePhone"), query); } else if (attr == LdapSearchDialog::WorkNumber) { result = result.arg(QStringLiteral("telephoneNumber"), query); } else { // Error? result.clear(); return result; } } result += QLatin1Char(')'); return result; } static KContacts::Addressee convertLdapAttributesToAddressee(const KLDAP::LdapAttrMap &attrs) { KContacts::Addressee addr; // name if (!attrs.value(QStringLiteral("cn")).isEmpty()) { addr.setNameFromString(asUtf8(attrs[QStringLiteral("cn")].first())); } // email KLDAP::LdapAttrValue lst = attrs[QStringLiteral("mail")]; KLDAP::LdapAttrValue::ConstIterator it = lst.constBegin(); bool pref = true; while (it != lst.constEnd()) { addr.insertEmail(asUtf8(*it), pref); pref = false; ++it; } if (!attrs.value(QStringLiteral("o")).isEmpty()) { addr.setOrganization(asUtf8(attrs[ QStringLiteral("o") ].first())); } if (addr.organization().isEmpty() && !attrs.value(QStringLiteral("Company")).isEmpty()) { addr.setOrganization(asUtf8(attrs[ QStringLiteral("Company") ].first())); } // Address KContacts::Address workAddr(KContacts::Address::Work); if (!attrs.value(QStringLiteral("department")).isEmpty()) { addr.setDepartment(asUtf8(attrs[ QStringLiteral("department") ].first())); } if (!workAddr.isEmpty()) { addr.insertAddress(workAddr); } // phone if (!attrs.value(QStringLiteral("homePhone")).isEmpty()) { KContacts::PhoneNumber homeNr = asUtf8(attrs[ QStringLiteral("homePhone") ].first()); homeNr.setType(KContacts::PhoneNumber::Home); addr.insertPhoneNumber(homeNr); } if (!attrs.value(QStringLiteral("telephoneNumber")).isEmpty()) { KContacts::PhoneNumber workNr = asUtf8(attrs[ QStringLiteral("telephoneNumber") ].first()); workNr.setType(KContacts::PhoneNumber::Work); addr.insertPhoneNumber(workNr); } if (!attrs.value(QStringLiteral("facsimileTelephoneNumber")).isEmpty()) { KContacts::PhoneNumber faxNr = asUtf8(attrs[ QStringLiteral("facsimileTelephoneNumber") ].first()); faxNr.setType(KContacts::PhoneNumber::Fax); addr.insertPhoneNumber(faxNr); } if (!attrs.value(QStringLiteral("mobile")).isEmpty()) { KContacts::PhoneNumber cellNr = asUtf8(attrs[ QStringLiteral("mobile") ].first()); cellNr.setType(KContacts::PhoneNumber::Cell); addr.insertPhoneNumber(cellNr); } if (!attrs.value(QStringLiteral("pager")).isEmpty()) { KContacts::PhoneNumber pagerNr = asUtf8(attrs[ QStringLiteral("pager") ].first()); pagerNr.setType(KContacts::PhoneNumber::Pager); addr.insertPhoneNumber(pagerNr); } return addr; } class ContactListModel : public QAbstractTableModel { public: enum Role { ServerRole = Qt::UserRole + 1 }; explicit ContactListModel(QObject *parent) : QAbstractTableModel(parent) { } void addContact(const KLDAP::LdapAttrMap &contact, const QString &server) { beginResetModel(); mContactList.append(contact); mServerList.append(server); endResetModel(); } QPair contact(const QModelIndex &index) const { if (!index.isValid() || index.row() < 0 || index.row() >= mContactList.count()) { return qMakePair(KLDAP::LdapAttrMap(), QString()); } return qMakePair(mContactList.at(index.row()), mServerList.at(index.row())); } QString email(const QModelIndex &index) const { if (!index.isValid() || index.row() < 0 || index.row() >= mContactList.count()) { return QString(); } return asUtf8(mContactList.at(index.row()).value(QStringLiteral("mail")).first()).trimmed(); } QString fullName(const QModelIndex &index) const { if (!index.isValid() || index.row() < 0 || index.row() >= mContactList.count()) { return QString(); } return asUtf8(mContactList.at(index.row()).value(QStringLiteral("cn")).first()).trimmed(); } void clear() { beginResetModel(); mContactList.clear(); mServerList.clear(); endResetModel(); } int rowCount(const QModelIndex &parent = QModelIndex()) const override { if (!parent.isValid()) { return mContactList.count(); } else { return 0; } } int columnCount(const QModelIndex &parent = QModelIndex()) const override { if (!parent.isValid()) { return 18; } else { return 0; } } QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override { if (orientation == Qt::Vertical || role != Qt::DisplayRole || section < 0 || section > 17) { return QVariant(); } switch (section) { case 0: return i18n("Full Name"); case 1: return i18nc("@title:column Column containing email addresses", "Email"); case 2: return i18n("Home Number"); case 3: return i18n("Work Number"); case 4: return i18n("Mobile Number"); case 5: return i18n("Fax Number"); case 6: return i18n("Company"); case 7: return i18n("Organization"); case 8: return i18n("Street"); case 9: return i18nc("@title:column Column containing the residential state of the address", "State"); case 10: return i18n("Country"); case 11: return i18n("Zip Code"); case 12: return i18n("Postal Address"); case 13: return i18n("City"); case 14: return i18n("Department"); case 15: return i18n("Description"); case 16: return i18n("User ID"); case 17: return i18nc("@title:column Column containing title of the person", "Title"); default: return QVariant(); } } QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override { if (!index.isValid()) { return QVariant(); } if (index.row() < 0 || index.row() >= mContactList.count() || index.column() < 0 || index.column() > 17) { return QVariant(); } if (role == ServerRole) { return mServerList.at(index.row()); } if ((role != Qt::DisplayRole) && (role != Qt::ToolTipRole)) { return QVariant(); } const KLDAP::LdapAttrMap map = mContactList.at(index.row()); switch (index.column()) { case 0: return join(map.value(QStringLiteral("cn")), QStringLiteral(", ")); case 1: return join(map.value(QStringLiteral("mail")), QStringLiteral(", ")); case 2: return join(map.value(QStringLiteral("homePhone")), QStringLiteral(", ")); case 3: return join(map.value(QStringLiteral("telephoneNumber")), QStringLiteral(", ")); case 4: return join(map.value(QStringLiteral("mobile")), QStringLiteral(", ")); case 5: return join(map.value(QStringLiteral("facsimileTelephoneNumber")), QStringLiteral(", ")); case 6: return join(map.value(QStringLiteral("Company")), QStringLiteral(", ")); case 7: return join(map.value(QStringLiteral("o")), QStringLiteral(", ")); case 8: return join(map.value(QStringLiteral("street")), QStringLiteral(", ")); case 9: return join(map.value(QStringLiteral("st")), QStringLiteral(", ")); case 10: return join(map.value(QStringLiteral("co")), QStringLiteral(", ")); case 11: return join(map.value(QStringLiteral("postalCode")), QStringLiteral(", ")); case 12: return join(map.value(QStringLiteral("postalAddress")), QStringLiteral(", ")); case 13: return join(map.value(QStringLiteral("l")), QStringLiteral(", ")); case 14: return join(map.value(QStringLiteral("department")), QStringLiteral(", ")); case 15: return join(map.value(QStringLiteral("description")), QStringLiteral(", ")); case 16: return join(map.value(QStringLiteral("uid")), QStringLiteral(", ")); case 17: return join(map.value(QStringLiteral("title")), QStringLiteral(", ")); default: return QVariant(); } } private: QVector mContactList; QStringList mServerList; }; class Q_DECL_HIDDEN LdapSearchDialog::Private { public: Private(LdapSearchDialog *qq) : q(qq) { } QList< QPair > selectedItems() { QList< QPair > contacts; const QModelIndexList selected = mResultView->selectionModel()->selectedRows(); const int numberOfSelectedElement(selected.count()); contacts.reserve(numberOfSelectedElement); for (int i = 0; i < numberOfSelectedElement; ++i) { contacts.append(mModel->contact(sortproxy->mapToSource(selected.at(i)))); } return contacts; } void saveSettings(); void restoreSettings(); void cancelQuery(); void slotAddResult(const KLDAP::LdapClient &, const KLDAP::LdapObject &); void slotSetScope(bool); void slotStartSearch(); void slotStopSearch(); void slotSearchDone(); void slotError(const QString &); void slotSelectAll(); void slotUnselectAll(); void slotSelectionChanged(); LdapSearchDialog *q; KGuiItem startSearchGuiItem; KGuiItem stopSearchGuiItem; int mNumHosts = 0; QList mLdapClientList; bool mIsConfigured = false; KContacts::Addressee::List mSelectedContacts; KComboBox *mFilterCombo = nullptr; KComboBox *mSearchType = nullptr; QLineEdit *mSearchEdit = nullptr; QCheckBox *mRecursiveCheckbox = nullptr; QTableView *mResultView = nullptr; QPushButton *mSearchButton = nullptr; ContactListModel *mModel = nullptr; KPIM::ProgressIndicatorLabel *progressIndication = nullptr; QSortFilterProxyModel *sortproxy = nullptr; KLineEdit *searchLine = nullptr; QPushButton *user1Button = nullptr; }; LdapSearchDialog::LdapSearchDialog(QWidget *parent) : QDialog(parent) , d(new Private(this)) { - setWindowTitle(i18n("Import Contacts from LDAP")); + setWindowTitle(i18nc("@title:window", "Import Contacts from LDAP")); QVBoxLayout *mainLayout = new QVBoxLayout(this); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel, this); d->user1Button = new QPushButton; buttonBox->addButton(d->user1Button, QDialogButtonBox::ActionRole); QPushButton *user2Button = new QPushButton; buttonBox->addButton(user2Button, QDialogButtonBox::ActionRole); connect(d->user1Button, &QPushButton::clicked, this, &LdapSearchDialog::slotUser1); connect(user2Button, &QPushButton::clicked, this, &LdapSearchDialog::slotUser2); connect(buttonBox, &QDialogButtonBox::rejected, this, &LdapSearchDialog::slotCancelClicked); d->user1Button->setDefault(true); setModal(false); KGuiItem::assign(buttonBox->button(QDialogButtonBox::Cancel), KStandardGuiItem::close()); QFrame *page = new QFrame(this); mainLayout->addWidget(page); mainLayout->addWidget(buttonBox); QVBoxLayout *topLayout = new QVBoxLayout(page); topLayout->setContentsMargins(0, 0, 0, 0); QGroupBox *groupBox = new QGroupBox(i18n("Search for Addresses in Directory"), page); QGridLayout *boxLayout = new QGridLayout(); groupBox->setLayout(boxLayout); boxLayout->setColumnStretch(1, 1); QLabel *label = new QLabel(i18n("Search for:"), groupBox); boxLayout->addWidget(label, 0, 0); d->mSearchEdit = new QLineEdit(groupBox); d->mSearchEdit->setClearButtonEnabled(true); boxLayout->addWidget(d->mSearchEdit, 0, 1); label->setBuddy(d->mSearchEdit); label = new QLabel(i18nc("In LDAP attribute", "in"), groupBox); boxLayout->addWidget(label, 0, 2); d->mFilterCombo = new KComboBox(groupBox); d->mFilterCombo->addItem(i18nc("@item:inlistbox Name of the contact", "Name"), QVariant::fromValue(Name)); d->mFilterCombo->addItem(i18nc("@item:inlistbox email address of the contact", "Email"), QVariant::fromValue(Email)); d->mFilterCombo->addItem(i18nc("@item:inlistbox", "Home Number"), QVariant::fromValue(HomeNumber)); d->mFilterCombo->addItem(i18nc("@item:inlistbox", "Work Number"), QVariant::fromValue(WorkNumber)); boxLayout->addWidget(d->mFilterCombo, 0, 3); d->startSearchGuiItem = KGuiItem(i18nc("@action:button Start searching", "&Search"), QStringLiteral("edit-find")); d->stopSearchGuiItem = KStandardGuiItem::stop(); QSize buttonSize; d->mSearchButton = new QPushButton(groupBox); KGuiItem::assign(d->mSearchButton, d->startSearchGuiItem); buttonSize = d->mSearchButton->sizeHint(); if (buttonSize.width() < d->mSearchButton->sizeHint().width()) { buttonSize = d->mSearchButton->sizeHint(); } d->mSearchButton->setFixedWidth(buttonSize.width()); d->mSearchButton->setDefault(true); boxLayout->addWidget(d->mSearchButton, 0, 4); d->mRecursiveCheckbox = new QCheckBox(i18n("Recursive search"), groupBox); d->mRecursiveCheckbox->setChecked(true); boxLayout->addWidget(d->mRecursiveCheckbox, 1, 0, 1, 5); d->mSearchType = new KComboBox(groupBox); d->mSearchType->addItem(i18n("Contains")); d->mSearchType->addItem(i18n("Starts With")); boxLayout->addWidget(d->mSearchType, 1, 3, 1, 2); topLayout->addWidget(groupBox); QHBoxLayout *quickSearchLineLayout = new QHBoxLayout; quickSearchLineLayout->addStretch(); d->searchLine = new KLineEdit; d->searchLine->setTrapReturnKey(true); d->searchLine->setClearButtonEnabled(true); d->searchLine->setPlaceholderText(i18n("Search in result")); quickSearchLineLayout->addWidget(d->searchLine); topLayout->addLayout(quickSearchLineLayout); d->mResultView = new QTableView(page); d->mResultView->setSelectionMode(QTableView::MultiSelection); d->mResultView->setSelectionBehavior(QTableView::SelectRows); d->mModel = new ContactListModel(d->mResultView); d->sortproxy = new QSortFilterProxyModel(this); d->sortproxy->setFilterKeyColumn(-1); //Search in all column d->sortproxy->setSourceModel(d->mModel); d->sortproxy->setFilterCaseSensitivity(Qt::CaseInsensitive); connect(d->searchLine, &QLineEdit::textChanged, d->sortproxy, &QSortFilterProxyModel::setFilterFixedString); d->mResultView->setModel(d->sortproxy); d->mResultView->verticalHeader()->hide(); d->mResultView->setSortingEnabled(true); d->mResultView->horizontalHeader()->setSortIndicatorShown(true); connect(d->mResultView, qOverload(&QTableView::clicked), this, [this]() { d->slotSelectionChanged(); }); topLayout->addWidget(d->mResultView); d->mResultView->setContextMenuPolicy(Qt::CustomContextMenu); connect(d->mResultView, &QTableView::customContextMenuRequested, this, &LdapSearchDialog::slotCustomContextMenuRequested); QHBoxLayout *buttonLayout = new QHBoxLayout; buttonLayout->setContentsMargins(0, 0, 0, 0); topLayout->addLayout(buttonLayout); d->progressIndication = new KPIM::ProgressIndicatorLabel(i18n("Searching...")); buttonLayout->addWidget(d->progressIndication); QDialogButtonBox *buttons = new QDialogButtonBox(page); QPushButton *button = buttons->addButton(i18n("Select All"), QDialogButtonBox::ActionRole); connect(button, &QPushButton::clicked, this, [this]() { d->slotSelectAll(); }); button = buttons->addButton(i18n("Unselect All"), QDialogButtonBox::ActionRole); connect(button, &QPushButton::clicked, this, [this]() { d->slotUnselectAll(); }); buttonLayout->addWidget(buttons); d->user1Button->setText(i18n("Add Selected")); user2Button->setText(i18n("Configure LDAP Servers...")); connect(d->mRecursiveCheckbox, &QCheckBox::toggled, this, [this](bool state) { d->slotSetScope(state); }); connect(d->mSearchButton, SIGNAL(clicked()), this, SLOT(slotStartSearch())); setTabOrder(d->mSearchEdit, d->mFilterCombo); setTabOrder(d->mFilterCombo, d->mSearchButton); d->mSearchEdit->setFocus(); d->slotSelectionChanged(); d->restoreSettings(); } LdapSearchDialog::~LdapSearchDialog() { d->saveSettings(); delete d; } void LdapSearchDialog::setSearchText(const QString &text) { d->mSearchEdit->setText(text); } KContacts::Addressee::List LdapSearchDialog::selectedContacts() const { return d->mSelectedContacts; } void LdapSearchDialog::slotCustomContextMenuRequested(const QPoint &pos) { const QModelIndex index = d->mResultView->indexAt(pos); if (index.isValid()) { QMenu menu(this); QAction *act = menu.addAction(i18n("Copy")); if (menu.exec(QCursor::pos()) == act) { QClipboard *cb = QApplication::clipboard(); cb->setText(index.data().toString(), QClipboard::Clipboard); } } } void LdapSearchDialog::Private::slotSelectionChanged() { user1Button->setEnabled(mResultView->selectionModel()->hasSelection()); } void LdapSearchDialog::Private::restoreSettings() { // Create one KLDAP::LdapClient per selected server and configure it. // First clean the list to make sure it is empty at // the beginning of the process qDeleteAll(mLdapClientList); mLdapClientList.clear(); KConfig *config = KLDAP::LdapClientSearchConfig::config(); KConfigGroup searchGroup(config, "LDAPSearch"); mSearchType->setCurrentIndex(searchGroup.readEntry("SearchType", 0)); // then read the config file and register all selected // server in the list KConfigGroup group(config, "LDAP"); mNumHosts = group.readEntry("NumSelectedHosts", 0); if (!mNumHosts) { mIsConfigured = false; } else { mIsConfigured = true; KLDAP::LdapClientSearchConfig *clientSearchConfig = new KLDAP::LdapClientSearchConfig; for (int j = 0; j < mNumHosts; ++j) { KLDAP::LdapServer ldapServer; KLDAP::LdapClient *ldapClient = new KLDAP::LdapClient(0, q); clientSearchConfig->readConfig(ldapServer, group, j, true); ldapClient->setServer(ldapServer); QStringList attrs; QMap::ConstIterator end(adrbookattr2ldap().constEnd()); for (QMap::ConstIterator it = adrbookattr2ldap().constBegin(); it != end; ++it) { attrs << *it; } ldapClient->setAttributes(attrs); q->connect(ldapClient, SIGNAL(result(KLDAP::LdapClient,KLDAP::LdapObject)), q, SLOT(slotAddResult(KLDAP::LdapClient,KLDAP::LdapObject))); q->connect(ldapClient, SIGNAL(done()), q, SLOT(slotSearchDone())); q->connect(ldapClient, &LdapClient::error, q, [this](const QString &err) {slotError(err);}); mLdapClientList.append(ldapClient); } delete clientSearchConfig; mModel->clear(); } KConfigGroup groupHeader(config, "Headers"); mResultView->horizontalHeader()->restoreState(groupHeader.readEntry("HeaderState", QByteArray())); KConfigGroup groupSize(config, "Size"); const QSize dialogSize = groupSize.readEntry("Size", QSize()); if (dialogSize.isValid()) { q->resize(dialogSize); } else { q->resize(QSize(600, 400).expandedTo(q->minimumSizeHint())); } } void LdapSearchDialog::Private::saveSettings() { KConfig *config = KLDAP::LdapClientSearchConfig::config(); KConfigGroup group(config, "LDAPSearch"); group.writeEntry("SearchType", mSearchType->currentIndex()); KConfigGroup groupHeader(config, "Headers"); groupHeader.writeEntry("HeaderState", mResultView->horizontalHeader()->saveState()); groupHeader.sync(); KConfigGroup size(config, "Size"); size.writeEntry("Size", q->size()); size.sync(); group.sync(); } void LdapSearchDialog::Private::cancelQuery() { for (KLDAP::LdapClient *client : qAsConst(mLdapClientList)) { client->cancelQuery(); } } void LdapSearchDialog::Private::slotAddResult(const KLDAP::LdapClient &client, const KLDAP::LdapObject &obj) { mModel->addContact(obj.attributes(), client.server().host()); } void LdapSearchDialog::Private::slotSetScope(bool rec) { for (KLDAP::LdapClient *client : qAsConst(mLdapClientList)) { if (rec) { client->setScope(QStringLiteral("sub")); } else { client->setScope(QStringLiteral("one")); } } } void LdapSearchDialog::Private::slotStartSearch() { cancelQuery(); if (!mIsConfigured) { KMessageBox::error(q, i18n("You must select an LDAP server before searching.")); q->slotUser2(); return; } #ifndef QT_NO_CURSOR QApplication::setOverrideCursor(Qt::WaitCursor); #endif KGuiItem::assign(mSearchButton, stopSearchGuiItem); progressIndication->start(); q->disconnect(mSearchButton, SIGNAL(clicked()), q, SLOT(slotStartSearch())); q->connect(mSearchButton, SIGNAL(clicked()), q, SLOT(slotStopSearch())); const bool startsWith = (mSearchType->currentIndex() == 1); const QString filter = makeFilter(mSearchEdit->text().trimmed(), mFilterCombo->currentData().value(), startsWith); // loop in the list and run the KLDAP::LdapClients mModel->clear(); for (KLDAP::LdapClient *client : qAsConst(mLdapClientList)) { client->startQuery(filter); } saveSettings(); } void LdapSearchDialog::Private::slotStopSearch() { cancelQuery(); slotSearchDone(); } void LdapSearchDialog::Private::slotSearchDone() { // If there are no more active clients, we are done. for (KLDAP::LdapClient *client : qAsConst(mLdapClientList)) { if (client->isActive()) { return; } } q->disconnect(mSearchButton, SIGNAL(clicked()), q, SLOT(slotStopSearch())); q->connect(mSearchButton, SIGNAL(clicked()), q, SLOT(slotStartSearch())); KGuiItem::assign(mSearchButton, startSearchGuiItem); progressIndication->stop(); #ifndef QT_NO_CURSOR QApplication::restoreOverrideCursor(); #endif } void LdapSearchDialog::Private::slotError(const QString &error) { #ifndef QT_NO_CURSOR QApplication::restoreOverrideCursor(); #endif KMessageBox::error(q, error); } void LdapSearchDialog::closeEvent(QCloseEvent *e) { d->slotStopSearch(); e->accept(); } void LdapSearchDialog::Private::slotUnselectAll() { mResultView->clearSelection(); slotSelectionChanged(); } void LdapSearchDialog::Private::slotSelectAll() { mResultView->selectAll(); slotSelectionChanged(); } void LdapSearchDialog::slotUser1() { // Import selected items d->mSelectedContacts.clear(); const QList< QPair > &items = d->selectedItems(); if (!items.isEmpty()) { const QDateTime now = QDateTime::currentDateTime(); for (int i = 0; i < items.count(); ++i) { KContacts::Addressee contact = convertLdapAttributesToAddressee(items.at(i).first); // set a comment where the contact came from contact.setNote(i18nc("arguments are host name, datetime", "Imported from LDAP directory %1 on %2", items.at(i).second, QLocale().toString(now, QLocale::ShortFormat))); d->mSelectedContacts.append(contact); } } d->slotStopSearch(); Q_EMIT contactsAdded(); accept(); } void LdapSearchDialog::slotUser2() { // Configure LDAP servers QPointer dialog = new KCMultiDialog(this); - dialog->setWindowTitle(i18n("Configure the Address Book LDAP Settings")); + dialog->setWindowTitle(i18nc("@title:window", "Configure the Address Book LDAP Settings")); dialog->addModule(QStringLiteral("kcmldap.desktop")); if (dialog->exec()) { //krazy:exclude=crashy d->restoreSettings(); } delete dialog; } void LdapSearchDialog::slotCancelClicked() { d->slotStopSearch(); reject(); } #include "moc_ldapsearchdialog.cpp" diff --git a/src/libkdepim/prefs/kprefsdialog.cpp b/src/libkdepim/prefs/kprefsdialog.cpp index 85886a4..e51948f 100644 --- a/src/libkdepim/prefs/kprefsdialog.cpp +++ b/src/libkdepim/prefs/kprefsdialog.cpp @@ -1,926 +1,926 @@ /* This file is part of libkdepim. Copyright (c) 2001,2003 Cornelius Schumacher Copyright (C) 2003-2004 Reinhold Kainhofer Copyright (C) 2005,2008,2011 Allen Winter This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ //krazy:excludeall=tipsandthis #include "kprefsdialog.h" #include #include #include #include #include "libkdepim_debug.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace KPIM; namespace KPrefsWidFactory { KPrefsWid *create(KConfigSkeletonItem *item, QWidget *parent) { KConfigSkeleton::ItemBool *boolItem = dynamic_cast(item); if (boolItem) { return new KPrefsWidBool(boolItem, parent); } KConfigSkeleton::ItemString *stringItem = dynamic_cast(item); if (stringItem) { return new KPrefsWidString(stringItem, parent); } KConfigSkeleton::ItemEnum *enumItem = dynamic_cast(item); if (enumItem) { QList choices = enumItem->choices(); if (choices.isEmpty()) { qCritical() << "Enum has no choices."; return nullptr; } else { KPrefsWidRadios *radios = new KPrefsWidRadios(enumItem, parent); QList::ConstIterator it; int value = 0; QList::ConstIterator end(choices.constEnd()); for (it = choices.constBegin(); it != end; ++it) { radios->addRadio(value++, (*it).label); } return radios; } } KConfigSkeleton::ItemInt *intItem = dynamic_cast(item); if (intItem) { return new KPrefsWidInt(intItem, parent); } return nullptr; } } // namespace KPrefsWidFactory QList KPrefsWid::widgets() const { return QList(); } KPrefsWidBool::KPrefsWidBool(KConfigSkeleton::ItemBool *item, QWidget *parent) : mItem(item) { mCheck = new QCheckBox(mItem->label(), parent); connect(mCheck, &QCheckBox::clicked, this, &KPrefsWidBool::changed); QString toolTip = mItem->toolTip(); if (!toolTip.isEmpty()) { mCheck->setToolTip(toolTip); } QString whatsThis = mItem->whatsThis(); if (!whatsThis.isEmpty()) { mCheck->setWhatsThis(whatsThis); } } void KPrefsWidBool::readConfig() { mCheck->setChecked(mItem->value()); } void KPrefsWidBool::writeConfig() { mItem->setValue(mCheck->isChecked()); } QCheckBox *KPrefsWidBool::checkBox() { return mCheck; } QList KPrefsWidBool::widgets() const { QList widgets; widgets.append(mCheck); return widgets; } KPrefsWidInt::KPrefsWidInt(KConfigSkeleton::ItemInt *item, QWidget *parent) : mItem(item) { mLabel = new QLabel(mItem->label() + QLatin1Char(':'), parent); mSpin = new QSpinBox(parent); if (!mItem->minValue().isNull()) { mSpin->setMinimum(mItem->minValue().toInt()); } if (!mItem->maxValue().isNull()) { mSpin->setMaximum(mItem->maxValue().toInt()); } connect(mSpin, qOverload(&QSpinBox::valueChanged), this, &KPrefsWidInt::changed); mLabel->setBuddy(mSpin); QString toolTip = mItem->toolTip(); if (!toolTip.isEmpty()) { mLabel->setToolTip(toolTip); mSpin->setToolTip(toolTip); } QString whatsThis = mItem->whatsThis(); if (!whatsThis.isEmpty()) { mLabel->setWhatsThis(whatsThis); mSpin->setWhatsThis(whatsThis); } } void KPrefsWidInt::readConfig() { mSpin->setValue(mItem->value()); } void KPrefsWidInt::writeConfig() { mItem->setValue(mSpin->value()); } QLabel *KPrefsWidInt::label() const { return mLabel; } QSpinBox *KPrefsWidInt::spinBox() { return mSpin; } QList KPrefsWidInt::widgets() const { QList widgets; widgets.append(mLabel); widgets.append(mSpin); return widgets; } KPrefsWidColor::KPrefsWidColor(KConfigSkeleton::ItemColor *item, QWidget *parent) : mItem(item) { mButton = new KColorButton(parent); connect(mButton, &KColorButton::changed, this, &KPrefsWidColor::changed); mLabel = new QLabel(mItem->label() + QLatin1Char(':'), parent); mLabel->setBuddy(mButton); QString toolTip = mItem->toolTip(); if (!toolTip.isEmpty()) { mButton->setToolTip(toolTip); } QString whatsThis = mItem->whatsThis(); if (!whatsThis.isEmpty()) { mButton->setWhatsThis(whatsThis); } } KPrefsWidColor::~KPrefsWidColor() { } void KPrefsWidColor::readConfig() { mButton->setColor(mItem->value()); } void KPrefsWidColor::writeConfig() { mItem->setValue(mButton->color()); } QLabel *KPrefsWidColor::label() { return mLabel; } KColorButton *KPrefsWidColor::button() { return mButton; } KPrefsWidFont::KPrefsWidFont(KConfigSkeleton::ItemFont *item, QWidget *parent, const QString &sampleText) : mItem(item) { mLabel = new QLabel(mItem->label() + QLatin1Char(':'), parent); mPreview = new QLabel(sampleText, parent); mPreview->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); mButton = new QPushButton(i18n("Choose..."), parent); connect(mButton, &QPushButton::clicked, this, &KPIM::KPrefsWidFont::selectFont); QString toolTip = mItem->toolTip(); if (!toolTip.isEmpty()) { mPreview->setToolTip(toolTip); mButton->setToolTip(toolTip); } QString whatsThis = mItem->whatsThis(); if (!whatsThis.isEmpty()) { mPreview->setWhatsThis(whatsThis); mButton->setWhatsThis(whatsThis); } } KPrefsWidFont::~KPrefsWidFont() { } void KPrefsWidFont::readConfig() { mPreview->setFont(mItem->value()); } void KPrefsWidFont::writeConfig() { mItem->setValue(mPreview->font()); } QLabel *KPrefsWidFont::label() { return mLabel; } QFrame *KPrefsWidFont::preview() { return mPreview; } QPushButton *KPrefsWidFont::button() { return mButton; } void KPrefsWidFont::selectFont() { #ifndef QT_NO_FONTDIALOG bool ok; QFont myFont = QFontDialog::getFont(&ok, mPreview->font()); if (ok) { mPreview->setFont(myFont); Q_EMIT changed(); } #endif } KPrefsWidTime::KPrefsWidTime(KConfigSkeleton::ItemDateTime *item, QWidget *parent) : mItem(item) { mLabel = new QLabel(mItem->label() + QLatin1Char(':'), parent); mTimeEdit = new KTimeComboBox(parent); mLabel->setBuddy(mTimeEdit); connect(mTimeEdit, &KTimeComboBox::timeEdited, this, &KPrefsWidTime::changed); connect(mTimeEdit, &KTimeComboBox::timeEntered, this, &KPrefsWidTime::changed); QString toolTip = mItem->toolTip(); if (!toolTip.isEmpty()) { mTimeEdit->setToolTip(toolTip); } QString whatsThis = mItem->whatsThis(); if (!whatsThis.isEmpty()) { mTimeEdit->setWhatsThis(whatsThis); } } void KPrefsWidTime::readConfig() { mTimeEdit->setTime(mItem->value().time()); } void KPrefsWidTime::writeConfig() { // Don't overwrite the date value of the QDateTime, so we can use a // KPrefsWidTime and a KPrefsWidDate on the same config entry! QDateTime dt(mItem->value()); dt.setTime(mTimeEdit->time()); mItem->setValue(dt); } QLabel *KPrefsWidTime::label() { return mLabel; } KTimeComboBox *KPrefsWidTime::timeEdit() { return mTimeEdit; } KPrefsWidDuration::KPrefsWidDuration(KConfigSkeleton::ItemDateTime *item, const QString &format, QWidget *parent) : mItem(item) { mLabel = new QLabel(mItem->label() + QLatin1Char(':'), parent); mTimeEdit = new QTimeEdit(parent); mLabel->setBuddy(mTimeEdit); if (format.isEmpty()) { mTimeEdit->setDisplayFormat(QStringLiteral("hh:mm:ss")); } else { mTimeEdit->setDisplayFormat(format); } mTimeEdit->setMinimumTime(QTime(0, 1)); // [1 min] mTimeEdit->setMaximumTime(QTime(24, 0)); // [24 hr] connect(mTimeEdit, &QTimeEdit::timeChanged, this, &KPrefsWidDuration::changed); QString toolTip = mItem->toolTip(); if (!toolTip.isEmpty()) { mTimeEdit->setToolTip(toolTip); } QString whatsThis = mItem->whatsThis(); if (!whatsThis.isEmpty()) { mTimeEdit->setWhatsThis(whatsThis); } } void KPrefsWidDuration::readConfig() { mTimeEdit->setTime(mItem->value().time()); } void KPrefsWidDuration::writeConfig() { QDateTime dt(mItem->value()); dt.setTime(mTimeEdit->time()); mItem->setValue(dt); } QLabel *KPrefsWidDuration::label() { return mLabel; } QTimeEdit *KPrefsWidDuration::timeEdit() { return mTimeEdit; } KPrefsWidDate::KPrefsWidDate(KConfigSkeleton::ItemDateTime *item, QWidget *parent) : mItem(item) { mLabel = new QLabel(mItem->label() + QLatin1Char(':'), parent); mDateEdit = new KDateComboBox(parent); mLabel->setBuddy(mDateEdit); connect(mDateEdit, &KDateComboBox::dateEdited, this, &KPrefsWidDate::changed); QString toolTip = mItem->toolTip(); if (!toolTip.isEmpty()) { mDateEdit->setToolTip(toolTip); } QString whatsThis = mItem->whatsThis(); if (!whatsThis.isEmpty()) { mDateEdit->setWhatsThis(whatsThis); } } void KPrefsWidDate::readConfig() { if (!mItem->value().date().isValid()) { mItem->setValue(QDateTime::currentDateTime()); } mDateEdit->setDate(mItem->value().date().isValid() ? mItem->value().date() : QDate::currentDate()); } void KPrefsWidDate::writeConfig() { QDateTime dt(mItem->value()); dt.setDate(mDateEdit->date()); mItem->setValue(dt); if (!mItem->value().date().isValid()) { mItem->setValue(QDateTime::currentDateTime()); } } QLabel *KPrefsWidDate::label() { return mLabel; } KDateComboBox *KPrefsWidDate::dateEdit() { return mDateEdit; } KPrefsWidRadios::KPrefsWidRadios(KConfigSkeleton::ItemEnum *item, QWidget *parent) : mItem(item) { mBox = new QGroupBox(mItem->label(), parent); new QVBoxLayout(mBox); mGroup = new QButtonGroup(parent); connect(mGroup, qOverload(&QButtonGroup::buttonClicked), this, &KPrefsWidRadios::changed); } KPrefsWidRadios::~KPrefsWidRadios() { } void KPrefsWidRadios::addRadio(int value, const QString &text, const QString &toolTip, const QString &whatsThis) { QRadioButton *r = new QRadioButton(text, mBox); mBox->layout()->addWidget(r); mGroup->addButton(r, value); if (!toolTip.isEmpty()) { r->setToolTip(toolTip); } if (!whatsThis.isEmpty()) { r->setWhatsThis(whatsThis); } } QGroupBox *KPrefsWidRadios::groupBox() const { return mBox; } void KPrefsWidRadios::readConfig() { if (!mGroup->button(mItem->value())) { return; } mGroup->button(mItem->value())->setChecked(true); } void KPrefsWidRadios::writeConfig() { mItem->setValue(mGroup->checkedId()); } QList KPrefsWidRadios::widgets() const { QList w; w.append(mBox); return w; } KPrefsWidCombo::KPrefsWidCombo(KConfigSkeleton::ItemEnum *item, QWidget *parent) : mItem(item) { mLabel = new QLabel(mItem->label(), parent); mCombo = new KComboBox(parent); connect(mCombo, qOverload(&KComboBox::activated), this, &KPrefsWidCombo::changed); mLabel->setBuddy(mCombo); QString toolTip = mItem->toolTip(); if (!toolTip.isEmpty()) { mLabel->setToolTip(toolTip); mCombo->setToolTip(toolTip); } QString whatsThis = mItem->whatsThis(); if (!whatsThis.isEmpty()) { mLabel->setWhatsThis(whatsThis); mCombo->setWhatsThis(whatsThis); } } KPrefsWidCombo::~KPrefsWidCombo() { } void KPrefsWidCombo::readConfig() { mCombo->setCurrentIndex(mItem->value()); } void KPrefsWidCombo::writeConfig() { mItem->setValue(mCombo->currentIndex()); } QList KPrefsWidCombo::widgets() const { QList w; w.append(mCombo); return w; } KComboBox *KPrefsWidCombo::comboBox() { return mCombo; } QLabel *KPrefsWidCombo::label() const { return mLabel; } KPrefsWidString::KPrefsWidString(KConfigSkeleton::ItemString *item, QWidget *parent, KLineEdit::EchoMode echomode) : mItem(item) { mLabel = new QLabel(mItem->label() + QLatin1Char(':'), parent); mEdit = new KLineEdit(parent); mLabel->setBuddy(mEdit); connect(mEdit, &KLineEdit::textChanged, this, &KPrefsWidString::changed); mEdit->setEchoMode(echomode); QString toolTip = mItem->toolTip(); if (!toolTip.isEmpty()) { mEdit->setToolTip(toolTip); } QString whatsThis = mItem->whatsThis(); if (!whatsThis.isEmpty()) { mEdit->setWhatsThis(whatsThis); } } KPrefsWidString::~KPrefsWidString() { } void KPrefsWidString::readConfig() { mEdit->setText(mItem->value()); } void KPrefsWidString::writeConfig() { mItem->setValue(mEdit->text()); } QLabel *KPrefsWidString::label() { return mLabel; } KLineEdit *KPrefsWidString::lineEdit() { return mEdit; } QList KPrefsWidString::widgets() const { QList widgets; widgets.append(mLabel); widgets.append(mEdit); return widgets; } KPrefsWidPath::KPrefsWidPath(KConfigSkeleton::ItemPath *item, QWidget *parent, const QString &filter, KFile::Modes mode) : mItem(item) { mLabel = new QLabel(mItem->label() + QLatin1Char(':'), parent); mURLRequester = new KUrlRequester(parent); mLabel->setBuddy(mURLRequester); mURLRequester->setMode(mode); mURLRequester->setFilter(filter); connect(mURLRequester, &KUrlRequester::textChanged, this, &KPrefsWidPath::changed); QString toolTip = mItem->toolTip(); if (!toolTip.isEmpty()) { mURLRequester->setToolTip(toolTip); } QString whatsThis = mItem->whatsThis(); if (!whatsThis.isEmpty()) { mURLRequester->setWhatsThis(whatsThis); } } KPrefsWidPath::~KPrefsWidPath() { } void KPrefsWidPath::readConfig() { mURLRequester->setUrl(QUrl(mItem->value())); } void KPrefsWidPath::writeConfig() { mItem->setValue(mURLRequester->url().path()); } QLabel *KPrefsWidPath::label() { return mLabel; } KUrlRequester *KPrefsWidPath::urlRequester() { return mURLRequester; } QList KPrefsWidPath::widgets() const { QList widgets; widgets.append(mLabel); widgets.append(mURLRequester); return widgets; } KPrefsWidManager::KPrefsWidManager(KConfigSkeleton *prefs) : mPrefs(prefs) { } KPrefsWidManager::~KPrefsWidManager() { qDeleteAll(mPrefsWids); mPrefsWids.clear(); } void KPrefsWidManager::addWid(KPrefsWid *wid) { mPrefsWids.append(wid); } KPrefsWidBool *KPrefsWidManager::addWidBool(KConfigSkeleton::ItemBool *item, QWidget *parent) { KPrefsWidBool *w = new KPrefsWidBool(item, parent); addWid(w); return w; } KPrefsWidTime *KPrefsWidManager::addWidTime(KConfigSkeleton::ItemDateTime *item, QWidget *parent) { KPrefsWidTime *w = new KPrefsWidTime(item, parent); addWid(w); return w; } KPrefsWidDuration *KPrefsWidManager::addWidDuration(KConfigSkeleton::ItemDateTime *item, const QString &format, QWidget *parent) { KPrefsWidDuration *w = new KPrefsWidDuration(item, format, parent); addWid(w); return w; } KPrefsWidDate *KPrefsWidManager::addWidDate(KConfigSkeleton::ItemDateTime *item, QWidget *parent) { KPrefsWidDate *w = new KPrefsWidDate(item, parent); addWid(w); return w; } KPrefsWidColor *KPrefsWidManager::addWidColor(KConfigSkeleton::ItemColor *item, QWidget *parent) { KPrefsWidColor *w = new KPrefsWidColor(item, parent); addWid(w); return w; } KPrefsWidRadios *KPrefsWidManager::addWidRadios(KConfigSkeleton::ItemEnum *item, QWidget *parent) { KPrefsWidRadios *w = new KPrefsWidRadios(item, parent); QList choices; choices = item->choices2(); QList::ConstIterator it; QList::ConstIterator end(choices.constEnd()); int value = 0; for (it = choices.constBegin(); it != end; ++it) { w->addRadio(value++, (*it).label, (*it).toolTip, (*it).whatsThis); } addWid(w); return w; } KPrefsWidCombo *KPrefsWidManager::addWidCombo(KConfigSkeleton::ItemEnum *item, QWidget *parent) { KPrefsWidCombo *w = new KPrefsWidCombo(item, parent); QList choices; choices = item->choices(); QList::ConstIterator end(choices.constEnd()); for (QList::ConstIterator it = choices.constBegin(); it != end; ++it) { w->comboBox()->addItem((*it).label); } addWid(w); return w; } KPrefsWidString *KPrefsWidManager::addWidString(KConfigSkeleton::ItemString *item, QWidget *parent) { KPrefsWidString *w = new KPrefsWidString(item, parent, KLineEdit::Normal); addWid(w); return w; } KPrefsWidPath *KPrefsWidManager::addWidPath(KConfigSkeleton::ItemPath *item, QWidget *parent, const QString &filter, KFile::Modes mode) { KPrefsWidPath *w = new KPrefsWidPath(item, parent, filter, mode); addWid(w); return w; } KPrefsWidString *KPrefsWidManager::addWidPassword(KConfigSkeleton::ItemString *item, QWidget *parent) { KPrefsWidString *w = new KPrefsWidString(item, parent, KLineEdit::Password); addWid(w); return w; } KPrefsWidFont *KPrefsWidManager::addWidFont(KConfigSkeleton::ItemFont *item, QWidget *parent, const QString &sampleText) { KPrefsWidFont *w = new KPrefsWidFont(item, parent, sampleText); addWid(w); return w; } KPrefsWidInt *KPrefsWidManager::addWidInt(KConfigSkeleton::ItemInt *item, QWidget *parent) { KPrefsWidInt *w = new KPrefsWidInt(item, parent); addWid(w); return w; } void KPrefsWidManager::setWidDefaults() { bool tmp = mPrefs->useDefaults(true); readWidConfig(); mPrefs->useDefaults(tmp); } void KPrefsWidManager::readWidConfig() { QList::Iterator it; for (it = mPrefsWids.begin(); it != mPrefsWids.end(); ++it) { (*it)->readConfig(); } } void KPrefsWidManager::writeWidConfig() { QList::Iterator it; for (it = mPrefsWids.begin(); it != mPrefsWids.end(); ++it) { (*it)->writeConfig(); } mPrefs->save(); } KPrefsDialog::KPrefsDialog(KConfigSkeleton *prefs, QWidget *parent, bool modal) : KPageDialog(parent) , KPrefsWidManager(prefs) { setFaceType(List); - setWindowTitle(i18n("Preferences")); + setWindowTitle(i18nc("@title:window", "Preferences")); setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Apply | QDialogButtonBox::Cancel | QDialogButtonBox::RestoreDefaults); button(QDialogButtonBox::Ok)->setDefault(true); setModal(modal); connect(button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &KPrefsDialog::slotOk); connect(button(QDialogButtonBox::Apply), &QPushButton::clicked, this, &KPrefsDialog::slotApply); connect(button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked, this, &KPrefsDialog::slotDefault); connect(button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &KPrefsDialog::reject); } KPrefsDialog::~KPrefsDialog() { } void KPrefsDialog::autoCreate() { KConfigSkeletonItem::List items = prefs()->items(); QMap mGroupPages; QMap mGroupLayouts; QMap mCurrentRows; KConfigSkeletonItem::List::ConstIterator it; for (it = items.constBegin(); it != items.constEnd(); ++it) { QString group = (*it)->group(); QWidget *page = nullptr; QGridLayout *layout = nullptr; int currentRow; if (!mGroupPages.contains(group)) { page = new QWidget(this); addPage(page, group); layout = new QGridLayout(page); mGroupPages.insert(group, page); mGroupLayouts.insert(group, layout); currentRow = 0; mCurrentRows.insert(group, currentRow); } else { page = mGroupPages[ group ]; layout = mGroupLayouts[ group ]; currentRow = mCurrentRows[ group ]; } KPrefsWid *wid = KPrefsWidFactory::create(*it, page); if (wid) { QList widgets = wid->widgets(); if (widgets.count() == 1) { layout->addWidget(widgets[ 0 ], currentRow, currentRow, 0, 1); } else if (widgets.count() == 2) { layout->addWidget(widgets[ 0 ], currentRow, 0); layout->addWidget(widgets[ 1 ], currentRow, 1); } else { qCritical() << "More widgets than expected:" << widgets.count(); } if ((*it)->isImmutable()) { QList::Iterator it2; for (it2 = widgets.begin(); it2 != widgets.end(); ++it2) { (*it2)->setEnabled(false); } } addWid(wid); mCurrentRows.insert(group, ++currentRow); } } readConfig(); } void KPrefsDialog::setDefaults() { setWidDefaults(); } void KPrefsDialog::readConfig() { readWidConfig(); usrReadConfig(); } void KPrefsDialog::writeConfig() { writeWidConfig(); usrWriteConfig(); readConfig(); } void KPrefsDialog::slotApply() { writeConfig(); Q_EMIT configChanged(); } void KPrefsDialog::slotOk() { slotApply(); accept(); } void KPrefsDialog::slotDefault() { if (KMessageBox::warningContinueCancel( this, i18n("You are about to set all preferences to default values. " "All custom modifications will be lost."), i18n("Setting Default Preferences"), KGuiItem(i18n("Reset to Defaults"))) == KMessageBox::Continue) { setDefaults(); } } KPrefsModule::KPrefsModule(KConfigSkeleton *prefs, QWidget *parent, const QVariantList &args) : KCModule(parent, args) , KPrefsWidManager(prefs) { Q_EMIT changed(false); } void KPrefsModule::addWid(KPrefsWid *wid) { KPrefsWidManager::addWid(wid); connect(wid, &KPrefsWid::changed, this, &KPrefsModule::slotWidChanged); } void KPrefsModule::slotWidChanged() { Q_EMIT changed(true); } void KPrefsModule::load() { readWidConfig(); usrReadConfig(); Q_EMIT changed(false); } void KPrefsModule::save() { writeWidConfig(); usrWriteConfig(); } void KPrefsModule::defaults() { setWidDefaults(); Q_EMIT changed(true); } diff --git a/src/libkdepimakonadi/addressline/completionconfiguredialog/completionconfiguredialog.cpp b/src/libkdepimakonadi/addressline/completionconfiguredialog/completionconfiguredialog.cpp index 183d918..7ea4c7e 100644 --- a/src/libkdepimakonadi/addressline/completionconfiguredialog/completionconfiguredialog.cpp +++ b/src/libkdepimakonadi/addressline/completionconfiguredialog/completionconfiguredialog.cpp @@ -1,150 +1,150 @@ /* Copyright (c) 2015-2019 Montel Laurent This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "completionconfiguredialog.h" #include #include #include #include #include #include #include #include #include #if !DISABLE_AKONADI_SEARCH #include #endif #include using namespace KPIM; class KPIM::CompletionConfigureDialogPrivate { public: CompletionConfigureDialogPrivate() { } QTabWidget *mTabWidget = nullptr; KPIM::CompletionOrderWidget *mCompletionOrderWidget = nullptr; #if !DISABLE_AKONADI_SEARCH KPIM::BlackListBalooEmailCompletionWidget *mBlackListBalooWidget = nullptr; #endif KPIM::RecentAddressWidget *mRecentaddressWidget = nullptr; }; CompletionConfigureDialog::CompletionConfigureDialog(QWidget *parent) : QDialog(parent) , d(new KPIM::CompletionConfigureDialogPrivate) { - setWindowTitle(i18n("Configure completion")); + setWindowTitle(i18nc("@title:window", "Configure Completion")); QVBoxLayout *mainLayout = new QVBoxLayout(this); d->mTabWidget = new QTabWidget(this); d->mTabWidget->setObjectName(QStringLiteral("tabwidget")); mainLayout->addWidget(d->mTabWidget); d->mCompletionOrderWidget = new KPIM::CompletionOrderWidget(this); d->mCompletionOrderWidget->setObjectName(QStringLiteral("completionorder_widget")); d->mTabWidget->addTab(d->mCompletionOrderWidget, i18n("Completion Order")); d->mRecentaddressWidget = new KPIM::RecentAddressWidget(this); d->mRecentaddressWidget->setObjectName(QStringLiteral("recentaddress_widget")); d->mTabWidget->addTab(d->mRecentaddressWidget, i18n("Recent Address")); #if !DISABLE_AKONADI_SEARCH d->mBlackListBalooWidget = new KPIM::BlackListBalooEmailCompletionWidget(this); d->mBlackListBalooWidget->setObjectName(QStringLiteral("blacklistbaloo_widget")); d->mTabWidget->addTab(d->mBlackListBalooWidget, i18n("Blacklist Email Address")); #endif QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); buttonBox->setObjectName(QStringLiteral("buttonbox")); connect(buttonBox, &QDialogButtonBox::accepted, this, &CompletionConfigureDialog::slotSave); connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); mainLayout->addWidget(buttonBox); readConfig(); } CompletionConfigureDialog::~CompletionConfigureDialog() { writeConfig(); delete d; } void CompletionConfigureDialog::readConfig() { KConfigGroup group(KSharedConfig::openConfig(), "CompletionConfigureDialog"); const QSize size = group.readEntry("Size", QSize(600, 400)); if (size.isValid()) { resize(size); } } void CompletionConfigureDialog::writeConfig() { KConfigGroup group(KSharedConfig::openConfig(), "CompletionConfigureDialog"); group.writeEntry("Size", size()); group.sync(); } void CompletionConfigureDialog::setRecentAddresses(const QStringList &lst) { d->mRecentaddressWidget->setAddresses(lst); } void CompletionConfigureDialog::setLdapClientSearch(KLDAP::LdapClientSearch *ldapSearch) { d->mCompletionOrderWidget->setLdapClientSearch(ldapSearch); } void CompletionConfigureDialog::load() { d->mCompletionOrderWidget->loadCompletionItems(); #if !DISABLE_AKONADI_SEARCH d->mBlackListBalooWidget->load(); #endif } bool CompletionConfigureDialog::recentAddressWasChanged() const { return d->mRecentaddressWidget->wasChanged(); } void CompletionConfigureDialog::storeAddresses(KConfig *config) { d->mRecentaddressWidget->storeAddresses(config); } void CompletionConfigureDialog::slotSave() { #if !DISABLE_AKONADI_SEARCH d->mBlackListBalooWidget->save(); #endif d->mCompletionOrderWidget->save(); accept(); } void CompletionConfigureDialog::setEmailBlackList(const QStringList &lst) { #if !DISABLE_AKONADI_SEARCH d->mBlackListBalooWidget->setEmailBlackList(lst); #endif } diff --git a/src/libkdepimakonadi/addressline/completionorder/completionordereditor.cpp b/src/libkdepimakonadi/addressline/completionorder/completionordereditor.cpp index bfdaa91..95b3066 100644 --- a/src/libkdepimakonadi/addressline/completionorder/completionordereditor.cpp +++ b/src/libkdepimakonadi/addressline/completionorder/completionordereditor.cpp @@ -1,116 +1,116 @@ /** -*- c++ -*- * completionordereditor.cpp * * Copyright (c) 2004 David Faure * 2010 Tobias Koenig * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * In addition, as a special exception, the copyright holders give * permission to link the code of this program with any edition of * the Qt library by Trolltech AS, Norway (or with modified versions * of Qt that use the same license as Qt), and distribute linked * combinations including the two. You must obey the GNU General * Public License in all respects for all of the code used other than * Qt. If you modify this file, you may extend this exception to * your version of the file, but you are not obligated to do so. If * you do not wish to do so, delete this exception statement from * your version. */ #include "completionordereditor.h" #include "completionorderwidget.h" #include #include "Libkdepim/LdapClient" #include "ldap/ldapclientsearch.h" #include "ldap/ldapclientsearchconfig.h" #include #include #include #include #include #include #include #include #include using namespace KPIM; class KPIM::CompletionOrderEditorPrivate { public: CompletionOrderEditorPrivate() { } CompletionOrderWidget *mCompletionOrderWidget = nullptr; }; CompletionOrderEditor::CompletionOrderEditor(KLDAP::LdapClientSearch *ldapSearch, QWidget *parent) : QDialog(parent) , d(new KPIM::CompletionOrderEditorPrivate) { - setWindowTitle(i18n("Edit Completion Order")); + setWindowTitle(i18nc("@title:window", "Edit Completion Order")); QVBoxLayout *mainLayout = new QVBoxLayout(this); d->mCompletionOrderWidget = new CompletionOrderWidget(this); d->mCompletionOrderWidget->setObjectName(QStringLiteral("completionorderwidget")); mainLayout->addWidget(d->mCompletionOrderWidget); d->mCompletionOrderWidget->setLdapClientSearch(ldapSearch); d->mCompletionOrderWidget->loadCompletionItems(); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); okButton->setDefault(true); okButton->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox, &QDialogButtonBox::accepted, this, &CompletionOrderEditor::slotOk); connect(buttonBox, &QDialogButtonBox::rejected, this, &CompletionOrderEditor::reject); mainLayout->addWidget(buttonBox); readConfig(); } CompletionOrderEditor::~CompletionOrderEditor() { writeConfig(); delete d; } void CompletionOrderEditor::readConfig() { KConfigGroup group(KSharedConfig::openConfig(), "CompletionOrderEditor"); const QSize size = group.readEntry("Size", QSize(600, 400)); if (size.isValid()) { resize(size); } } void CompletionOrderEditor::writeConfig() { KConfigGroup group(KSharedConfig::openConfig(), "CompletionOrderEditor"); group.writeEntry("Size", size()); group.sync(); } void CompletionOrderEditor::slotOk() { d->mCompletionOrderWidget->save(); accept(); } diff --git a/src/libkdepimakonadi/job/addemailaddressjob.cpp b/src/libkdepimakonadi/job/addemailaddressjob.cpp index 8b6b249..7239c37 100644 --- a/src/libkdepimakonadi/job/addemailaddressjob.cpp +++ b/src/libkdepimakonadi/job/addemailaddressjob.cpp @@ -1,323 +1,323 @@ /* Copyright 2010 Tobias Koenig Copyright 2010 Nicolas Lécureuil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "addemailaddressjob.h" #include #include "akonadi/contact/selectaddressbookdialog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace KPIM; class Q_DECL_HIDDEN AddEmailAddressJob::Private { public: Private(AddEmailAddressJob *qq, const QString &emailString, QWidget *parentWidget) : q(qq) , mCompleteAddress(emailString) , mParentWidget(parentWidget) , mInteractive(true) { KContacts::Addressee::parseEmailAddress(emailString, mName, mEmail); } void slotResourceCreationDone(KJob *job) { if (job->error()) { q->setError(job->error()); q->setErrorText(job->errorText()); q->emitResult(); return; } createContact(); } void slotSearchDone(KJob *job) { if (job->error()) { q->setError(job->error()); q->setErrorText(job->errorText()); q->emitResult(); return; } const Akonadi::ContactSearchJob *searchJob = qobject_cast(job); const KContacts::Addressee::List contacts = searchJob->contacts(); if (!contacts.isEmpty()) { if (mInteractive) { const QString text = xi18nc("@info", "A contact with the email address %1 " "is already in your address book.", mCompleteAddress); KMessageBox::information( mParentWidget, text, QString(), QStringLiteral("alreadyInAddressBook")); } q->setError(UserDefinedError); q->emitResult(); return; } createContact(); } void createContact() { const QStringList mimeTypes(KContacts::Addressee::mimeType()); Akonadi::CollectionFetchJob *const addressBookJob = new Akonadi::CollectionFetchJob(Akonadi::Collection::root(), Akonadi::CollectionFetchJob::Recursive); addressBookJob->fetchScope().setContentMimeTypes(mimeTypes); q->connect(addressBookJob, &Akonadi::CollectionFetchJob::result, q, [this](KJob *job) { slotCollectionsFetched(job); }); } void slotCollectionsFetched(KJob *job) { if (job->error()) { q->setError(job->error()); q->setErrorText(job->errorText()); q->emitResult(); return; } const Akonadi::CollectionFetchJob *addressBookJob = qobject_cast(job); Akonadi::Collection::List canCreateItemCollections; const Akonadi::Collection::List lstColls = addressBookJob->collections(); for (const Akonadi::Collection &collection : lstColls) { if (Akonadi::Collection::CanCreateItem &collection.rights()) { canCreateItemCollections.append(collection); } } Akonadi::Collection addressBook; const int nbItemCollection(canCreateItemCollections.size()); if (nbItemCollection == 0) { if (KMessageBox::questionYesNo( mParentWidget, i18nc("@info", "You must create an address book before adding a contact. Do you want to create an address book?"), i18nc("@title:window", "No Address Book Available")) == KMessageBox::Yes) { QPointer dlg = new Akonadi::AgentTypeDialog(mParentWidget); - dlg->setWindowTitle(i18n("Add Address Book")); + dlg->setWindowTitle(i18nc("@title:window", "Add Address Book")); dlg->agentFilterProxyModel()->addMimeTypeFilter(KContacts::Addressee::mimeType()); dlg->agentFilterProxyModel()->addMimeTypeFilter(KContacts::ContactGroup::mimeType()); dlg->agentFilterProxyModel()->addCapabilityFilter(QStringLiteral("Resource")); if (dlg->exec()) { const Akonadi::AgentType agentType = dlg->agentType(); if (agentType.isValid()) { Akonadi::AgentInstanceCreateJob *job = new Akonadi::AgentInstanceCreateJob(agentType, q); q->connect(job, &Akonadi::AgentInstanceCreateJob::result, q, [this](KJob *job) { slotResourceCreationDone(job); }); job->configure(mParentWidget); job->start(); delete dlg; return; } else { //if agent is not valid => return error and finish job q->setError(UserDefinedError); q->emitResult(); delete dlg; return; } } else { //Canceled create agent => return error and finish job q->setError(UserDefinedError); q->emitResult(); delete dlg; return; } } else { q->setError(UserDefinedError); q->emitResult(); return; } } else if (nbItemCollection == 1) { addressBook = canCreateItemCollections[0]; } else { // ask user in which address book the new contact shall be stored QPointer dlg = new Akonadi::SelectAddressBookDialog(mParentWidget); bool gotIt = true; if (dlg->exec()) { addressBook = dlg->selectedCollection(); } else { q->setError(UserDefinedError); q->emitResult(); gotIt = false; } delete dlg; if (!gotIt) { return; } } if (!addressBook.isValid()) { q->setError(UserDefinedError); q->emitResult(); return; } KContacts::Addressee contact; contact.setNameFromString(mName); contact.insertEmail(mEmail, true); // create the new item Akonadi::Item item; item.setMimeType(KContacts::Addressee::mimeType()); item.setPayload(contact); // save the new item in akonadi storage Akonadi::ItemCreateJob *createJob = new Akonadi::ItemCreateJob(item, addressBook, q); q->connect(createJob, &Akonadi::ItemCreateJob::result, q, [this](KJob *job) { slotAddContactDone(job); }); } void slotAddContactDone(KJob *job) { if (job->error()) { q->setError(job->error()); q->setErrorText(job->errorText()); q->emitResult(); return; } const Akonadi::ItemCreateJob *createJob = qobject_cast(job); mItem = createJob->item(); if (mInteractive) { const QString text = xi18nc("@info", "A contact for \"%1\" was successfully added " "to your address book." "Do you want to edit this new contact now?", mCompleteAddress); if (KMessageBox::questionYesNo( mParentWidget, text, QString(), KStandardGuiItem::yes(), KStandardGuiItem::no(), QStringLiteral("addedtokabc")) == KMessageBox::Yes) { QPointer dlg = new Akonadi::ContactEditorDialog(Akonadi::ContactEditorDialog::EditMode, mParentWidget); dlg->setContact(mItem); connect(dlg.data(), &Akonadi::ContactEditorDialog::contactStored, q, [this](const Akonadi::Item &item) { contactStored(item); }); connect(dlg.data(), &Akonadi::ContactEditorDialog::error, q, [this](const QString &str) { slotContactEditorError(str); }); dlg->exec(); delete dlg; } } q->emitResult(); } void slotContactEditorError(const QString &error) { if (mInteractive) { KMessageBox::error(mParentWidget, i18n("Contact cannot be stored: %1", error), i18n("Failed to store contact")); } } void contactStored(const Akonadi::Item &) { if (mInteractive) { KPIM::BroadcastStatus::instance()->setStatusMsg(i18n("Contact created successfully")); } } AddEmailAddressJob *q; QString mCompleteAddress; QString mEmail; QString mName; QWidget *mParentWidget = nullptr; Akonadi::Item mItem; bool mInteractive = false; }; AddEmailAddressJob::AddEmailAddressJob(const QString &email, QWidget *parentWidget, QObject *parent) : KJob(parent) , d(new Private(this, email, parentWidget)) { } AddEmailAddressJob::~AddEmailAddressJob() { delete d; } void AddEmailAddressJob::start() { // first check whether a contact with the same email exists already Akonadi::ContactSearchJob *searchJob = new Akonadi::ContactSearchJob(this); searchJob->setLimit(1); searchJob->setQuery(Akonadi::ContactSearchJob::Email, d->mEmail.toLower(), Akonadi::ContactSearchJob::ExactMatch); connect(searchJob, &Akonadi::ContactSearchJob::result, this, [this](KJob *job) { d->slotSearchDone(job); }); } Akonadi::Item AddEmailAddressJob::contact() const { return d->mItem; } void AddEmailAddressJob::setInteractive(bool b) { d->mInteractive = b; } #include "moc_addemailaddressjob.cpp" diff --git a/src/libkdepimakonadi/job/addemaildisplayjob.cpp b/src/libkdepimakonadi/job/addemaildisplayjob.cpp index 9921432..fd58513 100644 --- a/src/libkdepimakonadi/job/addemaildisplayjob.cpp +++ b/src/libkdepimakonadi/job/addemaildisplayjob.cpp @@ -1,313 +1,313 @@ /* Copyright 2013-2019 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "addemaildisplayjob.h" #include #include "akonadi/contact/selectaddressbookdialog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace KPIM; class Q_DECL_HIDDEN AddEmailDiplayJob::Private { public: Private(AddEmailDiplayJob *qq, const QString &emailString, QWidget *parentWidget) : q(qq) , mCompleteAddress(emailString) , mParentWidget(parentWidget) , mShowAsHTML(false) , mRemoteContent(false) { KContacts::Addressee::parseEmailAddress(emailString, mName, mEmail); } void slotResourceCreationDone(KJob *job) { if (job->error()) { q->setError(job->error()); q->setErrorText(job->errorText()); q->emitResult(); return; } createContact(); } void searchContact() { // first check whether a contact with the same email exists already Akonadi::ContactSearchJob *searchJob = new Akonadi::ContactSearchJob(q); searchJob->setLimit(1); searchJob->setQuery(Akonadi::ContactSearchJob::Email, mEmail.toLower(), Akonadi::ContactSearchJob::ExactMatch); q->connect(searchJob, &Akonadi::ContactSearchJob::result, q, [this](KJob *job) { slotSearchDone(job); }); } void modifyContact() { Akonadi::Item item = contact; if (item.hasPayload()) { KContacts::Addressee address = item.payload(); address.insertCustom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("MailPreferedFormatting"), mShowAsHTML ? QStringLiteral("HTML") : QStringLiteral("TEXT")); address.insertCustom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("MailAllowToRemoteContent"), mRemoteContent ? QStringLiteral("TRUE") : QStringLiteral("FALSE")); item.setPayload(address); Akonadi::ItemModifyJob *job = new Akonadi::ItemModifyJob(item); q->connect(job, &Akonadi::ItemModifyJob::result, q, [this](KJob *job) { Akonadi::ItemModifyJob *modifiedJob = static_cast(job); q->contactUpdated(modifiedJob->item(), messageId); slotAddModifyContactDone(job); }); } else { searchContact(); } } void slotSearchDone(KJob *job) { if (job->error()) { q->setError(job->error()); q->setErrorText(job->errorText()); q->emitResult(); return; } const Akonadi::ContactSearchJob *searchJob = qobject_cast(job); const Akonadi::Item::List items = searchJob->items(); if (items.isEmpty()) { createContact(); } else { Akonadi::Item item = items.at(0); KContacts::Addressee contact = searchJob->contacts().at(0); contact.insertCustom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("MailPreferedFormatting"), mShowAsHTML ? QStringLiteral("HTML") : QStringLiteral("TEXT")); contact.insertCustom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("MailAllowToRemoteContent"), mRemoteContent ? QStringLiteral("TRUE") : QStringLiteral("FALSE")); item.setPayload(contact); Akonadi::ItemModifyJob *job = new Akonadi::ItemModifyJob(item); q->connect(job, &Akonadi::ItemModifyJob::result, q, [this](KJob *job) { Akonadi::ItemModifyJob *modifiedJob = static_cast(job); q->contactUpdated(modifiedJob->item(), messageId); slotAddModifyContactDone(job); }); } } void createContact() { const QStringList mimeTypes(KContacts::Addressee::mimeType()); Akonadi::CollectionFetchJob *const addressBookJob = new Akonadi::CollectionFetchJob(Akonadi::Collection::root(), Akonadi::CollectionFetchJob::Recursive); addressBookJob->fetchScope().setContentMimeTypes(mimeTypes); q->connect(addressBookJob, &Akonadi::CollectionFetchJob::result, q, [this](KJob *job) { slotCollectionsFetched(job); }); } void slotCollectionsFetched(KJob *job) { if (job->error()) { q->setError(job->error()); q->setErrorText(job->errorText()); q->emitResult(); return; } const Akonadi::CollectionFetchJob *addressBookJob = qobject_cast(job); Akonadi::Collection::List canCreateItemCollections; const Akonadi::Collection::List colsList = addressBookJob->collections(); for (const Akonadi::Collection &collection : colsList) { if (Akonadi::Collection::CanCreateItem &collection.rights()) { canCreateItemCollections.append(collection); } } Akonadi::Collection addressBook; const int nbItemCollection(canCreateItemCollections.size()); if (nbItemCollection == 0) { if (KMessageBox::questionYesNo( mParentWidget, i18nc("@info", "You must create an address book before adding a contact. Do you want to create an address book?"), i18nc("@title:window", "No Address Book Available")) == KMessageBox::Yes) { QPointer dlg = new Akonadi::AgentTypeDialog(mParentWidget); - dlg->setWindowTitle(i18n("Add Address Book")); + dlg->setWindowTitle(i18nc("@title:window", "Add Address Book")); dlg->agentFilterProxyModel()->addMimeTypeFilter(KContacts::Addressee::mimeType()); dlg->agentFilterProxyModel()->addMimeTypeFilter(KContacts::ContactGroup::mimeType()); dlg->agentFilterProxyModel()->addCapabilityFilter(QStringLiteral("Resource")); if (dlg->exec()) { const Akonadi::AgentType agentType = dlg->agentType(); if (agentType.isValid()) { Akonadi::AgentInstanceCreateJob *job = new Akonadi::AgentInstanceCreateJob(agentType, q); q->connect(job, &Akonadi::AgentInstanceCreateJob::result, q, [this](KJob *job) { slotResourceCreationDone(job); }); job->configure(mParentWidget); job->start(); delete dlg; return; } else { //if agent is not valid => return error and finish job q->setError(UserDefinedError); q->emitResult(); delete dlg; return; } } else { //Canceled create agent => return error and finish job q->setError(UserDefinedError); q->emitResult(); delete dlg; return; } } else { q->setError(UserDefinedError); q->emitResult(); return; } } else if (nbItemCollection == 1) { addressBook = canCreateItemCollections[0]; } else { // ask user in which address book the new contact shall be stored QPointer dlg = new Akonadi::SelectAddressBookDialog(mParentWidget); bool gotIt = true; if (dlg->exec()) { addressBook = dlg->selectedCollection(); } else { q->setError(UserDefinedError); q->emitResult(); gotIt = false; } delete dlg; if (!gotIt) { return; } } if (!addressBook.isValid()) { q->setError(UserDefinedError); q->emitResult(); return; } KContacts::Addressee contact; contact.setNameFromString(mName); contact.insertEmail(mEmail, true); contact.insertCustom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("MailPreferedFormatting"), mShowAsHTML ? QStringLiteral("HTML") : QStringLiteral("TEXT")); contact.insertCustom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("MailAllowToRemoteContent"), mRemoteContent ? QStringLiteral("TRUE") : QStringLiteral("FALSE")); // create the new item Akonadi::Item item; item.setMimeType(KContacts::Addressee::mimeType()); item.setPayload(contact); // save the new item in akonadi storage Akonadi::ItemCreateJob *createJob = new Akonadi::ItemCreateJob(item, addressBook, q); q->connect(createJob, &Akonadi::ItemCreateJob::result, q, [this](KJob *job) { Akonadi::ItemCreateJob *modifiedJob = static_cast(job); q->contactUpdated(modifiedJob->item(), messageId); slotAddModifyContactDone(job); }); } void slotAddModifyContactDone(KJob *job) { if (job->error()) { q->setError(job->error()); q->setErrorText(job->errorText()); } q->emitResult(); } AddEmailDiplayJob *q; Akonadi::Item contact; Akonadi::Item::Id messageId; QString mCompleteAddress; QString mEmail; QString mName; QWidget *mParentWidget = nullptr; bool mShowAsHTML = false; bool mRemoteContent = false; }; AddEmailDiplayJob::AddEmailDiplayJob(const QString &email, QWidget *parentWidget, QObject *parent) : KJob(parent) , d(new Private(this, email, parentWidget)) { } AddEmailDiplayJob::~AddEmailDiplayJob() { delete d; } void AddEmailDiplayJob::setShowAsHTML(bool html) { d->mShowAsHTML = html; } void AddEmailDiplayJob::setRemoteContent(bool b) { d->mRemoteContent = b; } void AddEmailDiplayJob::setContact(const Akonadi::Item &contact) { d->contact = contact; } void AddEmailDiplayJob::setMessageId(Akonadi::Item::Id id) { d->messageId = id; } void AddEmailDiplayJob::start() { if (d->contact.isValid()) { d->modifyContact(); } else { d->searchContact(); } } #include "moc_addemaildisplayjob.cpp"