summaryrefslogtreecommitdiffstats
path: root/opensuse
diff options
context:
space:
mode:
authorRobert Xu <robxu9@gmail.com>2011-08-24 17:26:04 -0400
committerRobert Xu <robxu9@gmail.com>2011-08-24 17:26:04 -0400
commit93c66bf8bb8ac0124ae1800cbaaeb814742bfac5 (patch)
tree2551422a7981b35684110fae090223b7a1b6d73f /opensuse
parent425774d7d1d663e08bb06050924f2eeca9147bba (diff)
downloadtde-packaging-93c66bf8bb8ac0124ae1800cbaaeb814742bfac5.tar.gz
tde-packaging-93c66bf8bb8ac0124ae1800cbaaeb814742bfac5.zip
dbus-1-tqt -> libdbus-tqt-1-0 AND tdelibs import (unchanged)
Diffstat (limited to 'opensuse')
-rw-r--r--opensuse/dbus-1-tqt/baselibs.conf1
-rwxr-xr-xopensuse/gentarball4
-rw-r--r--opensuse/libdbus-tqt-1-0/README.VERSION (renamed from opensuse/dbus-1-tqt/README.VERSION)0
-rw-r--r--opensuse/libdbus-tqt-1-0/baselibs.conf1
-rw-r--r--opensuse/libdbus-tqt-1-0/dbus-qt3-compile-fix-thoenig-01.patch (renamed from opensuse/dbus-1-tqt/dbus-qt3-compile-fix-thoenig-01.patch)0
-rw-r--r--opensuse/libdbus-tqt-1-0/dbus-qt3-do-not-close-shared-connection-thoenig-01.patch (renamed from opensuse/dbus-1-tqt/dbus-qt3-do-not-close-shared-connection-thoenig-01.patch)0
-rw-r--r--opensuse/libdbus-tqt-1-0/dbus-tqt-0.62.tar.bz2bin0 -> 187005 bytes
-rw-r--r--opensuse/libdbus-tqt-1-0/libdbus-tqt-1-0.changes (renamed from opensuse/dbus-1-tqt/dbus-1-tqt.changes)5
-rw-r--r--opensuse/libdbus-tqt-1-0/libdbus-tqt-1-0.spec (renamed from opensuse/dbus-1-tqt/dbus-1-tqt.spec)14
-rw-r--r--opensuse/tdebase/3_5_BRANCH.diff1176
-rw-r--r--opensuse/tdebase/access.diff51
-rw-r--r--opensuse/tdebase/applet-lock-logout.diff122
-rw-r--r--opensuse/tdebase/arts-start-on-demand.diff98
-rw-r--r--opensuse/tdebase/artwork.diff35
-rw-r--r--opensuse/tdebase/autorun.patch27
-rw-r--r--opensuse/tdebase/background_default.diff13
-rw-r--r--opensuse/tdebase/baselibs.conf2
-rw-r--r--opensuse/tdebase/beagle-0.3.diff21
-rw-r--r--opensuse/tdebase/bnc.desktop8
-rw-r--r--opensuse/tdebase/bnc584223.diff189
-rw-r--r--opensuse/tdebase/clock-applet-style.diff22
-rw-r--r--opensuse/tdebase/clock-suse-integrate.diff288
-rw-r--r--opensuse/tdebase/console8x16.pcf.gzbin0 -> 12244 bytes
-rw-r--r--opensuse/tdebase/default-kdeprintfax.diff13
-rw-r--r--opensuse/tdebase/default_fonts.diff25
-rw-r--r--opensuse/tdebase/devmon-automounter.sh1086
-rw-r--r--opensuse/tdebase/dont-always-start-kaccess.diff66
-rw-r--r--opensuse/tdebase/fileshareset.8.gzbin0 -> 1086 bytes
-rw-r--r--opensuse/tdebase/fileshareset2.tar.bz2bin0 -> 8677 bytes
-rw-r--r--opensuse/tdebase/fix-desktop-icons.diff250
-rw-r--r--opensuse/tdebase/fix-kcontrol-yast.diff63
-rw-r--r--opensuse/tdebase/fix-kio-smb-auth.diff13
-rw-r--r--opensuse/tdebase/fix-lockup-from-gnome-apps.diff20
-rw-r--r--opensuse/tdebase/fix_default_theme_reset.diff59
-rw-r--r--opensuse/tdebase/gcc44.diff20
-rw-r--r--opensuse/tdebase/hide-only-showin-entries.diff14
-rw-r--r--opensuse/tdebase/improve-panelservicemenu-geticonset.diff32
-rw-r--r--opensuse/tdebase/ioslaveinfo-icon.diff13
-rw-r--r--opensuse/tdebase/kcheckpass-pam-11.06
-rw-r--r--opensuse/tdebase/kcheckpass-pam-11.15
-rw-r--r--opensuse/tdebase/kcheckpass-pam-legacy7
-rw-r--r--opensuse/tdebase/kcheckpass.8.gzbin0 -> 836 bytes
-rw-r--r--opensuse/tdebase/kcminit-ignore-arts.diff14
-rw-r--r--opensuse/tdebase/kcmkdm-default-grub.diff13
-rw-r--r--opensuse/tdebase/kcmsamba_log.diff31
-rw-r--r--opensuse/tdebase/kcmshell_use_kde-sound.diff11
-rw-r--r--opensuse/tdebase/kcontrol-energy.diff167
-rw-r--r--opensuse/tdebase/kcontrol.diff11
-rw-r--r--opensuse/tdebase/kde3-session-restore.diff12
-rw-r--r--opensuse/tdebase/kde3-session.diff13
-rw-r--r--opensuse/tdebase/kdebase_khc_rellinks.diff606
-rw-r--r--opensuse/tdebase/kdebase_networkstatus_branch.diff36
-rw-r--r--opensuse/tdebase/kdeeject.diff58
-rw-r--r--opensuse/tdebase/kdesktop_icons.diff311
-rw-r--r--opensuse/tdebase/kdesu-remember-keep-password.diff18
-rw-r--r--opensuse/tdebase/kdesud-security.diff21
-rw-r--r--opensuse/tdebase/kdm-admin-mode.diff424
-rw-r--r--opensuse/tdebase/kdm-aliasing.diff11
-rw-r--r--opensuse/tdebase/kdm-align-userlist-labels.diff46
-rw-r--r--opensuse/tdebase/kdm-all-users-nopass.diff34
-rw-r--r--opensuse/tdebase/kdm-audit-log.diff190
-rw-r--r--opensuse/tdebase/kdm-color-scheme.diff28
-rw-r--r--opensuse/tdebase/kdm-consolekit.diff822
-rw-r--r--opensuse/tdebase/kdm-cope-with-new-grub.diff27
-rw-r--r--opensuse/tdebase/kdm-make_it_cool.diff1534
-rw-r--r--opensuse/tdebase/kdm-mark_autologin.diff13
-rw-r--r--opensuse/tdebase/kdm-pam-np-legacy7
-rw-r--r--opensuse/tdebase/kdm-relaxed-auth.diff22
-rw-r--r--opensuse/tdebase/kdm-suspend-hal.diff331
-rw-r--r--opensuse/tdebase/kdm-sysconfig-values.diff737
-rw-r--r--opensuse/tdebase/kdm-use-rpmoptflags.diff29
-rw-r--r--opensuse/tdebase/kdm-wordbreak.diff22
-rw-r--r--opensuse/tdebase/kfontinst.diff10
-rw-r--r--opensuse/tdebase/khelpcenter-beagle.diff172
-rw-r--r--opensuse/tdebase/khelpcenter-delayed-indexcheck.cpp23
-rw-r--r--opensuse/tdebase/khelpcenter-gnome-support-legacy.patch327
-rw-r--r--opensuse/tdebase/khelpcenter-gnome-support.patch335
-rw-r--r--opensuse/tdebase/khelpcenter-localindices.patch41
-rw-r--r--opensuse/tdebase/khelpcenter-use-suseconfig-indexer.diff25
-rw-r--r--opensuse/tdebase/khelpcenter-use-susehelp.diff13
-rw-r--r--opensuse/tdebase/khotkeys-multimedia-action.diff345
-rw-r--r--opensuse/tdebase/khotkeys-multimedia-action2.diff81
-rw-r--r--opensuse/tdebase/kicker-defaults.diff57
-rw-r--r--opensuse/tdebase/kickerrc63
-rw-r--r--opensuse/tdebase/kickoff-beagle.diff1329
-rw-r--r--opensuse/tdebase/kickoff-data.tar.bz2bin0 -> 581352 bytes
-rw-r--r--opensuse/tdebase/kickoff-install-software.diff25
-rw-r--r--opensuse/tdebase/kickoff-kcm.diff217
-rw-r--r--opensuse/tdebase/kickoff.diff9812
-rw-r--r--opensuse/tdebase/kio-media-errorhandling.diff18
-rw-r--r--opensuse/tdebase/klipperrc.diff22
-rw-r--r--opensuse/tdebase/kmenu-search-fs20050503-fixed.diff342
-rw-r--r--opensuse/tdebase/kmenu-search-slowdown-fix.diff129
-rw-r--r--opensuse/tdebase/knetattach-show.diff7
-rw-r--r--opensuse/tdebase/kompmgr_use_defaults.diff34
-rw-r--r--opensuse/tdebase/konq-combo-editor.diff42
-rw-r--r--opensuse/tdebase/konsole-schema-update.diff33
-rw-r--r--opensuse/tdebase/konsole_keytab.diff17
-rw-r--r--opensuse/tdebase/kpamgreeter.diff852
-rw-r--r--opensuse/tdebase/krandr-0.5.2.1.diff.bz2bin0 -> 22752 bytes
-rw-r--r--opensuse/tdebase/kscreensaver-random-NG.diff189
-rw-r--r--opensuse/tdebase/ksmserver-defaulttohalt.diff13
-rw-r--r--opensuse/tdebase/ksmserver-kdeinit.diff67
-rw-r--r--opensuse/tdebase/ksmserver-suspend.diff233
-rw-r--r--opensuse/tdebase/ksmserver-timed.diff700
-rw-r--r--opensuse/tdebase/ksmserver-tooltips.diff38
-rw-r--r--opensuse/tdebase/ksplashml.patch19
-rw-r--r--opensuse/tdebase/ksysguard-slp-ratelimit.diff15
-rw-r--r--opensuse/tdebase/ksysguardd-openslp.diff288
-rw-r--r--opensuse/tdebase/ksysguardd.init80
-rw-r--r--opensuse/tdebase/ksysguardd.reg12
-rw-r--r--opensuse/tdebase/kwinbindings.diff43
-rw-r--r--opensuse/tdebase/kxkb-include-latin-layout.diff14
-rw-r--r--opensuse/tdebase/less_verbal_kdesu.patch26
-rw-r--r--opensuse/tdebase/libkonq-kdemm.diff117
-rw-r--r--opensuse/tdebase/locale-dont-show-flag.diff33
-rw-r--r--opensuse/tdebase/lock-xvkbd.diff380
-rw-r--r--opensuse/tdebase/lowdiskspace.patch413
-rw-r--r--opensuse/tdebase/mach_blass.diff160
-rw-r--r--opensuse/tdebase/make-wallpapers-hideable.diff48
-rw-r--r--opensuse/tdebase/media-cryptosupport.diff31
-rw-r--r--opensuse/tdebase/media-iPod.diff26
-rw-r--r--opensuse/tdebase/media-teardown_crypto.diff175
-rw-r--r--opensuse/tdebase/media_suse.diff49
-rw-r--r--opensuse/tdebase/mediamanager-mount-point-utf8.diff13
-rw-r--r--opensuse/tdebase/minicli-combo-editor.diff34
-rw-r--r--opensuse/tdebase/mp3-info.tar.bz2bin0 -> 2606 bytes
-rw-r--r--opensuse/tdebase/mtab-reenable.patch153
-rw-r--r--opensuse/tdebase/non-fast-malloc.diff15
-rw-r--r--opensuse/tdebase/nsplugin-Preference.diff13
-rw-r--r--opensuse/tdebase/nsplugin-init-gtk.diff49
-rw-r--r--opensuse/tdebase/openssl1.patch40
-rw-r--r--opensuse/tdebase/optional-compmgr.diff32
-rw-r--r--opensuse/tdebase/quick_browser_menu.diff30
-rw-r--r--opensuse/tdebase/remove-beagle-stuff.diff34
-rw-r--r--opensuse/tdebase/restore-description-parens.diff13
-rw-r--r--opensuse/tdebase/rotate-wacom-pointers.diff291
-rw-r--r--opensuse/tdebase/runupdater.patch133
-rw-r--r--opensuse/tdebase/select-wm-gui.diff635
-rw-r--r--opensuse/tdebase/short-menus.diff209
-rw-r--r--opensuse/tdebase/show-konqueror-in-menu.diff30
-rw-r--r--opensuse/tdebase/simplify-randr-settings.diff91
-rw-r--r--opensuse/tdebase/sourceforge.desktop7
-rw-r--r--opensuse/tdebase/spellcheck-default-utf8.diff13
-rw-r--r--opensuse/tdebase/startkde.diff80
-rw-r--r--opensuse/tdebase/startkde.suse.sh140
-rw-r--r--opensuse/tdebase/stopkde.suse.sh13
-rw-r--r--opensuse/tdebase/suse_default_move.diff83
-rw-r--r--opensuse/tdebase/suspend-kpowersave.diff178
-rw-r--r--opensuse/tdebase/suspend-unmount.diff179
-rw-r--r--opensuse/tdebase/system-folder_man.diff13
-rw-r--r--opensuse/tdebase/systray_order.diff162
-rw-r--r--opensuse/tdebase/taskbar.patch29
-rw-r--r--opensuse/tdebase/tdebase.changes5422
-rw-r--r--opensuse/tdebase/tdebase.fillup25
-rw-r--r--opensuse/tdebase/tdebase.spec1851
-rw-r--r--opensuse/tdebase/teach-minicli-lock.diff30
-rw-r--r--opensuse/tdebase/uninit.diff10
-rw-r--r--opensuse/tdebase/use-full-hinting-by-default.diff35
-rw-r--r--opensuse/tdebase/use-pam-before-classic.diff17
-rw-r--r--opensuse/tdebase/wizard_small.pngbin0 -> 40259 bytes
-rw-r--r--opensuse/tdebase/workaround-pdf-on64bit-nsplugin-bug.diff44
-rw-r--r--opensuse/tdebase/xcursor.diff36
-rw-r--r--opensuse/tdebase/xinerama.patch951
-rw-r--r--opensuse/tdebase/zh_TW.flag.pngbin0 -> 175 bytes
-rw-r--r--opensuse/tdelibs/kdelibs-3.5.12.99.tar.bz2bin0 -> 14993135 bytes
-rw-r--r--opensuse/tdelibs/tdelibs.spec3
167 files changed, 38035 insertions, 9 deletions
diff --git a/opensuse/dbus-1-tqt/baselibs.conf b/opensuse/dbus-1-tqt/baselibs.conf
deleted file mode 100644
index eadc4f615..000000000
--- a/opensuse/dbus-1-tqt/baselibs.conf
+++ /dev/null
@@ -1 +0,0 @@
-dbus-1-tqt
diff --git a/opensuse/gentarball b/opensuse/gentarball
index 9ef2732f7..e9498c0ba 100755
--- a/opensuse/gentarball
+++ b/opensuse/gentarball
@@ -49,7 +49,7 @@ if [ "$SELECTION" = "1" ]; then
clear
echo "Dependencies: Select what you want us to generate."
echo "(1) libtqt4"
- echo "(2) dbus-1-tqt"
+ echo "(2) libdbus-tqt-1-0"
echo "(3) libdbus-1-tqt-0"
echo "(4) arts"
read CHOICE
@@ -66,9 +66,11 @@ elif [ "$SELECTION" = "2" ]; then
clear
echo "Main: Select what you want us to generate."
echo "(1) tdelibs"
+ echo "(2) tdebase"
read CHOICE
if [ "$CHOICE" = "1" ]; then NAME='kdelibs';
+ elif [ "$CHOICE" = "2" ]; then NAME='kdebase';
else
echo "Invalid, bye." && exit 1
fi
diff --git a/opensuse/dbus-1-tqt/README.VERSION b/opensuse/libdbus-tqt-1-0/README.VERSION
index 3167a4836..3167a4836 100644
--- a/opensuse/dbus-1-tqt/README.VERSION
+++ b/opensuse/libdbus-tqt-1-0/README.VERSION
diff --git a/opensuse/libdbus-tqt-1-0/baselibs.conf b/opensuse/libdbus-tqt-1-0/baselibs.conf
new file mode 100644
index 000000000..245517231
--- /dev/null
+++ b/opensuse/libdbus-tqt-1-0/baselibs.conf
@@ -0,0 +1 @@
+libdbus-tqt-1-0
diff --git a/opensuse/dbus-1-tqt/dbus-qt3-compile-fix-thoenig-01.patch b/opensuse/libdbus-tqt-1-0/dbus-qt3-compile-fix-thoenig-01.patch
index 00b8b6026..00b8b6026 100644
--- a/opensuse/dbus-1-tqt/dbus-qt3-compile-fix-thoenig-01.patch
+++ b/opensuse/libdbus-tqt-1-0/dbus-qt3-compile-fix-thoenig-01.patch
diff --git a/opensuse/dbus-1-tqt/dbus-qt3-do-not-close-shared-connection-thoenig-01.patch b/opensuse/libdbus-tqt-1-0/dbus-qt3-do-not-close-shared-connection-thoenig-01.patch
index 3cc726de1..3cc726de1 100644
--- a/opensuse/dbus-1-tqt/dbus-qt3-do-not-close-shared-connection-thoenig-01.patch
+++ b/opensuse/libdbus-tqt-1-0/dbus-qt3-do-not-close-shared-connection-thoenig-01.patch
diff --git a/opensuse/libdbus-tqt-1-0/dbus-tqt-0.62.tar.bz2 b/opensuse/libdbus-tqt-1-0/dbus-tqt-0.62.tar.bz2
new file mode 100644
index 000000000..b56ca56e6
--- /dev/null
+++ b/opensuse/libdbus-tqt-1-0/dbus-tqt-0.62.tar.bz2
Binary files differ
diff --git a/opensuse/dbus-1-tqt/dbus-1-tqt.changes b/opensuse/libdbus-tqt-1-0/libdbus-tqt-1-0.changes
index 152c611cd..c3d66974d 100644
--- a/opensuse/dbus-1-tqt/dbus-1-tqt.changes
+++ b/opensuse/libdbus-tqt-1-0/libdbus-tqt-1-0.changes
@@ -1,4 +1,9 @@
-------------------------------------------------------------------
+Wed Aug 24 19:36:38 UTC 2011 - rxu@lincomlinux.org
+
+- fix naming error: libdbus-tqt-1-0
+
+-------------------------------------------------------------------
Sat Aug 13 16:49:42 UTC 2011 - rxu@lincomlinux.org
- upgrade to trinity dbus-tqt and adjust accordingly
diff --git a/opensuse/dbus-1-tqt/dbus-1-tqt.spec b/opensuse/libdbus-tqt-1-0/libdbus-tqt-1-0.spec
index 1ab86c544..85cfb9d28 100644
--- a/opensuse/dbus-1-tqt/dbus-1-tqt.spec
+++ b/opensuse/libdbus-tqt-1-0/libdbus-tqt-1-0.spec
@@ -18,7 +18,7 @@
# norootforbuild
-Name: dbus-1-tqt
+Name: libdbus-tqt-1-0
BuildRequires: dbus-1 dbus-1-devel libtqt4-devel cmake
URL: http://dbus.freedesktop.org/
License: GPLv2+
@@ -33,13 +33,15 @@ Patch0: dbus-qt3-compile-fix-thoenig-01.patch
Patch1: dbus-qt3-do-not-close-shared-connection-thoenig-01.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
Requires: dbus-1 >= %( echo `rpm -q --queryformat '%{VERSION}-%{RELEASE}' dbus-1`)
+Provides: dbus-1-tqt
%package devel
License: Other uncritical OpenSource License
Summary: Developer package for TQt/KDE bindings for D-Bus
Requires: dbus-1 >= %( echo `rpm -q --queryformat '%{VERSION}-%{RELEASE}' dbus-1`)
Requires: dbus-1-devel >= %( echo `rpm -q --queryformat '%{VERSION}-%{RELEASE}' dbus-1-devel`)
-Requires: dbus-1-tqt = %{version}
+Requires: %{name} = %{version}
+Provides: dbus-1-tqt-devel
AutoReqProv: on
Group: Development/Libraries/TDE
@@ -89,8 +91,8 @@ Authors:
%prep
%setup -n dbus-tqt-%{version} -q
-%patch0 -p0
-%patch1 -p0
+#%patch0 -p0
+#%patch1 -p0
%build
RPM_OPT_FLAGS="${RPM_OPT_FLAGS} -fstack-protector -fno-strict-aliasing -fPIC"
@@ -114,6 +116,7 @@ cd build
make
%install
+cd build
make DESTDIR=%{buildroot} install
%post
@@ -127,7 +130,7 @@ make DESTDIR=%{buildroot} install
%files
%defattr(-, root, root)
-%{_libdir}/libdbus-tqt-1.so.1*
+%{_libdir}/libdbus-tqt-1.so.0*
%files devel
%defattr(-, root, root)
@@ -139,5 +142,6 @@ make DESTDIR=%{buildroot} install
%{_includedir}/dbus-1.0/dbus/server.h
%{_libdir}/libdbus-tqt-1.la
%{_libdir}/libdbus-tqt-1.so
+%{_libdir}/pkgconfig/dbus-tqt.pc
%changelog
diff --git a/opensuse/tdebase/3_5_BRANCH.diff b/opensuse/tdebase/3_5_BRANCH.diff
new file mode 100644
index 000000000..bff4be17d
--- /dev/null
+++ b/opensuse/tdebase/3_5_BRANCH.diff
@@ -0,0 +1,1176 @@
+package: kdebase-3.5.10.tar.bz2
+kdemod: kdebase
+Index: BRANCH_STATUS
+===================================================================
+--- /dev/null
++++ BRANCH_STATUS
+@@ -0,0 +1,2 @@
++current HEAD: 865247
++svn di between //tags/KDE/3.5.10/kdebase and //branches/KDE/3.5/kdebase
+Index: kcontrol/background/bgrender.cpp
+===================================================================
+--- kcontrol/background/bgrender.cpp.orig
++++ kcontrol/background/bgrender.cpp
+@@ -1163,9 +1163,8 @@ void KVirtualBGRenderer::desktopResized(
+ m_pPixmap = new QPixmap(m_size);
+ m_pPixmap->fill(Qt::black);
+ }
+-
+- for (unsigned i=0; i<m_numRenderers; ++i)
+- m_renderer[i]->desktopResized();
++
++ initRenderers();
+ }
+
+
+Index: kcontrol/info/opengl.cpp
+===================================================================
+--- kcontrol/info/opengl.cpp.orig
++++ kcontrol/info/opengl.cpp
+@@ -608,7 +608,6 @@ static QListViewItem *get_gl_info(Displa
+ }
+ else {
+ kdDebug() << "Error: glXMakeCurrent failed\n";
+- glXDestroyContext(dpy, ctx);
+ }
+
+ glXDestroyContext(dpy, ctx);
+Index: kicker/taskbar/taskbar.cpp
+===================================================================
+--- kicker/taskbar/taskbar.cpp.orig
++++ kicker/taskbar/taskbar.cpp
+@@ -61,8 +61,6 @@ TaskBar::TaskBar( QWidget *parent, const
+ m_textShadowEngine(0),
+ m_ignoreUpdates(false)
+ {
+- setFrameStyle( NoFrame );
+-
+ arrowType = LeftArrow;
+ blocklayout = true;
+
+@@ -81,6 +79,8 @@ TaskBar::TaskBar( QWidget *parent, const
+ connect(&m_relayoutTimer, SIGNAL(timeout()),
+ this, SLOT(reLayout()));
+
++ connect(this, SIGNAL(contentsMoving(int, int)), SLOT(setBackground()));
++
+ // connect manager
+ connect(TaskManager::the(), SIGNAL(taskAdded(Task::Ptr)),
+ this, SLOT(add(Task::Ptr)));
+@@ -647,7 +647,7 @@ void TaskBar::reLayoutEventually()
+
+ if (!blocklayout && !m_ignoreUpdates)
+ {
+- m_relayoutTimer.start(100, true);
++ m_relayoutTimer.start(25, true);
+ }
+ }
+
+@@ -814,24 +814,16 @@ void TaskBar::reLayout()
+ QTimer::singleShot(100, this, SLOT(publishIconGeometry()));
+ }
+
+-void TaskBar::viewportResizeEvent( QResizeEvent* e )
+-{
+- Panner::viewportResizeEvent(e);
+- setViewportBackground();
+-}
+-
+ void TaskBar::setViewportBackground()
+ {
+ const QPixmap *bg = parentWidget()->backgroundPixmap();
+
+- viewport()->unsetPalette();
+-
+ if (bg)
+ {
+ QPixmap pm(parentWidget()->size());
+ pm.fill(parentWidget(), pos() + viewport()->pos());
+ viewport()->setPaletteBackgroundPixmap(pm);
+- viewport()->setBackgroundOrigin( WidgetOrigin );
++ viewport()->setBackgroundOrigin(WidgetOrigin);
+ }
+ else
+ viewport()->setPaletteBackgroundColor(paletteBackgroundColor());
+Index: kicker/taskbar/taskbar.h
+===================================================================
+--- kicker/taskbar/taskbar.h.orig
++++ kicker/taskbar/taskbar.h
+@@ -63,12 +63,11 @@ public:
+
+ QImage* blendGradient(const QSize& size);
+
+- void setBackground();
+-
+ KTextShadowEngine *textShadowEngine();
+
+ public slots:
+ void configure();
++ void setBackground();
+
+ signals:
+ void containerCountChanged();
+@@ -98,7 +97,6 @@ protected:
+ void viewportMouseReleaseEvent( QMouseEvent* );
+ void viewportMouseDoubleClickEvent( QMouseEvent* );
+ void viewportMouseMoveEvent( QMouseEvent* );
+- void viewportResizeEvent( QResizeEvent * );
+ void wheelEvent(QWheelEvent*);
+ void propagateMouseEvent( QMouseEvent* );
+ void resizeEvent( QResizeEvent* );
+Index: kicker/libkicker/panner.cpp
+===================================================================
+--- kicker/libkicker/panner.cpp.orig
++++ kicker/libkicker/panner.cpp
+@@ -35,28 +35,28 @@ CONNECTION WITH THE SOFTWARE OR THE USE
+ #include "panner.h"
+ #include "panner.moc"
+
+-
+ Panner::Panner( QWidget* parent, const char* name )
+- : QScrollView( parent, name ),
++ : QWidget( parent, name ),
+ _luSB(0),
+- _rdSB(0)
++ _rdSB(0),
++ _cwidth(0), _cheight(0),
++ _cx(0), _cy(0)
+ {
+ KGlobal::locale()->insertCatalogue("libkicker");
+ setBackgroundOrigin( AncestorOrigin );
+
+ _updateScrollButtonsTimer = new QTimer(this);
+ connect(_updateScrollButtonsTimer, SIGNAL(timeout()), this, SLOT(reallyUpdateScrollButtons()));
+-
+- setResizePolicy(Manual);
+- setVScrollBarMode( QScrollView::AlwaysOff );
+- setHScrollBarMode( QScrollView::AlwaysOff );
+-
+- viewport()->setBackgroundMode( PaletteBackground );
+- viewport()->setBackgroundOrigin( AncestorOrigin );
+
++ _clipper = new QWidget(this);
++ _clipper->setBackgroundOrigin(AncestorOrigin);
++ _clipper->installEventFilter( this );
++ _viewport = new QWidget(_clipper);
++ _viewport->setBackgroundOrigin(AncestorOrigin);
++
+ // layout
+ _layout = new QBoxLayout(this, QBoxLayout::LeftToRight);
+- _layout->addWidget(viewport(), 1);
++ _layout->addWidget(_clipper, 1);
+ setOrientation(Horizontal);
+ }
+
+@@ -64,6 +64,37 @@ Panner::~Panner()
+ {
+ }
+
++void Panner::createScrollButtons()
++{
++ if (_luSB)
++ {
++ return;
++ }
++
++ // left/up scroll button
++ _luSB = new SimpleArrowButton(this);
++ _luSB->installEventFilter(this);
++ //_luSB->setAutoRepeat(true);
++ _luSB->setMinimumSize(12, 12);
++ _luSB->hide();
++ _layout->addWidget(_luSB);
++ connect(_luSB, SIGNAL(pressed()), SLOT(startScrollLeftUp()));
++ connect(_luSB, SIGNAL(released()), SLOT(stopScroll()));
++
++ // right/down scroll button
++ _rdSB = new SimpleArrowButton(this);
++ _rdSB->installEventFilter(this);
++ //_rdSB->setAutoRepeat(true);
++ _rdSB->setMinimumSize(12, 12);
++ _rdSB->hide();
++ _layout->addWidget(_rdSB);
++ connect(_rdSB, SIGNAL(pressed()), SLOT(startScrollRightDown()));
++ connect(_rdSB, SIGNAL(released()), SLOT(stopScroll()));
++
++ // set up the buttons
++ setupButtons();
++}
++
+ void Panner::setupButtons()
+ {
+ if (orientation() == Horizontal)
+@@ -110,55 +141,54 @@ void Panner::setOrientation(Orientation
+ reallyUpdateScrollButtons();
+ }
+
+-void Panner::resizeEvent( QResizeEvent* e )
++void Panner::resizeEvent( QResizeEvent* )
+ {
+- QScrollView::resizeEvent( e );
+- updateScrollButtons();
++ //QScrollView::resizeEvent( e );
++ //updateScrollButtons();
+ }
+
+ void Panner::scrollRightDown()
+ {
+ if(orientation() == Horizontal) // scroll right
+- scrollBy( 40, 0 );
++ scrollBy( _step, 0 );
+ else // scroll down
+- scrollBy( 0, 40 );
++ scrollBy( 0, _step );
++ if (_step < 64)
++ _step++;
+ }
+
+ void Panner::scrollLeftUp()
+ {
+ if(orientation() == Horizontal) // scroll left
+- scrollBy( -40, 0 );
++ scrollBy( -_step, 0 );
+ else // scroll up
+- scrollBy( 0, -40 );
++ scrollBy( 0, -_step );
++ if (_step < 64)
++ _step++;
+ }
+
+-void Panner::createScrollButtons()
++void Panner::startScrollRightDown()
+ {
+- if (_luSB)
+- {
+- return;
+- }
+-
+- // left/up scroll button
+- _luSB = new SimpleArrowButton(this);
+- _luSB->installEventFilter(this);
+- _luSB->setAutoRepeat(true);
+- _luSB->setMinimumSize(12, 12);
+- _luSB->hide();
+- _layout->addWidget(_luSB);
+- connect(_luSB, SIGNAL(clicked()), SLOT(scrollLeftUp()));
++ _scrollTimer = new QTimer(this);
++ connect(_scrollTimer, SIGNAL(timeout()), SLOT(scrollRightDown()));
++ _scrollTimer->start(50);
++ _step = 8;
++ scrollRightDown();
++}
+
+- // right/down scroll button
+- _rdSB = new SimpleArrowButton(this);
+- _rdSB->installEventFilter(this);
+- _rdSB->setAutoRepeat(true);
+- _rdSB->setMinimumSize(12, 12);
+- _rdSB->hide();
+- _layout->addWidget(_rdSB);
+- connect(_rdSB, SIGNAL(clicked()), SLOT(scrollRightDown()));
++void Panner::startScrollLeftUp()
++{
++ _scrollTimer = new QTimer(this);
++ connect(_scrollTimer, SIGNAL(timeout()), SLOT(scrollLeftUp()));
++ _scrollTimer->start(50);
++ _step = 8;
++ scrollLeftUp();
++}
+
+- // set up the buttons
+- setupButtons();
++void Panner::stopScroll()
++{
++ delete _scrollTimer;
++ _scrollTimer = 0;
+ }
+
+ void Panner::reallyUpdateScrollButtons()
+@@ -176,7 +206,7 @@ void Panner::reallyUpdateScrollButtons()
+ delta = contentsHeight() - height();
+ }
+
+- if (delta > 1)
++ if (delta >= 1)
+ {
+ createScrollButtons();
+
+@@ -184,21 +214,11 @@ void Panner::reallyUpdateScrollButtons()
+ // we need to do this every single time
+ _luSB->show();
+ _rdSB->show();
+-
+- if (orientation() == Horizontal)
+- {
+- setMargins(0, 0, _luSB->width() + _rdSB->width(), 0);
+- }
+- else
+- {
+- setMargins(0, 0, 0, _luSB->height() + _rdSB->height());
+- }
+ }
+ else if (_luSB && _luSB->isVisibleTo(this))
+ {
+ _luSB->hide();
+ _rdSB->hide();
+- setMargins(0, 0, 0, 0);
+ }
+ }
+
+@@ -207,8 +227,170 @@ void Panner::updateScrollButtons()
+ _updateScrollButtonsTimer->start(200, true);
+ }
+
++void Panner::setContentsPos(int x, int y)
++{
++ if (x < 0)
++ x = 0;
++ else if (x > (contentsWidth() - visibleWidth()))
++ x = contentsWidth() - visibleWidth();
++
++ if (y < 0)
++ y = 0;
++ else if (y > (contentsHeight() - visibleHeight()))
++ y = contentsHeight() - visibleHeight();
++
++ if (x == contentsX() && y == contentsY())
++ return;
++
++ _viewport->move(-x, -y);
++ emit contentsMoving(x, y);
++}
++
++void Panner::scrollBy(int dx, int dy)
++{
++ setContentsPos(contentsX() + dx, contentsY() + dy);
++}
++
+ void Panner::resizeContents( int w, int h )
+ {
+- QScrollView::resizeContents( w, h );
++ _viewport->resize(w, h);
++ setContentsPos(contentsX(), contentsY());
+ updateScrollButtons();
+ }
++
++QPoint Panner::contentsToViewport( const QPoint& p ) const
++{
++ return QPoint(p.x() - contentsX() - _clipper->x(), p.y() - contentsY() - _clipper->y());
++}
++
++QPoint Panner::viewportToContents( const QPoint& vp ) const
++{
++ return QPoint(vp.x() + contentsX() + _clipper->x(), vp.y() + contentsY() + _clipper->y());
++}
++
++void Panner::contentsToViewport( int x, int y, int& vx, int& vy ) const
++{
++ const QPoint v = contentsToViewport(QPoint(x,y));
++ vx = v.x();
++ vy = v.y();
++}
++
++void Panner::viewportToContents( int vx, int vy, int& x, int& y ) const
++{
++ const QPoint c = viewportToContents(QPoint(vx,vy));
++ x = c.x();
++ y = c.y();
++}
++
++void Panner::ensureVisible( int x, int y )
++{
++ ensureVisible(x, y, 50, 50);
++}
++
++void Panner::ensureVisible( int x, int y, int xmargin, int ymargin )
++{
++ int pw=visibleWidth();
++ int ph=visibleHeight();
++
++ int cx=-contentsX();
++ int cy=-contentsY();
++ int cw=contentsWidth();
++ int ch=contentsHeight();
++
++ if ( pw < xmargin*2 )
++ xmargin=pw/2;
++ if ( ph < ymargin*2 )
++ ymargin=ph/2;
++
++ if ( cw <= pw ) {
++ xmargin=0;
++ cx=0;
++ }
++ if ( ch <= ph ) {
++ ymargin=0;
++ cy=0;
++ }
++
++ if ( x < -cx+xmargin )
++ cx = -x+xmargin;
++ else if ( x >= -cx+pw-xmargin )
++ cx = -x+pw-xmargin;
++
++ if ( y < -cy+ymargin )
++ cy = -y+ymargin;
++ else if ( y >= -cy+ph-ymargin )
++ cy = -y+ph-ymargin;
++
++ if ( cx > 0 )
++ cx=0;
++ else if ( cx < pw-cw && cw>pw )
++ cx=pw-cw;
++
++ if ( cy > 0 )
++ cy=0;
++ else if ( cy < ph-ch && ch>ph )
++ cy=ph-ch;
++
++ setContentsPos( -cx, -cy );
++}
++
++bool Panner::eventFilter( QObject *obj, QEvent *e )
++{
++ if ( obj == _viewport || obj == _clipper )
++ {
++ switch ( e->type() )
++ {
++ case QEvent::Resize:
++ viewportResizeEvent((QResizeEvent *)e);
++ break;
++ case QEvent::MouseButtonPress:
++ viewportMousePressEvent( (QMouseEvent*)e );
++ if ( ((QMouseEvent*)e)->isAccepted() )
++ return true;
++ break;
++ case QEvent::MouseButtonRelease:
++ viewportMouseReleaseEvent( (QMouseEvent*)e );
++ if ( ((QMouseEvent*)e)->isAccepted() )
++ return true;
++ break;
++ case QEvent::MouseButtonDblClick:
++ viewportMouseDoubleClickEvent( (QMouseEvent*)e );
++ if ( ((QMouseEvent*)e)->isAccepted() )
++ return true;
++ break;
++ case QEvent::MouseMove:
++ viewportMouseMoveEvent( (QMouseEvent*)e );
++ if ( ((QMouseEvent*)e)->isAccepted() )
++ return true;
++ break;
++ default:
++ break;
++ }
++ }
++
++ return QWidget::eventFilter( obj, e ); // always continue with standard event processing
++}
++
++void Panner::viewportResizeEvent( QResizeEvent* )
++{
++}
++
++void Panner::viewportMousePressEvent( QMouseEvent* e)
++{
++ e->ignore();
++}
++
++void Panner::viewportMouseReleaseEvent( QMouseEvent* e )
++{
++ e->ignore();
++}
++
++void Panner::viewportMouseDoubleClickEvent( QMouseEvent* e )
++{
++ e->ignore();
++}
++
++void Panner::viewportMouseMoveEvent( QMouseEvent* e )
++{
++ e->ignore();
++}
+Index: kicker/libkicker/panner.h
+===================================================================
+--- kicker/libkicker/panner.h.orig
++++ kicker/libkicker/panner.h
+@@ -24,14 +24,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE
+ #ifndef __panner_h__
+ #define __panner_h__
+
+-#include <qscrollview.h>
++#include <qwidget.h>
+
+ #include "simplebutton.h"
+
+ class QBoxLayout;
+ class QTimer;
+
+-class KDE_EXPORT Panner : public QScrollView
++class KDE_EXPORT Panner : public QWidget
+ {
+ Q_OBJECT
+
+@@ -43,17 +43,55 @@ public:
+
+ Qt::Orientation orientation() const { return _orient; }
+ virtual void setOrientation(Orientation orientation);
++
++ QWidget *viewport() const { return _viewport; }
++
++ QRect contentsRect() const { return QRect(0, 0, width(), height()); }
++
++ int contentsX() const { return _viewport ? -_viewport->x() : 0; }
++ int contentsY() const { return _viewport ? -_viewport->y() : 0; }
++ int contentsWidth() const { return _viewport ? _viewport->width() : 0; }
++ int contentsHeight() const { return _viewport ? _viewport->height() : 0; }
++ void setContentsPos(int x, int y);
++
++ int visibleWidth() const { return _clipper->width(); }
++ int visibleHeight() const { return _clipper->height(); }
++
++ void contentsToViewport( int x, int y, int& vx, int& vy ) const;
++ void viewportToContents( int vx, int vy, int& x, int& y ) const;
++ QPoint contentsToViewport( const QPoint& ) const;
++ QPoint viewportToContents( const QPoint& ) const;
++
++ void addChild(QWidget *child) { child->show(); }
++ void removeChild(QWidget *child) { child->hide(); }
++ int childX(QWidget *child) const { return child->x(); }
++ int childY(QWidget *child) const { return child->y(); }
++ void moveChild(QWidget *child, int x, int y) { child->move(x, y); }
++
++ void ensureVisible( int x, int y );
++ void ensureVisible( int x, int y, int xmargin, int ymargin );
+
+ public slots:
+ virtual void resizeContents( int w, int h );
++ void startScrollRightDown();
++ void startScrollLeftUp();
++ void stopScroll();
+ void scrollRightDown();
+ void scrollLeftUp();
+ void reallyUpdateScrollButtons();
++ void scrollBy(int dx, int dy);
++
++signals:
++ void contentsMoving(int x, int y);
+
+ protected:
+- void resizeEvent(QResizeEvent *ev);
+- void contentsWheelEvent(QWheelEvent *){;}
+- void viewportWheelEvent(QWheelEvent *){;}
++ virtual bool eventFilter( QObject *obj, QEvent *e );
++ virtual void resizeEvent(QResizeEvent *ev);
++ virtual void viewportResizeEvent( QResizeEvent* );
++ virtual void viewportMousePressEvent( QMouseEvent* );
++ virtual void viewportMouseReleaseEvent( QMouseEvent* );
++ virtual void viewportMouseDoubleClickEvent( QMouseEvent* );
++ virtual void viewportMouseMoveEvent( QMouseEvent* );
+
+ private:
+ void setupButtons();
+@@ -65,6 +103,13 @@ private:
+ SimpleArrowButton *_luSB; // Left Scroll Button
+ SimpleArrowButton *_rdSB; // Right Scroll Button
+ QTimer *_updateScrollButtonsTimer;
++ QTimer *_scrollTimer;
++
++ QWidget *_clipper;
++ QWidget *_viewport;
++ int _cwidth, _cheight;
++ int _cx, _cy;
++ int _step;
+ };
+
+ #endif
+Index: kicker/extensions/taskbar/taskbarextension.cpp
+===================================================================
+--- kicker/extensions/taskbar/taskbarextension.cpp.orig
++++ kicker/extensions/taskbar/taskbarextension.cpp
+@@ -170,7 +170,6 @@ void TaskBarExtension::setBackgroundThem
+ }
+
+ unsetPalette();
+- m_container->unsetPalette();
+
+ if (KickerSettings::useBackgroundTheme())
+ {
+@@ -215,17 +214,17 @@ void TaskBarExtension::setBackgroundThem
+ KickerLib::colorize(bgImage);
+ }
+ setPaletteBackgroundPixmap(bgImage);
+- m_container->setPaletteBackgroundPixmap(bgImage);
+ }
+ }
++
++ m_container->setBackground();
+ }
+
+ void TaskBarExtension::updateBackground(const QPixmap& bgImage)
+ {
+ unsetPalette();
+ setPaletteBackgroundPixmap(bgImage);
+- m_container->unsetPalette();
+- m_container->setPaletteBackgroundPixmap(bgImage);
++ m_container->setBackground();
+ }
+
+ void TaskBarExtension::resizeEvent(QResizeEvent *e)
+Index: kicker/kicker/core/container_extension.cpp
+===================================================================
+--- kicker/kicker/core/container_extension.cpp.orig
++++ kicker/kicker/core/container_extension.cpp
+@@ -126,6 +126,7 @@ void ExtensionContainer::init()
+ connect(Kicker::the()->kwinModule(), SIGNAL(currentDesktopChanged(int)),
+ this, SLOT( currentDesktopChanged(int)));
+
++ setBackgroundOrigin(AncestorOrigin);
+ setFrameStyle(NoFrame);
+ setLineWidth(0);
+ setMargin(0);
+@@ -163,7 +164,7 @@ void ExtensionContainer::init()
+ {
+ _userHidden = static_cast<UserHidden>(tmp);
+ }
+-
++
+ if (m_extension)
+ {
+ // if we have an extension, we need to grab the extension-specific
+Index: kicker/kicker/core/containerarea.cpp
+===================================================================
+--- kicker/kicker/core/containerarea.cpp.orig
++++ kicker/kicker/core/containerarea.cpp
+@@ -90,15 +90,12 @@ ContainerArea::ContainerArea(KConfig* _c
+ m_addAppletDialog(0)
+ {
+ setBackgroundOrigin( WidgetOrigin );
+- viewport()->setBackgroundOrigin( AncestorOrigin );
+
+- m_contents = new QWidget(viewport());
+- m_contents->setBackgroundOrigin(AncestorOrigin);
++ m_contents = viewport();
+
+ m_layout = new ContainerAreaLayout(m_contents);
+
+- // Install an event filter to propagate layout hints coming from
+- // m_contents.
++ // Install an event filter to propagate layout hints coming from m_contents.
+ m_contents->installEventFilter(this);
+
+ setBackground();
+Index: kicker/kicker/core/panelextension.cpp
+===================================================================
+--- kicker/kicker/core/panelextension.cpp.orig
++++ kicker/kicker/core/panelextension.cpp
+@@ -74,7 +74,6 @@ PanelExtension::PanelExtension(const QSt
+ connect(_containerArea, SIGNAL(maintainFocus(bool)), this, SIGNAL(maintainFocus(bool)));
+ _layout->addWidget(_containerArea);
+
+- _containerArea->setFrameStyle(QFrame::NoFrame);
+ _containerArea->viewport()->installEventFilter(this);
+ _containerArea->configure();
+
+Index: kicker/applets/systemtray/systemtrayapplet.h
+===================================================================
+--- kicker/applets/systemtray/systemtrayapplet.h.orig
++++ kicker/applets/systemtray/systemtrayapplet.h
+@@ -118,6 +118,7 @@ public:
+ TrayEmbed( bool kdeTray, QWidget* parent = NULL );
+ bool kdeTray() const { return kde_tray; }
+ void setBackground();
++ void getIconSize(int defaultIconSize);
+ private:
+ bool kde_tray;
+ };
+Index: kicker/applets/systemtray/systemtrayapplet.cpp
+===================================================================
+--- kicker/applets/systemtray/systemtrayapplet.cpp.orig
++++ kicker/applets/systemtray/systemtrayapplet.cpp
+@@ -54,6 +54,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE
+
+ #include <X11/Xlib.h>
+
++#define ICON_MARGIN 1
++
+ extern "C"
+ {
+ KDE_EXPORT KPanelApplet* init(QWidget *parent, const QString& configFile)
+@@ -459,9 +461,9 @@ void SystemTrayApplet::embedWindow( WId
+ delete emb;
+ return;
+ }
+-
++
+ connect(emb, SIGNAL(embeddedWindowDestroyed()), SLOT(updateTrayWindows()));
+- emb->setMinimumSize(m_iconSize, m_iconSize);
++ emb->getIconSize(m_iconSize);
+
+ if (shouldHide(w))
+ {
+@@ -471,7 +473,7 @@ void SystemTrayApplet::embedWindow( WId
+ }
+ else
+ {
+- emb->hide();
++ //emb->hide();
+ emb->setBackground();
+ emb->show();
+ m_shownWins.append(emb);
+@@ -515,7 +517,7 @@ void SystemTrayApplet::updateVisibleWins
+ {
+ for (; emb != lastEmb; ++emb)
+ {
+- (*emb)->hide();
++ //(*emb)->hide();
+ (*emb)->setBackground();
+ (*emb)->show();
+ }
+@@ -744,8 +746,7 @@ int SystemTrayApplet::widthForHeight(int
+ }
+
+ int currentHeight = height();
+- int minHeight = m_iconSize + 4;
+- if (currentHeight != h && currentHeight != minHeight)
++ if (currentHeight != h)
+ {
+ SystemTrayApplet* me = const_cast<SystemTrayApplet*>(this);
+ me->setMinimumSize(0, 0);
+@@ -764,8 +765,7 @@ int SystemTrayApplet::heightForWidth(int
+ }
+
+ int currentWidth = width();
+- int minSize = m_iconSize + 4;
+- if (currentWidth != w && currentWidth != minSize)
++ if (currentWidth != w)
+ {
+ SystemTrayApplet* me = const_cast<SystemTrayApplet*>(this);
+ me->setMinimumSize(0, 0);
+@@ -782,10 +782,8 @@ void SystemTrayApplet::moveEvent( QMoveE
+ }
+
+
+-void SystemTrayApplet::resizeEvent( QResizeEvent* e )
++void SystemTrayApplet::resizeEvent( QResizeEvent* )
+ {
+- KPanelApplet::resizeEvent(e);
+-
+ layoutTray();
+ // we need to give ourselves a chance to adjust our size before calling this
+ QTimer::singleShot(0, this, SIGNAL(updateLayout()));
+@@ -808,7 +806,7 @@ void SystemTrayApplet::layoutTray()
+ int i = 0, line, nbrOfLines, heightWidth;
+ bool showExpandButton = m_expandButton && m_expandButton->isVisibleTo(this);
+ delete m_layout;
+- m_layout = new QGridLayout(this, 1, 1, 2, 2);
++ m_layout = new QGridLayout(this, 1, 1, ICON_MARGIN, ICON_MARGIN);
+
+ if (m_expandButton)
+ {
+@@ -828,18 +826,18 @@ void SystemTrayApplet::layoutTray()
+
+ //
+ // The margin and spacing specified in the layout implies that:
+- // [-- 2 pixels --] [-- first icon --] [-- 2 pixels --] ... [-- 2 pixels --] [-- last icon --] [-- 2 pixels --]
++ // [-- ICON_MARGIN pixels --] [-- first icon --] [-- ICON_MARGIN pixels --] ... [-- ICON_MARGIN pixels --] [-- last icon --] [-- ICON_MARGIN pixels --]
+ //
+- // So, if we say that iconWidth is the icon width plus the 2 pixels spacing, then the available width for the icons
+- // is the widget width minus 2 pixels margin. Forgetting these 2 pixels broke the layout algorithm in KDE <= 3.5.9.
++ // So, if we say that iconWidth is the icon width plus the ICON_MARGIN pixels spacing, then the available width for the icons
++ // is the widget width minus ICON_MARGIN pixels margin. Forgetting these ICON_MARGIN pixels broke the layout algorithm in KDE <= 3.5.9.
+ //
+- // This fix makes the workaround in the heightForWidth() and widthForHeight() methods unneeded.
++ // This fix makes the workarounds in the heightForWidth() and widthForHeight() methods unneeded.
+ //
+
+ if (orientation() == Vertical)
+ {
+- int iconWidth = maxIconWidth() + 2; // +2 for the margins that implied by the layout
+- heightWidth = width() - 2;
++ int iconWidth = maxIconWidth() + ICON_MARGIN; // +2 for the margins that implied by the layout
++ heightWidth = width() - ICON_MARGIN;
+ // to avoid nbrOfLines=0 we ensure heightWidth >= iconWidth!
+ heightWidth = heightWidth < iconWidth ? iconWidth : heightWidth;
+ nbrOfLines = heightWidth / iconWidth;
+@@ -860,12 +858,12 @@ void SystemTrayApplet::layoutTray()
+ emb != lastEmb; ++emb)
+ {
+ line = i % nbrOfLines;
+- (*emb)->hide();
++ //(*emb)->hide();
+ (*emb)->show();
+ m_layout->addWidget(*emb, col, line,
+ Qt::AlignHCenter | Qt::AlignVCenter);
+
+- if (line + 1 == nbrOfLines)
++ if ((line + 1) == nbrOfLines)
+ {
+ ++col;
+ }
+@@ -879,12 +877,12 @@ void SystemTrayApplet::layoutTray()
+ emb != lastEmb; ++emb)
+ {
+ line = i % nbrOfLines;
+- (*emb)->hide();
++ //(*emb)->hide();
+ (*emb)->show();
+ m_layout->addWidget(*emb, col, line,
+ Qt::AlignHCenter | Qt::AlignVCenter);
+
+- if (line + 1 == nbrOfLines)
++ if ((line + 1) == nbrOfLines)
+ {
+ ++col;
+ }
+@@ -894,8 +892,8 @@ void SystemTrayApplet::layoutTray()
+ }
+ else // horizontal
+ {
+- int iconHeight = maxIconHeight() + 2; // +2 for the margins that implied by the layout
+- heightWidth = height() - 2;
++ int iconHeight = maxIconHeight() + ICON_MARGIN; // +2 for the margins that implied by the layout
++ heightWidth = height() - ICON_MARGIN;
+ heightWidth = heightWidth < iconHeight ? iconHeight : heightWidth; // to avoid nbrOfLines=0
+ nbrOfLines = heightWidth / iconHeight;
+
+@@ -914,12 +912,12 @@ void SystemTrayApplet::layoutTray()
+ for (TrayEmbedList::const_iterator emb = m_hiddenWins.begin(); emb != lastEmb; ++emb)
+ {
+ line = i % nbrOfLines;
+- (*emb)->hide();
++ //(*emb)->hide();
+ (*emb)->show();
+ m_layout->addWidget(*emb, line, col,
+ Qt::AlignHCenter | Qt::AlignVCenter);
+
+- if (line + 1 == nbrOfLines)
++ if ((line + 1) == nbrOfLines)
+ {
+ ++col;
+ }
+@@ -933,12 +931,12 @@ void SystemTrayApplet::layoutTray()
+ emb != lastEmb; ++emb)
+ {
+ line = i % nbrOfLines;
+- (*emb)->hide();
++ //(*emb)->hide();
+ (*emb)->show();
+ m_layout->addWidget(*emb, line, col,
+ Qt::AlignHCenter | Qt::AlignVCenter);
+
+- if (line + 1 == nbrOfLines)
++ if ((line + 1) == nbrOfLines)
+ {
+ ++col;
+ }
+@@ -975,6 +973,21 @@ TrayEmbed::TrayEmbed( bool kdeTray, QWid
+ : QXEmbed( parent ), kde_tray( kdeTray )
+ {
+ hide();
++}
++
++void TrayEmbed::getIconSize(int defaultIconSize)
++{
++ QSize minSize = minimumSizeHint();
++
++ int width = minSize.width();
++ int height = minSize.height();
++
++ if (width < 1 || width > defaultIconSize)
++ width = defaultIconSize;
++ if (height < 1 || height > defaultIconSize)
++ height = defaultIconSize;
++
++ setFixedSize(width, height);
+ setBackground();
+ }
+
+@@ -994,9 +1007,7 @@ void TrayEmbed::setBackground()
+
+ if (!isHidden())
+ {
+- hide();
+- show();
++ XClearArea(x11Display(), embeddedWinId(), 0, 0, 0, 0, True);
+ }
+- //XClearArea(x11Display(), embeddedWinId(), 0, 0, 0, 0, True);
+ }
+
+Index: kicker/applets/clock/clock.h
+===================================================================
+--- kicker/applets/clock/clock.h.orig
++++ kicker/applets/clock/clock.h
+@@ -41,6 +41,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE
+
+ #include <kickertip.h>
+ #include "settings.h"
++#include "kshadowengine.h"
+
+ class QTimer;
+ class QBoxLayout;
+@@ -152,6 +153,9 @@ class PlainClock : public QLabel, public
+ bool showDayOfWeek();
+
+ protected:
++ void paintEvent(QPaintEvent *e);
++ void drawContents(QPainter *p);
++
+ QString _timeStr;
+ };
+
+@@ -279,6 +283,8 @@ class ClockApplet : public KPanelApplet,
+ QDate clockGetDate();
+
+ virtual void updateKickerTip(KickerTip::Data&);
++
++ KTextShadowEngine *shadowEngine();
+
+ k_dcop:
+ void reconfigure();
+@@ -335,6 +341,7 @@ class ClockApplet : public KPanelApplet,
+ QStringList _remotezonelist;
+ KPopupMenu* menu;
+ ClockAppletToolTip m_tooltip;
++ KTextShadowEngine *m_shadowEngine;
+ };
+
+
+Index: kicker/applets/clock/Makefile.am
+===================================================================
+--- kicker/applets/clock/Makefile.am.orig
++++ kicker/applets/clock/Makefile.am
+@@ -1,7 +1,7 @@
+ pic_DATA = lcd.png
+ picdir = $(kde_datadir)/clockapplet/pics
+
+-INCLUDES = -I$(top_srcdir)/kicker/libkicker $(all_includes)
++INCLUDES = -I$(top_srcdir)/kicker/libkicker -I../../libkicker $(all_includes)
+
+ kde_module_LTLIBRARIES = clock_panelapplet.la
+
+Index: kicker/applets/clock/clock.cpp
+===================================================================
+--- kicker/applets/clock/clock.cpp.orig
++++ kicker/applets/clock/clock.cpp
+@@ -57,6 +57,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE
+
+ #include <global.h> // libkickermain
+
++#include "kickerSettings.h"
+ #include "clock.h"
+ #include "datepicker.h"
+ #include "zone.h"
+@@ -219,6 +220,7 @@ ClockWidget::~ClockWidget()
+ PlainClock::PlainClock(ClockApplet *applet, Prefs *prefs, QWidget *parent, const char *name)
+ : QLabel(parent, name), ClockWidget(applet, prefs)
+ {
++ setWFlags(WNoAutoErase);
+ setBackgroundOrigin(AncestorOrigin);
+ loadSettings();
+ updateClock();
+@@ -228,7 +230,7 @@ PlainClock::PlainClock(ClockApplet *appl
+ int PlainClock::preferedWidthForHeight(int ) const
+ {
+ QString maxLengthTime = KGlobal::locale()->formatTime( QTime( 23, 59 ), _prefs->plainShowSeconds());
+- return fontMetrics().width( maxLengthTime+2 );
++ return fontMetrics().width( maxLengthTime ) + 8;
+ }
+
+
+@@ -244,7 +246,7 @@ void PlainClock::updateClock()
+
+ if (_force || newStr != _timeStr) {
+ _timeStr = newStr;
+- setText(_timeStr);
++ update();
+ }
+ }
+
+@@ -266,6 +268,32 @@ bool PlainClock::showDayOfWeek()
+ return _prefs->plainShowDayOfWeek();
+ }
+
++void PlainClock::paintEvent(QPaintEvent *)
++{
++ QPainter p;
++ QPixmap buf(size());
++ buf.fill(this, 0, 0);
++ p.begin(&buf);
++ p.setFont(font());
++ p.setPen(paletteForegroundColor());
++ drawContents(&p);
++ drawFrame(&p);
++ p.end();
++ p.begin(this);
++ p.drawPixmap(0, 0, buf);
++ p.end();
++}
++
++void PlainClock::drawContents(QPainter *p)
++{
++ QRect tr(0, 0, width(), height());
++
++ if (!KickerSettings::transparent())
++ p->drawText(tr, AlignCenter, _timeStr);
++ else
++ _applet->shadowEngine()->drawText(*p, tr, AlignCenter, _timeStr, size());
++}
++
+ //************************************************************
+
+
+@@ -834,12 +862,22 @@ void FuzzyClock::drawContents(QPainter *
+
+ p->setFont(_prefs->fuzzyFont());
+ p->setPen(_prefs->fuzzyForegroundColor());
+- if (_applet->getOrientation() == Vertical) {
++
++ QRect tr;
++
++ if (_applet->getOrientation() == Vertical)
++ {
+ p->rotate(90);
+- p->drawText(4, -2, height() - 8, -(width()) + 2, AlignCenter, _timeStr);
+- } else {
+- p->drawText(4, 2, width() - 8, height() - 4, AlignCenter, _timeStr);
++ tr = QRect(4, -2, height() - 8, -(width()) + 2);
+ }
++ else
++ tr = QRect(4, 2, width() - 8, height() - 4);
++
++ if (!KickerSettings::transparent())
++ p->drawText(tr, AlignCenter, _timeStr);
++ else
++ _applet->shadowEngine()->drawText(*p, tr, AlignCenter, _timeStr, size());
++
+ alreadyDrawing = false;
+ }
+
+@@ -872,7 +910,8 @@ ClockApplet::ClockApplet(const QString&
+ _prefs(new Prefs(sharedConfig())),
+ zone(new Zone(config())),
+ menu(0),
+- m_tooltip(this)
++ m_tooltip(this),
++ m_shadowEngine(0)
+ {
+ DCOPObject::setObjId("ClockApplet");
+ _prefs->readConfig();
+@@ -910,6 +949,7 @@ ClockApplet::ClockApplet(const QString&
+
+ ClockApplet::~ClockApplet()
+ {
++ delete m_shadowEngine;
+ //reverse for the moment
+ KGlobal::locale()->removeCatalogue("clockapplet");
+ KGlobal::locale()->removeCatalogue("timezones"); // For time zone translations
+@@ -929,6 +969,16 @@ ClockApplet::~ClockApplet()
+ config()->sync();
+ }
+
++
++KTextShadowEngine *ClockApplet::shadowEngine()
++{
++ if (!m_shadowEngine)
++ m_shadowEngine = new KTextShadowEngine();
++
++ return m_shadowEngine;
++}
++
++
+ int ClockApplet::widthForHeight(int h) const
+ {
+ if (orientation() == Qt::Vertical)
+Index: kioslave/media/mediamanager/halbackend.cpp
+===================================================================
+--- kioslave/media/mediamanager/halbackend.cpp.orig
++++ kioslave/media/mediamanager/halbackend.cpp
+@@ -851,13 +851,6 @@ QStringList HALBackend::mountoptions(con
+ result << tmp;
+ }
+
+- if ( valids.contains("locale") )
+- {
+- value = config.readBoolEntry( "locale", true );
+- tmp = QString( "locale=%1" ).arg( value ? "true" : "false" );
+- result << tmp;
+- }
+-
+ if (valids.contains("utf8"))
+ {
+ value = config.readBoolEntry("utf8", true);
+@@ -878,6 +871,17 @@ QStringList HALBackend::mountoptions(con
+ result << "shortname=lower";
+ }
+
++ // pass our locale to the ntfs-3g driver so it can translate local characters
++ if (valids.contains("locale") && fstype == "ntfs-3g")
++ {
++ // have to obtain LC_CTYPE as returned by the `locale` command
++ // check in the same order as `locale` does
++ char *cType;
++ if ( (cType = getenv("LC_ALL")) || (cType = getenv("LC_CTYPE")) || (cType = getenv("LANG")) ) {
++ result << QString("locale=%1").arg(cType);
++ }
++ }
++
+ if (valids.contains("sync"))
+ {
+ value = config.readBoolEntry("sync", ( valids.contains("flush") && !fstype.endsWith("fat") ) && removable);
+@@ -931,7 +935,7 @@ bool HALBackend::setMountoptions(const Q
+
+ QMap<QString,QString> valids = MediaManagerUtils::splitOptions(options);
+
+- const char *names[] = { "ro", "quiet", "atime", "uid", "utf8", "flush", "sync", "locale", 0 };
++ const char *names[] = { "ro", "quiet", "atime", "uid", "utf8", "flush", "sync", 0 };
+ for (int index = 0; names[index]; ++index)
+ if (valids.contains(names[index]))
+ config.writeEntry(names[index], valids[names[index]] == "true");
+@@ -951,10 +955,6 @@ bool HALBackend::setMountoptions(const Q
+ config.writeEntry("automount", valids["automount"]);
+ }
+
+- if (valids.contains("locale") ) {
+- config.writeEntry("locale", valids["locale"]);
+- }
+-
+ return true;
+ }
+
+@@ -1153,11 +1153,6 @@ QString HALBackend::mount(const Medium *
+ soptions << QString("uid=%1").arg(getuid());
+ }
+
+- if (valids["locale"] == "true")
+- {
+- soptions << QString("locale=%1").arg( KGlobal::locale()->language() );
+- }
+-
+ if (valids["ro"] == "true")
+ soptions << "ro";
+
+@@ -1182,6 +1177,11 @@ QString HALBackend::mount(const Medium *
+ soptions << QString("shortname=%1").arg(valids["shortname"]);
+ }
+
++ if (valids.contains("locale"))
++ {
++ soptions << QString("locale=%1").arg(valids["locale"]);
++ }
++
+ if (valids.contains("journaling"))
+ {
+ QString option = valids["journaling"];
+Index: knetattach/knetattach.ui
+===================================================================
+--- knetattach/knetattach.ui.orig
++++ knetattach/knetattach.ui
+@@ -236,7 +236,7 @@
+ </sizepolicy>
+ </property>
+ <property name="maxValue">
+- <number>32768</number>
++ <number>65535</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
diff --git a/opensuse/tdebase/access.diff b/opensuse/tdebase/access.diff
new file mode 100644
index 000000000..9f105550b
--- /dev/null
+++ b/opensuse/tdebase/access.diff
@@ -0,0 +1,51 @@
+Index: kcontrol/access/kaccess.cpp
+===================================================================
+--- kcontrol/access/kaccess.cpp.orig
++++ kcontrol/access/kaccess.cpp
+@@ -216,7 +216,7 @@ void KAccessApp::readSettings()
+ xkb->ctrls->debounce_delay = config->readNumEntry("BounceKeysDelay", 500);
+
+ // gestures for enabling the other features
+- _gestures = config->readBoolEntry("Gestures", true);
++ _gestures = config->readBoolEntry("Gestures", ::access("/opt/kde3/bin/kmag", X_OK) == 0);
+ if (_gestures)
+ xkb->ctrls->enabled_ctrls |= XkbAccessXKeysMask;
+ else
+@@ -241,7 +241,7 @@ void KAccessApp::readSettings()
+ else
+ xkb->ctrls->ax_options &= ~(XkbAX_FeatureFBMask | XkbAX_SlowWarnFBMask);
+
+- _gestureConfirmation = config->readBoolEntry("GestureConfirmation", true);
++ _gestureConfirmation = config->readBoolEntry("GestureConfirmation", ::access("/opt/kde3/bin/kmag", X_OK) == 0);
+
+ _kNotifyModifiers = config->readBoolEntry("kNotifyModifiers", false);
+ _kNotifyAccessX = config->readBoolEntry("kNotifyAccessX", false);
+Index: kcontrol/access/kcmaccess.cpp
+===================================================================
+--- kcontrol/access/kcmaccess.cpp.orig
++++ kcontrol/access/kcmaccess.cpp
+@@ -7,6 +7,7 @@
+
+
+ #include <stdlib.h>
++#include <unistd.h>
+ #include <math.h>
+
+ #include <dcopref.h>
+@@ -686,12 +687,14 @@ void KAccessConfig::load( bool useDefaul
+ bounceKeysDelay->setValue(config->readNumEntry("BounceKeysDelay", 500));
+ bounceKeysRejectBeep->setChecked(config->readBoolEntry("BounceKeysRejectBeep", true));
+
+- gestures->setChecked(config->readBoolEntry("Gestures", true));
++ gestures->setChecked(config->readBoolEntry("Gestures",
++ ::access("/opt/kde3/bin/kmag", X_OK) == 0));
+ timeout->setChecked(config->readBoolEntry("AccessXTimeout", false));
+ timeoutDelay->setValue(config->readNumEntry("AccessXTimeoutDelay", 30));
+
+ accessxBeep->setChecked(config->readBoolEntry("AccessXBeep", true));
+- gestureConfirmation->setChecked(config->readBoolEntry("GestureConfirmation", false));
++ gestureConfirmation->setChecked(config->readBoolEntry("GestureConfirmation",
++ ::access("/opt/kde3/bin/kmag", X_OK) == 0));
+ kNotifyAccessX->setChecked(config->readBoolEntry("kNotifyAccessX", false));
+
+ delete config;
diff --git a/opensuse/tdebase/applet-lock-logout.diff b/opensuse/tdebase/applet-lock-logout.diff
new file mode 100644
index 000000000..75363e768
--- /dev/null
+++ b/opensuse/tdebase/applet-lock-logout.diff
@@ -0,0 +1,122 @@
+Index: kicker/applets/lockout/lockout.cpp
+===================================================================
+--- kicker/applets/lockout/lockout.cpp.orig
++++ kicker/applets/lockout/lockout.cpp
+@@ -31,6 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE
+ #include <qtoolbutton.h>
+ #include <qstyle.h>
+ #include <qtooltip.h>
++#include <qobjectlist.h>
+
+ #include <dcopclient.h>
+
+@@ -54,7 +55,7 @@ extern "C"
+ }
+
+ Lockout::Lockout( const QString& configFile, QWidget *parent, const char *name)
+- : KPanelApplet( configFile, KPanelApplet::Normal, 0, parent, name ), bTransparent( false )
++ : KPanelApplet( configFile, KPanelApplet::Normal, 0, parent, name ), bTransparent( false ), bAlternateButtonOrder( false )
+ {
+ KConfig *conf = config();
+ conf->setGroup("lockout");
+@@ -71,8 +72,16 @@ Lockout::Lockout( const QString& configF
+ layout->setMargin( 0 );
+ layout->setSpacing( 0 );
+
+- lockButton = new SimpleButton( this, "lock");
+- logoutButton = new SimpleButton( this, "logout");
++ bAlternateButtonOrder = !conf->readBoolEntry( "OriginalLayout",true );
++
++ if (bAlternateButtonOrder) {
++ lockButton = new SimpleButton( this, "lock");
++ logoutButton = new SimpleButton( this, "logout");
++ }
++ else {
++ logoutButton = new SimpleButton( this, "logout");
++ lockButton = new SimpleButton( this, "lock");
++ }
+
+ QToolTip::add( lockButton, i18n("Lock the session") );
+ QToolTip::add( logoutButton, i18n("Log out") );
+@@ -204,12 +213,15 @@ bool Lockout::eventFilter( QObject *o, Q
+ this, SLOT( lock() ) );
+ popup->insertSeparator();
+
++ popup->insertItem( i18n( "&Alternate Button Order" ), 90 );
+ i18n("&Transparent");
+ //popup->insertItem( i18n( "&Transparent" ), 100 );
+ popup->insertItem( SmallIcon( "configure" ),
+ i18n( "&Configure Screen Saver..." ),
+ this, SLOT( slotLockPrefs() ) );
+
++ popup->setItemChecked( 90, bAlternateButtonOrder );
++ popup->connectItem(90, this, SLOT( slotButtonOrder() ) );
+ //popup->setItemChecked( 100, bTransparent );
+ //popup->connectItem(100, this, SLOT( slotTransparent() ) );
+ //if (conf->entryIsImmutable( "Transparent" ))
+@@ -226,6 +238,7 @@ bool Lockout::eventFilter( QObject *o, Q
+ popup->insertItem( SmallIcon( "exit" ), i18n("&Log Out..."),
+ this, SLOT( logout() ) );
+ popup->insertSeparator();
++ popup->insertItem( i18n( "&Alternate Button Order" ), 90 );
+ //popup->insertItem( i18n( "&Transparent" ), 100 );
+ popup->insertItem( SmallIcon( "configure" ),
+ i18n( "&Configure Session Manager..." ),
+@@ -235,6 +248,9 @@ bool Lockout::eventFilter( QObject *o, Q
+ //popup->connectItem(100, this, SLOT( slotTransparent() ) );
+ //if (conf->entryIsImmutable( "Transparent" ))
+ // popup->setItemEnabled( 100, false );
++ popup->setItemChecked( 90, bAlternateButtonOrder );
++ popup->connectItem(90, this, SLOT( slotButtonOrder() ) );
++
+ popup->exec( me->globalPos() );
+ delete popup;
+
+@@ -263,6 +279,27 @@ void Lockout::slotTransparent()
+ conf->sync();
+ }
+
++void Lockout::slotButtonOrder()
++{
++ QObject* child = children()->getFirst();
++
++ if (bAlternateButtonOrder)
++ child = lockButton;
++ else
++ child = logoutButton;
++
++ removeChild(child);
++ insertChild(child);
++ update();
++
++ bAlternateButtonOrder = !bAlternateButtonOrder;
++
++ KConfig* conf = config();
++ conf->setGroup("lockout");
++ conf->writeEntry( "OriginalLayout", !bAlternateButtonOrder );
++ conf->sync();
++}
++
+ void Lockout::slotLogoutPrefs()
+ {
+ // Run the logout settings.
+Index: kicker/applets/lockout/lockout.h
+===================================================================
+--- kicker/applets/lockout/lockout.h.orig
++++ kicker/applets/lockout/lockout.h
+@@ -36,6 +36,7 @@ private slots:
+
+ void slotLockPrefs();
+ void slotLogoutPrefs();
++ void slotButtonOrder();
+ void slotTransparent();
+ void slotIconChanged();
+
+@@ -47,6 +48,7 @@ private:
+ QBoxLayout *layout;
+
+ bool bTransparent;
++ bool bAlternateButtonOrder;
+ };
+
+ #endif // LOCKOUT_H
diff --git a/opensuse/tdebase/arts-start-on-demand.diff b/opensuse/tdebase/arts-start-on-demand.diff
new file mode 100644
index 000000000..27fcc2292
--- /dev/null
+++ b/opensuse/tdebase/arts-start-on-demand.diff
@@ -0,0 +1,98 @@
+Index: kcontrol/arts/Makefile.am
+===================================================================
+--- kcontrol/arts/Makefile.am.orig
++++ kcontrol/arts/Makefile.am
+@@ -1,3 +1,9 @@
++bin_PROGRAMS = arts-start
++
++arts_start_SOURCES = arts-start.cpp
++arts_start_LDFLAGS = $(all_libraries)
++arts_start_LDADD = $(LIB_KDECORE)
++
+ kde_module_LTLIBRARIES = kcm_arts.la
+
+ kcm_arts_la_SOURCES = arts.cpp generaltab.ui hardwaretab.ui krichtextlabel.cpp
+Index: kcontrol/arts/arts-start.cpp
+===================================================================
+--- /dev/null
++++ kcontrol/arts/arts-start.cpp
+@@ -0,0 +1,79 @@
++/*
++
++ Copyright (C) 2007 Lubos Lunak <l.lunak@suse.cz>
++
++ 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.
++
++ Permission is also granted to link this program with the Qt
++ library, treating Qt like a library that normally accompanies the
++ operating system kernel, whether or not that is in fact the case.
++
++*/
++
++#include <kconfig.h>
++#include <kinstance.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <X11/Xlib.h>
++
++static bool arts_running()
++ {
++ int status = system( "artsshell status >/dev/null 2>/dev/null" );
++ return WIFEXITED( status ) && WEXITSTATUS( status ) == 0;
++ }
++
++int main()
++ {
++ // Try to launch arts this way only a single time in the whole session. After first
++ // try set X property on the root window and following attemps bail out if it's set.
++ Display* dpy = XOpenDisplay( NULL );
++ if( dpy == NULL ) // don't launch arts without X
++ return 4;
++ Atom atom = XInternAtom( dpy, "_KDE_ARTS_TRIED", False );
++ int count;
++ Atom* atoms = XListProperties( dpy, DefaultRootWindow( dpy ), &count );
++ bool tried = false;
++ if( atoms != NULL )
++ {
++ for( int i = 0;
++ i < count;
++ ++i )
++ if( atoms[ i ] == atom )
++ {
++ tried = true;
++ break;
++ }
++ }
++ if( tried ) // this should probably wait, but artsshell will result in calling this too
++ return 2;
++ long dummy = 1;
++ XChangeProperty( dpy, DefaultRootWindow( dpy ), atom, atom, 32, PropModeReplace, (const unsigned char*)&dummy, 1 );
++ XCloseDisplay( dpy );
++ KInstance inst( "arts-start" );
++ KConfig config("kcmartsrc", true, false);
++ config.setGroup("Arts");
++ if( !config.readBoolEntry("StartServer",true))
++ return 2;
++ system( "kcminit arts" );
++ for( int i = 0;
++ i < 50; // give it 5 seconds
++ ++i )
++ {
++ if( arts_running())
++ return 0;
++ usleep( 100 * 1000 );
++ }
++ return 3;
++ }
diff --git a/opensuse/tdebase/artwork.diff b/opensuse/tdebase/artwork.diff
new file mode 100644
index 000000000..ba13e5757
--- /dev/null
+++ b/opensuse/tdebase/artwork.diff
@@ -0,0 +1,35 @@
+Index: kioslave/fish/fish.protocol
+===================================================================
+--- kioslave/fish/fish.protocol.orig
++++ kioslave/fish/fish.protocol
+@@ -10,7 +10,7 @@ makedir=true
+ deleting=true
+ linking=true
+ moving=true
+-Icon=remote
++Icon=folder_html
+ Description=A kioslave for the FISH protocol
+ Description[af]='n Kioslave vir die FISH protokol
+ Description[be]=Kioslave для пратакола FISH
+Index: kioslave/floppy/floppy.protocol
+===================================================================
+--- kioslave/floppy/floppy.protocol.orig
++++ kioslave/floppy/floppy.protocol
+@@ -9,6 +9,6 @@ writing=true
+ makedir=true
+ deleting=true
+ moving=true
+-Icon=3floppy_mount
++Icon=3floppy_unmount
+ DocPath=kioslave/floppy.html
+ Class=:local
+Index: kioslave/nfs/nfs.protocol
+===================================================================
+--- kioslave/nfs/nfs.protocol.orig
++++ kioslave/nfs/nfs.protocol
+@@ -11,4 +11,4 @@ deleting=true
+ linking=true
+ moving=true
+ DocPath=kioslave/nfs.html
+-Icon=nfs_mount
++Icon=nfs_unmount
diff --git a/opensuse/tdebase/autorun.patch b/opensuse/tdebase/autorun.patch
new file mode 100644
index 000000000..962740cdc
--- /dev/null
+++ b/opensuse/tdebase/autorun.patch
@@ -0,0 +1,27 @@
+Index: kioslave/media/medianotifier/medianotifier.cpp
+===================================================================
+--- kioslave/media/medianotifier/medianotifier.cpp.orig
++++ kioslave/media/medianotifier/medianotifier.cpp
+@@ -133,7 +133,7 @@ bool MediaNotifier::autostart( const KFi
+ // be checked for the following Autostart files in order of precedence:
+ // .autorun, autorun, autorun.sh
+ QStringList autorun_list;
+- autorun_list << ".autorun" << "autorun" << "autorun.sh";
++ autorun_list << ".autorun" << "autorun" << "autorun.sh" << "setup.sh" << "media.1/patches";
+
+ QStringList::iterator it = autorun_list.begin();
+ QStringList::iterator end = autorun_list.end();
+@@ -191,7 +191,12 @@ bool MediaNotifier::execAutorun( const K
+ // with the current working directory ( CWD ) set to the root
+ // directory of the medium.
+ KProcess proc;
+- proc << "sh" << autorunFile;
++ if (autorunFile == "setup.sh")
++ proc << "kdesu" << autorunFile;
++ else if (autorunFile == "media.1/patches")
++ proc << "kdesu" << "--nonewdcop" << "/sbin/yast2" << "online_update" << ".cd_default";
++ else
++ proc << "sh" << autorunFile;
+ proc.setWorkingDirectory( path );
+ proc.start();
+ proc.detach();
diff --git a/opensuse/tdebase/background_default.diff b/opensuse/tdebase/background_default.diff
new file mode 100644
index 000000000..71f9a96bb
--- /dev/null
+++ b/opensuse/tdebase/background_default.diff
@@ -0,0 +1,13 @@
+Index: kcontrol/background/bgwallpaper.cpp
+===================================================================
+--- kcontrol/background/bgwallpaper.cpp.orig
++++ kcontrol/background/bgwallpaper.cpp
+@@ -149,7 +149,7 @@ void BGMultiWallpaperDialog::slotAdd()
+ mimeTypes += "image/svg+xml";
+ #endif
+
+- KFileDialog fileDialog(KGlobal::dirs()->findDirs("wallpaper", "").first(),
++ KFileDialog fileDialog("/usr/share/wallpapers",
+ mimeTypes.join( " " ), this,
+ 0L, true);
+
diff --git a/opensuse/tdebase/baselibs.conf b/opensuse/tdebase/baselibs.conf
new file mode 100644
index 000000000..29e28ab1d
--- /dev/null
+++ b/opensuse/tdebase/baselibs.conf
@@ -0,0 +1,2 @@
+kdebase3
+kdebase3-runtime
diff --git a/opensuse/tdebase/beagle-0.3.diff b/opensuse/tdebase/beagle-0.3.diff
new file mode 100644
index 000000000..6e65be590
--- /dev/null
+++ b/opensuse/tdebase/beagle-0.3.diff
@@ -0,0 +1,21 @@
+--- kicker/configure.in.in 2008/01/28 11:03:28 1.1
++++ kicker/configure.in.in 2008/01/28 11:03:45
+@@ -42,14 +42,14 @@
+ AC_SUBST(GLIB_LIBADD)
+ AC_SUBST(GLIB_LDFLAGS)
+
+-dnl Check for libbeagle 0.2.0
++dnl Check for libbeagle 0.3.0
+ # LIBBEAGLE_CFLAGS: cflags for compiling libbeagle dependant sources
+ # LIBBEAGLE_LIBADD: libbeagle libraries (-l options)
+ # LIBBEAGLE_LDFLAGS: flags containing path to libbeagle libraries (-L options)
+
+-LIBBEAGLE_PACKAGES="libbeagle-0.0"
+-LIBBEAGLE_VERSION="0.2.4"
+-AC_MSG_CHECKING(for libbeagle-0.2.4 (at least $LIBBEAGLE_VERSION))
++LIBBEAGLE_PACKAGES="libbeagle-1.0"
++LIBBEAGLE_VERSION="0.3.0"
++AC_MSG_CHECKING(for libbeagle-0.3.0 (at least $LIBBEAGLE_VERSION))
+
+ if $PKG_CONFIG --atleast-pkgconfig-version 0.15 ; then
+ if $PKG_CONFIG --atleast-version $LIBBEAGLE_VERSION $LIBBEAGLE_PACKAGES >/dev/null 2>&1 ; then
diff --git a/opensuse/tdebase/bnc.desktop b/opensuse/tdebase/bnc.desktop
new file mode 100644
index 000000000..c5db233cf
--- /dev/null
+++ b/opensuse/tdebase/bnc.desktop
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Charset=
+Hidden=false
+Keys=bnc
+Name=Novell Bugzilla
+Query=https://bugzilla.novell.com/show_bug.cgi?id=\\{@}
+ServiceTypes=SearchProvider
+Type=Service
diff --git a/opensuse/tdebase/bnc584223.diff b/opensuse/tdebase/bnc584223.diff
new file mode 100644
index 000000000..370abf150
--- /dev/null
+++ b/opensuse/tdebase/bnc584223.diff
@@ -0,0 +1,189 @@
+--- kdebase-3.5.10/kdm/backend/ctrl.c.sav 2010-03-23 13:22:28.000000000 +0100
++++ kdebase-3.5.10/kdm/backend/ctrl.c 2010-03-23 14:21:48.619350322 +0100
+@@ -78,7 +78,25 @@ nukeSock( struct cmdsock *cs )
+ }
+
+
++#ifdef HONORS_SOCKET_PERMS
+ static CtrlRec ctrl = { 0, 0, -1, 0, 0, { -1, 0, 0 } };
++#else
++static CtrlRec ctrl = { 0, 0, 0, -1, 0, 0, { -1, 0, 0 } };
++
++static int mkTempDir( char *dir )
++{
++ int i, l = strlen( dir ) - 6;
++
++ for (i = 0; i < 100; i++) {
++ randomStr( dir + l );
++ if (!mkdir( dir, 0700 ))
++ return True;
++ if (errno != EEXIST)
++ break;
++ }
++ return False;
++}
++#endif
+
+ void
+ openCtrl( struct display *d )
+@@ -140,22 +158,50 @@ openCtrl( struct display *d )
+ if (strlen( cr->path ) >= sizeof(sa.sun_path))
+ LogError( "path %\"s too long; no control sockets will be available\n",
+ cr->path );
+- else if (mkdir( sockdir, 0755 ) && errno != EEXIST)
++#ifdef HONORS_SOCKET_PERMS
++ else if (mkdir( sockdir, 0700 ) && errno != EEXIST)
+ LogError( "mkdir %\"s failed; no control sockets will be available\n",
+ sockdir );
++ else if (unlink( cr->path ) && errno != ENOENT)
++ LogError( "unlink %\"s failed: %m; control socket will not be available\n",
++ cr->path );
+ else {
+- if (!d)
+- chown( sockdir, -1, fifoGroup );
++#else
++ else if (unlink( sockdir ) && errno != ENOENT)
++ LogError( "unlink %\"s failed: %m; control socket will not be available\n",
++ sockdir );
++ else if (!strApp( &cr->realdir, sockdir, "-XXXXXX", (char *)0))
++ ;
++ else if (!mkTempDir( cr->realdir )) {
++ LogError( "mkdir %\"s failed: %m; control socket will not be available\n",
++ cr->realdir );
++ free( cr->realdir );
++ cr->realdir = 0;
++ } else if (symlink( cr->realdir, sockdir )) {
++ LogError( "symlink %\"s => %\"s failed: %m; control socket will not be available\n",
++ sockdir, cr->realdir );
++ rmdir( cr->realdir );
++ free( cr->realdir );
++ cr->realdir = 0;
++ } else {
++ chown( sockdir, 0, d ? 0 : fifoGroup );
+ chmod( sockdir, 0750 );
++#endif
+ if ((cr->fd = socket( PF_UNIX, SOCK_STREAM, 0 )) < 0)
+ LogError( "Cannot create control socket\n" );
+ else {
+- unlink( cr->path );
+ sa.sun_family = AF_UNIX;
+ strcpy( sa.sun_path, cr->path );
+ if (!bind( cr->fd, (struct sockaddr *)&sa, sizeof(sa) )) {
+ if (!listen( cr->fd, 5 )) {
++#ifdef HONORS_SOCKET_PERMS
++ chmod( cr->path, 0660 );
++ if (!d)
++ chown( cr->path, -1, fifoGroup );
++ chmod( sockdir, 0755 );
++#else
+ chmod( cr->path, 0666 );
++#endif
+ RegisterCloseOnFork( cr->fd );
+ RegisterInput( cr->fd );
+ free( sockdir );
+@@ -170,6 +216,14 @@ openCtrl( struct display *d )
+ close( cr->fd );
+ cr->fd = -1;
+ }
++#ifdef HONORS_SOCKET_PERMS
++ rmdir( sockdir );
++#else
++ unlink( sockdir );
++ rmdir( cr->realdir );
++ free( cr->realdir );
++ cr->realdir = 0;
++#endif
+ }
+ free( cr->path );
+ cr->path = 0;
+@@ -190,7 +244,14 @@ closeCtrl( struct display *d )
+ cr->fd = -1;
+ unlink( cr->path );
+ *strrchr( cr->path, '/' ) = 0;
++#ifdef HONORS_SOCKET_PERMS
+ rmdir( cr->path );
++#else
++ unlink( cr->path );
++ rmdir( cr->realdir );
++ free( cr->realdir );
++ cr->realdir = 0;
++#endif
+ free( cr->path );
+ cr->path = 0;
+ while (cr->css) {
+@@ -218,12 +279,12 @@ chownCtrl( CtrlRec *cr, int uid )
+ {
+ if (cr->fpath)
+ chown( cr->fpath, uid, -1 );
+- if (cr->path) {
+- char *ptr = strrchr( cr->path, '/' );
+- *ptr = 0;
++ if (cr->path)
++#ifdef HONORS_SOCKET_PERMS
+ chown( cr->path, uid, -1 );
+- *ptr = '/';
+- }
++#else
++ chown( cr->realdir, uid, -1 );
++#endif
+ }
+
+ void
+--- kdebase-3.5.10/kdm/backend/dm.h.sav 2010-03-23 13:22:28.401354858 +0100
++++ kdebase-3.5.10/kdm/backend/dm.h 2010-03-23 13:28:24.843351116 +0100
+@@ -218,6 +218,9 @@ typedef struct {
+ struct cmdsock *css; /* open connections */
+
+ char *path; /* filename of the socket */
++#ifndef HONORS_SOCKET_PERMS
++ char *realdir; /* real dirname of the socket */
++#endif
+ int fd; /* fd of the socket */
+ int gid; /* owner group of the socket */
+
+--- kdebase-3.5.10/config.h.in.sav 2008-08-20 18:00:23.000000000 +0200
++++ kdebase-3.5.10/config.h.in 2010-03-23 13:36:38.913475918 +0100
+@@ -739,6 +739,9 @@
+ /* Defined if your system has XRandR support */
+ #undef XRANDR_SUPPORT
+
++/* Define to 1 if OS honors permission bits on socket inodes */
++#undef HONORS_SOCKET_PERMS
++
+ /*
+ * jpeg.h needs HAVE_BOOLEAN, when the system uses boolean in system
+ * headers and I'm too lazy to write a configure test as long as only
+--- kdebase-3.5.10/configure.in.in.sav 2006-07-22 10:15:55.000000000 +0200
++++ kdebase-3.5.10/configure.in.in 2010-03-23 13:51:24.504477535 +0100
+@@ -274,3 +274,31 @@ AC_SUBST(LIBART_RPATH)
+ AC_ARG_WITH([composite],
+ AC_HELP_STRING([--without-composite], [Disable Xcomposite support (default: check)]) )
+
++AC_TRY_RUN([
++#include <sys/socket.h>
++#include <sys/un.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++#include <string.h>
++#include <unistd.h>
++#include <errno.h>
++int main()
++{
++ int fd, fd2;
++ struct sockaddr_un sa;
++
++ if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
++ return 2;
++ sa.sun_family = AF_UNIX;
++ strcpy(sa.sun_path, "testsock");
++ unlink(sa.sun_path);
++ if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)))
++ return 2;
++ chmod(sa.sun_path, 0);
++ setuid(getuid() + 1000);
++ if ((fd2 = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
++ return 2;
++ connect(fd2, (struct sockaddr *)&sa, sizeof(sa));
++ return errno != EACCES;
++}
++], AC_DEFINE_UNQUOTED(HONORS_SOCKET_PERMS, 1, [Define to 1 if OS honors permission bits on socket inodes]))
diff --git a/opensuse/tdebase/clock-applet-style.diff b/opensuse/tdebase/clock-applet-style.diff
new file mode 100644
index 000000000..42c768337
--- /dev/null
+++ b/opensuse/tdebase/clock-applet-style.diff
@@ -0,0 +1,22 @@
+Index: kicker/applets/clock/clockapplet.kcfg
+===================================================================
+--- kicker/applets/clock/clockapplet.kcfg.orig
++++ kicker/applets/clock/clockapplet.kcfg
+@@ -14,7 +14,7 @@
+ <choice name="Analog"/>
+ <choice name="Fuzzy"/>
+ </choices>
+- <default>Digital</default>
++ <default>Plain</default>
+ </entry>
+ </group>
+ <group name="Date">
+@@ -56,7 +56,7 @@ defFont.setPointSize(8);
+ <label>Font for the clock.</label>
+ <code>
+ defFont=KGlobalSettings::generalFont();
+-defFont.setPointSize(8);
++defFont.setPointSize(16);
+ defFont.setBold(true);
+ </code>
+ <default code="true">defFont</default>
diff --git a/opensuse/tdebase/clock-suse-integrate.diff b/opensuse/tdebase/clock-suse-integrate.diff
new file mode 100644
index 000000000..a4d24dff8
--- /dev/null
+++ b/opensuse/tdebase/clock-suse-integrate.diff
@@ -0,0 +1,288 @@
+Index: kcontrol/clock/tzone.cpp
+===================================================================
+--- kcontrol/clock/tzone.cpp.orig
++++ kcontrol/clock/tzone.cpp
+@@ -27,12 +27,16 @@
+
+ #include <qlabel.h>
+ #include <qfile.h>
++#include <qregexp.h>
+
+ #include <kdebug.h>
+ #include <klocale.h>
+ #include <kmessagebox.h>
+ #include <kdialog.h>
+ #include <kio/netaccess.h>
++#include <kprocess.h>
++#include <ksavefile.h>
++#include <kstandarddirs.h>
+
+ //#include "xpm/world.xpm"
+ #include "tzone.h"
+@@ -55,6 +59,8 @@ Tzone::Tzone(QWidget * parent, const cha
+ connect( tzonelist, SIGNAL(selectionChanged()), SLOT(handleZoneChange()) );
+
+ m_local = new QLabel(this);
++
++ setupSuseTimezone();
+
+ load();
+
+@@ -158,28 +164,38 @@ void Tzone::save()
+
+ QString val = selectedzone;
+ #else
+- QFile fTimezoneFile("/etc/timezone");
++ QString tz = "/usr/share/zoneinfo/" + selectedzone;
+
+- if (fTimezoneFile.open(IO_WriteOnly | IO_Truncate) )
++ kdDebug() << "Set time zone " << tz << endl;
++
++ writeSuseTimezone( selectedzone );
++
++ if( !KStandardDirs::findExe( "zic" ).isEmpty())
+ {
+- QTextStream t(&fTimezoneFile);
+- t << selectedzone;
+- fTimezoneFile.close();
++ KProcess proc;
++ proc << "zic" << "-l" << selectedzone;
++ proc.start( KProcess::Block );
+ }
++ else
++ {
++ QFile fTimezoneFile("/etc/timezone");
+
+- QString tz = "/usr/share/zoneinfo/" + selectedzone;
+-
+- kdDebug() << "Set time zone " << tz << endl;
++ if (fTimezoneFile.open(IO_WriteOnly | IO_Truncate) )
++ {
++ QTextStream t(&fTimezoneFile);
++ t << selectedzone;
++ fTimezoneFile.close();
++ }
+
+- if (!QFile::remove("/etc/localtime"))
+- {
++ if (!QFile::remove("/etc/localtime"))
++ {
+ //After the KDE 3.2 release, need to add an error message
+- }
+- else
++ }
++ else
+ if (!KIO::NetAccess::file_copy(KURL(tz),KURL("/etc/localtime")))
+ KMessageBox::error( 0, i18n("Error setting new timezone."),
+ i18n("Timezone Error"));
+-
++ }
+ QString val = ":" + tz;
+ #endif // !USE_SOLARIS
+
+@@ -198,3 +214,58 @@ void Tzone::save()
+
+ currentZone();
+ }
++
++// read the configured timezone from /etc/sysconfig/clock
++// and simply set it as $TZ, KDE code then will take it as the timezone
++void Tzone::setupSuseTimezone()
++{
++ QFile f( "/etc/sysconfig/clock" );
++ if( !f.open( IO_ReadOnly ))
++ return;
++ QTextStream str( &f );
++ while( !str.atEnd())
++ {
++ QString line = str.readLine();
++ if( line.startsWith( "TIMEZONE=" ))
++ {
++ QRegExp r( "\\s*TIMEZONE=\"(.*)\"\\s*" );
++ if( r.exactMatch( line ))
++ {
++ QString tz = r.cap( 1 );
++ setenv( "TZ", tz.ascii(), 1 );
++ }
++ }
++ }
++}
++
++void Tzone::writeSuseTimezone( QString zone )
++{
++ QFile f( "/etc/sysconfig/clock" );
++ if( !f.open( IO_ReadOnly ))
++ return;
++ KSaveFile out( "/etc/sysconfig/clock", 0644 );
++ QFile* fout = out.file();
++ if( fout == NULL )
++ return;
++ QTextStream str( &f );
++ QTextStream strout( fout );
++ while( !str.atEnd())
++ {
++ QString line = str.readLine();
++ if( line.startsWith( "TIMEZONE=" ))
++ {
++ QRegExp r( "\\s*TIMEZONE=\"(.*)\"\\s*" );
++ if( r.exactMatch( line ))
++ {
++ QString tz = r.cap( 1 );
++ if( tz == zone ) // not changed, abort
++ {
++ out.abort();
++ return;
++ }
++ line = "TIMEZONE=\"" + zone + "\"";
++ }
++ }
++ strout << line << '\n';
++ }
++}
+Index: kcontrol/clock/tzone.h
+===================================================================
+--- kcontrol/clock/tzone.h.orig
++++ kcontrol/clock/tzone.h
+@@ -47,6 +47,8 @@ protected slots:
+
+ private:
+ void currentZone();
++ void setupSuseTimezone();
++ void writeSuseTimezone( QString timezone );
+ KTimezones m_zoneDb;
+ QLabel *m_local;
+ KTimezoneWidget *tzonelist;
+Index: kcontrol/clock/dtime.h
+===================================================================
+--- kcontrol/clock/dtime.h.orig
++++ kcontrol/clock/dtime.h
+@@ -65,6 +65,9 @@ signals:
+ void timeout();
+ void set_time();
+ void changeDate(QDate);
++#if 1
++ void configureTimeServer();
++#endif
+
+ private:
+ void findNTPutility();
+@@ -72,7 +75,11 @@ private:
+
+ QWidget* privateLayoutWidget;
+ QCheckBox *setDateTimeAuto;
++#if 1
++ QPushButton *timeServerConfigure;
++#else
+ QComboBox *timeServerList;
++#endif
+
+ KDatePicker *cal;
+ QComboBox *month;
+Index: kcontrol/clock/dtime.cpp
+===================================================================
+--- kcontrol/clock/dtime.cpp.orig
++++ kcontrol/clock/dtime.cpp
+@@ -38,6 +38,7 @@
+ #include <kmessagebox.h>
+ #include <kdialog.h>
+ #include <kconfig.h>
++#include <kstandarddirs.h>
+
+ #include "dtime.h"
+ #include "dtime.moc"
+@@ -74,6 +75,18 @@ Dtime::Dtime(QWidget * parent, const cha
+ connect(setDateTimeAuto, SIGNAL(toggled(bool)), SLOT(configChanged()));
+ layout1->addWidget( setDateTimeAuto );
+
++#if 1
++ // simply add a pushbutton that'll invoke the yast module
++ ntpUtility = KStandardDirs::findExe( "rcntp");
++ timeServerConfigure = new QPushButton( i18n( "Configure" ), privateLayoutWidget, "timeServerConfigure" );
++ connect(timeServerConfigure, SIGNAL(clicked()), SLOT(configChanged()));
++ connect(timeServerConfigure, SIGNAL(clicked()), SLOT(configureTimeServer()));
++ connect(setDateTimeAuto, SIGNAL(toggled(bool)), timeServerConfigure, SLOT(setEnabled(bool)));
++ timeServerConfigure->setEnabled(false);
++ layout1->addWidget( timeServerConfigure );
++ if( ntpUtility.isEmpty())
++ privateLayoutWidget->hide();
++#else
+ timeServerList = new QComboBox( false, privateLayoutWidget, "timeServerList" );
+ connect(timeServerList, SIGNAL(activated(int)), SLOT(configChanged()));
+ connect(timeServerList, SIGNAL(textChanged(const QString &)), SLOT(configChanged()));
+@@ -82,6 +95,7 @@ Dtime::Dtime(QWidget * parent, const cha
+ timeServerList->setEditable(true);
+ layout1->addWidget( timeServerList );
+ findNTPutility();
++#endif
+
+ // Date box
+ QGroupBox* dateBox = new QGroupBox( this, "dateBox" );
+@@ -179,7 +193,11 @@ Dtime::Dtime(QWidget * parent, const cha
+ hour->setEnabled(false);
+ minute->setEnabled(false);
+ second->setEnabled(false);
++#if 1
++ timeServerConfigure->setEnabled(false);
++#else
+ timeServerList->setEnabled(false);
++#endif
+ setDateTimeAuto->setEnabled(false);
+ }
+ kclock->setEnabled(false);
+@@ -241,6 +259,15 @@ void Dtime::configChanged(){
+ void Dtime::load()
+ {
+ KConfig config("kcmclockrc", true, false);
++#if 1
++ if( !ntpUtility.isEmpty())
++ {
++ KProcess proc;
++ proc << ntpUtility << "status";
++ proc.start( KProcess::Block );
++ setDateTimeAuto->setChecked( proc.exitStatus() == 0 );
++ }
++#else
+ config.setGroup("NTP");
+ timeServerList->insertStringList(QStringList::split(',', config.readEntry("servers",
+ i18n("Public Time Server (pool.ntp.org),\
+@@ -249,6 +276,7 @@ europe.pool.ntp.org,\
+ north-america.pool.ntp.org,\
+ oceania.pool.ntp.org"))));
+ setDateTimeAuto->setChecked(config.readBoolEntry("enabled", false));
++#endif
+
+ // Reset to the current date and time
+ time = QTime::currentTime();
+@@ -264,6 +292,7 @@ oceania.pool.ntp.org"))));
+ void Dtime::save()
+ {
+ KConfig config("kcmclockrc", false, false);
++#if 0
+ config.setGroup("NTP");
+
+ // Save the order, but don't duplicate!
+@@ -301,7 +330,9 @@ void Dtime::save()
+ kdDebug() << "Set date from time server " << timeServer.latin1() << " success!" << endl;
+ }
+ }
+- else {
++ else
++#endif
++ {
+ // User time setting
+ KProcess c_proc;
+
+@@ -356,6 +387,13 @@ void Dtime::timeout()
+ kclock->setTime( time );
+ }
+
++void Dtime::configureTimeServer()
++{
++ KProcess proc;
++ proc << "/sbin/yast2" << "ntp-client";
++ proc.start( KProcess::DontCare );
++}
++
+ QString Dtime::quickHelp() const
+ {
+ return i18n("<h1>Date & Time</h1> This control module can be used to set the system date and"
diff --git a/opensuse/tdebase/console8x16.pcf.gz b/opensuse/tdebase/console8x16.pcf.gz
new file mode 100644
index 000000000..db4be9f47
--- /dev/null
+++ b/opensuse/tdebase/console8x16.pcf.gz
Binary files differ
diff --git a/opensuse/tdebase/default-kdeprintfax.diff b/opensuse/tdebase/default-kdeprintfax.diff
new file mode 100644
index 000000000..ed686b4a7
--- /dev/null
+++ b/opensuse/tdebase/default-kdeprintfax.diff
@@ -0,0 +1,13 @@
+Index: kdeprint/kdeprintfax/confsystem.cpp
+===================================================================
+--- kdeprint/kdeprintfax/confsystem.cpp.orig
++++ kdeprint/kdeprintfax/confsystem.cpp
+@@ -103,7 +103,7 @@ void ConfSystem::load()
+ m_commands << conf->readPathEntry("HylaFax", defaultCommand(hylafax_default_cmd));
+ m_commands << conf->readPathEntry("Mgetty", defaultCommand(mgetty_default_cmd));
+ m_commands << conf->readPathEntry( "Other", QString::null );
+- QString v = conf->readEntry("System", "efax");
++ QString v = conf->readEntry("System", "hylafax");
+ if (v == "mgetty") m_current = MGETTY_ID;
+ else if (v == "hylafax") m_current = HYLAFAX_ID;
+ else if ( v == "other" ) m_current = OTHER_ID;
diff --git a/opensuse/tdebase/default_fonts.diff b/opensuse/tdebase/default_fonts.diff
new file mode 100644
index 000000000..4300b5aed
--- /dev/null
+++ b/opensuse/tdebase/default_fonts.diff
@@ -0,0 +1,25 @@
+Index: kcontrol/fonts/fonts.cpp
+===================================================================
+--- kcontrol/fonts/fonts.cpp.orig
++++ kcontrol/fonts/fonts.cpp
+@@ -1,3 +1,4 @@
++
+ // KDE Display fonts setup tab
+ //
+ // Copyright (c) Mark Donohoe 1997
+@@ -524,11 +525,11 @@ KFonts::KFonts(QWidget *parent, const ch
+
+ // Keep in sync with kdelibs/kdecore/kglobalsettings.cpp
+
+- QFont f0("Sans Serif", 10);
+- QFont f1("Monospace", 10);
++ QFont f0("Sans Serif", 12);
++ QFont f1("courier", 12);
+ QFont f2("Sans Serif", 10);
+- QFont f3("Sans Serif", 9, QFont::Bold);
+- QFont f4("Sans Serif", 10);
++ QFont f3("Sans Serif", 12, QFont::Bold);
++ QFont f4("Sans Serif", 11);
+
+ f0.setPointSize(10);
+ f1.setPointSize(10);
diff --git a/opensuse/tdebase/devmon-automounter.sh b/opensuse/tdebase/devmon-automounter.sh
new file mode 100644
index 000000000..ff2de18f1
--- /dev/null
+++ b/opensuse/tdebase/devmon-automounter.sh
@@ -0,0 +1,1086 @@
+#!/bin/bash
+# Script Name: devmon http://igurublog.wordpress.com/downloads/script-devmon/
+# Requires: udisks bash>=4
+# Recommended: consolekit zenity
+# License: GNU GENERAL PUBLIC LICENSE Version 3 http://www.gnu.org/licenses/gpl-3.0.txt
+# Thanks to Bernard Baeyens (berbae) for code from udisksvm script
+# https://bbs.archlinux.org/viewtopic.php?id=112397
+
+#=========================================================================
+
+defaultmountoptions="noexec,nosuid,noatime"
+
+#=========================================================================
+
+help()
+{
+ cat << EOF
+devmon version 1.0.5
+Automounts and unmounts optical and removable drives using udisks
+Requires: udisks bash>=4 Recommended: consolekit zenity
+Usage: devmon [AUTOMOUNT-OPTIONS] # Run as daemon to automount
+ devmon [MOUNT-OPTIONS] # Or run as client to manually un/mount
+AUTOMOUNT-OPTIONS: (these can be used only in daemon mode)
+--exec-on-device DEVICE "COMMAND" Execute COMMAND after mounting DEVICE
+--exec-on-label "LABEL" "COMMAND" Execute COMMAND after mounting LABEL
+--exec-on-video "COMMAND" Execute COMMAND after video DVD mount
+--exec-on-audio "COMMAND" Execute COMMAND after audio CD insertion
+--exec-on-disc "COMMAND" Execute COMMAND after data CD/DVD mount
+--exec-on-drive "COMMAND" Execute COMMAND after drive mount
+--exec-on-unmount "COMMAND" Execute COMMAND after unmount
+--exec-on-remove "COMMAND" Execute COMMAND after drive removal
+ Where the following in COMMAND will be replaced with:
+ %d mount point directory (eg /media/cd)
+ %f device name (eg /dev/sdd1)
+ %l label of mounted volume
+ Multiple --exec-on-XXX options may be used to execute multiple commands.
+ Other exec-on-XXX commands are ignored if exec-on-device or -label executed.
+--mount-options "OPTIONS" Default: $defaultmountoptions
+--info-on-mount Show mounted drive info in a zenity dialog
+--no-mount Don't mount anything, just exec (disables
+ --exec-on-video)
+--no-unmount Don't unmount all removable drives on exit
+
+MOUNT-OPTIONS: (these can be used only in client mode)
+--unmount-removable | -r Sync and unmount all removable drives and show
+ pop-up dialog (zenity installation required)
+--unmount-recent | -c Unmount most recently mounted removable drive
+--unmount-optical | -o Unmount all optical drives (error pop-up only)
+--unmount-all | -u Same as --unmount-removable --unmount-optical
+--unmount DIR|DEVICE Unmount DEVICE or mount point DIR
+--eject DIR|DEVICE Unmount and eject DEVICE or mount point DIR
+--mount-all | -a Mount all removable and optical drives
+--mount DEVICE Mount DEVICE
+--mount-options|--mount-fstype|--unmount-options|--eject-options "OPTIONS"
+ These options will be passed to udisks
+
+UNIVERSAL OPTIONS: (these can be used in both daemon and client modes)
+--ignore-device DEVICE Ignore DEVICE (eg /dev/sdd1)
+--ignore-label "LABEL" Ignore volume with LABEL
+--sync | -s Add sync mount option for ext2-4 ntfs ufs, or
+ flush for fat & vfat (slower writing but safer)
+--internal Also attempt to un/mount internal system drives
+ (this is mostly a fix for esata issues)
+--no-gui | -g Do not show zenity pop-up dialogs
+Instructions and updates:
+ http://igurublog.wordpress.com/downloads/script-devmon/
+EOF
+ exit
+}
+
+test2()
+{
+ if [ "${2:0:1}" = "-" ] || [ "$2" = "" ]; then
+ echo "devmon: Option $1 requires an argument" 1>&2
+ exit 1
+ fi
+}
+
+test3()
+{
+ if [ "${2:0:1}" = "-" ] || [ "$2" = "" ] || \
+ [ "${3:0:1}" = "-" ] || [ "$3" = "" ]; then
+ echo "devmon: Option $1 requires two arguments" 1>&2
+ exit 1
+ fi
+}
+
+unknown()
+{
+ echo "devmon: Unknown option $1" 1>&2
+ echo " For help use: devmon --help" 1>&2
+ exit 1
+}
+
+# parse command line
+execoix=0
+execomx=0
+execovx=0
+execoax=0
+execodx=0
+execolx=0
+execoux=0
+execorx=0
+umntx=0
+mntx=0
+ejx=0
+igdevx=0
+iglabx=0
+while [ "$1" != "" ]; do
+ if [ "${1:0:1}" = "-" ]; then
+ case "$1" in
+ --help )
+ help
+ exit
+ ;;
+ # don't use eval on these to preserve command strings
+ --exec-on-drive )
+ test2 "$1" "$2"
+ execoi[$execoix]="$2"
+ (( execoix++ ))
+ shift
+ ;;
+ --exec-on-disc )
+ test2 "$1" "$2"
+ execom[$execomx]="$2"
+ (( execomx++ ))
+ shift
+ ;;
+ --exec-on-video )
+ test2 "$1" "$2"
+ execov[$execovx]="$2"
+ (( execovx++ ))
+ shift
+ ;;
+ --exec-on-audio )
+ test2 "$1" "$2"
+ execoa[$execoax]="$2"
+ (( execoax++ ))
+ shift
+ ;;
+ --exec-on-device )
+ test3 "$1" "$2" "$3"
+ execod1[$execodx]="$2"
+ execod2[$execodx]="$3"
+ (( execodx++ ))
+ shift 2
+ ;;
+ --exec-on-label )
+ test3 "$1" "$2" "$3"
+ execol1[$execolx]="$2"
+ execol2[$execolx]="$3"
+ (( execolx++ ))
+ shift 2
+ ;;
+ --exec-on-unmount )
+ test2 "$1" "$2"
+ execou[$execoux]="$2"
+ (( execoux++ ))
+ shift
+ ;;
+ --exec-on-remove )
+ test2 "$1" "$2"
+ execor[$execorx]="$2"
+ (( execorx++ ))
+ shift
+ ;;
+ --info-on-mount )
+ infomount=1
+ ;;
+ --no-mount )
+ nomount=1
+ ;;
+ --sync )
+ syncopt=1
+ ;;
+ --unmount-on-exit )
+ # leave for usage compat with versions prior to 1.0.1
+ ;;
+ --no-unmount )
+ nounmount=1
+ ;;
+ --unmount-all )
+ unmountrem=1
+ unmountoptical=1
+ ;;
+ --unmount-removable )
+ unmountrem=1
+ ;;
+ --unmount-optical )
+ unmountoptical=1
+ ;;
+ --unmount-recent )
+ unmountrecent=1
+ ;;
+ --unmount )
+ test2 "$1" "$2"
+ umnt[$umntx]="$2"
+ (( umntx++ ))
+ shift
+ ;;
+ --mount-all )
+ mountall=1
+ ;;
+ --mount )
+ test2 "$1" "$2"
+ mnt[$mntx]="$2"
+ (( mntx++ ))
+ shift
+ ;;
+ --eject )
+ test2 "$1" "$2"
+ ej[$ejx]="$2"
+ (( ejx++ ))
+ shift
+ ;;
+ --mount-options )
+ test2 "$1" "$2"
+ mountoptions="$2"
+ shift
+ ;;
+ --mount-fstype )
+ test2 "$1" "$2"
+ mountfstype="$2"
+ shift
+ ;;
+ --unmount-options )
+ test2 "$1" "$2"
+ unmountoptions="$2"
+ shift
+ ;;
+ --eject-options )
+ test2 "$1" "$2"
+ ejectoptions="$2"
+ shift
+ ;;
+ --internal )
+ internal=1
+ ;;
+ --nogui | --no-gui )
+ nogui=1
+ ;;
+ --ignore-device )
+ test2 "$1" "$2"
+ igdev[$igdevx]="$2"
+ (( igdevx++ ))
+ shift
+ ;;
+ --ignore-label )
+ test2 "$1" "$2"
+ iglab[$iglabx]="$2"
+ (( iglabx++ ))
+ shift
+ ;;
+ --* )
+ unknown "$1";;
+ -* )
+ o="${1:1}"
+ while [ "$o" != "" ]; do
+ case "${o:0:1}" in
+ r )
+ unmountrem=1;;
+ o )
+ unmountoptical=1;;
+ u )
+ unmountrem=1
+ unmountoptical=1
+ ;;
+ a )
+ mountall=1;;
+ s )
+ syncopt=1;;
+ c )
+ unmountrecent=1;;
+ g )
+ nogui=1;;
+ h )
+ help
+ exit
+ ;;
+ * )
+ unknown "-${o:0:1}";;
+ esac
+ o="${o:1}"
+ done
+ ;;
+ esac
+ else
+ unknown "$1"
+ fi
+ shift
+done
+(( mountmode = umntx + mntx + ejx + unmountrem + unmountoptical + mountall + unmountrecent ))
+
+# Warnings
+if [ "$(whoami)" = "root" ]; then
+ echo "WARNING: running devmon as root is usually not required or recommended" 1>&2
+fi
+
+if (( execoix + execomx + execovx + execoax + execodx + execolx + execoux + execorx \
+ + nounmount + infomount != 0 )) && (( mountmode != 0 )); then
+ echo "WARNING: devmon automount options ignored in mount mode" 1>&2
+fi
+
+driveinfo() #$1=dev #Optional $2=quiet
+{
+ unset systeminternal usage ismounted presentationnopolicy hasmedia \
+ opticaldisc numaudiotracks type partition media blank label
+ uinfos=`udisks --show-info $1 2> /dev/null`
+ label=`echo "$uinfos" | grep -m 1 "^ label:" | sed 's/ *label: *\(.*\)/\1/'`
+ listinfos=`echo "$uinfos" | grep \
+ -e "^ system internal:" \
+ -e "^ usage:" \
+ -e "^ type:" \
+ -e "^ is mounted:" \
+ -e "^ presentation nopolicy:" \
+ -e "^ has media" \
+ -e "^ optical disc:" \
+ -e " blank:" \
+ -e " num audio tracks:" \
+ -e "^ partition:" \
+ -e " media:"`
+ # The change for type= is to take only its first value in listinfos
+ listinfos=$(echo "$listinfos" | sed 's/ //g
+ s/:/=/
+ s/opticaldisc=/&1/
+ s/type=\(.*\)/type=${type:-\1}/
+ s/[()]//g
+ s/partition=/&1/')
+ eval "$listinfos"
+ if (( internal == 1 )); then
+ systeminternal="ignored"
+ fi
+ # Take only the first character
+ hasmedia=${hasmedia:0:1}
+ # If "partition:" not find in listinfos, should mean it is not a partition
+ partition=${partition:-0}
+ nopolicy="$presentationnopolicy"
+ if (( mountmode == 0 )) && [ "$systeminternal" != "1" ] && [ "$2" != "quiet" ]; then
+ if [ "$usage" = "filesystem" ] || [ "$opticaldisc" = "1" ]; then
+ echo "device: [$1]"
+ echo " systeminternal: [$systeminternal]"
+ echo " usage: [$usage]"
+ echo " type: [$type]"
+ echo " label: [$label]"
+ echo " ismounted: [$ismounted]"
+ echo " nopolicy: [$nopolicy]"
+ echo " hasmedia: [$hasmedia]"
+ echo " opticaldisc: [$opticaldisc]"
+ echo " numaudiotracks: [$numaudiotracks]"
+ echo " blank: [$blank]"
+ echo " media: [$media]"
+ echo " partition: [$partition]"
+ fi
+ fi
+}
+
+ignoredevice()
+{
+ idx=0
+ while (( idx < igdevx )); do
+ if [ "$1" = "${igdev[$idx]}" ]; then
+ echo "devmon: ignored device $1"
+ return 0
+ fi
+ (( idx++ ))
+ done
+ return 1
+}
+
+ignorelabel()
+{
+ ilx=0
+ while (( ilx < iglabx )); do
+ if [ "$1" = "${iglab[$ilx]}" ]; then
+ echo "devmon: ignored label $1"
+ return 0
+ fi
+ (( ilx++ ))
+ done
+ return 1
+}
+
+execcommands() # $exectype "${exec[@]}"
+{
+ exectype="$1"
+ shift
+ while [ "$1" != "" ]; do
+ usercmd="$1"
+ usercmd="${usercmd//%f/$dv}"
+ usercmd="${usercmd//%l/'$lb'}"
+ usercmd="${usercmd//%d/'$point'}"
+ if [ "$usercmd" != "" ]; then
+ echo "devmon: [$exectype] eval $usercmd &"
+ eval $usercmd &
+ fi
+ shift
+ done
+}
+
+mountdev() # $1=device [$2=label] [$3=devtype or fstype]
+{
+ # set label comment
+ if [ "$2" = "" ]; then
+ lblcmt=""
+ else
+ lblcmt="($2)"
+ fi
+ # set mount-fstype option
+ if [ "$mountfstype" != "" ]; then
+ fst="--mount-fstype"
+ else
+ fst=""
+ fi
+ # set default mount options
+ if [ "$mountoptions" != "" ]; then
+ mopts="$mountoptions"
+ else
+ mopts="$defaultmountoptions"
+ fi
+ # set sync mount options
+ if (( syncopt == 1 )); then
+ case "$3" in
+ ext2 | ext3 | ext4 | ufs | ntfs )
+ mopts="$mopts,sync";;
+ fat | vfat )
+ mopts="$mopts,flush";;
+ esac
+ fi
+ # mount
+ mntmsg="devmon: mount $1 --mount-options $mopts $fst $mountfstype $lblcmt"
+ if [ "$3" != "nofs" ]; then
+ echo "$mntmsg"
+ fi
+ umsg=`udisks --mount $1 --mount-options "$mopts" $fst $mountfstype 2>&1`
+ mounterr="$?"
+ # get mount point
+ point=`echo "$umsg" | grep "^Mounted " | sed 's/^Mounted .* at \(.*\)/\1/'`
+ if [ "$mounterr" != "0" ] || [ "$point" = "" ]; then
+ # if $3=nofs then there was no apparent filesystem but we tried to mount it
+ # anyway in case it didn't report the filesystem accurately, so ignore the
+ # error
+ if [ "$3" != "nofs" ]; then
+ echo "$umsg" 1>&2
+ echo "devmon: error mounting $1 ($mounterr)" 1>&2
+ if (( mountmode == 0 )) && (( polkiterrgiven != 1 )) && \
+ [ "$(echo "$umsg" | grep "Not Authorized")" != "" ]; then
+ if (( nogui != 1 )); then
+ ( sleep 3 && WINDOWID="" zenity --error --no-wrap --title="devmon error" \
+ --text="udisks functions are not authorized through policykit,\nso devmon cannot automount drives.\nPlease see devmon's consolekit installation instructions:\n\nhttp://igurublog.wordpress.com/downloads/script-devmon/#install\n\n(To silence this pop-up add --no-gui to devmon's command line.)" &> /dev/null ) &
+ fi
+ echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" 1>&2
+ echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" 1>&2
+ echo "udisks functions are not authorized through policykit," 1>&2
+ echo "so devmon cannot automount drives." 1>&2
+ echo "Please see devmon's consolekit installation instructions:" 1>&2
+ echo "http://igurublog.wordpress.com/downloads/script-devmon/#install" 1>&2
+ echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" 1>&2
+ echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" 1>&2
+ polkiterrgiven=1
+ fi
+ fi
+ uerr=3
+ return 3
+ elif [ "$3" = "nofs" ]; then
+ # no filesystem reported but successful mount
+ echo "$mntmsg"
+ fi
+ echo "$umsg"
+}
+
+unmountdev() # $1=device
+{
+ if [ "$unmountoptions" != "" ]; then
+ echo "devmon: unmount $1 --unmount-options $unmountoptions"
+ uerrmsg=`udisks --unmount $1 --unmount-options "$unmountoptions" 2>&1`
+ else
+ echo "devmon: unmount $1"
+ uerrmsg=`udisks --unmount $1 2>&1`
+ fi
+ if [ "$uerrmsg" != "" ]; then
+ # bug: udisks returns $?==0 when unmount fails
+ echo "$uerrmsg"
+ uerr=3
+ return 3
+ fi
+}
+
+ejectdev()
+{
+ if [ "$ejectoptions" != "" ]; then
+ echo "devmon: eject $1 --eject-options $ejectoptions"
+ udisks --eject $1 --eject-options "$ejectoptions"
+ else
+ echo "devmon: eject $1"
+ udisks --eject $1
+ fi
+ if [ "$?" != "0" ]; then
+ uerr=3
+ return 3
+ fi
+}
+
+mountdrive() # $1=device $2=label [$3=devtype or fstype]
+{
+ dv="$1"
+ lb="$2"
+ tp="$3"
+ unset point
+
+ if ( ignoredevice "$dv" ) || ( ignorelabel "$lb" ); then
+ return
+ fi
+
+ # mount
+ if [ "$tp" != "audiocd" ] && (( nomount != 1 )); then
+ mountdev $dv "$lb" "$tp"
+ if [ "$?" != "0" ]; then
+ return
+ fi
+ fi
+
+ # exec on device
+ unset execdone
+ x=0
+ while (( x < execodx )); do
+ if [ "${execod1[$x]}" = "$dv" ]; then
+ usercmd="${execod2[$x]}"
+ usercmd="${usercmd//%f/$dv}"
+ usercmd="${usercmd//%l/'$lb'}"
+ usercmd="${usercmd//%d/'$point'}"
+ if [ "$usercmd" != "" ]; then
+ echo "devmon: [exec on device] eval $usercmd"
+ eval $usercmd &
+ execdone=1
+ fi
+ fi
+ (( x++ ))
+ done
+ if (( execdone == 1 )); then return; fi
+
+ # exec on label
+ x=0
+ while (( x < execolx )); do
+ if [ "${execol1[$x]}" = "$lb" ]; then
+ usercmd="${execol2[$x]}"
+ usercmd="${usercmd//%f/$dv}"
+ usercmd="${usercmd//%l/'$lb'}"
+ usercmd="${usercmd//%d/'$point'}"
+ if [ "$usercmd" != "" ]; then
+ echo "devmon: [exec on label] eval $usercmd"
+ eval $usercmd &
+ execdone=1
+ fi
+ fi
+ (( x++ ))
+ done
+ if (( execdone == 1 )); then return; fi
+
+ # exec on video
+ if [ "$tp" = "dvd" ] && [ "$point" != "" ] && [ -d "$point/VIDEO_TS" ]; then
+ echo "devmon: videodvd $dv ($lb) on $point"
+ if (( execovx != 0 )); then
+ execcommands "exec on video" "${execov[@]}"
+ fi
+ return
+ fi
+
+ # exec on audio
+ if [ "$tp" = "audiocd" ]; then
+ echo "devmon: audiocd $dv ($lb)"
+ if (( execoax != 0 )); then
+ execcommands "exec on audio" "${execoa[@]}"
+ fi
+ return
+ fi
+
+ # exec on disc
+ if [ "$tp" = "optical" ] || [ "$tp" = "dvd" ]; then
+ if [ "$point" != "" ] || (( nomount == 1 )); then
+ if (( execomx != 0 )); then
+ execcommands "exec on disc" "${execom[@]}"
+ fi
+ fi
+ return
+ fi
+
+ # exec on drive
+ if [ "$point" != "" ] || (( nomount == 1 )); then
+ if (( execoix != 0 )); then
+ execcommands "exec on drive" "${execoi[@]}"
+ fi
+ fi
+
+ # info on mount
+ if [ "$point" != "" ] && (( infomount == 1 )) && (( nomount != 1 )); then
+ sleep .5
+ echo "devmon: [info on mount] $dv"
+ if (( nogui != 1 )); then
+ WINDOWID="" zenity --info --text="The following device has been mounted:\n\n$(df -hT "$dv" \
+ | grep "$dv" | awk '{print "Device:\\t"$1"\x0AType:\\t"$2"\nSize:\\t\\t"$3"\nUsed:\\t"$4"\n""Avail:\\t"$5"\nUse%:\\t"$6"\nMount:\\t"$7,$8,$9,$10}')\nLabel:\\t$lb" --title="devmon mount" &
+ fi
+ df -hT "$dv"
+ fi
+}
+
+mountalldrives()
+{
+ # Mount all optical drives, no exec
+ x=0
+ while [ -e /dev/sr$x ]; do
+ driveinfo /dev/sr$x
+ if [ "$numaudiotracks" = "" ]; then
+ numaudiotracks=0
+ fi
+ if [ "$systeminternal" != "1" ] && [ "$opticaldisc" = "1" ] && \
+ [ "$ismounted" != "1" ] && [ "$hasmedia" != "0" ] && \
+ [ "$blank" != "1" ] && (( numaudiotracks == 0 )) && \
+ [ "$nopolicy" != "1" ]; then
+ if ( ignoredevice "/dev/sr$x" ) || ( ignorelabel "$label" ); then
+ (( x++ ))
+ continue
+ fi
+ mountdev /dev/sr$x "$label"
+ eval notejectedsr$x=1
+ fi
+ (( x++ ))
+ done
+ # Mount removable drives, no exec
+ IFSOLD="$IFS"
+ IFS=$'\n'
+ partlist=`grep " sd[a-z0-9]*$" /proc/partitions | sed 's/.* \(sd[a-z0-9]*\)/\1/'`
+ for p in $partlist; do
+ if ( ignoredevice "/dev/$p" ); then
+ continue
+ fi
+ driveinfo /dev/$p
+ if ( ignorelabel "$label" ); then
+ continue
+ else
+ if [ "$systeminternal" != "1" ] && [ "$opticaldisc" != "1" ] && \
+ [ "$ismounted" = "0" ] && [ "$nopolicy" != "1" ]; then
+ if [ "$usage" = "filesystem" ]; then
+ echo "mountdev /dev/$p $label $type"
+ mountdev /dev/$p "$label" "$type"
+ else
+ mountdev /dev/$p "$label" nofs
+ fi
+ fi
+ fi
+ done
+ IFS="$IFSOLD"
+}
+
+trapexit()
+{
+ kill $COPROC_PID 2> /dev/null
+
+ # prevent trap code from executing multiple times on different signals
+ if (( trapdone != 1 )); then
+ trapdone=1
+ # Unmount All
+ if (( nounmount != 1 )); then
+ IFSOLD="$IFS"
+ IFS=$'\n'
+ uerr=0
+ partlist=`grep " sd[a-z0-9]*$" /proc/partitions | \
+ sed 's/.* \(sd[a-z0-9]*\)/\1/'`
+ for p in $partlist; do
+ if ( ignoredevice "/dev/$p" ); then
+ continue
+ fi
+ driveinfo /dev/$p
+ if ( ignorelabel "$label" ); then
+ continue
+ else
+ if [ "$systeminternal" != "1" ] && [ "$opticaldisc" != "1" ] && \
+ [ "$usage" = "filesystem" ] && [ "$ismounted" = "1" ]; then
+ echo "devmon: [on exit] unmount /dev/$p &"
+ udisks --unmount /dev/$p &
+ if [ "$?" != "0" ]; then
+ uerr=3
+ fi
+ fi
+ fi
+ done
+ IFS="$IFSOLD"
+ fi
+ echo 'devmon: stopped'
+ exit $uerr
+ fi
+}
+
+# Client Mode
+if (( mountmode != 0 )); then
+ uerr=0
+ if (( unmountrem == 1 )) || (( unmountrecent == 1 )); then
+ y=0
+ unset udrive zpid
+ IFSOLD="$IFS"
+ IFS=$'\n'
+ if (( unmountrem == 1 )); then
+ # Unmount All Removable Drives
+ partlist=`grep " sd[a-z0-9]*$" /proc/partitions | sed 's/.* \(sd[a-z0-9]*\)/\1/'`
+ msgtitle="devmon unmount"
+ else
+ # Unmount Recent
+ partlist=`mount | grep "^/dev/.* on " | sed 's/^\/dev\/\(.*\) on .*/\1/' \
+ | grep -v -e "null" -e "shm" -e "mapper" -e "snd" \
+ -e "video" -e "random" | tac`
+ msgtitle="devmon unmount recent"
+ fi
+ for p in $partlist; do
+ if ( ignoredevice "/dev/$p" ); then
+ continue
+ fi
+ driveinfo /dev/$p
+ if ( ignorelabel "$label" ); then
+ continue
+ else
+ if [ "$systeminternal" != "1" ] && [ "$opticaldisc" != "1" ] \
+ && [ "$ismounted" = "1" ]; then
+ udrive[$y]="/dev/$p"
+ (( y++ ))
+ if (( unmountrem != 1 )); then break; fi
+ fi
+ fi
+ done
+ IFS="$IFSOLD"
+ if (( y == 0 )); then
+ msg="No removable drives are mounted"
+ echo "$msg"
+ else
+ msg="Unmounting ${udrive[@]}...\n\n(This dialog will close when the devices are unmounted)"
+ echo "Preparing to unmount ${udrive[@]}"
+ fi
+ if (( nogui != 1 )); then
+ WINDOWID="" zenity --info --title="$msgtitle" --text="$msg" &> /dev/null &
+ zpid=$!
+ fi
+ if (( y > 0 )); then
+ echo "devmon: sync"
+ sync
+ for d in ${udrive[@]}; do
+ unmountdev $d
+ if [ "$?" != "0" ] && (( nogui != 1 )); then
+ driveinfo "$d" quiet
+ if [ "$label" = "" ]; then
+ lb=""
+ else
+ lb=" ($label)"
+ fi
+ msg="Unmount error on $d$lb:\n\n$uerrmsg"
+ WINDOWID="" zenity --error --title="$msgtitle" --text="$msg" &> /dev/null &
+ fi
+ done
+ echo "devmon: sync"
+ sync
+ fi
+ if [ "$zpid" != "" ]; then
+ sleep 2
+ kill $zpid 2> /dev/null
+ fi
+ fi
+
+ # Unmount Optical
+ if (( unmountoptical == 1 )); then
+ x=0
+ while [ -e "/dev/sr$x" ]; do
+ if ( ignoredevice "/dev/sr$x" ); then
+ (( x++ ))
+ continue
+ fi
+ driveinfo /dev/sr$x
+ if ( ignorelabel "$label" ); then
+ (( x++ ))
+ continue
+ else
+ if [ "$systeminternal" != "1" ] && [ "$opticaldisc" = "1" ] && \
+ [ "$ismounted" = "1" ]; then
+ unmountdev /dev/sr$x
+ if [ "$?" != "0" ] && (( nogui != 1 )); then
+ if [ "$label" = "" ]; then
+ lb=""
+ else
+ lb=" ($label)"
+ fi
+ msg="Unmount error on /dev/sr$x$lb:\n\n$uerrmsg"
+ WINDOWID="" zenity --error --title="devmon unmount optical" \
+ --text="$msg" &> /dev/null &
+ fi
+ fi
+ fi
+ (( x++ ))
+ done
+ fi
+
+ # Unmount DIR|DEVICE
+ if (( umntx > 0 )); then
+ x=0
+ while (( x < umntx )); do
+ d="${umnt[$x]}"
+ # remove trailing slash
+ if [ "$d" != "/" ]; then
+ d="${d%/}"
+ fi
+ if [ "${d:0:5}" = "/dev/" ]; then
+ # Unmount DEVICE
+ unmountdev "$d"
+ else
+ # Unmount DIR
+ if [ "$(dirname "$d")" = "." ]; then
+ if [ -d "$(pwd)/$d" ]; then
+ d="$(pwd)/$d"
+ elif [ -d "/media/$d" ]; then
+ d="/media/$d"
+ elif [ -e "/dev/$d" ] && [ "$(mount | grep "^/dev/$d on ")" != "" ]; then
+ unmountdev "/dev/$d"
+ (( x++ ))
+ continue
+ fi
+ fi
+ if [ ! -d "$d" ]; then
+ echo "devmon: No such directory or mounted device $d" 1>&2
+ uerr=3
+ else
+ dv=`mount | grep -m 1 " on $d type " | awk '{print $1}'`
+ if [ "$dv" = "" ]; then
+ echo "devmon: Nothing mounted on $d (mtab)" 1>&2
+ uerr=3
+ else
+ unmountdev "$dv"
+ fi
+ fi
+ fi
+ (( x++ ))
+ done
+ fi
+
+ # Eject DIR|DEVICE
+ if (( ejx > 0 )); then
+ x=0
+ while (( x < ejx )); do
+ d="${ej[$x]}"
+ # remove trailing slash
+ if [ "$d" != "/" ]; then
+ d="${d%/}"
+ fi
+ dv=""
+ if [ "${d:0:5}" = "/dev/" ]; then
+ # Eject DEVICE
+ dv="$d"
+ else
+ # Eject DIR
+ if [ "$(dirname "$d")" = "." ]; then
+ if [ -d "$(pwd)/$d" ]; then
+ d="$(pwd)/$d"
+ elif [ -d "/media/$d" ]; then
+ d="/media/$d"
+ elif [ -e "/dev/$d" ] && [ "$(mount | grep "^/dev/$d on ")" != "" ]; then
+ dv="/dev/$d"
+ fi
+ fi
+ if [ "$dv" = "" ]; then
+ if [ ! -d "$d" ]; then
+ echo "devmon: No such directory or mounted device $d" 1>&2
+ uerr=3
+ else
+ dv=`mount | grep -m 1 " on $d type " | awk '{print $1}'`
+ if [ "$dv" = "" ]; then
+ echo "devmon: Nothing mounted on $d (mtab)" 1>&2
+ uerr=3
+ fi
+ fi
+ fi
+ fi
+ if [ "$dv" != "" ]; then
+ driveinfo "$dv"
+ if [ "$systeminternal" != "1" ] && [ "$opticaldisc" = "1" ] && \
+ [ "$ismounted" = "1" ]; then
+ unmountdev "$dv"
+ fi
+ ejectdev "$dv"
+ fi
+ (( x++ ))
+ done
+ fi
+
+ # Mount DEVICE
+ if (( mntx > 0 )); then
+ x=0
+ while (( x < mntx )); do
+ d="${mnt[$x]}"
+ # remove trailing slash
+ if [ "$d" != "/" ]; then
+ d="${d%/}"
+ fi
+ if [ "$(dirname "$d")" = "." ] && [ "${d:0:5}" != "/dev/" ]; then
+ d="/dev/$d"
+ fi
+ driveinfo "$d" quiet
+ if [ "$opticaldisc" = "1" ]; then
+ mountdev $d "$label"
+ else
+ mountdev $d "$label" "$type"
+ fi
+ (( x++ ))
+ done
+ fi
+
+ # Mount All Unmounted
+ if (( mountall == 1 )); then
+ mountalldrives
+ fi
+
+ exit $uerr
+fi
+
+# Daemon Mode
+if [ "$mountfstype" != "" ]; then
+ echo "WARNING: --mount-fstype ignored in daemon mode" 1>&2
+ mountfstype=""
+fi
+if [ "$unmountoptions" != "" ]; then
+ echo "WARNING: --unmount-options ignored in daemon mode" 1>&2
+ unmountoptions=""
+fi
+if [ "$ejectoptions" != "" ]; then
+ echo "WARNING: --eject-options ignored in daemon mode" 1>&2
+ ejectoptions=""
+fi
+pidcount=`ps h -C ${0//*\//} -o pid | wc -l`
+if (( pidcount > 2 )); then
+ echo
+ echo "WARNING: multiple instances of devmon appear to be running"
+ echo
+fi
+
+# Trigger udisks daemon start two ways
+if [ -e /dev/sr0 ]; then
+ udisks --poll-for-media /dev/sr0
+fi
+udisks --show-info /dev/sda > /dev/null
+sleep 2 # helps successful sr0 startup mount on reboot
+
+
+# Startup Mounting
+if (( nomount != 1 )); then
+ mountalldrives
+fi
+
+# Start monitoring
+coproc udisks --monitor
+err=$?
+trap trapexit EXIT SIGINT SIGTERM SIGQUIT
+trap "echo devmon: ignored HUP" SIGHUP
+
+if [ $err != "0" ] || [ ! ps -p $COPROC_PID &>/dev/null ]; then
+ echo "devmon: unable to start udisks --monitor" 1>&2
+ echo " is udisks installed and dbus running?" 1>&2
+ exit 2
+fi
+
+
+# Monitoring Loop
+while ps -p $COPROC_PID &>/dev/null; do
+ read -u ${COPROC[0]}
+ echo "==========================================="
+ echo "$REPLY"
+ event="${REPLY%:*}"
+ devpath="${REPLY#*:}"
+ devpath="/dev/${devpath##*/}"
+ if [ "$event" != "" ] && [ "$devpath" != "/dev/" ] && [ -e "$devpath" ]; then
+ case $event in
+ added )
+ driveinfo $devpath
+ if [ "$systeminternal" != "1" ] && [ "$ismounted" = "0" ] && \
+ [ "$nopolicy" != "1" ]; then
+ if [ "$usage" = "filesystem" ]; then
+ mountdrive $devpath "$label" "$type"
+ else
+ mountdrive $devpath "$label" nofs
+ fi
+ fi
+ ;;
+ job-changed )
+ ;;
+ removed )
+ ;;
+ changed )
+ driveinfo $devpath
+ eval notejected=\$notejected${devpath#/dev/}
+ eval devmounted=\$devmounted${devpath#/dev/}
+ eval devmounted${devpath#/dev/}="$ismounted"
+ # If notejected==1 then cd has not been ejected and was probably
+ # manually unmounted, so don't automount it. Otherwise
+ # devmon will instantly mount any manual unmount.
+ if [ "$systeminternal" != "1" ] && [ "$opticaldisc" = "1" ] && \
+ [ "$ismounted" != "1" ] && [ "$hasmedia" != "0" ] && \
+ [ "$blank" != "1" ] && (( notejected != 1 )) && \
+ [ "$nopolicy" != "1" ]; then
+ if [ "$media" = "optical_dvd" ]; then
+ mountdrive $devpath "$label" dvd
+ elif (( numaudiotracks > 0 )); then
+ mountdrive $devpath "$label" audiocd
+ else
+ mountdrive $devpath "$label" optical
+ fi
+ eval notejected${devpath#/dev/}=1
+ else
+ if [ "$systeminternal" != "1" ] && \
+ [ "$ismounted" != "1" ] && [ "$hasmedia" = "0" ]; then
+ # disc ejected
+ echo "devmon: $devpath eject detected"
+ eval notejected${devpath#/dev/}=0
+ fi
+ if [ "$systeminternal" != "1" ] && [ "$ismounted" != "1" ] && \
+ [ "$nopolicy" != "1" ] && [ "$devmounted" = "1" ]; then
+ # exec-on-unmount
+ if (( execoux != 0 )); then
+ if ( ! ignoredevice "$devpath" ) && ( ! ignorelabel "$label" ); then
+ dv="$devpath"
+ execcommands "exec on unmount" "${execou[@]}"
+ fi
+ fi
+ fi
+ fi
+ ;;
+ esac
+ elif [ "$event" = "removed" ]; then
+ eval unset devmounted${devpath#/dev/}
+ # exec-on-remove
+ if (( execorx != 0 )); then
+ if ( ! ignoredevice "$devpath" ); then
+ unset lb point
+ dv="$devpath"
+ execcommands "exec on remove" "${execor[@]}"
+ fi
+ fi
+ fi
+done
+
+exit
+
+# CHANGELOG
+# 1.0.5: --exec-on-unmount now executes only once per unmount
+# 1.0.4: added --exec-on-unmount, --exec-on-remove
+# added multiple instance warning
+# %f device spec no longer passed in quotes to commands
+# 1.0.3: help updated for sync
+# corrected exec-on-drive bug introduced in 1.0.1
+# 1.0.2: --sync adds sync for ntfs
+# 1.0.1: added --sync
+# added --no-unmount; unmount-on-exit is now default
+# obey UDISKS_PRESENTATION_NOPOLICY to inhibit automount
+# added unmount-all error pop-ups
+# 1.0.0: added --unmount-recent
+# improved udisks mount info to stdout
+# improved mount/unmount without apparent filesystem
+# 0.9.5: ignore trailing slash in un/mount dir/dev specs
+# attempt to mount no filesystem in case there is one
+# 0.9.4: polkit error more selective
+# 0.9.3: corrected problems with spaces in volume labels
+# corrected un/mounting of partitionless devices
+# corrected --ignore-devices problem
+# added not authorized pop-up error
+# 0.9.2: added --internal
+# 0.9.1: corrected --unmount-on-removable not recognized
+# 0.9.0: changed --unmount-all to --unmount-removable
+# added --unmount-all (now includes optical)
+# added --unmount-optical
+# added --unmount DIR|DEVICE
+# added --eject DIR|DEVICE
+# added --mount-all
+# added --mount DEVICE
+# added --info-on-mount
+# added pass options to udisks
+# better error msg from udisks
+# individual drive eject detection
+# no limit on number of optical drives
+# 0.8.2: more verbose errors
+# run as root changed to warning
+# 0.8.1: added --unmount-on-exit
+# adjusted start daemon trigger, timing
+# added 'do not run as root' catcher
+# added trap to ignore SIGHUP
+
diff --git a/opensuse/tdebase/dont-always-start-kaccess.diff b/opensuse/tdebase/dont-always-start-kaccess.diff
new file mode 100644
index 000000000..f50747274
--- /dev/null
+++ b/opensuse/tdebase/dont-always-start-kaccess.diff
@@ -0,0 +1,66 @@
+Index: kcontrol/access/kcmaccess.cpp
+===================================================================
+--- kcontrol/access/kcmaccess.cpp.orig
++++ kcontrol/access/kcmaccess.cpp
+@@ -103,10 +103,57 @@ void ExtendedIntNumInput::slotSliderValu
+
+ static bool needToRunKAccessDaemon( KConfig *config )
+ {
+- // We always start the KAccess Daemon, if it is not needed,
+- // it will terminate itself after configuring the AccessX
+- // features.
+- return true;
++ KConfigGroup bell( config, "Bell" );
++
++ if (!bell.readBoolEntry("SystemBell", true))
++ return true;
++ if (bell.readBoolEntry("ArtsBell", false))
++ return true;
++ if (bell.readBoolEntry("VisibleBell", false))
++ return true;
++
++ KConfigGroup keyboard( config, "Keyboard" );
++
++ if (keyboard.readBoolEntry("StickyKeys", false))
++ return true;
++ if (keyboard.readBoolEntry("SlowKeys", false))
++ return true;
++ if (keyboard.readBoolEntry("BounceKeys", false))
++ return true;
++ if (keyboard.readBoolEntry("Gestures", true))
++ return true;
++ // Find out whether the gestures are activated by default in the X configuration or not.
++ int major = XkbMajorVersion;
++ int minor = XkbMinorVersion;
++ if (XkbLibraryVersion(&major, &minor))
++ {
++ int opcode_rtrn;
++ int error_rtrn;
++ int xkb_opcode;
++ if (XkbQueryExtension(qt_xdisplay(), &opcode_rtrn, &xkb_opcode, &error_rtrn,
++ &major, &minor))
++ {
++ if(XkbDescPtr xkbdesc = XkbGetMap(qt_xdisplay(), 0, XkbUseCoreKbd))
++ {
++ if(XkbGetControls(qt_xdisplay(), XkbAllControlsMask/*XkbAccessXKeysMask*/, xkbdesc ) == Success )
++ {
++ if(xkbdesc->ctrls->enabled_ctrls & XkbAccessXKeysMask)
++ {
++ XkbFreeClientMap(xkbdesc,0,True);
++ return true;
++ }
++ }
++ XkbFreeClientMap(xkbdesc,0,True);
++ }
++ }
++ }
++
++ KConfigGroup mouse( config, "Mouse" );
++
++ if (mouse.readBoolEntry("MouseKeys", false))
++ return true;
++
++ return false; // don't need it
+ }
+
+ QString mouseKeysShortcut (Display *display) {
diff --git a/opensuse/tdebase/fileshareset.8.gz b/opensuse/tdebase/fileshareset.8.gz
new file mode 100644
index 000000000..c311d10b3
--- /dev/null
+++ b/opensuse/tdebase/fileshareset.8.gz
Binary files differ
diff --git a/opensuse/tdebase/fileshareset2.tar.bz2 b/opensuse/tdebase/fileshareset2.tar.bz2
new file mode 100644
index 000000000..5e26bb796
--- /dev/null
+++ b/opensuse/tdebase/fileshareset2.tar.bz2
Binary files differ
diff --git a/opensuse/tdebase/fix-desktop-icons.diff b/opensuse/tdebase/fix-desktop-icons.diff
new file mode 100644
index 000000000..27d83f685
--- /dev/null
+++ b/opensuse/tdebase/fix-desktop-icons.diff
@@ -0,0 +1,250 @@
+Index: kcontrol/componentchooser/componentchooser.desktop
+===================================================================
+--- kcontrol/componentchooser/componentchooser.desktop.orig
++++ kcontrol/componentchooser/componentchooser.desktop
+@@ -1,6 +1,6 @@
+ [Desktop Entry]
+ Exec=kcmshell componentchooser
+-Icon=misc
++Icon=kcmcomponentchooser
+ Type=Application
+
+
+Index: kcontrol/taskbar/kcmtaskbar.desktop
+===================================================================
+--- kcontrol/taskbar/kcmtaskbar.desktop.orig
++++ kcontrol/taskbar/kcmtaskbar.desktop
+@@ -1,5 +1,5 @@
+ [Desktop Entry]
+-Icon=kmenu
++Icon=kcmtaskbar
+ Type=Application
+ DocPath=kcontrol/kcmtaskbar/index.html
+ Exec=kcmshell kcmtaskbar
+Index: kcontrol/nics/nic.desktop
+===================================================================
+--- kcontrol/nics/nic.desktop.orig
++++ kcontrol/nics/nic.desktop
+@@ -2,7 +2,7 @@
+ Exec=kcmshell nic
+ Type=Application
+ DocPath=kinfocenter/nics/index.html
+-Icon=network
++Icon=kcmnic
+
+
+ X-KDE-Library=nic
+Index: kcontrol/input/mouse.desktop
+===================================================================
+--- kcontrol/input/mouse.desktop.orig
++++ kcontrol/input/mouse.desktop
+@@ -1,6 +1,6 @@
+ [Desktop Entry]
+ Exec=kcmshell mouse
+-Icon=mouse
++Icon=kcmmouse
+ Type=Application
+ DocPath=kcontrol/mouse/index.html
+
+Index: kcontrol/smserver/kcmsmserver.desktop
+===================================================================
+--- kcontrol/smserver/kcmsmserver.desktop.orig
++++ kcontrol/smserver/kcmsmserver.desktop
+@@ -1,5 +1,5 @@
+ [Desktop Entry]
+-Icon=exit
++Icon=kcmsmserver
+ Type=Application
+ DocPath=kcontrol/kcmsmserver/index.html
+ Exec=kcmshell kcmsmserver
+Index: kcontrol/kded/kcmkded.desktop
+===================================================================
+--- kcontrol/kded/kcmkded.desktop.orig
++++ kcontrol/kded/kcmkded.desktop
+@@ -1,6 +1,6 @@
+ [Desktop Entry]
+ Exec=kcmshell kcmkded
+-Icon=services
++Icon=kcmkded
+ Type=Application
+
+
+Index: kcontrol/konq/desktop.desktop
+===================================================================
+--- kcontrol/konq/desktop.desktop.orig
++++ kcontrol/konq/desktop.desktop
+@@ -1,7 +1,7 @@
+ [Desktop Entry]
+ Type=Application
+ DocPath=kcontrol/desktop/index.html#desktop-number
+-Icon=desktop
++Icon=kcmdesktop
+ Exec=kcmshell desktop
+
+
+Index: kcontrol/konq/desktopbehavior.desktop
+===================================================================
+--- kcontrol/konq/desktopbehavior.desktop.orig
++++ kcontrol/konq/desktopbehavior.desktop
+@@ -1,7 +1,7 @@
+ [Desktop Entry]
+ Type=Application
+ DocPath=kcontrol/desktopbehavior/index.html
+-Icon=desktop
++Icon=kcmdesktopbehavior
+ Exec=kcmshell desktopbehavior
+
+
+Index: kcontrol/privacy/privacy.desktop
+===================================================================
+--- kcontrol/privacy/privacy.desktop.orig
++++ kcontrol/privacy/privacy.desktop
+@@ -1,5 +1,5 @@
+ [Desktop Entry]
+-Icon=trashcan_empty
++Icon=kcmprivacy
+ Comment=Privacy - a kcontrol module to clean unwanted traces the user leaves on the system
+ Comment[af]=Privaatheid - 'n Beheer module wat voetspore wat deur gebruikers op die stelsel gelaat word skoon maak
+ Comment[ar]=الخصوصية - وحدة kcontrol لتنظيف الآثار غير المرغوب بها التي يتركها المستخدم على النظام
+Index: kcontrol/crypto/crypto.desktop
+===================================================================
+--- kcontrol/crypto/crypto.desktop.orig
++++ kcontrol/crypto/crypto.desktop
+@@ -1,5 +1,5 @@
+ [Desktop Entry]
+-Icon=encrypted
++Icon=kcmcrypto
+ Type=Application
+ Exec=kcmshell crypto
+ DocPath=kcontrol/crypto/index.html
+Index: kcontrol/kio/netpref.desktop
+===================================================================
+--- kcontrol/kio/netpref.desktop.orig
++++ kcontrol/kio/netpref.desktop
+@@ -76,7 +76,7 @@ Comment[zh_CN]=配置通用网络首选
+ Comment[zh_TW]=設定一般網路喜好設定,例如逾時值
+ Comment[zu]=Hlanganisela okuncanyelwa uwonkewonke koxhumano olusazekile, njengamanani esikhathi sokuphuma
+ Exec=kcmshell netpref
+-Icon=network
++Icon=kcmnetpref
+ Keywords=timeout,iopref,netpref,network preferences,ftp
+ Keywords[be]=Тэрмін чакання,Уласцівасці сеткі,timeout,iopref,netpref,network preferences,ftp
+ Keywords[bg]=просрочка, време, времето, пауза, прекъсване, връзка, timeout, iopref, netpref, network preferences, ftp
+Index: kcontrol/konqhtml/khtml_filter.desktop
+===================================================================
+--- kcontrol/konqhtml/khtml_filter.desktop.orig
++++ kcontrol/konqhtml/khtml_filter.desktop
+@@ -1,7 +1,7 @@
+ [Desktop Entry]
+ Type=Application
+ DocPath=kcontrol/khtml/index.html#khtml-adblock
+-Icon=filter
++Icon=kcmkhtml_filter
+ Exec=kcmshell khtml_filter
+
+ X-KDE-Library=konqhtml
+Index: kcontrol/joystick/joystick.desktop
+===================================================================
+--- kcontrol/joystick/joystick.desktop.orig
++++ kcontrol/joystick/joystick.desktop
+@@ -173,5 +173,5 @@ Type=Application
+ X-KDE-FactoryName=kcm_joystick
+ X-KDE-Library=joystick
+ X-KDE-Test-Module=true
+-Icon=joystick
++Icon=kcmjoystick
+ Categories=Qt;KDE;X-KDE-settings-hardware;
+Index: kcontrol/colors/colors.desktop
+===================================================================
+--- kcontrol/colors/colors.desktop.orig
++++ kcontrol/colors/colors.desktop
+@@ -1,6 +1,6 @@
+ [Desktop Entry]
+ Exec=kcmshell colors
+-Icon=colorscm
++Icon=kcmcolors
+ Type=Application
+ DocPath=kcontrol/colors/index.html
+
+Index: kcontrol/performance/kcmperformance.desktop
+===================================================================
+--- kcontrol/performance/kcmperformance.desktop.orig
++++ kcontrol/performance/kcmperformance.desktop
+@@ -1,5 +1,5 @@
+ [Desktop Entry]
+-Icon=launch
++Icon=kcmperformance
+ Type=Application
+ Exec=kcmshell kcmperformance
+
+Index: kcontrol/launch/kcmlaunch.desktop
+===================================================================
+--- kcontrol/launch/kcmlaunch.desktop.orig
++++ kcontrol/launch/kcmlaunch.desktop
+@@ -1,5 +1,5 @@
+ [Desktop Entry]
+-Icon=launch
++Icon=kcmlaunch
+ Type=Application
+ DocPath=kcontrol/kcmlaunch/index.html
+ Exec=kcmshell kcmlaunch
+Index: kcontrol/dnssd/kcm_kdnssd.desktop
+===================================================================
+--- kcontrol/dnssd/kcm_kdnssd.desktop.orig
++++ kcontrol/dnssd/kcm_kdnssd.desktop
+@@ -70,7 +70,7 @@ Comment[zh_TW]=設定服務偵測
+ Exec=kcmshell kcm_kdnssd
+ GenericName=
+ GenericName[ko]=일반
+-Icon=blockdevice
++Icon=kcmkdnssd
+ MimeType=
+ Name=Service Discovery
+ Name[af]=Dienste ontdekker
+Index: kcontrol/spellchecking/spellchecking.desktop
+===================================================================
+--- kcontrol/spellchecking/spellchecking.desktop.orig
++++ kcontrol/spellchecking/spellchecking.desktop
+@@ -1,6 +1,6 @@
+ [Desktop Entry]
+ Exec=kcmshell spellchecking
+-Icon=spellcheck
++Icon=kcmspellchecking
+ Type=Application
+ DocPath=kcontrol/spellchecking/index.html
+
+Index: konqueror/sidebar/trees/history_module/kcmhistory.desktop
+===================================================================
+--- konqueror/sidebar/trees/history_module/kcmhistory.desktop.orig
++++ konqueror/sidebar/trees/history_module/kcmhistory.desktop
+@@ -1,5 +1,5 @@
+ [Desktop Entry]
+-Icon=history
++Icon=kcmhistory
+ Type=Application
+ Exec=kcmshell kcmhistory
+
+Index: kioslave/cgi/kcmcgi/kcmcgi.desktop
+===================================================================
+--- kioslave/cgi/kcmcgi/kcmcgi.desktop.orig
++++ kioslave/cgi/kcmcgi/kcmcgi.desktop
+@@ -1,5 +1,5 @@
+ [Desktop Entry]
+-Icon=run
++Icon=kcmcgi
+ Type=Application
+ Exec=kcmshell kcmcgi
+ DocPath=
+Index: kioslave/media/kcmodule/media.desktop
+===================================================================
+--- kioslave/media/kcmodule/media.desktop.orig
++++ kioslave/media/kcmodule/media.desktop
+@@ -1,7 +1,7 @@
+ [Desktop Entry]
+ Type=Application
+ #DocPath=
+-Icon=system
++Icon=kcmmedia
+ Exec=kcmshell media
+
+
diff --git a/opensuse/tdebase/fix-kcontrol-yast.diff b/opensuse/tdebase/fix-kcontrol-yast.diff
new file mode 100644
index 000000000..5902d904d
--- /dev/null
+++ b/opensuse/tdebase/fix-kcontrol-yast.diff
@@ -0,0 +1,63 @@
+Index: kcontrol/kcontrol/modules.cpp
+===================================================================
+--- kcontrol/kcontrol/modules.cpp.orig
++++ kcontrol/kcontrol/modules.cpp
+@@ -19,6 +19,7 @@
+
+ #include <unistd.h>
+ #include <sys/types.h>
++#include <stdlib.h>
+
+
+ #include <qlabel.h>
+@@ -59,6 +60,10 @@ ConfigModule::~ConfigModule()
+
+ ProxyWidget *ConfigModule::module()
+ {
++ KDesktopFile kd(service()->desktopEntryPath());
++ if ( !kd.readEntry("X-SuSE-YaST-Call").isEmpty() )
++ setenv("KCMYAST2_CALL", kd.readEntry("X-SuSE-YaST-Call").latin1(), 1 );
++
+ if (_module)
+ return _module;
+
+@@ -168,6 +173,7 @@ void ConfigModule::runAsRoot()
+ // prepare the process to run the kcmshell
+ QString cmd = service()->exec().stripWhiteSpace();
+ bool kdeshell = false;
++ bool proxy = false;
+ if (cmd.left(5) == "kdesu")
+ {
+ cmd = cmd.remove(0,5).stripWhiteSpace();
+@@ -185,6 +191,15 @@ void ConfigModule::runAsRoot()
+ kdeshell = true;
+ }
+
++ KDesktopFile kd(service()->desktopEntryPath());
++ if ( !kd.readEntry("X-SuSE-YaST-Call").isEmpty() ){
++ kdeshell = true;
++ proxy = true;
++ cmd=service()->desktopEntryPath();
++
++ setenv("KCMYAST2_CALL", kd.readEntry("X-SuSE-YaST-Call").latin1(), 1 );
++ }
++
+ // run the process
+ QString kdesu = KStandardDirs::findExe("kdesu");
+ if (!kdesu.isEmpty())
+@@ -196,12 +211,12 @@ void ConfigModule::runAsRoot()
+ // in that case the modules is started through kdesud and kdesu
+ // returns before the module is running and that doesn't work.
+ // We also don't have a way to close the module in that case.
+- *_rootProcess << "--n"; // Don't keep password.
++ *_rootProcess << "--n" << "-t"; // Don't keep password.
+ if (kdeshell) {
+- *_rootProcess << QString("%1 %2 --embed %3 --lang %4").arg(locate("exe", "kcmshell")).arg(cmd).arg(_embedWidget->winId()).arg(KGlobal::locale()->language());
++ *_rootProcess << QString("%1 %2 %3 %4 --lang %5").arg(locate("exe", "kcmshell")).arg(cmd).arg(proxy?"--embed-proxy":"--embed").arg(_embedWidget->winId()).arg(KGlobal::locale()->language());
+ }
+ else {
+- *_rootProcess << QString("%1 --embed %2 --lang %3").arg(cmd).arg(_embedWidget->winId()).arg( KGlobal::locale()->language() );
++ *_rootProcess << QString("%1 %2 %3 --lang %4").arg(cmd).arg(proxy?"--embed-proxy":"--embed").arg(_embedWidget->winId()).arg( KGlobal::locale()->language() );
+ }
+
+ connect(_rootProcess, SIGNAL(processExited(KProcess*)), this, SLOT(rootExited(KProcess*)));
diff --git a/opensuse/tdebase/fix-kio-smb-auth.diff b/opensuse/tdebase/fix-kio-smb-auth.diff
new file mode 100644
index 000000000..d591be038
--- /dev/null
+++ b/opensuse/tdebase/fix-kio-smb-auth.diff
@@ -0,0 +1,13 @@
+? kioslave/smb/kio_smb_la_all_cpp.cpp
+Index: kioslave/smb/kio_smb_auth.cpp
+===================================================================
+--- kioslave/smb/kio_smb_auth.cpp.orig
++++ kioslave/smb/kio_smb_auth.cpp
+@@ -144,6 +144,7 @@ bool SMBSlave::checkPassword(SMBUrl &url
+ if ( openPassDlg(info) ) {
+ kdDebug(KIO_SMB) << "openPassDlg returned " << info.username << endl;
+ url.setUser(info.username);
++ url.setPass(info.password);
+ return true;
+ }
+ kdDebug(KIO_SMB) << "no value from openPassDlg\n";
diff --git a/opensuse/tdebase/fix-lockup-from-gnome-apps.diff b/opensuse/tdebase/fix-lockup-from-gnome-apps.diff
new file mode 100644
index 000000000..05fc4313b
--- /dev/null
+++ b/opensuse/tdebase/fix-lockup-from-gnome-apps.diff
@@ -0,0 +1,20 @@
+Index: khelpcenter/navigator.cpp
+===================================================================
+--- khelpcenter/navigator.cpp.orig
++++ khelpcenter/navigator.cpp
+@@ -333,9 +333,14 @@ void Navigator::selectItem( const KURL &
+ // First, populate the NavigatorAppItems if we don't want the home page
+ if ( url != homeURL() ) {
+ for ( QListViewItem *item = mContentsTree->firstChild(); item;
+- item = item->nextSibling() ) {
++ item = item->nextSibling() ) {
+ NavigatorAppItem *appItem = dynamic_cast<NavigatorAppItem *>( item );
+ if ( appItem ) appItem->populate( true /* recursive */ );
++ for ( QListViewItem *subitem = item->firstChild(); subitem;
++ subitem = subitem->nextSibling() ) {
++ appItem = dynamic_cast<NavigatorAppItem *>( subitem );
++ if ( appItem ) appItem->populate( true /* recursive */ );
++ }
+ }
+ }
+
diff --git a/opensuse/tdebase/fix_default_theme_reset.diff b/opensuse/tdebase/fix_default_theme_reset.diff
new file mode 100644
index 000000000..2b2a6805a
--- /dev/null
+++ b/opensuse/tdebase/fix_default_theme_reset.diff
@@ -0,0 +1,59 @@
+Index: kcontrol/kthememanager/ktheme.cpp
+===================================================================
+--- kcontrol/kthememanager/ktheme.cpp.orig
++++ kcontrol/kthememanager/ktheme.cpp
+@@ -188,11 +188,11 @@ QString KTheme::createYourself( bool pac
+ globalConf->setGroup( "Icons" );
+ QDomElement iconElem = m_dom.createElement( "icons" );
+ iconElem.setAttribute( "name", globalConf->readEntry( "Theme",KIconTheme::current() ) );
+- createIconElems( "DesktopIcons", "desktop", iconElem, globalConf );
+- createIconElems( "MainToolbarIcons", "mainToolbar", iconElem, globalConf );
+- createIconElems( "PanelIcons", "panel", iconElem, globalConf );
+- createIconElems( "SmallIcons", "small", iconElem, globalConf );
+- createIconElems( "ToolbarIcons", "toolbar", iconElem, globalConf );
++ createIconElems( "DesktopIcons", "desktop", 32, iconElem, globalConf );
++ createIconElems( "MainToolbarIcons", "mainToolbar", 22, iconElem, globalConf );
++ createIconElems( "PanelIcons", "panel", 32, iconElem, globalConf );
++ createIconElems( "SmallIcons", "small", 16, iconElem, globalConf );
++ createIconElems( "ToolbarIcons", "toolbar", 22, iconElem, globalConf );
+ m_root.appendChild( iconElem );
+
+ // 4. Sounds
+@@ -726,7 +726,7 @@ QString KTheme::getProperty( QDomElement
+ }
+
+ void KTheme::createIconElems( const QString & group, const QString & object,
+- QDomElement parent, KConfig * cfg )
++ int defsize, QDomElement parent, KConfig * cfg )
+ {
+ cfg->setGroup( group );
+ QStringList elemNames;
+@@ -745,7 +745,9 @@ void KTheme::createIconElems( const QStr
+ QDomElement tmpCol = m_dom.createElement( *it );
+ tmpCol.setAttribute( "object", object );
+
+- if ( (*it).contains( "Value" ) || *it == "Size" )
++ if ( *it == "Size" )
++ tmpCol.setAttribute( "value", cfg->readNumEntry( *it, defsize ) );
++ else if ( (*it).contains( "Value" ))
+ tmpCol.setAttribute( "value", cfg->readNumEntry( *it, 1 ) );
+ else if ( (*it).contains( "DisabledEffect" ) )
+ tmpCol.setAttribute( "name", cfg->readEntry( *it, "togray" ) );
+Index: kcontrol/kthememanager/ktheme.h
+===================================================================
+--- kcontrol/kthememanager/ktheme.h.orig
++++ kcontrol/kthememanager/ktheme.h
+@@ -155,11 +155,12 @@ private:
+ * Creates a list of "icon" elements based on:
+ * @param group The group in the KConfig object @p cfg
+ * @param object Specifier (similiar, but not identical to @p group)
++ * @param defsize default icon size
+ * @param parent Parent element to append to
+ * @param cfg The KConfig object to work with
+ */
+ void createIconElems( const QString & group, const QString & object,
+- QDomElement parent, KConfig * cfg );
++ int defsize, QDomElement parent, KConfig * cfg );
+
+ /**
+ * Creates a color DOM element @p name, with a specifier @p object,
diff --git a/opensuse/tdebase/gcc44.diff b/opensuse/tdebase/gcc44.diff
new file mode 100644
index 000000000..999b5f3ca
--- /dev/null
+++ b/opensuse/tdebase/gcc44.diff
@@ -0,0 +1,20 @@
+--- kcontrol/kfontinst/kfontinst/Fontmap.cpp.sav 2006-01-19 18:00:49.000000000 +0100
++++ kcontrol/kfontinst/kfontinst/Fontmap.cpp 2009-05-29 14:50:08.000000000 +0200
+@@ -44,7 +44,7 @@
+
+ using namespace std;
+
+-static char * findSpace(char *str)
++static const char * findSpace(const char *str)
+ {
+ while(str && *str!=' ' && *str!='\t')
+ str++;
+@@ -65,7 +65,7 @@ static bool parseLine(const char *line,
+ char a[constMaxLen+1],
+ b[constFileMaxLen+1];
+
+- char *slash1=strchr(line, '/'),
++ const char *slash1=strchr(line, '/'),
+ *space1=slash1 ? findSpace(slash1) : NULL, //strchr(slash1, ' ') : NULL,
+ *ob=slash1 ? strchr(slash1, '(') : NULL,
+ *cb=ob ? strchr(ob, ')') : NULL,
diff --git a/opensuse/tdebase/hide-only-showin-entries.diff b/opensuse/tdebase/hide-only-showin-entries.diff
new file mode 100644
index 000000000..f403d38c5
--- /dev/null
+++ b/opensuse/tdebase/hide-only-showin-entries.diff
@@ -0,0 +1,14 @@
+Index: konqueror/konq_mainwindow.cc
+===================================================================
+--- konqueror/konq_mainwindow.cc.orig
++++ konqueror/konq_mainwindow.cc
+@@ -4926,6 +4926,9 @@ void KonqMainWindow::updateOpenWithActio
+ KTrader::OfferList::ConstIterator end = services.end();
+ for (; it != end; ++it )
+ {
++ if ( (*it)->noDisplay() )
++ continue;
++
+ KAction *action = new KAction( i18n( "Open with %1" ).arg( (*it)->name() ), 0, 0, (*it)->desktopEntryName().latin1() );
+ action->setIcon( (*it)->icon() );
+
diff --git a/opensuse/tdebase/improve-panelservicemenu-geticonset.diff b/opensuse/tdebase/improve-panelservicemenu-geticonset.diff
new file mode 100644
index 000000000..842976d5a
--- /dev/null
+++ b/opensuse/tdebase/improve-panelservicemenu-geticonset.diff
@@ -0,0 +1,32 @@
+Index: kicker/libkicker/global.cpp
+===================================================================
+--- kicker/libkicker/global.cpp.orig
++++ kicker/libkicker/global.cpp
+@@ -425,6 +425,12 @@ QIconSet menuIconSet(const QString& icon
+ KIcon::ActiveState,
+ 0,
+ true);
++ QPixmap disabled = KGlobal::iconLoader()->loadIcon(icon,
++ KIcon::Small,
++ 0,
++ KIcon::DisabledState,
++ 0,
++ true);
+
+ // make sure they are not larger than 20x20
+ if (normal.width() > 20 || normal.height() > 20)
+@@ -437,8 +443,14 @@ QIconSet menuIconSet(const QString& icon
+ active.convertFromImage(active.convertToImage().smoothScale(20,20));
+ }
+
++ if (disabled.width() > 20 || disabled.height() > 20)
++ {
++ disabled.convertFromImage(disabled.convertToImage().smoothScale(20,20));
++ }
++
+ iconset.setPixmap(normal, QIconSet::Small, QIconSet::Normal);
+ iconset.setPixmap(active, QIconSet::Small, QIconSet::Active);
++ iconset.setPixmap(disabled, QIconSet::Small, QIconSet::Disabled);
+ }
+ }
+
diff --git a/opensuse/tdebase/ioslaveinfo-icon.diff b/opensuse/tdebase/ioslaveinfo-icon.diff
new file mode 100644
index 000000000..5f64f89d9
--- /dev/null
+++ b/opensuse/tdebase/ioslaveinfo-icon.diff
@@ -0,0 +1,13 @@
+Index: kcontrol/ioslaveinfo/ioslaveinfo.desktop
+===================================================================
+--- kcontrol/ioslaveinfo/ioslaveinfo.desktop.orig
++++ kcontrol/ioslaveinfo/ioslaveinfo.desktop
+@@ -79,7 +79,7 @@ Comment[zh_TW]=可用協定的資訊
+ Comment[zu]=Ulwazi mayelana nemithetho elandelwayo ekhona
+ DocPath=kinfocenter/protocols/index.html
+ Exec=kcmshell ioslaveinfo
+-Icon=history
++Icon=enhanced_browsing
+ Keywords=Protocol,IO slaves,Slaves,Network,Information,Timeout
+ Keywords[ar]=الميفاق,IO Slaves,Slaves,الشبكة,معلومات نفاذ الوقت
+ Keywords[az]=Protokol, IO Kölələri, Kölələr, Şəbəkə,Mə'lumat, Vaxt Dolması
diff --git a/opensuse/tdebase/kcheckpass-pam-11.0 b/opensuse/tdebase/kcheckpass-pam-11.0
new file mode 100644
index 000000000..eae973612
--- /dev/null
+++ b/opensuse/tdebase/kcheckpass-pam-11.0
@@ -0,0 +1,6 @@
+#%PAM-1.0
+auth include common-auth
+account include common-account
+password include common-password
+session include common-session
+session required pam_resmgr.so
diff --git a/opensuse/tdebase/kcheckpass-pam-11.1 b/opensuse/tdebase/kcheckpass-pam-11.1
new file mode 100644
index 000000000..c6a7c9c90
--- /dev/null
+++ b/opensuse/tdebase/kcheckpass-pam-11.1
@@ -0,0 +1,5 @@
+#%PAM-1.0
+auth include common-auth
+account include common-account
+password include common-password
+session include common-session
diff --git a/opensuse/tdebase/kcheckpass-pam-legacy b/opensuse/tdebase/kcheckpass-pam-legacy
new file mode 100644
index 000000000..87df34589
--- /dev/null
+++ b/opensuse/tdebase/kcheckpass-pam-legacy
@@ -0,0 +1,7 @@
+#%PAM-1.0
+auth include common-auth
+account include common-account
+password include common-password
+session include common-session
+session required pam_devperm.so
+session required pam_resmgr.so
diff --git a/opensuse/tdebase/kcheckpass.8.gz b/opensuse/tdebase/kcheckpass.8.gz
new file mode 100644
index 000000000..81f8aae2a
--- /dev/null
+++ b/opensuse/tdebase/kcheckpass.8.gz
Binary files differ
diff --git a/opensuse/tdebase/kcminit-ignore-arts.diff b/opensuse/tdebase/kcminit-ignore-arts.diff
new file mode 100644
index 000000000..2c987aae1
--- /dev/null
+++ b/opensuse/tdebase/kcminit-ignore-arts.diff
@@ -0,0 +1,14 @@
+Index: kcminit/main.cpp
+===================================================================
+--- kcminit/main.cpp.orig
++++ kcminit/main.cpp
+@@ -98,6 +98,9 @@ void KCMInit::runModules( int phase )
+ if (library.isEmpty())
+ library = service->library();
+
++ if (library == "arts" && list.size() > 1)
++ continue;
++
+ if (library.isEmpty() || service->init().isEmpty())
+ continue; // Skip
+
diff --git a/opensuse/tdebase/kcmkdm-default-grub.diff b/opensuse/tdebase/kcmkdm-default-grub.diff
new file mode 100644
index 000000000..1d758eb57
--- /dev/null
+++ b/opensuse/tdebase/kcmkdm-default-grub.diff
@@ -0,0 +1,13 @@
+Index: kcontrol/kdm/kdm-shut.cpp
+===================================================================
+--- kcontrol/kdm/kdm-shut.cpp.orig
++++ kcontrol/kdm/kdm-shut.cpp
+@@ -90,7 +90,7 @@ KDMSessionsWidget::KDMSessionsWidget(QWi
+ QGroupBox *group4 = new QGroupBox( i18n("Miscellaneous"), this );
+
+ bm_combo = new KBackedComboBox( group4 );
+- bm_combo->insertItem("None", i18n("boot manager", "None"));
++ bm_combo->insertItem("None", i18n("boot manager", "Grub"));
+ bm_combo->insertItem("Grub", i18n("Grub"));
+ #if defined(__linux__) && ( defined(__i386__) || defined(__amd64__) )
+ bm_combo->insertItem("Lilo", i18n("Lilo"));
diff --git a/opensuse/tdebase/kcmsamba_log.diff b/opensuse/tdebase/kcmsamba_log.diff
new file mode 100644
index 000000000..e29ca1e13
--- /dev/null
+++ b/opensuse/tdebase/kcmsamba_log.diff
@@ -0,0 +1,31 @@
+Index: kcontrol/samba/kcmsambalog.cpp
+===================================================================
+--- kcontrol/samba/kcmsambalog.cpp.orig
++++ kcontrol/samba/kcmsambalog.cpp
+@@ -39,7 +39,7 @@ LogView::LogView(QWidget *parent,KConfig
+ ,configFile(config)
+ ,filesCount(0)
+ ,connectionsCount(0)
+-,logFileName("/var/log/samba.log",this)
++,logFileName("/var/log/samba/log.smbd",this)
+ ,label(&logFileName,i18n("Samba log file: "),this)
+ ,viewHistory(this)
+ ,showConnOpen(i18n("Show opened connections"),this)
+@@ -88,7 +88,7 @@ LogView::LogView(QWidget *parent,KConfig
+ " on this page. The log file (shown above) will be read to obtain the"
+ " events logged by samba.") );
+
+- logFileName.setURL("/var/log/samba.log");
++ logFileName.setURL("/var/log/samba/log.smbd");
+
+ viewHistory.setAllColumnsShowFocus(TRUE);
+ viewHistory.setFocusPolicy(QWidget::ClickFocus);
+@@ -130,7 +130,7 @@ void LogView::loadSettings()
+ {
+ if (configFile==0) return;
+ configFile->setGroup(LOGGROUPNAME);
+- logFileName.setURL(configFile->readPathEntry( "SambaLogFile", "/var/log/samba.log"));
++ logFileName.setURL(configFile->readPathEntry( "SambaLogFile", "/var/log/samba/log.smbd"));
+
+ showConnOpen.setChecked(configFile->readBoolEntry( "ShowConnectionOpen", TRUE));
+ showConnClose.setChecked(configFile->readBoolEntry( "ShowConnectionClose", FALSE));
diff --git a/opensuse/tdebase/kcmshell_use_kde-sound.diff b/opensuse/tdebase/kcmshell_use_kde-sound.diff
new file mode 100644
index 000000000..ac6d434e4
--- /dev/null
+++ b/opensuse/tdebase/kcmshell_use_kde-sound.diff
@@ -0,0 +1,11 @@
+Index: kcontrol/info/sound.desktop
+===================================================================
+--- kcontrol/info/sound.desktop.orig
++++ kcontrol/info/sound.desktop
+@@ -1,5 +1,5 @@
+ [Desktop Entry]
+-Exec=kcmshell sound
++Exec=kcmshell kde-sound
+ Icon=kcmsound
+ Type=Application
+ DocPath=kinfocenter/sound/index.html
diff --git a/opensuse/tdebase/kcontrol-energy.diff b/opensuse/tdebase/kcontrol-energy.diff
new file mode 100644
index 000000000..b98a648bc
--- /dev/null
+++ b/opensuse/tdebase/kcontrol-energy.diff
@@ -0,0 +1,167 @@
+Index: kcontrol/energy/energy.h
+===================================================================
+--- kcontrol/energy/energy.h.orig
++++ kcontrol/energy/energy.h
+@@ -44,6 +44,7 @@ private slots:
+ void slotChangeStandby(int);
+ void slotChangeSuspend(int);
+ void slotChangeOff(int);
++ void slotLaunchKPowersave();
+ void openURL(const QString &);
+
+ private:
+@@ -54,7 +55,7 @@ private:
+ static void applySettings(bool, int, int, int);
+ friend void init_energy();
+
+- bool m_bChanged, m_bDPMS, m_bEnabled, m_bMaintainSanity;
++ bool m_bChanged, m_bDPMS, m_bKPowersave, m_bEnabled, m_bMaintainSanity;
+ int m_Standby, m_Suspend, m_Off;
+ int m_StandbyDesired, m_SuspendDesired, m_OffDesired;
+
+Index: kcontrol/energy/energy.cpp
+===================================================================
+--- kcontrol/energy/energy.cpp.orig
++++ kcontrol/energy/energy.cpp
+@@ -26,6 +26,7 @@
+ #include <qlabel.h>
+ #include <qlayout.h>
+ #include <qwhatsthis.h>
++#include <qpushbutton.h>
+
+ #include <kconfig.h>
+ #include <kcursor.h>
+@@ -36,6 +37,7 @@
+ #include <krun.h>
+ #include <kstandarddirs.h>
+ #include <kurllabel.h>
++#include <dcopref.h>
+
+ #include <X11/X.h>
+ #include <X11/Xlib.h>
+@@ -140,6 +142,7 @@ KEnergy::KEnergy(QWidget *parent, const
+ m_Suspend = DFLT_SUSPEND;
+ m_Off = DFLT_OFF;
+ m_bDPMS = false;
++ m_bKPowersave = false;
+ m_bMaintainSanity = true;
+
+ setQuickHelp( i18n("<h1>Display Power Control</h1> If your display supports"
+@@ -154,6 +157,13 @@ KEnergy::KEnergy(QWidget *parent, const
+ #ifdef HAVE_DPMS
+ int dummy;
+ m_bDPMS = DPMSQueryExtension(qt_xdisplay(), &dummy, &dummy);
++
++ DCOPRef kpowersave("kpowersave", "KPowersaveIface");
++ DCOPReply managingDPMS = kpowersave.call("currentSchemeManagesDPMS()");
++ if (managingDPMS.isValid()) {
++ m_bKPowersave = managingDPMS;
++ m_bDPMS = !m_bKPowersave;
++ }
+ #endif
+
+ QVBoxLayout *top = new QVBoxLayout(this, 0, KDialog::spacingHint());
+@@ -162,14 +172,26 @@ KEnergy::KEnergy(QWidget *parent, const
+
+ QLabel *lbl;
+ if (m_bDPMS) {
+- m_pCBEnable= new QCheckBox(i18n("&Enable display power management" ), this);
+- connect(m_pCBEnable, SIGNAL(toggled(bool)), SLOT(slotChangeEnable(bool)));
+- hbox->addWidget(m_pCBEnable);
++ KGlobal::locale()->insertCatalogue("kpowersave");
++
++ // ### these i18n strings need to be synced with kpowersave !!
++ m_pCBEnable= new QCheckBox(i18n("&Enable display power management" ), this);
++ connect(m_pCBEnable, SIGNAL(toggled(bool)), SLOT(slotChangeEnable(bool)));
++ hbox->addWidget(m_pCBEnable);
+ QWhatsThis::add( m_pCBEnable, i18n("Check this option to enable the"
+- " power saving features of your display.") );
+- } else {
++ " power saving features of your display.") );
++
++ // ###
++ } else if(m_bKPowersave) {
++ m_pCBEnable = new QCheckBox(i18n("&Enable specific display power management"), this);
++ hbox->addWidget(m_pCBEnable);
++ m_bEnabled = false;
++ m_pCBEnable->setChecked(true);
++ m_pCBEnable->setEnabled(false);
++
++ } else {
+ lbl = new QLabel(i18n("Your display does not support power saving."), this);
+- hbox->addWidget(lbl);
++ hbox->addWidget(lbl);
+ }
+
+ KURLLabel *logo = new KURLLabel(this);
+@@ -183,6 +205,7 @@ connect(logo, SIGNAL(leftClickedURL(cons
+ hbox->addWidget(logo);
+
+ // Sliders
++ if (!m_bKPowersave) {
+ m_pStandbySlider = new KIntNumInput(m_Standby, this);
+ m_pStandbySlider->setLabel(i18n("&Standby after:"));
+ m_pStandbySlider->setRange(0, 120, 10);
+@@ -218,6 +241,17 @@ connect(logo, SIGNAL(leftClickedURL(cons
+ " greatest level of power saving that can be achieved while the"
+ " display is still physically turned on.") );
+
++ }
++ else {
++ m_pStandbySlider = 0;
++ m_pSuspendSlider = 0;
++ m_pOffSlider = 0;
++ QPushButton* btnKPowersave = new QPushButton(this);
++ btnKPowersave->setText(i18n("Configure KPowersave..."));
++ connect(btnKPowersave, SIGNAL(clicked()), SLOT(slotLaunchKPowersave()));
++ top->addWidget(btnKPowersave);
++ }
++
+ top->addStretch();
+
+ if (m_bDPMS)
+@@ -270,7 +304,8 @@ void KEnergy::defaults()
+
+ void KEnergy::readSettings()
+ {
+- m_bEnabled = m_pConfig->readBoolEntry("displayEnergySaving", false);
++ if (m_bDPMS)
++ m_bEnabled = m_pConfig->readBoolEntry("displayEnergySaving", false);
+ m_Standby = m_pConfig->readNumEntry("displayStandby", DFLT_STANDBY);
+ m_Suspend = m_pConfig->readNumEntry("displaySuspend", DFLT_SUSPEND);
+ m_Off = m_pConfig->readNumEntry("displayPowerOff", DFLT_OFF);
+@@ -297,20 +332,27 @@ void KEnergy::writeSettings()
+ m_bChanged = false;
+ }
+
++void KEnergy::slotLaunchKPowersave()
++{
++ DCOPRef r("kpowersave", "KPowersaveIface");
++ r.send("openConfigureDialog()");
++}
+
+ void KEnergy::showSettings()
+ {
+ m_bMaintainSanity = false;
+
+ if (m_bDPMS)
+- m_pCBEnable->setChecked(m_bEnabled);
++ m_pCBEnable->setChecked(m_bEnabled);
+
+- m_pStandbySlider->setEnabled(m_bEnabled);
+- m_pStandbySlider->setValue(m_Standby);
+- m_pSuspendSlider->setEnabled(m_bEnabled);
+- m_pSuspendSlider->setValue(m_Suspend);
+- m_pOffSlider->setEnabled(m_bEnabled);
+- m_pOffSlider->setValue(m_Off);
++ if (!m_bKPowersave) {
++ m_pStandbySlider->setEnabled(m_bEnabled);
++ m_pStandbySlider->setValue(m_Standby);
++ m_pSuspendSlider->setEnabled(m_bEnabled);
++ m_pSuspendSlider->setValue(m_Suspend);
++ m_pOffSlider->setEnabled(m_bEnabled);
++ m_pOffSlider->setValue(m_Off);
++ }
+
+ m_bMaintainSanity = true;
+ }
diff --git a/opensuse/tdebase/kcontrol.diff b/opensuse/tdebase/kcontrol.diff
new file mode 100644
index 000000000..ab23e34ba
--- /dev/null
+++ b/opensuse/tdebase/kcontrol.diff
@@ -0,0 +1,11 @@
+Index: kcontrol/kcontrol/KControl.desktop
+===================================================================
+--- kcontrol/kcontrol/KControl.desktop.orig
++++ kcontrol/kcontrol/KControl.desktop
+@@ -1,4 +1,6 @@
+ [Desktop Entry]
++Categories=Qt;KDE;X-SuSE-core
++OnlyShowIn=KDE;
+ Exec=kcontrol -caption "%c" %i %m
+ Icon=kcontrol
+ Type=Application
diff --git a/opensuse/tdebase/kde3-session-restore.diff b/opensuse/tdebase/kde3-session-restore.diff
new file mode 100644
index 000000000..6ade7063b
--- /dev/null
+++ b/opensuse/tdebase/kde3-session-restore.diff
@@ -0,0 +1,12 @@
+Index: kde3
+===================================================================
+--- kde3.orig
++++ kde3
+@@ -6,4 +6,7 @@
+ # and make sure this script is in $PATH (e.g. make a symlink if necessary).
+ #
+
++PATH=/opt/kde3/bin:${PATH/:\/opt\/kde3\/bin}
++export PATH
++
+ exec "$@"
diff --git a/opensuse/tdebase/kde3-session.diff b/opensuse/tdebase/kde3-session.diff
new file mode 100644
index 000000000..763879088
--- /dev/null
+++ b/opensuse/tdebase/kde3-session.diff
@@ -0,0 +1,13 @@
+Index: kdm/kfrontend/sessions/kde.desktop.in
+===================================================================
+--- kdm/kfrontend/sessions/kde.desktop.in.orig
++++ kdm/kfrontend/sessions/kde.desktop.in
+@@ -3,7 +3,7 @@ Encoding=UTF-8
+ Type=XSession
+ Exec=@KDE_BINDIR@/startkde
+ TryExec=@KDE_BINDIR@/startkde
+-Name=KDE
++Name=KDE3
+ Name[hi]=केडीई
+ Name[mn]=КДЭ
+ Name[ta]=Kஏற்றக் காவலன்
diff --git a/opensuse/tdebase/kdebase_khc_rellinks.diff b/opensuse/tdebase/kdebase_khc_rellinks.diff
new file mode 100644
index 000000000..e11269095
--- /dev/null
+++ b/opensuse/tdebase/kdebase_khc_rellinks.diff
@@ -0,0 +1,606 @@
+Index: khelpcenter/khelpcenterui.rc
+===================================================================
+--- khelpcenter/khelpcenterui.rc.orig
++++ khelpcenter/khelpcenterui.rc
+@@ -1,5 +1,5 @@
+ <!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+-<kpartgui name="khelpcenter" version="14">
++<kpartgui name="khelpcenter" version="15">
+ <MenuBar>
+ <Menu name="file" noMerge="1">
+ <text>&amp;File</text>
+@@ -23,8 +23,8 @@
+ </Menu>
+ <Menu name="go_web">
+ <text>&amp;Go</text>
+- <Action name="prevPage" />
+- <Action name="nextPage" />
++ <Action name="rellinks_previous" />
++ <Action name="rellinks_next" />
+ <Separator />
+ <Action name="back" />
+ <Action name="forward" />
+@@ -41,13 +41,19 @@
+ <Action name="go_home" />
+ <Action name="back" />
+ <Action name="forward" />
+- <Separator />
++ <Separator />
+ <Action name="printFrame" />
+ <Separator />
+ <Action name="copy_text" />
+ <Action name="find" />
+- <Separator />
+ <Action name="incFontSizes" />
+ <Action name="decFontSizes" />
++ <Separator />
++ <Action name="rellinks_top" />
++ <Action name="rellinks_up" />
++ <Action name="rellinks_first" />
++ <Action name="rellinks_previous" />
++ <Action name="rellinks_next" />
++ <Action name="rellinks_last" />
+ </ToolBar>
+ </kpartgui>
+Index: khelpcenter/mainwindow.cpp
+===================================================================
+--- khelpcenter/mainwindow.cpp.orig
++++ khelpcenter/mainwindow.cpp
+@@ -41,6 +41,7 @@
+ #include <kstatusbar.h>
+ #include <kstdaccel.h>
+ #include <kdialogbase.h>
++#include <kpopupmenu.h>
+
+ #include <qsplitter.h>
+ #include <qtextedit.h>
+@@ -106,6 +107,8 @@ MainWindow::MainWindow()
+
+ connect( mDoc, SIGNAL( selectionChanged() ),
+ SLOT( enableCopyTextAction() ) );
++ connect( mDoc, SIGNAL( completed() ),
++ SLOT( updateLinkActions() ) );
+
+ statusBar()->insertItem(i18n("Preparing Index"), 0, 1);
+ statusBar()->setItemAlignment(0, AlignLeft | AlignVCenter);
+@@ -250,6 +253,8 @@ void MainWindow::setupActions()
+ new KAction( i18n( "Configure Fonts..." ), KShortcut(), this, SLOT( slotConfigureFonts() ), actionCollection(), "configure_fonts" );
+ new KAction( i18n( "Increase Font Sizes" ), "viewmag+", KShortcut(), this, SLOT( slotIncFontSizes() ), actionCollection(), "incFontSizes" );
+ new KAction( i18n( "Decrease Font Sizes" ), "viewmag-", KShortcut(), this, SLOT( slotDecFontSizes() ), actionCollection(), "decFontSizes" );
++
++ initActions();
+ }
+
+ void MainWindow::slotCopySelectedText()
+@@ -462,6 +467,418 @@ void MainWindow::slotConfigureFonts()
+ mDoc->slotReload();
+ }
+
++void MainWindow::initActions()
++{
++ kdDebug() << k_funcinfo << endl;
++
++ // ------------- Navigation links --------------
++ kaction_map["home"] = new KAction( i18n("&Top"), "2uparrow", KShortcut("Ctrl+Alt+T"), this, SLOT(goHome()), actionCollection(), "rellinks_top" );
++ kaction_map["home"]->setWhatsThis( i18n("<p>This link references a home page or the top of some hierarchy.</p>") );
++
++ kaction_map["up"] = new KAction( i18n("&Up"), "1uparrow", KShortcut("Ctrl+Alt+U"), this, SLOT(goUp()), actionCollection(), "rellinks_up" );
++ kaction_map["up"]->setWhatsThis( i18n("<p>This link references the immediate parent of the current document.</p>") );
++
++ bool isRTL = QApplication::reverseLayout();
++
++ kaction_map["begin"] = new KAction( i18n("&First"), isRTL ? "2rightarrow" : "2leftarrow", KShortcut("Ctrl+Alt+F"), this, SLOT(goFirst()), actionCollection(), "rellinks_first" );
++ kaction_map["begin"]->setWhatsThis( i18n("<p>This link type tells search engines which document is considered by the author to be the starting point of the collection.</p>") );
++
++ kaction_map["prev"] = new KAction( i18n("&Previous"), isRTL ? "1rightarrow" : "1leftarrow", KShortcut("Ctrl+Alt+P"), this, SLOT(goPrevious()), actionCollection(), "rellinks_previous" );
++ kaction_map["prev"]->setWhatsThis( i18n("<p>This link references the previous document in an ordered series of documents.</p>") );
++
++ kaction_map["next"] = new KAction( i18n("&Next"), isRTL ? "1leftarrow" : "1rightarrow", KShortcut("Ctrl+Alt+N"), this, SLOT(goNext()), actionCollection(), "rellinks_next" );
++ kaction_map["next"]->setWhatsThis( i18n("<p>This link references the next document in an ordered series of documents.</p>") );
++
++ kaction_map["last"] = new KAction( i18n("&Last"), isRTL ? "2leftarrow" : "2rightarrow", KShortcut("Ctrl+Alt+L"), this, SLOT(goLast()), actionCollection(), "rellinks_last" );
++ kaction_map["last"]->setWhatsThis( i18n("<p>This link references the end of a sequence of documents.</p>") );
++
++ // ------------ special items --------------------------
++ kaction_map["search"] = new KAction( i18n("&Search"), "filefind", KShortcut("Ctrl+Alt+S"), this, SLOT(goSearch()), actionCollection(), "rellinks_search" );
++ kaction_map["search"]->setWhatsThis( i18n("<p>This link references the search.</p>") );
++
++ // ------------ Document structure links ---------------
++ m_document = new KActionMenu( i18n("Document"), "contents", actionCollection(), "rellinks_document" );
++ m_document->setWhatsThis( i18n("<p>This menu contains the links referring the document information.</p>") );
++ m_document->setDelayed(false);
++
++ kaction_map["contents"] = new KAction( i18n("Table of &Contents"), "contents", KShortcut("Ctrl+Alt+C"), this, SLOT(goContents()), actionCollection(), "rellinks_toc" );
++ m_document->insert(kaction_map["contents"]);
++ kaction_map["contents"]->setWhatsThis( i18n("<p>This link references the table of contents.</p>") );
++
++ kactionmenu_map["chapter"] = new KActionMenu( i18n("Chapters"), "fileopen", actionCollection(), "rellinks_chapters" );
++ m_document->insert(kactionmenu_map["chapter"]);
++ connect( kactionmenu_map["chapter"]->popupMenu(), SIGNAL( activated( int ) ), this, SLOT(goChapter(int)));
++ kactionmenu_map["chapter"]->setWhatsThis( i18n("<p>This menu references the chapters of the document.</p>") );
++ kactionmenu_map["chapter"]->setDelayed(false);
++
++ kactionmenu_map["section"] = new KActionMenu( i18n("Sections"), "fileopen", actionCollection(), "rellinks_sections" );
++ m_document->insert(kactionmenu_map["section"]);
++ connect( kactionmenu_map["section"]->popupMenu(), SIGNAL( activated( int ) ), this, SLOT( goSection( int ) ) );
++ kactionmenu_map["section"]->setWhatsThis( i18n("<p>This menu references the sections of the document.</p>") );
++ kactionmenu_map["section"]->setDelayed(false);
++
++ kactionmenu_map["subsection"] = new KActionMenu( i18n("Subsections"), "fileopen", actionCollection(), "rellinks_subsections" );
++ m_document->insert(kactionmenu_map["subsection"]);
++ connect( kactionmenu_map["subsection"]->popupMenu(), SIGNAL( activated( int ) ), this, SLOT( goSubsection( int ) ) );
++ kactionmenu_map["subsection"]->setWhatsThis( i18n("<p>This menu references the subsections of the document.</p>") );
++ kactionmenu_map["subsection"]->setDelayed(false);
++
++ kactionmenu_map["appendix"] = new KActionMenu( i18n("Appendix"), "edit", actionCollection(), "rellinks_appendix" );
++ m_document->insert(kactionmenu_map["appendix"]);
++ connect( kactionmenu_map["appendix"]->popupMenu(), SIGNAL( activated( int ) ), this, SLOT( goAppendix( int ) ) );
++ kactionmenu_map["appendix"]->setWhatsThis( i18n("<p>This link references the appendix.</p>") );
++ kactionmenu_map["appendix"]->setDelayed(false);
++
++ kaction_map["glossary"] = new KAction( i18n("&Glossary"), "flag", KShortcut("Ctrl+Alt+G"), this, SLOT(goGlossary()), actionCollection(), "rellinks_glossary" );
++ m_document->insert(kaction_map["glossary"]);
++ kaction_map["glossary"]->setWhatsThis( i18n("<p>This link references the glossary.</p>") );
++
++ kaction_map["index"] = new KAction( i18n("&Index"), "info", KShortcut("Ctrl+Alt+I"), this, SLOT(goIndex()), actionCollection(), "rellinks_index" );
++ m_document->insert(kaction_map["index"]);
++ kaction_map["index"]->setWhatsThis( i18n("<p>This link references the index.</p>") );
++
++ // Other links
++ m_more = new KActionMenu( i18n("More"), "misc", actionCollection(), "rellinks_more" );
++ m_more->setWhatsThis( i18n("<p>This menu contains other important links.</p>") );
++ m_more->setDelayed(false);
++
++ kaction_map["help"] = new KAction( i18n("&Help"), "help", KShortcut("Ctrl+Alt+H"), this, SLOT(goHelp()), actionCollection(), "rellinks_help" );
++ m_more->insert(kaction_map["help"]);
++ kaction_map["help"]->setWhatsThis( i18n("<p>This link references the help.</p>") );
++
++ kaction_map["author"] = new KAction( i18n("&Authors"), "mail_new", KShortcut("Ctrl+Alt+A"), this, SLOT(goAuthor()), actionCollection(), "rellinks_authors" );
++ m_more->insert(kaction_map["author"]);
++ kaction_map["author"]->setWhatsThis( i18n("<p>This link references the author.</p>") );
++
++ kaction_map["copyright"] = new KAction( i18n("Copy&right"), "signature", KShortcut("Ctrl+Alt+R"), this, SLOT(goCopyright()), actionCollection(), "rellinks_copyright" );
++ m_more->insert(kaction_map["copyright"]);
++ kaction_map["copyright"]->setWhatsThis( i18n("<p>This link references the copyright.</p>") );
++
++ kactionmenu_map["bookmark"] = new KActionMenu( i18n("Bookmarks"), "bookmark_folder", actionCollection(), "rellinks_bookmarks" );
++ m_more->insert(kactionmenu_map["bookmark"]);
++ kactionmenu_map["bookmark"]->setWhatsThis( i18n("<p>This menu references the bookmarks.</p>") );
++ connect( kactionmenu_map["bookmark"]->popupMenu(), SIGNAL( activated( int ) ), this, SLOT( goBookmark( int ) ) );
++ kactionmenu_map["bookmark"]->setDelayed(false);
++
++ kactionmenu_map["alternate"] = new KActionMenu( i18n("Other Versions"), "attach", actionCollection(), "rellinks_other_versions" );
++ m_more->insert(kactionmenu_map["alternate"]);
++ kactionmenu_map["alternate"]->setWhatsThis( i18n("<p>This link references the alternate versions of this document.</p>") );
++ connect( kactionmenu_map["alternate"]->popupMenu(), SIGNAL( activated( int ) ), this, SLOT( goAlternate( int ) ) );
++ kactionmenu_map["alternate"]->setDelayed(false);
++
++ // Unclassified menu
++ m_links = new KActionMenu( i18n("Miscellaneous"), "rellinks", actionCollection(), "rellinks_links" );
++ kactionmenu_map["unclassified"] = m_links;
++ kactionmenu_map["unclassified"]->setWhatsThis( i18n("<p>Miscellaneous links.</p>") );
++ connect( kactionmenu_map["unclassified"]->popupMenu(), SIGNAL( activated( int ) ), this, SLOT( goAllElements( int ) ) );
++ kactionmenu_map["unclassified"]->setDelayed(false);
++
++ // We unactivate all the possible actions
++ disableAll();
++}
++
++/* Code from plugin_rellinks
++ * Copyright (C) 2002, Anders Lund <anders@alweb.dk> *
++ * Copyright (C) 2003, 2004, Franck Qu�ain <shift@free.fr> *
++ * Copyright (C) 2004, Kevin Krammer <kevin.krammer@gmx.at> *
++ * Copyright (C) 2004, 2005, Oliviet Goffart <ogoffart @ kde.org>
++*/
++void MainWindow::updateLinkActions()
++{
++ // We disable all
++ disableAll();
++
++ // get a list of LINK nodes in document
++ DOM::NodeList linkNodes = mDoc->document().getElementsByTagName( "link" );
++
++ kdDebug() << "HELP Rellinks: Link nodes =" << linkNodes.length() << endl;
++
++ unsigned long nodeLength = linkNodes.length();
++
++ for ( unsigned int i=0; i < nodeLength; i++ ) {
++ // create a entry for each one
++ DOM::Element e( linkNodes.item( i ) );
++
++
++ // --- Retrieve of the relation type --
++
++ QString rel = e.getAttribute( "rel" ).string();
++ rel = rel.simplifyWhiteSpace();
++ if (rel.isEmpty()) {
++ // If the "rel" attribut is null then use the "rev" attribute...
++ QString rev = e.getAttribute( "rev" ).string();
++ rev = rev.simplifyWhiteSpace();
++ if (rev.isEmpty()) {
++ // if "rev" attribut is also empty => ignore
++ continue;
++ }
++ // Determine the "rel" equivalent of "rev" type
++ rel = transformRevToRel(rev);
++ }
++ // Determin the name used internally
++ QString lrel = getLinkType(rel.lower());
++ // relation to ignore
++ if (lrel.isEmpty()) continue;
++ kdDebug() << "lrel=" << lrel << endl;
++
++ // -- Retrieve of other usefull informations --
++
++ QString href = e.getAttribute( "href" ).string();
++ // if nowhere to go, ignore the link
++ if (href.isEmpty()) continue;
++ QString title = e.getAttribute( "title" ).string();
++ QString hreflang = e.getAttribute( "hreflang" ).string();
++
++ KURL ref( mDoc->url(), href );
++ if ( title.isEmpty() )
++ title = ref.prettyURL();
++
++ // escape ampersand before settings as action title, otherwise the menu entry will interpret it as an
++ // accelerator
++ title.replace('&', "&&");
++
++ // -- Menus activation --
++
++ // Activation of "Document" menu ?
++ if (lrel == "contents" || lrel == "glossary" || lrel == "index" || lrel == "appendix") {
++ m_document->setEnabled(true);
++ }
++ // Activation of "More" menu ?
++ if (lrel == "help" || lrel == "author" || lrel == "copyright" ) {
++ m_more->setEnabled(true);
++ }
++
++ // -- Buttons or menu items activation / creation --
++ if (lrel == "bookmark" || lrel == "alternate") {
++ int id = kactionmenu_map[lrel]->popupMenu()->insertItem( title );
++ m_more->setEnabled(true);
++ kactionmenu_map[lrel]->setEnabled(true);
++ element_map[lrel][id] = e;
++
++ } else if (lrel == "appendix" || lrel == "chapter" || lrel == "section" || lrel == "subsection") {
++ int id = kactionmenu_map[lrel]->popupMenu()->insertItem( title );
++ m_document->setEnabled(true);
++ kactionmenu_map[lrel]->setEnabled(true);
++ element_map[lrel][id] = e;
++
++ } else {
++ // It is a unique action
++ element_map[lrel][0] = e;
++ if (kaction_map[lrel]) {
++ kaction_map[lrel]->setEnabled(true);
++ // Tooltip
++ if (hreflang.isEmpty()) {
++ kaction_map[lrel]->setToolTip( title );
++ } else {
++ kaction_map[lrel]->setToolTip( title + " [" + hreflang + "]");
++ }
++ } else {
++ // For the moment all the elements are reference in a separated menu
++ // TODO : reference the unknown ?
++ int id = kactionmenu_map["unclassified"]->popupMenu()->insertItem( lrel + " : " + title );
++ kactionmenu_map["unclassified"]->setEnabled(true);
++ element_map["unclassified"][id] = e;
++ }
++
++ }
++
++ }
++}
++
++void MainWindow::disableAll() {
++ element_map.clear();
++
++ // Clear actions
++ KActionMap::Iterator it;
++ for ( it = kaction_map.begin(); it != kaction_map.end(); ++it ) {
++ // If I don't test it crash :(
++ if (it.data()) {
++ it.data()->setEnabled(false);
++ it.data()->setToolTip(it.data()->text().remove('&'));
++ }
++ }
++
++ // Clear actions
++ KActionMenuMap::Iterator itmenu;
++ for ( itmenu = kactionmenu_map.begin(); itmenu != kactionmenu_map.end(); ++itmenu ) {
++ // If I don't test it crash :(
++ if (itmenu.data()) {
++ itmenu.data()->popupMenu()->clear();
++ itmenu.data()->setEnabled(false);
++ itmenu.data()->setToolTip(itmenu.data()->text().remove('&'));
++ }
++ }
++
++ // Unactivate menus
++ m_more->setEnabled(false);
++ m_document->setEnabled(false);
++
++}
++
++QString MainWindow::getLinkType(const QString &lrel) {
++ // Relations to ignore...
++ if (lrel.contains("stylesheet")
++ || lrel == "script"
++ || lrel == "icon"
++ || lrel == "shortcut icon"
++ || lrel == "prefetch" )
++ return QString::null;
++
++ // ...known relations...
++ if (lrel == "top" || lrel == "origin" || lrel == "start")
++ return "home";
++ if (lrel == "parent")
++ return "up";
++ if (lrel == "first")
++ return "begin";
++ if (lrel == "previous")
++ return "prev";
++ if (lrel == "child")
++ return "next";
++ if (lrel == "end")
++ return "last";
++ if (lrel == "toc")
++ return "contents";
++ if (lrel == "find")
++ return "search";
++ if (lrel == "alternative stylesheet")
++ return "alternate stylesheet";
++ if (lrel == "authors")
++ return "author";
++ if (lrel == "toc")
++ return "contents";
++
++ //...unknown relations or name that don't need to change
++ return lrel;
++}
++
++QString MainWindow::transformRevToRel(const QString &rev) {
++ QString altRev = getLinkType(rev);
++
++ // Known relations
++ if (altRev == "prev")
++ return getLinkType("next");
++ if (altRev == "next")
++ return getLinkType("prev");
++ if (altRev == "made")
++ return getLinkType("author");
++ if (altRev == "up")
++ return getLinkType("child");
++ if (altRev == "sibling")
++ return getLinkType("sibling");
++
++ //...unknown inverse relation => ignore for the moment
++ return QString::null;
++}
++
++void MainWindow::goHome() {
++ goToLink("home");
++}
++
++void MainWindow::goUp() {
++ goToLink("up");
++}
++
++void MainWindow::goFirst() {
++ goToLink("begin");
++}
++
++void MainWindow::goPrevious() {
++ goToLink("prev");
++}
++
++void MainWindow::goNext() {
++ goToLink("next");
++}
++
++void MainWindow::goLast() {
++ goToLink("last");
++}
++
++void MainWindow::goContents() {
++ goToLink("contents");
++}
++
++void MainWindow::goIndex() {
++ goToLink("index");
++}
++
++void MainWindow::goGlossary() {
++ goToLink("glossary");
++}
++
++void MainWindow::goHelp() {
++ goToLink("help");
++}
++
++void MainWindow::goSearch() {
++ goToLink("search");
++}
++
++void MainWindow::goAuthor() {
++ goToLink("author");
++}
++
++
++void MainWindow::goCopyright() {
++ goToLink("copyright");
++}
++
++void MainWindow::goBookmark(int id) {
++ goToLink("bookmark", id);
++}
++
++void MainWindow::goChapter(int id) {
++ goToLink("chapter", id);
++}
++
++void MainWindow::goSection(int id) {
++ goToLink("section", id);
++}
++
++void MainWindow::goSubsection(int id) {
++ goToLink("subsection", id);
++}
++
++void MainWindow::goAppendix(int id) {
++ goToLink("appendix", id);
++}
++
++void MainWindow::goAlternate(int id) {
++ goToLink("alternate", id);
++}
++
++void MainWindow::goAllElements(int id) {
++ goToLink("unclassified", id);
++}
++
++/** Menu links */
++void MainWindow::goToLink(const QString & rel, int id) {
++ // have the KHTML part open it
++ if (!mDoc)
++ return;
++
++ DOM::Element e = element_map[rel][id];
++ QString href = e.getAttribute("href").string();
++ KURL url( mDoc->url(), href );
++ QString target = e.getAttribute("target").string();
++
++ // URL arguments
++ KParts::URLArgs args;
++ args.frameName = target;
++
++ // Add base url if not valid
++ if (url.isValid()) {
++ mDoc->browserExtension()->openURLRequest(url, args);
++ } else {
++ KURL baseURL = mDoc->baseURL();
++ QString endURL = url.prettyURL();
++ KURL realURL = KURL(baseURL, endURL);
++ mDoc->browserExtension()->openURLRequest(realURL, args);
++ }
++
++}
++
+ #include "mainwindow.moc"
+
+ // vim:ts=2:sw=2:et
+Index: khelpcenter/mainwindow.h
+===================================================================
+--- khelpcenter/mainwindow.h.orig
++++ khelpcenter/mainwindow.h
+@@ -13,6 +13,15 @@
+ #include "navigator.h"
+ #include "glossary.h"
+
++#include <dom/dom_element.h>
++
++class KAction;
++class KActionMenu;
++// type definitions
++typedef QMap<int,DOM::Element> DOMElementMap;
++typedef QMap<QString, KAction*> KActionMap;
++typedef QMap<QString, KActionMenu*> KActionMenuMap;
++
+ class KHTMLPart;
+ class QSplitter;
+
+@@ -68,11 +77,43 @@ class MainWindow : public KMainWindow, p
+ void writeConfig();
+
+ protected slots:
++ void updateLinkActions();
+ void enableLastSearchAction();
+ void enableCopyTextAction();
+
+ private:
+ void stop();
++ /**
++ * initialise all KActions
++ */
++ void initActions();
++ /**
++ * Function used to disable all the item of the toolbar (c) rellinks
++ */
++ void disableAll();
++ /**
++ * Function used to get link type of a relation.
++ * For example "prev" is of type "previous" and "toc" is of type "contents"
++ * If the relation must be ignored return NULL.
++ * If the relation is unknow return the input relation type.
++ * @param lrel Previous relation name
++ * @return New relation name
++ */
++ QString getLinkType(const QString &lrel);
++ /**
++ * Function used to return the "rel" equivalent of "rev" link type
++ * If the equivalent is not found return NULL
++ * @param rev Inverse relation name
++ * @return Equivalent relation name
++ */
++ QString transformRevToRel(const QString &rev) ;
++
++ /**
++ * Go to the link (c) rellinks
++ * @param rel Relation name
++ * @param id Identifier of the menu item
++ */
++ void goToLink(const QString & rel, int id=0);
+
+ private slots:
+ void slotGlossSelected(const GlossaryEntry &entry);
+@@ -90,7 +131,29 @@ class MainWindow : public KMainWindow, p
+ void slotConfigureFonts();
+ void slotCopySelectedText();
+
+-private:
++ void goHome();
++ void goUp();
++ void goFirst();
++ void goPrevious();
++ void goNext();
++ void goLast();
++ void goContents();
++ void goIndex();
++ void goGlossary();
++ void goHelp();
++ void goSearch();
++ void goCopyright();
++ void goAuthor();
++
++ void goBookmark(int id);
++ void goChapter(int id);
++ void goSection(int id);
++ void goSubsection(int id);
++ void goAppendix(int id);
++ void goAlternate(int id);
++ void goAllElements(int id);
++
++ private:
+ void updateZoomActions();
+
+ QSplitter *mSplitter;
+@@ -100,6 +163,17 @@ private:
+ KAction *mLastSearchAction;
+ KAction *mCopyText;
+ LogDialog *mLogDialog;
++ //(c) rellinks
++ /** Map of KAction */
++ KActionMap kaction_map;
++ /** Map of KActionMenu */
++ KActionMenuMap kactionmenu_map;
++ /** Map of all the link element which can be managed by rellinks */
++ QMap<QString,DOMElementMap> element_map;
++ KActionMenu *m_document;
++ KActionMenu *m_more;
++ KActionMenu *m_links;
++
+ };
+
+ }
diff --git a/opensuse/tdebase/kdebase_networkstatus_branch.diff b/opensuse/tdebase/kdebase_networkstatus_branch.diff
new file mode 100644
index 000000000..8329d3cd2
--- /dev/null
+++ b/opensuse/tdebase/kdebase_networkstatus_branch.diff
@@ -0,0 +1,36 @@
+Index: konqueror/konq_frame.cc
+===================================================================
+--- konqueror/konq_frame.cc.orig
++++ konqueror/konq_frame.cc
+@@ -34,6 +34,7 @@
+ #include <kprogress.h>
+ #include <klocale.h>
+ #include <ksqueezedtextlabel.h>
++#include <networkstatusindicator.h>
+
+ #include "konq_events.h"
+ #include "konq_frame.h"
+@@ -97,6 +98,10 @@ KonqFrameStatusBar::KonqFrameStatusBar(
+ m_progressBar->hide();
+ addWidget( m_progressBar, 0, true /*permanent->right align*/ );
+
++ StatusBarNetworkStatusIndicator * indicator = new StatusBarNetworkStatusIndicator( this, "networkstatusindicator" );
++ addWidget( indicator, 0, false );
++ indicator->init();
++
+ fontChange(QFont());
+ installEventFilter( this );
+ }
+Index: konqueror/Makefile.am
+===================================================================
+--- konqueror/Makefile.am.orig
++++ konqueror/Makefile.am
+@@ -48,7 +48,7 @@ noinst_HEADERS = KonqMainWindowIface.h K
+ konq_misc.h konq_openurlrequest.h konq_profiledlg.h konq_run.h \
+ konq_view.h konq_viewmgr.h konq_extensionmanager.h version.h
+
+-konqueror_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries)
++konqueror_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) -lconnectionmanager
+ konqueror_la_LIBADD = ../libkonq/libkonq.la libkonqueror_intern.la $(LIBMALLOC) $(LIB_KUTILS)
+
+ # Hmm, this experiment of a static konq failed, don't trust it...
diff --git a/opensuse/tdebase/kdeeject.diff b/opensuse/tdebase/kdeeject.diff
new file mode 100644
index 000000000..d22e67fb6
--- /dev/null
+++ b/opensuse/tdebase/kdeeject.diff
@@ -0,0 +1,58 @@
+Index: kdeeject/kdeeject
+===================================================================
+--- kdeeject/kdeeject.orig
++++ kdeeject/kdeeject
+@@ -4,12 +4,38 @@
+ #
+ # Copyright GPL v2 by David Faure <david@mandrakesoft.com>
+ #
+-if test $# -ge 1 -a "$1" != "--help"; then
+- quiet=0
+- if test "$1" = "-q"; then
+- quiet=1
+- shift
+- fi
++quiet=0
++if test "$1" = "-q"; then
++ quiet=1
++ shift
++fi
++
++if test "$1" = "--help"; then
++ echo "Usage: $0 <name> where name is a device or a mountpoint."
++ exit 0
++fi
++
++if test -z "$1"; then
++ for dev in /dev/cdrom /dev/dvd /dev/dvdram /dev/cdrecorder; do
++ if test -e $dev; then
++ lp=`readlink $dev`
++ if test -n "$lp"; then
++ device=/dev/$lp
++ else
++ device=$dev
++ fi
++ break
++ fi
++ done
++else
++ device=$1
++fi
++
++udi=`dcop kded mediamanager properties $device 2>/dev/null | head -n 1 `
++if test -n "$udi"; then
++ dcop kded mediamanager unmount "$udi" >/dev/null 2>&1
++fi
++
+ # Checking for stuff in the PATH is ugly with sh.
+ # I guess this is the reason for making this a kde app...
+ OS=`uname -s`
+@@ -34,7 +60,5 @@ if test $# -ge 1 -a "$1" != "--help"; th
+ elif test $quiet -eq 0; then
+ kdialog --title "KDE Eject" --error "Eject $1 failed!"
+ fi
+-else
+- kdialog --title "KDE Eject" --msgbox "Usage: $0 <name> where name is a device or a mountpoint."
+-fi
++
+ exit 1
diff --git a/opensuse/tdebase/kdesktop_icons.diff b/opensuse/tdebase/kdesktop_icons.diff
new file mode 100644
index 000000000..5d208b0dd
--- /dev/null
+++ b/opensuse/tdebase/kdesktop_icons.diff
@@ -0,0 +1,311 @@
+Index: kdesktop/KDesktopIface.h
+===================================================================
+--- kdesktop/KDesktopIface.h.orig
++++ kdesktop/KDesktopIface.h
+@@ -107,6 +107,35 @@ k_dcop:
+ * space for desktop icons
+ */
+ virtual void desktopIconsAreaChanged(const QRect &area, int screen) = 0;
++
++ /**
++ * Find the next free place for a not yet existing icon, so it fits
++ * in the user arrangement. Basicly prepare for icons to be moved in.
++ * It will try to find a place in the virtual grid near col,row
++ * where no other icon is.
++ *
++ * If you specify -1 for row or column, it will try to find the next
++ * free room where no other icon follows. E.g. if you specify column
++ * = -1 and row = 0, kdesktop will find the next vertical placement
++ * so that the icon appears at the end of the existing icons preferable
++ * in the first column. If the first column is full, it will find the
++ * next free room in the second column.
++ *
++ * If you specify both column and row, kdesktop won't care for aligning,
++ * or surrounding icons, but try to find the free place near the given
++ * grid place (e.g. specify 0,0 to find the nearest place in the left
++ * upper corner).
++ */
++ virtual QPoint findPlaceForIcon( int column, int row) = 0;
++
++ /// copy the desktop file in the Desktop and place it at x, y
++ virtual void addIcon(const QString &url, int x, int y) = 0;
++
++ /// same with specific destination
++ virtual void addIcon(const QString &url, const QString &dest, int x, int y) = 0;
++
++ /// remove the desktop file (either full path or relative)
++ virtual void removeIcon(const QString &dest) = 0;
+ };
+
+ #endif
+Index: kdesktop/desktop.cc
+===================================================================
+--- kdesktop/desktop.cc.orig
++++ kdesktop/desktop.cc
+@@ -32,6 +32,9 @@
+ #include <unistd.h>
+ #include <kcolordrag.h>
+ #include <kurldrag.h>
++#include <stdlib.h>
++#include <kio/job.h>
++#include <qfile.h>
+
+ #include <qdir.h>
+ #include <qevent.h>
+@@ -58,6 +61,7 @@
+ #include <kglobalsettings.h>
+ #include <kpopupmenu.h>
+ #include <kapplication.h>
++#include <kdirlister.h>
+ // Create the equivalent of KAccelBase::connectItem
+ // and then remove this include and fix reconnects in initRoot() -- ellis
+ //#include <kaccelbase.h>
+@@ -983,4 +987,47 @@ bool KDesktop::event(QEvent * e)
+ return QWidget::event(e);
+ }
+
++QPoint KDesktop::findPlaceForIcon( int column, int row )
++{
++ if (m_pIconView)
++ return m_pIconView->findPlaceForIcon(column, row);
++ else
++ return QPoint(-1, -1);
++}
++
++void KDesktop::addIcon(const QString & _url, int x, int y)
++{
++ addIcon( _url, KGlobalSettings::desktopPath(), x, y );
++}
++
++void KDesktop::addIcon(const QString & _url, const QString & _dest, int x, int y)
++{
++ QString filename = _url.mid(_url.findRev('/') + 1);
++
++ QValueList<KIO::CopyInfo> files;
++ KIO::CopyInfo i;
++ i.uSource = KURL::fromPathOrURL( _url );
++ i.uDest = KURL::fromPathOrURL( _dest );
++ i.uDest.addPath( filename );
++ files.append(i);
++ if (!QFile::exists(i.uDest.prettyURL().replace("file://",QString::null))) { m_pIconView->slotAboutToCreate( QPoint( x, y ), files );
++ KIO::copy( i.uSource, i.uDest, false ); }
++
++// m_pIconView->addFuturePosition(filename, x, y);
++ // qDebug("addIcon %s %s %d %d", _url.latin1(), _dest.latin1(), x, y);
++// system(QString("cp \"%1\" \"%2/%3\"").arg(KURL(_url).path()).arg(KURL(_dest).path()).arg(filename).latin1());
++// m_pIconView->update( _dest );
++}
++
++void KDesktop::removeIcon(const QString &_url)
++{
++ if (_url.at(0) != '/') {
++ qDebug("removeIcon with relative path not supported for now");
++ return;
++ }
++ unlink(KURL(_url).path().latin1());
++ QString dest = _url.left(_url.findRev('/') + 1);
++ m_pIconView->update( dest );
++}
++
+ #include "desktop.moc"
+Index: kdesktop/desktop.h
+===================================================================
+--- kdesktop/desktop.h.orig
++++ kdesktop/desktop.h
+@@ -164,6 +164,11 @@ protected:
+ virtual void setIconsEnabled( bool enable );
+ virtual bool event ( QEvent * e );
+
++ virtual QPoint findPlaceForIcon( int column, int row);
++ virtual void addIcon(const QString &url, int x, int y);
++ virtual void addIcon(const QString &url, const QString &dest, int x, int y);
++ virtual void removeIcon(const QString &url);
++
+ private slots:
+ void desktopResized();
+
+Index: kdesktop/kdiconview.cc
+===================================================================
+--- kdesktop/kdiconview.cc.orig
++++ kdesktop/kdiconview.cc
+@@ -962,6 +962,18 @@ void KDIconView::slotNewItems( const KFi
+ kdDebug(1214) << "KDIconView::slotNewItems count=" << entries.count() << endl;
+ KFileItemListIterator it(entries);
+ KFileIVI* fileIVI = 0L;
++
++ if (m_nextItemPos.isNull() && !m_dotDirectory) {
++ // Not found, we'll need to save the new pos
++ kdDebug(1214)<<"Neither a drop position stored nor m_dotDirectory set"<<endl;
++ m_dotDirectory = new KSimpleConfig( dotDirectoryPath(), true );
++ // recursion
++ slotNewItems( entries );
++ delete m_dotDirectory;
++ m_dotDirectory = 0;
++ return;
++ }
++
+ for (; it.current(); ++it)
+ {
+ KURL url = it.current()->url();
+@@ -1026,15 +1038,6 @@ void KDIconView::slotNewItems( const KFi
+ kdDebug(1214)<<"Using saved position"<<endl;
+ }
+ }
+- else
+- {
+- // Not found, we'll need to save the new pos
+- kdDebug(1214)<<"slotNewItems(): New item without position information, try to find a sane location"<<endl;
+-
+- moveToFreePosition(fileIVI);
+-
+- m_bNeedSave = true;
+- }
+ }
+ }
+
+@@ -1638,6 +1641,98 @@ void KDIconView::moveToFreePosition(QIco
+ }
+
+
++QPoint KDIconView::findPlaceForIconCol( int column, int dx, int dy)
++{
++ if (column < 0)
++ return QPoint();
++
++ QRect rect;
++ rect.moveTopLeft( QPoint(column * dx, 0) );
++ rect.setWidth(dx);
++ rect.setHeight(dy);
++
++ if (rect.right() > viewport()->width())
++ return QPoint();
++
++ while ( rect.bottom() < viewport()->height() - spacing() )
++ {
++ if ( !isFreePosition(0,rect) )
++ rect.moveBy(0, rect.height());
++ else
++ return rect.topLeft();
++ }
++
++ return QPoint();
++}
++
++QPoint KDIconView::findPlaceForIconRow( int row, int dx, int dy )
++{
++ if (row < 0)
++ return QPoint();
++
++ QRect rect;
++ rect.moveTopLeft(QPoint(0, row * dy));
++ rect.setWidth(dx);
++ rect.setHeight(dy);
++
++ if (rect.bottom() > viewport()->height())
++ return QPoint();
++
++ while (rect.right() < viewport()->width() - spacing())
++ {
++ if (!isFreePosition(0,rect))
++ rect.moveBy(rect.width()+spacing(), 0);
++ else
++ return rect.topLeft();
++ }
++
++ return QPoint();
++}
++
++QPoint KDIconView::findPlaceForIcon( int column, int row)
++{
++ int dx = gridXValue(), dy = 0;
++ QIconViewItem *item = firstItem();
++ for ( ; item; item = item->nextItem() ) {
++ dx = QMAX( dx, item->width() );
++ dy = QMAX( dy, item->height() );
++ }
++
++ dx += spacing();
++ dy += spacing();
++
++ if (row == -1) {
++ int max_cols = viewport()->width() / dx;
++ int delta = 0;
++ QPoint res;
++ do {
++ delta++;
++ res = findPlaceForIconCol(column + (delta / 2) * (-2 * (delta % 2) + 1),
++ dx, dy);
++ if (delta / 2 > QMAX(max_cols - column, column))
++ return res;
++ } while (res.isNull());
++ return res;
++ }
++
++ if (column == -1) {
++ int max_rows = viewport()->height() / dy;
++ int delta = 0;
++ QPoint res;
++ do {
++ delta++;
++ res = findPlaceForIconRow(row + (delta / 2) * (-2 * (delta % 2) + 1),
++ dx, dy);
++ if (delta / 2 > QMAX(max_rows - row, row))
++ return res;
++ } while (res.isNull());
++ return res;
++ }
++
++ // very unlikely - if I may add that
++ return QPoint(0, 0);
++}
++
+ void KDIconView::saveIconPositions()
+ {
+ kdDebug(1214) << "KDIconView::saveIconPositions" << endl;
+@@ -1665,4 +1760,11 @@ void KDIconView::saveIconPositions()
+ m_dotDirectory->sync();
+ }
+
++void KDIconView::update( const QString &_url )
++{
++ if (m_dirLister)
++ m_dirLister->updateDirectory( _url );
++}
++
++
+ #include "kdiconview.moc"
+Index: kdesktop/kdiconview.h
+===================================================================
+--- kdesktop/kdiconview.h.orig
++++ kdesktop/kdiconview.h
+@@ -73,6 +73,8 @@ public:
+
+ QStringList selectedURLs();
+
++ void update( const QString &url );
++
+ /**
+ * Save the icon positions
+ */
+@@ -103,6 +105,10 @@ public:
+
+ void startDirLister();
+
++ QPoint findPlaceForIconCol( int column, int dx, int dy );
++ QPoint findPlaceForIconRow( int row, int dx, int dy );
++ QPoint findPlaceForIcon( int column, int row );
++
+ protected slots:
+
+ // slots connected to the icon view
+@@ -112,8 +118,9 @@ protected slots:
+ void slotMouseButtonClickedKDesktop(int _button, QIconViewItem* _item, const QPoint& _global);
+ void slotContextMenuRequested(QIconViewItem* _item, const QPoint& _global);
+ void slotEnableAction( const char * name, bool enabled );
++public slots:
+ void slotAboutToCreate(const QPoint &pos, const QValueList<KIO::CopyInfo> &files);
+-
++protected slots:
+ void slotItemRenamed(QIconViewItem*, const QString &name);
+
+ // slots connected to the directory lister
diff --git a/opensuse/tdebase/kdesu-remember-keep-password.diff b/opensuse/tdebase/kdesu-remember-keep-password.diff
new file mode 100644
index 000000000..29e9002d8
--- /dev/null
+++ b/opensuse/tdebase/kdesu-remember-keep-password.diff
@@ -0,0 +1,18 @@
+Subject: Default to kdesu password remembering on, but remember last state
+From: Lubos Lunak
+Feature: bnc#386531
+Patch-upstream: no
+Relates: kdebase4/kdesu-remember-keep-password.diff, kdelibs3/kdesu-settings.diff
+
+Index: kdesu/kdesu/kdesu.cpp
+===================================================================
+--- kdesu/kdesu/kdesu.cpp (revision 810363)
++++ kdesu/kdesu/kdesu.cpp (working copy)
+@@ -382,6 +382,7 @@
+ change_uid = false;
+ password = dlg.password();
+ keep = dlg.keep();
++ KConfigGroup(config,"Passwords").writeEntry("Keep", keep);
+ data.setSilent( KStartupInfoData::No );
+ KStartupInfo::sendChange( id, data );
+ }
diff --git a/opensuse/tdebase/kdesud-security.diff b/opensuse/tdebase/kdesud-security.diff
new file mode 100644
index 000000000..40b44de71
--- /dev/null
+++ b/opensuse/tdebase/kdesud-security.diff
@@ -0,0 +1,21 @@
+Index: kdesu/kdesud/kdesud.cpp
+===================================================================
+--- kdesu/kdesud/kdesud.cpp.orig
++++ kdesu/kdesud/kdesud.cpp
+@@ -45,6 +45,7 @@
+ #include <pwd.h>
+ #include <errno.h>
+
++#include <sys/prctl.h>
+ #include <sys/time.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
+@@ -248,6 +249,8 @@ int create_socket()
+
+ int main(int argc, char *argv[])
+ {
++ prctl(PR_SET_DUMPABLE, 0);
++
+ KAboutData aboutData("kdesud", I18N_NOOP("KDE su daemon"),
+ Version, I18N_NOOP("Daemon used by kdesu"),
+ KAboutData::License_Artistic,
diff --git a/opensuse/tdebase/kdm-admin-mode.diff b/opensuse/tdebase/kdm-admin-mode.diff
new file mode 100644
index 000000000..6028d7698
--- /dev/null
+++ b/opensuse/tdebase/kdm-admin-mode.diff
@@ -0,0 +1,424 @@
+Index: kdm/config.def
+===================================================================
+--- kdm/config.def.orig
++++ kdm/config.def
+@@ -2002,6 +2002,17 @@ Description:
+ Specify the widget style for the greeter. Empty means to use the
+ built-in default which currently is <literal>Plastik</literal>.
+
++Key: UseAdminSession
++Type: bool
++Default: false
++User: greeter
++Instance: #*/!
++Comment:
++ Admin session
++Description:
++ If given there will be a special button that requires root password
++ and starts the given session
++
+ Key: ColorScheme
+ Type: string
+ Default: ""
+Index: kdm/kfrontend/Makefile.am
+===================================================================
+--- kdm/kfrontend/Makefile.am.orig
++++ kdm/kfrontend/Makefile.am
+@@ -21,6 +21,7 @@ kdm_greet_SOURCES = \
+ kchooser.cpp \
+ kgverify.cpp \
+ kdmshutdown.cpp \
++ kdmadmindialog.cpp \
+ kgreeter.cpp \
+ kgapp.cpp
+ kdm_greet_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+Index: kdm/kfrontend/kdmadmindialog.cpp
+===================================================================
+--- /dev/null
++++ kdm/kfrontend/kdmadmindialog.cpp
+@@ -0,0 +1,176 @@
++ /*
++
++ Admin dialog
++
++ Copyright (C) 1997, 1998, 2000 Steffen Hansen <hansen@kde.org>
++ Copyright (C) 2000-2003 Oswald Buddenhagen <ossi@kde.org>
++
++
++ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ */
++
++#include "kdmadmindialog.h"
++#include "kdmconfig.h"
++#include "kgdialog.h"
++#include "kdm_greet.h"
++#include <stdlib.h>
++
++#include <kapplication.h>
++#include <kseparator.h>
++#include <klocale.h>
++#include <kpushbutton.h>
++#include <kstdguiitem.h>
++
++#include <qcombobox.h>
++#include <qvbuttongroup.h>
++#include <qstyle.h>
++#include <qlayout.h>
++#include <qaccel.h>
++#include <qpopupmenu.h>
++
++int KDMAdmin::curPlugin = -1;
++PluginList KDMAdmin::pluginList;
++
++KDMAdmin::KDMAdmin( const QString &user, QWidget *_parent )
++ : inherited( _parent )
++ , verify( 0 ), curUser(user)
++{
++ QSizePolicy fp( QSizePolicy::Fixed, QSizePolicy::Fixed );
++
++ QVBoxLayout *box = new QVBoxLayout( this, 10 );
++
++ QHBoxLayout *hlay = new QHBoxLayout( box );
++
++ GSendInt( G_ReadDmrc );
++ GSendStr( "root" );
++ GRecvInt(); // ignore status code ...
++
++ if (curPlugin < 0) {
++ curPlugin = 0;
++ pluginList = KGVerify::init( "classic" );
++ }
++ verify = new KGStdVerify( this, this,
++ this, "root",
++ pluginList, KGreeterPlugin::Authenticate,
++ KGreeterPlugin::Shutdown );
++ verify->selectPlugin( curPlugin );
++ box->addLayout( verify->getLayout() );
++ QAccel *accel = new QAccel( this );
++ accel->insertItem( ALT+Key_A, 0 );
++ connect( accel, SIGNAL(activated(int)), SLOT(slotActivatePlugMenu()) );
++
++ box->addWidget( new KSeparator( KSeparator::HLine, this ) );
++
++ okButton = new KPushButton( KStdGuiItem::ok(), this );
++ okButton->setSizePolicy( fp );
++ okButton->setDefault( true );
++ cancelButton = new KPushButton( KStdGuiItem::cancel(), this );
++ cancelButton->setSizePolicy( fp );
++
++ hlay = new QHBoxLayout( box );
++ hlay->addStretch( 1 );
++ hlay->addWidget( okButton );
++ hlay->addStretch( 1 );
++ hlay->addWidget( cancelButton );
++ hlay->addStretch( 1 );
++
++ connect( okButton, SIGNAL(clicked()), SLOT(accept()) );
++ connect( cancelButton, SIGNAL(clicked()), SLOT(reject()) );
++
++ slotWhenChanged();
++}
++
++KDMAdmin::~KDMAdmin()
++{
++ hide();
++ delete verify;
++}
++
++void
++KDMAdmin::slotActivatePlugMenu()
++{
++ QPopupMenu *cmnu = verify->getPlugMenu();
++ QSize sh( cmnu->sizeHint() / 2 );
++ cmnu->exec( geometry().center() - QPoint( sh.width(), sh.height() ) );
++}
++
++void
++KDMAdmin::accept()
++{
++ verify->accept();
++}
++
++void
++KDMAdmin::slotWhenChanged()
++{
++ verify->abort();
++ verify->setEnabled( 1 );
++ verify->start();
++}
++
++void
++KDMAdmin::bye_bye()
++{
++ GSendInt( G_GetDmrc );
++ GSendStr( "Session" );
++ char *sess = GRecvStr();
++ if (sess && strcmp(sess, "admin")) {
++ GSendInt( G_PutDmrc );
++ GSendStr( "OrigSession");
++ GSendStr( sess);
++ free(sess);
++ }
++
++ GSendInt( G_PutDmrc );
++ GSendStr( "Session" );
++ GSendStr( "admin" );
++ inherited::accept();
++}
++
++void
++KDMAdmin::verifyPluginChanged( int id )
++{
++ curPlugin = id;
++ adjustSize();
++}
++
++void
++KDMAdmin::verifyOk()
++{
++ bye_bye();
++}
++
++void
++KDMAdmin::verifyFailed()
++{
++ okButton->setEnabled( false );
++ cancelButton->setEnabled( false );
++}
++
++void
++KDMAdmin::verifyRetry()
++{
++ okButton->setEnabled( true );
++ cancelButton->setEnabled( true );
++}
++
++void
++KDMAdmin::verifySetUser( const QString & )
++{
++}
++
++
++#include "kdmadmindialog.moc"
+Index: kdm/kfrontend/kdmadmindialog.h
+===================================================================
+--- /dev/null
++++ kdm/kfrontend/kdmadmindialog.h
+@@ -0,0 +1,70 @@
++ /*
++
++ Shutdown dialog
++
++ Copyright (C) 1997, 1998 Steffen Hansen <hansen@kde.org>
++ Copyright (C) 2000-2003 Oswald Buddenhagen <ossi@kde.org>
++
++
++ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ */
++
++
++#ifndef KDMADMIN_H
++#define KDMADMIN_H
++
++#include "kgverify.h"
++
++#include <qradiobutton.h>
++
++class LiloInfo;
++class QLabel;
++class KPushButton;
++class QButtonGroup;
++class QComboBox;
++
++class KDMAdmin : public FDialog, public KGVerifyHandler {
++ Q_OBJECT
++ typedef FDialog inherited;
++
++public:
++ KDMAdmin( const QString &user, QWidget *_parent = 0 );
++ ~KDMAdmin();
++
++public slots:
++ void accept();
++ void slotWhenChanged();
++ void slotActivatePlugMenu();
++
++private:
++ void bye_bye();
++
++ KPushButton *okButton, *cancelButton;
++ KGStdVerify *verify;
++ QString curUser;
++
++ static int curPlugin;
++ static PluginList pluginList;
++
++public: // from KGVerifyHandler
++ virtual void verifyPluginChanged( int id );
++ virtual void verifyOk();
++ virtual void verifyFailed();
++ virtual void verifyRetry();
++ virtual void verifySetUser( const QString &user );
++};
++
++#endif
+Index: kdm/kfrontend/kgreeter.cpp
+===================================================================
+--- kdm/kfrontend/kgreeter.cpp.orig
++++ kdm/kfrontend/kgreeter.cpp
+@@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fi
+ #include "kdmconfig.h"
+ #include "kdmclock.h"
+ #include "kdm_greet.h"
++#include "kdmadmindialog.h"
+ #include "themer/kdmthemer.h"
+ #include "themer/kdmitem.h"
+ #include "themer/kdmlabel.h"
+@@ -509,7 +510,7 @@ KGreeter::insertSessions()
+ for (char **dit = _sessionsDirs; *dit; ++dit) {
+ QStringList ents = QDir( *dit ).entryList();
+ for (QStringList::ConstIterator it = ents.begin(); it != ents.end(); ++it)
+- if ((*it).endsWith( ".desktop" )) {
++ if ((*it).endsWith( ".desktop" ) && !(*it).endsWith("admin.desktop")) {
+ KSimpleConfig dsk( QString( *dit ).append( '/' ).append( *it ) );
+ dsk.setGroup( "Desktop Entry" );
+ putSession( (*it).left( (*it).length() - 8 ),
+@@ -648,6 +649,17 @@ KGreeter::slotLoadPrevWM()
+ return;
+ }
+ } else {
++ if (!strcmp(sess, "admin")) {
++ // need to get the original
++ GSendInt( G_GetDmrc);
++ GSendStr( "OrigSession");
++ sess = GRecvStr();
++ if (!sess) {
++ free(sess);
++ sess = strdup("default");
++ }
++ }
++
+ for (uint i = 0; i < sessionTypes.count() && !sessionTypes[i].hid; i++)
+ if (sessionTypes[i].type == sess) {
+ free( sess );
+@@ -998,6 +1010,12 @@ KThemedGreeter::KThemedGreeter()
+ }
+ }
+
++ admin_button = themer->findNode( "admin_button");
++ if ( admin_button ) {
++ if ( !_useAdminSession )
++ admin_button->hide( true );
++ }
++
+ if (plugMenu) {
+ inserten( i18n("&Authentication Method"), 0, plugMenu );
+ needSep = true;
+@@ -1103,6 +1121,8 @@ KThemedGreeter::slotThemeActivated( cons
+ slotSessMenu();
+ else if (id == "system_button")
+ slotActionMenu();
++ else if (id == "admin_button")
++ slotAskAdminPassword();
+ }
+
+ void
+@@ -1129,4 +1149,15 @@ KThemedGreeter::keyPressEvent( QKeyEvent
+ accept();
+ }
+
++void
++KThemedGreeter::slotAskAdminPassword()
++{
++ KDMAdmin k(curUser, this);
++ if (k.exec()) {
++ GSendInt(G_Ready);
++ hide();
++ done(ex_exit);
++ }
++}
++
+ #include "kgreeter.moc"
+Index: kdm/kfrontend/kgreeter.h
+===================================================================
+--- kdm/kfrontend/kgreeter.h.orig
++++ kdm/kfrontend/kgreeter.h
+@@ -146,6 +146,7 @@ class KThemedGreeter : public KGreeter {
+ void slotThemeActivated( const QString &id );
+ void slotSessMenu();
+ void slotActionMenu();
++ void slotAskAdminPassword();
+
+ protected:
+ virtual void updateStatus( bool fail, bool caps, int timedleft );
+@@ -158,7 +159,7 @@ class KThemedGreeter : public KGreeter {
+ KdmThemer *themer;
+ KdmItem *caps_warning, *xauth_warning, *pam_error, *timed_label,
+ *console_rect, *userlist_rect,
+- *session_button, *system_button;
++ *session_button, *system_button, *admin_button;
+
+ public: // from KGVerifyHandler
+ virtual void verifyFailed();
+Index: kdm/kfrontend/sessions/Makefile.am
+===================================================================
+--- kdm/kfrontend/sessions/Makefile.am.orig
++++ kdm/kfrontend/sessions/Makefile.am
+@@ -1,6 +1,6 @@
+ sessionsdir = $(kde_datadir)/kdm/sessions
+ sessions_DATA = \
+- kde.desktop gnome.desktop \
++ admin.desktop kde.desktop gnome.desktop \
+ 9wm.desktop \
+ aewm++.desktop \
+ aewm.desktop \
+Index: kdm/kfrontend/sessions/admin.desktop
+===================================================================
+--- /dev/null
++++ kdm/kfrontend/sessions/admin.desktop
+@@ -0,0 +1,7 @@
++[Desktop Entry]
++Encoding=UTF-8
++Type=XSession
++Exec=YaSTadminSession
++TryExec=YaSTadminSession
++Name=admin
++Comment=Yast Admin Session
+Index: kdm/kfrontend/themer/kdmlabel.cpp
+===================================================================
+--- kdm/kfrontend/themer/kdmlabel.cpp.orig
++++ kdm/kfrontend/themer/kdmlabel.cpp
+@@ -214,6 +214,7 @@ static const struct {
+ { "language", I18N_NOOP("&Language") },
+ { "session", I18N_NOOP("Session &Type") },
+ { "system", I18N_NOOP("&System") }, // i18n("Actions");
++ { "admin", I18N_NOOP("&Administration") },
+ { "disconnect", I18N_NOOP("&Disconnect") },
+ { "quit", I18N_NOOP("&Quit") },
+ { "halt", I18N_NOOP("Power O&ff") },
diff --git a/opensuse/tdebase/kdm-aliasing.diff b/opensuse/tdebase/kdm-aliasing.diff
new file mode 100644
index 000000000..73fc86e54
--- /dev/null
+++ b/opensuse/tdebase/kdm-aliasing.diff
@@ -0,0 +1,11 @@
+Index: kdm/backend/Makefile.am
+===================================================================
+--- kdm/backend/Makefile.am.orig
++++ kdm/backend/Makefile.am
+@@ -1,5 +1,6 @@
+ # forcibly remove thread-related defines & flags
+ AUTOMAKE_OPTIONS = foreign
++CFLAGS = $(XDM_CFLAGS) -fno-strict-aliasing
+ CPPFLAGS = $(USER_INCLUDES) $(X_INCLUDES) $(KRB4_INCS) $(KRB5_INCS) -I.. -I../..
+ LDFLAGS = $(USER_LDFLAGS) $(X_LDFLAGS) $(X_RPATH) $(KRB4_RPATH) $(KRB5_RPATH)
+ LDADD = $(LIB_X11) -lXau $(LIBXDMCP) $(PASSWDLIBS) $(LIBSHADOW) $(LIBGEN) \
diff --git a/opensuse/tdebase/kdm-align-userlist-labels.diff b/opensuse/tdebase/kdm-align-userlist-labels.diff
new file mode 100644
index 000000000..65accc55f
--- /dev/null
+++ b/opensuse/tdebase/kdm-align-userlist-labels.diff
@@ -0,0 +1,46 @@
+Index: kdm/kfrontend/kgreeter.cpp
+===================================================================
+--- kdm/kfrontend/kgreeter.cpp.orig
++++ kdm/kfrontend/kgreeter.cpp
+@@ -59,6 +59,7 @@ Foundation, Inc., 51 Franklin Street, Fi
+ #include <qtooltip.h>
+ #include <qaccel.h>
+ #include <qeventloop.h>
++#include <qbitmap.h>
+
+ #include <pwd.h>
+ #include <grp.h>
+@@ -313,6 +314,33 @@ KGreeter::insertUser( const QImage &defa
+ if ( p.isNull() )
+ p = default_pix;
+
++ const int size = 48;
++ const int wdiff = size - p.size().width();
++ const int hdiff = size - p.size().height();
++ if (wdiff>0 || hdiff>0) {
++ QPixmap pix(p);
++ QBitmap mask;
++ mask.convertFromImage(p.createAlphaMask());
++ pix.resize(size, size);
++ bitBlt(&pix, wdiff/2.0, hdiff/2.0, &pix);
++ if (mask.isNull()) {
++ mask = QBitmap(size, size);
++ mask.fill(Qt::color1);
++ }
++ else {
++ mask.resize(size, size);
++ bitBlt(&mask, wdiff/2.0, hdiff/2.0, &mask);
++ }
++ QPainter pa(&mask);
++ pa.fillRect(0, 0, size, hdiff/2.0, Qt::color0);
++ pa.fillRect(0, 0, wdiff/2.0, size, Qt::color0);
++ pa.fillRect(size-(wdiff/2.0), 0, size, size, Qt::color0);
++ pa.fillRect(0, size-(hdiff/2.0), size, size, Qt::color0);
++ pa.end();
++ pix.setMask(mask);
++ p=pix.convertToImage();
++ }
++
+ QString realname = KStringHandler::from8Bit( ps->pw_gecos );
+ realname.truncate( realname.find( ',' ) );
+ if (realname.isEmpty() || realname == username)
diff --git a/opensuse/tdebase/kdm-all-users-nopass.diff b/opensuse/tdebase/kdm-all-users-nopass.diff
new file mode 100644
index 000000000..612c6a553
--- /dev/null
+++ b/opensuse/tdebase/kdm-all-users-nopass.diff
@@ -0,0 +1,34 @@
+Index: kdm/backend/client.c
+===================================================================
+--- kdm/backend/client.c.orig
++++ kdm/backend/client.c
+@@ -386,6 +386,9 @@ AccNoPass( const char *un, struct passwd
+ if (cursource != PWSRC_MANUAL)
+ return 1;
+
++ if (td->noPassAllUsers)
++ return 1;
++
+ for (hg = 0, fp = td->noPassUsers; *fp; fp++)
+ if (**fp == '@')
+ hg = 1;
+Index: kdm/config.def
+===================================================================
+--- kdm/config.def.orig
++++ kdm/config.def
+@@ -1852,6 +1852,15 @@ Description:
+ (and any other user with UID = 0).
+ <emphasis>Never</emphasis> list <systemitem class="username">root</systemitem>.
+
++Key: NoPassAllUsers
++Type: bool
++Default: false
++User: core
++Instance: #:0/true
++Comment: &
++Description:
++ All users can login without password
++
+ Key: AutoLoginEnable
+ Type: bool
+ Default: false
diff --git a/opensuse/tdebase/kdm-audit-log.diff b/opensuse/tdebase/kdm-audit-log.diff
new file mode 100644
index 000000000..de571e44d
--- /dev/null
+++ b/opensuse/tdebase/kdm-audit-log.diff
@@ -0,0 +1,190 @@
+Index: kdm/backend/client.c
+===================================================================
+--- kdm/backend/client.c.orig
++++ kdm/backend/client.c
+@@ -87,6 +87,14 @@ extern int loginsuccess( const char *Use
+ #include "consolekit.h"
+ #endif
+
++#define AU_FAILED 0
++#define AU_SUCCESS 1
++#ifdef HAVE_LIBAUDIT
++#include <libaudit.h>
++#else
++#define log_to_audit_system(l,h,d,s) do { ; } while (0)
++#endif
++
+ /*
+ * Session data, mostly what struct verify_info was for
+ */
+@@ -291,6 +299,56 @@ fail_delay( int retval ATTR_UNUSED, unsi
+ {}
+ # endif
+
++ /**
++ * log_to_audit_system:
++ * @login: Name of user
++ * @hostname: Name of host machine
++ * @tty: Name of display
++ * @success: 1 for success, 0 for failure
++ *
++ * Logs the success or failure of the login attempt with the linux kernel
++ * audit system. The intent is to capture failed events where the user
++ * fails authentication or otherwise is not permitted to login. There are
++ * many other places where pam could potentially fail and cause login to
++ * fail, but these are system failures rather than the signs of an account
++ * being hacked.
++ *
++ * Returns nothing.
++ */
++
++#ifdef HAVE_LIBAUDIT
++static void
++log_to_audit_system (const char *loginname,
++ const char *hostname,
++ const char *tty,
++ int success)
++{
++ struct passwd *pw;
++ char buf[64];
++ int audit_fd;
++
++ audit_fd = audit_open();
++ if (loginname)
++ pw = getpwnam(loginname);
++ else {
++ loginname = "unknown";
++ pw = NULL;
++ }
++ Debug("log_to_audit %p %s\n", pw, loginname);
++
++ if (pw) {
++ snprintf(buf, sizeof(buf), "uid=%d", pw->pw_uid);
++ audit_log_user_message(audit_fd, AUDIT_USER_LOGIN,
++ buf, hostname, NULL, tty, (int)success);
++ } else {
++ snprintf(buf, sizeof(buf), "acct=%s", loginname);
++ audit_log_user_message(audit_fd, AUDIT_USER_LOGIN,
++ buf, hostname, NULL, tty, (int)success);
++ }
++ close(audit_fd);
++}
++#endif
++
+ static int
+ doPAMAuth( const char *psrv, struct pam_data *pdata )
+ {
+@@ -349,6 +407,8 @@ doPAMAuth( const char *psrv, struct pam_
+ GSendStr( curuser );
+ }
+ if (pretc != PAM_SUCCESS) {
++ /* Log the failed login attempt */
++ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
+ switch (pretc) {
+ case PAM_USER_UNKNOWN:
+ case PAM_AUTH_ERR:
+@@ -702,6 +762,8 @@ Verify( GConvFunc gconv, int rootok )
+ if (!p->pw_uid) {
+ if (!rootok && !td->allowRootLogin)
+ V_RET_FAIL( "Root logins are not allowed" );
++ /* Log the failed login attempt */
++ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
+ return 1; /* don't deny root to log in */
+ }
+
+@@ -738,6 +800,8 @@ Verify( GConvFunc gconv, int rootok )
+ }
+ if (pretc == PAM_SUCCESS)
+ break;
++ /* Log the failed login attempt */
++ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
+ /* effectively there is only PAM_AUTHTOK_ERR */
+ GSendInt( V_FAIL );
+ }
+@@ -827,6 +891,8 @@ Verify( GConvFunc gconv, int rootok )
+ GSendInt( V_MSG_ERR );
+ GSendStr( "Your account has expired;"
+ " please contact your system administrator" );
++ /* Log the failed login attempt */
++ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
+ GSendInt( V_FAIL );
+ LC_RET0;
+ } else if (tim > (expir - warntime) && !quietlog) {
+@@ -861,6 +927,8 @@ Verify( GConvFunc gconv, int rootok )
+ GSendInt( V_MSG_ERR );
+ GSendStr( "Your account has expired;"
+ " please contact your system administrator" );
++ /* Log the failed login attempt */
++ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
+ GSendInt( V_FAIL );
+ LC_RET0;
+ }
+@@ -920,6 +988,8 @@ Verify( GConvFunc gconv, int rootok )
+ close( fd );
+ }
+ GSendStr( "Logins are not allowed at the moment.\nTry again later" );
++ /* Log the failed login attempt */
++ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
+ GSendInt( V_FAIL );
+ LC_RET0;
+ }
+@@ -930,6 +1000,8 @@ Verify( GConvFunc gconv, int rootok )
+ PrepErrorGreet();
+ GSendInt( V_MSG_ERR );
+ GSendStr( "You are not allowed to login at the moment" );
++ /* Log the failed login attempt */
++ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
+ GSendInt( V_FAIL );
+ LC_RET0;
+ }
+@@ -941,6 +1013,8 @@ Verify( GConvFunc gconv, int rootok )
+ Debug( "shell not in /etc/shells\n" );
+ endusershell();
+ V_RET_FAIL( "Your login shell is not listed in /etc/shells" );
++ /* Log the failed login attempt */
++ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
+ }
+ if (!strcmp( s, p->pw_shell )) {
+ endusershell();
+@@ -1365,6 +1439,9 @@ StartClient()
+ # define D_LOGIN_SETGROUP 0
+ #endif /* USE_PAM */
+
++ /* Login succeeded */
++ log_to_audit_system (curuser, td->remoteHost, td->name, AU_SUCCESS);
++
+ removeAuth = 1;
+ chownCtrl( &td->ctrl, curuid );
+ endpwent();
+Index: kdm/configure.in.in
+===================================================================
+--- kdm/configure.in.in.orig
++++ kdm/configure.in.in
+@@ -288,3 +288,27 @@ fi
+ AC_SUBST(DBUS_LIBS)
+
+ dnl AC_OUTPUT(kdm/kfrontend/sessions/kde.desktop)
++
++
++AC_ARG_WITH(libaudit,
++ [ --with-libaudit=[auto/yes/no] Add Linux audit support [default=auto]],,
++ with_libaudit=auto)
++
++# Check for Linux auditing API
++#
++# libaudit detection
++if test x$with_libaudit = xno ; then
++ have_libaudit=no;
++else
++ # See if we have audit daemon library
++ AC_CHECK_LIB(audit, audit_log_user_message,
++ have_libaudit=yes, have_libaudit=no)
++fi
++
++AM_CONDITIONAL(HAVE_LIBAUDIT, test x$have_libaudit = xyes)
++
++if test x$have_libaudit = xyes ; then
++ EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -laudit"
++ AC_DEFINE(HAVE_LIBAUDIT,1,[linux audit support])
++fi
++
diff --git a/opensuse/tdebase/kdm-color-scheme.diff b/opensuse/tdebase/kdm-color-scheme.diff
new file mode 100644
index 000000000..f45486ad1
--- /dev/null
+++ b/opensuse/tdebase/kdm-color-scheme.diff
@@ -0,0 +1,28 @@
+Index: kdm/kfrontend/kgapp.cpp
+===================================================================
+--- kdm/kfrontend/kgapp.cpp.orig
++++ kdm/kfrontend/kgapp.cpp
+@@ -42,6 +42,7 @@ Foundation, Inc., 51 Franklin Street, Fi
+ #include <qtimer.h>
+ #include <qcursor.h>
+ #include <qpalette.h>
++#include <qfile.h>
+
+ #include <stdlib.h> // free(), exit()
+ #include <unistd.h> // alarm()
+@@ -144,7 +145,14 @@ kg_main( const char *argv0 )
+ if (!_GUIStyle.isEmpty())
+ app.setStyle( _GUIStyle );
+
+- _colorScheme = locate( "data", "kdisplay/color-schemes/" + _colorScheme + ".kcsrc" );
++ const QString _configColorScheme = _colorScheme;
++
++ if (_useTheme && !_theme.isEmpty())
++ _colorScheme = _theme + "/color.kcsrc";
++
++ if (!QFile::exists(_colorScheme))
++ _colorScheme = locate( "data", "kdisplay/color-schemes/" + _configColorScheme + ".kcsrc" );
++
+ if (!_colorScheme.isEmpty()) {
+ KSimpleConfig config( _colorScheme, true );
+ config.setGroup( "Color Scheme" );
diff --git a/opensuse/tdebase/kdm-consolekit.diff b/opensuse/tdebase/kdm-consolekit.diff
new file mode 100644
index 000000000..9b4df34bc
--- /dev/null
+++ b/opensuse/tdebase/kdm-consolekit.diff
@@ -0,0 +1,822 @@
+Index: kdm/backend/client.c
+===================================================================
+--- kdm/backend/client.c.orig
++++ kdm/backend/client.c
+@@ -83,6 +83,10 @@ extern int loginsuccess( const char *Use
+ #endif
+ #include <signal.h>
+
++#ifdef WITH_CONSOLE_KIT
++#include "consolekit.h"
++#endif
++
+ /*
+ * Session data, mostly what struct verify_info was for
+ */
+@@ -1124,8 +1128,13 @@ static int removeSession;
+ static int removeCreds;
+ #endif
+
++#ifdef WITH_CONSOLE_KIT
++int
++StartClient( const char *ck_session_cookie )
++#else
+ int
+ StartClient()
++#endif
+ {
+ const char *home, *sessargs, *desksess;
+ char **env, *xma;
+@@ -1223,6 +1232,11 @@ StartClient()
+ if (krbtkfile[0] != '\0')
+ env = setEnv( env, "KRBTKFILE", krbtkfile );
+ #endif
++#ifdef WITH_CONSOLE_KIT
++ if (ck_session_cookie != NULL) {
++ env = setEnv ( env, "XDG_SESSION_COOKIE", ck_session_cookie );
++ }
++#endif
+ userEnviron = inheritEnv( env, envvars );
+ env = systemEnv( p->pw_name );
+ systemEnviron = setEnv( env, "HOME", p->pw_dir );
+Index: kdm/backend/consolekit.c
+===================================================================
+--- /dev/null
++++ kdm/backend/consolekit.c
+@@ -0,0 +1,552 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
++ *
++ * Copyright (C) 2006-2007 William Jon McCann <mccann@jhu.edu>
++ * Copyright (C) 2007 Kevin Kofler <Kevin@tigcc.ticalc.org>
++ *
++ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ *
++ */
++
++#include "dm.h"
++#include "dm_auth.h"
++#include "dm_error.h"
++
++#include <stdlib.h>
++#include <string.h>
++#include <pwd.h>
++
++#define DBUS_API_SUBJECT_TO_CHANGE
++#include <dbus/dbus.h>
++
++#include "consolekit.h"
++
++
++#define CK_NAME "org.freedesktop.ConsoleKit"
++#define CK_PATH "/org/freedesktop/ConsoleKit"
++#define CK_INTERFACE "org.freedesktop.ConsoleKit"
++#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager"
++#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
++#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
++
++static DBusConnection *private_connection = NULL;
++
++static void
++add_param_int (DBusMessageIter *iter_struct,
++ const char *key,
++ int value)
++{
++ DBusMessageIter iter_struct_entry;
++ DBusMessageIter iter_var;
++
++ dbus_message_iter_open_container (iter_struct,
++ DBUS_TYPE_STRUCT,
++ NULL,
++ &iter_struct_entry);
++
++ dbus_message_iter_append_basic (&iter_struct_entry,
++ DBUS_TYPE_STRING,
++ &key);
++
++ dbus_message_iter_open_container (&iter_struct_entry,
++ DBUS_TYPE_VARIANT,
++ DBUS_TYPE_INT32_AS_STRING,
++ &iter_var);
++
++ dbus_message_iter_append_basic (&iter_var,
++ DBUS_TYPE_INT32,
++ &value);
++
++ dbus_message_iter_close_container (&iter_struct_entry,
++ &iter_var);
++
++ dbus_message_iter_close_container (iter_struct, &iter_struct_entry);
++}
++
++static void
++add_param_boolean (DBusMessageIter *iter_struct,
++ const char *key,
++ int value)
++{
++ DBusMessageIter iter_struct_entry;
++ DBusMessageIter iter_var;
++
++ dbus_message_iter_open_container (iter_struct,
++ DBUS_TYPE_STRUCT,
++ NULL,
++ &iter_struct_entry);
++
++ dbus_message_iter_append_basic (&iter_struct_entry,
++ DBUS_TYPE_STRING,
++ &key);
++
++ dbus_message_iter_open_container (&iter_struct_entry,
++ DBUS_TYPE_VARIANT,
++ DBUS_TYPE_BOOLEAN_AS_STRING,
++ &iter_var);
++
++ dbus_message_iter_append_basic (&iter_var,
++ DBUS_TYPE_BOOLEAN,
++ &value);
++
++ dbus_message_iter_close_container (&iter_struct_entry,
++ &iter_var);
++
++ dbus_message_iter_close_container (iter_struct, &iter_struct_entry);
++}
++
++static void
++add_param_string (DBusMessageIter *iter_struct,
++ const char *key,
++ const char *value)
++{
++ DBusMessageIter iter_struct_entry;
++ DBusMessageIter iter_var;
++
++ dbus_message_iter_open_container (iter_struct,
++ DBUS_TYPE_STRUCT,
++ NULL,
++ &iter_struct_entry);
++
++ dbus_message_iter_append_basic (&iter_struct_entry,
++ DBUS_TYPE_STRING,
++ &key);
++
++ dbus_message_iter_open_container (&iter_struct_entry,
++ DBUS_TYPE_VARIANT,
++ DBUS_TYPE_STRING_AS_STRING,
++ &iter_var);
++
++ dbus_message_iter_append_basic (&iter_var,
++ DBUS_TYPE_STRING,
++ &value);
++
++ dbus_message_iter_close_container (&iter_struct_entry,
++ &iter_var);
++
++ dbus_message_iter_close_container (iter_struct, &iter_struct_entry);
++}
++
++static int
++session_get_x11_display (DBusConnection *connection,
++ const char *ssid,
++ char **str)
++{
++ DBusError error;
++ DBusMessage *message;
++ DBusMessage *reply;
++ DBusMessageIter iter;
++ const char *value;
++
++ if (str != NULL) {
++ *str = NULL;
++ }
++
++ message = dbus_message_new_method_call (CK_NAME,
++ ssid,
++ CK_SESSION_INTERFACE,
++ "GetX11Display");
++ if (message == NULL) {
++ Debug ("ConsoleKit: Couldn't allocate the D-Bus message");
++ return FALSE;
++ }
++
++ dbus_error_init (&error);
++ reply = dbus_connection_send_with_reply_and_block (connection,
++ message,
++ -1, &error);
++ if (dbus_error_is_set (&error)) {
++ Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message);
++ reply = NULL;
++ }
++
++ dbus_connection_flush (connection);
++ dbus_message_unref (message);
++
++ if (reply == NULL) {
++ return FALSE;
++ }
++
++ dbus_message_iter_init (reply, &iter);
++ dbus_message_iter_get_basic (&iter, &value);
++ if (str != NULL) {
++ *str = strdup (value);
++ }
++ dbus_message_unref (reply);
++
++ return TRUE;
++}
++
++static int
++session_unlock (DBusConnection *connection,
++ const char *ssid)
++{
++ DBusError error;
++ DBusMessage *message;
++ DBusMessage *reply;
++
++ Debug ("ConsoleKit: Unlocking session %s", ssid);
++ message = dbus_message_new_method_call (CK_NAME,
++ ssid,
++ CK_SESSION_INTERFACE,
++ "Unlock");
++ if (message == NULL) {
++ Debug ("ConsoleKit: Couldn't allocate the D-Bus message");
++ return FALSE;
++ }
++
++ dbus_error_init (&error);
++ reply = dbus_connection_send_with_reply_and_block (connection,
++ message,
++ -1, &error);
++ dbus_message_unref (message);
++ dbus_message_unref (reply);
++ dbus_connection_flush (connection);
++
++ if (dbus_error_is_set (&error)) {
++ Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message);
++ return FALSE;
++ }
++
++ return TRUE;
++}
++
++/* from libhal */
++static char **
++get_path_array_from_iter (DBusMessageIter *iter,
++ int *num_elements)
++{
++ int count;
++ char **buffer;
++
++ count = 0;
++ buffer = (char **)malloc (sizeof (char *) * 8);
++
++ if (buffer == NULL)
++ goto oom;
++
++ buffer[0] = NULL;
++ while (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_OBJECT_PATH) {
++ const char *value;
++ char *str;
++
++ if ((count % 8) == 0 && count != 0) {
++ buffer = realloc (buffer, sizeof (char *) * (count + 8));
++ if (buffer == NULL)
++ goto oom;
++ }
++
++ dbus_message_iter_get_basic (iter, &value);
++ str = strdup (value);
++ if (str == NULL)
++ goto oom;
++
++ buffer[count] = str;
++
++ dbus_message_iter_next (iter);
++ count++;
++ }
++
++ if ((count % 8) == 0) {
++ buffer = realloc (buffer, sizeof (char *) * (count + 1));
++ if (buffer == NULL)
++ goto oom;
++ }
++
++ buffer[count] = NULL;
++ if (num_elements != NULL)
++ *num_elements = count;
++ return buffer;
++
++oom:
++ LogWarn ("%s %d : error allocating memory\n", __FILE__, __LINE__);
++ return NULL;
++
++}
++
++static char **
++get_sessions_for_user (DBusConnection *connection,
++ const char *user,
++ const char *x11_display)
++{
++ DBusError error;
++ DBusMessage *message;
++ DBusMessage *reply;
++ DBusMessageIter iter;
++ DBusMessageIter iter_reply;
++ DBusMessageIter iter_array;
++ struct passwd *pwent;
++ char **sessions;
++
++ sessions = NULL;
++ message = NULL;
++ reply = NULL;
++
++ pwent = getpwnam (user);
++
++ dbus_error_init (&error);
++ message = dbus_message_new_method_call (CK_NAME,
++ CK_MANAGER_PATH,
++ CK_MANAGER_INTERFACE,
++ "GetSessionsForUser");
++ if (message == NULL) {
++ Debug ("ConsoleKit: Couldn't allocate the D-Bus message");
++ goto out;
++ }
++
++ dbus_message_iter_init_append (message, &iter);
++ dbus_message_iter_append_basic (&iter,
++ DBUS_TYPE_UINT32,
++ &pwent->pw_uid);
++
++ dbus_error_init (&error);
++ reply = dbus_connection_send_with_reply_and_block (connection,
++ message,
++ -1, &error);
++ dbus_connection_flush (connection);
++
++ if (dbus_error_is_set (&error)) {
++ Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message);
++ goto out;
++ }
++
++ if (reply == NULL) {
++ Debug ("ConsoleKit: No reply for GetSessionsForUser");
++ goto out;
++ }
++
++ dbus_message_iter_init (reply, &iter_reply);
++ if (dbus_message_iter_get_arg_type (&iter_reply) != DBUS_TYPE_ARRAY) {
++ Debug ("ConsoleKit: Wrong reply for GetSessionsForUser - expecting an array.");
++ goto out;
++ }
++
++ dbus_message_iter_recurse (&iter_reply, &iter_array);
++ sessions = get_path_array_from_iter (&iter_array, NULL);
++
++ out:
++ if (message != NULL) {
++ dbus_message_unref (message);
++ }
++ if (reply != NULL) {
++ dbus_message_unref (reply);
++ }
++
++ return sessions;
++}
++
++void
++unlock_ck_session (const char *user,
++ const char *x11_display)
++{
++ DBusError error;
++ DBusConnection *connection;
++ char **sessions;
++ int i;
++
++ Debug ("ConsoleKit: Unlocking session for %s on %s", user, x11_display);
++
++ dbus_error_init (&error);
++ connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
++ if (connection == NULL) {
++ Debug ("ConsoleKit: Failed to connect to the D-Bus daemon: %s", error.message);
++ dbus_error_free (&error);
++ return;
++ }
++
++ sessions = get_sessions_for_user (connection, user, x11_display);
++ if (sessions == NULL || sessions[0] == NULL) {
++ Debug ("ConsoleKit: no sessions found");
++ return;
++ }
++
++ for (i = 0; sessions[i] != NULL; i++) {
++ char *ssid;
++ char *xdisplay;
++
++ ssid = sessions[i];
++ session_get_x11_display (connection, ssid, &xdisplay);
++ Debug ("ConsoleKit: session %s has DISPLAY %s", ssid, xdisplay);
++
++ if (xdisplay != NULL
++ && x11_display != NULL
++ && strcmp (xdisplay, x11_display) == 0) {
++ int res;
++
++ res = session_unlock (connection, ssid);
++ if (! res) {
++ LogError ("ConsoleKit: Unable to unlock %s", ssid);
++ }
++ }
++
++ free (xdisplay);
++ }
++
++ freeStrArr (sessions);
++}
++
++char *
++open_ck_session (struct passwd *pwent,
++ struct display *d)
++{
++ DBusConnection *connection;
++ DBusError error;
++ DBusMessage *message;
++ DBusMessage *reply;
++ DBusMessageIter iter;
++ DBusMessageIter iter_struct;
++ char *cookie;
++
++ cookie = NULL;
++
++ Debug ("ConsoleKit: Opening session for %s", pwent->pw_name);
++
++ dbus_error_init (&error);
++ connection = dbus_bus_get_private (DBUS_BUS_SYSTEM, &error);
++ private_connection = connection;
++
++ if (connection == NULL) {
++ Debug ("ConsoleKit: Failed to connect to the D-Bus daemon: %s", error.message);
++ dbus_error_free (&error);
++ return NULL;
++ }
++
++ dbus_connection_set_exit_on_disconnect (connection, FALSE);
++ /* FIXME: What to do about these?
++ dbus_connection_set_watch_functions( connection,
++ dbusAddWatch,
++ dbusRemoveWatch,
++ dbusToggleWatch,
++ data, 0 );
++ dbus_connection_set_timeout_functions( connection,
++ dbusAddTimeout,
++ dbusRemoveTimeout,
++ dbusToggleTimeout,
++ data, 0 );
++ dbus_connection_set_wakeup_main_function( connection,
++ dbusWakeupMain,
++ data, 0 ); */
++
++ dbus_error_init (&error);
++ message = dbus_message_new_method_call (CK_NAME,
++ CK_MANAGER_PATH,
++ CK_MANAGER_INTERFACE,
++ "OpenSessionWithParameters");
++ if (message == NULL) {
++ Debug ("ConsoleKit: Couldn't allocate the D-Bus message");
++ return NULL;
++ }
++
++ dbus_message_iter_init_append (message, &iter);
++ dbus_message_iter_open_container (&iter,
++ DBUS_TYPE_ARRAY,
++ DBUS_STRUCT_BEGIN_CHAR_AS_STRING
++ DBUS_TYPE_STRING_AS_STRING
++ DBUS_TYPE_VARIANT_AS_STRING
++ DBUS_STRUCT_END_CHAR_AS_STRING,
++ &iter_struct);
++
++ add_param_int (&iter_struct, "user", pwent->pw_uid);
++ add_param_string (&iter_struct, "x11-display", d->name);
++ add_param_boolean (&iter_struct, "is-local", ((d->displayType & d_location) == dLocal));
++#ifdef XDMCP
++ if (d->status == remoteLogin && !((d->displayType & d_location) == dLocal)) {
++ add_param_string (&iter_struct, "remote-host-name", d->remoteHost);
++ }
++#endif
++
++#ifdef HAVE_VTS
++ if (d->serverVT > 0) {
++ char device[20];
++
++ /* FIXME: how does xorg construct this */
++ sprintf(device, "/dev/tty%d", d->serverVT);
++ add_param_string (&iter_struct, "x11-display-device", device);
++ }
++#endif
++
++ dbus_message_iter_close_container (&iter, &iter_struct);
++
++ reply = dbus_connection_send_with_reply_and_block (connection,
++ message,
++ -1, &error);
++ if (dbus_error_is_set (&error)) {
++ Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message);
++ reply = NULL;
++ }
++
++ dbus_connection_flush (connection);
++
++ dbus_message_unref (message);
++ dbus_error_free (&error);
++
++ if (reply != NULL) {
++ const char *value;
++
++ dbus_message_iter_init (reply, &iter);
++ dbus_message_iter_get_basic (&iter, &value);
++ cookie = strdup (value);
++ dbus_message_unref (reply);
++ }
++
++ return cookie;
++}
++
++void
++close_ck_session (const char *cookie)
++{
++ DBusError error;
++ DBusMessage *message;
++ DBusMessage *reply;
++ DBusMessageIter iter;
++
++ if (cookie == NULL) {
++ return;
++ }
++
++ if (private_connection == NULL) {
++ return;
++ }
++
++ dbus_error_init (&error);
++ message = dbus_message_new_method_call (CK_NAME,
++ CK_MANAGER_PATH,
++ CK_MANAGER_INTERFACE,
++ "CloseSession");
++ if (message == NULL) {
++ Debug ("ConsoleKit: Couldn't allocate the D-Bus message");
++ return;
++ }
++
++ dbus_message_iter_init_append (message, &iter);
++ dbus_message_iter_append_basic (&iter,
++ DBUS_TYPE_STRING,
++ &cookie);
++
++ reply = dbus_connection_send_with_reply_and_block (private_connection,
++ message,
++ -1, &error);
++ if (dbus_error_is_set (&error)) {
++ Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message);
++ reply = NULL;
++ }
++
++ dbus_connection_flush (private_connection);
++
++ dbus_message_unref (message);
++ dbus_error_free (&error);
++
++ dbus_connection_close (private_connection);
++ private_connection = NULL;
++}
+Index: kdm/backend/consolekit.h
+===================================================================
+--- /dev/null
++++ kdm/backend/consolekit.h
+@@ -0,0 +1,36 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
++ *
++ * Copyright (C) 2006 William Jon McCann <mccann@jhu.edu>
++ * Copyright (C) 2007 Kevin Kofler <Kevin@tigcc.ticalc.org>
++ *
++ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ *
++ */
++
++
++#ifndef __CONSOLE_KIT_H
++#define __CONSOLE_KIT_H
++
++#include <pwd.h>
++
++struct display;
++
++char * open_ck_session (struct passwd *pwent,
++ struct display *display);
++void close_ck_session (const char *cookie);
++void unlock_ck_session (const char *user,
++ const char *x11_display);
++
++#endif /* __CONSOLE_KIT_H */
+Index: kdm/backend/dm.h
+===================================================================
+--- kdm/backend/dm.h.orig
++++ kdm/backend/dm.h
+@@ -37,6 +37,8 @@ from the copyright holder.
+ #ifndef _DM_H_
+ #define _DM_H_ 1
+
++#define WITH_CONSOLE_KIT
++
+ #include "greet.h"
+ #include <config.ci>
+
+@@ -476,7 +478,11 @@ char **GRecvArgv( void );
+ #define GCONV_BINARY 5
+ typedef char *(*GConvFunc)( int what, const char *prompt );
+ int Verify( GConvFunc gconv, int rootok );
++#ifdef WITH_CONSOLE_KIT
++int StartClient( const char *ck_session_cookie );
++#else
+ int StartClient( void );
++#endif
+ void SessionExit( int status ) ATTR_NORETURN;
+ int ReadDmrc( void );
+ extern char **userEnviron, **systemEnviron;
+Index: kdm/backend/Imakefile
+===================================================================
+--- kdm/backend/Imakefile.orig
++++ kdm/backend/Imakefile
+@@ -155,13 +155,13 @@ PROCTITLE_DEFINES = -DHAS_SETPROCTITLE
+ netaddr.c reset.c resource.c protodpy.c policy.c \
+ session.c socket.c streams.c util.c xdmcp.c \
+ process.c mitauth.c \
+- genauth.c access.c choose.c \
++ genauth.c access.c choose.c consolekit.c \
+ $(XDMAUTHSRCS) $(RPCSRCS) $(KRB5SRCS)
+ COMMOBJS = auth.o daemon.o server.o dpylist.o dm.o error.o \
+ netaddr.o reset.o resource.o protodpy.o policy.o \
+ session.o socket.o streams.o util.o xdmcp.o \
+ process.o mitauth.o \
+- genauth.o access.o choose.o \
++ genauth.o access.o choose.o consolekit.o \
+ $(XDMAUTHOBJS) $(RPCOBJS) $(KRB5OBJS)
+
+ SRCS1 = $(COMMSRCS) client.c
+Index: kdm/backend/Makefile.am
+===================================================================
+--- kdm/backend/Makefile.am.orig
++++ kdm/backend/Makefile.am
+@@ -1,6 +1,6 @@
+ # forcibly remove thread-related defines & flags
+ AUTOMAKE_OPTIONS = foreign
+-AM_CPPFLAGS = $(USER_INCLUDES) $(X_INCLUDES) $(KRB4_INCS) $(KRB5_INCS) -I.. -I../..
++AM_CPPFLAGS = -DWITH_CONSOLE_KIT=1 $(USER_INCLUDES) $(X_INCLUDES) $(KRB4_INCS) $(KRB5_INCS) $(DBUS_INCS) -I.. -I../..
+
+ bin_PROGRAMS = kdm
+ kdm_SOURCES = \
+@@ -9,6 +9,7 @@ kdm_SOURCES = \
+ bootman.c \
+ choose.c \
+ client.c \
++ consolekit.c \
+ ctrl.c \
+ daemon.c \
+ dm.c \
+@@ -37,7 +38,7 @@ kdm_SOURCES = \
+ kdm_LDFLAGS = $(USER_LDFLAGS) $(X_LDFLAGS) $(X_RPATH) $(KRB4_RPATH) $(KRB5_RPATH)
+ kdm_LDADD = $(LIB_X11) -lXau $(LIBXDMCP) $(PASSWDLIBS) \
+ $(LIB_LIBS) $(KRB4_LIBS) $(KRB5_LIBS) $(LIBSOCKET) $(LIBRESOLV) \
+- $(LIBUCB) $(LIBUTIL) $(LIBPOSIX4)
++ $(DBUS_LIBS) $(LIBUCB) $(LIBUTIL) $(LIBPOSIX4)
+
+ EXTRA_DIST = printf.c
+
+Index: kdm/backend/session.c
+===================================================================
+--- kdm/backend/session.c.orig
++++ kdm/backend/session.c
+@@ -45,6 +45,10 @@ from the copyright holder.
+ #include <ctype.h>
+ #include <signal.h>
+
++#ifdef WITH_CONSOLE_KIT
++#include "consolekit.h"
++#endif
++
+ struct display *td;
+ const char *td_setup = "auto";
+
+@@ -530,6 +534,9 @@ ManageSession( struct display *d )
+ int ex, cmd;
+ volatile int clientPid = 0;
+ volatile Time_t tdiff = 0;
++#ifdef WITH_CONSOLE_KIT
++ char *ck_session_cookie;
++#endif
+
+ td = d;
+ Debug( "ManageSession %s\n", d->name );
+@@ -626,7 +633,12 @@ ManageSession( struct display *d )
+ if (td_setup)
+ SetupDisplay( td_setup );
+
++#ifdef WITH_CONSOLE_KIT
++ ck_session_cookie = open_ck_session (getpwnam(curuser), d);
++ if (!(clientPid = StartClient(ck_session_cookie))) {
++#else
+ if (!(clientPid = StartClient())) {
++#endif
+ LogError( "Client start failed\n" );
+ SessionExit( EX_NORMAL ); /* XXX maybe EX_REMANAGE_DPY? -- enable in dm.c! */
+ }
+@@ -648,6 +660,14 @@ ManageSession( struct display *d )
+ catchTerm( SIGTERM );
+ }
+ }
++
++#ifdef WITH_CONSOLE_KIT
++ if (ck_session_cookie != NULL) {
++ close_ck_session (ck_session_cookie);
++ free (ck_session_cookie);
++ }
++#endif
++
+ /*
+ * Sometimes the Xsession somehow manages to exit before
+ * a server crash is noticed - so we sleep a bit and wait
+Index: kdm/configure.in.in
+===================================================================
+--- kdm/configure.in.in.orig
++++ kdm/configure.in.in
+@@ -240,4 +240,51 @@ if test "x$with_kdm_xconsole" = xyes; th
+ AC_DEFINE(WITH_KDM_XCONSOLE, 1, [Build kdm with built-in xconsole])
+ fi
+
++########### Check for DBus
++
++ AC_MSG_CHECKING(for DBus)
++
++ dbus_inc=NOTFOUND
++ dbus_lib=NOTFOUND
++ dbus=NOTFOUND
++
++ search_incs="$kde_includes $kde_extra_includes /usr/include /usr/include/dbus-1.0 /usr/local/include /usr/local/include/dbus-1.0"
++ AC_FIND_FILE(dbus/dbus.h, $search_incs, dbus_incdir)
++
++ search_incs_arch_deps="$kde_includes $kde_extra_includes /usr/lib$kdelibsuff/dbus-1.0/include /usr/local/lib$kdelibsuff/dbus-1.0/include"
++ AC_FIND_FILE(dbus/dbus-arch-deps.h, $search_incs_arch_deps, dbus_incdir_arch_deps)
++
++ if test -r $dbus_incdir/dbus/dbus.h && test -r $dbus_incdir_arch_deps/dbus/dbus-arch-deps.h ; then
++ DBUS_INCS="-I$dbus_incdir -I$dbus_incdir_arch_deps"
++ dbus_inc=FOUND
++ fi
++
++ search_libs="$kde_libraries $kde_extra_libs /usr/lib$kdelibsuff /usr/local/lib$kdelibsuff"
++ AC_FIND_FILE(libdbus-1.so, $search_libs, dbus_libdir)
++
++ if test -r $dbus_libdir/libdbus-1.so ; then
++ DBUS_LIBS="-L$dbus_libdir -ldbus-1"
++ dbus_lib=FOUND
++ fi
++
++ if test $dbus_inc != FOUND || test $dbus_lib != FOUND ; then
++ KDE_PKG_CHECK_MODULES( DBUS, "dbus-1", [ DBUS_INCS=$DBUS_CFLAGS; dbus_inc=FOUND; dbus_lib=FOUND; ] , AC_MSG_RESULT( Nothing found on PKG_CONFIG_PATH ) )
++ fi
++
++ dbus_bus_var=`pkg-config --variable=system_bus_default_address dbus-1 2>/dev/null`
++ if test -z "$dbus_bus_var"; then
++ dbus_bus_var="unix:path=/var/run/dbus/system_bus_socket"
++ fi
++ AC_DEFINE_UNQUOTED(DBUS_SYSTEM_BUS, "$dbus_bus_var", [Define the unix domain path for dbus system bus])
++
++ if test $dbus_inc = FOUND && test $dbus_lib = FOUND ; then
++ AC_MSG_RESULT(headers $DBUS_INCS libraries $DBUS_LIBS)
++ dbus=FOUND
++ else
++ AC_MSG_RESULT(searched but not found)
++ fi
++
++ AC_SUBST(DBUS_INCS)
++ AC_SUBST(DBUS_LIBS)
++
+ dnl AC_OUTPUT(kdm/kfrontend/sessions/kde.desktop)
diff --git a/opensuse/tdebase/kdm-cope-with-new-grub.diff b/opensuse/tdebase/kdm-cope-with-new-grub.diff
new file mode 100644
index 000000000..cf28cf9be
--- /dev/null
+++ b/opensuse/tdebase/kdm-cope-with-new-grub.diff
@@ -0,0 +1,27 @@
+Index: kdm/backend/bootman.c
+===================================================================
+--- kdm/backend/bootman.c.orig
++++ kdm/backend/bootman.c
+@@ -132,19 +132,14 @@ setGrub( const char *opt, SdRec *sdr )
+ static void
+ commitGrub( void )
+ {
+- FILE *f;
+- int pid;
+- static const char *args[] = { 0, "--batch", "--no-floppy", 0 };
++ char buffer[PATH_MAX];
+
+ if (sdRec.bmstamp != mTime( GRUB_MENU ) &&
+ setGrub( sdRec.osname, &sdRec ) != BO_OK)
+ return;
+
+- args[0] = grub;
+- if ((f = pOpen( (char **)args, 'w', &pid ))) {
+- fprintf( f, "savedefault --default=%d --once\n", sdRec.osindex );
+- pClose( f, pid );
+- }
++ snprintf(buffer, PATH_MAX, "/usr/sbin/grubonce %d", sdRec.osindex);
++ system(buffer);
+ }
+
+ static char *lilo;
diff --git a/opensuse/tdebase/kdm-make_it_cool.diff b/opensuse/tdebase/kdm-make_it_cool.diff
new file mode 100644
index 000000000..fb1f5b076
--- /dev/null
+++ b/opensuse/tdebase/kdm-make_it_cool.diff
@@ -0,0 +1,1534 @@
+Index: kdm/kfrontend/kdm_greet.c
+===================================================================
+--- kdm/kfrontend/kdm_greet.c.orig
++++ kdm/kfrontend/kdm_greet.c
+@@ -44,8 +44,8 @@ Foundation, Inc., 51 Franklin Street, Fi
+ # include <sched.h>
+ #endif
+
+-#if defined(HAVE_XTEST) || defined(HAVE_XKB)
+ # include <X11/Xlib.h>
++#if defined(HAVE_XTEST) || defined(HAVE_XKB)
+ # include <X11/keysym.h>
+ #endif
+
+Index: kdm/kfrontend/themer/kdmrect.h
+===================================================================
+--- kdm/kfrontend/themer/kdmrect.h.orig
++++ kdm/kfrontend/themer/kdmrect.h
+@@ -36,6 +36,7 @@ class KdmRect : public KdmItem {
+
+ public:
+ KdmRect( KdmItem *parent, const QDomNode &node, const char *name = 0 );
++ KdmRect( QWidget *parent, const QDomNode &node, const char *name = 0 );
+
+ protected:
+ // draw the rect
+@@ -54,8 +55,9 @@ protected:
+ bool hasBorder;
+ } rect;
+
+-// virtual void setWidget( QWidget *widget );
++ virtual void setWidget( QWidget *widget );
+ // virtual void setLayoutItem( QLayoutItem *item );
++ void init( const QDomNode &node, const char *name );
+
+ private:
+ void setAttribs( QWidget *widget );
+Index: kdm/kfrontend/themer/kdmitem.h
+===================================================================
+--- kdm/kfrontend/themer/kdmitem.h.orig
++++ kdm/kfrontend/themer/kdmitem.h
+@@ -90,6 +90,8 @@ public:
+ * Item constructor and destructor
+ */
+ KdmItem( KdmItem *parent, const QDomNode &node = QDomNode(), const char *name = 0 );
++ KdmItem( QWidget *parent, const QDomNode &node = QDomNode(), const char *name = 0 ); // for the root
++
+ virtual ~KdmItem();
+
+ /**
+@@ -151,6 +153,7 @@ public:
+
+ KdmItem *findNode( const QString &id ) const;
+ virtual void setWidget( QWidget *widget );
++ QWidget *widget() const { return myWidget; }
+ virtual void setLayoutItem( QLayoutItem *item );
+
+ virtual void hide( bool force = false );
+@@ -160,6 +163,9 @@ public:
+ bool isExplicitlyHidden() const { return isShown == ExplicitlyHidden; }
+ QRect rect() const { return area; }
+
++ QWidget *parentWidget() const;
++ QString getId() const { return id; }
++
+ signals:
+ void needUpdate( int x, int y, int w, int h );
+ void activated( const QString &id );
+@@ -237,6 +243,7 @@ protected:
+ void parseColor( const QString &, QColor & );
+
+ void inheritFromButton( KdmItem *button );
++ void init( const QDomNode &node = QDomNode(), const char *name = 0 );
+
+ QString itemType, id;
+ QValueList<KdmItem *> m_children;
+Index: kdm/kfrontend/themer/kdmpixmap.h
+===================================================================
+--- kdm/kfrontend/themer/kdmpixmap.h.orig
++++ kdm/kfrontend/themer/kdmpixmap.h
+@@ -61,9 +61,10 @@ protected:
+ } pixmap;
+
+ private:
+- // Method to load the pixmap given by the theme
+- void loadPixmap( const QString &fileName, QPixmap &p, QString &path );
++ // Method to load the pixmap path given by the theme
++ QString fullPath( const QString &fileName );
+ void renderSvg( PixmapStruct::PixmapClass *pClass, const QRect &area );
++ void loadPixmap( PixmapStruct::PixmapClass *pClass );
+ };
+
+ #endif
+Index: kdm/kfrontend/themer/kdmlabel.h
+===================================================================
+--- kdm/kfrontend/themer/kdmlabel.h.orig
++++ kdm/kfrontend/themer/kdmlabel.h
+@@ -67,6 +67,7 @@ protected:
+
+ public slots:
+ void update();
++ void slotAccel();
+
+ private:
+ /* Method to lookup the caption associated with an item */
+@@ -76,6 +77,10 @@ private:
+ QString lookupText( const QString &t );
+
+ QString cText;
++ int cAccel;
++ QAccel *myAccel;
++
++ void setTextInt(const QString &);
+ };
+
+ #endif
+Index: kdm/kfrontend/themer/kdmthemer.cpp
+===================================================================
+--- kdm/kfrontend/themer/kdmthemer.cpp.orig
++++ kdm/kfrontend/themer/kdmthemer.cpp
+@@ -36,11 +36,13 @@
+
+ #include <qfile.h>
+ #include <qfileinfo.h>
+-//#include <qtimer.h> // animation timer - TODO
++#include <qtimer.h> // animation timer - TODO
+ #include <qobjectlist.h>
+ #include <qpainter.h>
+ #include <qwidget.h>
+ #include <qregion.h>
++#include <qlineedit.h>
++#include <qapplication.h>
+
+ #include <unistd.h>
+
+@@ -72,7 +74,8 @@ KdmThemer::KdmThemer( const QString &_fi
+ return;
+ }
+ // Set the root (screen) item
+- rootItem = new KdmRect( 0, QDomNode(), "kdm root" );
++ rootItem = new KdmRect( parent, QDomNode(), "kdm root" );
++
+ connect( rootItem, SIGNAL(needUpdate( int, int, int, int )),
+ widget(), SLOT(update( int, int, int, int )) );
+
+@@ -82,6 +85,9 @@ KdmThemer::KdmThemer( const QString &_fi
+ generateItems( rootItem );
+
+ connect( rootItem, SIGNAL(activated( const QString & )), SIGNAL(activated( const QString & )) );
++ connect( rootItem, SIGNAL(activated( const QString & )), SLOT(slotActivated( const QString & )) );
++
++ QTimer::singleShot(800, this, SLOT(slotPaintRoot()));
+
+ /* *TODO*
+ // Animation timer
+@@ -151,7 +157,7 @@ KdmThemer::widgetEvent( QEvent *e )
+ case QEvent::Paint:
+ {
+ QRect paintRect = static_cast<QPaintEvent *>(e)->rect();
+- kdDebug() << "paint on: " << paintRect << endl;
++ kdDebug() << timestamp() << " paint on: " << paintRect << endl;
+
+ if (!backBuffer)
+ backBuffer = new QPixmap( widget()->size() );
+@@ -195,7 +201,7 @@ KdmThemer::generateItems( KdmItem *paren
+
+ // Get its tag, and check it's correct ("greeter")
+ if (theme.tagName() != "greeter") {
+- kdDebug() << "This does not seem to be a correct theme file." << endl;
++ kdDebug() << timestamp() << " This does not seem to be a correct theme file." << endl;
+ return;
+ }
+ // Get the list of child nodes
+@@ -214,6 +220,13 @@ KdmThemer::generateItems( KdmItem *paren
+ if (tagName == "item") {
+ if (!willDisplay( subnode ))
+ continue;
++ QString id = el.attribute("id");
++ if (id.startsWith("plugin-specific-")) {
++ id = id.mid(strlen("plugin-specific-"));
++ if (!_pluginsLogin.contains(id))
++ continue;
++ }
++
+ // It's a new item. Draw it
+ QString type = el.attribute( "type" );
+
+@@ -225,13 +238,11 @@ KdmThemer::generateItems( KdmItem *paren
+ newItem = new KdmPixmap( parent, subnode );
+ else if (type == "rect")
+ newItem = new KdmRect( parent, subnode );
+- else if (type == "entry") {
++ else if (type == "entry" || type == "list") {
+ newItem = new KdmRect( parent, subnode );
+ newItem->setType( type );
+ }
+ // newItem = new KdmEntry( parent, subnode );
+- //else if (type=="list")
+- // newItem = new KdmList( parent, subnode );
+ else if (type == "svg")
+ newItem = new KdmPixmap( parent, subnode );
+ if (newItem) {
+@@ -287,6 +298,11 @@ bool KdmThemer::willDisplay( const QDomN
+ #endif
+ if (type == "halt" || type == "reboot")
+ return _allowShutdown != SHUT_NONE;
++ else if (type == "userlist")
++ return _userList;
++ else if ( type == "!userlist" )
++ return !_userList;
++
+ // if (type == "system")
+ // return true;
+
+@@ -301,7 +317,7 @@ KdmThemer::showStructure( QObject *obj )
+ const QObjectList *wlist = obj->children();
+ static int counter = 0;
+ if (counter == 0)
+- kdDebug() << "\n\n<======= Widget tree =================" << endl;
++ kdDebug() << timestamp() << " \n\n<======= Widget tree =================" << endl;
+ if (wlist) {
+ counter++;
+ QObjectListIterator it( *wlist );
+@@ -323,7 +339,46 @@ KdmThemer::showStructure( QObject *obj )
+ counter--;
+ }
+ if (counter == 0)
+- kdDebug() << "\n\n<======= Widget tree =================\n\n" << endl;
++ kdDebug() << timestamp() << " \n\n<======= Widget tree =================\n\n" << endl;
++}
++
++void
++KdmThemer::slotActivated( const QString &id )
++{
++ QString toactivate;
++ if (id == "username-label")
++ toactivate = "user-entry";
++ else if (id == "password-label")
++ toactivate = "pw-entry";
++ else
++ return;
++
++ KdmItem *item = findNode(toactivate);
++ if (!item || !item->widget())
++ return;
++
++ item->widget()->setFocus();
++ QLineEdit *le = (QLineEdit*)item->widget()->qt_cast("QLineEdit");
++ if (le)
++ le->selectAll();
++}
++
++void
++KdmThemer::slotPaintRoot()
++{
++ KdmItem *back_item = findNode("background");
++ if (!back_item)
++ return;
++
++ QRect screen = QApplication::desktop()->screenGeometry(0);
++ QPixmap pm(screen.size());
++
++ QPainter painter( &pm, true );
++ back_item->paint( &painter, back_item->rect());
++ painter.end();
++
++ QApplication::desktop()->screen()->setErasePixmap(pm);
++ QApplication::desktop()->screen()->erase();
+ }
+
+ #include "kdmthemer.moc"
+Index: kdm/kfrontend/themer/kdmthemer.h
+===================================================================
+--- kdm/kfrontend/themer/kdmthemer.h.orig
++++ kdm/kfrontend/themer/kdmthemer.h
+@@ -80,6 +80,10 @@ public:
+ signals:
+ void activated( const QString &id );
+
++protected slots:
++ void slotActivated( const QString &id );
++ void slotPaintRoot();
++
+ private:
+ /*
+ * Our display mode (e.g. console, remote, ...)
+Index: kdm/kfrontend/themer/kdmlayout.cpp
+===================================================================
+--- kdm/kfrontend/themer/kdmlayout.cpp.orig
++++ kdm/kfrontend/themer/kdmlayout.cpp
+@@ -20,6 +20,7 @@
+ */
+
+ #include "kdmlayout.h"
++#include "kdmconfig.h"
+ #include "kdmitem.h"
+
+ #include <kdebug.h>
+@@ -35,11 +36,11 @@ KdmLayoutFixed::KdmLayoutFixed( const QD
+ void
+ KdmLayoutFixed::update( const QRect &parentGeometry, bool force )
+ {
+- kdDebug() << "KdmLayoutFixed::update " << parentGeometry << endl;
++ kdDebug() << timestamp() << " KdmLayoutFixed::update " << parentGeometry << endl;
+
+ // I can't layout children if the parent rectangle is not valid
+ if (parentGeometry.width() < 0 || parentGeometry.height() < 0) {
+- kdDebug() << "invalid\n";
++ kdDebug() << timestamp() << " invalid\n";
+ return;
+ }
+ // For each child in list I ask their hinted size and set it!
+@@ -102,7 +103,7 @@ KdmLayoutBox::update( const QRect &paren
+ childrenRect.setTop( childrenRect.top() + height + box.spacing );
+ } else {
+ QRect temp( childrenRect.left(), childrenRect.top(), width, childrenRect.height() );
+- kdDebug() << "placement " << *it << " " << temp << " " << (*it)->placementHint( temp ) << endl;
++ kdDebug() << timestamp() << " placement " << *it << " " << temp << " " << (*it)->placementHint( temp ) << endl;
+ temp = (*it)->placementHint( temp );
+ (*it)->setGeometry( temp, force );
+ childrenRect.setLeft( childrenRect.left() + width + box.spacing );
+@@ -125,7 +126,7 @@ KdmLayoutBox::update( const QRect &paren
+ kdDebug() << this << " placementHint " << *it << " " << temp << " " << itemRect << endl;
+ temp.setWidth( itemRect.width() );
+ childrenRect.setLeft( childrenRect.left() + itemRect.size().width() + box.spacing );
+- kdDebug() << "childrenRect after " << *it << " " << childrenRect << endl;
++ kdDebug() << timestamp() << " childrenRect after " << *it << " " << childrenRect << endl;
+ }
+ itemRect = (*it)->placementHint( temp );
+ kdDebug() << this << " placementHint2 " << *it << " " << temp << " " << itemRect << endl;
+Index: kdm/kfrontend/themer/kdmrect.cpp
+===================================================================
+--- kdm/kfrontend/themer/kdmrect.cpp.orig
++++ kdm/kfrontend/themer/kdmrect.cpp
+@@ -33,6 +33,18 @@
+ KdmRect::KdmRect( KdmItem *parent, const QDomNode &node, const char *name )
+ : KdmItem( parent, node, name )
+ {
++ init( node, name );
++}
++
++KdmRect::KdmRect( QWidget *parent, const QDomNode &node, const char *name )
++ : KdmItem( parent, node, name )
++{
++ init( node, name );
++}
++
++void
++KdmRect::init( const QDomNode &node, const char * )
++{
+ itemType = "rect";
+
+ // Set default values for rect (note: strings are already Null)
+@@ -137,13 +149,6 @@ KdmRect::recursiveSetAttribs( QLayoutIte
+ }
+
+ void
+-KdmRect::setWidget( QWidget *widget )
+-{
+- KdmItem::setWidget( widget );
+- setAttribs( widget );
+-}
+-
+-void
+ KdmRect::setLayoutItem( QLayoutItem *item )
+ {
+ KdmItem::setLayoutItem( item );
+@@ -151,4 +156,17 @@ KdmRect::setLayoutItem( QLayoutItem *ite
+ }
+ */
+
++void
++KdmRect::setWidget( QWidget *widget )
++{
++ if ( rect.normal.color.isValid() && widget )
++ {
++ QPalette p = widget->palette();
++ p.setColor( QPalette::Normal, QColorGroup::Text, rect.normal.color );
++ widget->setPalette(p);
++ }
++ KdmItem::setWidget( widget );
++ //setAttribs( widget );
++}
++
+ #include "kdmrect.moc"
+Index: kdm/kfrontend/themer/kdmitem.cpp
+===================================================================
+--- kdm/kfrontend/themer/kdmitem.cpp.orig
++++ kdm/kfrontend/themer/kdmitem.cpp
+@@ -23,10 +23,11 @@
+ * Generic Kdm Item
+ */
+
+-//#define DRAW_OUTLINE 1 // for debugging only
++// #define DRAW_OUTLINE 1 // for debugging only
+
+ #include "kdmitem.h"
+ #include "kdmlayout.h"
++#include "kdmconfig.h"
+
+ #include <kglobal.h>
+ #include <kdebug.h>
+@@ -35,9 +36,7 @@
+ #include <qwidget.h>
+ #include <qlayout.h>
+ #include <qimage.h>
+-#ifdef DRAW_OUTLINE
+-# include <qpainter.h>
+-#endif
++#include <qpainter.h>
+
+ KdmItem::KdmItem( KdmItem *parent, const QDomNode &node, const char *name )
+ : QObject( parent, name )
+@@ -48,6 +47,25 @@ KdmItem::KdmItem( KdmItem *parent, const
+ , myLayoutItem( 0 )
+ , buttonParent( 0 )
+ {
++ init(node, name);
++}
++
++
++KdmItem::KdmItem( QWidget *parent, const QDomNode &node, const char *name )
++ : QObject( parent, name )
++ , boxManager( 0 )
++ , fixedManager( 0 )
++ , image( 0 )
++ , myWidget( 0 )
++ , myLayoutItem( 0 )
++ , buttonParent( 0 )
++{
++ init(node, name);
++}
++
++void
++KdmItem::init( const QDomNode &node, const char * )
++{
+ // Set default layout for every item
+ currentManager = MNone;
+ pos.x = pos.y = 0;
+@@ -62,7 +80,7 @@ KdmItem::KdmItem( KdmItem *parent, const
+ state = Snormal;
+
+ // The "toplevel" node (the screen) is really just like a fixed node
+- if (!parent || !parent->inherits( "KdmItem" )) {
++ if (!parent() || !parent()->inherits( "KdmItem" )) {
+ setFixedLayout();
+ return;
+ }
+@@ -87,7 +105,7 @@ KdmItem::KdmItem( KdmItem *parent, const
+ id = tnode.toElement().attribute( "id", QString::number( (ulong)this, 16 ) );
+
+ // Tell 'parent' to add 'me' to its children
+- KdmItem *parentItem = static_cast<KdmItem *>( parent );
++ KdmItem *parentItem = static_cast<KdmItem *>( parent() );
+ parentItem->addChildItem( this );
+ }
+
+@@ -195,7 +213,7 @@ KdmItem::setWidget( QWidget *widget )
+ if (frame)
+ frame->setFrameStyle( QFrame::NoFrame );
+
+- myWidget->setGeometry(area);
++ setGeometry(area, true);
+
+ connect( myWidget, SIGNAL(destroyed()), SLOT(widgetGone()) );
+ }
+@@ -236,15 +254,21 @@ KdmItem::setGeometry( const QRect &newGe
+
+ area = newGeometry;
+
+- if (myWidget)
+- myWidget->setGeometry( newGeometry );
++ if (myWidget) {
++ QRect widGeo = newGeometry;
++ if ( widGeo.height() > myWidget->maximumHeight() ) {
++ widGeo.moveTop( widGeo.top() + ( widGeo.height() - myWidget->maximumHeight() ) / 2 );
++ widGeo.setHeight( myWidget->maximumHeight() );
++ }
++ myWidget->setGeometry( widGeo );
++ }
+ if (myLayoutItem)
+ myLayoutItem->setGeometry( newGeometry );
+
+ // recurr to all boxed children
+ if (boxManager && !boxManager->isEmpty())
+ boxManager->update( newGeometry, force );
+-
++
+ // recurr to all fixed children
+ if (fixedManager && !fixedManager->isEmpty())
+ fixedManager->update( newGeometry, force );
+@@ -258,8 +282,16 @@ KdmItem::paint( QPainter *p, const QRect
+ if (isHidden())
+ return;
+
+- if (myWidget || (myLayoutItem && myLayoutItem->widget()))
+- return;
++ if (myWidget || (myLayoutItem && myLayoutItem->widget())) {
++ // KListView because it's missing a Q_OBJECT
++ if ( myWidget && myWidget->isA( "KListView" ) ) {
++ QPixmap copy( myWidget->size() );
++ kdDebug() << myWidget->geometry() << " " << area << " " << myWidget->size() << endl;
++ bitBlt( &copy, QPoint( 0, 0), p->device(), myWidget->geometry(), Qt::CopyROP );
++ myWidget->setPaletteBackgroundPixmap( copy );
++ }
++ return;
++ }
+
+ if (area.intersects( rect )) {
+ QRect contentsRect = area.intersect( rect );
+@@ -280,6 +312,8 @@ KdmItem::paint( QPainter *p, const QRect
+ QValueList<KdmItem *>::Iterator it;
+ for (it = m_children.begin(); it != m_children.end(); ++it)
+ (*it)->paint( p, rect );
++
++
+ }
+
+ KdmItem *KdmItem::currentActive = 0;
+@@ -287,8 +321,11 @@ KdmItem *KdmItem::currentActive = 0;
+ void
+ KdmItem::mouseEvent( int x, int y, bool pressed, bool released )
+ {
++ if (isShown == ExplicitlyHidden)
++ return;
++
+ if (buttonParent && buttonParent != this) {
+- buttonParent->mouseEvent( x, y, pressed, released );
++ buttonParent->mouseEvent( x, y, pressed, released );
+ return;
+ }
+
+@@ -362,7 +399,8 @@ KdmItem::placementHint( const QRect &par
+ w = parentRect.width(),
+ h = parentRect.height();
+
+- kdDebug() << "KdmItem::placementHint parentRect=" << id << parentRect << " hintedSize=" << hintedSize << endl;
++ kdDebug() << timestamp() << " KdmItem::placementHint parentRect=" << parentRect << " hintedSize=" << hintedSize << endl;
++
+ // check if width or height are set to "box"
+ if (pos.wType == DTbox || pos.hType == DTbox) {
+ if (myLayoutItem || myWidget)
+@@ -372,7 +410,7 @@ KdmItem::placementHint( const QRect &par
+ return parentRect;
+ boxHint = boxManager->sizeHint();
+ }
+- kdDebug() << " => boxHint " << boxHint << endl;
++ kdDebug() << timestamp() << " boxHint " << boxHint << endl;
+ }
+
+ if (pos.xType == DTpixel)
+@@ -380,25 +418,25 @@ KdmItem::placementHint( const QRect &par
+ else if (pos.xType == DTnpixel)
+ x = parentRect.right() - pos.x;
+ else if (pos.xType == DTpercent)
+- x += int( parentRect.width() / 100.0 * pos.x );
++ x += qRound( parentRect.width() / 100.0 * pos.x );
+
+ if (pos.yType == DTpixel)
+ y += pos.y;
+ else if (pos.yType == DTnpixel)
+ y = parentRect.bottom() - pos.y;
+ else if (pos.yType == DTpercent)
+- y += int( parentRect.height() / 100.0 * pos.y );
++ y += qRound( parentRect.height() / 100.0 * pos.y );
+
+ if (pos.wType == DTpixel)
+ w = pos.width;
+ else if (pos.wType == DTnpixel)
+ w -= pos.width;
+ else if (pos.wType == DTpercent)
+- w = int( parentRect.width() / 100.0 * pos.width );
++ w = qRound( parentRect.width() / 100.0 * pos.width );
+ else if (pos.wType == DTbox)
+ w = boxHint.width();
+ else if (hintedSize.width() > 0)
+- w = hintedSize.width();
++ w = hintedSize.width();
+ else
+ w = 0;
+
+@@ -407,14 +445,22 @@ KdmItem::placementHint( const QRect &par
+ else if (pos.hType == DTnpixel)
+ h -= pos.height;
+ else if (pos.hType == DTpercent)
+- h = int( parentRect.height() / 100.0 * pos.height );
++ h = qRound( parentRect.height() / 100.0 * pos.height );
+ else if (pos.hType == DTbox)
+ h = boxHint.height();
+- else if (hintedSize.height() > 0)
+- h = hintedSize.height();
+- else
++ else if (hintedSize.height() > 0) {
++ if (w && pos.wType != DTnone)
++ h = (hintedSize.height() * w) / hintedSize.width();
++ else
++ h = hintedSize.height();
++ } else
+ h = 0;
+
++ // we choose to take the hinted size, but it's better to listen to the aspect ratio
++ if (pos.wType == DTnone && pos.hType != DTnone && h && w) {
++ w = qRound(float(hintedSize.width() * h) / hintedSize.height());
++ }
++
+ // defaults to center
+ int dx = -w / 2, dy = -h / 2;
+
+@@ -430,7 +476,7 @@ KdmItem::placementHint( const QRect &par
+ dx = -w;
+ }
+ // KdmItem *p = static_cast<KdmItem*>( parent() );
+- kdDebug() << "KdmItem::placementHint " << id << " x=" << x << " dx=" << dx << " w=" << w << " y=" << y << " dy=" << dy << " h=" << h << " " << parentRect << endl;
++ kdDebug() << timestamp() << " placementHint " << this << " x=" << x << " dx=" << dx << " w=" << w << " y=" << y << " dy=" << dy << " h=" << h << " " << parentRect << endl;
+ y += dy;
+ x += dx;
+
+@@ -529,4 +575,17 @@ KdmItem::setFixedLayout( const QDomNode
+ currentManager = MFixed;
+ }
+
++QWidget *
++KdmItem::parentWidget() const
++{
++ if (myWidget)
++ return myWidget;
++ if (!this->parent())
++ return 0;
++
++ if (parent()->qt_cast("QWidget"))
++ return (QWidget*)parent();
++ return ((KdmItem*)parent())->parentWidget();
++}
++
+ #include "kdmitem.moc"
+Index: kdm/kfrontend/themer/kdmpixmap.cpp
+===================================================================
+--- kdm/kfrontend/themer/kdmpixmap.cpp.orig
++++ kdm/kfrontend/themer/kdmpixmap.cpp
+@@ -22,6 +22,7 @@
+ #include <config.h>
+
+ #include "kdmpixmap.h"
++#include <kdmconfig.h>
+
+ #include <kimageeffect.h>
+ #ifdef HAVE_LIBART
+@@ -29,6 +30,7 @@
+ #endif
+
+ #include <kdebug.h>
++#include <kstandarddirs.h>
+
+ #include <qpainter.h>
+ #include <qpixmap.h>
+@@ -58,21 +60,28 @@ KdmPixmap::KdmPixmap( KdmItem *parent, c
+ QString tagName = el.tagName();
+
+ if (tagName == "normal") {
+- loadPixmap( el.attribute( "file", "" ), pixmap.normal.pixmap, pixmap.normal.fullpath );
++ pixmap.normal.fullpath = fullPath( el.attribute( "file", "" ) );
+ parseColor( el.attribute( "tint", "#ffffff" ), pixmap.normal.tint );
+ pixmap.normal.alpha = el.attribute( "alpha", "1.0" ).toFloat();
+ } else if (tagName == "active") {
+ pixmap.active.present = true;
+- loadPixmap( el.attribute( "file", "" ), pixmap.active.pixmap, pixmap.active.fullpath );
++ pixmap.active.fullpath = fullPath( el.attribute( "file", "" ) );
+ parseColor( el.attribute( "tint", "#ffffff" ), pixmap.active.tint );
+ pixmap.active.alpha = el.attribute( "alpha", "1.0" ).toFloat();
+ } else if (tagName == "prelight") {
+ pixmap.prelight.present = true;
+- loadPixmap( el.attribute( "file", "" ), pixmap.prelight.pixmap, pixmap.prelight.fullpath );
++ pixmap.prelight.fullpath = fullPath(el.attribute( "file", "" ) );
+ parseColor( el.attribute( "tint", "#ffffff" ), pixmap.prelight.tint );
+ pixmap.prelight.alpha = el.attribute( "alpha", "1.0" ).toFloat();
+ }
+ }
++
++ // look if we have to have the aspect ratio ready
++ if (((pos.wType == DTnone && pos.hType != DTnone) ||
++ (pos.wType != DTnone && pos.hType == DTnone) ||
++ (pos.wType == DTnone && pos.hType == DTnone)) &&
++ !pixmap.normal.fullpath.endsWith( ".svg" ))
++ loadPixmap( &pixmap.normal );
+ }
+
+ QSize
+@@ -100,19 +109,16 @@ KdmPixmap::setGeometry( const QRect &new
+ }
+
+
+-void
+-KdmPixmap::loadPixmap( const QString &fileName, QPixmap &map, QString &fullName )
++QString
++KdmPixmap::fullPath( const QString &fileName)
+ {
+- if (fileName.isEmpty())
+- return;
++ if (fileName.isEmpty())
++ return QString::null;
+
+- fullName = fileName;
++ QString fullName = fileName;
+ if (fullName.at( 0 ) != '/')
+ fullName = baseDir() + "/" + fileName;
+-
+- if (!fullName.endsWith( ".svg" )) // we delay it for svgs
+- if (!map.load( fullName ))
+- fullName = QString::null;
++ return fullName;
+ }
+
+ void
+@@ -140,6 +146,25 @@ KdmPixmap::renderSvg( PixmapStruct::Pixm
+ }
+
+ void
++KdmPixmap::loadPixmap( PixmapStruct::PixmapClass *pClass )
++{
++ QString fullpath = pClass->fullpath;
++
++ kdDebug() << timestamp() << " load " << fullpath << endl;
++ int index = fullpath.findRev('.');
++ QString ext = fullpath.right(fullpath.length() - index);
++ fullpath = fullpath.left(index);
++ kdDebug() << timestamp() << " ext " << ext << " " << fullpath << endl;
++ QString testpath = QString("-%1x%2").arg(area.width()).arg(area.height()) + ext;
++ kdDebug() << timestamp() << " testing for " << fullpath + testpath << endl;
++ if (KStandardDirs::exists(fullpath + testpath))
++ pClass->pixmap.load(fullpath + testpath);
++ else
++ pClass->pixmap.load( fullpath + ext );
++ kdDebug() << timestamp() << " done\n";
++}
++
++void
+ KdmPixmap::drawContents( QPainter *p, const QRect &r )
+ {
+ // choose the correct pixmap class
+@@ -149,12 +174,20 @@ KdmPixmap::drawContents( QPainter *p, co
+ if (state == Sprelight && pixmap.prelight.present)
+ pClass = &pixmap.prelight;
+
++ kdDebug() << "draw " << id << " " << pClass->pixmap.isNull() << endl;
++
+ if (pClass->pixmap.isNull()) {
+- if (pClass->fullpath.isEmpty()) // if neither is set, we're empty
++
++ if (pClass->fullpath.isEmpty()) // if neither is set, we're empty
+ return;
+-
+- kdDebug() << "renderSVG\n";
+- renderSvg( pClass, area );
++
++ if (!pClass->fullpath.endsWith( ".svg" ) ) {
++ loadPixmap(pClass);
++ } else {
++ kdDebug() << timestamp() << " renderSVG\n";
++ renderSvg( pClass, area );
++ kdDebug() << timestamp() << " done\n";
++ }
+ }
+
+ int px = area.left() + r.left();
+@@ -176,25 +209,37 @@ KdmPixmap::drawContents( QPainter *p, co
+
+
+ if (pClass->readyPixmap.isNull()) {
+- QImage scaledImage;
++
++ bool haveTint = pClass->tint.rgb() != 0xFFFFFF;
++ bool haveAlpha = pClass->alpha < 1.0;
+
++ QImage scaledImage;
++
+ // use the loaded pixmap or a scaled version if needed
+
++ kdDebug() << timestamp() << " prepare readyPixmap " << pClass->fullpath << " " << area.size() << " " << pClass->pixmap.size() << endl;
+ if (area.size() != pClass->pixmap.size()) {
+ if (pClass->fullpath.endsWith( ".svg" )) {
+- kdDebug() << "renderSVG\n";
++ kdDebug() << timestamp() << " renderSVG\n";
+ renderSvg( pClass, area );
+ scaledImage = pClass->pixmap.convertToImage();
+ } else {
+- kdDebug() << "convertFromImage\n";
++ kdDebug() << timestamp() << " convertFromImage smoothscale\n";
+ QImage tempImage = pClass->pixmap.convertToImage();
++ kdDebug() << timestamp() << " convertToImage done\n";
+ scaledImage = tempImage.smoothScale( area.width(), area.height() );
++ kdDebug() << timestamp() << " done\n";
+ }
+- } else
++ } else {
++ if (haveTint || haveAlpha)
++ {
+ scaledImage = pClass->pixmap.convertToImage();
+-
+- bool haveTint = pClass->tint.rgb() != 0xFFFFFF;
+- bool haveAlpha = pClass->alpha < 1.0;
++ // enforce rgba values for the later
++ scaledImage = scaledImage.convertDepth( 32 );
++ }
++ else
++ pClass->readyPixmap = pClass->pixmap;
++ }
+
+ if (haveTint || haveAlpha) {
+ // blend image(pix) with the given tint
+@@ -221,9 +266,12 @@ KdmPixmap::drawContents( QPainter *p, co
+
+ }
+
+- pClass->readyPixmap.convertFromImage( scaledImage );
++ if (!scaledImage.isNull()) {
++ kdDebug() << timestamp() << " convertFromImage " << id << " " << area << endl;
++ pClass->readyPixmap.convertFromImage( scaledImage );
++ }
+ }
+- // kdDebug() << "Pixmap::drawContents " << pClass->readyPixmap.size() << " " << px << " " << py << " " << sx << " " << sy << " " << sw << " " << sh << endl;
++ kdDebug() << timestamp() << " Pixmap::drawContents " << pClass->readyPixmap.size() << " " << px << " " << py << " " << sx << " " << sy << " " << sw << " " << sh << endl;
+ p->drawPixmap( px, py, pClass->readyPixmap, sx, sy, sw, sh );
+ }
+
+Index: kdm/kfrontend/themer/kdmlabel.cpp
+===================================================================
+--- kdm/kfrontend/themer/kdmlabel.cpp.orig
++++ kdm/kfrontend/themer/kdmlabel.cpp
+@@ -19,8 +19,10 @@
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
++#include <config.h>
+ #include "kdmlabel.h"
+-#include <kgreeter.h>
++#include "kdmconfig.h"
++#include "../kgreeter.h"
+
+ #include <kglobal.h>
+ #include <klocale.h>
+@@ -31,6 +33,7 @@
+ #include <qpainter.h>
+ #include <qfontmetrics.h>
+ #include <qtimer.h>
++#include <qaccel.h>
+
+ #include <unistd.h>
+ #include <sys/utsname.h>
+@@ -39,7 +42,7 @@
+ #endif
+
+ KdmLabel::KdmLabel( KdmItem *parent, const QDomNode &node, const char *name )
+- : KdmItem( parent, node, name )
++ : KdmItem( parent, node, name ), myAccel(0)
+ {
+ itemType = "label";
+
+@@ -92,21 +95,46 @@ KdmLabel::KdmLabel( KdmItem *parent, con
+ }
+ }
+
+- // Check if this is a timer label
++ // Check if this is a timer label)
+ label.isTimer = label.text.find( "%c" ) >= 0;
+ if (label.isTimer) {
+ timer = new QTimer( this );
+ timer->start( 1000 );
+ connect( timer, SIGNAL(timeout()), SLOT(update()) );
+ }
+- cText = lookupText( label.text );
++ setTextInt( lookupText( label.text ) );
++}
++
++void
++KdmLabel::setTextInt( const QString &txt)
++{
++ // TODO: catch &&
++ cText = txt;
++ cAccel = txt.find('&');
++ delete myAccel;
++ myAccel = 0;
++ if (cAccel != -1) {
++ cText.remove('&');
++ myAccel = new QAccel(parentWidget());
++ myAccel->insertItem(ALT + UNICODE_ACCEL + cText.at(cAccel).lower().unicode());
++ connect(myAccel, SIGNAL(activated(int)), SLOT(slotAccel()));
++ }
++}
++
++void
++KdmLabel::slotAccel()
++{
++ if (buttonParent)
++ emit activated(buttonParent->getId());
++ else
++ emit activated(id);
+ }
+
+ void
+ KdmLabel::setText( const QString &txt )
+ {
+ label.text = txt;
+- update();
++ setTextInt( lookupText( label.text ) );
+ }
+
+ QSize
+@@ -139,7 +167,23 @@ KdmLabel::drawContents( QPainter *p, con
+ p->setFont( l->font );
+ p->setPen( l->color );
+ //TODO paint clipped (tested but not working..)
+- p->drawText( area, AlignLeft | SingleLine, cText );
++ if (cAccel != -1 && (!id.isEmpty() || buttonParent) ) {
++ QString left = cText.left(cAccel);
++ QString right = cText.mid(cAccel + 1);
++ p->drawText( area, AlignLeft | SingleLine, left );
++ QRect tarea = area;
++ QFontMetrics fm(l->font);
++ tarea.rLeft() += fm.width(left);
++ QFont f(l->font);
++ f.setUnderline(true);
++ p->setFont ( f );
++ p->drawText( tarea, AlignLeft | SingleLine, QString(cText.at(cAccel)));
++ tarea.rLeft() += fm.width(cText.at(cAccel));
++ p->setFont( l->font );
++ p->drawText( tarea, AlignLeft | SingleLine, right);
++ } else {
++ p->drawText( area, AlignLeft | SingleLine, cText);
++ }
+ }
+
+ void
+@@ -159,7 +203,7 @@ KdmLabel::update()
+ {
+ QString text = lookupText( label.text );
+ if (text != cText) {
+- cText = text;
++ setTextInt(text);
+ needUpdate();
+ }
+ }
+@@ -167,22 +211,23 @@ KdmLabel::update()
+ static const struct {
+ const char *type, *text;
+ } stocks[] = {
+- { "language", I18N_NOOP("Language") },
+- { "session", I18N_NOOP("Session Type") },
+- { "system", I18N_NOOP("Menu") }, // i18n("Actions");
+- { "disconnect", I18N_NOOP("Disconnect") },
+- { "quit", I18N_NOOP("Quit") },
+- { "halt", I18N_NOOP("Power off") },
+- { "suspend", I18N_NOOP("Suspend") },
+- { "reboot", I18N_NOOP("Reboot") },
++ { "language", I18N_NOOP("&Language") },
++ { "session", I18N_NOOP("Session &Type") },
++ { "system", I18N_NOOP("&System") }, // i18n("Actions");
++ { "disconnect", I18N_NOOP("&Disconnect") },
++ { "quit", I18N_NOOP("&Quit") },
++ { "halt", I18N_NOOP("Power O&ff") },
++ { "suspend", I18N_NOOP("S&uspend") },
++ { "reboot", I18N_NOOP("&Reboot") },
+ { "chooser", I18N_NOOP("XDMCP Chooser") },
+ { "config", I18N_NOOP("Configure") },
+- { "caps-lock-warning", I18N_NOOP("You have got caps lock on.") },
+- { "timed-label", I18N_NOOP("User %s will login in %d seconds") },
+- { "welcome-label", I18N_NOOP("Welcome to %h") }, // _greetString
+- { "username-label", I18N_NOOP("Username:") },
+- { "password-label", I18N_NOOP("Password:") },
+- { "login", I18N_NOOP("Login") }
++ { "caps-lock-warning", I18N_NOOP("Caps Lock is enabled.") },
++ { "timed-label", I18N_NOOP("User %s will log in in %d seconds") },
++ { "welcome-label", I18N_NOOP("Welcome to %h") }, // _greetString
++ { "username-label", I18N_NOOP("&Username:") },
++ { "password-label", I18N_NOOP("&Password:") },
++ { "domain-label", I18N_NOOP("&Domain:") },
++ { "login", I18N_NOOP("L&ogin") }
+ };
+
+ QString
+@@ -195,7 +240,7 @@ KdmLabel::lookupStock( const QString &st
+ if (type == stocks[i].type)
+ return i18n(stocks[i].text);
+
+- kdDebug() << "Invalid <stock> element. Check your theme!" << endl;
++ kdDebug() << timestamp() << " Invalid <stock> element. Check your theme!" << endl;
+ return stock;
+ }
+
+@@ -205,7 +250,6 @@ KdmLabel::lookupText( const QString &t )
+ QString text = t;
+
+ text.replace( '_', '&' );
+-// text.remove( '_' ); // FIXME add key accels, remove underscores for now
+
+ QMap<QChar,QString> m;
+ struct utsname uts;
+Index: kdm/kfrontend/kdmconfig.h
+===================================================================
+--- kdm/kfrontend/kdmconfig.h.orig
++++ kdm/kfrontend/kdmconfig.h
+@@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fi
+ #include <qstring.h>
+ #include <qstringlist.h>
+ #include <qfont.h>
++#include <sys/time.h>
+
+ extern QString _stsFile;
+ extern bool _isLocal;
+@@ -46,6 +47,19 @@ CONF_GREET_CPP_DECLS
+ struct dpySpec;
+ void decodeSess( dpySpec *sess, QString &user, QString &loc );
+
++extern struct timeval st;
++
++inline QString timestamp() {
++ struct timeval nst;
++ gettimeofday(&nst, 0);
++ if (!st.tv_sec)
++ gettimeofday(&st, 0);
++
++ QString ret;
++ ret.sprintf("[%07ld]", (nst.tv_sec - st.tv_sec) * 1000 + (nst.tv_usec - st.tv_usec) / 1000);
++ return ret;
++}
++
+ extern "C"
+ #endif
+ void init_config( void );
+Index: kdm/kfrontend/kgreeter.h
+===================================================================
+--- kdm/kfrontend/kgreeter.h.orig
++++ kdm/kfrontend/kgreeter.h
+@@ -73,9 +73,10 @@ class KGreeter : public KGDialog, public
+ void slotUserEntered();
+
+ protected:
++ void readFacesList();
+ void installUserList();
+ void insertUser( const QImage &, const QString &, struct passwd * );
+- void insertUsers();
++ void insertUsers( int limit = -1);
+ void putSession( const QString &, const QString &, bool, const char * );
+ void insertSessions();
+ virtual void pluginSetup();
+@@ -87,10 +88,13 @@ class KGreeter : public KGDialog, public
+ QStringList *userList;
+ QPopupMenu *sessMenu;
+ QValueVector<SessType> sessionTypes;
++ QStringList randomFaces;
++ QMap<QString, QString> randomFacesMap;
+ int nNormals, nSpecials;
+ int curPrev, curSel;
+ bool prevValid;
+ bool needLoad;
++ bool themed;
+
+ static int curPlugin;
+ static PluginList pluginList;
+Index: kdm/kfrontend/kgdialog.cpp
+===================================================================
+--- kdm/kfrontend/kgdialog.cpp.orig
++++ kdm/kfrontend/kgdialog.cpp
+@@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fi
+ #include "kdm_greet.h"
+
+ #include <klocale.h>
++#include <kiconloader.h>
+
+ #include <qaccel.h>
+ #include <qlayout.h>
+@@ -58,7 +59,7 @@ KGDialog::completeMenu()
+ #ifdef HAVE_VTS
+ if (_isLocal) {
+ dpyMenu = new QPopupMenu( this );
+- int id = inserten( i18n("Sw&itch User"), ALT+Key_I, dpyMenu );
++ int id = inserten( i18n("Sw&itch User"), CTRL + Key_I, dpyMenu );
+ connect( dpyMenu, SIGNAL(activated( int )),
+ SLOT(slotDisplaySelected( int )) );
+ connect( dpyMenu, SIGNAL(aboutToShow()),
+@@ -71,7 +72,7 @@ KGDialog::completeMenu()
+
+ if (_allowClose)
+ inserten( _isLocal ? i18n("R&estart X Server") : i18n("Clos&e Connection"),
+- ALT+Key_E, SLOT(slotExit()) );
++ 0, SLOT(slotExit()) );
+
+ #ifdef XDMCP
+ if (_isLocal && _loginMode != _switchIf) {
+@@ -81,10 +82,11 @@ KGDialog::completeMenu()
+ #endif
+
+ if (_hasConsole)
+- inserten( i18n("Co&nsole Login"), ALT+Key_N, SLOT(slotConsole()) );
++ inserten( i18n("Co&nsole Login"), CTRL+Key_N, SLOT(slotConsole()) );
+
+ if (_allowShutdown != SHUT_NONE) {
+- inserten( i18n("&Shutdown..."), ALT+Key_S, SLOT(slotShutdown( int )) );
++ ensureMenu();
++ optMenu->insertItem(SmallIconSet( "exit" ), i18n("&Shutdown..."), this, SLOT(slotShutdown(int)), CTRL+Key_S );
+ QAccel *accel = new QAccel( this );
+ accel->insertItem( ALT+CTRL+Key_Delete );
+ connect( accel, SIGNAL(activated( int )), SLOT(slotShutdown( int )) );
+Index: kdm/kfrontend/kdmconfig.cpp
+===================================================================
+--- kdm/kfrontend/kdmconfig.cpp.orig
++++ kdm/kfrontend/kdmconfig.cpp
+@@ -33,6 +33,8 @@ Foundation, Inc., 51 Franklin Street, Fi
+ #include <unistd.h>
+ #include <sys/utsname.h>
+
++struct timeval st = {0, 0};
++
+ CONF_GREET_DEFS
+
+ QString _stsFile;
+Index: kdm/kfrontend/kgapp.cpp
+===================================================================
+--- kdm/kfrontend/kgapp.cpp.orig
++++ kdm/kfrontend/kgapp.cpp
+@@ -36,6 +36,8 @@ Foundation, Inc., 51 Franklin Street, Fi
+ #include <kcrash.h>
+ #include <kstandarddirs.h>
+ #include <ksimpleconfig.h>
++#include <klocale.h>
++#include <kdebug.h>
+
+ #include <qtimer.h>
+ #include <qcursor.h>
+@@ -130,6 +132,7 @@ kg_main( const char *argv0 )
+ static char *argv[] = { (char *)"kdmgreet", 0 };
+ KCmdLineArgs::init( 1, argv, *argv, 0, 0, 0, true );
+
++ kdDebug() << timestamp() << "start" << endl;
+ kde_have_kipc = false;
+ KApplication::disableAutoDcopRegistration();
+ KCrash::setSafer( true );
+@@ -166,6 +169,7 @@ kg_main( const char *argv0 )
+
+ GSendInt( G_Ready );
+
++ kdDebug() << timestamp() << " main1" << endl;
+ setCursor( dpy, app.desktop()->winId(), XC_left_ptr );
+
+ for (;;) {
+@@ -206,6 +210,7 @@ kg_main( const char *argv0 )
+ if (_useTheme && !_theme.isEmpty()) {
+ KThemedGreeter *tgrt;
+ dialog = tgrt = new KThemedGreeter;
++ kdDebug() << timestamp() << " themed" << endl;
+ if (!tgrt->isOK()) {
+ delete tgrt;
+ dialog = new KStdGreeter;
+Index: kdm/kfrontend/kgreeter.cpp
+===================================================================
+--- kdm/kfrontend/kgreeter.cpp.orig
++++ kdm/kfrontend/kgreeter.cpp
+@@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin Street, Fi
+ #include <klistview.h>
+ #include <ksimpleconfig.h>
+ #include <kstringhandler.h>
++#include <kdebug.h>
+
+ #undef Unsorted // x headers suck - make qdir.h work with --enable-final
+ #include <qdir.h>
+@@ -46,6 +47,7 @@ Foundation, Inc., 51 Franklin Street, Fi
+ #include <qmemarray.h>
+ #include <qimage.h>
+ #include <qmovie.h>
++#include <qpainter.h>
+ #include <qpopupmenu.h>
+ #include <qtimer.h>
+ #include <qheader.h>
+@@ -63,27 +65,46 @@ Foundation, Inc., 51 Franklin Street, Fi
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
++#include <utmp.h>
++#include <utmpx.h>
+
+ #include <X11/Xlib.h>
+
+ class UserListView : public KListView {
+ public:
+- UserListView( QWidget *parent = 0, const char *name = 0 )
++ UserListView( bool _them, QWidget *parent = 0, const char *name = 0 )
+ : KListView( parent, name )
+- , cachedSizeHint( -1, 0 )
++ , themed(_them), cachedSizeHint( -1, 0 )
+ {
+ setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Ignored );
+ header()->hide();
+ addColumn( QString::null );
+ setColumnAlignment( 0, AlignVCenter );
+ setResizeMode( QListView::LastColumn );
++ if (themed) {
++ setBackgroundMode( Qt::NoBackground );
++ viewport()->setBackgroundMode( Qt::NoBackground );
++ setFrameStyle( QFrame::NoFrame );
++ }
+ }
+
++ bool themed;
+ mutable QSize cachedSizeHint;
+
+- protected:
++ int sumHeight() const
++ {
++ int sum = 0;
++ for (QListViewItem *itm = firstChild(); itm; itm = itm->nextSibling()) {
++ sum += itm->height();
++ }
++ return sum;
++ }
++public:
+ virtual QSize sizeHint() const
+ {
++ if (themed)
++ return KListView::sizeHint();
++
+ if (!cachedSizeHint.isValid()) {
+ constPolish();
+ uint maxw = 0;
+@@ -98,8 +119,23 @@ class UserListView : public KListView {
+ }
+ return cachedSizeHint;
+ }
+-};
++ virtual void paintEmptyArea ( QPainter * p, const QRect & rect )
++ {
++ if (!themed)
++ return KListView::paintEmptyArea(p, rect );
++
++ const QPixmap *pm = paletteBackgroundPixmap();
++ if (!pm || pm->isNull())
++ return;
++
++ kdDebug() << "paintEmpty " << rect << endl;
++ QRect devRect = p->xForm( rect );
++ kdDebug() << "paintEmpty2 " << devRect << endl;
++ p->drawPixmap(0, 0, *pm, devRect.left(), devRect.top() );
++ }
+
++ QPixmap background;
++};
+
+ int KGreeter::curPlugin = -1;
+ PluginList KGreeter::pluginList;
+@@ -115,12 +151,14 @@ KGreeter::KGreeter( bool framed )
+ , curSel( -1 )
+ , prevValid( true )
+ , needLoad( false )
++ , themed( framed )
+ {
+ stsFile = new KSimpleConfig( _stsFile );
+ stsFile->setGroup( "PrevUser" );
+
+ if (_userList) {
+- userView = new UserListView( this );
++ readFacesList();
++ userView = new UserListView( framed, this );
+ connect( userView, SIGNAL(clicked( QListViewItem * )),
+ SLOT(slotUserClicked( QListViewItem * )) );
+ connect( userView, SIGNAL(doubleClicked( QListViewItem * )),
+@@ -128,10 +166,8 @@ KGreeter::KGreeter( bool framed )
+ }
+ if (_userCompletion)
+ userList = new QStringList;
+- if (userView || userList)
+- insertUsers();
+
+- sessMenu = new QPopupMenu( this );
++ sessMenu = new QPopupMenu( this );
+ connect( sessMenu, SIGNAL(activated( int )),
+ SLOT(slotSessionSelected( int )) );
+ insertSessions();
+@@ -150,6 +186,33 @@ KGreeter::~KGreeter()
+ delete stsFile;
+ }
+
++void KGreeter::readFacesList()
++{
++ FILE *f = fopen( QFile::encodeName( _faceDir + "/.randomlist" ), "rt" );
++ if ( !f )
++ return;
++ QTextIStream is( f );
++ while ( !is.eof() )
++ {
++ QString line = is.readLine().simplifyWhiteSpace();
++ if ( line.isEmpty() )
++ continue;
++ QString icon;
++ int index = line.find( ' ' );
++ if ( index > 0 ) {
++ icon = line.left( index );
++ line = line.mid( index );
++ } else {
++ icon = line;
++ line = QString::null;
++ }
++ randomFaces.push_back( icon );
++ QStringList list = QStringList::split( ' ', line );
++ for ( QStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
++ randomFacesMap[*it] = icon;
++ }
++}
++
+ class UserListViewItem : public KListViewItem {
+ public:
+ UserListViewItem( UserListView *parent, const QString &text,
+@@ -163,6 +226,14 @@ class UserListViewItem : public KListVie
+ parent->cachedSizeHint.setWidth( -1 );
+ }
+
++ virtual void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment)
++ {
++ if (((UserListView*)listView())->themed)
++ QListViewItem::paintCell(p, cg, column, width, alignment);
++ else
++ KListViewItem::paintCell(p, cg, column, width, alignment);
++ }
++
+ QString login;
+ };
+
+@@ -224,10 +295,23 @@ KGreeter::insertUser( const QImage &defa
+ QSize ns( 48, 48 );
+ if (p.size() != ns)
+ p = p.convertDepth( 32 ).smoothScale( ns, QImage::ScaleMin );
+- goto gotit;
++ break;
+ } while (--nd >= 0);
+- p = default_pix;
+- gotit:
++
++ if ( p.isNull() && randomFaces.count() ) {
++ QString randomFace = randomFacesMap[username];
++ if ( randomFace.isNull() ) {
++ QStringList::size_type index = 0;
++ for ( size_t i = 0; i < username.length(); ++i )
++ index += ( 0x7f - username.at( i ).latin1() ) % 37;
++ randomFace = randomFaces[ index % randomFaces.count() ];
++ }
++ p.load( _faceDir + "/../pics/users/" + randomFace + ".png" );
++ }
++
++ if ( p.isNull() )
++ p = default_pix;
++
+ QString realname = KStringHandler::from8Bit( ps->pw_gecos );
+ realname.truncate( realname.find( ',' ) );
+ if (realname.isEmpty() || realname == username)
+@@ -278,7 +362,7 @@ UserList::UserList( char **in )
+ }
+
+ void
+-KGreeter::insertUsers()
++KGreeter::insertUsers(int limit_users)
+ {
+ struct passwd *ps;
+
+@@ -305,6 +389,8 @@ KGreeter::insertUsers()
+ if (_showUsers == SHOW_ALL) {
+ UserList noUsers( _noUsers );
+ QDict<int> dupes( 1000 );
++ QStringList toinsert;
++ int count = 0;
+ for (setpwent(); (ps = getpwent()) != 0;) {
+ if (*ps->pw_dir && *ps->pw_shell &&
+ (ps->pw_uid >= (unsigned)_lowUserId ||
+@@ -316,10 +402,53 @@ KGreeter::insertUsers()
+ QString username( QFile::decodeName( ps->pw_name ) );
+ if (!dupes.find( username )) {
+ dupes.insert( username, (int *)-1 );
+- insertUser( default_pix, username, ps );
++ toinsert.append( username );
++
++ if ( limit_users >= 0 && ++count > limit_users )
++ break;
+ }
+ }
+ }
++ if ( limit_users >= 0 && ++count > limit_users ) {
++ utmpname( _PATH_WTMP );
++ setutxent();
++ toinsert = QStringList();
++ dupes.clear();
++
++ for ( count = 0; count < limit_users; ) {
++ struct utmpx * ent = getutxent();
++ if ( !ent )
++ break;
++ struct passwd *ps = getpwnam( ent->ut_user );
++ if (ps && *ps->pw_dir && *ps->pw_shell &&
++ (ps->pw_uid >= (unsigned)_lowUserId ||
++ !ps->pw_uid && _showRoot) &&
++ ps->pw_uid <= (unsigned)_highUserId &&
++ !noUsers.hasUser( ps->pw_name ) &&
++ !noUsers.hasGroup( ps->pw_gid ))
++ {
++ QString username( QFile::decodeName( ent->ut_user ) );
++ if (!dupes.find( username )) {
++ dupes.insert( username, (int *)-1 );
++ toinsert.append( username );
++ count++;
++ }
++ }
++
++
++ }
++ endutxent();
++ }
++
++ for ( QStringList::ConstIterator it = toinsert.begin();
++ it != toinsert.end(); ++it )
++ {
++ // pretty stupid to do another lookup round, but the number is limited
++ // and caching struct passwd is pretty ugly
++ struct passwd *ps = getpwnam( QFile::encodeName( *it ) );
++ if ( ps )
++ insertUser( default_pix, *it, ps );
++ }
+ } else {
+ UserList users( _users );
+ if (users.hasGroups()) {
+@@ -721,21 +850,24 @@ KStdGreeter::KStdGreeter()
+ hbox2->addStretch( 1 );
+
+ if (sessMenu->count() > 1) {
+- inserten( i18n("Session &Type"), ALT+Key_T, sessMenu );
++ inserten( i18n("Session &Type"), 0, sessMenu );
+ needSep = true;
+ }
+
+ if (plugMenu) {
+- inserten( i18n("&Authentication Method"), ALT+Key_A, plugMenu );
++ inserten( i18n("&Authentication Method"), 0, plugMenu );
+ needSep = true;
+ }
+
+ #ifdef XDMCP
+- completeMenu( LOGIN_LOCAL_ONLY, ex_choose, i18n("&Remote Login"), ALT+Key_R );
++ completeMenu( LOGIN_LOCAL_ONLY, ex_choose, i18n("&Remote Login"), 0 );
+ #else
+ completeMenu();
+ #endif
+
++ if (userView || userList)
++ insertUsers();
++
+ if (optMenu)
+ menuButton->setPopup( optMenu );
+ else
+@@ -829,6 +961,9 @@ KThemedGreeter::KThemedGreeter()
+ if (xauth_warning && (_authorized || !_authComplain))
+ xauth_warning->hide( true );
+
++ if (userView || userList)
++ insertUsers( 7 ); // TODO: find out how many are a good value
++
+ // if (!_greetString.isEmpty()) {
+ // }
+ // clock = new KdmClock( this, "clock" );
+@@ -854,37 +989,31 @@ KThemedGreeter::KThemedGreeter()
+ if ((itm = themer->findNode( "session_button" ))) {
+ if (sessMenu->count() <= 1)
+ itm->hide( true );
+- else {
+- session_button = itm;
+- QAccel *accel = new QAccel( this );
+- accel->insertItem( ALT+Key_T, 0 );
+- connect( accel, SIGNAL(activated( int )), SLOT(slotSessMenu()) );
+- }
++ else
++ session_button = itm;
+ } else {
+ if (sessMenu->count() > 1) {
+- inserten( i18n("Session &Type"), ALT+Key_T, sessMenu );
++ inserten( i18n("Session &Type"), 0, sessMenu );
+ needSep = true;
+ }
+ }
+
+ if (plugMenu) {
+- inserten( i18n("&Authentication Method"), ALT+Key_A, plugMenu );
++ inserten( i18n("&Authentication Method"), 0, plugMenu );
+ needSep = true;
+ }
+
+ #ifdef XDMCP
+- completeMenu( LOGIN_LOCAL_ONLY, ex_choose, i18n("&Remote Login"), ALT+Key_R );
++ completeMenu( LOGIN_LOCAL_ONLY, ex_choose, i18n("&Remote Login"), 0 );
+ #else
+ completeMenu();
+ #endif
+
+ system_button = themer->findNode( "system_button" );
+- QAccel *accel = new QAccel( this );
+- accel->insertItem( ALT+Key_M, 0 );
+- connect( accel, SIGNAL(activated( int )), SLOT(slotActionMenu()) );
+
+ pluginSetup();
+
++
+ verify->start();
+ }
+
+@@ -902,8 +1031,8 @@ KThemedGreeter::pluginSetup()
+ inherited::pluginSetup();
+
+ if (userView && verify->entitiesLocal() && verify->entityPresettable() && userlist_rect) {
++ userView->setMaximumHeight( userView->sumHeight() );
+ userlist_rect->setWidget( userView );
+- userView->show();
+ } else {
+ if (userView)
+ userView->hide();
+@@ -919,12 +1048,17 @@ KThemedGreeter::verifyFailed()
+ {
+ // goButton->setEnabled( false );
+ inherited::verifyFailed();
++ if (userView)
++ userView->setEnabled(false);
+ }
+
+ void
+ KThemedGreeter::verifyRetry()
+ {
+ // goButton->setEnabled( true );
++ if (userView)
++ userView->setEnabled(true);
++
+ }
+
+ QString KThemedGreeter::timedUser = QString::null;
diff --git a/opensuse/tdebase/kdm-mark_autologin.diff b/opensuse/tdebase/kdm-mark_autologin.diff
new file mode 100644
index 000000000..a913f5a94
--- /dev/null
+++ b/opensuse/tdebase/kdm-mark_autologin.diff
@@ -0,0 +1,13 @@
+Index: kdm/backend/client.c
+===================================================================
+--- kdm/backend/client.c.orig
++++ kdm/backend/client.c
+@@ -1214,6 +1214,8 @@ StartClient()
+ env = setEnv( env, "PATH", curuid ? td->userPath : td->systemPath );
+ env = setEnv( env, "SHELL", p->pw_shell );
+ env = setEnv( env, "HOME", p->pw_dir );
++ if (cursource == PWSRC_AUTOLOGIN)
++ env = setEnv (env, "KDM_AUTOLOGIN", curuser);
+ #if !defined(USE_PAM) && !defined(_AIX) && defined(KERBEROS)
+ if (krbtkfile[0] != '\0')
+ env = setEnv( env, "KRBTKFILE", krbtkfile );
diff --git a/opensuse/tdebase/kdm-pam-np-legacy b/opensuse/tdebase/kdm-pam-np-legacy
new file mode 100644
index 000000000..5d139e0bb
--- /dev/null
+++ b/opensuse/tdebase/kdm-pam-np-legacy
@@ -0,0 +1,7 @@
+#%PAM-1.0
+auth required pam_permit.so
+account include common-account
+password include common-password
+session include common-session
+session required pam_devperm.so
+session required pam_resmgr.so
diff --git a/opensuse/tdebase/kdm-relaxed-auth.diff b/opensuse/tdebase/kdm-relaxed-auth.diff
new file mode 100644
index 000000000..c94fa2b5d
--- /dev/null
+++ b/opensuse/tdebase/kdm-relaxed-auth.diff
@@ -0,0 +1,22 @@
+Index: kdm/backend/auth.c
+===================================================================
+--- kdm/backend/auth.c.orig
++++ kdm/backend/auth.c
+@@ -518,6 +518,7 @@ DefineLocal( FILE *file, Xauth *auth, in
+ uname( &name );
+ writeAddr( FamilyLocal, strlen( name.nodename ), name.nodename,
+ file, auth, ok );
++ setenv("XAUTHLOCALHOSTNAME", name.nodename, 1);
+ #endif
+
+ #if !defined(NEED_UTSNAME) || defined(__hpux)
+@@ -1211,6 +1212,9 @@ SetUserAuthorization( struct display *d
+ userEnviron = setEnv( userEnviron, "XAUTHORITY", envname );
+ systemEnviron = setEnv( systemEnviron, "XAUTHORITY", envname );
+ }
++ name = getenv("XAUTHLOCALHOSTNAME");
++ if (name)
++ userEnviron = setEnv( userEnviron, "XAUTHLOCALHOSTNAME", name);
+ /* a chown() used to be here, but this code runs as user anyway */
+ }
+ Debug( "done SetUserAuthorization\n" );
diff --git a/opensuse/tdebase/kdm-suspend-hal.diff b/opensuse/tdebase/kdm-suspend-hal.diff
new file mode 100644
index 000000000..711e1c114
--- /dev/null
+++ b/opensuse/tdebase/kdm-suspend-hal.diff
@@ -0,0 +1,331 @@
+Index: kdm/backend/ctrl.c
+===================================================================
+--- kdm/backend/ctrl.c.orig
++++ kdm/backend/ctrl.c
+@@ -483,6 +483,10 @@ processCtrl( const char *string, int len
+ Reply( "nuke\t" );
+ }
+ }
++ if (d->allowSuspend != SHUT_NONE) {
++ Reply( "suspend\t" );
++ }
++
+ if ((d->displayType & d_location) == dLocal &&
+ AnyReserveDisplays())
+ Writer( fd, cbuf, sprintf( cbuf, "reserve %d\t",
+Index: kdm/backend/greet.h
+===================================================================
+--- kdm/backend/greet.h.orig
++++ kdm/backend/greet.h
+@@ -125,6 +125,7 @@ from the copyright holder.
+ # define SHUT_REBOOT 1 /* how */
+ # define SHUT_HALT 2
+ # define SHUT_CONSOLE -1 /* pseudo-code */
++# define SHUT_SUSPEND -2 /* pseudo-code */
+ # define SHUT_SCHEDULE 0 /* when; config only */
+ # define SHUT_TRYNOW 1
+ # define SHUT_FORCENOW 2
+Index: kdm/config.def
+===================================================================
+--- kdm/config.def.orig
++++ kdm/config.def
+@@ -1799,6 +1799,19 @@ Description:
+ Who is allowed to shut down the system. This applies both to the
+ greeter and to the command <acronym>FiFo</acronym>.
+
++Key: AllowSuspend
++Type: enum
++ None/SHUT_NONE: no <guilabel>Suspend...</guilabel> menu entry is shown at all
++ Root/SHUT_ROOT: the <systemitem class="username">root</systemitem> password must be entered to suspend
++ All/SHUT_ALL: everybody can suspend the machine
++Default: Root
++User: greeter
++User: core
++Instance: #:0/All
++Comment: &
++Description:
++ If the user should have an option to suspend the system if configured to (also in the desktop)
++
+ Key: AllowSdForceNow
+ Type: enum
+ None: no forced shutdown is allowed at all
+Index: kdm/kfrontend/kdmshutdown.cpp
+===================================================================
+--- kdm/kfrontend/kdmshutdown.cpp.orig
++++ kdm/kfrontend/kdmshutdown.cpp
+@@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fi
+
+ */
+
++#include <liblazy.h>
+ #include "kdmshutdown.h"
+ #include "kdm_greet.h"
+
+@@ -34,6 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fi
+ #include <kdialog.h>
+ #include <kstandarddirs.h>
+ #include <kuser.h>
++#include <kdebug.h>
+
+ #include <qcombobox.h>
+ #include <qvbuttongroup.h>
+@@ -57,6 +59,10 @@ Foundation, Inc., 51 Franklin Street, Fi
+ int KDMShutdownBase::curPlugin = -1;
+ PluginList KDMShutdownBase::pluginList;
+
++#define DBUS_HAL_INTERFACE "org.freedesktop.Hal"
++#define DBUS_HAL_SYSTEM_POWER_INTERFACE "org.freedesktop.Hal.Device.SystemPowerManagement"
++#define HAL_UDI_COMPUTER "/org/freedesktop/Hal/devices/computer"
++
+ KDMShutdownBase::KDMShutdownBase( int _uid, QWidget *_parent )
+ : inherited( _parent )
+ , box( new QVBoxLayout( this, KDmh, KDsh ) )
+@@ -71,6 +77,7 @@ KDMShutdownBase::KDMShutdownBase( int _u
+ , verify( 0 )
+ , needRoot( -1 )
+ , uid( _uid )
++ , willSuspend( false )
+ {
+ }
+
+@@ -87,6 +94,7 @@ KDMShutdownBase::complete( QWidget *prev
+
+ if (uid &&
+ ((willShut && _allowShutdown == SHUT_ROOT) ||
++ ( willSuspend && _allowSuspend == SHUT_ROOT ) ||
+ (mayNuke && _allowNuke == SHUT_ROOT)))
+ {
+ rootlab = new QLabel( i18n("Root authorization required."), this );
+@@ -169,6 +177,7 @@ KDMShutdownBase::updateNeedRoot()
+ {
+ int nNeedRoot = uid &&
+ (((willShut && _allowShutdown == SHUT_ROOT) ||
++ ( willSuspend && _allowSuspend == SHUT_ROOT ) ||
+ (_allowNuke == SHUT_ROOT && doesNuke)));
+ if (verify && nNeedRoot != needRoot) {
+ if (needRoot == 1)
+@@ -425,7 +434,7 @@ KDMRadioButton::mouseDoubleClickEvent( Q
+
+
+ KDMDelayedPushButton::KDMDelayedPushButton( const KGuiItem &item,
+- QWidget *parent,
++ QWidget *parent,
+ const char *name )
+ : inherited( item, parent, name )
+ , pop( 0 )
+@@ -490,6 +499,57 @@ KDMSlimShutdown::KDMSlimShutdown( QWidge
+ buttonlay->addWidget( btnReboot );
+ connect( btnReboot, SIGNAL(clicked()), SLOT(slotReboot()) );
+
++ if ( _allowSuspend != SHUT_NONE )
++ {
++ int supported = -1;
++ liblazy_hal_get_property_bool(HAL_UDI_COMPUTER, "power_management.can_suspend", &supported);
++ if (supported == 1)
++ suspend_ram = true;
++ else
++ suspend_ram = false;
++
++ liblazy_hal_get_property_bool(HAL_UDI_COMPUTER, "power_management.can_standby", &supported);
++ if (supported == 1)
++ standby = true;
++ else
++ standby = false;
++ liblazy_hal_get_property_bool(HAL_UDI_COMPUTER, "power_management.can_hibernate", &supported);
++ if (supported == 1)
++ suspend_disk = true;
++ else
++ suspend_disk = false;
++
++/* if (liblazy_polkit_is_user_allowed_by_uid(0, "hal-power-hibernate", NULL) != 1)
++ suspend_disk = false;
++ if (liblazy_polkit_is_user_allowed_by_uid(0, "hal-power-suspend", NULL) != 1)
++ suspend_ram = false;
++ if (liblazy_polkit_is_user_allowed_by_uid(0, "hal-power-standby", NULL) != 1)
++ standby = false;
++*/
++ int sum = standby + suspend_ram + suspend_disk;
++ if ( sum ) {
++ buttonlay->addSpacing( KDialog::spacingHint() );
++
++ QButton *btnSuspend;
++ if (sum > 1) {
++ btnSuspend = new KDMDelayedPushButton( KGuiItem( i18n("&Suspend Computer"), "player_pause"), this );
++ QPopupMenu *suspends = new QPopupMenu(this);
++ if (suspend_disk)
++ suspends->insertItem(i18n("Suspend to Disk"), 1);
++ if (suspend_ram)
++ suspends->insertItem(i18n("Suspend to RAM"), 2);
++ if (standby)
++ suspends->insertItem(i18n("Standby"), 3);
++ connect(suspends, SIGNAL(activated(int)), SLOT(slotSuspend(int)));
++ static_cast<KDMDelayedPushButton*>(btnSuspend)->setPopup(suspends);
++ } else {
++ btnSuspend = new KPushButton( KGuiItem( i18n("&Suspend Computer"), "player_pause"), this );
++ }
++ buttonlay->addWidget( btnSuspend );
++ connect(btnSuspend, SIGNAL(clicked()), SLOT(slotSuspend()));
++ }
++ }
++
+ GSet( 1 );
+ GSendInt( G_ListBootOpts );
+ if (GRecvInt() == BO_OK) {
+@@ -536,6 +596,65 @@ KDMSlimShutdown::~KDMSlimShutdown()
+ freeStrArr( targetList );
+ }
+
++void KDMSlimShutdown::slotSuspend()
++{
++ if (suspend_disk)
++ slotSuspend( 1 );
++ else if (suspend_ram)
++ slotSuspend( 2 );
++ else if ( standby )
++ slotSuspend( 3 );
++ else
++ reject();
++}
++
++void KDMSlimShutdown::slotSuspend(int id)
++{
++ reject();
++ // dpySpec *sess = fetchSessions( lstRemote | lstTTY );
++ // it would be nice to show the sessions to suspend, but it
++ // would require string changes (coolo)
++ dpySpec *sess = 0;
++ kdDebug() << "slotSuspend " << _allowSuspend << endl;
++ if (sess || _allowSuspend == SHUT_ROOT)
++ {
++ int ret = KDMConfShutdown( -1, sess, SHUT_SUSPEND, 0 ).exec();
++ if ( !ret )
++ return;
++ }
++
++ int error = 0;
++ int wake = 0;
++ DBusMessage *reply;
++
++ if (suspend_disk && id == 1) {
++ error = liblazy_dbus_system_send_method_call(DBUS_HAL_INTERFACE,
++ HAL_UDI_COMPUTER,
++ DBUS_HAL_SYSTEM_POWER_INTERFACE,
++ "Hibernate",
++ &reply,
++ DBUS_TYPE_INVALID);
++ } else if (suspend_ram && id == 2)
++ error = liblazy_dbus_system_send_method_call(DBUS_HAL_INTERFACE,
++ HAL_UDI_COMPUTER,
++ DBUS_HAL_SYSTEM_POWER_INTERFACE,
++ "Suspend",
++ &reply,
++ DBUS_TYPE_INT32,
++ &wake,
++ DBUS_TYPE_INVALID);
++ else if (standby && id == 3)
++ error = liblazy_dbus_system_send_method_call(DBUS_HAL_INTERFACE,
++ HAL_UDI_COMPUTER,
++ DBUS_HAL_SYSTEM_POWER_INTERFACE,
++ "Standby",
++ &reply,
++ DBUS_TYPE_INVALID);
++ else {
++ return;
++ }
++}
++
+ void
+ KDMSlimShutdown::slotSched()
+ {
+@@ -601,16 +720,27 @@ KDMConfShutdown::KDMConfShutdown( int _u
+ if (type == SHUT_CONSOLE)
+ willShut = false;
+ #endif
++ QString title;
++ if ( type == SHUT_HALT)
++ title = i18n("Turn Off Computer");
++ else {
++#ifdef HAVE_VTS
++ if ( type == SHUT_CONSOLE)
++ title = i18n("Switch to Console");
++ else
++#endif
++ if ( type == SHUT_SUSPEND ) {
++ willSuspend = true;
++ title = i18n( "Suspend Computer" );
++ }
++ else
++ title = i18n("Restart Computer");
++ }
++
+ box->addWidget( new QLabel( QString( "<qt><center><b><nobr>"
+ "%1%2"
+ "</nobr></b></center><br></qt>" )
+- .arg( (type == SHUT_HALT) ?
+- i18n("Turn Off Computer") :
+-#ifdef HAVE_VTS
+- (type == SHUT_CONSOLE) ?
+- i18n("Switch to Console") :
+-#endif
+- i18n("Restart Computer") )
++ .arg( title )
+ .arg( os ?
+ i18n("<br>(Next boot: %1)")
+ .arg( QString::fromLocal8Bit( os ) ) :
+Index: kdm/kfrontend/kdmshutdown.h
+===================================================================
+--- kdm/kfrontend/kdmshutdown.h.orig
++++ kdm/kfrontend/kdmshutdown.h
+@@ -67,7 +67,7 @@ class KDMShutdownBase : public FDialog,
+ #else
+ static const bool willShut = true;
+ #endif
+- bool mayNuke, doesNuke, mayOk, maySched;
++ bool mayNuke, doesNuke, mayOk, maySched, willSuspend;
+
+ private slots:
+ void slotSched();
+@@ -118,7 +118,6 @@ class KDMShutdown : public KDMShutdownBa
+ QComboBox *targets;
+ int oldTarget;
+ int sch_st, sch_to;
+-
+ };
+
+ class KDMRadioButton : public QRadioButton {
+@@ -168,10 +167,13 @@ class KDMSlimShutdown : public FDialog {
+ void slotReboot();
+ void slotReboot( int );
+ void slotSched();
++ void slotSuspend();
++ void slotSuspend(int);
+
+ private:
+ bool checkShutdown( int type, const char *os );
+ char **targetList;
++ bool suspend_disk, suspend_ram, standby;
+
+ };
+
+Index: kdm/kfrontend/Makefile.am
+===================================================================
+--- kdm/kfrontend/Makefile.am.orig
++++ kdm/kfrontend/Makefile.am
+@@ -4,7 +4,7 @@ GENKDMCONF_FLAGS =
+ SUBDIRS = themer themes pics sessions
+
+ AM_CPPFLAGS = -I$(srcdir)/../backend -I.. -I$(top_srcdir)/kcontrol/background \
+- -I$(top_srcdir)/kdmlib $(all_includes)
++ -I$(top_srcdir)/kdmlib $(all_includes) $(DBUS_INCS)
+
+ bin_PROGRAMS = kdm_config kdm_greet krootimage genkdmconf kdmctl
+
+@@ -25,7 +25,7 @@ kdm_greet_SOURCES = \
+ kgreeter.cpp \
+ kgapp.cpp
+ kdm_greet_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+-kdm_greet_LDADD = themer/libkdmthemer.a $(LIB_KDEUI) $(XTESTLIB) $(LIBPOSIX4)
++kdm_greet_LDADD = themer/libkdmthemer.a $(LIB_KDEUI) $(XTESTLIB) $(LIBPOSIX4) -llazy $(DBUS_LIBS)
+
+ krootimage_SOURCES = krootimage.cpp
+ krootimage_LDFLAGS = $(all_libraries) $(KDE_RPATH)
diff --git a/opensuse/tdebase/kdm-sysconfig-values.diff b/opensuse/tdebase/kdm-sysconfig-values.diff
new file mode 100644
index 000000000..c3b9f8af9
--- /dev/null
+++ b/opensuse/tdebase/kdm-sysconfig-values.diff
@@ -0,0 +1,737 @@
+Index: kdm/config.def
+===================================================================
+--- kdm/config.def.orig
++++ kdm/config.def
+@@ -792,6 +792,21 @@ Description:
+ <emphasis>Do not</emphasis> change it, you may interfere with future
+ upgrades and this could result in &kdm; failing to run.
+
++Key: SUSEConfigVersion
++Type: string
++Default: ""
++CDefault: -
++User: dummy
++# will be overwritten
++Instance:
++Comment:
++ This option exists solely for the purpose of a clean automatic upgrade.
++ Do not even think about changing it!
++Description:
++ This option exists solely for the purpose of clean automatic upgrades.
++ <emphasis>Do not</emphasis> change it, you may interfere with future
++ upgrades and this could result in &kdm; failing to run.
++
+ Key: PAMService
+ If: defined(USE_PAM)
+ Type: string
+@@ -874,10 +889,10 @@ Description:
+
+ Key: PidFile
+ Type: string
+-Default: ""
++Default: "/var/run/kdm.pid"
+ User: core
+-Instance: "/var/run/kdm.pid"
+-Merge: xdm
++Instance: ""
++Update: reset_sec_0_1
+ Comment:
+ Where &kdm; should store its PID (do not store if empty).
+ Description:
+@@ -901,10 +916,10 @@ Description:
+ Key: AuthDir
+ Type: path
+ # differs from XDM
+-Default: "/var/run/xauth"
++Default: "/var/lib/xdm/authdir/authfiles"
+ User: core
+-Instance: #"/tmp"
+-Merge: xdm(P_authDir)
++Instance: #""
++Update: reset_sec_0_1
+ Comment:
+ Where to store authorization files.
+ Description:
+@@ -930,7 +945,7 @@ Description:
+
+ Key: ExportList
+ Type: list
+-Default: ""
++Default: "LANG,XCURSOR_THEME"
+ User: core
+ Instance: #"LD_LIBRARY_PATH,ANOTHER_IMPORTANT_VAR"
+ Merge: xdm(P_List)
+@@ -1063,9 +1078,10 @@ Description:
+
+ Key: Enable
+ Type: bool
+-Default: true
++Default: false
+ User: dep(xdmcpEnable)
+ Instance: false
++Update: reset_sec_0_1
+ Comment: &
+ Description:
+ Whether &kdm; should listen to incoming &XDMCP; requests.
+@@ -1102,11 +1118,10 @@ Description:
+ Key: Xaccess
+ Type: string
+ # differs from xdm
+-Default: *KDMCONF "/Xaccess"
++Default: *"/etc/X11/xdm/Xaccess"
+ User: config(Xaccess)
+-Instance: #""
+-Update: mk_xaccess
+-Merge: xdm:accessFile
++Instance: #
++Update: reset_sec_0_1
+ Comment:
+ &XDMCP; access control file in the usual XDM-Xaccess format.
+ Description:
+@@ -1164,13 +1179,11 @@ Description:
+
+ Key: Willing
+ Type: string
+-Default: ""
++Default: "/etc/X11/xdm/Xwilling"
+ User: core
+ # will be overwritten
+ Instance: #
+-Update: mk_willing
+-Merge: xdm
+-Merge: kdm:Xwilling
++Update: reset_sec_0_1
+ Comment:
+ The program which is invoked to dynamically generate replies to &XDMCP;
+ DirectQuery or BroadcastQuery requests.
+@@ -1244,7 +1257,7 @@ Type: enum
+ None/BO_NONE: no boot manager
+ Grub/BO_GRUB: Grub boot manager
+ Lilo/BO_LILO: Lilo boot manager (Linux on i386 &amp; x86-64 only)
+-Default: None
++Default: Grub
+ User: core
+ User: greeter
+ Instance: #Grub
+@@ -1347,6 +1360,7 @@ Default: DEF_SERVER_CMD
+ DDefault: -
+ User: core
+ Instance: :*/DEF_SERVER_CMD
++Update: reset_sec_0_1
+ Comment:
+ The command line to start the &X-Server;, without display number and VT spec.
+ This string is subject to word splitting.
+@@ -1355,7 +1369,7 @@ Description:
+ This string is subject to word splitting.
+ </para><para>
+ The default is something reasonable for the system on which &kdm; was built,
+- like <command>/usr/X11R6/bin/X</command>.
++ like <command>/usr/bin/X</command>.
+
+ Key: ServerArgsLocal
+ Type: string
+@@ -1549,11 +1563,10 @@ Description:
+ Key: Resources
+ # XXX strictly speaking this is supposed to be a string list, i think.
+ Type: string
+-Default: ""
++Default: "/etx/X11/xdm/Xresources"
+ User: core
+ Instance: #*/""
+-Update: cp_resources
+-Merge: xdm
++Update: reset_sec_0_1
+ Comment:
+ Specify a file with X-resources for the greeter, chooser and background.
+ The KDE frontend does not use this file, so you do not need it unless you
+@@ -1581,12 +1594,11 @@ Description:
+
+ Key: Setup
+ Type: string
+-Default: ""
++Default: "/etc/X11/xdm/Xsetup"
+ User: core
+ # will be overwritten
+ Instance: #*/""
+-Update: mk_setup
+-Merge: xdm
++Update: reset_sec_0_1
+ Comment:
+ A program to run before the greeter is shown. Can be used to start an
+ xconsole or an alternative background generator. Subject to word splitting.
+@@ -1602,12 +1614,11 @@ Description:
+
+ Key: Startup
+ Type: string
+-Default: ""
++Default: "/etc/X11/xdm/Xstartup"
+ User: core
+ # will be overwritten
+ Instance: #*/""
+-Update: mk_startup
+-Merge: xdm
++Update: reset_sec_0_1
+ Comment:
+ A program to run before a user session starts. Subject to word splitting.
+ Description:
+@@ -1620,12 +1631,11 @@ Description:
+
+ Key: Reset
+ Type: string
+-Default: ""
++Default: "/etc/X11/xdm/Xreset"
+ User: core
+ # will be overwritten
+ Instance: #*/""
+-Update: mk_reset
+-Merge: xdm
++Update: reset_sec_0_1
+ Comment:
+ A program to run after a user session exits. Subject to word splitting.
+ Description:
+@@ -1638,12 +1648,12 @@ Description:
+
+ Key: Session
+ Type: string
+-Default: XBINDIR "/xterm -ls -T"
++Default: "/etc/X11/xdm/Xsession"
+ #Merge: xdm - incompatible!
+ User: core
+ # will be overwritten
+ Instance: #*/""
+-Update: mk_session
++Update: reset_sec_0_1
+ Comment:
+ The program which is run as the user which logs in. It is supposed to
+ interpret the session argument (see SessionsDirs) and start an appropriate
+@@ -1746,10 +1756,11 @@ Description:
+
+ Key: AllowRootLogin
+ Type: bool
+-Default: true
++Default: false
+ User: core
+ User: greeter(showRoot)
+-Instance: */false
++Instance: #*/false
++Update: reset_sec_1_2
+ Merge: xdm
+ Comment:
+ Allow root logins?
+@@ -1764,6 +1775,7 @@ User: core
+ # sensible?
+ Instance: */false
+ Instance: :*/true
++Update: reset_sec_0_1
+ Merge: xdm
+ Comment:
+ Allow to log in, when user has set an empty password?
+@@ -1775,12 +1787,13 @@ Type: enum
+ None/SHUT_NONE: no <guilabel>Shutdown...</guilabel> menu entry is shown at all
+ Root/SHUT_ROOT: the <systemitem class="username">root</systemitem> password must be entered to shut down
+ All/SHUT_ALL: everybody can shut down the machine
+-Default: All
++Default: Root
+ User: core
+ User: greeter
+ Instance: */Root
+-Instance: :*/All
+-Merge: kdm:-Greeter/
++Instance: #:*/All
++Update: reset_sec_0_1
++#Merge: kdm:-Greeter/
+ Comment: &
+ Description:
+ Who is allowed to shut down the system. This applies both to the
+@@ -1866,6 +1879,7 @@ Type: bool
+ Default: false
+ User: dep
+ Instance: #:0/true
++Update: reset_sec_0_1
+ Comment: &
+ Description:
+ Enable automatic login. <emphasis>Use with extreme care!</emphasis>
+@@ -1899,7 +1913,7 @@ Default: ""
+ PostProc: PautoLoginX
+ User: core(autoUser)
+ User: greeter
+-Instance: #:0/"fred"
++Instance: #:0/""
+ Merge: xdm:autoUser(P_autoUser)
+ Comment: &
+ Description:
+@@ -1930,10 +1944,10 @@ Description:
+
+ Key: SessionsDirs
+ Type: list
+-Default: KDMDATA "/sessions"
++Default: "/etc/X11/sessions," KDMDATA "/sessions,/usr/share/xsessions"
+ User: core
+ User: greeter-c
+-Instance: #*/"/etc/X11/sessions,/usr/share/xsessions"
++Instance: #*/""
+ Comment:
+ The directories containing session type definitions in .desktop format.
+ Description:
+@@ -2008,7 +2022,8 @@ Type: enum
+ Clock/LOGO_CLOCK: a neat analog clock
+ Default: Clock
+ User: greeter
+-Instance: */Logo
++Instance: */Clock
++Update: reset_sec_0_1
+ Comment:
+ What should be shown in the greeter's logo are:
+ Description:
+@@ -2223,7 +2238,7 @@ Description:
+
+ Key: HiddenUsers
+ Type: list
+-Default: ""
++Default: "root"
+ User: greeter-c(noUsers)
+ Instance: #*/"root"
+ # depends on {Min,Max}ShowUID
+@@ -2363,13 +2378,14 @@ Type: enum
+ Default: OneStar
+ User: greeter
+ Instance: #*/NoEcho
++Update: reset_sec_0_1
+ Comment: &
+ Description:
+ The password input fields cloak the typed in text. Specify, how to do it:
+
+ Key: UseBackground
+ Type: bool
+-Default: true
++Default: false
+ User: greeter
+ Instance: #*/!
+ Comment:
+@@ -2507,6 +2523,7 @@ Type: bool
+ Default: false
+ User: greeter
+ Instance: :0/true
++Update: reset_sec_0_1
+ Comment:
+ Enable &kdm;'s built-in xconsole. Note that this can be enabled for only
+ one display at a time.
+@@ -2595,9 +2612,10 @@ Description:
+
+ Key: Preloader
+ Type: string
+-Default: ""
++Default: KDE_BINDIR "/preloadkde"
+ User: greeter-c
+-Instance: */KDE_BINDIR "/preloadkde"
++Instance: */""
++Update: reset_sec_0_1
+ Comment: &
+ Description:
+ A program to run while the greeter is visible. It is supposed to preload
+@@ -2606,7 +2624,7 @@ Description:
+
+ Key: UseTheme
+ Type: bool
+-Default: false
++Default: true
+ User: greeter
+ Instance: #*/true
+ Comment: &
+@@ -2615,9 +2633,10 @@ Description:
+
+ Key: Theme
+ Type: string
+-Default: ""
++Default: KDMDATA "/themes/SUSE"
+ User: greeter
+-Instance: */KDMDATA "/themes/circles"
++Instance: */""
++Update: reset_sec_0_1
+ Comment: &
+ Description:
+ The theme to use for the greeter. Can point to either a directory or an XML
+Index: kdm/kfrontend/read_sysconfig.sh
+===================================================================
+--- /dev/null
++++ kdm/kfrontend/read_sysconfig.sh
+@@ -0,0 +1,147 @@
++#!/bin/bash
++#
++# Copyright (c) 2006 SUSE Linux Products GmbH Nuernberg, Germany.
++#
++# Author: Stephan Kulow <coolo@suse.de>
++#
++
++#
++# check if we are started as root
++# only one of UID and USER must be set correctly
++#
++if test "$UID" != 0 -a "$USER" != root; then
++ echo "You must be root to start $0."
++ exit 1
++fi
++
++#
++# check for sysconfig/displaymanager or rc.config
++#
++test -f /etc/sysconfig/displaymanager && source /etc/sysconfig/displaymanager
++test -f /etc/sysconfig/security && source /etc/sysconfig/security
++test -f /etc/sysconfig/language && source /etc/sysconfig/language
++
++#
++# source /etc/profile to get $kdedir
++#
++kdedir="/opt/kde3"
++kdmdir="/var/adm/kdm"
++
++# check for write permissions
++[ -w ${kdmdir} ] || mkdir -p ${kdmdir}
++[ -w ${kdmdir} ] || exit
++
++#
++# Set Style of Shutdown
++#
++ECHO_MODE="OneStar"
++ALLOW_ROOT_LOGIN="true"
++case "$DISPLAYMANAGER_SHUTDOWN" in
++ all|ALL|All)
++ DISPLAYMANAGER_SHUTDOWN=All;;
++ none|NONE|None)
++ DISPLAYMANAGER_SHUTDOWN=None;;
++ auto|Auto|AUTO)
++ case "$PERMISSION_SECURITY" in
++ *easy*)
++ DISPLAYMANAGER_SHUTDOWN=All
++ ;;
++ *paranoid*)
++ ECHO_MODE="NoEcho"
++ ALLOW_ROOT_LOGIN="false"
++ DISPLAYMANAGER_SHUTDOWN=Root
++ ;;
++ *)
++ DISPLAYMANAGER_SHUTDOWN=Root
++ ;;
++ esac
++ ;;
++ * )
++ DISPLAYMANAGER_SHUTDOWN=Root;;
++esac
++
++(
++echo "[X-*-Greeter]"
++if [ -n "$KDM_USERS" ]; then
++ echo "ShowUsers=Selected"
++ echo -n "SelectedUsers="
++ echo ${KDM_USERS}|sed -e 's@ [ ]*@ @g' -e 's@ @,@g'
++else
++ echo "ShowUsers=NotHidden"
++fi
++if [ "$DISPLAYMANAGER_AD_INTEGRATION" = "yes" ]; then
++ echo "PluginsLogin=winbind"
++fi
++if [ -n "$DISPLAYMANAGER_KDM_THEME" -a -d "/opt/kde3/share/apps/kdm/themes/$DISPLAYMANAGER_KDM_THEME" ]; then
++ echo "Theme=/opt/kde3/share/apps/kdm/themes/$DISPLAYMANAGER_KDM_THEME"
++ echo "UseTheme=true"
++ echo "UseBackground=false"
++else
++ echo "UseTheme=false"
++ echo "UseBackground=true"
++fi
++# kdm has en_US as default instead of simply reading LC_LANG :(
++echo "Language="
++
++echo "[Xdmcp]"
++if [ "$DISPLAYMANAGER_REMOTE_ACCESS" = "yes" ]; then
++ echo "Enable=true"
++else
++ echo "Enable=false"
++fi
++
++echo "[X-:0-Core]"
++if [ "$DISPLAYMANAGER_AUTOLOGIN" ]; then
++ echo "AutoLoginEnable=true"
++ echo "AutoLoginUser=${DISPLAYMANAGER_AUTOLOGIN}"
++else
++ echo "AutoLoginEnable=false"
++fi
++if [ "$DISPLAYMANAGER_XSERVER_TCP_PORT_6000_OPEN" = "yes" ]; then
++ echo "ServerArgsLocal="
++else
++ echo "ServerArgsLocal=-nolisten tcp"
++fi
++if [ "$DISPLAYMANAGER_PASSWORD_LESS_LOGIN" = "yes" ]; then
++ echo "NoPassEnable=true"
++ echo "NoPassAllUsers=true"
++else
++ echo "NoPassEnable=false"
++ echo "NoPassAllUsers=false"
++fi
++
++echo "[X-:*-Core]"
++echo "AllowShutdown=${DISPLAYMANAGER_SHUTDOWN}"
++echo "AllowRootLogin=${ALLOW_ROOT_LOGIN}"
++echo "AllowNullPasswd=${ALLOW_ROOT_LOGIN}"
++
++echo "[X-*-Core]"
++
++if test "$DISPLAYMANAGER_ROOT_LOGIN_REMOTE" = "yes"; then
++ echo "AllowRootLogin=true"
++else
++ echo "AllowRootLogin=false"
++fi
++
++case "$DISPLAYMANAGER_XSERVER" in
++ Xgl)
++ xgl=`type -p Xgl`
++ echo "ServerCmd=$xgl $DISPLAYMANAGER_XGL_OPTS -br"
++ echo "ServerTimeout=50"
++ ;;
++ Xorg)
++ xorg=`type -p Xorg`
++ echo "ServerCmd=$xorg -br"
++ ;;
++ *)
++ echo "#Unknown X server - leaving X"
++ ;;
++esac
++
++echo "[General]"
++if [ "$DISPLAYMANAGER_STARTS_XSERVER" != "yes" ]; then
++ echo "StaticServers="
++fi
++
++) > ${kdmdir}/kdmrc.sysconfig
++
+Index: kdm/kfrontend/kdm_config.c
+===================================================================
+--- kdm/kfrontend/kdm_config.c.orig
++++ kdm/kfrontend/kdm_config.c
+@@ -386,7 +386,7 @@ static const char *kdmrc = KDMCONF "/kdm
+ static Section *rootsec;
+
+ static void
+-ReadConf()
++ReadConfFile(const char *rcfile)
+ {
+ const char *nstr, *dstr, *cstr, *dhost, *dnum, *dclass;
+ char *s, *e, *st, *en, *ek, *sl, *pt;
+@@ -396,14 +396,9 @@ ReadConf()
+ int nlen, dlen, clen, dhostl, dnuml, dclassl;
+ int i, line, sectmoan, restl;
+ File file;
+- static int confread;
+
+- if (confread)
+- return;
+- confread = 1;
+-
+- Debug( "reading config %s ...\n", kdmrc );
+- if (!readFile( &file, kdmrc, "master configuration" ))
++ Debug( "reading config %s ...\n", rcfile );
++ if (!readFile( &file, rcfile, "master configuration" ))
+ return;
+
+ for (s = file.buf, line = 0, cursec = 0, sectmoan = 1; s < file.eof; s++) {
+@@ -429,7 +424,7 @@ ReadConf()
+ e--;
+ if (*e != ']') {
+ cursec = 0;
+- LogError( "Invalid section header at %s:%d\n", kdmrc, line );
++ LogError( "Invalid section header at %s:%d\n", rcfile, line );
+ continue;
+ }
+ nstr = sl + 1;
+@@ -438,8 +433,8 @@ ReadConf()
+ if (nlen == cursec->nlen &&
+ !memcmp( nstr, cursec->name, nlen ))
+ {
+- LogInfo( "Multiple occurrences of section [%.*s] in %s. "
+- "Consider merging them.\n", nlen, nstr, kdmrc );
++ Debug( "Multiple occurrences of section [%.*s] in %s. "
++ "Consider merging them.\n", nlen, nstr, rcfile );
+ goto secfnd;
+ }
+ if (nstr[0] == 'X' && nstr[1] == '-') {
+@@ -495,7 +490,7 @@ ReadConf()
+ illsec:
+ cursec = 0;
+ LogError( "Unrecognized section name [%.*s] at %s:%d\n",
+- nlen, nstr, kdmrc, line );
++ nlen, nstr, rcfile, line );
+ continue;
+ newsec:
+ if (!(cursec = Malloc( sizeof(*cursec) )))
+@@ -523,7 +518,7 @@ ReadConf()
+ if (!cursec) {
+ if (sectmoan) {
+ sectmoan = 0;
+- LogError( "Entry outside any section at %s:%d", kdmrc, line );
++ LogError( "Entry outside any section at %s:%d", rcfile, line );
+ }
+ goto sktoeol;
+ }
+@@ -531,13 +526,13 @@ ReadConf()
+ for (; (s < file.eof) && (*s != '\n'); s++)
+ if (*s == '=')
+ goto haveeq;
+- LogError( "Invalid entry (missing '=') at %s:%d\n", kdmrc, line );
++ LogError( "Invalid entry (missing '=') at %s:%d\n", rcfile, line );
+ continue;
+
+ haveeq:
+ for (ek = s - 1; ; ek--) {
+ if (ek < sl) {
+- LogError( "Invalid entry (empty key) at %s:%d\n", kdmrc, line );
++ LogError( "Invalid entry (empty key) at %s:%d\n", rcfile, line );
+ goto sktoeol;
+ }
+ if (!isspace( *ek ))
+@@ -551,7 +546,7 @@ ReadConf()
+ if (*s == '\\') {
+ s++;
+ if (s >= file.eof || *s == '\n') {
+- LogError( "Trailing backslash at %s:%d\n", kdmrc, line );
++ LogError( "Trailing backslash at %s:%d\n", rcfile, line );
+ break;
+ }
+ switch (*s) {
+@@ -580,29 +575,42 @@ ReadConf()
+ goto keyok;
+ }
+ LogError( "Unrecognized key '%.*s' in section [%.*s] at %s:%d\n",
+- nlen, nstr, cursec->nlen, cursec->name, kdmrc, line );
++ nlen, nstr, cursec->nlen, cursec->name, rcfile, line );
+ continue;
+ keyok:
+ for (curent = cursec->entries; curent; curent = curent->next)
+ if (ce == curent->ent) {
+ LogError( "Multiple occurrences of key '%s' in section [%.*s]"
+ " of %s\n",
+- ce->name, cursec->nlen, cursec->name, kdmrc );
++ ce->name, cursec->nlen, cursec->name, rcfile );
+ goto keyfnd;
+ }
+ if (!(curent = Malloc( sizeof(*curent) )))
+ return;
++ curent->next = cursec->entries;
++ cursec->entries = curent;
++ keyfnd:
+ curent->ent = ce;
+ curent->line = line;
+ curent->val = st;
+ curent->vallen = en - st;
+- curent->next = cursec->entries;
+- cursec->entries = curent;
+- keyfnd:
+ continue;
+ }
+ }
+
++static void ReadConf()
++{
++ static int confread = 0;
++
++ if (confread)
++ return;
++ confread++;
++
++ system("/opt/kde3/share/apps/kdm/read_sysconfig.sh");
++ ReadConfFile("/var/adm/kdm/kdmrc.sysconfig");
++ ReadConfFile(kdmrc);
++}
++
+ static Entry *
+ FindGEnt( int id )
+ {
+Index: kdm/kfrontend/genkdmconf.c
+===================================================================
+--- kdm/kfrontend/genkdmconf.c.orig
++++ kdm/kfrontend/genkdmconf.c
+@@ -66,6 +66,7 @@ Foundation, Inc., 51 Franklin Street, Fi
+ #define stringify(x) __stringify(x)
+
+ #define RCVERSTR stringify(RCVERMAJOR) "." stringify(RCVERMINOR)
++#define SUSERCVERSTR "2"
+
+ static int old_scripts, no_old_scripts, old_confs, no_old,
+ no_backup, no_in_notice, use_destdir, mixed_scripts;
+@@ -73,7 +74,7 @@ static const char *newdir = KDMCONF, *fa
+ *oldxdm, *oldkde;
+
+ static int oldver;
+-
++static int oldsusever;
+
+ typedef struct StrList {
+ struct StrList *next;
+@@ -462,6 +463,7 @@ wrconf( FILE *f )
+ const char *cmt;
+
+ putfqval( "General", "ConfigVersion", RCVERSTR );
++ putfqval( "General", "SUSEConfigVersion", SUSERCVERSTR );
+ for (cs = config; cs; cs = cs->next) {
+ fprintf( f, "%s[%s]\n",
+ cs->comment ? cs->comment : "\n", cs->name );
+@@ -1363,6 +1365,26 @@ upd_consolettys( Entry *ce, Section *cs
+ }
+ #endif
+
++static void
++reset_sec_0_1( Entry *ce, Section *cs ATTR_UNUSED )
++{
++ if (oldsusever < 1 || !ce->written )
++ {
++ ce->active = 0;
++ }
++ return;
++}
++
++static void
++reset_sec_1_2( Entry *ce, Section *cs ATTR_UNUSED )
++{
++ if (oldsusever < 2 || !ce->written )
++ {
++ ce->active = 0;
++ }
++ return;
++}
++
+ #ifdef XDMCP
+ static void
+ cp_keyfile( Entry *ce, Section *cs ATTR_UNUSED )
+@@ -2228,7 +2250,7 @@ static int
+ mergeKdmRcNewer( const char *path )
+ {
+ char *p;
+- const char *cp, *sec, *key;
++ const char *cp, *sec, *key, *susever;
+ RSection *rootsect, *cs;
+ REntry *ce;
+ int i, j;
+@@ -2291,8 +2313,12 @@ mergeKdmRcNewer( const char *path )
+ }
+
+ #ifdef XDMCP
+- applydefs( kdmdefs_all, as(kdmdefs_all), path );
++ /* applydefs( kdmdefs_all, as(kdmdefs_all), path ); */
+ #endif
++ susever = getfqval( "General", "SUSEConfigVersion", "" );
++ if (sscanf( susever, "%u", &oldsusever ) != 1)
++ oldsusever = 0;
++
+ if (!*(cp = getfqval( "General", "ConfigVersion", "" ))) { /* < 3.1 */
+ mod_usebg = 1;
+ if (is22conf( path )) {
+Index: kdm/kfrontend/Makefile.am
+===================================================================
+--- kdm/kfrontend/Makefile.am.orig
++++ kdm/kfrontend/Makefile.am
+@@ -64,3 +64,7 @@ kdm_greet_COMPILE_FIRST = ../config.ci
+ kdm_config_COMPILE_FIRST = ../config.ci
+ genkdmconf_COMPILE_FIRST = ../config.ci
+
++
++appsdir = $(kde_datadir)/kdm
++apps_SCRIPTS = read_sysconfig.sh
++
diff --git a/opensuse/tdebase/kdm-use-rpmoptflags.diff b/opensuse/tdebase/kdm-use-rpmoptflags.diff
new file mode 100644
index 000000000..85a03e02b
--- /dev/null
+++ b/opensuse/tdebase/kdm-use-rpmoptflags.diff
@@ -0,0 +1,29 @@
+Index: kdm/backend/Makefile.am
+===================================================================
+--- kdm/backend/Makefile.am.orig
++++ kdm/backend/Makefile.am
+@@ -1,11 +1,6 @@
+ # forcibly remove thread-related defines & flags
+ AUTOMAKE_OPTIONS = foreign
+-CFLAGS = $(XDM_CFLAGS) -fno-strict-aliasing
+-CPPFLAGS = $(USER_INCLUDES) $(X_INCLUDES) $(KRB4_INCS) $(KRB5_INCS) -I.. -I../..
+-LDFLAGS = $(USER_LDFLAGS) $(X_LDFLAGS) $(X_RPATH) $(KRB4_RPATH) $(KRB5_RPATH)
+-LDADD = $(LIB_X11) -lXau $(LIBXDMCP) $(PASSWDLIBS) $(LIBSHADOW) $(LIBGEN) \
+- $(LIB_LIBS) $(KRB4_LIBS) $(KRB5_LIBS) $(LIBSOCKET) $(LIBRESOLV) \
+- $(LIBUCB) $(LIBUTIL) $(LIBPOSIX4)
++AM_CPPFLAGS = $(USER_INCLUDES) $(X_INCLUDES) $(KRB4_INCS) $(KRB5_INCS) -I.. -I../..
+
+ bin_PROGRAMS = kdm
+ kdm_SOURCES = \
+@@ -39,6 +34,11 @@ kdm_SOURCES = \
+ xdmauth.c \
+ xdmcp.c
+
++kdm_LDFLAGS = $(USER_LDFLAGS) $(X_LDFLAGS) $(X_RPATH) $(KRB4_RPATH) $(KRB5_RPATH)
++kdm_LDADD = $(LIB_X11) -lXau $(LIBXDMCP) $(PASSWDLIBS) \
++ $(LIB_LIBS) $(KRB4_LIBS) $(KRB5_LIBS) $(LIBSOCKET) $(LIBRESOLV) \
++ $(LIBUCB) $(LIBUTIL) $(LIBPOSIX4)
++
+ EXTRA_DIST = printf.c
+
+ noinst_HEADERS = dm.h dm_socket.h dm_error.h dm_auth.h greet.h
diff --git a/opensuse/tdebase/kdm-wordbreak.diff b/opensuse/tdebase/kdm-wordbreak.diff
new file mode 100644
index 000000000..9c50ecdc9
--- /dev/null
+++ b/opensuse/tdebase/kdm-wordbreak.diff
@@ -0,0 +1,22 @@
+Index: kdm/kfrontend/kfdialog.cpp
+===================================================================
+--- kdm/kfrontend/kfdialog.cpp.orig
++++ kdm/kfrontend/kfdialog.cpp
+@@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fi
+ #include <klocale.h>
+ #include <kpushbutton.h>
+ #include <kstdguiitem.h>
++#include <kglobalsettings.h>
+
+ #include <qlabel.h>
+ #include <qlayout.h>
+@@ -137,6 +138,9 @@ KFMsgBox::KFMsgBox( QWidget *parent, QMe
+ QLabel *label1 = new QLabel( this );
+ label1->setPixmap( QMessageBox::standardIcon( type ) );
+ QLabel *label2 = new QLabel( text, this );
++ QRect d = KGlobalSettings::desktopGeometry(this);
++ if ( label2->fontMetrics().size( 0, text).width() > d.width() * 3 / 5)
++ label2->setAlignment(Qt::WordBreak | Qt::AlignAuto );
+ KPushButton *button = new KPushButton( KStdGuiItem::ok(), this );
+ button->setDefault( true );
+ button->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ) );
diff --git a/opensuse/tdebase/kfontinst.diff b/opensuse/tdebase/kfontinst.diff
new file mode 100644
index 000000000..51c5e59b6
--- /dev/null
+++ b/opensuse/tdebase/kfontinst.diff
@@ -0,0 +1,10 @@
+--- kcontrol/kfontinst/kfontinst/Main.cpp
++++ kcontrol/kfontinst/kfontinst/Main.cpp 2004/01/27 08:43:25
+@@ -80,6 +80,7 @@
+ QStringList::ConstIterator xftIt;
+
+ for(xftIt=CGlobal::cfg().getUserFontsDirs().begin(); xftIt!=CGlobal::cfg().getUserFontsDirs().end(); ++xftIt)
++ CMisc::doCmd("/sbin/conf.d/SuSEconfig.fonts", "--module", "fonts");
+ CMisc::doCmd(XFT_CACHE_CMD, CMisc::xDirSyntax(*xftIt));
+ #else
+ CMisc::doCmd(XFT_CACHE_CMD, CMisc::xDirSyntax(ds));
diff --git a/opensuse/tdebase/khelpcenter-beagle.diff b/opensuse/tdebase/khelpcenter-beagle.diff
new file mode 100644
index 000000000..6b4314e6a
--- /dev/null
+++ b/opensuse/tdebase/khelpcenter-beagle.diff
@@ -0,0 +1,172 @@
+Index: khelpcenter/searchhandlers/khc_beagle_search.pl
+===================================================================
+--- /dev/null
++++ khelpcenter/searchhandlers/khc_beagle_search.pl
+@@ -0,0 +1,88 @@
++#!/usr/bin/perl -w
++# vim:sw=4:et
++
++use warnings;
++use strict;
++use Getopt::Long;
++
++sub isBeagleRunning()
++{
++ open(IN, "-|") || exec "beagle-ping";
++ while(<IN>) {
++ if (/^Daemon version:/) {
++ close(IN);
++ return 1;
++ }
++ }
++ close(IN);
++ return 0;
++}
++
++sub formatHTML($$)
++{
++ my ($query, $hits) = @_;
++
++ print "<html>\n<body\n<ul>\n";
++
++ foreach my $hit(@$hits) {
++ print "<li>$hit</li>\n";
++ }
++ print "</ul>\n</body>\n</html>\n";
++}
++
++sub beagleQuery($$$)
++{
++ my ($words, $method, $maxnum) = @_;
++
++ my @hits = ();
++
++ open(IN, "-|") || exec "beagle-query", "--type", "DocbookEntry", "--type", "File", "--max-hits", $maxnum, @$words, "ext:docbook";
++ while(<IN>) {
++ chop;
++ next if (/^Debug:/);
++
++ my $uri = $_;
++ $uri = $1 if ($uri =~ /^file:\/\/(.*)$/);
++
++ print "uri: $uri\n";
++ my $helpLink = &makeHelpLink($uri);
++
++ push(@hits, $helpLink) if (!grep { /^$helpLink$/ } @hits);
++ }
++ close(IN);
++ return @hits;
++}
++
++sub makeHelpLink($)
++{
++ # Try to figure out the name of the application from the path to its index.docbook file
++
++ my ($path) = @_;
++ my @pathcomponents = split '/', $path;
++
++ my $appName = $pathcomponents[-2];
++ my $appName2 = $pathcomponents[-3];
++
++ if ($appName eq $appName2 or $appName2 eq "doc"
++ or (-d "/usr/share/locale/$appName2")) {
++ return "<a href=\"help:/$appName\">$appName</a>";
++ }
++ return "<a href=\"help:/$appName2/$appName\">$appName ($appName2)</a>";
++}
++
++my $method = "and";
++my $maxnum = 100;
++
++GetOptions("method=s", \$method, "maxnum=i", \$maxnum);
++
++my @hits = ("The Beagle daemon is not running, search is not available");
++
++my @words = @ARGV;
++
++if (isBeagleRunning()) {
++ @hits = beagleQuery(\@words, $method, $maxnum);
++}
++
++@hits = ("There are no search results") if ($#hits < 0);
++
++formatHTML(\@words, \@hits);
+Index: khelpcenter/searchhandlers/khc_beagle_index.pl
+===================================================================
+--- /dev/null
++++ khelpcenter/searchhandlers/khc_beagle_index.pl
+@@ -0,0 +1,49 @@
++#!/usr/bin/perl
++# vim:sw=4:et
++
++use warnings;
++
++sub getKDEDocDir()
++{
++ my $prefix = `kde-config --prefix`;
++ chomp $prefix;
++
++ $prefix = "/opt/kde" if (not defined($prefix));
++ return "$prefix/share/doc";
++}
++
++sub addRoot()
++{
++ my $kdedocdir = &getKDEDocDir;
++
++ open (IN, "-|") || exec "beagle-config", "indexing", "ListRoots";
++
++ my $kdedoc_found = 0;
++ while(<IN>) {
++ if (/^$kdedocdir/o) {
++ $kdedoc_found = 1;
++ last;
++ }
++ }
++ close(IN);
++
++ if (not $kdedoc_found) {
++ `beagle-config indexing AddRoot $kdedocdir`;
++ `beagle-config indexing AddRoot $kdedocdir-bundle`;
++ }
++}
++
++sub createExistsFile($$)
++{
++ my ($idir, $ident) = @_;
++
++ open(OUT, ">", "$idir/$idir");
++ close(OUT);
++}
++
++my $idir = $ARGV[0];
++my $ident = $ARGV[1];
++
++if (addRoot) {
++ createExistsFile($idir, $ident);
++}
+Index: khelpcenter/searchhandlers/docbook.desktop
+===================================================================
+--- khelpcenter/searchhandlers/docbook.desktop.orig
++++ khelpcenter/searchhandlers/docbook.desktop
+@@ -2,5 +2,5 @@
+
+ DocumentTypes=text/docbook
+
+-SearchCommand=khc_htsearch.pl --docbook --indexdir=%d --config=%i --words=%w --method=%o --maxnum=%m --lang=en
+-IndexCommand=khc_docbookdig.pl --indexdir=%d --docpath=%p --identifier=%i
++SearchCommand=khc_beagle_search.pl --method=%o --maxnum=%m %w
++IndexCommand=khc_beagle_index.pl %d %i
+Index: khelpcenter/searchhandlers/Makefile.am
+===================================================================
+--- khelpcenter/searchhandlers/Makefile.am.orig
++++ khelpcenter/searchhandlers/Makefile.am
+@@ -3,7 +3,7 @@ searchhandlers_DATA = htdig.desktop man.
+ searchhandlersdir = $(kde_datadir)/khelpcenter/searchhandlers
+
+ kde_bin_SCRIPTS = khc_htdig.pl khc_htsearch.pl khc_mansearch.pl \
+- khc_docbookdig.pl
++ khc_docbookdig.pl khc_beagle_search.pl khc_beagle_index.pl
+
+ htdigdata_DATA = htdig_long.html
+
diff --git a/opensuse/tdebase/khelpcenter-delayed-indexcheck.cpp b/opensuse/tdebase/khelpcenter-delayed-indexcheck.cpp
new file mode 100644
index 000000000..37c3f195c
--- /dev/null
+++ b/opensuse/tdebase/khelpcenter-delayed-indexcheck.cpp
@@ -0,0 +1,23 @@
+Index: khelpcenter/navigator.cpp
+===================================================================
+--- khelpcenter/navigator.cpp.orig
++++ khelpcenter/navigator.cpp
+@@ -121,8 +121,6 @@ Navigator::Navigator( View *view, QWidge
+
+ mTabWidget = new QTabWidget( this );
+ topLayout->addWidget( mTabWidget );
+- connect( mTabWidget, SIGNAL( currentChanged( QWidget * ) ),
+- SLOT( slotTabChanged( QWidget * ) ) );
+
+ setupContentsTab();
+ setupGlossaryTab();
+@@ -136,6 +134,9 @@ Navigator::Navigator( View *view, QWidge
+ mSearchWidget->updateScopeList();
+ mSearchWidget->readConfig( KGlobal::config() );
+ }
++
++ connect( mTabWidget, SIGNAL( currentChanged( QWidget * ) ),
++ SLOT( slotTabChanged( QWidget * ) ) );
+ }
+
+ Navigator::~Navigator()
diff --git a/opensuse/tdebase/khelpcenter-gnome-support-legacy.patch b/opensuse/tdebase/khelpcenter-gnome-support-legacy.patch
new file mode 100644
index 000000000..fb9a11ee4
--- /dev/null
+++ b/opensuse/tdebase/khelpcenter-gnome-support-legacy.patch
@@ -0,0 +1,327 @@
+Index: khelpcenter/table-of-contents.xslt
+================================================================================
+--- khelpcenter/docentry.cpp
++++ khelpcenter/docentry.cpp
+@@ -1,5 +1,6 @@
+ #include <qregexp.h>
+ #include <qfileinfo.h>
++#include <stdlib.h>
+
+ #include <kdebug.h>
+ #include <kdesktopfile.h>
+@@ -206,6 +207,37 @@
+ {
+ KDesktopFile file( fileName );
+
++ static QString desktop;
++ if (desktop.isNull()) {
++ QString win_man = getenv("WINDOWMANAGER");
++ if (win_man.contains ("gnome", FALSE))
++ desktop = "GNOME";
++ else if (win_man.contains ("kde", FALSE))
++ desktop = "KDE";
++ else
++ desktop = "";
++ kdDebug() << "DocEntry::desktop = " << desktop << endl;
++ };
++
++ QString onlyShowIn = file.readEntry ("OnlyShowIn");
++
++ kdDebug() << "DocEntry::readFromFile(): " << fileName << " onlyShowIn = " << onlyShowIn << endl;
++
++ if ( !onlyShowIn.isNull() ) {
++ if (desktop.isEmpty())
++ return false;
++ QStringList list = QStringList::split (";", onlyShowIn);
++ if ( ! list.contains (desktop) )
++ return false;
++ }
++
++ QString notShowIn = file.readEntry ("NotShowIn");
++ if ( !notShowIn.isNull() ) {
++ QStringList list = QStringList::split (";", notShowIn);
++ if ( list.contains (desktop) )
++ return false;
++ }
++
+ mName = file.readName();
+ mSearch = file.readEntry( "X-DOC-Search" );
+ mIcon = file.readIcon();
+--- khelpcenter/navigator.cpp
++++ khelpcenter/navigator.cpp
+@@ -22,6 +22,7 @@
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
++#include <stdlib.h>
+
+ #include <qdir.h>
+ #include <qfile.h>
+@@ -275,6 +276,38 @@
+ const QString &file )
+ {
+ KDesktopFile desktopFile( file );
++
++ static QString desktop;
++ if (desktop.isNull()) {
++ QString win_man = getenv("WINDOWMANAGER");
++ if (win_man.contains ("gnome", FALSE))
++ desktop = "GNOME";
++ else if (win_man.contains ("kde", FALSE))
++ desktop = "KDE";
++ else
++ desktop = "";
++ kdDebug() << "Navigator::desktop = " << desktop << endl;
++ };
++
++ QString onlyShowIn = desktopFile.readEntry ("OnlyShowIn");
++
++ kdDebug() << "Navigator::createItemFromDesktopFile(): " << file << " onlyShowIn = " << onlyShowIn << endl;
++
++ if ( !onlyShowIn.isNull() ) {
++ if (desktop.isEmpty())
++ return;
++ QStringList list = QStringList::split (";", onlyShowIn);
++ if ( ! list.contains (desktop) )
++ return;
++ }
++
++ QString notShowIn = desktopFile.readEntry ("NotShowIn");
++ if ( !notShowIn.isNull() ) {
++ QStringList list = QStringList::split (";", notShowIn);
++ if ( list.contains (desktop) )
++ return;
++ }
++
+ QString docPath = desktopFile.readDocPath();
+ if ( !docPath.isNull() ) {
+ // First parameter is ignored if second is an absolute path
+@@ -317,6 +350,9 @@
+ {
+ alternativeURL.setQuery("anchor="+url.ref());
+ alternativeURL.setRef(QString::null);
++ } else if (url.url().endsWith("/index.html"))
++ {
++ alternativeURL = KURL (url.url().left (url.url().length() - strlen ("/index.html")));
+ }
+
+ // If the navigator already has the given URL selected, do nothing.
+@@ -401,15 +437,43 @@
+ TOC *tocTree = item->createTOC();
+ kdDebug( 1400 ) << "slotItemSelected(): Trying to build TOC for "
+ << item->entry()->name() << endl;
+- tocTree->setApplication( url.directory() );
++ if (url.directory() != "/")
++ tocTree->setApplication( url.directory() );
++ else
++ tocTree->setApplication( url.path() );
+ QString doc = View::langLookup( url.path() );
+ // Enforce the original .docbook version, in case langLookup returns a
+ // cached version
+ if ( !doc.isNull() ) {
+- int pos = doc.find( ".html" );
+- if ( pos >= 0 ) {
+- doc.replace( pos, 5, ".docbook" );
+- }
++ if (doc.endsWith( ".html" )) {
++ doc = doc.left (doc.length() - 5) + ".docbook";
++ }
++
++ QFileInfo di (doc);
++ if (!di.isFile()) {
++
++ int last_slash = doc.findRev ('/');
++ if (last_slash >= 1) {
++
++ QString filename = doc.right(doc.length() - last_slash - 1);
++ if (filename == "index.html" || filename == "") {
++
++ int slash2 = doc.findRev('/', last_slash -1);
++ if (slash2 != -1 && slash2 != 0) {
++
++ int slash3 = doc.findRev('/', slash2 - 1);
++ if (slash3 != -1) {
++ QString xml_file = doc.left(last_slash) + "/" + doc.mid(slash3 + 1, slash2 - (slash3 + 1)) + ".xml";
++ kdDebug() << "xml_file " << xml_file << endl;
++ QFileInfo fi(xml_file);
++ if (fi.exists())
++ doc = xml_file;
++
++ }
++ }
++ }
++ }
++ }
+ kdDebug( 1400 ) << "slotItemSelected(): doc = " << doc << endl;
+
+ tocTree->build( doc );
+--- khelpcenter/navigatorappitem.cpp
++++ khelpcenter/navigatorappitem.cpp
+@@ -21,6 +21,8 @@
+
+ #include "docentry.h"
+
++#include <stdlib.h>
++
+ #include <kdebug.h>
+ #include <kservicegroup.h>
+
+@@ -134,11 +136,42 @@
+
+ QString NavigatorAppItem::documentationURL( KService *s )
+ {
++ static QString desktop;
++ if (desktop.isNull()) {
++ QString win_man = getenv("WINDOWMANAGER");
++ if (win_man.contains ("gnome", FALSE))
++ desktop = "GNOME";
++ else if (win_man.contains ("kde", FALSE))
++ desktop = "KDE";
++ else
++ desktop = "";
++ kdDebug() << "NavigatorAppItem::desktop = " << desktop << endl;
++ };
++
++ QString onlyShowIn = s->property("OnlyShowIn", QVariant::String).toString();
++
++ kdDebug() << "NavigatorAppItem::onlyShowIn = " << onlyShowIn << endl;
++
++ if ( !onlyShowIn.isNull() ) {
++ if (desktop.isEmpty())
++ return QString::null;
++ QStringList list = QStringList::split (";", onlyShowIn);
++ if ( ! list.contains (desktop) )
++ return QString::null;
++ }
++
++ QString notShowIn = s->property("NotShowIn", QVariant::String).toString();
++ if ( !notShowIn.isNull() ) {
++ QStringList list = QStringList::split (";", notShowIn);
++ if ( list.contains (desktop) )
++ return QString::null;
++ }
++
+ QString docPath = s->property( "DocPath" ).toString();
+ if ( docPath.isEmpty() )
+ return QString::null;
+
+- if ( docPath.startsWith( "file:") || docPath.startsWith( "http:" ) )
++ if ( docPath.startsWith( "file:") || docPath.startsWith( "http:" ) || docPath.startsWith( "ghelp:" ))
+ return docPath;
+
+ return QString( "help:/" ) + docPath;
+--- khelpcenter/table-of-contents.xslt
++++ khelpcenter/table-of-contents.xslt
+@@ -8,6 +8,12 @@
+ </table-of-contents>
+ </xsl:template>
+
++<xsl:template match="article">
++<table-of-contents>
++<xsl:apply-templates select="sect1"/>
++</table-of-contents>
++</xsl:template>
++
+ <xsl:template match="chapter">
+ <chapter>
+ <title><xsl:value-of select="title"/></title>
+@@ -20,7 +26,15 @@
+ <section>
+ <title><xsl:value-of select="title"/></title>
+ <anchor><xsl:value-of select="@id"/></anchor>
++<xsl:apply-templates select="sect2"/>
+ </section>
+ </xsl:template>
+
++<xsl:template match="sect2">
++<subsection>
++<title><xsl:value-of select="title"/></title>
++<anchor><xsl:value-of select="@id"/></anchor>
++</subsection>
++</xsl:template>
++
+ </xsl:stylesheet>
+--- khelpcenter/view.cpp
++++ khelpcenter/view.cpp
+@@ -146,21 +146,51 @@
+ // assemble the local search paths
+ const QStringList localDoc = KGlobal::dirs()->resourceDirs("html");
+
++ kdDebug() << "Looking up help for: " << fname << endl;
++
++ QString path;
++ QString file_name;
++ int slash = fname.findRev ('/');
++ if (slash == -1 || slash == 0) {
++ path = fname;
++ file_name = "/";
++ } else {
++ path = fname.left (slash);
++ file_name = fname.right (fname.length() - slash);
++ }
++
++ QStringList langs = KGlobal::locale()->languageList();
++ QStringList::ConstIterator lang;
++ for (lang = langs.begin(); lang != langs.end(); ++lang)
++ if (*lang == "en")
++ search.append(QString("/opt/gnome/share/gnome/help/%1/C%2").arg(path).arg(file_name));
++ else
++ search.append(QString("/opt/gnome/share/gnome/help/%1/%2%3").arg(path).arg(*lang).arg(file_name));
++
++ langs.append( "en" );
++ langs.remove( "C" );
++
++ // this is kind of compat hack as we install our docs in en/ but the
++ // default language is en_US
++ for (QStringList::Iterator it = langs.begin(); it != langs.end(); ++it)
++ if ( *it == "en_US" )
++ *it = "en";
++
+ // look up the different languages
+- for (int id=localDoc.count()-1; id >= 0; --id)
++ int ldCount = localDoc.count();
++ for (int id=0; id < ldCount; id++)
+ {
+- QStringList langs = KGlobal::locale()->languageList();
+- langs.append( "en" );
+- langs.remove( "C" );
+ QStringList::ConstIterator lang;
+ for (lang = langs.begin(); lang != langs.end(); ++lang)
+- search.append(QString("%1%2/%3").arg(localDoc[id]).arg(*lang).arg(fname));
++ search.append(QString("%1%2/%3").arg(localDoc[id]).arg(*lang).arg(path + file_name));
+ }
+
+ // try to locate the file
+ QStringList::Iterator it;
+ for (it = search.begin(); it != search.end(); ++it)
+ {
++ kdDebug() << "Looking for help in: " << *it << endl;
++
+ QFileInfo info(*it);
+ if (info.exists() && info.isFile() && info.isReadable())
+ return *it;
+@@ -168,7 +198,7 @@
+ // Fall back to the index.docbook for this language if we couldn't find its
+ // specific docbook file. If we are not looking up docbook (images,
+ // css etc) then look in other languages first.
+- if ( ( *it ).endsWith( "docbook" ) )
++ if ( ( *it ).endsWith( "docbook" ) || ( *it).endsWith( ".xml") )
+ {
+ QString file = (*it).left((*it).findRev('/')) + "/index.docbook";
+ info.setFile(file);
+@@ -176,9 +206,15 @@
+ {
+ return *it;
+ }
++
++ file = (*it).left((*it).findRev('/')) + "/" + path + ".xml";
++ info.setFile(file);
++ if (info.exists() && info.isFile() && info.isReadable())
++ return *it;
+ }
+ }
+
++
+ return QString::null;
+ }
+
diff --git a/opensuse/tdebase/khelpcenter-gnome-support.patch b/opensuse/tdebase/khelpcenter-gnome-support.patch
new file mode 100644
index 000000000..d98ae01dc
--- /dev/null
+++ b/opensuse/tdebase/khelpcenter-gnome-support.patch
@@ -0,0 +1,335 @@
+Index: khelpcenter/docentry.cpp
+===================================================================
+--- khelpcenter/docentry.cpp.orig
++++ khelpcenter/docentry.cpp
+@@ -1,5 +1,6 @@
+ #include <qregexp.h>
+ #include <qfileinfo.h>
++#include <stdlib.h>
+
+ #include <kdebug.h>
+ #include <kdesktopfile.h>
+@@ -206,6 +207,37 @@ bool DocEntry::readFromFile( const QStri
+ {
+ KDesktopFile file( fileName );
+
++ static QString desktop;
++ if (desktop.isNull()) {
++ QString win_man = getenv("WINDOWMANAGER");
++ if (win_man.contains ("gnome", FALSE))
++ desktop = "GNOME";
++ else if (win_man.contains ("kde", FALSE))
++ desktop = "KDE";
++ else
++ desktop = "";
++ kdDebug() << "DocEntry::desktop = " << desktop << endl;
++ };
++
++ QString onlyShowIn = file.readEntry ("OnlyShowIn");
++
++ kdDebug() << "DocEntry::readFromFile(): " << fileName << " onlyShowIn = " << onlyShowIn << endl;
++
++ if ( !onlyShowIn.isNull() ) {
++ if (desktop.isEmpty())
++ return false;
++ QStringList list = QStringList::split (";", onlyShowIn);
++ if ( ! list.contains (desktop) )
++ return false;
++ }
++
++ QString notShowIn = file.readEntry ("NotShowIn");
++ if ( !notShowIn.isNull() ) {
++ QStringList list = QStringList::split (";", notShowIn);
++ if ( list.contains (desktop) )
++ return false;
++ }
++
+ mName = file.readName();
+ mSearch = file.readEntry( "X-DOC-Search" );
+ mIcon = file.readIcon();
+Index: khelpcenter/navigator.cpp
+===================================================================
+--- khelpcenter/navigator.cpp.orig
++++ khelpcenter/navigator.cpp
+@@ -22,6 +22,7 @@
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
++#include <stdlib.h>
+
+ #include <qdir.h>
+ #include <qfile.h>
+@@ -275,6 +276,38 @@ void Navigator::createItemFromDesktopFil
+ const QString &file )
+ {
+ KDesktopFile desktopFile( file );
++
++ static QString desktop;
++ if (desktop.isNull()) {
++ QString win_man = getenv("WINDOWMANAGER");
++ if (win_man.contains ("gnome", FALSE))
++ desktop = "GNOME";
++ else if (win_man.contains ("kde", FALSE))
++ desktop = "KDE";
++ else
++ desktop = "";
++ kdDebug() << "Navigator::desktop = " << desktop << endl;
++ };
++
++ QString onlyShowIn = desktopFile.readEntry ("OnlyShowIn");
++
++ kdDebug() << "Navigator::createItemFromDesktopFile(): " << file << " onlyShowIn = " << onlyShowIn << endl;
++
++ if ( !onlyShowIn.isNull() ) {
++ if (desktop.isEmpty())
++ return;
++ QStringList list = QStringList::split (";", onlyShowIn);
++ if ( ! list.contains (desktop) )
++ return;
++ }
++
++ QString notShowIn = desktopFile.readEntry ("NotShowIn");
++ if ( !notShowIn.isNull() ) {
++ QStringList list = QStringList::split (";", notShowIn);
++ if ( list.contains (desktop) )
++ return;
++ }
++
+ QString docPath = desktopFile.readDocPath();
+ if ( !docPath.isNull() ) {
+ // First parameter is ignored if second is an absolute path
+@@ -317,6 +350,9 @@ void Navigator::selectItem( const KURL &
+ {
+ alternativeURL.setQuery("anchor="+url.ref());
+ alternativeURL.setRef(QString::null);
++ } else if (url.url().endsWith("/index.html"))
++ {
++ alternativeURL = KURL (url.url().left (url.url().length() - strlen ("/index.html")));
+ }
+
+ // If the navigator already has the given URL selected, do nothing.
+@@ -401,15 +437,43 @@ void Navigator::slotItemSelected( QListV
+ TOC *tocTree = item->createTOC();
+ kdDebug( 1400 ) << "slotItemSelected(): Trying to build TOC for "
+ << item->entry()->name() << endl;
+- tocTree->setApplication( url.directory() );
++ if (url.directory() != "/")
++ tocTree->setApplication( url.directory() );
++ else
++ tocTree->setApplication( url.path() );
+ QString doc = View::langLookup( url.path() );
+ // Enforce the original .docbook version, in case langLookup returns a
+ // cached version
+ if ( !doc.isNull() ) {
+- int pos = doc.find( ".html" );
+- if ( pos >= 0 ) {
+- doc.replace( pos, 5, ".docbook" );
+- }
++ if (doc.endsWith( ".html" )) {
++ doc = doc.left (doc.length() - 5) + ".docbook";
++ }
++
++ QFileInfo di (doc);
++ if (!di.isFile()) {
++
++ int last_slash = doc.findRev ('/');
++ if (last_slash >= 1) {
++
++ QString filename = doc.right(doc.length() - last_slash - 1);
++ if (filename == "index.html" || filename == "") {
++
++ int slash2 = doc.findRev('/', last_slash -1);
++ if (slash2 != -1 && slash2 != 0) {
++
++ int slash3 = doc.findRev('/', slash2 - 1);
++ if (slash3 != -1) {
++ QString xml_file = doc.left(last_slash) + "/" + doc.mid(slash3 + 1, slash2 - (slash3 + 1)) + ".xml";
++ kdDebug() << "xml_file " << xml_file << endl;
++ QFileInfo fi(xml_file);
++ if (fi.exists())
++ doc = xml_file;
++
++ }
++ }
++ }
++ }
++ }
+ kdDebug( 1400 ) << "slotItemSelected(): doc = " << doc << endl;
+
+ tocTree->build( doc );
+Index: khelpcenter/navigatorappitem.cpp
+===================================================================
+--- khelpcenter/navigatorappitem.cpp.orig
++++ khelpcenter/navigatorappitem.cpp
+@@ -21,6 +21,8 @@
+
+ #include "docentry.h"
+
++#include <stdlib.h>
++
+ #include <kdebug.h>
+ #include <kservicegroup.h>
+
+@@ -134,11 +136,42 @@ void NavigatorAppItem::populate( bool re
+
+ QString NavigatorAppItem::documentationURL( KService *s )
+ {
++ static QString desktop;
++ if (desktop.isNull()) {
++ QString win_man = getenv("WINDOWMANAGER");
++ if (win_man.contains ("gnome", FALSE))
++ desktop = "GNOME";
++ else if (win_man.contains ("kde", FALSE))
++ desktop = "KDE";
++ else
++ desktop = "";
++ kdDebug() << "NavigatorAppItem::desktop = " << desktop << endl;
++ };
++
++ QString onlyShowIn = s->property("OnlyShowIn", QVariant::String).toString();
++
++ kdDebug() << "NavigatorAppItem::onlyShowIn = " << onlyShowIn << endl;
++
++ if ( !onlyShowIn.isNull() ) {
++ if (desktop.isEmpty())
++ return QString::null;
++ QStringList list = QStringList::split (";", onlyShowIn);
++ if ( ! list.contains (desktop) )
++ return QString::null;
++ }
++
++ QString notShowIn = s->property("NotShowIn", QVariant::String).toString();
++ if ( !notShowIn.isNull() ) {
++ QStringList list = QStringList::split (";", notShowIn);
++ if ( list.contains (desktop) )
++ return QString::null;
++ }
++
+ QString docPath = s->property( "DocPath" ).toString();
+ if ( docPath.isEmpty() )
+ return QString::null;
+
+- if ( docPath.startsWith( "file:") || docPath.startsWith( "http:" ) )
++ if ( docPath.startsWith( "file:") || docPath.startsWith( "http:" ) || docPath.startsWith( "ghelp:" ))
+ return docPath;
+
+ return QString( "help:/" ) + docPath;
+Index: khelpcenter/table-of-contents.xslt
+===================================================================
+--- khelpcenter/table-of-contents.xslt.orig
++++ khelpcenter/table-of-contents.xslt
+@@ -8,6 +8,12 @@
+ </table-of-contents>
+ </xsl:template>
+
++<xsl:template match="article">
++<table-of-contents>
++<xsl:apply-templates select="sect1"/>
++</table-of-contents>
++</xsl:template>
++
+ <xsl:template match="chapter">
+ <chapter>
+ <title><xsl:value-of select="title"/></title>
+@@ -20,7 +26,15 @@
+ <section>
+ <title><xsl:value-of select="title"/></title>
+ <anchor><xsl:value-of select="@id"/></anchor>
++<xsl:apply-templates select="sect2"/>
+ </section>
+ </xsl:template>
+
++<xsl:template match="sect2">
++<subsection>
++<title><xsl:value-of select="title"/></title>
++<anchor><xsl:value-of select="@id"/></anchor>
++</subsection>
++</xsl:template>
++
+ </xsl:stylesheet>
+Index: khelpcenter/view.cpp
+===================================================================
+--- khelpcenter/view.cpp.orig
++++ khelpcenter/view.cpp
+@@ -150,21 +150,51 @@ QString View::langLookup( const QString
+ // assemble the local search paths
+ const QStringList localDoc = KGlobal::dirs()->resourceDirs("html");
+
++ kdDebug() << "Looking up help for: " << fname << endl;
++
++ QString path;
++ QString file_name;
++ int slash = fname.findRev ('/');
++ if (slash == -1 || slash == 0) {
++ path = fname;
++ file_name = "/";
++ } else {
++ path = fname.left (slash);
++ file_name = fname.right (fname.length() - slash);
++ }
++
++ QStringList langs = KGlobal::locale()->languageList();
++ QStringList::ConstIterator lang;
++ for (lang = langs.begin(); lang != langs.end(); ++lang)
++ if (*lang == "en")
++ search.append(QString("/usr/share/gnome/help/%1/C%2").arg(path).arg(file_name));
++ else
++ search.append(QString("/usr/share/gnome/help/%1/%2%3").arg(path).arg(*lang).arg(file_name));
++
++ langs.append( "en" );
++ langs.remove( "C" );
++
++ // this is kind of compat hack as we install our docs in en/ but the
++ // default language is en_US
++ for (QStringList::Iterator it = langs.begin(); it != langs.end(); ++it)
++ if ( *it == "en_US" )
++ *it = "en";
++
+ // look up the different languages
+- for (int id=localDoc.count()-1; id >= 0; --id)
++ int ldCount = localDoc.count();
++ for (int id=0; id < ldCount; id++)
+ {
+- QStringList langs = KGlobal::locale()->languageList();
+- langs.append( "en" );
+- langs.remove( "C" );
+ QStringList::ConstIterator lang;
+ for (lang = langs.begin(); lang != langs.end(); ++lang)
+- search.append(QString("%1%2/%3").arg(localDoc[id]).arg(*lang).arg(fname));
++ search.append(QString("%1%2/%3").arg(localDoc[id]).arg(*lang).arg(path + file_name));
+ }
+
+ // try to locate the file
+ QStringList::Iterator it;
+ for (it = search.begin(); it != search.end(); ++it)
+ {
++ kdDebug() << "Looking for help in: " << *it << endl;
++
+ QFileInfo info(*it);
+ if (info.exists() && info.isFile() && info.isReadable())
+ return *it;
+@@ -172,7 +202,7 @@ QString View::langLookup( const QString
+ // Fall back to the index.docbook for this language if we couldn't find its
+ // specific docbook file. If we are not looking up docbook (images,
+ // css etc) then look in other languages first.
+- if ( ( *it ).endsWith( "docbook" ) )
++ if ( ( *it ).endsWith( "docbook" ) || ( *it).endsWith( ".xml") )
+ {
+ QString file = (*it).left((*it).findRev('/')) + "/index.docbook";
+ info.setFile(file);
+@@ -180,9 +210,15 @@ QString View::langLookup( const QString
+ {
+ return *it;
+ }
++
++ file = (*it).left((*it).findRev('/')) + "/" + path + ".xml";
++ info.setFile(file);
++ if (info.exists() && info.isFile() && info.isReadable())
++ return *it;
+ }
+ }
+
++
+ return QString::null;
+ }
+
diff --git a/opensuse/tdebase/khelpcenter-localindices.patch b/opensuse/tdebase/khelpcenter-localindices.patch
new file mode 100644
index 000000000..a2b41a78a
--- /dev/null
+++ b/opensuse/tdebase/khelpcenter-localindices.patch
@@ -0,0 +1,41 @@
+Index: khelpcenter/kcmhelpcenter.cpp
+===================================================================
+--- khelpcenter/kcmhelpcenter.cpp.orig
++++ khelpcenter/kcmhelpcenter.cpp
+@@ -321,6 +321,7 @@ bool KCMHelpCenter::save()
+
+ void KCMHelpCenter::load()
+ {
++ findWriteableIndexDir();
+ mIndexDirLabel->setText( Prefs::indexDirectory() );
+
+ mListView->clear();
+@@ -675,6 +676,12 @@ void KCMHelpCenter::checkSelection()
+ enableButtonOK( count != 0 );
+ }
+
++void KCMHelpCenter::findWriteableIndexDir()
++{
++ QFileInfo currentDir( Prefs::indexDirectory() );
++ if ( !currentDir.isWritable() )
++ Prefs::setIndexDirectory( KGlobal::dirs()->saveLocation("data", "khelpcenter/index/") );
++}
+ #include "kcmhelpcenter.moc"
+
+ // vim:ts=2:sw=2:et
+Index: khelpcenter/kcmhelpcenter.h
+===================================================================
+--- khelpcenter/kcmhelpcenter.h.orig
++++ khelpcenter/kcmhelpcenter.h
+@@ -146,6 +146,11 @@ class KCMHelpCenter : public KDialogBase
+
+ void advanceProgress();
+
++ /**
++ * Find a user-writeable location for the indices, if the current location
++ * is not.
++ */
++ void findWriteableIndexDir();
+ private:
+ KHC::SearchEngine *mEngine;
+
diff --git a/opensuse/tdebase/khelpcenter-use-suseconfig-indexer.diff b/opensuse/tdebase/khelpcenter-use-suseconfig-indexer.diff
new file mode 100644
index 000000000..e63e26ff7
--- /dev/null
+++ b/opensuse/tdebase/khelpcenter-use-suseconfig-indexer.diff
@@ -0,0 +1,25 @@
+Index: khelpcenter/navigator.cpp
+===================================================================
+--- khelpcenter/navigator.cpp.orig
++++ khelpcenter/navigator.cpp
+@@ -654,10 +654,16 @@ void Navigator::hideSearch()
+
+ bool Navigator::checkSearchIndex()
+ {
+- KConfig *cfg = KGlobal::config();
+- cfg->setGroup( "Search" );
+- if ( cfg->readBoolEntry( "IndexExists", false ) ) return true;
+-
++ // just check that the index dir contains something
++ QDir indexDir( Prefs::indexDirectory() );
++ QStringList dirEntries = indexDir.entryList();
++ QStringList::Iterator it = dirEntries.begin();
++ const QStringList::Iterator end = dirEntries.end();
++ for ( ; it != end; ++it )
++ {
++ if ( *it != "." && *it != ".." )
++ return true;
++ }
+ if ( mIndexDialog && mIndexDialog->isShown() ) return true;
+
+ QString text = i18n( "A search index does not yet exist. Do you want "
diff --git a/opensuse/tdebase/khelpcenter-use-susehelp.diff b/opensuse/tdebase/khelpcenter-use-susehelp.diff
new file mode 100644
index 000000000..6c130a6d1
--- /dev/null
+++ b/opensuse/tdebase/khelpcenter-use-susehelp.diff
@@ -0,0 +1,13 @@
+Index: kdebase-3.5.10/khelpcenter/khelpcenter.desktop
+===================================================================
+--- kdebase-3.5.10.orig/khelpcenter/khelpcenter.desktop
++++ kdebase-3.5.10/khelpcenter/khelpcenter.desktop
+@@ -127,7 +127,7 @@ Icon=khelpcenter
+ DocPath=khelpcenter/index.html
+ Type=Service
+ Terminal=false
+-Exec=khelpcenter %u
++Exec=susehelp %u
+ SwallowExec=
+ SwallowTitle=
+ X-KDE-StartupNotify=true
diff --git a/opensuse/tdebase/khotkeys-multimedia-action.diff b/opensuse/tdebase/khotkeys-multimedia-action.diff
new file mode 100644
index 000000000..050e31d60
--- /dev/null
+++ b/opensuse/tdebase/khotkeys-multimedia-action.diff
@@ -0,0 +1,345 @@
+Index: khotkeys/data/multimedia_keys.khotkeys
+===================================================================
+--- /dev/null
++++ khotkeys/data/multimedia_keys.khotkeys
+@@ -0,0 +1,311 @@
++[Data]
++DataCount=1
++
++[Data_1]
++Comment=This group contains actions that are set up by default.\n
++DataCount=8
++Enabled=true
++Name=Preset Actions
++SystemGroup=0
++Type=ACTION_DATA_GROUP
++AllowMerge=true
++
++[Data_1Conditions]
++Comment=
++ConditionsCount=0
++
++[Data_1_1]
++Comment=Opens the My Computer window when the multimedia My Computer key is pressed.\n
++Enabled=true
++Name=My Computer
++Type=COMMAND_URL_SHORTCUT_ACTION_DATA
++
++[Data_1_1Actions]
++ActionsCount=1
++
++[Data_1_1Actions0]
++CommandURL=sysinfo:/
++Type=COMMAND_URL
++
++[Data_1_1Conditions]
++Comment=
++ConditionsCount=0
++
++[Data_1_1Triggers]
++Comment=Simple_action
++TriggersCount=1
++
++[Data_1_1Triggers0]
++Key=XF86MyComputer
++Type=SHORTCUT
++
++[Data_1_2]
++Comment=Launch or activate Amarok when the multimedia Media key is pressed.\n
++Enabled=true
++Name=Media
++Type=COMMAND_URL_SHORTCUT_ACTION_DATA
++
++[Data_1_2Actions]
++ActionsCount=1
++
++[Data_1_2Actions0]
++CommandURL=amarok
++Type=COMMAND_URL
++
++[Data_1_2Conditions]
++Comment=
++ConditionsCount=0
++
++[Data_1_2Triggers]
++Comment=Simple_action
++TriggersCount=1
++
++[Data_1_2Triggers0]
++Key=XF86AudioMedia
++Type=SHORTCUT
++
++[Data_1_3]
++Comment=When the multimedia Calculator key is pressed, KCalc is either launched or activated if it is already running.\n
++DataCount=2
++Enabled=true
++Name=Calculator
++SystemGroup=0
++Type=ACTION_DATA_GROUP
++
++[Data_1_3Conditions]
++Comment=
++ConditionsCount=0
++
++[Data_1_3_1]
++Comment=Runs KCalc if it is not already running.\n
++Enabled=true
++Name=Run KCalc
++Type=GENERIC_ACTION_DATA
++
++[Data_1_3_1Actions]
++ActionsCount=1
++
++[Data_1_3_1Actions0]
++CommandURL=kcalc
++Type=COMMAND_URL
++
++[Data_1_3_1Conditions]
++Comment=
++ConditionsCount=1
++
++[Data_1_3_1Conditions0]
++ConditionsCount=1
++Type=NOT
++
++[Data_1_3_1Conditions00]
++Type=EXISTING_WINDOW
++
++[Data_1_3_1Conditions00Window]
++Comment=kcalc
++WindowsCount=1
++
++[Data_1_3_1Conditions00Window0]
++Class=kcalc Kcalc
++ClassType=2
++Comment=kcalc
++Role=kcalc-mainwindow#1
++RoleType=0
++Title=KCalc
++TitleType=0
++Type=SIMPLE
++WindowTypes=1
++
++[Data_1_3_1Triggers]
++Comment=
++TriggersCount=1
++
++[Data_1_3_1Triggers0]
++Key=XF86Calculator
++Type=SHORTCUT
++
++[Data_1_3_2]
++Comment=Activates KCalc window if it is already running.\n
++Enabled=true
++Name=Activate KCalc
++Type=GENERIC_ACTION_DATA
++
++[Data_1_3_2Actions]
++ActionsCount=1
++
++[Data_1_3_2Actions0]
++Type=ACTIVATE_WINDOW
++
++[Data_1_3_2Actions0Window]
++Comment=kcalc
++WindowsCount=1
++
++[Data_1_3_2Actions0Window0]
++Class=kcalc Kcalc
++ClassType=2
++Comment=kcalc
++Role=kcalc-mainwindow#1
++RoleType=0
++Title=KCalc
++TitleType=0
++Type=SIMPLE
++WindowTypes=1
++
++[Data_1_3_2Conditions]
++Comment=
++ConditionsCount=1
++
++[Data_1_3_2Conditions0]
++Type=EXISTING_WINDOW
++
++[Data_1_3_2Conditions0Window]
++Comment=kcalc
++WindowsCount=1
++
++[Data_1_3_2Conditions0Window0]
++Class=kcalc Kcalc
++ClassType=2
++Comment=kcalc
++Role=kcalc-mainwindow#1
++RoleType=0
++Title=KCalc
++TitleType=0
++Type=SIMPLE
++WindowTypes=1
++
++[Data_1_3_2Triggers]
++Comment=
++TriggersCount=1
++
++[Data_1_3_2Triggers0]
++Key=XF86Calculator
++Type=SHORTCUT
++
++[Data_1_4]
++Comment=Launches the default terminal application when the multimedia Terminal key is pressed.\n
++Enabled=true
++Name=Terminal
++Type=COMMAND_URL_SHORTCUT_ACTION_DATA
++
++[Data_1_4Actions]
++ActionsCount=1
++
++[Data_1_4Actions0]
++CommandURL=KHOTKEYS_TERMINAL
++Type=COMMAND_URL
++
++[Data_1_4Conditions]
++Comment=
++ConditionsCount=0
++
++[Data_1_4Triggers]
++Comment=Simple_action
++TriggersCount=1
++
++[Data_1_4Triggers0]
++Key=XF86Terminal
++Type=SHORTCUT
++
++[Data_1_5]
++Comment=Opens the default browser when the multimedia WWW key is pressed.\n
++Enabled=true
++Name=Browser (HomePage)
++Type=COMMAND_URL_SHORTCUT_ACTION_DATA
++
++[Data_1_5Actions]
++ActionsCount=1
++
++[Data_1_5Actions0]
++CommandURL=KHOTKEYS_BROWSER
++Type=COMMAND_URL
++
++[Data_1_5Conditions]
++Comment=
++ConditionsCount=0
++
++[Data_1_5Triggers]
++Comment=Simple_action
++TriggersCount=1
++
++[Data_1_5Triggers0]
++Key=XF86WWW
++Type=SHORTCUT
++
++[Data_1_6]
++Comment=Ejecting when the multimedia Eject key is pressed.\n
++Enabled=true
++Name=Eject
++Type=COMMAND_URL_SHORTCUT_ACTION_DATA
++
++[Data_1_6Actions]
++ActionsCount=1
++
++[Data_1_6Actions0]
++CommandURL=kdeeject ""
++Type=COMMAND_URL
++
++[Data_1_6Conditions]
++Comment=
++ConditionsCount=0
++
++[Data_1_6Triggers]
++Comment=Simple_action
++TriggersCount=1
++
++[Data_1_6Triggers0]
++Key=XF86Eject
++Type=SHORTCUT
++
++[Data_1_7]
++Comment=Launches KFind when the multimedia Search key is pressed.\n
++Enabled=true
++Name=Search
++Type=COMMAND_URL_SHORTCUT_ACTION_DATA
++
++[Data_1_7Actions]
++ActionsCount=1
++
++[Data_1_7Actions0]
++CommandURL=kfind
++Type=COMMAND_URL
++
++[Data_1_7Conditions]
++Comment=
++ConditionsCount=0
++
++[Data_1_7Triggers]
++Comment=Simple_action
++TriggersCount=1
++
++[Data_1_7Triggers0]
++Key=XF86Search
++Type=SHORTCUT
++
++[Data_1_8]
++Comment=Opens a new mail composer window when the multimedia Mail key is pressed.\n
++Enabled=true
++Name=Launch Mail
++Type=COMMAND_URL_SHORTCUT_ACTION_DATA
++
++[Data_1_8Actions]
++ActionsCount=1
++
++[Data_1_8Actions0]
++CommandURL=mailto:?
++Type=COMMAND_URL
++
++[Data_1_8Conditions]
++Comment=
++ConditionsCount=0
++
++[Data_1_8Triggers]
++Comment=Simple_action
++TriggersCount=1
++
++[Data_1_8Triggers0]
++Key=XF86Mail
++Type=SHORTCUT
++
++[Main]
++Version=2
++ImportId=multimedia_keys
++
+Index: khotkeys/data/Makefile.am
+===================================================================
+--- khotkeys/data/Makefile.am.orig
++++ khotkeys/data/Makefile.am
+@@ -1,7 +1,9 @@
+-khotkeys_data_DATA = kde32b1.khotkeys konqueror_gestures_kde321.khotkeys printscreen.khotkeys
++khotkeys_data_DATA = kde32b1.khotkeys konqueror_gestures_kde321.khotkeys printscreen.khotkeys \
++ multimedia_keys.khotkeys
+ khotkeys_datadir = $(kde_datadir)/khotkeys
+
+-khotkeys_update_DATA = khotkeys_32b1_update.upd konqueror_gestures_kde321_update.upd khotkeys_printscreen.upd
++khotkeys_update_DATA = khotkeys_32b1_update.upd konqueror_gestures_kde321_update.upd khotkeys_printscreen.upd \
++ khotkeys_multimedia_keys.upd
+ khotkeys_updatedir = $(kde_datadir)/kconf_update
+
+ EXTRA_DIST = $(khotkeys_data_DATA) $(khotkeys_update_DATA)
+Index: khotkeys/data/khotkeys_multimedia_keys.upd
+===================================================================
+--- /dev/null
++++ khotkeys/data/khotkeys_multimedia_keys.upd
+@@ -0,0 +1,8 @@
++Id=multimedia_keys
++# the file is intentionally a dummy, as the binary will update khotkeysrc,
++# the khotkeys_update will just remember it has been done
++File=khotkeys_update
++Group=Dummy
++Options=overwrite
++ScriptArguments=--id multimedia_keys
++Script=khotkeys_update
diff --git a/opensuse/tdebase/khotkeys-multimedia-action2.diff b/opensuse/tdebase/khotkeys-multimedia-action2.diff
new file mode 100644
index 000000000..9f995b1ab
--- /dev/null
+++ b/opensuse/tdebase/khotkeys-multimedia-action2.diff
@@ -0,0 +1,81 @@
+Index: khotkeys/shared/actions.cpp
+===================================================================
+--- khotkeys/shared/actions.cpp.orig
++++ khotkeys/shared/actions.cpp
+@@ -29,6 +29,7 @@
+ #include <kaccel.h>
+ #include <kservice.h>
+ #include <kprocess.h>
++#include <qregexp.h>
+
+ #include "windows.h"
+ #include "action_data.h"
+@@ -116,7 +117,6 @@ void Command_url_action::execute()
+ {
+ if( command_url().isEmpty())
+ return;
+- KURIFilterData uri;
+ QString cmd = command_url();
+ static bool sm_ready = false;
+ if( !sm_ready )
+@@ -124,6 +124,9 @@ void Command_url_action::execute()
+ kapp->propagateSessionManager();
+ sm_ready = true;
+ }
++ if( substituteAndHandleSpecial( cmd ))
++ return;
++ KURIFilterData uri;
+ // int space_pos = command_url().find( ' ' );
+ // if( command_url()[ 0 ] != '\'' && command_url()[ 0 ] != '"' && space_pos > -1
+ // && command_url()[ space_pos - 1 ] != '\\' )
+@@ -176,6 +179,38 @@ void Command_url_action::execute()
+ timeout.start( 1000, true ); // 1sec timeout
+ }
+
++// do special command substitutions, return true if also already handled
++bool Command_url_action::substituteAndHandleSpecial( QString& cmd )
++ {
++ if( cmd.contains( "KHOTKEYS_BROWSER" ))
++ { // the default browser
++ KConfig config( QString::fromLatin1("kfmclientrc")); // see KRun
++ config.setGroup("General");
++ QString browser = config.readEntry("BrowserApplication");
++ if( browser.startsWith( QString::fromLatin1( "!" )))
++ browser = browser.mid( 1 );
++ else
++ {
++ KService::Ptr service = KService::serviceByStorageId( browser );
++ if( service )
++ {
++ browser = service->exec();
++ browser.replace( QRegExp( " %.?" ), "" ); // remove " %u" and others
++ }
++ }
++ if( browser.isEmpty())
++ browser = QString::fromLatin1( "konqueror" ); // opens in webbrowsing profile by default
++ cmd = cmd.replace( "KHOTKEYS_BROWSER", browser );
++ }
++ if( cmd.contains( "KHOTKEYS_TERMINAL" ))
++ { // the default terminal application
++ KConfigGroup config( KGlobal::config(), "General" );
++ QString terminal = config.readPathEntry( "TerminalApplication", "konsole" );
++ cmd = cmd.replace( "KHOTKEYS_TERMINAL", terminal );
++ }
++ return false;
++ }
++
+ QString Command_url_action::description() const
+ {
+ return i18n( "Command/URL : " ) + command_url();
+Index: khotkeys/shared/actions.h
+===================================================================
+--- khotkeys/shared/actions.h.orig
++++ khotkeys/shared/actions.h
+@@ -75,6 +75,7 @@ class KDE_EXPORT Command_url_action
+ protected:
+ QTimer timeout;
+ private:
++ bool substituteAndHandleSpecial( QString& cmd );
+ QString _command_url;
+ };
+
diff --git a/opensuse/tdebase/kicker-defaults.diff b/opensuse/tdebase/kicker-defaults.diff
new file mode 100644
index 000000000..a92cae562
--- /dev/null
+++ b/opensuse/tdebase/kicker-defaults.diff
@@ -0,0 +1,57 @@
+Index: kcontrol/kcontrol/KControl.desktop
+===================================================================
+--- kcontrol/kcontrol/KControl.desktop.orig
++++ kcontrol/kcontrol/KControl.desktop
+@@ -7,7 +7,9 @@ Type=Application
+ DocPath=kcontrol/index.html
+ X-KDE-StartupNotify=true
+
+-Name=Control Center
++GenericName=Configure Desktop
++GenericName[de]=Desktop-Einstellungen
++Name=Personal Settings
+ Name[af]=Beheer Sentrum
+ Name[ar]=مركز التحكم
+ Name[az]=İdarə Mərkəzi
+@@ -93,3 +95,4 @@ Name[zu]=Indawo Yokulawula
+
+ X-DCOP-ServiceType=Unique
+ Categories=Qt;KDE;Core;
++Keywords=control,center
+Index: kicker/libkicker/kickerSettings.kcfg
+===================================================================
+--- kicker/libkicker/kickerSettings.kcfg.orig
++++ kicker/libkicker/kickerSettings.kcfg
+@@ -159,7 +159,7 @@
+
+ <entry name="MenuExtensions" key="Extensions" type="StringList" >
+ <label>Optional Menus</label>
+- <default>prefmenu.desktop,systemmenu.desktop</default>
++ <default>recentdocs.desktop,systemmenu.desktop</default>
+ </entry>
+
+ <entry name="RecentAppsStat" type="StringList" >
+Index: kicker/menuext/system/systemmenu.desktop
+===================================================================
+--- kicker/menuext/system/systemmenu.desktop.orig
++++ kicker/menuext/system/systemmenu.desktop
+@@ -1,5 +1,5 @@
+ [Desktop Entry]
+-Name=System Menu
++Name=My System
+ Name[af]=Stelsel Kieslys
+ Name[ar]=قائمة النظام
+ Name[be]=Сістэмнае меню
+Index: kcontrol/kicker/hidingtab_impl.cpp
+===================================================================
+--- kcontrol/kicker/hidingtab_impl.cpp.orig
++++ kcontrol/kicker/hidingtab_impl.cpp
+@@ -200,7 +200,7 @@ void HidingTab::defaults()
+ m_delaySpinBox->setValue( 3 );
+ m_autoHideSwitch->setChecked( false );
+ m_lHB->setChecked( false );
+- m_rHB->setChecked( true );
++ m_rHB->setChecked( false );
+ m_animateHiding->setChecked( true );
+ m_hideSlider->setValue( 10 );
+ m_delaySpinBox->setValue( 3 );
diff --git a/opensuse/tdebase/kickerrc b/opensuse/tdebase/kickerrc
new file mode 100644
index 000000000..e5d6351a7
--- /dev/null
+++ b/opensuse/tdebase/kickerrc
@@ -0,0 +1,63 @@
+[ServiceMenuButton_1]
+Label=work/
+RelPath=work/
+
+[buttons]
+EnableIconZoom=false
+EnableTileBackground=false
+
+[menus]
+DetailedMenuEntries=false
+ReduceMenuDepth=true
+ShowUnimportantEntries=false
+
+[Applet_1]
+DesktopFile=minipagerapplet.desktop
+FreeSpace=0.25
+
+[Applet_2]
+ConfigFile=taskbar_panelappletrc
+DesktopFile=taskbarapplet.desktop
+FreeSpace=0.25
+
+[Applet_3]
+ConfigFile=systemtray_panelappletrc
+DesktopFile=systemtrayapplet.desktop
+FreeSpace=1
+
+[Applet_4]
+DesktopFile=clockapplet.desktop
+FreeSpace=1
+
+[General]
+Applets=KMenuButton_1,ServiceMenuButton_1,ServiceButton_2,ServiceButton_1,ServiceButton_6,ServiceButton_3,ServiceButton_4,Applet_1,Applet_2,Applet_3,Applet_4
+CustomSize=58
+# this size gets converted to "3" via kconf_update
+Size=58
+
+[KFileDialog Speedbar]
+Speedbar IconSize=32
+
+[KMenuButton_1]
+FreeSpace=0
+
+[ServiceButton_1]
+DesktopFile=System/konsole.desktop
+FreeSpace=0
+
+[ServiceButton_2]
+DesktopFile=Home.desktop
+FreeSpace=0
+
+[ServiceButton_3]
+DesktopFile=Internet/konqbrowser.desktop
+FreeSpace=0
+
+[ServiceButton_4]
+DesktopFile=Internet/KMail.desktop
+FreeSpace=0
+
+[ServiceButton_6]
+DesktopFile=Help.desktop
+FreeSpace=0
+
diff --git a/opensuse/tdebase/kickoff-beagle.diff b/opensuse/tdebase/kickoff-beagle.diff
new file mode 100644
index 000000000..a850e78ce
--- /dev/null
+++ b/opensuse/tdebase/kickoff-beagle.diff
@@ -0,0 +1,1329 @@
+--- configure.in.in (Revision 0)
++++ configure.in.in (Revision 849791)
+@@ -0,0 +1,78 @@
++dnl Check for pkg-config
++AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
++
++if test "$PKG_CONFIG" = "no"; then
++ AC_MSG_ERROR([
++This package requires pkg-config.
++])
++fi
++
++dnl Check for Glib-2.0
++# GLIB_CFLAGS: cflags for compiling glib dependant sources
++# GLIB_LIBADD: glib libraries (-l options)
++# GLIB_LDFLAGS: flags containing path to glib libraries (-L options)
++
++GLIB_PACKAGES="gmodule-2.0 gthread-2.0"
++GLIB_VERSION="1.3.3"
++AC_MSG_CHECKING(for GLib-2.0 (at least $GLIB_VERSION))
++
++if $PKG_CONFIG --atleast-pkgconfig-version 0.15 ; then
++ if $PKG_CONFIG --atleast-version $GLIB_VERSION $GLIB_PACKAGES >/dev/null 2>&1 ; then
++ GLIB_CFLAGS="`$PKG_CONFIG --cflags $GLIB_PACKAGES`"
++ GLIB_LIBADD="`$PKG_CONFIG --libs-only-l --libs-only-other $GLIB_PACKAGES`"
++ GLIB_LDFLAGS="`$PKG_CONFIG --libs-only-L $GLIB_PACKAGES`"
++ AC_MSG_RESULT(yes)
++ fi
++else
++ if $PKG_CONFIG --atleast-version $GLIB_VERSION $GLIB_PACKAGES >/dev/null 2>&1 ; then
++ GLIB_CFLAGS="`$PKG_CONFIG --cflags $GLIB_PACKAGES`"
++ GLIB_LIBADD="`$PKG_CONFIG --libs-only-l $GLIB_PACKAGES`"
++ GLIB_LDFLAGS="`$PKG_CONFIG --libs-only-L $GLIB_PACKAGES`"
++ AC_MSG_RESULT(yes)
++ AC_MSG_WARN([you may need to run make LDFLAGS=-pthread to compile arts])
++ fi
++fi
++
++if test -z "$GLIB_LIBADD"; then
++ AC_MSG_RESULT(not installed)
++ DO_NOT_COMPILE="$DO_NOT_COMPILE kerry gmcop"
++fi
++
++AC_SUBST(GLIB_CFLAGS)
++AC_SUBST(GLIB_LIBADD)
++AC_SUBST(GLIB_LDFLAGS)
++
++dnl Check for libbeagle 0.2.0
++# LIBBEAGLE_CFLAGS: cflags for compiling libbeagle dependant sources
++# LIBBEAGLE_LIBADD: libbeagle libraries (-l options)
++# LIBBEAGLE_LDFLAGS: flags containing path to libbeagle libraries (-L options)
++
++LIBBEAGLE_PACKAGES="libbeagle-0.0"
++LIBBEAGLE_VERSION="0.2.4"
++AC_MSG_CHECKING(for libbeagle-0.2.4 (at least $LIBBEAGLE_VERSION))
++
++if $PKG_CONFIG --atleast-pkgconfig-version 0.15 ; then
++ if $PKG_CONFIG --atleast-version $LIBBEAGLE_VERSION $LIBBEAGLE_PACKAGES >/dev/null 2>&1 ; then
++ LIBBEAGLE_CFLAGS="`$PKG_CONFIG --cflags $LIBBEAGLE_PACKAGES`"
++ LIBBEAGLE_LIBADD="`$PKG_CONFIG --libs-only-l --libs-only-other $LIBBEAGLE_PACKAGES`"
++ LIBBEAGLE_LDFLAGS="`$PKG_CONFIG --libs-only-L $LIBBEAGLE_PACKAGES`"
++ AC_MSG_RESULT(yes)
++ fi
++else
++ if $PKG_CONFIG --atleast-version $LIBBEAGLE_VERSION $LIBBEAGLE_PACKAGES >/dev/null 2>&1 ; then
++ LIBBEAGLE_CFLAGS="`$PKG_CONFIG --cflags $LIBBEAGLE_PACKAGES`"
++ LIBBEAGLE_LIBADD="`$PKG_CONFIG --libs-only-l $LIBBEAGLE_PACKAGES`"
++ LIBBEAGLE_LDFLAGS="`$PKG_CONFIG --libs-only-L $LIBBEAGLE_PACKAGES`"
++ AC_MSG_RESULT(yes)
++ AC_MSG_WARN([you may need to run make LDFLAGS=-pthread to compile arts])
++ fi
++fi
++
++if test -z "$LIBBEAGLE_LIBADD"; then
++ AC_MSG_RESULT(not installed)
++ DO_NOT_COMPILE="$DO_NOT_COMPILE kerry gmcop"
++fi
++
++AC_SUBST(LIBBEAGLE_CFLAGS)
++AC_SUBST(LIBBEAGLE_LIBADD)
++AC_SUBST(LIBBEAGLE_LDFLAGS)
+--- kicker/plugins/beaglesearch.cpp (Revision 0)
++++ kicker/plugins/beaglesearch.cpp (Revision 849791)
+@@ -0,0 +1,362 @@
++/*****************************************************************
++
++ Copyright (c) 2006 Debajyoti Bera <dbera.web@gmail.com>
++
++ 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; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++
++******************************************************************/
++
++#include "beaglesearch.h"
++
++#include <qdatetime.h>
++#include <qmutex.h>
++#include <qstringlist.h>
++#include <qapplication.h>
++#include <time.h>
++
++void beagle_init ()
++{
++ g_type_init ();
++}
++
++// ---------------- Hit ---------------------------
++
++Hit::Hit (BeagleHit *_hit) : processed (false)
++{
++ hit = beagle_hit_ref (_hit);
++}
++
++Hit::~Hit ()
++{
++ beagle_hit_unref (hit);
++ if (! processed)
++ return;
++ QDictIterator<QStringList> it (property_map);
++ for( ; it.current(); ++it )
++ ((QStringList *)it.current())->clear ();
++
++}
++
++void Hit::processProperties ()
++{
++ processed = true;
++ GSList *prop_list = beagle_hit_get_all_properties (hit);
++ GSList *it;
++ property_map.setAutoDelete (true);
++ for (it = prop_list; it; it = it->next) {
++ BeagleProperty *property = (BeagleProperty *) it->data;
++ QString key = QString::fromUtf8 (beagle_property_get_key (property));
++ if (! property_map [key])
++ property_map.insert (key, new QStringList ());
++ property_map [key]->append (QString::fromUtf8 (beagle_property_get_value (property)));
++ }
++ g_slist_free (prop_list);
++}
++
++const QString Hit::operator[] (QString prop_name)
++{
++ if (! processed)
++ processProperties ();
++
++ QStringList *prop_list = property_map [prop_name];
++ if (! prop_list)
++ return QString::null;
++ if (prop_list->count () != 1)
++ return QString::null;
++ return (QString)prop_list->first ();
++}
++
++// ---------------- BeagleSearch ------------------
++
++BeagleSearchResult::BeagleSearchResult(int client_id)
++ : client_id (client_id), total (0)
++{
++ hitlist = new QPtrList<Hit>;
++ hitlist->setAutoDelete (true);
++}
++
++
++BeagleSearchResult::~BeagleSearchResult()
++{
++ // everything is set to autodelete
++}
++
++void BeagleSearchResult::addHit(BeagleHit *_hit)
++{
++ Hit *hit = new Hit (_hit);
++ hitlist->prepend (hit);
++}
++
++const QPtrList<Hit> *BeagleSearchResult::getHits () const
++{
++ return hitlist;
++}
++
++
++static int total_hits;
++
++static void print_feed_item_hit (BeagleHit *hit)
++{
++ const char *text;
++
++ if (beagle_hit_get_one_property (hit, "dc:title", &text))
++ g_print ("Blog: %s\n", text);
++}
++
++static void print_file_hit (BeagleHit *hit)
++{
++ g_print ("File: %s, (%s)\n", beagle_hit_get_uri (hit), beagle_hit_get_mime_type (hit));
++}
++
++static void print_other_hit (BeagleHit *hit)
++{
++ const char *text;
++
++ g_print ("%s (%s)", beagle_hit_get_uri (hit),
++ beagle_hit_get_source (hit));
++ if (beagle_hit_get_one_property (hit, "dc:title", &text))
++ g_print ("title = %s\n", text);
++}
++
++static void print_hit (BeagleHit *hit)
++{
++ if (strcmp (beagle_hit_get_type (hit), "FeedItem") == 0) {
++ print_feed_item_hit (hit);
++ }
++ else if (strcmp (beagle_hit_get_type (hit), "File") == 0) {
++ print_file_hit (hit);
++ } else {
++ print_other_hit (hit);
++ }
++}
++
++// ---------------- BeagleSearchClient ------------------
++
++void BeagleSearchClient::run ()
++{
++ kdDebug () << "Starting query ..." << endl;
++
++ QTime query_timer;
++ query_timer.start ();
++
++ g_signal_connect (query, "hits-added",
++ G_CALLBACK (hitsAddedSlot),
++ this);
++ g_signal_connect (query, "finished",
++ G_CALLBACK (finishedSlot),
++ this);
++ beagle_client_send_request_async (client,
++ BEAGLE_REQUEST (query),
++ NULL);
++ g_main_loop_run (main_loop);
++ kdDebug () << "Finished query ..." << endl;
++
++ QCustomEvent *ev;
++ if (collate_results) {
++ result->query_msec = query_timer.elapsed ();
++
++ ev = new QCustomEvent (RESULTFOUND, result);
++ QApplication::postEvent (object, ev);
++ }
++
++ ev = new QCustomEvent (KILLME, this);
++ QApplication::postEvent (object, ev);
++
++}
++
++void BeagleSearchClient::stopClient ()
++{
++ if (finished ())
++ return; // duh!
++ kdDebug () << "Query thread " << id << " not yet finished ..." << endl;
++ // get ready for suicide
++ client_mutex->lock ();
++ kill_me = true;
++ g_signal_handlers_disconnect_by_func (
++ query,
++ (void *)hitsAddedSlot,
++ this);
++ g_signal_handlers_disconnect_by_func (
++ query,
++ (void *)finishedSlot,
++ this);
++ g_main_loop_quit (main_loop);
++ client_mutex->unlock ();
++}
++
++void BeagleSearchClient::hitsAddedSlot (BeagleQuery *query,
++ BeagleHitsAddedResponse *response,
++ BeagleSearchClient *bsclient)
++{
++ GSList *hits, *l;
++ gint i;
++ gint nr_hits;
++
++ // check if we are supposed to be killed
++ bsclient->client_mutex->lock ();
++ if (bsclient->kill_me) {
++ kdDebug () << "Suicide time before processing" << endl;
++ bsclient->client_mutex->unlock ();
++ return;
++ }
++ bsclient->client_mutex->unlock ();
++
++ hits = beagle_hits_added_response_get_hits (response);
++
++ nr_hits = g_slist_length (hits);
++ total_hits += nr_hits;
++ g_print ("Found hits (%d) at %ld:\n", nr_hits, time (NULL));
++
++ BeagleSearchResult *search_result;
++ if (! bsclient->collate_results)
++ search_result = new BeagleSearchResult (bsclient->id);
++ else
++ search_result = bsclient->result;
++ search_result->total += nr_hits;
++
++ for (l = hits, i = 1; l; l = l->next, ++i) {
++ //g_print ("[%d] ", i);
++ //print_hit (BEAGLE_HIT (l->data));
++ //g_print ("\n");
++
++ search_result->addHit(BEAGLE_HIT (l->data));//hit);
++ }
++ g_print ("[%ld] hits adding finished \n", time (NULL));
++
++ // check if we are supposed to be killed
++ bsclient->client_mutex->lock ();
++ if (bsclient->kill_me) {
++ kdDebug () << "Suicide time before sending ..." << endl;
++ bsclient->client_mutex->unlock ();
++ if (! bsclient->collate_results)
++ delete search_result;
++ return;
++ }
++ bsclient->client_mutex->unlock ();
++
++ // time to send back results, if user asked so
++ if (bsclient->collate_results)
++ return;
++ QCustomEvent *ev = new QCustomEvent (RESULTFOUND, search_result);
++ g_print ("[%ld] event notified \n", time (NULL));
++ QApplication::postEvent (bsclient->object, ev);
++}
++
++void BeagleSearchClient::finishedSlot (BeagleQuery *query,
++ BeagleFinishedResponse *response,
++ BeagleSearchClient *bsclient)
++{
++ // check if we are supposed to be killed
++ bsclient->client_mutex->lock ();
++ bool should_kill = bsclient->kill_me;
++ QObject* receiver = bsclient->object;
++ bsclient->client_mutex->unlock ();
++
++ if (should_kill)
++ return;
++
++ g_main_loop_quit (bsclient->main_loop);
++
++ if (bsclient->collate_results)
++ return; // if we are collating, everything will be send from a central place
++ if (receiver) {
++ QCustomEvent *ev = new QCustomEvent (SEARCHOVER, bsclient);
++ g_print ("[%ld] query finish notified \n", time (NULL));
++ QApplication::postEvent (receiver, ev);
++ }
++}
++
++// ----------------- BeagleUtil -------------------
++
++BeagleQuery *
++BeagleUtil::createQueryFromString (QString query_str,
++ QStringList &sources_menu,
++ QStringList &types_menu,
++ int max_hits_per_source)
++{
++ BeagleQuery *beagle_query = beagle_query_new ();
++ beagle_query_set_max_hits (beagle_query, max_hits_per_source); // this is per source!
++
++ kdDebug () << "Creating query from \"" << query_str << "\"" << endl;
++ for ( QStringList::Iterator it = sources_menu.begin(); it != sources_menu.end(); ++it )
++ beagle_query_add_source (beagle_query, g_strdup ((*it).utf8 ()));
++
++ for ( QStringList::Iterator it = types_menu.begin(); it != types_menu.end(); ++it )
++ beagle_query_add_hit_type (beagle_query, g_strdup ((*it).utf8 ()));
++
++ QStringList query_terms;
++ QString start_date, end_date;
++ QStringList words = QStringList::split (' ', query_str, false);
++ for ( QStringList::Iterator it = words.begin(); it != words.end(); ++it ) {
++ QStringList key_value_pair = QStringList::split ('=', *it, false);
++ if (key_value_pair.count () == 1)
++ query_terms += *it;
++ else if (key_value_pair.count () == 2) {
++ QString key = key_value_pair [0].lower ();
++ QString value = key_value_pair [1];
++ if (key == "mime")
++ beagle_query_add_mime_type (beagle_query, g_strdup (value.utf8 ()));
++ else if (key == "type")
++ beagle_query_add_hit_type (beagle_query, g_strdup (value.utf8 ()));
++ else if (key == "source")
++ beagle_query_add_source (beagle_query, g_strdup (value.utf8 ()));
++ else if (key == "start")
++ start_date = value;
++ else if (key == "end")
++ end_date = value;
++ else
++ query_terms += *it;
++ } else
++ query_terms += *it;
++ }
++
++ beagle_query_add_text (beagle_query, g_strdup (query_terms.join (" ").utf8 ()));
++ kdDebug () << "Adding query text:" << query_terms.join (" ").utf8 () << endl;
++
++ if (start_date.isNull () && end_date.isNull ())
++ return beagle_query;
++
++ //kdDebug () << "Handling dates ..." << endl;
++ BeagleQueryPartDate * date_part = beagle_query_part_date_new ();
++ if (! start_date.isNull ())
++ beagle_query_part_date_set_start_date (date_part, timestringToBeagleTimestamp (start_date));
++ if (! end_date.isNull ())
++ beagle_query_part_date_set_end_date (date_part, timestringToBeagleTimestamp (end_date));
++ beagle_query_add_part (beagle_query, BEAGLE_QUERY_PART (date_part));
++
++ return beagle_query;
++}
++
++// timestring format allowed YYYYmmDD
++BeagleTimestamp *
++BeagleUtil::timestringToBeagleTimestamp(QString timestring)
++{
++ //kdDebug () << "datetime string:" << timestring << endl;
++ // FIXME: error check timestring format
++ if (timestring.isNull () || timestring.stripWhiteSpace () == "" || timestring.length() != 8 )
++ return beagle_timestamp_new_from_unix_time (QDateTime::currentDateTime ().toTime_t ());
++ //QDateTime dt = QDateTime::fromString (timestring, Qt::ISODate);
++ struct tm tm_time;
++ time_t timet_time;
++ time (&timet_time);
++ localtime_r (&timet_time, &tm_time);
++ strptime (timestring.ascii(), "%Y%m%d", &tm_time);
++ tm_time.tm_sec = tm_time.tm_min = tm_time.tm_hour = 0;
++ //kdDebug() << asctime (&tm_time) << endl;
++ timet_time = mktime (&tm_time);
++ return beagle_timestamp_new_from_unix_time (timet_time);
++}
++
+--- kicker/plugins/kickoff-beagle-plugin.cpp (Revision 0)
++++ kicker/plugins/kickoff-beagle-plugin.cpp (Revision 849791)
+@@ -0,0 +1,499 @@
++/***************************************************************************
++ * Copyright (C) 2006 by Stephan Binner <binner@kde.org> *
++ * Copyright (c) 2006 Debajyoti Bera <dbera.web@gmail.com> *
++ * *
++ * 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 "kickoff-beagle-plugin.h"
++
++#include <qregexp.h>
++#include <qtimer.h>
++
++#include <kapplication.h>
++#include <kdesktopfile.h>
++#include <kgenericfactory.h>
++#include <kservice.h>
++
++QString dc_identifier = "dc:identifier";
++QString dc_title = "dc:title";
++QString parent_dc_title = "parent:dc:title";
++QString exactfilename = "beagle:ExactFilename";
++QString fixme_name = "fixme:Name";
++QString beagle_filename = "beagle:Filename";
++QString fixme_attachment_title = "fixme:attachment_title";
++QString fixme_hasattachments = "fixme:hasAttachments";
++QString parent_prefix = "parent:";
++QString fixme_folder = "fixme:folder";
++QString fixme_categories = "fixme:Categories";
++QString fixme_comment = "fixme:Comment";
++QString fixme_width = "fixme:width";
++QString fixme_height = "fixme:height";
++QString fixme_from_address = "fixme:from_address";
++QString fixme_artist = "fixme:artist";
++QString fixme_album = "fixme:album";
++QString dc_source = "dc:source";
++QString dc_publisher = "dc:publisher";
++QString digikam_tag = "digikam:Tag";
++QString fixme_speakingto = "fixme:speakingto";
++QString fixme_starttime = "fixme:starttime";
++QString comma_string = ",";
++QString vCard_FN = "vCard:FN";
++QString vCard_PREFEMAIL = "vCard:PREFEMAIL";
++QString fixme_uid = "fixme:uid";
++
++static CATEGORY getHitCategory (Hit *hit)
++{
++ QString hittype = hit->getType();
++ QString hitsource = hit->getSource();
++
++ // if hit source is None, dont handle it. Might be anthrax-envelope :)
++ if (hitsource.isNull())
++ return OTHER;
++
++ if (hitsource == "documentation")
++ return DOCS;
++
++ if (hittype == "IMLog")
++ return CHATS;
++
++ // sure shots
++ if (hittype == "FeedItem")
++ return FEEDS;
++ if (hittype == "WebHistory")
++ return WEBHIST;
++ if (hittype == "MailMessage")
++ return MAILS;
++ if (hittype == "Note")
++ return NOTES;
++
++ // check for applications
++ if (hittype == "File" && (*hit) ["beagle:FilenameExtension"] == ".desktop")
++ return APPS;
++
++ // check for music
++ QString hitmimetype = hit->getMimeType();
++ if (hitsource == "Amarok"
++ || hitmimetype.startsWith ("audio")
++ || hitmimetype == "application/ogg")
++ return MUSIC; // not an exhaustive search
++
++ // check for images from files
++ if (hitsource == "Files" && hitmimetype.startsWith ("image"))
++ return PICS;
++
++ if (hitsource == "Files" && hitmimetype.startsWith ("video"))
++ return VIDEOS;
++
++ if (hitsource == "Files")
++ return FILES;
++
++ if (hitsource == "KAddressBook")
++ return ACTIONS;
++
++ return OTHER;
++}
++
++K_EXPORT_COMPONENT_FACTORY( kickoffsearch_beagle,
++ KGenericFactory<KickoffBeaglePlugin>( "kickoffsearch_beagle" ) )
++
++KickoffBeaglePlugin::KickoffBeaglePlugin(QObject *parent, const char* name, const QStringList&)
++ : KickoffSearch::Plugin(parent, name ), genericTitle( true )
++{
++ g_type_init ();
++ current_beagle_client = NULL;
++}
++
++bool KickoffBeaglePlugin::daemonRunning()
++{
++ return beagle_util_daemon_is_running();
++}
++
++void KickoffBeaglePlugin::query(QString term, bool _genericTitle)
++{
++ genericTitle = _genericTitle;
++ current_query_str = term;
++
++ // Beagle search
++ if (current_beagle_client != NULL) {
++ kdDebug () << "Previous client w/id " << current_beagle_client->id << " still running ... ignoring it." << endl;
++ current_beagle_client->stopClient ();
++ }
++ current_beagle_client_id = KApplication::random ();
++ kdDebug () << "Creating client with id:" << current_beagle_client_id << endl;
++
++ BeagleClient *beagle_client = beagle_client_new (NULL);
++ if (beagle_client == NULL) {
++ kdDebug() << "beagle service not running ..." << endl;
++ return;
++ }
++
++ QStringList sources, types;
++ BeagleQuery *beagle_query = BeagleUtil::createQueryFromString (term, sources, types, 99); // maximum 99 results, if this doesnt work, blame the stars
++
++ current_beagle_client = new BeagleSearchClient (
++ current_beagle_client_id,
++ this,
++ beagle_client,
++ beagle_query,
++ false);
++ current_beagle_client->start();
++// kdDebug () << "Query dispatched at " << time (NULL) << endl;
++}
++
++void KickoffBeaglePlugin::cleanClientList ()
++{
++ toclean_list_mutex.lock ();
++ BeagleSearchClient *old_client = toclean_client_list.take (0);
++ if (old_client != NULL) { // failsafe
++ kdDebug () << "Cleanup old client " << old_client->id << endl;
++ delete old_client;
++ }
++ toclean_list_mutex.unlock ();
++}
++
++void KickoffBeaglePlugin::customEvent (QCustomEvent *e)
++{
++ if (e->type () == RESULTFOUND) {
++// kdDebug () << "Quick query thread at " << time (NULL) << " with current_id=" << current_beagle_client_id << " finished ..." << endl;
++ BeagleSearchResult *result = (BeagleSearchResult *) e->data ();
++ if (current_beagle_client_id != result->client_id) {
++ kdDebug () << "Stale result from " << result->client_id << endl;
++ delete result;
++ // FIXME: Should I also free e ?
++ } else {
++ kdDebug () << "Good results ...total=" << result->total << endl;
++ showResults (result);
++ }
++ //KPassivePopup::message( "This is the message", this );
++ } else if (e->type () == SEARCHOVER) {
++ BeagleSearchClient *client = (BeagleSearchClient *) e->data ();
++ if (client == NULL) {
++// kdDebug () << "Query finished event at " << time (NULL) << " but client is already deleted" << endl;
++ return;
++ }
++// kdDebug () << "Query finished event at " << time (NULL) << " for id=" << client->id << endl;
++ if (current_beagle_client_id == client->id) {
++ kickoffSearchInterface()->searchOver();
++ current_beagle_client = NULL; // important !
++ }
++ } else if (e->type () == KILLME) {
++ BeagleSearchClient *client = (BeagleSearchClient *) e->data ();
++ if (client->finished ())
++ delete client;
++ else {
++ // add client to cleanup list
++ toclean_list_mutex.lock ();
++ toclean_client_list.append (client);
++ kdDebug () << "Scheduling client to be deleted in 500ms" << endl;
++ toclean_list_mutex.unlock ();
++ QTimer::singleShot (500, this, SLOT (cleanClientList ()));
++ }
++ }
++}
++
++// this method decides what to display in the result list
++HitMenuItem *KickoffBeaglePlugin::hitToHitMenuItem (int category, Hit *hit)
++{
++ QString title, info, mimetype, icon;
++ int score = 0;
++ KURL uri;
++
++#if 0
++ kdDebug() << "*** " << hit->getUri() << endl;
++ QDict<QStringList> all = hit->getAllProperties();
++ QDictIterator<QStringList> it( all );
++ for( ; it.current(); ++it )
++ kdDebug() << it.currentKey() << ": " << *(it.current()) << endl;
++#endif
++
++ switch (category) {
++ case FILES:
++ {
++ uri = hit->getUri ();
++ QString uristr = uri.path ();
++ title = (*hit) [exactfilename];
++ int last_slash = uristr.findRev ('/', -1);
++ info = i18n("Folder: %1").arg(last_slash == 0 ? "/"
++ : uristr.section ('/', -2, -2));
++ }
++ break;
++ case ACTIONS:
++ {
++ if (hit->getSource()=="KAddressBook"){
++ title = i18n("Send Email to %1").arg((*hit)[vCard_FN]);
++ info = (*hit)[vCard_PREFEMAIL];
++ uri = "mailto:"+(*hit)[vCard_PREFEMAIL];
++ mimetype = hit->getMimeType ();
++ icon = "mail_new";
++
++ HitMenuItem * first_item=new HitMenuItem (title, info, uri, mimetype, 0, category, icon, score);
++ kickoffSearchInterface()->addHitMenuItem(first_item);
++
++ title =i18n("Open Addressbook at %1").arg((*hit)[vCard_FN]);
++ uri = "kaddressbook:/"+(*hit)[fixme_uid];
++ icon = "kaddressbook";
++ }
++ break;
++ }
++ case MAILS:
++ {
++ QString prefix = QString::null;
++ bool is_attachment = ((*hit) [parent_prefix + fixme_hasattachments] == "true");
++ bool has_parent = (! hit->getParentUri ().isEmpty ());
++ bool parent_mbox_file = false;
++ if (has_parent)
++ parent_mbox_file = ((*hit) [parent_prefix + fixme_folder] == QString::null);
++
++ // Logic:
++ // If has_parent == false, everything is normal
++ // If has_parent == true, parent_mbox_file == false, everything is normal, use uri
++ // FIXME: If has_parent == true, parent_mbox_file == true, ???
++ // If has_parent == true, is_attachment == true, hit is attach and access with prefix "parent:", use parenturi
++ // Else, not attachment (multipart), access with prefix "parent:", use parenturi
++
++ if (has_parent && !parent_mbox_file) {
++ uri = hit->getParentUri ();
++ prefix = parent_prefix;
++ if (is_attachment)
++ title = (*hit) [fixme_attachment_title];
++ if (title.isEmpty ())
++ title = (*hit) [prefix + dc_title];
++ if (title.isEmpty ())
++ title = i18n("No subject");
++ if (is_attachment)
++ title = title.prepend (i18n("(Attachment) "));
++ info = (i18n("From %1").arg((*hit) [prefix + fixme_from_address]));
++ } else {
++ uri = hit->getUri ();
++ title = (*hit) [dc_title];
++ info = (i18n("From %1").arg((*hit) [fixme_from_address]));
++ }
++ }
++ mimetype = "message/rfc822"; // to handle attachment results
++ break;
++ case MUSIC:
++ uri = hit->getUri ();
++ title = (*hit) [exactfilename];
++ {
++ QString artist = (*hit) [fixme_artist];
++ QString album = (*hit) [fixme_album];
++ if (! artist.isEmpty ())
++ info = (i18n("By %1").arg(artist));
++ else if (! album.isEmpty ())
++ info = (i18n("From Album %1").arg(album));
++ else {
++ QString uristr = uri.path ();
++ int last_slash = uristr.findRev ('/', -1);
++ info = i18n("Folder: %1")
++ .arg(last_slash == 0 ? "/" : uristr.section ('/', -2, -2));
++ }
++ }
++ break;
++ case VIDEOS:
++ uri = hit->getUri ();
++ title = (*hit) [exactfilename];
++ {
++ QString uristr = uri.path ();
++ int last_slash = uristr.findRev ('/', -1);
++ info = i18n("Folder: %1").arg(last_slash == 0 ? "/" : uristr.section ('/', -2, -2));
++ }
++ break;
++ case WEBHIST:
++ uri = hit->getUri ();
++ title = (*hit) [dc_title];
++ title = title.replace(QRegExp("\n")," ");
++ mimetype = "text/html";
++ if (title.isEmpty () || title.stripWhiteSpace ().isEmpty ()) {
++ title = uri.prettyURL ();
++ } else {
++ info = uri.host () + uri.path ();
++ }
++ break;
++ case FEEDS:
++ {
++ uri = KURL ((*hit) [dc_identifier]);
++ title = (*hit) [dc_title];
++ mimetype = "text/html";
++ QString publisher = (*hit) [dc_publisher];
++ QString source = (*hit) [dc_source];
++ if (! publisher.isEmpty ())
++ info = publisher;
++ else if (! source.isEmpty ())
++ info = source;
++ }
++ break;
++ case PICS:
++ {
++ uri = hit->getUri ();
++ title = (*hit) [exactfilename];
++ QString width = (*hit) [fixme_width];
++ QString height = (*hit) [fixme_height];
++ if (width.isEmpty () || height.isEmpty ()) {
++ QString uristr = uri.path ();
++ int last_slash = uristr.findRev ('/', -1);
++ info = i18n("Folder: %1")
++ .arg(last_slash == 0 ? "/" : uristr.section ('/', -2, -2));
++ break;
++ }
++ info = (QString (" (%1x%2)").arg (width).arg (height));
++ const QStringList *tags = hit->getProperties (digikam_tag);
++ if (tags == NULL)
++ break;
++ QString tags_string = tags->join (comma_string);
++ info += (" " + tags_string);
++ }
++ break;
++ case APPS:
++ {
++ uri = hit->getUri ();
++ title = (*hit) [dc_title];
++ KDesktopFile desktopfile(uri.path(),true);
++ if (genericTitle && !desktopfile.readGenericName().isEmpty()) {
++ title = desktopfile.readGenericName();
++ info = desktopfile.readName();
++ }
++ else {
++ title = desktopfile.readName();
++ info = desktopfile.readGenericName();
++ }
++ icon = desktopfile.readIcon();
++ QString input = current_query_str.lower();
++ QString command = desktopfile.readEntry("Exec");
++ if (command==input)
++ score = 100;
++ else if (command.find(input)==0)
++ score = 50;
++ else if (command.find(input)!=-1)
++ score = 10;
++ else if (title==input)
++ score = 100;
++ else if (title.find(input)==0)
++ score = 50;
++ else if (title.find(input)!=-1)
++ score = 10;
++ break;
++ }
++ break;
++ case NOTES:
++ {
++ uri = hit->getUri ();
++ title = (*hit) [dc_title];
++ title = i18n("Title: %1").arg(title.isEmpty() ? i18n("Untitled") : title);
++
++ if (hit->getSource()=="KNotes")
++ icon="knotes";
++ else
++ icon="contents2";
++ }
++ break;
++ case CHATS:
++ {
++ uri = hit->getUri ();
++ title = (*hit) [fixme_speakingto];
++ title = i18n("Conversation With %1").arg(title.isEmpty() ? i18n("Unknown Person") : title);
++ QDateTime datetime;
++ datetime = datetimeFromString((*hit) [fixme_starttime]);
++ info=i18n("Date: %1").arg(KGlobal::locale()->formatDateTime(datetime,false));
++ if (hit->getMimeType()=="beagle/x-kopete-log")
++ icon="kopete";
++ else
++ icon="gaim";
++ }
++ break;
++ case DOCS:
++ {
++ uri = hit->getUri ();
++ title = (*hit) [dc_title];
++ if (title.isEmpty () || title.stripWhiteSpace ().isEmpty ())
++ title = uri.prettyURL ();
++ else {
++ QString uristr = uri.path ();
++ int last_slash = uristr.findRev ('/', -1);
++ info = i18n("Folder: %1").arg(last_slash == 0 ? "/" : uristr.section ('/',
++ -2, -2));
++ }
++ }
++ break;
++ default:
++ return NULL;
++ }
++ if (mimetype.isEmpty ())
++ mimetype = hit->getMimeType ();
++ return new HitMenuItem (title, info, uri, mimetype, 0, category, icon, score);
++}
++
++void KickoffBeaglePlugin::showResults(BeagleSearchResult *result)
++{
++ if (result->total == 0 ) {
++ // Dont report error from here ...
++ kdDebug() << "No matches found" << endl;
++ delete result;
++ return;
++ }
++
++ const QPtrList<Hit> *hits = result->getHits();
++ if (hits == NULL) {
++ kdDebug () << "Hmm... null" << endl;
++ delete result;
++ return;
++ }
++ kickoffSearchInterface()->initCategoryTitlesUpdate();
++
++ QPtrListIterator<Hit> it (*hits);
++ Hit *hit;
++ for (; (hit = it.current ()) != NULL; ++it) {
++ CATEGORY category = getHitCategory (hit);
++
++ // if category is not handled, continue
++ if (category == OTHER)
++ continue;
++
++ if ( category == APPS ) {
++ // we need to check if this is useful
++ KService cs( hit->getUri().path() );
++ if ( cs.noDisplay() )
++ continue;
++ }
++
++ if (!kickoffSearchInterface()->anotherHitMenuItemAllowed(category))
++ continue;
++
++ HitMenuItem *hit_item = hitToHitMenuItem (category, hit);
++
++ if (!hit_item)
++ continue;
++
++ kickoffSearchInterface()->addHitMenuItem(hit_item);
++ }
++
++ kickoffSearchInterface()->updateCategoryTitles();
++
++ delete result;
++}
++
++QDateTime KickoffBeaglePlugin::datetimeFromString( const QString& s)
++{
++ int year( s.mid( 0, 4 ).toInt() );
++ int month( s.mid( 4, 2 ).toInt() );
++ int day( s.mid( 6, 2 ).toInt() );
++ int hour( s.mid( 8, 2 ).toInt() );
++ int min( s.mid( 10, 2 ).toInt() );
++ int sec( s.mid( 12, 2 ).toInt() );
++ return QDateTime(QDate(year,month,day),QTime(hour,min,sec));
++}
++
++#include "kickoff-beagle-plugin.moc"
+--- kicker/plugins/Makefile.am (Revision 0)
++++ kicker/plugins/Makefile.am (Revision 849791)
+@@ -0,0 +1,24 @@
++INCLUDES = -I$(top_srcdir)/interfaces $(all_includes) $(LIBBEAGLE_CFLAGS) $(GLIB_CFLAGS)
++METASOURCES = AUTO
++
++# Install this plugin in the KDE modules directory
++kde_module_LTLIBRARIES = kickoffsearch_beagle.la
++
++# Srcs for the plugin
++kickoffsearch_beagle_la_SOURCES = kickoff-beagle-plugin.cpp beaglesearch.cpp
++
++# Libs needed by the plugin
++kickoffsearch_beagle_la_LIBADD = $(LIB_KPARTS) ../interfaces/libkickoffsearch_interfaces.la \
++ $(LIBBEAGLE_LIBADD) $(GLIB_LIBADD)
++
++# LD flags for the plugin
++# -module says: this is a module, i.e. something you're going to dlopen
++# so e.g. it has no version number like a normal shared lib would have.
++kickoffsearch_beagle_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries)
++
++# Install the desktop file needed to detect the plugin
++kde_services_DATA = kickoffsearch_beagle.desktop
++
++# i18n translation messages
++messages: rc.cpp
++ $(XGETTEXT) *.cpp *.h -o $(podir)/kickoffsearch_beagle.pot
+--- kicker/plugins/kickoffsearch_beagle.desktop (Revision 0)
++++ kicker/plugins/kickoffsearch_beagle.desktop (Revision 849791)
+@@ -0,0 +1,6 @@
++[Desktop Entry]
++Name=Beagle Search
++Comment=Beagle search plugin for Kickoff search
++ServiceTypes=KickoffSearch/Plugin
++Type=Service
++X-KDE-Library=kickoffsearch_beagle
+--- kicker/plugins/beaglesearch.h (Revision 0)
++++ kicker/plugins/beaglesearch.h (Revision 849791)
+@@ -0,0 +1,234 @@
++/*****************************************************************
++
++ Copyright (c) 2006 Debajyoti Bera <dbera.web@gmail.com>
++
++ 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; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++
++******************************************************************/
++
++#ifndef BEAGLESEARCH_H
++#define BEAGLESEARCH_H
++
++#include <qdict.h>
++#include <qptrlist.h>
++#include <qthread.h>
++#include <qevent.h>
++#include <qmutex.h>
++
++#include <kdebug.h>
++#include <kurl.h>
++
++extern "C" {
++#include <glib.h>
++#include <beagle/beagle.h>
++}
++
++// BeagleSearchClient sends 3 types of events
++// when results are to be sent as they arrive,
++// - RESULTFOUND : when result is found
++// - SEARCHOVER : when search is over
++// - KILLME : just before thread finishes - used to cleanup the thread object
++// when results are to be sent after receiving all of them
++// - RESULTFOUND : when all results are obtained
++// - KILLME : just before thread finishes - used to cleanup the thread object
++#define RESULTFOUND (QEvent::Type)1001 /* QEvent::User + 1 */
++#define SEARCHOVER (QEvent::Type)1002 /* QEvent::User + 2 */
++#define KILLME (QEvent::Type)1003 /* QEvent::User + 3 */
++
++class QStringList;
++
++// IMPORTANT: Call this before any beagle calls
++void beagle_init ();
++
++class Hit {
++public:
++ Hit (BeagleHit *_hit);
++ ~Hit ();
++
++ // convenience wrappers
++ // remember that the hit values are utf8 strings
++ const KURL getUri () const { return KURL (QString::fromUtf8 (beagle_hit_get_uri (hit)));}
++ const QString getType () const { return QString::fromUtf8 (beagle_hit_get_type (hit));}
++ const QString getMimeType () const { return QString::fromUtf8 (beagle_hit_get_mime_type (hit));}
++ const QString getSource () const { return QString::fromUtf8 (beagle_hit_get_source (hit));}
++ const KURL getParentUri () const { return KURL (QString::fromUtf8 (beagle_hit_get_parent_uri (hit)));}
++ const QDict<QStringList>& getAllProperties ()
++ {
++ if (! processed)
++ processProperties ();
++ return property_map;
++ }
++ const QStringList* getProperties (QString prop_name)
++ {
++ if (! processed)
++ processProperties ();
++ return property_map [prop_name];
++ }
++ const QString operator[] (QString prop_name);
++
++private:
++ BeagleHit *hit;
++ QDict<QStringList> property_map;
++ // not every hit may be used. so, do a lazy processing of property_map
++ bool processed;
++ void processProperties ();
++};
++
++class BeagleSearchResult{
++public:
++ BeagleSearchResult(int client_id);
++ ~BeagleSearchResult();
++ void addHit (BeagleHit *hit);
++ QString getHitCategory (Hit *hit);
++
++ // id of the bsclient
++ int client_id;
++ // time taken to finish query
++ int query_msec;
++ // total number of results in this query
++ int total;
++
++ const QPtrList<Hit> *getHits () const;
++
++private:
++ // lists of hits
++ QPtrList<Hit> *hitlist;
++};
++
++// caller should delete bsclient->result and bsclient
++class BeagleSearchClient : public QThread {
++public:
++ // passing NULL for client makes bsclient create client itself and
++ // delete it later
++ BeagleSearchClient (int id,
++ QObject *y,
++ BeagleClient *client,
++ BeagleQuery *query,
++ bool collate_results)
++ : id (id), kill_me (false), object (y), client (client),
++ query (query), destroy_client (false), collate_results (collate_results)
++ {
++ if (client == NULL) {
++ client = beagle_client_new (NULL);
++ destroy_client = true;
++ }
++
++// if (client == NULL)
++// throw -1;
++
++ main_loop = g_main_loop_new (NULL, FALSE);
++ if (collate_results)
++ result = new BeagleSearchResult (id);
++
++ client_mutex = new QMutex ();
++ }
++
++ // It is never safe to delete BeagleSearchClient directly, the thread might still be running
++ ~BeagleSearchClient ()
++ {
++ if (! finished ()) {
++ kdDebug () << "Thread " << id << " still running. Waiting.........." << endl;
++ wait ();
++ }
++
++ if (destroy_client)
++ g_object_unref (client);
++ g_main_loop_unref (main_loop);
++ g_object_unref (query);
++ kdDebug() << "Deleting client ..." << id << endl;
++ delete client_mutex;
++ }
++
++private:
++ static void hitsAddedSlot (BeagleQuery *query,
++ BeagleHitsAddedResponse *response,
++ BeagleSearchClient *bsclient);
++
++ static void finishedSlot (BeagleQuery *query,
++ BeagleFinishedResponse *response,
++ BeagleSearchClient *bsclient);
++
++public:
++ // run() starts the query and sends the result as follows:
++ // - either wait till get back all results and send it as RESULTFOUND
++ // - or, send results as it gets them as RESULTFOUND and
++ // send SEARCHOVER when finished
++ // collate_results controls the behaviour
++ virtual void run ( );
++
++ // after stopClient() is called, application can safely go and remove previous menu entries
++ // - i.e. after stopClient is called, app doesnt except the eventhandler to receive any results
++ // - use client_id to determine which is the current client, set it right after stopclient
++ // - Eventhandler checks client id, if it is current, it adds stuff to the menu
++ // else, it discards everything
++ // Once eventhandler is being processed, doQuery() wont be called and vice versa
++ // so no need to serialize eventhandler and doquery
++ //
++ // stopClient needs to make sure that once it is called, the thread is finished asap. Use a mutex
++ // to serialize actions. callbacks need to use mutex too.
++ // stopclient has to remove signal handlers to prevent further signal calls, set kill_me flag
++ // and quite main loop
++ // stopClient can be called at the following times:
++ // - Waiting for the first result:
++ // nothing extra
++ // - in hitsAddedSlot, processing results
++ // in callback, before processing, if killme is set, just return.
++ // - in hitsAddedSlot, after sending results
++ // before sending, if killme is set, dont send results
++ // (doing it twice in hitsAdded because forming BeagleSearchResult can take time)
++ // - Waiting for more results
++ // nothing extra
++ // - in finishedSlot, before sending finishedMsg
++ // if killme is set, just return
++ // - in finishedSlot, after sending finishedMsg
++ // if killme is set, just return
++ // in Run(), when return from mainloop, if killme is set, dont do anything more but call delete this
++ void stopClient ();
++
++ // id of the client
++ // this is required in case applications fires many clients in rapid succession
++ int id;
++
++ GMainLoop * main_loop;
++ BeagleSearchResult *result;
++
++ // this is set if the client is obsolete now i.e.
++ // the application doesnt need the results from the client anymore
++ bool kill_me;
++private:
++ // the application; need this to send events to the application
++ QObject *object;
++ // mutex to control setting the kill_me shared variable
++ QMutex *client_mutex;
++ BeagleClient *client;
++ BeagleQuery *query;
++ // should the client be destroyed by the client
++ // if the client created it, then most probably it should
++ bool destroy_client;
++ bool collate_results;
++};
++
++class BeagleUtil {
++public:
++
++ static BeagleQuery *createQueryFromString (QString query_str,
++ QStringList &sources,
++ QStringList &types,
++ int max_hits_per_source = 100);
++ static BeagleTimestamp *timestringToBeagleTimestamp (QString timestring);
++};
++
++#endif
+--- kicker/plugins/kickoff-beagle-plugin.h (Revision 0)
++++ kicker/plugins/kickoff-beagle-plugin.h (Revision 849791)
+@@ -0,0 +1,64 @@
++/***************************************************************************
++ * Copyright (C) 2006 by Stephan Binner <binner@kde.org> *
++ * Copyright (c) 2006 Debajyoti Bera <dbera.web@gmail.com> *
++ * *
++ * 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 CAPITALIZEPLUGIN_H
++#define CAPITALIZEPLUGIN_H
++
++#include "../interfaces/kickoff-search-plugin.h"
++#include "beaglesearch.h"
++
++class KickoffBeaglePlugin :public KickoffSearch::Plugin
++{
++ Q_OBJECT
++
++public:
++ KickoffBeaglePlugin(QObject *parent, const char* name, const QStringList&);
++
++ void query(QString, bool);
++ bool daemonRunning();
++
++protected slots:
++ // to clean beaglesearchclients
++ void cleanClientList ();
++
++private:
++ QString current_query_str;
++
++ // all beagle activity is done through the BSC object
++ BeagleSearchClient *current_beagle_client;
++
++ // used to send notification from the beagle thread to the main event loop
++ virtual void customEvent (QCustomEvent *e);
++
++ QPtrList<BeagleSearchClient> toclean_client_list;
++ QMutex toclean_list_mutex;
++
++ // show the results
++ void showResults (BeagleSearchResult *);
++ HitMenuItem *hitToHitMenuItem (int category, Hit *hit);
++
++ // use a different id for each bsc client, and use that to separate stale responses from current ones
++ int current_beagle_client_id;
++
++ bool genericTitle;
++ QDateTime datetimeFromString( const QString& );
++};
++
++#endif /* CAPITALIZEPLUGIN_H */
+
+Eigenschaftsänderungen: kicker/plugins
+___________________________________________________________________
+Hinzugefügt: svn:ignore
+ + .deps
+kickoffsearch_beagle.la
+.libs
+Makefile
+Makefile.in
+*.moc
+
+
+--- kicker/Makefile.am 2010/08/10 08:10:21 1.1
++++ kicker/Makefile.am 2010/08/10 08:10:33
+@@ -1,6 +1,6 @@
+ INCLUDES = $(all_includes)
+
+-SUBDIRS = core ui buttons interfaces .
++SUBDIRS = core ui buttons interfaces plugins .
+
+ bin_PROGRAMS =
+ lib_LTLIBRARIES =
+--- kicker/core/Makefile.am 2010/08/10 08:15:06 1.2
++++ kicker/core/Makefile.am 2010/08/10 08:17:08
+@@ -1,6 +1,6 @@
+ INCLUDES = -I$(srcdir)/../../libkicker -I../../libkicker \
+ -I../ui -I$(srcdir)/../ui -I$(srcdir)/../buttons -I$(top_srcdir)/libkonq \
+- $(all_includes)
++ $(all_includes) $(LIBBEAGLE_CFLAGS) $(GLIB_CFLAGS)
+
+ noinst_LTLIBRARIES = libkicker_core.la
+
+--- kicker/buttons/Makefile.am 2010/08/10 08:16:06 1.1
++++ kicker/buttons/Makefile.am 2010/08/10 08:16:28
+@@ -1,5 +1,5 @@
+ INCLUDES = -I$(srcdir)/../core -I$(srcdir)/../../libkicker -I../../libkicker \
+- -I../ui -I$(srcdir)/../ui -I$(top_srcdir)/libkonq $(all_includes)
++ -I../ui -I$(srcdir)/../ui -I$(top_srcdir)/libkonq $(all_includes) $(LIBBEAGLE_CFLAGS) $(GLIB_CFLAGS)
+
+ noinst_LTLIBRARIES = libkicker_buttons.la
+
diff --git a/opensuse/tdebase/kickoff-data.tar.bz2 b/opensuse/tdebase/kickoff-data.tar.bz2
new file mode 100644
index 000000000..9841a0aa0
--- /dev/null
+++ b/opensuse/tdebase/kickoff-data.tar.bz2
Binary files differ
diff --git a/opensuse/tdebase/kickoff-install-software.diff b/opensuse/tdebase/kickoff-install-software.diff
new file mode 100644
index 000000000..f053a45fb
--- /dev/null
+++ b/opensuse/tdebase/kickoff-install-software.diff
@@ -0,0 +1,25 @@
+--- kicker/kicker/ui/k_new_mnu.cpp 2007/08/08 15:14:50 1.141
++++ kicker/kicker/ui/k_new_mnu.cpp 2007/08/08 15:39:58
+@@ -1345,6 +1345,9 @@
+ KService::Ptr p = KService::serviceByStorageId("/usr/share/applications/YaST.desktop");
+ m_systemView->insertMenuItem(p, nId++, index++);
+
++ p = KService::serviceByStorageId("/usr/share/applications/package-manager.desktop");
++ m_systemView->insertMenuItem(p, nId++, index++);
++
+ m_systemView->insertItem( "info", i18n( "System Information" ),
+ "sysinfo:/", "sysinfo:/", nId++, index++ );
+
+--- kicker/kicker/ui/itemview.cpp 2007/08/08 15:14:50 1.141
++++ kicker/kicker/ui/itemview.cpp 2007/08/08 15:59:35
+@@ -139,7 +139,9 @@
+ void KMenuItem::setIcon(const QString& icon, int size)
+ {
+ m_icon = icon;
+- QListViewItem::setPixmap(0, KGlobal::iconLoader()->loadIcon(icon, KIcon::Panel, size ));
++ QPixmap pixmap = KGlobal::iconLoader()->loadIcon(icon, KIcon::Panel, size, KIcon::DefaultState, 0L, true);
++ if (!pixmap.isNull())
++ QListViewItem::setPixmap(0, pixmap);
+ }
+
+ void KMenuItem::setHasChildren( bool flag )
diff --git a/opensuse/tdebase/kickoff-kcm.diff b/opensuse/tdebase/kickoff-kcm.diff
new file mode 100644
index 000000000..1dd87afde
--- /dev/null
+++ b/opensuse/tdebase/kickoff-kcm.diff
@@ -0,0 +1,217 @@
+--- menutab_impl.h (revision 755866)
++++ menutab_impl.h (revision 774645)
+@@ -62,6 +62,7 @@ signals:
+
+ public slots:
+ void launchMenuEditor();
++ void menuStyleChanged();
+
+ protected:
+ kSubMenuItem *m_bookmarkMenu;
+--- kicker_config_hiding.desktop (revision 755866)
++++ kicker_config_hiding.desktop (revision 774645)
+@@ -146,7 +146,7 @@ Keywords[csb]=kicker,panel,kpanel,lëst
+ Keywords[cy]=ciciwr,kicker,panel,kpanel,bar tasgau,bar cychwyn,bar lansio,lleoliad,maint,awto-guddio,hunan-guddio,cuddio,botymau,animeiddiad,cefndir,themâu,storfa dewislen, storfa,cache,celc,cudd,K-Menu,nodau tudalen,dogfenni diweddar,porydd cyflym,dewislen porydd,dewislen,eiconau,teiliau,rhaglenigion,ymcychwyn,amlygu,carnau,eiconau chwyddo
+ Keywords[da]=kicker,panel,kpanel,opgavelinje,startlinje,sted,størrelse,autogem,gem,knapper,animering,baggrund,temaer,menucache,cache,skjult,K-Menu,bogmærker,nylige dokumenter,hurtigsøger,søgemenu,menu,ikoner,fliser,panelprogrammer,opstart,markér,håndterer,ikoner
+ Keywords[de]=Kicker,Panel,Taskbar,Kontrollleiste,Startleiste,Klickstartleiste,Fensterleiste,Autom. ausblenden,Ausblenden, Knöpfe,Animation,Hintergründe,Stile,Design,Themes,Menü-Zwischenspeicher, K-Menü,Zwischenspeicher,Lesezeichen,Zuletzt geöffnete Dateien, Schnellanzeiger,Menüs,Symbole,Icons,Kacheln,Applets,Miniprogramme, Java-Miniprogramme,Hervorhebung,Anfasser,Sicherheitsstufen,Zoom für Symbole
+-Keywords[el]=kicker,πίνακας,kpanel,γραμμή εργασιών,γραμμή έναρξης,γραμμή εκκίνησης,τοποθεσία,μέγεθος,αυτόματη απόκρυψη,απόκρυψη,κουμπιά,εφέ κίνησης,φόντο,θέματα,λανθάνουσα μνήμη μενού,λανθάνουσα μνήμη,κρυφό, K-Μενού,σελιδοδείκτες,πρόσφατα έγγραφα,γρήγορος εξερευνητής,μενού εξερευνητή,μενού,εικονίδια,tiles,μικροεφαρμογές,έναρξη,τονισμός,χειριστήρια, μεγέθυνση εικονιδίων
++Keywords[el]=kicker,πίνακας,kpanel,γραμμή εργασιών,γραμμή έναρξης,γραμμή εκκίνησης,τοποθεσία,μέγεθος,αυτόματη απόκρυψη,απόκρυψη,κουμπιά,εφέ κίνησης,φόντο,θέματα,λανθάνουσα μνήμη μενού,λανθάνουσα μνήμη,κρυφό, K-Μενού,σελιδοδείκτες,πρόσφατα έγγραφα,γρήγορος εξερευνητής,μενού εξερευνητή,μενού,εικονίδια,tiles,εφαρμογίδια,έναρξη,τονισμός,χειριστήρια, μεγέθυνση εικονιδίων
+ Keywords[eo]=lanĉilo,panelo,tasklistelo,situo,grandeco,aŭtokaŝo,kaŝo,butono,fono,etoso,menubufro,K-Menuo,legosigno,lasta dokumento,rapidrigardilo,rigardmenuo,piktogramo,kahelo,aplikaĵo,lanĉo,emfazo,teniloj,pligrandigo,fidindaj aplikaĵetoj,sekurecnivelo
+ Keywords[es]=kicker,panel,kpanel,barra de tareas,barra de inicio,barra de lanzamiento,dirección,tamaño,auto ocultar,ocultar,botones,animación,fondo,temas,caché de menú,caché,oculto,Menú K,marcadores,documentos recientes,navegador rápido,menú navegador,menú,iconos,mosaicos,miniaplicaciones,arranque,resaltado,asas,iconos ampliados
+ Keywords[et]=kicker,paneel,kpanel,tegumiriba,käivitusriba,asukoht,suurus,terminal,automaatne peitmine,peitmine,nupud,animatsioon,taust,teemad,menüü vahemälu,vahemälu,peidetud,K-menüü,järjehoidjad,viimati kasutatud dokumendid, kiirbrauser,lehitsemise menüü,menüü,ikoonid,apletid,käivitamine,esiletõstmine,piirded,ikoonide suurendamine,usaldusväärsed apletid,turvatase
+--- menutab_impl.cpp (revision 755866)
++++ menutab_impl.cpp (revision 774645)
+@@ -16,12 +16,16 @@
+ */
+
+ #include <qcheckbox.h>
++#include <qgroupbox.h>
+ #include <qdir.h>
+ #include <qlabel.h>
+ #include <qlayout.h>
+ #include <qpushbutton.h>
+ #include <qradiobutton.h>
++#include <qcombobox.h>
++#include <qbuttongroup.h>
+
++#include <dcopref.h>
+ #include <kapplication.h>
+ #include <kdebug.h>
+ #include <kdesktopfile.h>
+@@ -123,12 +127,41 @@ void MenuTab::load( bool useDefaults )
+ }
+ }
+
++ c->setGroup("General");
++ m_comboMenuStyle->setCurrentItem( c->readBoolEntry("LegacyKMenu", false) ? 1 : 0 );
++ m_openOnHover->setChecked( c->readBoolEntry("OpenOnHover", true) );
++ menuStyleChanged();
++
++ connect(m_comboMenuStyle, SIGNAL(activated(int)), SIGNAL(changed()));
++ connect(m_comboMenuStyle, SIGNAL(activated(int)), SLOT(menuStyleChanged()));
++ connect(m_openOnHover, SIGNAL(clicked()), SIGNAL(changed()));
++
+ m_showFrequent->setChecked(true);
+
+ if ( useDefaults )
+ emit changed();
+ }
+
++void MenuTab::menuStyleChanged()
++{
++ if (m_comboMenuStyle->currentItem()==1) {
++ m_openOnHover->setEnabled(false);
++ m_subMenus->setEnabled(true);
++ kcfg_UseSidePixmap->setEnabled(true);
++ kcfg_MenuEntryFormat->setEnabled(true);
++ kcfg_RecentVsOften->setEnabled(true);
++ m_showFrequent->setEnabled(true);
++ }
++ else {
++ m_openOnHover->setEnabled(true);
++ m_subMenus->setEnabled(false);
++ kcfg_UseSidePixmap->setEnabled(false);
++ kcfg_MenuEntryFormat->setEnabled(false);
++ kcfg_RecentVsOften->setEnabled(false);
++ m_showFrequent->setEnabled(false);
++ }
++}
++
+ void MenuTab::save()
+ {
+ KSharedConfig::Ptr c = KSharedConfig::openConfig(KickerConfig::the()->configName());
+@@ -154,8 +187,17 @@ void MenuTab::save()
+ }
+ }
+ c->writeEntry("Extensions", ext);
++ c->setGroup("General");
+
++ bool kmenusetting = m_comboMenuStyle->currentItem()==1;
++ bool oldkmenusetting = c->readBoolEntry("LegacyKMenu", false);
++
++ c->writeEntry("LegacyKMenu", kmenusetting);
++ c->writeEntry("OpenOnHover", m_openOnHover->isChecked());
+ c->sync();
++
++ if (kmenusetting != oldkmenusetting)
++ DCOPRef ("kicker", "default").call("restart()");
+ }
+
+ void MenuTab::defaults()
+--- menutab.ui (revision 755866)
++++ menutab.ui (revision 774645)
+@@ -8,8 +8,8 @@
+ <rect>
+ <x>0</x>
+ <y>0</y>
+- <width>410</width>
+- <height>437</height>
++ <width>923</width>
++ <height>649</height>
+ </rect>
+ </property>
+ <vbox>
+@@ -19,6 +19,59 @@
+ <property name="margin">
+ <number>0</number>
+ </property>
++ <widget class="QLayoutWidget">
++ <property name="name">
++ <cstring>layout5</cstring>
++ </property>
++ <hbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <widget class="QLabel">
++ <property name="name">
++ <cstring>textLabel1</cstring>
++ </property>
++ <property name="text">
++ <string>Start menu style:</string>
++ </property>
++ <property name="buddy" stdset="0">
++ <cstring>comboMenuStyle</cstring>
++ </property>
++ </widget>
++ <widget class="QComboBox">
++ <item>
++ <property name="text">
++ <string>SUSE</string>
++ </property>
++ </item>
++ <item>
++ <property name="text">
++ <string>KDE</string>
++ </property>
++ </item>
++ <property name="name">
++ <cstring>m_comboMenuStyle</cstring>
++ </property>
++ </widget>
++ <spacer>
++ <property name="name">
++ <cstring>spacer4</cstring>
++ </property>
++ <property name="orientation">
++ <enum>Horizontal</enum>
++ </property>
++ <property name="sizeType">
++ <enum>Expanding</enum>
++ </property>
++ <property name="sizeHint">
++ <size>
++ <width>40</width>
++ <height>20</height>
++ </size>
++ </property>
++ </spacer>
++ </hbox>
++ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>m_kmenuGroup</cstring>
+@@ -38,6 +91,14 @@
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
++ <widget class="QCheckBox" row="0" column="0">
++ <property name="name">
++ <cstring>m_openOnHover</cstring>
++ </property>
++ <property name="text">
++ <string>Open menu on mouse hover</string>
++ </property>
++ </widget>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>kcfg_MenuEntryFormat</cstring>
+@@ -377,6 +438,8 @@
+ </widget>
+ </vbox>
+ </widget>
++<customwidgets>
++</customwidgets>
+ <tabstops>
+ <tabstop>m_formatSimple</tabstop>
+ <tabstop>m_formatNameDesc</tabstop>
+@@ -400,8 +463,5 @@
+ <includehints>
+ <includehint>klistview.h</includehint>
+ <includehint>knuminput.h</includehint>
+- <includehint>knuminput.h</includehint>
+- <includehint>knuminput.h</includehint>
+- <includehint>knuminput.h</includehint>
+ </includehints>
+ </UI>
+--- kicker_config_menus.desktop (revision 755866)
++++ kicker_config_menus.desktop (revision 774645)
+@@ -143,7 +143,7 @@ Keywords[csb]=kicker,panel,kpanel,lëst
+ Keywords[cy]=ciciwr,kicker,panel,kpanel,bar tasgau,bar cychwyn,bar lansio,lleoliad,maint,awto-guddio,hunan-guddio,cuddio,botymau,animeiddiad,cefndir,themâu,storfa dewislen, storfa,cache,celc,cudd,K-Menu,nodau tudalen,dogfenni diweddar,porydd cyflym,dewislen porydd,dewislen,eiconau,teiliau,rhaglenigion,ymcychwyn,amlygu,carnau,eiconau chwyddo
+ Keywords[da]=kicker,panel,kpanel,opgavelinje,startlinje,sted,størrelse,autogem,gem,knapper,animering,baggrund,temaer,menucache,cache,skjult,K-Menu,bogmærker,nylige dokumenter,hurtigsøger,søgemenu,menu,ikoner,fliser,panelprogrammer,opstart,markér,håndterer,ikoner
+ Keywords[de]=Kicker,Panel,Taskbar,Kontrollleiste,Startleiste,Klickstartleiste,Fensterleiste,Autom. ausblenden,Ausblenden, Knöpfe,Animation,Hintergründe,Stile,Design,Themes,Menü-Zwischenspeicher, K-Menü,Zwischenspeicher,Lesezeichen,Zuletzt geöffnete Dateien, Schnellanzeiger,Menüs,Symbole,Icons,Kacheln,Applets,Miniprogramme, Java-Miniprogramme,Hervorhebung,Anfasser,Sicherheitsstufen,Zoom für Symbole
+-Keywords[el]=kicker,πίνακας,kpanel,γραμμή εργασιών,γραμμή έναρξης,γραμμή εκκίνησης,τοποθεσία,μέγεθος,αυτόματη απόκρυψη,απόκρυψη,κουμπιά,εφέ κίνησης,φόντο,θέματα,λανθάνουσα μνήμη μενού,λανθάνουσα μνήμη,κρυφό, K-Μενού,σελιδοδείκτες,πρόσφατα έγγραφα,γρήγορος εξερευνητής,μενού εξερευνητή,μενού,εικονίδια,tiles,μικροεφαρμογές,έναρξη,τονισμός,χειριστήρια, μεγέθυνση εικονιδίων
++Keywords[el]=kicker,πίνακας,kpanel,γραμμή εργασιών,γραμμή έναρξης,γραμμή εκκίνησης,τοποθεσία,μέγεθος,αυτόματη απόκρυψη,απόκρυψη,κουμπιά,εφέ κίνησης,φόντο,θέματα,λανθάνουσα μνήμη μενού,λανθάνουσα μνήμη,κρυφό, K-Μενού,σελιδοδείκτες,πρόσφατα έγγραφα,γρήγορος εξερευνητής,μενού εξερευνητή,μενού,εικονίδια,tiles,εφαρμογίδια,έναρξη,τονισμός,χειριστήρια, μεγέθυνση εικονιδίων
+ Keywords[eo]=lanĉilo,panelo,tasklistelo,situo,grandeco,aŭtokaŝo,kaŝo,butono,fono,etoso,menubufro,K-Menuo,legosigno,lasta dokumento,rapidrigardilo,rigardmenuo,piktogramo,kahelo,aplikaĵo,lanĉo,emfazo,teniloj,pligrandigo,fidindaj aplikaĵetoj,sekurecnivelo
+ Keywords[es]=kicker,panel,kpanel,barra de tareas,barra de inicio,barra de lanzamiento,dirección,tamaño,auto ocultar,ocultar,botones,animación,fondo,temas,caché de menú,caché,oculto,Menú K,marcadores,documentos recientes,navegador rápido,menú navegador,menú,iconos,mosaicos,miniaplicaciones,arranque,resaltado,asas,iconos ampliados
+ Keywords[et]=kicker,paneel,kpanel,tegumiriba,käivitusriba,asukoht,suurus,terminal,automaatne peitmine,peitmine,nupud,animatsioon,taust,teemad,menüü vahemälu,vahemälu,peidetud,K-menüü,järjehoidjad,viimati kasutatud dokumendid, kiirbrauser,lehitsemise menüü,menüü,ikoonid,apletid,käivitamine,esiletõstmine,piirded,ikoonide suurendamine,usaldusväärsed apletid,turvatase
diff --git a/opensuse/tdebase/kickoff.diff b/opensuse/tdebase/kickoff.diff
new file mode 100644
index 000000000..e2d73f567
--- /dev/null
+++ b/opensuse/tdebase/kickoff.diff
@@ -0,0 +1,9812 @@
+--- taskbar/taskcontainer.cpp (Revision 849788)
++++ taskbar/taskcontainer.cpp (Revision 849791)
+@@ -67,7 +67,11 @@
+ discardNextMouseEvent(false),
+ aboutToActivate(false),
+ m_mouseOver(false),
+- m_paintEventCompression(false)
++ animationTimer(0, "TaskContainer::animationTimer"),
++ dragSwitchTimer(0, "TaskContainer::dragSwitchTimer"),
++ attentionTimer(0, "TaskContainer::attentionTimer"),
++ m_paintEventCompression(false),
++ m_paintEventCompressionTimer(0, "TaskContainer::paintEventCompressionTimer")
+ {
+ init();
+ setAcceptDrops(true); // Always enabled to activate task during drag&drop.
+@@ -95,7 +99,11 @@
+ discardNextMouseEvent(false),
+ aboutToActivate(false),
+ m_mouseOver(false),
+- m_paintEventCompression(false)
++ animationTimer(0, "TaskContainer::animationTimer"),
++ dragSwitchTimer(0, "TaskContainer::dragSwitchTimer"),
++ attentionTimer(0, "TaskContainer::attentionTimer"),
++ m_paintEventCompression(false),
++ m_paintEventCompressionTimer(0, "TaskContainer::paintEventCompressionTimer")
+ {
+ init();
+ setEnabled(false);
+--- taskbar/taskbar.cpp 2009/11/20 21:00:26 1.1
++++ taskbar/taskbar.cpp 2009/11/20 21:00:38
+@@ -59,7 +59,8 @@
+ m_showIcon(false),
+ m_showOnlyIconified(false),
+ m_textShadowEngine(0),
+- m_ignoreUpdates(false)
++ m_ignoreUpdates(false),
++ m_relayoutTimer(0, "TaskBar::m_relayoutTimer")
+ {
+ arrowType = LeftArrow;
+ blocklayout = true;
+--- libkicker/panelbutton.h (Revision 849788)
++++ libkicker/panelbutton.h (Revision 849791)
+@@ -254,9 +254,11 @@
+ /**
+ * Sets the direction to pop up the contents of the button.
+ */
+- void setPopupDirection(KPanelApplet::Direction d);
++ virtual void setPopupDirection(KPanelApplet::Direction d);
+
+ protected:
++
++ void setIconAlignment(AlignmentFlags align);
+ /**
+ * Subclasses must implement this to define the name of the button which is
+ * used to identify this button for saving and loading. It must be unique
+@@ -391,6 +393,7 @@
+ QPixmap m_iconz; // mouse over
+ KPanelExtension::Position m_arrowDirection;
+ KPanelApplet::Direction m_popupDirection;
++ AlignmentFlags m_iconAlignment;
+ Orientation m_orientation;
+ int m_size;
+ double m_fontPercent;
+@@ -419,12 +422,12 @@
+ * Sets the button's popup menu.
+ * @param popup the menu to pop up
+ */
+- void setPopup(QPopupMenu *popup);
++ void setPopup(QWidget *popup);
+
+ /**
+ * @return the button's popup menu
+ */
+- QPopupMenu *popup() const;
++ QWidget *popup() const;
+
+ bool eventFilter(QObject *, QEvent *);
+ virtual void showMenu();
+@@ -459,8 +462,8 @@
+ private slots:
+ void menuAboutToHide();
+
+-private:
+- QPopupMenu *m_popup;
++protected:
++ QWidget *m_popup;
+ bool m_pressedDuringPopup;
+ bool m_initialized;
+
+--- libkicker/kickerSettings.kcfg (Revision 849788)
++++ libkicker/kickerSettings.kcfg (Revision 849791)
+@@ -98,6 +98,70 @@
+ <label>A list of extensions that have been loaded at runtime. In the case of a crash these extensions will not be loaded at the next Kicker start, in case they caused the crash</label>
+ </entry>
+
++<entry name="LegacyKMenu" type="Bool" >
++ <label>When this option is enabled, the classic K Menu is used.</label>
++ <default>false</default>
++ </entry>
++
++<entry name="OpenOnHover" type="Bool" >
++ <label>When this option is enabled, the SUSE Menu does open on mouse hover.</label>
++ <default>true</default>
++ </entry>
++
++<entry name="ScrollFlipView" type="Bool" >
++ <label>When this option is enabled, the SUSE Menu application view switching will scroll.</label>
++ <default>true</default>
++ </entry>
++
++<entry name="KMenuWidth" type="Int">
++ <label>Preferred width of the KMenu</label>
++ <default>0</default>
++ </entry>
++
++<entry name="KMenuHeight" type="Int">
++ <label>Preferred width of the KMenu</label>
++ <default>0</default>
++ </entry>
++
++<entry name="KickoffFontPointSizeOffset" type="Int" >
++ <label>With this option the scale of the fonts Kickoff uses can be influenced</label>
++ <default>0</default>
++ <min>-100</min>
++ <max>100</max>
++ </entry>
++
++<entry name="KickoffSearchAddressBook" type="Bool" >
++ <label>When this option is enabled, kabc is utilized to search for addresses. This may start KMail.</label>
++ <default>false</default>
++ </entry>
++
++<entry name="KickoffDrawGeekoEye" type="Bool" >
++ <label>When this option is enabled, the Geeko eye moves when the mouse hovers the start menu button</label>
++ <default>false</default>
++ </entry>
++
++<entry name="KickoffTabBarFormat" type="Enum" >
++ <choices>
++ <choice name="LabelAndIcon">
++ <label>Show names and icons on tabs</label>
++ </choice>
++ <choice name="LabelOnly">
++ <label>Show only the names</label>
++ </choice>
++ <choice name="IconOnly">
++ <label>Show only the icons</label>
++ </choice>
++ </choices>
++ <default>LabelAndIcon</default>
++ <label>Appearace of the Kickoff tabbar</label>
++ </entry>
++
++<entry name="KickoffSwitchTabsOnHover" type="Bool" >
++ <label>When this option is enabled, the tabs in the Kickoff menu will switch without the need to click</label>
++ <default>true</default>
++ </entry>
++
++
+ </group>
+
+ <group name="menus">
+@@ -172,6 +236,19 @@
+ <default>false</default>
+ </entry>
+
++<entry name="Favorites" type="StringList">
++ <label>The menu entries shown in the Favorites tab</label>
++ </entry>
++
++<entry name="FirstRun" type="Bool" >
++ <label>Whether the panel has been started before or not</label>
++ <default>false</default>
++ </entry>
++
++<entry name="FirstSeenApps" type="StringList">
++ <label>When the applications were first seen by Kickoff</label>
++ </entry>
++
+ </group>
+
+ <group name="button_tiles">
+@@ -337,6 +414,29 @@
+
+ </group>
+
++ <group name="SearchField">
++ <entry key="History" type="PathList">
++ <default></default>
++ <label></label>
++ <whatsthis></whatsthis>
++ </entry>
++ <entry key="HistoryLength" type="Int">
++ <default>50</default>
++ <label></label>
++ <whatsthis></whatsthis>
++ </entry>
++ <entry key="CompletionItems" type="PathList">
++ <default></default>
++ <label></label>
++ <whatsthis></whatsthis>
++ </entry>
++ <entry key="CompletionMode" type="Int">
++ <default>2</default>
++ <label></label>
++ <whatsthis></whatsthis>
++ </entry>
++ </group>
++
+ </kcfg>
+
+
+--- libkicker/kickertip.cpp (Revision 849788)
++++ libkicker/kickertip.cpp (Revision 849791)
+@@ -38,6 +38,7 @@
+
+ // putting this #include higher results in compile errors
+ #include <netwm.h>
++#include <assert.h>
+
+ static const int DEFAULT_FRAMES_PER_SECOND = 30;
+
+@@ -71,14 +72,16 @@
+ m_dissolveDelta(-1),
+ m_direction(KPanelApplet::Up),
+ m_dirty(false),
+- m_toolTipsEnabled(KickerSettings::showToolTips()),
+- m_tippingFor(0)
++ m_tippingFor(0),
++ m_timer(0, "KickerTip::m_timer"),
++ m_frameTimer(0, "KickerTip::m_frameTimer")
+ {
+ setFocusPolicy(NoFocus);
+ setBackgroundMode(NoBackground);
+ resize(0, 0);
+ hide();
+ connect(&m_frameTimer, SIGNAL(timeout()), SLOT(internalUpdate()));
++ connect(kapp, SIGNAL(settingsChanged(SettingsCategory)), SLOT(slotSettingsChanged()));
+ }
+
+ KickerTip::~KickerTip()
+@@ -87,6 +90,11 @@
+ delete m_mimeFactory;
+ }
+
++void KickerTip::slotSettingsChanged()
++{
++ QToolTip::setGloballyEnabled(KickerSettings::showToolTips());
++}
++
+ void KickerTip::display()
+ {
+ if (!tippingEnabled())
+@@ -192,9 +200,7 @@
+
+ void KickerTip::mousePressEvent(QMouseEvent * /*e*/)
+ {
+- QToolTip::setGloballyEnabled(m_toolTipsEnabled);
+ m_timer.stop();
+- m_frameTimer.stop();
+ hide();
+ }
+
+@@ -395,8 +401,11 @@
+ m_tippingEnabled--;
+ }
+
++ assert(m_tippingEnabled >= -1);
++
+ if (m_tippingEnabled < 1 && m_self)
+ {
++ m_self->m_timer.stop();
+ m_self->hide();
+ }
+ }
+@@ -411,6 +420,8 @@
+ m_tippingFor = 0;
+ m_frameTimer.stop();
+ QWidget::hide();
++
++ QToolTip::setGloballyEnabled(KickerSettings::showToolTips());
+ }
+
+ bool KickerTip::eventFilter(QObject *object, QEvent *event)
+@@ -439,7 +450,6 @@
+ !qApp->activePopupWidget() &&
+ !isTippingFor(widget))
+ {
+- m_toolTipsEnabled = QToolTip::isGloballyEnabled();
+ QToolTip::setGloballyEnabled(false);
+
+ tipFor(widget);
+@@ -461,8 +471,6 @@
+ }
+ break;
+ case QEvent::Leave:
+- QToolTip::setGloballyEnabled(m_toolTipsEnabled);
+-
+ m_timer.stop();
+
+ if (isTippingFor(widget) && isVisible())
+@@ -475,9 +483,7 @@
+ tipFor(0);
+ break;
+ case QEvent::MouseButtonPress:
+- QToolTip::setGloballyEnabled(m_toolTipsEnabled);
+ m_timer.stop();
+- m_frameTimer.stop();
+ hide();
+ default:
+ break;
+--- libkicker/kickertip.h (Revision 849788)
++++ libkicker/kickertip.h (Revision 849791)
+@@ -92,6 +92,7 @@
+ void tipperDestroyed(QObject* o);
+ void internalUpdate();
+ void display();
++ void slotSettingsChanged();
+
+ private:
+ QBitmap m_mask;
+@@ -108,7 +109,6 @@
+ QTimer m_timer;
+ QTimer m_frameTimer;
+ bool m_dirty;
+- bool m_toolTipsEnabled;
+
+ const QWidget* m_tippingFor;
+
+--- libkicker/panelbutton.cpp (Revision 849788)
++++ libkicker/panelbutton.cpp (Revision 849791)
+@@ -42,6 +42,7 @@
+ #include <kipc.h>
+ #include <kstandarddirs.h>
+ #include <klocale.h>
++#include <kdebug.h>
+
+ #include "global.h"
+
+@@ -65,6 +66,7 @@
+ m_hasAcceptedDrag(false),
+ m_arrowDirection(KPanelExtension::Bottom),
+ m_popupDirection(KPanelApplet::Up),
++ m_iconAlignment(AlignCenter),
+ m_orientation(Horizontal),
+ m_size((KIcon::StdSizes)-1),
+ m_fontPercent(0.40)
+@@ -186,6 +188,12 @@
+ setArrowDirection(KickerLib::directionToPopupPosition(d));
+ }
+
++void PanelButton::setIconAlignment(AlignmentFlags align)
++{
++ m_iconAlignment = align;
++ update();
++}
++
+ void PanelButton::setOrientation(Orientation o)
+ {
+ m_orientation = o;
+@@ -300,7 +308,9 @@
+
+ int PanelButton::heightForWidth(int width) const
+ {
+- return preferredDimension(width);
++ int rc=preferredDimension(width);
++
++ return rc;
+ }
+
+ const QPixmap& PanelButton::labelIcon() const
+@@ -556,11 +566,16 @@
+ icon.height() - 2);
+ }
+
++ int y = 0;
++ if (m_iconAlignment & AlignVCenter)
++ y = (height() - icon.height()) / 2;
++ else if (m_iconAlignment & AlignBottom)
++ y = (height() - icon.height());
++
+ if (!m_buttonText.isEmpty() && orientation() == Horizontal)
+ {
+ int h = height();
+ int w = width();
+- int y = (h - icon.height())/2;
+ p->save();
+ QFont f = font();
+
+@@ -629,8 +644,11 @@
+ }
+ else if (!icon.isNull())
+ {
+- int y = (height() - icon.height()) / 2;
+- int x = (width() - icon.width()) / 2;
++ int x = 0;
++ if (m_iconAlignment & AlignHCenter)
++ x = (width() - icon.width()) / 2;
++ else if (m_iconAlignment & AlignRight)
++ x = (width() - icon.width());
+ p->drawPixmap(x, y, icon);
+ }
+
+@@ -792,7 +810,19 @@
+ QString nm = m_iconName;
+ KIcon::States defaultState = isEnabled() ? KIcon::DefaultState :
+ KIcon::DisabledState;
+- m_icon = ldr->loadIcon(nm, KIcon::Panel, m_size, defaultState, 0L, true);
++ if (nm=="kmenu-suse")
++ {
++ QString pth = locate( "data", "kicker/pics/kmenu_basic.mng" );
++ if (!pth.isEmpty())
++ {
++ m_icon = QImage(pth);
++ m_iconh = QPixmap(m_icon);
++ m_iconz = QPixmap(m_icon);
++ return;
++ }
++ }
++ else
++ m_icon = ldr->loadIcon(nm, KIcon::Panel, m_size, defaultState, 0L, true);
+
+ if (m_icon.isNull())
+ {
+@@ -857,7 +887,7 @@
+ connect(this, SIGNAL(pressed()), SLOT(slotExecMenu()));
+ }
+
+-void PanelPopupButton::setPopup(QPopupMenu *popup)
++void PanelPopupButton::setPopup(QWidget *popup)
+ {
+ if (m_popup)
+ {
+@@ -875,7 +905,7 @@
+ }
+ }
+
+-QPopupMenu *PanelPopupButton::popup() const
++QWidget *PanelPopupButton::popup() const
+ {
+ return m_popup;
+ }
+@@ -954,7 +984,9 @@
+ }
+
+ m_popup->adjustSize();
+- m_popup->exec(KickerLib::popupPosition(popupDirection(), m_popup, this));
++ if(dynamic_cast<QPopupMenu*>(m_popup))
++ static_cast<QPopupMenu*>(m_popup)->exec(KickerLib::popupPosition(popupDirection(), m_popup, this));
++ // else.. hmm. some derived class has to fix it.
+ }
+
+ void PanelPopupButton::menuAboutToHide()
+@@ -964,8 +996,10 @@
+ return;
+ }
+
+- setDown(false);
+- KickerTip::enableTipping(true);
++ if (isDown()) {
++ setDown(false);
++ KickerTip::enableTipping(true);
++ }
+ }
+
+ void PanelPopupButton::triggerDrag()
+@@ -983,3 +1017,5 @@
+ m_initialized = initialized;
+ }
+
++
++
+--- extensions/kasbar/kasbar.cpp (Revision 849788)
++++ extensions/kasbar/kasbar.cpp (Revision 849791)
+@@ -719,7 +719,7 @@
+ i->setText( "Animated" );
+ i->setIcon( KGlobal::iconLoader()->loadIcon( "icons", KIcon::NoGroup, KIcon::SizeMedium ) );
+ i->setAnimation( resources()->startupAnimation() );
+- QTimer *aniTimer = new QTimer( i );
++ QTimer *aniTimer = new QTimer( i, "aniTimer" );
+ connect( aniTimer, SIGNAL( timeout() ), i, SLOT( advanceAnimation() ) );
+ aniTimer->start( 100 );
+ i->setShowAnimation( true );
+--- extensions/kasbar/kasclockitem.cpp (Revision 849788)
++++ extensions/kasbar/kasclockitem.cpp (Revision 849791)
+@@ -38,7 +38,7 @@
+ {
+ setCustomPopup( true );
+
+- QTimer *t = new QTimer( this );
++ QTimer *t = new QTimer( this, "t" );
+ connect( t, SIGNAL( timeout() ), SLOT( updateTime() ) );
+ t->start( 1000 );
+
+--- extensions/kasbar/kasstartupitem.cpp (Revision 849788)
++++ extensions/kasbar/kasstartupitem.cpp (Revision 849791)
+@@ -79,7 +79,7 @@
+ setShowFrame( false );
+ setAnimation( resources()->startupAnimation() );
+
+- aniTimer = new QTimer( this );
++ aniTimer = new QTimer( this, "aniTimer" );
+ connect( aniTimer, SIGNAL( timeout() ), SLOT( aniTimerFired() ) );
+ aniTimer->start( 100 );
+ }
+--- extensions/kasbar/kasloaditem.cpp (Revision 849788)
++++ extensions/kasbar/kasloaditem.cpp (Revision 849791)
+@@ -33,7 +33,7 @@
+ KasLoadItem::KasLoadItem( KasBar *parent )
+ : KasItem( parent )
+ {
+- QTimer *t = new QTimer( this );
++ QTimer *t = new QTimer( this, "KasLoadItem::t" );
+ connect( t, SIGNAL( timeout() ), SLOT( updateDisplay() ) );
+ t->start( 1000 );
+ updateDisplay();
+--- kicker/interfaces/kickoff-search-plugin.h (Revision 0)
++++ kicker/interfaces/kickoff-search-plugin.h (Revision 849791)
+@@ -0,0 +1,106 @@
++/***************************************************************************
++ * Copyright (C) 2006 by Stephan Binner <binner@kde.org> *
++ * Copyright (c) 2006 Debajyoti Bera <dbera.web@gmail.com> *
++ * *
++ * 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 KICKOFF_SEARCH_PLUGIN_H
++#define KICKOFF_SEARCH_PLUGIN_H
++
++#include "kickoffsearchinterface.h"
++
++#include <qobject.h>
++#include <kurl.h>
++#include <kservice.h>
++
++typedef enum {
++ ACTIONS = 0,
++ APPS,
++ BOOKMARKS,
++ NOTES,
++ MAILS,
++ FILES,
++ MUSIC,
++ WEBHIST,
++ CHATS,
++ FEEDS,
++ PICS,
++ VIDEOS,
++ DOCS,
++ OTHER,
++ num_categories
++} CATEGORY;
++
++class HitMenuItem
++{
++public:
++ HitMenuItem (int id, int category)
++ : id (id), category (category),score(0) { } /* dummy */
++ HitMenuItem (QString name, QString info, KURL uri, QString mimetype, int id, int category, QString icon=QString::null, int score = 0)
++ : display_name (name)
++ , display_info (info)
++ , uri (uri)
++ , mimetype (mimetype)
++ , id (id)
++ , category (category)
++ , icon (icon)
++ , score (score)
++ , service (NULL) { }
++
++ ~HitMenuItem () { }
++
++ bool operator< (HitMenuItem item)
++ {
++ return ((category == item.category && score > item.score) || (category == item.category && id < item.id) ||
++ (category < item.category));
++ }
++
++ // FIXME: We dont really need to store display_name and display_info
++ QString display_name; // name to display
++ QString display_info; // other information to display
++ KURL uri; // uri to open when clicked
++ QString mimetype;
++ int id; // id of the item in the menu
++ int category;
++ QString icon;
++ int score;
++ KService::Ptr service;
++
++ QString quotedPath () const
++ {
++ return uri.path ().replace ('"', "\\\"");
++ }
++};
++
++namespace KickoffSearch {
++
++ class Plugin : public QObject
++ {
++ Q_OBJECT
++
++ public:
++ Plugin(QObject *parent, const char* name=0);
++ virtual ~Plugin();
++
++ virtual bool daemonRunning()=0;
++ virtual void query(QString,bool)=0;
++
++ KickoffSearchInterface * kickoffSearchInterface();
++ };
++};
++
++#endif /* KICKOFF_SEARCH_PLUGIN_H */
+--- kicker/interfaces/kickoffsearchinterface.cpp (Revision 0)
++++ kicker/interfaces/kickoffsearchinterface.cpp (Revision 849791)
+@@ -0,0 +1,27 @@
++/***************************************************************************
++ * Copyright (C) 2006 by Stephan Binner <binner@kde.org> *
++ * *
++ * 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 "kickoffsearchinterface.h"
++
++KickoffSearch::KickoffSearchInterface::KickoffSearchInterface( QObject* parent, const char* name )
++ :QObject( parent, name )
++{
++}
++
++#include "kickoffsearchinterface.moc"
+--- kicker/interfaces/Makefile.am (Revision 0)
++++ kicker/interfaces/Makefile.am (Revision 849791)
+@@ -0,0 +1,12 @@
++METASOURCES = AUTO
++INCLUDES= -I$(top_srcdir)/src $(all_includes)
++
++# The library containing the plugin base class
++lib_LTLIBRARIES = libkickoffsearch_interfaces.la
++libkickoffsearch_interfaces_la_SOURCES = kickoff-search-plugin.cpp kickoffsearchinterface.cpp
++libkickoffsearch_interfaces_la_LDFLAGS = $(all_libraries) -version-info 0:0:0
++
++kickoffsearchincludedir = $(includedir)
++kickoffsearchinclude_HEADERS = kickoff-search-plugin.h kickoffsearchinterface.h
++
++kde_servicetypes_DATA = kickoffsearchplugin.desktop
+--- kicker/interfaces/kickoffsearchinterface.h (Revision 0)
++++ kicker/interfaces/kickoffsearchinterface.h (Revision 849791)
+@@ -0,0 +1,46 @@
++/***************************************************************************
++ * Copyright (C) 2006 by Stephan Binner <binner@kde.org> *
++ * *
++ * 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 KICKOFFSEARCHINTERFACE_H
++#define KICKOFFSEARCHINTERFACE_H
++
++#include <qobject.h>
++
++class HitMenuItem;
++
++namespace KickoffSearch
++{
++ class KickoffSearchInterface :public QObject
++ {
++ Q_OBJECT
++
++ public:
++ KickoffSearchInterface( QObject* parent, const char* name = 0);
++
++ public:
++ virtual bool anotherHitMenuItemAllowed(int cat) = 0;
++ virtual void addHitMenuItem(HitMenuItem* item) = 0;
++ virtual void searchOver() = 0;
++ virtual void initCategoryTitlesUpdate() = 0;
++ virtual void updateCategoryTitles() = 0;
++ };
++}
++
++#endif /* SELECTIONINTERFACE_H */
++
+--- kicker/interfaces/kickoffsearchplugin.desktop (Revision 0)
++++ kicker/interfaces/kickoffsearchplugin.desktop (Revision 849791)
+@@ -0,0 +1,4 @@
++[Desktop Entry]
++Type=ServiceType
++X-KDE-ServiceType=KickoffSearch/Plugin
++Comment=A search plugin for Kickoff
+--- kicker/interfaces/kickoff-search-plugin.cpp (Revision 0)
++++ kicker/interfaces/kickoff-search-plugin.cpp (Revision 849791)
+@@ -0,0 +1,37 @@
++/***************************************************************************
++ * Copyright (C) 2006 by Stephan Binner <binner@kde.org> *
++ * *
++ * 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 "kickoff-search-plugin.h"
++#include <qobjectlist.h>
++
++KickoffSearch::Plugin::Plugin(QObject *parent, const char* name )
++ :QObject( parent, name )
++{
++}
++
++KickoffSearch::Plugin::~Plugin()
++{
++}
++
++KickoffSearch::KickoffSearchInterface* KickoffSearch::Plugin::kickoffSearchInterface()
++{
++ return static_cast<KickoffSearchInterface*>( parent()->child( 0, "KickoffSearch::KickoffSearchInterface" ) );
++}
++
++#include "kickoff-search-plugin.moc"
+
+Eigenschaftsänderungen: kicker/interfaces
+___________________________________________________________________
+Hinzugefügt: svn:ignore
+ + .deps
+libkickoffsearch_interfaces.la
+.libs
+Makefile
+Makefile.in
+*.moc
+
+
+--- kicker/core/menumanager.h (Revision 849788)
++++ kicker/core/menumanager.h (Revision 849791)
+@@ -28,7 +28,9 @@
+ #include <qvaluelist.h>
+
+ class PanelKMenu;
++class KMenu;
+ class KickerClientMenu;
++class KMenuStub;
+ class PanelPopupButton;
+
+ typedef QValueList<PanelPopupButton*> KButtonList;
+@@ -50,13 +52,12 @@
+ bool process(const QCString &fun, const QByteArray &data, QCString& replyType, QByteArray &reply);
+
+ // KMenu controls
+- PanelKMenu* kmenu() { return m_kmenu; }
+- void showKMenu();
++ KMenuStub* kmenu() { return m_kmenu; }
+ void popupKMenu(const QPoint &p);
+
+ void registerKButton(PanelPopupButton *button);
+ void unregisterKButton(PanelPopupButton *button);
+- PanelPopupButton* findKButtonFor(QPopupMenu* menu);
++ PanelPopupButton* findKButtonFor(QWidget* menu);
+ ~MenuManager();
+
+ public slots:
+@@ -67,7 +68,7 @@
+ void applicationRemoved(const QCString&);
+
+ protected:
+- PanelKMenu* m_kmenu;
++ KMenuStub* m_kmenu;
+ typedef QValueList<KickerClientMenu*> ClientMenuList;
+ ClientMenuList clientmenus;
+
+--- kicker/core/kicker.cpp (Revision 849788)
++++ kicker/core/kicker.cpp (Revision 849791)
+@@ -48,6 +48,8 @@
+ #include "extensionmanager.h"
+ #include "pluginmanager.h"
+ #include "menumanager.h"
++#include "k_new_mnu.h"
++#include "k_mnu_stub.h"
+ #include "k_mnu.h"
+ #include "showdesktop.h"
+ #include "panelbutton.h"
+@@ -106,6 +108,7 @@
+
+ KGlobal::iconLoader()->addExtraDesktopThemes();
+
++ KGlobal::locale()->insertCatalogue("kdmgreet");
+ KGlobal::locale()->insertCatalogue("libkonq");
+ KGlobal::locale()->insertCatalogue("libdmctl");
+ KGlobal::locale()->insertCatalogue("libtaskbar");
+@@ -212,7 +215,7 @@
+
+ void Kicker::showKMenu()
+ {
+- MenuManager::the()->showKMenu();
++ MenuManager::the()->kmenuAccelActivated();
+ }
+
+ void Kicker::popupKMenu(const QPoint &p)
+--- kicker/core/container_button.cpp (Revision 849788)
++++ kicker/core/container_button.cpp (Revision 849791)
+@@ -43,6 +43,7 @@
+ #include "desktopbutton.h"
+ #include "extensionbutton.h"
+ #include "kbutton.h"
++#include "knewbutton.h"
+ #include "kicker.h"
+ #include "kickerSettings.h"
+ #include "kickertip.h"
+@@ -326,14 +327,20 @@
+ : ButtonContainer(opMenu, parent)
+ {
+ checkImmutability(config);
+- embedButton( new KButton(this) );
++ if(KickerSettings::legacyKMenu())
++ embedButton( new KButton(this) );
++ else
++ embedButton( new KNewButton(this) );
+ _actions = PanelAppletOpMenu::KMenuEditor;
+ }
+
+ KMenuButtonContainer::KMenuButtonContainer(QPopupMenu *opMenu, QWidget* parent)
+ : ButtonContainer(opMenu, parent)
+ {
+- embedButton( new KButton(this) );
++ if(KickerSettings::legacyKMenu())
++ embedButton( new KButton(this) );
++ else
++ embedButton( new KNewButton(this) );
+ _actions = PanelAppletOpMenu::KMenuEditor;
+ }
+
+--- kicker/core/main.cpp (Revision 849788)
++++ kicker/core/main.cpp (Revision 849791)
+@@ -108,7 +108,7 @@
+ appname.sprintf("kicker-screen-%d", kicker_screen_number);
+
+ KAboutData aboutData( appname.data(), I18N_NOOP("KDE Panel"),
+- version, description, KAboutData::License_BSD,
++ version, description, KAboutData::License_GPL_V2,
+ I18N_NOOP("(c) 1999-2004, The KDE Team") );
+
+ aboutData.addAuthor("Aaron J. Seigo", I18N_NOOP("Current maintainer"), "aseigo@kde.org");
+--- kicker/core/menumanager.cpp (Revision 849788)
++++ kicker/core/menumanager.cpp (Revision 849791)
+@@ -31,9 +31,12 @@
+ #include "client_mnu.h"
+ #include "container_extension.h"
+ #include "global.h"
++#include "k_new_mnu.h"
+ #include "k_mnu.h"
++#include "k_mnu_stub.h"
+ #include "kicker.h"
+ #include "panelbutton.h"
++#include "kickerSettings.h"
+
+ #include "menumanager.h"
+ #include "menumanager.moc"
+@@ -62,7 +65,11 @@
+ MenuManager::MenuManager(QObject *parent)
+ : QObject(parent, "MenuManager"), DCOPObject("MenuManager")
+ {
+- m_kmenu = new PanelKMenu;
++ if (KickerSettings::legacyKMenu())
++ m_kmenu = new KMenuStub(new PanelKMenu);
++ else
++ m_kmenu = new KMenuStub(new KMenu);
++
+ kapp->dcopClient()->setNotifications(true);
+ connect(kapp->dcopClient(), SIGNAL(applicationRemoved(const QCString&)),
+ this, SLOT(applicationRemoved(const QCString&)));
+@@ -83,14 +90,8 @@
+ m_kmenu->selectFirstItem();
+ }
+
+-void MenuManager::showKMenu()
+-{
+- m_kmenu->showMenu();
+-}
+-
+ void MenuManager::popupKMenu(const QPoint &p)
+ {
+-// kdDebug(1210) << "popupKMenu()" << endl;
+ if (m_kmenu->isVisible())
+ {
+ m_kmenu->hide();
+@@ -120,7 +121,7 @@
+ m_kbuttons.remove(button);
+ }
+
+-PanelPopupButton* MenuManager::findKButtonFor(QPopupMenu* menu)
++PanelPopupButton* MenuManager::findKButtonFor(QWidget* menu)
+ {
+ KButtonList::const_iterator itEnd = m_kbuttons.constEnd();
+ for (KButtonList::const_iterator it = m_kbuttons.constBegin(); it != itEnd; ++it)
+@@ -169,7 +170,7 @@
+ const QSize size = m_kmenu->sizeHint();
+ m_kmenu->resize(size.width(),size.height());
+
+- PanelPopupButton* button = findKButtonFor(m_kmenu);
++ PanelPopupButton* button = findKButtonFor(m_kmenu->widget());
+
+ // let's unhide the panel while we're at it. traverse the widget
+ // hierarchy until we find the panel, if any
+@@ -189,7 +190,6 @@
+
+ menuParent = menuParent->parent();
+ }
+-
+ button->showMenu();
+ }
+ }
+@@ -213,7 +213,7 @@
+
+ void MenuManager::removeMenu(QCString menu)
+ {
+- bool iterate = true;
++ bool iterate = true, need_adjustSize = false;
+ ClientMenuList::iterator it = clientmenus.begin();
+ for (; it != clientmenus.end(); iterate ? ++it : it)
+ {
+@@ -224,15 +224,17 @@
+ m_kmenu->removeClientMenu(m->idInParentMenu);
+ it = clientmenus.erase(it);
+ iterate = false;
++ need_adjustSize = true;
+ }
+ }
+- m_kmenu->adjustSize();
++ if (need_adjustSize)
++ m_kmenu->adjustSize();
+ }
+
+
+ void MenuManager::applicationRemoved(const QCString& appRemoved)
+ {
+- bool iterate = true;
++ bool iterate = true, need_adjustSize = false;
+ ClientMenuList::iterator it = clientmenus.begin();
+ for (; it != clientmenus.end(); iterate ? ++it : it)
+ {
+@@ -243,9 +245,11 @@
+ m_kmenu->removeClientMenu(m->idInParentMenu);
+ it = clientmenus.erase(it);
+ iterate = false;
++ need_adjustSize = true;
+ }
+ }
+- m_kmenu->adjustSize();
++ if (need_adjustSize)
++ m_kmenu->adjustSize();
+ }
+
+ bool MenuManager::process(const QCString &fun, const QByteArray &data,
+--- kicker/core/unhidetrigger.cpp (Revision 849788)
++++ kicker/core/unhidetrigger.cpp (Revision 849791)
+@@ -39,7 +39,7 @@
+ , _lastXineramaScreen( -1 )
+ , enabledCount( 0 )
+ {
+- _timer = new QTimer( this );
++ _timer = new QTimer( this, "UnhideTrigger" );
+ connect( _timer, SIGNAL(timeout()), SLOT(pollMouse()) );
+ }
+
+--- kicker/core/applethandle.cpp (Revision 849788)
++++ kicker/core/applethandle.cpp (Revision 849791)
+@@ -150,7 +150,7 @@
+ {
+ if (!m_handleHoverTimer)
+ {
+- m_handleHoverTimer = new QTimer(this);
++ m_handleHoverTimer = new QTimer(this, "m_handleHoverTimer");
+ connect(m_handleHoverTimer, SIGNAL(timeout()),
+ this, SLOT(checkHandleHover()));
+ m_applet->installEventFilter(this);
+@@ -177,11 +177,7 @@
+ m_drawHandle = true;
+ resetLayout();
+
+- if (m_handleHoverTimer)
+- {
+- m_handleHoverTimer->start(250);
+- }
+- break;
++ break;
+ }
+
+ case QEvent::Leave:
+@@ -191,6 +187,11 @@
+ break;
+ }
+
++ if (m_handleHoverTimer)
++ {
++ m_handleHoverTimer->start(250);
++ }
++
+ QWidget* w = dynamic_cast<QWidget*>(o);
+
+ bool nowDrawIt = false;
+@@ -207,11 +208,6 @@
+
+ if (nowDrawIt != m_drawHandle)
+ {
+- if (m_handleHoverTimer)
+- {
+- m_handleHoverTimer->stop();
+- }
+-
+ m_drawHandle = nowDrawIt;
+ resetLayout();
+ }
+@@ -297,6 +293,11 @@
+ }
+
+ m_menuButton->setDown(false);
++
++ if (m_handleHoverTimer)
++ {
++ m_handleHoverTimer->start(250);
++ }
+ }
+
+ AppletHandleDrag::AppletHandleDrag(AppletHandle* parent)
+--- kicker/core/containerarea.cpp 2009/11/20 21:00:18 1.1
++++ kicker/core/containerarea.cpp 2009/11/20 21:00:38
+@@ -87,7 +87,8 @@
+ m_immutable(_c->isImmutable()),
+ m_updateBackgroundsCalled(false),
+ m_layout(0),
+- m_addAppletDialog(0)
++ m_addAppletDialog(0),
++ _autoScrollTimer(0, "ContainerArea::autoScrollTimer")
+ {
+ setBackgroundOrigin( WidgetOrigin );
+
+--- kicker/core/Makefile.am (Revision 849788)
++++ kicker/core/Makefile.am (Revision 849791)
+@@ -1,6 +1,6 @@
+ INCLUDES = -I$(srcdir)/../../libkicker -I../../libkicker \
+- -I$(srcdir)/../ui -I$(srcdir)/../buttons -I$(top_srcdir)/libkonq \
+- $(all_includes)
++ -I../ui -I$(srcdir)/../ui -I$(srcdir)/../buttons -I$(top_srcdir)/libkonq \
++ $(all_includes)
+
+ noinst_LTLIBRARIES = libkicker_core.la
+
+--- kicker/Makefile.am (Revision 849788)
++++ kicker/Makefile.am (Revision 849791)
+@@ -1,6 +1,6 @@
+ INCLUDES = $(all_includes)
+
+-SUBDIRS = core ui buttons .
++SUBDIRS = core ui buttons interfaces .
+
+ bin_PROGRAMS =
+ lib_LTLIBRARIES =
+@@ -9,7 +9,7 @@
+ CLEANFILES = dummy.cpp
+
+ kicker_la_LIBADD = core/libkicker_core.la buttons/libkicker_buttons.la \
+- ui/libkicker_ui.la ../libkicker/libkickermain.la $(LIB_KIO) $(LIB_KUTILS)
++ ui/libkicker_ui.la ../libkicker/libkickermain.la $(LIB_KIO) $(LIB_KUTILS) $(LIB_KABC)
+
+ kicker_la_SOURCES = dummy.cpp
+ kicker_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries)
+--- kicker/ui/browser_mnu.cpp (Revision 849788)
++++ kicker/ui/browser_mnu.cpp (Revision 849791)
+@@ -329,7 +329,7 @@
+ if(_mimemap.count() > 0) {
+
+ if(!_mimecheckTimer)
+- _mimecheckTimer = new QTimer(this);
++ _mimecheckTimer = new QTimer(this, "_mimecheckTimer");
+
+ connect(_mimecheckTimer, SIGNAL(timeout()), SLOT(slotMimeCheck()));
+ _mimecheckTimer->start(0);
+--- kicker/ui/flipscrollview.cpp (Revision 0)
++++ kicker/ui/flipscrollview.cpp (Revision 849791)
+@@ -0,0 +1,324 @@
++/*****************************************************************
++
++Copyright (c) 2006 Will Stephenson <wstephenson@novell.com>
++
++Permission is hereby granted, free of charge, to any person obtaining a copy
++of this software and associated documentation files (the "Software"), to deal
++in the Software without restriction, including without limitation the rights
++to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
++copies of the Software, and to permit persons to whom the Software is
++furnished to do so, subject to the following conditions:
++
++The above copyright notice and this permission notice shall be included in
++all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
++AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
++CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++
++******************************************************************/
++
++#include <qapplication.h>
++#include <qhbox.h>
++#include <qheader.h>
++#include <assert.h>
++
++#include "itemview.h"
++#include "flipscrollview.h"
++#include "kickerSettings.h"
++
++/* Flip scroll steps, as percentage of itemview width to scroll per
++ * step. Assumes the itemview is scrolled in ten steps */
++
++/* slow start, then fast */
++//static const double scrollSteps[] = { 0.05, 0.05, 0.1125, 0.1125, 0.1125, 0.1125, 0.1125, 0.1125, 0.1125, 0.1125 };
++
++/* slow fast slow */
++//static const double scrollSteps[] = { 0.05, 0.05, 0.13, 0.13, 0.15, 0.13, 0.13, 0.13, 0.05, 0.05 };
++
++/* slow veryfast slow */
++static const double scrollSteps[] = { 0.03, 0.03, 0.147, 0.147, 0.147, 0.147, 0.147, 0.147, 0.03, 0.028 };
++;
++
++BackFrame::BackFrame( QWidget *parent )
++ : QFrame( parent ), mouse_inside( false )
++{
++ setFrameStyle( QFrame::NoFrame );
++ if ( QApplication::reverseLayout() )
++ left_triangle.load( locate( "data", "kicker/pics/right_triangle.png" ) );
++ else
++ left_triangle.load( locate( "data", "kicker/pics/left_triangle.png" ) );
++}
++
++void BackFrame::drawContents( QPainter *p )
++{
++ QColor gray( 230, 230, 230 );
++ if ( mouse_inside )
++ p->fillRect( 3, 3, width() - 6, height() - 6, colorGroup().color( QColorGroup::Highlight ) );
++ else
++ p->fillRect( 3, 3, width() - 6, height() - 6, gray );
++ p->setPen( gray.dark(110) );
++ p->drawRect( 3, 3, width() - 6, height() - 6 );
++
++ int pixsize = ( width() - 6 ) * 3 / 5;
++ QImage i = left_triangle.convertToImage().smoothScale( pixsize, pixsize );
++ QPixmap tri;
++ tri.convertFromImage( i );
++
++ p->drawPixmap( ( width() - tri.width() ) / 2, ( height() - tri.height() ) / 2, tri );
++}
++
++void BackFrame::enterEvent( QEvent *e )
++{
++ mouse_inside = true;
++ update();
++}
++
++void BackFrame::leaveEvent( QEvent *e )
++{
++ mouse_inside = false;
++ update();
++}
++
++void BackFrame::mousePressEvent ( QMouseEvent * e )
++{
++ emit clicked();
++}
++
++FlipScrollView::FlipScrollView( QWidget * parent, const char * name )
++ : QScrollView( parent, name ), mState( StoppedLeft ), mScrollDirection( 1 ), mShowBack( false )
++{
++ setVScrollBarMode( QScrollView::AlwaysOff );
++ setHScrollBarMode( QScrollView::AlwaysOff );
++ setFrameStyle( QFrame::NoFrame );
++ mLeftView = new ItemView( this, "left_view" );
++ addChild( mLeftView );
++
++ mRightView = new ItemView( this, "right_view" );
++ addChild( mRightView );
++
++ mTimer = new QTimer( this, "mTimer" );
++ connect( mTimer, SIGNAL( timeout() ), SLOT( slotScrollTimer() ) );
++
++ connect( mLeftView, SIGNAL( startService(KService::Ptr) ),
++ SIGNAL( startService(KService::Ptr) ) );
++ connect( mLeftView, SIGNAL( startURL(const QString& ) ),
++ SIGNAL( startURL(const QString& ) ) );
++ connect( mLeftView, SIGNAL( rightButtonPressed(QListViewItem*,const QPoint&,int) ),
++ SIGNAL( rightButtonPressed(QListViewItem*,const QPoint&,int) ) );
++ connect( mRightView, SIGNAL( startService(KService::Ptr) ),
++ SIGNAL( startService(KService::Ptr) ) );
++ connect( mRightView, SIGNAL( startURL(const QString& ) ),
++ SIGNAL( startURL(const QString& ) ) );
++ connect( mRightView, SIGNAL( rightButtonPressed(QListViewItem*,const QPoint&,int) ),
++ SIGNAL( rightButtonPressed(QListViewItem*,const QPoint&,int) ) );
++
++ // wild hack to make sure it has correct width
++ mLeftView->setVScrollBarMode( QScrollView::AlwaysOn );
++ mRightView->setVScrollBarMode( QScrollView::AlwaysOn );
++ mLeftView->setVScrollBarMode( QScrollView::Auto );
++ mRightView->setVScrollBarMode( QScrollView::Auto );
++
++ mBackrow = new BackFrame( this );
++ mBackrow->resize( 24, 100 );
++ connect( mBackrow, SIGNAL( clicked() ), SIGNAL( backButtonClicked() ) );
++}
++
++ItemView* FlipScrollView::prepareRightMove()
++{
++ if ( mState != StoppedLeft )
++ {
++ mTimer->stop();
++ ItemView *swap = mLeftView;
++ mLeftView = mRightView;
++ mRightView = swap;
++ moveChild( mLeftView, 0, 0 );
++ moveChild( mRightView, width(), 0 );
++ mBackrow->hide();
++ mRightView->resize( width(), height() );
++ mLeftView->resize( width(), height() );
++ setContentsPos( 0, 0 );
++ }
++
++ mState = StoppedLeft;
++ mRightView->clear();
++ return mRightView;
++}
++
++void FlipScrollView::showBackButton( bool enable )
++{
++ kdDebug() << "FlipScrollView::showBackButton " << enable << endl;
++ mShowBack = enable;
++}
++
++ItemView* FlipScrollView::prepareLeftMove(bool clear)
++{
++ if ( mState != StoppedRight )
++ {
++ mTimer->stop();
++ ItemView *swap = mLeftView;
++ mLeftView = mRightView;
++ mRightView = swap;
++ moveChild( mLeftView, 0, 0 );
++ moveChild( mRightView, width(), 0 );
++ mRightView->resize( width(), height() );
++ mLeftView->resize( width(), height() );
++ mBackrow->hide();
++ setContentsPos( width(), 0 );
++ }
++
++ mState = StoppedRight;
++ if (clear)
++ mLeftView->clear();
++ return mLeftView;
++}
++
++void FlipScrollView::viewportResizeEvent ( QResizeEvent * )
++{
++ mLeftView->resize( size() );
++ mRightView->resize( width() - mBackrow->width(), height() );
++ mBackrow->resize( mBackrow->width(), height() );
++ resizeContents( width() * 2, height() );
++ moveChild( mBackrow, width(), 0 );
++ moveChild( mRightView, width() + mBackrow->width(), 0 );
++ setContentsPos( 0, 0 );
++}
++
++ItemView *FlipScrollView::currentView() const
++{
++ if ( mState == StoppedRight )
++ return mRightView;
++ else
++ return mLeftView;
++}
++
++ItemView *FlipScrollView::leftView() const
++{
++ return mLeftView;
++}
++
++ItemView *FlipScrollView::rightView() const
++{
++ return mRightView;
++}
++
++FlipScrollView::~FlipScrollView() {}
++
++static const int max_steps = 10;
++
++void FlipScrollView::slotScrollTimer()
++{
++ mStepsRemaining--;
++ assert( mStepsRemaining >= 0 && mStepsRemaining < int(sizeof( scrollSteps ) / sizeof( double )) );
++ if (KickerSettings::scrollFlipView())
++ scrollBy( ( int )( mScrollDirection * mLeftView->width() * scrollSteps[ mStepsRemaining ] ), 0 );
++ else
++ scrollBy( ( int )( mScrollDirection * mLeftView->width()), 0 );
++
++ if ( mStepsRemaining == 0 )
++ {
++ if ( mState == ScrollingRight )
++ {
++ mState = StoppedRight;
++ setContentsPos( width(), 0 );
++ } else {
++ mState = StoppedLeft;
++ setContentsPos( 0, 0 );
++ }
++
++ kdDebug() << "slotScrollTimer " << mShowBack << endl;
++
++ if ( mShowBack )
++ {
++ mBackrow->show();
++ if ( mState == StoppedRight )
++ {
++
++ if ( QApplication::reverseLayout() )
++ moveChild( mRightView, width(), 0 );
++ else
++ moveChild( mRightView, width() + mBackrow->width(), 0 );
++ mRightView->resize( width() - mBackrow->width(), height() );
++ mLeftView->resize( width(), height() );
++ if ( QApplication::reverseLayout() )
++ moveChild( mBackrow, width() + mRightView->width(), 0 );
++ else
++ moveChild( mBackrow, width(), 0 );
++ moveChild( mLeftView, 0, 0 );
++ } else
++ {
++ moveChild( mRightView, width(), 0 );
++ mRightView->resize( width(), height() );
++ mLeftView->resize( width() - mBackrow->width(), height() );
++ if ( QApplication::reverseLayout() )
++ {
++ moveChild( mBackrow, mLeftView->width(), 0 );
++ moveChild( mLeftView, 0, 0 );
++ }
++ else
++ {
++ moveChild( mBackrow, 0, 0 );
++ moveChild( mLeftView, mBackrow->width(), 0 );
++ }
++ }
++ } else
++ mBackrow->hide();
++
++ if (!mSelectMenuPath.isEmpty()) {
++ if (mSelectMenuPath=="kicker:/goup/") {
++ currentView()->setSelected(currentView()->firstChild(),true);
++ currentView()->firstChild()->repaint();
++ }
++ else {
++ QListViewItem * child = currentView()->firstChild();
++ while( child ) {
++ KMenuItem* kitem = dynamic_cast<KMenuItem*>(child);
++ if (kitem && kitem->menuPath()==mSelectMenuPath) {
++ currentView()->setSelected(child,true);
++ kdDebug() << "child repaint\n";
++ child->repaint();
++ break;
++ }
++ child = child->nextSibling();
++ }
++ }
++ }
++ mLeftView->setVScrollBarMode( QScrollView::Auto );
++ mRightView->setVScrollBarMode( QScrollView::Auto );
++ mTimer->stop();
++ mLeftView->setMouseMoveSelects( true );
++ mRightView->setMouseMoveSelects( true );
++ }
++}
++
++void FlipScrollView::flipScroll(const QString& selectMenuPath)
++{
++ if ( mState == StoppedLeft )
++ {
++ mState = ScrollingRight;
++ mScrollDirection = 1;
++ }
++ else
++ {
++ mState = ScrollingLeft;
++ mScrollDirection = -1;
++ }
++
++ mLeftView->setVScrollBarMode( QScrollView::AlwaysOff );
++ mRightView->setVScrollBarMode( QScrollView::AlwaysOff );
++ if (KickerSettings::scrollFlipView())
++ mStepsRemaining = max_steps;
++ else
++ mStepsRemaining = 1;
++ mTimer->start( 30 );
++ mSelectMenuPath = selectMenuPath;
++ if (!mSelectMenuPath.isEmpty()) {
++ mLeftView->setMouseMoveSelects( false );
++ mRightView->setMouseMoveSelects( false );
++ }
++}
++
++#include "flipscrollview.moc"
+--- kicker/ui/query.cpp (Revision 0)
++++ kicker/ui/query.cpp (Revision 849791)
+@@ -0,0 +1,136 @@
++/*****************************************************************
++
++ Copyright (c) 2006 Stephan Binner <binner@kde.org>
++
++ 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; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++
++******************************************************************/
++
++#include "query.h"
++#include <kdebug.h>
++
++Query::Query()
++{
++ alternatives.setAutoDelete(true);
++}
++
++void Query::clear()
++{
++ query_term = QString::null;
++ alternatives.clear();
++}
++
++void Query::set(const QString &term)
++{
++ query_term = term;
++ alternatives.clear();
++
++ current_alternative = new Alternative;
++ current_part = QString::null;
++ within_quotes = false;
++ exclude_part = false;
++
++ for (uint index=0;index<term.length();index++) {
++ if (current_part.isEmpty() && query_term[index]=='-')
++ exclude_part = true;
++ else if (term[index]=='\'' || term[index]=='"') {
++ if (within_quotes)
++ add_term();
++ else
++ within_quotes = true;
++ }
++ else if (!within_quotes && query_term[index]==' ')
++ add_term();
++ else if (!exclude_part && !within_quotes && query_term[index]=='O' && index+1<term.length() && query_term[index+1]=='R') {
++ index++;
++ alternatives.append(current_alternative);
++ current_alternative = new Alternative;
++ within_quotes = false;
++ exclude_part = false;
++ current_part = QString::null;
++ }
++ else
++ current_part+=term[index];
++ }
++ add_term();
++ alternatives.append(current_alternative);
++
++#if 0
++ for (Alternative* alt=alternatives.first(); alt; alt=alternatives.next()) {
++ kdDebug() << "---" << endl;
++ kdDebug() << "*** includes = " << alt->includes << endl;
++ kdDebug() << "*** excludes = " << alt->excludes << endl;
++ }
++#endif
++}
++
++void Query::add_term() {
++ if (!current_part.isEmpty()) {
++ if (current_part.startsWith("*"))
++ current_part=current_part.mid(1);
++
++ if (current_part.endsWith("*"))
++ current_part=current_part.mid(0,current_part.length()-1);
++
++ if (exclude_part)
++ current_alternative->excludes+=current_part.lower();
++ else
++ current_alternative->includes+=current_part.lower();
++ }
++ within_quotes = false;
++ exclude_part = false;
++ current_part = QString::null;
++}
++
++QString Query::get() const
++{
++ return query_term;
++}
++
++bool Query::matches(const QString &term)
++{
++ QString lower_term = term.lower();
++
++ for (Alternative* alt=alternatives.first(); alt; alt=alternatives.next()) {
++ if (!alt->includes.count())
++ continue;
++
++ bool next_alternative = false;
++
++ for ( QStringList::ConstIterator it = alt->excludes.begin(); it != alt->excludes.end(); ++it ) {
++ if ( lower_term.find(*it)!=-1 ) {
++ next_alternative = true;
++ continue;
++ }
++ }
++ if (next_alternative)
++ continue;
++
++ for ( QStringList::ConstIterator it = alt->includes.begin(); it != alt->includes.end(); ++it ) {
++ if ( lower_term.find(*it)==-1 ) {
++ next_alternative = true;
++ continue;
++ }
++ }
++ if (next_alternative)
++ continue;
++
++//kdDebug() << "Found hit in '" << term << "'" << endl;
++ return true;
++ }
++
++ return false;
++}
+--- kicker/ui/k_new_mnu.cpp (Revision 0)
++++ kicker/ui/k_new_mnu.cpp (Revision 849791)
+@@ -0,0 +1,3779 @@
++/*****************************************************************
++
++ Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
++ Copyright (c) 2006 Debajyoti Bera <dbera.web@gmail.com>
++ Copyright (c) 2006 Dirk Mueller <mueller@kde.org>
++
++ 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; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++
++******************************************************************/
++
++#include <stdlib.h>
++#include <sys/types.h>
++#include <unistd.h>
++#include <dmctl.h>
++#include <inttypes.h>
++
++#include <qimage.h>
++#include <qpainter.h>
++#include <qstyle.h>
++#include <qwidgetstack.h>
++#include <qlayout.h>
++#include <qlabel.h>
++#include <qregexp.h>
++#include <qfile.h>
++#include <qstylesheet.h>
++#include <qaccel.h>
++#include <qcursor.h>
++#include <qdir.h>
++#include <qsimplerichtext.h>
++#include <qtooltip.h>
++#include <qtabbar.h>
++
++#include <dcopclient.h>
++#include <kapplication.h>
++#include <kaboutkde.h>
++#include <kaction.h>
++#include <kbookmarkmenu.h>
++#include <kconfig.h>
++#include <kdebug.h>
++#include <kglobal.h>
++#include <kglobalsettings.h>
++#include <kiconloader.h>
++#include <klineedit.h>
++#include <klocale.h>
++#include <kmessagebox.h>
++#include <kstandarddirs.h>
++#include <kcombobox.h>
++#include <kwin.h>
++#include <kdebug.h>
++#include <kuser.h>
++#include <kurllabel.h>
++#include <krun.h>
++#include <kmimetype.h>
++#include <krecentdocument.h>
++#include <kcompletionbox.h>
++#include <kurifilter.h>
++#include <kbookmarkmanager.h>
++#include <kbookmark.h>
++#include <kprocess.h>
++#include <kio/jobclasses.h>
++#include <kio/job.h>
++#include <dcopref.h>
++#include <konq_popupmenu.h>
++#include <konqbookmarkmanager.h>
++#include <kparts/componentfactory.h>
++
++#include "client_mnu.h"
++#include "container_base.h"
++#include "global.h"
++#include "knewbutton.h"
++#include "kicker.h"
++#include "kickerSettings.h"
++#include "konqbookmarkmanager.h"
++#include "menuinfo.h"
++#include "menumanager.h"
++#include "popupmenutitle.h"
++#include "quickbrowser_mnu.h"
++#include "recentapps.h"
++#include "flipscrollview.h"
++#include "itemview.h"
++#include <dmctl.h>
++#include <sys/vfs.h>
++#include <mykickoffsearchinterface.h>
++
++#include "media_watcher.h"
++#include "k_mnu.h"
++#include "k_new_mnu.h"
++#include "k_new_mnu.moc"
++#include "kickoff_bar.h"
++
++#define WAIT_BEFORE_QUERYING 700
++
++#define IDS_PER_CATEGORY 20
++#define ACTIONS_ID_BASE 10
++#define APP_ID_BASE 10 + IDS_PER_CATEGORY
++#define BOOKMARKS_ID_BASE 10 + (IDS_PER_CATEGORY * 2)
++#define NOTES_ID_BASE 10 + (IDS_PER_CATEGORY * 3)
++#define MAIL_ID_BASE 10 + (IDS_PER_CATEGORY * 4)
++#define FILE_ID_BASE 10 + (IDS_PER_CATEGORY * 5)
++#define MUSIC_ID_BASE 10 + (IDS_PER_CATEGORY * 6)
++#define WEBHIST_ID_BASE 10 + (IDS_PER_CATEGORY * 7)
++#define CHAT_ID_BASE 10 + (IDS_PER_CATEGORY * 8)
++#define FEED_ID_BASE 10 + (IDS_PER_CATEGORY * 9)
++#define PIC_ID_BASE 10 + (IDS_PER_CATEGORY * 10)
++#define VIDEO_ID_BASE 10 + (IDS_PER_CATEGORY * 11)
++#define DOC_ID_BASE 10 + (IDS_PER_CATEGORY * 12)
++#define OTHER_ID_BASE 10 + (IDS_PER_CATEGORY * 13)
++
++static QString calculate(const QString &exp)
++{
++ QString result, cmd;
++ const QString bc = KStandardDirs::findExe("bc");
++ if ( !bc.isEmpty() )
++ cmd = QString("echo %1 | %2").arg(KProcess::quote(exp), KProcess::quote(bc));
++ else
++ cmd = QString("echo $((%1))").arg(exp);
++ FILE *fs = popen(QFile::encodeName(cmd).data(), "r");
++ if (fs)
++ {
++ QTextStream ts(fs, IO_ReadOnly);
++ result = ts.read().stripWhiteSpace();
++ pclose(fs);
++ }
++ return result;
++}
++
++static QString workaroundStringFreeze(const QString& str)
++{
++ QString s = str;
++
++ s.replace("<u>","&");
++ QRegExp re("<[^>]+>");
++ re.setMinimal(true);
++ re.setCaseSensitive(false);
++
++ s.replace(re, "");
++ s = s.simplifyWhiteSpace();
++
++ return s;
++}
++
++int base_category_id[] = {ACTIONS_ID_BASE, APP_ID_BASE, BOOKMARKS_ID_BASE, NOTES_ID_BASE, MAIL_ID_BASE,
++ FILE_ID_BASE, MUSIC_ID_BASE, WEBHIST_ID_BASE, CHAT_ID_BASE, FEED_ID_BASE,
++ PIC_ID_BASE, VIDEO_ID_BASE, DOC_ID_BASE, OTHER_ID_BASE};
++
++#include <assert.h>
++
++static int used_size( QLabel *label, int oldsize )
++{
++ QSimpleRichText st( label->text(), KGlobalSettings::toolBarFont() );
++ st.setWidth( oldsize );
++ return QMAX( st.widthUsed(), oldsize );
++}
++
++KMenu::KMenu()
++ : KMenuBase(0, "SUSE::Kickoff::KMenu")
++ , m_sloppyTimer(0, "KNewMenu::sloppyTimer"), m_mediaFreeTimer(0, "KNewMenu::mediaFreeTimer"),
++ m_iconName(QString::null), m_orientation(UnDetermined), m_search_plugin( 0 )
++{
++ setMouseTracking(true);
++ connect(&m_sloppyTimer, SIGNAL(timeout()), SLOT(slotSloppyTimeout()));
++
++ // set the first client id to some arbitrarily large value.
++ client_id = 10000;
++ // Don't automatically clear the main menu.
++ actionCollection = new KActionCollection(this);
++
++ connect(Kicker::the(), SIGNAL(configurationChanged()),
++ this, SLOT(configChanged()));
++
++ KUser * user = new KUser();
++
++ char hostname[256];
++ hostname[0] = '\0';
++ if (!gethostname( hostname, sizeof(hostname) ))
++ hostname[sizeof(hostname)-1] = '\0';
++
++ m_userInfo->setText( i18n( "User&nbsp;<b>%1</b>&nbsp;on&nbsp;<b>%2</b>" )
++ .arg( user->loginName() ).arg( hostname ) );
++ setupUi();
++
++ m_userInfo->setBackgroundMode( PaletteBase );
++ QColor userInfoColor = QApplication::palette().color( QPalette::Normal, QColorGroup::Mid );
++ if ( qGray( userInfoColor.rgb() ) > 120 )
++ userInfoColor = userInfoColor.dark( 200 );
++ else
++ userInfoColor = userInfoColor.light( 200 );
++ m_userInfo->setPaletteForegroundColor( userInfoColor );
++
++ m_tabBar = new KickoffTabBar(this, "m_tabBar");
++ connect(m_tabBar, SIGNAL(tabClicked(QTab*)), SLOT(tabClicked(QTab*)));
++
++ const int tab_icon_size = 32;
++
++ m_tabs[FavoriteTab] = new QTab;
++ m_tabBar->addTab(m_tabs[FavoriteTab]);
++ m_tabBar->setToolTip(FavoriteTab, "<qt>" + i18n( "Most commonly used applications and documents" ) + "</qt>" );
++ m_tabs[ApplicationsTab] = new QTab;
++ m_tabBar->addTab(m_tabs[ApplicationsTab]);
++ m_tabBar->setToolTip(ApplicationsTab, "<qt>" + i18n( "List of installed applications" ) +
++ "</qt>" );
++
++ m_tabs[ComputerTab] = new QTab;
++ m_tabBar->addTab(m_tabs[ComputerTab]);
++ m_tabBar->setToolTip(ComputerTab, "<qt>" + i18n( "Information and configuration of your "
++ "system, access to personal files, network resources and connected disk drives")
++ + "</qt>");
++#if 0
++ m_tabs[SearchTab] = new QTab;
++ m_tabBar->addTab(m_tabs[SearchTab]);
++#endif
++ m_tabs[HistoryTab] = new QTab;
++ m_tabBar->addTab(m_tabs[HistoryTab]);
++ m_tabBar->setToolTip(HistoryTab, "<qt>" + i18n( "Recently used applications and documents" ) +
++ "</qt>" );
++ m_tabs[LeaveTab] = new QTab;
++ m_tabBar->addTab(m_tabs[LeaveTab]);
++ m_tabBar->setToolTip(LeaveTab, i18n("<qt>Logout, switch user, switch off or reset,"
++ " suspend of the system" ) + "</qt>" );
++
++ if (KickerSettings::kickoffTabBarFormat() != KickerSettings::IconOnly) {
++ m_tabs[FavoriteTab]->setText(workaroundStringFreeze(i18n("<p align=\"center\"> <u>F</u>avorites</p>")));
++ m_tabs[HistoryTab]->setText(workaroundStringFreeze(i18n("<p align=\"center\"><u>H</u>istory</p>")));
++ m_tabs[ComputerTab]->setText(
++ workaroundStringFreeze(i18n("<p align=\"center\"> <u>C</u>omputer</p>")));
++ m_tabs[ApplicationsTab]->setText(workaroundStringFreeze(i18n("<p align=\"center\"><u>A</u>pplications</p>")));
++ m_tabs[LeaveTab]->setText(
++ workaroundStringFreeze(i18n("<p align=\"center\"><u>L</u>eave</p>")));
++ }
++
++ if (KickerSettings::kickoffTabBarFormat() != KickerSettings::LabelOnly) {
++ m_tabs[FavoriteTab]->setIconSet(BarIcon("bookmark", tab_icon_size));
++ m_tabs[HistoryTab]->setIconSet(BarIcon("recently_used", tab_icon_size));
++ m_tabs[ComputerTab]->setIconSet(BarIcon("system", tab_icon_size));
++ m_tabs[ApplicationsTab]->setIconSet(BarIcon("player_playlist", tab_icon_size));
++ m_tabs[LeaveTab]->setIconSet(BarIcon("leave", tab_icon_size));
++ }
++
++ connect(m_tabBar, SIGNAL(selected(int)), m_stacker, SLOT(raiseWidget(int)));
++ connect(m_stacker, SIGNAL(aboutToShow(int)), m_tabBar, SLOT(setCurrentTab(int)));
++
++ m_favoriteView = new FavoritesItemView (m_stacker, "m_favoriteView");
++ m_favoriteView->setAcceptDrops(true);
++ m_favoriteView->setItemsMovable(true);
++ m_stacker->addWidget(m_favoriteView, FavoriteTab);
++
++ m_recentlyView = new ItemView (m_stacker, "m_recentlyView");
++ m_stacker->addWidget(m_recentlyView, HistoryTab);
++
++ m_systemView = new ItemView(m_stacker, "m_systemView");
++ m_stacker->addWidget(m_systemView, ComputerTab );
++
++ m_browserView = new FlipScrollView(m_stacker, "m_browserView");
++ m_stacker->addWidget(m_browserView, ApplicationsTab);
++ connect( m_browserView, SIGNAL( backButtonClicked() ), SLOT( slotGoBack() ) );
++
++ m_exitView = new FlipScrollView(m_stacker, "m_exitView");
++ m_stacker->addWidget(m_exitView, LeaveTab);
++ connect( m_exitView, SIGNAL( backButtonClicked() ), SLOT( slotGoExitMainMenu() ) );
++
++ m_searchWidget = new QVBox (m_stacker, "m_searchWidget");
++ m_searchWidget->setSpacing(0);
++ m_stacker->addWidget(m_searchWidget, 5);
++
++ // search provider icon
++ QPixmap icon;
++ KURIFilterData data;
++ QStringList list;
++ data.setData( QString("some keyword") );
++ list << "kurisearchfilter" << "kuriikwsfilter";
++
++ if ( KURIFilter::self()->filterURI(data, list) ) {
++ QString iconPath = locate("cache", KMimeType::favIconForURL(data.uri()) + ".png");
++ if ( iconPath.isEmpty() )
++ icon = SmallIcon("enhanced_browsing");
++ else
++ icon = QPixmap( iconPath );
++ }
++ else
++ icon = SmallIcon("enhanced_browsing");
++
++ m_searchResultsWidget = new ItemView (m_searchWidget, "m_searchResultsWidget");
++ m_searchResultsWidget->setItemMargin(4);
++ m_searchResultsWidget->setIconSize(16);
++ m_searchActions = new ItemView (m_searchWidget, "m_searchActions");
++ m_searchActions->setFocusPolicy(QWidget::NoFocus);
++ m_searchActions->setItemMargin(4);
++ m_searchInternet = new QListViewItem(m_searchActions, i18n("Search Internet"));
++ m_searchInternet->setPixmap(0,icon);
++ setTabOrder(m_kcommand, m_searchResultsWidget);
++
++ m_kerryInstalled = !KStandardDirs::findExe(QString::fromLatin1("kerry")).isEmpty();
++ m_isShowing = false;
++
++ if (!m_kerryInstalled) {
++ m_searchIndex = 0;
++ m_searchActions->setMaximumHeight(5+m_searchInternet->height());
++ }
++ else {
++ m_searchIndex = new QListViewItem(m_searchActions, i18n("Search Index"));
++ m_searchIndex->setPixmap(0,SmallIcon("kerry"));
++ m_searchActions->setMaximumHeight(5+m_searchIndex->height()*2);
++ }
++ connect(m_searchActions, SIGNAL(clicked(QListViewItem*)), SLOT(searchActionClicked(QListViewItem*)));
++ connect(m_searchActions, SIGNAL(returnPressed(QListViewItem*)), SLOT(searchActionClicked(QListViewItem*)));
++ connect(m_searchActions, SIGNAL(spacePressed(QListViewItem*)), SLOT(searchActionClicked(QListViewItem*)));
++
++ connect(m_searchResultsWidget, SIGNAL(startService(KService::Ptr)), SLOT(slotStartService(KService::Ptr)));
++ connect(m_searchResultsWidget, SIGNAL(startURL(const QString&)), SLOT(slotStartURL(const QString&)));
++ connect(m_searchResultsWidget, SIGNAL(rightButtonPressed( QListViewItem*, const QPoint &, int )), SLOT(slotContextMenuRequested( QListViewItem*, const QPoint &, int )));
++
++ connect(m_recentlyView, SIGNAL(startService(KService::Ptr)), SLOT(slotStartService(KService::Ptr)));
++ connect(m_recentlyView, SIGNAL(startURL(const QString&)), SLOT(slotStartURL(const QString&)));
++ connect(m_recentlyView, SIGNAL(rightButtonPressed( QListViewItem*, const QPoint &, int )), SLOT(slotContextMenuRequested( QListViewItem*, const QPoint &, int )));
++
++ connect(m_favoriteView, SIGNAL(startService(KService::Ptr)), SLOT(slotStartService(KService::Ptr)));
++ connect(m_favoriteView, SIGNAL(startURL(const QString&)), SLOT(slotStartURL(const QString&)));
++ connect(m_favoriteView, SIGNAL(rightButtonPressed( QListViewItem*, const QPoint &, int )), SLOT(slotContextMenuRequested( QListViewItem*, const QPoint &, int )));
++ connect(m_favoriteView, SIGNAL(moved(QListViewItem*, QListViewItem*, QListViewItem*)), SLOT(slotFavoritesMoved( QListViewItem*, QListViewItem*, QListViewItem* )));
++
++ connect(m_systemView, SIGNAL(startURL(const QString&)), SLOT(slotStartURL(const QString&)));
++ connect(m_systemView, SIGNAL(startService(KService::Ptr)), SLOT(slotStartService(KService::Ptr)));
++ connect(m_systemView, SIGNAL(rightButtonPressed( QListViewItem*, const QPoint &, int )), SLOT(slotContextMenuRequested( QListViewItem*, const QPoint &, int )));
++
++ connect(m_browserView, SIGNAL(startURL(const QString&)), SLOT(slotGoSubMenu(const QString&)));
++ connect(m_browserView, SIGNAL(startService(KService::Ptr)), SLOT(slotStartService(KService::Ptr)));
++ connect(m_browserView, SIGNAL(rightButtonPressed( QListViewItem*, const QPoint &, int )), SLOT(slotContextMenuRequested( QListViewItem*, const QPoint &, int )));
++
++ connect(m_exitView, SIGNAL(startURL(const QString&)), SLOT(slotStartURL(const QString&)));
++ connect(m_exitView, SIGNAL(rightButtonPressed( QListViewItem*, const QPoint &, int )), SLOT(slotContextMenuRequested( QListViewItem*, const QPoint &, int )));
++
++ m_kcommand->setDuplicatesEnabled( false );
++ m_kcommand->setLineEdit(new KLineEdit(m_kcommand, "m_kcommand-lineedit"));
++ m_kcommand->setCompletionMode( KGlobalSettings::CompletionAuto );
++ connect(m_kcommand, SIGNAL(cleared()), SLOT(clearedHistory()));
++ connect(m_kcommand->lineEdit(), SIGNAL(returnPressed()), SLOT(searchAccept()));
++ connect(m_kcommand->lineEdit(), SIGNAL(textChanged(const QString &)), SLOT(searchChanged(const QString &)));
++
++ // URI Filter meta object...
++ m_filterData = new KURIFilterData();
++
++ max_category_id = new int [num_categories];
++ categorised_hit_total = new int [num_categories];
++
++ input_timer = new QTimer (this, "input_timer");
++ connect( input_timer, SIGNAL(timeout()), this, SLOT(doQuery()) );
++
++ init_search_timer = new QTimer (this, "init_search_timer");
++ connect( init_search_timer, SIGNAL(timeout()), this, SLOT(initSearch()) );
++ init_search_timer->start(2000, true);
++
++ connect( m_favoriteView, SIGNAL( dropped (QDropEvent *, QListViewItem * ) ),
++ SLOT( slotFavDropped( QDropEvent *, QListViewItem * ) ) );
++
++ this->installEventFilter(this);
++ m_tabBar->installEventFilter(this);
++ m_favoriteView->installEventFilter(this);
++ m_recentlyView->installEventFilter(this);
++ m_browserView->leftView()->installEventFilter(this);
++ m_browserView->rightView()->installEventFilter(this);
++ m_systemView->installEventFilter(this);
++ m_exitView->leftView()->installEventFilter(this);
++ m_exitView->rightView()->installEventFilter(this);
++ m_kcommand->lineEdit()->installEventFilter(this);
++ m_searchLabel->installEventFilter(this);
++ m_searchPixmap->installEventFilter(this);
++ m_stacker->installEventFilter(this);
++
++ emailRegExp = QRegExp("^([\\w\\-]+\\.)*[\\w\\-]+@([\\w\\-]+\\.)*[\\w\\-]+$");
++ authRegExp = QRegExp("^[a-zA-Z]+://\\w+(:\\w+)?@([\\w\\-]+\\.)*[\\w\\-]+(:\\d+)?(/.*)?$");
++ uriRegExp = QRegExp("^[a-zA-Z]+://([\\w\\-]+\\.)*[\\w\\-]+(:\\d+)?(/.*)?$");
++ uri2RegExp = QRegExp("^([\\w\\-]+\\.)+[\\w\\-]+(:\\d+)?(/.*)?$");
++
++ m_resizeHandle = new QLabel(this);
++ m_resizeHandle->setBackgroundOrigin( QLabel::ParentOrigin );
++ m_resizeHandle->setScaledContents(true);
++ m_resizeHandle->setFixedSize( 16, 16 );
++ m_searchFrame->stackUnder( m_resizeHandle );
++ m_isresizing = false;
++
++ m_searchPixmap->setPixmap( BarIcon( "find", 32 ) );
++
++ QFont f = font();
++ f.setPointSize( kMax( 7, (f.pointSize() * 4 / 5 ) + KickerSettings::kickoffFontPointSizeOffset() ) );
++ m_tabBar->setFont ( f );
++ f.setPointSize( kMax( 7, (f.pointSize() * 3 / 2 ) + KickerSettings::kickoffFontPointSizeOffset() ) );
++ m_searchLabel->setFont( f );
++
++ static_cast<KLineEdit*>(m_kcommand->lineEdit())->setClickMessage(i18n( "Applications, Contacts and Documents" ) );
++
++ bookmarkManager = 0;
++ m_addressBook = 0;
++ m_popupMenu = 0;
++
++ main_border_tl.load( locate("data", "kicker/pics/main_corner_tl.png" ) );
++ main_border_tr.load( locate("data", "kicker/pics/main_corner_tr.png" ) );
++
++ search_tab_left.load( locate("data", "kicker/pics/search-tab-left.png" ) );
++ search_tab_right.load( locate("data", "kicker/pics/search-tab-right.png" ) );
++ search_tab_center.load( locate("data", "kicker/pics/search-tab-center.png" ) );
++
++ search_tab_top_left.load( locate("data", "kicker/pics/search-tab-top-left.png" ) );
++ search_tab_top_right.load( locate("data", "kicker/pics/search-tab-top-right.png" ) );
++ search_tab_top_center.load( locate("data", "kicker/pics/search-tab-top-center.png" ) );
++}
++
++void KMenu::setupUi()
++{
++ m_stacker = new QWidgetStack( this, "m_stacker" );
++ m_stacker->setGeometry( QRect( 90, 260, 320, 220 ) );
++ m_stacker->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)3, (QSizePolicy::SizeType)3, 1, 1, m_stacker->sizePolicy().hasHeightForWidth() ) );
++ m_stacker->setPaletteBackgroundColor( QColor( 255, 255, 255 ) );
++ // m_stacker->setFocusPolicy( QWidget::StrongFocus );
++ m_stacker->setLineWidth( 0 );
++ m_stacker->setFocusPolicy(QWidget::NoFocus);
++ connect(m_stacker, SIGNAL(aboutToShow(QWidget*)), SLOT(stackWidgetRaised(QWidget*)));
++
++ m_kcommand->setName("m_kcommand");
++}
++
++KMenu::~KMenu()
++{
++ saveConfig();
++
++ clearSubmenus();
++ delete m_filterData;
++}
++
++bool KMenu::eventFilter ( QObject * receiver, QEvent* e)
++{
++//kdDebug() << "eventFilter receiver=" << receiver->name() << " type=" << e->type() << endl;
++ QWidget* raiseWidget = 0;
++ QRect raiseRect;
++
++ if (e->type() == QEvent::KeyPress ||
++ e->type() == QEvent::MouseButtonPress ||
++ e->type() == QEvent::MouseMove
++ || e->type() == QEvent::FocusIn
++ || e->type() == QEvent::Wheel) {
++ QPoint p;
++
++ if (e->type() == QEvent::MouseMove || e->type() == QEvent::MouseButtonPress) {
++ QMouseEvent* me = static_cast<QMouseEvent*>(e);
++ p = me->globalPos();
++ }
++ else if (e->type() == QEvent::Wheel) {
++ QWheelEvent* we = static_cast<QWheelEvent*>(e);
++ p = we->globalPos();
++ }
++
++ while (receiver) {
++ if (receiver == m_tabBar && (e->type()!=QEvent::MouseMove || KickerSettings::kickoffSwitchTabsOnHover() ) ) {
++ QTab* s = m_tabBar->selectTab(m_tabBar->mapFromGlobal(p));
++ if (s && s->identifier() == ApplicationsTab)
++ raiseWidget = m_browserView;
++ if (s && s->identifier() == FavoriteTab)
++ raiseWidget = m_favoriteView;
++ if (s && s->identifier() == HistoryTab)
++ raiseWidget = m_recentlyView;
++ if (s && s->identifier() == ComputerTab)
++ raiseWidget = m_systemView;
++ if (s && s->identifier() == LeaveTab)
++ raiseWidget = m_exitView;
++
++ if (raiseWidget)
++ raiseRect = QRect( m_tabBar->mapToGlobal(s->rect().topLeft()),
++ s->rect().size());
++ }
++
++ /* we do not want hover activation for the search line edit as this can be
++ * pretty disturbing */
++ if ( (receiver == m_searchPixmap ||
++ ( ( receiver == m_searchLabel || receiver==m_kcommand->lineEdit() ) &&
++ ( e->type() == QEvent::KeyPress || e->type() == QEvent::Wheel
++ || e->type() == QEvent::MouseButtonPress ) ) ) &&
++ !m_isShowing) {
++ raiseWidget = m_searchWidget;
++ raiseRect = QRect( m_searchFrame->mapToGlobal(m_searchFrame->rect().topLeft()),
++ m_searchFrame->size());
++ }
++
++ if(raiseWidget)
++ break;
++ if(receiver->isWidgetType())
++ receiver = static_cast<QWidget*>(receiver)->parentWidget(true);
++ else
++ break;
++ }
++
++ if (e->type() == QEvent::FocusIn && receiver && raiseWidget) {
++ m_searchResultsWidget->setFocusPolicy(QWidget::StrongFocus);
++ m_searchActions->setFocusPolicy(raiseWidget == m_searchWidget ?
++ QWidget::StrongFocus : QWidget::NoFocus);
++ setTabOrder(raiseWidget, m_searchResultsWidget);
++ if (raiseWidget != m_stacker->visibleWidget()
++ && static_cast<QWidget*>(receiver)->focusPolicy() == QWidget::NoFocus
++ && m_stacker->id(raiseWidget) >= 0) {
++
++ m_stacker->raiseWidget(raiseWidget);
++ return true;
++ }
++
++ if (raiseWidget->focusPolicy() != QWidget::NoFocus)
++ return false;
++ }
++
++ if (m_sloppyRegion.contains(p)) {
++ if (e->type() == QEvent::MouseButtonPress /*&& m_sloppyTimer.isActive()*/)
++ m_sloppySourceClicked = true;
++
++ if (!m_sloppyTimer.isActive() || m_sloppySource != raiseRect) {
++ int timeout= style().styleHint(QStyle::SH_PopupMenu_SubMenuPopupDelay);
++ if (m_sloppySourceClicked)
++ timeout = 3000;
++ m_sloppyTimer.start(timeout);
++ }
++
++ m_sloppyWidget = raiseWidget;
++ m_sloppySource = raiseRect;
++ return false;
++ }
++ }
++
++ if(e->type() == QEvent::Enter && receiver->isWidgetType()) {
++ static_cast<QWidget*>(receiver)->setMouseTracking(true);
++ QToolTip::hide();
++ }
++
++ if ( ( e->type() == QEvent::DragEnter || e->type() == QEvent::DragMove ) &&
++ raiseWidget == m_favoriteView )
++ {
++ m_stacker->raiseWidget(m_favoriteView);
++
++ return false;
++ }
++
++ // This is a nightmare of a hack, look away. Logic needs
++ // to be moved to the stacker and all widgets in the stacker
++ // must have focusNextPrevChild() overwritten to do nothing
++ if (e->type() == QEvent::KeyPress && !raiseRect.isNull()) {
++ ItemView* view;
++ if (m_browserView==m_stacker->visibleWidget())
++ view = m_browserView->currentView();
++ else if (m_exitView==m_stacker->visibleWidget())
++ view = m_exitView->currentView();
++ else
++ view = dynamic_cast<ItemView*>(m_stacker->visibleWidget());
++
++ if (view)
++ {
++ bool handled = true;
++ switch (static_cast<QKeyEvent*>(e)->key()) {
++ case Key_Up:
++ if (view->selectedItem()) {
++ view->setSelected(view->selectedItem()->itemAbove(),true);
++ }
++ else {
++ view->setSelected(view->lastItem(),true);
++ }
++ break;
++ case Key_Down:
++ if (view->selectedItem()) {
++ view->setSelected(view->selectedItem()->itemBelow(),true);
++ }
++ else {
++ if (view->firstChild() && view->firstChild()->isSelectable())
++ view->setSelected(view->firstChild(),true);
++ else if (view->childCount()>2)
++ view->setSelected(view->firstChild()->itemBelow(),true);
++ }
++ break;
++ case Key_Right:
++ if (view->selectedItem() && !static_cast<KMenuItem*>(view->selectedItem())->hasChildren())
++ break;
++ // nobreak
++ case Key_Enter:
++ case Key_Return:
++ if (view->selectedItem())
++ view->slotItemClicked(view->selectedItem());
++
++ break;
++ case Key_Left:
++ if (m_browserView == m_stacker->visibleWidget() || m_exitView == m_stacker->visibleWidget()) {
++ FlipScrollView* flip = dynamic_cast<FlipScrollView*>(m_stacker->visibleWidget());
++ if (flip->showsBackButton()) {
++ if (m_browserView == m_stacker->visibleWidget())
++ goSubMenu( m_browserView->currentView()->backPath(), true );
++ else
++ view->slotItemClicked(view->firstChild());
++ }
++ break;
++ }
++ // nobreak
++ case Key_Backspace:
++ if (m_browserView == m_stacker->visibleWidget() || m_exitView == m_stacker->visibleWidget()) {
++ FlipScrollView* flip = dynamic_cast<FlipScrollView*>(m_stacker->visibleWidget());
++ if (flip->showsBackButton()) {
++ if (m_browserView == m_stacker->visibleWidget())
++ goSubMenu( m_browserView->currentView()->backPath(), true );
++ else
++ view->slotItemClicked(view->firstChild());
++ }
++ }
++
++ break;
++ default:
++ handled = false;
++ }
++
++ if (handled)
++ view->ensureItemVisible(view->selectedItem());
++
++ return handled;
++ }
++ }
++
++ bool r = KMenuBase::eventFilter(receiver, e);
++
++ if (!r && raiseWidget)
++ m_stacker->raiseWidget(raiseWidget);
++
++ if (e->type() == QEvent::Wheel && raiseWidget )
++ {
++ // due to an ugly Qt bug we have to kill wheel events
++ // that cause focus switches
++ r = true;
++ }
++
++ if (e->type() == QEvent::Enter && receiver == m_stacker)
++ {
++ QRect r(m_stacker->mapToGlobal(QPoint(-8,-32)), m_stacker->size());
++ r.setSize(r.size()+QSize(16,128));
++
++ m_sloppyRegion = QRegion(r);
++ }
++
++ // redo the sloppy region
++ if (e->type() == QEvent::MouseMove && !r && raiseWidget)
++ {
++ QPointArray points(4);
++
++ // hmm, eventually this should be mouse position + 10px, not
++ // just worst case. but worst case seems to work fine enough.
++ QPoint edge(raiseRect.topLeft());
++ edge.setX(edge.x()+raiseRect.center().x());
++
++ if (m_orientation == BottomUp)
++ {
++ points.setPoint(0, m_stacker->mapToGlobal(m_stacker->rect().bottomLeft()));
++ points.setPoint(1, m_stacker->mapToGlobal(m_stacker->rect().bottomRight()));
++
++ edge.setY(edge.y()+raiseRect.height());
++ points.setPoint(2, edge+QPoint(+raiseRect.width()/4,0));
++ points.setPoint(3, edge+QPoint(-raiseRect.width()/4,0));
++ }
++ else
++ {
++ points.setPoint(0, m_stacker->mapToGlobal(m_stacker->rect().topLeft()));
++ points.setPoint(1, m_stacker->mapToGlobal(m_stacker->rect().topRight()));
++ points.setPoint(2, edge+QPoint(-raiseRect.width()/4,0));
++ points.setPoint(3, edge+QPoint(+raiseRect.width()/4,0));
++ }
++
++ m_sloppyRegion = QRegion(points);
++ }
++
++ return r;
++}
++
++void KMenu::slotSloppyTimeout()
++{
++ if (m_sloppyRegion.contains(QCursor::pos()) && !m_sloppySource.isNull())
++ {
++ if ( m_sloppySource.contains(QCursor::pos()))
++ {
++ m_stacker->raiseWidget(m_sloppyWidget);
++
++ m_sloppyWidget = 0;
++ m_sloppySource = QRect();
++ m_sloppyRegion = QRegion();
++ m_sloppySourceClicked = false;
++ }
++ }
++ m_sloppyTimer.stop();
++}
++
++void KMenu::paintSearchTab( bool active )
++{
++ QPixmap canvas( m_searchFrame->size() );
++ QPainter p( &canvas );
++
++ QPixmap pix;
++
++ if ( m_orientation == BottomUp )
++ pix.load( locate("data", "kicker/pics/search-gradient.png" ) );
++ else
++ pix.load( locate("data", "kicker/pics/search-gradient-topdown.png" ) );
++
++ pix.convertFromImage( pix.convertToImage().scale(pix.width(), m_searchFrame->height()));
++ p.drawTiledPixmap( 0, 0, m_searchFrame->width(), m_searchFrame->height(), pix );
++
++ if ( active ) {
++
++ m_tabBar->deactivateTabs(true);
++
++ p.setBrush( Qt::white );
++ p.setPen( Qt::NoPen );
++
++ if ( m_orientation == BottomUp ) {
++ search_tab_center.convertFromImage( search_tab_center.convertToImage().scale(search_tab_center.width(), m_searchFrame->height()));
++ p.drawTiledPixmap( search_tab_left.width(), 0, m_searchFrame->width()-search_tab_left.width()-search_tab_right.width(), m_searchFrame->height(), search_tab_center );
++
++ search_tab_left.convertFromImage( search_tab_left.convertToImage().scale(search_tab_left.width(), m_searchFrame->height()));
++ p.drawPixmap( 0, 0, search_tab_left );
++
++ search_tab_right.convertFromImage( search_tab_right.convertToImage().scale(search_tab_right.width(), m_searchFrame->height()));
++ p.drawPixmap( m_searchFrame->width()-search_tab_right.width(), 0, search_tab_right );
++ }
++ else {
++ search_tab_top_center.convertFromImage( search_tab_top_center.convertToImage().scale(search_tab_top_center.width(), m_searchFrame->height()));
++ p.drawTiledPixmap( search_tab_top_left.width(), 0, m_searchFrame->width()-search_tab_top_left.width()-search_tab_top_right.width(), m_searchFrame->height(), search_tab_top_center );
++
++ search_tab_top_left.convertFromImage( search_tab_top_left.convertToImage().scale(search_tab_top_left.width(), m_searchFrame->height()));
++ p.drawPixmap( 0, 0, search_tab_top_left );
++
++ search_tab_top_right.convertFromImage( search_tab_top_right.convertToImage().scale(search_tab_top_right.width(), m_searchFrame->height()));
++ p.drawPixmap( m_searchFrame->width()-search_tab_top_right.width(), 0, search_tab_top_right );
++ }
++ }
++ else
++ m_tabBar->deactivateTabs(false);
++
++ p.end();
++ m_searchFrame->setPaletteBackgroundPixmap( canvas );
++}
++
++void KMenu::stackWidgetRaised(QWidget* raiseWidget)
++{
++ paintSearchTab(raiseWidget == m_searchWidget);
++
++ if (raiseWidget == m_browserView) {
++ if ( m_tabBar->currentTab() == ApplicationsTab)
++ slotGoSubMenu(QString::null);
++ if (m_browserDirty ) {
++ createNewProgramList();
++ m_browserView->prepareRightMove();
++ m_browserView->currentView()->clear();
++ fillSubMenu(QString::null, m_browserView->currentView());
++ m_browserDirty = false;
++ }
++ }
++ else if (raiseWidget == m_recentlyView) {
++ if (m_recentDirty)
++ updateRecent();
++ }
++ else if (raiseWidget == m_exitView) {
++ if (m_tabBar->currentTab() == LeaveTab)
++ slotGoExitMainMenu();
++ }
++
++
++#warning Qtab fixme
++#if 0
++ else if (raiseWidget == m_systemView)
++ frame = m_system;
++ else if (raiseWidget == m_favoriteView)
++ frame = m_btnFavorites;
++ if (!frame)
++ return;
++
++ if ( m_activeTab == frame )
++ return;
++
++ paintTab( m_activeTab, false );
++ paintTab( frame, true );
++
++ // if (dynamic_cast<QScrollView*>(raiseWidget))
++ // m_activeTab->setFocusProxy(static_cast<QScrollView*>(raiseWidget)->viewport());
++
++ if (0 && /*raiseWidget == m_stacker->visibleWidget() &&*/ !raiseWidget->hasFocus()) {
++
++ if (dynamic_cast<QScrollView*>(raiseWidget))
++ static_cast<QScrollView*>(raiseWidget)->viewport()->setFocus();
++ else
++ raiseWidget->setFocus();
++ }
++
++ m_activeTab = frame;
++
++ m_sloppyRegion = QRegion();
++ m_sloppyTimer.stop();
++
++ ItemView* view;
++ if (raiseWidget == m_browserView)
++ view = m_browserView->currentView();
++ else if (raiseWidget == m_exitView)
++ view = m_exitView->currentView();
++ else
++ view = dynamic_cast<ItemView*>(m_stacker->visibleWidget());
++ if (view && !view->selectedItem()) {
++ if (view->firstChild() && view->firstChild()->isSelectable()) {
++ view->setSelected(view->firstChild(),true);
++ }
++ else if (view->childCount()>1) {
++ view->setSelected(view->firstChild()->itemBelow(),true);
++ }
++ }
++#endif
++}
++
++void KMenu::paletteChanged()
++{
++}
++
++void KMenu::tabClicked(QTab* t)
++{
++ if (t==m_tabs[ApplicationsTab])
++ slotGoSubMenu(QString::null);
++ else if (t==m_tabs[LeaveTab])
++ slotGoExitMainMenu();
++}
++
++void KMenu::slotGoBack()
++{
++ goSubMenu( m_browserView->currentView()->backPath() );
++}
++
++void KMenu::slotGoExitMainMenu()
++{
++ if (m_exitView->currentView()==m_exitView->rightView()) {
++ m_exitView->prepareLeftMove(false);
++ m_exitView->showBackButton(false);
++ m_exitView->flipScroll(QString::null);
++ }
++}
++
++void KMenu::slotGoExitSubMenu(const QString& url)
++{
++ m_exitView->prepareRightMove();
++ m_exitView->showBackButton(true);
++
++ int nId = serviceMenuEndId() + 1;
++ int index = 1;
++
++ if (url=="kicker:/restart/") {
++ QStringList rebootOptions;
++ int def, cur;
++ if ( DM().bootOptions( rebootOptions, def, cur ) )
++ {
++ if ( cur == -1 )
++ cur = def;
++
++ int boot_index = 0;
++ QStringList::ConstIterator it = rebootOptions.begin();
++ for (; it != rebootOptions.end(); ++it, ++boot_index)
++ {
++
++ QString option = i18n( "Start '%1'" ).arg( *it );
++ if (boot_index == cur)
++ option = i18n("Start '%1' (current)").arg( *it );
++ m_exitView->rightView()->insertItem( "reload", option,
++ i18n( "Restart and boot directly into '%1'").arg( *it ),
++ QString( "kicker:/restart_%1" ).arg( boot_index ), nId++, index++ );
++ }
++ m_exitView->rightView()->insertHeader( nId++, "kicker:/restart/" );
++ }
++ }
++ else /*if (url=="kicker:/switchuser/") */{
++ m_exitView->rightView()->insertItem( "switchuser", i18n( "Start New Session" ),
++ i18n( "Start a parallel session" ), "kicker:/switchuser", nId++, index++ );
++
++ m_exitView->rightView()->insertItem( "lock", i18n( "Lock Current && Start New Session").replace("&&","&"),
++ i18n( "Lock screen and start a parallel session" ), "kicker:/switchuserafterlock", nId++, index++ );
++
++ SessList sess;
++ if (DM().localSessions( sess )) {
++ if (sess.count()>1)
++ m_exitView->rightView()->insertSeparator( nId++, QString::null, index++ );
++ for (SessList::ConstIterator it = sess.begin(); it != sess.end(); ++it) {
++ if ((*it).vt && !(*it).self) {
++ QString user, loc;
++ DM().sess2Str2( *it, user, loc );
++ QStringList list = QStringList::split(":", user);
++ m_exitView->rightView()->insertItem( "switchuser", i18n( "Switch to Session of User '%1'").arg(list[0]),
++ i18n("Session: %1").arg(list[1].mid(1)+", "+loc) , QString("kicker:/switchuser_%1").arg((*it).vt), nId++, index++ );
++ }
++ }
++ }
++
++ m_exitView->rightView()->insertHeader( nId++, "kicker:/switchuser/" );
++ }
++ m_exitView->flipScroll(QString::null);
++}
++
++void KMenu::slotGoSubMenu(const QString& relPath)
++{
++ goSubMenu(relPath);
++}
++
++void KMenu::goSubMenu(const QString& relPath, bool keyboard)
++{
++ if ( relPath.startsWith( "kicker:/goup/" ) )
++ {
++ QString rel = relPath.mid( strlen( "kicker:/goup/" ) );
++ int index = rel.length() - 1;
++ if ( rel.endsWith( "/" ) )
++ index--;
++ index = rel.findRev( '/', index );
++ kdDebug() << "goup, rel '" << rel << "' " << index << endl;
++ QString currel = rel;
++ rel = rel.left( index + 1 );
++ if ( rel == "/" )
++ rel = QString::null;
++
++ kdDebug() << "goup, rel '" << rel << "' " << rel.isEmpty() << endl;
++ fillSubMenu( rel, m_browserView->prepareLeftMove() );
++ m_browserView->flipScroll(keyboard ? currel : QString::null);
++ return;
++ } else if (relPath.isEmpty())
++ {
++ if (m_browserView->currentView()->path.isEmpty())
++ return;
++ fillSubMenu( relPath, m_browserView->prepareLeftMove() );
++ } else if ( relPath.startsWith( "kicker:/new/" ) )
++ {
++ ItemView* view = m_browserView->prepareRightMove();
++ m_browserView->showBackButton( true );
++
++ int nId = serviceMenuEndId() + 1;
++ view->insertHeader( nId++, "new/" );
++ int index = 2;
++ for (QStringList::ConstIterator it = m_newInstalledPrograms.begin();
++ it != m_newInstalledPrograms.end(); ++it) {
++ KService::Ptr p = KService::serviceByStorageId((*it));
++ view->insertMenuItem(p, nId++, index++);
++ }
++ } else
++ {
++ //m_browserView->clear();
++ fillSubMenu(relPath, m_browserView->prepareRightMove());
++ }
++ m_browserView->flipScroll(keyboard ? "kicker:/goup/": QString::null);
++}
++
++void KMenu::fillSubMenu(const QString& relPath, ItemView *view)
++{
++ kdDebug() << "fillSubMenu() " << relPath << endl;
++ KServiceGroup::Ptr root = KServiceGroup::group(relPath);
++ Q_ASSERT( root );
++
++ KServiceGroup::List list = root->entries(true, true, true, KickerSettings::
++ menuEntryFormat() == KickerSettings::DescriptionAndName || KickerSettings::menuEntryFormat()
++ == KickerSettings::DescriptionOnly);
++
++ int nId = serviceMenuStartId();
++ m_browserView->showBackButton( !relPath.isEmpty() );
++ if ( !relPath.isEmpty() )
++ {
++ view->insertHeader( nId++, relPath );
++ }
++ else if ( m_newInstalledPrograms.count() ) {
++ KMenuItem *item = view->insertItem( "clock", i18n( "New Applications" ),
++ QString::null, "kicker:/new/", nId++, -1 );
++ item->setHasChildren( true );
++ view->insertSeparator( nId++, QString::null, -1 );
++ }
++
++ view->path = relPath;
++
++ fillMenu (root, list, relPath, view, nId);
++}
++
++void KMenu::fillMenu(KServiceGroup::Ptr&
++#ifdef KDELIBS_SUSE
++ _root
++#endif
++ , KServiceGroup::List& _list,
++ const QString& _relPath,
++ ItemView* view,
++ int& id)
++{
++ bool separatorNeeded = false;
++ KServiceGroup::List::ConstIterator it = _list.begin();
++#ifdef KDELIBS_SUSE
++ KSortableValueList<KSharedPtr<KSycocaEntry>,QCString> slist;
++ KSortableValueList<KSharedPtr<KSycocaEntry>,QCString> glist;
++ QMap<QString,QString> specialTitle;
++ QMap<QString,QString> categoryIcon;
++ QMap<QString,QString> shortenedMenuPath;
++#endif
++
++ for (; it != _list.end(); ++it)
++ {
++ KSycocaEntry * e = *it;
++
++ if (e->isType(KST_KServiceGroup))
++ {
++ KServiceGroup::Ptr g(static_cast<KServiceGroup *>(e));
++#ifdef KDELIBS_SUSE
++ if ( true /*KickerSettings::reduceMenuDepth()*/ && g->SuSEshortMenu() ){
++ KServiceGroup::List l = g->entries(true, true /*excludeNoDisplay_*/ );
++ if ( l.count() == 1 ) {
++ // the special case, we want to short the menu.
++ // TOFIX? : this works only for one level
++ KServiceGroup::List::ConstIterator _it=l.begin();
++ KSycocaEntry *_e = *_it;
++ if (_e->isType(KST_KService)) {
++ KService::Ptr s(static_cast<KService *>(_e));
++ QString key;
++ if ( g->SuSEgeneralDescription() ) {
++ // we use the application name
++ key = s->name();
++ }
++ else {
++ // we use the normal menu description
++ key = s->name();
++ if( !s->genericName().isEmpty() && g->caption()!=s->genericName()) {
++ if (KickerSettings::menuEntryFormat() == KickerSettings::NameAndDescription)
++ key = s->name() + " (" + g->caption() + ")";
++ else if (KickerSettings::menuEntryFormat() == KickerSettings::DescriptionAndName)
++ key = g->caption() + " (" + s->name() + ")";
++ else if (KickerSettings::menuEntryFormat() == KickerSettings::DescriptionOnly)
++ key = g->caption();
++ }
++ }
++ specialTitle.insert( _e->name(), key );
++ categoryIcon.insert( _e->name(), g->icon() );
++ slist.insert( key.local8Bit(), _e );
++ shortenedMenuPath.insert( _e->name(), g->relPath() );
++ // and escape from here
++ continue;
++ }
++ }
++ }
++ glist.insert( g->caption().local8Bit(), e );
++ }else if( e->isType(KST_KService)) {
++ KService::Ptr s(static_cast<KService *>(e));
++ slist.insert( s->name().local8Bit(), e );
++ } else
++ slist.insert( e->name().local8Bit(), e );
++ }
++
++ _list = _root->SuSEsortEntries( slist, glist, true /*excludeNoDisplay_*/, true );
++ it = _list.begin();
++
++ for (; it != _list.end(); ++it) {
++
++ KSycocaEntry * e = *it;
++
++ if (e->isType(KST_KServiceGroup)) {
++
++ KServiceGroup::Ptr g(static_cast<KServiceGroup *>(e));
++ if ( true /*KickerSettings::reduceMenuDepth()*/ && g->SuSEshortMenu() ){
++ KServiceGroup::List l = g->entries(true, true /*excludeNoDisplay_*/ );
++ if ( l.count() == 1 ) {
++ continue;
++ }
++ }
++ // standard sub menu
++#endif
++ QString groupCaption = g->caption();
++
++ // Avoid adding empty groups.
++ KServiceGroup::Ptr subMenuRoot = KServiceGroup::group(g->relPath());
++
++ int nbChildCount = subMenuRoot->childCount();
++ if (nbChildCount == 0 && !g->showEmptyMenu())
++ {
++ continue;
++ }
++
++ bool is_description = KickerSettings::menuEntryFormat() == KickerSettings::DescriptionAndName ||
++ KickerSettings::menuEntryFormat() == KickerSettings::DescriptionOnly;
++
++ QString inlineHeaderName = g->showInlineHeader() ? groupCaption : "";
++
++ if ( nbChildCount == 1 && g->allowInline() && g->inlineAlias())
++ {
++ KServiceGroup::Ptr element = KServiceGroup::group(g->relPath());
++ if ( element )
++ {
++ //just one element
++
++ KServiceGroup::List listElement = element->entries(true, true, true, is_description );
++ KSycocaEntry * e1 = *( listElement.begin() );
++ if ( e1->isType( KST_KService ) )
++ {
++ KService::Ptr s(static_cast<KService *>(e1));
++ view->insertMenuItem(s, id++, -1, 0);
++ continue;
++ }
++ }
++ }
++
++ if (g->allowInline() && ((nbChildCount <= g->inlineValue() ) || (g->inlineValue() == 0)))
++ {
++ //inline all entries
++ KServiceGroup::Ptr rootElement = KServiceGroup::group(g->relPath());
++
++ if (!rootElement || !rootElement->isValid())
++ {
++ break;
++ }
++
++
++ KServiceGroup::List listElement = rootElement->entries(true, true, true, is_description );
++
++#if 0
++ if ( !g->inlineAlias() && !inlineHeaderName.isEmpty() )
++ {
++ int mid = view->insertItem(new PopupMenuTitle(inlineHeaderName, font()), id++, id, 0);
++ m_browserView->setItemEnabled( mid, false );
++ }
++#endif
++
++ fillMenu( rootElement, listElement, g->relPath(), 0, id );
++ continue;
++ }
++
++ // Ignore dotfiles.
++ if ((g->name().at(0) == '.'))
++ {
++ continue;
++ }
++
++ KMenuItem *item = view->insertItem(g->icon(), groupCaption, QString::null, g->relPath(), id++, -1);
++ item->setMenuPath(g->relPath());
++ item->setHasChildren( true );
++
++#warning FIXME
++#if 0
++ PanelServiceMenu * m =
++ newSubMenu(g->name(), g->relPath(), this, g->name().utf8(), inlineHeaderName);
++ m->setCaption(groupCaption);
++
++ QIconSet iconset = KickerLib::menuIconSet(g->icon());
++
++ if (separatorNeeded)
++ {
++ insertSeparator();
++ separatorNeeded = false;
++ }
++
++ int newId = insertItem(iconset, groupCaption, m, id++);
++ entryMap_.insert(newId, static_cast<KSycocaEntry*>(g));
++ // We have to delete the sub menu our selves! (See Qt docs.)
++ subMenus.append(m);
++#endif
++ }
++ if (e->isType(KST_KService))
++ {
++ KService::Ptr s(static_cast<KService *>(e));
++ if (_relPath.isEmpty()) {
++ QStringList favs = KickerSettings::favorites();
++ if (favs.find(s->storageId())!=favs.end())
++ continue;
++ }
++#ifdef KDELIBS_SUSE
++ KMenuItem *item = view->insertMenuItem(s, id++, -1, 0, QString::null, specialTitle[s->name()], categoryIcon[s->name()] );
++ if (shortenedMenuPath[s->name()].isEmpty())
++ item->setMenuPath(_relPath+s->menuId());
++ else
++ item->setMenuPath(shortenedMenuPath[s->name()]+s->menuId());
++#else
++ KMenuItem *item = view->insertMenuItem(s, id++, -1);
++ item->setMenuPath(_relPath+s->menuId());
++#endif
++ }
++ else if (e->isType(KST_KServiceSeparator))
++ {
++ separatorNeeded = true;
++ }
++ }
++
++ view->slotMoveContent();
++}
++
++void KMenu::initialize()
++{
++ static bool m_initialized=false;
++ if (m_initialized)
++ return;
++ m_initialized = true;
++
++ kdDebug(1210) << "KMenu::initialize()" << endl;
++
++ // in case we've been through here before, let's disconnect
++ disconnect(kapp, SIGNAL(kdisplayPaletteChanged()),
++ this, SLOT(paletteChanged()));
++ connect(kapp, SIGNAL(kdisplayPaletteChanged()),
++ this, SLOT(paletteChanged()));
++
++ /*
++ If the user configured ksmserver to
++ */
++ KConfig ksmserver("ksmserverrc", false, false);
++ ksmserver.setGroup("General");
++ connect( m_branding, SIGNAL(clicked()), SLOT(slotOpenHomepage()));
++ m_tabBar->setTabEnabled(LeaveTab, kapp->authorize("logout"));
++
++ // load search field history
++ QStringList histList = KickerSettings::history();
++ int maxHistory = KickerSettings::historyLength();
++
++ bool block = m_kcommand->signalsBlocked();
++ m_kcommand->blockSignals( true );
++ m_kcommand->setMaxCount( maxHistory );
++ m_kcommand->setHistoryItems( histList );
++ m_kcommand->blockSignals( block );
++
++ QStringList compList = KickerSettings::completionItems();
++ if( compList.isEmpty() )
++ m_kcommand->completionObject()->setItems( histList );
++ else
++ m_kcommand->completionObject()->setItems( compList );
++
++ KCompletionBox* box = m_kcommand->completionBox();
++ if (box)
++ box->setActivateOnSelect( false );
++
++ m_finalFilters = KURIFilter::self()->pluginNames();
++ m_finalFilters.remove("kuriikwsfilter");
++
++ m_middleFilters = m_finalFilters;
++ m_middleFilters.remove("localdomainurifilter");
++
++ QStringList favs = KickerSettings::favorites();
++ if (favs.isEmpty()) {
++ QFile f(locate("data", "kicker/default-favs"));
++ if (f.open(IO_ReadOnly)) {
++ QTextStream is(&f);
++
++ while (!is.eof())
++ favs << is.readLine();
++
++ f.close();
++ }
++ KickerSettings::setFavorites(favs);
++ KickerSettings::writeConfig();
++ }
++
++ int nId = serviceMenuEndId() + 1;
++ int index = 1;
++ for (QStringList::ConstIterator it = favs.begin(); it != favs.end(); ++it)
++ {
++ if ((*it)[0]=='/') {
++ KDesktopFile df((*it),true);
++ QString url = df.readURL();
++ if (!KURL(url).isLocalFile() || QFile::exists(url.replace("file://",QString::null)))
++ m_favoriteView->insertItem(df.readIcon(),df.readName(),df.readGenericName(), url, nId++, index++);
++ }
++ else {
++ KService::Ptr p = KService::serviceByStorageId((*it));
++ m_favoriteView->insertMenuItem(p, nId++, index++);
++ }
++ }
++
++ //nId = m_favoriteView->insertSeparator( nId, QString::null, index++ );
++// m_favoriteView->insertDocument(KURL("help:/khelpcenter/userguide/index.html"), nId++);
++
++ insertStaticItems();
++
++ m_stacker->raiseWidget (m_favoriteView);
++}
++
++void KMenu::insertStaticExitItems()
++{
++ int nId = serviceMenuEndId() + 1;
++ int index = 1;
++
++ m_exitView->leftView()->insertSeparator( nId++, i18n("Session"), index++ );
++ if (kapp->authorize("logout"))
++ m_exitView->leftView()->insertItem( "undo", i18n( "Logout" ),
++ i18n( "End session" ), "kicker:/logout", nId++, index++ );
++ if (kapp->authorize("lock_screen"))
++ m_exitView->leftView()->insertItem( "lock", i18n( "Lock" ),
++ i18n( "Lock screen" ), "kicker:/lock", nId++, index++ );
++
++ KConfig ksmserver("ksmserverrc", false, false);
++ ksmserver.setGroup("General");
++ if (ksmserver.readEntry( "loginMode" ) == "restoreSavedSession")
++ {
++ m_exitView->leftView()->insertItem("filesave", i18n("Save Session"),
++ i18n("Save current Session for next login"),
++ "kicker:/savesession", nId++, index++ );
++ }
++ if (DM().isSwitchable() && kapp->authorize("switch_user"))
++ {
++ KMenuItem *switchuser = m_exitView->leftView()->insertItem( "switchuser", i18n( "Switch User" ),
++ i18n( "Manage parallel sessions" ), "kicker:/switchuser/", nId++, index++ );
++ switchuser->setHasChildren(true);
++ }
++
++ bool maysd = false;
++ if (ksmserver.readBoolEntry( "offerShutdown", true ) && DM().canShutdown())
++ maysd = true;
++
++ if ( maysd )
++ {
++ m_exitView->leftView()->insertSeparator( nId++, i18n("System"), index++ );
++ m_exitView->leftView()->insertItem( "exit", i18n( "Shutdown Computer" ),
++ i18n( "Turn off computer" ), "kicker:/shutdown", nId++, index++ );
++
++ m_exitView->leftView()->insertItem( "reload", i18n( "&Restart Computer" ).replace("&",""),
++ i18n( "Restart and boot the default system" ),
++ "kicker:/restart", nId++, index++ );
++
++ insertSuspendOption(nId, index);
++
++ int def, cur;
++ QStringList dummy_opts;
++ if ( DM().bootOptions( dummy_opts, def, cur ) )
++ {
++
++ KMenuItem *restart = m_exitView->leftView()->insertItem( "reload", i18n( "Start Operating System" ),
++ i18n( "Restart and boot another operating system" ),
++ "kicker:/restart/", nId++, index++ );
++ restart->setHasChildren(true);
++ }
++ }
++}
++
++void KMenu::insertStaticItems()
++{
++ insertStaticExitItems();
++
++ int nId = serviceMenuEndId() + 10;
++ int index = 1;
++
++ m_systemView->insertSeparator( nId++, i18n("Applications"), index++);
++
++ KService::Ptr p = KService::serviceByStorageId("/usr/share/applications/YaST.desktop");
++ m_systemView->insertMenuItem(p, nId++, index++);
++
++ m_systemView->insertItem( "info", i18n( "System Information" ),
++ "sysinfo:/", "sysinfo:/", nId++, index++ );
++
++ m_systemView->insertSeparator( nId++, i18n("System Folders"), index++ );
++
++ m_systemView->insertItem( "folder_home", i18n( "Home Folder" ),
++ QDir::homeDirPath(), "file://"+QDir::homeDirPath(), nId++, index++ );
++
++ if ( KStandardDirs::exists( KGlobalSettings::documentPath() + "/" ) )
++ {
++ QString documentPath = KGlobalSettings::documentPath();
++ if ( documentPath.endsWith( "/" ) )
++ documentPath = documentPath.left( documentPath.length() - 1 );
++ if (documentPath!=QDir::homeDirPath())
++ m_systemView->insertItem( "folder_man", i18n( "My Documents" ), documentPath, documentPath, nId++, index++ );
++ }
++
++ m_systemView->insertItem( "network", i18n( "Network Folders" ),
++ "remote:/", "remote:/", nId++, index++ );
++
++ m_mediaWatcher = new MediaWatcher( this );
++ connect( m_mediaWatcher, SIGNAL( mediumChanged() ), SLOT( updateMedia() ) );
++ m_media_id = 0;
++
++ connect(&m_mediaFreeTimer, SIGNAL(timeout()), SLOT( updateMedia()));
++}
++
++int KMenu::insertClientMenu(KickerClientMenu *)
++{
++#if 0
++ int id = client_id;
++ clients.insert(id, p);
++ return id;
++#endif
++ return 0;
++}
++
++void KMenu::removeClientMenu(int)
++{
++#if 0
++ clients.remove(id);
++ slotClear();
++#endif
++}
++
++extern int kicker_screen_number;
++
++void KMenu::slotLock()
++{
++ kdDebug() << "slotLock " << endl;
++ accept();
++ QCString appname( "kdesktop" );
++ if ( kicker_screen_number )
++ appname.sprintf("kdesktop-screen-%d", kicker_screen_number);
++ kapp->dcopClient()->send(appname, "KScreensaverIface", "lock()", "");
++}
++
++void KMenu::slotOpenHomepage()
++{
++ accept();
++ kapp->invokeBrowser("http://opensuse.org");
++}
++
++void KMenu::slotLogout()
++{
++ kapp->requestShutDown();
++}
++
++void KMenu::slotPopulateSessions()
++{
++ int p = 0;
++ DM dm;
++
++ sessionsMenu->clear();
++ if (kapp->authorize("start_new_session") && (p = dm.numReserve()) >= 0)
++ {
++ if (kapp->authorize("lock_screen"))
++ sessionsMenu->insertItem(/*SmallIconSet("lockfork"),*/ i18n("Lock Current && Start New Session"), 100 );
++ sessionsMenu->insertItem(SmallIconSet("fork"), i18n("Start New Session"), 101 );
++ if (!p) {
++ sessionsMenu->setItemEnabled( 100, false );
++ sessionsMenu->setItemEnabled( 101, false );
++ }
++ sessionsMenu->insertSeparator();
++ }
++ SessList sess;
++ if (dm.localSessions( sess ))
++ for (SessList::ConstIterator it = sess.begin(); it != sess.end(); ++it) {
++ int id = sessionsMenu->insertItem( DM::sess2Str( *it ), (*it).vt );
++ if (!(*it).vt)
++ sessionsMenu->setItemEnabled( id, false );
++ if ((*it).self)
++ sessionsMenu->setItemChecked( id, true );
++ }
++}
++
++void KMenu::slotSessionActivated( int ent )
++{
++ if (ent == 100)
++ doNewSession( true );
++ else if (ent == 101)
++ doNewSession( false );
++ else if (!sessionsMenu->isItemChecked( ent ))
++ DM().lockSwitchVT( ent );
++}
++
++void KMenu::doNewSession( bool lock )
++{
++ int result = KMessageBox::warningContinueCancel(
++ kapp->desktop()->screen(kapp->desktop()->screenNumber(this)),
++ i18n("<p>You have chosen to open another desktop session.<br>"
++ "The current session will be hidden "
++ "and a new login screen will be displayed.<br>"
++ "An F-key is assigned to each session; "
++ "F%1 is usually assigned to the first session, "
++ "F%2 to the second session and so on. "
++ "You can switch between sessions by pressing "
++ "Ctrl, Alt and the appropriate F-key at the same time. "
++ "Additionally, the KDE Panel and Desktop menus have "
++ "actions for switching between sessions.</p>")
++ .arg(7).arg(8),
++ i18n("Warning - New Session"),
++ KGuiItem(i18n("&Start New Session"), "fork"),
++ ":confirmNewSession",
++ KMessageBox::PlainCaption | KMessageBox::Notify);
++
++ if (result==KMessageBox::Cancel)
++ return;
++
++ if (lock)
++ slotLock();
++
++ DM().startReserve();
++}
++
++void KMenu::searchAccept()
++{
++ QString cmd = m_kcommand->currentText().stripWhiteSpace();
++
++ bool logout = (cmd == "logout");
++ bool lock = (cmd == "lock");
++
++ addToHistory();
++
++ if ( !logout && !lock )
++ {
++ // first try if we have any search action
++ if (m_searchResultsWidget->currentItem()) {
++ m_searchResultsWidget->slotItemClicked(m_searchResultsWidget->currentItem());
++ return;
++ }
++ }
++
++ accept();
++ saveConfig();
++
++ if ( logout )
++ {
++ kapp->propagateSessionManager();
++ kapp->requestShutDown();
++ }
++ if ( lock )
++ {
++ QCString appname( "kdesktop" );
++ int kicker_screen_number = qt_xscreen();
++ if ( kicker_screen_number )
++ appname.sprintf("kdesktop-screen-%d", kicker_screen_number);
++ kapp->dcopClient()->send(appname, "KScreensaverIface", "lock()", "");
++ }
++}
++
++bool KMenu::runCommand()
++{
++ kdDebug() << "runCommand() " << m_kcommand->lineEdit()->text() << endl;
++ // Ignore empty commands...
++ if ( m_kcommand->lineEdit()->text().isEmpty() )
++ return true;
++
++ accept();
++
++ if (input_timer->isActive ())
++ input_timer->stop ();
++
++ // Make sure we have an updated data
++ parseLine( true );
++
++ bool block = m_kcommand->signalsBlocked();
++ m_kcommand->blockSignals( true );
++ m_kcommand->clearEdit();
++ m_kcommand->setFocus();
++ m_kcommand->reset();
++ m_kcommand->blockSignals( block );
++
++
++ QString cmd;
++ KURL uri = m_filterData->uri();
++ if ( uri.isLocalFile() && !uri.hasRef() && uri.query().isEmpty() )
++ cmd = uri.path();
++ else
++ cmd = uri.url();
++
++ QString exec;
++
++ switch( m_filterData->uriType() )
++ {
++ case KURIFilterData::LOCAL_FILE:
++ case KURIFilterData::LOCAL_DIR:
++ case KURIFilterData::NET_PROTOCOL:
++ case KURIFilterData::HELP:
++ {
++ // No need for kfmclient, KRun does it all (David)
++ (void) new KRun( m_filterData->uri(), parentWidget());
++ return false;
++ }
++ case KURIFilterData::EXECUTABLE:
++ {
++ if( !m_filterData->hasArgsAndOptions() )
++ {
++ // Look for desktop file
++ KService::Ptr service = KService::serviceByDesktopName(cmd);
++ if (service && service->isValid() && service->type() == "Application")
++ {
++ notifyServiceStarted(service);
++ KRun::run(*service, KURL::List());
++ return false;
++ }
++ }
++ }
++ // fall-through to shell case
++ case KURIFilterData::SHELL:
++ {
++ if (kapp->authorize("shell_access"))
++ {
++ exec = cmd;
++
++ if( m_filterData->hasArgsAndOptions() )
++ cmd += m_filterData->argsAndOptions();
++
++ break;
++ }
++ else
++ {
++ KMessageBox::sorry( this, i18n("<center><b>%1</b></center>\n"
++ "You do not have permission to execute "
++ "this command.")
++ .arg( QStyleSheet::convertFromPlainText(cmd) ));
++ return true;
++ }
++ }
++ case KURIFilterData::UNKNOWN:
++ case KURIFilterData::ERROR:
++ default:
++ {
++ // Look for desktop file
++ KService::Ptr service = KService::serviceByDesktopName(cmd);
++ if (service && service->isValid() && service->type() == "Application")
++ {
++ notifyServiceStarted(service);
++ KRun::run(*service, KURL::List(), this);
++ return false;
++ }
++
++ service = KService::serviceByName(cmd);
++ if (service && service->isValid() && service->type() == "Application")
++ {
++ notifyServiceStarted(service);
++ KRun::run(*service, KURL::List(), this);
++ return false;
++ }
++
++ KMessageBox::sorry( this, i18n("<center><b>%1</b></center>\n"
++ "Could not run the specified command.")
++ .arg( QStyleSheet::convertFromPlainText(cmd) ));
++ return true;
++ }
++ }
++
++ if ( KRun::runCommand( cmd, exec, m_iconName ) )
++ return false;
++
++ KMessageBox::sorry( this, i18n("<center><b>%1</b></center>\n"
++ "The specified command does not exist.").arg(cmd) );
++ return true; // Let the user try again...
++}
++
++void KMenu::show()
++{
++ m_isShowing = true;
++ emit aboutToShow();
++
++ initialize();
++
++ PanelPopupButton *kButton = MenuManager::the()->findKButtonFor( this );
++ if (kButton)
++ {
++ QPoint center = kButton->center();
++ QRect screen = QApplication::desktop()->screenGeometry( center );
++ setOrientation((center.y()-screen.y()<screen.height()/2)
++ ? TopDown : BottomUp);
++ }
++
++ m_browserDirty=true;
++ m_recentDirty=true;
++
++ updateMedia();
++ m_mediaFreeTimer.start(10 * 1000); // refresh all 10s
++
++ m_stacker->raiseWidget(FavoriteTab);
++ m_kcommand->clear();
++ current_query.clear();
++ m_kcommand->setFocus();
++
++ // we need to reenable it
++ m_toolTipsEnabled = QToolTip::isGloballyEnabled();
++ QToolTip::setGloballyEnabled(KickerSettings::showToolTips());
++
++ KMenuBase::show();
++ m_isShowing = false;
++}
++
++void KMenu::setOrientation(MenuOrientation orientation)
++{
++ if (m_orientation == orientation)
++ return;
++
++ m_orientation=orientation;
++
++ m_resizeHandle->setCursor(m_orientation == BottomUp ? Qt::sizeBDiagCursor : Qt::sizeFDiagCursor);
++
++ QPixmap pix;
++ if ( m_orientation == BottomUp )
++ pix.load( locate("data", "kicker/pics/search-gradient.png" ) );
++ else
++ pix.load( locate("data", "kicker/pics/search-gradient-topdown.png" ) );
++
++ pix.convertFromImage( pix.convertToImage().scale(pix.width(), m_searchFrame->height()));
++ m_search->mainWidget()->setPaletteBackgroundPixmap( pix );
++ m_resizeHandle->setPaletteBackgroundPixmap( pix );
++
++ m_tabBar->setShape( m_orientation == BottomUp
++ ? QTabBar::RoundedBelow : QTabBar::RoundedAbove);
++
++ QPixmap respix = QPixmap( locate("data", "kicker/pics/resize_handle.png" ) );
++ if ( m_orientation == TopDown ) {
++ QWMatrix m;
++ m.rotate( 90.0 );
++ respix=respix.xForm(m);
++ }
++ m_resizeHandle->setPixmap(respix);
++
++ {
++ QWidget *footer = m_footer->mainWidget();
++ QPixmap pix( 64, footer->height() );
++ QPainter p( &pix );
++ p.fillRect( 0, 0, 64, footer->height(), m_branding->colorGroup().brush( QColorGroup::Base ) );
++ p.fillRect( 0, m_orientation == BottomUp ? footer->height() - 2 : 0,
++ 64, 3, KNewButton::self()->borderColor() );
++ p.end();
++ footer->setPaletteBackgroundPixmap( pix );
++ }
++
++ resizeEvent(new QResizeEvent(sizeHint(), sizeHint()));
++}
++
++void KMenu::showMenu()
++{
++ kdDebug() << "KMenu::showMenu()" << endl;
++ PanelPopupButton *kButton = MenuManager::the()->findKButtonFor(this);
++ if (kButton)
++ {
++ adjustSize();
++ kButton->showMenu();
++ }
++ else
++ {
++ show();
++ }
++ kdDebug() << "end KMenu::showMenu()" << endl;
++}
++
++void KMenu::hide()
++{
++ //kdDebug() << "KMenu::hide() from " << kdBacktrace() << endl;
++
++ // TODO: hide popups
++
++ emit aboutToHide();
++
++ if (m_popupMenu) {
++ m_popupMenu->deleteLater();
++ m_popupMenu=0;
++ }
++ m_mediaFreeTimer.stop();
++
++ m_isresizing = false;
++
++ KickerSettings::setKMenuWidth(width());
++ KickerSettings::setKMenuHeight(height());
++ KickerSettings::writeConfig();
++
++ QToolTip::setGloballyEnabled(m_toolTipsEnabled);
++
++ // remove focus from lineedit again, otherwise it doesn't kill its timers
++ m_stacker->raiseWidget(FavoriteTab);
++
++ QWidget::hide();
++}
++
++void KMenu::paintEvent(QPaintEvent * e)
++{
++ KMenuBase::paintEvent(e);
++
++ QPainter p(this);
++ p.setClipRegion(e->region());
++
++ const BackgroundMode bgmode = backgroundMode();
++ const QColorGroup::ColorRole crole = QPalette::backgroundRoleFromMode( bgmode );
++ p.setBrush( colorGroup().brush( crole ) );
++
++ p.drawRect( 0, 0, width(), height() );
++ int ypos = m_search->mainWidget()->geometry().bottom();
++
++ p.drawPixmap( 0, ypos, main_border_tl );
++ p.drawPixmap( width() - main_border_tr.width(), ypos, main_border_tr );
++ // p.drawPixmap( 0, ->y(), button_box_left );
++}
++
++
++void KMenu::configChanged()
++{
++ RecentlyLaunchedApps::the().m_bNeedToUpdate = false;
++ RecentlyLaunchedApps::the().configChanged();
++
++ m_exitView->leftView()->clear();
++ insertStaticExitItems();
++}
++
++// create and fill "recent" section at first
++void KMenu::createRecentMenuItems()
++{
++ RecentlyLaunchedApps::the().init();
++
++ if (!KickerSettings::numVisibleEntries())
++ KickerSettings::setNumVisibleEntries(5);
++
++ int nId = serviceMenuEndId() + 1;
++ m_recentlyView->insertSeparator( nId++, i18n( "Applications" ), -1 );
++
++ QStringList RecentApps;
++
++ if (!KickerSettings::recentVsOften()) {
++ KickerSettings::setRecentVsOften(true);
++ RecentlyLaunchedApps::the().configChanged();
++ RecentlyLaunchedApps::the().getRecentApps(RecentApps);
++ KickerSettings::setRecentVsOften(false);
++ RecentlyLaunchedApps::the().configChanged();
++ }
++ else
++ RecentlyLaunchedApps::the().getRecentApps(RecentApps);
++
++
++ if (RecentApps.count() > 0)
++ {
++// bool bSeparator = KickerSettings::showMenuTitles();
++ int nIndex = 0;
++
++ for (QValueList<QString>::ConstIterator it =
++ RecentApps.begin(); it!=RecentApps.end(); ++it)
++ {
++ KService::Ptr s = KService::serviceByStorageId(*it);
++ if (!s)
++ {
++ RecentlyLaunchedApps::the().removeItem(*it);
++ }
++ else
++ m_recentlyView->insertMenuItem(s, nIndex++);
++ }
++
++ }
++
++ m_recentlyView->insertSeparator( nId++, i18n( "Documents" ), -1 );
++
++ QStringList fileList = KRecentDocument::recentDocuments();
++ kdDebug() << "createRecentMenuItems=" << fileList << endl;
++ for (QStringList::ConstIterator it = fileList.begin();
++ it != fileList.end();
++ ++it)
++ m_recentlyView->insertRecentlyItem(*it, nId++);
++
++}
++
++void KMenu::clearSubmenus()
++{
++ // we don't need to delete these on the way out since the libloader
++ // handles them for us
++ if (QApplication::closingDown())
++ {
++ return;
++ }
++
++ for (PopupMenuList::const_iterator it = dynamicSubMenus.constBegin();
++ it != dynamicSubMenus.constEnd();
++ ++it)
++ {
++ delete *it;
++ }
++ dynamicSubMenus.clear();
++}
++
++void KMenu::updateRecent()
++{
++ m_recentlyView->clear();
++
++ createRecentMenuItems();
++
++ m_recentDirty = false;
++}
++
++void KMenu::popup(const QPoint&, int)
++{
++ showMenu();
++}
++
++void KMenu::clearRecentAppsItems()
++{
++ RecentlyLaunchedApps::the().clearRecentApps();
++ RecentlyLaunchedApps::the().save();
++ RecentlyLaunchedApps::the().m_bNeedToUpdate = true;
++ updateRecent();
++}
++
++void KMenu::clearRecentDocsItems()
++{
++ KRecentDocument::clear();
++ updateRecent();
++}
++
++void KMenu::searchChanged(const QString & text)
++{
++ if (!text.isEmpty()) {
++ const QColor on = QColor( 244, 244, 244 );
++ const QColor off = QColor( 181, 181, 181 );
++ m_stacker->raiseWidget(m_searchWidget);
++ paintSearchTab(true);
++ }
++
++ m_searchActions->clearSelection();
++ m_searchResultsWidget->clearSelection();
++
++ if (input_timer->isActive ())
++ input_timer->stop ();
++ input_timer->start (WAIT_BEFORE_QUERYING, TRUE);
++}
++
++bool KMenu::dontQueryNow (const QString& str)
++{
++ if (str.isEmpty ())
++ return true;
++ if (str == current_query.get())
++ return true;
++ int length = str.length ();
++ int last_whitespace = str.findRev (' ', -1);
++ if (last_whitespace == length-1)
++ return false; // if the user typed a space, search
++ if (last_whitespace >= length-2)
++ return true; // dont search if the user only typed one character
++ QChar lastchar = str[length-1];
++ if (lastchar == ":" || lastchar == "=")
++ return true;
++ return false;
++}
++
++void KMenu::createNewProgramList()
++{
++ m_seenProgramsChanged = false;
++ m_seenPrograms = KickerSettings::firstSeenApps();
++ m_newInstalledPrograms.clear();
++
++ m_currentDate = QDate::currentDate().toString(Qt::ISODate);
++
++ bool initialize = (m_seenPrograms.count() == 0);
++
++ createNewProgramList(QString::null);
++
++ if (initialize) {
++ for (QStringList::Iterator it = m_seenPrograms.begin(); it != m_seenPrograms.end(); ++it)
++ *(++it)="-";
++
++ m_newInstalledPrograms.clear();
++ }
++
++ if (m_seenProgramsChanged) {
++ KickerSettings::setFirstSeenApps(m_seenPrograms);
++ KickerSettings::writeConfig();
++ }
++}
++
++void KMenu::createNewProgramList(QString relPath)
++{
++ KServiceGroup::Ptr group = KServiceGroup::group(relPath);
++ if (!group || !group->isValid())
++ return;
++
++ KServiceGroup::List list = group->entries();
++ if (list.isEmpty())
++ return;
++
++ KServiceGroup::List::ConstIterator it = list.begin();
++ for(; it != list.end(); ++it) {
++ KSycocaEntry *e = *it;
++
++ if(e != 0) {
++ if(e->isType(KST_KServiceGroup)) {
++ KServiceGroup::Ptr g(static_cast<KServiceGroup *>(e));
++ if(!g->noDisplay())
++ createNewProgramList(g->relPath());
++ } else if(e->isType(KST_KService)) {
++ KService::Ptr s(static_cast<KService *>(e));
++ if(s->type() == "Application" && !s->noDisplay() ) {
++ QString shortStorageId = s->storageId().replace(".desktop",QString::null);
++ QStringList::Iterator it_find = m_seenPrograms.begin();
++ QStringList::Iterator it_end = m_seenPrograms.end();
++ bool found = false;
++ for (; it_find != it_end; ++it_find) {
++ if (*(it_find)==shortStorageId) {
++ found = true;
++ break;
++ }
++ ++it_find;
++ }
++ if (!found) {
++ m_seenProgramsChanged=true;
++ m_seenPrograms+=shortStorageId;
++ m_seenPrograms+=m_currentDate;
++ if (m_newInstalledPrograms.find(s->storageId())==m_newInstalledPrograms.end())
++ m_newInstalledPrograms+=s->storageId();
++ }
++ else {
++ ++it_find;
++ if (*(it_find)!="-") {
++ QDate date = QDate::fromString(*(it_find),Qt::ISODate);
++ if (date.daysTo(QDate::currentDate())<3) {
++ if (m_newInstalledPrograms.find(s->storageId())==m_newInstalledPrograms.end())
++ m_newInstalledPrograms+=s->storageId();
++ }
++ else {
++ m_seenProgramsChanged=true;
++ (*it_find)="-";
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++}
++
++void KMenu::searchProgramList(QString relPath)
++{
++ KServiceGroup::Ptr group = KServiceGroup::group(relPath);
++ if (!group || !group->isValid())
++ return;
++
++ KServiceGroup::List list = group->entries();
++ if (list.isEmpty())
++ return;
++
++ KServiceGroup::List::ConstIterator it = list.begin();
++ for(; it != list.end(); ++it) {
++ KSycocaEntry *e = *it;
++
++ if(e != 0) {
++ if(e->isType(KST_KServiceGroup)) {
++ KServiceGroup::Ptr g(static_cast<KServiceGroup *>(e));
++ if(!g->noDisplay())
++ searchProgramList(g->relPath());
++ } else if(e->isType(KST_KService)) {
++ KService::Ptr s(static_cast<KService *>(e));
++ if(s->type() == "Application" && !s->noDisplay() && !checkUriInMenu(s->desktopEntryPath())) {
++ if (!current_query.matches(s->name()+' '+s->genericName()+' '+s->exec()+' '+
++ s->keywords().join(",")+' '+s->comment()+' '+group->caption()+' '+
++ s->categories().join(",")) || !anotherHitMenuItemAllowed(APPS))
++ continue;
++
++ QString input = current_query.get();
++ int score = 0;
++ if (s->exec()==input)
++ score = 100;
++ else if (s->exec().find(input)==0)
++ score = 50;
++ else if (s->exec().find(input)!=-1)
++ score = 10;
++ else if (s->name().lower()==input)
++ score = 100;
++ else if (s->genericName().lower()==input)
++ score = 100;
++ else if (s->name().lower().find(input)==0)
++ score = 50;
++ else if (s->genericName().lower().find(input)==0)
++ score = 50;
++ else if (s->name().lower().find(input)!=-1)
++ score = 10;
++ else if (s->genericName().lower().find(input)!=-1)
++ score = 10;
++
++ if (s->exec().find(' ')==-1)
++ score+=1;
++
++ if (s->substituteUid())
++ score-=1;
++
++ if (s->noDisplay())
++ score -= 100;
++ else if (s->terminal())
++ score -= 50;
++ else
++ score += kMin(10, s->initialPreference());
++
++ QString firstLine, secondLine;
++ if ((KickerSettings::DescriptionAndName || KickerSettings::menuEntryFormat() == KickerSettings::DescriptionOnly) && !s->genericName().isEmpty()) {
++ firstLine = s->genericName();
++ secondLine = s->name();
++ }
++ else {
++ firstLine = s->name();
++ secondLine = s->genericName();
++ }
++
++ HitMenuItem *hit_item = new HitMenuItem (firstLine, secondLine,
++ s->desktopEntryPath(), QString::null, 0, APPS, s->icon(), score);
++ if (hit_item == NULL)
++ continue;
++
++ hit_item->service = s;
++ insertSearchResult(hit_item);
++
++ QString exe = s->exec();
++ int pos = exe.find(' ');
++ if (pos>0)
++ exe=exe.left(pos);
++ m_programsInMenu+=KGlobal::dirs()->findExe(exe);
++ }
++ }
++ }
++ }
++}
++
++void KMenu::searchBookmarks(KBookmarkGroup group)
++{
++ KBookmark bookmark = group.first();
++ while(!bookmark.isNull()) {
++ if (bookmark.isGroup()) {
++ searchBookmarks(bookmark.toGroup());
++ } else if (!bookmark.isSeparator() && !bookmark.isNull()) {
++ if (!current_query.matches(bookmark.fullText()+' '+bookmark.url().url()) || !anotherHitMenuItemAllowed(BOOKMARKS)) {
++ bookmark = group.next(bookmark);
++ continue;
++ }
++
++ HitMenuItem *hit_item = new HitMenuItem (bookmark.fullText(), bookmark.fullText(),
++ bookmark.url(), QString::null, 0, BOOKMARKS, bookmark.icon());
++
++ insertSearchResult(hit_item);
++ }
++ bookmark = group.next(bookmark);
++ }
++}
++
++void KMenu::initSearch()
++{
++ if (!m_addressBook && KickerSettings::kickoffSearchAddressBook())
++ m_addressBook = KABC::StdAddressBook::self( false );
++
++ if (!bookmarkManager)
++ bookmarkManager = KBookmarkManager::userBookmarksManager();
++
++ if (!m_search_plugin) {
++ m_search_plugin_interface = new QObject( this, "m_search_plugin_interface" );
++ new MyKickoffSearchInterface( this, m_search_plugin_interface, "kickoffsearch interface" );
++ KTrader::OfferList offers = KTrader::self()->query("KickoffSearch/Plugin");
++
++ KService::Ptr service = *offers.begin();
++ if (service) {
++ int errCode = 0;
++ m_search_plugin = KParts::ComponentFactory::createInstanceFromService<KickoffSearch::Plugin>
++ ( service, m_search_plugin_interface, 0, QStringList(), &errCode);
++ }
++ }
++}
++
++void KMenu::searchAddressbook()
++{
++ if (!KickerSettings::kickoffSearchAddressBook())
++ return;
++
++ if (!m_addressBook)
++ m_addressBook = KABC::StdAddressBook::self( false );
++
++ KABC::AddressBook::ConstIterator it = m_addressBook->begin();
++ while (it!=m_addressBook->end()) {
++ if (!current_query.matches((*it).assembledName()+' '+(*it).fullEmail())) {
++ it++;
++ continue;
++ }
++
++ HitMenuItem *hit_item;
++ QString realName = (*it).realName();
++ if (realName.isEmpty())
++ realName=(*it).preferredEmail();
++
++ if (!(*it).preferredEmail().isEmpty()) {
++ if (!anotherHitMenuItemAllowed(ACTIONS)) {
++ it++;
++ continue;
++ }
++
++ hit_item = new HitMenuItem (i18n("Send Email to %1").arg(realName), (*it).preferredEmail(),
++ "mailto:"+(*it).preferredEmail(), QString::null, 0, ACTIONS, "mail_new");
++
++ insertSearchResult(hit_item);
++ }
++
++ if (!anotherHitMenuItemAllowed(ACTIONS)) {
++ it++;
++ continue;
++ }
++
++ hit_item = new HitMenuItem (i18n("Open Addressbook at %1").arg(realName), (*it).preferredEmail(),
++ "kaddressbook:/"+(*it).uid(), QString::null, 0, ACTIONS, "kaddressbook");
++
++ insertSearchResult(hit_item);
++
++ it++;
++ }
++}
++
++QString KMenu::insertBreaks(const QString& text, QFontMetrics fm, int width, QString leadInsert)
++{
++ QString result, line;
++ QStringList words = QStringList::split(' ', text);
++
++ for(QStringList::Iterator it = words.begin(); it != words.end(); ++it) {
++ if (fm.width(line+' '+*it) >= width) {
++ if (!result.isEmpty())
++ result = result + '\n';
++ result = result + line;
++ line = leadInsert + *it;
++ }
++ else
++ line = line + ' ' + *it;
++ }
++ if (!result.isEmpty())
++ result = result + '\n';
++
++ return result + line;
++}
++
++void KMenu::clearSearchResults(bool showHelp)
++{
++ m_searchResultsWidget->clear();
++ m_searchResultsWidget->setFocusPolicy(showHelp ? QWidget::NoFocus : QWidget::StrongFocus);
++ setTabOrder(m_kcommand, m_searchResultsWidget);
++
++ if (showHelp) {
++ const int width = m_searchResultsWidget->width()-10;
++ QFontMetrics fm = m_searchResultsWidget->fontMetrics();
++
++ QListViewItem* item;
++ item = new QListViewItem( m_searchResultsWidget, insertBreaks(i18n("- Add ext:type to specify a file extension."), fm, width, " ") );
++ item->setSelectable(false);
++ item->setMultiLinesEnabled(true);
++ item = new QListViewItem( m_searchResultsWidget, insertBreaks(i18n("- When searching for a phrase, add quotes."), fm, width, " " ) );
++ item->setSelectable(false);
++ item->setMultiLinesEnabled(true);
++ item = new QListViewItem( m_searchResultsWidget, insertBreaks(i18n("- To exclude search terms, use the minus symbol in front."), fm, width, " " ) );
++ item->setSelectable(false);
++ item->setMultiLinesEnabled(true);
++ item = new QListViewItem( m_searchResultsWidget, insertBreaks(i18n("- To search for optional terms, use OR."), fm, width, " ") );
++ item->setSelectable(false);
++ item->setMultiLinesEnabled(true);
++ item = new QListViewItem( m_searchResultsWidget, insertBreaks(i18n("- You can use upper and lower case."), fm, width, " ") );
++ item->setSelectable(false);
++ item->setMultiLinesEnabled(true);
++ item = new QListViewItem( m_searchResultsWidget, i18n("Search Quick Tips"));
++ item->setSelectable(false);
++ }
++
++ for (int i=0; i<num_categories; ++i) {
++ categorised_hit_total [i] = 0;
++ max_category_id [i] = base_category_id [i];
++ }
++}
++
++void KMenu::doQuery (bool return_pressed)
++{
++ QString query_str = m_kcommand->lineEdit()->text ().simplifyWhiteSpace ();
++ if (! return_pressed && dontQueryNow (query_str)) {
++ if (query_str.length()<3)
++ clearSearchResults();
++ else {
++ if (m_searchResultsWidget->firstChild() && m_searchResultsWidget->firstChild()->isSelectable()) {
++ m_searchResultsWidget->setSelected(m_searchResultsWidget->firstChild(),true);
++ }
++ else if (m_searchResultsWidget->childCount()>1) {
++ m_searchResultsWidget->setSelected(m_searchResultsWidget->firstChild()->itemBelow(),true);
++ }
++ }
++ return;
++ }
++ kdDebug() << "Querying for [" << query_str << "]" << endl;
++ current_query.set(query_str);
++
++ // reset search results
++ HitMenuItem *hit_item;
++ while ((hit_item = m_current_menu_items.take ()) != NULL) {
++ //kndDebug () << " (" << hit_item->id << "," << hit_item->category << ")" << endl;
++ delete hit_item;
++ }
++
++ clearSearchResults(false);
++ m_searchPixmap->setMovie(QMovie(locate( "data", "kicker/pics/search-running.mng" )));
++
++ resetOverflowCategory();
++
++ initCategoryTitlesUpdate();
++
++ // calculate ?
++ QString cmd = query_str.stripWhiteSpace();
++ if (!cmd.isEmpty() && (cmd[0].isNumber() || (cmd[0] == '(')) &&
++ (QRegExp("[a-zA-Z\\]\\[]").search(cmd) == -1))
++ {
++ QString result = calculate(cmd);
++ if (!result.isEmpty())
++ {
++ categorised_hit_total[ACTIONS] ++;
++ HitMenuItem *hit_item = new HitMenuItem (i18n("%1 = %2").arg(query_str, result), QString::null,
++ "kcalc", QString::null, (++max_category_id [ACTIONS]), ACTIONS, "kcalc");
++ int index = getHitMenuItemPosition (hit_item);
++ m_searchResultsWidget->insertItem(iconForHitMenuItem(hit_item), hit_item->display_name,
++ hit_item->display_info, KGlobal::dirs()->findExe("kcalc"), max_category_id [ACTIONS], index);
++ }
++ }
++
++ // detect email address
++ if (emailRegExp.exactMatch(query_str)) {
++ categorised_hit_total[ACTIONS] ++;
++ HitMenuItem *hit_item = new HitMenuItem (i18n("Send Email to %1").arg(query_str), QString::null,
++ "mailto:"+query_str, QString::null, (++max_category_id [ACTIONS]), ACTIONS, "mail_new");
++ int index = getHitMenuItemPosition (hit_item);
++ m_searchResultsWidget->insertItem(iconForHitMenuItem(hit_item), hit_item->display_name, hit_item->display_info, "mailto:"+query_str, max_category_id [ACTIONS], index);
++ }
++
++ // quick own application search
++ m_programsInMenu.clear();
++ searchProgramList(QString::null);
++
++ KURIFilterData filterData;
++ filterData.setData(query_str);
++ filterData.setCheckForExecutables(true);
++
++ if (KURIFilter::self()->filterURI(filterData)) {
++
++ QString description;
++ QString exe;
++
++ switch (filterData.uriType()) {
++ case KURIFilterData::LOCAL_FILE:
++ description = i18n("Open Local File: %1").arg(filterData.uri().url());
++ break;
++ case KURIFilterData::LOCAL_DIR:
++ description = i18n("Open Local Dir: %1").arg(filterData.uri().url());
++ break;
++ case KURIFilterData::NET_PROTOCOL:
++ description = i18n("Open Remote Location: %1").arg(filterData.uri().url());
++ break;
++ case KURIFilterData::SHELL:
++ case KURIFilterData::EXECUTABLE:
++ {
++ exe = KGlobal::dirs()->findExe(filterData.uri().url());
++#ifdef KDELIBS_SUSE
++ bool gimp_hack = false;
++ if (exe.endsWith("/bin/gimp")) {
++ QStringList::ConstIterator it = m_programsInMenu.begin();
++ for (; it != m_programsInMenu.end(); ++it)
++ if ((*it).find("bin/gimp-remote-")!=-1) {
++ gimp_hack = true;
++ break;
++ }
++ }
++#endif
++ if (m_programsInMenu.find(exe)!=m_programsInMenu.end()
++#ifdef KDELIBS_SUSE
++ || gimp_hack
++#endif
++ )
++ exe = QString::null;
++ else if (kapp->authorize("shell_access"))
++ {
++ if( filterData.hasArgsAndOptions() )
++ exe += filterData.argsAndOptions();
++
++ description = i18n("Run '%1'").arg(exe);
++ exe = "kicker:/runcommand";
++ }
++ }
++ default:
++ break;
++ }
++
++ if (!description.isEmpty()) {
++ categorised_hit_total[ACTIONS] ++;
++ HitMenuItem *hit_item = new HitMenuItem (description, QString::null,
++ exe.isEmpty() ? filterData.uri() : exe, QString::null,
++ (++max_category_id [ACTIONS]), ACTIONS, exe.isEmpty() ? "fileopen": "run");
++ int index = getHitMenuItemPosition (hit_item);
++ m_searchResultsWidget->insertItem(iconForHitMenuItem(hit_item), hit_item->display_name,
++ hit_item->display_info,
++ exe.isEmpty() ? filterData.uri().url() : exe, max_category_id [ACTIONS], index);
++ }
++ }
++
++ // search Konqueror bookmarks;
++ if (!bookmarkManager)
++ bookmarkManager = KBookmarkManager::userBookmarksManager();
++
++ if (query_str.length()>=3)
++ searchBookmarks(bookmarkManager->root());
++
++ // search KDE addressbook
++ if (query_str.length()>=3)
++ searchAddressbook();
++
++ updateCategoryTitles();
++
++ if (m_searchResultsWidget->childCount()>1)
++ m_searchResultsWidget->setSelected(m_searchResultsWidget->firstChild()->itemBelow(),true);
++ m_searchActions->clearSelection();
++
++ i