/// /// 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.Collections; using System.Drawing; using System.Windows.Forms; using System.IO; using JetBrains.Omea.OpenAPI; using JetBrains.Omea.GUIControls; using JetBrains.DataStructures; namespace JetBrains.Omea.FilePlugin { internal class SetFoldersForm : AbstractOptionsPane { private System.Windows.Forms.FolderBrowserDialog _selectFolderDialog; private System.Windows.Forms.Button _addBtn; private System.Windows.Forms.ComboBox _statusBox; private System.Windows.Forms.ToolTip _foldersTooltip; private System.ComponentModel.IContainer components; private System.Windows.Forms.Button _deleteBtn; private ResourceListView2 _folderList; private ResourceListView2Column _folderColumn; private ResourceListView2Column _statusColumn; private IResourceList _folders; private HashMap _initialStatuses; private bool _wereChanges; private IResource _statusChangingFolder; internal SetFoldersForm() { InitializeComponent(); _initialStatuses = new HashMap(); _folderColumn = new ResourceListView2Column( new int[] { Core.Props.Name } ); _folderColumn.Text = "Folder"; _folderColumn.Width = 180; _folderColumn.AutoSize = true; _folderList.Columns.Add( _folderColumn ); _statusColumn = new ResourceListView2Column( new int[] { FileProxy._propStatus } ); _statusColumn.Text = "Indexed"; _statusColumn.Width = 90; _statusColumn.SetPropToTextConverter( _statusColumn.PropIds[ 0 ], new PropertyToTextConverter( new PropertyToTextCallback( StatusToText ) ) ); _folderList.Columns.Add( _statusColumn ); _folderList.SelectAddedItems = true; _folderList.ShowContextMenu = false; } public static AbstractOptionsPane SetFoldersFormCreator() { return new SetFoldersForm(); } public override void ShowPane() { _wereChanges = false; _statusBox.Items.AddRange( new string[] { "Immediately", "On Startup", "Never" } ); _statusBox.SelectedIndex = 1; _folders = Core.ResourceStore.FindResourcesWithPropLive( FileProxy._folderResourceType, FileProxy._propStatus ); _folders = _folders.Minus( Core.ResourceStore.FindResourcesWithPropLive( FileProxy._folderResourceType, FileProxy._propDeleted ) ); ArrayList garbage = new ArrayList(); foreach( IResource folder in _folders ) { if( !folder.HasLink( FileProxy._propParentFolder, FoldersCollection.Instance.FilesRoot ) ) { garbage.Add( folder ); } } foreach( IResource folder in garbage ) { FoldersCollection.Instance.DeleteResource( folder ); } // force monitoring of my documents if list is empty and we are in Startup Wizard if( IsStartupPane ) { _statusColumn.Width = 0; _statusBox.Visible = false; if( _folders.Count == 0 ) { _wereChanges = true; Core.ResourceAP.RunUniqueJob( new MethodInvoker( CreateMyDocumentsFolder ) ); } } foreach( IResource folder in _folders ) { _initialStatuses[ folder.GetPropText( FileProxy._propDirectory ) ] = folder.GetIntProp( FileProxy._propStatus ); } _folders.Sort( new int[] { Core.Props.Name }, true ); _folderList.DataProvider = new ResourceListDataProvider( _folders ); } public override void OK() { if( _wereChanges ) { _wereChanges = false; _folderList.DataProvider = null; Cursor current = Cursor.Current; Cursor.Current = Cursors.WaitCursor; try { FoldersCollection.Instance.Interrupted = true; FoldersCollection.Instance.WaitUntilFinished(); Core.ResourceAP.RunUniqueJob( "Modifying settings for Indexed File Folders", new MethodInvoker( SubmitChanges ) ); if( !IsStartupPane ) { FoldersCollection.LoadFoldersForest(); } } finally { Cursor.Current = current; } } } public override void Cancel() { if( _wereChanges ) { _folderList.DataProvider = null; Core.ResourceAP.RunUniqueJob( "Rolling back settings for Indexed File Folders", new MethodInvoker( RollBack ) ); } } protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this._selectFolderDialog = new System.Windows.Forms.FolderBrowserDialog(); this._folderList = new JetBrains.Omea.GUIControls.ResourceListView2(); this._addBtn = new System.Windows.Forms.Button(); this._deleteBtn = new System.Windows.Forms.Button(); this._statusBox = new System.Windows.Forms.ComboBox(); this._foldersTooltip = new System.Windows.Forms.ToolTip(this.components); this.SuspendLayout(); // // _folderList // this._folderList.AllowColumnReorder = false; this._folderList.AllowDrop = true; this._folderList.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._folderList.AutoScroll = true; this._folderList.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this._folderList.ColumnSchemeProvider = null; this._folderList.ContextProvider = this._folderList; this._folderList.DataProvider = null; this._folderList.ExecuteDoubleClickAction = false; this._folderList.FullRowSelect = true; this._folderList.HeaderContextMenu = null; this._folderList.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Clickable; this._folderList.InPlaceEdit = false; this._folderList.Location = new System.Drawing.Point(0, 24); this._folderList.MultiLineView = false; this._folderList.MultiSelect = false; this._folderList.Name = "_folderList"; this._folderList.RowDelimiters = false; this._folderList.Size = new System.Drawing.Size(288, 223); this._folderList.TabIndex = 0; this._folderList.KeyDown += new System.Windows.Forms.KeyEventHandler(this._folderList_KeyDown); this._folderList.Resize += new System.EventHandler(this._folderList_Resize); this._folderList.HandleCreated += new System.EventHandler(this._folderList_ListHandleCreated); this._folderList.ColumnSizeChanged += new System.EventHandler(this._folderList_ColumnSizeChanged); this._folderList.SelectionChanged += new System.EventHandler(this._folderList_SelectedIndexChanged); // // _addBtn // this._addBtn.FlatStyle = System.Windows.Forms.FlatStyle.System; this._addBtn.Location = new System.Drawing.Point(0, 0); this._addBtn.Name = "_addBtn"; this._addBtn.TabIndex = 1; this._addBtn.Text = "&Add..."; this._addBtn.Click += new System.EventHandler(this._addBtn_Click); // // _deleteBtn // this._deleteBtn.FlatStyle = System.Windows.Forms.FlatStyle.System; this._deleteBtn.Location = new System.Drawing.Point(80, 0); this._deleteBtn.Name = "_deleteBtn"; this._deleteBtn.TabIndex = 2; this._deleteBtn.Text = "&Remove"; this._deleteBtn.Enabled = false; this._deleteBtn.Click += new System.EventHandler(this._deleteBtn_Click); // // _statusBox // this._statusBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this._statusBox.Location = new System.Drawing.Point(192, 0); this._statusBox.Name = "_statusBox"; this._statusBox.Size = new System.Drawing.Size(90, 21); this._statusBox.TabIndex = 3; this._statusBox.Visible = false; this._statusBox.Leave += new System.EventHandler(this._statusBox_Leave); // // SetFoldersForm // this.Controls.Add(this._statusBox); this.Controls.Add(this._deleteBtn); this.Controls.Add(this._addBtn); this.Controls.Add(this._folderList); this.Name = "SetFoldersForm"; this.Size = new System.Drawing.Size(288, 248); this.ResumeLayout(false); } #endregion private void _addBtn_Click( object sender, System.EventArgs e ) { _selectFolderDialog.ShowNewFolderButton = true; if( _selectFolderDialog.SelectedPath.Length == 0 ) { string lastSelectedFolder = Core.SettingStore.ReadString( "FilePlugin", "LastSelectedFolder" ); if( lastSelectedFolder.Length == 0 ) { lastSelectedFolder = Environment.GetFolderPath( Environment.SpecialFolder.Desktop ); } _selectFolderDialog.SelectedPath = lastSelectedFolder; } string description = "Select a path to be monitored"; if( !IsStartupPane ) { description += " or excluded"; } _selectFolderDialog.Description = description; DialogResult res; try { res = _selectFolderDialog.ShowDialog(); } catch( Exception exc ) { MessageBox.Show( this, "Selected folder could not be added.\r\n" + exc.Message, "Shell Error", MessageBoxButtons.OK, MessageBoxIcon.Error ); res = DialogResult.Cancel; } if( res == DialogResult.OK ) { string path = _selectFolderDialog.SelectedPath; Core.SettingStore.WriteString( "FilePlugin", "LastSelectedFolder", path ); foreach( IResource folder in _folders ) { if( String.Compare( path, folder.GetPropText( Core.Props.Name ), true ) == 0 ) { MessageBox.Show( this, path + " is already in list", "Attention", MessageBoxButtons.OK, MessageBoxIcon.Error ); return; } } try { DirectoryInfo di = new DirectoryInfo( path ); di.GetDirectories(); di.GetFiles(); } catch( Exception exc ) { MessageBox.Show( this, exc.Message, path, MessageBoxButtons.OK, MessageBoxIcon.Error ); return; } _wereChanges = true; Core.ResourceAP.QueueJob( JobPriority.Immediate, new CreateFolderDelegate( CreateFolder ), path ); } } private void _deleteBtn_Click(object sender, System.EventArgs e) { IResourceList list = _folderList.GetSelectedResources(); if( list.Count > 0 ) { _wereChanges = true; Core.ResourceAP.RunUniqueJob( "Mark directories deleted", new ResourceListDelegate( MarkDeleted ), list ); Core.UserInterfaceAP.QueueJob( new MethodInvoker( UpdateDeleteButton ) ); } } private void _folderList_SelectedIndexChanged(object sender, System.EventArgs e) { if( !Core.UserInterfaceAP.IsOwnerThread ) { Core.UserInterfaceAP.QueueJob( new EventHandler( _folderList_SelectedIndexChanged ), sender, e ); return; } IResourceList selected = _folderList.GetSelectedResources(); if( selected.Count == 0 ) { UpdateFolderStatus(); _statusBox.Visible = false; _foldersTooltip.Active = false; _statusChangingFolder = null; } else { IResource selectedFolder = selected[ 0 ]; _statusChangingFolder = selectedFolder; _statusBox.SelectedIndex = selectedFolder.GetIntProp( FileProxy._propStatus ); _statusBox.Visible = true; _statusBox.DroppedDown = false; _foldersTooltip.Active = true; _foldersTooltip.SetToolTip( _folderList, selectedFolder.GetPropText( FileProxy._propDirectory ) ); AdjustStatusBoxRectangle(); } UpdateDeleteButton(); } private void _folderList_Resize(object sender, System.EventArgs e) { AdjustStatusBoxRectangle(); } private void _folderList_ColumnSizeChanged(object sender, System.EventArgs e) { AdjustStatusBoxRectangle(); } private void _statusBox_Leave(object sender, System.EventArgs e) { UpdateFolderStatus(); } private void _folderList_ListHandleCreated(object sender, System.EventArgs e) { AdjustStatusBoxRectangle(); } private void _folderList_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) { switch( e.KeyCode ) { case Keys.Space: { _statusBox.Focus(); break; } case Keys.Delete: { _deleteBtn.PerformClick(); break; } } e.Handled = true; } private void CreateMyDocumentsFolder() { string path = Environment.GetFolderPath( Environment.SpecialFolder.Personal ); if( Directory.Exists( path ) ) { CreateFolder( path ); } } private string StatusToText( IResource folder, int propID ) { switch( folder.GetIntProp( FileProxy._propStatus ) ) { case 0 : return "Immediately »"; case 1 : return "On Startup »"; case 2 : return "Never »"; } return string.Empty; } private delegate void CreateFolderDelegate( string path ); private void CreateFolder( string path ) { IResource folder = Core.ResourceStore.FindUniqueResource( FileProxy._folderResourceType, FileProxy._propDirectory, path ); if( folder != null ) { folder.BeginUpdate(); } else { folder = Core.ResourceStore.BeginNewResource( FileProxy._folderResourceType ); } try { Core.WorkspaceManager.AddToActiveWorkspaceRecursive( folder ); folder.SetProp( Core.Props.Name, path ); folder.SetProp( FileProxy._propDirectory, path ); folder.SetProp( FileProxy._propParentFolder, FoldersCollection.Instance.FilesRoot ); folder.SetProp( FileProxy._propStatus, _statusBox.SelectedIndex ); folder.SetProp( FileProxy._propNew, true ); folder.SetProp( FileProxy._propDeleted, false ); } finally { folder.EndUpdate(); } } private void SubmitChanges() { IResourceList folders = Core.ResourceStore.FindResourcesWithProp( FileProxy._folderResourceType, FileProxy._propStatus ); foreach( IResource folder in folders ) { if( folder.HasProp( FileProxy._propDeleted ) ) { FoldersCollection.Instance.DeleteResource( folder ); } else { folder.SetProp( FileProxy._propNew, false ); } } } private void RollBack() { IResourceList folders = Core.ResourceStore.FindResourcesWithProp( FileProxy._folderResourceType, FileProxy._propStatus ); foreach( IResource folder in folders ) { if( folder.HasProp( FileProxy._propNew ) ) { FoldersCollection.Instance.DeleteResource( folder ); } else { folder.SetProp( FileProxy._propDeleted, false ); folder.SetProp( FileProxy._propStatus, _initialStatuses[ folder.GetPropText( FileProxy._propDirectory ) ] ); } } } private void AdjustStatusBoxRectangle() { IResourceList selected = _folderList.GetSelectedResources(); if( selected.Count > 0 ) { Rectangle rect = _folderList.JetListView.GetItemBounds( _folderList.NodeFromItem( selected[ 0 ] ), _statusColumn ); _statusBox.Top = rect.Top + _folderList.Top; _statusBox.Left = rect.Left - 1; _statusBox.Width = rect.Width + 3; _statusBox.Height = rect.Height; } } private void UpdateFolderStatus() { if( _statusChangingFolder != null ) { if( _statusChangingFolder.GetIntProp( FileProxy._propStatus ) != _statusBox.SelectedIndex ) { _wereChanges = true; new ResourceProxy( _statusChangingFolder ).SetPropAsync( FileProxy._propStatus, _statusBox.SelectedIndex ); } } } private static void MarkDeleted( IResourceList list ) { foreach( IResource toBeDeleted in list ) { toBeDeleted.SetProp( FileProxy._propDeleted, true ); } } private void UpdateDeleteButton() { IResourceList selected = _folderList.GetSelectedResources(); _deleteBtn.Enabled = selected.Count > 0; } public override string GetHelpKeyword() { return "/reference/indexed_folders.html"; } } }