File indexing completed on 2024-04-28 05:08:14

0001 /***************************************************************************
0002     Copyright (C) 2005-2009 Robby Stephenson <robby@periapsis.org>
0003  ***************************************************************************/
0004 
0005 /***************************************************************************
0006  *                                                                         *
0007  *   This program is free software; you can redistribute it and/or         *
0008  *   modify it under the terms of the GNU General Public License as        *
0009  *   published by the Free Software Foundation; either version 2 of        *
0010  *   the License or (at your option) version 3 or any later version        *
0011  *   accepted by the membership of KDE e.V. (or its successor approved     *
0012  *   by the membership of KDE e.V.), which shall act as a proxy            *
0013  *   defined in Section 14 of version 3 of the license.                    *
0014  *                                                                         *
0015  *   This program is distributed in the hope that it will be useful,       *
0016  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0018  *   GNU General Public License for more details.                          *
0019  *                                                                         *
0020  *   You should have received a copy of the GNU General Public License     *
0021  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
0022  *                                                                         *
0023  ***************************************************************************/
0024 
0025 #include "borrowerdialog.h"
0026 #include "document.h"
0027 #include "collection.h"
0028 #include "../tellico_debug.h"
0029 
0030 #include <KLocalizedString>
0031 #include <KLineEdit>
0032 #include <KJob>
0033 
0034 #ifdef HAVE_KABC
0035 #ifdef QT_STRICT_ITERATORS
0036 #define WAS_STRICT
0037 #undef QT_STRICT_ITERATORS
0038 #endif
0039 
0040 #include <kcontacts/addressee.h>
0041 #include <Akonadi/Contact/ContactSearchJob>
0042 
0043 #ifdef WAS_STRICT
0044 #define QT_STRICT_ITERATORS
0045 #undef WAS_STRICT
0046 #endif
0047 #endif
0048 
0049 #include <QVBoxLayout>
0050 #include <QDialogButtonBox>
0051 #include <QPushButton>
0052 
0053 using Tellico::BorrowerDialog;
0054 
0055 #ifdef HAVE_KABC
0056 BorrowerDialog::Item::Item(QTreeWidget* parent_, const KContacts::Addressee& add_)
0057     : QTreeWidgetItem(parent_), m_uid(add_.uid()) {
0058   setData(0, Qt::DisplayRole, add_.realName().trimmed());
0059   setData(0, Qt::DecorationRole, QIcon::fromTheme(QLatin1String("kaddressbook")));
0060 }
0061 #endif
0062 
0063 BorrowerDialog::Item::Item(QTreeWidget* parent_, const Tellico::Data::Borrower& bor_)
0064     : QTreeWidgetItem(parent_), m_uid(bor_.uid()) {
0065   setData(0, Qt::DisplayRole, bor_.name());
0066   setData(0, Qt::DecorationRole, QIcon::fromTheme(QStringLiteral("tellico"),
0067                                                   QIcon(QLatin1String(":/icons/tellico"))));
0068 }
0069 
0070 // default button is going to be used as a print button, so it's separated
0071 BorrowerDialog::BorrowerDialog(QWidget* parent_)
0072     : QDialog(parent_) {
0073   setModal(true);
0074   setWindowTitle(i18n("Select Borrower"));
0075 
0076   QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
0077   QVBoxLayout *mainLayout = new QVBoxLayout(this);
0078   setLayout(mainLayout);
0079 
0080   QWidget* mainWidget = new QWidget(this);
0081   mainLayout->addWidget(mainWidget);
0082 
0083   QPushButton* okButton = buttonBox->button(QDialogButtonBox::Ok);
0084   okButton->setDefault(true);
0085   okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
0086   connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
0087   connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
0088 
0089   m_treeWidget = new QTreeWidget(mainWidget);
0090   mainLayout->addWidget(m_treeWidget);
0091   m_treeWidget->setHeaderLabel(i18n("Name"));
0092   m_treeWidget->setRootIsDecorated(false);
0093   connect(m_treeWidget, &QTreeWidget::itemDoubleClicked,
0094           this, &QDialog::accept);
0095   connect(m_treeWidget, &QTreeWidget::currentItemChanged,
0096           this, &BorrowerDialog::updateEdit);
0097 
0098   m_lineEdit = new KLineEdit(mainWidget); //krazy:exclude=qclasses
0099   mainLayout->addWidget(m_lineEdit);
0100   connect(m_lineEdit->completionObject(), &KCompletion::match,
0101           this, &BorrowerDialog::selectItem);
0102   m_lineEdit->setFocus();
0103   m_lineEdit->completionObject()->setIgnoreCase(true);
0104 
0105   mainLayout->addWidget(buttonBox);
0106 
0107 #ifdef HAVE_KABC
0108   // Search for all existing contacts
0109   Akonadi::ContactSearchJob* job = new Akonadi::ContactSearchJob();
0110   connect(job, SIGNAL(result(KJob*)), this, SLOT(akonadiSearchResult(KJob*)));
0111 #endif
0112 
0113   populateBorrowerList();
0114 
0115   setMinimumWidth(400);
0116 }
0117 
0118 void BorrowerDialog::akonadiSearchResult(KJob* job_) {
0119   if(job_->error() != 0) {
0120     myDebug() << job_->errorString();
0121     return;
0122   }
0123 
0124 #ifdef HAVE_KABC
0125   Akonadi::ContactSearchJob* searchJob = qobject_cast<Akonadi::ContactSearchJob*>(job_);
0126   Q_ASSERT(searchJob);
0127 
0128   populateBorrowerList();
0129 
0130   foreach(const KContacts::Addressee& addressee, searchJob->contacts()) {
0131     // skip people with no name
0132     const QString name = addressee.realName().trimmed();
0133     if(name.isEmpty()) {
0134       continue;
0135     }
0136     if(m_itemHash.contains(name)) {
0137       continue; // if an item already exists with this name
0138     }
0139     Item* item = new Item(m_treeWidget, addressee);
0140     m_itemHash.insert(name, item);
0141     m_lineEdit->completionObject()->addItem(name);
0142   }
0143 #endif
0144 
0145   m_treeWidget->sortItems(0, Qt::AscendingOrder);
0146 }
0147 
0148 void BorrowerDialog::populateBorrowerList() {
0149   m_treeWidget->clear();
0150   m_itemHash.clear();
0151   m_lineEdit->completionObject()->clear();
0152 
0153   // Bug 307958 - KContacts::Addressee uids are not constant
0154   // so populate the borrower list with the existing borrowers
0155   // before adding ones from address book
0156   Data::BorrowerList borrowers = Data::Document::self()->collection()->borrowers();
0157   foreach(Data::BorrowerPtr bor, borrowers) {
0158     if(bor->name().isEmpty()) {
0159       continue;
0160     }
0161     if(m_itemHash.contains(bor->name())) {
0162       continue; // if an item already exists with this name
0163     }
0164     Item* item = new Item(m_treeWidget, *bor);
0165     m_itemHash.insert(bor->name(), item);
0166     m_lineEdit->completionObject()->addItem(bor->name());
0167   }
0168   m_treeWidget->sortItems(0, Qt::AscendingOrder);
0169 }
0170 
0171 void BorrowerDialog::selectItem(const QString& str_) {
0172   if(str_.isEmpty()) {
0173     return;
0174   }
0175 
0176   QTreeWidgetItem* item = m_itemHash.value(str_);
0177   if(item) {
0178     m_treeWidget->blockSignals(true);
0179     m_treeWidget->setCurrentItem(item);
0180     m_treeWidget->scrollToItem(item);
0181     m_treeWidget->blockSignals(false);
0182   }
0183 }
0184 
0185 void BorrowerDialog::updateEdit(QTreeWidgetItem* item_) {
0186   QString s = item_->data(0, Qt::DisplayRole).toString();
0187   m_lineEdit->setText(s);
0188   m_lineEdit->setSelection(0, s.length());
0189   m_uid = static_cast<Item*>(item_)->uid();
0190 }
0191 
0192 Tellico::Data::BorrowerPtr BorrowerDialog::borrower() {
0193   return Data::BorrowerPtr(new Data::Borrower(m_lineEdit->text(), m_uid));
0194 }
0195 
0196 // static
0197 Tellico::Data::BorrowerPtr BorrowerDialog::getBorrower(QWidget* parent_) {
0198   BorrowerDialog dlg(parent_);
0199 
0200   if(dlg.exec() == QDialog::Accepted) {
0201     return dlg.borrower();
0202   }
0203   return Data::BorrowerPtr();
0204 }