Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
grulja committed Feb 11, 2016
0 parents commit e3066c8
Show file tree
Hide file tree
Showing 20 changed files with 1,520 additions and 0 deletions.
46 changes: 46 additions & 0 deletions CMakeLists.txt
@@ -0,0 +1,46 @@
project(plasma-activity-monitor)

cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
set(QT_MIN_VERSION "5.4.0")

set(PROJECT_VERSION "5.5.50")
set(PROJECT_VERSION_MAJOR 5)
set(PLASMANM_VERSION_STRING ${PROJECT_VERSION} )

################# set KDE specific information #################

find_package(ECM 1.3.0 REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDECompilerSettings NO_POLICY_SCOPE)

include(ECMPackageConfigHelpers)
include(ECMOptionalAddSubdirectory)
include(FeatureSummary)

find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
Core
DBus
Quick
QuickWidgets
UiTools
Widgets
)

find_package(KF5 REQUIRED
CoreAddons
Declarative
I18n
Plasma
WindowSystem
)

add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0 -DQT_NO_KEYWORDS)
add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS)
remove_definitions(-DQT_NO_CAST_FROM_ASCII -DQT_STRICT_ITERATORS -DQT_NO_CAST_FROM_BYTEARRAY)

add_subdirectory(src)

feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
675 changes: 675 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions README.md
@@ -0,0 +1,6 @@
# Plasma activity monitor
Plasma applet for monitoring your activity

Author: Jan Grulichl <jgrulich@redhat.com>

Released under GPL 2.0+
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
@@ -0,0 +1,2 @@
add_subdirectory(declarative)
add_subdirectory(plasma)
21 changes: 21 additions & 0 deletions src/declarative/CMakeLists.txt
@@ -0,0 +1,21 @@
add_definitions(-DTRANSLATION_DOMAIN="activitymonitor")

set(plasmaactivitymonitor_qmlplugins_SRCS
activitymodel.cpp
activitysortmodel.cpp
qmlplugins.cpp
)

add_library(plasmaactivitymonitor_qmlplugins SHARED ${plasmaactivitymonitor_qmlplugins_SRCS})

target_link_libraries(plasmaactivitymonitor_qmlplugins
Qt5::Core
Qt5::Qml
Qt5::Widgets
KF5::I18n
KF5::CoreAddons
KF5::WindowSystem
)

install(TARGETS plasmaactivitymonitor_qmlplugins DESTINATION ${QML_INSTALL_DIR}/org/kde/plasma/activitymonitor)
install(FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kde/plasma/activitymonitor)
3 changes: 3 additions & 0 deletions src/declarative/Messages.sh
@@ -0,0 +1,3 @@
#!/usr/bin/env bash

$XGETTEXT `find . -name '*.cpp'` -o $podir/activitymonitor.pot
238 changes: 238 additions & 0 deletions src/declarative/activitymodel.cpp
@@ -0,0 +1,238 @@
/*
Copyright 2016 Jan Grulich <jgrulich@redhat.com>
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) version 3, or any
later version accepted by the membership of KDE e.V. (or its
successor approved by the membership of KDE e.V.), which shall
act as a proxy defined in Section 6 of version 3 of the license.
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, see <http://www.gnu.org/licenses/>.
*/

#include "activitymodel.h"

#include <KLocalizedString>
#include <KWindowSystem>

#include <QLoggingCategory>

Q_DECLARE_LOGGING_CATEGORY(PLASMA_ACTIVITY_MONITOR)

Q_LOGGING_CATEGORY(PLASMA_ACTIVITY_MONITOR, "plasma-activity-monitor")

/* ActivityModelItem *
* ----------------------------------------------------------------------- */

ActivityModelItem::ActivityModelItem(QObject* parent)
: QObject(parent)
{
}

ActivityModelItem::~ActivityModelItem()
{
}

void ActivityModelItem::setActivityIcon(const QPixmap& icon)
{
m_activityIcon = icon;
}

QPixmap ActivityModelItem::activityIcon() const
{
return m_activityIcon;
}

void ActivityModelItem::setActivityName(const QString& name)
{
m_activityName = name;
}

QString ActivityModelItem::activityName() const
{
return m_activityName;
}

void ActivityModelItem::setActivityTime(const QTime& time)
{
m_activityTime = time;
}

QTime ActivityModelItem::activityTime() const
{
return m_activityTime;
}

void ActivityModelItem::addSeconds(int secs)
{
m_activityTime = m_activityTime.addSecs(secs);
}

/* ActivityModel *
* ----------------------------------------------------------------------- */

ActivityModel::ActivityModel(QObject* parent)
: QAbstractListModel(parent),
m_timer(new QTimer(this)),
m_trackingEnabled(false)
{
QLoggingCategory::setFilterRules(QStringLiteral("plasma-activity-monitor.debug = false"));

// Process the currently active window
activeWindowChanged(KWindowSystem::activeWindow());

connect(KWindowSystem::self(), &KWindowSystem::activeWindowChanged, this, &ActivityModel::activeWindowChanged, Qt::UniqueConnection);
connect(m_timer, &QTimer::timeout, this, &ActivityModel::updateTime);
}

ActivityModel::~ActivityModel()
{
}

QVariant ActivityModel::data(const QModelIndex& index, int role) const
{
const int row = index.row();

if (row >= 0 && row < m_list.count()) {
ActivityModelItem * item = m_list.at(row);

switch (role) {
case ActivityIconRole:
return item->activityIcon();
break;
case ActivityNameRole:
return item->activityName();
break;
case ActivityTimeRole:
return item->activityTime().toString(QLatin1String("hh:mm:ss"));
break;
default:
break;
}
}

return QVariant();
}

int ActivityModel::rowCount(const QModelIndex& parent) const
{
Q_UNUSED(parent);
return m_list.count();
}

QHash< int, QByteArray > ActivityModel::roleNames() const
{
QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
roles[ActivityIconRole] = "ActivityIcon";
roles[ActivityNameRole] = "ActivityName";
roles[ActivityTimeRole] = "ActivityTime";

return roles;
}

bool ActivityModel::trackingEnabled() const
{
return m_trackingEnabled;
}

void ActivityModel::setTrackingEnabled(bool enable)
{
// Process the currently active window
activeWindowChanged(KWindowSystem::activeWindow());

m_trackingEnabled = enable;

Q_EMIT trackingEnabledChanged(m_trackingEnabled);
}

void ActivityModel::reset(const QString& activity)
{
Q_FOREACH (ActivityModelItem * item, m_list) {
if (activity.isEmpty() || (!activity.isEmpty() && activity == item->activityName())) {
item->setActivityTime(QTime(0, 0, 0));
updateItem(item);
}
}

m_currentActivity = QString();
m_currentTime = QTime::currentTime();

// Process the currently active window
activeWindowChanged(KWindowSystem::activeWindow());
}

void ActivityModel::activeWindowChanged(WId window)
{
KWindowInfo info = KWindowInfo(window, NET::WMName | NET::WMIconName, NET::WM2WindowClass);

qCDebug(PLASMA_ACTIVITY_MONITOR) << "Active window changed to " << info.windowClassName();

if (info.windowClassName().isEmpty()) {
return;
}

auto activityExist = std::find_if(m_list.constBegin(), m_list.constEnd(), [info] (ActivityModelItem * activityItem) {
return activityItem->activityName() == info.windowClassName();
});

if (activityExist == m_list.constEnd()) {
qCDebug(PLASMA_ACTIVITY_MONITOR) << "Adding new activity item " << info.windowClassName();
ActivityModelItem *item = new ActivityModelItem();
item->setActivityName(info.windowClassName());
item->setActivityIcon(KWindowSystem::icon(window, 64, 64, true));
item->setActivityTime(QTime(0, 0, 0));

const int index = m_list.count();
beginInsertRows(QModelIndex(), index, index);
m_list << item;
endInsertRows();
}

if (!m_trackingEnabled) {
// Update previous activity
Q_FOREACH (ActivityModelItem * item, m_list) {
if (m_currentActivity == item->activityName()) {
item->addSeconds(m_currentTime.secsTo(QTime::currentTime()));
updateItem(item);
}
}

// Start timer to update the time every minute
m_timer->stop();
m_timer->start(60000);
}

// Save current time and activity
m_currentActivity = info.windowClassName();
m_currentTime = QTime::currentTime();
}

void ActivityModel::updateTime()
{
Q_FOREACH (ActivityModelItem * item, m_list) {
if (m_currentActivity == item->activityName()) {
item->addSeconds(60);
updateItem(item);
}
}
m_currentTime = m_currentTime.addSecs(60);
m_timer->start(60000);
}

void ActivityModel::updateItem(ActivityModelItem* item)
{
const int row = m_list.indexOf(item);

if (row >= 0) {
QModelIndex index = createIndex(row, 0);
Q_EMIT dataChanged(index, index);
}
}

0 comments on commit e3066c8

Please sign in to comment.