first (somewhat) functional version of the Options window
This commit is contained in:
parent
fd7c0e6808
commit
af933bb22e
5 changed files with 178 additions and 40 deletions
|
@ -33,6 +33,18 @@
|
||||||
#include "configure.h"
|
#include "configure.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_PWD_H
|
||||||
|
#include <pwd.h>
|
||||||
|
#else
|
||||||
|
#error need pwd.h
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_STAT_H
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#else
|
||||||
|
#error need sys/stat.h
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <gtkmm/main.h>
|
#include <gtkmm/main.h>
|
||||||
|
|
||||||
|
@ -70,6 +82,16 @@ using namespace LiveSupport::GLiveSupport;
|
||||||
const std::string LiveSupport :: GLiveSupport ::
|
const std::string LiveSupport :: GLiveSupport ::
|
||||||
GLiveSupport :: configElementNameStr = "gLiveSupport";
|
GLiveSupport :: configElementNameStr = "gLiveSupport";
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* The name of the configuration file for this class
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
const std::string configFileDirStr = "/.livesupport/";
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* The name of the configuration file for this class
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
const std::string configFileNameStr = "gLiveSupport.xml";
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* The name of the config element for the list of supported languages
|
* The name of the config element for the list of supported languages
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
@ -298,9 +320,19 @@ GLiveSupport :: configure(const xmlpp::Element & element)
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
// save the config file so we can modify it later
|
// save the configuration so we can modify it later
|
||||||
// TODO: move configuration code to the OptionsContainer class?
|
// TODO: move configuration code to the OptionsContainer class?
|
||||||
optionsContainer.reset(new OptionsContainer(element));
|
Ptr<Glib::ustring>::Ref configFileName(new Glib::ustring);
|
||||||
|
struct passwd * pwd = getpwuid(getuid());
|
||||||
|
if (pwd) {
|
||||||
|
configFileName->append(pwd->pw_dir);
|
||||||
|
} else {
|
||||||
|
throw std::logic_error("this never happens: getpwuid() returned 0");
|
||||||
|
}
|
||||||
|
configFileName->append(configFileDirStr);
|
||||||
|
mkdir(configFileName->c_str(), 0700); // create dir if does not exist
|
||||||
|
configFileName->append(configFileNameStr);
|
||||||
|
optionsContainer.reset(new OptionsContainer(element, configFileName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -531,6 +563,10 @@ GLiveSupport :: logout(void) throw ()
|
||||||
authentication->logout(sessionId);
|
authentication->logout(sessionId);
|
||||||
sessionId.reset();
|
sessionId.reset();
|
||||||
|
|
||||||
|
if (optionsContainer->isChanged()) {
|
||||||
|
optionsContainer->writeToFile();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
#include "OptionsContainer.h"
|
#include "OptionsContainer.h"
|
||||||
|
|
||||||
|
@ -55,8 +56,12 @@ using namespace LiveSupport::GLiveSupport;
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
OptionsContainer :: OptionsContainer(const xmlpp::Element & optionsElement)
|
OptionsContainer :: OptionsContainer(
|
||||||
|
const xmlpp::Element & optionsElement,
|
||||||
|
Ptr<const Glib::ustring>::Ref configFileName)
|
||||||
throw ()
|
throw ()
|
||||||
|
: configFileName(configFileName),
|
||||||
|
changed(false)
|
||||||
{
|
{
|
||||||
optionsDocument.create_root_node_by_import(&optionsElement, true);
|
optionsDocument.create_root_node_by_import(&optionsElement, true);
|
||||||
// true == recursive
|
// true == recursive
|
||||||
|
@ -76,13 +81,13 @@ OptionsContainer :: setOptionItem(OptionItemString optionItem,
|
||||||
|
|
||||||
switch (optionItem) {
|
switch (optionItem) {
|
||||||
case outputPlayerDeviceName :
|
case outputPlayerDeviceName :
|
||||||
targetNode = getNode("/outputPlayer/audioPlayer/gstreamerPlayer/"
|
targetNode = getNode("outputPlayer/audioPlayer/gstreamerPlayer/"
|
||||||
"@audioDevice");
|
"@audioDevice");
|
||||||
isAttribute = true;
|
isAttribute = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cuePlayerDeviceName :
|
case cuePlayerDeviceName :
|
||||||
targetNode = getNode("/cuePlayer/audioPlayer/gstreamerPlayer/"
|
targetNode = getNode("cuePlayer/audioPlayer/gstreamerPlayer/"
|
||||||
"@audioDevice");
|
"@audioDevice");
|
||||||
isAttribute = true;
|
isAttribute = true;
|
||||||
break;
|
break;
|
||||||
|
@ -92,12 +97,14 @@ OptionsContainer :: setOptionItem(OptionItemString optionItem,
|
||||||
xmlpp::Attribute * attr = dynamic_cast<xmlpp::Attribute*>(targetNode);
|
xmlpp::Attribute * attr = dynamic_cast<xmlpp::Attribute*>(targetNode);
|
||||||
if (attr != 0) {
|
if (attr != 0) {
|
||||||
attr->set_value(*value);
|
attr->set_value(*value);
|
||||||
|
changed = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
xmlpp::TextNode * text = dynamic_cast<xmlpp::TextNode*>(targetNode);
|
xmlpp::TextNode * text = dynamic_cast<xmlpp::TextNode*>(targetNode);
|
||||||
if (text != 0) {
|
if (text != 0) {
|
||||||
text->set_content(*value);
|
text->set_content(*value);
|
||||||
|
changed = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,3 +184,18 @@ OptionsContainer :: getNode(const Glib::ustring & xPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Save the options to a file.
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
OptionsContainer :: writeToFile(void) throw ()
|
||||||
|
{
|
||||||
|
if (configFileName) {
|
||||||
|
std::ofstream file(configFileName->c_str());
|
||||||
|
optionsDocument.write_to_stream_formatted(file, "utf-8");
|
||||||
|
file.close();
|
||||||
|
changed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,17 @@ class OptionsContainer
|
||||||
/**
|
/**
|
||||||
* The XML document containing the options.
|
* The XML document containing the options.
|
||||||
*/
|
*/
|
||||||
xmlpp::Document optionsDocument;
|
xmlpp::Document optionsDocument;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The file name (including path) used by writeToFile().
|
||||||
|
*/
|
||||||
|
Ptr<const Glib::ustring>::Ref configFileName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remember if we have been changed.
|
||||||
|
*/
|
||||||
|
bool changed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor.
|
* Default constructor.
|
||||||
|
@ -99,8 +109,27 @@ class OptionsContainer
|
||||||
* Constructor with XML element parameter.
|
* Constructor with XML element parameter.
|
||||||
*
|
*
|
||||||
* @param optionsElement the XML element containing the options
|
* @param optionsElement the XML element containing the options
|
||||||
|
* @param configFileName the name (with path) of the configuration
|
||||||
|
* file used by writeToFile()
|
||||||
|
* @see writeToFile()
|
||||||
*/
|
*/
|
||||||
OptionsContainer(const xmlpp::Element & optionsElement) throw ();
|
OptionsContainer(const xmlpp::Element & optionsElement,
|
||||||
|
Ptr<const Glib::ustring>::Ref configFileName)
|
||||||
|
throw ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report if the object has been changed.
|
||||||
|
*
|
||||||
|
* It returns true if there has been any calls to setOptionItem()
|
||||||
|
* since its construction or the last call to writeToFile().
|
||||||
|
*
|
||||||
|
* @return whether the options have been changed
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
isChanged(void) throw ()
|
||||||
|
{
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of string options one can set.
|
* The list of string options one can set.
|
||||||
|
@ -133,6 +162,16 @@ class OptionsContainer
|
||||||
Ptr<Glib::ustring>::Ref
|
Ptr<Glib::ustring>::Ref
|
||||||
getOptionItem(OptionItemString optionItem)
|
getOptionItem(OptionItemString optionItem)
|
||||||
throw (std::invalid_argument);
|
throw (std::invalid_argument);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the options to a file.
|
||||||
|
*
|
||||||
|
* This writes the options in XML format to the file specified in the
|
||||||
|
* constructor, under $HOME/.livesupport. If the directory does not
|
||||||
|
* exist, it is created.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
writeToFile(void) throw ();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -88,14 +88,14 @@ OptionsWindow :: OptionsWindow (Ptr<GLiveSupport>::Ref gLiveSupport,
|
||||||
|
|
||||||
// build up the notepad for the various sections
|
// build up the notepad for the various sections
|
||||||
mainNotebook = Gtk::manage(new ScrolledNotebook);
|
mainNotebook = Gtk::manage(new ScrolledNotebook);
|
||||||
Gtk::Box * aboutSectionBox = constructAboutSection();
|
|
||||||
Gtk::Box * soundSectionBox = constructSoundSection();
|
Gtk::Box * soundSectionBox = constructSoundSection();
|
||||||
|
Gtk::Box * aboutSectionBox = constructAboutSection();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mainNotebook->appendPage(*aboutSectionBox,
|
|
||||||
*getResourceUstring("aboutSectionLabel"));
|
|
||||||
mainNotebook->appendPage(*soundSectionBox,
|
mainNotebook->appendPage(*soundSectionBox,
|
||||||
*getResourceUstring("soundSectionLabel"));
|
*getResourceUstring("soundSectionLabel"));
|
||||||
|
mainNotebook->appendPage(*aboutSectionBox,
|
||||||
|
*getResourceUstring("aboutSectionLabel"));
|
||||||
|
|
||||||
} catch (std::invalid_argument &e) {
|
} catch (std::invalid_argument &e) {
|
||||||
// TODO: signal error
|
// TODO: signal error
|
||||||
|
@ -156,7 +156,7 @@ OptionsWindow :: OptionsWindow (Ptr<GLiveSupport>::Ref gLiveSupport,
|
||||||
void
|
void
|
||||||
OptionsWindow :: onCancelButtonClicked(void) throw ()
|
OptionsWindow :: onCancelButtonClicked(void) throw ()
|
||||||
{
|
{
|
||||||
onCloseButtonClicked();
|
onCloseButtonClicked(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -166,6 +166,33 @@ OptionsWindow :: onCancelButtonClicked(void) throw ()
|
||||||
void
|
void
|
||||||
OptionsWindow :: onApplyButtonClicked(void) throw ()
|
OptionsWindow :: onApplyButtonClicked(void) throw ()
|
||||||
{
|
{
|
||||||
|
Ptr<OptionsContainer>::Ref
|
||||||
|
optionsContainer = gLiveSupport->getOptionsContainer();
|
||||||
|
|
||||||
|
// check for changes in the Sound tab
|
||||||
|
Ptr<const Glib::ustring>::Ref
|
||||||
|
oldCueDevice = optionsContainer->getOptionItem(
|
||||||
|
OptionsContainer::cuePlayerDeviceName );
|
||||||
|
Ptr<const Glib::ustring>::Ref
|
||||||
|
newCueDevice(new Glib::ustring(cuePlayerEntry->get_text()));
|
||||||
|
|
||||||
|
if (*oldCueDevice != *newCueDevice) {
|
||||||
|
optionsContainer->setOptionItem(
|
||||||
|
OptionsContainer::cuePlayerDeviceName,
|
||||||
|
newCueDevice );
|
||||||
|
}
|
||||||
|
|
||||||
|
Ptr<const Glib::ustring>::Ref
|
||||||
|
oldOutputDevice = optionsContainer->getOptionItem(
|
||||||
|
OptionsContainer::outputPlayerDeviceName );
|
||||||
|
Ptr<const Glib::ustring>::Ref
|
||||||
|
newOutputDevice(new Glib::ustring(outputPlayerEntry->get_text()));
|
||||||
|
|
||||||
|
if (*oldOutputDevice != *newOutputDevice) {
|
||||||
|
optionsContainer->setOptionItem(
|
||||||
|
OptionsContainer::outputPlayerDeviceName,
|
||||||
|
newOutputDevice );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -175,7 +202,8 @@ OptionsWindow :: onApplyButtonClicked(void) throw ()
|
||||||
void
|
void
|
||||||
OptionsWindow :: onOkButtonClicked(void) throw ()
|
OptionsWindow :: onOkButtonClicked(void) throw ()
|
||||||
{
|
{
|
||||||
onCloseButtonClicked();
|
onApplyButtonClicked();
|
||||||
|
onCloseButtonClicked(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -183,8 +211,11 @@ OptionsWindow :: onOkButtonClicked(void) throw ()
|
||||||
* Event handler for the Close button.
|
* Event handler for the Close button.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
OptionsWindow :: onCloseButtonClicked(void) throw ()
|
OptionsWindow :: onCloseButtonClicked(bool needConfirm) throw ()
|
||||||
{
|
{
|
||||||
|
if (needConfirm) {
|
||||||
|
//TODO: add confirmation dialog
|
||||||
|
}
|
||||||
gLiveSupport->putWindowPosition(shared_from_this());
|
gLiveSupport->putWindowPosition(shared_from_this());
|
||||||
hide();
|
hide();
|
||||||
}
|
}
|
||||||
|
@ -248,7 +279,7 @@ OptionsWindow :: constructSoundSection(void) throw ()
|
||||||
new Gtk::Label(cuePlayerLabelContents) );
|
new Gtk::Label(cuePlayerLabelContents) );
|
||||||
audioDeviceTable->attach(*cuePlayerLabel, 0, 1, 0, 1);
|
audioDeviceTable->attach(*cuePlayerLabel, 0, 1, 0, 1);
|
||||||
|
|
||||||
EntryBin * cuePlayerEntry = Gtk::manage(wf->createEntryBin());
|
cuePlayerEntry = Gtk::manage(wf->createEntryBin());
|
||||||
cuePlayerEntry->set_text(*optionsContainer->getOptionItem(
|
cuePlayerEntry->set_text(*optionsContainer->getOptionItem(
|
||||||
OptionsContainer::cuePlayerDeviceName ));
|
OptionsContainer::cuePlayerDeviceName ));
|
||||||
audioDeviceTable->attach(*cuePlayerEntry, 1, 2, 0, 1);
|
audioDeviceTable->attach(*cuePlayerEntry, 1, 2, 0, 1);
|
||||||
|
@ -267,19 +298,14 @@ OptionsWindow :: constructSoundSection(void) throw ()
|
||||||
new Gtk::Label(outputPlayerLabelContents) );
|
new Gtk::Label(outputPlayerLabelContents) );
|
||||||
audioDeviceTable->attach(*outputPlayerLabel, 0, 1, 1, 2);
|
audioDeviceTable->attach(*outputPlayerLabel, 0, 1, 1, 2);
|
||||||
|
|
||||||
EntryBin * outputPlayerEntry = Gtk::manage(wf->createEntryBin());
|
outputPlayerEntry = Gtk::manage(wf->createEntryBin());
|
||||||
outputPlayerEntry->set_text(*optionsContainer->getOptionItem(
|
outputPlayerEntry->set_text(*optionsContainer->getOptionItem(
|
||||||
OptionsContainer::outputPlayerDeviceName ));
|
OptionsContainer::outputPlayerDeviceName ));
|
||||||
audioDeviceTable->attach(*outputPlayerEntry, 1, 2, 1, 2);
|
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
|
// make a new box and pack the components into it
|
||||||
Gtk::VBox * section = Gtk::manage(new Gtk::VBox);
|
Gtk::VBox * section = Gtk::manage(new Gtk::VBox);
|
||||||
section->pack_start(*audioDeviceTable, Gtk::PACK_SHRINK, 5);
|
section->pack_start(*audioDeviceTable, Gtk::PACK_SHRINK, 5);
|
||||||
section->pack_start(*notFinishedWarning, Gtk::PACK_SHRINK, 20);
|
|
||||||
|
|
||||||
return section;
|
return section;
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,7 @@ using namespace LiveSupport::Widgets;
|
||||||
*/
|
*/
|
||||||
class OptionsWindow : public WhiteWindow, public LocalizedObject
|
class OptionsWindow : public WhiteWindow, public LocalizedObject
|
||||||
{
|
{
|
||||||
protected:
|
private:
|
||||||
/**
|
/**
|
||||||
* The notepad holding the different sections.
|
* The notepad holding the different sections.
|
||||||
*/
|
*/
|
||||||
|
@ -119,6 +119,16 @@ class OptionsWindow : public WhiteWindow, public LocalizedObject
|
||||||
*/
|
*/
|
||||||
Gtk::Button * okButton;
|
Gtk::Button * okButton;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The entry field for the cue player device's name.
|
||||||
|
*/
|
||||||
|
EntryBin * cuePlayerEntry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The entry field for the output player device's name.
|
||||||
|
*/
|
||||||
|
EntryBin * outputPlayerEntry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The gLiveSupport object, handling the logic of the application.
|
* The gLiveSupport object, handling the logic of the application.
|
||||||
*/
|
*/
|
||||||
|
@ -129,6 +139,24 @@ class OptionsWindow : public WhiteWindow, public LocalizedObject
|
||||||
*/
|
*/
|
||||||
bool isChanged;
|
bool isChanged;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct the "About" section.
|
||||||
|
*
|
||||||
|
* @return a pointer to the new box (already Gtk::manage()'ed)
|
||||||
|
*/
|
||||||
|
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 ();
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
/**
|
/**
|
||||||
* Event handler for the Cancel button.
|
* Event handler for the Cancel button.
|
||||||
*/
|
*/
|
||||||
|
@ -150,26 +178,13 @@ class OptionsWindow : public WhiteWindow, public LocalizedObject
|
||||||
/**
|
/**
|
||||||
* Event handler for the Close button.
|
* Event handler for the Close button.
|
||||||
*
|
*
|
||||||
* @see WhiteWindow::onCloseButtonClicked()
|
* @param needConfirm if true, we check if changes has been
|
||||||
|
* made to the input fields, and if yes, then
|
||||||
|
* a "save changes?" dialog is displayed
|
||||||
|
* @see WhiteWindow::onCloseButtonClicked()
|
||||||
*/
|
*/
|
||||||
virtual void
|
virtual void
|
||||||
onCloseButtonClicked(void) throw ();
|
onCloseButtonClicked(bool needConfirm = true) throw ();
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct the "About" section.
|
|
||||||
*
|
|
||||||
* @return a pointer to the new box (already Gtk::manage()'ed)
|
|
||||||
*/
|
|
||||||
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:
|
public:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue