diff --git a/livesupport/src/products/gLiveSupport/bin/gLiveSupport.sh b/livesupport/src/products/gLiveSupport/bin/gLiveSupport.sh index 1c89e5bab..315640bf7 100755 --- a/livesupport/src/products/gLiveSupport/bin/gLiveSupport.sh +++ b/livesupport/src/products/gLiveSupport/bin/gLiveSupport.sh @@ -49,7 +49,14 @@ gstreamer_dir=`find $libdir -type d -name "gstreamer-*"` export LD_LIBRARY_PATH=$libdir:$LD_LIBRARY_PATH gLiveSupport_exe=$bindir/gLiveSupport -config_file=$etcdir/gLiveSupport.xml + +if [ -f ~/.livesupport/gLiveSupport.xml ]; then + config_file=~/.livesupport/gLiveSupport.xml +elif [ -f $etcdir/gLiveSupport.xml ]; then + config_file=$etcdir/gLiveSupport.xml +else + echo "Can't find configuration file."; +fi $gLiveSupport_exe --version diff --git a/livesupport/src/products/gLiveSupport/etc/Makefile.in b/livesupport/src/products/gLiveSupport/etc/Makefile.in index c1927b9dc..fd7875372 100644 --- a/livesupport/src/products/gLiveSupport/etc/Makefile.in +++ b/livesupport/src/products/gLiveSupport/etc/Makefile.in @@ -259,6 +259,7 @@ G_LIVESUPPORT_OBJS = ${TMP_DIR}/GLiveSupport.o \ ${TMP_DIR}/CuePlayer.o \ ${TMP_DIR}/KeyboardShortcut.o \ ${TMP_DIR}/KeyboardShortcutContainer.o \ + ${TMP_DIR}/OptionsContainer.o \ ${TMP_DIR}/OptionsWindow.o G_LIVESUPPORT_RES = ${TMP_DIR}/${PACKAGE_NAME}_root.res \ diff --git a/livesupport/src/products/gLiveSupport/src/GLiveSupport.cxx b/livesupport/src/products/gLiveSupport/src/GLiveSupport.cxx index 3e04377f6..9b7def4b1 100644 --- a/livesupport/src/products/gLiveSupport/src/GLiveSupport.cxx +++ b/livesupport/src/products/gLiveSupport/src/GLiveSupport.cxx @@ -297,6 +297,10 @@ GLiveSupport :: configure(const xmlpp::Element & element) keyboardShortcutList[*ksc->getWindowName()] = ksc; ++it; } + + // save the config file so we can modify it later + // TODO: move configuration code to the OptionsContainer class? + optionsContainer.reset(new OptionsContainer(element)); } diff --git a/livesupport/src/products/gLiveSupport/src/GLiveSupport.h b/livesupport/src/products/gLiveSupport/src/GLiveSupport.h index 68b7e7f0c..2ebabf20e 100644 --- a/livesupport/src/products/gLiveSupport/src/GLiveSupport.h +++ b/livesupport/src/products/gLiveSupport/src/GLiveSupport.h @@ -55,6 +55,7 @@ #include "LiveSupport/PlaylistExecutor/AudioPlayerInterface.h" #include "LiveSupport/Widgets/WidgetFactory.h" #include "KeyboardShortcutContainer.h" +#include "OptionsContainer.h" namespace LiveSupport { @@ -327,6 +328,11 @@ class GLiveSupport : public LocalizedConfigurable, * The positions of the various windows. */ WindowPositionsListType windowPositions; + + /** + * An object containing the contents of the options file. + */ + Ptr::Ref optionsContainer; protected: @@ -1020,6 +1026,15 @@ class GLiveSupport : public LocalizedConfigurable, */ void loadWindowPositions(void) throw (); + + /** + * Access the OptionsContainer object containing the options. + */ + Ptr::Ref + getOptionsContainer(void) throw() + { + return optionsContainer; + } }; /* ================================================= external data structures */ diff --git a/livesupport/src/products/gLiveSupport/src/OptionsContainer.cxx b/livesupport/src/products/gLiveSupport/src/OptionsContainer.cxx new file mode 100644 index 000000000..040145177 --- /dev/null +++ b/livesupport/src/products/gLiveSupport/src/OptionsContainer.cxx @@ -0,0 +1,180 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 Media Development Loan Fund + + This file is part of the LiveSupport project. + http://livesupport.campware.org/ + To report bugs, send an e-mail to bugs@campware.org + + LiveSupport 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. + + LiveSupport 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 LiveSupport; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + Author : $Author $ + Version : $Revision $ + Location : $URL $ + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#include + +#include "OptionsContainer.h" + + +using namespace LiveSupport::Core; +using namespace LiveSupport::GLiveSupport; + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Constructor. + *----------------------------------------------------------------------------*/ +OptionsContainer :: OptionsContainer(const xmlpp::Element & optionsElement) + throw () +{ + optionsDocument.create_root_node_by_import(&optionsElement, true); + // true == recursive +} + + +/*------------------------------------------------------------------------------ + * Set a string type option. + *----------------------------------------------------------------------------*/ +void +OptionsContainer :: setOptionItem(OptionItemString optionItem, + Ptr::Ref value) + throw (std::invalid_argument) +{ + xmlpp::Node * targetNode = 0; + bool isAttribute = false; // text node or attr node + + switch (optionItem) { + case outputPlayerDeviceName : + targetNode = getNode("/outputPlayer/audioPlayer/gstreamerPlayer/" + "@audioDevice"); + isAttribute = true; + break; + + case cuePlayerDeviceName : + targetNode = getNode("/cuePlayer/audioPlayer/gstreamerPlayer/" + "@audioDevice"); + isAttribute = true; + break; + } + + if (isAttribute) { + xmlpp::Attribute * attr = dynamic_cast(targetNode); + if (attr != 0) { + attr->set_value(*value); + return; + } + } else { + xmlpp::TextNode * text = dynamic_cast(targetNode); + if (text != 0) { + text->set_content(*value); + return; + } + } + + throw std::invalid_argument("option item not found"); +} + + +/*------------------------------------------------------------------------------ + * Get a string type option. + *----------------------------------------------------------------------------*/ +Ptr::Ref +OptionsContainer :: getOptionItem(OptionItemString optionItem) + throw (std::invalid_argument) +{ + const xmlpp::Node * targetNode = 0; + bool isAttribute = false; // child text node or attr + Glib::ustring errorMessage = "option item not found"; + + switch (optionItem) { + case outputPlayerDeviceName : + targetNode = getNode("outputPlayer/audioPlayer/gstreamerPlayer/" + "@audioDevice"); + isAttribute = true; + break; + + case cuePlayerDeviceName : + targetNode = getNode("cuePlayer/audioPlayer/gstreamerPlayer/" + "@audioDevice"); + isAttribute = true; + break; + } + + if (isAttribute) { + const xmlpp::Attribute * + attr = dynamic_cast(targetNode); + if (attr != 0) { + Ptr::Ref value(new Glib::ustring( + attr->get_value() )); + return value; + } + } else { + const xmlpp::TextNode * + text = dynamic_cast(targetNode); + if (text != 0) { + Ptr::Ref value(new Glib::ustring( + text->get_content() )); + return value; + } + } + + throw std::invalid_argument("option item not found"); +} + + +/*------------------------------------------------------------------------------ + * Return the first node matching an XPath string. + *----------------------------------------------------------------------------*/ +xmlpp::Node * +OptionsContainer :: getNode(const Glib::ustring & xPath) + throw (std::invalid_argument) +{ + xmlpp::Element * rootNode = optionsDocument.get_root_node(); + xmlpp::NodeSet nodes; + + try { + nodes = rootNode->find(xPath); + + } catch (xmlpp::exception &e) { + throw std::invalid_argument(e.what()); + } + + std::vector::iterator it = nodes.begin(); + if (it != nodes.end()) { + return *it; + } else { + return 0; + } +} + diff --git a/livesupport/src/products/gLiveSupport/src/OptionsContainer.h b/livesupport/src/products/gLiveSupport/src/OptionsContainer.h new file mode 100644 index 000000000..dd956d042 --- /dev/null +++ b/livesupport/src/products/gLiveSupport/src/OptionsContainer.h @@ -0,0 +1,149 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 Media Development Loan Fund + + This file is part of the LiveSupport project. + http://livesupport.campware.org/ + To report bugs, send an e-mail to bugs@campware.org + + LiveSupport 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. + + LiveSupport 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 LiveSupport; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + Author : $Author $ + Version : $Revision $ + Location : $URL $ + +------------------------------------------------------------------------------*/ +#ifndef LiveSupport_GLiveSupport_OptionsContainer_h +#define LiveSupport_GLiveSupport_OptionsContainer_h + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#include +#include +#include "libxml++/libxml++.h" + +#include "LiveSupport/Core/Ptr.h" + + +namespace LiveSupport { +namespace GLiveSupport { + +using namespace LiveSupport::Core; + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A container for the options in gLiveSupport.xml. + * + * @author $Author $ + * @version $Revision $ + */ +class OptionsContainer +{ + private: + /** + * The XML document containing the options. + */ + xmlpp::Document optionsDocument; + + /** + * Default constructor. + */ + OptionsContainer(void) throw () + { + } + + /** + * Return the first node matching an XPath string. + * + * If there is no matching node, it returns a 0 pointer. + * + * @param xPath the XPath of the node (from the root node) + * @return a pointer to the node found, or 0 + */ + xmlpp::Node * + getNode(const Glib::ustring & xPath) + throw (std::invalid_argument); + + + public: + /** + * Constructor with XML element parameter. + * + * @param optionsElement the XML element containing the options + */ + OptionsContainer(const xmlpp::Element & optionsElement) throw (); + + /** + * The list of string options one can set. + * + * These are options of type Glib::ustring; any string is accepted + * as value, no range checking is done. + * + * For the moment, this is the only kind of option supported. + */ + typedef enum { outputPlayerDeviceName, + cuePlayerDeviceName } OptionItemString; + + /** + * Set a string type option. + * + * @param value the new value of the option + * @exception std::invalid_argument if the option name is not found + */ + void + setOptionItem(OptionItemString optionItem, + Ptr::Ref value) + throw (std::invalid_argument); + + /** + * Get a string type option. + * + * @return the value of the option + * @exception std::invalid_argument if the option name is not found + */ + Ptr::Ref + getOptionItem(OptionItemString optionItem) + throw (std::invalid_argument); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + +} // namespace GLiveSupport +} // namespace LiveSupport + +#endif // LiveSupport_GLiveSupport_OptionsContainer_h + diff --git a/livesupport/src/products/gLiveSupport/src/OptionsWindow.cxx b/livesupport/src/products/gLiveSupport/src/OptionsWindow.cxx index 3f7789b9b..d0665bffd 100644 --- a/livesupport/src/products/gLiveSupport/src/OptionsWindow.cxx +++ b/livesupport/src/products/gLiveSupport/src/OptionsWindow.cxx @@ -38,6 +38,7 @@ #include "LiveSupport/Widgets/WidgetFactory.h" #include "LiveSupport/Widgets/Button.h" #include "LiveSupport/Widgets/ScrolledNotebook.h" +#include "LiveSupport/Widgets/EntryBin.h" #include "OptionsWindow.h" @@ -88,10 +89,13 @@ OptionsWindow :: OptionsWindow (Ptr::Ref gLiveSupport, // build up the notepad for the various sections mainNotebook = Gtk::manage(new ScrolledNotebook); Gtk::Box * aboutSectionBox = constructAboutSection(); + Gtk::Box * soundSectionBox = constructSoundSection(); try { mainNotebook->appendPage(*aboutSectionBox, - *getResourceUstring("aboutSectionLabel")); + *getResourceUstring("aboutSectionLabel")); + mainNotebook->appendPage(*soundSectionBox, + *getResourceUstring("soundSectionLabel")); } catch (std::invalid_argument &e) { // TODO: signal error @@ -138,7 +142,7 @@ OptionsWindow :: OptionsWindow (Ptr::Ref gLiveSupport, // show everything set_name(windowName); - set_default_size(350, 250); + set_default_size(350, 300); set_modal(false); property_window_position().set_value(Gtk::WIN_POS_NONE); @@ -215,3 +219,68 @@ OptionsWindow :: constructAboutSection(void) throw () return section; } + +/*------------------------------------------------------------------------------ + * Construct the "Sound" section. + *----------------------------------------------------------------------------*/ +Gtk::VBox* +OptionsWindow :: constructSoundSection(void) throw () +{ + Ptr::Ref optionsContainer + = gLiveSupport->getOptionsContainer(); + Ptr::Ref wf = WidgetFactory::getInstance(); + + Gtk::Table * audioDeviceTable = Gtk::manage(new Gtk::Table); + audioDeviceTable->set_row_spacings(10); + audioDeviceTable->set_col_spacings(5); + + // display the settings for the cue player device + Glib::ustring cuePlayerLabelContents; + try { + cuePlayerLabelContents.append(*getResourceUstring("cueDeviceLabel")); + + } catch (std::invalid_argument &e) { + // TODO: signal error + std::cerr << e.what() << std::endl; + std::exit(1); + } + Gtk::Label * cuePlayerLabel = Gtk::manage( + new Gtk::Label(cuePlayerLabelContents) ); + audioDeviceTable->attach(*cuePlayerLabel, 0, 1, 0, 1); + + EntryBin * cuePlayerEntry = Gtk::manage(wf->createEntryBin()); + cuePlayerEntry->set_text(*optionsContainer->getOptionItem( + OptionsContainer::cuePlayerDeviceName )); + audioDeviceTable->attach(*cuePlayerEntry, 1, 2, 0, 1); + + // display the settings for the output player device + Glib::ustring outputPlayerLabelContents; + try { + outputPlayerLabelContents.append(*getResourceUstring( + "outputDeviceLabel")); + } catch (std::invalid_argument &e) { + // TODO: signal error + std::cerr << e.what() << std::endl; + std::exit(1); + } + Gtk::Label * outputPlayerLabel = Gtk::manage( + new Gtk::Label(outputPlayerLabelContents) ); + audioDeviceTable->attach(*outputPlayerLabel, 0, 1, 1, 2); + + EntryBin * outputPlayerEntry = Gtk::manage(wf->createEntryBin()); + outputPlayerEntry->set_text(*optionsContainer->getOptionItem( + OptionsContainer::outputPlayerDeviceName )); + audioDeviceTable->attach(*outputPlayerEntry, 1, 2, 1, 2); + + // TODO: remove this + Gtk::Label * notFinishedWarning = Gtk::manage(new Gtk::Label( + "Note: device settings can not be edited (yet)." )); + + // make a new box and pack the components into it + Gtk::VBox * section = Gtk::manage(new Gtk::VBox); + section->pack_start(*audioDeviceTable, Gtk::PACK_SHRINK, 5); + section->pack_start(*notFinishedWarning, Gtk::PACK_SHRINK, 20); + + return section; +} + diff --git a/livesupport/src/products/gLiveSupport/src/OptionsWindow.h b/livesupport/src/products/gLiveSupport/src/OptionsWindow.h index 75197a854..087b1fba9 100644 --- a/livesupport/src/products/gLiveSupport/src/OptionsWindow.h +++ b/livesupport/src/products/gLiveSupport/src/OptionsWindow.h @@ -163,6 +163,14 @@ class OptionsWindow : public WhiteWindow, public LocalizedObject Gtk::VBox* constructAboutSection(void) throw (); + /** + * Construct the "Sound" section. + * + * @return a pointer to the new box (already Gtk::manage()'ed) + */ + Gtk::VBox* + constructSoundSection(void) throw (); + public: /** diff --git a/livesupport/src/products/gLiveSupport/src/main.cxx b/livesupport/src/products/gLiveSupport/src/main.cxx index c82cac251..6785016f0 100644 --- a/livesupport/src/products/gLiveSupport/src/main.cxx +++ b/livesupport/src/products/gLiveSupport/src/main.cxx @@ -157,7 +157,7 @@ int main ( int argc, try { std::auto_ptr - parser(new xmlpp::DomParser(configFileName, true)); + parser(new xmlpp::DomParser(configFileName, false)); const xmlpp::Document * document = parser->get_document(); gLiveSupport->configure(*(document->get_root_node())); } catch (std::invalid_argument &e) { diff --git a/livesupport/src/products/gLiveSupport/var/root.txt b/livesupport/src/products/gLiveSupport/var/root.txt index bb20190e9..dce6ed804 100644 --- a/livesupport/src/products/gLiveSupport/var/root.txt +++ b/livesupport/src/products/gLiveSupport/var/root.txt @@ -222,12 +222,16 @@ root:table windowTitle:string { "LiveSupport Options Window" } aboutSectionLabel:string { "About" } + soundSectionLabel:string { "Sound" } cancelButtonLabel:string { "Cancel" } applyButtonLabel:string { "Apply" } okButtonLabel:string { "OK" } reportBugsToText:string { "Report bugs to: {0}" } + + cueDeviceLabel:string { "Cue audio device:" } + outputDeviceLabel:string { "Live Mode audio device:" } } metadataTypes:table