diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-12-11 20:21:27 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-12-11 20:21:27 +0000 |
commit | 10e41144596fc9ced40fc349d9ecd099b1c2ea19 (patch) | |
tree | 88ab04e475ff5a4cd889cb082f5760b6e0bf5e4e | |
parent | 4aed2c8219774f5d797760606b8489a92ddc5163 (diff) | |
download | tdebase-10e41144596fc9ced40fc349d9ecd099b1c2ea19.tar.gz tdebase-10e41144596fc9ced40fc349d9ecd099b1c2ea19.zip |
Initial import of Trinity 3.5.11 to kdebase
Extends krandrtray, adds iccconfig kcontrol module, adds run dialog autocomplete and lots of bugfixes
Will need to check for commit warnings and repair as encountered
Also needs full compile test
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1061475 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
254 files changed, 7545 insertions, 1368 deletions
diff --git a/doc/kdeprint/cups-config.docbook b/doc/kdeprint/cups-config.docbook index ff286e632..3196c9af3 100644 --- a/doc/kdeprint/cups-config.docbook +++ b/doc/kdeprint/cups-config.docbook @@ -487,11 +487,11 @@ unprivileged account for the server directive <term><guilabel>Server group</guilabel></term> <listitem> <para>The group the server runs under. Normally this must be -<systemitem class="groupname">sys</systemitem>, however you can +<systemitem class="groupname">lpadmin</systemitem>, however you can configure things for another group as needed.</para> <informalexample> -<para>Enter for example <userinput>sys</userinput>.</para> +<para>Enter for example <userinput>lpadmin</userinput>.</para> </informalexample> </listitem> </varlistentry> @@ -1012,7 +1012,7 @@ format="PNG"/></imageobject> <listitem> <para>The root folder for &HTTP; documents that are served. By default the compiled in folder, <filename -class="directory">/usr/share/cups/doc</filename></para> +class="directory">/usr/share/cups/doc-root</filename></para> </listitem> </varlistentry> @@ -1756,7 +1756,7 @@ over.</para> <para>The group name for <systemitem class="groupname">System</systemitem> or printer administration access. The default varies depending on the operating system, but -will be <systemitem class="groupname">sys</systemitem>, <systemitem +will be <systemitem class="groupname">lpadmin</systemitem>, <systemitem class="groupname">system</systemitem> or <systemitem class="groupname">root</systemitem> (checked for in that order).</para> </listitem> diff --git a/doc/konqueror/basics.docbook b/doc/konqueror/basics.docbook index 8940df621..55c690c03 100644 --- a/doc/konqueror/basics.docbook +++ b/doc/konqueror/basics.docbook @@ -124,10 +124,7 @@ Your Bookmarks</link> section of this document.</para> <para>The <interface>Window</interface> is the main area of &konqueror; and -can show you the contents of a directory, web page, document or image. Using -the <link linkend="menu-window"><guimenu>Window</guimenu></link> menu you can -split &konqueror;'s main window into one or more separate views, useful for -drag and drop operations, or set it to contain two or more tabbed views. +can show you the contents of a directory, web page, document or image. </para> <para>The <interface>Status Bar</interface> runs across the bottom of the diff --git a/doc/konqueror/commands.docbook b/doc/konqueror/commands.docbook index 2b3142ecc..62cff66ad 100644 --- a/doc/konqueror/commands.docbook +++ b/doc/konqueror/commands.docbook @@ -678,108 +678,6 @@ shown in Tree, Detailed List and Text views.</para></listitem> </sect2> -<sect2 id="menu-go"> -<title>The <guimenu>Go</guimenu> Menu</title> - -<variablelist> - -<varlistentry> -<term><menuchoice> -<shortcut> -<keycombo action="simul">&Alt;<keysym>Up Arrow</keysym></keycombo> -</shortcut><guimenu>Go</guimenu> -<guimenuitem>Up</guimenuitem> -</menuchoice></term> -<listitem><para>Go up a level in the folder -hierarchy.</para></listitem> -</varlistentry> - -<varlistentry> -<term><menuchoice> -<shortcut> -<keycombo action="simul">&Alt;<keysym>Left Arrow</keysym></keycombo> -</shortcut><guimenu>Go</guimenu> -<guimenuitem>Back</guimenuitem> -</menuchoice></term> -<listitem><para>Go back to the previous -view.</para></listitem> -</varlistentry> - -<varlistentry> -<term><menuchoice> -<shortcut> -<keycombo action="simul">&Alt;<keysym>Right Arrow</keysym></keycombo> -</shortcut><guimenu>Go</guimenu> -<guimenuitem>Forward</guimenuitem> -</menuchoice></term> -<listitem><para>You can only go forward if you've just gone -back.</para></listitem> -</varlistentry> - -<varlistentry> -<term><menuchoice> -<shortcut> -<keycombo action="simul">&Ctrl;<keycap>Home</keycap></keycombo> -</shortcut><guimenu>Go</guimenu> -<guimenuitem>Home URL</guimenuitem> -</menuchoice></term> -<listitem><para>Go to your home folder.</para></listitem> -</varlistentry> - -<varlistentry> -<term><menuchoice> -<guimenu>Go</guimenu> -<guimenuitem>Applications</guimenuitem> -</menuchoice></term> -<listitem><para>Open the folder holding your -applications.</para></listitem> -</varlistentry> - -<varlistentry> -<term><menuchoice> -<guimenu>Go</guimenu> -<guimenuitem>Trash</guimenuitem> -</menuchoice></term> -<listitem><para>Open your <filename - class="directory">Trash</filename> -folder in a separate window.</para></listitem> -</varlistentry> - -<varlistentry> -<term><menuchoice> -<guimenu>Go</guimenu> -<guimenuitem>Templates</guimenuitem> -</menuchoice></term> -<listitem><para>Open the <filename -class="directory">Templates</filename> folder in a separate -window.</para></listitem> -</varlistentry> - -<varlistentry> -<term><menuchoice> -<guimenu>Go</guimenu> -<guimenuitem>Autostart</guimenuitem> -</menuchoice></term> -<listitem><para>Open your <filename -class="directory">Autostart</filename> folder in a separate -window.</para></listitem> -</varlistentry> - -<varlistentry> -<term><menuchoice> -<guimenu>Go</guimenu> -<guisubmenu>Most Often Visited</guisubmenu> -</menuchoice></term> -<listitem> -<para>Displays a submenu showing the &URL;s you visit most often. Selecting one -of these will make &konqueror; open that &URL;.</para> -</listitem> -</varlistentry> - -</variablelist> - -</sect2> - <sect2 id="menu-bookmarks"> <title>The <guimenu>Bookmarks</guimenu> Menu</title> @@ -1006,129 +904,6 @@ change settings associated with spell checking in &konqueror;.</para> </sect2> -<sect2 id="menu-window"> -<title>The <guimenu>Window</guimenu> Menu</title> - -<variablelist> - -<varlistentry> -<term><menuchoice> -<shortcut> -<keycombo action="simul">&Ctrl;&Shift;<keycap>L</keycap></keycombo></shortcut> -<guimenu>Window</guimenu> -<guimenuitem>Split View Left/Right</guimenuitem> -</menuchoice></term> -<listitem><para>Split View Left/Right.</para></listitem> -</varlistentry> - -<varlistentry> -<term><menuchoice> -<shortcut> -<keycombo -action="simul">&Ctrl;&Shift;<keycap>T</keycap></keycombo></shortcut> -<guimenu>Window</guimenu> -<guimenuitem>Split View Top/Bottom</guimenuitem> -</menuchoice></term> -<listitem><para>Split View Top/Bottom.</para></listitem> -</varlistentry> - -<varlistentry> -<term><menuchoice> -<shortcut> -<keycombo -action="simul">&Ctrl;&Shift;<keycap>R</keycap></keycombo></shortcut> -<guimenu>Window</guimenu> -<guimenuitem>Remove Active View</guimenuitem> -</menuchoice></term> -<listitem><para>Remove Active View.</para></listitem> -</varlistentry> - -<varlistentry> -<term><menuchoice> -<shortcut> -<keycombo action="simul">&Ctrl;&Shift;<keycap>N</keycap></keycombo></shortcut> -<guimenu>Window</guimenu> -<guimenuitem>New Tab</guimenuitem> -</menuchoice></term> -<listitem><para>Open a new, empty, tab page.</para></listitem> -</varlistentry> - -<varlistentry> -<term><menuchoice> -<shortcut> -<keycombo action="simul">&Ctrl;&Shift;<keycap>D</keycap></keycombo></shortcut> -<guimenu>Window</guimenu> -<guimenuitem>Duplicate Current Tab</guimenuitem> -</menuchoice></term> -<listitem><para>Open a duplicate tab page.</para></listitem> -</varlistentry> - -<varlistentry> -<term><menuchoice> -<shortcut> -<keycombo action="simul">&Ctrl;&Shift;<keycap>B</keycap></keycombo></shortcut> -<guimenu>Window</guimenu> -<guimenuitem>Detach Current Tab</guimenuitem> -</menuchoice></term> -<listitem><para>Show the current tab page in a new instance of -&konqueror;.</para></listitem> -</varlistentry> - -<varlistentry> -<term><menuchoice> -<shortcut> -<keycombo action="simul">&Ctrl;<keycap>W</keycap></keycombo></shortcut> -<guimenu>Window</guimenu> -<guimenuitem>Close Current Tab</guimenuitem> -</menuchoice></term> -<listitem><para>Close the current tab page.</para></listitem> -</varlistentry> - -<varlistentry> -<term><menuchoice> -<shortcut> -<keycombo action="simul">&Ctrl;&Shift;<keycap>Left</keycap></keycombo></shortcut> -<guimenu>Window</guimenu> -<guimenuitem>Move Tab Left</guimenuitem> -</menuchoice></term> -<listitem><para>Move the current tab one place left in the list of tabs.</para></listitem> -</varlistentry> - -<varlistentry> -<term><menuchoice> -<shortcut> -<keycombo action="simul">&Ctrl;&Shift;<keycap>Left</keycap></keycombo></shortcut> -<guimenu>Window</guimenu> -<guimenuitem>Move Tab Right</guimenuitem> -</menuchoice></term> -<listitem><para>Move the current tab one place right in the list of tabs.</para></listitem> -</varlistentry> - -<varlistentry> -<term><menuchoice> -<guimenu>Window</guimenu> -<guimenuitem>Show Terminal Emulator</guimenuitem> -</menuchoice></term> -<listitem><para>Open a small text terminal view at the bottom of the - main -window.</para></listitem> -</varlistentry> - -<varlistentry> -<term><menuchoice> -<shortcut> -<keycombo action="simul"><keycap>F9</keycap></keycombo></shortcut> -<guimenu>Window</guimenu> -<guimenuitem>Show Navigation Panel</guimenuitem> -</menuchoice></term> -<listitem><para>Toggles the display of the &konqueror; navigation panel. See -<xref linkend="sidebar"/>.</para></listitem> -</varlistentry> - -</variablelist> - -</sect2> - <sect2 id="menu-help"> <title>The <guimenu>Help</guimenu> Menu</title> diff --git a/doc/userguide/kde-for-admins.docbook b/doc/userguide/kde-for-admins.docbook index f7d5d2ee0..a44055ca3 100644 --- a/doc/userguide/kde-for-admins.docbook +++ b/doc/userguide/kde-for-admins.docbook @@ -1669,7 +1669,7 @@ new menu format: </para> <informalexample> -<para>Example from <filename>applications.menu</filename>: +<para>Example from <filename>kde-applications.menu</filename>: <programlisting> <markup> <Menu> @@ -1743,7 +1743,7 @@ These are controlled by $<envar>XDG_DATA_HOME</envar>. For more information, see <ulink url="http://www.freedesktop.org/Standards/basedir-spec">http://www.freedesktop.org/Standards/basedir-spec</ulink></para> <informalexample> -<para>Example from <filename>applications.menu</filename>: +<para>Example from <filename>kde-applications.menu</filename>: <programlisting> <markup> <Menu> diff --git a/kate/data/kate.desktop b/kate/data/kate.desktop index 4881d70d1..17862fe95 100644 --- a/kate/data/kate.desktop +++ b/kate/data/kate.desktop @@ -83,7 +83,7 @@ Name[ne]=क्येट Name[pa]=ਕੇਟ Name[te]=కేట్ MimeType=text/plain; -Exec=kate %U +Exec=kate --use %U X-KDE-StartupNotify=true X-KDE-HasTempFileOption=true Icon=kate @@ -91,5 +91,6 @@ Path= DocPath=kate/index.html Type=Application Terminal=false +InitialPreference=8 X-DCOP-ServiceType=Multi Categories=Qt;KDE;TextEditor; diff --git a/kcontrol/Makefile.am b/kcontrol/Makefile.am index 50e8242de..d1fe576ac 100644 --- a/kcontrol/Makefile.am +++ b/kcontrol/Makefile.am @@ -11,6 +11,10 @@ if include_kcontrol_smartcard KSMCARD_SUBDIR=smartcard endif +if include_kcontrol_iccconfig +ICCCONFIG_SUBDIR=iccconfig +endif + if include_kcontrol_usbview USBVIEW_SUBDIR=usbview endif @@ -36,4 +40,4 @@ SUBDIRS = bell background dnssd filetypes samba krdb input info ioslaveinfo kdm\ konsole spellchecking $(USBVIEW_SUBDIR) \ $(KSMCARD_SUBDIR) nics $(FONTINST_SUBDIR) $(RANDR_SUBDIR) \ componentchooser performance xinerama $(VIEW1394_SUBDIR) display kthememanager \ - $(JOYSTICK_SUBDIR) + $(JOYSTICK_SUBDIR) $(ICCCONFIG_SUBDIR) diff --git a/kcontrol/background/bgdialog.cpp b/kcontrol/background/bgdialog.cpp index 398e30d56..34cff9f53 100644 --- a/kcontrol/background/bgdialog.cpp +++ b/kcontrol/background/bgdialog.cpp @@ -53,6 +53,7 @@ #include <kstringhandler.h> #include <kurlrequester.h> #include <kwin.h> +#include <kwinmodule.h> #include <kimagefilepreview.h> #include <knewstuff/downloaddialog.h> @@ -73,7 +74,14 @@ BGDialog::BGDialog(QWidget* parent, KConfig* _config, bool _multidesktop) m_multidesktop = _multidesktop; m_previewUpdates = true; + KWinModule *m_kwin; + m_kwin = new KWinModule(this); + m_curDesk = m_kwin->currentDesktop(); + QSize s(m_kwin->numberOfViewports(m_kwin->currentDesktop())); + m_useViewports = s.width() * s.height() > 1; + m_numDesks = m_multidesktop ? KWin::numberOfDesktops() : 1; + m_numViewports = s.width() * s.height(); m_numScreens = QApplication::desktop()->numScreens(); QCString multiHead = getenv("KDE_MULTIHEAD"); @@ -81,8 +89,19 @@ BGDialog::BGDialog(QWidget* parent, KConfig* _config, bool _multidesktop) { m_numScreens = 1; } + + QPoint vx(m_kwin->currentViewport(m_kwin->currentDesktop())); + int t_eViewport = (vx.x() * vx.y()); + if (t_eViewport < 1) { + t_eViewport = 1; + } + delete m_kwin; m_desk = m_multidesktop ? KWin::currentDesktop() : 1; + //m_desk = m_multidesktop ? (m_useViewports ? (m_desk * m_numViewports) : m_desk) : m_desk; + m_desk = m_multidesktop ? (m_useViewports ? (((m_desk - 1) * m_numViewports) + t_eViewport) : m_desk) : m_desk; + m_numDesks = m_multidesktop ? (m_useViewports ? (m_numDesks * m_numViewports) : m_numDesks) : m_numDesks; + m_screen = QApplication::desktop()->screenNumber(this); if (m_screen >= (int)m_numScreens) m_screen = m_numScreens-1; @@ -416,8 +435,18 @@ void BGDialog::slotIdentifyScreens() void BGDialog::initUI() { // Desktop names - for (unsigned i = 0; i < m_numDesks; ++i) - m_comboDesktop->insertItem(m_pGlobals->deskName(i)); + if (m_useViewports == false) { + for (unsigned i = 0; i < m_numDesks; ++i) { + m_comboDesktop->insertItem(m_pGlobals->deskName(i)); + } + } + else { + for (unsigned i = 0; i < (m_numDesks/m_numViewports); ++i) { + for (unsigned j = 0; j < m_numViewports; ++j) { + m_comboDesktop->insertItem(i18n("Desktop %1 Viewport %2").arg(i+1).arg(j+1)); + } + } + } // Screens for (unsigned i = 0; i < m_numScreens; ++i) diff --git a/kcontrol/background/bgdialog.h b/kcontrol/background/bgdialog.h index 02fbf3f3a..8782b73f7 100644 --- a/kcontrol/background/bgdialog.h +++ b/kcontrol/background/bgdialog.h @@ -86,8 +86,10 @@ protected: KGlobalBackgroundSettings *m_pGlobals; KStandardDirs *m_pDirs; bool m_multidesktop; - + bool m_useViewports; + int m_curDesk; unsigned m_numDesks; + unsigned m_numViewports; unsigned m_numScreens; int m_desk; int m_screen; diff --git a/kcontrol/background/bgrender.cpp b/kcontrol/background/bgrender.cpp index f17892dce..47d52b193 100644 --- a/kcontrol/background/bgrender.cpp +++ b/kcontrol/background/bgrender.cpp @@ -54,8 +54,7 @@ KBackgroundRenderer::KBackgroundRenderer(int desk, int screen, bool drawBackgrou m_isBusyCursor = false; m_enableBusyCursor = false; m_pDirs = KGlobal::dirs(); - m_rSize = m_Size = drawBackgroundPerScreen ? - QApplication::desktop()->screenGeometry(screen).size() : QApplication::desktop()->size(); + m_rSize = m_Size = drawBackgroundPerScreen ? KApplication::desktop()->screenGeometry(screen).size() : KApplication::desktop()->geometry().size(); m_pProc = 0L; m_Tempfile = 0L; m_bPreview = false; @@ -86,8 +85,7 @@ void KBackgroundRenderer::setSize(const QSize &size) void KBackgroundRenderer::desktopResized() { m_State = 0; - m_rSize = drawBackgroundPerScreen() ? - QApplication::desktop()->screenGeometry(screen()).size() : QApplication::desktop()->size(); + m_rSize = drawBackgroundPerScreen() ? KApplication::desktop()->screenGeometry(screen()).size() : KApplication::desktop()->geometry().size(); if( !m_bPreview ) m_Size = m_rSize; } @@ -1048,7 +1046,7 @@ KVirtualBGRenderer::KVirtualBGRenderer( int desk, KConfig *config ) } initRenderers(); - m_size = QApplication::desktop()->size(); + m_size = KApplication::desktop()->geometry().size(); } KVirtualBGRenderer::~KVirtualBGRenderer() @@ -1155,7 +1153,7 @@ void KVirtualBGRenderer::setEnabled(bool enable) void KVirtualBGRenderer::desktopResized() { - m_size = QApplication::desktop()->size(); + m_size = KApplication::desktop()->geometry().size(); if (m_pPixmap) { @@ -1164,7 +1162,7 @@ void KVirtualBGRenderer::desktopResized() m_pPixmap->fill(Qt::black); } - initRenderers(); + initRenderers(); } @@ -1196,8 +1194,7 @@ void KVirtualBGRenderer::setPreview(const QSize & size) QSize KVirtualBGRenderer::renderSize(int screen) { - return m_bDrawBackgroundPerScreen ? - QApplication::desktop()->screenGeometry(screen).size() : QApplication::desktop()->size(); + return m_bDrawBackgroundPerScreen ? KApplication::desktop()->screenGeometry(screen).size() : KApplication::desktop()->geometry().size(); } @@ -1208,7 +1205,7 @@ void KVirtualBGRenderer::initRenderers() m_bCommonScreen = m_pConfig->readBoolEntry("CommonScreen", _defCommonScreen); - m_numRenderers = m_bDrawBackgroundPerScreen ? QApplication::desktop()->numScreens() : 1; + m_numRenderers = m_bDrawBackgroundPerScreen ? KApplication::desktop()->numScreens() : 1; m_bFinished.resize(m_numRenderers); m_bFinished.fill(false); @@ -1267,10 +1264,11 @@ void KVirtualBGRenderer::screenDone(int _desk, int _screen) // There's more than one renderer, so we are drawing each output to our own pixmap QRect overallGeometry; - for (int i=0; i < QApplication::desktop()->numScreens(); ++i) - overallGeometry |= QApplication::desktop()->screenGeometry(i); + for (int i=0; i < KApplication::desktop()->numScreens(); ++i) { + overallGeometry |= KApplication::desktop()->screenGeometry(i); + } - QPoint drawPos = QApplication::desktop()->screenGeometry(screen).topLeft() - overallGeometry.topLeft(); + QPoint drawPos = KApplication::desktop()->screenGeometry(screen).topLeft() - overallGeometry.topLeft(); drawPos.setX( int(drawPos.x() * m_scaleX) ); drawPos.setY( int(drawPos.y() * m_scaleY) ); diff --git a/kcontrol/dnssd/configdialog.ui b/kcontrol/dnssd/configdialog.ui index 83808d1bb..848457a44 100644 --- a/kcontrol/dnssd/configdialog.ui +++ b/kcontrol/dnssd/configdialog.ui @@ -44,45 +44,17 @@ <attribute name="title"> <string>&General</string> </attribute> - <vbox> + <grid> <property name="name"> <cstring>unnamed</cstring> </property> - <widget class="QCheckBox"> - <property name="name"> - <cstring>kcfg_BrowseLocal</cstring> - </property> - <property name="text"> - <string>Browse local networ&k</string> - </property> - <property name="whatsThis" stdset="0"> - <string>Browse local network (domain .local) using multicast DNS.</string> - </property> - </widget> - <widget class="KEditListBox"> - <property name="name"> - <cstring>kcfg_DomainList</cstring> - </property> - <property name="sizePolicy"> - <sizepolicy> - <hsizetype>7</hsizetype> - <vsizetype>7</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="title"> - <string>Additional Domains</string> - </property> - <property name="whatsThis" stdset="0"> - <string>List of Internet domains that will be browsed for services. Do not put .local here - it -is configured with 'Browse local network' option above.</string> - </property> - </widget> - <widget class="QButtonGroup"> + <widget class="QButtonGroup" row="3" column="0"> <property name="name"> <cstring>kcfg_PublishType</cstring> </property> + <property name="enabled"> + <bool>true</bool> + </property> <property name="sizePolicy"> <sizepolicy> <hsizetype>5</hsizetype> @@ -96,50 +68,104 @@ is configured with 'Browse local network' option above.</string> </property> <widget class="QRadioButton"> <property name="name"> - <cstring>LANButtor</cstring> + <cstring>WANButton</cstring> + </property> + <property name="enabled"> + <bool>true</bool> </property> <property name="geometry"> <rect> <x>11</x> - <y>23</y> + <y>51</y> <width>618</width> <height>22</height> </rect> </property> <property name="text"> - <string>Loc&al network</string> + <string>&Wide area network</string> </property> - <property name="checked"> - <bool>false</bool> + <property name="accel"> + <string>Alt+W</string> </property> <property name="whatsThis" stdset="0"> - <string>Advertise services on local network (in domain .local) using multicast DNS.</string> + <string>Advertise services on Internet domain using public IP. To have this option working you need to configure wide area operation in using administrator mode</string> </property> </widget> <widget class="QRadioButton"> <property name="name"> - <cstring>WANButton</cstring> - </property> - <property name="enabled"> - <bool>true</bool> + <cstring>LANButtor</cstring> </property> <property name="geometry"> <rect> <x>11</x> - <y>51</y> + <y>23</y> <width>618</width> <height>22</height> </rect> </property> <property name="text"> - <string>&Wide area network</string> + <string>Loc&al network</string> + </property> + <property name="accel"> + <string>Alt+A</string> + </property> + <property name="checked"> + <bool>false</bool> </property> <property name="whatsThis" stdset="0"> - <string>Advertise services on Internet domain using public IP. To have this option working you need to configure wide area operation in using administrator mode</string> + <string>Advertise services on local network (in domain .local) using multicast DNS.</string> </property> </widget> </widget> - </vbox> + <widget class="QCheckBox" row="1" column="0"> + <property name="name"> + <cstring>kcfg_BrowseLocal</cstring> + </property> + <property name="text"> + <string>Browse local networ&k</string> + </property> + <property name="accel"> + <string>Alt+K</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Browse local network (domain .local) using multicast DNS.</string> + </property> + </widget> + <widget class="QCheckBox" row="0" column="0"> + <property name="name"> + <cstring>enableZeroconf</cstring> + </property> + <property name="text"> + <string>Enable &Zeroconf network browsing</string> + </property> + <property name="accel"> + <string>Alt+Z</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Browse local network (domain .local) using multicast DNS.</string> + </property> + </widget> + <widget class="KEditListBox" row="2" column="0"> + <property name="name"> + <cstring>kcfg_DomainList</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Additional Domains</string> + </property> + <property name="whatsThis" stdset="0"> + <string>List of Internet domains that will be browsed for services. Do not put .local here - it +is configured with 'Browse local network' option above.</string> + </property> + </widget> + </grid> </widget> <widget class="QWidget"> <property name="name"> diff --git a/kcontrol/dnssd/kcm_kdnssd.desktop b/kcontrol/dnssd/kcm_kdnssd.desktop index 8b949e370..b0d731098 100644 --- a/kcontrol/dnssd/kcm_kdnssd.desktop +++ b/kcontrol/dnssd/kcm_kdnssd.desktop @@ -70,9 +70,9 @@ Comment[zh_TW]=設定服務偵測 Exec=kcmshell kcm_kdnssd GenericName= GenericName[ko]=일반 -Icon=blockdevice +Icon=network_local MimeType= -Name=Service Discovery +Name=Zeroconf Service Discovery Name[af]=Dienste ontdekker Name[ar]=إكتشاف الخدمات Name[be]=Пошук сервісаў @@ -149,6 +149,7 @@ X-KDE-HasReadOnlyMode=false X-KDE-Library=kdnssd X-KDE-ModuleType=Library X-KDE-ParentApp=kcontrol -X-KDE-SubstituteUID=false -X-KDE-RootOnly=true +#root parts unused with Avahi +#X-KDE-SubstituteUID=false +#X-KDE-RootOnly=true Categories=Qt;KDE;X-KDE-settings-network; diff --git a/kcontrol/dnssd/kcmdnssd.cpp b/kcontrol/dnssd/kcmdnssd.cpp index d86cc2897..d754f0025 100644 --- a/kcontrol/dnssd/kcmdnssd.cpp +++ b/kcontrol/dnssd/kcmdnssd.cpp @@ -27,6 +27,10 @@ #include <qradiobutton.h> #include <qtimer.h> #include <qtabwidget.h> +#include <qcheckbox.h> +#include <qprocess.h> +#include <qcursor.h> +#include <qbuttongroup.h> #include <klocale.h> #include <kglobal.h> @@ -35,6 +39,8 @@ #include <klineedit.h> #include <kpassdlg.h> #include <ksimpleconfig.h> +#include <kapplication.h> +#include <kmessagebox.h> #include "kcmdnssd.h" #include <dnssd/settings.h> @@ -65,7 +71,10 @@ KCMDnssd::KCMDnssd(QWidget *parent, const char *name, const QStringList&) connect(hostedit,SIGNAL(textChanged(const QString&)),this,SLOT(wdchanged())); connect(secretedit,SIGNAL(textChanged(const QString&)),this,SLOT(wdchanged())); connect(domainedit,SIGNAL(textChanged(const QString&)),this,SLOT(wdchanged())); + connect(enableZeroconf,SIGNAL(toggled(bool)),this,SLOT(enableZeroconfChanged(bool))); + m_enableZeroconfChanged=false; if (DNSSD::Configuration::self()->publishDomain().isEmpty()) WANButton->setEnabled(false); + kcfg_PublishType->hide(); //unused with Avahi } KCMDnssd::~KCMDnssd() @@ -75,18 +84,55 @@ KCMDnssd::~KCMDnssd() void KCMDnssd::save() { + setCursor(QCursor(Qt::BusyCursor)); KCModule::save(); if (geteuid()==0 && m_wdchanged) saveMdnsd(); domain->setFileWriteMode(0644); // this should be readable for everyone domain->writeEntry("PublishDomain",domainedit->text()); domain->sync(); KIPC::sendMessageAll((KIPC::Message)KIPCDomainsChanged); + if (m_enableZeroconfChanged) { + + QString scaryMessage = i18n("Enabling local network browsing will open a network port (5353) on your computer. If security problems are discovered in the zeroconf server, remote attackers could access your computer as the \"avahi\" user."); + + KProcess *proc = new KProcess; + + *proc << "kdesu"; + + if (enableZeroconf->isChecked()) { + if (KMessageBox::warningYesNo( this, scaryMessage, i18n("Enable Zeroconf Network Browsing"), KGuiItem(i18n("Enable Browsing")), KGuiItem(i18n("Don't Enable Browsing")) ) == KMessageBox::Yes) { + + *proc << "/usr/share/avahi/enable_avahi 1"; + proc->start(KProcess::Block); + } else { + enableZeroconf->setChecked(false); + } + } else { + *proc << "/usr/share/avahi/enable_avahi 0"; + proc->start(KProcess::Block); + } + } + setCursor(QCursor(Qt::ArrowCursor)); } void KCMDnssd::load() { - KCModule::load(); if (geteuid()==0) loadMdnsd(); + enableZeroconf->setChecked(false); + QProcess avahiStatus(QString("/usr/share/avahi/avahi_status"), this, "avahiStatus"); + avahiStatus.start(); + while (avahiStatus.isRunning()) { + kapp->processEvents(); + } + int exitStatus = avahiStatus.exitStatus(); + if (exitStatus == 0) { // disabled + enableZeroconf->setChecked(false); + } else if (exitStatus == 1) { // enabled + enableZeroconf->setChecked(true); + } else if (exitStatus == 2) { // custom setup + enableZeroconf->setEnabled(false); + } + KCModule::load(); } // hack to work around not working isModified() for KPasswordEdit @@ -97,6 +143,12 @@ void KCMDnssd::wdchanged() m_wdchanged=true; } +void KCMDnssd::enableZeroconfChanged(bool) +{ + changed(); + m_enableZeroconfChanged=true; +} + void KCMDnssd::loadMdnsd() { QFile f(MDNSD_CONF); diff --git a/kcontrol/dnssd/kcmdnssd.h b/kcontrol/dnssd/kcmdnssd.h index 2e66f6a8f..384f7b625 100644 --- a/kcontrol/dnssd/kcmdnssd.h +++ b/kcontrol/dnssd/kcmdnssd.h @@ -38,12 +38,14 @@ public: virtual void load(); private slots: void wdchanged(); + void enableZeroconfChanged(bool); private: void loadMdnsd(); bool saveMdnsd(); QMap<QString,QString> mdnsdLines; bool m_wdchanged; KSimpleConfig* domain; + bool m_enableZeroconfChanged; }; #endif diff --git a/kcontrol/ebrowsing/plugins/ikws/ikwsopts.cpp b/kcontrol/ebrowsing/plugins/ikws/ikwsopts.cpp index 6c055255d..ca79f0b36 100644 --- a/kcontrol/ebrowsing/plugins/ikws/ikwsopts.cpp +++ b/kcontrol/ebrowsing/plugins/ikws/ikwsopts.cpp @@ -164,6 +164,9 @@ void FilterOptions::load( bool useDefaults ) this, SLOT(checkFavoritesChanged())); connect(m_dlg->lvSearchProviders, SIGNAL(pressed(QListViewItem *)), this, SLOT(checkFavoritesChanged())); + connect(m_dlg->lvSearchProviders, SIGNAL(clicked(QListViewItem *)), + this, SLOT(checkFavoritesChanged())); + connect(m_dlg->cmbDefaultEngine, SIGNAL(activated(const QString &)), this, SLOT(configChanged())); diff --git a/kcontrol/ebrowsing/plugins/ikws/searchproviders/kde.desktop b/kcontrol/ebrowsing/plugins/ikws/searchproviders/kde.desktop index f5a96f71e..961b236be 100644 --- a/kcontrol/ebrowsing/plugins/ikws/searchproviders/kde.desktop +++ b/kcontrol/ebrowsing/plugins/ikws/searchproviders/kde.desktop @@ -74,7 +74,6 @@ Name[vi]=Tài liệu về API của KDE Name[wa]=Documintåcion di l' API di KDE Name[zh_CN]=KDE API 文档 Name[zh_TW]=KDE API 文件 -Query=http://developer.kde.org/documentation/library/classmapper.php?class=\\{@} -Query[bg]=http://developer.kde.org/documentation/library/classmapper.php?class=\ +Query=http://api.kde.org/classmapper.php?class=\\{@} ServiceTypes=SearchProvider Type=Service diff --git a/kcontrol/fonts/fonts.cpp b/kcontrol/fonts/fonts.cpp index 8cb1cbafc..c50c89bc9 100644 --- a/kcontrol/fonts/fonts.cpp +++ b/kcontrol/fonts/fonts.cpp @@ -331,7 +331,7 @@ bool FontAASettings::load( bool useDefaults ) kglobals.setReadDefaults( useDefaults ); kglobals.setGroup("General"); - hStyle=KXftConfig::Hint::Medium; + hStyle=KXftConfig::Hint::Full; xft.setHintStyle(hStyle); xft.apply(); // Save this setting kglobals.writeEntry("XftHintStyle", KXftConfig::toStr(hStyle)); @@ -449,7 +449,7 @@ KXftConfig::Hint::Style FontAASettings::getHintStyle() if(hintingStyle->currentText()==KXftConfig::description((KXftConfig::Hint::Style)s)) return (KXftConfig::Hint::Style)s; - return KXftConfig::Hint::Medium; + return KXftConfig::Hint::Full; } #endif @@ -527,13 +527,13 @@ KFonts::KFonts(QWidget *parent, const char *name, const QStringList &) QFont f0("Sans Serif", 10); QFont f1("Monospace", 10); QFont f2("Sans Serif", 10); - QFont f3("Sans Serif", 9, QFont::Bold); + QFont f3("Sans Serif", 10, QFont::Bold); QFont f4("Sans Serif", 10); f0.setPointSize(10); f1.setPointSize(10); f2.setPointSize(10); - f3.setPointSize(9); + f3.setPointSize(10); f4.setPointSize(10); defaultFontList << f0 << f1 << f2 << f0 << f3 << f4 << f0; diff --git a/kcontrol/fonts/kxftconfig.cpp b/kcontrol/fonts/kxftconfig.cpp index 833e31118..22621f5e6 100644 --- a/kcontrol/fonts/kxftconfig.cpp +++ b/kcontrol/fonts/kxftconfig.cpp @@ -1147,7 +1147,7 @@ void KXftConfig::readContents() if(*ptr=='\"') { ptr++; - if(NULL!=(eostr=strchr(ptr, '\"')) && eostr-ptr<constMaxDataLen) + if(NULL!=(eostr=(char*)strchr(ptr, '\"')) && eostr-ptr<constMaxDataLen) { memcpy(data, ptr, eostr-ptr); data[eostr-ptr]='\0'; @@ -1183,7 +1183,7 @@ void KXftConfig::readContents() if(*ptr=='\"') { ptr++; - if(NULL!=(eostr=strchr(ptr, '\"')) && eostr-ptr<constMaxDataLen) + if(NULL!=(eostr=(char*)strchr(ptr, '\"')) && eostr-ptr<constMaxDataLen) { memcpy(data, ptr, eostr-ptr); data[eostr-ptr]='\0'; diff --git a/kcontrol/iccconfig/Makefile.am b/kcontrol/iccconfig/Makefile.am new file mode 100644 index 000000000..8ebd2b289 --- /dev/null +++ b/kcontrol/iccconfig/Makefile.am @@ -0,0 +1,17 @@ +AM_CPPFLAGS = $(all_includes) +kde_module_LTLIBRARIES = kcm_iccconfig.la + +kcm_iccconfig_la_SOURCES = iccconfig.cpp iccconfigbase.ui iccconfig.skel + +kcm_iccconfig_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined + +kcm_iccconfig_la_LIBADD = -lkdeui $(LIB_KIO) + +METASOURCES = AUTO + +noinst_HEADERS = iccconfig.h + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kcmiccconfig.pot + +xdg_apps_DATA = iccconfig.desktop diff --git a/kcontrol/iccconfig/configure.in.in b/kcontrol/iccconfig/configure.in.in new file mode 100644 index 000000000..a98dfc1b2 --- /dev/null +++ b/kcontrol/iccconfig/configure.in.in @@ -0,0 +1,7 @@ +case "$host" in + *-*-linux*) + FOUND_LINUX=yes + ;; +esac + +AM_CONDITIONAL(include_kcontrol_iccconfig, test "$FOUND_LINUX" = "yes")
\ No newline at end of file diff --git a/kcontrol/iccconfig/iccconfig.cpp b/kcontrol/iccconfig/iccconfig.cpp new file mode 100644 index 000000000..36eb20593 --- /dev/null +++ b/kcontrol/iccconfig/iccconfig.cpp @@ -0,0 +1,166 @@ +/** + * smartcard.cpp + * + * Copyright (c) 2001 George Staikos <[email protected]> + * Copyright (c) 2001 Fernando Llobregat <[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 "iccconfig.h" + +#include <qcheckbox.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qlineedit.h> +#include <qpushbutton.h> + +#include <dcopclient.h> + +#include <kaboutdata.h> +#include <kapplication.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kdialog.h> +#include <kglobal.h> +#include <klistview.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kpopupmenu.h> +#include <kurlrequester.h> +#include <kgenericfactory.h> + +#include <unistd.h> +#include <ksimpleconfig.h> +#include <string> +#include <stdio.h> +#include <qstring.h> + +using namespace std; + +/**** DLL Interface ****/ +typedef KGenericFactory<KICCConfig, QWidget> KICCCFactory; +K_EXPORT_COMPONENT_FACTORY( kcm_iccconfig, KICCCFactory("kcmiccconfig") ) + +KSimpleConfig *config; + +/**** KICCConfig ****/ + +KICCConfig::KICCConfig(QWidget *parent, const char *name, const QStringList &) + : KCModule(KICCCFactory::instance(), parent, name) +{ + + QVBoxLayout *layout = new QVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint()); + config = new KSimpleConfig( QString::fromLatin1( KDE_CONFDIR "/kicc/kiccconfigrc" )); + + KAboutData *about = + new KAboutData(I18N_NOOP("kcmiccconfig"), I18N_NOOP("KDE ICC Profile Control Module"), + 0, 0, KAboutData::License_GPL, + I18N_NOOP("(c) 2009 Timothy Pearson")); + + about->addAuthor("Timothy Pearson", 0, "[email protected]"); + setAboutData( about ); + + base = new ICCConfigBase(this); + layout->add(base); + + setRootOnlyMsg(i18n("<b>The ICC color profile is a system wide setting, and requires administrator access</b><br>To alter the system's ICC profile, click on the \"Administrator Mode\" button below.")); + setUseRootOnlyMsg(true); + + connect(base->enableSupport, SIGNAL(clicked()), SLOT(changed())); + connect(base->enableSupport, SIGNAL(toggled(bool)), base->iccFile, SLOT(setEnabled(bool))); + + connect(base->iccFile, SIGNAL(textChanged(const QString&)), SLOT(changed())); + + load(); + + if (getuid() != 0 || !config->checkConfigFilesWritable( true )) { + base->enableSupport->setEnabled(false); + base->iccFile->setEnabled(false); + } +} + +KICCConfig::~KICCConfig() +{ + delete config; +} + +void KICCConfig::load() +{ + load( false ); +} + +void KICCConfig::load(bool useDefaults ) +{ + //Update the toggle buttons with the current configuration + + config->setReadDefaults( useDefaults ); + + base->enableSupport->setChecked(config->readBoolEntry("EnableICC", false)); + base->iccFile->setEnabled(config->readBoolEntry("EnableICC", false)); + base->iccFile->setURL(config->readEntry("ICCFile")); + + emit changed(useDefaults); +} + +void KICCConfig::save() +{ + config->writeEntry("EnableICC", base->enableSupport->isChecked()); + config->writeEntry("ICCFile", base->iccFile->url()); + + if (base->enableSupport->isChecked()) { + // Apply ICC settings with XCalib + string icc_command="/usr/bin/xcalib "; + FILE *pipe_xcalib; + char xcalib_result[2048]; + int i; + xcalib_result[0]=0; + + icc_command.append(base->iccFile->url().ascii()); + if ((pipe_xcalib = popen(icc_command.c_str(), "r")) == NULL) + { + printf("Xcalib pipe error\n\r"); + } + else { + fgets(xcalib_result, 2048, pipe_xcalib); + pclose(pipe_xcalib); + for (i=1;i<2048;i++) { + if (xcalib_result[i] == 0) { + xcalib_result[i-1]=0; + i=2048; + } + } + if (strlen(xcalib_result) > 2) { + KMessageBox::error(this, QString("Unable to apply ICC configuration:\n\r%1").arg(xcalib_result)); + } + } + } + + emit changed(false); +} + +void KICCConfig::defaults() +{ + load( true ); +} + +QString KICCConfig::quickHelp() const +{ + return i18n("<h1>ICC Profile Configuration</h1> This module allows you to configure KDE support" + " for ICC profiles. This allows you to easily color correct your monitor" + " for a more lifelike and vibrant image."); +} + +#include "iccconfig.moc"
\ No newline at end of file diff --git a/kcontrol/iccconfig/iccconfig.desktop b/kcontrol/iccconfig/iccconfig.desktop new file mode 100644 index 000000000..97f1b5a9d --- /dev/null +++ b/kcontrol/iccconfig/iccconfig.desktop @@ -0,0 +1,21 @@ +[Desktop Entry] +Exec=kcmshell iccconfig +Icon=kcoloredit +Type=Application +DocPath=kcontrol/iccconfig/index.html + +X-KDE-Library=iccconfig +X-KDE-ParentApp=kcontrol +X-KDE-RootOnly=true +X-KDE-SubstituteUID=true + +Categories=Qt;KDE;X-KDE-settings-peripherals; +Comment=Configure display ICC profile +Comment[en_US]=Configure display ICC profile +DocPath=kcontrol/iccconfig.html +GenericName= +GenericName[en_US]= +Keywords=ICC,display,color,profile +MimeType= +Name=ICC Color Profile +Name[en_US]=ICC Color Profile
\ No newline at end of file diff --git a/kcontrol/iccconfig/iccconfig.h b/kcontrol/iccconfig/iccconfig.h new file mode 100644 index 000000000..0736968b4 --- /dev/null +++ b/kcontrol/iccconfig/iccconfig.h @@ -0,0 +1,71 @@ +/** + * iccconfig.h + * + * Copyright (c) 2009 Timothy Pearson <[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 _KCM_ICCCONFIG_H +#define _KCM_ICCCONFIG_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <dcopobject.h> + +#include <kcmodule.h> + +#include "iccconfigbase.h" + +class KConfig; +class KPopupMenu; +class KListViewItem; + +class KICCConfig : public KCModule, public DCOPObject +{ + K_DCOP + Q_OBJECT + + +public: + //KICCConfig(QWidget *parent = 0L, const char *name = 0L); + KICCConfig(QWidget *parent, const char *name, const QStringList &); + virtual ~KICCConfig(); + + ICCConfigBase *base; + + void load(); + void load( bool useDefaults); + void save(); + void defaults(); + + int buttons(); + QString quickHelp() const; + + k_dcop: + +private: + + KConfig *config; + bool _ok; + KPopupMenu * _popUpKardChooser; + + +}; + +#endif + diff --git a/kcontrol/iccconfig/iccconfigbase.ui b/kcontrol/iccconfig/iccconfigbase.ui new file mode 100644 index 000000000..0d6689fd7 --- /dev/null +++ b/kcontrol/iccconfig/iccconfigbase.ui @@ -0,0 +1,102 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>ICCConfigBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ICCConfigBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>519</width> + <height>356</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QTabWidget" row="0" column="0"> + <property name="name"> + <cstring>TabWidget2</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>ICC Color Profile Configuration</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox" row="0" column="0" colspan="2"> + <property name="name"> + <cstring>enableSupport</cstring> + </property> + <property name="text"> + <string>&Enable global ICC color profile support</string> + </property> + </widget> + <widget class="KURLRequester" row="1" column="1"> + <property name="name"> + <cstring>iccFile</cstring> + </property> + <property name="filter"> + <string>*.icc</string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel2_2</cstring> + </property> + <property name="text"> + <string>ICC File</string> + </property> + </widget> + <spacer row="2" column="0"> + <property name="name" stdset="0"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>enableSupport</sender> + <signal>toggled(bool)</signal> + <receiver>ICCConfigBase</receiver> + <slot>enableSupport_toggled(bool)</slot> + </connection> +</connections> +<includes> + <include location="local" impldecl="in implementation">ICCConfigBase.ui.h</include> +</includes> +<slots> + <slot>enableSupport_toggled(bool)</slot> +</slots> +<includes> + <include location="local" impldecl="in implementation">kdialog.h</include> +</includes> +<layoutdefaults spacing="3" margin="6"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +</UI> diff --git a/kcontrol/iccconfig/iccconfigbase2.ui b/kcontrol/iccconfig/iccconfigbase2.ui new file mode 100644 index 000000000..cad130b47 --- /dev/null +++ b/kcontrol/iccconfig/iccconfigbase2.ui @@ -0,0 +1,104 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ICCConfigBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ICCConfigBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>519</width> + <height>356</height> + </rect> + </property> + <property name="caption"> + <string>ICCConfigBase</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QTabWidget" row="0" column="0"> + <property name="name"> + <cstring>TabWidget2</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>ICC Color Profile Configuration</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>enableSupport</cstring> + </property> + <property name="text"> + <string>&Enable ICC color profile support</string> + </property> + </widget> + <widget class="KURLRequester" row="1" column="1"> + <property name="name"> + <cstring>editPCF</cstring> + </property> + <property name="filter"> + <string>.icc</string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel2_2</cstring> + </property> + <property name="text"> + <string>ICC File</string> + </property> + </widget> + <spacer row="2" column="0"> + <property name="name"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>enableSupport</sender> + <signal>toggled(bool)</signal> + <receiver>ICCConfigBase</receiver> + <slot>enableSupport_toggled(bool)</slot> + </connection> +</connections> +<slots> + <slot>enableSupport_toggled(bool)</slot> +</slots> +<layoutdefaults spacing="3" margin="6"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +<includehints> + <includehint>kurlrequester.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/kcontrol/info/cdinfo.desktop b/kcontrol/info/cdinfo.desktop index b5a441e47..17302d5b5 100644 --- a/kcontrol/info/cdinfo.desktop +++ b/kcontrol/info/cdinfo.desktop @@ -163,4 +163,4 @@ Keywords[uk]=CD-ROM Information,CD-ROM,CD,CD Drive,Writer Capabilities,Інфо� Keywords[vi]=Thông tin đĩa CD-ROM,CD-ROM,CD, ổ đĩa CD, Khả năng ổ ghi Keywords[wa]=Informåcion do CD-ROM,CD-ROM,CD,léjheu d' CD,Usteyes di scrijhaedje -Categories=Qt;KDE;X-KDE-information; +Categories=Qt;KDE;X-KDE-settings-hardware; diff --git a/kcontrol/info/devices.desktop b/kcontrol/info/devices.desktop index 171224aa6..5895b8c3a 100644 --- a/kcontrol/info/devices.desktop +++ b/kcontrol/info/devices.desktop @@ -3,7 +3,7 @@ Exec=kcmshell devices Icon=kcmdevices Type=Application DocPath=kinfocenter/devices/index.html -Categories=Qt;KDE;X-KDE-information; +Categories=Qt;KDE;X-KDE-settings-hardware; X-KDE-Library=info diff --git a/kcontrol/info/dma.desktop b/kcontrol/info/dma.desktop index e420acaea..bb02419ca 100644 --- a/kcontrol/info/dma.desktop +++ b/kcontrol/info/dma.desktop @@ -3,7 +3,7 @@ Exec=kcmshell dma Icon=kcmmemory Type=Application DocPath=kinfocenter/dma/index.html -Categories=Qt;KDE;X-KDE-information; +Categories=Qt;KDE;X-KDE-settings-hardware; X-KDE-Library=info diff --git a/kcontrol/info/interrupts.desktop b/kcontrol/info/interrupts.desktop index a18bde656..bdfb6e6e6 100644 --- a/kcontrol/info/interrupts.desktop +++ b/kcontrol/info/interrupts.desktop @@ -3,7 +3,7 @@ Exec=kcmshell interrupts Icon=kcmmemory Type=Application DocPath=kinfocenter/interrupts/index.html -Categories=Qt;KDE;X-KDE-information; +Categories=Qt;KDE;X-KDE-settings-hardware; X-KDE-Library=info diff --git a/kcontrol/info/ioports.desktop b/kcontrol/info/ioports.desktop index f66b81288..1a3505314 100644 --- a/kcontrol/info/ioports.desktop +++ b/kcontrol/info/ioports.desktop @@ -3,7 +3,7 @@ Exec=kcmshell ioports Icon=kcmmemory Type=Application DocPath=kinfocenter/ioports/index.html -Categories=Qt;KDE;X-KDE-information; +Categories=Qt;KDE;X-KDE-settings-hardware; X-KDE-Library=info diff --git a/kcontrol/info/memory.desktop b/kcontrol/info/memory.desktop index f9aca9869..e94646cfe 100644 --- a/kcontrol/info/memory.desktop +++ b/kcontrol/info/memory.desktop @@ -245,4 +245,5 @@ Keywords[xh]=Inkumbulo,RAM,Inkumbulo yobume,Inkumbulo yomzimba,Inkumbulo yokwahl Keywords[zh_CN]=Memory,RAM,Virtual memory,Physical memory,Shared memory,Swap,System Information,内存,虚拟存储,物理存储,共享内存,交换,系统信息 Keywords[zh_TW]=Memory,RAM,Virtual memory,Physical memory,Shared memory,Swap,System Information,記憶體,虛擬記憶體,實體記憶體,共享記憶體,系統資訊 Keywords[zu]=Inkumbulo,RAM,Inkumbulo yamanga,Inkumbulo siqu,Inkumbulo yokwabelana,Shintshanisa,Ulwazi Lwesistimu -Categories=Qt;KDE;X-KDE-information; +Categories=Qt;KDE;X-KDE-settings-hardware; + diff --git a/kcontrol/info/opengl.desktop b/kcontrol/info/opengl.desktop index 07d6b76ce..4451c5167 100644 --- a/kcontrol/info/opengl.desktop +++ b/kcontrol/info/opengl.desktop @@ -1,4 +1,5 @@ [Desktop Entry] +NoDisplay=true Exec=kcmshell opengl Icon=kcmopengl Type=Application @@ -144,4 +145,5 @@ Keywords[wa]=OpenGL,DRI,GLX,3D,VideoCard,cåte videyo,Hardware Acceleration,Grap Keywords[zh_CN]=OpenGL,DRI,GLX,3D,VideoCard,Hardware Acceleration,Graphics,X,X11,Xserver,X-Server,XFree86,Display,显卡,硬件加速,图形,X 服务器,显示 Keywords[zh_TW]=OpenGL,DRI,GLX,3D,VideoCard,Hardware Acceleration,Graphics,X,X11,Xserver,X-Server,XFree86,Display,顯示卡,硬體加速,圖形,顯示 -Categories=Qt;KDE;X-KDE-information; +Categories=Qt;KDE;X-KDE-settings-hardware; + diff --git a/kcontrol/info/partitions.desktop b/kcontrol/info/partitions.desktop index 89851a34e..ec9fce463 100644 --- a/kcontrol/info/partitions.desktop +++ b/kcontrol/info/partitions.desktop @@ -243,4 +243,5 @@ Keywords[zh_CN]=Partitions,Harddrive,HD,System Information,分区,硬盘,系统� Keywords[zh_TW]=Partitions,Harddrive,HD,System Information,磁碟分割區,硬式磁碟機,硬碟,系統資訊 Keywords[zu]=Izahluko,Harddrive,HD,Ulwazi Lwesistimu -Categories=Qt;KDE;X-KDE-information; +Categories=Qt;KDE;X-KDE-settings-hardware; + diff --git a/kcontrol/info/pci.desktop b/kcontrol/info/pci.desktop index 9ee4452b3..d60a876ef 100644 --- a/kcontrol/info/pci.desktop +++ b/kcontrol/info/pci.desktop @@ -177,4 +177,5 @@ Keywords[xh]=PCI,PCI-Amacebo,PCI-Ibhasi,Ulwazi lwendlela Keywords[zh_CN]=PCI,PCI-Devices,PCI-Bus,System Information,PCI 设备,PCI 总线,系统信息 Keywords[zh_TW]=PCI,PCI-Devices,PCI-Bus,System Information,PCI 設備,PCI 匯流排,系統資訊 Keywords[zu]=PCI,Amathuluzi-PCI,Ibhasi-PCI,Ulwaz Lwesistimu -Categories=Qt;KDE;X-KDE-information; +Categories=Qt;KDE;X-KDE-settings-hardware; + diff --git a/kcontrol/info/processor.desktop b/kcontrol/info/processor.desktop index 580aa7e3a..c72f50e2c 100644 --- a/kcontrol/info/processor.desktop +++ b/kcontrol/info/processor.desktop @@ -246,4 +246,5 @@ Keywords[xh]=Umqhubekekisi,CPU,FPU,MHz,Inkcukacha Yendlela yokusebenza Keywords[zh_CN]=Processor,CPU,FPU,MHz,System Information,处理器,系统信息 Keywords[zh_TW]=Processor,CPU,FPU,MHz,System Information,處理器,中央處理器,浮點運算器,系統資訊 Keywords[zu]=Umqhubekisi,CPU,FPU,MHz,Ulwazi Lwesistimu -Categories=Qt;KDE;X-KDE-information; +Categories=Qt;KDE;X-KDE-settings-hardware; + diff --git a/kcontrol/info/scsi.desktop b/kcontrol/info/scsi.desktop index 9b62edbf7..9b2aa65a8 100644 --- a/kcontrol/info/scsi.desktop +++ b/kcontrol/info/scsi.desktop @@ -174,4 +174,5 @@ Keywords[xh]=SCSI,SCSI-Ibhasi,Ulwazi lwendlela Keywords[zh_CN]=SCSI,SCSI-Bus,System Information,SCSI 总线,系统信息 Keywords[zh_TW]=SCSI,SCSI-Bus,System Information,系統資訊 Keywords[zu]=SCSI,Ibhasi-SCSI,Ulwazi Lwesistimu -Categories=Qt;KDE;X-KDE-information; +Categories=Qt;KDE;X-KDE-settings-hardware; + diff --git a/kcontrol/info/sound.desktop b/kcontrol/info/sound.desktop index 6a96da85d..4f8942871 100644 --- a/kcontrol/info/sound.desktop +++ b/kcontrol/info/sound.desktop @@ -240,4 +240,5 @@ Keywords[vi]=Âm thanh,âm,Bo mạch âm thanh,Midi,OSS,Thông tin Hệ thống Keywords[wa]=Son,Audiocåte son,MIDI,OSS,informåcion do sistinme Keywords[zh_CN]=Sound,Audio,Soundcard,MIDI,OSS,System Information,音频,音响,声卡,系统信息 Keywords[zh_TW]=Sound,Audio,Soundcard,Midi,OSS,系統資訊 -Categories=Qt;KDE;X-KDE-information; +Categories=Qt;KDE;X-KDE-settings-hardware; + diff --git a/kcontrol/info/xserver.desktop b/kcontrol/info/xserver.desktop index 1751a4b6e..e54b9e2a4 100644 --- a/kcontrol/info/xserver.desktop +++ b/kcontrol/info/xserver.desktop @@ -224,4 +224,4 @@ Keywords[wa]=X,X-Server,XServer,sierveu X,XFree86,håynaedje,Display,cåte videy Keywords[zh_CN]=X,X-Server,XServer,XFree86,Display,VideoCard,System InformationX 服务器,显示器,显卡,系统信息 Keywords[zh_TW]=X,X-Server,XServer,XFree86,Display,VideoCard,System Information,X 伺服器,X伺服器,顯示器,顯示卡,系統資訊 -Categories=Qt;KDE;X-KDE-information; +Categories=Qt;KDE;X-KDE-settings-hardware; diff --git a/kcontrol/input/consoleUserPerms b/kcontrol/input/consoleUserPerms index 015df642f..af7e267bd 100755 --- a/kcontrol/input/consoleUserPerms +++ b/kcontrol/input/consoleUserPerms @@ -1,42 +1,16 @@ -#!/bin/bash -# -# /etc/hotplug/usb/consoleUserPerms -# -# Sets up newly plugged in USB device so that the user who owns -# the console according to pam_console can access it from user space -# -# Note that for this script to work, you'll need all of the following: -# a) a line in the file /etc/hotplug/usb.usermap or another usermap file -# in /etc/hotplug/usb/ that corresponds to the device you are using. -# b) a setup using pam_console creates the respective lock files -# containing the name of the respective user. You can check for that -# by executing "echo `cat /var/{run,lock}/console.lock`" and -# verifying the appropriate user is mentioned somewhere there. -# c) a Linux kernel supporting hotplug and usbdevfs -# d) the hotplug package (http://linux-hotplug.sourceforge.net/) -# -# In the usermap file, the first field "usb module" should be named -# "consoleUserPerms" to invoke this script. -# +#!/bin/sh -if [ "${ACTION}" = "add" ] && [ -f "${DEVICE}" ] +GROUP=plugdev + +if [ "${ACTION}" = "add" ] then - # New code, using lock files instead of copying /dev/console permissions - # This also works with non-kdm logins (e.g. on a virtual terminal) - # Idea and code from Nalin Dahyabhai <[email protected]> - if [ -f /var/run/console.lock ] - then - CONSOLEOWNER=`cat /var/run/console.lock` - elif [ -f /var/lock/console.lock ] - then - CONSOLEOWNER=`cat /var/lock/console.lock` - else - CONSOLEOWNER= - fi - if [ -n "$CONSOLEOWNER" ] - then - chmod 0000 "${DEVICE}" - chown "$CONSOLEOWNER" "${DEVICE}" - chmod 0600 "${DEVICE}" + if getent group $GROUP > /dev/null; then + N=0 + while [ ! -e $DEVICE ] && [ $N -lt 25 ]; do + sleep 1 + N=$(expr $N + 1) + done + chmod 660 "${DEVICE}" + chown root:$GROUP "${DEVICE}" fi fi diff --git a/kcontrol/ioslaveinfo/ioslaveinfo.desktop b/kcontrol/ioslaveinfo/ioslaveinfo.desktop index a9ece6f71..ccc39962e 100644 --- a/kcontrol/ioslaveinfo/ioslaveinfo.desktop +++ b/kcontrol/ioslaveinfo/ioslaveinfo.desktop @@ -234,4 +234,4 @@ X-KDE-Library=ioslaveinfo X-KDE-ParentApp=kinfocenter -Categories=Qt;KDE;X-KDE-information; +Categories=Qt;KDE;X-KDE-settings-network; diff --git a/kcontrol/kcontrol/KControl.desktop b/kcontrol/kcontrol/KControl.desktop index c174a867a..1640fca11 100644 --- a/kcontrol/kcontrol/KControl.desktop +++ b/kcontrol/kcontrol/KControl.desktop @@ -91,3 +91,5 @@ Name[zu]=Indawo Yokulawula X-DCOP-ServiceType=Unique Categories=Qt;KDE;Core; +OnlyShowIn=KDE; +NoDisplay=true diff --git a/kcontrol/kcontrol/kinfocenter.desktop b/kcontrol/kcontrol/kinfocenter.desktop index cd3e27f0a..56be4ec0d 100644 --- a/kcontrol/kcontrol/kinfocenter.desktop +++ b/kcontrol/kcontrol/kinfocenter.desktop @@ -107,3 +107,4 @@ GenericName[zh_TW]=資訊中心 X-DCOP-ServiceType=Unique Categories=Qt;KDE;System; +OnlyShowIn=KDE; diff --git a/kcontrol/kdm/kdm-appear.cpp b/kcontrol/kdm/kdm-appear.cpp index 684371d74..7d1d034ca 100644 --- a/kcontrol/kdm/kdm-appear.cpp +++ b/kcontrol/kdm/kdm-appear.cpp @@ -442,7 +442,7 @@ void KDMAppearanceWidget::load() config->setGroup("X-*-Greeter"); // Read the greeting string - greetstr_lined->setText(config->readEntry("GreetString", i18n("Welcome to %s at %n"))); + greetstr_lined->setText(config->readEntry("GreetString", i18n("Welcome to Kubuntu at %n"))); // Regular logo or clock QString logoArea = config->readEntry("LogoArea", "Logo" ); @@ -485,7 +485,7 @@ void KDMAppearanceWidget::load() void KDMAppearanceWidget::defaults() { - greetstr_lined->setText( i18n("Welcome to %s at %n") ); + greetstr_lined->setText( i18n("Welcome to Kubuntu at %n") ); logoRadio->setChecked( true ); slotAreaRadioClicked( KdmLogo ); setLogo( "" ); diff --git a/kcontrol/kdm/kdm-font.cpp b/kcontrol/kdm/kdm-font.cpp index da67e5eaa..456573b4d 100644 --- a/kcontrol/kdm/kdm-font.cpp +++ b/kcontrol/kdm/kdm-font.cpp @@ -92,7 +92,7 @@ void KDMFontWidget::set_def() { stdFontChooser->setFont(QFont("Sans Serif", 10)); failFontChooser->setFont(QFont("Sans Serif", 10, QFont::Bold)); - greetingFontChooser->setFont(QFont("Serif", 20)); + greetingFontChooser->setFont(QFont("Sans Serif", 22)); } void KDMFontWidget::save() @@ -128,7 +128,7 @@ void KDMFontWidget::load() void KDMFontWidget::defaults() { set_def(); - aacb->setChecked(false); + aacb->setChecked(true); } #include "kdm-font.moc" diff --git a/kcontrol/kdm/kdm-shut.cpp b/kcontrol/kdm/kdm-shut.cpp index c958e1464..2eb88ac51 100644 --- a/kcontrol/kdm/kdm-shut.cpp +++ b/kcontrol/kdm/kdm-shut.cpp @@ -200,7 +200,7 @@ void KDMSessionsWidget::load() config->setGroup("Shutdown"); restart_lined->setURL(config->readEntry("RebootCmd", "/sbin/reboot")); - shutdown_lined->setURL(config->readEntry("HaltCmd", "/sbin/halt")); + shutdown_lined->setURL(config->readEntry("HaltCmd", "/sbin/poweroff")); bm_combo->setCurrentId(config->readEntry("BootManager", "None")); } @@ -210,7 +210,7 @@ void KDMSessionsWidget::load() void KDMSessionsWidget::defaults() { restart_lined->setURL("/sbin/reboot"); - shutdown_lined->setURL("/sbin/halt"); + shutdown_lined->setURL("/sbin/poweroff"); sdlcombo->setCurrentItem(SdAll); sdrcombo->setCurrentItem(SdRoot); diff --git a/kcontrol/keys/shortcuts.cpp b/kcontrol/keys/shortcuts.cpp index e65364f4c..2ceceb46a 100644 --- a/kcontrol/keys/shortcuts.cpp +++ b/kcontrol/keys/shortcuts.cpp @@ -24,9 +24,12 @@ #include "shortcuts.h" +#include <stdlib.h> + #include <qdir.h> #include <qlayout.h> #include <qwhatsthis.h> +#include <qcheckbox.h> #include <kapplication.h> #include <kdebug.h> @@ -101,6 +104,8 @@ QString ShortcutsModule::quickHelp() const void ShortcutsModule::initGUI() { + QString kde_winkeys_env_dir = KGlobal::dirs()->localkdedir() + "/env/"; + kdDebug(125) << "A-----------" << endl; KAccelActions* keys = &m_actionsGeneral; // see also KShortcutsModule::init() below !!! @@ -172,8 +177,27 @@ void ShortcutsModule::initGUI() m_pTab->setMargin( KDialog::marginHint() ); pVLayout->addWidget( m_pTab ); + // See if ~/.kde3/env/win-key.sh exists + QFile f( kde_winkeys_env_dir + "win-key.sh" ); + if ( f.exists() == false ) { + // No, it does not, so Win is a modifier + m_bUseRmWinKeys = true; + } + else { + // Yes, it does, so Win is a key + m_bUseRmWinKeys = false; + } m_pListGeneral = new KAccelShortcutList( m_actionsGeneral, true ); + m_pkcGeneral = new KKeyChooser( m_pListGeneral, this, KKeyChooser::Global, false ); + m_pkcGeneral->resize (m_pkcGeneral->sizeHint() ); + if (system("xmodmap 1> /dev/null 2> /dev/null") == 0) { + m_useRmWinKeys = new QCheckBox( i18n("Use Win key as modifier (uncheck to bind Win key to Menu)"), this ); + m_useRmWinKeys->resize( m_useRmWinKeys->sizeHint() ); + m_useRmWinKeys->setChecked( m_bUseRmWinKeys ); + pVLayout->addWidget( m_useRmWinKeys, 1, 0 ); + connect( m_useRmWinKeys, SIGNAL(clicked()), SLOT(slotUseRmWinKeysClicked()) ); + } m_pTab->addTab( m_pkcGeneral, i18n("&Global Shortcuts") ); connect( m_pkcGeneral, SIGNAL(keyChange()), SLOT(slotKeyChange()) ); @@ -432,4 +456,37 @@ void ShortcutsModule::slotRemoveScheme() { } +void ShortcutsModule::slotUseRmWinKeysClicked() +{ + QString kde_winkeys_env_dir = KGlobal::dirs()->localkdedir() + "/env/"; + + // See if ~/.kde3/env/win-key.sh exists + QFile f( kde_winkeys_env_dir + "win-key.sh" ); + if ( f.exists() == false ) { + // No, it does not, so Win is currently a modifier + if (m_useRmWinKeys->isChecked() == false) { + // Create the file + if ( f.open( IO_WriteOnly ) ) { + QTextStream stream( &f ); + stream << "xmodmap -e 'keycode 133=Menu'" << "\n"; + stream << "xmodmap -e 'keycode 134=Menu'" << "\n"; + f.close(); + system("xmodmap -e 'keycode 133=Menu'"); + system("xmodmap -e 'keycode 134=Menu'"); + } + } + } + else { + // Yes, it does, so Win is currently a key + m_bUseRmWinKeys = false; + if (m_useRmWinKeys->isChecked() == true) { + // Remove the file + f.remove(); + // Update key mappings + system("xmodmap -e 'keycode 133=Super_L'"); + system("xmodmap -e 'keycode 134=Super_R'"); + } + } +} + #include "shortcuts.moc" diff --git a/kcontrol/keys/shortcuts.h b/kcontrol/keys/shortcuts.h index a16a619e3..e51d8cb7a 100644 --- a/kcontrol/keys/shortcuts.h +++ b/kcontrol/keys/shortcuts.h @@ -25,6 +25,7 @@ #define __SHORTCUTS_MODULE_H #include <qbuttongroup.h> +#include <qcheckbox.h> #include <qpushbutton.h> #include <qradiobutton.h> #include <qtabwidget.h> @@ -61,6 +62,7 @@ class ShortcutsModule : public QWidget void slotSelectScheme( int = 0 ); void slotSaveSchemeAs(); void slotRemoveScheme(); + void slotUseRmWinKeysClicked(); private: QTabWidget* m_pTab; @@ -72,6 +74,8 @@ class ShortcutsModule : public QWidget KAccelActions m_actionsGeneral, m_actionsSequence;//, m_actionsApplication; KShortcutList* m_pListGeneral, * m_pListSequence, * m_pListApplication; KKeyChooser* m_pkcGeneral, * m_pkcSequence, * m_pkcApplication; + QCheckBox* m_useRmWinKeys; + bool m_bUseRmWinKeys; }; #endif // __SHORTCUTS_MODULE_H diff --git a/kcontrol/kfontinst/kfontinst/Fontmap.cpp b/kcontrol/kfontinst/kfontinst/Fontmap.cpp index 0f8178dee..87cfabad8 100644 --- a/kcontrol/kfontinst/kfontinst/Fontmap.cpp +++ b/kcontrol/kfontinst/kfontinst/Fontmap.cpp @@ -65,13 +65,13 @@ static bool parseLine(const char *line, QString &ps, QString &fname, bool &isAli char a[constMaxLen+1], b[constFileMaxLen+1]; - const char *slash1=strchr(line, '/'), + char *slash1=(char*)strchr(line, '/'), *space1=slash1 ? findSpace(slash1) : NULL, //strchr(slash1, ' ') : NULL, - *ob=slash1 ? strchr(slash1, '(') : NULL, - *cb=ob ? strchr(ob, ')') : NULL, - *slash2=space1 && !ob && !cb ? strchr(space1, '/') : NULL, + *ob=slash1 ? (char*)strchr(slash1, '(') : NULL, + *cb=ob ? (char*)strchr(ob, ')') : NULL, + *slash2=space1 && !ob && !cb ? (char*)strchr(space1, '/') : NULL, *space2=slash2 ? findSpace(slash2) : NULL, // strchr(slash2, ' ') : NULL, - *semic=cb || space2 ? strchr(cb ? cb : space2, ';') : NULL; + *semic=cb || space2 ? (char*)strchr(cb ? cb : space2, ';') : NULL; if(semic && space1-slash1<constMaxLen) { diff --git a/kcontrol/kfontinst/kfontinst/XConfig.cpp b/kcontrol/kfontinst/kfontinst/XConfig.cpp index 490c8dfe5..aa63e52af 100644 --- a/kcontrol/kfontinst/kfontinst/XConfig.cpp +++ b/kcontrol/kfontinst/kfontinst/XConfig.cpp @@ -356,8 +356,8 @@ static char * getItem(char **start, char **end, const char *key, unsigned int &s if(s && *s=='\"' && s<*end) { - char *e=strchr(s+1, '\"'), - *nl=strchr(s+1, '\n'); + char *e=(char*)strchr(s+1, '\"'), + *nl=(char*)strchr(s+1, '\n'); if(e && e<*end && (!nl || nl>e) && e-s<=constMaxItemLen) { diff --git a/kcontrol/kicker/main.cpp b/kcontrol/kicker/main.cpp index 4ef0f842f..021cfbdd9 100644 --- a/kcontrol/kicker/main.cpp +++ b/kcontrol/kicker/main.cpp @@ -132,6 +132,18 @@ void KickerConfig::init() configFileWatch->startScan(); } +void KickerConfig::restartKicker() +{ + // Tell kicker to restart + if (!kapp->dcopClient()->isAttached()) + { + kapp->dcopClient()->attach(); + } + QCString appname; + appname = "kicker"; + kapp->dcopClient()->send(appname, appname, "restart", ""); +} + void KickerConfig::notifyKicker() { kdDebug() << "KickerConfig::notifyKicker()" << endl; diff --git a/kcontrol/kicker/main.h b/kcontrol/kicker/main.h index cb585b077..1797f7637 100644 --- a/kcontrol/kicker/main.h +++ b/kcontrol/kicker/main.h @@ -43,6 +43,7 @@ public: QString configName(); void notifyKicker(); + void restartKicker(); QString quickHelp() const; KAboutData *aboutData(); diff --git a/kcontrol/kicker/menutab.ui b/kcontrol/kicker/menutab.ui index 8d49a7965..e64285767 100644 --- a/kcontrol/kicker/menutab.ui +++ b/kcontrol/kicker/menutab.ui @@ -143,6 +143,155 @@ </size> </property> </spacer> + <widget class="QCheckBox" row="0" column="0" colspan="2"> + <property name="name"> + <cstring>kcfg_ShowKMenuText</cstring> + </property> + <property name="text"> + <string>Display text in K Menu button</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string><qt>When this option is selected the text below will be shown in the K Menu button.</string> + </property> + </widget> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QLineEdit" row="0" column="1" colspan="3"> + <property name="name"> + <cstring>kcfg_KMenuText</cstring> + </property> + <property name="maxLength"> + <number>35</number> + </property> + </widget> + <widget class="QLabel" row="3" column="0" colspan="2"> + <property name="name"> + <cstring>TextLabel1_3_3_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Custom K Menu button icon:</string> + </property> + </widget> + <widget class="KPushButton" row="3" column="3" colspan="2"> + <property name="name"> + <cstring>btnCustomKMenuIcon</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>26</width> + <height>26</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>26</width> + <height>26</height> + </size> + </property> + <property name="acceptDrops"> + <bool>false</bool> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>TextLabel1_3_3_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Text:</string> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>TextLabel1_3_3_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Font:</string> + </property> + </widget> + <widget class="KFontRequester" row="2" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>kcfg_ButtonFont</cstring> + </property> + </widget> + <spacer row="3" column="3"> + <property name="name"> + <cstring>spacer6</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + <spacer> + <property name="name"> + <cstring>spacer8</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>MinimumExpanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>0</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> <property name="name"> <cstring>m_editKMenuButton</cstring> @@ -194,187 +343,266 @@ </widget> </hbox> </widget> - <widget class="QGroupBox"> - <property name="name"> - <cstring>m_browserGroup</cstring> - </property> - <property name="title"> - <string>QuickBrowser Menus</string> - </property> - <grid> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="QLayoutWidget" row="1" column="0"> - <property name="name"> - <cstring>Layout3</cstring> - </property> - <hbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="QLabel"> - <property name="name"> - <cstring>m_maxQuickBrowserItemsLabel</cstring> - </property> - <property name="text"> - <string>Ma&ximum number of entries:</string> - </property> - <property name="buddy" stdset="0"> - <cstring>kcfg_MaxEntries2</cstring> - </property> - <property name="whatsThis" stdset="0"> - <string>When browsing directories that contain a lot of files, the QuickBrowser can sometimes hide your whole desktop. Here you can limit the number of entries shown at a time in the QuickBrowser. This is particularly useful for low screen resolutions.</string> - </property> - </widget> - <widget class="KIntNumInput"> - <property name="name"> - <cstring>kcfg_MaxEntries2</cstring> - </property> - <property name="value"> - <number>30</number> - </property> - <property name="minValue"> - <number>10</number> - </property> - <property name="maxValue"> - <number>100</number> - </property> - <property name="whatsThis" stdset="0"> - <string>When browsing directories that contain a lot of files, the QuickBrowser can sometimes hide your whole desktop. Here you can limit the number of entries shown at a time in the QuickBrowser. This is particularly useful for low screen resolutions.</string> - </property> - </widget> - </hbox> - </widget> - <widget class="QCheckBox" row="0" column="0"> - <property name="name"> - <cstring>kcfg_ShowHiddenFiles</cstring> - </property> - <property name="text"> - <string>Show hidden fi&les</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - <property name="whatsThis" stdset="0"> - <string>If this option is enabled, hidden files (i.e. files beginning with a dot) will be shown in the QuickBrowser menus.</string> - </property> - </widget> - <spacer row="0" column="1" rowspan="2" colspan="1"> - <property name="name"> - <cstring>Spacer7</cstring> - </property> - <property name="orientation"> - <enum>Horizontal</enum> - </property> - <property name="sizeType"> - <enum>Expanding</enum> - </property> - <property name="sizeHint"> - <size> - <width>20</width> - <height>0</height> - </size> - </property> - </spacer> - </grid> - </widget> - <widget class="QButtonGroup"> - <property name="name"> - <cstring>m_pRecentOrderGroup</cstring> - </property> - <property name="title"> - <string>QuickStart Menu Items</string> - </property> - <grid> - <property name="name"> - <cstring>unnamed</cstring> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> </property> - <widget class="QLayoutWidget" row="2" column="0"> - <property name="name"> - <cstring>Layout4</cstring> - </property> - <hbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="QLabel"> - <property name="name"> - <cstring>TextLabel2</cstring> - </property> - <property name="text"> - <string>Maxim&um number of entries:</string> - </property> - <property name="buddy" stdset="0"> - <cstring>kcfg_NumVisibleEntries</cstring> - </property> - <property name="whatsThis" stdset="0"> - <string>This option allows you to define the maximum number of applications that should be displayed in the QuickStart menu area.</string> - </property> - </widget> - <widget class="KIntNumInput"> - <property name="name"> - <cstring>kcfg_NumVisibleEntries</cstring> - </property> - <property name="value"> - <number>5</number> - </property> - <property name="minValue"> - <number>0</number> - </property> - <property name="maxValue"> - <number>20</number> - </property> - <property name="whatsThis" stdset="0"> - <string>This option allows you to define how many applications should be displayed at most in the QuickStart menu area.</string> - </property> - </widget> - </hbox> - </widget> - <widget class="QRadioButton" row="0" column="0"> - <property name="name"> - <cstring>kcfg_RecentVsOften</cstring> - </property> - <property name="text"> - <string>Show the &applications most recently used</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - <property name="whatsThis" stdset="0"> - <string>When this option is selected the QuickStart menu area will be filled with the applications you have used most recently.</string> - </property> - </widget> - <widget class="QRadioButton" row="1" column="0"> - <property name="name"> - <cstring>m_showFrequent</cstring> - </property> - <property name="text"> - <string>Show the applications most fre&quently used</string> - </property> - <property name="whatsThis" stdset="0"> - <string>When this option is selected the QuickStart menu area will be filled with the applications you use most frequently.</string> - </property> - </widget> - <spacer row="0" column="1" rowspan="3" colspan="1"> - <property name="name"> - <cstring>Spacer8</cstring> - </property> - <property name="orientation"> - <enum>Horizontal</enum> - </property> - <property name="sizeType"> - <enum>Expanding</enum> - </property> - <property name="sizeHint"> - <size> - <width>20</width> - <height>0</height> - </size> - </property> - </spacer> - </grid> - </widget> + <widget class="QGroupBox" row="0" column="0"> + <property name="name"> + <cstring>m_browserGroup</cstring> + </property> + <property name="title"> + <string>QuickBrowser Menus</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>Layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>m_maxQuickBrowserItemsLabel</cstring> + </property> + <property name="text"> + <string>Ma&ximum number of entries:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>kcfg_MaxEntries2</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string>When browsing directories that contain a lot of files, the QuickBrowser can sometimes hide your whole desktop. Here you can limit the number of entries shown at a time in the QuickBrowser. This is particularly useful for low screen resolutions.</string> + </property> + </widget> + <widget class="KIntNumInput"> + <property name="name"> + <cstring>kcfg_MaxEntries2</cstring> + </property> + <property name="value"> + <number>30</number> + </property> + <property name="minValue"> + <number>10</number> + </property> + <property name="maxValue"> + <number>100</number> + </property> + <property name="whatsThis" stdset="0"> + <string>When browsing directories that contain a lot of files, the QuickBrowser can sometimes hide your whole desktop. Here you can limit the number of entries shown at a time in the QuickBrowser. This is particularly useful for low screen resolutions.</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QCheckBox" row="0" column="0"> + <property name="name"> + <cstring>kcfg_ShowHiddenFiles</cstring> + </property> + <property name="text"> + <string>Show hidden fi&les</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>If this option is enabled, hidden files (i.e. files beginning with a dot) will be shown in the QuickBrowser menus.</string> + </property> + </widget> + <spacer row="0" column="1" rowspan="2" colspan="1"> + <property name="name"> + <cstring>Spacer7</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>0</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="QGroupBox" row="1" column="0"> + <property name="name"> + <cstring>m_recentGroup</cstring> + </property> + <property name="title"> + <string>Recent Documents Menu</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>Layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>m_maxRecentDocumentsItemsLabel</cstring> + </property> + <property name="text"> + <string>Ma&ximum number of entries:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>kcfg_MaxEntries2</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string>This sets the maximum number of recently accessed documents stored for fast retrieval.</string> + </property> + </widget> + <widget class="KIntNumInput"> + <property name="name"> + <cstring>maxrecentdocs</cstring> + </property> + <property name="value"> + <number>10</number> + </property> + <property name="minValue"> + <number>10</number> + </property> + <property name="maxValue"> + <number>100</number> + </property> + <property name="whatsThis" stdset="0"> + <string>This sets the maximum number of recently accessed documents stored for fast retrieval.</string> + </property> + </widget> + </hbox> + </widget> + <spacer row="0" column="1" rowspan="2" colspan="1"> + <property name="name"> + <cstring>Spacer7</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>0</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="QButtonGroup" row="0" column="1" rowspan="2"> + <property name="name"> + <cstring>m_pRecentOrderGroup</cstring> + </property> + <property name="title"> + <string>QuickStart Menu Items</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="2" column="0"> + <property name="name"> + <cstring>Layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel2</cstring> + </property> + <property name="text"> + <string>Maxim&um number of entries:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>kcfg_NumVisibleEntries</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string>This option allows you to define the maximum number of applications that should be displayed in the QuickStart menu area.</string> + </property> + </widget> + <widget class="KIntNumInput"> + <property name="name"> + <cstring>kcfg_NumVisibleEntries</cstring> + </property> + <property name="value"> + <number>5</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="maxValue"> + <number>20</number> + </property> + <property name="whatsThis" stdset="0"> + <string>This option allows you to define how many applications should be displayed at most in the QuickStart menu area.</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QRadioButton" row="0" column="0"> + <property name="name"> + <cstring>kcfg_RecentVsOften</cstring> + </property> + <property name="text"> + <string>Show the &applications most recently used</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>When this option is selected the QuickStart menu area will be filled with the applications you have used most recently.</string> + </property> + </widget> + <widget class="QRadioButton" row="1" column="0"> + <property name="name"> + <cstring>m_showFrequent</cstring> + </property> + <property name="text"> + <string>Show the applications most fre&quently used</string> + </property> + <property name="whatsThis" stdset="0"> + <string>When this option is selected the QuickStart menu area will be filled with the applications you use most frequently.</string> + </property> + </widget> + <spacer row="0" column="1" rowspan="3" colspan="1"> + <property name="name"> + <cstring>Spacer8</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>0</height> + </size> + </property> + </spacer> + </grid> + </widget> + </grid> </vbox> </widget> <tabstops> diff --git a/kcontrol/kicker/menutab_impl.cpp b/kcontrol/kicker/menutab_impl.cpp index 55cabaa88..935f04684 100644 --- a/kcontrol/kicker/menutab_impl.cpp +++ b/kcontrol/kicker/menutab_impl.cpp @@ -32,8 +32,13 @@ #include <knuminput.h> #include <kstandarddirs.h> +#include <kicondialog.h> +#include <kiconloader.h> + #include "main.h" +#include "kickerSettings.h" + #include "menutab_impl.h" #include "menutab_impl.moc" @@ -66,6 +71,25 @@ MenuTab::MenuTab( QWidget *parent, const char* name ) { // connections connect(m_editKMenuButton, SIGNAL(clicked()), SLOT(launchMenuEditor())); + connect(btnCustomKMenuIcon, SIGNAL(clicked()), SLOT(launchIconEditor())); + connect(kcfg_KMenuText, SIGNAL(textChanged(QString)), SLOT(kmenuChanged())); + connect(kcfg_ShowKMenuText, SIGNAL(toggled(bool)), SLOT(kmenuChanged())); + //connect(kcfg_ButtonFont, SIGNAL(fontSelected(const QFont &)), SLOT(kmenuChanged())); + connect(maxrecentdocs, SIGNAL(valueChanged(int)), this, SLOT(changed())); + + KIconLoader * ldr = KGlobal::iconLoader(); + QPixmap kmenu_icon; + m_kmenu_icon = KickerSettings::customKMenuIcon(); + if (m_kmenu_icon.isNull() == true) { + m_kmenu_icon = QString("kmenu"); + } + kmenu_icon = ldr->loadIcon(m_kmenu_icon, KIcon::Small, KIcon::SizeSmall); + btnCustomKMenuIcon->setPixmap(kmenu_icon); + + KConfig *config; + config = new KConfig(QString::fromLatin1("kdeglobals"), false, false); + config->setGroup(QString::fromLatin1("RecentDocuments")); + maxrecentdocs->setValue(config->readNumEntry(QString::fromLatin1("MaxEntries"), 10)); m_browserGroupLayout->setColStretch( 1, 1 ); m_pRecentOrderGroupLayout->setColStretch( 1, 1 ); @@ -156,6 +180,22 @@ void MenuTab::save() c->writeEntry("Extensions", ext); c->sync(); + + // Save KMenu settings + c->setGroup("KMenu"); + c->writeEntry("CustomIcon", m_kmenu_icon); + c->sync(); + + // Save recent documents + KConfig *config; + config = new KConfig(QString::fromLatin1("kdeglobals"), false, false); + config->setGroup(QString::fromLatin1("RecentDocuments")); + config->writeEntry("MaxEntries", maxrecentdocs->value()); + config->sync(); + + if (m_kmenu_button_changed == true) { + system("dcop kicker kicker restart &"); + } } void MenuTab::defaults() @@ -179,3 +219,25 @@ void MenuTab::launchMenuEditor() i18n("Application Missing")); } } + +void MenuTab::launchIconEditor() +{ + KIconDialog dlg(this); + QString newIcon = dlg.selectIcon(KIcon::Small, KIcon::Application); + if (newIcon.isEmpty()) + return; + + m_kmenu_icon = newIcon; + KIconLoader * ldr = KGlobal::iconLoader(); + QPixmap kmenu_icon; + kmenu_icon = ldr->loadIcon(m_kmenu_icon, KIcon::Small, KIcon::SizeSmall); + btnCustomKMenuIcon->setPixmap(kmenu_icon); + m_kmenu_button_changed = true; + + emit changed(); +} + +void MenuTab::kmenuChanged() +{ + m_kmenu_button_changed = true; +} diff --git a/kcontrol/kicker/menutab_impl.h b/kcontrol/kicker/menutab_impl.h index 20ed393e1..71c669048 100644 --- a/kcontrol/kicker/menutab_impl.h +++ b/kcontrol/kicker/menutab_impl.h @@ -62,10 +62,14 @@ signals: public slots: void launchMenuEditor(); + void launchIconEditor(); + void kmenuChanged(); protected: kSubMenuItem *m_bookmarkMenu; kSubMenuItem *m_quickBrowserMenu; + QString m_kmenu_icon; + bool m_kmenu_button_changed; }; #endif diff --git a/kcontrol/kio/uasproviders/safari20.desktop b/kcontrol/kio/uasproviders/safari20.desktop index 14f3a8883..d86fe1977 100644 --- a/kcontrol/kio/uasproviders/safari20.desktop +++ b/kcontrol/kio/uasproviders/safari20.desktop @@ -51,7 +51,7 @@ Name[zh_TW]=使用者代理描述 (Safari 2.0 on MacOS X) Type=Service ServiceTypes=UserAgentStrings X-KDE-UA-TAG=SAF -X-KDE-UA-FULL=Mozilla/5.0 (Macintosh; U; PPC Mac OS X; appLanguage) AppleWebKit/412 (KHTML, like Gecko) Safari/412 +X-KDE-UA-FULL=Mozilla/5.0 (Macintosh; U; PPC Mac OS X; appLanguage) AppleWebKit/418.8 (KHTML, like Gecko) Safari/419.3 X-KDE-UA-NAME=Safari X-KDE-UA-VERSION=2.0 X-KDE-UA-SYSNAME=Mac OS diff --git a/kcontrol/konq/rootopts.cpp b/kcontrol/konq/rootopts.cpp index c546aa3ee..1a14c68e3 100644 --- a/kcontrol/konq/rootopts.cpp +++ b/kcontrol/konq/rootopts.cpp @@ -129,14 +129,16 @@ void DesktopPathConfig::load( bool useDefaults ) { KConfig config("kdeglobals", true, false); // Desktop Paths - config.setReadDefaults( useDefaults ); - - config.setGroup("Paths"); - urDesktop->setURL( config.readPathEntry( "Desktop" , KGlobalSettings::desktopPath() )); + config.setReadDefaults( useDefaults ); + config.setGroup("Paths"); urAutostart->setURL( config.readPathEntry( "Autostart" , KGlobalSettings::autostartPath() )); - urDocument->setURL( config.readPathEntry( "Documents", KGlobalSettings::documentPath() )); - emit changed( useDefaults ); + KConfig xdguserconfig( QDir::homeDirPath()+"/.config/user-dirs.dirs" ); + + urDesktop->setURL( xdguserconfig.readPathEntry( "XDG_DESKTOP_DIR" , QDir::homeDirPath() + "/Desktop" ).remove( "\"" )); + urDocument->setURL( xdguserconfig.readPathEntry( "XDG_DOCUMENTS_DIR", QDir::homeDirPath()).remove( "\"" )); + + emit changed( useDefaults ); } void DesktopPathConfig::defaults() @@ -147,6 +149,7 @@ void DesktopPathConfig::defaults() void DesktopPathConfig::save() { KConfig *config = KGlobal::config(); + KConfig *xdgconfig = new KConfig( QDir::homeDirPath()+"/.config/user-dirs.dirs" ); KConfigGroupSaver cgs( config, "Paths" ); bool pathChanged = false; @@ -205,8 +208,7 @@ void DesktopPathConfig::save() if ( moveDir( KURL( KGlobalSettings::desktopPath() ), KURL( urlDesktop ), i18n("Desktop") ) ) { -// config->writeEntry( "Desktop", urDesktop->url()); - config->writePathEntry( "Desktop", urlDesktop, true, true ); + xdgconfig->writePathEntry( "XDG_DESKTOP_DIR", '"'+ urlDesktop + '"', true, false ); pathChanged = true; } } @@ -217,7 +219,6 @@ void DesktopPathConfig::save() autostartMoved = moveDir( KURL( KGlobalSettings::autostartPath() ), KURL( urAutostart->url() ), i18n("Autostart") ); if (autostartMoved) { -// config->writeEntry( "Autostart", Autostart->url()); config->writePathEntry( "Autostart", urAutostart->url(), true, true ); pathChanged = true; } @@ -239,12 +240,13 @@ void DesktopPathConfig::save() if (pathOk) { - config->writePathEntry( "Documents", path, true, true ); + xdgconfig->writePathEntry( "XDG_DOCUMENTS_DIR", '"' + path + '"', true, false ); pathChanged = true; } } config->sync(); + xdgconfig->sync(); if (pathChanged) { diff --git a/kcontrol/konqhtml/pluginopts.cpp b/kcontrol/konqhtml/pluginopts.cpp index 7fec6f9d3..f31af3c40 100644 --- a/kcontrol/konqhtml/pluginopts.cpp +++ b/kcontrol/konqhtml/pluginopts.cpp @@ -376,6 +376,8 @@ void KPluginOptions::dirLoad( KConfig *config, bool useDefault ) else {//keep sync with kdebase/nsplugins paths.append("$HOME/.mozilla/plugins"); paths.append("$HOME/.netscape/plugins"); + paths.append("/usr/lib/iceweasel/plugins"); + paths.append("/usr/lib/iceape/plugins"); paths.append("/usr/lib/firefox/plugins"); paths.append("/usr/lib64/browser-plugins"); paths.append("/usr/lib/browser-plugins"); diff --git a/kcontrol/krdb/krdb.cpp b/kcontrol/krdb/krdb.cpp index 690dbce9a..cd8f08905 100644 --- a/kcontrol/krdb/krdb.cpp +++ b/kcontrol/krdb/krdb.cpp @@ -524,7 +524,7 @@ void runRdb( uint flags ) if (kglobals.hasKey("XftHintStyle")) { - QString hintStyle = kglobals.readEntry("XftHintStyle", "hintmedium"); + QString hintStyle = kglobals.readEntry("XftHintStyle", "hintfull"); contents += "Xft.hinting: "; if(hintStyle.isEmpty()) contents += "-1\n"; @@ -540,7 +540,7 @@ void runRdb( uint flags ) if (kglobals.hasKey("XftSubPixel")) { - QString subPixel = kglobals.readEntry("XftSubPixel"); + QString subPixel = kglobals.readEntry("XftSubPixel", "none"); if(!subPixel.isEmpty()) contents += "Xft.rgba: " + subPixel + '\n'; } diff --git a/kcontrol/krdb/themes/Plastik/Plastik.xml b/kcontrol/krdb/themes/Plastik/Plastik.xml index 4e317ed59..53b115550 100644 --- a/kcontrol/krdb/themes/Plastik/Plastik.xml +++ b/kcontrol/krdb/themes/Plastik/Plastik.xml @@ -113,12 +113,12 @@ </panel> <widgets name="Plastik" /> <fonts> - <font value="Arial,12,-1,5,50,0,0,0,0,0" object="General" /> - <fixed value="Courier New,10,-1,5,50,0,0,0,0,0" object="General" /> - <toolBarFont value="Arial,12,-1,5,50,0,0,0,0,0" object="General" /> - <menuFont value="Arial,12,-1,5,50,0,0,0,0,0" object="General" /> - <activeFont value="Arial,12,-1,5,75,0,0,0,0,0" object="WM" /> - <taskbarFont value="Arial,11,-1,5,50,0,0,0,0,0" object="General" /> + <font value="Sans Serif,10,-1,5,50,0,0,0,0,0" object="General" /> + <fixed value="Monospace,10,-1,5,50,0,0,0,0,0" object="General" /> + <toolBarFont value="Sans Serif,10,-1,5,50,0,0,0,0,0" object="General" /> + <menuFont value="Sans Serif,10,-1,5,50,0,0,0,0,0" object="General" /> + <activeFont value="Sans Serif,10,-1,5,75,0,0,0,0,0" object="WM" /> + <taskbarFont value="Sans Serif,10,-1,5,50,0,0,0,0,0" object="General" /> <StandardFont value="" object="FMSettings" /> </fonts> </ktheme> diff --git a/kcontrol/locale/Makefile.am b/kcontrol/locale/Makefile.am index 8ca082408..6872f1436 100644 --- a/kcontrol/locale/Makefile.am +++ b/kcontrol/locale/Makefile.am @@ -26,7 +26,7 @@ timezones: messages: $(XGETTEXT) -ktranslate $(kcm_locale_la_SOURCES) -o $(podir)/kcmlocale.pot - $(XGETTEXT) TIMEZONES -o $(podir)/../kdelibs/timezones.pot + $(XGETTEXT) TIMEZONES -o $(podir)/timezones.pot xdg_apps_DATA = language.desktop diff --git a/kcontrol/locale/kcmlocale.cpp b/kcontrol/locale/kcmlocale.cpp index 5d746212e..0a24b4a59 100644 --- a/kcontrol/locale/kcmlocale.cpp +++ b/kcontrol/locale/kcmlocale.cpp @@ -47,7 +47,7 @@ KLocaleConfig::KLocaleConfig(KLocale *locale, : QWidget (parent, name), m_locale(locale) { - QGridLayout *lay = new QGridLayout(this, 3, 3, + QGridLayout *lay = new QGridLayout(this, 4, 3, KDialog::marginHint(), KDialog::spacingHint()); @@ -99,6 +99,65 @@ KLocaleConfig::KLocaleConfig(KLocale *locale, lay->setColStretch(1, 1); lay->setColStretch(2, 1); + + // Added jriddell 2007-01-08, for Kubuntu Language Selector spec + QHBoxLayout* languageSelectorLayout = new QHBoxLayout(); + installLanguage = new QPushButton(i18n("Install New Language"), this); + languageSelectorLayout->addWidget(installLanguage); + uninstallLanguage = new QPushButton(i18n("Uninstall Language"), this); + languageSelectorLayout->addWidget(uninstallLanguage); + selectLanguage = new QPushButton(i18n("Select System Language"), this); + languageSelectorLayout->addWidget(selectLanguage); + languageSelectorLayout->addStretch(); + lay->addMultiCellLayout(languageSelectorLayout, 3, 3, 0, 2); + + connect( installLanguage, SIGNAL(clicked()), this, SLOT(slotInstallLanguage()) ); + connect( uninstallLanguage, SIGNAL(clicked()), this, SLOT(slotUninstallLanguage()) ); + connect( selectLanguage, SIGNAL(clicked()), this, SLOT(slotSelectLanguage()) ); + +} + +void KLocaleConfig::slotInstallLanguage() +{ + KProcess *proc = new KProcess; + + *proc << "kdesu"; + *proc << "qt-language-selector --mode install"; + QApplication::connect(proc, SIGNAL(processExited(KProcess *)), + this, SLOT(slotLanguageSelectorExited(KProcess *))); + setEnabled(false); + proc->start(); +} + +void KLocaleConfig::slotUninstallLanguage() +{ + KProcess *proc = new KProcess; + + *proc << "kdesu"; + *proc << "qt-language-selector --mode uninstall"; + QApplication::connect(proc, SIGNAL(processExited(KProcess *)), + this, SLOT(slotLanguageSelectorExited(KProcess *))); + setEnabled(false); + proc->start(); +} + +void KLocaleConfig::slotSelectLanguage() +{ + KProcess *proc = new KProcess; + + *proc << "kdesu"; + *proc << "qt-language-selector --mode select"; + QApplication::connect(proc, SIGNAL(processExited(KProcess *)), + this, SLOT(slotLanguageSelectorExited(KProcess *))); + setEnabled(false); + proc->start(); +} + +void KLocaleConfig::slotLanguageSelectorExited(KProcess *) +{ + //reload here + loadLanguageList(); + setEnabled(true); } void KLocaleConfig::slotAddLanguage(const QString & code) diff --git a/kcontrol/locale/kcmlocale.h b/kcontrol/locale/kcmlocale.h index f71193418..46f954730 100644 --- a/kcontrol/locale/kcmlocale.h +++ b/kcontrol/locale/kcmlocale.h @@ -75,6 +75,11 @@ private slots: void slotLanguageDown(); void slotCheckButtons(); + void slotInstallLanguage(); + void slotUninstallLanguage(); + void slotSelectLanguage(); + void slotLanguageSelectorExited(KProcess *); + private: QStringList languageList() const; @@ -90,6 +95,10 @@ private: QPushButton * m_removeLanguage; QPushButton * m_upButton; QPushButton * m_downButton; + + QPushButton* installLanguage; + QPushButton* uninstallLanguage; + QPushButton* selectLanguage; }; #endif diff --git a/kcontrol/nics/nic.desktop b/kcontrol/nics/nic.desktop index cddf242f6..b2ad111eb 100644 --- a/kcontrol/nics/nic.desktop +++ b/kcontrol/nics/nic.desktop @@ -170,4 +170,5 @@ Comment[zh_CN]=网络接口信息 Comment[zh_TW]=網路界面資訊 Comment[zu]=Ulwazi lomxhumanisi woxhumano olusakazekile -Categories=Qt;KDE;X-KDE-information; +Categories=Qt;KDE;X-KDE-settings-network; + diff --git a/kcontrol/randr/Makefile.am b/kcontrol/randr/Makefile.am index 6707a380d..b0ca50920 100644 --- a/kcontrol/randr/Makefile.am +++ b/kcontrol/randr/Makefile.am @@ -13,7 +13,7 @@ kcm_randr_la_LDFLAGS = -module -avoid-version $(all_libraries) -no-undefined kcm_randr_la_LIBADD = librandrinternal.la $(LIB_KDEUI) $(LIB_XRANDR) noinst_HEADERS = randr.h krandrmodule.h krandrtray.h krandrapp.h ktimerdialog.h \ - krandrpassivepopup.h + krandrpassivepopup.h lowlevel_randr.h configdialog.h xdg_apps_DATA = krandrtray.desktop @@ -28,7 +28,7 @@ krandr_datadir = $(kde_appsdir)/.hidden bin_PROGRAMS = krandrtray -krandrtray_SOURCES = main.cpp krandrtray.cpp krandrapp.cpp krandrpassivepopup.cpp +krandrtray_SOURCES = main.cpp krandrtray.cpp krandrapp.cpp krandrpassivepopup.cpp configdialog.cpp lowlevel_randr.c krandrtray_LDFLAGS = $(all_libraries) $(KDE_RPATH) krandrtray_LDADD = librandrinternal.la $(LIB_KFILE) $(LIB_KUTILS) $(LIB_XRANDR) diff --git a/kcontrol/randr/configdialog.cpp b/kcontrol/randr/configdialog.cpp new file mode 100644 index 000000000..681610c66 --- /dev/null +++ b/kcontrol/randr/configdialog.cpp @@ -0,0 +1,87 @@ +// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- +/* This file is part of the KDE project + Copyright (C) 2000 by Carsten Pfeiffer <[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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#include <qlabel.h> +#include <qlayout.h> +#include <qlistview.h> +#include <qpushbutton.h> +#include <qtooltip.h> +#include <qwhatsthis.h> +#include <qvbuttongroup.h> +#include <assert.h> + +#include <kiconloader.h> +#include <klocale.h> +#include <kpopupmenu.h> +#include <kwinmodule.h> +#include <kregexpeditorinterface.h> +#include <kparts/componentfactory.h> + +#include "configdialog.h" + +ConfigDialog::ConfigDialog(KGlobalAccel *accel, + bool isApplet ) + : KDialogBase( Tabbed, i18n("Configure"), + Ok | Cancel | Help, + Ok, 0L, "config dialog" ) +{ + if ( isApplet ) + setHelp( QString::null, "krandrtray" ); + + QFrame *w = 0L; // the parent for the widgets + + w = addVBoxPage( i18n("Global &Shortcuts") ); + keysWidget = new KKeyChooser( accel, w ); +} + + +ConfigDialog::~ConfigDialog() +{ +} + +// prevent huge size due to long regexps in the action-widget +void ConfigDialog::show() +{ + if ( !isVisible() ) { + KWinModule module(0, KWinModule::INFO_DESKTOP); + QSize s1 = sizeHint(); + QSize s2 = module.workArea().size(); + int w = s1.width(); + int h = s1.height(); + + if ( s1.width() >= s2.width() ) + w = s2.width(); + if ( s1.height() >= s2.height() ) + h = s2.height(); + + resize( w, h ); + } + + KDialogBase::show(); +} + +void ConfigDialog::commitShortcuts() +{ + keysWidget->commitChanges(); +} + +///////////////////////////////////////// +//// + +#include "configdialog.moc" diff --git a/kcontrol/randr/configdialog.h b/kcontrol/randr/configdialog.h new file mode 100644 index 000000000..c307a8aaa --- /dev/null +++ b/kcontrol/randr/configdialog.h @@ -0,0 +1,88 @@ +// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- +/* This file is part of the KDE project + Copyright (C) 2000 by Carsten Pfeiffer <[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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#ifndef CONFIGDIALOG_H +#define CONFIGDIALOG_H + +#include <qcheckbox.h> +#include <qevent.h> +#include <qgroupbox.h> +#include <qheader.h> +#include <qradiobutton.h> +#include <qvbox.h> + +#include <kdialogbase.h> +#include <keditlistbox.h> +#include <kkeydialog.h> +#include <klistview.h> +#include <knuminput.h> + +class KGlobalAccel; +class KKeyChooser; +class KListView; +class QPushButton; +class QDialog; +class ConfigDialog; + +class ConfigDialog : public KDialogBase +{ + Q_OBJECT + +public: + ConfigDialog(KGlobalAccel *accel, bool isApplet ); + ~ConfigDialog(); + + virtual void show(); + void commitShortcuts(); + +private: + KKeyChooser *keysWidget; + +}; + +class ListView : public KListView +{ +public: + ListView( ConfigDialog* configWidget, QWidget *parent, const char *name ) + : KListView( parent, name ), _configWidget( configWidget ), + _regExpEditor(0L) {} + // QListView has a weird idea of a sizeHint... + virtual QSize sizeHint () const { + int w = minimumSizeHint().width(); + int h = header()->height(); + h += viewport()->sizeHint().height(); + h += horizontalScrollBar()->height(); + + QListViewItem *item = firstChild(); + while ( item ) { + h += item->totalHeight(); + item = item->nextSibling(); + } + + return QSize( w, h ); + } + +protected: + virtual void rename( QListViewItem* item, int c ); +private: + ConfigDialog* _configWidget; + QDialog* _regExpEditor; +}; + +#endif // CONFIGDIALOG_H diff --git a/kcontrol/randr/krandrbindings.cpp b/kcontrol/randr/krandrbindings.cpp new file mode 100644 index 000000000..bb694a9bd --- /dev/null +++ b/kcontrol/randr/krandrbindings.cpp @@ -0,0 +1,34 @@ +// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- +/* This file is part of the KDE project + Copyright (C) by Andrew Stanley-Jones + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#ifndef NOSLOTS +# define DEF( name, key3, key4, fnSlot ) \ + keys->insert( name, i18n(name), QString::null, key3, key4, this, SLOT(fnSlot) ) +#else +# define DEF( name, key3, key4, fnSlot ) \ + keys->insert( name, i18n(name), QString::null, key3, key4 ) +#endif +#define WIN KKey::QtWIN + + keys->insert( "Program:krandrtray", i18n("Display Control") ); + + DEF( I18N_NOOP("Switch Displays"), KShortcut::KShortcut(QString("XF86Display")), KShortcut::KShortcut(QString("XF86Display")), slotCycleDisplays() ); + +#undef DEF +#undef WIN diff --git a/kcontrol/randr/krandrtray.cpp b/kcontrol/randr/krandrtray.cpp index 8e80c7cc6..20e617d75 100644 --- a/kcontrol/randr/krandrtray.cpp +++ b/kcontrol/randr/krandrtray.cpp @@ -29,11 +29,21 @@ #include <kpopupmenu.h> #include <kstdaction.h> #include <kstdguiitem.h> +#include <kglobal.h> +#include <kmessagebox.h> + +#include "configdialog.h" #include "krandrtray.h" #include "krandrpassivepopup.h" #include "krandrtray.moc" +#define OUTPUT_CONNECTED (1 << 0) +#define OUTPUT_UNKNOWN (1 << 1) +#define OUTPUT_DISCONNECTED (1 << 2) +#define OUTPUT_ON (1 << 3) +#define OUTPUT_ALL (0xf) + KRandRSystemTray::KRandRSystemTray(QWidget* parent, const char *name) : KSystemTray(parent, name) , m_popupUp(false) @@ -43,6 +53,20 @@ KRandRSystemTray::KRandRSystemTray(QWidget* parent, const char *name) setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); connect(this, SIGNAL(quitSelected()), kapp, SLOT(quit())); QToolTip::add(this, i18n("Screen resize & rotate")); + my_parent = parent; + + printf("Reading configuration...\n\r"); + globalKeys = new KGlobalAccel(this); + KGlobalAccel* keys = globalKeys; +#include "krandrbindings.cpp" + // the keys need to be read from kdeglobals, not kickerrc + globalKeys->readSettings(); + globalKeys->setEnabled(true); + globalKeys->updateConnections(); + + connect(kapp, SIGNAL(settingsChanged(int)), SLOT(slotSettingsChanged(int))); + + randr_display = XOpenDisplay(NULL); } void KRandRSystemTray::mousePressEvent(QMouseEvent* e) @@ -60,7 +84,51 @@ void KRandRSystemTray::mousePressEvent(QMouseEvent* e) void KRandRSystemTray::contextMenuAboutToShow(KPopupMenu* menu) { + //int lastIndex = 0; + + // Reload the randr configuration... + XRROutputInfo *output_info; + char *output_name; + RROutput output_id; + int i; int lastIndex = 0; + int screenDeactivated = 0; + + if (isValid() == true) { + randr_screen_info = read_screen_info(randr_display); + + for (i = 0; i < randr_screen_info->n_output; i++) { + output_info = randr_screen_info->outputs[i]->info; + // Look for ON outputs + if (!randr_screen_info->outputs[i]->cur_crtc) { + continue; + } + if (RR_Disconnected != randr_screen_info->outputs[i]->info->connection) { + continue; + } + + output_name = output_info->name; + output_id = randr_screen_info->outputs[i]->id; + + // Deactivate this display to avoid a crash! + randr_screen_info->cur_crtc = randr_screen_info->outputs[i]->cur_crtc; + randr_screen_info->cur_output = randr_screen_info->outputs[i]; + randr_screen_info->cur_output->auto_set = 0; + randr_screen_info->cur_output->off_set = 1; + output_off(randr_screen_info, randr_screen_info->cur_output); + main_low_apply(randr_screen_info); + + screenDeactivated = 1; + } + + if (screenDeactivated == 1) { + findPrimaryDisplay(); + refresh(); + + currentScreen()->proposeSize(GetDefaultResolutionParameter()); + currentScreen()->applyProposed(); + } + } menu->clear(); menu->setCheckable(true); @@ -89,12 +157,19 @@ void KRandRSystemTray::contextMenuAboutToShow(KPopupMenu* menu) populateMenu(menu); } - menu->insertSeparator(); + addOutputMenu(menu); + + menu->insertTitle(SmallIcon("randr"), i18n("Global Configuation")); + +// KAction *actPrefs = new KAction( i18n( "Configure Display..." ), +// SmallIconSet( "configure" ), KShortcut(), this, SLOT( slotPrefs() ), +// actionCollection() ); +// actPrefs->plug( menu ); - KAction *actPrefs = new KAction( i18n( "Configure Display..." ), - SmallIconSet( "configure" ), KShortcut(), this, SLOT( slotPrefs() ), + KAction *actSKeys = new KAction( i18n( "Configure Shortcut Keys..." ), + SmallIconSet( "configure" ), KShortcut(), this, SLOT( slotSKeys() ), actionCollection() ); - actPrefs->plug( menu ); + actSKeys->plug( menu ); menu->insertItem(SmallIcon("help"),KStdGuiItem::help().text(), m_help->menu()); KAction *quitAction = actionCollection()->action(KStdAction::name(KStdAction::Quit)); @@ -121,6 +196,36 @@ void KRandRSystemTray::configChanged() first = false; } +int KRandRSystemTray::GetDefaultResolutionParameter() +{ + int returnIndex = 0; + + int numSizes = currentScreen()->numSizes(); + int* sizeSort = new int[numSizes]; + + for (int i = 0; i < numSizes; i++) { + sizeSort[i] = currentScreen()->pixelCount(i); + } + + int highest = -1, highestIndex = -1; + + for (int i = 0; i < numSizes; i++) { + if (sizeSort[i] && sizeSort[i] > highest) { + highest = sizeSort[i]; + highestIndex = i; + } + } + sizeSort[highestIndex] = -1; + Q_ASSERT(highestIndex != -1); + + returnIndex = highestIndex; + + delete [] sizeSort; + sizeSort = 0L; + + return returnIndex; +} + void KRandRSystemTray::populateMenu(KPopupMenu* menu) { int lastIndex = 0; @@ -194,8 +299,15 @@ void KRandRSystemTray::populateMenu(KPopupMenu* menu) void KRandRSystemTray::slotResolutionChanged(int parameter) { - if (currentScreen()->currentSize() == parameter) +// if (currentScreen()->currentSize() == parameter) +// return; + + if (currentScreen()->currentSize() == parameter) { + //printf("This resolution is already in use; applying again...\n\r"); + currentScreen()->proposeSize(parameter); + currentScreen()->applyProposed(); return; + } currentScreen()->proposeSize(parameter); @@ -247,7 +359,347 @@ void KRandRSystemTray::slotPrefs() { KCMultiDialog *kcm = new KCMultiDialog( KDialogBase::Plain, i18n( "Configure" ), this ); - kcm->addModule( "display" ); + kcm->addModule( "displayconfig" ); kcm->setPlainCaption( i18n( "Configure Display" ) ); kcm->exec(); } + +void KRandRSystemTray::slotSettingsChanged(int category) +{ + if ( category == (int) KApplication::SETTINGS_SHORTCUTS ) { + globalKeys->readSettings(); + globalKeys->updateConnections(); + } +} + +void KRandRSystemTray::slotSKeys() +{ + ConfigDialog *dlg = new ConfigDialog(globalKeys, true); + + if ( dlg->exec() == QDialog::Accepted ) { + dlg->commitShortcuts(); + globalKeys->writeSettings(0, true); + globalKeys->updateConnections(); + } + + delete dlg; +} + +void KRandRSystemTray::slotCycleDisplays() +{ + XRROutputInfo *output_info; + char *output_name; + RROutput output_id; + int i; + int lastIndex = 0; + int current_on_index = -1; + int max_index = -1; + int prev_on_index; + Status s; + + randr_screen_info = read_screen_info(randr_display); + + for (i = 0; i < randr_screen_info->n_output; i++) { + output_info = randr_screen_info->outputs[i]->info; + // Look for ON outputs... + if (!randr_screen_info->outputs[i]->cur_crtc) { + continue; + } + // ...that are connected + if (RR_Disconnected == randr_screen_info->outputs[i]->info->connection) { + continue; + } + + output_name = output_info->name; + output_id = randr_screen_info->outputs[i]->id; + current_on_index = i; + if (i > max_index) { + max_index = i; + } + } + + for (i = 0; i < randr_screen_info->n_output; i++) { + output_info = randr_screen_info->outputs[i]->info; + // Look for CONNECTED outputs.... + if (RR_Disconnected == randr_screen_info->outputs[i]->info->connection) { + continue; + } + // ...that are not ON + if (randr_screen_info->outputs[i]->cur_crtc) { + continue; + } + + output_name = output_info->name; + output_id = randr_screen_info->outputs[i]->id; + if (i > max_index) { + max_index = i; + } + } + + for (i = 0; i < randr_screen_info->n_output; i++) { + output_info = randr_screen_info->outputs[i]->info; + // Look for ALL outputs that are not connected.... + if (RR_Disconnected != randr_screen_info->outputs[i]->info->connection) { + continue; + } + // ...or ON + if (randr_screen_info->outputs[i]->cur_crtc) { + continue; + } + + output_name = output_info->name; + output_id = randr_screen_info->outputs[i]->id; + if (i > max_index) { + max_index = i; + } + } + + printf("Active: %d\n\r", current_on_index); + printf("Max: %d\n\r", max_index); + + if ((current_on_index == -1) && (max_index == -1)) { + // There is no connected display available! ABORT + return; + } + + prev_on_index = current_on_index; + current_on_index = current_on_index + 1; + if (current_on_index > max_index) { + current_on_index = 0; + } + while (RR_Disconnected == randr_screen_info->outputs[current_on_index]->info->connection) { + current_on_index = current_on_index + 1; + if (current_on_index > max_index) { + current_on_index = 0; + } + } + if (prev_on_index != current_on_index) { + randr_screen_info->cur_crtc = randr_screen_info->outputs[current_on_index]->cur_crtc; + randr_screen_info->cur_output = randr_screen_info->outputs[current_on_index]; + randr_screen_info->cur_output->auto_set = 1; + randr_screen_info->cur_output->off_set = 0; + output_auto (randr_screen_info, randr_screen_info->cur_output); + i=main_low_apply(randr_screen_info); + + if (randr_screen_info->outputs[current_on_index]->cur_crtc) { + if (prev_on_index != -1) { + if (randr_screen_info->outputs[prev_on_index]->cur_crtc != NULL) { + if (RR_Disconnected != randr_screen_info->outputs[prev_on_index]->info->connection) { + randr_screen_info->cur_crtc = randr_screen_info->outputs[prev_on_index]->cur_crtc; + randr_screen_info->cur_output = randr_screen_info->outputs[prev_on_index]; + randr_screen_info->cur_output->auto_set = 0; + randr_screen_info->cur_output->off_set = 1; + output_off(randr_screen_info, randr_screen_info->cur_output); + i=main_low_apply(randr_screen_info); + } + } + } + + // Do something about the disconnected outputs + for (i = 0; i < randr_screen_info->n_output; i++) { + output_info = randr_screen_info->outputs[i]->info; + // Look for ON outputs + if (!randr_screen_info->outputs[i]->cur_crtc) { + continue; + } + if (RR_Disconnected != randr_screen_info->outputs[i]->info->connection) { + continue; + } + + output_name = output_info->name; + output_id = randr_screen_info->outputs[i]->id; + + // Deactivate this display to avoid a crash! + randr_screen_info->cur_crtc = randr_screen_info->outputs[i]->cur_crtc; + randr_screen_info->cur_output = randr_screen_info->outputs[i]; + randr_screen_info->cur_output->auto_set = 0; + randr_screen_info->cur_output->off_set = 1; + output_off(randr_screen_info, randr_screen_info->cur_output); + main_low_apply(randr_screen_info); + } + + findPrimaryDisplay(); + refresh(); + + currentScreen()->proposeSize(GetDefaultResolutionParameter()); + currentScreen()->applyProposed(); + } + else { + output_name = randr_screen_info->outputs[current_on_index]->info->name; + KMessageBox::sorry(my_parent, i18n("<b>Unable to activate output %1</b><p>Either the output is not connected to a display,<br>or the display configuration is not detectable").arg(output_name), i18n("Output Unavailable")); + } + } +} + +void KRandRSystemTray::findPrimaryDisplay() +{ + XRROutputInfo *output_info; + char *output_name; + RROutput output_id; + int i; + int lastIndex = 0; + + for (i = 0; i < randr_screen_info->n_output; i++) { + output_info = randr_screen_info->outputs[i]->info; + // Look for ON outputs... + if (!randr_screen_info->outputs[i]->cur_crtc) { + continue; + } + + // ...that are connected + if (RR_Disconnected == randr_screen_info->outputs[i]->info->connection) { + continue; + } + + output_name = output_info->name; + output_id = randr_screen_info->outputs[i]->id; + printf("ACTIVE CHECK: Found output %s\n\r", output_name); + + randr_screen_info->cur_crtc = randr_screen_info->outputs[i]->cur_crtc; + randr_screen_info->cur_output = randr_screen_info->outputs[i]; + } +} + +void KRandRSystemTray::addOutputMenu(KPopupMenu* menu) +{ + XRROutputInfo *output_info; + char *output_name; + RROutput output_id; + int i; + int lastIndex = 0; + int connected_displays = 0; + + if (isValid() == true) { + menu->insertTitle(SmallIcon("kcmkwm"), i18n("Output Port")); + + for (i = 0; i < randr_screen_info->n_output; i++) { + output_info = randr_screen_info->outputs[i]->info; + // Look for ON outputs + if (!randr_screen_info->outputs[i]->cur_crtc) { + continue; + } + if (RR_Disconnected == randr_screen_info->outputs[i]->info->connection) { + continue; + } + + output_name = output_info->name; + output_id = randr_screen_info->outputs[i]->id; + //printf("ON: Found output %s\n\r", output_name); + + lastIndex = menu->insertItem(i18n("%1 (Active)").arg(output_name)); + menu->setItemChecked(lastIndex, true); + menu->connectItem(lastIndex, this, SLOT(slotOutputChanged(int))); + menu->setItemParameter(lastIndex, i); + + connected_displays++; + } + + for (i = 0; i < randr_screen_info->n_output; i++) { + output_info = randr_screen_info->outputs[i]->info; + // Look for CONNECTED outputs.... + if (RR_Disconnected == randr_screen_info->outputs[i]->info->connection) { + continue; + } + // ...that are not ON + if (randr_screen_info->outputs[i]->cur_crtc) { + continue; + } + + output_name = output_info->name; + output_id = randr_screen_info->outputs[i]->id; + //printf("CONNECTED, NOT ON: Found output %s\n\r", output_name); + + lastIndex = menu->insertItem(i18n("%1 (Connected, Inactive)").arg(output_name)); + menu->setItemChecked(lastIndex, false); + menu->connectItem(lastIndex, this, SLOT(slotOutputChanged(int))); + menu->setItemParameter(lastIndex, i); + + connected_displays++; + } + + for (i = 0; i < randr_screen_info->n_output; i++) { + output_info = randr_screen_info->outputs[i]->info; + // Look for ALL outputs that are not connected.... + if (RR_Disconnected != randr_screen_info->outputs[i]->info->connection) { + continue; + } + // ...or ON + if (randr_screen_info->outputs[i]->cur_crtc) { + continue; + } + + output_name = output_info->name; + output_id = randr_screen_info->outputs[i]->id; + //printf("DISCONNECTED, NOT ON: Found output %s\n\r", output_name); + + lastIndex = menu->insertItem(i18n("%1 (Disconnected, Inactive)").arg(output_name)); + menu->setItemChecked(lastIndex, false); + menu->setItemEnabled(lastIndex, false); + menu->connectItem(lastIndex, this, SLOT(slotOutputChanged(int))); + menu->setItemParameter(lastIndex, i); + } + + lastIndex = menu->insertItem(SmallIcon("forward"), i18n("Next available output")); + if (connected_displays < 2) { + menu->setItemEnabled(lastIndex, false); + } + menu->connectItem(lastIndex, this, SLOT(slotCycleDisplays())); + } +} + +void KRandRSystemTray::slotOutputChanged(int parameter) +{ + XRROutputInfo *output_info; + char *output_name; + RROutput output_id; + int i; + Status s; + int num_outputs_on; + + num_outputs_on = 0; + for (i = 0; i < randr_screen_info->n_output; i++) { + output_info = randr_screen_info->outputs[i]->info; + // Look for ON outputs + if (!randr_screen_info->outputs[i]->cur_crtc) { + continue; + } + + num_outputs_on++; + } + + if (!randr_screen_info->outputs[parameter]->cur_crtc) { + //printf("Screen was off, turning it on...\n\r"); + + randr_screen_info->cur_crtc = randr_screen_info->outputs[parameter]->cur_crtc; + randr_screen_info->cur_output = randr_screen_info->outputs[parameter]; + randr_screen_info->cur_output->auto_set = 1; + randr_screen_info->cur_output->off_set = 0; + output_auto (randr_screen_info, randr_screen_info->cur_output); + i=main_low_apply(randr_screen_info); + + if (!randr_screen_info->outputs[parameter]->cur_crtc) { + output_name = randr_screen_info->outputs[parameter]->info->name; + KMessageBox::sorry(my_parent, i18n("<b>Unable to activate output %1</b><p>Either the output is not connected to a display,<br>or the display configuration is not detectable").arg(output_name), i18n("Output Unavailable")); + } + } + else { + if (num_outputs_on > 1) { + //printf("Screen was on, turning it off...\n\r"); + randr_screen_info->cur_crtc = randr_screen_info->outputs[parameter]->cur_crtc; + randr_screen_info->cur_output = randr_screen_info->outputs[parameter]; + randr_screen_info->cur_output->auto_set = 0; + randr_screen_info->cur_output->off_set = 1; + output_off(randr_screen_info, randr_screen_info->cur_output); + i=main_low_apply(randr_screen_info); + + findPrimaryDisplay(); + refresh(); + + currentScreen()->proposeSize(GetDefaultResolutionParameter()); + currentScreen()->applyProposed(); + } + else { + KMessageBox::sorry(my_parent, i18n("<b>You are attempting to deactivate the only active output</b><p>You must keep at least one display output active at all times!"), i18n("Invalid Operation Requested")); + } + } +}
\ No newline at end of file diff --git a/kcontrol/randr/krandrtray.h b/kcontrol/randr/krandrtray.h index 829306437..9387f8cad 100644 --- a/kcontrol/randr/krandrtray.h +++ b/kcontrol/randr/krandrtray.h @@ -22,9 +22,12 @@ #include <qptrlist.h> #include <ksystemtray.h> +#include <kglobalaccel.h> #include "randr.h" +#include "lowlevel_randr.h" + class KHelpMenu; class KPopupMenu; @@ -34,6 +37,7 @@ class KRandRSystemTray : public KSystemTray, public RandRDisplay public: KRandRSystemTray(QWidget* parent = 0, const char *name = 0); + KGlobalAccel *globalKeys; virtual void contextMenuAboutToShow(KPopupMenu* menu); @@ -45,16 +49,27 @@ protected slots: void slotOrientationChanged(int parameter); void slotRefreshRateChanged(int parameter); void slotPrefs(); + void slotSKeys(); + void slotSettingsChanged(int category); + void slotCycleDisplays(); + void slotOutputChanged(int parameter); protected: void mousePressEvent( QMouseEvent *e ); private: void populateMenu(KPopupMenu* menu); + void addOutputMenu(KPopupMenu* menu); + int GetDefaultResolutionParameter(); + void findPrimaryDisplay(); bool m_popupUp; KHelpMenu* m_help; QPtrList<KPopupMenu> m_screenPopups; + + Display *randr_display; + ScreenInfo *randr_screen_info; + QWidget* my_parent; }; #endif diff --git a/kcontrol/randr/lowlevel_randr.c b/kcontrol/randr/lowlevel_randr.c new file mode 100644 index 000000000..a6d54dbcd --- /dev/null +++ b/kcontrol/randr/lowlevel_randr.c @@ -0,0 +1,700 @@ +/* + * Copyright © 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "lowlevel_randr.h" +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +Status crtc_disable (struct CrtcInfo *crtc); + +char * get_output_name (struct ScreenInfo *screen_info, RROutput id) +{ + char *output_name = NULL; + int i; + + for (i = 0; i < screen_info->n_output; i++) { + if (id == screen_info->outputs[i]->id) { + output_name = screen_info->outputs[i]->info->name; + } + } + + if (!output_name) { + output_name = "Unknown"; + } + + return output_name; +} + +XRRModeInfo * find_mode_by_xid (struct ScreenInfo *screen_info, RRMode mode_id) +{ + XRRModeInfo *mode_info = NULL; + XRRScreenResources *res; + int i; + + res = screen_info->res; + for (i = 0; i < res->nmode; i++) { + if (mode_id == res->modes[i].id) { + mode_info = &res->modes[i]; + break; + } + } + + return mode_info; +} + +static XRRCrtcInfo * find_crtc_by_xid (struct ScreenInfo *screen_info, RRCrtc crtc_id) +{ + XRRCrtcInfo *crtc_info; + Display *dpy; + XRRScreenResources *res; + + dpy = screen_info->dpy; + res = screen_info->res; + + crtc_info = XRRGetCrtcInfo (dpy, res, crtc_id); + + return crtc_info; +} + +int get_width_by_output_id (struct ScreenInfo *screen_info, RROutput output_id) +{ + struct OutputInfo *output_info; + struct CrtcInfo *crtc_info; + RRMode mode_id; + XRRModeInfo *mode_info; + int i; + int width = -1; + + for (i = 0; i < screen_info->n_output; i++) { + if (output_id == screen_info->outputs[i]->id) { + crtc_info = screen_info->outputs[i]->cur_crtc; + if (!crtc_info) { + width = 0; + break; + } + mode_id = crtc_info->cur_mode_id; + mode_info = find_mode_by_xid (screen_info, mode_id); + + width = mode_width (mode_info, crtc_info->cur_rotation); + + break; + } + } + + return width; +} + +int get_height_by_output_id (struct ScreenInfo *screen_info, RROutput output_id) +{ + struct OutputInfo *output_info; + struct CrtcInfo *crtc_info; + RRMode mode_id; + XRRModeInfo *mode_info; + int i; + int height = -1; + + for (i = 0; i < screen_info->n_output; i++) { + if (output_id == screen_info->outputs[i]->id) { + crtc_info = screen_info->outputs[i]->cur_crtc; + if (!crtc_info) { + height = 0; + break; + } + mode_id = crtc_info->cur_mode_id; + mode_info = find_mode_by_xid (screen_info, mode_id); + + height = mode_height (mode_info, crtc_info->cur_rotation); + + break; + } + } + + return height; +} + +int mode_height (XRRModeInfo *mode_info, Rotation rotation) +{ + switch (rotation & 0xf) { + case RR_Rotate_0: + case RR_Rotate_180: + return mode_info->height; + case RR_Rotate_90: + case RR_Rotate_270: + return mode_info->width; + default: + return 0; + } +} + +int mode_width (XRRModeInfo *mode_info, Rotation rotation) +{ + switch (rotation & 0xf) { + case RR_Rotate_0: + case RR_Rotate_180: + return mode_info->width; + case RR_Rotate_90: + case RR_Rotate_270: + return mode_info->height; + default: + return 0; + } +} + + +static struct CrtcInfo * find_crtc (struct ScreenInfo *screen_info, XRROutputInfo *output) +{ + struct CrtcInfo *crtc_info = NULL; + int i; + + for (i = 0; i < screen_info->n_crtc; i++) { + if (screen_info->crtcs[i]->id == output->crtc) { + crtc_info = screen_info->crtcs[i]; + break; + } + } + + return crtc_info; +} + +struct CrtcInfo * auto_find_crtc (struct ScreenInfo *screen_info, struct OutputInfo *output_info) +{ + struct CrtcInfo *crtc_info = NULL; + int i; + + for (i = 0; i < screen_info->n_crtc; i++) { + if (0 == screen_info->crtcs[i]->cur_noutput) { + crtc_info = screen_info->crtcs[i]; + break; + } + } + + if (NULL == crtc_info) { + crtc_info = screen_info->crtcs[0]; + } + + return crtc_info; +} + +int set_screen_size (struct ScreenInfo *screen_info) +{ + Display *dpy; + int screen; + struct CrtcInfo *crtc; + XRRModeInfo *mode_info; + int cur_x = 0, cur_y = 0; + int w = 0, h = 0; + int mmW, mmH; + int max_width = 0, max_height = 0; + int i; + + dpy = screen_info->dpy; + screen = DefaultScreen (dpy); + + for (i = 0; i < screen_info->n_crtc; i++) { + crtc = screen_info->crtcs[i]; + if (!crtc->cur_mode_id) { + continue; + } + mode_info = find_mode_by_xid (screen_info, crtc->cur_mode_id); + cur_x = crtc->cur_x; + cur_y = crtc->cur_y; + + w = mode_width (mode_info, crtc->cur_rotation); + h = mode_height (mode_info, crtc->cur_rotation); + + if (cur_x + w > max_width) { + max_width = cur_x + w; + } + if (cur_y + h > max_height) { + max_height = cur_y + h; + } + } + + if (max_width > screen_info->max_width) { + #if RANDR_GUI_DEBUG + fprintf (stderr, "user set screen width %d, larger than max width %d, set to max width\n", + cur_x + w, screen_info->max_width); + #endif + return 0; + } else if (max_width < screen_info->min_width) { + screen_info->cur_width = screen_info->min_width; + } else { + screen_info->cur_width = max_width; + } + + if (max_height > screen_info->max_height) { + #if RANDR_GUI_DEBUG + fprintf (stderr, "user set screen height %d, larger than max height %d, set to max height\n", + cur_y + h, screen_info->max_height); + #endif + return 0; + } else if (max_height < screen_info->min_height) { + screen_info->cur_height = screen_info->min_height; + } else { + screen_info->cur_height = max_height; + } + + /* calculate mmWidth, mmHeight */ + if (screen_info->cur_width != DisplayWidth (dpy, screen) || + screen_info->cur_height != DisplayHeight (dpy, screen) ) { + double dpi; + + dpi = (25.4 * DisplayHeight (dpy, screen)) / DisplayHeightMM(dpy, screen); + mmW = (25.4 * screen_info->cur_width) / dpi; + mmH = (25.4 * screen_info->cur_height) / dpi; + } else { + mmW = DisplayWidthMM (dpy, screen); + mmH = DisplayHeightMM (dpy, screen); + } + + screen_info->cur_mmWidth = mmW; + screen_info->cur_mmHeight = mmH; + + return 1; +} + +void screen_apply (struct ScreenInfo *screen_info) +{ + int width, height; + int mmWidth, mmHeight; + Display *dpy, *cur_dpy; + Window window; + int screen; + static int first = 1; + + width = screen_info->cur_width; + height = screen_info->cur_height; + mmWidth = screen_info->cur_mmWidth; + mmHeight = screen_info->cur_mmHeight; + dpy = screen_info->dpy; + window = screen_info->window; + screen = DefaultScreen (dpy); + + cur_dpy = XOpenDisplay (NULL); + + if (width == DisplayWidth (cur_dpy, screen) && + height == DisplayHeight (cur_dpy, screen) && + mmWidth == DisplayWidthMM (cur_dpy, screen) && + mmHeight == DisplayHeightMM (cur_dpy, screen) ) { + return; + } else { + XRRSetScreenSize (dpy, window, width, height, mmWidth, mmHeight); + } +} + +Status crtc_apply (struct CrtcInfo *crtc_info) +{ + struct ScreenInfo *screen_info; + XRRCrtcInfo *rr_crtc_info; + Display *dpy; + XRRScreenResources *res; + RRCrtc crtc_id; + int x, y; + RRMode mode_id; + Rotation rotation; + RROutput *outputs; + int noutput; + Status s; + int i; + + /*if (!crtc_info->changed) { + return RRSetConfigSuccess; + }*/ + + screen_info = crtc_info->screen_info; + dpy = screen_info->dpy; + res = screen_info->res; + crtc_id = crtc_info->id; + x = crtc_info->cur_x; + y = crtc_info->cur_y; + + mode_id = crtc_info->cur_mode_id; + rotation = crtc_info->cur_rotation; + + noutput = crtc_info->cur_noutput; + + if (0 == noutput) { + return crtc_disable (crtc_info); + } + + outputs = malloc (sizeof (RROutput) * noutput); + noutput = 0; + for (i = 0; i < screen_info->n_output; i++) { + struct OutputInfo *output_info = screen_info->outputs[i]; + + if (output_info->cur_crtc && crtc_id == output_info->cur_crtc->id) { + outputs[noutput++] = output_info->id; + } + } + + + s = XRRSetCrtcConfig (dpy, res, crtc_id, CurrentTime, + x, y, mode_id, rotation, + outputs, noutput); + + if (RRSetConfigSuccess == s) { + crtc_info->changed = 0; + } + + free (outputs); + + return s; +} + +Status crtc_disable (struct CrtcInfo *crtc) +{ + struct ScreenInfo *screen_info; + + screen_info = crtc->screen_info; + + return XRRSetCrtcConfig (screen_info->dpy, screen_info->res, crtc->id, CurrentTime, + 0, 0, None, RR_Rotate_0, NULL, 0); +} + +struct ScreenInfo* read_screen_info (Display *display) +{ + struct ScreenInfo *screen_info; + int screen_num; + Window root_window; + XRRScreenResources *sr; + int i; + + screen_num = DefaultScreen (display); + root_window = RootWindow (display, screen_num); + + sr = XRRGetScreenResources (display, root_window); + + screen_info = malloc (sizeof (struct ScreenInfo)); + screen_info->dpy = display; + screen_info->window = root_window; + screen_info->res = sr; + screen_info->cur_width = DisplayWidth (display, screen_num); + screen_info->cur_height = DisplayHeight (display, screen_num); + screen_info->cur_mmWidth = DisplayWidthMM (display, screen_num); + screen_info->cur_mmHeight = DisplayHeightMM (display, screen_num); + screen_info->n_output = sr->noutput; + screen_info->n_crtc = sr->ncrtc; + screen_info->outputs = malloc (sizeof (struct OutputInfo *) * sr->noutput); + screen_info->crtcs = malloc (sizeof (struct CrtcInfo *) * sr->ncrtc); + screen_info->clone = 0; + + XRRGetScreenSizeRange (display, root_window, &screen_info->min_width, &screen_info->min_height, &screen_info->max_width, &screen_info->max_height); + + /* get crtc */ + for (i = 0; i < sr->ncrtc; i++) { + struct CrtcInfo *crtc_info; + screen_info->crtcs[i] = malloc (sizeof (struct CrtcInfo)); + crtc_info = screen_info->crtcs[i]; + XRRCrtcInfo *xrr_crtc_info = XRRGetCrtcInfo (display, sr, sr->crtcs[i]); + + crtc_info->id = sr->crtcs[i]; + crtc_info->info = xrr_crtc_info; + crtc_info->cur_x = xrr_crtc_info->x; + crtc_info->cur_y = xrr_crtc_info->y; + crtc_info->cur_mode_id = xrr_crtc_info->mode; + crtc_info->cur_rotation = xrr_crtc_info->rotation; + crtc_info->rotations = xrr_crtc_info->rotations; + crtc_info->cur_noutput = xrr_crtc_info->noutput; + + crtc_info->changed = 0; + crtc_info->screen_info = screen_info; + } + + + /* get output */ + for (i = 0; i < sr->noutput; i++) { + struct OutputInfo *output; + screen_info->outputs[i] = malloc (sizeof (struct OutputInfo)); + output = screen_info->outputs[i]; + + output->id = sr->outputs[i]; + output->info = XRRGetOutputInfo (display, sr, sr->outputs[i]); + output->cur_crtc = find_crtc (screen_info, output->info); + output->auto_set = 0; + if (output->cur_crtc) { + output->off_set = 0; + } else { + output->off_set = 1; + } + + } + + /* set current crtc */ + screen_info->cur_crtc = screen_info->outputs[0]->cur_crtc; + screen_info->primary_crtc = screen_info->cur_crtc; + screen_info->cur_output = screen_info->outputs[0]; + + return screen_info; +} + +void free_screen_info (struct ScreenInfo *screen_info) +{ + free (screen_info->outputs); + free (screen_info->crtcs); + free (screen_info); +} + + + +static char * get_mode_name (struct ScreenInfo *screen_info, RRMode mode_id) +{ + XRRScreenResources *sr; + char *mode_name = NULL; + int i; + + sr = screen_info->res; + + for (i = 0; i < sr->nmode; i++) { + if (sr->modes[i].id == mode_id) { + break; + } + } + + if (i == sr->nmode) { + mode_name = g_strdup ("Unknown mode"); + } else { + double rate; + if (sr->modes[i].hTotal && sr->modes[i].vTotal) { + rate = ((double) sr->modes[i].dotClock / + ((double) sr->modes[i].hTotal * (double) sr->modes[i].vTotal)); + } else { + rate = 0; + } + mode_name = g_strdup_printf ("%s%6.1fHz", sr->modes[i].name, rate); + } + + return mode_name; +} + +/*check if other outputs that connected to the same crtc support this mode*/ +static int check_mode (struct ScreenInfo *screen_info, struct OutputInfo *output, RRMode mode_id) +{ + XRRCrtcInfo *crtc_info; + /* XRR */ + int i, j; + int mode_ok = 1; + + if (!output->cur_crtc) { + return 1; + } + + crtc_info = output->cur_crtc->info; + for (i = 0; i < crtc_info->noutput; i++) { + XRROutputInfo *output_info; + int nmode; + + if (output->id == crtc_info->outputs[i]) { + continue; + } + + mode_ok = 0; + output_info = XRRGetOutputInfo (screen_info->dpy, screen_info->res, crtc_info->outputs[i]); + nmode = output_info->nmode; + for (j = 0; j < nmode; j++) { + if (mode_id == output_info->modes[j]) { + mode_ok = 1; + break; + } + } + if (!mode_ok) { + break; + } + } + + return mode_ok; +} + +static RRCrtc get_crtc_id_by_output_id (struct ScreenInfo *screen_info, RROutput output_id) +{ + int i; + RRCrtc crtc_id = -1; + + for (i = 0; i < screen_info->n_output; i++) { + if (output_id == screen_info->outputs[i]->id) { + if (screen_info->outputs[i]->cur_crtc) { + crtc_id = screen_info->outputs[i]->cur_crtc->id; + } else { + crtc_id = 0; /* this output is off */ + } + break; + } + } + + return crtc_id; +} + +static struct CrtcInfo * +get_crtc_info_by_xid (struct ScreenInfo *screen_info, RRCrtc crtc_id) +{ + struct CrtcInfo *crtc_info = NULL; + int i; + + for (i = 0; i < screen_info->n_crtc; i++) { + if (crtc_id == screen_info->crtcs[i]->id) { + crtc_info = screen_info->crtcs[i]; + break; + } + } + + return crtc_info; +} + +static XRRModeInfo * +preferred_mode (struct ScreenInfo *screen_info, struct OutputInfo *output) +{ + XRROutputInfo *output_info = output->info; + Display *dpy; + int screen; + int m; + XRRModeInfo *best; + int bestDist; + + dpy = screen_info->dpy; + screen = DefaultScreen (dpy); + best = NULL; + bestDist = 0; + for (m = 0; m < output_info->nmode; m++) { + XRRModeInfo *mode_info = find_mode_by_xid (screen_info, output_info->modes[m]); + int dist; + + if (m < output_info->npreferred) + dist = 0; + else if (output_info->mm_height) + dist = (1000 * DisplayHeight(dpy, screen) / DisplayHeightMM(dpy, screen) - + 1000 * mode_info->height / output_info->mm_height); + else + dist = DisplayHeight(dpy, screen) - mode_info->height; + + if (dist < 0) dist = -dist; + if (!best || dist < bestDist) { + best = mode_info; + bestDist = dist; + } + } + return best; +} + +int main_low_apply (struct ScreenInfo *screen_info) +{ + int i; + struct CrtcInfo *crtc_info; + + /* set_positions (screen_info); */ + + if (!set_screen_size (screen_info)) { + printf("Screen Size FAILURE\n\r"); + return 0; + } + + for (i = 0; i < screen_info->n_crtc; i++) { + int old_x, old_y, old_w, old_h; + + XRRCrtcInfo *crtc_info = XRRGetCrtcInfo (screen_info->dpy, screen_info->res, screen_info->crtcs[i]->id); + XRRModeInfo *old_mode = find_mode_by_xid (screen_info, crtc_info->mode); + + if (crtc_info->mode == None) { + continue; + } + + old_x = crtc_info->x; + old_y = crtc_info->y; + old_w = mode_width (old_mode, crtc_info->rotation); + old_h = mode_height (old_mode, crtc_info->rotation); + + if (old_x + old_w <= screen_info->cur_width && + old_y + old_h <= screen_info->cur_height ) { + continue; + } else { + crtc_disable (screen_info->crtcs[i]); + } + } + + screen_apply (screen_info); + + for (i = 0; i < screen_info->n_crtc; i++) { + Status s; + crtc_info = screen_info->crtcs[i]; + + s = crtc_apply (crtc_info); + if (RRSetConfigSuccess != s) { + fprintf (stderr, "crtc apply error\n"); + } + } + + return 1; +} + +void output_auto (struct ScreenInfo *screen_info, struct OutputInfo *output_info) +{ + XRRModeInfo *mode_info; + RRMode mode_id; + struct CrtcInfo *crtc_info; + XRROutputInfo *probe_output_info; + + if (RR_Disconnected == output_info->info->connection) { + XRRScreenResources *cur_res; + + cur_res = XRRGetScreenResources (screen_info->dpy, screen_info->window); + probe_output_info = XRRGetOutputInfo (screen_info->dpy, cur_res, output_info->id); + if (RR_Disconnected != probe_output_info->connection) { + output_info->info = probe_output_info; + output_info->cur_crtc = auto_find_crtc (screen_info, output_info); + } + } + + mode_info = preferred_mode (screen_info, output_info); + if (!mode_info) { + return; + } + mode_id = mode_info->id; + + crtc_info = output_info->cur_crtc; + if (crtc_info) { + crtc_info->cur_mode_id = mode_id; + } else { + crtc_info = auto_find_crtc (screen_info, output_info); + if (!crtc_info) { +#if RANDR_GUI_DEBUG + fprintf (stderr, "Can not find usable CRTC\n"); +#endif + return; + } else { + screen_info->cur_output->cur_crtc = crtc_info; + screen_info->cur_crtc = crtc_info; + screen_info->cur_crtc->cur_noutput++; + fprintf (stderr, "n output: %d\n", screen_info->cur_crtc->cur_noutput); + screen_info->cur_crtc->cur_mode_id = mode_id; + screen_info->cur_crtc->changed = 1; + } + } + +} + +void output_off (struct ScreenInfo *screen_info, struct OutputInfo *output) +{ + if (output->cur_crtc) { + output->cur_crtc->cur_noutput--; + } + output->cur_crtc = NULL; + screen_info->cur_crtc = NULL; + output->off_set = 1; +} diff --git a/kcontrol/randr/lowlevel_randr.h b/kcontrol/randr/lowlevel_randr.h new file mode 100644 index 000000000..a9a519125 --- /dev/null +++ b/kcontrol/randr/lowlevel_randr.h @@ -0,0 +1,102 @@ +/* + * Copyright © 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <X11/Xlib.h> +#include <X11/extensions/Xrandr.h> + +struct ScreenInfo; + +struct CrtcInfo { + RRCrtc id; + XRRCrtcInfo *info; + int cur_x; + int cur_y; + RRMode cur_mode_id; + Rotation cur_rotation; + Rotation rotations; + int cur_noutput; + + int changed; + + struct ScreenInfo *screen_info; +}; + +struct OutputInfo { + RROutput id; + XRROutputInfo *info; + struct CrtcInfo *cur_crtc; + + int auto_set; + int off_set; +}; + +struct ScreenInfo { + Display *dpy; + Window window; + XRRScreenResources *res; + int min_width, min_height; + int max_width, max_height; + int cur_width; + int cur_height; + int cur_mmWidth; + int cur_mmHeight; + + int n_output; + int n_crtc; + struct OutputInfo **outputs; + struct CrtcInfo **crtcs; + + int clone; + struct CrtcInfo *primary_crtc; + + struct CrtcInfo *cur_crtc; + struct OutputInfo *cur_output; +}; + +extern struct ScreenInfo *screen_info; +extern const uint big_pixbuf[], small_pixbuf[]; + +#ifdef __cplusplus +extern "C" { +#endif +void free_screen_info (struct ScreenInfo *screen_info); + +struct ScreenInfo* read_screen_info (Display *); + +int set_screen_size (struct ScreenInfo *screen_info); +void output_auto (struct ScreenInfo *screen_info, struct OutputInfo *output_info); +void output_off (struct ScreenInfo *screen_info, struct OutputInfo *output); +struct CrtcInfo* auto_find_crtc (struct ScreenInfo *screen_info, struct OutputInfo *output_info); + +XRRModeInfo *find_mode_by_xid (struct ScreenInfo *screen_info, RRMode mode_id); +int mode_height (XRRModeInfo *mode_info, Rotation rotation); +int mode_width (XRRModeInfo *mode_info, Rotation rotation); +int get_width_by_output_id (struct ScreenInfo *screen_info, RROutput output_id); +int get_height_by_output_id (struct ScreenInfo *screen_info, RROutput output_id); +char *get_output_name (struct ScreenInfo *screen_info, RROutput id); +Status crtc_apply (struct CrtcInfo *crtc_info); +Status crtc_disable (struct CrtcInfo *crtc); +int main_low_apply (struct ScreenInfo *screen_info); + +#ifdef __cplusplus +} +#endif
\ No newline at end of file diff --git a/kcontrol/samba/ksmbstatus.cpp b/kcontrol/samba/ksmbstatus.cpp index 4866a3a1e..b5bc6599f 100644 --- a/kcontrol/samba/ksmbstatus.cpp +++ b/kcontrol/samba/ksmbstatus.cpp @@ -136,7 +136,7 @@ void NetMon::slotReceivedData(KProcess *, char *buffer, int ) char s[250],*start,*end; size_t len; start = buffer; - while ((end = strchr(start,'\n'))) // look for '\n' + while ((end = (char*)strchr(start,'\n'))) // look for '\n' { len = end-start; if (len>=sizeof(s)) diff --git a/kcontrol/samba/smbstatus.desktop b/kcontrol/samba/smbstatus.desktop index c0b6db58a..14b8425ed 100644 --- a/kcontrol/samba/smbstatus.desktop +++ b/kcontrol/samba/smbstatus.desktop @@ -238,4 +238,5 @@ Keywords[xh]=SMB,SAMBA,umsebenzi womnatha wee window,LAN,Ulwazi lwendlela yokuse Keywords[zh_CN]=SMB,SAMBA,Windows network,LAN,System Information,局域网,系统信息 Keywords[zh_TW]=SMB,SAMBA,Windows network,LAN,System Information,Windows 網路,區域網路,系統資訊 Keywords[zu]=SMB,SAMBA,Uxhumano olusakazekile lwama-windows,LAN,Ulwazi lwesistimu -Categories=Qt;KDE;X-KDE-information; +Categories=Qt;KDE;X-KDE-settings-network; + diff --git a/kcontrol/style/kcmstyle.cpp b/kcontrol/style/kcmstyle.cpp index 9333c0f72..098990afd 100644 --- a/kcontrol/style/kcmstyle.cpp +++ b/kcontrol/style/kcmstyle.cpp @@ -229,6 +229,14 @@ KCMStyle::KCMStyle( QWidget* parent, const char* name ) containerLayout->addWidget( lblTooltipEffect, 1, 0 ); containerLayout->addWidget( comboTooltipEffect, 1, 1 ); + comboRubberbandEffect = new QComboBox( FALSE, containerFrame ); + comboRubberbandEffect->insertItem( i18n("Disable") ); + comboRubberbandEffect->insertItem( i18n("Make translucent") ); + lblRubberbandEffect = new QLabel( i18n("&Rubberband effect:"), containerFrame ); + lblRubberbandEffect->setBuddy( comboRubberbandEffect ); + containerLayout->addWidget( lblRubberbandEffect, 2, 0 ); + containerLayout->addWidget( comboRubberbandEffect, 2, 1 ); + comboMenuEffect = new QComboBox( FALSE, containerFrame ); comboMenuEffect->insertItem( i18n("Disable") ); comboMenuEffect->insertItem( i18n("Animate") ); @@ -236,8 +244,8 @@ KCMStyle::KCMStyle( QWidget* parent, const char* name ) comboMenuEffect->insertItem( i18n("Make Translucent") ); lblMenuEffect = new QLabel( i18n("&Menu effect:"), containerFrame ); lblMenuEffect->setBuddy( comboMenuEffect ); - containerLayout->addWidget( lblMenuEffect, 2, 0 ); - containerLayout->addWidget( comboMenuEffect, 2, 1 ); + containerLayout->addWidget( lblMenuEffect, 3, 0 ); + containerLayout->addWidget( comboMenuEffect, 3, 1 ); comboMenuHandle = new QComboBox( FALSE, containerFrame ); comboMenuHandle->insertItem( i18n("Disable") ); @@ -245,11 +253,11 @@ KCMStyle::KCMStyle( QWidget* parent, const char* name ) // comboMenuHandle->insertItem( i18n("Enable") ); lblMenuHandle = new QLabel( i18n("Me&nu tear-off handles:"), containerFrame ); lblMenuHandle->setBuddy( comboMenuHandle ); - containerLayout->addWidget( lblMenuHandle, 3, 0 ); - containerLayout->addWidget( comboMenuHandle, 3, 1 ); + containerLayout->addWidget( lblMenuHandle, 4, 0 ); + containerLayout->addWidget( comboMenuHandle, 4, 1 ); cbMenuShadow = new QCheckBox( i18n("Menu &drop shadow"), containerFrame ); - containerLayout->addWidget( cbMenuShadow, 4, 0 ); + containerLayout->addWidget( cbMenuShadow, 5, 0 ); // Push the [label combo] to the left. comboSpacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); @@ -359,6 +367,7 @@ KCMStyle::KCMStyle( QWidget* parent, const char* name ) connect( cbEnableEffects, SIGNAL(toggled(bool)), this, SLOT(setEffectsDirty())); connect( cbEnableEffects, SIGNAL(toggled(bool)), this, SLOT(setStyleDirty())); connect( comboTooltipEffect, SIGNAL(activated(int)), this, SLOT(setEffectsDirty())); + connect( comboRubberbandEffect, SIGNAL(activated(int)), this, SLOT(setStyleDirty())); connect( comboComboEffect, SIGNAL(activated(int)), this, SLOT(setEffectsDirty())); connect( comboMenuEffect, SIGNAL(activated(int)), this, SLOT(setStyleDirty())); connect( comboMenuHandle, SIGNAL(activated(int)), this, SLOT(setStyleDirty())); @@ -556,6 +565,11 @@ void KCMStyle::save() item = comboTooltipEffect->currentItem(); config.writeEntry( "EffectAnimateTooltip", item == 1); config.writeEntry( "EffectFadeTooltip", item == 2 ); + item = comboRubberbandEffect->currentItem(); + { + QSettings settings; // Only for KStyle stuff + settings.writeEntry("/KStyle/Settings/SemiTransparentRubberband", item == 1); + } item = comboMenuHandle->currentItem(); config.writeEntry( "InsertTearOffHandle", item ); item = comboMenuEffect->currentItem(); @@ -887,7 +901,11 @@ void KCMStyle::loadEffects( KConfig& config ) comboTooltipEffect->setCurrentItem( 2 ); else comboTooltipEffect->setCurrentItem( 0 ); - + + QSettings settings; + bool semiTransparentRubberband = settings.readBoolEntry("/KStyle/Settings/SemiTransparentRubberband", false); + comboRubberbandEffect->setCurrentItem( semiTransparentRubberband ? 1 : 0 ); + if ( config.readBoolEntry( "EffectAnimateMenu", false) ) comboMenuEffect->setCurrentItem( 1 ); else if ( config.readBoolEntry( "EffectFadeMenu", false) ) @@ -898,7 +916,7 @@ void KCMStyle::loadEffects( KConfig& config ) comboMenuHandle->setCurrentItem(config.readNumEntry("InsertTearOffHandle", 0)); // KStyle Menu transparency and drop-shadow options... - QSettings settings; + QString effectEngine = settings.readEntry("/KStyle/Settings/MenuTransparencyEngine", "Disabled"); #ifdef HAVE_XRENDER @@ -1027,6 +1045,8 @@ void KCMStyle::addWhatsThis() QWhatsThis::add( comboTooltipEffect, i18n( "<p><b>Disable: </b>do not use any tooltip effects.</p>\n" "<p><b>Animate: </b>Do some animation.</p>\n" "<b>Fade: </b>Fade in tooltips using alpha-blending.") ); + QWhatsThis::add( comboRubberbandEffect, i18n( "<p><b>Disable: </b>do not use any rubberband effects.</p>\n" + "<b>Make Translucent: </b>Draw a translucent rubberband.") ); QWhatsThis::add( comboMenuEffect, i18n( "<p><b>Disable: </b>do not use any menu effects.</p>\n" "<p><b>Animate: </b>Do some animation.</p>\n" "<p><b>Fade: </b>Fade in menus using alpha-blending.</p>\n" diff --git a/kcontrol/style/kcmstyle.h b/kcontrol/style/kcmstyle.h index fb2909b1a..6f6da6d1c 100644 --- a/kcontrol/style/kcmstyle.h +++ b/kcontrol/style/kcmstyle.h @@ -126,11 +126,13 @@ private: QFrame* containerFrame; QGridLayout* containerLayout; QComboBox* comboTooltipEffect; + QComboBox* comboRubberbandEffect; QComboBox* comboComboEffect; QComboBox* comboMenuEffect; QComboBox* comboMenuHandle; QLabel* lblTooltipEffect; + QLabel* lblRubberbandEffect; QLabel* lblComboEffect; QLabel* lblMenuEffect; QLabel* lblMenuHandle; diff --git a/kcontrol/usbview/kcmusb.desktop b/kcontrol/usbview/kcmusb.desktop index 0ae4500f2..76729bb5d 100644 --- a/kcontrol/usbview/kcmusb.desktop +++ b/kcontrol/usbview/kcmusb.desktop @@ -237,4 +237,4 @@ Keywords[zh_CN]=USB,devices,viewer,control,设备,查看器,控制 Keywords[zh_TW]=USB,devices,viewer,control,裝置,檢視器,控制 Keywords[zu]=USB,amathukuzi ananjongo,umbukisi,lawula -Categories=Qt;KDE;X-KDE-information; +Categories=Qt;KDE;X-KDE-settings-hardware; diff --git a/kcontrol/view1394/kcmview1394.desktop b/kcontrol/view1394/kcmview1394.desktop index 04a831f58..fb1b7ad79 100644 --- a/kcontrol/view1394/kcmview1394.desktop +++ b/kcontrol/view1394/kcmview1394.desktop @@ -216,4 +216,5 @@ Keywords[wa]=1394,IEEE 1394,Firewire,éndjins,håyneu,contrôle,corwaitaedje Keywords[zh_CN]=1394,Firewire,devices,viewer,control,设备,查看器,控制,火线 Keywords[zh_TW]=1394,Firewire,devices,viewer,control,裝置,檢視器,控制 -Categories=Qt;KDE;X-KDE-information; +Categories=Qt;KDE;X-KDE-settings-hardware; + diff --git a/kdeeject/kdeeject b/kdeeject/kdeeject index 1b55b73d4..71079794d 100755 --- a/kdeeject/kdeeject +++ b/kdeeject/kdeeject @@ -29,7 +29,7 @@ if test $# -ge 1 -a "$1" != "--help"; then ;; esac if test $? -eq 0; then - dcop kdesktop default refreshIcons +# dcop kdesktop default refreshIcons exit 0 elif test $quiet -eq 0; then kdialog --title "KDE Eject" --error "Eject $1 failed!" diff --git a/kdeprint/descriptions/Makefile.am b/kdeprint/descriptions/Makefile.am index b8b0bd95a..66b8205e6 100644 --- a/kdeprint/descriptions/Makefile.am +++ b/kdeprint/descriptions/Makefile.am @@ -18,7 +18,7 @@ printers.cpp: sortthem ./sortthem < printers.cpp | perl -n -e "print \"// xgettext: no-c-format\n\".\$$_;" > printers.new && mv printers.new $(srcdir)/printers.cpp messages: - $(XGETTEXT) printers.cpp -o $(podir)/../kdelibs/ppdtranslations.pot + $(XGETTEXT) printers.cpp -o $(podir)/ppdtranslations.pot .PHONY: printers.cpp diff --git a/kdeprint/kdeprintfax/defcmds.h b/kdeprint/kdeprintfax/defcmds.h index 6502250d3..cf9131e86 100644 --- a/kdeprint/kdeprintfax/defcmds.h +++ b/kdeprint/kdeprintfax/defcmds.h @@ -23,7 +23,7 @@ #include <qstring.h> -#define efax_default_cmd "%exe_fax %user_{NAME=\"@@\"} %dev_{DEV=@@} PAGE=%page %from_{FROM=@@} %res_{?\?-l} send %number %files" +#define efax_default_cmd "%exe_fax %user_{NAME=\"@@\"} %dev_{DEV=@@} PAGE=%page %from_{FROM=\"@@\"} %res_{?\?-l} send %number %files" #define hylafax_default_cmd "%exe_sendfax %cover_{?\?-n} %server_h %res_{-m?\?-l} %subject_r %time_a %enterprise_x %comment_c %email_f %from_W %page_s -d %name_{@@@}%number %files" #define mgetty_default_cmd "%exe_faxspool %user_F %email_f %name_D %time_t %number %files %res_{?\?-n} %cover_{?\?-C -}" diff --git a/kdesktop/bgmanager.cc b/kdesktop/bgmanager.cc index 62f97cecc..6274cf757 100644 --- a/kdesktop/bgmanager.cc +++ b/kdesktop/bgmanager.cc @@ -62,7 +62,7 @@ KBackgroundManager::KBackgroundManager(QWidget *desktop, KWinModule* kwinModule) m_pDesktop = desktop; if (desktop == 0L) - desktop = QApplication::desktop()->screen(); + desktop = KApplication::desktop()->screen(); m_Renderer.resize( 1 ); m_Cache.resize( 1 ); @@ -95,6 +95,9 @@ KBackgroundManager::KBackgroundManager(QWidget *desktop, KWinModule* kwinModule) SLOT(slotChangeDesktop(int))); connect(m_pKwinmodule, SIGNAL(numberOfDesktopsChanged(int)), SLOT(slotChangeNumberOfDesktops(int))); + connect(m_pKwinmodule, SIGNAL(currentDesktopViewportChanged(int, const QPoint&)), + SLOT(slotChangeViewport(int, const QPoint&))); + #if (QT_VERSION-0 >= 0x030200) connect( kapp->desktop(), SIGNAL( resized( int )), SLOT( desktopResized())); // RANDR support @@ -227,7 +230,21 @@ int KBackgroundManager::realDesktop() int KBackgroundManager::effectiveDesktop() { - return m_bCommon ? 0 : realDesktop(); + QSize s(m_pKwinmodule->numberOfViewports(m_pKwinmodule->currentDesktop())); + m_numberOfViewports = s.width() * s.height(); + + if (m_numberOfViewports > 1) { + if (m_bCommon) { + return 0; + } + else { + QPoint vx(m_pKwinmodule->currentViewport(m_pKwinmodule->currentDesktop())); + return (realDesktop() * m_numberOfViewports) + ((vx.x() * vx.y()) - 1); + } + } + else { + return m_bCommon ? 0 : realDesktop(); + } } @@ -236,6 +253,13 @@ int KBackgroundManager::effectiveDesktop() */ void KBackgroundManager::slotChangeNumberOfDesktops(int num) { + QSize s(m_pKwinmodule->numberOfViewports(m_pKwinmodule->currentDesktop())); + m_numberOfViewports = s.width() * s.height(); + if (m_numberOfViewports < 1) { + m_numberOfViewports = 1; + } + num = (num * m_numberOfViewports); + if (m_Renderer.size() == (unsigned) num) return; @@ -278,20 +302,26 @@ void KBackgroundManager::slotChangeNumberOfDesktops(int num) */ void KBackgroundManager::slotChangeDesktop(int desk) { + QSize s(m_pKwinmodule->numberOfViewports(m_pKwinmodule->currentDesktop())); + m_numberOfViewports = s.width() * s.height(); + if (m_numberOfViewports < 1) { + m_numberOfViewports = 1; + } + if (desk == 0) desk = realDesktop(); else desk--; // Lazy initialisation of # of desktops - if ((unsigned) desk >= m_Renderer.size()) - slotChangeNumberOfDesktops( m_pKwinmodule->numberOfDesktops() ); + if ((m_pKwinmodule->numberOfDesktops() * m_numberOfViewports) >= m_Renderer.size()) + slotChangeNumberOfDesktops( m_pKwinmodule->numberOfDesktops() * m_numberOfViewports); int edesk = effectiveDesktop(); m_Serial++; // If the background is the same: do nothing - if (m_Hash == m_Renderer[edesk]->hash()) + if ((m_Hash == m_Renderer[edesk]->hash()) && (desk != 0)) { exportBackground(m_Current, desk); return; @@ -306,6 +336,8 @@ void KBackgroundManager::slotChangeDesktop(int desk) continue; if (m_Cache[i]->hash != m_Renderer[edesk]->hash()) continue; + if (desk == 0) + continue; // kdDebug() << "slotChangeDesktop i=" << i << endl; setPixmap(m_Cache[i]->pixmap, m_Cache[i]->hash, i); m_Cache[i]->atime = m_Serial; @@ -316,8 +348,72 @@ void KBackgroundManager::slotChangeDesktop(int desk) // Do we have this or an identical config already running? for (unsigned i=0; i<m_Renderer.size(); i++) { - if ((m_Renderer[i]->hash() == m_Renderer[edesk]->hash()) && - (m_Renderer[i]->isActive())) + if (((m_Renderer[i]->hash() == m_Renderer[edesk]->hash()) && (m_Renderer[i]->isActive())) && (desk != 0)) + return; + } + + renderBackground(edesk); +} + +/* + * Call this when the viewport has been changed. + * Desk is in KWin convention: [1..desks], instead of [0..desks-1]. + * 0 repaints the current viewport. + */ +void KBackgroundManager::slotChangeViewport(int desk, const QPoint& viewport) +{ + QSize s(m_pKwinmodule->numberOfViewports(m_pKwinmodule->currentDesktop())); + m_numberOfViewports = s.width() * s.height(); + if (m_numberOfViewports < 1) { + m_numberOfViewports = 1; + } + + if (desk == 0) + desk = realDesktop(); + else + desk--; + + // Lazy initialisation of # of desktops + if ((m_pKwinmodule->numberOfDesktops() * m_numberOfViewports) >= m_Renderer.size()) + slotChangeNumberOfDesktops( m_pKwinmodule->numberOfDesktops() * m_numberOfViewports ); + + int edesk = effectiveDesktop(); + m_Serial++; + + // If the background is the same: do nothing + if ((m_Hash == m_Renderer[edesk]->hash()) && (desk != 0)) + { + exportBackground(m_Current, desk); + return; + } + m_Renderer[edesk]->stop(); + m_Renderer[edesk]->cleanup(); + + // If we have the background already rendered: set it + for (unsigned i=0; i<m_Cache.size(); i++) + { + if (!m_Cache[i]->pixmap) + continue; + if (m_Cache[i]->hash != m_Renderer[edesk]->hash()) + continue; + if (desk == 0) + continue; +// kdDebug() << "slotChangeDesktop i=" << i << endl; + + //KPixmap * viewport_background = new KPixmap(QPixmap(m_Cache[i]->pixmap->width()*s.width(), m_Cache[i]->pixmap->height()*s.height())); + //setPixmap(viewport_background, m_Cache[i]->hash, i); + //delete viewport_background; + + setPixmap(m_Cache[i]->pixmap, m_Cache[i]->hash, i); + m_Cache[i]->atime = m_Serial; + exportBackground(i, desk); + return; + } + + // Do we have this or an identical config already running? + for (unsigned i=0; i<m_Renderer.size(); i++) + { + if (((m_Renderer[i]->hash() == m_Renderer[edesk]->hash()) && (m_Renderer[i]->isActive())) && (desk != 0)) return; } @@ -360,14 +456,14 @@ void KBackgroundManager::setPixmap(KPixmap *pm, int hash, int desk) root_cleared = true; QTimer::singleShot( 0, this, SLOT( clearRoot())); // but make the pixmap visible until m_pDesktop is visible - QApplication::desktop()->screen()->setErasePixmap(*pm); - QApplication::desktop()->screen()->erase(); + KApplication::desktop()->screen()->setErasePixmap(*pm); + KApplication::desktop()->screen()->erase(); } } else { - QApplication::desktop()->screen()->setErasePixmap(*pm); - QApplication::desktop()->screen()->erase(); + KApplication::desktop()->screen()->setErasePixmap(*pm); + KApplication::desktop()->screen()->erase(); } // and export it via Esetroot-style for gnome/GTK apps to share in the pretties @@ -387,8 +483,8 @@ void KBackgroundManager::setPixmap(KPixmap *pm, int hash, int desk) void KBackgroundManager::clearRoot() { - QApplication::desktop()->screen()->setErasePixmap( QPixmap()); - QApplication::desktop()->screen()->erase(); + KApplication::desktop()->screen()->setErasePixmap( QPixmap()); + KApplication::desktop()->screen()->erase(); } /* @@ -412,6 +508,14 @@ void KBackgroundManager::renderBackground(int desk) */ void KBackgroundManager::slotImageDone(int desk) { + bool t_useViewports = 1; + QSize s(m_pKwinmodule->numberOfViewports(m_pKwinmodule->currentDesktop())); + m_numberOfViewports = s.width() * s.height(); + if (m_numberOfViewports < 1) { + m_numberOfViewports = 1; + t_useViewports = 0; + } + KPixmap *pm = new KPixmap(); KVirtualBGRenderer *r = m_Renderer[desk]; bool do_cleanup = true; @@ -421,6 +525,11 @@ void KBackgroundManager::slotImageDone(int desk) bool current = (r->hash() == m_Renderer[effectiveDesktop()]->hash()); if (current) { + //KPixmap * viewport_background = new KPixmap(QPixmap(pm->width()*s.width(), pm->height()*s.height())); + //printf("slotImageDone(): x: %d y: %d\n\r", viewport_background->size().width(), viewport_background->size().height()); + //setPixmap(viewport_background, r->hash(), desk); + //delete viewport_background; + setPixmap(pm, r->hash(), desk); if (!m_bBgInitDone) { @@ -742,7 +851,7 @@ void KBackgroundManager::repaintBackground() if (m_pDesktop) m_pDesktop->repaint(); else - QApplication::desktop()->screen()->erase(); + KApplication::desktop()->screen()->erase(); } void KBackgroundManager::desktopResized() @@ -755,12 +864,19 @@ void KBackgroundManager::desktopResized() removeCache(i); // make the renderer update its desktop size r->desktopResized(); + for (unsigned j=0; j<(r->numRenderers()); ++j) { + r->renderer(j)->desktopResized(); + } } m_Hash = 0; if( m_pDesktop ) - m_pDesktop->resize( kapp->desktop()->size()); + m_pDesktop->resize( kapp->desktop()->geometry().size()); // Repaint desktop slotChangeDesktop(0); + repaintBackground(); + + // Signal KWin that the usable desktop area has probably changed... + // Use the DCOP signal kDestopResized } // DCOP exported diff --git a/kdesktop/bgmanager.h b/kdesktop/bgmanager.h index e029cf6cd..53787e501 100644 --- a/kdesktop/bgmanager.h +++ b/kdesktop/bgmanager.h @@ -78,6 +78,7 @@ private slots: void slotTimeout(); void slotImageDone(int desk); void slotChangeDesktop(int); + void slotChangeViewport(int, const QPoint&); void slotChangeNumberOfDesktops(int); void repaintBackground(); void desktopResized(); @@ -92,6 +93,7 @@ private: int realDesktop(); int effectiveDesktop(); int validateDesk(int desk); + int m_numberOfViewports; void renderBackground(int desk); void exportBackground(int pixmap, int desk); diff --git a/kdesktop/desktop.cc b/kdesktop/desktop.cc index 6e2b1e9c0..18cb69fb4 100644 --- a/kdesktop/desktop.cc +++ b/kdesktop/desktop.cc @@ -516,9 +516,12 @@ void KDesktop::popupExecuteCommand(const QString& command) if ( m_miniCli->isVisible() ) { KWin::forceActiveWindow( m_miniCli->winId() ); } else { - QRect rect = KGlobalSettings::desktopGeometry(QCursor::pos()); - m_miniCli->move(rect.x() + (rect.width() - m_miniCli->width())/2, - rect.y() + (rect.height() - m_miniCli->height())/2); + NETRootInfo i( qt_xdisplay(), NET::Supported ); + if( !i.isSupported( NET::WM2FullPlacement )) { + QRect rect = KGlobalSettings::desktopGeometry(QCursor::pos()); + m_miniCli->move(rect.x() + (rect.width() - m_miniCli->width())/2, + rect.y() + (rect.height() - m_miniCli->height())/2); + } m_miniCli->show(); // non-modal } } diff --git a/kdesktop/kdesktop.kcfg b/kdesktop/kdesktop.kcfg index 597377661..b949efbea 100644 --- a/kdesktop/kdesktop.kcfg +++ b/kdesktop/kdesktop.kcfg @@ -331,6 +331,27 @@ <!-- minicli.cpp:192 --> <!-- int maxHistory = config->readNumEntry("HistoryLength", 50); --> </entry> + <entry key="MiniCLIAutocompletionLength" type="Int"> + <default>10</default> + <label></label> + <whatsthis></whatsthis> + <!-- minicli.cpp:651 --> + <!-- int maxAutocompletion = KDesktopSettings::MiniCLIAutocompletionLength(); --> + </entry> + <entry key="MiniCLIFilesystemAutoComplete" type="Bool"> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- minicli.cpp:216 --> + <!-- m_dlg->cbAutocomplete->setChecked( KDesktopSettings::miniCLIFilesystemAutoComplete() ); --> + </entry> + <entry key="MiniCLIHistoryAndFilesystemAutoComplete" type="Bool"> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- minicli.cpp:217 --> + <!-- m_dlg->cbAutohistory->setChecked( KDesktopSettings::miniCLIHistoryAndFilesystemAutoComplete() ); --> + </entry> <entry key="TerminalApps" type="PathList"> <default></default> <label></label> diff --git a/kdesktop/kdiconview.cc b/kdesktop/kdiconview.cc index f9ca6c446..b143dc231 100644 --- a/kdesktop/kdiconview.cc +++ b/kdesktop/kdiconview.cc @@ -485,7 +485,7 @@ void KDIconView::setAutoAlign( bool b ) // Auto line-up icons if ( b ) { - lineupIcons(); + if (!KRootWm::self()->startup) lineupIcons(); else KRootWm::self()->startup = false; connect( this, SIGNAL( iconMoved() ), this, SLOT( lineupIcons() ) ); } @@ -1440,7 +1440,7 @@ void KDIconView::updateWorkArea( const QRect &wr ) << " " << oldArea.width() << "x" << oldArea.height() << endl; if ( m_autoAlign ) - lineupIcons(); + int dummy = 0; //lineupIcons(); else { bool needRepaint = false; QIconViewItem* item; diff --git a/kdesktop/kfileividesktop.cpp b/kdesktop/kfileividesktop.cpp index 28bf51105..f9ea12a51 100644 --- a/kdesktop/kfileividesktop.cpp +++ b/kdesktop/kfileividesktop.cpp @@ -134,40 +134,11 @@ bool KFileIVIDesktop::shouldUpdateShadow(bool selected) return false; } -void KFileIVIDesktop::paintFocus( QPainter *p, const QColorGroup &cg ) -{ - if ( !iconView() ) - return; - - if ( !m_shadow || !wordWrap() || - !( static_cast<KDesktopShadowSettings *> - ( m_shadow->shadowSettings() ) )->isEnabled() ) { - QIconViewItem::paintFocus( p, cg ); - return; - } - - int spread = shadowThickness(); - - iconView()->style().drawPrimitive( QStyle::PE_FocusRect, p, - QRect( textRect( false ).x(), textRect( false ).y(), - textRect( false ).width() - spread, - textRect( false ).height() - spread + 1 ), - cg, - isSelected() ? QStyle::Style_FocusAtBorder : QStyle::Style_Default, - QStyleOption( isSelected() ? cg.highlight() : cg.base() ) ); - - if ( this != iconView()->currentItem() ) { - iconView()->style().drawPrimitive( QStyle::PE_FocusRect, p, - QRect( pixmapRect( false ).x(), pixmapRect( false ).y(), - pixmapRect( false ).width(), pixmapRect( false ).height() ), - cg, QStyle::Style_Default, QStyleOption( cg.base() ) ); - } -} void KFileIVIDesktop::drawShadowedText( QPainter *p, const QColorGroup &cg ) { - int textX = textRect( FALSE ).x() + 2; + int textX = textRect( FALSE ).x() + 4; int textY = textRect( FALSE ).y(); int align = ((KIconView *) iconView())->itemTextPos() == QIconView::Bottom ? AlignHCenter : AlignAuto; @@ -184,12 +155,15 @@ void KFileIVIDesktop::drawShadowedText( QPainter *p, const QColorGroup &cg ) int spread = shadowThickness(); if ( isSelected() && settings->selectionType() != KShadowSettings::InverseVideoOnSelection ) { - // select using a filled rect text = cg.highlightedText(); QRect rect = textRect( false ); rect.setRight( rect.right() - spread ); rect.setBottom( rect.bottom() - spread + 1 ); - p->fillRect( rect, cg.highlight() ); + p->setBrush( QBrush( cg.highlight() ) ); + p->setPen( QPen( cg.highlight() ) ); + p->drawRoundRect( rect, + 1000 / rect.width(), + 1000 / rect.height() ); } else { // use shadow diff --git a/kdesktop/kfileividesktop.h b/kdesktop/kfileividesktop.h index 0fb764cd0..c245a6800 100644 --- a/kdesktop/kfileividesktop.h +++ b/kdesktop/kfileividesktop.h @@ -80,12 +80,7 @@ class KFileIVIDesktop : public KFileIVI virtual void paintItem(QPainter *p, const QColorGroup &cg); /** - * Reimplements QIconView::paintFocus() to take the shadow - * metrics into account(); - */ - virtual void paintFocus( QPainter *p, const QColorGroup &cg ); - /** * Draws the shadow text. * @param p the painter for drawing the item * @param cg the base color group diff --git a/kdesktop/krootwm.cc b/kdesktop/krootwm.cc index 51586f878..fa22ab146 100644 --- a/kdesktop/krootwm.cc +++ b/kdesktop/krootwm.cc @@ -241,7 +241,7 @@ void KRootWm::initConfig() // Read configuration for icons alignment if ( m_bDesktopEnabled ) { - m_pDesktop->iconView()->setAutoAlign( KDesktopSettings::autoLineUpIcons() ); + bool startup = true; m_pDesktop->iconView()->setAutoAlign( KDesktopSettings::autoLineUpIcons() ); if ( kapp->authorize( "editable_desktop_icons" ) ) { m_pDesktop->iconView()->setItemsMovable( !KDesktopSettings::lockIcons() ); KToggleAction *aLockIcons = static_cast<KToggleAction*>(m_actionCollection->action("lock_icons")); diff --git a/kdesktop/krootwm.h b/kdesktop/krootwm.h index 9231b4bb6..3363fbf42 100644 --- a/kdesktop/krootwm.h +++ b/kdesktop/krootwm.h @@ -66,6 +66,7 @@ public: KRootWm(KDesktop*); ~KRootWm(); + bool startup; void mousePressed( const QPoint& _global, int _button ); bool hasLeftButtonMenu() { return leftButtonChoice != NOTHING; } diff --git a/kdesktop/minicli.cpp b/kdesktop/minicli.cpp index 096b293d0..2cf225bcc 100644 --- a/kdesktop/minicli.cpp +++ b/kdesktop/minicli.cpp @@ -1,5 +1,8 @@ /* This file is part of the KDE project + Autocompletion code: + Copyright (C) 2009 Timothy Pearson <[email protected]> + Copyright (C) 1999-2002,2003 Dawit Alemayehu <[email protected]> Copyright (C) 2000 Malte Starostik <[email protected]> Copyright (C) 2003 Sven Leiber <[email protected]> @@ -76,6 +79,8 @@ Minicli::Minicli( QWidget *parent, const char *name) :KDialog( parent, name, false, WType_TopLevel ), m_autoCheckedRunInTerm(false) { + m_pURLCompletion = 0L; + setPlainCaption( i18n("Run Command") ); KWin::setIcons( winId(), DesktopIcon("run"), SmallIcon("run") ); @@ -121,6 +126,13 @@ Minicli::Minicli( QWidget *parent, const char *name) m_dlg->leUsername->setText("root"); + // Autocomplete system + m_filesystemAutocomplete = 0; + m_histfilesystemAutocomplete = 0; + m_pURLCompletion = new KURLCompletion(); + //m_pURLCompletion->setCompletionMode( KGlobalSettings::completionMode() ); + connect( m_pURLCompletion, SIGNAL( match(const QString&) ), SLOT( slotMatch(const QString&) )); + // Main widget buttons... connect( m_dlg->pbRun, SIGNAL(clicked()), this, SLOT(accept()) ); connect( m_dlg->pbCancel, SIGNAL(clicked()), this, SLOT(reject()) ); @@ -137,6 +149,8 @@ Minicli::Minicli( QWidget *parent, const char *name) connect(m_dlg->cbPriority, SIGNAL(toggled(bool)), SLOT(slotChangeScheduler(bool))); connect(m_dlg->slPriority, SIGNAL(valueChanged(int)), SLOT(slotPriority(int))); connect(m_dlg->cbRealtime, SIGNAL(toggled(bool)), SLOT(slotRealtime(bool))); + connect(m_dlg->cbAutocomplete, SIGNAL(toggled(bool)), SLOT(slotAutocompleteToggled(bool))); + connect(m_dlg->cbAutohistory, SIGNAL(toggled(bool)), SLOT(slotAutohistoryToggled(bool))); connect(m_dlg->cbRunAsOther, SIGNAL(toggled(bool)), SLOT(slotChangeUid(bool))); connect(m_dlg->leUsername, SIGNAL(lostFocus()), SLOT(updateAuthLabel())); connect(m_dlg->cbRunInTerminal, SIGNAL(toggled(bool)), SLOT(slotTerminal(bool))); @@ -149,6 +163,7 @@ Minicli::Minicli( QWidget *parent, const char *name) Minicli::~Minicli() { delete m_filterData; + delete m_pURLCompletion; } void Minicli::setCommand(const QString& command) @@ -198,6 +213,19 @@ void Minicli::loadConfig() m_dlg->cbCommand->setHistoryItems( histList ); m_dlg->cbCommand->blockSignals( block ); + m_dlg->cbAutocomplete->setChecked( KDesktopSettings::miniCLIFilesystemAutoComplete() ); + m_dlg->cbAutohistory->setChecked( KDesktopSettings::miniCLIHistoryAndFilesystemAutoComplete() ); + + m_filesystemAutocomplete = KDesktopSettings::miniCLIFilesystemAutoComplete(); + m_histfilesystemAutocomplete = KDesktopSettings::miniCLIHistoryAndFilesystemAutoComplete(); + + if (m_histfilesystemAutocomplete == true) { + m_dlg->cbAutocomplete->setDisabled( true ); + } + else { + m_dlg->cbAutocomplete->setDisabled( false ); + } + QStringList compList = KDesktopSettings::completionItems(); if( compList.isEmpty() ) m_dlg->cbCommand->completionObject()->setItems( histList ); @@ -241,8 +269,10 @@ void Minicli::saveConfig() { KDesktopSettings::setHistory( m_dlg->cbCommand->historyItems() ); KDesktopSettings::setTerminalApps( m_terminalAppList ); - KDesktopSettings::setCompletionItems( m_dlg->cbCommand->completionObject()->items() ); + //KDesktopSettings::setCompletionItems( m_dlg->cbCommand->completionObject()->items() ); KDesktopSettings::setCompletionMode( m_dlg->cbCommand->completionMode() ); + KDesktopSettings::setMiniCLIFilesystemAutoComplete( m_filesystemAutocomplete ); + KDesktopSettings::setMiniCLIHistoryAndFilesystemAutoComplete( m_histfilesystemAutocomplete ); KDesktopSettings::writeConfig(); } @@ -369,6 +399,17 @@ int Minicli::runCommand() cmd = uri.path(); else cmd = uri.url(); + + QCString asn; + if( qApp->desktop()->isVirtualDesktop()) + { + asn = KStartupInfo::createNewStartupId(); + KStartupInfoId id; + id.initId( asn ); + KStartupInfoData data; + data.setXinerama( qApp->desktop()->screenNumber( this )); + KStartupInfo::sendChange( id, data ); + } // Determine whether the application should be run through // the command line (terminal) interface... @@ -504,7 +545,7 @@ int Minicli::runCommand() case KURIFilterData::HELP: { // No need for kfmclient, KRun does it all (David) - (void) new KRun( m_filterData->uri(), parentWidget()); + (void) new KRun( m_filterData->uri(), parentWidget(), asn ); return 0; } case KURIFilterData::EXECUTABLE: @@ -516,7 +557,7 @@ int Minicli::runCommand() if (service && service->isValid() && service->type() == "Application") { notifyServiceStarted(service); - KRun::run(*service, KURL::List()); + KRun::run(*service, KURL::List(), parentWidget(), asn ); return 0; } } @@ -551,7 +592,7 @@ int Minicli::runCommand() if (service && service->isValid() && service->type() == "Application") { notifyServiceStarted(service); - KRun::run(*service, KURL::List(), this); + KRun::run(*service, KURL::List(), parentWidget(), asn ); return 0; } @@ -559,7 +600,7 @@ int Minicli::runCommand() if (service && service->isValid() && service->type() == "Application") { notifyServiceStarted(service); - KRun::run(*service, KURL::List(), this); + KRun::run(*service, KURL::List(), parentWidget(), asn ); return 0; } @@ -571,7 +612,7 @@ int Minicli::runCommand() } } - if ( KRun::runCommand( cmd, exec, m_iconName ) ) + if ( KRun::runCommand( cmd, exec, m_iconName, parentWidget(), asn ) ) return 0; else { @@ -615,10 +656,58 @@ void Minicli::slotCmdChanged(const QString& text) return; } + else if ((m_filesystemAutocomplete == true) && ( m_pURLCompletion )) { + // Attempt to autocomplete the entered URL if it starts with the / character, meaning I am looking for something on the filesystem + // Also use autocompletion if it appears that I am using some kind of ioslave, except the http:// ioslave + m_urlCompletionStarted = true; // flag for slotMatch() + + if ((text.startsWith( "/" ) || text.startsWith( "~" ) || (text.contains("://", false) != 0)) && (text.contains("http://", false) == 0)) { + QString completion = m_pURLCompletion->makeCompletion( text ); + } + } m_parseTimer->start(250, true); } +// Handle match() from m_pURLCompletion +void Minicli::slotMatch( const QString &match ) +{ + QString current_text; + QStringList histList = KDesktopSettings::history(); + int maxHistory = KDesktopSettings::historyLength(); + int maxAutocompletion = KDesktopSettings::miniCLIAutocompletionLength(); + + if ( match.isEmpty() ) // this case is handled directly + return; + + // Check flag to avoid match() raised by rotation + if ( m_urlCompletionStarted ) { + m_urlCompletionStarted = false; + + if (m_filesystemAutocomplete == true) { + bool block = m_dlg->cbCommand->signalsBlocked(); + m_dlg->cbCommand->blockSignals( true ); + QStringList items = m_pURLCompletion->allMatches(); + items.sort(); + if (m_histfilesystemAutocomplete == true) { + // Add the history to the list + histList += items; + maxHistory += maxAutocompletion; + } + else { + histList = items; + maxHistory = maxAutocompletion; + } + current_text = m_dlg->cbCommand->currentText(); + //histList.prepend ( current_text ); // Add the current text to the autocompletion list + m_dlg->cbCommand->setMaxCount( maxHistory ); + m_dlg->cbCommand->completionObject()->setItems( histList ); + m_dlg->cbCommand->setCurrentText( current_text ); + m_dlg->cbCommand->blockSignals( block ); + } + } +} + void Minicli::slotAdvanced() { if (m_dlg->gbAdvanced->isHidden()) @@ -722,7 +811,7 @@ void Minicli::setIcon () void Minicli::updateAuthLabel() { - if (m_dlg->cbPriority->isChecked() && (m_iPriority > 50) || + if ((m_dlg->cbPriority->isChecked() && (m_iPriority > 50)) || (m_iScheduler != StubProcess::SchedNormal)) { if (!m_prevCached && !m_dlg->leUsername->text().isEmpty()) @@ -843,6 +932,42 @@ void Minicli::slotRealtime(bool enabled) updateAuthLabel(); } +void Minicli::slotAutocompleteToggled(bool enabled) +{ + if (enabled) + { + // Enable filesystem autocompletion + m_filesystemAutocomplete = true; + } + else { + // Enable history only autocompletion + m_filesystemAutocomplete = false; + } + + QString current_text = m_dlg->cbCommand->currentText(); + m_dlg->cbCommand->setCurrentText( current_text ); // Force an update of the autocompletion list +} + +void Minicli::slotAutohistoryToggled(bool enabled) +{ + if (enabled) + { + // Enable history and filesystem autocompletion + m_histfilesystemAutocomplete = true; + m_filesystemAutocomplete = true; + m_dlg->cbAutocomplete->setChecked( true ); + m_dlg->cbAutocomplete->setDisabled ( true ); + } + else { + // Disable history and filesystem autocompletion + m_histfilesystemAutocomplete = false; + m_dlg->cbAutocomplete->setDisabled ( false ); + } + + QString current_text = m_dlg->cbCommand->currentText(); + m_dlg->cbCommand->setCurrentText( current_text ); // Force an update of the autocompletion list +} + void Minicli::slotPriority(int priority) { // Provide a way to easily return to the default priority diff --git a/kdesktop/minicli.h b/kdesktop/minicli.h index 8f98fe3ea..a4215582f 100644 --- a/kdesktop/minicli.h +++ b/kdesktop/minicli.h @@ -37,6 +37,8 @@ #include <kdialog.h> #include <kservice.h> +#include <kurlcompletion.h> + class QTimer; class QWidget; class MinicliDlgUI; @@ -74,10 +76,13 @@ private slots: void slotParseTimer(); void slotPriority(int); void slotRealtime(bool); + void slotAutocompleteToggled(bool); + void slotAutohistoryToggled(bool); void slotTerminal(bool); void slotChangeUid(bool); void slotChangeScheduler(bool); void slotCmdChanged(const QString&); + void slotMatch( const QString&); private: void setIcon(); @@ -108,5 +113,11 @@ private: bool m_prevChecked; bool m_prevCached; bool m_autoCheckedRunInTerm; + + // Autocomplete + KURLCompletion *m_pURLCompletion; + bool m_filesystemAutocomplete; + bool m_histfilesystemAutocomplete; + bool m_urlCompletionStarted; }; #endif diff --git a/kdesktop/minicli_ui.ui b/kdesktop/minicli_ui.ui index 32416b8f3..3809eb852 100644 --- a/kdesktop/minicli_ui.ui +++ b/kdesktop/minicli_ui.ui @@ -9,7 +9,7 @@ <x>0</x> <y>0</y> <width>325</width> - <height>370</height> + <height>390</height> </rect> </property> <property name="sizePolicy"> @@ -180,6 +180,30 @@ </qt></string> </property> </widget> + <widget class="QCheckBox" row="8" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>cbAutocomplete</cstring> + </property> + <property name="text"> + <string>Autocomplete uses &filesystem instead of history</string> + </property> + <property name="whatsThis" stdset="0"> + <string><qt>This selects whether the filesystem or the past command history will be used for autocompletion. + </qt></string> + </property> + </widget> + <widget class="QCheckBox" row="9" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>cbAutohistory</cstring> + </property> + <property name="text"> + <string>Autocomplete uses &both history and filesystem</string> + </property> + <property name="whatsThis" stdset="0"> + <string><qt>This selects whether the filesystem and the past command history will be used for autocompletion. + </qt></string> + </property> + </widget> <widget class="QLabel" row="3" column="1"> <property name="name"> <cstring>lbUsername</cstring> diff --git a/kdesu/kdesu/kdesu.cpp b/kdesu/kdesu/kdesu.cpp index f45d68092..3e7b7a77b 100644 --- a/kdesu/kdesu/kdesu.cpp +++ b/kdesu/kdesu/kdesu.cpp @@ -274,7 +274,7 @@ static int startApp() // Try to exec the command with kdesud. bool keep = !args->isSet("n") && have_daemon; - bool terminal = args->isSet("t"); + bool terminal = true; bool new_dcop = args->isSet("newdcop"); bool withIgnoreButton = args->isSet("ignorebutton"); diff --git a/kdm/backend/Imakefile b/kdm/backend/Imakefile index 75efcb45a..f3b4e0050 100644 --- a/kdm/backend/Imakefile +++ b/kdm/backend/Imakefile @@ -155,13 +155,13 @@ PROCTITLE_DEFINES = -DHAS_SETPROCTITLE netaddr.c reset.c resource.c protodpy.c policy.c \ session.c socket.c streams.c util.c xdmcp.c \ process.c mitauth.c \ - genauth.c access.c choose.c \ + genauth.c access.c choose.c consolekit.c \ $(XDMAUTHSRCS) $(RPCSRCS) $(KRB5SRCS) COMMOBJS = auth.o daemon.o server.o dpylist.o dm.o error.o \ netaddr.o reset.o resource.o protodpy.o policy.o \ session.o socket.o streams.o util.o xdmcp.o \ process.o mitauth.o \ - genauth.o access.o choose.o \ + genauth.o access.o choose.o consolekit.o \ $(XDMAUTHOBJS) $(RPCOBJS) $(KRB5OBJS) SRCS1 = $(COMMSRCS) client.c diff --git a/kdm/backend/Makefile.am b/kdm/backend/Makefile.am index 81dc2702f..58c2a9e43 100644 --- a/kdm/backend/Makefile.am +++ b/kdm/backend/Makefile.am @@ -1,9 +1,9 @@ # forcibly remove thread-related defines & flags AUTOMAKE_OPTIONS = foreign -CPPFLAGS = $(USER_INCLUDES) $(X_INCLUDES) $(KRB4_INCS) $(KRB5_INCS) -I.. -I../.. +CPPFLAGS = $(USER_INCLUDES) $(X_INCLUDES) $(KRB4_INCS) $(KRB5_INCS) $(DBUS_INCS) -I.. -I../.. LDFLAGS = $(USER_LDFLAGS) $(X_LDFLAGS) $(X_RPATH) $(KRB4_RPATH) $(KRB5_RPATH) LDADD = $(LIB_X11) -lXau $(LIBXDMCP) $(PASSWDLIBS) $(LIBSHADOW) $(LIBGEN) \ - $(LIB_LIBS) $(KRB4_LIBS) $(KRB5_LIBS) $(LIBSOCKET) $(LIBRESOLV) \ + $(LIB_LIBS) $(KRB4_LIBS) $(KRB5_LIBS) $(DBUS_LIBS) $(LIBSOCKET) $(LIBRESOLV) \ $(LIBUCB) $(LIBUTIL) $(LIBPOSIX4) bin_PROGRAMS = kdm @@ -13,6 +13,7 @@ kdm_SOURCES = \ bootman.c \ choose.c \ client.c \ + consolekit.c \ ctrl.c \ daemon.c \ dm.c \ diff --git a/kdm/backend/auth.c b/kdm/backend/auth.c index fa7afac01..21b3c5d48 100644 --- a/kdm/backend/auth.c +++ b/kdm/backend/auth.c @@ -942,7 +942,7 @@ setAuthNumber( Xauth *auth, const char *name ) colon = strrchr( name, ':' ); if (colon) { ++colon; - dot = strchr( colon, '.' ); + dot = (char*)strchr( colon, '.' ); if (dot) auth->number_length = dot - colon; else diff --git a/kdm/backend/bootman.c b/kdm/backend/bootman.c index c6ac968a2..291164ea7 100644 --- a/kdm/backend/bootman.c +++ b/kdm/backend/bootman.c @@ -82,7 +82,7 @@ getGrub( char ***opts, int *def, int *cur ) int len; char line[1000]; - if (!grub && !(grub = locate( "grub" ))) + if (!grub && !(grub = locate( "grub-set-default" ))) return BO_NOMAN; *def = 0; @@ -132,19 +132,14 @@ setGrub( const char *opt, SdRec *sdr ) static void commitGrub( void ) { - FILE *f; - int pid; - static const char *args[] = { 0, "--batch", "--no-floppy", 0 }; + char command[256]; if (sdRec.bmstamp != mTime( GRUB_MENU ) && setGrub( sdRec.osname, &sdRec ) != BO_OK) return; - args[0] = grub; - if ((f = pOpen( (char **)args, 'w', &pid ))) { - fprintf( f, "savedefault --default=%d --once\n", sdRec.osindex ); - pClose( f, pid ); - } + sprintf(command, "%s %d", grub, sdRec.osindex); + system(command); } static char *lilo; diff --git a/kdm/backend/client.c b/kdm/backend/client.c index c807b6e15..b2e7ebbc7 100644 --- a/kdm/backend/client.c +++ b/kdm/backend/client.c @@ -83,6 +83,10 @@ extern int loginsuccess( const char *User, const char *Host, const char *Tty, ch #endif #include <signal.h> +#ifdef WITH_CONSOLE_KIT +#include "consolekit.h" +#endif + /* * Session data, mostly what struct verify_info was for */ @@ -310,7 +314,7 @@ doPAMAuth( const char *psrv, struct pam_data *pdata ) V_RET_FAIL( 0 ); } if ((td->displayType & d_location) == dForeign) { - char *cp = strchr( td->name, ':' ); + char *cp = (char*)strchr( td->name, ':' ); *cp = 0; pretc = pam_set_item( pamh, PAM_RHOST, td->name ); *cp = ':'; @@ -495,7 +499,7 @@ Verify( GConvFunc gconv, int rootok ) char *tmpch; strncpy( hostname, td->name, sizeof(hostname) - 1 ); hostname[sizeof(hostname)-1] = '\0'; - if ((tmpch = strchr( hostname, ':' ))) + if ((tmpch = (char*)strchr( hostname, ':' ))) *tmpch = '\0'; } else hostname[0] = '\0'; @@ -1121,8 +1125,13 @@ static int removeSession; static int removeCreds; #endif +#ifdef WITH_CONSOLE_KIT +int +StartClient( const char *ck_session_cookie ) +#else int StartClient() +#endif { const char *home, *sessargs, *desksess; char **env, *xma; @@ -1218,6 +1227,11 @@ StartClient() if (krbtkfile[0] != '\0') env = setEnv( env, "KRBTKFILE", krbtkfile ); #endif +#ifdef WITH_CONSOLE_KIT + if (ck_session_cookie != NULL) { + env = setEnv ( env, "XDG_SESSION_COOKIE", ck_session_cookie ); + } +#endif userEnviron = inheritEnv( env, envvars ); env = systemEnv( p->pw_name ); systemEnviron = setEnv( env, "HOME", p->pw_dir ); diff --git a/kdm/backend/consolekit.c b/kdm/backend/consolekit.c new file mode 100644 index 000000000..cb59b7369 --- /dev/null +++ b/kdm/backend/consolekit.c @@ -0,0 +1,557 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2006-2007 William Jon McCann <[email protected]> + * Copyright (C) 2007 Kevin Kofler <[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 "dm.h" +#include "dm_auth.h" +#include "dm_error.h" + +#include <stdlib.h> +#include <string.h> +#include <pwd.h> + +#define DBUS_API_SUBJECT_TO_CHANGE +#include <dbus/dbus.h> + +#include "consolekit.h" + + +#define CK_NAME "org.freedesktop.ConsoleKit" +#define CK_PATH "/org/freedesktop/ConsoleKit" +#define CK_INTERFACE "org.freedesktop.ConsoleKit" +#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager" +#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager" +#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session" + +static DBusConnection *private_connection = NULL; + +static void +add_param_int (DBusMessageIter *iter_struct, + const char *key, + int value) +{ + DBusMessageIter iter_struct_entry; + DBusMessageIter iter_var; + + dbus_message_iter_open_container (iter_struct, + DBUS_TYPE_STRUCT, + NULL, + &iter_struct_entry); + + dbus_message_iter_append_basic (&iter_struct_entry, + DBUS_TYPE_STRING, + &key); + + dbus_message_iter_open_container (&iter_struct_entry, + DBUS_TYPE_VARIANT, + DBUS_TYPE_INT32_AS_STRING, + &iter_var); + + dbus_message_iter_append_basic (&iter_var, + DBUS_TYPE_INT32, + &value); + + dbus_message_iter_close_container (&iter_struct_entry, + &iter_var); + + dbus_message_iter_close_container (iter_struct, &iter_struct_entry); +} + +static void +add_param_boolean (DBusMessageIter *iter_struct, + const char *key, + int value) +{ + DBusMessageIter iter_struct_entry; + DBusMessageIter iter_var; + + dbus_message_iter_open_container (iter_struct, + DBUS_TYPE_STRUCT, + NULL, + &iter_struct_entry); + + dbus_message_iter_append_basic (&iter_struct_entry, + DBUS_TYPE_STRING, + &key); + + dbus_message_iter_open_container (&iter_struct_entry, + DBUS_TYPE_VARIANT, + DBUS_TYPE_BOOLEAN_AS_STRING, + &iter_var); + + dbus_message_iter_append_basic (&iter_var, + DBUS_TYPE_BOOLEAN, + &value); + + dbus_message_iter_close_container (&iter_struct_entry, + &iter_var); + + dbus_message_iter_close_container (iter_struct, &iter_struct_entry); +} + +static void +add_param_string (DBusMessageIter *iter_struct, + const char *key, + const char *value) +{ + DBusMessageIter iter_struct_entry; + DBusMessageIter iter_var; + + dbus_message_iter_open_container (iter_struct, + DBUS_TYPE_STRUCT, + NULL, + &iter_struct_entry); + + dbus_message_iter_append_basic (&iter_struct_entry, + DBUS_TYPE_STRING, + &key); + + dbus_message_iter_open_container (&iter_struct_entry, + DBUS_TYPE_VARIANT, + DBUS_TYPE_STRING_AS_STRING, + &iter_var); + + dbus_message_iter_append_basic (&iter_var, + DBUS_TYPE_STRING, + &value); + + dbus_message_iter_close_container (&iter_struct_entry, + &iter_var); + + dbus_message_iter_close_container (iter_struct, &iter_struct_entry); +} + +static int +session_get_x11_display (DBusConnection *connection, + const char *ssid, + char **str) +{ + DBusError error; + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + const char *value; + + if (str != NULL) { + *str = NULL; + } + + message = dbus_message_new_method_call (CK_NAME, + ssid, + CK_SESSION_INTERFACE, + "GetX11Display"); + if (message == NULL) { + Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); + return FALSE; + } + + dbus_error_init (&error); + reply = dbus_connection_send_with_reply_and_block (connection, + message, + -1, &error); + if (dbus_error_is_set (&error)) { + Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); + reply = NULL; + } + + dbus_connection_flush (connection); + dbus_message_unref (message); + + if (reply == NULL) { + return FALSE; + } + + dbus_message_iter_init (reply, &iter); + dbus_message_iter_get_basic (&iter, &value); + if (str != NULL) { + *str = strdup (value); + } + dbus_message_unref (reply); + + return TRUE; +} + +static int +session_unlock (DBusConnection *connection, + const char *ssid) +{ + DBusError error; + DBusMessage *message; + DBusMessage *reply; + + Debug ("ConsoleKit: Unlocking session %s", ssid); + message = dbus_message_new_method_call (CK_NAME, + ssid, + CK_SESSION_INTERFACE, + "Unlock"); + if (message == NULL) { + Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); + return FALSE; + } + + dbus_error_init (&error); + reply = dbus_connection_send_with_reply_and_block (connection, + message, + -1, &error); + dbus_message_unref (message); + dbus_message_unref (reply); + dbus_connection_flush (connection); + + if (dbus_error_is_set (&error)) { + Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); + return FALSE; + } + + return TRUE; +} + +/* from libhal */ +static char ** +get_path_array_from_iter (DBusMessageIter *iter, + int *num_elements) +{ + int count; + char **buffer; + + count = 0; + buffer = (char **)malloc (sizeof (char *) * 8); + + if (buffer == NULL) + goto oom; + + buffer[0] = NULL; + while (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_OBJECT_PATH) { + const char *value; + char *str; + + if ((count % 8) == 0 && count != 0) { + buffer = realloc (buffer, sizeof (char *) * (count + 8)); + if (buffer == NULL) + goto oom; + } + + dbus_message_iter_get_basic (iter, &value); + str = strdup (value); + if (str == NULL) + goto oom; + + buffer[count] = str; + + dbus_message_iter_next (iter); + count++; + } + + if ((count % 8) == 0) { + buffer = realloc (buffer, sizeof (char *) * (count + 1)); + if (buffer == NULL) + goto oom; + } + + buffer[count] = NULL; + if (num_elements != NULL) + *num_elements = count; + return buffer; + +oom: + LogWarn ("%s %d : error allocating memory\n", __FILE__, __LINE__); + return NULL; + +} + +static char ** +get_sessions_for_user (DBusConnection *connection, + const char *user, + const char *x11_display) +{ + DBusError error; + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + DBusMessageIter iter_reply; + DBusMessageIter iter_array; + struct passwd *pwent; + char **sessions; + + sessions = NULL; + message = NULL; + reply = NULL; + + pwent = getpwnam (user); + + dbus_error_init (&error); + message = dbus_message_new_method_call (CK_NAME, + CK_MANAGER_PATH, + CK_MANAGER_INTERFACE, + "GetSessionsForUser"); + if (message == NULL) { + Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); + goto out; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, + DBUS_TYPE_UINT32, + &pwent->pw_uid); + + dbus_error_init (&error); + reply = dbus_connection_send_with_reply_and_block (connection, + message, + -1, &error); + dbus_connection_flush (connection); + + if (dbus_error_is_set (&error)) { + Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); + goto out; + } + + if (reply == NULL) { + Debug ("ConsoleKit: No reply for GetSessionsForUser"); + goto out; + } + + dbus_message_iter_init (reply, &iter_reply); + if (dbus_message_iter_get_arg_type (&iter_reply) != DBUS_TYPE_ARRAY) { + Debug ("ConsoleKit: Wrong reply for GetSessionsForUser - expecting an array."); + goto out; + } + + dbus_message_iter_recurse (&iter_reply, &iter_array); + sessions = get_path_array_from_iter (&iter_array, NULL); + + out: + if (message != NULL) { + dbus_message_unref (message); + } + if (reply != NULL) { + dbus_message_unref (reply); + } + + return sessions; +} + +void +unlock_ck_session (const char *user, + const char *x11_display) +{ + DBusError error; + DBusConnection *connection; + char **sessions; + int i; + + Debug ("ConsoleKit: Unlocking session for %s on %s", user, x11_display); + + dbus_error_init (&error); + connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); + if (connection == NULL) { + Debug ("ConsoleKit: Failed to connect to the D-Bus daemon: %s", error.message); + dbus_error_free (&error); + return; + } + + sessions = get_sessions_for_user (connection, user, x11_display); + if (sessions == NULL || sessions[0] == NULL) { + Debug ("ConsoleKit: no sessions found"); + return; + } + + for (i = 0; sessions[i] != NULL; i++) { + char *ssid; + char *xdisplay; + + ssid = sessions[i]; + session_get_x11_display (connection, ssid, &xdisplay); + Debug ("ConsoleKit: session %s has DISPLAY %s", ssid, xdisplay); + + if (xdisplay != NULL + && x11_display != NULL + && strcmp (xdisplay, x11_display) == 0) { + int res; + + res = session_unlock (connection, ssid); + if (! res) { + LogError ("ConsoleKit: Unable to unlock %s", ssid); + } + } + + free (xdisplay); + } + + freeStrArr (sessions); +} + +char * +open_ck_session (struct passwd *pwent, + struct display *d) +{ + DBusConnection *connection; + DBusError error; + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + DBusMessageIter iter_struct; + char *cookie; + + cookie = NULL; + + if (pwent == NULL) { + Debug ("ConsoleKit: NULL user passed as parameter"); + return NULL; + } + + Debug ("ConsoleKit: Opening session for %s", pwent->pw_name); + + dbus_error_init (&error); + connection = dbus_bus_get_private (DBUS_BUS_SYSTEM, &error); + private_connection = connection; + + if (connection == NULL) { + Debug ("ConsoleKit: Failed to connect to the D-Bus daemon: %s", error.message); + dbus_error_free (&error); + return NULL; + } + + dbus_connection_set_exit_on_disconnect (connection, FALSE); + /* FIXME: What to do about these? + dbus_connection_set_watch_functions( connection, + dbusAddWatch, + dbusRemoveWatch, + dbusToggleWatch, + data, 0 ); + dbus_connection_set_timeout_functions( connection, + dbusAddTimeout, + dbusRemoveTimeout, + dbusToggleTimeout, + data, 0 ); + dbus_connection_set_wakeup_main_function( connection, + dbusWakeupMain, + data, 0 ); */ + + dbus_error_init (&error); + message = dbus_message_new_method_call (CK_NAME, + CK_MANAGER_PATH, + CK_MANAGER_INTERFACE, + "OpenSessionWithParameters"); + if (message == NULL) { + Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); + return NULL; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_open_container (&iter, + DBUS_TYPE_ARRAY, + DBUS_STRUCT_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_STRUCT_END_CHAR_AS_STRING, + &iter_struct); + + add_param_int (&iter_struct, "user", pwent->pw_uid); + add_param_string (&iter_struct, "x11-display", d->name); + add_param_boolean (&iter_struct, "is-local", ((d->displayType & d_location) == dLocal)); +#ifdef XDMCP + if ((d->displayType & d_location) != dLocal) { + add_param_string (&iter_struct, "remote-host-name", d->remoteHost); + } +#endif + +#ifdef HAVE_VTS + if (d->serverVT > 0) { + char device[20]; + + /* FIXME: how does xorg construct this */ + sprintf(device, "/dev/tty%d", d->serverVT); + add_param_string (&iter_struct, "x11-display-device", device); + } +#endif + + dbus_message_iter_close_container (&iter, &iter_struct); + + reply = dbus_connection_send_with_reply_and_block (connection, + message, + -1, &error); + if (dbus_error_is_set (&error)) { + Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); + reply = NULL; + } + + dbus_connection_flush (connection); + + dbus_message_unref (message); + dbus_error_free (&error); + + if (reply != NULL) { + const char *value; + + dbus_message_iter_init (reply, &iter); + dbus_message_iter_get_basic (&iter, &value); + cookie = strdup (value); + dbus_message_unref (reply); + } + + return cookie; +} + +void +close_ck_session (const char *cookie) +{ + DBusError error; + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + + if (cookie == NULL) { + return; + } + + if (private_connection == NULL) { + return; + } + + dbus_error_init (&error); + message = dbus_message_new_method_call (CK_NAME, + CK_MANAGER_PATH, + CK_MANAGER_INTERFACE, + "CloseSession"); + if (message == NULL) { + Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); + return; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, + DBUS_TYPE_STRING, + &cookie); + + reply = dbus_connection_send_with_reply_and_block (private_connection, + message, + -1, &error); + if (dbus_error_is_set (&error)) { + Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); + reply = NULL; + } + + dbus_connection_flush (private_connection); + + dbus_message_unref (message); + dbus_error_free (&error); + + dbus_connection_close (private_connection); + private_connection = NULL; +} diff --git a/kdm/backend/consolekit.h b/kdm/backend/consolekit.h new file mode 100644 index 000000000..f1cbddb54 --- /dev/null +++ b/kdm/backend/consolekit.h @@ -0,0 +1,36 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2006 William Jon McCann <[email protected]> + * Copyright (C) 2007 Kevin Kofler <[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 __CONSOLE_KIT_H +#define __CONSOLE_KIT_H + +#include <pwd.h> + +struct display; + +char * open_ck_session (struct passwd *pwent, + struct display *display); +void close_ck_session (const char *cookie); +void unlock_ck_session (const char *user, + const char *x11_display); + +#endif /* __CONSOLE_KIT_H */ diff --git a/kdm/backend/dm.c b/kdm/backend/dm.c index e696a1a5e..a372686df 100644 --- a/kdm/backend/dm.c +++ b/kdm/backend/dm.c @@ -39,6 +39,7 @@ from the copyright holder. #include "dm_error.h" #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <unistd.h> #include <stdarg.h> @@ -122,7 +123,8 @@ main( int argc, char **argv ) StrApp( &progpath, directory, "/", argv[0], (char *)0 ); else { int len; - char *path, *pathe, *name, *thenam, nambuf[PATH_MAX+1]; + char *path, *name, *thenam, nambuf[PATH_MAX+1]; + char *pathe; if (!(path = getenv( "PATH" ))) Panic( "Can't find myself (no PATH)" ); @@ -131,7 +133,7 @@ main( int argc, char **argv ) memcpy( name, argv[0], len + 1 ); *--name = '/'; do { - if (!(pathe = strchr( path, ':' ))) + if (!(pathe = (char*)strchr( path, ':' ))) pathe = path + strlen( path ); len = pathe - path; if (!len || (len == 1 && *path == '.')) { @@ -564,6 +566,21 @@ StartRemoteLogin( struct display *d ) Debug( "exec %\"[s\n", argv ); (void)execv( argv[0], argv ); LogError( "X server %\"s cannot be executed\n", argv[0] ); + + /* Let's try again with some standard paths */ + argv[0] = (char *)realloc(argv[0], strlen("/usr/X11R6/bin/X") + 1); + if (argv[0] != NULL) { + argv[0] = "/usr/X11R6/bin/X"; + Debug( "exec %\"[s\n", argv ); + (void)execv( argv[0], argv ); + LogError( "X server %\"s cannot be executed\n", argv[0] ); + + argv[0] = "/usr/bin/X"; /* Shorter than the previous file name */ + Debug( "exec %\"[s\n", argv ); + (void)execv( argv[0], argv ); + LogError( "X server %\"s cannot be executed\n", argv[0] ); + } + exit( 1 ); case -1: LogError( "Forking X server for remote login failed: %m" ); diff --git a/kdm/backend/dm.h b/kdm/backend/dm.h index 6d2f59768..664d2cf1a 100644 --- a/kdm/backend/dm.h +++ b/kdm/backend/dm.h @@ -37,6 +37,8 @@ from the copyright holder. #ifndef _DM_H_ #define _DM_H_ 1 +#define WITH_CONSOLE_KIT + #include "greet.h" #include <config.ci> @@ -476,7 +478,11 @@ char **GRecvArgv( void ); #define GCONV_BINARY 5 typedef char *(*GConvFunc)( int what, const char *prompt ); int Verify( GConvFunc gconv, int rootok ); +#ifdef WITH_CONSOLE_KIT +int StartClient( const char *ck_session_cookie ); +#else int StartClient( void ); +#endif void SessionExit( int status ) ATTR_NORETURN; int ReadDmrc( void ); extern char **userEnviron, **systemEnviron; diff --git a/kdm/backend/process.c b/kdm/backend/process.c index 30dca096d..8e21d789b 100644 --- a/kdm/backend/process.c +++ b/kdm/backend/process.c @@ -264,7 +264,8 @@ char * locate( const char *exe ) { int len; - char *path, *pathe, *name, *thenam, nambuf[PATH_MAX+1]; + char *path, *name, *thenam, nambuf[PATH_MAX+1]; + char *pathe; if (!(path = getenv( "PATH" ))) { LogError( "Can't execute %'s: $PATH not set.\n", exe ); @@ -275,7 +276,7 @@ locate( const char *exe ) memcpy( name, exe, len + 1 ); *--name = '/'; do { - if (!(pathe = strchr( path, ':' ))) + if (!(pathe = (char*)strchr( path, ':' ))) pathe = path + strlen( path ); len = pathe - path; if (len && !(len == 1 && *path == '.')) { diff --git a/kdm/backend/server.c b/kdm/backend/server.c index 129c8bfe1..e78d8a66c 100644 --- a/kdm/backend/server.c +++ b/kdm/backend/server.c @@ -41,6 +41,7 @@ from the copyright holder. #include <X11/Xlib.h> #include <stdio.h> +#include <stdlib.h> #include <signal.h> @@ -94,6 +95,21 @@ StartServerOnce( void ) (void)Signal( SIGUSR1, SIG_IGN ); (void)execv( argv[0], argv ); LogError( "X server %\"s cannot be executed\n", argv[0] ); + + /* Let's try again with some standard paths */ + argv[0] = (char *)realloc(argv[0], strlen("/usr/X11R6/bin/X") + 1); + if (argv[0] != NULL) { + argv[0] = "/usr/X11R6/bin/X"; + Debug( "exec %\"[s\n", argv ); + (void)execv( argv[0], argv ); + LogError( "X server %\"s cannot be executed\n", argv[0] ); + + argv[0] = "/usr/bin/X"; /* Shorter than the previous file name */ + Debug( "exec %\"[s\n", argv ); + (void)execv( argv[0], argv ); + LogError( "X server %\"s cannot be executed\n", argv[0] ); + } + exit( 47 ); case -1: LogError( "X server fork failed\n" ); diff --git a/kdm/backend/session.c b/kdm/backend/session.c index 72da0a820..9a12ce312 100644 --- a/kdm/backend/session.c +++ b/kdm/backend/session.c @@ -45,6 +45,10 @@ from the copyright holder. #include <ctype.h> #include <signal.h> +#ifdef WITH_CONSOLE_KIT +#include "consolekit.h" +#endif + struct display *td; const char *td_setup = "auto"; @@ -530,6 +534,10 @@ ManageSession( struct display *d ) int ex, cmd; volatile int clientPid = 0; volatile Time_t tdiff = 0; +#ifdef WITH_CONSOLE_KIT + char *ck_session_cookie; +#endif + td = d; Debug( "ManageSession %s\n", d->name ); @@ -626,7 +634,12 @@ ManageSession( struct display *d ) if (td_setup) SetupDisplay( td_setup ); +#ifdef WITH_CONSOLE_KIT + ck_session_cookie = open_ck_session (getpwnam(curuser), d); + if (!(clientPid = StartClient(ck_session_cookie))) { +#else if (!(clientPid = StartClient())) { +#endif LogError( "Client start failed\n" ); SessionExit( EX_NORMAL ); /* XXX maybe EX_REMANAGE_DPY? -- enable in dm.c! */ } @@ -648,6 +661,14 @@ ManageSession( struct display *d ) catchTerm( SIGTERM ); } } + +#ifdef WITH_CONSOLE_KIT + if (ck_session_cookie != NULL) { + close_ck_session (ck_session_cookie); + free (ck_session_cookie); + } +#endif + /* * Sometimes the Xsession somehow manages to exit before * a server crash is noticed - so we sleep a bit and wait diff --git a/kdm/backend/sessreg.c b/kdm/backend/sessreg.c index 03a46e992..e603ff4c6 100644 --- a/kdm/backend/sessreg.c +++ b/kdm/backend/sessreg.c @@ -102,7 +102,7 @@ crc32s( const unsigned char *str ) void sessreg( struct display *d, int pid, const char *user, int uid ) { - const char *dot, *colon; + char *dot, *colon; int left, clen; #ifdef BSD_UTMP FILE *ttys; @@ -134,7 +134,7 @@ sessreg( struct display *d, int pid, const char *user, int uid ) } ut_ent.ut_time = time( 0 ); - colon = strchr( d->name, ':' ); + colon = (char*)strchr( d->name, ':' ); clen = strlen( colon ); if (clen > (int)(sizeof(ut_ent.ut_line) - UTL_OFF) - 2) return; /* uhm, well ... */ @@ -175,7 +175,7 @@ sessreg( struct display *d, int pid, const char *user, int uid ) colon = d->name; left = 0; } else { - dot = strchr( d->name, '.' ); + dot = (char*)strchr( d->name, '.' ); if (dot && dot - d->name < left) { memcpy( ut_ent.ut_line + UTL_OFF, d->name, left - 1 ); ut_ent.ut_line[UTL_OFF + left - 1] = '~'; diff --git a/kdm/backend/util.c b/kdm/backend/util.c index a5358cd65..c3e9a520c 100644 --- a/kdm/backend/util.c +++ b/kdm/backend/util.c @@ -409,9 +409,10 @@ setEnv( char **e, const char *name, const char *value ) char ** putEnv( const char *string, char **env ) { - char *b, *n; + char *n; + char *b; - if (!(b = strchr( string, '=' ))) + if (!(b = (char*)strchr( string, '=' ))) return NULL; if (!StrNDup( &n, string, b - string )) return NULL; diff --git a/kdm/backend/xdmcp.c b/kdm/backend/xdmcp.c index 2925a6bbc..e82305f89 100644 --- a/kdm/backend/xdmcp.c +++ b/kdm/backend/xdmcp.c @@ -386,7 +386,8 @@ NetworkAddressToName( CARD16 connectionType, ARRAY8Ptr connectionAddress, ASPrintf( &name, "localhost:%d", displayNumber ); else { if (removeDomainname) { - char *localDot, *remoteDot; + char *remoteDot; + char *localDot; /* check for a common domain name. This * could reduce names by recognising common @@ -394,8 +395,8 @@ NetworkAddressToName( CARD16 connectionType, ARRAY8Ptr connectionAddress, * this is as useful, and will confuse more * people */ - if ((localDot = strchr( localhost, '.' )) && - (remoteDot = strchr( hostname, '.' ))) + if ((localDot = (char*)strchr( localhost, '.' )) && + (remoteDot = (char*)strchr( hostname, '.' ))) { /* smash the name in place; it won't * be needed later. @@ -924,6 +925,9 @@ manage( struct sockaddr *from, int fromlen, int length, int fd ) } d->clientAddr = clientAddress; d->connectionType = connectionType; + d->remoteHost = NetworkAddressToHostname (pdpy->connectionType, + &pdpy->connectionAddress); + XdmcpDisposeARRAY8( &clientPort ); if (pdpy->fileAuthorization) { d->authorizations = (Xauth **)Malloc( sizeof(Xauth *) ); @@ -1048,7 +1052,8 @@ NetworkAddressToHostname( CARD16 connectionType, ARRAY8Ptr connectionAddress ) #endif { struct hostent *he; - char *myDot, *name, *lname; + char *name, *lname; + char *myDot; int af_type; #if defined(IPv6) && defined(AF_INET6) char dotted[INET6_ADDRSTRLEN]; @@ -1094,7 +1099,7 @@ NetworkAddressToHostname( CARD16 connectionType, ARRAY8Ptr connectionAddress ) oki: if (StrDup( &name, he->h_name ) && !strchr( name, '.' ) && - (myDot = strchr( localHostname(), '.' ))) + (myDot = (char*)strchr( localHostname(), '.' ))) { if (ASPrintf( &lname, "%s%s", name, myDot )) { #if defined(IPv6) && defined(AF_INET6) diff --git a/kdm/config.def b/kdm/config.def index ae026ba52..f8d1f1c87 100644 --- a/kdm/config.def +++ b/kdm/config.def @@ -42,16 +42,16 @@ # define HALT_CMD "/usr/sbin/halt" # define REBOOT_CMD "/usr/sbin/reboot" #else -# define HALT_CMD "/sbin/halt" +# define HALT_CMD "/sbin/poweroff" # define REBOOT_CMD "/sbin/reboot" #endif #if defined(BSD) || defined(__linux__) -# define DEF_USER_PATH "/usr/local/bin:/usr/bin:/bin:" XBINDIR ":/usr/games" -# define DEF_SYSTEM_PATH "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:" XBINDIR +# define DEF_USER_PATH "/usr/local/bin:/opt/kde3/bin:/usr/bin:/bin:/opt/kde3/games:/usr/games" +# define DEF_SYSTEM_PATH "/usr/local/sbin:/usr/local/bin:/opt/kde3/sbin:/usr/sbin:/opt/kde3/bin:/usr/bin:/sbin:/bin" #else -# define DEF_USER_PATH "/usr/local/bin:/usr/bin:/bin:" XBINDIR ":/usr/games:/usr/ucb" -# define DEF_SYSTEM_PATH "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:" XBINDIR ":/etc:/usr/ucb" +# define DEF_USER_PATH "/usr/local/bin:/opt/kde3/bin:/usr/bin:/bin:/opt/kde3/games:/usr/games:/usr/ucb" +# define DEF_SYSTEM_PATH "/usr/local/sbin:/usr/local/bin:/opt/kde3/sbin:/usr/sbin:/opt/kde3/bin:/usr/bin:/sbin:/bin:/etc:/usr/ucb" #endif #if 0 /*def HASXDMAUTH*/ @@ -91,6 +91,12 @@ <kdmrc> &kdm; master configuration file _ + Please note: Settings in this file are sometimes ignored (overridden). + The default KDM startup script /etc/init.d/kdm looks in /etc/default/kdm.d + for theme-related settings which, if found, take precedence. The possibly + overridden settings are: UseBackground, BackgroundCfg, UseTheme, Theme. + See /usr/share/doc/kdm/README.Debian for details + _ Definition: the greeter is the login dialog, i.e., the part of &kdm; which the user sees. _ @@ -1355,7 +1361,7 @@ Description: This string is subject to word splitting. </para><para> The default is something reasonable for the system on which &kdm; was built, - like <command>/usr/X11R6/bin/X</command>. + like <command>/usr/bin/X</command>. Key: ServerArgsLocal Type: string @@ -1921,10 +1927,10 @@ Description: Key: SessionsDirs Type: list -Default: KDMDATA "/sessions" +Default: "/usr/share/xsessions,/var/lib/menu-xdg/xsessions,/usr/share/apps/kdm/sessions" User: core User: greeter-c -Instance: #*/"/etc/X11/sessions,/usr/share/xsessions" +Instance: #*/"/usr/share/xsessions,/var/lib/menu-xdg/xsessions,/usr/share/apps/kdm/sessions" Comment: The directories containing session type definitions in .desktop format. Description: @@ -1948,7 +1954,7 @@ Description: Key: UseSessReg Type: bool -Default: true +Default: false User: core Instance: #*/! Comment: @@ -2044,9 +2050,9 @@ Description: Key: GreetString Type: string -Default: "Welcome to %s at %n" +Default: "Welcome to Kubuntu at %n" User: greeter -Instance: #*/"K Desktop Environment (%n)" +Instance: #*/"Welcome to Kubuntu at %n" Comment: The headline in the greeter. The following character pairs are replaced: - %d -> current display @@ -2096,19 +2102,19 @@ Description: # This needs to come _in front_ of the font settings to be effective! Key: AntiAliasing Type: bool -Default: false +Default: true User: greeter -Instance: #*/! +Instance: */ Comment: & Description: Whether the fonts used in the greeter should be antialiased. Key: GreetFont Type: string -Default: "Serif,20,5,0,50,0" +Default: "Sans Serif,22,5,0,50,0" CDefault: "Serif,20,bold" User: greeter:font -Instance: #*/"Serif,20,5,0,50,0" +Instance: #*/"Sans Serif,22,5,0,50,0" Comment: & Description: The font for the greeter headline. @@ -2482,7 +2488,6 @@ Type: int Default: 0 User: greeter Instance: #*/ -Update: upd_forgingseed Comment: Random seed for forging saved session types, etc. of unknown users. This value should be random but constant across the login domain. @@ -2579,7 +2584,7 @@ Key: AllowClose Type: bool Default: true User: greeter -Instance: :*/false +Instance: :*/true Comment: & Description: Show the <guilabel>Restart X Server</guilabel>/<guilabel>Close Connection</guilabel> action in the greeter. @@ -2608,7 +2613,7 @@ Key: Theme Type: string Default: "" User: greeter -Instance: */KDMDATA "/themes/circles" +Instance: */ "@@@ToBeReplacedByDesktopBase@@@" Comment: & Description: The theme to use for the greeter. Can point to either a directory or an XML diff --git a/kdm/configure.in.in b/kdm/configure.in.in index 4f3ff82d7..4b6972178 100644 --- a/kdm/configure.in.in +++ b/kdm/configure.in.in @@ -11,10 +11,10 @@ AC_CACHE_VAL(kde_cv_defines_imake, [ cat > Imakefile <<'EOF'[ acimake: - @echo "XBINDIR=\"$(BINDIR)\" XLIBDIR=\"$(LIBDIR)\"" + @echo "XBINDIR=\"/usr/bin\" XLIBDIR=\"$(LIBDIR)\"" ]EOF - if $XMKMF >&5 2>&1 && test -f Makefile; then + if imake -I/usr/lib/X11/config -DTOPDIR=/etc/X11 -DCURDIR=. /etc/X11 >&5 2>&1 && test -f Makefile; then kde_cv_defines_imake=`${MAKE-make} acimake 2> /dev/null | grep -v "^make"` kde_cv_defines_imake_version=$imkv else @@ -240,4 +240,51 @@ if test "x$with_kdm_xconsole" = xyes; then AC_DEFINE(WITH_KDM_XCONSOLE, 1, [Build kdm with built-in xconsole]) fi +########### Check for DBus + + AC_MSG_CHECKING(for DBus) + + dbus_inc=NOTFOUND + dbus_lib=NOTFOUND + dbus=NOTFOUND + + search_incs="$kde_includes $kde_extra_includes /usr/include /usr/include/dbus-1.0 /usr/local/include /usr/local/include/dbus-1.0" + AC_FIND_FILE(dbus/dbus.h, $search_incs, dbus_incdir) + + search_incs_arch_deps="$kde_includes $kde_extra_includes /usr/lib$kdelibsuff/dbus-1.0/include /usr/local/lib$kdelibsuff/dbus-1.0/include" + AC_FIND_FILE(dbus/dbus-arch-deps.h, $search_incs_arch_deps, dbus_incdir_arch_deps) + + if test -r $dbus_incdir/dbus/dbus.h && test -r $dbus_incdir_arch_deps/dbus/dbus-arch-deps.h ; then + DBUS_INCS="-I$dbus_incdir -I$dbus_incdir_arch_deps" + dbus_inc=FOUND + fi + + search_libs="$kde_libraries $kde_extra_libs /usr/lib$kdelibsuff /usr/local/lib$kdelibsuff" + AC_FIND_FILE(libdbus-1.so, $search_libs, dbus_libdir) + + if test -r $dbus_libdir/libdbus-1.so ; then + DBUS_LIBS="-L$dbus_libdir -ldbus-1" + dbus_lib=FOUND + fi + + if test $dbus_inc != FOUND || test $dbus_lib != FOUND ; then + KDE_PKG_CHECK_MODULES( DBUS, "dbus-1", [ DBUS_INCS=$DBUS_CFLAGS; dbus_inc=FOUND; dbus_lib=FOUND; ] , AC_MSG_RESULT( Nothing found on PKG_CONFIG_PATH ) ) + fi + + dbus_bus_var=`pkg-config --variable=system_bus_default_address dbus-1 2>/dev/null` + if test -z "$dbus_bus_var"; then + dbus_bus_var="unix:path=/var/run/dbus/system_bus_socket" + fi + AC_DEFINE_UNQUOTED(DBUS_SYSTEM_BUS, "$dbus_bus_var", [Define the unix domain path for dbus system bus]) + + if test $dbus_inc = FOUND && test $dbus_lib = FOUND ; then + AC_MSG_RESULT(headers $DBUS_INCS libraries $DBUS_LIBS) + dbus=FOUND + else + AC_MSG_RESULT(searched but not found) + fi + + AC_SUBST(DBUS_INCS) + AC_SUBST(DBUS_LIBS) + dnl AC_OUTPUT(kdm/kfrontend/sessions/kde.desktop) diff --git a/kdm/kfrontend/Makefile.am b/kdm/kfrontend/Makefile.am index 8f123509d..5c5dfd61a 100644 --- a/kdm/kfrontend/Makefile.am +++ b/kdm/kfrontend/Makefile.am @@ -1,5 +1,5 @@ # use 'make GENKDMCONF_FLAGS=... install' to override -GENKDMCONF_FLAGS = +GENKDMCONF_FLAGS = --no-old SUBDIRS = themer themes pics sessions diff --git a/kdm/kfrontend/genkdmconf.c b/kdm/kfrontend/genkdmconf.c index 5c0cb91e0..631561d17 100644 --- a/kdm/kfrontend/genkdmconf.c +++ b/kdm/kfrontend/genkdmconf.c @@ -322,7 +322,8 @@ static char * locate( const char *exe ) { int len; - char *path, *pathe, *name, *thenam, nambuf[PATH_MAX+1]; + char *path, *name, *thenam, nambuf[PATH_MAX+1]; + char *pathe; if (!(path = getenv( "PATH" ))) return 0; @@ -331,7 +332,7 @@ locate( const char *exe ) memcpy( name, exe, len + 1 ); *--name = '/'; do { - if (!(pathe = strchr( path, ':' ))) + if (!(pathe = (char*)strchr( path, ':' ))) pathe = path + strlen( path ); len = pathe - path; if (len && !(len == 1 && *path == '.')) { @@ -531,7 +532,7 @@ static const char def_xaccess[] = "# right hand sides can match.\n" "#\n" "\n" -"* #any host can get a login window\n" +"#* #any host can get a login window\n" "\n" "#\n" "# To hardwire a specific terminal to a specific host, you can\n" @@ -549,7 +550,7 @@ static const char def_xaccess[] = "# so this may not work in all environments.\n" "#\n" "\n" -"* CHOOSER BROADCAST #any indirect host can get a chooser\n" +"#* CHOOSER BROADCAST #any indirect host can get a chooser\n" "\n" "#\n" "# If you'd prefer to configure the set of hosts each terminal sees,\n" @@ -585,35 +586,25 @@ static const char def_startup[] = "#! /bin/sh\n" "# Xstartup - run as root before session starts\n" "\n" -"# By convention, both xconsole and xterm -C check that the\n" -"# console is owned by the invoking user and is readable before attaching\n" -"# the console output. This way a random user can invoke xterm -C without\n" -"# causing serious grief; still, it can cause havoc, so xconsole is started\n" -"# by Xsetup usually.\n" -"# This is not required if you use PAM with the pam_console module.\n" -"#\n" -"#chown $USER /dev/console\n" "\n" -#ifdef _AIX -"# We create a pseudodevice for finger. (host:0 becomes xdm/host_0)\n" -"# Without it, finger errors out with \"Can't stat /dev/host:0\".\n" -"#\n" -"#devname=`echo $DISPLAY | cut -c1-8`\n" -"#if [ ! -d /dev/xdm ]; then\n" -"# mkdir /dev/xdm\n" -"# chmod 755 /dev/xdm\n" -"#fi\n" -"#touch /dev/xdm/$devname\n" -"#chmod 644 /dev/xdm/$devname\n" -"#exec sessreg -a -l xdm/$devname -h \"`echo $DISPLAY | cut -d: -f1`\"" -#else -"#exec sessreg -a -l $DISPLAY -h \"`echo $DISPLAY | cut -d: -f1`\"" -# ifdef BSD -" -x " KDMCONF "/Xservers" -# endif -#endif /* _AIX */ -" $USER\n" -"\n# NOTE: The session is aborted if the last command returns non-zero.\n"; +"\n" +"if [ -e /etc/nologin ]; then\n" +" # always display the nologin message, if possible\n" +" if [ -s /etc/nologin ] && which xmessage > /dev/null 2>&1; then\n" +" xmessage -file /etc/nologin -geometry 640x480\n" +" fi\n" +" if [ \"$(id -u)\" != \"0\" ] && \\\n" +" ! grep -qs '^ignore-nologin' /etc/kde3/kdm/kdm.options; then\n" +" exit 1\n" +" fi\n" +"fi\n" +"\n" +"if grep -qs '^use-sessreg' /etc/kde3/kdm/kdm.options && \\\n" +" which sessreg > /dev/null 2>&1; then\n" +" exec sessreg -a -l \"$DISPLAY\" -u /var/run/utmp \\\n" +" -h \"`echo $DISPLAY | cut -d: -f1`\" \"$USER\"\n" +" # NOTREACHED\n" +"fi\n"; static const char def_reset[] = "#! /bin/sh\n" @@ -629,12 +620,13 @@ static const char def_reset[] = "#devname=`echo $DISPLAY | cut -c1-8`\n" "#exec sessreg -d -l xdm/$devname -h \"`echo $DISPLAY | cut -d: -f1`\"" #else -"#exec sessreg -d -l $DISPLAY -h \"`echo $DISPLAY | cut -d: -f1`\"" -# ifdef BSD -" -x " KDMCONF "/Xservers" -# endif +"if grep -qs '^use-sessreg' /etc/kde3/kdm/kdm.options && \\\n" +" which sessreg > /dev/null 2>&1; then\n" +" exec sessreg -d -l \"$DISPLAY\" -u /var/run/utmp \\\n" +" -h \"`echo $DISPLAY | cut -d: -f1`\" \"$USER\"\n" +" # NOTREACHED\n" +"fi\n"; #endif /* _AIX */ -" $USER\n"; static const char def_session1[] = "#! /bin/sh\n" @@ -666,6 +658,7 @@ static const char def_session1[] = " [ -f $zhome/.zprofile ] && . $zhome/.zprofile\n" " [ -f $zdir/zlogin ] && . $zdir/zlogin\n" " [ -f $zhome/.zlogin ] && . $zhome/.zlogin\n" +" setopt shwordsplit noextendedglob\n" " ;;\n" " */csh|*/tcsh)\n" " # [t]cshrc is always sourced automatically.\n" @@ -682,28 +675,8 @@ static const char def_session2[] = " [ -f $HOME/.profile ] && . $HOME/.profile\n" " ;;\n" "esac\n" -"\n" -"[ -f /etc/xprofile ] && . /etc/xprofile\n" -"[ -f $HOME/.xprofile ] && . $HOME/.xprofile\n" -"\n" -"case $session in\n" -" \"\")\n" -" exec xmessage -center -buttons OK:0 -default OK \"Sorry, $DESKTOP_SESSION is no valid session.\"\n" -" ;;\n" -" failsafe)\n" -" exec xterm -geometry 80x24-0-0\n" -" ;;\n" -" custom)\n" -" exec $HOME/.xsession\n" -" ;;\n" -" default)\n" -" exec " KDE_BINDIR "/startkde\n" -" ;;\n" -" *)\n" -" eval exec \"$session\"\n" -" ;;\n" -"esac\n" -"exec xmessage -center -buttons OK:0 -default OK \"Sorry, cannot execute $session. Check $DESKTOP_SESSION.desktop.\"\n"; +"# invoke global X session script\n" +". /etc/X11/Xsession\n"; static const char def_background[] = "[Desktop0]\n" @@ -978,29 +951,6 @@ getInitTab( void ) if (maxTTY) return; - if (readFile( &it, "/etc/inittab" )) { - usedFile( "/etc/inittab" ); - for (p = it.buf; p < it.eof; p = eol + 1) { - for (eol = p; eol < it.eof && *eol != '\n'; eol++); - if (*p != '#') { - if ((ep = mem_mem( p, eol - p, " tty", 4 )) && - ep < eol && isdigit( *ep )) - { - if (ep + 1 == eol || isspace( *(ep + 1) )) - tty = *ep - '0'; - else if (isdigit( *(ep + 1) ) && - (ep + 2 == eol || isspace( *(ep + 2) ))) - tty = (*ep - '0') * 10 + (*(ep + 1) - '0'); - else - continue; - TTYmask |= 1 << (tty - 1); - if (tty > maxTTY) - maxTTY = tty; - } - } - } - freeBuf( &it ); - } if (!maxTTY) { maxTTY = 6; TTYmask = 0x3f; @@ -1390,12 +1340,12 @@ mk_xaccess( Entry *ce, Section *cs ATTR_UNUSED ) static void mk_willing( Entry *ce, Section *cs ATTR_UNUSED ) { - const char *fname; + char *fname; if (!ce->active) /* there is only the Global one */ goto dflt; else { - if (!(fname = strchr( ce->value, '/' ))) + if (!(fname = (char*)strchr( ce->value, '/' ))) return; /* obviously in-line (or empty) */ if (old_scripts || inNewDir( fname )) dlinkfile( fname ); diff --git a/kdm/kfrontend/kdmctl.c b/kdm/kfrontend/kdmctl.c index 72e133162..82a12e653 100644 --- a/kdm/kfrontend/kdmctl.c +++ b/kdm/kfrontend/kdmctl.c @@ -219,7 +219,7 @@ main( int argc, char **argv ) fprintf( stderr, "Cannot create UNIX socket\n" ); return 1; } - if (dpy && (ptr = strchr( dpy, ':' )) && (ptr = strchr( ptr, '.' ))) + if (dpy && (ptr = (char*)strchr( dpy, ':' )) && (ptr = (char*)strchr( ptr, '.' ))) *ptr = 0; if (ctl && *ctl) { if (!openctl( fd, 1, ctl, dpy )) diff --git a/kdm/kfrontend/kdmshutdown.cpp b/kdm/kfrontend/kdmshutdown.cpp index dfd8558e2..74f62550e 100644 --- a/kdm/kfrontend/kdmshutdown.cpp +++ b/kdm/kfrontend/kdmshutdown.cpp @@ -34,6 +34,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include <kdialog.h> #include <kstandarddirs.h> #include <kuser.h> +#include <kconfig.h> +#include <kiconloader.h> #include <qcombobox.h> #include <qvbuttongroup.h> @@ -48,6 +50,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include <qlistview.h> #include <qheader.h> #include <qdatetime.h> +#include <qregexp.h> #define KDmh KDialog::marginHint() #define KDsh KDialog::spacingHint() @@ -459,76 +462,152 @@ void KDMDelayedPushButton::slotTimeout() setDown( false ); } - KDMSlimShutdown::KDMSlimShutdown( QWidget *_parent ) : inherited( _parent ) , targetList( 0 ) { - QHBoxLayout *hbox = new QHBoxLayout( this, KDmh, KDsh ); - - QFrame *lfrm = new QFrame( this ); - lfrm->setFrameStyle( QFrame::Panel | QFrame::Sunken ); - hbox->addWidget( lfrm, AlignCenter ); - QLabel *icon = new QLabel( lfrm ); - icon->setPixmap( QPixmap( locate( "data", "kdm/pics/shutdown.jpg" ) ) ); - QVBoxLayout *iconlay = new QVBoxLayout( lfrm ); - iconlay->addWidget( icon ); - - QVBoxLayout *buttonlay = new QVBoxLayout( hbox, KDsh ); - - buttonlay->addStretch( 1 ); - - KPushButton *btnHalt = new - KPushButton( KGuiItem( i18n("&Turn Off Computer"), "exit" ), this ); - buttonlay->addWidget( btnHalt ); - connect( btnHalt, SIGNAL(clicked()), SLOT(slotHalt()) ); - - buttonlay->addSpacing( KDialog::spacingHint() ); - KDMDelayedPushButton *btnReboot = new - KDMDelayedPushButton( KGuiItem( i18n("&Restart Computer"), "reload" ), this ); - buttonlay->addWidget( btnReboot ); - connect( btnReboot, SIGNAL(clicked()), SLOT(slotReboot()) ); + bool doUbuntuLogout = KConfigGroup(KGlobal::config(), "Shutdown").readBoolEntry("doUbuntuLogout", false); - GSet( 1 ); - GSendInt( G_ListBootOpts ); - if (GRecvInt() == BO_OK) { - targetList = GRecvStrArr( 0 ); - /*int def =*/ GRecvInt(); - int cur = GRecvInt(); - QPopupMenu *targets = new QPopupMenu( this ); - for (int i = 0; targetList[i]; i++) { - QString t( QString::fromLocal8Bit( targetList[i] ) ); - targets->insertItem( i == cur ? - i18n("current option in boot loader", - "%1 (current)").arg( t ) : - t, i ); + QVBoxLayout* vbox = new QVBoxLayout( this ); + QHBoxLayout *hbox = new QHBoxLayout( this, KDmh, KDsh ); + QFrame* lfrm = new QFrame( this ); + QHBoxLayout* hbuttonbox; + + if(doUbuntuLogout) + { + lfrm->setFrameStyle( QFrame::StyledPanel | QFrame::Raised ); + lfrm->setLineWidth( style().pixelMetric( QStyle::PM_DefaultFrameWidth, lfrm ) ); + // we need to set the minimum size for the logout box, since it + // gets too small if there isn't all options available + lfrm->setMinimumSize(300,120); + vbox->addWidget( lfrm ); + vbox = new QVBoxLayout( lfrm, 2 * KDialog::marginHint(), + 2 * KDialog::spacingHint() ); + + // first line of buttons + hbuttonbox = new QHBoxLayout( vbox, 8 * KDialog::spacingHint() ); + hbuttonbox->setAlignment( Qt::AlignHCenter ); + + // Reboot + FlatButton* btnReboot = new FlatButton( lfrm ); + btnReboot->setTextLabel( i18n("&Restart"), false ); + btnReboot->setPixmap( DesktopIcon( "reload") ); + int i = btnReboot->textLabel().find( QRegExp("\\&"), 0 ); // i == 1 + btnReboot->setAccel( "ALT+" + btnReboot->textLabel().lower()[i+1] ) ; + hbuttonbox->addWidget ( btnReboot); + connect(btnReboot, SIGNAL(clicked()), SLOT(slotReboot())); + + // Copied completely from the standard restart/shutdown dialog + GSet( 1 ); + GSendInt( G_ListBootOpts ); + if (GRecvInt() == BO_OK) { + targetList = GRecvStrArr( 0 ); + /*int def =*/ GRecvInt(); + int cur = GRecvInt(); + QPopupMenu *targets = new QPopupMenu( this ); + btnReboot->setPopupDelay(300); // visually add dropdown + for (int i = 0; targetList[i]; i++) { + QString t( QString::fromLocal8Bit( targetList[i] ) ); + targets->insertItem( i == cur ? + i18n("current option in boot loader", + "%1 (current)").arg( t ) : + t, i ); + } + btnReboot->setPopup( targets ); + connect( targets, SIGNAL(activated(int)), SLOT(slotReboot(int)) ); } - btnReboot->setPopup( targets ); - connect( targets, SIGNAL(activated(int)), SLOT(slotReboot(int)) ); + GSet( 0 ); + // Copied completely from the standard restart/shutdown dialog + + // Shutdown + FlatButton* btnHalt = new FlatButton( lfrm ); + btnHalt->setTextLabel( i18n("&Turn Off"), false ); + btnHalt->setPixmap( DesktopIcon( "exit") ); + i = btnHalt->textLabel().find( QRegExp("\\&"), 0 ); // i == 1 + btnHalt->setAccel( "ALT+" + btnHalt->textLabel().lower()[i+1] ) ; + hbuttonbox->addWidget ( btnHalt ); + connect(btnHalt, SIGNAL(clicked()), SLOT(slotHalt())); + + // cancel buttonbox + QHBoxLayout* hbuttonbox2 = new QHBoxLayout( vbox, 8 * KDialog::spacingHint() ); + hbuttonbox2->setAlignment( Qt::AlignRight ); + + // Back to kdm + KSMPushButton* btnBack = new KSMPushButton( KStdGuiItem::cancel(), lfrm ); + hbuttonbox2->addWidget( btnBack ); + connect(btnBack, SIGNAL(clicked()), SLOT(reject())); + + } - GSet( 0 ); - - buttonlay->addStretch( 1 ); - - if (_scheduledSd != SHUT_NEVER) { - KPushButton *btnSched = new - KPushButton( KGuiItem( i18n("&Schedule...") ), this ); - buttonlay->addWidget( btnSched ); - connect( btnSched, SIGNAL(clicked()), SLOT(slotSched()) ); - + else + { + lfrm->setFrameStyle( QFrame::Panel | QFrame::Sunken ); + hbox->addWidget( lfrm, AlignCenter ); + QLabel *icon = new QLabel( lfrm ); + icon->setPixmap( QPixmap( locate( "data", "kdm/pics/shutdown.jpg" ) ) ); + QVBoxLayout *iconlay = new QVBoxLayout( lfrm ); + iconlay->addWidget( icon ); + + QVBoxLayout *buttonlay = new QVBoxLayout( hbox, KDsh ); + + buttonlay->addStretch( 1 ); + + KPushButton *btnHalt = new + KPushButton( KGuiItem( i18n("&Turn Off Computer"), "exit" ), this ); + buttonlay->addWidget( btnHalt ); + connect( btnHalt, SIGNAL(clicked()), SLOT(slotHalt()) ); + + buttonlay->addSpacing( KDialog::spacingHint() ); + + KDMDelayedPushButton *btnReboot = new + KDMDelayedPushButton( KGuiItem( i18n("&Restart Computer"), "reload" ), this ); + buttonlay->addWidget( btnReboot ); + connect( btnReboot, SIGNAL(clicked()), SLOT(slotReboot()) ); + + GSet( 1 ); + GSendInt( G_ListBootOpts ); + if (GRecvInt() == BO_OK) { + targetList = GRecvStrArr( 0 ); + /*int def =*/ GRecvInt(); + int cur = GRecvInt(); + QPopupMenu *targets = new QPopupMenu( this ); + for (int i = 0; targetList[i]; i++) { + QString t( QString::fromLocal8Bit( targetList[i] ) ); + targets->insertItem( i == cur ? + i18n("current option in boot loader", + "%1 (current)").arg( t ) : + t, i ); + } + btnReboot->setPopup( targets ); + connect( targets, SIGNAL(activated(int)), SLOT(slotReboot(int)) ); + } + GSet( 0 ); + buttonlay->addStretch( 1 ); + + if (_scheduledSd != SHUT_NEVER) { + KPushButton *btnSched = new + KPushButton( KGuiItem( i18n("&Schedule...") ), this ); + buttonlay->addWidget( btnSched ); + connect( btnSched, SIGNAL(clicked()), SLOT(slotSched()) ); + + buttonlay->addStretch( 1 ); + } + + buttonlay->addWidget( new KSeparator( this ) ); + + buttonlay->addSpacing( 0 ); + + KPushButton *btnBack = new KPushButton( KStdGuiItem::cancel(), this ); + buttonlay->addWidget( btnBack ); + connect( btnBack, SIGNAL(clicked()), SLOT(reject()) ); + + buttonlay->addSpacing( KDialog::spacingHint() ); + + } - buttonlay->addWidget( new KSeparator( this ) ); - - buttonlay->addSpacing( 0 ); - - KPushButton *btnBack = new KPushButton( KStdGuiItem::cancel(), this ); - buttonlay->addWidget( btnBack ); - connect( btnBack, SIGNAL(clicked()), SLOT(reject()) ); - - buttonlay->addSpacing( KDialog::spacingHint() ); } KDMSlimShutdown::~KDMSlimShutdown() @@ -593,6 +672,129 @@ KDMSlimShutdown::externShutdown( int type, const char *os, int uid ) } +KSMPushButton::KSMPushButton( const KGuiItem &item, + QWidget *parent, + const char *name) + : KPushButton( item, parent, name), + m_pressed(false) +{ + setDefault( false ); + setAutoDefault ( false ); +} + +void KSMPushButton::keyPressEvent( QKeyEvent* e ) +{ + switch ( e->key() ) + { + case Key_Enter: + case Key_Return: + case Key_Space: + m_pressed = TRUE; + setDown(true); + emit pressed(); + break; + case Key_Escape: + e->ignore(); + break; + default: + e->ignore(); + } + + QPushButton::keyPressEvent(e); +} + + +void KSMPushButton::keyReleaseEvent( QKeyEvent* e ) +{ + switch ( e->key() ) + { + case Key_Space: + case Key_Enter: + case Key_Return: + if ( m_pressed ) + { + setDown(false); + m_pressed = FALSE; + emit released(); + emit clicked(); + } + break; + case Key_Escape: + e->ignore(); + break; + default: + e->ignore(); + + } +} + +FlatButton::FlatButton( QWidget *parent, const char *name ) + : QToolButton( parent, name/*, WNoAutoErase*/ ), + m_pressed(false) +{ + init(); +} + + +FlatButton::~FlatButton() {} + +void FlatButton::init() +{ + setUsesTextLabel(true); + setUsesBigPixmap(true); + setAutoRaise(true); + setTextPosition( QToolButton::Under ); + setFocusPolicy(QWidget::StrongFocus); + } + + +void FlatButton::keyPressEvent( QKeyEvent* e ) +{ + switch ( e->key() ) + { + case Key_Enter: + case Key_Return: + case Key_Space: + m_pressed = TRUE; + setDown(true); + emit pressed(); + break; + case Key_Escape: + e->ignore(); + break; + default: + e->ignore(); + } + + QToolButton::keyPressEvent(e); +} + +void FlatButton::keyReleaseEvent( QKeyEvent* e ) +{ + switch ( e->key() ) + { + case Key_Space: + case Key_Enter: + case Key_Return: + if ( m_pressed ) + { + setDown(false); + m_pressed = FALSE; + emit released(); + emit clicked(); + } + break; + case Key_Escape: + e->ignore(); + break; + default: + e->ignore(); + } + +} + + + KDMConfShutdown::KDMConfShutdown( int _uid, dpySpec *sess, int type, const char *os, QWidget *_parent ) : inherited( _uid, _parent ) diff --git a/kdm/kfrontend/kdmshutdown.h b/kdm/kfrontend/kdmshutdown.h index 9020b1513..98877fcbb 100644 --- a/kdm/kfrontend/kdmshutdown.h +++ b/kdm/kfrontend/kdmshutdown.h @@ -32,6 +32,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include <kpushbutton.h> #include <qradiobutton.h> +#include <qtoolbutton.h> +#include <qpixmap.h> class QLabel; class KPushButton; @@ -193,4 +195,46 @@ class KDMCancelShutdown : public KDMShutdownBase { const char *os, QWidget *_parent ); }; +class KSMPushButton : public KPushButton +{ + Q_OBJECT + +public: + + KSMPushButton( const KGuiItem &item, QWidget *parent, const char *name = 0 ); + +protected: + virtual void keyPressEvent(QKeyEvent*e); + virtual void keyReleaseEvent(QKeyEvent*e); + +private: + + bool m_pressed; + +}; + +class FlatButton : public QToolButton +{ + Q_OBJECT + + public: + + FlatButton( QWidget *parent = 0, const char *name = 0 ); + ~FlatButton(); + + protected: + virtual void keyPressEvent(QKeyEvent*e); + virtual void keyReleaseEvent(QKeyEvent*e); + + private slots: + + private: + void init(); + + bool m_pressed; + QString m_text; + QPixmap m_pixmap; + +}; + #endif /* KDMSHUTDOWN_H */ diff --git a/kdm/kfrontend/kgapp.cpp b/kdm/kfrontend/kgapp.cpp index 711853c37..a5bb667ef 100644 --- a/kdm/kfrontend/kgapp.cpp +++ b/kdm/kfrontend/kgapp.cpp @@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include <ksimpleconfig.h> #include <qtimer.h> +#include <qstring.h> #include <qcursor.h> #include <qpalette.h> @@ -124,6 +125,8 @@ xIOErr( Display * ) exit( EX_RESERVER_DPY ); } +//KSimpleConfig *iccconfig; + void kg_main( const char *argv0 ) { @@ -141,6 +144,17 @@ kg_main( const char *argv0 ) if (!_GUIStyle.isEmpty()) app.setStyle( _GUIStyle ); + // Load up the systemwide ICC profile + QString iccConfigFile = QString(KDE_CONFDIR); + iccConfigFile += "/kicc/kiccconfigrc"; + KSimpleConfig iccconfig(iccConfigFile, true); + if (iccconfig.readBoolEntry("EnableICC", false) == true) { + QString iccCommand = QString("/usr/bin/xcalib "); + iccCommand += iccconfig.readEntry("ICCFile"); + iccCommand += QString(" &"); + system(iccCommand.ascii()); + } + _colorScheme = locate( "data", "kdisplay/color-schemes/" + _colorScheme + ".kcsrc" ); if (!_colorScheme.isEmpty()) { KSimpleConfig config( _colorScheme, true ); diff --git a/kdm/kfrontend/kgreeter.cpp b/kdm/kfrontend/kgreeter.cpp index 574f4e340..407b3d879 100644 --- a/kdm/kfrontend/kgreeter.cpp +++ b/kdm/kfrontend/kgreeter.cpp @@ -55,6 +55,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include <qpushbutton.h> #include <qtooltip.h> #include <qaccel.h> +#include <qstring.h> #include <qeventloop.h> #include <pwd.h> @@ -173,6 +174,13 @@ void KGreeter::insertUser( const QImage &default_pix, const QString &username, struct passwd *ps ) { + if (setegid( ps->pw_gid )) + return; + if (seteuid( ps->pw_uid )) { + setegid(0); + return; + } + if (userList) userList->append( username ); if (!userView) @@ -236,6 +244,9 @@ KGreeter::insertUser( const QImage &default_pix, realname.append( "\n" ).append( username ); new UserListViewItem( userView, realname, QPixmap( p ), username ); } + + seteuid( 0 ); + setegid( 0 ); } class KCStringList : public QValueList<QCString> { @@ -282,15 +293,8 @@ KGreeter::insertUsers() { struct passwd *ps; - // XXX remove seteuid-voodoo when we run as nobody if (!(ps = getpwnam( "nobody" ))) return; - if (setegid( ps->pw_gid )) - return; - if (seteuid( ps->pw_uid )) { - setegid(0); - return; - } QImage default_pix; if (userView) { @@ -354,17 +358,12 @@ KGreeter::insertUsers() if (userList) userList->sort(); } - - // XXX remove seteuid-voodoo when we run as nobody - seteuid( 0 ); - setegid( 0 ); } void KGreeter::putSession( const QString &type, const QString &name, bool hid, const char *exe ) { int prio = exe ? (!strcmp( exe, "default" ) ? 0 : - !strcmp( exe, "custom" ) ? 1 : !strcmp( exe, "failsafe" ) ? 3 : 2) : 2; for (uint i = 0; i < sessionTypes.size(); i++) if (sessionTypes[i].type == type) { @@ -392,7 +391,6 @@ KGreeter::insertSessions() } } putSession( "default", i18n("Default"), false, "default" ); - putSession( "custom", i18n("Custom"), false, "custom" ); putSession( "failsafe", i18n("Failsafe"), false, "failsafe" ); qBubbleSort( sessionTypes ); for (uint i = 0; i < sessionTypes.size() && !sessionTypes[i].hid; i++) { @@ -610,7 +608,6 @@ KGreeter::verifySetUser( const QString &user ) slotUserEntered(); } - KStdGreeter::KStdGreeter() : KGreeter() , clock( 0 ) diff --git a/kdm/kfrontend/sessions/kde.desktop.in b/kdm/kfrontend/sessions/kde.desktop.in index b032d395a..cf91472ae 100644 --- a/kdm/kfrontend/sessions/kde.desktop.in +++ b/kdm/kfrontend/sessions/kde.desktop.in @@ -3,7 +3,7 @@ Encoding=UTF-8 Type=XSession Exec=@KDE_BINDIR@/startkde TryExec=@KDE_BINDIR@/startkde -Name=KDE +Name=KDE3 Name[hi]=केडीई Name[mn]=КДЭ Name[ta]=Kஏற்றக் காவலன் diff --git a/kdm/kfrontend/sessions/matchbox.desktop b/kdm/kfrontend/sessions/matchbox.desktop index 8c6e2fd52..3bec343b0 100644 --- a/kdm/kfrontend/sessions/matchbox.desktop +++ b/kdm/kfrontend/sessions/matchbox.desktop @@ -1,7 +1,7 @@ [Desktop Entry] Type=XSession -Exec=matchbox -TryExec=matchbox +Exec=matchbox-window-manager +TryExec=matchbox-window-manager Name=Matchbox Name[bn]=ম্যাচবক্স Name[eo]=Alumetujo diff --git a/kdm/kfrontend/sessions/olvwm.desktop b/kdm/kfrontend/sessions/olvwm.desktop index e181331bc..23dee1169 100644 --- a/kdm/kfrontend/sessions/olvwm.desktop +++ b/kdm/kfrontend/sessions/olvwm.desktop @@ -1,7 +1,7 @@ [Desktop Entry] Type=XSession -Exec= -TryExec= +Exec=olvwm-x-window-manager +TryExec=olvwm-x-window-manager Name=OLVWM Name[br]=OVLWM Name[eo]=OLVFA diff --git a/kdm/kfrontend/sessions/olwm.desktop b/kdm/kfrontend/sessions/olwm.desktop index e3368af74..32612eaa3 100644 --- a/kdm/kfrontend/sessions/olwm.desktop +++ b/kdm/kfrontend/sessions/olwm.desktop @@ -1,7 +1,7 @@ [Desktop Entry] Type=XSession -Exec=olwm -TryExec=olwm +Exec=olwm-x-window-manager +TryExec=olwm-x-window-manager Name=OLWM Name[eo]=OLFA Name[hi]=ओएलडबल्यूएम diff --git a/kdm/kfrontend/sessions/pwm.desktop b/kdm/kfrontend/sessions/pwm.desktop index 036c9bff4..5d967c0c0 100644 --- a/kdm/kfrontend/sessions/pwm.desktop +++ b/kdm/kfrontend/sessions/pwm.desktop @@ -1,7 +1,7 @@ [Desktop Entry] Type=XSession -Exec=pwm -TryExec=pwm +Exec=pwm1 +TryExec=pwm1 Name=PWM Name[eo]=UnuFA Name[hi]=पीडबल्यूएम diff --git a/kdm/kfrontend/sessions/ude.desktop b/kdm/kfrontend/sessions/ude.desktop index fb451da1a..108a493e4 100644 --- a/kdm/kfrontend/sessions/ude.desktop +++ b/kdm/kfrontend/sessions/ude.desktop @@ -1,7 +1,7 @@ [Desktop Entry] Type=XSession -Exec=ude -TryExec=ude +Exec=uwm +TryExec=uwm Name=UDE Name[eo]=ULĈ Name[hi]=यूडीई diff --git a/kdmlib/dmctl.cpp b/kdmlib/dmctl.cpp index 4475ae1e7..cd20ee4ab 100644 --- a/kdmlib/dmctl.cpp +++ b/kdmlib/dmctl.cpp @@ -42,7 +42,7 @@ static const char *ctl, *dpy; DM::DM() : fd( -1 ) { - const char *ptr; + char *ptr; struct sockaddr_un sa; if (DMType == Dunno) { @@ -77,8 +77,8 @@ DM::DM() : fd( -1 ) } GDMAuthenticate(); } else { - if ((ptr = strchr( dpy, ':' ))) - ptr = strchr( ptr, '.' ); + if ((ptr = (char*)strchr( dpy, ':' ))) + ptr = (char*)strchr( ptr, '.' ); snprintf( sa.sun_path, sizeof(sa.sun_path), "%s/dmctl-%.*s/socket", ctl, ptr ? int(ptr - dpy) : 512, dpy ); diff --git a/kfind/kquery.cpp b/kfind/kquery.cpp index 5d5446fc6..92b867567 100644 --- a/kfind/kquery.cpp +++ b/kfind/kquery.cpp @@ -372,11 +372,16 @@ void KQuery::processQuery( KFileItem* file) } else { - if (str.find(m_context, 0, m_casesensitive) != -1) - { - matchingLine=QString::number(matchingLineNumber)+": "+str; - found = true; - break; + if ((!str.isNull()) && (!m_context.isNull())) { + if (str.find(m_context, 0, m_casesensitive) != -1) + { + matchingLine=QString::number(matchingLineNumber)+": "+str; + found = true; + break; + } + } + else { + return; } } kapp->processEvents(); diff --git a/khelpcenter/searchhandlers/khc_docbookdig.pl.in b/khelpcenter/searchhandlers/khc_docbookdig.pl.in index 63f787515..e49df688d 100755 --- a/khelpcenter/searchhandlers/khc_docbookdig.pl.in +++ b/khelpcenter/searchhandlers/khc_docbookdig.pl.in @@ -26,10 +26,12 @@ use strict; use Getopt::Long; -my $htdigdata = "/srv/www/htdig/common/"; +my $htdigdata = "/etc/htdig"; my $htdigbin = "/usr/bin"; my $kdeprefix = "@prefix@"; +my $kdehtmldir = `kde-config --expandvars --install html`; chomp $kdeprefix; +chomp $kdehtmldir; my $dbg = 1; @@ -89,7 +91,7 @@ $ENV{ PATH } = '/bin:/usr/bin'; $ENV{ CDPATH } = ''; $ENV{ ENV } = ''; -my $findpath = "$kdeprefix/share/doc/HTML/$lang/"; +my $findpath = "$kdehtmldir/$lang/"; my $findcmd = "find $findpath -name index.docbook"; print STDERR "FINDCMD: $findcmd\n"; @@ -132,15 +134,15 @@ mime=\$1 shift if test "\$#" -gt 0; then - orig=\${1/file:\\//} + orig=\${1#file:/} shift fi case "\$orig" in help:/*) - orig=\${orig/help:\\//} - orig=\${orig/\/index.docbook/} - cd $kdeprefix/share/doc/HTML/en/\$orig + orig=\${orig#help:/} + orig=\${orig%\/index.docbook} + cd $kdehtmldir/en/\$orig file=index.docbook ;; *) @@ -167,7 +169,7 @@ common_dir: $commondir locale: $locale database_dir: $htdigdb database_base: \${database_dir}/$identifier -local_urls: help://=$kdeprefix/share/doc/HTML/en/ file://=/ +local_urls: help://=$kdehtmldir/en/ file://=/ local_urls_only: true limit_urls_to: file:// help:/ ignore_noindex: true diff --git a/khelpcenter/searchhandlers/khc_htdig.pl.in b/khelpcenter/searchhandlers/khc_htdig.pl.in index 909d53fd1..a9eb25de6 100755 --- a/khelpcenter/searchhandlers/khc_htdig.pl.in +++ b/khelpcenter/searchhandlers/khc_htdig.pl.in @@ -26,7 +26,7 @@ use strict; use Getopt::Long; -my $htdigdata = "/srv/www/htdig/common/"; +my $htdigdata = "/etc/htdig"; my $htdigbin = "/usr/bin"; my $kdeprefix = "@prefix@"; chomp $kdeprefix; diff --git a/khelpcenter/searchhandlers/khc_htsearch.pl b/khelpcenter/searchhandlers/khc_htsearch.pl index 451e858dd..b7ea694b3 100755 --- a/khelpcenter/searchhandlers/khc_htsearch.pl +++ b/khelpcenter/searchhandlers/khc_htsearch.pl @@ -8,7 +8,7 @@ use Getopt::Long; use open IO => ':utf8'; use open ':std'; -my $htsearchpath="/srv/www/cgi-bin/htsearch"; +my $htsearchpath="/usr/lib/cgi-bin/htsearch"; my $config; my $format; @@ -42,7 +42,7 @@ my $charset = langCharset( $lang ); $words = encode( $charset, $words ); if ( !open( HTSEARCH, "-|", "$htsearchpath", "-c", "$indexdir/$config.conf", - "format=$format&method=$method&words=$words" ) ) + "format=$format&method=$method&words=$words&matchesperpage=$maxnum&exclude=[index.html]" ) ) { print "Can't execute htsearch at '$htsearchpath'.\n"; exit 1; diff --git a/khotkeys/data/printscreen.khotkeys b/khotkeys/data/printscreen.khotkeys index c56638fc5..66af14462 100644 --- a/khotkeys/data/printscreen.khotkeys +++ b/khotkeys/data/printscreen.khotkeys @@ -34,7 +34,7 @@ Comment[sv]=Gruppen innehåller åtgärder som normalt är förinställda. Comment[uk]=Ця група містить типові налаштовані дії. Comment[wa]=Ci groupe a des accions ki sont prémetowes. Comment[zh_TW]=此群組包含了預先設定好的動作。 -DataCount=1 +DataCount=2 Enabled=true Name=Preset Actions Name[bg]=Фиксирани действия @@ -193,6 +193,31 @@ TriggersCount=1 Key=Print Type=SHORTCUT +[Data_1_2] +Comment=Launches KSnapShot in window capture mode when ALT+PrintScrn is pressed.\n +Enabled=true +Name=PrintWindow +Type=COMMAND_URL_SHORTCUT_ACTION_DATA + +[Data_1_2Actions] +ActionsCount=1 + +[Data_1_2Actions0] +CommandURL=ksnapshot -c +Type=COMMAND_URL + +[Data_1_2Conditions] +Comment= +ConditionsCount=0 + +[Data_1_2Triggers] +Comment=Simple_action +TriggersCount=1 + +[Data_1_2Triggers0] +Key=Alt+Print +Type=SHORTCUT + [Main] Version=2 ImportId=printscreen diff --git a/kicker/applets/media/mediumbutton.cpp b/kicker/applets/media/mediumbutton.cpp index 2c96601ea..e8007a989 100644 --- a/kicker/applets/media/mediumbutton.cpp +++ b/kicker/applets/media/mediumbutton.cpp @@ -123,7 +123,7 @@ void MediumButton::refreshType() { KMimeType::Ptr mime = mFileItem.determineMimeType(); QToolTip::add(this, mime->comment()); - setIcon(mime->icon(QString::null, false)); + setIcon(mFileItem.iconName()); } // Activate this code only if we find a way to have both an diff --git a/kicker/applets/minipager/pagerapplet.cpp b/kicker/applets/minipager/pagerapplet.cpp index 3ba87c0b1..6cc000562 100644 --- a/kicker/applets/minipager/pagerapplet.cpp +++ b/kicker/applets/minipager/pagerapplet.cpp @@ -136,6 +136,7 @@ KMiniPager::KMiniPager(const QString& configFile, Type type, int actions, connect( m_kwin, SIGNAL( currentDesktopViewportChanged(int, const QPoint&)), SLOT(slotSetDesktopViewport(int, const QPoint&))); connect( m_kwin, SIGNAL( numberOfDesktopsChanged(int)), SLOT( slotSetDesktopCount(int) ) ); + connect( m_kwin, SIGNAL( desktopGeometryChanged(int)), SLOT( slotRefreshViewportCount(int) ) ); connect( m_kwin, SIGNAL( activeWindowChanged(WId)), SLOT( slotActiveWindowChanged(WId) ) ); connect( m_kwin, SIGNAL( windowAdded(WId) ), this, SLOT( slotWindowAdded(WId) ) ); connect( m_kwin, SIGNAL( windowRemoved(WId) ), this, SLOT( slotWindowRemoved(WId) ) ); @@ -513,6 +514,28 @@ void KMiniPager::slotSetDesktopCount( int ) updateLayout(); } +void KMiniPager::slotRefreshViewportCount( int ) +{ + QValueList<KMiniPagerButton*>::ConstIterator it; + QValueList<KMiniPagerButton*>::ConstIterator itEnd = m_desktops.end(); + for( it = m_desktops.begin(); it != itEnd; ++it ) + { + delete (*it); + } + m_desktops.clear(); + + drawButtons(); + + m_curDesk = m_kwin->currentDesktop(); + if ( m_curDesk == 0 ) + { + m_curDesk = 1; + } + + resizeEvent(0); + updateLayout(); +} + void KMiniPager::slotActiveWindowChanged( WId win ) { if (desktopPreview()) @@ -715,8 +738,10 @@ void KMiniPager::aboutToShowContextMenu() PagerSettings::EnumBackgroundType::BgPlain + bgOffset); showMenu->insertItem(i18n("&Transparent"), PagerSettings::EnumBackgroundType::BgTransparent + bgOffset); - showMenu->insertItem(i18n("&Desktop Wallpaper"), + if (m_useViewports == false) { + showMenu->insertItem(i18n("&Desktop Wallpaper"), PagerSettings::EnumBackgroundType::BgLive + bgOffset); + } connect(showMenu, SIGNAL(activated(int)), SLOT(contextMenuActivated(int))); m_contextMenu->insertItem(i18n("&Pager Options"),showMenu); @@ -795,12 +820,17 @@ void KMiniPager::contextMenuActivated(int result) break; case PagerSettings::EnumBackgroundType::BgLive + bgOffset: { - m_settings->setBackgroundType(PagerSettings::EnumBackgroundType::BgLive); - QValueList<KMiniPagerButton*>::ConstIterator it; - QValueList<KMiniPagerButton*>::ConstIterator itEnd = m_desktops.end(); - for( it = m_desktops.begin(); it != itEnd; ++it ) - { - (*it)->backgroundChanged(); + if (m_useViewports == true) { + m_settings->setBackgroundType(PagerSettings::EnumBackgroundType::BgLive); + QValueList<KMiniPagerButton*>::ConstIterator it; + QValueList<KMiniPagerButton*>::ConstIterator itEnd = m_desktops.end(); + for( it = m_desktops.begin(); it != itEnd; ++it ) + { + (*it)->backgroundChanged(); + } + } + else { + m_settings->setBackgroundType(PagerSettings::EnumBackgroundType::BgTransparent); } break; } diff --git a/kicker/applets/minipager/pagerapplet.h b/kicker/applets/minipager/pagerapplet.h index f47b0411d..d96ba83f7 100644 --- a/kicker/applets/minipager/pagerapplet.h +++ b/kicker/applets/minipager/pagerapplet.h @@ -84,6 +84,7 @@ public slots: void slotSetDesktop(int desktop); void slotSetDesktopViewport(int desktop, const QPoint& viewport); void slotSetDesktopCount(int count); + void slotRefreshViewportCount(int currentDesktop); void slotButtonSelected(int desk ); void slotActiveWindowChanged( WId win ); void slotWindowAdded( WId ); diff --git a/kicker/kicker/buttons/kbutton.cpp b/kicker/kicker/buttons/kbutton.cpp index 071d15981..320a45842 100644 --- a/kicker/kicker/buttons/kbutton.cpp +++ b/kicker/kicker/buttons/kbutton.cpp @@ -45,7 +45,9 @@ KButton::KButton( QWidget* parent ) setPopup(MenuManager::the()->kmenu()); MenuManager::the()->registerKButton(this); + setIcon("kmenu"); + setIcon(KickerSettings::customKMenuIcon()); if (KickerSettings::showKMenuText()) { diff --git a/kicker/libkicker/kickerSettings.kcfg b/kicker/libkicker/kickerSettings.kcfg index 42f02bcad..7e6f76366 100644 --- a/kicker/libkicker/kickerSettings.kcfg +++ b/kicker/libkicker/kickerSettings.kcfg @@ -275,6 +275,11 @@ <default code="true">i18n("Applications")</default> </entry> +<entry name="CustomKMenuIcon" key="CustomIcon" type="Path" > + <label>Custom K Menu Button Icon</label> + <default code="true">QString("kmenu")</default> + </entry> + </group> <group name="buttons" > diff --git a/kicker/libkicker/panelbutton.cpp b/kicker/libkicker/panelbutton.cpp index f53d4b38f..407a78ca6 100644 --- a/kicker/libkicker/panelbutton.cpp +++ b/kicker/libkicker/panelbutton.cpp @@ -29,6 +29,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <qstyle.h> #include <qstylesheet.h> #include <qtooltip.h> +#include <qpixmap.h> #include <kapplication.h> #include <kconfig.h> @@ -39,6 +40,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <kglobalsettings.h> #include <kiconloader.h> #include <kicontheme.h> +#include <kiconeffect.h> #include <kipc.h> #include <kstandarddirs.h> #include <klocale.h> @@ -289,10 +291,11 @@ int PanelButton::widthForHeight(int height) const if (orientation() == Horizontal && !m_buttonText.isEmpty()) { QFont f(font()); - f.setPixelSize(KMIN(height, KMAX(int(float(height) * m_fontPercent), 16))); + //f.setPixelSize(KMIN(height, KMAX(int(float(height) * m_fontPercent), 16))); QFontMetrics fm(f); - rc += fm.width(m_buttonText) + KMIN(25, KMAX(5, fm.width('m') / 2)); + //rc += fm.width(m_buttonText) + KMIN(25, KMAX(5, fm.width('m') / 2)); + rc += fm.width(m_buttonText); } return rc; @@ -348,7 +351,7 @@ bool PanelButton::hasText() const void PanelButton::setButtonText(const QString& text) { - m_buttonText = text; + m_buttonText = " " + text; update(); } @@ -489,6 +492,9 @@ void PanelButton::mouseReleaseEvent(QMouseEvent *e) if (e->button() == LeftButton) { m_isLeftMouseButtonDown = false; + + QPixmap pix = labelIcon(); + KIconEffect::visualActivate(this, this->geometry(), &pix); } QButton::mouseReleaseEvent(e); } @@ -569,7 +575,7 @@ void PanelButton::drawButtonLabel(QPainter *p) { fontPercent *= .8; } - f.setPixelSize(KMIN(h, KMAX(int(float(h) * m_fontPercent), 16))); + //f.setPixelSize(KMIN(h, KMAX(int(float(h) * m_fontPercent), 16))); QFontMetrics fm(f); p->setFont(f); diff --git a/kicker/menuext/recentdocs/recentdocsmenu.cpp b/kicker/menuext/recentdocs/recentdocsmenu.cpp index 98357fe52..06c84d7a6 100644 --- a/kicker/menuext/recentdocs/recentdocsmenu.cpp +++ b/kicker/menuext/recentdocs/recentdocsmenu.cpp @@ -22,6 +22,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #include <qdragobject.h> +#include <qstring.h> +#include <qstringlist.h> #include <kglobal.h> #include <kiconloader.h> @@ -50,8 +52,7 @@ RecentDocsMenu::~RecentDocsMenu() void RecentDocsMenu::initialize() { if (initialized()) clear(); - insertItem(SmallIconSet("history_clear"), i18n("Clear History"), - this, SLOT(slotClearHistory())); + insertItem(SmallIconSet("history_clear"), i18n("Clear History"), this, SLOT(slotClearHistory())); insertSeparator(); _fileList = KRecentDocument::recentDocuments(); @@ -60,17 +61,30 @@ void RecentDocsMenu::initialize() { insertItem(i18n("No Entries"), 0); setItemEnabled(0, false); return; - } + } int id = 0; - - for (QStringList::ConstIterator it = _fileList.begin(); - it != _fileList.end(); - ++it) - { + char alreadyPresentInMenu; + QStringList previousEntries; + for (QStringList::ConstIterator it = _fileList.begin(); it != _fileList.end(); ++it) { KDesktopFile f(*it, true /* read only */); - insertItem(SmallIconSet(f.readIcon()), f.readName().replace('&', QString::fromAscii("&&") ), id++); - } + + // Make sure this entry is not already present in the menu + alreadyPresentInMenu = 0; + for ( QStringList::Iterator previt = previousEntries.begin(); previt != previousEntries.end(); ++previt ) { + if (QString::localeAwareCompare(*previt, f.readName().replace('&', QString::fromAscii("&&") )) == 0) { + alreadyPresentInMenu = 1; + } + } + + if (alreadyPresentInMenu == 0) { + // Add item to menu + insertItem(SmallIconSet(f.readIcon()), f.readName().replace('&', QString::fromAscii("&&") ), id++); + + // Append to duplicate checking list + previousEntries.append(f.readName().replace('&', QString::fromAscii("&&") )); + } + } setInitialized(true); } diff --git a/kicker/taskbar/taskbar.cpp b/kicker/taskbar/taskbar.cpp index 8c5bb73c1..c2580f5f1 100644 --- a/kicker/taskbar/taskbar.cpp +++ b/kicker/taskbar/taskbar.cpp @@ -241,9 +241,9 @@ void TaskBar::configure() m_showOnlyIconified = TaskBarSettings::showOnlyIconified(); m_currentScreen = -1; // Show all screens or re-get our screen - m_showOnlyCurrentScreen = TaskBarSettings::showCurrentScreenOnly() && + m_showOnlyCurrentScreen = (TaskBarSettings::showCurrentScreenOnly() && QApplication::desktop()->isVirtualDesktop() && - QApplication::desktop()->numScreens() > 1; + QApplication::desktop()->numScreens() > 1) || (QApplication::desktop()->numScreens() < 2); // we need to watch geometry issues if we aren't showing windows when we // are paying attention to the current Xinerama screen diff --git a/kioslave/fish/Makefile.am b/kioslave/fish/Makefile.am index 27308245b..444d037fb 100644 --- a/kioslave/fish/Makefile.am +++ b/kioslave/fish/Makefile.am @@ -4,8 +4,8 @@ INCLUDES = $(all_includes) AM_LDFLAGS = $(all_libraries) $(KDE_RPATH) kio_fish_la_SOURCES = fish.cpp -kio_fish_la_LIBADD = $(LIB_KSYCOCA) #$(LIBUTIL) -kio_fish_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +kio_fish_la_LIBADD = $(LIB_KSYCOCA) $(LIBUTIL) +kio_fish_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -lutil noinst_HEADERS = fishcode.h fish.h EXTRA_DIST = AUTHORS COPYING ChangeLog INSTALL README TODO FAQ fish.pl diff --git a/kioslave/man/kio_man.cpp b/kioslave/man/kio_man.cpp index 0511a165d..068287b7e 100644 --- a/kioslave/man/kio_man.cpp +++ b/kioslave/man/kio_man.cpp @@ -517,6 +517,11 @@ void MANProtocol::slotGetStdOutput(KProcess* /* p */, char *s, int len) myStdStream += QString::fromLocal8Bit(s, len); } +void MANProtocol::slotGetStdOutputUtf8(KProcess* /* p */, char *s, int len) +{ + myStdStream += QString::fromUtf8(s, len); +} + char *MANProtocol::readManPage(const char *_filename) { QCString filename = _filename; @@ -564,24 +569,20 @@ char *MANProtocol::readManPage(const char *_filename) } lastdir = filename.left(filename.findRev('/')); - QIODevice *fd= KFilterDev::deviceForFile(filename); - - if ( !fd || !fd->open(IO_ReadOnly)) - { - delete fd; - return 0; - } - QByteArray array(fd->readAll()); - kdDebug(7107) << "read " << array.size() << endl; - fd->close(); - delete fd; - - if (array.isEmpty()) - return 0; - - const int len = array.size(); + myStdStream = QString::null; + KProcess proc; + /* TODO: detect availability of 'man --recode' so that this can go + * upstream */ + proc << "man" << "--recode" << "UTF-8" << filename; + + QApplication::connect(&proc, SIGNAL(receivedStdout (KProcess *, char *, int)), + this, SLOT(slotGetStdOutputUtf8(KProcess *, char *, int))); + proc.start(KProcess::Block, KProcess::All); + + const QCString cstr=myStdStream.utf8(); + const int len = cstr.size()-1; buf = new char[len + 4]; - qmemmove(buf + 1, array.data(), len); + qmemmove(buf + 1, cstr.data(), len); buf[0]=buf[len]='\n'; // Start and end with a end of line buf[len+1]=buf[len+2]='\0'; // Two NUL characters at end } diff --git a/kioslave/man/kio_man.h b/kioslave/man/kio_man.h index f571082db..d1d924ce0 100644 --- a/kioslave/man/kio_man.h +++ b/kioslave/man/kio_man.h @@ -61,6 +61,7 @@ public: private slots: void slotGetStdOutput(KProcess*, char*, int); + void slotGetStdOutputUtf8(KProcess*, char*, int); private: void checkManPaths(); diff --git a/kioslave/man/man2html.cpp b/kioslave/man/man2html.cpp index 725fba36a..b502e8edc 100644 --- a/kioslave/man/man2html.cpp +++ b/kioslave/man/man2html.cpp @@ -705,17 +705,18 @@ static void add_links(char *c) } int i,j,nr; - char *f, *g,*h; + char *f, *h; + char *g; const int numtests=6; // Nmber of tests char *idtest[numtests]; // url, mailto, www, ftp, manpage, C header file bool ok; /* search for (section) */ nr=0; idtest[0]=strstr(c+1,"://"); - idtest[1]=strchr(c+1,'@'); + idtest[1]=(char*)strchr(c+1,'@'); idtest[2]=strstr(c,"www."); idtest[3]=strstr(c,"ftp."); - idtest[4]=strchr(c+1,'('); + idtest[4]=(char*)strchr(c+1,'('); idtest[5]=strstr(c+1,".h>"); for (i=0; i<numtests; ++i) nr += (idtest[i]!=NULL); while (nr) { @@ -770,7 +771,7 @@ static void add_links(char *c) case 4: /* manpage */ f=idtest[j]; /* check section */ - g=strchr(f,')'); + g=(char*)strchr(f,')'); // The character before f must alphanumeric, the end of a HTML tag or the end of a if (g!=NULL && f>c && (g-f)<12 && (isalnum(f[-1]) || f[-1]=='>' || ( f[-1] == ';' ) ) && isdigit(f[1]) && f[1]!='0' && ((g-f)<=2 || isalpha(f[2]))) @@ -936,10 +937,10 @@ static void add_links(char *c) } nr=0; if (idtest[0] && idtest[0]<=c) idtest[0]=strstr(c+1,"://"); - if (idtest[1] && idtest[1]<=c) idtest[1]=strchr(c+1,'@'); + if (idtest[1] && idtest[1]<=c) idtest[1]=(char*)strchr(c+1,'@'); if (idtest[2] && idtest[2]<c) idtest[2]=strstr(c,"www."); if (idtest[3] && idtest[3]<c) idtest[3]=strstr(c,"ftp."); - if (idtest[4] && idtest[4]<=c) idtest[4]=strchr(c+1,'('); + if (idtest[4] && idtest[4]<=c) idtest[4]=(char*)strchr(c+1,'('); if (idtest[5] && idtest[5]<=c) idtest[5]=strstr(c+1,".h>"); for (i=0; i<numtests; i++) nr += (idtest[i]!=NULL); } @@ -3714,8 +3715,8 @@ static char *scan_request(char *c) char* font[2] = { "B", "R" }; c+=j; if (*c=='\n') c++; - char *eol=strchr(c,'\n'); - char *semicolon=strchr(c,';'); + char *eol=(char*)strchr(c,'\n'); + char *semicolon=(char*)strchr(c,';'); if ((semicolon!=0) && (semicolon<eol)) *semicolon=' '; sl=fill_words(c, wordlist, &words, true, &c); @@ -4338,7 +4339,7 @@ static char *scan_request(char *c) case REQ_Bl: // mdoc(7) "Begin List" { char list_options[NULL_TERMINATED(MED_STR_MAX)]; - char *nl = strchr(c,'\n'); + char *nl = (char*)strchr(c,'\n'); c=c+j; if (dl_set[itemdepth]) /* These things can nest. */ @@ -4519,7 +4520,7 @@ static char *scan_request(char *c) case REQ_Bd: /* mdoc(7) */ { /* Seems like a kind of example/literal mode */ char bd_options[NULL_TERMINATED(MED_STR_MAX)]; - char *nl = strchr(c,'\n'); + char *nl = (char*)strchr(c,'\n'); c=c+j; if (nl) strlimitcpy(bd_options, c, nl - c, MED_STR_MAX); @@ -4877,8 +4878,8 @@ static char *scan_request(char *c) } else if (!mandoc_name_count) { - const char *nextbreak = strchr(c, '\n'); - const char *nextspace = strchr(c, ' '); + char *nextbreak = (char*)strchr(c, '\n'); + char *nextspace = (char*)strchr(c, ' '); if (nextspace < nextbreak) nextbreak = nextspace; diff --git a/kioslave/media/kfile-plugin/kfile_media.desktop b/kioslave/media/kfile-plugin/kfile_media.desktop index 474ab12b2..c29d590e3 100644 --- a/kioslave/media/kfile-plugin/kfile_media.desktop +++ b/kioslave/media/kfile-plugin/kfile_media.desktop @@ -72,4 +72,4 @@ Name[zh_CN]=介质信息 Name[zh_TW]=媒體資訊 ServiceTypes=KFilePlugin X-KDE-Library=kfile_media -MimeType=media/audiocd;media/hdd_mounted;media/blankcd;media/hdd_unmounted;media/blankdvd;media/cdrom_mounted;media/cdrom_unmounted;media/cdwriter_mounted;media/nfs_mounted;media/cdwriter_unmounted;media/nfs_unmounted;media/removable_mounted;media/dvd_mounted;media/removable_unmounted;media/dvd_unmounted;media/smb_mounted;media/dvdvideo;media/smb_unmounted;media/floppy5_mounted;media/svcd;media/floppy5_unmounted;media/vcd;media/floppy_mounted;media/zip_mounted;media/floppy_unmounted;media/zip_unmounted;media/gphoto2camera;media/camera_mounted;media/camera_unmounted +MimeType=media/audiocd;media/hdd_mounted;media/hdd_mounted_decrypted;media/blankcd;media/hdd_unmounted;media/hdd_unmounted_decrypted;media/blankdvd;media/cdrom_mounted;media/cdrom_mounted_decrypted;media/cdrom_unmounted;media/cdrom_unmounted_decrypted;media/cdwriter_mounted;media/cdwriter_mounted_decrypted;media/nfs_mounted;media/cdwriter_unmounted;media/cdwriter_unmounted_decrypted;media/nfs_unmounted;media/removable_mounted;media/removable_mounted_decrypted;media/dvd_mounted;media/dvd_mounted_decrypted;media/removable_unmounted;media/removable_unmounted_decrypted;media/dvd_unmounted;media/dvd_unmounted_decrypted;media/smb_mounted;media/dvdvideo;media/smb_unmounted;media/floppy5_mounted;media/svcd;media/floppy5_unmounted;media/vcd;media/floppy_mounted;media/zip_mounted;media/floppy_unmounted;media/zip_unmounted;media/gphoto2camera;media/camera_mounted;media/camera_unmounted diff --git a/kioslave/media/kfile-plugin/kfilemediaplugin.cpp b/kioslave/media/kfile-plugin/kfilemediaplugin.cpp index c91dbf21a..37aa7d61f 100644 --- a/kioslave/media/kfile-plugin/kfilemediaplugin.cpp +++ b/kioslave/media/kfile-plugin/kfilemediaplugin.cpp @@ -47,19 +47,29 @@ KFileMediaPlugin::KFileMediaPlugin(QObject *parent, const char *name, { addMimeType( "media/audiocd" ); addMimeType( "media/hdd_mounted" ); + addMimeType( "media/hdd_mounted_decrypted" ); addMimeType( "media/blankcd" ); addMimeType( "media/hdd_unmounted" ); + addMimeType( "media/hdd_unmounted_decrypted" ); addMimeType( "media/blankdvd" ); addMimeType( "media/cdrom_mounted" ); + addMimeType( "media/cdrom_mounted_decrypted" ); addMimeType( "media/cdrom_unmounted" ); + addMimeType( "media/cdrom_unmounted_decrypted" ); addMimeType( "media/cdwriter_mounted" ); + addMimeType( "media/cdwriter_mounted_decrypted" ); addMimeType( "media/nfs_mounted" ); addMimeType( "media/cdwriter_unmounted" ); + addMimeType( "media/cdwriter_unmounted_decrypted" ); addMimeType( "media/nfs_unmounted" ); addMimeType( "media/removable_mounted" ); + addMimeType( "media/removable_mounted_decrypted" ); addMimeType( "media/dvd_mounted" ); + addMimeType( "media/dvd_mounted_decrypted" ); addMimeType( "media/removable_unmounted" ); + addMimeType( "media/removable_unmounted_decrypted" ); addMimeType( "media/dvd_unmounted" ); + addMimeType( "media/dvd_unmounted_decrypted" ); addMimeType( "media/smb_mounted" ); addMimeType( "media/dvdvideo" ); addMimeType( "media/smb_unmounted" ); diff --git a/kioslave/media/libmediacommon/medium.cpp b/kioslave/media/libmediacommon/medium.cpp index 5767a6c9a..4cba32aeb 100644 --- a/kioslave/media/libmediacommon/medium.cpp +++ b/kioslave/media/libmediacommon/medium.cpp @@ -38,6 +38,8 @@ Medium::Medium(const QString &id, const QString &name) m_properties+= QString::null; /* BASE_URL */ m_properties+= QString::null; /* MIME_TYPE */ m_properties+= QString::null; /* ICON_NAME */ + m_properties+= "false"; /* ENCRYPTED */ + m_properties+= QString::null; /* CLEAR_DEVICE_UDI */ loadUserLabel(); @@ -59,6 +61,8 @@ Medium::Medium() m_properties+= QString::null; /* BASE_URL */ m_properties+= QString::null; /* MIME_TYPE */ m_properties+= QString::null; /* ICON_NAME */ + m_properties+= QString::null; /* ENCRYPTED */ + m_properties+= QString::null; /* CLEAR_DEVICE_UDI */ m_halmounted = false; } @@ -82,6 +86,8 @@ const Medium Medium::create(const QStringList &properties) m.m_properties[BASE_URL] = properties[BASE_URL]; m.m_properties[MIME_TYPE] = properties[MIME_TYPE]; m.m_properties[ICON_NAME] = properties[ICON_NAME]; + m.m_properties[ENCRYPTED] = properties[ENCRYPTED]; + m.m_properties[CLEAR_DEVICE_UDI] = properties[CLEAR_DEVICE_UDI]; } return m; @@ -123,6 +129,11 @@ void Medium::setLabel(const QString &label) m_properties[LABEL] = label; } +void Medium::setEncrypted(bool state) +{ + m_properties[ENCRYPTED] = ( state ? "true" : "false" ); +} + void Medium::setUserLabel(const QString &label) { KConfig cfg("mediamanagerrc"); @@ -185,6 +196,19 @@ void Medium::mountableState(const QString &deviceNode, m_properties[MOUNTED] = ( mounted ? "true" : "false" ); } +void Medium::mountableState(const QString &deviceNode, + const QString &clearDeviceUdi, + const QString &mountPoint, + const QString &fsType, bool mounted) +{ + m_properties[MOUNTABLE] = "true"; + m_properties[DEVICE_NODE] = deviceNode; + m_properties[CLEAR_DEVICE_UDI] = clearDeviceUdi; + m_properties[MOUNT_POINT] = mountPoint; + m_properties[FS_TYPE] = fsType; + m_properties[MOUNTED] = ( mounted ? "true" : "false" ); +} + void Medium::unmountableState(const QString &baseURL) { m_properties[MOUNTABLE] = "false"; @@ -206,6 +230,11 @@ bool Medium::needMounting() const return isMountable() && !isMounted(); } +bool Medium::needDecryption() const +{ + return isEncrypted() && clearDeviceUdi().isEmpty(); +} + KURL Medium::prettyBaseURL() const { if ( !baseURL().isEmpty() ) diff --git a/kioslave/media/libmediacommon/medium.h b/kioslave/media/libmediacommon/medium.h index f94545e8e..543bdf596 100644 --- a/kioslave/media/libmediacommon/medium.h +++ b/kioslave/media/libmediacommon/medium.h @@ -41,7 +41,9 @@ public: static const uint BASE_URL = 9; static const uint MIME_TYPE = 10; static const uint ICON_NAME = 11; - static const uint PROPERTIES_COUNT = 12; + static const uint ENCRYPTED = 12; + static const uint CLEAR_DEVICE_UDI = 13; + static const uint PROPERTIES_COUNT = 14; static const QString SEPARATOR; Medium(const QString &id, const QString &name); @@ -62,19 +64,27 @@ public: QString baseURL() const { return m_properties[BASE_URL]; } QString mimeType() const { return m_properties[MIME_TYPE]; } QString iconName() const { return m_properties[ICON_NAME]; } + bool isEncrypted() const { return m_properties[ENCRYPTED]=="true"; }; + QString clearDeviceUdi() const { return m_properties[CLEAR_DEVICE_UDI]; }; bool needMounting() const; + bool needDecryption() const; KURL prettyBaseURL() const; QString prettyLabel() const; void setName(const QString &name); void setLabel(const QString &label); void setUserLabel(const QString &label); + void setEncrypted(bool state); bool mountableState(bool mounted); void mountableState(const QString &deviceNode, const QString &mountPoint, const QString &fsType, bool mounted); + void mountableState(const QString &deviceNode, + const QString &clearDeviceUdi, + const QString &mountPoint, + const QString &fsType, bool mounted); void unmountableState(const QString &baseURL = QString::null); void setMimeType(const QString &mimeType); diff --git a/kioslave/media/libmediacommon/notifieropenaction.cpp b/kioslave/media/libmediacommon/notifieropenaction.cpp index 82db14b97..2cf664cc6 100644 --- a/kioslave/media/libmediacommon/notifieropenaction.cpp +++ b/kioslave/media/libmediacommon/notifieropenaction.cpp @@ -40,6 +40,6 @@ void NotifierOpenAction::execute(KFileItem &medium) bool NotifierOpenAction::supportsMimetype( const QString &mimetype ) const { - return !mimetype.contains( "blank" ); + return !mimetype.contains( "blank" ) && !mimetype.contains( "encrypted" ); } diff --git a/kioslave/media/libmediacommon/notifiersettings.cpp b/kioslave/media/libmediacommon/notifiersettings.cpp index c7ad616a5..c7ba40e85 100644 --- a/kioslave/media/libmediacommon/notifiersettings.cpp +++ b/kioslave/media/libmediacommon/notifiersettings.cpp @@ -32,16 +32,28 @@ NotifierSettings::NotifierSettings() { m_supportedMimetypes.append( "media/removable_unmounted" ); + m_supportedMimetypes.append( "media/removable_unmounted_encrypted" ); + m_supportedMimetypes.append( "media/removable_unmounted_decrypted" ); m_supportedMimetypes.append( "media/removable_mounted" ); + m_supportedMimetypes.append( "media/removable_mounted_decrypted" ); m_supportedMimetypes.append( "media/camera_unmounted" ); m_supportedMimetypes.append( "media/camera_mounted" ); m_supportedMimetypes.append( "media/gphoto2camera" ); m_supportedMimetypes.append( "media/cdrom_unmounted" ); + m_supportedMimetypes.append( "media/cdrom_unmounted_encrypted" ); + m_supportedMimetypes.append( "media/cdrom_unmounted_decrypted" ); m_supportedMimetypes.append( "media/cdrom_mounted" ); + m_supportedMimetypes.append( "media/cdrom_mounted_decrypted" ); m_supportedMimetypes.append( "media/dvd_unmounted" ); + m_supportedMimetypes.append( "media/dvd_unmounted_encrypted" ); + m_supportedMimetypes.append( "media/dvd_unmounted_decrypted" ); m_supportedMimetypes.append( "media/dvd_mounted" ); + m_supportedMimetypes.append( "media/dvd_mounted_decrypted" ); m_supportedMimetypes.append( "media/cdwriter_unmounted" ); + m_supportedMimetypes.append( "media/cdwriter_unmounted_encrypted" ); + m_supportedMimetypes.append( "media/cdwriter_unmounted_decrypted" ); m_supportedMimetypes.append( "media/cdwriter_mounted" ); + m_supportedMimetypes.append( "media/cdwriter_mounted_decrypted" ); m_supportedMimetypes.append( "media/blankcd" ); m_supportedMimetypes.append( "media/blankdvd" ); m_supportedMimetypes.append( "media/audiocd" ); diff --git a/kioslave/media/mediaimpl.cpp b/kioslave/media/mediaimpl.cpp index 741227cdb..516bcdb01 100644 --- a/kioslave/media/mediaimpl.cpp +++ b/kioslave/media/mediaimpl.cpp @@ -226,6 +226,13 @@ bool MediaImpl::ensureMediumMounted(Medium &medium) m_lastErrorMessage = i18n("No such medium."); return false; } + + if ( medium.isEncrypted() && medium.clearDeviceUdi().isEmpty() ) + { + m_lastErrorCode = KIO::ERR_COULD_NOT_MOUNT; + m_lastErrorMessage = i18n("The drive is encrypted."); + return false; + } if ( medium.needMounting() ) { diff --git a/kioslave/media/mediamanager/halbackend.cpp b/kioslave/media/mediamanager/halbackend.cpp index 65c796605..4d6d9b19d 100644 --- a/kioslave/media/mediamanager/halbackend.cpp +++ b/kioslave/media/mediamanager/halbackend.cpp @@ -20,8 +20,10 @@ #include "linuxcdpolling.h" #include <stdlib.h> +#include <locale.h> #include <kapplication.h> +#include <kmessagebox.h> #include <qeventloop.h> #include <qfile.h> #include <klocale.h> @@ -33,9 +35,17 @@ #include <kmountpoint.h> #include <kmessagebox.h> #include <kio/job.h> +#include <kstandarddirs.h> +#include <kprocess.h> -#define MOUNT_SUFFIX (libhal_volume_is_mounted(halVolume) ? QString("_mounted") : QString("_unmounted")) -#define MOUNT_ICON_SUFFIX (libhal_volume_is_mounted(halVolume) ? QString("_mount") : QString("_unmount")) +#define MOUNT_SUFFIX ( \ + (medium->isMounted() ? QString("_mounted") : QString("_unmounted")) + \ + (medium->isEncrypted() ? (halClearVolume ? "_decrypted" : "_encrypted") : "" ) \ + ) +#define MOUNT_ICON_SUFFIX ( \ + (medium->isMounted() ? QString("_mount") : QString("_unmount")) + \ + (medium->isEncrypted() ? (halClearVolume ? "_decrypt" : "_encrypt") : "" ) \ + ) /* Static instance of this class, for static HAL callbacks */ static HALBackend* s_HALBackend; @@ -211,8 +221,15 @@ void HALBackend::AddDevice(const char *udi, bool allowNotification) /* Add volume block devices */ if (libhal_device_query_capability(m_halContext, udi, "volume", NULL)) { - /* We only list volume that have a filesystem or volume that have an audio track*/ - if ( libhal_device_get_property_QString(m_halContext, udi, "volume.fsusage") != "filesystem" && + /* We only list volumes that... + * - are encrypted with LUKS or + * - have a filesystem or + * - have an audio track + */ + if ( ( libhal_device_get_property_QString(m_halContext, udi, "volume.fsusage") != "crypto" || + libhal_device_get_property_QString(m_halContext, udi, "volume.fstype") != "crypto_LUKS" + ) && + libhal_device_get_property_QString(m_halContext, udi, "volume.fsusage") != "filesystem" && !libhal_device_get_property_bool(m_halContext, udi, "volume.disc.has_audio", NULL) && !libhal_device_get_property_bool(m_halContext, udi, "volume.disc.is_blank", NULL) ) return; @@ -232,6 +249,21 @@ void HALBackend::AddDevice(const char *udi, bool allowNotification) /** @todo check exclusion list **/ + /* Special handling for clear crypto volumes */ + LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, udi); + if (!halVolume) + return; + const char* backingVolumeUdi = libhal_volume_crypto_get_backing_volume_udi(halVolume); + if ( backingVolumeUdi != NULL ) + { + /* The crypto drive was unlocked and may now be mounted... */ + kdDebug(1219) << "HALBackend::AddDevice : ClearVolume appeared for " << backingVolumeUdi << endl; + ResetProperties(backingVolumeUdi, allowNotification); + libhal_volume_free(halVolume); + return; + } + libhal_volume_free(halVolume); + /* Create medium */ Medium* medium = new Medium(udi, ""); setVolumeProperties(medium); @@ -247,6 +279,11 @@ void HALBackend::AddDevice(const char *udi, bool allowNotification) return; } } + + // instert medium into list + m_mediaList.addMedium(medium, allowNotification); + + // finally check for automount QMap<QString,QString> options = MediaManagerUtils::splitOptions(mountoptions(udi)); kdDebug() << "automount " << options["automount"] << endl; if (options["automount"] == "true" && allowNotification ) { @@ -254,7 +291,6 @@ void HALBackend::AddDevice(const char *udi, bool allowNotification) if (!error.isEmpty()) kdDebug() << "error " << error << endl; } - m_mediaList.addMedium(medium, allowNotification); return; } @@ -295,11 +331,18 @@ void HALBackend::AddDevice(const char *udi, bool allowNotification) void HALBackend::RemoveDevice(const char *udi) { - m_mediaList.removeMedium(udi, true); + const Medium *medium = m_mediaList.findByClearUdi(udi); + if (medium) { + ResetProperties(medium->id().ascii()); + } else { + m_mediaList.removeMedium(udi, true); + } } void HALBackend::ModifyDevice(const char *udi, const char* key) { + kdDebug(1219) << "HALBackend::ModifyDevice for '" << udi << "' on '" << key << "'\n"; + const char* mediumUdi = findMediumUdiFromUdi(udi); if (!mediumUdi) return; @@ -381,6 +424,18 @@ const char* HALBackend::findMediumUdiFromUdi(const char* udi) if (libhal_device_property_exists(m_halContext, udi, "info.capabilities", NULL)) if (libhal_device_query_capability(m_halContext, udi, "volume", NULL)) { + /* check if this belongs to an encrypted volume */ + LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, udi); + if (!halVolume) return NULL; + const char* backingUdi = libhal_volume_crypto_get_backing_volume_udi(halVolume); + if (backingUdi != NULL) { + const char* result = findMediumUdiFromUdi(backingUdi); + libhal_volume_free(halVolume); + return result; + } + libhal_volume_free(halVolume); + + /* this is a volume whose drive is registered */ QString driveUdi = libhal_device_get_property_QString(m_halContext, udi, "block.storage_device"); return findMediumUdiFromUdi(driveUdi.ascii()); } @@ -445,11 +500,47 @@ void HALBackend::setVolumeProperties(Medium* medium) medium->setName( generateName(libhal_volume_get_device_file(halVolume)) ); - medium->mountableState( - libhal_volume_get_device_file(halVolume), /* Device node */ - libhal_volume_get_mount_point(halVolume), /* Mount point */ - libhal_volume_get_fstype(halVolume), /* Filesystem type */ - libhal_volume_is_mounted(halVolume) ); /* Mounted ? */ + LibHalVolume* halClearVolume = NULL; + if ( libhal_device_get_property_QString(m_halContext, udi, "volume.fsusage") == "crypto" ) + { + kdDebug(1219) << "HALBackend::setVolumeProperties : crypto volume" << endl; + + medium->setEncrypted(true); + char* clearUdi = libhal_volume_crypto_get_clear_volume_udi(m_halContext, halVolume); + QString clearUdiString; + if (clearUdi != NULL) { + kdDebug(1219) << "HALBackend::setVolumeProperties : crypto clear volume avail - " << clearUdi << endl; + halClearVolume = libhal_volume_from_udi(m_halContext, clearUdi); + // ignore if halClearVolume is NULL -> just not decrypted in this case + clearUdiString = clearUdi; + libhal_free_string(clearUdi); + } + + if (halClearVolume) + medium->mountableState( + libhal_volume_get_device_file(halVolume), /* Device node */ + clearUdiString, + libhal_volume_get_mount_point(halClearVolume), /* Mount point */ + libhal_volume_get_fstype(halClearVolume), /* Filesystem type */ + libhal_volume_is_mounted(halClearVolume) ); /* Mounted ? */ + else + medium->mountableState( + libhal_volume_get_device_file(halVolume), /* Device node */ + QString::null, + QString::null, /* Mount point */ + QString::null, /* Filesystem type */ + false ); /* Mounted ? */ + } + else + { + kdDebug(1219) << "HALBackend::setVolumeProperties : normal volume" << endl; + medium->mountableState( + libhal_volume_get_device_file(halVolume), /* Device node */ + libhal_volume_get_mount_point(halVolume), /* Mount point */ + libhal_volume_get_fstype(halVolume), /* Filesystem type */ + libhal_volume_is_mounted(halVolume) ); /* Mounted ? */ + } + char* name = libhal_volume_policy_compute_display_name(halDrive, halVolume, m_halStoragePolicy); QString volume_name = QString::fromUtf8(name); @@ -777,13 +868,35 @@ void HALBackend::hal_device_condition(LibHalContext *ctx, const char *udi, QStringList HALBackend::mountoptions(const QString &name) { const Medium* medium = m_mediaList.findById(name); - if (medium && !isInFstab(medium).isNull()) + if (!medium) + return QStringList(); // we don't know about that one + if (!isInFstab(medium).isNull()) return QStringList(); // not handled by HAL - fstab entry + QString volume_udi = name; + if (medium->isEncrypted()) { + // see if we have a clear volume + LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, medium->id().latin1()); + if (halVolume) { + char* clearUdi = libhal_volume_crypto_get_clear_volume_udi(m_halContext, halVolume); + if (clearUdi != NULL) { + volume_udi = clearUdi; + libhal_free_string(clearUdi); + } else { + // if not decrypted yet then no mountoptions + return QStringList(); + } + libhal_volume_free(halVolume); + } else { + // strange... + return QStringList(); + } + } + KConfig config("mediamanagerrc"); config.setGroup(name); - char ** array = libhal_device_get_property_strlist(m_halContext, name.latin1(), "volume.mount.valid_options", NULL); + char ** array = libhal_device_get_property_strlist(m_halContext, volume_udi.latin1(), "volume.mount.valid_options", NULL); QMap<QString,bool> valids; for (int index = 0; array && array[index]; ++index) { @@ -797,11 +910,11 @@ QStringList HALBackend::mountoptions(const QString &name) QStringList result; QString tmp; - QString fstype = libhal_device_get_property_QString(m_halContext, name.latin1(), "volume.fstype"); + QString fstype = libhal_device_get_property_QString(m_halContext, volume_udi.latin1(), "volume.fstype"); if (fstype.isNull()) - fstype = libhal_device_get_property_QString(m_halContext, name.latin1(), "volume.policy.mount_filesystem"); + fstype = libhal_device_get_property_QString(m_halContext, volume_udi.latin1(), "volume.policy.mount_filesystem"); - QString drive_udi = libhal_device_get_property_QString(m_halContext, name.latin1(), "block.storage_device"); + QString drive_udi = libhal_device_get_property_QString(m_halContext, volume_udi.latin1(), "block.storage_device"); bool removable = false; if ( !drive_udi.isNull() ) @@ -812,11 +925,11 @@ QStringList HALBackend::mountoptions(const QString &name) bool value = config.readBoolEntry("automount", false); config.setGroup(name); - if (libhal_device_get_property_bool(m_halContext, name.latin1(), "volume.disc.is_blank", NULL) - || libhal_device_get_property_bool(m_halContext, name.latin1(), "volume.disc.is_vcd", NULL) - || libhal_device_get_property_bool(m_halContext, name.latin1(), "volume.disc.is_svcd", NULL) - || libhal_device_get_property_bool(m_halContext, name.latin1(), "volume.disc.is_videodvd", NULL) - || libhal_device_get_property_bool(m_halContext, name.latin1(), "volume.disc.has_audio", NULL)) + if (libhal_device_get_property_bool(m_halContext, volume_udi.latin1(), "volume.disc.is_blank", NULL) + || libhal_device_get_property_bool(m_halContext, volume_udi.latin1(), "volume.disc.is_vcd", NULL) + || libhal_device_get_property_bool(m_halContext, volume_udi.latin1(), "volume.disc.is_svcd", NULL) + || libhal_device_get_property_bool(m_halContext, volume_udi.latin1(), "volume.disc.is_videodvd", NULL) + || libhal_device_get_property_bool(m_halContext, volume_udi.latin1(), "volume.disc.has_audio", NULL)) value = false; result << QString("automount=%1").arg(value ? "true" : "false"); @@ -898,9 +1011,9 @@ QStringList HALBackend::mountoptions(const QString &name) result << tmp; } - QString mount_point = libhal_device_get_property_QString(m_halContext, name.latin1(), "volume.mount_point"); + QString mount_point = libhal_device_get_property_QString(m_halContext, volume_udi.latin1(), "volume.mount_point"); if (mount_point.isEmpty()) - mount_point = libhal_device_get_property_QString(m_halContext, name.latin1(), "volume.policy.desired_mount_point"); + mount_point = libhal_device_get_property_QString(m_halContext, volume_udi.latin1(), "volume.policy.desired_mount_point"); mount_point = config.readEntry("mountpoint", mount_point); @@ -958,6 +1071,120 @@ bool HALBackend::setMountoptions(const QString &name, const QStringList &options return true; } +QString startKdeSudoProcess(const QString& kdesudoPath, const QString& command, + const QString& dialogCaption, const QString& dialogComment) +{ + KProcess kdesudoProcess; + + kdesudoProcess << kdesudoPath + << "-d" + << "--noignorebutton" + << "--caption" << dialogCaption + << "--comment" << dialogComment + << "-c" << command; + + // @todo handle kdesudo output + kdesudoProcess.start(KProcess::Block); + + return QString(); +} + +QString startKdeSuProcess(const QString& kdesuPath, const QString& command, + const QString& dialogCaption) +{ + KProcess kdesuProcess; + + kdesuProcess << kdesuPath + << "-d" + << "--noignorebutton" + << "--caption" << dialogCaption + << "-c" << command; + + // @todo handle kdesu output + kdesuProcess.start(KProcess::Block); + + return QString(); +} + +QString startPrivilegedProcess(const QString& command, const QString& dialogCaption, const QString& dialogComment) +{ + QString error; + + QString kdesudoPath = KStandardDirs::findExe("kdesudo"); + + if (!kdesudoPath.isEmpty()) + error = startKdeSudoProcess(kdesudoPath, command, dialogCaption, dialogComment); + else { + QString kdesuPath = KStandardDirs::findExe("kdesu"); + + if (!kdesuPath.isEmpty()) + error = startKdeSuProcess(kdesuPath, command, dialogCaption); + } + + return error; +} + +QString privilegedMount(const char* udi, const char* mountPoint, const char** options, int numberOfOptions) +{ + QString error; + + kdDebug() << "run privileged mount for " << udi << endl; + + QString dbusSendPath = KStandardDirs::findExe("dbus-send"); + + // @todo return error message + if (dbusSendPath.isEmpty()) + return QString(); + + QString mountOptions; + QTextOStream optionsStream(&mountOptions); + for (int optionIndex = 0; optionIndex < numberOfOptions; optionIndex++) { + optionsStream << options[optionIndex]; + if (optionIndex < numberOfOptions - 1) + optionsStream << ","; + } + + QString command; + QTextOStream(&command) << dbusSendPath + << " --system --print-reply --dest=org.freedesktop.Hal " << udi + << " org.freedesktop.Hal.Device.Volume.Mount string:" << mountPoint + << " string: array:string:" << mountOptions; + + kdDebug() << "command: " << command << endl; + + error = startPrivilegedProcess(command, + i18n("Authenticate"), + i18n("<big><b>System policy prevents mounting internal media</b></big><br/>Authentication is required to perform this action. Please enter your password to verify.")); + + return error; +} + +QString privilegedUnmount(const char* udi) +{ + QString error; + + kdDebug() << "run privileged unmount for " << udi << endl; + + QString dbusSendPath = KStandardDirs::findExe("dbus-send"); + + // @todo return error message + if (dbusSendPath.isEmpty()) + return QString(); + + QString command; + QTextOStream(&command) << dbusSendPath + << " --system --print-reply --dest=org.freedesktop.Hal " << udi + << " org.freedesktop.Hal.Device.Volume.Unmount array:string:force"; + + kdDebug() << "command: " << command << endl; + + error = startPrivilegedProcess(command, + i18n("Authenticate"), + i18n("<big><b>System policy prevents unmounting media mounted by other users</b></big><br/>Authentication is required to perform this action. Please enter your password to verify.")); + + return error; +} + static QString mount_priv(const char *udi, const char *mount_point, const char **poptions, int noptions, DBusConnection *dbus_connection) { @@ -992,6 +1219,8 @@ static QString mount_priv(const char *udi, const char *mount_point, const char * qerror = i18n("Invalid filesystem type"); else if ( !strcmp(error.name, "org.freedesktop.Hal.Device.Volume.PermissionDenied")) qerror = i18n("Permissions denied"); + else if ( !strcmp(error.name, "org.freedesktop.Hal.Device.PermissionDeniedByPolicy")) + qerror = privilegedMount(udi, mount_point, poptions, noptions); else if ( !strcmp(error.name, "org.freedesktop.Hal.Device.Volume.AlreadyMounted")) qerror = i18n("Device is already mounted."); else if ( !strcmp(error.name, "org.freedesktop.Hal.Device.Volume.InvalidMountpoint") && strlen(mount_point)) { @@ -1050,6 +1279,41 @@ QString HALBackend::listUsingProcesses(const Medium* medium) } } +QString HALBackend::killUsingProcesses(const Medium* medium) +{ + QString proclist, fullmsg; + QString cmdline = QString("/usr/bin/env fuser -vmk %1 2>&1").arg(KProcess::quote(medium->mountPoint())); + FILE *fuser = popen(cmdline.latin1(), "r"); + + uint counter = 0; + if (fuser) { + proclist += "<pre>"; + QTextIStream is(fuser); + QString tmp; + while (!is.atEnd()) { + tmp = is.readLine(); + tmp = QStyleSheet::escape(tmp) + "\n"; + + proclist += tmp; + if (counter++ > 10) + { + proclist += "..."; + break; + } + } + proclist += "</pre>"; + (void)pclose( fuser ); + } + if (counter) { + fullmsg = i18n("Programs that were still using the device " + "have been forcibly terminated. They are listed below."); + fullmsg += "<br>" + proclist; + return fullmsg; + } else { + return QString::null; + } +} + void HALBackend::slotResult(KIO::Job *job) { kdDebug() << "slotResult " << mount_jobs[job] << endl; @@ -1148,7 +1412,7 @@ QString HALBackend::mount(const Medium *medium) if (valids["flush"] == "true") soptions << "flush"; - if (valids["uid"] == "true") + if ((valids["uid"] == "true") && (medium->fsType() != "ntfs")) { soptions << QString("uid=%1").arg(getuid()); } @@ -1168,6 +1432,13 @@ QString HALBackend::mount(const Medium *medium) if (valids["sync"] == "true") soptions << "sync"; + if (medium->fsType() == "ntfs") { + QString fsLocale("locale="); + fsLocale += setlocale(LC_ALL, ""); + + soptions << fsLocale; + } + QString mount_point = valids["mountpoint"]; if (mount_point.startsWith("/media/")) mount_point = mount_point.mid(7); @@ -1199,7 +1470,24 @@ QString HALBackend::mount(const Medium *medium) options[noptions] = (*it).latin1(); options[noptions] = NULL; - QString qerror = mount_priv(medium->id().latin1(), mount_point.utf8(), options, noptions, dbus_connection); + QString qerror = i18n("Cannot mount encrypted drives!"); + + if (!medium->isEncrypted()) { + // normal volume + qerror = mount_priv(medium->id().latin1(), mount_point.utf8(), options, noptions, dbus_connection); + } else { + // see if we have a clear volume + LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, medium->id().latin1()); + if (halVolume) { + char* clearUdi = libhal_volume_crypto_get_clear_volume_udi(m_halContext, halVolume); + if (clearUdi != NULL) { + qerror = mount_priv(clearUdi, mount_point.utf8(), options, noptions, dbus_connection); + libhal_free_string(clearUdi); + } + libhal_volume_free(halVolume); + } + } + if (!qerror.isEmpty()) { kdError() << "mounting " << medium->id() << " returned " << qerror << endl; return qerror; @@ -1266,8 +1554,26 @@ QString HALBackend::unmount(const QString &_udi) DBusMessage *dmesg, *reply; DBusError error; const char *options[2]; + QString udi = QString::null; + + if (!medium->isEncrypted()) { + // normal volume + udi = medium->id(); + } else { + // see if we have a clear volume + LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, medium->id().latin1()); + if (halVolume) { + char *clearUdi = libhal_volume_crypto_get_clear_volume_udi(m_halContext, halVolume); + udi = clearUdi; + libhal_free_string(clearUdi); + libhal_volume_free(halVolume); + } + } + if (udi.isNull()) { + kdDebug() << "unmount failed: no udi" << endl; + return i18n("Internal Error"); + } - const char *udi = medium->id().latin1(); kdDebug() << "unmounting " << udi << "..." << endl; dbus_error_init(&error); @@ -1278,7 +1584,7 @@ QString HALBackend::unmount(const QString &_udi) return false; } - if (!(dmesg = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + if (!(dmesg = dbus_message_new_method_call ("org.freedesktop.Hal", udi.latin1(), "org.freedesktop.Hal.Device.Volume", "Unmount"))) { kdDebug() << "unmount failed for " << udi << ": could not create dbus message\n"; @@ -1296,11 +1602,25 @@ QString HALBackend::unmount(const QString &_udi) return i18n("Internal Error"); } + char thisunmounthasfailed = 0; dbus_error_init (&error); if (!(reply = dbus_connection_send_with_reply_and_block (dbus_connection, dmesg, -1, &error))) { - QString qerror, reason; + thisunmounthasfailed = 1; + QString qerror, reason, origqerror; + if (!strcmp(error.name, "org.freedesktop.Hal.Device.PermissionDeniedByPolicy")) { + qerror = privilegedUnmount(udi.latin1()); + + if (qerror.isEmpty()) { + dbus_message_unref(dmesg); + dbus_error_free(&error); + return QString(); + } + + // @todo handle unmount error message + } + kdDebug() << "unmount failed for " << udi << ": " << error.name << " " << error.message << endl; qerror = "<qt>"; qerror += "<p>" + i18n("Unfortunately, the device <b>%1</b> (%2) named <b>'%3'</b> and " @@ -1312,6 +1632,7 @@ QString HALBackend::unmount(const QString &_udi) qerror += "<p>" + i18n("Unmounting failed due to the following error:") + "</p>"; if (!strcmp(error.name, "org.freedesktop.Hal.Device.Volume.Busy")) { reason = i18n("Device is Busy:"); + thisunmounthasfailed = 2; } else if (!strcmp(error.name, "org.freedesktop.Hal.Device.Volume.NotMounted")) { // this is faking. The error is that the device wasn't mounted by hal (but by the system) reason = i18n("Permissions denied"); @@ -1319,16 +1640,29 @@ QString HALBackend::unmount(const QString &_udi) reason = error.message; } qerror += "<p><b>" + reason + "</b></p>"; + origqerror = qerror; // Include list of processes (if any) using the device in the error message reason = listUsingProcesses(medium); if (!reason.isEmpty()) { qerror += reason; + if (thisunmounthasfailed == 2) { // Failed as BUSY + if (KMessageBox::warningYesNo(0, i18n("%1<p><b>Would you like to forcibly terminate these processes?</b><br><i>All unsaved data would be lost</i>").arg(qerror)) == KMessageBox::Yes) { + qerror = origqerror; + reason = killUsingProcesses(medium); + qerror = HALBackend::unmount(udi); + if (qerror.isNull()) { + thisunmounthasfailed = 0; + } + } + } } - dbus_message_unref (dmesg); - dbus_error_free (&error); - return qerror; + if (thisunmounthasfailed != 0) { + dbus_message_unref (dmesg); + dbus_error_free (&error); + return qerror; + } } kdDebug() << "unmount queued for " << udi << endl; @@ -1337,8 +1671,117 @@ QString HALBackend::unmount(const QString &_udi) dbus_message_unref (reply); medium->setHalMounted(false); + ResetProperties(medium->id().latin1()); + + while (dbus_connection_dispatch(dbus_connection) == DBUS_DISPATCH_DATA_REMAINS) ; + + return QString(); +} + +QString HALBackend::decrypt(const QString &_udi, const QString &password) +{ + const Medium* medium = m_mediaList.findById(_udi); + if (!medium) + return i18n("No such medium: %1").arg(_udi); + + if (!medium->isEncrypted() || !medium->clearDeviceUdi().isNull()) + return QString(); + + const char *udi = medium->id().latin1(); + DBusMessage *msg = NULL; + DBusMessage *reply = NULL; + DBusError error; + + kdDebug() << "Setting up " << udi << " for crypto\n" <<endl; + + msg = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device.Volume.Crypto", + "Setup"); + if (msg == NULL) { + kdDebug() << "decrypt failed for " << udi << ": could not create dbus message\n"; + return i18n("Internal Error"); + } + + QCString pwdUtf8 = password.utf8(); + const char *pwd_utf8 = pwdUtf8; + if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &pwd_utf8, DBUS_TYPE_INVALID)) { + kdDebug() << "decrypt failed for " << udi << ": could not append args to dbus message\n"; + dbus_message_unref (msg); + return i18n("Internal Error"); + } + + dbus_error_init (&error); + if (!(reply = dbus_connection_send_with_reply_and_block (dbus_connection, msg, -1, &error)) || + dbus_error_is_set (&error)) + { + QString qerror = i18n("Internal Error"); + kdDebug() << "decrypt failed for " << udi << ": " << error.name << " " << error.message << endl; + if (strcmp (error.name, "org.freedesktop.Hal.Device.Volume.Crypto.SetupPasswordError") == 0) { + qerror = i18n("Wrong password"); + } + dbus_error_free (&error); + dbus_message_unref (msg); + while (dbus_connection_dispatch(dbus_connection) == DBUS_DISPATCH_DATA_REMAINS) ; + return qerror; + } + + dbus_message_unref (msg); + dbus_message_unref (reply); + + while (dbus_connection_dispatch(dbus_connection) == DBUS_DISPATCH_DATA_REMAINS) ; + + return QString(); +} + +QString HALBackend::undecrypt(const QString &_udi) +{ + const Medium* medium = m_mediaList.findById(_udi); + if (!medium) + return i18n("No such medium: %1").arg(_udi); + + if (!medium->isEncrypted() || medium->clearDeviceUdi().isNull()) + return QString(); + + const char *udi = medium->id().latin1(); + DBusMessage *msg = NULL; + DBusMessage *reply = NULL; + DBusError error; + + kdDebug() << "Tear down " << udi << "\n" <<endl; + + msg = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device.Volume.Crypto", + "Teardown"); + if (msg == NULL) { + kdDebug() << "teardown failed for " << udi << ": could not create dbus message\n"; + return i18n("Internal Error"); + } + + if (!dbus_message_append_args (msg, DBUS_TYPE_INVALID)) { + kdDebug() << "teardown failed for " << udi << ": could not append args to dbus message\n"; + dbus_message_unref (msg); + return i18n("Internal Error"); + } + + dbus_error_init (&error); + if (!(reply = dbus_connection_send_with_reply_and_block (dbus_connection, msg, -1, &error)) || + dbus_error_is_set (&error)) + { + QString qerror = i18n("Internal Error"); + kdDebug() << "teardown failed for " << udi << ": " << error.name << " " << error.message << endl; + dbus_error_free (&error); + dbus_message_unref (msg); + while (dbus_connection_dispatch(dbus_connection) == DBUS_DISPATCH_DATA_REMAINS) ; + return qerror; + } + + dbus_message_unref (msg); + dbus_message_unref (reply); + ResetProperties(udi); + while (dbus_connection_dispatch(dbus_connection) == DBUS_DISPATCH_DATA_REMAINS) ; + return QString(); } diff --git a/kioslave/media/mediamanager/halbackend.h b/kioslave/media/mediamanager/halbackend.h index 31c682374..c5bdd532c 100644 --- a/kioslave/media/mediamanager/halbackend.h +++ b/kioslave/media/mediamanager/halbackend.h @@ -85,6 +85,8 @@ public: QString mount(const QString &id); QString mount(const Medium *medium); QString unmount(const QString &id); + QString decrypt(const QString &id, const QString &password); + QString undecrypt(const QString &id); private: /** @@ -143,6 +145,7 @@ private: QString generateName(const QString &devNode); static QString isInFstab(const Medium *medium); static QString listUsingProcesses(const Medium *medium); + static QString killUsingProcesses(const Medium *medium); private slots: void slotResult(KIO::Job *job); diff --git a/kioslave/media/mediamanager/medialist.cpp b/kioslave/media/mediamanager/medialist.cpp index fed6091fb..974eddbf6 100644 --- a/kioslave/media/mediamanager/medialist.cpp +++ b/kioslave/media/mediamanager/medialist.cpp @@ -52,6 +52,18 @@ const Medium *MediaList::findByName(const QString &name) const return m_nameMap[name]; } +const Medium *MediaList::findByClearUdi(const QString &name) +{ + kdDebug(1219) << "MediaList::findByClearUdi(" << name << ")" << endl; + + Medium *medium; + for (medium = m_media.first(); medium; medium = m_media.next()) { + if (medium->clearDeviceUdi() == name) return medium; + } + + return 0L; +} + QString MediaList::addMedium(Medium *medium, bool allowNotification) { @@ -121,11 +133,12 @@ bool MediaList::changeMediumState(const Medium &medium, bool allowNotification) if ( medium.isMountable() ) { QString device_node = medium.deviceNode(); + QString clear_device_udi = medium.clearDeviceUdi(); QString mount_point = medium.mountPoint(); QString fs_type = medium.fsType(); bool mounted = medium.isMounted(); - m->mountableState( device_node, mount_point, + m->mountableState( device_node, clear_device_udi, mount_point, fs_type, mounted ); } else diff --git a/kioslave/media/mediamanager/medialist.h b/kioslave/media/mediamanager/medialist.h index 590491b0c..4de333875 100644 --- a/kioslave/media/mediamanager/medialist.h +++ b/kioslave/media/mediamanager/medialist.h @@ -34,6 +34,7 @@ public: const QPtrList<Medium> list() const; const Medium *findById(const QString &id) const; const Medium *findByName(const QString &name) const; + const Medium *findByClearUdi(const QString &name); public: QString addMedium(Medium *medium, bool allowNotification = true); diff --git a/kioslave/media/mediamanager/mediamanager.cpp b/kioslave/media/mediamanager/mediamanager.cpp index ad8f1b447..f1569e817 100644 --- a/kioslave/media/mediamanager/mediamanager.cpp +++ b/kioslave/media/mediamanager/mediamanager.cpp @@ -232,6 +232,28 @@ QString MediaManager::unmount(const QString &name) #endif } +QString MediaManager::decrypt(const QString &name, const QString &password) +{ +#ifdef COMPILE_HALBACKEND + if (!m_halbackend) + return i18n("Feature only available with HAL"); + return m_halbackend->decrypt(name, password); +#else + return i18n("Feature only available with HAL"); +#endif +} + +QString MediaManager::undecrypt(const QString &name) +{ +#ifdef COMPILE_HALBACKEND + if (!m_halbackend) + return i18n("Feature only available with HAL"); + return m_halbackend->undecrypt(name); +#else + return i18n("Feature only available with HAL"); +#endif +} + QString MediaManager::nameForLabel(const QString &label) { const QPtrList<Medium> media = m_mediaList.list(); diff --git a/kioslave/media/mediamanager/mediamanager.h b/kioslave/media/mediamanager/mediamanager.h index 1e5aa1d84..36942362d 100644 --- a/kioslave/media/mediamanager/mediamanager.h +++ b/kioslave/media/mediamanager/mediamanager.h @@ -47,6 +47,8 @@ k_dcop: QString mount(const QString &uid); QString unmount(const QString &uid); + QString decrypt(const QString &uid, const QString &password); + QString undecrypt(const QString &uid); QString nameForLabel(const QString &label); ASYNC setUserLabel(const QString &name, const QString &label); diff --git a/kioslave/media/medianotifier/medianotifier.cpp b/kioslave/media/medianotifier/medianotifier.cpp index 98a474ba7..ce39215d9 100644 --- a/kioslave/media/medianotifier/medianotifier.cpp +++ b/kioslave/media/medianotifier/medianotifier.cpp @@ -19,8 +19,12 @@ #include "medianotifier.h" +#include <sys/vfs.h> + #include <qfile.h> #include <qfileinfo.h> +#include <qdir.h> +#include <qcheckbox.h> #include <kapplication.h> #include <kglobal.h> @@ -44,6 +48,11 @@ MediaNotifier::MediaNotifier(const QCString &name) : KDEDModule(name) connectDCOPSignal( "kded", "mediamanager", "mediumChanged(QString, bool)", "onMediumChange(QString, bool)", true ); + + m_freeTimer = new QTimer( this ); + connect( m_freeTimer, SIGNAL( timeout() ), SLOT( checkFreeDiskSpace() ) ); + m_freeTimer->start( 1000*6*2 /* 20 minutes */ ); + m_freeDialog = 0; } MediaNotifier::~MediaNotifier() @@ -103,12 +112,12 @@ bool MediaNotifier::autostart( const KFileItem &medium ) { QString mimetype = medium.mimetype(); - bool is_cdrom = mimetype.startsWith( "cd" ) || mimetype.startsWith( "dvd" ); - bool is_mounted = mimetype.endsWith( "_mounted" ); + bool is_cdrom = mimetype.startsWith( "media/cd" ) || mimetype.startsWith( "media/dvd" ); + bool is_mounted = mimetype.contains( "_mounted" ); // We autorun only on CD/DVD or removable disks (USB, Firewire) if ( !( is_cdrom || is_mounted ) - && mimetype!="media/removable_mounted" ) + && !mimetype.startsWith("media/removable_mounted") ) { return false; } @@ -309,4 +318,69 @@ extern "C" } } +void MediaNotifier::checkFreeDiskSpace() +{ + struct statfs sfs; + long total, avail; + if ( m_freeDialog ) + return; + + if ( statfs( QFile::encodeName( QDir::homeDirPath() ), &sfs ) == 0 ) + { + total = sfs.f_blocks; + avail = ( getuid() ? sfs.f_bavail : sfs.f_bfree ); + + if (avail < 0 || total <= 0) + return; // we better do not say anything about it + + int freeperc = static_cast<int>(100 * double(avail) / total); + + if ( freeperc < 5 && KMessageBox::shouldBeShownContinue( "dontagainfreespace" ) ) // free disk space dropped under a limit + { + m_freeDialog= new KDialogBase( + i18n( "Low Disk Space" ), + KDialogBase::Yes | KDialogBase::No, + KDialogBase::Yes, KDialogBase::No, + 0, "warningYesNo", false, true, + i18n( "Start Konqueror" ), KStdGuiItem::cancel()); + + QString text = i18n( "You are running low on disk space on your home partition (currently %1% free), would you like to " + "run Konqueror to free some disk space and fix the problem?" ).arg( freeperc ); + bool checkboxResult = false; + KMessageBox::createKMessageBox(m_freeDialog, QMessageBox::Warning, text, QStringList(), + i18n("Do not ask again"), + &checkboxResult, KMessageBox::Notify | KMessageBox::NoExec); + m_freeDialog->show(); + connect( m_freeDialog, SIGNAL( yesClicked() ), SLOT( slotFreeContinue() ) ); + connect( m_freeDialog, SIGNAL( noClicked() ), SLOT( slotFreeCancel() ) ); + } + } +} + +void MediaNotifier::slotFreeContinue() +{ + slotFreeFinished( KMessageBox::Continue ); +} + +void MediaNotifier::slotFreeCancel() +{ + slotFreeFinished( KMessageBox::Cancel ); +} + +void MediaNotifier::slotFreeFinished( KMessageBox::ButtonCode res ) +{ + QCheckBox *checkbox = ::qt_cast<QCheckBox*>( m_freeDialog->child( 0, "QCheckBox" ) ); + if ( checkbox && checkbox->isChecked() ) + KMessageBox::saveDontShowAgainYesNo("dontagainfreespace", res); + m_freeDialog->delayedDestruct(); + m_freeDialog = 0; + + if ( res == KMessageBox::Continue ) // start Konqi + { + ( void ) new KRun( KURL::fromPathOrURL( QDir::homeDirPath() ) ); + } + else // people don't want to be bothered, at least stop the timer; there's no way to save the dontshowagain entry in this case + m_freeTimer->stop(); +} + #include "medianotifier.moc" diff --git a/kioslave/media/medianotifier/medianotifier.h b/kioslave/media/medianotifier/medianotifier.h index c3e4b9bf9..e070ac7ac 100644 --- a/kioslave/media/medianotifier/medianotifier.h +++ b/kioslave/media/medianotifier/medianotifier.h @@ -23,10 +23,13 @@ #include <kdedmodule.h> #include <kfileitem.h> #include <kio/job.h> +#include <kmessagebox.h> #include <qstring.h> #include <qmap.h> +class KDialogBase; + class MediaNotifier: public KDEDModule { Q_OBJECT @@ -41,6 +44,10 @@ k_dcop: private slots: void slotStatResult( KIO::Job *job ); + void checkFreeDiskSpace(); + void slotFreeFinished( KMessageBox::ButtonCode ); + void slotFreeContinue(); + void slotFreeCancel(); private: bool autostart( const KFileItem &medium ); @@ -52,6 +59,8 @@ private: const QString &autoopenFile ); QMap<KIO::Job*,bool> m_allowNotificationMap; + QTimer * m_freeTimer; + KDialogBase * m_freeDialog; }; #endif diff --git a/kioslave/media/mimetypes/Makefile.am b/kioslave/media/mimetypes/Makefile.am index 25c718035..cdb66a1ac 100644 --- a/kioslave/media/mimetypes/Makefile.am +++ b/kioslave/media/mimetypes/Makefile.am @@ -4,10 +4,20 @@ mimetype_DATA = floppy_mounted.desktop floppy_unmounted.desktop \ floppy5_unmounted.desktop floppy5_mounted.desktop \ zip_mounted.desktop zip_unmounted.desktop \ hdd_mounted.desktop hdd_unmounted.desktop \ + hdd_mounted_decrypted.desktop hdd_unmounted_encrypted.desktop \ + hdd_unmounted_decrypted.desktop \ removable_mounted.desktop removable_unmounted.desktop \ + removable_mounted_decrypted.desktop removable_unmounted_encrypted.desktop \ + removable_unmounted_decrypted.desktop \ cdrom_mounted.desktop cdrom_unmounted.desktop \ + cdrom_mounted_decrypted.desktop cdrom_unmounted_encrypted.desktop \ + cdrom_unmounted_decrypted.desktop \ dvd_mounted.desktop dvd_unmounted.desktop \ + dvd_mounted_decrypted.desktop dvd_unmounted_encrypted.desktop \ + dvd_unmounted_decrypted.desktop \ cdwriter_mounted.desktop cdwriter_unmounted.desktop \ + cdwriter_mounted_decrypted.desktop cdwriter_unmounted_encrypted.desktop \ + cdwriter_unmounted_decrypted.desktop \ smb_mounted.desktop smb_unmounted.desktop \ nfs_mounted.desktop nfs_unmounted.desktop \ audiocd.desktop \ diff --git a/kioslave/media/mimetypes/cdrom_mounted_decrypted.desktop b/kioslave/media/mimetypes/cdrom_mounted_decrypted.desktop new file mode 100644 index 000000000..2729ff4f5 --- /dev/null +++ b/kioslave/media/mimetypes/cdrom_mounted_decrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=cdrom_mount_decrypt +Type=MimeType +MimeType=media/cdrom_mounted_decrypted +Comment=Mounted Decrypted CD-ROM +Comment[de]=Eingebundene, entschlüsselte CD-ROM +Patterns= + +X-KDE-AutoEmbed=true +X-KDE-IsAlso=inode/directory diff --git a/kioslave/media/mimetypes/cdrom_unmounted_decrypted.desktop b/kioslave/media/mimetypes/cdrom_unmounted_decrypted.desktop new file mode 100644 index 000000000..d6b2be0c2 --- /dev/null +++ b/kioslave/media/mimetypes/cdrom_unmounted_decrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=cdrom_unmount_decrypt +Type=MimeType +MimeType=media/cdrom_unmounted_decrypted +Comment=Unmounted Decrypted CD-ROM +Comment[de]=Nicht eingebundene, entschlüsselte CD-ROM +Patterns= + +X-KDE-AutoEmbed=true +X-KDE-IsAlso=inode/directory diff --git a/kioslave/media/mimetypes/cdrom_unmounted_encrypted.desktop b/kioslave/media/mimetypes/cdrom_unmounted_encrypted.desktop new file mode 100644 index 000000000..95fa31b3b --- /dev/null +++ b/kioslave/media/mimetypes/cdrom_unmounted_encrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=cdrom_unmount_encrypt +Type=MimeType +MimeType=media/cdrom_unmounted_encrypted +Comment=Unmounted Encrypted CD-ROM +Comment[de]=Nicht eingebundene, verschlüsselte CD-ROM +Patterns= + +X-KDE-AutoEmbed=true +X-KDE-IsAlso=inode/directory diff --git a/kioslave/media/mimetypes/cdwriter_mounted_decrypted.desktop b/kioslave/media/mimetypes/cdwriter_mounted_decrypted.desktop new file mode 100644 index 000000000..b831be152 --- /dev/null +++ b/kioslave/media/mimetypes/cdwriter_mounted_decrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=cdwriter_mount_decrypt +Type=MimeType +MimeType=media/cdwriter_mounted_decrypted +Comment=Mounted Decrypted CD Writer +Comment[de]=Eingebundener, entschlüsselter CD-Brenner +Patterns= + +X-KDE-AutoEmbed=true +X-KDE-IsAlso=inode/directory diff --git a/kioslave/media/mimetypes/cdwriter_unmounted_decrypted.desktop b/kioslave/media/mimetypes/cdwriter_unmounted_decrypted.desktop new file mode 100644 index 000000000..48f49ccb4 --- /dev/null +++ b/kioslave/media/mimetypes/cdwriter_unmounted_decrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=cdwriter_unmount_decrypt +Type=MimeType +MimeType=media/cdwriter_unmounted_decrypted +Comment=Unmounted Decrypted CD Writer +Comment[de]=Nicht eingebundener, entschlüsselter CD-Brenner +Patterns= + +X-KDE-AutoEmbed=true +X-KDE-IsAlso=inode/directory diff --git a/kioslave/media/mimetypes/cdwriter_unmounted_encrypted.desktop b/kioslave/media/mimetypes/cdwriter_unmounted_encrypted.desktop new file mode 100644 index 000000000..c31e66089 --- /dev/null +++ b/kioslave/media/mimetypes/cdwriter_unmounted_encrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=cdwriter_unmount_encrypt +Type=MimeType +MimeType=media/cdwriter_unmounted_encrypted +Comment=Unmounted Encrypted CD Writer +Comment[de]=Nicht eingebundener, entschlüsselter CD-Brenner +Patterns= + +X-KDE-AutoEmbed=true +X-KDE-IsAlso=inode/directory diff --git a/kioslave/media/mimetypes/dvd_mounted_decrypted.desktop b/kioslave/media/mimetypes/dvd_mounted_decrypted.desktop new file mode 100644 index 000000000..22a90b52d --- /dev/null +++ b/kioslave/media/mimetypes/dvd_mounted_decrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=dvd_mount_decrypt +Type=MimeType +MimeType=media/dvd_mounted_decrypted +Comment=Mounted Decrypted DVD +Comment[de]=Eingebundene, entschlüsselte DVD +Patterns= + +X-KDE-AutoEmbed=true +X-KDE-IsAlso=inode/directory diff --git a/kioslave/media/mimetypes/dvd_unmounted_decrypted.desktop b/kioslave/media/mimetypes/dvd_unmounted_decrypted.desktop new file mode 100644 index 000000000..129f3f177 --- /dev/null +++ b/kioslave/media/mimetypes/dvd_unmounted_decrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=dvd_unmount_decrypt +Type=MimeType +MimeType=media/dvd_unmounted_decrypted +Comment=Unmounted Decrypted DVD +Comment[de]=Nicht eingebundene, entschlüsselte DVD +Patterns= + +X-KDE-AutoEmbed=true +X-KDE-IsAlso=inode/directory diff --git a/kioslave/media/mimetypes/dvd_unmounted_encrypted.desktop b/kioslave/media/mimetypes/dvd_unmounted_encrypted.desktop new file mode 100644 index 000000000..23d2353b5 --- /dev/null +++ b/kioslave/media/mimetypes/dvd_unmounted_encrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=dvd_unmount_encrypt +Type=MimeType +MimeType=media/dvd_unmounted_encrypted +Comment=Unmounted Encrypted DVD +Comment[de]=Nicht eingebundene, verschlüsselte DVD +Patterns= + +X-KDE-AutoEmbed=true +X-KDE-IsAlso=inode/directory diff --git a/kioslave/media/mimetypes/hdd_mounted_decrypted.desktop b/kioslave/media/mimetypes/hdd_mounted_decrypted.desktop new file mode 100644 index 000000000..f4b1c1749 --- /dev/null +++ b/kioslave/media/mimetypes/hdd_mounted_decrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=hdd_mount_decrypt +Type=MimeType +MimeType=media/hdd_mounted_decrypted +Comment=Mounted Decrypted Hard Disk Volume +Comment[de]=Eingebundene, entschlüsselte Festplattenpartition +Patterns= + +X-KDE-AutoEmbed=true +X-KDE-IsAlso=inode/directory diff --git a/kioslave/media/mimetypes/hdd_unmounted_decrypted.desktop b/kioslave/media/mimetypes/hdd_unmounted_decrypted.desktop new file mode 100644 index 000000000..f41411314 --- /dev/null +++ b/kioslave/media/mimetypes/hdd_unmounted_decrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=hdd_unmount_decrypt +Type=MimeType +MimeType=media/hdd_unmounted_decrypted +Comment=Unmounted Decrypted Hard Disk Volume +Comment[de]=Nicht eingebundene, entschlüsselte Festplattenpartition +Patterns= + +X-KDE-AutoEmbed=true +X-KDE-IsAlso=inode/directory diff --git a/kioslave/media/mimetypes/hdd_unmounted_encrypted.desktop b/kioslave/media/mimetypes/hdd_unmounted_encrypted.desktop new file mode 100644 index 000000000..60e277811 --- /dev/null +++ b/kioslave/media/mimetypes/hdd_unmounted_encrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=hdd_unmount_encrypt +Type=MimeType +MimeType=media/hdd_unmounted_encrypted +Comment=Unmounted Encrypted Hard Disk Volume +Comment[de]=Nicht eingebundene, verschlüsselte Festplattenpartition +Patterns= + +X-KDE-AutoEmbed=true +X-KDE-IsAlso=inode/directory diff --git a/kioslave/media/mimetypes/removable_mounted_decrypted.desktop b/kioslave/media/mimetypes/removable_mounted_decrypted.desktop new file mode 100644 index 000000000..6a025119d --- /dev/null +++ b/kioslave/media/mimetypes/removable_mounted_decrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=usbpendrive_mount_decrypt +Type=MimeType +MimeType=media/removable_mounted_decrypted +Comment=Mounted Decrypted Removable Medium +Comment[de]=Eingebundenes, entschlüsseltes Wechsellaufwerk +Patterns= + +X-KDE-AutoEmbed=true +X-KDE-IsAlso=inode/directory diff --git a/kioslave/media/mimetypes/removable_unmounted_decrypted.desktop b/kioslave/media/mimetypes/removable_unmounted_decrypted.desktop new file mode 100644 index 000000000..fe3ecd6a8 --- /dev/null +++ b/kioslave/media/mimetypes/removable_unmounted_decrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=usbpendrive_unmount_decrypt +Type=MimeType +MimeType=media/removable_unmounted_decrypted +Comment=Unmounted Decrypted Removable Medium +Comment[de]=Nicht eingebundenes, entschlüsseltes Wechsellaufwerk +Patterns= + +X-KDE-AutoEmbed=true +X-KDE-IsAlso=inode/directory diff --git a/kioslave/media/mimetypes/removable_unmounted_encrypted.desktop b/kioslave/media/mimetypes/removable_unmounted_encrypted.desktop new file mode 100644 index 000000000..e2949bfed --- /dev/null +++ b/kioslave/media/mimetypes/removable_unmounted_encrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=usbpendrive_unmount_encrypt +Type=MimeType +MimeType=media/removable_unmounted_encrypted +Comment=Unmounted Encrypted Removable Medium +Comment[de]=Nicht eingebundenes, verschlüsseltes Wechsellaufwerk +Patterns= + +X-KDE-AutoEmbed=true +X-KDE-IsAlso=inode/directory diff --git a/kioslave/media/mounthelper/Makefile.am b/kioslave/media/mounthelper/Makefile.am index 9080ba81a..9c03ba688 100644 --- a/kioslave/media/mounthelper/Makefile.am +++ b/kioslave/media/mounthelper/Makefile.am @@ -3,10 +3,10 @@ bin_PROGRAMS = kio_media_mounthelper INCLUDES = -I$(srcdir)/../libmediacommon $(all_includes) AM_LDFLAGS = $(all_libraries) -kio_media_mounthelper_SOURCES = kio_media_mounthelper.cpp +kio_media_mounthelper_SOURCES = kio_media_mounthelper.cpp decryptdialog.ui dialog.cpp kio_media_mounthelper_LDFLAGS = $(KDE_RPATH) $(all_libraries) -kio_media_mounthelper_LDADD = ../libmediacommon/libmediacommon.la $(LIB_KIO) +kio_media_mounthelper_LDADD = ../libmediacommon/libmediacommon.la $(LIB_KIO) $(LIB_KDEUI) METASOURCES = AUTO diff --git a/kioslave/media/mounthelper/decryptdialog.ui b/kioslave/media/mounthelper/decryptdialog.ui new file mode 100644 index 000000000..15790c8ef --- /dev/null +++ b/kioslave/media/mounthelper/decryptdialog.ui @@ -0,0 +1,201 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>DecryptDialog</class> +<widget class="QWidget"> + <property name="name"> + <cstring>DecryptDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>207</width> + <height>172</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="caption"> + <string>Decrypting Storage Device</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>encryptedIcon</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>48</width> + <height>48</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + <property name="alignment"> + <set>AlignTop</set> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>31</width> + <height>41</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>descLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string><p><b>%1</b> is an encrypted storage device.</p> +<p>Please enter the password to decrypt the storage device.</p></string> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>&Password:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>passwordEdit</cstring> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>passwordEdit</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="echoMode"> + <enum>Password</enum> + </property> + </widget> + </hbox> + </widget> + <widget class="QGroupBox" row="2" column="0"> + <property name="name"> + <cstring>errorBox</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Error</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>errorLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + </grid> + </widget> + </grid> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kioslave/media/mounthelper/dialog.cpp b/kioslave/media/mounthelper/dialog.cpp new file mode 100644 index 000000000..74bcfb388 --- /dev/null +++ b/kioslave/media/mounthelper/dialog.cpp @@ -0,0 +1,68 @@ +/* This file is part of the KDE project + * Copyright (C) 2007 Jan Klötzke <jan kloetzke at freenet de> + * + * Based on kryptomedia- Another KDE cryto media application. + * Copyright (C) 2006 Daniel Gollub <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "dialog.h" + +Dialog::Dialog(QString url, QString iconName) : + KDialogBase(NULL, "Dialog", true, "Decrypt Storage Device", (Cancel|User1), User1, false, KGuiItem(i18n("Decrypt"), "decrypted" )) +{ + decryptDialog = new DecryptDialog(this); + + decryptDialog->errorBox->hide(); + decryptDialog->descLabel->setText(decryptDialog->descLabel->text().arg(url)); + decryptDialog->descLabel->adjustSize(); + decryptDialog->adjustSize(); + + enableButton( User1, false ); + + QPixmap pixmap = KGlobal::iconLoader()->loadIcon(iconName, KIcon::NoGroup, KIcon::SizeLarge); + decryptDialog->encryptedIcon->setPixmap( pixmap ); + + connect(decryptDialog->passwordEdit, SIGNAL (textChanged(const QString &)), this, SLOT (slotPasswordChanged(const QString &))); + + setMainWidget(decryptDialog); +} + +Dialog::~Dialog() +{ + delete decryptDialog; +} + +QString Dialog::getPassword() +{ + return decryptDialog->passwordEdit->text(); +} + +void Dialog::slotDialogError(QString errorMsg) +{ + kdDebug() << __func__ << "(" << errorMsg << " )" << endl; + + decryptDialog->errorLabel->setText(QString("<b>%1</b>").arg(errorMsg)); + decryptDialog->errorBox->show(); +} + +void Dialog::slotPasswordChanged(const QString &text) +{ + enableButton( User1, !text.isEmpty() ); +} + +#include "dialog.moc" diff --git a/kioslave/media/mounthelper/dialog.h b/kioslave/media/mounthelper/dialog.h new file mode 100644 index 000000000..1f544c370 --- /dev/null +++ b/kioslave/media/mounthelper/dialog.h @@ -0,0 +1,61 @@ +/* This file is part of the KDE project + * Copyright (C) 2007 Jan Klötzke <jan kloetzke at freenet de> + * + * Based on kryptomedia- Another KDE cryto media application. + * Copyright (C) 2006 Daniel Gollub <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef DIALOG_H_ +#define DIALOG_H_ + +#include <kmessagebox.h> +#include <klocale.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kdialogbase.h> +#include <kiconloader.h> + +#include <qlineedit.h> +#include <qlabel.h> +#include <qgroupbox.h> + +#include "decryptdialog.h" + +class KryptoMedia; + +class Dialog : public KDialogBase +{ + +Q_OBJECT + +public: + Dialog(QString url, QString iconName); + ~Dialog(); + + QString getPassword(); + +public slots: + void slotDialogError(QString errorMsg); + void slotPasswordChanged(const QString &text); + +private: + DecryptDialog *decryptDialog; +}; + +#endif // DIALOG_H_ + diff --git a/kioslave/media/mounthelper/kio_media_mounthelper.cpp b/kioslave/media/mounthelper/kio_media_mounthelper.cpp index 12743847f..5dae9e0d3 100644 --- a/kioslave/media/mounthelper/kio_media_mounthelper.cpp +++ b/kioslave/media/mounthelper/kio_media_mounthelper.cpp @@ -32,7 +32,9 @@ #include <kglobal.h> #include <kprocess.h> #include <kstartupinfo.h> +#include <kmimetype.h> +#include "dialog.h" #include "kio_media_mounthelper.h" const Medium MountHelper::findMedium(const KURL &url) @@ -63,7 +65,7 @@ MountHelper::MountHelper() : KApplication() { KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); - m_errorStr = ""; + m_errorStr = QString::null; KURL url(args->url(0)); const Medium medium = findMedium(url); @@ -89,7 +91,37 @@ MountHelper::MountHelper() : KApplication() m_isCdrom = medium.mimeType().find("dvd")!=-1 || medium.mimeType().find("cd")!=-1; - if (args->isSet("u")) + if (args->isSet("d")) + { + if (!medium.isEncrypted()) + { + m_errorStr = i18n("%1 is not an encrypted media.").arg(url.prettyURL()); + QTimer::singleShot(0, this, SLOT(error()) ); + return; + } + if (!medium.needDecryption()) + { + m_errorStr = i18n("%1 is already decrypted.").arg(url.prettyURL()); + QTimer::singleShot(0, this, SLOT(error()) ); + return; + } + + QString iconName = medium.iconName(); + if (iconName.isEmpty()) + { + QString mime = medium.mimeType(); + iconName = KMimeType::mimeType(mime)->icon(mime, false); + } + + m_mediumId = medium.id(); + dialog = new Dialog(url.prettyURL(), iconName); + dialog->show(); + + connect(dialog, SIGNAL (user1Clicked()), this, SLOT (slotSendPassword())); + connect(dialog, SIGNAL (cancelClicked()), this, SLOT (slotCancel())); + connect(this, SIGNAL (signalPasswordError(QString)), dialog, SLOT (slotDialogError(QString))); + } + else if (args->isSet("u")) { DCOPRef mediamanager("kded", "mediamanager"); DCOPReply reply = mediamanager.call( "unmount", medium.id()); @@ -103,6 +135,8 @@ MountHelper::MountHelper() : KApplication() } else if (args->isSet("s") || args->isSet("e")) { + DCOPRef mediamanager("kded", "mediamanager"); + /* * We want to call mediamanager unmount before invoking eject. That's * because unmount would provide an informative error message in case of @@ -114,17 +148,24 @@ MountHelper::MountHelper() : KApplication() */ if (medium.isMounted()) { - DCOPRef mediamanager("kded", "mediamanager"); DCOPReply reply = mediamanager.call( "unmount", medium.id()); if (reply.isValid()) reply.get(m_errorStr); - if (m_errorStr.isNull()) - invokeEject(device, true); - else - error(); - m_device = device; - } else - invokeEject(device, true); + } + + /* If this is a decrypted volume and there is no error yet + * we try to teardown the decryption */ + if (m_errorStr.isNull() && medium.isEncrypted() && !medium.clearDeviceUdi().isNull()) + { + DCOPReply reply = mediamanager.call( "undecrypt", medium.id()); + if (reply.isValid()) + reply.get(m_errorStr); + } + + if (m_errorStr.isNull()) + invokeEject(device, true); + else + error(); } else { @@ -167,7 +208,9 @@ void MountHelper::ejectFinished(KProcess* proc) else m_errorStr = i18n("The device was successfully unmounted, but could not be ejected"); } - QTimer::singleShot(0, this, SLOT(error())); +//X Comment this because the error is useless as long as the unmount is successfull. +//X QTimer::singleShot(0, this, SLOT(error())); + ::exit(0); } } @@ -177,8 +220,32 @@ void MountHelper::error() ::exit(1); } +void MountHelper::slotSendPassword() +{ + DCOPRef mediamanager("kded", "mediamanager"); + + DCOPReply reply = mediamanager.call( "decrypt", m_mediumId, dialog->getPassword() ); + if (!reply.isValid()) { + m_errorStr = i18n("The KDE mediamanager is not running."); + error(); + } else { + QString errorMsg = reply; + if (errorMsg.isNull()) { + exit(0); + } else { + emit signalPasswordError(errorMsg); + } + } +} + +void MountHelper::slotCancel() +{ + exit(0); +} + static KCmdLineOptions options[] = { + { "d", I18N_NOOP("Decrypt given URL"), 0 }, { "u", I18N_NOOP("Unmount given URL"), 0 }, { "m", I18N_NOOP("Mount given URL (default)"), 0 }, { "e", I18N_NOOP("Eject given URL via kdeeject"), 0}, diff --git a/kioslave/media/mounthelper/kio_media_mounthelper.h b/kioslave/media/mounthelper/kio_media_mounthelper.h index 478d802f9..ed5884d4f 100644 --- a/kioslave/media/mounthelper/kio_media_mounthelper.h +++ b/kioslave/media/mounthelper/kio_media_mounthelper.h @@ -28,6 +28,8 @@ #include "medium.h" +class Dialog; + class MountHelper : public KApplication { Q_OBJECT @@ -38,12 +40,18 @@ private: const Medium findMedium(const KURL &url); void invokeEject(const QString &device, bool quiet=false); QString m_errorStr; - QString m_device; bool m_isCdrom; + QString m_mediumId; + Dialog *dialog; private slots: + void slotSendPassword(); + void slotCancel(); void ejectFinished(KProcess* proc); void error(); + +signals: + void signalPasswordError(QString errorMsg); }; #endif diff --git a/kioslave/media/propsdlgplugin/media_propsdlgplugin.desktop b/kioslave/media/propsdlgplugin/media_propsdlgplugin.desktop index c0cdcbbba..d5e13eda5 100644 --- a/kioslave/media/propsdlgplugin/media_propsdlgplugin.desktop +++ b/kioslave/media/propsdlgplugin/media_propsdlgplugin.desktop @@ -99,4 +99,4 @@ Comment[wa]=Tchôke-divins di dvize di prôpietés Konqueror po-z apontyî l' du Comment[zh_CN]=配置挂载行为的 Konqueror 属性对话框插件 Comment[zh_TW]=Konqueror 內容對話框外掛程式,用於設定掛載的行為 X-KDE-Library=media_propsdlgplugin -ServiceTypes=KPropsDlg/Plugin,media/audiocd,media/hdd_mounted,media/hdd_unmounted,media/cdrom_mounted,media/cdrom_unmounted,media/cdwriter_mounted,media/nfs_mounted,media/cdwriter_unmounted,media/nfs_unmounted,media/removable_mounted,media/dvd_mounted,media/removable_unmounted,media/dvd_unmounted,media/smb_mounted,media/dvdvideo,media/smb_unmounted,media/floppy5_mounted,media/floppy5_unmounted,media/floppy_mounted,media/zip_mounted,media/floppy_unmounted,media/zip_unmounted,media/camera_mounted,media/camera_unmounted +ServiceTypes=KPropsDlg/Plugin,media/audiocd,media/hdd_mounted,media/hdd_unmounted,media/hdd_mounted_decrypted,media/hdd_unmounted_decrypted,media/cdrom_mounted,media/cdrom_unmounted,media/cdrom_mounted_decrypted,media/cdrom_unmounted_decrypted,media/cdwriter_mounted,media/cdwriter_mounted_decrypted,media/nfs_mounted,media/cdwriter_unmounted,media/cdwriter_unmounted_decrypted,media/nfs_unmounted,media/removable_mounted,media/removable_mounted_decrypted,media/dvd_mounted,media/dvd_mounted_decrypted,media/removable_unmounted,media/removable_unmounted_decrypted,media/dvd_unmounted,media/dvd_unmounted_decrypted,media/smb_mounted,media/dvdvideo,media/smb_unmounted,media/floppy5_mounted,media/floppy5_unmounted,media/floppy_mounted,media/zip_mounted,media/floppy_unmounted,media/zip_unmounted,media/camera_mounted,media/camera_unmounted diff --git a/kioslave/media/services/Makefile.am b/kioslave/media/services/Makefile.am index dded3c403..c744934f2 100644 --- a/kioslave/media/services/Makefile.am +++ b/kioslave/media/services/Makefile.am @@ -1,3 +1,3 @@ servicesdir = $(kde_datadir)/konqueror/servicemenus -services_DATA = media_mount.desktop media_unmount.desktop media_eject.desktop media_safelyremove.desktop +services_DATA = media_decrypt.desktop media_mount.desktop media_unmount.desktop media_eject.desktop media_safelyremove.desktop diff --git a/kioslave/media/services/media_decrypt.desktop b/kioslave/media/services/media_decrypt.desktop new file mode 100644 index 000000000..dd8dadc39 --- /dev/null +++ b/kioslave/media/services/media_decrypt.desktop @@ -0,0 +1,9 @@ +[Desktop Action Decrypt] +Exec=kio_media_mounthelper -d %u +Icon=decrypted +Name=Decrypt +Name[de]=Entschlüsseln + +[Desktop Entry] +Actions=Decrypt +ServiceTypes=media/removable_unmounted_encrypted,media/hdd_unmounted_encrypted,media/cdrom_unmounted_encrypted,media/cdwriter_unmounted_encrypted,media/dvd_unmounted_encrypted diff --git a/kioslave/media/services/media_eject.desktop b/kioslave/media/services/media_eject.desktop index 1ecd29fa8..f5ab3582e 100644 --- a/kioslave/media/services/media_eject.desktop +++ b/kioslave/media/services/media_eject.desktop @@ -1,5 +1,5 @@ [Desktop Entry] -ServiceTypes=media/cdrom_mounted,media/cdrom_unmounted,media/cdwriter_mounted,media/cdwriter_unmounted,media/dvd_mounted,media/dvd_unmounted,media/audiocd,media/blankcd,media/blankdvd,media/dvdvideo,media/svcd,media/vcd +ServiceTypes=media/cdrom_mounted,media/cdrom_unmounted,media/cdrom_mounted_decrypted,media/cdrom_unmounted_decrypted,media/cdrom_unmounted_encrypted,media/cdwriter_mounted,media/cdwriter_unmounted,media/cdwriter_mounted_decrypted,media/cdwriter_unmounted_decrypted,media/cdwriter_unmounted_encrypted,media/dvd_mounted,media/dvd_unmounted,media/dvd_mounted_decrypted,media/dvd_unmounted_decrypted,media/dvd_unmounted_encrypted,media/audiocd,media/blankcd,media/blankdvd,media/dvdvideo,media/svcd,media/vcd Actions=MediaEject; X-KDE-Priority=TopLevel X-KDE-MediaNotifierHide=true diff --git a/kioslave/media/services/media_mount.desktop b/kioslave/media/services/media_mount.desktop index 1779d2208..b2166f8ea 100644 --- a/kioslave/media/services/media_mount.desktop +++ b/kioslave/media/services/media_mount.desktop @@ -1,5 +1,5 @@ [Desktop Entry] -ServiceTypes=media/cdrom_unmounted,media/cdwriter_unmounted,media/dvd_unmounted,media/floppy5_unmounted,media/floppy_unmounted,media/hdd_unmounted,media/nfs_unmounted,media/removable_unmounted,media/smb_unmounted,media/zip_unmounted,media/camera_unmounted +ServiceTypes=media/cdrom_unmounted,media/cdrom_unmounted_decrypted,media/cdwriter_unmounted,media/cdwriter_unmounted_decrypted,media/dvd_unmounted,media/dvd_unmounted_decrypted,media/floppy5_unmounted,media/floppy_unmounted,media/hdd_unmounted,media/hdd_unmounted_decrypted,media/nfs_unmounted,media/removable_unmounted,media/removable_unmounted_decrypted,media/smb_unmounted,media/zip_unmounted,media/camera_unmounted Actions=MediaMount; X-KDE-Priority=TopLevel X-KDE-MediaNotifierHide=true diff --git a/kioslave/media/services/media_safelyremove.desktop b/kioslave/media/services/media_safelyremove.desktop index 298a5f2e5..ce92f348c 100644 --- a/kioslave/media/services/media_safelyremove.desktop +++ b/kioslave/media/services/media_safelyremove.desktop @@ -1,5 +1,5 @@ [Desktop Entry] -ServiceTypes=media/removable_mounted,media/removable_unmounted,media/camera_mounted,media/camera_unmounted +ServiceTypes=media/removable_mounted,media/removable_mounted_decrypted,media/removable_unmounted,media/removable_unmounted_decrypted,media/camera_mounted,media/camera_unmounted Actions=MediaSafelyRemove; X-KDE-Priority=TopLevel X-KDE-MediaNotifierHide=true diff --git a/kioslave/media/services/media_unmount.desktop b/kioslave/media/services/media_unmount.desktop index 537750095..5877e484e 100644 --- a/kioslave/media/services/media_unmount.desktop +++ b/kioslave/media/services/media_unmount.desktop @@ -1,5 +1,5 @@ [Desktop Entry] -ServiceTypes=media/cdrom_mounted,media/cdwriter_mounted,media/dvd_mounted,media/floppy5_mounted,media/floppy_mounted,media/hdd_mounted,media/nfs_mounted,media/smb_mounted,media/zip_mounted,media/vcd,media/svcd,media/dvdvideo +ServiceTypes=media/cdrom_mounted,media/cdrom_mounted_decrypted,media/cdwriter_mounted,media/cdwriter_mounted_decrypted,media/dvd_mounted,media/dvd_mounted_decrypted,media/floppy5_mounted,media/floppy_mounted,media/hdd_mounted,media/hdd_mounted_decrypted,media/nfs_mounted,media/smb_mounted,media/zip_mounted,media/vcd,media/svcd,media/dvdvideo Actions=MediaUnmount; X-KDE-Priority=TopLevel X-KDE-MediaNotifierHide=true diff --git a/kioslave/nfs/kio_nfs.cpp b/kioslave/nfs/kio_nfs.cpp index 18a7f1393..b35489c8d 100644 --- a/kioslave/nfs/kio_nfs.cpp +++ b/kioslave/nfs/kio_nfs.cpp @@ -89,7 +89,7 @@ int x_getdomainname(char *name, size_t len) { if ((hent = gethostbyname(uts.nodename)) != 0L) { - char *p = strchr(hent->h_name, '.'); + char *p = (char*)strchr(hent->h_name, '.'); if (p != 0L) { ++p; diff --git a/kioslave/system/systemimpl.cpp b/kioslave/system/systemimpl.cpp index f773dc20e..46214ce20 100644 --- a/kioslave/system/systemimpl.cpp +++ b/kioslave/system/systemimpl.cpp @@ -228,8 +228,16 @@ void SystemImpl::createEntry(KIO::UDSEntry &entry, QString new_filename = file; new_filename.truncate(file.length()-8); - addAtom(entry, KIO::UDS_URL, 0, "system:/"+new_filename); + if ( desktop.readURL().isEmpty() ) + { + addAtom(entry, KIO::UDS_URL, 0, desktop.readPath()); + } + else + { + addAtom(entry, KIO::UDS_URL, 0, "system:/"+new_filename); + } + addAtom(entry, KIO::UDS_FILE_TYPE, S_IFDIR); addAtom(entry, KIO::UDS_MIME_TYPE, 0, "inode/directory"); diff --git a/klipper/urlgrabber.cpp b/klipper/urlgrabber.cpp index 352f3ab74..45d5f5e4b 100644 --- a/klipper/urlgrabber.cpp +++ b/klipper/urlgrabber.cpp @@ -51,7 +51,6 @@ URLGrabber::URLGrabber( KConfig* config ) { if( m_config == NULL ) m_config = kapp->config(); - myCurrentAction = 0L; myMenu = 0L; myPopupKillTimeout = 8; m_stripWhiteSpace = true; @@ -160,6 +159,7 @@ void URLGrabber::actionMenu( bool wm_class_check ) QString item; myCommandMapper.clear(); + myGroupingMapper.clear(); myPopupKillTimer->stop(); delete myMenu; @@ -184,6 +184,7 @@ void URLGrabber::actionMenu( bool wm_class_check ) else id = myMenu->insertItem( SmallIcon(command->pixmap), item); myCommandMapper.insert( id, command ); + myGroupingMapper.insert( id, action->capturedTexts() ); } } @@ -224,19 +225,27 @@ void URLGrabber::slotItemSelected( int id ) break; default: ClipCommand *command = myCommandMapper.find( id ); - if ( !command ) + QStringList *backrefs = myGroupingMapper.find( id ); + if ( !command || !backrefs ) qWarning("Klipper: can't find associated action"); else - execute( command ); + execute( command, backrefs ); } } -void URLGrabber::execute( const struct ClipCommand *command ) const +void URLGrabber::execute( const struct ClipCommand *command, + QStringList *backrefs) const { if ( command->isEnabled ) { QMap<QChar,QString> map; map.insert( 's', myClipData ); + int brCounter = -1; + QStringList::Iterator it = backrefs->begin(); + while( it != backrefs->end() ) { + map.insert( char(++brCounter + '0') , *it ); + ++it; + } QString cmdLine = KMacroExpander::expandMacrosShellQuote( command->command, map ); if ( cmdLine.isEmpty() ) diff --git a/klipper/urlgrabber.h b/klipper/urlgrabber.h index ae39d648d..232455fa0 100644 --- a/klipper/urlgrabber.h +++ b/klipper/urlgrabber.h @@ -72,7 +72,8 @@ public: private: const ActionList& matchingActions( const QString& ); - void execute( const struct ClipCommand *command ) const; + void execute( const struct ClipCommand *command, + QStringList *backrefs ) const; void editData(); bool isAvoidedWindow() const; void actionMenu( bool wm_class_check ); @@ -83,6 +84,7 @@ private: QString myClipData; ClipAction *myCurrentAction; QIntDict<ClipCommand> myCommandMapper; + QIntDict<QStringList> myGroupingMapper; KPopupMenu *myMenu; QTimer *myPopupKillTimer; int myPopupKillTimeout; @@ -127,8 +129,13 @@ public: void setRegExp( const QString& r) { myRegExp = QRegExp( r ); } QString regExp() const { return myRegExp.pattern(); } - inline bool matches( const QString& string ) const { - return ( myRegExp.search( string ) != -1 ); + inline bool matches( const QString& string ) { + int res = myRegExp.search( string ) ; + if ( res != -1 ) { + myCapturedTexts = myRegExp.capturedTexts(); + return true; + } + return false; } void setDescription( const QString& d) { myDescription = d; } @@ -147,9 +154,15 @@ public: */ void save( KConfig * ) const; + /** + * Returns the most recent list of matched group backreferences. + * Note: you probably need to call matches() first. + */ + inline const QStringList* capturedTexts() const { return &myCapturedTexts; } private: QRegExp myRegExp; + QStringList myCapturedTexts; QString myDescription; QPtrList<ClipCommand> myCommands; diff --git a/konqueror/about/konq.css b/konqueror/about/konq.css index 735861d9e..db6983bc1 100644 --- a/konqueror/about/konq.css +++ b/konqueror/about/konq.css @@ -18,4 +18,11 @@ background-repeat: no-repeat; } +#searchbarlabel { + font-size: 10pt; + font-style: italic; +} +#searchbarinput { + width: 100%; +} diff --git a/konqueror/about/konq_aboutpage.cc b/konqueror/about/konq_aboutpage.cc index 03da9a060..8a5385697 100644 --- a/konqueror/about/konq_aboutpage.cc +++ b/konqueror/about/konq_aboutpage.cc @@ -11,6 +11,9 @@ #include <kstandarddirs.h> #include <kaction.h> #include <kiconloader.h> +#include <kurifilter.h> +#include <ktrader.h> +#include <kconfig.h> #include <assert.h> #include <qfile.h> @@ -85,8 +88,11 @@ QString KonqAboutPageFactory::loadFile( const QString& file ) QString KonqAboutPageFactory::launch() { + // FIXME: only regenerate launch page if kuriikwsfilterrc changed. + /* if ( s_launch_html ) return *s_launch_html; + */ QString res = loadFile( locate( "data", "konqueror/about/launch.html" )); if ( res.isEmpty() ) @@ -100,6 +106,7 @@ QString KonqAboutPageFactory::launch() QString wastebin_icon_path = iconloader->iconPath("trashcan_full", KIcon::Desktop ); QString applications_icon_path = iconloader->iconPath("kmenu", KIcon::Desktop ); QString settings_icon_path = iconloader->iconPath("kcontrol", KIcon::Desktop ); + QString help_icon_path = iconloader->iconPath("khelpcenter", KIcon::Desktop ); QString home_folder = QDir::homeDirPath(); QString continue_icon_path = QApplication::reverseLayout()?iconloader->iconPath("1leftarrow", KIcon::Small ):iconloader->iconPath("1rightarrow", KIcon::Small ); @@ -109,6 +116,26 @@ QString KonqAboutPageFactory::launch() else res = res.arg( "" ); + // Try to split page in three. If it succeeds, insert the default search into the middle part. + QStringList parts = QStringList::split( "<!--search bar splitter-->", res ); + if ( parts.count() == 3 ) { + KConfig config( "kuriikwsfilterrc", true /*read-only*/, false /*no KDE globals*/ ); + config.setGroup( "General" ); + QString name = config.readEntry("DefaultSearchEngine"); + KService::Ptr service = + KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(name)); + if ( service ) { + QString searchBar = parts[1]; + searchBar = searchBar + .arg( iconSize ).arg( iconSize ) + .arg( service->name() ) + .arg( service->property("Keys").toStringList()[0] ) + ; + res = parts[0] + searchBar + parts[2]; + } + else res = parts[0] + parts[2]; + } + res = res.arg( i18n("Conquer your Desktop!") ) .arg( i18n( "Konqueror" ) ) .arg( i18n("Conquer your Desktop!") ) @@ -139,10 +166,10 @@ QString KonqAboutPageFactory::launch() .arg(iconSize).arg(iconSize) .arg( i18n( "Applications" ) ) .arg( i18n( "Installed programs" ) ) - .arg( settings_icon_path ) + .arg( help_icon_path ) .arg(iconSize).arg(iconSize) - .arg( i18n( "Settings" ) ) - .arg( i18n( "Desktop configuration" ) ) + .arg( i18n( "About Kubuntu" ) ) + .arg( i18n( "<a href=\"help:/kubuntu/\">Kubuntu Documentation</a>" ) ) .arg( continue_icon_path ) .arg( KIcon::SizeSmall ).arg( KIcon::SizeSmall ) .arg( i18n( "Next: An Introduction to Konqueror" ) ) @@ -422,10 +449,23 @@ KonqAboutPage::~KonqAboutPage() bool KonqAboutPage::openURL( const KURL &u ) { - if (u.url() == "about:plugins") - serve( KonqAboutPageFactory::plugins(), "plugins" ); - else serve( KonqAboutPageFactory::launch(), "konqueror" ); - return true; + kdDebug(1202) << "now in KonqAboutPage::openURL( \"" << u.url() << "\" )" << endl; + if ( u.url() == "about:plugins" ) + serve( KonqAboutPageFactory::plugins(), "plugins" ); + else if ( !u.query().isEmpty() ) { + QMap< QString, QString > queryItems = u.queryItems( 0 ); + QMap< QString, QString >::ConstIterator query = queryItems.begin(); + QString newUrl; + if (query.key() == "strigi") { + newUrl = KURIFilter::self()->filteredURI( query.key() + ":?q=" + query.data() ); + } else { + newUrl = KURIFilter::self()->filteredURI( query.key() + ":" + query.data() ); + } + kdDebug(1202) << "scheduleRedirection( 0, \"" << newUrl << "\" )" << endl; + scheduleRedirection( 0, newUrl ); + } + else serve( KonqAboutPageFactory::launch(), "konqueror" ); + return true; } bool KonqAboutPage::openFile() diff --git a/konqueror/about/launch.html b/konqueror/about/launch.html index 80ad01eaa..9acc5d6a9 100644 --- a/konqueror/about/launch.html +++ b/konqueror/about/launch.html @@ -60,6 +60,20 @@ <div id="boxCenter"> <table border="0" align="center"> +<!--search bar argument replacement is performed between the "search bar splitter" lines--> +<!--search bar splitter--> + + <tr> + <form action="about:konqueror"> + <td colspan="2" style="text-align:right;"><label id="searchbarlabel" for="searchbarinput">%2: </label></td> + <td colspan="2"><input id="searchbarinput" name="%3" type="text"></td> + </form> + </tr> + <tr> + <td colspan="4"><div style="width:%1px; height:%1px;"/></td> + </tr> + +<!--search bar splitter--> <tr> <td valign="bottom"> <a href="%1"><img src="%1" height="%1" width="%1" /></a> @@ -96,10 +110,10 @@ <a href="applications:/">%1</a><br><span id="subtext"><nobr>%1</span> </td> <td> - <a href="settings:/"><img src="%1" height="%1" width="%1" /></a> + <a href="help:/kubuntu/about-kubuntu/index.html"><img src="%1" height="%1" width="%1" /></a> </td> <td valign="bottom"> - <a href="settings:/">%1</a><br><span id="subtext"><nobr>%1</span> + <a href="help:/kubuntu/about-kubuntu/index.html">%1</a><br><span id="subtext"><nobr>%1</span> </td> </tr> </table> diff --git a/konqueror/iconview/konq_iconview.desktop b/konqueror/iconview/konq_iconview.desktop index 2d355b771..8f85b9146 100644 --- a/konqueror/iconview/konq_iconview.desktop +++ b/konqueror/iconview/konq_iconview.desktop @@ -85,8 +85,5 @@ X-KDE-Library=konq_iconview X-KDE-BrowserView-AllowAsDefault=true X-KDE-BrowserView-HideFromMenus=true X-KDE-BrowserView-Args=IconView -X-KDE-BrowserView-ModeProperty=viewMode -X-KDE-BrowserView-ModePropertyValue=IconView -X-KDE-BrowserView-Built-Into=konqueror Icon=view_icon InitialPreference=10 diff --git a/konqueror/iconview/konq_multicolumnview.desktop b/konqueror/iconview/konq_multicolumnview.desktop index 94b6c7288..2b3e55dd9 100644 --- a/konqueror/iconview/konq_multicolumnview.desktop +++ b/konqueror/iconview/konq_multicolumnview.desktop @@ -85,8 +85,5 @@ X-KDE-Library=konq_iconview X-KDE-BrowserView-AllowAsDefault=true X-KDE-BrowserView-HideFromMenus=true X-KDE-BrowserView-Args=MultiColumnView -X-KDE-BrowserView-ModeProperty=viewMode -X-KDE-BrowserView-ModePropertyValue=MultiColumnView -X-KDE-BrowserView-Built-Into=konqueror Icon=view_multicolumn InitialPreference=9 diff --git a/konqueror/konq_combo.cc b/konqueror/konq_combo.cc index 2e5279474..4ea68abb3 100644 --- a/konqueror/konq_combo.cc +++ b/konqueror/konq_combo.cc @@ -204,6 +204,7 @@ void KonqCombo::removeDuplicates( int index ) if ( item == url ) removeItem( i ); } + lineEdit()->setCursorPosition( 0 ); } // called via DCOP in all instances diff --git a/konqueror/konq_mainwindow.cc b/konqueror/konq_mainwindow.cc index 071c7e0be..e2e516b39 100644 --- a/konqueror/konq_mainwindow.cc +++ b/konqueror/konq_mainwindow.cc @@ -563,7 +563,7 @@ void KonqMainWindow::openURL( KonqView *_view, const KURL &_url, kdDebug(1202) << "trying openView for " << url << " (serviceType " << serviceType << ")" << endl; if ( ( !serviceType.isEmpty() && serviceType != "application/octet-stream") || - url.url() == "about:konqueror" || url.url() == "about:plugins" ) + url.url().startsWith("about:konqueror") || url.url() == "about:plugins" ) { KService::Ptr offer = KServiceTypeProfile::preferredService(serviceType, "Application"); // If the associated app is konqueror itself, then make sure we try to embed before bailing out. @@ -731,7 +731,7 @@ bool KonqMainWindow::openView( QString serviceType, const KURL &_url, KonqView * QString serviceName; // default: none provided - if ( url.url() == "about:konqueror" || url.url() == "about:plugins" ) + if ( url.url().startsWith("about:konqueror") || url.url() == "about:plugins" ) { serviceType = "KonqAboutPage"; // not KParts/ReadOnlyPart, it fills the Location menu ! :) serviceName = "konq_aboutpage"; @@ -1772,6 +1772,34 @@ void KonqMainWindow::slotReload( KonqView* reloadView ) } } +void KonqMainWindow::slotReloadStop() { + if (m_paReloadStop->icon() == "reload") { + slotReload(); + toggleReloadStopButton(true); + } else { + slotStop(); + toggleReloadStopButton(false); + } +} + +void KonqMainWindow::toggleReloadStopButton(bool isReload) { + //m_paStop = new KAction( i18n( "&Stop" ), "stop", Key_Escape, this, SLOT( slotStop() ), actionCollection(), "stop" ); + if (isReload) { + m_paReloadStop->setIcon("stop"); + m_paReloadStop->setWhatsThis( i18n( "Stop loading the document<p>" + "All network transfers will be stopped and Konqueror will display the content " + "that has been received so far." ) ); + m_paReloadStop->setToolTip( i18n( "Stop loading the document" ) ); + //m_paReloadStop = new KAction( i18n( "&Reload" ), "reload", reloadShortcut, this, SLOT( slotReloadStop() ), actionCollection(), "reload" ); + } else { + m_paReloadStop->setIcon("reload"); + m_paReloadStop->setWhatsThis( i18n( "Reload the currently displayed document<p>" + "This may, for example, be needed to refresh webpages that have been " + "modified since they were loaded, in order to make the changes visible." ) ); + m_paReloadStop->setToolTip( i18n( "Reload the currently displayed document" ) ); + } +} + void KonqMainWindow::slotReloadPopup() { if (m_pWorkingTab) @@ -2196,7 +2224,7 @@ void KonqMainWindow::slotPartActivated( KParts::Part *part ) KService::Ptr serv = KService::serviceByDesktopName( ittb.current()->name() ); if ( serv && viewModeActionKey( serv ) == currentServiceLibrary ) { KToggleAction* ta = static_cast<KToggleAction*>( ittb.current() ); - ta->setChecked( true ); + ta->setChecked( false ); QString servicename = m_currentView->service()->genericName(); if (servicename.isEmpty()) servicename = m_currentView->service()->name(); @@ -3664,6 +3692,7 @@ void KonqMainWindow::startAnimation() //kdDebug(1202) << "KonqMainWindow::startAnimation" << endl; m_paAnimatedLogo->start(); m_paStop->setEnabled( true ); + toggleReloadStopButton( true ); } void KonqMainWindow::stopAnimation() @@ -3671,6 +3700,7 @@ void KonqMainWindow::stopAnimation() //kdDebug(1202) << "KonqMainWindow::stopAnimation" << endl; m_paAnimatedLogo->stop(); m_paStop->setEnabled( false ); + toggleReloadStopButton( false ); } void KonqMainWindow::setUpEnabled( const KURL &url ) @@ -3833,6 +3863,8 @@ void KonqMainWindow::initActions() reloadShortcut.append(KKey(CTRL + Key_R)); m_paReload = new KAction( i18n( "&Reload" ), "reload", reloadShortcut, this, SLOT( slotReload() ), actionCollection(), "reload" ); m_paReloadAllTabs = new KAction( i18n( "&Reload All Tabs" ), "reload_all_tabs", SHIFT+Key_F5, this, SLOT( slotReloadAllTabs() ), actionCollection(), "reload_all_tabs" ); + + m_paReloadStop = new KAction( i18n( "&Reload/Stop" ), "reload", 0, this, SLOT( slotReloadStop() ), actionCollection(), "reload_stop" ); m_paUndo = KStdAction::undo( KonqUndoManager::self(), SLOT( undo() ), actionCollection(), "undo" ); //m_paUndo->setEnabled( KonqUndoManager::self()->undoAvailable() ); @@ -4067,6 +4099,7 @@ void KonqMainWindow::updateToolBarActions( bool pendingAction /*=false*/) { m_paAnimatedLogo->stop(); m_paStop->setEnabled( pendingAction ); //enable/disable based on any pending actions... + toggleReloadStopButton( pendingAction ); } if ( m_currentView && m_currentView->url().isLocalFile() && @@ -4368,6 +4401,7 @@ void KonqMainWindow::enableAllActions( bool enable ) updateViewActions(); // undo, lock, link and other view-dependent actions m_paStop->setEnabled( m_currentView && m_currentView->isLoading() ); + toggleReloadStopButton( m_currentView && m_currentView->isLoading() ); if (m_toggleViewGUIClient) { @@ -5089,7 +5123,6 @@ void KonqMainWindow::updateViewModeActions() bool bIsCurrentView = (*it)->desktopEntryName() == m_currentView->service()->desktopEntryName(); if ( bIsCurrentView ) { - (*mapIt)->setChecked( true ); action->setChecked( true ); } diff --git a/konqueror/konq_mainwindow.h b/konqueror/konq_mainwindow.h index a99c485bf..3dbba5658 100644 --- a/konqueror/konq_mainwindow.h +++ b/konqueror/konq_mainwindow.h @@ -313,6 +313,8 @@ public: static bool isPreloaded() { return s_preloaded; } static void setPreloadedWindow( KonqMainWindow* ); static KonqMainWindow* preloadedWindow() { return s_preloadedWindow; } + + void toggleReloadStopButton(bool isStop); QString currentTitle() const; QString currentURL() const; @@ -375,6 +377,7 @@ public slots: void slotLinkView(); void slotReload( KonqView* view = 0L ); void slotStop(); + void slotReloadStop(); // Go menu void slotUp(); @@ -649,6 +652,8 @@ private: KAction *m_paStop; KAction *m_paRename; + KAction *m_paReloadStop; + KAction *m_paTrash; KAction *m_paDelete; diff --git a/konqueror/listview/konq_detailedlistview.desktop b/konqueror/listview/konq_detailedlistview.desktop index 9dc4938bd..ceb220194 100644 --- a/konqueror/listview/konq_detailedlistview.desktop +++ b/konqueror/listview/konq_detailedlistview.desktop @@ -84,6 +84,5 @@ ServiceTypes=KParts/ReadOnlyPart,Browser/View X-KDE-Library=konq_listview X-KDE-BrowserView-Args=DetailedList X-KDE-BrowserView-HideFromMenus=true -X-KDE-BrowserView-Built-Into=konqueror Icon=view_detailed InitialPreference=7 diff --git a/konqueror/listview/konq_infolistview.desktop b/konqueror/listview/konq_infolistview.desktop index 12186d8f7..bee857315 100644 --- a/konqueror/listview/konq_infolistview.desktop +++ b/konqueror/listview/konq_infolistview.desktop @@ -82,6 +82,5 @@ ServiceTypes=KParts/ReadOnlyPart,Browser/View X-KDE-Library=konq_listview X-KDE-BrowserView-Args=InfoListView X-KDE-BrowserView-HideFromMenus=true -X-KDE-BrowserView-Built-Into=konqueror Icon=view_detailed InitialPreference=7 diff --git a/konqueror/listview/konq_listviewwidget.cc b/konqueror/listview/konq_listviewwidget.cc index f3016b433..7d9231758 100644 --- a/konqueror/listview/konq_listviewwidget.cc +++ b/konqueror/listview/konq_listviewwidget.cc @@ -33,6 +33,7 @@ #include <kurldrag.h> #include <kmessagebox.h> #include <kiconloader.h> +#include <kiconeffect.h> #include <qheader.h> #include <qpainter.h> @@ -405,9 +406,11 @@ void KonqBaseListViewWidget::contentsMousePressEvent( QMouseEvent *e ) { if ( m_rubber ) { - drawRubber(); - delete m_rubber; - m_rubber = 0; + + QRect r( m_rubber->normalize() ); + delete m_rubber; + m_rubber = 0; + repaintContents( r, FALSE ); } delete m_selected; @@ -417,14 +420,15 @@ void KonqBaseListViewWidget::contentsMousePressEvent( QMouseEvent *e ) KonqBaseListViewItem* item = isExecuteArea( vp ) ? static_cast<KonqBaseListViewItem*>( itemAt( vp ) ) : 0L; - if ( item ) + if ( item ) { KListView::contentsMousePressEvent( e ); + } else { if ( e->button() == LeftButton ) { - if ( !( e->state() & ControlButton ) ) - setSelected( itemAt( vp ), false ); m_rubber = new QRect( e->x(), e->y(), 0, 0 ); + clearSelection(); + emit selectionChanged(); m_fileTip->setItem( 0 ); } if ( e->button() != RightButton ) @@ -440,9 +444,11 @@ void KonqBaseListViewWidget::contentsMouseReleaseEvent( QMouseEvent *e ) { if ( m_rubber ) { - drawRubber(); + + QRect r( m_rubber->normalize() ); delete m_rubber; m_rubber = 0; + repaintContents( r, FALSE ); } if ( m_scrollTimer ) @@ -534,23 +540,21 @@ void KonqBaseListViewWidget::leaveEvent( QEvent *e ) KListView::leaveEvent( e ); } -void KonqBaseListViewWidget::drawRubber() +void KonqBaseListViewWidget::drawRubber( QPainter *p ) { if ( !m_rubber ) return; - QPainter p; - p.begin( viewport() ); - p.setRasterOp( NotROP ); - p.setPen( QPen( color0, 1 ) ); - p.setBrush( NoBrush ); + p->setRasterOp( NotROP ); + p->setPen( QPen( color0, 1 ) ); + p->setBrush( NoBrush ); QPoint pt( m_rubber->x(), m_rubber->y() ); pt = contentsToViewport( pt ); - style().drawPrimitive( QStyle::PE_FocusRect, &p, + style().drawPrimitive( QStyle::PE_RubberBand, p, QRect( pt.x(), pt.y(), m_rubber->width(), m_rubber->height() ), colorGroup(), QStyle::Style_Default, colorGroup().base() ); - p.end(); + } void KonqBaseListViewWidget::slotAutoScroll() @@ -566,10 +570,12 @@ void KonqBaseListViewWidget::slotAutoScroll() if ( vc == m_rubber->bottomRight() ) return; + QRect oldRubber = *m_rubber; + const int oldTop = m_rubber->normalize().top(); const int oldBottom = m_rubber->normalize().bottom(); - drawRubber(); + m_rubber->setBottomRight( vc ); QListViewItem *cur = itemAt( QPoint(0,0) ); @@ -577,12 +583,20 @@ void KonqBaseListViewWidget::slotAutoScroll() bool block = signalsBlocked(); blockSignals( true ); + QRect rr; QRect nr = m_rubber->normalize(); + bool changed = FALSE; + if ( cur ) { - QRect rect = itemRect( cur ); - if ( !allColumnsShowFocus() ) + QRect rect; + if ( allColumnsShowFocus() ) + rect = itemRect( cur ); + else { + rect = itemRect( cur ); rect.setWidth( executeArea( cur ) ); + } + rect = QRect( viewportToContents( rect.topLeft() ), viewportToContents( rect.bottomRight() ) ); @@ -606,9 +620,26 @@ void KonqBaseListViewWidget::slotAutoScroll() if ( rect.intersects( nr ) ) { if ( !cur->isSelected() && cur->isSelectable() ) + { setSelected( cur, true ); - } else if ( !m_selected || !m_selected->contains( (KonqBaseListViewItem*)cur ) ) - setSelected( cur, false ); + changed = TRUE; + rr = rr.unite( itemRect( cur ) ); + } + } + else + { + if ( cur->isSelected() ) + { + changed = TRUE; + rr = rr.unite( itemRect( cur ) ); + } + + if ( !m_selected || !m_selected->contains( (KonqBaseListViewItem*)cur ) ) + { + setSelected( cur, false ); + } + } + cur = cur->itemBelow(); if (cur && !allColumnsShowFocus()) @@ -625,9 +656,26 @@ void KonqBaseListViewWidget::slotAutoScroll() if ( rect.intersects( nr ) ) { if ( !cur->isSelected() && cur->isSelectable() ) + { setSelected( cur, true ); - } else if ( !m_selected || !m_selected->contains( (KonqBaseListViewItem*)cur ) ) - setSelected( cur, false ); + changed = TRUE; + rr = rr.unite( itemRect( cur ) ); + } + } + else + { + if ( cur->isSelected() ) + { + changed = TRUE; + rr = rr.unite( itemRect( cur ) ); + } + + if ( !m_selected || !m_selected->contains( (KonqBaseListViewItem*)cur ) ) + { + setSelected( cur, false ); + } + } + cur = cur->itemAbove(); if (cur && !allColumnsShowFocus()) @@ -639,7 +687,31 @@ void KonqBaseListViewWidget::slotAutoScroll() blockSignals( block ); emit selectionChanged(); - drawRubber(); + QRect allRect = oldRubber.normalize(); + if ( changed ) + { + allRect |= rr.normalize(); + } + allRect |= m_rubber->normalize(); + QPoint point = contentsToViewport( allRect.topLeft() ); + allRect = QRect( point.x(), point.y(), allRect.width(), allRect.height() ); + allRect &= viewport()->rect(); + allRect.addCoords( -2, -2, 2, 2 ); + + QPixmap backrubber( viewport()->rect().size() ); + backrubber.fill( viewport(), viewport()->rect().topLeft() ); + + QPainter p( &backrubber ); + p.save(); + drawContentsOffset( &p, + contentsX(), + contentsY(), + contentsX() + allRect.left(), contentsY() + allRect.top(), + allRect.width(), allRect.height() ); + p.restore(); + drawRubber( &p ); + p.end(); + bitBlt( viewport(), allRect.topLeft(), &backrubber, allRect ); const int scroll_margin = 40; ensureVisible( vc.x(), vc.y(), scroll_margin, scroll_margin ); @@ -669,9 +741,12 @@ void KonqBaseListViewWidget::slotAutoScroll() void KonqBaseListViewWidget::viewportPaintEvent( QPaintEvent *e ) { - drawRubber(); + KListView::viewportPaintEvent( e ); - drawRubber(); + + QPainter p( viewport() ); + drawRubber( &p ); + p.end(); } void KonqBaseListViewWidget::viewportResizeEvent(QResizeEvent * e) @@ -904,7 +979,42 @@ void KonqBaseListViewWidget::slotReturnPressed( QListViewItem *_item ) url.cleanPath(); bool isIntoTrash = url.isLocalFile() && url.path(1).startsWith(KGlobalSettings::trashPath()); if ( !isIntoTrash || (isIntoTrash && fileItem->isDir()) ) - m_pBrowserView->lmbClicked( fileItem ); + { + m_pBrowserView->lmbClicked( fileItem ); + + if (_item->pixmap(0) != 0) + { + // Rect of the QListViewItem's pixmap area. + QRect rect = _item->listView()->itemRect(_item); + + // calculate nesting depth + int nestingDepth = 0; + for (QListViewItem *currentItem = _item->parent(); + currentItem != 0; + currentItem = currentItem->parent()) + nestingDepth++; + + // no parent no indent + if (_item->parent() == 0) + nestingDepth = 0; + + // Root decoration means additional indent + if (_item->listView()->rootIsDecorated()) + nestingDepth++; + + // set recalculated rect + rect.setLeft(_item->listView()->itemMargin() + _item->listView()->treeStepSize() * nestingDepth); + rect.setWidth(_item->pixmap(0)->width()); + + // gather pixmap + QPixmap *pix = new QPixmap(*(_item->pixmap(0))); + + // call the icon effect + KIconEffect::visualActivate(viewport(), rect, pix); + + delete(pix); + } + } else KMessageBox::information( 0, i18n("You must take the file out of the trash before being able to use it.") ); } diff --git a/konqueror/listview/konq_listviewwidget.h b/konqueror/listview/konq_listviewwidget.h index bc4161862..d6451e50d 100644 --- a/konqueror/listview/konq_listviewwidget.h +++ b/konqueror/listview/konq_listviewwidget.h @@ -206,7 +206,7 @@ protected: virtual void viewportPaintEvent( QPaintEvent *e ); virtual void viewportResizeEvent( QResizeEvent *e ); - virtual void drawRubber(); + virtual void drawRubber( QPainter * ); virtual void contentsMousePressEvent( QMouseEvent *e ); virtual void contentsMouseReleaseEvent( QMouseEvent *e ); virtual void contentsMouseMoveEvent( QMouseEvent *e ); @@ -246,7 +246,8 @@ protected: QColor m_itemColor; QRect *m_rubber; - + QPixmap *m_backrubber; + bool m_bTopLevelComplete:1; bool m_showIcons:1; bool m_bCaseInsensitive:1; diff --git a/konqueror/listview/konq_textview.desktop b/konqueror/listview/konq_textview.desktop index f5d4e5c98..1a88b242b 100644 --- a/konqueror/listview/konq_textview.desktop +++ b/konqueror/listview/konq_textview.desktop @@ -85,6 +85,5 @@ ServiceTypes=Browser/View X-KDE-Library=konq_listview X-KDE-BrowserView-Args=TextView X-KDE-BrowserView-HideFromMenus=true -X-KDE-BrowserView-Built-Into=konqueror Icon=view_text InitialPreference=6 diff --git a/konqueror/listview/konq_treeview.desktop b/konqueror/listview/konq_treeview.desktop index 3fcce32db..3f9f0890c 100644 --- a/konqueror/listview/konq_treeview.desktop +++ b/konqueror/listview/konq_treeview.desktop @@ -85,6 +85,5 @@ X-KDE-Library=konq_listview X-KDE-BrowserView-Args=MixedTree X-KDE-BrowserView-HideFromMenus=true X-KDE-BrowserView-HierarchicalView=true -X-KDE-BrowserView-Built-Into=konqueror Icon=view_tree InitialPreference=8 diff --git a/konqueror/sidebar/trees/dirtree_module/dirtree_item.cpp b/konqueror/sidebar/trees/dirtree_module/dirtree_item.cpp index 78132010a..7f7ee8849 100644 --- a/konqueror/sidebar/trees/dirtree_module/dirtree_item.cpp +++ b/konqueror/sidebar/trees/dirtree_module/dirtree_item.cpp @@ -105,7 +105,7 @@ bool KonqSidebarDirTreeItem::hasStandardIcon() { // The reason why we can't use KFileItem::iconName() is that it doesn't // take custom icons in .directory files into account - return m_fileItem->determineMimeType()->icon( m_fileItem->url(), m_fileItem->isLocalFile() ) == "folder"; + return m_fileItem->iconName() == "folder"; } void KonqSidebarDirTreeItem::paintCell( QPainter *_painter, const QColorGroup & _cg, int _column, int _width, int _alignment ) diff --git a/konsole/konsole/TEHistory.cpp b/konsole/konsole/TEHistory.cpp index 5a0ee5477..a24635acb 100644 --- a/konsole/konsole/TEHistory.cpp +++ b/konsole/konsole/TEHistory.cpp @@ -207,23 +207,24 @@ void HistoryScrollFile::addLine(bool previousWrapped) // History Scroll Buffer ////////////////////////////////////// HistoryScrollBuffer::HistoryScrollBuffer(unsigned int maxNbLines) : HistoryScroll(new HistoryTypeBuffer(maxNbLines)), - m_histBuffer(maxNbLines), - m_wrappedLine(maxNbLines), m_maxNbLines(maxNbLines), m_nbLines(0), - m_arrayIndex(maxNbLines - 1) + m_arrayIndex(0), + m_buffFilled(false) { + m_histBuffer.setAutoDelete(true); + m_histBuffer.resize(maxNbLines); + m_wrappedLine.resize(maxNbLines); } HistoryScrollBuffer::~HistoryScrollBuffer() { - for(size_t line = 0; line < m_nbLines; ++line) { - delete m_histBuffer[adjustLineNb(line)]; - } } void HistoryScrollBuffer::addCells(ca a[], int count) { + //unsigned int nbLines = countLines(bytes, len); + histline* newLine = new histline; newLine->duplicate(a, count); @@ -231,15 +232,45 @@ void HistoryScrollBuffer::addCells(ca a[], int count) ++m_arrayIndex; if (m_arrayIndex >= m_maxNbLines) { m_arrayIndex = 0; - } + m_buffFilled = true; + } - if (m_nbLines < m_maxNbLines) ++m_nbLines; + // FIXME: See BR96605 + if (m_nbLines < m_maxNbLines - 1) ++m_nbLines; - delete m_histBuffer[m_arrayIndex]; + // m_histBuffer.remove(m_arrayIndex); // not necessary m_histBuffer.insert(m_arrayIndex, newLine); m_wrappedLine.clearBit(m_arrayIndex); } +void HistoryScrollBuffer::normalize() +{ + if (!m_buffFilled || !m_arrayIndex) return; + QPtrVector<histline> newHistBuffer; + newHistBuffer.resize(m_maxNbLines); + QBitArray newWrappedLine; + newWrappedLine.resize(m_maxNbLines); + for(int i = 0; i < (int) m_maxNbLines-2; i++) + { + int lineno = adjustLineNb(i); + newHistBuffer.insert(i+1, m_histBuffer[lineno]); + newWrappedLine.setBit(i+1, m_wrappedLine[lineno]); + } + m_histBuffer.setAutoDelete(false); + // Qt 2.3: QVector copy assignment is buggy :-( + // m_histBuffer = newHistBuffer; + for(int i = 0; i < (int) m_maxNbLines; i++) + { + m_histBuffer.insert(i, newHistBuffer[i]); + m_wrappedLine.setBit(i, newWrappedLine[i]); + } + m_histBuffer.setAutoDelete(true); + + m_arrayIndex = m_maxNbLines; + m_buffFilled = false; + m_nbLines = m_maxNbLines-2; +} + void HistoryScrollBuffer::addLine(bool previousWrapped) { m_wrappedLine.setBit(m_arrayIndex,previousWrapped); @@ -284,40 +315,19 @@ void HistoryScrollBuffer::getCells(int lineno, int colno, int count, ca res[]) return; } - assert(colno <= (int) l->size() - count); + assert((colno < (int) l->size()) || (count == 0)); memcpy(res, l->data() + colno, count * sizeof(ca)); } void HistoryScrollBuffer::setMaxNbLines(unsigned int nbLines) { - QPtrVector<histline> newHistBuffer(nbLines); - QBitArray newWrappedLine(nbLines); - - size_t preservedLines = (nbLines > m_nbLines ? m_nbLines : nbLines); //min - - // delete any lines that will be lost - size_t lineOld; - for(lineOld = 0; lineOld < m_nbLines - preservedLines; ++lineOld) { - delete m_histBuffer[adjustLineNb(lineOld)]; - } - - // copy the lines to new arrays - size_t indexNew = 0; - while(indexNew < preservedLines) { - newHistBuffer.insert(indexNew, m_histBuffer[adjustLineNb(lineOld)]); - newWrappedLine.setBit(indexNew, m_wrappedLine[adjustLineNb(lineOld)]); - ++lineOld; - ++indexNew; - } - m_arrayIndex = preservedLines - 1; - - m_histBuffer = newHistBuffer; - m_wrappedLine = newWrappedLine; - + normalize(); m_maxNbLines = nbLines; - if (m_nbLines > m_maxNbLines) - m_nbLines = m_maxNbLines; + m_histBuffer.resize(m_maxNbLines); + m_wrappedLine.resize(m_maxNbLines); + if (m_nbLines > m_maxNbLines - 2) + m_nbLines = m_maxNbLines -2; delete m_histType; m_histType = new HistoryTypeBuffer(nbLines); @@ -325,10 +335,10 @@ void HistoryScrollBuffer::setMaxNbLines(unsigned int nbLines) int HistoryScrollBuffer::adjustLineNb(int lineno) { - // lineno = 0: oldest line - // lineno = getLines() - 1: newest line - - return (m_arrayIndex + lineno - (m_nbLines - 1) + m_maxNbLines) % m_maxNbLines; + if (m_buffFilled) + return (lineno + m_arrayIndex + 2) % m_maxNbLines; + else + return lineno ? lineno + 1 : 0; } diff --git a/konsole/konsole/TEHistory.h b/konsole/konsole/TEHistory.h index c8fa2f379..446611e0a 100644 --- a/konsole/konsole/TEHistory.h +++ b/konsole/konsole/TEHistory.h @@ -142,11 +142,16 @@ public: private: int adjustLineNb(int lineno); + // Normalize buffer so that the size can be changed. + void normalize(); + + bool m_hasScroll; QPtrVector<histline> m_histBuffer; QBitArray m_wrappedLine; unsigned int m_maxNbLines; unsigned int m_nbLines; unsigned int m_arrayIndex; + bool m_buffFilled; }; diff --git a/konsole/konsole/TEPty.h b/konsole/konsole/TEPty.h index 294fde8c7..1597d44d8 100644 --- a/konsole/konsole/TEPty.h +++ b/konsole/konsole/TEPty.h @@ -39,6 +39,13 @@ Q_OBJECT ~TEPty(); public: + bool setPtyFd(int p) { + bool res = pty()->setPty(p); + setupCommunication((Communication)(Stdin|Stdout)); + commSetupDoneP(); + runs = true; + return res; + }; /*! * having a `run' separate from the constructor allows to make diff --git a/konsole/konsole/keytrans.cpp b/konsole/konsole/keytrans.cpp index 7632520ba..f0c8311a7 100644 --- a/konsole/konsole/keytrans.cpp +++ b/konsole/konsole/keytrans.cpp @@ -140,10 +140,10 @@ bool KeyTrans::findEntry(int key, int bits, int* cmd, const char** txt, int* len if ((*cmd==CMD_send) && it.current()->anymodspecified() && (*len < 16)) { static char buf[16]; - char *c, mask = '1' + BITS(0, bits&(1<<BITS_Shift)) + - BITS(1, bits&(1<<BITS_Alt)) + BITS(2, bits&(1<<BITS_Control)); + char *c; + char mask = '1' + BITS(0, bits&(1<<BITS_Shift)) + BITS(1, bits&(1<<BITS_Alt)) + BITS(2, bits&(1<<BITS_Control)); strcpy(buf, it.current()->txt.ascii()); - c = strchr(buf, '*'); + c = (char*)strchr(buf, '*'); if (c) *c = mask; *txt = buf; } diff --git a/konsole/konsole/konsole.cpp b/konsole/konsole/konsole.cpp index 2f9abdf52..2b85b6f39 100644 --- a/konsole/konsole/konsole.cpp +++ b/konsole/konsole/konsole.cpp @@ -3345,8 +3345,8 @@ void Konsole::addSessionCommand(const QString &path) // try to locate the binary QString exec= co->readPathEntry("Exec"); - if (exec.startsWith("su -c \'")) { - exec = exec.mid(7,exec.length()-8); + if (exec.startsWith("sudo su -c \'")) { + exec = exec.mid(12,exec.length()-13); } exec = KRun::binaryName(exec, false); diff --git a/konsole/konsole/konsole_part.cpp b/konsole/konsole/konsole_part.cpp index bfb183935..68ca36024 100644 --- a/konsole/konsole/konsole_part.cpp +++ b/konsole/konsole/konsole_part.cpp @@ -1064,6 +1064,16 @@ void konsolePart::startProgram( const QString& program, se->run(); } +bool konsolePart::setPtyFd( int master_pty ) +{ + kdDebug(1211) << "konsolePart::setPtyFd " << master_pty << endl; + TEPty *pty = new TEPty(); + pty->setPtyFd(master_pty); + if ( !se ) + newSession(); + se->setPty(pty); +} + void konsolePart::newSession() { if ( se ) delete se; diff --git a/konsole/konsole/konsole_part.h b/konsole/konsole/konsole_part.h index 6f410d3c3..5cff68c4e 100644 --- a/konsole/konsole/konsole_part.h +++ b/konsole/konsole/konsole_part.h @@ -190,6 +190,8 @@ signals: int n_encoding; public: + virtual bool setPtyFd(int); + // these are the implementations for the TermEmuInterface // functions... void startProgram( const QString& program, diff --git a/konsole/konsole/konsole_wcwidth.cpp b/konsole/konsole/konsole_wcwidth.cpp index eeb82f4a2..1592e2de3 100644 --- a/konsole/konsole/konsole_wcwidth.cpp +++ b/konsole/konsole/konsole_wcwidth.cpp @@ -9,6 +9,10 @@ #include "konsole_wcwidth.h" +#include <stdlib.h> // for getenv() + + + struct interval { unsigned short first; unsigned short last; @@ -65,7 +69,7 @@ static int bisearch(Q_UINT16 ucs, const struct interval *table, int max) { * in ISO 10646. */ -int konsole_wcwidth(Q_UINT16 ucs) +int konsole_wcwidth_normal(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ static const struct interval combining[] = { @@ -131,7 +135,6 @@ int konsole_wcwidth(Q_UINT16 ucs) (ucs >= 0x20000 && ucs <= 0x2ffff) */)); } -#if 0 /* * The following function is the same as konsole_wcwidth(), except that * spacing characters in the East Asian Ambiguous (A) category as @@ -202,15 +205,31 @@ int konsole_wcwidth_cjk(Q_UINT16 ucs) sizeof(ambiguous) / sizeof(struct interval) - 1)) return 2; - return konsole_wcwidth(ucs); + return konsole_wcwidth_normal(ucs); } -#endif // single byte char: +1, multi byte char: +2 int string_width( const QString &txt ) { int w = 0; - for ( uint i = 0; i < txt.length(); ++i ) - w += konsole_wcwidth( txt[ i ].unicode() ); + + for ( uint i = 1; i < txt.length(); ++i ) { + w += konsole_wcwidth(txt[i].unicode()); + } return w; } + + +int konsole_wcwidth(Q_UINT16 ucs) { + + static int use_wcwidth_cjk = (getenv("KONSOLE_WCWIDTH_CJK")) ? 1: 0; + + if (use_wcwidth_cjk) { + return konsole_wcwidth_cjk(ucs); + } else { + return konsole_wcwidth_normal(ucs); + } + +} + + diff --git a/konsole/konsole/konsole_wcwidth.h b/konsole/konsole/konsole_wcwidth.h index 274fc5b7d..15f6ef9a8 100644 --- a/konsole/konsole/konsole_wcwidth.h +++ b/konsole/konsole/konsole_wcwidth.h @@ -10,9 +10,7 @@ #include <qstring.h> int konsole_wcwidth(Q_UINT16 ucs); -#if 0 -int konsole_wcwidth_cjk(Q_UINT16 ucs); -#endif +//int konsole_wcwidth_cjk(Q_UINT16 ucs); int string_width( const QString &txt ); diff --git a/konsole/other/su.desktop b/konsole/other/su.desktop index 1a2b89844..5d7b5287e 100644 --- a/konsole/other/su.desktop +++ b/konsole/other/su.desktop @@ -123,7 +123,7 @@ Comment[vi]=Mở một Trình giao diện Gốc mới Comment[wa]=Novea shell root Comment[zh_CN]=新建 Root Shell Comment[zh_TW]=新增 Root Shell -Exec=su - +Exec=sudo su - Schema=BlackOnLightYellow.schema #Schema=Linux.schema #VGA diff --git a/konsole/other/sumc.desktop b/konsole/other/sumc.desktop index 04daff141..b8a6ef535 100644 --- a/konsole/other/sumc.desktop +++ b/konsole/other/sumc.desktop @@ -139,7 +139,7 @@ Comment[wa]=Novea «Midnight Commander» e môde root Comment[zh_CN]=新建 Root Midnight Commander Comment[zh_TW]=新增 Root Midnight Commander Comment[zu]=Umyaleli Waphakathi nobusuku Wempande Entsha -Exec=su -c 'mc -c' +Exec=sudo su -c 'mc -c' Schema=BlackOnLightYellow.schema #VGA #Font=6 diff --git a/ksmserver/Makefile.am b/ksmserver/Makefile.am index 00ce998c8..62f9d8976 100644 --- a/ksmserver/Makefile.am +++ b/ksmserver/Makefile.am @@ -17,7 +17,7 @@ SUBDIRS = . -INCLUDES= -I$(top_srcdir)/kdmlib $(all_includes) +INCLUDES= -I$(top_srcdir)/kdmlib $(all_includes) $(HAL_INCS) $(DBUS_INCS) bin_PROGRAMS = lib_LTLIBRARIES = @@ -31,7 +31,7 @@ ksmserver_la_SOURCES = main.cpp server.cpp shutdowndlg.cpp \ KSMServerInterface.skel server.skel ksmserver_la_LDFLAGS = $(all_libraries) -avoid-version -module -ksmserver_la_LIBADD = ../kdmlib/libdmctl.la $(LIB_KDEUI) +ksmserver_la_LIBADD = ../kdmlib/libdmctl.la $(LIB_KDEUI) $(HAL_LIBS) $(DBUS_LIBS) picsdir = $(kde_datadir)/ksmserver/pics pics_DATA = shutdownkonq.png @@ -44,7 +44,7 @@ updatedir = $(kde_datadir)/kconf_update EXTRA_PROGRAMS = testsh testsh_SOURCES = test.cpp testsh_LDFLAGS = $(all_libraries) $(KDE_RPATH) -testsh_LDADD = $(LIB_KDEUI) shutdowndlg.lo ../kdmlib/libdmctl.la +testsh_LDADD = $(LIB_KDEUI) shutdowndlg.lo ../kdmlib/libdmctl.la $(HAL_LIBS) $(DBUS_LIBS) messages: $(XGETTEXT) *.cpp -o $(podir)/ksmserver.pot diff --git a/ksmserver/legacy.cpp b/ksmserver/legacy.cpp index ca198a212..464ded3d8 100644 --- a/ksmserver/legacy.cpp +++ b/ksmserver/legacy.cpp @@ -358,7 +358,7 @@ QString KSMServer::windowWmClientMachine(WId w) hostnamebuf[sizeof(hostnamebuf)-1] = 0; if (result == hostnamebuf) result = "localhost"; - if(char *dot = strchr(hostnamebuf, '.')) { + if(char *dot = (char*)strchr(hostnamebuf, '.')) { *dot = '\0'; if(result == hostnamebuf) result = "localhost"; diff --git a/ksmserver/server.cpp b/ksmserver/server.cpp index 2fcb83785..1bcdea9ac 100644 --- a/ksmserver/server.cpp +++ b/ksmserver/server.cpp @@ -366,12 +366,12 @@ Status SetAuthentication_local (int count, IceListenObj *listenObjs) for (i = 0; i < count; i ++) { char *prot = IceGetListenConnectionString(listenObjs[i]); if (!prot) continue; - char *host = strchr(prot, '/'); + char *host = (char*)strchr(prot, '/'); char *sock = 0; if (host) { *host=0; host++; - sock = strchr(host, ':'); + sock = (char*)strchr(host, ':'); if (sock) { *sock = 0; sock++; diff --git a/ksmserver/shutdowndlg.cpp b/ksmserver/shutdowndlg.cpp index 06bc03c4c..814736b96 100644 --- a/ksmserver/shutdowndlg.cpp +++ b/ksmserver/shutdowndlg.cpp @@ -20,15 +20,20 @@ Copyright (C) 2000 Matthias Ettrich <[email protected]> #include <qmessagebox.h> #include <qbuttongroup.h> #include <qiconset.h> +#include <qpixmap.h> #include <qpopupmenu.h> #include <qtooltip.h> #include <qimage.h> +#include <qpainter.h> +#include <qfontmetrics.h> +#include <qregexp.h> #include <klocale.h> #include <kapplication.h> #include <kdebug.h> #include <kpushbutton.h> #include <kstdguiitem.h> +#include <kguiitem.h> #include <kiconloader.h> #include <kglobalsettings.h> #include <kwin.h> @@ -37,12 +42,19 @@ Copyright (C) 2000 Matthias Ettrich <[email protected]> #include <kimageeffect.h> #include <kdialog.h> #include <kseparator.h> +#include <kconfig.h> + +#include <dcopclient.h> +#include <dcopref.h> #include <sys/types.h> #include <sys/utsname.h> #include <unistd.h> #include <stdlib.h> +#include <math.h> #include <dmctl.h> +#include <kaction.h> + #include <X11/Xlib.h> @@ -52,35 +64,195 @@ KSMShutdownFeedback * KSMShutdownFeedback::s_pSelf = 0L; KSMShutdownFeedback::KSMShutdownFeedback() : QWidget( 0L, "feedbackwidget", WType_Popup ), - m_currentY( 0 ) + m_currentY( 0 ), + m_grayOpacity( 0.0f ), + m_compensation( 0.0f ), + m_fadeBackwards( FALSE ), + m_unfadedImage(), + m_grayImage(), + m_fadeTime(), + m_pmio() + { - setBackgroundMode( QWidget::NoBackground ); - setGeometry( QApplication::desktop()->geometry() ); - QTimer::singleShot( 10, this, SLOT( slotPaintEffect() ) ); - m_root.resize( width(), height() ); + m_grayImage = QImage::QImage(); + m_unfadedImage = QImage::QImage(); + resize(0, 0); + setShown(true); + QTimer::singleShot( 500, this, SLOT( slotPaintEffect() ) ); } +// called after stopping shutdown-feedback -> smooth fade-back to color-mode +void KSMShutdownFeedback::fadeBack( void ) +{ + m_fadeTime.restart(); + m_fadeBackwards = TRUE; + // its possible that we have to fade back, before all is completely gray, so we cannot start + // with completely gray when fading back... + m_compensation = 1.0f - m_grayOpacity; + // wait until we're completely back in color-mode... + while ( m_grayOpacity > 0.0f ) + slotPaintEffect(); +} void KSMShutdownFeedback::slotPaintEffect() { - if ( m_currentY >= height() ) { - if ( backgroundMode() == QWidget::NoBackground ) { - setBackgroundMode( QWidget::NoBackground ); - setBackgroundPixmap( m_root ); - } - return; + // determine which fade to use + if (KConfigGroup(KGlobal::config(), "Logout").readBoolEntry("doFancyLogout", true)) + { + + float doFancyLogoutAdditionalDarkness = (float)KConfigGroup(KGlobal::config(), "Logout").readDoubleNumEntry("doFancyLogoutAdditionalDarkness", 0.6); + + float doFancyLogoutFadeTime = (float)KConfigGroup(KGlobal::config(), "Logout").readDoubleNumEntry("doFancyLogoutFadeTime", 4000); + + float doFancyLogoutFadeBackTime = (float)KConfigGroup(KGlobal::config(), "Logout").readDoubleNumEntry("doFancyLogoutFadeBackTime", 1000); + + // if slotPaintEffect() is called first time, we have to initialize the gray image + // we also could do that in the constructor, but then the displaying of the + // logout-UI would be too much delayed... + if ( m_grayImage.isNull() ) + { + setBackgroundMode( QWidget::NoBackground ); + setGeometry( QApplication::desktop()->geometry() ); + m_root.resize( width(), height() ); // for the default logout + + m_grayImage = QPixmap::grabWindow(qt_xrootwin(), 0, 0, QApplication::desktop()->width(), QApplication::desktop()->height()).convertToImage(); + m_unfadedImage = m_grayImage.copy(); + register uchar * r = m_grayImage.bits(); + register uchar * g = m_grayImage.bits() + 1; + register uchar * b = m_grayImage.bits() + 2; + uchar * end = m_grayImage.bits() + m_grayImage.numBytes(); + + while ( r != end ) { + *r = *g = *b = (uchar) ( ( (*r)*11 + ((*g)<<4) + (*b)*5 ) * doFancyLogoutAdditionalDarkness / 32.0f ); + r += 4; + g += 4; + b += 4; + } + // start timer which is used for cpu-speed-independent fading + m_fadeTime.start(); + m_rowsDone = 0; + } + + // return if fading is completely done... + if ( ( m_grayOpacity >= 1.0f && m_fadeBackwards == FALSE ) || ( m_grayOpacity <= 0.0f && m_fadeBackwards == TRUE ) ) + return; + + + if ( m_fadeBackwards == FALSE ) + { + m_grayOpacity = m_fadeTime.elapsed() / doFancyLogoutFadeTime; + if ( m_grayOpacity > 1.0f ) + m_grayOpacity = 1.0f; + } + else + { + m_grayOpacity = 1.0f - m_fadeTime.elapsed() / doFancyLogoutFadeBackTime - m_compensation; + if ( m_grayOpacity < 0.0f ) + m_grayOpacity = 0.0f; + } + + const int imgWidth = m_unfadedImage.width(); + int imgHeight = m_unfadedImage.height(); + int heightUnit = imgHeight / 3; + if( heightUnit < 1 ) + heightUnit = 1; + + int y1 = static_cast<int>( imgHeight*m_grayOpacity - heightUnit + m_grayOpacity*heightUnit*2.0f ); + if( y1 > imgHeight ) + y1 = imgHeight; + + int y2 = y1+heightUnit; + if( y2 > imgHeight ) + y2 = imgHeight; + + if( m_fadeBackwards == FALSE ) + { + if( y1 > 0 && y1 < imgHeight && y1-m_rowsDone > 0 && m_rowsDone < imgHeight ) + { + QImage img( imgWidth, y1-m_rowsDone, 32 ); + memcpy( img.bits(), m_grayImage.scanLine( m_rowsDone ), imgWidth*(y1-m_rowsDone)*4 ); + // conversion is slow as hell if desktop-depth != 24bpp... + //Pixmap pm = m_pmio.convertToPixmap( img ); + //bitBlt( this, 0, m_rowsDone, &pm ); +// QImage pm = m_pmio.convertToImage( img ); + bitBlt( this, 0, m_rowsDone, &img ); + m_rowsDone = y1; + } + } + else + { + // when fading back we have to blit area which isnt gray anymore to unfaded image + if( y2 > 0 && y2 < imgHeight && m_rowsDone > y2 ) + { + QImage img( imgWidth, m_rowsDone-y2, 32 ); + memcpy( img.bits(), m_unfadedImage.scanLine( y2 ), imgWidth*(m_rowsDone-y2)*4 ); + // conversion is slow as hell if desktop-depth != 24bpp... + //QPixmap pm = m_pmio.convertToPixmap( img ); + //bitBlt( this, 0, y2, &pm ); + bitBlt( this, 0, y2, &img ); + m_rowsDone = y2; + } + } + + int start_y1 = y1; + if( start_y1 < 0 ) + start_y1 = 0; + if( y2 > start_y1 ) + { + QImage img( imgWidth, y2-start_y1, 32 ); + memcpy( img.bits(), m_grayImage.scanLine( start_y1 ), ( y2-start_y1 ) * imgWidth * 4 ); + register uchar * rs = m_unfadedImage.scanLine( start_y1 ); + register uchar * gs = rs + 1; + register uchar * bs = gs + 1; + register uchar * rd = img.bits(); + register uchar * gd = rd + 1; + register uchar * bd = gd + 1; + for( int y = start_y1; y < y2; ++y ) + { + // linear gradients look bad, so use cos-function + short int opac = static_cast<short int>( 128 - cosf( M_PI*(y-y1)/heightUnit )*128.0f ); + for( short int x = 0; x < imgWidth; ++x ) + { + *rd += ( ( ( *rs - *rd ) * opac ) >> 8 ); + rs += 4; rd += 4; + *gd += ( ( ( *gs - *gd ) * opac ) >> 8 ); + gs += 4; gd += 4; + *bd += ( ( ( *bs - *bd ) * opac ) >> 8 ); + bs += 4; bd += 4; + } + } + // conversion is slow as hell if desktop-depth != 24bpp... + //QPixmap pm = m_pmio.convertToPixmap( img ); + //bitBlt( this, 0, start_y1, &pm ); + bitBlt( this, 0, start_y1, &img ); + } + + QTimer::singleShot( 5, this, SLOT( slotPaintEffect() ) ); + + } + // standard logout fade + else + { + if ( m_currentY >= height() ) { + if ( backgroundMode() == QWidget::NoBackground ) { + setBackgroundMode( QWidget::NoBackground ); + setBackgroundPixmap( m_root ); + } + return; + } + + KPixmap pixmap; + pixmap = QPixmap::grabWindow( qt_xrootwin(), 0, m_currentY, width(), 10 ); + QImage image = pixmap.convertToImage(); + KImageEffect::blend( Qt::black, image, 0.4 ); + KImageEffect::toGray( image, true ); + pixmap.convertFromImage( image ); + bitBlt( this, 0, m_currentY, &pixmap ); + bitBlt( &m_root, 0, m_currentY, &pixmap ); + m_currentY += 10; + QTimer::singleShot( 1, this, SLOT( slotPaintEffect() ) ); } - KPixmap pixmap; - pixmap = QPixmap::grabWindow( qt_xrootwin(), 0, m_currentY, width(), 10 ); - QImage image = pixmap.convertToImage(); - KImageEffect::blend( Qt::black, image, 0.4 ); - KImageEffect::toGray( image, true ); - pixmap.convertFromImage( image ); - bitBlt( this, 0, m_currentY, &pixmap ); - bitBlt( &m_root, 0, m_currentY, &pixmap ); - m_currentY += 10; - QTimer::singleShot( 1, this, SLOT( slotPaintEffect() ) ); } ////// @@ -90,97 +262,363 @@ KSMShutdownDlg::KSMShutdownDlg( QWidget* parent, : QDialog( parent, 0, TRUE, WType_Popup ), targets(0) // this is a WType_Popup on purpose. Do not change that! Not // having a popup here has severe side effects. + { QVBoxLayout* vbox = new QVBoxLayout( this ); + + QFrame* frame = new QFrame( this ); frame->setFrameStyle( QFrame::StyledPanel | QFrame::Raised ); frame->setLineWidth( style().pixelMetric( QStyle::PM_DefaultFrameWidth, frame ) ); + // we need to set the minimum size for the logout box, since it + // gets too small if there isn't all options available + frame->setMinimumWidth(400); vbox->addWidget( frame ); vbox = new QVBoxLayout( frame, 2 * KDialog::marginHint(), 2 * KDialog::spacingHint() ); - QLabel* label = new QLabel( i18n("End Session for \"%1\"").arg(KUser().loginName()), frame ); - QFont fnt = label->font(); - fnt.setBold( true ); - fnt.setPointSize( fnt.pointSize() * 3 / 2 ); - label->setFont( fnt ); - vbox->addWidget( label, 0, AlignHCenter ); - - QHBoxLayout* hbox = new QHBoxLayout( vbox, 2 * KDialog::spacingHint() ); - - // konqy - QFrame* lfrm = new QFrame( frame ); - lfrm->setFrameStyle( QFrame::Panel | QFrame::Sunken ); - hbox->addWidget( lfrm, AlignCenter ); - - QLabel* icon = new QLabel( lfrm ); - icon->setPixmap( UserIcon( "shutdownkonq" ) ); - lfrm->setFixedSize( icon->sizeHint()); - icon->setFixedSize( icon->sizeHint()); - - // right column (buttons) - QVBoxLayout* buttonlay = new QVBoxLayout( hbox, 2 * KDialog::spacingHint() ); - buttonlay->setAlignment( Qt::AlignHCenter ); - - buttonlay->addStretch( 1 ); - - // End session - KPushButton* btnLogout = new KPushButton( KGuiItem( i18n("&End Current Session"), "undo"), frame ); - QFont btnFont = btnLogout->font(); - buttonlay->addWidget( btnLogout ); - connect(btnLogout, SIGNAL(clicked()), SLOT(slotLogout())); - - if (maysd) { - - // Shutdown - KPushButton* btnHalt = new KPushButton( KGuiItem( i18n("&Turn Off Computer"), "exit"), frame ); - btnHalt->setFont( btnFont ); - buttonlay->addWidget( btnHalt ); - connect(btnHalt, SIGNAL(clicked()), SLOT(slotHalt())); - if ( sdtype == KApplication::ShutdownTypeHalt ) - btnHalt->setFocus(); - - // Reboot - KSMDelayedPushButton* btnReboot = new KSMDelayedPushButton( KGuiItem( i18n("&Restart Computer"), "reload"), frame ); - btnReboot->setFont( btnFont ); - buttonlay->addWidget( btnReboot ); - - connect(btnReboot, SIGNAL(clicked()), SLOT(slotReboot())); - if ( sdtype == KApplication::ShutdownTypeReboot ) - btnReboot->setFocus(); - - int def, cur; - if ( DM().bootOptions( rebootOptions, def, cur ) ) { - targets = new QPopupMenu( frame ); - if ( cur == -1 ) - cur = def; - - int index = 0; - for (QStringList::ConstIterator it = rebootOptions.begin(); it != rebootOptions.end(); ++it, ++index) - { - QString label = (*it); - label=label.replace('&',"&&"); - if (index == cur) - targets->insertItem( label + i18n("current option in boot loader", " (current)"), index); - else - targets->insertItem( label, index ); - } + // default factor + bool doUbuntuLogout = KConfigGroup(KGlobal::config(), "Logout").readBoolEntry("doUbuntuLogout", false); + + // slighty more space for the new logout + int factor = 2; - btnReboot->setPopup(targets); - connect( targets, SIGNAL(activated(int)), SLOT(slotReboot(int)) ); + if(doUbuntuLogout) + { + factor = 8; } - } + else { + QLabel* label = new QLabel( i18n("End Session for \"%1\"").arg(KUser().loginName()), frame ); + QFont fnt = label->font(); + fnt.setBold( true ); + fnt.setPointSize( fnt.pointSize() * 3 / 2 ); + label->setFont( fnt ); + vbox->addWidget( label, 0, AlignHCenter ); + } + + // for the basic layout, within this box either the ubuntu dialog or + // standard konqy+buttons will be placed. + QHBoxLayout* hbox = new QHBoxLayout( vbox, factor * KDialog::spacingHint() ); + + // from here on we have to adapt to the two different dialogs + QFrame* lfrm; + QVBoxLayout* buttonlay; + QHBoxLayout* hbuttonbox; + QFont btnFont; + + if(doUbuntuLogout) + { + // first line of buttons + hbuttonbox = new QHBoxLayout( hbox, factor * KDialog::spacingHint() ); + hbuttonbox->setAlignment( Qt::AlignHCenter ); + // End session + FlatButton* btnLogout = new FlatButton( frame ); + btnLogout->setTextLabel( i18n("&Log out"), false ); + btnLogout->setPixmap( DesktopIcon( "back") ); + int i = btnLogout->textLabel().find( QRegExp("\\&"), 0 ); // i == 1 + btnLogout->setAccel( "ALT+" + btnLogout->textLabel().lower()[i+1] ) ; + hbuttonbox->addWidget ( btnLogout ); + connect(btnLogout, SIGNAL(clicked()), SLOT(slotLogout())); - buttonlay->addStretch( 1 ); + } + else + { + + // konqy + lfrm = new QFrame( frame ); + lfrm->setFrameStyle( QFrame::Panel | QFrame::Sunken ); + hbox->addWidget( lfrm, AlignCenter ); + + buttonlay = new QVBoxLayout( hbox, factor * KDialog::spacingHint() ); + buttonlay->setAlignment( Qt::AlignHCenter ); + + QLabel* icon = new QLabel( lfrm ); + icon->setPixmap( UserIcon( "shutdownkonq" ) ); + lfrm->setFixedSize( icon->sizeHint()); + icon->setFixedSize( icon->sizeHint()); + + buttonlay->addStretch( 1 ); + // End session + KPushButton* btnLogout = new KPushButton( KGuiItem( i18n("&End Current Session"), "undo"), frame ); + btnFont = btnLogout->font(); + buttonlay->addWidget( btnLogout ); + connect(btnLogout, SIGNAL(clicked()), SLOT(slotLogout())); + } - // Separator - buttonlay->addWidget( new KSeparator( frame ) ); + + + m_halCtx = NULL; + + if (maysd) { + + // respect lock on resume & disable suspend/hibernate settings + // from power-manager + KConfig config("power-managerrc"); + bool disableSuspend = config.readBoolEntry("disableSuspend", false); + bool disableHibernate = config.readBoolEntry("disableHibernate", false); + m_lockOnResume = config.readBoolEntry("lockOnResume", true); + + bool canSuspend = false; + bool canHibernate = false; + + // Query HAL for suspend/resume support + m_halCtx = libhal_ctx_new(); + + DBusError error; + dbus_error_init(&error); + m_dbusConn = dbus_connection_open_private(DBUS_SYSTEM_BUS, &error); + if (!m_dbusConn) + { + dbus_error_free(&error); + libhal_ctx_free(m_halCtx); + m_halCtx = NULL; + } + else + { + dbus_bus_register(m_dbusConn, &error); + if (dbus_error_is_set(&error)) + { + dbus_error_free(&error); + libhal_ctx_free(m_halCtx); + m_dbusConn = NULL; + m_halCtx = NULL; + } + else + { + libhal_ctx_set_dbus_connection(m_halCtx, m_dbusConn); + if (!libhal_ctx_init(m_halCtx, &error)) + { + if (dbus_error_is_set(&error)) + dbus_error_free(&error); + libhal_ctx_free(m_halCtx); + m_dbusConn = NULL; + m_halCtx = NULL; + } + } + } + + if (m_halCtx) + { + if (libhal_device_get_property_bool(m_halCtx, + "/org/freedesktop/Hal/devices/computer", + "power_management.can_suspend", + NULL)) + { + canSuspend = true; + } + + if (libhal_device_get_property_bool(m_halCtx, + "/org/freedesktop/Hal/devices/computer", + "power_management.can_hibernate", + NULL)) + { + canHibernate = true; + } + } + + + if(doUbuntuLogout) { + + if (canSuspend && !disableSuspend) + { + // Suspend + FlatButton* btnSuspend = new FlatButton( frame ); + btnSuspend->setTextLabel( i18n("&Suspend"), false ); + btnSuspend->setPixmap( DesktopIcon( "suspend") ); + int i = btnSuspend->textLabel().find( QRegExp("\\&"), 0 ); // i == 1 + btnSuspend->setAccel( "ALT+" + btnSuspend->textLabel().lower()[i+1] ) ; + hbuttonbox->addWidget ( btnSuspend); + connect(btnSuspend, SIGNAL(clicked()), SLOT(slotSuspend())); + } + + if (canHibernate && !disableHibernate) + { + // Hibernate + FlatButton* btnHibernate = new FlatButton( frame ); + btnHibernate->setTextLabel( i18n("&Hibernate"), false ); + btnHibernate->setPixmap( DesktopIcon( "hibernate") ); + int i = btnHibernate->textLabel().find( QRegExp("\\&"), 0 ); // i == 1 + btnHibernate->setAccel( "ALT+" + btnHibernate->textLabel().lower()[i+1] ) ; + hbuttonbox->addWidget ( btnHibernate); + connect(btnHibernate, SIGNAL(clicked()), SLOT(slotHibernate())); + } + + // Separator (within buttonlay) + vbox->addWidget( new KSeparator( frame ) ); + + // bottom buttons + QHBoxLayout* hbuttonbox2 = new QHBoxLayout( vbox, factor * KDialog::spacingHint() ); + hbuttonbox2->setAlignment( Qt::AlignHCenter ); + + // Reboot + FlatButton* btnReboot = new FlatButton( frame ); + btnReboot->setTextLabel( i18n("&Restart"), false ); + btnReboot->setPixmap( DesktopIcon( "reload") ); + int i = btnReboot->textLabel().find( QRegExp("\\&"), 0 ); // i == 1 + btnReboot->setAccel( "ALT+" + btnReboot->textLabel().lower()[i+1] ) ; + hbuttonbox2->addWidget ( btnReboot); + connect(btnReboot, SIGNAL(clicked()), SLOT(slotReboot())); + if ( sdtype == KApplication::ShutdownTypeReboot ) + btnReboot->setFocus(); + + // BAD CARMA .. this code is copied line by line from standard konqy dialog + int def, cur; + if ( DM().bootOptions( rebootOptions, def, cur ) ) { + btnReboot->setPopupDelay(300); // visually add dropdown + targets = new QPopupMenu( frame ); + if ( cur == -1 ) + cur = def; + + int index = 0; + for (QStringList::ConstIterator it = rebootOptions.begin(); it != rebootOptions.end(); ++it, ++index) + { + QString label = (*it); + label=label.replace('&',"&&"); + if (index == cur) + targets->insertItem( label + i18n("current option in boot loader", " (current)"), index); + else + targets->insertItem( label, index ); + } + + btnReboot->setPopup(targets); + connect( targets, SIGNAL(activated(int)), SLOT(slotReboot(int)) ); + } + // BAD CARMA .. this code is copied line by line from standard konqy dialog [EOF] + + // Shutdown + FlatButton* btnHalt = new FlatButton( frame ); + btnHalt->setTextLabel( i18n("&Turn Off"), false ); + btnHalt->setPixmap( DesktopIcon( "exit") ); + i = btnHalt->textLabel().find( QRegExp("\\&"), 0 ); // i == 1 + btnHalt->setAccel( "ALT+" + btnHalt->textLabel().lower()[i+1] ) ; + hbuttonbox2->addWidget ( btnHalt ); + connect(btnHalt, SIGNAL(clicked()), SLOT(slotHalt())); + if ( sdtype == KApplication::ShutdownTypeHalt ) + btnHalt->setFocus(); + + // cancel buttonbox + QHBoxLayout* hbuttonbox3 = new QHBoxLayout( vbox, factor * KDialog::spacingHint() ); + hbuttonbox3->setAlignment( Qt::AlignRight ); + + // Back to Desktop + KSMPushButton* btnBack = new KSMPushButton( KStdGuiItem::cancel(), frame ); + hbuttonbox3->addWidget( btnBack ); + connect(btnBack, SIGNAL(clicked()), SLOT(reject())); + + } + else + { + // Shutdown + KPushButton* btnHalt = new KPushButton( KGuiItem( i18n("&Turn Off Computer"), "exit"), frame ); + btnHalt->setFont( btnFont ); + buttonlay->addWidget( btnHalt ); + connect(btnHalt, SIGNAL(clicked()), SLOT(slotHalt())); + if ( sdtype == KApplication::ShutdownTypeHalt ) + btnHalt->setFocus(); + + // Reboot + KSMDelayedPushButton* btnReboot = new KSMDelayedPushButton( KGuiItem( i18n("&Restart Computer"), "reload"), frame ); + btnReboot->setFont( btnFont ); + buttonlay->addWidget( btnReboot ); + + connect(btnReboot, SIGNAL(clicked()), SLOT(slotReboot())); + if ( sdtype == KApplication::ShutdownTypeReboot ) + btnReboot->setFocus(); + + // this section is copied as-is into ubuntulogout as well + int def, cur; + if ( DM().bootOptions( rebootOptions, def, cur ) ) { + targets = new QPopupMenu( frame ); + if ( cur == -1 ) + cur = def; + + int index = 0; + for (QStringList::ConstIterator it = rebootOptions.begin(); it != rebootOptions.end(); ++it, ++index) + { + QString label = (*it); + label=label.replace('&',"&&"); + if (index == cur) + targets->insertItem( label + i18n("current option in boot loader", " (current)"), index); + else + targets->insertItem( label, index ); + } + + btnReboot->setPopup(targets); + connect( targets, SIGNAL(activated(int)), SLOT(slotReboot(int)) ); + } + + + if (canSuspend && !disableSuspend) + { + KPushButton* btnSuspend = new KPushButton( KGuiItem( i18n("&Suspend Computer"), "suspend"), frame ); + btnSuspend->setFont( btnFont ); + buttonlay->addWidget( btnSuspend ); + connect(btnSuspend, SIGNAL(clicked()), SLOT(slotSuspend())); + } + + if (canHibernate && !disableHibernate) + { + KPushButton* btnHibernate = new KPushButton( KGuiItem( i18n("&Hibernate Computer"), "hibernate"), frame ); + btnHibernate->setFont( btnFont ); + buttonlay->addWidget( btnHibernate ); + connect(btnHibernate, SIGNAL(clicked()), SLOT(slotHibernate())); + } + + buttonlay->addStretch( 1 ); + + // Separator + buttonlay->addWidget( new KSeparator( frame ) ); + + // Back to Desktop + KPushButton* btnBack = new KPushButton( KStdGuiItem::cancel(), frame ); + buttonlay->addWidget( btnBack ); + connect(btnBack, SIGNAL(clicked()), SLOT(reject())); + + } - // Back to Desktop - KPushButton* btnBack = new KPushButton( KStdGuiItem::cancel(), frame ); - buttonlay->addWidget( btnBack ); - connect(btnBack, SIGNAL(clicked()), SLOT(reject())); + } + else { + // finish the dialog correctly + if(doUbuntuLogout) + { + // cancel buttonbox + QHBoxLayout* hbuttonbox3 = new QHBoxLayout( vbox, factor * KDialog::spacingHint() ); + hbuttonbox3->setAlignment( Qt::AlignRight ); + // Back to Desktop + KSMPushButton* btnBack = new KSMPushButton( KStdGuiItem::cancel(), frame ); + hbuttonbox3->addWidget( btnBack ); + + connect(btnBack, SIGNAL(clicked()), SLOT(reject())); + } + else + { + // Separator + buttonlay->addWidget( new KSeparator( frame ) ); + + // Back to Desktop + KPushButton* btnBack = new KPushButton( KStdGuiItem::cancel(), frame ); + buttonlay->addWidget( btnBack ); + + connect(btnBack, SIGNAL(clicked()), SLOT(reject())); + } + + + } + + +} + + +KSMShutdownDlg::~KSMShutdownDlg() +{ + if (m_halCtx) + { + DBusError error; + dbus_error_init(&error); + libhal_ctx_shutdown(m_halCtx, &error); + libhal_ctx_free(m_halCtx); + } } @@ -215,6 +653,52 @@ void KSMShutdownDlg::slotHalt() accept(); } +void KSMShutdownDlg::slotSuspend() +{ + if (m_lockOnResume) { + DCOPRef("kdesktop", "KScreensaverIface").send("lock"); + } + + if (m_dbusConn) + { + DBusMessage *msg = dbus_message_new_method_call( + "org.freedesktop.Hal", + "/org/freedesktop/Hal/devices/computer", + "org.freedesktop.Hal.Device.SystemPowerManagement", + "Suspend"); + + int wakeup=0; + dbus_message_append_args(msg, DBUS_TYPE_INT32, &wakeup, DBUS_TYPE_INVALID); + + dbus_connection_send(m_dbusConn, msg, NULL); + + dbus_message_unref(msg); + } + + reject(); // continue on resume +} + +void KSMShutdownDlg::slotHibernate() +{ + if (m_lockOnResume) { + DCOPRef("kdesktop", "KScreensaverIface").send("lock"); + } + + if (m_dbusConn) + { + DBusMessage *msg = dbus_message_new_method_call( + "org.freedesktop.Hal", + "/org/freedesktop/Hal/devices/computer", + "org.freedesktop.Hal.Device.SystemPowerManagement", + "Hibernate"); + + dbus_connection_send(m_dbusConn, msg, NULL); + + dbus_message_unref(msg); + } + + reject(); // continue on resume +} bool KSMShutdownDlg::confirmShutdown( bool maysd, KApplication::ShutdownType& sdtype, QString& bootOption ) { @@ -276,3 +760,132 @@ void KSMDelayedPushButton::slotTimeout() popt->stop(); setDown(false); } + +KSMPushButton::KSMPushButton( const KGuiItem &item, + QWidget *parent, + const char *name) + : KPushButton( item, parent, name), + m_pressed(false) +{ + setDefault( false ); + setAutoDefault ( false ); +} + + +void KSMPushButton::keyPressEvent( QKeyEvent* e ) +{ +switch ( e->key() ) + { + case Key_Enter: + case Key_Return: + case Key_Space: + m_pressed = TRUE; + setDown(true); + emit pressed(); + break; + case Key_Escape: + e->ignore(); + break; + default: + e->ignore(); + } + + QPushButton::keyPressEvent(e); +} + + +void KSMPushButton::keyReleaseEvent( QKeyEvent* e ) +{ + switch ( e->key() ) + { + case Key_Space: + case Key_Enter: + case Key_Return: + if ( m_pressed ) + { + setDown(false); + m_pressed = FALSE; + emit released(); + emit clicked(); + } + break; + case Key_Escape: + e->ignore(); + break; + default: + e->ignore(); + } + +} + + + + +FlatButton::FlatButton( QWidget *parent, const char *name ) + : QToolButton( parent, name/*, WNoAutoErase*/ ), + m_pressed(false) +{ + init(); +} + + +FlatButton::~FlatButton() {} + + +void FlatButton::init() +{ + setUsesTextLabel(true); + setUsesBigPixmap(true); + setAutoRaise(true); + setTextPosition( QToolButton::Under ); + setFocusPolicy(QWidget::StrongFocus); + } + + +void FlatButton::keyPressEvent( QKeyEvent* e ) +{ + switch ( e->key() ) + { + case Key_Enter: + case Key_Return: + case Key_Space: + m_pressed = TRUE; + setDown(true); + emit pressed(); + break; + case Key_Escape: + e->ignore(); + break; + default: + e->ignore(); + } + + QToolButton::keyPressEvent(e); +} + + +void FlatButton::keyReleaseEvent( QKeyEvent* e ) +{ + switch ( e->key() ) + { + case Key_Space: + case Key_Enter: + case Key_Return: + if ( m_pressed ) + { + setDown(false); + m_pressed = FALSE; + emit released(); + emit clicked(); + } + break; + case Key_Escape: + e->ignore(); + break; + default: + e->ignore(); + } + +} + + diff --git a/ksmserver/shutdowndlg.h b/ksmserver/shutdowndlg.h index 9fcb77c51..d696dff71 100644 --- a/ksmserver/shutdowndlg.h +++ b/ksmserver/shutdowndlg.h @@ -8,23 +8,40 @@ Copyright (C) 2000 Matthias Ettrich <[email protected]> #define SHUTDOWNDLG_H #include <qpixmap.h> +#include <qimage.h> +#include <qdatetime.h> #include <qdialog.h> #include <kpushbutton.h> +#include <qpushbutton.h> +#include <qframe.h> +#include <kguiitem.h> +#include <qtoolbutton.h> + class QPushButton; class QVButtonGroup; class QPopupMenu; class QTimer; +class QPainter; +class QString; +class KAction; + #include <kapplication.h> +#include <kpixmapio.h> -// The (singleton) widget that makes the desktop gray. +/* We acknowledge the the dbus API is unstable */ +#define DBUS_API_SUBJECT_TO_CHANGE +#include <dbus/connection.h> +#include <libhal.h> + +// The (singleton) widget that makes/fades the desktop gray. class KSMShutdownFeedback : public QWidget { Q_OBJECT public: - static void start() { s_pSelf = new KSMShutdownFeedback(); s_pSelf->show(); } - static void stop() { delete s_pSelf; s_pSelf = 0L; } + static void start() { s_pSelf = new KSMShutdownFeedback(); } + static void stop() { if ( s_pSelf != 0L ) s_pSelf->fadeBack(); delete s_pSelf; s_pSelf = 0L; } static KSMShutdownFeedback * self() { return s_pSelf; } protected: @@ -38,6 +55,17 @@ private: KSMShutdownFeedback(); int m_currentY; QPixmap m_root; + void fadeBack( void ); + float m_grayOpacity; + float m_compensation; + bool m_fadeBackwards; + bool m_readDelayComplete; + QImage m_unfadedImage; + QImage m_grayImage; + QTime m_fadeTime; + int m_rowsDone; + KPixmapIO m_pmio; + }; @@ -54,9 +82,11 @@ public slots: void slotHalt(); void slotReboot(); void slotReboot(int); + void slotSuspend(); + void slotHibernate(); protected: - ~KSMShutdownDlg() {}; + ~KSMShutdownDlg(); private: KSMShutdownDlg( QWidget* parent, bool maysd, KApplication::ShutdownType sdtype ); @@ -64,6 +94,9 @@ private: QString m_bootOption; QPopupMenu *targets; QStringList rebootOptions; + LibHalContext* m_halCtx; + DBusConnection *m_dbusConn; + bool m_lockOnResume; }; class KSMDelayedPushButton : public KPushButton @@ -85,4 +118,51 @@ private: QTimer *popt; }; +class KSMPushButton : public KPushButton +{ + Q_OBJECT + +public: + + KSMPushButton( const KGuiItem &item, QWidget *parent, const char *name = 0 ); + +protected: + virtual void keyPressEvent(QKeyEvent*e); + virtual void keyReleaseEvent(QKeyEvent*e); + +private: + + bool m_pressed; + +}; + + + +class FlatButton : public QToolButton +{ + Q_OBJECT + + public: + + FlatButton( QWidget *parent = 0, const char *name = 0 ); + ~FlatButton(); + + protected: + virtual void keyPressEvent(QKeyEvent*e); + virtual void keyReleaseEvent(QKeyEvent*e); + + private slots: + + private: + void init(); + + bool m_pressed; + QString m_text; + QPixmap m_pixmap; + +}; + + + + #endif diff --git a/ksplashml/main.cpp b/ksplashml/main.cpp index c1208cc3b..2a79723d2 100644 --- a/ksplashml/main.cpp +++ b/ksplashml/main.cpp @@ -54,12 +54,6 @@ int main( int argc, char **argv ) KCmdLineArgs::addCmdLineOptions(options); KCmdLineArgs *arg = KCmdLineArgs::parsedArgs(); - if( arg->isSet( "fork" ) ) - { - if (fork()) - exit(0); - } - if ( !( arg->isSet( "dcop" ) ) ) KApplication::disableAutoDcopRegistration(); else if ( KApplication::dcopClient()->attach() ) @@ -75,6 +69,18 @@ int main( int argc, char **argv ) wndMain.setStartupItemCount( steps ); } + // The position of this fork() matters, fork too early and you risk the + // calls to KSplash::programStarted being missed. Now that wndMain has + // been instantiated it is safe to do this. An earlier version of + // this program had this fork occuring before the instantiation, + // and this led to a race condition where if ksplash lost the race it would + // hang because it would wait for signals that had already been sent + if( arg->isSet( "fork" ) ) + { + if (fork()) + exit(0); + } + app.setMainWidget(&wndMain); app.setTopWidget(&wndMain); return(app.exec()); diff --git a/ksysguard/configure.in.in b/ksysguard/configure.in.in index 0173b28ea..f4ab83853 100644 --- a/ksysguard/configure.in.in +++ b/ksysguard/configure.in.in @@ -3,6 +3,7 @@ AC_MSG_CHECKING([if ksysguardd can be compiled]) case "$host" in *-*-linux*) ksysguardd_compile=yes; UNAME='Linux' ;; *-*-freebsd*) ksysguardd_compile=yes; UNAME='FreeBSD' ;; + *-*-kfreebsd*-gnu) ksysguardd_compile=yes; UNAME='Linux' ;; *-*-dragonfly*) ksysguardd_compile=yes; UNAME='FreeBSD' ;; *-*-netbsd*) ksysguardd_compile=yes; UNAME='NetBSD' ;; *-*-solaris*) ksysguardd_compile=yes; UNAME='Solaris' ;; diff --git a/ksysguard/gui/Makefile.am b/ksysguard/gui/Makefile.am index c0b9d12b3..fd798bc61 100644 --- a/ksysguard/gui/Makefile.am +++ b/ksysguard/gui/Makefile.am @@ -59,5 +59,5 @@ METASOURCES = AUTO messages: rc.cpp $(EXTRACTRC) `find . -name "*.ui"` >> rc.cpp - $(EXTRACTATTR) --attr=display,title SystemLoad.sgrd KSysGuardApplet.xml >> rc.cpp + extractattr --attr=display,title SystemLoad.sgrd KSysGuardApplet.xml >> rc.cpp $(XGETTEXT) `find . -name "*.cpp" -o -name "*.cc"` -o $(podir)/ksysguard.pot diff --git a/ksysguard/ksysguardd/Linux/ProcessList.c b/ksysguard/ksysguardd/Linux/ProcessList.c index b267c7005..e9e8c1315 100644 --- a/ksysguard/ksysguardd/Linux/ProcessList.c +++ b/ksysguard/ksysguardd/Linux/ProcessList.c @@ -292,7 +292,7 @@ static int updateProcess( int pid ) strncmp( ps->cmdline, "kdeinit: ", KDEINITLEN ) == 0 && strcmp( ps->cmdline + KDEINITLEN, "Running..." ) != 0 ) { size_t len; - char* end = strchr( ps->cmdline + KDEINITLEN, ' ' ); + char* end = (char*)strchr( ps->cmdline + KDEINITLEN, ' ' ); if ( end ) len = ( end - ps->cmdline ) - KDEINITLEN; else diff --git a/ksysguard/ksysguardd/Linux/acpi.c b/ksysguard/ksysguardd/Linux/acpi.c index b3100c363..6e9470b59 100644 --- a/ksysguard/ksysguardd/Linux/acpi.c +++ b/ksysguard/ksysguardd/Linux/acpi.c @@ -130,7 +130,7 @@ int updateAcpiBattery( void ) p = AcpiBatInfoBuf; while ( ( p!= NULL ) && ( sscanf( p, "last full capacity: %d ", &AcpiBatCapacity ) != 1 ) ) { - p = strchr( p, '\n' ); + p = (char*)strchr( p, '\n' ); if ( p ) p++; } @@ -152,7 +152,7 @@ int updateAcpiBattery( void ) p = AcpiBatStateBuf; while ( ( p!= NULL ) && ( sscanf( p, "remaining capacity: %d ", &AcpiBatRemainingCapacity ) != 1 ) ) { - p = strchr( p, '\n' ); + p = (char*)strchr( p, '\n' ); if ( p ) p++; } @@ -161,7 +161,7 @@ int updateAcpiBattery( void ) p = AcpiBatStateBuf; while ( ( p!= NULL ) && ( sscanf( p, "present rate: %d ", &AcpiBatteryUsage[i] ) != 1 ) ) { - p = strchr( p, '\n' ); + p = (char*)strchr( p, '\n' ); if ( p ) p++; } @@ -229,12 +229,12 @@ void printAcpiBatUsageInfo( const char* cmd) static int extract_zone_name(char **startidx, const char *cmd) { char *idx = NULL; - idx = strchr(cmd, '/'); + idx = (char*)strchr(cmd, '/'); if (idx == NULL) return 0; - idx = strchr(idx+1, '/'); + idx = (char*)strchr(idx+1, '/'); if (idx == NULL) return 0; *startidx = idx+1; - idx = strchr(*startidx, '/'); + idx = (char*)strchr(*startidx, '/'); if (idx == NULL) return 0; return idx - *startidx; } diff --git a/ksysguard/ksysguardd/Linux/cpuinfo.c b/ksysguard/ksysguardd/Linux/cpuinfo.c index de5deb80f..fa55aabd9 100644 --- a/ksysguard/ksysguardd/Linux/cpuinfo.c +++ b/ksysguard/ksysguardd/Linux/cpuinfo.c @@ -83,7 +83,7 @@ static void processCpuInfo( void ) sscanf( value, "%f", &Clocks[ cpuId ] ); /* Move cibp to begining of next line, if there is one. */ - cibp = strchr( cibp, '\n' ); + cibp = (char*)strchr( cibp, '\n' ); if ( cibp ) cibp++; else diff --git a/ksysguard/ksysguardd/Linux/netdev.c b/ksysguard/ksysguardd/Linux/netdev.c index 55e812807..867678642 100644 --- a/ksysguard/ksysguardd/Linux/netdev.c +++ b/ksysguard/ksysguardd/Linux/netdev.c @@ -142,7 +142,7 @@ static int processNetDev_( void ) netDevBufP += strlen( buf ) + 1; /* move netDevBufP to next line */ if ( sscanf( buf, devFormat, tag ) ) { - char* pos = strchr( tag, ':' ); + char* pos = (char*)strchr( tag, ':' ); if ( pos ) { FORALL( DEFVARS ); *pos = '\0'; @@ -227,7 +227,7 @@ void initNetDev( struct SensorModul* sm ) netDevBufP += strlen( buf ) + 1; /* move netDevBufP to next line */ if ( sscanf( buf, devFormat, tag ) ) { - char* pos = strchr( tag, ':' ); + char* pos = (char*)strchr( tag, ':' ); if ( pos ) { char mon[ MON_SIZE ]; *pos = '\0'; @@ -339,9 +339,9 @@ void printNetDev##a( const char* cmd ) \ char* end; \ char dev[ 64 ]; \ \ - beg = strchr( cmd, '/' ); \ - beg = strchr( beg + 1, '/' ); \ - end = strchr( beg + 1, '/' ); \ + beg = (char*)strchr( cmd, '/' ); \ + beg = (char*)strchr( beg + 1, '/' ); \ + end = (char*)strchr( beg + 1, '/' ); \ strncpy( dev, beg + 1, end - beg - 1 ); \ dev[ end - beg - 1 ] = '\0'; \ \ diff --git a/ksysguard/ksysguardd/Linux/stat.c b/ksysguard/ksysguardd/Linux/stat.c index 0e03e4d53..9bc576deb 100644 --- a/ksysguard/ksysguardd/Linux/stat.c +++ b/ksysguard/ksysguardd/Linux/stat.c @@ -267,10 +267,10 @@ static int processDiskIO( const char* buf ) } /* Move p after the sencond ')'. We can safely assume that * those two ')' exist. */ - p = strchr( p, ')' ) + 1; - p = strchr( p, ')' ) + 1; + p = (char*)strchr( p, ')' ) + 1; + p = (char*)strchr( p, ')' ) + 1; if ( p && *p ) - p = strchr( p, '(' ); + p = (char*)strchr( p, '(' ); } return 0; diff --git a/ksysguard/ksysguardd/Solaris/NetDev.c b/ksysguard/ksysguardd/Solaris/NetDev.c index 89db266cb..836e2832b 100644 --- a/ksysguard/ksysguardd/Solaris/NetDev.c +++ b/ksysguard/ksysguardd/Solaris/NetDev.c @@ -436,9 +436,9 @@ void printIPackets( const char *cmd ) { char *name, *ptr; int i; - ptr = strchr( cmdcopy, (int) '/' ); + ptr = (char*)strchr( cmdcopy, (int) '/' ); name = ++ptr; - ptr = strchr( name, (int) '/' ); + ptr = (char*)strchr( name, (int) '/' ); *ptr = '\0'; for( i = 0; i < NetDevCount; i++ ) { @@ -464,9 +464,9 @@ void printOPackets( const char *cmd ) { char *name, *ptr; int i; - ptr = strchr( cmdcopy, (int) '/' ); + ptr = (char*)strchr( cmdcopy, (int) '/' ); name = ++ptr; - ptr = strchr( name, (int) '/' ); + ptr = (char*)strchr( name, (int) '/' ); *ptr = '\0'; for( i = 0; i < NetDevCount; i++ ) { @@ -492,9 +492,9 @@ void printIErrors( const char *cmd ) { char *name, *ptr; int i; - ptr = strchr( cmdcopy, (int) '/' ); + ptr = (char*)strchr( cmdcopy, (int) '/' ); name = ++ptr; - ptr = strchr( name, (int) '/' ); + ptr = (char*)strchr( name, (int) '/' ); *ptr = '\0'; for( i = 0; i < NetDevCount; i++ ) { @@ -520,9 +520,9 @@ void printOErrors( const char *cmd ) { char *name, *ptr; int i; - ptr = strchr( cmdcopy, (int) '/' ); + ptr = (char*)strchr( cmdcopy, (int) '/' ); name = ++ptr; - ptr = strchr( name, (int) '/' ); + ptr = (char*)strchr( name, (int) '/' ); *ptr = '\0'; for( i = 0; i < NetDevCount; i++ ) { @@ -548,9 +548,9 @@ void printCollisions( const char *cmd ) { char *name, *ptr; int i; - ptr = strchr( cmdcopy, (int) '/' ); + ptr = (char*)strchr( cmdcopy, (int) '/' ); name = ++ptr; - ptr = strchr( name, (int) '/' ); + ptr = (char*)strchr( name, (int) '/' ); *ptr = '\0'; for( i = 0; i < NetDevCount; i++ ) { @@ -576,9 +576,9 @@ void printMultiXmits( const char *cmd ) { char *name, *ptr; int i; - ptr = strchr( cmdcopy, (int) '/' ); + ptr = (char*)strchr( cmdcopy, (int) '/' ); name = ++ptr; - ptr = strchr( name, (int) '/' ); + ptr = (char*)strchr( name, (int) '/' ); *ptr = '\0'; for( i = 0; i < NetDevCount; i++ ) { @@ -604,9 +604,9 @@ void printMultiRecvs( const char *cmd ) { char *name, *ptr; int i; - ptr = strchr( cmdcopy, (int) '/' ); + ptr = (char*)strchr( cmdcopy, (int) '/' ); name = ++ptr; - ptr = strchr( name, (int) '/' ); + ptr = (char*)strchr( name, (int) '/' ); *ptr = '\0'; for( i = 0; i < NetDevCount; i++ ) { @@ -632,9 +632,9 @@ void printBcastXmits( const char *cmd ) { char *name, *ptr; int i; - ptr = strchr( cmdcopy, (int) '/' ); + ptr = (char*)strchr( cmdcopy, (int) '/' ); name = ++ptr; - ptr = strchr( name, (int) '/' ); + ptr = (char*)strchr( name, (int) '/' ); *ptr = '\0'; for( i = 0; i < NetDevCount; i++ ) { @@ -660,9 +660,9 @@ void printBcastRecvs( const char *cmd ) { char *name, *ptr; int i; - ptr = strchr( cmdcopy, (int) '/' ); + ptr = (char*)strchr( cmdcopy, (int) '/' ); name = ++ptr; - ptr = strchr( name, (int) '/' ); + ptr = (char*)strchr( name, (int) '/' ); *ptr = '\0'; for( i = 0; i < NetDevCount; i++ ) { diff --git a/ksysguard/ksysguardd/Tru64/NetDev.c b/ksysguard/ksysguardd/Tru64/NetDev.c index 0699b929a..a28c7ecf7 100644 --- a/ksysguard/ksysguardd/Tru64/NetDev.c +++ b/ksysguard/ksysguardd/Tru64/NetDev.c @@ -435,9 +435,9 @@ void printIPackets( const char *cmd ) { char *name, *ptr; int i; - ptr = strchr( cmdcopy, (int) '/' ); + ptr = (char*)strchr( cmdcopy, (int) '/' ); name = ++ptr; - ptr = strchr( name, (int) '/' ); + ptr = (char*)strchr( name, (int) '/' ); *ptr = '\0'; for( i = 0; i < NetDevCount; i++ ) { @@ -463,9 +463,9 @@ void printOPackets( const char *cmd ) { char *name, *ptr; int i; - ptr = strchr( cmdcopy, (int) '/' ); + ptr = (char*)strchr( cmdcopy, (int) '/' ); name = ++ptr; - ptr = strchr( name, (int) '/' ); + ptr = (char*)strchr( name, (int) '/' ); *ptr = '\0'; for( i = 0; i < NetDevCount; i++ ) { @@ -491,9 +491,9 @@ void printIErrors( const char *cmd ) { char *name, *ptr; int i; - ptr = strchr( cmdcopy, (int) '/' ); + ptr = (char*)strchr( cmdcopy, (int) '/' ); name = ++ptr; - ptr = strchr( name, (int) '/' ); + ptr = (char*)strchr( name, (int) '/' ); *ptr = '\0'; for( i = 0; i < NetDevCount; i++ ) { @@ -519,9 +519,9 @@ void printOErrors( const char *cmd ) { char *name, *ptr; int i; - ptr = strchr( cmdcopy, (int) '/' ); + ptr = (char*)strchr( cmdcopy, (int) '/' ); name = ++ptr; - ptr = strchr( name, (int) '/' ); + ptr = (char*)strchr( name, (int) '/' ); *ptr = '\0'; for( i = 0; i < NetDevCount; i++ ) { @@ -547,9 +547,9 @@ void printCollisions( const char *cmd ) { char *name, *ptr; int i; - ptr = strchr( cmdcopy, (int) '/' ); + ptr = (char*)strchr( cmdcopy, (int) '/' ); name = ++ptr; - ptr = strchr( name, (int) '/' ); + ptr = (char*)strchr( name, (int) '/' ); *ptr = '\0'; for( i = 0; i < NetDevCount; i++ ) { @@ -575,9 +575,9 @@ void printMultiXmits( const char *cmd ) { char *name, *ptr; int i; - ptr = strchr( cmdcopy, (int) '/' ); + ptr = (char*)strchr( cmdcopy, (int) '/' ); name = ++ptr; - ptr = strchr( name, (int) '/' ); + ptr = (char*)strchr( name, (int) '/' ); *ptr = '\0'; for( i = 0; i < NetDevCount; i++ ) { @@ -603,9 +603,9 @@ void printMultiRecvs( const char *cmd ) { char *name, *ptr; int i; - ptr = strchr( cmdcopy, (int) '/' ); + ptr = (char*)strchr( cmdcopy, (int) '/' ); name = ++ptr; - ptr = strchr( name, (int) '/' ); + ptr = (char*)strchr( name, (int) '/' ); *ptr = '\0'; for( i = 0; i < NetDevCount; i++ ) { @@ -631,9 +631,9 @@ void printBcastXmits( const char *cmd ) { char *name, *ptr; int i; - ptr = strchr( cmdcopy, (int) '/' ); + ptr = (char*)strchr( cmdcopy, (int) '/' ); name = ++ptr; - ptr = strchr( name, (int) '/' ); + ptr = (char*)strchr( name, (int) '/' ); *ptr = '\0'; for( i = 0; i < NetDevCount; i++ ) { @@ -659,9 +659,9 @@ void printBcastRecvs( const char *cmd ) { char *name, *ptr; int i; - ptr = strchr( cmdcopy, (int) '/' ); + ptr = (char*)strchr( cmdcopy, (int) '/' ); name = ++ptr; - ptr = strchr( name, (int) '/' ); + ptr = (char*)strchr( name, (int) '/' ); *ptr = '\0'; for( i = 0; i < NetDevCount; i++ ) { diff --git a/ksysguard/ksysguardd/conf.c b/ksysguard/ksysguardd/conf.c index 1d857137b..7f48ee590 100644 --- a/ksysguard/ksysguardd/conf.c +++ b/ksysguard/ksysguardd/conf.c @@ -93,9 +93,9 @@ void parseConfigFile( const char *filename ) if ( line[ strlen( line ) - 1 ] == '\n' ) line[ strlen( line ) - 1 ] = '\0'; - if ( !strncmp( line, "RegisterDomain",14) && (begin = strchr( line, '=' )) ) RegisterDomain=strdup(begin+1); + if ( !strncmp( line, "RegisterDomain",14) && (begin = (char*)strchr( line, '=' )) ) RegisterDomain=strdup(begin+1); - if ( !strncmp( line, "LogFiles", 8 ) && (begin = strchr( line, '=' )) ) { + if ( !strncmp( line, "LogFiles", 8 ) && (begin = (char*)strchr( line, '=' )) ) { begin++; for ( token = strtok( begin, "," ); token; token = strtok( NULL, "," ) ) { @@ -104,7 +104,7 @@ void parseConfigFile( const char *filename ) continue; } confLog->name = strdup( token ); - tmp = strchr( confLog->name, ':' ); + tmp = (char*)strchr( confLog->name, ':' ); *tmp = '\0'; confLog->path = tmp; confLog->path++; @@ -113,7 +113,7 @@ void parseConfigFile( const char *filename ) } } - if ( !strncmp( line, "Sensors", 7 ) && (begin = strchr( line, '=' )) ) { + if ( !strncmp( line, "Sensors", 7 ) && (begin = (char*)strchr( line, '=' )) ) { begin++; for ( token = strtok( begin, ","); token; token = strtok( NULL, "," ) ) diff --git a/kwin/KWinInterface.h b/kwin/KWinInterface.h index d368ec368..bca7354b5 100644 --- a/kwin/KWinInterface.h +++ b/kwin/KWinInterface.h @@ -16,6 +16,7 @@ class KWinInterface : virtual public DCOPObject virtual void refresh() = 0; virtual void doNotManage(QString)= 0; virtual void showWindowMenuAt(unsigned long winId, int x, int y)= 0; + virtual void kDestopResized() = 0; virtual void setDesktopLayout(int orientation, int x, int y)= 0; virtual bool setCurrentDesktop(int)= 0; virtual int currentDesktop() const = 0; diff --git a/kwin/activation.cpp b/kwin/activation.cpp index 2551519ec..a6844b737 100644 --- a/kwin/activation.cpp +++ b/kwin/activation.cpp @@ -360,6 +360,8 @@ void Workspace::takeActivity( Client* c, int flags, bool handled ) return; } c->takeActivity( flags, handled, Allowed ); + if( !c->isOnScreen( active_screen )) + active_screen = c->screen(); } void Workspace::handleTakeActivity( Client* c, Time /*timestamp*/, int flags ) @@ -413,6 +415,13 @@ bool Workspace::activateNextClient( Client* c ) { if( !(*it)->isShown( false ) || !(*it)->isOnCurrentDesktop()) continue; + if( options->separateScreenFocus ) + { + if( c != NULL && !(*it)->isOnScreen( c->screen())) + continue; + if( c == NULL && !(*it)->isOnScreen( activeScreen())) + continue; + } if( mainwindows.contains( *it )) { get_focus = *it; @@ -438,6 +447,31 @@ bool Workspace::activateNextClient( Client* c ) return true; } +void Workspace::setCurrentScreen( int new_screen ) + { + if (new_screen < 0 || new_screen > numScreens()) + return; + if ( !options->focusPolicyIsReasonable()) + return; + closeActivePopup(); + Client* get_focus = NULL; + for( ClientList::ConstIterator it = focus_chain[currentDesktop()].fromLast(); + it != focus_chain[currentDesktop()].end(); + --it ) + { + if( !(*it)->isShown( false ) || !(*it)->isOnCurrentDesktop()) + continue; + if( !(*it)->screen() == new_screen ) + continue; + get_focus = *it; + break; + } + if( get_focus == NULL ) + get_focus = findDesktop( true, currentDesktop()); + if( get_focus != NULL && get_focus != mostRecentlyActivatedClient()) + requestFocus( get_focus ); + active_screen = new_screen; + } void Workspace::gotFocusIn( const Client* c ) { @@ -860,6 +894,8 @@ void Client::startupIdChanged() desktop = asn_data.desktop(); if( !isOnAllDesktops()) workspace()->sendClientToDesktop( this, desktop, true ); + if( asn_data.xinerama() != -1 ) + workspace()->sendClientToScreen( this, asn_data.xinerama()); Time timestamp = asn_id.timestamp(); if( timestamp == 0 && asn_data.timestamp() != -1U ) timestamp = asn_data.timestamp(); diff --git a/kwin/client.cpp b/kwin/client.cpp index fe8c59c58..9fc5353df 100644 --- a/kwin/client.cpp +++ b/kwin/client.cpp @@ -1255,6 +1255,20 @@ bool Client::isOnCurrentDesktop() const return isOnDesktop( workspace()->currentDesktop()); } +int Client::screen() const + { + if( !options->xineramaEnabled ) + return 0; + return workspace()->screenNumber( geometry().center()); + } + +bool Client::isOnScreen( int screen ) const + { + if( !options->xineramaEnabled ) + return screen == 0; + return workspace()->screenGeometry( screen ).intersects( geometry()); + } + // performs activation and/or raising of the window void Client::takeActivity( int flags, bool handled, allowed_t ) { diff --git a/kwin/client.h b/kwin/client.h index d0d8e9d54..0905b5794 100644 --- a/kwin/client.h +++ b/kwin/client.h @@ -118,6 +118,9 @@ class Client : public QObject, public KDecorationDefines bool isOnCurrentDesktop() const; bool isOnAllDesktops() const; void setOnAllDesktops( bool set ); + + bool isOnScreen( int screen ) const; // true if it's at least partially there + int screen() const; // the screen where the center is // !isMinimized() && not hidden, i.e. normally visible on some virtual desktop bool isShown( bool shaded_is_shown ) const; diff --git a/kwin/geometry.cpp b/kwin/geometry.cpp index 7c64eadcf..cff5a3a19 100644 --- a/kwin/geometry.cpp +++ b/kwin/geometry.cpp @@ -43,13 +43,30 @@ namespace KWinInternal */ void Workspace::desktopResized() { - QRect geom = QApplication::desktop()->geometry(); + printf("Workspace::desktopResized()\n\r"); + QRect geom = KApplication::desktop()->geometry(); NETSize desktop_geometry; desktop_geometry.width = geom.width(); desktop_geometry.height = geom.height(); rootInfo->setDesktopGeometry( -1, desktop_geometry ); - updateClientArea(); + updateClientArea( true ); + checkElectricBorders( true ); + } + +/*! + Resizes the workspace after kdesktop signals a desktop resize + */ +void Workspace::kDestopResized() + { + printf("Workspace::kDesktopResized()\n\r"); + QRect geom = KApplication::desktop()->geometry(); + NETSize desktop_geometry; + desktop_geometry.width = geom.width(); + desktop_geometry.height = geom.height(); + rootInfo->setDesktopGeometry( -1, desktop_geometry ); + + updateClientArea( true ); checkElectricBorders( true ); } @@ -211,14 +228,11 @@ void Workspace::updateClientArea() \sa geometry() */ -QRect Workspace::clientArea( clientAreaOption opt, const QPoint& p, int desktop ) const +QRect Workspace::clientArea( clientAreaOption opt, int screen, int desktop ) const { if( desktop == NETWinInfo::OnAllDesktops || desktop == 0 ) desktop = currentDesktop(); QDesktopWidget *desktopwidget = KApplication::desktop(); - int screen = desktopwidget->isVirtualDesktop() ? desktopwidget->screenNumber( p ) : desktopwidget->primaryScreen(); - if( screen < 0 ) - screen = desktopwidget->primaryScreen(); QRect sarea = screenarea // may be NULL during KWin initialization ? screenarea[ desktop ][ screen ] : desktopwidget->screenGeometry( screen ); @@ -263,11 +277,21 @@ QRect Workspace::clientArea( clientAreaOption opt, const QPoint& p, int desktop return QRect(); } +QRect Workspace::clientArea( clientAreaOption opt, const QPoint& p, int desktop ) const + { + QDesktopWidget *desktopwidget = KApplication::desktop(); + int screen = desktopwidget->screenNumber( p ); + if( screen < 0 ) + screen = desktopwidget->primaryScreen(); + return clientArea( opt, screen, desktop ); + } + QRect Workspace::clientArea( clientAreaOption opt, const Client* c ) const { return clientArea( opt, c->geometry().center(), c->desktop()); } + /*! Client \a c is moved around to position \a pos. This gives the workspace the opportunity to interveniate and to implement @@ -896,10 +920,6 @@ void Client::checkWorkspacePosition() setGeometry( area ); return; } - if( maximizeMode() != MaximizeRestore ) - // TODO update geom_restore? - changeMaximize( false, false, true ); // adjust size - if( isFullScreen()) { QRect area = workspace()->clientArea( FullScreenArea, this ); @@ -926,6 +946,10 @@ void Client::checkWorkspacePosition() return; } + if( maximizeMode() != MaximizeRestore ) + // TODO update geom_restore? + changeMaximize( false, false, true ); // adjust size + if( !isShade()) // TODO { int old_diff_x = workarea_diff_x; @@ -1722,6 +1746,7 @@ void Client::setGeometry( int x, int y, int w, int h, ForceGeometry_t force ) sendSyntheticConfigureNotify(); updateWindowRules(); checkMaximizeGeometry(); + workspace()->checkActiveScreen( this ); } void Client::plainResize( int w, int h, ForceGeometry_t force ) @@ -1775,6 +1800,7 @@ void Client::plainResize( int w, int h, ForceGeometry_t force ) sendSyntheticConfigureNotify(); updateWindowRules(); checkMaximizeGeometry(); + workspace()->checkActiveScreen( this ); } /*! @@ -1795,6 +1821,7 @@ void Client::move( int x, int y, ForceGeometry_t force ) sendSyntheticConfigureNotify(); updateWindowRules(); checkMaximizeGeometry(); + workspace()->checkActiveScreen( this ); } diff --git a/kwin/kcmkwin/kwinoptions/windows.cpp b/kwin/kcmkwin/kwinoptions/windows.cpp index db682b316..aa779125b 100644 --- a/kwin/kcmkwin/kwinoptions/windows.cpp +++ b/kwin/kcmkwin/kwinoptions/windows.cpp @@ -76,6 +76,8 @@ #define KWIN_SHADEHOVER_INTERVAL "ShadeHoverInterval" #define KWIN_FOCUS_STEALING "FocusStealingPreventionLevel" #define KWIN_HIDE_UTILITY "HideUtilityWindowsForInactive" +#define KWIN_SEPARATE_SCREEN_FOCUS "SeparateScreenFocus" +#define KWIN_ACTIVE_MOUSE_SCREEN "ActiveMouseScreen" // kwm config keywords #define KWM_ELECTRIC_BORDER "ElectricBorders" @@ -209,6 +211,27 @@ KFocusConfig::KFocusConfig (bool _standAlone, KConfig *_config, QWidget * parent QWhatsThis::add( delayFocus, i18n("This is the delay after which the window the mouse pointer is over" " will automatically receive focus.") ); + separateScreenFocus = new QCheckBox( i18n( "S&eparate screen focus" ), fcsBox ); + fLay->addWidget( separateScreenFocus ); + wtstr = i18n( "When this option is enabled, focus operations are limited only to the active Xinerama screen" ); + QWhatsThis::add( separateScreenFocus, wtstr ); + + activeMouseScreen = new QCheckBox( i18n( "Active &mouse screen" ), fcsBox ); + fLay->addWidget( activeMouseScreen ); + wtstr = i18n( "When this option is enabled, active Xinerama screen (where for example new windows appear)" + " is the screen with the mouse pointer. When disabled, the active Xinerama screen is the screen" + " with the focused window. This option is by default disabled for Click to focus and" + " enabled for other focus policies." ); + QWhatsThis::add( activeMouseScreen, wtstr ); + connect(focusCombo, SIGNAL(activated(int)), this, SLOT(updateActiveMouseScreen())); + + if (!QApplication::desktop()->isVirtualDesktop() || + QApplication::desktop()->numScreens() == 1) // No Ximerama + { + separateScreenFocus->hide(); + activeMouseScreen->hide(); + } + lay->addWidget(fcsBox); kbdBox = new QButtonGroup(i18n("Navigation"), this); @@ -260,6 +283,8 @@ KFocusConfig::KFocusConfig (bool _standAlone, KConfig *_config, QWidget * parent connect(fcsBox, SIGNAL(clicked(int)), SLOT(changed())); connect(autoRaise, SIGNAL(valueChanged(int)), SLOT(changed())); connect(delayFocus, SIGNAL(valueChanged(int)), SLOT(changed())); + connect(separateScreenFocus, SIGNAL(clicked()), SLOT(changed())); + connect(activeMouseScreen, SIGNAL(clicked()), SLOT(changed())); connect(altTabPopup, SIGNAL(clicked()), SLOT(changed())); connect(traverseAll, SIGNAL(clicked()), SLOT(changed())); connect(rollOverDesktops, SIGNAL(clicked()), SLOT(changed())); @@ -366,6 +391,22 @@ void KFocusConfig::delayFocusOnTog(bool a) { void KFocusConfig::clickRaiseOnTog(bool ) { } +void KFocusConfig::setSeparateScreenFocus(bool s) { + separateScreenFocus->setChecked(s); +} + +void KFocusConfig::setActiveMouseScreen(bool a) { + activeMouseScreen->setChecked(a); +} + +void KFocusConfig::updateActiveMouseScreen() +{ + // on by default for non click to focus policies + KConfigGroup cfg( config, "Windows" ); + if( !cfg.hasKey( KWIN_ACTIVE_MOUSE_SCREEN )) + setActiveMouseScreen( focusCombo->currentItem() != 0 ); +} + void KFocusConfig::setAltTabMode(bool a) { altTabPopup->setChecked(a); } @@ -412,6 +453,10 @@ void KFocusConfig::load( void ) setClickRaise(key != "off"); setAutoRaiseEnabled(); // this will disable/hide the auto raise delay widget if focus==click setDelayFocusEnabled(); + + setSeparateScreenFocus( config->readBoolEntry(KWIN_SEPARATE_SCREEN_FOCUS, false)); + // on by default for non click to focus policies + setActiveMouseScreen( config->readBoolEntry(KWIN_ACTIVE_MOUSE_SCREEN, focusCombo->currentItem() != 0 )); key = config->readEntry(KWIN_ALTTABMODE, "KDE"); setAltTabMode(key == "KDE"); @@ -467,6 +512,9 @@ void KFocusConfig::save( void ) else config->writeEntry(KWIN_CLICKRAISE, "off"); + config->writeEntry(KWIN_SEPARATE_SCREEN_FOCUS, separateScreenFocus->isChecked()); + config->writeEntry(KWIN_ACTIVE_MOUSE_SCREEN, activeMouseScreen->isChecked()); + if (altTabPopup->isChecked()) config->writeEntry(KWIN_ALTTABMODE, "KDE"); else @@ -500,6 +548,9 @@ void KFocusConfig::defaults() setAutoRaise(false); setDelayFocus(false); setClickRaise(true); + setSeparateScreenFocus( false ); + // on by default for non click to focus policies + setActiveMouseScreen( focusCombo->currentItem() != 0 ); setAltTabMode(true); setTraverseAll( false ); setRollOverDesktops(true); diff --git a/kwin/kcmkwin/kwinoptions/windows.h b/kwin/kcmkwin/kwinoptions/windows.h index 60a4d69f0..14537b922 100644 --- a/kwin/kcmkwin/kwinoptions/windows.h +++ b/kwin/kcmkwin/kwinoptions/windows.h @@ -86,6 +86,7 @@ private slots: void delayFocusOnTog(bool); void clickRaiseOnTog(bool); void updateAltTabMode(); + void updateActiveMouseScreen(); void changed() { emit KCModule::changed(true); } @@ -101,6 +102,8 @@ private: void setDelayFocusInterval(int); void setDelayFocus(bool); void setClickRaise(bool); + void setSeparateScreenFocus(bool); + void setActiveMouseScreen(bool); void setAltTabMode(bool); void setTraverseAll(bool); void setRollOverDesktops(bool); @@ -113,6 +116,8 @@ private: QCheckBox *clickRaiseOn; KIntNumInput *autoRaise; KIntNumInput *delayFocus; + QCheckBox *separateScreenFocus; + QCheckBox *activeMouseScreen; QButtonGroup *kbdBox; QCheckBox *altTabPopup; diff --git a/kwin/kwin.kcfg b/kwin/kwin.kcfg index 9865d296c..63749c1f8 100644 --- a/kwin/kwin.kcfg +++ b/kwin/kwin.kcfg @@ -60,6 +60,9 @@ <entry key="IgnorePositionClasses" type="StringList" /> <entry key="KillPingTimeout" type="Int" /> <entry key="ShowDesktopIsMinimizeAll" type="Bool" /> + <entry key="SeparateScreenFocus" type="Bool" /> + <entry key="ActiveMouseScreen" type="Bool" /> + <entry key="XineramaPlacementScreen" type="Int" /> </group> <group name="WM" > diff --git a/kwin/kwinbindings.cpp b/kwin/kwinbindings.cpp index 1fd8c572f..9dee0a071 100644 --- a/kwin/kwinbindings.cpp +++ b/kwin/kwinbindings.cpp @@ -104,6 +104,15 @@ DEF( I18N_NOOP("Window One Desktop to the Left"), 0, 0, slotWindowToDesktopLeft() ); DEF( I18N_NOOP("Window One Desktop Up"), 0, 0, slotWindowToDesktopUp() ); DEF( I18N_NOOP("Window One Desktop Down"), 0, 0, slotWindowToDesktopDown() ); + DEF( I18N_NOOP("Window to Screen 0"), 0, 0, slotWindowToScreen(int) ); + DEF( I18N_NOOP("Window to Screen 1"), 0, 0, slotWindowToScreen(int) ); + DEF( I18N_NOOP("Window to Screen 2"), 0, 0, slotWindowToScreen(int) ); + DEF( I18N_NOOP("Window to Screen 3"), 0, 0, slotWindowToScreen(int) ); + DEF( I18N_NOOP("Window to Screen 4"), 0, 0, slotWindowToScreen(int) ); + DEF( I18N_NOOP("Window to Screen 5"), 0, 0, slotWindowToScreen(int) ); + DEF( I18N_NOOP("Window to Screen 6"), 0, 0, slotWindowToScreen(int) ); + DEF( I18N_NOOP("Window to Screen 7"), 0, 0, slotWindowToScreen(int) ); + DEF( I18N_NOOP("Window to Next Screen"), 0, 0, slotWindowToNextScreen() ); keys->insert( "Group:Desktop Switching", i18n("Desktop Switching") ); DEF( I18N_NOOP("Switch to Desktop 1"), CTRL+Qt::Key_F1, WIN+Qt::Key_F1, slotSwitchToDesktop(int) ); @@ -132,6 +141,15 @@ DEF( I18N_NOOP("Switch One Desktop to the Left"), 0, 0, slotSwitchDesktopLeft() ); DEF( I18N_NOOP("Switch One Desktop Up"), 0, 0, slotSwitchDesktopUp() ); DEF( I18N_NOOP("Switch One Desktop Down"), 0, 0, slotSwitchDesktopDown() ); + DEF( I18N_NOOP("Switch to Screen 0"), 0, 0, slotSwitchToScreen(int) ); + DEF( I18N_NOOP("Switch to Screen 1"), 0, 0, slotSwitchToScreen(int) ); + DEF( I18N_NOOP("Switch to Screen 2"), 0, 0, slotSwitchToScreen(int) ); + DEF( I18N_NOOP("Switch to Screen 3"), 0, 0, slotSwitchToScreen(int) ); + DEF( I18N_NOOP("Switch to Screen 4"), 0, 0, slotSwitchToScreen(int) ); + DEF( I18N_NOOP("Switch to Screen 5"), 0, 0, slotSwitchToScreen(int) ); + DEF( I18N_NOOP("Switch to Screen 6"), 0, 0, slotSwitchToScreen(int) ); + DEF( I18N_NOOP("Switch to Screen 7"), 0, 0, slotSwitchToScreen(int) ); + DEF( I18N_NOOP("Switch to Next Screen"), 0, 0, slotSwitchToNextScreen() ); keys->insert( "Group:Miscellaneous", i18n("Miscellaneous") ); DEF( I18N_NOOP("Mouse Emulation"), ALT+Qt::Key_F12, 0, slotMouseEmulation() ); diff --git a/kwin/manage.cpp b/kwin/manage.cpp index 35dcc88ba..24398dcae 100644 --- a/kwin/manage.cpp +++ b/kwin/manage.cpp @@ -166,7 +166,7 @@ bool Client::manage( Window w, bool isMapped ) it != mainclients.end(); ++it ) { - if( (*it)->isSpecialWindow()) + if( mainclients.count() > 1 && (*it)->isSpecialWindow()) continue; // don't consider toolbars etc when placing maincl = *it; if( (*it)->isOnCurrentDesktop()) @@ -202,9 +202,14 @@ bool Client::manage( Window w, bool isMapped ) if( isMapped || session ) area = workspace()->clientArea( FullArea, geom.center(), desktop()); else if( options->xineramaPlacementEnabled ) - area = workspace()->clientArea( PlacementArea, QCursor::pos(), desktop()); + { + int screen = options->xineramaPlacementScreen; + if( screen == -1 ) // active screen + screen = asn_data.xinerama() == -1 ? workspace()->activeScreen() : asn_data.xinerama(); + area = workspace()->clientArea( PlacementArea, workspace()->screenGeometry( screen ).center(), desktop()); + } else - area = workspace()->clientArea( PlacementArea, geom.center(), desktop()); + area = workspace()->clientArea( PlacementArea, QCursor::pos(), desktop()); if( int type = checkFullScreenHack( geom )) { diff --git a/kwin/options.cpp b/kwin/options.cpp index 690266fc9..f74051bbb 100644 --- a/kwin/options.cpp +++ b/kwin/options.cpp @@ -71,6 +71,9 @@ unsigned long Options::updateSettings() altTabStyle = KDE; // what a default :-) if ( val == "CDE" ) altTabStyle = CDE; + + separateScreenFocus = config->readBoolEntry( "SeparateScreenFocus", false ); + activeMouseScreen = config->readBoolEntry( "ActiveMouseScreen", focusPolicy != ClickToFocus ); rollOverDesktops = config->readBoolEntry("RollOverDesktops", TRUE); @@ -91,9 +94,10 @@ unsigned long Options::updateSettings() delete gc; placement = Placement::policyFromString( config->readEntry("Placement"), true ); + xineramaPlacementScreen = KCLAMP( config->readNumEntry( "XineramaPlacementScreen", -1 ), + -1, qApp->desktop()->numScreens() - 1 ); animateShade = config->readBoolEntry("AnimateShade", TRUE ); - animateMinimize = config->readBoolEntry("AnimateMinimize", TRUE ); animateMinimizeSpeed = config->readNumEntry("AnimateMinimizeSpeed", 5 ); diff --git a/kwin/options.h b/kwin/options.h index 59279fe80..034c9759b 100644 --- a/kwin/options.h +++ b/kwin/options.h @@ -124,6 +124,11 @@ class Options : public KDecorationOptions */ enum AltTabStyle { KDE, CDE }; AltTabStyle altTabStyle; + + // whether to see Xinerama screens separately for focus (in Alt+Tab, when activating next client) + bool separateScreenFocus; + // whether active Xinerama screen is the one with mouse (or with the active window) + bool activeMouseScreen; /** * Xinerama options @@ -133,6 +138,9 @@ class Options : public KDecorationOptions bool xineramaMovementEnabled; bool xineramaMaximizeEnabled; bool xineramaFullscreenEnabled; + + // number, or -1 = active screen (Workspace::activeScreen()) + int xineramaPlacementScreen; /** MoveResizeMode, either Tranparent or Opaque. diff --git a/kwin/placement.cpp b/kwin/placement.cpp index 223b95c5b..e9ae1b95e 100644 --- a/kwin/placement.cpp +++ b/kwin/placement.cpp @@ -473,7 +473,7 @@ void Placement::placeOnMainWindow(Client* c, QRect& area, Policy nextPlacement ) it != mainwindows.end(); ++it ) { - if( (*it)->isSpecialWindow()) + if( mainwindows.count() > 1 && (*it)->isSpecialWindow()) continue; // don't consider toolbars etc when placing ++mains_count; place_on2 = *it; @@ -502,6 +502,11 @@ void Placement::placeOnMainWindow(Client* c, QRect& area, Policy nextPlacement ) } place_on = place_on2; // use the only window filtered together with 'mains_count' } + if( place_on->isDesktop()) + { + place( c, area, Centered ); + return; + } QRect geom = c->geometry(); geom.moveCenter( place_on->geometry().center()); c->move( geom.topLeft()); diff --git a/kwin/popupinfo.cpp b/kwin/popupinfo.cpp index aef5dbea7..906489e67 100644 --- a/kwin/popupinfo.cpp +++ b/kwin/popupinfo.cpp @@ -25,7 +25,6 @@ License. See the file "COPYING" for the exact licensing terms. #include <klocale.h> #include <qapplication.h> #include <qdesktopwidget.h> -#include <qcursor.h> #include <kstringhandler.h> #include <kglobalsettings.h> @@ -34,8 +33,8 @@ License. See the file "COPYING" for the exact licensing terms. namespace KWinInternal { -PopupInfo::PopupInfo( const char *name ) - : QWidget( 0, name ) +PopupInfo::PopupInfo( Workspace* ws, const char *name ) + : QWidget( 0, name ), workspace( ws ) { m_infoString = ""; m_shown = false; @@ -60,7 +59,7 @@ PopupInfo::~PopupInfo() */ void PopupInfo::reset() { - QRect r = KGlobalSettings::desktopGeometry(QCursor::pos()); + QRect r = workspace->screenGeometry( workspace->activeScreen()); int w = fontMetrics().width( m_infoString ) + 30; diff --git a/kwin/popupinfo.h b/kwin/popupinfo.h index 11936fcfb..0b31846ed 100644 --- a/kwin/popupinfo.h +++ b/kwin/popupinfo.h @@ -24,7 +24,7 @@ class PopupInfo : public QWidget { Q_OBJECT public: - PopupInfo( const char *name=0 ); + PopupInfo( Workspace* ws, const char *name=0 ); ~PopupInfo(); void reset(); @@ -43,6 +43,7 @@ class PopupInfo : public QWidget bool m_show; bool m_shown; QString m_infoString; + Workspace* workspace; }; } // namespace diff --git a/kwin/tabbox.cpp b/kwin/tabbox.cpp index 96440e7af..29bef47b8 100644 --- a/kwin/tabbox.cpp +++ b/kwin/tabbox.cpp @@ -23,7 +23,6 @@ License. See the file "COPYING" for the exact licensing terms. #include <klocale.h> #include <qapplication.h> #include <qdesktopwidget.h> -#include <qcursor.h> #include <kstringhandler.h> #include <stdarg.h> #include <kdebug.h> @@ -110,26 +109,36 @@ void TabBox::createClientList(ClientList &list, int desktop /*-1 = all*/, Client while ( c ) { + Client* add = NULL; if ( ((desktop == -1) || c->isOnDesktop(desktop)) && c->wantsTabFocus() ) + { // don't add windows that have modal dialogs + Client* modal = c->findModal(); + if( modal == NULL || modal == c ) + add = c; + else if( !list.contains( modal )) + add = modal; + else + { + // nothing + } + } + + if( options->separateScreenFocus && options->xineramaEnabled ) { - if ( start == c ) + if( c->screen() != workspace()->activeScreen()) + add = NULL; + } + + if( add != NULL ) + { + if ( start == add ) { - list.remove( c ); - list.prepend( c ); + list.remove( add ); + list.prepend( add ); } else - { // don't add windows that have modal dialogs - Client* modal = c->findModal(); - if( modal == NULL || modal == c ) - list += c; - else if( !list.contains( modal )) - list += modal; - else - { - // nothing - } - } + list += add; } if ( chain ) @@ -156,7 +165,7 @@ void TabBox::reset() { int w, h, cw = 0, wmax = 0; - QRect r = KGlobalSettings::desktopGeometry(QCursor::pos()); + QRect r = workspace()->screenGeometry( workspace()->activeScreen()); // calculate height of 1 line // fontheight + 1 pixel above + 1 pixel below, or 32x32 icon + 2 pixel above + below diff --git a/kwin/useractions.cpp b/kwin/useractions.cpp index b722bf1a1..4a431b339 100644 --- a/kwin/useractions.cpp +++ b/kwin/useractions.cpp @@ -482,27 +482,33 @@ bool Client::performMouseCommand( Options::MouseCommand command, QPoint globalPo case Options::MouseActivateAndRaise: replay = isActive(); // for clickraise mode workspace()->takeActivity( this, ActivityFocus | ActivityRaise, handled && replay ); + workspace()->setActiveScreenMouse( globalPos ); break; case Options::MouseActivateAndLower: workspace()->requestFocus( this ); workspace()->lowerClient( this ); + workspace()->setActiveScreenMouse( globalPos ); break; case Options::MouseActivate: replay = isActive(); // for clickraise mode workspace()->takeActivity( this, ActivityFocus, handled && replay ); + workspace()->setActiveScreenMouse( globalPos ); break; case Options::MouseActivateRaiseAndPassClick: workspace()->takeActivity( this, ActivityFocus | ActivityRaise, handled ); + workspace()->setActiveScreenMouse( globalPos ); replay = TRUE; break; case Options::MouseActivateAndPassClick: workspace()->takeActivity( this, ActivityFocus, handled ); + workspace()->setActiveScreenMouse( globalPos ); replay = TRUE; break; case Options::MouseActivateRaiseAndMove: case Options::MouseActivateRaiseAndUnrestrictedMove: workspace()->raiseClient( this ); workspace()->requestFocus( this ); + workspace()->setActiveScreenMouse( globalPos ); if( options->moveMode == Options::Transparent && isMovable()) move_faked_activity = workspace()->fakeRequestedActivity( this ); // fallthrough @@ -709,6 +715,40 @@ void Workspace::slotWindowToDesktop( int i ) sendClientToDesktop( c, i, true ); } +void Workspace::slotSwitchToScreen( int i ) + { + setCurrentScreen( i ); + } + +void Workspace::slotSwitchToNextScreen() + { + slotSwitchToScreen(( activeScreen() + 1 ) % numScreens()); + } + +void Workspace::slotWindowToScreen( int i ) + { + Client* c = active_popup_client ? active_popup_client : active_client; + if( i >= 0 && i <= numScreens() && c + && !c->isDesktop() + && !c->isDock() + && !c->isTopMenu()) + { + sendClientToScreen( c, i ); + } + } + +void Workspace::slotWindowToNextScreen() + { + Client* c = active_popup_client ? active_popup_client : active_client; + if( c + && !c->isDesktop() + && !c->isDock() + && !c->isTopMenu()) + { + sendClientToScreen( c, ( c->screen() + 1 ) % numScreens()); + } + } + /*! Maximizes the popup client */ diff --git a/kwin/utils.cpp b/kwin/utils.cpp index b0f77df37..7c4fd00eb 100644 --- a/kwin/utils.cpp +++ b/kwin/utils.cpp @@ -314,7 +314,7 @@ bool isLocalMachine( const QCString& host ) hostnamebuf[sizeof(hostnamebuf)-1] = 0; if (host == hostnamebuf) return true; - if( char *dot = strchr(hostnamebuf, '.')) + if( char *dot = (char*)strchr(hostnamebuf, '.')) { *dot = '\0'; if( host == hostnamebuf ) diff --git a/kwin/workspace.cpp b/kwin/workspace.cpp index 1335a888c..2bf94c9a5 100644 --- a/kwin/workspace.cpp +++ b/kwin/workspace.cpp @@ -71,6 +71,7 @@ Workspace::Workspace( bool restore ) QObject (0, "workspace"), current_desktop (0), number_of_desktops(0), + active_screen (0), active_popup( NULL ), active_popup_client( NULL ), desktop_widget (0), @@ -191,7 +192,7 @@ Workspace::Workspace( bool restore ) client_keys = new KGlobalAccel( this ); initShortcuts(); tab_box = new TabBox( this ); - popupinfo = new PopupInfo( ); + popupinfo = new PopupInfo( this ); init(); @@ -290,6 +291,7 @@ void Workspace::init() NET::WM2ExtendedStrut | NET::WM2KDETemporaryRules | NET::WM2ShowingDesktop | + NET::WM2FullPlacement | NET::WM2DesktopLayout | 0 , @@ -1523,6 +1525,81 @@ void Workspace::sendClientToDesktop( Client* c, int desk, bool dont_activate ) updateClientArea(); } +int Workspace::numScreens() const + { + if( !options->xineramaEnabled ) + return 0; + return qApp->desktop()->numScreens(); + } + +int Workspace::activeScreen() const + { + if( !options->xineramaEnabled ) + return 0; + if( !options->activeMouseScreen ) + { + if( activeClient() != NULL && !activeClient()->isOnScreen( active_screen )) + return qApp->desktop()->screenNumber( activeClient()->geometry().center()); + return active_screen; + } + return qApp->desktop()->screenNumber( QCursor::pos()); + } + +// check whether a client moved completely out of what's considered the active screen, +// if yes, set a new active screen +void Workspace::checkActiveScreen( const Client* c ) + { + if( !options->xineramaEnabled ) + return; + if( !c->isActive()) + return; + if( !c->isOnScreen( active_screen )) + active_screen = c->screen(); + } + +// called e.g. when a user clicks on a window, set active screen to be the screen +// where the click occured +void Workspace::setActiveScreenMouse( QPoint mousepos ) + { + if( !options->xineramaEnabled ) + return; + active_screen = qApp->desktop()->screenNumber( mousepos ); + } + +QRect Workspace::screenGeometry( int screen ) const + { + if( !options->xineramaEnabled ) + return qApp->desktop()->geometry(); + return qApp->desktop()->screenGeometry( screen ); + } + +int Workspace::screenNumber( QPoint pos ) const + { + if( !options->xineramaEnabled ) + return 0; + return qApp->desktop()->screenNumber( pos ); + } + +void Workspace::sendClientToScreen( Client* c, int screen ) + { + if( c->screen() == screen ) // don't use isOnScreen(), that's true even when only partially + return; + GeometryUpdatesPostponer blocker( c ); + QRect old_sarea = clientArea( MaximizeArea, c ); + QRect sarea = clientArea( MaximizeArea, screen, c->desktop()); + c->setGeometry( sarea.x() - old_sarea.x() + c->x(), sarea.y() - old_sarea.y() + c->y(), + c->size().width(), c->size().height()); + c->checkWorkspacePosition(); + ClientList transients_stacking_order = ensureStackingOrder( c->transients()); + for( ClientList::ConstIterator it = transients_stacking_order.begin(); + it != transients_stacking_order.end(); + ++it ) + sendClientToScreen( *it, screen ); + if( c->isActive()) + active_screen = screen; + } + + void Workspace::setDesktopLayout( int, int, int ) { // DCOP-only, unused } diff --git a/kwin/workspace.h b/kwin/workspace.h index 9ccf889b4..efb31de8a 100644 --- a/kwin/workspace.h +++ b/kwin/workspace.h @@ -91,6 +91,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine QRect clientArea( clientAreaOption, const QPoint& p, int desktop ) const; QRect clientArea( clientAreaOption, const Client* c ) const; + QRect clientArea( clientAreaOption, int screen, int desktop ) const; /** * @internal @@ -161,6 +162,13 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine */ int numberOfDesktops() const; void setNumberOfDesktops( int n ); + + int activeScreen() const; + int numScreens() const; + void checkActiveScreen( const Client* c ); + void setActiveScreenMouse( QPoint mousepos ); + QRect screenGeometry( int screen ) const; + int screenNumber( QPoint pos ) const; QWidget* desktopWidget(); @@ -186,9 +194,11 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine void sendClientToDesktop( Client* c, int desktop, bool dont_activate ); void windowToPreviousDesktop( Client* c ); void windowToNextDesktop( Client* c ); + void sendClientToScreen( Client* c, int screen ); // KDE4 remove me - and it's also in the DCOP interface :( void showWindowMenuAt( unsigned long id, int x, int y ); + void kDestopResized(); /** * Shows the menu operations menu for the client and makes it active if @@ -224,6 +234,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine void nextDesktop(); void previousDesktop(); void circulateDesktopApplications(); + void setCurrentScreen( int new_screen ); QString desktopName( int desk ) const; virtual void setDesktopLayout(int , int , int ); @@ -301,6 +312,10 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine //void slotSwitchToWindow( int ); void slotWindowToDesktop( int ); //void slotWindowToListPosition( int ); + void slotSwitchToScreen( int ); + void slotWindowToScreen( int ); + void slotSwitchToNextScreen(); + void slotWindowToNextScreen(); void slotWindowMaximize(); void slotWindowMaximizeVertical(); @@ -481,6 +496,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine int current_desktop; int number_of_desktops; QMemArray<int> desktop_focus_chain; + int active_screen; QWidget* active_popup; Client* active_popup_client; diff --git a/kxkb/extension.cpp b/kxkb/extension.cpp index f4eee125c..405208020 100644 --- a/kxkb/extension.cpp +++ b/kxkb/extension.cpp @@ -4,6 +4,7 @@ #include <qstring.h> #include <qmap.h> #include <qfile.h> +#include <qdir.h> #include <kdebug.h> #include <kstandarddirs.h> @@ -176,12 +177,18 @@ bool XKBExtension::setLayoutInternal(const QString& model, if( !fullVariant.isNull() && !fullVariant.isEmpty() ) p << "-variant" << fullVariant; - if (p.start(KProcess::Block) && p.normalExit() && (p.exitStatus() == 0)) { - return true; //setGroup( group ); - } - else { - return false; - } + p.start(KProcess::Block); + + // reload ubuntu hotkey-setup keycode -> keysym maps + KProcess pXmodmap; + pXmodmap << "/usr/bin/xmodmap" << "/usr/share/apps/kxkb/ubuntu.xmodmap"; + pXmodmap.start(KProcess::Block); + + KProcess pXmodmapHome; + pXmodmapHome << "/usr/bin/xmodmap" << QDir::home().path() + "/.Xmodmap"; + pXmodmapHome.start(KProcess::Block); + + return p.normalExit() && (p.exitStatus() == 0); } bool XKBExtension::setGroup(unsigned int group) diff --git a/libkonq/konq_iconviewwidget.cc b/libkonq/konq_iconviewwidget.cc index 99d92ebde..f30873a9e 100644 --- a/libkonq/konq_iconviewwidget.cc +++ b/libkonq/konq_iconviewwidget.cc @@ -1848,7 +1848,7 @@ void KonqIconViewWidget::visualActivate(QIconViewItem * item) // Adjust for scrolling (David) rect.moveBy( -contentsX(), -contentsY() ); - KIconEffect::visualActivate(viewport(), rect); + KIconEffect::visualActivate(viewport(), rect, item->pixmap()); } void KonqIconViewWidget::backgroundPixmapChange( const QPixmap & ) diff --git a/nsplugins/plugin_paths.cpp b/nsplugins/plugin_paths.cpp index 3e8c71712..2c228ac25 100644 --- a/nsplugins/plugin_paths.cpp +++ b/nsplugins/plugin_paths.cpp @@ -41,6 +41,8 @@ QStringList getSearchPaths() // keep sync with kdebase/kcontrol/konqhtml paths.append("$HOME/.mozilla/plugins"); paths.append("$HOME/.netscape/plugins"); + paths.append("/usr/lib/iceweasel/plugins"); + paths.append("/usr/lib/iceape/plugins"); paths.append("/usr/lib/firefox/plugins"); paths.append("/usr/lib64/browser-plugins"); paths.append("/usr/lib/browser-plugins"); @@ -19,12 +19,21 @@ fi # people's heads. We use colours from the standard KDE palette for those with # palettised displays. if test -z "$XDM_MANAGED" || echo "$XDM_MANAGED" | grep ",auto" > /dev/null; then - xsetroot -solid "#000000" + xsetroot -solid "#618DCC" fi # we have to unset this for Darwin since it will screw up KDE's dynamic-loading unset DYLD_FORCE_FLAT_NAMESPACE +# Check if prelinking is enabled. If so, exporting KDE_IS_PRELINKED improves +# loading KDE. +if test -f /etc/default/prelink; then + . /etc/default/prelink + if [ "$PRELINKING" == yes ]; then + export KDE_IS_PRELINKED=1 + fi +fi + # in case we have been started with full pathname spec without being in PATH bindir=`echo "$0" | sed -n 's,^\(/.*\)/[^/][^/]*$,\1,p'` if [ -n "$bindir" ]; then @@ -48,10 +57,10 @@ fi # # * Then ksmserver is started which takes control of the rest of the startup sequence -# The user's personal KDE directory is usually ~/.kde, but this setting +# The user's personal KDE directory is usually ~/.kde3, but this setting # may be overridden by setting KDEHOME. -kdehome=$HOME/.kde +export KDEHOME=$HOME/.kde3 && export PATH=/opt/kde3/bin:/opt/kde3/games:$PATH && export KDEDIRS=/usr/:/opt/kde3/ && export XDG_DATA_DIRS=/opt/kde3/share/:/usr/share/ && export XDG_CONFIG_DIRS=/opt/kde3/etc/xdg/:/etc/xdg/ && export MANPATH=/opt/kde3/share/man:$MANPATH && export DESKTOP_SESSION=kde3 test -n "$KDEHOME" && kdehome=`echo "$KDEHOME"|sed "s,^~/,$HOME/,"` # see kstartupconfig source for usage @@ -160,8 +169,22 @@ Xft.dpi: 96 EOF fi +# configuration of the gtk_qt_engine if not already set + +if [ ! -e $kdehome/env/gtk-qt-engine.rc.sh ] && [ -e /usr/share/kubuntu-default-settings/gtk-qt-engine.rc.sh ] +then + mkdir -p $kdehome/env + cp -f /usr/share/kubuntu-default-settings/gtk-qt-engine.rc.sh $kdehome/env + chmod 755 $kdehome/env/gtk-qt-engine.rc.sh +fi + +if [ ! -e $HOME/.gtkrc-2.0-kde ] && [ -e /usr/share/kubuntu-default-settings/.gtkrc-2.0-kde ] +then + cp -f /usr/share/kubuntu-default-settings/.gtkrc-2.0-kde $HOME +fi + # Source scripts found in <localprefix>/env/*.sh and <prefixes>/env/*.sh -# (where <localprefix> is $KDEHOME or ~/.kde, and <prefixes> is where KDE is installed) +# (where <localprefix> is $KDEHOME or ~/.kde3, and <prefixes> is where KDE is installed) # # This is where you can define environment variables that will be available to # all KDE programs, so this is where you can run agents using e.g. eval `ssh-agent` @@ -287,17 +310,26 @@ echo 'startkde: Starting up...' 1>&2 # run KPersonalizer before the session, if this is the first login if test "$kpersonalizerrc_general_firstlogin" = "true"; then - # start only dcopserver, don't start whole kdeinit (takes too long) - echo 'startkde: Running kpersonalizer...' 1>&2 - dcopserver - kwin --lock & - kpersonalizer --before-session - # handle kpersonalizer restarts (language change) - while test $? -eq 1; do - kpersonalizer --r --before-session - done - dcopquit kwin - dcopserver_shutdown --wait + if [ ! -x /opt/kde3/bin/kpersonalizer ]; then + echo 'startkde: kpersonalizer not found! Please install to properly configure your user.' 1>&2 + else + # start only dcopserver, don't start whole kdeinit (takes too long) + echo 'startkde: Running kpersonalizer...' 1>&2 + dcopserver + kwin --lock & + kpersonalizer --before-session + # handle kpersonalizer restarts (language change) + while test $? -eq 1; do + kpersonalizer --r --before-session + done + dcopquit kwin + dcopserver_shutdown --wait + fi +fi + +#remove moodin cache if we have a new wallpaper installed, jriddell +if [ /usr/share/wallpapers/kubuntu-wallpaper.png -nt $kdehome/share/apps/ksplash/cache/Moodin/kubuntu/ ]; then + rm -rf $kdehome/share/apps/ksplash/cache/Moodin/kubuntu/; fi if test -z "$dl"; then @@ -358,6 +390,15 @@ if test -n "$dl"; then sleep 1 fi +# configuration of kwalletmanager if not already set + +if [ ! -e $kdehome/share/config/kwalletrc ] && [ -e /usr/share/kubuntu-default-settings/kde-profile/default/share/config/kwalletrc ] +then + mkdir -p "$kdehome/share/config/" + cp -f /usr/share/kubuntu-default-settings/kde-profile/default/share/config/kwalletrc $kdehome/share/config/ +fi + + # finally, give the session control to the session manager # see kdebase/ksmserver for the description of the rest of the startup sequence # if the KDEWM environment variable has been set, then it will be used as KDE's |