File indexing completed on 2024-04-28 05:48:38

0001 /***************************************************************************
0002  *   This file is part of Kate search plugin                               *
0003  *   SPDX-FileCopyrightText: 2014 Kåre Särs <kare.sars@iki.fi>             *
0004  *                                                                         *
0005  *   SPDX-License-Identifier: LGPL-2.0-or-later                            *
0006  ***************************************************************************/
0007 
0008 #include "TargetHtmlDelegate.h"
0009 #include "TargetModel.h"
0010 
0011 #include <KLocalizedString>
0012 #include <QAbstractTextDocumentLayout>
0013 #include <QCompleter>
0014 #include <QFileSystemModel>
0015 #include <QLineEdit>
0016 #include <QModelIndex>
0017 #include <QPainter>
0018 #include <QTextCharFormat>
0019 #include <QTextDocument>
0020 #include <QToolButton>
0021 
0022 #include "UrlInserter.h"
0023 
0024 #include <QDebug>
0025 
0026 TargetHtmlDelegate::TargetHtmlDelegate(QObject *parent)
0027     : QStyledItemDelegate(parent)
0028     , m_isEditing(false)
0029 {
0030     connect(this, &TargetHtmlDelegate::sendEditStart, this, &TargetHtmlDelegate::editStarted);
0031 }
0032 
0033 TargetHtmlDelegate::~TargetHtmlDelegate()
0034 {
0035 }
0036 
0037 void TargetHtmlDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
0038 {
0039     QStyleOptionViewItem options = option;
0040     initStyleOption(&options, index);
0041 
0042     QTextDocument doc;
0043 
0044     QString str;
0045     int rowtype = index.data(TargetModel::RowTypeRole).toInt();
0046     if (rowtype == TargetModel::RootRow) {
0047         str = QStringLiteral("<B>%1</B>").arg(index.data().toString().toHtmlEscaped());
0048     } else if (rowtype == TargetModel::TargetSetRow) {
0049         if (index.column() == 0) {
0050             str = i18nc("T as in Target set", "<B>T:</B> %1", index.data().toString().toHtmlEscaped());
0051         } else if (index.column() == 1) {
0052             str = i18nc("D as in working Directory", "<B>Dir:</B> %1", index.data().toString().toHtmlEscaped());
0053         }
0054     } else {
0055         str = index.data().toString().toHtmlEscaped();
0056     }
0057 
0058     if (option.state & QStyle::State_Selected) {
0059         str = QStringLiteral("<font color=\"%1\">").arg(option.palette.highlightedText().color().name()) + str + QStringLiteral("</font>");
0060     }
0061     doc.setHtml(str);
0062     doc.setDocumentMargin(2);
0063 
0064     painter->save();
0065 
0066     // paint background
0067     if (option.state & QStyle::State_Selected) {
0068         painter->fillRect(option.rect, option.palette.highlight());
0069     } else {
0070         painter->fillRect(option.rect, option.palette.base());
0071     }
0072 
0073     options.text = QString(); // clear old text
0074     options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &options, painter, options.widget);
0075 
0076     // draw text
0077     painter->translate(option.rect.x(), option.rect.y());
0078     doc.drawContents(painter);
0079 
0080     painter->restore();
0081 }
0082 
0083 QSize TargetHtmlDelegate::sizeHint(const QStyleOptionViewItem & /* option */, const QModelIndex &index) const
0084 {
0085     QTextDocument doc;
0086     doc.setHtml(index.data().toString().toHtmlEscaped());
0087     doc.setDocumentMargin(2);
0088     if (index.column() == 1 && !index.parent().isValid()) {
0089         return doc.size().toSize() + QSize(38, 0); // add space for "Dir"
0090     }
0091     return doc.size().toSize();
0092 }
0093 
0094 QWidget *TargetHtmlDelegate::createEditor(QWidget *dparent, const QStyleOptionViewItem & /* option */, const QModelIndex &index) const
0095 {
0096     QWidget *editor;
0097     if (index.internalId() == TargetModel::InvalidIndex && index.column() == 1) {
0098         UrlInserter *requester = new UrlInserter(parent()->property("docUrl").toUrl(), dparent);
0099         requester->setReplace(true);
0100         editor = requester;
0101         editor->setToolTip(i18n("Leave empty to use the directory of the current document.\nAdd search directories by adding paths separated by ';'"));
0102     } else if (index.column() == 1) {
0103         UrlInserter *urlEditor = new UrlInserter(parent()->property("docUrl").toUrl(), dparent);
0104         editor = urlEditor;
0105         editor->setToolTip(i18n("Use:\n\"%f\" for current file\n\"%d\" for directory of current file\n\"%n\" for current file name without suffix"));
0106     } else {
0107         QLineEdit *e = new QLineEdit(dparent);
0108         QCompleter *completer = new QCompleter(e);
0109         QFileSystemModel *model = new QFileSystemModel(e);
0110         model->setFilter(QDir::AllDirs | QDir::NoDotAndDotDot);
0111         completer->setModel(model);
0112         e->setCompleter(completer);
0113         editor = e;
0114     }
0115     editor->setAutoFillBackground(true);
0116     Q_EMIT sendEditStart();
0117     connect(editor, &QWidget::destroyed, this, &TargetHtmlDelegate::editEnded);
0118     return editor;
0119 }
0120 
0121 void TargetHtmlDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
0122 {
0123     QString value = index.model()->data(index, Qt::EditRole).toString();
0124 
0125     if (index.column() == 1) {
0126         UrlInserter *ledit = static_cast<UrlInserter *>(editor);
0127         if (ledit) {
0128             ledit->lineEdit()->setText(value);
0129         }
0130     } else {
0131         QLineEdit *ledit = static_cast<QLineEdit *>(editor);
0132         if (ledit) {
0133             ledit->setText(value);
0134         }
0135     }
0136 }
0137 
0138 void TargetHtmlDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
0139 {
0140     QString value;
0141     if (index.column() == 1) {
0142         UrlInserter *ledit = static_cast<UrlInserter *>(editor);
0143         value = ledit->lineEdit()->text();
0144     } else {
0145         QLineEdit *ledit = static_cast<QLineEdit *>(editor);
0146         value = ledit->text();
0147     }
0148     model->setData(index, value, Qt::EditRole);
0149 }
0150 
0151 void TargetHtmlDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const
0152 {
0153     QRect rect = option.rect;
0154     int heightDiff = QToolButton().sizeHint().height() - rect.height();
0155     int half = heightDiff / 2;
0156     rect.adjust(0, -half, 0, heightDiff - half);
0157     editor->setGeometry(rect);
0158 }
0159 
0160 void TargetHtmlDelegate::editStarted()
0161 {
0162     m_isEditing = true;
0163 }
0164 void TargetHtmlDelegate::editEnded()
0165 {
0166     m_isEditing = false;
0167 }
0168 bool TargetHtmlDelegate::isEditing() const
0169 {
0170     return m_isEditing;
0171 }
0172 
0173 #include "moc_TargetHtmlDelegate.cpp"