kde-extraapps/kdeplasma-addons/applets/fileWatcher/fileWatcher.cpp
Ivailo Monev a174092cbe kdeplasma-addons: adjust to KDirWatch changes
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
2022-12-21 00:27:21 +02:00

294 lines
9.7 KiB
C++

/***************************************************************************
* Copyright (C) 2007 by Jesper Thomschutz <jesperht@yahoo.com> *
* Simon Hausmann <hausmann@kde.org> *
* Copyright (C) 2008 by Davide Bettio <davide.bettio@kdemail.net> *
* *
* 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; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#include "fileWatcher.h"
#include <QtGui/qgraphicsitem.h>
#include <KDirWatch>
#include <QFile>
#include <QStringList>
#include <QTextDocument>
#include <QTextCursor>
#include <QTextStream>
#include <KConfigDialog>
#include <KMimeType>
#include <Plasma/Theme>
#include "fileWatcherTextItem.h"
FileWatcher::FileWatcher(QObject *parent, const QVariantList &args)
: Plasma::Applet(parent, args),
file(new QFile(this)),
watcher(new KDirWatch(this)),
textItem(new FileWatcherTextItem(this)),
textStream(0)
{
setAspectRatioMode(Plasma::IgnoreAspectRatio);
setHasConfigurationInterface(true);
resize(400, 200);
}
FileWatcher::~FileWatcher()
{
delete textStream;
}
void FileWatcher::init()
{
Plasma::ToolTipManager::self()->registerWidget(this);
textItem->moveBy(contentsRect().x(), contentsRect().y());
textItem->setSize((int) contentsRect().width(), (int) contentsRect().height());
textDocument = textItem->document();
QObject::connect(watcher, SIGNAL(dirty(QString)), this, SLOT(loadFile(QString)));
configChanged();
updateRows();
textItem->update();
}
void FileWatcher::configChanged()
{
KConfigGroup cg = config();
QString path = cg.readEntry("path", QString());
setAssociatedApplicationUrls(KUrl(path));
textItem->setDefaultTextColor(cg.readEntry("textColor", Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor)));
textItem->setFont(cg.readEntry("font", Plasma::Theme::defaultTheme()->font(Plasma::Theme::DefaultFont)));
m_filters = cg.readEntry("filters", QStringList());
m_showOnlyMatches = cg.readEntry("showOnlyMatches", false);
m_useRegularExpressions = cg.readEntry("useRegularExpressions", false);
if (path.isEmpty()) {
setConfigurationRequired(true, i18n("Select a file to watch."));
} else {
loadFile(path);
}
}
void FileWatcher::updateRows()
{
QFontMetrics metrics(textItem->font());
textDocument->setMaximumBlockCount((int) (contentsRect().height()) / metrics.height());
if (textStream){
textDocument->clear();
textItem->update();
textStream->seek(0);
newData();
}
}
void FileWatcher::constraintsEvent(Plasma::Constraints constraints)
{
if (constraints & Plasma::SizeConstraint){
textItem->setSize((int) contentsRect().width(), (int) contentsRect().height());
textItem->setPos(contentsRect().topLeft());
updateRows();
}
if (constraints & Plasma::FormFactorConstraint) {
const Plasma::FormFactor f = formFactor();
if (f == Plasma::Planar || f == Plasma::MediaCenter) {
setMinimumSize(200, 100);
} else {
setMinimumSize(-1, -1);
}
}
}
void FileWatcher::loadFile(const QString& path)
{
if (path.isEmpty())
return;
if (!QFile::exists(path)) {
delete textStream;
textStream = 0;
file->close();
setConfigurationRequired(true, i18n("Could not open file: %1", path));
textDocument->clear();
return;
}
bool newFile = !textStream || m_currentPath != path;
if (newFile) {
delete textStream;
textStream = 0;
watcher->removeFile(m_currentPath);
watcher->addFile(path);
file->close();
KMimeType::Ptr mimeType = KMimeType::findByFileContent(path);
if (!(mimeType->is("text/plain") || mimeType->name() == QLatin1String("application/x-zerosize"))) {
setConfigurationRequired(true, i18n("Cannot watch non-text file: %1", path));
return;
}
file->setFileName(path);
if (!file->open(QIODevice::ReadOnly | QIODevice::Text)){
setConfigurationRequired(true, i18n("Could not open file: %1", path));
return;
}
textStream = new QTextStream(file);
setConfigurationRequired(false);
Plasma::ToolTipContent toolTipData;
toolTipData.setMainText(path);
Plasma::ToolTipManager::self()->setContent(this, toolTipData);
m_currentPath = path;
textDocument->clear();
}
newData();
}
void FileWatcher::newData()
{
QTextCursor cursor(textDocument);
cursor.movePosition(QTextCursor::End);
cursor.beginEditBlock();
QStringList list;
{
//Slight speed optimization hack for bigger files.
//Doing this is faster than doing unnecessary insertText()
QString data = textStream->readAll();
if (data.isEmpty()) {
textStream->seek(0);
data = textStream->readAll();
textDocument->clear();
}
QStringList tmpList = data.split('\n', QString::SkipEmptyParts);
//Add lines from the back into the file
for (int i = tmpList.size() - 1; i >= 0; --i){
if (m_showOnlyMatches){
for (int j = 0; j < m_filters.size(); ++j)
if (tmpList.at(i).contains(QRegExp(m_filters.at(j), Qt::CaseSensitive, m_useRegularExpressions ? QRegExp::RegExp : QRegExp::FixedString))){
list.insert(0, tmpList.at(i));
break;
}
}
else
list.insert(0, tmpList.at(i));
if (list.size() == textDocument->maximumBlockCount()) break;
}
}
// go through the lines of readed block
for (int i = 0; i < list.size(); ++i){
// insert new block before line, but skip insertion on beginning of document
// because we don't want empty space on first line
if (cursor.position() != 0){
cursor.insertBlock();
}
cursor.insertText(list.at(i));
}
cursor.endEditBlock();
emit sizeHintChanged(Qt::PreferredSize);
}
void FileWatcher::createConfigurationInterface(KConfigDialog *parent)
{
QWidget *widget = new QWidget();
ui.setupUi(widget);
parent->addPage(widget, i18n("General"), icon());
connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted()));
connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted()));
ui.pathUrlRequester->setUrl(file->fileName());
ui.fontRequester->setFont(textItem->font());
ui.fontColorButton->setColor(textItem->defaultTextColor());
widget = new QWidget();
filtersUi.setupUi(widget);
parent->addPage(widget, i18n("Filters"), icon());
filtersUi.filtersListWidget->setItems(m_filters);
filtersUi.showOnlyMatchesCheckBox->setChecked(m_showOnlyMatches);
filtersUi.useRegularExpressionsRadioButton->setChecked(m_useRegularExpressions);
connect(ui.fontColorButton,SIGNAL(changed(QColor)),parent, SLOT(settingsModified()));
connect(ui.fontRequester,SIGNAL(fontSelected(QFont)),parent, SLOT(settingsModified()));
connect(ui.pathUrlRequester,SIGNAL(textChanged(QString)),parent, SLOT(settingsModified()));
connect(filtersUi.filtersListWidget,SIGNAL(changed()),parent, SLOT(settingsModified()));
connect(filtersUi.showOnlyMatchesCheckBox,SIGNAL(toggled(bool)),parent, SLOT(settingsModified()));
connect(filtersUi.useExactMatchRadioButton,SIGNAL(toggled(bool)),parent, SLOT(settingsModified()));
connect(filtersUi.useRegularExpressionsRadioButton,SIGNAL(toggled(bool)),parent, SLOT(settingsModified()));
}
void FileWatcher::configAccepted()
{
KConfigGroup cg = config();
QFileInfo file(ui.pathUrlRequester->url().toLocalFile());
QString tmpPath;
if (file.isFile()){
tmpPath = file.absoluteFilePath();
cg.writePathEntry("path", file.absoluteFilePath());
}
textItem->setFont(ui.fontRequester->font());
cg.writeEntry("font", ui.fontRequester->font());
textItem->setDefaultTextColor(ui.fontColorButton->color());
cg.writeEntry("textColor", ui.fontColorButton->color());
m_filters = filtersUi.filtersListWidget->items();
cg.writeEntry("filters", m_filters);
m_showOnlyMatches = filtersUi.showOnlyMatchesCheckBox->isChecked();
cg.writeEntry("showOnlyMatches", m_showOnlyMatches);
m_useRegularExpressions = filtersUi.useRegularExpressionsRadioButton->isChecked();
cg.writeEntry("useRegularExpressions", m_useRegularExpressions);
textItem->update();
loadFile(tmpPath);
setAssociatedApplicationUrls(KUrl(tmpPath));
emit configNeedsSaving();
}
QSizeF FileWatcher::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
{
QSizeF hint = QGraphicsWidget::sizeHint(which, constraint);
if (which == Qt::PreferredSize) {
hint.setHeight(qMax((qreal)200.0, textItem->document()->size().height()));
}
return hint;
}
#include "moc_fileWatcher.cpp"