merged kactivities

This commit is contained in:
Ivailo Monev 2014-11-22 18:36:32 +00:00
parent b355de5a12
commit 727e78a4bd
181 changed files with 14734 additions and 0 deletions

View file

@ -272,6 +272,7 @@ add_subdirectory( kdewebkit )
add_subdirectory( includes ) add_subdirectory( includes )
add_subdirectory( experimental ) add_subdirectory( experimental )
add_subdirectory( kactivities )
################# write dependency file which will be installed ################# ################# write dependency file which will be installed #################

12
kactivities/.gitignore vendored Normal file
View file

@ -0,0 +1,12 @@
.debug
tags
_tests
.videproject/ctags
*swp
*~
.kdev4
.cmake-params
.ycm_extra_conf.py
.ycm_extra_conf.pyc
.clang_complete
kactivities.kdev4

View file

@ -0,0 +1,30 @@
[Project]
Name=KDE Activities
Location=/opt/kde/src/libs/kactivities
MakeCommand='OBJ_REPLACEMENT="s:/opt/kde/src/core/libs/kactivities:/opt/kde/build-clang/core/libs/kactivities:" makeobj'
RunLocation=./
RunCommand=./
[General]
OverrideVimCommands=1
AutoInsertModeOnOpen=0
Tags=
SourcePaths=.
[KeyBindings]
SidePanelOpen='<C-A>'
MakeProject='<F5>'
RunProject='<F6>'
[Grep]
Root=.
[Find]
Root=.
[QuickBrowser]
iNotifyEnabled=0
Root=.
TagsSystem=ctags

View file

@ -0,0 +1,2 @@
set tags+=/opt/kde4trunk/ctags/libQt.tags

View file

@ -0,0 +1,32 @@
project (KACTIVITIES)
find_package (KDE4 REQUIRED)
include (GenerateExportHeader)
include (KDE4Defaults)
include (MacroLibrary)
include (MacroOptionalAddSubdirectory)
include (FindPackageHandleStandardArgs)
# Until this is set by FindQt, we are defining the
# QT_NO_DEBUG_OUTPUT if this is not a debug build
string (TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_TOLOWER)
if (NOT CMAKE_BUILD_TYPE_TOLOWER MATCHES "debug")
add_definitions(-DQT_NO_DEBUG_OUTPUT)
endif()
set (
CMAKE_MODULE_PATH
${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules
${CMAKE_MODULE_PATH}
)
if (KAMD_PEDANTIC_COMPILATION)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic")
endif ()
add_subdirectory (src)
macro_display_feature_log ()

3
kactivities/MAINTAINER Normal file
View file

@ -0,0 +1,3 @@
Current kactivities maintainer is: Ivan Čukić <ivan.cukic@kde.org>

17
kactivities/Mainpage.dox Normal file
View file

@ -0,0 +1,17 @@
/** @mainpage KActivities
@authors
See the copyright notices on the individual files.
@maintainers
See the MAINTAINER file
@licenses
@lgpl
*/
// DOXYGEN_SET_PROJECT_NAME = KActivities
// DOXYGEN_SET_RECURSIVE = YES
// DOXYGEN_EXCLUDE_PATTERNS = *_p.h */private/* */tests/* */ontologies/* */service/* */scripts/* */workspace/*
// vim:ts=4:sw=4:expandtab:filetype=doxygen

6
kactivities/README Normal file
View file

@ -0,0 +1,6 @@
See README.developers and README.packagers (the former is also for users).
In order to properly display the files, use the GNU man command.
man README.developers
man README.packagers

View file

@ -0,0 +1,112 @@
.\" " " " " " " " " " " " " " " " " " " " " " " " " " " "
.\" "
.\" It is best to view this file with the man tool: "
.\" man ./README.developers "
.\" "
.\" " " " " " " " " " " " " " " " " " " " " " " " " " " "
.TH README KAMD 2012-08-29 "KDE" "KActivities Developers"
.SH COMMIT POLICY
Every non-trivial patch must go through the review before it goes into the
master branch.
http://git.reviewboard.kde.org
repository: kactivities
groups: plasma
people: Ivan Cukic
If you don't have an account for identity.kde.org, you can send smaller
patches to the plasma-devel@kde.org mailing list, or (please don't) directly
to the repository maintainer (see MAINTAINER file).
.SH CODE POLICY
The code needs to follow KDElibs coding style in *all* parts of the project,
not only the library. You can find more information about the style here:
http://techbase.kde.org/Policies/Kdelibs_Coding_Style
Macros in CMakeLists.txt should be lowercase throughout the project,
and indentation should be 4, with the closing parenthesis in the same level
as the content.
.SH COMPILER COMPATIBILITY
The library (src/lib) needs to be compilable with all compilers that the
latest version of Qt (4.x) supports.
Other parts require modern compilers. You can (and should) use more modern
C++ coding practices. Including auto, lambdas, smart pointers etc. You can
use anything that GCC 4.5 can compile.
These are the compilers you need to test your patches against:
- GCC 4.5
- GCC 4.7
- LLVM/Clang 3.1
When you set up different builds alongside the main one, you can use
scripts/commit.sh to build them all before committing. The script
calls git commit if all builds finished successfully. See the script
for more info.
.SH FILE NAMING
The library files are lower-case, apart from the pretty headers.
The service, and the rest of the repository should be in camel-case
(with the exception of source files that don't have corresponding
headers, or vice-versa).
.SH CONVENIENCE MACROS AND METHODS
There are some convenience macros and methods defined in the headers placed
in the service/utils/ directory.
.TP
.B nullptr
nullptr.h defines nullptr macro if the compiler doesn't support it. It is
defined as 0 which is far from perfect, but works good enough on obsolete
compilers.
.TP
.B _override
override.h defines _override to express explicit virtual overrides. Will
expand to nothing on obsolete compilers.
.TP
.B val
val.h defines a macro 'val' that expands to 'const auto'. People tend not
to use the const keyword even when they are defining a variable that will
not change. This way, it is easier to do so. For example, instead of writing:
const QString path = KStandardDirs::locateLocal("data", ...);
const int id = object->id();
you can (and should) write this:
val path = KStandardDirs::locateLocal("data", ...);
val id = object->id();
This should be always last included header since other parts of the project
or upstream libraries could have used val as a variable name.
.TP
.B D_PTR
d_ptr.h and d_ptr_implementation.h define a smart pointer way of doing
the d-ptr (aka pimpl) idiom.
.TP
.B remove_if
remove_if.h is a generic implementation of the erase-remove idiom
.TP
.B for_each_assoc, find_if_assoc
for_each_assoc.h and find_if_assoc.h define the for_each and find_if
algorithms for associative containers. Works with both Qt and STL containers.

View file

@ -0,0 +1,23 @@
.\" " " " " " " " " " " " " " " " " " " " " " " " " " " "
.\" "
.\" It is best to view this file with the man tool: "
.\" man ./README.packagers "
.\" "
.\" " " " " " " " " " " " " " " " " " " " " " " " " " " "
.\" Best to view this file with the man tool
.TH README KAMD 2012-08-29 "KDE" "KActivities Packagers"
.SH LIBRARY
The library can be used even if the service is not running nor installed.
The dependencies are minimal since it is only a thin wrapper for the d-bus
service.
.SH SERVICE
.TP

11
kactivities/TODO Normal file
View file

@ -0,0 +1,11 @@
Add focus and modification (src/service/plugins/sqlite/StatsPlugin.cpp:176)
A possible problem is that theoretically the dangling ones can be (src/service/plugins/activityranking/ActivityRanking.cpp:316)
Move this to job-based execution (src/service/Activities.cpp:140)
Remove (src/service/Event.h:57)
Test whether necessary services are running (src/workspace/kio/KioActivities.cpp:245)
This should be also done from time to time, (src/service/plugins/sqlite/StatsPlugin.cpp:111)
This should be removed as soon as we get rid of the ResourcesLinkedToActivity method (src/service/plugins/nepomuk/NepomukPlugin.cpp:478)
This should be tested - something is wrong here (src/service/plugins/activityranking/ActivityRanking.cpp:541)
update the service info (src/lib/core/resourceinstance.cpp:152)
update the service info (src/lib/core/resourceinstance.cpp:162)
We should move away from any GUI code (src/service/Application.cpp:107)

View file

@ -0,0 +1,113 @@
# Macro that tests and returns whether a C++ feature is present in the
# current compiler
set(CXX_CHECK_FEATURE_MODULE_DIR "${CMAKE_SOURCE_DIR}/cmake/modules")
set(CXX_FEATURES_SUPPORTED "")
set(CXX_FEATURES_UNSUPPORTED "")
macro(CXX_PERFORM_TEST TEST_SOURCE_FILE TEST_TEST_BINARY_DIR EXPECTED_RESULT RESULT COMPILE_DEFINITIONS)
try_run(
RUN_RESULT_VAR COMPILE_RESULT_VAR
"${TEST_BINARY_DIR}" "${TEST_SOURCE_FILE}"
COMPILE_DEFINITIONS "${COMPILE_DEFINITIONS}"
COMPILE_OUTPUT_VARIABLE COMPILE_OUT
RUN_OUTPUT_VARIABLE RUN_OUT
)
set(RESULT_VAR FALSE)
if (COMPILE_RESULT_VAR AND NOT RUN_RESULT_VAR)
set(RESULT_VAR TRUE)
endif (COMPILE_RESULT_VAR AND NOT RUN_RESULT_VAR)
if (NOT ("${RESULT_VAR}" STREQUAL "${EXPECTED_RESULT}"))
# message ("Got ${RESULT_VAR} as a result, but ${EXPECTED_RESULT} expected")
if (NOT ${COMPILE_RESULT_VAR})
# message("------ compilation output ------")
# message("${COMPILE_OUT}")
endif (NOT ${COMPILE_RESULT_VAR})
if (${RUN_RESULT_VAR})
# message("---------- run output ----------")
# message("${RUN_OUT}")
# message("Process returned: ${RUN_RESULT_VAR}")
endif (${RUN_RESULT_VAR})
# message("--------------------------------")
set (${RESULT} FALSE)
else ()
set (${RESULT} TRUE)
endif ()
endmacro(CXX_PERFORM_TEST TEST_SOURCE EXPECTED_RESULT RESULT)
macro(CXX_CHECK_FEATURE CXX_VERSION FEATURE_NAME FEATURE_NUMBER RESULT_VAR COMPILE_DEFINITIONS)
# Testing whether we have previously set the variable
if(NOT DEFINED ${RESULT_VAR})
set(TEST_BINARY_DIR
"${CMAKE_CURRENT_BINARY_DIR}/cxx-check-feature/cxx_${FEATURE_NUMBER}"
)
set(TEST_SOURCE_BASE
"${CXX_CHECK_FEATURE_MODULE_DIR}/${CXX_VERSION}-test-${FEATURE_NAME}-${FEATURE_NUMBER}"
)
set(TEST_SOURCE_FILE "${TEST_SOURCE_BASE}.cpp")
set(FAILTEST_SOURCE_FILE "${TEST_SOURCE_BASE}-fail.cpp")
set(FEATURE_NAME
"'${FEATURE_NAME}' (${CXX_VERSION} N${FEATURE_NUMBER})"
)
message(STATUS "Checking C++ support for ${FEATURE_NAME}")
string (COMPARE EQUAL "${CMAKE_CXX_COMPILER_ID}" "Clang" CMAKE_COMPILER_IS_CLANG)
string (COMPARE EQUAL "${CMAKE_CXX_COMPILER_ID}" "GNU" CMAKE_COMPILER_IS_GCC)
set (ADD_COMPILE_DEFINITIONS "")
if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG OR CMAKE_COMPILER_IS_GCC)
set (ADD_COMPILE_DEFINITIONS "-std=c++0x")
endif ()
if (EXISTS ${TEST_SOURCE_FILE})
CXX_PERFORM_TEST(${TEST_SOURCE_FILE} ${TEST_BINARY_DIR} TRUE ${RESULT_VAR} "${COMPILE_DEFINITIONS} ${ADD_COMPILE_DEFINITIONS}")
endif ()
if (${RESULT_VAR} AND EXISTS ${FAILTEST_SOURCE_FILE})
CXX_PERFORM_TEST(${FAILTEST_SOURCE_FILE} ${TEST_BINARY_DIR} FALSE ${RESULT_VAR} "${COMPILE_DEFINITIONS} ${ADD_COMPILE_DEFINITIONS}")
endif ()
if (${RESULT_VAR})
message(STATUS "Checking C++ support for ${FEATURE_NAME} -- works")
set (CXX_FEATURES_SUPPORTED
"${CXX_FEATURES_SUPPORTED} ${FEATURE_NAME} (${FEATURE_NUMBER}),"
)
else ()
message(STATUS "Checking C++ support for ${FEATURE_NAME} -- not supported")
set (CXX_FEATURES_UNSUPPORTED
"${CXX_FEATURES_UNSUPPORTED} ${FEATURE_NAME} (${FEATURE_NUMBER}),"
)
endif ()
# This would break the feature reporting on second call of cmake
# TODO: Fix?
# set(${RESULT_VAR} ${${RESULT_VAR}} CACHE INTERNAL "C++ support for ${FEATURE_NAME}")
endif(NOT DEFINED ${RESULT_VAR})
endmacro(CXX_CHECK_FEATURE)

View file

@ -0,0 +1,27 @@
#include <iostream>
class A {
public:
virtual int fn(int arg) {
return 10 * arg;
};
};
class B: public A {
public:
virtual int fn(long arg) __attribute__((override)) {
return 20 * arg;
};
};
int main()
{
A * a = new A();
A * b = new B();
int result = a->fn(2) - b->fn(1);
return 0;
}

View file

@ -0,0 +1,27 @@
#include <iostream>
class A {
public:
virtual int fn(int arg) {
return 10 * arg;
};
};
class B: public A {
public:
virtual int fn(long arg) __attribute__((override)) {
return 20 * arg;
};
};
int main()
{
A * a = new A();
A * b = new B();
int result = a->fn(2) - b->fn(1);
return 0;
}

View file

@ -0,0 +1,20 @@
#include <iostream>
int main()
{
auto i = 5;
auto f = 3.14159f;
auto d = 3.14159;
auto l = 3l;
bool checkFloats = (sizeof(f) < sizeof(d));
bool checkInts = (sizeof(i) == sizeof(int));
bool checkLongs = (sizeof(l) == sizeof(long));
std::cout
<< "Float sizes correct: " << checkFloats << std::endl
<< "Integer size correct: " << checkFloats << std::endl
<< "Long sizes correct: " << checkFloats << std::endl;
return (checkFloats && checkInts && checkLongs) ? 0 : 1;
}

View file

@ -0,0 +1,24 @@
#include <iostream>
#include <vector>
#include <string>
struct test {
int i;
int j;
double k;
std::string s;
};
int main()
{
test t { 1, 2, 4, "asdf" };
std::vector<int> v { 1, 2, 3, 4 };
return (
t.i == v[0]
&& t.j == v[1]
&& t.k > v[2]
&& t.s.size() == v[3]
)
? 0 : 1;
}

View file

@ -0,0 +1,25 @@
#include <iostream>
int main()
{
int ref = 10;
int pass = 2;
([&](int mul) {
ref *= mul;
})(pass);
bool checkRefNoref = (ref == 10 * pass);
int result = ([=](int mul) {
return ref * mul;
})(pass);
bool checkReturn = (result == 10 * pass * pass);
std::cout
<< "Capture by reference: " << checkRefNoref << std::endl
<< "Return a value: " << checkReturn << std::endl;
return (checkRefNoref && checkReturn) ? 0 : 1;
}

View file

@ -0,0 +1,5 @@
int main()
{
int i = nullptr;
return 1;
}

View file

@ -0,0 +1,5 @@
int main()
{
int * test = nullptr;
return test ? 1 : 0;
}

View file

@ -0,0 +1,27 @@
#include <iostream>
class A {
public:
virtual int fn(int arg) {
return 10 * arg;
};
};
class B: public A {
public:
virtual int fn(long arg) override {
return 20 * arg;
};
};
int main()
{
A * a = new A();
A * b = new B();
int result = a->fn(2) - b->fn(1);
return 0;
}

View file

@ -0,0 +1,27 @@
#include <iostream>
class A {
public:
virtual int fn(int arg) {
return 10 * arg;
};
};
class B: public A {
public:
virtual int fn(int arg) override {
return 20 * arg;
};
};
int main()
{
A * a = new A();
A * b = new B();
int result = a->fn(2) - b->fn(1);
return 0;
}

View file

@ -0,0 +1,21 @@
#include <memory>
#include <string>
#include <iostream>
#include <utility>
struct Question {
long answer;
std::string description;
};
int main()
{
std::unique_ptr < Question > node_original(new Question());
node_original->answer = 42;
node_original->description = "The Answer to the Ultimate Question of Life, the Universe, and Everything";
std::unique_ptr < Question > node_second(std::move(node_original));
return (!node_original && (node_second->answer == 42))?0:1;
}

View file

@ -0,0 +1,20 @@
#include <iostream>
template <typename T>
int addall(T value)
{
return value;
}
template <typename T, typename... Args>
int addall(T value, Args ... args)
{
return value + addall(args...);
}
int main()
{
int v1 = addall(1, 2, 3, 4, 5); // 15
int v2 = addall(1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4); // 40
return ((v1 == 15) && (v2 == 40)) ? 0 : 1;
}

35
kactivities/scripts/commit.sh Executable file
View file

@ -0,0 +1,35 @@
#!/bin/bash
# The script finds build directories for the current
# src directory and builds them
#
# For example, for the source dir:
# /some/path/kde/src/project/whatever
# It finds:
# /some/path/kde/build*/project/whatever
current_dir=`pwd`
all_root_dir=`pwd | sed 's#/src/.*##'`
src_root_dir=$all_root_dir/src
echo "src: $src_root_dir"
for build_root_dir in $all_root_dir/build*; do
echo "building in $build_root_dir"
cd $current_dir
current_dir_log=`OBJ_REPLACEMENT=s#$src_root_dir#$build_root_dir# makeobj`
if [ "$?" = "0" ]
then
echo "... success"
else
echo "... FAILED"
echo $current_dir_log
exit
fi
done
git commit

View file

@ -0,0 +1,3 @@
#!/bin/zsh
alias nepomukcmd="sopranocmd --socket `kde4-config --path socket`nepomuk-socket --model main --nrl"
for res in `nepomukcmd --foo query 'select ?r { ?r a kao:Activity . }'`; nepomukcmd rm $res

View file

@ -0,0 +1,4 @@
#!/bin/zsh
alias nepomukcmd="sopranocmd --socket `kde4-config --path socket`nepomuk-socket --model main --nrl"
for res in `nepomukcmd --foo query 'select ?r { ?r a kao:ResourceScoreCache . }'`; nepomukcmd rm $res
for res in `nepomukcmd --foo query 'select ?r { ?r a nuao:DesktopEvent . }'`; nepomukcmd rm $res

View file

@ -0,0 +1,25 @@
#!/bin/bash
if [ ! -f "scripts/run-krazy.sh" ];
then
echo "This script needs to be started from KAMD's root directory"
exit
fi
DIRS=$1
if [ ! -n "$1" ];
then
DIRS="lib service utils workspace"
fi
echo $DIRS
CURRENT_DIRECTORY=$PWD
for dir in $DIRS;
do
echo "Running krazy2 on $dir ..."
cd $CURRENT_DIRECTORY/src/$dir && krazy2all --exclude license > /tmp/$dir.krazy
done

View file

@ -0,0 +1,3 @@
#!/bin/bash
grep -n -I -r TODO src | sed 's/^\([^:]*:[^:]*\):[- \/#]*\(.*\)/\2\t(\1)/' | sed 's/^TODO: //' | sed 's/(TODO)//' | sed 's/BLOCKER/!!! BLOCKER !!!/' | sort | tee TODO

View file

@ -0,0 +1,129 @@
import os
import ycm_core
from clang_helpers import PrepareClangFlags
# Set this to the absolute path to the folder (NOT the file!) containing the
# compile_commands.json file to use that instead of 'flags'. See here for
# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
# Most projects will NOT need to set this to anything; you can just change the
# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
compilation_database_folder = ''
# These are the compilation flags that will be used in case there's no
# compilation database set.
flags = [
'-Wall',
'-Wextra',
'-Werror',
'-Wc++98-compat',
'-Wno-long-long',
'-Wno-variadic-macros',
'-DUSE_CLANG_COMPLETER',
'-std=c++11',
'-x',
'c++',
'-I/opt/kde/build/core/libs/kactivities/src',
'-I/opt/kde/src/core/libs/kactivities/src',
'-I/opt/kde/usr/kde/include',
'-I/opt/kde/usr/kde/include/KDE',
'-I/usr/include',
'-I/usr/include/qt4',
'-I/usr/include/qt4/Qt',
'-I/usr/include/qt4/Qt3Support',
'-I/usr/include/qt4/QtCore',
'-I/usr/include/qt4/QtDBus',
'-I/usr/include/qt4/QtDeclarative',
'-I/usr/include/qt4/QtDesigner',
'-I/usr/include/qt4/QtDesigner',
'-I/usr/include/qt4/QtGui',
'-I/usr/include/qt4/QtHelp',
'-I/usr/include/qt4/QtNetwork',
'-I/usr/include/qt4/QtOpenGL',
'-I/usr/include/qt4/QtScript',
'-I/usr/include/qt4/QtScriptTools',
'-I/usr/include/qt4/QtSql',
'-I/usr/include/qt4/QtSvg',
'-I/usr/include/qt4/QtTest',
'-I/usr/include/qt4/QtUiTools',
'-I/usr/include/qt4/QtWebKit',
'-I/usr/include/qt4/QtXml',
'-I/usr/include/qt4/QtXmlPatterns',
'-I/usr/share/qt4/mkspecs/default',
'-D_BSD_SOURCE',
'-DQT_NO_DEBUG_OUTPUT',
'-DQT_USE_FAST_CONCATENATION',
'-DQT_USE_FAST_OPERATOR_PLUS',
'-D_XOPEN_SOURCE=500',
'-D_BSD_SOURCE',
'-DQT_NO_STL',
'-DQT_NO_CAST_TO_ASCII',
'-D_REENTRANT',
'-DKDE_DEPRECATED_WARNINGS',
'-DKDE4_CMAKE_TOPLEVEL_DIR_LENGTH=22'
]
if compilation_database_folder:
database = ycm_core.CompilationDatabase( compilation_database_folder )
else:
database = None
def DirectoryOfThisScript():
return os.path.dirname( os.path.abspath( __file__ ) )
def MakeRelativePathsInFlagsAbsolute( flags, working_directory ):
if not working_directory:
return flags
new_flags = []
make_next_absolute = False
path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
for flag in flags:
new_flag = flag
if make_next_absolute:
make_next_absolute = False
if not flag.startswith( '/' ):
new_flag = os.path.join( working_directory, flag )
for path_flag in path_flags:
if flag == path_flag:
make_next_absolute = True
break
if flag.startswith( path_flag ):
path = flag[ len( path_flag ): ]
new_flag = path_flag + os.path.join( working_directory, path )
break
if new_flag:
new_flags.append( new_flag )
return new_flags
def FlagsForFile( filename ):
if database:
# Bear in mind that compilation_info.compiler_flags_ does NOT return a
# python list, but a "list-like" StringVec object
compilation_info = database.GetCompilationInfoForFile( filename )
final_flags = PrepareClangFlags(
MakeRelativePathsInFlagsAbsolute(
compilation_info.compiler_flags_,
compilation_info.compiler_working_dir_ ),
filename )
# NOTE: This is just for YouCompleteMe; it's highly likely that your project
# does NOT need to remove the stdlib flag. DO NOT USE THIS IN YOUR
# ycm_extra_conf IF YOU'RE NOT 100% YOU NEED IT.
try:
final_flags.remove( '-stdlib=libc++' )
except ValueError:
pass
else:
relative_to = DirectoryOfThisScript()
final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to )
return {
'flags': final_flags,
'do_cache': True
}

View file

@ -0,0 +1,76 @@
set (CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH})
# Installation directory for ontologies. Needed here because used in both ontology/ and lib/ sub
# directories.
set (KACTIVITIES_ONTOLOGIES_DIR ${CMAKE_INSTALL_PREFIX}/share/ontology/kde)
add_definitions (-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS)
# Testing for C++0x/C++11 features
include (CheckCxxFeatures)
cxx_check_feature ("c++11" "auto" "N2546" HAVE_CXX11_AUTO "${ADDITIONAL_DEFINITIONS}")
cxx_check_feature ("c++11" "nullptr" "N2431" HAVE_CXX11_NULLPTR "${ADDITIONAL_DEFINITIONS}")
cxx_check_feature ("c++11" "lambda" "N2927" HAVE_CXX11_LAMBDA "${ADDITIONAL_DEFINITIONS}")
cxx_check_feature ("c++11" "override" "N3206" HAVE_CXX11_OVERRIDE "${ADDITIONAL_DEFINITIONS}")
cxx_check_feature ("c++11" "unique_ptr" "none" HAVE_CXX11_UNIQUE_PTR "${ADDITIONAL_DEFINITIONS}")
cxx_check_feature ("c++11" "variadic-templates" "N2242" HAVE_CXX11_VARIADIC_TEMPLATES "${ADDITIONAL_DEFINITIONS}")
cxx_check_feature ("c++11" "initializer-lists" "N2672" HAVE_CXX11_INITIALIZER_LISTS "${ADDITIONAL_DEFINITIONS}")
add_subdirectory (lib)
# config file
set (KAMD_DATA_DIR "${DATA_INSTALL_DIR}/activitymanager/")
configure_file (config-features.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-features.h)
# main part
option (KACTIVITIES_LIBRARY_ONLY "If true, compiles only the KActivities library, without the service and other modules." OFF)
if (NOT KACTIVITIES_LIBRARY_ONLY)
string (COMPARE EQUAL "${CXX_FEATURES_UNSUPPORTED}" "" CXX_COMPILER_IS_MODERN)
if (NOT HAVE_CXX11_AUTO OR NOT HAVE_CXX11_LAMBDA OR NOT HAVE_CXX11_UNIQUE_PTR OR NOT HAVE_CXX11_VARIADIC_TEMPLATES OR NOT HAVE_CXX11_INITIALIZER_LISTS)
macro_log_feature (FALSE
"C++11 enabled compiler"
"GCC >=4.5 or Clang 3.1"
"http://www.open-std.org/jtc1/sc22/wg21/" FALSE ""
"REQUIRED: You need a more modern compiler in order to build the Activity Manager daemon"
)
else ()
if (CXX_COMPILER_IS_MODERN)
macro_log_feature (
CXX_COMPILER_IS_MODERN
"C++11 enabled compiler"
"Your compiler is state-of-the-art"
"http://www.open-std.org/jtc1/sc22/wg21/" FALSE ""
"Your compiler doesn't support the following features: ${CXX_FEATURES_UNSUPPORTED} but
the list of the supported ones is sufficient for the build: ${CXX_FEATURES_SUPPORTED}"
)
else ()
macro_log_feature (
CXX_COMPILER_IS_MODERN
"C++11 enabled compiler"
"Having to use the latest versions of GCC and Clang would be awesome"
"http://www.open-std.org/jtc1/sc22/wg21/" FALSE ""
"Your compiler doesn't support the following features: ${CXX_FEATURES_UNSUPPORTED} but
the list of the supported ones is sufficient for the build: ${CXX_FEATURES_SUPPORTED}"
)
endif ()
add_subdirectory (service)
# No point in having workspace addons without the service
add_subdirectory (workspace)
endif ()
endif()

View file

@ -0,0 +1,76 @@
/*
* Copyright (C) 2010, 2011, 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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 "org.kde.ActivityManager.Activities.h"
#include <QMetaType>
#include <QDBusMetaType>
namespace details {
class ActivityInfoStaticInit {
public:
ActivityInfoStaticInit()
{
qDBusRegisterMetaType < ActivityInfo > ();
qDBusRegisterMetaType < ActivityInfoList > ();
}
static ActivityInfoStaticInit _instance;
};
ActivityInfoStaticInit ActivityInfoStaticInit::_instance;
} // namespace details
QDBusArgument & operator << (QDBusArgument & arg, const ActivityInfo r)
{
arg.beginStructure();
arg << r.id;
arg << r.name;
arg << r.icon;
arg << r.state;
arg.endStructure();
return arg;
}
const QDBusArgument & operator >> (const QDBusArgument & arg, ActivityInfo & r)
{
arg.beginStructure();
arg >> r.id;
arg >> r.name;
arg >> r.icon;
arg >> r.state;
arg.endStructure();
return arg;
}
QDebug operator << (QDebug dbg, const ActivityInfo & r)
{
dbg << "ActivityInfo(" << r.id << r.name << ")";
return dbg.space();
}

View file

@ -0,0 +1,45 @@
/*
* Copyright (C) 2010, 2011, 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef KAMD_ACTIVITIES_DBUS_H
#define KAMD_ACTIVITIES_DBUS_H
#include <QString>
#include <QList>
#include <QDBusArgument>
#include <QDebug>
struct ActivityInfo {
QString id;
QString name;
QString icon;
int state;
};
typedef QList<ActivityInfo> ActivityInfoList;
Q_DECLARE_METATYPE(ActivityInfo)
Q_DECLARE_METATYPE(ActivityInfoList)
QDBusArgument & operator << (QDBusArgument & arg, const ActivityInfo);
const QDBusArgument & operator >> (const QDBusArgument & arg, ActivityInfo & rec);
QDebug operator << (QDebug dbg, const ActivityInfo & r);
#endif // KAMD_ACTIVITIES_DBUS_H

View file

@ -0,0 +1,102 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.kde.ActivityManager.Activities">
<method name="CurrentActivity">
<arg type="s" direction="out"/>
</method>
<method name="SetCurrentActivity">
<arg type="b" direction="out"/>
<arg name="activity" type="s" direction="in"/>
</method>
<method name="AddActivity">
<arg type="s" direction="out"/>
<arg name="name" type="s" direction="in"/>
</method>
<method name="StartActivity">
<arg name="activity" type="s" direction="in"/>
</method>
<method name="StopActivity">
<arg name="activity" type="s" direction="in"/>
</method>
<method name="ActivityState">
<arg type="i" direction="out"/>
<arg name="activity" type="s" direction="in"/>
</method>
<method name="RemoveActivity">
<arg name="activity" type="s" direction="in"/>
</method>
<method name="ListActivities">
<arg type="as" direction="out"/>
</method>
<method name="ListActivities">
<arg type="as" direction="out"/>
<arg name="state" type="i" direction="in"/>
</method>
<method name="ListActivitiesWithInformation">
<arg type="a(sssd)" direction="out"/>
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="ActivityInfoList" />
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="ActivityInfoList" />
</method>
<method name="ActivityInformation">
<arg type="(sssd)" direction="out"/>
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="ActivityInfo" />
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="ActivityInfo" />
<arg name="activity" type="s" direction="in"/>
</method>
<method name="ActivityName">
<arg type="s" direction="out"/>
<arg name="activity" type="s" direction="in"/>
</method>
<method name="SetActivityName">
<arg name="activity" type="s" direction="in"/>
<arg name="name" type="s" direction="in"/>
</method>
<method name="ActivityIcon">
<arg type="s" direction="out"/>
<arg name="activity" type="s" direction="in"/>
</method>
<method name="SetActivityIcon">
<arg name="activity" type="s" direction="in"/>
<arg name="icon" type="s" direction="in"/>
</method>
<signal name="CurrentActivityChanged">
<arg name="activity" type="s" direction="out"/>
</signal>
<signal name="ActivityAdded">
<arg name="activity" type="s" direction="out"/>
</signal>
<signal name="ActivityStarted">
<arg name="activity" type="s" direction="out"/>
</signal>
<signal name="ActivityStopped">
<arg name="activity" type="s" direction="out"/>
</signal>
<signal name="ActivityRemoved">
<arg name="activity" type="s" direction="out"/>
</signal>
<signal name="ActivityChanged">
<arg name="activity" type="s" direction="out"/>
</signal>
<signal name="ActivityNameChanged">
<arg name="activity" type="s" direction="out"/>
<arg name="name" type="s" direction="out"/>
</signal>
<signal name="ActivityIconChanged">
<arg name="activity" type="s" direction="out"/>
<arg name="icon" type="s" direction="out"/>
</signal>
<signal name="ActivityStateChanged">
<arg name="activity" type="s" direction="out"/>
<arg name="state" type="i" direction="out"/>
</signal>
</interface>
</node>

View file

@ -0,0 +1,21 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.kde.ActivityManager.Features">
<method name="IsFeatureOperational">
<arg type="b" direction="out"/>
<arg name="feature" type="s" direction="in"/>
</method>
<method name="IsFeatureEnabled">
<arg type="b" direction="out"/>
<arg name="feature" type="s" direction="in"/>
</method>
<method name="SetFeatureEnabled">
<arg name="feature" type="s" direction="in"/>
<arg name="value" type="b" direction="in"/>
</method>
<method name="ListFeatures">
<arg type="as" direction="out"/>
<arg name="module" type="s" direction="in"/>
</method>
</interface>
</node>

View file

@ -0,0 +1,24 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.kde.ActivityManager.Resources">
<method name="RegisterResourceEvent">
<arg name="application" type="s" direction="in"/>
<arg name="windowId" type="u" direction="in"/>
<arg name="uri" type="s" direction="in"/>
<arg name="event" type="u" direction="in"/>
<arg name="reason" type="u" direction="in"/>
</method>
<method name="RegisterResourceMimeType">
<arg name="uri" type="s" direction="in"/>
<arg name="mimetype" type="s" direction="in"/>
</method>
<method name="RegisterResourceTitle">
<arg name="uri" type="s" direction="in"/>
<arg name="title" type="s" direction="in"/>
</method>
</interface>
</node>

View file

@ -0,0 +1,46 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.kde.ActivityManager.ResourcesLinking">
<method name="LinkResourceToActivity">
<arg name="uri" type="s" direction="in"/>
<arg name="activity" type="s" direction="in"/>
</method>
<method name="LinkResourceToActivity">
<arg name="uri" type="s" direction="in"/>
</method>
<method name="UnlinkResourceFromActivity">
<arg name="uri" type="s" direction="in"/>
<arg name="activity" type="s" direction="in"/>
</method>
<method name="UnlinkResourceFromActivity">
<arg name="uri" type="s" direction="in"/>
</method>
<method name="IsResourceLinkedToActivity">
<arg name="uri" type="s" direction="in"/>
<arg name="activity" type="s" direction="in"/>
<arg type="b" direction="out"/>
</method>
<method name="IsResourceLinkedToActivity">
<arg name="uri" type="s" direction="in"/>
<arg type="b" direction="out"/>
</method>
<!-- KDE_DEPRECATED -->
<method name="ResourcesLinkedToActivity">
<arg type="as" direction="out"/>
<arg name="activity" type="s" direction="in"/>
</method>
<!-- KDE_DEPRECATED -->
<method name="ResourcesLinkedToActivity">
<arg type="as" direction="out"/>
</method>
</interface>
</node>

View file

@ -0,0 +1,14 @@
#ifndef CONFIG_FEATURES_H_
#define CONFIG_FEATURES_H_
#cmakedefine01 HAVE_NEPOMUK
#cmakedefine KAMD_DATA_DIR "@KAMD_DATA_DIR@"
#cmakedefine01 HAVE_CXX11_AUTO
#cmakedefine01 HAVE_CXX11_NULLPTR
#cmakedefine01 HAVE_CXX11_LAMBDA
#cmakedefine01 HAVE_CXX11_OVERRIDE
#cmakedefine01 HAVE_CXX_OVERRIDE_ATTR
#endif

View file

@ -0,0 +1,3 @@
add_subdirectory (core)

View file

@ -0,0 +1,183 @@
project (kactivities)
find_package (Qt4 REQUIRED)
find_package (KDE4 REQUIRED)
include (KDE4Defaults)
include (MacroLibrary)
include (MacroOptionalAddSubdirectory)
include (FindPackageHandleStandardArgs)
# =======================================================
# Information to update before to release this library.
# Library version history:
# API ABI
# 0.1.0 => 0.1.0
# 0.1.1 => 0.1.1
# 0.2.0 => 0.2.0
# 6.1.0 => 6.1.0
# 6.2.0 => 6.2.0
# Library API version
set (KACTIVITIES_LIB_MAJOR_VERSION "6")
set (KACTIVITIES_LIB_MINOR_VERSION "2")
set (KACTIVITIES_LIB_PATCH_VERSION "0")
# Suffix to add at end of version string. Usual values are:
# "-git" : alpha code unstable from git. Do not use in production
# "-beta1" : beta1 release.
# "-beta2" : beta2 release.
# "-beta3" : beta3 release.
# "-rc" : release candidate.
# "" : final relase. Can be used in production.
set (KACTIVITIES_LIB_SUFFIX_VERSION "")
# Library ABI version used by linker.
# For details : http://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info
set (KACTIVITIES_LIB_SO_CUR_VERSION "6")
set (KACTIVITIES_LIB_SO_REV_VERSION "2")
set (KACTIVITIES_LIB_SO_AGE_VERSION "0")
# =======================================================
# Set env. variables accordinly.
set (KACTIVITIES_INCLUDE_DIR
"${CMAKE_CURRENT_SOURCE_DIR}/.."
"${CMAKE_CURRENT_SOURCE_DIR}/"
CACHE STRING
"Location of libkactivities headers" FORCE)
set (KACTIVITIES_LIBS
"kactivities"
CACHE STRING
"Location of libkactivities binary" FORCE)
set (KACTIVITIES_LIB_VERSION_STRING "${KACTIVITIES_LIB_MAJOR_VERSION}.${KACTIVITIES_LIB_MINOR_VERSION}.${KACTIVITIES_LIB_PATCH_VERSION}${KACTIVITIES_LIB_SUFFIX_VERSION}")
set (KACTIVITIES_LIB_VERSION_ID "0x0${KACTIVITIES_LIB_MAJOR_VERSION}0${KACTIVITIES_LIB_MINOR_VERSION}0${KACTIVITIES_LIB_PATCH_VERSION}")
set (KACTIVITIES_LIB_SO_VERSION_STRING "${KACTIVITIES_LIB_SO_CUR_VERSION}.${KACTIVITIES_LIB_SO_REV_VERSION}.${KACTIVITIES_LIB_SO_AGE_VERSION}")
add_definitions (${QT_DEFINITIONS} ${QT_QTDBUS_DEFINITIONS} ${KDE4_DEFINITIONS})
include_directories (
${CMAKE_SOURCE_DIR}/kactivities/src
${CMAKE_BINARY_DIR}/src
${QDBUS_INCLUDE_DIRS}
${KDE4_INCLUDES}
${KDE4_KIO_INCLUDES}
)
set (
kactivities_LIB_SRCS
${CMAKE_SOURCE_DIR}/kactivities/src/common/dbus/org.kde.ActivityManager.Activities.cpp
consumer.cpp
controller.cpp
info.cpp
manager_p.cpp
resourceinstance.cpp
version.cpp
)
set_source_files_properties (
${CMAKE_SOURCE_DIR}/kactivities/src/common/dbus/org.kde.ActivityManager.Activities.xml
PROPERTIES
INCLUDE ${CMAKE_SOURCE_DIR}/kactivities/src/common/dbus/org.kde.ActivityManager.Activities.h
)
qt4_add_dbus_interface (
kactivities_LIB_SRCS
${CMAKE_SOURCE_DIR}/kactivities/src/common/dbus/org.kde.ActivityManager.Activities.xml
activities_interface
)
qt4_add_dbus_interface (
kactivities_LIB_SRCS
${CMAKE_SOURCE_DIR}/kactivities/src/common/dbus/org.kde.ActivityManager.Resources.xml
resources_interface
)
qt4_add_dbus_interface (
kactivities_LIB_SRCS
${CMAKE_SOURCE_DIR}/kactivities/src/common/dbus/org.kde.ActivityManager.Features.xml
features_interface
)
qt4_add_dbus_interface (
kactivities_LIB_SRCS
${CMAKE_SOURCE_DIR}/kactivities/src/common/dbus/org.kde.ActivityManager.ResourcesLinking.xml
resources_linking_interface
)
kde4_add_library (
kactivities SHARED
${kactivities_LIB_SRCS}
)
set_target_properties (
kactivities
PROPERTIES
VERSION ${KACTIVITIES_LIB_SO_VERSION_STRING}
SOVERSION ${KACTIVITIES_LIB_SO_CUR_VERSION}
)
target_link_libraries (
kactivities
${KDE4_KDECORE_LIBS}
)
## install
set (
kactivities_LIB_HEADERS
consumer.h
controller.h
info.h
resourceinstance.h
version.h
kactivities_export.h
)
set (
kactivities_LIB_PRETTY_HEADERS
includes/KActivities/Consumer
includes/KActivities/Controller
includes/KActivities/Info
includes/KActivities/ResourceInstance
includes/KActivities/Version
)
install (
FILES ${kactivities_LIB_HEADERS}
DESTINATION ${INCLUDE_INSTALL_DIR}/kactivities
COMPONENT Devel
)
install (
FILES ${kactivities_LIB_PRETTY_HEADERS}
DESTINATION ${INCLUDE_INSTALL_DIR}/KDE/KActivities
COMPONENT Devel
)
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/libkactivities.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libkactivities.pc)
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/libkactivities.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig )
configure_file (KActivitiesConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/KActivitiesConfig.cmake @ONLY)
macro_write_basic_cmake_version_file (
${CMAKE_CURRENT_BINARY_DIR}/KActivitiesConfigVersion.cmake
${KACTIVITIES_LIB_MAJOR_VERSION}
${KACTIVITIES_LIB_MINOR_VERSION}
${KACTIVITIES_LIB_PATCH_VERSION}
)
install (
FILES
${CMAKE_CURRENT_BINARY_DIR}/KActivitiesConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/KActivitiesConfigVersion.cmake
KActivitiesLibraryTargets.cmake
DESTINATION
${LIB_INSTALL_DIR}/cmake/KActivities
)

View file

@ -0,0 +1,24 @@
get_filename_component(myDir ${CMAKE_CURRENT_LIST_FILE} PATH) # get the directory where I myself am
get_filename_component(rootDir ${myDir}/@relInstallDir@ ABSOLUTE) # get the chosen install prefix
# set the version of myself
set(KACTIVITIES_VERSION_MAJOR @KACTIVITIES_LIB_MAJOR_VERSION@)
set(KACTIVITIES_VERSION_MINOR @KACTIVITIES_LIB_MINOR_VERSION@)
set(KACTIVITIES_VERSION_PATCH @KACTIVITIES_LIB_PATCH_VERSION@)
set(KACTIVITIES_VERSION @KACTIVITIES_LIB_MAJOR_VERSION@.@KACTIVITIES_LIB_MINOR_VERSION@.@KACTIVITIES_LIB_PATCH_VERSION@)
set(KACTIVITIES_VERSION_STRING "@KACTIVITIES_LIB_MAJOR_VERSION@.@KACTIVITIES_LIB_MINOR_VERSION@.@KACTIVITIES_LIB_PATCH_VERSION@")
# what is my include directory
# we have _DIRS for compat with existing usage
SET(KACTIVITIES_INCLUDE_DIRS "@INCLUDE_INSTALL_DIR@" "@INCLUDE_INSTALL_DIR@/KDE" CACHE PATH "Include path for the KActivities library")
set(KACTIVITIES_INCLUDES "${rootDir}/@INCLUDE_INSTALL_DIR@" "@INCLUDE_INSTALL_DIR@/KDE")
set(KACTIVITIES_ONTOLOGIES_DIR "@KACTIVITIES_ONTOLOGIES_DIR@")
# import the exported targets
include(${myDir}/KActivitiesLibraryTargets.cmake)
# set the expected library variable
# XXX: only KACTIVITIES_LIBRARIES should be used according to CMake's conventions,
# KACTIVITIES_LIBRARY is kept for compatibility with all the places using it.
set(KACTIVITIES_LIBRARY kactivities)
set(KACTIVITIES_LIBRARIES kactivities)

View file

@ -0,0 +1,210 @@
/*
* Copyright (c) 2010, 2011, 2012 Ivan Cukic <ivan.cukic(at)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 "consumer.h"
#include "consumer_p.h"
#include "manager_p.h"
#include <QDebug>
namespace KActivities {
static QString nulluuid = "00000000-0000-0000-0000-000000000000";
ConsumerPrivate * ConsumerPrivate::s_instance = 0;
ConsumerPrivate * ConsumerPrivate::self(QObject * consumer)
{
if (!s_instance) {
s_instance = new ConsumerPrivate();
}
s_instance->consumers << consumer;
return s_instance;
}
void ConsumerPrivate::free(QObject * consumer)
{
consumers.remove(consumer);
if (consumers.isEmpty()) {
s_instance = 0;
deleteLater();
}
}
KAMD_RETRIEVE_REMOTE_VALUE_HANDLER(QString, ConsumerPrivate, currentActivity, nulluuid)
KAMD_RETRIEVE_REMOTE_VALUE_HANDLER(QStringList, ConsumerPrivate, listActivities, QStringList())
KAMD_RETRIEVE_REMOTE_VALUE_HANDLER(QStringList, ConsumerPrivate, runningActivities, QStringList())
ConsumerPrivate::ConsumerPrivate()
: currentActivityCallWatcher(0),
listActivitiesCallWatcher(0),
runningActivitiesCallWatcher(0)
{
connect(Manager::activities(), SIGNAL(CurrentActivityChanged(const QString &)),
this, SLOT(setCurrentActivity(const QString &)));
connect(Manager::activities(), SIGNAL(ActivityAdded(QString)),
this, SLOT(addActivity(QString)));
connect(Manager::activities(), SIGNAL(ActivityRemoved(QString)),
this, SLOT(removeActivity(QString)));
connect(Manager::activities(), SIGNAL(ActivityStateChanged(QString,int)),
this, SLOT(setActivityState(QString, int)));
connect(Manager::self(), SIGNAL(servicePresenceChanged(bool)),
this, SLOT(setServicePresent(bool)));
qDebug() << "We are checking whether the service is present" <<
Manager::isServicePresent();
if (Manager::isServicePresent()) {
initializeCachedData();
}
}
void ConsumerPrivate::setServicePresent(bool present)
{
emit serviceStatusChanged(
present ? Consumer::Running : Consumer::NotRunning
);
if (present) {
initializeCachedData();
}
}
void ConsumerPrivate::initializeCachedData()
{
KAMD_RETRIEVE_REMOTE_VALUE(currentActivity, CurrentActivity(), this);
KAMD_RETRIEVE_REMOTE_VALUE(listActivities, ListActivities(), this);
KAMD_RETRIEVE_REMOTE_VALUE(runningActivities, ListActivities(Info::Running), this);
}
void ConsumerPrivate::setCurrentActivity(const QString & activity)
{
qDebug() << "current activity is" << activity;
currentActivity = activity;
emit currentActivityChanged(activity);
}
void ConsumerPrivate::addActivity(const QString & activity)
{
qDebug() << "new activity added" << activity;
if (!listActivities.contains(activity)) {
listActivities << activity;
runningActivities << activity;
}
emit activityAdded(activity);
}
void ConsumerPrivate::removeActivity(const QString & activity)
{
qDebug() << "activity removed added" << activity;
listActivities.removeAll(activity);
runningActivities.removeAll(activity);
emit activityRemoved(activity);
}
void ConsumerPrivate::setActivityState(const QString & activity, int state)
{
if (!listActivities.contains(activity)) {
qWarning("trying to alter state of unknown activity!!");
return; // denied
}
if (state == Info::Running) {
if (!runningActivities.contains(activity))
runningActivities << activity;
} else {
runningActivities.removeAll(activity);
}
}
Consumer::Consumer(QObject * parent)
: QObject(parent), d(ConsumerPrivate::self(this))
{
connect(d, SIGNAL(serviceStatusChanged(KActivities::Consumer::ServiceStatus)),
this, SIGNAL(serviceStatusChanged(KActivities::Consumer::ServiceStatus)));
connect(d, SIGNAL(currentActivityChanged(QString)),
this, SIGNAL(currentActivityChanged(QString)));
connect(d, SIGNAL(activityAdded(QString)),
this, SIGNAL(activityAdded(QString)));
connect(d, SIGNAL(activityRemoved(QString)),
this, SIGNAL(activityRemoved(QString)));
}
Consumer::~Consumer()
{
d->free(this);
}
KAMD_REMOTE_VALUE_GETTER(QString, Consumer, currentActivity, nulluuid)
KAMD_REMOTE_VALUE_GETTER(QStringList, Consumer, listActivities, QStringList(nulluuid))
QStringList Consumer::listActivities(Info::State state) const
{
if (state == Info::Running) {
if (!Manager::isServicePresent()) return QStringList(nulluuid);
waitForCallFinished(d->runningActivitiesCallWatcher, &d->runningActivitiesMutex);
qDebug() << "Returning the running activities" << d->runningActivities;
return d->runningActivities;
}
KAMD_RETRIEVE_REMOTE_VALUE_SYNC(
QStringList, activities, ListActivities(state), QStringList(nulluuid)
);
}
void Consumer::linkResourceToActivity(const QUrl & uri, const QString & activity)
{
if (Manager::isServicePresent())
Manager::resourcesLinking()->LinkResourceToActivity(uri.toString(), activity);
}
void Consumer::unlinkResourceFromActivity(const QUrl & uri, const QString & activity)
{
if (Manager::isServicePresent())
Manager::resourcesLinking()->UnlinkResourceFromActivity(uri.toString(), activity);
}
bool Consumer::isResourceLinkedToActivity(const QUrl & uri, const QString & activity) const
{
KAMD_RETRIEVE_REMOTE_VALUE_SYNC(
bool, resourcesLinking, IsResourceLinkedToActivity(uri.toString(), activity), false
);
}
Consumer::ServiceStatus Consumer::serviceStatus()
{
if (!Manager::isServicePresent()) {
return NotRunning;
}
return Running;
}
} // namespace KActivities

View file

@ -0,0 +1,198 @@
/*
* Copyright (c) 2010, 2011, 2012 Ivan Cukic <ivan.cukic(at)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 ACTIVITIES_CONSUMER_H
#define ACTIVITIES_CONSUMER_H
#include <QObject>
#include <QWidget>
#include <QString>
#include <QStringList>
#include "info.h"
#include <kurl.h>
#include "kactivities_export.h"
namespace KActivities {
class ConsumerPrivate;
/**
* Contextual information can be, from the user's point of view, divided
* into three aspects - "who am I?", "where am I?" (what are my surroundings?)
* and "what am I doing?".
*
* Activities deal with the last one - "what am I doing?". The current activity
* refers to what the user is doing at the moment, while the other activities represent
* things that he/she was doing before, and probably will be doing again.
*
* Activity is an abstract concept whose meaning can differ from one user to another.
* Typical examples of activities are "developing a KDE project", "studying the
* 19th century art", "composing music", "lazing on a Sunday afternoon" etc.
*
* Every activity can have applications, documents, or other types of resources
* assigned to it.
*
* Consumer provides an entry-level API for supporting activities in an
* application - to react to the changes to the current activity as well as
* registering the resources with its windows.
*
* Resource can be anything that is identifiable by an URI (for example,
* a local file or a web page)
*
* The API of the class is synchronous, but the most used properties
* are pre-fetched and cached. This means that, in order to get the least
* amount of d-bus related locks, you should declare long-lived instances
* of this class.
*
* For example, this is wrong (works, but blocks):
* @code
* void someMethod() {
* Consumer c;
* doSomethingWith(c.listActivities());
* }
* @endcode
*
* The methods that are cached are marked as 'pre-fetched and cached'.
* Methods that will block until the response from the service is returned
* are marked as 'blocking'.
*
* @since 4.5
*/
class KACTIVITIES_EXPORT Consumer: public QObject {
Q_OBJECT
Q_PROPERTY(QString currentActivity READ currentActivity NOTIFY currentActivityChanged)
Q_PROPERTY(QStringList activities READ listActivities)
public:
/**
* Different states of the activities service
*/
enum ServiceStatus {
NotRunning, ///< Service is not running
BareFunctionality, ///< @deprecated Service is running without a sane backend.
FullFunctionality, ///< @deprecated Service is running, and a backend is available
Running
};
explicit Consumer(QObject * parent = 0 /*nullptr*/);
~Consumer();
/**
* @returns the id of the current activity
* @note Activity ID is a UUID-formatted string. If the activities
* service is not running, or there was some error, the
* method will return null UUID. The ID can also be an empty
* string in the case there is no current activity.
* @note This method is <b>pre-fetched and cached</b>
*/
QString currentActivity() const;
/**
* @returns the list of activities filtered by state
* @param state state of the activity
* @note If the activities service is not running, only a null
* activity will be returned.
* @note This method is <b>pre-fetched and cached only for the Info::Running state</b>
*/
QStringList listActivities(Info::State state) const;
/**
* @returns the list of all existing activities
* @note If the activities service is not running, only a null
* activity will be returned.
* @note This method is <b>pre-fetched and cached</b>
*/
QStringList listActivities() const;
/**
* @returns status of the activities service
*/
static ServiceStatus serviceStatus();
/**
* Links a resource to the activity
* @param uri URI of the resource
* @param activity id of the activity to link to. If empty, the
* resource is linked to the current activity.
* @note This method is <b>asynchronous</b>
* @deprecated use Info::linkResource
*/
KDE_DEPRECATED
void linkResourceToActivity(const QUrl & uri, const QString & activity = QString());
/**
* Unlinks a resource from the activity
* @param uri URI of the resource
* @param activity id of the activity to unlink from. If empty, the
* resource is unlinked from the current activity.
* @note This method is <b>asynchronous</b>
* @deprecated use Info::unlinkResource
*/
KDE_DEPRECATED
void unlinkResourceFromActivity(const QUrl & uri, const QString & activity = QString());
/**
* @returns whether the resource is linket to the specified activity
* @param uri URI of the resource
* @param activity id of the activity. If empty, the current activity is used.
* @note This method is <b>blocking</b>
* @deprecated use Info::isResourceLinked
*/
KDE_DEPRECATED
bool isResourceLinkedToActivity(const QUrl & uri, const QString & activity = QString()) const;
Q_SIGNALS:
/**
* This signal is emitted when the global
* activity is changed
* @param id id of the new current activity
*/
void currentActivityChanged(const QString & id);
/**
* This signal is emitted when the activity service
* goes online or offline
* @param status new status of the service
*/
void serviceStatusChanged(KActivities::Consumer::ServiceStatus status);
/**
* This signal is emitted when a new activity is added
* @param id id of the new activity
*/
void activityAdded(const QString & id);
/**
* This signal is emitted when the activity
* is removed
* @param id id of the removed activity
*/
void activityRemoved(const QString & id);
private:
ConsumerPrivate * const d;
};
} // namespace KActivities
#endif // ACTIVITIES_CONSUMER_H

View file

@ -0,0 +1,74 @@
/*
* Copyright (c) 2010, 2011, 2012 Ivan Cukic <ivan.cukic(at)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 ACTIVITIES_CONSUMER_P_H
#define ACTIVITIES_CONSUMER_P_H
#include "consumer.h"
#include <QSet>
#include "utils_p.h"
class QDBusPendingCallWatcher;
namespace KActivities {
class ConsumerPrivate: public QObject {
Q_OBJECT
public:
static ConsumerPrivate * self(QObject * consumer);
void free(QObject * consumer);
public Q_SLOTS:
void setServicePresent(bool present);
void initializeCachedData();
void currentActivityCallFinished(QDBusPendingCallWatcher * call);
void listActivitiesCallFinished(QDBusPendingCallWatcher * call);
void runningActivitiesCallFinished(QDBusPendingCallWatcher * call);
void setCurrentActivity(const QString & activity);
void addActivity(const QString & activity);
void removeActivity(const QString & activity);
void setActivityState(const QString & activity, int state);
Q_SIGNALS:
void serviceStatusChanged(KActivities::Consumer::ServiceStatus status);
void currentActivityChanged(const QString & id);
void activityAdded(const QString & id);
void activityRemoved(const QString & id);
public:
KAMD_REMOTE_VALUE_CUSTOM_HANDLER(QString, currentActivity);
KAMD_REMOTE_VALUE_CUSTOM_HANDLER(QStringList, listActivities);
KAMD_REMOTE_VALUE_CUSTOM_HANDLER(QStringList, runningActivities);
QSet <QObject *> consumers;
private:
ConsumerPrivate();
static ConsumerPrivate * s_instance;
};
} // namespace KActivities
#endif // ACTIVITIES_CONSUMER_P_H

View file

@ -0,0 +1,93 @@
/*
* Copyright (c) 2010, 2011, 2012 Ivan Cukic <ivan.cukic(at)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 "controller.h"
#include "consumer_p.h"
#include "manager_p.h"
#include <QObject>
#include <QDebug>
namespace KActivities {
class ControllerPrivate: public QObject {
public:
ControllerPrivate(Controller * parent)
: q(parent)
{
}
private:
Controller * const q;
};
Controller::Controller(QObject * parent)
: Consumer(parent), d(new ControllerPrivate(this))
{
}
Controller::~Controller()
{
delete d;
}
void Controller::setActivityName(const QString & id, const QString & name)
{
Manager::activities()->SetActivityName(id, name);
}
void Controller::setActivityIcon(const QString & id, const QString & icon)
{
Manager::activities()->SetActivityIcon(id, icon);
}
void Controller::setActivityEncrypted(const QString & id, bool encrypted)
{
Q_UNUSED(id)
Q_UNUSED(encrypted)
// Manager::activities()->SetActivityEncrypted(id, encrypted);
}
bool Controller::setCurrentActivity(const QString & id)
{
return Manager::activities()->SetCurrentActivity(id);
}
QString Controller::addActivity(const QString & name)
{
return Manager::activities()->AddActivity(name);
}
void Controller::removeActivity(const QString & id)
{
Manager::activities()->RemoveActivity(id);
}
void Controller::stopActivity(const QString & id)
{
Manager::activities()->StopActivity(id);
}
void Controller::startActivity(const QString & id)
{
Manager::activities()->StartActivity(id);
}
} // namespace KActivities
#include "controller.moc"

View file

@ -0,0 +1,116 @@
/*
* Copyright (c) 2010, 2011, 2012 Ivan Cukic <ivan.cukic(at)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 ACTIVITIES_CONTROLLER_H
#define ACTIVITIES_CONTROLLER_H
#include <QObject>
#include <QWidget>
#include <QString>
#include <QStringList>
#include "consumer.h"
#include <kurl.h>
#include "kactivities_export.h"
namespace KActivities {
class ControllerPrivate;
/**
* This class provides methods for controlling and managing
* the activities.
*
* @see Consumer for info about activities
*
* @since 4.5
*/
class KACTIVITIES_EXPORT Controller: public Consumer
{
Q_OBJECT
Q_PROPERTY(QString currentActivity READ currentActivity WRITE setCurrentActivity)
public:
explicit Controller(QObject * parent = 0 /*nullptr*/);
~Controller();
/**
* Sets the name of the specified activity
* @param id id of the activity
* @param name name to be set
*/
void setActivityName(const QString & id, const QString & name);
/**
* Sets the icon of the specified activity
* @param id id of the activity
* @param icon icon to be set - freedesktop.org name or file path
*/
void setActivityIcon(const QString & id, const QString & icon);
/**
* Sets whether the activity should be encrypted
* @param id id of the activity
* @param encrypted should the activity be encrypted
*/
KDE_DEPRECATED
void setActivityEncrypted(const QString & id, bool encrypted);
/**
* Sets the current activity
* @param id id of the activity to make current
* @returns true if successful
*/
bool setCurrentActivity(const QString & id);
/**
* Adds a new activity
* @param name name of the activity
* @returns id of the newly created activity
*/
QString addActivity(const QString & name);
/**
* Removes the specified activity
* @param id id of the activity to delete
*/
void removeActivity(const QString & id);
/**
* Stops the activity
* @param id id of the activity to stop
*/
void stopActivity(const QString & id);
/**
* Starts the activity
* @param id id of the activity to start
*/
void startActivity(const QString & id);
private:
ControllerPrivate * const d;
};
} // namespace KActivities
#endif // ACTIVITIES_CONTROLLER_H

View file

@ -0,0 +1 @@
#include "../../kactivities/consumer.h"

View file

@ -0,0 +1 @@
#include "../../kactivities/controller.h"

View file

@ -0,0 +1 @@
#include "../../kactivities/info.h"

View file

@ -0,0 +1 @@
#include "../../kactivities/resourceinstance.h"

View file

@ -0,0 +1 @@
#include "../../kactivities/version.h"

View file

@ -0,0 +1,257 @@
/*
* Copyright (c) 2010, 2011, 2012 Ivan Cukic <ivan.cukic(at)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 "info.h"
#include "info_p.h"
#include "manager_p.h"
#include <QFileSystemWatcher>
namespace KActivities {
// Private common
InfoPrivateCommon * InfoPrivateCommon::s_instance = 0;
InfoPrivateCommon * InfoPrivateCommon::self()
{
if (!s_instance) {
s_instance = new InfoPrivateCommon();
}
return s_instance;
}
InfoPrivateCommon::InfoPrivateCommon()
{
}
InfoPrivateCommon::~InfoPrivateCommon()
{
}
// Private
InfoPrivate::InfoPrivate(Info *info, const QString &activity)
: q(info),
state(Info::Invalid),
nameCallWatcher(0),
iconCallWatcher(0),
id(activity)
{
if (Manager::isServicePresent()) {
initializeCachedData();
}
}
// Filters out signals for only this activity
#define IMPLEMENT_SIGNAL_HANDLER(ORIGINAL, INTERNAL) \
void InfoPrivate::INTERNAL(const QString & _id) const \
{ \
if (id == _id) emit q->INTERNAL(); \
}
IMPLEMENT_SIGNAL_HANDLER(ActivityAdded, added)
IMPLEMENT_SIGNAL_HANDLER(ActivityRemoved, removed)
IMPLEMENT_SIGNAL_HANDLER(ActivityStarted, started)
IMPLEMENT_SIGNAL_HANDLER(ActivityStopped, stopped)
IMPLEMENT_SIGNAL_HANDLER(ActivityChanged, infoChanged)
#undef IMPLEMENT_SIGNAL_HANDLER
KAMD_RETRIEVE_REMOTE_VALUE_HANDLER(QString, InfoPrivate, name, QString())
KAMD_RETRIEVE_REMOTE_VALUE_HANDLER(QString, InfoPrivate, icon, QString())
void InfoPrivate::nameChanged(const QString & _id, const QString & _name) const
{
if (id == _id) {
name = _name;
emit q->nameChanged(name);
}
}
void InfoPrivate::iconChanged(const QString & _id, const QString & _icon) const
{
if (id == _id) {
icon = _icon;
emit q->iconChanged(icon);
}
}
void InfoPrivate::setServicePresent(bool present)
{
if (present) {
initializeCachedData();
}
}
void InfoPrivate::activityStateChanged(const QString & idChanged, int newState)
{
if (idChanged == id) {
state = static_cast<Info::State>(newState);
emit q->stateChanged(state);
}
}
void InfoPrivate::initializeCachedData()
{
KAMD_RETRIEVE_REMOTE_VALUE(name, ActivityName(id), q);
KAMD_RETRIEVE_REMOTE_VALUE(icon, ActivityIcon(id), q);
}
// Info
Info::Info(const QString &activity, QObject *parent)
: QObject(parent),
d(new InfoPrivate(this, activity))
{
connect(Manager::activities(), SIGNAL(ActivityStateChanged(QString, int)),
this, SLOT(activityStateChanged(QString, int)));
connect(Manager::activities(), SIGNAL(ActivityChanged(QString)),
this, SLOT(infoChanged(QString)));
connect(Manager::activities(), SIGNAL(ActivityNameChanged(QString, QString)),
this, SLOT(nameChanged(QString, QString)));
connect(Manager::activities(), SIGNAL(ActivityIconChanged(QString, QString)),
this, SLOT(iconChanged(QString, QString)));
connect(Manager::activities(), SIGNAL(ActivityAdded(QString)),
this, SLOT(added(QString)));
connect(Manager::activities(), SIGNAL(ActivityRemoved(QString)),
this, SLOT(removed(QString)));
connect(Manager::activities(), SIGNAL(ActivityStarted(QString)),
this, SLOT(started(QString)));
connect(Manager::activities(), SIGNAL(ActivityStopped(QString)),
this, SLOT(stopped(QString)));
}
Info::~Info()
{
delete d;
}
bool Info::isValid() const
{
return (state() != Invalid);
}
KUrl Info::uri() const
{
return KUrl("activities://" + d->id);
}
KUrl Info::resourceUri() const
{
return KUrl();
}
QString Info::id() const
{
return d->id;
}
KAMD_REMOTE_VALUE_GETTER(QString, Info, name,
i18nc("The name of the main activity - when the activity manager is not running", "Main"))
KAMD_REMOTE_VALUE_GETTER(QString, Info, icon, "preferences-activities")
Info::State Info::state() const
{
if (d->state == Invalid) {
QDBusReply < int > dbusReply = Manager::activities()->ActivityState(d->id);
if (dbusReply.isValid()) {
d->state = (State)(dbusReply.value());
}
}
return d->state;
}
QString Info::name(const QString & id)
{
KAMD_RETRIEVE_REMOTE_VALUE_SYNC(
QString, activities, ActivityName(id),
i18nc("The name of the main activity - when the activity manager is not running", "Main")
);
}
bool Info::isEncrypted() const
{
return false;
}
Info::Availability Info::availability() const
{
Availability result = Nothing;
if (!Manager::isServicePresent()) {
return result;
}
if (Manager::activities()->ListActivities().value().contains(d->id)) {
result = BasicInfo;
if (Manager::features()->IsFeatureOperational("org.kde.ActivityManager.Nepomuk/linking")) {
result = Everything;
}
}
return result;
}
KUrl::List Info::linkedResources() const
{
KUrl::List result;
QDBusReply < QStringList > dbusReply = Manager::resourcesLinking()->ResourcesLinkedToActivity(d->id);
if (dbusReply.isValid()) {
foreach (const QString & uri, dbusReply.value()) {
result << KUrl(uri);
}
}
return result;
}
void Info::linkResource(const KUrl & resourceUri)
{
Manager::resourcesLinking()->LinkResourceToActivity(resourceUri.url(), d->id);
}
void Info::unlinkResource(const KUrl & resourceUri)
{
Manager::resourcesLinking()->UnlinkResourceFromActivity(resourceUri.url(), d->id);
}
bool Info::isResourceLinked(const KUrl & resourceUri)
{
return Manager::resourcesLinking()->IsResourceLinkedToActivity(resourceUri.url(), d->id);
}
} // namespace KActivities
#include "info_p.moc"
#include "info.moc"

View file

@ -0,0 +1,255 @@
/*
* Copyright (c) 2010, 2011, 2012 Ivan Cukic <ivan.cukic(at)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 ACTIVITIES_INFO_H
#define ACTIVITIES_INFO_H
#include <QObject>
#include <QWidget>
#include <QString>
#include <QStringList>
#include <kurl.h>
#include <kdemacros.h>
#include "kactivities_export.h"
namespace KActivities {
class InfoPrivate;
/**
* This class provides info about an activity. Most methods in it
* require a Nepomuk backend running.
*
* This class is not thread-safe
*
* @see Consumer for info about activities
*
* The API of the class is synchronous, but the most used properties
* are pre-fetched and cached. This means that, in order to get the least
* amount of d-bus related locks, you should declare long-lived instances
* of this class.
*
* For example, this is wrong (works, but blocks):
* @code
* void someMethod(const QString & activity) {
* Info info(activity);
* doSomethingWith(info.name());
* }
* @endcode
*
* The methods that are cached are marked as 'pre-fetched and cached'.
* Methods that will block until the response from the service is returned
* are marked as 'blocking'.
*
* @since 4.5
*/
class KACTIVITIES_EXPORT Info: public QObject
{
Q_OBJECT
Q_PROPERTY(QString id READ id)
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
Q_PROPERTY(QString icon READ icon NOTIFY iconChanged)
public:
explicit Info(const QString & activity, QObject * parent = 0 /*nullptr*/);
~Info();
/**
* @return true if the activity represented by this object exists and is valid
*/
bool isValid() const;
/**
* Specifies which parts of this class are functional
*/
enum Availability {
Nothing = 0, ///< No activity info provided (isValid is false)
BasicInfo = 1, ///< Basic info is provided
Everything = 2 ///< Everything is available
};
/**
* State of the activity
*/
enum State {
Invalid = 0,
Running = 2,
Starting = 3,
Stopped = 4,
Stopping = 5
};
/**
* @returns what info is provided by this instance of Info
*/
Availability availability() const;
/**
* @returns the URI of this activity. The same URI is used by
* activities KIO slave.
*/
KUrl uri() const;
/**
* @deprecated we don't guarantee that nepomuk is the backend
* @returns the Nepomuk resource URI of this activity
* @note Functional only when availability is Everything
*/
KDE_DEPRECATED
KUrl resourceUri() const;
/**
* @returns the id of the activity
*/
QString id() const;
/**
* @returns the name of the activity
* @note Functional when availability is BasicInfo or Everything
* @note This method is <b>pre-fetched and cached</b>
*/
QString name() const;
/**
* @returns the icon of the activity. Icon can be a
* freedesktop.org name or a file path. Or empty if
* no icon is set.
* @note Functional only when availability is Everything
* @note This method is <b>pre-fetched and cached</b>
*/
QString icon() const;
/**
* @returns the state of the activity
* @note This method is <b>cached</b>
*/
State state() const;
/**
* @returns true if encrypted
* @since 4.8
*/
KDE_DEPRECATED
bool isEncrypted() const;
/**
* This function is provided for convenience.
* @returns the name of the specified activity
* @param id id of the activity
* @note This method is <b>blocking</b>, you should use Info::name()
*/
static QString name(const QString & id);
/**
* Links the specified resource to the activity
* @param resourceUri resource URI
* @note This method is <b>asynchronous</b>
*/
void linkResource(const KUrl & resourceUri);
/**
* Unlinks the specified resource from the activity
* @param resourceUri resource URI
* @note This method is <b>asynchronous</b>
*/
void unlinkResource(const KUrl & resourceUri);
/**
* @returns the list of linked resources
* @note This method is <b>blocking</b>
*/
KDE_DEPRECATED
KUrl::List linkedResources() const;
/**
* @returns whether a resource is linked to this activity
* @note this method is <b>blocking</b>
* @since 4.11
*/
bool isResourceLinked(const KUrl & resourceUri);
Q_SIGNALS:
/**
* Emitted when the activity's name, icon or some custom property is changed
*/
void infoChanged();
/**
* Emitted when the name is changed
*/
void nameChanged(const QString & name);
/**
* Emitted when the icon was changed
*/
void iconChanged(const QString & icon);
/**
* Emitted when the activity is added
*/
void added();
/**
* Emitted when the activity is removed
*/
void removed();
/**
* Emitted when the activity is started
*/
void started();
/**
* Emitted when the activity is stopped
*/
void stopped();
/**
* Emitted when the activity changes state
* @param state new state of the activity
*/
void stateChanged(KActivities::Info::State state);
private:
InfoPrivate * const d;
Q_PRIVATE_SLOT(d, void activityStateChanged(const QString &, int))
Q_PRIVATE_SLOT(d, void added(const QString &))
Q_PRIVATE_SLOT(d, void removed(const QString &))
Q_PRIVATE_SLOT(d, void started(const QString &))
Q_PRIVATE_SLOT(d, void stopped(const QString &))
Q_PRIVATE_SLOT(d, void infoChanged(const QString &))
Q_PRIVATE_SLOT(d, void nameChanged(const QString &, const QString &))
Q_PRIVATE_SLOT(d, void iconChanged(const QString &, const QString &))
Q_PRIVATE_SLOT(d, void setServicePresent(bool))
Q_PRIVATE_SLOT(d, void nameCallFinished(QDBusPendingCallWatcher*))
Q_PRIVATE_SLOT(d, void iconCallFinished(QDBusPendingCallWatcher*))
friend class InfoPrivate;
};
} // namespace KActivities
#endif // ACTIVITIES_INFO_H

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2010, 2011, 2012 Ivan Cukic <ivan.cukic(at)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 KACTIVITIESINFO_P_H
#define KACTIVITIESINFO_P_H
#include "info.h"
#include <QObject>
#include "utils_p.h"
namespace KActivities {
class InfoPrivateCommon: public QObject {
Q_OBJECT
public:
static InfoPrivateCommon * self();
InfoPrivateCommon();
virtual ~InfoPrivateCommon();
private:
static InfoPrivateCommon * s_instance;
};
class InfoPrivate {
public:
InfoPrivate(Info * info, const QString & activity);
void activityStateChanged(const QString &, int);
void added(const QString &) const;
void removed(const QString &) const;
void started(const QString &) const;
void stopped(const QString &) const;
void infoChanged(const QString &) const;
void nameChanged(const QString &, const QString &) const;
void iconChanged(const QString &, const QString &) const;
void setServicePresent(bool present);
void initializeCachedData();
Info *q;
Info::State state;
KAMD_REMOTE_VALUE(QString, name);
KAMD_REMOTE_VALUE(QString, icon);
const QString id;
};
} // namespace KActivities
#endif // ACTIVITIES_INFO_P_H

View file

@ -0,0 +1,52 @@
/****************************************************************************************
* Copyright (c) 2012 Patrick von Reth <patrick.vonreth@gmail.com> *
* *
* This program 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 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 Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
****************************************************************************************/
#ifndef KACTIVITIES_EXPORT_H
#define KACTIVITIES_EXPORT_H
/* needed for KDE_EXPORT and KDE_IMPORT macros */
#include <kdemacros.h>
#ifndef KACTIVITIES_EXPORT
# ifdef MAKE_KACTIVITIES_LIB
/* We are building this library */
# define KACTIVITIES_EXPORT KDE_EXPORT
# if defined(DEBUG)
# define KACTIVITIES_EXPORT_TESTS KDE_EXPORT
# else
# define KACTIVITIES_EXPORT_TESTS
# endif
# else
/* We are using this library */
# define KACTIVITIES_EXPORT KDE_IMPORT
# if defined(DEBUG)
# define KACTIVITIES_EXPORT_TESTS KDE_IMPORT
# else
# define KACTIVITIES_EXPORT_TESTS
# endif
# endif//MAKE_KACTIVITIES_LIB
#endif// KACTIVITIES_EXPORT
# ifndef KACTIVITIES_EXPORT_DEPRECATED
# define KACTIVITIES_EXPORT_DEPRECATED KDE_DEPRECATED KACTIVITIES_EXPORT
# endif
#endif

View file

@ -0,0 +1,12 @@
prefix=${CMAKE_INSTALL_PREFIX}
exec_prefix=${BIN_INSTALL_DIR}
libdir=${LIB_INSTALL_DIR}
includedir=${INCLUDE_INSTALL_DIR}
Name: libkkactivities
Description: libkkactivities is a C++ library for using KDE activities
URL: http://www.kde.org
Requires:
Version: ${KACTIVITIES_LIB_VERSION_STRING}
Libs: -L${LIB_INSTALL_DIR} -lkactivities
Cflags: -I${INCLUDE_INSTALL_DIR}

View file

@ -0,0 +1,134 @@
/*
* Copyright (C) 2010, 2011, 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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 Lesser General Public License for more details
*
* You should have received a copy of the GNU Lesser 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 "manager_p.h"
#include <QDBusConnection>
#include <QDebug>
#include <ktoolinvocation.h>
#include <kdbusconnectionpool.h>
namespace KActivities {
Manager * Manager::s_instance = 0 /*nullptr*/;
#define ACTIVITY_MANAGER_DBUS_PATH "org.kde.ActivityManager"
#define ACTIVITY_MANAGER_DBUS_OBJECT "/ActivityManager"
Manager::Manager()
: QObject(),
m_activities(
new org::kde::ActivityManager::Activities(
ACTIVITY_MANAGER_DBUS_PATH,
ACTIVITY_MANAGER_DBUS_OBJECT "/Activities",
KDBusConnectionPool::threadConnection(),
this
)),
m_resources(
new org::kde::ActivityManager::Resources(
ACTIVITY_MANAGER_DBUS_PATH,
ACTIVITY_MANAGER_DBUS_OBJECT "/Resources",
KDBusConnectionPool::threadConnection(),
this
)),
m_resourcesLinking(
new org::kde::ActivityManager::ResourcesLinking(
ACTIVITY_MANAGER_DBUS_PATH,
ACTIVITY_MANAGER_DBUS_OBJECT "/Resources/Linking",
KDBusConnectionPool::threadConnection(),
this
)),
m_features(
new org::kde::ActivityManager::Features(
ACTIVITY_MANAGER_DBUS_PATH,
ACTIVITY_MANAGER_DBUS_OBJECT "/Features",
KDBusConnectionPool::threadConnection(),
this
))
{
connect(&m_watcher, SIGNAL(serviceOwnerChanged(const QString &, const QString &, const QString &)),
this, SLOT(serviceOwnerChanged(const QString &, const QString &, const QString &)));
}
Manager * Manager::self()
{
if (!s_instance) {
// check if the activity manager is already running
if (!isServicePresent()) {
// not running, trying to launch it
QString error;
int ret = KToolInvocation::startServiceByDesktopPath("kactivitymanagerd.desktop", QStringList(), &error);
if (ret > 0) {
qDebug() << "Activity: Couldn't start kactivitymanagerd: " << error << endl;
QProcess::startDetached("kactivitymanagerd");
}
if (!KDBusConnectionPool::threadConnection().interface()->isServiceRegistered(ACTIVITY_MANAGER_DBUS_PATH)) {
qDebug() << "Activity: The kactivitymanagerd service is still not registered";
} else {
qDebug() << "Activity: The kactivitymanagerd service has been registered";
}
}
// creating a new instance of the class
s_instance = new Manager();
}
return s_instance;
}
bool Manager::isServicePresent()
{
return KDBusConnectionPool::threadConnection().interface()->isServiceRegistered(ACTIVITY_MANAGER_DBUS_PATH);
}
void Manager::serviceOwnerChanged(const QString & serviceName, const QString & oldOwner, const QString & newOwner)
{
Q_UNUSED(oldOwner)
if (serviceName == ACTIVITY_MANAGER_DBUS_PATH) {
emit servicePresenceChanged(!newOwner.isEmpty());
}
}
Service::Activities * Manager::activities()
{
return self()->m_activities;
}
Service::Resources * Manager::resources()
{
return self()->m_resources;
}
Service::ResourcesLinking * Manager::resourcesLinking()
{
return self()->m_resourcesLinking;
}
Service::Features * Manager::features()
{
return self()->m_features;
}
} // namespace KActivities

View file

@ -0,0 +1,71 @@
/*
* Copyright (C) 2010, 2011, 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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 Lesser General Public License for more details
*
* You should have received a copy of the GNU Lesser 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.
*/
#ifndef ACTIVITIES_MANAGER_P
#define ACTIVITIES_MANAGER_P
#include <common/dbus/org.kde.ActivityManager.Activities.h>
#include "activities_interface.h"
#include "resources_interface.h"
#include "resources_linking_interface.h"
#include "features_interface.h"
#include <QDBusServiceWatcher>
namespace Service = org::kde::ActivityManager;
namespace KActivities {
class Manager: public QObject {
Q_OBJECT
public:
static Manager * self();
static bool isServicePresent();
static Service::Activities * activities();
static Service::Resources * resources();
static Service::ResourcesLinking * resourcesLinking();
static Service::Features * features();
public Q_SLOTS:
void serviceOwnerChanged(const QString & serviceName, const QString & oldOwner, const QString & newOwner);
Q_SIGNALS:
void servicePresenceChanged(bool present);
private:
Manager();
QDBusServiceWatcher m_watcher;
static Manager * s_instance;
Service::Activities * const m_activities;
Service::Resources * const m_resources;
Service::ResourcesLinking * const m_resourcesLinking;
Service::Features * const m_features;
};
} // namespace KActivities
#endif // ACTIVITIES_MANAGER_P

View file

@ -0,0 +1,4 @@
#!/bin/bash
grep KDE_EXPORT *.h | sed 's/:.*KDE_EXPORT//' | sed 's/:.*//g' | sed 's/\([^ ]*\) \(.*\)/echo "#include \\"..\/..\/kactivities\/\1\\"" > includes\/Activities\/\2/g'

View file

@ -0,0 +1,198 @@
/*
* Copyright (C) 2011, 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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 "resourceinstance.h"
#include "manager_p.h"
#include <QCoreApplication>
#include <QDebug>
namespace KActivities {
#ifdef Q_OS_WIN64 // krazy:skip
__inline int toInt(WId wid)
{
return (int)((__int64)wid);
}
#else
__inline int toInt(WId wid)
{
return (int)wid;
}
#endif
class ResourceInstancePrivate {
public:
WId wid;
ResourceInstance::AccessReason reason;
QUrl uri;
QString mimetype;
QString title;
QString application;
void closeResource();
void openResource();
enum Type {
Accessed = 0,
Opened = 1,
Modified = 2,
Closed = 3,
FocusedIn = 4,
FocusedOut = 5
};
static void registerResourceEvent(const QString &application, WId wid, const QUrl &uri, Type event, ResourceInstance::AccessReason reason)
{
Manager::resources()->RegisterResourceEvent(application, toInt(wid), uri.toString(), uint(event), uint(reason));
}
};
void ResourceInstancePrivate::closeResource()
{
registerResourceEvent(application, wid, uri, Closed, reason);
}
void ResourceInstancePrivate::openResource()
{
registerResourceEvent(application, wid, uri, Opened, reason);
}
ResourceInstance::ResourceInstance(WId wid, QObject *parent)
: QObject(parent), d(new ResourceInstancePrivate())
{
qDebug() << "Creating ResourceInstance: empty for now";
d->wid = wid;
d->reason = User;
d->application = QCoreApplication::instance()->applicationName();
}
ResourceInstance::ResourceInstance(WId wid, AccessReason reason, const QString &application, QObject *parent)
: QObject(parent), d(new ResourceInstancePrivate())
{
qDebug() << "Creating ResourceInstance: empty for now";
d->wid = wid;
d->reason = reason;
d->application = application.isEmpty() ? QCoreApplication::instance()->applicationName() : application;
}
ResourceInstance::ResourceInstance(WId wid, QUrl resourceUri, const QString &mimetype,
const QString &title, AccessReason reason, const QString &application, QObject *parent)
: QObject(parent), d(new ResourceInstancePrivate())
{
qDebug() << "Creating ResourceInstance: " << resourceUri;
d->wid = wid;
d->reason = reason;
d->uri = resourceUri;
d->application = application.isEmpty() ? QCoreApplication::instance()->applicationName() : application;
d->openResource();
setTitle(title);
setMimetype(mimetype);
}
ResourceInstance::~ResourceInstance()
{
d->closeResource();
delete d;
}
void ResourceInstance::notifyModified()
{
d->registerResourceEvent(d->application, d->wid, d->uri, ResourceInstancePrivate::Modified, d->reason);
}
void ResourceInstance::notifyFocusedIn()
{
d->registerResourceEvent(d->application, d->wid, d->uri, ResourceInstancePrivate::FocusedIn, d->reason);
}
void ResourceInstance::notifyFocusedOut()
{
d->registerResourceEvent(d->application, d->wid, d->uri, ResourceInstancePrivate::FocusedOut, d->reason);
}
void ResourceInstance::setUri(const QUrl &newUri)
{
if (d->uri == newUri)
return;
if (!d->uri.isEmpty()) {
d->closeResource();
}
d->uri = newUri;
d->openResource();
}
void ResourceInstance::setMimetype(const QString &mimetype)
{
if (mimetype.isEmpty()) return;
d->mimetype = mimetype;
// TODO: update the service info
Manager::resources()->RegisterResourceMimeType(d->uri.toString(), mimetype);
}
void ResourceInstance::setTitle(const QString &title)
{
qDebug() << "Setting the title: " << title;
if (title.isEmpty()) return;
d->title = title;
// TODO: update the service info
Manager::resources()->RegisterResourceTitle(d->uri.toString(), title);
}
QUrl ResourceInstance::uri() const
{
return d->uri;
}
QString ResourceInstance::mimetype() const
{
return d->mimetype;
}
QString ResourceInstance::title() const
{
return d->title;
}
WId ResourceInstance::winId() const
{
return d->wid;
}
ResourceInstance::AccessReason ResourceInstance::accessReason() const
{
return d->reason;
}
void ResourceInstance::notifyAccessed(const QUrl &uri, const QString &application)
{
ResourceInstancePrivate::registerResourceEvent(
application.isEmpty() ? QCoreApplication::instance()->applicationName() : application,
0, uri, ResourceInstancePrivate::Accessed, User);
}
} // namespace KActivities

View file

@ -0,0 +1,223 @@
/*
* Copyright (C) 2011, 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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 Lesser General Public License for more details
*
* You should have received a copy of the GNU Lesser 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.
*/
#ifndef ACTIVITIES_RESOURCEINSTANCE_H
#define ACTIVITIES_RESOURCEINSTANCE_H
#include <QObject>
#include <QWidget>
#include <QUrl>
#include "kactivities_export.h"
namespace KActivities {
class ResourceInstancePrivate;
/**
* This class is used to notify the system that a file, web page
* or some other resource has been accessed.
*
* It provides methods to notify the system when the resource was
* opened, modified and closed, along with in what window the
* resource is shown.
*
* You should create an instance of this class for every resource
* you open.
*
* "The system" in this case can be the backend for tracking
* and automatically scoring files that are being accessed, the
* system to show the open files per window in the taskbar,
* the share-like-connect, etc.
*
* The user of this class shouldn't care about the backend
* systems - everything is done under-the-hood automatically.
*
*/
class KACTIVITIES_EXPORT ResourceInstance: public QObject
{
Q_OBJECT
Q_PROPERTY(QUrl uri READ uri WRITE setUri)
Q_PROPERTY(QString mimetype READ mimetype WRITE setMimetype)
Q_PROPERTY(QString title READ title WRITE setTitle)
Q_PROPERTY(WId winId READ winId)
Q_PROPERTY(AccessReason accessReason READ accessReason)
public:
/***
* The reason for opening the resource
*/
enum AccessReason {
User = 0, ///< Due to an explicit user request
Scheduled = 1, ///< As a result of a user-scheduled action
Heuristic = 2, ///< Deduced from user's activity, or indirectly requested
System = 3, ///< Due to a system event
World = 4 ///< Due to an action performed by an external entity
};
Q_ENUMS(AccessReason)
/**
* Creates a new resource instance
* @param wid id of the window that will show the resource
* @param parent pointer to the parent object
* @since 4.10
*/
explicit ResourceInstance(WId wid, QObject *parent = 0 /*nullptr*/);
/**
* Creates a new resource instance
* @param wid id of the window that will show the resource
* @param reason reason for opening the resource
* @param application application's name (the name used for the .desktop file).
* If not specified, QCoreApplication::applicationName is used
* @param parent pointer to the parent object
*/
explicit ResourceInstance(WId wid, AccessReason reason = User, const QString &application = QString(), QObject * parent = 0 /*nullptr*/);
/**
* Creates a new resource instance and automatically
* notifies the system that it was opened.
*
* In some special cases, where the URI of the resource is
* being constantly changed (for example, in the world globe,
* street map applications) you have two options:
* - to pass an empty resourceUri while passing the mimetype
* - to update the uri from time to time (in the example of
* the world map - to send URIs for major objects - cities
* or main streets.
* and in both cases reimplementing the currentUri() method
* which will return the exact URI shown at that specific moment.
*
* @param wid window id in which the resource is shown
* @param resourceUri URI of the resource that is shown
* @param mimetype the mime type of the resource
* @param title the title of the resource
* @param reason reason for opening the resource
* @param application application's name (the name used for the .desktop file).
* If not specified, QCoreApplication::applicationName is used
* @param parent pointer to the parent object
*/
ResourceInstance(WId wid, QUrl resourceUri, const QString &mimetype = QString(), const QString &title = QString(), AccessReason reason = User, const QString &application = QString(), QObject *parent = 0 /*nullptr*/);
/**
* Destroys the ResourceInstance and notifies the system
* that the resource has been closed
*/
~ResourceInstance();
public Q_SLOTS:
/**
* Call this method to notify the system that you modified
* (the contents of) the resource
*/
void notifyModified();
/**
* Call this method to notify the system that the resource
* has the focus in your application
* @note You only need to call this in MDI applications
*/
void notifyFocusedIn();
/**
* Call this method to notify the system that the resource
* lost the focus in your application
* @note You only need to call this in MDI applications
*/
void notifyFocusedOut();
/**
* This is a convenience method that sets the new URI.
* This is usually handled by sending the close event for
* the previous URI, and an open event for the new one.
*/
void setUri(const QUrl &newUri);
/**
* Sets the mimetype for this resource
*/
void setMimetype(const QString &mimetype);
/**
* Sets the title for this resource
*/
void setTitle(const QString &title);
Q_SIGNALS:
/**
* Emitted when the system wants to show the resource
* represented by this ResourceInstance.
*
* You should listen to this signal if you have multiple
* resources shown in one window (MDI). On catching it, show
* the resource and give it focus.
*/
void requestsFocus();
public:
/**
* @returns the current uri
* The default implementation returns the URI that was passed
* to the constructor.
* You need to reimplement it only for the applications with
* frequently updated URIs.
*/
virtual QUrl uri() const;
/**
* @returns mimetype of the resource
*/
QString mimetype() const;
/**
* @returns title of the resource
*/
QString title() const;
/**
* @returns the window id
*/
WId winId() const;
/**
* @returns the reason for accessing the resource
*/
AccessReason accessReason() const;
/**
* If there's no way to tell for how long an application is keeping
* the resource open, you can just call this static method - it
* will notify the system that the application has accessed the
* resource
* @param uri URI of the resource
* @param application application's name (the name used for the .desktop file).
* If not specified, QCoreApplication::applicationName is used
*
*/
static void notifyAccessed(const QUrl &uri, const QString &application = QString());
private:
ResourceInstancePrivate * const d;
};
}
#endif // ACTIVITIES_RESOURCEINSTANCE_H

View file

@ -0,0 +1,104 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef UTILS_P_H
#define UTILS_P_H
#include <QDBusPendingCallWatcher>
#include <QMutex>
#include <QDebug>
#include <KLocalizedString>
// Creates an async call to retrieve a value from the dbus service
// and initializes the call watcher
#define KAMD_RETRIEVE_REMOTE_VALUE(Variable, MethodToCall, Target) \
Variable##Mutex.lock(); \
const QDBusPendingCall & Variable##Call = Manager::activities()->MethodToCall; \
Variable##CallWatcher = new QDBusPendingCallWatcher(Variable##Call, Target); \
\
QObject::connect(Variable##CallWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), \
Target, SLOT(Variable##CallFinished(QDBusPendingCallWatcher*)))
// Defines a variable and handlers for a variable on a dbus service
// without a handler for when a call is finished
#define KAMD_REMOTE_VALUE_CUSTOM_HANDLER(Type, Name) \
mutable Type Name; \
QDBusPendingCallWatcher * Name##CallWatcher; \
QMutex Name##Mutex
// Defines a variable and handlers for a variable on a dbus service
#define KAMD_REMOTE_VALUE(Type, Name) \
KAMD_REMOTE_VALUE_CUSTOM_HANDLER(Type, Name); \
void Name##CallFinished(QDBusPendingCallWatcher * call)
// macro defines a shorthand for validating and returning a d-bus result
// @param TYPE type of the result
// @param METHOD invocation of the d-bus method
// @param DEFAULT value to be used if the reply was not valid
#define KAMD_RETRIEVE_REMOTE_VALUE_SYNC(TYPE, OBJECT, METHOD, DEFAULT) \
if (!Manager::isServicePresent()) return DEFAULT; \
\
QDBusReply < TYPE > dbusReply = Manager::OBJECT()->METHOD; \
if (dbusReply.isValid()) { \
return dbusReply.value(); \
} else { \
qDebug() << "d-bus reply was invalid" \
<< dbusReply.value() \
<< dbusReply.error(); \
return DEFAULT; \
}
// Defines a handler for pre-fetching of the activity info
#define KAMD_RETRIEVE_REMOTE_VALUE_HANDLER(ReturnType, Namespace, Variable, DefaultValue) \
void Namespace::Variable##CallFinished(QDBusPendingCallWatcher * call) \
{ \
QDBusPendingReply <ReturnType> reply = * call; \
\
Variable = reply.isError() \
? DefaultValue \
: reply.argumentAt<0>(); \
\
Variable##CallWatcher = 0; \
Variable##Mutex.unlock(); \
call->deleteLater(); \
}
// Implements a value getter
#define KAMD_REMOTE_VALUE_GETTER(ReturnType, Namespace, Variable, Default) \
ReturnType Namespace::Variable() const \
{ \
if (!Manager::isServicePresent()) return Default; \
waitForCallFinished(d->Variable##CallWatcher, &d->Variable##Mutex); \
return d->Variable; \
}
static inline void waitForCallFinished(QDBusPendingCallWatcher * watcher, QMutex * mutex)
{
if (watcher) {
watcher->waitForFinished();
mutex->lock();
mutex->unlock();
}
}
#endif // UTILS_P_H

View file

@ -0,0 +1,51 @@
/*
* Copyright 2008 by Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 "version.h"
namespace KActivities
{
unsigned int version()
{
return KACTIVITIES_VERSION;
}
unsigned int versionMajor()
{
return KACTIVITIES_VERSION_MAJOR;
}
unsigned int versionMinor()
{
return KACTIVITIES_VERSION_MINOR;
}
unsigned int versionRelease()
{
return KACTIVITIES_VERSION_RELEASE;
}
const char *versionString()
{
return KACTIVITIES_VERSION_STRING;
}
} // KActivities namespace

View file

@ -0,0 +1,87 @@
/*
* Copyright 2008 by Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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.
*/
#ifndef KACTIVITIES_VERSION_H
#define KACTIVITIES_VERSION_H
/** @file version.h <KActivities/Version> */
#include "kactivities_export.h"
/**
* String version of libkactivities version, suitable for use in
* file formats or network protocols
*/
#define KACTIVITIES_VERSION_STRING "6.2.0"
/// @brief Major version of libkactivities, at compile time
#define KACTIVITIES_VERSION_MAJOR 6
/// @brief Minor version of libkactivities, at compile time
#define KACTIVITIES_VERSION_MINOR 2
/// @brief Release version of libkactivities, at compile time
#define KACTIVITIES_VERSION_RELEASE 0
#define KACTIVITIES_MAKE_VERSION(a,b,c) (((a) << 16) | ((b) << 8) | (c))
/**
* Compile time macro for the version number of libkactivities
*/
#define KACTIVITIES_VERSION \
KACTIVITIES_MAKE_VERSION(KACTIVITIES_VERSION_MAJOR, KACTIVITIES_VERSION_MINOR, KACTIVITIES_VERSION_RELEASE)
/**
* Compile-time macro for checking the kactivities version. Not useful for
* detecting the version of libkactivities at runtime.
*/
#define KACTIVITIES_IS_VERSION(a,b,c) (KACTIVITIES_VERSION >= KACTIVITIES_MAKE_VERSION(a,b,c))
/**
* Namespace for everything in libkactivities
*/
namespace KActivities
{
/**
* The runtime version of libkactivities
*/
KACTIVITIES_EXPORT unsigned int version();
/**
* The runtime major version of libkactivities
*/
KACTIVITIES_EXPORT unsigned int versionMajor();
/**
* The runtime major version of libkactivities
*/
KACTIVITIES_EXPORT unsigned int versionMinor();
/**
* The runtime major version of libkactivities
*/
KACTIVITIES_EXPORT unsigned int versionRelease();
/**
* The runtime version string of libkactivities
*/
KACTIVITIES_EXPORT const char *versionString();
} // KActivities namespace
#endif // multiple inclusion guard

View file

@ -0,0 +1,502 @@
/*
* Copyright (C) 2010, 2011, 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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 "Activities.h"
#include "Activities_p.h"
#include "activitiesadaptor.h"
#include <QDBusConnection>
#include <QUuid>
#include <QDebug>
#include <kauthorized.h>
#include <kdbusconnectionpool.h>
#include <config-features.h>
#include "jobs/activity/all.h"
#include "jobs/general/all.h"
#include "jobs/schedulers/all.h"
#include "jobs/ksmserver/KSMServer.h"
#include "common.h"
#include <utils/nullptr.h>
#include <utils/d_ptr_implementation.h>
#include <utils/find_if_assoc.h>
#include <utils/val.h>
// Private
Activities::Private::Private(Activities * parent)
: config("activitymanagerrc"),
q(parent)
{
}
Activities::Private::~Private()
{
configSync();
}
// Main
Activities::Activities(QObject * parent)
: Module("activities", parent), d(this)
{
qDebug() << "\n\n-------------------------------------------------------";
qDebug() << "Starting the KDE Activity Manager daemon" << QDateTime::currentDateTime();
qDebug() << "-------------------------------------------------------";
// Basic initialization //////////////////////////////////////////////////////////////////////////////////
// Initializing D-Bus service
new ActivitiesAdaptor(this);
KDBusConnectionPool::threadConnection().registerObject(
ACTIVITY_MANAGER_OBJECT_PATH(Activities), this);
// Initializing config
d->connect(&d->configSyncTimer, SIGNAL(timeout()),
SLOT(configSync()));
d->configSyncTimer.setSingleShot(true);
d->ksmserver = new KSMServer(this);
d->connect(d->ksmserver, SIGNAL(activitySessionStateChanged(QString, int)),
SLOT(activitySessionStateChanged(QString, int)));
// Activity initialization ///////////////////////////////////////////////////////////////////////////////
// Reading activities from the config file
foreach (val & activity, d->activitiesConfig().keyList()) {
d->activities[activity] = Activities::Stopped;
}
val & runningActivities = d->mainConfig().readEntry("runningActivities", d->activities.keys());
foreach (val & activity, runningActivities) {
if (d->activities.contains(activity)) {
d->activities[activity] = Activities::Running;
}
}
d->loadLastActivity();
}
Activities::~Activities()
{
}
QString Activities::CurrentActivity() const
{
return d->currentActivity;
}
bool Activities::SetCurrentActivity(const QString & activity)
{
// Public method can not put us in a limbo state
if (activity.isEmpty()) {
return false;
}
return d->setCurrentActivity(activity);
}
bool Activities::Private::setCurrentActivity(const QString & activity)
{
using namespace Jobs;
using namespace Jobs::General;
// If the activity is empty, this means we are entering a limbo state
if (activity.isEmpty()) {
currentActivity.clear();
emit q->CurrentActivityChanged(currentActivity);
return true;
}
// Sanity checks
if (!activities.contains(activity)) return false;
if (currentActivity == activity) return true;
// Start activity
// TODO: Move this to job-based execution
q->StartActivity(activity);
// - change the current activity and signal the change
emitCurrentActivityChanged(activity);
return true;
}
void Activities::Private::loadLastActivity()
{
// If there are no public activities, try to load the last used activity
val & lastUsedActivity = mainConfig().readEntry("currentActivity", QString());
setCurrentActivity(
(lastUsedActivity.isEmpty() && activities.size() > 0)
? activities.keys().at(0)
: lastUsedActivity
);
}
void Activities::Private::emitCurrentActivityChanged(const QString & activity)
{
// Saving the current activity, and notifying
// clients of the change
currentActivity = activity;
mainConfig().writeEntry("currentActivity", activity);
scheduleConfigSync();
emit q->CurrentActivityChanged(activity);
}
QString Activities::AddActivity(const QString & name)
{
if (!KAuthorized::authorize("plasma-desktop/add_activities")) {
return QString();
}
if (name.isEmpty()) {
Q_ASSERT(!name.isEmpty());
return QString();
}
QString activity;
// Ensuring a new Uuid. The loop should usually end after only
// one iteration
val & existingActivities = d->activities.keys();
while (activity.isEmpty() || existingActivities.contains(activity)) {
activity = QUuid::createUuid();
activity.replace(QRegExp("[{}]"), QString());
}
// Saves the activity info to the config
d->activities[activity] = Invalid;
d->setActivityState(activity, Running);
SetActivityName(activity, name);
emit ActivityAdded(activity);
d->scheduleConfigSync(true);
return activity;
}
void Activities::RemoveActivity(const QString & activity)
{
if (!KAuthorized::authorize("plasma-desktop/add_activities")) {
return;
}
// Sanity checks
if (!d->activities.contains(activity)) {
return;
}
d->removeActivity(activity);
}
void Activities::Private::removeActivity(const QString & activity)
{
qDebug() << activities << activity;
Q_ASSERT(!activity.isEmpty());
Q_ASSERT(activities.contains(activity));
// If the activity is running, stash it
q->StopActivity(activity);
setActivityState(activity, Activities::Invalid);
// Removing the activity
activities.remove(activity);
activitiesConfig().deleteEntry(activity);
// If the removed activity was the current one,
// set another activity as current
if (currentActivity == activity) {
ensureCurrentActivityIsRunning();
}
emit q->ActivityRemoved(activity);
configSync();
}
KConfigGroup Activities::Private::activityIconsConfig()
{
return KConfigGroup(&config, "activities-icons");
}
KConfigGroup Activities::Private::activitiesConfig()
{
return KConfigGroup(&config, "activities");
}
KConfigGroup Activities::Private::mainConfig()
{
return KConfigGroup(&config, "main");
}
QString Activities::Private::activityName(const QString & activity)
{
return activitiesConfig().readEntry(activity, QString());
}
QString Activities::Private::activityIcon(const QString & activity)
{
return activityIconsConfig().readEntry(activity, QString());
}
void Activities::Private::scheduleConfigSync(const bool soon)
{
static const auto shortInterval = 1000;
static const auto longInterval = 2 * 60 * 1000;
// If the timer is not running, or has a longer interval than we need,
// start it
if ((soon && configSyncTimer.interval() > shortInterval)
|| !configSyncTimer.isActive()) {
QMetaObject::invokeMethod(
&configSyncTimer, "start", Qt::QueuedConnection,
Q_ARG(int, soon ? shortInterval : longInterval));
}
}
void Activities::Private::configSync()
{
QMetaObject::invokeMethod(&configSyncTimer, "stop", Qt::QueuedConnection);
config.sync();
}
QStringList Activities::ListActivities() const
{
qDebug() << "This is the current thread id for Activities" << QThread::currentThreadId() << QThread::currentThread();
return d->activities.keys();
}
QStringList Activities::ListActivities(int state) const
{
return d->activities.keys((State)state);
}
QList<ActivityInfo> Activities::ListActivitiesWithInformation() const
{
QList<ActivityInfo> result;
foreach (const QString & activity, ListActivities()) {
result << ActivityInformation(activity);
}
return result;
}
ActivityInfo Activities::ActivityInformation(const QString & activity) const
{
if (!d->activities.contains(activity)) return ActivityInfo();
ActivityInfo activityInfo;
activityInfo.id = activity;
activityInfo.name = ActivityName(activity);
activityInfo.icon = ActivityIcon(activity);
activityInfo.state = ActivityState(activity);
return activityInfo;
}
QString Activities::ActivityName(const QString & activity) const
{
if (!d->activities.contains(activity)) return QString();
return d->activityName(activity);
}
void Activities::SetActivityName(const QString & activity, const QString & name)
{
if (!d->activities.contains(activity)) return;
if (name == d->activityName(activity)) return;
d->activitiesConfig().writeEntry(activity, name);
d->scheduleConfigSync(true);
emit ActivityNameChanged(activity, name);
emit ActivityChanged(activity);
}
QString Activities::ActivityIcon(const QString & activity) const
{
if (!d->activities.contains(activity)) return QString();
return d->activityIcon(activity);
}
void Activities::SetActivityIcon(const QString & activity, const QString & icon)
{
if (!d->activities.contains(activity)) return;
d->activityIconsConfig().writeEntry(activity, icon);
d->scheduleConfigSync();
emit ActivityIconChanged(activity, icon);
emit ActivityChanged(activity);
}
void Activities::Private::setActivityState(const QString & activity, Activities::State state)
{
qDebug() << activities << activity;
Q_ASSERT(activities.contains(activity));
if (activities.value(activity) == state) return;
// Treating 'Starting' as 'Running', and 'Stopping' as 'Stopped'
// as far as the config file is concerned
bool configNeedsUpdating = ((activities[activity] & 4) != (state & 4));
activities[activity] = state;
switch (state) {
case Activities::Running:
emit q->ActivityStarted(activity);
break;
case Activities::Stopped:
emit q->ActivityStopped(activity);
break;
default:
break;
}
emit q->ActivityStateChanged(activity, state);
if (configNeedsUpdating) {
mainConfig().writeEntry("runningActivities",
activities.keys(Activities::Running) +
activities.keys(Activities::Starting));
scheduleConfigSync();
}
}
void Activities::Private::ensureCurrentActivityIsRunning()
{
// If the current activity is not running,
// make some other activity current
val & runningActivities = q->ListActivities(Activities::Running);
if (!runningActivities.contains(currentActivity)) {
if (runningActivities.size() > 0) {
qDebug() << "Somebody called ensureCurrentActivityIsRunning?";
setCurrentActivity(runningActivities.first());
}
}
}
// Main
void Activities::StartActivity(const QString & activity)
{
if (!d->activities.contains(activity) ||
d->activities[activity] != Stopped) {
return;
}
qDebug() << "Starting the session";
d->setActivityState(activity, Starting);
d->ksmserver->startActivitySession(activity);
}
void Activities::StopActivity(const QString & activity)
{
if (!d->activities.contains(activity) ||
d->activities[activity] == Stopped) {
return;
}
qDebug() << "Stopping the session";
d->setActivityState(activity, Stopping);
d->ksmserver->stopActivitySession(activity);
}
void Activities::Private::activitySessionStateChanged(const QString & activity, int status)
{
if (!activities.contains(activity)) return;
switch (status) {
case KSMServer::Started:
case KSMServer::FailedToStop:
setActivityState(activity, Activities::Running);
break;
case KSMServer::Stopped:
setActivityState(activity, Activities::Stopped);
if (currentActivity == activity) {
ensureCurrentActivityIsRunning();
}
break;
}
configSync();
}
int Activities::ActivityState(const QString & activity) const
{
return d->activities.contains(activity) ? d->activities[activity] : Invalid;
}
bool Activities::isFeatureOperational(const QStringList & feature) const
{
Q_UNUSED(feature)
return false;
}
bool Activities::isFeatureEnabled(const QStringList & feature) const
{
Q_UNUSED(feature)
return false;
}
void Activities::setFeatureEnabled(const QStringList & feature, bool value)
{
Q_UNUSED(feature)
Q_UNUSED(value)
}
QStringList Activities::listFeatures(const QStringList & feature) const
{
Q_UNUSED(feature)
return QStringList();
}

View file

@ -0,0 +1,238 @@
/*
* Copyright (C) 2010, 2011, 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef ACTIVITIES_H
#define ACTIVITIES_H
#include <QString>
#include <QStringList>
#include <Module.h>
#include <utils/d_ptr.h>
#include <utils/nullptr.h>
#include <common/dbus/org.kde.ActivityManager.Activities.h>
/**
* Service for tracking the user actions and managing the
* activities
*/
class Activities: public Module {
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.ActivityManager.Activities")
Q_PROPERTY(QString CurrentActivity READ CurrentActivity WRITE SetCurrentActivity NOTIFY CurrentActivityChanged)
public:
/**
* Activity state
* @note: Do not change the values, needed for bit-operations
*/
enum State {
Invalid = 0,
Running = 2,
Starting = 3,
Stopped = 4,
Stopping = 5
};
/**
* The event type
*/
enum EventType {
Accessed = 1,
Opened = 2,
Modified = 3,
Closed = 4,
FocussedIn = 5,
FocussedOut = 6
};
/**
* Creates new Activities object
*/
Activities(QObject * parent = nullptr);
/**
* Destroys this interface
*/
virtual ~Activities();
// workspace activities control
public Q_SLOTS:
/**
* @returns the id of the current activity, empty string if none
*/
QString CurrentActivity() const;
/**
* Sets the current activity
* @param activity id of the activity to make current
*/
bool SetCurrentActivity(const QString & activity);
/**
* Adds a new activity
* @param name name of the activity
* @returns id of the newly created activity
*/
QString AddActivity(const QString & name);
/**
* Starts the specified activity
* @param activity id of the activity to stash
*/
void StartActivity(const QString & activity);
/**
* Stops the specified activity
* @param activity id of the activity to stash
*/
void StopActivity(const QString & activity);
/**
* @returns the state of the activity
* @param activity id of the activity
*/
int ActivityState(const QString & activity) const;
/**
* Removes the specified activity
* @param activity id of the activity to delete
*/
void RemoveActivity(const QString & activity);
/**
* @returns the list of all existing activities
*/
QStringList ListActivities() const;
/**
* @returns the list of activities with the specified state
* @param state state
*/
QStringList ListActivities(int state) const;
/**
* @returns the name of the specified activity
* @param activity id of the activity
*/
QString ActivityName(const QString & activity) const;
/**
* Sets the name of the specified activity
* @param activity id of the activity
* @param name name to be set
*/
void SetActivityName(const QString & activity, const QString & name);
/**
* @returns the icon of the specified activity
* @param activity id of the activity
*/
QString ActivityIcon(const QString & activity) const;
/**
* Sets the icon of the specified activity
* @param activity id of the activity
* @param icon icon to be set
*/
void SetActivityIcon(const QString & activity, const QString & icon);
public Q_SLOTS:
/**
* @returns a list of activities with basic info about them
*/
ActivityInfoList ListActivitiesWithInformation() const;
/**
* @returns the info about an activity
*/
ActivityInfo ActivityInformation(const QString & activity) const;
Q_SIGNALS:
/**
* This signal is emitted when the global
* activity is changed
* @param activity id of the new current activity
*/
void CurrentActivityChanged(const QString & activity);
/**
* This signal is emitted when a new activity is created
* @param activity id of the activity
*/
void ActivityAdded(const QString & activity);
/**
* This signal is emitted when an activity is started
* @param activity id of the activity
*/
void ActivityStarted(const QString & activity);
/**
* This signal is emitted when an activity is stashed
* @param activity id of the activity
*/
void ActivityStopped(const QString & activity);
/**
* This signal is emitted when an activity is deleted
* @param activity id of the activity
*/
void ActivityRemoved(const QString & activity);
/**
* Emitted when an activity name is changed
* @param activity id of the changed activity
* @param name name of the changed activity
*/
void ActivityNameChanged(const QString & activity, const QString & name);
/**
* Emitted when an activity icon is changed
* @param activity id of the changed activity
* @param icon name of the changed activity
*/
void ActivityIconChanged(const QString & activity, const QString & icon);
/**
* Emitted when an activity is changed (name, icon, or some other property)
* @param activity id of the changed activity
*/
void ActivityChanged(const QString & activity);
/**
* Emitted when the state of activity is changed
*/
void ActivityStateChanged(const QString & activity, int state);
public:
virtual bool isFeatureOperational(const QStringList & feature) const _override;
virtual bool isFeatureEnabled(const QStringList & feature) const _override;
virtual void setFeatureEnabled(const QStringList & feature, bool value) _override;
virtual QStringList listFeatures(const QStringList & feature) const _override;
private:
D_PTR;
};
#endif // ACTIVITIES_H

View file

@ -0,0 +1,96 @@
/*
* Copyright (C) 2010, 2011, 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef ACTIVITIES_P_H
#define ACTIVITIES_P_H
#include <QString>
#include <QTimer>
#include <KConfig>
#include <KConfigGroup>
#include "Activities.h"
class KSMServer;
class QDBusInterface;
class KJob;
class Activities::Private: public QObject {
Q_OBJECT
public:
Private(Activities * parent);
~Private();
// Loads the last activity
// the user has used
void loadLastActivity();
// If the current activity is not running,
// make some other activity current
void ensureCurrentActivityIsRunning();
public Q_SLOTS:
bool setCurrentActivity(const QString & activity);
public:
void setActivityState(const QString & activity, Activities::State state);
QHash < QString, Activities::State > activities;
// Current activity
QString currentActivity;
// Configuration
QTimer configSyncTimer;
KConfig config;
// Interface to the session management
KSMServer * ksmserver;
public:
KConfigGroup activitiesConfig();
KConfigGroup activityIconsConfig();
KConfigGroup mainConfig();
QString activityName(const QString & activity);
QString activityIcon(const QString & activity);
public Q_SLOTS:
// Schedules config syncing to be done after
// a predefined time interval
// if soon == true, the syncing is performed
// after a few seconds, otherwise a few minutes
void scheduleConfigSync(const bool soon = false);
// Immediately syncs the configuration file
void configSync();
void removeActivity(const QString & activity);
void activitySessionStateChanged(const QString & activity, int state);
void emitCurrentActivityChanged(const QString & activity);
private:
Activities * const q;
};
#endif // ACTIVITIES_P_H

View file

@ -0,0 +1,238 @@
/*
* Copyright (C) 2010, 2011, 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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 <Application.h>
#include <QDebug>
#include <QDBusConnection>
#include <QThread>
#include <KCrash>
#include <KAboutData>
#include <KCmdLineArgs>
#include <KServiceTypeTrader>
#include <KSharedConfig>
#include <kdbusconnectionpool.h>
#include <Activities.h>
#include <Resources.h>
#include <Features.h>
#include <Plugin.h>
#include <signal.h>
#include <stdlib.h>
#include <memory>
#include <utils/nullptr.h>
#include <utils/override.h>
#include <utils/d_ptr_implementation.h>
#include <utils/val.h>
namespace {
QList < QThread * > s_moduleThreads;
}
// Runs a QObject inside a QThread
template <typename T>
T * runInQThread()
{
T * object = new T();
class Thread: public QThread {
public:
Thread(T * ptr = nullptr)
: QThread(), object(ptr)
{
}
void run() _override
{
std::unique_ptr<T> o(object);
exec();
}
private:
T * object;
} * thread = new Thread(object);
s_moduleThreads << thread;
object->moveToThread(thread);
thread->start();
return object;
}
class Application::Private {
public:
Private()
: resources (runInQThread <Resources> ()),
activities (runInQThread <Activities> ()),
features (runInQThread <Features> ())
{
}
Resources * resources;
Activities * activities;
Features * features;
QList < Plugin * > plugins;
static Application * s_instance;
};
Application * Application::Private::s_instance = nullptr;
Application::Application()
: KUniqueApplication(), d()
{
// TODO: We should move away from any GUI code
setQuitOnLastWindowClosed(false);
if (!KDBusConnectionPool::threadConnection().registerService("org.kde.ActivityManager")) {
exit(0);
}
// KAMD is a daemon, if it crashes it is not a problem as
// long as it restarts properly
// NOTE: We have a custom crash handler
KCrash::setFlags(KCrash::AutoRestart);
QMetaObject::invokeMethod(this, "loadPlugins", Qt::QueuedConnection);
}
void Application::loadPlugins()
{
val offers = KServiceTypeTrader::self()->query("ActivityManager/Plugin");
val config = KSharedConfig::openConfig("activitymanagerrc");
auto disabledPlugins = config->group("Global").readEntry("disabledPlugins", QStringList());
val pluginsGroup = config->group("Plugins");
foreach (const QString & plugin, pluginsGroup.keyList()) {
if (!pluginsGroup.readEntry(plugin, true))
disabledPlugins << plugin;
}
// Adding overridden plugins into the list of disabled ones
foreach (val & service, offers) {
if (!disabledPlugins.contains(service->library())) {
disabledPlugins.append(
service->property("X-ActivityManager-PluginOverrides", QVariant::StringList).toStringList()
);
}
}
qDebug() << "These are the disabled plugins:" << disabledPlugins;
// Loading plugins and initializing them
foreach (val & service, offers) {
if (disabledPlugins.contains(service->library()) ||
disabledPlugins.contains(service->property("X-KDE-PluginInfo-Name").toString() + "Enabled")) {
continue;
}
val factory = KPluginLoader(service->library()).factory();
if (!factory) {
continue;
}
val plugin = factory->create < Plugin > (this);
if (plugin) {
qDebug() << "Got the plugin: " << service->library();
d->plugins << plugin;
}
}
foreach (Plugin * plugin, d->plugins) {
plugin->init(Module::get());
}
}
Application::~Application()
{
foreach (val plugin, d->plugins) {
delete plugin;
}
foreach (val thread, s_moduleThreads) {
thread->quit();
thread->wait();
delete thread;
}
Private::s_instance = nullptr;
}
int Application::newInstance()
{
//We don't want to show the mainWindow()
return 0;
}
Activities & Application::activities() const
{
return *d->activities;
}
Resources & Application::resources() const
{
return *d->resources;
}
Application * Application::self()
{
if (!Private::s_instance) {
Private::s_instance = new Application();
}
return Private::s_instance;
}
void Application::quit()
{
if (Private::s_instance) {
Private::s_instance->exit();
delete Private::s_instance;
}
}
// Leaving object oriented world :)
int main(int argc, char ** argv)
{
KAboutData about("kactivitymanagerd", nullptr, ki18n("KDE Activity Manager"), "3.0",
ki18n("KDE Activity Management Service"),
KAboutData::License_GPL,
ki18n("(c) 2010, 2011, 2012 Ivan Cukic"), KLocalizedString(),
"http://www.kde.org/");
KCmdLineArgs::init(argc, argv, &about);
return Application::self()->exec();
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef APPLICATION_H
#define APPLICATION_H
#include <KUniqueApplication>
#include <utils/d_ptr.h>
class Resources;
class Activities;
class Features;
/**
* Main application object
*/
class Application: public KUniqueApplication {
Q_OBJECT
public:
Application();
virtual ~Application();
virtual int newInstance();
static Application * self();
static void quit();
Resources & resources() const;
Activities & activities() const;
Features & features() const;
private Q_SLOTS:
void loadPlugins();
private:
D_PTR;
};
#endif // APPLICATION_H

View file

@ -0,0 +1,113 @@
project (ActivityManager)
# C++11
string (COMPARE EQUAL "${CMAKE_CXX_COMPILER_ID}" "Clang" CMAKE_COMPILER_IS_CLANG)
if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG)
message (STATUS "We have GNU or Clang, adding -std=c++0x flag")
add_definitions ("-std=c++0x")
set (ADDITIONAL_DEFINITIONS "-std=c++0x")
endif ()
# General
find_package(KDeclarative)
set (ADDITIONAL_LINK_LIBS)
set (sdo_SRCS)
# Standard stuff
include_directories (
${CMAKE_SOURCE_DIR}/src
${CMAKE_BINARY_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${KDE4_INCLUDES}
)
set (plugin_implementation_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/Plugin.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Module.cpp
)
add_subdirectory (plugins)
set (activity_manager_SRCS
Application.cpp
${CMAKE_SOURCE_DIR}/src/common/dbus/org.kde.ActivityManager.Activities.cpp
Activities.cpp
Resources.cpp
Features.cpp
${plugin_implementation_SRCS}
Event.cpp
jobs/Job.cpp
jobs/JobFactory.cpp
jobs/schedulers/Abstract.cpp
jobs/schedulers/Ordered.cpp
jobs/schedulers/Fallible.cpp
jobs/schedulers/Given.cpp
jobs/schedulers/Retry.cpp
jobs/schedulers/Switch.cpp
jobs/schedulers/Test.cpp
jobs/general/Call.cpp
jobs/ksmserver/KSMServer.cpp
${sdo_SRCS}
)
qt4_add_dbus_adaptor (
activity_manager_SRCS
../common/dbus/org.kde.ActivityManager.Activities.xml
Activities.h Activities
)
qt4_add_dbus_adaptor (
activity_manager_SRCS
../common/dbus/org.kde.ActivityManager.Resources.xml
Resources.h Resources
)
qt4_add_dbus_adaptor (
activity_manager_SRCS
../common/dbus/org.kde.ActivityManager.Features.xml
Features.h Features
)
kde4_add_executable (activity-manager ${activity_manager_SRCS})
target_link_libraries (activity-manager
${KDE4_KDECORE_LIBS}
${KDE4_KDEUI_LIBS} # KUniqueApplication
${ADDITIONAL_LINK_LIBS}
)
set_target_properties (activity-manager
PROPERTIES OUTPUT_NAME kactivitymanagerd
)
########### install application ###############
install (FILES
files/kactivitymanagerd.desktop
DESTINATION ${SERVICES_INSTALL_DIR}
)
install (TARGETS
activity-manager ${INSTALL_TARGETS_DEFAULT_ARGS}
)
install (FILES
files/activitymanager-plugin.desktop
DESTINATION ${SERVICETYPES_INSTALL_DIR}
)

View file

@ -0,0 +1,79 @@
/*
* Copyright (C) 2011, 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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 "Event.h"
#include <QDebug>
#include <common.h>
Event::Event()
: wid(0), type(Accessed), reason(User), timestamp(QDateTime::currentDateTime())
{
}
Event::Event(const QString & vApplication, WId vWid, const QString & vUri, int vType, int vReason)
: application(vApplication), wid(vWid), uri(vUri), type(vType), reason(vReason), timestamp(QDateTime::currentDateTime())
{
Q_ASSERT(!vApplication.isEmpty());
Q_ASSERT(!vUri.isEmpty());
}
Event Event::deriveWithType(Type type) const
{
Event result(*this);
result.type = type;
return result;
}
bool Event::operator == (const Event & other) const
{
return
application == other.application &&
wid == other.wid &&
uri == other.uri &&
type == other.type &&
reason == other.reason &&
timestamp == other.timestamp;
}
QString Event::typeName() const
{
switch (type) {
case Accessed: return "Accessed";
case Opened: return "Opened";
case Modified: return "Modified";
case Closed: return "Closed";
case FocussedIn: return "FocussedIn";
case FocussedOut: return "FocussedOut";
default: return "Other";
}
}
QDebug operator << (QDebug dbg, const Event & e)
{
#ifndef QT_NO_DEBUG_OUTPUT
dbg << "Event(" << e.application << e.wid << e.typeName() << e.uri << ":" << e.timestamp << ")";
#else
Q_UNUSED(e)
#endif
return dbg.space();
}

View file

@ -0,0 +1,99 @@
/*
* Copyright (C) 2011, 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef EVENT_H
#define EVENT_H
#include <QString>
#include <QWidget>
#include <QDateTime>
#include <QMetaType>
/**
*
*/
class Event {
public:
enum Type {
Accessed = 0, ///< resource was accessed, but we don't know for how long it will be open/used
Opened = 1, ///< resource was opened
Modified = 2, ///< previously opened resource was modified
Closed = 3, ///< previously opened resource was closed
FocussedIn = 4, ///< resource get the keyboard focus
FocussedOut = 5, ///< resource lost the focus
LastEventType = 5,
UserEventType = 32
};
// These events can't come outside of the activity manager daemon,
// they are intended to provide some additional functionality
// to the daemon plugins
enum UserType {
UpdateScore = UserEventType + 1
};
// TODO: Remove
// Was introduced for better cooperation with Zeitgeist
// We don't use it
enum Reason {
User = 0,
Scheduled = 1,
Heuristic = 2,
System = 3,
World = 4,
LastEventReason = 4,
UserEventReason = 32
};
Event();
explicit Event(const QString & application, WId wid, const QString & uri,
int type = Accessed, int reason = User);
Event deriveWithType(Type type) const;
bool operator == (const Event & other) const;
public:
QString application;
WId wid;
QString uri;
int type;
int reason;
QDateTime timestamp;
QString typeName() const;
};
QDebug operator << (QDebug dbg, const Event & e);
typedef QList<Event> EventList;
Q_DECLARE_METATYPE(Event)
Q_DECLARE_METATYPE(EventList)
#endif // EVENT_H

View file

@ -0,0 +1,105 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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 <Features.h>
#include "featuresadaptor.h"
#include "common.h"
#include <kdbusconnectionpool.h>
#include <utils/d_ptr_implementation.h>
#include <utils/val.h>
class Features::Private {
};
Features::Features(QObject * parent)
: Module("features", parent), d()
{
new FeaturesAdaptor(this);
KDBusConnectionPool::threadConnection().registerObject(
ACTIVITY_MANAGER_OBJECT_PATH(Features), this);
}
Features::~Features()
{
}
// Features object is just a gateway to the other KAMD modules.
// This is a convenience method to pass the request down to the module
template <typename RetType, typename Function>
static RetType passToModule(const QString & feature, RetType defaultResult, Function f)
{
val params = feature.split('/');
val module = Module::get(params.first());
if (!module) return defaultResult;
return f(static_cast<Module*>(module), params.mid(1));
}
#define FEATURES_PASS_TO_MODULE(RetType, DefaultResult, What) \
passToModule(feature, DefaultResult, \
[=] (Module * module, const QStringList & params) -> RetType { \
What \
});
bool Features::IsFeatureOperational(const QString & feature) const
{
if (feature.isEmpty()) return false;
return FEATURES_PASS_TO_MODULE(bool, false,
return module->isFeatureOperational(params);
);
}
bool Features::IsFeatureEnabled(const QString & feature) const
{
if (feature.isEmpty()) return false;
return FEATURES_PASS_TO_MODULE(bool, false,
return module->isFeatureEnabled(params);
);
}
void Features::SetFeatureEnabled(const QString & feature, bool value)
{
if (feature.isEmpty()) return;
FEATURES_PASS_TO_MODULE(bool, false,
module->setFeatureEnabled(params, value);
return true;
);
}
QStringList Features::ListFeatures(const QString & feature) const
{
if (feature.isEmpty()) {
return Module::get().keys();
}
return FEATURES_PASS_TO_MODULE(QStringList, QStringList(),
return module->listFeatures(params);
);
}
#undef FEATURES_PASS_TO_MODULE

View file

@ -0,0 +1,56 @@
/*
* Copyright (C) 2010, 2011, 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef FEATURES_H
#define FEATURES_H
#include <QObject>
#include <QString>
#include <Module.h>
#include <utils/d_ptr.h>
#include <utils/nullptr.h>
/**
* Features object provides one interface for clients
* to access other objects' features
*/
class Features: public Module {
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.ActivityManager.Features")
public:
Features(QObject * parent = nullptr);
virtual ~Features();
public Q_SLOTS:
bool IsFeatureOperational(const QString & feature) const;
bool IsFeatureEnabled(const QString & feature) const;
void SetFeatureEnabled(const QString & feature, bool value);
QStringList ListFeatures(const QString & module) const;
private:
D_PTR;
};
#endif // FEATURES_H

View file

@ -0,0 +1,2 @@
#! /usr/bin/env bash
$XGETTEXT *.cpp -o $podir/kactivitymanagerd.pot

View file

@ -0,0 +1,95 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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 "Module.h"
#include <QHash>
#include <QString>
#include <QObject>
#include <QDebug>
#include <utils/d_ptr_implementation.h>
class Module::Private {
public:
static QHash < QString, QObject * > s_modules;
};
QHash < QString, QObject * > Module::Private::s_modules;
Module::Module(const QString & name, QObject * parent)
: QObject(parent), d()
{
registerModule(name, this);
}
void Module::registerModule(const QString & name, QObject * module) {
if (!name.isEmpty()) {
Private::s_modules[name] = module;
qDebug() << "Module " << name << "is registered";
}
}
Module::~Module()
{
}
QObject * Module::get(const QString & name)
{
Q_ASSERT(!name.isEmpty());
if (Private::s_modules.contains(name)) {
qDebug() << "Returning a valid module object for:" << name;
return Private::s_modules[name];
}
qDebug() << "The requested module doesn't exist:" << name;
return nullptr;
}
const QHash < QString, QObject * > Module::get()
{
return Private::s_modules;
}
bool Module::isFeatureEnabled(const QStringList & feature) const
{
Q_UNUSED(feature)
return false;
}
bool Module::isFeatureOperational(const QStringList & feature) const
{
Q_UNUSED(feature)
return false;
}
void Module::setFeatureEnabled(const QStringList & feature, bool value)
{
Q_UNUSED(feature)
Q_UNUSED(value)
}
QStringList Module::listFeatures(const QStringList & feature) const
{
Q_UNUSED(feature)
return QStringList();
}

View file

@ -0,0 +1,57 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef MODULE_H
#define MODULE_H
#include <QObject>
#include <QString>
#include <QStringList>
#include <utils/d_ptr.h>
#include <utils/nullptr.h>
#include <utils/override.h>
/**
* Module
*/
class Module: public QObject {
Q_OBJECT
public:
explicit Module(const QString & name, QObject * parent = nullptr);
virtual ~Module();
static QObject * get(const QString & name);
static const QHash < QString, QObject * > get();
virtual bool isFeatureOperational(const QStringList & feature) const;
virtual bool isFeatureEnabled(const QStringList & feature) const;
virtual void setFeatureEnabled(const QStringList & feature, bool value);
virtual QStringList listFeatures(const QStringList & feature) const;
protected:
static void registerModule(const QString & name, QObject * module);
private:
D_PTR;
};
#endif // MODULE_H

View file

@ -0,0 +1,79 @@
/*
* Copyright (C) 2011, 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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 "Plugin.h"
#include <QDebug>
#include <utils/nullptr.h>
#include <utils/d_ptr_implementation.h>
class Plugin::Private {
public:
Private()
: config(nullptr)
{
}
QString name;
KSharedConfig::Ptr config;
};
Plugin::Plugin(QObject * parent)
: Module(QString(), parent), d()
{
}
Plugin::~Plugin()
{
}
bool Plugin::init(const QHash < QString, QObject * > & modules)
{
Q_UNUSED(modules)
return true;
}
KConfigGroup Plugin::config()
{
if (d->name.isEmpty()) {
qWarning() << "The plugin needs a name in order to have a config section";
return KConfigGroup();
}
if (!d->config) {
d->config = KSharedConfig::openConfig("activitymanager-pluginsrc");
}
return d->config->group("Plugin-" + d->name);
}
void Plugin::setName(const QString & name)
{
Q_ASSERT_X(d->name.isEmpty(), "Plugin::setName", "The name can not be set twice");
Q_ASSERT_X(!name.isEmpty(), "Plugin::setName", "The name can not be empty");
d->name = name;
registerModule(name, this);
}
QString Plugin::name() const
{
return d->name;
}

View file

@ -0,0 +1,105 @@
/*
* Copyright (C) 2011, 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef PLUGIN_H
#define PLUGIN_H
#include <kdemacros.h>
#include <QObject>
#include <QMetaObject>
#include <KPluginFactory>
#include <KConfigGroup>
#include "Event.h"
#include "Module.h"
#include <utils/d_ptr.h>
#define KAMD_EXPORT_PLUGIN(ClassName, AboutData) \
K_PLUGIN_FACTORY(ClassName##Factory, registerPlugin<ClassName>();) \
K_EXPORT_PLUGIN(ClassName##Factory(AboutData))
/**
*
*/
class KDE_EXPORT Plugin: public Module {
Q_OBJECT
public:
Plugin(QObject * parent);
virtual ~Plugin();
/**
* Initializes the plugin.
* @arg modules Activities, Resources and Features manager objects
* @returns the plugin needs to return whether it has
* successfully been initialized
*/
virtual bool init(const QHash < QString, QObject * > & modules);
/**
* Returns the config group for the plugin.
* In order to use it, you need to set the plugin name.
*/
KConfigGroup config();
QString name() const;
/**
* Convenience meta-method to provide prettier invocation of QMetaObject::invokeMethod
*/
template <typename ReturnType, Qt::ConnectionType connection>
static ReturnType callOn(QObject * object, const char * method, const char * returnTypeName)
{
ReturnType result;
QMetaObject::invokeMethod(
object, method, connection,
QReturnArgument < ReturnType > (returnTypeName, result)
);
return result;
}
template <typename ReturnType, Qt::ConnectionType connection, typename... Args>
static ReturnType callOnWithArgs(QObject * object, const char * method, const char * returnTypeName, Args ... args)
{
ReturnType result;
QMetaObject::invokeMethod(
object, method, connection,
QReturnArgument < ReturnType > (returnTypeName, result),
args...
);
return result;
}
protected:
void setName(const QString & name);
private:
D_PTR;
};
#endif // PLUGIN_H

View file

@ -0,0 +1,339 @@
/*
* Copyright (C) 2010, 2011, 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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 "Resources.h"
#include "Resources_p.h"
#include "resourcesadaptor.h"
#include <QDBusConnection>
#include <QThread>
#include <QMutex>
#include <QMutexLocker>
#include <QDebug>
#include <KUrl>
#include <KWindowSystem>
#include <kdbusconnectionpool.h>
#include <Application.h>
#include <Activities.h>
#include <time.h>
#include "common.h"
#include <utils/d_ptr_implementation.h>
#include <utils/remove_if.h>
Resources::Private::Private(Resources * parent)
: QThread(parent), focussedWindow(0), q(parent)
{
}
namespace {
EventList events;
QMutex events_mutex;
}
void Resources::Private::run()
{
forever {
// initial delay before processing the events
sleep(5);
EventList currentEvents;
{
QMutexLocker locker(& events_mutex);
if (events.count() == 0) {
// qDebug() << "No more events to process, exiting.";
return;
}
currentEvents = events;
events.clear();
}
emit q->ProcessedResourceEvents(currentEvents);
}
}
void Resources::Private::insertEvent(const Event & newEvent)
{
if (lastEvent == newEvent) return;
lastEvent = newEvent;
{
QMutexLocker locker(& events_mutex);
events << newEvent;
}
emit q->RegisteredResourceEvent(newEvent);
}
void Resources::Private::addEvent(const QString & application, WId wid, const QString & uri,
int type, int reason)
{
Event newEvent(application, wid, uri, type, reason);
addEvent(newEvent);
}
void Resources::Private::addEvent(const Event & newEvent)
{
// And now, for something completely delayed
{
QMutexLocker locker(& events_mutex);
// Deleting previously registered Accessed events if
// the current one has the same application and uri
if (newEvent.type != Event::Accessed) {
kamd::utils::remove_if(events, [&newEvent] (const Event & event) -> bool {
return
event.reason == Event::Accessed &&
event.application == newEvent.application &&
event.uri == newEvent.uri
;
});
}
}
// Process the windowing
// Essentially, this is the brain of SLC. We need to track the
// window focus changes to be able to generate the potential
// missing events like FocussedOut before Closed and similar.
// So, there is no point in having the same logic in SLC plugin
// as well.
if (newEvent.wid != 0) {
WindowData & data = windows[newEvent.wid];
const KUrl & kuri(newEvent.uri);
qDebug() << kuri << data.focussedResource;
data.application = newEvent.application;
switch (newEvent.type) {
case Event::Opened:
insertEvent(newEvent);
if (data.focussedResource.isEmpty()) {
// This window haven't had anything focused,
// assuming the new document is focused
data.focussedResource = newEvent.uri;
insertEvent(newEvent.deriveWithType(Event::FocussedIn));
}
break;
case Event::FocussedIn:
if (!data.resources.contains(kuri)) {
// This window did not contain this resource before,
// sending Opened event
insertEvent(newEvent.deriveWithType(Event::Opened));
}
data.focussedResource = newEvent.uri;
insertEvent(newEvent);
break;
case Event::Closed:
qDebug() << data.focussedResource << kuri;
if (data.focussedResource == kuri) {
// If we are closing a document that is in focus,
// release focus first
insertEvent(newEvent.deriveWithType(Event::FocussedOut));
data.focussedResource.clear();
}
insertEvent(newEvent);
break;
case Event::FocussedOut:
if (data.focussedResource == kuri) {
data.focussedResource.clear();
}
insertEvent(newEvent);
break;
default:
insertEvent(newEvent);
break;
}
}
start();
}
void Resources::Private::windowClosed(WId windowId)
{
// Testing whether the window is a registered one
if (!windows.contains(windowId)) {
return;
}
if (focussedWindow == windowId) {
focussedWindow = 0;
}
// Closing all the resources that the window registered
foreach (const KUrl & uri, windows[windowId].resources) {
q->RegisterResourceEvent(windows[windowId].application,
toInt(windowId), uri.url(), Event::Closed, 0);
}
windows.remove(windowId);
}
void Resources::Private::activeWindowChanged(WId windowId)
{
// If the focused window has changed, we need to create a
// FocussedOut event for the resource it contains,
// and FocussedIn for the resource of the new active window.
// The windows can do this manually, but if they are
// SDI, we can do it on our own.
if (windowId == focussedWindow) return;
if (windows.contains(focussedWindow)) {
const WindowData & data = windows[focussedWindow];
if (!data.focussedResource.isEmpty()) {
insertEvent(Event(data.application, focussedWindow, data.focussedResource.url(), Event::FocussedOut));
}
}
focussedWindow = windowId;
if (windows.contains(focussedWindow)) {
const WindowData & data = windows[focussedWindow];
if (!data.focussedResource.isEmpty()) {
insertEvent(Event(data.application, windowId, data.focussedResource.url(), Event::FocussedIn));
}
}
}
Resources::Resources(QObject * parent)
: Module("resources", parent), d(this)
{
qRegisterMetaType < Event > ("Event");
qRegisterMetaType < EventList > ("EventList");
qRegisterMetaType < WId > ("WId");
new ResourcesAdaptor(this);
KDBusConnectionPool::threadConnection().registerObject(
ACTIVITY_MANAGER_OBJECT_PATH(Resources), this);
d->connect(KWindowSystem::self(), SIGNAL(windowRemoved(WId)),
SLOT(windowClosed(WId)));
d->connect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)),
SLOT(activeWindowChanged(WId)));
}
Resources::~Resources()
{
}
void Resources::RegisterResourceEvent(QString application, uint _windowId,
const QString & uri, uint event, uint reason)
{
Q_ASSERT_X(!uri.startsWith("nepomuk:"), "Resources::RegisterResourceEvent",
"We do not accept nepomuk URIs for resource events");
if (
event > Event::LastEventType
|| reason > Event::LastEventReason
|| uri.isEmpty()
|| application.isEmpty()
// Dirty way to skip special web browser URIs
// This is up to the plugin - whether it wants it filtered out or not
// || uri.startsWith(QLatin1String("about:"))
) return;
KUrl kuri(uri);
WId windowId = (WId) _windowId;
d->addEvent(application, windowId,
kuri.url(), (Event::Type) event, (Event::Reason) reason);
}
void Resources::RegisterResourceMimeType(const QString & uri, const QString & mimetype)
{
if (!mimetype.isEmpty()) return;
KUrl kuri(uri);
emit RegisteredResourceMimeType(uri, mimetype);
}
void Resources::RegisterResourceTitle(const QString & uri, const QString & title)
{
// A dirty saninty check for the title
if (title.length() < 3) return;
KUrl kuri(uri);
emit RegisteredResourceTitle(uri, title);
}
bool Resources::isFeatureOperational(const QStringList & feature) const
{
Q_UNUSED(feature)
return false;
}
bool Resources::isFeatureEnabled(const QStringList & feature) const
{
Q_UNUSED(feature)
return false;
}
void Resources::setFeatureEnabled(const QStringList & feature, bool value)
{
Q_UNUSED(feature)
Q_UNUSED(value)
}
QStringList Resources::listFeatures(const QStringList & feature) const
{
Q_UNUSED(feature)
static QStringList features;
return features;
}

View file

@ -0,0 +1,89 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef RESOURCES_H
#define RESOURCES_H
#include <QString>
#include <QStringList>
#include <Module.h>
#include <Event.h>
#include <utils/d_ptr.h>
#include <utils/nullptr.h>
/**
* Resources
*/
class Resources: public Module {
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.ActivityManager.Resources")
public:
Resources(QObject * parent = nullptr);
virtual ~Resources();
public Q_SLOTS:
/**
* Registers a new event
* @param application the name of application that sent the event. Ignored if the event is not of type Opened
* @param windowId ID of the window that displays the resource. Ignored if the event is of type Accessed
* @param uri URI of the resource on which the event happened
* @param event type of the event
* @param reason reason for opening the resource
*/
void RegisterResourceEvent(QString application, uint windowId, const QString & uri, uint event, uint reason);
/**
* Registers resource's mimetype. If not manually specified, it will
* be retrieved if needed from Nepomuk
*
* Note that this will be forgotten when the resource in question is closed.
* @param uri URI of the resource
*/
void RegisterResourceMimeType(const QString & uri, const QString & mimetype);
/**
* Registers resource's title. If not manually specified, it will be a shortened
* version of the uri
*
* Note that this will be forgotten when the resource in question is closed.
* @param uri URI of the resource
*/
void RegisterResourceTitle(const QString & uri, const QString & title);
Q_SIGNALS:
void RegisteredResourceEvent(const Event & event);
void ProcessedResourceEvents(const EventList & events);
void RegisteredResourceMimeType(const QString & uri, const QString & mimetype);
void RegisteredResourceTitle(const QString & uri, const QString & title);
public:
virtual bool isFeatureOperational(const QStringList & feature) const _override;
virtual bool isFeatureEnabled(const QStringList & feature) const _override;
virtual void setFeatureEnabled(const QStringList & feature, bool value) _override;
virtual QStringList listFeatures(const QStringList & feature) const _override;
private:
D_PTR;
};
#endif // RESOURCES_H

View file

@ -0,0 +1,73 @@
/*
* Copyright (C) 2010, 2011, 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef RESOURCES_P_H
#define RESOURCES_P_H
#include "Resources.h"
#include "resourcesadaptor.h"
#include <QString>
#include <QList>
#include <KUrl>
class Resources::Private: public QThread {
Q_OBJECT
public:
Private(Resources * parent);
void run();
// Inserts the event directly into the queue
void insertEvent(const Event & newEvent);
// Processes the event and inserts it into the queue
void addEvent(const QString & application, WId wid, const QString & uri,
int type, int reason);
// Processes the event and inserts it into the queue
void addEvent(const Event & newEvent);
QList <KUrl> resourcesLinkedToActivity(const QString & activity) const;
private Q_SLOTS:
// Reacting to window manager signals
void windowClosed(WId windowId);
void activeWindowChanged(WId windowId);
private:
struct WindowData {
QSet < KUrl > resources;
KUrl focussedResource;
QString application;
};
Event lastEvent;
// EventList events;
// QMutex events_mutex;
QHash < WId, WindowData > windows;
WId focussedWindow;
Resources * const q;
};
#endif // RESOURCES_P_H

View file

@ -0,0 +1,34 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#define ACTIVITY_MANAGER_SERVICE "org.kde.ActivityManager"
#define ACTIVITY_MANAGER_OBJECT_TYPE(A) ACTIVITY_MANAGER_SERVICE #A
#define ACTIVITY_MANAGER_OBJECT_PATH(A) "/ActivityManager/" #A
#include <qwindowdefs.h>
__inline int toInt(WId wid)
{
#ifdef Q_OS_WIN64 // krazy:skip
return (int)((__int64)wid);
#else
return (int)wid;
#endif
}

View file

@ -0,0 +1,58 @@
[Desktop Entry]
Type=ServiceType
X-KDE-ServiceType=ActivityManager/Plugin
Comment=Activity manager plugin
Comment[bs]=Priključak za praćenje aktivnosti
Comment[ca]=Connector del gestor d'activitats
Comment[ca@valencia]=Connector del gestor d'activitats
Comment[cs]=Modul Správce aktivit
Comment[da]=Aktivitetshåndtering-plugin
Comment[de]=Modul für Aktivitätenverwaltung
Comment[el]=Πρόσθετο διαχειριστή δραστηριοτήτων
Comment[en_GB]=Activity manager plugin
Comment[es]=Complemento del gestor de actividades
Comment[et]=Tegevuste haldamise plugin
Comment[eu]=Jarduera kudeatzailearen plugina
Comment[fi]=Aktiviteettihallintaliitännäinen
Comment[fr]=Module externe de gestionnaire d'activités
Comment[ga]=Breiseán bainisteora gníomhaíochta
Comment[gl]=Complemento de xestión da actividade
Comment[he]=תוסף מנהל פעילויות
Comment[hu]=Aktivitáskezelő bővítmény
Comment[ia]=Plugin de gerente de activitate
Comment[is]=Virknistjórnunarviðbót
Comment[it]=Estensione di gestione delle attività
Comment[kk]=Белсенділік менеджер плагині
Comment[km]=
Comment[ko]=
Comment[lt]=Veiklų tvarkyklės priedas
Comment[mr]=
Comment[nb]=Programtillegg for aktivitetsbehandler
Comment[nds]=Aktivitetenpleger-Moduul
Comment[nl]=Plug-in van activiteitenbeheerder
Comment[pa]=ਿ
Comment[pl]=Wtyczka menadżera działań
Comment[pt]='Plugin' de gestão de actividades
Comment[pt_BR]=Plugin do gerenciador de atividades
Comment[ro]=Extensie pentru gestionarul de activități
Comment[ru]=Расширение «Диспетчер комнат»
Comment[se]=Lassemodula aktivitehtagieđahallamii
Comment[sk]=Plugin správcu aktivít
Comment[sl]=Vstavek upravljalnika dejavnosti
Comment[sr]=Прикључак менаџера активности
Comment[sr@ijekavian]=Прикључак менаџера активности
Comment[sr@ijekavianlatin]=Priključak menadžera aktivnosti
Comment[sr@latin]=Priključak menadžera aktivnosti
Comment[sv]=Insticksprogram för aktivitetshantering
Comment[tg]=Плагини мудири фаъолият
Comment[tr]=Etkinlik yöneticisi eklentisi
Comment[ug]=پائالىيەت باشقۇرغۇچ قىستۇرمىسى
Comment[uk]=Додаток керування просторами дій
Comment[x-test]=xxActivity manager pluginxx
Comment[zh_CN]=
Comment[zh_TW]=
[PropertyDef::X-ActivityManager-PluginOverrides]
Type=QString

View file

@ -0,0 +1,109 @@
[Desktop Entry]
Type=Service
Icon=preferences-activities
X-KDE-ServiceTypes=
X-DBUS-StartupType=Unique
X-KDE-StartupNotify=false
Exec=kactivitymanagerd
Name=Activity Manager
Name[bs]=Menadžer aktivnosti
Name[ca]=Gestor d'activitats
Name[ca@valencia]=Gestor d'activitats
Name[cs]=Správce aktivit
Name[da]=Aktivitetshåndtering
Name[de]=Aktivitätenverwaltung
Name[el]=Διαχειριστής δραστηριοτήτων
Name[en_GB]=Activity Manager
Name[es]=Gestor de actividades
Name[et]=Tegevuste haldur
Name[eu]=Jarduera kudeatzailea
Name[fi]=Aktiviteettienhallinta
Name[fr]=Gestionnaire d'activités
Name[ga]=Bainisteoir Gníomhaíochta
Name[gl]=Xestor da actividade
Name[he]=מנהל פעילויות
Name[hu]=Aktivitáskezelő
Name[ia]=Gerente de activitate
Name[is]=Virknistjóri
Name[it]=Gestore delle attività
Name[kk]=Белсенділік менеджері
Name[km]=
Name[ko]=
Name[lt]=Veiklų tvarkyklė
Name[mr]=
Name[nb]=Aktivitetsbehandler
Name[nds]=Aktivitetenpleger
Name[nl]=Activiteitenbeheerder
Name[pa]=ਿ
Name[pl]=Menadżer działań
Name[pt]=Gestor de Actividades
Name[pt_BR]=Gerenciador de atividades
Name[ro]=Gestionar de activități
Name[ru]=Диспетчер комнат
Name[se]=Aktivitehtagieđahalli
Name[sk]=Správca aktivít
Name[sl]=Upravljalnik dejavnosti
Name[sr]=Менаџер активности
Name[sr@ijekavian]=Менаџер активности
Name[sr@ijekavianlatin]=Menadžer aktivnosti
Name[sr@latin]=Menadžer aktivnosti
Name[sv]=Aktivitetshanterare
Name[tg]=Мудири фаъолият
Name[tr]=Etkinlik Yöneticisi
Name[ug]=پائالىيەت باشقۇرغۇچ
Name[uk]=Керування просторами дій
Name[x-test]=xxActivity Managerxx
Name[zh_CN]=
Name[zh_TW]=
Comment=The activity management backend
Comment[bs]=Pozadina za upravljanje aktivnostima
Comment[ca]=Dorsal de gestió d'activitats
Comment[ca@valencia]=Dorsal de gestió d'activitats
Comment[cs]=Podpůrná vrstva pro správu aktivit
Comment[da]=Motor til aktivitetshåndtering
Comment[de]=Backend der Aktivitätenverwaltung
Comment[el]=Το σύστημα υποστήριξης διαχείρισης δραστηριοτήτων
Comment[en_GB]=The activity management backend
Comment[es]=El motor de la gestión de actividades
Comment[et]=Tegevuste haldamise taustaprogramm
Comment[eu]=Jarduera kudeaketa 'backend'
Comment[fi]=Aktiviteettihallintataustaohjelma
Comment[fr]=Le moteur de gestion d'activités
Comment[ga]=Inneall bainisteoireachta gníomhaíochta
Comment[gl]=A infraestrutura de xestión da actividade
Comment[he]=מנוע ניהול הפעילויות
Comment[hu]=Aktivitáskezelő modul
Comment[ia]=Le retro-administration de gestion de activitate
Comment[is]=Stýringarkerfi fyrir virkni
Comment[it]=Il motore di gestione delle attività
Comment[kk]=Белсенділікті басқару бағдарламасы
Comment[km]=
Comment[ko]=
Comment[lt]=Veiklos tvarkymo sąsaja
Comment[mr]=
Comment[nb]=Bakgrunnsmotoren for aktivitetsbehandling
Comment[nds]=Hülpprogramm för den Aktivitetenpleger
Comment[nl]=De activiteitenbeheerder-backend
Comment[pa]=ਿ ਿ
Comment[pl]=Silnik zarządzania działaniami
Comment[pt]=A infra-estrutura de gestão de actividades
Comment[pt_BR]=Infraestrutura de gerenciamento de atividades
Comment[ro]=Suport pentru administrare activități
Comment[ru]=Механизм управления комнатами
Comment[se]=Aktivitehtagieđahallama duogášmohtor
Comment[sk]=Backend pre správu aktivít
Comment[sl]=Zaledje za upravljanje z dejavnostmi
Comment[sr]=Позадина за управљање активностима
Comment[sr@ijekavian]=Позадина за управљање активностима
Comment[sr@ijekavianlatin]=Pozadina za upravljanje aktivnostima
Comment[sr@latin]=Pozadina za upravljanje aktivnostima
Comment[sv]=Gränssnittet för aktivitetshanteringen
Comment[tg]=Сервери идоракунии фаъолият
Comment[tr]=Etkinlik yönetimi arkaucu
Comment[ug]=پائالىيەت باشقۇرغۇچ ئارقا ئۇچى
Comment[uk]=Сервер керування просторами дій
Comment[x-test]=xxThe activity management backendxx
Comment[zh_CN]=
Comment[zh_TW]=

View file

@ -0,0 +1,55 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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 "Job.h"
#include <QDebug>
#include <utils/d_ptr_implementation.h>
class Job::Private {
public:
static QObject * s_global;
};
QObject * Job::Private::s_global = nullptr;
Job::Job(QObject * parent)
:KJob(parent), d()
{
}
Job::~Job()
{
}
void Job::init()
{
}
QObject * Job::global()
{
if (!Private::s_global) {
Private::s_global = new QObject();
}
return Private::s_global;
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef JOBS_JOB_H
#define JOBS_JOB_H
#include <KJob>
#include <utils/override.h>
#include <utils/nullptr.h>
#include <utils/d_ptr.h>
/**
* Job
*/
class Job: public KJob {
Q_OBJECT
public:
Job(QObject * parent = nullptr);
virtual ~Job();
virtual void init();
static QObject * global();
private:
D_PTR;
};
#endif // JOBS_JOB_H

View file

@ -0,0 +1,97 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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 "JobFactory.h"
#include <QString>
#include <QVariant>
#include <QHash>
#include <QDebug>
#include <utils/d_ptr_implementation.h>
class JobFactory::Private {
public:
QHash < QString, QVariant > properties;
};
JobFactory::JobFactory()
: d()
{
}
JobFactory::~JobFactory()
{
}
void JobFactory::setProperty(const QString & key, const QVariant & value)
{
d->properties[key] = value;
}
void JobFactory::clearProperty(const QString & key)
{
d->properties.remove(key);
}
void JobFactory::property(const QString & key) const
{
d->properties[key];
}
Job * JobFactory::create(QObject * parent)
{
Job * result = createJob(parent);
QHashIterator < QString, QVariant > i(d->properties);
while (i.hasNext()) {
i.next();
result->setProperty(i.key().toAscii(), i.value());
}
return result;
}
class JobFactoryWrapper: public JobFactory {
public:
JobFactoryWrapper(Job * job)
: m_job(job)
{
}
protected:
virtual Job * createJob(QObject * parent) _override
{
m_job->setParent(parent);
return m_job;
}
private:
Job * m_job;
};
JobFactory * JobFactory::wrap(Job * job)
{
return new JobFactoryWrapper(job);
}
// class JobFactory

View file

@ -0,0 +1,69 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef JOBS_JOB_FACTORY_H
#define JOBS_JOB_FACTORY_H
#include "Job.h"
#include <QVariant>
#include <utils/d_ptr.h>
#define DECLARE_JOB_FACTORY(Type, ConstructorParams) \
Type(QObject * parent) \
:Job(parent) \
{ init(); } \
class Factory: public JobFactory { \
public: \
Factory ConstructorParams ; \
Job * createJob(QObject * parent) { \
return new Type(parent); \
} \
}
#define JOB_FACTORY Factory::Factory
#define JOB_FACTORY_PROPERTY(PropertyName) \
setProperty(#PropertyName, QVariant::fromValue(PropertyName))
/**
* JobFactory
*/
class JobFactory {
public:
JobFactory();
virtual ~JobFactory();
virtual Job * create(QObject * parent);
void setProperty(const QString & key, const QVariant & value);
void clearProperty(const QString & key);
void property(const QString & key) const;
static JobFactory * wrap(Job * job);
protected:
virtual Job * createJob(QObject * parent) = 0;
private:
D_PTR;
};
#endif // JOBS_JOB_FACTORY_H

View file

@ -0,0 +1,73 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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 "Change.h"
#include <QDebug>
namespace Jobs {
namespace Activity {
Change::JOB_FACTORY(QObject * receiver, const QString & slot, const QString & activity)
{
JOB_FACTORY_PROPERTY(receiver);
JOB_FACTORY_PROPERTY(slot);
JOB_FACTORY_PROPERTY(activity);
}
QString Change::activity() const
{
return m_activity;
}
void Change::setActivity(const QString & activity)
{
m_activity = activity;
}
void Change::setReceiver(QObject * receiver)
{
m_receiver = receiver;
}
void Change::setSlot(const QString & slot)
{
m_slot = slot;
}
void Change::start()
{
if (m_receiver) {
qDebug() << ">>> Calling the method to set activity" << m_activity << "slot" << m_slot;
bool ret = QMetaObject::invokeMethod(m_receiver, m_slot.toAscii(), Qt::QueuedConnection, Q_ARG(QString, m_activity));
qDebug() << ret;
} else {
qDebug() << ">>> Receiver is nullptr, failing";
setError(1);
setErrorText("There is no receiver registered to signal the change activity");
}
emit emitResult();
}
} // namespace Activity
} // namespace Jobs

View file

@ -0,0 +1,71 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef JOBS_ACTIVITY_START_H
#define JOBS_ACTIVITY_START_H
#include "../Job.h"
#include "../JobFactory.h"
namespace Jobs {
namespace Activity {
/**
* Change
*/
class Change: public Job {
Q_OBJECT
Q_PROPERTY(QObject * receiver WRITE setReceiver)
Q_PROPERTY(QString slot WRITE setSlot)
Q_PROPERTY(QString activity READ activity WRITE setActivity)
public:
enum Type {
Information,
Warning,
Error
};
DECLARE_JOB_FACTORY(Change, (QObject * receiver, const QString & slot, const QString & activity));
QString activity() const;
void setActivity(const QString & activity);
void setReceiver(QObject * receiver);
void setSlot(const QString & slot);
virtual void start() _override;
private:
QObject * m_receiver;
QString m_slot;
QString m_activity;
};
inline Change::Factory * change(QObject * receiver, const QString & slot, const QString & activity)
{
return new Change::Factory(receiver, slot, activity);
}
} // namespace Activity
} // namespace Jobs
#endif // JOBS_ACTIVITY_START_H

View file

@ -0,0 +1,26 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef JOBS_ACTIVITY_ALL_H
#define JOBS_ACTIVITY_ALL_H
#include "Start.h"
#endif // JOBS_ACTIVITY_ALL_H

View file

@ -0,0 +1,96 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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 "Call.h"
#include <QDebug>
namespace Jobs {
namespace General {
Call::JOB_FACTORY(QObject * receiver, const QString & slot, const QString & argument, bool waitFinished)
{
JOB_FACTORY_PROPERTY(receiver);
JOB_FACTORY_PROPERTY(slot);
JOB_FACTORY_PROPERTY(argument);
JOB_FACTORY_PROPERTY(waitFinished);
}
QString Call::argument() const
{
return m_argument;
}
void Call::setArgument(const QString & argument)
{
m_argument = argument;
}
void Call::setReceiver(QObject * receiver)
{
m_receiver = receiver;
}
void Call::setSlot(const QString & slot)
{
m_slot = slot;
}
QObject * Call::receiver() const
{
return m_receiver;
}
QString Call::slot() const
{
return m_slot;
}
bool Call::waitFinished() const
{
return m_waitFinished;
}
void Call::setWaitFinished(bool value)
{
m_waitFinished = value;
}
void Call::start()
{
if (m_receiver) {
qDebug() << ">>> Calling the method" << m_slot << "with" << m_argument;
QMetaObject::invokeMethod(m_receiver, m_slot.toAscii(),
(m_waitFinished ? Qt::QueuedConnection : Qt::DirectConnection),
Q_ARG(QString, m_argument));
} else {
qDebug() << ">>> Receiver is nullptr, failing";
setError(1);
setErrorText("There is no receiver registered to call");
}
emit emitResult();
}
} // namespace General
} // namespace Jobs

View file

@ -0,0 +1,80 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef JOBS_GENERAL_CALL_H
#define JOBS_GENERAL_CALL_H
#include "../Job.h"
#include "../JobFactory.h"
namespace Jobs {
namespace General {
/**
* Call
*/
class Call: public Job {
Q_OBJECT
Q_PROPERTY(QObject * receiver READ receiver WRITE setReceiver)
Q_PROPERTY(QString slot READ slot WRITE setSlot)
Q_PROPERTY(QString argument READ argument WRITE setArgument)
Q_PROPERTY(bool waitFinished READ waitFinished WRITE setWaitFinished)
public:
enum Type {
Information,
Warning,
Error
};
DECLARE_JOB_FACTORY(Call, (QObject * receiver, const QString & slot, const QString & argument, bool waitFinished));
QString argument() const;
void setArgument(const QString & argument);
void setReceiver(QObject * receiver);
QObject * receiver() const;
void setSlot(const QString & slot);
QString slot() const;
void setWaitFinished(bool value);
bool waitFinished() const;
virtual void start() _override;
private:
QObject * m_receiver;
QString m_slot;
QString m_argument;
bool m_waitFinished;
};
inline Call::Factory * call(QObject * receiver, const QString & slot,
const QString & argument, bool waitFinished = false)
{
return new Call::Factory(receiver, slot, argument, waitFinished);
}
} // namespace General
} // namespace Jobs
#endif // JOBS_GENERAL_CALL_H

View file

@ -0,0 +1,26 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef JOBS_GENERAL_ALL_H
#define JOBS_GENERAL_ALL_H
#include "Call.h"
#endif // JOBS_GENERAL_ALL_H

View file

@ -0,0 +1,265 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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 "KSMServer.h"
#include "KSMServer_p.h"
#include <QDBusConnection>
#include <QDBusServiceWatcher>
#include <QDBusInterface>
#include <QDBusPendingReply>
#include <QDBusPendingCallWatcher>
#include <QDebug>
#include <kdbusconnectionpool.h>
#include <utils/d_ptr_implementation.h>
#include <utils/val.h>
#define KWIN_SERVICE "org.kde.kwin"
#define KSMSERVER_SERVICE "org.kde.ksmserver"
KSMServer::Private::Private(KSMServer * parent)
: serviceWatcher(nullptr),
kwin(nullptr),
ksmserver(nullptr),
processing(false),
q(parent)
{
serviceWatcher = new QDBusServiceWatcher(this);
serviceWatcher->setConnection(KDBusConnectionPool::threadConnection());
serviceWatcher->addWatchedService(KWIN_SERVICE);
serviceWatcher->addWatchedService(KSMSERVER_SERVICE);
connect(serviceWatcher, SIGNAL(serviceOwnerChanged(QString, QString, QString)),
this, SLOT(serviceOwnerChanged(QString, QString, QString)));
serviceOwnerChanged(KWIN_SERVICE, QString(), QString());
serviceOwnerChanged(KSMSERVER_SERVICE, QString(), QString());
}
template < typename Func >
static void initializeInterface(QDBusInterface * & service,
const QString & servicePath, const QString & path, const QString & object, Func init)
{
// Delete the old object, just in case
delete service;
// Creating the new dbus interface
service = new QDBusInterface(servicePath, path, object);
qDebug() << path << "is valid?" << service->isValid();
// If the service is valid, initialize it
// otherwise delete the object
if (service->isValid()) {
init(service);
} else {
delete service;
service = nullptr;
}
}
void KSMServer::Private::serviceOwnerChanged(const QString & service,
const QString & oldOwner, const QString & newOwner)
{
Q_UNUSED(oldOwner);
Q_UNUSED(newOwner);
if (service == KSMSERVER_SERVICE) {
initializeInterface(
ksmserver,
KSMSERVER_SERVICE, "/KSMServer", "org.kde.KSMServerInterface",
[this] (QObject * service) {
service->setParent(this);
connect(service, SIGNAL(subSessionOpened()),
this, SLOT(subSessionOpened()));
connect(service, SIGNAL(subSessionClosed()),
this, SLOT(subSessionClosed()));
connect(service, SIGNAL(subSessionCloseCanceled()),
this, SLOT(subSessionCloseCanceled()));
}
);
} else if (service == KWIN_SERVICE) {
initializeInterface(
kwin,
KWIN_SERVICE, "/KWin", "org.kde.KWin",
[this] (QObject * service) {
service->setParent(this);
}
);
}
}
KSMServer::KSMServer(QObject * parent)
: QObject(parent), d(this)
{
}
KSMServer::~KSMServer()
{
}
void KSMServer::startActivitySession(const QString & activity)
{
d->processLater(activity, true);
}
void KSMServer::stopActivitySession(const QString & activity)
{
d->processLater(activity, false);
}
void KSMServer::Private::processLater(const QString & activity, bool start)
{
qDebug() << "Scheduling" << activity << "to be" << (start ? "started" : "stopped");
foreach (val & item, queue) {
if (item.first == activity) {
return;
}
}
queue << qMakePair(activity, start);
if (!processing) {
processing = true;
QMetaObject::invokeMethod(this, "process", Qt::QueuedConnection);
}
}
void KSMServer::Private::process()
{
// If the queue is empty, we have nothing more to do
if (queue.isEmpty()) {
processing = false;
return;
}
val item = queue.takeFirst();
processingActivity = item.first;
qDebug() << "Processing" << item;
makeRunning(item.second);
// Calling process again for the rest of the list
QMetaObject::invokeMethod(this, "process", Qt::QueuedConnection);
}
void KSMServer::Private::makeRunning(bool value)
{
if (!kwin) {
qDebug() << "There is no KWin";
subSessionSendEvent(value ? KSMServer::Started : KSMServer::Stopped);
return;
}
val call = kwin->asyncCall(
value ? QLatin1String("startActivity") : QLatin1String("stopActivity"),
processingActivity);
val watcher = new QDBusPendingCallWatcher(call, this);
QObject::connect(
watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
this,
value
? SLOT(startCallFinished(QDBusPendingCallWatcher*))
: SLOT(stopCallFinished(QDBusPendingCallWatcher*))
);
}
void KSMServer::Private::startCallFinished(QDBusPendingCallWatcher * call)
{
QDBusPendingReply < bool > reply = * call;
if (reply.isError()) {
qDebug() << "Session starting call failed, but we are returning success";
emit q->activitySessionStateChanged(processingActivity, KSMServer::Started);
} else {
// If we got false, it means something is going on with ksmserver
// and it didn't start our activity
val retval = reply.argumentAt<0>();
qDebug() << "Did we start the activity successfully:" << retval;
if (!retval) {
subSessionSendEvent(KSMServer::Stopped);
}
}
call->deleteLater();
}
void KSMServer::Private::stopCallFinished(QDBusPendingCallWatcher * call)
{
QDBusPendingReply < bool > reply = * call;
if (reply.isError()) {
qDebug() << "Session stopping call failed, but we are returning success";
emit q->activitySessionStateChanged(processingActivity, KSMServer::Stopped);
} else {
// If we got false, it means something is going on with ksmserver
// and it didn't stop our activity
val retval = reply.argumentAt<0>();
qDebug() << "Did we stop the activity successfully:" << retval;
if (!retval) {
subSessionSendEvent(KSMServer::FailedToStop);
}
}
call->deleteLater();
}
void KSMServer::Private::subSessionSendEvent(int event)
{
if (processingActivity.isEmpty()) return;
emit q->activitySessionStateChanged(processingActivity, event);
processingActivity.clear();
}
void KSMServer::Private::subSessionOpened()
{
subSessionSendEvent(KSMServer::Started);
}
void KSMServer::Private::subSessionClosed()
{
subSessionSendEvent(KSMServer::Stopped);
}
void KSMServer::Private::subSessionCloseCanceled()
{
subSessionSendEvent(KSMServer::FailedToStop);
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef KSMSERVER_H
#define KSMSERVER_H
#include <QObject>
#include <utils/d_ptr.h>
#include <utils/nullptr.h>
/**
* KSMServer
*/
class KSMServer: public QObject {
Q_OBJECT
public:
enum ReturnStatus {
Started = 0,
Stopped = 1,
FailedToStop = 2
};
KSMServer(QObject * parent = nullptr);
virtual ~KSMServer();
public Q_SLOTS:
void startActivitySession(const QString & activity);
void stopActivitySession(const QString & activity);
Q_SIGNALS:
void activitySessionStateChanged(const QString & activity, int status);
private:
D_PTR;
};
#endif // KSMSERVER_H

View file

@ -0,0 +1,65 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef KSMSERVER_P_H
#define KSMSERVER_P_H
#include "KSMServer.h"
#include <QPair>
class QDBusServiceWatcher;
class QDBusInterface;
class QDBusPendingCallWatcher;
class KSMServer::Private: public QObject {
Q_OBJECT
public:
Private(KSMServer * parent);
void processLater(const QString & activity, bool start);
private Q_SLOTS:
void serviceOwnerChanged(const QString & service, const QString & oldOwner, const QString & newOwner);
void process();
void makeRunning(bool value);
void startCallFinished(QDBusPendingCallWatcher * watcher);
void stopCallFinished(QDBusPendingCallWatcher * watcher);
void subSessionOpened();
void subSessionClosed();
void subSessionCloseCanceled();
void subSessionSendEvent(int event);
private:
QDBusServiceWatcher * serviceWatcher;
QDBusInterface * kwin;
QDBusInterface * ksmserver;
bool processing;
QString processingActivity;
QList < QPair < QString, bool > > queue;
KSMServer * const q;
};
#endif // KSMSERVER_P_H

View file

@ -0,0 +1,133 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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 "Abstract.h"
#include "Abstract_p.h"
#include <QDebug>
#include <utils/d_ptr_implementation.h>
namespace Jobs {
namespace Schedulers {
Abstract::Private::Private(Abstract * parent)
: q(parent)
{
}
void Abstract::Private::jobFinished(KJob * job)
{
qDebug() << "Job has finished with this result" << job->error();
q->jobFinished(job->error());
}
bool Abstract::startJob(int index)
{
d->lastJobStarted = index;
// If the index is not valid
if (index < 0 || d->jobs.size() <= index) {
returnResult(0);
return false;
}
JobFactory * factory = d->jobs[index];
// If the job factory is null, exit
if (!factory) {
returnResult(0);
return false;
}
// Starting the job
KJob * job = d->jobs[index]->create(this);
d->connect(job, SIGNAL(finished(KJob *)),
SLOT(jobFinished(KJob *)));
job->start();
return true;
}
Abstract::Abstract(QObject * parent)
: Job(parent), d(this)
{
d->lastJobStarted = -1;
if (!parent) {
connect(
this, SIGNAL(finished(KJob *)),
this, SLOT(deleteLater()),
Qt::QueuedConnection
);
}
}
Abstract::~Abstract()
{
qDeleteAll(d->jobs);
}
void Abstract::addJob(Job * other)
{
d->jobs << JobFactory::wrap(other);
}
void Abstract::addJob(JobFactory * other)
{
d->jobs << other;
}
void Abstract::start()
{
if (d->jobs.size() == 0) {
returnResult(0);
return;
}
startJob(0);
}
int Abstract::lastJobStarted() const
{
return d->lastJobStarted;
}
int Abstract::jobCount() const
{
return d->jobs.size();
}
bool Abstract::hasJob(int index) const
{
return (index >= 0 && index < d->jobs.size() && d->jobs[index] != nullptr);
}
void Abstract::returnResult(int result)
{
qDebug() << "Returning" << result;
setError(result);
emitResult();
}
} // namespace Schedulers
} // namespace Jobs

View file

@ -0,0 +1,69 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef JOBS_SCHEDULER_ABSTRACT_H
#define JOBS_SCHEDULER_ABSTRACT_H
#include <jobs/Job.h>
#include <jobs/JobFactory.h>
#include <utils/d_ptr.h>
namespace Jobs {
namespace Schedulers {
/**
* Abstract
*/
class Abstract: public Job {
Q_OBJECT
public:
Abstract(QObject * parent = nullptr);
virtual ~Abstract();
virtual void start() _override;
protected:
bool startJob(int index);
virtual void jobFinished(int result) = 0;
int lastJobStarted() const;
int jobCount() const;
bool hasJob(int index) const;
void addJob(JobFactory * job);
void addJob(Job * job);
void returnResult(int result);
private:
Abstract(const Abstract & original);
Abstract & operator = (const Abstract & original);
D_PTR;
};
// class Abstract
} // namespace Schedulers
} // namespace Jobs
#endif // JOBS_SCHEDULER_ABSTRACT_H

View file

@ -0,0 +1,48 @@
/*
* Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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.
*/
#ifndef JOBS_SCHEDULER_ABSTRACT_P_H
#define JOBS_SCHEDULER_ABSTRACT_P_H
#include "Abstract.h"
#include <QList>
namespace Jobs {
namespace Schedulers {
class Abstract::Private: public QObject {
Q_OBJECT
public:
Private(Abstract * parent);
QList < JobFactory * > jobs;
int lastJobStarted;
public Q_SLOTS:
void jobFinished(KJob * job);
public:
Abstract * const q;
};
} // namespace Schedulers
} // namespace Jobs
#endif // JOBS_SCHEDULER_ABSTRACT_P_H

Some files were not shown because too many files have changed in this diff Show more