File indexing completed on 2024-04-28 05:49:04
0001 /* 0002 SPDX-FileCopyrightText: 2021 Waqar Ahmed <waqar.17a@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 #include "branchesdialog.h" 0007 #include "branchesdialogmodel.h" 0008 #include "gitprocess.h" 0009 #include "ktexteditor_utils.h" 0010 0011 #include <QPainter> 0012 #include <QTreeView> 0013 #include <QWidget> 0014 0015 #include <KFuzzyMatcher> 0016 #include <KLocalizedString> 0017 #include <KTextEditor/Message> 0018 #include <KTextEditor/View> 0019 0020 #include <drawing_utils.h> 0021 0022 class StyleDelegate : public HUDStyleDelegate 0023 { 0024 public: 0025 using HUDStyleDelegate::HUDStyleDelegate; 0026 0027 void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override 0028 { 0029 QStyleOptionViewItem options = option; 0030 initStyleOption(&options, index); 0031 0032 auto name = index.data().toString(); 0033 0034 QList<QTextLayout::FormatRange> formats; 0035 QTextCharFormat fmt; 0036 fmt.setForeground(options.palette.link()); 0037 fmt.setFontWeight(QFont::Bold); 0038 0039 const auto itemType = (BranchesDialogModel::ItemType)index.data(BranchesDialogModel::ItemTypeRole).toInt(); 0040 const bool branchItem = itemType == BranchesDialogModel::BranchItem; 0041 const int offset = branchItem ? 0 : 2; 0042 0043 const auto ranges = KFuzzyMatcher::matchedRanges(m_filterString, name); 0044 std::transform(ranges.begin(), ranges.end(), std::back_inserter(formats), [offset, fmt](const KFuzzyMatcher::Range &fr) { 0045 return QTextLayout::FormatRange{fr.start + offset, fr.length, fmt}; 0046 }); 0047 0048 if (!branchItem) { 0049 name = QStringLiteral("+ ") + name; 0050 } 0051 0052 const int nameLen = name.length(); 0053 int len = 6; 0054 if (branchItem) { 0055 const auto refType = (GitUtils::RefType)index.data(BranchesDialogModel::RefType).toInt(); 0056 using RefType = GitUtils::RefType; 0057 if (refType == RefType::Head) { 0058 name.append(QStringLiteral(" local")); 0059 } else if (refType == RefType::Remote) { 0060 name.append(QStringLiteral(" remote")); 0061 len = 7; 0062 } 0063 } 0064 QTextCharFormat lf; 0065 lf.setFontItalic(true); 0066 lf.setForeground(Qt::gray); 0067 formats.append({nameLen, len, lf}); 0068 0069 painter->save(); 0070 0071 auto *style = options.widget->style(); 0072 options.text = QString(); // clear old text 0073 style->drawControl(QStyle::CE_ItemViewItem, &options, painter, options.widget); 0074 0075 // leave space for icon 0076 const int hMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin, &option, option.widget); 0077 const int iconWidth = option.decorationSize.width() + (hMargin * 2); 0078 if (itemType == BranchesDialogModel::BranchItem) { 0079 options.rect.adjust(iconWidth, 0, 0, 0); 0080 } else { 0081 options.rect.adjust((hMargin * 2), 0, 0, 0); 0082 } 0083 Utils::paintItemViewText(painter, name, options, formats); 0084 0085 painter->restore(); 0086 } 0087 }; 0088 0089 BranchesDialog::BranchesDialog(QWidget *window, QString projectPath) 0090 : HUDDialog(nullptr, window) 0091 , m_model(new BranchesDialogModel(this)) 0092 , m_projectPath(projectPath) 0093 { 0094 setModel(m_model, FilterType::ScoredFuzzy, 0, Qt::DisplayRole, BranchesDialogModel::FuzzyScore); 0095 setDelegate(new StyleDelegate(this)); 0096 } 0097 0098 void BranchesDialog::openDialog(GitUtils::RefType r) 0099 { 0100 m_lineEdit.setPlaceholderText(i18n("Select Branch...")); 0101 0102 QList<GitUtils::Branch> branches = GitUtils::getAllBranchesAndTags(m_projectPath, r); 0103 m_model->refresh(branches); 0104 0105 reselectFirst(); 0106 exec(); 0107 } 0108 0109 void BranchesDialog::slotReturnPressed(const QModelIndex &index) 0110 { 0111 if (index.isValid()) { 0112 const auto branch = index.data().toString(); 0113 const auto itemType = (BranchesDialogModel::ItemType)index.data(BranchesDialogModel::ItemTypeRole).toInt(); 0114 Q_ASSERT(itemType == BranchesDialogModel::BranchItem); 0115 0116 m_branch = branch; 0117 Q_EMIT branchSelected(branch); 0118 } 0119 0120 clearLineEdit(); 0121 hide(); 0122 } 0123 0124 void BranchesDialog::sendMessage(const QString &plainText, bool warn) 0125 { 0126 Utils::showMessage(plainText, gitIcon(), i18n("Git"), warn ? MessageType::Error : MessageType::Info); 0127 } 0128 0129 #include "moc_branchesdialog.cpp"