diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0e6085f --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/kde-workspace-4.11.19.tar.xz diff --git a/.kde-workspace.metadata b/.kde-workspace.metadata new file mode 100644 index 0000000..772fee6 --- /dev/null +++ b/.kde-workspace.metadata @@ -0,0 +1 @@ +2ab5b46aa7189efd6371461dd3f0bc2513fa560c SOURCES/kde-workspace-4.11.19.tar.xz diff --git a/SOURCES/fedora-plasma-cache.sh b/SOURCES/fedora-plasma-cache.sh new file mode 100755 index 0000000..5428fab --- /dev/null +++ b/SOURCES/fedora-plasma-cache.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +if [ "`kreadconfig --file fedora-plasma-cacherc --group General --key FirstRun --default true`" = "true" ]; then + rm -fv "`kde4-config --path cache`/"*.kcache + rm -fv "`kde4-config --path cache`/"plasma-svgelements-* + #rm -fv ${XDG_CONFIG_HOME-${HOME}/.config}/Trolltech.conf + kwriteconfig --file fedora-plasma-cacherc --group General --key FirstRun --type bool false +fi diff --git a/SOURCES/kde-workspace-4.10-bz#921742.patch b/SOURCES/kde-workspace-4.10-bz#921742.patch new file mode 100644 index 0000000..0433650 --- /dev/null +++ b/SOURCES/kde-workspace-4.10-bz#921742.patch @@ -0,0 +1,118 @@ +diff --git a/powerdevil/daemon/powerdevilactionpool.cpp b/powerdevil/daemon/powerdevilactionpool.cpp +index 970aa18..6ca0d57 100644 +--- a/powerdevil/daemon/powerdevilactionpool.cpp ++++ b/powerdevil/daemon/powerdevilactionpool.cpp +@@ -82,6 +82,7 @@ void ActionPool::clearCache() + i.value()->deleteLater(); + i = m_actionPool.erase(i); + } ++ m_initErrors.clear(); + } + + void ActionPool::init(PowerDevil::Core *parent) +@@ -99,6 +100,7 @@ void ActionPool::init(PowerDevil::Core *parent) + if (!retaction) { + // Troubles... + kWarning() << "failed to load" << offer->desktopEntryName(); ++ m_initErrors.insert(actionId, LoadFailed); + continue; + } + +@@ -106,6 +108,7 @@ void ActionPool::init(PowerDevil::Core *parent) + if (!retaction->isSupported()) { + // Skip that + retaction->deleteLater(); ++ m_initErrors.insert(actionId, NotSupported); + continue; + } + +@@ -169,7 +172,13 @@ Action* ActionPool::loadAction(const QString& actionId, const KConfigGroup& grou + + return retaction; + } else { +- // Hmm... troubles in configuration. Np, let's just return 0 and let the core handle this ++ // may be a misconfiguration. ++ // Set the error code and return 0 and let the caller handle this as it sees fit ++ if (m_initErrors.contains(actionId)) { ++ m_error = m_initErrors[actionId]; ++ } else { // no error recorded during initialisation, therefore action does not exist ++ m_error = NoAction; ++ } + return 0; + } + } +@@ -183,4 +192,9 @@ void ActionPool::unloadAllActiveActions() + m_activeActions.clear(); + } + ++ActionPool::ErrorCode ActionPool::error() ++{ ++ return m_error; ++} ++ + } +diff --git a/powerdevil/daemon/powerdevilactionpool.h b/powerdevil/daemon/powerdevilactionpool.h +index ca436ff..816449e 100644 +--- a/powerdevil/daemon/powerdevilactionpool.h ++++ b/powerdevil/daemon/powerdevilactionpool.h +@@ -36,6 +36,11 @@ class Action; + class KDE_EXPORT ActionPool + { + public: ++ enum ErrorCode { ++ NoAction, ++ LoadFailed, ++ NotSupported ++ }; + static ActionPool *instance(); + + virtual ~ActionPool(); +@@ -48,11 +53,15 @@ public: + + void clearCache(); + ++ ErrorCode error(); ++ + private: + ActionPool(); + + QHash< QString, Action* > m_actionPool; + QStringList m_activeActions; ++ ErrorCode m_error; ++ QHash< QString, ErrorCode > m_initErrors; + }; + + } +diff --git a/powerdevil/daemon/powerdevilcore.cpp b/powerdevil/daemon/powerdevilcore.cpp +index d096d74..c35b29d 100644 +--- a/powerdevil/daemon/powerdevilcore.cpp ++++ b/powerdevil/daemon/powerdevilcore.cpp +@@ -357,11 +357,23 @@ void Core::loadProfile(bool force) + if (action) { + action->onProfileLoad(); + } else { +- // Ouch, error. But let's just warn and move on anyway +- //TODO Maybe Remove from the configuration if unsupported +- kWarning() << "The profile " << profileId << "tried to activate" +- << actionName << "a non existent action. This is usually due to an installation problem" +- " or to a configuration problem. or simlpy the action is not supported"; ++ switch (ActionPool::instance()->error()) { ++ case ActionPool::NotSupported: ++ kWarning().nospace() << "Attempted to load unsupported action " << actionName ++ << ", skipping"; ++ break; ++ case ActionPool::LoadFailed: ++ kWarning() << "Action" << actionName << "failed during initialisation"; ++ // fallthrough ++ case ActionPool::NoAction: ++ default: ++ // Ouch, error. But let's just warn and move on anyway ++ //TODO Maybe Remove from the configuration if unsupported ++ kWarning() << "The profile " << profileId << "tried to activate" ++ << actionName << "a non existent action. This is usually due to an installation problem" ++ " or to a configuration problem. or simlpy the action is not supported"; ++ break; ++ } + } + } + diff --git a/SOURCES/kde-workspace-4.10.2-BUILD_KCM_RANDR.patch b/SOURCES/kde-workspace-4.10.2-BUILD_KCM_RANDR.patch new file mode 100644 index 0000000..5aaf976 --- /dev/null +++ b/SOURCES/kde-workspace-4.10.2-BUILD_KCM_RANDR.patch @@ -0,0 +1,16 @@ +diff -up kde-workspace-4.10.2/kcontrol/CMakeLists.txt.BUILD_KCM_RANDR kde-workspace-4.10.2/kcontrol/CMakeLists.txt +--- kde-workspace-4.10.2/kcontrol/CMakeLists.txt.BUILD_KCM_RANDR 2013-03-01 00:32:25.040847159 -0600 ++++ kde-workspace-4.10.2/kcontrol/CMakeLists.txt 2013-04-18 08:58:31.086753204 -0500 +@@ -6,9 +6,10 @@ macro_log_feature(FREETYPE_FOUND "FreeTy + set(libkxftconfig_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/fonts/kxftconfig.cpp ) + + +-if( X11_Xrandr_FOUND ) ++OPTION(BUILD_KCM_RANDR "Build kcontrol/randr module" ON) ++if(BUILD_KCM_RANDR AND X11_Xrandr_FOUND) + add_subdirectory( randr ) +-endif(X11_Xrandr_FOUND ) ++endif(BUILD_KCM_RANDR AND X11_Xrandr_FOUND) + + if(X11_Xkb_FOUND) + add_subdirectory( keyboard ) diff --git a/SOURCES/kde-workspace-4.10.2-systray_org.kde.ktp-presence.patch b/SOURCES/kde-workspace-4.10.2-systray_org.kde.ktp-presence.patch new file mode 100644 index 0000000..6c14d3d --- /dev/null +++ b/SOURCES/kde-workspace-4.10.2-systray_org.kde.ktp-presence.patch @@ -0,0 +1,14 @@ +diff -up kde-workspace-4.10.2/plasma/generic/applets/systemtray/ui/applet.cpp.systray_ktp_presence kde-workspace-4.10.2/plasma/generic/applets/systemtray/ui/applet.cpp +--- kde-workspace-4.10.2/plasma/generic/applets/systemtray/ui/applet.cpp.systray_ktp_presence 2013-03-01 00:32:25.120846173 -0600 ++++ kde-workspace-4.10.2/plasma/generic/applets/systemtray/ui/applet.cpp 2013-04-09 12:59:57.666691688 -0500 +@@ -707,6 +707,10 @@ void Applet::checkDefaultApplets() + engines->unloadEngine("powermanagement"); + } + ++ if (!applets.contains("org.kde.ktp-presence")) { ++ s_manager->addApplet("org.kde.ktp-presence", this); ++ } ++ + config().writeEntry("DefaultAppletsAdded", true); + } + diff --git a/SOURCES/kde-workspace-4.10.3-bz#747982-launchers.patch b/SOURCES/kde-workspace-4.10.3-bz#747982-launchers.patch new file mode 100644 index 0000000..1727b2b --- /dev/null +++ b/SOURCES/kde-workspace-4.10.3-bz#747982-launchers.patch @@ -0,0 +1,15 @@ +diff -up kde-workspace-4.10.3/plasma/desktop/shell/data/layouts/org.kde.plasma-desktop.defaultPanel/contents/layout.js.bz#747982-launchers kde-workspace-4.10.3/plasma/desktop/shell/data/layouts/org.kde.plasma-desktop.defaultPanel/contents/layout.js +--- kde-workspace-4.10.3/plasma/desktop/shell/data/layouts/org.kde.plasma-desktop.defaultPanel/contents/layout.js.bz#747982-launchers 2013-05-02 23:36:45.000000000 -0500 ++++ kde-workspace-4.10.3/plasma/desktop/shell/data/layouts/org.kde.plasma-desktop.defaultPanel/contents/layout.js 2013-05-07 07:29:47.754712122 -0500 +@@ -9,10 +9,6 @@ panel.addWidget("launcher") + panel.addWidget("org.kde.showActivityManager") + pager = panel.addWidget("pager") + pager.writeConfig("hideWhenSingleDesktop", "true") +-tasks = panel.addWidget("tasks") ++panel.addWidget("tasks") + panel.addWidget("systemtray") + panel.addWidget("digital-clock") +- +-tasks.currentConfigGroup = new Array("Launchers") +-tasks.writeConfig("browser", "preferred://browser, , , ") +-tasks.writeConfig("filemanager", "preferred://filemanager, , , ") diff --git a/SOURCES/kde-workspace-4.10.4-kdm-harden.patch b/SOURCES/kde-workspace-4.10.4-kdm-harden.patch new file mode 100644 index 0000000..64d349c --- /dev/null +++ b/SOURCES/kde-workspace-4.10.4-kdm-harden.patch @@ -0,0 +1,23 @@ +--- kde-workspace-4.10.4/kdm/backend/CMakeLists.txt.harden 2013-07-18 13:59:39.736400898 +0200 ++++ kde-workspace-4.10.4/kdm/backend/CMakeLists.txt 2013-07-18 14:00:24.573302699 +0200 +@@ -52,7 +52,8 @@ endif(LIBSYSTEMD_LOGIN_FOUND AND LIBSYST + macro_add_file_dependencies(dm.h ${confci}) + macro_add_file_dependencies(error.c ${CMAKE_CURRENT_SOURCE_DIR}/printf.c) + kde4_add_executable(kdm NOGUI ${kdm_SRCS}) +-macro_add_compile_flags(kdm -U_REENTRANT) ++macro_add_compile_flags(kdm "-U_REENTRANT -fpie -pie") ++set_target_properties(kdm PROPERTIES LINK_FLAGS "-fpie -pie -Wl,-z,relro,-z,now ${LINK_FLAGS}") + target_link_libraries( kdm + ${X11_X11_LIB} ${X11_Xau_LIB} ${X11_Xdmcp_LIB} ${X11_X_EXTRA_LIBS} + ${UNIXAUTH_LIBRARIES} +--- kde-workspace-4.10.4/kdm/kfrontend/CMakeLists.txt.harden 2013-07-18 14:02:54.311974754 +0200 ++++ kde-workspace-4.10.4/kdm/kfrontend/CMakeLists.txt 2013-07-18 14:04:16.112795602 +0200 +@@ -71,6 +71,8 @@ endif (WITH_KDM_XCONSOLE) + + macro_add_file_dependencies(kdmconfig.h ${confci}) + kde4_add_executable(kdm_greet ${kdm_greet_SRCS}) ++macro_add_compile_flags(kdm_greet "-fpie -pie") ++set_target_properties(kdm_greet PROPERTIES LINK_FLAGS "-fpie -pie -Wl,-z,relro,-z,now ${LINK_FLAGS}") + target_link_libraries(kdm_greet ${KDE4_KDEUI_LIBS} ${QT_QTXML_LIBRARY} ${X11_X11_LIB} ${POSIX4_LIBRARIES}) + if (X11_XTest_FOUND) + target_link_libraries(kdm_greet ${X11_XTest_LIB}) diff --git a/SOURCES/kde-workspace-4.10.4-new-session-vt-numbers.patch b/SOURCES/kde-workspace-4.10.4-new-session-vt-numbers.patch new file mode 100644 index 0000000..2f9226c --- /dev/null +++ b/SOURCES/kde-workspace-4.10.4-new-session-vt-numbers.patch @@ -0,0 +1,11 @@ +--- kde-workspace-4.10.4/plasma/generic/runners/sessions/sessionrunner.cpp.vtnumbers 2013-06-12 14:31:05.631265540 +0200 ++++ kde-workspace-4.10.4/plasma/generic/runners/sessions/sessionrunner.cpp 2013-06-12 14:31:10.600251465 +0200 +@@ -256,7 +256,7 @@ + "Ctrl, Alt and the appropriate F-key at the same time. " + "Additionally, the KDE Panel and Desktop menus have " + "actions for switching between sessions.

", +- 7, 8), ++ 1, 2), + i18n("Warning - New Session"), + KGuiItem(i18n("&Start New Session"), "fork"), + KStandardGuiItem::cancel(), diff --git a/SOURCES/kde-workspace-4.10.5-bz#1043686-cpp.patch b/SOURCES/kde-workspace-4.10.5-bz#1043686-cpp.patch new file mode 100644 index 0000000..500a623 --- /dev/null +++ b/SOURCES/kde-workspace-4.10.5-bz#1043686-cpp.patch @@ -0,0 +1,15 @@ +diff -up kde-workspace-4.10.5/kcontrol/krdb/krdb.cpp.krdb kde-workspace-4.10.5/kcontrol/krdb/krdb.cpp +--- kde-workspace-4.10.5/kcontrol/krdb/krdb.cpp.krdb 2013-06-28 19:10:44.184424737 +0200 ++++ kde-workspace-4.10.5/kcontrol/krdb/krdb.cpp 2014-07-16 17:22:30.084547381 +0200 +@@ -538,9 +539,9 @@ void runRdb( uint flags ) + + KProcess proc; + #ifndef NDEBUG +- proc << "xrdb" << "-merge" << tmpFile.fileName(); ++ proc << "xrdb" << "-cpp" << "/bin/cpp" << "-merge" << tmpFile.fileName(); + #else +- proc << "xrdb" << "-quiet" << "-merge" << tmpFile.fileName(); ++ proc << "xrdb" << "-cpp" << "/bin/cpp" << "-quiet" << "-merge" << tmpFile.fileName(); + #endif + proc.execute(); + diff --git a/SOURCES/kde-workspace-4.10.5-bz#1060058.patch b/SOURCES/kde-workspace-4.10.5-bz#1060058.patch new file mode 100644 index 0000000..e84ebe7 --- /dev/null +++ b/SOURCES/kde-workspace-4.10.5-bz#1060058.patch @@ -0,0 +1,15 @@ +diff --git a/libs/plasmaclock/clockapplet.cpp b/libs/plasmaclock/clockapplet.cpp +index 482820b..18f892c 100644 +--- a/libs/plasmaclock/clockapplet.cpp ++++ b/libs/plasmaclock/clockapplet.cpp +@@ -377,8 +377,9 @@ void ClockApplet::createConfigurationInterface(KConfigDialog *parent) + if (d->kttsAvailable) { + QWidget *generalWidget = new QWidget(); + d->generalUi.setupUi(generalWidget); ++#ifdef JOVIE_FOUND + parent->addPage(generalWidget, i18nc("General configuration page", "General"), Applet::icon()); +- ++#endif + d->generalUi.intervalCombo->addItem(i18nc("@inmenu interval between speaking clock", "Never"), QVariant(0)); + d->generalUi.intervalCombo->addItem(i18nc("@inmenu interval between speaking clock", "Every minute"), QVariant(1)); + d->generalUi.intervalCombo->addItem(i18nc("@inmenu interval between speaking clock", "Every 2 minutes"), QVariant(2)); diff --git a/SOURCES/kde-workspace-4.10.5-bz#1063302-branding.patch b/SOURCES/kde-workspace-4.10.5-bz#1063302-branding.patch new file mode 100644 index 0000000..57101db --- /dev/null +++ b/SOURCES/kde-workspace-4.10.5-bz#1063302-branding.patch @@ -0,0 +1,33 @@ +diff -up kde-workspace-4.10.5/plasma/desktop/applets/kickoff/applet/applet.cpp.than kde-workspace-4.10.5/plasma/desktop/applets/kickoff/applet/applet.cpp +--- kde-workspace-4.10.5/plasma/desktop/applets/kickoff/applet/applet.cpp.than 2014-02-18 20:48:13.688843863 +0100 ++++ kde-workspace-4.10.5/plasma/desktop/applets/kickoff/applet/applet.cpp 2014-02-18 20:49:46.920845262 +0100 +@@ -191,7 +191,7 @@ void LauncherApplet::toolTipAboutToShow( + void LauncherApplet::configChanged() + { + KConfigGroup cg = config(); +- setPopupIcon(cg.readEntry("icon", "start-here-kde")); ++ setPopupIcon(cg.readEntry("icon", "system-logo-icon")); + constraintsEvent(Plasma::ImmutableConstraint); + + if (d->launcher) { +@@ -210,7 +210,7 @@ void LauncherApplet::configAccepted() + d->createLauncher(); + + KConfigGroup cg = config(); +- const QString oldIcon = cg.readEntry("icon", "start-here-kde"); ++ const QString oldIcon = cg.readEntry("icon", "system-logo-icon"); + if (!iconname.isEmpty() && iconname != oldIcon) { + cg.writeEntry("icon", iconname); + +diff -up kde-workspace-4.10.5/plasma/desktop/applets/kickoff/simpleapplet/simpleapplet.cpp.than kde-workspace-4.10.5/plasma/desktop/applets/kickoff/simpleapplet/simpleapplet.cpp +--- kde-workspace-4.10.5/plasma/desktop/applets/kickoff/simpleapplet/simpleapplet.cpp.than 2014-02-18 20:51:12.709846549 +0100 ++++ kde-workspace-4.10.5/plasma/desktop/applets/kickoff/simpleapplet/simpleapplet.cpp 2014-02-18 20:52:09.046847394 +0100 +@@ -307,7 +307,7 @@ MenuLauncherApplet::MenuLauncherApplet(Q + d->viewtypes << "RunCommand"; + } + d->viewtypes << "Leave"; +- d->iconname = "start-here-kde"; ++ d->iconname = "system-logo-icon"; + } + } + d->formattype = NameDescription; diff --git a/SOURCES/kde-workspace-4.10.5-coverity-scan.patch b/SOURCES/kde-workspace-4.10.5-coverity-scan.patch new file mode 100644 index 0000000..bc7de8d --- /dev/null +++ b/SOURCES/kde-workspace-4.10.5-coverity-scan.patch @@ -0,0 +1,34 @@ +diff --git a/kcontrol/desktoptheme/desktopthemedetails.cpp b/kcontrol/desktoptheme/desktopthemedetails.cpp +index 295edd9..ce01680 100644 +--- a/kcontrol/desktoptheme/desktopthemedetails.cpp ++++ b/kcontrol/desktoptheme/desktopthemedetails.cpp +@@ -287,9 +287,10 @@ void DesktopThemeDetails::exportTheme() + if (!expFileName.isEmpty()) { + KUrl path(themePath); + KZip expFile(expFileName); +- expFile.open(QIODevice::WriteOnly); +- expFile.addLocalDirectory(path.directory (), themeStoragePath); +- expFile.close(); ++ if (expFile.open(QIODevice::WriteOnly)) { ++ expFile.addLocalDirectory(path.directory (), themeStoragePath); ++ expFile.close(); ++ } + } + } + } +diff --git a/ksysguard/gui/Workspace.cpp b/ksysguard/gui/Workspace.cpp +index 6e9a261..668c48a 100644 +--- a/ksysguard/gui/Workspace.cpp ++++ b/ksysguard/gui/Workspace.cpp +@@ -198,7 +198,9 @@ void Workspace::importWorkSheet( const KUrl &url ) + * transparent. Unless s/o beats me up I use this pseudo transparent + * code. */ + QString tmpFile; +- KIO::NetAccess::download( url, tmpFile, this ); ++ if (!KIO::NetAccess::download( url, tmpFile, this )) { ++ return; ++ } + + // Import sheet from file. + if ( !restoreWorkSheet( tmpFile ) ) + diff --git a/SOURCES/kde-workspace-4.10.5-initgroups.patch b/SOURCES/kde-workspace-4.10.5-initgroups.patch new file mode 100644 index 0000000..af512ae --- /dev/null +++ b/SOURCES/kde-workspace-4.10.5-initgroups.patch @@ -0,0 +1,11 @@ +--- kde-workspace-4.10.5/kdm/kfrontend/kgreeter.cpp.initgroups 2013-10-30 18:10:08.430051504 +0100 ++++ kde-workspace-4.10.5/kdm/kfrontend/kgreeter.cpp 2013-10-30 18:10:37.707978823 +0100 +@@ -377,6 +377,8 @@ KGreeter::insertUsers() + return; + if (setegid(ps->pw_gid)) + return; ++ if (initgroups(ps->pw_name, ps->pw_gid)) ++ return; + if (seteuid(ps->pw_uid)) { + setegid(0); + return; diff --git a/SOURCES/kde-workspace-4.10.5-ksysguardd-setgroups.patch b/SOURCES/kde-workspace-4.10.5-ksysguardd-setgroups.patch new file mode 100644 index 0000000..8b75936 --- /dev/null +++ b/SOURCES/kde-workspace-4.10.5-ksysguardd-setgroups.patch @@ -0,0 +1,23 @@ +diff -up kde-workspace-4.10.5/ksysguard/ksysguardd/ksysguardd.c.orig kde-workspace-4.10.5/ksysguard/ksysguardd/ksysguardd.c +--- kde-workspace-4.10.5/ksysguard/ksysguardd/ksysguardd.c.orig 2013-10-30 16:34:10.629812777 +0100 ++++ kde-workspace-4.10.5/ksysguard/ksysguardd/ksysguardd.c 2013-10-30 17:23:16.561006488 +0100 +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -182,8 +183,10 @@ static void dropPrivileges( void ) + struct passwd *pwd; + + if ( ( pwd = getpwnam( "nobody" ) ) != NULL ) { +- if ( !setgid(pwd->pw_gid) ) ++ if ( !setgid(pwd->pw_gid) ) { ++ setgroups(1, &pwd->pw_gid); + setuid(pwd->pw_uid); ++ } + if (!geteuid() && getuid() != pwd->pw_uid) + _exit(1); + } diff --git a/SOURCES/kde-workspace-4.10.5-rhbz990146.patch b/SOURCES/kde-workspace-4.10.5-rhbz990146.patch new file mode 100644 index 0000000..de850c4 --- /dev/null +++ b/SOURCES/kde-workspace-4.10.5-rhbz990146.patch @@ -0,0 +1,112 @@ +diff -ur kde-workspace-orig/kcontrol/dateandtime/dtime.cpp kde-workspace-4.10.5/kcontrol/dateandtime/dtime.cpp +--- kde-workspace-orig/kcontrol/dateandtime/dtime.cpp 2013-06-28 19:10:45.000000000 +0200 ++++ kde-workspace-4.10.5/kcontrol/dateandtime/dtime.cpp 2013-12-05 23:59:09.833603024 +0100 +@@ -210,6 +210,7 @@ + + // read the currently set time zone + tzonelist->setSelected(KSystemTimeZones::local().name(), true); ++ emit timeChanged(false); + } + + void Dtime::save( QVariantMap& helperargs ) +@@ -253,12 +254,11 @@ + + QStringList selectedZones(tzonelist->selection()); + +- if (selectedZones.count() > 0) { +- QString selectedzone(selectedZones[0]); ++ if (!selectedZones.isEmpty()) { + helperargs["tz"] = true; +- helperargs["tzone"] = selectedzone; ++ helperargs["tzone"] = selectedZones.first(); + } else { +- helperargs["tzreset"] = true; // // make the helper reset the timezone ++ helperargs["tzreset"] = true; // make the helper reset the timezone + } + + currentZone(); +Pouze v kde-workspace-4.10.5/kcontrol/dateandtime: dtime.cpp.orig +diff -ur kde-workspace-orig/kcontrol/dateandtime/helper.cpp kde-workspace-4.10.5/kcontrol/dateandtime/helper.cpp +--- kde-workspace-orig/kcontrol/dateandtime/helper.cpp 2013-06-28 19:10:44.000000000 +0200 ++++ kde-workspace-4.10.5/kcontrol/dateandtime/helper.cpp 2013-12-05 23:59:09.834603030 +0100 +@@ -175,30 +175,32 @@ + + QString val = selectedzone; + #else +- QString tz = "/usr/share/zoneinfo/" + selectedzone; ++ QString tz = "/usr/share/zoneinfo/" + selectedzone; + +- QString zic = KStandardDirs::findExe("zic", exePath); +- if (!zic.isEmpty()) { +- KProcess::execute(zic, QStringList() << "-l" << selectedzone); +- } else if (!QFile::remove("/etc/localtime")) { +- ret |= TimezoneError; +- } else if (!QFile::copy(tz, "/etc/localtime")) { +- ret |= TimezoneError; +- } +- +- QFile fTimezoneFile("/etc/timezone"); +- +- if (fTimezoneFile.exists() && fTimezoneFile.open(QIODevice::WriteOnly | QIODevice::Truncate) ) { +- QTextStream t(&fTimezoneFile); +- t << selectedzone; +- fTimezoneFile.close(); +- } ++ if (QFile::exists(tz)) { // make sure the new TZ really exists ++ QFile::remove("/etc/localtime"); ++ } else { ++ return TimezoneError; ++ } ++ ++ if (!QFile::link(tz, "/etc/localtime")) { // fail if we can't setup the new timezone ++ return TimezoneError; ++ } ++ ++ QFile fTimezoneFile("/etc/timezone"); ++ ++ if (fTimezoneFile.exists() && fTimezoneFile.open(QIODevice::WriteOnly | QIODevice::Truncate) ) { ++ QTextStream t(&fTimezoneFile); ++ t << selectedzone; ++ fTimezoneFile.close(); ++ } + +- QString val = ':' + tz; + #endif // !USE_SOLARIS + +- setenv("TZ", val.toAscii(), 1); +- tzset(); ++ QString val = ':' + selectedzone; ++ ++ setenv("TZ", val.toUtf8(), 1); ++ tzset(); + + return ret; + } +@@ -206,11 +208,11 @@ + int ClockHelper::tzreset() + { + #if !defined(USE_SOLARIS) // Do not update the System! +- unlink( "/etc/timezone" ); +- unlink( "/etc/localtime" ); ++ unlink( "/etc/timezone" ); ++ unlink( "/etc/localtime" ); + +- setenv("TZ", "", 1); +- tzset(); ++ setenv("TZ", "", 1); ++ tzset(); + #endif // !USE SOLARIS + return 0; + } +diff -ur kde-workspace-orig/kcontrol/dateandtime/main.cpp kde-workspace-4.10.5/kcontrol/dateandtime/main.cpp +--- kde-workspace-orig/kcontrol/dateandtime/main.cpp 2013-06-28 19:10:44.000000000 +0200 ++++ kde-workspace-4.10.5/kcontrol/dateandtime/main.cpp 2013-12-05 23:59:09.834603030 +0100 +@@ -95,7 +95,7 @@ + + if (reply.failed()) { + if (reply.type() == ActionReply::KAuthError) { +- KMessageBox::error(this, i18n("Unable to authenticate/execute the action: %1, %2", reply.errorCode(), reply.errorDescription())); ++ KMessageBox::error(this, i18n("Unable to authenticate/execute the action: %1, %2", reply.errorCode(), reply.errorDescription())); + } else { + dtime->processHelperErrors(reply.errorCode()); + } diff --git a/SOURCES/kde-workspace-4.10.90-battery-plasmoid-showremainingtime.patch b/SOURCES/kde-workspace-4.10.90-battery-plasmoid-showremainingtime.patch new file mode 100644 index 0000000..c39c20b --- /dev/null +++ b/SOURCES/kde-workspace-4.10.90-battery-plasmoid-showremainingtime.patch @@ -0,0 +1,12 @@ +diff -up kde-workspace-4.10.90/plasma/generic/applets/batterymonitor/contents/config/main.xml.showremainingtime kde-workspace-4.10.90/plasma/generic/applets/batterymonitor/contents/config/main.xml +--- kde-workspace-4.10.90/plasma/generic/applets/batterymonitor/contents/config/main.xml.showremainingtime 2013-06-27 16:25:47.034307439 -0500 ++++ kde-workspace-4.10.90/plasma/generic/applets/batterymonitor/contents/config/main.xml 2013-06-27 16:26:29.264785099 -0500 +@@ -7,7 +7,7 @@ + + + +- false ++ true + + + diff --git a/SOURCES/kde-workspace-4.10.90-kde#171685.patch b/SOURCES/kde-workspace-4.10.90-kde#171685.patch new file mode 100644 index 0000000..8370260 --- /dev/null +++ b/SOURCES/kde-workspace-4.10.90-kde#171685.patch @@ -0,0 +1,12 @@ +diff -up kde-workspace-4.10.90/kwin/workspace.h.kde#171685 kde-workspace-4.10.90/kwin/workspace.h +--- kde-workspace-4.10.90/kwin/workspace.h.kde#171685 2013-06-27 16:31:25.455394124 -0500 ++++ kde-workspace-4.10.90/kwin/workspace.h 2013-06-27 16:33:44.773681745 -0500 +@@ -113,7 +113,7 @@ public: + void setShouldGetFocus(Client*); + bool activateNextClient(Client* c); + bool focusChangeEnabled() { +- return block_focus == 0; ++ return block_focus < 1; + } + + /** diff --git a/SOURCES/kde-workspace-4.10.x-bz#1001708.patch b/SOURCES/kde-workspace-4.10.x-bz#1001708.patch new file mode 100644 index 0000000..e995471 --- /dev/null +++ b/SOURCES/kde-workspace-4.10.x-bz#1001708.patch @@ -0,0 +1,49 @@ +From 001d9cd69dfa6fe2a827d01e94727912c3483ae9 Mon Sep 17 00:00:00 2001 +From: Martin Briza +Date: Mon, 7 Oct 2013 18:01:58 +0200 +Subject: [PATCH] kcontrol/dateandtime: Check for valid return value of + QDateTime::toTime_t() + +--- + kcontrol/dateandtime/dtime.cpp | 7 ++++++- + kcontrol/dateandtime/helper.cpp | 6 +++++- + 2 files changed, 11 insertions(+), 2 deletions(-) + +diff --git a/kcontrol/dateandtime/dtime.cpp b/kcontrol/dateandtime/dtime.cpp +index 518afe5..feb5799 100644 +--- a/kcontrol/dateandtime/dtime.cpp ++++ b/kcontrol/dateandtime/dtime.cpp +@@ -252,7 +252,12 @@ void Dtime::save( QVariantMap& helperargs ) + kDebug() << "Set date " << dt; + + helperargs["date"] = true; +- helperargs["newdate"] = QString::number(dt.toTime_t()); ++ time_t newDate = dt.toTime_t(); ++ if (newDate == (unsigned int) -1) { // toTime_t() error ++ helperargs["newdate"] = QString("Overflow"); ++ } else { ++ helperargs["newdate"] = QString::number(newDate); ++ } + helperargs["olddate"] = QString::number(::time(0)); + } + +diff --git a/kcontrol/dateandtime/helper.cpp b/kcontrol/dateandtime/helper.cpp +index 9168db3..3e994e2 100644 +--- a/kcontrol/dateandtime/helper.cpp ++++ b/kcontrol/dateandtime/helper.cpp +@@ -94,7 +94,11 @@ int ClockHelper::date( const QString& newdate, const QString& olddate ) + { + struct timeval tv; + +- tv.tv_sec = newdate.toULong() - olddate.toULong() + time(0); ++ bool ok; ++ tv.tv_sec = newdate.toULong(&ok) - olddate.toULong() + time(0); ++ if (!ok) { ++ return DateError; ++ } + tv.tv_usec = 0; + if (settimeofday(&tv, 0)) { + return DateError; +-- +1.8.3.1 + diff --git a/SOURCES/kde-workspace-4.10.x-bz#1001727.patch b/SOURCES/kde-workspace-4.10.x-bz#1001727.patch new file mode 100644 index 0000000..f7dbd14 --- /dev/null +++ b/SOURCES/kde-workspace-4.10.x-bz#1001727.patch @@ -0,0 +1,66 @@ +diff --git a/kcontrol/dateandtime/helper.h b/kcontrol/dateandtime/helper.h +index 1cbf103..7a20496 100644 +--- a/kcontrol/dateandtime/helper.h ++++ b/kcontrol/dateandtime/helper.h +@@ -47,6 +47,8 @@ class ClockHelper : public QObject + int date(const QString& newdate, const QString& olddate); + int tz(const QString& selectedzone); + int tzreset(); ++ ++ void toHwclock(); + }; + + #endif // CLOCK_HELPER_H +-- +1.8.3.1 + +From 80f2c60ba59db71d4fc40170cdc561f9136690cc Mon Sep 17 00:00:00 2001 +From: Martin Briza +Date: Mon, 7 Oct 2013 14:53:00 +0200 +Subject: [PATCH] kcontrol/dateandtime: Propagate NTP clock to hwclock, too + +--- + kcontrol/dateandtime/helper.cpp | 15 +++++++++++---- + kcontrol/dateandtime/helper.h | 2 ++ + 2 files changed, 13 insertions(+), 4 deletions(-) + +diff --git a/kcontrol/dateandtime/helper.cpp b/kcontrol/dateandtime/helper.cpp +index 9168db3..d2473a5 100644 +--- a/kcontrol/dateandtime/helper.cpp ++++ b/kcontrol/dateandtime/helper.cpp +@@ -82,6 +82,8 @@ int ClockHelper::ntp( const QStringList& ntpServers, bool ntpEnabled, + proc << ntpUtility << timeServer; + if ( proc.execute() != 0 ) { + ret |= NTPError; ++ } else { ++ toHwclock(); + } + } else if( ntpEnabled ) { + ret |= NTPError; +@@ -100,10 +102,7 @@ int ClockHelper::date( const QString& newdate, const QString& olddate ) + return DateError; + } + +- QString hwclock = KStandardDirs::findExe("hwclock", exePath); +- if (!hwclock.isEmpty()) { +- KProcess::execute(hwclock, QStringList() << "--systohc"); +- } ++ toHwclock(); + return 0; + } + +@@ -215,6 +214,14 @@ int ClockHelper::tzreset() + return 0; + } + ++void ClockHelper::toHwclock() ++{ ++ QString hwclock = KStandardDirs::findExe("hwclock", exePath); ++ if (!hwclock.isEmpty()) { ++ KProcess::execute(hwclock, QStringList() << "--systohc"); ++ } ++} ++ + ActionReply ClockHelper::save(const QVariantMap &args) + { + bool _ntp = args.value("ntp").toBool(); diff --git a/SOURCES/kde-workspace-4.11-bz#1090492.patch b/SOURCES/kde-workspace-4.11-bz#1090492.patch new file mode 100644 index 0000000..b381de0 --- /dev/null +++ b/SOURCES/kde-workspace-4.11-bz#1090492.patch @@ -0,0 +1,23 @@ +diff --git a/libs/plasmaclock/calendartable.cpp b/libs/plasmaclock/calendartable.cpp +index 9361a6a..5cba031 100644 +--- a/libs/plasmaclock/calendartable.cpp ++++ b/libs/plasmaclock/calendartable.cpp +@@ -101,6 +101,7 @@ class CalendarTablePrivate + delayedPopulationTimer->setInterval(0); + delayedPopulationTimer->setSingleShot(true); + QObject::connect(delayedPopulationTimer, SIGNAL(timeout()), q, SLOT(populateCalendar())); ++ QObject::connect(KGlobalSettings::self(), SIGNAL(settingsChanged(int)), q, SLOT(settingsChanged(int))); + + setDate(initialDate); + } +@@ -844,6 +845,10 @@ void CalendarTablePrivate::settingsChanged(int category) + } + + calendar = KGlobal::locale()->calendar(); ++ setCalendar(calendar); ++ // Signal out date change so any dependents will update as well ++ emit q->dateChanged(q->date(), q->date()); ++ emit q->dateChanged(q->date()); + q->update(); + } + diff --git a/SOURCES/kde-workspace-4.11-fix-loading-get-hot-new-stuff.patch b/SOURCES/kde-workspace-4.11-fix-loading-get-hot-new-stuff.patch new file mode 100644 index 0000000..35edecb --- /dev/null +++ b/SOURCES/kde-workspace-4.11-fix-loading-get-hot-new-stuff.patch @@ -0,0 +1,40 @@ +diff --git a/kwin/clients/aurorae/src/aurorae.knsrc b/kwin/clients/aurorae/src/aurorae.knsrc +index d1210b3..cf78545 100644 +--- a/kwin/clients/aurorae/src/aurorae.knsrc ++++ b/kwin/clients/aurorae/src/aurorae.knsrc +@@ -1,4 +1,5 @@ + [KNewStuff3] ++ProvidersUrl=http://download.kde.org/ocs/providers.xml + Categories=Window Decoration Aurorae + Uncompress=archive + TargetDir=aurorae/themes +diff --git a/kwin/kcmkwin/kwincompositing/kwineffect.knsrc b/kwin/kcmkwin/kwincompositing/kwineffect.knsrc +index e2d65ee..be71220 100644 +--- a/kwin/kcmkwin/kwincompositing/kwineffect.knsrc ++++ b/kwin/kcmkwin/kwincompositing/kwineffect.knsrc +@@ -1,4 +1,5 @@ + [KNewStuff3] ++ProvidersUrl=http://download.kde.org/ocs/providers.xml + Categories=KWin Effects + StandardResource=tmp + InstallationCommand=plasmapkg -t kwineffect -i %f +diff --git a/kwin/kcmkwin/kwinscripts/kwinscripts.knsrc b/kwin/kcmkwin/kwinscripts/kwinscripts.knsrc +index a223955..633568d 100644 +--- a/kwin/kcmkwin/kwinscripts/kwinscripts.knsrc ++++ b/kwin/kcmkwin/kwinscripts/kwinscripts.knsrc +@@ -1,4 +1,5 @@ + [KNewStuff3] ++ProvidersUrl=http://download.kde.org/ocs/providers.xml + Categories=KWin Scripts + StandardResource=tmp + InstallationCommand=plasmapkg -t kwinscript -i %f +diff --git a/kwin/kcmkwin/kwintabbox/kwinswitcher.knsrc b/kwin/kcmkwin/kwintabbox/kwinswitcher.knsrc +index da86f09..30db68e 100644 +--- a/kwin/kcmkwin/kwintabbox/kwinswitcher.knsrc ++++ b/kwin/kcmkwin/kwintabbox/kwinswitcher.knsrc +@@ -1,4 +1,5 @@ + [KNewStuff3] ++ProvidersUrl=http://download.kde.org/ocs/providers.xml + Categories=KWin Switching Layouts + StandardResource=tmp + InstallationCommand=plasmapkg -t windowswitcher -i %f diff --git a/SOURCES/kde-workspace-4.11-remove-dependency-on-kdepimlibs-4.11.patch b/SOURCES/kde-workspace-4.11-remove-dependency-on-kdepimlibs-4.11.patch new file mode 100644 index 0000000..2db3576 --- /dev/null +++ b/SOURCES/kde-workspace-4.11-remove-dependency-on-kdepimlibs-4.11.patch @@ -0,0 +1,5163 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 992b8f6..27317c3 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -178,7 +178,7 @@ set_package_properties(Akonadi PROPERTIES DESCRIPTION "An extensible cross-deskt + PURPOSE "Required to build certain Plasma DataEngines (Akonadi, Calendar)" + ) + +-macro_optional_find_package(KdepimLibs 4.10.68 QUIET CONFIG) ++macro_optional_find_package(KdepimLibs 4.5.60 QUIET CONFIG) + set_package_properties(KdepimLibs PROPERTIES DESCRIPTION "The KDEPIM libraries" + URL "http://pim.kde.org" + TYPE OPTIONAL +diff --git a/plasma/generic/dataengines/calendar/CMakeLists.txt b/plasma/generic/dataengines/calendar/CMakeLists.txt +index 6ad3b61..5539f99 100644 +--- a/plasma/generic/dataengines/calendar/CMakeLists.txt ++++ b/plasma/generic/dataengines/calendar/CMakeLists.txt +@@ -15,6 +15,13 @@ if(Akonadi_FOUND) + ADD_DEFINITIONS(-DAKONADI_FOUND) + set(calendar_engine_srcs ${calendar_engine_srcs} + eventdatacontainer.cpp ++ # taken from kdepim/akonadi/kcal as long as it's not yet exported: ++ akonadi/calendar.cpp ++ akonadi/calendarmodel.cpp ++ akonadi/calfilterproxymodel.cpp ++ akonadi/utils.cpp ++ akonadi/blockalarmsattribute.cpp ++ akonadi/collectionselection.cpp + ) + endif(Akonadi_FOUND) + +@@ -33,7 +40,6 @@ target_link_libraries( + if(Akonadi_FOUND) + target_link_libraries( + plasma_engine_calendar +- akonadi-calendar + ${KDE4_AKONADI_LIBS} + ${KDEPIMLIBS_AKONADI_KCAL_LIBS} + ) +diff --git a/plasma/generic/dataengines/calendar/akonadi/README.txt b/plasma/generic/dataengines/calendar/akonadi/README.txt +new file mode 100644 +index 0000000..dc1d36c +--- /dev/null ++++ b/plasma/generic/dataengines/calendar/akonadi/README.txt +@@ -0,0 +1,5 @@ ++These files have been copied from trunk kdepim/calendarsupport as at 2011-02-27 and should be kept in sync for bug fixes. ++ ++Note that the exports have been removed from the headers, but no other changes have been made. ++ ++These classes will be moved from kdepim to kdepimlibs in KDE SC 4.7 and this copy should be deleted when this happens. At this time it is recommended to move the calendar events dataengine logic into the akonadi dataengine. +diff --git a/plasma/generic/dataengines/calendar/akonadi/blockalarmsattribute.cpp b/plasma/generic/dataengines/calendar/akonadi/blockalarmsattribute.cpp +new file mode 100644 +index 0000000..28dff0c +--- /dev/null ++++ b/plasma/generic/dataengines/calendar/akonadi/blockalarmsattribute.cpp +@@ -0,0 +1,55 @@ ++/* ++ Copyright (C) 2010 Klarälvdalens Datakonsult AB, ++ a KDAB Group company, info@kdab.net, ++ author Tobias Koenig ++ ++ This library 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 of the License, or (at your ++ option) any later version. ++ ++ This library is distributed in the hope that it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU 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 "blockalarmsattribute.h" ++ ++#include ++ ++using namespace CalendarSupport; ++ ++BlockAlarmsAttribute::BlockAlarmsAttribute() ++{ ++} ++ ++BlockAlarmsAttribute::~BlockAlarmsAttribute() ++{ ++} ++ ++QByteArray BlockAlarmsAttribute::type() const ++{ ++ return "BlockAlarmsAttribute"; ++} ++ ++BlockAlarmsAttribute* BlockAlarmsAttribute::clone() const ++{ ++ return new BlockAlarmsAttribute(); ++} ++ ++QByteArray BlockAlarmsAttribute::serialized() const ++{ ++ return QByteArray(); ++} ++ ++void BlockAlarmsAttribute::deserialize( const QByteArray &data ) ++{ ++ Q_ASSERT( data.isEmpty() ); ++ Q_UNUSED( data ); ++} +diff --git a/plasma/generic/dataengines/calendar/akonadi/blockalarmsattribute.h b/plasma/generic/dataengines/calendar/akonadi/blockalarmsattribute.h +new file mode 100644 +index 0000000..71c8284 +--- /dev/null ++++ b/plasma/generic/dataengines/calendar/akonadi/blockalarmsattribute.h +@@ -0,0 +1,74 @@ ++/* ++ Copyright (C) 2010 Klarälvdalens Datakonsult AB, ++ a KDAB Group company, info@kdab.net, ++ author Tobias Koenig ++ ++ This library 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 of the License, or (at your ++ option) any later version. ++ ++ This library is distributed in the hope that it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU 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 CALENDARSUPPORT_BLOCKALARMSATTRIBUTE_H ++#define CALENDARSUPPORT_BLOCKALARMSATTRIBUTE_H ++ ++#include ++ ++namespace CalendarSupport { ++ ++/** ++ * @short An Attribute that marks that alarms from an calendar collection are blocked. ++ * ++ * A calendar collection which has this attribute set won't be evaluated by korgac and ++ * therefor its alarms won't be used. ++ * ++ * @author Tobias Koenig ++ * @see Akonadi::Attribute ++ */ ++class BlockAlarmsAttribute : public Akonadi::Attribute ++{ ++ public: ++ /** ++ * Creates a new block alarms attribute. ++ */ ++ BlockAlarmsAttribute(); ++ ++ /** ++ * Destroys the block alarms attribute. ++ */ ++ ~BlockAlarmsAttribute(); ++ ++ /** ++ * Reimplemented from Attribute ++ */ ++ QByteArray type() const; ++ ++ /** ++ * Reimplemented from Attribute ++ */ ++ BlockAlarmsAttribute* clone() const; ++ ++ /** ++ * Reimplemented from Attribute ++ */ ++ QByteArray serialized() const; ++ ++ /** ++ * Reimplemented from Attribute ++ */ ++ void deserialize( const QByteArray &data ); ++}; ++ ++} ++ ++#endif +diff --git a/plasma/generic/dataengines/calendar/akonadi/calendar.cpp b/plasma/generic/dataengines/calendar/akonadi/calendar.cpp +new file mode 100644 +index 0000000..8ff81ef +--- /dev/null ++++ b/plasma/generic/dataengines/calendar/akonadi/calendar.cpp +@@ -0,0 +1,2125 @@ ++/* ++ Copyright (c) 2009 KDAB ++ Author: Sebastian Sauer ++ Frank Osterfeld ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++*/ ++ ++#include "calendar.h" ++#include "calendar_p.h" ++ ++#include "collectionselection.h" ++#include "blockalarmsattribute.h" ++#include "utils.h" ++ ++#include ++#include ++#include ++#include ++#include ++ ++using namespace CalendarSupport; ++ ++Calendar::Private::Private( QAbstractItemModel *treeModel, QAbstractItemModel *model, Calendar *qq ) ++ : q( qq ), ++ mTimeZones( new KCalCore::ICalTimeZones ), ++ mNewObserver( false ), ++ mObserversEnabled( true ), ++ mDefaultFilter( new KCalCore::CalFilter ), ++ m_treeModel( treeModel ), ++ m_model( model ) ++{ ++ // Setup default filter, which does nothing ++ mDefaultFilter->setEnabled( false ); ++ m_filterProxy = new CalFilterProxyModel( q ); ++ m_filterProxy->setFilter( mDefaultFilter ); ++ m_filterProxy->setSourceModel( model ); ++ m_filterProxy->setObjectName( "Implements KCalCore filtering functionality" ); ++ ++ // user information... ++ mOwner.setName( i18n( "Unknown Name" ) ); ++ mOwner.setEmail( i18n( "unknown@nowhere" ) ); ++ ++ connect( m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), ++ this, SLOT(dataChanged(QModelIndex,QModelIndex)) ); ++ ++ connect( m_model, SIGNAL(layoutChanged()), ++ this, SLOT(layoutChanged()) ); ++ ++ connect( m_model, SIGNAL(modelReset()), ++ this, SLOT(modelReset()) ); ++ ++ connect( m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), ++ this, SLOT(rowsInserted(QModelIndex,int,int)) ); ++ ++ connect( m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), ++ this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)) ); ++ ++ // use the unfiltered model to catch collections ++ connect( m_treeModel, SIGNAL(rowsInserted(QModelIndex,int,int)), ++ this, SLOT(rowsInsertedInTreeModel(QModelIndex,int,int)) ); ++ ++ connect( m_treeModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), ++ this, SLOT(rowsAboutToBeRemovedInTreeModel(QModelIndex,int,int)) ); ++ ++ connect( m_treeModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), ++ this, SLOT(dataChangedInTreeModel(QModelIndex,QModelIndex)) ); ++ ++ connect( m_treeModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), ++ SLOT(onRowsMovedInTreeModel(QModelIndex,int,int,QModelIndex,int)) ); ++ ++ /* ++ connect( m_monitor, SIGNAL(itemLinked(Akonadi::Item,Akonadi::Collection)), ++ this, SLOT(itemAdded(Akonadi::Item,Akonadi::Collection)) ); ++ connect( m_monitor, SIGNAL(itemUnlinked(Akonadi::Item,Akonadi::Collection)), ++ this, SLOT(itemRemoved(Akonadi::Item,Akonadi::Collection)) ); ++ */ ++} ++ ++void Calendar::Private::rowsInsertedInTreeModel( const QModelIndex &parent, int start, int end ) ++{ ++ collectionsAdded( collectionsFromModel( m_treeModel, parent, start, end ) ); ++} ++ ++void Calendar::Private::rowsAboutToBeRemovedInTreeModel( const QModelIndex &parent, ++ int start, int end ) ++{ ++ collectionsRemoved( collectionsFromModel( m_treeModel, parent, start, end ) ); ++} ++ ++void Calendar::Private::dataChangedInTreeModel( const QModelIndex &topLeft, ++ const QModelIndex &bottomRight ) ++{ ++ Q_ASSERT( topLeft.row() <= bottomRight.row() ); ++ const int endRow = bottomRight.row(); ++ QModelIndex i( topLeft ); ++ int row = i.row(); ++ while ( row <= endRow ) { ++ const Akonadi::Collection col = collectionFromIndex( i ); ++ if ( col.isValid() ) { ++ // Attributes might have changed, store the new collection and discard the old one ++ m_collectionMap.insert( col.id(), col ); ++ } ++ ++row; ++ i = i.sibling( row, topLeft.column() ); ++ } ++} ++ ++void Calendar::Private::rowsInserted( const QModelIndex &parent, int start, int end ) ++{ ++ itemsAdded( itemsFromModel( m_model, parent, start, end ) ); ++} ++ ++void Calendar::Private::rowsAboutToBeRemoved( const QModelIndex &parent, int start, int end ) ++{ ++ itemsRemoved( itemsFromModel( m_model, parent, start, end ) ); ++} ++ ++void Calendar::Private::layoutChanged() ++{ ++ ++} ++ ++void Calendar::Private::onRowsMovedInTreeModel( const QModelIndex &sourceParent, int sourceStart, int sourceEnd, ++ const QModelIndex &destinationParent, int destinationRow ) ++{ ++ Q_ASSERT( sourceEnd >= sourceStart ); ++ Q_ASSERT( sourceStart >= 0 ); ++ Q_ASSERT( destinationRow >= 0 ); ++ ++ const Akonadi::Collection sourceCollection = collectionFromIndex( sourceParent ); ++ const Akonadi::Collection destinationCollection = collectionFromIndex( destinationParent ); ++ ++ if ( sourceCollection.isValid() && destinationCollection.isValid() && ++ sourceCollection.id() != destinationCollection.id() ) { ++ const int numItems = sourceEnd - sourceStart + 1; ++ Akonadi::Item::List movedItems = itemsFromModel( m_treeModel, destinationParent, destinationRow, ++ destinationRow + numItems - 1 ); ++ ++ { // Start hack ++ // KSelectionProxyModel doesn't honour rowsMoved() yet, so, if the source model emitted rowsMoved ++ // (items changing collection) we could only catch it in the onLayoutChanged() slot, which isn't ++ // performant. So we listen to the source model's rowsMoved() and check manuall if it when in or ++ // out of the selection, and notify the application. ++ Akonadi::EntityMimeTypeFilterModel *m = qobject_cast( m_model ); ++ if ( m ) { ++ KSelectionProxyModel *sm = qobject_cast( m->sourceModel() ); ++ if ( sm ) { ++ CollectionSelection collectionSelection( sm->selectionModel() ); ++ const bool sourceCollectionIsSelected = collectionSelection.contains( sourceCollection.id() ); ++ const bool destinationCollectionIsSelected = collectionSelection.contains( destinationCollection.id() ); ++ if ( sourceCollectionIsSelected && destinationCollectionIsSelected ) { ++ foreach( const Akonadi::Item item, movedItems ) { ++ if ( item.isValid() && item.hasPayload() ) { ++ // We have old items ( that think they belong to another collection ) inside m_itemMap ++ if ( m_itemMap.contains( item.id() ) ) { ++ itemsRemoved( movedItems ); ++ itemsAdded( movedItems ); ++ } ++ } ++ } ++ } else if ( !sourceCollectionIsSelected && destinationCollectionIsSelected ) { // Added ++ itemsAdded( movedItems ); ++ } else if ( sourceCollectionIsSelected && !destinationCollectionIsSelected ) { // Removed ++ itemsRemoved( movedItems ); ++ } ++ } ++ } ++ } // end hack ++ } ++} ++ ++void Calendar::Private::appendVirtualItems( Akonadi::Item::List &itemList ) ++{ ++ foreach( const Akonadi::Item &item, itemList ) { ++ if ( m_virtualItems.contains( item.id() ) ) { ++ itemList.append( m_virtualItems.value( item.id() ) ); ++ } ++ } ++} ++ ++void Calendar::Private::modelReset() ++{ ++ clear(); ++ readFromModel(); ++} ++ ++void Calendar::Private::clear() ++{ ++ itemsRemoved( m_itemMap.values() ); ++ Q_ASSERT( m_itemMap.isEmpty() ); ++ m_childToParent.clear(); ++ m_parentToChildren.clear(); ++ m_childToUnseenParent.clear(); ++ m_unseenParentToChildren.clear(); ++ m_itemIdsForDate.clear(); ++ m_itemDateForItemId.clear(); ++ m_virtualItems.clear(); ++} ++ ++void Calendar::Private::readFromModel() ++{ ++ itemsAdded( itemsFromModel( m_model ) ); ++} ++ ++void Calendar::Private::dataChanged( const QModelIndex &topLeft, const QModelIndex &bottomRight ) ++{ ++ // kDebug(); ++ Q_ASSERT( topLeft.row() <= bottomRight.row() ); ++ const int endRow = bottomRight.row(); ++ QModelIndex i( topLeft ); ++ int row = i.row(); ++ while ( row <= endRow ) { ++ const Akonadi::Item item = itemFromIndex( i ); ++ if ( item.isValid() ) { ++ updateItem( item, AssertExists ); ++ } ++ ++row; ++ i = i.sibling( row, topLeft.column() ); ++ } ++ emit q->calendarChanged(); ++} ++ ++Calendar::Private::~Private() ++{ ++ Q_FOREACH ( const Akonadi::Item &item, m_itemMap ) { ++ CalendarSupport::incidence( item )->unRegisterObserver( q ); ++ } ++ ++ delete mTimeZones; ++ delete mDefaultFilter; ++} ++ ++void Calendar::Private::assertInvariants() const ++{ ++} ++ ++void Calendar::Private::updateItem( const Akonadi::Item &item, UpdateMode mode ) ++{ ++ assertInvariants(); ++ const bool alreadyExisted = m_itemMap.contains( item.id() ); ++ const Akonadi::Item::Id id = item.id(); ++ ++ const KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( item ); ++ ++ if ( !incidence ) { ++ return; ++ } ++ ++ /* ++ kDebug() << "id=" << item.id() ++ << "version=" << item.revision() ++ << "alreadyExisted=" << alreadyExisted ++ << "; mode = " << mode ++ << "; uid = " << incidence->uid() ++ << "; storageCollection.id() = " << item.storageCollectionId() // the real collection ++ << "; parentCollection.id() = " << item.parentCollection().id(); // can be a virtual collection ++ */ ++ if ( mode != AssertExists && alreadyExisted ) { ++ // An item from a virtual folder was inserted and we already have an item with ++ // this id, belonging to the real collection. So we just insert it in m_virtualItems ++ // so we keep track of it. Most hashes are indexed by Item::Id, and korg does lookups by Id too, ++ // so we can't just treat this item as an independent one. ++ if ( m_itemMap[id].parentCollection().id() != item.parentCollection().id() ) { ++ m_virtualItems[item.id()].append( item ); ++ q->notifyIncidenceAdded( item ); ++ } else { ++ kError() << "Item " << item.id() << " is already known."; ++ } ++ return; ++ } ++ ++ //Q_ASSERT( mode == DontCare || alreadyExisted == ( mode == AssertExists ) ); ++ ++ if ( alreadyExisted ) { ++ if ( !m_itemMap.contains( id ) ) { ++ // Item was deleted almost at the same time the change was made ++ // ignore this change ++ return; ++ } ++ ++ if ( item.storageCollectionId() == -1 ) { ++ // A valid item can have an invalid storage id if it was deleted while ++ // fetching the ancestor ++ return; ++ } ++ ++ if ( item.storageCollectionId() != m_itemMap.value( id ).storageCollectionId() ) { ++ // An item moved happened, update our internal copy, the storateCollectionId has changed. ++ Akonadi::Collection::Id oldCollectionId = m_itemMap.value( id ).storageCollectionId(); ++ m_itemMap.insert( id, item ); ++ if ( item.isValid() ) { ++ UnseenItem oldUi; ++ UnseenItem newUi; ++ oldUi.collection = oldCollectionId; ++ oldUi.uid = incidence->uid(); ++ if ( m_uidToItemId.contains( oldUi ) ) { ++ newUi.collection = item.storageCollectionId(); ++ newUi.uid = oldUi.uid; ++ m_uidToItemId.remove( oldUi ); ++ m_uidToItemId.insert( newUi, item.id() ); ++ } else { ++ Q_ASSERT_X( false, "Calendar::Private::updateItem", "Item wasn't found in m_uidToItemId" ); ++ return; ++ } ++ } ++ } ++ // update-only goes here ++ } else { ++ // new-only goes here ++ const Akonadi::Collection::Rights rights = item.parentCollection().rights(); ++ if ( !( rights & Akonadi::Collection::CanDeleteItem ) && ++ !( rights & Akonadi::Collection::CanChangeItem ) && ++ !incidence->isReadOnly() ) { ++ incidence->setReadOnly( true ); ++ } ++ } ++ ++ if ( alreadyExisted && m_itemDateForItemId.contains( item.id() ) ) { ++ // for changed items, we must remove existing date entries (they might have changed) ++ m_itemIdsForDate.remove( m_itemDateForItemId[item.id()], item.id() ); ++ m_itemDateForItemId.remove( item.id() ); ++ } ++ ++ QString date; ++ if ( const KCalCore::Todo::Ptr t = CalendarSupport::todo( item ) ) { ++ if ( t->hasDueDate() ) { ++ date = t->dtDue().date().toString(); ++ } ++ } else if ( const KCalCore::Event::Ptr e = CalendarSupport::event( item ) ) { ++ if ( !e->recurs() && !e->isMultiDay() ) { ++ date = e->dtStart().date().toString(); ++ } ++ } else if ( const KCalCore::Journal::Ptr j = CalendarSupport::journal( item ) ) { ++ date = j->dtStart().date().toString(); ++ } else { ++ kError() << "Item id is " << item.id() ++ << item.hasPayload() ++ << item.hasPayload() ++ << item.hasPayload() ++ << item.hasPayload(); ++ KCalCore::Incidence::Ptr p = CalendarSupport::incidence( item ); ++ if ( p ) { ++ kError() << "incidence uid is " << p->uid() ++ << " and type is " << p->typeStr(); ++ } ++ ++ Q_ASSERT( false ); ++ return; ++ } ++ ++ if ( !m_itemIdsForDate.contains( date, item.id() ) && !date.isEmpty() ) { ++ m_itemIdsForDate.insert( date, item.id() ); ++ m_itemDateForItemId.insert( item.id(), date ); ++ } ++ ++ m_itemMap.insert( id, item ); ++ ++ UnseenItem ui; ++ ui.collection = item.storageCollectionId(); ++ ui.uid = incidence->uid(); ++ ++ //REVIEW(AKONADI_PORT) ++ //UIDs might be duplicated and thus not unique, so for now we assume that the relatedTo ++ // UID refers to an item in the same collection. ++ //this might break with virtual collections, so we might fall back to a global UID ++ //to akonadi item mapping, and pick just any item (or the first found, or whatever ++ //strategy makes sense) from the ones with the same UID ++ const QString parentUID = incidence->relatedTo(); ++ const bool hasParent = !parentUID.isEmpty(); ++ UnseenItem parentItem; ++ QMap::const_iterator parentIt = m_uidToItemId.constEnd(); ++ bool knowParent = false; ++ bool parentNotChanged = false; ++ if ( hasParent ) { ++ parentItem.collection = item.storageCollectionId(); ++ parentItem.uid = parentUID; ++ parentIt = m_uidToItemId.constFind( parentItem ); ++ knowParent = parentIt != m_uidToItemId.constEnd(); ++ } ++ ++ if ( alreadyExisted ) { // We're updating an existing item ++ const bool existedInUidMap = m_uidToItemId.contains( ui ); ++ if ( m_uidToItemId.value( ui ) != item.id() ) { ++ kError()<< "Ignoring item. item.id() = " << item.id() << "; cached id = " << m_uidToItemId.value( ui ) ++ << "; item uid = " << ui.uid ++ << "; calendar = " << q->objectName() ++ << "; existed in cache = " << existedInUidMap ++ << "; storageCollection.id() = " << item.storageCollectionId() // the real collection ++ << "; parentCollection.id() = " << item.parentCollection().id() // can be a virtual collection ++ << "; hasParent = " << hasParent ++ << "; knowParent = " << knowParent; ++ if ( existedInUidMap ) { ++ Q_ASSERT_X( false, "updateItem", "uidToId map disagrees with item id" ); ++ } else { ++ kDebug() << "m_uidToItemId has size " << m_uidToItemId.count(); ++ QMapIterator i( m_uidToItemId ); ++ while ( i.hasNext() ) { ++ i.next(); ++ if ( i.key().uid == ui.uid || i.value() == item.id() ) { ++ kDebug() << " key " << i.key().uid << i.key().collection << " has value " << i.value(); ++ } ++ } ++ kError() << "Possible cause is that the resource isn't explicitly setting an uid ( and a random one is generated )"; ++ Q_ASSERT_X( false, "updateItem", "Item not found inside m_uidToItemId" ); ++ } ++ return; ++ } ++ ++ QHash::Iterator oldParentIt = m_childToParent.find( id ); ++ if ( oldParentIt != m_childToParent.end() ) { ++ const KCalCore::Incidence::Ptr parentInc = ++ CalendarSupport::incidence( m_itemMap.value( oldParentIt.value() ) ); ++ Q_ASSERT( parentInc ); ++ if ( parentInc->uid() != parentUID ) { ++ //parent changed, remove old entries ++ QList& l = m_parentToChildren[oldParentIt.value()]; ++ l.removeAll( id ); ++ m_childToParent.remove( id ); ++ } else { ++ parentNotChanged = true; ++ } ++ } else { //old parent not seen, maybe unseen? ++ QHash::Iterator oldUnseenParentIt = ++ m_childToUnseenParent.find( id ); ++ if ( oldUnseenParentIt != m_childToUnseenParent.end() ) { ++ if ( oldUnseenParentIt.value().uid != parentUID ) { ++ //parent changed, remove old entries ++ QList& l = m_unseenParentToChildren[oldUnseenParentIt.value()]; ++ l.removeAll( id ); ++ m_childToUnseenParent.remove( id ); ++ } else { ++ parentNotChanged = true; ++ } ++ } ++ } ++ } else { // We're inserting a new item ++ m_uidToItemId.insert( ui, item.id() ); ++ ++ //check for already known children: ++ const QList orphanedChildren = m_unseenParentToChildren.value( ui ); ++ if ( !orphanedChildren.isEmpty() ) { ++ m_parentToChildren.insert( id, orphanedChildren ); ++ } ++ ++ Q_FOREACH ( const Akonadi::Item::Id &cid, orphanedChildren ) { ++ m_childToParent.insert( cid, id ); ++ } ++ ++ m_unseenParentToChildren.remove( ui ); ++ m_childToUnseenParent.remove( id ); ++ } ++ ++ if ( hasParent && !parentNotChanged ) { ++ if ( knowParent ) { ++ Q_ASSERT( !m_parentToChildren.value( parentIt.value() ).contains( id ) ); ++ const KCalCore::Incidence::Ptr parentInc = ++ CalendarSupport::incidence( m_itemMap.value( parentIt.value() ) ); ++ Q_ASSERT( parentInc ); ++ m_parentToChildren[parentIt.value()].append( id ); ++ m_childToParent.insert( id, parentIt.value() ); ++ } else { ++ m_childToUnseenParent.insert( id, parentItem ); ++ m_unseenParentToChildren[parentItem].append( id ); ++ } ++ } ++ ++ if ( !alreadyExisted ) { ++ incidence->registerObserver( q ); ++ q->notifyIncidenceAdded( item ); ++ } else { ++ q->notifyIncidenceChanged( item ); ++ } ++ assertInvariants(); ++} ++ ++void Calendar::Private::itemChanged( const Akonadi::Item &item ) ++{ ++ assertInvariants(); ++ Q_ASSERT( item.isValid() ); ++ const KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( item ); ++ if ( !incidence ) { ++ kWarning() << "Really? No incidence for item.id() " << item.id(); ++ return; ++ } ++ updateItem( item, AssertExists ); ++ emit q->calendarChanged(); ++ assertInvariants(); ++} ++ ++void Calendar::Private::itemsAdded( const Akonadi::Item::List &items ) ++{ ++ assertInvariants(); ++ foreach ( const Akonadi::Item &item, items ) { ++ Q_ASSERT( item.isValid() ); ++ if ( !hasIncidence( item ) ) { ++ continue; ++ } ++ updateItem( item, AssertNew ); ++ const KCalCore::Incidence::Ptr incidence = item.payload(); ++ } ++ emit q->calendarChanged(); ++ assertInvariants(); ++} ++ ++void Calendar::Private::collectionsAdded( const Akonadi::Collection::List &collections ) ++{ ++ foreach ( const Akonadi::Collection &collection, collections ) { ++ m_collectionMap[collection.id()] = collection; ++ } ++} ++ ++void Calendar::Private::collectionsRemoved( const Akonadi::Collection::List &collections ) ++{ ++ // kDebug() << "removing collections: " << collections.count(); ++ foreach ( const Akonadi::Collection &collection, collections ) { ++ m_collectionMap.remove( collection.id() ); ++ } ++} ++ ++void Calendar::Private::removeItemFromMaps( const Akonadi::Item &item ) ++{ ++ UnseenItem unseen_item; ++ UnseenItem unseen_parent; ++ ++ unseen_item.collection = unseen_parent.collection = item.storageCollectionId(); ++ ++ KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( item ); ++ if ( incidence ) { ++ unseen_item.uid = incidence->uid(); ++ unseen_parent.uid = incidence->relatedTo(); ++ } ++ ++ if ( m_childToParent.contains( item.id() ) ) { ++ Akonadi::Item::Id parentId = m_childToParent.take( item.id() ); ++ m_parentToChildren[parentId].removeAll( item.id() ); ++ } ++ ++ foreach ( const Akonadi::Item::Id &id, m_parentToChildren[item.id()] ) { ++ m_childToUnseenParent[id] = unseen_item; ++ m_unseenParentToChildren[unseen_item].push_back( id ); ++ } ++ ++ m_parentToChildren.remove( item.id() ); ++ ++ m_childToUnseenParent.remove( item.id() ); ++ ++ m_unseenParentToChildren[unseen_parent].removeAll( item.id() ); ++ ++ m_uidToItemId.remove( unseen_item ); ++ m_itemDateForItemId.remove( item.id() ); ++ ++ const QList entriesToDelete = m_itemIdsForDate.keys( item.id() ); ++ foreach( const QString &entryToDelete, entriesToDelete ) { ++ m_itemIdsForDate.remove( entryToDelete ); ++ } ++} ++ ++void Calendar::Private::itemsRemoved( const Akonadi::Item::List &items ) ++{ ++ assertInvariants(); ++ foreach ( const Akonadi::Item &item, items ) { ++ Q_ASSERT( item.isValid() ); ++ ++ if ( !m_virtualItems.value( item.id() ).isEmpty() ) { ++ // We have more than one item with the same id, due to virtual folders, so we can't ++ // cleanup any hashes, to-do hierarchies, id to uid maps, etc, yet. We can only do that ++ // when the last item is removed. Just decrement and return. ++ m_virtualItems[item.id()].removeLast(); ++ q->notifyIncidenceDeleted( item ); ++ emit q->calendarChanged(); ++ return; ++ } ++ ++ if ( !m_itemMap.contains( item.id() ) ) { ++ /** There's an off by one error in the ETM which steveire doesn't have time right now to look at. ++ * When removing an item in korganizer, the plasma's calendar ETM emits rowsAboutToBeRemoved() ++ * for the wrong item, which makes plasma crash. ++ * ++ * I won't remove this hack in the future because this code is to be deleted and replaced by ++ * kdepimlibs/akonadi/calendar/etmcalendar.cpp ( branch calendaring ), which i'm currently writting ++ * unit tests. So until then no need to crash with an empty payload exception. ++ */ ++ return; ++ } ++ ++ Akonadi::Item oldItem( m_itemMap.take( item.id() ) ); ++ ++ removeItemFromMaps( oldItem ); ++ ++ Q_ASSERT( oldItem.hasPayload() ); ++ const KCalCore::Incidence::Ptr incidence = oldItem.payload(); ++ /* ++ kDebug() << "Remove uid=" << incidence->uid() ++ << "summary=" << incidence->summary() ++ << "type=" << int( incidence->type() ) ++ << "; id= " << item.id() << "; revision=" << item.revision() ++ << " calendar = " ++ << q; ++ */ ++ ++ if ( const KCalCore::Event::Ptr e = incidence.dynamicCast() ) { ++ if ( !e->recurs() ) { ++ m_itemIdsForDate.remove( e->dtStart().date().toString(), item.id() ); ++ } ++ } else if ( const KCalCore::Todo::Ptr t = incidence.dynamicCast( ) ) { ++ if ( t->hasDueDate() ) { ++ m_itemIdsForDate.remove( t->dtDue().date().toString(), item.id() ); ++ } ++ } else if ( const KCalCore::Journal::Ptr j = incidence.dynamicCast() ) { ++ m_itemIdsForDate.remove( j->dtStart().date().toString(), item.id() ); ++ } else { ++ kError() << "Unsupported incidence type: " << incidence; ++ Q_ASSERT( false ); ++ continue; ++ } ++ ++ // oldItem will almost always be the same as item, but, when you move an item from one collection ++ // and the destination collection isn't selected, itemsRemoved() is called, and they will differ ++ // on the parentCollection id. ++ q->notifyIncidenceDeleted( oldItem ); ++ incidence->unRegisterObserver( q ); ++ } ++ emit q->calendarChanged(); ++ assertInvariants(); ++} ++ ++Calendar::Calendar( QAbstractItemModel *treeModel, QAbstractItemModel *model, ++ const KDateTime::Spec &timeSpec, QObject *parent ) ++ : QObject( parent ), d( new Private( treeModel, model, this ) ) ++{ ++ d->mTimeSpec = timeSpec; ++ d->mViewTimeSpec = timeSpec; ++ d->readFromModel(); ++} ++ ++Calendar::~Calendar() ++{ ++ delete d; ++} ++ ++QAbstractItemModel *Calendar::treeModel() const ++{ ++ return d->m_treeModel; ++} ++ ++QAbstractItemModel *Calendar::model() const ++{ ++ return d->m_filterProxy; ++} ++ ++QAbstractItemModel *Calendar::unfilteredModel() const ++{ ++ return d->m_model; ++} ++ ++void Calendar::setUnfilteredModel( QAbstractItemModel *model ) ++{ ++ ++ if ( d->m_model == model ) { ++ return; ++ } ++ ++ if ( d->m_model ) { ++ disconnect( d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), ++ d, SLOT(dataChanged(QModelIndex,QModelIndex)) ); ++ ++ disconnect( d->m_model, SIGNAL(layoutChanged()), ++ d, SLOT(layoutChanged()) ); ++ ++ disconnect( d->m_model, SIGNAL(modelReset()), ++ d, SLOT(modelReset()) ); ++ ++ disconnect( d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), ++ d, SLOT(rowsInserted(QModelIndex,int,int)) ); ++ ++ disconnect( d->m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), ++ d, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)) ); ++ } ++ d->m_model = model; ++ d->m_filterProxy->setSourceModel( model ); ++ if ( model ) { ++ connect( d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), ++ d, SLOT(dataChanged(QModelIndex,QModelIndex)) ); ++ ++ connect( d->m_model, SIGNAL(layoutChanged()), ++ d, SLOT(layoutChanged()) ); ++ ++ connect( d->m_model, SIGNAL(modelReset()), ++ d, SLOT(modelReset()) ); ++ ++ connect( d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), ++ d, SLOT(rowsInserted(QModelIndex,int,int)) ); ++ ++ connect( d->m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), ++ d, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)) ); ++ d->modelReset(); ++ } ++} ++ ++// This method will be called probably multiple times if a series of changes where done. ++// One finished the endChange() method got called. ++ ++void Calendar::incidenceUpdate( const QString &uid, const KDateTime &recurrenceId ) ++{ ++ Q_UNUSED( uid ); ++ Q_UNUSED( recurrenceId ); ++} ++ ++void Calendar::incidenceUpdated( const QString &uid, const KDateTime &recurrenceId ) ++{ ++ Q_UNUSED( recurrenceId ); ++ KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( itemForIncidenceUid( uid ) ); ++ ++ if ( !incidence ) { ++ return; ++ } ++ ++ incidence->setLastModified( KDateTime::currentUtcDateTime() ); ++ // we should probably update the revision number here, ++ // or internally in the Event itself when certain things change. ++ // need to verify with ical documentation. ++ ++ // The static_cast is ok as the CalendarLocal only observes Incidence objects ++#ifdef AKONADI_PORT_DISABLED ++ notifyIncidenceChanged( static_cast( incidence ) ); ++#else ++ kDebug() << "AKONADI PORT: Disabled code in " << Q_FUNC_INFO; ++#endif ++} ++ ++Akonadi::Item Calendar::event( Akonadi::Item::Id id ) const ++{ ++ const Akonadi::Item item = d->m_itemMap.value( id ); ++ if ( CalendarSupport::event( item ) ) { ++ return item; ++ } else { ++ return Akonadi::Item(); ++ } ++} ++ ++Akonadi::Item Calendar::todo( Akonadi::Item::Id id ) const ++{ ++ const Akonadi::Item item = d->m_itemMap.value( id ); ++ if ( CalendarSupport::todo( item ) ) { ++ return item; ++ } else { ++ return Akonadi::Item(); ++ } ++} ++ ++Akonadi::Item::List Calendar::rawTodos( TodoSortField sortField, ++ SortDirection sortDirection ) ++{ ++ Akonadi::Item::List todoList; ++ QHashIterator i( d->m_itemMap ); ++ while ( i.hasNext() ) { ++ i.next(); ++ if ( CalendarSupport::todo( i.value() ) ) { ++ todoList.append( i.value() ); ++ } ++ } ++ d->appendVirtualItems( todoList ); ++ return sortTodos( todoList, sortField, sortDirection ); ++} ++ ++Akonadi::Item::List Calendar::rawTodosForDate( const QDate &date ) ++{ ++ Akonadi::Item::List todoList; ++ QString dateStr = date.toString(); ++ QMultiHash::const_iterator it = ++ d->m_itemIdsForDate.constFind( dateStr ); ++ while ( it != d->m_itemIdsForDate.constEnd() && it.key() == dateStr ) { ++ if ( CalendarSupport::todo( d->m_itemMap[it.value()] ) ) { ++ todoList.append( d->m_itemMap[it.value()] ); ++ } ++ ++it; ++ } ++ d->appendVirtualItems( todoList ); ++ return todoList; ++} ++ ++KCalCore::Alarm::List Calendar::alarmsTo( const KDateTime &to ) ++{ ++ return alarms( KDateTime( QDate( 1900, 1, 1 ) ), to ); ++} ++ ++KCalCore::Alarm::List Calendar::alarms( const KDateTime &from, const KDateTime &to, bool excludeBlockedAlarms ) ++{ ++ KCalCore::Alarm::List alarmList; ++ QHashIterator i( d->m_itemMap ); ++ while ( i.hasNext() ) { ++ const Akonadi::Item item = i.next().value(); ++ ++ if ( excludeBlockedAlarms ) { ++ // take the collection from m_collectionMap, because we need the up-to-date collection attributes ++ const Akonadi::Collection parentCollection = d->m_collectionMap.value( item.storageCollectionId() ); ++ if ( parentCollection.isValid() ) { ++ if ( parentCollection.hasAttribute() ) ++ continue; // do not include alarms from this collection ++ } ++ } ++ ++ KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( item ); ++ if ( !incidence ) { ++ continue; ++ } ++ ++ if ( incidence->recurs() ) { ++ appendRecurringAlarms( alarmList, item, from, to ); ++ } else { ++ appendAlarms( alarmList, item, from, to ); ++ } ++ } ++ return alarmList; ++} ++ ++Akonadi::Item::List Calendar::rawEventsForDate( const QDate &date, ++ const KDateTime::Spec ×pec, ++ EventSortField sortField, ++ SortDirection sortDirection ) ++{ ++ Akonadi::Item::List eventList; ++ // Find the hash for the specified date ++ const QString dateStr = date.toString(); ++ // Iterate over all non-recurring, single-day events that start on this date ++ QMultiHash::const_iterator it = ++ d->m_itemIdsForDate.constFind( dateStr ); ++ KDateTime::Spec ts = timespec.isValid() ? timespec : timeSpec(); ++ KDateTime kdt( date, ts ); ++ while ( it != d->m_itemIdsForDate.constEnd() && it.key() == dateStr ) { ++ if ( KCalCore::Event::Ptr ev = CalendarSupport::event( d->m_itemMap[it.value()] ) ) { ++ KDateTime end( ev->dtEnd().toTimeSpec( ev->dtStart() ) ); ++ if ( ev->allDay() ) { ++ end.setDateOnly( true ); ++ } else { ++ end = end.addSecs( -1 ); ++ } ++ if ( end >= kdt ) { ++ eventList.append( d->m_itemMap[it.value()] ); ++ } ++ } ++ ++it; ++ } ++ // Iterate over all events. Look for recurring events that occur on this date ++ QHashIterator i( d->m_itemMap ); ++ while ( i.hasNext() ) { ++ i.next(); ++ if ( KCalCore::Event::Ptr ev = CalendarSupport::event( i.value() ) ) { ++ if ( ev->recurs() ) { ++ if ( ev->isMultiDay() ) { ++ int extraDays = ev->dtStart().date().daysTo( ev->dtEnd().date() ); ++ for ( int j = 0; j <= extraDays; ++j ) { ++ if ( ev->recursOn( date.addDays( -j ), ts ) ) { ++ eventList.append( i.value() ); ++ break; ++ } ++ } ++ } else { ++ if ( ev->recursOn( date, ts ) ) { ++ eventList.append( i.value() ); ++ } ++ } ++ } else { ++ if ( ev->isMultiDay() ) { ++ if ( ev->dtStart().date() <= date && ev->dtEnd().date() >= date ) { ++ eventList.append( i.value() ); ++ } ++ } ++ } ++ } ++ } ++ ++ d->appendVirtualItems( eventList ); ++ ++ return sortEvents( eventList, sortField, sortDirection ); ++} ++ ++Akonadi::Item::List Calendar::rawEvents( const QDate &start, const QDate &end, ++ const KDateTime::Spec ×pec, bool inclusive ) ++{ ++ Akonadi::Item::List eventList; ++ KDateTime::Spec ts = timespec.isValid() ? timespec : timeSpec(); ++ KDateTime st( start, ts ); ++ KDateTime nd( end, ts ); ++ KDateTime yesterStart = st.addDays( -1 ); ++ // Get non-recurring events ++ QHashIterator i( d->m_itemMap ); ++ while ( i.hasNext() ) { ++ i.next(); ++ if ( KCalCore::Event::Ptr event = CalendarSupport::event( i.value() ) ) { ++ KDateTime rStart = event->dtStart(); ++ if ( nd < rStart ) continue; ++ if ( inclusive && rStart < st ) { ++ continue; ++ } ++ if ( !event->recurs() ) { // non-recurring events ++ KDateTime rEnd = event->dtEnd(); ++ if ( rEnd < st ) { ++ continue; ++ } ++ if ( inclusive && nd < rEnd ) { ++ continue; ++ } ++ } else { // recurring events ++ switch( event->recurrence()->duration() ) { ++ case -1: // infinite ++ if ( inclusive ) { ++ continue; ++ } ++ break; ++ case 0: // end date given ++ default: // count given ++ KDateTime rEnd( event->recurrence()->endDate(), ts ); ++ if ( !rEnd.isValid() ) { ++ continue; ++ } ++ if ( rEnd < st ) { ++ continue; ++ } ++ if ( inclusive && nd < rEnd ) { ++ continue; ++ } ++ break; ++ } // switch(duration) ++ } //if (recurs) ++ eventList.append( i.value() ); ++ } ++ } ++ ++ d->appendVirtualItems( eventList ); ++ ++ return eventList; ++} ++ ++Akonadi::Item::List Calendar::rawEventsForDate( const KDateTime &kdt ) ++{ ++ return rawEventsForDate( kdt.date(), kdt.timeSpec() ); ++} ++ ++Akonadi::Item::List Calendar::rawEvents( EventSortField sortField, ++ SortDirection sortDirection ) ++{ ++ Akonadi::Item::List eventList; ++ QHashIterator i( d->m_itemMap ); ++ while ( i.hasNext() ) { ++ i.next(); ++ if ( CalendarSupport::event( i.value() ) ) { ++ eventList.append( i.value() ); ++ } ++ } ++ d->appendVirtualItems( eventList ); ++ return sortEvents( eventList, sortField, sortDirection ); ++} ++ ++Akonadi::Item Calendar::journal( Akonadi::Item::Id id ) const ++{ ++ const Akonadi::Item item = d->m_itemMap.value( id ); ++ if ( CalendarSupport::journal( item ) ) { ++ return item; ++ } else { ++ return Akonadi::Item(); ++ } ++} ++ ++Akonadi::Item::List Calendar::rawJournals( JournalSortField sortField, ++ SortDirection sortDirection ) ++{ ++ Akonadi::Item::List journalList; ++ QHashIterator i( d->m_itemMap ); ++ while ( i.hasNext() ) { ++ i.next(); ++ if ( CalendarSupport::journal( i.value() ) ) { ++ journalList.append( i.value() ); ++ } ++ } ++ d->appendVirtualItems( journalList ); ++ return sortJournals( journalList, sortField, sortDirection ); ++} ++ ++Akonadi::Item::List Calendar::rawJournalsForDate( const QDate &date ) ++{ ++ Akonadi::Item::List journalList; ++ QString dateStr = date.toString(); ++ QMultiHash::const_iterator it = ++ d->m_itemIdsForDate.constFind( dateStr ); ++ while ( it != d->m_itemIdsForDate.constEnd() && it.key() == dateStr ) { ++ if ( CalendarSupport::journal( d->m_itemMap[it.value()] ) ) { ++ journalList.append( d->m_itemMap[it.value()] ); ++ } ++ ++it; ++ } ++ d->appendVirtualItems( journalList ); ++ return journalList; ++} ++ ++Akonadi::Item Calendar::findParent( const Akonadi::Item &child ) const ++{ ++ return d->m_itemMap.value( d->m_childToParent.value( child.id() ) ); ++} ++ ++Akonadi::Item::List Calendar::findChildren( const KCalCore::Incidence::Ptr &incidence ) const ++{ ++ Akonadi::Item item = itemForIncidenceUid( incidence->uid() ); ++ ++ return findChildren( item ); ++} ++ ++Akonadi::Item::List Calendar::findChildren( const Akonadi::Item &parent ) const ++{ ++ Akonadi::Item::List l; ++ Q_FOREACH( const Akonadi::Item::Id &id, d->m_parentToChildren.value( parent.id() ) ) { ++ l.push_back( d->m_itemMap.value( id ) ); ++ } ++ return l; ++} ++ ++bool Calendar::isChild( const Akonadi::Item &parent, const Akonadi::Item &child ) const ++{ ++ return d->m_childToParent.value( child.id() ) == parent.id(); ++} ++ ++Akonadi::Item::Id Calendar::itemIdForIncidenceUid( const QString &uid ) const ++{ ++ QHashIterator i( d->m_itemMap ); ++ while ( i.hasNext() ) { ++ i.next(); ++ const Akonadi::Item item = i.value(); ++ Q_ASSERT( item.isValid() ); ++ Q_ASSERT( item.hasPayload() ); ++ KCalCore::Incidence::Ptr inc = item.payload(); ++ if ( inc->uid() == uid ) { ++ return item.id(); ++ } ++ } ++ kWarning() << "Failed to find Akonadi::Item for KCal uid " << uid; ++ return -1; ++} ++ ++Akonadi::Item Calendar::itemForIncidenceUid( const QString &uid ) const ++{ ++ return incidence( itemIdForIncidenceUid( uid ) ); ++} ++ ++// calendarbase.cpp ++ ++KCalCore::Person Calendar::owner() const ++{ ++ return d->mOwner; ++} ++ ++void Calendar::setOwner( const KCalCore::Person &owner ) ++{ ++ d->mOwner = owner; ++} ++ ++void Calendar::setTimeSpec( const KDateTime::Spec &timeSpec ) ++{ ++ d->mTimeSpec = timeSpec; ++ d->mBuiltInTimeZone = KCalCore::ICalTimeZone(); ++ setViewTimeSpec( timeSpec ); ++ ++ doSetTimeSpec( d->mTimeSpec ); ++} ++ ++KDateTime::Spec Calendar::timeSpec() const ++{ ++ return d->mTimeSpec; ++} ++ ++void Calendar::setTimeZoneId( const QString &timeZoneId ) ++{ ++ d->mTimeSpec = d->timeZoneIdSpec( timeZoneId, false ); ++ d->mViewTimeSpec = d->mTimeSpec; ++ d->mBuiltInViewTimeZone = d->mBuiltInTimeZone; ++ ++ doSetTimeSpec( d->mTimeSpec ); ++} ++ ++//@cond PRIVATE ++KDateTime::Spec Calendar::Private::timeZoneIdSpec( const QString &timeZoneId, ++ bool view ) ++{ ++ if ( view ) { ++ mBuiltInViewTimeZone = KCalCore::ICalTimeZone(); ++ } else { ++ mBuiltInTimeZone = KCalCore::ICalTimeZone(); ++ } ++ if ( timeZoneId == QLatin1String( "UTC" ) ) { ++ return KDateTime::UTC; ++ } ++ KCalCore::ICalTimeZone tz = mTimeZones->zone( timeZoneId ); ++ if ( !tz.isValid() ) { ++ KCalCore::ICalTimeZoneSource tzsrc; ++#ifdef AKONADI_PORT_DISABLED ++ tz = tzsrc.parse( icaltimezone_get_builtin_timezone( timeZoneId.toLatin1() ) ); ++#else ++ kDebug() << "AKONADI PORT: Disabled code in " << Q_FUNC_INFO; ++#endif ++ if ( view ) { ++ mBuiltInViewTimeZone = tz; ++ } else { ++ mBuiltInTimeZone = tz; ++ } ++ } ++ if ( tz.isValid() ) { ++ return tz; ++ } else { ++ return KDateTime::ClockTime; ++ } ++} ++//@endcond ++ ++QString Calendar::timeZoneId() const ++{ ++ KTimeZone tz = d->mTimeSpec.timeZone(); ++ return tz.isValid() ? tz.name() : QString(); ++} ++ ++void Calendar::setViewTimeSpec( const KDateTime::Spec &timeSpec ) const ++{ ++ d->mViewTimeSpec = timeSpec; ++ d->mBuiltInViewTimeZone = KCalCore::ICalTimeZone(); ++} ++ ++void Calendar::setViewTimeZoneId( const QString &timeZoneId ) const ++{ ++ d->mViewTimeSpec = d->timeZoneIdSpec( timeZoneId, true ); ++} ++ ++KDateTime::Spec Calendar::viewTimeSpec() const ++{ ++ return d->mViewTimeSpec; ++} ++ ++QString Calendar::viewTimeZoneId() const ++{ ++ KTimeZone tz = d->mViewTimeSpec.timeZone(); ++ return tz.isValid() ? tz.name() : QString(); ++} ++ ++void Calendar::shiftTimes( const KDateTime::Spec &oldSpec, ++ const KDateTime::Spec &newSpec ) ++{ ++ setTimeSpec( newSpec ); ++ int i, end; ++ Akonadi::Item::List ev = events(); ++ for ( i = 0, end = ev.count(); i < end; ++i ) { ++ CalendarSupport::event( ev[i] )->shiftTimes( oldSpec, newSpec ); ++ } ++ ++ Akonadi::Item::List to = todos(); ++ for ( i = 0, end = to.count(); i < end; ++i ) { ++ CalendarSupport::todo( to[i] )->shiftTimes( oldSpec, newSpec ); ++ } ++ ++ Akonadi::Item::List jo = journals(); ++ for ( i = 0, end = jo.count(); i < end; ++i ) { ++ CalendarSupport::journal( jo[i] )->shiftTimes( oldSpec, newSpec ); ++ } ++} ++ ++void Calendar::setFilter( KCalCore::CalFilter *filter ) ++{ ++ d->m_filterProxy->setFilter( filter ? filter : d->mDefaultFilter ); ++} ++ ++KCalCore::CalFilter *Calendar::filter() ++{ ++ return d->m_filterProxy->filter(); ++} ++ ++QStringList Calendar::categories( Calendar *cal ) ++{ ++ Akonadi::Item::List rawInc( cal->rawIncidences() ); ++ QStringList cats, thisCats; ++ // @TODO: For now just iterate over all incidences. In the future, ++ // the list of categories should be built when reading the file. ++ Q_FOREACH( const Akonadi::Item &i, rawInc ) { ++ thisCats = CalendarSupport::incidence( i )->categories(); ++ for ( QStringList::ConstIterator si = thisCats.constBegin(); ++ si != thisCats.constEnd(); ++si ) { ++ if ( !cats.contains( *si ) ) { ++ cats.append( *si ); ++ } ++ } ++ } ++ return cats; ++} ++ ++Akonadi::Item::List Calendar::incidences( const QDate &date ) ++{ ++ return mergeIncidenceList( events( date ), todos( date ), journals( date ) ); ++} ++ ++Akonadi::Item::List Calendar::incidences() ++{ ++ if ( d->m_filterProxy->filter() == 0 || !d->m_filterProxy->filter()->isEnabled() ) { ++ // Lets skip the filterProxy and return m_itemMap, which is cheaper. ++ return rawIncidences(); ++ } else { ++ return itemsFromModel( d->m_filterProxy ); ++ } ++} ++ ++Akonadi::Item::List Calendar::rawIncidences() ++{ ++ // The following code is 100x faster than: return itemsFromModel( d->m_model ) ++ QHashIterator i( d->m_itemMap ); ++ Akonadi::Item::List list; ++ while ( i.hasNext() ) { ++ i.next(); ++ list.append( i.value() ); ++ } ++ ++ return list; ++} ++ ++Akonadi::Item::List Calendar::sortEvents( const Akonadi::Item::List &eventList_, ++ EventSortField sortField, ++ SortDirection sortDirection ) ++{ ++ Akonadi::Item::List eventList = eventList_; ++ Akonadi::Item::List eventListSorted; ++ Akonadi::Item::List tempList, t; ++ Akonadi::Item::List alphaList; ++ Akonadi::Item::List::Iterator sortIt; ++ Akonadi::Item::List::Iterator eit; ++ ++ // Notice we alphabetically presort Summaries first. ++ // We do this so comparison "ties" stay in a nice order. ++ ++ switch( sortField ) { ++ case EventSortUnsorted: ++ eventListSorted = eventList; ++ break; ++ ++ case EventSortStartDate: ++ alphaList = sortEvents( eventList, EventSortSummary, sortDirection ); ++ for ( eit = alphaList.begin(); eit != alphaList.end(); ++eit ) { ++ KCalCore::Event::Ptr e = CalendarSupport::event( *eit ); ++ Q_ASSERT( e ); ++ if ( e->dtStart().isDateOnly() ) { ++ tempList.append( *eit ); ++ continue; ++ } ++ sortIt = eventListSorted.begin(); ++ if ( sortDirection == SortDirectionAscending ) { ++ while ( sortIt != eventListSorted.end() && ++ e->dtStart() >= CalendarSupport::event(*sortIt)->dtStart() ) { ++ ++sortIt; ++ } ++ } else { ++ while ( sortIt != eventListSorted.end() && ++ e->dtStart() < CalendarSupport::event(*sortIt)->dtStart() ) { ++ ++sortIt; ++ } ++ } ++ eventListSorted.insert( sortIt, *eit ); ++ } ++ if ( sortDirection == SortDirectionAscending ) { ++ // Prepend the list of Events without End DateTimes ++ tempList += eventListSorted; ++ eventListSorted = tempList; ++ } else { ++ // Append the list of Events without End DateTimes ++ eventListSorted += tempList; ++ } ++ break; ++ ++ case EventSortEndDate: ++ alphaList = sortEvents( eventList, EventSortSummary, sortDirection ); ++ for ( eit = alphaList.begin(); eit != alphaList.end(); ++eit ) { ++ KCalCore::Event::Ptr e = CalendarSupport::event( *eit ); ++ Q_ASSERT( e ); ++ if ( e->hasEndDate() ) { ++ sortIt = eventListSorted.begin(); ++ if ( sortDirection == SortDirectionAscending ) { ++ while ( sortIt != eventListSorted.end() && ++ e->dtEnd() >= CalendarSupport::event(*sortIt)->dtEnd() ) { ++ ++sortIt; ++ } ++ } else { ++ while ( sortIt != eventListSorted.end() && ++ e->dtEnd() < CalendarSupport::event(*sortIt)->dtEnd() ) { ++ ++sortIt; ++ } ++ } ++ } else { ++ // Keep a list of the Events without End DateTimes ++ tempList.append( *eit ); ++ } ++ eventListSorted.insert( sortIt, *eit ); ++ } ++ if ( sortDirection == SortDirectionAscending ) { ++ // Append the list of Events without End DateTimes ++ eventListSorted += tempList; ++ } else { ++ // Prepend the list of Events without End DateTimes ++ tempList += eventListSorted; ++ eventListSorted = tempList; ++ } ++ break; ++ ++ case EventSortSummary: ++ for ( eit = eventList.begin(); eit != eventList.end(); ++eit ) { ++ KCalCore::Event::Ptr e = CalendarSupport::event( *eit ); ++ Q_ASSERT( e ); ++ sortIt = eventListSorted.begin(); ++ if ( sortDirection == SortDirectionAscending ) { ++ while ( sortIt != eventListSorted.end() && ++ e->summary() >= CalendarSupport::event(*sortIt)->summary() ) { ++ ++sortIt; ++ } ++ } else { ++ while ( sortIt != eventListSorted.end() && ++ e->summary() < CalendarSupport::event(*sortIt)->summary() ) { ++ ++sortIt; ++ } ++ } ++ eventListSorted.insert( sortIt, *eit ); ++ } ++ break; ++ } ++ ++ return eventListSorted; ++} ++ ++Akonadi::Item::List Calendar::events( const QDate &date, ++ const KDateTime::Spec &timeSpec, ++ EventSortField sortField, ++ SortDirection sortDirection ) ++{ ++ const Akonadi::Item::List el = rawEventsForDate( date, timeSpec, sortField, sortDirection ); ++ return applyCalFilter( el, filter() ); ++} ++ ++Akonadi::Item::List Calendar::events( const KDateTime &dt ) ++{ ++ const Akonadi::Item::List el = rawEventsForDate( dt ); ++ return applyCalFilter( el, filter() ); ++} ++ ++Akonadi::Item::List Calendar::events( const QDate &start, const QDate &end, ++ const KDateTime::Spec &timeSpec, ++ bool inclusive ) ++{ ++ const Akonadi::Item::List el = rawEvents( start, end, timeSpec, inclusive ); ++ return applyCalFilter( el, filter() ); ++} ++ ++Akonadi::Item::List Calendar::events( EventSortField sortField, ++ SortDirection sortDirection ) ++{ ++ const Akonadi::Item::List el = rawEvents( sortField, sortDirection ); ++ return applyCalFilter( el, filter() ); ++} ++ ++KCalCore::Incidence::Ptr Calendar::dissociateOccurrence( const Akonadi::Item &item, ++ const QDate &date, ++ const KDateTime::Spec &spec, ++ bool single ) ++{ ++ if ( !item.isValid() ) { ++ return KCalCore::Incidence::Ptr(); ++ } ++ ++ const KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( item ); ++ if ( !incidence || !incidence->recurs() ) { ++ return KCalCore::Incidence::Ptr(); ++ } ++ ++ KCalCore::Incidence::Ptr newInc = KCalCore::Incidence::Ptr( incidence->clone() ); ++ newInc->recreate(); ++ // Do not call setRelatedTo() when dissociating recurring to-dos, otherwise the new to-do ++ // will appear as a child. Originally, we planned to set a relation with reltype SIBLING ++ // when dissociating to-dos, but currently kcal only supports reltype PARENT. ++ // We can uncomment the following line when we support the PARENT reltype. ++ //newInc->setRelatedTo( incidence ); ++ KCalCore::Recurrence *recur = newInc->recurrence(); ++ if ( single ) { ++ recur->clear(); ++ } else { ++ // Adjust the recurrence for the future incidences. In particular adjust ++ // the "end after n occurrences" rules! "No end date" and "end by ..." ++ // don't need to be modified. ++ int duration = recur->duration(); ++ if ( duration > 0 ) { ++ int doneduration = recur->durationTo( date.addDays( -1 ) ); ++ if ( doneduration >= duration ) { ++ kDebug() << "The dissociated event already occurred more often" ++ << "than it was supposed to ever occur. ERROR!"; ++ recur->clear(); ++ } else { ++ recur->setDuration( duration - doneduration ); ++ } ++ } ++ } ++ // Adjust the date of the incidence ++ if ( incidence->type() == KCalCore::IncidenceBase::TypeEvent ) { ++ KCalCore::Event::Ptr ev = newInc.staticCast(); ++ KDateTime start( ev->dtStart() ); ++ int daysTo = start.toTimeSpec( spec ).date().daysTo( date ); ++ ev->setDtStart( start.addDays( daysTo ) ); ++ ev->setDtEnd( ev->dtEnd().addDays( daysTo ) ); ++ } else if ( incidence->type() == KCalCore::IncidenceBase::TypeTodo ) { ++ KCalCore::Todo::Ptr td = newInc.staticCast(); ++ bool haveOffset = false; ++ int daysTo = 0; ++ if ( td->hasDueDate() ) { ++ KDateTime due( td->dtDue() ); ++ daysTo = due.toTimeSpec( spec ).date().daysTo( date ); ++ td->setDtDue( due.addDays( daysTo ), true ); ++ haveOffset = true; ++ } ++ if ( td->hasStartDate() ) { ++ KDateTime start( td->dtStart() ); ++ if ( !haveOffset ) { ++ daysTo = start.toTimeSpec( spec ).date().daysTo( date ); ++ } ++ td->setDtStart( start.addDays( daysTo ) ); ++ haveOffset = true; ++ } ++ } ++ recur = incidence->recurrence(); ++ if ( recur ) { ++ if ( single ) { ++ recur->addExDate( date ); ++ } else { ++ // Make sure the recurrence of the past events ends ++ // at the corresponding day ++ recur->setEndDate( date.addDays(-1) ); ++ } ++ } ++ return KCalCore::Incidence::Ptr( newInc ); ++} ++ ++Akonadi::Item Calendar::incidence( Akonadi::Item::Id uid ) const ++{ ++ Akonadi::Item i = event( uid ); ++ if ( i.isValid() ) { ++ return i; ++ } ++ ++ i = todo( uid ); ++ if ( i.isValid() ) { ++ return i; ++ } ++ ++ i = journal( uid ); ++ return i; ++} ++ ++Akonadi::Item::List Calendar::incidencesFromSchedulingID( const QString &sid ) ++{ ++ Akonadi::Item::List result; ++ const Akonadi::Item::List incidences = rawIncidences(); ++ Akonadi::Item::List::const_iterator it = incidences.begin(); ++ for ( ; it != incidences.end(); ++it ) { ++ if ( CalendarSupport::incidence(*it)->schedulingID() == sid ) { ++ result.append( *it ); ++ } ++ } ++ return result; ++} ++ ++Akonadi::Item Calendar::incidenceFromSchedulingID( const QString &UID ) ++{ ++ const Akonadi::Item::List incidences = rawIncidences(); ++ Akonadi::Item::List::const_iterator it = incidences.begin(); ++ for ( ; it != incidences.end(); ++it ) { ++ if ( CalendarSupport::incidence(*it)->schedulingID() == UID ) { ++ // Touchdown, and the crowd goes wild ++ return *it; ++ } ++ } ++ // Not found ++ return Akonadi::Item(); ++} ++ ++Akonadi::Item::List Calendar::sortTodos( const Akonadi::Item::List &todoList_, ++ TodoSortField sortField, ++ SortDirection sortDirection ) ++{ ++ Akonadi::Item::List todoList( todoList_ ); ++ Akonadi::Item::List todoListSorted; ++ Akonadi::Item::List tempList, t; ++ Akonadi::Item::List alphaList; ++ Akonadi::Item::List::Iterator sortIt; ++ Akonadi::Item::List::ConstIterator eit; ++ ++ // Notice we alphabetically presort Summaries first. ++ // We do this so comparison "ties" stay in a nice order. ++ ++ // Note that To-dos may not have Start DateTimes nor due DateTimes. ++ ++ switch( sortField ) { ++ case TodoSortUnsorted: ++ todoListSorted = todoList; ++ break; ++ ++ case TodoSortStartDate: ++ alphaList = sortTodos( todoList, TodoSortSummary, sortDirection ); ++ for ( eit = alphaList.constBegin(); eit != alphaList.constEnd(); ++eit ) { ++ const KCalCore::Todo::Ptr e = CalendarSupport::todo( *eit ); ++ if ( e->hasStartDate() ) { ++ sortIt = todoListSorted.begin(); ++ if ( sortDirection == SortDirectionAscending ) { ++ while ( sortIt != todoListSorted.end() && ++ e->dtStart() >= CalendarSupport::todo(*sortIt)->dtStart() ) { ++ ++sortIt; ++ } ++ } else { ++ while ( sortIt != todoListSorted.end() && ++ e->dtStart() < CalendarSupport::todo(*sortIt)->dtStart() ) { ++ ++sortIt; ++ } ++ } ++ todoListSorted.insert( sortIt, *eit ); ++ } else { ++ // Keep a list of the To-dos without Start DateTimes ++ tempList.append( *eit ); ++ } ++ } ++ if ( sortDirection == SortDirectionAscending ) { ++ // Append the list of To-dos without Start DateTimes ++ todoListSorted += tempList; ++ } else { ++ // Prepend the list of To-dos without Start DateTimes ++ tempList += todoListSorted; ++ todoListSorted = tempList; ++ } ++ break; ++ ++ case TodoSortDueDate: ++ alphaList = sortTodos( todoList, TodoSortSummary, sortDirection ); ++ for ( eit = alphaList.constBegin(); eit != alphaList.constEnd(); ++eit ) { ++ const KCalCore::Todo::Ptr e = CalendarSupport::todo( *eit ); ++ if ( e->hasDueDate() ) { ++ sortIt = todoListSorted.begin(); ++ if ( sortDirection == SortDirectionAscending ) { ++ while ( sortIt != todoListSorted.end() && ++ e->dtDue() >= CalendarSupport::todo( *sortIt )->dtDue() ) { ++ ++sortIt; ++ } ++ } else { ++ while ( sortIt != todoListSorted.end() && ++ e->dtDue() < CalendarSupport::todo( *sortIt )->dtDue() ) { ++ ++sortIt; ++ } ++ } ++ todoListSorted.insert( sortIt, *eit ); ++ } else { ++ // Keep a list of the To-dos without Due DateTimes ++ tempList.append( *eit ); ++ } ++ } ++ if ( sortDirection == SortDirectionAscending ) { ++ // Append the list of To-dos without Due DateTimes ++ todoListSorted += tempList; ++ } else { ++ // Prepend the list of To-dos without Due DateTimes ++ tempList += todoListSorted; ++ todoListSorted = tempList; ++ } ++ break; ++ ++ case TodoSortPriority: ++ alphaList = sortTodos( todoList, TodoSortSummary, sortDirection ); ++ for ( eit = alphaList.constBegin(); eit != alphaList.constEnd(); ++eit ) { ++ const KCalCore::Todo::Ptr e = CalendarSupport::todo( *eit ); ++ sortIt = todoListSorted.begin(); ++ if ( sortDirection == SortDirectionAscending ) { ++ while ( sortIt != todoListSorted.end() && ++ e->priority() >= CalendarSupport::todo(*sortIt)->priority() ) { ++ ++sortIt; ++ } ++ } else { ++ while ( sortIt != todoListSorted.end() && ++ e->priority() < CalendarSupport::todo(*sortIt)->priority() ) { ++ ++sortIt; ++ } ++ } ++ todoListSorted.insert( sortIt, *eit ); ++ } ++ break; ++ ++ case TodoSortPercentComplete: ++ alphaList = sortTodos( todoList, TodoSortSummary, sortDirection ); ++ for ( eit = alphaList.constBegin(); eit != alphaList.constEnd(); ++eit ) { ++ const KCalCore::Todo::Ptr e = CalendarSupport::todo( *eit ); ++ sortIt = todoListSorted.begin(); ++ if ( sortDirection == SortDirectionAscending ) { ++ while ( sortIt != todoListSorted.end() && ++ e->percentComplete() >= CalendarSupport::todo(*sortIt)->percentComplete() ) { ++ ++sortIt; ++ } ++ } else { ++ while ( sortIt != todoListSorted.end() && ++ e->percentComplete() < CalendarSupport::todo(*sortIt)->percentComplete() ) { ++ ++sortIt; ++ } ++ } ++ todoListSorted.insert( sortIt, *eit ); ++ } ++ break; ++ ++ case TodoSortSummary: ++ for ( eit = todoList.constBegin(); eit != todoList.constEnd(); ++eit ) { ++ const KCalCore::Todo::Ptr e = CalendarSupport::todo( *eit ); ++ sortIt = todoListSorted.begin(); ++ if ( sortDirection == SortDirectionAscending ) { ++ while ( sortIt != todoListSorted.end() && ++ e->summary() >= CalendarSupport::todo(*sortIt)->summary() ) { ++ ++sortIt; ++ } ++ } else { ++ while ( sortIt != todoListSorted.end() && ++ e->summary() < CalendarSupport::todo(*sortIt)->summary() ) { ++ ++sortIt; ++ } ++ } ++ todoListSorted.insert( sortIt, *eit ); ++ } ++ break; ++ } ++ ++ return todoListSorted; ++} ++ ++Akonadi::Item::List Calendar::todos( TodoSortField sortField, ++ SortDirection sortDirection ) ++{ ++ const Akonadi::Item::List tl = rawTodos( sortField, sortDirection ); ++ return CalendarSupport::applyCalFilter( tl, filter() ); ++} ++ ++Akonadi::Item::List Calendar::todos( const QDate &date ) ++{ ++ Akonadi::Item::List el = rawTodosForDate( date ); ++ return applyCalFilter( el, filter() ); ++} ++ ++Akonadi::Item::List Calendar::sortJournals( const Akonadi::Item::List &journalList_, ++ JournalSortField sortField, ++ SortDirection sortDirection ) ++{ ++ Akonadi::Item::List journalList( journalList_ ); ++ Akonadi::Item::List journalListSorted; ++ Akonadi::Item::List::Iterator sortIt; ++ Akonadi::Item::List::ConstIterator eit; ++ ++ switch( sortField ) { ++ case JournalSortUnsorted: ++ journalListSorted = journalList; ++ break; ++ ++ case JournalSortDate: ++ for ( eit = journalList.constBegin(); eit != journalList.constEnd(); ++eit ) { ++ const KCalCore::Journal::Ptr e = CalendarSupport::journal( *eit ); ++ sortIt = journalListSorted.begin(); ++ if ( sortDirection == SortDirectionAscending ) { ++ while ( sortIt != journalListSorted.end() && ++ e->dtStart() >= CalendarSupport::journal(*sortIt)->dtStart() ) { ++ ++sortIt; ++ } ++ } else { ++ while ( sortIt != journalListSorted.end() && ++ e->dtStart() < CalendarSupport::journal(*sortIt)->dtStart() ) { ++ ++sortIt; ++ } ++ } ++ journalListSorted.insert( sortIt, *eit ); ++ } ++ break; ++ ++ case JournalSortSummary: ++ for ( eit = journalList.constBegin(); eit != journalList.constEnd(); ++eit ) { ++ const KCalCore::Journal::Ptr e = CalendarSupport::journal( *eit ); ++ sortIt = journalListSorted.begin(); ++ if ( sortDirection == SortDirectionAscending ) { ++ while ( sortIt != journalListSorted.end() && ++ e->summary() >= CalendarSupport::journal(*sortIt)->summary() ) { ++ ++sortIt; ++ } ++ } else { ++ while ( sortIt != journalListSorted.end() && ++ e->summary() < CalendarSupport::journal(*sortIt)->summary() ) { ++ ++sortIt; ++ } ++ } ++ journalListSorted.insert( sortIt, *eit ); ++ } ++ break; ++ } ++ ++ return journalListSorted; ++} ++ ++Akonadi::Item::List Calendar::journals( JournalSortField sortField, ++ SortDirection sortDirection ) ++{ ++ const Akonadi::Item::List jl = rawJournals( sortField, sortDirection ); ++ return CalendarSupport::applyCalFilter( jl, filter() ); ++} ++ ++Akonadi::Item::List Calendar::journals( const QDate &date ) ++{ ++ Akonadi::Item::List el = rawJournalsForDate( date ); ++ return CalendarSupport::applyCalFilter( el, filter() ); ++} ++ ++void Calendar::beginBatchAdding() ++{ ++ emit batchAddingBegins(); ++} ++ ++void Calendar::endBatchAdding() ++{ ++ emit batchAddingEnds(); ++} ++ ++#ifdef AKONADI_PORT_DISABLED ++ ++void Calendar::setupRelations( const Akonadi::Item &forincidence ) ++{ ++ if ( !forincidence ) { ++ return; ++ } ++ ++ QString uid = forincidence->uid(); ++ ++ // First, go over the list of orphans and see if this is their parent ++ QList l = d->mOrphans.values( uid ); ++ d->mOrphans.remove( uid ); ++ for ( int i = 0, end = l.count(); i < end; ++i ) { ++ forincidence->addRelation( l[i] ); ++ d->mOrphanUids.remove( l[i]->uid() ); ++ } ++ ++ // Now see about this incidences parent ++ if ( !forincidence->relatedTo() && !forincidence->relatedToUid().isEmpty() ) { ++ // Incidence has a uid it is related to but is not registered to it yet. ++ // Try to find it ++ KCalCore::Incidence::Ptr parent = incidence( forincidence->relatedToUid() ); ++ if ( !parent ) { ++ // Not found, put this in the mOrphans list ++ // Note that the mOrphans dict might contain multiple entries with the ++ // same key! which are multiple children that wait for the parent ++ // incidence to be inserted. ++ d->mOrphans.insert( forincidence->relatedToUid(), forincidence ); ++ d->mOrphanUids.insert( forincidence->uid(), forincidence ); ++ } ++ } ++ } ++#endif // AKONADI_PORT_DISABLED ++ ++#ifdef AKONADI_PORT_DISABLED ++// If a to-do with sub-to-dos is deleted, move it's sub-to-dos to the orphan list ++void Calendar::removeRelations( const Akonadi::Item &incidence ) ++{ ++ if ( !incidence ) { ++ kDebug() << "Warning: incidence is 0"; ++ return; ++ } ++ ++ QString uid = incidence->uid(); ++ foreach ( KCalCore::Incidence::Ptr i, incidence->relations() ) { ++ if ( !d->mOrphanUids.contains( i->uid() ) ) { ++ d->mOrphans.insert( uid, i ); ++ d->mOrphanUids.insert( i->uid(), i ); ++ i->setRelatedTo( uid ); ++ } ++ } ++ ++ // If this incidence is related to something else, tell that about it ++ if ( incidence->relatedTo() ) { ++ incidence->relatedTo()->removeRelation( incidence ); ++ } ++ ++ // Remove this one from the orphans list ++ if ( d->mOrphanUids.remove( uid ) ) { ++ // This incidence is located in the orphans list - it should be removed ++ // Since the mOrphans dict might contain the same key (with different ++ // child incidence pointers!) multiple times, take care that we remove ++ // the correct one. So we need to remove all items with the given ++ // parent UID, and readd those that are not for this item. Also, there ++ // might be other entries with differnet UID that point to this ++ // incidence (this might happen when the relatedTo of the item is ++ // changed before its parent is inserted. This might happen with ++ // groupware servers....). Remove them, too ++ QStringList relatedToUids; ++ ++ // First, create a list of all keys in the mOrphans list which point ++ // to the removed item ++ relatedToUids << incidence->relatedToUid(); ++ for ( QMultiHash::Iterator it = d->mOrphans.begin(); ++ it != d->mOrphans.end(); ++it ) { ++ if ( it.value()->uid() == uid ) { ++ relatedToUids << it.key(); ++ } ++ } ++ ++ // now go through all uids that have one entry that point to the incidence ++ for ( QStringList::const_iterator uidit = relatedToUids.constBegin(); ++ uidit != relatedToUids.constEnd(); ++uidit ) { ++ Incidence::List tempList; ++ // Remove all to get access to the remaining entries ++ QList l = d->mOrphans.values( *uidit ); ++ d->mOrphans.remove( *uidit ); ++ foreach ( Incidence *i, l ) { ++ if ( i != incidence ) { ++ tempList.append( i ); ++ } ++ } ++ // Readd those that point to a different orphan incidence ++ for ( KCalCore::Incidence::List::Iterator incit = tempList.begin(); ++ incit != tempList.end(); ++incit ) { ++ d->mOrphans.insert( *uidit, *incit ); ++ } ++ } ++ } ++ ++ // Make sure the deleted incidence doesn't relate to a non-deleted incidence, ++ // since that would cause trouble in CalendarLocal::close(), as the deleted ++ // incidences are destroyed after the non-deleted incidences. The destructor ++ // of the deleted incidences would then try to access the already destroyed ++ // non-deleted incidence, which would segfault. ++ // ++ // So in short: Make sure dead incidences don't point to alive incidences ++ // via the relation. ++ // ++ // This crash is tested in CalendarLocalTest::testRelationsCrash(). ++} ++#endif // AKONADI_PORT_DISABLED ++ ++void Calendar::CalendarObserver::calendarIncidenceAdded( const Akonadi::Item &incidence ) ++{ ++ Q_UNUSED( incidence ); ++} ++ ++void Calendar::CalendarObserver::calendarIncidenceChanged( const Akonadi::Item &incidence ) ++{ ++ Q_UNUSED( incidence ); ++} ++ ++void Calendar::CalendarObserver::calendarIncidenceDeleted( const Akonadi::Item &incidence ) ++{ ++ Q_UNUSED( incidence ); ++} ++ ++void Calendar::registerObserver( CalendarObserver *observer ) ++{ ++ if ( !d->mObservers.contains( observer ) ) { ++ d->mObservers.append( observer ); ++ } ++ d->mNewObserver = true; ++} ++ ++void Calendar::unregisterObserver( CalendarObserver *observer ) ++{ ++ d->mObservers.removeAll( observer ); ++} ++ ++void Calendar::doSetTimeSpec( const KDateTime::Spec &timeSpec ) ++{ ++ Q_UNUSED( timeSpec ); ++} ++ ++void Calendar::notifyIncidenceAdded( const Akonadi::Item &i ) ++{ ++ if ( !d->mObserversEnabled ) { ++ return; ++ } ++ ++ foreach ( CalendarObserver *observer, d->mObservers ) { ++ observer->calendarIncidenceAdded( i ); ++ } ++} ++ ++void Calendar::notifyIncidenceChanged( const Akonadi::Item &i ) ++{ ++ if ( !d->mObserversEnabled ) { ++ return; ++ } ++ ++ foreach ( CalendarObserver *observer, d->mObservers ) { ++ observer->calendarIncidenceChanged( i ); ++ } ++} ++ ++void Calendar::notifyIncidenceDeleted( const Akonadi::Item &i ) ++{ ++ if ( !d->mObserversEnabled ) { ++ return; ++ } ++ ++ foreach ( CalendarObserver *observer, d->mObservers ) { ++ observer->calendarIncidenceDeleted( i ); ++ } ++} ++ ++void Calendar::customPropertyUpdated() ++{ ++} ++ ++void Calendar::setProductId( const QString &id ) ++{ ++ d->mProductId = id; ++} ++ ++QString Calendar::productId() const ++{ ++ return d->mProductId; ++} ++ ++Akonadi::Item::List Calendar::mergeIncidenceList( const Akonadi::Item::List &events, ++ const Akonadi::Item::List &todos, ++ const Akonadi::Item::List &journals ) ++{ ++ Akonadi::Item::List incidences; ++ ++ int i, end; ++ for ( i = 0, end = events.count(); i < end; ++i ) { ++ incidences.append( events[i] ); ++ } ++ ++ for ( i = 0, end = todos.count(); i < end; ++i ) { ++ incidences.append( todos[i] ); ++ } ++ ++ for ( i = 0, end = journals.count(); i < end; ++i ) { ++ incidences.append( journals[i] ); ++ } ++ ++ return incidences; ++} ++ ++void Calendar::setObserversEnabled( bool enabled ) ++{ ++ d->mObserversEnabled = enabled; ++} ++ ++void Calendar::appendAlarms( KCalCore::Alarm::List &alarms, const Akonadi::Item &item, ++ const KDateTime &from, const KDateTime &to ) ++{ ++ const KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( item ); ++ Q_ASSERT( incidence ); ++ ++ KDateTime preTime = from.addSecs(-1); ++ ++ KCalCore::Alarm::List alarmlist = incidence->alarms(); ++ for ( int i = 0, iend = alarmlist.count(); i < iend; ++i ) { ++ if ( alarmlist[i]->enabled() ) { ++ KDateTime dt = alarmlist[i]->nextRepetition( preTime ); ++ if ( dt.isValid() && dt <= to ) { ++ kDebug() << incidence->summary() << "':" << dt.toString(); ++ alarms.append( alarmlist[i] ); ++ } ++ } ++ } ++} ++ ++void Calendar::appendRecurringAlarms( KCalCore::Alarm::List &alarms, ++ const Akonadi::Item &item, ++ const KDateTime &from, ++ const KDateTime &to ) ++{ ++ KDateTime dt; ++ bool endOffsetValid = false; ++ KCalCore::Duration endOffset( 0 ); ++ KCalCore::Duration period( from, to ); ++ ++ const KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( item ); ++ Q_ASSERT( incidence ); ++ ++ KCalCore::Alarm::List alarmlist = incidence->alarms(); ++ for ( int i = 0, iend = alarmlist.count(); i < iend; ++i ) { ++ KCalCore::Alarm::Ptr a = alarmlist[i]; ++ if ( a->enabled() ) { ++ if ( a->hasTime() ) { ++ // The alarm time is defined as an absolute date/time ++ dt = a->nextRepetition( from.addSecs(-1) ); ++ if ( !dt.isValid() || dt > to ) { ++ continue; ++ } ++ } else { ++ // Alarm time is defined by an offset from the event start or end time. ++ // Find the offset from the event start time, which is also used as the ++ // offset from the recurrence time. ++ KCalCore::Duration offset( 0 ); ++ if ( a->hasStartOffset() ) { ++ offset = a->startOffset(); ++ } else if ( a->hasEndOffset() ) { ++ offset = a->endOffset(); ++ if ( !endOffsetValid ) { ++ endOffset = KCalCore::Duration( ++ incidence->dtStart(), ++ incidence->dateTime( KCalCore::IncidenceBase::RoleAlarmEndOffset ) ); ++ endOffsetValid = true; ++ } ++ } ++ ++ // Find the incidence's earliest alarm ++ KDateTime alarmStart = ++ offset.end( a->hasEndOffset() ? ++ incidence->dateTime( KCalCore::IncidenceBase::RoleAlarmEndOffset ) : ++ incidence->dtStart() ); ++// KDateTime alarmStart = incidence->dtStart().addSecs( offset ); ++ if ( alarmStart > to ) { ++ continue; ++ } ++ KDateTime baseStart = incidence->dtStart(); ++ if ( from > alarmStart ) { ++ alarmStart = from; // don't look earlier than the earliest alarm ++ baseStart = (-offset).end( (-endOffset).end( alarmStart ) ); ++ } ++ ++ // Adjust the 'alarmStart' date/time and find the next recurrence at or after it. ++ // Treate the two offsets separately in case one is daily and the other not. ++ dt = incidence->recurrence()->getNextDateTime( baseStart.addSecs(-1) ); ++ if ( !dt.isValid() || ++ ( dt = endOffset.end( offset.end( dt ) ) ) > to ) // adjust 'dt' to get the alarm time ++ { ++ // The next recurrence is too late. ++ if ( !a->repeatCount() ) { ++ continue; ++ } ++ ++ // The alarm has repetitions, so check whether repetitions of previous ++ // recurrences fall within the time period. ++ bool found = false; ++ KCalCore::Duration alarmDuration = a->duration(); ++ for ( KDateTime base = baseStart; ++ ( dt = incidence->recurrence()->getPreviousDateTime( base ) ).isValid(); ++ base = dt ) { ++ if ( a->duration().end( dt ) < base ) { ++ break; // this recurrence's last repetition is too early, so give up ++ } ++ ++ // The last repetition of this recurrence is at or after 'alarmStart' time. ++ // Check if a repetition occurs between 'alarmStart' and 'to'. ++ int snooze = a->snoozeTime().value(); // in seconds or days ++ if ( a->snoozeTime().isDaily() ) { ++ KCalCore::Duration toFromDuration( dt, base ); ++ int toFrom = toFromDuration.asDays(); ++ if ( a->snoozeTime().end( from ) <= to || ++ ( toFromDuration.isDaily() && toFrom % snooze == 0 ) || ++ ( toFrom / snooze + 1 ) * snooze <= toFrom + period.asDays() ) { ++ found = true; ++#ifndef NDEBUG ++ // for debug output ++ dt = offset.end( dt ).addDays( ( ( toFrom - 1 ) / snooze + 1 ) * snooze ); ++#endif ++ break; ++ } ++ } else { ++ int toFrom = dt.secsTo( base ); ++ if ( period.asSeconds() >= snooze || ++ toFrom % snooze == 0 || ++ ( toFrom / snooze + 1 ) * snooze <= toFrom + period.asSeconds() ) ++ { ++ found = true; ++#ifndef NDEBUG ++ // for debug output ++ dt = offset.end( dt ).addSecs( ( ( toFrom - 1 ) / snooze + 1 ) * snooze ); ++#endif ++ break; ++ } ++ } ++ } ++ if ( !found ) { ++ continue; ++ } ++ } ++ } ++ // kDebug() << incidence->summary() << "':" << dt.toString(); ++ alarms.append( a ); ++ } ++ } ++} ++ ++Akonadi::Collection Calendar::collection( const Akonadi::Collection::Id &id ) const ++{ ++ if ( d->m_collectionMap.contains( id ) ) { ++ return d->m_collectionMap[id]; ++ } else { ++ return Akonadi::Collection(); ++ } ++} ++ ++bool Calendar::hasChangeRights( const Akonadi::Item &item ) const ++{ ++ // if the users changes the rights, item.parentCollection() ++ // can still have the old rights, so we use call collection() ++ // which returns the updated one ++ const Akonadi::Collection col = collection( item.storageCollectionId() ); ++ return col.rights() & Akonadi::Collection::CanChangeItem; ++} ++ ++bool Calendar::hasDeleteRights( const Akonadi::Item &item ) const ++{ ++ // if the users changes the rights, item.parentCollection() ++ // can still have the old rights, so we use call collection() ++ // which returns the updated one ++ const Akonadi::Collection col = collection( item.storageCollectionId() ); ++ return col.rights() & Akonadi::Collection::CanDeleteItem; ++} ++ ++int Calendar::incidencesCount() const ++{ ++ return d->m_model->rowCount(); ++} +diff --git a/plasma/generic/dataengines/calendar/akonadi/calendar.h b/plasma/generic/dataengines/calendar/akonadi/calendar.h +new file mode 100644 +index 0000000..364fc81 +--- /dev/null ++++ b/plasma/generic/dataengines/calendar/akonadi/calendar.h +@@ -0,0 +1,772 @@ ++/* ++ Copyright (c) 2009 KDAB ++ Author: Sebastian Sauer ++ Frank Osterfeld ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++*/ ++ ++#ifndef CALENDARSUPPORT_CALENDAR_H ++#define CALENDARSUPPORT_CALENDAR_H ++ ++#include ++ ++#include ++#include ++ ++#include ++ ++#include ++ ++namespace KCalCore { ++ class CalFilter; ++} ++ ++class QAbstractItemModel; ++ ++namespace CalendarSupport { ++ ++/** ++ Calendar KCalCore::Incidence sort directions. ++*/ ++enum SortDirection { ++ SortDirectionAscending, /**< Sort in ascending order (first to last) */ ++ SortDirectionDescending /**< Sort in descending order (last to first) */ ++}; ++ ++/** ++ Calendar Event sort keys. ++*/ ++enum EventSortField { ++ EventSortUnsorted, /**< Do not sort Events */ ++ EventSortStartDate, /**< Sort Events chronologically, by start date */ ++ EventSortEndDate, /**< Sort Events chronologically, by end date */ ++ EventSortSummary /**< Sort Events alphabetically, by summary */ ++}; ++ ++/** ++ Calendar Todo sort keys. ++*/ ++enum TodoSortField { ++ TodoSortUnsorted, /**< Do not sort Todos */ ++ TodoSortStartDate, /**< Sort Todos chronologically, by start date */ ++ TodoSortDueDate, /**< Sort Todos chronologically, by due date */ ++ TodoSortPriority, /**< Sort Todos by priority */ ++ TodoSortPercentComplete, /**< Sort Todos by percentage completed */ ++ TodoSortSummary /**< Sort Todos alphabetically, by summary */ ++}; ++ ++/** ++ Calendar Journal sort keys. ++*/ ++enum JournalSortField { ++ JournalSortUnsorted, /**< Do not sort Journals */ ++ JournalSortDate, /**< Sort Journals chronologically by date */ ++ JournalSortSummary /**< Sort Journals alphabetically, by summary */ ++}; ++ ++/** ++ * Implements a KCalCore::Calendar that uses Akonadi as backend. ++ */ ++class Calendar : public QObject, ++ public KCalCore::CustomProperties, ++ public KCalCore::IncidenceBase::IncidenceObserver ++{ ++ Q_OBJECT ++ ++ Q_PROPERTY( int incidencesCount READ incidencesCount NOTIFY calendarChanged ) ++ public: ++ ++ /** ++ Sets the calendar Product ID to @p id. ++ @param id is a string containing the Product ID. ++ @see productId() const ++ */ ++ void setProductId( const QString &id ); ++ ++ /** ++ Returns the calendar's Product ID. ++ @see setProductId() ++ */ ++ QString productId() const; ++ ++ /** ++ Sets the owner of the calendar to @p owner. ++ @param owner is a Person object. ++ @see owner() ++ */ ++ void setOwner( const KCalCore::Person &owner ); ++ ++ /** ++ Returns the owner of the calendar. ++ @return the owner Person object. ++ @see setOwner() ++ */ ++ KCalCore::Person owner() const; ++ ++ /** ++ Sets the default time specification (time zone, etc.) used for creating ++ or modifying incidences in the Calendar. ++ ++ The method also calls setViewTimeSpec(@p timeSpec). ++ ++ @param timeSpec time specification ++ */ ++ void setTimeSpec( const KDateTime::Spec &timeSpec ); ++ ++ /** ++ Get the time specification (time zone etc.) used for creating or ++ modifying incidences in the Calendar. ++ @return time specification ++ */ ++ KDateTime::Spec timeSpec() const; ++ ++ /** ++ Sets the time zone ID used for creating or modifying incidences in the ++ Calendar. This method has no effect on existing incidences. ++ ++ The method also calls setViewTimeZoneId(@p timeZoneId). ++ ++ @param timeZoneId is a string containing a time zone ID, which is ++ assumed to be valid. The time zone ID is used to set the time zone ++ for viewing KCalCore::Incidence date/times. If no time zone is found, the ++ viewing time specification is set to local clock time. ++ @e Example: "Europe/Berlin" ++ @see setTimeSpec() ++ */ ++ void setTimeZoneId( const QString &timeZoneId ); ++ ++ /** ++ Returns the time zone ID used for creating or modifying incidences in ++ the calendar. ++ ++ @return the string containing the time zone ID, or empty string if the ++ creation/modification time specification is not a time zone. ++ */ ++ QString timeZoneId() const; ++ ++ /** ++ Notes the time specification which the client application intends to ++ use for viewing the incidences in this calendar. This is simply a ++ convenience method which makes a note of the new time zone so that ++ it can be read back by viewTimeSpec(). The client application must ++ convert date/time values to the desired time zone itself. ++ ++ The time specification is not used in any way by the Calendar or its ++ incidences; it is solely for use by the client application. ++ ++ @param timeSpec time specification ++ ++ @see viewTimeSpec() ++ */ ++ void setViewTimeSpec( const KDateTime::Spec &timeSpec ) const; ++ ++ /** ++ Notes the time zone Id which the client application intends to use for ++ viewing the incidences in this calendar. This is simply a convenience ++ method which makes a note of the new time zone so that it can be read ++ back by viewTimeId(). The client application must convert date/time ++ values to the desired time zone itself. ++ ++ The Id is not used in any way by the Calendar or its incidences. ++ It is solely for use by the client application. ++ ++ @param timeZoneId is a string containing a time zone ID, which is ++ assumed to be valid. The time zone ID is used to set the time zone ++ for viewing KCalCore::Incidence date/times. If no time zone is found, the ++ viewing time specification is set to local clock time. ++ @e Example: "Europe/Berlin" ++ ++ @see viewTimeZoneId() ++ */ ++ void setViewTimeZoneId( const QString &timeZoneId ) const; ++ ++ /** ++ Returns the time specification used for viewing the incidences in ++ this calendar. This simply returns the time specification last ++ set by setViewTimeSpec(). ++ @see setViewTimeSpec(). ++ */ ++ KDateTime::Spec viewTimeSpec() const; ++ ++ /** ++ Returns the time zone Id used for viewing the incidences in this ++ calendar. This simply returns the time specification last set by ++ setViewTimeSpec(). ++ @see setViewTimeZoneId(). ++ */ ++ QString viewTimeZoneId() const; ++ ++ /** ++ Shifts the times of all incidences so that they appear at the same clock ++ time as before but in a new time zone. The shift is done from a viewing ++ time zone rather than from the actual incidence time zone. ++ ++ For example, shifting an incidence whose start time is 09:00 America/New York, ++ using an old viewing time zone (@p oldSpec) of Europe/London, to a new time ++ zone (@p newSpec) of Europe/Paris, will result in the time being shifted ++ from 14:00 (which is the London time of the incidence start) to 14:00 Paris ++ time. ++ ++ @param oldSpec the time specification which provides the clock times ++ @param newSpec the new time specification ++ ++ @see isLocalTime() ++ */ ++ void shiftTimes( const KDateTime::Spec &oldSpec, const KDateTime::Spec &newSpec ); ++ ++ /** ++ Returns a list of all categories used by KCalCore::Incidences in the calendar @p cal. ++ ++ @param cal the calendar to return incidences from ++ @return a QStringList containing all the categories. ++ */ ++ static QStringList categories( Calendar *cal ); ++ ++// KCalCore::Incidence Specific Methods // ++ ++ /** ++ Returns a filtered list of all KCalCore::Incidences for this Calendar. ++ @deprecated: ++ ++ @return the list of all filtered KCalCore::Incidences. ++ */ ++ Akonadi::Item::List incidences(); ++ ++ /** ++ Returns a filtered list of all KCalCore::Incidences which occur on the given date. ++ ++ @param date request filtered KCalCore::Incidence list for this QDate only. ++ @deprecated: ++ ++ @return the list of filtered KCalCore::Incidences occurring on the specified date. ++ */ ++ Akonadi::Item::List incidences( const QDate &date ); ++ ++ /** ++ Returns an unfiltered list of all KCalCore::Incidences for this Calendar. ++ @deprecated: ++ ++ @return the list of all unfiltered KCalCore::Incidences. ++ */ ++ Akonadi::Item::List rawIncidences(); ++ ++ /** ++ Returns the KCalCore::Incidence associated with the given unique identifier. ++ ++ @param uid is a unique identifier string. ++ @deprecated: ++ ++ @return a pointer to the KCalCore::Incidence. ++ A null pointer is returned if no such KCalCore::Incidence exists. ++ */ ++ Akonadi::Item incidence( Akonadi::Item::Id id ) const; ++ ++ Akonadi::Collection collection( const Akonadi::Entity::Id &id ) const; ++ ++ /** ++ Returns the KCalCore::Incidence associated with the given scheduling identifier. ++ ++ @param sid is a unique scheduling identifier string. ++ @deprecated: ++ ++ @return a pointer to the KCalCore::Incidence. ++ A null pointer is returned if no such KCalCore::Incidence exists. ++ */ ++ Akonadi::Item incidenceFromSchedulingID( const QString &sid ); ++ ++ /** ++ Searches all events and todos for an incidence with this ++ scheduling identifiere. Returns a list of matching results. ++ @deprecated: ++ ++ @param sid is a unique scheduling identifier string. ++ */ ++ Akonadi::Item::List incidencesFromSchedulingID( const QString &sid ); ++ ++ /** ++ Create a merged list of KCalCore::Events, KCalCore::Todos, and KCalCore::Journals. ++ ++ @param events is an KCalCore::Event list to merge. ++ @param todos is a KCalCore::Todo list to merge. ++ @param journals is a KCalCore::Journal list to merge. ++ @deprecated: ++ ++ @return a list of merged KCalCore::Incidences. ++ */ ++ static Akonadi::Item::List mergeIncidenceList( const Akonadi::Item::List &events, ++ const Akonadi::Item::List &todos, ++ const Akonadi::Item::List &journals ); ++ ++ /** ++ Dissociate an KCalCore::Incidence from a recurring KCalCore::Incidence. ++ By default, only one single KCalCore::Incidence for the specified @a date ++ will be dissociated and returned. If @a single is false, then ++ the recurrence will be split at @a date, the old KCalCore::Incidence will ++ have its recurrence ending at @a date and the new KCalCore::Incidence ++ will have all recurrences past the @a date. ++ ++ @param incidence is a pointer to a recurring KCalCore::Incidence. ++ @param date is the QDate within the recurring KCalCore::Incidence on which ++ the dissociation will be performed. ++ @param spec is the spec in which the @a date is formulated. ++ @param single is a flag meaning that a new KCalCore::Incidence should be created ++ from the recurring KCalCore::Incidences after @a date. ++ @deprecated: ++ ++ @return a pointer to a new recurring KCalCore::Incidence if @a single is false. ++ */ ++ KCalCore::Incidence::Ptr dissociateOccurrence( const Akonadi::Item &incidence, ++ const QDate &date, ++ const KDateTime::Spec &spec, ++ bool single = true ); ++ ++// KCalCore::Event Specific Methods // ++ ++ /** ++ Sort a list of KCalCore::Events. ++ ++ @param eventList is a pointer to a list of KCalCore::Events. ++ @param sortField specifies the EventSortField. ++ @param sortDirection specifies the SortDirection. ++ @deprecated: ++ ++ @return a list of KCalCore::Events sorted as specified. ++ */ ++ static Akonadi::Item::List sortEvents( const Akonadi::Item::List &eventList, ++ EventSortField sortField, ++ SortDirection sortDirection ); ++ ++ /** ++ Returns a sorted, filtered list of all KCalCore::Events for this Calendar. ++ ++ @param sortField specifies the EventSortField. ++ @param sortDirection specifies the SortDirection. ++ @deprecated: ++ ++ @return the list of all filtered KCalCore::Events sorted as specified. ++ */ ++ virtual Akonadi::Item::List events( ++ EventSortField sortField = EventSortUnsorted, ++ SortDirection sortDirection = SortDirectionAscending ); ++ ++ /** ++ Returns a filtered list of all KCalCore::Events which occur on the given timestamp. ++ ++ @param dt request filtered KCalCore::Event list for this KDateTime only. ++ @deprecated: ++ ++ @return the list of filtered KCalCore::Events occurring on the specified timestamp. ++ */ ++ Akonadi::Item::List events( const KDateTime &dt ); ++ ++ /** ++ Returns a filtered list of all KCalCore::Events occurring within a date range. ++ ++ @param start is the starting date. ++ @param end is the ending date. ++ @param timeSpec time zone etc. to interpret @p start and @p end, ++ or the calendar's default time spec if none is specified ++ @param inclusive if true only KCalCore::Events which are completely included ++ within the date range are returned. ++ @deprecated: ++ ++ @return the list of filtered KCalCore::Events occurring within the specified ++ date range. ++ */ ++ Akonadi::Item::List events( const QDate &start, const QDate &end, ++ const KDateTime::Spec &timeSpec = KDateTime::Spec(), ++ bool inclusive = false ); ++ ++ /** ++ Returns a sorted, filtered list of all KCalCore::Events which occur on the given ++ date. The KCalCore::Events are sorted according to @a sortField and ++ @a sortDirection. ++ ++ @param date request filtered KCalCore::Event list for this QDate only. ++ @param timeSpec time zone etc. to interpret @p start and @p end, ++ or the calendar's default time spec if none is specified ++ @param sortField specifies the EventSortField. ++ @param sortDirection specifies the SortDirection. ++ @deprecated: ++ ++ @return the list of sorted, filtered KCalCore::Events occurring on @a date. ++ */ ++ Akonadi::Item::List events( ++ const QDate &date, ++ const KDateTime::Spec &timeSpec = KDateTime::Spec(), ++ EventSortField sortField = EventSortUnsorted, ++ SortDirection sortDirection = SortDirectionAscending ); ++ ++// KCalCore::Todo Specific Methods // ++ ++ /** ++ Sort a list of KCalCore::Todos. ++ ++ @param todoList is a pointer to a list of KCalCore::Todos. ++ @param sortField specifies the TodoSortField. ++ @param sortDirection specifies the SortDirection. ++ @deprecated: ++ ++ @return a list of KCalCore::Todos sorted as specified. ++ */ ++ static Akonadi::Item::List sortTodos( const Akonadi::Item::List &todoList, ++ TodoSortField sortField, ++ SortDirection sortDirection ); ++ ++ /** ++ Returns a sorted, filtered list of all KCalCore::Todos for this Calendar. ++ ++ @param sortField specifies the TodoSortField. ++ @param sortDirection specifies the SortDirection. ++ @deprecated: ++ ++ @return the list of all filtered KCalCore::Todos sorted as specified. ++ */ ++ virtual Akonadi::Item::List todos( ++ TodoSortField sortField = TodoSortUnsorted, ++ SortDirection sortDirection = SortDirectionAscending ); ++ ++ /** ++ Returns a filtered list of all KCalCore::Todos which are due on the specified date. ++ ++ @param date request filtered KCalCore::Todos due on this QDate. ++ @deprecated: ++ ++ @return the list of filtered KCalCore::Todos due on the specified date. ++ */ ++ virtual Akonadi::Item::List todos( const QDate &date ); ++ ++// KCalCore::Journal Specific Methods // ++ ++ /** ++ Sort a list of KCalCore::Journals. ++ ++ @param journalList is a pointer to a list of KCalCore::Journals. ++ @param sortField specifies the JournalSortField. ++ @param sortDirection specifies the SortDirection. ++ @deprecated: ++ ++ @return a list of KCalCore::Journals sorted as specified. ++ */ ++ static Akonadi::Item::List sortJournals( const Akonadi::Item::List &journalList, ++ JournalSortField sortField, ++ SortDirection sortDirection ); ++ ++ /** ++ Returns a sorted, filtered list of all KCalCore::Journals for this Calendar. ++ ++ @param sortField specifies the JournalSortField. ++ @param sortDirection specifies the SortDirection. ++ @deprecated: ++ ++ @return the list of all filtered KCalCore::Journals sorted as specified. ++ */ ++ virtual Akonadi::Item::List journals( ++ JournalSortField sortField = JournalSortUnsorted, ++ SortDirection sortDirection = SortDirectionAscending ); ++ ++ /** ++ Returns a filtered list of all KCalCore::Journals for on the specified date. ++ ++ @param date request filtered KCalCore::Journals for this QDate only. ++ @deprecated: ++ ++ @return the list of filtered KCalCore::Journals for the specified date. ++ */ ++ virtual Akonadi::Item::List journals( const QDate &date ); ++ ++ /** ++ Emits the beginBatchAdding() signal. ++ ++ This should be called before adding a batch of incidences with ++ addIncidence( KCalCore::Incidence::Ptr ), addTodo( KCalCore::Todo::Ptr ), ++ addEvent( KCalCore::Event::Ptr ) or addJournal( KCalCore::Journal::Ptr ). ++ Some Calendars are connected to this signal, e.g: CalendarResources uses ++ it to know a series of incidenceAdds are related so the user isn't prompted ++ multiple times which resource to save the incidence to ++ ++ @since 4.4 ++ */ ++ void beginBatchAdding(); ++ ++ /** ++ Emits the endBatchAdding() signal. ++ ++ Used with beginBatchAdding(). Should be called after ++ adding all incidences. ++ ++ @since 4.4 ++ */ ++ void endBatchAdding(); ++ ++// Filter Specific Methods // ++ ++ /** ++ Sets the calendar filter. ++ ++ @param filter a pointer to a CalFilter object which will be ++ used to filter Calendar KCalCore::Incidences. ++ @deprecated: ++ ++ @see filter() ++ */ ++ void setFilter( KCalCore::CalFilter *filter ); ++ ++ /** ++ Returns the calendar filter. ++ ++ @return a pointer to the calendar CalFilter. ++ A null pointer is returned if no such CalFilter exists. ++ @deprecated: ++ ++ @see setFilter() ++ */ ++ KCalCore::CalFilter *filter(); ++ ++// Observer Specific Methods // ++ ++ /** ++ @class CalendarObserver ++ ++ The CalendarObserver class. ++ */ ++ class CalendarObserver //krazy:exclude=dpointer ++ { ++ public: ++ /** ++ Destructor. ++ */ ++ virtual ~CalendarObserver() {} ++ ++ /** ++ Notify the Observer that an KCalCore::Incidence has been inserted. ++ @deprecated: ++ ++ @param incidence is a pointer to the KCalCore::Incidence that was inserted. ++ */ ++ virtual void calendarIncidenceAdded( const Akonadi::Item &incidence ); ++ ++ /** ++ Notify the Observer that an KCalCore::Incidence has been modified. ++ @deprecated: ++ ++ @param incidence is a pointer to the KCalCore::Incidence that was modified. ++ */ ++ virtual void calendarIncidenceChanged( const Akonadi::Item &incidence ); ++ ++ /** ++ Notify the Observer that an KCalCore::Incidence has been removed. ++ @deprecated: ++ ++ @param incidence is a pointer to the KCalCore::Incidence that was removed. ++ */ ++ virtual void calendarIncidenceDeleted( const Akonadi::Item &incidence ); ++ ++ }; ++ ++ /** ++ Registers an Observer for this Calendar. ++ ++ @param observer is a pointer to an Observer object that will be ++ watching this Calendar. ++ ++ @see unregisterObserver() ++ */ ++ void registerObserver( CalendarObserver *observer ); ++ ++ /** ++ Unregisters an Observer for this Calendar. ++ ++ @param observer is a pointer to an Observer object that has been ++ watching this Calendar. ++ ++ @see registerObserver() ++ */ ++ void unregisterObserver( CalendarObserver *observer ); ++ ++ /** ++ Returns if the parent collection's rights allow deleting this item. ++ Isn't merged with hasChangeRights() for convenience. ++ */ ++ bool hasDeleteRights( const Akonadi::Item &item ) const; ++ ++ /** ++ Returns if the parent collection's rights allow changing this item. ++ Isn't merged with hasDeleteRights() for convenience. ++ */ ++ bool hasChangeRights( const Akonadi::Item &item ) const; ++ ++ Q_SIGNALS: ++ /** ++ Signals that the calendar has been modified. ++ */ ++ void calendarChanged(); ++ ++ /** ++ @see beginBatchAdding() ++ @since 4.4 ++ */ ++ void batchAddingBegins(); ++ ++ /** ++ @see endBatchAdding() ++ @since 4.4 ++ */ ++ void batchAddingEnds(); ++ ++ protected: ++ /** ++ Let Calendar subclasses set the time specification. ++ @param timeSpec is the time specification (time zone, etc.) for ++ viewing KCalCore::Incidence dates.\n ++ */ ++ virtual void doSetTimeSpec( const KDateTime::Spec &timeSpec ); ++ ++ /** ++ Let Calendar subclasses notify that they inserted an KCalCore::Incidence. ++ @deprecated: ++ @param incidence is a pointer to the KCalCore::Incidence object that was inserted. ++ */ ++ void notifyIncidenceAdded( const Akonadi::Item &incidence ); ++ ++ /** ++ Let Calendar subclasses notify that they modified an KCalCore::Incidence. ++ @deprecated: ++ @param incidence is a pointer to the KCalCore::Incidence object that was modified. ++ */ ++ void notifyIncidenceChanged( const Akonadi::Item &incidence ); ++ ++ /** ++ Let Calendar subclasses notify that they removed an KCalCore::Incidence. ++ @deprecated: ++ @param incidence is a pointer to the KCalCore::Incidence object that was removed. ++ */ ++ void notifyIncidenceDeleted( const Akonadi::Item &incidence ); ++ ++ /** ++ @copydoc ++ CustomProperties::customPropertyUpdated() ++ */ ++ virtual void customPropertyUpdated(); ++ ++ /** ++ Let Calendar subclasses notify that they enabled an Observer. ++ @param enabled if true tells the calendar that a subclass has ++ enabled an Observer. ++ */ ++ void setObserversEnabled( bool enabled ); ++ ++ /** ++ Appends alarms of incidence in interval to list of alarms. ++ ++ @param alarms is a List of KCalCore::Alarms to be appended onto. ++ @param incidence is a pointer to an KCalCore::Incidence containing the KCalCore::Alarm ++ to be appended. ++ @param from is the lower range of the next KCalCore::Alarm repitition. ++ @param to is the upper range of the next KCalCore::Alarm repitition. ++ @deprecated: ++ */ ++ void appendAlarms( KCalCore::Alarm::List &alarms, const Akonadi::Item &incidence, ++ const KDateTime &from, const KDateTime &to ); ++ ++ /** ++ Appends alarms of recurring events in interval to list of alarms. ++ ++ @param alarms is a List of KCalCore::Alarms to be appended onto. ++ @param incidence is a pointer to an KCalCore::Incidence containing the KCalCore::Alarm ++ to be appended. ++ @param from is the lower range of the next KCalCore::Alarm repitition. ++ @param to is the upper range of the next KCalCore::Alarm repitition. ++ @deprecated: ++ */ ++ void appendRecurringAlarms( KCalCore::Alarm::List &alarms, const Akonadi::Item &incidence, ++ const KDateTime &from, const KDateTime &to ); ++ public: ++ explicit Calendar( QAbstractItemModel *treeModel, QAbstractItemModel *model, ++ const KDateTime::Spec &timeSpec, QObject *parent=0 ); ++ ~Calendar(); ++ ++ QAbstractItemModel *model() const; ++ ++ QAbstractItemModel *unfilteredModel() const; ++ void setUnfilteredModel( QAbstractItemModel *model ); ++ ++ QAbstractItemModel *treeModel() const; ++ ++ void incidenceUpdated( const QString &uid, const KDateTime &recurrenceId ); ++ void incidenceUpdate( const QString &uid, const KDateTime &recurrenceId ); ++ ++ Akonadi::Item ::List rawEvents( EventSortField sortField = EventSortUnsorted, ++ SortDirection sortDirection = SortDirectionAscending ); ++ ++ Akonadi::Item ::List rawEvents( const QDate &start, const QDate &end, ++ const KDateTime::Spec &timeSpec = KDateTime::Spec(), ++ bool inclusive = false ); ++ ++ Akonadi::Item ::List rawEventsForDate( const QDate &date, ++ const KDateTime::Spec &timeSpec = KDateTime::Spec(), ++ EventSortField sortField = EventSortUnsorted, ++ SortDirection sortDirection = SortDirectionAscending ); ++ ++ Akonadi::Item::List rawEventsForDate( const KDateTime &dt ); ++ ++ Akonadi::Item event( Akonadi::Item::Id id ) const; ++ ++ Akonadi::Item::List rawTodos( TodoSortField sortField = TodoSortUnsorted, ++ SortDirection sortDirection = SortDirectionAscending ); ++ ++ Akonadi::Item::List rawTodosForDate( const QDate &date ); ++ ++ Akonadi::Item todo( Akonadi::Item::Id uid ) const; ++ ++ Akonadi::Item::List rawJournals( JournalSortField sortField = JournalSortUnsorted, ++ SortDirection sortDirection = SortDirectionAscending ); ++ ++ Akonadi::Item::List rawJournalsForDate( const QDate &date ); ++ ++ Akonadi::Item journal( Akonadi::Item::Id id ) const; ++ ++ KCalCore::Alarm::List alarms( const KDateTime &from, const KDateTime &to, bool excludeBlockedAlarms = false ); ++ KCalCore::Alarm::List alarmsTo( const KDateTime &to ); ++ ++ Akonadi::Item findParent( const Akonadi::Item &item ) const; ++ ++ Akonadi::Item::List findChildren( const KCalCore::Incidence::Ptr &incidence ) const; ++ Akonadi::Item::List findChildren( const Akonadi::Item &item ) const; ++ bool isChild( const Akonadi::Item &parent, const Akonadi::Item &child ) const; ++ ++ Akonadi::Item::Id itemIdForIncidenceUid( const QString &uid ) const; ++ Akonadi::Item itemForIncidenceUid( const QString &uid ) const; ++ ++ /** ++ * Returns the number of incidences in the calendar. ++ */ ++ int incidencesCount() const; ++ ++ using QObject::event; // prevent warning about hidden virtual method ++ ++ Q_SIGNALS: ++ void signalErrorMessage( const QString & ); ++ ++ private: ++ Q_DISABLE_COPY( Calendar ) ++ class Private; ++ Private *const d; ++}; ++ ++} ++ ++#endif +diff --git a/plasma/generic/dataengines/calendar/akonadi/calendar_p.h b/plasma/generic/dataengines/calendar/akonadi/calendar_p.h +new file mode 100644 +index 0000000..f9b92de +--- /dev/null ++++ b/plasma/generic/dataengines/calendar/akonadi/calendar_p.h +@@ -0,0 +1,161 @@ ++/* ++ Copyright (c) 2009 KDAB ++ Authors: Sebastian Sauer ++ Till Adam ++ Frank Osterfeld ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++*/ ++ ++#ifndef CALENDARSUPPORT_CALENDAR_P_H ++#define CALENDARSUPPORT_CALENDAR_P_H ++ ++#include "calendar.h" ++#include "calfilterproxymodel.h" ++ ++#include ++ ++#include ++#include ++ ++#include ++ ++namespace CalendarSupport { ++ ++class CalendarCollection : public QObject ++{ ++ Q_OBJECT ++ public: ++ Calendar *m_calendar; ++ Akonadi::Collection m_collection; ++ ++ CalendarCollection( Calendar *calendar, const Akonadi::Collection &collection ) ++ : QObject(), m_calendar(calendar), m_collection(collection) ++ { ++ } ++ ++ ~CalendarCollection() ++ { ++ } ++}; ++ ++struct UnseenItem ++{ ++ Akonadi::Entity::Id collection; ++ QString uid; ++ ++ bool operator<( const UnseenItem &other ) const ++ { ++ if ( collection != other.collection ) { ++ return collection < other.collection; ++ } ++ return uid < other.uid; ++ } ++}; ++ ++class Calendar::Private : public QObject ++{ ++ Q_OBJECT ++ private: ++ void removeItemFromMaps( const Akonadi::Item &item ); ++ Calendar *const q; ++ ++ public: ++ explicit Private( QAbstractItemModel *treeModel, QAbstractItemModel *model, Calendar *q ); ++ ~Private(); ++ ++ enum UpdateMode { ++ DontCare, ++ AssertExists, ++ AssertNew ++ }; ++ ++ void updateItem( const Akonadi::Item &item, UpdateMode mode ); ++ void itemChanged( const Akonadi::Item &item ); ++ ++ void assertInvariants() const; ++ void appendVirtualItems( Akonadi::Item::List &itemList ); ++ //CalendarBase begin ++ ++ KDateTime::Spec timeZoneIdSpec( const QString &timeZoneId, bool view ); ++ QString mProductId; ++ KCalCore::Person mOwner; ++ KCalCore::ICalTimeZones *mTimeZones; // collection of time zones used in this calendar ++ KCalCore::ICalTimeZone mBuiltInTimeZone; // cached time zone lookup ++ KCalCore::ICalTimeZone mBuiltInViewTimeZone; // cached viewing time zone lookup ++ KDateTime::Spec mTimeSpec; ++ mutable KDateTime::Spec mViewTimeSpec; ++ bool mModified; ++ bool mNewObserver; ++ bool mObserversEnabled; ++ QList mObservers; ++ ++ KCalCore::CalFilter *mDefaultFilter; ++ //CalendarBase end ++ ++ QAbstractItemModel *m_treeModel; ++ QAbstractItemModel *m_model; ++ CalFilterProxyModel *m_filterProxy; ++ QHash m_itemMap; // akonadi id to items ++ QHash m_collectionMap; // akonadi id to collections ++ ++ // child to parent map, for already cached parents ++ QHash m_childToParent; ++ ++ //parent to children map for alread cached children ++ QHash > m_parentToChildren; ++ ++ QMap m_uidToItemId; ++ ++ // child to parent map, unknown/not cached parent items ++ QHash m_childToUnseenParent; ++ ++ QMap > m_unseenParentToChildren; ++ ++ // on start dates/due dates of non-recurring, single-day Incidences ++ QMultiHash m_itemIdsForDate; ++ ++ QHash m_itemDateForItemId; ++ ++ // From search folders. ++ QHash > m_virtualItems; ++ ++ void clear(); ++ void readFromModel(); ++ ++ public Q_SLOTS: ++ void itemsAdded( const Akonadi::Item::List &items ); ++ void itemsRemoved( const Akonadi::Item::List &items ); ++ ++ void collectionsAdded( const Akonadi::Collection::List &collections ); ++ void collectionsRemoved( const Akonadi::Collection::List &collections ); ++ ++ void rowsInserted( const QModelIndex &index, int start, int end ); ++ void rowsAboutToBeRemoved( const QModelIndex &index, int start, int end ); ++ void rowsInsertedInTreeModel( const QModelIndex &index, int start, int end ); ++ void rowsAboutToBeRemovedInTreeModel( const QModelIndex &index, int start, int end ); ++ void dataChangedInTreeModel( const QModelIndex &topLeft, const QModelIndex &bottomRight ); ++ ++ void layoutChanged(); ++ void modelReset(); ++ void dataChanged( const QModelIndex &topLeft, const QModelIndex &bottomRight ); ++ ++ void onRowsMovedInTreeModel( const QModelIndex &sourceParent, int sourceStart, int sourceEnd, ++ const QModelIndex &destinationParent, int destinationRow ); ++}; ++ ++} ++ ++#endif +diff --git a/plasma/generic/dataengines/calendar/akonadi/calendarmodel.cpp b/plasma/generic/dataengines/calendar/akonadi/calendarmodel.cpp +new file mode 100644 +index 0000000..251a615 +--- /dev/null ++++ b/plasma/generic/dataengines/calendar/akonadi/calendarmodel.cpp +@@ -0,0 +1,248 @@ ++/* ++ Copyright (c) 2008 Bruno Virlet ++ 2009 KDAB; Author: Frank Osterfeld ++ ++ This library 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 of the License, or (at your ++ option) any later version. ++ ++ This library is distributed in the hope that it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU 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 "calendarmodel.h" ++#include "utils.h" ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++using namespace CalendarSupport; ++ ++class CalendarModel::Private ++{ ++ public: ++ explicit Private( CalendarModel *qq ) ++ :q( qq ) ++ { ++ } ++ ++ private: ++ CalendarModel *const q; ++}; ++ ++CalendarModel::CalendarModel( Akonadi::ChangeRecorder *monitor, QObject *parent ) ++ : EntityTreeModel( monitor, parent ), ++ d( new Private( this ) ) ++{ ++ monitor->itemFetchScope().fetchAllAttributes( true ); ++} ++ ++CalendarModel::~CalendarModel() ++{ ++ delete d; ++} ++ ++static KDateTime primaryDateForIncidence( const Akonadi::Item &item ) ++{ ++ if ( const KCalCore::Todo::Ptr t = CalendarSupport::todo( item ) ) { ++ return t->hasDueDate() ? t->dtDue() : KDateTime(); ++ } ++ ++ if ( const KCalCore::Event::Ptr e = CalendarSupport::event( item ) ) { ++ return ( !e->recurs() && !e->isMultiDay() ) ? e->dtStart() : KDateTime(); ++ } ++ ++ if ( const KCalCore::Journal::Ptr j = CalendarSupport::journal( item ) ) { ++ return j->dtStart(); ++ } ++ ++ return KDateTime(); ++} ++ ++QVariant CalendarModel::entityData( const Akonadi::Item &item, int column, int role ) const ++{ ++ const KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( item ); ++ if ( !incidence ) { ++ return QVariant(); ++ } ++ ++ switch( role ) { ++ case Qt::DecorationRole: ++ if ( column != Summary ) { ++ return QVariant(); ++ } ++ if ( incidence->type() == KCalCore::IncidenceBase::TypeTodo ) { ++ return SmallIcon( QLatin1String( "view-pim-tasks" ) ); ++ } ++ if ( incidence->type() == KCalCore::IncidenceBase::TypeJournal ) { ++ return SmallIcon( QLatin1String( "view-pim-journal" ) ); ++ } ++ if ( incidence->type() == KCalCore::IncidenceBase::TypeEvent ) { ++ return SmallIcon( QLatin1String( "view-calendar" ) ); ++ } ++ return SmallIcon( QLatin1String( "network-wired" ) ); ++ ++ case Qt::DisplayRole: ++ switch( column ) { ++ case Summary: ++ return incidence->summary(); ++ ++ case DateTimeStart: ++ return incidence->dtStart().toString(); ++ ++ case DateTimeEnd: ++ return incidence->dateTime( KCalCore::Incidence::RoleEndTimeZone ).toString(); ++ ++ case DateTimeDue: ++ if ( KCalCore::Todo::Ptr todo = CalendarSupport::todo( item ) ) { ++ return todo->dtDue().toString(); ++ } else { ++ return QVariant(); ++ } ++ ++ case Priority: ++ if ( KCalCore::Todo::Ptr todo = CalendarSupport::todo( item ) ) { ++ return todo->priority(); ++ } else { ++ return QVariant(); ++ } ++ ++ case PercentComplete: ++ if ( KCalCore::Todo::Ptr todo = CalendarSupport::todo( item ) ) { ++ return todo->percentComplete(); ++ } else { ++ return QVariant(); ++ } ++ ++ case PrimaryDate: ++ return primaryDateForIncidence( item ).toString(); ++ ++ case Type: ++ ++ return incidence->type(); ++ default: ++ break; ++ } ++ ++ case SortRole: ++ switch( column ) { ++ case Summary: ++ return incidence->summary(); ++ ++ case DateTimeStart: ++ return incidence->dtStart().toUtc().dateTime(); ++ ++ case DateTimeEnd: ++ return incidence->dateTime( KCalCore::Incidence::RoleEndTimeZone ).toUtc().dateTime(); ++ ++ case DateTimeDue: ++ if ( KCalCore::Todo::Ptr todo = CalendarSupport::todo( item ) ) { ++ return todo->dtDue().toUtc().dateTime(); ++ } else { ++ return QVariant(); ++ } ++ ++ case PrimaryDate: ++ return primaryDateForIncidence( item ).toUtc().dateTime(); ++ ++ case Priority: ++ if ( KCalCore::Todo::Ptr todo = CalendarSupport::todo( item ) ) { ++ return todo->priority(); ++ } else { ++ return QVariant(); ++ } ++ ++ case PercentComplete: ++ if ( KCalCore::Todo::Ptr todo = CalendarSupport::todo( item ) ) { ++ return todo->percentComplete(); ++ } else { ++ return QVariant(); ++ } ++ ++ case Type: ++ return incidence->type(); ++ ++ default: ++ break; ++ } ++ ++ return QVariant(); ++ ++ case RecursRole: ++ return incidence->recurs(); ++ ++ default: ++ return QVariant(); ++ } ++ ++ return QVariant(); ++} ++ ++QVariant CalendarModel::entityData( const Akonadi::Collection &collection, ++ int column, int role ) const ++{ ++ return EntityTreeModel::entityData( collection, column, role ); ++} ++ ++int CalendarModel::entityColumnCount( EntityTreeModel::HeaderGroup headerSet ) const ++{ ++ if ( headerSet == EntityTreeModel::ItemListHeaders ) { ++ return ItemColumnCount; ++ } else { ++ return CollectionColumnCount; ++ } ++} ++ ++QVariant CalendarModel::entityHeaderData( int section, Qt::Orientation orientation, ++ int role, EntityTreeModel::HeaderGroup headerSet ) const ++{ ++ if ( role != Qt::DisplayRole || orientation != Qt::Horizontal ) { ++ return QVariant(); ++ } ++ ++ if ( headerSet == EntityTreeModel::ItemListHeaders ) { ++ switch( section ) { ++ case Summary: ++ return i18nc( "@title:column calendar event summary", "Summary" ); ++ case DateTimeStart: ++ return i18nc( "@title:column calendar event start date and time", "Start Date and Time" ); ++ case DateTimeEnd: ++ return i18nc( "@title:column calendar event end date and time", "End Date and Time" ); ++ case Type: ++ return i18nc( "@title:column calendar event type", "Type" ); ++ case DateTimeDue: ++ return i18nc( "@title:column todo item due date and time", "Due Date and Time" ); ++ case Priority: ++ return i18nc( "@title:column todo item priority", "Priority" ); ++ case PercentComplete: ++ return i18nc( "@title:column todo item completion in percent", "Complete" ); ++ default: ++ return QVariant(); ++ } ++ } ++ ++ if ( headerSet == EntityTreeModel::CollectionTreeHeaders ) { ++ switch ( section ) { ++ case CollectionTitle: ++ return i18nc( "@title:column calendar title", "Calendar" ); ++ default: ++ return QVariant(); ++ } ++ } ++ return QVariant(); ++} ++ +diff --git a/plasma/generic/dataengines/calendar/akonadi/calendarmodel.h b/plasma/generic/dataengines/calendar/akonadi/calendarmodel.h +new file mode 100644 +index 0000000..1acbfdd +--- /dev/null ++++ b/plasma/generic/dataengines/calendar/akonadi/calendarmodel.h +@@ -0,0 +1,79 @@ ++/* ++ Copyright (c) 2009 KDAB ++ Author: Frank Osterfeld ++ ++ This library 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 of the License, or (at your ++ option) any later version. ++ ++ This library is distributed in the hope that it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU 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 CALENDARSUPPORT_CALENDARMODEL_H ++#define CALENDARSUPPORT_CALENDARMODEL_H ++ ++#include ++ ++namespace CalendarSupport { ++ ++class CalendarModel : public Akonadi::EntityTreeModel ++{ ++ Q_OBJECT ++ public: ++ enum ItemColumn { ++ Summary=0, ++ Type, ++ DateTimeStart, ++ DateTimeEnd, ++ DateTimeDue, ++ PrimaryDate, ++ Priority, ++ PercentComplete, ++ ItemColumnCount ++ }; ++ ++ enum CollectionColumn { ++ CollectionTitle=0, ++ CollectionColumnCount ++ }; ++ ++ enum Role { ++ SortRole=Akonadi::EntityTreeModel::UserRole, ++ RecursRole ++ }; ++ ++ explicit CalendarModel( Akonadi::ChangeRecorder *monitor, QObject *parent = 0 ); ++ ~CalendarModel(); ++ ++ /* reimp */ ++ QVariant entityData( const Akonadi::Item &item, int column, int role=Qt::DisplayRole ) const; ++ ++ /* reimp */ ++ QVariant entityData( const Akonadi::Collection &collection, int column, ++ int role=Qt::DisplayRole ) const; ++ ++ /* reimp */ ++ int entityColumnCount( EntityTreeModel::HeaderGroup headerSet ) const; ++ ++ /* reimp */ ++ QVariant entityHeaderData( int section, Qt::Orientation orientation, int role, ++ EntityTreeModel::HeaderGroup headerSet ) const; ++ ++ private: ++ class Private; ++ Private *const d; ++}; ++ ++} ++ ++#endif ++ +diff --git a/plasma/generic/dataengines/calendar/akonadi/calfilterproxymodel.cpp b/plasma/generic/dataengines/calendar/akonadi/calfilterproxymodel.cpp +new file mode 100644 +index 0000000..1820084 +--- /dev/null ++++ b/plasma/generic/dataengines/calendar/akonadi/calfilterproxymodel.cpp +@@ -0,0 +1,90 @@ ++/* ++ Copyright (c) 2009 KDAB ++ Author: Frank Osterfeld ++ ++ This library 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 of the License, or (at your ++ option) any later version. ++ ++ This library is distributed in the hope that it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU 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 "calfilterproxymodel.h" ++#include "calendarmodel.h" ++ ++#include ++ ++#include ++#include ++ ++using namespace CalendarSupport; ++ ++class CalFilterProxyModel::Private ++{ ++ public: ++ explicit Private() : filter( 0 ) {} ++ KCalCore::CalFilter *filter; ++}; ++ ++CalFilterProxyModel::CalFilterProxyModel( QObject *parent ) ++ : QSortFilterProxyModel( parent ), d( new Private ) ++{ ++ setSortRole( CalendarModel::SortRole ); ++ setFilterKeyColumn( 0 ); ++} ++ ++CalFilterProxyModel::~CalFilterProxyModel() ++{ ++ delete d; ++} ++ ++KCalCore::CalFilter *CalFilterProxyModel::filter() const ++{ ++ return d->filter; ++} ++ ++void CalFilterProxyModel::setFilter( KCalCore::CalFilter *filter ) ++{ ++ if ( filter == d->filter ) { ++ return; ++ } ++ ++ d->filter = filter; ++ invalidateFilter(); ++} ++ ++bool CalFilterProxyModel::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const ++{ ++ if ( !d->filter ) { ++ return true; ++ } ++ if ( source_row < 0 || !source_parent.isValid() ) { ++ return false; ++ } ++ ++ const QModelIndex idx = sourceModel()->index( source_row, 0, source_parent ); ++ if ( !idx.isValid() ) { ++ return false; ++ } ++ ++ const Akonadi::Item item = idx.data( Akonadi::EntityTreeModel::ItemRole ).value(); ++ if ( !item.isValid() || !item.hasPayload() ) { ++ return false; ++ } ++ ++ const KCalCore::Incidence::Ptr inc = item.payload(); ++ if ( !inc ) { ++ return false; ++ } ++ ++ return d->filter->filterIncidence( inc ); ++} +diff --git a/plasma/generic/dataengines/calendar/akonadi/calfilterproxymodel.h b/plasma/generic/dataengines/calendar/akonadi/calfilterproxymodel.h +new file mode 100644 +index 0000000..fe62155 +--- /dev/null ++++ b/plasma/generic/dataengines/calendar/akonadi/calfilterproxymodel.h +@@ -0,0 +1,51 @@ ++/* ++ Copyright (c) 2009 KDAB ++ Author: Frank Osterfeld ++ ++ This library 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 of the License, or (at your ++ option) any later version. ++ ++ This library is distributed in the hope that it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU 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 CALENDARSUPPORT_CALFILTERPROXYMODEL_H ++#define CALENDARSUPPORT_CALFILTERPROXYMODEL_H ++ ++#include ++ ++namespace KCalCore { ++ class CalFilter; ++} ++ ++namespace CalendarSupport { ++ ++class CalFilterProxyModel : public QSortFilterProxyModel ++{ ++ Q_OBJECT ++ public: ++ explicit CalFilterProxyModel( QObject *parent=0 ); ++ ~CalFilterProxyModel(); ++ ++ KCalCore::CalFilter *filter() const; ++ void setFilter( KCalCore::CalFilter *filter ); ++ ++ protected: ++ /* reimp */ bool filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const; ++ ++ private: ++ class Private; ++ Private *const d; ++}; ++ ++} ++ ++#endif +diff --git a/plasma/generic/dataengines/calendar/akonadi/collectionselection.cpp b/plasma/generic/dataengines/calendar/akonadi/collectionselection.cpp +new file mode 100644 +index 0000000..41e03da +--- /dev/null ++++ b/plasma/generic/dataengines/calendar/akonadi/collectionselection.cpp +@@ -0,0 +1,104 @@ ++/* ++ Copyright (c) 2009 KDAB ++ Author: Frank Osterfeld ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ ++ As a special exception, permission is given to link this program ++ with any edition of Qt, and distribute the resulting executable, ++ without including the source code for Qt in the source distribution. ++*/ ++ ++#include "collectionselection.h" ++#include "utils.h" ++ ++#include ++ ++using namespace CalendarSupport; ++ ++class CollectionSelection::Private ++{ ++ public: ++ explicit Private( QItemSelectionModel *model_ ) : model( model_ ) ++ { ++ } ++ ++ QItemSelectionModel *model; ++}; ++ ++CollectionSelection::CollectionSelection( QItemSelectionModel *selectionModel, QObject *parent ) ++ : QObject( parent ), d( new Private ( selectionModel ) ) ++{ ++ connect( selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), ++ this, SLOT(slotSelectionChanged(QItemSelection,QItemSelection)) ); ++} ++ ++CollectionSelection::~CollectionSelection() ++{ ++ delete d; ++} ++ ++QItemSelectionModel *CollectionSelection::model() const ++{ ++ return d->model; ++} ++ ++bool CollectionSelection::hasSelection() const ++{ ++ return d->model->hasSelection(); ++} ++ ++bool CollectionSelection::contains( const Akonadi::Collection &c ) const ++{ ++ return selectedCollectionIds().contains( c.id() ); ++} ++ ++bool CollectionSelection::contains( const Akonadi::Collection::Id &id ) const ++{ ++ return selectedCollectionIds().contains( id ); ++} ++ ++Akonadi::Collection::List CollectionSelection::selectedCollections() const ++{ ++ Akonadi::Collection::List selected; ++ Q_FOREACH ( const QModelIndex &idx, d->model->selectedIndexes() ) { ++ selected.append( collectionFromIndex( idx ) ); ++ } ++ return selected; ++} ++ ++QList CollectionSelection::selectedCollectionIds() const ++{ ++ QList selected; ++ Q_FOREACH ( const QModelIndex &idx, d->model->selectedIndexes() ) { ++ selected.append( collectionIdFromIndex( idx ) ); ++ } ++ return selected; ++} ++ ++void CollectionSelection::slotSelectionChanged( const QItemSelection &selectedIndexes, ++ const QItemSelection &deselIndexes ) ++{ ++ const Akonadi::Collection::List selected = collectionsFromIndexes( selectedIndexes.indexes() ); ++ const Akonadi::Collection::List deselected = collectionsFromIndexes( deselIndexes.indexes() ); ++ ++ emit selectionChanged( selected, deselected ); ++ Q_FOREACH ( const Akonadi::Collection &c, deselected ) { ++ emit collectionDeselected( c ); ++ } ++ Q_FOREACH ( const Akonadi::Collection &c, selected ) { ++ emit collectionSelected( c ); ++ } ++} +diff --git a/plasma/generic/dataengines/calendar/akonadi/collectionselection.h b/plasma/generic/dataengines/calendar/akonadi/collectionselection.h +new file mode 100644 +index 0000000..4447afb +--- /dev/null ++++ b/plasma/generic/dataengines/calendar/akonadi/collectionselection.h +@@ -0,0 +1,67 @@ ++/* ++ Copyright (c) 2009 KDAB ++ Author: Frank Osterfeld ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ ++ As a special exception, permission is given to link this program ++ with any edition of Qt, and distribute the resulting executable, ++ without including the source code for Qt in the source distribution. ++*/ ++ ++#ifndef CALENDARSUPPORT_COLLECTIONSELECTION_H ++#define CALENDARSUPPORT_COLLECTIONSELECTION_H ++ ++#include ++ ++#include ++ ++class QItemSelection; ++class QItemSelectionModel; ++ ++namespace CalendarSupport { ++ ++class CollectionSelection : public QObject ++{ ++ Q_OBJECT ++ public: ++ explicit CollectionSelection( QItemSelectionModel *selectionModel, QObject *parent = 0 ); ++ ~CollectionSelection(); ++ ++ QItemSelectionModel *model() const; ++ Akonadi::Collection::List selectedCollections() const; ++ QList selectedCollectionIds() const; ++ bool contains( const Akonadi::Collection &c ) const; ++ bool contains( const Akonadi::Collection::Id &id ) const; ++ ++ bool hasSelection() const; ++ ++ Q_SIGNALS: ++ void selectionChanged( const Akonadi::Collection::List &selected, ++ const Akonadi::Collection::List &deselected ); ++ void collectionDeselected( const Akonadi::Collection & ); ++ void collectionSelected( const Akonadi::Collection & ); ++ ++ private Q_SLOTS: ++ void slotSelectionChanged( const QItemSelection &, const QItemSelection & ); ++ ++ private: ++ class Private; ++ Private *const d; ++}; ++ ++} ++ ++#endif +diff --git a/plasma/generic/dataengines/calendar/akonadi/utils.cpp b/plasma/generic/dataengines/calendar/akonadi/utils.cpp +new file mode 100644 +index 0000000..895edf9 +--- /dev/null ++++ b/plasma/generic/dataengines/calendar/akonadi/utils.cpp +@@ -0,0 +1,707 @@ ++/* ++ Copyright (c) 2009, 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com ++ Copyright (C) 2009 KDAB (author: Frank Osterfeld ) ++ Copyright (c) 2010 Andras Mantia ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ ++ As a special exception, permission is given to link this program ++ with any edition of Qt, and distribute the resulting executable, ++ without including the source code for Qt in the source distribution. ++*/ ++ ++#include "utils.h" ++/*#include "kcalprefs.h" ++#include "mailclient.h" ++#include "mailscheduler.h" ++#include "publishdialog.h"*/ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++using namespace CalendarSupport; ++using namespace KHolidays; ++ ++KCalCore::Incidence::Ptr CalendarSupport::incidence( const Akonadi::Item &item ) ++{ ++ return ++ item.hasPayload() ? ++ item.payload() : ++ KCalCore::Incidence::Ptr(); ++} ++ ++KCalCore::Event::Ptr CalendarSupport::event( const Akonadi::Item &item ) ++{ ++ return ++ item.hasPayload() ? ++ item.payload() : ++ KCalCore::Event::Ptr(); ++} ++ ++KCalCore::Event::List CalendarSupport::eventsFromItems( const Akonadi::Item::List &items ) ++{ ++ KCalCore::Event::List events; ++ Q_FOREACH ( const Akonadi::Item &item, items ) { ++ if ( const KCalCore::Event::Ptr e = CalendarSupport::event( item ) ) { ++ events.push_back( e ); ++ } ++ } ++ return events; ++} ++ ++KCalCore::Incidence::List CalendarSupport::incidencesFromItems( const Akonadi::Item::List &items ) ++{ ++ KCalCore::Incidence::List incidences; ++ Q_FOREACH ( const Akonadi::Item &item, items ) { ++ if ( const KCalCore::Incidence::Ptr e = CalendarSupport::incidence( item ) ) { ++ incidences.push_back( e ); ++ } ++ } ++ return incidences; ++} ++ ++KCalCore::Todo::Ptr CalendarSupport::todo( const Akonadi::Item &item ) ++{ ++ return ++ item.hasPayload() ? ++ item.payload() : ++ KCalCore::Todo::Ptr(); ++} ++ ++KCalCore::Journal::Ptr CalendarSupport::journal( const Akonadi::Item &item ) ++{ ++ return ++ item.hasPayload() ? ++ item.payload() : ++ KCalCore::Journal::Ptr(); ++} ++ ++bool CalendarSupport::hasIncidence( const Akonadi::Item &item ) ++{ ++ return item.hasPayload(); ++} ++ ++bool CalendarSupport::hasEvent( const Akonadi::Item &item ) ++{ ++ return item.hasPayload(); ++} ++ ++bool CalendarSupport::hasTodo( const Akonadi::Item &item ) ++{ ++ return item.hasPayload(); ++} ++ ++bool CalendarSupport::hasJournal( const Akonadi::Item &item ) ++{ ++ return item.hasPayload(); ++} ++ ++QMimeData *CalendarSupport::createMimeData( const Akonadi::Item::List &items, ++ const KDateTime::Spec &timeSpec ) ++{ ++ if ( items.isEmpty() ) { ++ return 0; ++ } ++ ++ KCalCore::MemoryCalendar::Ptr cal( new KCalCore::MemoryCalendar( timeSpec ) ); ++ ++ QList urls; ++ int incidencesFound = 0; ++ Q_FOREACH ( const Akonadi::Item &item, items ) { ++ const KCalCore::Incidence::Ptr incidence( CalendarSupport::incidence( item ) ); ++ if ( !incidence ) { ++ continue; ++ } ++ ++incidencesFound; ++ urls.push_back( item.url() ); ++ KCalCore::Incidence::Ptr i( incidence->clone() ); ++ cal->addIncidence( i ); ++ } ++ ++ if ( incidencesFound == 0 ) { ++ return 0; ++ } ++ ++ std::auto_ptr mimeData( new QMimeData ); ++ ++ mimeData->setUrls( urls ); ++ ++ KCalUtils::ICalDrag::populateMimeData( mimeData.get(), cal ); ++ KCalUtils::VCalDrag::populateMimeData( mimeData.get(), cal ); ++ ++ return mimeData.release(); ++} ++ ++QMimeData *CalendarSupport::createMimeData( const Akonadi::Item &item, ++ const KDateTime::Spec &timeSpec ) ++{ ++ return createMimeData( Akonadi::Item::List() << item, timeSpec ); ++} ++ ++#ifndef QT_NO_DRAGANDDROP ++QDrag *CalendarSupport::createDrag( const Akonadi::Item &item, ++ const KDateTime::Spec &timeSpec, QWidget *parent ) ++{ ++ return createDrag( Akonadi::Item::List() << item, timeSpec, parent ); ++} ++#endif ++ ++static QByteArray findMostCommonType( const Akonadi::Item::List &items ) ++{ ++ QByteArray prev; ++ if ( items.isEmpty() ) { ++ return "Incidence"; ++ } ++ ++ Q_FOREACH( const Akonadi::Item &item, items ) { ++ if ( !CalendarSupport::hasIncidence( item ) ) { ++ continue; ++ } ++ const QByteArray type = CalendarSupport::incidence( item )->typeStr(); ++ if ( !prev.isEmpty() && type != prev ) { ++ return "Incidence"; ++ } ++ prev = type; ++ } ++ return prev; ++} ++ ++#ifndef QT_NO_DRAGANDDROP ++QDrag *CalendarSupport::createDrag( const Akonadi::Item::List &items, ++ const KDateTime::Spec &timeSpec, QWidget *parent ) ++{ ++ std::auto_ptr drag( new QDrag( parent ) ); ++ drag->setMimeData( CalendarSupport::createMimeData( items, timeSpec ) ); ++ ++ const QByteArray common = findMostCommonType( items ); ++ if ( common == "Event" ) { ++ drag->setPixmap( BarIcon( QLatin1String( "view-calendar-day" ) ) ); ++ } else if ( common == "Todo" ) { ++ drag->setPixmap( BarIcon( QLatin1String( "view-calendar-tasks" ) ) ); ++ } ++ ++ return drag.release(); ++} ++#endif ++ ++static bool itemMatches( const Akonadi::Item &item, const KCalCore::CalFilter *filter ) ++{ ++ assert( filter ); ++ KCalCore::Incidence::Ptr inc = CalendarSupport::incidence( item ); ++ if ( !inc ) { ++ return false; ++ } ++ return filter->filterIncidence( inc ); ++} ++ ++Akonadi::Item::List CalendarSupport::applyCalFilter( const Akonadi::Item::List &items_, ++ const KCalCore::CalFilter *filter ) ++{ ++ Q_ASSERT( filter ); ++ Akonadi::Item::List items( items_ ); ++ items.erase( std::remove_if( items.begin(), items.end(), ++ !bind( itemMatches, _1, filter ) ), items.end() ); ++ return items; ++} ++ ++bool CalendarSupport::isValidIncidenceItemUrl( const KUrl &url, ++ const QStringList &supportedMimeTypes ) ++{ ++ if ( !url.isValid() ) { ++ return false; ++ } ++ ++ if ( url.scheme() != QLatin1String( "akonadi" ) ) { ++ return false; ++ } ++ ++ return supportedMimeTypes.contains( url.queryItem( QLatin1String( "type" ) ) ); ++} ++ ++bool CalendarSupport::isValidIncidenceItemUrl( const KUrl &url ) ++{ ++ return isValidIncidenceItemUrl( url, ++ QStringList() << KCalCore::Event::eventMimeType() ++ << KCalCore::Todo::todoMimeType() ++ << KCalCore::Journal::journalMimeType() ++ << KCalCore::FreeBusy::freeBusyMimeType() ); ++} ++ ++static bool containsValidIncidenceItemUrl( const QList& urls ) ++{ ++ return ++ std::find_if( urls.begin(), urls.end(), ++ bind( CalendarSupport::isValidIncidenceItemUrl, _1 ) ) != urls.constEnd(); ++} ++ ++bool CalendarSupport::isValidTodoItemUrl( const KUrl &url ) ++{ ++ if ( !url.isValid() || url.scheme() != QLatin1String( "akonadi" ) ) { ++ return false; ++ } ++ ++ return url.queryItem( QLatin1String( "type" ) ) == KCalCore::Todo::todoMimeType(); ++} ++ ++bool CalendarSupport::canDecode( const QMimeData *md ) ++{ ++ Q_ASSERT( md ); ++ return ++ containsValidIncidenceItemUrl( md->urls() ) || ++ KCalUtils::ICalDrag::canDecode( md ) || ++ KCalUtils::VCalDrag::canDecode( md ); ++} ++ ++QList CalendarSupport::incidenceItemUrls( const QMimeData *mimeData ) ++{ ++ QList urls; ++ Q_FOREACH( const KUrl &i, mimeData->urls() ) { ++ if ( isValidIncidenceItemUrl( i ) ) { ++ urls.push_back( i ); ++ } ++ } ++ return urls; ++} ++ ++QList CalendarSupport::todoItemUrls( const QMimeData *mimeData ) ++{ ++ QList urls; ++ ++ Q_FOREACH( const KUrl &i, mimeData->urls() ) { ++ if ( isValidIncidenceItemUrl( i, QStringList() << KCalCore::Todo::todoMimeType() ) ) { ++ urls.push_back( i ); ++ } ++ } ++ return urls; ++} ++ ++bool CalendarSupport::mimeDataHasTodo( const QMimeData *mimeData ) ++{ ++ return !todoItemUrls( mimeData ).isEmpty() || !todos( mimeData, KDateTime::Spec() ).isEmpty(); ++} ++ ++KCalCore::Todo::List CalendarSupport::todos( const QMimeData *mimeData, ++ const KDateTime::Spec &spec ) ++{ ++ KCalCore::Todo::List todos; ++ ++#ifndef QT_NO_DRAGANDDROP ++ KCalCore::Calendar::Ptr cal( KCalUtils::DndFactory::createDropCalendar( mimeData, spec ) ); ++ if ( cal ) { ++ Q_FOREACH( const KCalCore::Todo::Ptr &i, cal->todos() ) { ++ todos.push_back( KCalCore::Todo::Ptr( i->clone() ) ); ++ } ++ } ++#endif ++ ++ return todos; ++} ++ ++Akonadi::Collection CalendarSupport::selectCollection( QWidget *parent, ++ int &dialogCode, ++ const QStringList &mimeTypes, ++ const Akonadi::Collection &defCollection ) ++{ ++ QPointer dlg( new Akonadi::CollectionDialog( parent ) ); ++ ++ kDebug() << "selecting collections with mimeType in " << mimeTypes; ++ ++ dlg->setMimeTypeFilter( mimeTypes ); ++ dlg->setAccessRightsFilter( Akonadi::Collection::CanCreateItem ); ++ if ( defCollection.isValid() ) { ++ dlg->setDefaultCollection( defCollection ); ++ } ++ Akonadi::Collection collection; ++ ++ // FIXME: don't use exec. ++ dialogCode = dlg->exec(); ++ if ( dialogCode == QDialog::Accepted ) { ++ collection = dlg->selectedCollection(); ++ ++ if ( !collection.isValid() ) { ++ kWarning() <<"An invalid collection was selected!"; ++ } ++ } ++ delete dlg; ++ ++ return collection; ++} ++ ++Akonadi::Item CalendarSupport::itemFromIndex( const QModelIndex &idx ) ++{ ++ Akonadi::Item item = idx.data( Akonadi::EntityTreeModel::ItemRole ).value(); ++ item.setParentCollection( ++ idx.data( Akonadi::EntityTreeModel::ParentCollectionRole ).value() ); ++ return item; ++} ++ ++Akonadi::Collection::List CalendarSupport::collectionsFromModel( const QAbstractItemModel *model, ++ const QModelIndex &parentIndex, ++ int start, int end ) ++{ ++ const int endRow = end >= 0 ? end : model->rowCount( parentIndex ) - 1; ++ Akonadi::Collection::List collections; ++ int row = start; ++ QModelIndex i = model->index( row, 0, parentIndex ); ++ while ( row <= endRow ) { ++ const Akonadi::Collection collection = collectionFromIndex( i ); ++ if ( collection.isValid() ) { ++ collections << collection; ++ QModelIndex childIndex = i.child( 0, 0 ); ++ if ( childIndex.isValid() ) { ++ collections << collectionsFromModel( model, i ); ++ } ++ } ++ ++row; ++ i = i.sibling( row, 0 ); ++ } ++ return collections; ++} ++ ++Akonadi::Item::List CalendarSupport::itemsFromModel( const QAbstractItemModel * model, ++ const QModelIndex &parentIndex, ++ int start, int end ) ++{ ++ const int endRow = end >= 0 ? end : model->rowCount( parentIndex ) - 1; ++ Akonadi::Item::List items; ++ int row = start; ++ QModelIndex i = model->index( row, 0, parentIndex ); ++ while ( row <= endRow ) { ++ const Akonadi::Item item = itemFromIndex( i ); ++ if ( CalendarSupport::hasIncidence( item ) ) { ++ items << item; ++ } else { ++ QModelIndex childIndex = i.child( 0, 0 ); ++ if ( childIndex.isValid() ) { ++ items << itemsFromModel( model, i ); ++ } ++ } ++ ++ ++row; ++ i = i.sibling( row, 0 ); ++ } ++ return items; ++} ++ ++Akonadi::Collection CalendarSupport::collectionFromIndex( const QModelIndex &index ) ++{ ++ return index.data( Akonadi::EntityTreeModel::CollectionRole ).value(); ++} ++ ++Akonadi::Collection::Id CalendarSupport::collectionIdFromIndex( const QModelIndex &index ) ++{ ++ return index.data( Akonadi::EntityTreeModel::CollectionIdRole ).value(); ++} ++ ++Akonadi::Collection::List CalendarSupport::collectionsFromIndexes( const QModelIndexList &indexes ) ++{ ++ Akonadi::Collection::List l; ++ Q_FOREACH( const QModelIndex &idx, indexes ) { ++ l.push_back( collectionFromIndex( idx ) ); ++ } ++ return l; ++} ++ ++QString CalendarSupport::displayName( const Akonadi::Collection &c ) ++{ ++ const Akonadi::EntityDisplayAttribute *attr = c.attribute(); ++ return ( attr && !attr->displayName().isEmpty() ) ? attr->displayName() : c.name(); ++} ++ ++QString CalendarSupport::subMimeTypeForIncidence( const KCalCore::Incidence::Ptr &incidence ) ++{ ++ return incidence->mimeType(); ++} ++ ++QList CalendarSupport::workDays( const QDate &startDate, ++ const QDate &endDate ) ++{ ++ QList result; ++ ++/* const int mask( ~( KCalPrefs::instance()->mWorkWeekMask ) ); ++ const int numDays = startDate.daysTo( endDate ) + 1; ++ ++ for ( int i = 0; i < numDays; ++i ) { ++ const QDate date = startDate.addDays( i ); ++ if ( !( mask & ( 1 << ( date.dayOfWeek() - 1 ) ) ) ) { ++ result.append( date ); ++ } ++ } ++ ++ if ( KCalPrefs::instance()->mExcludeHolidays ) { ++ // NOTE: KOGlobals, where this method comes from, used to hold a pointer to ++ // a KHolidays object. I'm not sure about how expensive it is, just ++ // creating one here. ++ const HolidayRegion holidays( KCalPrefs::instance()->mHolidays ); ++ const Holiday::List list = holidays.holidays( startDate, endDate ); ++ for ( int i = 0; i < list.count(); ++i ) { ++ const Holiday &h = list.at( i ); ++ const QString dateString = h.date().toString(); ++ if ( h.dayType() == Holiday::NonWorkday ) { ++ result.removeAll( h.date() ); ++ } ++ } ++ }*/ ++ ++ return result; ++} ++ ++QStringList CalendarSupport::holiday( const QDate &date ) ++{ ++ QStringList hdays; ++ ++/* const HolidayRegion holidays( KCalPrefs::instance()->mHolidays ); ++ const Holiday::List list = holidays.holidays( date ); ++ ++ for ( int i = 0; i < list.count(); ++i ) { ++ hdays.append( list.at( i ).text() ); ++ }*/ ++ return hdays; ++} ++ ++void CalendarSupport::sendAsICalendar(const Akonadi::Item& item, KPIMIdentities::IdentityManager* identityManager, QWidget* parentWidget) ++{ ++/* Incidence::Ptr incidence = CalendarSupport::incidence( item ); ++ ++ if ( !incidence ) { ++ KMessageBox::information( ++ parentWidget, ++ i18n( "No item selected." ), ++ i18n( "Forwarding" ), ++ "ForwardNoEventSelected" ); ++ return; ++ } ++ ++ QPointer publishdlg = new PublishDialog; ++ if ( publishdlg->exec() == QDialog::Accepted ) { ++ const QString recipients = publishdlg->addresses(); ++ if ( incidence->organizer()->isEmpty() ) { ++ incidence->setOrganizer( Person::Ptr( new Person( CalendarSupport::KCalPrefs::instance()->fullName(), ++ CalendarSupport::KCalPrefs::instance()->email() ) ) ); ++ } ++ ++ ICalFormat format; ++ const QString from = CalendarSupport::KCalPrefs::instance()->email(); ++ const bool bccMe = CalendarSupport::KCalPrefs::instance()->mBcc; ++ const QString messageText = format.createScheduleMessage( incidence, iTIPRequest ); ++ CalendarSupport::MailClient mailer; ++ if ( mailer.mailTo( ++ incidence, ++ identityManager->identityForAddress( from ), ++ from, bccMe, recipients, messageText, MailTransport::TransportManager::self()->defaultTransportName() ) ) { ++ KMessageBox::information( ++ parentWidget, ++ i18n( "The item information was successfully sent." ), ++ i18n( "Forwarding" ), ++ "IncidenceForwardSuccess" ); ++ } else { ++ KMessageBox::error( ++ parentWidget, ++ i18n( "Unable to forward the item '%1'", incidence->summary() ), ++ i18n( "Forwarding Error" ) ); ++ } ++ } ++ delete publishdlg;*/ ++} ++ ++void CalendarSupport::publishItemInformation(const Akonadi::Item& item, Calendar* calendar, QWidget* parentWidget) ++{ ++/* Incidence::Ptr incidence = CalendarSupport::incidence( item ); ++ ++ if ( !incidence ) { ++ KMessageBox::information( ++ parentWidget, ++ i18n( "No item selected." ), ++ "PublishNoEventSelected" ); ++ return; ++ } ++ ++ QPointer publishdlg = new PublishDialog(); ++ if ( incidence->attendeeCount() > 0 ) { ++ Attendee::List attendees = incidence->attendees(); ++ Attendee::List::ConstIterator it; ++ for ( it = attendees.constBegin(); it != attendees.constEnd(); ++it ) { ++ publishdlg->addAttendee( *it ); ++ } ++ } ++ if ( publishdlg->exec() == QDialog::Accepted ) { ++ Incidence::Ptr inc( incidence->clone() ); ++ inc->registerObserver( 0 ); ++ inc->clearAttendees(); ++ ++ // Send the mail ++ CalendarSupport::MailScheduler scheduler( calendar ); ++ if ( scheduler.publish( incidence, publishdlg->addresses() ) ) { ++ KMessageBox::information( ++ parentWidget, ++ i18n( "The item information was successfully sent." ), ++ i18n( "Publishing" ), ++ "IncidencePublishSuccess" ); ++ } else { ++ KMessageBox::error( ++ parentWidget, ++ i18n( "Unable to publish the item '%1'", incidence->summary() ) ); ++ } ++ } ++ delete publishdlg;*/ ++} ++ ++void CalendarSupport::scheduleiTIPMethods( KCalCore::iTIPMethod method, const Akonadi::Item& item, CalendarSupport::Calendar* calendar, QWidget* parentWidget ) ++{ ++/* Incidence::Ptr incidence = CalendarSupport::incidence( item ); ++ ++ if ( !incidence ) { ++ KMessageBox::sorry( ++ parentWidget, ++ i18n( "No item selected." ), ++ "ScheduleNoEventSelected" ); ++ return; ++ } ++ ++ if ( incidence->attendeeCount() == 0 && method != iTIPPublish ) { ++ KMessageBox::information( ++ parentWidget, ++ i18n( "The item has no attendees." ), ++ "ScheduleNoIncidences" ); ++ return; ++ } ++ ++ Incidence *inc = incidence->clone(); ++ inc->registerObserver( 0 ); ++ inc->clearAttendees(); ++ ++ // Send the mail ++ CalendarSupport::MailScheduler scheduler( calendar ); ++ if ( scheduler.performTransaction( incidence, method ) ) { ++ KMessageBox::information( ++ parentWidget, ++ i18n( "The groupware message for item '%1' " ++ "was successfully sent.\nMethod: %2", ++ incidence->summary(), ++ ScheduleMessage::methodName( method ) ), ++ i18n( "Sending Free/Busy" ), ++ "FreeBusyPublishSuccess" ); ++ } else { ++ KMessageBox::error( ++ parentWidget, ++ i18nc( "Groupware message sending failed. " ++ "%2 is request/reply/add/cancel/counter/etc.", ++ "Unable to send the item '%1'.\nMethod: %2", ++ incidence->summary(), ++ ScheduleMessage::methodName( method ) ) ); ++ }*/ ++} ++ ++void CalendarSupport::saveAttachments(const Akonadi::Item& item, QWidget* parentWidget) ++{ ++/* Incidence::Ptr incidence = CalendarSupport::incidence( item ); ++ ++ if ( !incidence ) { ++ KMessageBox::sorry( ++ parentWidget, ++ i18n( "No item selected." ), ++ "SaveAttachments" ); ++ return; ++ } ++ ++ Attachment::List attachments = incidence->attachments(); ++ ++ if ( attachments.empty() ) ++ return; ++ ++ QString targetFile, targetDir; ++ if ( attachments.count() > 1 ) { ++ // get the dir ++ targetDir = KFileDialog::getExistingDirectory( KUrl( "kfiledialog:///saveAttachment" ), ++ parentWidget, ++ i18n( "Save Attachments To" ) ); ++ if ( targetDir.isEmpty() ) { ++ return; ++ } ++ ++ // we may not get a slash-terminated url out of KFileDialog ++ if ( !targetDir.endsWith('/') ) ++ targetDir.append('/'); ++ } ++ else { ++ // only one item, get the desired filename ++ QString fileName = attachments.first()->label(); ++ if ( fileName.isEmpty() ) { ++ fileName = i18nc( "filename for an unnamed attachment", "attachment.1" ); ++ } ++ targetFile = KFileDialog::getSaveFileName( KUrl( "kfiledialog:///saveAttachment/" + fileName ), ++ QString(), ++ parentWidget, ++ i18n( "Save Attachment" ) ); ++ if ( targetFile.isEmpty() ) { ++ return; ++ } ++ ++ targetDir = QFileInfo( targetFile ).absolutePath() + "/"; ++ } ++ ++ Q_FOREACH( Attachment::Ptr attachment, attachments ) { ++ targetFile = targetDir + attachment->label(); ++ KUrl sourceUrl; ++ if ( attachment->isUri() ) { ++ sourceUrl = attachment->uri(); ++ } else { ++ sourceUrl = incidence->writeAttachmentToTempFile( attachment ); ++ } ++ // save the attachment url ++ if ( !KIO::NetAccess::file_copy( sourceUrl, KUrl( targetFile ) ) && ++ KIO::NetAccess::lastError() ) { ++ KMessageBox::error( parentWidget, KIO::NetAccess::lastErrorString() ); ++ } ++ }*/ ++ ++} +diff --git a/plasma/generic/dataengines/calendar/akonadi/utils.h b/plasma/generic/dataengines/calendar/akonadi/utils.h +new file mode 100644 +index 0000000..d923594 +--- /dev/null ++++ b/plasma/generic/dataengines/calendar/akonadi/utils.h +@@ -0,0 +1,250 @@ ++/* ++ Copyright (c) 2009, 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com ++ Copyright (C) 2009 KDAB (author: Frank Osterfeld ) ++ Copyright (c) 2010 Andras Mantia ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ ++ As a special exception, permission is given to link this program ++ with any edition of Qt, and distribute the resulting executable, ++ without including the source code for Qt in the source distribution. ++*/ ++#ifndef CALENDARSUPPORT_UTILS_H ++#define CALENDARSUPPORT_UTILS_H ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++ ++namespace KPIMIdentities { ++class IdentityManager; ++} ++ ++namespace KCalCore { ++ class CalFilter; ++} ++ ++class QAbstractItemModel; ++class QDrag; ++class QMimeData; ++ ++typedef QList QModelIndexList; ++ ++namespace CalendarSupport ++{ ++ ++class Calendar; ++ ++ /** ++ * returns the incidence from an akonadi item, or a null pointer if the item has no such payload ++ */ ++ KCalCore::Incidence::Ptr incidence( const Akonadi::Item &item ); ++ ++ /** ++ * returns the event from an akonadi item, or a null pointer if the item has no such payload ++ */ ++ KCalCore::Event::Ptr event( const Akonadi::Item &item ); ++ ++ /** ++ * returns event pointers from an akonadi item, or a null pointer if the item has no such payload ++ */ ++ KCalCore::Event::List eventsFromItems( ++ const Akonadi::Item::List &items ); ++ ++ /** ++ * returns incidence pointers from an akonadi item. ++ */ ++ KCalCore::Incidence::List incidencesFromItems( ++ const Akonadi::Item::List &items ); ++ ++ ++ /** ++ * returns the todo from an akonadi item, or a null pointer if the item has no such payload ++ */ ++ KCalCore::Todo::Ptr todo( const Akonadi::Item &item ); ++ ++ /** ++ * returns the journal from an akonadi item, or a null pointer if the item has no such payload ++ */ ++ KCalCore::Journal::Ptr journal( const Akonadi::Item &item ); ++ ++ /** ++ * returns whether an Akonadi item contains an incidence ++ */ ++ bool hasIncidence( const Akonadi::Item &item ); ++ ++ /** ++ * returns whether an Akonadi item contains an event ++ */ ++ bool hasEvent( const Akonadi::Item &item ); ++ ++ /** ++ * returns whether an Akonadi item contains a todo ++ */ ++ bool hasTodo( const Akonadi::Item &item ); ++ ++ /** ++ * returns whether an Akonadi item contains a journal ++ */ ++ bool hasJournal( const Akonadi::Item &item ); ++ ++ /** ++ * returns whether this item can be deleted ++ */ ++ bool hasDeleteRights( const Akonadi::Item &item ); ++ ++ /** ++ * returns whether this item can be changed ++ */ ++ bool hasChangeRights( const Akonadi::Item &item ); ++ ++ /** ++ * returns @p true if the URL represents an Akonadi item and has one of the given mimetypes. ++ */ ++ bool isValidIncidenceItemUrl( const KUrl &url, ++ const QStringList &supportedMimeTypes ); ++ ++ bool isValidIncidenceItemUrl( const KUrl &url ); ++ ++ /** ++ * returns @p true if the mime data object contains any of the following: ++ * ++ * * An akonadi item with a supported KCal mimetype ++ * * an iCalendar ++ * * a VCard ++ */ ++ bool canDecode( const QMimeData *mimeData ); ++ ++ QList incidenceItemUrls( const QMimeData *mimeData ); ++ ++ QList todoItemUrls( const QMimeData *mimeData ); ++ ++ bool mimeDataHasTodo( const QMimeData *mimeData ); ++ ++ KCalCore::Todo::List todos( const QMimeData *mimeData, ++ const KDateTime::Spec &timeSpec ); ++ ++ /** ++ * returns @p true if the URL represents an Akonadi item and has one of the given mimetypes. ++ */ ++ bool isValidTodoItemUrl( const KUrl &url ); ++ ++ /** ++ * creates mime data object for dragging an akonadi item containing an incidence ++ */ ++ QMimeData *createMimeData( const Akonadi::Item &item, ++ const KDateTime::Spec &timeSpec ); ++ ++ /** ++ * creates mime data object for dragging akonadi items containing an incidence ++ */ ++ QMimeData *createMimeData( const Akonadi::Item::List &items, ++ const KDateTime::Spec &timeSpec ); ++ ++#ifndef QT_NO_DRAGANDDROP ++ /** ++ * creates a drag object for dragging an akonadi item containing an incidence ++ */ ++ QDrag *createDrag( const Akonadi::Item &item, ++ const KDateTime::Spec &timeSpec, QWidget *parent ); ++ ++ /** ++ * creates a drag object for dragging akonadi items containing an incidence ++ */ ++ QDrag *createDrag( const Akonadi::Item::List &items, ++ const KDateTime::Spec &timeSpec, QWidget *parent ); ++#endif ++ /** ++ Applies a filter to a list of items containing incidences. ++ Items not containing incidences or not matching the filter are removed. ++ Helper method anologous to KCalCore::CalFilter::apply() ++ @see KCalCore::CalFilter::apply() ++ @param items the list of items to filter ++ @param filter the filter to apply to the list of items ++ @return the filtered list of items ++ */ ++ Akonadi::Item::List applyCalFilter( const Akonadi::Item::List &items, ++ const KCalCore::CalFilter *filter ); ++ ++ /** ++ Shows a modal dialog that allows to select a collection. ++ ++ @param will contain the dialogCode, QDialog::Accepted if the user pressed Ok, ++ QDialog::Rejected otherwise ++ @param parent The optional parent of the modal dialog. ++ @return The select collection or an invalid collection if ++ there was no collection selected. ++ */ ++ Akonadi::Collection selectCollection( ++ QWidget *parent, int &dialogCode, ++ const QStringList &mimeTypes, ++ const Akonadi::Collection &defaultCollection = Akonadi::Collection() ); ++ ++ Akonadi::Item itemFromIndex( const QModelIndex &index ); ++ ++ Akonadi::Item::List itemsFromModel( ++ const QAbstractItemModel *model, ++ const QModelIndex &parentIndex = QModelIndex(), ++ int start = 0, ++ int end = -1 ); ++ ++ Akonadi::Collection::List collectionsFromModel( ++ const QAbstractItemModel *model, ++ const QModelIndex &parentIndex = QModelIndex(), ++ int start = 0, ++ int end = -1 ); ++ ++ Akonadi::Collection collectionFromIndex( const QModelIndex &index ); ++ ++ Akonadi::Collection::Id collectionIdFromIndex( const QModelIndex &index ); ++ ++ Akonadi::Collection::List collectionsFromIndexes( ++ const QModelIndexList &indexes ); ++ ++ QString displayName( const Akonadi::Collection &coll ); ++ ++ QString subMimeTypeForIncidence( ++ const KCalCore::Incidence::Ptr &incidence ); ++ ++ /** ++ Returns a list containing work days between @p start and @end. ++ */ ++ QList workDays( const QDate &start, const QDate &end ); ++ ++ /** ++ Returns a list of holidays that occur at @param date. ++ */ ++ QStringList holiday( const QDate &date ); ++ ++ void sendAsICalendar( const Akonadi::Item& item, KPIMIdentities::IdentityManager *identityManager, QWidget* parentWidget = 0 ); ++ ++ void publishItemInformation( const Akonadi::Item& item, Calendar* calendar, QWidget* parentWidget = 0 ); ++ ++ void scheduleiTIPMethods( KCalCore::iTIPMethod method, const Akonadi::Item &item, Calendar* calendar, QWidget *parentWidget = 0 ); ++ ++ void saveAttachments( const Akonadi::Item& item, QWidget* parentWidget = 0 ); ++ ++} ++ ++#endif +diff --git a/plasma/generic/dataengines/calendar/calendarengine.cpp b/plasma/generic/dataengines/calendar/calendarengine.cpp +index 5b98d8a..7235f74 100644 +--- a/plasma/generic/dataengines/calendar/calendarengine.cpp ++++ b/plasma/generic/dataengines/calendar/calendarengine.cpp +@@ -31,13 +31,24 @@ + #include + #include + #include ++#include + + #ifdef AKONADI_FOUND ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "akonadi/calendar.h" ++#include "akonadi/calendarmodel.h" + #include "eventdatacontainer.h" + #endif + + CalendarEngine::CalendarEngine(QObject* parent, const QVariantList& args) +- : Plasma::DataEngine(parent) ++ : Plasma::DataEngine(parent), ++ m_calendar(0) + { + Q_UNUSED(args); + } +@@ -299,16 +310,46 @@ bool CalendarEngine::akonadiCalendarSourceRequest(const QString& key, const QStr + return false; + } + +- if (!m_calendar) { +- m_calendar = Akonadi::ETMCalendar::Ptr(new Akonadi::ETMCalendar()); +- m_calendar->setCollectionFilteringEnabled(false); +- } ++ // start akonadi etc if needed ++ initAkonadiCalendar(); + + // create the corresponding EventDataContainer + addSource(new EventDataContainer(m_calendar, request, KDateTime(start, QTime(0, 0, 0)), KDateTime(end, QTime(23, 59, 59)))); + return true; + } + +-#endif // AKONADI_FOUND ++void CalendarEngine::initAkonadiCalendar() ++{ ++ if (m_calendar != 0) { ++ // we have been initialized already ++ return; ++ } ++ ++ // ask for akonadi events ++ Akonadi::Session *session = new Akonadi::Session("PlasmaCalendarEngine", this); ++ Akonadi::ChangeRecorder* monitor = new Akonadi::ChangeRecorder(this); ++ Akonadi::ItemFetchScope scope; ++ scope.fetchFullPayload(true); ++ scope.fetchAttribute(); ++ ++ // setup what part of akonadi data we want (calendar incidences) ++ monitor->setSession(session); ++ monitor->setCollectionMonitored(Akonadi::Collection::root()); ++ monitor->fetchCollection(true); ++ monitor->setItemFetchScope(scope); ++ monitor->setMimeTypeMonitored(KCalCore::Event::eventMimeType(), true); ++ monitor->setMimeTypeMonitored(KCalCore::Todo::todoMimeType(), true); ++ monitor->setMimeTypeMonitored(KCalCore::Journal::journalMimeType(), true); ++ ++ // create the models that contain the data. they will be updated automatically from akonadi. ++ CalendarSupport::CalendarModel *calendarModel = new CalendarSupport::CalendarModel(monitor, this); ++ KDescendantsProxyModel *flatModel = new KDescendantsProxyModel(this); ++ flatModel->setSourceModel(calendarModel); ++ Akonadi::EntityMimeTypeFilterModel *mimeFilteredModel = new Akonadi::EntityMimeTypeFilterModel(this); ++ mimeFilteredModel->addMimeTypeExclusionFilter(Akonadi::Collection::mimeType()); ++ mimeFilteredModel->setSourceModel(flatModel); ++ m_calendar = new CalendarSupport::Calendar(mimeFilteredModel, mimeFilteredModel, KSystemTimeZones::local()); ++} ++#endif + + #include "calendarengine.moc" +diff --git a/plasma/generic/dataengines/calendar/calendarengine.h b/plasma/generic/dataengines/calendar/calendarengine.h +index 21ad533..18ae774 100644 +--- a/plasma/generic/dataengines/calendar/calendarengine.h ++++ b/plasma/generic/dataengines/calendar/calendarengine.h +@@ -24,9 +24,9 @@ + + #include + +-#ifdef AKONADI_FOUND +-# include +-#endif ++namespace CalendarSupport { ++ class Calendar; ++} + + namespace KHolidays + { +@@ -163,10 +163,11 @@ class CalendarEngine : public Plasma::DataEngine + /// creates EventDataContainers as needed + bool akonadiCalendarSourceRequest(const QString& key, const QStringList& args, const QString& request); + +-#ifdef AKONADI_FOUND ++ /// this will start akonadi if necessary and init m_calendarModel ++ void initAkonadiCalendar(); ++ + /// this is the representation of the root calendar itself. it contains everything (calendars, incidences) +- Akonadi::ETMCalendar::Ptr m_calendar; +-#endif ++ CalendarSupport::Calendar *m_calendar; + + /// holiday calendar + QHash m_regions; +diff --git a/plasma/generic/dataengines/calendar/eventdatacontainer.cpp b/plasma/generic/dataengines/calendar/eventdatacontainer.cpp +index 27a1d58..63db4df 100644 +--- a/plasma/generic/dataengines/calendar/eventdatacontainer.cpp ++++ b/plasma/generic/dataengines/calendar/eventdatacontainer.cpp +@@ -21,14 +21,19 @@ + + #include + ++#include + #include + #include + #include + #include + ++#include "akonadi/calendar.h" ++#include "akonadi/calendarmodel.h" ++ + using namespace Akonadi; ++using namespace CalendarSupport; + +-EventDataContainer::EventDataContainer(const Akonadi::ETMCalendar::Ptr &calendar, const QString& name, const KDateTime& start, const KDateTime& end, QObject* parent) ++EventDataContainer::EventDataContainer(CalendarSupport::Calendar* calendar, const QString& name, const KDateTime& start, const KDateTime& end, QObject* parent) + : Plasma::DataContainer(parent), + m_calendar(calendar), + m_name(name), +@@ -39,7 +44,7 @@ EventDataContainer::EventDataContainer(const Akonadi::ETMCalendar::Ptr &calendar + setObjectName(name); + + // Connect directly to the calendar for now +- connect(calendar.data(), SIGNAL(calendarChanged()), this, SLOT(updateData())); ++ connect(calendar, SIGNAL(calendarChanged()), this, SLOT(updateData())); + + // create the initial data + updateData(); +@@ -56,10 +61,14 @@ void EventDataContainer::updateData() + + void EventDataContainer::updateEventData() + { +- KCalCore::Event::List events = m_calendar->events(m_startDate.date(), m_endDate.date(), m_calendar->timeSpec()); ++ Akonadi::Item::List events = m_calendar->events(m_startDate.date(), m_endDate.date(), m_calendar->timeSpec()); ++ ++ foreach (const Akonadi::Item &item, events) { ++ Q_ASSERT(item.hasPayload()); ++ const KCalCore::Event::Ptr event = item.payload(); + +- foreach (const KCalCore::Event::Ptr &event, events) { + Plasma::DataEngine::Data eventData; ++ + populateIncidenceData(event, eventData); + + // Event specific fields +@@ -81,10 +90,14 @@ void EventDataContainer::updateTodoData() + { + QDate todoDate = m_startDate.date(); + while(todoDate <= m_endDate.date()) { +- KCalCore::Todo::List todos = m_calendar->todos(todoDate); ++ Akonadi::Item::List todos = m_calendar->todos(todoDate); ++ ++ foreach (const Akonadi::Item &item, todos) { ++ Q_ASSERT(item.hasPayload()); ++ const KCalCore::Todo::Ptr todo = item.payload(); + +- foreach (const KCalCore::Todo::Ptr &todo, todos) { + Plasma::DataEngine::Data todoData; ++ + populateIncidenceData(todo, todoData); + + QVariant var; +@@ -113,13 +126,18 @@ void EventDataContainer::updateJournalData() + { + QDate journalDate = m_startDate.date(); + while(journalDate <= m_endDate.date()) { +- KCalCore::Journal::List journals = m_calendar->journals(journalDate); ++ Akonadi::Item::List journals = m_calendar->journals(journalDate); ++ ++ foreach (const Akonadi::Item &item, journals) { ++ Q_ASSERT(item.hasPayload()); ++ const KCalCore::Journal::Ptr journal = item.payload(); + +- foreach (const KCalCore::Journal::Ptr &journal, journals) { + Plasma::DataEngine::Data journalData; ++ + populateIncidenceData(journal, journalData); + + // No Journal specific fields ++ + setData(journal->uid(), journalData); + } + +@@ -127,7 +145,7 @@ void EventDataContainer::updateJournalData() + } + } + +-void EventDataContainer::populateIncidenceData(const KCalCore::Incidence::Ptr &incidence, Plasma::DataEngine::Data &incidenceData) ++void EventDataContainer::populateIncidenceData(KCalCore::Incidence::Ptr incidence, Plasma::DataEngine::Data &incidenceData) + { + QVariant var; + incidenceData["UID"] = incidence->uid(); +diff --git a/plasma/generic/dataengines/calendar/eventdatacontainer.h b/plasma/generic/dataengines/calendar/eventdatacontainer.h +index fd3996f..b170a14 100644 +--- a/plasma/generic/dataengines/calendar/eventdatacontainer.h ++++ b/plasma/generic/dataengines/calendar/eventdatacontainer.h +@@ -21,15 +21,20 @@ + #define EVENTDATACONTAINER_H + + #include +-#include ++ + #include ++ + #include + +-class EventDataContainer : public Plasma::DataContainer ++namespace CalendarSupport { ++ class Calendar; ++} ++ ++class EventDataContainer :public Plasma::DataContainer + { + Q_OBJECT + public: +- EventDataContainer(const Akonadi::ETMCalendar::Ptr &calendar, const QString& name, const KDateTime& start, const KDateTime& end, QObject* parent = 0); ++ EventDataContainer(CalendarSupport::Calendar* calendar, const QString& name, const KDateTime& start, const KDateTime& end, QObject* parent = 0); + + public Q_SLOTS: + // update the list of incidents +@@ -39,9 +44,9 @@ private: + void updateEventData(); + void updateTodoData(); + void updateJournalData(); +- void populateIncidenceData(const KCalCore::Incidence::Ptr &incidence, Plasma::DataEngine::Data &incidenceData); ++ void populateIncidenceData(KCalCore::Incidence::Ptr incidence, Plasma::DataEngine::Data &incidenceData); + +- Akonadi::ETMCalendar::Ptr m_calendar; ++ CalendarSupport::Calendar *m_calendar; + QString m_name; + KDateTime m_startDate; + KDateTime m_endDate; diff --git a/SOURCES/kde-workspace-4.11.0-backlight_actual_brightness.patch b/SOURCES/kde-workspace-4.11.0-backlight_actual_brightness.patch new file mode 100644 index 0000000..eb375c8 --- /dev/null +++ b/SOURCES/kde-workspace-4.11.0-backlight_actual_brightness.patch @@ -0,0 +1,12 @@ +diff -up kde-workspace-4.11.0/powerdevil/daemon/backends/upower/backlighthelper.cpp.actual_brightness kde-workspace-4.11.0/powerdevil/daemon/backends/upower/backlighthelper.cpp +--- kde-workspace-4.11.0/powerdevil/daemon/backends/upower/backlighthelper.cpp.actual_brightness 2013-07-09 17:44:32.000000000 -0500 ++++ kde-workspace-4.11.0/powerdevil/daemon/backends/upower/backlighthelper.cpp 2013-08-21 08:07:27.207287869 -0500 +@@ -252,7 +252,7 @@ ActionReply BacklightHelper::brightness( + return reply; + } + #else +- QFile file(m_dirname + "/brightness"); ++ QFile file(m_dirname + "/actual_brightness"); + if (!file.open(QIODevice::ReadOnly)) { + reply = ActionReply::HelperErrorReply; + reply.setErrorCode(file.error()); diff --git a/SOURCES/kde-workspace-4.11.1-kdm-logind-multiseat.patch b/SOURCES/kde-workspace-4.11.1-kdm-logind-multiseat.patch new file mode 100644 index 0000000..99a259e --- /dev/null +++ b/SOURCES/kde-workspace-4.11.1-kdm-logind-multiseat.patch @@ -0,0 +1,405 @@ +diff -up kde-workspace-4.10.90/CMakeLists.txt.kdm_logind kde-workspace-4.10.90/CMakeLists.txt +--- kde-workspace-4.10.90/CMakeLists.txt.kdm_logind 2013-06-27 16:27:30.199895076 -0500 ++++ kde-workspace-4.10.90/CMakeLists.txt 2013-06-27 16:30:25.167008304 -0500 +@@ -128,6 +128,13 @@ if(Q_WS_X11) + endif() + endif(Q_WS_X11) + ++macro_optional_find_package(Systemd) ++set_package_properties(Systemd PROPERTIES DESCRIPTION "Init and service manager for Linux" ++ URL "http://www.freedesktop.org/wiki/Software/systemd" ++ TYPE OPTIONAL ++ PURPOSE "Provides automatic multi-seat, session and power management features" ++ ) ++ + macro_optional_find_package(GLIB2 2.0) + set_package_properties(GLIB2 PROPERTIES DESCRIPTION "Low-level core library for data structure handling, portability wrappers, etc." + URL "http://www.gtk.org" +diff -up kde-workspace-4.10.90/cmake/modules/CMakeLists.txt.kdm_logind kde-workspace-4.10.90/cmake/modules/CMakeLists.txt +--- kde-workspace-4.10.90/cmake/modules/CMakeLists.txt.kdm_logind 2013-06-10 13:51:11.000000000 -0500 ++++ kde-workspace-4.10.90/cmake/modules/CMakeLists.txt 2013-06-27 16:27:30.199895076 -0500 +@@ -8,6 +8,7 @@ set(cmakeFiles FindCkConnector.cmake + FindOpenGLES.cmake + FindPAM.cmake + FindSensors.cmake ++ FindSystemd.cmake + PkgConfigGetVar.cmake + UnixAuth.cmake ) + +diff -up kde-workspace-4.10.90/cmake/modules/FindSystemd.cmake.kdm_logind kde-workspace-4.10.90/cmake/modules/FindSystemd.cmake +--- kde-workspace-4.10.90/cmake/modules/FindSystemd.cmake.kdm_logind 2013-06-27 16:27:30.200895065 -0500 ++++ kde-workspace-4.10.90/cmake/modules/FindSystemd.cmake 2013-06-27 16:27:30.200895065 -0500 +@@ -0,0 +1,39 @@ ++# Finds systemd and its libraries ++# Not a huge module but sufficient for now ++# Uses the same semantics as pkg_check_modules, i.e. ${LIB}{_FOUND,_INCLUDE_DIR,_LIBRARIES} ++# where ${LIB} can be one of the following: ++# LIBSYSTEMD_JOURNAL, SYSTEMD, LIBSYSTEMD_DAEMON, LIBSYSTEMD_LOGIN, LIBSYSTEMD_ID128 ++# ++# Copyright: Red Hat, Inc. 2013 ++# Author: Martin Briza ++# ++# Distributed under the BSD license. See COPYING-CMAKE-SCRIPTS for details. ++ ++#defining any of these disables systemd support ++if (NOT LIBSYSTEMD_JOURNAL_FOUND AND ++ NOT SYSTEMD_FOUND AND ++ NOT LIBSYSTEMD_DAEMON_FOUND AND ++ NOT LIBSYSTEMD_LOGIN_FOUND AND ++ NOT LIBSYSTEMD_ID128_FOUND) ++find_package(PkgConfig) ++if (PKG_CONFIG_FOUND) ++ pkg_check_modules(LIBSYSTEMD_JOURNAL QUIET "libsystemd-journal") ++ pkg_check_modules(SYSTEMD QUIET "systemd") ++ pkg_check_modules(LIBSYSTEMD_DAEMON QUIET "libsystemd-daemon") ++ pkg_check_modules(LIBSYSTEMD_LOGIN QUIET "libsystemd-login") ++ pkg_check_modules(LIBSYSTEMD_ID128 QUIET "libsystemd-id128") ++endif (PKG_CONFIG_FOUND) ++ ++if (SYSTEMD_FOUND) ++ message(STATUS "Found systemd") ++endif(SYSTEMD_FOUND) ++ ++mark_as_advanced(LIBSYSTEMD_JOURNAL_FOUND SYSTEMD_FOUND LIBSYSTEMD_DAEMON_FOUND LIBSYSTEMD_LOGIN_FOUND LIBSYSTEMD_ID128_FOUND) ++mark_as_advanced(LIBSYSTEMD_JOURNAL_INCLUDE_DIR SYSTEMD_INCLUDE_DIR LIBSYSTEMD_DAEMON_INCLUDE_DIR LIBSYSTEMD_LOGIN_INCLUDE_DIR LIBSYSTEMD_ID128_INCLUDE_DIR) ++mark_as_advanced(LIBSYSTEMD_JOURNAL_LIBRARIES SYSTEMD_LIBRARIES LIBSYSTEMD_DAEMON_LIBRARIES LIBSYSTEMD_LOGIN_LIBRARIES LIBSYSTEMD_ID128_LIBRARIES) ++ ++endif (NOT LIBSYSTEMD_JOURNAL_FOUND AND ++ NOT SYSTEMD_FOUND AND ++ NOT LIBSYSTEMD_DAEMON_FOUND AND ++ NOT LIBSYSTEMD_LOGIN_FOUND AND ++ NOT LIBSYSTEMD_ID128_FOUND) +diff -up kde-workspace-4.10.90/kdm/backend/CMakeLists.txt.kdm_logind kde-workspace-4.10.90/kdm/backend/CMakeLists.txt +--- kde-workspace-4.10.90/kdm/backend/CMakeLists.txt.kdm_logind 2013-05-28 13:38:21.000000000 -0500 ++++ kde-workspace-4.10.90/kdm/backend/CMakeLists.txt 2013-06-27 16:27:30.201895054 -0500 +@@ -45,6 +45,10 @@ if (SECURE_RPC) + rpcauth.c + ) + endif (SECURE_RPC) ++if(LIBSYSTEMD_LOGIN_FOUND AND LIBSYSTEMD_DAEMON_FOUND) ++ add_definitions( -DWITH_SYSTEMD=1 ) ++ set(KDM_SYSTEMD_LIBRARIES ${LIBSYSTEMD_DAEMON_LIBRARIES} ${LIBSYSTEMD_LOGIN_LIBRARIES} ) ++endif(LIBSYSTEMD_LOGIN_FOUND AND LIBSYSTEMD_DAEMON_FOUND) + macro_add_file_dependencies(dm.h ${confci}) + macro_add_file_dependencies(error.c ${CMAKE_CURRENT_SOURCE_DIR}/printf.c) + kde4_add_executable(kdm NOGUI ${kdm_SRCS}) +@@ -61,6 +65,7 @@ target_link_libraries( kdm + ${NSL_LIBRARIES} + ${RESOLV_LIBRARIES} + ${SOCKET_LIBRARIES} ++ ${KDM_SYSTEMD_LIBRARIES} + ) + if (CKCONNECTOR_FOUND) + include_directories(${CKCONNECTOR_INCLUDE_DIR} ${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR}) +diff -up kde-workspace-4.10.90/kdm/backend/dm.c.kdm_logind kde-workspace-4.10.90/kdm/backend/dm.c +--- kde-workspace-4.10.90/kdm/backend/dm.c.kdm_logind 2013-06-27 16:27:30.184895241 -0500 ++++ kde-workspace-4.10.90/kdm/backend/dm.c 2013-06-27 16:27:30.201895054 -0500 +@@ -50,6 +50,23 @@ from the copyright holder. + # include + #endif + ++#ifdef WITH_SYSTEMD ++# include ++# include ++ ++#define SYSTEMD_FAILURE_LIMIT 25 ++ ++ static int systemdMonitorInit(void); ++ static void systemdMonitorDeinit(); ++ static int systemdStartDisplay(char *); ++ static void systemdCheckAdded(char **); ++ static void systemdCheckRemoved(char **); ++ static void systemdHandleChange(); ++ ++ sd_login_monitor *systemd_monitor = NULL; ++ int systemd_monitor_fd = -1; ++#endif ++ + static void sigHandler(int n); + static int scanConfigs(int force); + static void startDisplay(struct display *d); +@@ -308,7 +325,16 @@ main(int argc, char **argv) + #ifdef XDMCP + updateListenSockets(); + #endif ++ ++#ifdef WITH_SYSTEMD ++ if (systemdMonitorInit()) ++ systemdHandleChange(); ++#endif ++ + mainLoop(); ++#ifdef WITH_SYSTEMD ++ systemdMonitorDeinit(); ++#endif + closeCtrl(0); + if (sdRec.how) { + int pid; +@@ -1280,6 +1306,14 @@ mainLoop(void) + } + continue; + } ++ logError("STARTING"); ++#ifdef WITH_SYSTEMD ++ if (systemd_monitor_fd >= 0 && FD_ISSET(systemd_monitor_fd, &reads)) { ++ systemdHandleChange(); ++ sd_login_monitor_flush(systemd_monitor); ++ continue; ++ } ++#endif + #ifdef XDMCP + if (processListenSockets(&reads)) + continue; +@@ -1304,6 +1338,151 @@ mainLoop(void) + } + } + ++#ifdef WITH_SYSTEMD ++static int ++systemdMonitorInit(void) ++{ ++ if (sd_booted() <= 0) { ++ logError("Didn't boot with systemd, automatic multiseat won't be enabled\n"); ++ return False; ++ } ++ ++ int check = sd_login_monitor_new("seat", &systemd_monitor); ++ if (check < 0) { ++ logError("Can't get systemd monitor: %d, automatic multiseat won't be enabled\n", check); ++ return False; ++ } ++ ++ systemd_monitor_fd = sd_login_monitor_get_fd(systemd_monitor); ++ if (systemd_monitor_fd < 0) { ++ logError("Can't retrieve file descriptor from the systemd monitor: %d, automatic multiseat won't be enabled\n", systemd_monitor_fd); ++ sd_login_monitor_unref(systemd_monitor); ++ systemd_monitor_fd = -1; ++ return False; ++ } ++ ++ registerInput(systemd_monitor_fd); ++ return True; ++} ++ ++static void ++systemdMonitorDeinit(void) ++{ ++ if (systemd_monitor) { ++ sd_login_monitor_unref(systemd_monitor); ++ } ++ systemd_monitor_fd = -1; ++} ++ ++static int ++systemdStartDisplay(char *seat) ++{ ++ struct display *link = NULL; ++ for (link = displays; link; link = link-> next) { ++ if (link->status == reserve) ++ break; ++ } ++ if (!link) { ++ logError("There's not enough reserve displays for all your seats/sessions"); ++ return False; ++ } ++ if (!strDup((&link->systemd_seat), seat)) { ++ return False; ++ } ++#ifdef HAVE_VTS ++ link->serverVT = 0; ++#endif ++ link->status = notRunning; ++ link->stillThere = True; ++ link->authorize = True; ++ link->displayType = dLocal | dPermanent; ++ link->reqSrvVT = -1; ++ link->serverPid = -1; ++ return True; ++} ++ ++static void ++systemdCheckAdded(char **seat_names) ++{ ++ char **iter_name; ++ struct display *link; ++ for (iter_name = seat_names; *iter_name; iter_name++) { ++ if (strcmp(*iter_name, "seat0") == 0) ++ continue; /* ignore the main seat */ ++ int can_graphical = sd_seat_can_graphical(*iter_name); ++ for (link = displays; link; link = link->next) { ++ if (!link->systemd_seat) ++ continue; ++ /* see if the can_graphical property didn't change */ ++ if (strcmp(*iter_name, link->systemd_seat) == 0) { ++ if (!can_graphical) { ++ free(link->systemd_seat); ++ link->systemd_seat = NULL; ++ rStopDisplay(link, DS_RESERVE); ++ } ++ break; ++ } ++ } ++ /* the display wasn't found */ ++ if (!link) { ++ if (can_graphical) { ++ /* if starting the display failed, skip this round until the next change */ ++ if (!systemdStartDisplay(*iter_name)) ++ break; ++ } ++ } ++ } ++} ++ ++static void ++systemdCheckRemoved(char **seat_names) ++{ ++ char **iter_name; ++ struct display *link; ++ for (link = displays; link; link = link->next) { ++ for (iter_name = seat_names; *iter_name; iter_name++) { ++ if (strcmp(*iter_name, "seat0") == 0) ++ continue; /* ignore the main seat */ ++ if (link->systemd_seat && strcmp(*iter_name, link->systemd_seat) == 0) ++ break; ++ } ++ if (!(*iter_name) && link->systemd_seat) { /* was not found, stop this one */ ++ free(link->systemd_seat); ++ link->systemd_seat = NULL; ++ rStopDisplay(link, DS_RESERVE); ++ } ++ } ++} ++ ++static void ++systemdHandleChange(void) ++{ ++ static int failures = 0; ++ char **seat_names; ++ char **iter_name; ++ int check; ++ if ((check = sd_get_seats(&seat_names)) < 0) { ++ logError("Can't obtain systemd seats, error %d\n", -check); ++ failures++; ++ if (failures >= SYSTEMD_FAILURE_LIMIT) { ++ logError("%u failed calls to sd_get_seats, disabling systemd multi-seat support\n", SYSTEMD_FAILURE_LIMIT); ++ systemdMonitorDeinit(); ++ } ++ return; ++ } ++ ++ if (!check) ++ return; ++ ++ systemdCheckAdded(seat_names); ++ systemdCheckRemoved(seat_names); ++ ++ for (iter_name = seat_names; *iter_name; iter_name++) ++ free(*iter_name); ++ free(seat_names); ++} ++#endif ++ + static void + checkDisplayStatus(struct display *d) + { +diff -up kde-workspace-4.10.90/kdm/backend/dm.h.kdm_logind kde-workspace-4.10.90/kdm/backend/dm.h +--- kde-workspace-4.10.90/kdm/backend/dm.h.kdm_logind 2013-06-27 16:27:30.184895241 -0500 ++++ kde-workspace-4.10.90/kdm/backend/dm.h 2013-06-27 16:27:30.201895054 -0500 +@@ -306,6 +306,9 @@ struct display { + char *greeterAuthFile; /* file to store authorization for greeter in */ + + int plymouth_vt; /* Plymouth's VT nr */ ++#ifdef WITH_SYSTEMD ++ char *systemd_seat; ++#endif + }; + + #define d_location 1 +diff -up kde-workspace-4.10.90/kdm/backend/server.c.kdm_logind kde-workspace-4.10.90/kdm/backend/server.c +--- kde-workspace-4.10.90/kdm/backend/server.c.kdm_logind 2013-06-27 16:27:30.184895241 -0500 ++++ kde-workspace-4.10.90/kdm/backend/server.c 2013-06-27 16:27:30.201895054 -0500 +@@ -43,6 +43,7 @@ from the copyright holder. + #include + #include + ++#define SYSTEMD_X_WRAPPER "/lib/systemd/systemd-multi-seat-x" + + struct display *startingServer; + time_t serverTimeout = TO_INF; +@@ -55,9 +56,18 @@ prepareServerArgv(struct display *d, con + char vtstr[8]; + #endif + +- if (!(argv = parseArgs(0, d->serverCmd)) || +- !(argv = addStrArr(argv, d->name, -1))) ++#if WITH_SYSTEMD ++ FILE *tmpFile = NULL; ++ if ((tmpFile = fopen(SYSTEMD_X_WRAPPER, "rb")) != NULL && fclose(tmpFile) == 0) { ++ if (!(argv = parseArgs(0, SYSTEMD_X_WRAPPER)) || !(argv = addStrArr(argv, d->name, -1))) { ++ exit(47); ++ } ++ } ++ else ++#endif ++ if (!(argv = parseArgs(0, d->serverCmd)) || !(argv = addStrArr(argv, d->name, -1))) { + exit(47); ++ } + #ifdef HAVE_VTS + if (d->serverVT && + !(argv = addStrArr(argv, vtstr, +@@ -70,6 +80,25 @@ prepareServerArgv(struct display *d, con + if (!changeUser(d->serverUID, d->authFile)) + exit(47); + ++#ifdef WITH_SYSTEMD ++ if (d->systemd_seat) { ++ if (!(argv = parseArgs(argv, "-seat"))) ++ exit(47); ++ if (!(argv = parseArgs(argv, d->systemd_seat))) ++ exit(47); ++ if (!(argv = parseArgs(argv, "-layout"))) ++ exit(47); ++ if (!(argv = parseArgs(argv, d->systemd_seat))) ++ exit(47); ++ } ++ else { ++ if (!(argv = parseArgs(argv, "-seat"))) ++ exit(47); ++ if (!(argv = parseArgs(argv, "seat0"))) ++ exit(47); ++ } ++#endif ++ + return argv; + } + +--- kde-workspace-4.10.2/kdm/backend/client.c.kdm_logind ++++ kde-workspace-4.10.2/kdm/backend/client.c +@@ -1460,6 +1460,14 @@ startClient(volatile int *pid) + #endif + userEnviron = inheritEnv(env, envvars); + env = systemEnv(0, curuser); ++#ifdef WITH_SYSTEMD ++ if (td->systemd_seat) { ++ char *envbuf; ++ ASPrintf(&envbuf, "XDG_SEAT=%s", td->systemd_seat); ++ pam_putenv(pamh, envbuf); ++ env = setEnv(env, "XDG_SEAT", td->systemd_seat); ++ } ++#endif + systemEnviron = setEnv(env, "HOME", p->pw_dir); + debug("user environment:\n%[|''>'\n's" + "system environment:\n%[|''>'\n's" +--- kde-workspace-4.10.2/kdm/backend/session.c.kdm_logind ++++ kde-workspace-4.10.2/kdm/backend/session.c +@@ -437,6 +437,10 @@ openGreeter() + + grttalk.pipe = &grtproc.pipe; + env = systemEnv(dupEnv(), 0); ++#ifdef WITH_SYSTEMD ++ if (td->systemd_seat) ++ env = setEnv(env, "XDG_SEAT", td->systemd_seat); ++#endif + if (gOpen(&grtproc, (char **)0, "_greet", env, name, + greeterUID, td->greeterAuthFile, &td->gpipe)) + sessionExit(EX_UNMANAGE_DPY); diff --git a/SOURCES/kde-workspace-4.11.1-kdm_plymouth081.patch b/SOURCES/kde-workspace-4.11.1-kdm_plymouth081.patch new file mode 100644 index 0000000..3899bbb --- /dev/null +++ b/SOURCES/kde-workspace-4.11.1-kdm_plymouth081.patch @@ -0,0 +1,311 @@ +diff --git a/kdm/backend/dm.c b/kdm/backend/dm.c +index e0f1366..5a5f8a7 100644 +--- a/kdm/backend/dm.c ++++ b/kdm/backend/dm.c +@@ -1347,54 +1347,207 @@ getBusyVTs(void) + return activeVTs; + } + ++static int ++get_active_vt (void) ++{ ++ int console_fd; ++ struct vt_stat console_state = { 0 }; ++ console_fd = open ("/dev/tty0", O_RDONLY | O_NOCTTY); ++ if (console_fd < 0) { ++ return 0; ++ } ++ ioctl (console_fd, VT_GETSTATE, &console_state); ++ ++ close (console_fd); ++ return console_state.v_active; ++} ++ ++static int ++plymouth_is_running (void) ++{ ++ static int running = -1; ++ if (running == 0) ++ return 0; ++ ++ int status; ++ status = system ("/usr/bin/plymouth --ping"); ++ ++ running = WIFEXITED (status) && WEXITSTATUS (status) == 0; ++ logWarn ("plymouth is %srunning\n", running?"":"NOT "); ++ return running; ++} ++ ++static int ++plymouth_has_active_vt (void) ++{ ++ int status; ++ status = system ("/usr/bin/plymouth --has-active-vt"); ++ ++ return WIFEXITED (status) && WEXITSTATUS (status) == 0; ++} ++ ++static int ++plymouth_prepare_for_transition (void) ++{ ++ int status; ++ status = system ("/usr/bin/plymouth deactivate"); ++ ++ return WIFEXITED (status) && WEXITSTATUS (status) == 0; ++} ++ ++int ++plymouth_quit_with_transition (void) ++{ ++ int status; ++ status = system ("/usr/bin/plymouth --wait quit --retain-splash"); ++ ++ return WIFEXITED (status) && WEXITSTATUS (status) == 0; ++} ++ ++int ++plymouth_quit_without_transition (void) ++{ ++ int status; ++ status = system ("/usr/bin/plymouth --wait quit"); ++ ++ return WIFEXITED (status) && WEXITSTATUS (status) == 0; ++} ++ ++static int ++triggered_to_force_display_on_active_vt (void) ++{ ++ int should_force_display_on_active_vt; ++ should_force_display_on_active_vt=open("/var/spool/gdm/force-display-on-active-vt", O_RDONLY); ++ if ( should_force_display_on_active_vt >= 0 ) ++ close(should_force_display_on_active_vt); ++ unlink("/var/spool/gdm/force-display-on-active-vt"); ++ return should_force_display_on_active_vt; ++} ++ + static void + allocateVT(struct display *d) + { + struct display *cd; +- int i, tvt, volun; ++ int i, tvt; + + if ((d->displayType & d_location) == dLocal && + d->status == notRunning && !d->serverVT && d->reqSrvVT >= 0) + { ++ /* Try to find the correct VT. ++ * If ServerVT is specified in the config, use it (if the admin used the ++ * same VT for multiple display, it is his/her own fault, no checks done). ++ * Otherwise, walk the list of specified VTs. Positive numbers are used ++ * even if the VT is already in use by a tty. Negative numbers and ++ * unspecified numbers (up to #15) are used if not already in use. ++ * VTs already in use (cd->serverVT) or requested (cd->reqSrvVT) ++ * by any display are skipped. ++ */ ++ ++ /* some special handling is needed for Plymouth: ++ * if no VT is requested, use the active VT from plymouth for the first ++ * started display. ++ * If the display takes over the VT from plymouth, deactivate plymouth ++ */ ++ ++ char allowedVTs[16] = { 0 }; + if (d->reqSrvVT && d->reqSrvVT < 16) { +- d->serverVT = d->reqSrvVT; ++ allowedVTs[d->reqSrvVT] = 1; + } else { +- for (i = tvt = 0;;) { +- if (serverVTs[i]) { +- tvt = atoi(serverVTs[i++]); +- volun = False; +- if (tvt < 0) { +- tvt = -tvt; +- volun = True; +- } +- if (!tvt || tvt >= 16) +- continue; +- } else { +- if (++tvt >= 16) +- break; +- volun = True; ++ for (i = 0; serverVTs[i]; i++) { ++ tvt = atoi(serverVTs[i]); ++ if ((tvt >= 0) && (tvt < 16)) { ++ allowedVTs[tvt] = 1; ++ } else if (tvt > -16) { ++ allowedVTs[-tvt] = 2; + } +- for (cd = displays; cd; cd = cd->next) { +- if (cd->reqSrvVT == tvt && /* protect from lusers */ +- (cd->status != zombie || cd->zstatus != DS_REMOVE)) +- goto next; +- if (cd->serverVT == tvt) { +- if (cd->status != zombie || cd->zstatus == DS_REMOTE) +- goto next; +- if (!cd->follower) { +- d->serverVT = -1; +- cd->follower = d; +- return; +- } +- } ++ } ++ ++ for (tvt = 15; allowedVTs[tvt] == 0; tvt--) { ++ allowedVTs[tvt] = 2; ++ } ++ ++ for (cd = displays; cd; cd = cd->next) { ++ if (cd->status != zombie) { ++ if (cd->reqSrvVT >= 0) allowedVTs[cd->reqSrvVT] = 0; ++ if (cd->serverVT >= 0) allowedVTs[cd->serverVT] = 0; ++ } else if (cd->zstatus == DS_REMOTE) { ++ /* dying, but will spawn new server for remote login */ ++ if (cd->serverVT >= 0) allowedVTs[cd->serverVT] = 0; ++ } else if (cd->zstatus != DS_REMOVE) { ++ /* dying, but will be restarted or reserved */ ++ if (cd->reqSrvVT >= 0) allowedVTs[cd->reqSrvVT] = 0; + } +- if (!volun || !((1 << tvt) & getBusyVTs())) { +- d->serverVT = tvt; ++ } ++ } ++ ++ /* check for plymouth using newer methods */ ++ d->plymouth_vt = -1; ++ if (plymouth_is_running ()) { ++ if (plymouth_has_active_vt ()) { ++ int vt = get_active_vt (); ++ if (allowedVTs[vt]) { ++ logWarn ("plymouth is active on VT %d, reusing for %s\n", vt, d->name); ++ d->serverVT = vt; ++ d->plymouth_vt = vt; + return; + } +- next: ; ++ } ++ /* fallback to old/deprecated method */ ++ } else if ( triggered_to_force_display_on_active_vt() >= 0 ) { ++ int vt = get_active_vt (); ++ if (allowedVTs[vt]) { ++ d->serverVT = vt; ++ return; ++ } ++ } ++ ++ for (tvt = 0; tvt < 16; tvt++) { ++ if ((allowedVTs[tvt] == 1) || ++ ((allowedVTs[tvt] == 2) && !((1 << tvt) & getBusyVTs()))) { ++ d->serverVT = tvt; ++ return; + } + } ++ ++ for (cd = displays; cd; cd = cd->next) { ++ if ((cd->status == zombie) && (cd->zstatus != DS_REMOTE) && ++ (cd->follower == 0) && (cd->reqSrvVT != cd->serverVT)) { ++ /* removed; or restarted/reserved on any VT */ ++ d->serverVT = -1; ++ cd->follower = d; ++ return; ++ } ++ } ++ } ++} ++ ++static void ++replacePlymouth(void) ++{ ++ struct display *cd; ++ ++ /* if one display reuses plymouth' VT, plymouth is stopped in the ++ * startServerSuccess/Failed callback (see server.c). In any other ++ * case plymouth is stopped now. ++ */ ++ for (cd = displays; cd; cd = cd->next) { ++ if ((cd->serverVT > 0) && (cd->serverVT == cd->plymouth_vt)) { ++ if (cd->status == notRunning) { ++ /* tell plymouth to quit when server has started */ ++ logWarn ("plymouth should quit after server startup\n"); ++ plymouth_prepare_for_transition (); ++ kickDisplay(cd); ++ return; ++ } else if (cd->status == running) { ++ /* replacing server is starting up, do nothing */ ++ return; ++ } ++ } ++ } ++ ++ if ( plymouth_is_running ()) { ++ plymouth_prepare_for_transition (); ++ plymouth_quit_without_transition (); + } + } + #endif +@@ -1407,6 +1560,7 @@ startDisplays(void) + #ifdef HAVE_VTS + activeVTs = -1; + forEachDisplayRev(allocateVT); ++ replacePlymouth(); + #endif + forEachDisplay(kickDisplay); + } +diff --git a/kdm/backend/dm.h b/kdm/backend/dm.h +index 64e106b..930af0e 100644 +--- a/kdm/backend/dm.h ++++ b/kdm/backend/dm.h +@@ -304,6 +304,8 @@ struct display { + int authNum; /* number of authorizations */ + char *authFile; /* file to store authorization in */ + char *greeterAuthFile; /* file to store authorization for greeter in */ ++ ++ int plymouth_vt; /* Plymouth's VT nr */ + }; + + #define d_location 1 +@@ -428,6 +430,9 @@ int anyDisplaysLeft(void); + void forEachDisplay(void (*f)(struct display *)); + #ifdef HAVE_VTS + void forEachDisplayRev(void (*f)(struct display *)); ++/* function for plymouth */ ++int plymouth_quit_with_transition (void); ++int plymouth_quit_without_transition (void); + #endif + void removeDisplay(struct display *old); + struct display +diff --git a/kdm/backend/server.c b/kdm/backend/server.c +index d8dd6f3..8b4708e 100644 +--- a/kdm/backend/server.c ++++ b/kdm/backend/server.c +@@ -80,6 +80,7 @@ startServerOnce(void) + char **argv; + + debug("startServerOnce for %s, try %d\n", d->name, ++d->startTries); ++ + d->serverStatus = starting; + switch (Fork(&d->serverPid)) { + case 0: +@@ -137,6 +138,12 @@ startServerSuccess() + struct display *d = startingServer; + d->serverStatus = ignore; + serverTimeout = TO_INF; ++ if ((d->serverVT > 0) && (d->serverVT == d->plymouth_vt)) { ++ int plymouth_running; ++ logWarn ("Quitting Plymouth with transition\n" ); ++ plymouth_running = !plymouth_quit_with_transition (); ++ logWarn ("Is Plymouth still running? %s\n", plymouth_running ? "yes" : "no"); ++ } + debug("X server ready, starting session\n"); + startDisplayP2(d); + } +@@ -154,6 +161,10 @@ startServerFailed() + startingServer = 0; + logError("X server for display %s cannot be started," + " session disabled\n", d->name); ++ if ((d->serverVT > 0) && (d->serverVT == d->plymouth_vt)) { ++ logWarn ("Quitting Plymouth without transition\n" ); ++ plymouth_quit_without_transition (); ++ } + stopDisplay(d); + } + } diff --git a/SOURCES/kde-workspace-4.11.16-colorschemes-kde4.patch b/SOURCES/kde-workspace-4.11.16-colorschemes-kde4.patch new file mode 100644 index 0000000..47b991f --- /dev/null +++ b/SOURCES/kde-workspace-4.11.16-colorschemes-kde4.patch @@ -0,0 +1,33 @@ +diff -ur kde-workspace-4.11.16/kcontrol/colors/CMakeLists.txt kde-workspace-4.11.16-colorschemes-kde4/kcontrol/colors/CMakeLists.txt +--- kde-workspace-4.11.16/kcontrol/colors/CMakeLists.txt 2015-01-29 19:49:17.000000000 +0100 ++++ kde-workspace-4.11.16-colorschemes-kde4/kcontrol/colors/CMakeLists.txt 2015-03-07 02:36:25.000000000 +0100 +@@ -9,7 +9,7 @@ + + install(TARGETS kcm_colors DESTINATION ${PLUGIN_INSTALL_DIR}) + install( FILES colors.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) +-install( FILES colorschemes.knsrc DESTINATION ${CONFIG_INSTALL_DIR} ) ++install( FILES colorschemes.knsrc DESTINATION ${CONFIG_INSTALL_DIR} RENAME "colorschemes-kde4.knsrc" ) + + # built-in color schemes + FILE(GLOB schemefiles schemes/*.colors) +diff -ur kde-workspace-4.11.16/kcontrol/colors/colorscm.cpp kde-workspace-4.11.16-colorschemes-kde4/kcontrol/colors/colorscm.cpp +--- kde-workspace-4.11.16/kcontrol/colors/colorscm.cpp 2015-01-29 19:49:17.000000000 +0100 ++++ kde-workspace-4.11.16-colorschemes-kde4/kcontrol/colors/colorscm.cpp 2015-03-07 02:36:54.000000000 +0100 +@@ -397,7 +397,7 @@ + + void KColorCm::on_schemeKnsButton_clicked() + { +- KNS3::DownloadDialog dialog("colorschemes.knsrc", this); ++ KNS3::DownloadDialog dialog("colorschemes-kde4.knsrc", this); + dialog.exec(); + if ( ! dialog.changedEntries().isEmpty() ) + { +@@ -428,7 +428,7 @@ + } + + // upload +- KNS3::UploadDialog dialog("colorschemes.knsrc", this); ++ KNS3::UploadDialog dialog("colorschemes-kde4.knsrc", this); + dialog.setUploadFile(KUrl(path) ); + dialog.exec(); + } diff --git a/SOURCES/kde-workspace-4.11.19-coverity-scan-fixes.patch b/SOURCES/kde-workspace-4.11.19-coverity-scan-fixes.patch new file mode 100644 index 0000000..c585cd4 --- /dev/null +++ b/SOURCES/kde-workspace-4.11.19-coverity-scan-fixes.patch @@ -0,0 +1,74 @@ +diff --git a/kwin/clients/aurorae/src/aurorae.cpp b/kwin/clients/aurorae/src/aurorae.cpp +index a9487c3..6f63f6e 100644 +--- a/kwin/clients/aurorae/src/aurorae.cpp ++++ b/kwin/clients/aurorae/src/aurorae.cpp +@@ -435,13 +435,13 @@ KDecorationDefines::Position AuroraeClient::mousePosition(const QPoint &point) c + } + if (point.x() >= (m_view->width() - borderRight - paddingRight)) { + pos |= PositionRight; +- } else if (point.x() <= borderLeft + paddingLeft) { ++ } else if (point.x() <= (borderLeft + paddingLeft)) { + pos |= PositionLeft; + } + +- if (point.y() >= m_view->height() - borderBottom - paddingBottom) { ++ if (point.y() >= (m_view->height() - borderBottom - paddingBottom)) { + pos |= PositionBottom; +- } else if (point.y() <= borderTop + paddingTop ) { ++ } else if (point.y() <= (borderTop + paddingTop)) { + pos |= PositionTop; + } + +diff --git a/kwin/clients/oxygen/config/oxygenexceptionlistwidget.cpp b/kwin/clients/oxygen/config/oxygenexceptionlistwidget.cpp +index 3710ba2..8a11d07 100644 +--- a/kwin/clients/oxygen/config/oxygenexceptionlistwidget.cpp ++++ b/kwin/clients/oxygen/config/oxygenexceptionlistwidget.cpp +@@ -86,8 +86,8 @@ namespace Oxygen + //__________________________________________________________ + ConfigurationList ExceptionListWidget::exceptions( void ) + { +- return model().get(); + setChanged( false ); ++ return model().get(); + } + + //__________________________________________________________ +diff --git a/plasma/generic/applets/systemtray/protocols/fdo/fdographicswidget.cpp b/plasma/generic/applets/systemtray/protocols/fdo/fdographicswidget.cpp +index 80fbed3..7b8f8ed 100644 +--- a/plasma/generic/applets/systemtray/protocols/fdo/fdographicswidget.cpp ++++ b/plasma/generic/applets/systemtray/protocols/fdo/fdographicswidget.cpp +@@ -74,8 +74,8 @@ FdoGraphicsWidget::FdoGraphicsWidget(WId winId, QGraphicsWidget *parent) + } + } + +- if (parentView) { +- parentView->setViewportUpdateMode(QGraphicsView::FullViewportUpdate); ++ if (parentView) { ++ parentView->setViewportUpdateMode(QGraphicsView::FullViewportUpdate); + } + + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), +@@ -216,10 +216,10 @@ void FdoGraphicsWidget::handleClientError(QX11EmbedContainer::Error error) + + void FdoGraphicsWidget::resizeEvent(QGraphicsSceneResizeEvent *event) + { ++ Q_UNUSED(event); + if (d->widget) { + d->widget.data()->resize(size().toSize()); + } +- + } + + } +diff --git a/powerdevil/daemon/backends/upower/xrandrx11helper.h b/powerdevil/daemon/backends/upower/xrandrx11helper.h +index 184f582..7c4a154 100644 +--- a/powerdevil/daemon/backends/upower/xrandrx11helper.h ++++ b/powerdevil/daemon/backends/upower/xrandrx11helper.h +@@ -42,7 +42,6 @@ class XRandRX11Helper : public QWidget + int m_versionMajor; + int m_versionMinor; + +- bool m_debugMode; + Window m_window; + }; + diff --git a/SOURCES/kde-workspace-4.11.7-weather-fix-bbcukmet-clear-sky.patch b/SOURCES/kde-workspace-4.11.7-weather-fix-bbcukmet-clear-sky.patch new file mode 100644 index 0000000..99c1708 --- /dev/null +++ b/SOURCES/kde-workspace-4.11.7-weather-fix-bbcukmet-clear-sky.patch @@ -0,0 +1,12 @@ +diff -ur kde-workspace-4.11.7-weather-fix-bbcukmet-temp/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp kde-workspace-4.11.7-weather-fix-bbcukmet-clear-sky/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp +--- kde-workspace-4.11.7-weather-fix-bbcukmet-temp/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp 2014-03-16 00:53:22.000000000 +0100 ++++ kde-workspace-4.11.7-weather-fix-bbcukmet-clear-sky/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp 2014-03-24 02:27:37.000000000 +0100 +@@ -75,7 +75,7 @@ + dayList["sunny"] = ClearDay; + //dayList["sunny night"] = ClearNight; + dayList["clear"] = ClearDay; +- dayList["clar sky"] = ClearDay; ++ dayList["clear sky"] = ClearDay; + dayList["sunny intervals"] = PartlyCloudyDay; + //dayList["sunny intervals night"] = ClearNight; + dayList["partly cloudy"] = PartlyCloudyDay; diff --git a/SOURCES/kde-workspace-4.11.7-weather-fix-bbcukmet-crash-kde#332392.patch b/SOURCES/kde-workspace-4.11.7-weather-fix-bbcukmet-crash-kde#332392.patch new file mode 100644 index 0000000..a07421d --- /dev/null +++ b/SOURCES/kde-workspace-4.11.7-weather-fix-bbcukmet-crash-kde#332392.patch @@ -0,0 +1,157 @@ +diff -ur kde-workspace-4.11.7-weather-fix-bbcukmet-clear-sky/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp kde-workspace-4.11.7-weather-fix-bbcukmet-crash-kde#332392/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp +--- kde-workspace-4.11.7-weather-fix-bbcukmet-clear-sky/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp 2014-03-24 02:27:37.000000000 +0100 ++++ kde-workspace-4.11.7-weather-fix-bbcukmet-crash-kde#332392/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp 2014-03-25 16:00:40.000000000 +0100 +@@ -23,6 +23,13 @@ + + #include + #include ++#include ++ ++WeatherData::WeatherData() ++ : obsTime("N/A"), iconPeriodHour(12), iconPeriodMinute(0), ++ longitude(0.), latitude(0.), condition("N/A") ++{ ++} + + // ctor, dtor + UKMETIon::UKMETIon(QObject *parent, const QVariantList &args) +@@ -553,16 +560,31 @@ + + // Get the observation time and condition + int splitIndex = conditionString.lastIndexOf(':'); +- QStringRef conditionData = conditionString.midRef(splitIndex + 1); // Include ':' +- data.obsTime = conditionString.midRef(0, splitIndex).toString(); ++ if (splitIndex >= 0) { ++ QString conditionData = conditionString.mid(splitIndex + 1); // Skip ':' ++ data.obsTime = conditionString.left(splitIndex); ++ ++ if (data.obsTime.contains('-')) { ++ // Saturday - 13:00 CET ++ // Saturday - 12:00 GMT ++ m_dateFormat = KDateTime::fromString(data.obsTime.section('-', 1, 1).trimmed(), ++ "%H:%M %Z").toLocalZone().dateTime(); ++ if (m_dateFormat.isValid()) { ++ data.iconPeriodHour = m_dateFormat.toString("hh").toInt(); ++ data.iconPeriodMinute = m_dateFormat.toString("mm").toInt(); ++ } ++ } else { ++ m_dateFormat = QDateTime(); ++ } + +- // Saturday - 13:00 CET +- // Saturday - 12:00 GMT +- m_dateFormat = QDateTime::fromString(data.obsTime.split("-")[1].trimmed(), "hh:mm 'GMT'"); +- data.iconPeriodHour = m_dateFormat.toString("hh").toInt(); +- data.iconPeriodMinute = m_dateFormat.toString("mm").toInt(); ++ if (conditionData.contains(',')) { ++ data.condition = conditionData.section(',', 0, 0).trimmed(); + +- data.condition = conditionData.toString().split(',')[0].trimmed(); ++ if (data.condition == "null") { ++ data.condition = "N/A"; ++ } ++ } ++ } + + } else if (xml.name() == "link") { + m_place[source].forecastHTMLUrl = xml.readElementText(); +@@ -705,12 +727,12 @@ + + // Sometimes only one of min or max are reported + if (high.indexIn(line.split(',')[1]) == -1) +- forecast->tempHigh = 0; ++ forecast->tempHigh = UNKNOWN_TEMPERATURE; + else + forecast->tempHigh = high.cap(1).toInt(); + + if (low.indexIn(line.split(',')[1]) == -1) +- forecast->tempLow = 0; ++ forecast->tempLow = UNKNOWN_TEMPERATURE; + else + forecast->tempLow = low.cap(1).toInt(); + +@@ -777,16 +799,21 @@ + + const double lati = periodLatitude(source); + const double longi = periodLongitude(source); +- const Plasma::DataEngine::Data timeData = m_timeEngine->query( +- QString("Local|Solar|Latitude=%1|Longitude=%2|DateTime=%3") +- .arg(lati).arg(longi).arg(m_dateFormat.toString(Qt::ISODate))); +- +- // Tell applet which icon to use for conditions and provide mapping for condition type to the icons to display +- if (timeData["Corrected Elevation"].toDouble() >= 0.0) { +- //kDebug() << "Using daytime icons\n"; +- data.insert("Condition Icon", getWeatherIcon(dayIcons(), condition(source))); ++ ++ if (m_dateFormat.isValid()) { ++ const Plasma::DataEngine::Data timeData = m_timeEngine->query( ++ QString("Local|Solar|Latitude=%1|Longitude=%2|DateTime=%3") ++ .arg(lati).arg(longi).arg(m_dateFormat.toString(Qt::ISODate))); ++ ++ // Tell applet which icon to use for conditions and provide mapping for condition type to the icons to display ++ if (timeData["Corrected Elevation"].toDouble() >= 0.0) { ++ //kDebug() << "Using daytime icons\n"; ++ data.insert("Condition Icon", getWeatherIcon(dayIcons(), condition(source))); ++ } else { ++ data.insert("Condition Icon", getWeatherIcon(nightIcons(), condition(source))); ++ } + } else { +- data.insert("Condition Icon", getWeatherIcon(nightIcons(), condition(source))); ++ data.insert("Condition Icon", getWeatherIcon(dayIcons(), condition(source))); + } + + data.insert("Latitude", lati); +@@ -969,12 +996,22 @@ + m_weatherData[source].forecasts[i]->period.replace("Friday", i18nc("Short for Friday", "Fri")); + } + ++ int tempHigh = m_weatherData[source].forecasts[i]->tempHigh; ++ QString tempHighStr = (tempHigh == UNKNOWN_TEMPERATURE) ++ ? QString::fromLatin1("N/A") ++ : QString::number(tempHigh); ++ ++ int tempLow = m_weatherData[source].forecasts[i]->tempLow; ++ QString tempLowStr = (tempLow == UNKNOWN_TEMPERATURE) ++ ? QString::fromLatin1("N/A") ++ : QString::number(tempLow); ++ + forecastData.append(QString("%1|%2|%3|%4|%5|%6") \ + .arg(m_weatherData[source].forecasts[i]->period) \ + .arg(m_weatherData[source].forecasts[i]->iconName) \ + .arg(m_weatherData[source].forecasts[i]->summary) \ +- .arg(m_weatherData[source].forecasts[i]->tempHigh) \ +- .arg(m_weatherData[source].forecasts[i]->tempLow) \ ++ .arg(tempHighStr) \ ++ .arg(tempLowStr) \ + .arg("N/U")); + //.arg(m_weatherData[source].forecasts[i]->windSpeed) + //arg(m_weatherData[source].forecasts[i]->windDirection)); +diff -ur kde-workspace-4.11.7-weather-fix-bbcukmet-clear-sky/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.h kde-workspace-4.11.7-weather-fix-bbcukmet-crash-kde#332392/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.h +--- kde-workspace-4.11.7-weather-fix-bbcukmet-clear-sky/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.h 2014-02-28 00:09:20.000000000 +0100 ++++ kde-workspace-4.11.7-weather-fix-bbcukmet-crash-kde#332392/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.h 2014-03-24 22:34:59.000000000 +0100 +@@ -24,6 +24,7 @@ + + #include + #include ++#include + + #include "../ion.h" + #include "../dataengineconsumer.h" +@@ -39,6 +40,8 @@ + { + + public: ++ WeatherData(); ++ + QString place; + QString stationName; + // Current observation information. +@@ -171,6 +174,8 @@ + + QDateTime m_dateFormat; + QStringList m_sourcesToReset; ++ ++ static const int UNKNOWN_TEMPERATURE = INT_MIN; + }; + + K_EXPORT_PLASMA_DATAENGINE(bbcukmet, UKMETIon) diff --git a/SOURCES/kde-workspace-4.11.7-weather-fix-bbcukmet-temp.patch b/SOURCES/kde-workspace-4.11.7-weather-fix-bbcukmet-temp.patch new file mode 100644 index 0000000..147cccb --- /dev/null +++ b/SOURCES/kde-workspace-4.11.7-weather-fix-bbcukmet-temp.patch @@ -0,0 +1,41 @@ +diff -ur kde-workspace-4.11.7-weather-fix-bbcukmet/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp kde-workspace-4.11.7-weather-fix-bbcukmet-temp/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp +--- kde-workspace-4.11.7-weather-fix-bbcukmet/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp 2014-03-16 00:49:44.000000000 +0100 ++++ kde-workspace-4.11.7-weather-fix-bbcukmet-temp/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp 2014-03-16 00:53:22.000000000 +0100 +@@ -690,8 +690,8 @@ + QString line; + QString period; + QString summary; +- QRegExp high("-?\\d+.C"); +- QRegExp low("-?\\d+.C"); ++ QRegExp high("Maximum Temperature: (-?\\d+).C", Qt::CaseInsensitive); ++ QRegExp low("Minimum Temperature: (-?\\d+).C", Qt::CaseInsensitive); + while (!xml.atEnd()) { + xml.readNext(); + if (xml.name() == "title") { +@@ -702,15 +702,22 @@ + + period = line.split(',')[0].split(':')[0]; + summary = line.split(',')[0].split(':')[1].trimmed(); +- high.indexIn(line.split(',')[1].split(':')[1]); +- low.indexIn(line.split(',')[1].split(':')[2]); ++ ++ // Sometimes only one of min or max are reported ++ if (high.indexIn(line.split(',')[1]) == -1) ++ forecast->tempHigh = 0; ++ else ++ forecast->tempHigh = high.cap(1).toInt(); ++ ++ if (low.indexIn(line.split(',')[1]) == -1) ++ forecast->tempLow = 0; ++ else ++ forecast->tempLow = low.cap(1).toInt(); + + forecast->period = period; + forecast->iconName = getWeatherIcon(dayIcons(), summary.toLower()); + forecast->summary = i18nc("weather forecast", summary.toUtf8()); + kDebug() << "i18n summary string: " << qPrintable(forecast->summary); +- forecast->tempHigh = high.cap(0).toInt(); +- forecast->tempLow = low.cap(0).toInt(); + m_weatherData[source].forecasts.append(forecast); + forecast = new WeatherData::ForecastInfo; + } diff --git a/SOURCES/kde-workspace-4.11.7-weather-fix-bbcukmet.patch b/SOURCES/kde-workspace-4.11.7-weather-fix-bbcukmet.patch new file mode 100644 index 0000000..545ac93 --- /dev/null +++ b/SOURCES/kde-workspace-4.11.7-weather-fix-bbcukmet.patch @@ -0,0 +1,209 @@ +From 55644fae34ab49834dd52c834c211e765d41f8ab Mon Sep 17 00:00:00 2001 +From: Raphael Geissert +Date: Sat, 15 Feb 2014 15:20:26 +0100 +Subject: [PATCH 1/3] Update to BBC's new json-based search and modified xml + +BUG:330773 +--- + .../weather/ions/bbcukmet/ion_bbcukmet.cpp | 93 ++++++++++++-------- + 1 file changed, 54 insertions(+), 39 deletions(-) + +diff --git a/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp b/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp +index 746a734..c656e40 100644 +--- a/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp ++++ b/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp +@@ -80,6 +80,7 @@ QMap UKMETIon::setupDayIconMappings(void) + //dayList["sunny intervals night"] = ClearNight; + dayList["partly cloudy"] = PartlyCloudyDay; + dayList["cloudy"] = Overcast; ++ dayList["light cloud"] = Overcast; + dayList["white cloud"] = Overcast; + dayList["grey cloud"] = Overcast; + //dayList["low level cloud"] = NotAvailable; +@@ -131,6 +132,7 @@ QMap UKMETIon::setupNightIconMappings(voi + nightList["sunny intervals"] = PartlyCloudyDay; // it's not really sunny + nightList["sunny"] = ClearDay; + nightList["cloudy"] = Overcast; ++ nightList["light cloud"] = Overcast; + nightList["white cloud"] = Overcast; + nightList["grey cloud"] = Overcast; + nightList["partly cloudy"] = PartlyCloudyNight; +@@ -252,7 +254,8 @@ void UKMETIon::getXMLData(const QString& source) + void UKMETIon::findPlace(const QString& place, const QString& source) + { + KUrl url; +- url = "http://news.bbc.co.uk/weather/util/search/SearchResultsNode.xhtml?&search=" + place + "®ion=world&startIndex=0&count=500"; ++ /* There's a page= parameter, results are limited to 10 by page */ ++ url = "http://www.bbc.com/locator/default/en-GB/search.json?search="+place+"&filter=international&postcode_unit=false&postcode_district=true"; + + m_job = KIO::get(url.url(), KIO::Reload, KIO::HideProgressInfo); + m_job->addMetaData("cookies", "none"); // Disable displaying cookies +@@ -281,7 +284,7 @@ void UKMETIon::getFiveDayForecast(const QString& source) + + int splitIDPos = xmlPath.lastIndexOf('/'); + QString stationID = xmlPath.midRef(splitIDPos + 1).toString(); +- m_place[source].XMLforecastURL = "http://newsrss.bbc.co.uk/weather/forecast/" + stationID + "/Next3DaysRSS.xml" + xmlMap.query(); ++ m_place[source].XMLforecastURL = "http://open.live.bbc.co.uk/weather/feeds/en/" + stationID + "/3dayforecast.rss" + xmlMap.query(); + KUrl url(m_place[source].XMLforecastURL); + + m_job = KIO::get(url.url(), KIO::Reload, KIO::HideProgressInfo); +@@ -303,47 +306,43 @@ void UKMETIon::readSearchHTMLData(const QString& source, const QByteArray& html) + QStringList tokens; + QString url; + QString tmp; +- int flag = 0; + int counter = 2; + +- // "

Vitoria, Brazil

" +- QRegExp grabURL("/[a-z]+/[a-z]+/([0-9]+)(\\?[^\"]+)?"); +- QRegExp grabPlace(">([^<]*[a-z()])"); // FIXME: It would be better to strip away the extra '>' ++#ifdef __GNUC__ ++#warning FIXME: use a json parser instead of regexes ++#endif ++ ++ QRegExp grabURL("\"id\":\\s*\"([0-9]+)\""); ++ QRegExp grabPlace("\"fullName\":\\s*\"([^\"]+)\""); + + while (!stream.atEnd()) { + line = stream.readLine(); +- if (line.contains("

") > 0) { +- flag = 1; +- } + +- if (line.contains("There are no forecasts matching") > 0) { ++ if (line.contains("Sorry, no results found for") > 0) { + break; + } + +- if (flag) { ++ if (line.contains("\"results\"") > 0) { + + if (grabURL.indexIn(line.trimmed()) > 0) { +- url = "http://newsrss.bbc.co.uk/weather/forecast/" + grabURL.cap(1) + "/ObservationsRSS.xml"; +- if (grabURL.captureCount() > 1) { +- url += grabURL.cap(2); +- } +- grabPlace.indexIn(line.trimmed()); +- tmp = QString("bbcukmet|").append(grabPlace.cap(1)); + +- // Duplicate places can exist +- if (m_locations.contains(tmp)) { +- tmp = QString("bbcukmet|").append(QString("%1 (#%2)").arg(grabPlace.cap(1)).arg(counter)); +- counter++; +- } ++ for (int captureIndex = 1; captureIndex <= grabURL.captureCount(); captureIndex++) { + +- m_place[tmp].XMLurl = url; +- m_place[tmp].place = grabPlace.cap(1); +- m_locations.append(tmp); +- } +- } ++ url = "http://open.live.bbc.co.uk/weather/feeds/en/" + grabURL.cap(captureIndex) + "/observations.rss"; ++ grabPlace.indexIn(line.trimmed()); ++ tmp = QString("bbcukmet|").append(grabPlace.cap(captureIndex)); ++ ++ // Duplicate places can exist ++ if (m_locations.contains(tmp)) { ++ tmp = QString("bbcukmet|").append(QString("%1 (#%2)").arg(grabPlace.cap(captureIndex)).arg(counter)); ++ counter++; ++ } + +- if (line.contains("

") > 0) { +- flag = 0; ++ m_place[tmp].XMLurl = url; ++ m_place[tmp].place = grabPlace.cap(captureIndex); ++ m_locations.append(tmp); ++ } ++ } + } + } + +@@ -557,12 +556,13 @@ void UKMETIon::parseWeatherObservation(const QString& source, WeatherData& data, + QStringRef conditionData = conditionString.midRef(splitIndex + 1); // Include ':' + data.obsTime = conditionString.midRef(0, splitIndex).toString(); + +- // Friday at 0200 GMT +- m_dateFormat = QDateTime::fromString(data.obsTime.split("at")[1].trimmed(), "hhmm 'GMT'"); ++ // Saturday - 13:00 CET ++ // Saturday - 12:00 GMT ++ m_dateFormat = QDateTime::fromString(data.obsTime.split("-")[1].trimmed(), "hh:mm 'GMT'"); + data.iconPeriodHour = m_dateFormat.toString("hh").toInt(); + data.iconPeriodMinute = m_dateFormat.toString("mm").toInt(); + +- data.condition = conditionData.toString().split('.')[0].trimmed(); ++ data.condition = conditionData.toString().split(',')[0].trimmed(); + + } else if (xml.name() == "link") { + m_place[source].forecastHTMLUrl = xml.readElementText(); +@@ -575,21 +575,32 @@ void UKMETIon::parseWeatherObservation(const QString& source, WeatherData& data, + #endif + + data.temperature_C = observeData[1].split(QChar(176))[0].trimmed(); +- +- // Temperature might be not available +- if (data.temperature_C.contains("N/A")) { ++ if (data.temperature_C.contains("N/A") || data.temperature_C.contains("null")) { + data.temperature_C = i18n("N/A"); + } + + data.windDirection = observeData[2].split(',')[0].trimmed(); ++ if (data.windDirection.contains("null")) { ++ data.windDirection = ""; ++ } ++ + data.windSpeed_miles = observeData[3].split(',')[0].split(' ')[1].remove("mph"); ++ if (data.windSpeed_miles.contains("null")) { ++ data.windSpeed_miles = "N/A"; ++ } + + data.humidity = observeData[4].split(',')[0].split(' ')[1]; + if (data.humidity.endsWith('%')) { + data.humidity.chop(1); + } ++ if (data.humidity.contains("null")) { ++ data.humidity = "N/A"; ++ } + + data.pressure = observeData[5].split(',')[0].split(' ')[1].split("mb")[0]; ++ if (data.pressure.contains("null")) { ++ data.pressure = "N/A"; ++ } + data.pressureTendency = observeData[5].split(',')[1].trimmed(); + + data.visibilityStr = observeData[6].trimmed(); +@@ -600,6 +611,10 @@ void UKMETIon::parseWeatherObservation(const QString& source, WeatherData& data, + } else if (xml.name() == "long") { + const QString ordinate = xml.readElementText(); + data.longitude = ordinate.toDouble(); ++ } else if (xml.name() == "georss:point") { ++ const QString ordinates = xml.readElementText(); ++ data.latitude = ordinates.split(' ')[0].toDouble(); ++ data.longitude = ordinates.split(' ')[1].toDouble(); + } else { + parseUnknownElement(xml); + } +@@ -675,8 +690,8 @@ void UKMETIon::parseFiveDayForecast(const QString& source, QXmlStreamReader& xml + QString line; + QString period; + QString summary; +- QRegExp high("-?\\d+"); +- QRegExp low("-?\\d+"); ++ QRegExp high("-?\\d+.C"); ++ QRegExp low("-?\\d+.C"); + while (!xml.atEnd()) { + xml.readNext(); + if (xml.name() == "title") { +@@ -687,8 +702,8 @@ void UKMETIon::parseFiveDayForecast(const QString& source, QXmlStreamReader& xml + + period = line.split(',')[0].split(':')[0]; + summary = line.split(',')[0].split(':')[1].trimmed(); +- high.indexIn(line.split(',')[1]); +- low.indexIn(line.split(',')[2]); ++ high.indexIn(line.split(',')[1].split(':')[1]); ++ low.indexIn(line.split(',')[1].split(':')[2]); + + forecast->period = period; + forecast->iconName = getWeatherIcon(dayIcons(), summary.toLower()); +-- +1.7.10 + diff --git a/SOURCES/kde-workspace-4.7.80-classicmenu-logout.patch b/SOURCES/kde-workspace-4.7.80-classicmenu-logout.patch new file mode 100644 index 0000000..120e695 --- /dev/null +++ b/SOURCES/kde-workspace-4.7.80-classicmenu-logout.patch @@ -0,0 +1,65 @@ +diff -up kde-workspace-4.7.80/plasma/desktop/applets/kickoff/core/itemhandlers.cpp.classicmenu-logout kde-workspace-4.7.80/plasma/desktop/applets/kickoff/core/itemhandlers.cpp +--- kde-workspace-4.7.80/plasma/desktop/applets/kickoff/core/itemhandlers.cpp.classicmenu-logout 2011-10-11 16:42:11.000000000 +0200 ++++ kde-workspace-4.7.80/plasma/desktop/applets/kickoff/core/itemhandlers.cpp 2011-11-21 14:56:36.108858679 +0100 +@@ -105,7 +105,8 @@ bool LeaveItemHandler::openUrl(const KUr + QTimer::singleShot(0, this, SLOT(switchUser())); + return true; + } else if (m_logoutAction == "logout" || m_logoutAction == "logoutonly" || +- m_logoutAction == "restart" || m_logoutAction == "shutdown") { ++ m_logoutAction == "restart" || m_logoutAction == "shutdown" || ++ m_logoutAction == "leave") { + // decouple dbus call, otherwise we'll run into a dead-lock + QTimer::singleShot(0, this, SLOT(logout())); + return true; +@@ -158,6 +159,10 @@ void LeaveItemHandler::logout() + type = KWorkSpace::ShutdownTypeReboot; + } else if (m_logoutAction == "shutdown") { + type = KWorkSpace::ShutdownTypeHalt; ++ } else if (m_logoutAction == "leave") { ++ // This one brings up the dialog, for use in the classic menu. ++ confirm = KWorkSpace::ShutdownConfirmYes; ++ type = KWorkSpace::ShutdownTypeDefault; + } + + KWorkSpace::requestShutDown(confirm, type); +diff -up kde-workspace-4.7.80/plasma/desktop/applets/kickoff/simpleapplet/simpleapplet.cpp.classicmenu-logout kde-workspace-4.7.80/plasma/desktop/applets/kickoff/simpleapplet/simpleapplet.cpp +--- kde-workspace-4.7.80/plasma/desktop/applets/kickoff/simpleapplet/simpleapplet.cpp.classicmenu-logout 2011-11-04 15:33:12.000000000 +0100 ++++ kde-workspace-4.7.80/plasma/desktop/applets/kickoff/simpleapplet/simpleapplet.cpp 2011-11-21 14:48:59.281609964 +0100 +@@ -209,6 +209,7 @@ public: + case Shutdown: return i18n("Shut down"); + case Logout: return i18n("Log out"); + case Leave: return i18n("Leave"); ++ case LeaveDialog: return i18n("Leave..."); + } + return QString(); + } +@@ -234,6 +235,7 @@ public: + case Shutdown: return "system-shutdown"; + case Logout: return "system-log-out"; + case Leave: return "system-shutdown"; ++ case LeaveDialog: return "system-shutdown"; + } + return QString(); + } +@@ -741,6 +743,8 @@ void MenuLauncherApplet::showMenu(bool p + menuview->addAction(KIcon(d->viewIcon(LockScreen)), d->viewText(LockScreen))->setData(KUrl("leave:/lock")); + } else if(vtname == "Logout") { + menuview->addAction(KIcon(d->viewIcon(Logout)), d->viewText(Logout))->setData(KUrl("leave:/logout")); ++ } else if(vtname == "LeaveDialog") { ++ menuview->addAction(KIcon(d->viewIcon(LeaveDialog)), d->viewText(LeaveDialog))->setData(KUrl("leave:/leave")); + } else if(vtname == "Leave") { + Kickoff::LeaveModel *leavemodel = new Kickoff::LeaveModel(menuview); + leavemodel->updateModel(); +diff -up kde-workspace-4.7.80/plasma/desktop/applets/kickoff/simpleapplet/simpleapplet.h.classicmenu-logout kde-workspace-4.7.80/plasma/desktop/applets/kickoff/simpleapplet/simpleapplet.h +--- kde-workspace-4.7.80/plasma/desktop/applets/kickoff/simpleapplet/simpleapplet.h.classicmenu-logout 2011-07-27 20:35:42.000000000 +0200 ++++ kde-workspace-4.7.80/plasma/desktop/applets/kickoff/simpleapplet/simpleapplet.h 2011-11-21 14:48:59.282609967 +0100 +@@ -59,7 +59,8 @@ public: + Restart, ///< Restart Action + Shutdown, ///< Shutdown Action + Logout, ///< Logout Action +- Leave ///< Leave Menu ++ Leave, ///< Leave Menu ++ LeaveDialog ///< Leave Dialog Action + }; + + /** diff --git a/SOURCES/kde-workspace-4.7.80-no_HAL.patch b/SOURCES/kde-workspace-4.7.80-no_HAL.patch new file mode 100644 index 0000000..2149aa2 --- /dev/null +++ b/SOURCES/kde-workspace-4.7.80-no_HAL.patch @@ -0,0 +1,24 @@ +diff -up kde-workspace-4.7.80/powerdevil/daemon/BackendConfig.cmake.no_HAL kde-workspace-4.7.80/powerdevil/daemon/BackendConfig.cmake +--- kde-workspace-4.7.80/powerdevil/daemon/BackendConfig.cmake.no_HAL 2011-10-20 22:52:49.000000000 +0200 ++++ kde-workspace-4.7.80/powerdevil/daemon/BackendConfig.cmake 2011-11-21 15:59:36.707272566 +0100 +@@ -39,18 +39,7 @@ install(TARGETS backlighthelper DESTINAT + kde4_install_auth_helper_files(backlighthelper org.kde.powerdevil.backlighthelper root) + kde4_install_auth_actions(org.kde.powerdevil.backlighthelper ${CMAKE_CURRENT_SOURCE_DIR}/backends/upower/backlight_helper_actions.actions) + +-########################## HAL Backend ##################################### +- +-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/backends/hal) +- +-set(powerdevilhalbackend_SRCS +- backends/hal/halsuspendjob.cpp +- backends/hal/powerdevilhalbackend.cpp +-) +- +-set(powerdevilhalbackend_LIBS ${KDE4_SOLID_LIBS}) +- + ########################## Daemon variables ################################ + +-set(POWERDEVIL_BACKEND_SRCS ${powerdevilupowerbackend_SRCS} ${powerdevilhalbackend_SRCS}) +-set(POWERDEVIL_BACKEND_LIBS ${powerdevilupowerbackend_LIBS} ${powerdevilhalbackend_LIBS}) ++set(POWERDEVIL_BACKEND_SRCS ${powerdevilupowerbackend_SRCS}) ++set(POWERDEVIL_BACKEND_LIBS ${powerdevilupowerbackend_LIBS}) diff --git a/SOURCES/kde-workspace-4.7.95-kdm_xauth.patch b/SOURCES/kde-workspace-4.7.95-kdm_xauth.patch new file mode 100644 index 0000000..5c7a388 --- /dev/null +++ b/SOURCES/kde-workspace-4.7.95-kdm_xauth.patch @@ -0,0 +1,16 @@ +diff -up kde-workspace-4.7.95/kdm/backend/auth.c.selinux_wtf kde-workspace-4.7.95/kdm/backend/auth.c +--- kde-workspace-4.7.95/kdm/backend/auth.c.selinux_wtf 2011-12-20 18:40:36.000000000 -0600 ++++ kde-workspace-4.7.95/kdm/backend/auth.c 2012-01-03 14:33:38.931306044 -0600 +@@ -1292,6 +1292,12 @@ removeUserAuthorization(struct display * + + if (!(auths = d->authorizations)) + return; ++ ++ /* given that the code below doesn't handle the forceUserAuthDir case, */ ++ /* let's just bail out for now, see http://bugs.kde.org/242065 */ ++ if ( d->forceUserAuthDir ) ++ return; ++ + debug("removeUserAuthorization\n"); + startUserAuth(name, new_name, &old, &new); + if (new) { diff --git a/SOURCES/kde-workspace-4.8.0-bug796969.patch b/SOURCES/kde-workspace-4.8.0-bug796969.patch new file mode 100644 index 0000000..16e2938 --- /dev/null +++ b/SOURCES/kde-workspace-4.8.0-bug796969.patch @@ -0,0 +1,37 @@ +per https://bugzilla.redhat.com/show_bug.cgi?id=796969#c23 +The process that executes kdm/backend/session.c:manageSession() is the leader +process of the logind session. + +manageSession() calls: + + blockTerm(); + clientExited(); + unblockTerm(); + +where clientExited() ends the PAM session. +With the current systemd-logind, ending the PAM session will cause the leader +process to be delivered SIGHUP and SIGTERM. The process will die and the +remainder of manageSession() will not be executed. + +Interestingly, at the end of the function there's a call to sessionExit(), +which calls clientExited() again. + +Removing the three lines quoted above makes reboot from KDE work again. I +haven't noticed any bad effects. + +diff -up kde-workspace-4.8.0/kdm/backend/session.c.bz796969 kde-workspace-4.8.0/kdm/backend/session.c +--- kde-workspace-4.8.0/kdm/backend/session.c.bz796969 2012-01-18 14:08:40.000000000 -0600 ++++ kde-workspace-4.8.0/kdm/backend/session.c 2012-02-28 07:17:16.270219932 -0600 +@@ -662,9 +662,9 @@ manageSession(void) + sessionExit(EX_AL_RESERVER_DPY); + } + +- blockTerm(); +- clientExited(); +- unblockTerm(); ++ /* blockTerm(); */ ++ /* clientExited(); */ ++ /* unblockTerm(); */ + + gSet(&mstrtalk); + gSendInt(D_UnUser); diff --git a/SOURCES/kde-workspace-4.8.2-bz#732830-login.patch b/SOURCES/kde-workspace-4.8.2-bz#732830-login.patch new file mode 100644 index 0000000..c930a01 --- /dev/null +++ b/SOURCES/kde-workspace-4.8.2-bz#732830-login.patch @@ -0,0 +1,497 @@ +diff -up kde-workspace-4.8.2/kdm/CMakeLists.txt.bz#732830-login kde-workspace-4.8.2/kdm/CMakeLists.txt +--- kde-workspace-4.8.2/kdm/CMakeLists.txt.bz#732830-login 2012-03-30 00:02:31.000000000 +0200 ++++ kde-workspace-4.8.2/kdm/CMakeLists.txt 2012-03-30 13:38:35.094493727 +0200 +@@ -33,6 +33,11 @@ set(backgroundlib_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/kcm/background/bgsettings.cpp + ) + ++set(kdmminmaxuidlib_SRCS ++ ${CMAKE_CURRENT_SOURCE_DIR}/kdm-minmaxuid.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/kdm-minmaxuid.h ++) ++ + # after confci is defined + add_subdirectory(backend) + add_subdirectory(kfrontend) +diff -up kde-workspace-4.8.2/kdm/config.def.bz#732830-login kde-workspace-4.8.2/kdm/config.def +--- kde-workspace-4.8.2/kdm/config.def.bz#732830-login 2012-03-30 00:02:31.000000000 +0200 ++++ kde-workspace-4.8.2/kdm/config.def 2012-03-30 13:38:35.112493501 +0200 +@@ -2288,9 +2288,13 @@ Instance: #*/ + Update: upd_minshowuid + Comment: + Special case of HiddenUsers: users with a non-zero UID less than this number +- will not be shown as well. ++ will not be shown as well. Setting this to -1 means that the limit should be ++ determined in a platform-specific way (by reading /etc/login.defs or using a ++ compiled-in default). + Description: +- See . ++ See . Setting this to -1 means that the limit ++ should be determined in a platform-specific way (by reading ++ /etc/login.defs or using a compiled-in default). + + Key: MaxShowUID + Type: int +@@ -2301,9 +2305,11 @@ Instance: #*/ + Update: upd_maxshowuid + Comment: + Complement to MinShowUID: users with a UID greater than this number will +- not be shown as well. ++ not be shown as well. Unlike MinShowUID, the special value -1 is not ++ supported. + Description: +- See . ++ See . Unlike , the ++ special value -1 is not supported. + + Key: SortUsers + Type: bool +diff -up kde-workspace-4.8.2/kdm/kcm/CMakeLists.txt.bz#732830-login kde-workspace-4.8.2/kdm/kcm/CMakeLists.txt +--- kde-workspace-4.8.2/kdm/kcm/CMakeLists.txt.bz#732830-login 2012-03-30 00:02:31.000000000 +0200 ++++ kde-workspace-4.8.2/kdm/kcm/CMakeLists.txt 2012-03-30 13:38:35.114493477 +0200 +@@ -15,6 +15,7 @@ kde4_add_ui_files(kcmbackgroundlib_SRCS + background/bgadvanced_ui.ui) + + set(kcm_kdm_PART_SRCS ${kcmbackgroundlib_SRCS} ${backgroundlib_SRCS} ++ ${kdmminmaxuidlib_SRCS} + background.cpp + kdm-gen.cpp + kdm-dlg.cpp +diff -up kde-workspace-4.8.2/kdm/kcm/kdm-users.cpp.bz#732830-login kde-workspace-4.8.2/kdm/kcm/kdm-users.cpp +--- kde-workspace-4.8.2/kdm/kcm/kdm-users.cpp.bz#732830-login 2012-03-30 00:02:31.000000000 +0200 ++++ kde-workspace-4.8.2/kdm/kcm/kdm-users.cpp 2012-03-30 13:38:35.123493365 +0200 +@@ -58,6 +58,9 @@ + #include + #include + ++#include "../kdm-minmaxuid.h" ++ ++ + extern KConfig *config; + + extern int handleActionReply(QWidget *parent, const KAuth::ActionReply &reply); +@@ -80,28 +83,11 @@ static int executeFaceAction(QWidget *pa + KDMUsersWidget::KDMUsersWidget(QWidget *parent) + : QWidget(parent) + { +-#ifdef __linux__ +- struct stat st; +- if (!stat("/etc/debian_version", &st)) { /* debian */ +- defminuid = "1000"; +- defmaxuid = "29999"; +- } else if (!stat("/usr/portage", &st)) { /* gentoo */ +- defminuid = "1000"; +- defmaxuid = "65000"; +- } else if (!stat("/etc/mandrake-release", &st)) { /* mandrake - check before redhat! */ +- defminuid = "500"; +- defmaxuid = "65000"; +- } else if (!stat("/etc/redhat-release", &st)) { /* redhat */ +- defminuid = "100"; +- defmaxuid = "65000"; +- } else /* if (!stat("/etc/SuSE-release", &st)) */ { /* suse */ +- defminuid = "500"; +- defmaxuid = "65000"; +- } +-#else +- defminuid = "1000"; +- defmaxuid = "65000"; +-#endif ++ int minUid, maxUid; ++ ++ getDefaultMinMaxUids(&minUid, &maxUid); ++ defminuid = QString::number(minUid); ++ defmaxuid = QString::number(maxUid); + + m_userPixDir = config->group("X-*-Greeter").readEntry("FaceDir", + QString(KStandardDirs::installPath("data") + "kdm/faces" + '/')); +diff -up kde-workspace-4.8.2/kdm/kcm/main.cpp.bz#732830-login kde-workspace-4.8.2/kdm/kcm/main.cpp +--- kde-workspace-4.8.2/kdm/kcm/main.cpp.bz#732830-login 2012-03-30 00:02:31.000000000 +0200 ++++ kde-workspace-4.8.2/kdm/kcm/main.cpp 2012-03-30 13:38:35.135493214 +0200 +@@ -59,6 +59,7 @@ + #include + #include + ++#include "../kdm-minmaxuid.h" + + K_PLUGIN_FACTORY(KDMFactory, registerPlugin();) + K_EXPORT_PLUGIN(KDMFactory("kdmconfig")) +@@ -393,13 +394,14 @@ void KDModule::propagateUsers() + { + groupmap.clear(); + emit clearUsers(); ++ int realminuid = interpretMinUid(minshowuid); + QMap lusers; + QMap >::const_iterator it; + QStringList::ConstIterator jt; + QMap::Iterator gmapi; + for (it = usermap.constBegin(); it != usermap.constEnd(); ++it) { + int uid = it.value().first; +- if (!uid || (uid >= minshowuid && uid <= maxshowuid)) { ++ if (!uid || (uid >= realminuid && uid <= maxshowuid)) { + lusers[it.key()] = uid; + for (jt = it.value().second.begin(); jt != it.value().second.end(); ++jt) + if ((gmapi = groupmap.find(*jt)) == groupmap.end()) { +@@ -415,6 +417,8 @@ void KDModule::propagateUsers() + + void KDModule::slotMinMaxUID(int min, int max) + { ++ int oldrealmin = interpretMinUid(minshowuid); ++ int newrealmin = interpretMinUid(min); + if (updateOK) { + QMap alusers, dlusers; + QMap >::const_iterator it; +@@ -424,8 +428,8 @@ void KDModule::slotMinMaxUID(int min, in + int uid = it.value().first; + if (!uid) + continue; +- if ((uid >= minshowuid && uid <= maxshowuid) && +- !(uid >= min && uid <= max)) { ++ if ((uid >= oldrealmin && uid <= maxshowuid) && ++ !(uid >= newrealmin && uid <= max)) { + dlusers[it.key()] = uid; + for (jt = it.value().second.begin(); + jt != it.value().second.end(); ++jt) { +@@ -435,8 +439,8 @@ void KDModule::slotMinMaxUID(int min, in + dlusers['@' + *jt] = -uid; + } + } +- } else if ((uid >= min && uid <= max) && +- !(uid >= minshowuid && uid <= maxshowuid)) { ++ } else if ((uid >= newrealmin && uid <= max) && ++ !(uid >= oldrealmin && uid <= maxshowuid)) { + alusers[it.key()] = uid; + for (jt = it.value().second.begin(); + jt != it.value().second.end(); ++jt) +diff -up kde-workspace-4.8.2/kdm/kdm-minmaxuid.c.bz#732830-login kde-workspace-4.8.2/kdm/kdm-minmaxuid.c +--- kde-workspace-4.8.2/kdm/kdm-minmaxuid.c.bz#732830-login 2012-03-30 13:38:35.137493189 +0200 ++++ kde-workspace-4.8.2/kdm/kdm-minmaxuid.c 2012-03-30 13:38:35.137493189 +0200 +@@ -0,0 +1,152 @@ ++/* ++ * Utilities for handling the UID range allocated for non-system user ++ */ ++ ++#include ++#include ++#ifdef __linux__ ++#include ++#include ++#include ++#include ++#include ++#include ++#endif ++ ++#include "kdm-minmaxuid.h" ++ ++static void internalMinMaxUids(int *minUid, int *maxUid, int staticValues) ++{ ++ struct stat st; ++ ++#ifdef __linux__ ++ if (!stat("/etc/debian_version", &st)) { /* debian */ ++ *minUid = 1000; ++ *maxUid = 29999; ++ } else if (!stat("/usr/portage", &st)) { /* gentoo */ ++ *minUid = 1000; ++ *maxUid = 65000; ++ } else if (!stat("/etc/mandrake-release", &st)) { /* mandrake - check before redhat! */ ++ *minUid = 500; ++ *maxUid = 65000; ++ } else if (!stat("/etc/redhat-release", &st)) { /* redhat */ ++ if (!staticValues && !stat("/etc/login.defs", &st)) ++ *minUid = -1; ++ else ++ *minUid = 100; ++ *maxUid = 65000; ++ } else /* if (!stat("/etc/SuSE-release", &st)) */ { /* suse */ ++ *minUid = 500; ++ *maxUid = 65000; ++ } ++#else ++ *minUid = 1000; ++ *maxUid = 65000; ++#endif ++} ++ ++void getDefaultMinMaxUids(int *minUid, int *maxUid) ++{ ++ internalMinMaxUids(minUid, maxUid, 0); ++} ++ ++#ifdef __linux__ ++static int getLoginDefsMinUid(void) ++{ ++ int res; ++ char *buf; ++ size_t buf_size; ++ ssize_t line_len; ++ regex_t re; ++ FILE *f; ++ ++ f = fopen("/etc/login.defs", "r"); ++ if (f == NULL) ++ return -1; ++ ++ /* No, this is not particularly nice, but "compatible" is more important ++ than "beautiful". */ ++ if (regcomp(&re, ++ "^[ \t]*" /* Initial whitespace */ ++ "([^ \t]+)" /* Variable name */ ++ "[ \t][ \t\"]*" /* Separator - yes, may have multiple "s */ ++ "(" ++ "([^\"]*)\".*" /* Value, case 1 - terminated by " */ ++ /* Value, case 2 - only drop trailing [[:space:]] */ ++ "|([^\"]*[^[:space:]])?[[:space:]]*" ++ ")$", REG_EXTENDED) != 0) ++ abort(); ++ ++ buf = NULL; ++ buf_size = 0; ++ res = -1; ++ while ((line_len = getline(&buf, &buf_size, f)) > 0) { ++ regmatch_t match[5]; ++ const char *name, *value; ++ ++ if (line_len > 0 && buf[line_len - 1] == '\n') ++ buf[line_len - 1] = '\0'; ++ ++ if (regexec(&re, buf, sizeof(match) / sizeof(*match), match, 0) != 0) ++ continue; ++ ++ assert(match[1].rm_so != -1); ++ name = buf + match[1].rm_so; ++ if (*name == '#') ++ continue; ++ /* The "separator" is at least one character long, so we can safely ++ overwrite it with '\0'. */ ++ buf[match[1].rm_eo] = '\0'; ++ ++ if (match[3].rm_so != -1) { ++ value = buf + match[3].rm_so; ++ buf[match[3].rm_eo] = '\0'; ++ } else if (match[4].rm_so != -1) { ++ value = buf + match[4].rm_so; ++ buf[match[4].rm_eo] = '\0'; ++ } else ++ value = ""; ++ ++ /* fprintf(stderr, "\tMatched: %s = %s!\n", name, value); */ ++ ++ if (strcmp(name, "UID_MIN") == 0) { ++ intmax_t imax; ++ char *p; ++ ++ errno = 0; ++ imax = strtoimax(value, &p, 10); ++ if (errno == 0 && *p == '\0' && p != value && (uid_t)imax == imax) ++ res = imax; ++ } ++ } ++ free(buf); ++ ++ regfree(&re); ++ fclose(f); ++ ++ return res; ++} ++#endif ++ ++int interpretMinUid(int minUid) ++{ ++ int res, dummy; ++ ++ if (minUid != -1) ++ return minUid; ++#ifdef __linux__ ++ res = getLoginDefsMinUid(); ++ if (res != -1) ++ return res; ++#endif ++ internalMinMaxUids(&res, &dummy, 1); ++ return res; ++} ++ ++#ifdef TESTING ++int main(void) ++{ ++ printf("interpretMinUid returns %d\n", interpretMinUid(-1)); ++ return 0; ++} ++#endif +diff -up kde-workspace-4.8.2/kdm/kdm-minmaxuid.h.bz#732830-login kde-workspace-4.8.2/kdm/kdm-minmaxuid.h +--- kde-workspace-4.8.2/kdm/kdm-minmaxuid.h.bz#732830-login 2012-03-30 13:38:35.148493053 +0200 ++++ kde-workspace-4.8.2/kdm/kdm-minmaxuid.h 2012-03-30 13:38:35.138493177 +0200 +@@ -0,0 +1,25 @@ ++/* ++ * Utilities for handling the UID range allocated for non-system user ++ */ ++ ++#ifndef KDM_MINMAXUID_H ++#define KDM_MINMAXUID_H ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/* Get platform-specific defaults for minShowUID and maxShowUID. ++ Never fails. */ ++void getDefaultMinMaxUids(int *minUid, int *maxUid); ++ ++/* Return the lower limit of user UIDs, based on supplied minShowUID value ++ (i.e. interpret the value -1). */ ++int interpretMinUid(int minUid); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++ ++#endif +diff -up kde-workspace-4.8.2/kdm/kfrontend/CMakeLists.txt.bz#732830-login kde-workspace-4.8.2/kdm/kfrontend/CMakeLists.txt +--- kde-workspace-4.8.2/kdm/kfrontend/CMakeLists.txt.bz#732830-login 2012-03-30 00:02:31.000000000 +0200 ++++ kde-workspace-4.8.2/kdm/kfrontend/CMakeLists.txt 2012-03-30 13:38:35.149493040 +0200 +@@ -52,6 +52,7 @@ set(kdm_greet_SRCS + utils.cpp + utils.h + ${kdmthemer_SRCS} ++ ${kdmminmaxuidlib_SRCS} + ) + + if (XDMCP) +@@ -93,7 +94,7 @@ kde4_add_executable(krootimage ${krootim + target_link_libraries(krootimage ${KDE4_KDEUI_LIBS} ${X11_X11_LIB} ${QIMAGEBLITZ_LIBRARIES}) + install(TARGETS krootimage DESTINATION ${LIBEXEC_INSTALL_DIR}) + +-set(genkdmconf_SRCS genkdmconf.c) ++set(genkdmconf_SRCS genkdmconf.c ${kdmminmaxuidlib_SRCS}) + macro_add_file_dependencies(genkdmconf.c ${confci}) + kde4_add_executable(genkdmconf NOGUI ${genkdmconf_SRCS}) + macro_add_compile_flags(genkdmconf -U_REENTRANT) +diff -up kde-workspace-4.8.2/kdm/kfrontend/genkdmconf.c.bz#732830-login kde-workspace-4.8.2/kdm/kfrontend/genkdmconf.c +--- kde-workspace-4.8.2/kdm/kfrontend/genkdmconf.c.bz#732830-login 2012-03-30 00:02:31.000000000 +0200 ++++ kde-workspace-4.8.2/kdm/kfrontend/genkdmconf.c 2012-03-30 13:49:49.760059248 +0200 +@@ -58,6 +58,8 @@ Foundation, Inc., 51 Franklin Street, Fi + # endif + #endif + ++#include "../kdm-minmaxuid.h" ++ + #define WANT_CONF_GEN + #include + +@@ -2008,7 +2010,7 @@ upd_showusers(Entry *ce, Section *cs) + } + } + +-static const char *defminuid, *defmaxuid; ++static char defminuid[64], defmaxuid[64]; + + static void + upd_minshowuid(Entry *ce, Section *cs ATTR_UNUSED) +@@ -2034,16 +2036,18 @@ upd_hiddenusers(Entry *ce, Section *cs) + char *nv; + const char *msu, *pt, *et; + struct passwd *pw; +- unsigned minuid, maxuid; ++ int minuid, maxuid; + char nbuf[128]; + + if (!ce->active) + return; + + msu = getFqVal(cs->name, "MinShowUID", "0"); +- sscanf(msu, "%u", &minuid); ++ sscanf(msu, "%d", &minuid); + msu = getFqVal(cs->name, "MaxShowUID", "65535"); +- sscanf(msu, "%u", &maxuid); ++ sscanf(msu, "%d", &maxuid); ++ ++ minuid = interpretMinUid(minuid); + + nv = 0; + pt = ce->value; +@@ -2057,7 +2061,7 @@ upd_hiddenusers(Entry *ce, Section *cs) + } + if ((pw = getpwnam(nbuf))) { + if (!pw->pw_uid || +- (pw->pw_uid >= minuid && pw->pw_uid <= maxuid)) ++ (pw->pw_uid >= (uid_t)minuid && pw->pw_uid <= (uid_t)maxuid)) + { + if (nv) + strCat(&nv, ",%s", nbuf); +@@ -3000,7 +3004,7 @@ int main(int argc, char **argv) + StrList *fp; + Section *cs; + Entry *ce, **cep; +- int i, ap, locals, foreigns; ++ int i, ap, locals, foreigns, minuid, maxuid; + int no_old_xdm = 0, no_old_kde = 0; + struct stat st; + +@@ -3239,27 +3243,9 @@ int main(int argc, char **argv) + } + } + } +-#ifdef __linux__ +- if (!stat("/etc/debian_version", &st)) { /* debian */ +- defminuid = "1000"; +- defmaxuid = "29999"; +- } else if (!stat("/usr/portage", &st)) { /* gentoo */ +- defminuid = "1000"; +- defmaxuid = "65000"; +- } else if (!stat("/etc/mandrake-release", &st)) { /* mandrake - check before redhat! */ +- defminuid = "500"; +- defmaxuid = "65000"; +- } else if (!stat("/etc/redhat-release", &st)) { /* redhat */ +- defminuid = "100"; +- defmaxuid = "65000"; +- } else /* if (!stat("/etc/SuSE-release", &st)) */ { /* suse */ +- defminuid = "500"; +- defmaxuid = "65000"; +- } +-#else +- defminuid = "1000"; +- defmaxuid = "65000"; +-#endif ++ getDefaultMinMaxUids(&minuid, &maxuid); ++ sprintf(defminuid, "%d", minuid); ++ sprintf(defmaxuid, "%d", maxuid); + for (i = 0; i <= CONF_MAX_PRIO; i++) + for (cs = config; cs; cs = cs->next) + for (ce = cs->ents; ce; ce = ce->next) +diff -up kde-workspace-4.8.2/kdm/kfrontend/kgreeter.cpp.bz#732830-login kde-workspace-4.8.2/kdm/kfrontend/kgreeter.cpp +--- kde-workspace-4.8.2/kdm/kfrontend/kgreeter.cpp.bz#732830-login 2012-03-30 00:02:31.000000000 +0200 ++++ kde-workspace-4.8.2/kdm/kfrontend/kgreeter.cpp 2012-03-30 13:38:35.163492865 +0200 +@@ -66,6 +66,8 @@ Foundation, Inc., 51 Franklin Street, Fi + #include + #include + ++#include "../kdm-minmaxuid.h" ++ + class UserListView : public QListWidget { + public: + UserListView(QWidget *parent = 0) +@@ -389,12 +391,13 @@ KGreeter::insertUsers() + default_pix.fill(0); + } + } ++ int realLowUserId = interpretMinUid(_lowUserId); + if (_showUsers == SHOW_ALL) { + UserList noUsers(_noUsers); + QSet dupes; + for (setpwent(); (ps = getpwent()) != 0;) { + if (*ps->pw_dir && *ps->pw_shell && +- (ps->pw_uid >= (unsigned)_lowUserId || ++ (ps->pw_uid >= (unsigned)realLowUserId || + (!ps->pw_uid && _showRoot)) && + ps->pw_uid <= (unsigned)_highUserId && + !noUsers.hasUser(ps->pw_name) && +@@ -413,7 +416,7 @@ KGreeter::insertUsers() + QSet dupes; + for (setpwent(); (ps = getpwent()) != 0;) { + if (*ps->pw_dir && *ps->pw_shell && +- (ps->pw_uid >= (unsigned)_lowUserId || ++ (ps->pw_uid >= (unsigned)realLowUserId || + (!ps->pw_uid && _showRoot)) && + ps->pw_uid <= (unsigned)_highUserId && + (users.hasUser(ps->pw_name) || diff --git a/SOURCES/kde-workspace-4.8.3-webkit.patch b/SOURCES/kde-workspace-4.8.3-webkit.patch new file mode 100644 index 0000000..0115c94 --- /dev/null +++ b/SOURCES/kde-workspace-4.8.3-webkit.patch @@ -0,0 +1,104 @@ +diff -up kde-workspace-4.8.3/krunner/ksystemactivitydialog.cpp.webkit kde-workspace-4.8.3/krunner/ksystemactivitydialog.cpp +--- kde-workspace-4.8.3/krunner/ksystemactivitydialog.cpp.webkit 2012-05-07 15:38:33.380747874 +0200 ++++ kde-workspace-4.8.3/krunner/ksystemactivitydialog.cpp 2012-05-07 15:38:48.108759698 +0200 +@@ -41,7 +41,6 @@ KSystemActivityDialog::KSystemActivityDi + setWindowIcon(KIcon(QLatin1String( "utilities-system-monitor" ))); + setButtons(0); + setMainWidget(&m_processList); +- m_processList.setScriptingEnabled(true); + setSizeGripEnabled(true); + (void)minimumSizeHint(); //Force the dialog to be laid out now + layout()->setContentsMargins(0,0,0,0); +diff -up kde-workspace-4.8.3/ksysguard/gui/SensorDisplayLib/ProcessController.cpp.webkit kde-workspace-4.8.3/ksysguard/gui/SensorDisplayLib/ProcessController.cpp +--- kde-workspace-4.8.3/ksysguard/gui/SensorDisplayLib/ProcessController.cpp.webkit 2012-05-07 15:34:25.472580194 +0200 ++++ kde-workspace-4.8.3/ksysguard/gui/SensorDisplayLib/ProcessController.cpp 2012-05-07 15:34:30.485583409 +0200 +@@ -147,7 +147,6 @@ bool ProcessController::addSensor(const + mProcessList = new KSysGuardProcessList(this, hostName); + mProcessList->setUpdateIntervalMSecs(0); //we will call updateList() manually + mProcessList->setContentsMargins(0,0,0,0); +- mProcessList->setScriptingEnabled(true); + addActions(mProcessList->actions()); + connect(mProcessList, SIGNAL(updated()), this, SIGNAL(updated())); + connect(mProcessList, SIGNAL(processListChanged()), this, SIGNAL(processListChanged())); +diff -up kde-workspace-4.8.3/libs/ksysguard/CMakeLists.txt.webkit kde-workspace-4.8.3/libs/ksysguard/CMakeLists.txt +--- kde-workspace-4.8.3/libs/ksysguard/CMakeLists.txt.webkit 2012-04-29 23:05:49.239145354 +0200 ++++ kde-workspace-4.8.3/libs/ksysguard/CMakeLists.txt 2012-05-07 15:21:28.103104008 +0200 +@@ -21,6 +21,3 @@ add_subdirectory( processui ) + add_subdirectory( signalplotter ) + add_subdirectory( ksgrd ) + add_subdirectory( tests ) +- +-install(DIRECTORY scripts/ DESTINATION ${DATA_INSTALL_DIR}/ksysguard/scripts) +- +diff -up kde-workspace-4.8.3/libs/ksysguard/processui/CMakeLists.txt.webkit kde-workspace-4.8.3/libs/ksysguard/processui/CMakeLists.txt +--- kde-workspace-4.8.3/libs/ksysguard/processui/CMakeLists.txt.webkit 2012-04-29 23:05:49.242145324 +0200 ++++ kde-workspace-4.8.3/libs/ksysguard/processui/CMakeLists.txt 2012-05-07 15:21:28.104104008 +0200 +@@ -12,7 +12,6 @@ set(processui_LIB_SRCS + ProcessModel.cpp + ReniceDlg.cpp + KTextEditVT.cpp +- scripting.cpp + ) + + kde4_add_ui_files( processui_LIB_SRCS +@@ -27,7 +26,7 @@ if(X11_XRes_FOUND) + include_directories(${X11_XRes_INCLUDE_PATH}) + endif(X11_XRes_FOUND) + +-target_link_libraries(processui ${KDE4_KDEUI_LIBS} ${QT_QTSCRIPT_LIBRARY} ${QT_QTWEBKIT_LIBRARY} processcore) ++target_link_libraries(processui ${KDE4_KDEUI_LIBS} processcore) + target_link_libraries(processui LINK_INTERFACE_LIBRARIES ${KDE4_KDEUI_LIBS} processcore) + + +diff -up kde-workspace-4.8.3/libs/ksysguard/processui/ksysguardprocesslist.cpp.webkit kde-workspace-4.8.3/libs/ksysguard/processui/ksysguardprocesslist.cpp +--- kde-workspace-4.8.3/libs/ksysguard/processui/ksysguardprocesslist.cpp.webkit 2012-04-29 23:05:49.245145296 +0200 ++++ kde-workspace-4.8.3/libs/ksysguard/processui/ksysguardprocesslist.cpp 2012-05-07 15:21:28.104104008 +0200 +@@ -894,9 +894,6 @@ void KSysGuardProcessList::hideEvent ( Q + //Stop updating the process list if we are hidden + if(d->mUpdateTimer) + d->mUpdateTimer->stop(); +- //stop any scripts running, to save on memory +- if(d->mScripting) +- d->mScripting->stopAllScripts(); + QWidget::hideEvent(event); + } + +@@ -1419,16 +1416,3 @@ bool KSysGuardProcessList::scriptingEnab + { + return !!d->mScripting; + } +-void KSysGuardProcessList::setScriptingEnabled(bool enabled) +-{ +- if(!!d->mScripting == enabled) +- return; //Nothing changed +- if(!enabled) { +- delete d->mScripting; +- d->mScripting = NULL; +- } else { +- d->mScripting = new Scripting(this); +- d->mScripting->hide(); +- } +- +-} +diff -up kde-workspace-4.8.3/libs/ksysguard/processui/ksysguardprocesslist.h.webkit kde-workspace-4.8.3/libs/ksysguard/processui/ksysguardprocesslist.h +--- kde-workspace-4.8.3/libs/ksysguard/processui/ksysguardprocesslist.h.webkit 2012-04-29 23:05:49.245145296 +0200 ++++ kde-workspace-4.8.3/libs/ksysguard/processui/ksysguardprocesslist.h 2012-05-07 15:21:28.105104008 +0200 +@@ -52,7 +52,6 @@ class KDE_EXPORT KSysGuardProcessList : + Q_PROPERTY( int updateIntervalMSecs READ updateIntervalMSecs WRITE setUpdateIntervalMSecs ) + Q_PROPERTY( ProcessModel::Units units READ units WRITE setUnits ) + Q_PROPERTY( bool killButtonVisible READ isKillButtonVisible WRITE setKillButtonVisible ) +- Q_PROPERTY( bool scriptingEnabled READ scriptingEnabled WRITE setScriptingEnabled ) + Q_ENUMS( ProcessFilter::State ) + Q_ENUMS( ProcessModel::Units ) + +@@ -112,10 +111,6 @@ class KDE_EXPORT KSysGuardProcessList : + * + * Default is false. */ + bool scriptingEnabled() const; +- /** Set whether scripting support is enabled. +- * +- * Default is false. */ +- void setScriptingEnabled(bool enabled); + + Q_SIGNALS: + /** Emitted when the display has been updated */ diff --git a/SOURCES/kde-workspace-4.9.0-add_apper_to_kickoff_favorites.patch b/SOURCES/kde-workspace-4.9.0-add_apper_to_kickoff_favorites.patch new file mode 100644 index 0000000..9d30c2a --- /dev/null +++ b/SOURCES/kde-workspace-4.9.0-add_apper_to_kickoff_favorites.patch @@ -0,0 +1,12 @@ +diff -up kde-workspace-4.9.0/plasma/desktop/applets/kickoff/core/favoritesmodel.cpp.kickoff_favorites kde-workspace-4.9.0/plasma/desktop/applets/kickoff/core/favoritesmodel.cpp +--- kde-workspace-4.9.0/plasma/desktop/applets/kickoff/core/favoritesmodel.cpp.kickoff_favorites 2012-05-22 18:54:42.000000000 -0500 ++++ kde-workspace-4.9.0/plasma/desktop/applets/kickoff/core/favoritesmodel.cpp 2012-08-21 11:44:22.597969049 -0500 +@@ -105,7 +105,7 @@ public: + static QList defaultFavorites() + { + QList applications; +- applications << "konqbrowser" << "KMail2" << "systemsettings" << "dolphin"; ++ applications << "konqbrowser" << "KMail2" << "systemsettings" << "dolphin" << "apper"; + + QList desktopFiles; + diff --git a/SOURCES/kde-workspace-4.9.90-plasma_konsole.patch b/SOURCES/kde-workspace-4.9.90-plasma_konsole.patch new file mode 100644 index 0000000..5e5a49b --- /dev/null +++ b/SOURCES/kde-workspace-4.9.90-plasma_konsole.patch @@ -0,0 +1,78 @@ +diff -up kde-workspace-4.9.90/plasma/generic/containmentactions/contextmenu/menu.cpp.plasma-konsole kde-workspace-4.9.90/plasma/generic/containmentactions/contextmenu/menu.cpp +--- kde-workspace-4.9.90/plasma/generic/containmentactions/contextmenu/menu.cpp.plasma-konsole 2012-11-14 10:06:18.000000000 -0600 ++++ kde-workspace-4.9.90/plasma/generic/containmentactions/contextmenu/menu.cpp 2012-12-03 17:01:20.403223435 -0600 +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -46,6 +47,7 @@ + + ContextMenu::ContextMenu(QObject *parent, const QVariantList &args) + : Plasma::ContainmentActions(parent, args), ++ m_runKonsoleAction(0), + m_runCommandAction(0), + m_lockScreenAction(0), + m_logoutAction(0), +@@ -74,7 +76,7 @@ void ContextMenu::init(const KConfigGrou + m_actionOrder << "add widgets" << "_add panel" << "lock widgets" << "_context" << "remove"; + } else { + actions.insert("configure shortcuts", false); +- m_actionOrder << "_context" << "_run_command" << "add widgets" << "_add panel" ++ m_actionOrder << "_context" << "_run_konsole" << "_run_command" << "add widgets" << "_add panel" + << "manage activities" << "remove" << "lock widgets" << "_sep1" + <<"_lock_screen" << "_logout" << "_sep2" << "configure" + << "configure shortcuts" << "_sep3" << "_wallpaper"; +@@ -96,6 +98,10 @@ void ContextMenu::init(const KConfigGrou + c->containmentType() == Plasma::Containment::CustomPanelContainment) { + //FIXME: panel does its own config action atm... + } else if (!m_runCommandAction) { ++ m_runKonsoleAction = new QAction(i18n("Konsole"), this); ++ m_runKonsoleAction->setIcon(KIcon("utilities-terminal")); ++ connect(m_runKonsoleAction, SIGNAL(triggered(bool)), this, SLOT(runKonsole())); ++ + m_runCommandAction = new QAction(i18n("Run Command..."), this); + m_runCommandAction->setIcon(KIcon("system-run")); + connect(m_runCommandAction, SIGNAL(triggered(bool)), this, SLOT(runCommand())); +@@ -168,6 +174,8 @@ QAction *ContextMenu::action(const QStri + if (c->corona() && c->corona()->immutability() == Plasma::Mutable) { + return c->corona()->action("add panel"); + } ++ } else if (name == "_run_konsole") { ++ return m_runKonsoleAction; + } else if (name == "_run_command") { + if (KAuthorized::authorizeKAction("run_command")) { + return m_runCommandAction; +@@ -191,6 +199,11 @@ QAction *ContextMenu::action(const QStri + return 0; + } + ++void ContextMenu::runKonsole() ++{ ++ KToolInvocation::invokeTerminal(QString(), QDir::homePath()); ++} ++ + void ContextMenu::runCommand() + { + if (!KAuthorized::authorizeKAction("run_command")) { +diff -up kde-workspace-4.9.90/plasma/generic/containmentactions/contextmenu/menu.h.plasma-konsole kde-workspace-4.9.90/plasma/generic/containmentactions/contextmenu/menu.h +--- kde-workspace-4.9.90/plasma/generic/containmentactions/contextmenu/menu.h.plasma-konsole 2012-11-14 10:06:18.000000000 -0600 ++++ kde-workspace-4.9.90/plasma/generic/containmentactions/contextmenu/menu.h 2012-12-03 16:59:09.172842770 -0600 +@@ -41,12 +41,14 @@ public: + void save(KConfigGroup &config); + + public slots: ++ void runKonsole(); + void runCommand(); + void lockScreen(); + void startLogout(); + void logout(); + + private: ++ QAction *m_runKonsoleAction; + QAction *m_runCommandAction; + QAction *m_lockScreenAction; + QAction *m_logoutAction; diff --git a/SOURCES/kde-workspace-close-menu-on-closed-task.patch b/SOURCES/kde-workspace-close-menu-on-closed-task.patch new file mode 100644 index 0000000..b535a88 --- /dev/null +++ b/SOURCES/kde-workspace-close-menu-on-closed-task.patch @@ -0,0 +1,14 @@ +diff --git a/plasma/desktop/applets/tasks/tasks.cpp b/plasma/desktop/applets/tasks/tasks.cpp +index a881e16..4ebb87d 100644 +--- a/plasma/desktop/applets/tasks/tasks.cpp ++++ b/plasma/desktop/applets/tasks/tasks.cpp +@@ -273,6 +273,9 @@ void Tasks::itemContextMenu(int id) + menu->setMinimumWidth(declItem->implicitWidth()); + } + ++ // Close menu when the delegate is destroyed ++ connect(item, SIGNAL(destroyed(QObject*)), menu, SLOT(close())); ++ + menu->exec(containment()->corona()->popupPosition(declItem, menu->size())); + menu->deleteLater(); + } diff --git a/SOURCES/kde-workspace-disable-plasma-screensaver.patch b/SOURCES/kde-workspace-disable-plasma-screensaver.patch new file mode 100644 index 0000000..c955e28 --- /dev/null +++ b/SOURCES/kde-workspace-disable-plasma-screensaver.patch @@ -0,0 +1,209 @@ +diff --git a/kcontrol/screensaver/screensaver.ui b/kcontrol/screensaver/screensaver.ui +index 6524e27..5cf64d6 100644 +--- a/kcontrol/screensaver/screensaver.ui ++++ b/kcontrol/screensaver/screensaver.ui +@@ -21,6 +21,9 @@ + + + ++ ++ QFormLayout::ExpandingFieldsGrow ++ + + + +@@ -102,34 +105,13 @@ + + + +- +- +- +- +- &Desktop Widgets +- +- +- +- +- +- +- false +- +- +- Configure... +- +- +- +- +- +- + + + S&creen saver + + + +- ++ + + + false +@@ -292,16 +274,16 @@ + + + +- +- KIntSpinBox +- QSpinBox +-
knuminput.h
+-
+ + KPushButton + QPushButton +
kpushbutton.h
+
++ ++ KIntSpinBox ++ QSpinBox ++
knuminput.h
++
+
+ + mEnabledCheckBox +@@ -309,29 +291,11 @@ + mLockCheckBox + mWaitLockEdit + mSimpleLockerRadio +- mPlasmaWidgetsRadio +- mPlasmaSetup + mScreenSaverRadio + mSaverListView + + + +- +- mPlasmaWidgetsRadio +- toggled(bool) +- mPlasmaSetup +- setEnabled(bool) +- +- +- 175 +- 147 +- +- +- 283 +- 147 +- +- +- + + mScreenSaverRadio + toggled(bool) +diff --git a/kcontrol/screensaver/scrnsave.cpp b/kcontrol/screensaver/scrnsave.cpp +index 0125620..a9e5c4a 100644 +--- a/kcontrol/screensaver/scrnsave.cpp ++++ b/kcontrol/screensaver/scrnsave.cpp +@@ -167,12 +167,8 @@ KScreenSaver::KScreenSaver(QWidget *parent, const QVariantList&) + connect(mWaitLockEdit, SIGNAL(valueChanged(int)), + this, SLOT(slotLockTimeoutChanged(int))); + +- connect(mPlasmaWidgetsRadio, SIGNAL(toggled(bool)), this, SLOT(slotEnablePlasma(bool))); + connect(mScreenSaverRadio, SIGNAL(toggled(bool)), this, SLOT(slotEnableLegacyScreenSaver(bool))); + +- mPlasmaSetup->setEnabled(mPlasmaEnabled); +- connect(mPlasmaSetup, SIGNAL(clicked()), this, SLOT(slotPlasmaSetup())); +- + mMonitorPreview = new ScreenPreviewWidget(this); + mMonitorPreview->setFixedSize(200,220); + QDesktopWidget *desktop = QApplication::desktop(); +@@ -300,13 +296,8 @@ void KScreenSaver::readSettings() + + bool legacyScreenSaver = config.readEntry("LegacySaverEnabled", false); + mScreenSaverRadio->setChecked(legacyScreenSaver); ++ + if (!legacyScreenSaver) { +- mPlasmaEnabled = config.readEntry("PlasmaEnabled", false); +- mPlasmaWidgetsRadio->setChecked(mPlasmaEnabled); +- } else { +- mPlasmaEnabled = false; +- } +- if (!legacyScreenSaver && !mPlasmaEnabled) { + mSimpleLockerRadio->setChecked(true); + } + +@@ -351,7 +342,6 @@ void KScreenSaver::defaults() + slotLock( false ); + mEnabledCheckBox->setChecked(false); + mSimpleLockerRadio->setChecked(true); +- mPlasmaSetup->setEnabled(false); + + updateValues(); + +@@ -371,7 +361,6 @@ void KScreenSaver::save() + config.writeEntry("Timeout", mTimeout); + config.writeEntry("LockGrace", mLockTimeout); + config.writeEntry("Lock", mLock); +- config.writeEntry("PlasmaEnabled", mPlasmaEnabled); + config.writeEntry("LegacySaverEnabled", mScreenSaverRadio->isChecked()); + + if ( !mSaver.isEmpty() ) +@@ -558,17 +547,6 @@ void KScreenSaver::slotEnable(bool e) + emit changed(true); + } + +-void KScreenSaver::slotEnablePlasma(bool enable) +-{ +- mPlasmaEnabled = enable; +- //FIXME even though the button's enabled, plasma isn't until the user hits apply +- //so the button will just show the screensaver, no plasma. +- //what should I do about this? +- mPlasmaSetup->setEnabled(mPlasmaEnabled); +- mChanged = true; +- emit changed(true); +-} +- + void KScreenSaver::slotEnableLegacyScreenSaver(bool enable) + { + if (mMonitor) { +@@ -578,12 +556,6 @@ void KScreenSaver::slotEnableLegacyScreenSaver(bool enable) + emit changed(true); + } + +-void KScreenSaver::slotPlasmaSetup() +-{ +- org::kde::screensaver kscreensaver("org.kde.screensaver", "/ScreenSaver", QDBusConnection::sessionBus()); +- kscreensaver.setupPlasma(); +-} +- + + //--------------------------------------------------------------------------- + // +diff --git a/kcontrol/screensaver/scrnsave.h b/kcontrol/screensaver/scrnsave.h +index 202e14e..ac2a539 100644 +--- a/kcontrol/screensaver/scrnsave.h ++++ b/kcontrol/screensaver/scrnsave.h +@@ -80,9 +80,7 @@ protected Q_SLOTS: + // new preview + void slotPreviewExited(); + void findSavers(); +- void slotEnablePlasma(bool enable); + void slotEnableLegacyScreenSaver(bool enable); +- void slotPlasmaSetup(); + + protected: + void writeSettings(); +diff --git a/ksmserver/screenlocker/ksldapp.cpp b/ksmserver/screenlocker/ksldapp.cpp +index 78c1ddf..82fb57e 100644 +--- a/ksmserver/screenlocker/ksldapp.cpp ++++ b/ksmserver/screenlocker/ksldapp.cpp +@@ -161,7 +161,8 @@ void KSldApp::configure() + m_lockGrace = -1; + } + m_autoLogoutTimeout = KScreenSaverSettings::autoLogout() ? KScreenSaverSettings::autoLogoutTimeout() * 1000 : 0; +- m_plasmaEnabled = KScreenSaverSettings::plasmaEnabled(); ++ // m_plasmaEnabled = KScreenSaverSettings::plasmaEnabled(); ++ m_plasmaEnabled = false; + } + + void KSldApp::lock() diff --git a/SOURCES/kde-workspace-exclude_kdm.patch b/SOURCES/kde-workspace-exclude_kdm.patch new file mode 100644 index 0000000..8f31cc9 --- /dev/null +++ b/SOURCES/kde-workspace-exclude_kdm.patch @@ -0,0 +1,64 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 27317c3..64d36cf 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -100,8 +100,6 @@ if(Q_WS_X11) + + add_feature_info("Automated testing of X clients" X11_XTest_FOUND + "The X11 Testing Resource extension library is useful for automated testing of X clients") +- add_feature_info("libXau" X11_Xau_FOUND "The X11 Authorization Protocol library may be used by KDM") +- add_feature_info("LibXdmcp" X11_Xdmcp_FOUND "The X Display Manager Control Protocol library may be used by KDM") + if(NOT X11_Xkbfile_FOUND) + message(FATAL_ERROR "The X11 keyboard layout library was not found. Required for building keyboard modules.") + endif() +@@ -262,11 +260,6 @@ if(${KDE_PLATFORM_PROFILE} STREQUAL "Desktop") + macro_optional_add_subdirectory(appmenu) + endif(NOT WIN32) + +- if(X11_Xau_FOUND AND X11_Xdmcp_FOUND) +- macro_optional_add_subdirectory( kdm ) +- else(X11_Xau_FOUND AND X11_Xdmcp_FOUND) +- message(STATUS "Xau lib or Xdmcp lib was missing. kdm will not compile") +- endif(X11_Xau_FOUND AND X11_Xdmcp_FOUND) + endif(${KDE_PLATFORM_PROFILE} STREQUAL "Desktop") + + if(NOT WIN32) +diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt +index af00f4c..d49d590 100644 +--- a/doc/CMakeLists.txt ++++ b/doc/CMakeLists.txt +@@ -1,4 +1,3 @@ +-add_subdirectory(kdm) + add_subdirectory(klipper) + add_subdirectory(kfontview) + add_subdirectory(kmenuedit) +diff --git a/kdm/kfrontend/sessions/kde-plasma-safe.desktop.cmake b/kdm/kfrontend/sessions/kde-plasma-safe.desktop.cmake +index 3cf746b..0af75fa 100644 +--- a/kdm/kfrontend/sessions/kde-plasma-safe.desktop.cmake ++++ b/kdm/kfrontend/sessions/kde-plasma-safe.desktop.cmake +@@ -1,8 +1,8 @@ + [Desktop Entry] + Encoding=UTF-8 + Type=XSession +-Exec=${BIN_INSTALL_DIR}/startkde --failsafe +-TryExec=${BIN_INSTALL_DIR}/startkde ++Exec=/usr/bin/startkde --failsafe ++TryExec=/usr/bin/startkde + DesktopNames=KDE + Name=KDE Plasma Workspace (failsafe session) + Name[ar]=مساحة عمل بلازما كدي (الجلسة الآمنة) +diff --git a/kdm/kfrontend/sessions/kde-plasma.desktop.cmake b/kdm/kfrontend/sessions/kde-plasma.desktop.cmake +index 613f7dd..40089bb 100644 +--- a/kdm/kfrontend/sessions/kde-plasma.desktop.cmake ++++ b/kdm/kfrontend/sessions/kde-plasma.desktop.cmake +@@ -1,8 +1,8 @@ + [Desktop Entry] + Encoding=UTF-8 + Type=XSession +-Exec=${BIN_INSTALL_DIR}/startkde +-TryExec=${BIN_INSTALL_DIR}/startkde ++Exec=/usr/bin/startkde ++TryExec=/usr/bin/startkde + DesktopNames=KDE + Name=KDE Plasma Workspace + Name[ar]=مساحة عمل بلازما كدي diff --git a/SOURCES/kde-workspace-kcm_fonts_dont_change_on_load.patch b/SOURCES/kde-workspace-kcm_fonts_dont_change_on_load.patch new file mode 100644 index 0000000..97c1589 --- /dev/null +++ b/SOURCES/kde-workspace-kcm_fonts_dont_change_on_load.patch @@ -0,0 +1,38 @@ +diff -up kde-workspace-4.10.2/kcontrol/fonts/fonts.cpp.kcm_fonts_dont_change_on_load kde-workspace-4.10.2/kcontrol/fonts/fonts.cpp +--- kde-workspace-4.10.2/kcontrol/fonts/fonts.cpp.kcm_fonts_dont_change_on_load 2013-03-01 00:32:24.000000000 -0600 ++++ kde-workspace-4.10.2/kcontrol/fonts/fonts.cpp 2013-05-03 07:22:57.033141204 -0500 +@@ -330,14 +330,9 @@ bool FontAASettings::load() + + if(!xft.getHintStyle(hStyle) || KXftConfig::Hint::NotSet==hStyle) + { +- KConfig kglobals("kdeglobals", KConfig::NoGlobals); +- + hStyle=KXftConfig::Hint::Medium; + xft.setHintStyle(hStyle); +- xft.apply(); // Save this setting +- KConfigGroup(&kglobals, "General").writeEntry("XftHintStyle", KXftConfig::toStr(hStyle)); +- kglobals.sync(); +- runRdb(KRdbExportXftSettings | KRdbExportGtkTheme); ++ changesMade = true; + } + + hintingStyle->setCurrentIndex(getIndex(hStyle)); +diff -up kde-workspace-4.10.2/kcontrol/fonts/kxftconfig.cpp.kcm_fonts_dont_change_on_load kde-workspace-4.10.2/kcontrol/fonts/kxftconfig.cpp +--- kde-workspace-4.10.2/kcontrol/fonts/kxftconfig.cpp.kcm_fonts_dont_change_on_load 2013-03-01 00:32:24.056859289 -0600 ++++ kde-workspace-4.10.2/kcontrol/fonts/kxftconfig.cpp 2013-05-03 07:13:43.182065296 -0500 +@@ -282,7 +282,6 @@ bool KXftConfig::reset() + m_excludePixelRange.from=pFrom; + m_excludePixelRange.to=pTo; + m_madeChanges=true; +- apply(); + } + } + else if(!equal(0, m_excludePixelRange.from) || !equal(0, m_excludePixelRange.to)) +@@ -291,7 +290,6 @@ bool KXftConfig::reset() + m_excludeRange.from=(int)pixel2Point(m_excludePixelRange.from); + m_excludeRange.to=(int)pixel2Point(m_excludePixelRange.to); + m_madeChanges=true; +- apply(); + } + } + diff --git a/SOURCES/kde-workspace-kdm_local_ipv6.patch b/SOURCES/kde-workspace-kdm_local_ipv6.patch new file mode 100644 index 0000000..b767a2a --- /dev/null +++ b/SOURCES/kde-workspace-kdm_local_ipv6.patch @@ -0,0 +1,45 @@ +--- ./kdm/backend/auth.c 2015-02-06 17:59:27.473734701 -0600 ++++ ./kdm/backend/auth.c.orig 2015-02-06 18:46:13.072441136 -0600 +@@ -44,6 +44,10 @@ + + #include + ++#ifdef XDMCP ++# include ++#endif ++ + #include "dm_socket.h" + #ifdef DNETCONN + # include +@@ -1075,10 +1079,28 @@ + static int + convertAuthAddr(char *saddr, int *len, CARD8 **addr) + { ++ static const unsigned char ipv6_lo[] = { ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ++ }; ++ ++ static const unsigned char ipv4_lo[] = { ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01 ++ }; ++ + int ret = convertAddr(saddr, len, addr); +- if (ret == FamilyInternet && +- ((struct in_addr *)*addr)->s_addr == htonl(0x7F000001L)) +- ret = FamilyLocal; ++ ++ if (ret == FamilyInternet) { ++ if (((struct in_addr *)*addr)->s_addr == htonl(0x7F000001L)) ++ ret = FamilyLocal; ++ } else if (ret == FamilyInternet6) { ++ if (memcmp(*addr, ipv6_lo, sizeof ipv6_lo) == 0) ++ ret = FamilyLocal; ++ else if (memcmp(*addr, ipv4_lo, sizeof ipv4_lo) == 0) ++ ret = FamilyLocal; ++ } ++ + return ret; + } + diff --git a/SOURCES/kde-workspace-kscreenlocker-greeter-unlock-just-once.patch b/SOURCES/kde-workspace-kscreenlocker-greeter-unlock-just-once.patch new file mode 100644 index 0000000..6bb4d24 --- /dev/null +++ b/SOURCES/kde-workspace-kscreenlocker-greeter-unlock-just-once.patch @@ -0,0 +1,18 @@ +diff --git a/ksmserver/screenlocker/greeter/greeterapp.cpp b/ksmserver/screenlocker/greeter/greeterapp.cpp +index 8ac0de4..64f7b2c 100644 +--- a/ksmserver/screenlocker/greeter/greeterapp.cpp ++++ b/ksmserver/screenlocker/greeter/greeterapp.cpp +@@ -418,8 +418,11 @@ bool UnlockApp::eventFilter(QObject *obj, QEvent *event) + } + } + if (!saverVisible) { +- shareEvent(event, qobject_cast(obj)); +- return false; // we don't care ++ QKeyEvent *ke = static_cast(event); ++ if (ke->key() != Qt::Key_Enter && ke->key() != Qt::Key_Return) { ++ shareEvent(event, qobject_cast(obj)); ++ } ++ return false; + } + ignoreNextEscape = bool(static_cast(event)->key() == Qt::Key_Escape); + capsLocked(); diff --git a/SOURCES/kde-workspace-ksysguard-increase-cpu-buffer.patch b/SOURCES/kde-workspace-ksysguard-increase-cpu-buffer.patch new file mode 100644 index 0000000..553853c --- /dev/null +++ b/SOURCES/kde-workspace-ksysguard-increase-cpu-buffer.patch @@ -0,0 +1,13 @@ +diff --git a/ksysguard/ksysguardd/Linux/cpuinfo.c b/ksysguard/ksysguardd/Linux/cpuinfo.c +index 9427ec0..12786c5 100644 +--- a/ksysguard/ksysguardd/Linux/cpuinfo.c ++++ b/ksysguard/ksysguardd/Linux/cpuinfo.c +@@ -40,7 +40,7 @@ static int numCores = 0; /* Total # of cores */ + static int HighNumCores = 0; /* Highest # of cores ever seen */ + static float* Clocks = 0; /* Array with one entry per core */ + +-#define CPUINFOBUFSIZE (32 * 1024) ++#define CPUINFOBUFSIZE (128 * 1024) + static char CpuInfoBuf[ CPUINFOBUFSIZE ]; + static int Dirty = 0; + static struct SensorModul *CpuInfoSM; diff --git a/SOURCES/kde-workspace-plastik-do-not-show-disabled-buttons.patch b/SOURCES/kde-workspace-plastik-do-not-show-disabled-buttons.patch new file mode 100644 index 0000000..81d6f08 --- /dev/null +++ b/SOURCES/kde-workspace-plastik-do-not-show-disabled-buttons.patch @@ -0,0 +1,64 @@ +diff --git a/kwin/clients/aurorae/themes/plastik/package/contents/ui/main.qml b/kwin/clients/aurorae/themes/plastik/package/contents/ui/main.qml +index 77676bf..6772d06 100644 +--- a/kwin/clients/aurorae/themes/plastik/package/contents/ui/main.qml ++++ b/kwin/clients/aurorae/themes/plastik/package/contents/ui/main.qml +@@ -19,6 +19,29 @@ import org.kde.kwin.decoration 0.1 + import org.kde.kwin.decorations.plastik 1.0 + + Decoration { ++ function removeDisabledButtons(buttons) { ++ var btns = ""; ++ for (var i = 0; i < buttons.length; i++) { ++ if (buttons[i] == 'I') { ++ if (!decoration.minimizeable) { ++ continue; ++ } ++ } ++ if (buttons[i] == 'A') { ++ if (!decoration.maximizeable) { ++ continue; ++ { ++ } ++ if (buttons[i] == 'X') { ++ if (!decoration.closeable) { ++ continue; ++ } ++ } ++ btns += buttons[i]; ++ } ++ return btns; ++ } ++ + function readConfig() { + switch (decoration.readConfig("BorderSize", DecorationOptions.BorderNormal)) { + case DecorationOptions.BorderTiny: +@@ -263,11 +286,13 @@ Decoration { + shadeButton: shadeButtonComponent + allDesktopsButton: stickyButtonComponent + closeButton: closeButtonComponent +- buttons: options.titleButtonsLeft + anchors { + top: parent.top + left: parent.left + } ++ Component.onCompleted: { ++ buttons = removeDisabledButtons(options.titleButtonsLeft); ++ } + } + Text { + id: caption +@@ -304,11 +329,13 @@ Decoration { + shadeButton: shadeButtonComponent + allDesktopsButton: stickyButtonComponent + closeButton: closeButtonComponent +- buttons: options.titleButtonsRight + anchors { + top: parent.top + right: parent.right + } ++ Component.onCompleted: { ++ buttons = removeDisabledButtons(options.titleButtonsRight); ++ } + } + } + } diff --git a/SOURCES/kde-workspace-revert-improve-systemtray-on-hdpi-displays.patch b/SOURCES/kde-workspace-revert-improve-systemtray-on-hdpi-displays.patch new file mode 100755 index 0000000..374180e --- /dev/null +++ b/SOURCES/kde-workspace-revert-improve-systemtray-on-hdpi-displays.patch @@ -0,0 +1,35 @@ +diff --git a/plasma/generic/applets/systemtray/package/contents/ui/IconsList.qml b/plasma/generic/applets/systemtray/package/contents/ui/IconsList.qml +index d72733c..7ec7346 100644 +--- a/plasma/generic/applets/systemtray/package/contents/ui/IconsList.qml ++++ b/plasma/generic/applets/systemtray/package/contents/ui/IconsList.qml +@@ -33,7 +33,7 @@ MouseArea { + id: root_item + + property int icons_size: 24 ///< Size of icons, icons are square i.e. width == height +- property int icons_margins: icons_size/6 ///< Margins for icons ++ property int icons_margins: 4 ///< Margins for icons + property alias icons_number: repeater.count ///< [readonly] Number of icons + property alias model: repeater.model; ///< Model for grid + property int cell_size: icons_size + 2*icons_margins ///< [readonly] size of grid cell +diff --git a/plasma/generic/applets/systemtray/package/contents/ui/main.qml b/plasma/generic/applets/systemtray/package/contents/ui/main.qml +index 209091b..8577362 100644 +--- a/plasma/generic/applets/systemtray/package/contents/ui/main.qml ++++ b/plasma/generic/applets/systemtray/package/contents/ui/main.qml +@@ -34,7 +34,7 @@ Item { + property int minimumWidth: JS.MINIMUM_SIZE + property int minimumHeight: JS.MINIMUM_SIZE + +- property int iconSize: Math.min(root_item.width, Math.min(root_item.height, theme.defaultFont.mSize.height < 20 ? 24 : theme.largeIconSize)) //Math.min(root_item.width, Math.min(root_item.height, JS.ICONS_SIZE)) ++ property int iconSize: Math.min(root_item.width, Math.min(root_item.height, JS.ICONS_SIZE)) + + // Data Models + property list models: [ +@@ -112,7 +112,7 @@ Item { + + content: IconsList { + id: popup_area +- icons_size: root_item.iconSize ++ icons_size: JS.ICONS_SIZE + model: model_popup + } + } diff --git a/SOURCES/kde-workspace-sanitise-notification-html.patch b/SOURCES/kde-workspace-sanitise-notification-html.patch new file mode 100644 index 0000000..8d5e84e --- /dev/null +++ b/SOURCES/kde-workspace-sanitise-notification-html.patch @@ -0,0 +1,257 @@ +diff --git a/plasma/generic/dataengines/notifications/CMakeLists.txt b/plasma/generic/dataengines/notifications/CMakeLists.txt +index cf34971..e1d567f 100644 +--- a/plasma/generic/dataengines/notifications/CMakeLists.txt ++++ b/plasma/generic/dataengines/notifications/CMakeLists.txt +@@ -2,6 +2,7 @@ set(notifications_engine_SRCS + notificationsengine.cpp + notificationservice.cpp + notificationaction.cpp ++ notificationsanitizer.cpp + ) + + qt4_add_dbus_adaptor( notifications_engine_SRCS org.freedesktop.Notifications.xml notificationsengine.h NotificationsEngine ) +@@ -13,3 +14,15 @@ target_link_libraries(plasma_engine_notifications ${KDE4_PLASMA_LIBS} ${KDE4_KDE + install(TARGETS plasma_engine_notifications DESTINATION ${PLUGIN_INSTALL_DIR}) + install(FILES plasma-dataengine-notifications.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) + install(FILES notifications.operations DESTINATION ${DATA_INSTALL_DIR}/plasma/services) ++ ++set(notificationstest_SRCS notificationsanitizer.cpp notifications_test.cpp) ++ ++kde4_add_unit_test( notificationstest ++ TESTNAME notifications-notificationstest ++ ${notificationstest_SRCS} ++) ++ ++target_link_libraries(notificationstest ++ ${QT_QTTEST_LIBRARY} ++ ${KDE4_KDECORE_LIBS} ++) +\ No newline at end of file +diff --git a/plasma/generic/dataengines/notifications/notifications_test.cpp b/plasma/generic/dataengines/notifications/notifications_test.cpp +new file mode 100644 +index 0000000..ffa5187 +--- /dev/null ++++ b/plasma/generic/dataengines/notifications/notifications_test.cpp +@@ -0,0 +1,68 @@ ++#include ++#include ++#include ++#include "notificationsanitizer.h" ++ ++class NotificationTest : public QObject ++{ ++ Q_OBJECT ++public: ++ NotificationTest() {} ++private Q_SLOTS: ++ void parse_data(); ++ void parse(); ++}; ++ ++void NotificationTest::parse_data() ++{ ++ QTest::addColumn("messageIn"); ++ QTest::addColumn("expectedOut"); ++ ++ QTest::newRow("basic no HTML") << "I am a notification" << "I am a notification"; ++ QTest::newRow("whitespace") << " I am a notification " << "I am a notification"; ++ ++ QTest::newRow("basic html") << "I am the notification" << "I am the notification"; ++ QTest::newRow("nested html") << "I am the notification" << "I am the notification"; ++ ++ QTest::newRow("no extra tags") << "I am the notification" << "I am the notification"; ++ QTest::newRow("no extra attrs") << "I am the notification" << "I am the notification"; ++ ++ QTest::newRow("newlines") << "I am\nthe\nnotification" << "I am
the
notification"; ++ QTest::newRow("multinewlines") << "I am\n\nthe\n\n\nnotification" << "I am
the
notification"; ++ ++ QTest::newRow("amp") << "me&you" << "me&you"; ++ QTest::newRow("double escape") << "foo & <bar>" << "foo & <bar>"; ++ ++ QTest::newRow("quotes") << "'foo'" << "'foo'";//as label can't handle this normally valid entity ++ ++ QTest::newRow("image normal") << "This is \"cheese\"/ and more text" << "This is \"cheese\"/ and more text"; ++ ++ //this input is technically wrong, so the output is also wrong, but QTextHtmlParser does the "right" thing ++ QTest::newRow("image normal no close") << "This is \"cheese\" and more text" << "This is \"cheese\" and more text"; ++ ++ QTest::newRow("image remote URL") << "This is \"cheese\" and more text" << "This is \"cheese\"/ and more text"; ++ ++ //more bad formatted options. To some extent actual output doesn't matter. Garbage in, garbabe out. ++ //the important thing is that it doesn't contain anything that could be parsed as the remote URL ++ QTest::newRow("image remote URL no close") << "This is \" alt=\"cheese\"> and more text" << "This is \"cheese\" and more text"; ++ QTest::newRow("image remote URL double open") << "This is <\" and more text" << "This is "; ++ QTest::newRow("image remote URL no entitiy close") << "This is \"cheese\" and more text" << "This is "; ++ ++ QTest::newRow("link") << "This is a link and more text" << "This is a link and more text"; ++} ++ ++void NotificationTest::parse() ++{ ++ QFETCH(QString, messageIn); ++ QFETCH(QString, expectedOut); ++ ++ const QString out = NotificationSanitizer::parse(messageIn); ++ expectedOut = "" + expectedOut + "\n"; ++ QCOMPARE(out, expectedOut); ++} ++ ++ ++QTEST_MAIN(NotificationTest) ++ ++#include "notificationtest.moc" +\ No newline at end of file +diff --git a/plasma/generic/dataengines/notifications/notificationsanitizer.cpp b/plasma/generic/dataengines/notifications/notificationsanitizer.cpp +new file mode 100644 +index 0000000..8750958 +--- /dev/null ++++ b/plasma/generic/dataengines/notifications/notificationsanitizer.cpp +@@ -0,0 +1,106 @@ ++/* ++ * Copyright (C) 2017 David Edmundson ++ * ++ * 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 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 ++ * 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 "notificationsanitizer.h" ++ ++#include ++#include ++#include ++#include ++#include ++ ++QString NotificationSanitizer::parse(const QString &text) ++{ ++ // replace all \ns with
++ QString t = text; ++ ++ t.replace(QLatin1String("\n"), QLatin1String("
")); ++ // Now remove all inner whitespace (\ns are already
s) ++ t = t.simplified(); ++ // Finally, check if we don't have multiple
s following, ++ // can happen for example when "\n \n" is sent, this replaces ++ // all
s in succsession with just one ++ t.replace(QRegExp(QLatin1String("
\\s*
(\\s|
)*")), QLatin1String("
")); ++ // This fancy RegExp escapes every occurence of & since QtQuick Text will blatantly cut off ++ // text where it finds a stray ampersand. ++ // Only &{apos, quot, gt, lt, amp}; as well as { character references will be allowed ++ t.replace(QRegExp(QLatin1String("&(?!(?:apos|quot|[gl]t|amp);|#)")), QLatin1String("&")); ++ ++ QXmlStreamReader r(QLatin1String("") + t + QLatin1String("")); ++ QString result; ++ QXmlStreamWriter out(&result); ++ ++ QVector allowedTags; ++ allowedTags << "b" << "i" << "u" << "img" << "a" << "html"<< "br"; ++ ++ out.writeStartDocument(); ++ while (!r.atEnd()) { ++ r.readNext(); ++ ++ if (r.tokenType() == QXmlStreamReader::StartElement) { ++ const QString name = r.name().toString(); ++ if (!allowedTags.contains(name)) { ++ continue; ++ } ++ out.writeStartElement(name); ++ if (name == QLatin1String("img")) { ++ QString src = r.attributes().value("src").toString(); ++ QString alt = r.attributes().value("alt").toString(); ++ ++ const QUrl url(src); ++ if (url.isLocalFile()) { ++ out.writeAttribute(QLatin1String("src"), src); ++ } else { ++ //image denied for security reasons! Do not copy the image src here! ++ } ++ ++ out.writeAttribute(QLatin1String("alt"), alt); ++ } ++ if (name == QLatin1String("a")) { ++ out.writeAttribute(QLatin1String("href"), r.attributes().value("href").toString()); ++ } ++ } ++ ++ if (r.tokenType() == QXmlStreamReader::EndElement) { ++ const QString name = r.name().toString(); ++ if (!allowedTags.contains(name)) { ++ continue; ++ } ++ out.writeEndElement(); ++ } ++ ++ if (r.tokenType() == QXmlStreamReader::Characters) { ++ const QString text = r.text().toString(); ++ out.writeCharacters(text); //this auto escapes chars -> HTML entities ++ } ++ } ++ out.writeEndDocument(); ++ ++ if (r.hasError()) { ++ qWarning() << "Notification to send to backend contains invalid XML: " ++ << r.errorString() << "line" << r.lineNumber() ++ << "col" << r.columnNumber(); ++ } ++ ++ // The Text.StyledText format handles only html3.2 stuff and ' is html4 stuff ++ // so we need to replace it here otherwise it will not render at all. ++ result = result.replace(QLatin1String("'"), QChar('\'')); ++ ++ return result; ++} +diff --git a/plasma/generic/dataengines/notifications/notificationsanitizer.h b/plasma/generic/dataengines/notifications/notificationsanitizer.h +new file mode 100644 +index 0000000..b0c3ccd +--- /dev/null ++++ b/plasma/generic/dataengines/notifications/notificationsanitizer.h +@@ -0,0 +1,35 @@ ++/* ++ * Copyright (C) 2017 David Edmundson ++ * ++ * 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 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 ++ * 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 ++ ++namespace NotificationSanitizer ++{ ++ /* ++ * This turns generic random text of either plain text of any degree of faux-HTML into HTML allowed ++ * in the notification spec namely: ++ * a, img, b, i, u and br ++ * All other tags and attributes are stripped ++ * Whitespace is stripped and converted to
++ * Double newlines are compressed ++ * ++ * Image src is only copied when referring to a local file ++ */ ++ QString parse(const QString &in); ++} diff --git a/SOURCES/kde-workspace-taskmanager-check-if-full-when-item-from-group-is-removed.patch b/SOURCES/kde-workspace-taskmanager-check-if-full-when-item-from-group-is-removed.patch new file mode 100644 index 0000000..a05844a --- /dev/null +++ b/SOURCES/kde-workspace-taskmanager-check-if-full-when-item-from-group-is-removed.patch @@ -0,0 +1,12 @@ +diff --git a/libs/taskmanager/groupmanager.cpp b/libs/taskmanager/groupmanager.cpp +index d1f304f..fc2f01f 100644 +--- a/libs/taskmanager/groupmanager.cpp ++++ b/libs/taskmanager/groupmanager.cpp +@@ -392,6 +392,7 @@ void GroupManagerPrivate::removeTask(::TaskManager::Task *task) + + if (item->parentGroup()) { + item->parentGroup()->remove(item); ++ checkIfFull(); + } + + //the item must exist as long as the Task does because of activate calls so don't delete the item here, it will delete itself. diff --git a/SOURCES/kde-workspace-taskmanager-grouping.patch b/SOURCES/kde-workspace-taskmanager-grouping.patch new file mode 100644 index 0000000..6aefc51 --- /dev/null +++ b/SOURCES/kde-workspace-taskmanager-grouping.patch @@ -0,0 +1,96 @@ +diff --git a/plasma/desktop/applets/tasks/CMakeLists.txt b/plasma/desktop/applets/tasks/CMakeLists.txt +index 29bb5ad..aee560d 100644 +--- a/plasma/desktop/applets/tasks/CMakeLists.txt ++++ b/plasma/desktop/applets/tasks/CMakeLists.txt +@@ -11,7 +11,7 @@ kde4_add_ui_files(tasks_SRCS tasksConfig.ui) + + kde4_add_plugin(plasma_applet_tasks ${tasks_SRCS}) + +-target_link_libraries(plasma_applet_tasks ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS} ${QT_QTDECLARATIVE_LIBRARY} taskmanager) ++target_link_libraries(plasma_applet_tasks ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS} ${QT_QTDECLARATIVE_LIBRARY} taskmanager kephal) + + install(TARGETS plasma_applet_tasks DESTINATION ${PLUGIN_INSTALL_DIR}) + install(FILES plasma-tasks-default.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +diff --git a/plasma/desktop/applets/tasks/package/contents/ui/GroupDialog.qml b/plasma/desktop/applets/tasks/package/contents/ui/GroupDialog.qml +index 4bba608..fe3c2b7 100644 +--- a/plasma/desktop/applets/tasks/package/contents/ui/GroupDialog.qml ++++ b/plasma/desktop/applets/tasks/package/contents/ui/GroupDialog.qml +@@ -20,6 +20,7 @@ + import QtQuick 1.1 + + import org.kde.plasma.core 0.1 as PlasmaCore ++import org.kde.plasma.extras 0.1 as PlasmaExtras + import org.kde.draganddrop 1.0 + + import "../code/layout.js" as Layout +@@ -45,10 +46,15 @@ PlasmaCore.Dialog { + + anchors.fill: parent + +- Repeater { +- id: groupRepeater ++ PlasmaExtras.ScrollArea { ++ id: scrollArea ++ anchors.fill: parent + +- onCountChanged: updateSize() ++ ListView { ++ id: groupRepeater ++ anchors.fill: parent ++ onCountChanged: updateSize() ++ } + } + } + } +@@ -87,8 +93,12 @@ PlasmaCore.Dialog { + var task; + var maxWidth = 0; + +- for (var i = 0; i < taskList.children.length - 1; ++i) { +- task = taskList.children[i]; ++ for (var i = 0; i < groupRepeater.count - 1; ++i) { ++ task = groupRepeater.contentItem.children[i]; ++ ++ if (!task || typeof task.textWidth == 'undefined') { ++ continue ++ } + + if (task.textWidth > maxWidth) { + maxWidth = task.textWidth; +@@ -100,8 +110,13 @@ PlasmaCore.Dialog { + maxWidth += Layout.horizontalMargins() + theme.smallIconSize + 6; + + // TODO: Properly derive limits from work area size (screen size sans struts). ++ mainItem.height = Math.min(screenHeight / 2, groupRepeater.count * (Layout.verticalMargins() + theme.smallIconSize)); + mainItem.width = Math.min(maxWidth, (tasks.vertical ? 640 - tasks.width : Math.max(tasks.width, 640)) - 20); +- mainItem.height = groupRepeater.count * (Layout.verticalMargins() + theme.smallIconSize); ++ ++ // Scrollbar is used so adjust width ++ if (mainItem.height >= screenHeight / 2) { ++ mainItem.width += 5 ++ } + } + } + +diff --git a/plasma/desktop/applets/tasks/tasks.cpp b/plasma/desktop/applets/tasks/tasks.cpp +index 4ebb87d..a919948 100644 +--- a/plasma/desktop/applets/tasks/tasks.cpp ++++ b/plasma/desktop/applets/tasks/tasks.cpp +@@ -41,6 +41,9 @@ + #include + #include + ++#include "kephal/kephal/desktopwidgetscreens.h" ++#include "kephal/kephal/screens.h" ++ + #include + + class GroupManager : public TaskManager::GroupManager +@@ -97,6 +100,7 @@ void Tasks::init() + qmlRegisterType( "Tasks", 0, 1, "ToolTip" ); + rootContext->setContextProperty("tasksModel", QVariant::fromValue(static_cast(m_tasksModel))); + rootContext->setContextProperty("dragHelper", QVariant::fromValue(static_cast(new DragHelper(this)))); ++ rootContext->setContextProperty("screenHeight", Kephal::Screens::self()->screen(c->screen())->size().height()); + + // NOTE: This can go away once Plasma::Location becomes available (i.e. once this is + // a pure-QML applet.) diff --git a/SOURCES/kdebase-workspace-4.2.85-klipper-url.patch b/SOURCES/kdebase-workspace-4.2.85-klipper-url.patch new file mode 100644 index 0000000..a15fea5 --- /dev/null +++ b/SOURCES/kdebase-workspace-4.2.85-klipper-url.patch @@ -0,0 +1,30 @@ +diff -up kdebase-workspace-4.2.85/klipper/klipperrc.desktop.klipper-url kdebase-workspace-4.2.85/klipper/klipperrc.desktop +--- kdebase-workspace-4.2.85/klipper/klipperrc.desktop.klipper-url 2009-04-05 22:00:13.000000000 +0200 ++++ kdebase-workspace-4.2.85/klipper/klipperrc.desktop 2009-05-11 22:56:51.000000000 +0200 +@@ -409,7 +409,7 @@ Description[zh_TW]=使用 &Konqueror 開 + Enabled=true + + [Action_1/Command_2] +-Commandline=ps x |grep -q '[m]ozilla' && "mozilla -remote openURL(%s, new-window)" || mozilla %s ++Commandline=ps x |grep -q '[m]ozilla' && mozilla -remote 'openURL(%s, new-window)' || mozilla %s + Icon=mozilla + Description=Open with &Mozilla + Description[af]=Maak oop met Mozilla +@@ -581,7 +581,7 @@ Description[zh_TW]=送出 &URL + Enabled=true + + [Action_1/Command_4] +-Commandline=ps x |grep -q '[f]irefox' && "firefox -remote openURL(%s, new-window)" || firefox "%s" ++Commandline=ps x |grep -q '[f]irefox' && firefox -remote 'openURL(%s, new-window)' || firefox "%s" + Icon=firefox + Description=Open with &Firefox + Description[af]=Maak oop met Firefox +@@ -1892,7 +1892,7 @@ Description[zh_TW]=使用 &Konqueror 開 + Enabled=true + + [Action_6/Command_2] +-Commandline=mozilla -remote openURL(%s, new-window) ++Commandline=mozilla -remote 'openURL(%s, new-window)' + Description=Open with &Mozilla + Description[af]=Maak oop met Mozilla + Description[ar]=افتح بواسطة &موزيلا diff --git a/SOURCES/kdebase-workspace-4.3.75-kio_sysinfo.patch b/SOURCES/kdebase-workspace-4.3.75-kio_sysinfo.patch new file mode 100644 index 0000000..68a95ac --- /dev/null +++ b/SOURCES/kdebase-workspace-4.3.75-kio_sysinfo.patch @@ -0,0 +1,67 @@ +diff -U5 -r kdebase-workspace-4.3.75svn1048496/plasma/desktop/applets/kickoff/core/models.cpp kdebase-workspace-4.3.75svn1048496.kio_sysinfo/plasma/desktop/applets/kickoff/core/models.cpp +--- kdebase-workspace-4.3.75svn1048496/plasma/desktop/applets/kickoff/core/models.cpp 2009-10-15 12:33:38.000000000 -0400 ++++ kdebase-workspace-4.3.75svn1048496.kio_sysinfo/plasma/desktop/applets/kickoff/core/models.cpp 2009-11-21 15:24:44.000000000 -0500 +@@ -176,10 +176,12 @@ + QStringList Kickoff::systemApplicationList() + { + KConfigGroup appsGroup = componentData().config()->group("SystemApplications"); + QStringList apps; + apps << "systemsettings"; ++ if (QFile::exists("/usr/share/kde4/services/sysinfo.protocol")) ++ apps << "/usr/share/kde4/services/sysinfo.protocol"; + apps = appsGroup.readEntry("DesktopFiles", apps); + return apps; + } + + #if 0 +diff -U5 -r kdebase-workspace-4.3.75svn1048496/plasma/desktop/applets/kickoff/core/systemmodel.cpp kdebase-workspace-4.3.75svn1048496.kio_sysinfo/plasma/desktop/applets/kickoff/core/systemmodel.cpp +--- kdebase-workspace-4.3.75svn1048496/plasma/desktop/applets/kickoff/core/systemmodel.cpp 2009-11-13 05:57:47.000000000 -0500 ++++ kdebase-workspace-4.3.75svn1048496.kio_sysinfo/plasma/desktop/applets/kickoff/core/systemmodel.cpp 2009-11-21 15:25:04.000000000 -0500 +@@ -244,21 +244,36 @@ + } + } + + KService::Ptr service = d->appsList[index.row()]; + +- switch (role) { +- case Qt::DisplayRole: +- return service->name(); +- case Qt::DecorationRole: +- return KIcon(service->icon()); +- case SubTitleRole: +- return service->genericName(); +- case UrlRole: +- return service->entryPath(); +- default: +- return QVariant(); ++ if (service->name()=="sysinfo") { ++ switch(role) { ++ case Qt::DisplayRole: ++ return i18n("System Information"); ++ case Qt::DecorationRole: ++ return KIcon("hwinfo"); ++ case SubTitleRole: ++ return "sysinfo:/"; ++ case UrlRole: ++ return "sysinfo:/"; ++ default: ++ return QVariant(); ++ } ++ } else { ++ switch (role) { ++ case Qt::DisplayRole: ++ return service->name(); ++ case Qt::DecorationRole: ++ return KIcon(service->icon()); ++ case SubTitleRole: ++ return service->genericName(); ++ case UrlRole: ++ return service->entryPath(); ++ default: ++ return QVariant(); ++ } + } + } + + if (role == UrlRole && !d->placesModel->isHidden(mapToSource(index))) { + QModelIndex parent = index.parent(); diff --git a/SOURCES/kdebase-workspace-4.3.98-platformplugin-widgetstyle4.patch b/SOURCES/kdebase-workspace-4.3.98-platformplugin-widgetstyle4.patch new file mode 100644 index 0000000..c6b4201 --- /dev/null +++ b/SOURCES/kdebase-workspace-4.3.98-platformplugin-widgetstyle4.patch @@ -0,0 +1,12 @@ +diff -ur kdebase-workspace-4.3.98/qguiplatformplugin_kde/qguiplatformplugin_kde.cpp kdebase-workspace-4.3.98-platformplugin-widgetstyle4/qguiplatformplugin_kde/qguiplatformplugin_kde.cpp +--- kdebase-workspace-4.3.98/qguiplatformplugin_kde/qguiplatformplugin_kde.cpp 2009-12-17 17:35:19.000000000 +0100 ++++ kdebase-workspace-4.3.98-platformplugin-widgetstyle4/qguiplatformplugin_kde/qguiplatformplugin_kde.cpp 2010-02-02 01:24:26.000000000 +0100 +@@ -159,7 +159,7 @@ + { + const QString defaultStyle = KStyle::defaultStyle(); + const KConfigGroup pConfig(KGlobal::config(), "General"); +- return pConfig.readEntry("widgetStyle", defaultStyle); ++ return pConfig.readEntry("widgetStyle4", pConfig.readEntry("widgetStyle", defaultStyle)); + } + virtual QPalette palette() + { diff --git a/SOURCES/kdebase-workspace-4.4.90-rootprivs.patch b/SOURCES/kdebase-workspace-4.4.90-rootprivs.patch new file mode 100644 index 0000000..f330491 --- /dev/null +++ b/SOURCES/kdebase-workspace-4.4.90-rootprivs.patch @@ -0,0 +1,47 @@ +diff -ur kdebase-workspace-4.4.90/systemsettings/core/ModuleView.cpp kdebase-workspace-4.4.90-rootprivs/systemsettings/core/ModuleView.cpp +--- kdebase-workspace-4.4.90/systemsettings/core/ModuleView.cpp 2010-06-24 18:28:10.000000000 +0200 ++++ kdebase-workspace-4.4.90-rootprivs/systemsettings/core/ModuleView.cpp 2010-06-26 00:47:30.000000000 +0200 +@@ -41,6 +41,7 @@ + #include + #include + #include ++#include + #include + + #include "MenuItem.h" +@@ -131,6 +132,35 @@ + return; + } + ++ { ++ MenuItem *menuItemPtr = menuItem.data( Qt::UserRole ).value(); ++ if ( menuItemPtr->service()->property( "X-KDE-RootOnly", QVariant::Bool ).toBool() ) { ++ QString kdesu = KStandardDirs::findExe( "kdesu" ); ++ QString cmd = menuItemPtr->service()->exec().trimmed(); ++ ++ /* Prepare the process to run the kcmshell */ ++ if ( cmd.left(5) == "kdesu" ) ++ { ++ cmd = cmd.remove(0,5).trimmed(); ++ ++ /* Remove all kdesu switches */ ++ while ( cmd.length() > 1 && cmd[ 0 ] == '-' ) ++ cmd = cmd.remove( 0, cmd.indexOf( ' ' ) ).trimmed(); ++ } ++ ++ if ( cmd.left(9) == "kcmshell4" ) ++ cmd = cmd.remove(0,9).trimmed(); ++ ++ QStringList args; ++ args << "-i" << QString( menuItemPtr->service()->icon() ) << "-c" << QString( "%1 %2 --lang %3" ).arg( KStandardDirs::locate("exe", "kcmshell4") ).arg( cmd ).arg( KGlobal::locale()->language() ); ++ ++ kDebug() << "Starting root module: " << args; ++ QProcess::startDetached( kdesu, args ); ++ ++ return; ++ } ++ } ++ + QList indexes; + for ( int done = 0; menuItem.model()->rowCount( menuItem ) > done; done = 1 + done ) { + indexes << menuItem.model()->index( done, 0, menuItem ); diff --git a/SOURCES/kdebase-workspace-4.4.92-xsession_errors_O_APPEND.patch b/SOURCES/kdebase-workspace-4.4.92-xsession_errors_O_APPEND.patch new file mode 100644 index 0000000..a7b27d8 --- /dev/null +++ b/SOURCES/kdebase-workspace-4.4.92-xsession_errors_O_APPEND.patch @@ -0,0 +1,12 @@ +diff -up kdebase-workspace-4.4.92/kdm/backend/client.c.xsession_errors_O_APPEND kdebase-workspace-4.4.92/kdm/backend/client.c +--- kdebase-workspace-4.4.92/kdm/backend/client.c.xsession_errors_O_APPEND 2010-07-06 01:54:30.000000000 -0500 ++++ kdebase-workspace-4.4.92/kdm/backend/client.c 2010-07-07 12:27:24.901922619 -0500 +@@ -1223,7 +1223,7 @@ createClientLog(const char *log) + if (!(lname = expandMacros(log, macros))) + exit(1); + unlink(lname); +- if ((lfd = open(lname, O_WRONLY|O_CREAT|O_EXCL, 0600)) >= 0) { ++ if ((lfd = open(lname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0600)) >= 0) { + dup2(lfd, 1); + dup2(lfd, 2); + close(lfd); diff --git a/SOURCES/kdebase-workspace-4.5.90-no_HAL2.patch b/SOURCES/kdebase-workspace-4.5.90-no_HAL2.patch new file mode 100644 index 0000000..d5af03c --- /dev/null +++ b/SOURCES/kdebase-workspace-4.5.90-no_HAL2.patch @@ -0,0 +1,29 @@ +diff -up kdebase-workspace-4.5.90/powerdevil/daemon/powerdevilbackendloader.cpp.no_HAL2 kdebase-workspace-4.5.90/powerdevil/daemon/powerdevilbackendloader.cpp +--- kdebase-workspace-4.5.90/powerdevil/daemon/powerdevilbackendloader.cpp.no_HAL2 2010-12-10 09:18:05.000000000 -0600 ++++ kdebase-workspace-4.5.90/powerdevil/daemon/powerdevilbackendloader.cpp 2010-12-22 13:36:36.476705060 -0600 +@@ -21,7 +21,7 @@ + #include "powerdevilbackendloader.h" + + #include "backends/upower/powerdevilupowerbackend.h" +-#include "backends/hal/powerdevilhalbackend.h" ++// #include "backends/hal/powerdevilhalbackend.h" + + #include + +@@ -39,6 +39,7 @@ BackendInterface* loadBackend(QObject *p + + kDebug() << "Failed!"; + ++#if 0 + // If we are here, try HAL + kDebug() << "Loading HAL backend..."; + if (PowerDevilHALBackend::isAvailable()) { +@@ -48,6 +49,8 @@ BackendInterface* loadBackend(QObject *p + + // Fail... + kDebug() << "Failed!"; ++#endif ++ + return 0; + } + diff --git a/SOURCES/kdebase-workspace-4.6.80-krdb.patch b/SOURCES/kdebase-workspace-4.6.80-krdb.patch new file mode 100644 index 0000000..696c095 --- /dev/null +++ b/SOURCES/kdebase-workspace-4.6.80-krdb.patch @@ -0,0 +1,11 @@ +diff -up kde-workspace-4.6.80/kcontrol/krdb/krdb.cpp.krdb kde-workspace-4.6.80/kcontrol/krdb/krdb.cpp +--- kde-workspace-4.6.80/kcontrol/krdb/krdb.cpp.krdb 2011-05-20 22:32:06.000000000 +0200 ++++ kde-workspace-4.6.80/kcontrol/krdb/krdb.cpp 2011-05-27 17:05:16.251235301 +0200 +@@ -259,6 +259,7 @@ static void createGtkrc( bool exportColo + if ( 2==version ) { // we should maybe check for MacOS settings here + t << endl; + t << "gtk-alternative-button-order = 1" << endl; ++ t << "gtk-fallback-icon-theme = \"gnome\"" << endl; + t << endl; + } + diff --git a/SOURCES/ksysguarddrc.5 b/SOURCES/ksysguarddrc.5 new file mode 100644 index 0000000..26757a7 --- /dev/null +++ b/SOURCES/ksysguarddrc.5 @@ -0,0 +1,55 @@ +.TH "ksysguarddrc" "5" "ksysguardd" "ksysguardd configuration file" +.SH NAME +ksysguarddrc \- ksysguardd configuration +.SH DESCRIPTION +.sp +ksysguardd uses a configuration file at /etc/ksysguarddrc. +.SH PARAMETERS +.sp +There are 2 sections of configuration in the ksysguardd configuration file: LogFiles, +Sensors. +.SH [LogFiles] OPTIONS +.sp +.in +the list of all available logfiles +.in +messages:/var/log/messages,kern:/var/log/kern.log,daemon:/var/log/daemon.log,syslog:/var/log/syslog,auth:/var/log/auth.log +.SH [Sensors] OPTIONS +.sp +.in +Sensors: the list of all accessible sensors +.in + Apm Advanced Power Management +.in + Acpi Advanced Configuration and Power Interface +.in + CpuInfo CPU-Clock information +.in + DiskStat partition space. Data comes from mtab, getmntent() and statfs() +.in + DiskStats disk throughput. Data comes from /etc/diskstats +.in + LmSensors information about motherboard and CPU +.in + LoadAvg system load values +.in + LogFile local logfiles +.in + Memory physical memory and swap +.in + NetDev throughput of network interfaces +.in + NetStat number of TCP/UDP/ICMP/Unix sockets +.in + ProcessList current processes +.in + SoftRaid Monitors software raid devices. See mdadm. +.in + Stat interrupts, CPU and disk throughput. Data comes from /etc/stat +.in + Uptime System uptime. Data comes from /etc/uptime +.in +Sensors=ProcessList,Memory,Stat,NetDev,NetStat,Apm,Acpi,CpuInfo,LoadAvg,LmSensors,DiskStat,LogFile,DiskStats,Uptime,SoftRaid +.SH FILES +.sp +/etc/ksysguarddrc diff --git a/SOURCES/powerdevil-upower-0.99.patch b/SOURCES/powerdevil-upower-0.99.patch new file mode 100644 index 0000000..c3ac47a --- /dev/null +++ b/SOURCES/powerdevil-upower-0.99.patch @@ -0,0 +1,71 @@ +diff --git a/powerdevil/daemon/backends/upower/powerdevilupowerbackend.cpp b/powerdevil/daemon/backends/upower/powerdevilupowerbackend.cpp +index cc20dc7..297b020 100644 +--- a/powerdevil/daemon/backends/upower/powerdevilupowerbackend.cpp ++++ b/powerdevil/daemon/backends/upower/powerdevilupowerbackend.cpp +@@ -75,7 +75,7 @@ bool checkSystemdVersion(uint requiredVersion) + + PowerDevilUPowerBackend::PowerDevilUPowerBackend(QObject* parent) + : BackendInterface(parent), +- m_brightnessControl(0), m_kbdMaxBrightness(0), ++ m_displayDevice(0), m_brightnessControl(0), m_kbdMaxBrightness(0), + m_lidIsPresent(false), m_lidIsClosed(false), m_onBattery(false) + { + +@@ -451,6 +451,14 @@ void PowerDevilUPowerBackend::enumerateDevices() + m_devices.insert(device.path(), upowerDevice); + } + ++ QDBusReply reply = m_upowerInterface->call("GetDisplayDevice"); ++ if (reply.isValid()) { ++ const QString path = reply.value().path(); ++ if (!path.isEmpty() && path != QLatin1String("/")) { ++ m_displayDevice = new OrgFreedesktopUPowerDeviceInterface(UPOWER_SERVICE, path, QDBusConnection::systemBus(), this); ++ } ++ } ++ + updateDeviceProps(); + + if (m_onBattery) +@@ -500,14 +508,22 @@ void PowerDevilUPowerBackend::updateDeviceProps() + { + qlonglong remainingTime = 0; + +- foreach(OrgFreedesktopUPowerDeviceInterface * upowerDevice, m_devices) { +- const uint type = upowerDevice->type(); +- if (( type == 2 || type == 3) && upowerDevice->powerSupply()) { +- const uint state = upowerDevice->state(); +- if (state == 1) // charging +- remainingTime += upowerDevice->timeToFull(); +- else if (state == 2) //discharging +- remainingTime += upowerDevice->timeToEmpty(); ++ if (m_displayDevice && m_displayDevice->isPresent()) { ++ const uint state = m_displayDevice->state(); ++ if (state == 1) // charging ++ remainingTime = m_displayDevice->timeToFull(); ++ else if (state == 2) //discharging ++ remainingTime = m_displayDevice->timeToEmpty(); ++ } else { ++ foreach(OrgFreedesktopUPowerDeviceInterface * upowerDevice, m_devices) { ++ const uint type = upowerDevice->type(); ++ if (( type == 2 || type == 3) && upowerDevice->powerSupply()) { ++ const uint state = upowerDevice->state(); ++ if (state == 1) // charging ++ remainingTime += upowerDevice->timeToFull(); ++ else if (state == 2) //discharging ++ remainingTime += upowerDevice->timeToEmpty(); ++ } + } + } + +diff --git a/powerdevil/daemon/backends/upower/powerdevilupowerbackend.h b/powerdevil/daemon/backends/upower/powerdevilupowerbackend.h +index c6563b0..14f4c5e 100644 +--- a/powerdevil/daemon/backends/upower/powerdevilupowerbackend.h ++++ b/powerdevil/daemon/backends/upower/powerdevilupowerbackend.h +@@ -84,6 +84,7 @@ private slots: + private: + // upower devices + QMap m_devices; ++ OrgFreedesktopUPowerDeviceInterface *m_displayDevice; + + // brightness + QMap m_cachedBrightnessMap; diff --git a/SOURCES/startkde.cmake b/SOURCES/startkde.cmake new file mode 100644 index 0000000..11da90f --- /dev/null +++ b/SOURCES/startkde.cmake @@ -0,0 +1,357 @@ +#!/bin/sh +# +# DEFAULT KDE STARTUP SCRIPT ( @KDE4WORKSPACE_VERSION@ ) +# + +if test "x$1" = x--failsafe; then + KDE_FAILSAFE=1 # General failsafe flag + KWIN_COMPOSE=N # Disable KWin's compositing + export KWIN_COMPOSE KDE_FAILSAFE +fi + +# When the X server dies we get a HUP signal from xinit. We must ignore it +# because we still need to do some cleanup. +trap 'echo GOT SIGHUP' HUP + +# we have to unset this for Darwin since it will screw up KDE's dynamic-loading +unset DYLD_FORCE_FLAT_NAMESPACE + +qdbus=qdbus + +# See http://bugzilla.redhat.com/537609 , a naive attempt to drop dep +# on xmessage and allow alternatives like zenity. +message() { + xmessage -geometry 500x100 "$1" > /dev/null 2>/dev/null || \ + zenity --info --text="$1" > /dev/null 2>/dev/null ||: + return $? +} + +# Check if a KDE session already is running and whether it's possible to connect to X +kcheckrunning +kcheckrunning_result=$? +if test $kcheckrunning_result -eq 0 ; then + echo "KDE seems to be already running on this display." + message "KDE seems to be already running on this display." > /dev/null 2>/dev/null + exit 1 +elif test $kcheckrunning_result -eq 2 ; then + echo "\$DISPLAY is not set or cannot connect to the X server." + exit 1 +fi + +# Boot sequence: +# +# kdeinit is used to fork off processes which improves memory usage +# and startup time. +# +# * kdeinit starts klauncher first. +# * Then kded is started. kded is responsible for keeping the sycoca +# database up to date. When an up to date database is present it goes +# into the background and the startup continues. +# * Then kdeinit starts kcminit. kcminit performs initialisation of +# certain devices according to the user's settings +# +# * Then ksmserver is started which takes control of the rest of the startup sequence + +# The user's personal KDE directory is usually ~/.kde, but this setting +# may be overridden by setting KDEHOME. + +kdehome=$HOME/@KDE_DEFAULT_HOME@ +test -n "$KDEHOME" && kdehome=`echo "$KDEHOME"|sed "s,^~/,$HOME/,"` + +# see kstartupconfig source for usage +mkdir -m 700 -p $kdehome +mkdir -m 700 -p $kdehome/share +mkdir -m 700 -p $kdehome/share/config +cat >$kdehome/share/config/startupconfigkeys </env/*.sh and /env/*.sh +# (where is $KDEHOME or ~/.kde, and is where KDE is installed) +# +# This is where you can define environment variables that will be available to +# all KDE programs, so this is where you can run agents using e.g. eval `ssh-agent` +# or eval `gpg-agent --daemon`. +# Note: if you do that, you should also put "ssh-agent -k" as a shutdown script +# +# (see end of this file). +# For anything else (that doesn't set env vars, or that needs a window manager), +# better use the Autostart folder. + +libpath=`kde4-config --path lib | tr : '\n'` +envpath=/etc/kde/env/ + +for prefix in `echo "$libpath" | sed -n -e 's,/lib[^/]*/,/env/,p'` $envpath ; do + for file in "$prefix"*.sh; do + test -r "$file" && . "$file" + done +done + +# Set the path for Qt plugins provided by KDE +QT_PLUGIN_PATH=${QT_PLUGIN_PATH+$QT_PLUGIN_PATH:}`kde4-config --path qtplugins` +export QT_PLUGIN_PATH + +# Set a left cursor instead of the standard X11 "X" cursor, since I've heard +# from some users that they're confused and don't know what to do. This is +# especially necessary on slow machines, where starting KDE takes one or two +# minutes until anything appears on the screen. +# +# If the user has overwritten fonts, the cursor font may be different now +# so don't move this up. +# +xsetroot -cursor_name left_ptr + +# Get Ghostscript to look into user's KDE fonts dir for additional Fontmap +if test -n "$GS_LIB" ; then + GS_LIB=$usr_fdir:$GS_LIB + export GS_LIB +else + GS_LIB=$usr_fdir + export GS_LIB +fi + +lnusertemp=`kde4-config --path exe --locate lnusertemp` +if test -z "$lnusertemp"; then + # Startup error + echo 'startkde: ERROR: Could not locate lnusertemp in '`kde4-config --path exe` 1>&2 +fi + +# Link "tmp" "socket" and "cache" resources to directory in /tmp +# Creates: +# - a directory /tmp/kde-$USER and links $KDEHOME/tmp-$HOSTNAME to it. +# - a directory /tmp/ksocket-$USER and links $KDEHOME/socket-$HOSTNAME to it. +# - a directory /var/tmp/kdecache-$USER and links $KDEHOME/cache-$HOSTNAME to it. +# Note: temporary locations can be overriden through the KDETMP and KDEVARTMP +# environment variables +for resource in tmp cache socket; do + if "$lnusertemp" $resource >/dev/null; then + : # ok + else + echo 'startkde: Call to lnusertemp failed (temporary directories full?). Check your installation.' 1>&2 + test -n "$ksplash_pid" && kill "$ksplash_pid" 2>/dev/null + message "Call to lnusertemp failed (temporary directories full?). Check your installation." + exit 1 + fi +done + +# In case of dcop sockets left by a previous session, cleanup +#dcopserver_shutdown + +echo 'startkde: Starting up...' 1>&2 + +# Make sure that D-Bus is running +# D-Bus autolaunch is broken +if test -z "$DBUS_SESSION_BUS_ADDRESS" ; then + eval `dbus-launch --sh-syntax --exit-with-session` +fi +if $qdbus >/dev/null 2>/dev/null; then + : # ok +else + echo 'startkde: Could not start D-Bus. Can you call qdbus?' 1>&2 + test -n "$ksplash_pid" && kill "$ksplash_pid" 2>/dev/null + message "Could not start D-Bus. Can you call qdbus?" + exit 1 +fi + + +# Mark that full KDE session is running (e.g. Konqueror preloading works only +# with full KDE running). The KDE_FULL_SESSION property can be detected by +# any X client connected to the same X session, even if not launched +# directly from the KDE session but e.g. using "ssh -X", kdesu. $KDE_FULL_SESSION +# however guarantees that the application is launched in the same environment +# like the KDE session and that e.g. KDE utilities/libraries are available. +# KDE_FULL_SESSION property is also only available since KDE 3.5.5. +# The matching tests are: +# For $KDE_FULL_SESSION: +# if test -n "$KDE_FULL_SESSION"; then ... whatever +# For KDE_FULL_SESSION property: +# xprop -root | grep "^KDE_FULL_SESSION" >/dev/null 2>/dev/null +# if test $? -eq 0; then ... whatever +# +# Additionally there is (since KDE 3.5.7) $KDE_SESSION_UID with the uid +# of the user running the KDE session. It should be rarely needed (e.g. +# after sudo to prevent desktop-wide functionality in the new user's kded). +# +# Since KDE4 there is also KDE_SESSION_VERSION, containing the major version number. +# Note that this didn't exist in KDE3, which can be detected by its absense and +# the presence of KDE_FULL_SESSION. +# +KDE_FULL_SESSION=true +export KDE_FULL_SESSION +xprop -root -f KDE_FULL_SESSION 8t -set KDE_FULL_SESSION true + +KDE_SESSION_VERSION=4 +export KDE_SESSION_VERSION +xprop -root -f KDE_SESSION_VERSION 32c -set KDE_SESSION_VERSION 4 + +KDE_SESSION_UID=`id -ru` +export KDE_SESSION_UID + +XDG_CURRENT_DESKTOP=KDE +export XDG_CURRENT_DESKTOP + +# At this point all the environment is ready, let's send it to kwalletd if running +if test -n "$PAM_KWALLET_LOGIN" ; then + env | socat STDIN UNIX-CONNECT:$PAM_KWALLET_LOGIN +fi + +@KDE4_LIBEXEC_INSTALL_DIR@/start_kdeinit_wrapper +kcminit_startup +if test $? -ne 0; then + # Startup error + echo 'startkde: Could not start kdeinit4. Check your installation.' 1>&2 + test -n "$ksplash_pid" && kill "$ksplash_pid" 2>/dev/null + message "Could not start kdeinit4. Check your installation." + exit 1 +fi + +# finally, give the session control to the session manager +# see kdebase/ksmserver for the description of the rest of the startup sequence +# if the KDEWM environment variable has been set, then it will be used as KDE's +# window manager instead of kwin. +# if KDEWM is not set, ksmserver will ensure kwin is started. +# kwrapper4 is used to reduce startup time and memory usage +# kwrapper4 does not return useful error codes such as the exit code of ksmserver. +# We only check for 255 which means that the ksmserver process could not be +# started, any problems thereafter, e.g. ksmserver failing to initialize, +# will remain undetected. +test -n "$KDEWM" && KDEWM="--windowmanager $KDEWM" +# If the session should be locked from the start (locked autologin), +# lock now and do the rest of the KDE startup underneath the locker. +KSMSERVEROPTIONS="" +test -n "$dl" && KSMSERVEROPTIONS=" --lockscreen" +kwrapper4 ksmserver $KDEWM $KSMSERVEROPTIONS +if test $? -eq 255; then + # Startup error + echo 'startkde: Could not start ksmserver. Check your installation.' 1>&2 + test -n "$ksplash_pid" && kill "$ksplash_pid" 2>/dev/null + message "Could not start ksmserver. Check your installation." +fi + +wait_drkonqi=`kreadconfig --file startkderc --group WaitForDrKonqi --key Enabled --default true` + +if test x"$wait_drkonqi"x = x"true"x ; then + # wait for remaining drkonqi instances with timeout (in seconds) + wait_drkonqi_timeout=`kreadconfig --file startkderc --group WaitForDrKonqi --key Timeout --default 900` + wait_drkonqi_counter=0 + while $qdbus | grep "^[^w]*org.kde.drkonqi" > /dev/null ; do + sleep 5 + wait_drkonqi_counter=$((wait_drkonqi_counter+5)) + if test "$wait_drkonqi_counter" -ge "$wait_drkonqi_timeout" ; then + # ask remaining drkonqis to die in a graceful way + $qdbus | grep 'org.kde.drkonqi-' | while read address ; do + $qdbus "$address" "/MainApplication" "quit" + done + break + fi + done +fi + +echo 'startkde: Shutting down...' 1>&2 +# just in case +test -n "$ksplash_pid" && kill "$ksplash_pid" 2>/dev/null + +# Clean up +kdeinit4_shutdown +# KDE3 support +kde3 kdeinit_shutdown 2>/dev/null +kde3 dcopserver_shutdown --wait 2>/dev/null + +echo 'startkde: Running shutdown scripts...' 1>&2 + +# Run scripts found in $KDEDIRS/shutdown +shutdownpath=/etc/kde/shutdown/ +for prefix in `echo "$libpath" | sed -n -e 's,/lib[^/]*/,/shutdown/,p'` $shutdownpath; do + for file in `ls "$prefix" 2> /dev/null | egrep -v '(~|\.bak)$'`; do + test -x "$prefix$file" && "$prefix$file" + done +done + +unset KDE_FULL_SESSION +xprop -root -remove KDE_FULL_SESSION +unset KDE_SESSION_VERSION +xprop -root -remove KDE_SESSION_VERSION +unset KDE_SESSION_UID + +echo 'startkde: Done.' 1>&2 diff --git a/SPECS/kde-workspace.spec b/SPECS/kde-workspace.spec new file mode 100755 index 0000000..443494a --- /dev/null +++ b/SPECS/kde-workspace.spec @@ -0,0 +1,3290 @@ +%if 0%{?fedora} +%define gpsd 1 +%endif +%if 0%{?fedora} || 0%{?epel} +%define webkit 1 +%define libqalculate 1 +%endif + +%if 0%{?fedora} < 20 || 0%{?rhel} <= 7 +%define nepomuk 1 +%endif + +%if 0%{?fedora} > 18 || 0%{?rhel} > 6 +# Require kscreen, omit kcontrol/randr bits +%define kscreen 1 +%endif + +%if 0%{?fedora} > 17 || 0%{?rhel} > 6 +%define systemd_login1 1 +%endif + +Summary: KDE Workspace +Name: kde-workspace +Version: 4.11.19 +Release: 14%{?dist} +License: GPLv2 +URL: https://projects.kde.org/projects/kde/kde-workspace +Source0: http://download.kde.org/stable/applications/src/14.12.1/kde-workspace-%{version}.tar.xz + +# create missing manpage +Source1: ksysguarddrc.5 + +# modified version of startkde.cmake, the template for startkde +# not shipped as a patch because we have been burned too often by new upstream +# additions that just break things for us +Source2: startkde.cmake + +# hack/workaround to invalidate (delete) plasma pixmap cache on upgrade +Source10: fedora-plasma-cache.sh + +# add konsole menuitem +# FIXME? only show menu when/if konsole is installed? then we can drop the hard-dep +Patch2: kde-workspace-4.9.90-plasma_konsole.patch + +# RH/Fedora-specific: VT numbers on fast user switching +# could be handled dynamically eventually +Patch3: kde-workspace-4.10.4-new-session-vt-numbers.patch + +# RH/Fedora-specific: Force kdm and kdm_greet to be hardened +Patch4: kde-workspace-4.10.4-kdm-harden.patch + +# 441062: packagekit tools do not show icons correctly on KDE +Patch7: kdebase-workspace-4.6.80-krdb.patch + +# correct quoting +Patch8: kdebase-workspace-4.2.85-klipper-url.patch + +# 434824: KDE4 System Settings - No Method To Enter Administrative Mode +Patch9: kdebase-workspace-4.4.90-rootprivs.patch + +# kio_sysinfo based on OpenSUSE's patch +Patch15: kdebase-workspace-4.3.75-kio_sysinfo.patch + +# TODO: verify this still works (does not seem to for me) -- rex +Patch16: kde-workspace-4.10.90-battery-plasmoid-showremainingtime.patch + +# allow adding a "Leave..." button which brings up the complete shutdown dialog +# to the classic menu (as in KDE <= 4.2.x); the default is still the upstream +# default Leave submenu +Patch17: kde-workspace-4.7.80-classicmenu-logout.patch + +# SUSE kudos! plymouth fixed by Laercio de Sousa and Stefan Brüns +Patch19: kde-workspace-4.11.1-kdm_plymouth081.patch +Patch20: kdebase-workspace-4.4.92-xsession_errors_O_APPEND.patch + +# support the widgetStyle4 hack in the Qt KDE platform plugin +Patch21: kdebase-workspace-4.3.98-platformplugin-widgetstyle4.patch + +# revert patch adding broken browser launcher +# https://projects.kde.org/projects/kde/kde-workspace/repository/revisions/2bbbbdd8fe5a38ae27bab44c9515b2ba78f75277 +# https://bugzilla.redhat.com/show_bug.cgi?id=747982 +# https://bugs.kde.org/show_bug.cgi?id=284628 +Patch25: kde-workspace-4.10.3-bz#747982-launchers.patch + +# add org.kde.ktp-presence applet to default systray +Patch26: kde-workspace-4.10.2-systray_org.kde.ktp-presence.patch + +# add support for automatic multi-seat provided by systemd using existing reserve seats in KDM +# needs having ServerCmd=/usr/lib/systemd/systemd-multi-seat-x set in /etc/kde/kdm/kdmrc +Patch27: kde-workspace-4.11.1-kdm-logind-multiseat.patch + +# drop supplemental groups, if we don't call setgroups or initgroups then the +# ksysguardd, kdm_greet process will inherit a random set of supplemental groups from parent process +Patch28: kde-workspace-4.10.5-ksysguardd-setgroups.patch +Patch29: kde-workspace-4.10.5-initgroups.patch + +# hide generalWidget, jovie is disable +Patch30: kde-workspace-4.10.5-bz#1060058.patch + +# apps fail in KDE with unknown color name BACKGROUND +Patch31: kde-workspace-4.10.5-bz#1043686-cpp.patch + +# avoid conflict between kcm_colors 4 and plasma-desktop 5 +Patch32: kde-workspace-4.11.16-colorschemes-kde4.patch + +## upstreamable patches: +# "keyboard stops working", https://bugs.kde.org/show_bug.cgi?id=171685#c135 +Patch50: kde-workspace-4.10.90-kde#171685.patch + +# add apper to kickoff favorites +# Apper is hard to find, http://bugzilla.redhat.com/850445 +Patch51: kde-workspace-4.9.0-add_apper_to_kickoff_favorites.patch + +# use /etc/login.defs to define a 'system' account instead of hard-coding 500 +Patch52: kde-workspace-4.8.2-bz#732830-login.patch + +# kdm overwrites ~/.Xauthority with wrong SELinux context on logout +# http://bugzilla.redhat.com/567914 +# http://bugs.kde.org/242065 +Patch53: kde-workspace-4.7.95-kdm_xauth.patch + +# don't modify font settings on load (without explicit save) +# http://bugs.kde.org/105797 +Patch54: kde-workspace-kcm_fonts_dont_change_on_load.patch + +# support BUILD_KCM_RANDR (default ON) option +Patch55: kde-workspace-4.10.2-BUILD_KCM_RANDR.patch + +# kdm (local) ipv6 +# https://bugzilla.redhat.com/show_bug.cgi?id=1187957 +Patch56: kde-workspace-kdm_local_ipv6.patch + +# pam/systemd bogosity: kdm restart/shutdown does not work +# http://bugzilla.redhat.com/796969 +Patch57: kde-workspace-4.8.0-bug796969.patch + +# use backlight actual_brightness interface +Patch58: kde-workspace-4.11.0-backlight_actual_brightness.patch + +# https://bugs.kde.org/show_bug.cgi?id=330773#c5 +# bbcukmet: update to BBC's new json-based search and modified xml +Patch59: kde-workspace-4.11.7-weather-fix-bbcukmet.patch + +# https://bugs.kde.org/show_bug.cgi?id=330773#c6 +# bbcukmet: handle cases where min. or max. temperatures are not reported +Patch60: kde-workspace-4.11.7-weather-fix-bbcukmet-temp.patch + +# fix some warnings from coverity scan +Patch64: kde-workspace-4.10.5-coverity-scan.patch + +# https://bugs.kde.org/show_bug.cgi?id=330773#c16 +# bbcukmet: fix typo in the condition->icon matching ("clar sky" -> "clear sky") +Patch65: kde-workspace-4.11.7-weather-fix-bbcukmet-clear-sky.patch + +# https://bugs.kde.org/show_bug.cgi?id=332392 +# bbcukmet: fix a crash (#1079296/kde#332392) and improve error handling +Patch66: kde-workspace-4.11.7-weather-fix-bbcukmet-crash-kde#332392.patch + +# Get rid of dependency on kdepimlibs 4.11 +Patch67: kde-workspace-4.11-remove-dependency-on-kdepimlibs-4.11.patch + +# Fix coverity scan issues +Patch68: kde-workspace-4.11.19-coverity-scan-fixes.patch + +# Fix grouping of tasks in taskmanager applet +# Bug 1348917 - Display problem with applications grouped by type (> 20 programs) in KDE4 +Patch69: kde-workspace-taskmanager-grouping.patch + +# Fix unlocking of screenlocker +# Bug 1333441 - System not unlocking on extended monitors when using screensaver +Patch70: kde-workspace-kscreenlocker-greeter-unlock-just-once.patch + +# Bug 1568853 - CVE-2018-6790 kde-workspace: Missing sanitization of notifications allows to leak client IP address via IMG element +Patch71: kde-workspace-sanitise-notification-html.patch + +# Bug 1611762 - ksysguardd: "internal buffer too small to read /proc/cpuinfo" when running with many CPUs +Patch72: kde-workspace-ksysguard-increase-cpu-buffer.patch + +# Bug 1677641 - Plastik theme shows defunct close button on non deletable gtk window +Patch73: kde-workspace-plastik-do-not-show-disabled-buttons.patch + +# Bug 1698048 - KDE Task Manager always groups programs even when 'Only when the taskbar is full' is checked +Patch74: kde-workspace-taskmanager-check-if-full-when-item-from-group-is-removed.patch + +## upstream patches +Patch101: kde-workspace-4.10-bz#921742.patch +Patch104: kde-workspace-4.10.x-bz#1001708.patch +Patch105: kde-workspace-4.10.x-bz#1001727.patch +Patch106: kde-workspace-4.10.5-rhbz990146.patch +Patch109: kde-workspace-4.11-bz#1090492.patch + +## plasma active patches + +## Fedora specific patches +## HAL-ectomy +Patch200: kde-workspace-4.7.80-no_HAL.patch +Patch210: kdebase-workspace-4.5.90-no_HAL2.patch + +# rhel patches +Patch300: kde-workspace-4.8.3-webkit.patch +Patch301: kde-workspace-4.10.5-bz#1063302-branding.patch +Patch302: kde-workspace-exclude_kdm.patch +Patch303: powerdevil-upower-0.99.patch +Patch304: kde-workspace-revert-improve-systemtray-on-hdpi-displays.patch +Patch305: kde-workspace-close-menu-on-closed-task.patch +Patch306: kde-workspace-4.11-fix-loading-get-hot-new-stuff.patch +Patch307: kde-workspace-disable-plasma-screensaver.patch + +## trunk (Plasma 5) patches + +# pkg rename +Obsoletes: kdebase-workspace < 4.7.97-10 +Provides: kdebase-workspace = %{version}-%{release} + +Requires: polkit-kde +%if 0%{?systemd_login1} +Requires: systemd +%endif + +%if ! 0%{?akonadi_subpkg} +Obsoletes: %{name}-akonadi < %{version}-%{release} +Provides: %{name}-akonadi = %{version}-%{release} +Provides: plasma-dataengine-akonadi = %{version}-%{release} +Provides: plasma-dataengine-calendar = %{version}-%{release} +%endif + +# kwin apparently provides this internally, kwin/scripting/scripting.cpp +# our scripts can't grok it automatically +Provides: plasma4(scriptengine-declarativescript) +Provides: plasma-scriptengine-declarativescript = %{version}-%{release} + +# http://bugzilla.redhat.com/605675 +Provides: firstboot(windowmanager) = kwin + +# kdmtheme's functionality is provided here +Obsoletes: kdmtheme < 1.3 + +BuildRequires: desktop-file-utils +BuildRequires: kdelibs4-devel >= 4.14.4 +%if 0%{?webkit} +BuildRequires: kdelibs4-webkit-devel +%endif +BuildRequires: kdepimlibs-devel >= 4.10.5 +BuildRequires: kactivities-devel +%if 0%{?nepomuk} +BuildRequires: nepomuk-core-devel >= 4.10.5 +BuildRequires: pkgconfig(soprano) +%else +BuildConflicts: nepomuk-core-devel +%endif +BuildRequires: libjpeg-devel +BuildRequires: libutempter-devel +%ifnarch s390 s390x +BuildRequires: lm_sensors-devel +BuildRequires: pkgconfig(libraw1394) +%endif +BuildRequires: pam-devel +%if 0%{?fedora} +BuildRequires: prison-devel +BuildRequires: pkgconfig(libdmtx) +%endif +BuildRequires: pkgconfig(akonadi) +BuildRequires: pkgconfig(bluez) +BuildRequires: pkgconfig(dbusmenu-qt) +BuildRequires: pkgconfig(gl) +BuildRequires: pkgconfig(glib-2.0) +%if 0%{?gpsd} +BuildRequires: pkgconfig(libgps) +%endif +BuildRequires: pkgconfig(libpci) +BuildRequires: pkgconfig(libpng) +%if 0%{?libqalculate} +BuildRequires: pkgconfig(libqalculate) +%endif +BuildRequires: pkgconfig(libstreamanalyzer) +# used for the Logitech mouse KCM, disabled until #399931 is fixed +# BuildRequires: pkgconfig(libusb) +BuildRequires: pkgconfig(libudev) +BuildRequires: pkgconfig(libxklavier) +# added libnm-glib to workaround https://bugzilla.redhat.com/show_bug.cgi?id=685442 +BuildRequires: pkgconfig(NetworkManager) pkgconfig(libnm-glib) +BuildRequires: pkgconfig(polkit-qt-1) +BuildRequires: pkgconfig(qimageblitz) +BuildRequires: pkgconfig(QJson) +BuildRequires: pkgconfig(xau) +BuildRequires: pkgconfig(xcb) +BuildRequires: pkgconfig(xcb-icccm) +BuildRequires: pkgconfig(xcb-image) +BuildRequires: pkgconfig(xcb-keysyms) +BuildRequires: pkgconfig(xcb-renderutil) +BuildRequires: pkgconfig(xdmcp) +BuildRequires: pkgconfig(xres) +# kwin +BuildRequires: pkgconfig(xcomposite) pkgconfig(xdamage) pkgconfig(xrender) +BuildRequires: pkgconfig(gl) pkgconfig(glu) +# kwin-gles +%if 0%{?fedora} || 0%{?rhel} > 6 +%define gles 1 +BuildRequires: pkgconfig(glesv2) pkgconfig(egl) +%if 0%{?fedora} +BuildRequires: pkgconfig(wayland-client) pkgconfig(wayland-egl) pkgconfig(wayland-server) +%endif +%endif +BuildRequires: python2-devel + +Obsoletes: kdebase-workspace-googlegadgets < 4.5.80-7 +Obsoletes: plasma-scriptengine-googlegadgets < %{version}-%{release} + +Requires: konsole +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: kcm_colors = %{version}-%{release} +%{?_kde4_macros_api:Requires: kde4-macros(api) = %{_kde4_macros_api} } +Requires: kde-runtime >= 4.10.5 + +Obsoletes: kded_randrmonitor < 4.9.98-5 +%if 0%{?kscreen} +Requires: kscreen +%endif + +Requires: cpp +# for kcm_keyboard +Requires: iso-codes +# activity manager +Requires: kactivities +# for kscreenlocker +Requires: kgreeter-plugins = %{version}-%{release} +# startkde references: dbus-launch df mkdir test xmessage xprop xrandr xrdb xset xsetroot +Requires: coreutils +Requires: dbus-x11 +# See http://bugzilla.redhat.com/537609 +#Requires: xorg-x11-apps +Requires: xorg-x11-utils +Requires: xorg-x11-server-utils + +# Make sure we have kwin, but don't care whether it's our kwin, or kwin5 +Requires: kwin + +Requires: khotkeys +Requires: kmenuedit +Requires: kinfocenter + +%define default_face_icon default1.png +%if 0%{?fedora} || 0%{?rhel} > 6 +Requires: kde-settings-ksplash +Requires: kde-settings-plasma +%endif + +%description +The KDE Workspace consists of what is the desktop of the +KDE Desktop Environment. + +This package contains: +* khotkeys (a hotkey daemon) +* klipper (a cut & paste history utility) +* kmenuedit (the menu editor) +* krunner (a command run interface) +* kwin (the window manager of KDE) +* plasma (the KDE desktop, panels and widgets workspace application) +* systemsettings (the configuration editor) +%{!?kscreen:* krandrtray (resize and rotate X screens)} + +%package devel +Summary: Development files for %{name} +Obsoletes: kdebase-workspace-devel < 4.7.97-10 +Provides: kdebase-workspace-devel = %{version}-%{release} +Provides: solid-bluetooth-devel = %{version}-%{release} +Requires: ksysguard-libs%{?_isa} = %{version}-%{release} +Requires: kwin-libs%{?_isa} = %{version}-%{release} +%if 0%{?gles} +Requires: kwin-gles-libs%{?_isa} = %{version}-%{release} +%endif +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +%if 0%{?akonadi_subpkg} +Requires: %{name}-akonadi%{?_isa} = %{version}-%{release} +%endif +Requires: kdelibs4-devel +%description devel +%{summary}. + +%package libs +Summary: Runtime libraries for %{name} +Obsoletes: kdebase-workspace-libs < 4.7.97-10 +Provides: kdebase-workspace-libs = %{version}-%{release} +Provides: kdebase-workspace-libs%{?_isa} = %{version}-%{release} +Provides: solid-bluetooth = %{version}-%{release} +Requires: libkworkspace%{?_isa} = %{version}-%{release} +%{?kdelibs4_requires} +# at least while oyxgen style is default +# make dep unversioned to allow plasma5's oxygen to replace it +Requires: kde-style-oxygen%{?_isa} +%description libs +%{summary}. + +%package ksplash-themes +Summary: KDE ksplash themes +Obsoletes: kdebase-workspace-ksplash-themes < 4.7.97-10 +Provides: kdebase-workspace-ksplash-themes = %{version}-%{release} +Requires: %{name} = %{version}-%{release} +BuildArch: noarch +%description ksplash-themes +%{summary}, including Horos and Minimalistic. + +%package -n kcm_colors +Summary: Colors KDE Control Module +Conflicts: kde-workspace < 4.8.0-2 +Requires: kde-runtime >= 4.10.5 +%description -n kcm_colors +The Color Selection module is comprised of several sections: +* The Scheme tab, used to manage schemes +* The Options tab, used to change the options of the current scheme +* The Colors tab, used to change the colors of the current scheme +* The state effects tabs (Inactive, Disabled) + +%package -n kdm +Summary: The KDE login manager +Provides: kdebase-kdm = %{version}-%{release} +Provides: service(graphical-login) = kdm +Requires: kgreeter-plugins = %{version}-%{release} +Requires: libkworkspace%{?_isa} = %{version}-%{release} +Requires: kde-settings-kdm +%description -n kdm +KDM provides the graphical login screen, shown shortly after boot up, +log out, and when user switching. + +%package -n kdm-themes +Summary: KDM Themes +group: User Interface/X +Obsoletes: kdm < 4.7.3-9 +Requires: kdm = %{version}-%{release} +# http://bugzilla.redhat.com/753409 +# http://bugzilla.redhat.com/784389 +Requires: kde-wallpapers +BuildArch: noarch +%description -n kdm-themes +A collection of kdm themes, including: circles, horos, oxygen, oxygen-air, +as well as stripes wallpaper. + +%package -n kgreeter-plugins +Summary: KDE Greeter Plugin Components +# kgreet_* plugins moved +Conflicts: kdm < 4.6.90-4 +Conflicts: kde-workspace < 4.7.80-3 +%description -n kgreeter-plugins +%{summary} that are needed by KDM and Screensaver unlocking. + +%package -n ksysguard +Summary: KDE System Monitor +Requires: ksysguardd = %{version}-%{release} +Requires: ksysguard-libs%{?_isa} = %{version}-%{release} +%description -n ksysguard +%{summary}. + +%package -n ksysguard-libs +Summary: Runtime libraries for ksysguard +# when spilt occurred +Conflicts: kdebase-workspace-libs < 4.7.2-2 +%{?kdelibs4_requires} +%description -n ksysguard-libs +%{summary}. + +%package -n ksysguardd +Summary: Performance monitor daemon +%description -n ksysguardd +%{summary}. + +%package -n kwin +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +# When the kwin subpackage was split +Conflicts: kde-workspace <= 4.11.14-1 +Summary: KDE Window Manager + +%description -n kwin +%{summary}. + +%package -n kwin-libs +Summary: Runtime kwin libraries +# When kwin-libs subpackage was split +Conflicts: %{name}-libs%{?_isa} <= 4.11.14-1 +%description -n kwin-libs +%{summary}. + +%package -n kwin-gles +Summary: KWin built to support GLES +# for libkwin* and friends +Requires: kwin-libs%{?_isa} = %{version}-%{release} +Requires: kwin = %{version}-%{release} +%description -n kwin-gles +%{summary}. + +%package -n kwin-gles-libs +Summary: Runtime libraries for kwin-gles +%description -n kwin-gles-libs +%{summary}. + +%package -n libkworkspace +Summary: Runtime libkworkspace library +# when spilt occurred +Conflicts: kdebase-workspace-libs < 4.7.2-2 +Obsoletes: kdebase-workspace-libs-kworkspace < 4.7.2-3 +%{?kdelibs4_requires} +%description -n libkworkspace +%{summary}. + +%package -n kde-style-oxygen +Summary: Oxygen widget style for KDE +# when split from kde-workspace(-libs) +Conflicts: kde-workspace-libs < 4.11.2-2 +%description -n kde-style-oxygen +%{summary}. + +%package -n kdeclassic-cursor-theme +Summary: KDE Classic cursor theme +BuildArch: noarch +%description -n kdeclassic-cursor-theme +%{summary}. + +%package -n oxygen-cursor-themes +Summary: Oxygen cursor themes +BuildArch: noarch +%description -n oxygen-cursor-themes +%{summary}. + +%package -n plasma-scriptengine-python +Summary: Plasma scriptengine for python +Obsoletes: %{name}-python-applet < 4.5.80-7 +Provides: %{name}-python-applet = %{version}-%{release} +Requires: %{name} = %{version}-%{release} +Requires: pykde4%{?_isa} +%description -n plasma-scriptengine-python +%{summary}. + +%package -n plasma-scriptengine-ruby +Summary: Plasma scriptengine for ruby +Requires: %{name} = %{version}-%{release} +Requires: ruby +%description -n plasma-scriptengine-ruby +%{summary}. + +%package akonadi +Summary: Akonadi integration for KDE Workspace +Obsoletes: kdebase-workspace-akonadi < 4.7.97-10 +Provides: kdebase-workspace-akonadi = %{version}-%{release} +Provides: plasma-dataengine-akonadi = %{version}-%{release} +Requires: %{name} = %{version}-%{release} +Requires: akonadi +%description akonadi +%{summary}. + +%package -n khotkeys +Summary: Application to configure hotkeys in KDE +Conflicts: kde-workspace < 4.11.15-3 +Requires: khotkeys-libs%{?_isa} = %{version}-%{release} +%description -n khotkeys +%{summary}. + +%package -n khotkeys-libs +Summary: Runtime libraries for %{name} +Conflicts: kde-workspace < 4.11.15-3 +%description -n khotkeys-libs +%{summary}. + +%package -n kmenuedit +Summary: KDE Menu Editor +Conflicts: kde-workspace < 4.11.15-3 +%description -n kmenuedit +%{summary}. + +%package -n kinfocenter +Summary: KDE Info Center +Conflicts: kde-workspace < 4.11.15-3 +%description -n kinfocenter +%{summary}. + +%prep +%setup -q -n kde-workspace-%{version} + +# Well, I looked at doing this using the context menu plugin system and it +# looked like a lot more work than this simple patch to me. -- Kevin +# FIXME/REBASE -- rex +%patch2 -p1 -b .plasma-konsole +%patch3 -p1 -b .vtnumbers +%patch4 -p1 -b .harden +%patch7 -p1 -b .krdb +%patch8 -p1 -b .klipper-url +%patch9 -p1 -b .rootprivs +%patch15 -p1 -b .kio_sysinfo +%patch16 -p1 -b .showremainingtime +%patch17 -p1 -b .classicmenu-logout +%patch19 -p1 -b .kdm_plymouth +%patch20 -p1 -b .xsession_errors_O_APPEND +%patch21 -p1 -b .platformplugin-widgetstyle4 +%patch25 -p1 -b .bz#747982-launchers +%patch26 -p1 -b .systray_org.kde.ktp-presence +%patch27 -p1 -b .kdm_logind +%patch28 -p1 -b .ksysguardd-setgroups +%patch29 -p1 -b .kdm_greet-initgroups +%patch30 -p1 -b .bz#1060058 +%patch31 -p1 -b .bz#1043686 +%patch32 -p1 -b .colorschemes-kde4 + +# upstreamable patches +%patch50 -p1 -b .kde#171685 +%patch51 -p1 -b .add_apper_to_kickoff_favorites +%patch52 -p1 -b .bz#732830-login +%patch53 -p1 -b .kdm_xauth +%patch54 -p1 -b .kcm_fonts_dont_change_on_load +%patch55 -p1 -b .BUILD_KCM_RANDR +%patch56 -p0 -b .kdm_local_ipv6 +%patch57 -p1 -b .bug796969 +%patch58 -p1 -b .backlight_actual_brightness +%patch59 -p1 -b .weather-fix-bbcukmet +%patch60 -p1 -b .weather-fix-bbcukmet-temp +%patch64 -p1 -b .coverity-scan +%patch65 -p1 -b .weather-fix-bbcukmet-clear-sky +%patch66 -p1 -b .weather-fix-bbcukmet-crash +%patch67 -p1 -b .remove-dependency-on-kdepimlibs-4.11 +%patch68 -p1 -b .coverity-scan-fixes +%patch69 -p1 -b .taskmanager-grouping +%patch70 -p1 -b .kscreenlocker-greeter-unlock-just-once +%patch71 -p1 -b .sanitise-notification-html +%patch72 -p1 -b .ksysguard-increase-cpu-buffer +%patch73 -p1 -b .plastik-do-not-show-disabled-buttons +%patch74 -p1 -b .taskmanager-check-if-full-when-item-from-group-is-removed + +# upstream patches +%patch101 -p1 -b .bug921742 +%patch104 -p1 -b .bz#1001708 +%patch105 -p1 -b .bz#1001727 +%patch106 -p1 -b .bz#990146 +%patch109 -p1 -b .bz#1090492 + +# Fedora patches +%if 0%{?fedora} && 0%{?rhel} > 6 +%patch200 -p1 -b .no_HAL +%patch210 -p1 -b .no_HAL2 +%endif + +# rhel patches +%if ! 0%{?webkit} +%patch300 -p1 -b .webkit +%endif +%patch301 -p1 -b .branding +%if ! 0%{?kdm} +%patch302 -p1 -b .bz#1070140 +%endif +%patch303 -p1 -b .powerdevil-upower099 +%patch304 -p1 -b .improve-systemtray-on-hdpi-displays +%patch305 -p1 -b .close-menu-on-closed-task.patch +%patch306 -p1 -b .fix-loading-get-hot-new-stuff +%patch307 -p1 -b .disable-plasma-screensaver + +# trunk patches + +%if 0%{?systemd_login1} +# allow/support f18+ patched version of systemd-197 too +sed -i -e 's|198|197|g' powerdevil/daemon/backends/upower/powerdevilupowerbackend.cpp +%endif + +# ensure the file we are about to replace exists +[ -f startkde.cmake ] +# replace it with our known good, patched copy +cp -pf %{SOURCE2} startkde.cmake + +## some plasma-dataengine-extractor love +if [ -x %{_bindir}/plasma-dataengine-depextractor ] ; then +plasma-dataengine-depextractor plasma/desktop/applets/showActivityManager/package/ +plasma-dataengine-depextractor plasma/generic/applets/activitybar/ plasma-applet-activitybar.desktop +plasma-dataengine-depextractor plasma/generic/applets/analog-clock/ plasma-applet-analogclock.desktop +plasma-dataengine-depextractor plasma/generic/applets/batterymonitor/ +plasma-dataengine-depextractor plasma/generic/applets/devicenotifier/package/ +plasma-dataengine-depextractor plasma/generic/applets/digital-clock/ plasma-applet-digitalclock.desktop +plasma-dataengine-depextractor plasma/generic/applets/lock_logout +plasma-dataengine-depextractor plasma/generic/applets/notifications/ +plasma-dataengine-depextractor plasma/generic/applets/system-monitor/ plasma-applet-system-monitor.desktop +plasma-dataengine-depextractor plasma/generic/applets/webbrowser/ plasma-applet-webbrowser.desktop +plasma-dataengine-depextractor plasma/generic/runners/solid/ plasma-runner-solid.desktop +plasma-dataengine-depextractor plasma/netbook/applets/searchbox/ plasma-applet-searchbox.desktop +fi + +%build +mkdir -p %{_target_platform} +pushd %{_target_platform} +%{cmake_kde4} \ + -DKDE4_ENABLE_FPIE:BOOL=ON \ + -DKDE4_KDM_PAM_SERVICE=kdm \ + -DKDE4_KCHECKPASS_PAM_SERVICE=kcheckpass \ + -DKDE4_KSCREENSAVER_PAM_SERVICE=kscreensaver \ + %{?kscreen:-DBUILD_KCM_RANDR:BOOL=OFF} \ + .. +popd + +make %{?_smp_mflags} -C %{_target_platform} + + +%install +make install/fast DESTDIR=%{buildroot} -C %{_target_platform} + +# xsession support +mkdir -p %{buildroot}%{_datadir}/xsessions/ + +%if 0%{?kdm} +mv %{buildroot}%{_kde4_appsdir}/kdm/sessions/kde-plasma.desktop \ + %{buildroot}%{_kde4_appsdir}/kdm/sessions/kde-plasma-safe.desktop \ + %{buildroot}%{_datadir}/xsessions/ + +# rename kde-plasma-safe.desktop to ensure it's sorted *after* kde-plasma.desktop +# https://bugzilla.redhat.com/show_bug.cgi?id=1164783 +mv %{buildroot}%{_datadir}/xsessions/kde-plasma-safe.desktop \ + %{buildroot}%{_datadir}/xsessions/kde-plasma99-safe.desktop + +# remove extraneous xsession files +rm -rfv %{buildroot}%{_kde4_appsdir}/kdm/sessions + +# nuke, use external kde-settings-kdm +rm -rfv %{buildroot}%{_kde4_configdir}/kdm + +# own %{_kde4_appsdir}/kdm/faces and set default user image +mkdir -p %{buildroot}%{_kde4_appsdir}/kdm/faces +pushd %{buildroot}%{_kde4_appsdir}/kdm/faces +ln -sf ../pics/users/%{default_face_icon} .default.face.icon +popd + +bunzip2 %{buildroot}%{_kde4_docdir}/HTML/en/kdm/index.cache.bz2 +sed -i -e 's!name="id[a-z]*[0-9]*"!!g' %{buildroot}%{_kde4_docdir}/HTML/en/kdm/index.cache +sed -i -e 's!#id[a-z]*[0-9]*"!!g' %{buildroot}%{_kde4_docdir}/HTML/en/kdm/index.cache +bzip2 -9 %{buildroot}%{_kde4_docdir}/HTML/en/kdm/index.cache +%else +install -p -m644 kdm/kfrontend/sessions/kde-plasma.desktop.cmake %{buildroot}%{_datadir}/xsessions/1-kde-plasma-standard.desktop +install -p -m644 kdm/kfrontend/sessions/kde-plasma-safe.desktop.cmake %{buildroot}%{_datadir}/xsessions/2-kde-plasma-safe.desktop +%endif + +# fedora-plasma-cache hack +mkdir -p %{buildroot}%{_sysconfdir}/kde/env/ +install -m644 -p %{SOURCE10} %{buildroot}%{_sysconfdir}/kde/env/ + +# unpackaged files +rm -rfv %{buildroot}%{_kde4_appsdir}/ksplash/Themes/Default/ +rm -fv %{buildroot}%{_kde4_libdir}/liboxygenstyle{,config}.so + +# fix documentation multilib conflict in index.cache +for f in kcontrol/colors kmenuedit kcontrol/windowbehaviour kcontrol/kwindecoration \ + kcontrol/khotkeys ksysguard plasma-desktop ; do + bunzip2 %{buildroot}%{_kde4_docdir}/HTML/en/$f/index.cache.bz2 + sed -i -e 's!name="id[a-z]*[0-9]*"!!g' %{buildroot}%{_kde4_docdir}/HTML/en/$f/index.cache + sed -i -e 's!#id[a-z]*[0-9]*"!!g' %{buildroot}%{_kde4_docdir}/HTML/en/$f/index.cache + sed -i -e 's!a href="#ftn.id[a-z]*[0-9]*"!a href="ftn"!g' %{buildroot}%{_kde4_docdir}/HTML/en/$f/index.cache + sed -i -e 's!id="ftn.id[a-z]*[0-9]*"!id="ftn"!g' %{buildroot}%{_kde4_docdir}/HTML/en/$f/index.cache + bzip2 -9 %{buildroot}%{_kde4_docdir}/HTML/en/$f/index.cache +done + +# fix multilib conflict cause by a different order of dataengines +sed -i 's!\(^X-Plasma-RequiredDataEngines=\).*!\1applicationjobs,notifications,powermanagement!' %{buildroot}%{_kde4_datadir}/kde4/services/plasma-applet-org.kde.notifications.desktop +sed -i 's!\(^X-Plasma-RequiredDataEngines=\).*!\1applicationjobs,notifications,powermanagement!' %{buildroot}%{_kde4_datadir}/kde4/apps/plasma/plasmoids/org.kde.notifications/metadata.desktop +sed -i 's!\(^X-Plasma-RequiredDataEngines=\).*!\1executable,soliddevice,systemmonitor!' %{buildroot}%{_kde4_datadir}/kde4/services/plasma-applet-system-monitor.desktop + +# install manpage +mkdir -p %{buildroot}%{_mandir}/man5 +install -m 644 -p %{SOURCE1} %{buildroot}%{_mandir}/man5/ + +%check +for f in %{buildroot}%{_kde4_datadir}/applications/kde4/*.desktop ; do + desktop-file-validate $f +done + + +%post +touch --no-create %{_kde4_iconsdir}/hicolor &> /dev/null || : +touch --no-create %{_kde4_iconsdir}/oxygen &> /dev/null || : + +%posttrans +gtk-update-icon-cache %{_kde4_iconsdir}/hicolor &> /dev/null || : +gtk-update-icon-cache %{_kde4_iconsdir}/oxygen &> /dev/null || : +update-desktop-database -q &> /dev/null || : + +%postun +if [ $1 -eq 0 ] ; then +touch --no-create %{_kde4_iconsdir}/hicolor &> /dev/null || : +touch --no-create %{_kde4_iconsdir}/oxygen &> /dev/null || : +gtk-update-icon-cache %{_kde4_iconsdir}/hicolor &> /dev/null || : +gtk-update-icon-cache %{_kde4_iconsdir}/oxygen &> /dev/null || : +update-desktop-database -q &> /dev/null || : +fi + +%files +%doc COPYING README +%{_sysconfdir}/kde/env/fedora-plasma-cache.sh +%{_kde4_bindir}/kaccess +%{_kde4_bindir}/kapplymousetheme +%{_kde4_bindir}/kblankscrn.kss +%{_kde4_bindir}/kcheckrunning +%{_kde4_bindir}/kcminit +%{_kde4_bindir}/kcminit_startup +%{_kde4_bindir}/kdostartupconfig4 +%{_kde4_bindir}/klipper +%{_kde4_bindir}/krandom.kss +%if ! 0%{?kscreen} +%{_kde4_bindir}/krandrstartup +%{_kde4_bindir}/krandrtray +%endif +%{_kde4_bindir}/krdb +%{_kde4_bindir}/krunner +%{_kde4_bindir}/ksmserver +%{_kde4_bindir}/ksplashsimple +%{_kde4_bindir}/ksplashx +%{_kde4_bindir}/ksplashx_scale +%{_kde4_bindir}/ksplashqml +%{_kde4_bindir}/kstartupconfig4 +%{_kde4_bindir}/ksystraycmd +%{_kde4_bindir}/oxygen-shadow-demo +%{_kde4_bindir}/plasma-desktop +%{_kde4_bindir}/plasma-netbook +%{_kde4_bindir}/plasma-overlay +%{_kde4_bindir}/plasma-windowed +%{_kde4_bindir}/solid-action-desktop-gen +%{_kde4_bindir}/startkde +%{_kde4_bindir}/systemsettings +%{_kde4_appsdir}/desktoptheme/ +%{_kde4_appsdir}/freespacenotifier/ +%{_kde4_appsdir}/kaccess/ +%{_kde4_appsdir}/katepart/syntax/plasma-desktop-js.xml +%{_kde4_appsdir}/kcminput/ +%{_kde4_appsdir}/kcmkeyboard/ +%{_kde4_appsdir}/kcmkeys/ +%{_kde4_appsdir}/kcmsolidactions/ +%{_kde4_appsdir}/kcmstyle/ +%{_kde4_appsdir}/kconf_update/ +%exclude %{_kde4_appsdir}/kconf_update/kwin_* +%{_kde4_appsdir}/kcontrol/ +%{_kde4_appsdir}/kdisplay/ +%dir %{_kde4_appsdir}/ksmserver/ +%{_kde4_appsdir}/ksmserver/ksmserver.notifyrc +%{_kde4_appsdir}/ksmserver/screenlocker/ +%dir %{_kde4_appsdir}/ksmserver/themes/ +%{_kde4_appsdir}/ksmserver/themes/contour/ +%{_kde4_appsdir}/ksmserver/themes/default/ +%dir %{_kde4_appsdir}/ksplash/ +%dir %{_kde4_appsdir}/ksplash/Themes/ +%{_kde4_appsdir}/ksplash/Themes/None/ +%{_kde4_appsdir}/ksplash/Themes/Simple/ +%{_kde4_appsdir}/ksplash/Themes/SimpleSmall/ +%dir %{_kde4_appsdir}/kstyle +%dir %{_kde4_appsdir}/kstyle/themes/ +%{_kde4_appsdir}/kstyle/themes/qt*.themerc +%{_kde4_appsdir}/kthememanager/ +%{_kde4_appsdir}/kwrited/ +%{_kde4_appsdir}/plasma/ +%{_kde4_appsdir}/plasma-desktop/ +%{_kde4_appsdir}/plasma-netbook/ +%{_kde4_appsdir}/powerdevil/ +%{_kde4_appsdir}/solid/ +%{_kde4_appsdir}/systemsettings/ + +%{_kde4_configdir}/activities.knsrc +%{_kde4_configdir}/aurorae.knsrc +%if 0%{?kdm} +%{_kde4_configdir}/background.knsrc +%endif +%{_kde4_configdir}/ksplash.knsrc +%{_kde4_configdir}/plasma-overlayrc +%{_kde4_configdir}/plasma-themes.knsrc +%{_kde4_configdir}/wallpaper.knsrc +%{_kde4_configdir}/xcursor.knsrc + +%{_kde4_datadir}/kde4/services/ScreenSavers +%{_kde4_datadir}/kde4/services/ServiceMenus +%{_kde4_datadir}/kde4/services/kded/*.desktop +%exclude %{_kde4_datadir}/kde4/services/kded/khotkeys.desktop +%{_kde4_datadir}/kde4/services/fonts.protocol +%{_kde4_datadir}/kde4/services/*.desktop +%if 0%{?kdm} +%exclude %{_kde4_datadir}/kde4/services/kdm.desktop +%endif +%exclude %{_kde4_datadir}/kde4/services/kwin*.desktop +%exclude %{_kde4_datadir}/kde4/services/khotkeys.desktop +# KInfoCenter +%exclude %{_kde4_datadir}/kde4/services/kcmusb.desktop +%exclude %{_kde4_datadir}/kde4/services/kcm_infosummary.desktop +%exclude %{_kde4_datadir}/kde4/services/kcm_memory.desktop +%exclude %{_kde4_datadir}/kde4/services/devinfo.desktop +%exclude %{_kde4_datadir}/kde4/services/interrupts.desktop +%exclude %{_kde4_datadir}/kde4/services/nic.desktop +%exclude %{_kde4_datadir}/kde4/services/opengl.desktop +%exclude %{_kde4_datadir}/kde4/services/smbstatus.desktop +%exclude %{_kde4_datadir}/kde4/services/kcm_pci.desktop +%ifnarch s390 s390x +%exclude %{_kde4_datadir}/kde4/services/kcmview1394.desktop +%endif +%{_kde4_datadir}/kde4/servicetypes/* +%exclude %{_kde4_datadir}/kde4/servicetypes/kwin*.desktop +%{_kde4_datadir}/sounds/pop.wav +%{_kde4_datadir}/autostart/klipper.desktop +%{_kde4_datadir}/autostart/krunner.desktop +%{_kde4_datadir}/autostart/plasma.desktop +%{_kde4_datadir}/autostart/plasma-desktop.desktop +%{_kde4_datadir}/applications/kde4/* +%exclude %{_kde4_datadir}/applications/kde4/kmenuedit.desktop +%exclude %{_kde4_datadir}/applications/kde4/kinfocenter.desktop +%{_sysconfdir}/dbus-1/system.d/org.kde.fontinst.conf +%{_sysconfdir}/dbus-1/system.d/org.kde.kcontrol.kcmclock.conf +%if 0%{?kdm} +%{_sysconfdir}/dbus-1/system.d/org.kde.kcontrol.kcmkdm.conf +%endif +%{_sysconfdir}/dbus-1/system.d/org.kde.powerdevil.backlighthelper.conf +%{_datadir}/dbus-1/interfaces/com.canonical.AppMenu.Registrar.xml +%{_datadir}/dbus-1/interfaces/org.kde.kded.appmenu.xml +%{_datadir}/dbus-1/interfaces/org.kde.KSMServerInterface.xml +%{_datadir}/dbus-1/interfaces/org.kde.krunner.App.xml +%{_datadir}/dbus-1/services/org.kde.fontinst.service +%{_datadir}/dbus-1/services/org.kde.krunner.service +%{_datadir}/dbus-1/system-services/org.kde.fontinst.service +%{_datadir}/dbus-1/system-services/org.kde.kcontrol.kcmclock.service +%if 0%{?kdm} +%{_datadir}/dbus-1/system-services/org.kde.kcontrol.kcmkdm.service +%endif +%{_datadir}/dbus-1/system-services/org.kde.powerdevil.backlighthelper.service +%{_kde4_datadir}/config.kcfg/freespacenotifier.kcfg +%{_kde4_datadir}/config.kcfg/klaunch.kcfg +%{_kde4_datadir}/config.kcfg/plasma-shell-desktop.kcfg +%{_datadir}/xsessions/*.desktop +%{_kde4_docdir}/HTML/en/kfontview/ +%{_kde4_docdir}/HTML/en/kcontrol/ +%exclude %{_kde4_docdir}/HTML/en/kcontrol/colors/ +%{_kde4_docdir}/HTML/en/klipper/ +%{_kde4_docdir}/HTML/en/plasma-desktop/ +%{_kde4_docdir}/HTML/en/systemsettings/ +%{_kde4_iconsdir}/hicolor/*/*/* +%{_kde4_iconsdir}/oxygen/*/*/* +%exclude %{_kde4_iconsdir}/oxygen/*/*/kwin.* +%{_kde4_libdir}/kde4/classic_mode.so +%{_kde4_libdir}/kde4/devinfo.so +%{_kde4_libdir}/kde4/icon_mode.so +%{_kde4_libdir}/kde4/ion_*.so +%{_kde4_libdir}/kde4/kcm_*.so +%exclude %{_kde4_libdir}/kde4/kcm_colors.so +%if 0%{?kdm} +%exclude %{_kde4_libdir}/kde4/kcm_kdm.so +%endif +%exclude %{_kde4_libdir}/kde4/kcm_kwin* +%exclude %{_kde4_libdir}/kde4/kcm_hotkeys.so +# KInfoCenter +%exclude %{_kde4_libdir}/kde4/kcm_usb.so +%exclude %{_kde4_libdir}/kde4/kcm_infosummary.so +%exclude %{_kde4_libdir}/kde4/kcm_memory.so +%exclude %{_kde4_libdir}/kde4/devinfo.so +%exclude %{_kde4_libdir}/kde4/kcm_info.so +%exclude %{_kde4_libdir}/kde4/kcm_samba.so +%exclude %{_kde4_libdir}/kde4/kcm_nic.so +%exclude %{_kde4_libdir}/kde4/kcm_opengl.so +%exclude %{_kde4_libdir}/kde4/kcm_pci.so +%ifnarch s390 s390x +%exclude %{_kde4_libdir}/kde4/kcm_view1394.so +%endif +%{_kde4_libdir}/kde4/kded_*.so +%exclude %{_kde4_libdir}/kde4/kded_khotkeys.so +%{_kde4_libdir}/kde4/keyboard_layout_widget.so +%{_kde4_libdir}/kde4/krunner_*.so +%{_kde4_libdir}/kde4/plasma_animator_default.so +%{_kde4_libdir}/kde4/plasma_applet_*.so +%{_kde4_libdir}/kde4/plasma_containmentactions_*.so +%if 0%{?webkit} +%{_kde4_libdir}/kde4/plasma_appletscriptengine_dashboard.so +%{_kde4_libdir}/kde4/plasma_appletscriptengine_webapplet.so +%endif +%{_kde4_libdir}/kde4/plasma_containment_*.so +%{_kde4_libdir}/kde4/plasma_engine_*.so +%if 0%{?gpsd} +%{_kde4_libdir}/kde4/plasma-geolocation-gps.so +# covered by a glob above, dont list here to avoid "File listed twice" bogosity -- rex +#{_kde4_datadir}/kde4/services/plasma-geolocation-gps.desktop +%endif +%{_kde4_libdir}/kde4/plasma-geolocation-ip.so +%{_kde4_libdir}/kde4/plasma_package*_*.so +%{_kde4_libdir}/kde4/plasma_toolbox_*.so +%{_kde4_libdir}/kde4/plasma_wallpaper_*.so +%{_kde4_libdir}/kde4/powerdevil*.so +%{_kde4_libexecdir}/kcheckpass +%{_kde4_libexecdir}/kcmdatetimehelper +%if 0%{?kdm} +%{_kde4_libexecdir}/kcmkdmhelper +%{_kde4_libexecdir}/krootimage +%endif +%{_kde4_libexecdir}/kscreenlocker_greet +%{_kde4_libdir}/libkdeinit4_kaccess.so +%{_kde4_libdir}/libkdeinit4_kcminit.so +%{_kde4_libdir}/libkdeinit4_kcminit_startup.so +%{_kde4_libdir}/libkdeinit4_klipper.so +%{_kde4_libdir}/libkdeinit4_krunner.so +%{_kde4_libdir}/libkdeinit4_ksmserver.so +%{_kde4_libdir}/libkdeinit4_plasma-desktop.so +%{_kde4_libdir}/libkdeinit4_plasma-netbook.so +%{_kde4_libdir}/libkdeinit4_plasma-windowed.so +%{_kde4_libdir}/libkickoff.so +%{_kde4_libdir}/libpowerdevilcore.so +%{_kde4_libdir}/libpowerdevilconfigcommonprivate.so +%{_kde4_libdir}/libsystemsettingsview.so +%{_kde4_libdir}/kconf_update_bin/* +%exclude %{_kde4_libdir}/kconf_update_bin/kwin_* +# python +%exclude %{_kde4_datadir}/kde4/services/plasma-scriptengine*python.desktop +# ruby +%exclude %{_kde4_datadir}/kde4/services/plasma-scriptengine-*ruby*.desktop +%if 0%{?akonadi_subpkg} +%exclude %{_kde4_libdir}/kde4/plasma_applet_calendar.so +%exclude %{_kde4_libdir}/kde4/plasma_applet_clock.so +%exclude %{_kde4_libdir}/kde4/plasma_applet_dig_clock.so +%exclude %{_kde4_libdir}/kde4/plasma_engine_akonadi.so +%exclude %{_kde4_libdir}/kde4/plasma_engine_calendar.so +%exclude %{_kde4_datadir}/kde4/services/plasma-applet-analogclock.desktop +%exclude %{_kde4_datadir}/kde4/services/plasma-applet-calendar.desktop +%exclude %{_kde4_datadir}/kde4/services/plasma-applet-digitalclock.desktop +%exclude %{_kde4_datadir}/kde4/services/plasma-engine-akonadi.desktop +%exclude %{_kde4_datadir}/kde4/services/plasma-dataengine-calendar.desktop +%endif +%{_kde4_bindir}/kfontinst +%{_kde4_bindir}/kfontview +%{_kde4_libdir}/kde4/fontthumbnail.so +%{_kde4_libdir}/kde4/kfontviewpart.so +%{_kde4_libdir}/kde4/kio_fonts.so +%{_kde4_libdir}/strigi/strigita_font.so +%{_kde4_libexecdir}/backlighthelper +%{_kde4_libexecdir}/fontinst +%{_kde4_libexecdir}/fontinst_helper +%{_kde4_libexecdir}/fontinst_x11 +%{_kde4_libexecdir}/kfontprint +%{_kde4_configdir}/kfontinst.knsrc +%{_polkit_qt_policydir}/org.kde.fontinst.policy +%{_polkit_qt_policydir}/org.kde.kcontrol.kcmclock.policy +%if 0%{?kdm} +%{_polkit_qt_policydir}/org.kde.kcontrol.kcmkdm.policy +%endif +%{_polkit_qt_policydir}/org.kde.powerdevil.backlighthelper.policy +%{_kde4_appsdir}/kfontinst/ +%{_kde4_appsdir}/kfontview/ +%{_kde4_appsdir}/konqsidebartng/virtual_folders/services/fonts.desktop +# exclude ksysguard bits +%exclude /usr/share/applications/kde4/ksysguard.desktop +# exclude ksysguard icons +%exclude %{_kde4_iconsdir}/oxygen/*/apps/computer.* +%exclude %{_kde4_iconsdir}/oxygen/*/apps/daemon.* +%exclude %{_kde4_iconsdir}/oxygen/*/apps/kdeapp.* +%exclude %{_kde4_iconsdir}/oxygen/*/apps/kernel.* +%exclude %{_kde4_iconsdir}/oxygen/*/apps/ksysguardd.* +%exclude %{_kde4_iconsdir}/oxygen/*/apps/running.* +%exclude %{_kde4_iconsdir}/oxygen/*/apps/shell.* +%exclude %{_kde4_iconsdir}/oxygen/*/apps/unknownapp.* +%exclude %{_kde4_iconsdir}/oxygen/*/apps/waiting.* + +%post libs -p /sbin/ldconfig +%postun libs -p /sbin/ldconfig + +%files libs +%{_kde4_libdir}/libkephal.so.4* +%{_kde4_libdir}/libkfontinst.so.4* +%{_kde4_libdir}/libkfontinstui.so.4* +%{_kde4_libdir}/libkscreensaver.so.5* +%{_kde4_libdir}/libplasma-geolocation-interface.so.4* +%{_kde4_libdir}/libplasma_applet-system-monitor.so.4* +%if ! 0%{?akonadi_subpkg} +# libplasmaclock has an implicit dependency on plasma-dataengine-calendar + %{_kde4_libdir}/libplasmaclock.so.4* +%endif +%{_kde4_libdir}/libplasmagenericshell.so.4* +%{_kde4_libdir}/libpowerdevilui.so.4* +%{_kde4_libdir}/libsystemsettingsview.so.2* +%{_kde4_libdir}/libtaskmanager.so.4* +%{_kde4_libdir}/libweather_ion.so.6* +%{_kde4_libdir}/libpowerdevilcore.so.0* +%{_kde4_libdir}/libpowerdevilconfigcommonprivate.so.4* +%{_kde4_libdir}/kde4/plugins/gui_platform/libkde.so + +%files devel +%{_kde4_includedir}/* +%{_kde4_appsdir}/cmake/modules/*.cmake +%{_kde4_libdir}/cmake/KDE4Workspace/ +%{_kde4_libdir}/libkdecorations.so +%{_kde4_libdir}/libkephal.so +%{_kde4_libdir}/libkfontinst.so +%{_kde4_libdir}/libkfontinstui.so +%{_kde4_libdir}/libkscreensaver.so +%{_kde4_libdir}/libksgrd.so +%{_kde4_libdir}/libksignalplotter.so +%{_kde4_libdir}/libkwineffects.so +%{_kde4_libdir}/libkworkspace.so +%{_kde4_libdir}/liblsofui.so +%{_kde4_libdir}/libplasma-geolocation-interface.so +%{_kde4_libdir}/libplasma_applet-system-monitor.so +%{_kde4_libdir}/libplasmaclock.so +%{_kde4_libdir}/libplasmagenericshell.so +%{_kde4_libdir}/libpowerdevilui.so +%{_kde4_libdir}/libprocesscore.so +%{_kde4_libdir}/libprocessui.so +%{_kde4_libdir}/libtaskmanager.so +%{_kde4_libdir}/libweather_ion.so +%{_kde4_libdir}/libkwinglutils.so +%if 0%{?gles} +%{_kde4_libdir}/libkwinglesutils.so +%endif + +%files ksplash-themes +%{_kde4_appsdir}/ksplash/Themes/Minimalistic/ + +%files -n kcm_colors +%{_kde4_datadir}/kde4/services/colors.desktop +%{_kde4_libdir}/kde4/kcm_colors.so +%{_kde4_configdir}/colorschemes-kde4.knsrc +%{_kde4_docdir}/HTML/en/kcontrol/colors/ +%{_kde4_appsdir}/color-schemes/Honeycomb.colors +%{_kde4_appsdir}/color-schemes/Norway.colors +%{_kde4_appsdir}/color-schemes/ObsidianCoast.colors +%{_kde4_appsdir}/color-schemes/Oxygen.colors +%{_kde4_appsdir}/color-schemes/OxygenCold.colors +%{_kde4_appsdir}/color-schemes/Steel.colors +%{_kde4_appsdir}/color-schemes/WontonSoup.colors +%{_kde4_appsdir}/color-schemes/Zion.colors +%{_kde4_appsdir}/color-schemes/ZionReversed.colors + +%if 0%{?kdm} +%files -n kdm +%{_kde4_bindir}/genkdmconf +%{_kde4_bindir}/kdm +%{_kde4_bindir}/kdmctl +%{_kde4_libdir}/kde4/kcm_kdm.so +%{_kde4_libexecdir}/kdm_config +%{_kde4_libexecdir}/kdm_greet +%{_kde4_configdir}/kdm.knsrc +%{_kde4_docdir}/HTML/en/kdm/ +%dir %{_kde4_appsdir}/doc +%{_kde4_appsdir}/doc/kdm/ +%dir %{_kde4_appsdir}/kdm/ +%{_kde4_appsdir}/kdm/faces/ +%{_kde4_appsdir}/kdm/patterns/ +%{_kde4_appsdir}/kdm/pics/ +%{_kde4_appsdir}/kdm/programs/ +%dir %{_kde4_appsdir}/kdm/themes/ +%{_kde4_datadir}/kde4/services/kdm.desktop + + +%files -n kdm-themes +%{_kde4_appsdir}/kdm/themes/ariya/ +%{_kde4_appsdir}/kdm/themes/circles/ +%{_kde4_appsdir}/kdm/themes/elarun/ +%{_kde4_appsdir}/kdm/themes/horos/ +%{_kde4_appsdir}/kdm/themes/oxygen/ +%{_kde4_appsdir}/kdm/themes/oxygen-air/ +# not sure why this is included in kdm sources... ? -- rex +%{_kde4_datadir}/wallpapers/stripes.png* +%endif + +%files -n kgreeter-plugins +%{_kde4_libdir}/kde4/kgreet_classic.so +%{_kde4_libdir}/kde4/kgreet_generic.so +%{_kde4_libdir}/kde4/kgreet_winbind.so + +%post -n ksysguard +touch --no-create %{_kde4_iconsdir}/oxygen &> /dev/null || : + +%posttrans -n ksysguard +gtk-update-icon-cache %{_kde4_iconsdir}/oxygen &> /dev/null || : + +%postun -n ksysguard +if [ $1 -eq 0 ] ; then +touch --no-create %{_kde4_iconsdir}/oxygen &> /dev/null || : +gtk-update-icon-cache %{_kde4_iconsdir}/oxygen &> /dev/null || : +fi + +%files -n ksysguard +#doc %{name}-%{version}/ksysguard/README +%{_kde4_bindir}/ksysguard +%{_kde4_libdir}/libkdeinit4_ksysguard.so +%{_kde4_appsdir}/ksysguard/ +%{_kde4_configdir}/ksysguard.knsrc +%{_kde4_datadir}/applications/kde4/ksysguard.desktop +%{_kde4_docdir}/HTML/en/ksysguard/ +%{_kde4_iconsdir}/oxygen/*/apps/computer.* +%{_kde4_iconsdir}/oxygen/*/apps/daemon.* +%{_kde4_iconsdir}/oxygen/*/apps/kdeapp.* +%{_kde4_iconsdir}/oxygen/*/apps/kernel.* +%{_kde4_iconsdir}/oxygen/*/apps/ksysguardd.* +%{_kde4_iconsdir}/oxygen/*/apps/running.* +%{_kde4_iconsdir}/oxygen/*/apps/shell.* +%{_kde4_iconsdir}/oxygen/*/apps/unknownapp.* +%{_kde4_iconsdir}/oxygen/*/apps/waiting.* +%{_kde4_libexecdir}/ksysguardprocesslist_helper +%{_polkit_qt_policydir}/org.kde.ksysguard.processlisthelper.policy +%{_sysconfdir}/dbus-1/system.d/org.kde.ksysguard.processlisthelper.conf +%{_datadir}/dbus-1/system-services/org.kde.ksysguard.processlisthelper.service + +%post -n ksysguard-libs -p /sbin/ldconfig +%postun -n ksysguard-libs -p /sbin/ldconfig + +%files -n ksysguard-libs +%{_kde4_libdir}/kde4/plugins/designer/ksignalplotterwidgets.so +%{_kde4_libdir}/libksignalplotter.so.4* +%{_kde4_libdir}/kde4/plugins/designer/ksysguardwidgets.so +%{_kde4_libdir}/kde4/plugins/designer/ksysguardlsofwidgets.so +%{_kde4_libdir}/libksgrd.so.4* +%{_kde4_libdir}/liblsofui.so.4* +%{_kde4_libdir}/libprocesscore.so.4* +%{_kde4_libdir}/libprocessui.so.4* + +%files -n ksysguardd +%config(noreplace) %{_kde4_sysconfdir}/ksysguarddrc +%{_mandir}/man5/* +%{_kde4_bindir}/ksysguardd + +%if 0%{?gles} +%files -n kwin-gles +%{_kde4_bindir}/kwin_gles +%{_kde4_libdir}/libkdeinit4_kwin_gles.so +%{_kde4_libdir}/kde4/kwin4_effect_gles_builtins.so + +%post -n kwin-gles-libs -p /sbin/ldconfig +%postun -n kwin-gles-libs -p /sbin/ldconfig + +%files -n kwin-gles-libs +%{_kde4_libdir}/libkwinglesutils.so.1* +%endif + +%post -n libkworkspace -p /sbin/ldconfig +%postun -n libkworkspace -p /sbin/ldconfig + +%files -n libkworkspace +%{_kde4_libdir}/libkworkspace.so.4* + +%post -n kde-style-oxygen -p /sbin/ldconfig +%postun -n kde-style-oxygen -p /sbin/ldconfig + +%files -n kde-style-oxygen +%{_kde4_bindir}/oxygen-demo +%{_kde4_bindir}/oxygen-settings +%{_kde4_appsdir}/kstyle/themes/oxygen.themerc +%{_kde4_libdir}/liboxygenstyle.so.4* +%{_kde4_libdir}/liboxygenstyleconfig.so.4* +%{_kde4_libdir}/kde4/kstyle_oxygen_config.so +%{_kde4_libdir}/kde4/plugins/styles/oxygen.so + + +%post -n kwin +touch --no-create %{_kde4_iconsdir}/oxygen &> /dev/null || : + +%posttrans -n kwin +gtk-update-icon-cache %{_kde4_iconsdir}/oxygen &> /dev/null || : +update-desktop-database -q &> /dev/null || : + +%postun -n kwin +if [ $1 -eq 0 ] ; then +touch --no-create %{_kde4_iconsdir}/oxygen &> /dev/null || : +gtk-update-icon-cache %{_kde4_iconsdir}/oxygen &> /dev/null || : +update-desktop-database -q &> /dev/null || : +fi + +%files -n kwin +%{_kde4_bindir}/kwin +%{_kde4_appsdir}/kwin/ +%{_kde4_configdir}/kwineffect.knsrc +%{_kde4_configdir}/kwinscripts.knsrc +%{_kde4_configdir}/kwinswitcher.knsrc +%{_kde4_datadir}/config.kcfg/kwin.kcfg +%{_datadir}/dbus-1/interfaces/org.kde.KWin.xml +%{_kde4_libdir}/kde4/kwin3_aurorae.so +%{_kde4_libdir}/kde4/kwin3_b2.so +%{_kde4_libdir}/kde4/kwin3_laptop.so +%{_kde4_libdir}/kde4/kwin3_oxygen.so +%{_kde4_libdir}/kde4/kwin4_effect_builtins.so +%{_kde4_libdir}/kde4/kwin_b2_config.so +%{_kde4_libdir}/kde4/kwin_oxygen_config.so +%{_kde4_libdir}/kde4/kcm_kwin* +%{_kde4_libexecdir}/kwin_killer_helper +%{_kde4_libexecdir}/kwin_opengl_test +%{_kde4_libexecdir}/kwin_rules_dialog +%{_kde4_libdir}/libkdeinit4_kwin.so +%{_kde4_libdir}/libkdeinit4_kwin_rules_dialog.so +%{_kde4_libdir}/kconf_update_bin/kwin_* +%{_kde4_libdir}/kde4/imports/org/kde/kwin/ +%{_kde4_iconsdir}/oxygen/*/*/kwin.* +%{_kde4_appsdir}/kconf_update/kwin_* +%{_kde4_datadir}/kde4/services/kwin +%{_kde4_datadir}/kde4/services/kwin*.desktop +%{_kde4_datadir}/kde4/servicetypes/kwin*.desktop + +%post -n kwin-libs -p /sbin/ldconfig +%postun -n kwin-libs -p /sbin/ldconfig + +%files -n kwin-libs +%{_kde4_libdir}/libkdecorations.so.4* +%{_kde4_libdir}/libkwineffects.so.1* +%{_kde4_libdir}/libkwinglutils.so.1* + + +%post -n kdeclassic-cursor-theme +touch --no-create %{_kde4_iconsdir}/KDE_Classic &> /dev/null || : + +%posttrans -n kdeclassic-cursor-theme +gtk-update-icon-cache %{_kde4_iconsdir}/KDE_Classic &> /dev/null || : + +%postun -n kdeclassic-cursor-theme +if [ $1 -eq 0 ] ; then +touch --no-create %{_kde4_iconsdir}/KDE_Classic &> /dev/null || : +gtk-update-icon-cache %{_kde4_iconsdir}/KDE_Classic &> /dev/null || : +fi + +%files -n kdeclassic-cursor-theme +%{_kde4_iconsdir}/KDE_Classic/ + +%files -n oxygen-cursor-themes +%{_kde4_iconsdir}/Oxygen_Black/ +%{_kde4_iconsdir}/Oxygen_Blue/ +%{_kde4_iconsdir}/Oxygen_White/ +%{_kde4_iconsdir}/Oxygen_Yellow/ +%{_kde4_iconsdir}/Oxygen_Zion/ + +%files -n plasma-scriptengine-python +%{python_sitearch}/PyKDE4/plasmascript.py* +%{_kde4_appsdir}/plasma_scriptengine_python +%{_kde4_datadir}/kde4/services/plasma-scriptengine*python.desktop + +%files -n plasma-scriptengine-ruby +%{_kde4_appsdir}/plasma_scriptengine_ruby/ +%{_kde4_datadir}/kde4/services/plasma-scriptengine-*ruby*.desktop + +%if 0%{?akonadi_subpkg} +%post akonadi -p /sbin/ldconfig +%postun akonadi -p /sbin/ldconfig + +%files akonadi +%{_kde4_libdir}/libplasmaclock.so.4* +%{_kde4_libdir}/kde4/plasma_applet_calendar.so +%{_kde4_libdir}/kde4/plasma_applet_clock.so +%{_kde4_libdir}/kde4/plasma_applet_dig_clock.so +%{_kde4_libdir}/kde4/plasma_engine_akonadi.so +%{_kde4_libdir}/kde4/plasma_engine_calendar.so +%{_kde4_datadir}/kde4/services/plasma-applet-analogclock.desktop +%{_kde4_datadir}/kde4/services/plasma-applet-calendar.desktop +%{_kde4_datadir}/kde4/services/plasma-applet-digitalclock.desktop +%{_kde4_datadir}/kde4/services/plasma-engine-akonadi.desktop +%{_kde4_datadir}/kde4/services/plasma-dataengine-calendar.desktop +%endif + +%files -n khotkeys +%{_kde4_libdir}/kde4/kded_khotkeys.so +%{_kde4_libdir}/kde4/kcm_hotkeys.so +%{_kde4_appsdir}/khotkeys/ +%{_kde4_datadir}/kde4/services/khotkeys.desktop +%{_kde4_datadir}/kde4/services/kded/khotkeys.desktop +%{_datadir}/dbus-1/interfaces/org.kde.khotkeys.xml + +%post -n khotkeys-libs -p /sbin/ldconfig +%postun -n khotkeys-libs -p /sbin/ldconfig + +%files -n khotkeys-libs +%{_kde4_libdir}/libkhotkeysprivate.so.4* + +%files -n kmenuedit +%{_kde4_bindir}/kmenuedit +%{_kde4_libdir}/libkdeinit4_kmenuedit.so +%{_kde4_appsdir}/kmenuedit +%{_kde4_datadir}/applications/kde4/kmenuedit.desktop +%{_kde4_docdir}/HTML/en/kmenuedit/ + +%files -n kinfocenter +%{_kde4_bindir}/kinfocenter +%{_kde4_libdir}/kde4/kcm_usb.so +%{_kde4_libdir}/kde4/kcm_infosummary.so +%{_kde4_libdir}/kde4/kcm_memory.so +%{_kde4_libdir}/kde4/devinfo.so +%{_kde4_libdir}/kde4/kcm_info.so +%{_kde4_libdir}/kde4/kcm_samba.so +%{_kde4_libdir}/kde4/kcm_nic.so +%{_kde4_libdir}/kde4/kcm_opengl.so +%{_kde4_libdir}/kde4/kcm_pci.so +%{_kde4_datadir}/applications/kde4/kinfocenter.desktop +%{_kde4_datadir}/kde4/services/kcmusb.desktop +%{_kde4_datadir}/kde4/services/kcm_infosummary.desktop +%{_kde4_datadir}/kde4/services/kcm_memory.desktop +%{_kde4_datadir}/kde4/services/devinfo.desktop +%{_kde4_datadir}/kde4/services/interrupts.desktop +%{_kde4_datadir}/kde4/services/nic.desktop +%{_kde4_datadir}/kde4/services/opengl.desktop +%{_kde4_datadir}/kde4/services/smbstatus.desktop +%{_kde4_datadir}/kde4/services/kcm_pci.desktop +%{_kde4_appsdir}/kinfocenter/ +%{_kde4_appsdir}/kcmusb/ +%{_kde4_docdir}/HTML/en/kinfocenter/ +%ifnarch s390 s390x +%{_kde4_libdir}/kde4/kcm_view1394.so +%{_kde4_datadir}/kde4/services/kcmview1394.desktop +%{_kde4_appsdir}/kcmview1394/ +%endif + +%changelog +* Mon Aug 05 2019 Jan Grulich - 4.11.19-14 +- Do not show disabled buttons in Plastik decoration theme + Resolves: bz#1677641 + +- Taskmanager: dismiss group when application is closed and there is enough space + Resolve: bz#1698048 + +* Tue Feb 12 2019 Jan Grulich - 4.11.19-13 +- Sanitise notification HTML + Resolves: bz#1568853 + +- Increase cpu buffer size in ksysguard + Resolves: bz#1611762 + +* Mon Oct 16 2017 Jan Grulich - 4.11.19-12 +- Make sure that plasma screensaver is not used when previously configured + Resolves: bz#1342560 + +* Fri Oct 13 2017 Jan Grulich - 4.11.19-11 +- Disable plasma screensaver for security reasons + Resolves: bz#1342560 + +* Tue Sep 26 2017 Jan Grulich - 4.11.19-10 +- Fix grouping of tasks in taskmanager applet + Resolves: bz#1348917 +- Fix unlocking of kscreenlocker, unlock it just once + Resolves: bz#1333441 + +* Mon Sep 11 2017 Jan Grulich - 4.11.19-9 +- Fix loading of get hot new stuff for KWin decorations and effects + Resolves: bz#1422002 + +* Tue Mar 22 2016 Jan Grulich - 4.11.19-8 +- Powerdevil: do not notify about a non existent action + Resolves: bz#1289149 +- Plasma taskmanager: close context menu when task is closed + Resolves: bz#1262603 + +* Mon Sep 07 2015 Jan Grulich - 4.11-19-7 +- Requires: cpp + Resolves: bz#1260129 + +* Tue Jul 07 2015 Jan Grulich - 4.11-19-6 +- Revert "Improve systemtray on HiDPI displays" + Resolves: #1238300 + +* Fri Jun 12 2015 Jan Grulich - 4.11.19-5 +- Fix accidentally removed KDE session + +* Mon Jun 08 2015 Jan Grulich - 4.11-19-4 +- Fix multilib issues++ + +* Mon Jun 08 2015 Jan Grulich - 4.11-19-3 +- Fix multilib issues + +* Fri Jun 05 2015 Jan Grulich - 4.11.19-2 +- Fix coverity scan issues +- Re-add kwin-gles subpackages + +* Tue Jun 02 2015 Jan Grulich - 4.11.19-1 +- Re-base to 4.11.19 (sync with F21) + +* Mon Apr 13 2015 Lukáš Tinkl - 4.10.5-22 +- Resolves: #1202801 - Backport patch to with upower 1.0 API + +* Tue Sep 02 2014 Daniel Vrátil - 4.10.5-21 +- Resolves: bz#1090492 - changing calendar settings does not appear in plasmoid until month changed (fixed patch) +- Resolves: bz#1109936 - incorrect dispaly corner detection with multiple displays (fixed patch) + +* Wed Aug 20 2014 Than Ngo - 4.10.5-20 +- Resolves: bz#1040678 - cannot assign custom keyboard shortcut for Show Desktop Grid +- Resolves: bz#1090492 - changing calendar settings does not appear in plasmoid until month changed +- Resolves: bz#1109936 - incorrect dispaly corner detection with multiple displays + +* Mon Aug 18 2014 Than Ngo - 4.10.5-19 +- Resolves: bz#1109987 +- Resolves: bz#1060058 +- Resolves: bz#1043686 + +* Mon Apr 28 2014 Than Ngo - 4.10.5-18 +- Resolves: bz#1091087 + +* Thu Mar 06 2014 Jan Grulich - 4.10.5-17 +- Fix some warnings from coverity scan + +* Tue Mar 04 2014 Jan Grulich - 4.10.5-16 +- Last try to fix rhbz#1067111 + +* Sat Mar 01 2014 Jan Grulich - 4.10.5-15 +- Really resolves: rhbz#1067111 + +* Fri Feb 28 2014 Than Ngo - 4.10.5-14 +- add missing xsessions + +* Thu Feb 27 2014 Than Ngo - 4.10.5-13 +- Exclude kdm + +* Mon Feb 24 2014 Jan Grulich - 4.10.5-12 +- Resolves: rhbz#1067111 - adding second panel on second monitor places panel on top + +* Wed Feb 19 2014 Than Ngo - 4.10.5-11 +- fix branding issue + +* Fri Jan 24 2014 Daniel Mach - 4.10.5-10 +- Mass rebuild 2014-01-24 + +* Fri Dec 27 2013 Daniel Mach - 4.10.5-9 +- Mass rebuild 2013-12-27 + +* Fri Dec 06 2013 Lukáš Tinkl - 4.10.5-8 +- Resolves: rhbz#990146 - Timezone changed to Bratislava instead of Prague + +* Wed Oct 30 2013 Than Ngo - 4.10.5-7 +- bz#1001708, Out of range date +- bz#1001727, "RTC time" is not changed when using time server + +* Wed Aug 07 2013 Than Ngo - 4.10.5-6 +- rebuilt + +* Tue Aug 06 2013 Than Ngo - 4.10.5-5 +- enable libkscreen + +* Wed Jul 24 2013 Than Ngo - 4.10.5-4 +- cleanup + +* Wed Jul 17 2013 Than Ngo - 4.10.5-3 +- CVE-2013-4132, backport systray icons memleak fix +- CVE-2013-4133, backport potential kcheckpass security issue + +* Tue Jul 02 2013 Than Ngo - 4.10.5-2 +- drop the rejected KMix memory leak workaround + +* Sun Jun 30 2013 Than Ngo - 4.10.5-1 +- 4.10.5 + +* Wed Jun 26 2013 Rex Dieter 4.10.4-6 +- kmix: media track change memory leaks with pulseaudio+oxygen widget style (kde#309464, #912457) + +* Fri Jun 14 2013 Lukáš Tinkl - 4.10.4-5 +- fix kickoff menu kbd navigation (kdebz#310166) + +* Fri Jun 14 2013 Daniel Vrátil - 4.10.4-4 +- add upstream patch for #921742 + +* Thu Jun 13 2013 Martin Briza - 4.10.4-3 +- Fix VT numbers on starting a new session (#857366) + +* Tue Jun 11 2013 Daniel Vrátil - 4.10.4-2 +- backport upstream patch for #921781 + +* Sat Jun 01 2013 Rex Dieter - 4.10.4-1 +- 4.10.4 + +* Mon May 06 2013 Than Ngo - 4.10.3-1 +- 4.10.3 +- restore patch omitting broken launchers + +* Fri May 03 2013 Rex Dieter - 4.10.2-12 +- -DKDE4_ENABLE_FPIE:BOOL=ON +- don't write fonts.conf on load (kde#105797) + +* Mon Apr 29 2013 Than Ngo - 4.10.2-11 +- drop old patch for aurora +- fix multilib issue + +* Mon Apr 29 2013 Martin Briza 4.10.2-10 +- changed the systemd-displaymanager patch to switch the sessions using systemd-logind, too + +* Thu Apr 25 2013 Martin Briza 4.10.2-9 +- regenerated the systemd-displaymanager patch against latest upstream master +- worked around #955374 before I fix it clean upstream + +* Wed Apr 24 2013 Rex Dieter 4.10.2-8 +- avoid/revert commit to avoid plasma crash on wallpaper change (kde#318806) + +* Mon Apr 22 2013 Than Ngo - 4.10.2-7 +- fedora/rhel condition + +* Sun Apr 21 2013 Rex Dieter 4.10.2-6 +- sync to latest 4.10 branch commits + +* Thu Apr 18 2013 Rex Dieter 4.10.2-5 +- drop LD_BIND_NOW from startkde (#908380) +- fold all startkde-related patches into redhat_startkde.patch + +* Thu Apr 11 2013 Daniel Vrátil 4.10.2-4 +- clear screenlocker password on ESC (#949452) + +* Thu Apr 11 2013 Martin Briza 4.10.2-3 +- added basic support for automatic multi-seat in KDM (#884271) + +* Tue Apr 09 2013 Rex Dieter 4.10.2-2 +- rebase systray_ktp-presence patch for applet rename + +* Sun Mar 31 2013 Rex Dieter 4.10.2-1 +- 4.10.2 + +* Sun Mar 24 2013 Rex Dieter 4.10.1-3 +- don't apply no_HAL on el6 + +* Wed Mar 13 2013 Rex Dieter 4.10.1-2 +- PowerDevil should use upower to suspend on F17 (#920874) +- other small upstream fixes (xrandrbrightness, login1 leak, stop screensaver) + +* Sat Mar 02 2013 Rex Dieter 4.10.1-1 +- 4.10.1 + +* Wed Feb 20 2013 Rex Dieter 4.10.0-11 +- python-scriptengine-python: s/Requires: PyKDE4/Requires: pykde4/ + +* Fri Feb 15 2013 Rex Dieter 4.10.0-10 +- respin BUILD_KCM_RANDR.patch, avoid failure in startkde when krandrstartup doesn't exist + +* Fri Feb 15 2013 Rex Dieter 4.10.0-9 +- drop solid_krunner_disable patch (seems better now) + +* Thu Feb 14 2013 Rex Dieter 4.10.0-8 +- kscreen support => disable all of kcontrol/randr (f19+ currently) + +* Sat Feb 09 2013 Rex Dieter 4.10.0-7 +- fedora-plasma-cache.sh: don't delete Trolltech.conf + +* Sat Feb 09 2013 Rex Dieter 4.10.0-6 +- tweak fedora-plasma-cache.sh for plasma-svgelements*, Trolltech.conf too +- enable powerdevil-login1 support on f18 + +* Fri Feb 08 2013 Rex Dieter 4.10.0-5 +- fix fedora-plasma-cache.sh (to not exit) + +* Thu Feb 07 2013 Lukáš Tinkl 4.10.0-4 +- fix wrong description and size for 2-stage USB storage devices + +* Mon Feb 04 2013 Rex Dieter 4.10.0-3 +- refresh Powerdevil login1 patch + +* Sat Feb 02 2013 Kevin Kofler - 4.10.0-2 +- fix kcmdatetimehelper search path so hwclock and zic are found (#906854) + +* Thu Jan 31 2013 Rex Dieter - 4.10.0-1 +- 4.10.0 + +* Wed Jan 30 2013 Lukáš Tinkl 4.9.98-7 +- update Powerdevil login1 patch + +* Mon Jan 28 2013 Rex Dieter 4.9.98-6 +- unconditionally Obsoletes: kded_randrmonitor + +* Mon Jan 28 2013 Rex Dieter 4.9.98-5 +- Requires: kscreen, Obsoletes: kded_randrmonitor (f19+) + +* Mon Jan 28 2013 Rex Dieter 4.9.98-4 +- drop Requires: kde-display-management (for now) +- switch fedora-plasma-cache hack to env script + +* Fri Jan 25 2013 Rex Dieter 4.9.98-3 +- add fedora-plasma-cache kconf_update script + +* Tue Jan 22 2013 Rex Dieter 4.9.98-2 +- respin systemd_login1 patch + +* Sun Jan 20 2013 Rex Dieter - 4.9.98-1 +- 4.9.98 + +* Fri Jan 18 2013 Adam Tkac - 4.9.97-6 +- rebuild due to "jpeg8-ABI" feature drop + +* Mon Jan 14 2013 Rex Dieter 4.9.97-5 +- refresh powerdevil_systemd_login1 patch (kde review#108407) + +* Mon Jan 14 2013 Rex Dieter 4.9.97-4 +- proper powerdevil systemd-login1 support (kde review#108407) + +* Thu Jan 10 2013 Rex Dieter 4.9.97-3 +- hack to use org.freedesktop.login1 to handle suspend (instead of upower), + seems to help avoid double-sleep (#859227) + +* Wed Jan 09 2013 Rex Dieter 4.9.97-2 +- kded_xrandrmonitor subpkg, to allow use of it or kscreen + +* Fri Jan 04 2013 Rex Dieter - 4.9.97-1 +- 4.9.97 + +* Thu Dec 20 2012 Rex Dieter - 4.9.95-1 +- 4.9.95 + +* Thu Dec 06 2012 Martin Briza 4.9.90-2 +- Merged and cleaned the systemd shutdown and logout patches. +- It is possible to use systemd and/or CK without defining it at compile time + +* Mon Dec 03 2012 Rex Dieter 4.9.90-1 +- 4.9.90 (4.10 beta2) + +* Mon Dec 03 2012 Than Ngo - 4.9.4-1 +- 4.9.4 + +* Fri Nov 16 2012 Martin Briza - 4.9.3-3 +- user switching dialog now doesn't list inactive (closing) sessions and more information is retrieved from logind + +* Thu Nov 15 2012 Rex Dieter - 4.9.3-2 +- pull upstream fix for some regressions (krunner, analog clock) +- drop unused llvm_whitelist patch + +* Fri Nov 02 2012 Rex Dieter 4.9.3-1 +- 4.9.3 + +* Fri Nov 02 2012 Than Ngo - 4.9.2-10 +- rhel/fedora condition + +* Thu Nov 1 2012 Lukáš Tinkl 4.9.2-9 +- build against prison only under Fedora + +* Tue Oct 30 2012 Rex Dieter 4.9.2-8 +- more systemd_inhibit love (#859227, kde#307412) + +* Fri Oct 26 2012 Rex Dieter 4.9.2-7 +- rework fontconfig patch to ensure $XDG_CONFIG_HOME/fontconfig exists + +* Thu Oct 18 2012 Rex Dieter 4.9.2-6 +- monitor sleep settings reset, resulting in monitor turning off (kde#295164) + +* Mon Oct 08 2012 Martin Briza 4.9.2-5 +- Fixing user switching with SystemD (#859347), for LightDM + +* Thu Oct 04 2012 Rex Dieter 4.9.2-4 +- ongoing systemd_inhibit work (#859227) + +* Mon Oct 01 2012 Rex Dieter 4.9.2-3 +- tarball respin (includes plasma/python2 patch) + +* Mon Oct 01 2012 Lukáš Tinkl - 4.9.2-2 +- fix loading of Python2 plasmoids + +* Fri Sep 28 2012 Rex Dieter - 4.9.2-1 +- 4.9.2 + +* Thu Sep 27 2012 Rex Dieter 4.9.1-7 +- disable plasma-runner-solid by default (kde#307445) + +* Fri Sep 21 2012 Lukáš Tinkl 4.9.1-6 +- update the systemd PowerDevil Policy Agent patch to match the upstream + version (part of KDE 4.9.2) +- update clock applets on system date/time changes + +* Tue Sep 18 2012 Lukáš Tinkl 4.9.1-5 +- fix device notifier Free Space meter + +* Thu Sep 13 2012 Lukáš Tinkl 4.9.1-4 +- hopefully also solve the screen dimming issue when inactive session goes idle + +* Thu Sep 13 2012 Lukáš Tinkl 4.9.1-3 +- Resolves #849334 - screen lock failure (laptop lid) + +* Wed Sep 05 2012 Rex Dieter 4.9.1-2 +- upstream patch for kwin regression (kde#306260, kde#306275) + +* Mon Sep 03 2012 Than Ngo - 4.9.1-1 +- 4.9.1 + +* Mon Aug 27 2012 Lukáš Tinkl 4.9.0-6 +- Resolves #851887 - KDE Logout does not Suspend to RAM/Disk + +* Tue Aug 21 2012 Rex Dieter 4.9.0-5 +- Add apper to default kickoff favorites (#850445) + +* Thu Aug 09 2012 Rex Dieter 4.9.0-4 +- upstream patch for aurora/qml-based kwin decorations + +* Tue Aug 07 2012 Rex Dieter 4.9.0-3 +- window keeps status 'asking for attention' after gaining focus (kde#303208) + +* Fri Aug 03 2012 Rex Dieter 4.9.0-2 +- kcm_fonts should use $XDG_CONFIG_HOME/fontconfig/fonts.conf for storage settings for fontconfig > 2.10.0 (kde#304317) + +* Thu Jul 26 2012 Lukas Tinkl - 4.9.0-1 +- 4.9.0 + +* Thu Jul 19 2012 Fedora Release Engineering - 4.8.97-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Thu Jul 12 2012 Than Ngo - 4.8.97-2 +- remove obsolete stuffs in startkde, kde-4.6.x already uses QLocale + to try obtain a default country. + +* Wed Jul 11 2012 Rex Dieter - 4.8.97-1 +- 4.8.97 + +* Tue Jul 10 2012 Rex Dieter 4.8.95-4 +- fix tooltip for OpticalDisc + +* Mon Jul 09 2012 Rex Dieter 4.8.95-3 +- Battery Monitor widget stops tracking charging state changes after suspend/resume cycle (#837345, kde#287952) + +* Tue Jul 03 2012 Rex Dieter 4.8.95-2 +- restore stable kdecoration API to 4.8 (#831958, kde#301728) + +* Wed Jun 27 2012 Jaroslav Reznik - 4.8.95-1 +- 4.8.95 +- remove battery size patch + +* Mon Jun 25 2012 Rex Dieter 4.8.90-3 +- Requires: konsole + +* Tue Jun 19 2012 Rex Dieter 4.8.90-2 +- battery plasmoid icon does not scale below a certain size (kde#301877) + +* Sat Jun 09 2012 Rex Dieter - 4.8.90-1 +- 4.8.90 + +* Fri Jun 01 2012 Jaroslav Reznik 4.8.80-4 +- respin +- remove kwin check opengl patch + +* Tue May 29 2012 Rex Dieter 4.8.80-3 +- Provides: plasma4(scriptengine-declarativescript) + +* Sat May 26 2012 Kevin Kofler - 4.8.80-2 +- new showremainingtime patch, now just defaults the option to true + (It doesn't have ugly side effects anymore with the rewritten plasmoid.) + +* Sat May 26 2012 Jaroslav Reznik - 4.8.80-1 +- 4.8.80 +- remove remaining time patch, should be enabled in kde-settings + +* Tue May 08 2012 Than Ngo - 4.8.3-4 +- add rhel/fedora conditions + +* Wed May 02 2012 Rex Dieter 4.8.3-3 +- more work on plasma clock widget/locale crash (kde#299237) + +* Wed May 02 2012 Rex Dieter 4.8.3-2 +- plasma clock widget/locale crash (kde#299237) + +* Mon Apr 30 2012 Jaroslav Reznik - 4.8.3-1 +- 4.8.3 +- kdm grub2 integration upstreamed + +* Tue Apr 3 2012 Lukas Tinkl 4.8.2-3 +- respin 4.8.2 tarball + +* Sun Apr 01 2012 Rex Dieter 4.8.2-2 +- Kwin does not repaint window shadow regions after closing window (#808791, kde#297272) + +* Fri Mar 30 2012 Jaroslav Reznik - 4.8.2-1 +- 4.8.2 + +* Mon Mar 19 2012 Kevin Kofler 4.8.1-7 +- rebuild for plasma4.prov fix (no more spaces in Plasma runner auto-Provides) + +* Thu Mar 15 2012 Rex Dieter 4.8.1-6 +- Requires: kactivities >= %%{version} + +* Wed Mar 14 2012 Kevin Kofler 4.8.1-5 +- fix another bug in the systemd shutdown/restart patch (missing parameter) + +* Tue Mar 13 2012 Kevin Kofler 4.8.1-4 +- fix bugs in the systemd shutdown/restart patch + +* Mon Mar 12 2012 Rex Dieter 4.8.1-3 +- Port shutdown/restart code from ConsoleKit to systemd (#788171) + +* Thu Mar 08 2012 Rex Dieter 4.8.1-2 +- 4.8 branch commit for settings_style support + +* Mon Mar 05 2012 Jaroslav Reznik - 4.8.1-1 +- 4.8.1 +- removed powerdevil verb., eDP and gcc47 patches + +* Tue Feb 28 2012 Rex Dieter 4.8.0-12 +- kdm restart/shutdown does not work (#796969) + +* Wed Feb 22 2012 Rex Dieter 4.8.0-11 +- drop ConsoleKit support f17+ + +* Wed Feb 22 2012 Rex Dieter 4.8.0-10 +- kdm: Requires: ConsoleKit-x11 (#787855) + +* Tue Feb 21 2012 Rex Dieter 4.8.0-9 +- add ktp_presence applet to default systray + +* Tue Feb 21 2012 Rex Dieter 4.8.0-8 +- omit kwin_llvmpipe_whitelist patch, not ready/testable (#794835) + +* Mon Feb 13 2012 Rex Dieter 4.8.0-7 +- kwin llvmpipe whitelist (#790142) +- powerdevil verbosity++ (kde#289760) + +* Sat Feb 11 2012 Rex Dieter 4.8.0-6 +- kdm-grub2 integration (#785849) + +* Tue Feb 07 2012 Kevin Kofler 4.8.0-5 +- kde-workspace: Requires: ConsoleKit (shutdown/restart, works around #788171) +- kdm: Requires: ConsoleKit (works around #787855, nasty error message on login) + +* Thu Feb 02 2012 Rex Dieter 4.8.0-4 +- eDP patch (kde#289760) + +* Tue Jan 31 2012 Rex Dieter 4.8.0-3 +- kgreeter-plugins subpkg (#785817) + +* Tue Jan 24 2012 Rex Dieter 4.8.0-2 +- kcm_colors subpkg (#761184) +- kdm-themes: Requires: kde-wallpapers unconditionally (#784389) +- s/kdebase-runtime/kde-runtime/ + +* Fri Jan 20 2012 Jaroslav Reznik - 4.8.0-1 +- 4.8.0 + +* Wed Jan 04 2012 Rex Dieter 4.7.97-10 +- rename kdebase-workspace -> kde-workspace + +* Wed Jan 04 2012 Radek Novacek - 4.7.97-1 +- 4.7.97 + +* Tue Jan 03 2012 Rex Dieter 4.7.95-3 +- kdm overwrites ~/.Xauthority with wrong SELinux context on logout (#567914,kde#242065) +- gcc47 fixes + +* Thu Dec 29 2011 Rex Dieter 4.7.95-2 +- startkde: omit MALLOC_CHECK_ debug'ery + +* Wed Dec 21 2011 Radek Novacek 4.7.95-1 +- 4.7.95 +- Add Ariya kdm theme + +* Wed Dec 14 2011 Rex Dieter 4.7.90-3 +-libs: move libkworkspace (versioned) dep here (from -devel) + +* Thu Dec 08 2011 Rex Dieter 4.7.90-2 +- kwin-gles: move kwin4_effect_gles_builtins here + +* Sat Dec 03 2011 Rex Dieter 4.7.90-1 +- 4.7.90 +- BR: libjpeg-devel (ksplash) + +* Thu Dec 01 2011 Rex Dieter 4.7.80-6 +- get some kwin-gles love + +* Tue Nov 29 2011 Rex Dieter 4.7.80-5 +- BR: kactivities-devel + +* Thu Nov 24 2011 Radek Novacek 4.7.80-4 +- Respin with new upstream tarball +- Drop patch: don't use INSTALL to copy file to current binary dir + +* Thu Nov 24 2011 Radek Novacek 4.7.80-3 +- Fixed file listed twice +- Remove big cursors from files (they are no longer in upstream tarball) +- Add new files: libkwinglutils.so*, liboxygenstyleconfig.so* + libpowerdevilconfigcommonprivate.so*, kfontinst.knsrc +- New ksplash theme Minimalistic +- patch: don't use INSTALL to copy file to current binary dir + +* Thu Nov 24 2011 Radek Novacek 4.7.80-2 +- Drop "only show in kde" patch (applied upstream) + +* Fri Nov 18 2011 Jaroslav Reznik 4.7.80-1 +- 4.7.80 (beta 1) + +* Thu Nov 17 2011 Rex Dieter 4.7.3-13 +- add plasma-active patches + +* Thu Nov 17 2011 Rex Dieter 4.7.3-12 +- Crash in TaskManager::TaskItem::task (kde#272495) +- Crashes When Adding Weather Widgets (Geolocation) (kde#277036) + +* Thu Nov 17 2011 Lukas Tinkl 4.7.3-11 +- battery plasmoid fixes (#753429) + +* Wed Nov 16 2011 Lukas Tinkl 4.7.3-10 +- fix kwin + twinview + +* Tue Nov 15 2011 Rex Dieter 4.7.3-9 +- kdm-themes subpkg (#753409) + +* Mon Nov 07 2011 Rex Dieter 4.7.3-8 +- rebuild (libpng) + +* Mon Nov 07 2011 Than Ngo - 4.7.3-7 +- Fix possible uninitialized variable use in ksplashx multi-screen code + +* Fri Nov 04 2011 Rex Dieter 4.7.3-6 +- build against libkactivities-6.1 + +* Tue Nov 01 2011 Rex Dieter 4.7.3-5 +- drop kde-wallpapers (now packaged separately) + +* Tue Nov 01 2011 Rex Dieter 4.7.3-4 +- tarball respin + +* Mon Oct 31 2011 Rex Dieter 4.7.3-3 +- kde-wallpapers: Obsoletes: kdebase-workspace-wallpapers < 4.7.2-10 + +* Mon Oct 31 2011 Rex Dieter 4.7.3-2 +- Requires: kde-settings-ksplash kde-settings-plasma (f16+) + +* Sat Oct 29 2011 Rex Dieter 4.7.3-1 +- 4.7.3 +- -devel: Provides: kde-workspace-devel +- -libs: Provides: kde-workspace-libs + +* Sat Oct 29 2011 Kevin Kofler 4.7.2-12 +- kcm_clock helper: Sync the hwclock after setting the date (#749516) + +* Wed Oct 26 2011 Fedora Release Engineering - 4.7.2-11 +- Rebuilt for glibc bug#747377 + +* Tue Oct 25 2011 Rex Dieter 4.7.2-10 +- BR: libkactivities-devel + +* Mon Oct 24 2011 Rex Dieter 4.7.2-9 +- kdebase-workspace-wallpapers -> kde-wallpapers + +* Fri Oct 21 2011 Alexey Kurov - 4.7.2-8 +- revert patch adding broken launchers (#747982) + +* Mon Oct 17 2011 Rex Dieter 4.7.2-7 +- Generate texture coordinates for limited NPOT support (kde#269576) + +* Sat Oct 15 2011 Kevin Kofler 4.7.2-6 +- drop displayEvents patch, moved to kde-settings (in kde-settings-4.7-12) + +* Thu Oct 13 2011 Rex Dieter 4.7.2-5 +- ksysguard: include ksysguard.desktop + +* Wed Oct 12 2011 Rex Dieter 4.7.2-4 +- plasmaclock displayEvents=false default + +* Mon Oct 10 2011 Rex Dieter 4.7.2-3 +- ksysguard(-libs) subpkg +- libkworkspace subpkg +- kdm: Requires: libkworkspace + +* Tue Oct 04 2011 Rex Dieter 4.7.2-1 +- 4.7.2 + +* Tue Sep 20 2011 Rex Dieter 4.7.1-3 +- switch to pkgconfig-style deps + +* Fri Sep 16 2011 Rex Dieter 4.7.1-2 +- upstream kwin_performance patch +- Use /etc/login.defs to define a 'system' account instead of hard-coding 500 (#732830) + +* Wed Sep 14 2011 Radek Novacek 4.7.1-1 +- Remove upstreamed patch kdebase-workspace-4.7.0-kde#278206.patch + +* Tue Sep 06 2011 Than Ngo - 4.7.1-1 +- 4.7.1 + +* Tue Aug 23 2011 Rex Dieter 4.7.0-9 +- disable google-gadget support (f16+) + +* Sun Aug 21 2011 Kevin Kofler 4.7.0-8 +- rebuild again for the fixed RPM dependency generators for Plasma (#732271) + +* Sun Aug 21 2011 Kevin Kofler 4.7.0-7 +- rebuild for the RPM dependency generators for Plasma (GSoC 2011) + +* Wed Aug 17 2011 Rex Dieter 4.7.0-6 +- upstream kwin malloc patch + +* Sat Aug 13 2011 Rex Dieter 4.7.0-5 +- upstream kwin software rasterizer patch + +* Thu Aug 11 2011 Rex Dieter 4.7.0-4 +- modularize googlegadget/gpsd support a bit + +* Sat Aug 06 2011 Rex Dieter 4.7.0-3 +- drop Requires: nepomukcontroller (included in kde-runtime now) + +* Thu Jul 28 2011 Kevin Kofler 4.7.0-2 +- fix GDM getting misdetected as LightDM (kde#278206, patch by Alex Fiestas) + +* Tue Jul 26 2011 Jaroslav Reznik 4.7.0-1 +- 4.7.0 +- kde4workspace_version is not needed anymore +- Provides: kde-workspace kde-wallpapers (to match new upstream tarballs) + +* Thu Jul 21 2011 Rex Dieter 4.6.95-4 +- rebuild (qt48) + +* Mon Jul 18 2011 Rex Dieter 4.6.95-3 +- Conflicts: kdm < 4.6.90-4 (when kgreet_* plugins moved) + +* Tue Jul 12 2011 Rex Dieter 4.6.95-2 +- fix redhat_startkde.patch + +* Fri Jul 08 2011 Jaroslav Reznik 4.6.95-1 +- 4.6.95 (rc2) + +* Wed Jul 06 2011 Rex Dieter 4.6.90-4 +- move kgreet_* plugins to main pkg, needed by kscreenlocker (#711234) + +* Tue Jul 05 2011 Rex Dieter 4.6.90-3 +- startkde: omit MALLOC_CHECK pieces + +* Thu Jun 30 2011 Rex Dieter 4.6.90-2 +- cleanup/remove some old/deprecated pieces + +* Mon Jun 27 2011 Than Ngo - 4.6.90-1 +- 4.6.90 (rc1) + +* Fri May 27 2011 Jaroslav Reznik 4.6.80-1 +- 4.6.80 (beta1) +- add BR prison-devel + +* Thu May 26 2011 Rex Dieter 4.6.3-9 +- drop BR: libcaptury-devel + +* Wed May 25 2011 Rex Dieter 4.6.3-8 +- virtual desktop names are lost after log out (kde#272666) + +* Sat May 21 2011 Rex Dieter 4.6.3-7 +- multilib QT_PLUGIN_PATH (#704840) + +* Thu May 19 2011 Kevin Kofler 4.6.3-6 +- make nm-09-compat patch F15-only, it won't work on Rawhide anyway + +* Sun May 15 2011 Rex Dieter 4.6.3-5 +- kde4/plugins/styles/oxygen.so is not multilib (#704840) + +* Sun May 08 2011 Kevin Kofler 4.6.3-4 +- nm-09-compat: reenable Solid NM backend build with NM 0.9 (disabled in 4.6.3) + +* Sat Apr 30 2011 Jaroslav Reznik 4.6.3-3 +- fix spurious "Networking system disabled" message (#700831) + +* Fri Apr 29 2011 Rex Dieter 4.6.3-2 +- use updated plymouth patch trying new method first + +* Thu Apr 28 2011 Rex Dieter 4.6.3-1 +- 4.6.3 + +* Thu Apr 21 2011 Kevin Kofler - 4.6.2-4 +- fix kde#270942 (direct rendering disabled on Intel graphics since mesa 7.10.1) + +* Fri Apr 08 2011 Jaroslav Reznik - 4.6.2-3 +- fix the temperature plasmoids and ksysguard temperature sensors regression + +* Thu Apr 07 2011 Lukas Tinkl - 4.6.2-2 +- #694222 - Brightness controls no longer work +- kdebug#257948 - Powerdevil can no longer control brightness +- drop obsolete HAL backlight patch + +* Wed Apr 06 2011 Than Ngo - 4.6.2-1 +- 4.6.2 + +* Tue Apr 05 2011 Rex Dieter 4.6.1-7.1 +- apply no_HAL patches on f14 too + +* Sun Apr 03 2011 Kevin Kofler 4.6.1-7 +- Restore lost hunks from redhat_startkde patch, fixes regressions with running + Qt 3 binaries (Qt 3 Assistant etc.) and with the initial background color +- Fix incorrectly rebased hunk from redhat_startkde patch, fixes regression with + language setting + +* Wed Mar 30 2011 Jaroslav Reznik 4.6.1-6 +- Autohide panel gets visible and does not hide itself (#690450) + +* Thu Mar 24 2011 Dan Williams 4.6.1-5 +- Rebuild with NM 0.9 compat patches (F15+) + +* Thu Mar 24 2011 Rex Dieter 4.6.1-4 +- Notification size increases randomly and cant be restored (#688967) + +* Mon Mar 07 2011 Rex Dieter 4.6.1-3 +- solid_nm_emit patch + +* Mon Mar 07 2011 Rex Dieter 4.6.1-2 +- use system-kde-theme again (ie, lovelock-kde-theme on f15) +- -Requires: system-backgrounds-kde +- +Requires: system-plasma-desktoptheme +- -ksplash-themes: move Default (Air+Horos) ksplash theme here + +* Sat Feb 26 2011 Rex Dieter 4.6.1-1 +- 4.6.1 + +* Fri Feb 11 2011 Rex Dieter 4.6.0-8 +- include Horos wallpaper (upstream default) in main pkg, not -wallpapers + +* Mon Feb 07 2011 Fedora Release Engineering - 4.6.0-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Mon Feb 07 2011 Rex Dieter 4.6.0-6 +- drop Requires: system-{backgrounds,ksplash}-kde, use + generic/upstream theming, for now. + +* Thu Feb 03 2011 Rex Dieter 4.6.0-5 +- oxygen theme crasher (#674792, kde#265271) + +* Wed Jan 26 2011 Rex Dieter 4.6.0-4 +- startkde: drop MALLOC_CHECK bits + +* Tue Jan 25 2011 Lukas Tinkl - 4.6.0-3 +- respun tarball, omit (now upstreamed) PowerDevil + fixes from 4.6.0-2 + +* Mon Jan 24 2011 Lukas Tinkl - 4.6.0-2 +- handle PowerDevil config migration + +* Fri Jan 21 2011 Jaroslav Reznik 4.6.0-1 +- 4.6.0 + +* Tue Jan 18 2011 Jaroslav Reznik 4.5.95-3 +- require nepomukcontroller (temporary) + +* Fri Jan 14 2011 Jaroslav Reznik 4.5.95-2 +- add optional BR libdmtx (data matrix bar-codes support) + +* Wed Jan 05 2011 Jaroslav Reznik 4.5.95-1 +- 4.5.95 (4.6rc2) + +* Wed Dec 22 2010 Rex Dieter 4.5.90-1 +- 4.5.90 (4.6rc1) + +* Sat Dec 04 2010 Lukas Tinkl - 4.5.85-2 +- adjust the HALsectomy patches +- remove solid-powermanagement + +* Sat Dec 04 2010 Thomas Janssen - 4.5.85-1 +- 4.5.85 (4.6beta2) + +* Wed Dec 01 2010 Rex Dieter - 4.5.80-7 +- -googlegadgets => plasma-scriptengine-googlegaddgets +- -python-applet => plasma-scriptengine-python +- (new) plasma-scriptengine-ruby + +* Wed Nov 24 2010 Rex Dieter - 4.5.80-6 +- drop old polkit conditionals +- don't include libpowerdevil{core,ui}.so in -devel + +* Tue Nov 23 2010 Rex Dieter - 4.5.80-5 +- drop Obsoletes: -python-applet + +* Tue Nov 23 2010 Kevin Kofler - 4.5.80-4 +- respun tarball, includes Python script engine fixes + +* Mon Nov 22 2010 Lukas Tinkl - 4.5.80-3 +- disable PowerDevil's HAL backend (aka project HALsectomy) + +* Mon Nov 22 2010 Kevin Kofler - 4.5.80-2 +- backport upstream fixes to reenable and fix the Python script engine + +* Sat Nov 20 2010 Rex Dieter - 4.5.80-1 +- 4.5.80 (4.6beta1) + +* Mon Nov 15 2010 Than Ngo - 4.5.3-3 +- apply patch to fix crash on automatic re-login after automatic login + +* Sat Nov 06 2010 Kevin Kofler - 4.5.3-2 +- drop classicmenu-games patch, upstream fixed the same issue differently and + now the 2 fixes conflict (classic menu confuses Name and Description) + +* Fri Oct 29 2010 Than Ngo - 4.5.3-1 +- 4.5.3 + +* Wed Oct 27 2010 Kevin Kofler - 4.5.2-5 +- use upstream ck-shutdown patch from 4.6 trunk (instead of my old one), + supports GDM session switching (#560511, kde#186198) +- drop old F11- version of the ck-shutdown patch, F11 is EOL + +* Wed Oct 20 2010 Rex Dieter - 4.5.2-4 +- kdebase-workspace depends on xorg-x11-apps (#537609) + +* Sat Oct 16 2010 Rex Dieter - 4.5.2-3 +- backport kwin ui for unredirecting fullscreen windows + +* Fri Oct 15 2010 Rex Dieter - 4.5.2-2 +- include better, upstream fix for: krandr: Display Settings are Lost + on Logout (kdebug183143, rh#607180) + +* Fri Oct 01 2010 Rex Dieter - 4.5.2-1 +- 4.5.2 + +* Wed Sep 29 2010 jkeating - 4.5.1-5 +- Rebuilt for gcc bug 634757 + +* Mon Sep 20 2010 Rex Dieter - 4.5.1-4 +- kdm is not localized when changing lang using system-config-language (#631861) + +* Wed Sep 15 2010 Rex Dieter - 4.5.1-3 +- Provides: firstboot(windowmanager) (#605675) + +* Sun Aug 29 2010 Rex Dieter - 4.5.1-2 +- "fonts/package" is an invalid MIME type (#581896) + +* Fri Aug 27 2010 Jaroslav Reznik - 4.5.1-1 +- 4.5.1 + +* Thu Aug 26 2010 Rex Dieter - 4.5.0-4 +- Requires: iso-codes (for kcm_keyboard) + +* Fri Aug 20 2010 Rex Dieter - 4.5.0-3 +- krunner "run command" doesn't keep any history (kde#247566) + +* Thu Aug 12 2010 Lukas Tinkl - 4.5.0-2 +- disable malloc checking in startkde for releases + +* Tue Aug 03 2010 Than Ngo - 4.5.0-1 +- 4.5.0 +- kde4workspace_version + +* Tue Jul 27 2010 Rex Dieter - 4.4.95-1.py27 +- rebuild for python27 + +* Sun Jul 25 2010 Rex Dieter - 4.4.95-1 +- 4.5 RC3 (4.4.95) + +* Wed Jul 21 2010 David Malcolm - 4.4.92-3 +- Rebuilt for https://fedoraproject.org/wiki/Features/Python_2.7/MassRebuild + +* Fri Jul 16 2010 Rex Dieter - 4.4.92-2 +- omit non-essential xsession .desktop files, runs afoul of selinux (#588130) + +* Wed Jul 07 2010 Rex Dieter - 4.4.92-1 +- 4.5 RC2 (4.4.92) + +* Fri Jun 25 2010 Kevin Kofler - 4.4.90-2 +- port and reapply rootprivs (#434824) patch + +* Fri Jun 25 2010 Jaroslav Reznik - 4.4.90-1 +- 4.5 RC1 (4.4.90) + +* Wed Jun 23 2010 Rex Dieter - 4.4.85-5 +- krandr: Display Settings are Lost on Logout (kdebug183143, rh#607180) + +* Mon Jun 21 2010 Karsten Hopp 4.4.85-4 +- don't require raw1394 on s390, s390x + +* Sun Jun 13 2010 Rex Dieter - 4.4.85-3 +- Significant CPU penalty for using Kwin effects (kde#239963) + +* Tue Jun 08 2010 Rex Dieter - 4.4.85-2 +- Adding "Enable networking" button to knetworkmanager (rh#598765, kde#238325) +- drop < f12 conditionals +- pciutils, raw1394 & qualculate BRs +- added kcmkdm helper and policy (from kdelibs) + +* Mon Jun 07 2010 Jaroslav Reznik - 4.4.85-1 +- 4.5 Beta 2 (4.4.85) + +* Fri May 28 2010 Rex Dieter - 4.4.80-3 +- Conflicts: kdebase < 6:4.4.80 + +* Tue May 25 2010 Rex Dieter - 4.4.80-2 +- Blur shadow around widgets does not smoothly fade out (kde#235620) + +* Fri May 21 2010 Jaroslav Reznik - 4.4.80-1 +- 4.5 Beta 1 (4.4.80) +- kxkb and safestartkde has been removed +- add newly installed files + +* Sat May 08 2010 Rex Dieter - 4.4.3-2 +- rebuild (gpsd,kdelibs) + +* Fri Apr 30 2010 Jaroslav Reznik - 4.4.3-1 +- 4.4.3 + +* Tue Apr 13 2010 Rex Dieter - 4.4.2-5 +- powerdevil only autosuspends once/twice (kde#221648) +- CVE-2010-0436 + +* Mon Apr 12 2010 Rex Dieter - 4.4.2-4 +- another stab at f13 kdm/plymouth love (#577482) +- powerdevil always suspends twice (kde#221637) + +* Wed Apr 07 2010 Kevin Kofler - 4.4.2-3 +- rip out bulletproof X changes (cf. kubuntu_33_kdm_bulletproof_x.diff) from + our copy of kubuntu_34_kdm_plymouth_transition.diff +- drop experimental novt patch, should not be needed with the working Plymouth + integration and may have side effects (can readd it later if really needed) +- fix icon name in plasma-konsole patch: use XDG icon instead of kappfinder one + +* Tue Apr 06 2010 Rex Dieter - 4.4.2-2 +- try to workaround "X server hogs the CPU (#577482)" by letting X + choose vt itself +- include (but not yet apply) kubuntu_34_kdm_plymouth_transition.diff + +* Mon Mar 29 2010 Lukas Tinkl - 4.4.2-1 +- 4.4.2 + +* Thu Mar 11 2010 Kevin Kofler - 4.4.1-2 +- fix KSysGuard and KRunner System Activity dialog not refreshing (kde#230187) + +* Sat Feb 27 2010 Rex Dieter - 4.4.1-1 +- 4.4.1 + +* Fri Feb 26 2010 Kevin Kofler - 4.4.0-8 +- fix the Games menu in the classic menu mixing up Name and Description + +* Fri Feb 19 2010 Rex Dieter - 4.4.0-7 +- version solid-bluetooth(-devel) better + +* Fri Feb 19 2010 Rex Dieter - 4.4.0-6 +- solid-bluetooth and Requires: bluez ... pulls unwanted baggage (#566306) + +* Tue Feb 16 2010 Rex Dieter - 4.4.0-5.1 +- Requires: kbluetooth ( - 4.4.0-5 +- fix incorrectly rebased classicmenu-logout patch (#564536) + +* Thu Feb 11 2010 Than Ngo - 4.4.0-4 +- move xsession desktop files to main package + (cannot start kde from gdm if kdm not installed) +- Desktop locking crashes (kde#217882#16) + +* Thu Feb 11 2010 Jaroslav Reznik - 4.4.0-3 +- requires bluez for solid-bluetooth + +* Tue Feb 09 2010 Kevin Kofler - 4.4.0-2.1 +- use old ck-shutdown patch without the CanStop check on F11 (#562851) + +* Mon Feb 08 2010 Than Ngo - 4.4.0-2 +- apply upstream patch to fix Plasma Memory Leak and High CPU usage + +* Fri Feb 05 2010 Than Ngo - 4.4.0-1 +- 4.4.0 + +* Tue Feb 02 2010 Kevin Kofler - 4.3.98-3 +- support the widgetStyle4 hack in the Qt KDE platform plugin + +* Mon Feb 01 2010 Kevin Kofler - 4.3.98-2 +- rebase battery-plasmoid-showremainingtime patch and remove references to 4.2 + +* Sun Jan 31 2010 Rex Dieter - 4.3.98-1 +- KDE 4.3.98 (4.4rc3) + +* Sat Jan 30 2010 Kevin Kofler - 4.3.95-2 +- ck-shutdown: don't offer shutdown/restart when not allowed by CK (#529644) + +* Thu Jan 21 2010 Lukas Tinkl - 4.3.95-1 +- KDE 4.3.95 (4.4rc2) + +* Thu Jan 21 2010 Jaroslav Reznik - 4.3.90-10 +- fix polkit-1 conditionals + +* Wed Jan 20 2010 Kevin Kofler - 4.3.90-9 +- fix infinite recursion in the patch for #556643 + +* Tue Jan 19 2010 Rex Dieter - 4.3.90-8 +- SELinux is preventing /sbin/setfiles "read" access on + /var/spool/gdm/force-display-on-active-vt (deleted) (#556643) + +* Sun Jan 17 2010 Rex Dieter - 4.3.90-7 +- rebuild (libxklavier) + +* Thu Jan 14 2010 Jaroslav Reznik - 4.3.90-6 +- fix KDM's missing header build problem +- polkit-qt BR for polkit-1 + +* Mon Jan 11 2010 Rex Dieter - 4.3.90-5 +- do not link calendar dataengine with Akonadi (kde#215150, rh#552473) +- s/plasma-engine/plasma-dataengine/ + +* Sat Jan 09 2010 Rex Dieter - 4.3.90-4 +- krunner crasher (kde#221871) + +* Fri Jan 08 2010 Rex Dieter - 4.3.90-3 +- rebuild (kdelibs polkit-1 macros) + +* Wed Jan 06 2010 Rex Dieter - 4.3.90-2 +- drop -akonadi subpkg + +* Wed Jan 06 2010 Rex Dieter - 4.3.90-1 +- kde-4.3.90 (4.4rc1) + +* Tue Jan 05 2010 Kevin Kofler - 4.3.85-3 +- F13+: don't Obsoletes: PolicyKit-kde, let polkit-kde obsolete it +- F13+: explicitly require polkit-kde instead of PolicyKit-authentication-agent + +* Sat Jan 02 2010 Rex Dieter - 4.3.85-2 +- startkde: disable MALLOC_CHECK_ + +* Fri Dec 18 2009 Rex Dieter - 4.3.85-1 +- kde-4.3.85 (4.4beta2) + +* Wed Dec 16 2009 Jaroslav Reznik - 4.3.80-5 +- Repositioning the KDE Brand (#547361) + +* Fri Dec 11 2009 Rex Dieter - 4.3.80-4 +- SELinux is preventing access to a leaked .xsession-errors-:0 file descriptor (#542312) + +* Wed Dec 09 2009 Kevin Kofler - 4.3.80-3 +- drop polkit-qt* Obsoletes, we have a new polkit-qt now + +* Wed Dec 09 2009 Rex Dieter - 4.3.80-2 +- BR: shared-desktop-ontologies-devel + +* Tue Dec 01 2009 Lukáš Tinkl - 4.3.80-1 +- KDE 4.4 beta1 (4.3.80) +- kdm_plymouth patch (#475890) + +* Sat Nov 28 2009 Kevin Kofler - 4.3.75-0.4.svn1048496 +- backport battery plasmoid from current pre-4.3.80 trunk for showremainingtime +- rebase battery-plasmoid-showremainingtime patch +- rebase brightness-keys patch for the above backport + +* Sat Nov 28 2009 Kevin Kofler - 4.3.75-0.3.svn1048496 +- rebase plasma-konsole patch + +* Wed Nov 25 2009 Rex Dieter - 4.3.75-0.2.svn1048496 +- Requires: PolicyKit-authentication-agent unconditionally + +* Sat Nov 21 2009 Ben Boeckel - 4.3.75-0.1.svn1048496 +- update to 4.3.75 snapshot + +* Wed Nov 18 2009 Lukáš Tinkl 4.3.3-8 +- correctly try to deduce LANG (kubuntu_13_startkde_set_country.diff) + +* Fri Nov 13 2009 Rex Dieter 4.3.3-7 +- kubuntu_101_brightness_fn_keys_and_osd.diff (#509295) + +* Fri Nov 13 2009 Than Ngo - 4.3.3-6 +- rhel cleanup, fix conditional for RHEL + +* Thu Nov 12 2009 Rex Dieter - 4.3.3-5 +- fix logic on Requires: kdm (ie, make F-12 builds not include it) + +* Thu Nov 12 2009 Rex Dieter - 4.3.3-4 +- try experimental patch for "keyboard stops working" (kde#171685) + +* Wed Nov 11 2009 Than Ngo - 4.3.3-3 +- rhel cleanup, drop BR on libcaptury-devel + +* Mon Nov 09 2009 Rex Dieter - 4.3.3-2 +- Obsoletes: polkit-qt-examples (f12+) +- -devel: Obsoletes: polkit-qt-devel (f12+) + +* Sat Oct 31 2009 Rex Dieter - 4.3.3-1 +- 4.3.3 +- BR: libXau-devel libXdmcp-devel + +* Thu Oct 15 2009 Rex Dieter - 4.3.2-2 +- drop Requires: oxygen-icon-theme (dep moved to kdebase-runtime) + +* Sun Oct 04 2009 Than Ngo - 4.3.2-1 +- 4.3.2 + +* Sun Sep 27 2009 Kevin Kofler - 4.3.1-9 +- fix classicmenu-logout ("Leave...") patch + +* Sun Sep 27 2009 Kevin Kofler - 4.3.1-8 +- support "Leave..." which brings up complete shutdown dialog in classic menu + +* Fri Sep 25 2009 Than Ngo - 4.3.1-7 +- don't include googlegadgets on RHEL + +* Thu Sep 24 2009 Than Ngo - 4.3.1-6 +- rhel cleanup + +* Wed Sep 23 2009 Lukáš Tinkl - 4.3.1-5 +- fix spontaneous Plasma crashes due to uninitialized vars + +* Mon Sep 14 2009 Kevin Kofler - 4.3.1-4 +- drop PolicyKit 0.9 support (PolicyKit-kde) on F12+/EL + +* Sat Sep 12 2009 Rex Dieter - 4.3.1-3 +- -python-applet: Provides: plasma-scriptengine-python +- Requires: system-ksplash-theme (f12+,rhel6+) + +* Fri Sep 11 2009 Than Ngo - 4.3.1-2 +- drop BR: lm_sensors-devel on s390(x) + +* Fri Aug 28 2009 Than Ngo - 4.3.1-1 +- 4.3.1 +- drop Requires: kde-plasma-folderview, rely on comps instead + +* Fri Aug 28 2009 Mamoru Tasaka - 4.3.0-102 +- Fix typo + +* Thu Aug 27 2009 Rex Dieter - 4.3.0-101 +- inflate Release tag, avoiding possible upgrade/obsoletes pain +- -devel: drop Provides: PolicyKit-kde-devel, bump Obsoletes + +* Thu Aug 27 2009 Rex Dieter - 4.3.0-12 +- PolicyKit-kde subpkg (#519172, #519654) + +* Wed Aug 26 2009 Rex Dieter - 4.3.0-11 +- Requires: system-backgrounds-kde (f12+) + +* Tue Aug 25 2009 Rex Dieter - 4.3.0-10 +- Requires: kde-plasma-folderview + +* Sun Aug 23 2009 Rex Dieter - 4.3.0-9 +- -akonadi: move plasma_engine_calendar here +- drop Requires: kdm (F-12+) + +* Wed Aug 19 2009 Rex Dieter - 4.3.0-8 +- adjust default-applets patch to not load plasma-networkmanagement + +* Tue Aug 18 2009 Lukáš Tinkl - 4.3.0-7 +- move akonadi stuff to subpackage + +* Fri Aug 07 2009 Rex Dieter - 4.3.0-6 +- Requires: oxygen-icon-theme >= 4.3.0 + +* Tue Aug 04 2009 Than Ngo - 4.3.0-5 +- respin + +* Mon Aug 03 2009 Than Ngo - 4.3.0-4 +- respin + +* Mon Aug 03 2009 Kevin Kofler - 4.3.0-3 +- show the remaining time in the battery plasmoid's popup (as in 4.2) (#515166) + +* Sat Aug 01 2009 Rex Dieter - 4.3.0-2 +- move designer plugins to -libs, fixes + Multilib conflicts for index.cache.bz2 (#515088) +- tighten -libs deps, using %%{?_isa} +- %%check: desktop-file-validate + +* Thu Jul 30 2009 Than Ngo - 4.3.0-1 +- 4.3.0 + +* Mon Jul 27 2009 Lukáš Tinkl - 4.2.98-3 +- backport forgotten method impl in Solid from 4.3 branch, r1000715 + +* Fri Jul 24 2009 Fedora Release Engineering - 4.2.98-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Wed Jul 22 2009 Than Ngo - 4.2.98-1 +- 4.3rc3 + +* Thu Jul 09 2009 Than Ngo - 4.2.96-1 +- 4.3rc2 + +* Mon Jul 06 2009 Than Ngo - 4.2.95-7 +- plasma-desktop crashes when closing/opening windows (upstream patch) + +* Fri Jul 03 2009 Kevin Kofler - 4.2.95-6 +- add kde-plasma-networkmanagement to the default panel if installed + +* Wed Jul 01 2009 Michel Salim - 4.2.95-5 +- rebuild (google-gadgets) + +* Wed Jul 01 2009 Rex Dieter 4.2.95-4 +- rebuild (libxklavier) + +* Mon Jun 29 2009 Rex Dieter 4.2.95-3 +- omit a few kdm bits from main pkg (#508647) + +* Mon Jun 29 2009 Kevin Kofler - 4.2.95-2 +- port and reapply rootprivs (#434824) patch (#508593) +- fix internal version number (otherwise it mismatches with our file list) + +* Fri Jun 26 2009 Than Ngo - 4.2.95-1 +- 4.3rc1 + +* Thu Jun 18 2009 Rex Dieter 4.2.90-3 +- startkde: make MALLOC_CHECK opt-in (default off) + +* Fri Jun 12 2009 Rex Dieter 4.2.90-2 +- bump Obsoletes: PolicyKit-kde + +* Wed Jun 03 2009 Rex Dieter 4.2.90-1 +- KDE-4.3 beta2 (4.2.90) + +* Sun May 31 2009 Kevin Kofler - 4.2.85-5 +- make default_leonidas.png the default face icon on F11 + +* Sat May 30 2009 Rex Dieter 4.2.85-4 +- -devel: exclude libkickoff.so, libsystemsettingsview.so +- drop old cmake crud + +* Fri May 29 2009 Rex Dieter 4.2.85-3 +- omit/revert session-button patch (kde#194506,rh#502953) +- drop unused knotificationitem-1 patch + +* Wed May 27 2009 Rex Dieter 4.2.85-2 +- upgrade path broken (F-11+), Obsoletes: guidance-power-manager (#502892) +- drop < F-10 crud, have_bluez3 + +* Mon May 11 2009 Than Ngo 4.2.85-1 +- 4.2.85 +- Obsoletes/Provides: PolicyKit-kde(-devel) + +* Wed May 06 2009 Than Ngo - 4.2.3-2 +- Requires: oxygen-icon-theme >= 4.2.2 +- fix oxygen-cursor-themes noarch'ness + +* Sun May 03 2009 Than Ngo - 4.2.3-1 +- 4.2.3 + +* Tue Apr 28 2009 Lukáš Tinkl - 4.2.2-5 +- #497657 - kpackagekit/kopete notification misrendering/missing + buttons with qt-4.5.1 + +* Wed Apr 22 2009 Than Ngo - 4.2.2-4 +- dropp unused BR on libraw1394, it breaks the build on s390(x) + +* Sun Apr 12 2009 Rex Dieter - 4.2.2-3 +- Calendar standalone plasmoid on Desktop using 100% of CPU (kde#187699) + +* Wed Apr 01 2009 Rex Dieter - 4.2.2-2 +- optimize scriptlets +- drop upstreamed patches + +* Mon Mar 30 2009 Lukáš Tinkl - 4.2.2-1 +- KDE 4.2.2 + +* Mon Mar 23 2009 Than Ngo - 4.2.1-12 +- upstream patch to fix suspending issue + +* Mon Mar 23 2009 Rex Dieter - 4.2.1-11 +- Obsoletes: guidance-power-manager (-> powerdevil upgrade path, F-11+) + +* Wed Mar 18 2009 Than Ngo - 4.2.1-10 +- upstream patch to fix MenuEntryActions created from khotkeys + +* Mon Mar 16 2009 Rex Dieter - 4.2.1-9 +- kdm subpkg +- -devel: move cmake modules here +- Requires: kdelibs4%%{?_isa} .. +- BR: libutempter-devel (drops need for kwrited helper) + +* Thu Mar 12 2009 Rex Dieter - 4.2.1-8 +- oxygen-cursor-themes: make noarch (f10+) + +* Thu Mar 12 2009 Rex Dieter - 4.2.1-7 +- fix quicklauch (kdebug#185585,rh#489769) +- -wallpapers: make noarch (f10+) + +* Tue Mar 10 2009 Than Ngo - 4.2.1-6 +- fix konsole patch to use invokeTerminal + +* Mon Mar 9 2009 Lukáš Tinkl - 4.2.1-5 +- fix pager not displaying desktop numbers (kdebug#184152) + +* Mon Mar 09 2009 Rex Dieter - 4.2.1-4 +- kde 4.2 update crashes plasma (kdebug#185736) + +* Wed Mar 04 2009 Rex Dieter - 4.2.1-3 +- move designer plugins to main/runtime (#487622) + +* Tue Mar 03 2009 Than Ngo - 4.2.1-2 +- respin + +* Fri Feb 27 2009 Than Ngo - 4.2.1-1 +- 4.2.1 + +* Thu Feb 26 2009 Jaroslav Reznik - 4.2.0-17 +- kio_sysinfo kick-off integration + +* Tue Feb 24 2009 Jaroslav Reznik - 4.2.0-16 +- no klipper action on selection for Arora browser + +* Fri Feb 20 2009 Rex Dieter - 4.2.0-15 +- Provides: service(graphical-login) = kdm + +* Fri Feb 20 2009 Rex Dieter - 4.2.0-14 +- Requires: oxygen-icon-theme >= %%version + +* Thu Feb 19 2009 Rex Dieter - 4.2.0-13 +- dpms issues (kdebug#177123) + +* Wed Feb 18 2009 Than Ngo - 4.2.0-12 +- drop the BR on PyKDE4, it's just needed for runtime +- python-applet subpackage + +* Tue Feb 17 2009 Than Ngo - 4.2.0-11 +- googlegadgets subpackage + +* Mon Feb 16 2009 Kevin Kofler - 4.2.0-10 +- fix shutdown dialog not centered, sometimes entirely off screen (kde#181199) + +* Wed Feb 11 2009 Than Ngo - 4.2.0-9 +- fix kdm crash with Qt-4.5 + +* Mon Feb 09 2009 Rex Dieter - 4.2.0-8 +- kickoff logout shuts down system (#484737, kdebug#180576) + +* Sun Feb 08 2009 Rex Dieter - 4.2.0-7 +- include awol rss dataengine, BR: kdepimlibs-devel (see also kdebug#179050) + +* Fri Jan 30 2009 Rex Dieter - 4.2.0-4.2 +- respin default_applets patch for kpowersave too (#483163) + +* Thu Jan 29 2009 Kevin Kofler - 4.2.0-4.1 +- conditionalize bluetooth backport on F10+ +- F9: revert solid-bluetooth to the version from KDE 4.1.4 + +* Thu Jan 29 2009 Rex Dieter - 4.2.0-4 +- omit ldap hack (#457638), kde42's reduced linkage to the rescue + +* Thu Jan 29 2009 Rex Dieter - 4.2.0-3 +- Requires: PyKDE4 (for plasmascript bits) +- solid-bluetoothTrunkTo42.diff (bug #481801), and + +Provides: solid-bluetooth(-devel) = 4.3 + +* Wed Jan 28 2009 Than Ngo - 4.2.0-2 +- readd the patch that omist battery applet when guidance-power-manager is installed + +* Thu Jan 22 2009 Than Ngo - 4.2.0-1 +- 4.2.0 + +* Fri Jan 16 2009 Than Ngo - 4.1.96-4 +- backport fix from trunk to allow symlinks in wallpaper theme + +* Wed Jan 14 2009 Rex Dieter - 4.1.96-3 +- BR: google-gadgets-devel > 0.10.5 + +* Fri Jan 09 2009 Than Ngo - 4.1.96-2 +- remove Provides: plasma-devel + +* Wed Jan 07 2009 Than Ngo - 4.1.96-1 +- 4.2rc1 + +* Tue Dec 23 2008 Rex Dieter 4.1.85-7 +- Obsoletes: kpowersave (kpowersave -> powerdevil upgrade path, F-11+) + +* Mon Dec 22 2008 Rex Dieter 4.1.85-6 +- (re)enable edje, google-gadget support + +* Thu Dec 18 2008 Kevin Kofler 4.1.85-5 +- drop BR edje-devel, we need QEdje instead, which we don't have yet +- comment out BR google-gadgets-* for now, need 0.10.4, have 0.10.3 + +* Thu Dec 18 2008 Rex Dieter - 4.1.85-4 +- BR: edje-devel +- BR: google-gadgets-devel + +* Tue Dec 16 2008 Rex Dieter - 4.1.85-3 +- respun tarball + +* Fri Dec 12 2008 Rex Dieter - 4.1.85-2 +- BR: PyKDE4-devel >= %%version + +* Thu Dec 11 2008 Than Ngo - 4.1.85-1 +- 4.2beta2 + +* Wed Dec 10 2008 Lorenzo Villani - 4.1.82-1 +- 4.1.82 +- rebase redhat-startkde patch + +* Fri Dec 05 2008 Kevin Kofler 4.1.80-12 +- move libplasma_applet-system-monitor.so from -devel to -libs (not a symlink) + +* Fri Dec 05 2008 Kevin Kofler 4.1.80-11 +- drop devel symlink (parallel -devel) hacks, not needed anymore in this package + +* Tue Dec 02 2008 Kevin Kofler 4.1.80-10 +- keep libtaskmanager.so in libdir + +* Tue Dec 02 2008 Kevin Kofler 4.1.80-9 +- keep libweather_ion.so in libdir + +* Tue Dec 02 2008 Kevin Kofler 4.1.80-8 +- keep libplasmaclock.so in libdir + +* Mon Dec 01 2008 Kevin Kofler 4.1.80-7 +- rebuild for Python 2.6 + +* Thu Nov 27 2008 Kevin Kofler 4.1.80-6 +- disable Logitech mouse KCM again until #399931 is fixed + +* Thu Nov 27 2008 Lorenzo Villani - 4.1.80-5 +- use python_sitearch for x86_64 systems +- kephal seems to be disabled/removed, re-adapted file lists + +* Tue Nov 25 2008 Than Ngo 4.1.80-4 +- respin + +* Sun Nov 23 2008 Lorenzo Villani - 4.1.80-3 +- rebase kdebase-workspace-4.1.1-show-systemsettings.patch +- new library: Kephal -> adapt file lists + +* Wed Nov 19 2008 Than Ngo 4.1.80-2 +- merged +- drop kdebase-workspace-4.1.2-kdm-i18n.patch, it's included in upstream +- drop kdebase-workspace-4.0.85-plasma-default-wallpaper.patch, it's included in upstream +- drop kdebase-workspace-4.1.65-consolekit-kdm.patch +- add kdebase-workspace-4.1.80-session-button.patch +- add kdebase-workspace-4.1.2-ldap.patch + +* Wed Nov 19 2008 Lorenzo Villani - 4.1.80-1 +- 4.1.80 +- BR cmake >= 2.6.2 +- make install/fast +- drop _default_patch_fuzz 2 +- rebase startkde patch +- rebase plasma-konsole patch +- rebase ck-shutdown patch +- add PyKDE4-devel, python-devel and PyQt4-devel to build plasma's python + scripting interface +- BR google-gadgets-devel for google gadgets scriptengine +- BR libusb-devel for Logitech USB support in KControl + +* Thu Nov 13 2008 Than Ngo  4.1.3-5 +- apply upstream patch to fix X crash when disabling compositing + +* Wed Nov 12 2008 Than Ngo 4.1.3-1 +- 4.1.3 + +* Fri Nov 07 2008 Than Ngo 4.1.2-14 +- only omit battery applet when guidance-power-manager is installed + +* Fri Nov 07 2008 Rex Dieter 4.1.2-13 +- omit battery applet from default panel + +* Wed Nov 05 2008 Than Ngo 4.1.2-12 +- fix i18n issue in kdm + +* Tue Nov 04 2008 Than Ngo 4.1.2-11 +- add workaround for ldap issue (#457638) + +* Sun Nov 02 2008 Kevin Kofler 4.1.2-10 +- never touch PATH in startkde, prepending $QTDIR/bin is unnecessary on Fedora + and breaks locating Qt 3 Assistant and other Qt 3 stuff (startkde gets run + with a full path by KDM) + +* Sat Nov 01 2008 Than Ngo 4.1.2-9 +- previous session button should be enabled + +* Fri Oct 31 2008 Than Ngo 4.1.2-8 +- apply patch to fix multihead issue +- bz#469235, use non-blocking QProcess:startDetacted + +* Sat Oct 25 2008 Kevin Kofler 4.1.2-7 +- F10: use KDM default face icon from solar-kde-theme, require it + +* Sat Oct 18 2008 Kevin Kofler 4.1.2-6 +- reenable panel-autohide-fix-flicker patch +- backport revision 866998 to fix the CPU consumption problem (kde#172549) +- backport panelview.cpp coordinate fixes (revisions 869882, 869925, 870041) +- backport revision 871058 (request config sync when panel controller goes away) + +* Fri Oct 10 2008 Kevin Kofler 4.1.2-5 +- disable panel-autohide-fix-flicker patch for now, eats CPU + +* Thu Oct 09 2008 Kevin Kofler 4.1.2-4 +- backport panel autohide from 4.2 / plasma-4.1-openSUSE + +* Wed Oct 8 2008 Lukáš Tinkl 4.1.2-3 +- fix crash when invoking a klipper command for a second time + +* Sun Sep 28 2008 Rex Dieter 4.1.2-2 +- make VERBOSE=1 +- respin against new(er) kde-filesystem + +* Fri Sep 26 2008 Rex Dieter 4.1.2-1 +- 4.1.2 + +* Mon Sep 01 2008 Kevin Kofler 4.1.1-2 +- show KCM icon in rootprivs patch (thanks to Harald Sitter "apachelogger") + +* Thu Aug 28 2008 Than Ngo 4.1.1-1 +- 4.1.1 + +* Mon Aug 04 2008 Kevin Kofler 4.1.0-8 +- patch another place where systemsettings was hidden from the menu (#457739) + +* Mon Aug 04 2008 Kevin Kofler 4.1.0-7 +- enable KWin taskbarthumbnail effect (used by backported tooltip manager) + +* Fri Aug 01 2008 Rex Dieter 4.1.0-6 +- patch to help krandr issues/crashes (kde#152914) + +* Fri Aug 01 2008 Lukáš Tinkl 4.1.0-5 +- fix 457479: "Run as root" dialog of kdm system settings is shown twice + (due to activated signal being connected to twice) + +* Fri Aug 01 2008 Kevin Kofler 4.1.0-4 +- fix KDM configuration using the wrong appsdir for themes (#455623) + +* Mon Jul 28 2008 Rex Dieter 4.1.0-3 +- respun tarball + +* Sun Jul 27 2008 Kevin Kofler 4.1.0-2 +- updated tooltip manager from 4.2 (fixes Plasma crash on theme change, #456820) + +* Wed Jul 23 2008 Than Ngo 4.1.0-1 +- 4.1.0 + +* Wed Jul 23 2008 Kevin Kofler 4.0.99-5 +- F10+: fix circular kdebase<->kdebase-workspace dependency: don't Obsolete or + Require kdebase, as kdebase now requires kdebase-workspace, obviating the + upgrade path hack + +* Tue Jul 22 2008 Rex Dieter 4.0.99-4 +- oxygen-cursor-themes, -wallpapers subpkgs + +* Sat Jul 19 2008 Kevin Kofler 4.0.99-3 +- BR soprano-devel (optional dependency of the Plasma Engine Explorer) + +* Sat Jul 19 2008 Kevin Kofler 4.0.99-2 +- backport Plasma tooltip manager from KDE 4.2 (fixes regression from 4.0) + WARNING: Adds some new APIs from 4.2 (Plasma::popupPosition, Plasma::viewFor, + Plasma::ToolTip*), use at your own risk, we have no control to + guarantee that they will not change! + +* Fri Jul 18 2008 Rex Dieter 4.0.99-1 +- 4.0.99 + +* Wed Jul 16 2008 Kevin Kofler 4.0.98-8 +- fix KDM ConsoleKit patch to use x11-display-device instead of display-device + +* Wed Jul 16 2008 Kevin Kofler 4.0.98-7 +- fix segfault in KDM ConsoleKit patch (#455562) + +* Tue Jul 15 2008 Kevin Kofler 4.0.98-6 +- move systemsettings back from System to Settings in the menu + +* Mon Jul 14 2008 Kevin Kofler 4.0.98-5 +- new consolekit-kdm patch using libck-connector, BR ConsoleKit-devel (#430388) + +* Mon Jul 14 2008 Rex Dieter 4.0.98-4 +- install circles kdm theme + +* Sun Jul 13 2008 Kevin Kofler 4.0.98-3 +- sync kickoff-suspend patch from F9 (loads ksmserver translations) + +* Fri Jul 11 2008 Rex Dieter 4.0.98-2 +- respun tarball (with systray patch) + +* Thu Jul 10 2008 Rex Dieter 4.0.98-1 +- 4.0.98 + +* Wed Jul 09 2008 Kevin Kofler 4.0.85-3 +- rewrite and reapply plasma-default-wallpaper patch +- (no more separate plasma-default-wallpaper-config part) +- rediff kde#154119 patch one last time + +* Wed Jul 09 2008 Rex Dieter 4.0.85-2 +- systray icon patch (kde#164786) + +* Sun Jul 06 2008 Rex Dieter 4.0.85-1 +- 4.0.85 + +* Fri Jun 27 2008 Rex Dieter 4.0.84-1 +- 4.0.84 + +* Fri Jun 27 2008 Kevin Kofler 4.0.83-2 +- port and apply kde#154119/kde#158301 patch for moving icons on panel (#439587) + +* Thu Jun 19 2008 Than Ngo 4.0.83-1 +- 4.0.83 (beta2) + +* Tue Jun 17 2008 Rex Dieter 4.0.82-2 +- +Provides: kdm + +* Sat Jun 14 2008 Rex Dieter 4.0.82-1 +- 4.0.82 + +* Wed Jun 04 2008 Than Ngo 4.0.80-4 +- fix #449881, ksysguard OnlyShowIn=KDE + +* Tue Jun 03 2008 Kevin Kofler 4.0.80-3 +- enable NetworkManager support, now compatible with NM 0.7 + +* Thu May 29 2008 Rex Dieter 4.0.80-2 +- BR: libcaptury-devel + +* Mon May 26 2008 Than Ngo 4.0.80-1 +- 4.1 beta1 + +* Wed May 21 2008 Than Ngo 4.0.72-4 +- fix #447030, hyperlinks do not open correctly in firefox + +* Thu May 08 2008 Rex Dieter 4.0.72-3 +- ksysguardd subpkg (#426543) +- %%config(noreplace) systemsettingsrc + +* Thu May 08 2008 Rex Dieter 4.0.72-2 +- gtkrc patch (rh#443309, kde#146779) + +* Wed May 07 2008 Kevin Kofler 4.0.72-1 +- update to 4.0.72 +- update file list (Lorenzo Villani) +- port plasma-konsole, ck-shutdown, rootprivs, plasma-default-wallpaper patches +- remove NoDisplay=true in systemsettings onlyshowkde patch (still add + OnlyShowIn=KDE), rename to show-systemsettings +- drop upstreamed suspend patch +- drop backported kde#155362 and menu-switch patches +- drop rh#443610 patch, "Zoom Out" should be working in 4.1 +- disable kde#158301 patch for now (fails to apply, looks hard to port) + +* Fri May 02 2008 Rex Dieter 4.0.3-20 +- Requires: kdebase , so it doesn't go missing on upgrades from kde3 (#444928) + +* Mon Apr 28 2008 Lukáš Tinkl 4.0.3-19 +- #444141: Initial wallpaper chooser has "EOS" preselected but wallpaper is "Fedora Waves" + +* Sun Apr 27 2008 Kevin Kofler 4.0.3-18 +- don't show "Zoom Out" toolbox action (#443610, patch from openSUSE branch) + +* Sat Apr 19 2008 Kevin Kofler 4.0.3-17 +- allow moving plasmoids on panels (#439587, kde#158301) (upstream patch) + +* Fri Apr 18 2008 Than Ngo 4.0.3-16 +- fix #442559, Suspend/Hibernate issue on logout + +* Tue Apr 15 2008 Lukáš Tinkl 4.0.3-15 +- workaround #434824: KDE4 System Settings - No Method To Enter Administrative Mode +- fix #441062: packagekit tools do not show icons correctly on KDE + +* Tue Apr 15 2008 Sebastian Vahl 4.0.3-13 +- update redhat-startkde.patch to match waves background color (#442312) + +* Fri Apr 11 2008 Lukáš Tinkl 4.0.3-12 +- allow to define a default wallpaper (plasmarc:wallpaper) + +* Wed Apr 09 2008 Kevin Kofler 4.0.3-11 +- read the default KSplash theme from kde-settings in startkde (#441565) + +* Mon Apr 07 2008 Kevin Kofler 4.0.3-7 +- own %%{_kde4_appsdir}/kdm/faces and set default user image (#441154) + +* Thu Apr 03 2008 Kevin Kofler 4.0.3-6 +- rebuild for the fixed %%{_kde4_buildtype} + +* Mon Mar 31 2008 Kevin Kofler 4.0.3-5 +- update file list for _kde4_libexecdir + +* Mon Mar 31 2008 Kevin Kofler 4.0.3-4 +- backport context menu switch between Kickoff and simple menu from 4.1 + +* Sat Mar 29 2008 Kevin Kofler 4.0.3-3 +- add support for shutdown/reboot through ConsoleKit >= 0.2.4 (#431817) + +* Fri Mar 28 2008 Kevin Kofler 4.0.3-2 +- most of the kde#155362 patch has been merged, keep only the config part + +* Fri Mar 28 2008 Than Ngo 4.0.3-1 +- 4.0.3 + +* Fri Mar 28 2008 Than Ngo 4.0.2-9 +- add onlyshowin=KDE for systemsetting + +* Thu Mar 13 2008 Than Ngo 4.0.2-8 +- backport upstream patch to fix crash in kmenuedit when users + delete entry and save it + +* Wed Mar 12 2008 Than Ngo 4.0.2-7 +- apply upstream patch to fix changing wallpaper causes desktop to go white +- apply upstream patch to check whether the to-be-embedded window has been destroyed, (bz#437058) + +* Mon Mar 10 2008 Than Ngo 4.0.2-6 +- add gestures=false in kde-settings, remove kdebase-workspace-4.0.2-Gestures.patch + +* Thu Mar 06 2008 Than Ngo 4.0.2-5 +- typo fix + +* Tue Mar 04 2008 Than Ngo 4.0.2-4 +- disable gestures as default +- add konsole in desktop menu + +* Mon Mar 03 2008 Than Ngo 4.0.2-3 +- apply upstream patch to fix crash in khotkeys + +* Fri Feb 29 2008 Kevin Kofler 4.0.2-2 +- drop upstreamed kde#155974 patch +- update kde#155362 patch + +* Thu Feb 28 2008 Than Ngo 4.0.2-1 +- 4.0.2 + +* Mon Feb 25 2008 Rex Dieter 4.0.1-8 +- %%files: don't own %%_kde4_libdir/kde4/plugins (thanks wolfy!) + +* Sat Feb 16 2008 Kevin Kofler 4.0.1-7 +- omit broken disk space checking hunk from redhat-startkde patch (#426871) + +* Wed Feb 06 2008 Rex Dieter 4.0.1-6 +- revert Conflicts, it matches against Provides from kdelibs3. + +* Wed Feb 06 2008 Rex Dieter 4.0.1-5 +- Conflicts: kdelibs < 6:4 (temporary, to ease upgrade pain) +- -devel: Requires: %%name-libs + +* Mon Feb 04 2008 Kevin Kofler 4.0.1-4 +- backport enhancement to allow multi-line taskbar from 4.1 (kde#155974) + +* Mon Feb 04 2008 Than Ngo 4.0.1-3 +- respin + +* Fri Feb 01 2008 Kevin Kofler 4.0.1-2 +- update kde#155362 (simple menu) patch for 4.0.1 (thanks to Jan Mette) + +* Wed Jan 30 2008 Rex Dieter 4.0.1-1 +- 4.0.1 + +* Wed Jan 30 2008 Rex Dieter 4.0.0-8 +- respin (qt4) + +* Sat Jan 26 2008 Kevin Kofler 4.0.0-7 +- backport simple menu enhancement to show .desktop Name from 4.1 (kde#155362) + +* Wed Jan 23 2008 Rex Dieter 4.0.0-6 +- Obsoletes: kdebase < 6:4 + +* Wed Jan 09 2008 Rex Dieter 4.0.0-5 +- initial login with white background (#428131, kde#155122) + +* Wed Jan 09 2008 Rex Dieter 4.0.0-4 +- use upstream systemtray patch (#427442, kde#153193) + +* Tue Jan 08 2008 Rex Dieter 4.0.0-3 +- respun tarball +- omit gtk_applet patch (for now, doesn't build) + +* Tue Jan 08 2008 Rex Dieter 4.0.0-2 +- omit plasma-pager patch +- pull upstream patch to workaround gtk applet crasher (#427442) + +* Mon Jan 07 2008 Kevin Kofler 4.0.0-1 +- update to 4.0.0 +- drop upstreamed creategtkrc-gtk212 patch +- update redhat-startkde and consolekit-kdm patches + +* Mon Dec 31 2007 Kevin Kofler - 3.97.0-5 +- fix createGtkrc to set tooltip colors also for GTK+ 2.12+ + +* Sun Dec 30 2007 Kevin Kofler 3.97.0-4 +- Obsoletes: kdmtheme + +* Mon Dec 17 2007 Rex Dieter 3.97.0-3 +- Requires: coreutils dbus-x11 xorg-x11-apps xorg-x11-utils + xorg-x11-server-utils (used in startkde) +- drop pam configs that were previously moved to kde-settings + +* Tue Dec 11 2007 Kevin Kofler 3.97.0-2 +- rebuild for changed _kde4_includedir + +* Wed Dec 05 2007 Rex Dieter 3.96.2-3 +- fix kdm/kcheckpass/kscreensaver to get working + +* Sat Dec 01 2007 Sebastian Vahl 3.96.2-2 +- BR: dbus-devel +- crystalsvg icons are not part of kdebase-workspace anymore +- make sure libkdeinit_plasma.so is in normal package + +* Sat Dec 01 2007 Rex Dieter 3.96.2-1 +- kde-3.96.2 + +* Sat Dec 01 2007 Kevin Kofler 3.96.1-4 +- Obsoletes and Provides kdebase-kdm for upgrades from old kde-redhat + +* Fri Nov 30 2007 Kevin Kofler 3.96.1-3 +- update and apply redhat-startkde patch +- update and apply KDM ConsoleKit patch (#228111, kde#147790) +- ConsoleKit patch also includes xdmcp fixes from Mandriva (#243560) + +* Wed Nov 28 2007 Rex Dieter 3.96.1-2 +- %%doc README COPYING +- -libs subpkg +- -libs: Requires: kdelibs4 +- don't remove libplasma.so from %%{_kde4_libdir} +- %%files: use %%_datadir for dbus-1/interfaces,xsessions + +* Mon Nov 19 2007 Sebastian Vahl 3.96.1-1 +- kde-3.96.1 + +* Mon Nov 19 2007 Sebastian Vahl 3.96.0-7 +- use kde.desktop from /usr/share/apps/kdm/sessions/kde.desktop +- use %%config(noreplace) for /etc/ksysguarddrc +- Requires: kdebase, kdebase-runtime, oxygen-icon-theme +- fix url + +* Mon Nov 19 2007 Sebastian Vahl 3.96.0-6 +- add patch to get pager in plasma bar +- re-added BR: libraw1394-devel + +* Mon Nov 19 2007 Sebastian Vahl 3.96.0-5 +- leave libkworkspace.so for kate +- BR: kde-filesystem >= 4 + +* Mon Nov 19 2007 Sebastian Vahl 3.96.0-4 +- BR: libXtst-devel +- BR: libXScrnSaver-devel + +* Fri Nov 16 2007 Sebastian Vahl 3.96.0-3 +- own some more directories +- add %%defattr to package devel +- some spec cleanups +- -R: kdepimlibs-devel +- +BR: libXpm-devel +- +BR: glib2-devel (do we really need this?) + +* Thu Nov 15 2007 Sebastian Vahl 3.96.0-2 +- BR: libXxf86misc-devel +- BR: libXxf86misc-devel +- BR: libXcomposite-devel +- BR: bluez-libs-devel +- BR: libxklavier-devel +- BR: pam-devel +- BR: lm_sensors-devel +- BR: libXdamage-devel +- BR: libXv-devel +- BR: libXres-devel + +* Wed Nov 14 2007 Sebastian Vahl 3.96.0-1 +- kde-3.96.0 + +* Wed Nov 14 2007 Sebastian Vahl 3.95.2-1 +- Initial version of kdebase-workspace