diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2013-02-01 17:25:31 -0600 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2013-02-01 17:25:31 -0600 |
commit | 3c66b171a6f0ad667c538fd727bbcef54af71d37 (patch) | |
tree | ae80c2d1cb16b92fb7d5a73bbe5ce34fbc5ae016 /kiostdetool | |
parent | 867b7c23aa5ee22368683f23635ded9506587069 (diff) | |
download | kiosktool-3c66b171a6f0ad667c538fd727bbcef54af71d37.tar.gz kiosktool-3c66b171a6f0ad667c538fd727bbcef54af71d37.zip |
Fix FTBFS
Diffstat (limited to 'kiostdetool')
66 files changed, 9734 insertions, 0 deletions
diff --git a/kiostdetool/Makefile.am b/kiostdetool/Makefile.am new file mode 100644 index 0000000..47756e9 --- /dev/null +++ b/kiostdetool/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-tdedirs + +# set the include path for X, qt and KDE +INCLUDES = $(all_includes) + +# the library search path. +kiosktool_LDFLAGS = $(KDE_RPATH) $(all_libraries) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor + +# the libraries to link against. +kiosktool_LDADD = $(LIB_TDEFILE) -ltdeprint + +# 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_tdedirs_LDFLAGS = $(KDE_RPATH) $(all_libraries) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor + +# the libraries to link against. +kiosktool_tdedirs_LDADD = $(LIB_TDECORE) + +# which sources should be compiled for kiosktool +kiosktool_tdedirs_SOURCES = kiosktool-tdedirs.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)/tdeiosktool.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)/tdeiosktool +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/kiostdetool/background.png b/kiostdetool/background.png Binary files differnew file mode 100644 index 0000000..0341206 --- /dev/null +++ b/kiostdetool/background.png diff --git a/kiostdetool/caption-da.png b/kiostdetool/caption-da.png Binary files differnew file mode 100644 index 0000000..7894085 --- /dev/null +++ b/kiostdetool/caption-da.png diff --git a/kiostdetool/caption-empty.png b/kiostdetool/caption-empty.png Binary files differnew file mode 100644 index 0000000..07a6a3a --- /dev/null +++ b/kiostdetool/caption-empty.png diff --git a/kiostdetool/caption-et.png b/kiostdetool/caption-et.png Binary files differnew file mode 100644 index 0000000..8cba1b3 --- /dev/null +++ b/kiostdetool/caption-et.png diff --git a/kiostdetool/caption-pt.png b/kiostdetool/caption-pt.png Binary files differnew file mode 100644 index 0000000..db57843 --- /dev/null +++ b/kiostdetool/caption-pt.png diff --git a/kiostdetool/caption-pt_BR.png b/kiostdetool/caption-pt_BR.png Binary files differnew file mode 100644 index 0000000..db57843 --- /dev/null +++ b/kiostdetool/caption-pt_BR.png diff --git a/kiostdetool/caption-sv.png b/kiostdetool/caption-sv.png Binary files differnew file mode 100644 index 0000000..358cad3 --- /dev/null +++ b/kiostdetool/caption-sv.png diff --git a/kiostdetool/caption.png b/kiostdetool/caption.png Binary files differnew file mode 100644 index 0000000..0ce1c8d --- /dev/null +++ b/kiostdetool/caption.png diff --git a/kiostdetool/component.cpp b/kiostdetool/component.cpp new file mode 100644 index 0000000..00b98bc --- /dev/null +++ b/kiostdetool/component.cpp @@ -0,0 +1,52 @@ +/* + * component.cpp + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "component.h" + +Component::Component( TQObject *parent) + : TQObject(parent) +{ +} + +Component::~Component() +{ +} + +void +Component::slotSetupPrepare() +{ +} + +void +Component::slotSetupStarted() +{ +} + +void +Component::slotPreviewStarted() +{ +} + +bool +Component::setupFinished() +{ + return true; +} + +#include "component.moc" diff --git a/kiostdetool/component.h b/kiostdetool/component.h new file mode 100644 index 0000000..febcd81 --- /dev/null +++ b/kiostdetool/component.h @@ -0,0 +1,41 @@ +/* + * component.h + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _COMPONENT_H_ +#define _COMPONENT_H_ + +#include <tqobject.h> + +class Component : public TQObject +{ + Q_OBJECT + +public: + Component( TQObject *parent); + virtual ~Component(); + + virtual bool setupFinished(); + +public slots: + + virtual void slotSetupPrepare(); + virtual void slotSetupStarted(); + virtual void slotPreviewStarted(); +}; + +#endif diff --git a/kiostdetool/componentPage.cpp b/kiostdetool/componentPage.cpp new file mode 100644 index 0000000..915a3e3 --- /dev/null +++ b/kiostdetool/componentPage.cpp @@ -0,0 +1,306 @@ +/* + * componentPage.cpp + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "componentPage.h" + +#include <tqcursor.h> +#include <tqfileinfo.h> +#include <tqlabel.h> +#include <tqstylesheet.h> +#include <tqtextedit.h> +#include <tqpushbutton.h> + +#include <dcopref.h> + +#include <kapplication.h> +#include <kdebug.h> +#include <klistview.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kprocess.h> +#include <kstdguiitem.h> + +#include "component.h" +#include "kioskdata.h" +#include "kioskrun.h" + +ComponentPage::ComponentPage( ComponentData *data, Component *component, TQWidget* parent, const char* name, WFlags fl ) + : ComponentPageUI(parent, name, fl), PageWidget(this), m_data(data), m_component(component) +{ + m_process = 0; + connect(pbSetup, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotSetup())); + connect(pbPreview, TQT_SIGNAL(clicked()), this, TQT_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; + TQTimer::singleShot(0, this, TQT_SLOT(slotShowNotice())); + } + } + + fillActionList(listComponentConfig, m_data); + + connect(listComponentConfig, TQT_SIGNAL(currentChanged(TQListViewItem *)), + this, TQT_SLOT(slotShowAction(TQListViewItem *))); + 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(); +} + +TQString ComponentPage::subCaption() +{ + return i18n("Setup %1").arg(m_data->caption); +} + +void ComponentPage::slotSetup() +{ + if (m_process) + { + m_process->kill(); + delete m_process; + } + TQCString dcopApp = m_data->setup.dcop.utf8(); + TQCString dcopObj = "qt/" + dcopApp; + if (!dcopApp.isEmpty() && m_data->setup.hasOption("restart")) + DCOPRef(dcopApp, dcopObj).call("quit"); + + TQApplication::setOverrideCursor( TQCursor(TQt::WaitCursor) ); + if (!KioskRun::self()->prepare()) + { + TQApplication::restoreOverrideCursor(); + KMessageBox::sorry(this, + i18n("<qt>There was an unexpected problem with the runtime environment.</qt>")); + return; + } + KioskRun::self()->makeMutable(true); + if (!save()) + { + TQApplication::restoreOverrideCursor(); + return; + } + if (m_component) + m_component->slotSetupPrepare(); + KioskRun::self()->updateSycoca(); + TQApplication::restoreOverrideCursor(); + + if (!dcopApp.isEmpty()) + { + KioskRun::self()->dcopClient()->setNotifications(true); + connect(KioskRun::self()->dcopClient(), TQT_SIGNAL(applicationRegistered( const TQCString& )), + this, TQT_SLOT(slotSetupAppRegistered( const TQCString& ))); + } + + TQStringList args; + if (m_data->setup.hasOption("nofork")) + args << "--nofork"; + + args += m_data->setup.args; + + m_process = KioskRun::self()->run(m_data->setup.exec, args); + int result = KMessageBox::questionYesNo(this, + i18n("<qt>You can now configure %1. " + "When you are finished click <b>Save</b> to make the new configuration permanent.") + .arg(m_data->caption), i18n("%1 Setup").arg(m_data->caption), + KStdGuiItem::save(), KStdGuiItem::discard()); + m_saveSettings = (result == KMessageBox::Yes); + if (!dcopApp.isEmpty()) + KioskRun::self()->dcopRef(dcopApp, dcopObj).call("quit"); + + if (m_process->isRunning()) + { + connect(m_process, TQT_SIGNAL(processExited(TDEProcess *)), this, TQT_SLOT(slotPreviewDone())); + } + else + { + slotSetupDone(); + } +} + +void ComponentPage::slotSetupDone() +{ + delete m_process; + m_process = 0; + + KioskRun::self()->dcopClient()->setNotifications(false); + disconnect(KioskRun::self()->dcopClient(), TQT_SIGNAL(applicationRegistered( const TQCString& )), + this, TQT_SLOT(slotSetupAppRegistered( const TQCString& ))); + + KioskRun::self()->makeMutable(false); + if (m_saveSettings) + { + bool result = true; + if (m_component) + result = m_component->setupFinished(); + + if (!result) return; + + // Find new config files. + TQStringList newFiles = KioskRun::self()->newConfigFiles(); + for(TQStringList::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")) + TDEApplication::tdeinitExec(m_data->setup.exec); +} + +void ComponentPage::slotSetupAppRegistered( const TQCString &appid) +{ + TQCString 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; + } + TQCString dcopApp = m_data->preview.dcop.utf8(); + TQCString dcopObj = "qt/" + dcopApp; + if (!dcopApp.isEmpty() && m_data->preview.hasOption("restart")) + DCOPRef(dcopApp, dcopObj).call("quit"); + + TQApplication::setOverrideCursor( TQCursor(TQt::WaitCursor) ); + KioskRun::self()->prepare(); + save(); + KioskRun::self()->updateSycoca(); + TQApplication::restoreOverrideCursor(); + + if (!dcopApp.isEmpty()) + { + KioskRun::self()->dcopClient()->setNotifications(true); + connect(KioskRun::self()->dcopClient(), TQT_SIGNAL(applicationRegistered( const TQCString& )), + this, TQT_SLOT(slotPreviewAppRegistered( const TQCString& ))); + } + + TQStringList args; + if (m_data->preview.hasOption("nofork")) + args << "--nofork"; + + args += m_data->preview.args; + + m_process = KioskRun::self()->run(m_data->preview.exec, args); + KMessageBox::information(this, + i18n("<qt>This is how %1 will behave and look with the new settings. " + "Any changes you now make to the settings will not be saved.<p>" + "Click <b>Ok</b> to return to your own personal %2 configuration.") + .arg(m_data->caption, m_data->caption), i18n("%1 Preview").arg(m_data->caption)); + if (!dcopApp.isEmpty()) + KioskRun::self()->dcopRef(dcopApp, dcopObj).call("quit"); + + if (m_process->isRunning()) + { + connect(m_process, TQT_SIGNAL(processExited(TDEProcess *)), this, TQT_SLOT(slotPreviewDone())); + } + else + { + slotPreviewDone(); + } +} + +void ComponentPage::slotPreviewAppRegistered( const TQCString &appid) +{ + TQCString 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(), TQT_SIGNAL(applicationRegistered( const TQCString& )), + this, TQT_SLOT(slotPreviewAppRegistered( const TQCString& ))); + + delete m_process; + m_process = 0; + if (m_data->preview.hasOption("restart")) + TDEApplication::tdeinitExec(m_data->preview.exec); +} + +void ComponentPage::slotShowAction(TQListViewItem *item) +{ + ComponentActionItem *actionItem = dynamic_cast<ComponentActionItem*>(item); + TQString description; + if (actionItem) + { + description = "<h2>"+TQStyleSheet::escape(actionItem->action()->caption)+"</h2>\n"; + description += actionItem->action()->description; + } + componentDescription->setText(description); +} + +#include "componentPage.moc" diff --git a/kiostdetool/componentPage.h b/kiostdetool/componentPage.h new file mode 100644 index 0000000..8e0e716 --- /dev/null +++ b/kiostdetool/componentPage.h @@ -0,0 +1,66 @@ +/* + * componentPage.h + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _COMPONENTPAGE_H_ +#define _COMPONENTPAGE_H_ + +#include "componentPage_ui.h" +#include "pageWidget.h" + +class TDEProcess; +class Component; +class ComponentData; + +class ComponentPage : public ComponentPageUI, public PageWidget +{ + Q_OBJECT + +public: + ComponentPage( ComponentData *data, Component *component, TQWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~ComponentPage(); + + virtual void load(); + virtual bool save(); + + virtual void setFocus(); + + virtual TQString subCaption(); + +public slots: + void slotSetup(); + void slotPreview(); + +protected slots: + void slotShowNotice(); + void slotSetupDone(); + void slotPreviewDone(); + void slotShowAction(TQListViewItem *item); + void slotSetupAppRegistered( const TQCString &appid); + void slotPreviewAppRegistered( const TQCString &appid); + +protected: + void prepareMutableFiles(); + +private: + TDEProcess *m_process; + ComponentData *m_data; + Component *m_component; + bool m_saveSettings; +}; + +#endif diff --git a/kiostdetool/componentPage_ui.ui b/kiostdetool/componentPage_ui.ui new file mode 100644 index 0000000..c305237 --- /dev/null +++ b/kiostdetool/componentPage_ui.ui @@ -0,0 +1,195 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ComponentPageUI</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>ComponentPageUI</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>559</width> + <height>372</height> + </rect> + </property> + <property name="backgroundOrigin"> + <enum>WindowOrigin</enum> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="3" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>componentDescription</cstring> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>140</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>140</height> + </size> + </property> + <property name="frameShape"> + <enum>StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + <spacer row="2" column="1"> + <property name="name"> + <cstring>spacer8</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="TQLayoutWidget" row="1" column="3"> + <property name="name"> + <cstring>layout1</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQPushButton"> + <property name="name"> + <cstring>pbSetup</cstring> + </property> + <property name="text"> + <string>&Setup XXX</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer8_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="TQPushButton"> + <property name="name"> + <cstring>pbPreview</cstring> + </property> + <property name="text"> + <string>&Preview XXX</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer8_3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>21</width> + <height>171</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <spacer row="1" column="2"> + <property name="name"> + <cstring>spacer7</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TDEListView" row="1" column="0" rowspan="1" colspan="2"> + <column> + <property name="text"> + <string>Restriction</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>listComponentConfig</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>1</horstretch> + <verstretch>1</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>300</width> + <height>150</height> + </size> + </property> + <property name="backgroundOrigin"> + <enum>WindowOrigin</enum> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="fullWidth"> + <bool>true</bool> + </property> + </widget> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Enable &restrictions:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>listComponentConfig</cstring> + </property> + </widget> + </grid> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kiostdetool/componentSelectionPage.cpp b/kiostdetool/componentSelectionPage.cpp new file mode 100644 index 0000000..43ee39f --- /dev/null +++ b/kiostdetool/componentSelectionPage.cpp @@ -0,0 +1,143 @@ +/* + * componentSelectionPage.cpp + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "componentSelectionPage.h" + +#include <tqpushbutton.h> + +#include <kapplication.h> +#include <tdeconfig.h> +#include <kiconloader.h> +#include <kiconview.h> +#include <klocale.h> + +#include "kioskdata.h" + +class ComponentViewItem : public TQIconViewItem +{ +public: + ComponentViewItem( TQIconView * parent, const TQString & text, const TQPixmap & icon, const TQString & _id ) + : TQIconViewItem( parent, text, icon), id(_id) + { + } + + TQString id; +}; + +ComponentSelectionPage::ComponentSelectionPage( KioskData *data, TQWidget* parent, const char* name, WFlags fl ) + : ComponentSelectionPageUI(parent, name, fl), PageWidget(this), m_data(data) +{ + listComponent->setSelectionMode(TQIconView::Single); + listComponent->setItemsMovable(false); + listComponent->setSpacing(20); + listComponent->setGridX(110); + listComponent->setGridY(75); + loadComponentList(); + connect(listComponent, TQT_SIGNAL(clicked(TQIconViewItem *)), this, TQT_SLOT(slotComponentActivated(TQIconViewItem *))); + connect(listComponent, TQT_SIGNAL(returnPressed (TQIconViewItem *)), this, TQT_SLOT(slotComponentActivated(TQIconViewItem *))); + connect(pbSetup, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotComponentActivated())); +} + +ComponentSelectionPage::~ComponentSelectionPage() +{ +} + +void ComponentSelectionPage::load() +{ +} + +bool ComponentSelectionPage::save() +{ + TDEConfig *config = kapp->config(); + config->setGroup("General"); + config->writeEntry("CurrentComponent", currentComponent()); + config->sync(); + return true; +} + +void ComponentSelectionPage::setFocus() +{ +} + +TQString ComponentSelectionPage::subCaption() +{ + return TQString(); +} + +void ComponentSelectionPage::loadComponentList() +{ + listComponent->clear(); + for(TQStringList::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; + TQPixmap icon = DesktopIcon( data->icon, KIcon::SizeMedium ); + new ComponentViewItem(listComponent, data->caption, icon, data->id); + } +} + +bool ComponentSelectionPage::hasSelection() +{ + return !currentComponent().isEmpty(); +} + +TQString ComponentSelectionPage::currentComponent() +{ + ComponentViewItem *item = static_cast<ComponentViewItem *>(listComponent->firstItem()); + while(item) + { + if (item->isSelected()) + return item->id; + + item = static_cast<ComponentViewItem *>(item->nextItem()); + } + return TQString(); +} + +void ComponentSelectionPage::setCurrentComponent(const TQString &id) +{ + ComponentViewItem *item = static_cast<ComponentViewItem *>(listComponent->firstItem()); + while(item) + { + if (item->id == id) + { + listComponent->setSelected(item, true); + return; + } + item = static_cast<ComponentViewItem *>(item->nextItem()); + } + if (listComponent->firstItem()) + listComponent->setSelected(listComponent->firstItem(), true); +} + +void ComponentSelectionPage::slotComponentActivated(TQIconViewItem *item) +{ + if (item) + emit componentActivated(); +} + +void ComponentSelectionPage::slotComponentActivated() +{ + if (!currentComponent().isEmpty()) + emit componentActivated(); +} + +#include "componentSelectionPage.moc" diff --git a/kiostdetool/componentSelectionPage.h b/kiostdetool/componentSelectionPage.h new file mode 100644 index 0000000..c9366de --- /dev/null +++ b/kiostdetool/componentSelectionPage.h @@ -0,0 +1,60 @@ +/* + * componentSelectionPage.h + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _COMPONENTSELECTIONPAGE_H_ +#define _COMPONENTSELECTIONPAGE_H_ + +#include "componentSelectionPage_ui.h" +#include "pageWidget.h" + +class KioskData; + +class ComponentSelectionPage : public ComponentSelectionPageUI, public PageWidget +{ + Q_OBJECT + +public: + ComponentSelectionPage( KioskData *data, TQWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~ComponentSelectionPage(); + + virtual void load(); + virtual bool save(); + + virtual void setFocus(); + + virtual TQString subCaption(); + + void setCurrentComponent(const TQString &); + TQString currentComponent(); + +signals: + void componentActivated(); + +protected: + void loadComponentList(); + bool hasSelection(); + +protected slots: + void slotComponentActivated(TQIconViewItem *item); + void slotComponentActivated(); + +private: + KioskData *m_data; +}; + +#endif diff --git a/kiostdetool/componentSelectionPage_ui.ui b/kiostdetool/componentSelectionPage_ui.ui new file mode 100644 index 0000000..be874a4 --- /dev/null +++ b/kiostdetool/componentSelectionPage_ui.ui @@ -0,0 +1,124 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ComponentSelectionPageUI</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>ComponentSelectionPageUI</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>682</width> + <height>373</height> + </rect> + </property> + <property name="backgroundOrigin"> + <enum>WindowOrigin</enum> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="1" column="2"> + <property name="name"> + <cstring>spacer2_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <spacer row="2" column="1"> + <property name="name"> + <cstring>spacer5</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQLayoutWidget" row="1" column="3"> + <property name="name"> + <cstring>layout1</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQPushButton"> + <property name="name"> + <cstring>pbSetup</cstring> + </property> + <property name="text"> + <string>&Setup Component</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer5_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>211</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="TQIconView" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>listComponent</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>400</width> + <height>200</height> + </size> + </property> + </widget> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Select &component:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>listComponent</cstring> + </property> + </widget> + </grid> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kiostdetool/configure.in.in b/kiostdetool/configure.in.in new file mode 100644 index 0000000..84cf170 --- /dev/null +++ b/kiostdetool/configure.in.in @@ -0,0 +1,2 @@ +AC_CHECK_SETENV +AC_CHECK_UNSETENV diff --git a/kiostdetool/cr16-app-kiostdetool.png b/kiostdetool/cr16-app-kiostdetool.png Binary files differnew file mode 100644 index 0000000..ccd2b43 --- /dev/null +++ b/kiostdetool/cr16-app-kiostdetool.png diff --git a/kiostdetool/cr32-app-kiostdetool.png b/kiostdetool/cr32-app-kiostdetool.png Binary files differnew file mode 100644 index 0000000..a987516 --- /dev/null +++ b/kiostdetool/cr32-app-kiostdetool.png diff --git a/kiostdetool/cr48-app-kiostdetool.png b/kiostdetool/cr48-app-kiostdetool.png Binary files differnew file mode 100644 index 0000000..87e18dd --- /dev/null +++ b/kiostdetool/cr48-app-kiostdetool.png diff --git a/kiostdetool/desktopComponent.cpp b/kiostdetool/desktopComponent.cpp new file mode 100644 index 0000000..5456687 --- /dev/null +++ b/kiostdetool/desktopComponent.cpp @@ -0,0 +1,239 @@ +/* + * desktopComponent.cpp + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "desktopComponent.h" + +#include <tqdir.h> +#include <tqfileinfo.h> + +#include <kdebug.h> +#include <kmimetype.h> +#include <kprocess.h> +#include <ksimpleconfig.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kurl.h> + +#include "kioskrun.h" + +DesktopComponent::DesktopComponent( TQObject *parent) + : Component(parent) +{ +} + +DesktopComponent::~DesktopComponent() +{ +} + +void +DesktopComponent::slotSetupPrepare() +{ + m_iconPositionsFile = KioskRun::self()->locateLocal("data", "kdesktop/IconPositions"); + ::unlink(TQFile::encodeName(m_iconPositionsFile)); + connect(&m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotSetupStarted())); +} + +void +DesktopComponent::slotSetupStarted() +{ + TQString desktop = KioskRun::self()->desktopPath(); + TQFileInfo info(desktop); + if (info.exists()) + { + disconnect(&m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotSetupStarted())); + connect(&m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotSetupReady())); + m_timer.start(1000, true); + } + else + { + m_timer.start(500, true); + } +} + +void filterFileList(const TQString &path, TQStringList *files, TQStringList *oldFiles) +{ + files->remove("."); + files->remove(".."); + + TQStringList::Iterator next; + for(TQStringList::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() +{ + TQString desktop = KioskRun::self()->desktopPath(); + + TQDir dir(desktop); + m_origDesktopFiles = dir.entryList(TQDir::All, TQDir::Unsorted); + + filterFileList(desktop, &m_origDesktopFiles, 0); +} + +bool +DesktopComponent::setupFinished() +{ + bool result = true; + + disconnect(&m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotSetupStarted())); + disconnect(&m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotSetupReady())); + m_timer.stop(); + + KSimpleConfig newCfg(m_iconPositionsFile, true); + + TQString desktop = KioskRun::self()->desktopPath(); + + TQDir dir(desktop); + TQStringList newDesktopFiles = dir.entryList(TQDir::All, TQDir::Unsorted); + filterFileList(desktop, &newDesktopFiles, &m_origDesktopFiles); + + KTempFile positionsFile; + positionsFile.close(); + + KSimpleConfig positions(positionsFile.name()); + + TQStringList newGroups = newCfg.groupList(); + + TQString prefix = "IconPosition::"; + + // Save icon positions + for(TQStringList::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 + TQStringList::Iterator next; + for(TQStringList::Iterator it = m_origDesktopFiles.begin(); + it != m_origDesktopFiles.end(); it = next) + { + next = it; + next++; + + if (newDesktopFiles.remove(*it)) + { + m_origDesktopFiles.remove(it); + continue; + } + + } + + TQString installPath = KioskRun::self()->locateSave("data", "kdesktop/Desktop/"); + TQString installPath2 = KioskRun::self()->locateSave("data", "kdesktop/DesktopLinks/"); + + // Remove all icons that are no longer + for(TQStringList::Iterator it = m_origDesktopFiles.begin(); + it != m_origDesktopFiles.end(); ++it) + { + TQString file; + if (TQFile::exists(installPath + *it)) + file = installPath + *it; + else if (TQFile::exists(installPath2 + *it)) + file = installPath2 + *it; + + if (!file.isEmpty()) + { + result = KioskRun::self()->remove(file); + if (!result) return false; + positions.deleteGroup(prefix+*it); + } + else + { + TQString 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(TQStringList::Iterator it = newDesktopFiles.begin(); + it != newDesktopFiles.end(); ++it) + { + TQString file = KioskRun::self()->desktopPath() + *it; + if (TQFile::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/kiostdetool/desktopComponent.h b/kiostdetool/desktopComponent.h new file mode 100644 index 0000000..1b28c13 --- /dev/null +++ b/kiostdetool/desktopComponent.h @@ -0,0 +1,51 @@ +/* + * desktopComponent.h + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _DESKTOPCOMPONENT_H_ +#define _DESKTOPCOMPONENT_H_ + +#include "component.h" + +#include <tqstringlist.h> +#include <tqtimer.h> + +class DesktopComponent: public Component +{ + Q_OBJECT + +public: + DesktopComponent( TQObject *parent = 0); + virtual ~DesktopComponent(); + + virtual bool setupFinished(); + +public slots: + + virtual void slotSetupPrepare(); + virtual void slotSetupStarted(); + +protected slots: + void slotSetupReady(); + +private: + TQTimer m_timer; + TQString m_iconPositionsFile; + TQStringList m_origDesktopFiles; +}; + +#endif diff --git a/kiostdetool/extractxml b/kiostdetool/extractxml new file mode 100755 index 0000000..629ab1d --- /dev/null +++ b/kiostdetool/extractxml @@ -0,0 +1,120 @@ +#! /usr/bin/perl +# +# This script extracts messages from kiosk_data.xml +# and writes on standard output (usually redirected to rc.cpp) +# the equivalent i18n() calls so that xgettext can parse them. +# +# It is based on extractrc but differs in the following ways: +# *) Extracts <caption> and <description> tags +# *) Performs equivalent of QString::simplifyWhiteSpace on all strings +# +# known flags: +# --tag=name : extract also the tag name +# --context=name : give all i18n calls a context name: i18n( "name",...) + +$filename = ""; +@filenames = (); + +sub writeoutstring +{ + print STDOUT "i18n(\""; + if (@_[0]) + { + # We have a I18N context + print STDOUT @_[0]; + print STDOUT "\",\""; + } + print STDOUT @_[1]; + print STDOUT "\"); // $filename \n"; +} + +$extratags = ""; +$context = ""; # I18N context + +ARGUMENTS: while (defined ($ARGV[0])) +{ + $_ = shift; + + if (/^--tag=(\w+)/) # --tag=name + { + $extratags .= "|" . $1; + next ARGUMENTS; + } + elsif (/^--context=(\w+)/) # --context=name + { + $context = $1; + next ARGUMENTS; + } + + $filename = $_; # maybe check for more options + +if (! $filename) { + print STDERR "no file to open\n"; + exit 1; +} + +$string = ""; +$intext = 0; +$linenr = 0; +$inskippedprop = 0; + +open(FILE, $filename); + +READING: while ( <FILE> ) { + $linenr++; + if ($linenr == 1 && ($_ !~ /^<!DOCTYPE/) && ($_ !~ /^<\?xml/)) { + last READING; + } + + $string .= "\\n" . $_; + chomp($string); + + $textstring = '(caption|description' . $extratags .')>'; + + # The 'database' property contains strings that shouldn't be translated + if ($inskippedprop == 0 && ($string =~ /<property name=\"database\"/ || $string=~ /<property name=\"associations\"/)) { + $inskippedprop = 1; + } elsif ($inskippedprop == 1 && ($string =~ /<\/property/)) { + $inskippedprop = 0; + $string = ""; + } + + if ($inskippedprop == 0 && $intext == 0) { + if ($string =~ /<$textstring/) { + $string =~ s/^.*<$textstring//; + $intext = 1; + $starting_linenr = $linenr; + } else { + $string = ""; + } + } + + if (($intext == 1) && ($string =~ /<\/$textstring/)) { + my $text = $string; + $text =~ s/<\/$textstring.*$//; + $text =~ s/</</g; + $text =~ s/>/>/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 <text> floating $filename\n"; + } + } + +} + +if ($intext == 1) { + print STDERR "parsing error in $filename $linenr\n"; + exit 1; +} + +} diff --git a/kiostdetool/filetypeeditComponent.cpp b/kiostdetool/filetypeeditComponent.cpp new file mode 100644 index 0000000..ce9b815 --- /dev/null +++ b/kiostdetool/filetypeeditComponent.cpp @@ -0,0 +1,133 @@ +/* + * filetypeeditComponent.cpp + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "filetypeeditComponent.h" + +#include <tqdir.h> +#include <tqdom.h> +#include <tqfileinfo.h> + +#include <kapplication.h> +#include <kdebug.h> +#include <kmimetype.h> +#include <kprocess.h> +#include <ksavefile.h> +#include <ksimpleconfig.h> +#include <kstandarddirs.h> +#include <kurl.h> + +#include "kioskrun.h" +#include "kiosksync.h" + +FileTypeEditComponent::FileTypeEditComponent( TQObject *parent) + : Component(parent) +{ +} + +FileTypeEditComponent::~FileTypeEditComponent() +{ +} + +void +FileTypeEditComponent::slotSetupPrepare() +{ +} + +void +FileTypeEditComponent::slotSetupStarted() +{ +} + +bool +FileTypeEditComponent::setupFinished() +{ + bool result; + + // Install mimetype files + { + TQString mimetypeFiles = KioskRun::self()->locateLocal("mime", TQString()); + TQString mimetypeSaveFiles = KioskRun::self()->locateSave("mime", TQString()); + + KioskSync mimeDir(kapp->mainWidget()); + mimeDir.addDir(mimetypeFiles, KURL()); + + TQStringList newMimetypeFiles = mimeDir.listFiles(); + + for(TQStringList::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 + { + TQString legacyApplications = KioskRun::self()->locateLocal("apps", TQString()); + TQString legacySaveApplications = KioskRun::self()->locateSave("apps", TQString()); + + KioskSync legacyDir(kapp->mainWidget()); + legacyDir.addDir(legacyApplications, KURL()); + + TQStringList newLegacyApplications = legacyDir.listFiles(); + + for(TQStringList::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 + { + TQString xdgApplications = KioskRun::self()->locateLocal("xdgdata-apps", TQString()); + TQString xdgSaveApplications = KioskRun::self()->locateSave("xdgdata-apps", TQString()); + + TQDir dir(xdgApplications); + TQStringList newXdgApplications = dir.entryList(TQDir::All, TQDir::Unsorted); + newXdgApplications.remove("."); + newXdgApplications.remove(".."); + + for(TQStringList::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/kiostdetool/filetypeeditComponent.h b/kiostdetool/filetypeeditComponent.h new file mode 100644 index 0000000..2113bbd --- /dev/null +++ b/kiostdetool/filetypeeditComponent.h @@ -0,0 +1,43 @@ +/* + * filetypeeditComponent.h + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _FILETYPEEDITCOMPONENT_H_ +#define _FILETYPEEDITCOMPONENT_H_ + +#include "component.h" + +#include <tqstringlist.h> +#include <tqtimer.h> + +class FileTypeEditComponent: public Component +{ + Q_OBJECT + +public: + FileTypeEditComponent( TQObject *parent = 0); + virtual ~FileTypeEditComponent(); + + virtual bool setupFinished(); + +public slots: + + virtual void slotSetupPrepare(); + virtual void slotSetupStarted(); +}; + +#endif diff --git a/kiostdetool/kcms/Makefile.am b/kiostdetool/kcms/Makefile.am new file mode 100644 index 0000000..335ab60 --- /dev/null +++ b/kiostdetool/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/kiostdetool/kcms/autostart/Makefile.am b/kiostdetool/kcms/autostart/Makefile.am new file mode 100644 index 0000000..993941a --- /dev/null +++ b/kiostdetool/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/kiostdetool/kcms/autostart/kcmautostart.cpp b/kiostdetool/kcms/autostart/kcmautostart.cpp new file mode 100644 index 0000000..77dbc6e --- /dev/null +++ b/kiostdetool/kcms/autostart/kcmautostart.cpp @@ -0,0 +1,202 @@ +/* +This file is part of the KDE project +Copyright (C) 2004 Martijn Klingens <klingens@kde.org> + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. +*/ + +#include <tqlayout.h> +#include <tqwhatsthis.h> +#include <tqvgroupbox.h> +#include <tqpushbutton.h> +#include <tqheader.h> +#include <tqtimer.h> +#include <tqfileinfo.h> + +#include <kaboutdata.h> +#include <kapplication.h> +#include <kdesktopfile.h> +#include <kdialog.h> +#include <kgenericfactory.h> +#include <klistview.h> +#include <kmessagebox.h> +#include <kservice.h> +#include <kstandarddirs.h> + +#include <dcopclient.h> +#include <dcopref.h> + +#include <kdebug.h> + +#include "kcmautostart.h" +#include "kcmautostart.moc" + +typedef KGenericFactory<AutoStartConfig, TQWidget> AutoStartFactory; +K_EXPORT_COMPONENT_FACTORY( kcm_autostart, AutoStartFactory( "kcmautostart" ) ) + +AutoStartConfig::AutoStartConfig(TQWidget* parent, const char* name, const TQStringList &) : + TDECModule( AutoStartFactory::instance(), parent, name ) +{ + TDEGlobal::dirs()->addResourceType("autostart", "share/autostart"); + TDEAboutData *about = + new TDEAboutData( I18N_NOOP( "kcmautostart" ), I18N_NOOP( "TDE Service Manager" ), + 0, 0, TDEAboutData::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 + + TQVBoxLayout *lay = new TQVBoxLayout( this, 0, KDialog::spacingHint() ); + + TQGroupBox *gb = new TQVGroupBox( i18n( "Startup Services" ), this ); + TQWhatsThis::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 TDEListView( gb ); + _lvStartup->addColumn(i18n("Use")); + _lvStartup->addColumn(i18n("Service")); + _lvStartup->addColumn(i18n("Description")); + _lvStartup->setAllColumnsShowFocus(true); + _lvStartup->header()->setStretchEnabled(true, 2); + + load(); +} + +void setModuleGroup(TDEConfig *config, const TQString &filename) +{ + TQString 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(TQString("Module-%1").arg(module)); +} + +bool AutoStartConfig::autoloadEnabled(TDEConfig *config, const TQString &filename) +{ + setModuleGroup(config, filename); + return config->readBoolEntry("autoload", true); +} + +void AutoStartConfig::setAutoloadEnabled(TDEConfig *config, const TQString &filename, bool b) +{ + setModuleGroup(config, filename); + return config->writeEntry("autoload", b); +} + +void AutoStartConfig::load() { + _lvStartup->clear(); + + TQStringList files = TDEGlobal::dirs()->findAllResources( "autostart", TQString::fromLatin1( "*.desktop" ), false, true ); + + for ( TQStringList::ConstIterator it = files.begin(); it != files.end(); it++ ) + { + if ( KDesktopFile::isDesktopFile( TQFileInfo( *it ).fileName() ) ) + { + KDesktopFile file( TQFileInfo( *it ).fileName(), true, "autostart" ); + TQString name = file.readName(); + if ( !name.isEmpty() ) + { + CheckListItem *clitem = new CheckListItem( _lvStartup, TQString() ); + connect( clitem, TQT_SIGNAL( changed( TQCheckListItem * ) ), TQT_SLOT( slotItemChecked( TQCheckListItem * ) ) ); + clitem->setText( 1, name ); + clitem->setText( 2, file.readComment() ); + clitem->setText( 3, *it ); + clitem->setOn( !file.readBoolEntry( "Hidden", false ) ); + } + } + } +} + +void AutoStartConfig::save() +{ + TQListViewItemIterator 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 + TQString path = it.current()->text( 3 ); + KDesktopFile file( path, true, "services" ); + bool shouldBeHidden = !( static_cast<TQCheckListItem *>( it.current() )->isOn() ); + if ( file.readBoolEntry( "Hidden", false ) != shouldBeHidden ) + { + KDesktopFile outFile( TQFileInfo( path ).fileName(), false, "autostart" ); + kdDebug() << "************** Writing out " << path << endl; + outFile.writeEntry( "Hidden", shouldBeHidden ); + outFile.sync(); + } + } + ++it; + } + + //TQTimer::singleShot(0, this, TQT_SLOT(slotServiceRunningToggled())); +} + +void AutoStartConfig::defaults() +{ + TQListViewItemIterator it( _lvStartup); + while ( it.current() != 0 ) { + if (it.current()->rtti()==1) { + TQCheckListItem *item = static_cast<TQCheckListItem *>(it.current()); + item->setOn(false); + } + ++it; + } +} + +void AutoStartConfig::slotReload() +{ + TQString current = _lvStartup->currentItem()->text(4); + load(); + TQListViewItem *item = _lvStartup->findItem(current, 4); + if (item) + _lvStartup->setCurrentItem(item); +} + +void AutoStartConfig::slotItemChecked(TQCheckListItem*) +{ + emit changed(true); +} + +TQString AutoStartConfig::quickHelp() const +{ + return i18n("<h1>Service Manager</h1><p>This module allows you to have an overview of all plugins of the " + "KDE Daemon, also referred to as KDE Services. Generally, there are two types of service:</p>" + "<ul><li>Services invoked at startup</li><li>Services called on demand</li></ul>" + "<p>The latter are only listed for convenience. The startup services can be started and stopped. " + "In Administrator mode, you can also define whether services should be loaded at startup.</p>" + "<p><b> Use this with care: some services are vital for KDE; do not deactivate services if you" + " do not know what you are doing.</b></p>"); +} + +CheckListItem::CheckListItem(TQListView *parent, const TQString &text) + : TQObject(parent), + TQCheckListItem(parent, text, CheckBox) +{ } + +void CheckListItem::stateChange(bool on) +{ + TQCheckListItem::stateChange(on); + emit changed(this); +} diff --git a/kiostdetool/kcms/autostart/kcmautostart.desktop b/kiostdetool/kcms/autostart/kcmautostart.desktop new file mode 100644 index 0000000..599da87 --- /dev/null +++ b/kiostdetool/kcms/autostart/kcmautostart.desktop @@ -0,0 +1,56 @@ +[Desktop Entry] +Encoding=UTF-8 +Exec=tdecmshell kcmautostart +Icon=autostart +Type=Application + +X-TDE-ModuleType=Library +X-TDE-Library=autostart +X-TDE-Factoryname=autostart +X-TDE-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;TDE;X-TDE-settings-components; diff --git a/kiostdetool/kcms/autostart/kcmautostart.h b/kiostdetool/kcms/autostart/kcmautostart.h new file mode 100644 index 0000000..dcfe25a --- /dev/null +++ b/kiostdetool/kcms/autostart/kcmautostart.h @@ -0,0 +1,68 @@ +/* + This file is part of the KDE project + Copyright (C) 2004 Martijn Klingens <klingens@kde.org> + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#ifndef KCMAUTOSTART_H +#define KCMAUTOSTART_H + +#include <tqlistview.h> +#include <tdecmodule.h> + +class TDEListView; +class TQStringList; +class TQPushButton; + +class AutoStartConfig : public TDECModule +{ +Q_OBJECT + +public: + AutoStartConfig(TQWidget* parent, const char* name= 0L, const TQStringList& foo = TQStringList()); + ~AutoStartConfig() {}; + + void load(); + void save(); + void defaults(); + + TQString quickHelp() const; + +protected slots: + void slotReload(); + void slotItemChecked(TQCheckListItem *item); + + bool autoloadEnabled(TDEConfig *config, const TQString &filename); + void setAutoloadEnabled(TDEConfig *config, const TQString &filename, bool b); + +private: + TDEListView *_lvStartup; +}; + +class CheckListItem : public TQObject, public TQCheckListItem +{ + Q_OBJECT + +public: + CheckListItem(TQListView* parent, const TQString &text); + ~CheckListItem() { } +signals: + void changed(TQCheckListItem*); +protected: + virtual void stateChange(bool); +}; + +#endif // KCMAUTOSTART_H + diff --git a/kiostdetool/kioskConfigDialog.cpp b/kiostdetool/kioskConfigDialog.cpp new file mode 100644 index 0000000..e624afe --- /dev/null +++ b/kiostdetool/kioskConfigDialog.cpp @@ -0,0 +1,149 @@ +/* + * kioskConfigDialog.cpp + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "kioskConfigDialog.h" + +#include <tqcheckbox.h> +#include <tqtextedit.h> + +#include <kapplication.h> +#include <tdeconfig.h> +#include <tdefiledialog.h> +#include <knuminput.h> +#include <klineedit.h> +#include <klocale.h> +#include <kurlrequester.h> + +#include "kioskrun.h" + +#include "kioskConfigDialog_ui.h" + +KioskConfigDialog::KioskConfigDialog(TQWidget *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, TQT_SIGNAL(textChanged( const TQString& )), TQT_SLOT(updateExample())); + connect(w->lineUpload, TQT_SIGNAL(textChanged( const TQString& )), TQT_SLOT(updateExample())); + connect(w->lineUploadPrefix, TQT_SIGNAL(textChanged( const TQString& )), TQT_SLOT(updateExample())); +} + +KioskConfigDialog::~KioskConfigDialog() +{ +} + +void KioskConfigDialog::init() +{ + TQString 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); + } + + TDEConfig *config = kapp->config(); + config->setGroup("General"); + + TQString 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() +{ + TQString uploadPrefix = w->lineUploadPrefix->text(); + TQString file1 = w->lineProfilePrefix->url()+"default"; + TQString file2 = file1; + if (file2.startsWith(uploadPrefix)) + file2 = file2.mid(uploadPrefix.length()); + if (file2.startsWith("/")) + file2 = file2.mid(1); + TQString url = w->lineUpload->url(); + if (!url.endsWith("/")) + url += "/"; + url += file2; + TQString example = TQString("<qt><center><b>%1</b><br>--><br><b>%2</b></center>").arg(file1, url); + w->lblUploadExample->setText(example); + w->lblUploadExample->setFixedSize(TQSize(500,fontMetrics().lineSpacing()*3 + 6)); +} + +bool KioskConfigDialog::save() +{ + TQString uploadURL; + TQString uploadPrefix; + TQString 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(); + + TDEConfig *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/kiostdetool/kioskConfigDialog.h b/kiostdetool/kioskConfigDialog.h new file mode 100644 index 0000000..7695f40 --- /dev/null +++ b/kiostdetool/kioskConfigDialog.h @@ -0,0 +1,47 @@ +/* + * kioskConfigDialog.h + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _KIOSKCONFIGDIALOG_H_ +#define _KIOSKCONFIGDIALOG_H_ + +#include <kdialogbase.h> + +class KioskConfigDialogUI; + +class KioskConfigDialog : public KDialogBase +{ + Q_OBJECT + +public: + KioskConfigDialog(TQWidget *parent); + ~KioskConfigDialog(); + + bool save(); + + +protected slots: + void updateExample(); + +protected: + void init(); + +private: + KioskConfigDialogUI *w; +}; + +#endif diff --git a/kiostdetool/kioskConfigDialog_ui.ui b/kiostdetool/kioskConfigDialog_ui.ui new file mode 100644 index 0000000..64d2753 --- /dev/null +++ b/kiostdetool/kioskConfigDialog_ui.ui @@ -0,0 +1,329 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>KioskConfigDialogUI</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>KioskConfigDialogUI</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>551</width> + <height>501</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>checkProfilePrefix</cstring> + </property> + <property name="text"> + <string>Store all &profiles under the same base directory</string> + </property> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>&Base directory:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>lineProfilePrefix</cstring> + </property> + </widget> + <widget class="KURLRequester"> + <property name="name"> + <cstring>lineProfilePrefix</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </vbox> + </widget> + </hbox> + </widget> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>checkUpload</cstring> + </property> + <property name="text"> + <string>On exit, &upload profiles to remote server</string> + </property> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout8</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>spacer1_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout7</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="text"> + <string>&Server URL:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>lineUpload</cstring> + </property> + </widget> + <widget class="KURLRequester"> + <property name="name"> + <cstring>lineUpload</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1_3</cstring> + </property> + <property name="text"> + <string>Strip off the following directory prefix when uploading:</string> + </property> + </widget> + <widget class="KLineEdit"> + <property name="name"> + <cstring>lineUploadPrefix</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Example:</string> + </property> + </widget> + <widget class="TQTextEdit"> + <property name="name"> + <cstring>lblUploadExample</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>500</width> + <height>10</height> + </size> + </property> + <property name="vScrollBarMode"> + <enum>AlwaysOff</enum> + </property> + <property name="hScrollBarMode"> + <enum>AlwaysOff</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </vbox> + </widget> + </hbox> + </widget> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>checkUID</cstring> + </property> + <property name="text"> + <string>Do not show users with a UID lower than</string> + </property> + <property name="accel"> + <string></string> + </property> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout6</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>spacer1_2_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KIntNumInput"> + <property name="name"> + <cstring>numUID</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="minValue"> + <number>1</number> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>60</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> +</widget> +<customwidgets> +</customwidgets> +<connections> + <connection> + <sender>checkProfilePrefix</sender> + <signal>toggled(bool)</signal> + <receiver>lineProfilePrefix</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>checkUpload</sender> + <signal>toggled(bool)</signal> + <receiver>lineUpload</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>checkUID</sender> + <signal>toggled(bool)</signal> + <receiver>numUID</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>checkUpload</sender> + <signal>toggled(bool)</signal> + <receiver>lineUploadPrefix</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>checkUpload</sender> + <signal>toggled(bool)</signal> + <receiver>lblUploadExample</receiver> + <slot>setEnabled(bool)</slot> + </connection> +</connections> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> +</includehints> +</UI> diff --git a/kiostdetool/kiosk_data.xml b/kiostdetool/kiosk_data.xml new file mode 100644 index 0000000..92144b6 --- /dev/null +++ b/kiostdetool/kiosk_data.xml @@ -0,0 +1,778 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE kiosk SYSTEM "kiosk.dtd"> +<kiosk> + <group name="general" icon="package_settings"> + <caption>General</caption> + <description> + Generic restrictions + </description> + <actions> + <action type="action restriction" key="action/twin_rmb"> + <caption>Disable Window Manager context menu (Alt-F3)</caption> + <description> + The Window Manager context menu is normally shown when Alt-F3 is pressed + or when the menu button on the window frame is pressed. + </description> + </action> + <action type="action restriction" key="action/bookmarks"> + <caption>Disable Bookmarks</caption> + <description>Disable Bookmarks in all applications.</description> + </action> + <action type="action restriction" key="user/root"> + <caption>Disable all tasks and applications that require root access</caption> + <description> + In multi-user + environments the users normally do not know the root password; in such a case, it + may be desirable to use this option to remove the tasks and applications + from the menus that the users cannot use. + </description> + </action> + <action type="action restriction" key="shell_access"> + <caption>Disable access to a command shell</caption> + <description> + In an environment where the desktop is dedicated + to a defined set of tasks it may be desirable to disable access to a command shell to + prevent users from engaging in tasks that were not intended or authorized; hence, it is + strongly recommended to disable access to a command shell if the desktop is to act + as a public terminal. + </description> + </action> + <action type="action restriction" key="logout"> + <caption>Disable Logout option</caption> + <description> + This prevents the user from logging out. To make this option + effective it is important to ensure that key-combinations to terminate the X-server, + such as Alt-Ctrl-Backspace, are disabled in the configuration of the X-server. + </description> + </action> + <action type="action restriction" key="lock_screen"> + <caption>Disable Lock Screen option</caption> + <description> + When the desktop is to act as a public terminal or is to be + shared by different users it may be desirable to prevent locking of the screen to ensure that + the system remains accessible if a user leaves the terminal. + </description> + </action> + <action type="action restriction" key="run_command"> + <caption>Disable "Run Command" option (Alt-F2)</caption> + <description> + The "Run Command" option can normally be used to execute arbitrary commands; however, when + access to a command shell is restricted only applications and services defined by a .desktop file + can be started this way. Disabling "Run Command" here hides the option completely. + </description> + </action> + <action type="action restriction" key="movable_toolbars"> + <caption>Disable toolbar moving</caption> + <description> + Normally toolbars in applications can be moved around; when this option is chosen + all toolbars are fixed in their original positions. + </description> + </action> + <action type="action restriction" key="run_desktop_files"> + <caption>Disable execution of arbitrary .desktop files.</caption> + <description> + This option defines whether users may execute .desktop files that are not + part of the system-wide desktop icons, TDE menu, registered services or + autostart services. When access to a command shell is restricted it is recommended to + to disable the execution of arbitrary .desktop files as well since such .desktop files + can be used to circumvent the command shell restriction. + </description> + </action> + <action type="action restriction" key="start_new_session"> + <caption>Disable starting of a second X session.</caption> + <description> + TDM 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 TDM settings in which case + the setting here should be left enabled. + </description> + </action> + <action type="action restriction" key="lineedit_text_completion"> + <caption>Disable input line history</caption> + <description> + If a single account is used by multiple people it may be desirable to disable + the input line history out of privacy considerations. + </description> + </action> + </actions> + </group> + <group name="kdesktop" icon="desktop"> + <caption>Desktop Icons</caption> + <description> + Desktop Icons are provided by "kdesktop". + </description> + <preview binary="kdesktop" dcop="kdesktop" options="restart"> + </preview> + <setup binary="kdesktop" dcop="kdesktop" options="restart"> + <mutable file="kdesktoprc" /> + <mutable file="kdeglobals" /> + </setup> + <actions> + <action type="immutable" file="kdesktoprc"> + <caption>Lock down Desktop Settings</caption> + <description> + When the desktop settings are locked down the user can no longer change how the desktop + behaves or look like. This does not affect the ability to add new files or shortcuts to the + desktop. + </description> + </action> + <action type="action restriction" key="action/kdesktop_rmb"> + <caption>Disable context menus</caption> + <description> + When checked the user will no longer get any context menu. Normally the user + can get a context menu by clicking with the right mouse button. + </description> + </action> + <action type="action restriction" key="editable_desktop_icons"> + <caption>Lock down all Desktop icons</caption> + <description> + When checked the user will not be able to remove or edit any existing + icon or file on the Desktop or add any new icon or file. + </description> + </action> +<!-- Not implemented yet + <action type="action restriction" key="editable_system_desktop_icons"> + <caption>Lock down system wide Desktop icons</caption> + <description> + When checked the user will not be able to remove or edit any of + the system wide icons but will still be able to add, remove or edit + personal icons or files on the desktop. + </description> + </action> +--> + <action type="config" file="kdesktoprc" group="General" key="CopyDesktopLinks" default="true"> + <caption>Add additional vendor specific icons</caption> + <description> + When this option is checked users will get additional icons + copied to their Desktop when they first log in. These icons + do not appear in the preview. + </description> + </action> + </actions> + </group> + <group name="background" icon="background"> + <caption>Desktop Background</caption> + <description> + Set up the Desktop Background also known as Wallpaper. + </description> + <preview binary="kdesktop" dcop="kdesktop" options="restart"> + </preview> + <setup binary="tdecmshell" args="tde-background.desktop"> + <mutable file="kdesktoprc" /> + <mutable file="kdeglobals" /> + </setup> + <actions> + <action type="module" key="tde-background.desktop"> + <caption>Lock down Desktop Background Settings</caption> + <description> + When the desktop background settings are locked down the user can no longer change them. + </description> + <action type="immutable" file="kdesktoprc" group="Desktop0"/> + <action type="immutable" file="kdesktoprc" group="Desktop1"/> + <action type="immutable" file="kdesktoprc" group="Desktop2"/> + <action type="immutable" file="kdesktoprc" group="Desktop3"/> + <action type="immutable" file="kdesktoprc" group="Desktop4"/> + <action type="immutable" file="kdesktoprc" group="Desktop5"/> + <action type="immutable" file="kdesktoprc" group="Desktop6"/> + <action type="immutable" file="kdesktoprc" group="Desktop7"/> + </action> + </actions> + </group> + <group name="screensaver" icon="tdescreensaver"> + <caption>Screen Saver</caption> + <description> + Set up Screen Saver + </description> + <preview binary="kdesktop" dcop="kdesktop" options="restart"> + </preview> + <setup binary="tdecmshell" args="tde-screensaver.desktop"> + <mutable file="kdesktoprc" /> + <mutable file="kdeglobals" /> + </setup> + <actions> + <action type="module" key="tde-screensaver.desktop"> + <caption>Lock down Screen Saver Settings</caption> + <description> + When the Screen Saver settings are locked down the user can no longer change them. + </description> + <action type="immutable" file="kdesktoprc" group="ScreenSaver"/> + </action> + <action type="action restriction" key="opengl_screensavers"> + <caption>Disable OpenGL-based Screen Savers</caption> + <description> + OpenGL-based screen savers may cause problems on systems without decent OpenGL + support; with this option all such screensavers can be disabled. + </description> + </action> + <action type="action restriction" key="manipulatescreen_screensavers"> + <caption>Discreet Screen Savers Only</caption> + <description> + Some screensavers do not hide the complete screen content and may leave possible + sensitive information visible. This option disables all such screensavers and only + enables those screensavers that completely hide the original content of the screen. + </description> + </action> + </actions> + </group> + <group name="kdemenu" icon="kmenuedit"> + <caption>TDE Menu</caption> + <description> + The TDE Application menu + </description> + <preview binary="kicker" dcop="kicker" options="restart"> + </preview> + <setup binary="kmenuedit" options="nofork"> + <ignore file="kmenueditrc" /> + </setup> + <actions> + <action type="action restriction" key="user/root"> + <caption>Disable all tasks and applications that require root access</caption> + <description> + This option disables all menu items that require root access and that will ask the user for the root password. + </description> + </action> + <action type="action restriction" key="action/menuedit"> + <caption>Disable menu editing</caption> + <description> + This disables the menu-option to edit the TDE Application Menu. When disabled, users will no longer be + able to make changes to their personal application menu. + </description> + <action type="resource restriction" key="xdgconf-menu" /> + </action> + </actions> + </group> + <group name="theming" icon="style"> + <caption>Theming</caption> + <description> + Set up of Fonts, Colors and Style + </description> +<!-- + <preview binary="kdesktop" dcop="kdesktop" options="restart"> + </preview> +--> + <setup binary="tdecmshell" args="tde-style.desktop,tde-colors.desktop,tde-fonts.desktop,tde-twindecoration.desktop"> + <mutable file="kdesktoprc" /> + <mutable file="kdeglobals" /> + </setup> + <actions> + <action type="module" key="tde-style.desktop"> + <caption>Lock down Style Settings</caption> + <description> + When the Style settings are locked down the user can no longer change them. + </description> + </action> + <action type="module" key="tde-colors.desktop"> + <caption>Lock down Color Settings</caption> + <description> + When the Color settings are locked down the user can no longer change them. + </description> + </action> + <action type="module" key="tde-fonts.desktop"> + <caption>Lock down Font Settings</caption> + <description> + When the Font settings are locked down the user can no longer change them. + </description> + </action> + <action type="module" key="tde-twindecoration.desktop"> + <caption>Lock down Window Decoration Settings</caption> + <description> + When the Window Decoration settings are locked down the user can no longer change them. + </description> + </action> + </actions> + </group> + <group name="kicker" icon="kcmkicker"> + <caption>Panel</caption> + <description> + The TDE panel "kicker" is normally found at the bottom of the screen. + </description> + <preview binary="kicker" dcop="kicker" options="restart"> + </preview> + <setup binary="kicker" dcop="kicker" options="restart"> + <mutable file="kickerrc" /> + <ignore file="kdeglobals" /> + </setup> + <actions> + <action type="immutable" file="kickerrc"> + <caption>Lock down panel</caption> + <description> + This option can be used to lock down the panel. The user will then no longer be able to add, remove or change + any of the permanent panel items. + </description> + </action> + <action type="action restriction" key="action/kicker_rmb"> + <caption>Disable Context Menus</caption> + <description> + This option disables the context menus that one normally gets when pressing the right mouse button in the panel. + </description> + </action> + </actions> + </group> + <group name="proxy" icon="proxy"> + <caption>Network Proxy</caption> + <description> + Set up of Network Proxy settings + </description> + <setup binary="tdecmshell" args="tde-proxy.desktop"> + <mutable file="kdesktoprc" /> + <mutable file="kdeglobals" /> + </setup> + <actions> + <action type="module" key="tde-proxy.desktop"> + <caption>Lock down Proxy Settings</caption> + <description> + When the Proxy settings are locked down the user can no longer change them. + </description> + </action> + </actions> + </group> + <group name="konqueror" icon="konqueror"> + <caption>Konqueror</caption> + <description> + Konqueror is a combined web- and filebrowser. + </description> + <actions> + <action type="action restriction" key="action/properties"> + <caption>Disable Properties in context menu</caption> + <description> + This option can be used to disable the <i>Properties</i> option in the context menu for files. + </description> + </action> + <action type="action restriction" key="action/openwith"> + <caption>Disable Open With action</caption> + <description> + This option can be used to disable the <i>Open With</i> menu option. + </description> + </action> + <action type="action restriction" key="action/openintab"> + <caption>Disable Open In New Tab action</caption> + <description> + This option can be used to disable the <i>Open In New Tab</i> menu option. + </description> + </action> + <action type="custom" key="restrict_file_browsing"> + <caption>Disable file-browsing outside home directory</caption> + <description> + This option can be used to prevent the user from browsing the + file system outside his or her own home directory. + </description> + </action> + </actions> + </group> + <group name="menus"> + <caption>Menu Actions</caption> + <description> + Common menu actions found in applications. + </description> + <actions> + <action type="action restriction" key="action/file_new"> + <caption>Disable File -> %action</caption> + <description> + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/file_open"> + <caption>Disable File -> %action</caption> + <description> + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + See also <i>Open Recent</i> + </description> + </action> + <action type="action restriction" key="action/file_open_recent"> + <caption>Disable File -> %action</caption> + <description> + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/file_save"> + <caption>Disable File -> %action</caption> + <description> + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/file_save_as"> + <caption>Disable File -> %action</caption> + <description> + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/file_revert"> + <caption>Disable File -> %action</caption> + <description> + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/file_close"> + <caption>Disable File -> %action</caption> + <description> + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/file_print"> + <caption>Disable File -> %action</caption> + <description> + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + See also <i>Print Preview</i> + </description> + </action> + <action type="action restriction" key="action/file_print_preview"> + <caption>Disable File -> %action</caption> + <description> + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/file_mail"> + <caption>Disable File -> %action</caption> + <description> + This option can be used to remove the <i>File -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/file_quit"> + <caption>Disable File -> %action</caption> + <description> + 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. + </description> + </action> + <action type="action restriction" key="action/edit_undo"> + <caption>Disable Edit -> %action</caption> + <description> + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/edit_redo"> + <caption>Disable Edit -> %action</caption> + <description> + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/edit_cut"> + <caption>Disable Edit -> %action</caption> + <description> + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/edit_copy"> + <caption>Disable Edit -> %action</caption> + <description> + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/edit_paste"> + <caption>Disable Edit -> %action</caption> + <description> + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/edit_select_all"> + <caption>Disable Edit -> %action</caption> + <description> + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/edit_deselect"> + <caption>Disable Edit -> %action</caption> + <description> + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/edit_find"> + <caption>Disable Edit -> %action</caption> + <description> + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/edit_find_next"> + <caption>Disable Edit -> %action</caption> + <description> + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/edit_find_last"> + <caption>Disable Edit -> %action</caption> + <description> + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/edit_replace"> + <caption>Disable Edit -> %action</caption> + <description> + This option can be used to remove the <i>Edit -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/view_actual_size"> + <caption>Disable View -> %action</caption> + <description> + This option can be used to remove the <i>View -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/view_fit_to_page"> + <caption>Disable View -> %action</caption> + <description> + This option can be used to remove the <i>View -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/view_fit_to_width"> + <caption>Disable View -> %action</caption> + <description> + This option can be used to remove the <i>View -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/view_fit_to_height"> + <caption>Disable View -> %action</caption> + <description> + This option can be used to remove the <i>View -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/view_zoom_in"> + <caption>Disable View -> %action</caption> + <description> + This option can be used to remove the <i>View -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/view_zoom_out"> + <caption>Disable View -> %action</caption> + <description> + This option can be used to remove the <i>View -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/view_zoom"> + <caption>Disable View -> %action</caption> + <description> + This option can be used to remove the <i>View -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/view_redisplay"> + <caption>Disable View -> %action</caption> + <description> + This option can be used to remove the <i>View -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/go_up"> + <caption>Disable Go -> %action</caption> + <description> + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/go_back"> + <caption>Disable Go -> %action</caption> + <description> + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/go_forward"> + <caption>Disable Go -> %action</caption> + <description> + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/go_home"> + <caption>Disable Go -> %action</caption> + <description> + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/go_previous"> + <caption>Disable Go -> %action</caption> + <description> + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/go_next"> + <caption>Disable Go -> %action</caption> + <description> + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/go_goto"> + <caption>Disable Go -> %action</caption> + <description> + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/go_goto_page"> + <caption>Disable Go -> %action</caption> + <description> + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/go_goto_line"> + <caption>Disable Go -> %action</caption> + <description> + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/go_first"> + <caption>Disable Go -> %action</caption> + <description> + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/go_last"> + <caption>Disable Go -> %action</caption> + <description> + This option can be used to remove the <i>Go -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/bookmarks"> + <caption>Disable Bookmarks</caption> + <description> + This option can be used to completely disable bookmarks in all applications. + </description> + </action> + <action type="action restriction" key="action/bookmark_add"> + <caption>Disable Bookmarks -> %action</caption> + <description> + This option can be used to prevent users from creating new bookmarks. + </description> + </action> + <action type="action restriction" key="action/bookmark_edit"> + <caption>Disable Bookmarks -> %action</caption> + <description> + This option can be used to prevent users from editing bookmarks. + </description> + </action> + <action type="action restriction" key="action/tools_spelling"> + <caption>Disable Tools -> %action</caption> + <description> + This option can be used to remove the <i>Tools -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/options_show_menubar"> + <caption>Disable Settings -> %action</caption> + <description> + This option can be used to remove the <i>Settings -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/options_show_toolbar"> + <caption>Disable Settings -> %action</caption> + <description> + This option can be used to remove the <i>Settings -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/options_show_statusbar"> + <caption>Disable Settings -> %action</caption> + <description> + This option can be used to remove the <i>Settings -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/fullscreen"> + <caption>Disable Settings -> %action</caption> + <description> + This option can be used to remove the <i>Settings -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/options_save_options"> + <caption>Disable Settings -> %action</caption> + <description> + This option can be used to remove the <i>Settings -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/options_configure"> + <caption>Disable Settings -> Configure <Application></caption> + <description> + This option can be used to remove the <i>Settings -> Configure &lt;Application&gt;</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/options_configure_keybinding"> + <caption>Disable Settings -> %action</caption> + <description> + This option can be used to remove the <i>Settings -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/options_configure_toolbars"> + <caption>Disable Settings -> %action</caption> + <description> + This option can be used to remove the <i>Settings -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/options_configure_notifications"> + <caption>Disable Settings -> %action</caption> + <description> + This option can be used to remove the <i>Settings -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/help"> + <caption>Disable Help</caption> + <description> + You can use this to completely disable the help menu + </description> + </action> + <action type="action restriction" key="action/help_contents"> + <caption>Disable Help -> <Application> Handbook</caption> + <description> + This option can be used to remove the <i>Help -> &lt;Application&gt; Handbook</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/help_whats_this"> + <caption>Disable Help -> %action</caption> + <description> + This option can be used to remove the <i>Help -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/help_report_bug"> + <caption>Disable Help -> %action</caption> + <description> + This option can be used to remove the <i>Help -> %action</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/help_about_app"> + <caption>Disable Help -> About <Application></caption> + <description> + This option can be used to remove the <i>Help -> About &lt;Application&gt;</i> menu-option from all applications. + </description> + </action> + <action type="action restriction" key="action/help_about_kde"> + <caption>Disable Help -> %action</caption> + <description> + This option can be used to remove the <i>Help -> %action</i> menu-option from all applications. + </description> + </action> + </actions> + + </group> + <group name="krfb" icon="krfb"> + <caption>Desktop Sharing</caption> + <description> + Remote Desktop Sharing + </description> + <setup binary="tdecmshell" args="kcmkrfb"> + </setup> + <actions> + <action type="immutable" file="krfbrc"> + <caption>Lock down Desktop Sharing Settings</caption> + <description> + When the setting for remote desktop sharing are locked down the user can no longer change them. + </description> + </action> + </actions> + </group> + <group name="filetypes" icon="filetypes"> + <caption>File Associations</caption> + <description> + Configure the applications used for opening files. + </description> + <setup binary="tdecmshell" args="filetypes"> + </setup> + <actions> + <action type="module" key="tde-filetypes.desktop"> + <caption>Lock down File Associations Settings</caption> + <description> + When the setting for file associations are locked down the user can no longer change + the default applications used for opening files. + </description> + <action type="action restriction" key="action/editfiletype"></action> + <action type="immutable" file="profilerc"></action> + </action> +<!-- + <action type="action restriction" key="action/editfiletype"> + <caption>Disable "Edit file type" in properties dialog</caption> + <description> + The "Edit file type" can be used to change how files are recognized and with which + applications such files are opened. + </description> + </action> +--> + </actions> + </group> +</tdeiosk> diff --git a/kiostdetool/kioskdata.cpp b/kiostdetool/kioskdata.cpp new file mode 100644 index 0000000..a5d9f2b --- /dev/null +++ b/kiostdetool/kioskdata.cpp @@ -0,0 +1,309 @@ +/* + * kioskdata.cpp + * + * Copyright (C) 2003, 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "kioskdata.h" + +#include <tqdom.h> +#include <tqfile.h> + +#include <kaction.h> +#include <kdebug.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kstdaction.h> + +TQDict<TQString> *ComponentAction::s_stdActionCaptions = 0; + +ComponentAction::ComponentAction() +{ +} + +ComponentAction::~ComponentAction() +{ +} + +static TQDict<TQString> *readStdActionCaptions() +{ + TQDict<TQString> *captions = new TQDict<TQString>; + for(int i = KStdAction::ActionNone; true;) + { + i++; + TDEAction *action = KStdAction::create((KStdAction::StdAction) i, 0, 0, 0, 0); + if (!action) + break; + + TQString caption = action->text(); + caption.replace("&",""); + + captions->insert(TQString::fromLatin1(action->name()), new TQString(caption)); + } + return captions; +} + +TQString +ComponentAction::expand(const TQString &s) +{ + if (s.contains("%action")) + { + if (!s_stdActionCaptions) + s_stdActionCaptions= readStdActionCaptions(); + + TQString action = key; + action.replace("action/", ""); + TQString *caption = s_stdActionCaptions->find(action); + if (caption) + { + TQString result = s; + result.replace("%action", *caption); + return result; + } + } + return s; +} + +bool +ComponentAction::load(const TQDomElement &docElem) +{ + TQString _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"); + + TQDomNode n = docElem.firstChild(); + while( !n.isNull() ) + { + TQDomElement 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 TQDomElement &docElem) +{ + TQDomNode n = docElem.firstChild(); + while( !n.isNull() ) + { + TQDomElement 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 TQDomElement &e) +{ + exec = e.attribute("binary"); + dcop = e.attribute("dcop"); + options = TQStringList::split(',', e.attribute("options")); + args = TQStringList::split(',', e.attribute("args")); +} + +void +ComponentData::loadSetup(const TQDomElement &docElem) +{ + TQDomNode n = docElem.firstChild(); + while( !n.isNull() ) + { + TQDomElement e = n.toElement(); // try to convert the node to an element. + + if (e.tagName() == "mutable") + { + TQString f = e.attribute("file"); + if (!f.isEmpty()) + mutableFiles.append(f); + } + else if (e.tagName() == "ignore") + { + TQString f = e.attribute("file"); + if (!f.isEmpty()) + ignoreFiles.append(f); + } + + n = n.nextSibling(); + } +} + +bool ComponentData::load(const TQDomElement &docElem) +{ + id = docElem.attribute("name"); + icon = docElem.attribute("icon"); + if (id.isEmpty()) + return false; + TQDomNode n = docElem.firstChild(); + while( !n.isNull() ) + { + TQDomElement 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() +{ + TQString filename = locate("appdata", "kiosk_data.xml"); + if (filename.isEmpty()) + { + m_errorMsg = i18n("<qt>Could not find <b>kiosk_data.xml</b></qt>"); + return false; + } + + TQDomDocument doc; + TQFile file( filename ); + if ( !file.open( IO_ReadOnly ) ) + { + m_errorMsg = i18n("<qt>Could not open <b>%1</b></qt>").arg(filename); + return false; + } + + TQString errorMsg; + int errorRow; + int errorCol; + if ( !doc.setContent( &file, &errorMsg, &errorRow, &errorCol ) ) + { + m_errorMsg = i18n("<qt>Syntax error in <b>%1</b><br>Line %3, column %4: %2</qt>").arg(filename, errorMsg).arg(errorRow).arg(errorCol); + file.close(); + return false; + } + file.close(); + + TQDomElement docElem = doc.documentElement(); + TQDomNode n = docElem.firstChild(); + while( !n.isNull() ) + { + TQDomElement 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/kiostdetool/kioskdata.h b/kiostdetool/kioskdata.h new file mode 100644 index 0000000..57b265e --- /dev/null +++ b/kiostdetool/kioskdata.h @@ -0,0 +1,105 @@ +/* + * kioskdata.h + * + * Copyright (C) 2003, 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _KIOSKDATA_H_ +#define _KIOSKDATA_H_ + +#include <tqdict.h> +#include <tqptrlist.h> +#include <tqstringlist.h> + +class TQDomElement; + +class ComponentAction +{ +public: + ComponentAction(); + ~ComponentAction(); + bool load(const TQDomElement &docElem); + +private: + TQString expand(const TQString &); + +public: + TQString caption; + TQString description; + typedef enum {ActImmutable, ActRestrict, ActCustom, ActModule, ActConfig, ActResource } ActionType; + ActionType type; + TQString file; + TQString group; + TQString key; + TQPtrList<ComponentAction> subActions; + bool defaultValue; + + static TQDict<TQString> *s_stdActionCaptions; +}; + +class ComponentExecData +{ +public: + void load(const TQDomElement &docElem); + bool hasOption(const TQString &option) { return options.contains(option); } +public: + TQString exec; + TQString dcop; + TQStringList options; + TQStringList args; +}; + +class ComponentData +{ +public: + ComponentData(); + ~ComponentData(); + bool load(const TQDomElement &docElem); + bool loadActions(const TQDomElement &docElem); + +protected: + void loadSetup(const TQDomElement &docElem); + +public: + TQString id; + TQString caption; +// TQString description; + TQString icon; + TQPtrList<ComponentAction> actions; + TQStringList mutableFiles; + TQStringList ignoreFiles; + ComponentExecData setup; + ComponentExecData preview; +}; + +class KioskData +{ +public: + KioskData(); + ~KioskData(); + + TQString errorMsg() { return m_errorMsg; } + + bool load(); + +public: + TQStringList m_componentList; + TQDict<ComponentData> m_componentData; + +protected: + TQString m_errorMsg; +}; + +#endif diff --git a/kiostdetool/kioskgui.cpp b/kiostdetool/kioskgui.cpp new file mode 100644 index 0000000..ee9afac --- /dev/null +++ b/kiostdetool/kioskgui.cpp @@ -0,0 +1,727 @@ +/* + * kioskgui.cpp + * + * Copyright (C) 2003,2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License versin 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include "kioskgui.h" + +#include <tqdir.h> +#include <tqlineedit.h> +#include <tqobjectlist.h> +#include <tqwidgetstack.h> +#include <tqpushbutton.h> + +#include <kapplication.h> +#include <kaction.h> +#include <kcombobox.h> +#include <tdeconfig.h> +#include <tdefiledialog.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <kiconview.h> +#include <klocale.h> +#include <kmenubar.h> +#include <kmessagebox.h> +#include <kstatusbar.h> +#include <kstdaccel.h> +#include <kstdaction.h> +#include <kstandarddirs.h> +#include <kurlrequester.h> + +#include "mainview.h" +#include "profileSelectionPage_ui.h" +#include "profilePropsPage.h" +#include "componentSelectionPage.h" +#include "desktopComponent.h" +#include "menueditComponent.h" +#include "screensaverComponent.h" +#include "panelComponent.h" +#include "filetypeeditComponent.h" +#include "componentPage.h" +#include "pageWidget.h" +#include "userManagement.h" +#include "kioskConfigDialog.h" +#include "kioskdata.h" +#include "kioskrun.h" +#include "kiosksync.h" + +KioskGui::KioskGui() + : TDEMainWindow( 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 TDEMainWindow 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, TQT_SIGNAL(clicked()), this, TQT_SLOT(discardPage())); + connect(m_view->pbFinished, TQT_SIGNAL(clicked()), this, TQT_SLOT(finishedPage())); + + TDEConfig *config = kapp->config(); + config->setGroup("General"); + m_profile = config->readEntry("CurrentProfile", "default"); + m_component = config->readEntry("CurrentComponent"); + + selectPage(PAGE_PROFILE_SELECTION, true); + + TQTimer::singleShot(0, this, TQT_SLOT(slotCheckEtcSkel())); +} + +KioskGui::~KioskGui() +{ + delete m_data; + delete m_run; +} + +void KioskGui::slotCheckEtcSkel() +{ + TQString etcSkel = "/etc/skel/.trinity"; + KioskSync skelDir; + skelDir.addDir(etcSkel, KURL()); + TQStringList skelFiles = skelDir.listFiles(); + if (!skelFiles.isEmpty()) + { + KMessageBox::informationList(this, + i18n("<qt>Your system contains KDE configuration settings in the " + "skeleton directory <b>%1</b>. These files are copied to the " + "personal KDE settings directory of newly created users.<p>" + "This may interfere with the correct operation of user profiles.<p>" + "Unless a setting has been locked down, settings that have been copied " + "to the personal KDE settings directory of a user will override " + "a default setting configured in a profile.<p>" + "<b>If this is not the intended behavior, please remove the offending " + "files from the skeleton folder on all systems that you want to " + "administer with user profiles.</b><p>" + "The following files were found under <b>%2</b>:").arg(etcSkel).arg(etcSkel), + skelFiles, + TQString(), + "etc_skel_warning"); + } +} + +void KioskGui::setWidgetBackground(TQWidget *w) +{ + TQObjectList *l = w->queryList( TQWIDGET_OBJECT_NAME_STRING ); + TQObjectListIt it( *l ); + for(TQWidget *wid=0; (wid = (TQWidget*)it.current()); ++it) + { + wid->setBackgroundOrigin(WindowOrigin); + if (::tqqt_cast<TQPushButton*>(wid)) + wid->setAutoMask(true); + } + w->setBackgroundOrigin(WindowOrigin); + delete l; +} + +void KioskGui::setSubCaption(const TQString &subCaption) +{ + m_view->subCaptionLabel->setText("<h1>"+subCaption+"</h1>"); +} + +void KioskGui::setupActions() +{ +// KStdAction::open(this, TQT_SLOT(fileOpen()), actionCollection()); +// KStdAction::save(this, TQT_SLOT(fileSave()), actionCollection()); +// KStdAction::saveAs(this, TQT_SLOT(fileSaveAs()), actionCollection()); + KStdAction::quit(this, TQT_SLOT(close()), actionCollection()); +// KStdAction::back(this, TQT_SLOT(previousPage()), actionCollection(), "previousPage"); +// KStdAction::forward(this, TQT_SLOT(nextPage()), actionCollection(), "nextPage"); + +// createStandardStatusBarAction(); +// setStandardToolBarMenuEnabled(true); + +// KStdAction::keyBindings(this, TQT_SLOT(optionsConfigureKeys()), actionCollection()); +// KStdAction::configureToolbars(this, TQT_SLOT(optionsConfigureToolbars()), actionCollection()); + KStdAction::preferences(this, TQT_SLOT(slotConfig()), actionCollection()); + m_uploadAction = new TDEAction(i18n("Upload &All Profiles"), TQString(), 0, this, TQT_SLOT(uploadAllProfiles()), actionCollection(), "upload_all"); + m_backgroundAction = new TDEToggleAction(i18n("Background Graphics"), TQString(), 0, this, TQT_SLOT(slotUpdateBackground()), actionCollection(), "show_background"); + + updateActions(); +} + +void KioskGui::updateActions() +{ + TDEConfig *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(TDEConfig * /*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(TDEConfig * /*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(TQListViewItem *item) +{ + if (!m_profileSelectionPage) + return; + if (!item) + item = m_profileSelectionPage->listProfile->selectedItem(); + if (!item) + return; + TQString profile = item->text(0); + int result = KMessageBox::warningContinueCancel(this, + i18n("<qt>You are about to delete the profile <b>%1</b>.<p>" + "Are you sure you want to do this?").arg(profile), + TQString(), 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(TQListViewItem *item, const TQPoint &p) +{ + if (!item) return; // No item selected + + TQPopupMenu 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, + TQT_SIGNAL(contextMenuRequested(TQListViewItem *, const TQPoint &, int)), + this, TQT_SLOT(slotProfileContextMenu(TQListViewItem *, const TQPoint &))); + connect(m_profileSelectionPage->listProfile, + TQT_SIGNAL(doubleClicked (TQListViewItem *, const TQPoint &, int )), + this, TQT_SLOT(nextPage())); + connect(m_profileSelectionPage->buttonDelete, TQT_SIGNAL(clicked()), + this, TQT_SLOT(slotDeleteProfile())); + connect(m_profileSelectionPage->buttonAdd, TQT_SIGNAL(clicked()), + this, TQT_SLOT(slotAddProfile())); + connect(m_profileSelectionPage->buttonProperty, TQT_SIGNAL(clicked()), + this, TQT_SLOT(slotProfileProperties())); + connect(m_profileSelectionPage->buttonSetup, TQT_SIGNAL(clicked()), + this, TQT_SLOT(slotProfileSetup())); + connect(m_profileSelectionPage->buttonUsers, TQT_SIGNAL(clicked()), + this, TQT_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, TQT_SIGNAL(componentActivated()), this, TQT_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, TQString()); + 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(); + + TQStringList profiles = KioskRun::self()->allProfiles(); + + for(TQStringList::ConstIterator it = profiles.begin(); + it != profiles.end(); ++it) + { + TQString profile = *it; + TQString description; + TQString installUser; + TQString installDir; + + KioskRun::self()->getProfileInfo(profile, description, installDir, installUser); + + TQListViewItem *item = new TQListViewItem(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) : TQString(); + + TDEConfig *config = kapp->config(); + config->setGroup("General"); + config->writeEntry("CurrentProfile", m_profile); + config->sync(); + + TQString description; + TQString installDir; + TQString installUser; + + KioskRun::self()->getProfileInfo(m_profile, description, installDir, installUser); + + TQStringList 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?"), + TQString(), + KStdGuiItem::quit()); + if (result == KMessageBox::Continue) + return true; + return false; + } + if (m_uploadAction->isEnabled()) + { + TDEConfig *config = kapp->config(); + config->setGroup("General"); + + KURL uploadUrl = config->readEntry("uploadURL"); + int result = KMessageBox::questionYesNo(this, + i18n("<qt>Do you want to upload the profiles to <b>%1</b> ?</qt>").arg(uploadUrl.prettyURL())); + if (result == KMessageBox::Yes) + { + uploadAllProfiles(); + } + } + + return true; +} + +void KioskGui::uploadAllProfiles() +{ + TDEConfig *config = kapp->config(); + config->setGroup("General"); + TQString uploadPrefix = config->readEntry("uploadPrefix"); + TQString uploadURL = config->readEntry("uploadURL"); + + KioskSync sync(this); + + TQStringList profiles = KioskRun::self()->allProfiles(); + + for(TQStringList::ConstIterator it = profiles.begin(); + it != profiles.end(); ++it) + { + TQString profile = *it; + TQString description; + TQString installUser; + TQString installDir; + + KioskRun::self()->getProfileInfo(profile, description, installDir, installUser); + +// sync.addDir(installDir, KURL("ftp://localhost/kde/profiles")); + + TQString dir = installDir; + if (dir.startsWith(uploadPrefix)) + dir = dir.mid(uploadPrefix.length()); + if (dir.startsWith("/")) + dir = dir.mid(1); + + KURL url(uploadURL); + url.setPath(url.path(1)+dir); + sync.addDir(installDir, url); + } + + if (sync.sync()) + { + KMessageBox::information(this, i18n("<qt>All profiles have been successfully uploaded to <b>%1</b>").arg(uploadURL)); + } +} + +void KioskGui::uploadCurrentProfile() +{ +} + +void KioskGui::slotUpdateBackground() +{ + TDEConfig *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(TQSize(160,170)); + TQString language = TDEGlobal::locale()->language(); + TQString caption = locate("appdata", "caption-"+language+".png"); + if (caption.isEmpty()) + caption = locate("appdata", "caption.png"); + TQPixmap pm(caption); + m_view->captionLabel->setPixmap(pm); + m_view->captionLabel->setMinimumHeight(pm.height()); + } + else + { + m_view->unsetPalette(); + m_view->logoLabel->setPixmap(TQPixmap()); + m_view->logoLabel->setMinimumSize(0,0); + m_view->captionLabel->setPixmap(TQPixmap()); + m_view->captionLabel->setMinimumHeight(0); + } +} + + +#include "kioskgui.moc" diff --git a/kiostdetool/kioskgui.h b/kiostdetool/kioskgui.h new file mode 100644 index 0000000..e196474 --- /dev/null +++ b/kiostdetool/kioskgui.h @@ -0,0 +1,110 @@ +/* + * kioskgui.h + * + * Copyright (C) 2003,2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _KIOSKGUI_H_ +#define _KIOSKGUI_H_ + +#include <tqlistview.h> + +#include <tdeconfig.h> +#include <kmainwindow.h> + +class MainView; +class ProfileSelectionPageUI; +class ComponentSelectionPage; +class ProfilePropsPage; +class PageWidget; +class KioskData; +class KioskRun; +class ComponentData; +class TDEAction; +class TDEToggleAction; + +class KioskGui : public TDEMainWindow +{ + 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(TDEConfig *config); + void readProperties(TDEConfig *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(TQListViewItem *item=0); + void slotAddProfile(); + void slotProfileProperties(); + void slotProfileSetup(); + void slotManageUsers(); + void slotProfileContextMenu(TQListViewItem *item, const TQPoint &p); + void slotConfig(); + + void uploadAllProfiles(); + void uploadCurrentProfile(); + void slotUpdateBackground(); + + void slotCheckEtcSkel(); + +protected: + void updateActions(); + void updateBackground(); + void setWidgetBackground(TQWidget *w); + void setSubCaption(const TQString &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; + TQString m_profile; + TQString m_component; + ComponentData * m_componentData; + TDEAction *m_uploadAction; + TDEToggleAction *m_backgroundAction; +}; + +#endif diff --git a/kiostdetool/kioskrun.cpp b/kiostdetool/kioskrun.cpp new file mode 100644 index 0000000..f5693ca --- /dev/null +++ b/kiostdetool/kioskrun.cpp @@ -0,0 +1,1687 @@ +/* + * kioskrun.cpp + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "kioskrun.h" + +#include "config.h" + +#include <assert.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include <tqdir.h> +#include <tqfile.h> + +#include <kapplication.h> +#include <kcmdlineargs.h> +#include <tdeconfig.h> +#include <kdebug.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kprocess.h> +#include <ksavefile.h> +#include <ksimpleconfig.h> +#include <kstandarddirs.h> +#include <kurl.h> +#include <kuser.h> + +#include "kiosksync.h" + +#include <tdeio/netaccess.h> +#define NETACCESS TDEIO::NetAccess + +#undef DEBUG_ENTRIES + +KioskRun *KioskRun::s_self = 0; + +KioskRun::KioskRun( TQObject* parent, const char* name) + : TQObject(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 = TQDir::homeDirPath()+"/.trinity-test"; + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + m_kderc = TQFile::decodeName(args->getOption("kderc")); + m_isRoot = (getuid() == 0); +} + +KioskRun::~KioskRun() +{ + shutdownRuntimeEnv(); + s_self = 0; +} + +void +KioskRun::setUser(const TQString &user) +{ + if (m_user == user) return; + + shutdownRuntimeEnv(); + shutdownConfigEnv(); + m_user = user; +} + +static void filterDupes(TQStringList &list) +{ + TQStringList tmp; + for(TQStringList::ConstIterator it = list.begin(); + it != list.end(); ++it) + { + if (!tmp.contains(*it)) + tmp.append(*it); + } + list = tmp; +} + +void +KioskRun::setKdeDirs(const TQStringList &dirs) +{ + if (m_kdeDirs == dirs) return; + + shutdownRuntimeEnv(); + shutdownConfigEnv(); + m_kdeDirs = dirs; + TQStringList xdgDataDirs = TQStringList::split(':', TQFile::decodeName(getenv("XDG_DATA_DIRS"))); + if (xdgDataDirs.isEmpty()) + { + xdgDataDirs = TQStringList::split(':', TDEGlobal::dirs()->kfsstnd_prefixes()); + xdgDataDirs.pop_front(); + for(TQStringList::Iterator it = xdgDataDirs.begin(); + it != xdgDataDirs.end(); ++it) + { + *it += "share"; + } + xdgDataDirs << "/usr/local/share" << "/usr/share"; + } + + m_xdgDataDirs.clear(); + for(TQStringList::ConstIterator it = dirs.begin(); + it != dirs.end(); ++it) + { + m_xdgDataDirs.append(*it+"/share"); + } + m_xdgDataDirs += xdgDataDirs; + filterDupes(m_xdgDataDirs); + + TQStringList xdgConfigDirs = TQStringList::split(':', TQFile::decodeName(getenv("XDG_CONFIG_DIRS"))); + if (xdgConfigDirs.isEmpty()) + { + xdgConfigDirs << "/etc/xdg"; + TQString sysconfMenuDir = TDEGlobal::dirs()->findDirs("xdgconf-menu", TQString()).last(); + if (sysconfMenuDir.endsWith("/menus/")) + xdgConfigDirs << sysconfMenuDir.left(sysconfMenuDir.length()-7); + + } + + m_xdgConfigDirs.clear(); + for(TQStringList::ConstIterator it = dirs.begin(); + it != dirs.end(); ++it) + { + m_xdgConfigDirs.append(*it+"/etc/xdg"); + } + + m_xdgConfigDirs += xdgConfigDirs; + filterDupes(m_xdgConfigDirs); +} + +void +KioskRun::deleteDir(const TQString &dir) +{ + if (dir.length() <= 1) // Safety + return; + if (!dir.startsWith("/")) // Safety + return; + Q_ASSERT(dir.startsWith(m_homeDir)); + + TDEProcess proc; + proc << "rm" << "-rf" << dir; + proc.start(TDEProcess::Block); +} + +void +KioskRun::applyEnvironment(TDEProcess *p) +{ + p->setEnvironment("HOME", m_homeDir); + p->setEnvironment("TDEHOME", m_homeDir+"/.trinity"); + p->setEnvironment("TDEROOTHOME", m_homeDir+"/.trinity"); + p->setEnvironment("TDEDIRS", 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+"/.trinity/DCOPserver"); + p->setEnvironment("TDE_KIOSK_NO_PROFILES", "true"); + if (m_noRestrictions) + p->setEnvironment("TDE_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 + TQString sycocaUpdateFile = KioskRun::self()->locateLocal("services", "update_tdesycoca"); + TQFile file(sycocaUpdateFile); + file.remove(); + file.open(IO_WriteOnly); + file.close(); + + dcopRef("kded", "tdebuildsycoca").call("recreate"); +} + +TDEProcess* +KioskRun::run(const TQString &cmd, const TQStringList &args) +{ + TDEProcess *proc = new TDEProcess(this); + + applyEnvironment(proc); + + *proc << cmd; + *proc << args; + + proc->start(TDEProcess::NotifyOnExit); + return proc; +} + +class SetEnv +{ +public: + SetEnv(const char *key, const TQString &value) : m_key(key) + { + m_oldValue = getenv(m_key); + setenv(m_key, TQFile::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; + TQCString m_oldValue; +}; + +void +KioskRun::setupConfigEnv() +{ + if (m_instance) return; + + // ::locateLocal must be called before we change the env. vars! + TQString newTmpDir = ::locateLocal("tmp", "kioskdir"); + TQString newSocketDir = ::locateLocal("socket", "kioskdir"); + + SetEnv home("HOME", m_homeDir); + TQString kdeHome = m_homeDir+"/.trinity"; + SetEnv tdehome("TDEHOME", kdeHome); + SetEnv tderoothome("TDEROOTHOME", kdeHome); + SetEnv tdedirs("TDEDIRS", 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(TQFile::encodeName(m_homeDir), 0700); + ::mkdir(TQFile::encodeName(kdeHome), 0700); + + // Create temp & socket dirs. + char hostname[256]; + hostname[0] = 0; + gethostname(hostname, 255); + + TQString tmpDir = TQString("%1/%2-%3").arg(kdeHome).arg("tmp").arg(hostname); + deleteDir(tmpDir); + ::mkdir(TQFile::encodeName(newTmpDir), 0700); + ::symlink(TQFile::encodeName(newTmpDir), TQFile::encodeName(tmpDir)); + + TQString socketDir = TQString("%1/%2-%3").arg(kdeHome).arg("socket").arg(hostname); + deleteDir(socketDir); + ::mkdir(TQFile::encodeName(newSocketDir), 0700); + ::symlink(TQFile::encodeName(newSocketDir), TQFile::encodeName(socketDir)); + + m_configDir = TQString("%1/.trinity/share/config/").arg(m_homeDir); + + m_instance = new TDEInstance("kioskrun"); + (void) m_instance->dirs(); // Create TDEStandardDirs obj + + m_desktopPath = m_homeDir + "/Desktop/"; + m_desktopPath = m_instance->config()->readPathEntry( "Desktop", m_desktopPath); + m_desktopPath = TQDir::cleanDirPath( m_desktopPath ); + if ( !m_desktopPath.endsWith("/") ) + m_desktopPath.append('/'); + + { + SetEnv tdehome("TDEHOME", "-"); + SetEnv tderoothome("TDEROOTHOME", "-"); + SetEnv xdgDataHome("XDG_DATA_HOME", m_xdgDataDirs.first()); + SetEnv xdgConfigHome("XDG_CONFIG_HOME", m_xdgConfigDirs.first()); + + m_saveInstance = new TDEInstance("kioskrun"); + (void) m_saveInstance->dirs(); // Create TDEStandardDirs obj + } +} + +TQString +KioskRun::locate(const char *resource, const TQString &filename) +{ + setupConfigEnv(); + + return m_saveInstance->dirs()->findResource(resource, filename); +} + +TQString +KioskRun::locateSave(const char *resource, const TQString &filename) +{ + setupConfigEnv(); + + // split path from filename + int slash = filename.findRev('/')+1; + TQString dir = filename.left(slash); + TQString file = filename.mid(slash); + return m_saveInstance->dirs()->saveLocation(resource, dir, false) + file; +} + +TQString +KioskRun::locateLocal(const char *resource, const TQString &filename) +{ + setupConfigEnv(); + + // split path from filename + int slash = filename.findRev('/')+1; + TQString dir = filename.left(slash); + TQString 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; + TQDict<int> m_lines; + TQString m_tmpFile; + bool m_dirty; +}; + + +bool +KioskRun::isConfigImmutable(const TQString &filename, const TQString &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 TQString &filename, const TQString &_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 + { + TQString group = TQString("[%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(TQString &ext) +{ + ext.replace("i", ""); + if (ext == "[$]") + ext = TQString(); +} + +static void addImmutable(TQString &ext) +{ + ext.replace("[$", "[$i"); +} + +TQString +KioskRun::saveImmutableStatus(const TQString &filename) +{ + ImmutableStatus *status = new ImmutableStatus; + status->m_fileScope = false; + status->m_dirty = false; + m_immutableStatusCache.insert(filename, status); + + KTempFile tmp; + tmp.close(); + + TQString newPath = tmp.name(); + status->m_tmpFile = tmp.name(); + + TQString path = m_saveInstance->dirs()->findResource("config", filename); + if (path.isEmpty()) + return newPath; // Nothing to do + + TQFile oldCfg(path); + + if (!oldCfg.open( IO_ReadOnly )) + return newPath; // Error + + TQFile newCfg(newPath); + if (!newCfg.open( IO_WriteOnly )) + return newPath; // Error + + TQTextStream txtIn(&oldCfg); + txtIn.setEncoding(TQTextStream::UnicodeUTF8); + + TQTextStream pTxtOut(&newCfg); + pTxtOut.setEncoding(TQTextStream::UnicodeUTF8); + + TQRegExp immutable("(\\[\\$e?ie?\\])$"); + + // TODO: Use "group+key" instead of "key" as index, otherwise it might not be unique + + while(! txtIn.atEnd()) + { + TQString line = txtIn.readLine().stripWhiteSpace(); + + if (line.startsWith("#")) + { + // Comment, do nothing... + } + else if (line.startsWith("[")) + { + int pos = immutable.searchRev(line); + if (pos != -1) + { + TQString group = line.left(pos); + TQString 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) + { + TQString key = line.left(equal).stripWhiteSpace(); + int pos = immutable.searchRev(key); + if (pos != -1) + { + key = key.left(pos); + TQString 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 TQString &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; + + TQString path = status->m_tmpFile; + + KSaveFile newCfg(path); + if (newCfg.status() != 0) + { + delete status; + return true; // Continue + } + + TQTextStream *pTxtOut = newCfg.textStream(); + pTxtOut->setEncoding(TQTextStream::UnicodeUTF8); + + TQRegExp option("(\\[\\$e\\])$"); + + if (status->m_fileScope) + { + kdDebug() << "Marking file " << filename << " immutable" << endl; + (*pTxtOut) << "[$i]" << endl; + } + + TQFile oldCfg(path); + if (oldCfg.open( IO_ReadOnly )) + { + + TQTextStream txtIn(&oldCfg); + txtIn.setEncoding(TQTextStream::UnicodeUTF8); + + while(! txtIn.atEnd()) + { + TQString 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) + { + TQString key = line.left(equal).stripWhiteSpace(); + int pos = option.searchRev(key); + if (pos != -1) + { + key = key.left(pos); + TQString 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 + TQDictIterator<int> it( status->m_lines ); + for( ; it.current(); ++it ) + { + TQString group = it.currentKey(); + if ( it.current() ) + (*pTxtOut) << endl << group << "[$i]" << endl; + } + + if (!newCfg.close()) + { + kdWarning() << "Error writing" << path << endl; + delete status; + return true; // Continue + } + + TQString installLocation = m_saveInstance->dirs()->saveLocation("config", TQString(), 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() ) + { + TQDictIterator<TDEConfig> it( m_saveConfigCache ); + TQString file = it.currentKey(); + TDEConfig *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; +} + +TDEConfig * +KioskRun::configFile(const TQString &filename) +{ + TDEConfig *config = m_saveConfigCache.find(filename); + if (config) + return config; + + kdDebug() << "KioskRun::configFile(" << filename << ") loading file" << endl; + + setupConfigEnv(); + + TQString saveLocation = saveImmutableStatus(filename); + config = new KSimpleConfig(saveLocation); + m_saveConfigCache.insert(filename, config); + + return config; +} + +void +KioskRun::makeMutable(bool bMutable) +{ + TDEConfig *config = configFile("kdeglobals"); + + m_noRestrictions = bMutable; + if (KDE::version() < TDE_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", TQString()); + } + } + // Propagate to tdeinit + dcopRef("tdelauncher", "tdelauncher").call("setLaunchEnv", + TQCString("TDE_KIOSK_NO_RESTRICTIONS"), TQCString(m_noRestrictions ? "true" : "")); + + setConfigImmutable("kdeglobals", "KDE Action Restrictions", true); +} + +TQStringList +KioskRun::newConfigFiles() +{ + setupConfigEnv(); + + TQStringList exceptions; + exceptions << "tdeconf_updaterc"; + + TQStringList result; + TQDir dir(m_configDir); + dir.setFilter( TQDir::Files | TQDir::NoSymLinks ); + + const TQFileInfoList *list = dir.entryInfoList(); + if (!list) return result; + + TQFileInfoListIterator it( *list ); + TQFileInfo *fi; + while ( (fi = it.current()) != 0 ) + { + TQString file = fi->fileName(); + if (!file.endsWith("~") && !exceptions.contains(file)) // Skip backup files & exceptions + result.append(file); + ++it; + } + return result; +} + +void +KioskRun::mergeConfigFile(const TQString &filename) +{ + TDEConfig *saveCfg = configFile(filename); + + kdDebug() << "KioskRun::mergeConfigFile(" << (m_configDir + filename) << ")" << endl; + KSimpleConfig newCfg(m_configDir + filename); + + TQStringList groups = newCfg.groupList(); + for(TQStringList::ConstIterator it = groups.begin(); + it != groups.end(); ++it) + { + saveCfg->setGroup(*it); + TQMap<TQString, TQString> map = newCfg.entryMap(*it); + for(TQMap<TQString, TQString>::Iterator it2 = map.begin(); + it2 != map.end(); ++it2) + { +#ifdef DEBUG_ENTRIES +tqWarning("[%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); + TQString cacheDir = TQString("%1/.trinity/cache-%2").arg(m_homeDir).arg(hostname); + + deleteDir(cacheDir); + TDEStandardDirs::makeDir(cacheDir); + deleteDir(m_homeDir+"/.qt"); + ::unlink(TQFile::encodeName(m_homeDir+".kderc")); + + + TQString iceAuth = TQString("%1/.ICEauthority").arg(TQDir::homeDirPath()); + setenv("ICEAUTHORITY", TQFile::encodeName(iceAuth), 0); // Don't overwrite existing setting + + TQString xAuth = TQString("%1/.Xauthority").arg(TQDir::homeDirPath()); + setenv("XAUTHORITY", TQFile::encodeName(xAuth), 0); // Don't overwrite existing setting + + TQString dcopServerFile = m_homeDir+"/.trinity/DCOPserver"; + + TDEProcess tdeinit; + + applyEnvironment(&tdeinit); + + tdeinit << "tdeinit"; + + connect(&tdeinit, TQT_SIGNAL(processExited(TDEProcess *)), &dlg, TQT_SLOT(slotFinished())); + + tdeinit.start(TDEProcess::NotifyOnExit); + + dlg.exec(); + + TQCString dcopSrv; + TQFile f(dcopServerFile); + if (f.open(IO_ReadOnly)) + { + int size = TQMIN( 1024, f.size() ); // protection against a huge file + TQCString 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; + + TDEProcess tdeinit; + applyEnvironment(&tdeinit); + + tdeinit << "tdeinit_shutdown"; + + tdeinit.start(TDEProcess::Block); + + TDEProcess dcopserver; + applyEnvironment(&dcopserver); + + dcopserver << "dcopserver_shutdown"; + + dcopserver.start(TDEProcess::Block); +} + +DCOPRef +KioskRun::dcopRef(const TQCString &appId, const TQCString &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 TQString &action) +{ + TDEConfig *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 TQString &action, bool checked) +{ + TDEConfig *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 TQString &dir) +{ + if (TQDir(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; + + TQString error = NETACCESS::lastErrorString(); + TQString msg; + + if (error.isEmpty()) + msg = i18n("<qt>The directory <b>%1</b> could not be created because of an unspecified problem.<p>") + .arg(dir); + else + msg = i18n("<qt>The directory <b>%1</b> could not be created because of the following problem:" + "<p>%2<p>") + .arg(dir, NETACCESS::lastErrorString()); + + msg += i18n("Without this directory your changes can not be saved.<p>" + "Do you want to retry creating the directory or abort the saving of changes?</qt>"); + + int msgResult = KMessageBox::warningYesNo(kapp->mainWidget(), msg, TQString(), + i18n("&Retry"), i18n("&Abort")); + + if (msgResult == KMessageBox::No) + return false; + + // Maybe the user created it in the meantime + if (TQDir(dir).exists()) + return true; // Exists already + } + while (true); + return false; +} + +// Create directory +bool +KioskRun::createRemoteDirRecursive(const KURL &dest, bool ask) +{ + if (NETACCESS::exists(dest, false, kapp->mainWidget())) + return true; + + KURL parent = dest.upURL(); + + if (NETACCESS::exists(dest, false, kapp->mainWidget())) + { + return createRemoteDir(dest); + } + + if (ask) + { + // Parent doesn't exist, + int result = KMessageBox::warningContinueCancel(kapp->mainWidget(), + i18n("<qt>The directory <b>%1</b> does not yet exist. " + "Do you want to create it?").arg(parent.prettyURL()), TQString(), + i18n("Create &Dir")); + if (result != KMessageBox::Continue) + return false; + } + + TQString 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() == TDEIO::ERR_DIR_ALREADY_EXIST) + return true; +#endif + + //TODO Check directory already exists error + TQString error = NETACCESS::lastErrorString(); + TQString msg; + + if (error.isEmpty()) + msg = i18n("<qt>The directory <b>%1</b> could not be created because of an unspecified problem.<p>") + .arg(dest.prettyURL()); + else + msg = i18n("<qt>The directory <b>%1</b> could not be created because of the following problem:" + "<p>%2<p>") + .arg(dest.prettyURL(), NETACCESS::lastErrorString()); + + msg += i18n("Without this directory your files can not be uploaded.<p>" + "Do you want to retry creating the directory or abort uploading?</qt>"); + + int msgResult = KMessageBox::warningYesNo(kapp->mainWidget(), msg, TQString(), + i18n("&Retry"), i18n("&Abort")); + + if (msgResult == KMessageBox::No) + return false; + } + while (true); + return false; +} + +// Install file +bool +KioskRun::install(const TQString &file, const TQString &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(TQFile::encodeName(file)); + return true; + } + + TQString error = NETACCESS::lastErrorString(); + TQString msg; + if (error.isEmpty()) + msg = i18n("<qt>The file <b>%1</b> could not be installed because of an unspecified problem.") + .arg(destination); + else + msg = i18n("<qt>The file <b>%1</b> could not be installed because of the following problem:" + "<p>%2<p>") + .arg(destination, NETACCESS::lastErrorString()); + + msg += i18n("Do you want to retry the installation or abort the saving of changes?</qt>"); + + int msgResult = KMessageBox::warningYesNo(kapp->mainWidget(), msg, TQString(), + i18n("&Retry"), i18n("&Abort")); + + if (msgResult == KMessageBox::No) + return false; + } + while (true); + return false; +} + +// Upload file +bool +KioskRun::uploadRemote(const TQString &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; + + TQString error = NETACCESS::lastErrorString(); + TQString msg; + if (error.isEmpty()) + msg = i18n("<qt>The file <b>%1</b> could not be uploaded to <b>%2</b> because of an unspecified problem.") + .arg(file, dest.prettyURL()); + else + msg = i18n("<qt>The file <b>%1</b> could not be uploaded to <b>%2</b> because of the following problem:" + "<p>%3<p>") + .arg(file, dest.prettyURL(),NETACCESS::lastErrorString()); + + msg += i18n("Do you want to retry or abort the uploading?</qt>"); + + int msgResult = KMessageBox::warningYesNo(kapp->mainWidget(), msg, TQString(), + i18n("&Retry"), i18n("&Abort")); + + if (msgResult == KMessageBox::No) + return false; + } + while (true); + return false; +} + +// Remove file +bool +KioskRun::remove(const TQString &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 TQString &source, const TQString &destination, const TQStringList &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(TQStringList::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 TQString &profile, TQString &description, TQString &installDir, TQString &installUser) +{ + TDEConfig *config = kapp->config(); + + TQString defaultInstallDir = getProfilePrefix(); + if (defaultInstallDir.isEmpty()) + { + defaultInstallDir = "/etc/kde-profile/"; + } + if (!defaultInstallDir.endsWith("/")) + defaultInstallDir.append("/"); + TQString tmp = profile; + tmp.replace(" ", "_"); + tmp.replace(":", "_"); + tmp.replace("/", "_"); + defaultInstallDir += tmp+"/"; + + TQString group = TQString("Directories-%1").arg(profile); + config->setGroup(group); + + installDir = config->readEntry("prefixes", defaultInstallDir); + if (!installDir.endsWith("/")) + installDir.append("/"); + + TQString profileInfoFile = installDir + ".kdeprofile"; + if (TQFile::exists(profileInfoFile)) + { + KSimpleConfig profileInfo(profileInfoFile, true); + description = profileInfo.readEntry("Description"); + installUser = profileInfo.readEntry("InstallUser", "root"); + return; + } + + TQString 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(TQFile::encodeName(m_localKderc)); + + KURL localCopyUrl; + localCopyUrl.setPath(m_localKderc); + + if (TQFile::exists(settingsUrl.path())) + { + + while (!NETACCESS::copy(settingsUrl, localCopyUrl, kapp->mainWidget())) + { + TQString error = NETACCESS::lastErrorString(); + TQString msg; + if (error.isEmpty()) + msg = i18n("<qt>The file <b>%1</b> could not be accessed because of an unspecified problem.") + .arg(settingsUrl.path()); + else + msg = i18n("<qt>The file <b>%1</b> could not be accessed because of the following problem:" + "<p>%2<p>") + .arg(settingsUrl.path(), error); + + msg += i18n("Do you want to retry the operation or abort the saving of changes?</qt>"); + + int msgResult = KMessageBox::warningYesNo(kapp->mainWidget(), msg, TQString(), + 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; + + TQString saveUser = m_user; + m_user = "root"; + bool result = install(m_localKderc, m_kderc); + m_localKderc = TQString(); + m_user = saveUser; + kapp->config()->reparseConfiguration(); + return result; +} + +// Store information for profile @p profile +bool +KioskRun::setProfileInfo(const TQString &profile, const TQString &description, const TQString &_installDir, const TQString &installUser, bool deleteProfile, bool deleteFiles) +{ + TQString installDir = _installDir; + if (!installDir.endsWith("/")) + installDir.append("/"); + + TQString saveProfileInfo = installDir + ".kdeprofile"; + KSimpleConfig profileInfo(saveProfileInfo, true); + TQString oldDescription = profileInfo.readEntry("Description"); + TQString oldInstallUser = profileInfo.readEntry("InstallUser"); + if (deleteProfile && !installDir.isEmpty()) + { + bool result = true; + KioskSync profileDir(kapp->mainWidget()); + profileDir.addDir(installDir, KURL()); + TQStringList allFiles = profileDir.listFiles(); + allFiles.remove(".kdeprofile"); + if (allFiles.isEmpty()) + { + if (TQDir(installDir).exists()) + { + m_user = installUser; + remove(installDir); + m_user = TQString(); + } + } + else if (deleteFiles) + { + int msgResult = KMessageBox::warningYesNoCancelList(kapp->mainWidget(), + i18n("<qt>The profile directory <b>%1</b> contains the following files, " + "do you wish to delete these files?").arg(installDir), + allFiles, + i18n("Deleting Profile"), +#if KDE_IS_VERSION(3,2,91) + KStdGuiItem::del(), +#else + i18n("&Delete"), +#endif + i18n("&Keep Files") + ); + switch(msgResult) + { + case KMessageBox::Yes: + // Delete files + m_user = installUser; + result = remove(installDir); + m_user = TQString(); + if (!result) + return false; + break; + + case KMessageBox::No: + // Keep files + break; + + default: + // Cancel + return false; + } + } + + m_user = installUser; + if (TQFile::exists(saveProfileInfo)) + result = remove(saveProfileInfo); + m_user = TQString(); + if (!result) + return false; + } + else if ((description != oldDescription) || + (installUser != oldInstallUser)) + { + TQString localProfileInfo = ::locateLocal("tmp", "kdeprofile_"+kapp->randomString(5)); + ::unlink(TQFile::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; + TQString newAdmin = thisUser.loginName()+":"; // This user, all hosts + + TDEConfig *config = kapp->config(); + + config->setGroup("Directories"); + TQString oldAdmin = config->readEntry("kioskAdmin"); + + TQString group = TQString("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 TQString &profile, bool deleteFiles) +{ + TQString description; + TQString installDir; + TQString installUser; + getProfileInfo(profile, description, installDir, installUser); + return setProfileInfo(profile, description, installDir, installUser, true, deleteFiles); +} + +// Read profile prefix +TQString +KioskRun::getProfilePrefix() +{ + TDEConfig *config = kapp->config(); + + config->setGroup("Directories"); + + TQString prefix = config->readEntry("profileDirsPrefix"); + if (!prefix.isEmpty() && !prefix.endsWith("/")) + prefix.append('/'); + return prefix; +} + +// Store profile prefix +bool +KioskRun::setProfilePrefix(const TQString &_prefix) +{ + TQString 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(); +} + +TQString +KioskRun::newProfile() +{ + TQString profilePrefix = getProfilePrefix(); + + TDEConfig *config = kapp->config(); + for(int p = 1; p; p++) + { + TQString profile = TQString("profile%1").arg(p); + TQString group = TQString("Directories-%1").arg(profile); + if (!config->hasGroup(group)) + { + if (profilePrefix.isEmpty()) + return profile; + + TQString profileDir = profilePrefix + profile; + if (!TQDir(profileDir).exists() && !TQFile::exists(profileDir)) + return profile; + + // Keep on looking... + } + } + return TQString(); +} + +TQStringList +KioskRun::allProfiles() +{ + TDEConfig *config = kapp->config(); + TQStringList groups = config->groupList(); + TQStringList profiles; + TQStringList directories; + for(TQStringList::ConstIterator it = groups.begin(); + it != groups.end(); ++it) + { + if (!(*it).startsWith("Directories-")) + continue; + profiles.append((*it).mid(12)); + config->setGroup(*it); + TQString installDir = config->readEntry("prefixes"); + if (!installDir.endsWith("/")) + installDir.append("/"); + directories.append(installDir); + } + + TQString profilePrefix = getProfilePrefix(); + if (!profilePrefix.isEmpty()) + { + TQDir dir(profilePrefix, TQString(), TQDir::Unsorted, TQDir::Dirs); + TQStringList profileDirs = dir.entryList(); + for(TQStringList::ConstIterator it = profileDirs.begin(); + it != profileDirs.end(); ++it) + { + if ((*it).startsWith(".")) + continue; + TQString 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 (!TQFile::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, TQStringList &groupOrder) +{ + groups.clear(); + users.clear(); + + TDEConfig *config = kapp->config(); + config->setGroup("Directories"); + TQString mapFile = config->readEntry("userProfileMapFile"); + + if (mapFile.isEmpty() || !TQFile::exists(mapFile)) + return; + + KSimpleConfig mapCfg(mapFile, true); + + mapCfg.setGroup("General"); + groupOrder = mapCfg.readListEntry("groups"); + + mapCfg.setGroup("Groups"); + for ( TQStringList::ConstIterator it = groupOrder.begin(); + it != groupOrder.end(); ++it ) + { + TQString group = *it; + TQStringList profiles = mapCfg.readListEntry(group); + if (!profiles.isEmpty()) + groups.insert(group, profiles); + } + + TQMap<TQString, TQString> cfg_users = mapCfg.entryMap("Users"); + for ( TQMap<TQString, TQString>::Iterator it = cfg_users.begin(); + it != cfg_users.end(); ++it ) + { + TQString user = it.key(); + TQStringList profiles = TQStringList::split(",", it.data()); + if (!profiles.isEmpty()) + users.insert(user, profiles); + } +} + +bool +KioskRun::setUserProfileMappings( const ProfileMapping &groups, const ProfileMapping &users, const TQStringList &groupOrder) +{ + TDEConfig *config = kapp->config(); + config->setGroup("Directories"); + TQString 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; + } + + TQString localMapFile = ::locateLocal("tmp", "kde-user-profile_"+kapp->randomString(5)); + ::unlink(TQFile::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 ) + { + TQString group = it.key(); + mapConfig.writeEntry(group, it.data()); + } + mapConfig.setGroup("Users"); + for ( it = users.begin(); it != users.end(); ++it ) + { + TQString user = it.key(); + mapConfig.writeEntry(user, it.data()); + } + + mapConfig.sync(); + + TQString saveUser = m_user; + m_user = "root"; + bool result = install(localMapFile, mapFile); + m_user = saveUser; + return result; +} + +void +KioskRun::forceSycocaUpdate() +{ + // Touch $TDEDIR/share/services/update_tdesycoca + KTempFile tempFile; + tempFile.close(); + TQString sycocaUpdateFile = locateSave("services", "update_tdesycoca"); + remove(sycocaUpdateFile); + install(tempFile.name(), sycocaUpdateFile); +} + +void +KioskRun::scheduleSycocaUpdate() +{ + m_forceSycocaUpdate = true; +} + +void +KioskRun::setCustomRestrictionFileBrowsing(bool restrict) +{ + TQString file = "kdeglobals"; + TQString group = "KDE URL Restrictions"; + TDEConfig *cfg = KioskRun::self()->configFile(file); + cfg->setGroup(group); + int count = cfg->readNumEntry("rule_count"); + TQStringList urlRestrictions; + for(int i = 0; i < count; i++) + { + TQString key = TQString("rule_%1").arg(i+1); + if (cfg->hasKey(key)) + urlRestrictions.append(cfg->readEntry(key)); + } + + TQStringList newRestrictions; + newRestrictions << "list,,,,file,,,false"; + newRestrictions << "list,,,,file,,$HOME,true"; + + for(TQStringList::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++) + { + TQString key = TQString("rule_%1").arg(i+1); + cfg->writeEntry(key, urlRestrictions[i]); + } + KioskRun::self()->setConfigImmutable(file, group, true); +} + +KioskRunProgressDialog::KioskRunProgressDialog(TQWidget *parent, const char *name, + const TQString &caption, const TQString &text) + : KProgressDialog(parent, name, caption, text, true) +{ + connect(&m_timer, TQT_SIGNAL(timeout()), this, TQT_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(); + TQTimer::singleShot(1000, this, TQT_SLOT(close())); +} + + +#include "kioskrun.moc" + diff --git a/kiostdetool/kioskrun.h b/kiostdetool/kioskrun.h new file mode 100644 index 0000000..54a25a2 --- /dev/null +++ b/kiostdetool/kioskrun.h @@ -0,0 +1,231 @@ +/* + * kioskrun.h + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _KIOSKRUN_H_ +#define _KIOSKRUN_H_ + +#include <tqdict.h> +#include <tqobject.h> +#include <tqregexp.h> +#include <tqstringlist.h> +#include <tqtimer.h> + +#include <dcopclient.h> +#include <dcopref.h> + +#include <kprogress.h> + +class ImmutableStatus; +class TDEConfig; +class TDEProcess; +class KSimpleConfig; + +class KioskGui; + +class KioskRun : public TQObject +{ + friend class KioskGui; + + Q_OBJECT + +public: + static KioskRun* self() { return s_self; } + + void setKdeDirs(const TQStringList &dirs); + void setUser(const TQString &user); + + TQString homeDir() { return m_homeDir; } + TQStringList kdeDirs() { return m_kdeDirs; } + TQString desktopPath() { return m_desktopPath; } + + // Locate existing anywhere + TQString locate(const char *resource, const TQString &filename=TQString()); + + // Locate for saving + TQString locateSave(const char *resource, const TQString &filename=TQString()); + + // Locate for reading saved changed + TQString locateLocal(const char *resource, const TQString &filename=TQString()); + + // 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 + TDEProcess* run(const TQString &cmd, const TQStringList &args=TQStringList()); + + // A DCOPRef to make dcop calls into the runtime test environment + DCOPRef dcopRef(const TQCString &appId, const TQCString &objId); + + // A DCOPClient to make dcop calls into the runtime test environment + DCOPClient *dcopClient() { return m_dcopClient; } + + // Open config file in the install directory + TDEConfig *configFile(const TQString &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 TQString &filename, const TQString &group); + + // Make specific config group immutable, + // or entire file if group is empty + void setConfigImmutable(const TQString &filename, const TQString &group, bool bImmutable); + + // Close all opened config files. + bool flushConfigCache(); + + // Return all config files created by the user + TQStringList newConfigFiles(); + + // Merge new settings from the test directory into the installation directory + void mergeConfigFile(const TQString &filename); + + // Lookup the setting for a custom action + bool lookupCustomAction(const TQString &action); + + // Change the setting for a custom action + void setCustomAction(const TQString &action, bool checked); + + // Create installation directory and its parent dirs + bool createDir(const TQString &dir); + + // Install file + bool install(const TQString &file, const TQString &destination); + + // Delete file + bool remove(const TQString &destination); + + // Move file or directory + bool move(const TQString &source, const TQString &destination, const TQStringList &files); + + // Delete directory in test home dir + void deleteDir(const TQString &); + + // Open /etc/kderc for writing + KSimpleConfig *openKderc(); + + // Install new /etc/kderc + bool closeKderc(); + + // Read information of profile @p profile + void getProfileInfo(const TQString &profile, TQString &description, TQString &installDir, TQString &installUser); + + // Store information for profile @p profile + bool setProfileInfo(const TQString &profile, const TQString &description, const TQString &installDir, const TQString &installUser, bool b=false, bool deleteFiles=true); + + // Get new, non-existing, profile name + TQString newProfile(); + + // Delete profile @p profile + bool deleteProfile(const TQString &profile, bool deleteFiles = true); + + // Get list of all existing profiles + TQStringList allProfiles(); + + // Maps a single group or user to a one or more profiles + typedef TQMap<TQString,TQStringList> ProfileMapping; + + // Read mappings between groups/users and profiles + void getUserProfileMappings( ProfileMapping &groups, ProfileMapping &users, TQStringList &groupOrder); + + // Store mappings between groups/users and profiles + bool setUserProfileMappings( const ProfileMapping &groups, const ProfileMapping &users, const TQStringList &groupOrder); + + // Read profile prefix + TQString getProfilePrefix(); + + // Store profile prefix + bool setProfilePrefix(const TQString &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 TQString &file, const KURL &dest); + +protected: + KioskRun( TQObject* parent = 0, const char* name = 0); + ~KioskRun(); + + bool setupRuntimeEnv(); + void shutdownRuntimeEnv(); + void setupConfigEnv(); + void shutdownConfigEnv(); + void applyEnvironment(TDEProcess *p); + + TQString saveImmutableStatus(const TQString &filename); + bool restoreImmutableStatus(const TQString &filename, bool force); + + void setCustomRestrictionFileBrowsing(bool restrict); + +private: + static KioskRun* s_self; + TQString m_homeDir; + TQString m_configDir; + TQString m_desktopPath; + TQString m_user; + TQStringList m_kdeDirs; + TQStringList m_xdgDataDirs; + TQStringList m_xdgConfigDirs; + DCOPClient *m_dcopClient; + TDEInstance *m_instance; + TDEInstance *m_saveInstance; + TQDict<TDEConfig> m_saveConfigCache; + TQDict<ImmutableStatus> m_immutableStatusCache; + bool m_noRestrictions; + bool m_forceSycocaUpdate; + bool m_isRoot; + + TQString m_kderc; + TQString m_localKderc; + KSimpleConfig *m_localKdercConfig; +}; + + +class KioskRunProgressDialog : public KProgressDialog +{ + Q_OBJECT + +public: + KioskRunProgressDialog(TQWidget *parent, const char *name, + const TQString &caption, const TQString &text); +public slots: + void slotProgress(); + void slotFinished(); + +private: + TQTimer m_timer; + int m_timeStep; +}; + + +#endif diff --git a/kiostdetool/kiosksync.cpp b/kiostdetool/kiosksync.cpp new file mode 100644 index 0000000..3f20044 --- /dev/null +++ b/kiostdetool/kiosksync.cpp @@ -0,0 +1,211 @@ +/* + * kiosksync.cpp + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "kiosksync.h" + +#include <tqdir.h> +#include <tqwidget.h> + +#include <kdebug.h> +#include <klocale.h> +#include <ksimpleconfig.h> +#include <kstandarddirs.h> + +KioskSync::KioskSync( TQWidget* parent, const char* name) + : TQObject(parent, name), + m_parent(parent) +{ +} + +KioskSync::~KioskSync() +{ +} + +void +KioskSync::addDir(const TQString &_src, const KURL &dest) +{ + TQString 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, TQString()); + + for(TQStringList::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(TQStringList::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; +} + +TQStringList +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, TQString()); + } + return m_changedFiles; +} + +void +KioskSync::addChangedDir(const TQString &dir) +{ + if (dir.isEmpty()) + return; + + if (m_changedDirs.contains(dir)) + return; + + int i = dir.findRev('/', -2); + if (i != -1) + { + TQString parentDir = dir.left(i+1); + addChangedDir(parentDir); + } + + kdDebug() << "KioskSync: Adding " << dir << endl; + m_changedDirs.append(dir); +} + +void +KioskSync::scanChangedFiles(const TQString &_dir, const TQString &prefix) +{ + kdDebug() << "KioskSync: Scanning " << _dir << endl; + TQDir dir(_dir); + if (!dir.exists()) + { + emit warning(i18n("Directory <b>%1</b> does not exist.").arg(_dir)); + return; + } + if (!dir.isReadable()) + { + emit warning(i18n("Directory <b>%1</b> is not readable.").arg(_dir)); + return; + } + + TQStringList subDirs; + const TQFileInfoList *list = dir.entryInfoList(TQDir::Dirs | TQDir::Files | TQDir::NoSymLinks); + + bool dirtyDir = false; + TQFileInfoListIterator it( *list ); + for ( TQFileInfo *fi; (fi = it.current()) != 0; ++it) + { + if (fi->isDir()) + { + TQString subDir = fi->fileName(); + if ((subDir != ".") && (subDir != "..")) + subDirs.append(subDir+"/"); + continue; + } + + // TODO: Check file + TQString file = prefix + fi->fileName(); + TQDateTime 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( TQStringList::ConstIterator it = subDirs.begin(); + it != subDirs.end(); ++it) + { + TQString subDir = *it; + scanChangedFiles(_dir + subDir, prefix + subDir); + } +} + +bool +KioskSync::syncFile(const TQString &prefix, const TQString &file, const KURL &dest) +{ + kdDebug() << "KioskSync: Syncing [" << prefix << "]" << file << " --> " << dest.prettyURL() << endl; + + if (!KioskRun::self()->uploadRemote(prefix+file, dest)) + return false; + + TQFileInfo fi(prefix+file); + m_timestamps->writeEntry(file, fi.lastModified()); + return true; +} + +#include "kiosksync.moc" diff --git a/kiostdetool/kiosksync.h b/kiostdetool/kiosksync.h new file mode 100644 index 0000000..9218f77 --- /dev/null +++ b/kiostdetool/kiosksync.h @@ -0,0 +1,81 @@ +/* + * kiosksync.h + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _KIOSKSYNC_H_ +#define _KIOSKSYNC_H_ + +#include <tqobject.h> +#include <tqstringlist.h> + +#include <kurl.h> + +#include "kioskrun.h" + +class TQWidget; +class KSimpleConfig; + +class KioskSync : public TQObject +{ + Q_OBJECT + +public: + KioskSync( TQWidget* parent = 0, const char* name = 0); + ~KioskSync(); + + void addDir(const TQString &src, const KURL &dest); + bool sync(bool incremental = false); + // Returns all files found in the directories + TQStringList listFiles(); + +signals: + void finished(); + void status(const TQString &); + void warning(const TQString &); + +protected: + void scanChangedFiles(const TQString &_dir, const TQString &prefix); + bool syncFile(const TQString &prefix, const TQString &file, const KURL &dest); + void addChangedDir(const TQString &dir); + +private: + struct SyncDir + { + SyncDir() + { } + + SyncDir(const TQString &_src, const KURL &_dest) : src(_src), dest(_dest) + { } + + SyncDir(const SyncDir &dir) : src(dir.src), dest(dir.dest) + { } + + TQString src; + KURL dest; + }; + + typedef TQValueList<SyncDir> SyncDirList; + + SyncDirList m_syncDirs; + TQWidget *m_parent; + KSimpleConfig *m_timestamps; + TQStringList m_changedFiles; + TQStringList m_changedDirs; + bool m_incremental; +}; + +#endif diff --git a/kiostdetool/kiostdetool-tdedirs.cpp b/kiostdetool/kiostdetool-tdedirs.cpp new file mode 100644 index 0000000..7f8b1f7 --- /dev/null +++ b/kiostdetool/kiostdetool-tdedirs.cpp @@ -0,0 +1,184 @@ +/* + * kiosktool-tdedirs.cpp + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License versin 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <config.h> + +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <pwd.h> +#include <grp.h> + +#include <tqfile.h> + +#include <kaboutdata.h> +#include <kcmdlineargs.h> +#include <kglobal.h> +#include <klocale.h> +#include <kinstance.h> +#include <kshell.h> +#include <ksimpleconfig.h> +#include <kstandarddirs.h> + +static const char *description = I18N_NOOP("A tool to set $TDEDIRS according to the current user profile."); + + +static TQString readEnvPath(const char *env) +{ + TQCString c_path = getenv(env); + if (c_path.isEmpty()) + return TQString(); + return TQFile::decodeName(c_path); +} + +static TQStringList lookupProfiles(const TQString &mapFile) +{ + TQStringList profiles; + + if (mapFile.isEmpty() || !TQFile::exists(mapFile)) + { + profiles << "default"; + return profiles; + } + + struct passwd *pw = getpwuid(geteuid()); + if (!pw) + { + profiles << "default"; + return profiles; // Not good + } + + TQCString 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"); + TQStringList groups = mapCfg.readListEntry("groups"); + + mapCfg.setGroup("Groups"); + + for( TQStringList::ConstIterator it = groups.begin(); + it != groups.end(); ++it ) + { + TQCString 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) +{ + TDELocale::setMainCatalogue("kiosktool"); + TDEAboutData about("kiosktool-tdedirs", "kiosktool-tdedirs", "1.0", description, TDEAboutData::License_GPL, "(C) 2004 Waldo Bastian"); + TDECmdLineArgs::init( argc, argv, &about); + TDECmdLineArgs::addCmdLineOptions(options); + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + + TDEInstance a("kiosktool-tdedirs"); + + if (args->isSet("check")) + { + (void) TDEGlobal::config(); // Force config file processing + TQString dirs = TDEGlobal::dirs()->kfsstnd_prefixes(); + printf("%s\n", TQFile::encodeName(dirs).data()); + return 0; + } + + TQStringList tdedirList; + + // begin TDEDIRS + TQString tdedirs = readEnvPath("TDEDIRS"); + if (!tdedirs.isEmpty()) + { + tdedirList = TQStringList::split(":", tdedirs); + } + else + { + TQString tdedir = readEnvPath("TDEDIR"); + if (!tdedir.isEmpty()) + { + tdedir = KShell::tildeExpand(tdedir); + tdedirList.append(tdedir); + } + } + + TDEConfig *config = TDEGlobal::config(); + config->setGroup("Directories"); + TQString userMapFile = config->readEntry("userProfileMapFile"); + TQString profileDirsPrefix = config->readEntry("profileDirsPrefix"); + if (!profileDirsPrefix.isEmpty() && !profileDirsPrefix.endsWith("/")) + profileDirsPrefix.append('/'); + TQStringList profiles = lookupProfiles(userMapFile); + + while(!profiles.isEmpty()) + { + TQString profile = profiles.back(); + config->setGroup(TQString::fromLatin1("Directories-%1").arg(profile)); + profiles.pop_back(); + TQStringList list = config->readListEntry("prefixes"); + for (TQStringList::ConstIterator it = list.begin(); it != list.end(); it++) + { + tdedirList.prepend(*it); + } + if (list.isEmpty() && !profile.isEmpty() && !profileDirsPrefix.isEmpty()) + { + tdedirList.prepend(profileDirsPrefix + profile); + } + } + printf("%s\n", TQFile::encodeName(tdedirList.join(":")).data()); + + return 0; +} diff --git a/kiostdetool/kiostdetool.desktop b/kiostdetool/kiostdetool.desktop new file mode 100644 index 0000000..96faf29 --- /dev/null +++ b/kiostdetool/kiostdetool.desktop @@ -0,0 +1,28 @@ +[Desktop Entry] +Encoding=UTF-8 +Type=Application +Exec=kiosktool +Icon=kiosktool +DocPath=kioskgui/index.html +X-TDE-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-TDE-AuthorizeAction=user/root +X-DCOP-ServiceType=None +Categories=Qt;TDE;System; diff --git a/kiostdetool/kiostdetoolui.rc b/kiostdetool/kiostdetoolui.rc new file mode 100644 index 0000000..7ab96c6 --- /dev/null +++ b/kiostdetool/kiostdetoolui.rc @@ -0,0 +1,13 @@ +<?xml version="1.0"?> +<!DOCTYPE gui SYSTEM "kpartgui.dtd"> +<gui name="kioskgui" version="3"> +<MenuBar> + <Menu name="file"> + <Action name="upload_all"/> + </Menu> + <Menu name="settings"> + <Action name="show_background" append="show_merge"/> + </Menu> +</MenuBar> +</gui> + diff --git a/kiostdetool/logo.png b/kiostdetool/logo.png Binary files differnew file mode 100644 index 0000000..f3163c0 --- /dev/null +++ b/kiostdetool/logo.png diff --git a/kiostdetool/main.cpp b/kiostdetool/main.cpp new file mode 100644 index 0000000..716b894 --- /dev/null +++ b/kiostdetool/main.cpp @@ -0,0 +1,80 @@ +/* + * main.cpp + * + * Copyright (C) 2003,2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License versin 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include "kioskgui.h" + +#include <dcopclient.h> + +#include <tqfile.h> + +#include <kaboutdata.h> +#include <kapplication.h> +#include <kcmdlineargs.h> +#include <tdeversion.h> +#include <klocale.h> +#include <kmessagebox.h> + +static const char *description = + I18N_NOOP("KIOSK Admin Tool"); + +static const char *version = "1.0"; + +#ifndef KDERC +#define KDERC "/etc/kderc" +#endif + +static const KCmdLineOptions options[] = +{ + { "kderc <file>", I18N_NOOP("kderc file to save settings to"), KDERC }, + KCmdLineLastOption +}; + +int main(int argc, char *argv[]) +{ + TDEAboutData aboutData( "kiosktool", I18N_NOOP("KIOSK Admin Tool"), + version, description, TDEAboutData::License_GPL_V2, + "(c) 2003,2004 Waldo Bastian"); + aboutData.addAuthor("Waldo Bastian",I18N_NOOP("Author"), "bastian@kde.org"); + + TDECmdLineArgs::init(argc, argv, &aboutData); + + TDECmdLineArgs::addCmdLineOptions( options ); + + TDEApplication a; + + KioskGui *w = new KioskGui(); + a.setMainWidget(w); + w->show(); + + bool versionOk; + if (TQFile::exists("/etc/SuSE-release")) + versionOk = KDE::version() >= TDE_MAKE_VERSION(3,2,1); + else + versionOk = KDE::version() >= TDE_MAKE_VERSION(3,2,2); + + if (!versionOk) + { + KMessageBox::information(w, i18n("<qt>KIOSK Admin Tool requires KDE 3.2.2 or later!<p>" + "With older versions you may experience problems with" + "the <i>Setup</i> functionality of the various components.")); + } + + kapp->exec(); + + return 0; +} diff --git a/kiostdetool/mainview.ui b/kiostdetool/mainview.ui new file mode 100644 index 0000000..9cd33c8 --- /dev/null +++ b/kiostdetool/mainview.ui @@ -0,0 +1,258 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>MainView</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>MainView</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>573</width> + <height>526</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="TQLabel" row="0" column="2" rowspan="1" colspan="3"> + <property name="name"> + <cstring>captionLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>70</height> + </size> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + </widget> + <widget class="TQLabel" row="0" column="0" rowspan="2" colspan="2"> + <property name="name"> + <cstring>logoLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>160</width> + <height>170</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLabel" row="1" column="2"> + <property name="name"> + <cstring>subCaptionLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <property name="alignment"> + <set>AlignCenter</set> + </property> + </widget> + <spacer row="2" column="0"> + <property name="name"> + <cstring>spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>25</width> + <height>20</height> + </size> + </property> + </spacer> + <spacer row="2" column="4"> + <property name="name"> + <cstring>spacer5_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>25</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQLayoutWidget" row="2" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQWidgetStack"> + <property name="name"> + <cstring>widgetStack</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>1</verstretch> + </sizepolicy> + </property> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>0</number> + </attribute> + </widget> + </widget> + <widget class="TQFrame"> + <property name="name"> + <cstring>frame3</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Raised</enum> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQPushButton"> + <property name="name"> + <cstring>pbHelp</cstring> + </property> + <property name="text"> + <string>&Help</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQPushButton"> + <property name="name"> + <cstring>pbDiscard</cstring> + </property> + <property name="text"> + <string>&Discard Changes</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQPushButton"> + <property name="name"> + <cstring>pbFinished</cstring> + </property> + <property name="text"> + <string>&Finished</string> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + <spacer row="1" column="3" rowspan="1" colspan="2"> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>160</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kiostdetool/menueditComponent.cpp b/kiostdetool/menueditComponent.cpp new file mode 100644 index 0000000..c087e91 --- /dev/null +++ b/kiostdetool/menueditComponent.cpp @@ -0,0 +1,241 @@ +/* + * menueditComponent.cpp + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "menueditComponent.h" + +#include <tqdir.h> +#include <tqdom.h> +#include <tqfileinfo.h> + +#include <kapplication.h> +#include <kdebug.h> +#include <kmimetype.h> +#include <kprocess.h> +#include <ksavefile.h> +#include <ksimpleconfig.h> +#include <kstandarddirs.h> +#include <kurl.h> + +#include "kioskrun.h" +#include "kiosksync.h" + +MenuEditComponent::MenuEditComponent( TQObject *parent) + : Component(parent) +{ +} + +MenuEditComponent::~MenuEditComponent() +{ +} + +void +MenuEditComponent::slotSetupPrepare() +{ + (void) KioskRun::self()->locateLocal("xdgconf-menu", "applications-kmenuedit.menu"); // Create dir +} + +void +MenuEditComponent::slotSetupStarted() +{ +} + +static TQDomDocument loadDoc(const TQString &fileName) +{ + TQDomDocument doc; + + TQFile file( fileName ); + if ( !file.open( IO_ReadOnly ) ) + { + kdWarning() << "Could not open " << fileName << endl; + return doc; + } + TQString 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 TQString &fileName, TQDomDocument doc) +{ + KSaveFile saveFile(fileName); + + TQTextStream *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; + TQString menuEditFile = KioskRun::self()->locateLocal("xdgconf-menu", "applications-kmenuedit.menu"); + TQString menuFile = KioskRun::self()->locate("xdgconf-menu", "applications.menu"); + TQString menuFileSave = KioskRun::self()->locateSave("xdgconf-menu", "applications.menu"); + + kdDebug() << "MenuEditComponent: menuEditFile = " << menuEditFile << endl; + kdDebug() << "MenuEditComponent: menuFile = " << menuFile << endl; + kdDebug() << "MenuEditComponent: menuFileSave = " << menuFileSave << endl; + + TQDomDocument docChanges = loadDoc(menuEditFile); + if (docChanges.isNull()) + { + kdDebug() << "No menu changes." << endl; + return true; + } + + TQDomDocument doc = loadDoc(menuFile); + if (doc.isNull()) + { + kdWarning() << "Can't find menu file!" << endl; + return true; + } + + TQDomElement docElem = doc.documentElement(); + TQDomNode n = docElem.firstChild(); + TQDomNode next; + for(; !n.isNull(); n = next ) + { + TQDomElement e = n.toElement(); // try to convert the node to an element. + next = n.nextSibling(); + + if ((e.tagName() == "MergeFile") && (e.text() == "applications-kmenuedit.menu")) + break; + } + TQDomNode insertionPoint = n; + if (insertionPoint.isNull()) + { + kdWarning() << "Application menu fails to include applications-kmenuedit.menu" << endl; + return false; + } + TQDomElement docChangesElem = docChanges.documentElement(); + n = docChangesElem.firstChild(); + for(; !n.isNull(); n = next ) + { + TQDomElement 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 + { + TQString legacyApplications = KioskRun::self()->locateLocal("apps", TQString()); + TQString legacySaveApplications = KioskRun::self()->locateSave("apps", TQString()); + + KioskSync legacyDir(kapp->mainWidget()); + legacyDir.addDir(legacyApplications, KURL()); + + TQStringList newLegacyApplications = legacyDir.listFiles(); + + for(TQStringList::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 + { + TQString xdgApplications = KioskRun::self()->locateLocal("xdgdata-apps", TQString()); + TQString xdgSaveApplications = KioskRun::self()->locateSave("xdgdata-apps", TQString()); + + TQDir dir(xdgApplications); + TQStringList newXdgApplications = dir.entryList(TQDir::All, TQDir::Unsorted); + newXdgApplications.remove("."); + newXdgApplications.remove(".."); + + for(TQStringList::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 + { + TQString xdgDirectories = KioskRun::self()->locateLocal("xdgdata-dirs", TQString()); + TQString xdgSaveDirectories = KioskRun::self()->locateSave("xdgdata-dirs", TQString()); + + TQDir dir(xdgDirectories); + TQStringList newXdgDirectories = dir.entryList(TQDir::All, TQDir::Unsorted); + newXdgDirectories.remove("."); + newXdgDirectories.remove(".."); + + for(TQStringList::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/kiostdetool/menueditComponent.h b/kiostdetool/menueditComponent.h new file mode 100644 index 0000000..cea42a0 --- /dev/null +++ b/kiostdetool/menueditComponent.h @@ -0,0 +1,44 @@ +/* + * menueditComponent.h + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _MENUEDITCOMPONENT_H_ +#define _MENUEDITCOMPONENT_H_ + +#include "component.h" + +#include <tqstringlist.h> +#include <tqtimer.h> + +class MenuEditComponent: public Component +{ + Q_OBJECT + +public: + MenuEditComponent( TQObject *parent = 0); + virtual ~MenuEditComponent(); + + virtual bool setupFinished(); + +public slots: + + virtual void slotSetupPrepare(); + virtual void slotSetupStarted(); + virtual void slotPreviewStarted(); +}; + +#endif diff --git a/kiostdetool/pageWidget.cpp b/kiostdetool/pageWidget.cpp new file mode 100644 index 0000000..05571c2 --- /dev/null +++ b/kiostdetool/pageWidget.cpp @@ -0,0 +1,210 @@ +/* + * pageWidget.cpp + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "pageWidget.h" + +#include <tdeconfig.h> +#include <klistview.h> + +#include "kioskdata.h" +#include "kioskrun.h" + +ComponentActionItem::ComponentActionItem( TQListView * parent, ComponentAction *action, int index) + : TQCheckListItem(parent, action->caption, TQCheckListItem::CheckBox), + m_action(action), m_index(index) +{ + +} + +int ComponentActionItem::compare ( TQListViewItem * i, int, bool ) const +{ + ComponentActionItem *cai = static_cast<ComponentActionItem*>(i); + if (m_index == cai->m_index) + return 0; + if (m_index < cai->m_index) + return -1; + return 1; +} + +PageWidget::PageWidget(TQWidget *me) +{ + m_widget = me; +} + +PageWidget::~PageWidget() +{ +} + +void +PageWidget::fillActionList(TDEListView *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) + { + TQString file = action->file; + if (file.isEmpty()) + file = "kdeglobals"; + TDEConfig *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) + { + TQString file = action->file; + if (file.isEmpty()) + file = "kdeglobals"; + TDEConfig *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) + { + TQString file = "kdeglobals"; + TDEConfig *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) + { + TQString file = action->file; + if (file.isEmpty()) + file = "kdeglobals"; + TQString group = action->group; + bool immutable = KioskRun::self()->isConfigImmutable(file, group); +tqWarning("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) + { + TQString file = action->file; + if (file.isEmpty()) + file = "kdeglobals"; + TDEConfig *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) + { + TQString file = action->file; + if (file.isEmpty()) + file = "kdeglobals"; + TDEConfig *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) + { + TQString file = action->file; + if (file.isEmpty()) + file = "kdeglobals"; + TDEConfig *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) + { + TQString file = "kdeglobals"; + TDEConfig *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) + { + TQString file = action->file; + if (file.isEmpty()) + file = "kdeglobals"; + TQString 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) + { + TQString file = action->file; + if (file.isEmpty()) + file = "kdeglobals"; + TDEConfig *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(TDEListView *listView) +{ + for(ComponentActionItem *item = static_cast<ComponentActionItem*>(listView->firstChild()); + item; item = static_cast<ComponentActionItem*>(item->nextSibling())) + { + saveActionListItem(item->action(), item->isOn()); + } + return KioskRun::self()->flushConfigCache(); +} diff --git a/kiostdetool/pageWidget.h b/kiostdetool/pageWidget.h new file mode 100644 index 0000000..cd64137 --- /dev/null +++ b/kiostdetool/pageWidget.h @@ -0,0 +1,67 @@ +/* + * pageWidget.h + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _PAGEWIDGET_H_ +#define _PAGEWIDGET_H_ + +#include <klistview.h> + +class ComponentAction; +class ComponentData; + +class ComponentActionItem : public TQCheckListItem +{ +public: + ComponentActionItem( TQListView * parent, ComponentAction *action, int index); + + ComponentAction *action() const { return m_action; } + + virtual int compare ( TQListViewItem * i, int col, bool ascending ) const; +private: + + ComponentAction *m_action; + int m_index; +}; + +class PageWidget +{ +public: + PageWidget(TQWidget *me); + virtual ~PageWidget(); + + TQWidget *widget() const { return m_widget; } + + void fillActionList(TDEListView *listView, ComponentData *componentData); + bool saveActionListChanges(TDEListView *listView); + + virtual void load() = 0; + virtual bool save() = 0; + + virtual void setFocus() = 0; + + virtual TQString subCaption() = 0; + +protected: + void saveActionListItem(ComponentAction *action, bool b); + +private: + + TQWidget *m_widget; +}; + +#endif diff --git a/kiostdetool/panelComponent.cpp b/kiostdetool/panelComponent.cpp new file mode 100644 index 0000000..9f0b984 --- /dev/null +++ b/kiostdetool/panelComponent.cpp @@ -0,0 +1,83 @@ +/* + * panelComponent.cpp + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "panelComponent.h" + +#include <tqdir.h> +#include <tqfileinfo.h> + +#include <kdebug.h> +#include <kmimetype.h> +#include <kprocess.h> +#include <ksavefile.h> +#include <ksimpleconfig.h> +#include <kstandarddirs.h> +#include <kurl.h> + +#include "kioskrun.h" + +PanelComponent::PanelComponent( TQObject *parent) + : Component(parent) +{ +} + +PanelComponent::~PanelComponent() +{ +} + +void +PanelComponent::slotSetupPrepare() +{ +} + +void +PanelComponent::slotSetupStarted() +{ +} + +bool +PanelComponent::setupFinished() +{ + bool result; + + // Install .desktop files + { + TQString kickerApplications = KioskRun::self()->locateLocal("data", "kicker/"); + TQString kickerSaveApplications = KioskRun::self()->locateSave("data", "kicker/"); + + TQDir dir(kickerApplications); + TQStringList newKickerApplications = dir.entryList(TQDir::All, TQDir::Unsorted); + newKickerApplications.remove("."); + newKickerApplications.remove(".."); + + for(TQStringList::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/kiostdetool/panelComponent.h b/kiostdetool/panelComponent.h new file mode 100644 index 0000000..05fac1b --- /dev/null +++ b/kiostdetool/panelComponent.h @@ -0,0 +1,43 @@ +/* + * panelComponent.h + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _PANELCOMPONENT_H_ +#define _PANELCOMPONENT_H_ + +#include "component.h" + +#include <tqstringlist.h> +#include <tqtimer.h> + +class PanelComponent: public Component +{ + Q_OBJECT + +public: + PanelComponent( TQObject *parent = 0); + virtual ~PanelComponent(); + + virtual bool setupFinished(); + +public slots: + + virtual void slotSetupPrepare(); + virtual void slotSetupStarted(); +}; + +#endif diff --git a/kiostdetool/profilePropsPage.cpp b/kiostdetool/profilePropsPage.cpp new file mode 100644 index 0000000..d90d131 --- /dev/null +++ b/kiostdetool/profilePropsPage.cpp @@ -0,0 +1,234 @@ +/* + * profilePropsPage.cpp + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "profilePropsPage.h" + +#include <tqcombobox.h> +#include <tqvalidator.h> + +#include <kapplication.h> +#include <tdeconfig.h> +#include <klineedit.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kurlrequester.h> +#include <kuser.h> + +#include "kioskrun.h" +#include "kiosksync.h" + +static TQStringList userList() +{ + KUser thisUser; + TQStringList result; + result << thisUser.loginName(); + result << "root"; + + TDEConfig *config = kapp->config(); + config->setGroup("General"); + result += config->readListEntry("PreviousUsers"); + result.sort(); + + // Remove dupes + TQStringList::Iterator nextIt = result.begin(); + for(TQStringList::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(TQWidget *parent, const TQString &profile) + : ProfilePropsPageUI(parent), PageWidget(this), m_profile(profile) +{ +} + +ProfilePropsPage::~ProfilePropsPage() +{ +} + +void ProfilePropsPage::slotProfileNameChanged() +{ + TQString profile = editProfileName->text(); + if (m_fixedProfileDir) + { + TQString profilePrefix = KioskRun::self()->getProfilePrefix(); + TQString 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; + } + + TQString profilePrefix = KioskRun::self()->getProfilePrefix(); + m_fixedProfileDir = !profilePrefix.isEmpty(); + connect(editProfileName, TQT_SIGNAL(textChanged(const TQString&)), + this, TQT_SLOT(slotProfileNameChanged())); + +#if 0 + connect(kurlInstallDir, TQT_SIGNAL(textChanged(const TQString&)), + this, TQT_SLOT(updateButtons())); +#endif + + comboUser->setEditable(true); + comboUser->insertStringList(userList()); + + TQRegExp rx( "[^/ :]*" ); + TQValidator* validator = new TQRegExpValidator( rx, this ); + + editProfileName->setValidator(validator); + editProfileName->setFocus(); + + TQString description; + TQString installDir; + TQString 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() +{ + TQString user = comboUser->currentText(); + KUser userInfo(user); + if (!userInfo.isValid()) + { + KMessageBox::sorry(this, + i18n("<qt>The user <b>%1</b> is not an existing user.</qt>").arg(user)); + comboUser->setFocus(); + return false; + } + + m_profile = editProfileName->text(); + TQString description = editDescription->text(); + TQString 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()); + TQStringList fileList = origInstallDir.listFiles(); + fileList.remove(".kdeprofile"); + if (!fileList.isEmpty()) + { + int msgResult = KMessageBox::warningContinueCancelList(this, + i18n("<qt>The directory for this profile has changed " + "from <b>%1</b> to <b>%2</b>.<p>" + "The following files under <b>%3</b> will be moved to <b>%4</b>") + .arg(m_origInstallDir, installDir, m_origInstallDir, installDir), + fileList, + i18n("Profile Directory Changed")); + if (msgResult != KMessageBox::Continue) + return false; + } + KioskRun::self()->setUser(user); + if (!KioskRun::self()->move(m_origInstallDir, installDir, fileList)) + return false; + if (TQDir(m_origInstallDir).exists()) + { + if (!KioskRun::self()->remove(m_origInstallDir)) + return false; + } + } + + TQString 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 + TDEConfig *config = kapp->config(); + config->setGroup("General"); + TQStringList previousUsers= config->readListEntry("PreviousUsers"); + if (!previousUsers.contains(user)) + { + previousUsers << user; + config->writeEntry("PreviousUsers", previousUsers); + config->sync(); + } + + return result; +} + +void ProfilePropsPage::setFocus() +{ + editProfileName->setFocus(); +} + +TQString ProfilePropsPage::subCaption() +{ + return TQString(); +} + +#include "profilePropsPage.moc" diff --git a/kiostdetool/profilePropsPage.h b/kiostdetool/profilePropsPage.h new file mode 100644 index 0000000..446ae5d --- /dev/null +++ b/kiostdetool/profilePropsPage.h @@ -0,0 +1,52 @@ +/* + * profilePropsPage.h + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _PROFILEPROPSPAGE_H_ +#define _PROFILEPROPSPAGE_H_ + +#include "profilePropsPage_ui.h" +#include "pageWidget.h" + +class ProfilePropsPage : public ProfilePropsPageUI, public PageWidget +{ + Q_OBJECT + +public: + ProfilePropsPage(TQWidget *parent, const TQString &profile); + ~ProfilePropsPage(); + + virtual void load(); + virtual bool save(); + + virtual void setFocus(); + + virtual TQString subCaption(); + + TQString profile() { return m_profile; } + +protected slots: + void slotProfileNameChanged(); + +private: + TQString m_profile; + bool m_fixedProfileDir; + TQString m_origProfile; + TQString m_origInstallDir; +}; + +#endif diff --git a/kiostdetool/profilePropsPage_ui.ui b/kiostdetool/profilePropsPage_ui.ui new file mode 100644 index 0000000..96043b2 --- /dev/null +++ b/kiostdetool/profilePropsPage_ui.ui @@ -0,0 +1,255 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>ProfilePropsPageUI</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>Page2</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>721</width> + <height>543</height> + </rect> + </property> + <property name="backgroundOrigin"> + <enum>WindowOrigin</enum> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="0" column="2"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>20</height> + </size> + </property> + </spacer> + <spacer row="0" column="0"> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>60</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQFrame" row="0" column="1"> + <property name="name"> + <cstring>frame3</cstring> + </property> + <property name="backgroundOrigin"> + <enum>WindowOrigin</enum> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Raised</enum> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="backgroundOrigin"> + <enum>WindowOrigin</enum> + </property> + <property name="text"> + <string>&Profile name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editProfileName</cstring> + </property> + </widget> + <widget class="KLineEdit"> + <property name="name"> + <cstring>editProfileName</cstring> + </property> + <property name="minimumSize"> + <size> + <width>400</width> + <height>0</height> + </size> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer5_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="backgroundOrigin"> + <enum>WindowOrigin</enum> + </property> + <property name="text"> + <string>Short &description:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editDescription</cstring> + </property> + </widget> + <widget class="KLineEdit"> + <property name="name"> + <cstring>editDescription</cstring> + </property> + <property name="minimumSize"> + <size> + <width>400</width> + <height>0</height> + </size> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer5_2_2_3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel4_2</cstring> + </property> + <property name="backgroundOrigin"> + <enum>WindowOrigin</enum> + </property> + <property name="text"> + <string>&Files in this profile will be owned by:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>kurlInstallDir</cstring> + </property> + </widget> + <widget class="TQComboBox"> + <property name="name"> + <cstring>comboUser</cstring> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer5_2_2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel4</cstring> + </property> + <property name="backgroundOrigin"> + <enum>WindowOrigin</enum> + </property> + <property name="text"> + <string>&Directory for this profile:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>kurlInstallDir</cstring> + </property> + </widget> + <widget class="KURLRequester"> + <property name="name"> + <cstring>kurlInstallDir</cstring> + </property> + <property name="minimumSize"> + <size> + <width>400</width> + <height>0</height> + </size> + </property> + <property name="backgroundOrigin"> + <enum>WindowOrigin</enum> + </property> + </widget> + <widget class="KLineEdit"> + <property name="name"> + <cstring>labelInstallDir</cstring> + </property> + </widget> + </vbox> + </widget> + <spacer row="1" column="1"> + <property name="name"> + <cstring>spacer5</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>30</height> + </size> + </property> + </spacer> + </grid> +</widget> +<customwidgets> +</customwidgets> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kcombobox.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>klineedit.h</includehint> +</includehints> +</UI> diff --git a/kiostdetool/profileSelectionPage_ui.ui b/kiostdetool/profileSelectionPage_ui.ui new file mode 100644 index 0000000..5ba9974 --- /dev/null +++ b/kiostdetool/profileSelectionPage_ui.ui @@ -0,0 +1,230 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ProfileSelectionPageUI</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>Page1</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>656</width> + <height>362</height> + </rect> + </property> + <property name="backgroundOrigin"> + <enum>WindowOrigin</enum> + </property> + <property name="caption"> + <string>Page1</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="4" column="1"> + <property name="name"> + <cstring>spacer5</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TDEListView" row="2" column="1" rowspan="2" colspan="1"> + <column> + <property name="text"> + <string>Profile</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Description</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>listProfile</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>1</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>300</width> + <height>220</height> + </size> + </property> + <property name="backgroundOrigin"> + <enum>WindowOrigin</enum> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="fullWidth"> + <bool>true</bool> + </property> + </widget> + <spacer row="3" column="2"> + <property name="name"> + <cstring>spacer2_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQLayoutWidget" row="2" column="3" rowspan="2" colspan="1"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQPushButton"> + <property name="name"> + <cstring>buttonAdd</cstring> + </property> + <property name="text"> + <string>Add &New Profile</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer5_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>10</height> + </size> + </property> + </spacer> + <widget class="TQPushButton"> + <property name="name"> + <cstring>buttonSetup</cstring> + </property> + <property name="text"> + <string>&Setup Profile</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer5_2_3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>10</height> + </size> + </property> + </spacer> + <widget class="TQPushButton"> + <property name="name"> + <cstring>buttonUsers</cstring> + </property> + <property name="text"> + <string>&Assign Profiles</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer6_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>MinimumExpanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + <widget class="TQPushButton"> + <property name="name"> + <cstring>buttonProperty</cstring> + </property> + <property name="text"> + <string>&Profile Properties</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer6</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>10</height> + </size> + </property> + </spacer> + <widget class="TQPushButton"> + <property name="name"> + <cstring>buttonDelete</cstring> + </property> + <property name="text"> + <string>&Delete Profile</string> + </property> + </widget> + </vbox> + </widget> + </grid> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kiostdetool/screensaverComponent.cpp b/kiostdetool/screensaverComponent.cpp new file mode 100644 index 0000000..73a99c0 --- /dev/null +++ b/kiostdetool/screensaverComponent.cpp @@ -0,0 +1,41 @@ +/* + * screensaverComponent.cpp + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "screensaverComponent.h" + +#include "kioskrun.h" + +ScreenSaverComponent::ScreenSaverComponent( TQObject *parent) + : Component(parent) +{ +tqWarning("ScreenSaverComponent::ScreenSaverComponent"); + connect(&m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotPreviewStarted())); +} + +ScreenSaverComponent::~ScreenSaverComponent() +{ +} + +void +ScreenSaverComponent::slotPreviewStarted() +{ + KioskRun::self()->dcopRef("kdesktop", "KScreensaverIface").call("save"); +} + +#include "screensaverComponent.moc" diff --git a/kiostdetool/screensaverComponent.h b/kiostdetool/screensaverComponent.h new file mode 100644 index 0000000..5c507f8 --- /dev/null +++ b/kiostdetool/screensaverComponent.h @@ -0,0 +1,42 @@ +/* + * screensaverComponent.h + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _SCREENSAVERCOMPONENT_H_ +#define _SCREENSAVERCOMPONENT_H_ + +#include "component.h" + +#include <tqtimer.h> + +class ScreenSaverComponent: public Component +{ + Q_OBJECT + +public: + ScreenSaverComponent( TQObject *parent = 0); + virtual ~ScreenSaverComponent(); + +public slots: + + virtual void slotPreviewStarted(); + +private: + TQTimer m_timer; +}; + +#endif diff --git a/kiostdetool/userManagement.cpp b/kiostdetool/userManagement.cpp new file mode 100644 index 0000000..000e00e --- /dev/null +++ b/kiostdetool/userManagement.cpp @@ -0,0 +1,306 @@ +/* + * userManagement.cpp + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "userManagement.h" + +#include <unistd.h> +#include <grp.h> +#include <pwd.h> +#include <sys/types.h> + +#include <tqcombobox.h> +#include <tqlabel.h> +#include <tqpushbutton.h> + +#include <kapplication.h> +#include <tdeconfig.h> +#include <klistview.h> +#include <klocale.h> +#include <kmessagebox.h> + +#include "kioskrun.h" + +#include "userManagement_ui.h" +#include "userManagementGroup_ui.h" +#include "userManagementUser_ui.h" + +#define AVAILABLE_SINCE "KDE 3.2.3" + +UserManagementPage::UserManagementPage(TQWidget* 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, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotAddGroup())); + connect(buttonDeleteGroup, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotDeleteGroup())); + connect(buttonAddUser, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotAddUser())); + connect(buttonDeleteUser, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotDeleteUser())); + + connect(listGroups, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(slotUpdateButtons())); + connect(listUsers, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(slotUpdateButtons())); + +// init(); + static bool firstTime = true; + + if (firstTime) + { + firstTime = false; + TQTimer::singleShot(0, this, TQT_SLOT(slotShowNotice())); + } +} + +UserManagementPage::~UserManagementPage() +{ +} + +void UserManagementPage::slotShowNotice() +{ + KMessageBox::information(this, + i18n("<qt>The profiles that you define here are automatically applied when the " + "user logs in to %1 or newer.<p>" + "If you want to use these profiles in combination with older versions you need " + "to manually set the $TDEDIRS environment variable from the <b>starttde</b> " + "script by adding the following line:<br><br>" + "<i>export TDEDIRS=$(kiosktool-tdedirs)</i><br><br>").arg(AVAILABLE_SINCE), + i18n("Attention"), "user-profiles"); +} + +void UserManagementPage::load() +{ + listGroups->clear(); + listUsers->clear(); + + m_allProfiles = KioskRun::self()->allProfiles(); + m_allProfiles.sort(); + + KioskRun::ProfileMapping groups; + KioskRun::ProfileMapping users; + TQStringList groupOrder; + + KioskRun::self()->getUserProfileMappings(groups, users, groupOrder); + + for ( TQStringList::ConstIterator it = groupOrder.begin(); + it != groupOrder.end(); ++it ) + { + TQString group = *it; + TQString profile = groups[group].join(","); + new TQListViewItem(listGroups, group, profile); + } + + for ( KioskRun::ProfileMapping::Iterator it = users.begin(); + it != users.end(); ++it ) + { + TQString user = it.key(); + TQString profile = it.data().join(","); + new TQListViewItem(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; + TQStringList groupOrder; + + TQListViewItem *item = listGroups->firstChild(); + for(; item; item = item->nextSibling()) + { + TQString group = item->text(0); + TQStringList profiles = TQStringList::split(",", item->text(1)); + groups.insert(group, profiles); + groupOrder.prepend(group); + } + + item = listUsers->firstChild(); + for(; item; item = item->nextSibling()) + { + TQString user = item->text(0); + TQStringList profiles = TQStringList::split(",", item->text(1)); + users.insert(user, profiles); + } + + return KioskRun::self()->setUserProfileMappings(groups, users, groupOrder); +} + +void UserManagementPage::slotAddGroup() +{ + TDEConfig *config = kapp->config(); + config->setGroup("General"); + TQStringList groupBlacklist = config->readListEntry("GroupBlacklist"); + + m_allGroups.clear(); + setgrent(); + for (struct group *grp; (grp = getgrent()); ) + { + TQString group = TQString::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) + { + TQString group = wid->comboGroup->currentText(); + TQString profile = wid->comboProfile->currentText(); + + // Check for dupes + TQListViewItem *item = listGroups->firstChild(); + for( ;item; item = item->nextSibling()) + { + if (item->text(0) == group) + break; + } + if (item) + { + int result = KMessageBox::warningContinueCancel(this, + i18n("<qt>You already have a profile defined for group <b>%1</b>. " + "Do you want to replace it?</qt>").arg(group), + i18n("Duplicate Warning"), + i18n("&Replace")); + if (result != KMessageBox::Continue) + continue; // Go back to edit dialog + delete item; + } + + item = new TQListViewItem(listGroups, group, profile); + listGroups->setSelected(item, true); + slotUpdateButtons(); + return; + } +} + +void UserManagementPage::slotDeleteGroup() +{ + TQListViewItem *item = listGroups->selectedItem(); + if (!item) + return; + + delete item; + + item = listGroups->currentItem(); + if (item) + listGroups->setSelected(item, true); + slotUpdateButtons(); +} + +void UserManagementPage::slotAddUser() +{ + TDEConfig *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(TQString::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) + { + TQString user = wid->comboUser->currentText(); + TQString profile = wid->comboProfile->currentText(); + + // Check for dupes + TQListViewItem *item = listUsers->firstChild(); + for( ;item; item = item->nextSibling()) + { + if (item->text(0) == user) + break; + } + if (item) + { + int result = KMessageBox::warningContinueCancel(this, + i18n("<qt>You already have a profile defined for user <b>%1</b>. " + "Do you want to replace it?</<qt>").arg(user), + i18n("Duplicate Warning"), + i18n("&Replace")); + if (result != KMessageBox::Continue) + continue; // Go back to edit dialog + delete item; + } + + item = new TQListViewItem(listUsers, user, profile); + listUsers->setSelected(item, true); + slotUpdateButtons(); + return; + } +} + +void UserManagementPage::slotDeleteUser() +{ + TQListViewItem *item = listUsers->selectedItem(); + if (!item) + return; + + delete item; + + item = listUsers->currentItem(); + if (item) + listUsers->setSelected(item, true); + slotUpdateButtons(); +} + +void UserManagementPage::setFocus() +{ + // TODO +} + +TQString UserManagementPage::subCaption() +{ + return i18n("Assign Profiles"); +} + +#include "userManagement.moc" diff --git a/kiostdetool/userManagement.h b/kiostdetool/userManagement.h new file mode 100644 index 0000000..309e764 --- /dev/null +++ b/kiostdetool/userManagement.h @@ -0,0 +1,61 @@ +/* + * userManagement.h + * + * Copyright (C) 2004 Waldo Bastian <bastian@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _USERMANAGEMENT_H_ +#define _USERMANAGEMENT_H_ + +#include "pageWidget.h" +#include "userManagement_ui.h" + +class UserManagementUI; + +class UserManagementPage : public UserManagementUI, public PageWidget +{ + Q_OBJECT + +public: + UserManagementPage(TQWidget* parent, const char* name = 0, WFlags fl = 0); + ~UserManagementPage(); + + virtual void load(); + virtual bool save(); + + virtual void setFocus(); + + virtual TQString subCaption(); + +protected: + void init(); + +private slots: + void slotAddGroup(); + void slotDeleteGroup(); + void slotAddUser(); + void slotDeleteUser(); + + void slotUpdateButtons(); + void slotShowNotice(); + +private: + UserManagementUI *w; + TQStringList m_allUsers; + TQStringList m_allGroups; + TQStringList m_allProfiles; +}; + +#endif diff --git a/kiostdetool/userManagementGroup_ui.ui b/kiostdetool/userManagementGroup_ui.ui new file mode 100644 index 0000000..92879a9 --- /dev/null +++ b/kiostdetool/userManagementGroup_ui.ui @@ -0,0 +1,117 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>UserManagementGroupUI</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>UserManagementGroupUI</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>402</width> + <height>92</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>labelCaption</cstring> + </property> + <property name="text"> + <string>Select the profile to use for all users in the specified group.</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>10</height> + </size> + </property> + </spacer> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>labelGroup</cstring> + </property> + <property name="text"> + <string>Group:</string> + </property> + </widget> + <widget class="TQComboBox"> + <property name="name"> + <cstring>comboGroup</cstring> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQLabel"> + <property name="name"> + <cstring>labelProfile</cstring> + </property> + <property name="text"> + <string>Profile:</string> + </property> + </widget> + <widget class="TQComboBox"> + <property name="name"> + <cstring>comboProfile</cstring> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>51</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </vbox> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kiostdetool/userManagementUser_ui.ui b/kiostdetool/userManagementUser_ui.ui new file mode 100644 index 0000000..d7bd5e5 --- /dev/null +++ b/kiostdetool/userManagementUser_ui.ui @@ -0,0 +1,117 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>UserManagementUserUI</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>UserManagementUserUI</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>402</width> + <height>92</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>labelCaption</cstring> + </property> + <property name="text"> + <string>Select the profile to use for the specified user.</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>10</height> + </size> + </property> + </spacer> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>labelUser</cstring> + </property> + <property name="text"> + <string>User:</string> + </property> + </widget> + <widget class="TQComboBox"> + <property name="name"> + <cstring>comboUser</cstring> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQLabel"> + <property name="name"> + <cstring>labelProfile</cstring> + </property> + <property name="text"> + <string>Profile:</string> + </property> + </widget> + <widget class="TQComboBox"> + <property name="name"> + <cstring>comboProfile</cstring> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>51</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </vbox> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kiostdetool/userManagement_ui.ui b/kiostdetool/userManagement_ui.ui new file mode 100644 index 0000000..3062e41 --- /dev/null +++ b/kiostdetool/userManagement_ui.ui @@ -0,0 +1,278 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>UserManagementUI</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>UserManagementUI</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>659</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQGroupBox"> + <property name="name"> + <cstring>groupBox3</cstring> + </property> + <property name="title"> + <string>Default Policy</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Profile used for users with no assigned profile:</string> + </property> + </widget> + <widget class="KLineEdit"> + <property name="name"> + <cstring>kLineEdit1</cstring> + </property> + <property name="text"> + <string>default</string> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </vbox> + </widget> + <widget class="TQGroupBox"> + <property name="name"> + <cstring>groupBox1</cstring> + </property> + <property name="title"> + <string>Group Policies</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TDEListView"> + <column> + <property name="text"> + <string>Group</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Profile</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>listGroups</cstring> + </property> + <property name="minimumSize"> + <size> + <width>350</width> + <height>0</height> + </size> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="fullWidth"> + <bool>true</bool> + </property> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout1</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQPushButton"> + <property name="name"> + <cstring>buttonAddGroup</cstring> + </property> + <property name="text"> + <string>&Add Group Policy...</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQPushButton"> + <property name="name"> + <cstring>buttonDeleteGroup</cstring> + </property> + <property name="text"> + <string>&Delete Group Policy</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>31</height> + </size> + </property> + </spacer> + </vbox> + </widget> + </hbox> + </widget> + <widget class="TQGroupBox"> + <property name="name"> + <cstring>groupBox2</cstring> + </property> + <property name="title"> + <string>Individual User Policies</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TDEListView"> + <column> + <property name="text"> + <string>User</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Profile</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>listUsers</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="fullWidth"> + <bool>true</bool> + </property> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout1_2</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQPushButton"> + <property name="name"> + <cstring>buttonAddUser</cstring> + </property> + <property name="text"> + <string>&Add User Policy...</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQPushButton"> + <property name="name"> + <cstring>buttonDeleteUser</cstring> + </property> + <property name="text"> + <string>&Delete User Policy</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer1_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>31</height> + </size> + </property> + </spacer> + </vbox> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> |