Commit 19854671 authored by Vishesh Handa's avatar Vishesh Handa
Browse files

Add the Baloo "File Search" KCM

The KCM is being moved from the Baloo repository.
parent 994f1a38
......@@ -42,7 +42,6 @@ find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS
Attica
Wallet
Runner
)
find_package(KDecorations REQUIRED CONFIG)
......@@ -62,6 +61,16 @@ set_package_properties(KF5Activities PROPERTIES DESCRIPTION "management of Plasm
PURPOSE "Needed by activity related plasmoids and the pager."
)
# Baloo is currently part of the KF5 namespace, but it is not
# a proper framework. Hence the strange versioning.
# This will be fixed with Plasma 5.2, as Baloo should have
# become a framework by then
find_package(KF5Baloo "5.1.90")
set_package_properties(KF5Baloo PROPERTIES DESCRIPTION "File Searching"
TYPE REQUIRED
PURPOSE "Needed to build to File Search KCM"
)
find_package(USB)
set(HAVE_LIBUSB ${LIBUSB_FOUND})
set_package_properties(USB PROPERTIES DESCRIPTION "User level access to USB devices"
......
......@@ -51,6 +51,7 @@ add_subdirectory(phonon)
add_subdirectory(runners)
add_subdirectory(useraccount)
add_subdirectory(workspaceoptions)
add_subdirectory(baloo)
if( FREETYPE_FOUND )
if(FONTCONFIG_FOUND )
......
remove_definitions(-DTRANSLATION_DOMAIN=\"baloo_file\")
add_definitions(-DTRANSLATION_DOMAIN=\"kcm_baloofile\")
set(kcm_file_SRCS
kcm.cpp
fileexcludefilters.cpp
folderselectionwidget.cpp
)
qt5_add_dbus_interface(kcm_file_SRCS ${BALOO_DBUS_INTERFACES_DIR}/org.kde.baloo.file.indexer.xml fileindexerinterface)
ki18n_wrap_ui(kcm_file_SRCS
configwidget.ui
)
add_library(kcm_baloofile MODULE ${kcm_file_SRCS})
target_link_libraries(kcm_baloofile
KF5::KIOWidgets
KF5::CoreAddons
KF5::KCMUtils
KF5::I18n
KF5::Solid
KF5::Baloo
Qt5::DBus
Qt5::Widgets
)
install(FILES kcm_baloofile.desktop DESTINATION ${SERVICES_INSTALL_DIR})
install(TARGETS kcm_baloofile DESTINATION ${PLUGIN_INSTALL_DIR})
#! /usr/bin/env bash
$EXTRACTRC `find . -name "*.ui"` >> rc.cpp || exit 11
$XGETTEXT `find . -name "*.cpp"` -o $podir/kcm_baloofile.pot
rm -f rc.cpp
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<author>Vishesh Handa</author>
<class>ConfigWidget</class>
<widget class="QWidget" name="ConfigWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>669</width>
<height>671</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,5">
<item>
<widget class="QLabel" name="m_pixmapLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="m_mainLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Desktop Search helps you quickly locate all your files based on their content</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="m_groupBox">
<property name="title">
<string>Do not search in these locations</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="FolderSelectionWidget" name="m_folderSelectionWidget" native="true"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="m_enableCheckbox">
<property name="text">
<string>Enable Desktop Search</string>
</property>
</widget>
</item>
<item>
<spacer name="bottomSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>66</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>FolderSelectionWidget</class>
<extends>QWidget</extends>
<header>folderselectionwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
/* This file is part of the KDE Project
Copyright (c) 2008-2010 Sebastian Trueg <trueg@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "fileexcludefilters.h"
namespace
{
const char* const s_defaultFileExcludeFilters[] = {
// tmp files
"*~",
"*.part",
// temporary build files
"*.o",
"*.la",
"*.lo",
"*.loT",
"*.moc",
"moc_*.cpp",
"qrc_*.cpp",
"ui_*.h",
"cmake_install.cmake",
"CMakeCache.txt",
"CTestTestfile.cmake",
"libtool",
"config.status",
"confdefs.h",
"autom4te",
"conftest",
"confstat",
"Makefile.am",
// misc
"*.csproj",
"*.m4",
"*.rej",
"*.gmo",
"*.pc",
"*.omf",
"*.aux",
"*.tmp",
"*.po",
"*.vm*",
"*.nvram",
"*.rcore",
"*.swap",
"lzo",
"litmain.sh",
"*.orig",
".histfile.*",
".xsession-errors*",
// Compiled files
"*.class", // Java
"*.pyc", // Python
"*.elc", // Emacs Lisp
// end of list
0
};
const int s_defaultFileExcludeFiltersVersion = 2;
const char* const s_defaultFolderExcludeFilters[] = {
"po",
// VCS
"CVS",
".svn",
".git",
"_darcs",
".bzr",
".hg",
// development
"CMakeFiles",
"CMakeTmp",
"CMakeTmpQmake",
".moc",
".obj",
".pch",
".uic",
//misc
"core-dumps",
"lost+found",
// end of list
0
};
const int s_defaultFolderExcludeFiltersVersion = 1;
const char* const s_sourceCodeMimeTypes[] = {
"text/css",
"text/x-c++src",
"text/x-c++hdr",
"text/x-csrc",
"text/x-chdr", // c header files
"text/x-python",
"text/x-assembly",
"text/x-java",
"text/x-objsrc",
"text/x-ruby",
"text/x-scheme",
"text/x-pascal",
"text/x-yacc",
"text/x-sed",
"text/x-haskell",
"text/asp",
"application/x-awk",
"application/x-cgi",
"application/x-csh",
"application/x-java",
"application/x-javascript",
"application/x-perl",
"application/x-php",
"application/x-python",
"application/x-sh",
"application/x-tex",
// end of list
0
};
const int s_sourceCodeMimeTypesVersion = 1;
}
QStringList Baloo::defaultExcludeFilterList()
{
QStringList l;
for (int i = 0; s_defaultFileExcludeFilters[i]; ++i)
l << QLatin1String(s_defaultFileExcludeFilters[i]);
for (int i = 0; s_defaultFolderExcludeFilters[i]; ++i)
l << QLatin1String(s_defaultFolderExcludeFilters[i]);
return l;
}
int Baloo::defaultExcludeFilterListVersion()
{
return qMax(s_defaultFileExcludeFiltersVersion, s_defaultFolderExcludeFiltersVersion);
}
QStringList Baloo::sourceCodeMimeTypes()
{
QStringList l;
for (int i = 0; s_sourceCodeMimeTypes[i]; ++i)
l << QLatin1String(s_sourceCodeMimeTypes[i]);
return l;
}
QStringList Baloo::defaultExcludeMimetypes()
{
return sourceCodeMimeTypes();
}
int Baloo::defaultExcludeMimetypesVersion()
{
// The +1 is the image, video and audio mimetypes
return s_sourceCodeMimeTypesVersion + 1;
}
/* This file is part of the KDE Project
Copyright (c) 2008-2010 Sebastian Trueg <trueg@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef _FILE_EXCLUDE_FILTERS_H_
#define _FILE_EXCLUDE_FILTERS_H_
#include <QtCore/QStringList>
namespace Baloo
{
/**
* \return A list of default exclude filters to be used
* in the filewatch service to ignore temporary files
* and folders that change a lot and as a basis for the
* user configurable exclude filters in the strigi service.
*/
QStringList defaultExcludeFilterList();
/**
* \return The version of the default exclude filter list.
* This is increased whenever the list changes.
*/
int defaultExcludeFilterListVersion();
QStringList defaultExcludeMimetypes();
int defaultExcludeMimetypesVersion();
QStringList sourceCodeMimeTypes();
}
#endif
/*
* This file is part of the KDE Baloo Project
* Copyright (C) 2014 Vishesh Handa <me@vhanda.in>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "folderselectionwidget.h"
#include <Solid/Device>
#include <Solid/StorageAccess>
#include <Solid/StorageDrive>
#include <QIcon>
#include <QDebug>
#include <QFileDialog>
#include <QDir>
#include <QTimer>
#include <QUrl>
#include <KLocalizedString>
#include <QBoxLayout>
#include <QSpacerItem>
#include <QPushButton>
FolderSelectionWidget::FolderSelectionWidget(QWidget* parent, Qt::WindowFlags f)
: QWidget(parent, f)
{
m_listWidget = new QListWidget(this);
m_listWidget->setAlternatingRowColors(true);
m_messageWidget = new KMessageWidget(this);
m_messageWidget->hide();
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(m_messageWidget);
layout->addWidget(m_listWidget);
QHBoxLayout* hLayout = new QHBoxLayout;
QSpacerItem* spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
hLayout->addItem(spacer);
m_addButton = new QPushButton(this);
m_addButton->setIcon(QIcon::fromTheme(QLatin1String("list-add")));
connect(m_addButton, &QPushButton::clicked, this, &FolderSelectionWidget::slotAddButtonClicked);
m_removeButton = new QPushButton(this);
m_removeButton->setIcon(QIcon::fromTheme(QLatin1String("list-remove")));
m_removeButton->setEnabled(false);
connect(m_removeButton, &QPushButton::clicked, this, &FolderSelectionWidget::slotRemoveButtonClicked);
connect(m_listWidget, &QListWidget::currentItemChanged, this, &FolderSelectionWidget::slotCurrentItemChanged);
hLayout->addWidget(m_addButton);
hLayout->addWidget(m_removeButton);
layout->addItem(hLayout);
}
namespace {
QStringList addTrailingSlashes(const QStringList& input) {
QStringList output;
Q_FOREACH (QString str, input) {
if (!str.endsWith(QDir::separator()))
str.append(QDir::separator());
output << str;
}
return output;
}
QString makeHomePretty(const QString& url) {
if (url.startsWith(QDir::homePath()))
return QString(url).replace(0, QDir::homePath().length(), QLatin1String("~"));
return url;
}
}
void FolderSelectionWidget::setFolders(QStringList includeDirs, QStringList exclude)
{
m_listWidget->clear();
m_mountPoints.clear();
QList<Solid::Device> devices
= Solid::Device::listFromType(Solid::DeviceInterface::StorageAccess);
Q_FOREACH (const Solid::Device& dev, devices) {
const Solid::StorageAccess* sa = dev.as<Solid::StorageAccess>();
if (!sa->isAccessible())
continue;
QString mountPath = sa->filePath();
if (!shouldShowMountPoint(mountPath))
continue;
m_mountPoints << mountPath;
}
m_mountPoints << QDir::homePath();
m_mountPoints = addTrailingSlashes(m_mountPoints);
includeDirs = addTrailingSlashes(includeDirs);
exclude = addTrailingSlashes(exclude);
QStringList excludeList = exclude;
Q_FOREACH (const QString& mountPath, m_mountPoints) {
if (includeDirs.contains(mountPath))
continue;
if (exclude.contains(mountPath))
continue;
excludeList << mountPath;
}
Q_FOREACH (QString url, excludeList) {
QListWidgetItem* item = new QListWidgetItem(m_listWidget);
QString display = getFolderDisplayName(url);
item->setData(Qt::DisplayRole, display);
item->setData(Qt::WhatsThisRole, url);
item->setData(UrlRole, url);
item->setData(Qt::DecorationRole, QIcon(iconName(url)));
item->setToolTip(makeHomePretty(url));
m_listWidget->addItem(item);
}
if (m_listWidget->count() == 0) {
m_removeButton->setEnabled(false);
}
}
QStringList FolderSelectionWidget::includeFolders() const
{
QStringList folders;
Q_FOREACH (const QString& mountPath, m_mountPoints) {
bool inExclude = false;
for (int i=0; i<m_listWidget->count(); ++i) {
QListWidgetItem* item = m_listWidget->item(i);
QString url = item->data(UrlRole).toString();
if (mountPath == url) {
inExclude = true;
break;
}
}
if (!inExclude) {
folders << mountPath;
}
}
return folders;
}
QStringList FolderSelectionWidget::excludeFolders() const
{
QStringList folders;
for (int i=0; i<m_listWidget->count(); ++i) {
QListWidgetItem* item = m_listWidget->item(i);
QString url = item->data(UrlRole).toString();
folders << url;
}
return folders;
}
QString FolderSelectionWidget::fetchMountPoint(const QString& url) const
{
QString mountPoint;
Q_FOREACH (const QString& mount, m_mountPoints) {
if (url.startsWith(mount) && mount.size() > mountPoint.size())
mountPoint = mount;
}
return mountPoint;
}
void FolderSelectionWidget::slotAddButtonClicked()
{
QString url = QFileDialog::getExistingDirectory(this, i18n("Select the folder which should be excluded"));
if (url.isEmpty()) {
return;
}
if (!url.endsWith(QDir::separator()))
url.append(QDir::separator());
// We don't care about the root dir
if (url == QLatin1String("/")) {
showMessage(i18n("The root directory is always hidden"));
}
// Remove any existing folder with that name
// Remove any folder which is a sub-folder
QVector<QListWidgetItem*> deleteList;
for (int i=0; i<m_listWidget->count(); ++i) {
QListWidgetItem* item = m_listWidget->item(i);
QString existingUrl = item->data(UrlRole).toString();
if (existingUrl == url) {
QString name = QUrl::fromLocalFile(url).fileName();
showMessage(i18n("Folder %1 is already excluded").arg(name));
deleteList << item;
continue;
}
QString existingMountPoint = fetchMountPoint(existingUrl);
QString mountPoint = fetchMountPoint(url);
if (existingMountPoint == mountPoint) {
// existingUrl is not required since it comes under url
if (existingUrl.startsWith(url)) {
deleteList << item;
}
else if (url.startsWith(existingUrl)) {
// No point adding ourselves since our parents exists
// we just move the parent to the bottom