///
/// Copyright © 2003-2008 JetBrains s.r.o.
/// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder).
///
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Net;
using System.Windows.Forms;
using System.Xml;
using JetBrains.Omea.Base;
using JetBrains.Omea.GUIControls;
using JetBrains.Omea.OpenAPI;
namespace JetBrains.Omea.RSSPlugin
{
///
/// Summary description for BloglinesImporter.
///
internal class OPMLImporterPane : AbstractOptionsPane
{
///
/// Required designer variable.
///
private System.ComponentModel.Container components = null;
private System.Windows.Forms.OpenFileDialog _odOPML;
private System.Windows.Forms.Button _btnAdd;
private System.Windows.Forms.Button _btnDel;
private System.Windows.Forms.ListBox _lstFiles;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button _btnAddURL;
private System.Windows.Forms.CheckBox _chkPreview;
private OPMLImporter _importer = null;
private ImportManager _manager = null;
private IResource _importRoot = null;
private AbstractWizardPane _previewPane = null;
private abstract class PathItem
{
private Control _owner = null;
private string _name = null;
private string _shortName = null;
private int _lastWidth = -1;
internal string Name
{
get { return _name; }
set { _name = value; }
}
internal PathItem( System.Windows.Forms.Control owner, string name )
{
_owner = owner;
_name = name;
}
internal abstract string TrimName( System.Windows.Forms.Control owner, string name, int width );
public override string ToString()
{
if( _shortName == null || _owner.Width != _lastWidth )
{
_shortName = TrimName( _owner, _name, _owner.Width );
_lastWidth = _owner.Width;
}
return _shortName;
}
}
private class FileItem : PathItem
{
internal FileItem( System.Windows.Forms.Control owner, string name ) : base( owner, name )
{
}
internal override string TrimName( System.Windows.Forms.Control owner, string name, int width )
{
string shortName = "";
// check width.
using( Graphics g = Graphics.FromHwnd( owner.Handle ) )
{
// Simple check
if( g.MeasureString( name, owner.Font ).Width < width )
{
return name;
}
else
{ // And trim path.
string[] path = name.Split( '\\' );
int lastComponent = path.Length - 1;
shortName = path[lastComponent];
string p0 = path[0] + "\\...";
while( g.MeasureString( p0 + "\\" + path[lastComponent] + "\\" + shortName, owner.Font ).Width < width &&
lastComponent > 1 )
{
shortName = path[lastComponent] + "\\" + shortName;
--lastComponent;
}
shortName = p0 + "\\" + shortName;
}
}
return shortName;
}
}
private class URLItem : PathItem
{
internal URLItem( System.Windows.Forms.Control owner, string name ) : base( owner, name )
{
}
internal override string TrimName( System.Windows.Forms.Control owner, string name, int width )
{
string shortName = "";
// check width.
using( Graphics g = Graphics.FromHwnd( owner.Handle ) )
{
// Simple check
if( g.MeasureString( name, owner.Font ).Width < width )
{
return name;
}
else
{ // And trim path.
string[] path = name.Split( '/' );
int lastComponent = path.Length - 1;
shortName = path[lastComponent];
string p0 = path[0] + "//" + path[2] + "/...";
while( g.MeasureString( p0 + "/" + path[lastComponent] + "/" + shortName, owner.Font ).Width < width &&
lastComponent > 2 )
{
shortName = path[lastComponent] + "/" + shortName;
--lastComponent;
}
shortName = p0 + "/" + shortName;
}
}
return shortName;
}
}
internal OPMLImporterPane( OPMLImporter importer ) : this( importer, null, null )
{
}
internal OPMLImporterPane( OPMLImporter importer, ImportManager manager, IResource importRoot )
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
_importer = importer;
_manager = manager;
_importRoot = importRoot;
_lstFiles.SizeChanged +=new EventHandler(_lstFiles_SizeChanged);
}
///
/// Clean up any resources being used.
///
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(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._btnAdd = new System.Windows.Forms.Button();
this._odOPML = new System.Windows.Forms.OpenFileDialog();
this._btnDel = new System.Windows.Forms.Button();
this._lstFiles = new System.Windows.Forms.ListBox();
this.label1 = new System.Windows.Forms.Label();
this._btnAddURL = new System.Windows.Forms.Button();
this._chkPreview = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// _btnAdd
//
this._btnAdd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this._btnAdd.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._btnAdd.Location = new System.Drawing.Point(160, 288);
this._btnAdd.Name = "_btnAdd";
this._btnAdd.Size = new System.Drawing.Size(72, 23);
this._btnAdd.TabIndex = 1;
this._btnAdd.Text = "Add &File...";
this._btnAdd.Click += new System.EventHandler(this._btnAdd_Click);
//
// _odOPML
//
this._odOPML.DefaultExt = "opml";
this._odOPML.Filter = "OPML files|*.opml|XML files|*.xml|All files|*.*";
this._odOPML.Multiselect = true;
this._odOPML.Title = "Select OPML files to import";
//
// _btnDel
//
this._btnDel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this._btnDel.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._btnDel.Location = new System.Drawing.Point(319, 288);
this._btnDel.Name = "_btnDel";
this._btnDel.Size = new System.Drawing.Size(72, 23);
this._btnDel.TabIndex = 3;
this._btnDel.Text = "&Remove";
this._btnDel.Click += new System.EventHandler(this._btnDel_Click);
//
// _lstFiles
//
this._lstFiles.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this._lstFiles.ItemHeight = 17;
this._lstFiles.Location = new System.Drawing.Point(8, 32);
this._lstFiles.Name = "_lstFiles";
this._lstFiles.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended;
this._lstFiles.Size = new System.Drawing.Size(384, 212);
this._lstFiles.TabIndex = 4;
this._lstFiles.SelectedIndexChanged += new System.EventHandler(this._lstFiles_SelectedIndexChanged);
//
// label1
//
this.label1.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.label1.Location = new System.Drawing.Point(8, 8);
this.label1.Name = "label1";
this.label1.TabIndex = 5;
this.label1.Text = "Files to import:";
//
// _btnAddURL
//
this._btnAddURL.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this._btnAddURL.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._btnAddURL.Location = new System.Drawing.Point(238, 288);
this._btnAddURL.Name = "_btnAddURL";
this._btnAddURL.TabIndex = 6;
this._btnAddURL.Text = "Add &URL...";
this._btnAddURL.Click += new System.EventHandler(this._btnAddURL_Click);
//
// _chkPreview
//
this._chkPreview.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this._chkPreview.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._chkPreview.Location = new System.Drawing.Point(8, 258);
this._chkPreview.Name = "_chkPreview";
this._chkPreview.Size = new System.Drawing.Size(152, 24);
this._chkPreview.TabIndex = 7;
this._chkPreview.Text = "&Preview subscription";
this._chkPreview.CheckedChanged += new System.EventHandler(this._chkPreview_CheckedChanged);
//
// OPMLImporterPane
//
this.Controls.Add(this._chkPreview);
this.Controls.Add(this._btnAddURL);
this.Controls.Add(this.label1);
this.Controls.Add(this._lstFiles);
this.Controls.Add(this._btnDel);
this.Controls.Add(this._btnAdd);
this.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(204)));
this.Name = "OPMLImporterPane";
this.Size = new System.Drawing.Size(400, 320);
this.ResumeLayout(false);
}
#endregion
public override void ShowPane()
{
if( _manager == null )
{
_chkPreview.Hide();
}
_btnDel_enable();
}
public override void LeavePane()
{
string[] names = new string[_lstFiles.Items.Count];
for( int i = 0; i < _lstFiles.Items.Count; ++i )
{
names[i] = ((PathItem)_lstFiles.Items[i]).Name;
}
_importer.FileNames = names;
}
private void _btnAdd_Click(object sender, System.EventArgs e)
{
DialogResult dr = _odOPML.ShowDialog( this );
if( dr == DialogResult.OK )
{
foreach( string name in _odOPML.FileNames )
{
bool found = false;
for( int i = 0; i < _lstFiles.Items.Count && ! found ; ++i )
{
PathItem item = (PathItem)_lstFiles.Items[i];
found = item.Name == name;
}
if( ! found )
{
_lstFiles.Items.Add( new FileItem( _lstFiles, name ) );
}
}
}
_btnDel_enable();
}
private void _btnDel_Click(object sender, System.EventArgs e)
{
object[] selected = new object[ _lstFiles.SelectedIndices.Count ];
for( int i = 0; i < _lstFiles.SelectedIndices.Count; ++i )
{
selected[i] = _lstFiles.Items[i];
}
for( int i = 0; i < selected.Length; ++i )
{
_lstFiles.Items.Remove( selected[ i ] );
}
_btnDel_enable();
}
private void _btnDel_enable()
{
if( _lstFiles.Items.Count > 0 && _lstFiles.SelectedIndices.Count > 0 )
{
_btnDel.Enabled = true;
}
else
{
_btnDel.Enabled = false;
}
}
private void _lstFiles_SelectedIndexChanged(object sender, System.EventArgs e)
{
_btnDel_enable();
}
private void _lstFiles_SizeChanged(object sender, EventArgs e)
{
object[] tmp = new object[ _lstFiles.Items.Count ];
_lstFiles.BeginUpdate();
_lstFiles.Items.CopyTo( tmp, 0 );
_lstFiles.Items.Clear();
_lstFiles.Items.AddRange( tmp );
_lstFiles.EndUpdate();
}
private void _btnAddURL_Click(object sender, System.EventArgs e)
{
string url = Core.UIManager.InputString( "Import OPML File from URL",
"Enter the URL of the OPML file:", "", null, this );
if( url == null || url.Length == 0 )
{
return;
}
// Fix url with "http://"
if( url.IndexOf( "://" ) == -1 )
{
url = "http://" + url;
}
url = url.Trim();
Uri uri = null;
try
{
uri = new Uri( url );
}
catch( UriFormatException )
{
MessageBox.Show( this, "The format of the URL is not valid:\n" + url +
"\nPlease enter the URL again and verify that it is correct.",
"Add URL", MessageBoxButtons.OK );
return;
}
if( null != uri )
{
_lstFiles.Items.Add( new URLItem( _lstFiles, uri.ToString() ) );
}
}
private void _chkPreview_CheckedChanged(object sender, System.EventArgs e)
{
if( _manager == null )
{
return;
}
AddPreviewPane( _chkPreview.Enabled && _chkPreview.Checked );
}
private void AddPreviewPane( bool add )
{
if( _manager == null )
{
return;
}
if( add )
{
if( _previewPane == null )
{
_previewPane = new PreviewSubscriptionsPaneAdapter( "Preview subscriptions", new OptionsPaneCreator( CreatePreviewPane ) );
}
_manager.Wizard.RegisterPane( 0xFFFF, _previewPane );
}
else
{
if( _previewPane != null )
{
_manager.Wizard.DeregisterPane( _previewPane );
}
}
}
private AbstractOptionsPane CreatePreviewPane()
{
return new PreviewSubscriptionsPane( _manager, _importRoot );
}
}
internal class OPMLImporter : IFeedImporter
{
private const string _progressMessage = "Importing ";
private string[] _fileNames = null;
private ImportManager _manager = null;
private IResource _importRoot = null;
internal string[] FileNames
{
get { return _fileNames; }
set { _fileNames = value; }
}
internal OPMLImporter() : this( null, null )
{
}
internal OPMLImporter( ImportManager manager, IResource importRoot )
{
if( manager == null )
{
RSSPlugin.GetInstance().RegisterFeedImporter( "OPML Files", this );
}
else
{
_manager = manager;
_importRoot = importRoot;
}
}
#region IFeedImporter implementation
///
/// Check if importer needs configuration before import starts.
///
public bool HasSettings
{
get { return true; }
}
///
/// Returns creator of options pane.
///
public OptionsPaneCreator GetSettingsPaneCreator()
{
return new OptionsPaneCreator( this.CreateOptionPane );
}
///
/// Import subscription
///
public void DoImport( IResource importRoot, bool addToWorkspace )
{
if( null == FileNames )
{
return;
}
int totalFeeds = Math.Max( FileNames.Length, 1 );
int processedFeeds = 0;
ImportUtils.UpdateProgress( processedFeeds / totalFeeds, _progressMessage );
IResource currentRoot = null;
foreach( string fileName in FileNames )
{
string defaultName = null;
Stream opml = null;
if( ! File.Exists( fileName ) )
{
defaultName = fileName;
// Try to load as URL
try
{
opml = new JetMemoryStream( new WebClient().DownloadData( fileName ), true );
}
catch( Exception ex )
{
Trace.WriteLine( "OPML file '" + fileName + "' can not be load: '" + ex.Message + "'" );
opml = null;
}
}
else
{
defaultName = Path.GetFileName( fileName );
// Try to load title from this file
try
{
opml = new FileStream( fileName, FileMode.Open, FileAccess.Read );
}
catch( Exception ex )
{
Trace.WriteLine( "OPML file '" + fileName + "' can not be load: '" + ex.Message + "'" );
opml = null;
}
}
if( null == opml )
{
continue;
}
// Try to get name
string name = null;
try
{
XmlDocument xml = new XmlDocument();
xml.Load( opml );
XmlElement title = xml.SelectSingleNode( "/opml/head/title" ) as XmlElement;
name = title.InnerText;
}
catch( Exception ex )
{
Trace.WriteLine( "OPML file '" + fileName + "' doesn't have title: '" + ex.Message + "'" );
}
if( name == null || name.Length == 0 )
{
name = defaultName;
}
try
{
opml.Seek( 0, SeekOrigin.Begin );
if( _manager == null || FileNames.Length > 1 )
{
currentRoot = RSSPlugin.GetInstance().FindOrCreateGroup( "Subscription from " + name , importRoot );
}
else
{
currentRoot = importRoot;
}
OPMLProcessor.Import( new StreamReader(opml), currentRoot, addToWorkspace );
}
catch( Exception ex )
{
Trace.WriteLine( "OPML file '" + fileName + "' can not be load: '" + ex.Message + "'" );
RemoveFeedsAndGroupsAction.DeleteFeedGroup( currentRoot );
ImportUtils.ReportError( "OPML File Import", "Import of OPML file '" + fileName + "' failed:\n" + ex.Message );
}
processedFeeds += 100;
ImportUtils.UpdateProgress( processedFeeds / totalFeeds, _progressMessage );
}
return;
}
///
/// Import cached items, flags, etc.
///
public void DoImportCache()
{
// do nothing
}
#endregion
private AbstractOptionsPane CreateOptionPane()
{
return new OPMLImporterPane( this, _manager, _importRoot );
}
}
}