summaryrefslogtreecommitdiffstats
path: root/kiosktool
diff options
context:
space:
mode:
Diffstat (limited to 'kiosktool')
-rw-r--r--kiosktool/Makefile.am62
-rw-r--r--kiosktool/background.pngbin0 -> 1583 bytes
-rw-r--r--kiosktool/caption-da.pngbin0 -> 20749 bytes
-rw-r--r--kiosktool/caption-empty.pngbin0 -> 912 bytes
-rw-r--r--kiosktool/caption-et.pngbin0 -> 15081 bytes
-rw-r--r--kiosktool/caption-pt.pngbin0 -> 28703 bytes
-rw-r--r--kiosktool/caption-pt_BR.pngbin0 -> 28703 bytes
-rw-r--r--kiosktool/caption-sv.pngbin0 -> 22583 bytes
-rw-r--r--kiosktool/caption.pngbin0 -> 20656 bytes
-rw-r--r--kiosktool/component.cpp52
-rw-r--r--kiosktool/component.h40
-rw-r--r--kiosktool/componentPage.cpp306
-rw-r--r--kiosktool/componentPage.h65
-rw-r--r--kiosktool/componentPage_ui.ui195
-rw-r--r--kiosktool/componentSelectionPage.cpp143
-rw-r--r--kiosktool/componentSelectionPage.h59
-rw-r--r--kiosktool/componentSelectionPage_ui.ui124
-rw-r--r--kiosktool/configure.in.in2
-rw-r--r--kiosktool/cr16-app-kiosktool.pngbin0 -> 528 bytes
-rw-r--r--kiosktool/cr32-app-kiosktool.pngbin0 -> 1021 bytes
-rw-r--r--kiosktool/cr48-app-kiosktool.pngbin0 -> 1612 bytes
-rw-r--r--kiosktool/desktopComponent.cpp239
-rw-r--r--kiosktool/desktopComponent.h50
-rwxr-xr-xkiosktool/extractxml120
-rw-r--r--kiosktool/filetypeeditComponent.cpp133
-rw-r--r--kiosktool/filetypeeditComponent.h42
-rw-r--r--kiosktool/kcms/Makefile.am6
-rw-r--r--kiosktool/kcms/autostart/Makefile.am17
-rw-r--r--kiosktool/kcms/autostart/kcmautostart.cpp202
-rw-r--r--kiosktool/kcms/autostart/kcmautostart.desktop56
-rw-r--r--kiosktool/kcms/autostart/kcmautostart.h66
-rw-r--r--kiosktool/kioskConfigDialog.cpp149
-rw-r--r--kiosktool/kioskConfigDialog.h46
-rw-r--r--kiosktool/kioskConfigDialog_ui.ui329
-rw-r--r--kiosktool/kiosk_data.xml778
-rw-r--r--kiosktool/kioskdata.cpp309
-rw-r--r--kiosktool/kioskdata.h105
-rw-r--r--kiosktool/kioskgui.cpp727
-rw-r--r--kiosktool/kioskgui.h109
-rw-r--r--kiosktool/kioskrun.cpp1687
-rw-r--r--kiosktool/kioskrun.h229
-rw-r--r--kiosktool/kiosksync.cpp211
-rw-r--r--kiosktool/kiosksync.h80
-rw-r--r--kiosktool/kiosktool-kdedirs.cpp184
-rw-r--r--kiosktool/kiosktool.desktop28
-rw-r--r--kiosktool/kiosktoolui.rc13
-rw-r--r--kiosktool/logo.pngbin0 -> 4734 bytes
-rw-r--r--kiosktool/main.cpp80
-rw-r--r--kiosktool/mainview.ui258
-rw-r--r--kiosktool/menueditComponent.cpp241
-rw-r--r--kiosktool/menueditComponent.h43
-rw-r--r--kiosktool/pageWidget.cpp210
-rw-r--r--kiosktool/pageWidget.h67
-rw-r--r--kiosktool/panelComponent.cpp83
-rw-r--r--kiosktool/panelComponent.h42
-rw-r--r--kiosktool/profilePropsPage.cpp234
-rw-r--r--kiosktool/profilePropsPage.h51
-rw-r--r--kiosktool/profilePropsPage_ui.ui255
-rw-r--r--kiosktool/profileSelectionPage_ui.ui230
-rw-r--r--kiosktool/screensaverComponent.cpp41
-rw-r--r--kiosktool/screensaverComponent.h41
-rw-r--r--kiosktool/userManagement.cpp306
-rw-r--r--kiosktool/userManagement.h60
-rw-r--r--kiosktool/userManagementGroup_ui.ui117
-rw-r--r--kiosktool/userManagementUser_ui.ui117
-rw-r--r--kiosktool/userManagement_ui.ui278
66 files changed, 9717 insertions, 0 deletions
diff --git a/kiosktool/Makefile.am b/kiosktool/Makefile.am
new file mode 100644
index 0000000..915f197
--- /dev/null
+++ b/kiosktool/Makefile.am
@@ -0,0 +1,62 @@
+## Makefile.am for kiosktool
+
+# this has all of the subdirectories that make will recurse into. if
+# there are none, comment this out
+SUBDIRS = . kcms
+
+# this is the program that gets installed. it's name is used for all
+# of the other Makefile.am variables
+bin_PROGRAMS = kiosktool kiosktool-kdedirs
+
+# set the include path for X, qt and KDE
+INCLUDES = $(all_includes)
+
+# the library search path.
+kiosktool_LDFLAGS = $(KDE_RPATH) $(all_libraries)
+
+# the libraries to link against.
+kiosktool_LDADD = $(LIB_KFILE) -lkdeprint
+
+# which sources should be compiled for kiosktool
+kiosktool_SOURCES = main.cpp kioskgui.cpp kioskdata.cpp kioskrun.cpp \
+ mainview.ui profileSelectionPage_ui.ui \
+ profilePropsPage.cpp profilePropsPage_ui.ui \
+ pageWidget.cpp component.cpp \
+ desktopComponent.cpp menueditComponent.cpp screensaverComponent.cpp \
+ panelComponent.cpp filetypeeditComponent.cpp \
+ componentSelectionPage.cpp componentSelectionPage_ui.ui \
+ componentPage.cpp componentPage_ui.ui \
+ userManagement.cpp userManagement_ui.ui userManagementGroup_ui.ui \
+ userManagementUser_ui.ui \
+ kioskConfigDialog.cpp kioskConfigDialog_ui.ui \
+ kiosksync.cpp
+
+# the library search path.
+kiosktool_kdedirs_LDFLAGS = $(KDE_RPATH) $(all_libraries)
+
+# the libraries to link against.
+kiosktool_kdedirs_LDADD = $(LIB_KDECORE)
+
+# which sources should be compiled for kiosktool
+kiosktool_kdedirs_SOURCES = kiosktool-kdedirs.cpp
+
+# these are the headers for your project
+noinst_HEADERS = kioskgui.h
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+
+messages: rc.cpp
+ ./extractxml kiosk_data.xml > kiosk_data.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/kiosktool.pot
+ rm kiosk_data.cpp
+
+KDE_ICON = kiosktool
+
+xdg_apps_DATA = kiosktool.desktop
+
+# this is where the XML-GUI resource file goes
+rcdir = $(kde_datadir)/kiosktool
+rc_DATA = kiosktoolui.rc kiosk_data.xml caption.png background.png logo.png \
+ caption-da.png caption-empty.png caption-et.png caption-pt.png caption-pt_BR.png \
+ caption-sv.png
diff --git a/kiosktool/background.png b/kiosktool/background.png
new file mode 100644
index 0000000..0341206
--- /dev/null
+++ b/kiosktool/background.png
Binary files differ
diff --git a/kiosktool/caption-da.png b/kiosktool/caption-da.png
new file mode 100644
index 0000000..7894085
--- /dev/null
+++ b/kiosktool/caption-da.png
Binary files differ
diff --git a/kiosktool/caption-empty.png b/kiosktool/caption-empty.png
new file mode 100644
index 0000000..07a6a3a
--- /dev/null
+++ b/kiosktool/caption-empty.png
Binary files differ
diff --git a/kiosktool/caption-et.png b/kiosktool/caption-et.png
new file mode 100644
index 0000000..8cba1b3
--- /dev/null
+++ b/kiosktool/caption-et.png
Binary files differ
diff --git a/kiosktool/caption-pt.png b/kiosktool/caption-pt.png
new file mode 100644
index 0000000..db57843
--- /dev/null
+++ b/kiosktool/caption-pt.png
Binary files differ
diff --git a/kiosktool/caption-pt_BR.png b/kiosktool/caption-pt_BR.png
new file mode 100644
index 0000000..db57843
--- /dev/null
+++ b/kiosktool/caption-pt_BR.png
Binary files differ
diff --git a/kiosktool/caption-sv.png b/kiosktool/caption-sv.png
new file mode 100644
index 0000000..358cad3
--- /dev/null
+++ b/kiosktool/caption-sv.png
Binary files differ
diff --git a/kiosktool/caption.png b/kiosktool/caption.png
new file mode 100644
index 0000000..0ce1c8d
--- /dev/null
+++ b/kiosktool/caption.png
Binary files differ
diff --git a/kiosktool/component.cpp b/kiosktool/component.cpp
new file mode 100644
index 0000000..f00c414
--- /dev/null
+++ b/kiosktool/component.cpp
@@ -0,0 +1,52 @@
+/*
+ * component.cpp
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 "component.h"
+
+Component::Component( QObject *parent)
+ : QObject(parent)
+{
+}
+
+Component::~Component()
+{
+}
+
+void
+Component::slotSetupPrepare()
+{
+}
+
+void
+Component::slotSetupStarted()
+{
+}
+
+void
+Component::slotPreviewStarted()
+{
+}
+
+bool
+Component::setupFinished()
+{
+ return true;
+}
+
+#include "component.moc"
diff --git a/kiosktool/component.h b/kiosktool/component.h
new file mode 100644
index 0000000..a9c4cd2
--- /dev/null
+++ b/kiosktool/component.h
@@ -0,0 +1,40 @@
+/*
+ * component.h
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _COMPONENT_H_
+#define _COMPONENT_H_
+
+#include <qobject.h>
+
+class Component : public QObject
+{
+ Q_OBJECT
+public:
+ Component( QObject *parent);
+ virtual ~Component();
+
+ virtual bool setupFinished();
+
+public slots:
+
+ virtual void slotSetupPrepare();
+ virtual void slotSetupStarted();
+ virtual void slotPreviewStarted();
+};
+
+#endif
diff --git a/kiosktool/componentPage.cpp b/kiosktool/componentPage.cpp
new file mode 100644
index 0000000..4793db4
--- /dev/null
+++ b/kiosktool/componentPage.cpp
@@ -0,0 +1,306 @@
+/*
+ * componentPage.cpp
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 "componentPage.h"
+
+#include <qcursor.h>
+#include <qfileinfo.h>
+#include <qlabel.h>
+#include <qstylesheet.h>
+#include <qtextedit.h>
+#include <qpushbutton.h>
+
+#include <dcopref.h>
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <klistview.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kprocess.h>
+#include <kstdguiitem.h>
+
+#include "component.h"
+#include "kioskdata.h"
+#include "kioskrun.h"
+
+ComponentPage::ComponentPage( ComponentData *data, Component *component, QWidget* parent, const char* name, WFlags fl )
+ : ComponentPageUI(parent, name, fl), PageWidget(this), m_data(data), m_component(component)
+{
+ m_process = 0;
+ connect(pbSetup, SIGNAL(clicked()), this, SLOT(slotSetup()));
+ connect(pbPreview, SIGNAL(clicked()), this, SLOT(slotPreview()));
+
+ pbSetup->setText(i18n("&Setup %1").arg(m_data->caption));
+ pbPreview->setText(i18n("&Preview %1").arg(m_data->caption));
+
+ if (m_data->preview.exec.isEmpty())
+ pbPreview->hide();
+
+ if (m_data->setup.exec.isEmpty())
+ pbSetup->hide();
+
+ if (!pbPreview->isHidden() && !pbSetup->isHidden())
+ {
+ static bool firstTime = true;
+
+ if (firstTime)
+ {
+ firstTime = false;
+ QTimer::singleShot(0, this, SLOT(slotShowNotice()));
+ }
+ }
+
+ fillActionList(listComponentConfig, m_data);
+
+ connect(listComponentConfig, SIGNAL(currentChanged(QListViewItem *)),
+ this, SLOT(slotShowAction(QListViewItem *)));
+ slotShowAction(listComponentConfig->currentItem());
+}
+
+ComponentPage::~ComponentPage()
+{
+ delete m_component;
+}
+
+void ComponentPage::slotShowNotice()
+{
+ KMessageBox::information(this,
+ i18n("Selecting the Setup or Preview option may cause the panel and/or the desktop to be temporarily shut down. "
+ "To prevent data loss please make sure you are not actively using these components."),
+ i18n("Attention"), "shutdown_notice");
+}
+
+void ComponentPage::load()
+{
+}
+
+bool ComponentPage::save()
+{
+ return saveActionListChanges(listComponentConfig);
+}
+
+void ComponentPage::setFocus()
+{
+ listComponentConfig->setFocus();
+}
+
+QString ComponentPage::subCaption()
+{
+ return i18n("Setup %1").arg(m_data->caption);
+}
+
+void ComponentPage::slotSetup()
+{
+ if (m_process)
+ {
+ m_process->kill();
+ delete m_process;
+ }
+ QCString dcopApp = m_data->setup.dcop.utf8();
+ QCString dcopObj = "qt/" + dcopApp;
+ if (!dcopApp.isEmpty() && m_data->setup.hasOption("restart"))
+ DCOPRef(dcopApp, dcopObj).call("quit");
+
+ QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) );
+ if (!KioskRun::self()->prepare())
+ {
+ QApplication::restoreOverrideCursor();
+ KMessageBox::sorry(this,
+ i18n("<qt>There was an unexpected problem with the runtime environment.</qt>"));
+ return;
+ }
+ KioskRun::self()->makeMutable(true);
+ if (!save())
+ {
+ QApplication::restoreOverrideCursor();
+ return;
+ }
+ if (m_component)
+ m_component->slotSetupPrepare();
+ KioskRun::self()->updateSycoca();
+ QApplication::restoreOverrideCursor();
+
+ if (!dcopApp.isEmpty())
+ {
+ KioskRun::self()->dcopClient()->setNotifications(true);
+ connect(KioskRun::self()->dcopClient(), SIGNAL(applicationRegistered( const QCString& )),
+ this, SLOT(slotSetupAppRegistered( const QCString& )));
+ }
+
+ QStringList args;
+ if (m_data->setup.hasOption("nofork"))
+ args << "--nofork";
+
+ args += m_data->setup.args;
+
+ m_process = KioskRun::self()->run(m_data->setup.exec, args);
+ int result = KMessageBox::questionYesNo(this,
+ i18n("<qt>You can now configure %1. "
+ "When you are finished click <b>Save</b> to make the new configuration permanent.")
+ .arg(m_data->caption), i18n("%1 Setup").arg(m_data->caption),
+ KStdGuiItem::save(), KStdGuiItem::discard());
+ m_saveSettings = (result == KMessageBox::Yes);
+ if (!dcopApp.isEmpty())
+ KioskRun::self()->dcopRef(dcopApp, dcopObj).call("quit");
+
+ if (m_process->isRunning())
+ {
+ connect(m_process, SIGNAL(processExited(KProcess *)), this, SLOT(slotPreviewDone()));
+ }
+ else
+ {
+ slotSetupDone();
+ }
+}
+
+void ComponentPage::slotSetupDone()
+{
+ delete m_process;
+ m_process = 0;
+
+ KioskRun::self()->dcopClient()->setNotifications(false);
+ disconnect(KioskRun::self()->dcopClient(), SIGNAL(applicationRegistered( const QCString& )),
+ this, SLOT(slotSetupAppRegistered( const QCString& )));
+
+ KioskRun::self()->makeMutable(false);
+ if (m_saveSettings)
+ {
+ bool result = true;
+ if (m_component)
+ result = m_component->setupFinished();
+
+ if (!result) return;
+
+ // Find new config files.
+ QStringList newFiles = KioskRun::self()->newConfigFiles();
+ for(QStringList::ConstIterator it = newFiles.begin();
+ it != newFiles.end(); ++it)
+ {
+ if (m_data->ignoreFiles.contains(*it))
+ {
+ kdDebug() << "Ignoring new config file " << (*it) << endl;
+ continue;
+ }
+ KioskRun::self()->mergeConfigFile(*it);
+ }
+ }
+ KioskRun::self()->flushConfigCache();
+
+ if (m_data->setup.hasOption("restart"))
+ KApplication::kdeinitExec(m_data->setup.exec);
+}
+
+void ComponentPage::slotSetupAppRegistered( const QCString &appid)
+{
+ QCString dcopApp = m_data->setup.dcop.utf8();
+ if (dcopApp == appid)
+ {
+ kdDebug() << appid << " is up and running" << endl;
+ if (m_component)
+ m_component->slotSetupStarted();
+ }
+}
+
+void ComponentPage::slotPreview()
+{
+ if (m_process)
+ {
+ m_process->kill();
+ delete m_process;
+ }
+ QCString dcopApp = m_data->preview.dcop.utf8();
+ QCString dcopObj = "qt/" + dcopApp;
+ if (!dcopApp.isEmpty() && m_data->preview.hasOption("restart"))
+ DCOPRef(dcopApp, dcopObj).call("quit");
+
+ QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) );
+ KioskRun::self()->prepare();
+ save();
+ KioskRun::self()->updateSycoca();
+ QApplication::restoreOverrideCursor();
+
+ if (!dcopApp.isEmpty())
+ {
+ KioskRun::self()->dcopClient()->setNotifications(true);
+ connect(KioskRun::self()->dcopClient(), SIGNAL(applicationRegistered( const QCString& )),
+ this, SLOT(slotPreviewAppRegistered( const QCString& )));
+ }
+
+ QStringList args;
+ if (m_data->preview.hasOption("nofork"))
+ args << "--nofork";
+
+ args += m_data->preview.args;
+
+ m_process = KioskRun::self()->run(m_data->preview.exec, args);
+ KMessageBox::information(this,
+ i18n("<qt>This is how %1 will behave and look with the new settings. "
+ "Any changes you now make to the settings will not be saved.<p>"
+ "Click <b>Ok</b> to return to your own personal %2 configuration.")
+ .arg(m_data->caption, m_data->caption), i18n("%1 Preview").arg(m_data->caption));
+ if (!dcopApp.isEmpty())
+ KioskRun::self()->dcopRef(dcopApp, dcopObj).call("quit");
+
+ if (m_process->isRunning())
+ {
+ connect(m_process, SIGNAL(processExited(KProcess *)), this, SLOT(slotPreviewDone()));
+ }
+ else
+ {
+ slotPreviewDone();
+ }
+}
+
+void ComponentPage::slotPreviewAppRegistered( const QCString &appid)
+{
+ QCString dcopApp = m_data->preview.dcop.utf8();
+ if (dcopApp == appid)
+ {
+ kdDebug() << appid << " is up and running" << endl;
+ if (m_component)
+ m_component->slotPreviewStarted();
+ }
+}
+
+void ComponentPage::slotPreviewDone()
+{
+ KioskRun::self()->dcopClient()->setNotifications(false);
+ disconnect(KioskRun::self()->dcopClient(), SIGNAL(applicationRegistered( const QCString& )),
+ this, SLOT(slotPreviewAppRegistered( const QCString& )));
+
+ delete m_process;
+ m_process = 0;
+ if (m_data->preview.hasOption("restart"))
+ KApplication::kdeinitExec(m_data->preview.exec);
+}
+
+void ComponentPage::slotShowAction(QListViewItem *item)
+{
+ ComponentActionItem *actionItem = dynamic_cast<ComponentActionItem*>(item);
+ QString description;
+ if (actionItem)
+ {
+ description = "<h2>"+QStyleSheet::escape(actionItem->action()->caption)+"</h2>\n";
+ description += actionItem->action()->description;
+ }
+ componentDescription->setText(description);
+}
+
+#include "componentPage.moc"
diff --git a/kiosktool/componentPage.h b/kiosktool/componentPage.h
new file mode 100644
index 0000000..d5d392c
--- /dev/null
+++ b/kiosktool/componentPage.h
@@ -0,0 +1,65 @@
+/*
+ * componentPage.h
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _COMPONENTPAGE_H_
+#define _COMPONENTPAGE_H_
+
+#include "componentPage_ui.h"
+#include "pageWidget.h"
+
+class KProcess;
+class Component;
+class ComponentData;
+
+class ComponentPage : public ComponentPageUI, public PageWidget
+{
+ Q_OBJECT
+public:
+ ComponentPage( ComponentData *data, Component *component, QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~ComponentPage();
+
+ virtual void load();
+ virtual bool save();
+
+ virtual void setFocus();
+
+ virtual QString subCaption();
+
+public slots:
+ void slotSetup();
+ void slotPreview();
+
+protected slots:
+ void slotShowNotice();
+ void slotSetupDone();
+ void slotPreviewDone();
+ void slotShowAction(QListViewItem *item);
+ void slotSetupAppRegistered( const QCString &appid);
+ void slotPreviewAppRegistered( const QCString &appid);
+
+protected:
+ void prepareMutableFiles();
+
+private:
+ KProcess *m_process;
+ ComponentData *m_data;
+ Component *m_component;
+ bool m_saveSettings;
+};
+
+#endif
diff --git a/kiosktool/componentPage_ui.ui b/kiosktool/componentPage_ui.ui
new file mode 100644
index 0000000..73f88cf
--- /dev/null
+++ b/kiosktool/componentPage_ui.ui
@@ -0,0 +1,195 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>ComponentPageUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>ComponentPageUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>559</width>
+ <height>372</height>
+ </rect>
+ </property>
+ <property name="backgroundOrigin">
+ <enum>WindowOrigin</enum>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="3" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>componentDescription</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>140</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32767</width>
+ <height>140</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignTop</set>
+ </property>
+ </widget>
+ <spacer row="2" column="1">
+ <property name="name">
+ <cstring>spacer8</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLayoutWidget" row="1" column="3">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>pbSetup</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Setup XXX</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer8_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>pbPreview</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Preview XXX</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer8_3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>21</width>
+ <height>171</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <spacer row="1" column="2">
+ <property name="name">
+ <cstring>spacer7</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KListView" row="1" column="0" rowspan="1" colspan="2">
+ <column>
+ <property name="text">
+ <string>Restriction</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>listComponentConfig</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>1</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>300</width>
+ <height>150</height>
+ </size>
+ </property>
+ <property name="backgroundOrigin">
+ <enum>WindowOrigin</enum>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="fullWidth">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Enable &amp;restrictions:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>listComponentConfig</cstring>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kiosktool/componentSelectionPage.cpp b/kiosktool/componentSelectionPage.cpp
new file mode 100644
index 0000000..f02ef33
--- /dev/null
+++ b/kiosktool/componentSelectionPage.cpp
@@ -0,0 +1,143 @@
+/*
+ * componentSelectionPage.cpp
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 "componentSelectionPage.h"
+
+#include <qpushbutton.h>
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kiconloader.h>
+#include <kiconview.h>
+#include <klocale.h>
+
+#include "kioskdata.h"
+
+class ComponentViewItem : public QIconViewItem
+{
+public:
+ ComponentViewItem( QIconView * parent, const QString & text, const QPixmap & icon, const QString & _id )
+ : QIconViewItem( parent, text, icon), id(_id)
+ {
+ }
+
+ QString id;
+};
+
+ComponentSelectionPage::ComponentSelectionPage( KioskData *data, QWidget* parent, const char* name, WFlags fl )
+ : ComponentSelectionPageUI(parent, name, fl), PageWidget(this), m_data(data)
+{
+ listComponent->setSelectionMode(QIconView::Single);
+ listComponent->setItemsMovable(false);
+ listComponent->setSpacing(20);
+ listComponent->setGridX(110);
+ listComponent->setGridY(75);
+ loadComponentList();
+ connect(listComponent, SIGNAL(clicked(QIconViewItem *)), this, SLOT(slotComponentActivated(QIconViewItem *)));
+ connect(listComponent, SIGNAL(returnPressed (QIconViewItem *)), this, SLOT(slotComponentActivated(QIconViewItem *)));
+ connect(pbSetup, SIGNAL(clicked()), this, SLOT(slotComponentActivated()));
+}
+
+ComponentSelectionPage::~ComponentSelectionPage()
+{
+}
+
+void ComponentSelectionPage::load()
+{
+}
+
+bool ComponentSelectionPage::save()
+{
+ KConfig *config = kapp->config();
+ config->setGroup("General");
+ config->writeEntry("CurrentComponent", currentComponent());
+ config->sync();
+ return true;
+}
+
+void ComponentSelectionPage::setFocus()
+{
+}
+
+QString ComponentSelectionPage::subCaption()
+{
+ return QString::null;
+}
+
+void ComponentSelectionPage::loadComponentList()
+{
+ listComponent->clear();
+ for(QStringList::ConstIterator it = m_data->m_componentList.begin();
+ it != m_data->m_componentList.end(); ++it)
+ {
+ ComponentData *data = m_data->m_componentData.find(*it);
+ Q_ASSERT(data);
+ if (!data) continue;
+ QPixmap icon = DesktopIcon( data->icon, KIcon::SizeMedium );
+ new ComponentViewItem(listComponent, data->caption, icon, data->id);
+ }
+}
+
+bool ComponentSelectionPage::hasSelection()
+{
+ return !currentComponent().isEmpty();
+}
+
+QString ComponentSelectionPage::currentComponent()
+{
+ ComponentViewItem *item = static_cast<ComponentViewItem *>(listComponent->firstItem());
+ while(item)
+ {
+ if (item->isSelected())
+ return item->id;
+
+ item = static_cast<ComponentViewItem *>(item->nextItem());
+ }
+ return QString::null;
+}
+
+void ComponentSelectionPage::setCurrentComponent(const QString &id)
+{
+ ComponentViewItem *item = static_cast<ComponentViewItem *>(listComponent->firstItem());
+ while(item)
+ {
+ if (item->id == id)
+ {
+ listComponent->setSelected(item, true);
+ return;
+ }
+ item = static_cast<ComponentViewItem *>(item->nextItem());
+ }
+ if (listComponent->firstItem())
+ listComponent->setSelected(listComponent->firstItem(), true);
+}
+
+void ComponentSelectionPage::slotComponentActivated(QIconViewItem *item)
+{
+ if (item)
+ emit componentActivated();
+}
+
+void ComponentSelectionPage::slotComponentActivated()
+{
+ if (!currentComponent().isEmpty())
+ emit componentActivated();
+}
+
+#include "componentSelectionPage.moc"
diff --git a/kiosktool/componentSelectionPage.h b/kiosktool/componentSelectionPage.h
new file mode 100644
index 0000000..7472d1e
--- /dev/null
+++ b/kiosktool/componentSelectionPage.h
@@ -0,0 +1,59 @@
+/*
+ * componentSelectionPage.h
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _COMPONENTSELECTIONPAGE_H_
+#define _COMPONENTSELECTIONPAGE_H_
+
+#include "componentSelectionPage_ui.h"
+#include "pageWidget.h"
+
+class KioskData;
+
+class ComponentSelectionPage : public ComponentSelectionPageUI, public PageWidget
+{
+ Q_OBJECT
+public:
+ ComponentSelectionPage( KioskData *data, QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~ComponentSelectionPage();
+
+ virtual void load();
+ virtual bool save();
+
+ virtual void setFocus();
+
+ virtual QString subCaption();
+
+ void setCurrentComponent(const QString &);
+ QString currentComponent();
+
+signals:
+ void componentActivated();
+
+protected:
+ void loadComponentList();
+ bool hasSelection();
+
+protected slots:
+ void slotComponentActivated(QIconViewItem *item);
+ void slotComponentActivated();
+
+private:
+ KioskData *m_data;
+};
+
+#endif
diff --git a/kiosktool/componentSelectionPage_ui.ui b/kiosktool/componentSelectionPage_ui.ui
new file mode 100644
index 0000000..17b2ab5
--- /dev/null
+++ b/kiosktool/componentSelectionPage_ui.ui
@@ -0,0 +1,124 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>ComponentSelectionPageUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>ComponentSelectionPageUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>682</width>
+ <height>373</height>
+ </rect>
+ </property>
+ <property name="backgroundOrigin">
+ <enum>WindowOrigin</enum>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer row="1" column="2">
+ <property name="name">
+ <cstring>spacer2_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="2" column="1">
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLayoutWidget" row="1" column="3">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>pbSetup</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Setup Component</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer5_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>211</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget class="QIconView" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>listComponent</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>400</width>
+ <height>200</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Select &amp;component:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>listComponent</cstring>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kiosktool/configure.in.in b/kiosktool/configure.in.in
new file mode 100644
index 0000000..84cf170
--- /dev/null
+++ b/kiosktool/configure.in.in
@@ -0,0 +1,2 @@
+AC_CHECK_SETENV
+AC_CHECK_UNSETENV
diff --git a/kiosktool/cr16-app-kiosktool.png b/kiosktool/cr16-app-kiosktool.png
new file mode 100644
index 0000000..ccd2b43
--- /dev/null
+++ b/kiosktool/cr16-app-kiosktool.png
Binary files differ
diff --git a/kiosktool/cr32-app-kiosktool.png b/kiosktool/cr32-app-kiosktool.png
new file mode 100644
index 0000000..a987516
--- /dev/null
+++ b/kiosktool/cr32-app-kiosktool.png
Binary files differ
diff --git a/kiosktool/cr48-app-kiosktool.png b/kiosktool/cr48-app-kiosktool.png
new file mode 100644
index 0000000..87e18dd
--- /dev/null
+++ b/kiosktool/cr48-app-kiosktool.png
Binary files differ
diff --git a/kiosktool/desktopComponent.cpp b/kiosktool/desktopComponent.cpp
new file mode 100644
index 0000000..b8aa060
--- /dev/null
+++ b/kiosktool/desktopComponent.cpp
@@ -0,0 +1,239 @@
+/*
+ * desktopComponent.cpp
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 "desktopComponent.h"
+
+#include <qdir.h>
+#include <qfileinfo.h>
+
+#include <kdebug.h>
+#include <kmimetype.h>
+#include <kprocess.h>
+#include <ksimpleconfig.h>
+#include <kstandarddirs.h>
+#include <ktempfile.h>
+#include <kurl.h>
+
+#include "kioskrun.h"
+
+DesktopComponent::DesktopComponent( QObject *parent)
+ : Component(parent)
+{
+}
+
+DesktopComponent::~DesktopComponent()
+{
+}
+
+void
+DesktopComponent::slotSetupPrepare()
+{
+ m_iconPositionsFile = KioskRun::self()->locateLocal("data", "kdesktop/IconPositions");
+ ::unlink(QFile::encodeName(m_iconPositionsFile));
+ connect(&m_timer, SIGNAL(timeout()), this, SLOT(slotSetupStarted()));
+}
+
+void
+DesktopComponent::slotSetupStarted()
+{
+ QString desktop = KioskRun::self()->desktopPath();
+ QFileInfo info(desktop);
+ if (info.exists())
+ {
+ disconnect(&m_timer, SIGNAL(timeout()), this, SLOT(slotSetupStarted()));
+ connect(&m_timer, SIGNAL(timeout()), this, SLOT(slotSetupReady()));
+ m_timer.start(1000, true);
+ }
+ else
+ {
+ m_timer.start(500, true);
+ }
+}
+
+void filterFileList(const QString &path, QStringList *files, QStringList *oldFiles)
+{
+ files->remove(".");
+ files->remove("..");
+
+ QStringList::Iterator next;
+ for(QStringList::Iterator it = files->begin();
+ it != files->end(); it = next)
+ {
+ next = it;
+ next++;
+
+ KURL u;
+ u.setPath(path+*it);
+
+ KMimeType::Ptr mime = KMimeType::findByURL(u, 0, true);
+ if (mime->name() == "application/x-desktop")
+ {
+ KSimpleConfig cfg(path+*it);
+ cfg.setDesktopGroup();
+ if (cfg.readBoolEntry("Hidden", false))
+ {
+ if (oldFiles)
+ oldFiles->append(*it);
+ files->remove(it);
+ continue;
+ }
+ }
+ }
+}
+
+void
+DesktopComponent::slotSetupReady()
+{
+ QString desktop = KioskRun::self()->desktopPath();
+
+ QDir dir(desktop);
+ m_origDesktopFiles = dir.entryList(QDir::All, QDir::Unsorted);
+
+ filterFileList(desktop, &m_origDesktopFiles, 0);
+}
+
+bool
+DesktopComponent::setupFinished()
+{
+ bool result = true;
+
+ disconnect(&m_timer, SIGNAL(timeout()), this, SLOT(slotSetupStarted()));
+ disconnect(&m_timer, SIGNAL(timeout()), this, SLOT(slotSetupReady()));
+ m_timer.stop();
+
+ KSimpleConfig newCfg(m_iconPositionsFile, true);
+
+ QString desktop = KioskRun::self()->desktopPath();
+
+ QDir dir(desktop);
+ QStringList newDesktopFiles = dir.entryList(QDir::All, QDir::Unsorted);
+ filterFileList(desktop, &newDesktopFiles, &m_origDesktopFiles);
+
+ KTempFile positionsFile;
+ positionsFile.close();
+
+ KSimpleConfig positions(positionsFile.name());
+
+ QStringList newGroups = newCfg.groupList();
+
+ QString prefix = "IconPosition::";
+
+ // Save icon positions
+ for(QStringList::Iterator it = newGroups.begin();
+ it != newGroups.end(); ++it)
+ {
+ if (!(*it).startsWith(prefix))
+ continue;
+
+ newCfg.setGroup(*it);
+ positions.setGroup(*it);
+ if (newCfg.hasKey("X"))
+ {
+ positions.writeEntry("X", newCfg.readEntry("X"));
+ positions.writeEntry("Y", newCfg.readEntry("Y"));
+ }
+ }
+
+ // Remove old icons from new list
+ QStringList::Iterator next;
+ for(QStringList::Iterator it = m_origDesktopFiles.begin();
+ it != m_origDesktopFiles.end(); it = next)
+ {
+ next = it;
+ next++;
+
+ if (newDesktopFiles.remove(*it))
+ {
+ m_origDesktopFiles.remove(it);
+ continue;
+ }
+
+ }
+
+ QString installPath = KioskRun::self()->locateSave("data", "kdesktop/Desktop/");
+ QString installPath2 = KioskRun::self()->locateSave("data", "kdesktop/DesktopLinks/");
+
+ // Remove all icons that are no longer
+ for(QStringList::Iterator it = m_origDesktopFiles.begin();
+ it != m_origDesktopFiles.end(); ++it)
+ {
+ QString file;
+ if (QFile::exists(installPath + *it))
+ file = installPath + *it;
+ else if (QFile::exists(installPath2 + *it))
+ file = installPath2 + *it;
+
+ if (!file.isEmpty())
+ {
+ result = KioskRun::self()->remove(file);
+ if (!result) return false;
+ positions.deleteGroup(prefix+*it);
+ }
+ else
+ {
+ QString installFile = installPath + *it;
+ file = KioskRun::self()->locate("data", "kdesktop/Desktop/" + *it);
+ if (file.isEmpty())
+ {
+ installFile = installPath2 + *it;
+ file = KioskRun::self()->locate("data", "kdesktop/DesktopLinks/" + *it);
+ }
+
+ if (!file.isEmpty())
+ {
+ // Hide via "Hidden=True", not sure if this works
+ KTempFile tmp;
+ tmp.close();
+ KSimpleConfig cfg(tmp.name());
+ cfg.setDesktopGroup();
+ cfg.writeEntry("Hidden", true);
+ cfg.sync();
+ result = KioskRun::self()->install(tmp.name(), installFile);
+ if (!result) return false;
+ positions.deleteGroup(prefix+*it);
+ }
+ else
+ {
+ kdWarning() << "DesktopComponent: Can't remove " << (*it) << endl;
+ }
+ }
+ }
+ positions.sync();
+ result = KioskRun::self()->install(positionsFile.name(), KioskRun::self()->locateSave("data", "kdesktop/Desktop/.directory"));
+ if (!result) return false;
+
+ // Add all icons that have been added
+ for(QStringList::Iterator it = newDesktopFiles.begin();
+ it != newDesktopFiles.end(); ++it)
+ {
+ QString file = KioskRun::self()->desktopPath() + *it;
+ if (QFile::exists(file))
+ {
+ result = KioskRun::self()->install(file, installPath + *it);
+ if (!result) return false;
+ }
+ else
+ {
+ kdWarning() << "DesktopComponent: Can't find new file " << file << endl;
+ }
+ }
+ return true;
+}
+
+#include "desktopComponent.moc"
diff --git a/kiosktool/desktopComponent.h b/kiosktool/desktopComponent.h
new file mode 100644
index 0000000..189f4f2
--- /dev/null
+++ b/kiosktool/desktopComponent.h
@@ -0,0 +1,50 @@
+/*
+ * desktopComponent.h
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _DESKTOPCOMPONENT_H_
+#define _DESKTOPCOMPONENT_H_
+
+#include "component.h"
+
+#include <qstringlist.h>
+#include <qtimer.h>
+
+class DesktopComponent: public Component
+{
+ Q_OBJECT
+public:
+ DesktopComponent( QObject *parent = 0);
+ virtual ~DesktopComponent();
+
+ virtual bool setupFinished();
+
+public slots:
+
+ virtual void slotSetupPrepare();
+ virtual void slotSetupStarted();
+
+protected slots:
+ void slotSetupReady();
+
+private:
+ QTimer m_timer;
+ QString m_iconPositionsFile;
+ QStringList m_origDesktopFiles;
+};
+
+#endif
diff --git a/kiosktool/extractxml b/kiosktool/extractxml
new file mode 100755
index 0000000..629ab1d
--- /dev/null
+++ b/kiosktool/extractxml
@@ -0,0 +1,120 @@
+#! /usr/bin/perl
+#
+# This script extracts messages from kiosk_data.xml
+# and writes on standard output (usually redirected to rc.cpp)
+# the equivalent i18n() calls so that xgettext can parse them.
+#
+# It is based on extractrc but differs in the following ways:
+# *) Extracts <caption> and <description> tags
+# *) Performs equivalent of QString::simplifyWhiteSpace on all strings
+#
+# known flags:
+# --tag=name : extract also the tag name
+# --context=name : give all i18n calls a context name: i18n( "name",...)
+
+$filename = "";
+@filenames = ();
+
+sub writeoutstring
+{
+ print STDOUT "i18n(\"";
+ if (@_[0])
+ {
+ # We have a I18N context
+ print STDOUT @_[0];
+ print STDOUT "\",\"";
+ }
+ print STDOUT @_[1];
+ print STDOUT "\"); // $filename \n";
+}
+
+$extratags = "";
+$context = ""; # I18N context
+
+ARGUMENTS: while (defined ($ARGV[0]))
+{
+ $_ = shift;
+
+ if (/^--tag=(\w+)/) # --tag=name
+ {
+ $extratags .= "|" . $1;
+ next ARGUMENTS;
+ }
+ elsif (/^--context=(\w+)/) # --context=name
+ {
+ $context = $1;
+ next ARGUMENTS;
+ }
+
+ $filename = $_; # maybe check for more options
+
+if (! $filename) {
+ print STDERR "no file to open\n";
+ exit 1;
+}
+
+$string = "";
+$intext = 0;
+$linenr = 0;
+$inskippedprop = 0;
+
+open(FILE, $filename);
+
+READING: while ( <FILE> ) {
+ $linenr++;
+ if ($linenr == 1 && ($_ !~ /^<!DOCTYPE/) && ($_ !~ /^<\?xml/)) {
+ last READING;
+ }
+
+ $string .= "\\n" . $_;
+ chomp($string);
+
+ $textstring = '(caption|description' . $extratags .')>';
+
+ # The 'database' property contains strings that shouldn't be translated
+ if ($inskippedprop == 0 && ($string =~ /<property name=\"database\"/ || $string=~ /<property name=\"associations\"/)) {
+ $inskippedprop = 1;
+ } elsif ($inskippedprop == 1 && ($string =~ /<\/property/)) {
+ $inskippedprop = 0;
+ $string = "";
+ }
+
+ if ($inskippedprop == 0 && $intext == 0) {
+ if ($string =~ /<$textstring/) {
+ $string =~ s/^.*<$textstring//;
+ $intext = 1;
+ $starting_linenr = $linenr;
+ } else {
+ $string = "";
+ }
+ }
+
+ if (($intext == 1) && ($string =~ /<\/$textstring/)) {
+ my $text = $string;
+ $text =~ s/<\/$textstring.*$//;
+ $text =~ s/&lt;/</g;
+ $text =~ s/&gt;/>/g;
+ $text =~ s/&amp;/&/g;
+ $text =~ s/\\n/ /g;
+ $text =~ s/\\([^n])/\\\\$1/g;
+ $text =~ s/\"/\\\"/g;
+ $text =~ s/ +/ /g;
+ $text =~ s/^ //g;
+ $text =~ s/ $//g;
+ writeoutstring($context, $text);
+ $string =~ s/^.*<\/$textstring//;
+ $intext = 0;
+ # Text can be multiline in .ui files (possibly), but we warn about it in XMLGUI .rc files.
+ if ($linenr != $starting_linenr && $filename =~ m/\.rc$/) {
+ print STDERR "there is <text> floating $filename\n";
+ }
+ }
+
+}
+
+if ($intext == 1) {
+ print STDERR "parsing error in $filename $linenr\n";
+ exit 1;
+}
+
+}
diff --git a/kiosktool/filetypeeditComponent.cpp b/kiosktool/filetypeeditComponent.cpp
new file mode 100644
index 0000000..4e3fbaa
--- /dev/null
+++ b/kiosktool/filetypeeditComponent.cpp
@@ -0,0 +1,133 @@
+/*
+ * filetypeeditComponent.cpp
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 "filetypeeditComponent.h"
+
+#include <qdir.h>
+#include <qdom.h>
+#include <qfileinfo.h>
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kmimetype.h>
+#include <kprocess.h>
+#include <ksavefile.h>
+#include <ksimpleconfig.h>
+#include <kstandarddirs.h>
+#include <kurl.h>
+
+#include "kioskrun.h"
+#include "kiosksync.h"
+
+FileTypeEditComponent::FileTypeEditComponent( QObject *parent)
+ : Component(parent)
+{
+}
+
+FileTypeEditComponent::~FileTypeEditComponent()
+{
+}
+
+void
+FileTypeEditComponent::slotSetupPrepare()
+{
+}
+
+void
+FileTypeEditComponent::slotSetupStarted()
+{
+}
+
+bool
+FileTypeEditComponent::setupFinished()
+{
+ bool result;
+
+ // Install mimetype files
+ {
+ QString mimetypeFiles = KioskRun::self()->locateLocal("mime", QString::null);
+ QString mimetypeSaveFiles = KioskRun::self()->locateSave("mime", QString::null);
+
+ KioskSync mimeDir(kapp->mainWidget());
+ mimeDir.addDir(mimetypeFiles, KURL());
+
+ QStringList newMimetypeFiles = mimeDir.listFiles();
+
+ for(QStringList::ConstIterator it = newMimetypeFiles.begin();
+ it != newMimetypeFiles.end(); ++it)
+ {
+ if ((*it).endsWith(".desktop"))
+ {
+ kdDebug() << "FileTypeEditComponent: New mimetype file %s" << (mimetypeFiles+(*it)) << endl;
+ result = KioskRun::self()->install(mimetypeFiles+(*it), mimetypeSaveFiles+(*it));
+ if (!result) return false;
+ }
+ }
+ }
+
+ // Install legacy .desktop files
+ {
+ QString legacyApplications = KioskRun::self()->locateLocal("apps", QString::null);
+ QString legacySaveApplications = KioskRun::self()->locateSave("apps", QString::null);
+
+ KioskSync legacyDir(kapp->mainWidget());
+ legacyDir.addDir(legacyApplications, KURL());
+
+ QStringList newLegacyApplications = legacyDir.listFiles();
+
+ for(QStringList::ConstIterator it = newLegacyApplications.begin();
+ it != newLegacyApplications.end(); ++it)
+ {
+ if ((*it).endsWith(".desktop") || (*it).endsWith(".kdelnk") || (*it).endsWith(".directory"))
+ {
+ kdDebug() << "MenueditComponent: New legacy file %s" << (legacyApplications+(*it)) << endl;
+ result = KioskRun::self()->install(legacyApplications+(*it), legacySaveApplications+(*it));
+ if (!result) return false;
+ }
+ }
+ }
+
+ // Install .desktop files
+ {
+ QString xdgApplications = KioskRun::self()->locateLocal("xdgdata-apps", QString::null);
+ QString xdgSaveApplications = KioskRun::self()->locateSave("xdgdata-apps", QString::null);
+
+ QDir dir(xdgApplications);
+ QStringList newXdgApplications = dir.entryList(QDir::All, QDir::Unsorted);
+ newXdgApplications.remove(".");
+ newXdgApplications.remove("..");
+
+ for(QStringList::ConstIterator it = newXdgApplications.begin();
+ it != newXdgApplications.end(); ++it)
+ {
+ if ((*it).endsWith(".desktop") || (*it).endsWith(".kdelnk"))
+ {
+ kdDebug() << "MenueditComponent: New .desktop file %s" << (xdgApplications+(*it)) << endl;
+ result = KioskRun::self()->install(xdgApplications+(*it), xdgSaveApplications+(*it));
+ if (!result) return false;
+ }
+ }
+ }
+
+ KioskRun::self()->forceSycocaUpdate();
+
+ return true;
+}
+
+#include "filetypeeditComponent.moc"
diff --git a/kiosktool/filetypeeditComponent.h b/kiosktool/filetypeeditComponent.h
new file mode 100644
index 0000000..1410dc5
--- /dev/null
+++ b/kiosktool/filetypeeditComponent.h
@@ -0,0 +1,42 @@
+/*
+ * filetypeeditComponent.h
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _FILETYPEEDITCOMPONENT_H_
+#define _FILETYPEEDITCOMPONENT_H_
+
+#include "component.h"
+
+#include <qstringlist.h>
+#include <qtimer.h>
+
+class FileTypeEditComponent: public Component
+{
+ Q_OBJECT
+public:
+ FileTypeEditComponent( QObject *parent = 0);
+ virtual ~FileTypeEditComponent();
+
+ virtual bool setupFinished();
+
+public slots:
+
+ virtual void slotSetupPrepare();
+ virtual void slotSetupStarted();
+};
+
+#endif
diff --git a/kiosktool/kcms/Makefile.am b/kiosktool/kcms/Makefile.am
new file mode 100644
index 0000000..335ab60
--- /dev/null
+++ b/kiosktool/kcms/Makefile.am
@@ -0,0 +1,6 @@
+## Makefile.am for kiosktool's additional KCMs
+
+# this has all of the subdirectories that make will recurse into. if
+# there are none, comment this out
+#SUBDIRS = autostart
+
diff --git a/kiosktool/kcms/autostart/Makefile.am b/kiosktool/kcms/autostart/Makefile.am
new file mode 100644
index 0000000..993941a
--- /dev/null
+++ b/kiosktool/kcms/autostart/Makefile.am
@@ -0,0 +1,17 @@
+kde_module_LTLIBRARIES = kcm_autostart.la
+
+kcm_autostart_la_SOURCES = kcmautostart.cpp
+
+kcm_autostart_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined
+kcm_autostart_la_LIBADD = $(LIB_KIO)
+
+INCLUDES= $(all_includes)
+
+kcm_autostart_la_METASOURCES = AUTO
+
+KDE_ICON = autostart
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/kcmautostart.pot
+
+xdg_apps_DATA = kcmautostart.desktop
diff --git a/kiosktool/kcms/autostart/kcmautostart.cpp b/kiosktool/kcms/autostart/kcmautostart.cpp
new file mode 100644
index 0000000..7a553bb
--- /dev/null
+++ b/kiosktool/kcms/autostart/kcmautostart.cpp
@@ -0,0 +1,202 @@
+/*
+This file is part of the KDE project
+Copyright (C) 2004 Martijn Klingens <klingens@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., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+#include <qlayout.h>
+#include <qwhatsthis.h>
+#include <qvgroupbox.h>
+#include <qpushbutton.h>
+#include <qheader.h>
+#include <qtimer.h>
+#include <qfileinfo.h>
+
+#include <kaboutdata.h>
+#include <kapplication.h>
+#include <kdesktopfile.h>
+#include <kdialog.h>
+#include <kgenericfactory.h>
+#include <klistview.h>
+#include <kmessagebox.h>
+#include <kservice.h>
+#include <kstandarddirs.h>
+
+#include <dcopclient.h>
+#include <dcopref.h>
+
+#include <kdebug.h>
+
+#include "kcmautostart.h"
+#include "kcmautostart.moc"
+
+typedef KGenericFactory<AutoStartConfig, QWidget> AutoStartFactory;
+K_EXPORT_COMPONENT_FACTORY( kcm_autostart, AutoStartFactory( "kcmautostart" ) )
+
+AutoStartConfig::AutoStartConfig(QWidget* parent, const char* name, const QStringList &) :
+ KCModule( AutoStartFactory::instance(), parent, name )
+{
+ KGlobal::dirs()->addResourceType("autostart", "share/autostart");
+ KAboutData *about =
+ new KAboutData( I18N_NOOP( "kcmautostart" ), I18N_NOOP( "KDE Service Manager" ),
+ 0, 0, KAboutData::License_GPL, I18N_NOOP( "(c) 2004 Martijn Klingens" ) );
+ about->addAuthor( "Martijn Klingens", 0, "klingens@kde.org" );
+
+#if KDE_IS_VERSION(3,2,91)
+ setAboutData( about );
+#endif
+
+ QVBoxLayout *lay = new QVBoxLayout( this, 0, KDialog::spacingHint() );
+
+ QGroupBox *gb = new QVGroupBox( i18n( "Startup Services" ), this );
+ QWhatsThis::add(gb, i18n("This shows all KDE services that can be loaded "
+ "on KDE startup. Checked services will be invoked on next startup. "
+ "Be careful with deactivation of unknown services."));
+ lay->addWidget( gb );
+
+ _lvStartup = new KListView( gb );
+ _lvStartup->addColumn(i18n("Use"));
+ _lvStartup->addColumn(i18n("Service"));
+ _lvStartup->addColumn(i18n("Description"));
+ _lvStartup->setAllColumnsShowFocus(true);
+ _lvStartup->header()->setStretchEnabled(true, 2);
+
+ load();
+}
+
+void setModuleGroup(KConfig *config, const QString &filename)
+{
+ QString module = filename;
+ int i = module.findRev('/');
+ if (i != -1)
+ module = module.mid(i+1);
+ i = module.findRev('.');
+ if (i != -1)
+ module = module.left(i);
+
+ config->setGroup(QString("Module-%1").arg(module));
+}
+
+bool AutoStartConfig::autoloadEnabled(KConfig *config, const QString &filename)
+{
+ setModuleGroup(config, filename);
+ return config->readBoolEntry("autoload", true);
+}
+
+void AutoStartConfig::setAutoloadEnabled(KConfig *config, const QString &filename, bool b)
+{
+ setModuleGroup(config, filename);
+ return config->writeEntry("autoload", b);
+}
+
+void AutoStartConfig::load() {
+ _lvStartup->clear();
+
+ QStringList files = KGlobal::dirs()->findAllResources( "autostart", QString::fromLatin1( "*.desktop" ), false, true );
+
+ for ( QStringList::ConstIterator it = files.begin(); it != files.end(); it++ )
+ {
+ if ( KDesktopFile::isDesktopFile( QFileInfo( *it ).fileName() ) )
+ {
+ KDesktopFile file( QFileInfo( *it ).fileName(), true, "autostart" );
+ QString name = file.readName();
+ if ( !name.isEmpty() )
+ {
+ CheckListItem *clitem = new CheckListItem( _lvStartup, QString::null );
+ connect( clitem, SIGNAL( changed( QCheckListItem * ) ), SLOT( slotItemChecked( QCheckListItem * ) ) );
+ clitem->setText( 1, name );
+ clitem->setText( 2, file.readComment() );
+ clitem->setText( 3, *it );
+ clitem->setOn( !file.readBoolEntry( "Hidden", false ) );
+ }
+ }
+ }
+}
+
+void AutoStartConfig::save()
+{
+ QListViewItemIterator it( _lvStartup );
+ while ( it.current() )
+ {
+ if ( KDesktopFile::isDesktopFile( it.current()->text( 3 ) ) )
+ {
+ // Determine whether we need to change the file on a readonly desktop file
+ // by giving a full path first
+ QString path = it.current()->text( 3 );
+ KDesktopFile file( path, true, "services" );
+ bool shouldBeHidden = !( static_cast<QCheckListItem *>( it.current() )->isOn() );
+ if ( file.readBoolEntry( "Hidden", false ) != shouldBeHidden )
+ {
+ KDesktopFile outFile( QFileInfo( path ).fileName(), false, "autostart" );
+ kdDebug() << "************** Writing out " << path << endl;
+ outFile.writeEntry( "Hidden", shouldBeHidden );
+ outFile.sync();
+ }
+ }
+ ++it;
+ }
+
+ //QTimer::singleShot(0, this, SLOT(slotServiceRunningToggled()));
+}
+
+void AutoStartConfig::defaults()
+{
+ QListViewItemIterator it( _lvStartup);
+ while ( it.current() != 0 ) {
+ if (it.current()->rtti()==1) {
+ QCheckListItem *item = static_cast<QCheckListItem *>(it.current());
+ item->setOn(false);
+ }
+ ++it;
+ }
+}
+
+void AutoStartConfig::slotReload()
+{
+ QString current = _lvStartup->currentItem()->text(4);
+ load();
+ QListViewItem *item = _lvStartup->findItem(current, 4);
+ if (item)
+ _lvStartup->setCurrentItem(item);
+}
+
+void AutoStartConfig::slotItemChecked(QCheckListItem*)
+{
+ emit changed(true);
+}
+
+QString AutoStartConfig::quickHelp() const
+{
+ return i18n("<h1>Service Manager</h1><p>This module allows you to have an overview of all plugins of the "
+ "KDE Daemon, also referred to as KDE Services. Generally, there are two types of service:</p>"
+ "<ul><li>Services invoked at startup</li><li>Services called on demand</li></ul>"
+ "<p>The latter are only listed for convenience. The startup services can be started and stopped. "
+ "In Administrator mode, you can also define whether services should be loaded at startup.</p>"
+ "<p><b> Use this with care: some services are vital for KDE; do not deactivate services if you"
+ " do not know what you are doing.</b></p>");
+}
+
+CheckListItem::CheckListItem(QListView *parent, const QString &text)
+ : QObject(parent),
+ QCheckListItem(parent, text, CheckBox)
+{ }
+
+void CheckListItem::stateChange(bool on)
+{
+ QCheckListItem::stateChange(on);
+ emit changed(this);
+}
diff --git a/kiosktool/kcms/autostart/kcmautostart.desktop b/kiosktool/kcms/autostart/kcmautostart.desktop
new file mode 100644
index 0000000..fa82104
--- /dev/null
+++ b/kiosktool/kcms/autostart/kcmautostart.desktop
@@ -0,0 +1,56 @@
+[Desktop Entry]
+Encoding=UTF-8
+Exec=kcmshell kcmautostart
+Icon=autostart
+Type=Application
+
+X-KDE-ModuleType=Library
+X-KDE-Library=autostart
+X-KDE-Factoryname=autostart
+X-KDE-ParentApp=kcontrol
+
+Name=AutoStart Manager
+Name[da]=Autostarthåndtering
+Name[es]=Gestor de arranque automático
+Name[et]=Autostardi haldur
+Name[fr]=Gestion du lancement automatique
+Name[it]=Gestore di avvio automatico
+Name[nl]=Autostartbeheer
+Name[pt]=Gestor de Arranque Automático
+Name[pt_BR]=Gestor de Arranque Automático
+Name[sr]=Менаџер аутоматског покретања
+Name[sr@Latn]=Menadžer automatskog pokretanja
+Name[ta]=தானாக துவங்கும் மேலாளர்
+Name[xx]=xxAutoStart Managerxx
+Comment=AutoStart Configuration
+Comment[da]=Indstilling for autostart
+Comment[es]=Configuración de arranque automático
+Comment[et]=Autostardi seadistamine
+Comment[fr]=Configuration du lancement automatique
+Comment[it]=Configurazione dell'avvio automatico
+Comment[nl]=Autostartconfiguratie
+Comment[pt]=Configuração de Arranque Automático
+Comment[pt_BR]=Configuração de Arranque Automático
+Comment[ru]=Настройка служб
+Comment[sr]=Подешавање аутоматског покретања
+Comment[sr@Latn]=Podešavanje automatskog pokretanja
+Comment[sv]=Inställning av automatisk start
+Comment[ta]=தானாகவே துவங்கும் வடிவமைப்பு
+Comment[xx]=xxAutoStart Configurationxx
+Keywords=AutoStart,Services
+Keywords[da]=AutoStart, Tjenester
+Keywords[es]=Arranque automático,Servicios
+Keywords[et]=AutoStart,Teenused
+Keywords[fr]=Lancement automatique, Services
+Keywords[it]=Avvio automatico,Servizi
+Keywords[nl]=autoStart,services,diensten
+Keywords[pt]=Arranque Automático,Serviços
+Keywords[pt_BR]=Arranque Automático,Serviços
+Keywords[ru]=AutoStart,Services,Службы,Автозапуск
+Keywords[sr]=AutoStart,Services,аутоматско,покретање,сервиси
+Keywords[sr@Latn]=AutoStart,Services,automatsko,pokretanje,servisi
+Keywords[sv]=automatisk start,tjänster
+Keywords[ta]=தானாக துவங்கும், சேவைகள்
+Keywords[xx]=xxAutoStart,Servicesxx
+
+Categories=Qt;KDE;X-KDE-settings-components;
diff --git a/kiosktool/kcms/autostart/kcmautostart.h b/kiosktool/kcms/autostart/kcmautostart.h
new file mode 100644
index 0000000..dfb5eba
--- /dev/null
+++ b/kiosktool/kcms/autostart/kcmautostart.h
@@ -0,0 +1,66 @@
+/*
+ This file is part of the KDE project
+ Copyright (C) 2004 Martijn Klingens <klingens@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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+#ifndef KCMAUTOSTART_H
+#define KCMAUTOSTART_H
+
+#include <qlistview.h>
+#include <kcmodule.h>
+
+class KListView;
+class QStringList;
+class QPushButton;
+
+class AutoStartConfig : public KCModule
+{
+Q_OBJECT
+public:
+ AutoStartConfig(QWidget* parent, const char* name= 0L, const QStringList& foo = QStringList());
+ ~AutoStartConfig() {};
+
+ void load();
+ void save();
+ void defaults();
+
+ QString quickHelp() const;
+
+protected slots:
+ void slotReload();
+ void slotItemChecked(QCheckListItem *item);
+
+ bool autoloadEnabled(KConfig *config, const QString &filename);
+ void setAutoloadEnabled(KConfig *config, const QString &filename, bool b);
+
+private:
+ KListView *_lvStartup;
+};
+
+class CheckListItem : public QObject, public QCheckListItem
+{
+ Q_OBJECT
+public:
+ CheckListItem(QListView* parent, const QString &text);
+ ~CheckListItem() { }
+signals:
+ void changed(QCheckListItem*);
+protected:
+ virtual void stateChange(bool);
+};
+
+#endif // KCMAUTOSTART_H
+
diff --git a/kiosktool/kioskConfigDialog.cpp b/kiosktool/kioskConfigDialog.cpp
new file mode 100644
index 0000000..8b523bb
--- /dev/null
+++ b/kiosktool/kioskConfigDialog.cpp
@@ -0,0 +1,149 @@
+/*
+ * kioskConfigDialog.cpp
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 "kioskConfigDialog.h"
+
+#include <qcheckbox.h>
+#include <qtextedit.h>
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kfiledialog.h>
+#include <knuminput.h>
+#include <klineedit.h>
+#include <klocale.h>
+#include <kurlrequester.h>
+
+#include "kioskrun.h"
+
+#include "kioskConfigDialog_ui.h"
+
+KioskConfigDialog::KioskConfigDialog(QWidget *parent)
+ : KDialogBase(parent, "KioskConfigDialog", true, i18n("Configure Kiosk Admin Tool"),
+ KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, true )
+{
+ w = new KioskConfigDialogUI(this);
+ w->lineProfilePrefix->setMode(KFile::Directory | KFile::LocalOnly);
+ w->lineUpload->setMode(KFile::Directory);
+
+ setMainWidget(w);
+
+ init();
+ connect(w->lineProfilePrefix, SIGNAL(textChanged( const QString& )), SLOT(updateExample()));
+ connect(w->lineUpload, SIGNAL(textChanged( const QString& )), SLOT(updateExample()));
+ connect(w->lineUploadPrefix, SIGNAL(textChanged( const QString& )), SLOT(updateExample()));
+}
+
+KioskConfigDialog::~KioskConfigDialog()
+{
+}
+
+void KioskConfigDialog::init()
+{
+ QString prefix = KioskRun::self()->getProfilePrefix();
+
+ if (prefix.isEmpty())
+ {
+ w->checkProfilePrefix->setChecked(false);
+ w->lineProfilePrefix->setURL("/etc/kde-profile/");
+ }
+ else
+ {
+ w->checkProfilePrefix->setChecked(true);
+ w->lineProfilePrefix->setURL(prefix);
+ }
+
+ KConfig *config = kapp->config();
+ config->setGroup("General");
+
+ QString uploadURL = config->readEntry("uploadURL");
+ if (uploadURL.isEmpty())
+ {
+ w->checkUpload->setChecked(false);
+ w->lineUpload->setURL("fish://root@host/");
+ }
+ else
+ {
+ w->checkUpload->setChecked(true);
+ w->lineUpload->setURL(uploadURL);
+ }
+ w->lineUploadPrefix->setText(config->readEntry("uploadPrefix"));
+
+ int minUID = config->readNumEntry("FirstUIDShown", 500);
+ if (!minUID)
+ {
+ w->checkUID->setChecked(false);
+ w->numUID->setValue(500);
+ }
+ else
+ {
+ w->checkUID->setChecked(true);
+ w->numUID->setValue(minUID);
+ }
+
+ updateExample();
+}
+
+void KioskConfigDialog::updateExample()
+{
+ QString uploadPrefix = w->lineUploadPrefix->text();
+ QString file1 = w->lineProfilePrefix->url()+"default";
+ QString file2 = file1;
+ if (file2.startsWith(uploadPrefix))
+ file2 = file2.mid(uploadPrefix.length());
+ if (file2.startsWith("/"))
+ file2 = file2.mid(1);
+ QString url = w->lineUpload->url();
+ if (!url.endsWith("/"))
+ url += "/";
+ url += file2;
+ QString example = QString("<qt><center><b>%1</b><br>--><br><b>%2</b></center>").arg(file1, url);
+ w->lblUploadExample->setText(example);
+ w->lblUploadExample->setFixedSize(QSize(500,fontMetrics().lineSpacing()*3 + 6));
+}
+
+bool KioskConfigDialog::save()
+{
+ QString uploadURL;
+ QString uploadPrefix;
+ QString prefix;
+ int minUID = 0;
+
+ uploadPrefix = w->lineUploadPrefix->text();
+
+ if (w->checkUpload->isChecked())
+ uploadURL = w->lineUpload->url();
+
+ if (w->checkProfilePrefix->isChecked())
+ prefix = w->lineProfilePrefix->url();
+
+ if (w->checkUID->isChecked())
+ minUID = w->numUID->value();
+
+ KConfig *config = kapp->config();
+ config->setGroup("General");
+ config->writeEntry("uploadURL", uploadURL);
+ config->writeEntry("uploadPrefix", uploadPrefix);
+ config->writeEntry("FirstUIDShown", minUID);
+ config->sync();
+
+ return KioskRun::self()->setProfilePrefix(prefix);
+}
+
+#include "kioskConfigDialog.moc"
diff --git a/kiosktool/kioskConfigDialog.h b/kiosktool/kioskConfigDialog.h
new file mode 100644
index 0000000..56c969c
--- /dev/null
+++ b/kiosktool/kioskConfigDialog.h
@@ -0,0 +1,46 @@
+/*
+ * kioskConfigDialog.h
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _KIOSKCONFIGDIALOG_H_
+#define _KIOSKCONFIGDIALOG_H_
+
+#include <kdialogbase.h>
+
+class KioskConfigDialogUI;
+
+class KioskConfigDialog : public KDialogBase
+{
+ Q_OBJECT
+public:
+ KioskConfigDialog(QWidget *parent);
+ ~KioskConfigDialog();
+
+ bool save();
+
+
+protected slots:
+ void updateExample();
+
+protected:
+ void init();
+
+private:
+ KioskConfigDialogUI *w;
+};
+
+#endif
diff --git a/kiosktool/kioskConfigDialog_ui.ui b/kiosktool/kioskConfigDialog_ui.ui
new file mode 100644
index 0000000..136ce9d
--- /dev/null
+++ b/kiosktool/kioskConfigDialog_ui.ui
@@ -0,0 +1,329 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>KioskConfigDialogUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>KioskConfigDialogUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>551</width>
+ <height>501</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>checkProfilePrefix</cstring>
+ </property>
+ <property name="text">
+ <string>Store all &amp;profiles under the same base directory</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout3</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Base directory:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>lineProfilePrefix</cstring>
+ </property>
+ </widget>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>lineProfilePrefix</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>checkUpload</cstring>
+ </property>
+ <property name="text">
+ <string>On exit, &amp;upload profiles to remote server</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout8</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout7</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Server URL:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>lineUpload</cstring>
+ </property>
+ </widget>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>lineUpload</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3</cstring>
+ </property>
+ <property name="text">
+ <string>Strip off the following directory prefix when uploading:</string>
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>lineUploadPrefix</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Example:</string>
+ </property>
+ </widget>
+ <widget class="QTextEdit">
+ <property name="name">
+ <cstring>lblUploadExample</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>500</width>
+ <height>10</height>
+ </size>
+ </property>
+ <property name="vScrollBarMode">
+ <enum>AlwaysOff</enum>
+ </property>
+ <property name="hScrollBarMode">
+ <enum>AlwaysOff</enum>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>checkUID</cstring>
+ </property>
+ <property name="text">
+ <string>Do not show users with a UID lower than</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout6</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1_2_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KIntNumInput">
+ <property name="name">
+ <cstring>numUID</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>60</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2</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>
+ </vbox>
+</widget>
+<customwidgets>
+</customwidgets>
+<connections>
+ <connection>
+ <sender>checkProfilePrefix</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>lineProfilePrefix</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>checkUpload</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>lineUpload</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>checkUID</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>numUID</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>checkUpload</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>lineUploadPrefix</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>checkUpload</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>lblUploadExample</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+</includehints>
+</UI>
diff --git a/kiosktool/kiosk_data.xml b/kiosktool/kiosk_data.xml
new file mode 100644
index 0000000..0f25d4e
--- /dev/null
+++ b/kiosktool/kiosk_data.xml
@@ -0,0 +1,778 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE kiosk SYSTEM "kiosk.dtd">
+<kiosk>
+ <group name="general" icon="package_settings">
+ <caption>General</caption>
+ <description>
+ Generic restrictions
+ </description>
+ <actions>
+ <action type="action restriction" key="action/kwin_rmb">
+ <caption>Disable Window Manager context menu (Alt-F3)</caption>
+ <description>
+ The Window Manager context menu is normally shown when Alt-F3 is pressed
+ or when the menu button on the window frame is pressed.
+ </description>
+ </action>
+ <action type="action restriction" key="action/bookmarks">
+ <caption>Disable Bookmarks</caption>
+ <description>Disable Bookmarks in all applications.</description>
+ </action>
+ <action type="action restriction" key="user/root">
+ <caption>Disable all tasks and applications that require root access</caption>
+ <description>
+ In multi-user
+ environments the users normally do not know the root password; in such a case, it
+ may be desirable to use this option to remove the tasks and applications
+ from the menus that the users cannot use.
+ </description>
+ </action>
+ <action type="action restriction" key="shell_access">
+ <caption>Disable access to a command shell</caption>
+ <description>
+ In an environment where the desktop is dedicated
+ to a defined set of tasks it may be desirable to disable access to a command shell to
+ prevent users from engaging in tasks that were not intended or authorized; hence, it is
+ strongly recommended to disable access to a command shell if the desktop is to act
+ as a public terminal.
+ </description>
+ </action>
+ <action type="action restriction" key="logout">
+ <caption>Disable Logout option</caption>
+ <description>
+ This prevents the user from logging out. To make this option
+ effective it is important to ensure that key-combinations to terminate the X-server,
+ such as Alt-Ctrl-Backspace, are disabled in the configuration of the X-server.
+ </description>
+ </action>
+ <action type="action restriction" key="lock_screen">
+ <caption>Disable Lock Screen option</caption>
+ <description>
+ When the desktop is to act as a public terminal or is to be
+ shared by different users it may be desirable to prevent locking of the screen to ensure that
+ the system remains accessible if a user leaves the terminal.
+ </description>
+ </action>
+ <action type="action restriction" key="run_command">
+ <caption>Disable "Run Command" option (Alt-F2)</caption>
+ <description>
+ The "Run Command" option can normally be used to execute arbitrary commands; however, when
+ access to a command shell is restricted only applications and services defined by a .desktop file
+ can be started this way. Disabling "Run Command" here hides the option completely.
+ </description>
+ </action>
+ <action type="action restriction" key="movable_toolbars">
+ <caption>Disable toolbar moving</caption>
+ <description>
+ Normally toolbars in applications can be moved around; when this option is chosen
+ all toolbars are fixed in their original positions.
+ </description>
+ </action>
+ <action type="action restriction" key="run_desktop_files">
+ <caption>Disable execution of arbitrary .desktop files.</caption>
+ <description>
+ This option defines whether users may execute .desktop files that are not
+ part of the system-wide desktop icons, KDE menu, registered services or
+ autostart services. When access to a command shell is restricted it is recommended to
+ to disable the execution of arbitrary .desktop files as well since such .desktop files
+ can be used to circumvent the command shell restriction.
+ </description>
+ </action>
+ <action type="action restriction" key="start_new_session">
+ <caption>Disable starting of a second X session.</caption>
+ <description>
+ KDM has the possibility to login a second user in parallel to the current session.
+ Note that this can also be configured as part of the KDM settings in which case
+ the setting here should be left enabled.
+ </description>
+ </action>
+ <action type="action restriction" key="lineedit_text_completion">
+ <caption>Disable input line history</caption>
+ <description>
+ If a single account is used by multiple people it may be desirable to disable
+ the input line history out of privacy considerations.
+ </description>
+ </action>
+ </actions>
+ </group>
+ <group name="kdesktop" icon="desktop">
+ <caption>Desktop Icons</caption>
+ <description>
+ Desktop Icons are provided by "kdesktop".
+ </description>
+ <preview binary="kdesktop" dcop="kdesktop" options="restart">
+ </preview>
+ <setup binary="kdesktop" dcop="kdesktop" options="restart">
+ <mutable file="kdesktoprc" />
+ <mutable file="kdeglobals" />
+ </setup>
+ <actions>
+ <action type="immutable" file="kdesktoprc">
+ <caption>Lock down Desktop Settings</caption>
+ <description>
+ When the desktop settings are locked down the user can no longer change how the desktop
+ behaves or look like. This does not affect the ability to add new files or shortcuts to the
+ desktop.
+ </description>
+ </action>
+ <action type="action restriction" key="action/kdesktop_rmb">
+ <caption>Disable context menus</caption>
+ <description>
+ When checked the user will no longer get any context menu. Normally the user
+ can get a context menu by clicking with the right mouse button.
+ </description>
+ </action>
+ <action type="action restriction" key="editable_desktop_icons">
+ <caption>Lock down all Desktop icons</caption>
+ <description>
+ When checked the user will not be able to remove or edit any existing
+ icon or file on the Desktop or add any new icon or file.
+ </description>
+ </action>
+<!-- Not implemented yet
+ <action type="action restriction" key="editable_system_desktop_icons">
+ <caption>Lock down system wide Desktop icons</caption>
+ <description>
+ When checked the user will not be able to remove or edit any of
+ the system wide icons but will still be able to add, remove or edit
+ personal icons or files on the desktop.
+ </description>
+ </action>
+-->
+ <action type="config" file="kdesktoprc" group="General" key="CopyDesktopLinks" default="true">
+ <caption>Add additional vendor specific icons</caption>
+ <description>
+ When this option is checked users will get additional icons
+ copied to their Desktop when they first log in. These icons
+ do not appear in the preview.
+ </description>
+ </action>
+ </actions>
+ </group>
+ <group name="background" icon="background">
+ <caption>Desktop Background</caption>
+ <description>
+ Set up the Desktop Background also known as Wallpaper.
+ </description>
+ <preview binary="kdesktop" dcop="kdesktop" options="restart">
+ </preview>
+ <setup binary="kcmshell" args="kde-background.desktop">
+ <mutable file="kdesktoprc" />
+ <mutable file="kdeglobals" />
+ </setup>
+ <actions>
+ <action type="module" key="kde-background.desktop">
+ <caption>Lock down Desktop Background Settings</caption>
+ <description>
+ When the desktop background settings are locked down the user can no longer change them.
+ </description>
+ <action type="immutable" file="kdesktoprc" group="Desktop0"/>
+ <action type="immutable" file="kdesktoprc" group="Desktop1"/>
+ <action type="immutable" file="kdesktoprc" group="Desktop2"/>
+ <action type="immutable" file="kdesktoprc" group="Desktop3"/>
+ <action type="immutable" file="kdesktoprc" group="Desktop4"/>
+ <action type="immutable" file="kdesktoprc" group="Desktop5"/>
+ <action type="immutable" file="kdesktoprc" group="Desktop6"/>
+ <action type="immutable" file="kdesktoprc" group="Desktop7"/>
+ </action>
+ </actions>
+ </group>
+ <group name="screensaver" icon="kscreensaver">
+ <caption>Screen Saver</caption>
+ <description>
+ Set up Screen Saver
+ </description>
+ <preview binary="kdesktop" dcop="kdesktop" options="restart">
+ </preview>
+ <setup binary="kcmshell" args="kde-screensaver.desktop">
+ <mutable file="kdesktoprc" />
+ <mutable file="kdeglobals" />
+ </setup>
+ <actions>
+ <action type="module" key="kde-screensaver.desktop">
+ <caption>Lock down Screen Saver Settings</caption>
+ <description>
+ When the Screen Saver settings are locked down the user can no longer change them.
+ </description>
+ <action type="immutable" file="kdesktoprc" group="ScreenSaver"/>
+ </action>
+ <action type="action restriction" key="opengl_screensavers">
+ <caption>Disable OpenGL-based Screen Savers</caption>
+ <description>
+ OpenGL-based screen savers may cause problems on systems without decent OpenGL
+ support; with this option all such screensavers can be disabled.
+ </description>
+ </action>
+ <action type="action restriction" key="manipulatescreen_screensavers">
+ <caption>Discreet Screen Savers Only</caption>
+ <description>
+ Some screensavers do not hide the complete screen content and may leave possible
+ sensitive information visible. This option disables all such screensavers and only
+ enables those screensavers that completely hide the original content of the screen.
+ </description>
+ </action>
+ </actions>
+ </group>
+ <group name="kdemenu" icon="kmenuedit">
+ <caption>KDE Menu</caption>
+ <description>
+ The KDE Application menu
+ </description>
+ <preview binary="kicker" dcop="kicker" options="restart">
+ </preview>
+ <setup binary="kmenuedit" options="nofork">
+ <ignore file="kmenueditrc" />
+ </setup>
+ <actions>
+ <action type="action restriction" key="user/root">
+ <caption>Disable all tasks and applications that require root access</caption>
+ <description>
+ This option disables all menu items that require root access and that will ask the user for the root password.
+ </description>
+ </action>
+ <action type="action restriction" key="action/menuedit">
+ <caption>Disable menu editing</caption>
+ <description>
+ This disables the menu-option to edit the KDE Application Menu. When disabled, users will no longer be
+ able to make changes to their personal application menu.
+ </description>
+ <action type="resource restriction" key="xdgconf-menu" />
+ </action>
+ </actions>
+ </group>
+ <group name="theming" icon="style">
+ <caption>Theming</caption>
+ <description>
+ Set up of Fonts, Colors and Style
+ </description>
+<!--
+ <preview binary="kdesktop" dcop="kdesktop" options="restart">
+ </preview>
+-->
+ <setup binary="kcmshell" args="kde-style.desktop,kde-colors.desktop,kde-fonts.desktop,kde-kwindecoration.desktop">
+ <mutable file="kdesktoprc" />
+ <mutable file="kdeglobals" />
+ </setup>
+ <actions>
+ <action type="module" key="kde-style.desktop">
+ <caption>Lock down Style Settings</caption>
+ <description>
+ When the Style settings are locked down the user can no longer change them.
+ </description>
+ </action>
+ <action type="module" key="kde-colors.desktop">
+ <caption>Lock down Color Settings</caption>
+ <description>
+ When the Color settings are locked down the user can no longer change them.
+ </description>
+ </action>
+ <action type="module" key="kde-fonts.desktop">
+ <caption>Lock down Font Settings</caption>
+ <description>
+ When the Font settings are locked down the user can no longer change them.
+ </description>
+ </action>
+ <action type="module" key="kde-kwindecoration.desktop">
+ <caption>Lock down Window Decoration Settings</caption>
+ <description>
+ When the Window Decoration settings are locked down the user can no longer change them.
+ </description>
+ </action>
+ </actions>
+ </group>
+ <group name="kicker" icon="kcmkicker">
+ <caption>Panel</caption>
+ <description>
+ The KDE panel "kicker" is normally found at the bottom of the screen.
+ </description>
+ <preview binary="kicker" dcop="kicker" options="restart">
+ </preview>
+ <setup binary="kicker" dcop="kicker" options="restart">
+ <mutable file="kickerrc" />
+ <ignore file="kdeglobals" />
+ </setup>
+ <actions>
+ <action type="immutable" file="kickerrc">
+ <caption>Lock down panel</caption>
+ <description>
+ This option can be used to lock down the panel. The user will then no longer be able to add, remove or change
+ any of the permanent panel items.
+ </description>
+ </action>
+ <action type="action restriction" key="action/kicker_rmb">
+ <caption>Disable Context Menus</caption>
+ <description>
+ This option disables the context menus that one normally gets when pressing the right mouse button in the panel.
+ </description>
+ </action>
+ </actions>
+ </group>
+ <group name="proxy" icon="proxy">
+ <caption>Network Proxy</caption>
+ <description>
+ Set up of Network Proxy settings
+ </description>
+ <setup binary="kcmshell" args="kde-proxy.desktop">
+ <mutable file="kdesktoprc" />
+ <mutable file="kdeglobals" />
+ </setup>
+ <actions>
+ <action type="module" key="kde-proxy.desktop">
+ <caption>Lock down Proxy Settings</caption>
+ <description>
+ When the Proxy settings are locked down the user can no longer change them.
+ </description>
+ </action>
+ </actions>
+ </group>
+ <group name="konqueror" icon="konqueror">
+ <caption>Konqueror</caption>
+ <description>
+ Konqueror is a combined web- and filebrowser.
+ </description>
+ <actions>
+ <action type="action restriction" key="action/properties">
+ <caption>Disable Properties in context menu</caption>
+ <description>
+ This option can be used to disable the &lt;i&gt;Properties&lt;/i&gt; option in the context menu for files.
+ </description>
+ </action>
+ <action type="action restriction" key="action/openwith">
+ <caption>Disable Open With action</caption>
+ <description>
+ This option can be used to disable the &lt;i&gt;Open With&lt;/i&gt; menu option.
+ </description>
+ </action>
+ <action type="action restriction" key="action/openintab">
+ <caption>Disable Open In New Tab action</caption>
+ <description>
+ This option can be used to disable the &lt;i&gt;Open In New Tab&lt;/i&gt; menu option.
+ </description>
+ </action>
+ <action type="custom" key="restrict_file_browsing">
+ <caption>Disable file-browsing outside home directory</caption>
+ <description>
+ This option can be used to prevent the user from browsing the
+ file system outside his or her own home directory.
+ </description>
+ </action>
+ </actions>
+ </group>
+ <group name="menus">
+ <caption>Menu Actions</caption>
+ <description>
+ Common menu actions found in applications.
+ </description>
+ <actions>
+ <action type="action restriction" key="action/file_new">
+ <caption>Disable File -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;File -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/file_open">
+ <caption>Disable File -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;File -&gt; %action&lt;/i&gt; menu-option from all applications.
+ See also &lt;i&gt;Open Recent&lt;/i&gt;
+ </description>
+ </action>
+ <action type="action restriction" key="action/file_open_recent">
+ <caption>Disable File -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;File -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/file_save">
+ <caption>Disable File -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;File -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/file_save_as">
+ <caption>Disable File -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;File -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/file_revert">
+ <caption>Disable File -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;File -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/file_close">
+ <caption>Disable File -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;File -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/file_print">
+ <caption>Disable File -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;File -&gt; %action&lt;/i&gt; menu-option from all applications.
+ See also &lt;i&gt;Print Preview&lt;/i&gt;
+ </description>
+ </action>
+ <action type="action restriction" key="action/file_print_preview">
+ <caption>Disable File -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;File -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/file_mail">
+ <caption>Disable File -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;File -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/file_quit">
+ <caption>Disable File -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;File -&gt; %action&lt;/i&gt; menu-option from all applications.
+ This option has been added for completeness.
+ Usually the application can be terminated via the window manager as well.
+ </description>
+ </action>
+ <action type="action restriction" key="action/edit_undo">
+ <caption>Disable Edit -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Edit -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/edit_redo">
+ <caption>Disable Edit -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Edit -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/edit_cut">
+ <caption>Disable Edit -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Edit -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/edit_copy">
+ <caption>Disable Edit -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Edit -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/edit_paste">
+ <caption>Disable Edit -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Edit -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/edit_select_all">
+ <caption>Disable Edit -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Edit -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/edit_deselect">
+ <caption>Disable Edit -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Edit -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/edit_find">
+ <caption>Disable Edit -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Edit -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/edit_find_next">
+ <caption>Disable Edit -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Edit -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/edit_find_last">
+ <caption>Disable Edit -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Edit -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/edit_replace">
+ <caption>Disable Edit -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Edit -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/view_actual_size">
+ <caption>Disable View -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;View -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/view_fit_to_page">
+ <caption>Disable View -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;View -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/view_fit_to_width">
+ <caption>Disable View -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;View -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/view_fit_to_height">
+ <caption>Disable View -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;View -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/view_zoom_in">
+ <caption>Disable View -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;View -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/view_zoom_out">
+ <caption>Disable View -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;View -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/view_zoom">
+ <caption>Disable View -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;View -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/view_redisplay">
+ <caption>Disable View -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;View -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/go_up">
+ <caption>Disable Go -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Go -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/go_back">
+ <caption>Disable Go -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Go -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/go_forward">
+ <caption>Disable Go -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Go -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/go_home">
+ <caption>Disable Go -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Go -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/go_previous">
+ <caption>Disable Go -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Go -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/go_next">
+ <caption>Disable Go -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Go -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/go_goto">
+ <caption>Disable Go -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Go -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/go_goto_page">
+ <caption>Disable Go -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Go -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/go_goto_line">
+ <caption>Disable Go -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Go -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/go_first">
+ <caption>Disable Go -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Go -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/go_last">
+ <caption>Disable Go -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Go -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/bookmarks">
+ <caption>Disable Bookmarks</caption>
+ <description>
+ This option can be used to completely disable bookmarks in all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/bookmark_add">
+ <caption>Disable Bookmarks -&gt; %action</caption>
+ <description>
+ This option can be used to prevent users from creating new bookmarks.
+ </description>
+ </action>
+ <action type="action restriction" key="action/bookmark_edit">
+ <caption>Disable Bookmarks -&gt; %action</caption>
+ <description>
+ This option can be used to prevent users from editing bookmarks.
+ </description>
+ </action>
+ <action type="action restriction" key="action/tools_spelling">
+ <caption>Disable Tools -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Tools -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/options_show_menubar">
+ <caption>Disable Settings -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Settings -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/options_show_toolbar">
+ <caption>Disable Settings -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Settings -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/options_show_statusbar">
+ <caption>Disable Settings -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Settings -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/fullscreen">
+ <caption>Disable Settings -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Settings -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/options_save_options">
+ <caption>Disable Settings -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Settings -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/options_configure">
+ <caption>Disable Settings -&gt; Configure &lt;Application&gt;</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Settings -&gt; Configure &amp;lt;Application&amp;gt;&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/options_configure_keybinding">
+ <caption>Disable Settings -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Settings -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/options_configure_toolbars">
+ <caption>Disable Settings -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Settings -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/options_configure_notifications">
+ <caption>Disable Settings -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Settings -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/help">
+ <caption>Disable Help</caption>
+ <description>
+ You can use this to completely disable the help menu
+ </description>
+ </action>
+ <action type="action restriction" key="action/help_contents">
+ <caption>Disable Help -&gt; &lt;Application&gt; Handbook</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Help -&gt; &amp;lt;Application&amp;gt; Handbook&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/help_whats_this">
+ <caption>Disable Help -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Help -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/help_report_bug">
+ <caption>Disable Help -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Help -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/help_about_app">
+ <caption>Disable Help -&gt; About &lt;Application&gt;</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Help -&gt; About &amp;lt;Application&amp;gt;&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ <action type="action restriction" key="action/help_about_kde">
+ <caption>Disable Help -&gt; %action</caption>
+ <description>
+ This option can be used to remove the &lt;i&gt;Help -&gt; %action&lt;/i&gt; menu-option from all applications.
+ </description>
+ </action>
+ </actions>
+
+ </group>
+ <group name="krfb" icon="krfb">
+ <caption>Desktop Sharing</caption>
+ <description>
+ Remote Desktop Sharing
+ </description>
+ <setup binary="kcmshell" args="kcmkrfb">
+ </setup>
+ <actions>
+ <action type="immutable" file="krfbrc">
+ <caption>Lock down Desktop Sharing Settings</caption>
+ <description>
+ When the setting for remote desktop sharing are locked down the user can no longer change them.
+ </description>
+ </action>
+ </actions>
+ </group>
+ <group name="filetypes" icon="filetypes">
+ <caption>File Associations</caption>
+ <description>
+ Configure the applications used for opening files.
+ </description>
+ <setup binary="kcmshell" args="filetypes">
+ </setup>
+ <actions>
+ <action type="module" key="kde-filetypes.desktop">
+ <caption>Lock down File Associations Settings</caption>
+ <description>
+ When the setting for file associations are locked down the user can no longer change
+ the default applications used for opening files.
+ </description>
+ <action type="action restriction" key="action/editfiletype"></action>
+ <action type="immutable" file="profilerc"></action>
+ </action>
+<!--
+ <action type="action restriction" key="action/editfiletype">
+ <caption>Disable "Edit file type" in properties dialog</caption>
+ <description>
+ The "Edit file type" can be used to change how files are recognized and with which
+ applications such files are opened.
+ </description>
+ </action>
+-->
+ </actions>
+ </group>
+</kiosk>
diff --git a/kiosktool/kioskdata.cpp b/kiosktool/kioskdata.cpp
new file mode 100644
index 0000000..a007389
--- /dev/null
+++ b/kiosktool/kioskdata.cpp
@@ -0,0 +1,309 @@
+/*
+ * kioskdata.cpp
+ *
+ * Copyright (C) 2003, 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 "kioskdata.h"
+
+#include <qdom.h>
+#include <qfile.h>
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kstdaction.h>
+
+QDict<QString> *ComponentAction::s_stdActionCaptions = 0;
+
+ComponentAction::ComponentAction()
+{
+}
+
+ComponentAction::~ComponentAction()
+{
+}
+
+static QDict<QString> *readStdActionCaptions()
+{
+ QDict<QString> *captions = new QDict<QString>;
+ for(int i = KStdAction::ActionNone; true;)
+ {
+ i++;
+ KAction *action = KStdAction::create((KStdAction::StdAction) i, 0, 0, 0, 0);
+ if (!action)
+ break;
+
+ QString caption = action->text();
+ caption.replace("&","");
+
+ captions->insert(QString::fromLatin1(action->name()), new QString(caption));
+ }
+ return captions;
+}
+
+QString
+ComponentAction::expand(const QString &s)
+{
+ if (s.contains("%action"))
+ {
+ if (!s_stdActionCaptions)
+ s_stdActionCaptions= readStdActionCaptions();
+
+ QString action = key;
+ action.replace("action/", "");
+ QString *caption = s_stdActionCaptions->find(action);
+ if (caption)
+ {
+ QString result = s;
+ result.replace("%action", *caption);
+ return result;
+ }
+ }
+ return s;
+}
+
+bool
+ComponentAction::load(const QDomElement &docElem)
+{
+ QString _type = docElem.attribute("type");
+ if (_type == "immutable")
+ type = ActImmutable;
+ else if (_type == "action restriction")
+ type = ActRestrict;
+ else if (_type == "resource restriction")
+ type = ActResource;
+ else if (_type == "module")
+ type = ActModule;
+ else if (_type == "custom")
+ type = ActCustom;
+ else if (_type == "config")
+ type = ActConfig;
+ else
+ {
+#ifndef NDEBUG
+ if (_type.isEmpty())
+ kdFatal() << "'type' attribute missing or empty in action." << endl;
+ else
+ kdFatal() << "Unknown 'type' attribute '" << _type << "' in action." << endl;
+#endif
+ return false;
+ }
+
+ file = docElem.attribute("file");
+ group = docElem.attribute("group");
+ key = docElem.attribute("key");
+ defaultValue = (docElem.attribute("default").lower() == "true");
+
+ QDomNode n = docElem.firstChild();
+ while( !n.isNull() )
+ {
+ QDomElement e = n.toElement(); // try to convert the node to an element.
+
+ if (e.tagName() == "caption")
+ caption = expand(i18n(e.text().simplifyWhiteSpace().utf8()));
+ else if (e.tagName() == "description")
+ description = expand(i18n(e.text().simplifyWhiteSpace().utf8()));
+ else if (e.tagName() == "action")
+ {
+ ComponentAction *subAction = new ComponentAction;
+ if (subAction->load(e))
+ {
+ subActions.append(subAction);
+ }
+ else
+ {
+ delete subAction;
+ }
+ }
+
+ n = n.nextSibling();
+ }
+
+ return true;
+}
+
+
+ComponentData::ComponentData()
+{
+ actions.setAutoDelete(true);
+}
+
+ComponentData::~ComponentData()
+{
+}
+
+bool ComponentData::loadActions(const QDomElement &docElem)
+{
+ QDomNode n = docElem.firstChild();
+ while( !n.isNull() )
+ {
+ QDomElement e = n.toElement(); // try to convert the node to an element.
+
+ if (e.tagName() != "action")
+ return false;
+
+ ComponentAction *action = new ComponentAction;
+ if (action->load(e))
+ {
+ actions.append(action);
+ }
+ else
+ {
+ delete action;
+ }
+ n = n.nextSibling();
+ }
+ return true;
+}
+
+void
+ComponentExecData::load(const QDomElement &e)
+{
+ exec = e.attribute("binary");
+ dcop = e.attribute("dcop");
+ options = QStringList::split(',', e.attribute("options"));
+ args = QStringList::split(',', e.attribute("args"));
+}
+
+void
+ComponentData::loadSetup(const QDomElement &docElem)
+{
+ QDomNode n = docElem.firstChild();
+ while( !n.isNull() )
+ {
+ QDomElement e = n.toElement(); // try to convert the node to an element.
+
+ if (e.tagName() == "mutable")
+ {
+ QString f = e.attribute("file");
+ if (!f.isEmpty())
+ mutableFiles.append(f);
+ }
+ else if (e.tagName() == "ignore")
+ {
+ QString f = e.attribute("file");
+ if (!f.isEmpty())
+ ignoreFiles.append(f);
+ }
+
+ n = n.nextSibling();
+ }
+}
+
+bool ComponentData::load(const QDomElement &docElem)
+{
+ id = docElem.attribute("name");
+ icon = docElem.attribute("icon");
+ if (id.isEmpty())
+ return false;
+ QDomNode n = docElem.firstChild();
+ while( !n.isNull() )
+ {
+ QDomElement e = n.toElement(); // try to convert the node to an element.
+
+ if (e.tagName() == "caption")
+ {
+ caption = i18n(e.text().simplifyWhiteSpace().utf8());
+ }
+#if 0
+ else if (e.tagName() == "description")
+ {
+ description = i18n(e.text().simplifyWhiteSpace().utf8());
+ }
+#endif
+ else if (e.tagName() == "actions")
+ {
+ loadActions(e);
+ }
+ else if (e.tagName() == "setup")
+ {
+ setup.load(e);
+ loadSetup(e);
+ }
+ else if (e.tagName() == "preview")
+ {
+ preview.load(e);
+ }
+
+ n = n.nextSibling();
+ }
+ return true;
+}
+
+KioskData::KioskData()
+{
+ m_componentData.setAutoDelete(true);
+}
+
+KioskData::~KioskData()
+{
+}
+
+bool KioskData::load()
+{
+ QString filename = locate("appdata", "kiosk_data.xml");
+ if (filename.isEmpty())
+ {
+ m_errorMsg = i18n("<qt>Could not find <b>kiosk_data.xml</b></qt>");
+ return false;
+ }
+
+ QDomDocument doc;
+ QFile file( filename );
+ if ( !file.open( IO_ReadOnly ) )
+ {
+ m_errorMsg = i18n("<qt>Could not open <b>%1</b></qt>").arg(filename);
+ return false;
+ }
+
+ QString errorMsg;
+ int errorRow;
+ int errorCol;
+ if ( !doc.setContent( &file, &errorMsg, &errorRow, &errorCol ) )
+ {
+ m_errorMsg = i18n("<qt>Syntax error in <b>%1</b><br>Line %3, column %4: %2</qt>").arg(filename, errorMsg).arg(errorRow).arg(errorCol);
+ file.close();
+ return false;
+ }
+ file.close();
+
+ QDomElement docElem = doc.documentElement();
+ QDomNode n = docElem.firstChild();
+ while( !n.isNull() )
+ {
+ QDomElement e = n.toElement(); // try to convert the node to an element.
+
+ if (e.tagName() == "group")
+ {
+ ComponentData *componentData = new ComponentData;
+ if (componentData->load(e))
+ {
+ m_componentData.insert(componentData->id, componentData);
+ m_componentList.append(componentData->id);
+ }
+ else
+ {
+ delete componentData;
+ }
+ }
+
+ n = n.nextSibling();
+ }
+
+ return true;
+}
diff --git a/kiosktool/kioskdata.h b/kiosktool/kioskdata.h
new file mode 100644
index 0000000..fcae0f9
--- /dev/null
+++ b/kiosktool/kioskdata.h
@@ -0,0 +1,105 @@
+/*
+ * kioskdata.h
+ *
+ * Copyright (C) 2003, 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _KIOSKDATA_H_
+#define _KIOSKDATA_H_
+
+#include <qdict.h>
+#include <qptrlist.h>
+#include <qstringlist.h>
+
+class QDomElement;
+
+class ComponentAction
+{
+public:
+ ComponentAction();
+ ~ComponentAction();
+ bool load(const QDomElement &docElem);
+
+private:
+ QString expand(const QString &);
+
+public:
+ QString caption;
+ QString description;
+ typedef enum {ActImmutable, ActRestrict, ActCustom, ActModule, ActConfig, ActResource } ActionType;
+ ActionType type;
+ QString file;
+ QString group;
+ QString key;
+ QPtrList<ComponentAction> subActions;
+ bool defaultValue;
+
+ static QDict<QString> *s_stdActionCaptions;
+};
+
+class ComponentExecData
+{
+public:
+ void load(const QDomElement &docElem);
+ bool hasOption(const QString &option) { return options.contains(option); }
+public:
+ QString exec;
+ QString dcop;
+ QStringList options;
+ QStringList args;
+};
+
+class ComponentData
+{
+public:
+ ComponentData();
+ ~ComponentData();
+ bool load(const QDomElement &docElem);
+ bool loadActions(const QDomElement &docElem);
+
+protected:
+ void loadSetup(const QDomElement &docElem);
+
+public:
+ QString id;
+ QString caption;
+// QString description;
+ QString icon;
+ QPtrList<ComponentAction> actions;
+ QStringList mutableFiles;
+ QStringList ignoreFiles;
+ ComponentExecData setup;
+ ComponentExecData preview;
+};
+
+class KioskData
+{
+public:
+ KioskData();
+ ~KioskData();
+
+ QString errorMsg() { return m_errorMsg; }
+
+ bool load();
+
+public:
+ QStringList m_componentList;
+ QDict<ComponentData> m_componentData;
+
+protected:
+ QString m_errorMsg;
+};
+
+#endif
diff --git a/kiosktool/kioskgui.cpp b/kiosktool/kioskgui.cpp
new file mode 100644
index 0000000..44ec213
--- /dev/null
+++ b/kiosktool/kioskgui.cpp
@@ -0,0 +1,727 @@
+/*
+ * kioskgui.cpp
+ *
+ * Copyright (C) 2003,2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License versin 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 "kioskgui.h"
+
+#include <qdir.h>
+#include <qlineedit.h>
+#include <qobjectlist.h>
+#include <qwidgetstack.h>
+#include <qpushbutton.h>
+
+#include <kapplication.h>
+#include <kaction.h>
+#include <kcombobox.h>
+#include <kconfig.h>
+#include <kfiledialog.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+#include <kiconview.h>
+#include <klocale.h>
+#include <kmenubar.h>
+#include <kmessagebox.h>
+#include <kstatusbar.h>
+#include <kstdaccel.h>
+#include <kstdaction.h>
+#include <kstandarddirs.h>
+#include <kurlrequester.h>
+
+#include "mainview.h"
+#include "profileSelectionPage_ui.h"
+#include "profilePropsPage.h"
+#include "componentSelectionPage.h"
+#include "desktopComponent.h"
+#include "menueditComponent.h"
+#include "screensaverComponent.h"
+#include "panelComponent.h"
+#include "filetypeeditComponent.h"
+#include "componentPage.h"
+#include "pageWidget.h"
+#include "userManagement.h"
+#include "kioskConfigDialog.h"
+#include "kioskdata.h"
+#include "kioskrun.h"
+#include "kiosksync.h"
+
+KioskGui::KioskGui()
+ : KMainWindow( 0, "kioskgui" ), m_profileSelectionPage(0),
+ m_componentSelectionPage(0), m_componentPage(0), m_profileAssignPage(0),
+ m_profilePropsPage(0), m_data(0),
+ m_activePage(0), m_profile(0), m_componentData(0)
+{
+ m_run = new KioskRun;
+
+ m_view = new MainView(this);
+
+ setupActions();
+
+ updateBackground();
+
+ // tell the KMainWindow that this is indeed the main widget
+ setCentralWidget(m_view);
+
+ setWidgetBackground(m_view);
+ m_view->setBackgroundOrigin(WindowOrigin);
+
+
+ createGUI();
+
+ // apply the saved mainwindow settings, if any, and ask the mainwindow
+ // to automatically save settings if changed: window size, toolbar
+ // position, icon size, etc.
+ setAutoSaveSettings();
+
+ m_view->pbHelp->hide(); // TODO, write help :)
+
+ connect(m_view->pbDiscard, SIGNAL(clicked()), this, SLOT(discardPage()));
+ connect(m_view->pbFinished, SIGNAL(clicked()), this, SLOT(finishedPage()));
+
+ KConfig *config = kapp->config();
+ config->setGroup("General");
+ m_profile = config->readEntry("CurrentProfile", "default");
+ m_component = config->readEntry("CurrentComponent");
+
+ selectPage(PAGE_PROFILE_SELECTION, true);
+
+ QTimer::singleShot(0, this, SLOT(slotCheckEtcSkel()));
+}
+
+KioskGui::~KioskGui()
+{
+ delete m_data;
+ delete m_run;
+}
+
+void KioskGui::slotCheckEtcSkel()
+{
+ QString etcSkel = "/etc/skel/.kde";
+ KioskSync skelDir;
+ skelDir.addDir(etcSkel, KURL());
+ QStringList skelFiles = skelDir.listFiles();
+ if (!skelFiles.isEmpty())
+ {
+ KMessageBox::informationList(this,
+ i18n("<qt>Your system contains KDE configuration settings in the "
+ "skeleton directory <b>%1</b>. These files are copied to the "
+ "personal KDE settings directory of newly created users.<p>"
+ "This may interfere with the correct operation of user profiles.<p>"
+ "Unless a setting has been locked down, settings that have been copied "
+ "to the personal KDE settings directory of a user will override "
+ "a default setting configured in a profile.<p>"
+ "<b>If this is not the intended behavior, please remove the offending "
+ "files from the skeleton folder on all systems that you want to "
+ "administer with user profiles.</b><p>"
+ "The following files were found under <b>%2</b>:").arg(etcSkel).arg(etcSkel),
+ skelFiles,
+ QString::null,
+ "etc_skel_warning");
+ }
+}
+
+void KioskGui::setWidgetBackground(QWidget *w)
+{
+ QObjectList *l = w->queryList( "QWidget" );
+ QObjectListIt it( *l );
+ for(QWidget *wid=0; (wid = (QWidget*)it.current()); ++it)
+ {
+ wid->setBackgroundOrigin(WindowOrigin);
+ if (::qt_cast<QPushButton*>(wid))
+ wid->setAutoMask(true);
+ }
+ w->setBackgroundOrigin(WindowOrigin);
+ delete l;
+}
+
+void KioskGui::setSubCaption(const QString &subCaption)
+{
+ m_view->subCaptionLabel->setText("<h1>"+subCaption+"</h1>");
+}
+
+void KioskGui::setupActions()
+{
+// KStdAction::open(this, SLOT(fileOpen()), actionCollection());
+// KStdAction::save(this, SLOT(fileSave()), actionCollection());
+// KStdAction::saveAs(this, SLOT(fileSaveAs()), actionCollection());
+ KStdAction::quit(this, SLOT(close()), actionCollection());
+// KStdAction::back(this, SLOT(previousPage()), actionCollection(), "previousPage");
+// KStdAction::forward(this, SLOT(nextPage()), actionCollection(), "nextPage");
+
+// createStandardStatusBarAction();
+// setStandardToolBarMenuEnabled(true);
+
+// KStdAction::keyBindings(this, SLOT(optionsConfigureKeys()), actionCollection());
+// KStdAction::configureToolbars(this, SLOT(optionsConfigureToolbars()), actionCollection());
+ KStdAction::preferences(this, SLOT(slotConfig()), actionCollection());
+ m_uploadAction = new KAction(i18n("Upload &All Profiles"), QString::null, 0, this, SLOT(uploadAllProfiles()), actionCollection(), "upload_all");
+ m_backgroundAction = new KToggleAction(i18n("Background Graphics"), QString::null, 0, this, SLOT(slotUpdateBackground()), actionCollection(), "show_background");
+
+ updateActions();
+}
+
+void KioskGui::updateActions()
+{
+ KConfig *config = kapp->config();
+ config->setGroup("General");
+
+ bool uploadEnabled = !config->readEntry("uploadURL").isEmpty();
+
+ m_uploadAction->setEnabled(uploadEnabled);
+ m_backgroundAction->setChecked(config->readBoolEntry("FancyBackground", true));
+}
+
+void KioskGui::saveProperties(KConfig * /*config*/ )
+{
+ // the 'config' object points to the session managed
+ // config file. anything you write here will be available
+ // later when this app is restored
+}
+
+void KioskGui::readProperties(KConfig * /*config*/ )
+{
+ // the 'config' object points to the session managed
+ // config file. this function is automatically called whenever
+ // the app is being restored. read in here whatever you wrote
+ // in 'saveProperties'
+}
+
+void KioskGui::slotAddProfile()
+{
+ selectPage(PAGE_PROFILE_NEW, true);
+}
+
+void KioskGui::slotProfileProperties()
+{
+ selectPage(PAGE_PROFILE_PROPS, true);
+#if 0
+ savePage(PAGE_PROFILE_SELECTION);
+ ProfileConfigDialog dlg(this, m_profile);
+ if (dlg.exec())
+ {
+ loadPage(PAGE_PROFILE_SELECTION);
+ updateActions();
+ }
+#endif
+}
+
+void KioskGui::slotProfileSetup()
+{
+ selectPage(PAGE_COMPONENT_SELECTION, true);
+}
+
+void KioskGui::slotDeleteProfile(QListViewItem *item)
+{
+ if (!m_profileSelectionPage)
+ return;
+ if (!item)
+ item = m_profileSelectionPage->listProfile->selectedItem();
+ if (!item)
+ return;
+ QString profile = item->text(0);
+ int result = KMessageBox::warningContinueCancel(this,
+ i18n("<qt>You are about to delete the profile <b>%1</b>.<p>"
+ "Are you sure you want to do this?").arg(profile),
+ QString::null, KGuiItem(i18n("Delete"),"editdelete"));
+ if (result == KMessageBox::Continue)
+ {
+ if (KioskRun::self()->deleteProfile(profile))
+ {
+ delete item;
+
+ item = m_profileSelectionPage->listProfile->currentItem();
+ if (item)
+ m_profileSelectionPage->listProfile->setSelected(item, true);
+ }
+ }
+}
+
+void KioskGui::slotManageUsers()
+{
+ selectPage(PAGE_PROFILE_ASSIGN, true);
+}
+
+void KioskGui::slotProfileContextMenu(QListViewItem *item, const QPoint &p)
+{
+ if (!item) return; // No item selected
+
+ QPopupMenu menu(this);
+ menu.insertItem(i18n("&Delete Profile"), 1);
+
+ int result = menu.exec( p );
+ if (result == 1)
+ slotDeleteProfile(item);
+}
+
+void KioskGui::selectPage(int page, bool save)
+{
+ if (save && !savePage(m_activePage))
+ return;
+ m_activePage = page;
+ if ((m_activePage == PAGE_PROFILE_SELECTION) && !m_profileSelectionPage)
+ {
+ m_profileSelectionPage = new ProfileSelectionPageUI(this);
+ setWidgetBackground(m_profileSelectionPage);
+
+ connect(m_profileSelectionPage->listProfile,
+ SIGNAL(contextMenuRequested(QListViewItem *, const QPoint &, int)),
+ this, SLOT(slotProfileContextMenu(QListViewItem *, const QPoint &)));
+ connect(m_profileSelectionPage->listProfile,
+ SIGNAL(doubleClicked (QListViewItem *, const QPoint &, int )),
+ this, SLOT(nextPage()));
+ connect(m_profileSelectionPage->buttonDelete, SIGNAL(clicked()),
+ this, SLOT(slotDeleteProfile()));
+ connect(m_profileSelectionPage->buttonAdd, SIGNAL(clicked()),
+ this, SLOT(slotAddProfile()));
+ connect(m_profileSelectionPage->buttonProperty, SIGNAL(clicked()),
+ this, SLOT(slotProfileProperties()));
+ connect(m_profileSelectionPage->buttonSetup, SIGNAL(clicked()),
+ this, SLOT(slotProfileSetup()));
+ connect(m_profileSelectionPage->buttonUsers, SIGNAL(clicked()),
+ this, SLOT(slotManageUsers()));
+
+ m_view->widgetStack->addWidget(m_profileSelectionPage, PAGE_PROFILE_SELECTION);
+ m_profileSelectionPage->listProfile->setFocus();
+ }
+ if ((m_activePage == PAGE_COMPONENT_SELECTION) && !m_componentSelectionPage)
+ {
+ m_data = new KioskData;
+ if (!m_data->load())
+ {
+ KMessageBox::error(this, m_data->errorMsg(), i18n("Error accessing Kiosk data"));
+ }
+
+ m_componentSelectionPage = new ComponentSelectionPage(m_data, this);
+ connect(m_componentSelectionPage, SIGNAL(componentActivated()), this, SLOT(nextPage()));
+ m_componentSelectionPage->setCurrentComponent(m_component);
+ setWidgetBackground(m_componentSelectionPage);
+
+ m_view->widgetStack->addWidget(m_componentSelectionPage, PAGE_COMPONENT_SELECTION);
+ m_componentSelectionPage->listComponent->setFocus();
+ }
+ if (m_activePage == PAGE_PROFILE_NEW)
+ {
+ delete m_profilePropsPage;
+ m_profilePropsPage = new ProfilePropsPage(this, QString::null);
+ setWidgetBackground(m_profilePropsPage->widget());
+
+ m_view->widgetStack->addWidget(m_profilePropsPage->widget(), PAGE_PROFILE_NEW);
+ m_profilePropsPage->setFocus();
+ }
+ if (m_activePage == PAGE_PROFILE_PROPS)
+ {
+ delete m_profilePropsPage;
+ m_profilePropsPage = new ProfilePropsPage(this, m_profile);
+ setWidgetBackground(m_profilePropsPage->widget());
+
+ m_view->widgetStack->addWidget(m_profilePropsPage->widget(), PAGE_PROFILE_PROPS);
+ m_profilePropsPage->setFocus();
+ }
+ if ((m_activePage == PAGE_PROFILE_ASSIGN) && !m_profileAssignPage)
+ {
+ m_profileAssignPage = new UserManagementPage(this);
+ setWidgetBackground(m_profileAssignPage->widget());
+
+ m_view->widgetStack->addWidget(m_profileAssignPage->widget(), PAGE_PROFILE_ASSIGN);
+ m_profileAssignPage->setFocus();
+ }
+ if (m_activePage == PAGE_COMPONENT)
+ {
+ delete m_componentPage;
+
+ Component *component = 0;
+ if (m_component == "kdesktop")
+ component = new DesktopComponent;
+ else if (m_component == "kdemenu")
+ component = new MenuEditComponent;
+ else if (m_component == "screensaver")
+ component = new ScreenSaverComponent;
+ else if (m_component == "kicker")
+ component = new PanelComponent;
+ else if (m_component == "filetypes")
+ component = new FileTypeEditComponent;
+
+ m_componentPage = new ComponentPage(m_componentData, component, m_view->widgetStack);
+ setWidgetBackground(m_componentPage->widget());
+ m_view->widgetStack->addWidget(m_componentPage->widget(), PAGE_COMPONENT);
+ m_componentPage->setFocus();
+ }
+ m_view->widgetStack->raiseWidget(m_activePage);
+
+ switch (m_activePage)
+ {
+ case PAGE_PROFILE_SELECTION:
+ setSubCaption(i18n("Main Menu"));
+ setCaption(i18n("Main Menu"));
+ break;
+ case PAGE_PROFILE_NEW:
+ setSubCaption(i18n("Add New Profile"));
+ setCaption(i18n("Add New Profile"));
+ break;
+ case PAGE_PROFILE_PROPS:
+ setSubCaption(i18n("Profile Properties"));
+ setCaption(i18n("Profile Properties"));
+ break;
+ case PAGE_COMPONENT_SELECTION:
+ setSubCaption(i18n("Setup Profile \"%1\"").arg(m_profile));
+ setCaption(m_profile);
+ break;
+ case PAGE_COMPONENT:
+ setSubCaption(m_componentPage->subCaption());
+ break;
+ case PAGE_PROFILE_ASSIGN:
+ setSubCaption(i18n("Assign Profiles"));
+ break;
+ }
+
+ loadPage(m_activePage);
+
+ updateButtons();
+}
+
+void KioskGui::updateButtons()
+{
+ switch(m_activePage)
+ {
+ case PAGE_PROFILE_SELECTION:
+ {
+ m_view->pbDiscard->hide();
+ m_view->pbFinished->hide();
+ break;
+ }
+
+ case PAGE_COMPONENT_SELECTION:
+ {
+ m_view->pbDiscard->hide();
+ m_view->pbFinished->show();
+ break;
+ }
+
+ case PAGE_COMPONENT:
+ {
+ m_view->pbDiscard->hide();
+ m_view->pbFinished->show();
+ break;
+ }
+
+ case PAGE_PROFILE_NEW:
+ {
+ m_view->pbDiscard->show();
+ m_view->pbFinished->show();
+ break;
+ }
+
+ case PAGE_PROFILE_PROPS:
+ {
+ m_view->pbDiscard->show();
+ m_view->pbFinished->show();
+ break;
+ }
+
+ case PAGE_PROFILE_ASSIGN:
+ {
+ m_view->pbDiscard->show();
+ m_view->pbFinished->show();
+ break;
+ }
+ }
+
+ if (m_activePage == PAGE_PROFILE_NEW)
+ {
+ m_view->pbDiscard->setText(i18n("&Cancel"));
+ m_view->pbFinished->setText(i18n("&Add"));
+ }
+ else
+ {
+ m_view->pbDiscard->setText(i18n("&Discard Changes"));
+ m_view->pbFinished->setText(i18n("&Finished"));
+ }
+
+}
+
+void KioskGui::loadProfiles()
+{
+ m_profileSelectionPage->listProfile->clear();
+
+ QStringList profiles = KioskRun::self()->allProfiles();
+
+ for(QStringList::ConstIterator it = profiles.begin();
+ it != profiles.end(); ++it)
+ {
+ QString profile = *it;
+ QString description;
+ QString installUser;
+ QString installDir;
+
+ KioskRun::self()->getProfileInfo(profile, description, installDir, installUser);
+
+ QListViewItem *item = new QListViewItem(m_profileSelectionPage->listProfile, profile, description);
+ if (m_profile == profile)
+ m_profileSelectionPage->listProfile->setSelected(item, true);
+ }
+ if (!m_profileSelectionPage->listProfile->selectedItem())
+ m_profileSelectionPage->listProfile->setSelected(m_profileSelectionPage->listProfile->firstChild(), true);
+}
+
+void KioskGui::loadPage(int page)
+{
+ switch(page)
+ {
+ case PAGE_PROFILE_SELECTION:
+ {
+ loadProfiles();
+ break;
+ }
+
+ case PAGE_COMPONENT:
+ {
+ m_componentPage->load();
+ break;
+ }
+
+ case PAGE_PROFILE_NEW:
+ {
+ m_profilePropsPage->load();
+ break;
+ }
+
+ case PAGE_PROFILE_PROPS:
+ {
+ m_profilePropsPage->load();
+ break;
+ }
+
+ case PAGE_PROFILE_ASSIGN:
+ {
+ m_profileAssignPage->load();
+ break;
+ }
+ }
+}
+
+bool KioskGui::savePage(int page)
+{
+ switch(page)
+ {
+ case PAGE_PROFILE_SELECTION:
+ {
+ m_profile = m_profileSelectionPage->listProfile->selectedItem() ?
+ m_profileSelectionPage->listProfile->selectedItem()->text(0) : QString::null;
+
+ KConfig *config = kapp->config();
+ config->setGroup("General");
+ config->writeEntry("CurrentProfile", m_profile);
+ config->sync();
+
+ QString description;
+ QString installDir;
+ QString installUser;
+
+ KioskRun::self()->getProfileInfo(m_profile, description, installDir, installUser);
+
+ QStringList kdeDirs;
+ kdeDirs << installDir;
+ m_run->setKdeDirs(kdeDirs);
+ m_run->setUser(installUser);
+
+ break;
+ }
+
+ case PAGE_COMPONENT_SELECTION:
+ {
+ m_component = m_componentSelectionPage->currentComponent();
+ m_componentData = m_data->m_componentData.find(m_component);
+ if (!m_componentData)
+ return false;
+
+ return m_componentSelectionPage->save();
+ }
+
+ case PAGE_COMPONENT:
+ {
+ if (m_componentPage)
+ return m_componentPage->save();
+ }
+
+ case PAGE_PROFILE_NEW:
+ {
+ if (m_profilePropsPage)
+ {
+ m_profile = m_profilePropsPage->profile();
+ return m_profilePropsPage->save();
+ }
+ }
+
+ case PAGE_PROFILE_PROPS:
+ {
+ if (m_profilePropsPage)
+ {
+ m_profile = m_profilePropsPage->profile();
+ return m_profilePropsPage->save();
+ }
+ }
+
+ case PAGE_PROFILE_ASSIGN:
+ {
+ if (m_profileAssignPage)
+ return m_profileAssignPage->save();
+ }
+ }
+ return true;
+}
+
+void KioskGui::finishedPage(bool save)
+{
+ if (m_activePage == PAGE_PROFILE_NEW)
+ selectPage(PAGE_PROFILE_SELECTION, save);
+ else if (m_activePage == PAGE_PROFILE_PROPS)
+ selectPage(PAGE_PROFILE_SELECTION, save);
+ else if (m_activePage == PAGE_PROFILE_ASSIGN)
+ selectPage(PAGE_PROFILE_SELECTION, save);
+ else if (m_activePage > 1)
+ selectPage(m_activePage - 1, save);
+}
+
+void KioskGui::discardPage()
+{
+ finishedPage(false);
+}
+
+void KioskGui::nextPage()
+{
+ if (m_activePage < PAGE_LAST)
+ selectPage(m_activePage + 1, true);
+}
+
+void KioskGui::slotConfig()
+{
+ KioskConfigDialog dlg(this);
+ if (dlg.exec())
+ {
+ dlg.save();
+ updateActions();
+ }
+}
+
+bool KioskGui::queryClose()
+{
+ if (!savePage(m_activePage))
+ {
+ int result = KMessageBox::warningContinueCancel(this,
+ i18n("Your changes could not be saved, do you want to quit anyway?"),
+ QString::null,
+ KStdGuiItem::quit());
+ if (result == KMessageBox::Continue)
+ return true;
+ return false;
+ }
+ if (m_uploadAction->isEnabled())
+ {
+ KConfig *config = kapp->config();
+ config->setGroup("General");
+
+ KURL uploadUrl = config->readEntry("uploadURL");
+ int result = KMessageBox::questionYesNo(this,
+ i18n("<qt>Do you want to upload the profiles to <b>%1</b> ?</qt>").arg(uploadUrl.prettyURL()));
+ if (result == KMessageBox::Yes)
+ {
+ uploadAllProfiles();
+ }
+ }
+
+ return true;
+}
+
+void KioskGui::uploadAllProfiles()
+{
+ KConfig *config = kapp->config();
+ config->setGroup("General");
+ QString uploadPrefix = config->readEntry("uploadPrefix");
+ QString uploadURL = config->readEntry("uploadURL");
+
+ KioskSync sync(this);
+
+ QStringList profiles = KioskRun::self()->allProfiles();
+
+ for(QStringList::ConstIterator it = profiles.begin();
+ it != profiles.end(); ++it)
+ {
+ QString profile = *it;
+ QString description;
+ QString installUser;
+ QString installDir;
+
+ KioskRun::self()->getProfileInfo(profile, description, installDir, installUser);
+
+// sync.addDir(installDir, KURL("ftp://localhost/kde/profiles"));
+
+ QString dir = installDir;
+ if (dir.startsWith(uploadPrefix))
+ dir = dir.mid(uploadPrefix.length());
+ if (dir.startsWith("/"))
+ dir = dir.mid(1);
+
+ KURL url(uploadURL);
+ url.setPath(url.path(1)+dir);
+ sync.addDir(installDir, url);
+ }
+
+ if (sync.sync())
+ {
+ KMessageBox::information(this, i18n("<qt>All profiles have been successfully uploaded to <b>%1</b>").arg(uploadURL));
+ }
+}
+
+void KioskGui::uploadCurrentProfile()
+{
+}
+
+void KioskGui::slotUpdateBackground()
+{
+ KConfig *config = kapp->config();
+ config->setGroup("General");
+ config->writeEntry("FancyBackground", m_backgroundAction->isChecked());
+ config->sync();
+ updateBackground();
+}
+
+void KioskGui::updateBackground()
+{
+ if (m_backgroundAction->isChecked())
+ {
+ m_view->setPaletteBackgroundPixmap(locate("appdata", "background.png"));
+ m_view->logoLabel->setPixmap(locate("appdata", "logo.png"));
+ m_view->logoLabel->setMinimumSize(QSize(160,170));
+ QString language = KGlobal::locale()->language();
+ QString caption = locate("appdata", "caption-"+language+".png");
+ if (caption.isEmpty())
+ caption = locate("appdata", "caption.png");
+ QPixmap pm(caption);
+ m_view->captionLabel->setPixmap(pm);
+ m_view->captionLabel->setMinimumHeight(pm.height());
+ }
+ else
+ {
+ m_view->unsetPalette();
+ m_view->logoLabel->setPixmap(QPixmap());
+ m_view->logoLabel->setMinimumSize(0,0);
+ m_view->captionLabel->setPixmap(QPixmap());
+ m_view->captionLabel->setMinimumHeight(0);
+ }
+}
+
+
+#include "kioskgui.moc"
diff --git a/kiosktool/kioskgui.h b/kiosktool/kioskgui.h
new file mode 100644
index 0000000..2cb814d
--- /dev/null
+++ b/kiosktool/kioskgui.h
@@ -0,0 +1,109 @@
+/*
+ * kioskgui.h
+ *
+ * Copyright (C) 2003,2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _KIOSKGUI_H_
+#define _KIOSKGUI_H_
+
+#include <qlistview.h>
+
+#include <kconfig.h>
+#include <kmainwindow.h>
+
+class MainView;
+class ProfileSelectionPageUI;
+class ComponentSelectionPage;
+class ProfilePropsPage;
+class PageWidget;
+class KioskData;
+class KioskRun;
+class ComponentData;
+class KAction;
+class KToggleAction;
+
+class KioskGui : public KMainWindow
+{
+ Q_OBJECT
+public:
+ enum { PAGE_PROFILE_SELECTION = 1,
+ PAGE_COMPONENT_SELECTION = 2,
+ PAGE_COMPONENT = 3,
+ PAGE_PROFILE_NEW = 4,
+ PAGE_PROFILE_PROPS = 5,
+ PAGE_PROFILE_ASSIGN = 6,
+ PAGE_LAST = PAGE_PROFILE_ASSIGN };
+
+ KioskGui();
+ ~KioskGui();
+
+ void setupActions();
+ void saveProperties(KConfig *config);
+ void readProperties(KConfig *config);
+
+ void selectPage(int page, bool save);
+ void loadPage(int page);
+ bool savePage(int page);
+
+ void loadProfiles();
+
+public slots:
+ void updateButtons();
+ void finishedPage(bool save=true);
+ void discardPage();
+ void nextPage();
+ void slotDeleteProfile(QListViewItem *item=0);
+ void slotAddProfile();
+ void slotProfileProperties();
+ void slotProfileSetup();
+ void slotManageUsers();
+ void slotProfileContextMenu(QListViewItem *item, const QPoint &p);
+ void slotConfig();
+
+ void uploadAllProfiles();
+ void uploadCurrentProfile();
+ void slotUpdateBackground();
+
+ void slotCheckEtcSkel();
+
+protected:
+ void updateActions();
+ void updateBackground();
+ void setWidgetBackground(QWidget *w);
+ void setSubCaption(const QString &subCaption);
+
+ virtual bool queryClose();
+
+protected:
+ MainView *m_view;
+ ProfileSelectionPageUI *m_profileSelectionPage;
+ ComponentSelectionPage *m_componentSelectionPage;
+ PageWidget *m_componentPage;
+ PageWidget *m_profileAssignPage;
+ ProfilePropsPage *m_profilePropsPage;
+
+ KioskData *m_data;
+ KioskRun *m_run;
+
+ int m_activePage;
+ QString m_profile;
+ QString m_component;
+ ComponentData * m_componentData;
+ KAction *m_uploadAction;
+ KToggleAction *m_backgroundAction;
+};
+
+#endif
diff --git a/kiosktool/kioskrun.cpp b/kiosktool/kioskrun.cpp
new file mode 100644
index 0000000..f243cfc
--- /dev/null
+++ b/kiosktool/kioskrun.cpp
@@ -0,0 +1,1687 @@
+/*
+ * kioskrun.cpp
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 "kioskrun.h"
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <qdir.h>
+#include <qfile.h>
+
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kprocess.h>
+#include <ksavefile.h>
+#include <ksimpleconfig.h>
+#include <kstandarddirs.h>
+#include <kurl.h>
+#include <kuser.h>
+
+#include "kiosksync.h"
+
+#include <kio/netaccess.h>
+#define NETACCESS KIO::NetAccess
+
+#undef DEBUG_ENTRIES
+
+KioskRun *KioskRun::s_self = 0;
+
+KioskRun::KioskRun( QObject* parent, const char* name)
+ : QObject(parent, name), m_dcopClient(0), m_instance(0), m_localKdercConfig(0)
+{
+ m_noRestrictions = false;
+ m_forceSycocaUpdate = false;
+ s_self = this;
+ m_saveConfigCache.setAutoDelete(true);
+ m_immutableStatusCache.setAutoDelete(true);
+ m_homeDir = QDir::homeDirPath()+"/.kde-test";
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ m_kderc = QFile::decodeName(args->getOption("kderc"));
+ m_isRoot = (getuid() == 0);
+}
+
+KioskRun::~KioskRun()
+{
+ shutdownRuntimeEnv();
+ s_self = 0;
+}
+
+void
+KioskRun::setUser(const QString &user)
+{
+ if (m_user == user) return;
+
+ shutdownRuntimeEnv();
+ shutdownConfigEnv();
+ m_user = user;
+}
+
+static void filterDupes(QStringList &list)
+{
+ QStringList tmp;
+ for(QStringList::ConstIterator it = list.begin();
+ it != list.end(); ++it)
+ {
+ if (!tmp.contains(*it))
+ tmp.append(*it);
+ }
+ list = tmp;
+}
+
+void
+KioskRun::setKdeDirs(const QStringList &dirs)
+{
+ if (m_kdeDirs == dirs) return;
+
+ shutdownRuntimeEnv();
+ shutdownConfigEnv();
+ m_kdeDirs = dirs;
+ QStringList xdgDataDirs = QStringList::split(':', QFile::decodeName(getenv("XDG_DATA_DIRS")));
+ if (xdgDataDirs.isEmpty())
+ {
+ xdgDataDirs = QStringList::split(':', KGlobal::dirs()->kfsstnd_prefixes());
+ xdgDataDirs.pop_front();
+ for(QStringList::Iterator it = xdgDataDirs.begin();
+ it != xdgDataDirs.end(); ++it)
+ {
+ *it += "share";
+ }
+ xdgDataDirs << "/usr/local/share" << "/usr/share";
+ }
+
+ m_xdgDataDirs.clear();
+ for(QStringList::ConstIterator it = dirs.begin();
+ it != dirs.end(); ++it)
+ {
+ m_xdgDataDirs.append(*it+"/share");
+ }
+ m_xdgDataDirs += xdgDataDirs;
+ filterDupes(m_xdgDataDirs);
+
+ QStringList xdgConfigDirs = QStringList::split(':', QFile::decodeName(getenv("XDG_CONFIG_DIRS")));
+ if (xdgConfigDirs.isEmpty())
+ {
+ xdgConfigDirs << "/etc/xdg";
+ QString sysconfMenuDir = KGlobal::dirs()->findDirs("xdgconf-menu", QString::null).last();
+ if (sysconfMenuDir.endsWith("/menus/"))
+ xdgConfigDirs << sysconfMenuDir.left(sysconfMenuDir.length()-7);
+
+ }
+
+ m_xdgConfigDirs.clear();
+ for(QStringList::ConstIterator it = dirs.begin();
+ it != dirs.end(); ++it)
+ {
+ m_xdgConfigDirs.append(*it+"/etc/xdg");
+ }
+
+ m_xdgConfigDirs += xdgConfigDirs;
+ filterDupes(m_xdgConfigDirs);
+}
+
+void
+KioskRun::deleteDir(const QString &dir)
+{
+ if (dir.length() <= 1) // Safety
+ return;
+ if (!dir.startsWith("/")) // Safety
+ return;
+ Q_ASSERT(dir.startsWith(m_homeDir));
+
+ KProcess proc;
+ proc << "rm" << "-rf" << dir;
+ proc.start(KProcess::Block);
+}
+
+void
+KioskRun::applyEnvironment(KProcess *p)
+{
+ p->setEnvironment("HOME", m_homeDir);
+ p->setEnvironment("KDEHOME", m_homeDir+"/.kde");
+ p->setEnvironment("KDEROOTHOME", m_homeDir+"/.kde");
+ p->setEnvironment("KDEDIRS", m_kdeDirs.join(":"));
+ p->setEnvironment("XDG_DATA_HOME", m_homeDir+"/.local/share");
+ p->setEnvironment("XDG_DATA_DIRS", m_xdgDataDirs.join(":"));
+ p->setEnvironment("XDG_CONFIG_HOME", m_homeDir+"/.config");
+ p->setEnvironment("XDG_CONFIG_DIRS", m_xdgConfigDirs.join(":"));
+ p->setEnvironment("DCOPAUTHORITY", m_homeDir+"/.kde/DCOPserver");
+ p->setEnvironment("KDE_KIOSK_NO_PROFILES", "true");
+ if (m_noRestrictions)
+ p->setEnvironment("KDE_KIOSK_NO_RESTRICTIONS", "true");
+}
+
+bool
+KioskRun::prepare()
+{
+ bool result = setupRuntimeEnv();
+
+ deleteDir(m_configDir);
+ deleteDir(locateLocal("data"));
+ deleteDir(m_desktopPath);
+ deleteDir(m_homeDir+"/.config");
+ deleteDir(m_homeDir+"/.local/share");
+ return result;
+}
+
+void
+KioskRun::updateSycoca()
+{
+ // Force update
+ QString sycocaUpdateFile = KioskRun::self()->locateLocal("services", "update_ksycoca");
+ QFile file(sycocaUpdateFile);
+ file.remove();
+ file.open(IO_WriteOnly);
+ file.close();
+
+ dcopRef("kded", "kbuildsycoca").call("recreate");
+}
+
+KProcess*
+KioskRun::run(const QString &cmd, const QStringList &args)
+{
+ KProcess *proc = new KProcess(this);
+
+ applyEnvironment(proc);
+
+ *proc << cmd;
+ *proc << args;
+
+ proc->start(KProcess::NotifyOnExit);
+ return proc;
+}
+
+class SetEnv
+{
+public:
+ SetEnv(const char *key, const QString &value) : m_key(key)
+ {
+ m_oldValue = getenv(m_key);
+ setenv(m_key, QFile::encodeName(value), 1);
+ }
+
+ ~SetEnv()
+ {
+ if (m_oldValue.isEmpty())
+ setenv(m_key,"",1);
+ else
+ setenv(m_key,m_oldValue.data(),1);
+ }
+
+private:
+ const char* m_key;
+ QCString m_oldValue;
+};
+
+void
+KioskRun::setupConfigEnv()
+{
+ if (m_instance) return;
+
+ // ::locateLocal must be called before we change the env. vars!
+ QString newTmpDir = ::locateLocal("tmp", "kioskdir");
+ QString newSocketDir = ::locateLocal("socket", "kioskdir");
+
+ SetEnv home("HOME", m_homeDir);
+ QString kdeHome = m_homeDir+"/.kde";
+ SetEnv kdehome("KDEHOME", kdeHome);
+ SetEnv kderoothome("KDEROOTHOME", kdeHome);
+ SetEnv kdedirs("KDEDIRS", m_kdeDirs.join(":"));
+ SetEnv xdgDataHome("XDG_DATA_HOME", m_homeDir+"/.local/share");
+ SetEnv xdgDataDirs("XDG_DATA_DIRS", m_xdgDataDirs.join(":"));
+ SetEnv xdgConfigHome("XDG_CONFIG_HOME", m_homeDir+"/.config");
+ SetEnv xdgConfigDirs("XDG_CONFIG_DIRS", m_xdgConfigDirs.join(":"));
+
+ ::mkdir(QFile::encodeName(m_homeDir), 0700);
+ ::mkdir(QFile::encodeName(kdeHome), 0700);
+
+ // Create temp & socket dirs.
+ char hostname[256];
+ hostname[0] = 0;
+ gethostname(hostname, 255);
+
+ QString tmpDir = QString("%1/%2-%3").arg(kdeHome).arg("tmp").arg(hostname);
+ deleteDir(tmpDir);
+ ::mkdir(QFile::encodeName(newTmpDir), 0700);
+ ::symlink(QFile::encodeName(newTmpDir), QFile::encodeName(tmpDir));
+
+ QString socketDir = QString("%1/%2-%3").arg(kdeHome).arg("socket").arg(hostname);
+ deleteDir(socketDir);
+ ::mkdir(QFile::encodeName(newSocketDir), 0700);
+ ::symlink(QFile::encodeName(newSocketDir), QFile::encodeName(socketDir));
+
+ m_configDir = QString("%1/.kde/share/config/").arg(m_homeDir);
+
+ m_instance = new KInstance("kioskrun");
+ (void) m_instance->dirs(); // Create KStandardDirs obj
+
+ m_desktopPath = m_homeDir + "/Desktop/";
+ m_desktopPath = m_instance->config()->readPathEntry( "Desktop", m_desktopPath);
+ m_desktopPath = QDir::cleanDirPath( m_desktopPath );
+ if ( !m_desktopPath.endsWith("/") )
+ m_desktopPath.append('/');
+
+ {
+ SetEnv kdehome("KDEHOME", "-");
+ SetEnv kderoothome("KDEROOTHOME", "-");
+ SetEnv xdgDataHome("XDG_DATA_HOME", m_xdgDataDirs.first());
+ SetEnv xdgConfigHome("XDG_CONFIG_HOME", m_xdgConfigDirs.first());
+
+ m_saveInstance = new KInstance("kioskrun");
+ (void) m_saveInstance->dirs(); // Create KStandardDirs obj
+ }
+}
+
+QString
+KioskRun::locate(const char *resource, const QString &filename)
+{
+ setupConfigEnv();
+
+ return m_saveInstance->dirs()->findResource(resource, filename);
+}
+
+QString
+KioskRun::locateSave(const char *resource, const QString &filename)
+{
+ setupConfigEnv();
+
+ // split path from filename
+ int slash = filename.findRev('/')+1;
+ QString dir = filename.left(slash);
+ QString file = filename.mid(slash);
+ return m_saveInstance->dirs()->saveLocation(resource, dir, false) + file;
+}
+
+QString
+KioskRun::locateLocal(const char *resource, const QString &filename)
+{
+ setupConfigEnv();
+
+ // split path from filename
+ int slash = filename.findRev('/')+1;
+ QString dir = filename.left(slash);
+ QString file = filename.mid(slash);
+ return m_instance->dirs()->saveLocation(resource, dir, true) + file;
+}
+
+
+void
+KioskRun::shutdownConfigEnv()
+{
+ if (!m_instance) return;
+
+ delete m_instance;
+ m_instance = 0;
+}
+
+class ImmutableStatus
+{
+public:
+ bool m_fileScope;
+ QDict<int> m_lines;
+ QString m_tmpFile;
+ bool m_dirty;
+};
+
+
+bool
+KioskRun::isConfigImmutable(const QString &filename, const QString &group)
+{
+ (void) configFile(filename);
+ ImmutableStatus *status = m_immutableStatusCache.find(filename);
+ assert(status);
+ if (group.isEmpty())
+ return status->m_fileScope;
+
+ return status->m_lines.find(group);
+}
+
+void
+KioskRun::setConfigImmutable(const QString &filename, const QString &_group, bool bImmutable)
+{
+ (void) configFile(filename);
+ ImmutableStatus *status = m_immutableStatusCache.find(filename);
+ assert(status);
+ if (_group.isEmpty())
+ {
+ if (status->m_fileScope != bImmutable)
+ {
+ status->m_fileScope = bImmutable;
+ status->m_dirty = true;
+ m_forceSycocaUpdate = true;
+ }
+ }
+ else
+ {
+ QString group = QString("[%1]").arg(_group);
+ if (status->m_lines.find(group))
+ {
+ if (!bImmutable)
+ {
+ status->m_lines.remove(group);
+ status->m_dirty = true;
+ m_forceSycocaUpdate = true;
+ }
+ }
+ else
+ {
+ if (bImmutable)
+ {
+ status->m_lines.insert(group, (int *) 1);
+ status->m_dirty = true;
+ m_forceSycocaUpdate = true;
+ }
+ }
+ }
+}
+
+static void stripImmutable(QString &ext)
+{
+ ext.replace("i", "");
+ if (ext == "[$]")
+ ext = QString::null;
+}
+
+static void addImmutable(QString &ext)
+{
+ ext.replace("[$", "[$i");
+}
+
+QString
+KioskRun::saveImmutableStatus(const QString &filename)
+{
+ ImmutableStatus *status = new ImmutableStatus;
+ status->m_fileScope = false;
+ status->m_dirty = false;
+ m_immutableStatusCache.insert(filename, status);
+
+ KTempFile tmp;
+ tmp.close();
+
+ QString newPath = tmp.name();
+ status->m_tmpFile = tmp.name();
+
+ QString path = m_saveInstance->dirs()->findResource("config", filename);
+ if (path.isEmpty())
+ return newPath; // Nothing to do
+
+ QFile oldCfg(path);
+
+ if (!oldCfg.open( IO_ReadOnly ))
+ return newPath; // Error
+
+ QFile newCfg(newPath);
+ if (!newCfg.open( IO_WriteOnly ))
+ return newPath; // Error
+
+ QTextStream txtIn(&oldCfg);
+ txtIn.setEncoding(QTextStream::UnicodeUTF8);
+
+ QTextStream pTxtOut(&newCfg);
+ pTxtOut.setEncoding(QTextStream::UnicodeUTF8);
+
+ QRegExp immutable("(\\[\\$e?ie?\\])$");
+
+ // TODO: Use "group+key" instead of "key" as index, otherwise it might not be unique
+
+ while(! txtIn.atEnd())
+ {
+ QString line = txtIn.readLine().stripWhiteSpace();
+
+ if (line.startsWith("#"))
+ {
+ // Comment, do nothing...
+ }
+ else if (line.startsWith("["))
+ {
+ int pos = immutable.searchRev(line);
+ if (pos != -1)
+ {
+ QString group = line.left(pos);
+ QString ext = immutable.cap(0);
+ stripImmutable(ext);
+ if (pos == 0)
+ {
+ status->m_fileScope = true;
+ continue;
+ }
+ status->m_lines.replace(group, (int *)1 );
+ line = group + ext;
+ }
+ }
+ else
+ {
+ int equal = line.find('=');
+ if (equal != -1)
+ {
+ QString key = line.left(equal).stripWhiteSpace();
+ int pos = immutable.searchRev(key);
+ if (pos != -1)
+ {
+ key = key.left(pos);
+ QString ext = immutable.cap(0);
+ stripImmutable(ext);
+ status->m_lines.replace(key, (int *)1 );
+ line = key + ext + line.mid(equal);
+ }
+ }
+ }
+
+ pTxtOut << line << endl;
+ }
+ oldCfg.close();
+ newCfg.close();
+
+ if (newCfg.status() != IO_Ok )
+ {
+ kdWarning() << "Error writing " << newPath << endl;
+ return newPath;
+ }
+ return newPath;
+}
+
+bool
+KioskRun::restoreImmutableStatus(const QString &filename, bool force)
+{
+ ImmutableStatus *status = m_immutableStatusCache.take(filename);
+ if (!status)
+ {
+ kdDebug() << "KioskRun::restoreImmutableStatus(" << filename << ") status info missing" << endl;
+ return true;
+ }
+ if (!force && !status->m_dirty)
+ {
+ kdDebug() << "KioskRun::restoreImmutableStatus(" << filename << ") not changed" << endl;
+ delete status;
+ return true;
+ }
+ kdDebug() << "KioskRun::restoreImmutableStatus(" << filename << ") restoring" << endl;
+
+ QString path = status->m_tmpFile;
+
+ KSaveFile newCfg(path);
+ if (newCfg.status() != 0)
+ {
+ delete status;
+ return true; // Continue
+ }
+
+ QTextStream *pTxtOut = newCfg.textStream();
+ pTxtOut->setEncoding(QTextStream::UnicodeUTF8);
+
+ QRegExp option("(\\[\\$e\\])$");
+
+ if (status->m_fileScope)
+ {
+ kdDebug() << "Marking file " << filename << " immutable" << endl;
+ (*pTxtOut) << "[$i]" << endl;
+ }
+
+ QFile oldCfg(path);
+ if (oldCfg.open( IO_ReadOnly ))
+ {
+
+ QTextStream txtIn(&oldCfg);
+ txtIn.setEncoding(QTextStream::UnicodeUTF8);
+
+ while(! txtIn.atEnd())
+ {
+ QString line = txtIn.readLine().stripWhiteSpace();
+
+ if (line.startsWith("#"))
+ {
+ // Comment, do nothing...
+ }
+ else if (line.startsWith("["))
+ {
+ if (status->m_lines.take(line))
+ line += "[$i]";
+ }
+ else
+ {
+ int equal = line.find('=');
+ if (equal != -1)
+ {
+ QString key = line.left(equal).stripWhiteSpace();
+ int pos = option.searchRev(key);
+ if (pos != -1)
+ {
+ key = key.left(pos);
+ QString ext = option.cap(0);
+ if (status->m_lines.take(key))
+ addImmutable(ext);
+ line = key + ext + line.mid(equal);
+ }
+ else
+ {
+ if (status->m_lines.take(key))
+ line = key + "[$i]" + line.mid(equal);
+ }
+ }
+ }
+
+ (*pTxtOut) << line << endl;
+ }
+ oldCfg.close();
+ }
+
+ // Create remaining groups that were marked as immutable
+ QDictIterator<int> it( status->m_lines );
+ for( ; it.current(); ++it )
+ {
+ QString group = it.currentKey();
+ if ( it.current() )
+ (*pTxtOut) << endl << group << "[$i]" << endl;
+ }
+
+ if (!newCfg.close())
+ {
+ kdWarning() << "Error writing" << path << endl;
+ delete status;
+ return true; // Continue
+ }
+
+ QString installLocation = m_saveInstance->dirs()->saveLocation("config", QString::null, false) + filename;
+ if (!install(path, installLocation))
+ {
+ m_immutableStatusCache.insert(filename, status); // Keep it around
+ return false;
+ }
+ delete status;
+ return true;
+}
+
+bool
+KioskRun::flushConfigCache()
+{
+ while ( !m_saveConfigCache.isEmpty() )
+ {
+ QDictIterator<KConfig> it( m_saveConfigCache );
+ QString file = it.currentKey();
+ KConfig *config = it.current();
+ bool dirty = config->isDirty();
+ config->sync(); // Save
+ if (!restoreImmutableStatus(file, dirty))
+ return false;
+ m_saveConfigCache.remove(file);
+ }
+
+ if (m_forceSycocaUpdate)
+ forceSycocaUpdate();
+ return true;
+}
+
+KConfig *
+KioskRun::configFile(const QString &filename)
+{
+ KConfig *config = m_saveConfigCache.find(filename);
+ if (config)
+ return config;
+
+ kdDebug() << "KioskRun::configFile(" << filename << ") loading file" << endl;
+
+ setupConfigEnv();
+
+ QString saveLocation = saveImmutableStatus(filename);
+ config = new KSimpleConfig(saveLocation);
+ m_saveConfigCache.insert(filename, config);
+
+ return config;
+}
+
+void
+KioskRun::makeMutable(bool bMutable)
+{
+ KConfig *config = configFile("kdeglobals");
+
+ m_noRestrictions = bMutable;
+ if (KDE::version() < KDE_MAKE_VERSION(3,2,4))
+ {
+ config->setGroup("KDE Action Restrictions");
+ if (bMutable)
+ {
+ KUser thisUser;
+ config->writeEntry("kiosk_exception", thisUser.loginName()+":"); // This user, all hosts
+ }
+ else
+ {
+ config->writeEntry("kiosk_exception", QString::null);
+ }
+ }
+ // Propagate to kdeinit
+ dcopRef("klauncher", "klauncher").call("setLaunchEnv",
+ QCString("KDE_KIOSK_NO_RESTRICTIONS"), QCString(m_noRestrictions ? "true" : ""));
+
+ setConfigImmutable("kdeglobals", "KDE Action Restrictions", true);
+}
+
+QStringList
+KioskRun::newConfigFiles()
+{
+ setupConfigEnv();
+
+ QStringList exceptions;
+ exceptions << "kconf_updaterc";
+
+ QStringList result;
+ QDir dir(m_configDir);
+ dir.setFilter( QDir::Files | QDir::NoSymLinks );
+
+ const QFileInfoList *list = dir.entryInfoList();
+ if (!list) return result;
+
+ QFileInfoListIterator it( *list );
+ QFileInfo *fi;
+ while ( (fi = it.current()) != 0 )
+ {
+ QString file = fi->fileName();
+ if (!file.endsWith("~") && !exceptions.contains(file)) // Skip backup files & exceptions
+ result.append(file);
+ ++it;
+ }
+ return result;
+}
+
+void
+KioskRun::mergeConfigFile(const QString &filename)
+{
+ KConfig *saveCfg = configFile(filename);
+
+ kdDebug() << "KioskRun::mergeConfigFile(" << (m_configDir + filename) << ")" << endl;
+ KSimpleConfig newCfg(m_configDir + filename);
+
+ QStringList groups = newCfg.groupList();
+ for(QStringList::ConstIterator it = groups.begin();
+ it != groups.end(); ++it)
+ {
+ saveCfg->setGroup(*it);
+ QMap<QString, QString> map = newCfg.entryMap(*it);
+ for(QMap<QString, QString>::Iterator it2 = map.begin();
+ it2 != map.end(); ++it2)
+ {
+#ifdef DEBUG_ENTRIES
+qWarning("[%s] %s --> %s", (*it).latin1(), it2.key().latin1(), it2.data().latin1());
+#endif
+ saveCfg->writeEntry(it2.key(), it2.data());
+ }
+ }
+}
+
+bool
+KioskRun::setupRuntimeEnv()
+{
+ if (m_dcopClient) return true;
+
+ KioskRunProgressDialog dlg(kapp->mainWidget(), "kioskrun_progress",
+ i18n("Setting Up Configuration Environment"),
+ i18n("Setting up configuration environment."));
+
+ char hostname[256];
+ hostname[0] = 0;
+ gethostname(hostname, 255);
+ QString cacheDir = QString("%1/.kde/cache-%2").arg(m_homeDir).arg(hostname);
+
+ deleteDir(cacheDir);
+ KStandardDirs::makeDir(cacheDir);
+ deleteDir(m_homeDir+"/.qt");
+ ::unlink(QFile::encodeName(m_homeDir+".kderc"));
+
+
+ QString iceAuth = QString("%1/.ICEauthority").arg(QDir::homeDirPath());
+ setenv("ICEAUTHORITY", QFile::encodeName(iceAuth), 0); // Don't overwrite existing setting
+
+ QString xAuth = QString("%1/.Xauthority").arg(QDir::homeDirPath());
+ setenv("XAUTHORITY", QFile::encodeName(xAuth), 0); // Don't overwrite existing setting
+
+ QString dcopServerFile = m_homeDir+"/.kde/DCOPserver";
+
+ KProcess kdeinit;
+
+ applyEnvironment(&kdeinit);
+
+ kdeinit << "kdeinit";
+
+ connect(&kdeinit, SIGNAL(processExited(KProcess *)), &dlg, SLOT(slotFinished()));
+
+ kdeinit.start(KProcess::NotifyOnExit);
+
+ dlg.exec();
+
+ QCString dcopSrv;
+ QFile f(dcopServerFile);
+ if (f.open(IO_ReadOnly))
+ {
+ int size = QMIN( 1024, f.size() ); // protection against a huge file
+ QCString contents( size+1 );
+ if ( f.readBlock( contents.data(), size ) == size )
+ {
+ contents[size] = '\0';
+ int pos = contents.find('\n');
+ if ( pos == -1 ) // Shouldn't happen
+ dcopSrv = contents;
+ else
+ dcopSrv = contents.left( pos );
+ }
+ }
+
+ if (dcopSrv.isEmpty())
+ {
+ kdWarning() << "Error reading " << dcopServerFile << endl;
+ m_dcopClient = new DCOPClient;
+ shutdownRuntimeEnv();
+ return false;
+ }
+
+ m_dcopClient = new DCOPClient;
+ m_dcopClient->setServerAddress(dcopSrv);
+ unsetenv("DCOPSERVER"); // Don't propagate it
+ m_dcopClient->attach();
+ return true;
+}
+
+void
+KioskRun::shutdownRuntimeEnv()
+{
+ if (!m_dcopClient) return;
+
+ delete m_dcopClient;
+ m_dcopClient = 0;
+
+ KProcess kdeinit;
+ applyEnvironment(&kdeinit);
+
+ kdeinit << "kdeinit_shutdown";
+
+ kdeinit.start(KProcess::Block);
+
+ KProcess dcopserver;
+ applyEnvironment(&dcopserver);
+
+ dcopserver << "dcopserver_shutdown";
+
+ dcopserver.start(KProcess::Block);
+}
+
+DCOPRef
+KioskRun::dcopRef(const QCString &appId, const QCString &objId)
+{
+ if (!setupRuntimeEnv())
+ return DCOPRef();
+ DCOPRef ref(appId, objId);
+ ref.setDCOPClient(m_dcopClient);
+ return ref;
+}
+
+// Lookup the setting for a custom action
+bool
+KioskRun::lookupCustomAction(const QString &action)
+{
+ KConfig *cfg = KioskRun::self()->configFile("kdeglobals");
+ cfg->setGroup("KDE Custom Restrictions");
+ return cfg->readBoolEntry(action, false);
+}
+
+// Change the setting for a custom action
+void
+KioskRun::setCustomAction(const QString &action, bool checked)
+{
+ KConfig *cfg = KioskRun::self()->configFile("kdeglobals");
+ cfg->setGroup("KDE Custom Restrictions");
+ if (cfg->readBoolEntry(action, false) != checked)
+ {
+ cfg->writeEntry(action, checked);
+ KioskRun::self()->scheduleSycocaUpdate();
+
+ if (action == "restrict_file_browsing")
+ {
+ setCustomRestrictionFileBrowsing(checked);
+ }
+ }
+}
+
+// Create directory
+bool
+KioskRun::createDir(const QString &dir)
+{
+ if (QDir(dir).exists())
+ return true; // Exists already
+
+ KURL dest;
+ if (!m_isRoot || (m_user != "root"))
+ {
+ dest.setProtocol("fish");
+ dest.setHost("localhost");
+ dest.setUser(m_user);
+ }
+ dest.setPath(dir);
+
+ if (dir.length() > 1)
+ {
+ KURL parent = dest.upURL();
+
+ bool result = createDir(parent.path());
+ if (!result)
+ return false;
+ }
+
+ do
+ {
+ if (NETACCESS::exists(dest, false, kapp->mainWidget()))
+ return true;
+
+ bool result = NETACCESS::mkdir(dest, kapp->mainWidget(), 0755);
+ if (result == true)
+ return true;
+
+ QString error = NETACCESS::lastErrorString();
+ QString msg;
+
+ if (error.isEmpty())
+ msg = i18n("<qt>The directory <b>%1</b> could not be created because of an unspecified problem.<p>")
+ .arg(dir);
+ else
+ msg = i18n("<qt>The directory <b>%1</b> could not be created because of the following problem:"
+ "<p>%2<p>")
+ .arg(dir, NETACCESS::lastErrorString());
+
+ msg += i18n("Without this directory your changes can not be saved.<p>"
+ "Do you want to retry creating the directory or abort the saving of changes?</qt>");
+
+ int msgResult = KMessageBox::warningYesNo(kapp->mainWidget(), msg, QString::null,
+ i18n("&Retry"), i18n("&Abort"));
+
+ if (msgResult == KMessageBox::No)
+ return false;
+
+ // Maybe the user created it in the meantime
+ if (QDir(dir).exists())
+ return true; // Exists already
+ }
+ while (true);
+ return false;
+}
+
+// Create directory
+bool
+KioskRun::createRemoteDirRecursive(const KURL &dest, bool ask)
+{
+ if (NETACCESS::exists(dest, false, kapp->mainWidget()))
+ return true;
+
+ KURL parent = dest.upURL();
+
+ if (NETACCESS::exists(dest, false, kapp->mainWidget()))
+ {
+ return createRemoteDir(dest);
+ }
+
+ if (ask)
+ {
+ // Parent doesn't exist,
+ int result = KMessageBox::warningContinueCancel(kapp->mainWidget(),
+ i18n("<qt>The directory <b>%1</b> does not yet exist. "
+ "Do you want to create it?").arg(parent.prettyURL()), QString::null,
+ i18n("Create &Dir"));
+ if (result != KMessageBox::Continue)
+ return false;
+ }
+
+ QString path = dest.path(1);
+ int i = 0;
+ while ( (i = path.find('/', i+1)) != -1)
+ {
+ parent.setPath(path.left(i+1));
+ if (! createRemoteDir(parent))
+ return false;
+ }
+ return true;
+}
+
+// Create directory
+bool
+KioskRun::createRemoteDir(const KURL &dest)
+{
+ do
+ {
+ if (NETACCESS::exists(dest, false, kapp->mainWidget()))
+ return true;
+
+ if (NETACCESS::mkdir(dest, kapp->mainWidget(), 0755))
+ return true;
+
+#if KDE_IS_VERSION(3,2,91)
+ if (NETACCESS::lastError() == KIO::ERR_DIR_ALREADY_EXIST)
+ return true;
+#endif
+
+ //TODO Check directory already exists error
+ QString error = NETACCESS::lastErrorString();
+ QString msg;
+
+ if (error.isEmpty())
+ msg = i18n("<qt>The directory <b>%1</b> could not be created because of an unspecified problem.<p>")
+ .arg(dest.prettyURL());
+ else
+ msg = i18n("<qt>The directory <b>%1</b> could not be created because of the following problem:"
+ "<p>%2<p>")
+ .arg(dest.prettyURL(), NETACCESS::lastErrorString());
+
+ msg += i18n("Without this directory your files can not be uploaded.<p>"
+ "Do you want to retry creating the directory or abort uploading?</qt>");
+
+ int msgResult = KMessageBox::warningYesNo(kapp->mainWidget(), msg, QString::null,
+ i18n("&Retry"), i18n("&Abort"));
+
+ if (msgResult == KMessageBox::No)
+ return false;
+ }
+ while (true);
+ return false;
+}
+
+// Install file
+bool
+KioskRun::install(const QString &file, const QString &destination)
+{
+ KURL dest;
+ if (!m_isRoot || (m_user != "root"))
+ {
+ dest.setProtocol("fish");
+ dest.setHost("localhost");
+ dest.setUser(m_user);
+ }
+ dest.setPath(destination);
+
+ if (!createDir(dest.upURL().path()))
+ return false;
+
+ do
+ {
+ KURL src;
+ src.setPath(file);
+ bool result = NETACCESS::file_copy(src, dest, 0644, true, false, kapp->mainWidget());
+ if (result == true)
+ {
+ ::unlink(QFile::encodeName(file));
+ return true;
+ }
+
+ QString error = NETACCESS::lastErrorString();
+ QString msg;
+ if (error.isEmpty())
+ msg = i18n("<qt>The file <b>%1</b> could not be installed because of an unspecified problem.")
+ .arg(destination);
+ else
+ msg = i18n("<qt>The file <b>%1</b> could not be installed because of the following problem:"
+ "<p>%2<p>")
+ .arg(destination, NETACCESS::lastErrorString());
+
+ msg += i18n("Do you want to retry the installation or abort the saving of changes?</qt>");
+
+ int msgResult = KMessageBox::warningYesNo(kapp->mainWidget(), msg, QString::null,
+ i18n("&Retry"), i18n("&Abort"));
+
+ if (msgResult == KMessageBox::No)
+ return false;
+ }
+ while (true);
+ return false;
+}
+
+// Upload file
+bool
+KioskRun::uploadRemote(const QString &file, const KURL &dest)
+{
+ do
+ {
+ KURL src;
+ src.setPath(file);
+ bool result = NETACCESS::file_copy(src, dest, 0644, true, false, kapp->mainWidget());
+ if (result == true)
+ return true;
+
+ QString error = NETACCESS::lastErrorString();
+ QString msg;
+ if (error.isEmpty())
+ msg = i18n("<qt>The file <b>%1</b> could not be uploaded to <b>%2</b> because of an unspecified problem.")
+ .arg(file, dest.prettyURL());
+ else
+ msg = i18n("<qt>The file <b>%1</b> could not be uploaded to <b>%2</b> because of the following problem:"
+ "<p>%3<p>")
+ .arg(file, dest.prettyURL(),NETACCESS::lastErrorString());
+
+ msg += i18n("Do you want to retry or abort the uploading?</qt>");
+
+ int msgResult = KMessageBox::warningYesNo(kapp->mainWidget(), msg, QString::null,
+ i18n("&Retry"), i18n("&Abort"));
+
+ if (msgResult == KMessageBox::No)
+ return false;
+ }
+ while (true);
+ return false;
+}
+
+// Remove file
+bool
+KioskRun::remove(const QString &destination)
+{
+ KURL dest;
+ if (!m_isRoot || (m_user != "root"))
+ {
+ dest.setProtocol("fish");
+ dest.setHost("localhost");
+ dest.setUser(m_user);
+ }
+ dest.setPath(destination);
+
+ return NETACCESS::del(dest, kapp->mainWidget());
+}
+
+// Move file or directory
+bool
+KioskRun::move(const QString &source, const QString &destination, const QStringList &files)
+{
+ KURL src;
+ KURL dest;
+ if (!m_isRoot || (m_user != "root"))
+ {
+ dest.setProtocol("fish");
+ dest.setHost("localhost");
+ dest.setUser(m_user);
+ src.setProtocol("fish");
+ src.setHost("localhost");
+ src.setUser(m_user);
+ }
+
+ for(QStringList::ConstIterator it = files.begin();
+ it != files.end(); ++it)
+ {
+ src.setPath(source + *it);
+ dest.setPath(destination + *it);
+
+kdDebug() << "Moving " << src << " --> " << dest << endl;
+ if (!createRemoteDirRecursive(dest.upURL(), false))
+ return false;
+
+ if (!NETACCESS::file_move(src, dest, -1, true, false, kapp->mainWidget()))
+ {
+ // TODO add error message + retry
+ return false;
+ }
+ }
+ return true;
+}
+
+// Read information of profile @p profile
+void
+KioskRun::getProfileInfo(const QString &profile, QString &description, QString &installDir, QString &installUser)
+{
+ KConfig *config = kapp->config();
+
+ QString defaultInstallDir = getProfilePrefix();
+ if (defaultInstallDir.isEmpty())
+ {
+ defaultInstallDir = "/etc/kde-profile/";
+ }
+ if (!defaultInstallDir.endsWith("/"))
+ defaultInstallDir.append("/");
+ QString tmp = profile;
+ tmp.replace(" ", "_");
+ tmp.replace(":", "_");
+ tmp.replace("/", "_");
+ defaultInstallDir += tmp+"/";
+
+ QString group = QString("Directories-%1").arg(profile);
+ config->setGroup(group);
+
+ installDir = config->readEntry("prefixes", defaultInstallDir);
+ if (!installDir.endsWith("/"))
+ installDir.append("/");
+
+ QString profileInfoFile = installDir + ".kdeprofile";
+ if (QFile::exists(profileInfoFile))
+ {
+ KSimpleConfig profileInfo(profileInfoFile, true);
+ description = profileInfo.readEntry("Description");
+ installUser = profileInfo.readEntry("InstallUser", "root");
+ return;
+ }
+
+ QString defaultDescription;
+ if (profile == "default")
+ defaultDescription = i18n("Default profile");
+
+ description = config->readEntry("ProfileDescription", defaultDescription);
+ installUser = config->readEntry("ProfileInstallUser", "root");
+}
+
+KSimpleConfig *
+KioskRun::openKderc()
+{
+ if (m_localKdercConfig)
+ return m_localKdercConfig;
+
+ KURL settingsUrl;
+ settingsUrl.setPath(m_kderc);
+
+ m_localKderc = ::locateLocal("tmp", "kderc_"+kapp->randomString(5));
+ ::unlink(QFile::encodeName(m_localKderc));
+
+ KURL localCopyUrl;
+ localCopyUrl.setPath(m_localKderc);
+
+ if (QFile::exists(settingsUrl.path()))
+ {
+
+ while (!NETACCESS::copy(settingsUrl, localCopyUrl, kapp->mainWidget()))
+ {
+ QString error = NETACCESS::lastErrorString();
+ QString msg;
+ if (error.isEmpty())
+ msg = i18n("<qt>The file <b>%1</b> could not be accessed because of an unspecified problem.")
+ .arg(settingsUrl.path());
+ else
+ msg = i18n("<qt>The file <b>%1</b> could not be accessed because of the following problem:"
+ "<p>%2<p>")
+ .arg(settingsUrl.path(), error);
+
+ msg += i18n("Do you want to retry the operation or abort the saving of changes?</qt>");
+
+ int msgResult = KMessageBox::warningYesNo(kapp->mainWidget(), msg, QString::null,
+ i18n("&Retry"), i18n("&Abort"));
+
+ if (msgResult == KMessageBox::No)
+ return 0;
+ }
+ }
+
+ m_localKdercConfig = new KSimpleConfig(m_localKderc);
+ return m_localKdercConfig;
+}
+
+bool
+KioskRun::closeKderc()
+{
+ if (!m_localKdercConfig)
+ return false;
+ m_localKdercConfig->sync();
+ delete m_localKdercConfig;
+ m_localKdercConfig = 0;
+
+ QString saveUser = m_user;
+ m_user = "root";
+ bool result = install(m_localKderc, m_kderc);
+ m_localKderc = QString::null;
+ m_user = saveUser;
+ kapp->config()->reparseConfiguration();
+ return result;
+}
+
+// Store information for profile @p profile
+bool
+KioskRun::setProfileInfo(const QString &profile, const QString &description, const QString &_installDir, const QString &installUser, bool deleteProfile, bool deleteFiles)
+{
+ QString installDir = _installDir;
+ if (!installDir.endsWith("/"))
+ installDir.append("/");
+
+ QString saveProfileInfo = installDir + ".kdeprofile";
+ KSimpleConfig profileInfo(saveProfileInfo, true);
+ QString oldDescription = profileInfo.readEntry("Description");
+ QString oldInstallUser = profileInfo.readEntry("InstallUser");
+ if (deleteProfile && !installDir.isEmpty())
+ {
+ bool result = true;
+ KioskSync profileDir(kapp->mainWidget());
+ profileDir.addDir(installDir, KURL());
+ QStringList allFiles = profileDir.listFiles();
+ allFiles.remove(".kdeprofile");
+ if (allFiles.isEmpty())
+ {
+ if (QDir(installDir).exists())
+ {
+ m_user = installUser;
+ remove(installDir);
+ m_user = QString::null;
+ }
+ }
+ else if (deleteFiles)
+ {
+ int msgResult = KMessageBox::warningYesNoCancelList(kapp->mainWidget(),
+ i18n("<qt>The profile directory <b>%1</b> contains the following files, "
+ "do you wish to delete these files?").arg(installDir),
+ allFiles,
+ i18n("Deleting Profile"),
+#if KDE_IS_VERSION(3,2,91)
+ KStdGuiItem::del(),
+#else
+ i18n("&Delete"),
+#endif
+ i18n("&Keep Files")
+ );
+ switch(msgResult)
+ {
+ case KMessageBox::Yes:
+ // Delete files
+ m_user = installUser;
+ result = remove(installDir);
+ m_user = QString::null;
+ if (!result)
+ return false;
+ break;
+
+ case KMessageBox::No:
+ // Keep files
+ break;
+
+ default:
+ // Cancel
+ return false;
+ }
+ }
+
+ m_user = installUser;
+ if (QFile::exists(saveProfileInfo))
+ result = remove(saveProfileInfo);
+ m_user = QString::null;
+ if (!result)
+ return false;
+ }
+ else if ((description != oldDescription) ||
+ (installUser != oldInstallUser))
+ {
+ QString localProfileInfo = ::locateLocal("tmp", "kdeprofile_"+kapp->randomString(5));
+ ::unlink(QFile::encodeName(localProfileInfo));
+ KSimpleConfig newProfileInfo(localProfileInfo);
+ newProfileInfo.writeEntry("Description", description);
+ newProfileInfo.writeEntry("InstallUser", installUser);
+ newProfileInfo.sync();
+ bool result = install(localProfileInfo, saveProfileInfo);
+ if (!result)
+ return false;
+ }
+
+ KUser thisUser;
+ QString newAdmin = thisUser.loginName()+":"; // This user, all hosts
+
+ KConfig *config = kapp->config();
+
+ config->setGroup("Directories");
+ QString oldAdmin = config->readEntry("kioskAdmin");
+
+ QString group = QString("Directories-%1").arg(profile);
+ config->setGroup(group);
+
+ if ((installDir == config->readEntry("prefixes")) &&
+ (newAdmin == oldAdmin) &&
+ !deleteProfile)
+ return true; // Nothing to do
+
+ KSimpleConfig *cfg = openKderc();
+ if (!cfg)
+ return false;
+
+ cfg->setGroup("Directories");
+ cfg->writeEntry("kioskAdmin", newAdmin);
+
+ if (deleteProfile)
+ {
+ cfg->deleteGroup(group);
+ }
+ else
+ {
+ cfg->setGroup(group);
+ // TODO: update prefixes
+ cfg->writeEntry("prefixes", installDir);
+ }
+ cfg->sync();
+
+ return closeKderc();
+}
+
+bool
+KioskRun::deleteProfile(const QString &profile, bool deleteFiles)
+{
+ QString description;
+ QString installDir;
+ QString installUser;
+ getProfileInfo(profile, description, installDir, installUser);
+ return setProfileInfo(profile, description, installDir, installUser, true, deleteFiles);
+}
+
+// Read profile prefix
+QString
+KioskRun::getProfilePrefix()
+{
+ KConfig *config = kapp->config();
+
+ config->setGroup("Directories");
+
+ QString prefix = config->readEntry("profileDirsPrefix");
+ if (!prefix.isEmpty() && !prefix.endsWith("/"))
+ prefix.append('/');
+ return prefix;
+}
+
+// Store profile prefix
+bool
+KioskRun::setProfilePrefix(const QString &_prefix)
+{
+ QString prefix = _prefix;
+
+ if (!prefix.isEmpty() && !prefix.endsWith("/"))
+ prefix.append('/');
+
+ if (prefix == getProfilePrefix())
+ return true; // Nothing to do
+
+ KSimpleConfig *cfg = openKderc();
+ if (!cfg)
+ return false;
+
+ cfg->setGroup("Directories");
+ cfg->writeEntry("profileDirsPrefix", prefix);
+
+ cfg->sync();
+
+ return closeKderc();
+}
+
+QString
+KioskRun::newProfile()
+{
+ QString profilePrefix = getProfilePrefix();
+
+ KConfig *config = kapp->config();
+ for(int p = 1; p; p++)
+ {
+ QString profile = QString("profile%1").arg(p);
+ QString group = QString("Directories-%1").arg(profile);
+ if (!config->hasGroup(group))
+ {
+ if (profilePrefix.isEmpty())
+ return profile;
+
+ QString profileDir = profilePrefix + profile;
+ if (!QDir(profileDir).exists() && !QFile::exists(profileDir))
+ return profile;
+
+ // Keep on looking...
+ }
+ }
+ return QString::null;
+}
+
+QStringList
+KioskRun::allProfiles()
+{
+ KConfig *config = kapp->config();
+ QStringList groups = config->groupList();
+ QStringList profiles;
+ QStringList directories;
+ for(QStringList::ConstIterator it = groups.begin();
+ it != groups.end(); ++it)
+ {
+ if (!(*it).startsWith("Directories-"))
+ continue;
+ profiles.append((*it).mid(12));
+ config->setGroup(*it);
+ QString installDir = config->readEntry("prefixes");
+ if (!installDir.endsWith("/"))
+ installDir.append("/");
+ directories.append(installDir);
+ }
+
+ QString profilePrefix = getProfilePrefix();
+ if (!profilePrefix.isEmpty())
+ {
+ QDir dir(profilePrefix, QString::null, QDir::Unsorted, QDir::Dirs);
+ QStringList profileDirs = dir.entryList();
+ for(QStringList::ConstIterator it = profileDirs.begin();
+ it != profileDirs.end(); ++it)
+ {
+ if ((*it).startsWith("."))
+ continue;
+ QString dir = profilePrefix + *it + "/";
+ if (directories.contains(dir))
+ {
+ kdDebug() << "Skipping " << dir << ", dir already listed" << endl;
+ continue;
+ }
+ if (profiles.contains(*it))
+ {
+ kdDebug() << "Skipping " << dir << ", profile [" << (*it) << "] already listed" << endl;
+ continue;
+ }
+
+ if (!QFile::exists(dir+".kdeprofile"))
+ {
+ kdDebug() << "Skipping " << dir << ", no profile info" << endl;
+ continue;
+ }
+ profiles.append(*it);
+ directories.append(dir);
+ }
+ }
+
+ if (!profiles.contains("default"))
+ profiles.append("default");
+
+ return profiles;
+}
+
+void
+KioskRun::getUserProfileMappings( ProfileMapping &groups, ProfileMapping &users, QStringList &groupOrder)
+{
+ groups.clear();
+ users.clear();
+
+ KConfig *config = kapp->config();
+ config->setGroup("Directories");
+ QString mapFile = config->readEntry("userProfileMapFile");
+
+ if (mapFile.isEmpty() || !QFile::exists(mapFile))
+ return;
+
+ KSimpleConfig mapCfg(mapFile, true);
+
+ mapCfg.setGroup("General");
+ groupOrder = mapCfg.readListEntry("groups");
+
+ mapCfg.setGroup("Groups");
+ for ( QStringList::ConstIterator it = groupOrder.begin();
+ it != groupOrder.end(); ++it )
+ {
+ QString group = *it;
+ QStringList profiles = mapCfg.readListEntry(group);
+ if (!profiles.isEmpty())
+ groups.insert(group, profiles);
+ }
+
+ QMap<QString, QString> cfg_users = mapCfg.entryMap("Users");
+ for ( QMap<QString, QString>::Iterator it = cfg_users.begin();
+ it != cfg_users.end(); ++it )
+ {
+ QString user = it.key();
+ QStringList profiles = QStringList::split(",", it.data());
+ if (!profiles.isEmpty())
+ users.insert(user, profiles);
+ }
+}
+
+bool
+KioskRun::setUserProfileMappings( const ProfileMapping &groups, const ProfileMapping &users, const QStringList &groupOrder)
+{
+ KConfig *config = kapp->config();
+ config->setGroup("Directories");
+ QString mapFile = config->readEntry("userProfileMapFile");
+ if (mapFile.isEmpty())
+ {
+ mapFile = "/etc/kde-user-profile";
+
+ KSimpleConfig *cfg = openKderc();
+ if (!cfg)
+ return false;
+
+ cfg->setGroup("Directories");
+ cfg->writeEntry("userProfileMapFile", mapFile);
+ if (!closeKderc())
+ return false;
+ }
+
+ QString localMapFile = ::locateLocal("tmp", "kde-user-profile_"+kapp->randomString(5));
+ ::unlink(QFile::encodeName(localMapFile));
+
+ KSimpleConfig mapConfig(localMapFile);
+
+ mapConfig.setGroup("General");
+ mapConfig.writeEntry("groups", groupOrder);
+
+ KioskRun::ProfileMapping::ConstIterator it;
+
+ mapConfig.setGroup("Groups");
+ for ( it = groups.begin(); it != groups.end(); ++it )
+ {
+ QString group = it.key();
+ mapConfig.writeEntry(group, it.data());
+ }
+ mapConfig.setGroup("Users");
+ for ( it = users.begin(); it != users.end(); ++it )
+ {
+ QString user = it.key();
+ mapConfig.writeEntry(user, it.data());
+ }
+
+ mapConfig.sync();
+
+ QString saveUser = m_user;
+ m_user = "root";
+ bool result = install(localMapFile, mapFile);
+ m_user = saveUser;
+ return result;
+}
+
+void
+KioskRun::forceSycocaUpdate()
+{
+ // Touch $KDEDIR/share/services/update_ksycoca
+ KTempFile tempFile;
+ tempFile.close();
+ QString sycocaUpdateFile = locateSave("services", "update_ksycoca");
+ remove(sycocaUpdateFile);
+ install(tempFile.name(), sycocaUpdateFile);
+}
+
+void
+KioskRun::scheduleSycocaUpdate()
+{
+ m_forceSycocaUpdate = true;
+}
+
+void
+KioskRun::setCustomRestrictionFileBrowsing(bool restrict)
+{
+ QString file = "kdeglobals";
+ QString group = "KDE URL Restrictions";
+ KConfig *cfg = KioskRun::self()->configFile(file);
+ cfg->setGroup(group);
+ int count = cfg->readNumEntry("rule_count");
+ QStringList urlRestrictions;
+ for(int i = 0; i < count; i++)
+ {
+ QString key = QString("rule_%1").arg(i+1);
+ if (cfg->hasKey(key))
+ urlRestrictions.append(cfg->readEntry(key));
+ }
+
+ QStringList newRestrictions;
+ newRestrictions << "list,,,,file,,,false";
+ newRestrictions << "list,,,,file,,$HOME,true";
+
+ for(QStringList::ConstIterator it = newRestrictions.begin();
+ it != newRestrictions.end(); ++it)
+ {
+ urlRestrictions.remove(*it);
+ }
+
+ if (restrict)
+ {
+ newRestrictions += urlRestrictions;
+ urlRestrictions = newRestrictions;
+ }
+
+ count = urlRestrictions.count();
+ cfg->writeEntry("rule_count", count);
+
+ for(int i = 0; i < count; i++)
+ {
+ QString key = QString("rule_%1").arg(i+1);
+ cfg->writeEntry(key, urlRestrictions[i]);
+ }
+ KioskRun::self()->setConfigImmutable(file, group, true);
+}
+
+KioskRunProgressDialog::KioskRunProgressDialog(QWidget *parent, const char *name,
+ const QString &caption, const QString &text)
+ : KProgressDialog(parent, name, caption, text, true)
+{
+ connect(&m_timer, SIGNAL(timeout()), this, SLOT(slotProgress()));
+ progressBar()->setTotalSteps(20);
+ m_timeStep = 700;
+ m_timer.start(m_timeStep);
+ setAutoClose(false);
+}
+
+void
+KioskRunProgressDialog::slotProgress()
+{
+ int p = progressBar()->progress();
+ if (p == 18)
+ {
+ progressBar()->reset();
+ progressBar()->setProgress(1);
+ m_timeStep = m_timeStep * 2;
+ m_timer.start(m_timeStep);
+ }
+ else
+ {
+ progressBar()->setProgress(p+1);
+ }
+}
+
+void
+KioskRunProgressDialog::slotFinished()
+{
+ progressBar()->setProgress(20);
+ m_timer.stop();
+ QTimer::singleShot(1000, this, SLOT(close()));
+}
+
+
+#include "kioskrun.moc"
+
diff --git a/kiosktool/kioskrun.h b/kiosktool/kioskrun.h
new file mode 100644
index 0000000..c4cb8f8
--- /dev/null
+++ b/kiosktool/kioskrun.h
@@ -0,0 +1,229 @@
+/*
+ * kioskrun.h
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _KIOSKRUN_H_
+#define _KIOSKRUN_H_
+
+#include <qdict.h>
+#include <qobject.h>
+#include <qregexp.h>
+#include <qstringlist.h>
+#include <qtimer.h>
+
+#include <dcopclient.h>
+#include <dcopref.h>
+
+#include <kprogress.h>
+
+class ImmutableStatus;
+class KConfig;
+class KProcess;
+class KSimpleConfig;
+
+class KioskGui;
+
+class KioskRun : public QObject
+{
+ friend class KioskGui;
+
+ Q_OBJECT
+public:
+ static KioskRun* self() { return s_self; }
+
+ void setKdeDirs(const QStringList &dirs);
+ void setUser(const QString &user);
+
+ QString homeDir() { return m_homeDir; }
+ QStringList kdeDirs() { return m_kdeDirs; }
+ QString desktopPath() { return m_desktopPath; }
+
+ // Locate existing anywhere
+ QString locate(const char *resource, const QString &filename=QString::null);
+
+ // Locate for saving
+ QString locateSave(const char *resource, const QString &filename=QString::null);
+
+ // Locate for reading saved changed
+ QString locateLocal(const char *resource, const QString &filename=QString::null);
+
+ // Prepare runtime environment for run()
+ bool prepare();
+
+ // Update sycoca database in runtime environment
+ void updateSycoca();
+
+ // Request sycoca update in install environment after flushing config files
+ void scheduleSycocaUpdate();
+
+ // Request sycoca update in install environment
+ void forceSycocaUpdate();
+
+ // Run a program inside the runtime test environment
+ KProcess* run(const QString &cmd, const QStringList &args=QStringList());
+
+ // A DCOPRef to make dcop calls into the runtime test environment
+ DCOPRef dcopRef(const QCString &appId, const QCString &objId);
+
+ // A DCOPClient to make dcop calls into the runtime test environment
+ DCOPClient *dcopClient() { return m_dcopClient; }
+
+ // Open config file in the install directory
+ KConfig *configFile(const QString &filename);
+
+ // Make config files temporary mutable.
+ void makeMutable(bool bMutable);
+
+ // Returns whether specific config group is immutable,
+ // or entire file if group is empty
+ bool isConfigImmutable(const QString &filename, const QString &group);
+
+ // Make specific config group immutable,
+ // or entire file if group is empty
+ void setConfigImmutable(const QString &filename, const QString &group, bool bImmutable);
+
+ // Close all opened config files.
+ bool flushConfigCache();
+
+ // Return all config files created by the user
+ QStringList newConfigFiles();
+
+ // Merge new settings from the test directory into the installation directory
+ void mergeConfigFile(const QString &filename);
+
+ // Lookup the setting for a custom action
+ bool lookupCustomAction(const QString &action);
+
+ // Change the setting for a custom action
+ void setCustomAction(const QString &action, bool checked);
+
+ // Create installation directory and its parent dirs
+ bool createDir(const QString &dir);
+
+ // Install file
+ bool install(const QString &file, const QString &destination);
+
+ // Delete file
+ bool remove(const QString &destination);
+
+ // Move file or directory
+ bool move(const QString &source, const QString &destination, const QStringList &files);
+
+ // Delete directory in test home dir
+ void deleteDir(const QString &);
+
+ // Open /etc/kderc for writing
+ KSimpleConfig *openKderc();
+
+ // Install new /etc/kderc
+ bool closeKderc();
+
+ // Read information of profile @p profile
+ void getProfileInfo(const QString &profile, QString &description, QString &installDir, QString &installUser);
+
+ // Store information for profile @p profile
+ bool setProfileInfo(const QString &profile, const QString &description, const QString &installDir, const QString &installUser, bool b=false, bool deleteFiles=true);
+
+ // Get new, non-existing, profile name
+ QString newProfile();
+
+ // Delete profile @p profile
+ bool deleteProfile(const QString &profile, bool deleteFiles = true);
+
+ // Get list of all existing profiles
+ QStringList allProfiles();
+
+ // Maps a single group or user to a one or more profiles
+ typedef QMap<QString,QStringList> ProfileMapping;
+
+ // Read mappings between groups/users and profiles
+ void getUserProfileMappings( ProfileMapping &groups, ProfileMapping &users, QStringList &groupOrder);
+
+ // Store mappings between groups/users and profiles
+ bool setUserProfileMappings( const ProfileMapping &groups, const ProfileMapping &users, const QStringList &groupOrder);
+
+ // Read profile prefix
+ QString getProfilePrefix();
+
+ // Store profile prefix
+ bool setProfilePrefix(const QString &prefix);
+
+ // Create upload directory
+ bool createRemoteDir(const KURL &dir);
+
+ // Create upload directory and all its parent dirs and be polite if ask = true
+ bool createRemoteDirRecursive(const KURL &dir, bool ask);
+
+ // Upload file
+ bool uploadRemote(const QString &file, const KURL &dest);
+
+protected:
+ KioskRun( QObject* parent = 0, const char* name = 0);
+ ~KioskRun();
+
+ bool setupRuntimeEnv();
+ void shutdownRuntimeEnv();
+ void setupConfigEnv();
+ void shutdownConfigEnv();
+ void applyEnvironment(KProcess *p);
+
+ QString saveImmutableStatus(const QString &filename);
+ bool restoreImmutableStatus(const QString &filename, bool force);
+
+ void setCustomRestrictionFileBrowsing(bool restrict);
+
+private:
+ static KioskRun* s_self;
+ QString m_homeDir;
+ QString m_configDir;
+ QString m_desktopPath;
+ QString m_user;
+ QStringList m_kdeDirs;
+ QStringList m_xdgDataDirs;
+ QStringList m_xdgConfigDirs;
+ DCOPClient *m_dcopClient;
+ KInstance *m_instance;
+ KInstance *m_saveInstance;
+ QDict<KConfig> m_saveConfigCache;
+ QDict<ImmutableStatus> m_immutableStatusCache;
+ bool m_noRestrictions;
+ bool m_forceSycocaUpdate;
+ bool m_isRoot;
+
+ QString m_kderc;
+ QString m_localKderc;
+ KSimpleConfig *m_localKdercConfig;
+};
+
+
+class KioskRunProgressDialog : public KProgressDialog
+{
+ Q_OBJECT
+public:
+ KioskRunProgressDialog(QWidget *parent, const char *name,
+ const QString &caption, const QString &text);
+public slots:
+ void slotProgress();
+ void slotFinished();
+
+private:
+ QTimer m_timer;
+ int m_timeStep;
+};
+
+
+#endif
diff --git a/kiosktool/kiosksync.cpp b/kiosktool/kiosksync.cpp
new file mode 100644
index 0000000..34f9df9
--- /dev/null
+++ b/kiosktool/kiosksync.cpp
@@ -0,0 +1,211 @@
+/*
+ * kiosksync.cpp
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 "kiosksync.h"
+
+#include <qdir.h>
+#include <qwidget.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <ksimpleconfig.h>
+#include <kstandarddirs.h>
+
+KioskSync::KioskSync( QWidget* parent, const char* name)
+ : QObject(parent, name),
+ m_parent(parent)
+{
+}
+
+KioskSync::~KioskSync()
+{
+}
+
+void
+KioskSync::addDir(const QString &_src, const KURL &dest)
+{
+ QString src = _src;
+ if (!src.endsWith("/"))
+ src.append("/");
+
+ m_syncDirs.append(SyncDir(src, dest));
+}
+
+bool
+KioskSync::sync(bool incremental)
+{
+ m_incremental = incremental;
+ m_timestamps = new KSimpleConfig(locateLocal("appdata", "profile-data"));
+
+ bool canceled = false;
+
+ for(SyncDirList::ConstIterator it = m_syncDirs.begin();
+ it != m_syncDirs.end(); ++it)
+ {
+ m_changedFiles.clear();
+ m_changedDirs.clear();
+
+ m_timestamps->setGroup((*it).src);
+
+ if (!KioskRun::self()->createRemoteDirRecursive((*it).dest, true))
+ {
+ canceled = true;
+ break;
+ }
+
+ scanChangedFiles((*it).src, QString::null);
+
+ for(QStringList::ConstIterator it2 = m_changedDirs.begin();
+ it2 != m_changedDirs.end(); ++it2)
+ {
+ KURL dest = (*it).dest;
+ dest.setPath(dest.path(1) + *it2);
+ if (!KioskRun::self()->createRemoteDir(dest))
+ {
+ canceled = true;
+ break;
+ }
+ }
+
+ if (canceled)
+ break;
+
+ for(QStringList::ConstIterator it2 = m_changedFiles.begin();
+ it2 != m_changedFiles.end(); ++it2)
+ {
+ KURL dest = (*it).dest;
+ dest.setPath(dest.path(1) + *it2);
+ if (!syncFile((*it).src, *it2, dest))
+ {
+ canceled = true;
+ break;
+ }
+ }
+ if (canceled)
+ break;
+ }
+ delete m_timestamps;
+ m_changedFiles.clear();
+ m_changedDirs.clear();
+
+ return !canceled;
+}
+
+QStringList
+KioskSync::listFiles()
+{
+ m_changedFiles.clear();
+ m_changedDirs.clear();
+ m_incremental = false;
+ m_timestamps = 0;
+
+ for(SyncDirList::ConstIterator it = m_syncDirs.begin();
+ it != m_syncDirs.end(); ++it)
+ {
+ scanChangedFiles((*it).src, QString::null);
+ }
+ return m_changedFiles;
+}
+
+void
+KioskSync::addChangedDir(const QString &dir)
+{
+ if (dir.isEmpty())
+ return;
+
+ if (m_changedDirs.contains(dir))
+ return;
+
+ int i = dir.findRev('/', -2);
+ if (i != -1)
+ {
+ QString parentDir = dir.left(i+1);
+ addChangedDir(parentDir);
+ }
+
+ kdDebug() << "KioskSync: Adding " << dir << endl;
+ m_changedDirs.append(dir);
+}
+
+void
+KioskSync::scanChangedFiles(const QString &_dir, const QString &prefix)
+{
+ kdDebug() << "KioskSync: Scanning " << _dir << endl;
+ QDir dir(_dir);
+ if (!dir.exists())
+ {
+ emit warning(i18n("Directory <b>%1</b> does not exist.").arg(_dir));
+ return;
+ }
+ if (!dir.isReadable())
+ {
+ emit warning(i18n("Directory <b>%1</b> is not readable.").arg(_dir));
+ return;
+ }
+
+ QStringList subDirs;
+ const QFileInfoList *list = dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoSymLinks);
+
+ bool dirtyDir = false;
+ QFileInfoListIterator it( *list );
+ for ( QFileInfo *fi; (fi = it.current()) != 0; ++it)
+ {
+ if (fi->isDir())
+ {
+ QString subDir = fi->fileName();
+ if ((subDir != ".") && (subDir != ".."))
+ subDirs.append(subDir+"/");
+ continue;
+ }
+
+ // TODO: Check file
+ QString file = prefix + fi->fileName();
+ QDateTime lastModified = fi->lastModified();
+ if (!m_incremental || !m_timestamps->hasKey(file) ||
+ (m_timestamps->readDateTimeEntry(file) != lastModified))
+ {
+ dirtyDir = true;
+ m_changedFiles.append(file);
+ }
+ }
+ if (dirtyDir)
+ addChangedDir(prefix);
+
+ for( QStringList::ConstIterator it = subDirs.begin();
+ it != subDirs.end(); ++it)
+ {
+ QString subDir = *it;
+ scanChangedFiles(_dir + subDir, prefix + subDir);
+ }
+}
+
+bool
+KioskSync::syncFile(const QString &prefix, const QString &file, const KURL &dest)
+{
+ kdDebug() << "KioskSync: Syncing [" << prefix << "]" << file << " --> " << dest.prettyURL() << endl;
+
+ if (!KioskRun::self()->uploadRemote(prefix+file, dest))
+ return false;
+
+ QFileInfo fi(prefix+file);
+ m_timestamps->writeEntry(file, fi.lastModified());
+ return true;
+}
+
+#include "kiosksync.moc"
diff --git a/kiosktool/kiosksync.h b/kiosktool/kiosksync.h
new file mode 100644
index 0000000..ffcc001
--- /dev/null
+++ b/kiosktool/kiosksync.h
@@ -0,0 +1,80 @@
+/*
+ * kiosksync.h
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _KIOSKSYNC_H_
+#define _KIOSKSYNC_H_
+
+#include <qobject.h>
+#include <qstringlist.h>
+
+#include <kurl.h>
+
+#include "kioskrun.h"
+
+class QWidget;
+class KSimpleConfig;
+
+class KioskSync : public QObject
+{
+ Q_OBJECT
+public:
+ KioskSync( QWidget* parent = 0, const char* name = 0);
+ ~KioskSync();
+
+ void addDir(const QString &src, const KURL &dest);
+ bool sync(bool incremental = false);
+ // Returns all files found in the directories
+ QStringList listFiles();
+
+signals:
+ void finished();
+ void status(const QString &);
+ void warning(const QString &);
+
+protected:
+ void scanChangedFiles(const QString &_dir, const QString &prefix);
+ bool syncFile(const QString &prefix, const QString &file, const KURL &dest);
+ void addChangedDir(const QString &dir);
+
+private:
+ struct SyncDir
+ {
+ SyncDir()
+ { }
+
+ SyncDir(const QString &_src, const KURL &_dest) : src(_src), dest(_dest)
+ { }
+
+ SyncDir(const SyncDir &dir) : src(dir.src), dest(dir.dest)
+ { }
+
+ QString src;
+ KURL dest;
+ };
+
+ typedef QValueList<SyncDir> SyncDirList;
+
+ SyncDirList m_syncDirs;
+ QWidget *m_parent;
+ KSimpleConfig *m_timestamps;
+ QStringList m_changedFiles;
+ QStringList m_changedDirs;
+ bool m_incremental;
+};
+
+#endif
diff --git a/kiosktool/kiosktool-kdedirs.cpp b/kiosktool/kiosktool-kdedirs.cpp
new file mode 100644
index 0000000..3aaa0b7
--- /dev/null
+++ b/kiosktool/kiosktool-kdedirs.cpp
@@ -0,0 +1,184 @@
+/*
+ * kiosktool-kdedirs.cpp
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License versin 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 <config.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include <qfile.h>
+
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kinstance.h>
+#include <kshell.h>
+#include <ksimpleconfig.h>
+#include <kstandarddirs.h>
+
+static const char *description = I18N_NOOP("A tool to set $KDEDIRS according to the current user profile.");
+
+
+static QString readEnvPath(const char *env)
+{
+ QCString c_path = getenv(env);
+ if (c_path.isEmpty())
+ return QString::null;
+ return QFile::decodeName(c_path);
+}
+
+static QStringList lookupProfiles(const QString &mapFile)
+{
+ QStringList profiles;
+
+ if (mapFile.isEmpty() || !QFile::exists(mapFile))
+ {
+ profiles << "default";
+ return profiles;
+ }
+
+ struct passwd *pw = getpwuid(geteuid());
+ if (!pw)
+ {
+ profiles << "default";
+ return profiles; // Not good
+ }
+
+ QCString user = pw->pw_name;
+
+ gid_t sup_gids[512];
+ int sup_gids_nr = getgroups(512, sup_gids);
+
+ KSimpleConfig mapCfg(mapFile, true);
+ mapCfg.setGroup("Users");
+ if (mapCfg.hasKey(user.data()))
+ {
+ profiles = mapCfg.readListEntry(user.data());
+ return profiles;
+ }
+
+ mapCfg.setGroup("General");
+ QStringList groups = mapCfg.readListEntry("groups");
+
+ mapCfg.setGroup("Groups");
+
+ for( QStringList::ConstIterator it = groups.begin();
+ it != groups.end(); ++it )
+ {
+ QCString grp = (*it).utf8();
+ // Check if user is in this group
+ struct group *grp_ent = getgrnam(grp);
+ if (!grp_ent) continue;
+ gid_t gid = grp_ent->gr_gid;
+ if (pw->pw_gid == gid)
+ {
+ // User is in this group --> add profiles
+ profiles += mapCfg.readListEntry(*it);
+ }
+ else
+ {
+ for(int i = 0; i < sup_gids_nr; i++)
+ {
+ if (sup_gids[i] == gid)
+ {
+ // User is in this group --> add profiles
+ profiles += mapCfg.readListEntry(*it);
+ break;
+ }
+ }
+ }
+ }
+
+ if (profiles.isEmpty())
+ profiles << "default";
+ return profiles;
+}
+
+static KCmdLineOptions options[] = {
+ { "check", I18N_NOOP("Output currently active prefixes"), 0 },
+ KCmdLineLastOption
+};
+
+int main(int argc, char **argv)
+{
+ KLocale::setMainCatalogue("kiosktool");
+ KAboutData about("kiosktool-kdedirs", "kiosktool-kdedirs", "1.0", description, KAboutData::License_GPL, "(C) 2004 Waldo Bastian");
+ KCmdLineArgs::init( argc, argv, &about);
+ KCmdLineArgs::addCmdLineOptions(options);
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ KInstance a("kiosktool-kdedirs");
+
+ if (args->isSet("check"))
+ {
+ (void) KGlobal::config(); // Force config file processing
+ QString dirs = KGlobal::dirs()->kfsstnd_prefixes();
+ printf("%s\n", QFile::encodeName(dirs).data());
+ return 0;
+ }
+
+ QStringList kdedirList;
+
+ // begin KDEDIRS
+ QString kdedirs = readEnvPath("KDEDIRS");
+ if (!kdedirs.isEmpty())
+ {
+ kdedirList = QStringList::split(":", kdedirs);
+ }
+ else
+ {
+ QString kdedir = readEnvPath("KDEDIR");
+ if (!kdedir.isEmpty())
+ {
+ kdedir = KShell::tildeExpand(kdedir);
+ kdedirList.append(kdedir);
+ }
+ }
+
+ KConfig *config = KGlobal::config();
+ config->setGroup("Directories");
+ QString userMapFile = config->readEntry("userProfileMapFile");
+ QString profileDirsPrefix = config->readEntry("profileDirsPrefix");
+ if (!profileDirsPrefix.isEmpty() && !profileDirsPrefix.endsWith("/"))
+ profileDirsPrefix.append('/');
+ QStringList profiles = lookupProfiles(userMapFile);
+
+ while(!profiles.isEmpty())
+ {
+ QString profile = profiles.back();
+ config->setGroup(QString::fromLatin1("Directories-%1").arg(profile));
+ profiles.pop_back();
+ QStringList list = config->readListEntry("prefixes");
+ for (QStringList::ConstIterator it = list.begin(); it != list.end(); it++)
+ {
+ kdedirList.prepend(*it);
+ }
+ if (list.isEmpty() && !profile.isEmpty() && !profileDirsPrefix.isEmpty())
+ {
+ kdedirList.prepend(profileDirsPrefix + profile);
+ }
+ }
+ printf("%s\n", QFile::encodeName(kdedirList.join(":")).data());
+
+ return 0;
+}
diff --git a/kiosktool/kiosktool.desktop b/kiosktool/kiosktool.desktop
new file mode 100644
index 0000000..66fd0b9
--- /dev/null
+++ b/kiosktool/kiosktool.desktop
@@ -0,0 +1,28 @@
+[Desktop Entry]
+Encoding=UTF-8
+Type=Application
+Exec=kiosktool
+Icon=kiosktool
+DocPath=kioskgui/index.html
+X-KDE-StartupNotify=true
+
+Name=Kiosk Admin Tool
+Name[bs]=Kiosk administratorski alat
+Name[da]=Kiosk Admin-værktøj
+Name[es]=Herramienta de administración de Quiosco
+Name[et]=Kioski haldur
+Name[fr]=Outil d'administration Kiosk
+Name[it]=Strumento di amministrazione Kiosk
+Name[nl]=Kiosk Administratieprogramma
+Name[pt]=Ferramenta de Administração do Quiosque
+Name[pt_BR]=Ferramenta de administração Kiosh
+Name[sr]=Kiosk, администраторски алат
+Name[sr@Latn]=Kiosk, administratorski alat
+Name[sv]=Kiosk-administreringsverktyg
+Name[ta]=Kiosk மேலாளர கருவி
+Name[tr]=Kiosk Yönetim Aracı
+Name[xx]=xxKiosk Admin Toolxx
+
+X-KDE-AuthorizeAction=user/root
+X-DCOP-ServiceType=None
+Categories=Qt;KDE;System;
diff --git a/kiosktool/kiosktoolui.rc b/kiosktool/kiosktoolui.rc
new file mode 100644
index 0000000..7ab96c6
--- /dev/null
+++ b/kiosktool/kiosktoolui.rc
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!DOCTYPE gui SYSTEM "kpartgui.dtd">
+<gui name="kioskgui" version="3">
+<MenuBar>
+ <Menu name="file">
+ <Action name="upload_all"/>
+ </Menu>
+ <Menu name="settings">
+ <Action name="show_background" append="show_merge"/>
+ </Menu>
+</MenuBar>
+</gui>
+
diff --git a/kiosktool/logo.png b/kiosktool/logo.png
new file mode 100644
index 0000000..f3163c0
--- /dev/null
+++ b/kiosktool/logo.png
Binary files differ
diff --git a/kiosktool/main.cpp b/kiosktool/main.cpp
new file mode 100644
index 0000000..c6c80df
--- /dev/null
+++ b/kiosktool/main.cpp
@@ -0,0 +1,80 @@
+/*
+ * main.cpp
+ *
+ * Copyright (C) 2003,2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License versin 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 "kioskgui.h"
+
+#include <dcopclient.h>
+
+#include <qfile.h>
+
+#include <kaboutdata.h>
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <kdeversion.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+
+static const char *description =
+ I18N_NOOP("KIOSK Admin Tool");
+
+static const char *version = "1.0";
+
+#ifndef KDERC
+#define KDERC "/etc/kderc"
+#endif
+
+static const KCmdLineOptions options[] =
+{
+ { "kderc <file>", I18N_NOOP("kderc file to save settings to"), KDERC },
+ KCmdLineLastOption
+};
+
+int main(int argc, char *argv[])
+{
+ KAboutData aboutData( "kiosktool", I18N_NOOP("KIOSK Admin Tool"),
+ version, description, KAboutData::License_GPL_V2,
+ "(c) 2003,2004 Waldo Bastian");
+ aboutData.addAuthor("Waldo Bastian",I18N_NOOP("Author"), "bastian@kde.org");
+
+ KCmdLineArgs::init(argc, argv, &aboutData);
+
+ KCmdLineArgs::addCmdLineOptions( options );
+
+ KApplication a;
+
+ KioskGui *w = new KioskGui();
+ a.setMainWidget(w);
+ w->show();
+
+ bool versionOk;
+ if (QFile::exists("/etc/SuSE-release"))
+ versionOk = KDE::version() >= KDE_MAKE_VERSION(3,2,1);
+ else
+ versionOk = KDE::version() >= KDE_MAKE_VERSION(3,2,2);
+
+ if (!versionOk)
+ {
+ KMessageBox::information(w, i18n("<qt>KIOSK Admin Tool requires KDE 3.2.2 or later!<p>"
+ "With older versions you may experience problems with"
+ "the <i>Setup</i> functionality of the various components."));
+ }
+
+ kapp->exec();
+
+ return 0;
+}
diff --git a/kiosktool/mainview.ui b/kiosktool/mainview.ui
new file mode 100644
index 0000000..cef0d4d
--- /dev/null
+++ b/kiosktool/mainview.ui
@@ -0,0 +1,258 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>MainView</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>MainView</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>573</width>
+ <height>526</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLabel" row="0" column="2" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>captionLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>70</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="2" colspan="2">
+ <property name="name">
+ <cstring>logoLabel</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>160</width>
+ <height>170</height>
+ </size>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="2">
+ <property name="name">
+ <cstring>subCaptionLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ </widget>
+ <spacer row="2" column="0">
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>25</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="2" column="4">
+ <property name="name">
+ <cstring>spacer5_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>25</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLayoutWidget" row="2" column="1" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QWidgetStack">
+ <property name="name">
+ <cstring>widgetStack</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>1</verstretch>
+ </sizepolicy>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WStackPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>0</number>
+ </attribute>
+ </widget>
+ </widget>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>frame3</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>pbHelp</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Help</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>pbDiscard</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Discard Changes</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>pbFinished</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Finished</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer row="1" column="3" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>160</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kiosktool/menueditComponent.cpp b/kiosktool/menueditComponent.cpp
new file mode 100644
index 0000000..83606c6
--- /dev/null
+++ b/kiosktool/menueditComponent.cpp
@@ -0,0 +1,241 @@
+/*
+ * menueditComponent.cpp
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 "menueditComponent.h"
+
+#include <qdir.h>
+#include <qdom.h>
+#include <qfileinfo.h>
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kmimetype.h>
+#include <kprocess.h>
+#include <ksavefile.h>
+#include <ksimpleconfig.h>
+#include <kstandarddirs.h>
+#include <kurl.h>
+
+#include "kioskrun.h"
+#include "kiosksync.h"
+
+MenuEditComponent::MenuEditComponent( QObject *parent)
+ : Component(parent)
+{
+}
+
+MenuEditComponent::~MenuEditComponent()
+{
+}
+
+void
+MenuEditComponent::slotSetupPrepare()
+{
+ (void) KioskRun::self()->locateLocal("xdgconf-menu", "applications-kmenuedit.menu"); // Create dir
+}
+
+void
+MenuEditComponent::slotSetupStarted()
+{
+}
+
+static QDomDocument loadDoc(const QString &fileName)
+{
+ QDomDocument doc;
+
+ QFile file( fileName );
+ if ( !file.open( IO_ReadOnly ) )
+ {
+ kdWarning() << "Could not open " << fileName << endl;
+ return doc;
+ }
+ QString errorMsg;
+ int errorRow;
+ int errorCol;
+ if ( !doc.setContent( &file, &errorMsg, &errorRow, &errorCol ) ) {
+ kdWarning() << "Parse error in " << fileName << ", line " << errorRow << ", col " << errorCol << ": " << errorMsg << endl;
+ file.close();
+ return doc;
+ }
+ file.close();
+ return doc;
+}
+
+static bool saveDoc(const QString &fileName, QDomDocument doc)
+{
+ KSaveFile saveFile(fileName);
+
+ QTextStream *stream = saveFile.textStream();
+ if (!stream)
+ {
+ kdWarning() << "Could not write " << fileName << endl;
+ return false;
+ }
+ (*stream) << doc.toString();
+
+ if (!saveFile.close())
+ {
+ kdWarning() << "Could not write " << fileName << endl;
+ return false;
+ }
+
+ return true;
+}
+
+
+bool
+MenuEditComponent::setupFinished()
+{
+ bool result;
+ QString menuEditFile = KioskRun::self()->locateLocal("xdgconf-menu", "applications-kmenuedit.menu");
+ QString menuFile = KioskRun::self()->locate("xdgconf-menu", "applications.menu");
+ QString menuFileSave = KioskRun::self()->locateSave("xdgconf-menu", "applications.menu");
+
+ kdDebug() << "MenuEditComponent: menuEditFile = " << menuEditFile << endl;
+ kdDebug() << "MenuEditComponent: menuFile = " << menuFile << endl;
+ kdDebug() << "MenuEditComponent: menuFileSave = " << menuFileSave << endl;
+
+ QDomDocument docChanges = loadDoc(menuEditFile);
+ if (docChanges.isNull())
+ {
+ kdDebug() << "No menu changes." << endl;
+ return true;
+ }
+
+ QDomDocument doc = loadDoc(menuFile);
+ if (doc.isNull())
+ {
+ kdWarning() << "Can't find menu file!" << endl;
+ return true;
+ }
+
+ QDomElement docElem = doc.documentElement();
+ QDomNode n = docElem.firstChild();
+ QDomNode next;
+ for(; !n.isNull(); n = next )
+ {
+ QDomElement e = n.toElement(); // try to convert the node to an element.
+ next = n.nextSibling();
+
+ if ((e.tagName() == "MergeFile") && (e.text() == "applications-kmenuedit.menu"))
+ break;
+ }
+ QDomNode insertionPoint = n;
+ if (insertionPoint.isNull())
+ {
+ kdWarning() << "Application menu fails to include applications-kmenuedit.menu" << endl;
+ return false;
+ }
+ QDomElement docChangesElem = docChanges.documentElement();
+ n = docChangesElem.firstChild();
+ for(; !n.isNull(); n = next )
+ {
+ QDomElement e = n.toElement(); // try to convert the node to an element.
+ next = n.nextSibling();
+
+ docElem.insertBefore(n, insertionPoint);
+ }
+
+ KTempFile tempFile;
+ tempFile.close();
+
+ saveDoc(tempFile.name(), doc);
+ result = KioskRun::self()->install(tempFile.name(), menuFileSave);
+ if (!result) return false;
+
+
+ // Install .desktop files
+ {
+ QString legacyApplications = KioskRun::self()->locateLocal("apps", QString::null);
+ QString legacySaveApplications = KioskRun::self()->locateSave("apps", QString::null);
+
+ KioskSync legacyDir(kapp->mainWidget());
+ legacyDir.addDir(legacyApplications, KURL());
+
+ QStringList newLegacyApplications = legacyDir.listFiles();
+
+ for(QStringList::ConstIterator it = newLegacyApplications.begin();
+ it != newLegacyApplications.end(); ++it)
+ {
+ if ((*it).endsWith(".desktop") || (*it).endsWith(".kdelnk") || (*it).endsWith(".directory"))
+ {
+ kdDebug() << "MenueditComponent: New legacy file %s" << (legacyApplications+(*it)) << endl;
+ result = KioskRun::self()->install(legacyApplications+(*it), legacySaveApplications+(*it));
+ if (!result) return false;
+ }
+ }
+ }
+
+ // Install .desktop files
+ {
+ QString xdgApplications = KioskRun::self()->locateLocal("xdgdata-apps", QString::null);
+ QString xdgSaveApplications = KioskRun::self()->locateSave("xdgdata-apps", QString::null);
+
+ QDir dir(xdgApplications);
+ QStringList newXdgApplications = dir.entryList(QDir::All, QDir::Unsorted);
+ newXdgApplications.remove(".");
+ newXdgApplications.remove("..");
+
+ for(QStringList::ConstIterator it = newXdgApplications.begin();
+ it != newXdgApplications.end(); ++it)
+ {
+ if ((*it).endsWith(".desktop") || (*it).endsWith(".kdelnk"))
+ {
+ kdDebug() << "MenueditComponent: New .desktop file %s" << (xdgApplications+(*it)) << endl;
+ result = KioskRun::self()->install(xdgApplications+(*it), xdgSaveApplications+(*it));
+ if (!result) return false;
+ }
+ }
+ }
+
+ // Install .directory files
+ {
+ QString xdgDirectories = KioskRun::self()->locateLocal("xdgdata-dirs", QString::null);
+ QString xdgSaveDirectories = KioskRun::self()->locateSave("xdgdata-dirs", QString::null);
+
+ QDir dir(xdgDirectories);
+ QStringList newXdgDirectories = dir.entryList(QDir::All, QDir::Unsorted);
+ newXdgDirectories.remove(".");
+ newXdgDirectories.remove("..");
+
+ for(QStringList::ConstIterator it = newXdgDirectories.begin();
+ it != newXdgDirectories.end(); ++it)
+ {
+ if ((*it).endsWith(".directory"))
+ {
+ kdDebug() << "MenueditComponent: New .directory file %s" << (xdgDirectories+(*it)) << endl;
+ result = KioskRun::self()->install(xdgDirectories+(*it), xdgSaveDirectories+(*it));
+ if (!result) return false;
+ }
+ }
+ }
+
+ KioskRun::self()->forceSycocaUpdate();
+
+ return true;
+}
+
+void
+MenuEditComponent::slotPreviewStarted()
+{
+ KioskRun::self()->dcopRef("kicker", "kicker").call("showKMenu");
+}
+
+
+#include "menueditComponent.moc"
diff --git a/kiosktool/menueditComponent.h b/kiosktool/menueditComponent.h
new file mode 100644
index 0000000..b1a86ab
--- /dev/null
+++ b/kiosktool/menueditComponent.h
@@ -0,0 +1,43 @@
+/*
+ * menueditComponent.h
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _MENUEDITCOMPONENT_H_
+#define _MENUEDITCOMPONENT_H_
+
+#include "component.h"
+
+#include <qstringlist.h>
+#include <qtimer.h>
+
+class MenuEditComponent: public Component
+{
+ Q_OBJECT
+public:
+ MenuEditComponent( QObject *parent = 0);
+ virtual ~MenuEditComponent();
+
+ virtual bool setupFinished();
+
+public slots:
+
+ virtual void slotSetupPrepare();
+ virtual void slotSetupStarted();
+ virtual void slotPreviewStarted();
+};
+
+#endif
diff --git a/kiosktool/pageWidget.cpp b/kiosktool/pageWidget.cpp
new file mode 100644
index 0000000..487fac6
--- /dev/null
+++ b/kiosktool/pageWidget.cpp
@@ -0,0 +1,210 @@
+/*
+ * pageWidget.cpp
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 "pageWidget.h"
+
+#include <kconfig.h>
+#include <klistview.h>
+
+#include "kioskdata.h"
+#include "kioskrun.h"
+
+ComponentActionItem::ComponentActionItem( QListView * parent, ComponentAction *action, int index)
+ : QCheckListItem(parent, action->caption, QCheckListItem::CheckBox),
+ m_action(action), m_index(index)
+{
+
+}
+
+int ComponentActionItem::compare ( QListViewItem * i, int, bool ) const
+{
+ ComponentActionItem *cai = static_cast<ComponentActionItem*>(i);
+ if (m_index == cai->m_index)
+ return 0;
+ if (m_index < cai->m_index)
+ return -1;
+ return 1;
+}
+
+PageWidget::PageWidget(QWidget *me)
+{
+ m_widget = me;
+}
+
+PageWidget::~PageWidget()
+{
+}
+
+void
+PageWidget::fillActionList(KListView *listView, ComponentData *componentData)
+{
+ int index = 0;
+ for(ComponentAction *action = componentData->actions.first(); action;
+ action = componentData->actions.next())
+ {
+ ComponentActionItem *item = new ComponentActionItem(listView, action, index++);
+ if (index == 1)
+ item->setSelected(true);
+ if (action->type == ComponentAction::ActRestrict)
+ {
+ QString file = action->file;
+ if (file.isEmpty())
+ file = "kdeglobals";
+ KConfig *cfg = KioskRun::self()->configFile(file);
+ cfg->setGroup("KDE Action Restrictions");
+ bool restricted = !cfg->readBoolEntry(action->key, true);
+ item->setOn(restricted);
+ }
+ else if (action->type == ComponentAction::ActResource)
+ {
+ QString file = action->file;
+ if (file.isEmpty())
+ file = "kdeglobals";
+ KConfig *cfg = KioskRun::self()->configFile(file);
+ cfg->setGroup("KDE Resource Restrictions");
+ bool restricted = !cfg->readBoolEntry(action->key, true);
+ item->setOn(restricted);
+ }
+ else if (action->type == ComponentAction::ActModule)
+ {
+ QString file = "kdeglobals";
+ KConfig *cfg = KioskRun::self()->configFile(file);
+ cfg->setGroup("KDE Control Module Restrictions");
+ bool restricted = !cfg->readBoolEntry(action->key, true);
+ item->setOn(restricted);
+ }
+ else if (action->type == ComponentAction::ActImmutable)
+ {
+ QString file = action->file;
+ if (file.isEmpty())
+ file = "kdeglobals";
+ QString group = action->group;
+ bool immutable = KioskRun::self()->isConfigImmutable(file, group);
+qWarning("File = %s Group = %s Immutable = %s", file.latin1(), group.latin1(), immutable ? "true" : "false");
+ item->setOn(immutable);
+ }
+ else if (action->type == ComponentAction::ActCustom)
+ {
+ bool checked = KioskRun::self()->lookupCustomAction(action->key);
+ item->setOn(checked);
+ }
+ else if (action->type == ComponentAction::ActConfig)
+ {
+ QString file = action->file;
+ if (file.isEmpty())
+ file = "kdeglobals";
+ KConfig *cfg = KioskRun::self()->configFile(file);
+ cfg->setGroup(action->group);
+ bool checked = cfg->readBoolEntry(action->key, action->defaultValue);
+ item->setOn(checked);
+ }
+ }
+ KioskRun::self()->flushConfigCache();
+}
+
+void
+PageWidget::saveActionListItem(ComponentAction *action, bool b)
+{
+ if (action->type == ComponentAction::ActRestrict)
+ {
+ QString file = action->file;
+ if (file.isEmpty())
+ file = "kdeglobals";
+ KConfig *cfg = KioskRun::self()->configFile(file);
+ cfg->setGroup("KDE Action Restrictions");
+
+ bool allowed = !b; // reverse logic
+ if (cfg->readBoolEntry(action->key, true) != allowed)
+ {
+ cfg->writeEntry(action->key, allowed);
+ KioskRun::self()->scheduleSycocaUpdate();
+ }
+ }
+ else if (action->type == ComponentAction::ActResource)
+ {
+ QString file = action->file;
+ if (file.isEmpty())
+ file = "kdeglobals";
+ KConfig *cfg = KioskRun::self()->configFile(file);
+ cfg->setGroup("KDE Resource Restrictions");
+
+ bool allowed = !b; // reverse logic
+ if (cfg->readBoolEntry(action->key, true) != allowed)
+ {
+ cfg->writeEntry(action->key, allowed);
+ KioskRun::self()->scheduleSycocaUpdate();
+ }
+ }
+ else if (action->type == ComponentAction::ActModule)
+ {
+ QString file = "kdeglobals";
+ KConfig *cfg = KioskRun::self()->configFile(file);
+ cfg->setGroup("KDE Control Module Restrictions");
+
+ bool allowed = !b; // reverse logic
+ if (cfg->readBoolEntry(action->key, true) != allowed)
+ {
+ cfg->writeEntry(action->key, allowed);
+ KioskRun::self()->scheduleSycocaUpdate();
+ }
+ }
+ else if (action->type == ComponentAction::ActImmutable)
+ {
+ QString file = action->file;
+ if (file.isEmpty())
+ file = "kdeglobals";
+ QString group = action->group;
+ KioskRun::self()->setConfigImmutable(file, group, b);
+ }
+ else if (action->type == ComponentAction::ActCustom)
+ {
+ KioskRun::self()->setCustomAction(action->key, b);
+ }
+ else if (action->type == ComponentAction::ActConfig)
+ {
+ QString file = action->file;
+ if (file.isEmpty())
+ file = "kdeglobals";
+ KConfig *cfg = KioskRun::self()->configFile(file);
+ cfg->setGroup(action->group);
+
+ if (cfg->readBoolEntry(action->key, action->defaultValue) != b)
+ {
+ cfg->writeEntry(action->key, b);
+ KioskRun::self()->scheduleSycocaUpdate();
+ }
+ }
+
+ for(ComponentAction *subAction = action->subActions.first();
+ subAction; subAction = action->subActions.next())
+ {
+ saveActionListItem(subAction, b);
+ }
+}
+
+bool
+PageWidget::saveActionListChanges(KListView *listView)
+{
+ for(ComponentActionItem *item = static_cast<ComponentActionItem*>(listView->firstChild());
+ item; item = static_cast<ComponentActionItem*>(item->nextSibling()))
+ {
+ saveActionListItem(item->action(), item->isOn());
+ }
+ return KioskRun::self()->flushConfigCache();
+}
diff --git a/kiosktool/pageWidget.h b/kiosktool/pageWidget.h
new file mode 100644
index 0000000..4006fba
--- /dev/null
+++ b/kiosktool/pageWidget.h
@@ -0,0 +1,67 @@
+/*
+ * pageWidget.h
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _PAGEWIDGET_H_
+#define _PAGEWIDGET_H_
+
+#include <klistview.h>
+
+class ComponentAction;
+class ComponentData;
+
+class ComponentActionItem : public QCheckListItem
+{
+public:
+ ComponentActionItem( QListView * parent, ComponentAction *action, int index);
+
+ ComponentAction *action() const { return m_action; }
+
+ virtual int compare ( QListViewItem * i, int col, bool ascending ) const;
+private:
+
+ ComponentAction *m_action;
+ int m_index;
+};
+
+class PageWidget
+{
+public:
+ PageWidget(QWidget *me);
+ virtual ~PageWidget();
+
+ QWidget *widget() const { return m_widget; }
+
+ void fillActionList(KListView *listView, ComponentData *componentData);
+ bool saveActionListChanges(KListView *listView);
+
+ virtual void load() = 0;
+ virtual bool save() = 0;
+
+ virtual void setFocus() = 0;
+
+ virtual QString subCaption() = 0;
+
+protected:
+ void saveActionListItem(ComponentAction *action, bool b);
+
+private:
+
+ QWidget *m_widget;
+};
+
+#endif
diff --git a/kiosktool/panelComponent.cpp b/kiosktool/panelComponent.cpp
new file mode 100644
index 0000000..1e541e3
--- /dev/null
+++ b/kiosktool/panelComponent.cpp
@@ -0,0 +1,83 @@
+/*
+ * panelComponent.cpp
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 "panelComponent.h"
+
+#include <qdir.h>
+#include <qfileinfo.h>
+
+#include <kdebug.h>
+#include <kmimetype.h>
+#include <kprocess.h>
+#include <ksavefile.h>
+#include <ksimpleconfig.h>
+#include <kstandarddirs.h>
+#include <kurl.h>
+
+#include "kioskrun.h"
+
+PanelComponent::PanelComponent( QObject *parent)
+ : Component(parent)
+{
+}
+
+PanelComponent::~PanelComponent()
+{
+}
+
+void
+PanelComponent::slotSetupPrepare()
+{
+}
+
+void
+PanelComponent::slotSetupStarted()
+{
+}
+
+bool
+PanelComponent::setupFinished()
+{
+ bool result;
+
+ // Install .desktop files
+ {
+ QString kickerApplications = KioskRun::self()->locateLocal("data", "kicker/");
+ QString kickerSaveApplications = KioskRun::self()->locateSave("data", "kicker/");
+
+ QDir dir(kickerApplications);
+ QStringList newKickerApplications = dir.entryList(QDir::All, QDir::Unsorted);
+ newKickerApplications.remove(".");
+ newKickerApplications.remove("..");
+
+ for(QStringList::ConstIterator it = newKickerApplications.begin();
+ it != newKickerApplications.end(); ++it)
+ {
+ if ((*it).endsWith(".desktop"))
+ {
+ kdDebug() << "PanelComponent: New .desktop file = " << (kickerApplications+(*it)) << endl;
+ result = KioskRun::self()->install(kickerApplications+(*it), kickerSaveApplications+(*it));
+ if (!result) return false;
+ }
+ }
+ }
+ return true;
+}
+
+#include "panelComponent.moc"
diff --git a/kiosktool/panelComponent.h b/kiosktool/panelComponent.h
new file mode 100644
index 0000000..30a8871
--- /dev/null
+++ b/kiosktool/panelComponent.h
@@ -0,0 +1,42 @@
+/*
+ * panelComponent.h
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _PANELCOMPONENT_H_
+#define _PANELCOMPONENT_H_
+
+#include "component.h"
+
+#include <qstringlist.h>
+#include <qtimer.h>
+
+class PanelComponent: public Component
+{
+ Q_OBJECT
+public:
+ PanelComponent( QObject *parent = 0);
+ virtual ~PanelComponent();
+
+ virtual bool setupFinished();
+
+public slots:
+
+ virtual void slotSetupPrepare();
+ virtual void slotSetupStarted();
+};
+
+#endif
diff --git a/kiosktool/profilePropsPage.cpp b/kiosktool/profilePropsPage.cpp
new file mode 100644
index 0000000..73f410f
--- /dev/null
+++ b/kiosktool/profilePropsPage.cpp
@@ -0,0 +1,234 @@
+/*
+ * profilePropsPage.cpp
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 "profilePropsPage.h"
+
+#include <qcombobox.h>
+#include <qvalidator.h>
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <klineedit.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kurlrequester.h>
+#include <kuser.h>
+
+#include "kioskrun.h"
+#include "kiosksync.h"
+
+static QStringList userList()
+{
+ KUser thisUser;
+ QStringList result;
+ result << thisUser.loginName();
+ result << "root";
+
+ KConfig *config = kapp->config();
+ config->setGroup("General");
+ result += config->readListEntry("PreviousUsers");
+ result.sort();
+
+ // Remove dupes
+ QStringList::Iterator nextIt = result.begin();
+ for(QStringList::Iterator it = result.begin();
+ it != result.end(); it = nextIt)
+ {
+ nextIt = it;
+ nextIt++;
+
+ if ((nextIt != result.end()) && ((*it) == (*nextIt)))
+ result.remove(it);
+ }
+
+ return result;
+}
+
+
+ProfilePropsPage::ProfilePropsPage(QWidget *parent, const QString &profile)
+ : ProfilePropsPageUI(parent), PageWidget(this), m_profile(profile)
+{
+}
+
+ProfilePropsPage::~ProfilePropsPage()
+{
+}
+
+void ProfilePropsPage::slotProfileNameChanged()
+{
+ QString profile = editProfileName->text();
+ if (m_fixedProfileDir)
+ {
+ QString profilePrefix = KioskRun::self()->getProfilePrefix();
+ QString installDir = profilePrefix+profile+"/";
+ labelInstallDir->setText(installDir);
+ }
+// TODO: enableButtonOK(!profile.isEmpty());
+}
+
+void ProfilePropsPage::load()
+{
+ bool bNewProfile = false;
+ if (m_profile.isEmpty())
+ {
+ m_profile = KioskRun::self()->newProfile();
+ bNewProfile = true;
+ }
+
+ QString profilePrefix = KioskRun::self()->getProfilePrefix();
+ m_fixedProfileDir = !profilePrefix.isEmpty();
+ connect(editProfileName, SIGNAL(textChanged(const QString&)),
+ this, SLOT(slotProfileNameChanged()));
+
+#if 0
+ connect(kurlInstallDir, SIGNAL(textChanged(const QString&)),
+ this, SLOT(updateButtons()));
+#endif
+
+ comboUser->setEditable(true);
+ comboUser->insertStringList(userList());
+
+ QRegExp rx( "[^/ :]*" );
+ QValidator* validator = new QRegExpValidator( rx, this );
+
+ editProfileName->setValidator(validator);
+ editProfileName->setFocus();
+
+ QString description;
+ QString installDir;
+ QString installUser;
+
+ KioskRun::self()->getProfileInfo(m_profile, description, installDir, installUser);
+
+ if (!bNewProfile)
+ {
+ m_origProfile = m_profile;
+ m_origInstallDir = installDir;
+ }
+
+ editProfileName->setText(m_profile);
+ editDescription->setText(description);
+ if (m_fixedProfileDir)
+ {
+ delete kurlInstallDir;
+ labelInstallDir->setReadOnly(true);
+ labelInstallDir->setText(installDir);
+ setTabOrder(editDescription, comboUser);
+ setTabOrder(comboUser, labelInstallDir);
+ }
+ else
+ {
+ delete labelInstallDir;
+ kurlInstallDir->setMode(KFile::Directory);
+ kurlInstallDir->setURL(installDir);
+ setTabOrder(editDescription, comboUser);
+ setTabOrder(comboUser, kurlInstallDir);
+ }
+ comboUser->setCurrentText(installUser);
+}
+
+bool ProfilePropsPage::save()
+{
+ QString user = comboUser->currentText();
+ KUser userInfo(user);
+ if (!userInfo.isValid())
+ {
+ KMessageBox::sorry(this,
+ i18n("<qt>The user <b>%1</b> is not an existing user.</qt>").arg(user));
+ comboUser->setFocus();
+ return false;
+ }
+
+ m_profile = editProfileName->text();
+ QString description = editDescription->text();
+ QString installDir;
+ if (m_fixedProfileDir)
+ {
+ installDir = labelInstallDir->text();
+ }
+ else
+ {
+ installDir = kurlInstallDir->url();
+ }
+
+ if (!installDir.endsWith("/"))
+ installDir.append("/");
+
+ if (!m_origInstallDir.isEmpty() && (installDir != m_origInstallDir))
+ {
+ KioskSync origInstallDir;
+ origInstallDir.addDir(m_origInstallDir, KURL());
+ QStringList fileList = origInstallDir.listFiles();
+ fileList.remove(".kdeprofile");
+ if (!fileList.isEmpty())
+ {
+ int msgResult = KMessageBox::warningContinueCancelList(this,
+ i18n("<qt>The directory for this profile has changed "
+ "from <b>%1</b> to <b>%2</b>.<p>"
+ "The following files under <b>%3</b> will be moved to <b>%4</b>")
+ .arg(m_origInstallDir, installDir, m_origInstallDir, installDir),
+ fileList,
+ i18n("Profile Directory Changed"));
+ if (msgResult != KMessageBox::Continue)
+ return false;
+ }
+ KioskRun::self()->setUser(user);
+ if (!KioskRun::self()->move(m_origInstallDir, installDir, fileList))
+ return false;
+ if (QDir(m_origInstallDir).exists())
+ {
+ if (!KioskRun::self()->remove(m_origInstallDir))
+ return false;
+ }
+ }
+
+ QString installUser = user;
+
+ bool result = KioskRun::self()->setProfileInfo( m_profile, description, installDir, installUser);
+
+ if (result && !m_origProfile.isEmpty() && (m_origProfile != m_profile))
+ {
+ result = KioskRun::self()->deleteProfile( m_origProfile, false );
+ }
+
+ // Store this user for easy access later
+ KConfig *config = kapp->config();
+ config->setGroup("General");
+ QStringList previousUsers= config->readListEntry("PreviousUsers");
+ if (!previousUsers.contains(user))
+ {
+ previousUsers << user;
+ config->writeEntry("PreviousUsers", previousUsers);
+ config->sync();
+ }
+
+ return result;
+}
+
+void ProfilePropsPage::setFocus()
+{
+ editProfileName->setFocus();
+}
+
+QString ProfilePropsPage::subCaption()
+{
+ return QString::null;
+}
+
+#include "profilePropsPage.moc"
diff --git a/kiosktool/profilePropsPage.h b/kiosktool/profilePropsPage.h
new file mode 100644
index 0000000..e846020
--- /dev/null
+++ b/kiosktool/profilePropsPage.h
@@ -0,0 +1,51 @@
+/*
+ * profilePropsPage.h
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _PROFILEPROPSPAGE_H_
+#define _PROFILEPROPSPAGE_H_
+
+#include "profilePropsPage_ui.h"
+#include "pageWidget.h"
+
+class ProfilePropsPage : public ProfilePropsPageUI, public PageWidget
+{
+ Q_OBJECT
+public:
+ ProfilePropsPage(QWidget *parent, const QString &profile);
+ ~ProfilePropsPage();
+
+ virtual void load();
+ virtual bool save();
+
+ virtual void setFocus();
+
+ virtual QString subCaption();
+
+ QString profile() { return m_profile; }
+
+protected slots:
+ void slotProfileNameChanged();
+
+private:
+ QString m_profile;
+ bool m_fixedProfileDir;
+ QString m_origProfile;
+ QString m_origInstallDir;
+};
+
+#endif
diff --git a/kiosktool/profilePropsPage_ui.ui b/kiosktool/profilePropsPage_ui.ui
new file mode 100644
index 0000000..8cfefc1
--- /dev/null
+++ b/kiosktool/profilePropsPage_ui.ui
@@ -0,0 +1,255 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>ProfilePropsPageUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Page2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>721</width>
+ <height>543</height>
+ </rect>
+ </property>
+ <property name="backgroundOrigin">
+ <enum>WindowOrigin</enum>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer row="0" column="2">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="0" column="0">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>60</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QFrame" row="0" column="1">
+ <property name="name">
+ <cstring>frame3</cstring>
+ </property>
+ <property name="backgroundOrigin">
+ <enum>WindowOrigin</enum>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="backgroundOrigin">
+ <enum>WindowOrigin</enum>
+ </property>
+ <property name="text">
+ <string>&amp;Profile name:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>editProfileName</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>editProfileName</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>400</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer5_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="backgroundOrigin">
+ <enum>WindowOrigin</enum>
+ </property>
+ <property name="text">
+ <string>Short &amp;description:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>editDescription</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>editDescription</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>400</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer5_2_2_3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel4_2</cstring>
+ </property>
+ <property name="backgroundOrigin">
+ <enum>WindowOrigin</enum>
+ </property>
+ <property name="text">
+ <string>&amp;Files in this profile will be owned by:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kurlInstallDir</cstring>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <property name="name">
+ <cstring>comboUser</cstring>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer5_2_2_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="backgroundOrigin">
+ <enum>WindowOrigin</enum>
+ </property>
+ <property name="text">
+ <string>&amp;Directory for this profile:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kurlInstallDir</cstring>
+ </property>
+ </widget>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>kurlInstallDir</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>400</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="backgroundOrigin">
+ <enum>WindowOrigin</enum>
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>labelInstallDir</cstring>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer row="1" column="1">
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>30</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+</widget>
+<customwidgets>
+</customwidgets>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kcombobox.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>klineedit.h</includehint>
+</includehints>
+</UI>
diff --git a/kiosktool/profileSelectionPage_ui.ui b/kiosktool/profileSelectionPage_ui.ui
new file mode 100644
index 0000000..9142445
--- /dev/null
+++ b/kiosktool/profileSelectionPage_ui.ui
@@ -0,0 +1,230 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>ProfileSelectionPageUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Page1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>656</width>
+ <height>362</height>
+ </rect>
+ </property>
+ <property name="backgroundOrigin">
+ <enum>WindowOrigin</enum>
+ </property>
+ <property name="caption">
+ <string>Page1</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer row="4" column="1">
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KListView" row="2" column="1" rowspan="2" colspan="1">
+ <column>
+ <property name="text">
+ <string>Profile</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Description</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>listProfile</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>1</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>300</width>
+ <height>220</height>
+ </size>
+ </property>
+ <property name="backgroundOrigin">
+ <enum>WindowOrigin</enum>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="fullWidth">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer row="3" column="2">
+ <property name="name">
+ <cstring>spacer2_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLayoutWidget" row="2" column="3" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>layout3</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonAdd</cstring>
+ </property>
+ <property name="text">
+ <string>Add &amp;New Profile</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer5_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonSetup</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Setup Profile</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer5_2_3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonUsers</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Assign Profiles</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer6_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonProperty</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Profile Properties</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonDelete</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Delete Profile</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kiosktool/screensaverComponent.cpp b/kiosktool/screensaverComponent.cpp
new file mode 100644
index 0000000..530bd27
--- /dev/null
+++ b/kiosktool/screensaverComponent.cpp
@@ -0,0 +1,41 @@
+/*
+ * screensaverComponent.cpp
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 "screensaverComponent.h"
+
+#include "kioskrun.h"
+
+ScreenSaverComponent::ScreenSaverComponent( QObject *parent)
+ : Component(parent)
+{
+qWarning("ScreenSaverComponent::ScreenSaverComponent");
+ connect(&m_timer, SIGNAL(timeout()), this, SLOT(slotPreviewStarted()));
+}
+
+ScreenSaverComponent::~ScreenSaverComponent()
+{
+}
+
+void
+ScreenSaverComponent::slotPreviewStarted()
+{
+ KioskRun::self()->dcopRef("kdesktop", "KScreensaverIface").call("save");
+}
+
+#include "screensaverComponent.moc"
diff --git a/kiosktool/screensaverComponent.h b/kiosktool/screensaverComponent.h
new file mode 100644
index 0000000..fd60047
--- /dev/null
+++ b/kiosktool/screensaverComponent.h
@@ -0,0 +1,41 @@
+/*
+ * screensaverComponent.h
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _SCREENSAVERCOMPONENT_H_
+#define _SCREENSAVERCOMPONENT_H_
+
+#include "component.h"
+
+#include <qtimer.h>
+
+class ScreenSaverComponent: public Component
+{
+ Q_OBJECT
+public:
+ ScreenSaverComponent( QObject *parent = 0);
+ virtual ~ScreenSaverComponent();
+
+public slots:
+
+ virtual void slotPreviewStarted();
+
+private:
+ QTimer m_timer;
+};
+
+#endif
diff --git a/kiosktool/userManagement.cpp b/kiosktool/userManagement.cpp
new file mode 100644
index 0000000..3493b97
--- /dev/null
+++ b/kiosktool/userManagement.cpp
@@ -0,0 +1,306 @@
+/*
+ * userManagement.cpp
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 "userManagement.h"
+
+#include <unistd.h>
+#include <grp.h>
+#include <pwd.h>
+#include <sys/types.h>
+
+#include <qcombobox.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <klistview.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+
+#include "kioskrun.h"
+
+#include "userManagement_ui.h"
+#include "userManagementGroup_ui.h"
+#include "userManagementUser_ui.h"
+
+#define AVAILABLE_SINCE "KDE 3.2.3"
+
+UserManagementPage::UserManagementPage(QWidget* parent, const char* name, WFlags fl)
+ : UserManagementUI(parent, name, fl), PageWidget(this)
+{
+ setCaption(i18n("Assign Profiles"));
+ listGroups->setSorting(-1); // Disable sorting
+ listGroups->setDragEnabled(true);
+ listGroups->setAcceptDrops(true);
+
+// actionButton(KDialogBase::Ok)->setFocus();
+
+ connect(buttonAddGroup, SIGNAL(clicked()), this, SLOT(slotAddGroup()));
+ connect(buttonDeleteGroup, SIGNAL(clicked()), this, SLOT(slotDeleteGroup()));
+ connect(buttonAddUser, SIGNAL(clicked()), this, SLOT(slotAddUser()));
+ connect(buttonDeleteUser, SIGNAL(clicked()), this, SLOT(slotDeleteUser()));
+
+ connect(listGroups, SIGNAL(selectionChanged()), this, SLOT(slotUpdateButtons()));
+ connect(listUsers, SIGNAL(selectionChanged()), this, SLOT(slotUpdateButtons()));
+
+// init();
+ static bool firstTime = true;
+
+ if (firstTime)
+ {
+ firstTime = false;
+ QTimer::singleShot(0, this, SLOT(slotShowNotice()));
+ }
+}
+
+UserManagementPage::~UserManagementPage()
+{
+}
+
+void UserManagementPage::slotShowNotice()
+{
+ KMessageBox::information(this,
+ i18n("<qt>The profiles that you define here are automatically applied when the "
+ "user logs in to %1 or newer.<p>"
+ "If you want to use these profiles in combination with older versions you need "
+ "to manually set the $KDEDIRS environment variable from the <b>startkde</b> "
+ "script by adding the following line:<br><br>"
+ "<i>export KDEDIRS=$(kiosktool-kdedirs)</i><br><br>").arg(AVAILABLE_SINCE),
+ i18n("Attention"), "user-profiles");
+}
+
+void UserManagementPage::load()
+{
+ listGroups->clear();
+ listUsers->clear();
+
+ m_allProfiles = KioskRun::self()->allProfiles();
+ m_allProfiles.sort();
+
+ KioskRun::ProfileMapping groups;
+ KioskRun::ProfileMapping users;
+ QStringList groupOrder;
+
+ KioskRun::self()->getUserProfileMappings(groups, users, groupOrder);
+
+ for ( QStringList::ConstIterator it = groupOrder.begin();
+ it != groupOrder.end(); ++it )
+ {
+ QString group = *it;
+ QString profile = groups[group].join(",");
+ new QListViewItem(listGroups, group, profile);
+ }
+
+ for ( KioskRun::ProfileMapping::Iterator it = users.begin();
+ it != users.end(); ++it )
+ {
+ QString user = it.key();
+ QString profile = it.data().join(",");
+ new QListViewItem(listUsers, user, profile);
+ }
+ slotUpdateButtons();
+}
+
+void UserManagementPage::slotUpdateButtons()
+{
+ buttonDeleteGroup->setEnabled(listGroups->selectedItem() != 0);
+ buttonDeleteUser->setEnabled(listUsers->selectedItem() != 0);
+}
+
+bool UserManagementPage::save()
+{
+ KioskRun::ProfileMapping groups;
+ KioskRun::ProfileMapping users;
+ QStringList groupOrder;
+
+ QListViewItem *item = listGroups->firstChild();
+ for(; item; item = item->nextSibling())
+ {
+ QString group = item->text(0);
+ QStringList profiles = QStringList::split(",", item->text(1));
+ groups.insert(group, profiles);
+ groupOrder.prepend(group);
+ }
+
+ item = listUsers->firstChild();
+ for(; item; item = item->nextSibling())
+ {
+ QString user = item->text(0);
+ QStringList profiles = QStringList::split(",", item->text(1));
+ users.insert(user, profiles);
+ }
+
+ return KioskRun::self()->setUserProfileMappings(groups, users, groupOrder);
+}
+
+void UserManagementPage::slotAddGroup()
+{
+ KConfig *config = kapp->config();
+ config->setGroup("General");
+ QStringList groupBlacklist = config->readListEntry("GroupBlacklist");
+
+ m_allGroups.clear();
+ setgrent();
+ for (struct group *grp; (grp = getgrent()); )
+ {
+ QString group = QString::fromUtf8(grp->gr_name);
+ if (!groupBlacklist.contains(group))
+ m_allGroups.append(group);
+ }
+ endgrent();
+ m_allGroups.sort();
+
+ KDialogBase dlg(this, "addGroup", true, i18n("Add Group Policy"),
+ KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, true );
+
+ UserManagementGroupUI *wid = new UserManagementGroupUI(&dlg);
+ wid->labelCaption->setFixedSize(wid->labelCaption->sizeHint());
+ wid->comboGroup->insertStringList(m_allGroups);
+ wid->comboProfile->insertStringList(m_allProfiles);
+ wid->setFixedSize(wid->sizeHint());
+ dlg.setMainWidget(wid);
+ dlg.setFixedSize(dlg.sizeHint());
+ while (dlg.exec() == KDialogBase::Accepted)
+ {
+ QString group = wid->comboGroup->currentText();
+ QString profile = wid->comboProfile->currentText();
+
+ // Check for dupes
+ QListViewItem *item = listGroups->firstChild();
+ for( ;item; item = item->nextSibling())
+ {
+ if (item->text(0) == group)
+ break;
+ }
+ if (item)
+ {
+ int result = KMessageBox::warningContinueCancel(this,
+ i18n("<qt>You already have a profile defined for group <b>%1</b>. "
+ "Do you want to replace it?</qt>").arg(group),
+ i18n("Duplicate Warning"),
+ i18n("&Replace"));
+ if (result != KMessageBox::Continue)
+ continue; // Go back to edit dialog
+ delete item;
+ }
+
+ item = new QListViewItem(listGroups, group, profile);
+ listGroups->setSelected(item, true);
+ slotUpdateButtons();
+ return;
+ }
+}
+
+void UserManagementPage::slotDeleteGroup()
+{
+ QListViewItem *item = listGroups->selectedItem();
+ if (!item)
+ return;
+
+ delete item;
+
+ item = listGroups->currentItem();
+ if (item)
+ listGroups->setSelected(item, true);
+ slotUpdateButtons();
+}
+
+void UserManagementPage::slotAddUser()
+{
+ KConfig *config = kapp->config();
+ config->setGroup("General");
+ int minUID = config->readNumEntry("FirstUIDShown", 500);
+
+ m_allUsers.clear();
+ setpwent();
+ for (struct passwd *user; (user = getpwent()); )
+ {
+ if ((user->pw_uid >= (uid_t) minUID) || (user->pw_uid == 0))
+ m_allUsers.append(QString::fromUtf8(user->pw_name));
+ }
+ endpwent();
+ m_allUsers.sort();
+
+ KDialogBase dlg(this, "addUser", true, i18n("Add User Policy"),
+ KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, true );
+
+ UserManagementUserUI *wid = new UserManagementUserUI(&dlg);
+ wid->labelCaption->setFixedSize(wid->labelCaption->sizeHint());
+ wid->comboUser->insertStringList(m_allUsers);
+ wid->comboProfile->insertStringList(m_allProfiles);
+ wid->setFixedSize(wid->sizeHint());
+ dlg.setMainWidget(wid);
+ dlg.setFixedSize(dlg.sizeHint());
+ while (dlg.exec() == KDialogBase::Accepted)
+ {
+ QString user = wid->comboUser->currentText();
+ QString profile = wid->comboProfile->currentText();
+
+ // Check for dupes
+ QListViewItem *item = listUsers->firstChild();
+ for( ;item; item = item->nextSibling())
+ {
+ if (item->text(0) == user)
+ break;
+ }
+ if (item)
+ {
+ int result = KMessageBox::warningContinueCancel(this,
+ i18n("<qt>You already have a profile defined for user <b>%1</b>. "
+ "Do you want to replace it?</<qt>").arg(user),
+ i18n("Duplicate Warning"),
+ i18n("&Replace"));
+ if (result != KMessageBox::Continue)
+ continue; // Go back to edit dialog
+ delete item;
+ }
+
+ item = new QListViewItem(listUsers, user, profile);
+ listUsers->setSelected(item, true);
+ slotUpdateButtons();
+ return;
+ }
+}
+
+void UserManagementPage::slotDeleteUser()
+{
+ QListViewItem *item = listUsers->selectedItem();
+ if (!item)
+ return;
+
+ delete item;
+
+ item = listUsers->currentItem();
+ if (item)
+ listUsers->setSelected(item, true);
+ slotUpdateButtons();
+}
+
+void UserManagementPage::setFocus()
+{
+ // TODO
+}
+
+QString UserManagementPage::subCaption()
+{
+ return i18n("Assign Profiles");
+}
+
+#include "userManagement.moc"
diff --git a/kiosktool/userManagement.h b/kiosktool/userManagement.h
new file mode 100644
index 0000000..b4007a9
--- /dev/null
+++ b/kiosktool/userManagement.h
@@ -0,0 +1,60 @@
+/*
+ * userManagement.h
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _USERMANAGEMENT_H_
+#define _USERMANAGEMENT_H_
+
+#include "pageWidget.h"
+#include "userManagement_ui.h"
+
+class UserManagementUI;
+
+class UserManagementPage : public UserManagementUI, public PageWidget
+{
+ Q_OBJECT
+public:
+ UserManagementPage(QWidget* parent, const char* name = 0, WFlags fl = 0);
+ ~UserManagementPage();
+
+ virtual void load();
+ virtual bool save();
+
+ virtual void setFocus();
+
+ virtual QString subCaption();
+
+protected:
+ void init();
+
+private slots:
+ void slotAddGroup();
+ void slotDeleteGroup();
+ void slotAddUser();
+ void slotDeleteUser();
+
+ void slotUpdateButtons();
+ void slotShowNotice();
+
+private:
+ UserManagementUI *w;
+ QStringList m_allUsers;
+ QStringList m_allGroups;
+ QStringList m_allProfiles;
+};
+
+#endif
diff --git a/kiosktool/userManagementGroup_ui.ui b/kiosktool/userManagementGroup_ui.ui
new file mode 100644
index 0000000..62fdb6a
--- /dev/null
+++ b/kiosktool/userManagementGroup_ui.ui
@@ -0,0 +1,117 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>UserManagementGroupUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>UserManagementGroupUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>402</width>
+ <height>92</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>labelCaption</cstring>
+ </property>
+ <property name="text">
+ <string>Select the profile to use for all users in the specified group.</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>labelGroup</cstring>
+ </property>
+ <property name="text">
+ <string>Group:</string>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <property name="name">
+ <cstring>comboGroup</cstring>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>labelProfile</cstring>
+ </property>
+ <property name="text">
+ <string>Profile:</string>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <property name="name">
+ <cstring>comboProfile</cstring>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>51</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kiosktool/userManagementUser_ui.ui b/kiosktool/userManagementUser_ui.ui
new file mode 100644
index 0000000..82cda1e
--- /dev/null
+++ b/kiosktool/userManagementUser_ui.ui
@@ -0,0 +1,117 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>UserManagementUserUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>UserManagementUserUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>402</width>
+ <height>92</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>labelCaption</cstring>
+ </property>
+ <property name="text">
+ <string>Select the profile to use for the specified user.</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>labelUser</cstring>
+ </property>
+ <property name="text">
+ <string>User:</string>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <property name="name">
+ <cstring>comboUser</cstring>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>labelProfile</cstring>
+ </property>
+ <property name="text">
+ <string>Profile:</string>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <property name="name">
+ <cstring>comboProfile</cstring>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>51</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kiosktool/userManagement_ui.ui b/kiosktool/userManagement_ui.ui
new file mode 100644
index 0000000..6da92c7
--- /dev/null
+++ b/kiosktool/userManagement_ui.ui
@@ -0,0 +1,278 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>UserManagementUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>UserManagementUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>659</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox3</cstring>
+ </property>
+ <property name="title">
+ <string>Default Policy</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Profile used for users with no assigned profile:</string>
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>kLineEdit1</cstring>
+ </property>
+ <property name="text">
+ <string>default</string>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Group Policies</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KListView">
+ <column>
+ <property name="text">
+ <string>Group</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Profile</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>listGroups</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>350</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="fullWidth">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonAddGroup</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Add Group Policy...</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonDeleteGroup</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Delete Group Policy</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox2</cstring>
+ </property>
+ <property name="title">
+ <string>Individual User Policies</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KListView">
+ <column>
+ <property name="text">
+ <string>User</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Profile</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>listUsers</cstring>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="fullWidth">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout1_2</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonAddUser</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Add User Policy...</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonDeleteUser</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Delete User Policy</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>