File indexing completed on 2022-11-29 20:24:09

0001 /* This file is part of the KDE project
0002    Copyright (C) 2003 Alexander Kellett <lypanov@kde.org>
0003 
0004    This program is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU General Public
0006    License version 2 as published by the Free Software Foundation.
0007 
0008    This program is distributed in the hope that it will be useful,
0009    but WITHOUT ANY WARRANTY; without even the implied warranty of
0010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0011    General Public License for more details.
0012 
0013    You should have received a copy of the GNU General Public License
0014    along with this program; see the file COPYING.  If not, write to
0015    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0016    Boston, MA 02110-1301, USA.
0017 */
0018 
0019 #include "bookmarkinfowidget.h"
0020 #include "bookmarklistview.h"
0021 #include "globalbookmarkmanager.h"
0022 #include "kbookmarkmodel/commandhistory.h"
0023 #include "kbookmarkmodel/commands.h"
0024 #include "kbookmarkmodel/model.h"
0025 
0026 #include <stdlib.h>
0027 
0028 #include <QFormLayout>
0029 #include <QHBoxLayout>
0030 #include <QTimer>
0031 
0032 #include <KLocalizedString>
0033 
0034 #include <KLineEdit>
0035 
0036 // SHUFFLE all these functions around, the order is just plain stupid
0037 void BookmarkInfoWidget::showBookmark(const KBookmark &bk)
0038 {
0039     // Fast exit if already shown, otherwise editing a title leads to a command after each keypress
0040     if (m_bk == bk)
0041         return;
0042 
0043     commitChanges();
0044     m_bk = bk;
0045 
0046     if (m_bk.isNull()) {
0047         // all read only and blank
0048 
0049         m_title_le->setReadOnly(true);
0050         m_title_le->setText(QString());
0051 
0052         m_url_le->setReadOnly(true);
0053         m_url_le->setText(QString());
0054 
0055         m_comment_le->setReadOnly(true);
0056         m_comment_le->setText(QString());
0057 
0058         m_visitdate_le->setReadOnly(true);
0059         m_visitdate_le->setText(QString());
0060 
0061         m_credate_le->setReadOnly(true);
0062         m_credate_le->setText(QString());
0063 
0064         m_visitcount_le->setReadOnly(true);
0065         m_visitcount_le->setText(QString());
0066 
0067         return;
0068     }
0069 
0070     // read/write fields
0071     m_title_le->setReadOnly((bk.isSeparator() || !bk.hasParent()) ? true : false);
0072     if (bk.fullText() != m_title_le->text())
0073         m_title_le->setText(bk.fullText());
0074 
0075     m_url_le->setReadOnly(bk.isGroup() || bk.isSeparator());
0076     if (bk.isGroup()) {
0077         m_url_le->setText(QString());
0078     } else {
0079         // Update the text if and only if the text represents a different URL to that
0080         // of the current bookmark - the old method, "m_url_le->text() != bk.url().pathOrUrl()",
0081         // created difficulties due to the ambiguity of converting URLs to text. (#172647)
0082         if (QUrl::fromUserInput(m_url_le->text()) != bk.url()) {
0083             const int cursorPosition = m_url_le->cursorPosition();
0084             m_url_le->setText(bk.url().url(QUrl::PreferLocalFile));
0085             m_url_le->setCursorPosition(cursorPosition);
0086         }
0087     }
0088 
0089     m_comment_le->setReadOnly((bk.isSeparator() || !bk.hasParent()) ? true : false);
0090     QString commentText = bk.description();
0091     if (m_comment_le->text() != commentText) {
0092         const int cursorPosition = m_comment_le->cursorPosition();
0093         m_comment_le->setText(commentText);
0094         m_comment_le->setCursorPosition(cursorPosition);
0095     }
0096 
0097     // readonly fields
0098     updateStatus();
0099 }
0100 
0101 void BookmarkInfoWidget::updateStatus()
0102 {
0103     // FIXME we don't want every metadata element, but only that with owner "https://www.kde.org"
0104     QString visitDate = GlobalBookmarkManager::makeTimeStr(m_bk.metaDataItem(QStringLiteral("time_visited")));
0105     m_visitdate_le->setReadOnly(true);
0106     m_visitdate_le->setText(visitDate);
0107 
0108     QString creationDate = GlobalBookmarkManager::makeTimeStr(m_bk.metaDataItem(QStringLiteral("time_added")));
0109     m_credate_le->setReadOnly(true);
0110     m_credate_le->setText(creationDate);
0111 
0112     // TODO - get the actual field name from the spec if it exists, else copy galeon
0113     m_visitcount_le->setReadOnly(true);
0114     m_visitcount_le->setText(m_bk.metaDataItem(QStringLiteral("visit_count")));
0115 }
0116 
0117 void BookmarkInfoWidget::commitChanges()
0118 {
0119     commitTitle();
0120     commitURL();
0121     commitComment();
0122 }
0123 
0124 void BookmarkInfoWidget::commitTitle()
0125 {
0126     // no more change compression
0127     titlecmd = nullptr;
0128 }
0129 
0130 void BookmarkInfoWidget::slotTextChangedTitle(const QString &str)
0131 {
0132     if (m_bk.isNull() || !m_title_le->isModified())
0133         return;
0134 
0135     timer->start(1000);
0136 
0137     if (titlecmd) {
0138         titlecmd->modify(str);
0139         titlecmd->redo();
0140     } else {
0141         titlecmd = new EditCommand(m_model, m_bk.address(), 0, str);
0142         m_model->commandHistory()->addCommand(titlecmd);
0143     }
0144 }
0145 
0146 void BookmarkInfoWidget::commitURL()
0147 {
0148     urlcmd = nullptr;
0149 }
0150 
0151 void BookmarkInfoWidget::slotTextChangedURL(const QString &str)
0152 {
0153     if (m_bk.isNull() || !m_url_le->isModified())
0154         return;
0155 
0156     timer->start(1000);
0157 
0158     if (urlcmd) {
0159         urlcmd->modify(str);
0160         urlcmd->redo();
0161     } else {
0162         urlcmd = new EditCommand(m_model, m_bk.address(), 1, str);
0163         m_model->commandHistory()->addCommand(urlcmd);
0164     }
0165 }
0166 
0167 void BookmarkInfoWidget::commitComment()
0168 {
0169     commentcmd = nullptr;
0170 }
0171 
0172 void BookmarkInfoWidget::slotTextChangedComment(const QString &str)
0173 {
0174     if (m_bk.isNull() || !m_comment_le->isModified())
0175         return;
0176 
0177     timer->start(1000);
0178 
0179     if (commentcmd) {
0180         commentcmd->modify(str);
0181         commentcmd->redo();
0182     } else {
0183         commentcmd = new EditCommand(m_model, m_bk.address(), 2, str);
0184         m_model->commandHistory()->addCommand(commentcmd);
0185     }
0186 }
0187 
0188 void BookmarkInfoWidget::slotUpdate()
0189 {
0190     const QModelIndexList &list = mBookmarkListView->selectionModel()->selectedRows();
0191     if (list.count() == 1) {
0192         QModelIndex index = *list.constBegin();
0193         showBookmark(mBookmarkListView->bookmarkModel()->bookmarkForIndex(index));
0194     } else
0195         showBookmark(KBookmark());
0196 }
0197 
0198 BookmarkInfoWidget::BookmarkInfoWidget(BookmarkListView *lv, KBookmarkModel *model, QWidget *parent)
0199     : QWidget(parent)
0200     , m_model(model)
0201     , mBookmarkListView(lv)
0202 {
0203     connect(mBookmarkListView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &BookmarkInfoWidget::slotUpdate);
0204 
0205     connect(mBookmarkListView->model(), &QAbstractItemModel::dataChanged, this, &BookmarkInfoWidget::slotUpdate);
0206 
0207     timer = new QTimer(this);
0208     timer->setSingleShot(true);
0209     connect(timer, &QTimer::timeout, this, &BookmarkInfoWidget::commitChanges);
0210 
0211     titlecmd = nullptr;
0212     urlcmd = nullptr;
0213     commentcmd = nullptr;
0214 
0215     QHBoxLayout *layout = new QHBoxLayout(this);
0216     QFormLayout *form1 = new QFormLayout();
0217     QFormLayout *form2 = new QFormLayout();
0218     layout->addLayout(form1);
0219     layout->addLayout(form2);
0220 
0221     m_title_le = new KLineEdit(this);
0222     m_title_le->setClearButtonEnabled(true);
0223     form1->addRow(i18n("Name:"), m_title_le);
0224 
0225     connect(m_title_le, &KLineEdit::textChanged, this, &BookmarkInfoWidget::slotTextChangedTitle);
0226     connect(m_title_le, &KLineEdit::editingFinished, this, &BookmarkInfoWidget::commitTitle);
0227 
0228     m_url_le = new KLineEdit(this);
0229     m_url_le->setClearButtonEnabled(true);
0230     form1->addRow(i18n("Location:"), m_url_le);
0231 
0232     connect(m_url_le, &KLineEdit::textChanged, this, &BookmarkInfoWidget::slotTextChangedURL);
0233     connect(m_url_le, &KLineEdit::editingFinished, this, &BookmarkInfoWidget::commitURL);
0234 
0235     m_comment_le = new KLineEdit(this);
0236     m_comment_le->setClearButtonEnabled(true);
0237     form1->addRow(i18n("Comment:"), m_comment_le);
0238 
0239     connect(m_comment_le, &KLineEdit::textChanged, this, &BookmarkInfoWidget::slotTextChangedComment);
0240     connect(m_comment_le, &KLineEdit::editingFinished, this, &BookmarkInfoWidget::commitComment);
0241 
0242     m_credate_le = new KLineEdit(this);
0243     form2->addRow(i18n("First viewed:"), m_credate_le);
0244 
0245     m_visitdate_le = new KLineEdit(this);
0246     form2->addRow(i18n("Viewed last:"), m_visitdate_le);
0247 
0248     m_visitcount_le = new KLineEdit(this);
0249     form2->addRow(i18n("Times visited:"), m_visitcount_le);
0250 
0251     showBookmark(KBookmark());
0252 }