////////////////////////////////////////////////////
// File - Options.cpp
// Autor - Michael Mac
// Contact - GreenSequoia@wp.pl
// Description - Implementation of the Options and OptionsDlg classes
////////////////////////////////////////////////////
#include "stdafx.h"
#include "Options.h"
#include "MainForm.h"
using namespace System::Drawing;
#pragma warning( disable : 4506 ) // Disable warning C4506
namespace MaChat
{
////////////////////////////////////////////////////
// MaChat::Options
////////////////////////////////////////////////////
// Constructor
Options::Options( String* strXmlFileName )
{
// Load Xml file which contains options
m_xmlDoc = new XmlDocument( );
m_xmlDoc->Load( strXmlFileName );
}
// Save all modification to the disk
void Options::Save ( String* strXmlFileName )
{
m_xmlDoc->Save( strXmlFileName );
}
////////////////////////////////////////////////////
// MaChat::OptionsDlg
////////////////////////////////////////////////////
// Constructor
OptionsDlg::OptionsDlg( mshtml::IHTMLStyleSheet* sheet )
{
m_sheetStyle = sheet;
CreateUI();
// LoadOptions
m_txtNickName->Text = GetOpt()->UserNickName;
m_checkCustomIcon->Checked = GetOpt()->SpecificUserIcon;
UpdateIcon();
}
// Create and config UI
////////////////////////////////////////////////////
void OptionsDlg::CreateUI ()
{
// Create a ResourceManager class
m_mResources = new System::Resources::ResourceManager( __typeof(OptionsDlg) );
this->Text = GetString( "this.Name" );
this->ShowInTaskbar = false;
// Create TabControl and TabPages
Crownwood::Magic::Controls::TabControl* tabOptions = new Crownwood::Magic::Controls::TabControl();
tabOptions->Appearance = (Crownwood::Magic::Controls::TabControl::VisualAppearance)2;
tabOptions->Dock = DockStyle::Fill;
tabOptions->HotTrack = true;
tabOptions->IDEPixelBorder = true;
tabOptions->ShowArrows = true;
tabOptions->Style = Crownwood::Magic::Common::VisualStyle::IDE;
tabOptions->PositionTop = true;
Crownwood::Magic::Controls::TabPage* tabGeneral =
new Crownwood::Magic::Controls::TabPage( GetString( "TabPage.General" ) );
Crownwood::Magic::Controls::TabPage* tabUser =
new Crownwood::Magic::Controls::TabPage( GetString( "TabPage.User" ) );
Crownwood::Magic::Controls::TabPage* tabNetwork =
new Crownwood::Magic::Controls::TabPage( GetString( "TabPage.Network" ) );
// Create user page
Label* labelLanguage = new Label();
labelLanguage->AutoSize = true;
labelLanguage->Text = GetString( "TabPage.General.Language" );
labelLanguage->Location = System::Drawing::Point(8, 0);
// Language ComboBox
m_comboLanguages = new ComboBox();
m_comboLanguages->Location = System::Drawing::Point(8, 16);
m_comboLanguages->DropDownStyle = ComboBoxStyle::DropDownList;
m_comboLanguages->Items->Add( GetString( "TabPage.General.Language.Neutral" ) );
m_comboLanguages->Items->Add( GetString( "TabPage.General.Language.Polish" ) );
if ( GetOpt()->Language == 0 ) m_comboLanguages->SelectedIndex = 0;
else m_comboLanguages->SelectedIndex = 1;
tabGeneral->Controls->Add( m_comboLanguages );
tabGeneral->Controls->Add( labelLanguage );
// NickName Label
Label* labelNickName = new Label();
labelNickName->AutoSize = true;
labelNickName->Text = GetString( "User.NickName" );
labelNickName->Location = System::Drawing::Point(8, 0);
labelNickName->TabIndex = 0;
// NickName TextBox
m_txtNickName = new TextBox();
m_txtNickName->Location = System::Drawing::Point(8, 16);
m_txtNickName->Size = System::Drawing::Size(160, 21);
m_txtNickName->TabIndex = 1;
// GroupBox Icon
GroupBox* groupIcon = new GroupBox();
groupIcon->Location = System::Drawing::Point(8, 48);
groupIcon->Size = System::Drawing::Size(160, 88);
groupIcon->TabIndex = 5;
groupIcon->TabStop = false;
groupIcon->Text = GetString( "Panel.Icon" );
// CustomIcon CheckBox
m_checkCustomIcon = new CheckBox();
m_checkCustomIcon->Text = GetString( "CustomIcon" );
m_checkCustomIcon->Location = System::Drawing::Point(8, 16);
m_checkCustomIcon->Size = System::Drawing::Size(144, 16);
m_checkCustomIcon->CheckedChanged += new EventHandler( this, OnCheckedChanged );
// IconBrowse Button
m_buttonIconBrowse = new Button();
m_buttonIconBrowse->Location = System::Drawing::Point(56, 43);
m_buttonIconBrowse->Text = GetString( "Browse" );
m_buttonIconBrowse->Click += new System::EventHandler( this, OnIconBrowse );
// Icon PictureBox
m_pictureIcon = new PictureBox();
m_pictureIcon->Location = System::Drawing::Point(8, 40);
m_pictureIcon->Size = System::Drawing::Size(34, 34);
m_pictureIcon->SizeMode = PictureBoxSizeMode::CenterImage;
m_pictureIcon->TabStop = false;
// Add controls to the User tab page
tabUser->Controls->Add( labelNickName );
tabUser->Controls->Add( m_txtNickName );
tabUser->Controls->Add( groupIcon );
groupIcon->Controls->Add( m_checkCustomIcon );
groupIcon->Controls->Add( m_buttonIconBrowse );
groupIcon->Controls->Add( m_pictureIcon );
// Create Network page
m_errorProvider = new ErrorProvider();
// MulticastGroup Label
Label* labelMulticastGroup = new Label();
labelMulticastGroup->AutoSize = true;
labelMulticastGroup->Location = System::Drawing::Point(8, 0);
labelMulticastGroup->Text = GetString( "TabPage.Network.MulticastGroup" );
// MulticastGroup TextBox
m_txtMulticastGroup = new TextBox();;
m_txtMulticastGroup->Location = System::Drawing::Point(8, 16);
m_txtMulticastGroup->Text = GetOpt()->MulticastGroup;
m_txtMulticastGroup->Validating += new System::ComponentModel::CancelEventHandler( this, OnMulticastGroupValidating );
// Port Label
Label* labelPort = new Label();
labelPort->AutoSize = true;
labelPort->Location = System::Drawing::Point(8, 40);
labelPort->Text = GetString( "TabPage.Network.Port" );
// Port TextBox
m_txtPort = new TextBox();
m_txtPort->Location = System::Drawing::Point(8, 56);
m_txtPort->Text = GetOpt()->Port.ToString();
m_txtPort->Validating += new System::ComponentModel::CancelEventHandler( this, OnPortValidating );
// Add controls to the Network tab page
tabNetwork->Controls->Add( labelMulticastGroup );
tabNetwork->Controls->Add( m_txtMulticastGroup);
tabNetwork->Controls->Add( labelPort );
tabNetwork->Controls->Add( m_txtPort );
///tabNetwork->Controls->Add( );
// Add TabPages to the TabControl
tabOptions->TabPages->Add( tabGeneral );
tabOptions->TabPages->Add( tabUser );
tabOptions->TabPages->Add( tabNetwork );
tabOptions->TabPages->Add( CreateStylePage() );
// Buttons Panel
Panel* panelButtons = new Panel();
panelButtons->Height = 30;
panelButtons->Dock = DockStyle::Bottom;
// OK Button
Button* buttonOK = new Button();
buttonOK->Location = System::Drawing::Point(132, 5);
buttonOK->Text = GetString( "OK" );
buttonOK->DialogResult = DialogResult::OK;
buttonOK->Click += new EventHandler( this, OnClickOK );
// Cancel Button
Button* buttonCancel = new Button();
buttonCancel->Location = System::Drawing::Point(212, 5);
buttonCancel->Text = GetString( "Cancel" );
buttonCancel->DialogResult = DialogResult::Cancel;
panelButtons->Controls->Add( buttonOK );
panelButtons->Controls->Add( buttonCancel );
this->AcceptButton = buttonOK;
this->CancelButton = buttonCancel;
this->Controls->Add( tabOptions );
this->Controls->Add( panelButtons );
}
Crownwood::Magic::Controls::TabPage* OptionsDlg::CreateStylePage ()
{
Crownwood::Magic::Controls::TabPage* tabStyle =
new Crownwood::Magic::Controls::TabPage( GetString( "TabPage.Style" ) );
// Font
m_groupFont = new GroupBox();
m_groupFont->Location = System::Drawing::Point(8, 0);
m_groupFont->Size = System::Drawing::Size(200, 80);
m_groupFont->Text = GetString( "TabPage.Style.PanelFont" );
// Sample Label
m_labelSample = new Label();
m_labelSample->Location = System::Drawing::Point(8, 120);
m_labelSample->Size = System::Drawing::Size(200, 48);
m_labelSample->Text = GetString( "TabPage.Style.Sample" );
m_labelSample->BackColor = Color::White;
// Elements ComboBox
m_comboElements = new ComboBox();
m_comboElements->Location = System::Drawing::Point(8, 16);
m_comboElements->DropDownStyle = ComboBoxStyle::DropDownList;
String* strElements = GetString( "TabPage.Style.Elements" );
__wchar_t charSpliter __gc[] = new __wchar_t __gc[1];
charSpliter[0] = L'\\';
m_comboElements->Items->AddRange( strElements->Split( charSpliter ) );
m_comboElements->SelectedIndexChanged += new EventHandler( this, OnSelectionChange );
m_comboElements->SelectedIndex = 0;
// Font Button
Button* buttonFont = new Button();
buttonFont->Location = System::Drawing::Point(8, 48);
buttonFont->Text = GetString( "TabPage.Style.Font" );
buttonFont->Click += new EventHandler( this, OnFontClick );
// FontColor Button
Button* buttonFontColor = new Button();
buttonFontColor->Location = System::Drawing::Point(96, 48);
buttonFontColor->Text = GetString( "TabPage.Style.FontColor" );
buttonFontColor->Click += new EventHandler( this, OnFontColorClick );
// Add controls to the GroupBox
m_groupFont->Controls->Add( m_comboElements );
m_groupFont->Controls->Add( buttonFont );
m_groupFont->Controls->Add( buttonFontColor );
// BackColor Button
m_buttonBackColor = new Button();
m_buttonBackColor ->Location = System::Drawing::Point(8, 88);
m_buttonBackColor ->Text = GetString( "TabPage.Style.BackColor" );
m_buttonBackColor ->Click += new EventHandler( this, OnBackColorClick );
// ManualEdit CheckBox
m_checkManualEdit = new CheckBox();
m_checkManualEdit->Location = System::Drawing::Point(8, 176);
m_checkManualEdit->Size = System::Drawing::Size(240, 16);
m_checkManualEdit->Text = GetString( "TabPage.Style.ManualEdit" );
m_checkManualEdit->CheckedChanged += new EventHandler( this, OnCheckChange );
m_checkManualEdit->Checked = GetOpt()->ManualEdit;
tabStyle->Controls->Add( m_groupFont );
tabStyle->Controls->Add( m_buttonBackColor );
tabStyle->Controls->Add( m_labelSample );
tabStyle->Controls->Add( m_checkManualEdit );
return tabStyle;
}
// EventHandlers
////////////////////////////////////////////////////
void OptionsDlg::OnIconBrowse ( Object* sender, EventArgs* e )
{
OpenFileDialog* dlgOpen = new OpenFileDialog();
dlgOpen->Filter = GetString( "Filter.Icon" );
if ( dlgOpen->ShowDialog() == DialogResult::OK )
{
try
{
// Load icon
m_pictureIcon->Image = ( new System::Drawing::Icon(
dlgOpen->OpenFile(), 32, 32 ) )->ToBitmap();
// Copy icon
String* strDestination = String::Format( "{0}\\data\\icons\\user.ico",
Application::StartupPath );
System::IO::File::Copy( dlgOpen->FileName, strDestination, true );
}
catch ( Exception* e )
{
MainForm::ReportErr( GetString( "Error.InvalidIcon" ) );
}
}
}
void OptionsDlg::UpdateIcon()
{
if ( m_checkCustomIcon->Checked )
{
m_buttonIconBrowse->Enabled = true;
m_pictureIcon->Image = ( new System::Drawing::Icon(
String::Format( "{0}\\data\\icons\\user.ico",
Application::StartupPath ) ) )->ToBitmap();
}
else
{
m_buttonIconBrowse->Enabled = false;
m_pictureIcon->Image = ( new System::Drawing::Icon(
String::Format( "{0}\\data\\icons\\local.ico",
Application::StartupPath ) ) )->ToBitmap();
}
}
void OptionsDlg::OnClickOK ( Object* sender, EventArgs* e )
{
bool bRestart = false;
// General
if ( m_comboLanguages->SelectedIndex == 0 )
{
if ( GetOpt()->Language != 0 )
bRestart = true;
GetOpt()->Language = 0;
}
else
{
if ( GetOpt()->Language == 0 )
bRestart = true;
GetOpt()->Language = 1;
}
// User
GetOpt()->UserNickName = m_txtNickName->Text;
GetOpt()->SpecificUserIcon = m_checkCustomIcon->Checked;
// Network
try
{
System::Net::IPAddress* ipMulticastGroup;
ipMulticastGroup = System::Net::IPAddress::Parse( m_txtMulticastGroup->Text );
GetOpt()->MulticastGroup = ipMulticastGroup->ToString();
}
catch ( Exception* ) {}
try
{
int nPort = Convert::ToInt32( m_txtPort->Text );
GetOpt()->Port = nPort;
}
catch ( Exception* ) {}
// Style
if ( !m_checkManualEdit->Checked )
{
try
{
if ( m_sheetStyle )
{
// Save new css file
String* strFile = String::Format( "{0}\\data\\html\\style.css", Application::StartupPath );
System::IO::StreamWriter* w = System::IO::File::CreateText( strFile );
w->Write( m_sheetStyle->cssText );
w->Flush();
}
}
catch ( Exception* ) {}
}
if ( bRestart )
MessageBox::Show( GetString( "Info.Restart" ), GetString( "Info" ),MessageBoxButtons::OK, MessageBoxIcon::Information );
this->Close();
}
void OptionsDlg::OnFontClick( Object* sender, EventArgs* e )
{
FontDialog* dialogFont = new FontDialog();
dialogFont->AllowScriptChange = false;
dialogFont->AllowVerticalFonts = false;
dialogFont->ShowEffects = false;
dialogFont->ShowColor = true;
dialogFont->Font = m_fFont;
if ( dialogFont->ShowDialog( this ) != DialogResult::OK ) return;
// Set new font proprties
m_fFont = dialogFont->Font;
// FontFamily
m_ruleStyle->style->fontFamily = m_fFont->FontFamily->Name;
// Size
int nSize = dialogFont->Font->Size;
m_ruleStyle->style->fontSize = String::Format(
"{0}px", nSize.ToString() );
// Bold
if ( dialogFont->Font->Bold )
m_ruleStyle->style->fontWeight = "bold";
else
m_ruleStyle->style->fontWeight = "normal";
// Italic
if ( dialogFont->Font->Italic )
m_ruleStyle->style->fontStyle = "italic";
else
m_ruleStyle->style->fontStyle = "normal";
m_labelSample->Font = m_fFont;
}
void OptionsDlg::OnFontColorClick( Object* sender, EventArgs* e )
{
ColorDialog* dialogColor = new ColorDialog();
dialogColor->Color = m_colorText;
if ( dialogColor->ShowDialog( this ) != DialogResult::OK ) return;
m_colorText = dialogColor->Color;
m_labelSample->ForeColor = m_colorText;
m_ruleStyle->style->color = static_cast<Object*>( ColorToHTML( m_colorText ) );
}
void OptionsDlg::OnBackColorClick( Object* sender, EventArgs* e )
{
// Go through the IHTMLStyleSheet's elements and try to locate the matching one
mshtml::IHTMLStyleSheetRule* ruleStyle = 0;
if ( m_sheetStyle )
{
IHTMLStyleSheetRulesCollection* rules = m_sheetStyle->rules;
// Go through the rules
if ( rules )
{
for ( int i=0; i<rules->length; i++ )
{
ruleStyle = rules->item( i );
if ( ruleStyle )
{
if ( ruleStyle->selectorText->Equals( "BODY" ) )
break; // Found
ruleStyle = 0;
}
}
}
}
if ( ruleStyle )
{
ColorDialog* dialogColor = new ColorDialog();
String* strColor = 0;
if ( ruleStyle->style->backgroundColor )
strColor = static_cast<String*>( ruleStyle->style->backgroundColor );
dialogColor->Color = ColorFromHTML( strColor, Color::White );
if ( dialogColor->ShowDialog( this ) != DialogResult::OK ) return;
ruleStyle->style->backgroundColor = static_cast<Object*>( ColorToHTML( dialogColor->Color ) );
}
}
void OptionsDlg::OnSelectionChange( Object* sender, EventArgs* e )
{
// Get CSS selector name
String* strSelectors = ".localuser\\.remoteuser\\.time\\.nickname\\.join\\.leave\\.topic\\.state\\.rename\\A:link\\A:visited\\A:hover";
__wchar_t charSpliter __gc[] = new __wchar_t __gc[1];
charSpliter[0] = L'\\';
String* strSelector = strSelectors->Split( charSpliter )[ m_comboElements->SelectedIndex ];
// Go through the IHTMLStyleSheet's elements and try to locate the matching one
m_ruleStyle = 0;
if ( m_sheetStyle )
{
IHTMLStyleSheetRulesCollection* rules = m_sheetStyle->rules;
// Go through the rules
if ( rules )
{
for ( int i=0; i<rules->length; i++ )
{
m_ruleStyle = rules->item( i );
if ( m_ruleStyle )
{
if ( m_ruleStyle->selectorText->Equals( strSelector ) )
break; // Found
m_ruleStyle = 0;
}
}
}
}
if ( m_ruleStyle )
{
// Font
try
{
// Get size
String* strSize = static_cast<String*>( m_ruleStyle->style->fontSize );
int nSize = Convert::ToInt32( strSize->Substring( 0, strSize->IndexOf( "px" ) ) );
// Get style
FontStyle style;
if ( m_ruleStyle->style->fontWeight->Equals( "bold" ) )
style = (FontStyle)( style | FontStyle::Bold );
if ( m_ruleStyle->style->fontStyle->Equals( "italic" ) )
style = (FontStyle)( style | FontStyle::Italic );
// Creat Font
m_fFont = new System::Drawing::Font( m_ruleStyle->style->fontFamily, nSize, style );
}
catch ( Exception* )
{
m_fFont = new System::Drawing::Font( "Arial", 13 );
}
// Color
String* strColor = 0;
if ( m_ruleStyle->style->color )
strColor = static_cast<String*>( m_ruleStyle->style->color );
m_colorText = ColorFromHTML( strColor, Color::Black );
m_labelSample->Font = m_fFont;
m_labelSample->ForeColor = m_colorText;
}
}
void OptionsDlg::OnCheckChange ( Object* sender, EventArgs* e )
{
bool bManualEdit = static_cast<CheckBox*>( sender )->Checked;
GetOpt()->ManualEdit = bManualEdit;
m_groupFont->Enabled = !bManualEdit;
m_buttonBackColor->Enabled = !bManualEdit;
}
void OptionsDlg::OnMulticastGroupValidating( Object* sender, System::ComponentModel::CancelEventArgs* e )
{
try
{
System::Net::IPAddress::Parse( m_txtMulticastGroup->Text );
}
catch ( Exception* )
{
m_errorProvider->SetError( m_txtMulticastGroup, GetString ( "Error.IPAddress" ) );
return;
}
m_errorProvider->SetError( m_txtMulticastGroup, "" );
}
void OptionsDlg::OnPortValidating( Object* sender, System::ComponentModel::CancelEventArgs* e )
{
try
{
Convert::ToInt32( m_txtPort->Text );
}
catch ( Exception* )
{
m_errorProvider->SetError( m_txtPort, GetString( "Error.InvalidPort" ) );
return;
}
m_errorProvider->SetError( m_txtPort, "" );
}
// Private functions
////////////////////////////////////////////////////
Color OptionsDlg::ColorFromHTML( String* strHTML, Color colorDefault )
{
Color color;
try
{
strHTML = strHTML->Remove( 0, 1 );
int nRGB[3] = { 0,0,0 };
for ( int i=0; i<3; i++ )
{
char szRGB[2] = { strHTML->get_Chars(0), strHTML->get_Chars(1) };
for ( int ii=0; ii<2; ii++ )
{
if ( szRGB[ii] == 'a' || szRGB[ii] == 'A' ) nRGB[i] += 10;
else if ( szRGB[ii] == 'b' || szRGB[ii] == 'B' ) nRGB[i] += 11;
else if ( szRGB[ii] == 'c' || szRGB[ii] == 'C' ) nRGB[i] += 12;
else if ( szRGB[ii] == 'd' || szRGB[ii] == 'D' ) nRGB[i] += 13;
else if ( szRGB[ii] == 'e' || szRGB[ii] == 'E' ) nRGB[i] += 14;
else if ( szRGB[ii] == 'f' || szRGB[ii] == 'F' ) nRGB[i] += 15;
else
{
szRGB[ii] -= 48;
int n = Convert::ToInt32( szRGB[ii] );
if ( n < 0 || n > 9 ) throw new Exception();
nRGB[i] += n;
}
if ( ii == 0 )
nRGB[i] = nRGB[i] * 16;
}
strHTML = strHTML->Remove( 0, 2 );
}
color = System::Drawing::Color::FromArgb( nRGB[0], nRGB[1], nRGB[2] );
}
catch ( Exception* )
{
color = colorDefault;
}
return color;
}
String* OptionsDlg::ColorToHTML( Color color )
{
// Convert color to hex
String* strHexColor = "#";
int nRGB[3];
nRGB[0] = color.R;
nRGB[1] = color.G;
nRGB[2] = color.B;
int nElement[2] = {0, 0};
for ( int i=0; i<3; i++ )
{
nElement[0] = nRGB[i] / 16;
nElement[1] = nRGB[i] - ( nElement[0] * 16 );
for ( int ii=0; ii<2; ii++ )
{
if ( nElement[ii] == 10 ) strHexColor = String::Format( "{0}a", strHexColor );
else if ( nElement[ii] == 11 ) strHexColor = String::Format( "{0}b", strHexColor );
else if ( nElement[ii] == 12 ) strHexColor = String::Format( "{0}c", strHexColor );
else if ( nElement[ii] == 13 ) strHexColor = String::Format( "{0}d", strHexColor );
else if ( nElement[ii] == 14 ) strHexColor = String::Format( "{0}e", strHexColor );
else if ( nElement[ii] == 15 ) strHexColor = String::Format( "{0}f", strHexColor );
else strHexColor = String::Format( "{0}{1}", strHexColor, nElement[ii].ToString() );
}
}
return strHexColor;
}
inline String* OptionsDlg::GetString( String* strName )
{
return static_cast<String*>( m_mResources->GetObject( strName) );
}
inline Options* OptionsDlg::GetOpt()
{
return MainForm::GetOptions();
}
}