/***********************************************************************\
* Virtuoso.Miranda.Plugins (Hyphen) *
* Provides a managed wrapper for API of IM client Miranda. *
* Copyright (C) 2006-2009 virtuoso *
* deml.tomas@seznam.cz *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library 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 *
* Lesser General Public License for more details. *
\***********************************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Virtuoso.Miranda.Plugins.Resources;
using Virtuoso.Miranda.Plugins.Properties;
using Virtuoso.Miranda.Plugins.Configuration.Forms.Controls;
using RibbonStyle;
using Virtuoso.Miranda.Plugins.Infrastructure;
using Virtuoso.Miranda.Plugins.Collections;
using Virtuoso.Hyphen;
using Virtuoso.Hyphen.Mini;
using System.Collections.ObjectModel;
using Virtuoso.Miranda.Plugins.Forms;
using Virtuoso.Hyphen.Configuration;
namespace Virtuoso.Miranda.Plugins.Configuration.Forms
{
/// Casablanca
public sealed partial class ConfigurationDialog : SingletonDialog
{
#region Fields
private bool Ok;
private List ConfigurableEntities;
private const char PathSeparator = '/';
private string[] CurrentPath;
private string ConfigurationParameter;
private CategoryCollection categories;
#endregion
#region .ctors
private ConfigurationDialog()
{
InitializeComponent();
((RibbonStyle.TabStripProfessionalRenderer)RibbonStrip.Renderer).HaloColor = Color.FromArgb(254, 209, 94);
((RibbonStyle.TabStripProfessionalRenderer)RibbonStrip.Renderer).BaseColor = Color.FromArgb(215, 227, 242);
categories = new CategoryCollection();
ConfigurableEntities = new List(5);
}
public static void Present(bool modal)
{
Present(modal, null, null);
}
public static void Present(bool modal, IConfigurablePlugin plugin)
{
Present(modal, plugin, null);
}
public static void Present(bool modal, string path)
{
Present(modal, null, path);
}
public static void Present(bool modal, IConfigurablePlugin plugin, string path)
{
ConfigurationDialog dialog = ConfigurationDialog.GetSingleton(false);
if (dialog == null)
{
dialog = new ConfigurationDialog();
dialog.SetPath(path);
dialog.Populate(plugin);
}
dialog.ShowSingleton(modal);
}
#endregion
#region UI Handlers
private void OkBTN_Click(object sender, EventArgs e)
{
Ok = true;
Close();
}
private void CancelBTN_Click(object sender, EventArgs e)
{
Ok = false;
Close();
}
private void ConfigurationDialog_FormClosing(object sender, FormClosingEventArgs e)
{
if (Ok && !CanDismissActiveControl())
{
e.Cancel = true;
return;
}
foreach (ConfigurableEntityDescriptor descriptor in ConfigurableEntities)
ProcessChanges(descriptor, Ok);
if (Ok)
Settings.Default.Save();
}
private void ProcessChanges(ConfigurableEntityDescriptor descriptor, bool save)
{
foreach (Category category in descriptor.Categories)
{
foreach (CategoryItem item in category.Items)
{
if (!item.ControlInitialized)
continue;
CategoryItemControl control = item.Control;
if (save && control.IsDirty)
control.Save();
control.Close();
}
}
if (save)
{
foreach (PluginConfiguration config in descriptor.Plugin.Configuration)
if (config != null)
config.Save();
}
}
#endregion
#region Methods
#region Create/Set path
public static string CreatePath(IConfigurablePlugin plugin, string category, string item)
{
return CreatePath(plugin, category, item, null);
}
public static string CreatePath(IConfigurablePlugin plugin, string category, string item, string parameter)
{
if (plugin == null)
throw new ArgumentNullException("plugin");
if (String.IsNullOrEmpty(category))
throw new ArgumentNullException("category");
if (String.IsNullOrEmpty(item))
throw new ArgumentNullException("item");
return String.Format("{1}{0}{2}{0}{3}{0}{4}", PathSeparator.ToString(), plugin.Name, category, item, (parameter ?? String.Empty));
}
private void SetPath(string path)
{
if (String.IsNullOrEmpty(path))
return;
CurrentPath = path.Split(PathSeparator);
if (CurrentPath.Length != 4)
throw new ArgumentOutOfRangeException("path");
ConfigurationParameter = (String.IsNullOrEmpty(CurrentPath[3]) ? null : CurrentPath[3]);
}
private bool CanNavigateTo(IConfigurablePlugin plugin, Category category)
{
if (plugin == null)
throw new ArgumentNullException("plugin");
if (category == null)
throw new ArgumentNullException("category");
if (CurrentPath == null)
return false;
return (CurrentPath[0] == plugin.Name && CurrentPath[1] == category.Name);
}
private bool CanNavigateTo(CategoryItem item)
{
if (item == null)
throw new ArgumentNullException("item");
if (CurrentPath == null)
return false;
return CurrentPath[2] == item.Name;
}
#endregion
#region Entity population
private void Populate(IConfigurablePlugin pluginToPopulate)
{
ConfigurableEntities.Clear();
RibbonPageSwitcher.SelectedTabStripPage = null;
RibbonStrip.Items.Clear();
if (pluginToPopulate == null)
{
PopulateHyphenConfiguration();
if (AppDomain.CurrentDomain.IsDefaultAppDomain())
PopulateStandalonePlugins();
else
PopulateIsolatedPlugins();
}
else
{
ConfigurableEntities.Add(new ConfigurableEntityDescriptor(pluginToPopulate));
Text += String.Format(" : {0}", pluginToPopulate.Name);
}
PopulateItems();
}
private void PopulateItems()
{
CategoryCollection categories = null;
for (int i = 0; i < ConfigurableEntities.Count; i++)
{
ConfigurableEntityDescriptor descriptor = ConfigurableEntities[i];
TabStripPage page = CreateAndRegisterEntityPage(categories, descriptor.Plugin, i);
descriptor.Categories = (categories = new CategoryCollection());
descriptor.Plugin.PopulateConfiguration(categories);
for (int j = 0; j < categories.Count; j++)
{
Category category = categories[j];
if (category == null)
continue;
PopulateCategoryPanel(page, category, descriptor.Plugin, j);
}
}
}
private void PopulateIsolatedPlugins()
{
PluginDescriptorReadOnlyCollection plugins = MirandaContext.Current.PluginManager.Plugins;
try
{
SynchronizationHelper.BeginCollectionUpdate(plugins);
foreach (PluginDescriptor descriptor in plugins)
if (descriptor.IsConfigurable)
ConfigurableEntities.Add(new ConfigurableEntityDescriptor((IConfigurablePlugin)descriptor.Plugin));
}
finally
{
SynchronizationHelper.EndUpdate(plugins);
}
}
private void PopulateStandalonePlugins()
{
ModuleReadOnlyCollection modules = ModuleManager.Singleton.RegisteredModules;
try
{
SynchronizationHelper.BeginCollectionUpdate(modules);
foreach (Module module in modules)
if (module.StandalonePlugin.Descriptor.IsConfigurable)
ConfigurableEntities.Add(new ConfigurableEntityDescriptor((IConfigurablePlugin)module.StandalonePlugin));
}
finally
{
SynchronizationHelper.EndUpdate(modules);
}
}
private void PopulateHyphenConfiguration()
{
if (AppDomain.CurrentDomain.IsDefaultAppDomain())
ConfigurableEntities.Add(new ConfigurableEntityDescriptor(RuntimeConfigurator.Singleton));
else
ConfigurableEntities.Add(new ConfigurableEntityDescriptor(PMConfigurator.Singleton));
}
#endregion
#region Entity control creation
private void PopulateCategoryPanel(TabStripPage entityPage, Category category, IConfigurablePlugin plugin, int index)
{
TabPanel categoryPanel = CreateCategoryPanel(category, index);
entityPage.Controls.Add(categoryPanel);
if (CanNavigateTo(plugin, category))
RibbonPageSwitcher.SelectedTabStripPage = entityPage;
Point nextLocation = new Point();
foreach (CategoryItem item in category.Items)
{
RibbonButton btn = CreateButton(item, ref nextLocation);
categoryPanel.Controls.Add(btn);
if (CanNavigateTo(item))
RibbonButton_Click(btn, EventArgs.Empty);
}
}
private RibbonButton CreateButton(CategoryItem item, ref Point nextLocation)
{
RibbonButton btn = new RibbonButton();
btn.Text = item.Name;
btn.ShowInfoTips = true;
btn.InfoTitle = item.Name;
btn.InfoComment = item.Description;
if (item.Image == null)
item.Image = VisualResources.Image_64x67_Configuration;
btn.img = item.Image;
btn.Size = btn.img.Size;
if (nextLocation.IsEmpty)
nextLocation = new Point(-btn.Size.Width, 6);
btn.img_on = Properties.Resources.RibbonHover;
btn.img_click = Properties.Resources.RibbonClick;
nextLocation.Offset(btn.img.Size.Width + 5, 0);
btn.Location = nextLocation;
btn.Tag = item;
btn.Click += RibbonButton_Click;
return btn;
}
private TabPanel CreateCategoryPanel(Category category, int index)
{
TabPanel categoryPanel = new TabPanel();
categoryPanel.BaseColor = System.Drawing.Color.FromArgb(215, 227, 242);
categoryPanel.BaseColorOn = System.Drawing.Color.FromArgb(233, 239, 248);
categoryPanel.Dock = System.Windows.Forms.DockStyle.Left;
categoryPanel.ForeColor = System.Drawing.SystemColors.Desktop;
categoryPanel.Location = new System.Drawing.Point(101, 3);
categoryPanel.Opacity = 255;
categoryPanel.Padding = new System.Windows.Forms.Padding(6, 3, 6, 0);
categoryPanel.AutoSize = true;
categoryPanel.AutoSizeMode = AutoSizeMode.GrowAndShrink;
categoryPanel.Speed = 1;
categoryPanel.TabIndex = index;
categoryPanel.Caption = category.Name;
return categoryPanel;
}
private TabStripPage CreateAndRegisterEntityPage(CategoryCollection categories, IConfigurablePlugin entity, int index)
{
TabStripPage entityPage = new TabStripPage();
entityPage.BaseColor = System.Drawing.Color.FromArgb(215, 227, 242);
entityPage.BaseColorOn = System.Drawing.Color.FromArgb(215, 227, 242);
entityPage.Dock = System.Windows.Forms.DockStyle.Fill;
entityPage.Opacity = 255;
entityPage.Padding = new System.Windows.Forms.Padding(0, 3, 0, 0);
entityPage.Size = new System.Drawing.Size(784, 99);
entityPage.Speed = 1;
entityPage.TabIndex = index;
RibbonPageSwitcher.Controls.Add(entityPage);
Tab entityTab = new Tab(entity.Name);
entityTab.AutoSize = false;
entityTab.Checked = true;
entityTab.CheckState = CheckState.Checked;
entityTab.ForeColor = System.Drawing.Color.FromArgb(44, 90, 154);
entityTab.Margin = new Padding(6, 1, 0, 2);
entityTab.Size = new Size(73, 23);
entityTab.Text = entity.Name;
entityTab.TabStripPage = entityPage;
if (entity is IInternalConfigurator)
entityTab.Image = VisualResources.Icon_16x16_Hyphen.ToBitmap();
RibbonStrip.Items.Add(entityTab);
return entityPage;
}
#endregion
#region Entity control handling
private bool CanDismissActiveControl()
{
if (ControlPanel.Controls.Count > 0 && ControlPanel.Controls[0] is CategoryItemControl)
return !((CategoryItemControl)ControlPanel.Controls[0]).OnHide();
else
return true;
}
private void RibbonButton_Click(object sender, EventArgs e)
{
RibbonButton btn = (RibbonButton)sender;
CategoryItem item = (CategoryItem)btn.Tag;
bool firstTime = !item.ControlInitialized;
CategoryItemControl control = item.Control;
control.OnSelected();
if (control.HasUI && !control.OnShow(firstTime))
{
if (!CanDismissActiveControl())
return;
control.ConfigurationParameter = ConfigurationParameter;
ControlPanel.Controls.Clear();
control.Dock = DockStyle.Fill;
ControlPanel.Controls.Add(control);
}
}
#endregion
#endregion
}
}