1 /*
2   KeePass Password Safe - The Open-Source Password Manager
3   Copyright (C) 2003-2021 Dominik Reichl <dominik.reichl@t-online.de>
4 
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2 of the License, or
8   (at your option) any later version.
9 
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14 
15   You should have received a copy of the GNU General Public License
16   along with this program; if not, write to the Free Software
17   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19 
20 using System;
21 using System.Collections.Generic;
22 using System.ComponentModel;
23 using System.Diagnostics;
24 using System.Drawing;
25 using System.Text;
26 using System.Windows.Forms;
27 
28 using KeePass;
29 
30 using KeePassLib;
31 using KeePassLib.Native;
32 using KeePassLib.Utility;
33 
34 namespace KeePass.UI
35 {
36 	public sealed class NotifyIconEx
37 	{
38 		private NotifyIcon m_ntf = null;
39 
40 		private Icon m_ico = null; // Property value
41 		private Icon m_icoShell = null; // Private copy
42 
43 		public NotifyIcon NotifyIcon { get { return m_ntf; } }
44 
45 		public ContextMenuStrip ContextMenuStrip
46 		{
47 			get
48 			{
49 				try { if(m_ntf != null) return m_ntf.ContextMenuStrip; }
50 				catch(Exception) { Debug.Assert(false); }
51 				return null;
52 			}
53 			set
54 			{
55 				try { if(m_ntf != null) m_ntf.ContextMenuStrip = value; }
56 				catch(Exception) { Debug.Assert(false); }
57 			}
58 		}
59 
60 		public bool Visible
61 		{
62 			get
63 			{
64 				try { if(m_ntf != null) return m_ntf.Visible; }
65 				catch(Exception) { Debug.Assert(false); }
66 				return false;
67 			}
68 			set
69 			{
70 				try { if(m_ntf != null) m_ntf.Visible = value; }
71 				catch(Exception) { Debug.Assert(false); }
72 			}
73 		}
74 
75 		public Icon Icon
76 		{
77 			get { return m_ico; }
78 			set
79 			{
80 				if(value == m_ico) return; // Avoid small icon recreation
81 
82 				m_ico = value;
83 				RefreshShellIcon();
84 			}
85 		}
86 
87 		public string Text
88 		{
89 			get
90 			{
91 				try { if(m_ntf != null) return m_ntf.Text; }
92 				catch(Exception) { Debug.Assert(false); }
93 				return string.Empty;
94 			}
95 			set
96 			{
97 				try { if(m_ntf != null) m_ntf.Text = value; }
98 				catch(Exception) { Debug.Assert(false); }
99 			}
100 		}
101 
NotifyIconEx(IContainer container)102 		public NotifyIconEx(IContainer container)
103 		{
104 			try
105 			{
106 				bool bNtf = true;
107 				if(NativeLib.GetPlatformID() == PlatformID.MacOSX)
108 					bNtf = !MonoWorkarounds.IsRequired(1574);
109 				else
110 				{
111 					DesktopType t = NativeLib.GetDesktopType();
112 					if((t == DesktopType.Unity) || (t == DesktopType.Pantheon))
113 						bNtf = !MonoWorkarounds.IsRequired(1354);
114 				}
115 
116 				if(bNtf) m_ntf = new NotifyIcon(container);
117 			}
118 			catch(Exception) { Debug.Assert(false); }
119 		}
120 
SetHandlers(EventHandler ehClick, EventHandler ehDoubleClick, MouseEventHandler ehMouseDown)121 		public void SetHandlers(EventHandler ehClick, EventHandler ehDoubleClick,
122 			MouseEventHandler ehMouseDown)
123 		{
124 			if(m_ntf == null) return;
125 
126 			try
127 			{
128 				if(ehClick != null) m_ntf.Click += ehClick;
129 				if(ehDoubleClick != null) m_ntf.DoubleClick += ehDoubleClick;
130 				if(ehMouseDown != null) m_ntf.MouseDown += ehMouseDown;
131 			}
132 			catch(Exception) { Debug.Assert(false); }
133 		}
134 
RefreshShellIcon()135 		internal void RefreshShellIcon()
136 		{
137 			if(m_ntf == null) return;
138 
139 			try
140 			{
141 				Icon icoToDispose = m_icoShell;
142 				try
143 				{
144 					if(m_ico != null)
145 					{
146 						Size sz = UIUtil.GetSmallIconSize();
147 
148 						if(Program.Config.UI.TrayIcon.GrayIcon)
149 						{
150 							using(Bitmap bmpOrg = UIUtil.IconToBitmap(m_ico,
151 								sz.Width, sz.Height))
152 							{
153 								using(Bitmap bmpGray = UIUtil.CreateGrayImage(
154 									bmpOrg))
155 								{
156 									m_icoShell = UIUtil.BitmapToIcon(bmpGray);
157 								}
158 							}
159 						}
160 						else m_icoShell = new Icon(m_ico, sz);
161 
162 						m_ntf.Icon = m_icoShell;
163 					}
164 					else m_ntf.Icon = null;
165 				}
166 				catch(Exception)
167 				{
168 					Debug.Assert(false);
169 					m_ntf.Icon = m_ico;
170 				}
171 
172 				if(icoToDispose != null) icoToDispose.Dispose();
173 			}
174 			catch(Exception) { Debug.Assert(false); }
175 		}
176 	}
177 }
178