first (somewhat) functional version of the Options window

This commit is contained in:
fgerlits 2006-01-20 21:22:32 +00:00
parent fd7c0e6808
commit af933bb22e
5 changed files with 178 additions and 40 deletions

View file

@ -33,6 +33,18 @@
#include "configure.h"
#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 <gtkmm/main.h>
@ -70,6 +82,16 @@ using namespace LiveSupport::GLiveSupport;
const std::string LiveSupport :: 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
*----------------------------------------------------------------------------*/
@ -298,9 +320,19 @@ GLiveSupport :: configure(const xmlpp::Element & element)
++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?
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);
sessionId.reset();
if (optionsContainer->isChanged()) {
optionsContainer->writeToFile();
}
return true;
}

View file

@ -34,6 +34,7 @@
#endif
#include <iostream>
#include <fstream>
#include "OptionsContainer.h"
@ -55,8 +56,12 @@ using namespace LiveSupport::GLiveSupport;
/*------------------------------------------------------------------------------
* Constructor.
*----------------------------------------------------------------------------*/
OptionsContainer :: OptionsContainer(const xmlpp::Element & optionsElement)
OptionsContainer :: OptionsContainer(
const xmlpp::Element & optionsElement,
Ptr<const Glib::ustring>::Ref configFileName)
throw ()
: configFileName(configFileName),
changed(false)
{
optionsDocument.create_root_node_by_import(&optionsElement, true);
// true == recursive
@ -76,13 +81,13 @@ OptionsContainer :: setOptionItem(OptionItemString optionItem,
switch (optionItem) {
case outputPlayerDeviceName :
targetNode = getNode("/outputPlayer/audioPlayer/gstreamerPlayer/"
targetNode = getNode("outputPlayer/audioPlayer/gstreamerPlayer/"
"@audioDevice");
isAttribute = true;
break;
case cuePlayerDeviceName :
targetNode = getNode("/cuePlayer/audioPlayer/gstreamerPlayer/"
targetNode = getNode("cuePlayer/audioPlayer/gstreamerPlayer/"
"@audioDevice");
isAttribute = true;
break;
@ -92,12 +97,14 @@ OptionsContainer :: setOptionItem(OptionItemString optionItem,
xmlpp::Attribute * attr = dynamic_cast<xmlpp::Attribute*>(targetNode);
if (attr != 0) {
attr->set_value(*value);
changed = true;
return;
}
} else {
xmlpp::TextNode * text = dynamic_cast<xmlpp::TextNode*>(targetNode);
if (text != 0) {
text->set_content(*value);
changed = true;
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;
}
}

View file

@ -74,6 +74,16 @@ class OptionsContainer
*/
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.
*/
@ -99,8 +109,27 @@ class OptionsContainer
* Constructor with XML element parameter.
*
* @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.
@ -133,6 +162,16 @@ class OptionsContainer
Ptr<Glib::ustring>::Ref
getOptionItem(OptionItemString optionItem)
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 ();
};

View file

@ -88,14 +88,14 @@ OptionsWindow :: OptionsWindow (Ptr<GLiveSupport>::Ref gLiveSupport,
// build up the notepad for the various sections
mainNotebook = Gtk::manage(new ScrolledNotebook);
Gtk::Box * aboutSectionBox = constructAboutSection();
Gtk::Box * soundSectionBox = constructSoundSection();
Gtk::Box * aboutSectionBox = constructAboutSection();
try {
mainNotebook->appendPage(*aboutSectionBox,
*getResourceUstring("aboutSectionLabel"));
mainNotebook->appendPage(*soundSectionBox,
*getResourceUstring("soundSectionLabel"));
mainNotebook->appendPage(*aboutSectionBox,
*getResourceUstring("aboutSectionLabel"));
} catch (std::invalid_argument &e) {
// TODO: signal error
@ -156,7 +156,7 @@ OptionsWindow :: OptionsWindow (Ptr<GLiveSupport>::Ref gLiveSupport,
void
OptionsWindow :: onCancelButtonClicked(void) throw ()
{
onCloseButtonClicked();
onCloseButtonClicked(false);
}
@ -166,6 +166,33 @@ OptionsWindow :: onCancelButtonClicked(void) throw ()
void
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
OptionsWindow :: onOkButtonClicked(void) throw ()
{
onCloseButtonClicked();
onApplyButtonClicked();
onCloseButtonClicked(false);
}
@ -183,8 +211,11 @@ OptionsWindow :: onOkButtonClicked(void) throw ()
* Event handler for the Close button.
*----------------------------------------------------------------------------*/
void
OptionsWindow :: onCloseButtonClicked(void) throw ()
OptionsWindow :: onCloseButtonClicked(bool needConfirm) throw ()
{
if (needConfirm) {
//TODO: add confirmation dialog
}
gLiveSupport->putWindowPosition(shared_from_this());
hide();
}
@ -248,7 +279,7 @@ OptionsWindow :: constructSoundSection(void) throw ()
new Gtk::Label(cuePlayerLabelContents) );
audioDeviceTable->attach(*cuePlayerLabel, 0, 1, 0, 1);
EntryBin * cuePlayerEntry = Gtk::manage(wf->createEntryBin());
cuePlayerEntry = Gtk::manage(wf->createEntryBin());
cuePlayerEntry->set_text(*optionsContainer->getOptionItem(
OptionsContainer::cuePlayerDeviceName ));
audioDeviceTable->attach(*cuePlayerEntry, 1, 2, 0, 1);
@ -267,19 +298,14 @@ OptionsWindow :: constructSoundSection(void) throw ()
new Gtk::Label(outputPlayerLabelContents) );
audioDeviceTable->attach(*outputPlayerLabel, 0, 1, 1, 2);
EntryBin * outputPlayerEntry = Gtk::manage(wf->createEntryBin());
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;
}

View file

@ -93,7 +93,7 @@ using namespace LiveSupport::Widgets;
*/
class OptionsWindow : public WhiteWindow, public LocalizedObject
{
protected:
private:
/**
* The notepad holding the different sections.
*/
@ -119,6 +119,16 @@ class OptionsWindow : public WhiteWindow, public LocalizedObject
*/
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.
*/
@ -129,6 +139,24 @@ class OptionsWindow : public WhiteWindow, public LocalizedObject
*/
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.
*/
@ -150,26 +178,13 @@ class OptionsWindow : public WhiteWindow, public LocalizedObject
/**
* Event handler for the Close button.
*
* @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
onCloseButtonClicked(void) 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 ();
onCloseButtonClicked(bool needConfirm = true) throw ();
public: