diff --git a/AudioLibrary.PjSIP/AudioDevice.cs b/AudioLibrary.PjSIP/AudioDevice.cs index fb20969..6c4a1a7 100644 --- a/AudioLibrary.PjSIP/AudioDevice.cs +++ b/AudioLibrary.PjSIP/AudioDevice.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System; using AudioLibrary.Interfaces; using AudioLibrary.PjSIP.ManagedWatcher; @@ -15,8 +12,9 @@ internal class AudioDevice : IAudioDevice public event Action MuteChanged; internal int Index { get; private set; } + public Audio Audio { get; private set; } - public string Name { get; set; } + public string Name { get; private set; } public bool PlaybackSupport { get; private set; } public bool RecordingSupport { get; private set; } @@ -38,13 +36,19 @@ public int Volume { if (PlaybackSupport) Audio.SpeakerVolume = value; else Audio.MicVolume = value; + + VolumeChanged?.Invoke(this); } } public bool Mute { get { return Audio.MicMute; } - set { Audio.MicMute = value; } + set + { + Audio.MicMute = value; + MuteChanged?.Invoke(this); + } } internal AudioDevice(Audio audio, Imports.PjAudioDeviceInfo audioDeviceInfo, int index) diff --git a/AudioLibrary.WMME/AudioLibrary.WMME.csproj b/AudioLibrary.WMME/AudioLibrary.WMME.csproj index 89f5650..8e5722d 100644 --- a/AudioLibrary.WMME/AudioLibrary.WMME.csproj +++ b/AudioLibrary.WMME/AudioLibrary.WMME.csproj @@ -28,6 +28,7 @@ true AnyCPU false + 3009,3003,3001 pdbonly @@ -40,6 +41,7 @@ true AnyCPU false + 3009,3003 false @@ -72,6 +74,9 @@ + + + diff --git a/AudioLibrary.WMME/AudioLine.cs b/AudioLibrary.WMME/AudioLine.cs index 02108b2..0d61d73 100644 --- a/AudioLibrary.WMME/AudioLine.cs +++ b/AudioLibrary.WMME/AudioLine.cs @@ -1,8 +1,9 @@ -using System; +using System; using System.Collections.Generic; using AudioLibrary.Interfaces; using System.Runtime.InteropServices; using AudioLibrary.WMME.Native; +using System.Diagnostics; namespace AudioLibrary.WMME { @@ -284,7 +285,7 @@ private void SetVolumeOnChannel(Channel channel, int newVolume) } catch (Exception e) { - // TODO: Log error + Trace.TraceError("Unable to set volume on channel {0} #{1}: {2}", Name, Id, e.Message); } } @@ -329,7 +330,7 @@ internal void ReloadValues() } catch (Exception e) { - // TODO: log error + Trace.TraceError("Unable to reload values on audio line {0} #{1}: {2}", Name, Id, e.Message); } RaiseVolumeChangedEvent(this); diff --git a/AudioLibrary.WMME/AudioPlayer.cs b/AudioLibrary.WMME/AudioPlayer.cs index 91e3c7d..87ee109 100644 --- a/AudioLibrary.WMME/AudioPlayer.cs +++ b/AudioLibrary.WMME/AudioPlayer.cs @@ -1,8 +1,6 @@ -using System; -using System.Runtime.InteropServices; +using System; using System.IO; using AudioLibrary.Interfaces; -using System.Threading; using AudioLibrary.WMME.Native; namespace AudioLibrary.WMME @@ -25,15 +23,18 @@ public void Play(string fileName) try { - WaveStream stream = new WaveStream(fileName); - if (stream.Length <= 0) - throw new Exception("Invalid WAV file"); + using (var fileStream = new FileStream(fileName, FileMode.Open)) + using (var stream = new WaveStream(fileStream)) + { + if (stream.Length <= 0) + throw new Exception("Invalid WAV file"); - _format = stream.Format; - if (_format.formatTag != WaveFormatTag.PCM && _format.formatTag != WaveFormatTag.IEEE_FLOAT) - throw new Exception("Olny PCM files are supported"); + _format = stream.Format; + if (_format.formatTag != WaveFormatTag.PCM && _format.formatTag != WaveFormatTag.IEEE_FLOAT) + throw new Exception("Olny PCM files are supported"); - _stream = stream; + _stream = stream; + } } catch { @@ -105,385 +106,4 @@ public void Dispose() } internal delegate void BufferFillEventHandler(IntPtr data, int size); - - internal class WaveOut - { - private IntPtr m_WaveOut; - private WaveOutBuffer m_Buffers; // linked list - private WaveOutBuffer m_CurrentBuffer; - private Thread m_Thread; - private BufferFillEventHandler m_FillProc; - private bool m_Finished; - private byte m_zero; - - private WaveNative.WaveDelegate m_BufferProc = new WaveNative.WaveDelegate(WaveOutBuffer.WaveOutProc); - - public WaveOut(int device, WAVEFORMATEX format, int bufferSize, int bufferCount, BufferFillEventHandler fillProc) - { - m_zero = format.wBitsPerSample == 8 ? (byte)128 : (byte)0; - m_FillProc = fillProc; - - var errorCode = (MMErrors)WaveNative.waveOutOpen(out m_WaveOut, device, ref format, m_BufferProc, 0, (int)CallBackFlag.CALLBACK_FUNCTION); - if (errorCode != MMErrors.MMSYSERR_NOERROR) - throw new MixerException(errorCode, Audio.GetErrorDescription(FuncName.fnWaveOutOpen, errorCode)); - - AllocateBuffers(bufferSize, bufferCount); - m_Thread = new Thread(new ThreadStart(ThreadProc)); - m_Thread.Start(); - } - - ~WaveOut() - { - Dispose(); - } - - public void Dispose() - { - if (m_Thread != null) - try - { - m_Finished = true; - if (m_WaveOut != IntPtr.Zero) - WaveNative.waveOutReset(m_WaveOut); - m_Thread.Join(); - m_FillProc = null; - FreeBuffers(); - if (m_WaveOut != IntPtr.Zero) - WaveNative.waveOutClose(m_WaveOut); - } - finally - { - m_Thread = null; - m_WaveOut = IntPtr.Zero; - } - GC.SuppressFinalize(this); - } - - private void ThreadProc() - { - while (!m_Finished) - { - Advance(); - if (m_FillProc != null && !m_Finished) - m_FillProc(m_CurrentBuffer.Data, m_CurrentBuffer.Size); - else - { - // zero out buffer - byte v = m_zero; - byte[] b = new byte[m_CurrentBuffer.Size]; - for (int i = 0; i < b.Length; i++) - b[i] = v; - Marshal.Copy(b, 0, m_CurrentBuffer.Data, b.Length); - - } - m_CurrentBuffer.Play(); - } - WaitForAllBuffers(); - } - - #region Buffers - - private void AllocateBuffers(int bufferSize, int bufferCount) - { - FreeBuffers(); - if (bufferCount > 0) - { - m_Buffers = new WaveOutBuffer(m_WaveOut, bufferSize); - WaveOutBuffer Prev = m_Buffers; - try - { - for (int i = 1; i < bufferCount; i++) - { - WaveOutBuffer Buf = new WaveOutBuffer(m_WaveOut, bufferSize); - Prev.NextBuffer = Buf; - Prev = Buf; - } - } - finally - { - Prev.NextBuffer = m_Buffers; - } - } - } - - private void FreeBuffers() - { - m_CurrentBuffer = null; - if (m_Buffers != null) - { - WaveOutBuffer First = m_Buffers; - m_Buffers = null; - - WaveOutBuffer Current = First; - do - { - WaveOutBuffer Next = Current.NextBuffer; - Current.Dispose(); - Current = Next; - } while(Current != First); - } - } - - private void Advance() - { - m_CurrentBuffer = m_CurrentBuffer == null ? m_Buffers : m_CurrentBuffer.NextBuffer; - m_CurrentBuffer.WaitFor(); - } - - private void WaitForAllBuffers() - { - WaveOutBuffer Buf = m_Buffers; - while (Buf.NextBuffer != m_Buffers) - { - Buf.WaitFor(); - Buf = Buf.NextBuffer; - } - } - - #endregion - } - - internal class WaveOutBuffer : IDisposable - { - public WaveOutBuffer NextBuffer; - - private AutoResetEvent m_PlayEvent = new AutoResetEvent(false); - private IntPtr m_WaveOut; - - private WAVEHDR m_Header; - private byte[] m_HeaderData; - private GCHandle m_HeaderHandle; - private GCHandle m_HeaderDataHandle; - - private bool m_Playing; - - internal static void WaveOutProc(IntPtr hdrvr, int uMsg, int dwUser, ref WAVEHDR wavhdr, int dwParam2) - { - if (uMsg == WaveNative.MM_WOM_DONE) - { - try - { - GCHandle h = (GCHandle)wavhdr.dwUser; - WaveOutBuffer buf = (WaveOutBuffer)h.Target; - buf.OnCompleted(); - } - catch - { } - } - } - - public WaveOutBuffer(IntPtr waveOutHandle, int size) - { - m_WaveOut = waveOutHandle; - - m_HeaderHandle = GCHandle.Alloc(m_Header, GCHandleType.Pinned); - m_Header.dwUser = (IntPtr)GCHandle.Alloc(this); - m_HeaderData = new byte[size]; - m_HeaderDataHandle = GCHandle.Alloc(m_HeaderData, GCHandleType.Pinned); - m_Header.lpData = m_HeaderDataHandle.AddrOfPinnedObject(); - m_Header.dwBufferLength = size; - - var errorCode = (MMErrors)WaveNative.waveOutPrepareHeader(m_WaveOut, ref m_Header, Marshal.SizeOf(m_Header)); - if (errorCode != MMErrors.MMSYSERR_NOERROR) - throw new MixerException(errorCode, Audio.GetErrorDescription(FuncName.fnCustom, errorCode)); - } - ~WaveOutBuffer() - { - Dispose(); - } - public void Dispose() - { - if (m_Header.lpData != IntPtr.Zero) - { - WaveNative.waveOutUnprepareHeader(m_WaveOut, ref m_Header, Marshal.SizeOf(m_Header)); - m_HeaderHandle.Free(); - m_Header.lpData = IntPtr.Zero; - } - m_PlayEvent.Close(); - if (m_HeaderDataHandle.IsAllocated) - m_HeaderDataHandle.Free(); - GC.SuppressFinalize(this); - } - - public int Size - { - get { return m_Header.dwBufferLength; } - } - - public IntPtr Data - { - get { return m_Header.lpData; } - } - - public bool Play() - { - lock (this) - { - m_PlayEvent.Reset(); - m_Playing = (MMErrors)WaveNative.waveOutWrite(m_WaveOut, ref m_Header, Marshal.SizeOf(m_Header)) == MMErrors.MMSYSERR_NOERROR; - return m_Playing; - } - } - public void WaitFor() - { - if (m_Playing) - { - m_Playing = m_PlayEvent.WaitOne(); - } - else - { - Thread.Sleep(0); - } - } - public void OnCompleted() - { - m_PlayEvent.Set(); - m_Playing = false; - } - } - - internal class WaveStream : Stream, IDisposable - { - private Stream m_Stream; - private long m_DataPos; - private long m_Length; - - private WAVEFORMATEX m_Format; - - public WAVEFORMATEX Format - { - get { return m_Format; } - } - - private string ReadChunk(BinaryReader reader) - { - byte[] ch = new byte[4]; - reader.Read(ch, 0, ch.Length); - return System.Text.Encoding.ASCII.GetString(ch); - } - - private void ReadHeader() - { - BinaryReader Reader = new BinaryReader(m_Stream); - if (ReadChunk(Reader) != "RIFF") - throw new Exception("Invalid file format"); - - Reader.ReadInt32(); // File length minus first 8 bytes of RIFF description, we don't use it - - if (ReadChunk(Reader) != "WAVE") - throw new Exception("Invalid file format"); - - if (ReadChunk(Reader) != "fmt ") - throw new Exception("Invalid file format"); - - int len = Reader.ReadInt32(); - if (len < 16) // bad format chunk length - throw new Exception("Invalid file format"); - - m_Format = new WAVEFORMATEX(22050, 16, 2); // initialize to any format - m_Format.formatTag = (WaveFormatTag)Reader.ReadInt16(); - m_Format.nChannels = Reader.ReadInt16(); - m_Format.nSamplesPerSec = Reader.ReadInt32(); - m_Format.nAvgBytesPerSec = Reader.ReadInt32(); - m_Format.nBlockAlign = Reader.ReadInt16(); - m_Format.wBitsPerSample = Reader.ReadInt16(); - - // advance in the stream to skip the wave format block - len -= 16; // minimum format size - while (len > 0) - { - Reader.ReadByte(); - len--; - } - - // assume the data chunk is aligned - while(m_Stream.Position < m_Stream.Length && ReadChunk(Reader) != "data") - ; - - if (m_Stream.Position >= m_Stream.Length) - throw new Exception("Invalid file format"); - - m_Length = Reader.ReadInt32(); - m_DataPos = m_Stream.Position; - - Position = 0; - } - - public WaveStream(string fileName) : this(new FileStream(fileName, FileMode.Open)) - { - } - public WaveStream(Stream S) - { - m_Stream = S; - ReadHeader(); - } - ~WaveStream() - { - Dispose(); - } - public void Dispose() - { - if (m_Stream != null) - m_Stream.Close(); - GC.SuppressFinalize(this); - } - - public override bool CanRead - { - get { return true; } - } - public override bool CanSeek - { - get { return true; } - } - public override bool CanWrite - { - get { return false; } - } - public override long Length - { - get { return m_Length; } - } - public override long Position - { - get { return m_Stream.Position - m_DataPos; } - set { Seek(value, SeekOrigin.Begin); } - } - public override void Close() - { - Dispose(); - } - public override void Flush() - { - } - public override void SetLength(long len) - { - throw new InvalidOperationException(); - } - public override long Seek(long pos, SeekOrigin o) - { - switch(o) - { - case SeekOrigin.Begin: - m_Stream.Position = pos + m_DataPos; - break; - case SeekOrigin.Current: - m_Stream.Seek(pos, SeekOrigin.Current); - break; - case SeekOrigin.End: - m_Stream.Position = m_DataPos + m_Length - pos; - break; - } - return this.Position; - } - public override int Read(byte[] buf, int ofs, int count) - { - int toread = (int)Math.Min(count, m_Length - Position); - return m_Stream.Read(buf, ofs, toread); - } - public override void Write(byte[] buf, int ofs, int count) - { - throw new InvalidOperationException(); - } - } } diff --git a/AudioLibrary.WMME/WaveOut.cs b/AudioLibrary.WMME/WaveOut.cs new file mode 100644 index 0000000..1caceb8 --- /dev/null +++ b/AudioLibrary.WMME/WaveOut.cs @@ -0,0 +1,144 @@ +using System; +using System.Runtime.InteropServices; +using System.Threading; +using AudioLibrary.WMME.Native; + +namespace AudioLibrary.WMME +{ + internal class WaveOut : IDisposable + { + private IntPtr m_WaveOut; + private WaveOutBuffer m_Buffers; // linked list + private WaveOutBuffer m_CurrentBuffer; + private Thread m_Thread; + private BufferFillEventHandler m_FillProc; + private bool m_Finished; + private byte m_zero; + + private WaveNative.WaveDelegate m_BufferProc = new WaveNative.WaveDelegate(WaveOutBuffer.WaveOutProc); + + public WaveOut(int device, WAVEFORMATEX format, int bufferSize, int bufferCount, BufferFillEventHandler fillProc) + { + m_zero = format.wBitsPerSample == 8 ? (byte)128 : (byte)0; + m_FillProc = fillProc; + + var errorCode = (MMErrors)WaveNative.waveOutOpen(out m_WaveOut, device, ref format, m_BufferProc, 0, (int)CallBackFlag.CALLBACK_FUNCTION); + if (errorCode != MMErrors.MMSYSERR_NOERROR) + throw new MixerException(errorCode, Audio.GetErrorDescription(FuncName.fnWaveOutOpen, errorCode)); + + AllocateBuffers(bufferSize, bufferCount); + m_Thread = new Thread(new ThreadStart(ThreadProc)); + m_Thread.Start(); + } + + ~WaveOut() + { + Dispose(); + } + + public void Dispose() + { + if (m_Thread != null) + try + { + m_Finished = true; + if (m_WaveOut != IntPtr.Zero) + WaveNative.waveOutReset(m_WaveOut); + m_Thread.Join(); + m_FillProc = null; + FreeBuffers(); + if (m_WaveOut != IntPtr.Zero) + WaveNative.waveOutClose(m_WaveOut); + } + finally + { + m_Thread = null; + m_WaveOut = IntPtr.Zero; + } + GC.SuppressFinalize(this); + } + + private void ThreadProc() + { + while (!m_Finished) + { + Advance(); + if (m_FillProc != null && !m_Finished) + m_FillProc(m_CurrentBuffer.Data, m_CurrentBuffer.Size); + else + { + // zero out buffer + byte v = m_zero; + byte[] b = new byte[m_CurrentBuffer.Size]; + for (int i = 0; i < b.Length; i++) + b[i] = v; + Marshal.Copy(b, 0, m_CurrentBuffer.Data, b.Length); + + } + m_CurrentBuffer.Play(); + } + WaitForAllBuffers(); + } + + #region Buffers + + private void AllocateBuffers(int bufferSize, int bufferCount) + { + FreeBuffers(); + if (bufferCount > 0) + { + m_Buffers = new WaveOutBuffer(m_WaveOut, bufferSize); + WaveOutBuffer Prev = m_Buffers; + try + { + for (int i = 1; i < bufferCount; i++) + { + WaveOutBuffer Buf = new WaveOutBuffer(m_WaveOut, bufferSize); + Prev.NextBuffer = Buf; + Prev = Buf; + } + } + finally + { + Prev.NextBuffer = m_Buffers; + } + } + } + + private void FreeBuffers() + { + m_CurrentBuffer = null; + if (m_Buffers != null) + { + WaveOutBuffer First = m_Buffers; + m_Buffers = null; + + WaveOutBuffer Current = First; + do + { + WaveOutBuffer Next = Current.NextBuffer; + Current.Dispose(); + Current = Next; + } while(Current != First); + } + } + + private void Advance() + { + m_CurrentBuffer = m_CurrentBuffer == null ? m_Buffers : m_CurrentBuffer.NextBuffer; + m_CurrentBuffer.WaitFor(); + } + + private void WaitForAllBuffers() + { + WaveOutBuffer Buf = m_Buffers; + while (Buf.NextBuffer != m_Buffers) + { + Buf.WaitFor(); + Buf = Buf.NextBuffer; + } + } + + #endregion + } +} diff --git a/AudioLibrary.WMME/WaveOutBuffer.cs b/AudioLibrary.WMME/WaveOutBuffer.cs new file mode 100644 index 0000000..a67baa1 --- /dev/null +++ b/AudioLibrary.WMME/WaveOutBuffer.cs @@ -0,0 +1,108 @@ +using System; +using System.Runtime.InteropServices; +using System.Threading; +using AudioLibrary.WMME.Native; + +namespace AudioLibrary.WMME +{ + internal class WaveOutBuffer : IDisposable + { + private readonly object _lockObj = new object(); + + public WaveOutBuffer NextBuffer; + + private AutoResetEvent m_PlayEvent = new AutoResetEvent(false); + private IntPtr m_WaveOut; + + private WAVEHDR m_Header; + private byte[] m_HeaderData; + private GCHandle m_HeaderHandle; + private GCHandle m_HeaderDataHandle; + + private bool m_Playing; + + internal static void WaveOutProc(IntPtr hdrvr, int uMsg, int dwUser, ref WAVEHDR wavhdr, int dwParam2) + { + if (uMsg == WaveNative.MM_WOM_DONE) + { + try + { + GCHandle h = (GCHandle)wavhdr.dwUser; + WaveOutBuffer buf = (WaveOutBuffer)h.Target; + buf.OnCompleted(); + } + catch + { } + } + } + + public WaveOutBuffer(IntPtr waveOutHandle, int size) + { + m_WaveOut = waveOutHandle; + + m_HeaderHandle = GCHandle.Alloc(m_Header, GCHandleType.Pinned); + m_Header.dwUser = (IntPtr)GCHandle.Alloc(this); + m_HeaderData = new byte[size]; + m_HeaderDataHandle = GCHandle.Alloc(m_HeaderData, GCHandleType.Pinned); + m_Header.lpData = m_HeaderDataHandle.AddrOfPinnedObject(); + m_Header.dwBufferLength = size; + + var errorCode = (MMErrors)WaveNative.waveOutPrepareHeader(m_WaveOut, ref m_Header, Marshal.SizeOf(m_Header)); + if (errorCode != MMErrors.MMSYSERR_NOERROR) + throw new MixerException(errorCode, Audio.GetErrorDescription(FuncName.fnCustom, errorCode)); + } + ~WaveOutBuffer() + { + Dispose(); + } + public void Dispose() + { + if (m_Header.lpData != IntPtr.Zero) + { + WaveNative.waveOutUnprepareHeader(m_WaveOut, ref m_Header, Marshal.SizeOf(m_Header)); + m_HeaderHandle.Free(); + m_Header.lpData = IntPtr.Zero; + } + m_PlayEvent.Close(); + if (m_HeaderDataHandle.IsAllocated) + m_HeaderDataHandle.Free(); + GC.SuppressFinalize(this); + } + + public int Size + { + get { return m_Header.dwBufferLength; } + } + + public IntPtr Data + { + get { return m_Header.lpData; } + } + + public bool Play() + { + lock (_lockObj) + { + m_PlayEvent.Reset(); + m_Playing = (MMErrors)WaveNative.waveOutWrite(m_WaveOut, ref m_Header, Marshal.SizeOf(m_Header)) == MMErrors.MMSYSERR_NOERROR; + return m_Playing; + } + } + public void WaitFor() + { + if (m_Playing) + { + m_Playing = m_PlayEvent.WaitOne(); + } + else + { + Thread.Sleep(0); + } + } + public void OnCompleted() + { + m_PlayEvent.Set(); + m_Playing = false; + } + } +} diff --git a/AudioLibrary.WMME/WaveStream.cs b/AudioLibrary.WMME/WaveStream.cs new file mode 100644 index 0000000..74eb4ed --- /dev/null +++ b/AudioLibrary.WMME/WaveStream.cs @@ -0,0 +1,127 @@ +using System; +using System.IO; +using AudioLibrary.WMME.Native; + +namespace AudioLibrary.WMME +{ + internal class WaveStream : Stream, IDisposable + { + private Stream m_Stream; + private long m_DataPos; + private long m_Length; + + public WAVEFORMATEX Format { get; private set; } + + private string ReadChunk(BinaryReader reader) + { + byte[] ch = new byte[4]; + reader.Read(ch, 0, ch.Length); + return System.Text.Encoding.ASCII.GetString(ch); + } + + private void ReadHeader() + { + BinaryReader Reader = new BinaryReader(m_Stream); + if (ReadChunk(Reader) != "RIFF") + throw new Exception("Invalid file format"); + + Reader.ReadInt32(); // File length minus first 8 bytes of RIFF description, we don't use it + + if (ReadChunk(Reader) != "WAVE") + throw new Exception("Invalid file format"); + + if (ReadChunk(Reader) != "fmt ") + throw new Exception("Invalid file format"); + + int len = Reader.ReadInt32(); + if (len < 16) // bad format chunk length + throw new Exception("Invalid file format"); + + Format = new WAVEFORMATEX(22050, 16, 2) + { + formatTag = (WaveFormatTag)Reader.ReadInt16(), + nChannels = Reader.ReadInt16(), + nSamplesPerSec = Reader.ReadInt32(), + nAvgBytesPerSec = Reader.ReadInt32(), + nBlockAlign = Reader.ReadInt16(), + wBitsPerSample = Reader.ReadInt16() + }; // initialize to any format + + // advance in the stream to skip the wave format block + len -= 16; // minimum format size + while (len > 0) + { + Reader.ReadByte(); + len--; + } + + // assume the data chunk is aligned + while (m_Stream.Position < m_Stream.Length && ReadChunk(Reader) != "data") ; + + if (m_Stream.Position >= m_Stream.Length) + throw new Exception("Invalid file format"); + + m_Length = Reader.ReadInt32(); + m_DataPos = m_Stream.Position; + + Position = 0; + } + + public WaveStream(Stream stream) + { + m_Stream = stream; + ReadHeader(); + } + + public override bool CanRead => true; + public override bool CanSeek => true; + public override bool CanWrite => false; + public override long Length => m_Length; + public override long Position + { + get { return m_Stream.Position - m_DataPos; } + set { Seek(value, SeekOrigin.Begin); } + } + + public override void Close() + { + Dispose(); + } + + public override void Flush() + { } + + public override void SetLength(long value) + { + throw new InvalidOperationException(); + } + + public override long Seek(long offset, SeekOrigin origin) + { + switch (origin) + { + case SeekOrigin.Begin: + m_Stream.Position = offset + m_DataPos; + break; + case SeekOrigin.Current: + m_Stream.Seek(offset, SeekOrigin.Current); + break; + case SeekOrigin.End: + m_Stream.Position = m_DataPos + m_Length - offset; + break; + } + return this.Position; + } + + public override int Read(byte[] buffer, int offset, int count) + { + int toread = (int)Math.Min(count, m_Length - Position); + return m_Stream.Read(buffer, offset, toread); + } + + public override void Write(byte[] buffer, int offset, int count) + { + throw new InvalidOperationException(); + } + } +} diff --git a/ContactPoint.BaseDesign.Wpf/DelegateCommand.cs b/ContactPoint.BaseDesign.Wpf/DelegateCommand.cs index 2c768ce..77dd780 100644 --- a/ContactPoint.BaseDesign.Wpf/DelegateCommand.cs +++ b/ContactPoint.BaseDesign.Wpf/DelegateCommand.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System; using System.Windows.Input; namespace ContactPoint.BaseDesign.Wpf @@ -11,7 +8,9 @@ public class DelegateCommand : ICommand private readonly Action _handler; private readonly Func _canExecuteHandler; + #pragma warning disable 0067 public event EventHandler CanExecuteChanged; + #pragma warning restore 0067 public DelegateCommand(Action handler) { diff --git a/ContactPoint.BaseDesign/BaseNotifyControls/NotifyForm.cs b/ContactPoint.BaseDesign/BaseNotifyControls/NotifyForm.cs index 3e1206a..7fc6685 100644 --- a/ContactPoint.BaseDesign/BaseNotifyControls/NotifyForm.cs +++ b/ContactPoint.BaseDesign/BaseNotifyControls/NotifyForm.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; @@ -26,10 +26,11 @@ static extern bool SetWindowPos( int cy, // height uint uFlags); - MouseMessageFilter _messageFilter; - Timer _closeTimer = new Timer(); - Timer _showTimer = new Timer(); - int _timeout = 0; + private readonly object _lockObj = new object(); + private readonly MouseMessageFilter _messageFilter; + private readonly Timer _closeTimer = new Timer(); + private readonly Timer _showTimer = new Timer(); + private int _timeout = 0; private bool _loaded = false; private bool _closeOnShow = false; @@ -68,7 +69,7 @@ public NotifyForm(NotifyControl notifyControl) public void QueryClose() { - lock (this) + lock (_lockObj) { if (_loaded) CloseInternal(); else _closeOnShow = true; @@ -222,7 +223,7 @@ internal void SetPosition(Point position) internal void ShowGracefully() { - lock (this) + lock (_lockObj) { Opacity = 0; ShowWindow(Handle, SW_SHOWNOACTIVATE); diff --git a/ContactPoint.BaseDesign/Components/UIButton.cs b/ContactPoint.BaseDesign/Components/UIButton.cs index a5fb740..0762bc9 100644 --- a/ContactPoint.BaseDesign/Components/UIButton.cs +++ b/ContactPoint.BaseDesign/Components/UIButton.cs @@ -1,4 +1,4 @@ -using System; +using System; using ComponentFactory.Krypton.Toolkit; using System.Drawing; using System.Windows.Forms; @@ -131,12 +131,12 @@ public void PaintMe(Graphics g) this.OnPaint(new PaintEventArgs(g, new Rectangle(0, 0, this.Width, this.Height))); } - public void MouseEnter(EventArgs e) + public void MouseEnterMe(EventArgs e) { this.OnMouseEnter(e); } - public void MouseLeave(EventArgs e) + public void MouseLeaveMe(EventArgs e) { this.OnMouseLeave(e); } diff --git a/ContactPoint.BaseDesign/Components/UIToolStripButton.cs b/ContactPoint.BaseDesign/Components/UIToolStripButton.cs index 0749978..17e139d 100644 --- a/ContactPoint.BaseDesign/Components/UIToolStripButton.cs +++ b/ContactPoint.BaseDesign/Components/UIToolStripButton.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Windows.Forms; using System.Drawing; @@ -58,12 +58,12 @@ protected override void OnPaint(PaintEventArgs e) protected override void OnMouseEnter(EventArgs e) { - _myButton.MouseEnter(e); + _myButton.MouseEnterMe(e); } protected override void OnMouseLeave(EventArgs e) { - _myButton.MouseLeave(e); + _myButton.MouseLeaveMe(e); } } } diff --git a/ContactPoint.Contacts/ContactsManager.cs b/ContactPoint.Contacts/ContactsManager.cs index 139200c..459b8ab 100644 --- a/ContactPoint.Contacts/ContactsManager.cs +++ b/ContactPoint.Contacts/ContactsManager.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Data.SQLite; @@ -700,8 +700,6 @@ from contact_info_phones p return null; } } - - return null; } internal void InsertOrUpdateContactInfo(ContactInfoLocal contactInfo, bool repairDeleted) diff --git a/ContactPoint.Contacts/Locals/Contact.cs b/ContactPoint.Contacts/Locals/Contact.cs index 45a8bf6..eaae357 100644 --- a/ContactPoint.Contacts/Locals/Contact.cs +++ b/ContactPoint.Contacts/Locals/Contact.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using ContactPoint.Common.Contacts; @@ -8,46 +8,21 @@ namespace ContactPoint.Contacts.Locals { internal class Contact : IContact { - private readonly List _contactInfos = new List(); - private string _firstName = String.Empty; - private string _lastName = String.Empty; - private string _company = String.Empty; - private string _middleName = String.Empty; - public event Action Changed; public ContactsManager ContactsManager { get; private set; } public long Id { get; set; } - public string FirstName - { - get { return _firstName; } - set { _firstName = value; } - } - - public string LastName - { - get { return _lastName; } - set { _lastName = value; } - } - - public string MiddleName - { - get { return _middleName; } - set { _middleName = value; } - } - - public string Company - { - get { return _company; } - set { _company = value; } - } + public string FirstName { get; set; } = string.Empty; + public string LastName { get; set; } = string.Empty; + public string MiddleName { get; set; } = string.Empty; + public string Company { get; set; } = string.Empty; public string ShowedName { get { - var result = String.Empty; + var result = string.Empty; if (!string.IsNullOrEmpty(LastName)) result = LastName; if (!string.IsNullOrEmpty(FirstName)) result += string.Format("{1}{0}", FirstName, result.Length > 0 ? ", " : ""); @@ -60,13 +35,10 @@ public string ShowedName IEnumerable IContact.ContactInfos { - get { return _contactInfos.AsEnumerable(); } + get { return ContactInfos.AsEnumerable(); } } - internal List ContactInfos - { - get { return _contactInfos; } - } + internal List ContactInfos { get; } = new List(); internal Contact(ContactsManager contactsManager) : this(contactsManager, -1) @@ -81,22 +53,22 @@ public Contact(ContactsManager contactsManager, int id) public void LinkContactInfo(IContactInfoLocal contact) { - if (_contactInfos.Any(x => x.AddressBook.Id == contact.AddressBook.Id)) throw new InvalidOperationException("Contact info already linked."); + if (ContactInfos.Any(x => x.AddressBook.Id == contact.AddressBook.Id)) throw new InvalidOperationException("Contact info already linked."); var addressBook = ContactsManager.AddressBooks.FirstOrDefault(x => x.Id == contact.AddressBook.Id); if (addressBook == null) throw new InvalidOperationException("Address book is not registered."); var contactInfoLocal = contact as ContactInfoLocal ?? new ContactInfoLocal(contact, addressBook, ContactsManager); - _contactInfos.Add(contactInfoLocal); + ContactInfos.Add(contactInfoLocal); } public void UnlinkContactInfo(IContactInfoLocal contactInfo) { - var target = _contactInfos.FirstOrDefault(x => x.Id == contactInfo.Id); + var target = ContactInfos.FirstOrDefault(x => x.Id == contactInfo.Id); if (target != null) - _contactInfos.Remove(target); + ContactInfos.Remove(target); } public void Submit() @@ -138,5 +110,10 @@ public override bool Equals(object obj) return contact.Id == Id; } + + public override int GetHashCode() + { + return Id.GetHashCode(); + } } } diff --git a/ContactPoint.Contacts/Locals/TagLocal.cs b/ContactPoint.Contacts/Locals/TagLocal.cs index 12226e2..3ca7542 100644 --- a/ContactPoint.Contacts/Locals/TagLocal.cs +++ b/ContactPoint.Contacts/Locals/TagLocal.cs @@ -1,4 +1,4 @@ -using System; +using System; using ContactPoint.Common.Contacts; using ContactPoint.Common.Contacts.Local; @@ -102,5 +102,10 @@ public override bool Equals(object obj) return tag.Id == Id; } + + public override int GetHashCode() + { + return Id.GetHashCode(); + } } } diff --git a/ContactPoint.Core/CallManager/CallManager.cs b/ContactPoint.Core/CallManager/CallManager.cs index 9656435..e55e837 100644 --- a/ContactPoint.Core/CallManager/CallManager.cs +++ b/ContactPoint.Core/CallManager/CallManager.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Windows.Threading; @@ -7,6 +7,7 @@ using Sipek.Common; using System.Threading; using Sipek.Sip; +using System.Collections.Concurrent; namespace ContactPoint.Core.CallManager { @@ -28,7 +29,7 @@ internal class CallManager : ICallManager private readonly System.Windows.Forms.Timer _internalTimer; private readonly List _calls = new List(); private readonly Call[] _lines = new Call[LINES_MAXCOUNT + 1]; - private readonly List _defferedOperations = new List(); + private readonly ConcurrentQueue _defferedOperations = new ConcurrentQueue(); private readonly Dispatcher _dispatcher; private bool _isConferenceActive; @@ -91,11 +92,11 @@ internal CallManager(Core core) _raiseCallRemovedEventCallback = RaiseCallRemovedEventCallback; _deferredOperationCallback = DeferredOperationCallback; - _durationTimer = new System.Windows.Forms.Timer {Interval = 1000}; + _durationTimer = new System.Windows.Forms.Timer { Interval = 1000 }; _durationTimer.Tick += DurationTimerTick; _durationTimer.Start(); - _internalTimer = new System.Windows.Forms.Timer {Interval = 100}; + _internalTimer = new System.Windows.Forms.Timer { Interval = 100 }; _internalTimer.Tick += InternalTimerTick; _internalTimer.Start(); @@ -308,14 +309,14 @@ public ICall MakeCall(string number, IEnumerable> h } var newCall = new CallWrapper(this, number) - { - LastUserAction = CallAction.Make, - State = CallState.CONNECTING - }; + { + LastUserAction = CallAction.Make, + State = CallState.CONNECTING + }; var headersCollection = new List(); if (headers != null) - headersCollection.AddRange(headers.Select(header => new SipHeader() {name = header.Key, value = header.Value})); + headersCollection.AddRange(headers.Select(header => new SipHeader() { name = header.Key, value = header.Value })); if (!AssignLineForCall(newCall)) { @@ -359,7 +360,7 @@ public void TransferCall(ICall call, string number) var headers = new List(); foreach (var header in thisCall.Headers.Where(x => x.Name.StartsWith("x-", StringComparison.OrdinalIgnoreCase))) { - headers.Add(new SipHeader {name = header.Name, value = header.Value}); + headers.Add(new SipHeader { name = header.Name, value = header.Value }); } _sip.SipekResources.CallManager.OnUserTransfer(call.SessionId, number, headers.ToArray()); @@ -473,15 +474,19 @@ public void DoMakeConference() private void DoMakeConferenceInternal() { + Call[] calls; lock (_calls) { - var calls = _calls.Where(x => x.State == CallState.ACTIVE).ToArray(); + calls = _calls.Where(x => x.State == CallState.ACTIVE).ToArray(); + } - // Interconnect all calls between themselves - int i, j, n = calls.Length; - for (i = 0; i < n; i++) - for (j = i + 1; j < n; j++) - AddDeferredOperation(new Action(DoMakeConference), calls[i], calls[j]); + // Interconnect all calls between themselves + for (var i = 0; i < calls.Length; i++) + { + for (var j = i + 1; j < calls.Length; j++) + { + AddDeferredOperation(new Action(DoMakeConference), calls[i], calls[j]); + } } } @@ -515,7 +520,7 @@ private void OnIncomingCallNotification(int sessionId, string number, string inf // Incoming call raises after CallStateRefresh! So we have our call in collection Call call = FindCallBySessionId(sessionId); if (call == null) return; - + if (Monitor.TryEnter(call, OPERATION_WAIT_TIMEOUT)) { Logger.LogNotice($"Local call found! Id: {call.Id}. Assigning values."); @@ -548,7 +553,7 @@ private void OnCallStateRefresh(int sessionId) { Logger.LogNotice($"Call state refresh for {sessionId}."); Call call = FindCallBySessionId(sessionId); - + if (call == null) // Call not found in our collection, but it may be exists! Let's add it { Logger.LogNotice($"Call not found for {sessionId}."); @@ -650,51 +655,38 @@ private void InternalTimerTick(object sender, EventArgs e) private void RemoveNullCallsAndIncrementDuration() { - var killList = new List(); + IEnumerable calls; lock (_calls) { - foreach (var call in _calls) + calls = _calls.ToArray(); + } + + foreach (var call in calls) + { + try { - try + if (call != null && call.State != CallState.NULL) { - if (call != null && call.State != CallState.NULL) - { - call.Duration += TimeSpan.FromSeconds(1); - } - else - { - killList.Add(call); - } + call.Duration += TimeSpan.FromSeconds(1); } - catch (Exception ex) + else { - Logger.LogWarn(ex); + RemoveCallInternal(call, CallRemoveReason.NULL); } } + catch (Exception ex) + { + Logger.LogWarn(ex); + } } - - foreach (var call in killList) - { - RemoveCallInternal(call, CallRemoveReason.NULL); - } - - killList.Clear(); } private Call FindCallBySessionId(int sessionId) { lock (_calls) { - foreach (Call call in _calls) - { - if (call.SessionId == sessionId) - { - return call; - } - } + return _calls.FirstOrDefault(call => call.SessionId == sessionId); } - - return null; } private CallRemoveReason GetCallRemoveReason(Call call) @@ -713,11 +705,7 @@ private void RemoveCallInternal(Call call, CallRemoveReason reason) lock (_calls) { _isConferenceActive = _calls.Count(x => x.IsInConference) > 1; - - if (_calls.Contains(call)) - { - _calls.Remove(call); - } + _calls.Remove(call); } call.IsDisposed = true; @@ -729,7 +717,6 @@ private void RemoveCallInternal(Call call, CallRemoveReason reason) private bool AssignLineForCall(Call call) { lock (_lines) - lock (_calls) { int targetLine = -1; int maxAllowedCalls = LINES_MAXCOUNT; @@ -747,13 +734,11 @@ private bool AssignLineForCall(Call call) break; } - lock (_lines[i]) + var line = _lines[i]; + if (line.IsDisposed || line.State == CallState.NULL) { - if (_lines[i].IsDisposed || _lines[i].State == CallState.NULL) - { - targetLine = i; - break; - } + targetLine = i; + break; } } @@ -778,7 +763,7 @@ public void RaiseCallStateChanged(Call call) { if (call.LastState == CallState.NULL) // It is not normal!!! May be raise removed event RemoveCallInternal(call, CallRemoveReason.NULL); - + return; } @@ -869,25 +854,17 @@ private void RaiseCallRemovedEventCallback(IAsyncResult result) private void AddDeferredOperation(Delegate del, params object[] p) { - lock (_defferedOperations) - { - _defferedOperations.Add(new CallOperation(del, p)); - } + _defferedOperations.Enqueue(new CallOperation(del, p)); } private void ProcessDeferredOperations() { - lock (_defferedOperations) + CallOperation operation = null; + while (_defferedOperations.TryDequeue(out operation)) { - foreach (var operation in _defferedOperations) - { - CallOperation localOperation = operation; - - var del = new Action(localOperation.Execute); - del.BeginInvoke(_deferredOperationCallback, del); - } - - _defferedOperations.Clear(); + var localOperation = operation; + var del = new Action(localOperation.Execute); + del.BeginInvoke(_deferredOperationCallback, del); } } @@ -896,7 +873,6 @@ private static void DeferredOperationCallback(IAsyncResult result) try { var del = result.AsyncState as Action; - if (del != null) del.EndInvoke(result); } @@ -909,7 +885,7 @@ private static void DeferredOperationCallback(IAsyncResult result) private class CallOperation { Delegate OperationDelegate; - object[] Parameters; + readonly object[] Parameters; public CallOperation(Delegate operationDelegate, params object[] parameters) { @@ -929,12 +905,10 @@ public void Execute() public IEnumerator GetEnumerator() { - List calls = new List(); - + IEnumerable calls; lock (_calls) { - foreach (var call in _calls) - calls.Add(call); + calls = _calls.ToArray(); } return calls.GetEnumerator(); diff --git a/ContactPoint.Core/CallManager/CallWrapper.cs b/ContactPoint.Core/CallManager/CallWrapper.cs index 04b7432..7890415 100644 --- a/ContactPoint.Core/CallManager/CallWrapper.cs +++ b/ContactPoint.Core/CallManager/CallWrapper.cs @@ -1,12 +1,12 @@ -using System; -using System.Collections.Generic; +using System; +using System.Collections.Concurrent; using ContactPoint.Common; namespace ContactPoint.Core.CallManager { internal class CallWrapper : Call { - private readonly List _actions = new List(); + private readonly ConcurrentQueue _actions = new ConcurrentQueue(); public CallWrapper(CallManager callManager, string number) : base(callManager, -1) @@ -16,133 +16,114 @@ public CallWrapper(CallManager callManager, string number) public void SetSession(int sessionId) { - lock (_actions) + try + { + Number = ((SIP.SIP)CallManager.Core.Sip).SipekResources.CallManager[sessionId] != null ? ((SIP.SIP)CallManager.Core.Sip).SipekResources.CallManager[sessionId].CallingNumber : ""; + SessionId = sessionId; + } + catch (Exception e) + { + Logger.LogWarn(e, "Invalid flow of call. SessionId is invalid"); + return; + } + + while (_actions.TryDequeue(out Action action)) { try { - Number = ((SIP.SIP)CallManager.Core.Sip).SipekResources.CallManager[sessionId] != null ? ((SIP.SIP)CallManager.Core.Sip).SipekResources.CallManager[sessionId].CallingNumber : ""; - SessionId = sessionId; + action.Invoke(); } catch (Exception e) { - Logger.LogWarn(e, "Invalid flow of call. SessionId is invalid"); - - return; + Logger.LogWarn(e); } - - foreach (var action in _actions) - try - { - action.Invoke(); - } - catch (Exception e) - { - Logger.LogWarn(e); - } - - _actions.Clear(); } } public override void Answer() { - lock (_actions) - if (SessionId < 0) - { - _actions.Add(() => base.Answer()); - - return; - } + if (SessionId < 0) + { + _actions.Enqueue(() => base.Answer()); + return; + } base.Answer(); } public override void Drop() { - lock (_actions) - if (SessionId < 0 && State != CallState.CONNECTING && State != CallState.NULL) - { - _actions.Add(() => base.Drop()); - - return; - } + if (SessionId < 0 && State != CallState.CONNECTING && State != CallState.NULL) + { + _actions.Enqueue(() => base.Drop()); + return; + } base.Drop(); } public override void Hold() { - lock (_actions) - if (SessionId < 0) - { - _actions.Add(() => base.Hold()); - - return; - } + if (SessionId < 0) + { + _actions.Enqueue(() => base.Hold()); + return; + } base.Hold(); } public override void SendDTMF(string digits) { - lock (_actions) - if (SessionId < 0) - { - _actions.Add(() => base.SendDTMF(digits)); - - return; - } + if (SessionId < 0) + { + _actions.Enqueue(() => base.SendDTMF(digits)); + return; + } base.SendDTMF(digits); } public override void ToggleHold() { - lock (_actions) - if (SessionId < 0) - { - _actions.Add(() => base.ToggleHold()); - - return; - } + if (SessionId < 0) + { + _actions.Enqueue(() => base.ToggleHold()); + return; + } base.ToggleHold(); } public override void Transfer(string number) { - lock (_actions) - if (SessionId < 0) - { - _actions.Add(() => base.Transfer(number)); + if (SessionId < 0) + { + _actions.Enqueue(() => base.Transfer(number)); + return; + } - return; - } base.Transfer(number); } public override void TransferAttended(ICall destCall) { - lock (_actions) - if (SessionId < 0) - { - _actions.Add(() => base.TransferAttended(destCall)); - - return; - } + if (SessionId < 0) + { + _actions.Enqueue(() => base.TransferAttended(destCall)); + return; + } base.TransferAttended(destCall); } public override void UnHold() { - lock (_actions) - if (SessionId < 0) - { - _actions.Add(() => base.UnHold()); - - return; - } + if (SessionId < 0) + { + _actions.Enqueue(() => base.UnHold()); + return; + } base.UnHold(); } diff --git a/ContactPoint.Core/PluginManager/PluginInformation.cs b/ContactPoint.Core/PluginManager/PluginInformation.cs index c31c039..36209c3 100644 --- a/ContactPoint.Core/PluginManager/PluginInformation.cs +++ b/ContactPoint.Core/PluginManager/PluginInformation.cs @@ -1,5 +1,4 @@ -using System; -using System.Reflection; +using System; using ContactPoint.Common.PluginManager; using ContactPoint.Common; @@ -7,6 +6,8 @@ namespace ContactPoint.Core.PluginManager { internal class PluginInformation : IPluginInformation { + private readonly object _lockObj = new object(); + public event ServiceStartedDelegate Started; public event ServiceStoppedDelegate Stopped; @@ -48,7 +49,7 @@ public void ShowSettingsDialog() public void Start() { - lock (this) + lock (_lockObj) { if (_instance == null && CreateInstance() == null) return; if (_instance == null) return; @@ -60,7 +61,7 @@ public void Start() public void Stop() { - lock (this) + lock (_lockObj) { if (_instance == null) return; if (!_instance.IsStarted) return; @@ -73,7 +74,7 @@ public IPlugin GetInstance(bool create) { if (_instance == null && create) { - lock (this) + lock (_lockObj) { if (_instance == null) { diff --git a/ContactPoint.Core/PluginManager/PluginManagerWrapper.cs b/ContactPoint.Core/PluginManager/PluginManagerWrapper.cs index c9963b9..24aed38 100644 --- a/ContactPoint.Core/PluginManager/PluginManagerWrapper.cs +++ b/ContactPoint.Core/PluginManager/PluginManagerWrapper.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using ContactPoint.Common; using ContactPoint.Common.PluginManager; @@ -11,8 +11,10 @@ internal class PluginManagerWrapper : IPluginManager { private readonly ICore _core; + #pragma warning disable 0067 public event ServiceStartedDelegate Started; public event ServiceStoppedDelegate Stopped; + #pragma warning restore 0067 public ICore Core { get; } public IEnumerable Plugins { get; } diff --git a/ContactPoint.Core/SIP/SIP.cs b/ContactPoint.Core/SIP/SIP.cs index 53187a6..5105c4f 100644 --- a/ContactPoint.Core/SIP/SIP.cs +++ b/ContactPoint.Core/SIP/SIP.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Net.NetworkInformation; using ContactPoint.Common; @@ -14,11 +14,11 @@ namespace ContactPoint.Core.SIP { internal class SIP : ISip { + private readonly object _lockObj = new object(); private readonly Core _core; - private readonly List _codecsList; - private readonly ISipAccount _account; - private readonly SipekResources _sipekResources; private readonly System.Timers.Timer _deferredSetAudioDevicesTimer; + + internal SipekResources SipekResources { get; private set; } public SIP(Core core, ISynchronizeInvoke syncInvoke) { @@ -30,25 +30,25 @@ public SIP(Core core, ISynchronizeInvoke syncInvoke) _deferredSetAudioDevicesTimer.Stop(); // Initialize PjSIP - _sipekResources = new SipekResources(core); + SipekResources = new SipekResources(core); - if (!CheckUdpPort(_sipekResources.Configurator.SIPPort)) + if (!CheckUdpPort(SipekResources.Configurator.SIPPort)) { - if (CheckUdpPort(5060)) _sipekResources.Configurator.SIPPort = 5060; - else if (CheckUdpPort(5061)) _sipekResources.Configurator.SIPPort = 5061; + if (CheckUdpPort(5060)) SipekResources.Configurator.SIPPort = 5060; + else if (CheckUdpPort(5061)) SipekResources.Configurator.SIPPort = 5061; else throw new InvalidOperationException("SIP port is in use"); } - if (_sipekResources.StackProxy.initialize() != 0) + if (SipekResources.StackProxy.initialize() != 0) throw new InvalidOperationException("Can't initialize PjSIP proxy stack!"); - if (_sipekResources.CallManager.Initialize(_sipekResources.StackProxy) != 0) + if (SipekResources.CallManager.Initialize(SipekResources.StackProxy) != 0) throw new InvalidOperationException("Can't initialize PjSIP call manager!"); - _codecsList = LoadCodecs(); + Codecs = LoadCodecs(); // Initialize account - _account = new SipAccount(this); + Account = new SipAccount(this); Messenger = new SipMessenger(this); NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged; @@ -83,14 +83,9 @@ void Audio_RecordingDeviceChanged(IAudioDevice obj) SetAudioDevicesDeferred(); } - internal SipekResources SipekResources - { - get { return _sipekResources; } - } - void _deferredSetAudioDevicesTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { - lock (this) + lock (_lockObj) { _deferredSetAudioDevicesTimer.Stop(); @@ -104,7 +99,7 @@ void _deferredSetAudioDevicesTimer_Elapsed(object sender, System.Timers.ElapsedE /// private void SetAudioDevicesDeferred() { - lock (this) + lock (_lockObj) { _deferredSetAudioDevicesTimer.Start(); } @@ -112,7 +107,7 @@ private void SetAudioDevicesDeferred() void NetworkChange_NetworkAddressChanged(object sender, EventArgs e) { - _account.Renew(); + Account.Renew(); } /// @@ -120,43 +115,61 @@ void NetworkChange_NetworkAddressChanged(object sender, EventArgs e) /// private void SetAudioDevices() { - if (Core.Audio.PlaybackDevice != null) Core.SettingsManager["PlaybackDevice"] = Core.Audio.PlaybackDevice.Name; - if (Core.Audio.RecordingDevice != null) Core.SettingsManager["RecordingDevice"] = Core.Audio.RecordingDevice.Name; + var playbackDevice = Core.Audio.PlaybackDevice; + var recordingDevice = Core.Audio.RecordingDevice; + + Logger.LogNotice(string.Format("Setting audio devices {0}/{1}", playbackDevice?.Name ?? "none", recordingDevice?.Name ?? "none")); try { - if (Core.Audio.PlaybackDevice == null || Core.Audio.RecordingDevice == null) + if (playbackDevice == null || recordingDevice == null) { - _sipekResources.StackProxy.setSoundDevice( - String.Empty, - String.Empty - ); + Logger.LogWarn("One of audio devices is invalid or not found - reseting audio devices settings!"); + SipekResources.StackProxy.setSoundDevice(string.Empty, string.Empty); - Logger.LogWarn(String.Format("Setting null audio devices")); + playbackDevice = null; + recordingDevice = null; } else { - _sipekResources.StackProxy.setSoundDevice( - Core.Audio.PlaybackDevice.Name.Substring(0, Core.Audio.PlaybackDevice.Name.Length > 31 ? 31 : Core.Audio.PlaybackDevice.Name.Length), // 31 is the max length of sound device name in PjSIP - Core.Audio.RecordingDevice.Name.Substring(0, Core.Audio.RecordingDevice.Name.Length > 31 ? 31 : Core.Audio.RecordingDevice.Name.Length) - ); - - Logger.LogNotice(String.Format("Setting audio devices {0}/{1}", - Core.Audio.PlaybackDevice != null ? Core.Audio.PlaybackDevice.Name : "none", - Core.Audio.RecordingDevice != null ? Core.Audio.RecordingDevice.Name : "none")); + var playbackDeviceName = GetPjSipDeviceName(playbackDevice); + var recordingDeviceName = GetPjSipDeviceName(recordingDevice); + + SipekResources.StackProxy.setSoundDevice(playbackDeviceName, recordingDeviceName); + + if (Core.Audio.PlaybackDevice != null) Core.SettingsManager["PlaybackDevice"] = playbackDeviceName; + if (Core.Audio.RecordingDevice != null) Core.SettingsManager["RecordingDevice"] = recordingDeviceName; } } catch (Exception e) { Logger.LogWarn(e); } + + PlaybackDeviceChanged?.Invoke(playbackDevice); + RecordingDeviceChanged?.Invoke(recordingDevice); + } + + /// + /// 31 is the max length of sound device name in PjSIP + /// + /// Device + /// + string GetPjSipDeviceName(IAudioDevice device) + { + if (device.Name.Length > 31) + { + return device.Name.Substring(0, 31); + } + + return device.Name; } void codec_EnabledChanged(ISipCodec codec) { try { - Logger.LogNotice(String.Format("Setting codec priority on {0} to {1}", codec.Name, codec.Priority)); + Logger.LogNotice(string.Format("Setting codec priority on {0} to {1}", codec.Name, codec.Priority)); SipekResources.StackProxy.setCodecPriority(codec.Name, codec.Priority); } catch (Exception e) @@ -171,18 +184,18 @@ private List LoadCodecs() { List codecList = new List(); - int noOfCodecs = _sipekResources.StackProxy.getNoOfCodecs(); + int noOfCodecs = SipekResources.StackProxy.getNoOfCodecs(); Logger.LogNotice("Loading codecs"); for (int i = 0; i < noOfCodecs; i++) { - ISipCodec codec = new SipCodec(this, _sipekResources.StackProxy.getCodec(i)); + ISipCodec codec = new SipCodec(this, SipekResources.StackProxy.getCodec(i)); codec.EnabledChanged += new Action(codec_EnabledChanged); codecList.Add(codec); - Logger.LogNotice(String.Format("Codec {0} loaded", codec.Name)); + Logger.LogNotice(string.Format("Codec {0} loaded", codec.Name)); } Logger.LogNotice("Setting codecs priorities"); @@ -200,40 +213,34 @@ private List LoadCodecs() public event Action PlaybackDeviceChanged; - public ISipAccount Account - { - get { return _account; } - } + public ISipAccount Account { get; } public ISipMessenger Messenger { get; } - public List Codecs - { - get { return _codecsList; } - } + public List Codecs { get; } public SipTransportType TransportType { - get { return (_sipekResources.Configurator.Account.TransportMode == ETransportMode.TM_TCP ? SipTransportType.TCP : SipTransportType.UDP); } - set { _sipekResources.Configurator.Account.TransportMode = (value == SipTransportType.TCP ? ETransportMode.TM_TCP : ETransportMode.TM_UDP); } + get { return (SipekResources.Configurator.Account.TransportMode == ETransportMode.TM_TCP ? SipTransportType.TCP : SipTransportType.UDP); } + set { SipekResources.Configurator.Account.TransportMode = (value == SipTransportType.TCP ? ETransportMode.TM_TCP : ETransportMode.TM_UDP); } } public SipDTMFMode DTMFMode { - get { return ConvertSipekDTMFMode(_sipekResources.Configurator.DtmfMode); } - set { _sipekResources.Configurator.DtmfMode = ConvertSipDTMFMode(value); } + get { return ConvertSipekDTMFMode(SipekResources.Configurator.DtmfMode); } + set { SipekResources.Configurator.DtmfMode = ConvertSipDTMFMode(value); } } public int EchoCancelationTimeout { - get { return _sipekResources.Configurator.ECTail; } - set { _sipekResources.Configurator.ECTail = value; } + get { return SipekResources.Configurator.ECTail; } + set { SipekResources.Configurator.ECTail = value; } } public bool VoiceActiveDetection { - get { return _sipekResources.Configurator.VADEnabled; } - set { _sipekResources.Configurator.VADEnabled = value; } + get { return SipekResources.Configurator.VADEnabled; } + set { SipekResources.Configurator.VADEnabled = value; } } public ICore Core diff --git a/ContactPoint.Plugins.CallTools/CallNotifyWindow/CallNotifyControl.cs b/ContactPoint.Plugins.CallTools/CallNotifyWindow/CallNotifyControl.cs index d484b34..97b4cd5 100644 --- a/ContactPoint.Plugins.CallTools/CallNotifyWindow/CallNotifyControl.cs +++ b/ContactPoint.Plugins.CallTools/CallNotifyWindow/CallNotifyControl.cs @@ -1,44 +1,44 @@ -using System; +using System; using System.Drawing; -using System.Globalization; using ContactPoint.BaseDesign.BaseNotifyControls; using ContactPoint.Common; -namespace ContactPoint.Plugins.CallTools.CallNotifyWindow { - public partial class CallNotifyControl : NotifyControl { +namespace ContactPoint.Plugins.CallTools.CallNotifyWindow +{ + public partial class CallNotifyControl : NotifyControl + { + private readonly bool _persistentWindow; private ICall _call; - private bool _persistentWindow; - public CallNotifyControl(ICall call, bool persistentWindow) { + public CallNotifyControl(ICall call, bool persistentWindow) + { InitializeComponent(); - lock (call) { - _call = call; - _persistentWindow = persistentWindow; - AttachToEventHandlers(); - } - - labelColor.BackColor = Color.LightGray; - - RefreshUI(); - } - - private void AttachToEventHandlers() { + _call = call; _call.OnRemoved += _call_OnRemoved; _call.OnStateChanged += _call_OnStateChanged; _call.OnInfoChanged += _call_OnInfoChanged; _call.OnDurationChanged += _call_OnDurationChanged; + + _persistentWindow = persistentWindow; + + labelColor.BackColor = Color.LightGray; + + RefreshUI(); } - private void DetachFromEventHandlers() { + private void DetachFromEventHandlers() + { _call.OnRemoved -= _call_OnRemoved; _call.OnStateChanged -= _call_OnStateChanged; _call.OnInfoChanged -= _call_OnInfoChanged; _call.OnDurationChanged -= _call_OnDurationChanged; } - void _call_OnDurationChanged() { - if (InvokeRequired) { + void _call_OnDurationChanged() + { + if (InvokeRequired) + { BeginInvoke(new EmptyDelegate(_call_OnDurationChanged)); return; @@ -47,8 +47,10 @@ void _call_OnDurationChanged() { lblTime.Text = _call.Duration.ToFormattedString(); } - void _call_OnInfoChanged() { - if (InvokeRequired) { + void _call_OnInfoChanged() + { + if (InvokeRequired) + { BeginInvoke(new EmptyDelegate(_call_OnInfoChanged)); return; } @@ -56,34 +58,45 @@ void _call_OnInfoChanged() { RefreshUI(); } - void _call_OnStateChanged() { - if (InvokeRequired) { + void _call_OnStateChanged() + { + if (InvokeRequired) + { BeginInvoke(new EmptyDelegate(_call_OnStateChanged)); return; } - if (_call.State == CallState.ACTIVE && ParentForm != null && !_persistentWindow) { + if (_call.State == CallState.ACTIVE && ParentForm != null && !_persistentWindow) + { Close(); - } else if (ParentForm != null) { + } + else if (ParentForm != null) + { RefreshUI(); } } - void _call_OnRemoved(CallRemoveReason reason) { - if (InvokeRequired) { + void _call_OnRemoved(CallRemoveReason reason) + { + if (InvokeRequired) + { BeginInvoke(new Action(_call_OnRemoved), reason); return; } - if (Handle == IntPtr.Zero) { + if (Handle == IntPtr.Zero) + { _call = null; - } else { + } + else + { Close(); } } - void RefreshUI() { + void RefreshUI() + { this.lblLine.Text = this._call.Line >= 0 ? (this._call.Line + 1).ToString() : ""; this.lblName.Text = this._call.Name.Length > 0 ? this._call.Name : "-"; this.lblNumber.Text = this._call.Number; @@ -92,49 +105,62 @@ void RefreshUI() { if (_call.Headers.Contains("x-info")) this.labelInfo.Text = _call.Headers.GetValueSafe("x-info"); - if (_call.Contact != null && !string.IsNullOrWhiteSpace(_call.Contact.ShowedName)) { + if (_call.Contact != null && !string.IsNullOrWhiteSpace(_call.Contact.ShowedName)) + { lblName.Text = _call.Contact.ShowedName; var queueDisplayName = _call.Headers.GetValueSafe("x-queue-display-name"); if (!String.IsNullOrEmpty(queueDisplayName)) this.labelInfo.Text = Uri.UnescapeDataString(queueDisplayName); - } else { + } + else + { var queueDisplayName = _call.Headers.GetValueSafe("x-queue-display-name"); if (!String.IsNullOrEmpty(queueDisplayName)) this.lblName.Text = Uri.UnescapeDataString(queueDisplayName); } - if (_call.Headers.Contains("x-color")) { - try { + if (_call.Headers.Contains("x-color")) + { + try + { labelColor.BackColor = Color.FromName(_call.Headers["x-color"].Value); - } catch (Exception e) { + } + catch (Exception e) + { Logger.LogWarn(e, "Header 'x-color' was found but color can't be parsed. Color value is invalid or null."); } } } - private void btnCall_Click(object sender, EventArgs e) { + private void btnCall_Click(object sender, EventArgs e) + { _call.Answer(); - if (!_persistentWindow) { + if (!_persistentWindow) + { Close(); } } - private void btnDrop_Click(object sender, EventArgs e) { + private void btnDrop_Click(object sender, EventArgs e) + { _call.Drop(); Close(); } - public override void OnShow() { + public override void OnShow() + { if (_call == null || _call.IsDisposed) { Close(); } base.OnShow(); } - public override void OnClosing() { - if (_call != null) { + public override void OnClosing() + { + if (_call != null) + { DetachFromEventHandlers(); } } diff --git a/ContactPoint.Plugins.CallTools/CallNotifyWindow/CallNotifyWindowService.cs b/ContactPoint.Plugins.CallTools/CallNotifyWindow/CallNotifyWindowService.cs index 529a977..7404492 100644 --- a/ContactPoint.Plugins.CallTools/CallNotifyWindow/CallNotifyWindowService.cs +++ b/ContactPoint.Plugins.CallTools/CallNotifyWindow/CallNotifyWindowService.cs @@ -1,80 +1,79 @@ -using System; +using System; using ContactPoint.BaseDesign; using ContactPoint.Common; using ContactPoint.Common.PluginManager; -namespace ContactPoint.Plugins.CallTools.CallNotifyWindow { - internal class CallNotifyWindowService : IService { +namespace ContactPoint.Plugins.CallTools.CallNotifyWindow +{ + internal class CallNotifyWindowService : IService + { private readonly IPlugin _plugin; private readonly CallDelegate _callStatChanged; - private bool _isStarted = false; - private int _showingWindowTimeout = 0; public event ServiceStartedDelegate Started; public event ServiceStoppedDelegate Stopped; + + public bool NeedShowingNotification => _plugin.PluginManager.Core.SettingsManager.Get(CallToolsOptions.ShowIncomingCallWindowName); + public bool IsNotificationWindowPersistent => _plugin.PluginManager.Core.SettingsManager.Get(CallToolsOptions.NotHideCallWindowName); - public bool IsStarted { - get { return _isStarted; } - } + public bool IsStarted { get; private set; } = false; - public CallNotifyWindowService(IPlugin plugin) { + public CallNotifyWindowService(IPlugin plugin) + { _plugin = plugin; _callStatChanged = CallManager_OnCallStateChanged; } - public void Start() { + public void Start() + { if (IsStarted) { return; } + _plugin.PluginManager.Core.CallManager.OnCallStateChanged += _callStatChanged; _plugin.PluginManager.Core.CallManager.OnIncomingCall += CallManager_OnIncomingCall; - _isStarted = true; + IsStarted = true; + Started?.Invoke(this); } - public void Stop() { + public void Stop() + { if (!IsStarted) { return; } + _plugin.PluginManager.Core.CallManager.OnCallStateChanged -= _callStatChanged; _plugin.PluginManager.Core.CallManager.OnIncomingCall -= CallManager_OnIncomingCall; - _isStarted = false; + IsStarted = false; + Stopped?.Invoke(this, string.Empty); } - void CallManager_OnIncomingCall(ICall call) { + void CallManager_OnIncomingCall(ICall call) + { if (IsStarted && call.Headers.Contains("x-color") && !call.Tags.ContainsKey("color")) call.Tags.Add("color", call.Headers["x-color"].Value); } - void CallManager_OnCallStateChanged(ICall call) { - bool notifyUser = false; - - if (call == null) + void CallManager_OnCallStateChanged(ICall call) + { + if (call == null || call.IsDisposed) + { return; - - lock (call) { - if (call.IsDisposed) - return; - - if (call.State == CallState.INCOMING && call.LastState == CallState.NULL && call.IsIncoming) - notifyUser = true; } - if (notifyUser && NeedShowingNotification()) { - bool isWindowPersistent = IsNotificationWindowPersistent(); + if (NeedShowingNotification&& call.State == CallState.INCOMING && call.LastState == CallState.NULL && call.IsIncoming) + { + bool isWindowPersistent = IsNotificationWindowPersistent; int closeWindowTimeout = isWindowPersistent ? int.MaxValue : 0; - if (SyncUi.InvokeRequired) { + + if (SyncUi.InvokeRequired) + { SyncUi.Invoke(new Action(() => NotifyManager.NotifyUser(new CallNotifyControl(call, isWindowPersistent), closeWindowTimeout))); - } else { + } + else + { NotifyManager.NotifyUser(new CallNotifyControl(call, isWindowPersistent), closeWindowTimeout); } } } - - private bool NeedShowingNotification() { - return _plugin.PluginManager.Core.SettingsManager.Get(CallToolsOptions.ShowIncomingCallWindowName); - } - - private bool IsNotificationWindowPersistent() { - return _plugin.PluginManager.Core.SettingsManager.Get(CallToolsOptions.NotHideCallWindowName); - } } } diff --git a/ContactPoint.Plugins.CallTools/OneLine/OneLineService.cs b/ContactPoint.Plugins.CallTools/OneLine/OneLineService.cs index 5a5d97f..1acfcde 100644 --- a/ContactPoint.Plugins.CallTools/OneLine/OneLineService.cs +++ b/ContactPoint.Plugins.CallTools/OneLine/OneLineService.cs @@ -1,47 +1,51 @@ -using ContactPoint.Common; +using ContactPoint.Common; using ContactPoint.Common.PluginManager; -namespace ContactPoint.Plugins.CallTools.OneLine { - public class OneLineService { - private bool _isOneLine = false; - private bool _isStarted = false; +namespace ContactPoint.Plugins.CallTools.OneLine +{ + public class OneLineService + { private readonly IPluginManager _pluginManager; - public bool IsOneLine { - get { return this._isOneLine; } - set { this._isOneLine = value; } + public bool IsOneLine { get; set; } = false; + public bool IsStarted { get; private set; } = false; + + public OneLineService(IPlugin plugin) + { + _pluginManager = plugin.PluginManager; } - public void Start() { + public void Start() + { if (IsStarted) { return; } _pluginManager.Core.CallManager.OnCallStateChanged += CallManager_OnCallStateChanged; - this._isStarted = true; + this.IsStarted = true; } - public void Stop() { + public void Stop() + { if (!IsStarted) { return; } _pluginManager.Core.CallManager.OnCallStateChanged -= CallManager_OnCallStateChanged; - this._isStarted = false; + this.IsStarted = false; } - public bool IsStarted { - get { return this._isStarted; } - } + void CallManager_OnCallStateChanged(ICall call) + { + if (!IsOneLine) + { + return; + } - public OneLineService(IPlugin plugin) { - _pluginManager = plugin.PluginManager; - } + if (call == null || call.IsDisposed) + { + return; + } - void CallManager_OnCallStateChanged(ICall call) { - lock (call) { - if (call != null && - !call.IsDisposed && - this.IsOneLine && - call.IsIncoming && - _pluginManager.Core.CallManager.Count > 1) - call.Drop(); + if (call.IsIncoming && _pluginManager.Core.CallManager.Count > 1) + { + call.Drop(); } } } diff --git a/ContactPoint.Plugins.ContactsUi/ContactsCommand.cs b/ContactPoint.Plugins.ContactsUi/ContactsCommand.cs index 1effc80..2c208de 100644 --- a/ContactPoint.Plugins.ContactsUi/ContactsCommand.cs +++ b/ContactPoint.Plugins.ContactsUi/ContactsCommand.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Drawing; using ContactPoint.Common.PluginManager; @@ -11,6 +11,8 @@ internal class ContactsCommand : PluginUIElementBase { private static ContactsListForm _formInstance; + private readonly object _lockObj = new object(); + public ContactsCommand(IPlugin plugin) : base(plugin) { } @@ -25,7 +27,7 @@ public ContactsCommand(IPlugin plugin) : base(plugin) protected override void ExecuteCommand(object sender, object data) { - lock (this) + lock (_lockObj) { if (_formInstance == null) { @@ -39,10 +41,11 @@ protected override void ExecuteCommand(object sender, object data) private void FormInstanceClosing(object sender, System.ComponentModel.CancelEventArgs e) { - lock (this) + lock (_lockObj) { + _formInstance.Closing -= FormInstanceClosing; _formInstance = null; } } } -} \ No newline at end of file +} diff --git a/ContactPoint.Plugins.ContactsUi/Controls/DataGridViewTagsCell.cs b/ContactPoint.Plugins.ContactsUi/Controls/DataGridViewTagsCell.cs index 34d254b..a246672 100644 --- a/ContactPoint.Plugins.ContactsUi/Controls/DataGridViewTagsCell.cs +++ b/ContactPoint.Plugins.ContactsUi/Controls/DataGridViewTagsCell.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Windows.Forms; using ContactPoint.Common.Contacts.Local; @@ -7,8 +7,6 @@ namespace ContactPoint.Plugins.ContactsUi.Controls { public class DataGridViewTagsColumns : DataGridViewColumn { - public string DataPropertyName { get; set; } - public DataGridViewTagsColumns() : base(new DataGridViewTagsCell()) { } diff --git a/ContactPoint/ContactPoint.csproj b/ContactPoint/ContactPoint.csproj index b353c44..206e818 100644 --- a/ContactPoint/ContactPoint.csproj +++ b/ContactPoint/ContactPoint.csproj @@ -104,12 +104,6 @@ UserControl - - UserControl - - - CallNotifyControl.cs - True True @@ -161,9 +155,6 @@ AudioDevicesNotifyControl.cs - - CallNotifyControl.cs - ResXFileCodeGenerator CaptionStrings.Designer.cs diff --git a/ContactPoint/Controls/ColorSlider.cs b/ContactPoint/Controls/ColorSlider.cs index 5b79568..ec8195c 100644 --- a/ContactPoint/Controls/ColorSlider.cs +++ b/ContactPoint/Controls/ColorSlider.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; @@ -248,7 +248,8 @@ public int Maximum } } - private uint smallChange = 1; + #pragma warning disable 3003 + /// /// Gets or sets trackbar's small change. It affects how to behave when directional keys are pressed /// @@ -256,13 +257,7 @@ public int Maximum [Description("Set trackbar's small change")] [Category("ColorSlider")] [DefaultValue(1)] - public uint SmallChange - { - get { return smallChange; } - set { smallChange = value; } - } - - private uint largeChange = 5; + public uint SmallChange { get; set; } = 1; /// /// Gets or sets trackbar's large change. It affects how to behave when PageUp/PageDown keys are pressed @@ -271,11 +266,9 @@ public uint SmallChange [Description("Set trackbar's large change")] [Category("ColorSlider")] [DefaultValue(5)] - public uint LargeChange - { - get { return largeChange; } - set { largeChange = value; } - } + public uint LargeChange { get; set; } = 5; + + #pragma warning restore 3003 private bool drawFocusRectangle = true; /// @@ -935,12 +928,12 @@ protected override void OnKeyUp(KeyEventArgs e) { case Keys.Down: case Keys.Left: - SetProperValue(Value - (int)smallChange); + SetProperValue(Value - (int)SmallChange); if (Scroll != null) Scroll(this, new ScrollEventArgs(ScrollEventType.SmallDecrement, Value)); break; case Keys.Up: case Keys.Right: - SetProperValue(Value + (int)smallChange); + SetProperValue(Value + (int)SmallChange); if (Scroll != null) Scroll(this, new ScrollEventArgs(ScrollEventType.SmallIncrement, Value)); break; case Keys.Home: @@ -950,11 +943,11 @@ protected override void OnKeyUp(KeyEventArgs e) Value = barMaximum; break; case Keys.PageDown: - SetProperValue(Value - (int)largeChange); + SetProperValue(Value - (int)LargeChange); if (Scroll != null) Scroll(this, new ScrollEventArgs(ScrollEventType.LargeDecrement, Value)); break; case Keys.PageUp: - SetProperValue(Value + (int)largeChange); + SetProperValue(Value + (int)LargeChange); if (Scroll != null) Scroll(this, new ScrollEventArgs(ScrollEventType.LargeIncrement, Value)); break; } @@ -1070,4 +1063,4 @@ private static bool IsPointInRect(Point pt, Rectangle rect) #endregion } -} \ No newline at end of file +} diff --git a/ContactPoint/Controls/MainFormPhoneLineControl.cs b/ContactPoint/Controls/MainFormPhoneLineControl.cs index 41b3acf..872355e 100644 --- a/ContactPoint/Controls/MainFormPhoneLineControl.cs +++ b/ContactPoint/Controls/MainFormPhoneLineControl.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.Drawing; using System.Windows.Forms; @@ -7,26 +7,29 @@ namespace ContactPoint.Controls { - public class MainFormPhoneLineControl + class MainFormPhoneLineControl { private readonly ICore _core; private readonly EmptyDelegate _callOnStateChanged; private readonly EmptyDelegate _callOnInfoChanged; private readonly EmptyDelegate _callOnDurationChanged; private readonly Action _callOnRemoved; - private readonly KryptonCheckButton _controlButton; private readonly Control _controlCallerName; private readonly Control _controlCallerNumber; private readonly Control _controlDuration; private readonly Control _controlCallState; private readonly KryptonCheckButton _holdButton; - private ICall _call; + private bool _active = false; + + public int Line { get; } = -1; + public KryptonCheckButton ControlButton { get; } + public ICall Call { get { return _call; } set { - Trace.TraceInformation("Set call with sessionId '" + value?.SessionId + "' on MainFormPhoneLineControl" + _controlButton.Text); + Trace.TraceInformation("Set call with sessionId '" + value?.SessionId + "' on MainFormPhoneLineControl" + ControlButton.Text); if (_call != null) { @@ -34,25 +37,17 @@ public ICall Call _call.OnRemoved -= _callOnRemoved; _call.OnInfoChanged -= _callOnInfoChanged; _call.OnDurationChanged -= _callOnDurationChanged; + _call = null; } - if (value != null) + if (value != null && !value.IsDisposed) { - lock (value) - { - if (!value.IsDisposed) - { - _call = value; - _call.OnStateChanged += _callOnStateChanged; - _call.OnRemoved += _callOnRemoved; - _call.OnInfoChanged += _callOnInfoChanged; - _call.OnDurationChanged += _callOnDurationChanged; - } - else - _call = null; - } + _call = value; + _call.OnStateChanged += _callOnStateChanged; + _call.OnRemoved += _callOnRemoved; + _call.OnInfoChanged += _callOnInfoChanged; + _call.OnDurationChanged += _callOnDurationChanged; } - else _call = null; if (_active) { @@ -65,18 +60,11 @@ public ICall Call } } - private readonly int _line = -1; - public int Line - { - get { return _line; } - } - - private bool _active = false; public bool Active { get { return _active; } set { - Trace.TraceInformation("Activate MainFormPhoneLineControl" + _controlButton.Text); + Trace.TraceInformation("Activate MainFormPhoneLineControl" + ControlButton.Text); _active = value; @@ -91,8 +79,6 @@ public bool Active } } - public KryptonCheckButton ControlButton => _controlButton; - public MainFormPhoneLineControl( ICore core, int line, @@ -110,8 +96,8 @@ KryptonCheckButton holdButton _callOnRemoved = Call_OnRemoved; _core = core; - _line = line; - _controlButton = controlButton; + Line = line; + ControlButton = controlButton; _controlCallerName = controlCallerName; _controlCallerNumber = controlCallerNumber; _controlDuration = controlDuration; @@ -125,29 +111,38 @@ KryptonCheckButton holdButton void Call_OnDurationChanged() { - if (_controlButton.InvokeRequired) + if (!_active || _call == null) { - _controlButton.BeginInvoke(_callOnDurationChanged); + return; + } + + if (ControlButton.InvokeRequired) + { + ControlButton.BeginInvoke(_callOnDurationChanged); return; } - if (_active && _call != null && _call.ActiveDuration > TimeSpan.Zero) + if (_call.ActiveDuration > TimeSpan.Zero) { _controlDuration.Text = _call.ActiveDuration.ToFormattedString(); } + else if (_call.Duration > TimeSpan.Zero) + { + _controlDuration.Text = _call.Duration.ToFormattedString(); + } } void Call_OnStateChanged() { - if (_controlButton.InvokeRequired) + if (ControlButton.InvokeRequired) { - _controlButton.BeginInvoke(_callOnStateChanged); + ControlButton.BeginInvoke(_callOnStateChanged); return; } - Trace.TraceInformation("New call state on MainFormPhoneLineControl" + _controlButton.Text + ", new state: " + SipHelper.SipCallStateDecode(_call?.State ?? CallState.NULL)); + Trace.TraceInformation("New call state on MainFormPhoneLineControl" + ControlButton.Text + ", new state: " + SipHelper.SipCallStateDecode(_call?.State ?? CallState.NULL)); if (_active) { @@ -159,9 +154,9 @@ void Call_OnStateChanged() void Call_OnInfoChanged() { - if (_controlButton.InvokeRequired) + if (ControlButton.InvokeRequired) { - _controlButton.BeginInvoke(_callOnInfoChanged); + ControlButton.BeginInvoke(_callOnInfoChanged); return; } @@ -176,9 +171,9 @@ void Call_OnInfoChanged() void Call_OnRemoved(CallRemoveReason reason) { - if (_controlButton.InvokeRequired) + if (ControlButton.InvokeRequired) { - _controlButton.BeginInvoke(_callOnRemoved, reason); + ControlButton.BeginInvoke(_callOnRemoved, reason); return; } @@ -203,17 +198,15 @@ void _controlCallerNumber_TextChanged(object sender, EventArgs e) private readonly bool _callerNumberTrackChanges = true; void RefreshUI() { - //Logger.LogNotice("Refreshing UI on MainFormPhoneLineControl" + this._controlButton.Text); - if (Active) { - _controlButton.Checked = true; - _controlButton.StateCommon.Content.ShortText.Font = new Font(_controlButton.StateCommon.Content.ShortText.Font, FontStyle.Bold); + ControlButton.Checked = true; + ControlButton.StateCommon.Content.ShortText.Font = new Font(ControlButton.StateCommon.Content.ShortText.Font, FontStyle.Bold); } else { - _controlButton.Checked = false; - _controlButton.StateCommon.Content.ShortText.Font = new Font(_controlButton.StateCommon.Content.ShortText.Font, FontStyle.Regular); + ControlButton.Checked = false; + ControlButton.StateCommon.Content.ShortText.Font = new Font(ControlButton.StateCommon.Content.ShortText.Font, FontStyle.Regular); } if (_call != null && Active) @@ -224,7 +217,7 @@ void RefreshUI() if (_call.Contact != null && !string.IsNullOrWhiteSpace(_call.Contact.ShowedName)) _controlCallerName.Text = _call.Contact.ShowedName; - if (String.IsNullOrEmpty(_controlCallerNumber.Text)) + if (string.IsNullOrEmpty(_controlCallerNumber.Text)) { _controlCallerNumber.Text = _call.Number; @@ -235,6 +228,10 @@ void RefreshUI() { _controlDuration.Text = _call.ActiveDuration.ToFormattedString(); } + else if (_call.Duration > TimeSpan.Zero) + { + _controlDuration.Text = _call.Duration.ToFormattedString(); + } _holdButton.Checked = _call.State == CallState.HOLDING; @@ -277,6 +274,7 @@ void RefreshUI() static readonly Color DefaultOutgoingColor = Color.SkyBlue; static readonly Color DefaultHoldingColor = Color.Orange; static readonly Color DefaultConferenceColor = Color.HotPink; + void RefreshBackUI() { if (_call != null) @@ -304,36 +302,36 @@ void RefreshBackUI() void SetColorOnControlButton(Color color) { - var color1 = ControlPaint.LightLight(color); + var lightColor = ControlPaint.LightLight(color); - _controlButton.OverrideDefault.Back.Color2 = color; - _controlButton.OverrideDefault.Back.Color1 = color1; + ControlButton.OverrideDefault.Back.Color2 = color; + ControlButton.OverrideDefault.Back.Color1 = lightColor; - _controlButton.OverrideFocus.Back.Color2 = color; - _controlButton.OverrideFocus.Back.Color1 = color1; + ControlButton.OverrideFocus.Back.Color2 = color; + ControlButton.OverrideFocus.Back.Color1 = lightColor; - _controlButton.StateCommon.Back.Color2 = color; - _controlButton.StateCommon.Back.Color1 = color1; + ControlButton.StateCommon.Back.Color2 = color; + ControlButton.StateCommon.Back.Color1 = lightColor; - _controlButton.StateNormal.Back.Color2 = color; - _controlButton.StateNormal.Back.Color1 = color1; + ControlButton.StateNormal.Back.Color2 = color; + ControlButton.StateNormal.Back.Color1 = lightColor; - _controlButton.StatePressed.Back.Color2 = color; - _controlButton.StatePressed.Back.Color1 = color1; + ControlButton.StatePressed.Back.Color2 = color; + ControlButton.StatePressed.Back.Color1 = lightColor; - _controlButton.StateTracking.Back.Color2 = color; - _controlButton.StateTracking.Back.Color1 = color1; + ControlButton.StateTracking.Back.Color2 = color; + ControlButton.StateTracking.Back.Color1 = lightColor; - _controlButton.StateCheckedNormal.Back.Color2 = color; - _controlButton.StateCheckedNormal.Back.Color1 = color1; + ControlButton.StateCheckedNormal.Back.Color2 = color; + ControlButton.StateCheckedNormal.Back.Color1 = lightColor; - _controlButton.StateCheckedPressed.Back.Color2 = color; - _controlButton.StateCheckedPressed.Back.Color1 = color1; + ControlButton.StateCheckedPressed.Back.Color2 = color; + ControlButton.StateCheckedPressed.Back.Color1 = lightColor; - _controlButton.StateCheckedTracking.Back.Color2 = color; - _controlButton.StateCheckedTracking.Back.Color1 = color1; + ControlButton.StateCheckedTracking.Back.Color2 = color; + ControlButton.StateCheckedTracking.Back.Color1 = lightColor; - _controlButton.Update(); + ControlButton.Update(); } } } diff --git a/ContactPoint/Forms/MainForm.cs b/ContactPoint/Forms/MainForm.cs index 216d94b..13f14d8 100644 --- a/ContactPoint/Forms/MainForm.cs +++ b/ContactPoint/Forms/MainForm.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Drawing; using System.Runtime.InteropServices; @@ -186,15 +186,13 @@ private void MainForm_Load(object sender, EventArgs e) private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { - if (e.CloseReason != CloseReason.ApplicationExitCall && - e.CloseReason != CloseReason.WindowsShutDown && - e.CloseReason != CloseReason.TaskManagerClosing) + if (!e.CloseReason.HasFlag(CloseReason.ApplicationExitCall) && + !e.CloseReason.HasFlag(CloseReason.WindowsShutDown) && + !e.CloseReason.HasFlag(CloseReason.TaskManagerClosing)) { - if ((new QuestionForm(CaptionStrings.CaptionStrings.CloseQuestion)).ShowDialog() != DialogResult.OK && - e.CloseReason != CloseReason.WindowsShutDown) + if ((new QuestionForm(CaptionStrings.CaptionStrings.CloseQuestion)).ShowDialog() != DialogResult.OK) { e.Cancel = true; - return; } } @@ -571,14 +569,18 @@ private void btnHold_Click(object sender, EventArgs e) private void btnMinimize_Click(object sender, EventArgs e) { Focus(); - //this.ShowInTaskbar = false; Hide(); } private void btnClose_Click(object sender, EventArgs e) { Focus(); + +#if DEBUG + Close(); +#else Hide(); +#endif } private void kryptonCommandSettings_Execute(object sender, EventArgs e) diff --git a/ContactPoint/NotifyControls/CallNotifyControl.Designer.cs b/ContactPoint/NotifyControls/CallNotifyControl.Designer.cs deleted file mode 100644 index 48f854d..0000000 --- a/ContactPoint/NotifyControls/CallNotifyControl.Designer.cs +++ /dev/null @@ -1,233 +0,0 @@ -namespace ContactPoint.NotifyControls -{ - partial class CallNotifyControl - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Component Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.label3 = new System.Windows.Forms.Label(); - this.lblLine = new System.Windows.Forms.Label(); - this.btnCall = new ComponentFactory.Krypton.Toolkit.KryptonButton(); - this.btnDrop = new ComponentFactory.Krypton.Toolkit.KryptonButton(); - this.lblTime = new System.Windows.Forms.Label(); - this.lblDirection = new System.Windows.Forms.Label(); - this.lblName = new System.Windows.Forms.Label(); - this.lblNumber = new ComponentFactory.Krypton.Toolkit.KryptonLabel(); - this.SuspendLayout(); - // - // label3 - // - this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.label3.AutoSize = true; - this.label3.BackColor = System.Drawing.Color.Transparent; - this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.label3.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(55)))), ((int)(((byte)(55)))), ((int)(((byte)(55))))); - this.label3.Location = new System.Drawing.Point(262, 78); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(37, 13); - this.label3.TabIndex = 44; - this.label3.Text = "линия"; - this.label3.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // lblLine - // - this.lblLine.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.lblLine.BackColor = System.Drawing.Color.Transparent; - this.lblLine.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.lblLine.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(55)))), ((int)(((byte)(55)))), ((int)(((byte)(55))))); - this.lblLine.Location = new System.Drawing.Point(231, 78); - this.lblLine.Name = "lblLine"; - this.lblLine.Size = new System.Drawing.Size(33, 13); - this.lblLine.TabIndex = 43; - this.lblLine.Text = "1"; - this.lblLine.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // btnCall - // - this.btnCall.Location = new System.Drawing.Point(14, 72); - this.btnCall.Name = "btnCall"; - this.btnCall.OverrideDefault.Back.Color1 = System.Drawing.Color.FromArgb(((int)(((byte)(107)))), ((int)(((byte)(191)))), ((int)(((byte)(33))))); - this.btnCall.OverrideDefault.Back.Color2 = System.Drawing.Color.FromArgb(((int)(((byte)(7)))), ((int)(((byte)(161)))), ((int)(((byte)(68))))); - this.btnCall.OverrideDefault.Back.ColorStyle = ComponentFactory.Krypton.Toolkit.PaletteColorStyle.Linear; - this.btnCall.OverrideDefault.Back.Image = global::ContactPoint.Properties.Resources.call_green_big; - this.btnCall.OverrideDefault.Back.ImageAlign = ComponentFactory.Krypton.Toolkit.PaletteRectangleAlign.Control; - this.btnCall.OverrideDefault.Back.ImageStyle = ComponentFactory.Krypton.Toolkit.PaletteImageStyle.CenterMiddle; - this.btnCall.OverrideDefault.Border.Color1 = System.Drawing.Color.FromArgb(((int)(((byte)(28)))), ((int)(((byte)(167)))), ((int)(((byte)(61))))); - this.btnCall.OverrideDefault.Border.ColorStyle = ComponentFactory.Krypton.Toolkit.PaletteColorStyle.Solid; - this.btnCall.OverrideDefault.Border.DrawBorders = ((ComponentFactory.Krypton.Toolkit.PaletteDrawBorders)((((ComponentFactory.Krypton.Toolkit.PaletteDrawBorders.Top | ComponentFactory.Krypton.Toolkit.PaletteDrawBorders.Bottom) - | ComponentFactory.Krypton.Toolkit.PaletteDrawBorders.Left) - | ComponentFactory.Krypton.Toolkit.PaletteDrawBorders.Right))); - this.btnCall.OverrideDefault.Border.Rounding = 4; - this.btnCall.OverrideDefault.Border.Width = 1; - this.btnCall.Size = new System.Drawing.Size(50, 50); - this.btnCall.StateCommon.Back.Color1 = System.Drawing.Color.FromArgb(((int)(((byte)(107)))), ((int)(((byte)(191)))), ((int)(((byte)(33))))); - this.btnCall.StateCommon.Back.Color2 = System.Drawing.Color.FromArgb(((int)(((byte)(7)))), ((int)(((byte)(161)))), ((int)(((byte)(68))))); - this.btnCall.StateCommon.Back.ColorStyle = ComponentFactory.Krypton.Toolkit.PaletteColorStyle.Linear; - this.btnCall.StateCommon.Back.Image = global::ContactPoint.Properties.Resources.call_green_big; - this.btnCall.StateCommon.Back.ImageAlign = ComponentFactory.Krypton.Toolkit.PaletteRectangleAlign.Control; - this.btnCall.StateCommon.Back.ImageStyle = ComponentFactory.Krypton.Toolkit.PaletteImageStyle.CenterMiddle; - this.btnCall.StateCommon.Border.Color1 = System.Drawing.Color.FromArgb(((int)(((byte)(28)))), ((int)(((byte)(167)))), ((int)(((byte)(61))))); - this.btnCall.StateCommon.Border.Color2 = System.Drawing.Color.FromArgb(((int)(((byte)(81)))), ((int)(((byte)(183)))), ((int)(((byte)(42))))); - this.btnCall.StateCommon.Border.ColorStyle = ComponentFactory.Krypton.Toolkit.PaletteColorStyle.Solid; - this.btnCall.StateCommon.Border.DrawBorders = ((ComponentFactory.Krypton.Toolkit.PaletteDrawBorders)((((ComponentFactory.Krypton.Toolkit.PaletteDrawBorders.Top | ComponentFactory.Krypton.Toolkit.PaletteDrawBorders.Bottom) - | ComponentFactory.Krypton.Toolkit.PaletteDrawBorders.Left) - | ComponentFactory.Krypton.Toolkit.PaletteDrawBorders.Right))); - this.btnCall.StateCommon.Border.Rounding = 4; - this.btnCall.StateCommon.Border.Width = 1; - this.btnCall.StateDisabled.Back.ColorStyle = ComponentFactory.Krypton.Toolkit.PaletteColorStyle.Solid; - this.btnCall.StatePressed.Back.Color1 = System.Drawing.Color.FromArgb(((int)(((byte)(25)))), ((int)(((byte)(184)))), ((int)(((byte)(97))))); - this.btnCall.StatePressed.Back.Color2 = System.Drawing.Color.FromArgb(((int)(((byte)(136)))), ((int)(((byte)(207)))), ((int)(((byte)(58))))); - this.btnCall.StateTracking.Back.Color1 = System.Drawing.Color.FromArgb(((int)(((byte)(136)))), ((int)(((byte)(207)))), ((int)(((byte)(58))))); - this.btnCall.StateTracking.Back.Color2 = System.Drawing.Color.FromArgb(((int)(((byte)(25)))), ((int)(((byte)(184)))), ((int)(((byte)(97))))); - this.btnCall.TabIndex = 41; - this.btnCall.TabStop = false; - this.btnCall.Values.Text = ""; - this.btnCall.Click += new System.EventHandler(this.btnCall_Click); - // - // btnDrop - // - this.btnDrop.Location = new System.Drawing.Point(70, 72); - this.btnDrop.Name = "btnDrop"; - this.btnDrop.OverrideDefault.Back.Color1 = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(133)))), ((int)(((byte)(149))))); - this.btnDrop.OverrideDefault.Back.Color2 = System.Drawing.Color.FromArgb(((int)(((byte)(217)))), ((int)(((byte)(2)))), ((int)(((byte)(3))))); - this.btnDrop.OverrideDefault.Back.ColorStyle = ComponentFactory.Krypton.Toolkit.PaletteColorStyle.Linear; - this.btnDrop.OverrideDefault.Back.Image = global::ContactPoint.Properties.Resources.call_red_big; - this.btnDrop.OverrideDefault.Back.ImageAlign = ComponentFactory.Krypton.Toolkit.PaletteRectangleAlign.Control; - this.btnDrop.OverrideDefault.Back.ImageStyle = ComponentFactory.Krypton.Toolkit.PaletteImageStyle.CenterMiddle; - this.btnDrop.OverrideDefault.Border.Color1 = System.Drawing.Color.FromArgb(((int)(((byte)(195)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); - this.btnDrop.OverrideDefault.Border.ColorStyle = ComponentFactory.Krypton.Toolkit.PaletteColorStyle.Solid; - this.btnDrop.OverrideDefault.Border.DrawBorders = ((ComponentFactory.Krypton.Toolkit.PaletteDrawBorders)((((ComponentFactory.Krypton.Toolkit.PaletteDrawBorders.Top | ComponentFactory.Krypton.Toolkit.PaletteDrawBorders.Bottom) - | ComponentFactory.Krypton.Toolkit.PaletteDrawBorders.Left) - | ComponentFactory.Krypton.Toolkit.PaletteDrawBorders.Right))); - this.btnDrop.OverrideDefault.Border.Rounding = 4; - this.btnDrop.OverrideDefault.Border.Width = 1; - this.btnDrop.Size = new System.Drawing.Size(50, 50); - this.btnDrop.StateCommon.Back.Color1 = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(133)))), ((int)(((byte)(149))))); - this.btnDrop.StateCommon.Back.Color2 = System.Drawing.Color.FromArgb(((int)(((byte)(217)))), ((int)(((byte)(2)))), ((int)(((byte)(3))))); - this.btnDrop.StateCommon.Back.ColorStyle = ComponentFactory.Krypton.Toolkit.PaletteColorStyle.Linear; - this.btnDrop.StateCommon.Back.Image = global::ContactPoint.Properties.Resources.call_red_big; - this.btnDrop.StateCommon.Back.ImageAlign = ComponentFactory.Krypton.Toolkit.PaletteRectangleAlign.Control; - this.btnDrop.StateCommon.Back.ImageStyle = ComponentFactory.Krypton.Toolkit.PaletteImageStyle.CenterMiddle; - this.btnDrop.StateCommon.Border.Color1 = System.Drawing.Color.FromArgb(((int)(((byte)(195)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); - this.btnDrop.StateCommon.Border.ColorStyle = ComponentFactory.Krypton.Toolkit.PaletteColorStyle.Solid; - this.btnDrop.StateCommon.Border.DrawBorders = ((ComponentFactory.Krypton.Toolkit.PaletteDrawBorders)((((ComponentFactory.Krypton.Toolkit.PaletteDrawBorders.Top | ComponentFactory.Krypton.Toolkit.PaletteDrawBorders.Bottom) - | ComponentFactory.Krypton.Toolkit.PaletteDrawBorders.Left) - | ComponentFactory.Krypton.Toolkit.PaletteDrawBorders.Right))); - this.btnDrop.StateCommon.Border.Rounding = 4; - this.btnDrop.StateCommon.Border.Width = 1; - this.btnDrop.StateDisabled.Back.ColorStyle = ComponentFactory.Krypton.Toolkit.PaletteColorStyle.Solid; - this.btnDrop.StatePressed.Back.Color1 = System.Drawing.Color.FromArgb(((int)(((byte)(227)))), ((int)(((byte)(5)))), ((int)(((byte)(8))))); - this.btnDrop.StatePressed.Back.Color2 = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(159)))), ((int)(((byte)(173))))); - this.btnDrop.StateTracking.Back.Color1 = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(159)))), ((int)(((byte)(173))))); - this.btnDrop.StateTracking.Back.Color2 = System.Drawing.Color.FromArgb(((int)(((byte)(227)))), ((int)(((byte)(5)))), ((int)(((byte)(8))))); - this.btnDrop.TabIndex = 42; - this.btnDrop.TabStop = false; - this.btnDrop.Values.Text = ""; - this.btnDrop.Click += new System.EventHandler(this.btnDrop_Click); - // - // lblTime - // - this.lblTime.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.lblTime.BackColor = System.Drawing.Color.Transparent; - this.lblTime.ForeColor = System.Drawing.Color.DimGray; - this.lblTime.Location = new System.Drawing.Point(222, 97); - this.lblTime.Name = "lblTime"; - this.lblTime.Size = new System.Drawing.Size(76, 13); - this.lblTime.TabIndex = 40; - this.lblTime.Text = "00:00:00"; - this.lblTime.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // lblDirection - // - this.lblDirection.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.lblDirection.BackColor = System.Drawing.Color.Transparent; - this.lblDirection.ForeColor = System.Drawing.Color.DimGray; - this.lblDirection.Location = new System.Drawing.Point(141, 110); - this.lblDirection.Name = "lblDirection"; - this.lblDirection.Size = new System.Drawing.Size(157, 13); - this.lblDirection.TabIndex = 39; - this.lblDirection.Text = "Входящий"; - this.lblDirection.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // lblName - // - this.lblName.AutoSize = true; - this.lblName.BackColor = System.Drawing.Color.Transparent; - this.lblName.Font = new System.Drawing.Font("Microsoft Sans Serif", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.lblName.ForeColor = System.Drawing.Color.DimGray; - this.lblName.Location = new System.Drawing.Point(14, 14); - this.lblName.Name = "lblName"; - this.lblName.Size = new System.Drawing.Size(211, 18); - this.lblName.TabIndex = 38; - this.lblName.Text = "Евтушенко Александр (Киев)"; - // - // lblNumber - // - this.lblNumber.Location = new System.Drawing.Point(8, 35); - this.lblNumber.Name = "lblNumber"; - this.lblNumber.Size = new System.Drawing.Size(166, 32); - this.lblNumber.StateCommon.ShortText.Color1 = System.Drawing.Color.Black; - this.lblNumber.StateCommon.ShortText.Color2 = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); - this.lblNumber.StateCommon.ShortText.ColorAngle = 270F; - this.lblNumber.StateCommon.ShortText.ColorStyle = ComponentFactory.Krypton.Toolkit.PaletteColorStyle.Switch50; - this.lblNumber.StateNormal.ShortText.Color1 = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); - this.lblNumber.StateNormal.ShortText.Font = new System.Drawing.Font("Arial", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.lblNumber.TabIndex = 37; - this.lblNumber.Values.Text = "80505690256"; - // - // CallNotifyControl - // - this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; - this.BackColor = System.Drawing.Color.White; - this.Controls.Add(this.label3); - this.Controls.Add(this.lblLine); - this.Controls.Add(this.btnCall); - this.Controls.Add(this.btnDrop); - this.Controls.Add(this.lblTime); - this.Controls.Add(this.lblDirection); - this.Controls.Add(this.lblName); - this.Controls.Add(this.lblNumber); - this.Margin = new System.Windows.Forms.Padding(0); - this.Name = "CallNotifyControl"; - this.Size = new System.Drawing.Size(307, 136); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label label3; - private System.Windows.Forms.Label lblLine; - private ComponentFactory.Krypton.Toolkit.KryptonButton btnCall; - private ComponentFactory.Krypton.Toolkit.KryptonButton btnDrop; - private System.Windows.Forms.Label lblTime; - private System.Windows.Forms.Label lblDirection; - private System.Windows.Forms.Label lblName; - private ComponentFactory.Krypton.Toolkit.KryptonLabel lblNumber; - } -} diff --git a/ContactPoint/NotifyControls/CallNotifyControl.cs b/ContactPoint/NotifyControls/CallNotifyControl.cs deleted file mode 100644 index f002b16..0000000 --- a/ContactPoint/NotifyControls/CallNotifyControl.cs +++ /dev/null @@ -1,129 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Drawing; -using System.Data; -using System.Globalization; -using System.Text; -using System.Windows.Forms; -using ContactPoint.Common; -using ContactPoint.BaseDesign.BaseNotifyControls; - -namespace ContactPoint.NotifyControls -{ - public partial class CallNotifyControl : NotifyControl - { - private ICall _call; - - public ICall Call - { - get { return this._call; } - } - - public CallNotifyControl(ICall call) - { - InitializeComponent(); - - lock (call) - { - _call = call; - - _call.OnRemoved += new Action(_call_OnRemoved); - _call.OnStateChanged += new EmptyDelegate(_call_OnStateChanged); - _call.OnInfoChanged += new EmptyDelegate(_call_OnInfoChanged); - _call.OnDurationChanged += new EmptyDelegate(_call_OnDurationChanged); - } - - RefreshUI(); - } - - void _call_OnDurationChanged() - { - if (InvokeRequired) - { - BeginInvoke(new EmptyDelegate(_call_OnDurationChanged)); - - return; - } - - this.lblTime.Text = _call.Duration.ToFormattedString(); - } - - void _call_OnInfoChanged() - { - if (InvokeRequired) - { - BeginInvoke(new EmptyDelegate(_call_OnInfoChanged)); - - return; - } - - RefreshUI(); - } - - void _call_OnStateChanged() - { - if (InvokeRequired) - { - BeginInvoke(new EmptyDelegate(_call_OnStateChanged)); - - return; - } - - if (this._call.State == CallState.ACTIVE && ParentForm != null) - Close(); - } - - void _call_OnRemoved(CallRemoveReason reason) - { - if (InvokeRequired) - { - BeginInvoke(new Action(_call_OnRemoved), reason); - - return; - } - - if (Handle == IntPtr.Zero) _call = null; - else Close(); - } - - void RefreshUI() - { - this.lblLine.Text = this._call.Line >= 0 ? (this._call.Line + 1).ToString() : ""; - this.lblName.Text = this._call.Name.Length > 0 ? this._call.Name : "-"; - this.lblNumber.Text = this._call.Number; - } - - private void btnCall_Click(object sender, EventArgs e) - { - _call.Answer(); - - Close(); - } - - private void btnDrop_Click(object sender, EventArgs e) - { - _call.Drop(); - - Close(); - } - - public override void OnShow() - { - if (_call == null || _call.IsDisposed) Close(); - - base.OnShow(); - } - - public override void OnClosing() - { - if (this._call != null) - { - this._call.OnRemoved -= _call_OnRemoved; - this._call.OnStateChanged -= _call_OnStateChanged; - this._call.OnInfoChanged -= _call_OnInfoChanged; - this._call.OnDurationChanged -= _call_OnDurationChanged; - } - } - } -} diff --git a/ContactPoint/NotifyControls/CallNotifyControl.resx b/ContactPoint/NotifyControls/CallNotifyControl.resx deleted file mode 100644 index 1af7de1..0000000 --- a/ContactPoint/NotifyControls/CallNotifyControl.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/ContactPoint/Program.cs b/ContactPoint/Program.cs index a327767..184ebb7 100644 --- a/ContactPoint/Program.cs +++ b/ContactPoint/Program.cs @@ -1,4 +1,4 @@ -// ReSharper disable InconsistentNaming +// ReSharper disable InconsistentNaming using System; using System.ComponentModel; @@ -101,8 +101,11 @@ static void Main() // the Assert permission in this stack frame. perm.Assert(); +#if DEBUG + System.Windows.Forms.Timer watchdogTimer; +#endif + ThreadPool.SetMaxThreads(50, 200); - System.Windows.Forms.Timer watcherTimer; bool mutexAquired = false; using (var mutex = new Mutex(false, mutex_id)) { @@ -149,10 +152,9 @@ static void Main() #endif #if DEBUG - // Watcher initialization - watcherTimer = new System.Windows.Forms.Timer { Interval = 3000 }; - watcherTimer.Tick += (s, e) => { _watcherLastActivity = DateTime.Now; }; - watcherTimer.Start(); + watchdogTimer = new System.Windows.Forms.Timer { Interval = 3000 }; + watchdogTimer.Tick += (s, e) => { _watcherLastActivity = DateTime.Now; }; + watchdogTimer.Start(); _watcherTargetThread = Thread.CurrentThread; _watcherLastActivity = DateTime.Now; @@ -266,7 +268,7 @@ static void Main() #if DEBUG _watcherThreadShutdown = true; - watcherTimer.Stop(); + watchdogTimer.Stop(); #endif } } @@ -473,6 +475,7 @@ static void TakeScreenshot(ExceptionReporter.ExceptionReporter reporter) #region Debug Thread watcher #if DEBUG +#pragma warning disable 0618 private static DateTime _watcherLastActivity = DateTime.Now; private static Thread _watcherTargetThread = null; private static bool _watcherThreadShutdown = false; @@ -511,6 +514,7 @@ static StackTrace GetStackTrace(Thread targetThread) ready.Wait(); targetThread.Suspend(); + try { stackTrace = new StackTrace(targetThread, true); } catch { /* Deadlock */ } finally @@ -521,6 +525,7 @@ static StackTrace GetStackTrace(Thread targetThread) return stackTrace; } +#pragma warning restore 0618 #endif #endregion } diff --git a/ContactPoint/Properties/AssemblyInfo.cs b/ContactPoint/Properties/AssemblyInfo.cs index 83740a5..e84545f 100644 --- a/ContactPoint/Properties/AssemblyInfo.cs +++ b/ContactPoint/Properties/AssemblyInfo.cs @@ -1,6 +1,6 @@ -using System.Reflection; +using System.Reflection; using System.Runtime.InteropServices; -[assembly: AssemblyTitle("ContactPoint.exe")] +[assembly: AssemblyTitle("IP Phone")] [assembly: AssemblyDescription("ContactPoint IP Phone")] [assembly: ComVisible(false)] diff --git a/ContactPoint/Services/AutoAnswerService.cs b/ContactPoint/Services/AutoAnswerService.cs index 3e59f7a..6b2b4cc 100644 --- a/ContactPoint/Services/AutoAnswerService.cs +++ b/ContactPoint/Services/AutoAnswerService.cs @@ -1,5 +1,6 @@ -using ContactPoint.Common; +using ContactPoint.Common; using System.Timers; +using System.Linq; namespace ContactPoint.Services { @@ -83,13 +84,10 @@ void CallManager_OnIncomingCall(ICall call) { if (!_active || _callToPickup != null) return; - lock (call) + if (CanPickupCall(call)) { - if (CanPickupCall(call)) - { - _callToPickup = call; - _timer.Start(); - } + _callToPickup = call; + _timer.Start(); } } @@ -118,13 +116,10 @@ void _timer_Elapsed(object sender, ElapsedEventArgs e) bool CanPickupCall(ICall callToPickup) { - foreach (var call in Core.CallManager) - if (call != callToPickup) - if (call.State == CallState.ACTIVE || call.State == CallState.HOLDING || // Check if we have an active call - call.State == CallState.CONNECTING || call.State == CallState.ALERTING) // Check if we have an outgoing call - return false; - - return true; + return !Core.CallManager.ToArray().Any(call => + call != callToPickup && ( + call.State == CallState.ACTIVE || call.State == CallState.HOLDING || // Check if we have an active call + call.State == CallState.CONNECTING || call.State == CallState.ALERTING)); // Check if we have an outgoing call } } } diff --git a/ExceptionReporter/ExceptionReporter/ExceptionReporter.Core.csproj b/ExceptionReporter/ExceptionReporter/ExceptionReporter.Core.csproj index 0a13c7b..8e3f4f0 100644 --- a/ExceptionReporter/ExceptionReporter/ExceptionReporter.Core.csproj +++ b/ExceptionReporter/ExceptionReporter/ExceptionReporter.Core.csproj @@ -1,4 +1,4 @@ - + Debug @@ -12,7 +12,8 @@ ExceptionReporter.Core v4.5.2 512 - warning.ico + + false @@ -22,7 +23,7 @@ ..\..\..\Binaries\ DEBUG;TRACE prompt - 4 + 0 AnyCPU @@ -35,10 +36,9 @@ true ..\..\..\Binaries\ prompt - 4 + 0 AnyCPU AllRules.ruleset - false false true diff --git a/ExceptionReporter/ExceptionReporter/Properties/AssemblyInfo.cs b/ExceptionReporter/ExceptionReporter/Properties/AssemblyInfo.cs index c703e05..30a6855 100644 --- a/ExceptionReporter/ExceptionReporter/Properties/AssemblyInfo.cs +++ b/ExceptionReporter/ExceptionReporter/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -using System.Reflection; +using System.Reflection; using System.Runtime.InteropServices; [assembly: AssemblyTitle("ExceptionReporter.Core.dll")] diff --git a/ExceptionReporter/Win32Mapi/Win32Mapi.csproj b/ExceptionReporter/Win32Mapi/Win32Mapi.csproj index d1c437f..f881597 100644 --- a/ExceptionReporter/Win32Mapi/Win32Mapi.csproj +++ b/ExceptionReporter/Win32Mapi/Win32Mapi.csproj @@ -46,13 +46,13 @@ DEBUG;TRACE prompt 4 - x86 + AnyCPU AllRules.ruleset false pdbonly - true + false ..\..\..\Binaries\ @@ -61,7 +61,7 @@ AnyCPU AllRules.ruleset false - true + false true diff --git a/SipekSDK/SipekSdk/Common/CallControl/callManager.cs b/SipekSDK/SipekSdk/Common/CallControl/callManager.cs index 1f05410..a6c9e00 100644 --- a/SipekSDK/SipekSdk/Common/CallControl/callManager.cs +++ b/SipekSDK/SipekSdk/Common/CallControl/callManager.cs @@ -442,7 +442,7 @@ public int CreateSmartOutboundCall(string number, int accountId, Sipek.Sip.SipHe call.Session = newsession; _calls.Add(newsession, call); } - catch (ArgumentException e) + catch { // previous call not released () // first release old one diff --git a/SipekSDK/SipekSdk/Common/CallControl/callStateMachine.cs b/SipekSDK/SipekSdk/Common/CallControl/callStateMachine.cs index 95d6a0a..c93d0dc 100644 --- a/SipekSDK/SipekSdk/Common/CallControl/callStateMachine.cs +++ b/SipekSDK/SipekSdk/Common/CallControl/callStateMachine.cs @@ -53,8 +53,8 @@ public class CStateMachine : IStateMachine private DateTime _timestamp; private CCallManager _manager; // Timers - protected ITimer _noreplyTimer; - protected ITimer _noresponseTimer; + private ITimer _noreplyTimer; + private ITimer _noresponseTimer; private int _session = -1; private ICallProxyInterface _sigProxy; @@ -388,7 +388,7 @@ internal override bool StartTimer(ETimerType ttype) break; //case ETimerType.ERELEASED: // success = _releasedTimer.Start(); - break; + // break; case ETimerType.ENORESPONSE: success = _noresponseTimer.Start(); break; @@ -410,7 +410,7 @@ internal override bool StopTimer(ETimerType ttype) break; //case ETimerType.ERELEASED: // success = _releasedTimer.Stop(); - break; + // break; case ETimerType.ENORESPONSE: success = _noresponseTimer.Stop(); break; diff --git a/SipekSDK/SipekSdk/Sip/pjsipMediaPlayerProxy.cs b/SipekSDK/SipekSdk/Sip/pjsipMediaPlayerProxy.cs index 5afd854..345582c 100644 --- a/SipekSDK/SipekSdk/Sip/pjsipMediaPlayerProxy.cs +++ b/SipekSDK/SipekSdk/Sip/pjsipMediaPlayerProxy.cs @@ -1,15 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Text; using System.Threading.Tasks; using Sipek.Common; -using System.ComponentModel; using System.Runtime.InteropServices; namespace Sipek.Sip { internal class pjsipMediaPlayerProxy : IMediaProxyInterface { + private readonly object _lockObj = new object(); #if LINUX internal const string PJSIP_DLL = "libpjsipDll.so"; @@ -35,7 +32,7 @@ public int SessionId get { return _sessionId; } set { - lock (this) + lock (_lockObj) { if (_isPlaying) Task.Factory.StartNew(() => stopTone(), TaskCreationOptions.PreferFairness); @@ -46,7 +43,7 @@ public int SessionId public int playTone(ETones toneId) { - lock (this) + lock (_lockObj) { if (_isPlaying) { @@ -70,7 +67,7 @@ public int playTone(ETones toneId) public int stopTone() { - lock (this) + lock (_lockObj) { if (!_isPlaying) return 0; diff --git a/SipekSDK/SipekSdk/Sip/pjsipWrapper.cs b/SipekSDK/SipekSdk/Sip/pjsipWrapper.cs index 3bab4c2..f14e778 100644 --- a/SipekSDK/SipekSdk/Sip/pjsipWrapper.cs +++ b/SipekSDK/SipekSdk/Sip/pjsipWrapper.cs @@ -126,7 +126,7 @@ public override bool IsInitialized #region Variables // config structure (used for special configuration options) - public SipConfigStruct ConfigMore = SipConfigStruct.Instance; + public SipConfigStruct ConfigMore { get; private set; } = SipConfigStruct.Instance; #endregion Variables diff --git a/SipekSDK/SipekSdk/SipekSdk.csproj b/SipekSDK/SipekSdk/SipekSdk.csproj index 4dec996..b3268a2 100644 --- a/SipekSDK/SipekSdk/SipekSdk.csproj +++ b/SipekSDK/SipekSdk/SipekSdk.csproj @@ -50,6 +50,7 @@ AllRules.ruleset true false + 3005 pdbonly @@ -64,6 +65,7 @@ true false Auto + 3005 true