1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25
26 #include "searchresulttreeview.h"
27 #include "searchresulttreeitemroles.h"
28 #include "searchresulttreemodel.h"
29 #include "searchresulttreeitemdelegate.h"
30
31 #include <utils/qtcassert.h>
32
33 #include <QHeaderView>
34 #include <QKeyEvent>
35 #include <QVBoxLayout>
36
37 namespace Core {
38 namespace Internal {
39
40 class FilterWidget : public QWidget
41 {
42 public:
FilterWidget(QWidget * parent,QWidget * content)43 FilterWidget(QWidget *parent, QWidget *content) : QWidget(parent, Qt::Popup)
44 {
45 setAttribute(Qt::WA_DeleteOnClose);
46 const auto layout = new QVBoxLayout(this);
47 layout->setContentsMargins(2, 2, 2, 2);
48 layout->setSpacing(2);
49 layout->addWidget(content);
50 setLayout(layout);
51 move(parent->mapToGlobal(QPoint(0, -sizeHint().height())));
52 }
53 };
54
SearchResultTreeView(QWidget * parent)55 SearchResultTreeView::SearchResultTreeView(QWidget *parent)
56 : Utils::TreeView(parent)
57 , m_model(new SearchResultFilterModel(this))
58 , m_autoExpandResults(false)
59 {
60 setModel(m_model);
61 connect(m_model, &SearchResultFilterModel::filterInvalidated,
62 this, &SearchResultTreeView::filterInvalidated);
63
64 setItemDelegate(new SearchResultTreeItemDelegate(8, this));
65 setIndentation(14);
66 setUniformRowHeights(true);
67 setExpandsOnDoubleClick(true);
68 header()->setSectionResizeMode(QHeaderView::ResizeToContents);
69 header()->setStretchLastSection(false);
70 header()->hide();
71
72 connect(this, &SearchResultTreeView::activated,
73 this, &SearchResultTreeView::emitJumpToSearchResult);
74 }
75
setAutoExpandResults(bool expand)76 void SearchResultTreeView::setAutoExpandResults(bool expand)
77 {
78 m_autoExpandResults = expand;
79 }
80
setTextEditorFont(const QFont & font,const SearchResultColors & colors)81 void SearchResultTreeView::setTextEditorFont(const QFont &font, const SearchResultColors &colors)
82 {
83 m_model->setTextEditorFont(font, colors);
84
85 QPalette p;
86 p.setColor(QPalette::Base, colors.value(SearchResultColor::Style::Default).textBackground);
87 setPalette(p);
88 }
89
clear()90 void SearchResultTreeView::clear()
91 {
92 m_model->clear();
93 }
94
addResults(const QList<SearchResultItem> & items,SearchResult::AddMode mode)95 void SearchResultTreeView::addResults(const QList<SearchResultItem> &items, SearchResult::AddMode mode)
96 {
97 QList<QModelIndex> addedParents = m_model->addResults(items, mode);
98 if (m_autoExpandResults && !addedParents.isEmpty()) {
99 foreach (const QModelIndex &index, addedParents)
100 setExpanded(index, true);
101 }
102 }
103
setFilter(SearchResultFilter * filter)104 void SearchResultTreeView::setFilter(SearchResultFilter *filter)
105 {
106 m_filter = filter;
107 if (m_filter)
108 m_filter->setParent(this);
109 m_model->setFilter(filter);
110 emit filterChanged();
111 }
112
hasFilter() const113 bool SearchResultTreeView::hasFilter() const
114 {
115 return m_filter;
116 }
117
showFilterWidget(QWidget * parent)118 void SearchResultTreeView::showFilterWidget(QWidget *parent)
119 {
120 QTC_ASSERT(hasFilter(), return);
121 const auto optionsWidget = new FilterWidget(parent, m_filter->createWidget());
122 optionsWidget->show();
123 }
124
keyPressEvent(QKeyEvent * event)125 void SearchResultTreeView::keyPressEvent(QKeyEvent *event)
126 {
127 if ((event->key() == Qt::Key_Return
128 || event->key() == Qt::Key_Enter)
129 && event->modifiers() == 0
130 && currentIndex().isValid()
131 && state() != QAbstractItemView::EditingState) {
132 const SearchResultItem item
133 = model()->data(currentIndex(), ItemDataRoles::ResultItemRole).value<SearchResultItem>();
134 emit jumpToSearchResult(item);
135 return;
136 }
137 TreeView::keyPressEvent(event);
138 }
139
event(QEvent * e)140 bool SearchResultTreeView::event(QEvent *e)
141 {
142 if (e->type() == QEvent::Resize)
143 header()->setMinimumSectionSize(width());
144 return TreeView::event(e);
145 }
146
emitJumpToSearchResult(const QModelIndex & index)147 void SearchResultTreeView::emitJumpToSearchResult(const QModelIndex &index)
148 {
149 if (model()->data(index, ItemDataRoles::IsGeneratedRole).toBool())
150 return;
151 SearchResultItem item = model()->data(index, ItemDataRoles::ResultItemRole).value<SearchResultItem>();
152
153 emit jumpToSearchResult(item);
154 }
155
setTabWidth(int tabWidth)156 void SearchResultTreeView::setTabWidth(int tabWidth)
157 {
158 auto delegate = static_cast<SearchResultTreeItemDelegate *>(itemDelegate());
159 delegate->setTabWidth(tabWidth);
160 doItemsLayout();
161 }
162
model() const163 SearchResultFilterModel *SearchResultTreeView::model() const
164 {
165 return m_model;
166 }
167
168 } // namespace Internal
169 } // namespace Core
170