提交 ebd314b5 authored 作者: Mitch Capper's avatar Mitch Capper

Accessibility changes, keyboard shortcuts, UIA, key handling cleanup, account…

Accessibility changes, keyboard shortcuts, UIA, key handling cleanup, account enabled on account options page
上级 05667783
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text.RegularExpressions;
......@@ -383,10 +384,19 @@ namespace FSClient {
public bool edit() {
current_editing_account = this;
GenericEditor editor = new GenericEditor();
editor.Init("Editing Account", values);
List<FieldValue> vals = new List<FieldValue>(values);
var enabled_field = new Field(Field.FIELD_TYPE.Bool, "Account Enabled","enabled","",enabled ? "true" : "false","");
var enabled_val = enabled_field.GetDefaultValue();
vals.Insert(0, enabled_val);
editor.Init("Editing Account", vals);
editor.ShowDialog();
if (editor.DialogResult == true)
if (editor.DialogResult == true){
if (enabled_val.value == "true")
enabled = true;
else
enabled = false;
ReloadAccount();
}
else
return false;
return true;
......
......@@ -29,7 +29,6 @@ namespace FSClient {
NewEvent += conference.NewFSEvent;
Call.CallStateChanged += CallStateChangedHandler;
Call.ActiveCallChanged += ActiveCallChanged;
init_us();
DelayedFunction.DelayedCall("LoadContactManager", initContactManager, 1000);
......@@ -118,6 +117,7 @@ namespace FSClient {
theme = Properties.Settings.Default.Theme;
IncomingBalloons = Properties.Settings.Default.IncomingBalloons;
IncomingTopMost = Properties.Settings.Default.FrontOnIncoming;
IncomingKeyboardFocus = Properties.Settings.Default.KeyboardFocusIncomingCall;
ClearDTMFS = Properties.Settings.Default.ClearDTMFS;
UPNPNAT = Properties.Settings.Default.UPNPNAT;
DirectSipDial = Properties.Settings.Default.DirectSipDial;
......@@ -187,41 +187,7 @@ namespace FSClient {
#region Text Input
public enum KEYBOARD_ACTION { Backspace, Erase, Enter, Escape };
public void handle_special_action(KEYBOARD_ACTION action) {
switch (action) {
case KEYBOARD_ACTION.Backspace:
if (cur_dial_str.Length > 0 && (Call.active_call == null || Call.active_call.state != Call.CALL_STATE.Answered))
cur_dial_str = cur_dial_str.Remove(cur_dial_str.Length - 1);
break;
case KEYBOARD_ACTION.Escape:
HangupPressed();
break;
case KEYBOARD_ACTION.Enter:
TalkPressed();
break;
}
}
public void handle_key_action(char key) {
cur_dial_str += key;
if (key != '*' && key != '#' && (key < '0' || key > '9'))
return;
if (Call.active_call != null && Call.active_call.state == Call.CALL_STATE.Answered)
Call.active_call.send_dtmf(key.ToString());
else {
#if ! NO_FS
PortAudio.PlayDTMF(key, null, true);
DelayedFunction.DelayedCall("PortAudioLastDigitHitStreamClose", close_streams, 5000);
#endif
}
}
private void close_streams() {
if (active_calls == 0)
PortAudio.CloseStreams();
}
#endregion
public PortAudio.AudioDevice SpeakerInDev { get; private set; }
......@@ -350,34 +316,10 @@ namespace FSClient {
account.CreateCall(str);
}
public void TalkPressed() {
if (Call.active_call != null) {
if (Call.active_call.state == Call.CALL_STATE.Ringing && Call.active_call.is_outgoing == false)
Call.active_call.answer();
else
DialTone();
}
else {
if (String.IsNullOrEmpty(cur_dial_str))
DialTone();
else {
DialString(cur_dial_str);
cur_dial_str = "";
}
}
Application.Current.Dispatcher.BeginInvoke((Action)(() => MainWindow.get_instance().TalkPressed()));
}
public void HangupPressed() {
if (Call.active_call != null) {
if (Call.active_call.state == Call.CALL_STATE.Ringing) {
Call.active_call.hangup(Call.active_call.is_outgoing ? "User Cancelled" : "User Ignored Call");
}
else
Call.active_call.hangup("User Ended");
}
else
cur_dial_str = "";
}
public void FlashPressed() {
throw new NotImplementedException();
Application.Current.Dispatcher.BeginInvoke((Action)(() => MainWindow.get_instance().HangupPressed()));
}
public void TalkTogglePressed() {
if (Call.active_call != null && (Call.active_call.state != Call.CALL_STATE.Ringing || Call.active_call.is_outgoing))
......@@ -385,9 +327,6 @@ namespace FSClient {
else
TalkPressed();
}
public void RedialPressed() {
throw new NotImplementedException();
}
#region deconstructors
......@@ -416,6 +355,7 @@ namespace FSClient {
Properties.Settings.Default.CheckForUpdates = CheckForUpdates;
Properties.Settings.Default.GuiStartup = GUIStartup;
Properties.Settings.Default.FrontOnIncoming = IncomingTopMost;
Properties.Settings.Default.KeyboardFocusIncomingCall = IncomingKeyboardFocus;
Properties.Settings.Default.ClearDTMFS = ClearDTMFS;
Properties.Settings.Default.UPNPNAT = UPNPNAT;
Properties.Settings.Default.DirectSipDial = DirectSipDial;
......@@ -474,12 +414,6 @@ namespace FSClient {
call_answeredChanged(this, is_call_answered);
}
private void ActiveCallChanged(object sender, Call.ActiveCallChangedArgs e) {
if (Call.active_call != null)
cur_dial_str = Call.active_call.dtmfs;
else
cur_dial_str = "";
}
private void HandleCallWaiting(Timer timer, Call c) {
if (c.state != Call.CALL_STATE.Ringing || Call.active_call == c) {
if (timer != null) {
......@@ -509,6 +443,8 @@ namespace FSClient {
if (Call.active_call != args.call && Call.active_call != null)
HandleCallWaiting(null, args.call);
}
else if (IncomingKeyboardFocus)
Utils.SetForegroundWindow(MainWindow.get_instance());
}
if (DND && args.call != null && args.call.is_outgoing == false && args.call.state == Call.CALL_STATE.Ringing)
args.call.hangup("Call ignored due to DND");
......@@ -521,6 +457,7 @@ namespace FSClient {
public bool IncomingBalloons;
public bool IncomingTopMost;
public bool IncomingKeyboardFocus;
public string CheckForUpdates;
public string GUIStartup;
......@@ -713,19 +650,6 @@ namespace FSClient {
private bool _DND;
public Utils.ObjectEventHandler<bool> DNDChanged;
public string cur_dial_str {
get { return _cur_dial_str; }
set {
if (value == _cur_dial_str)
return;
_cur_dial_str = value;
if (cur_dial_strChanged != null)
cur_dial_strChanged(this, value);
}
}
private string _cur_dial_str;
public Utils.ObjectEventHandler<string> cur_dial_strChanged;
public string recordings_folder {
get { return _recordings_folder; }
set {
......
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
......@@ -193,7 +194,7 @@ namespace FSClient {
RaisePropertyChanged("dtmfs");
}
}
private string _dtmfs;
private string _dtmfs="";
#endregion
......@@ -253,13 +254,13 @@ namespace FSClient {
item = new MenuItem() { Header = "Their Volume" };
for (int x = -4; x <= 4; x++) {
int val = x;
item.Items.Add(CreateMenuItem("Level " + x, () => SetOtherPartyAudioLevel(val)));
item.Items.Add(CreateMenuItem("Level " + x + (other_audio_level == x ? "*" : ""), () => SetOtherPartyAudioLevel(val)));
}
menu.Items.Add(item);
item = new MenuItem() { Header = "Your Volume" };
for (int x = -4; x <= 4; x++) {
int val = x;
item.Items.Add(CreateMenuItem("Level " + x, () => SetOurAudioLevel(val)));
item.Items.Add(CreateMenuItem("Level " + x + (our_audio_level == x ? "*" : ""), () => SetOurAudioLevel(val)));
}
menu.Items.Add(item);
menu.Items.Add(CreateMenuItem("End Call", hangup));
......@@ -346,7 +347,6 @@ namespace FSClient {
var call = (from c in calls where (c.leg_a_uuid == uuid || c.leg_b_uuid == uuid) && c.call_ended==false select c).SingleOrDefault();
if (call != null && call.state == CALL_STATE.Answered && digit.Length == 1)
PortAudio.PlayDTMF(digit[0], call.leg_a_uuid);
}
public static void HandleOutgoingEvent(FSEvent evt, String uuid) //capture an outgoing call the other leg
{
......@@ -458,7 +458,7 @@ namespace FSClient {
return;
if (call.state == CALL_STATE.Ringing || (call.state == CALL_STATE.Hold_Ringing && !call.is_outgoing))
call.UpdateCallState(CALL_STATE.Answered, call.is_outgoing ? active_call : active_call);
call.UpdateCallState(CALL_STATE.Answered, (call.is_outgoing || call.is_conference_call) ? active_call : call);
else if (call.state == CALL_STATE.Hold_Ringing)
call.UpdateCallState(CALL_STATE.Hold, active_call);
else
......@@ -538,23 +538,31 @@ namespace FSClient {
item.Click += (o, args) => action();
return item;
}
public ContextMenu CallRightClickMenu() {
ContextMenu menu = new ContextMenu();
menu.Opened += call_ContextMenuOpened;
return menu;
private ContextMenu _CallRightClickMenu;
public ContextMenu CallRightClickMenu {
get{
if (_CallRightClickMenu == null){
_CallRightClickMenu = new ContextMenu();
_CallRightClickMenu.Opened += call_ContextMenuOpened;
}
return _CallRightClickMenu;
}
}
private static Broker broker;
private int our_audio_level;
public void SetOurAudioLevel(int level){
if (level > 4 || level < -4)
return;
our_audio_level = level;
Utils.bgapi_exec("uuid_audio", leg_b_uuid + " start write level " + level);
}
private int other_audio_level;
public void SetOtherPartyAudioLevel(int level){
if (level > 4 || level < -4)
return;
other_audio_level = level;
Utils.bgapi_exec("uuid_audio", leg_b_uuid + " start read level " + level);
}
public void RemoveCallFromHistory(){
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
namespace FSClient.Controls {
public class OurAutoCompleteBox : AutoCompleteBox {
private TextBox the_textbox;
private void find_textbox(){
if (the_textbox != null)
return;
the_textbox = Template.FindName("Text", this) as TextBox;
}
public TextBox GetActualTextbox() {
find_textbox();
return the_textbox;
}
public bool TextBoxHasFocus(){
find_textbox();
if (the_textbox == null)
return false;
return the_textbox.IsFocused;
}
public void TextBoxFocus(){
find_textbox();
if (the_textbox != null)
the_textbox.Focus();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
namespace FSClient.Controls {
public class OurAutoCompleteBox : AutoCompleteBox {
private TextBox the_textbox;
private void find_textbox(){
if (the_textbox != null)
return;
the_textbox = Template.FindName("Text", this) as TextBox;
if (the_textbox != null)
the_textbox.TabIndex = TabIndex;
}
public TextBox GetActualTextbox() {
find_textbox();
return the_textbox;
}
public bool TextBoxHasFocus(){
find_textbox();
if (the_textbox == null)
return false;
return the_textbox.IsFocused;
}
public void TextBoxFocus(){
find_textbox();
if (the_textbox != null)
the_textbox.Focus();
}
}
}
......@@ -2,14 +2,14 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Controls="clr-namespace:FSClient.Controls" mc:Ignorable="d"
x:Class="FSClient.Controls.PhonePadButton"
x:Name="UserControl"
Width="30" Height="30">
<Grid x:Name="LayoutRoot">
<Button Style="{DynamicResource GlassButtonStyle}" Foreground="White" x:Name="btn">
<Button Style="{DynamicResource GlassButtonStyle}" Foreground="White" x:Name="btn" TabIndex="{Binding Path=TabIndex, RelativeSource={RelativeSource AncestorType={x:Type Controls:PhonePadButton}}}">
<StackPanel Width="Auto">
<TextBlock x:Name="lblNumber" FontSize="12" FontWeight="Bold" HorizontalAlignment="Center" Margin="0,-2,0,0" Text="5"/>
<TextBlock x:Name="lblLetters" FontSize="7" HorizontalAlignment="Center" Foreground="#FFC2B4B4" FontWeight="Bold" Width="24.388" TextAlignment="Center" RenderTransformOrigin="0.5,0.5" Margin="0,-2,0,0" >
......
......@@ -2,7 +2,9 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Automation.Peers;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
......@@ -36,14 +38,17 @@ namespace FSClient.Controls
public string Number
{
get { return lblNumber.Text; }
set { lblNumber.Text = value; }
get { return lblNumber.Text; }
set { lblNumber.Text = value; AutomationProperties.SetName(btn, value); AutomationProperties.SetName(this, value); AutomationProperties.SetItemType(this,"Button"); }
}
public string Letters
{
get { return lblLetters.Text; }
set { lblLetters.Text = value; }
}
}
protected AutomationControlType GetAutomationControlTypeCore() {
return AutomationControlType.Button;
}
}
}
\ No newline at end of file
......@@ -88,7 +88,10 @@ namespace FSClient {
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
if (value == null)
return "";
bool is_outgoing = (bool)value;
return EnglishDirectionConverter.Convert((bool)value);
}
public static String Convert(bool is_outgoing) {
return is_outgoing ? "Outgoing" : "Incoming";
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
......@@ -110,7 +113,9 @@ namespace FSClient {
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
if (value == null)
return "";
TimeSpan duration = (TimeSpan)value;
return Convert((TimeSpan)value);
}
public static string Convert(TimeSpan duration) {
return duration.Minutes + ":" + duration.Seconds.ToString("00");
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
......
......@@ -10,8 +10,8 @@
<TabControl Margin="8,44,14,53" Name="tabControlMain">
</TabControl>
<Button x:Name="btnCancel" Content="Cancel" HorizontalAlignment="Right" Margin="0,0,82,17.04" VerticalAlignment="Bottom" Width="75" Click="btnCancel_Click" />
<Button x:Name="btnSave" Content="Save" HorizontalAlignment="Left" Margin="57,0,0,17.04" VerticalAlignment="Bottom" Width="75" Click="btnSave_Click" />
<Button x:Name="btnCancel" Content="Cancel" HorizontalAlignment="Right" Margin="0,0,82,17.04" VerticalAlignment="Bottom" Width="75" Click="btnCancel_Click" IsCancel="True" />
<Button x:Name="btnSave" Content="Save" HorizontalAlignment="Left" Margin="57,0,0,17.04" VerticalAlignment="Bottom" Width="75" Click="btnSave_Click" IsDefault="True" />
<TextBlock Height="29" Margin="8,9,14,0" Name="txtTitle" Text="Title Here" VerticalAlignment="Top" FontSize="20" FontWeight="Bold" TextAlignment="Center" />
</Grid>
</Window>
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Controls;
namespace FSClient {
......@@ -15,7 +16,7 @@ namespace FSClient {
}
private Dictionary<FieldValue, UIElement> elements_to_ui = new Dictionary<FieldValue, UIElement>();
private Dictionary<FieldValue, TabItem> element_to_page = new Dictionary<FieldValue, TabItem>();
public void Init(String title, FieldValue[] values) {
public void Init(String title, IEnumerable<FieldValue> values) {
txtTitle.Text = title;
Title = title;
Dictionary<string, StackPanel> tabs = new Dictionary<string, StackPanel>();
......@@ -108,6 +109,7 @@ namespace FSClient {
ret = comboBox;
break;
}
AutomationProperties.SetName(ret, value.field.display_name);
return ret;
}
private void btnCancel_Click(object sender, RoutedEventArgs e) {
......
......@@ -235,11 +235,11 @@ namespace FSClient {
broker.Muted = false;
break;
case IHeadsetDevice.HEADSET_EVENT_TYPE.Redial:
broker.RedialPressed();
//broker.RedialPressed();
break;
case IHeadsetDevice.HEADSET_EVENT_TYPE.Flash:
broker.FlashPressed();
//broker.FlashPressed();
break;
}
......
......@@ -25,9 +25,9 @@
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Name="lblCaller" HorizontalAlignment="Left" TextWrapping="Wrap" Text="800-ComCasT" VerticalAlignment="Top" Grid.ColumnSpan="3"/>
<Button Content="Answer" Height="20" x:Name="btnCall" Width="50" Click="btnCall_Click" Style="{DynamicResource GlassButtonStyle}" Foreground="#FF4EFF00" FontWeight="Bold" HorizontalAlignment="Left" VerticalAlignment="Bottom" Grid.Row="1" Margin="2,0,0,2" />
<Button Content="End" Height="20" HorizontalAlignment="Right" x:Name="btnHangup" Width="50" Click="btnHangup_Click" Style="{DynamicResource GlassButtonStyle}" Foreground="#FFF50000" FontWeight="Bold" VerticalAlignment="Bottom" Grid.Row="1" Grid.Column="2" Margin="0,0,2,2" />
<Button Content="Send To Voicemail" FontWeight="Bold" Foreground="#FFF5E200" Grid.RowSpan="2" Height="20" HorizontalAlignment="Stretch" Margin="20,18,20,0" Name="btnSendVoicemail" Style="{DynamicResource GlassButtonStyle}" VerticalAlignment="Top" Grid.ColumnSpan="3" Click="btnSendVoicemail_Click" />
<Button Content="XFER" FontWeight="Bold" Foreground="Blue" Height="20" Grid.Row="1" Grid.Column="1" VerticalAlignment="Bottom" Margin="0,0,2,2" Name="btnTransfer" Style="{DynamicResource GlassButtonStyle}" Width="40" Click="btnTransfer_Click" />
<Button Content="Answer" Height="20" x:Name="btnCall" Width="50" Click="btnCall_Click" Style="{DynamicResource GlassButtonStyle}" Foreground="#FF4EFF00" FontWeight="Bold" HorizontalAlignment="Left" VerticalAlignment="Bottom" Grid.Row="1" Margin="2,0,0,2" AutomationProperties.Name="Answer Call" TabIndex="1" IsDefault="True" />
<Button Content="End" Height="20" HorizontalAlignment="Right" x:Name="btnHangup" Width="50" Click="btnHangup_Click" Style="{DynamicResource GlassButtonStyle}" Foreground="#FFF50000" FontWeight="Bold" VerticalAlignment="Bottom" Grid.Row="1" Grid.Column="2" Margin="0,0,2,2" AutomationProperties.Name="End Call" TabIndex="3" />
<Button Content="Send To Voicemail" FontWeight="Bold" Foreground="#FFF5E200" Grid.RowSpan="2" Height="20" HorizontalAlignment="Stretch" Margin="20,18,20,0" Name="btnSendVoicemail" Style="{DynamicResource GlassButtonStyle}" VerticalAlignment="Top" Grid.ColumnSpan="3" Click="btnSendVoicemail_Click" AutomationProperties.Name="Send To Voicemail" TabIndex="4" />
<Button Content="XFER" FontWeight="Bold" Foreground="Blue" Height="20" Grid.Row="1" Grid.Column="1" VerticalAlignment="Bottom" Margin="0,0,2,2" Name="btnTransfer" Style="{DynamicResource GlassButtonStyle}" Width="40" Click="btnTransfer_Click" AutomationProperties.Name="Transfer" TabIndex="2" />
</Grid>
</Window>
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Forms;
namespace FSClient {
......@@ -23,12 +24,19 @@ namespace FSClient {
private void Window_Loaded(object sender, RoutedEventArgs e) {
PositionWindows();
lblCaller.Text = call.other_party_name + " - " + call.other_party_number;
Title = "FSClient Incoming Call " + lblCaller.Text;
prop_changed = new System.ComponentModel.PropertyChangedEventHandler(call_PropertyChanged);
call.PropertyChanged += prop_changed;
btnSendVoicemail.Visibility = call.CanSendToVoicemail() ? Visibility.Visible : Visibility.Hidden;
btnTransfer.ContextMenu = Broker.get_instance().XFERContextMenu();
if (Broker.get_instance().IncomingKeyboardFocus)
DelayedFunction.DelayedCall("BubbleTop", MakeUsTop, 500);
Show();
Topmost = true;
}
private void MakeUsTop(){
Dispatcher.BeginInvoke((Action)(() => Utils.SetForegroundWindow(this)));
}
void call_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) {
if (e.PropertyName == "state") {
if (call.state != Call.CALL_STATE.Ringing)
......
......@@ -9,14 +9,14 @@
<RowDefinition Height="35" />
</Grid.RowDefinitions>
<Label Name="lblDesc" Grid.Row="0"/>
<TextBox Name="txtInput" Grid.Row="1" Margin="10" KeyUp="txtInput_KeyUp" />
<TextBox Name="txtInput" Grid.Row="1" Margin="10" />
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Content="Ok" Width="75" Grid.Column="0" HorizontalAlignment="Left" Name="btnOk" Margin="5" Click="btnOk_Click" />
<Button Content="Cancel" Width="75" HorizontalAlignment="Right" Margin="5" Grid.Column="1" Name="btnCancel" Click="btnCancel_Click" />
<Button Content="Ok" Width="75" Grid.Column="0" HorizontalAlignment="Left" Name="btnOk" Margin="5" Click="btnOk_Click" IsDefault="True" />
<Button Content="Cancel" Width="75" HorizontalAlignment="Right" Margin="5" Grid.Column="1" Name="btnCancel" Click="btnCancel_Click" IsCancel="True" />
</Grid>
......
using System;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Input;
namespace FSClient {
......@@ -20,6 +21,7 @@ namespace FSClient {
InputBox box = new InputBox();
box.lblDesc.Content = desc;
box.Title = title;
AutomationProperties.SetName(box.txtInput, desc);
box.txtInput.Text = default_value;
if (box.ShowDialog() != true)
return null;
......@@ -36,9 +38,5 @@ namespace FSClient {
Close();
}
private void txtInput_KeyUp(object sender, KeyEventArgs e) {
if (e.Key == Key.Return)
btnOk_Click(null, null);
}
}
}
......@@ -18,7 +18,7 @@
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="130" />
<RowDefinition Height="110" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Grid Grid.ColumnSpan="2">
......@@ -37,49 +37,51 @@
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Column="0" Grid.ColumnSpan="2" HorizontalAlignment="Center" >
<Button Content="Reload Devices" Height="23" Name="btnReloadDevices" Width="100" Click="btnReloadDevices_Click" />
<Button Content="Sofia Settings" Height="23" Name="btnSofiaSettings" Width="100" Margin="10,0,0,0" Click="btnSofiaSettings_Click" />
<Button Content="Event Socket Settings" Height="23" Name="btnEventSocketSettings" Width="125" Margin="10,0,0,0" Click="btnEventSocketSettings_Click" />
<Button Content="Plugin Settings" Height="23" Name="btnPluginSettings" Width="100" Margin="10,0,0,0" Click="btnPluginSettings_Click" />
<Button Content="Reload Devices" Height="23" Name="btnReloadDevices" Width="100" Click="btnReloadDevices_Click" TabIndex="50" />
<Button Content="Sofia Settings" Height="23" Name="btnSofiaSettings" Width="100" Margin="10,0,0,0" Click="btnSofiaSettings_Click" TabIndex="51" />
<Button Content="Event Socket Settings" Height="23" Name="btnEventSocketSettings" Width="125" Margin="10,0,0,0" Click="btnEventSocketSettings_Click" TabIndex="52" />
<Button Content="Plugin Settings" Height="23" Name="btnPluginSettings" Width="100" Margin="10,0,0,0" Click="btnPluginSettings_Click" TabIndex="53" />
</StackPanel>
<TextBlock Grid.Row="1" Text="Headset Device:" Style="{DynamicResource OptionHeaderStyle}" />
<ComboBox Height="23" Grid.Row="1" Grid.Column="1" Name="comboHeadsetDevice" Width="340" />
<TextBlock Grid.Row="1" Text="Headset Extras:" Style="{DynamicResource OptionHeaderStyle}" />
<ComboBox Height="23" Grid.Row="1" Grid.Column="1" Name="comboHeadsetDevice" Width="340" TabIndex="1" />
<TextBlock Grid.Row="2" Text="Main Input:" Style="{DynamicResource OptionHeaderStyle}" />
<ComboBox Height="23" Grid.Row="2" Grid.Column="1" Name="comboHeadsetInput" Width="340" />
<ComboBox Height="23" Grid.Row="2" Grid.Column="1" Name="comboHeadsetInput" Width="340" TabIndex="2" />
<TextBlock Grid.Row="3" Text="Main Output:" Style="{DynamicResource OptionHeaderStyle}" />
<ComboBox Height="23" Grid.Row="3" Grid.Column="1" Name="comboHeadsetOutput" Width="340" />
<ComboBox Height="23" Grid.Row="3" Grid.Column="1" Name="comboHeadsetOutput" Width="340" TabIndex="3" />
<TextBlock Grid.Row="4" Text="Speakerphone Input:" Style="{DynamicResource OptionHeaderStyle}" />
<ComboBox Height="23" Grid.Row="4" Grid.Column="1" Name="comboSpeakerInput" Width="340" />
<ComboBox Height="23" Grid.Row="4" Grid.Column="1" Name="comboSpeakerInput" Width="340" TabIndex="4" />
<TextBlock Grid.Row="5" Text="Speakerphone Output:" Style="{DynamicResource OptionHeaderStyle}" />
<ComboBox Height="23" Grid.Row="5" Grid.Column="1" Name="comboSpeakerOutput" Width="340" />
<ComboBox Height="23" Grid.Row="5" Grid.Column="1" Name="comboSpeakerOutput" Width="340" TabIndex="5" />
<TextBlock Grid.Row="6" Text="Ring Device:" Style="{DynamicResource OptionHeaderStyle}" />
<ComboBox Height="23" Grid.Row="6" Grid.Column="1" Name="comboRingDevice" Width="340" />
<TextBlock Grid.Row="7" Text="Startup Layout:" Style="{DynamicResource OptionHeaderStyle}" />
<ComboBox Height="23" Grid.Row="7" Grid.Column="1" Name="comboGUIStartup" Width="340" />
<TextBlock Grid.Row="8" Text="Theme:" Style="{DynamicResource OptionHeaderStyle}" />
<ComboBox Height="23" Grid.Row="8" Grid.Column="1" Name="comboTheme" Width="340" />
<TextBlock Grid.Row="9" Text="Recording Path:" Style="{DynamicResource OptionHeaderStyle}" />
<StackPanel Orientation="Horizontal" Grid.Row="9" Grid.Column="1">
<TextBox Height="23" Name="txtRecordingPath" Width="286" Margin="10,0" />
<Button Name="btnPathBrowse" Content="Browse" Height="25" Click="btnPathBrowse_Click" />
<ComboBox Height="23" Grid.Row="6" Grid.Column="1" Name="comboRingDevice" Width="340" TabIndex="6" />
<TextBlock Grid.Row="7" Text="On Incoming Call:" Style="{DynamicResource OptionHeaderStyle}" />
<ComboBox Height="23" Grid.Row="7" Grid.Column="1" Name="comboOnIncomingCall" Width="340" TabIndex="6" />
<TextBlock Grid.Row="8" Text="Startup Layout:" Style="{DynamicResource OptionHeaderStyle}" />
<ComboBox Height="23" Grid.Row="8" Grid.Column="1" Name="comboGUIStartup" Width="340" TabIndex="15" />
<TextBlock Grid.Row="9" Text="Theme:" Style="{DynamicResource OptionHeaderStyle}" />
<ComboBox Height="23" Grid.Row="9" Grid.Column="1" Name="comboTheme" Width="340" TabIndex="16" />
<TextBlock Grid.Row="10" Text="Recording Path:" Style="{DynamicResource OptionHeaderStyle}" />
<StackPanel Orientation="Horizontal" Grid.Row="11" Grid.Column="1">
<TextBox Height="23" Name="txtRecordingPath" Width="286" Margin="10,0" AutomationProperties.Name="Path to store recordings in" TabIndex="17" />
<Button Name="btnPathBrowse" Content="Browse" Height="25" Click="btnPathBrowse_Click" AutomationProperties.Name="Browse for folder to store recordings in" TabIndex="18" />
</StackPanel>
</Grid>
<StackPanel Grid.Row="1" Grid.Column="1">
<CheckBox x:Name="chkIncomingFront" Content="Bring To Front On Incoming Calls" VerticalAlignment="Center" FontWeight="Bold" FontSize="13.333" />
<CheckBox x:Name="chkIncomingBalloons" Content="Show Incoming Call Notification Balloons" VerticalAlignment="Center" FontWeight="Bold" FontSize="13.333" />
<CheckBox x:Name="chkClearDTMFS" Content="Clear Key Presses In Call Stats On Disconnect" VerticalAlignment="Center" FontWeight="Bold" FontSize="13.333" />
<CheckBox x:Name="chkUseNumbers" Content="Only Allow Numerical Input While Dialing" VerticalAlignment="Center" FontWeight="Bold" FontSize="13.333" />
<CheckBox x:Name="chkUpdatesOnStart" Content="Check for Updates on Startup" VerticalAlignment="Center" FontWeight="Bold" FontSize="13.333" />
<CheckBox x:Name="chkNAT" Content="UPNP NAT Startup Check(slows startup 5-10s)" VerticalAlignment="Center" FontWeight="Bold" FontSize="13.333" />
<CheckBox x:Name="chkDirectSip" Content="Direct SIP: Dialing" VerticalAlignment="Center" FontWeight="Bold" FontSize="13.333" />
<CheckBox x:Name="chkIncomingBalloons" Content="Show Incoming Call Notification Balloons" VerticalAlignment="Center" FontWeight="Bold" FontSize="13.333" TabIndex="26" />
<CheckBox x:Name="chkClearDTMFS" Content="Clear Key Presses In Call Stats On Disconnect" VerticalAlignment="Center" FontWeight="Bold" FontSize="13.333" TabIndex="27" />
<CheckBox x:Name="chkUseNumbers" Content="Only Allow Numerical Input While Dialing" VerticalAlignment="Center" FontWeight="Bold" FontSize="13.333" TabIndex="28" />
<CheckBox x:Name="chkUpdatesOnStart" Content="Check for Updates on Startup" VerticalAlignment="Center" FontWeight="Bold" FontSize="13.333" TabIndex="29" />
<CheckBox x:Name="chkNAT" Content="UPNP NAT Startup Check(slows startup 5-10s)" VerticalAlignment="Center" FontWeight="Bold" FontSize="13.333" TabIndex="30" />
<CheckBox x:Name="chkDirectSip" Content="Direct SIP: Dialing" VerticalAlignment="Center" FontWeight="Bold" FontSize="13.333" TabIndex="31" />
</StackPanel>
<Button Content="Save" Grid.Row="2" Height="23" HorizontalAlignment="Left" Margin="101,0,0,0" Name="btnSave" VerticalAlignment="Center" Width="75" Grid.ColumnSpan="2" Click="btnSave_Click" />
<Button Content="Cancel" Grid.Column="1" Grid.Row="2" Height="23" HorizontalAlignment="Left" Margin="172,0,0,0" Name="btnCancel" VerticalAlignment="Center" Width="75" Click="btnCancel_Click" />
<Button Content="Save" Grid.Row="2" Height="23" HorizontalAlignment="Left" Margin="101,0,0,0" Name="btnSave" VerticalAlignment="Center" Width="75" Grid.ColumnSpan="2" Click="btnSave_Click" TabIndex="40" IsDefault="True" />
<Button Content="Cancel" Grid.Column="1" Grid.Row="2" Height="23" HorizontalAlignment="Left" Margin="172,0,0,0" Name="btnCancel" VerticalAlignment="Center" Width="75" Click="btnCancel_Click" TabIndex="41" IsCancel="True" />
</Grid>
......
......@@ -27,6 +27,13 @@ namespace FSClient {
themes.Add(new ComboOption { key = "Black", name = "Black" });
themes.Add(new ComboOption { key = "White", name = "White" });
comboTheme.ItemsSource = themes;
IncomingCallOptions = new List<ComboOption>();
IncomingCallOptions.Add(new ComboOption { key = "None", name = "Do Nothing" });
IncomingCallOptions.Add(new ComboOption { key = "Front", name = "Bring To Front" });
IncomingCallOptions.Add(new ComboOption { key = "FrontKeyboard", name = "Bring To Front & Keyboard Focus" });
comboOnIncomingCall.ItemsSource = IncomingCallOptions;
load_devices(true);
}
......@@ -38,7 +45,8 @@ namespace FSClient {
}
}
private List<ComboOption> GuiOptions;
private List<ComboOption> themes;
private List<ComboOption> themes;
private List<ComboOption> IncomingCallOptions;
private void load_devices(bool from_settings) {
PortAudio.AudioDevice[] devices = broker.audio_devices;
comboSpeakerInput.ItemsSource = comboHeadsetInput.ItemsSource = (from d in devices where d.inputs > 0 select d).ToArray();
......@@ -55,8 +63,13 @@ namespace FSClient {
comboSpeakerInput.SelectedItem = broker.SpeakerInDev;
comboSpeakerOutput.SelectedItem = broker.SpeakerOutDev;
comboRingDevice.SelectedItem = broker.RingDev;
chkIncomingBalloons.IsChecked = broker.IncomingBalloons;
chkIncomingFront.IsChecked = broker.IncomingTopMost;
chkIncomingBalloons.IsChecked = broker.IncomingBalloons;
string incoming_key = "None";
if (broker.IncomingTopMost)
incoming_key = broker.IncomingKeyboardFocus ? "FrontKeyboard" : "Front";
comboOnIncomingCall.SelectedItem = (from g in IncomingCallOptions where g.key == incoming_key select g).FirstOrDefault();
if (comboOnIncomingCall.SelectedIndex == -1)
comboOnIncomingCall.SelectedIndex = 1;
chkClearDTMFS.IsChecked = broker.ClearDTMFS;
chkUseNumbers.IsChecked = broker.UseNumberOnlyInput;
chkUpdatesOnStart.IsChecked = broker.CheckForUpdates != "Never";
......@@ -84,8 +97,14 @@ namespace FSClient {
broker.SetSpeakerDevs(indev == null ? "" : indev.name, outdev == null ? "" : outdev.name);
outdev = comboRingDevice.SelectedItem as PortAudio.AudioDevice;
broker.SetRingDev(outdev == null ? "" : outdev.name);
broker.IncomingBalloons = chkIncomingBalloons.IsChecked == true;
broker.IncomingTopMost = chkIncomingFront.IsChecked == true;
broker.IncomingBalloons = chkIncomingBalloons.IsChecked == true;
string incoming_key = (comboOnIncomingCall.SelectedItem as ComboOption).key;
if (incoming_key == "None")
broker.IncomingKeyboardFocus = broker.IncomingTopMost = false;
else{
broker.IncomingTopMost = true;
broker.IncomingKeyboardFocus = (incoming_key == "FrontKeyboard");
}
broker.ClearDTMFS = chkClearDTMFS.IsChecked == true;
broker.UPNPNAT = chkNAT.IsChecked == true;
broker.DirectSipDial = chkDirectSip.IsChecked == true;
......
......@@ -18,17 +18,24 @@
</Grid.ColumnDefinitions>
<TextBlock Text="Contact Plugin" TextAlignment="Center" FontWeight="Bold" />
<TextBlock Text="Headset Plugins" Grid.Column="1" TextAlignment="Center" FontWeight="Bold" />
<ComboBox HorizontalAlignment="Center" Name="comboContact" VerticalAlignment="Top" Width="220" Grid.Row="1" />
<ListBox Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" Height="100" HorizontalAlignment="Center" Name="listHeadset" VerticalAlignment="Top" Width="220" SelectionMode="Multiple" />
<ComboBox HorizontalAlignment="Center" Name="comboContact" VerticalAlignment="Top" Width="220" Grid.Row="1" AutomationProperties.Name="Contact Plugin Enabled" />
<ListBox Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" Height="100" HorizontalAlignment="Center" Name="listHeadset" VerticalAlignment="Top" Width="220" SelectionMode="Multiple" AutomationProperties.Name="Headset Plugins" />
<TextBlock Text="Enabled Plugins" Grid.Row="2" Grid.ColumnSpan="2" FontWeight="Bold" TextAlignment="Center" />
<ItemsControl Grid.Row="3" Grid.ColumnSpan="2" Name="itemscontrolEnabledPlugins">
<ItemsControl Grid.Row="3" Grid.ColumnSpan="2" Name="itemscontrolEnabledPlugins" AutomationProperties.Name="Plugin Options">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="1" Margin="0,3" Width="500">
<StackPanel Orientation="Horizontal" Margin="5">
<Button Content="Options" Visibility="{Binding has_options_button, Converter={StaticResource BoolToVisibilityConverter}}" Click="btn_PluginOptions_Click" />
<Button Content="Options" Visibility="{Binding has_options_button, Converter={StaticResource BoolToVisibilityConverter}}" Click="btn_PluginOptions_Click">
<AutomationProperties.Name>
<MultiBinding StringFormat="Plugin {0} Options - {1}">
<Binding Path="name" />
<Binding Path="error_msg" />
</MultiBinding>
</AutomationProperties.Name>
</Button>
<Image Source="warning.png" Margin="10,0" Visibility="{Binding error_exists, Converter={StaticResource BoolToVisibilityConverter}}" ToolTip="{Binding error_msg}" Height="20" />
<TextBlock Text="{Binding name}" VerticalAlignment="Center" />
</StackPanel>
......@@ -36,7 +43,7 @@
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button Content="Save" Grid.Row="4" Height="22" Width="50" Name="btnSave" Click="btnSave_Click" />
<Button Content="Cancel" Grid.Row="4" Height="22" Width="50" Grid.Column="1" Name="btnCancel" Click="btnCancel_Click" />
<Button Content="Save" Grid.Row="4" Height="22" Width="50" Name="btnSave" Click="btnSave_Click" IsDefault="True" />
<Button Content="Cancel" Grid.Row="4" Height="22" Width="50" Grid.Column="1" Name="btnCancel" Click="btnCancel_Click" IsCancel="True" />
</Grid>
</Window>
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Xml;
namespace FSClient {
public class PortAudio {
......@@ -116,7 +118,14 @@ namespace FSClient {
foreach (InternalAudioDevice device in _devices)
device.is_alive = false;
Utils.api_exec("pa", "rescan");
XmlDocument doc = XmlUtils.GetDocument(Utils.api_exec("pa", "devlist xml"));
XmlDocument doc=null;
try{
doc = XmlUtils.GetDocument(Utils.api_exec("pa", "devlist xml"));
}catch(KeyNotFoundException){
MessageBox.Show("Portaudio did not return a device list most likely because it cannot find an active microphone or speaker it can use, FSClient will now exit.", "Missing Device List", MessageBoxButton.OK, MessageBoxImage.Error);
Environment.Exit(-1);
return;
}
XmlNode node = XmlUtils.GetNode(doc, "devices", 0);
foreach (XmlNode child in node.ChildNodes) {
AudioDevice dev = new AudioDevice(
......
......@@ -51,5 +51,5 @@ using System.Windows;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.2.0.1")]
[assembly: AssemblyFileVersion("1.2.0.1")]
[assembly: AssemblyVersion("1.2.0.9")]
[assembly: AssemblyFileVersion("1.2.0.9")]
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.269
// Runtime Version:4.0.30319.17929
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
......@@ -293,5 +293,17 @@ namespace FSClient.Properties {
this["Theme"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool KeyboardFocusIncomingCall {
get {
return ((bool)(this["KeyboardFocusIncomingCall"]));
}
set {
this["KeyboardFocusIncomingCall"] = value;
}
}
}
}
......@@ -71,5 +71,8 @@
<Setting Name="Theme" Type="System.String" Scope="User">
<Value Profile="(Default)">Steel</Value>
</Setting>
<Setting Name="KeyboardFocusIncomingCall" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
</Settings>
</SettingsFile>
\ No newline at end of file
using System;
using System.Configuration;
using System.Reflection;
using System.Configuration;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Timers;
using System.Windows;
using System.Windows;
using System.Windows.Interop;
using System.Xml;
using FreeSWITCH.Native;
using System.IO;
......@@ -134,6 +137,39 @@ namespace FSClient {
}
DebugWrite(event_dump + "\n");
#endif
}
}
[DllImport("user32")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32")]
public static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
[DllImport("kernel32.dll")]
public static extern uint GetCurrentThreadId();
[DllImport("user32.dll", SetLastError = true)]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("user32.dll")]
public static extern bool ShowWindowAsync(IntPtr hWnd, uint nCmdShow);
[DllImport("user32")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
private static uint GetProcessId(IntPtr hwnd, out uint thread_id) {
uint pid = 0;
thread_id = GetWindowThreadProcessId(hwnd, out pid);
return pid;
}
public const uint SW_SHOW = 0x05;
public static void SetForegroundWindow(Window to_foreground){
IntPtr hWnd = new WindowInteropHelper(to_foreground).Handle;
uint thread_id;
IntPtr foregroundHwnd = GetForegroundWindow();
GetProcessId(foregroundHwnd, out thread_id);
uint our_id = GetCurrentThreadId();
SetForegroundWindow(hWnd);
ShowWindowAsync(hWnd, SW_SHOW);
if (!AttachThreadInput(thread_id, our_id, true))
return;
SetForegroundWindow(hWnd);
ShowWindowAsync(hWnd, SW_SHOW);
AttachThreadInput(thread_id, our_id, false);
}
}
}
......@@ -61,6 +61,9 @@
<setting name="Theme" serializeAs="String">
<value>Steel</value>
</setting>
<setting name="KeyboardFocusIncomingCall" serializeAs="String">
<value>False</value>
</setting>
</FSClient.Properties.Settings>
</userSettings>
</configuration>
Markdown 格式
0% 或
您添加了 0 人 到此讨论。请谨慎行事。
请先完成此评论的编辑!
请 注册 或者 后发表评论