From 281b2113b209bd51bd923ad8f289f4041ff03a0f Mon Sep 17 00:00:00 2001 From: tpearson Date: Sat, 15 Oct 2011 09:14:47 +0000 Subject: Initial import of kiosktool This source tree will most likely not even compile yet--stay tuned for updates! git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kiosktool@1258966 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kiosktool/Makefile.am | 62 + kiosktool/background.png | Bin 0 -> 1583 bytes kiosktool/caption-da.png | Bin 0 -> 20749 bytes kiosktool/caption-empty.png | Bin 0 -> 912 bytes kiosktool/caption-et.png | Bin 0 -> 15081 bytes kiosktool/caption-pt.png | Bin 0 -> 28703 bytes kiosktool/caption-pt_BR.png | Bin 0 -> 28703 bytes kiosktool/caption-sv.png | Bin 0 -> 22583 bytes kiosktool/caption.png | Bin 0 -> 20656 bytes kiosktool/component.cpp | 52 + kiosktool/component.h | 40 + kiosktool/componentPage.cpp | 306 +++++ kiosktool/componentPage.h | 65 + kiosktool/componentPage_ui.ui | 195 +++ kiosktool/componentSelectionPage.cpp | 143 +++ kiosktool/componentSelectionPage.h | 59 + kiosktool/componentSelectionPage_ui.ui | 124 ++ kiosktool/configure.in.in | 2 + kiosktool/cr16-app-kiosktool.png | Bin 0 -> 528 bytes kiosktool/cr32-app-kiosktool.png | Bin 0 -> 1021 bytes kiosktool/cr48-app-kiosktool.png | Bin 0 -> 1612 bytes kiosktool/desktopComponent.cpp | 239 ++++ kiosktool/desktopComponent.h | 50 + kiosktool/extractxml | 120 ++ kiosktool/filetypeeditComponent.cpp | 133 ++ kiosktool/filetypeeditComponent.h | 42 + kiosktool/kcms/Makefile.am | 6 + kiosktool/kcms/autostart/Makefile.am | 17 + kiosktool/kcms/autostart/kcmautostart.cpp | 202 +++ kiosktool/kcms/autostart/kcmautostart.desktop | 56 + kiosktool/kcms/autostart/kcmautostart.h | 66 + kiosktool/kioskConfigDialog.cpp | 149 +++ kiosktool/kioskConfigDialog.h | 46 + kiosktool/kioskConfigDialog_ui.ui | 329 +++++ kiosktool/kiosk_data.xml | 778 ++++++++++++ kiosktool/kioskdata.cpp | 309 +++++ kiosktool/kioskdata.h | 105 ++ kiosktool/kioskgui.cpp | 727 +++++++++++ kiosktool/kioskgui.h | 109 ++ kiosktool/kioskrun.cpp | 1687 +++++++++++++++++++++++++ kiosktool/kioskrun.h | 229 ++++ kiosktool/kiosksync.cpp | 211 ++++ kiosktool/kiosksync.h | 80 ++ kiosktool/kiosktool-kdedirs.cpp | 184 +++ kiosktool/kiosktool.desktop | 28 + kiosktool/kiosktoolui.rc | 13 + kiosktool/logo.png | Bin 0 -> 4734 bytes kiosktool/main.cpp | 80 ++ kiosktool/mainview.ui | 258 ++++ kiosktool/menueditComponent.cpp | 241 ++++ kiosktool/menueditComponent.h | 43 + kiosktool/pageWidget.cpp | 210 +++ kiosktool/pageWidget.h | 67 + kiosktool/panelComponent.cpp | 83 ++ kiosktool/panelComponent.h | 42 + kiosktool/profilePropsPage.cpp | 234 ++++ kiosktool/profilePropsPage.h | 51 + kiosktool/profilePropsPage_ui.ui | 255 ++++ kiosktool/profileSelectionPage_ui.ui | 230 ++++ kiosktool/screensaverComponent.cpp | 41 + kiosktool/screensaverComponent.h | 41 + kiosktool/userManagement.cpp | 306 +++++ kiosktool/userManagement.h | 60 + kiosktool/userManagementGroup_ui.ui | 117 ++ kiosktool/userManagementUser_ui.ui | 117 ++ kiosktool/userManagement_ui.ui | 278 ++++ 66 files changed, 9717 insertions(+) create mode 100644 kiosktool/Makefile.am create mode 100644 kiosktool/background.png create mode 100644 kiosktool/caption-da.png create mode 100644 kiosktool/caption-empty.png create mode 100644 kiosktool/caption-et.png create mode 100644 kiosktool/caption-pt.png create mode 100644 kiosktool/caption-pt_BR.png create mode 100644 kiosktool/caption-sv.png create mode 100644 kiosktool/caption.png create mode 100644 kiosktool/component.cpp create mode 100644 kiosktool/component.h create mode 100644 kiosktool/componentPage.cpp create mode 100644 kiosktool/componentPage.h create mode 100644 kiosktool/componentPage_ui.ui create mode 100644 kiosktool/componentSelectionPage.cpp create mode 100644 kiosktool/componentSelectionPage.h create mode 100644 kiosktool/componentSelectionPage_ui.ui create mode 100644 kiosktool/configure.in.in create mode 100644 kiosktool/cr16-app-kiosktool.png create mode 100644 kiosktool/cr32-app-kiosktool.png create mode 100644 kiosktool/cr48-app-kiosktool.png create mode 100644 kiosktool/desktopComponent.cpp create mode 100644 kiosktool/desktopComponent.h create mode 100755 kiosktool/extractxml create mode 100644 kiosktool/filetypeeditComponent.cpp create mode 100644 kiosktool/filetypeeditComponent.h create mode 100644 kiosktool/kcms/Makefile.am create mode 100644 kiosktool/kcms/autostart/Makefile.am create mode 100644 kiosktool/kcms/autostart/kcmautostart.cpp create mode 100644 kiosktool/kcms/autostart/kcmautostart.desktop create mode 100644 kiosktool/kcms/autostart/kcmautostart.h create mode 100644 kiosktool/kioskConfigDialog.cpp create mode 100644 kiosktool/kioskConfigDialog.h create mode 100644 kiosktool/kioskConfigDialog_ui.ui create mode 100644 kiosktool/kiosk_data.xml create mode 100644 kiosktool/kioskdata.cpp create mode 100644 kiosktool/kioskdata.h create mode 100644 kiosktool/kioskgui.cpp create mode 100644 kiosktool/kioskgui.h create mode 100644 kiosktool/kioskrun.cpp create mode 100644 kiosktool/kioskrun.h create mode 100644 kiosktool/kiosksync.cpp create mode 100644 kiosktool/kiosksync.h create mode 100644 kiosktool/kiosktool-kdedirs.cpp create mode 100644 kiosktool/kiosktool.desktop create mode 100644 kiosktool/kiosktoolui.rc create mode 100644 kiosktool/logo.png create mode 100644 kiosktool/main.cpp create mode 100644 kiosktool/mainview.ui create mode 100644 kiosktool/menueditComponent.cpp create mode 100644 kiosktool/menueditComponent.h create mode 100644 kiosktool/pageWidget.cpp create mode 100644 kiosktool/pageWidget.h create mode 100644 kiosktool/panelComponent.cpp create mode 100644 kiosktool/panelComponent.h create mode 100644 kiosktool/profilePropsPage.cpp create mode 100644 kiosktool/profilePropsPage.h create mode 100644 kiosktool/profilePropsPage_ui.ui create mode 100644 kiosktool/profileSelectionPage_ui.ui create mode 100644 kiosktool/screensaverComponent.cpp create mode 100644 kiosktool/screensaverComponent.h create mode 100644 kiosktool/userManagement.cpp create mode 100644 kiosktool/userManagement.h create mode 100644 kiosktool/userManagementGroup_ui.ui create mode 100644 kiosktool/userManagementUser_ui.ui create mode 100644 kiosktool/userManagement_ui.ui (limited to 'kiosktool') 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 Binary files /dev/null and b/kiosktool/background.png differ diff --git a/kiosktool/caption-da.png b/kiosktool/caption-da.png new file mode 100644 index 0000000..7894085 Binary files /dev/null and b/kiosktool/caption-da.png differ diff --git a/kiosktool/caption-empty.png b/kiosktool/caption-empty.png new file mode 100644 index 0000000..07a6a3a Binary files /dev/null and b/kiosktool/caption-empty.png differ diff --git a/kiosktool/caption-et.png b/kiosktool/caption-et.png new file mode 100644 index 0000000..8cba1b3 Binary files /dev/null and b/kiosktool/caption-et.png differ diff --git a/kiosktool/caption-pt.png b/kiosktool/caption-pt.png new file mode 100644 index 0000000..db57843 Binary files /dev/null and b/kiosktool/caption-pt.png differ diff --git a/kiosktool/caption-pt_BR.png b/kiosktool/caption-pt_BR.png new file mode 100644 index 0000000..db57843 Binary files /dev/null and b/kiosktool/caption-pt_BR.png differ diff --git a/kiosktool/caption-sv.png b/kiosktool/caption-sv.png new file mode 100644 index 0000000..358cad3 Binary files /dev/null and b/kiosktool/caption-sv.png differ diff --git a/kiosktool/caption.png b/kiosktool/caption.png new file mode 100644 index 0000000..0ce1c8d Binary files /dev/null and b/kiosktool/caption.png 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 + * + * 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 + * + * 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 + +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 + * + * 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 +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#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("There was an unexpected problem with the runtime environment.")); + 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("You can now configure %1. " + "When you are finished click Save 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("This is how %1 will behave and look with the new settings. " + "Any changes you now make to the settings will not be saved.

" + "Click Ok 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(item); + QString description; + if (actionItem) + { + description = "

"+QStyleSheet::escape(actionItem->action()->caption)+"

\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 + * + * 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 @@ + +ComponentPageUI + + + ComponentPageUI + + + + 0 + 0 + 559 + 372 + + + + WindowOrigin + + + + unnamed + + + + componentDescription + + + + 0 + 140 + + + + + 32767 + 140 + + + + StyledPanel + + + Sunken + + + WordBreak|AlignTop + + + + + spacer8 + + + Vertical + + + Fixed + + + + 20 + 16 + + + + + + layout1 + + + + unnamed + + + + pbSetup + + + &Setup XXX + + + + + spacer8_2 + + + Vertical + + + Fixed + + + + 20 + 16 + + + + + + pbPreview + + + &Preview XXX + + + + + spacer8_3 + + + Vertical + + + Expanding + + + + 21 + 171 + + + + + + + + spacer7 + + + Horizontal + + + Fixed + + + + 16 + 20 + + + + + + + Restriction + + + true + + + true + + + + listComponentConfig + + + + 7 + 7 + 1 + 1 + + + + + 300 + 150 + + + + WindowOrigin + + + true + + + true + + + + + textLabel1 + + + Enable &restrictions: + + + listComponentConfig + + + + + + 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 + * + * 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 + +#include +#include +#include +#include +#include + +#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(listComponent->firstItem()); + while(item) + { + if (item->isSelected()) + return item->id; + + item = static_cast(item->nextItem()); + } + return QString::null; +} + +void ComponentSelectionPage::setCurrentComponent(const QString &id) +{ + ComponentViewItem *item = static_cast(listComponent->firstItem()); + while(item) + { + if (item->id == id) + { + listComponent->setSelected(item, true); + return; + } + item = static_cast(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 + * + * 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 @@ + +ComponentSelectionPageUI + + + ComponentSelectionPageUI + + + + 0 + 0 + 682 + 373 + + + + WindowOrigin + + + + unnamed + + + + spacer2_2 + + + Horizontal + + + Fixed + + + + 20 + 20 + + + + + + spacer5 + + + Vertical + + + Fixed + + + + 20 + 20 + + + + + + layout1 + + + + unnamed + + + + pbSetup + + + &Setup Component + + + + + spacer5_2 + + + Vertical + + + Expanding + + + + 20 + 211 + + + + + + + + listComponent + + + + 7 + 7 + 1 + 0 + + + + + 400 + 200 + + + + + + textLabel1 + + + Select &component: + + + listComponent + + + + + + 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 Binary files /dev/null and b/kiosktool/cr16-app-kiosktool.png differ diff --git a/kiosktool/cr32-app-kiosktool.png b/kiosktool/cr32-app-kiosktool.png new file mode 100644 index 0000000..a987516 Binary files /dev/null and b/kiosktool/cr32-app-kiosktool.png differ diff --git a/kiosktool/cr48-app-kiosktool.png b/kiosktool/cr48-app-kiosktool.png new file mode 100644 index 0000000..87e18dd Binary files /dev/null and b/kiosktool/cr48-app-kiosktool.png 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 + * + * 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 +#include + +#include +#include +#include +#include +#include +#include +#include + +#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 + * + * 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 +#include + +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 and 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 ( ) { + $linenr++; + if ($linenr == 1 && ($_ !~ /^'; + + # The 'database' property contains strings that shouldn't be translated + if ($inskippedprop == 0 && ($string =~ //g; + $text =~ s/&/&/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 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 + * + * 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + * + * 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 +#include + +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 + +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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "kcmautostart.h" +#include "kcmautostart.moc" + +typedef KGenericFactory 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( 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(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("

Service Manager

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:

" + "
  • Services invoked at startup
  • Services called on demand
" + "

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.

" + "

Use this with care: some services are vital for KDE; do not deactivate services if you" + " do not know what you are doing.

"); +} + +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 + 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 +#include + +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 + * + * 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 +#include + +#include +#include +#include +#include +#include +#include +#include + +#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("
%1
-->
%2
").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 + * + * 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 + +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 @@ + +KioskConfigDialogUI + + + KioskConfigDialogUI + + + + 0 + 0 + 551 + 501 + + + + + unnamed + + + + checkProfilePrefix + + + Store all &profiles under the same base directory + + + + + layout3 + + + + unnamed + + + + spacer1 + + + Horizontal + + + Fixed + + + + 20 + 20 + + + + + + layout2 + + + + unnamed + + + + textLabel1 + + + &Base directory: + + + lineProfilePrefix + + + + + lineProfilePrefix + + + false + + + + + + + + + checkUpload + + + On exit, &upload profiles to remote server + + + + + layout8 + + + + unnamed + + + + spacer1_2 + + + Horizontal + + + Fixed + + + + 16 + 20 + + + + + + layout7 + + + + unnamed + + + + textLabel1_2 + + + &Server URL: + + + lineUpload + + + + + lineUpload + + + false + + + + + textLabel1_3 + + + Strip off the following directory prefix when uploading: + + + + + lineUploadPrefix + + + false + + + + + textLabel2 + + + Example: + + + + + lblUploadExample + + + false + + + + 0 + 0 + 0 + 0 + + + + + 500 + 10 + + + + AlwaysOff + + + AlwaysOff + + + + + + true + + + + + + + + + checkUID + + + Do not show users with a UID lower than + + + + + + + + layout6 + + + + unnamed + + + + spacer1_2_2 + + + Horizontal + + + Fixed + + + + 20 + 20 + + + + + + numUID + + + false + + + 1 + + + + + spacer4 + + + Horizontal + + + Expanding + + + + 60 + 20 + + + + + + + + spacer2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + + + checkProfilePrefix + toggled(bool) + lineProfilePrefix + setEnabled(bool) + + + checkUpload + toggled(bool) + lineUpload + setEnabled(bool) + + + checkUID + toggled(bool) + numUID + setEnabled(bool) + + + checkUpload + toggled(bool) + lineUploadPrefix + setEnabled(bool) + + + checkUpload + toggled(bool) + lblUploadExample + setEnabled(bool) + + + + + knuminput.h + knuminput.h + + 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 @@ + + + + + General + + Generic restrictions + + + + Disable Window Manager context menu (Alt-F3) + + The Window Manager context menu is normally shown when Alt-F3 is pressed + or when the menu button on the window frame is pressed. + + + + Disable Bookmarks + Disable Bookmarks in all applications. + + + Disable all tasks and applications that require root access + + 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. + + + + Disable access to a command shell + + 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. + + + + Disable Logout option + + 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. + + + + Disable Lock Screen option + + 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. + + + + Disable "Run Command" option (Alt-F2) + + 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. + + + + Disable toolbar moving + + Normally toolbars in applications can be moved around; when this option is chosen + all toolbars are fixed in their original positions. + + + + Disable execution of arbitrary .desktop files. + + 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. + + + + Disable starting of a second X session. + + 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. + + + + Disable input line history + + If a single account is used by multiple people it may be desirable to disable + the input line history out of privacy considerations. + + + + + + Desktop Icons + + Desktop Icons are provided by "kdesktop". + + + + + + + + + + Lock down Desktop Settings + + 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. + + + + Disable context menus + + 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. + + + + Lock down all Desktop icons + + 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. + + + + + Add additional vendor specific icons + + 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. + + + + + + Desktop Background + + Set up the Desktop Background also known as Wallpaper. + + + + + + + + + + Lock down Desktop Background Settings + + When the desktop background settings are locked down the user can no longer change them. + + + + + + + + + + + + + + Screen Saver + + Set up Screen Saver + + + + + + + + + + Lock down Screen Saver Settings + + When the Screen Saver settings are locked down the user can no longer change them. + + + + + Disable OpenGL-based Screen Savers + + OpenGL-based screen savers may cause problems on systems without decent OpenGL + support; with this option all such screensavers can be disabled. + + + + Discreet Screen Savers Only + + 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. + + + + + + KDE Menu + + The KDE Application menu + + + + + + + + + Disable all tasks and applications that require root access + + This option disables all menu items that require root access and that will ask the user for the root password. + + + + Disable menu editing + + 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. + + + + + + + Theming + + Set up of Fonts, Colors and Style + + + + + + + + + Lock down Style Settings + + When the Style settings are locked down the user can no longer change them. + + + + Lock down Color Settings + + When the Color settings are locked down the user can no longer change them. + + + + Lock down Font Settings + + When the Font settings are locked down the user can no longer change them. + + + + Lock down Window Decoration Settings + + When the Window Decoration settings are locked down the user can no longer change them. + + + + + + Panel + + The KDE panel "kicker" is normally found at the bottom of the screen. + + + + + + + + + + Lock down panel + + 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. + + + + Disable Context Menus + + This option disables the context menus that one normally gets when pressing the right mouse button in the panel. + + + + + + Network Proxy + + Set up of Network Proxy settings + + + + + + + + Lock down Proxy Settings + + When the Proxy settings are locked down the user can no longer change them. + + + + + + Konqueror + + Konqueror is a combined web- and filebrowser. + + + + Disable Properties in context menu + + This option can be used to disable the <i>Properties</i> option in the context menu for files. + + + + Disable Open With action + + This option can be used to disable the <i>Open With</i> menu option. + + + + Disable Open In New Tab action + + This option can be used to disable the <i>Open In New Tab</i> menu option. + + + + Disable file-browsing outside home directory + + This option can be used to prevent the user from browsing the + file system outside his or her own home directory. + + + + + + Menu Actions + + Common menu actions found in applications. + + + + Disable File -> %action + + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + + + + Disable File -> %action + + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + See also <i>Open Recent</i> + + + + Disable File -> %action + + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + + + + Disable File -> %action + + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + + + + Disable File -> %action + + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + + + + Disable File -> %action + + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + + + + Disable File -> %action + + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + + + + Disable File -> %action + + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + See also <i>Print Preview</i> + + + + Disable File -> %action + + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + + + + Disable File -> %action + + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + + + + Disable File -> %action + + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + This option has been added for completeness. + Usually the application can be terminated via the window manager as well. + + + + Disable Edit -> %action + + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + + + + Disable Edit -> %action + + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + + + + Disable Edit -> %action + + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + + + + Disable Edit -> %action + + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + + + + Disable Edit -> %action + + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + + + + Disable Edit -> %action + + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + + + + Disable Edit -> %action + + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + + + + Disable Edit -> %action + + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + + + + Disable Edit -> %action + + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + + + + Disable Edit -> %action + + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + + + + Disable Edit -> %action + + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + + + + Disable View -> %action + + This option can be used to remove the <i>View -> %action</i> menu-option from all applications. + + + + Disable View -> %action + + This option can be used to remove the <i>View -> %action</i> menu-option from all applications. + + + + Disable View -> %action + + This option can be used to remove the <i>View -> %action</i> menu-option from all applications. + + + + Disable View -> %action + + This option can be used to remove the <i>View -> %action</i> menu-option from all applications. + + + + Disable View -> %action + + This option can be used to remove the <i>View -> %action</i> menu-option from all applications. + + + + Disable View -> %action + + This option can be used to remove the <i>View -> %action</i> menu-option from all applications. + + + + Disable View -> %action + + This option can be used to remove the <i>View -> %action</i> menu-option from all applications. + + + + Disable View -> %action + + This option can be used to remove the <i>View -> %action</i> menu-option from all applications. + + + + Disable Go -> %action + + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + + + + Disable Go -> %action + + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + + + + Disable Go -> %action + + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + + + + Disable Go -> %action + + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + + + + Disable Go -> %action + + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + + + + Disable Go -> %action + + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + + + + Disable Go -> %action + + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + + + + Disable Go -> %action + + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + + + + Disable Go -> %action + + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + + + + Disable Go -> %action + + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + + + + Disable Go -> %action + + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + + + + Disable Bookmarks + + This option can be used to completely disable bookmarks in all applications. + + + + Disable Bookmarks -> %action + + This option can be used to prevent users from creating new bookmarks. + + + + Disable Bookmarks -> %action + + This option can be used to prevent users from editing bookmarks. + + + + Disable Tools -> %action + + This option can be used to remove the <i>Tools -> %action</i> menu-option from all applications. + + + + Disable Settings -> %action + + This option can be used to remove the <i>Settings -> %action</i> menu-option from all applications. + + + + Disable Settings -> %action + + This option can be used to remove the <i>Settings -> %action</i> menu-option from all applications. + + + + Disable Settings -> %action + + This option can be used to remove the <i>Settings -> %action</i> menu-option from all applications. + + + + Disable Settings -> %action + + This option can be used to remove the <i>Settings -> %action</i> menu-option from all applications. + + + + Disable Settings -> %action + + This option can be used to remove the <i>Settings -> %action</i> menu-option from all applications. + + + + Disable Settings -> Configure <Application> + + This option can be used to remove the <i>Settings -> Configure &lt;Application&gt;</i> menu-option from all applications. + + + + Disable Settings -> %action + + This option can be used to remove the <i>Settings -> %action</i> menu-option from all applications. + + + + Disable Settings -> %action + + This option can be used to remove the <i>Settings -> %action</i> menu-option from all applications. + + + + Disable Settings -> %action + + This option can be used to remove the <i>Settings -> %action</i> menu-option from all applications. + + + + Disable Help + + You can use this to completely disable the help menu + + + + Disable Help -> <Application> Handbook + + This option can be used to remove the <i>Help -> &lt;Application&gt; Handbook</i> menu-option from all applications. + + + + Disable Help -> %action + + This option can be used to remove the <i>Help -> %action</i> menu-option from all applications. + + + + Disable Help -> %action + + This option can be used to remove the <i>Help -> %action</i> menu-option from all applications. + + + + Disable Help -> About <Application> + + This option can be used to remove the <i>Help -> About &lt;Application&gt;</i> menu-option from all applications. + + + + Disable Help -> %action + + This option can be used to remove the <i>Help -> %action</i> menu-option from all applications. + + + + + + + Desktop Sharing + + Remote Desktop Sharing + + + + + + Lock down Desktop Sharing Settings + + When the setting for remote desktop sharing are locked down the user can no longer change them. + + + + + + File Associations + + Configure the applications used for opening files. + + + + + + Lock down File Associations Settings + + When the setting for file associations are locked down the user can no longer change + the default applications used for opening files. + + + + + + + + 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 + * + * 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 +#include + +#include +#include +#include +#include +#include + +QDict *ComponentAction::s_stdActionCaptions = 0; + +ComponentAction::ComponentAction() +{ +} + +ComponentAction::~ComponentAction() +{ +} + +static QDict *readStdActionCaptions() +{ + QDict *captions = new QDict; + 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("Could not find kiosk_data.xml"); + return false; + } + + QDomDocument doc; + QFile file( filename ); + if ( !file.open( IO_ReadOnly ) ) + { + m_errorMsg = i18n("Could not open %1").arg(filename); + return false; + } + + QString errorMsg; + int errorRow; + int errorCol; + if ( !doc.setContent( &file, &errorMsg, &errorRow, &errorCol ) ) + { + m_errorMsg = i18n("Syntax error in %1
Line %3, column %4: %2
").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 + * + * 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 +#include +#include + +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 subActions; + bool defaultValue; + + static QDict *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 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 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 + * + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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("Your system contains KDE configuration settings in the " + "skeleton directory %1. These files are copied to the " + "personal KDE settings directory of newly created users.

" + "This may interfere with the correct operation of user profiles.

" + "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.

" + "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.

" + "The following files were found under %2:").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(wid)) + wid->setAutoMask(true); + } + w->setBackgroundOrigin(WindowOrigin); + delete l; +} + +void KioskGui::setSubCaption(const QString &subCaption) +{ + m_view->subCaptionLabel->setText("

"+subCaption+"

"); +} + +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("You are about to delete the profile %1.

" + "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("Do you want to upload the profiles to %1 ?").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("All profiles have been successfully uploaded to %1").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 + * + * 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 + +#include +#include + +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 + * + * 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 +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kiosksync.h" + +#include +#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 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 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 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 map = newCfg.entryMap(*it); + for(QMap::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("The directory %1 could not be created because of an unspecified problem.

") + .arg(dir); + else + msg = i18n("The directory %1 could not be created because of the following problem:" + "

%2

") + .arg(dir, NETACCESS::lastErrorString()); + + msg += i18n("Without this directory your changes can not be saved.

" + "Do you want to retry creating the directory or abort the saving of changes?"); + + 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("The directory %1 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("The directory %1 could not be created because of an unspecified problem.

") + .arg(dest.prettyURL()); + else + msg = i18n("The directory %1 could not be created because of the following problem:" + "

%2

") + .arg(dest.prettyURL(), NETACCESS::lastErrorString()); + + msg += i18n("Without this directory your files can not be uploaded.

" + "Do you want to retry creating the directory or abort uploading?"); + + 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("The file %1 could not be installed because of an unspecified problem.") + .arg(destination); + else + msg = i18n("The file %1 could not be installed because of the following problem:" + "

%2

") + .arg(destination, NETACCESS::lastErrorString()); + + msg += i18n("Do you want to retry the installation or abort the saving of changes?"); + + 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("The file %1 could not be uploaded to %2 because of an unspecified problem.") + .arg(file, dest.prettyURL()); + else + msg = i18n("The file %1 could not be uploaded to %2 because of the following problem:" + "

%3

") + .arg(file, dest.prettyURL(),NETACCESS::lastErrorString()); + + msg += i18n("Do you want to retry or abort the uploading?"); + + 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("The file %1 could not be accessed because of an unspecified problem.") + .arg(settingsUrl.path()); + else + msg = i18n("The file %1 could not be accessed because of the following problem:" + "

%2

") + .arg(settingsUrl.path(), error); + + msg += i18n("Do you want to retry the operation or abort the saving of changes?"); + + 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("The profile directory %1 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 cfg_users = mapCfg.entryMap("Users"); + for ( QMap::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 + * + * 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 +#include +#include +#include +#include + +#include +#include + +#include + +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 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 m_saveConfigCache; + QDict 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 + * + * 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 +#include + +#include +#include +#include +#include + +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 %1 does not exist.").arg(_dir)); + return; + } + if (!dir.isReadable()) + { + emit warning(i18n("Directory %1 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 + * + * 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 +#include + +#include + +#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 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 + * + * 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 + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +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 @@ + + + + +

+ + + + + + + + diff --git a/kiosktool/logo.png b/kiosktool/logo.png new file mode 100644 index 0000000..f3163c0 Binary files /dev/null and b/kiosktool/logo.png 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 + * + * 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 + +#include + +#include +#include +#include +#include +#include +#include + +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 ", 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("KIOSK Admin Tool requires KDE 3.2.2 or later!

" + "With older versions you may experience problems with" + "the Setup 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 @@ + +MainView + + + MainView + + + + 0 + 0 + 573 + 526 + + + + + unnamed + + + 0 + + + + captionLabel + + + + 7 + 0 + 0 + 0 + + + + + 0 + 70 + + + + NoFrame + + + Plain + + + + + logoLabel + + + + 0 + 0 + 0 + 0 + + + + + 160 + 170 + + + + + + + + + subCaptionLabel + + + + 7 + 5 + 0 + 0 + + + + NoFrame + + + Plain + + + AlignCenter + + + + + spacer5 + + + Horizontal + + + Fixed + + + + 25 + 20 + + + + + + spacer5_2 + + + Horizontal + + + Fixed + + + + 25 + 20 + + + + + + layout4 + + + + unnamed + + + + widgetStack + + + + 7 + 7 + 0 + 1 + + + + + WStackPage + + + 0 + + + + + + frame3 + + + + 5 + 5 + 0 + 0 + + + + NoFrame + + + Raised + + + + unnamed + + + + pbHelp + + + &Help + + + + + spacer1 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + pbDiscard + + + &Discard Changes + + + + + spacer2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + pbFinished + + + &Finished + + + + + + + + + spacer3 + + + Horizontal + + + Fixed + + + + 160 + 20 + + + + + + + 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 + * + * 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + * + * 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 +#include + +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 + * + * 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 +#include + +#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(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(listView->firstChild()); + item; item = static_cast(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 + * + * 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 + +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 + * + * 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 +#include + +#include +#include +#include +#include +#include +#include +#include + +#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 + * + * 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 +#include + +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 + * + * 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 +#include + +#include +#include +#include +#include +#include +#include +#include + +#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("The user %1 is not an existing user.").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("The directory for this profile has changed " + "from %1 to %2.

" + "The following files under %3 will be moved to %4") + .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 + * + * 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 @@ + +ProfilePropsPageUI + + + Page2 + + + + 0 + 0 + 721 + 543 + + + + WindowOrigin + + + + unnamed + + + + spacer2 + + + Horizontal + + + Expanding + + + + 16 + 20 + + + + + + spacer1 + + + Horizontal + + + Expanding + + + + 60 + 20 + + + + + + frame3 + + + WindowOrigin + + + NoFrame + + + Raised + + + + unnamed + + + + textLabel2 + + + WindowOrigin + + + &Profile name: + + + editProfileName + + + + + editProfileName + + + + 400 + 0 + + + + + + spacer5_2 + + + Vertical + + + Fixed + + + + 20 + 20 + + + + + + textLabel3 + + + WindowOrigin + + + Short &description: + + + editDescription + + + + + editDescription + + + + 400 + 0 + + + + + + spacer5_2_2_3 + + + Vertical + + + Fixed + + + + 20 + 20 + + + + + + textLabel4_2 + + + WindowOrigin + + + &Files in this profile will be owned by: + + + kurlInstallDir + + + + + comboUser + + + + + spacer5_2_2_2 + + + Vertical + + + Fixed + + + + 20 + 20 + + + + + + textLabel4 + + + WindowOrigin + + + &Directory for this profile: + + + kurlInstallDir + + + + + kurlInstallDir + + + + 400 + 0 + + + + WindowOrigin + + + + + labelInstallDir + + + + + + + spacer5 + + + Vertical + + + Expanding + + + + 20 + 30 + + + + + + + + + + kcombobox.h + kpushbutton.h + klineedit.h + + 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 @@ + +ProfileSelectionPageUI + + + Page1 + + + + 0 + 0 + 656 + 362 + + + + WindowOrigin + + + Page1 + + + + unnamed + + + + spacer5 + + + Vertical + + + Fixed + + + + 20 + 20 + + + + + + + Profile + + + true + + + true + + + + + Description + + + true + + + true + + + + listProfile + + + + 7 + 7 + 0 + 1 + + + + + 300 + 220 + + + + WindowOrigin + + + true + + + true + + + + + spacer2_2 + + + Horizontal + + + Fixed + + + + 20 + 20 + + + + + + layout3 + + + + unnamed + + + + buttonAdd + + + Add &New Profile + + + + + spacer5_2 + + + Vertical + + + Fixed + + + + 20 + 10 + + + + + + buttonSetup + + + &Setup Profile + + + + + spacer5_2_3 + + + Vertical + + + Fixed + + + + 20 + 10 + + + + + + buttonUsers + + + &Assign Profiles + + + + + spacer6_2 + + + Vertical + + + MinimumExpanding + + + + 20 + 40 + + + + + + buttonProperty + + + &Profile Properties + + + + + spacer6 + + + Vertical + + + Fixed + + + + 20 + 10 + + + + + + buttonDelete + + + &Delete Profile + + + + + + + + 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 + * + * 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 + * + * 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 + +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 + * + * 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 +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#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("The profiles that you define here are automatically applied when the " + "user logs in to %1 or newer.

" + "If you want to use these profiles in combination with older versions you need " + "to manually set the $KDEDIRS environment variable from the startkde " + "script by adding the following line:

" + "export KDEDIRS=$(kiosktool-kdedirs)

").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("You already have a profile defined for group %1. " + "Do you want to replace it?").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("You already have a profile defined for user %1. " + "Do you want to replace it?").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 + * + * 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 @@ + +UserManagementGroupUI + + + UserManagementGroupUI + + + + 0 + 0 + 402 + 92 + + + + + unnamed + + + + labelCaption + + + Select the profile to use for all users in the specified group. + + + + + spacer3 + + + Vertical + + + Expanding + + + + 20 + 10 + + + + + + layout2 + + + + unnamed + + + + labelGroup + + + Group: + + + + + comboGroup + + + + + spacer1 + + + Horizontal + + + Fixed + + + + 20 + 20 + + + + + + labelProfile + + + Profile: + + + + + comboProfile + + + + + spacer2 + + + Horizontal + + + Expanding + + + + 51 + 20 + + + + + + + + + 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 @@ + +UserManagementUserUI + + + UserManagementUserUI + + + + 0 + 0 + 402 + 92 + + + + + unnamed + + + + labelCaption + + + Select the profile to use for the specified user. + + + + + spacer3 + + + Vertical + + + Expanding + + + + 20 + 10 + + + + + + layout2 + + + + unnamed + + + + labelUser + + + User: + + + + + comboUser + + + + + spacer1 + + + Horizontal + + + Fixed + + + + 20 + 20 + + + + + + labelProfile + + + Profile: + + + + + comboProfile + + + + + spacer2 + + + Horizontal + + + Expanding + + + + 51 + 20 + + + + + + + + + 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 @@ + +UserManagementUI + + + UserManagementUI + + + + 0 + 0 + 600 + 659 + + + + + unnamed + + + + groupBox3 + + + Default Policy + + + + unnamed + + + + textLabel1 + + + + 0 + 0 + + + + Profile used for users with no assigned profile: + + + + + kLineEdit1 + + + default + + + true + + + + + + + groupBox1 + + + Group Policies + + + + unnamed + + + + + Group + + + true + + + true + + + + + Profile + + + true + + + true + + + + listGroups + + + + 350 + 0 + + + + true + + + true + + + + + layout1 + + + + unnamed + + + + buttonAddGroup + + + &Add Group Policy... + + + + + spacer2 + + + Vertical + + + Fixed + + + + 20 + 20 + + + + + + buttonDeleteGroup + + + &Delete Group Policy + + + + + spacer1 + + + Vertical + + + Expanding + + + + 20 + 31 + + + + + + + + + + groupBox2 + + + Individual User Policies + + + + unnamed + + + + + User + + + true + + + true + + + + + Profile + + + true + + + true + + + + listUsers + + + true + + + true + + + + + layout1_2 + + + + unnamed + + + + buttonAddUser + + + &Add User Policy... + + + + + spacer2_2 + + + Vertical + + + Fixed + + + + 20 + 20 + + + + + + buttonDeleteUser + + + &Delete User Policy + + + + + spacer1_2 + + + Vertical + + + Expanding + + + + 20 + 31 + + + + + + + + + + + -- cgit v1.2.3