//
// The contents of this file are subject to the Mozilla Public License
// Version 1.0 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
// the License for the specific language governing rights and limitations
// under the License.
//
// The Original Code is CPhone, a cross platform voip gui.
//
// The Initial Developer of the Original Code is Derek Smithies.
//
// Copyright (C) 2002 Indranet Technologies Ltd,
// http://www.indranet-technologies.com
// All Rights Reserved.
//
// Contributor(s): _______________
/*
*
* $Log: settingsSub.cxx,v $
* Revision 1.10 2004/04/14 08:43:07 dereksmithies
* Fixes for windows etc.
*
* Revision 1.9 2004/02/18 03:16:55 dereksmithies
* Fix Nat translation feature. Thanks to dag@bakke.com for finding the problem.
*
* Revision 1.8 2003/09/02 03:37:32 dereksmithies
* Add statistics, new icons, toolbuttons (icon + name)
*
* Revision 1.7 2003/08/26 04:48:02 dereksmithies
* Fixes to get statistics working right, add icons, add ok,cancel,apply buttons
*
* Revision 1.6 2003/08/11 01:48:14 dereksmithies
* Fix windows compile errors
*
* Revision 1.5 2003/05/09 04:34:46 dereksmithies
* Tidy up gatekeeper finding. Works reliably.
*
* Revision 1.4 2003/05/09 03:08:24 dereksmithies
* Fix Microtelco handling, and message display
*
* Revision 1.3 2003/05/06 22:40:36 dereksmithies
* Fixes to get it working correctly on microtelco.
*
* Revision 1.2 2003/04/04 04:37:49 dereksmithies
* Major upgrade.
* Ixj & microtelco support added. Fix threading issues.
*
* Revision 1.1.1.1 2002/05/12 22:55:05 dereksmithies
* Initial release.
*
*
*
*
*/
#include <qapplication.h>
#include <qcheckbox.h>
#include <qfiledialog.h>
#include <qlineedit.h>
#include <qlistview.h>
#include <qobjcoll.h>
#include <qtoolbutton.h>
#include <qradiobutton.h>
#include <qslider.h>
#include <qspinbox.h>
#include "settingsSub.h"
#include "cpendpoint.h"
#include "message.h"
#include "vdisplay.h"
#include "images/microtelcoOn.xpm"
#include "images/microtelcoOff.xpm"
#include "images/nat_traversal_off.xpm"
#include "images/nat_traversal_on.xpm"
#include <ptlib.h>
#define CUSTOM_EVENT_SETUP (QEvent::User + 1)
/*
* Constructs a Settings which is a child of 'parent', with the
* name 'name' and widget flags set to 'f'
*
* The dialog will by default be modeless, unless you set 'modal' to
* TRUE to construct a modal dialog.
*/
Settings::Settings(ConnectOptions & co)
: FormConnectionSettings( 0, "Settings", FALSE, WDestructiveClose),
connectOpts(co),
controlsSet(false)
{
move(300, 300);
CPhone::Current().SetWindowId(eSettings, winId());
QApplication::postEvent(this, new QCustomEvent(CUSTOM_EVENT_SETUP));
}
/*
* Destroys the object and frees any allocated resources
*/
Settings::~Settings()
{
}
void Settings::Setup()
{
InitialiseCodecSettings();
CheckBoxAutoAnswer->setChecked(connectOpts.autoAnswer);
CheckBoxDisableFastStart->setChecked(connectOpts.noFastStart);
CheckBoxDisableH245Tunnel->setChecked(connectOpts.noH245Tunnelling);
CheckBoxDefaultAudio->setChecked(connectOpts.useDefaultAudioBandwidth);
CheckBoxDefaultVideo->setChecked(connectOpts.useDefaultVideoBandwidth);
SpinBoxFramesEthernetPacket->setValue(connectOpts.packetUtilization);
SpinBoxBandwidthAudio->setValue(connectOpts.audioBandwidth);
SpinBoxBandwidthVideo->setValue(connectOpts.videoBandwidth);
LineEditGatekeeper->setText((const char *)connectOpts.gatekeeperName.GetPointer());
LineEditGatekeeper->setEnabled(!connectOpts.searchForGatekeeper);
LineEditUserName->setText((const char *)connectOpts.userName.GetPointer());
toolButtonNatTraversal->setOn((connectOpts.doNatTraversal));
LineEditNatTraversal->setText((const char *)connectOpts.externalNatAddress.GetPointer());
toolButtonEnableMicroTelco->setOn((connectOpts.doMicroTelco));
LineEditUtAccount->setText((const char *)connectOpts.microTelcoAccount.GetPointer());
LineEditUtPassword->setText((const char *)connectOpts.microTelcoPassword.GetPointer());
SpinBoxLowUdp->setValue(connectOpts.lowUdpPort);
SpinBoxHighUdp->setValue(connectOpts.highUdpPort);
CheckBoxSearchForAGatekeeper->setChecked(connectOpts.searchForGatekeeper);
checkBoxEnableLogging->setChecked(connectOpts.doLogInternalActivity);
spinBoxLogLevel->setValue(connectOpts.logLevel);
logFileName = (const char *)connectOpts.logFileName;
checkBoxBlocks->setChecked(connectOpts.logBlocks);
checkBoxDateTime->setChecked(connectOpts.logDateTime);
checkBoxFileLine->setChecked(connectOpts.logFileLine);
checkBoxLevelNumber->setChecked(connectOpts.logLevelNumber);
checkBoxThreadAddress->setChecked(connectOpts.logThreadAddress);
checkBoxThreadNames->setChecked(connectOpts.logThreadNames);
checkBoxTimestamp->setChecked(connectOpts.logTimestamp);
/////
controlsSet = true;
NatTraversalChangedSlot();
MicroTelcoChangedSlot();
UpdateLogFileName();
EnableDisableLoggingSlot();
UpdateCurrentGatekeeperText();
BOOL inACall = !CPhone::GetUi().WaitingForACall();
OnConnectionEstablished(inACall);
}
void Settings::InitialiseCodecSettings()
{
ListViewActiveCodecs->setSorting(-1);
ListViewActiveCodecs->setColumnWidthMode(0, QListView::Maximum);
ListViewDormantCodecs->setSorting(-1);
ListViewDormantCodecs->setColumnWidthMode(0, QListView::Maximum);
PStringList activeCodecs = connectOpts.GetEnabledCapabilities();
PStringList dormantCodecs = connectOpts.GetDisabledCapabilities();
PINDEX i;
for(i=0; i < activeCodecs.GetSize(); i++)
AddItemToList(ListViewActiveCodecs, activeCodecs[i]);
for(i=0; i < dormantCodecs.GetSize(); i++)
AddItemToList(ListViewDormantCodecs, dormantCodecs[i]);
}
void Settings::AddItemToList(QListView *srcList, PString label)
{
QListViewItem *lastItem = srcList->firstChild();
if (lastItem != NULL) {
QListViewItem *lead = lastItem->nextSibling();
while (lead != NULL) {
lastItem = lead;
lead = lead->nextSibling();
}
}
QListViewItem *item;
if(lastItem == NULL)
item = new QListViewItem(srcList);
else
item = new QListViewItem(srcList, lastItem);
item->setText( 0, label.GetPointer() );
}
//Remove all the old codec kesy in the PConfig structure. Put new ones
//in. The order of insertion is important, as it determines the
//priority ranking of the codec.
void Settings::SaveCodecSettings()
{
PStringList dormantCodecs;
PStringList activeCodecs;
QListViewItem *item = ListViewActiveCodecs->firstChild();
while (item != NULL) {
activeCodecs.AppendString((const char *)item->text(0));
item = item->nextSibling();
}
connectOpts.SetEnabledCapabilities(activeCodecs);
CPhone::GetUi().RebuildCapabilityTable();
}
void Settings::MakeCodecActive_slot()
{
QListViewItem *next;
QListViewItem *item = ListViewDormantCodecs->firstChild();
while (item != NULL) {
next = item->nextSibling();
if(item->isSelected()) {
QString codecName = item->text(0);
delete item;
AddItemToList(ListViewActiveCodecs, PString((const char *)codecName));
}
item = next;
}
}
void Settings::MakeCodecDormant_slot()
{
QListViewItem *next;
QListViewItem *item = ListViewActiveCodecs->firstChild();
while (item != NULL) {
next = item->nextSibling();
if(item->isSelected()) {
QString codecName = item->text(0);
delete item;
AddItemToList(ListViewDormantCodecs, PString((const char *)codecName));
}
item = next;
}
}
void Settings::MoveCodecUp_slot()
{
PStringList list = GetSelectedCapabilities();
if (list.GetSize() == 0)
return;
//First check that we can move everything down;
QListViewItem *thisCodec,*parentCodec,*grandParentCodec;
thisCodec = FindThisCodec(QString((const char *)list[0]));
if(thisCodec->itemAbove() == NULL) {
return;
}
//We can move all items up.
for(PINDEX i= 0; i < list.GetSize(); i++) {
thisCodec = FindThisCodec(QString((const char *)list[i]));
if(thisCodec == NULL)
return;
parentCodec = thisCodec->itemAbove();
if(parentCodec == NULL)
return;
grandParentCodec = parentCodec->itemAbove();
if(grandParentCodec == NULL) {
thisCodec->moveItem(ListViewActiveCodecs->firstChild());
ListViewActiveCodecs->firstChild()->moveItem(thisCodec);
} else
thisCodec->moveItem(grandParentCodec);
}
}
void Settings::MoveCodecDown_slot()
{
PStringList list = GetSelectedCapabilities();
if (list.GetSize() == 0)
return;
//First check that we can move everything down;
QListViewItem *thisCodec;
thisCodec = FindThisCodec(QString((const char *)list[list.GetSize()-1]));
if(thisCodec == NULL)
return;
if(thisCodec->nextSibling() == NULL)
return;
//We can move all items down.
for(unsigned int i= list.GetSize(); i>0; i--) {
thisCodec = FindThisCodec(QString((const char *)list[i-1]));
if(thisCodec == NULL)
return;
thisCodec->moveItem(thisCodec->nextSibling());
}
}
PStringList Settings::GetSelectedCapabilities()
{
PStringList list;
QListViewItem *item = ListViewActiveCodecs->firstChild();
while (item != NULL) {
if(item->isSelected())
list.AppendString(PString((const char *)item->text(0)));
item = item->nextSibling();
}
return list;
}
QListViewItem * Settings::FindThisCodec(QString sourceCodec)
{
QListViewItem *thisCodec = ListViewActiveCodecs->firstChild();
while (thisCodec != NULL) {
if (thisCodec->text(0) == sourceCodec) {
return thisCodec;
}
thisCodec = thisCodec->nextSibling();
}
return NULL;
}
void Settings::UpdateCurrentGatekeeperText()
{
TextLabelMicroTelcoStatus->setText((const char *)CPhone::GetUi().GetGatekeeperName());
if (!TextLabelMicroTelcoStatus->text().isEmpty())
DisplayMessage(QString("Gatekeeper set to ") + TextLabelMicroTelcoStatus->text());
}
void Settings::DisplayMessage(const char * message)
{
DisplayMessage(QString(message));
}
void Settings::DisplayMessage(PString message)
{
DisplayMessage(QString((const char *)message));
}
void Settings::DisplayMessage(QString message)
{
// PTRACE(1, "GuiThread\t SettingsWindow " << (const char *)message);
LabelDisplaySettingsEnabled->prepareDisplayText(message);
QCustomEvent *ce = new QCustomEvent(QEvent::User);
QApplication::postEvent(LabelDisplaySettingsEnabled, ce);
killTimers();
startTimer(20 * 1000); //display text for 20 seconds.
}
void Settings::OnConnectionEstablished(bool isEstablished)
{
//isEstablished is true means this call is being created.
//isEstablished is false means this call is terminated.
DisplayMessage(isEstablished ? QString("Controls disabled during call") : QString("Controls now active"));
char * patterns[] = {"LineEditGatekeeper" , "LineEditUserName" , "SpinBox.*" , "toolButton.*",
"CheckBox.*", "LineEditNatTraversal", "toolButtonEnableMicroTelco",
"LineEditUtAccount,", "LineEditUtPassword",
"SpinBoxLowUdp", "SpinBoxHighUdp", "checkBox.*", "toolButtonEnableLogging",
"pushButtonDoSelectFile", "spinBox.*", 0 };
int index = 0;
while (patterns[index] != NULL) {
QObjectList * l = topLevelWidget()->queryList("QObject", patterns[index]);
QObjectListIt it( *l ); // iterate over the QObjects matching patterns[index]
QObject * obj;
while ((obj = it.current()) != 0) { // for each found QObject
++it;
((QWidget *)obj)->setEnabled(!isEstablished);
}
delete l; // delete the list, not the objects
index ++;
}
}
void Settings::UpdateLogFileName()
{
TextLabelLogFileName->setText(logFileName);
}
void Settings::EnableDisableLoggingSlot()
{
if (!controlsSet)
return;
// add more here if needed.
}
void Settings::SelectFileNameSlot()
{
QFileDialog *dlg = new QFileDialog(QString::null, QString::null, 0, 0, FALSE);
dlg->setCaption(QFileDialog::tr( "Select log file"));
dlg->setMode(QFileDialog::AnyFile);
if (dlg->exec() == QDialog::Accepted)
logFileName = dlg->selectedFile();
delete dlg;
UpdateLogFileName();
}
void Settings::MicroTelcoChangedSlot()
{
if (!controlsSet)
return;
bool b = ( toolButtonEnableMicroTelco->state() == QButton::On);
toolButtonEnableMicroTelco->setPixmap((const char **)(b ? microtelcoOn : microtelcoOff));
toolButtonEnableMicroTelco->setTextLabel((b ? QString("Micro Telco Services Active") : QString("No Micro Telco")));
CheckBoxSearchForAGatekeeper->setEnabled(!b);
LineEditGatekeeper->setEnabled(!b);
}
void Settings::NatTraversalChangedSlot()
{
if (!controlsSet)
return;
bool b = (toolButtonNatTraversal->state() == QButton::On);
toolButtonNatTraversal->setText((b ? "Enable traversal" : "No traversal"));
toolButtonNatTraversal->setPixmap((const char **) (b ? nat_traversal_on : nat_traversal_off));
}
void Settings::closeEvent(QCloseEvent *e)
{
CPhone::Current().ForgetExists(eSettings, winId());
e->accept();
}
void Settings::customEvent(QCustomEvent *e)
{
if (e->type() == CUSTOM_EVENT_DIE)
close(TRUE);
if (e->type() == CUSTOM_EVENT_SETUP)
Setup();
}
void Settings::timerEvent(QTimerEvent *)
{
LabelDisplaySettingsEnabled->clear(); //setText("");
}
void Settings::ApplySettings_Slot()
{
SaveCurrentEntries();
}
void Settings::CancelSettings_Slot()
{
close(TRUE);
}
void Settings::OkSettings_Slot()
{
SaveCurrentEntries();
close(TRUE);
}
void Settings::SaveCurrentEntries()
{
SaveCodecSettings();
SaveGatekeeperMicroTelco();
SaveConnectionInfo();
SaveErrorLogging();
}
void Settings::SaveGatekeeperMicroTelco()
{
PString res;
connectOpts.doMicroTelco = (toolButtonEnableMicroTelco->state() == QButton::On);
if (connectOpts.doMicroTelco) {
BOOL success = CPhone::GetUi().MicroTelcoActivate(true);
if (success)
DisplayMessage("Micro Telco Activated");
else {
toolButtonEnableMicroTelco->setOn(false);
PString res = CPhone::GetUi().GetGatekeeperRegistrationMessage();
DisplayMessage("Micro Telco Failed : " + res);
connectOpts.doMicroTelco = false;
MicroTelcoChangedSlot();
}
}
PString failMessage = "";
if (toolButtonEnableMicroTelco->state() == QButton::Off) {
connectOpts.gatekeeperName = (const char *)LineEditGatekeeper->text();
if (LineEditGatekeeper->text().isEmpty()) {
connectOpts.searchForGatekeeper = CheckBoxSearchForAGatekeeper->isChecked();
failMessage = "Could not find any gatekeeper : ";
} else {
connectOpts.searchForGatekeeper = false;
CheckBoxSearchForAGatekeeper->setChecked(false);
failMessage = LineEditGatekeeper->text() + " not found : ";
}
if (!CPhone::GetUi().InitialiseGatekeeper()) {
PString res = CPhone::GetUi().GetGatekeeperRegistrationMessage();
DisplayMessage(failMessage + res);
}
}
UpdateCurrentGatekeeperText();
}
void Settings::SaveConnectionInfo()
{
connectOpts.autoAnswer = CheckBoxAutoAnswer->isChecked();
connectOpts.noFastStart = CheckBoxDisableFastStart->isChecked();
connectOpts.noH245Tunnelling = CheckBoxDisableH245Tunnel->isChecked();
connectOpts.packetUtilization = SpinBoxFramesEthernetPacket->value();
connectOpts.noH245Tunnelling = CheckBoxDisableH245Tunnel->isChecked();
long i = SpinBoxBandwidthAudio->value();
connectOpts.audioBandwidth = i;
i = SpinBoxBandwidthVideo->value();
connectOpts.videoBandwidth = i;
bool b = CheckBoxDefaultAudio->isChecked();
connectOpts.useDefaultAudioBandwidth = b;
b = CheckBoxDefaultVideo->isChecked();
connectOpts.useDefaultVideoBandwidth = b;
b = (toolButtonNatTraversal->state() == QButton::On);
if (b && LineEditNatTraversal->text().isEmpty()) {
DisplayMessage("No external ip address supplied");
toolButtonNatTraversal->setDown(false);
b = false;
}
connectOpts.doNatTraversal = b;
connectOpts.externalNatAddress =
(const char *)LineEditNatTraversal->text();
CPhone::GetUi().UpdateNatTraversalAddress();
QString s = LineEditUserName->text();
if (s.isEmpty()) {
s = PProcess::Current().GetUserName().GetPointer();
DisplayMessage("Empty user name is ignored. Using \"" + s + "\"");
}
connectOpts.userName = (const char *)s;
CPhone::GetUi().UpdateUserName();
s = LineEditUtPassword->text();
connectOpts.microTelcoPassword = (const char *)s;
int l, h, t;
l = SpinBoxLowUdp->value();
h = SpinBoxHighUdp->value();
if (l > h) {
t = l;
l = h;
h = t;
}
connectOpts.highUdpPort = h;
connectOpts.lowUdpPort = l;
}
void Settings::SaveErrorLogging()
{
connectOpts.doLogInternalActivity = checkBoxEnableLogging->isChecked();
connectOpts.logLevel= spinBoxLogLevel->value();
connectOpts.logFileName = (const char *)logFileName;
connectOpts.logBlocks = checkBoxBlocks->isChecked();
connectOpts.logDateTime = checkBoxDateTime->isChecked();
connectOpts.logFileLine = checkBoxFileLine->isChecked();
connectOpts.logLevelNumber = checkBoxLevelNumber->isChecked();
connectOpts.logThreadAddress = checkBoxThreadAddress->isChecked();
connectOpts.logThreadNames = checkBoxThreadNames->isChecked();
connectOpts.logTimestamp = checkBoxTimestamp->isChecked();
connectOpts.InstallLogging();
}
syntax highlighted by Code2HTML, v. 0.9.1