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

Made NO_FS a bit more robust

Moved broker to have an actuall make call function so other things can place calls
Added Contact Search Box support, it is a bit hacky to say the least.....
上级 f2269751
...@@ -7,6 +7,7 @@ using System.Windows.Controls; ...@@ -7,6 +7,7 @@ using System.Windows.Controls;
using System.Xml; using System.Xml;
using FreeSWITCH.Native; using FreeSWITCH.Native;
using FSClient.Controls;
using Timer = System.Timers.Timer; using Timer = System.Timers.Timer;
namespace FSClient { namespace FSClient {
...@@ -70,6 +71,8 @@ namespace FSClient { ...@@ -70,6 +71,8 @@ namespace FSClient {
try {//it would be better if this was in the init function but it seems some dll load errors won't be caught if it is. try {//it would be better if this was in the init function but it seems some dll load errors won't be caught if it is.
#if ! NO_FS #if ! NO_FS
fs_core_init(); fs_core_init();
#else
fs_inited = false;
#endif #endif
if (FreeswitchLoaded != null) if (FreeswitchLoaded != null)
FreeswitchLoaded(this, null); FreeswitchLoaded(this, null);
...@@ -82,7 +85,9 @@ namespace FSClient { ...@@ -82,7 +85,9 @@ namespace FSClient {
Environment.Exit(-1); Environment.Exit(-1);
} }
#if ! NO_FS
DelayedFunction.DelayedCall("SofiaProfileCheck", sofia.sofia_profile_check, 100); DelayedFunction.DelayedCall("SofiaProfileCheck", sofia.sofia_profile_check, 100);
#endif
} }
private void initContactManager() { private void initContactManager() {
...@@ -118,8 +123,10 @@ namespace FSClient { ...@@ -118,8 +123,10 @@ namespace FSClient {
if (Call.active_call != null && Call.active_call.state == Call.CALL_STATE.Answered) if (Call.active_call != null && Call.active_call.state == Call.CALL_STATE.Answered)
Call.active_call.send_dtmf(key.ToString()); Call.active_call.send_dtmf(key.ToString());
else { else {
#if ! NO_FS
PortAudio.PlayDTMF(key, null, true); PortAudio.PlayDTMF(key, null, true);
DelayedFunction.DelayedCall("PortAudioLastDigitHitStreamClose", close_streams, 5000); DelayedFunction.DelayedCall("PortAudioLastDigitHitStreamClose", close_streams, 5000);
#endif
} }
} }
private void close_streams() { private void close_streams() {
...@@ -219,23 +226,17 @@ namespace FSClient { ...@@ -219,23 +226,17 @@ namespace FSClient {
//OffHook = true; //OffHook = true;
//Utils.bgapi_exec("pa", "play tone_stream://%(10000,0,350,440);loops=20"); //Utils.bgapi_exec("pa", "play tone_stream://%(10000,0,350,440);loops=20");
} }
public void TalkPressed() { public void DialString(String str){
if (Call.active_call != null) { if (string.IsNullOrWhiteSpace(str))
if (Call.active_call.state == Call.CALL_STATE.Ringing && Call.active_call.is_outgoing == false) return;
Call.active_call.answer(); MainWindow.get_instance().RemoveFocus();
else
DialTone(); if (str.StartsWith("#") && str.Length > 2) {
} else { String acct_num = str.Substring(1, 1);
if (String.IsNullOrEmpty(cur_dial_str)) str = str.Substring(2);
DialTone();
else {
if (cur_dial_str.StartsWith("#") && cur_dial_str.Length > 2) {
String acct_num = cur_dial_str.Substring(1, 1);
cur_dial_str = cur_dial_str.Substring(2);
Account acct = (from a in Account.accounts where a.guid == acct_num select a).SingleOrDefault(); Account acct = (from a in Account.accounts where a.guid == acct_num select a).SingleOrDefault();
if (acct != null) { if (acct != null) {
acct.CreateCall(cur_dial_str); acct.CreateCall(str);
cur_dial_str = "";
return; return;
} }
} }
...@@ -243,7 +244,19 @@ namespace FSClient { ...@@ -243,7 +244,19 @@ namespace FSClient {
MessageBox.Show("no default account, make sure you have added one or more accounts (right click in the account area to add) and they are enabled (checked)"); MessageBox.Show("no default account, make sure you have added one or more accounts (right click in the account area to add) and they are enabled (checked)");
return; return;
} }
Account.default_account.CreateCall(cur_dial_str); Account.default_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 = ""; cur_dial_str = "";
} }
} }
...@@ -555,6 +568,10 @@ namespace FSClient { ...@@ -555,6 +568,10 @@ namespace FSClient {
BroadcastHandler = new BroadcastEventDel(BroadcastEvent); BroadcastHandler = new BroadcastEventDel(BroadcastEvent);
Application.Current.Dispatcher.BeginInvoke(BroadcastHandler, new object[] { new FSEvent(args.EventObj) }); Application.Current.Dispatcher.BeginInvoke(BroadcastHandler, new object[] { new FSEvent(args.EventObj) });
} }
public OurAutoCompleteBox GetContactSearchBox() {
return MainWindow.get_instance().GetContactSearchBox();
}
private delegate void BroadcastEventDel(FSEvent evt); private delegate void BroadcastEventDel(FSEvent evt);
BroadcastEventDel BroadcastHandler; BroadcastEventDel BroadcastHandler;
private void BroadcastEvent(FSEvent evt) { private void BroadcastEvent(FSEvent evt) {
......
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();
}
}
}
...@@ -68,6 +68,10 @@ ...@@ -68,6 +68,10 @@
<Reference Include="System.configuration" /> <Reference Include="System.configuration" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Drawing" /> <Reference Include="System.Drawing" />
<Reference Include="System.Windows.Controls.Input.Toolkit, Version=3.5.40128.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>C:\Program Files (x86)\WPF Toolkit\v3.5.50211.1\System.Windows.Controls.Input.Toolkit.dll</HintPath>
</Reference>
<Reference Include="System.Windows.Forms" /> <Reference Include="System.Windows.Forms" />
<Reference Include="System.Xaml" /> <Reference Include="System.Xaml" />
<Reference Include="System.Xml"> <Reference Include="System.Xml">
...@@ -91,6 +95,7 @@ ...@@ -91,6 +95,7 @@
<Compile Include="Account.cs" /> <Compile Include="Account.cs" />
<Compile Include="Broker.cs" /> <Compile Include="Broker.cs" />
<Compile Include="Call.cs" /> <Compile Include="Call.cs" />
<Compile Include="Controls\OurAutoCompleteBox.cs" />
<Compile Include="Controls\PhonePadButton.xaml.cs"> <Compile Include="Controls\PhonePadButton.xaml.cs">
<DependentUpon>PhonePadButton.xaml</DependentUpon> <DependentUpon>PhonePadButton.xaml</DependentUpon>
</Compile> </Compile>
......
...@@ -6,6 +6,8 @@ using System.IO; ...@@ -6,6 +6,8 @@ using System.IO;
using System.Reflection; using System.Reflection;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using FSClient.Controls;
namespace FSClient { namespace FSClient {
public class ContactPluginManager : IDisposable { public class ContactPluginManager : IDisposable {
private bool IsTypeOf(Type to_check, Type of) { private bool IsTypeOf(Type to_check, Type of) {
...@@ -15,6 +17,9 @@ namespace FSClient { ...@@ -15,6 +17,9 @@ namespace FSClient {
return true; return true;
return IsTypeOf(to_check.BaseType, of); return IsTypeOf(to_check.BaseType, of);
} }
public static IEnumerable<MenuItem> ContactMenuItems { get; set; }
private List<IContactPlugin> plugins = new List<IContactPlugin>(); private List<IContactPlugin> plugins = new List<IContactPlugin>();
public void RegisterPlugin(IContactPlugin plugin) { public void RegisterPlugin(IContactPlugin plugin) {
if (plugins.Count > 0) if (plugins.Count > 0)
...@@ -22,12 +27,23 @@ namespace FSClient { ...@@ -22,12 +27,23 @@ namespace FSClient {
try { try {
plugins.Add(plugin); plugins.Add(plugin);
plugin.Initialize(); plugin.Initialize();
Application.Current.Dispatcher.BeginInvoke((Action)ContactInit);
} catch (Exception e) { } catch (Exception e) {
HandleError(plugin, e); HandleError(plugin, e);
} }
} }
private void ContactInit(){
IContactPlugin plugin = plugins[0];
ContactMenuItems = plugin.ContactRightClickMenu();
OurAutoCompleteBox box = Broker.get_instance().GetContactSearchBox();
if (!plugin.HandleSearchBox(box))
box.Visibility = Visibility.Collapsed;
}
private void HandleError(IContactPlugin plugin, Exception e) { private void HandleError(IContactPlugin plugin, Exception e) {
Utils.PluginLog("Contact Plugin Manager", "Plugin \"" + plugin.ProviderName() + "\" had an error Due to: " + e.Message); Utils.PluginLog("Contact Plugin Manager", "Plugin \"" + plugin.ProviderName() + "\" had an error Due to: " + e.Message);
} }
public ContactPluginManager() { public ContactPluginManager() {
...@@ -142,9 +158,11 @@ namespace FSClient { ...@@ -142,9 +158,11 @@ namespace FSClient {
public abstract void ResolveNumber(String number, NumberResolved on_resolved); public abstract void ResolveNumber(String number, NumberResolved on_resolved);
public abstract void CallRightClickMenu(Call call, ContextMenu menu); public abstract void CallRightClickMenu(Call call, ContextMenu menu);
public abstract IEnumerable<MenuItem> ContactRightClickMenu();
public abstract void Initialize(); public abstract void Initialize();
public abstract void Terminate(); public abstract void Terminate();
public abstract string ProviderName(); public abstract string ProviderName();
public abstract bool HandleSearchBox(OurAutoCompleteBox box);
} }
} }
<Window <Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ours="clr-namespace:FSClient.Controls" xmlns:ours="clr-namespace:FSClient.Controls" xmlns:local="clr-namespace:FSClient" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:Controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit" mc:Ignorable="d" x:Class="FSClient.MainWindow"
xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit" xmlns:local="clr-namespace:FSClient" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="FSClient.MainWindow"
Title="FSClient" Height="319" Width="666" WindowStyle="SingleBorderWindow" ResizeMode="CanMinimize" Closing="Window_Closing" Icon="phone.ico"> Title="FSClient" Height="319" Width="666" WindowStyle="SingleBorderWindow" ResizeMode="CanMinimize" Closing="Window_Closing" Icon="phone.ico">
<Window.Resources> <Window.Resources>
<local:DurationTimeConverter x:Key="DurationTimeConverter"/> <local:DurationTimeConverter x:Key="DurationTimeConverter"/>
...@@ -174,15 +172,27 @@ ...@@ -174,15 +172,27 @@
</StackPanel> </StackPanel>
</Border> </Border>
<Button Content="Options" HorizontalAlignment="Left" x:Name="btnOptions" Width="75" Click="btnOptions_Click" Style="{DynamicResource GlassButtonStyle}" Height="20" Canvas.Left="349" Canvas.Top="266" d:LayoutOverrides="VerticalAlignment" /> <Button Content="Options" HorizontalAlignment="Left" x:Name="btnOptions" Width="50" Click="btnOptions_Click" Style="{DynamicResource GlassButtonStyle}" Height="20" Canvas.Left="374" Canvas.Top="266" d:LayoutOverrides="VerticalAlignment" />
</Canvas> </Canvas>
<Button Canvas.Left="283" Canvas.Top="21" Content="Send To Voicemail" FontWeight="Bold" Foreground="#FFF5E200" Height="20" Name="btnSendVoicemail" Style="{DynamicResource GlassButtonStyle}" Width="120" Visibility="Hidden" Click="btnSendVoicemail_Click" /> <Button Canvas.Left="283" Canvas.Top="21" Content="Send To Voicemail" FontWeight="Bold" Foreground="#FFF5E200" Height="20" Name="btnSendVoicemail" Style="{DynamicResource GlassButtonStyle}" Width="120" Visibility="Hidden" Click="btnSendVoicemail_Click" />
<ours:OurAutoCompleteBox Canvas.Left="435" Text="Contact Search" Canvas.Top="265" Height="22" Width="164.553" Opacity="0.8" x:Name="txtSearchBox" FilterMode="Contains" GotKeyboardFocus="txtSearchBox_GotKeyboardFocus" LostKeyboardFocus="txtSearchBox_LostKeyboardFocus" DropDownClosing="txtSearchBox_DropDownClosing">
<ours:OurAutoCompleteBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}">
<TextBlock.ContextMenu>
<ContextMenu x:Name="contactSearchConextMenu" ItemsSource="{Binding Path=(local:ContactPluginManager.ContactMenuItems)}" IsEnabled="true" Closed="contactSearchConextMenu_Closed" Loaded="contactSearchConextMenu_Loaded" />
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
</ours:OurAutoCompleteBox.ItemTemplate>
</ours:OurAutoCompleteBox>
<Control <Control
x:Name="busyAnimation" x:Name="busyAnimation"
Style="{StaticResource BusyAnimationStyle}" Style="{StaticResource BusyAnimationStyle}"
Width="{Binding Path=ActualWidth, ElementName=mainControl}" Width="{Binding Path=ActualWidth, ElementName=mainControl}"
Height="{Binding Path=ActualHeight, ElementName=mainControl}" Height="{Binding Path=ActualHeight, ElementName=mainControl}" d:IsHidden="True"
/> />
</Canvas> </Canvas>
</Window> </Window>
...@@ -4,6 +4,8 @@ using System.Windows; ...@@ -4,6 +4,8 @@ using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using FSClient.Controls;
namespace FSClient { namespace FSClient {
public partial class MainWindow : Window { public partial class MainWindow : Window {
private Broker broker; private Broker broker;
...@@ -56,16 +58,12 @@ namespace FSClient { ...@@ -56,16 +58,12 @@ namespace FSClient {
void gridCalls_LoadingRow(object sender, DataGridRowEventArgs e) { void gridCalls_LoadingRow(object sender, DataGridRowEventArgs e) {
e.Row.SetResourceReference(ToolTipProperty, "mainCallTooltip"); e.Row.SetResourceReference(ToolTipProperty, "mainCallTooltip");
last_tip = e.Row.ToolTip as ToolTip;
Call c = e.Row.DataContext as Call; Call c = e.Row.DataContext as Call;
last_row = e.Row;
if (c == null) if (c == null)
return; return;
e.Row.ContextMenu = c.CallRightClickMenu(); e.Row.ContextMenu = c.CallRightClickMenu();
} }
private ToolTip last_tip;
private DataGridRow last_row;
public void SetDialStr(string str) { public void SetDialStr(string str) {
Dispatcher.BeginInvoke((Action)(() => { Dispatcher.BeginInvoke((Action)(() => {
txtNumber.Text = str; txtNumber.Text = str;
...@@ -109,7 +107,7 @@ namespace FSClient { ...@@ -109,7 +107,7 @@ namespace FSClient {
private TEXT_INPUT_MODE text_mode = TEXT_INPUT_MODE.NUMBERS_ONLY; private TEXT_INPUT_MODE text_mode = TEXT_INPUT_MODE.NUMBERS_ONLY;
private void simple_text_mode_char_convert(char c) { private void simple_text_mode_char_convert(char c) {
if (c == '*' || c == '#' || (c >= '0' && c <= '9')){ if (c == '*' || c == '#' || (c >= '0' && c <= '9')) {
broker.handle_key_action(c); broker.handle_key_action(c);
return; return;
} }
...@@ -158,13 +156,19 @@ namespace FSClient { ...@@ -158,13 +156,19 @@ namespace FSClient {
break; break;
} }
} }
private bool text_interception_enabled = true;
void MainWindow_PreviewTextInput(object sender, TextCompositionEventArgs e) { void MainWindow_PreviewTextInput(object sender, TextCompositionEventArgs e) {
if (!broker.fully_loaded) if (!broker.fully_loaded)
return; return;
if (!text_interception_enabled) {
e.Handled = false;
return;
}
char[] chars = e.Text.ToCharArray(); char[] chars = e.Text.ToCharArray();
char[] sys_chars = e.ControlText.ToCharArray(); char[] sys_chars = e.ControlText.ToCharArray();
foreach (Char c in sys_chars) { foreach (Char c in sys_chars) {
if (c == 22) //paste if (c == 22) //paste / control + v
{ {
String clipboard = Clipboard.GetText(); String clipboard = Clipboard.GetText();
char[] tmp = new char[chars.Length + clipboard.Length]; char[] tmp = new char[chars.Length + clipboard.Length];
...@@ -172,13 +176,16 @@ namespace FSClient { ...@@ -172,13 +176,16 @@ namespace FSClient {
clipboard.ToCharArray().CopyTo(tmp, chars.Length); clipboard.ToCharArray().CopyTo(tmp, chars.Length);
chars = tmp; chars = tmp;
} }
else if (c == 6){ // control + f
txtSearchBox.TextBoxFocus();
}
} }
e.Handled = false; e.Handled = false;
foreach (Char c in chars) { foreach (Char c in chars) {
bool handled = true; bool handled = true;
if (c > 32 && c < 127) { if (c > 32 && c < 127) {
if (text_mode == TEXT_INPUT_MODE.NUMBERS_ONLY || (Call.active_call != null && Call.active_call.state == Call.CALL_STATE.Answered) ) if (text_mode == TEXT_INPUT_MODE.NUMBERS_ONLY || (Call.active_call != null && Call.active_call.state == Call.CALL_STATE.Answered))
simple_text_mode_char_convert(c); simple_text_mode_char_convert(c);
else else
broker.handle_key_action(c); broker.handle_key_action(c);
...@@ -199,8 +206,12 @@ namespace FSClient { ...@@ -199,8 +206,12 @@ namespace FSClient {
void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e) { void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e) {
if (!broker.fully_loaded) if (!broker.fully_loaded)
return; return;
if (!text_interception_enabled) {
e.Handled = false;
return;
}
if (e.Key == Key.Return){ if (e.Key == Key.Return) {
broker.handle_special_action(Broker.KEYBOARD_ACTION.Enter); broker.handle_special_action(Broker.KEYBOARD_ACTION.Enter);
e.Handled = true; e.Handled = true;
} }
...@@ -225,10 +236,12 @@ namespace FSClient { ...@@ -225,10 +236,12 @@ namespace FSClient {
void MainWindow_Loaded(object sender, RoutedEventArgs e) { void MainWindow_Loaded(object sender, RoutedEventArgs e) {
PreviewTextInput += MainWindow_PreviewTextInput; PreviewTextInput += MainWindow_PreviewTextInput;
PreviewKeyDown += MainWindow_PreviewKeyDown; //return must be handled seperately as buttons are triggered on down it seems PreviewKeyDown += MainWindow_PreviewKeyDown; //return must be handled seperately as buttons are triggered on down it seems
MouseUp += MainWindow_MouseUp;
Call.CallStateChanged += CallStateChanged; Call.CallStateChanged += CallStateChanged;
Call.ActiveCallChanged += ActiveCallChanged; Call.ActiveCallChanged += ActiveCallChanged;
Account.accounts.CollectionChanged += accounts_CollectionChanged; Account.accounts.CollectionChanged += accounts_CollectionChanged;
Broker.FreeswitchLoaded += new EventHandler<EventArgs>(FreeswitchLoaded); Broker.FreeswitchLoaded += FreeswitchLoaded;
broker = Broker.get_instance(); broker = Broker.get_instance();
broker.cur_dial_strChanged += DialStrChanged; broker.cur_dial_strChanged += DialStrChanged;
...@@ -244,16 +257,32 @@ namespace FSClient { ...@@ -244,16 +257,32 @@ namespace FSClient {
Windows.systray_icon_setup(); Windows.systray_icon_setup();
} }
private void FreeswitchLoaded(object sender, EventArgs e){ void MainWindow_MouseUp(object sender, MouseButtonEventArgs e) {
Dispatcher.BeginInvoke((Action)(() => if (txtSearchBox.TextBoxHasFocus()){
{ DependencyObject parent = e.OriginalSource as UIElement;
while (parent != null && !(parent is OurAutoCompleteBox))
parent = VisualTreeHelper.GetParent(parent);
if (parent == null)
RemoveFocus();
}
}
public void RemoveFocus(){
btnMute.Focus(); //should really divert focus a better way
}
private void FreeswitchLoaded(object sender, EventArgs e) {
Dispatcher.BeginInvoke((Action)(() => {
busyAnimation.Visibility = Visibility.Hidden; busyAnimation.Visibility = Visibility.Hidden;
})); }));
} }
private void UseNumberOnlyInputChanged(object sender, bool data){ private void UseNumberOnlyInputChanged(object sender, bool data) {
text_mode = broker.UseNumberOnlyInput ? TEXT_INPUT_MODE.NUMBERS_ONLY : TEXT_INPUT_MODE.FULL; text_mode = broker.UseNumberOnlyInput ? TEXT_INPUT_MODE.NUMBERS_ONLY : TEXT_INPUT_MODE.FULL;
} }
...@@ -319,11 +348,11 @@ namespace FSClient { ...@@ -319,11 +348,11 @@ namespace FSClient {
} }
private void Window_Closing(object sender, CancelEventArgs e) { private void Window_Closing(object sender, CancelEventArgs e) {
try{ try {
Windows.systray_icon_remove(); Windows.systray_icon_remove();
broker.Dispose(); broker.Dispose();
} }
catch { } catch{ }
} }
private void btnSpeaker_Click(object sender, RoutedEventArgs e) { private void btnSpeaker_Click(object sender, RoutedEventArgs e) {
...@@ -368,7 +397,7 @@ namespace FSClient { ...@@ -368,7 +397,7 @@ namespace FSClient {
Button btn = sender as Button; Button btn = sender as Button;
if (btn != null) if (btn != null)
broker.handle_key_action(btn.Content.ToString()[0]); broker.handle_key_action(btn.Content.ToString()[0]);
Controls.PhonePadButton btn2 = sender as Controls.PhonePadButton; PhonePadButton btn2 = sender as PhonePadButton;
if (btn2 != null) if (btn2 != null)
broker.handle_key_action(btn2.Number[0]); broker.handle_key_action(btn2.Number[0]);
...@@ -390,7 +419,40 @@ namespace FSClient { ...@@ -390,7 +419,40 @@ namespace FSClient {
} }
#region ContactSearchBox
public OurAutoCompleteBox GetContactSearchBox() {
return txtSearchBox;
}
private void txtSearchBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) {
text_interception_enabled = false;
txtSearchBox.Opacity = 1;
if (txtSearchBox.Text == "Contact Search")
txtSearchBox.Text = "";
}
private void txtSearchBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) {
text_interception_enabled = true;
txtSearchBox.Opacity = 0.8;
if (String.IsNullOrWhiteSpace(txtSearchBox.Text))
txtSearchBox.Text = "Contact Search";
}
private bool ContactMenuOpen;
private void contactSearchConextMenu_Closed(object sender, RoutedEventArgs e) {
ContactMenuOpen = false;
txtSearchBox.IsDropDownOpen = false;
}
private void contactSearchConextMenu_Loaded(object sender, RoutedEventArgs e) {
ContactMenuOpen = true;
}
private void txtSearchBox_DropDownClosing(object sender, RoutedPropertyChangingEventArgs<bool> e) {
if (ContactMenuOpen)
e.Cancel = true;
}
#endregion
} }
} }
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input;
using FSClient.Controls;
namespace FSClient namespace FSClient
{ {
...@@ -40,16 +44,55 @@ namespace FSClient ...@@ -40,16 +44,55 @@ namespace FSClient
ModifyRightClickMenu(call, menu); ModifyRightClickMenu(call, menu);
} }
protected void item_Click(object sender, System.Windows.RoutedEventArgs e) public override IEnumerable<MenuItem> ContactRightClickMenu(){
List<MenuItem> items = new List<MenuItem>();
MenuItem item = new MenuItem();
item.Click += item_Click;
item.Header = "Edit Contact";
items.Add(item);
item = new MenuItem();
item.Click +=contact_call_click;
item.Header = "Call";
items.Add(item);
return items;
}
private void contact_call_click(object sender, RoutedEventArgs e){
MenuItem item = sender as MenuItem;
if (item == null)
return;
SearchAutoCompleteEntry entry = item.DataContext as SearchAutoCompleteEntry ?? search_box.SelectedItem as SearchAutoCompleteEntry;
if (entry == null)
return;
Broker.get_instance().DialString(entry.number);
}
protected void item_Click(object sender, RoutedEventArgs e)
{ {
MenuItem item = sender as MenuItem; MenuItem item = sender as MenuItem;
if (item == null) if (item == null)
return; return;
String number;
String default_edit_value;
Call c = item.DataContext as Call; Call c = item.DataContext as Call;
if (c == null) if (c != null){
number = c.other_party_number;
default_edit_value = DefaultEditValue(c);
}
else{
SearchAutoCompleteEntry entry = item.DataContext as SearchAutoCompleteEntry ?? search_box.SelectedItem as SearchAutoCompleteEntry;
if (entry == null)
return; return;
String number = NormalizeNumber(c.other_party_number); number = entry.number;
String alias = InputBox.GetInput("Editing Contact", "Edit alias for number: " + number, DefaultEditValue(c)); default_edit_value = entry.alias;
}
String orig_number = number;
number = NormalizeNumber(number);
String alias = InputBox.GetInput("Editing Contact", "Edit alias for number: " + number, default_edit_value);
alias = IsValidAlias(alias); alias = IsValidAlias(alias);
if (alias == null) if (alias == null)
return; return;
...@@ -58,11 +101,12 @@ namespace FSClient ...@@ -58,11 +101,12 @@ namespace FSClient
foreach (Call call in Call.calls) foreach (Call call in Call.calls)
{ {
if (c.other_party_number == call.other_party_number) if (orig_number == call.other_party_number || number == call.other_party_number)
c.other_party_name = alias; call.other_party_name = alias;
} }
UpdateDatabase(number, alias); UpdateDatabase(number, alias);
refresh_search_box();
} }
public override void ResolveNumber(string number, NumberResolved on_resolved) public override void ResolveNumber(string number, NumberResolved on_resolved)
{ {
...@@ -79,7 +123,68 @@ namespace FSClient ...@@ -79,7 +123,68 @@ namespace FSClient
{ {
LoadDatabase(ref number_to_alias); LoadDatabase(ref number_to_alias);
refresh_search_box();
}
protected void refresh_search_box(){
if (search_box == null)
return;
search_box.ItemsSource = from c in number_to_alias select new SearchAutoCompleteEntry(c.Key,c.Value);
}
protected class SearchAutoCompleteEntry{
public string number;
public string alias;
public string display_name;
public SearchAutoCompleteEntry(String number, String alias){
this.number = number;
this.alias = alias;
if (String.IsNullOrWhiteSpace(alias) || number == alias)
display_name = number;
else
display_name = alias + " - " + number;
}
public override string ToString(){
return display_name;
} }
}
protected void search_box_PreviewKeyUp(object sender, KeyEventArgs e){
if (e.Key == Key.Enter){
call_current_contact();
}
}
protected OurAutoCompleteBox search_box;
private TextBox real_search_box;
public override bool HandleSearchBox(OurAutoCompleteBox box) {
search_box = box;
real_search_box = search_box.GetActualTextbox();
real_search_box.ContextMenu = new ContextMenu();
real_search_box.ContextMenuOpening += search_box_ContextMenuOpening;
foreach (MenuItem item in ContactRightClickMenu()){
real_search_box.ContextMenu.Items.Add(item);
}
search_box.PreviewKeyUp += search_box_PreviewKeyUp;
search_box.MouseDoubleClick += search_box_MouseDoubleClick;
if (number_to_alias.Count > 0)
refresh_search_box();
return true;
}
protected void call_current_contact(){
SearchAutoCompleteEntry entry = search_box.SelectedItem as SearchAutoCompleteEntry;
if (entry != null)
Broker.get_instance().DialString(entry.number);
}
void search_box_MouseDoubleClick(object sender, MouseButtonEventArgs e){
call_current_contact();
}
void search_box_ContextMenuOpening(object sender, ContextMenuEventArgs e){
if (search_box.SelectedItem == null)
real_search_box.ContextMenu.Visibility = Visibility.Hidden;
else
real_search_box.ContextMenu.Visibility = Visibility.Visible;
}
} }
} }
Markdown 格式
0% 或
您添加了 0 人 到此讨论。请谨慎行事。
请先完成此评论的编辑!
请 注册 或者 后发表评论