diff options
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 <staikos@kde.org> + * Copyright (c) 2001 Fernando Llobregat <fernando.llobregat@free.fr> + * + * 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, "kb9vqf@pearsoncomputing.net"); + 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 <kb9vqf@pearsoncomputing.net> + * + * 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 <nalin@redhat.com> - 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 <pfeiffer@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#include <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 <pfeiffer@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#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 <kb9vqf@pearsoncomputing.net> + Copyright (C) 1999-2002,2003 Dawit Alemayehu <adawit@kde.org> Copyright (C) 2000 Malte Starostik <starosti@zedat.fu-berlin.de> Copyright (C) 2003 Sven Leiber <s.leiber@web.de> @@ -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 <mccann@jhu.edu> + * Copyright (C) 2007 Kevin Kofler <Kevin@tigcc.ticalc.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include "dm.h" +#include "dm_auth.h" +#include "dm_error.h" + +#include <stdlib.h> +#include <string.h> +#include <pwd.h> + +#define DBUS_API_SUBJECT_TO_CHANGE +#include <dbus/dbus.h> + +#include "consolekit.h" + + +#define CK_NAME "org.freedesktop.ConsoleKit" +#define CK_PATH "/org/freedesktop/ConsoleKit" +#define CK_INTERFACE "org.freedesktop.ConsoleKit" +#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager" +#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager" +#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session" + +static DBusConnection *private_connection = NULL; + +static void +add_param_int (DBusMessageIter *iter_struct, + const char *key, + int value) +{ + DBusMessageIter iter_struct_entry; + DBusMessageIter iter_var; + + dbus_message_iter_open_container (iter_struct, + DBUS_TYPE_STRUCT, + NULL, + &iter_struct_entry); + + dbus_message_iter_append_basic (&iter_struct_entry, + DBUS_TYPE_STRING, + &key); + + dbus_message_iter_open_container (&iter_struct_entry, + DBUS_TYPE_VARIANT, + DBUS_TYPE_INT32_AS_STRING, + &iter_var); + + dbus_message_iter_append_basic (&iter_var, + DBUS_TYPE_INT32, + &value); + + dbus_message_iter_close_container (&iter_struct_entry, + &iter_var); + + dbus_message_iter_close_container (iter_struct, &iter_struct_entry); +} + +static void +add_param_boolean (DBusMessageIter *iter_struct, + const char *key, + int value) +{ + DBusMessageIter iter_struct_entry; + DBusMessageIter iter_var; + + dbus_message_iter_open_container (iter_struct, + DBUS_TYPE_STRUCT, + NULL, + &iter_struct_entry); + + dbus_message_iter_append_basic (&iter_struct_entry, + DBUS_TYPE_STRING, + &key); + + dbus_message_iter_open_container (&iter_struct_entry, + DBUS_TYPE_VARIANT, + DBUS_TYPE_BOOLEAN_AS_STRING, + &iter_var); + + dbus_message_iter_append_basic (&iter_var, + DBUS_TYPE_BOOLEAN, + &value); + + dbus_message_iter_close_container (&iter_struct_entry, + &iter_var); + + dbus_message_iter_close_container (iter_struct, &iter_struct_entry); +} + +static void +add_param_string (DBusMessageIter *iter_struct, + const char *key, + const char *value) +{ + DBusMessageIter iter_struct_entry; + DBusMessageIter iter_var; + + dbus_message_iter_open_container (iter_struct, + DBUS_TYPE_STRUCT, + NULL, + &iter_struct_entry); + + dbus_message_iter_append_basic (&iter_struct_entry, + DBUS_TYPE_STRING, + &key); + + dbus_message_iter_open_container (&iter_struct_entry, + DBUS_TYPE_VARIANT, + DBUS_TYPE_STRING_AS_STRING, + &iter_var); + + dbus_message_iter_append_basic (&iter_var, + DBUS_TYPE_STRING, + &value); + + dbus_message_iter_close_container (&iter_struct_entry, + &iter_var); + + dbus_message_iter_close_container (iter_struct, &iter_struct_entry); +} + +static int +session_get_x11_display (DBusConnection *connection, + const char *ssid, + char **str) +{ + DBusError error; + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + const char *value; + + if (str != NULL) { + *str = NULL; + } + + message = dbus_message_new_method_call (CK_NAME, + ssid, + CK_SESSION_INTERFACE, + "GetX11Display"); + if (message == NULL) { + Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); + return FALSE; + } + + dbus_error_init (&error); + reply = dbus_connection_send_with_reply_and_block (connection, + message, + -1, &error); + if (dbus_error_is_set (&error)) { + Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); + reply = NULL; + } + + dbus_connection_flush (connection); + dbus_message_unref (message); + + if (reply == NULL) { + return FALSE; + } + + dbus_message_iter_init (reply, &iter); + dbus_message_iter_get_basic (&iter, &value); + if (str != NULL) { + *str = strdup (value); + } + dbus_message_unref (reply); + + return TRUE; +} + +static int +session_unlock (DBusConnection *connection, + const char *ssid) +{ + DBusError error; + DBusMessage *message; + DBusMessage *reply; + + Debug ("ConsoleKit: Unlocking session %s", ssid); + message = dbus_message_new_method_call (CK_NAME, + ssid, + CK_SESSION_INTERFACE, + "Unlock"); + if (message == NULL) { + Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); + return FALSE; + } + + dbus_error_init (&error); + reply = dbus_connection_send_with_reply_and_block (connection, + message, + -1, &error); + dbus_message_unref (message); + dbus_message_unref (reply); + dbus_connection_flush (connection); + + if (dbus_error_is_set (&error)) { + Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); + return FALSE; + } + + return TRUE; +} + +/* from libhal */ +static char ** +get_path_array_from_iter (DBusMessageIter *iter, + int *num_elements) +{ + int count; + char **buffer; + + count = 0; + buffer = (char **)malloc (sizeof (char *) * 8); + + if (buffer == NULL) + goto oom; + + buffer[0] = NULL; + while (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_OBJECT_PATH) { + const char *value; + char *str; + + if ((count % 8) == 0 && count != 0) { + buffer = realloc (buffer, sizeof (char *) * (count + 8)); + if (buffer == NULL) + goto oom; + } + + dbus_message_iter_get_basic (iter, &value); + str = strdup (value); + if (str == NULL) + goto oom; + + buffer[count] = str; + + dbus_message_iter_next (iter); + count++; + } + + if ((count % 8) == 0) { + buffer = realloc (buffer, sizeof (char *) * (count + 1)); + if (buffer == NULL) + goto oom; + } + + buffer[count] = NULL; + if (num_elements != NULL) + *num_elements = count; + return buffer; + +oom: + LogWarn ("%s %d : error allocating memory\n", __FILE__, __LINE__); + return NULL; + +} + +static char ** +get_sessions_for_user (DBusConnection *connection, + const char *user, + const char *x11_display) +{ + DBusError error; + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + DBusMessageIter iter_reply; + DBusMessageIter iter_array; + struct passwd *pwent; + char **sessions; + + sessions = NULL; + message = NULL; + reply = NULL; + + pwent = getpwnam (user); + + dbus_error_init (&error); + message = dbus_message_new_method_call (CK_NAME, + CK_MANAGER_PATH, + CK_MANAGER_INTERFACE, + "GetSessionsForUser"); + if (message == NULL) { + Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); + goto out; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, + DBUS_TYPE_UINT32, + &pwent->pw_uid); + + dbus_error_init (&error); + reply = dbus_connection_send_with_reply_and_block (connection, + message, + -1, &error); + dbus_connection_flush (connection); + + if (dbus_error_is_set (&error)) { + Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); + goto out; + } + + if (reply == NULL) { + Debug ("ConsoleKit: No reply for GetSessionsForUser"); + goto out; + } + + dbus_message_iter_init (reply, &iter_reply); + if (dbus_message_iter_get_arg_type (&iter_reply) != DBUS_TYPE_ARRAY) { + Debug ("ConsoleKit: Wrong reply for GetSessionsForUser - expecting an array."); + goto out; + } + + dbus_message_iter_recurse (&iter_reply, &iter_array); + sessions = get_path_array_from_iter (&iter_array, NULL); + + out: + if (message != NULL) { + dbus_message_unref (message); + } + if (reply != NULL) { + dbus_message_unref (reply); + } + + return sessions; +} + +void +unlock_ck_session (const char *user, + const char *x11_display) +{ + DBusError error; + DBusConnection *connection; + char **sessions; + int i; + + Debug ("ConsoleKit: Unlocking session for %s on %s", user, x11_display); + + dbus_error_init (&error); + connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); + if (connection == NULL) { + Debug ("ConsoleKit: Failed to connect to the D-Bus daemon: %s", error.message); + dbus_error_free (&error); + return; + } + + sessions = get_sessions_for_user (connection, user, x11_display); + if (sessions == NULL || sessions[0] == NULL) { + Debug ("ConsoleKit: no sessions found"); + return; + } + + for (i = 0; sessions[i] != NULL; i++) { + char *ssid; + char *xdisplay; + + ssid = sessions[i]; + session_get_x11_display (connection, ssid, &xdisplay); + Debug ("ConsoleKit: session %s has DISPLAY %s", ssid, xdisplay); + + if (xdisplay != NULL + && x11_display != NULL + && strcmp (xdisplay, x11_display) == 0) { + int res; + + res = session_unlock (connection, ssid); + if (! res) { + LogError ("ConsoleKit: Unable to unlock %s", ssid); + } + } + + free (xdisplay); + } + + freeStrArr (sessions); +} + +char * +open_ck_session (struct passwd *pwent, + struct display *d) +{ + DBusConnection *connection; + DBusError error; + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + DBusMessageIter iter_struct; + char *cookie; + + cookie = NULL; + + 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 <mccann@jhu.edu> + * Copyright (C) 2007 Kevin Kofler <Kevin@tigcc.ticalc.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + + +#ifndef __CONSOLE_KIT_H +#define __CONSOLE_KIT_H + +#include <pwd.h> + +struct display; + +char * open_ck_session (struct passwd *pwent, + struct display *display); +void close_ck_session (const char *cookie); +void unlock_ck_session (const char *user, + const char *x11_display); + +#endif /* __CONSOLE_KIT_H */ 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 <dgollub@suse.de> + * + * 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 <dgollub@suse.de> + * + * 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 <ettrich@kde.org> #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 <ettrich@kde.org> #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 <ettrich@kde.org> #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 |