// // 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 #include #include #include #include #include #include #include #include #include #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 #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(); }