Example #1
0
		public override void FinishInit()
		{
			m_chorusSystem = new ChorusSystem(Cache.ProjectId.ProjectFolder);
			m_chorusSystem.InitWithoutHg(SendReceiveUser);
			// This is a required object for CreateNotesBar. It specifies delegates for getting the information
			// the bar requires about the current object.
			var notesToRecordMapping = new NotesToRecordMapping()
				{
					FunctionToGetCurrentUrlForNewNotes = GetCurrentUrlForNewNotes,
					FunctionToGoFromObjectToItsId = GetIdForObject,
					FunctionToGoFromObjectToAdditionalIds = GetAdditionalIdsForObject
				};
			var dataFilePath = GetDataFilePath(Cache);
			var additionalPaths = GetAdditionalLexiconFilePaths(Cache);
			const string idAttrForOtherFiles = "guid"; // .lexdb chorus notes files identify FLEx object with a url attr of "guid".
			m_notesBar = m_chorusSystem.WinForms.CreateNotesBar(dataFilePath, additionalPaths, idAttrForOtherFiles, notesToRecordMapping, new NullProgress());
			m_notesBar.SetTargetObject(m_obj);
			// Set the writing systems for the NoteDetailDialog.  (See FWNX-1239.)
			var vernWs = Cache.ServiceLocator.WritingSystems.DefaultVernacularWritingSystem;
			var labelWs = new ChorusWritingSystem(vernWs.LanguageName, vernWs.RFC5646, vernWs.DefaultFontName, 12);
			m_notesBar.LabelWritingSystem = labelWs;
			var analWs = Cache.ServiceLocator.WritingSystems.DefaultAnalysisWritingSystem;
			var msgWs = new ChorusWritingSystem (analWs.LanguageName, analWs.RFC5646, analWs.DefaultFontName, 12);
			m_notesBar.MessageWritingSystem = msgWs;
			this.Control = m_notesBar;
		}
		/// <summary>
		/// Start doing whatever is needed for the supported type of action.
		/// </summary>
		public void StartWorking(Dictionary<string, string> commandLineArgs)
		{
			_fwProjectFolder = Path.GetDirectoryName(commandLineArgs["-p"]);

			MainForm = new MainBridgeForm
				{
					ClientSize = new Size(904, 510)
				};
			_chorusUser = new ChorusUser(commandLineArgs["-u"]);
			_chorusSystem = Utilities.InitializeChorusSystem(Utilities.LiftOffset(_fwProjectFolder), _chorusUser.Name, LiftFolder.AddLiftFileInfoToFolderConfiguration);
			_chorusSystem.EnsureAllNotesRepositoriesLoaded();

			_notesBrowser = _chorusSystem.WinForms.CreateNotesBrowser();
			var conflictHandler = _notesBrowser.MessageContentHandlerRepository.KnownHandlers.OfType<MergeConflictEmbeddedMessageContentHandler>().First();

			_chorusSystem.NavigateToRecordEvent.Subscribe(JumpToLiftObject);
			conflictHandler.HtmlAdjuster = AdjustConflictHtml;
			if (_connectionHelper != null)
				JumpUrlChanged += _connectionHelper.SendJumpUrlToFlex;

			var viewer = new BridgeConflictView();
			MainForm.Controls.Add(viewer);
			MainForm.Text = viewer.Text;
			viewer.Dock = DockStyle.Fill;
			viewer.SetBrowseView(_notesBrowser);

			// Only used by FLEx, so how can it not be in use?
			//if (_currentLanguageProject.FieldWorkProjectInUse)
			//	viewer.EnableWarning();
			viewer.SetProjectName(LiftUtilties.GetLiftProjectName(_fwProjectFolder));
		}
Example #3
0
        internal Shell CreateShell(BrowseForRepositoryEvent browseForRepositoryEvent, Arguments arguments)
        {
            var builder = new Autofac.ContainerBuilder();

            ChorusUIComponentsInjector.Inject(builder, _projectPath, SyncUIFeatures.Advanced);

            builder.RegisterInstance(browseForRepositoryEvent).As<BrowseForRepositoryEvent>().SingleInstance();

            //For now, we like the idea of just using the login name.  But
            //this allows someone to override that in the ini (which would be for all users of this machine, then)
            builder.Register<IChorusUser>(c => new ChorusUser(c.Resolve<HgRepository>().GetUserNameFromIni(new NullProgress(), System.Environment.UserName)));

            builder.RegisterType<Shell>();
            if(arguments!=null)
            {
                builder.RegisterInstance(arguments);
                Synchronizer.s_testingDoNotPush = arguments.DontPush; //hack, at this point it would take a lot of plumbing
                    //to get this properly to any synchronizer that is created.  Can be fixed if/when we go to the
                //autofac generated factor approach
            }

            _container = builder.Build();
            var shell= _container.Resolve<Shell>();

            var system = new ChorusSystem(_projectPath);
            system.Init(string.Empty);

            shell.AddPage("Review", system.WinForms.CreateHistoryPage());
            shell.AddPage("Notes", system.WinForms.CreateNotesBrowser());
            shell.AddPage("Send/Receive", _container.Resolve<SyncPanel>());
            shell.AddPage("Settings", _container.Resolve<SettingsView>());
            shell.AddPage("Troubleshooting", _container.Resolve<TroubleshootingView>());

            return shell;
        }
Example #4
0
        public DataEditor(ChorusSystem chorusSystem, string dataFilePath)
        {
            _chorusSystem = chorusSystem;
            _dataFilePath = dataFilePath;
            InitializeComponent();

            var notesToRecordMapping = new NotesToRecordMapping()
                                           {
                                               FunctionToGetCurrentUrlForNewNotes = GetCurrentUrlForNewNotes,
                                               FunctionToGoFromObjectToItsId = GetIdForObject
                                           };

            _notesBar = _chorusSystem.WinForms.CreateNotesBar(dataFilePath, notesToRecordMapping, new NullProgress());
            _notesBar.Location = new Point(10, 6);
            this.Controls.Add(_notesBar);

            XmlDocument doc = new XmlDocument();
            doc.Load(dataFilePath);

            var areas = doc.SelectNodes("//area");

            _area1Text.Tag = _area1Label.Text = areas[0].Attributes["id"].Value;
            _area1Text.Text = areas[0].InnerText.Trim();

            _area2Text.Tag = _area2Label.Text = areas[1].Attributes["id"].Value;
            _area2Text.Text = areas[1].InnerText.Trim();
        }
Example #5
0
        //, Form formWithContextForInvokingErrorDialogs)
        /// <summary>
        ///
        /// </summary>
        /// <param name="chorusSystem"></param>
        /// <param name="getFormWithContextForInvokingErrorDialogs">using a function here rather than a value
        /// becuase this class is created by the dependency injection system while building up this for (a
        /// project window), so that value isn't available yet.</param>
        public SendReceiver(ChorusSystem chorusSystem, Func<Form> getFormWithContextForInvokingErrorDialogs )
        {
            _getFormWithContextForInvokingErrorDialogs = getFormWithContextForInvokingErrorDialogs;
            //Guard.AgainstNull(formWithContextForInvokingErrorDialogs, "formWithContextForInvokingErrorDialogs");
            //_formWithContextForInvokingErrorDialogs = formWithContextForInvokingErrorDialogs;

            //we don't do chorus on our source tree
            SendReceiveDisabled = !Settings.Default.ShowSendReceive || !chorusSystem.DidLoadUpCorrectly || chorusSystem.ProjectFolderConfiguration.FolderPath.ToLower().Contains("distfiles");

            if (!SendReceiveDisabled)
            {
                _chorusSystem = chorusSystem;
                BloomChorusRules.AddFileInfoToFolderConfiguration(_chorusSystem.ProjectFolderConfiguration);
            }
        }
        //autofac uses this
        public HistoryAndNotesDialog(ChorusSystem chorusSystem)
        {
            InitializeComponent();

            #if notes
            var notes = chorusSystem.WinForms.CreateNotesBrowser();
            notes.Dock = DockStyle.Fill;
            _notesPage.Controls.Add(notes);
            #else
            tabControl1.Controls.Remove(_notesPage);
            #endif
            var history = chorusSystem.WinForms.CreateHistoryPage();
            history.Dock = DockStyle.Fill;
            _historyPage.Controls.Add(history);
        }
Example #7
0
        private void ChangeSimulatedUser(string userName)
        {
            ClearOutInAnticipationOfSwitchingUsers();

             var dir = Path.Combine(_testDirectory, userName);
             if (!Directory.Exists(dir))
             {
                 UnZipToDirectory(dir);
             }

            var shoppingListDir = Path.Combine(dir, "ShoppingList");

            //note: if you don't have a user name, you can just let chorus try to figure one out.
            //Also note that this is not the same name as that used for any given network repository credentials;
            //Rather, it's the name which will show in the history, and besides Notes that this user makes.
            _chorusSystem = new ChorusSystem(shoppingListDir);
            _chorusSystem.DisplaySettings = new ChorusNotesDisplaySettings()
            {
                WritingSystemForNoteLabel = new TestWritingSystem("Algerian"),
                WritingSystemForNoteContent = new TestWritingSystem("Bradley Hand ITC")
            };

            _chorusSystem.Init(userName);

            _chorusSystem.Repository.SetKnownRepositoryAddresses(new RepositoryAddress[] {_serverRepository});

            _chorusSystem.ProjectFolderConfiguration.IncludePatterns.Add("*.xml");

            _dataEditor = new DataEditor(_chorusSystem, Path.Combine(shoppingListDir, "shopping.xml"));
            _dataEditor.Dock = DockStyle.Fill;
            _frontPage.Controls.Add(_dataEditor);

            /*
             * Eberhard: I commented out the following lines because these components use the
             * Windows Forms WebBrowser. When we try to bring up the GeckoTestDlg this causes
             * a crash on Linux.
            _notesBrowserControl = _chorusSystem.WinForms.CreateNotesBrowser();
            _notesBrowserControl.Dock = DockStyle.Fill;
            _notesPage.Controls.Add(_notesBrowserControl);

            _historyControl = _chorusSystem.WinForms.CreateHistoryPage();
            _historyControl.Dock = DockStyle.Fill;
            _historyPage.Controls.Add(_historyControl);
            */
        }
Example #8
0
        internal Shell CreateShell(BrowseForRepositoryEvent browseForRepositoryEvent, Arguments arguments)
        {
            var builder = new Autofac.ContainerBuilder();

            ChorusUIComponentsInjector.Inject(builder, _projectPath, SyncUIFeatures.Advanced);

            builder.RegisterInstance(browseForRepositoryEvent).As <BrowseForRepositoryEvent>().SingleInstance();

            //For now, we like the idea of just using the login name.  But
            //this allows someone to override that in the ini (which would be for all users of this machine, then)
            builder.Register <IChorusUser>(c => new ChorusUser(c.Resolve <HgRepository>().GetUserNameFromIni(new NullProgress(), System.Environment.UserName)));

            builder.RegisterType <Shell>();
            if (arguments != null)
            {
                builder.RegisterInstance(arguments);
                Synchronizer.s_testingDoNotPush = arguments.DontPush;                 //hack, at this point it would take a lot of plumbing
                //to get this properly to any synchronizer that is created.  Can be fixed if/when we go to the
                //autofac generated factor approach
            }

            _container = builder.Build();
            var shell = _container.Resolve <Shell>();

            var system = new ChorusSystem(_projectPath);

            system.Init(string.Empty);

            shell.AddPage("Review", system.WinForms.CreateHistoryPage());
            shell.AddPage("Notes", system.WinForms.CreateNotesBrowser());
            shell.AddPage("Send/Receive", _container.Resolve <SyncPanel>());
            shell.AddPage("Settings", _container.Resolve <SettingsView>());
            shell.AddPage("Troubleshooting", _container.Resolve <TroubleshootingView>());

            return(shell);
        }
Example #9
0
 public void Dispose()
 {
     if(_chorusSystem!=null)
         _chorusSystem.Dispose();
     _chorusSystem = null;
 }
Example #10
0
 public WinFormsFactory(ChorusSystem parent, IContainer container)
 {
     _parent = parent;
     _container = container;
 }
Example #11
0
        /// ------------------------------------------------------------------------------------
        protected void BuildSubContainerForThisProject(string projectSettingsPath, IContainer parentContainer)
        {
            var editableCollectionDirectory = Path.GetDirectoryName(projectSettingsPath);
            _scope = parentContainer.BeginLifetimeScope(builder =>
            {
                //BloomEvents are by nature, singletons (InstancePerLifetimeScope)
                builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
                    .InstancePerLifetimeScope()
                    // Didn't work .Where(t => t.GetInterfaces().Contains(typeof(Bloom.Event<>)));
                    .Where(t => t is IEvent);

                //Other classes which are also  singletons
                builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
                    .InstancePerLifetimeScope()
                    .Where(t => new[]{
                    typeof(TemplateInsertionCommand),
                    typeof(DeletePageCommand),
                    typeof(EditBookCommand),
                    typeof(SendReceiveCommand),
                    typeof(SelectedTabAboutToChangeEvent),
                    typeof(SelectedTabChangedEvent),
                    typeof(BookRenamedEvent),
                    typeof(LibraryClosing),
                    typeof(PageListChangedEvent),  // REMOVE+++++++++++++++++++++++++++
                    typeof(BookRefreshEvent),
                    typeof(BookSelection),
                    typeof(CurrentEditableCollectionSelection),
                    typeof(RelocatePageEvent),
                    typeof(QueueRenameOfCollection),
                    typeof(PageSelection),
                    typeof(BloomParseClient),
                    typeof(EditingModel)}.Contains(t));

                try
                {
                    //nb: we split out the ChorusSystem.Init() so that this won't ever fail, so we have something registered even if we aren't
                    //going to be able to do HG for some reason.
                    var chorusSystem = new ChorusSystem(Path.GetDirectoryName(projectSettingsPath));
                    builder.Register<ChorusSystem>(c => chorusSystem).InstancePerLifetimeScope();
                    builder.Register<SendReceiver>(c => new SendReceiver(chorusSystem,()=>ProjectWindow)).InstancePerLifetimeScope();
                    chorusSystem.Init(string.Empty/*user name*/);
                }
                catch (Exception error)
                {
                    Palaso.Reporting.ErrorReport.NotifyUserOfProblem(error,
                        "There was a problem loading the Chorus Send/Receive system for this collection. Bloom will try to limp along, but you'll need technical help to resolve this. If you have no other choice, find this folder: {0}, move it somewhere safe, and restart Bloom.", Path.GetDirectoryName(projectSettingsPath).CombineForPath(".hg"));
                }

                //This deserves some explanation:
                //*every* collection has a "*.BloomCollection" settings file. But the one we make the most use of is the one editable collection
                //That's why we're registering it... it gets used all over. At the moment (May 2012), we don't ever read the
                //settings file of the collections we're using for sources.
                try
                {
                    builder.Register<CollectionSettings>(c => new CollectionSettings(projectSettingsPath)).InstancePerLifetimeScope();
                }
                catch(Exception)
                {
                    return;
                }

                builder.Register<LibraryModel>(c => new LibraryModel(editableCollectionDirectory, c.Resolve<CollectionSettings>(), c.Resolve<SendReceiver>(), c.Resolve<BookSelection>(), c.Resolve<SourceCollectionsList>(), c.Resolve<BookCollection.Factory>(), c.Resolve<EditBookCommand>(),c.Resolve<CreateFromSourceBookCommand>(),c.Resolve<BookServer>(), c.Resolve<CurrentEditableCollectionSelection>())).InstancePerLifetimeScope();

                builder.Register<IChangeableFileLocator>(c => new BloomFileLocator(c.Resolve<CollectionSettings>(), c.Resolve<XMatterPackFinder>(), GetFactoryFileLocations(),GetFoundFileLocations())).InstancePerLifetimeScope();

                const int kListViewIconHeightAndWidth = 70;
                builder.Register<HtmlThumbNailer>(c => new HtmlThumbNailer(kListViewIconHeightAndWidth, kListViewIconHeightAndWidth)).InstancePerLifetimeScope();

                builder.Register<LanguageSettings>(c =>
                                                    {
                                                        var librarySettings = c.Resolve<CollectionSettings>();
                                                        var preferredSourceLanguagesInOrder = new List<string>();
                                                        preferredSourceLanguagesInOrder.Add(librarySettings.Language2Iso639Code);
                                                        if (!string.IsNullOrEmpty(librarySettings.Language3Iso639Code)
                                                            && librarySettings.Language3Iso639Code != librarySettings.Language2Iso639Code)
                                                            preferredSourceLanguagesInOrder.Add(librarySettings.Language3Iso639Code);

                                                        return new LanguageSettings(librarySettings.Language1Iso639Code, preferredSourceLanguagesInOrder);
                                                    });
                builder.Register<XMatterPackFinder>(c =>
                                                        {
                                                            var locations = new List<string>();
                                                            locations.Add(FileLocator.GetDirectoryDistributedWithApplication("xMatter"));
                                                            locations.Add(XMatterAppDataFolder);
                                                            return new XMatterPackFinder(locations);
                                                        });

                builder.Register<SourceCollectionsList>(c =>
                     {
                         var l = new SourceCollectionsList(c.Resolve<Book.Book.Factory>(), c.Resolve<BookStorage.Factory>(), c.Resolve<BookCollection.Factory>(), editableCollectionDirectory);
                         l.RepositoryFolders = new string[] { FactoryCollectionsDirectory, InstalledCollectionsDirectory };
                         return l;
                     }).InstancePerLifetimeScope();

                builder.Register<ITemplateFinder>(c =>
                     {
                         return c.Resolve<SourceCollectionsList>();
                     }).InstancePerLifetimeScope();

                //TODO: this gave a stackoverflow exception
            //				builder.Register<WorkspaceModel>(c => c.Resolve<WorkspaceModel.Factory>()(rootDirectoryPath)).InstancePerLifetimeScope();
                //so we're doing this
                builder.Register(c=>editableCollectionDirectory).InstancePerLifetimeScope();

                builder.RegisterType<CreateFromSourceBookCommand>().InstancePerLifetimeScope();

                builder.Register<Func<WorkspaceView>>(c => ()=>
                                                    {
                                                        var factory = c.Resolve<WorkspaceView.Factory>();
                                                        if (projectSettingsPath.ToLower().Contains("web"))
                                                        {
                                                            return factory(c.Resolve<WebLibraryView>());
                                                        }
                                                        else
                                                        {
                                                            return factory(c.Resolve<LibraryView>());
                                                        }
                                                    });
            });
        }
Example #12
0
        public void Dispose()
        {
            if(_chorusSystem!=null)
                _chorusSystem.Dispose();
            _chorusSystem = null;

            GC.SuppressFinalize(this);
        }
Example #13
0
 /// <summary>
 /// Creates and initializes the ChorusSystem for use in FLExBridge
 /// </summary>
 public static ChorusSystem InitializeChorusSystem(string directoryName, string user, Action<ProjectFolderConfiguration> configure)
 {
     var system = new ChorusSystem(directoryName);
     system.Init(user);
     if (configure != null)
         configure(system.ProjectFolderConfiguration);
     return system;
 }
Example #14
0
 public WinFormsFactory(ChorusSystem parent, IContainer container)
 {
     _parent    = parent;
     _container = container;
 }
Example #15
0
		/// <summary>
		/// Determine if the object really has data to be shown in the slice. This method is called by reflection
		/// from DataTree.AddSimpleNode, to determine whether to create the slice when visibility is "ifdata".
		/// </summary>
		/// <param name="obj">object to check; should be an ILexEntry</param>
		/// <returns>true if there are chorus notes for this object; false otherwise</returns>
		public static bool ShowSliceForVisibleIfData(XmlNode node, ICmObject obj)
		{
			using (var chorusSystem = new ChorusSystem(obj.Cache.ProjectId.ProjectFolder))
			{
				chorusSystem.InitWithoutHg(SendReceiveUser);
				// This is a required object for CreateNotesBar. It specifies delegates for getting the information
				// the bar requires about the current object. For this model the FunctionToGetCurrentUrlForNewNotes will not be used.
				var notesToRecordMapping = new NotesToRecordMapping()
				{
					FunctionToGetCurrentUrlForNewNotes = DummyGetCurrentUrlForNewNotes,
					FunctionToGoFromObjectToItsId = GetIdForObject
				};
				var dataFilePath = GetDataFilePath(obj.Cache);
				var notesmodel = chorusSystem.WinForms.CreateNotesBarModel(dataFilePath, notesToRecordMapping, new NullProgress());
				notesmodel.SetTargetObject(obj);
				return notesmodel.GetAnnotationsToShow().Any();
			}
		}
Example #16
0
        //autofac uses this
        public WorkspaceView(WorkspaceModel model,
							 Control libraryView,
							 EditingView.Factory editingViewFactory,
							 PublishView.Factory pdfViewFactory,
							 CollectionSettingsDialog.Factory settingsDialogFactory,
							 EditBookCommand editBookCommand,
							SendReceiveCommand sendReceiveCommand,
							 SelectedTabAboutToChangeEvent selectedTabAboutToChangeEvent,
							SelectedTabChangedEvent selectedTabChangedEvent,
							 FeedbackDialog.Factory feedbackDialogFactory,
							ChorusSystem chorusSystem,
							Sparkle sparkleApplicationUpdater,
							LocalizationManager localizationManager

			)
        {
            _model = model;
            _settingsDialogFactory = settingsDialogFactory;
            _selectedTabAboutToChangeEvent = selectedTabAboutToChangeEvent;
            _selectedTabChangedEvent = selectedTabChangedEvent;
            _feedbackDialogFactory = feedbackDialogFactory;
            _chorusSystem = chorusSystem;
            _sparkleApplicationUpdater = sparkleApplicationUpdater;
            _localizationManager = localizationManager;
            _model.UpdateDisplay += new System.EventHandler(OnUpdateDisplay);
            InitializeComponent();

            #if !DEBUG
            _sparkleApplicationUpdater.CheckOnFirstApplicationIdle();
            #endif
            _toolStrip.Renderer = new NoBorderToolStripRenderer();

            //we have a number of buttons which don't make sense for the remote (therefore vulnerable) low-end user
            //_settingsLauncherHelper.CustomSettingsControl = _toolStrip;

            _settingsLauncherHelper.ManageComponent(_settingsButton);

            //NB: the rest of these aren't really settings, but we're using that feature to simplify this menu down to what makes sense for the easily-confused user
            _settingsLauncherHelper.ManageComponent(_openCreateCollectionButton);
            _settingsLauncherHelper.ManageComponent(deepBloomPaperToolStripMenuItem);
            _settingsLauncherHelper.ManageComponent(_makeASuggestionMenuItem);
            _settingsLauncherHelper.ManageComponent(_webSiteMenuItem);
            _settingsLauncherHelper.ManageComponent(_showLogMenuItem);
            _settingsLauncherHelper.ManageComponent(_releaseNotesMenuItem);
            _settingsLauncherHelper.ManageComponent(_divider2);
            _settingsLauncherHelper.ManageComponent(_divider3);
            _settingsLauncherHelper.ManageComponent(_divider4);

            OnSettingsProtectionChanged(this, null);//initial setup
            SettingsProtectionSettings.Default.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(OnSettingsProtectionChanged);

            _uiLanguageMenu.Visible = true;
               _settingsLauncherHelper.ManageComponent(_uiLanguageMenu);

            editBookCommand.Subscribe(OnEditBook);
            sendReceiveCommand.Subscribe(OnSendReceive);

            //Cursor = Cursors.AppStarting;
            Application.Idle += new EventHandler(Application_Idle);
            Text = _model.ProjectName;

            //SetupTabIcons();

            //
            // _collectionView
            //
            this._collectionView = (LibraryView) libraryView;
            this._collectionView.Dock = System.Windows.Forms.DockStyle.Fill;

            //
            // _editingView
            //
            this._editingView = editingViewFactory();
            this._editingView.Dock = System.Windows.Forms.DockStyle.Fill;

            //
            // _pdfView
            //
            this._publishView = pdfViewFactory();
            this._publishView.Dock = System.Windows.Forms.DockStyle.Fill;

            _collectionTab.Tag = _collectionView;
            _publishTab.Tag = _publishView;
            _editTab.Tag = _editingView;

            this._collectionTab.Text = _collectionView.CollectionTabLabel;

            SetTabVisibility(_publishTab, false);
            SetTabVisibility(_editTab, false);

            //			if (Program.StartUpWithFirstOrNewVersionBehavior)
            //			{
            //				_tabStrip.SelectedTab = _infoTab;
            //				SelectPage(_infoView);
            //			}
            //			else
            //			{
                _tabStrip.SelectedTab = _collectionTab;
                SelectPage(_collectionView);
            //			}

            SetupUILanguageMenu();
        }
		/// <summary>
		/// Open the given repo in the 'HistoryPage' control and its sub-system of controls.
		/// </summary>
		private void OpenLocalRepo()
		{
			if (string.IsNullOrWhiteSpace(_repoFolder))
				return;

			SuspendLayout();
			if (_historyPage != null)
			{
				_historyPage.RevisionSelectionChanged -= HistoryPageRevisionSelectionChanged;
				Controls.Remove(_historyPage);
				_historyPage.Dispose();
				_historyPage = null;
			}
			if (_chorusSystem != null)
			{
				_chorusSystem.Dispose();
				_chorusSystem = null;
			}

			var repoType = GetRepoType();
			ChorusSystem newChorusSystem;
			switch (repoType)
			{
				case RepoType.None:
					return;
				case RepoType.NotSupported:
					MessageBox.Show(this, "The selected repository is not supported.", "Unsupported Repository Type",
						MessageBoxButtons.OK, MessageBoxIcon.Warning);
					return;
				case RepoType.LIFT:
					newChorusSystem = Utilities.InitializeChorusSystem(_repoFolder, Environment.UserName, LiftFolder.AddLiftFileInfoToFolderConfiguration);
					break;
				case RepoType.FLEx:
					newChorusSystem = Utilities.InitializeChorusSystem(_repoFolder, Environment.UserName, FlexFolderSystem.ConfigureChorusProjectFolder);
					break;
				default:
					MessageBox.Show(this, "The selected repository is recognized, but not yet supported.", "Unsupported Repository Type",
						MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
					return;
			}
			_chorusSystem = newChorusSystem;

			// Set up some new columns in the main control of the history page.
			// This makes it easy for the user to know the selected revision's branch and simple rev id.
			var historyPageOptions = new HistoryPageOptions();
			var revisionListOptions = historyPageOptions.RevisionListOptions;
			// Not enabled in Chorus. revisionListOptions.ShowRevisionChoiceControls = true;
			var branchColumnDefinition = new HistoryColumnDefinition
			{
				ColumnLabel = "Branch",
				StringSupplier = BranchName
			};
			// This is available as a tool tip of the icon cell, but show it here, anyway.
			var revisionIdColumnDefinition = new HistoryColumnDefinition
			{
				ColumnLabel = "Revision Id",
				StringSupplier = RevisionId
			};
			revisionListOptions.ExtraColumns = new List<HistoryColumnDefinition>
				{
					branchColumnDefinition,
					revisionIdColumnDefinition
				};
			_historyPage = _chorusSystem.WinForms.CreateHistoryPage(historyPageOptions);
			_historyPage.RevisionSelectionChanged += HistoryPageRevisionSelectionChanged;
			Controls.Add(_historyPage);
			_historyPage.Dock = DockStyle.Fill;

			ResumeLayout(true);
			pullFileFromRevisionRangeToolStripMenuItem.Enabled = true;
		}
		public GetFileFromRevisionRange(string repoLocation, ChorusSystem chorusSystem)
		{
			InitializeComponent();
			_repoLocation = repoLocation;
			_chorusSystem = chorusSystem;
		}