summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kcheckpass/checkpass_pam.c11
-rw-r--r--kcontrol/background/bgdialog.cpp14
-rw-r--r--kcontrol/input/xcursor/themepage.cpp11
-rw-r--r--kcontrol/kicker/menutab_impl.h3
-rw-r--r--kcontrol/spellchecking/spellchecking.cpp2
-rwxr-xr-xkdeeject/kdeeject42
-rw-r--r--kdesktop/KDesktopIface.h29
-rw-r--r--kdesktop/Makefile.am2
-rw-r--r--kdesktop/desktop.cc47
-rw-r--r--kdesktop/desktop.h5
-rw-r--r--kdesktop/kdiconview.cc120
-rw-r--r--kdesktop/kdiconview.h9
-rw-r--r--kdesktop/lock/lockprocess.cc244
-rw-r--r--kdesktop/lock/lockprocess.h30
-rw-r--r--kdesktop/minicli.cpp15
-rw-r--r--kdesktop/minicli.h4
-rw-r--r--kdesu/kdesu/kdesu.cpp1
-rw-r--r--kdesu/kdesud/kdesud.cpp3
-rw-r--r--kdm/backend/client.c93
-rw-r--r--kdm/config.def11
-rw-r--r--kdm/configure.in.in71
-rw-r--r--kdm/kfrontend/Makefile.am1
-rw-r--r--kdm/kfrontend/kdm_greet.c2
-rw-r--r--kdm/kfrontend/kdmadmindialog.cpp176
-rw-r--r--kdm/kfrontend/kdmadmindialog.h70
-rw-r--r--kdm/kfrontend/kdmconfig.cpp2
-rw-r--r--kdm/kfrontend/kdmconfig.h14
-rw-r--r--kdm/kfrontend/kfdialog.cpp4
-rw-r--r--kdm/kfrontend/kgapp.cpp5
-rw-r--r--kdm/kfrontend/kgdialog.cpp4
-rw-r--r--kdm/kfrontend/kgreeter.cpp214
-rw-r--r--kdm/kfrontend/kgreeter.h9
-rw-r--r--kdm/kfrontend/sessions/Makefile.am2
-rw-r--r--kdm/kfrontend/sessions/admin.desktop7
-rw-r--r--kdm/kfrontend/themer/kdmitem.cpp107
-rw-r--r--kdm/kfrontend/themer/kdmitem.h7
-rw-r--r--kdm/kfrontend/themer/kdmlabel.cpp67
-rw-r--r--kdm/kfrontend/themer/kdmlabel.h6
-rw-r--r--kdm/kfrontend/themer/kdmlayout.cpp9
-rw-r--r--kdm/kfrontend/themer/kdmpixmap.cpp98
-rw-r--r--kdm/kfrontend/themer/kdmpixmap.h5
-rw-r--r--kdm/kfrontend/themer/kdmrect.cpp32
-rw-r--r--kdm/kfrontend/themer/kdmrect.h4
-rw-r--r--kdm/kfrontend/themer/kdmthemer.cpp73
-rw-r--r--kdm/kfrontend/themer/kdmthemer.h4
-rw-r--r--kdmlib/Makefile.am6
-rw-r--r--kdmlib/kgreet_pam.cpp668
-rw-r--r--kdmlib/kgreet_pam.h93
-rw-r--r--khelpcenter/kcmhelpcenter.cpp7
-rw-r--r--khelpcenter/kcmhelpcenter.h5
-rw-r--r--khelpcenter/navigator.cpp10
-rw-r--r--khelpcenter/searchhandlers/Makefile.am2
-rw-r--r--khelpcenter/searchhandlers/docbook.desktop4
-rw-r--r--khelpcenter/searchhandlers/khc_beagle_index.pl49
-rw-r--r--khelpcenter/searchhandlers/khc_beagle_search.pl88
-rw-r--r--kicker/applets/systemtray/systemtrayapplet.cpp98
-rw-r--r--kicker/applets/systemtray/systemtrayapplet.h1
-rw-r--r--kicker/data/kickoff/button-box-gradient-topdown.pngbin0 -> 213 bytes
-rw-r--r--kicker/data/kickoff/button-box-gradient.pngbin0 -> 255 bytes
-rw-r--r--kicker/data/kickoff/button-box-left-corner.pngbin0 -> 203 bytes
-rw-r--r--kicker/data/kickoff/button-box-left.pngbin0 -> 306 bytes
-rw-r--r--kicker/data/kickoff/button-box-right-corner.pngbin0 -> 214 bytes
-rw-r--r--kicker/data/kickoff/button-box-top.pngbin0 -> 163 bytes
-rw-r--r--kicker/data/kickoff/cr128-action-suspend2disk.pngbin0 -> 13797 bytes
-rw-r--r--kicker/data/kickoff/cr128-action-suspend2ram.pngbin0 -> 15500 bytes
-rw-r--r--kicker/data/kickoff/cr16-action-suspend2disk.pngbin0 -> 834 bytes
-rw-r--r--kicker/data/kickoff/cr16-action-suspend2ram.pngbin0 -> 865 bytes
-rw-r--r--kicker/data/kickoff/cr32-action-leave.pngbin0 -> 1602 bytes
-rw-r--r--kicker/data/kickoff/cr32-action-suspend2disk.pngbin0 -> 2091 bytes
-rw-r--r--kicker/data/kickoff/cr32-action-suspend2ram.pngbin0 -> 2243 bytes
-rw-r--r--kicker/data/kickoff/cr48-action-leave.pngbin0 -> 2475 bytes
-rw-r--r--kicker/data/kickoff/cr48-action-suspend2disk.pngbin0 -> 3713 bytes
-rw-r--r--kicker/data/kickoff/cr48-action-suspend2ram.pngbin0 -> 3965 bytes
-rw-r--r--kicker/data/kickoff/cr48-app-recently_used.pngbin0 -> 4736 bytes
-rw-r--r--kicker/data/kickoff/cr64-action-suspend2disk.pngbin0 -> 5601 bytes
-rw-r--r--kicker/data/kickoff/cr64-action-suspend2ram.pngbin0 -> 6115 bytes
-rw-r--r--kicker/data/kickoff/crsc-action-leave.svgzbin0 -> 3915 bytes
-rw-r--r--kicker/data/kickoff/crsc-action-suspend2disk.svgzbin0 -> 12713 bytes
-rw-r--r--kicker/data/kickoff/crsc-action-suspend2ram.svgzbin0 -> 13613 bytes
-rw-r--r--kicker/data/kickoff/kmenu_active.pngbin0 -> 3257 bytes
-rw-r--r--kicker/data/kickoff/kmenu_basic.mngbin0 -> 81101 bytes
-rw-r--r--kicker/data/kickoff/kmenu_flipped.mngbin0 -> 81240 bytes
-rw-r--r--kicker/data/kickoff/kmenu_vertical.mngbin0 -> 62006 bytes
-rw-r--r--kicker/data/kickoff/left_triangle.pngbin0 -> 781 bytes
-rw-r--r--kicker/data/kickoff/main_border_bc.pngbin0 -> 171 bytes
-rw-r--r--kicker/data/kickoff/main_border_lc.pngbin0 -> 166 bytes
-rw-r--r--kicker/data/kickoff/main_border_rc.pngbin0 -> 174 bytes
-rw-r--r--kicker/data/kickoff/main_border_tc.pngbin0 -> 163 bytes
-rw-r--r--kicker/data/kickoff/main_corner_bl.pngbin0 -> 211 bytes
-rw-r--r--kicker/data/kickoff/main_corner_br.pngbin0 -> 218 bytes
-rw-r--r--kicker/data/kickoff/main_corner_tl.pngbin0 -> 176 bytes
-rw-r--r--kicker/data/kickoff/main_corner_tr.pngbin0 -> 202 bytes
-rw-r--r--kicker/data/kickoff/menu_separator.pngbin0 -> 260 bytes
-rw-r--r--kicker/data/kickoff/resize_handle.pngbin0 -> 217 bytes
-rw-r--r--kicker/data/kickoff/right_triangle.pngbin0 -> 722 bytes
-rw-r--r--kicker/data/kickoff/search-gradient-topdown.pngbin0 -> 181 bytes
-rw-r--r--kicker/data/kickoff/search-gradient.pngbin0 -> 218 bytes
-rw-r--r--kicker/data/kickoff/search-running.mngbin0 -> 11888 bytes
-rw-r--r--kicker/data/kickoff/search-tab-center.pngbin0 -> 170 bytes
-rw-r--r--kicker/data/kickoff/search-tab-left.pngbin0 -> 398 bytes
-rw-r--r--kicker/data/kickoff/search-tab-right.pngbin0 -> 417 bytes
-rw-r--r--kicker/data/kickoff/search-tab-top-center.pngbin0 -> 146 bytes
-rw-r--r--kicker/data/kickoff/search-tab-top-left.pngbin0 -> 2960 bytes
-rw-r--r--kicker/data/kickoff/search-tab-top-right.pngbin0 -> 368 bytes
-rw-r--r--kicker/data/kickoff/tab-bottom-left-topdown.pngbin0 -> 145 bytes
-rw-r--r--kicker/data/kickoff/tab-bottom-left.pngbin0 -> 304 bytes
-rw-r--r--kicker/data/kickoff/tab-bottom-right-topdown.pngbin0 -> 171 bytes
-rw-r--r--kicker/data/kickoff/tab-bottom-right.pngbin0 -> 351 bytes
-rw-r--r--kicker/data/kickoff/tab-center-topdown.pngbin0 -> 142 bytes
-rw-r--r--kicker/data/kickoff/tab-center.pngbin0 -> 175 bytes
-rw-r--r--kicker/data/kickoff/tab-left_center.pngbin0 -> 165 bytes
-rw-r--r--kicker/data/kickoff/tab-right_center.pngbin0 -> 165 bytes
-rw-r--r--kicker/data/kickoff/tab-top-left-topdown.pngbin0 -> 256 bytes
-rw-r--r--kicker/data/kickoff/tab-top-left.pngbin0 -> 198 bytes
-rw-r--r--kicker/data/kickoff/tab-top-right-topdown.pngbin0 -> 327 bytes
-rw-r--r--kicker/data/kickoff/tab-top-right.pngbin0 -> 198 bytes
-rw-r--r--kicker/kicker/ui/browser_mnu.cpp9
-rw-r--r--kicker/kicker/ui/service_mnu.cpp123
-rw-r--r--kicker/kicker/ui/service_mnu.h3
-rw-r--r--kicker/libkicker/kickerSettings.kcfg5
-rw-r--r--kioslave/media/mediaimpl.cpp7
-rw-r--r--kioslave/media/mediamanager/halbackend.cpp8
-rw-r--r--kioslave/smb/kio_smb_auth.cpp1
-rw-r--r--kioslave/system/entries/documents.desktop2
-rw-r--r--klipper/klipperrc.desktop4
-rw-r--r--konqueror/Makefile.am4
-rw-r--r--konqueror/konq_combo.cc12
-rw-r--r--konqueror/konq_combo.h1
-rw-r--r--konqueror/konq_frame.cc5
-rw-r--r--konsole/other/x11r5.keytab4
-rw-r--r--kscreensaver/Makefile.am4
-rw-r--r--kscreensaver/random.cpp102
-rw-r--r--ksmserver/KSMServerInterface.h2
-rw-r--r--ksmserver/Makefile.am4
-rw-r--r--ksmserver/server.h12
-rw-r--r--ksmserver/shutdown.cpp78
-rw-r--r--ksmserver/shutdowndlg.cpp70
-rw-r--r--ksmserver/shutdowndlg.h19
-rw-r--r--ksmserver/test.cpp7
-rw-r--r--ksmserver/timed.ui352
-rw-r--r--kwin/workspace.cpp14
-rw-r--r--kxkb/kcmlayout.cpp3
-rw-r--r--nsplugins/nspluginloader.cpp6
-rw-r--r--nsplugins/nspluginloader.h2
-rw-r--r--nsplugins/pluginscan.cpp2
145 files changed, 3334 insertions, 251 deletions
diff --git a/kcheckpass/checkpass_pam.c b/kcheckpass/checkpass_pam.c
index 6f281165f..44758b696 100644
--- a/kcheckpass/checkpass_pam.c
+++ b/kcheckpass/checkpass_pam.c
@@ -140,13 +140,16 @@ AuthReturn Authenticate(const char *caller, const char *method,
openlog("kcheckpass", LOG_PID, LOG_AUTH);
PAM_data.conv = conv;
- if (strcmp(method, "classic")) {
- sprintf(pservb, "%.31s-%.31s", caller, method);
- pam_service = pservb;
- } else {
+ if (!strcmp(method, "classic")) {
PAM_data.classic = 1;
pam_service = caller;
}
+ else if (!strcmp(method, "pam")) {
+ pam_service = caller;
+ } else {
+ sprintf(pservb, "%.31s-%.31s", caller, method);
+ pam_service = pservb;
+ }
pam_error = pam_start(pam_service, user, &PAM_conversation, &pamh);
if (pam_error != PAM_SUCCESS)
return AuthError;
diff --git a/kcontrol/background/bgdialog.cpp b/kcontrol/background/bgdialog.cpp
index ae76b701a..8294f53a3 100644
--- a/kcontrol/background/bgdialog.cpp
+++ b/kcontrol/background/bgdialog.cpp
@@ -504,14 +504,23 @@ void BGDialog::loadWallpaperFilesList() {
//search for .desktop files before searching for images without .desktop files
TQStringList lst = m_pDirs->findAllResources("wallpaper", "*desktop", false, true);
TQStringList files;
+ TQStringList hiddenfiles;
for (TQStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it)
{
KSimpleConfig fileConfig(*it);
fileConfig.setGroup("Wallpaper");
+ int slash = (*it).findRev('/') + 1;
+ TQString directory = (*it).left(slash);
+
TQString imageCaption = fileConfig.readEntry("Name");
TQString fileName = fileConfig.readEntry("File");
+ if (fileConfig.readBoolEntry("Hidden",false)) {
+ hiddenfiles.append(directory + fileName);
+ continue;
+ }
+
if (imageCaption.isEmpty())
{
imageCaption = fileName;
@@ -527,9 +536,8 @@ void BGDialog::loadWallpaperFilesList() {
rs = imageCaption + " (" + TQString::number(n) + ')';
lrs = rs.lower();
}
- int slash = (*it).findRev('/') + 1;
- TQString directory = (*it).left(slash);
bool canLoadScaleable = false;
+
#ifdef HAVE_LIBART
canLoadScaleable = true;
#endif
@@ -543,7 +551,7 @@ void BGDialog::loadWallpaperFilesList() {
lst = m_pDirs->findAllResources("wallpaper", "*", false, true);
for (TQStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it)
{
- if ( !(*it).endsWith(".desktop") && files.grep(*it).empty() ) {
+ if ( !(*it).endsWith(".desktop") && files.grep(*it).empty() && hiddenfiles.grep(*it).empty() ) {
// First try to see if we have a comment describing the image. If we do
// just use the first line of said comment.
KFileMetaInfo metaInfo(*it);
diff --git a/kcontrol/input/xcursor/themepage.cpp b/kcontrol/input/xcursor/themepage.cpp
index 4fb8b8a69..7caf18c3f 100644
--- a/kcontrol/input/xcursor/themepage.cpp
+++ b/kcontrol/input/xcursor/themepage.cpp
@@ -73,6 +73,13 @@ struct ThemeInfo {
};
+static TQString defaultThemeDescription( const TQString& theme )
+{
+ if( theme == "redglass" || theme == "whiteglass" || theme == "pseudocore" || theme == "handhelds" )
+ return i18n( "XFree theme %1 - incomplete for KDE" ).arg( theme );
+ return i18n( "No description available" );;
+}
+
ThemePage::ThemePage( TQWidget* parent, const char* name )
: TQWidget( parent, name ), selectedTheme( NULL ), currentTheme( NULL )
{
@@ -333,7 +340,7 @@ void ThemePage::insertTheme( const TQString &path )
// Defaults in case there's no name or comment field.
TQString name = dirName;
- TQString desc = i18n( "No description available" );
+ TQString desc = defaultThemeDescription( name );
TQString sample = "left_ptr";
KSimpleConfig c( path + "/index.theme", true ); // Open read-only
@@ -480,7 +487,7 @@ void ThemePage::insertThemes()
// Defaults in case there's no index.theme file or it lacks
// a name and a comment field.
TQString name = *it;
- TQString desc = i18n( "No description available" );
+ TQString desc = defaultThemeDescription( name );
TQString sample = "left_ptr";
// Parse the index.theme file if the theme has one.
diff --git a/kcontrol/kicker/menutab_impl.h b/kcontrol/kicker/menutab_impl.h
index 3d0e09748..877e47ffe 100644
--- a/kcontrol/kicker/menutab_impl.h
+++ b/kcontrol/kicker/menutab_impl.h
@@ -19,6 +19,9 @@
#define __menutab_impl_h__
#include <tqlistview.h>
+#include <stdlib.h>
+
+#include <kpushbutton.h>
#include "menutab.h"
diff --git a/kcontrol/spellchecking/spellchecking.cpp b/kcontrol/spellchecking/spellchecking.cpp
index 6416f9e9c..a7ed79b46 100644
--- a/kcontrol/spellchecking/spellchecking.cpp
+++ b/kcontrol/spellchecking/spellchecking.cpp
@@ -67,7 +67,7 @@ void KSpellCheckingConfig::defaults()
spellConfig->setRunTogether(0);
spellConfig->setDictionary("");
spellConfig->setDictFromList(FALSE);
- spellConfig->setEncoding (KS_E_ASCII);
+ spellConfig->setEncoding (KS_E_UTF8);
spellConfig->setClient (KS_CLIENT_ISPELL);
}
diff --git a/kdeeject/kdeeject b/kdeeject/kdeeject
index 71079794d..34e61097e 100755
--- a/kdeeject/kdeeject
+++ b/kdeeject/kdeeject
@@ -4,12 +4,38 @@
#
# Copyright GPL v2 by David Faure <[email protected]>
#
-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"; then
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/kdesktop/KDesktopIface.h b/kdesktop/KDesktopIface.h
index 1aa90e538..b966405e4 100644
--- a/kdesktop/KDesktopIface.h
+++ b/kdesktop/KDesktopIface.h
@@ -107,6 +107,35 @@ k_dcop:
* space for desktop icons
*/
virtual void desktopIconsAreaChanged(const TQRect &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 TQPoint findPlaceForIcon( int column, int row) = 0;
+
+ /// copy the desktop file in the Desktop and place it at x, y
+ virtual void addIcon(const TQString &url, int x, int y) = 0;
+
+ /// same with specific destination
+ virtual void addIcon(const TQString &url, const TQString &dest, int x, int y) = 0;
+
+ /// remove the desktop file (either full path or relative)
+ virtual void removeIcon(const TQString &dest) = 0;
};
#endif
diff --git a/kdesktop/Makefile.am b/kdesktop/Makefile.am
index fecd9e9c4..5035fe77f 100644
--- a/kdesktop/Makefile.am
+++ b/kdesktop/Makefile.am
@@ -6,6 +6,8 @@ kdesktop_la_LIBADD = libkdesktopsettings.la $(top_builddir)/libkonq/libkonq.la
SUBDIRS = . lock pics patterns programs init kwebdesktop
+KDE_OPTIONS = nofinal
+
####### Files
bin_PROGRAMS = kcheckrunning
diff --git a/kdesktop/desktop.cc b/kdesktop/desktop.cc
index 54513e962..a05dfcb99 100644
--- a/kdesktop/desktop.cc
+++ b/kdesktop/desktop.cc
@@ -32,6 +32,9 @@
#include <unistd.h>
#include <kcolordrag.h>
#include <kurldrag.h>
+#include <stdlib.h>
+#include <kio/job.h>
+#include <tqfile.h>
#include <tqdir.h>
#include <tqevent.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>
@@ -986,4 +990,47 @@ bool KDesktop::event(TQEvent * e)
return TQWidget::event(e);
}
+TQPoint KDesktop::findPlaceForIcon( int column, int row )
+{
+ if (m_pIconView)
+ return m_pIconView->findPlaceForIcon(column, row);
+ else
+ return TQPoint(-1, -1);
+}
+
+void KDesktop::addIcon(const TQString & _url, int x, int y)
+{
+ addIcon( _url, KGlobalSettings::desktopPath(), x, y );
+}
+
+void KDesktop::addIcon(const TQString & _url, const TQString & _dest, int x, int y)
+{
+ TQString filename = _url.mid(_url.findRev('/') + 1);
+
+ TQValueList<KIO::CopyInfo> files;
+ KIO::CopyInfo i;
+ i.uSource = KURL::fromPathOrURL( _url );
+ i.uDest = KURL::fromPathOrURL( _dest );
+ i.uDest.addPath( filename );
+ files.append(i);
+ if (!TQFile::exists(i.uDest.prettyURL().replace("file://",TQString::null))) { m_pIconView->slotAboutToCreate( TQPoint( 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(TQString("cp \"%1\" \"%2/%3\"").arg(KURL(_url).path()).arg(KURL(_dest).path()).arg(filename).latin1());
+// m_pIconView->update( _dest );
+}
+
+void KDesktop::removeIcon(const TQString &_url)
+{
+ if (_url.at(0) != '/') {
+ qDebug("removeIcon with relative path not supported for now");
+ return;
+ }
+ unlink(KURL(_url).path().latin1());
+ TQString dest = _url.left(_url.findRev('/') + 1);
+ m_pIconView->update( dest );
+}
+
#include "desktop.moc"
diff --git a/kdesktop/desktop.h b/kdesktop/desktop.h
index d8ec12c69..31928e9d4 100644
--- a/kdesktop/desktop.h
+++ b/kdesktop/desktop.h
@@ -164,6 +164,11 @@ protected:
virtual void setIconsEnabled( bool enable );
virtual bool event ( TQEvent * e );
+ virtual TQPoint findPlaceForIcon( int column, int row);
+ virtual void addIcon(const TQString &url, int x, int y);
+ virtual void addIcon(const TQString &url, const TQString &dest, int x, int y);
+ virtual void removeIcon(const TQString &url);
+
private slots:
void desktopResized();
diff --git a/kdesktop/kdiconview.cc b/kdesktop/kdiconview.cc
index caa68feb9..5762458fd 100644
--- a/kdesktop/kdiconview.cc
+++ b/kdesktop/kdiconview.cc
@@ -962,6 +962,18 @@ void KDIconView::slotNewItems( const KFileItemList & entries )
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 KFileItemList & entries )
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(TQIconViewItem *item )
}
+TQPoint KDIconView::findPlaceForIconCol( int column, int dx, int dy)
+{
+ if (column < 0)
+ return TQPoint();
+
+ TQRect rect;
+ rect.moveTopLeft( TQPoint(column * dx, 0) );
+ rect.setWidth(dx);
+ rect.setHeight(dy);
+
+ if (rect.right() > viewport()->width())
+ return TQPoint();
+
+ while ( rect.bottom() < viewport()->height() - spacing() )
+ {
+ if ( !isFreePosition(0,rect) )
+ rect.moveBy(0, rect.height());
+ else
+ return rect.topLeft();
+ }
+
+ return TQPoint();
+}
+
+TQPoint KDIconView::findPlaceForIconRow( int row, int dx, int dy )
+{
+ if (row < 0)
+ return TQPoint();
+
+ TQRect rect;
+ rect.moveTopLeft(TQPoint(0, row * dy));
+ rect.setWidth(dx);
+ rect.setHeight(dy);
+
+ if (rect.bottom() > viewport()->height())
+ return TQPoint();
+
+ while (rect.right() < viewport()->width() - spacing())
+ {
+ if (!isFreePosition(0,rect))
+ rect.moveBy(rect.width()+spacing(), 0);
+ else
+ return rect.topLeft();
+ }
+
+ return TQPoint();
+}
+
+TQPoint KDIconView::findPlaceForIcon( int column, int row)
+{
+ int dx = gridXValue(), dy = 0;
+ TQIconViewItem *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;
+ TQPoint 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;
+ TQPoint 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 TQPoint(0, 0);
+}
+
void KDIconView::saveIconPositions()
{
kdDebug(1214) << "KDIconView::saveIconPositions" << endl;
@@ -1665,4 +1760,11 @@ void KDIconView::saveIconPositions()
m_dotDirectory->sync();
}
+void KDIconView::update( const TQString &_url )
+{
+ if (m_dirLister)
+ m_dirLister->updateDirectory( _url );
+}
+
+
#include "kdiconview.moc"
diff --git a/kdesktop/kdiconview.h b/kdesktop/kdiconview.h
index 715a0eb5e..5ef349322 100644
--- a/kdesktop/kdiconview.h
+++ b/kdesktop/kdiconview.h
@@ -73,6 +73,8 @@ public:
TQStringList selectedURLs();
+ void update( const TQString &url );
+
/**
* Save the icon positions
*/
@@ -103,6 +105,10 @@ public:
void startDirLister();
+ TQPoint findPlaceForIconCol( int column, int dx, int dy );
+ TQPoint findPlaceForIconRow( int row, int dx, int dy );
+ TQPoint findPlaceForIcon( int column, int row );
+
protected slots:
// slots connected to the icon view
@@ -112,8 +118,9 @@ protected slots:
void slotMouseButtonClickedKDesktop(int _button, TQIconViewItem* _item, const TQPoint& _global);
void slotContextMenuRequested(TQIconViewItem* _item, const TQPoint& _global);
void slotEnableAction( const char * name, bool enabled );
+public slots:
void slotAboutToCreate(const TQPoint &pos, const TQValueList<KIO::CopyInfo> &files);
-
+protected slots:
void slotItemRenamed(TQIconViewItem*, const TQString &name);
// slots connected to the directory lister
diff --git a/kdesktop/lock/lockprocess.cc b/kdesktop/lock/lockprocess.cc
index d589232a1..cdd5581e7 100644
--- a/kdesktop/lock/lockprocess.cc
+++ b/kdesktop/lock/lockprocess.cc
@@ -39,6 +39,8 @@
#include <kstdguiitem.h>
#include <kpixmapeffect.h>
#include <kpixmap.h>
+#include <kwin.h>
+#include <kwinmodule.h>
#include <tqframe.h>
#include <tqlabel.h>
@@ -119,6 +121,8 @@ static void segv_handler(int)
sleep(1);
}
+extern Atom qt_wm_state;
+
//===========================================================================
//
// Screen saver handling process. Handles screensaver window,
@@ -135,6 +139,8 @@ LockProcess::LockProcess(bool child, bool useBlankOnly)
mRestoreXF86Lock(false),
mForbidden(false),
mAutoLogout(false),
+ mVkbdProcess(NULL),
+ mKWinModule(NULL),
mPipeOpen(false),
mPipeOpen_out(false),
mInfoMessageDisplayed(false),
@@ -1120,9 +1126,11 @@ bool LockProcess::checkPass()
if (mAutoLogout)
killTimer(mAutoLogoutTimerId);
+ showVkbd();
PasswordDlg passDlg( this, &greetPlugin);
-
int ret = execDialog( &passDlg );
+ hideVkbd();
+
if (mForceReject == true) {
ret = TQDialog::Rejected;
}
@@ -1251,9 +1259,13 @@ bool LockProcess::x11Event(XEvent *event)
switch (event->type)
{
- case KeyPress:
case ButtonPress:
case MotionNotify:
+ case ButtonRelease:
+ if( forwardVkbdEvent( event ))
+ return true; // filter out
+ // fall through
+ case KeyPress:
if (mBusy || !mDialogs.isEmpty())
break;
mBusy = true;
@@ -1290,11 +1302,30 @@ bool LockProcess::x11Event(XEvent *event)
case ConfigureNotify: // from SubstructureNotifyMask on the root window
if(event->xconfigure.event == qt_xrootwin())
stayOnTop();
+ for( TQValueList< VkbdWindow >::Iterator it = mVkbdWindows.begin();
+ it != mVkbdWindows.end();
+ ++it ) {
+ if( (*it).id == event->xconfigure.window ) {
+ (*it).rect = TQRect( event->xconfigure.x, event->xconfigure.y,
+ event->xconfigure.width, event->xconfigure.height );
+ break;
+ }
+ }
break;
case MapNotify: // from SubstructureNotifyMask on the root window
+ windowAdded( event->xmap.window, false );
if( event->xmap.event == qt_xrootwin())
stayOnTop();
break;
+ case DestroyNotify:
+ for( TQValueList< VkbdWindow >::Iterator it = mVkbdWindows.begin();
+ it != mVkbdWindows.end();
+ ++it )
+ if( (*it).id == event->xdestroywindow.window ) {
+ mVkbdWindows.remove( it );
+ break;
+ }
+ break;
}
// We have grab with the grab window being the root window.
@@ -1319,17 +1350,24 @@ bool LockProcess::x11Event(XEvent *event)
void LockProcess::stayOnTop()
{
- if(!mDialogs.isEmpty())
+ if(!mDialogs.isEmpty() || !mVkbdWindows.isEmpty())
{
// this restacking is written in a way so that
// if the stacking positions actually don't change,
// all restacking operations will be no-op,
// and no ConfigureNotify will be generated,
// thus avoiding possible infinite loops
- XRaiseWindow( qt_xdisplay(), mDialogs.first()->winId()); // raise topmost
+ if( !mVkbdWindows.isEmpty())
+ XRaiseWindow( qt_xdisplay(), mVkbdWindows.first().id );
+ else
+ XRaiseWindow( qt_xdisplay(), mDialogs.first()->winId()); // raise topmost
// and stack others below it
- Window* stack = new Window[ mDialogs.count() + 1 ];
+ Window* stack = new Window[ mDialogs.count() + mVkbdWindows.count() + 1 ];
int count = 0;
+ for( TQValueList< VkbdWindow >::ConstIterator it = mVkbdWindows.begin();
+ it != mVkbdWindows.end();
+ ++it )
+ stack[ count++ ] = (*it).id;
for( TQValueList< TQWidget* >::ConstIterator it = mDialogs.begin();
it != mDialogs.end();
++it )
@@ -1428,4 +1466,200 @@ void LockProcess::msgBox( TQMessageBox::Icon type, const TQString &txt )
execDialog( &box );
}
+static int run_vkbd = -1;
+void LockProcess::showVkbd()
+{
+ if( run_vkbd == - 1 ) {
+ int status = system( "hal-find-by-property --key system.formfactor.subtype --string tabletpc" );
+// status = 0; // enable for testing
+ run_vkbd = ( WIFEXITED( status ) && WEXITSTATUS( status ) == 0
+ && !KStandardDirs::findExe( "xvkbd" ).isEmpty()) ? 1 : 0;
+ }
+ if( run_vkbd ) {
+ mVkbdWindows.clear();
+ mVkbdLastEventWindow = None;
+ mKWinModule = new KWinModule( NULL, KWinModule::INFO_WINDOWS );
+ connect( mKWinModule, TQT_SIGNAL( windowAdded( WId )), TQT_SLOT( windowAdded( WId )));
+ mVkbdProcess = new KProcess;
+ *mVkbdProcess << "xvkbd" << "-compact" << "-geometry" << "-0-0" << "-xdm";
+ mVkbdProcess->start();
+ }
+}
+
+void LockProcess::hideVkbd()
+{
+ if( mVkbdProcess != NULL ) {
+ mVkbdProcess->kill();
+ delete mVkbdProcess;
+ mVkbdProcess = NULL;
+ delete mKWinModule;
+ mKWinModule = NULL;
+ mVkbdWindows.clear();
+ }
+}
+
+void LockProcess::windowAdded( WId w )
+{
+ windowAdded( w, true );
+}
+
+void LockProcess::windowAdded( WId w, bool managed )
+{
+ KWin::WindowInfo info = KWin::windowInfo( w, 0, NET::WM2WindowClass );
+ if( info.windowClassClass().lower() != "xvkbd" )
+ return;
+ // Unmanaged windows (i.e. popups) don't currently work anyway, since they
+ // don't have WM_CLASS set anyway. I could perhaps try tricks with X id
+ // ranges if really needed.
+ if( managed ) {
+ // withdraw the window, wait for it to be withdrawn, reparent it directly
+ // to root at the right position
+ XWithdrawWindow( qt_xdisplay(), w, qt_xscreen());
+ for(;;) {
+ Atom type;
+ int format;
+ unsigned long length, after;
+ unsigned char *data;
+ int r = XGetWindowProperty( qt_xdisplay(), w, qt_wm_state, 0, 2,
+ false, AnyPropertyType, &type, &format,
+ &length, &after, &data );
+ bool withdrawn = true;
+ if ( r == Success && data && format == 32 ) {
+ Q_UINT32 *wstate = (Q_UINT32*)data;
+ withdrawn = (*wstate == WithdrawnState );
+ XFree( (char *)data );
+ }
+ if( withdrawn )
+ break;
+ }
+ }
+ XSelectInput( qt_xdisplay(), w, StructureNotifyMask );
+ XWindowAttributes attr_geom;
+ if( !XGetWindowAttributes( qt_xdisplay(), w, &attr_geom ))
+ return;
+ int x = XDisplayWidth( qt_xdisplay(), qt_xscreen()) - attr_geom.width;
+ int y = XDisplayHeight( qt_xdisplay(), qt_xscreen()) - attr_geom.height;
+ if( managed ) {
+ XSetWindowAttributes attr;
+ attr.override_redirect = True;
+ XChangeWindowAttributes( qt_xdisplay(), w, CWOverrideRedirect, &attr );
+ XReparentWindow( qt_xdisplay(), w, qt_xrootwin(), x, y );
+ XMapWindow( qt_xdisplay(), w );
+ }
+ VkbdWindow data;
+ data.id = w;
+ data.rect = TQRect( x, y, attr_geom.width, attr_geom.height );
+ mVkbdWindows.prepend( data );
+}
+
+bool LockProcess::forwardVkbdEvent( XEvent* event )
+{
+ if( mVkbdProcess == NULL )
+ return false;
+ TQPoint pos;
+ Time time;
+ switch( event->type )
+ {
+ case ButtonPress:
+ case ButtonRelease:
+ pos = TQPoint( event->xbutton.x, event->xbutton.y );
+ time = event->xbutton.time;
+ break;
+ case MotionNotify:
+ pos = TQPoint( event->xmotion.x, event->xmotion.y );
+ time = event->xmotion.time;
+ break;
+ default:
+ return false;
+ }
+ // vkbd windows are kept topmost, so just find the first one in the position
+ for( TQValueList< VkbdWindow >::ConstIterator it = mVkbdWindows.begin();
+ it != mVkbdWindows.end();
+ ++it ) {
+ if( (*it).rect.contains( pos )) {
+ // Find the subwindow where the event should actually go.
+ // Not exactly cheap in the number of X roundtrips but oh well.
+ Window window = (*it).id;
+ Window root, child;
+ int root_x, root_y, x, y;
+ unsigned int mask;
+ for(;;) {
+ if( !XQueryPointer( qt_xdisplay(), window, &root, &child, &root_x, &root_y, &x, &y, &mask ))
+ return false;
+ if( child == None )
+ break;
+ window = child;
+ }
+ switch( event->type )
+ {
+ case ButtonPress:
+ case ButtonRelease:
+ event->xbutton.x = x;
+ event->xbutton.y = y;
+ event->xbutton.subwindow = None;
+ break;
+ case MotionNotify:
+ event->xmotion.x = x;
+ event->xmotion.y = y;
+ event->xmotion.subwindow = None;
+ break;
+ }
+ event->xany.window = window;
+ sendVkbdFocusInOut( window, time );
+ XSendEvent( qt_xdisplay(), window, False, 0, event );
+ return true;
+ }
+ }
+ sendVkbdFocusInOut( None, time );
+ return false;
+}
+
+// Fake EnterNotify/LeaveNotify events as the mouse moves. They're not sent by X
+// because of the grab and having them makes xvkbd highlight the buttons (but
+// not needed otherwise it seems).
+void LockProcess::sendVkbdFocusInOut( WId window, Time t )
+{
+ if( mVkbdLastEventWindow == window )
+ return;
+ if( mVkbdLastEventWindow != None ) {
+ XEvent e;
+ e.xcrossing.type = LeaveNotify;
+ e.xcrossing.display = qt_xdisplay();
+ e.xcrossing.window = mVkbdLastEventWindow;
+ e.xcrossing.root = qt_xrootwin();
+ e.xcrossing.subwindow = None;
+ e.xcrossing.time = t;
+ e.xcrossing.x = 0;
+ e.xcrossing.y = 0;
+ e.xcrossing.x_root = -1;
+ e.xcrossing.y_root = -1;
+ e.xcrossing.mode = NotifyNormal;
+ e.xcrossing.detail = NotifyAncestor;
+ e.xcrossing.same_screen = True;
+ e.xcrossing.focus = False;
+ e.xcrossing.state = 0;
+ XSendEvent( qt_xdisplay(), mVkbdLastEventWindow, False, 0, &e );
+ }
+ mVkbdLastEventWindow = window;
+ if( mVkbdLastEventWindow != None ) {
+ XEvent e;
+ e.xcrossing.type = EnterNotify;
+ e.xcrossing.display = qt_xdisplay();
+ e.xcrossing.window = mVkbdLastEventWindow;
+ e.xcrossing.root = qt_xrootwin();
+ e.xcrossing.subwindow = None;
+ e.xcrossing.time = t;
+ e.xcrossing.x = 0;
+ e.xcrossing.y = 0;
+ e.xcrossing.x_root = 0;
+ e.xcrossing.y_root = 0;
+ e.xcrossing.mode = NotifyNormal;
+ e.xcrossing.detail = NotifyAncestor;
+ e.xcrossing.same_screen = True;
+ e.xcrossing.focus = False;
+ e.xcrossing.state = 0;
+ XSendEvent( qt_xdisplay(), mVkbdLastEventWindow, False, 0, &e );
+ }
+}
+
#include "lockprocess.moc"
diff --git a/kdesktop/lock/lockprocess.h b/kdesktop/lock/lockprocess.h
index cdbeb0da1..76ffb6013 100644
--- a/kdesktop/lock/lockprocess.h
+++ b/kdesktop/lock/lockprocess.h
@@ -23,6 +23,7 @@
#include <X11/Xlib.h>
class KLibrary;
+class KWinModule;
struct GreeterPluginHandle {
KLibrary *library;
@@ -79,6 +80,7 @@ private slots:
void suspend();
void checkDPMSActive();
void slotDeadTimePassed();
+ void windowAdded( WId );
private:
void configure();
@@ -103,6 +105,11 @@ private:
void stayOnTop();
void lockXF86();
void unlockXF86();
+ void showVkbd();
+ void hideVkbd();
+ bool forwardVkbdEvent( XEvent* event );
+ void sendVkbdFocusInOut( WId window, Time t );
+ void windowAdded( WId window, bool managed );
void resume( bool force );
static TQVariant getConf(void *ctx, const char *key, const TQVariant &dflt);
@@ -135,18 +142,29 @@ private:
int mAutoLogoutTimerId;
int mAutoLogoutTimeout;
bool mAutoLogout;
- bool mInfoMessageDisplayed;
- TQDialog *currentDialog;
- bool mDialogControlLock;
- bool mForceReject;
+
+ TQTimer *resizeTimer;
+ unsigned int mkeyCode;
+
+ KProcess* mVkbdProcess;
+ KWinModule* mKWinModule;
+ struct VkbdWindow
+ {
+ WId id;
+ QRect rect;
+ };
+ QValueList< VkbdWindow > mVkbdWindows;
+ WId mVkbdLastEventWindow;
bool mPipeOpen;
int mPipe_fd;
bool mPipeOpen_out;
int mPipe_fd_out;
- TQTimer *resizeTimer;
- unsigned int mkeyCode;
+ bool mInfoMessageDisplayed;
+ TQDialog *currentDialog;
+ bool mDialogControlLock;
+ bool mForceReject;
};
#endif
diff --git a/kdesktop/minicli.cpp b/kdesktop/minicli.cpp
index caef6197a..027aa0bfc 100644
--- a/kdesktop/minicli.cpp
+++ b/kdesktop/minicli.cpp
@@ -145,6 +145,9 @@ Minicli::Minicli( TQWidget *parent, const char *name)
connect( m_dlg->cbCommand, TQT_SIGNAL( returnPressed() ),
m_dlg->pbRun, TQT_SLOT( animateClick() ) );
+ m_dlg->cbCommand->setHistoryEditorEnabled( true );
+ connect( m_dlg->cbCommand, TQT_SIGNAL(removed( const TQString&) ), TQT_SLOT(saveConfig()) );
+
// Advanced group box...
connect(m_dlg->cbPriority, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotChangeScheduler(bool)));
connect(m_dlg->slPriority, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(slotPriority(int)));
@@ -295,7 +298,9 @@ void Minicli::accept()
}
bool logout = (cmd == "logout");
- if( !logout && runCommand() == 1 )
+ bool lock = (cmd == "lock");
+
+ if( !logout && !lock && runCommand() == 1 )
return;
m_dlg->cbCommand->addToHistory( m_dlg->cbCommand->currentText().stripWhiteSpace() );
@@ -308,6 +313,14 @@ void Minicli::accept()
kapp->propagateSessionManager();
kapp->requestShutDown();
}
+ if ( lock )
+ {
+ TQCString 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()", "");
+ }
}
void Minicli::reject()
diff --git a/kdesktop/minicli.h b/kdesktop/minicli.h
index ddbe868c0..4ae49cf7c 100644
--- a/kdesktop/minicli.h
+++ b/kdesktop/minicli.h
@@ -54,12 +54,14 @@ public:
void setCommand(const TQString& command);
void reset();
- void saveConfig();
void clearHistory();
virtual void show();
virtual TQSize sizeHint() const;
+public slots:
+ void saveConfig();
+
protected slots:
virtual void accept();
virtual void reject();
diff --git a/kdesu/kdesu/kdesu.cpp b/kdesu/kdesu/kdesu.cpp
index af2986b06..67ea55fe9 100644
--- a/kdesu/kdesu/kdesu.cpp
+++ b/kdesu/kdesu/kdesu.cpp
@@ -382,6 +382,7 @@ static int startApp()
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/kdesu/kdesud/kdesud.cpp b/kdesu/kdesud/kdesud.cpp
index 3e9462698..49006a401 100644
--- a/kdesu/kdesud/kdesud.cpp
+++ b/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/kdm/backend/client.c b/kdm/backend/client.c
index b2e7ebbc7..0807b2ce7 100644
--- a/kdm/backend/client.c
+++ b/kdm/backend/client.c
@@ -87,6 +87,18 @@ extern int loginsuccess( const char *User, const char *Host, const char *Tty, ch
#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
+
+#ifdef WITH_CONSOLE_KIT
+#include "consolekit.h"
+#endif
+
/*
* Session data, mostly what struct verify_info was for
*/
@@ -291,6 +303,56 @@ fail_delay( int retval ATTR_UNUSED, unsigned usec_delay ATTR_UNUSED,
{}
# 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 +411,8 @@ doPAMAuth( const char *psrv, struct pam_data *pdata )
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:
@@ -484,6 +548,9 @@ Verify( GConvFunc gconv, int rootok )
} else
psrv = PAMService;
pdata.usecur = TRUE;
+ } else if (!strcmp( curtype, "pam" )) {
+ psrv = PAMService;
+ pdata.usecur = FALSE;
} else {
sprintf( psrvb, "%.31s-%.31s", PAMService, curtype );
psrv = psrvb;
@@ -553,7 +620,7 @@ Verify( GConvFunc gconv, int rootok )
free( msg );
V_RET_FAIL( 0 );
}
- } else if (!strcmp( curtype, "generic" )) {
+ } else if (!strcmp( curtype, "generic" ) || !strcmp(curtype, "pam")) {
if (!gconv( GCONV_USER, 0 ))
return 0;
for (curret = 0;;) {
@@ -699,6 +766,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 */
}
@@ -735,6 +804,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 );
}
@@ -824,6 +895,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) {
@@ -858,6 +931,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;
}
@@ -917,6 +992,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;
}
@@ -927,6 +1004,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;
}
@@ -938,6 +1017,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();
@@ -1223,6 +1304,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 );
@@ -1232,6 +1315,11 @@ StartClient()
env = setEnv ( env, "XDG_SESSION_COOKIE", ck_session_cookie );
}
#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 );
@@ -1360,6 +1448,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();
diff --git a/kdm/config.def b/kdm/config.def
index ab1adac84..7bc39b36d 100644
--- a/kdm/config.def
+++ b/kdm/config.def
@@ -1985,6 +1985,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: ""
diff --git a/kdm/configure.in.in b/kdm/configure.in.in
index 4b6972178..da741e7f9 100644
--- a/kdm/configure.in.in
+++ b/kdm/configure.in.in
@@ -287,4 +287,75 @@ fi
AC_SUBST(DBUS_INCS)
AC_SUBST(DBUS_LIBS)
+########### 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)
+
+
+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/kdm/kfrontend/Makefile.am b/kdm/kfrontend/Makefile.am
index 5c5dfd61a..6d4fed27b 100644
--- a/kdm/kfrontend/Makefile.am
+++ b/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)
diff --git a/kdm/kfrontend/kdm_greet.c b/kdm/kfrontend/kdm_greet.c
index 53d164f45..b03d96e15 100644
--- a/kdm/kfrontend/kdm_greet.c
+++ b/kdm/kfrontend/kdm_greet.c
@@ -44,8 +44,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# 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
diff --git a/kdm/kfrontend/kdmadmindialog.cpp b/kdm/kfrontend/kdmadmindialog.cpp
new file mode 100644
index 000000000..637d6dd90
--- /dev/null
+++ b/kdm/kfrontend/kdmadmindialog.cpp
@@ -0,0 +1,176 @@
+ /*
+
+ Admin dialog
+
+ Copyright (C) 1997, 1998, 2000 Steffen Hansen <[email protected]>
+ Copyright (C) 2000-2003 Oswald Buddenhagen <[email protected]>
+
+
+ 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 <tqcombobox.h>
+#include <tqvbuttongroup.h>
+#include <tqstyle.h>
+#include <tqlayout.h>
+#include <tqaccel.h>
+#include <tqpopupmenu.h>
+
+int KDMAdmin::curPlugin = -1;
+PluginList KDMAdmin::pluginList;
+
+KDMAdmin::KDMAdmin( const TQString &user, TQWidget *_parent )
+ : inherited( _parent )
+ , verify( 0 ), curUser(user)
+{
+ TQSizePolicy fp( TQSizePolicy::Fixed, TQSizePolicy::Fixed );
+
+ TQVBoxLayout *box = new TQVBoxLayout( this, 10 );
+
+ TQHBoxLayout *hlay = new TQHBoxLayout( 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() );
+ TQAccel *accel = new TQAccel( this );
+ accel->insertItem( ALT+Key_A, 0 );
+ connect( accel, TQT_SIGNAL(activated(int)), TQT_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 TQHBoxLayout( box );
+ hlay->addStretch( 1 );
+ hlay->addWidget( okButton );
+ hlay->addStretch( 1 );
+ hlay->addWidget( cancelButton );
+ hlay->addStretch( 1 );
+
+ connect( okButton, TQT_SIGNAL(clicked()), TQT_SLOT(accept()) );
+ connect( cancelButton, TQT_SIGNAL(clicked()), TQT_SLOT(reject()) );
+
+ slotWhenChanged();
+}
+
+KDMAdmin::~KDMAdmin()
+{
+ hide();
+ delete verify;
+}
+
+void
+KDMAdmin::slotActivatePlugMenu()
+{
+ TQPopupMenu *cmnu = verify->getPlugMenu();
+ TQSize sh( cmnu->sizeHint() / 2 );
+ cmnu->exec( geometry().center() - TQPoint( 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 TQString & )
+{
+}
+
+
+#include "kdmadmindialog.moc"
diff --git a/kdm/kfrontend/kdmadmindialog.h b/kdm/kfrontend/kdmadmindialog.h
new file mode 100644
index 000000000..91f1ed3a6
--- /dev/null
+++ b/kdm/kfrontend/kdmadmindialog.h
@@ -0,0 +1,70 @@
+ /*
+
+ Shutdown dialog
+
+ Copyright (C) 1997, 1998 Steffen Hansen <[email protected]>
+ Copyright (C) 2000-2003 Oswald Buddenhagen <[email protected]>
+
+
+ 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 <tqradiobutton.h>
+
+class LiloInfo;
+class TQLabel;
+class KPushButton;
+class TQButtonGroup;
+class TQComboBox;
+
+class KDMAdmin : public FDialog, public KGVerifyHandler {
+ Q_OBJECT
+ typedef FDialog inherited;
+
+public:
+ KDMAdmin( const TQString &user, TQWidget *_parent = 0 );
+ ~KDMAdmin();
+
+public slots:
+ void accept();
+ void slotWhenChanged();
+ void slotActivatePlugMenu();
+
+private:
+ void bye_bye();
+
+ KPushButton *okButton, *cancelButton;
+ KGStdVerify *verify;
+ TQString 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 TQString &user );
+};
+
+#endif
diff --git a/kdm/kfrontend/kdmconfig.cpp b/kdm/kfrontend/kdmconfig.cpp
index 6f4c14031..15a63fa67 100644
--- a/kdm/kfrontend/kdmconfig.cpp
+++ b/kdm/kfrontend/kdmconfig.cpp
@@ -33,6 +33,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <unistd.h>
#include <sys/utsname.h>
+struct timeval st = {0, 0};
+
CONF_GREET_DEFS
TQString _stsFile;
diff --git a/kdm/kfrontend/kdmconfig.h b/kdm/kfrontend/kdmconfig.h
index f5420bcc4..52e054af6 100644
--- a/kdm/kfrontend/kdmconfig.h
+++ b/kdm/kfrontend/kdmconfig.h
@@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <tqstring.h>
#include <tqstringlist.h>
#include <tqfont.h>
+#include <sys/time.h>
extern TQString _stsFile;
extern bool _isLocal;
@@ -46,6 +47,19 @@ CONF_GREET_CPP_DECLS
struct dpySpec;
void decodeSess( dpySpec *sess, TQString &user, TQString &loc );
+extern struct timeval st;
+
+inline TQString timestamp() {
+ struct timeval nst;
+ gettimeofday(&nst, 0);
+ if (!st.tv_sec)
+ gettimeofday(&st, 0);
+
+ TQString 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 );
diff --git a/kdm/kfrontend/kfdialog.cpp b/kdm/kfrontend/kfdialog.cpp
index 62a4acb22..78359e237 100644
--- a/kdm/kfrontend/kfdialog.cpp
+++ b/kdm/kfrontend/kfdialog.cpp
@@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <klocale.h>
#include <kpushbutton.h>
#include <kstdguiitem.h>
+#include <kglobalsettings.h>
#include <tqlabel.h>
#include <tqlayout.h>
@@ -137,6 +138,9 @@ KFMsgBox::KFMsgBox( TQWidget *parent, TQMessageBox::Icon type, const TQString &t
TQLabel *label1 = new TQLabel( this );
label1->setPixmap( TQMessageBox::standardIcon( type ) );
TQLabel *label2 = new TQLabel( text, this );
+ TQRect 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( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Preferred ) );
diff --git a/kdm/kfrontend/kgapp.cpp b/kdm/kfrontend/kgapp.cpp
index 70b510645..50e65e916 100644
--- a/kdm/kfrontend/kgapp.cpp
+++ b/kdm/kfrontend/kgapp.cpp
@@ -36,6 +36,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <kcrash.h>
#include <kstandarddirs.h>
#include <ksimpleconfig.h>
+#include <klocale.h>
+#include <kdebug.h>
#include <tqtimer.h>
#include <tqstring.h>
@@ -133,6 +135,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 );
@@ -180,6 +183,7 @@ kg_main( const char *argv0 )
GSendInt( G_Ready );
+ kdDebug() << timestamp() << " main1" << endl;
setCursor( dpy, app.desktop()->winId(), XC_left_ptr );
for (;;) {
@@ -220,6 +224,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;
diff --git a/kdm/kfrontend/kgdialog.cpp b/kdm/kfrontend/kgdialog.cpp
index 1981eea83..f4ed918c6 100644
--- a/kdm/kfrontend/kgdialog.cpp
+++ b/kdm/kfrontend/kgdialog.cpp
@@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "kdm_greet.h"
#include <klocale.h>
+#include <kiconloader.h>
#include <tqaccel.h>
#include <tqlayout.h>
@@ -84,7 +85,8 @@ KGDialog::completeMenu()
inserten( i18n("Co&nsole Login"), ALT+Key_N, TQT_SLOT(slotConsole()) );
if (_allowShutdown != SHUT_NONE) {
- inserten( i18n("&Shutdown..."), ALT+Key_S, TQT_SLOT(slotShutdown( int )) );
+ ensureMenu();
+ optMenu->insertItem(SmallIconSet( "exit" ), i18n("&Shutdown..."), this, TQT_SLOT(slotShutdown(int)), ALT+Key_S );
TQAccel *accel = new TQAccel( this );
accel->insertItem( ALT+CTRL+Key_Delete );
connect( accel, TQT_SIGNAL(activated( int )), TQT_SLOT(slotShutdown( int )) );
diff --git a/kdm/kfrontend/kgreeter.cpp b/kdm/kfrontend/kgreeter.cpp
index ebd303525..74fc6b090 100644
--- a/kdm/kfrontend/kgreeter.cpp
+++ b/kdm/kfrontend/kgreeter.cpp
@@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#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"
@@ -38,6 +39,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <klistview.h>
#include <ksimpleconfig.h>
#include <kstringhandler.h>
+#include <kdebug.h>
#undef Unsorted // x headers suck - make tqdir.h work with --enable-final
#include <tqdir.h>
@@ -46,6 +48,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <tqmemarray.h>
#include <tqimage.h>
#include <tqmovie.h>
+#include <tqpainter.h>
#include <tqpopupmenu.h>
#include <tqtimer.h>
#include <tqheader.h>
@@ -57,6 +60,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <tqaccel.h>
#include <tqstring.h>
#include <tqeventloop.h>
+#include <tqbitmap.h>
#include <pwd.h>
#include <grp.h>
@@ -64,27 +68,46 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#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( TQWidget *parent = 0, const char *name = 0 )
+ UserListView( bool _them, TQWidget *parent = 0, const char *name = 0 )
: KListView( parent, name )
- , cachedSizeHint( -1, 0 )
+ , themed(_them), cachedSizeHint( -1, 0 )
{
setSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Ignored );
header()->hide();
addColumn( TQString::null );
setColumnAlignment( 0, AlignVCenter );
setResizeMode( TQListView::LastColumn );
+ if (themed) {
+ setBackgroundMode( Qt::NoBackground );
+ viewport()->setBackgroundMode( Qt::NoBackground );
+ setFrameStyle( TQFrame::NoFrame );
+ }
}
+ bool themed;
mutable TQSize cachedSizeHint;
- protected:
+ int sumHeight() const
+ {
+ int sum = 0;
+ for (TQListViewItem *itm = firstChild(); itm; itm = itm->nextSibling()) {
+ sum += itm->height();
+ }
+ return sum;
+ }
+public:
virtual TQSize sizeHint() const
{
+ if (themed)
+ return KListView::sizeHint();
+
if (!cachedSizeHint.isValid()) {
constPolish();
uint maxw = 0;
@@ -99,9 +122,24 @@ class UserListView : public KListView {
}
return cachedSizeHint;
}
+ virtual void paintEmptyArea ( TQPainter * p, const TQRect & rect )
+ {
+ if (!themed)
+ return KListView::paintEmptyArea(p, rect );
+
+ const TQPixmap *pm = paletteBackgroundPixmap();
+ if (!pm || pm->isNull())
+ return;
+
+ kdDebug() << "paintEmpty " << rect << endl;
+ TQRect devRect = p->xForm( rect );
+ kdDebug() << "paintEmpty2 " << devRect << endl;
+ p->drawPixmap(0, 0, *pm, devRect.left(), devRect.top() );
+ }
+
+ TQPixmap background;
};
-
int KGreeter::curPlugin = -1;
PluginList KGreeter::pluginList;
@@ -116,12 +154,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, TQT_SIGNAL(clicked( TQListViewItem * )),
TQT_SLOT(slotUserClicked( TQListViewItem * )) );
connect( userView, TQT_SIGNAL(doubleClicked( TQListViewItem * )),
@@ -129,10 +169,8 @@ KGreeter::KGreeter( bool framed )
}
if (_userCompletion)
userList = new TQStringList;
- if (userView || userList)
- insertUsers();
- sessMenu = new TQPopupMenu( this );
+ sessMenu = new TQPopupMenu( this );
connect( sessMenu, TQT_SIGNAL(activated( int )),
TQT_SLOT(slotSessionSelected( int )) );
insertSessions();
@@ -151,6 +189,33 @@ KGreeter::~KGreeter()
delete stsFile;
}
+void KGreeter::readFacesList()
+{
+ FILE *f = fopen( TQFile::encodeName( _faceDir + "/.randomlist" ), "rt" );
+ if ( !f )
+ return;
+ TQTextIStream is( f );
+ while ( !is.eof() )
+ {
+ TQString line = is.readLine().simplifyWhiteSpace();
+ if ( line.isEmpty() )
+ continue;
+ TQString icon;
+ int index = line.find( ' ' );
+ if ( index > 0 ) {
+ icon = line.left( index );
+ line = line.mid( index );
+ } else {
+ icon = line;
+ line = TQString::null;
+ }
+ randomFaces.push_back( icon );
+ TQStringList list = TQStringList::split( ' ', line );
+ for ( TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
+ randomFacesMap[*it] = icon;
+ }
+}
+
class UserListViewItem : public KListViewItem {
public:
UserListViewItem( UserListView *parent, const TQString &text,
@@ -164,6 +229,14 @@ class UserListViewItem : public KListViewItem {
parent->cachedSizeHint.setWidth( -1 );
}
+ virtual void paintCell(TQPainter *p, const TQColorGroup &cg, int column, int width, int alignment)
+ {
+ if (((UserListView*)listView())->themed)
+ TQListViewItem::paintCell(p, cg, column, width, alignment);
+ else
+ KListViewItem::paintCell(p, cg, column, width, alignment);
+ }
+
TQString login;
};
@@ -232,10 +305,23 @@ KGreeter::insertUser( const TQImage &default_pix,
TQSize ns( 48, 48 );
if (p.size() != ns)
p = p.convertDepth( 32 ).smoothScale( ns, TQImage::ScaleMin );
- goto gotit;
+ break;
} while (--nd >= 0);
- p = default_pix;
- gotit:
+
+ if ( p.isNull() && randomFaces.count() ) {
+ TQString randomFace = randomFacesMap[username];
+ if ( randomFace.isNull() ) {
+ TQStringList::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;
+
TQString realname = KStringHandler::from8Bit( ps->pw_gecos );
realname.truncate( realname.find( ',' ) );
if (realname.isEmpty() || realname == username)
@@ -289,7 +375,7 @@ UserList::UserList( char **in )
}
void
-KGreeter::insertUsers()
+KGreeter::insertUsers(int limit_users)
{
struct passwd *ps;
@@ -309,6 +395,8 @@ KGreeter::insertUsers()
if (_showUsers == SHOW_ALL) {
UserList noUsers( _noUsers );
TQDict<int> dupes( 1000 );
+ TQStringList toinsert;
+ int count = 0;
for (setpwent(); (ps = getpwent()) != 0;) {
if (*ps->pw_dir && *ps->pw_shell &&
(ps->pw_uid >= (unsigned)_lowUserId ||
@@ -320,10 +408,53 @@ KGreeter::insertUsers()
TQString username( TQFile::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 = TQStringList();
+ 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 ))
+ {
+ TQString username( TQFile::decodeName( ent->ut_user ) );
+ if (!dupes.find( username )) {
+ dupes.insert( username, (int *)-1 );
+ toinsert.append( username );
+ count++;
+ }
+ }
+
+
+ }
+ endutxent();
+ }
+
+ for ( TQStringList::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( TQFile::encodeName( *it ) );
+ if ( ps )
+ insertUser( default_pix, *it, ps );
+ }
} else {
UserList users( _users );
if (users.hasGroups()) {
@@ -379,7 +510,7 @@ KGreeter::insertSessions()
for (char **dit = _sessionsDirs; *dit; ++dit) {
TQStringList ents = TQDir( *dit ).entryList();
for (TQStringList::ConstIterator it = ents.begin(); it != ents.end(); ++it)
- if ((*it).endsWith( ".desktop" )) {
+ if ((*it).endsWith( ".desktop" ) && !(*it).endsWith("admin.desktop")) {
KSimpleConfig dsk( TQString( *dit ).append( '/' ).append( *it ) );
dsk.setGroup( "Desktop Entry" );
putSession( (*it).left( (*it).length() - 8 ),
@@ -517,6 +648,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 );
@@ -718,21 +860,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
@@ -826,6 +971,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" );
@@ -851,12 +999,8 @@ KThemedGreeter::KThemedGreeter()
if ((itm = themer->findNode( "session_button" ))) {
if (sessMenu->count() <= 1)
itm->hide( true );
- else {
+ else
session_button = itm;
- TQAccel *accel = new TQAccel( this );
- accel->insertItem( ALT+Key_T, 0 );
- connect( accel, TQT_SIGNAL(activated( int )), TQT_SLOT(slotSessMenu()) );
- }
} else {
if (sessMenu->count() > 1) {
inserten( i18n("Session &Type"), ALT+Key_T, sessMenu );
@@ -864,6 +1008,12 @@ KThemedGreeter::KThemedGreeter()
}
}
+ admin_button = themer->findNode( "admin_button");
+ if ( admin_button ) {
+ if ( !_useAdminSession )
+ admin_button->hide( true );
+ }
+
if (plugMenu) {
inserten( i18n("&Authentication Method"), ALT+Key_A, plugMenu );
needSep = true;
@@ -899,8 +1049,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();
@@ -916,12 +1066,17 @@ KThemedGreeter::verifyFailed()
{
// goButton->setEnabled( false );
inherited::verifyFailed();
+ if (userView)
+ userView->setEnabled(false);
}
void
KThemedGreeter::verifyRetry()
{
// goButton->setEnabled( true );
+ if (userView)
+ userView->setEnabled(true);
+
}
TQString KThemedGreeter::timedUser = TQString::null;
@@ -966,6 +1121,8 @@ KThemedGreeter::slotThemeActivated( const TQString &id )
slotSessMenu();
else if (id == "system_button")
slotActionMenu();
+ else if (id == "admin_button")
+ slotAskAdminPassword();
}
void
@@ -992,4 +1149,15 @@ KThemedGreeter::keyPressEvent( TQKeyEvent *e )
accept();
}
+void
+KThemedGreeter::slotAskAdminPassword()
+{
+ KDMAdmin k(curUser, this);
+ if (k.exec()) {
+ GSendInt(G_Ready);
+ hide();
+ done(ex_exit);
+ }
+}
+
#include "kgreeter.moc"
diff --git a/kdm/kfrontend/kgreeter.h b/kdm/kfrontend/kgreeter.h
index 61673badf..fdbd56209 100644
--- a/kdm/kfrontend/kgreeter.h
+++ b/kdm/kfrontend/kgreeter.h
@@ -73,9 +73,10 @@ class KGreeter : public KGDialog, public KGVerifyHandler {
void slotUserEntered();
protected:
+ void readFacesList();
void installUserList();
void insertUser( const TQImage &, const TQString &, struct passwd * );
- void insertUsers();
+ void insertUsers( int limit = -1);
void putSession( const TQString &, const TQString &, bool, const char * );
void insertSessions();
virtual void pluginSetup();
@@ -87,10 +88,13 @@ class KGreeter : public KGDialog, public KGVerifyHandler {
TQStringList *userList;
TQPopupMenu *sessMenu;
TQValueVector<SessType> sessionTypes;
+ TQStringList randomFaces;
+ TQMap<TQString, TQString> randomFacesMap;
int nNormals, nSpecials;
int curPrev, curSel;
bool prevValid;
bool needLoad;
+ bool themed;
static int curPlugin;
static PluginList pluginList;
@@ -142,6 +146,7 @@ class KThemedGreeter : public KGreeter {
void slotThemeActivated( const TQString &id );
void slotSessMenu();
void slotActionMenu();
+ void slotAskAdminPassword();
protected:
virtual void updateStatus( bool fail, bool caps, int timedleft );
@@ -154,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();
diff --git a/kdm/kfrontend/sessions/Makefile.am b/kdm/kfrontend/sessions/Makefile.am
index 14577ac42..71655c9a4 100644
--- a/kdm/kfrontend/sessions/Makefile.am
+++ b/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 \
diff --git a/kdm/kfrontend/sessions/admin.desktop b/kdm/kfrontend/sessions/admin.desktop
new file mode 100644
index 000000000..73e6ae3bf
--- /dev/null
+++ b/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
diff --git a/kdm/kfrontend/themer/kdmitem.cpp b/kdm/kfrontend/themer/kdmitem.cpp
index 38af9d0aa..d47c0242d 100644
--- a/kdm/kfrontend/themer/kdmitem.cpp
+++ b/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 <tqwidget.h>
#include <tqlayout.h>
#include <tqimage.h>
-#ifdef DRAW_OUTLINE
-# include <tqpainter.h>
-#endif
+#include <tqpainter.h>
KdmItem::KdmItem( KdmItem *parent, const TQDomNode &node, const char *name )
: TQObject( parent, name )
@@ -48,6 +47,25 @@ KdmItem::KdmItem( KdmItem *parent, const TQDomNode &node, const char *name )
, myLayoutItem( 0 )
, buttonParent( 0 )
{
+ init(node, name);
+}
+
+
+KdmItem::KdmItem( TQWidget *parent, const TQDomNode &node, const char *name )
+ : TQObject( parent, name )
+ , boxManager( 0 )
+ , fixedManager( 0 )
+ , image( 0 )
+ , myWidget( 0 )
+ , myLayoutItem( 0 )
+ , buttonParent( 0 )
+{
+ init(node, name);
+}
+
+void
+KdmItem::init( const TQDomNode &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 TQDomNode &node, const char *name )
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 TQDomNode &node, const char *name )
id = tnode.toElement().attribute( "id", TQString::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( TQWidget *widget )
if (frame)
frame->setFrameStyle( TQFrame::NoFrame );
- myWidget->setGeometry(area);
+ setGeometry(area, true);
connect( myWidget, TQT_SIGNAL(destroyed()), TQT_SLOT(widgetGone()) );
}
@@ -236,15 +254,21 @@ KdmItem::setGeometry( const TQRect &newGeometry, bool force )
area = newGeometry;
- if (myWidget)
- myWidget->setGeometry( newGeometry );
+ if (myWidget) {
+ TQRect 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( TQPainter *p, const TQRect &rect )
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" ) ) {
+ TQPixmap copy( myWidget->size() );
+ kdDebug() << myWidget->geometry() << " " << area << " " << myWidget->size() << endl;
+ bitBlt( &copy, TQPoint( 0, 0), p->device(), myWidget->geometry(), Qt::CopyROP );
+ myWidget->setPaletteBackgroundPixmap( copy );
+ }
+ return;
+ }
if (area.intersects( rect )) {
TQRect contentsRect = area.intersect( rect );
@@ -280,6 +312,8 @@ KdmItem::paint( TQPainter *p, const TQRect &rect )
TQValueList<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 TQRect &parentRect )
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 TQRect &parentRect )
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 TQRect &parentRect )
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 TQRect &parentRect )
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 TQRect &parentRect )
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 TQDomNode &node )
currentManager = MFixed;
}
+TQWidget *
+KdmItem::parentWidget() const
+{
+ if (myWidget)
+ return myWidget;
+ if (!this->parent())
+ return 0;
+
+ if (parent()->qt_cast("TQWidget"))
+ return (TQWidget*)parent();
+ return ((KdmItem*)parent())->parentWidget();
+}
+
#include "kdmitem.moc"
diff --git a/kdm/kfrontend/themer/kdmitem.h b/kdm/kfrontend/themer/kdmitem.h
index 6a73c889f..98b876977 100644
--- a/kdm/kfrontend/themer/kdmitem.h
+++ b/kdm/kfrontend/themer/kdmitem.h
@@ -90,6 +90,8 @@ public:
* Item constructor and destructor
*/
KdmItem( KdmItem *parent, const TQDomNode &node = TQDomNode(), const char *name = 0 );
+ KdmItem( TQWidget *parent, const TQDomNode &node = TQDomNode(), const char *name = 0 ); // for the root
+
virtual ~KdmItem();
/**
@@ -151,6 +153,7 @@ public:
KdmItem *findNode( const TQString &id ) const;
virtual void setWidget( TQWidget *widget );
+ TQWidget *widget() const { return myWidget; }
virtual void setLayoutItem( TQLayoutItem *item );
virtual void hide( bool force = false );
@@ -160,6 +163,9 @@ public:
bool isExplicitlyHidden() const { return isShown == ExplicitlyHidden; }
TQRect rect() const { return area; }
+ TQWidget *parentWidget() const;
+ TQString getId() const { return id; }
+
signals:
void needUpdate( int x, int y, int w, int h );
void activated( const TQString &id );
@@ -237,6 +243,7 @@ protected:
void parseColor( const TQString &, TQColor & );
void inheritFromButton( KdmItem *button );
+ void init( const TQDomNode &node = TQDomNode(), const char *name = 0 );
TQString itemType, id;
TQValueList<KdmItem *> m_children;
diff --git a/kdm/kfrontend/themer/kdmlabel.cpp b/kdm/kfrontend/themer/kdmlabel.cpp
index 297b7cc48..e83ae9dc7 100644
--- a/kdm/kfrontend/themer/kdmlabel.cpp
+++ b/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 <tqpainter.h>
#include <tqfontmetrics.h>
#include <tqtimer.h>
+#include <tqaccel.h>
#include <unistd.h>
#include <sys/utsname.h>
@@ -39,7 +42,7 @@
#endif
KdmLabel::KdmLabel( KdmItem *parent, const TQDomNode &node, const char *name )
- : KdmItem( parent, node, name )
+ : KdmItem( parent, node, name ), myAccel(0)
{
itemType = "label";
@@ -92,21 +95,46 @@ KdmLabel::KdmLabel( KdmItem *parent, const TQDomNode &node, const char *name )
}
}
- // 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 TQTimer( this );
timer->start( 1000 );
connect( timer, TQT_SIGNAL(timeout()), TQT_SLOT(update()) );
}
- cText = lookupText( label.text );
+ setTextInt( lookupText( label.text ) );
+}
+
+void
+KdmLabel::setTextInt( const TQString &txt)
+{
+ // TODO: catch &&
+ cText = txt;
+ cAccel = txt.find('&');
+ delete myAccel;
+ myAccel = 0;
+ if (cAccel != -1) {
+ cText.remove('&');
+ myAccel = new TQAccel(parentWidget());
+ myAccel->insertItem(ALT + UNICODE_ACCEL + cText.at(cAccel).lower().unicode());
+ connect(myAccel, TQT_SIGNAL(activated(int)), TQT_SLOT(slotAccel()));
+ }
+}
+
+void
+KdmLabel::slotAccel()
+{
+ if (buttonParent)
+ emit activated(buttonParent->getId());
+ else
+ emit activated(id);
}
void
KdmLabel::setText( const TQString &txt )
{
label.text = txt;
- update();
+ setTextInt( lookupText( label.text ) );
}
QSize
@@ -139,7 +167,23 @@ KdmLabel::drawContents( TQPainter *p, const TQRect &/*r*/ )
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) ) {
+ TQString left = cText.left(cAccel);
+ TQString right = cText.mid(cAccel + 1);
+ p->drawText( area, AlignLeft | SingleLine, left );
+ TQRect tarea = area;
+ TQFontMetrics fm(l->font);
+ tarea.rLeft() += fm.width(left);
+ TQFont f(l->font);
+ f.setUnderline(true);
+ p->setFont ( f );
+ p->drawText( tarea, AlignLeft | SingleLine, TQString(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()
{
TQString text = lookupText( label.text );
if (text != cText) {
- cText = text;
+ setTextInt(text);
needUpdate();
}
}
@@ -170,18 +214,20 @@ static const struct {
{ "language", I18N_NOOP("Language") },
{ "session", I18N_NOOP("Session Type") },
{ "system", I18N_NOOP("Menu") }, // i18n("Actions");
+ { "admin", I18N_NOOP("&Administration") },
{ "disconnect", I18N_NOOP("Disconnect") },
{ "quit", I18N_NOOP("Quit") },
- { "halt", I18N_NOOP("Power off") },
+ { "halt", I18N_NOOP("Power Off") },
{ "suspend", I18N_NOOP("Suspend") },
{ "reboot", I18N_NOOP("Reboot") },
{ "chooser", I18N_NOOP("XDMCP Chooser") },
{ "config", I18N_NOOP("Configure") },
- { "caps-lock-warning", I18N_NOOP("You have got caps lock on.") },
+ { "caps-lock-warning", I18N_NOOP("Caps Lock is enabled.") },
{ "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:") },
+ { "domain-label", I18N_NOOP("Domain:") },
{ "login", I18N_NOOP("Login") }
};
@@ -195,7 +241,7 @@ KdmLabel::lookupStock( const TQString &stock )
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 +251,6 @@ KdmLabel::lookupText( const TQString &t )
TQString text = t;
text.replace( '_', '&' );
-// text.remove( '_' ); // FIXME add key accels, remove underscores for now
TQMap<TQChar,TQString> m;
struct utsname uts;
diff --git a/kdm/kfrontend/themer/kdmlabel.h b/kdm/kfrontend/themer/kdmlabel.h
index 0770259c0..1ec2f88ec 100644
--- a/kdm/kfrontend/themer/kdmlabel.h
+++ b/kdm/kfrontend/themer/kdmlabel.h
@@ -50,6 +50,7 @@ protected:
// handle switching between normal / active / prelight configurations
virtual void statusChanged();
+public:
struct LabelStruct {
TQString text;
bool isTimer;
@@ -67,6 +68,7 @@ protected:
public slots:
void update();
+ void slotAccel();
private:
/* Method to lookup the caption associated with an item */
@@ -76,6 +78,10 @@ private:
TQString lookupText( const TQString &t );
TQString cText;
+ int cAccel;
+ TQAccel *myAccel;
+
+ void setTextInt(const TQString &);
};
#endif
diff --git a/kdm/kfrontend/themer/kdmlayout.cpp b/kdm/kfrontend/themer/kdmlayout.cpp
index 00ca693ae..b17d2e7b7 100644
--- a/kdm/kfrontend/themer/kdmlayout.cpp
+++ b/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 TQDomNode &/*node*/ )
void
KdmLayoutFixed::update( const TQRect &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 TQRect &parentGeometry, bool force )
childrenRect.setTop( childrenRect.top() + height + box.spacing );
} else {
TQRect 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 TQRect &parentGeometry, bool force )
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;
diff --git a/kdm/kfrontend/themer/kdmpixmap.cpp b/kdm/kfrontend/themer/kdmpixmap.cpp
index 07077e4a1..f18194f53 100644
--- a/kdm/kfrontend/themer/kdmpixmap.cpp
+++ b/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 <tqpainter.h>
#include <tqpixmap.h>
@@ -58,21 +60,28 @@ KdmPixmap::KdmPixmap( KdmItem *parent, const TQDomNode &node, const char *name )
TQString 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 TQRect &newGeometry, bool force )
}
-void
-KdmPixmap::loadPixmap( const TQString &fileName, TQPixmap &map, TQString &fullName )
+TQString
+KdmPixmap::fullPath( const TQString &fileName)
{
- if (fileName.isEmpty())
- return;
+ if (fileName.isEmpty())
+ return TQString::null;
- fullName = fileName;
+ TQString fullName = fileName;
if (fullName.at( 0 ) != '/')
fullName = baseDir() + "/" + fileName;
-
- if (!fullName.endsWith( ".svg" )) // we delay it for svgs
- if (!map.load( fullName ))
- fullName = TQString::null;
+ return fullName;
}
void
@@ -140,6 +146,25 @@ KdmPixmap::renderSvg( PixmapStruct::PixmapClass *pClass, const TQRect &area )
}
void
+KdmPixmap::loadPixmap( PixmapStruct::PixmapClass *pClass )
+{
+ TQString fullpath = pClass->fullpath;
+
+ kdDebug() << timestamp() << " load " << fullpath << endl;
+ int index = fullpath.findRev('.');
+ TQString ext = fullpath.right(fullpath.length() - index);
+ fullpath = fullpath.left(index);
+ kdDebug() << timestamp() << " ext " << ext << " " << fullpath << endl;
+ TQString testpath = TQString("-%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( TQPainter *p, const TQRect &r )
{
// choose the correct pixmap class
@@ -149,12 +174,20 @@ KdmPixmap::drawContents( TQPainter *p, const TQRect &r )
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( TQPainter *p, const TQRect &r )
if (pClass->readyPixmap.isNull()) {
- TQImage scaledImage;
+
+ bool haveTint = pClass->tint.rgb() != 0xFFFFFF;
+ bool haveAlpha = pClass->alpha < 1.0;
+ TQImage 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";
TQImage 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( TQPainter *p, const TQRect &r )
}
- 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 );
}
diff --git a/kdm/kfrontend/themer/kdmpixmap.h b/kdm/kfrontend/themer/kdmpixmap.h
index 479ef0f8d..92d4895d0 100644
--- a/kdm/kfrontend/themer/kdmpixmap.h
+++ b/kdm/kfrontend/themer/kdmpixmap.h
@@ -61,9 +61,10 @@ protected:
} pixmap;
private:
- // Method to load the pixmap given by the theme
- void loadPixmap( const TQString &fileName, TQPixmap &p, TQString &path );
+ // Method to load the pixmap path given by the theme
+ TQString fullPath( const TQString &fileName );
void renderSvg( PixmapStruct::PixmapClass *pClass, const TQRect &area );
+ void loadPixmap( PixmapStruct::PixmapClass *pClass );
};
#endif
diff --git a/kdm/kfrontend/themer/kdmrect.cpp b/kdm/kfrontend/themer/kdmrect.cpp
index 961809a37..1d854d213 100644
--- a/kdm/kfrontend/themer/kdmrect.cpp
+++ b/kdm/kfrontend/themer/kdmrect.cpp
@@ -33,6 +33,18 @@
KdmRect::KdmRect( KdmItem *parent, const TQDomNode &node, const char *name )
: KdmItem( parent, node, name )
{
+ init( node, name );
+}
+
+KdmRect::KdmRect( TQWidget *parent, const TQDomNode &node, const char *name )
+ : KdmItem( parent, node, name )
+{
+ init( node, name );
+}
+
+void
+KdmRect::init( const TQDomNode &node, const char * )
+{
itemType = "rect";
// Set default values for rect (note: strings are already Null)
@@ -137,13 +149,6 @@ KdmRect::recursiveSetAttribs( TQLayoutItem *li )
}
void
-KdmRect::setWidget( TQWidget *widget )
-{
- KdmItem::setWidget( widget );
- setAttribs( widget );
-}
-
-void
KdmRect::setLayoutItem( TQLayoutItem *item )
{
KdmItem::setLayoutItem( item );
@@ -151,4 +156,17 @@ KdmRect::setLayoutItem( TQLayoutItem *item )
}
*/
+void
+KdmRect::setWidget( TQWidget *widget )
+{
+ if ( rect.normal.color.isValid() && widget )
+ {
+ TQPalette p = widget->palette();
+ p.setColor( TQPalette::Normal, TQColorGroup::Text, rect.normal.color );
+ widget->setPalette(p);
+ }
+ KdmItem::setWidget( widget );
+ //setAttribs( widget );
+}
+
#include "kdmrect.moc"
diff --git a/kdm/kfrontend/themer/kdmrect.h b/kdm/kfrontend/themer/kdmrect.h
index 7e4776233..a505e1921 100644
--- a/kdm/kfrontend/themer/kdmrect.h
+++ b/kdm/kfrontend/themer/kdmrect.h
@@ -36,6 +36,7 @@ class KdmRect : public KdmItem {
public:
KdmRect( KdmItem *parent, const TQDomNode &node, const char *name = 0 );
+ KdmRect( TQWidget *parent, const TQDomNode &node, const char *name = 0 );
protected:
// draw the rect
@@ -54,8 +55,9 @@ protected:
bool hasBorder;
} rect;
-// virtual void setWidget( TQWidget *widget );
+ virtual void setWidget( TQWidget *widget );
// virtual void setLayoutItem( TQLayoutItem *item );
+ void init( const TQDomNode &node, const char *name );
private:
void setAttribs( TQWidget *widget );
diff --git a/kdm/kfrontend/themer/kdmthemer.cpp b/kdm/kfrontend/themer/kdmthemer.cpp
index aca43e45d..9e6db33db 100644
--- a/kdm/kfrontend/themer/kdmthemer.cpp
+++ b/kdm/kfrontend/themer/kdmthemer.cpp
@@ -36,11 +36,13 @@
#include <tqfile.h>
#include <tqfileinfo.h>
-//#include <tqtimer.h> // animation timer - TODO
+#include <tqtimer.h> // animation timer - TODO
#include <tqobjectlist.h>
#include <tqpainter.h>
#include <tqwidget.h>
#include <tqregion.h>
+#include <tqlineedit.h>
+#include <tqapplication.h>
#include <unistd.h>
@@ -72,7 +74,8 @@ KdmThemer::KdmThemer( const TQString &_filename, const TQString &mode, TQWidget
return;
}
// Set the root (screen) item
- rootItem = new KdmRect( 0, TQDomNode(), "kdm root" );
+ rootItem = new KdmRect( parent, TQDomNode(), "kdm root" );
+
connect( rootItem, TQT_SIGNAL(needUpdate( int, int, int, int )),
widget(), TQT_SLOT(update( int, int, int, int )) );
@@ -82,6 +85,9 @@ KdmThemer::KdmThemer( const TQString &_filename, const TQString &mode, TQWidget
generateItems( rootItem );
connect( rootItem, TQT_SIGNAL(activated( const TQString & )), TQT_SIGNAL(activated( const TQString & )) );
+ connect( rootItem, TQT_SIGNAL(activated( const TQString & )), TQT_SLOT(slotActivated( const TQString & )) );
+
+ TQTimer::singleShot(800, this, TQT_SLOT(slotPaintRoot()));
/* *TODO*
// Animation timer
@@ -151,7 +157,7 @@ KdmThemer::widgetEvent( TQEvent *e )
case TQEvent::Paint:
{
TQRect paintRect = static_cast<TQPaintEvent *>(e)->rect();
- kdDebug() << "paint on: " << paintRect << endl;
+ kdDebug() << timestamp() << " paint on: " << paintRect << endl;
if (!backBuffer)
backBuffer = new TQPixmap( widget()->size() );
@@ -195,7 +201,7 @@ KdmThemer::generateItems( KdmItem *parent, const TQDomNode &node )
// 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 *parent, const TQDomNode &node )
if (tagName == "item") {
if (!willDisplay( subnode ))
continue;
+ TQString 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
TQString type = el.attribute( "type" );
@@ -225,13 +238,11 @@ KdmThemer::generateItems( KdmItem *parent, const TQDomNode &node )
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 TQDomNode &node )
#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( TQObject *obj )
const TQObjectList *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++;
TQObjectListIterator it( *wlist );
@@ -323,7 +339,46 @@ KdmThemer::showStructure( TQObject *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 TQString &id )
+{
+ TQString 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();
+ TQLineEdit *le = (TQLineEdit*)item->widget()->qt_cast("TQLineEdit");
+ if (le)
+ le->selectAll();
+}
+
+void
+KdmThemer::slotPaintRoot()
+{
+ KdmItem *back_item = findNode("background");
+ if (!back_item)
+ return;
+
+ TQRect screen = TQApplication::desktop()->screenGeometry(0);
+ TQPixmap pm(screen.size());
+
+ TQPainter painter( &pm, true );
+ back_item->paint( &painter, back_item->rect());
+ painter.end();
+
+ TQApplication::desktop()->screen()->setErasePixmap(pm);
+ TQApplication::desktop()->screen()->erase();
}
#include "kdmthemer.moc"
diff --git a/kdm/kfrontend/themer/kdmthemer.h b/kdm/kfrontend/themer/kdmthemer.h
index 6bf6af00d..6dc2318dd 100644
--- a/kdm/kfrontend/themer/kdmthemer.h
+++ b/kdm/kfrontend/themer/kdmthemer.h
@@ -80,6 +80,10 @@ public:
signals:
void activated( const TQString &id );
+protected slots:
+ void slotActivated( const TQString &id );
+ void slotPaintRoot();
+
private:
/*
* Our display mode (e.g. console, remote, ...)
diff --git a/kdmlib/Makefile.am b/kdmlib/Makefile.am
index 91218a8c3..eedb681bc 100644
--- a/kdmlib/Makefile.am
+++ b/kdmlib/Makefile.am
@@ -1,11 +1,15 @@
AM_CPPFLAGS = -I$(top_srcdir)/kdm/kfrontend $(all_includes)
-kde_module_LTLIBRARIES = kgreet_classic.la kgreet_winbind.la
+kde_module_LTLIBRARIES = kgreet_classic.la kgreet_pam.la kgreet_winbind.la
kgreet_classic_la_SOURCES = kgreet_classic.cpp
kgreet_classic_la_LDFLAGS = -module -no-undefined $(KDE_PLUGIN) $(all_libraries)
kgreet_classic_la_LIBADD = $(LIB_KDEUI)
+kgreet_pam_la_SOURCES = kgreet_pam.cpp
+kgreet_pam_la_LDFLAGS = -module -no-undefined $(KDE_PLUGIN) $(all_libraries)
+kgreet_pam_la_LIBADD = $(LIB_KDEUI)
+
kgreet_winbind_la_SOURCES = kgreet_winbind.cpp
kgreet_winbind_la_LDFLAGS = -module -no-undefined $(KDE_PLUGIN) $(all_libraries)
kgreet_winbind_la_LIBADD = $(LIB_KDEUI)
diff --git a/kdmlib/kgreet_pam.cpp b/kdmlib/kgreet_pam.cpp
new file mode 100644
index 000000000..b43952488
--- /dev/null
+++ b/kdmlib/kgreet_pam.cpp
@@ -0,0 +1,668 @@
+/*
+
+Conversation widget for kdm greeter
+
+Copyright (C) 2008 Dirk Mueller <[email protected]>
+
+based on classic kdm greeter:
+
+ Copyright (C) 1997, 1998, 2000 Steffen Hansen <[email protected]>
+ Copyright (C) 2000-2003 Oswald Buddenhagen <[email protected]>
+
+
+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 "kgreet_pam.h"
+#include "themer/kdmthemer.h"
+#include "themer/kdmlabel.h"
+
+#include <klocale.h>
+#include <klineedit.h>
+#include <kpassdlg.h>
+#include <kuser.h>
+
+#include <tqregexp.h>
+#include <tqlayout.h>
+#include <tqlabel.h>
+#include <tqtimer.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <syslog.h>
+
+//#define PAM_GREETER_DEBUG
+
+class KDMPasswordEdit : public KPasswordEdit {
+public:
+ KDMPasswordEdit( TQWidget *parent ) : KPasswordEdit( parent, 0 ) {}
+ KDMPasswordEdit( KPasswordEdit::EchoModes echoMode, TQWidget *parent ) : KPasswordEdit( echoMode, parent, 0 ) {}
+protected:
+ virtual void contextMenuEvent( TQContextMenuEvent * ) {}
+};
+
+static FILE* log;
+static void debug(const char* fmt, ...)
+{
+ va_list lst;
+ va_start(lst, fmt);
+
+#ifdef PAM_GREETER_DEBUG
+#if 0
+ vfprintf(log, fmt, lst);
+ fflush(log);
+#else
+ char buf[6000];
+ sprintf(buf, "*** %s\n", fmt);
+ vsyslog(LOG_WARNING, buf, lst);
+#endif
+#endif
+ va_end(lst);
+}
+
+static KPasswordEdit::EchoModes echoMode;
+
+KPamGreeter::KPamGreeter( KGreeterPluginHandler *_handler,
+ KdmThemer *themer,
+ TQWidget *parent, TQWidget *pred,
+ const TQString &_fixedEntity,
+ Function _func, Context _ctx ) :
+ TQObject(),
+ KGreeterPlugin( _handler ),
+ fixedUser( _fixedEntity ),
+ func( _func ),
+ ctx( _ctx ),
+ exp( -1 ),
+ pExp( -1 ),
+ running( false )
+{
+ ctx = Login;
+
+ debug("KPamGreeter constructed\n");
+
+ m_parentWidget = parent;
+
+ KdmItem *user_entry = 0, *pw_entry = 0;
+ int line = 0;
+
+ layoutItem = 0;
+
+ if (themer &&
+ (!(user_entry = themer->findNode( "user-entry" )) ||
+ !(pw_entry = themer->findNode( "pw-entry" ))))
+ themer = 0;
+
+ m_themer = themer;
+
+ if (!themer)
+ layoutItem = new TQGridLayout( 0, 0, 10 );
+
+ loginLabel = 0;
+ authLabel.clear();
+ authEdit.clear();
+ loginLabel = 0;
+ loginEdit = 0;
+ if (ctx == ExUnlock || ctx == ExChangeTok)
+ fixedUser = KUser().loginName();
+ if (func != ChAuthTok) {
+ debug("func != ChAuthTok\n");
+ debug("fixedUser: *%s*\n", fixedUser.latin1());
+
+ if (fixedUser.isEmpty()) {
+ loginEdit = new KLineEdit( parent );
+ loginEdit->setContextMenuEnabled( false );
+ connect( loginEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotLoginLostFocus()) );
+ connect( loginEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotActivity()) );
+ connect( loginEdit, TQT_SIGNAL(textChanged( const TQString & )), TQT_SLOT(slotActivity()) );
+ connect( loginEdit, TQT_SIGNAL(selectionChanged()), TQT_SLOT(slotActivity()) );
+ if (pred) {
+ parent->setTabOrder( pred, loginEdit );
+ pred = loginEdit;
+ }
+ if (!getLayoutItem()) {
+ loginEdit->adjustSize();
+ user_entry->setWidget( loginEdit );
+ } else {
+ loginLabel = new TQLabel( loginEdit, i18n("Username:"), parent );
+ getLayoutItem()->addWidget( loginLabel, line, 0 );
+ getLayoutItem()->addWidget( loginEdit, line++, 1 );
+ }
+ } else if (ctx != Login && ctx != Shutdown && getLayoutItem()) {
+ loginLabel = new TQLabel( i18n("Username:"), parent );
+ getLayoutItem()->addWidget( loginLabel, line, 0 );
+ getLayoutItem()->addWidget( new TQLabel( fixedUser, parent ), line++, 1 );
+ }
+#if 0
+ if (echoMode == -1)
+ passwdEdit = new KDMPasswordEdit( parent );
+ else
+ passwdEdit = new KDMPasswordEdit( echoMode,
+ parent );
+ connect( passwdEdit, TQT_SIGNAL(textChanged( const TQString & )),
+ TQT_SLOT(slotActivity()) );
+ connect( passwdEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotActivity()) );
+ if (pred) {
+ parent->setTabOrder( pred, passwdEdit );
+ pred = passwdEdit;
+ }
+ if (!getLayoutItem()) {
+ passwdEdit->adjustSize();
+ pw_entry->setWidget( passwdEdit );
+ } else {
+ passwdLabel = new TQLabel( passwdEdit,
+ func == Authenticate ?
+ i18n("hello &Password:") :
+ i18n("Current &password:"),
+ parent );
+ getLayoutItem()->addWidget( passwdLabel, line, 0 );
+ getLayoutItem()->addWidget( passwdEdit, line++, 1 );
+ }
+#endif
+ if (loginEdit)
+ loginEdit->setFocus();
+ }
+ if (func != Authenticate) {
+ if (echoMode == -1) {
+ authEdit << new KDMPasswordEdit( echoMode, parent );
+ authEdit << new KDMPasswordEdit( echoMode, parent );
+ } else {
+ authEdit << new KDMPasswordEdit( parent );
+ authEdit << new KDMPasswordEdit( parent );
+ }
+ authLabel << new TQLabel( authEdit[0], i18n("&New password:"), parent );
+ authLabel << new TQLabel( authEdit[1], i18n("Con&firm password:"), parent );
+ if (pred) {
+ parent->setTabOrder( pred, authEdit[0] );
+ parent->setTabOrder( authEdit[0], authEdit[1] );
+ }
+ if (getLayoutItem()) {
+ getLayoutItem()->addWidget( authLabel[0], line, 0 );
+ getLayoutItem()->addWidget( authEdit[0], line++, 1 );
+ getLayoutItem()->addWidget( authLabel[1], line, 0 );
+ getLayoutItem()->addWidget( authEdit[1], line, 1 );
+ }
+ if (authEdit.size() >= 2)
+ authEdit[1]->setFocus();
+ }
+}
+
+// virtual
+KPamGreeter::~KPamGreeter()
+{
+ debug("KPamGreeter::~KPamGreeter");
+ abort();
+ if (!layoutItem) {
+ delete loginEdit;
+ return;
+ }
+ TQLayoutIterator it = static_cast<TQLayout *>(layoutItem)->iterator();
+ for (TQLayoutItem *itm = it.current(); itm; itm = ++it)
+ delete itm->widget();
+ delete layoutItem;
+ debug("destructor finished, good bye");
+}
+
+void // virtual
+KPamGreeter::loadUsers( const TQStringList &users )
+{
+ KCompletion *userNamesCompletion = new KCompletion;
+ userNamesCompletion->setItems( users );
+ loginEdit->setCompletionObject( userNamesCompletion );
+ loginEdit->setAutoDeleteCompletionObject( true );
+ loginEdit->setCompletionMode( KGlobalSettings::CompletionAuto );
+}
+
+void // virtual
+KPamGreeter::presetEntity( const TQString &entity, int field )
+{
+ debug("presetEntity(%s,%d) called!\n", entity.latin1(), field);
+ loginEdit->setText( entity );
+ if (field == 1 && authEdit.size() >= 1)
+ authEdit[0]->setFocus();
+ else {
+ loginEdit->setFocus();
+ loginEdit->selectAll();
+ if (field == -1 && authEdit.size() >= 1) {
+ authEdit[0]->setText( " " );
+ authEdit[0]->setEnabled( false );
+ authTok = false;
+ }
+ }
+ curUser = entity;
+}
+
+TQString // virtual
+KPamGreeter::getEntity() const
+{
+ return fixedUser.isEmpty() ? loginEdit->text() : fixedUser;
+}
+
+void // virtual
+KPamGreeter::setUser( const TQString &user )
+{
+ // assert( fixedUser.isEmpty() );
+ curUser = user;
+ loginEdit->setText( user );
+ if (authEdit.size() >= 1) {
+ authEdit[0]->setFocus();
+ authEdit[0]->selectAll();
+ }
+}
+
+void // virtual
+KPamGreeter::setEnabled(bool enable)
+{
+ // assert( !passwd1Label );
+ // assert( func == Authenticate && ctx == Shutdown );
+// if (loginLabel)
+// loginLabel->setEnabled( enable );
+ authEdit[0]->setEnabled( enable );
+ setActive( enable );
+ if (enable)
+ authEdit[0]->setFocus();
+ }
+
+void // private
+KPamGreeter::returnData()
+{
+ debug("*************** returnData called with exp %d\n", exp);
+
+
+ switch (exp) {
+ case 0:
+ handler->gplugReturnText( (loginEdit ? loginEdit->text() :
+ fixedUser).local8Bit(),
+ KGreeterPluginHandler::IsUser );
+ break;
+ case 1:
+ handler->gplugReturnText( authEdit[0]->password(),
+ KGreeterPluginHandler::IsPassword |
+ KGreeterPluginHandler::IsSecret );
+ break;
+ case 2:
+ handler->gplugReturnText( authEdit[1]->password(),
+ KGreeterPluginHandler::IsSecret );
+ break;
+ default: // case 3:
+ handler->gplugReturnText( authEdit[2]->password(),
+ KGreeterPluginHandler::IsNewPassword |
+ KGreeterPluginHandler::IsSecret );
+ break;
+ }
+}
+
+bool // virtual
+KPamGreeter::textMessage( const char *text, bool err )
+{
+ debug(" ************** textMessage(%s, %d)\n", text, err);
+
+ if (!authEdit.size())
+ return false;
+
+ if (getLayoutItem()) {
+ TQLabel* label = new TQLabel(TQString::fromUtf8(text), m_parentWidget);
+ getLayoutItem()->addWidget(label, state+1, 0, 0);
+ }
+
+ return true;
+}
+
+void // virtual
+KPamGreeter::textPrompt( const char *prompt, bool echo, bool nonBlocking )
+{
+ debug("textPrompt called with prompt %s echo %d nonBlocking %d", prompt, echo, nonBlocking);
+ debug("state is %d, authEdit.size is %d\n", state, authEdit.size());
+
+ if (state == 0 && echo) {
+ if (loginLabel)
+ loginLabel->setText(TQString::fromUtf8(prompt));
+ else if (m_themer) {
+ KdmLabel *kdmlabel = static_cast<KdmLabel*>(m_themer->findNode("user-label"));
+ if (kdmlabel) {
+ //userLabel->setText(TQString::fromUtf8(prompt));
+ kdmlabel->label.text = TQString::fromUtf8(prompt);
+ TQTimer::singleShot(0, kdmlabel, TQT_SLOT(update()));
+ }
+ }
+ }
+ else if (state >= authEdit.size()) {
+ if (getLayoutItem()) {
+ TQLabel* label = new TQLabel(TQString::fromUtf8(prompt), m_parentWidget);
+ getLayoutItem()->addWidget(label, state+1, 0, 0);
+ debug("added label widget to layout");
+ }
+ else if (m_themer) {
+ debug("themer found!");
+ KdmItem *pw_label = 0;
+
+ KdmLabel *kdmlabel = static_cast<KdmLabel*>(m_themer->findNode("pw-label"));
+ if (kdmlabel) {
+ //userLabel->setText(TQString::fromUtf8(prompt));
+ TQString str = TQString::fromUtf8(prompt);
+ kdmlabel->label.text = str;
+ TQTimer::singleShot(0, kdmlabel, TQT_SLOT(update()));
+ }
+ }
+
+ KDMPasswordEdit* passwdEdit;
+
+ if (echoMode == -1)
+ passwdEdit = new KDMPasswordEdit( m_parentWidget );
+ else
+ passwdEdit = new KDMPasswordEdit( echoMode, m_parentWidget);
+ connect( passwdEdit, TQT_SIGNAL(textChanged( const TQString & )),
+ TQT_SLOT(slotActivity()) );
+ connect( passwdEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotActivity()) );
+ authEdit << passwdEdit;
+
+#if 1
+ for(TQValueList<KPasswordEdit*>::iterator it = authEdit.begin();
+ it != authEdit.end();
+ ++it) {
+ if ((*it)->isEnabled() && (*it)->text().isEmpty()) {
+ (*it)->setFocus();
+ break;
+ }
+ }
+#endif
+ if (getLayoutItem())
+ getLayoutItem()->addWidget(passwdEdit, state+1, 1, 0);
+
+ if (m_themer) {
+ debug("themer found!");
+ KdmItem *pw_entry = 0;
+
+ pw_entry = m_themer->findNode("pw-entry");
+
+ if (pw_entry && passwdEdit)
+ pw_entry->setWidget(passwdEdit);
+
+ if (0) {
+ //userLabel->setText(TQString::fromUtf8(prompt));
+ //kdmlabel->label.text = TQString::fromUtf8(prompt);
+ //TQTimer::singleShot(0, kdmlabel, TQT_SLOT(update()));
+ }
+ }
+ else
+ debug("no themer found!");
+ }
+ ++state;
+ pExp = exp;
+
+ exp = authEdit.size();
+ debug("state %d exp: %d, has %d\n", state, exp, has);
+
+ if (has >= exp || nonBlocking)
+ returnData();
+}
+
+bool // virtual
+KPamGreeter::binaryPrompt( const char *, bool )
+{
+ // this simply cannot happen ... :}
+ return true;
+}
+
+void // virtual
+KPamGreeter::start()
+{
+ debug("******* start() called\n");
+
+ while(authEdit.begin() != authEdit.end()) {
+ KPasswordEdit* item = *authEdit.remove(authEdit.begin());
+ delete item;
+ }
+
+ while(authLabel.begin() != authLabel.end()) {
+ TQLabel* item = *authLabel.remove(authLabel.begin());
+ delete item;
+ }
+
+ authTok = !(authEdit.size() >= 2 && authEdit[1]->isEnabled());
+ exp = has = -1;
+ state = 0;
+ running = true;
+ handler->gplugStart();
+}
+
+void // virtual
+KPamGreeter::suspend()
+{
+}
+
+void // virtual
+KPamGreeter::resume()
+{
+}
+
+void // virtual
+KPamGreeter::next()
+{
+ debug("********* next() called state %d\n", state);
+
+ if (state == 0 && running && handler) {
+ debug(" **** returned text!\n");
+ handler->gplugReturnText( (loginEdit ? loginEdit->text() :
+ fixedUser).local8Bit(),
+ KGreeterPluginHandler::IsUser );
+ setActive(false);
+ }
+
+ has = 0;
+
+ for(TQValueList<KPasswordEdit*>::iterator it = authEdit.begin();
+ it != authEdit.end();
+ ++it) {
+
+ has++;
+ if ((*it)->hasFocus()) {
+ ++it;
+ if (it != authEdit.end())
+ (*it)->setFocus();
+ break;
+ }
+ if (it == authEdit.end())
+ has = -1;
+ }
+
+ debug(" has %d and exp %d\n", has, exp);
+
+#if 0
+ // assert( running );
+ if (loginEdit && loginEdit->hasFocus()) {
+ passwdEdit->setFocus(); // will cancel running login if necessary
+ has = 0;
+ } else if (passwdEdit && passwdEdit->hasFocus()) {
+ if (passwd1Edit)
+ passwd1Edit->setFocus();
+ has = 1;
+ } else if (passwd1Edit) {
+ if (passwd1Edit->hasFocus()) {
+ passwd2Edit->setFocus();
+ has = 1; // sic!
+ } else
+ has = 3;
+ } else
+ has = 1;
+ if (exp < 0)
+ handler->gplugStart();
+#endif
+ if (has >= exp)
+ returnData();
+}
+
+void // virtual
+KPamGreeter::abort()
+{
+ debug("***** abort() called\n");
+
+ running = false;
+ if (exp >= 0) {
+ exp = -1;
+ handler->gplugReturnText( 0, 0 );
+ }
+}
+
+void // virtual
+KPamGreeter::succeeded()
+{
+ debug("**** succeeded() called\n");
+
+ // assert( running || timed_login );
+ if (!authTok)
+ setActive( false );
+ else
+ setAllActive( false );
+ exp = -1;
+ running = false;
+}
+
+void // virtual
+KPamGreeter::failed()
+{
+ // assert( running || timed_login );
+ setActive( false );
+ setAllActive( false );
+ exp = -1;
+ running = false;
+}
+
+#include<assert.h>
+void // virtual
+KPamGreeter::revive()
+{
+ // assert( !running );
+ setAllActive( true );
+
+#if 1
+ if (authEdit.size() < 1)
+ return;
+#endif
+
+ assert(authEdit.size() >= 1);
+ if (authTok) {
+ authEdit[0]->erase();
+ if(authEdit.size() >= 2)
+ authEdit[1]->erase();
+ authEdit[0]->setFocus();
+ } else {
+ authEdit[0]->erase();
+ if (loginEdit && loginEdit->isEnabled())
+ authEdit[0]->setEnabled( true );
+ else {
+ setActive( true );
+ if (loginEdit && loginEdit->text().isEmpty())
+ loginEdit->setFocus();
+ else
+ authEdit[0]->setFocus();
+ }
+ }
+}
+
+void // virtual
+KPamGreeter::clear()
+{
+ // assert( !running && !passwd1Edit );
+ authEdit[0]->erase();
+ if (loginEdit) {
+ loginEdit->clear();
+ loginEdit->setFocus();
+ curUser = TQString::null;
+ } else
+ authEdit[0]->setFocus();
+}
+
+
+// private
+
+void
+KPamGreeter::setActive( bool enable )
+{
+ if (loginEdit)
+ loginEdit->setEnabled( enable );
+}
+
+void
+KPamGreeter::setAllActive( bool enable )
+{
+ for(TQValueList<KPasswordEdit*>::iterator it = authEdit.begin();
+ it != authEdit.end();
+ ++it)
+ (*it)->setEnabled( enable );
+}
+
+void
+KPamGreeter::slotLoginLostFocus()
+{
+ if (!running)
+ return;
+ if (exp > 0) {
+ if (curUser == loginEdit->text())
+ return;
+ exp = -1;
+ handler->gplugReturnText( 0, 0 );
+ }
+ curUser = loginEdit->text();
+ debug("curUser is %s", curUser.latin1());
+ handler->gplugSetUser( curUser );
+}
+
+void
+KPamGreeter::slotActivity()
+{
+ debug("slotActivity");
+
+ if (running)
+ handler->gplugActivity();
+}
+
+// factory
+
+static bool init( const TQString &,
+ TQVariant (*getConf)( void *, const char *, const TQVariant & ),
+ void *ctx )
+{
+ echoMode = (KPasswordEdit::EchoModes) getConf( ctx, "EchoMode", TQVariant( -1 ) ).toInt();
+ KGlobal::locale()->insertCatalogue( "kgreet_pam" );
+ return true;
+}
+
+static void done( void )
+{
+ KGlobal::locale()->removeCatalogue( "kgreet_pam" );
+ if (log && log != stderr)
+ fclose(log);
+ log = 0;
+}
+
+static KGreeterPlugin *
+create( KGreeterPluginHandler *handler, KdmThemer *themer,
+ TQWidget *parent, TQWidget *predecessor,
+ const TQString &fixedEntity,
+ KGreeterPlugin::Function func,
+ KGreeterPlugin::Context ctx )
+{
+ return new KPamGreeter( handler, themer, parent, predecessor, fixedEntity, func, ctx );
+}
+
+KDE_EXPORT kgreeterplugin_info kgreeterplugin_info = {
+ I18N_NOOP("Pam conversation plugin"), "pam",
+ kgreeterplugin_info::Local | kgreeterplugin_info::Presettable,
+ init, done, create
+};
+
+#include "kgreet_pam.moc"
diff --git a/kdmlib/kgreet_pam.h b/kdmlib/kgreet_pam.h
new file mode 100644
index 000000000..f0bea7d02
--- /dev/null
+++ b/kdmlib/kgreet_pam.h
@@ -0,0 +1,93 @@
+/*
+
+Conversation widget for kdm greeter
+
+Copyright (C) 2008 Dirk Mueller <[email protected]>
+
+
+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 KGREET_CLASSIC_H
+#define KGREET_CLASSIC_H
+
+#include "kgreeterplugin.h"
+
+#include <tqobject.h>
+#include <tqlayout.h>
+
+class KLineEdit;
+class KPasswordEdit;
+class KSimpleConfig;
+class TQGridLayout;
+class TQLabel;
+
+class KPamGreeter : public TQObject, public KGreeterPlugin {
+ Q_OBJECT
+
+ public:
+ KPamGreeter( KGreeterPluginHandler *handler,
+ KdmThemer *themer,
+ TQWidget *parent, TQWidget *predecessor,
+ const TQString &fixedEntitiy,
+ Function func, Context ctx );
+ ~KPamGreeter();
+ virtual void loadUsers( const TQStringList &users );
+ virtual void presetEntity( const TQString &entity, int field );
+ virtual TQString getEntity() const;
+ virtual void setUser( const TQString &user );
+ virtual void setEnabled( bool on );
+ virtual bool textMessage( const char *message, bool error );
+ virtual void textPrompt( const char *prompt, bool echo, bool nonBlocking );
+ virtual bool binaryPrompt( const char *prompt, bool nonBlocking );
+ virtual void start();
+ virtual void suspend();
+ virtual void resume();
+ virtual void next();
+ virtual void abort();
+ virtual void succeeded();
+ virtual void failed();
+ virtual void revive();
+ virtual void clear();
+
+ TQGridLayout *getLayoutItem() const { return static_cast<TQGridLayout*>(layoutItem); }
+
+ public slots:
+ void slotLoginLostFocus();
+ void slotActivity();
+
+ private:
+ void setActive( bool enable );
+ void setAllActive( bool enable );
+ void returnData();
+
+ TQLabel *loginLabel;
+ TQValueList<TQLabel*> authLabel;
+ KLineEdit *loginEdit;
+ TQWidget* m_parentWidget;
+ TQValueList<KPasswordEdit*> authEdit;
+ KSimpleConfig *stsFile;
+ KdmThemer *m_themer;
+ TQString fixedUser, curUser;
+ Function func;
+ Context ctx;
+ int exp, pExp, has;
+ unsigned state;
+ bool running, authTok;
+};
+
+#endif /* KGREET_CLASSIC_H */
diff --git a/khelpcenter/kcmhelpcenter.cpp b/khelpcenter/kcmhelpcenter.cpp
index c3b3e3094..aadce700a 100644
--- a/khelpcenter/kcmhelpcenter.cpp
+++ b/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()
+{
+ TQFileInfo currentDir( Prefs::indexDirectory() );
+ if ( !currentDir.isWritable() )
+ Prefs::setIndexDirectory( KGlobal::dirs()->saveLocation("data", "khelpcenter/index/") );
+}
#include "kcmhelpcenter.moc"
// vim:ts=2:sw=2:et
diff --git a/khelpcenter/kcmhelpcenter.h b/khelpcenter/kcmhelpcenter.h
index 4715d1a0a..8bf2f3b6c 100644
--- a/khelpcenter/kcmhelpcenter.h
+++ b/khelpcenter/kcmhelpcenter.h
@@ -146,6 +146,11 @@ class KCMHelpCenter : public KDialogBase, virtual public KCMHelpCenterIface
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/khelpcenter/navigator.cpp b/khelpcenter/navigator.cpp
index 48ae76dd0..ad308cfc6 100644
--- a/khelpcenter/navigator.cpp
+++ b/khelpcenter/navigator.cpp
@@ -120,8 +120,6 @@ Navigator::Navigator( View *view, TQWidget *parent, const char *name )
mTabWidget = new TQTabWidget( this );
topLayout->addWidget( mTabWidget );
- connect( mTabWidget, TQT_SIGNAL( currentChanged( TQWidget * ) ),
- TQT_SLOT( slotTabChanged( TQWidget * ) ) );
setupContentsTab();
setupGlossaryTab();
@@ -135,6 +133,9 @@ Navigator::Navigator( View *view, TQWidget *parent, const char *name )
mSearchWidget->updateScopeList();
mSearchWidget->readConfig( KGlobal::config() );
}
+
+ connect( mTabWidget, TQT_SIGNAL( currentChanged( QWidget * ) ),
+ TQT_SLOT( slotTabChanged( QWidget * ) ) );
}
Navigator::~Navigator()
@@ -336,6 +337,11 @@ void Navigator::selectItem( const KURL &url )
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/khelpcenter/searchhandlers/Makefile.am b/khelpcenter/searchhandlers/Makefile.am
index 65f4060b6..f2ebd57ff 100644
--- a/khelpcenter/searchhandlers/Makefile.am
+++ b/khelpcenter/searchhandlers/Makefile.am
@@ -3,7 +3,7 @@ searchhandlers_DATA = htdig.desktop man.desktop docbook.desktop
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/khelpcenter/searchhandlers/docbook.desktop b/khelpcenter/searchhandlers/docbook.desktop
index 08208c187..5c6d11284 100644
--- a/khelpcenter/searchhandlers/docbook.desktop
+++ b/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
diff --git a/khelpcenter/searchhandlers/khc_beagle_index.pl b/khelpcenter/searchhandlers/khc_beagle_index.pl
new file mode 100644
index 000000000..02f1b9330
--- /dev/null
+++ b/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);
+}
diff --git a/khelpcenter/searchhandlers/khc_beagle_search.pl b/khelpcenter/searchhandlers/khc_beagle_search.pl
new file mode 100644
index 000000000..d7a1f44b8
--- /dev/null
+++ b/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);
diff --git a/kicker/applets/systemtray/systemtrayapplet.cpp b/kicker/applets/systemtray/systemtrayapplet.cpp
index 933855f74..51bf2b9d8 100644
--- a/kicker/applets/systemtray/systemtrayapplet.cpp
+++ b/kicker/applets/systemtray/systemtrayapplet.cpp
@@ -189,6 +189,7 @@ bool SystemTrayApplet::x11Event( XEvent *e )
if( isWinManaged( (WId)e->xclient.data.l[2] ) ) // we already manage it
return true;
embedWindow( e->xclient.data.l[2], false );
+ updateVisibleWins();
layoutTray();
return true;
}
@@ -215,13 +216,12 @@ void SystemTrayApplet::preferences()
connect(m_settingsDialog, TQT_SIGNAL(finished()), this, TQT_SLOT(settingsDialogFinished()));
m_iconSelector = new KActionSelector(m_settingsDialog);
- m_iconSelector->setAvailableLabel(i18n("Visible icons:"));
- m_iconSelector->setSelectedLabel(i18n("Hidden icons:"));
- m_iconSelector->setShowUpDownButtons(false);
+ m_iconSelector->setAvailableLabel(i18n("Hidden icons:"));
+ m_iconSelector->setSelectedLabel(i18n("Visible icons:"));
m_settingsDialog->setMainWidget(m_iconSelector);
- TQListBox *shownListBox = m_iconSelector->availableListBox();
- TQListBox *hiddenListBox = m_iconSelector->selectedListBox();
+ TQListBox *hiddenListBox = m_iconSelector->availableListBox();
+ TQListBox *shownListBox = m_iconSelector->selectedListBox();
TrayEmbedList::const_iterator it = m_shownWins.begin();
TrayEmbedList::const_iterator itEnd = m_shownWins.end();
@@ -263,26 +263,48 @@ void SystemTrayApplet::applySettings()
}
KConfig *conf = config();
- conf->setGroup("HiddenTrayIcons");
- TQString name;
-
- // use the following snippet of code someday to implement ordering
- // of icons
- /*
- m_visibleIconList.clear();
- TQListBoxItem* item = m_iconSelector->availableListBox()->firstItem();
- for (; item; item = item->next())
+
+ // Save the sort order and hidden status using the window class (WM_CLASS) rather
+ // than window name (caption) - window name is i18n-ed, so it's for example
+ // not possible to create default settings.
+ // For backwards compatibility, name is kept as it is, class is preceded by '!'.
+ TQMap< TQString, TQString > windowNameToClass;
+ for( TrayEmbedList::ConstIterator it = m_shownWins.begin();
+ it != m_shownWins.end();
+ ++it ) {
+ KWin::WindowInfo info = KWin::windowInfo( (*it)->embeddedWinId(), NET::WMName, NET::WM2WindowClass);
+ windowNameToClass[ info.name() ] = '!' + info.windowClassClass();
+ }
+ for( TrayEmbedList::ConstIterator it = m_hiddenWins.begin();
+ it != m_hiddenWins.end();
+ ++it ) {
+ KWin::WindowInfo info = KWin::windowInfo( (*it)->embeddedWinId(), NET::WMName, NET::WM2WindowClass);
+ windowNameToClass[ info.name() ] = '!' + info.windowClassClass();
+ }
+
+ conf->setGroup("SortedTrayIcons");
+ m_sortOrderIconList.clear();
+ for(TQListBoxItem* item = m_iconSelector->selectedListBox()->firstItem();
+ item;
+ item = item->next())
{
- m_visibleIconList.append(item->text());
+ if( windowNameToClass.contains(item->text()))
+ m_sortOrderIconList.append(windowNameToClass[item->text()]);
+ else
+ m_sortOrderIconList.append(item->text());
}
- conf->writeEntry("Visible", m_visibleIconList);
- selection.clear();*/
+ conf->writeEntry("SortOrder", m_sortOrderIconList);
+ conf->setGroup("HiddenTrayIcons");
m_hiddenIconList.clear();
- TQListBoxItem* item = m_iconSelector->selectedListBox()->firstItem();
- for (; item; item = item->next())
+ for(TQListBoxItem* item = m_iconSelector->availableListBox()->firstItem();
+ item;
+ item = item->next())
{
- m_hiddenIconList.append(item->text());
+ if( windowNameToClass.contains(item->text()))
+ m_hiddenIconList.append(windowNameToClass[item->text()]);
+ else
+ m_hiddenIconList.append(item->text());
}
conf->writeEntry("Hidden", m_hiddenIconList);
conf->sync();
@@ -437,6 +459,9 @@ void SystemTrayApplet::loadSettings()
conf->setGroup("HiddenTrayIcons");
m_hiddenIconList = conf->readListEntry("Hidden");
+ conf->setGroup("SortedTrayIcons");
+ m_sortOrderIconList = conf->readListEntry("SortOrder");
+
//Note This setting comes from kdeglobal.
conf->setGroup("System Tray");
m_iconSize = conf->readNumEntry("systrayIconWidth", 22);
@@ -526,7 +551,9 @@ bool SystemTrayApplet::isWinManaged(WId w)
bool SystemTrayApplet::shouldHide(WId w)
{
- return m_hiddenIconList.find(KWin::windowInfo(w).name()) != m_hiddenIconList.end();
+ return m_hiddenIconList.find(KWin::windowInfo(w).name()) != m_hiddenIconList.end()
+ || m_hiddenIconList.find('!'+KWin::windowInfo(w,0,NET::WM2WindowClass).windowClassClass())
+ != m_hiddenIconList.end();
}
void SystemTrayApplet::updateVisibleWins()
@@ -549,6 +576,35 @@ void SystemTrayApplet::updateVisibleWins()
(*emb)->hide();
}
}
+
+ TQMap< QXEmbed*, TQString > names; // cache window names and classes
+ TQMap< QXEmbed*, TQString > classes;
+ for( TrayEmbedList::const_iterator it = m_shownWins.begin();
+ it != m_shownWins.end();
+ ++it ) {
+ KWin::WindowInfo info = KWin::windowInfo((*it)->embeddedWinId(),NET::WMName,NET::WM2WindowClass);
+ names[ *it ] = info.name();
+ classes[ *it ] = '!'+info.windowClassClass();
+ }
+ TrayEmbedList newList;
+ for( TQStringList::const_iterator it1 = m_sortOrderIconList.begin();
+ it1 != m_sortOrderIconList.end();
+ ++it1 ) {
+ for( TrayEmbedList::iterator it2 = m_shownWins.begin();
+ it2 != m_shownWins.end();
+ ) {
+ if( (*it1).startsWith("!") ? classes[ *it2 ] == *it1 : names[ *it2 ] == *it1 ) {
+ newList.append( *it2 ); // don't bail out, there may be multiple ones
+ it2 = m_shownWins.erase( it2 );
+ } else
+ ++it2;
+ }
+ }
+ for( TrayEmbedList::const_iterator it = m_shownWins.begin();
+ it != m_shownWins.end();
+ ++it )
+ newList.append( *it ); // append unsorted items
+ m_shownWins = newList;
}
void SystemTrayApplet::toggleExpanded()
diff --git a/kicker/applets/systemtray/systemtrayapplet.h b/kicker/applets/systemtray/systemtrayapplet.h
index a92b8f74e..f66e0caa5 100644
--- a/kicker/applets/systemtray/systemtrayapplet.h
+++ b/kicker/applets/systemtray/systemtrayapplet.h
@@ -98,6 +98,7 @@ private:
TrayEmbedList m_shownWins;
TrayEmbedList m_hiddenWins;
TQStringList m_hiddenIconList;
+ TQStringList m_sortOrderIconList;
KWinModule *kwin_module;
Atom net_system_tray_selection;
Atom net_system_tray_opcode;
diff --git a/kicker/data/kickoff/button-box-gradient-topdown.png b/kicker/data/kickoff/button-box-gradient-topdown.png
new file mode 100644
index 000000000..378816342
--- /dev/null
+++ b/kicker/data/kickoff/button-box-gradient-topdown.png
Binary files differ
diff --git a/kicker/data/kickoff/button-box-gradient.png b/kicker/data/kickoff/button-box-gradient.png
new file mode 100644
index 000000000..a7c11adba
--- /dev/null
+++ b/kicker/data/kickoff/button-box-gradient.png
Binary files differ
diff --git a/kicker/data/kickoff/button-box-left-corner.png b/kicker/data/kickoff/button-box-left-corner.png
new file mode 100644
index 000000000..c4080cb00
--- /dev/null
+++ b/kicker/data/kickoff/button-box-left-corner.png
Binary files differ
diff --git a/kicker/data/kickoff/button-box-left.png b/kicker/data/kickoff/button-box-left.png
new file mode 100644
index 000000000..3b532f8bd
--- /dev/null
+++ b/kicker/data/kickoff/button-box-left.png
Binary files differ
diff --git a/kicker/data/kickoff/button-box-right-corner.png b/kicker/data/kickoff/button-box-right-corner.png
new file mode 100644
index 000000000..ef44b1fab
--- /dev/null
+++ b/kicker/data/kickoff/button-box-right-corner.png
Binary files differ
diff --git a/kicker/data/kickoff/button-box-top.png b/kicker/data/kickoff/button-box-top.png
new file mode 100644
index 000000000..1cac298be
--- /dev/null
+++ b/kicker/data/kickoff/button-box-top.png
Binary files differ
diff --git a/kicker/data/kickoff/cr128-action-suspend2disk.png b/kicker/data/kickoff/cr128-action-suspend2disk.png
new file mode 100644
index 000000000..b3ac2fe05
--- /dev/null
+++ b/kicker/data/kickoff/cr128-action-suspend2disk.png
Binary files differ
diff --git a/kicker/data/kickoff/cr128-action-suspend2ram.png b/kicker/data/kickoff/cr128-action-suspend2ram.png
new file mode 100644
index 000000000..9e641bd47
--- /dev/null
+++ b/kicker/data/kickoff/cr128-action-suspend2ram.png
Binary files differ
diff --git a/kicker/data/kickoff/cr16-action-suspend2disk.png b/kicker/data/kickoff/cr16-action-suspend2disk.png
new file mode 100644
index 000000000..a28ab8ad9
--- /dev/null
+++ b/kicker/data/kickoff/cr16-action-suspend2disk.png
Binary files differ
diff --git a/kicker/data/kickoff/cr16-action-suspend2ram.png b/kicker/data/kickoff/cr16-action-suspend2ram.png
new file mode 100644
index 000000000..45738ccc5
--- /dev/null
+++ b/kicker/data/kickoff/cr16-action-suspend2ram.png
Binary files differ
diff --git a/kicker/data/kickoff/cr32-action-leave.png b/kicker/data/kickoff/cr32-action-leave.png
new file mode 100644
index 000000000..89dc15953
--- /dev/null
+++ b/kicker/data/kickoff/cr32-action-leave.png
Binary files differ
diff --git a/kicker/data/kickoff/cr32-action-suspend2disk.png b/kicker/data/kickoff/cr32-action-suspend2disk.png
new file mode 100644
index 000000000..7bcb027b1
--- /dev/null
+++ b/kicker/data/kickoff/cr32-action-suspend2disk.png
Binary files differ
diff --git a/kicker/data/kickoff/cr32-action-suspend2ram.png b/kicker/data/kickoff/cr32-action-suspend2ram.png
new file mode 100644
index 000000000..7a96cd24f
--- /dev/null
+++ b/kicker/data/kickoff/cr32-action-suspend2ram.png
Binary files differ
diff --git a/kicker/data/kickoff/cr48-action-leave.png b/kicker/data/kickoff/cr48-action-leave.png
new file mode 100644
index 000000000..7c01634b9
--- /dev/null
+++ b/kicker/data/kickoff/cr48-action-leave.png
Binary files differ
diff --git a/kicker/data/kickoff/cr48-action-suspend2disk.png b/kicker/data/kickoff/cr48-action-suspend2disk.png
new file mode 100644
index 000000000..9ff2148b8
--- /dev/null
+++ b/kicker/data/kickoff/cr48-action-suspend2disk.png
Binary files differ
diff --git a/kicker/data/kickoff/cr48-action-suspend2ram.png b/kicker/data/kickoff/cr48-action-suspend2ram.png
new file mode 100644
index 000000000..2aefa6ce4
--- /dev/null
+++ b/kicker/data/kickoff/cr48-action-suspend2ram.png
Binary files differ
diff --git a/kicker/data/kickoff/cr48-app-recently_used.png b/kicker/data/kickoff/cr48-app-recently_used.png
new file mode 100644
index 000000000..b97479759
--- /dev/null
+++ b/kicker/data/kickoff/cr48-app-recently_used.png
Binary files differ
diff --git a/kicker/data/kickoff/cr64-action-suspend2disk.png b/kicker/data/kickoff/cr64-action-suspend2disk.png
new file mode 100644
index 000000000..f6e57d786
--- /dev/null
+++ b/kicker/data/kickoff/cr64-action-suspend2disk.png
Binary files differ
diff --git a/kicker/data/kickoff/cr64-action-suspend2ram.png b/kicker/data/kickoff/cr64-action-suspend2ram.png
new file mode 100644
index 000000000..cdb47d04f
--- /dev/null
+++ b/kicker/data/kickoff/cr64-action-suspend2ram.png
Binary files differ
diff --git a/kicker/data/kickoff/crsc-action-leave.svgz b/kicker/data/kickoff/crsc-action-leave.svgz
new file mode 100644
index 000000000..b6a93b05c
--- /dev/null
+++ b/kicker/data/kickoff/crsc-action-leave.svgz
Binary files differ
diff --git a/kicker/data/kickoff/crsc-action-suspend2disk.svgz b/kicker/data/kickoff/crsc-action-suspend2disk.svgz
new file mode 100644
index 000000000..d73b491d9
--- /dev/null
+++ b/kicker/data/kickoff/crsc-action-suspend2disk.svgz
Binary files differ
diff --git a/kicker/data/kickoff/crsc-action-suspend2ram.svgz b/kicker/data/kickoff/crsc-action-suspend2ram.svgz
new file mode 100644
index 000000000..c38d2ed33
--- /dev/null
+++ b/kicker/data/kickoff/crsc-action-suspend2ram.svgz
Binary files differ
diff --git a/kicker/data/kickoff/kmenu_active.png b/kicker/data/kickoff/kmenu_active.png
new file mode 100644
index 000000000..fa5ae4de1
--- /dev/null
+++ b/kicker/data/kickoff/kmenu_active.png
Binary files differ
diff --git a/kicker/data/kickoff/kmenu_basic.mng b/kicker/data/kickoff/kmenu_basic.mng
new file mode 100644
index 000000000..4cea61fff
--- /dev/null
+++ b/kicker/data/kickoff/kmenu_basic.mng
Binary files differ
diff --git a/kicker/data/kickoff/kmenu_flipped.mng b/kicker/data/kickoff/kmenu_flipped.mng
new file mode 100644
index 000000000..2b78b4007
--- /dev/null
+++ b/kicker/data/kickoff/kmenu_flipped.mng
Binary files differ
diff --git a/kicker/data/kickoff/kmenu_vertical.mng b/kicker/data/kickoff/kmenu_vertical.mng
new file mode 100644
index 000000000..9cd3aac2b
--- /dev/null
+++ b/kicker/data/kickoff/kmenu_vertical.mng
Binary files differ
diff --git a/kicker/data/kickoff/left_triangle.png b/kicker/data/kickoff/left_triangle.png
new file mode 100644
index 000000000..b8ac404fd
--- /dev/null
+++ b/kicker/data/kickoff/left_triangle.png
Binary files differ
diff --git a/kicker/data/kickoff/main_border_bc.png b/kicker/data/kickoff/main_border_bc.png
new file mode 100644
index 000000000..05e497763
--- /dev/null
+++ b/kicker/data/kickoff/main_border_bc.png
Binary files differ
diff --git a/kicker/data/kickoff/main_border_lc.png b/kicker/data/kickoff/main_border_lc.png
new file mode 100644
index 000000000..c440e859e
--- /dev/null
+++ b/kicker/data/kickoff/main_border_lc.png
Binary files differ
diff --git a/kicker/data/kickoff/main_border_rc.png b/kicker/data/kickoff/main_border_rc.png
new file mode 100644
index 000000000..6cef8af01
--- /dev/null
+++ b/kicker/data/kickoff/main_border_rc.png
Binary files differ
diff --git a/kicker/data/kickoff/main_border_tc.png b/kicker/data/kickoff/main_border_tc.png
new file mode 100644
index 000000000..bc03e85dd
--- /dev/null
+++ b/kicker/data/kickoff/main_border_tc.png
Binary files differ
diff --git a/kicker/data/kickoff/main_corner_bl.png b/kicker/data/kickoff/main_corner_bl.png
new file mode 100644
index 000000000..32ea680f1
--- /dev/null
+++ b/kicker/data/kickoff/main_corner_bl.png
Binary files differ
diff --git a/kicker/data/kickoff/main_corner_br.png b/kicker/data/kickoff/main_corner_br.png
new file mode 100644
index 000000000..b2d898ab6
--- /dev/null
+++ b/kicker/data/kickoff/main_corner_br.png
Binary files differ
diff --git a/kicker/data/kickoff/main_corner_tl.png b/kicker/data/kickoff/main_corner_tl.png
new file mode 100644
index 000000000..11fe645ce
--- /dev/null
+++ b/kicker/data/kickoff/main_corner_tl.png
Binary files differ
diff --git a/kicker/data/kickoff/main_corner_tr.png b/kicker/data/kickoff/main_corner_tr.png
new file mode 100644
index 000000000..a439d9763
--- /dev/null
+++ b/kicker/data/kickoff/main_corner_tr.png
Binary files differ
diff --git a/kicker/data/kickoff/menu_separator.png b/kicker/data/kickoff/menu_separator.png
new file mode 100644
index 000000000..2ba13727d
--- /dev/null
+++ b/kicker/data/kickoff/menu_separator.png
Binary files differ
diff --git a/kicker/data/kickoff/resize_handle.png b/kicker/data/kickoff/resize_handle.png
new file mode 100644
index 000000000..c0811dc50
--- /dev/null
+++ b/kicker/data/kickoff/resize_handle.png
Binary files differ
diff --git a/kicker/data/kickoff/right_triangle.png b/kicker/data/kickoff/right_triangle.png
new file mode 100644
index 000000000..9766030c0
--- /dev/null
+++ b/kicker/data/kickoff/right_triangle.png
Binary files differ
diff --git a/kicker/data/kickoff/search-gradient-topdown.png b/kicker/data/kickoff/search-gradient-topdown.png
new file mode 100644
index 000000000..b13a19290
--- /dev/null
+++ b/kicker/data/kickoff/search-gradient-topdown.png
Binary files differ
diff --git a/kicker/data/kickoff/search-gradient.png b/kicker/data/kickoff/search-gradient.png
new file mode 100644
index 000000000..3478ea18b
--- /dev/null
+++ b/kicker/data/kickoff/search-gradient.png
Binary files differ
diff --git a/kicker/data/kickoff/search-running.mng b/kicker/data/kickoff/search-running.mng
new file mode 100644
index 000000000..9f477c9c3
--- /dev/null
+++ b/kicker/data/kickoff/search-running.mng
Binary files differ
diff --git a/kicker/data/kickoff/search-tab-center.png b/kicker/data/kickoff/search-tab-center.png
new file mode 100644
index 000000000..26ec2f2e9
--- /dev/null
+++ b/kicker/data/kickoff/search-tab-center.png
Binary files differ
diff --git a/kicker/data/kickoff/search-tab-left.png b/kicker/data/kickoff/search-tab-left.png
new file mode 100644
index 000000000..507b41767
--- /dev/null
+++ b/kicker/data/kickoff/search-tab-left.png
Binary files differ
diff --git a/kicker/data/kickoff/search-tab-right.png b/kicker/data/kickoff/search-tab-right.png
new file mode 100644
index 000000000..94a410443
--- /dev/null
+++ b/kicker/data/kickoff/search-tab-right.png
Binary files differ
diff --git a/kicker/data/kickoff/search-tab-top-center.png b/kicker/data/kickoff/search-tab-top-center.png
new file mode 100644
index 000000000..51482ad23
--- /dev/null
+++ b/kicker/data/kickoff/search-tab-top-center.png
Binary files differ
diff --git a/kicker/data/kickoff/search-tab-top-left.png b/kicker/data/kickoff/search-tab-top-left.png
new file mode 100644
index 000000000..97264782a
--- /dev/null
+++ b/kicker/data/kickoff/search-tab-top-left.png
Binary files differ
diff --git a/kicker/data/kickoff/search-tab-top-right.png b/kicker/data/kickoff/search-tab-top-right.png
new file mode 100644
index 000000000..fc80f40c2
--- /dev/null
+++ b/kicker/data/kickoff/search-tab-top-right.png
Binary files differ
diff --git a/kicker/data/kickoff/tab-bottom-left-topdown.png b/kicker/data/kickoff/tab-bottom-left-topdown.png
new file mode 100644
index 000000000..a96a7bf12
--- /dev/null
+++ b/kicker/data/kickoff/tab-bottom-left-topdown.png
Binary files differ
diff --git a/kicker/data/kickoff/tab-bottom-left.png b/kicker/data/kickoff/tab-bottom-left.png
new file mode 100644
index 000000000..fd8a34aca
--- /dev/null
+++ b/kicker/data/kickoff/tab-bottom-left.png
Binary files differ
diff --git a/kicker/data/kickoff/tab-bottom-right-topdown.png b/kicker/data/kickoff/tab-bottom-right-topdown.png
new file mode 100644
index 000000000..d1d80a6b3
--- /dev/null
+++ b/kicker/data/kickoff/tab-bottom-right-topdown.png
Binary files differ
diff --git a/kicker/data/kickoff/tab-bottom-right.png b/kicker/data/kickoff/tab-bottom-right.png
new file mode 100644
index 000000000..86d226b51
--- /dev/null
+++ b/kicker/data/kickoff/tab-bottom-right.png
Binary files differ
diff --git a/kicker/data/kickoff/tab-center-topdown.png b/kicker/data/kickoff/tab-center-topdown.png
new file mode 100644
index 000000000..c35438d91
--- /dev/null
+++ b/kicker/data/kickoff/tab-center-topdown.png
Binary files differ
diff --git a/kicker/data/kickoff/tab-center.png b/kicker/data/kickoff/tab-center.png
new file mode 100644
index 000000000..0ef1f6d34
--- /dev/null
+++ b/kicker/data/kickoff/tab-center.png
Binary files differ
diff --git a/kicker/data/kickoff/tab-left_center.png b/kicker/data/kickoff/tab-left_center.png
new file mode 100644
index 000000000..4c8c39794
--- /dev/null
+++ b/kicker/data/kickoff/tab-left_center.png
Binary files differ
diff --git a/kicker/data/kickoff/tab-right_center.png b/kicker/data/kickoff/tab-right_center.png
new file mode 100644
index 000000000..3df6564f4
--- /dev/null
+++ b/kicker/data/kickoff/tab-right_center.png
Binary files differ
diff --git a/kicker/data/kickoff/tab-top-left-topdown.png b/kicker/data/kickoff/tab-top-left-topdown.png
new file mode 100644
index 000000000..3df580e1d
--- /dev/null
+++ b/kicker/data/kickoff/tab-top-left-topdown.png
Binary files differ
diff --git a/kicker/data/kickoff/tab-top-left.png b/kicker/data/kickoff/tab-top-left.png
new file mode 100644
index 000000000..910967a18
--- /dev/null
+++ b/kicker/data/kickoff/tab-top-left.png
Binary files differ
diff --git a/kicker/data/kickoff/tab-top-right-topdown.png b/kicker/data/kickoff/tab-top-right-topdown.png
new file mode 100644
index 000000000..dd672cad9
--- /dev/null
+++ b/kicker/data/kickoff/tab-top-right-topdown.png
Binary files differ
diff --git a/kicker/data/kickoff/tab-top-right.png b/kicker/data/kickoff/tab-top-right.png
new file mode 100644
index 000000000..e96019d6d
--- /dev/null
+++ b/kicker/data/kickoff/tab-top-right.png
Binary files differ
diff --git a/kicker/kicker/ui/browser_mnu.cpp b/kicker/kicker/ui/browser_mnu.cpp
index 6802e6388..88ce30713 100644
--- a/kicker/kicker/ui/browser_mnu.cpp
+++ b/kicker/kicker/ui/browser_mnu.cpp
@@ -31,6 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <kfileitem.h>
#include <kglobal.h>
#include <kglobalsettings.h>
+#include <kconfig.h>
#include <kiconloader.h>
#include <kio/global.h>
#include <klocale.h>
@@ -148,12 +149,14 @@ void PanelBrowserMenu::initialize()
// only the first part menu got them
if(_startid == 0 && !_filesOnly) {
insertTitle(path());
+ KConfig *c = KGlobal::config();
+ c->setGroup("menus");
insertItem(CICON("kfm"), i18n("Open in File Manager"), this, TQT_SLOT(slotOpenFileManager()));
- if (kapp->authorize("shell_access"))
- insertItem(CICON("terminal"), i18n("Open in Terminal"), this, TQT_SLOT(slotOpenTerminal()));
+ if (kapp->authorize("shell_access") && c->readBoolEntry("kickerOpenInTerminalIsVisible",false))
+ insertItem(CICON("terminal"), i18n("Open in Terminal"), this, TQT_SLOT(slotOpenTerminal()));
+ insertSeparator();
}
-
bool first_entry = true;
bool dirfile_separator = false;
unsigned int item_count = 0;
diff --git a/kicker/kicker/ui/service_mnu.cpp b/kicker/kicker/ui/service_mnu.cpp
index fa18a7038..3042eddfe 100644
--- a/kicker/kicker/ui/service_mnu.cpp
+++ b/kicker/kicker/ui/service_mnu.cpp
@@ -114,6 +114,11 @@ void PanelServiceMenu::fillMenu(KServiceGroup::Ptr& _root,
TQStringList suppressGenericNames = _root->suppressGenericNames();
KServiceGroup::List::ConstIterator it = _list.begin();
+ KSortableValueList<KSharedPtr<KSycocaEntry>,TQCString> slist;
+ KSortableValueList<KSharedPtr<KSycocaEntry>,TQCString> glist;
+ TQMap<TQString,TQString> specialTitle;
+ TQMap<TQString,TQString> categoryIcon;
+
bool separatorNeeded = false;
for (; it != _list.end(); ++it)
{
@@ -121,19 +126,108 @@ void PanelServiceMenu::fillMenu(KServiceGroup::Ptr& _root,
if (e->isType(KST_KServiceGroup))
{
+ KServiceGroup::Ptr g(static_cast<KServiceGroup *>(e));
+ if ( KickerSettings::reduceMenuDepth() && g->SuSEshortMenu() ){
+ KServiceGroup::List l = g->entries(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));
+ TQString key;
+ if ( g->SuSEgeneralDescription() ) {
+ // we use the application name
+ key = s->name();
+ if( !s->genericName().isEmpty()) {
+ if (KickerSettings::menuEntryFormat() == KickerSettings::NameAndDescription)
+ key = s->name() + " (" + s->genericName() + ")";
+ else if (KickerSettings::menuEntryFormat() == KickerSettings::DescriptionAndName)
+ key = s->genericName() + " (" + s->name() + ")";
+ else if (KickerSettings::menuEntryFormat() == KickerSettings::DescriptionOnly)
+ key = s->genericName();
+ }
+ }
+ else {
+ // we use the normal menu description
+ key = s->name();
+ if( !s->genericName().isEmpty()) {
+ 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 );
+ // and escape from here
+ continue;
+ }
+ }
+ }
+ glist.insert( g->caption().local8Bit(), e );
+ }else if( e->isType(KST_KService)) {
+ KService::Ptr s(static_cast<KService *>(e));
+ TQString name = s->name();
+ if( !s->genericName().isEmpty()) {
+ if (KickerSettings::menuEntryFormat() == KickerSettings::NameAndDescription)
+ name = s->name() + " (" + s->genericName() + ")";
+ else if (KickerSettings::menuEntryFormat() == KickerSettings::DescriptionAndName)
+ name = s->genericName() + " (" + s->name() + ")";
+ else if (KickerSettings::menuEntryFormat() == KickerSettings::DescriptionOnly)
+ name = s->genericName();
+ }
+ slist.insert( name.local8Bit(), e );
+ } else
+ slist.insert( e->name().local8Bit(), e );
+ }
+
+ _list = _root->SuSEsortEntries( slist, glist, 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 ( KickerSettings::reduceMenuDepth() && g->SuSEshortMenu() ){
+ KServiceGroup::List l = g->entries(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));
+ if ( g->SuSEgeneralDescription() )
+ // we use the application name
+ insertMenuItem(s, id++, -1, 0, TQString::null, TQString::null, g->icon() );
+ else
+ // we use the normal menu description
+ insertMenuItem(s, id++, -1, 0, TQString::null, g->caption(), g->icon() );
+ // and escape from here */
+ continue;
+ // }
+ }
+ }
+ // standard sub menu
+
TQString groupCaption = g->caption();
-
+
// Avoid adding empty groups.
KServiceGroup::Ptr subMenuRoot = KServiceGroup::group(g->relPath());
-
+
int nbChildCount = subMenuRoot->childCount();
if (nbChildCount == 0 && !g->showEmptyMenu())
- {
+ {
continue;
- }
-
+ }
+
TQString inlineHeaderName = g->showInlineHeader() ? groupCaption : "";
// Item names may contain ampersands. To avoid them being converted
// to accelerators, replace them with two ampersands.
@@ -156,7 +250,8 @@ void PanelServiceMenu::fillMenu(KServiceGroup::Ptr& _root,
}
KService::Ptr s(static_cast<KService *>(e1));
- insertMenuItem(s, id++, -1, &suppressGenericNames);
+// insertMenuItem(s, id++, -1, &suppressGenericNames);
+ insertMenuItem(s, id++, -1, &suppressGenericNames, TQString::null, specialTitle[s->name()], categoryIcon[s->name()] );
continue;
}
}
@@ -222,7 +317,8 @@ void PanelServiceMenu::fillMenu(KServiceGroup::Ptr& _root,
KService::Ptr s(static_cast<KService *>(e));
searchMenuItems.insert(id);
- insertMenuItem(s, id++, -1, &suppressGenericNames);
+// insertMenuItem(s, id++, -1, &suppressGenericNames);
+ insertMenuItem(s, id++, -1, &suppressGenericNames, TQString::null, specialTitle[s->name()], categoryIcon[s->name()] );
}
else if (e->isType(KST_KServiceSeparator))
{
@@ -304,7 +400,8 @@ void PanelServiceMenu::configChanged()
void PanelServiceMenu::insertMenuItem(KService::Ptr & s, int nId,
int nIndex/*= -1*/,
const TQStringList *suppressGenericNames /* = 0 */,
- const TQString & aliasname)
+ const TQString & aliasname, const TQString & label /*=TQString::NULL*/,
+ const TQString & categoryIcon /*=TQString::null*/)
{
TQString serviceName = (aliasname.isEmpty() ? s->name() : aliasname).simplifyWhiteSpace();
TQString comment = s->genericName().simplifyWhiteSpace();
@@ -355,7 +452,15 @@ void PanelServiceMenu::insertMenuItem(KService::Ptr & s, int nId,
// to accelerators, replace them with two ampersands.
serviceName.replace("&", "&&");
- int newId = insertItem(KickerLib::menuIconSet(s->icon()), serviceName, nId, nIndex);
+ TQString icon = s->icon();
+ if (icon=="unknown")
+ icon = categoryIcon;
+
+ int newId;
+ if ( label.isEmpty() )
+ newId = insertItem(KickerLib::menuIconSet(s->icon()), serviceName, nId, nIndex);
+ else
+ newId = insertItem(KickerLib::menuIconSet(s->icon()), label, nId, nIndex);
entryMap_.insert(newId, static_cast<KSycocaEntry*>(s));
}
diff --git a/kicker/kicker/ui/service_mnu.h b/kicker/kicker/ui/service_mnu.h
index 193e4faf8..44e35a6c2 100644
--- a/kicker/kicker/ui/service_mnu.h
+++ b/kicker/kicker/ui/service_mnu.h
@@ -89,7 +89,8 @@ protected slots:
protected:
void insertMenuItem(KService::Ptr & s, int nId, int nIndex = -1,
const TQStringList *suppressGenericNames=0,
- const TQString &aliasname = TQString::null);
+ const TQString &aliasname = TQString::null,
+ const TQString &label = TQString::null, const TQString &categoryIcon = TQString::null);
virtual PanelServiceMenu * newSubMenu(const TQString & label,
const TQString & relPath,
TQWidget * parent, const char * name,
diff --git a/kicker/libkicker/kickerSettings.kcfg b/kicker/libkicker/kickerSettings.kcfg
index ff86c8431..6f7f2427e 100644
--- a/kicker/libkicker/kickerSettings.kcfg
+++ b/kicker/libkicker/kickerSettings.kcfg
@@ -126,6 +126,11 @@
<default>true</default>
</entry>
+<entry name="ReduceMenuDepth" type="Bool" >
+ <label>Simplify menus with only a single item inside</label>
+ <default>false</default>
+ </entry>
+
<entry name="MenuEntryHeight" type="Int" >
<label>Height of menu entries in pixels</label>
<default>0</default>
diff --git a/kioslave/media/mediaimpl.cpp b/kioslave/media/mediaimpl.cpp
index fb9e01480..b55b37e5d 100644
--- a/kioslave/media/mediaimpl.cpp
+++ b/kioslave/media/mediaimpl.cpp
@@ -281,6 +281,13 @@ bool MediaImpl::ensureMediumMounted(Medium &medium)
return m_lastErrorCode==0;
}
+ if (medium.id().isEmpty())
+ {
+ m_lastErrorCode = KIO::ERR_COULD_NOT_MOUNT;
+ m_lastErrorMessage = i18n("No such medium.");
+ return false;
+ }
+
return true;
}
diff --git a/kioslave/media/mediamanager/halbackend.cpp b/kioslave/media/mediamanager/halbackend.cpp
index b6763ee84..7b56d46ad 100644
--- a/kioslave/media/mediamanager/halbackend.cpp
+++ b/kioslave/media/mediamanager/halbackend.cpp
@@ -35,6 +35,7 @@
#include <kmountpoint.h>
#include <kmessagebox.h>
#include <kio/job.h>
+#include <kprotocolinfo.h>
#include <kstandarddirs.h>
#include <kprocess.h>
@@ -623,6 +624,13 @@ void HALBackend::setVolumeProperties(Medium* medium)
case LIBHAL_DRIVE_TYPE_PORTABLE_AUDIO_PLAYER:
{
medium->setIconName("ipod" + MOUNT_ICON_SUFFIX);
+
+ if (libhal_device_get_property_QString(m_halContext, driveUdi.latin1(), "info.product") == "iPod" &&
+ KProtocolInfo::isKnownProtocol( TQString("ipod") ) )
+ {
+ medium->unmountableState( "ipod:/" );
+ medium->mountableState( libhal_volume_is_mounted(halVolume) );
+ }
break;
}
case LIBHAL_DRIVE_TYPE_CAMERA:
diff --git a/kioslave/smb/kio_smb_auth.cpp b/kioslave/smb/kio_smb_auth.cpp
index d216e1e5b..d4a48239f 100644
--- a/kioslave/smb/kio_smb_auth.cpp
+++ b/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/kioslave/system/entries/documents.desktop b/kioslave/system/entries/documents.desktop
index 16016e0c5..a2c0fe528 100644
--- a/kioslave/system/entries/documents.desktop
+++ b/kioslave/system/entries/documents.desktop
@@ -1,7 +1,7 @@
[Desktop Entry]
Type=Link
Path[$e]=$( kio_system_documenthelper )
-Icon=folder_important
+Icon=folder_man
Name=Documents Folder
Name[af]=Dokument Gids
Name[ar]=مستنداتي
diff --git a/klipper/klipperrc.desktop b/klipper/klipperrc.desktop
index ba04cf594..5ad72c141 100644
--- a/klipper/klipperrc.desktop
+++ b/klipper/klipperrc.desktop
@@ -232,7 +232,7 @@ Number of commands=5
Regexp=^https?://.
[Action_1/Command_0]
-Commandline=kfmclient exec %s
+Commandline=kfmclient openURL %s
Description=Open with &Konqueror
Description[af]=Maak oop met Konqueror
Description[ar]=إفتح بــ &Konqueror
@@ -1644,7 +1644,7 @@ Number of commands=5
Regexp=^ftp://.
[Action_6/Command_0]
-Commandline=kfmclient exec %s
+Commandline=kfmclient openURL %s
Description=Open with &Konqueror
Description[af]=Maak oop met Konqueror
Description[ar]=إفتح بــ &Konqueror
diff --git a/konqueror/Makefile.am b/konqueror/Makefile.am
index 0fd86b2f5..116a7a915 100644
--- a/konqueror/Makefile.am
+++ b/konqueror/Makefile.am
@@ -48,8 +48,8 @@ noinst_HEADERS = KonqMainWindowIface.h KonqViewIface.h delayedinitializer.h \
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_LIBADD = ../libkonq/libkonq.la libkonqueror_intern.la $(LIBMALLOC) $(LIB_KUTILS)
+konqueror_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) -lconnectionmanager
+konqueror_la_LIBADD = ../libkonq/libkonq.la libkonqueror_intern.la $(LIBMALLOC) $(LIB_KUTILS) -lconnectionmanager
# Hmm, this experiment of a static konq failed, don't trust it...
# (but feel free to fix it :)
diff --git a/konqueror/konq_combo.cc b/konqueror/konq_combo.cc
index 86747ebde..0a73e6c83 100644
--- a/konqueror/konq_combo.cc
+++ b/konqueror/konq_combo.cc
@@ -128,6 +128,9 @@ KonqCombo::KonqCombo( TQWidget *parent, const char *name )
connect( this, TQT_SIGNAL(activated( const TQString& )),
TQT_SLOT(slotActivated( const TQString& )) );
+ setHistoryEditorEnabled( true );
+ connect( this, TQT_SIGNAL(removed( const TQString&) ), TQT_SLOT(slotRemoved( const TQString& )) );
+
if ( !kapp->dcopClient()->isAttached() )
kapp->dcopClient()->attach();
}
@@ -507,6 +510,15 @@ void KonqCombo::slotCleared()
kapp->dcopClient()->send( "konqueror*", "KonquerorIface", "comboCleared(TQCString)", data);
}
+void KonqCombo::slotRemoved( const TQString& item )
+{
+ TQByteArray data;
+ TQDataStream s( data, IO_WriteOnly );
+ s << item << kapp->dcopClient()->defaultObject();
+ kapp->dcopClient()->send( "konqueror*", "KonquerorIface",
+ "removeFromCombo(TQString,TQCString)", data);
+}
+
void KonqCombo::removeURL( const TQString& url )
{
setUpdatesEnabled( false );
diff --git a/konqueror/konq_combo.h b/konqueror/konq_combo.h
index dfb2778dc..3650eb9a4 100644
--- a/konqueror/konq_combo.h
+++ b/konqueror/konq_combo.h
@@ -87,6 +87,7 @@ signals:
private slots:
void slotCleared();
+ void slotRemoved( const TQString& item );
void slotSetIcon( int index );
void slotActivated( const TQString& text );
diff --git a/konqueror/konq_frame.cc b/konqueror/konq_frame.cc
index 77310ebbc..149a2f92d 100644
--- a/konqueror/konq_frame.cc
+++ b/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( KonqFrame *_parent, const char *_name )
m_progressBar->hide();
addWidget( m_progressBar, 0, true /*permanent->right align*/ );
+ StatusBarNetworkStatusIndicator * indicator = new StatusBarNetworkStatusIndicator( this, "networkstatusindicator" );
+ addWidget( indicator, 0, false );
+ indicator->init();
+
fontChange(TQFont());
installEventFilter( this );
}
diff --git a/konsole/other/x11r5.keytab b/konsole/other/x11r5.keytab
index 75ba06ec4..c731807ca 100644
--- a/konsole/other/x11r5.keytab
+++ b/konsole/other/x11r5.keytab
@@ -32,10 +32,10 @@ key Left -Shift : "\EOD"
key Enter : "\r"
-key Home : "\E[1~"
+key Home : "\E[H"
key Insert-Shift : "\E[2~"
key Delete : "\E[3~"
-key End : "\E[4~"
+key End : "\E[F"
key Prior -Shift : "\E[5~"
key Next -Shift : "\E[6~"
diff --git a/kscreensaver/Makefile.am b/kscreensaver/Makefile.am
index 75cf37640..2823d4e17 100644
--- a/kscreensaver/Makefile.am
+++ b/kscreensaver/Makefile.am
@@ -3,13 +3,13 @@
AM_CPPFLAGS = -UQT_NO_ASCII_CAST
-INCLUDES = $(all_includes)
+INCLUDES = $(GLINC) $(all_includes)
AM_LDFLAGS = $(all_libraries) $(KDE_RPATH)
bin_PROGRAMS = krandom.kss kblankscrn.kss
krandom_kss_SOURCES = random.cpp
-krandom_kss_LDADD = $(LIB_KDEUI) -lm
+krandom_kss_LDADD = $(LIB_KDEUI) $(GLLIB) -lm
kblankscrn_kss_SOURCES = blankscrn.cpp
kblankscrn_kss_LDADD = $(LIB_KDEUI) -lkscreensaver -lm
diff --git a/kscreensaver/random.cpp b/kscreensaver/random.cpp
index c1cd8dcad..cd984a145 100644
--- a/kscreensaver/random.cpp
+++ b/kscreensaver/random.cpp
@@ -1,4 +1,4 @@
-//-----------------------------------------------------------------------------
+ //-----------------------------------------------------------------------------
//
// Screen savers for KDE
//
@@ -19,6 +19,7 @@
#include <tqframe.h>
#include <tqcheckbox.h>
#include <tqwidget.h>
+#include <tqfileinfo.h>
#include <kapplication.h>
#include <kstandarddirs.h>
@@ -36,7 +37,7 @@
#define MAX_ARGS 20
-void usage(char *name)
+static void usage(char *name)
{
puts(i18n("Usage: %1 [-setup] [args]\n"
"Starts a random screen saver.\n"
@@ -60,6 +61,43 @@ static const KCmdLineOptions options[] =
//----------------------------------------------------------------------------
+#ifdef HAVE_GLXCHOOSEVISUAL
+#include <GL/glx.h>
+#endif
+
+//-------------------------------------
+bool hasDirectRendering () {
+ Display *dpy = TQApplication::desktop()->x11Display();
+
+#ifdef HAVE_GLXCHOOSEVISUAL
+ int attribSingle[] = {
+ GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ None
+ };
+ XVisualInfo* visinfo = glXChooseVisual (
+ dpy, TQApplication::desktop()->primaryScreen(), attribSingle
+ );
+ if (visinfo) {
+ GLXContext ctx = glXCreateContext ( dpy, visinfo, NULL, True );
+ if (glXIsDirect(dpy, ctx)) {
+ glXDestroyContext (dpy,ctx);
+ return true;
+ }
+ glXDestroyContext (dpy,ctx);
+ return false;
+ } else {
+ return false;
+ }
+#else
+#error no GL?
+ return false;
+#endif
+
+}
+
int main(int argc, char *argv[])
{
KLocale::setMainCatalogue("kscreensaver");
@@ -103,55 +141,63 @@ int main(int argc, char *argv[])
KConfig type("krandom.kssrc");
type.setGroup("Settings");
- bool opengl = type.readBoolEntry("OpenGL");
+ bool opengl = type.readBoolEntry("OpenGL", hasDirectRendering());
+ kdDebug() << "hasOPEN " << opengl << endl;
bool manipulatescreen = type.readBoolEntry("ManipulateScreen");
bool fortune = !KStandardDirs::findExe("fortune").isEmpty();
+ TQStringList defaults = type.readListEntry( "Defaults" );
+ TQMap<TQString, int> def_numbers;
+ for ( TQStringList::ConstIterator it = defaults.begin(); it != defaults.end(); ++it ) {
+ int index = ( *it ).find( ':' );
+ if ( index == -1 )
+ def_numbers[*it] = 1;
+ else
+ def_numbers[( *it ).left( index )] = ( *it ).mid( index + 1 ).toInt();
+ }
for (uint i = 0; i < tempSaverFileList.count(); i++)
{
- kdDebug() << "Looking at " << tempSaverFileList[i] << endl;
+ int howoften = 1;
+ if ( defaults.count() != 0 ) {
+ TQFileInfo fi( tempSaverFileList[i] );
+ if ( def_numbers.contains( fi.fileName() ) )
+ howoften = def_numbers[fi.fileName()];
+ else
+ howoften = 0;
+ }
+
KDesktopFile saver(tempSaverFileList[i], true);
- if(!saver.tryExec())
- continue;
- kdDebug() << "read X-KDE-Type" << endl;
+ if (!saver.tryExec())
+ continue;
TQString saverType = saver.readEntry("X-KDE-Type");
-
- if (saverType.isEmpty()) // no X-KDE-Type defined so must be OK
- {
- saverFileList.append(tempSaverFileList[i]);
- }
- else
- {
+ if (!saverType.isEmpty()) // no X-KDE-Type defined so must be OK
+ {
TQStringList saverTypes = TQStringList::split(";", saverType);
for (TQStringList::ConstIterator it = saverTypes.begin(); it != saverTypes.end(); ++it )
{
- kdDebug() << "saverTypes is "<< *it << endl;
if (*it == "ManipulateScreen")
{
- if (manipulatescreen)
- {
- saverFileList.append(tempSaverFileList[i]);
- }
+ if (!manipulatescreen)
+ howoften = 0;
}
else
if (*it == "OpenGL")
{
- if (opengl)
- {
- saverFileList.append(tempSaverFileList[i]);
- }
+ if (!opengl)
+ howoften = 0;
}
if (*it == "Fortune")
{
- if (fortune)
- {
- saverFileList.append(tempSaverFileList[i]);
- }
+ if (!fortune)
+ howoften = 0;
}
}
}
+ for ( int j = 0; j < howoften; ++j )
+ saverFileList.append(tempSaverFileList[i]);
}
+ kdDebug() << "final " << saverFileList << endl;
KRandomSequence rnd;
int indx = rnd.getLong(saverFileList.count());
@@ -229,7 +275,7 @@ KRandomSetup::KRandomSetup( TQWidget *parent, const char *name )
KConfig config("krandom.kssrc");
config.setGroup("Settings");
- openGL->setChecked(config.readBoolEntry("OpenGL", true));
+ openGL->setChecked(config.readBoolEntry("OpenGL", hasDirectRendering()));
manipulateScreen->setChecked(config.readBoolEntry("ManipulateScreen", true));
}
diff --git a/ksmserver/KSMServerInterface.h b/ksmserver/KSMServerInterface.h
index 52fdf0942..a628b92ba 100644
--- a/ksmserver/KSMServerInterface.h
+++ b/ksmserver/KSMServerInterface.h
@@ -22,6 +22,8 @@ k_dcop:
virtual void suspendStartup( TQCString ) = 0;
virtual void resumeStartup( TQCString ) = 0;
+
+ virtual void logoutTimed( int, int, TQString ) = 0;
};
#endif
diff --git a/ksmserver/Makefile.am b/ksmserver/Makefile.am
index 62f9d8976..19b328bc5 100644
--- a/ksmserver/Makefile.am
+++ b/ksmserver/Makefile.am
@@ -28,7 +28,7 @@ ksmserver_la_METASOURCES = AUTO
# Order is important for --enable-final!
ksmserver_la_SOURCES = main.cpp server.cpp shutdowndlg.cpp \
legacy.cpp startup.cpp shutdown.cpp client.cpp \
- KSMServerInterface.skel server.skel
+ KSMServerInterface.skel server.skel timed.ui
ksmserver_la_LDFLAGS = $(all_libraries) -avoid-version -module
ksmserver_la_LIBADD = ../kdmlib/libdmctl.la $(LIB_KDEUI) $(HAL_LIBS) $(DBUS_LIBS)
@@ -42,7 +42,7 @@ updatedir = $(kde_datadir)/kconf_update
EXTRA_PROGRAMS = testsh
-testsh_SOURCES = test.cpp
+testsh_SOURCES = test.cpp timed.ui
testsh_LDFLAGS = $(all_libraries) $(KDE_RPATH)
testsh_LDADD = $(LIB_KDEUI) shutdowndlg.lo ../kdmlib/libdmctl.la $(HAL_LIBS) $(DBUS_LIBS)
diff --git a/ksmserver/server.h b/ksmserver/server.h
index 3d5904e53..0fc900042 100644
--- a/ksmserver/server.h
+++ b/ksmserver/server.h
@@ -85,6 +85,7 @@ public:
// public API
void restoreSession( TQString sessionName );
void startDefaultSession();
+
void shutdown( KApplication::ShutdownConfirm confirm,
KApplication::ShutdownType sdtype,
KApplication::ShutdownMode sdmode );
@@ -92,6 +93,11 @@ public:
virtual void suspendStartup( TQCString app );
virtual void resumeStartup( TQCString app );
+ bool checkStatus( bool &logoutConfirmed, bool &maysd,
+ KApplication::ShutdownConfirm confirm,
+ KApplication::ShutdownType sdtype,
+ KApplication::ShutdownMode sdmode );
+
public slots:
void cleanUp();
@@ -142,6 +148,11 @@ private:
bool defaultSession() const; // empty session
void setupXIOErrorHandler();
+ void shutdownInternal( KApplication::ShutdownConfirm confirm,
+ KApplication::ShutdownType sdtype,
+ KApplication::ShutdownMode sdmode,
+ TQString bootOption = TQString::null );
+
void performLegacySessionSave();
void storeLegacySession( KConfig* config );
void restoreLegacySession( KConfig* config );
@@ -157,6 +168,7 @@ private:
// public dcop interface
void logout( int, int, int );
+ virtual void logoutTimed( int, int, TQString );
TQStringList sessionList();
TQString currentSession();
void saveCurrentSession();
diff --git a/ksmserver/shutdown.cpp b/ksmserver/shutdown.cpp
index 16fab8b4d..a850d40be 100644
--- a/ksmserver/shutdown.cpp
+++ b/ksmserver/shutdown.cpp
@@ -93,14 +93,16 @@ void KSMServer::logout( int confirm, int sdtype, int sdmode )
(KApplication::ShutdownMode)sdmode );
}
-void KSMServer::shutdown( KApplication::ShutdownConfirm confirm,
- KApplication::ShutdownType sdtype, KApplication::ShutdownMode sdmode )
+bool KSMServer::checkStatus( bool &logoutConfirmed, bool &maysd,
+ KApplication::ShutdownConfirm confirm,
+ KApplication::ShutdownType sdtype,
+ KApplication::ShutdownMode sdmode )
{
pendingShutdown.stop();
if( dialogActive )
- return;
+ return false;
if( state >= Shutdown ) // already performing shutdown
- return;
+ return false;
if( state != Idle ) // performing startup
{
// perform shutdown as soon as startup is finished, in order to avoid saving partial session
@@ -111,25 +113,44 @@ void KSMServer::shutdown( KApplication::ShutdownConfirm confirm,
pendingShutdown_sdtype = sdtype;
pendingShutdown_sdmode = sdmode;
}
- return;
+ return false;
}
KConfig *config = KGlobal::config();
config->reparseConfiguration(); // config may have changed in the KControl module
config->setGroup("General" );
- bool logoutConfirmed =
+ logoutConfirmed =
(confirm == KApplication::ShutdownConfirmYes) ? false :
- (confirm == KApplication::ShutdownConfirmNo) ? true :
- !config->readBoolEntry( "confirmLogout", true );
- bool maysd = false;
+ (confirm == KApplication::ShutdownConfirmNo) ? true :
+ !config->readBoolEntry( "confirmLogout", true );
+ maysd = false;
if (config->readBoolEntry( "offerShutdown", true ) && DM().canShutdown())
maysd = true;
if (!maysd) {
if (sdtype != KApplication::ShutdownTypeNone &&
sdtype != KApplication::ShutdownTypeDefault &&
logoutConfirmed)
- return; /* unsupported fast shutdown */
+ return false; /* unsupported fast shutdown */
+ }
+
+ return true;
+}
+
+void KSMServer::shutdownInternal( KApplication::ShutdownConfirm confirm,
+ KApplication::ShutdownType sdtype,
+ KApplication::ShutdownMode sdmode,
+ TQString bopt )
+{
+ bool maysd = false;
+ bool logoutConfirmed = false;
+ if ( !checkStatus( logoutConfirmed, maysd, confirm, sdtype, sdmode ) )
+ return;
+
+ KConfig *config = KGlobal::config();
+
+ config->setGroup("General" );
+ if (!maysd) {
sdtype = KApplication::ShutdownTypeNone;
} else if (sdtype == KApplication::ShutdownTypeDefault)
sdtype = (KApplication::ShutdownType)
@@ -138,7 +159,6 @@ void KSMServer::shutdown( KApplication::ShutdownConfirm confirm,
sdmode = KApplication::ShutdownModeInteractive;
dialogActive = true;
- TQString bopt;
if ( !logoutConfirmed ) {
KSMShutdownFeedback::start(); // make the screen gray
logoutConfirmed =
@@ -204,6 +224,42 @@ void KSMServer::shutdown( KApplication::ShutdownConfirm confirm,
dialogActive = false;
}
+void KSMServer::shutdown( KApplication::ShutdownConfirm confirm,
+ KApplication::ShutdownType sdtype, KApplication::ShutdownMode sdmode )
+{
+ shutdownInternal( confirm, sdtype, sdmode );
+}
+
+#include <kmessagebox.h>
+
+void KSMServer::logoutTimed( int sdtype, int sdmode, TQString bootOption )
+{
+ int confirmDelay;
+
+ KConfig* config = KGlobal::config();
+ config->setGroup( "General" );
+
+ if ( sdtype == KApplication::ShutdownTypeHalt )
+ confirmDelay = config->readNumEntry( "confirmShutdownDelay", 31 );
+ else if ( sdtype == KApplication::ShutdownTypeReboot )
+ confirmDelay = config->readNumEntry( "confirmRebootDelay", 31 );
+ else
+ confirmDelay = config->readNumEntry( "confirmLogoutDelay", 31 );
+
+ bool result = true;
+ if (confirmDelay) {
+ KSMShutdownFeedback::start(); // make the screen gray
+ result = KSMDelayedMessageBox::showTicker( (KApplication::ShutdownType)sdtype, bootOption, confirmDelay );
+ KSMShutdownFeedback::stop(); // make the screen become normal again
+ }
+
+ if ( result )
+ shutdownInternal( KApplication::ShutdownConfirmNo,
+ (KApplication::ShutdownType)sdtype,
+ (KApplication::ShutdownMode)sdmode,
+ bootOption );
+}
+
void KSMServer::pendingShutdownTimeout()
{
shutdown( pendingShutdown_confirm, pendingShutdown_sdtype, pendingShutdown_sdmode );
diff --git a/ksmserver/shutdowndlg.cpp b/ksmserver/shutdowndlg.cpp
index 7b0493559..f6295a158 100644
--- a/ksmserver/shutdowndlg.cpp
+++ b/ksmserver/shutdowndlg.cpp
@@ -29,6 +29,7 @@ Copyright (C) 2000 Matthias Ettrich <[email protected]>
#include <tqregexp.h>
#include <klocale.h>
+#include <kconfig.h>
#include <kapplication.h>
#include <kdebug.h>
#include <kpushbutton.h>
@@ -340,6 +341,7 @@ KSMShutdownDlg::KSMShutdownDlg( TQWidget* parent,
buttonlay->addStretch( 1 );
// End session
KPushButton* btnLogout = new KPushButton( KGuiItem( i18n("&End Current Session"), "undo"), frame );
+ TQToolTip::add( btnLogout, i18n( "<qt><h3>End Current Session</h3><p>Log out of the current session to login with a different user</p></qt>" ) );
btnFont = btnLogout->font();
buttonlay->addWidget( btnLogout );
connect(btnLogout, TQT_SIGNAL(clicked()), TQT_SLOT(slotLogout()));
@@ -510,14 +512,16 @@ KSMShutdownDlg::KSMShutdownDlg( TQWidget* parent,
{
// Shutdown
KPushButton* btnHalt = new KPushButton( KGuiItem( i18n("&Turn Off Computer"), "exit"), frame );
+ TQToolTip::add( btnHalt, i18n( "<qt><h3>Turn Off Computer</h3><p>Log out of the current session and turn off the computer</p></qt>" ) );
btnHalt->setFont( btnFont );
buttonlay->addWidget( btnHalt );
connect(btnHalt, TQT_SIGNAL(clicked()), TQT_SLOT(slotHalt()));
- if ( sdtype == KApplication::ShutdownTypeHalt )
+ if ( sdtype == KApplication::ShutdownTypeHalt || getenv("KDM_AUTOLOGIN") )
btnHalt->setFocus();
// Reboot
KSMDelayedPushButton* btnReboot = new KSMDelayedPushButton( KGuiItem( i18n("&Restart Computer"), "reload"), frame );
+ TQToolTip::add( btnReboot, i18n( "<qt><h3>Restart Computer</h3><p>Log out of the current session and restart the computer</p><p>Hold the mouse button or the space bar for a short while to get a list of options what to boot</p></qt>" ) );
btnReboot->setFont( btnFont );
buttonlay->addWidget( btnReboot );
@@ -761,6 +765,70 @@ void KSMDelayedPushButton::slotTimeout()
setDown(false);
}
+KSMDelayedMessageBox::KSMDelayedMessageBox( KApplication::ShutdownType sdtype, const TQString &bootOption, int confirmDelay )
+ : TimedLogoutDlg( 0, 0, true, WType_Popup ), m_remaining(confirmDelay)
+{
+ if ( sdtype == KApplication::ShutdownTypeHalt )
+ {
+ m_title->setText( i18n( "Would you like to turn off your computer?" ) );
+ m_template = i18n( "This computer will turn off automatically\n"
+ "after %1 seconds." );
+ m_logo->setPixmap( BarIcon( "exit", 48 ) );
+ } else if ( sdtype == KApplication::ShutdownTypeReboot )
+ {
+ if (bootOption.isEmpty())
+ m_title->setText( i18n( "Would you like to reboot your computer?" ) );
+ else
+ m_title->setText( i18n( "Would you like to reboot to \"%1\"?" ).arg(bootOption) );
+ m_template = i18n( "This computer will reboot automatically\n"
+ "after %1 seconds." );
+ m_logo->setPixmap( BarIcon( "reload", 48 ) );
+ } else {
+ m_title->setText( i18n( "Would you like to end your current session?" ) );
+ m_template = i18n( "This session will end\n"
+ "after %1 seconds automatically." );
+ m_logo->setPixmap( BarIcon( "previous", 48 ) );
+ }
+
+ updateText();
+ adjustSize();
+ if ( double( height() ) / width() < 0.25 )
+ {
+ setFixedHeight( qRound( width() * 0.3 ) );
+ adjustSize();
+ }
+ TQTimer *timer = new TQTimer( this );
+ timer->start( 1000 );
+ connect( timer, TQT_SIGNAL( timeout() ), TQT_SLOT( updateText() ) );
+ KDialog::centerOnScreen(this);
+}
+
+void KSMDelayedMessageBox::updateText()
+{
+ m_remaining--;
+ if ( m_remaining == 0 )
+ {
+ accept();
+ return;
+ }
+ m_text->setText( m_template.arg( m_remaining ) );
+}
+
+bool KSMDelayedMessageBox::showTicker( KApplication::ShutdownType sdtype, const TQString &bootOption, int confirmDelay )
+{
+ kapp->enableStyles();
+ KSMDelayedMessageBox msg( sdtype, bootOption, confirmDelay );
+ TQSize sh = msg.sizeHint();
+ TQRect rect = KGlobalSettings::desktopGeometry(TQCursor::pos());
+
+ msg.move(rect.x() + (rect.width() - sh.width())/2,
+ rect.y() + (rect.height() - sh.height())/2);
+ bool result = msg.exec();
+
+ kapp->disableStyles();
+ return result;
+}
+
KSMPushButton::KSMPushButton( const KGuiItem &item,
TQWidget *parent,
const char *name)
diff --git a/ksmserver/shutdowndlg.h b/ksmserver/shutdowndlg.h
index a1d720669..79ee8ca37 100644
--- a/ksmserver/shutdowndlg.h
+++ b/ksmserver/shutdowndlg.h
@@ -26,6 +26,7 @@ class TQString;
class KAction;
+#include "timed.h"
#include <kapplication.h>
#include <kpixmapio.h>
@@ -165,4 +166,22 @@ class FlatButton : public QToolButton
+class TQLabel;
+
+class KSMDelayedMessageBox : public TimedLogoutDlg
+{
+ Q_OBJECT
+
+public:
+ KSMDelayedMessageBox( KApplication::ShutdownType sdtype, const TQString &bootOption, int confirmDelay );
+ static bool showTicker( KApplication::ShutdownType sdtype, const TQString &bootOption, int confirmDelay );
+
+protected slots:
+ void updateText();
+
+private:
+ TQString m_template;
+ int m_remaining;
+};
+
#endif
diff --git a/ksmserver/test.cpp b/ksmserver/test.cpp
index 846c449db..8f248725f 100644
--- a/ksmserver/test.cpp
+++ b/ksmserver/test.cpp
@@ -14,11 +14,16 @@ main(int argc, char *argv[])
a.iconLoader()->addAppDir("ksmserver");
KSMShutdownFeedback::start();
+ // ShutdownTypeNone == Logout == 0
+ // ShutdownTypeReboot == 1
+ // ShutdownTypeHalt == 2
KApplication::ShutdownType sdtype = KApplication::ShutdownTypeNone;
TQString bopt;
+ KSMDelayedMessageBox::showTicker( sdtype );
+ /*
(void)KSMShutdownDlg::confirmShutdown( true,
sdtype,
- bopt );
+ bopt );*/
/* (void)KSMShutdownDlg::confirmShutdown( false,
sdtype,
bopt ); */
diff --git a/ksmserver/timed.ui b/ksmserver/timed.ui
new file mode 100644
index 000000000..23d7aa2a0
--- /dev/null
+++ b/ksmserver/timed.ui
@@ -0,0 +1,352 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>TimedLogoutDlg</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>TimedLogoutDlg</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>381</width>
+ <height>131</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>Confirmation</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>frame3</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ <property name="lineWidth">
+ <number>2</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="midLineWidth">
+ <number>0</number>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout10</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout8</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout6</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer3_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>2</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>m_logo</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>48</width>
+ <height>48</height>
+ </size>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>2</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout7</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>7</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>m_title</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Would you like to shutdown your computer?</string>
+ </property>
+ <property name="textFormat">
+ <enum>PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignLeft</set>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>m_text</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>If you do not act, your computer will shutdown
+after X automatically.</string>
+ </property>
+ <property name="textFormat">
+ <enum>RichText</enum>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Preferred</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>30</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout9</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>90</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>pushButton1</cstring>
+ </property>
+ <property name="text">
+ <string>Confirm</string>
+ </property>
+ <property name="on">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>90</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>pushButton2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2_2_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>90</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>pushButton1</sender>
+ <signal>clicked()</signal>
+ <receiver>TimedLogoutDlg</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>pushButton2</sender>
+ <signal>clicked()</signal>
+ <receiver>TimedLogoutDlg</receiver>
+ <slot>reject()</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kwin/workspace.cpp b/kwin/workspace.cpp
index fe008c399..bc8914f5b 100644
--- a/kwin/workspace.cpp
+++ b/kwin/workspace.cpp
@@ -59,6 +59,17 @@ KSelectionOwner* kompmgr_selection;
bool allowKompmgrRestart = TRUE;
+bool supportsCompMgr()
+{
+ int i;
+
+ bool damageExt = XQueryExtension(qt_xdisplay(), "DAMAGE", &i, &i, &i);
+ bool compositeExt = XQueryExtension(qt_xdisplay(), "Composite", &i, &i, &i);
+ bool xfixesExt = XQueryExtension(qt_xdisplay(), "XFIXES", &i, &i, &i);
+
+ return damageExt && compositeExt && xfixesExt;
+}
+
// Rikkus: This class is too complex. It needs splitting further.
// It's a nightmare to understand, especially with so few comments :(
@@ -200,6 +211,9 @@ Workspace::Workspace( bool restore )
connect( kapp->desktop(), TQT_SIGNAL( resized( int )), TQT_SLOT( desktopResized()));
#endif
+ if (!supportsCompMgr())
+ options->useTranslucency = false;
+
// start kompmgr - i wanted to put this into main.cpp, but that would prevent dcop support, as long as Application was no dcop_object
if (options->useTranslucency)
{
diff --git a/kxkb/kcmlayout.cpp b/kxkb/kcmlayout.cpp
index 502bf7972..7af7ae691 100644
--- a/kxkb/kcmlayout.cpp
+++ b/kxkb/kcmlayout.cpp
@@ -352,6 +352,9 @@ void LayoutConfig::add()
// Create a copy of the sel widget, as one might add the same layout more
// than one time, with different variants.
TQListViewItem* toadd = copyLVI(sel, widget->listLayoutsDst);
+
+ // Turn on "Include Latin layout" for new language by default (bnc:204402)
+ toadd->setText(LAYOUT_COLUMN_INCLUDE, "us");
widget->listLayoutsDst->insertItem(toadd);
if( widget->listLayoutsDst->childCount() > 1 )
diff --git a/nsplugins/nspluginloader.cpp b/nsplugins/nspluginloader.cpp
index e9c502169..3824334c0 100644
--- a/nsplugins/nspluginloader.cpp
+++ b/nsplugins/nspluginloader.cpp
@@ -326,7 +326,7 @@ TQString NSPluginLoader::lookup(const TQString &mimeType)
}
-bool NSPluginLoader::loadViewer()
+bool NSPluginLoader::loadViewer(const TQString &mimeType)
{
kdDebug() << "NSPluginLoader::loadViewer" << endl;
@@ -350,7 +350,7 @@ bool NSPluginLoader::loadViewer()
}
// find the external artsdsp process
- if( _useArtsdsp ) {
+ if( _useArtsdsp && mimeType != "application/pdf" ) {
kdDebug() << "trying to use artsdsp" << endl;
TQString artsdsp = KGlobal::dirs()->findExe("artsdsp");
if (!artsdsp)
@@ -464,7 +464,7 @@ NSPluginInstance *NSPluginLoader::newInstance(TQWidget *parent, TQString url,
if ( !_viewer )
{
// load plugin viewer process
- loadViewer();
+ loadViewer(mimeType);
if ( !_viewer )
{
diff --git a/nsplugins/nspluginloader.h b/nsplugins/nspluginloader.h
index 6c2fe83c0..1748bb504 100644
--- a/nsplugins/nspluginloader.h
+++ b/nsplugins/nspluginloader.h
@@ -101,7 +101,7 @@ protected:
TQString lookup(const TQString &mimeType);
TQString lookupMimeType(const TQString &url);
- bool loadViewer();
+ bool loadViewer(const TQString &mimeType);
void unloadViewer();
protected slots:
diff --git a/nsplugins/pluginscan.cpp b/nsplugins/pluginscan.cpp
index 82a5defb2..6914deb93 100644
--- a/nsplugins/pluginscan.cpp
+++ b/nsplugins/pluginscan.cpp
@@ -470,7 +470,7 @@ void writeServicesFile( TQStringList mimeTypes )
ts << "Icon=netscape" << endl;
ts << "Comment=" << i18n("Netscape plugin viewer") << endl;
ts << "X-KDE-Library=libnsplugin" << endl;
- ts << "InitialPreference=0" << endl;
+ ts << "InitialPreference=7" << endl;
ts << "ServiceTypes=KParts/ReadOnlyPart,Browser/View" << endl;
ts << "X-KDE-BrowserView-PluginsInfo=nsplugins/pluginsinfo" << endl;