Commit 1e872d5a authored by Kåre Särs's avatar Kåre Särs

Add a new search plugin

parent b1936990
......@@ -26,6 +26,7 @@ add_subdirectory( filetemplates )
add_subdirectory( kate-ctags )
add_subdirectory( katebuild-plugin )
add_subdirectory( search )
add_subdirectory( kttsd )
......
# building separately or as part of kdesdk?
if(NOT KDE4_FOUND)
cmake_minimum_required( VERSION 2.6 )
find_package(KDE4 REQUIRED)
ADD_DEFINITIONS(-DKDE_DEFAULT_DEBUG_AREA=13040)
include_directories(${KDE4_INCLUDES})
include_directories(${KDE4_KIO_INCLUDES})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
endif(NOT KDE4_FOUND)
set(katesearchplugin_PART_SRCS
plugin_search.cpp
search_open_files.cpp
search_folder.cpp
)
kde4_add_ui_files(katesearchplugin_PART_SRCS search.ui)
kde4_add_plugin(katesearchplugin ${katesearchplugin_PART_SRCS})
target_link_libraries(katesearchplugin ${KDE4_KDEUI_LIBS} ${KDE4_KDECORE_LIBS} ${KDE4_KTEXTEDITOR_LIBS} kateinterfaces)
########### install files ###############
install(TARGETS katesearchplugin DESTINATION ${PLUGIN_INSTALL_DIR})
install(FILES ui.rc DESTINATION ${DATA_INSTALL_DIR}/kate/plugins/katesearch)
install(FILES katesearch.desktop DESTINATION ${SERVICES_INSTALL_DIR})
#! /bin/sh
$EXTRACTRC *.rc >> rc.cpp
$XGETTEXT *.cpp -o $podir/katehelloworld.pot
[Desktop Entry]
Type=Service
ServiceTypes=Kate/Plugin
X-KDE-Library=katesearchplugin
X-Kate-Version=2.9
Name=Search Plugin
Comment=Find a pattern in files
/* Kate search plugin
*
* Copyright (C) 2011 by Kåre Särs <kare.sars@iki.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program in a file called COPYING; if not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include "plugin_search.h"
#include "plugin_search.moc"
#include <kate/application.h>
#include <ktexteditor/view.h>
#include <ktexteditor/document.h>
#include <kate/documentmanager.h>
#include <kaction.h>
#include <kactioncollection.h>
#include <klocale.h>
#include <kpluginfactory.h>
#include <kpluginloader.h>
#include <kaboutdata.h>
K_PLUGIN_FACTORY(KatePluginSearchFactory, registerPlugin<KatePluginSearch>();)
K_EXPORT_PLUGIN(KatePluginSearchFactory(KAboutData("katesearch","katesearch",ki18n("Search in files"), "0.1", ki18n("Find in open files plugin"))))
KatePluginSearch::KatePluginSearch(QObject* parent, const QList<QVariant>&)
: Kate::Plugin((Kate::Application*)parent, "kate-search-plugin")
{
KGlobal::locale()->insertCatalog("katesearch");
}
KatePluginSearch::~KatePluginSearch()
{
}
Kate::PluginView *KatePluginSearch::createView(Kate::MainWindow *mainWindow)
{
return new KatePluginSearchView(mainWindow, application());
}
KatePluginSearchView::KatePluginSearchView(Kate::MainWindow *mainWin, Kate::Application* application)
: Kate::PluginView(mainWin),
Kate::XMLGUIClient(KatePluginSearchFactory::componentData()),
m_kateApp(application)
{
KAction *a = actionCollection()->addAction("search_in_files");
a->setText(i18n("Search in Files"));
connect(a, SIGNAL(triggered(bool)), this, SLOT(toggleSearchView()));
m_toolView = mainWin->createToolView ("kate_plugin_katesearch",
Kate::MainWindow::Bottom,
SmallIcon("edit-find"),
i18n("Search in files"));
QWidget *container = new QWidget(m_toolView);
m_ui.setupUi(container);
m_ui.displayOptions->setIcon(KIcon("list-add"));
m_ui.searchButton->setIcon(KIcon("edit-find"));
m_ui.stopButton->setIcon(KIcon("process-stop"));
m_matchCase = new KAction(i18n("Match case"), this);
m_matchCase->setCheckable(true);
m_ui.optionsButton->addAction(m_matchCase);
m_useRegExp = new KAction(i18n("Regular Expression"), this);
m_useRegExp->setCheckable(true);
m_ui.optionsButton->addAction(m_useRegExp);
connect(m_ui.searchButton, SIGNAL(clicked()), this, SLOT(startSearch()));
connect(m_ui.displayOptions, SIGNAL(toggled(bool)), this, SLOT(toggleOptions(bool)));
connect(m_ui.searchPlaceCombo, SIGNAL(currentIndexChanged (int)), this, SLOT(searchPlaceChanged()));
connect(m_ui.searchCombo, SIGNAL(editTextChanged(QString)), this, SLOT(searchPatternChanged()));
connect(m_ui.stopButton, SIGNAL(clicked()), &m_searchOpenFiles, SLOT(cancelSearch()));
connect(m_ui.stopButton, SIGNAL(clicked()), &m_searchFolder, SLOT(cancelSearch()));
m_ui.displayOptions->setChecked(true);
connect(m_ui.searchResults, SIGNAL(itemClicked(QTreeWidgetItem *, int)),
SLOT(itemSelected(QTreeWidgetItem *)));
connect(&m_searchOpenFiles, SIGNAL(matchFound(QString, int, QString)),
this, SLOT(matchFound(QString, int, QString)));
connect(&m_searchOpenFiles, SIGNAL(searchDone()), this, SLOT(searchDone()));
connect(&m_searchFolder, SIGNAL(matchFound(QString, int, QString)),
this, SLOT(matchFound(QString, int, QString)));
connect(&m_searchFolder, SIGNAL(searchDone()), this, SLOT(searchDone()));
mainWindow()->guiFactory()->addClient(this);
}
KatePluginSearchView::~KatePluginSearchView()
{
mainWindow()->guiFactory()->removeClient(this);
}
void KatePluginSearchView::toggleSearchView()
{
if (!mainWindow()) {
return;
}
if (!m_toolView->isVisible()) {
mainWindow()->showToolView(m_toolView);
m_ui.searchCombo->setFocus(Qt::OtherFocusReason);
}
else {
mainWindow()->hideToolView(m_toolView);
}
}
void KatePluginSearchView::startSearch()
{
m_ui.searchButton->setDisabled(true);
m_ui.stopButton->setDisabled(false);
m_ui.optionsButton->setDisabled(true);
m_ui.displayOptions->setChecked (false);
m_ui.displayOptions->setDisabled(true);
QRegExp reg(m_ui.searchCombo->currentText(),
m_matchCase->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive,
m_useRegExp->isChecked() ? QRegExp::RegExp : QRegExp::FixedString);
m_ui.searchResults->clear();
if (m_ui.searchPlaceCombo->currentIndex() == 0) {
m_searchOpenFiles.startSearch(m_kateApp->documentManager()->documents(), reg);
}
else {
m_searchFolder.startSearch(m_ui.searchFolder->text(),
m_ui.recursiveCheckBox->isChecked(),
m_ui.hiddenCheckBox->isChecked(),
m_ui.symLinkCheckBox->isChecked(),
m_ui.filterCombo->currentText(),
reg);
}
}
void KatePluginSearchView::toggleOptions(bool show)
{
m_ui.stackedWidget->setCurrentIndex((show) ? 1:0);
searchPlaceChanged();
}
void KatePluginSearchView::searchPlaceChanged()
{
bool disable = (m_ui.searchPlaceCombo->currentIndex() == 0);
m_ui.recursiveCheckBox->setDisabled(disable);
m_ui.hiddenCheckBox->setDisabled(disable);
m_ui.symLinkCheckBox->setDisabled(disable);
m_ui.folderLabel->setDisabled(disable);
m_ui.searchFolder->setDisabled(disable);
m_ui.filterLabel->setDisabled(disable);
m_ui.filterCombo->setDisabled(disable);
}
void KatePluginSearchView::searchPatternChanged()
{
m_ui.searchButton->setDisabled(m_ui.searchCombo->currentText().isEmpty());
}
void KatePluginSearchView::matchFound(const QString &fileName, int line, const QString &lineContent)
{
QStringList row;
row << fileName << QString::number(line) << lineContent;
new QTreeWidgetItem(m_ui.searchResults, row);
}
void KatePluginSearchView::searchDone()
{
m_ui.searchButton->setDisabled(false);
m_ui.stopButton->setDisabled(true);
m_ui.optionsButton->setDisabled(false);
m_ui.displayOptions->setDisabled(false);
m_ui.searchResults->resizeColumnToContents(0);
m_ui.searchResults->resizeColumnToContents(1);
m_ui.searchResults->resizeColumnToContents(2);
}
void KatePluginSearchView::itemSelected(QTreeWidgetItem *item)
{
// get stuff
const QString url = item->data(0, Qt::DisplayRole).toString();
if (url.isEmpty()) return;
int line = item->data(1, Qt::DisplayRole).toInt();
// open file (if needed, otherwise, this will activate only the right view...)
mainWindow()->openUrl(KUrl(url));
// any view active?
if (!mainWindow()->activeView()) {
return;
}
// do it ;)
mainWindow()->activeView()->setCursorPosition(KTextEditor::Cursor(line, 0));
mainWindow()->activeView()->setFocus();
}
void KatePluginSearchView::readSessionConfig(KConfigBase* config, const QString& groupPrefix)
{
KConfigGroup cg(config, groupPrefix + ":search-plugin");
m_ui.searchCombo->clear();
m_ui.searchCombo->addItem(cg.readEntry("Search", QString()));
m_matchCase->setChecked(cg.readEntry("MatchCase", false));
m_useRegExp->setChecked(cg.readEntry("UseRegExp", false));
m_ui.searchPlaceCombo->setCurrentIndex(cg.readEntry("Place", 0));
m_ui.recursiveCheckBox->setChecked(cg.readEntry("Recursive", true));
m_ui.hiddenCheckBox->setChecked(cg.readEntry("HiddenFiles", false));
m_ui.symLinkCheckBox->setChecked(cg.readEntry("FollowSymLink", false));
m_ui.searchFolder->setText(cg.readEntry("SearchFolder", QString()));
m_ui.filterCombo->clear();
m_ui.filterCombo->addItems(cg.readEntry("Filters", QString()).split(";"));
m_ui.filterCombo->setCurrentIndex(cg.readEntry("CurrentFilter", 0));
}
void KatePluginSearchView::writeSessionConfig(KConfigBase* config, const QString& groupPrefix)
{
KConfigGroup cg(config, groupPrefix + ":search-plugin");
cg.writeEntry("Search", m_ui.searchCombo->currentText()); // FIXME
cg.writeEntry("MatchCase", m_matchCase->isChecked());
cg.writeEntry("UseRegExp", m_useRegExp->isChecked());
cg.writeEntry("Place", m_ui.searchPlaceCombo->currentIndex());
cg.writeEntry("Recursive", m_ui.recursiveCheckBox->isChecked());
cg.writeEntry("HiddenFiles", m_ui.hiddenCheckBox->isChecked());
cg.writeEntry("FollowSymLink", m_ui.symLinkCheckBox->isChecked());
cg.writeEntry("SearchFolder", m_ui.searchFolder->text());
QStringList filterItems;
for (int i=0; i<qMin(m_ui.filterCombo->count(), 10); i++) {
filterItems << m_ui.filterCombo->itemText(i);
}
cg.writeEntry("Filters", filterItems.join(";"));
cg.writeEntry("CurrentFilter", m_ui.filterCombo->currentIndex());
}
// kate: space-indent on; indent-width 4; replace-tabs on;
/* Kate search plugin
*
* Copyright (C) 2011 by Kåre Särs <kare.sars@iki.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program in a file called COPYING; if not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#ifndef _PLUGIN_SEARCH_H_
#define _PLUGIN_SEARCH_H_
#include <kate/mainwindow.h>
#include <kate/plugin.h>
#include <kxmlguiclient.h>
#include <kaction.h>
#include "ui_search.h"
#include "search_open_files.h"
#include "search_folder.h"
class KatePluginSearch : public Kate::Plugin
{
Q_OBJECT
public:
explicit KatePluginSearch(QObject* parent = 0, const QList<QVariant>& = QList<QVariant>());
virtual ~KatePluginSearch();
Kate::PluginView *createView(Kate::MainWindow *mainWindow);
};
class KatePluginSearchView : public Kate::PluginView, public Kate::XMLGUIClient
{
Q_OBJECT
public:
KatePluginSearchView(Kate::MainWindow *mainWindow, Kate::Application* application);
~KatePluginSearchView();
virtual void readSessionConfig(KConfigBase* config, const QString& groupPrefix);
virtual void writeSessionConfig(KConfigBase* config, const QString& groupPrefix);
private Q_SLOTS:
void toggleSearchView();
void startSearch();
void toggleOptions(bool show);
void searchPlaceChanged();
void searchPatternChanged();
void matchFound(const QString &fileName, int line, const QString &lineContent);
void searchDone();
void itemSelected(QTreeWidgetItem *item);
private:
Ui::SearchDialog m_ui;
QWidget *m_toolView;
Kate::Application *m_kateApp;
SearchOpenFiles m_searchOpenFiles;
SearchFolder m_searchFolder;
KAction *m_matchCase;
KAction *m_useRegExp;
};
#endif
// kate: space-indent on; indent-width 4; replace-tabs on;
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SearchDialog</class>
<widget class="QWidget" name="SearchDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>413</width>
<height>126</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="1,0,0,0,0">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="KComboBox" name="searchCombo">
<property name="editable">
<bool>true</bool>
</property>
<property name="autoCompletion">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QToolButton" name="optionsButton">
<property name="text">
<string>Options</string>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QToolButton" name="displayOptions">
<property name="text">
<string>...</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRaise">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="5">
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>1</number>
</property>
<widget class="QWidget" name="page">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QTreeWidget" name="searchResults">
<property name="autoScroll">
<bool>false</bool>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="itemsExpandable">
<bool>false</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<property name="expandsOnDoubleClick">
<bool>false</bool>
</property>
<attribute name="headerStretchLastSection">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string notr="true">File</string>
</property>
</column>
<column>
<property name="text">
<string notr="true">Line</string>
</property>
</column>
<column>
<property name="text">
<string>Text</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_2">
<layout class="QGridLayout" name="gridLayout_3">
<property name="margin">
<number>0</number>
</property>
<item row="7" column="1">
<widget class="QLabel" name="folderLabel">
<property name="text">
<string>Folder</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>searchFolder</cstring>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QLabel" name="filterLabel">
<property name="text">
<string>Filter</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>filterCombo</cstring>
</property>
</widget>
</item>
<item row="10" column="2" colspan="5">
<widget class="KComboBox" name="filterCombo">
<property name="editable">
<bool>true</bool>
</property>
<property name="insertPolicy">
<enum>QComboBox::InsertAtTop</enum>
</property>
<item>
<property name="text">
<string>*</string>
</property>
</item>
</widget>
</item>
<item row="11" column="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="2">
<widget class="KComboBox" name="searchPlaceCombo">
<item>
<property name="text">
<string>Open files</string>
</property>
</item>
<item>
<property name="text">
<string>Folder</string>
</property>
</item>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Search in</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>searchPlaceCombo</cstring>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QCheckBox" name="recursiveCheckBox">
<property name="text">
<string>Recursive</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="5">
<widget class="QCheckBox" name="symLinkCheckBox">
<property name="text">
<string>Follow symbolic links</string>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QCheckBox" name="hiddenCheckBox">
<property name="text">
<string>Include hidden</string>
</property>
</widget>
</item>
<item row="3" column="6">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="7" column="2" colspan="5">
<widget class="KUrlRequester" name="searchFolder">
<property name="mode">
<set>KFile::Directory|KFile::ExistingOnly|KFile::LocalOnly</set>
</property>
</widget>
</item>
<item row="1" column="1" colspan="6">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>