Commit 9f42b0f2 authored by Waqar Ahmed's avatar Waqar Ahmed Committed by Christoph Cullmann
Browse files

Allow detaching search tab to mainWindow

When there are a lot of results and you have to go through them all,
a bigger widget can be very helpful.

Once detached, it will be a _read only_ widget i.e., you can only view
the search results and click on a result to jump to the document.
parent 9547bebd
......@@ -12,11 +12,33 @@
#include <KSyntaxHighlighting/Theme>
#include <KTextEditor/Editor>
#include <QPushButton>
Results::Results(QWidget *parent)
: QWidget(parent)
, m_detachButton(new QPushButton(this))
{
setupUi(this);
m_detachButton->setIcon(QIcon::fromTheme(QStringLiteral("draw-arrow")));
m_detachButton->show();
m_detachButton->raise();
m_detachButton->resize(m_detachButton->minimumSizeHint());
connect(m_detachButton, &QAbstractButton::clicked, this, [this] {
m_detachButton->setEnabled(false);
m_detachButton->setVisible(false);
Q_EMIT requestDetachToMainWindow(this);
});
connect(treeView, &ResultsTreeView::geometryChanged, this, [this] {
auto topRight = treeView->viewport()->geometry().topRight();
topRight.rx() -= 4;
topRight.ry() += 4;
auto btnGeometry = m_detachButton->geometry();
btnGeometry.moveTopRight(topRight);
m_detachButton->setGeometry(btnGeometry);
});
treeView->setItemDelegate(new SearchResultsDelegate(treeView));
MatchProxyModel *proxy = new MatchProxyModel(this);
......
......@@ -27,6 +27,13 @@ public:
QString treeRootText;
MatchModel matchModel;
bool displayFolderOptions = false;
class QPushButton *const m_detachButton;
// Used by katemainwindow when we try to close this widget
Q_INVOKABLE bool shouldClose()
{
return true;
}
bool isEmpty() const;
void setFilterLineVisible(bool visible);
......@@ -42,6 +49,10 @@ public:
QModelIndex lastMatch() const;
KTextEditor::Range matchRange(const QModelIndex &matchIndex) const;
bool replaceSingleMatch(KTextEditor::Document *doc, const QModelIndex &matchIndex, const QRegularExpression &regExp, const QString &replaceString);
void itemSelected(const QModelIndex &item);
Q_SIGNALS:
void requestDetachToMainWindow(Results *);
};
#endif
......@@ -54,3 +54,9 @@ void ResultsTreeView::initViewItemOption(QStyleOptionViewItem *option) const
option->palette.setColor(QPalette::WindowText, m_fg);
}
#endif
void ResultsTreeView::resizeEvent(QResizeEvent *e)
{
Q_EMIT geometryChanged();
QTreeView::resizeEvent(e);
}
......@@ -23,6 +23,12 @@ public:
private:
QColor m_fg;
protected:
void resizeEvent(QResizeEvent *) override;
Q_SIGNALS:
void geometryChanged();
};
#endif
......@@ -1672,12 +1672,13 @@ void KatePluginSearchView::itemSelected(const QModelIndex &item)
// open any children to go to the first match in the file
QModelIndex matchItem = item;
while (m_curResults->model()->hasChildren(matchItem)) {
matchItem = m_curResults->model()->index(0, 0, matchItem);
if (item.model() == m_curResults->model()) {
while (m_curResults->model()->hasChildren(matchItem)) {
matchItem = m_curResults->model()->index(0, 0, matchItem);
}
m_curResults->treeView->setCurrentIndex(matchItem);
}
m_curResults->treeView->setCurrentIndex(matchItem);
// get stuff
int toLine = matchItem.data(MatchModel::StartLineRole).toInt();
int toColumn = matchItem.data(MatchModel::StartColumnRole).toInt();
......@@ -1994,6 +1995,7 @@ void KatePluginSearchView::addTab()
res->treeView->setRootIsDecorated(false);
connect(res->treeView, &QTreeView::doubleClicked, this, &KatePluginSearchView::itemSelected, Qt::UniqueConnection);
connect(res->treeView, &QTreeView::customContextMenuRequested, this, &KatePluginSearchView::customResMenuRequested, Qt::UniqueConnection);
connect(res, &Results::requestDetachToMainWindow, this, &KatePluginSearchView::detachTabToMainWindow, Qt::UniqueConnection);
res->matchModel.setDocumentManager(m_kateApp);
connect(&res->matchModel, &MatchModel::replaceDone, this, &KatePluginSearchView::replaceDone);
......@@ -2015,6 +2017,21 @@ void KatePluginSearchView::addTab()
res->treeView->installEventFilter(this);
}
void KatePluginSearchView::detachTabToMainWindow(Results *res)
{
if (!res) {
return;
}
int i = m_tabBar->currentIndex();
m_curResults->setWindowIcon(QIcon::fromTheme(QStringLiteral("edit-find")));
m_curResults->setWindowTitle(i18n("Search: %1", m_tabBar->tabText(i)));
Utils::addWidget(m_curResults, m_mainWindow);
m_curResults = nullptr;
m_tabBar->removeTab(i);
addTab();
}
void KatePluginSearchView::tabCloseRequested(int index)
{
Results *tmp = qobject_cast<Results *>(m_ui.resultWidget->widget(index));
......@@ -2149,6 +2166,14 @@ void KatePluginSearchView::customResMenuRequested(const QPoint &pos)
menu->addAction(exportMatches);
}
if (m_curResults) {
QAction *openAsEditorTab = new QAction(i18n("Open as Editor Tab"), tree);
connect(openAsEditorTab, &QAction::triggered, this, [this] {
detachTabToMainWindow(m_curResults);
});
menu->addAction(openAsEditorTab);
}
QAction *clear = menu->addAction(i18n("Clear"));
menu->popup(tree->viewport()->mapToGlobal(pos));
......
......@@ -109,6 +109,7 @@ private Q_SLOTS:
void addTab();
void tabCloseRequested(int index);
void toggleOptions(bool show);
void detachTabToMainWindow(Results *);
void searchContextMenu(const QPoint &pos);
void replaceContextMenu(const QPoint &pos);
......
......@@ -1325,6 +1325,11 @@ QObject *KateMainWindow::pluginView(const QString &name)
bool KateMainWindow::addWidget(QWidget *widget)
{
if (!widget) {
qWarning() << Q_FUNC_INFO << "Unexpected null widget!";
return false;
}
auto vs = m_viewManager->activeViewSpace();
vs->addWidgetAsTab(widget);
Q_EMIT widgetAdded(widget);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment