2015-01-15 17:07:43 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* 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"
|
|
|
|
|
2015-11-25 11:50:42 +00:00
|
|
|
#include <QtGui/qgraphicsitem.h>
|
2015-01-15 17:07:43 +00:00
|
|
|
#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)
|
|
|
|
{
|
2022-12-21 00:27:21 +02:00
|
|
|
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;
|
|
|
|
}
|
2015-01-15 17:07:43 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2015-02-27 11:02:43 +00:00
|
|
|
#include "moc_fileWatcher.cpp"
|