context: /*
    KeePass Password Safe - The Open-Source Password Manager
    Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
  
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
  
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
  
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
  
  using System;
  using System.Collections.Generic;
  using System.Text;
  using System.Text.RegularExpressions;
  using System.Windows.Forms;
  using System.Windows.Forms.VisualStyles;
  using System.Runtime.InteropServices;
  using System.Diagnostics;
  using System.Drawing;
  using System.Drawing.Drawing2D;
  using System.Drawing.Imaging;
  using System.Threading;
  using System.IO;
  using System.Media;
  
  using Microsoft.Win32;
  
  using KeePass.App;
  using KeePass.App.Configuration;
  using KeePass.Native;
  using KeePass.Resources;
  using KeePass.Util;
  using KeePass.Util.Spr;
  
  using KeePassLib;
  using KeePassLib.Collections;
  using KeePassLib.Delegates;
  using KeePassLib.Interfaces;
  using KeePassLib.Utility;
  
  namespace KeePass.UI
  {
  	public static class UIUtil
  	{
  		private static ToolStripRenderer m_tsrOverride = null;
  		public static ToolStripRenderer ToolStripRendererOverride
  		{
  			get { return m_tsrOverride; }
  			set { m_tsrOverride = value; }
  		}
  
  		private static bool m_bVistaStyleLists = false;
  		public static bool VistaStyleListsSupported
  		{
  			get { return m_bVistaStyleLists; }
  		}
  
  		public static void Initialize(bool bReinitialize)
  		{
  			bool bVisualStyles = true;
  			try { bVisualStyles = VisualStyleRenderer.IsSupported; }
  			catch(Exception) { Debug.Assert(false); bVisualStyles = false; }
  
  			if(m_tsrOverride != null) ToolStripManager.Renderer = m_tsrOverride;
  			else if(Program.Config.UI.UseCustomToolStripRenderer && bVisualStyles)
  			{
  				ToolStripManager.Renderer = new CustomToolStripRendererEx();
  				Debug.Assert(ToolStripManager.RenderMode == ToolStripManagerRenderMode.Custom);
  			}
  			else if(bReinitialize)
  				ToolStripManager.Renderer = new ToolStripProfessionalRenderer();
  
  			m_bVistaStyleLists = (WinUtil.IsAtLeastWindowsVista &&
  				(Environment.Version.Major >= 2));
  		}
  
  		public static void RtfSetSelectionLink(RichTextBox richTextBox)
  		{
  			try
  			{
  				NativeMethods.CHARFORMAT2 cf = new NativeMethods.CHARFORMAT2();
  				cf.cbSize = (uint)Marshal.SizeOf(cf);
  
  				cf.dwMask = NativeMethods.CFM_LINK;
  				cf.dwEffects = NativeMethods.CFE_LINK;
  
  				IntPtr wParam = (IntPtr)NativeMethods.SCF_SELECTION;
  				IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf));
  				Marshal.StructureToPtr(cf, lParam, false);
  
  				NativeMethods.SendMessage(richTextBox.Handle,
  					NativeMethods.EM_SETCHARFORMAT, wParam, lParam);
  
  				Marshal.FreeCoTaskMem(lParam);
  			}
  			catch(Exception) { Debug.Assert(false); }
  		}
  
  		private static NativeMethods.CHARFORMAT2 RtfGetCharFormat(RichTextBox rtb)
  		{
  			NativeMethods.CHARFORMAT2 cf = new NativeMethods.CHARFORMAT2();
  			cf.cbSize = (uint)Marshal.SizeOf(cf);
  
  			try
  			{
  				IntPtr wParam = (IntPtr)NativeMethods.SCF_SELECTION;
  				IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf));
  				Marshal.StructureToPtr(cf, lParam, false);
  
  				NativeMethods.SendMessage(rtb.Handle,
  					NativeMethods.EM_GETCHARFORMAT, wParam, lParam);
  
  				cf = (NativeMethods.CHARFORMAT2)Marshal.PtrToStructure(lParam,
  					typeof(NativeMethods.CHARFORMAT2));
  				Marshal.FreeCoTaskMem(lParam);
  			}
  			catch(Exception) { Debug.Assert(false); }
  
  			return cf;
  		}
  
  		public static bool RtfIsFirstCharLink(RichTextBox rtb)
  		{
  			NativeMethods.CHARFORMAT2 cf = RtfGetCharFormat(rtb);
  			return ((cf.dwEffects & NativeMethods.CFE_LINK) != 0);
  		}
  
  		public static void RtfLinkifyExtUrls(RichTextBox richTextBox, bool bResetSelection)
  		{
  			const string strProto = "cmd://";
  
  			try
  			{
  				string strText = richTextBox.Text;
  
  				int nOffset = 0;
  				while(nOffset < strText.Length)
  				{
  					int nStart = strText.IndexOf(strProto, nOffset, StrUtil.CaseIgnoreCmp);
  					if(nStart < 0) break;
  
  					richTextBox.Select(nStart, UrlUtil.GetUrlLength(strText, nStart));
  					RtfSetSelectionLink(richTextBox);
  
  					nOffset = nStart + 1;
  				}
  
  				if(bResetSelection) richTextBox.Select(0, 0);
  			}
  			catch(Exception) { Debug.Assert(false); }
  		}
  
  		public static void RtfLinkifyText(RichTextBox rtb, string strLinkText,
  			bool bResetTempSelection)
  		{
  			if(rtb == null) throw new ArgumentNullException("rtb");
  			if(string.IsNullOrEmpty(strLinkText)) return; // No assert
  
  			try
  			{
  				string strText = rtb.Text;
  				int nStart = strText.IndexOf(strLinkText);
  
  				if(nStart >= 0)
  				{
  					rtb.Select(nStart, strLinkText.Length);
  					RtfSetSelectionLink(rtb);
  
  					if(bResetTempSelection) rtb.Select(0, 0);
  				}
  			}
  			catch(Exception) { Debug.Assert(false); }
  		}
  
  		public static void RtfLinkifyReferences(RichTextBox rtb,
  			bool bResetTempSelection)
  		{
  			try
  			{
  				string str = rtb.Text;
  
  				int iOffset = 0;
  				while(true)
  				{
  					int iStart = str.IndexOf(SprEngine.StrRefStart, iOffset,
  						StrUtil.CaseIgnoreCmp);
  					if(iStart < 0) break;
  					int iEnd = str.IndexOf(SprEngine.StrRefEnd, iStart + 1,
  						StrUtil.CaseIgnoreCmp);
  					if(iEnd <= iStart) break;
  
  					string strRef = str.Substring(iStart, iEnd - iStart + 1);
  					RtfLinkifyText(rtb, strRef, bResetTempSelection);
  
  					iOffset = iStart + 1;
  				}
  			}
  
gt: 			catch(Exception) { Debug.Assert(false); }