Changeset 3557
- Timestamp:
- 04/29/10 15:10:17 (15 years ago)
- Location:
- trunk/sources
- Files:
-
- 24 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Core.Views/3.3/Clipboard.cs
r3526 r3557 231 231 if (listView.SelectedItems.Count == 1) { 232 232 T item = (T)listView.SelectedItems[0].Tag; 233 IView view = MainFormManager. CreateDefaultView(item);233 IView view = MainFormManager.MainForm.ShowContent(item); 234 234 if (view != null) { 235 235 view.ReadOnly = this.ReadOnly; 236 view.Show();237 236 } 238 237 } -
trunk/sources/HeuristicLab.Core.Views/3.3/ItemArrayView.cs
r3526 r3557 229 229 T item = itemsListView.SelectedItems[0].Tag as T; 230 230 if (item != null) { 231 IContentView view = MainFormManager. CreateDefaultView(item);231 IContentView view = MainFormManager.MainForm.ShowContent(item); 232 232 if (view != null) { 233 233 view.ReadOnly = ReadOnly; 234 234 view.Locked = Locked; 235 view.Show();236 235 } 237 236 } -
trunk/sources/HeuristicLab.Core.Views/3.3/ItemCollectionView.cs
r3526 r3557 189 189 if (itemsListView.SelectedItems.Count == 1) { 190 190 T item = (T)itemsListView.SelectedItems[0].Tag; 191 IContentView view = MainFormManager. CreateDefaultView(item);191 IContentView view = MainFormManager.MainForm.ShowContent(item); 192 192 if (view != null) { 193 193 view.ReadOnly = ReadOnly; 194 194 view.Locked = Locked; 195 view.Show();196 195 } 197 196 } -
trunk/sources/HeuristicLab.Core.Views/3.3/ItemListView.cs
r3526 r3557 223 223 if (itemsListView.SelectedItems.Count == 1) { 224 224 T item = (T)itemsListView.SelectedItems[0].Tag; 225 IContentView view = MainFormManager. CreateDefaultView(item);225 IContentView view = MainFormManager.MainForm.ShowContent(item); 226 226 if (view != null) { 227 227 view.ReadOnly = ReadOnly; 228 228 view.Locked = Locked; 229 view.Show();230 229 } 231 230 } -
trunk/sources/HeuristicLab.Core.Views/3.3/OperatorTreeView.cs
r3432 r3557 355 355 IOperator op = GetOperatorTag(graphTreeView.SelectedNode); 356 356 if (op != null) { 357 IContentView view = MainFormManager.CreateDefaultView(op); 358 if (view != null) { 359 view.ReadOnly = this.ReadOnly; 360 view.Locked = this.Locked; 357 Type viewType = MainFormManager.GetDefaultViewType(op.GetType()); 358 if (viewType != null) { 361 359 viewToolStripMenuItem.Enabled = true; 362 viewToolStripMenuItem.Tag = view;360 viewToolStripMenuItem.Tag = op; 363 361 } 364 362 breakpointToolStripMenuItem.Enabled = true; … … 414 412 #region Context Menu Events 415 413 private void viewToolStripMenuItem_Click(object sender, EventArgs e) { 416 IView view = ((ToolStripMenuItem)sender).Tag as IView; 417 if (view != null) view.Show(); 414 IOperator op = ((ToolStripMenuItem)sender).Tag as IOperator; 415 IContentView view = MainFormManager.MainForm.ShowContent(op); 416 if (view != null) { 417 view.ReadOnly = this.ReadOnly; 418 view.Locked = this.Locked; 419 } 418 420 } 419 421 private void breakpointToolStripMenuItem_Click(object sender, EventArgs e) { -
trunk/sources/HeuristicLab.MainForm.WindowsForms/3.3/ContentView.cs
r3483 r3557 37 37 get { return content; } 38 38 set { 39 if ((value != null) && (!MainFormManager.ViewCanView Object(this, value)))39 if ((value != null) && (!MainFormManager.ViewCanViewContent(this, value))) 40 40 throw new ArgumentException(string.Format("View \"{0}\" cannot view object \"{1}\".", this.GetType().Name, value.GetType().Name)); 41 41 if (InvokeRequired) { … … 57 57 InitializeComponent(); 58 58 this.locked = false; 59 }60 public ContentView(IContent content)61 : this() {62 this.content = content;63 59 } 64 60 -
trunk/sources/HeuristicLab.MainForm.WindowsForms/3.3/DockingMainForm.cs
r3437 r3557 40 40 InitializeComponent(); 41 41 } 42 public DockingMainForm(Type userInterfaceItemType, bool show ViewsInViewHost)42 public DockingMainForm(Type userInterfaceItemType, bool showContentInViewHost) 43 43 : this(userInterfaceItemType) { 44 this.Show ViewsInViewHost = showViewsInViewHost;44 this.ShowContentInViewHost = showContentInViewHost; 45 45 } 46 46 … … 67 67 68 68 protected override Form CreateForm(IView view) { 69 DockForm form; 70 IContentView contentView = view as IContentView; 71 if (ShowViewsInViewHost && contentView != null && contentView.GetType() != typeof(ViewHost)) { 72 ViewHost viewHost = new ViewHost(contentView); 73 form = new DockForm(viewHost); 74 this.AddViewFormCombination(viewHost, form); 75 } else { 76 form = new DockForm(view); 77 this.AddViewFormCombination(view, form); 78 } 79 return form; 69 return new DockForm(view); 80 70 } 81 71 -
trunk/sources/HeuristicLab.MainForm.WindowsForms/3.3/MainForm.cs
r3488 r3557 32 32 using System.Collections; 33 33 using WeifenLuo.WinFormsUI.Docking; 34 using HeuristicLab.Common; 34 35 35 36 namespace HeuristicLab.MainForm.WindowsForms { … … 43 44 this.userInterfaceItems = new List<IUserInterfaceItem>(); 44 45 this.initialized = false; 45 this.show ViewsInViewHost = false;46 this.showContentInViewHost = false; 46 47 } 47 48 … … 52 53 53 54 #region properties 54 private bool show ViewsInViewHost;55 public bool Show ViewsInViewHost {56 get { return this.show ViewsInViewHost; }57 set { this.show ViewsInViewHost = value; }55 private bool showContentInViewHost; 56 public bool ShowContentInViewHost { 57 get { return this.showContentInViewHost; } 58 set { this.showContentInViewHost = value; } 58 59 } 59 60 … … 88 89 public IEnumerable<IView> Views { 89 90 get { return views.Keys; } 90 }91 protected void AddViewFormCombination(IView view, Form form) {92 this.views.Add(view, form);93 view.Changed += new EventHandler(View_Changed);94 91 } 95 92 … … 216 213 217 214 internal Form GetForm(IView view) { 218 IView internalView = GetView(view); 219 if (internalView != null && views.ContainsKey(internalView)) 220 return views[internalView]; 215 if (views.ContainsKey(view)) 216 return views[view]; 221 217 return null; 222 218 } … … 224 220 return views.Where(x => x.Value == form).Single().Key; 225 221 } 226 private IView GetView(IView view) { 227 if (view == null || views.ContainsKey(view)) 228 return view; 229 IContentView contentView = view as IContentView; 230 if (contentView != null) { 231 IView viewHost = 232 (from ViewHost v in views.Keys.OfType<ViewHost>() 233 where v.Views.Contains(contentView) 234 select v).SingleOrDefault(); 235 return viewHost; 236 } 237 return contentView; 222 223 public IContentView ShowContent(IContent content) { 224 IContentView view; 225 if (this.ShowContentInViewHost) 226 view = new ViewHost(); 227 else 228 view = MainFormManager.CreateDefaultView(content.GetType()); 229 230 if (view != null) { 231 view.Show(); 232 view.Content = content; 233 } 234 return view; 238 235 } 239 236 … … 243 240 Form form = GetForm(view); 244 241 bool firstTimeShown = form == null; 245 if (f orm == null) {242 if (firstTimeShown) { 246 243 form = CreateForm(view); 247 244 form.Activated += new EventHandler(FormActivated); 248 245 form.FormClosed += new FormClosedEventHandler(ChildFormClosed); 249 } 250 IView internalView = GetView(form); 251 this.ShowView(internalView, firstTimeShown); 252 this.OnViewShown(internalView, firstTimeShown); 246 view.Changed += new EventHandler(View_Changed); 247 views[view] = form; 248 } 249 this.ShowView(view, firstTimeShown); 250 this.OnViewShown(view, firstTimeShown); 253 251 } 254 252 } … … 267 265 if (InvokeRequired) Invoke((Action<IView>)HideView, view); 268 266 else { 269 IView internalView = this.GetView(view); 270 if (internalView != null && this.views.ContainsKey(internalView)) { 271 this.Hide(internalView); 272 if (this.activeView == internalView) 273 this.ActiveView = null; 274 this.OnViewHidden(internalView); 275 } 267 this.Hide(view); 268 if (this.activeView == view) 269 this.ActiveView = null; 270 this.OnViewHidden(view); 276 271 } 277 272 } … … 296 291 internal void CloseView(IView view) { 297 292 if (InvokeRequired) Invoke((Action<IView>)CloseView, view); 298 else { 299 IView internalView = GetView(view); 300 if (internalView != null && this.views.ContainsKey(internalView)) { 301 this.views[internalView].Close(); 302 this.OnViewClosed(internalView); 303 } 293 else if (views.ContainsKey(view)) { 294 this.views[view].Close(); 295 this.OnViewClosed(view); 304 296 } 305 297 } … … 307 299 internal void CloseView(IView view, CloseReason closeReason) { 308 300 if (InvokeRequired) Invoke((Action<IView>)CloseView, view); 309 else { 310 IView internalView = GetView(view); 311 if (internalView != null && this.views.ContainsKey(internalView)) { 312 ((View)internalView).CloseReason = closeReason; 313 this.CloseView(internalView); 314 } 301 else if (views.ContainsKey(view)) { 302 ((View)view).CloseReason = closeReason; 303 this.CloseView(view); 315 304 } 316 305 } -
trunk/sources/HeuristicLab.MainForm.WindowsForms/3.3/MultipleDocumentMainForm.cs
r3437 r3557 39 39 InitializeComponent(); 40 40 } 41 public MultipleDocumentMainForm(Type userInterfaceItemType, bool show ViewsInViewHost)41 public MultipleDocumentMainForm(Type userInterfaceItemType, bool showContentInViewHost) 42 42 : this(userInterfaceItemType) { 43 this.Show ViewsInViewHost = showViewsInViewHost;43 this.ShowContentInViewHost = showContentInViewHost; 44 44 } 45 45 … … 76 76 77 77 protected override Form CreateForm(IView view) { 78 Form form; 79 IContentView contentView = view as IContentView; 80 if (ShowViewsInViewHost && contentView != null && contentView.GetType() != typeof(ViewHost)) { 81 ViewHost viewHost = new ViewHost(contentView); 82 form = new DocumentForm(viewHost); 83 this.AddViewFormCombination(viewHost, form); 84 } else { 85 form = new DocumentForm(view); 86 this.AddViewFormCombination(view, form); 87 } 88 78 Form form = new DocumentForm(view); 89 79 form.MdiParent = this; 90 80 return form; -
trunk/sources/HeuristicLab.MainForm.WindowsForms/3.3/SingleDocumentMainForm.cs
r3437 r3557 40 40 InitializeComponent(); 41 41 } 42 public SingleDocumentMainForm(Type userInterfaceItemType, bool show ViewsInViewHost)42 public SingleDocumentMainForm(Type userInterfaceItemType, bool showContentInViewHost) 43 43 : this(userInterfaceItemType) { 44 this.Show ViewsInViewHost = showViewsInViewHost;44 this.ShowContentInViewHost = showContentInViewHost; 45 45 } 46 46 … … 70 70 71 71 protected override Form CreateForm(IView view) { 72 Form form; 73 IContentView contentView = view as IContentView; 74 if (ShowViewsInViewHost && contentView != null && contentView.GetType() != typeof(ViewHost)) { 75 ViewHost viewHost = new ViewHost(contentView); 76 form = new DocumentForm(viewHost); 77 this.AddViewFormCombination(viewHost, form); 78 } else { 79 form = new DocumentForm(view); 80 this.AddViewFormCombination(view, form); 81 } 82 72 Form form = new DocumentForm(view); 83 73 form.ShowInTaskbar = true; 84 74 return form; -
trunk/sources/HeuristicLab.MainForm.WindowsForms/3.3/View.cs
r3437 r3557 35 35 this.closeReason = CloseReason.None; 36 36 this.readOnly = false; 37 }38 39 public View(bool readOnly)40 : this() {41 this.readOnly = readOnly;42 37 } 43 38 -
trunk/sources/HeuristicLab.MainForm.WindowsForms/3.3/ViewHost.cs
r3552 r3557 28 28 29 29 namespace HeuristicLab.MainForm.WindowsForms { 30 [Content(typeof( object))]30 [Content(typeof(IContent))] 31 31 public sealed partial class ViewHost : AsynchronousContentView { 32 32 public ViewHost() { … … 39 39 Content = null; 40 40 OnContentChanged(); 41 }42 public ViewHost(IContent content)43 : this() {44 this.Content = content;45 }46 47 public ViewHost(IContentView contentView)48 : this() {49 this.viewType = contentView.GetType();50 this.Content = contentView.Content;51 this.cachedViews.Add(contentView.GetType(), contentView);52 this.activeView = contentView;53 this.RegisterActiveViewEvents();54 this.OnViewTypeChanged();55 this.ActiveViewChanged();56 41 } 57 42 … … 117 102 } 118 103 119 120 121 104 protected override void OnContentChanged() { 122 105 messageLabel.Visible = false; … … 133 116 } 134 117 135 136 118 if (!ViewCanShowContent(viewType, Content)) { 137 119 ViewType = MainFormManager.GetDefaultViewType(Content.GetType()); … … 148 130 } 149 131 } 150 151 132 152 133 private void OnViewTypeChanged() { … … 176 157 } 177 158 178 179 180 159 private void RegisterActiveViewEvents() { 181 160 activeView.Changed += new EventHandler(activeView_Changed); … … 256 235 257 236 private void viewsLabel_DoubleClick(object sender, EventArgs e) { 258 IContentView view = MainFormManager. CreateView(viewType,Content);237 IContentView view = MainFormManager.MainForm.ShowContent(this.Content); 259 238 view.ReadOnly = this.ReadOnly; 260 239 view.Locked = this.Locked; 261 view.Show();262 240 } 263 241 private void viewContextMenuStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { -
trunk/sources/HeuristicLab.MainForm/3.3/Interfaces/IMainForm.cs
r3437 r3557 26 26 using System.Drawing; 27 27 using System.ComponentModel; 28 using HeuristicLab.Common; 28 29 29 30 namespace HeuristicLab.MainForm { … … 41 42 event EventHandler<ViewEventArgs> ViewHidden; 42 43 44 IContentView ShowContent(IContent content); 45 43 46 Type UserInterfaceItemType { get; } 44 47 void CloseAllViews(); -
trunk/sources/HeuristicLab.MainForm/3.3/MainFormManager.cs
r3437 r3557 105 105 } 106 106 107 public static bool ViewCanView Object(IContentView view, IContent content) {107 public static bool ViewCanViewContent(IContentView view, IContent content) { 108 108 return ContentAttribute.CanViewType(view.GetType(), content.GetType()); 109 109 } … … 145 145 } 146 146 147 public static IContentView CreateDefaultView(object content) { 148 Type t = GetDefaultViewType(content.GetType()); 147 public static IContentView CreateDefaultView(Type contentType) { 148 CheckForContentType(contentType); 149 Type t = GetDefaultViewType(contentType); 149 150 if (t == null) 150 151 return null; 151 152 152 return (IContentView)Activator.CreateInstance(t , content);153 return (IContentView)Activator.CreateInstance(t); 153 154 } 154 155 public static IContentView CreateView(Type viewType) { 155 if (!typeof(IView).IsAssignableFrom(viewType)) 156 throw new ArgumentException("View can not be created becaues given type " + viewType.ToString() + " is not of type IView."); 156 CheckForContentViewType(viewType); 157 157 if (viewType.IsGenericTypeDefinition) 158 158 throw new ArgumentException("View can not be created becaues given type " + viewType.ToString() + " is a generic type definition."); 159 159 160 160 return (IContentView)Activator.CreateInstance(viewType); 161 }162 public static IContentView CreateView(Type viewType, object content) {163 CheckForContentType(content.GetType());164 CheckForContentViewType(viewType);165 166 Type view = viewType;167 if (view.IsGenericTypeDefinition)168 view = TransformGenericTypeDefinition(view, content.GetType());169 170 return (IContentView)Activator.CreateInstance(view, content);171 161 } 172 162 -
trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorGraphView.cs
r3556 r3557 157 157 if (shapeInfo != null) { 158 158 IOperator op = this.VisualizationInfo.GetOperatorForShapeInfo(shapeInfo); 159 IContentView view = MainFormManager. CreateDefaultView(op);159 IContentView view = MainFormManager.MainForm.ShowContent(op); 160 160 if (view != null) { 161 161 view.ReadOnly = this.ReadOnly; 162 162 view.Locked = this.Locked; 163 view.Show();164 163 } 165 164 HandledMouseEventArgs eventArgs = e as HandledMouseEventArgs; … … 197 196 if (shapeInfo != null) { 198 197 IOperator op = this.VisualizationInfo.GetOperatorForShapeInfo(shapeInfo); 199 IContentView view = MainFormManager.CreateDefaultView(op); 200 view.ReadOnly = this.ReadOnly; 201 view.Locked = this.Locked; 202 view.Show(); 198 IContentView view = MainFormManager.MainForm.ShowContent(op); 199 if (view != null) { 200 view.ReadOnly = this.ReadOnly; 201 view.Locked = this.Locked; 202 } 203 203 } 204 204 } -
trunk/sources/HeuristicLab.Optimization.Views/3.3/EngineAlgorithmView.cs
r3455 r3557 153 153 154 154 protected virtual void createUserDefinedAlgorithmButton_Click(object sender, EventArgs e) { 155 IContentView view = MainFormManager. CreateDefaultView(Content.CreateUserDefinedAlgorithm());155 IContentView view = MainFormManager.MainForm.ShowContent(Content.CreateUserDefinedAlgorithm()); 156 156 if (view != null) { 157 157 view.ReadOnly = this.ReadOnly; 158 158 view.Locked = this.Locked; 159 view.Show();160 159 } 161 160 } -
trunk/sources/HeuristicLab.Optimization.Views/3.3/RunCollectionBubbleChartView.cs
r3546 r3557 289 289 IRun run = (IRun)((DataPoint)h.Object).Tag; 290 290 if (e.Clicks >= 2) { 291 IContentView view = MainFormManager.CreateDefaultView(run); 292 view.ReadOnly = this.ReadOnly; 293 view.Locked = this.Locked; 294 view.Show(); 291 IContentView view = MainFormManager.MainForm.ShowContent(run); 292 if (view != null) { 293 view.ReadOnly = this.ReadOnly; 294 view.Locked = this.Locked; 295 } 295 296 } else 296 297 this.draggedRun = run; -
trunk/sources/HeuristicLab.Optimization.Views/3.3/RunCollectionTabularView.cs
r3546 r3557 102 102 if (e.RowIndex >= 0) { 103 103 IRun run = Content.ElementAt(virtualRowIndizes[e.RowIndex]); 104 IContentView view = MainFormManager. CreateDefaultView(run);104 IContentView view = MainFormManager.MainForm.ShowContent(run); 105 105 if (view != null) { 106 106 view.ReadOnly = this.ReadOnly; 107 107 view.Locked = this.Locked; 108 view.Show();109 108 } 110 109 } -
trunk/sources/HeuristicLab.Optimization.Views/3.3/RunCollectionView.cs
r3526 r3557 195 195 if (itemsListView.SelectedItems.Count == 1) { 196 196 IRun item = (IRun)itemsListView.SelectedItems[0].Tag; 197 IContentView view = MainFormManager. CreateDefaultView(item);197 IContentView view = MainFormManager.MainForm.ShowContent(item); 198 198 if (view != null) { 199 199 view.ReadOnly = ReadOnly; 200 200 view.Locked = Locked; 201 view.Show();202 201 } 203 202 } … … 242 241 protected virtual void menuItem_Click(object sender, EventArgs e) { 243 242 ToolStripMenuItem menuItem = (ToolStripMenuItem)sender; 244 IContentView view = MainFormManager.CreateView((Type)menuItem.Tag , Content);243 IContentView view = MainFormManager.CreateView((Type)menuItem.Tag); 245 244 if (view != null) { 246 245 view.Locked = Locked; 247 246 view.ReadOnly = ReadOnly; 248 247 view.Show(); 248 view.Content = Content; 249 249 } 250 250 } -
trunk/sources/HeuristicLab.Optimization.Views/3.3/RunView.cs
r3506 r3557 119 119 if (listView.SelectedItems.Count == 1) { 120 120 viewHost.ViewType = null; 121 viewHost.Content = (IContent) 121 viewHost.Content = (IContent)listView.SelectedItems[0].Tag; 122 122 } else { 123 123 viewHost.Content = null; … … 127 127 if (listView.SelectedItems.Count == 1) { 128 128 IItem item = (IItem)listView.SelectedItems[0].Tag; 129 IContentView view = MainFormManager. CreateDefaultView(item);129 IContentView view = MainFormManager.MainForm.ShowContent(item); 130 130 if (view != null) { 131 131 view.ReadOnly = ReadOnly; 132 132 view.Locked = Locked; 133 view.Show();134 133 } 135 134 } … … 147 146 private void showAlgorithmButton_Click(object sender, EventArgs e) { 148 147 if (!Locked) { 149 IContentView view = MainFormManager.CreateDefaultView(Content.Algorithm.Clone()); 150 if (view != null) { 151 view.Show(); 152 } 148 MainFormManager.MainForm.ShowContent((IContent)Content.Algorithm.Clone()); 153 149 } 154 150 } -
trunk/sources/HeuristicLab.Optimizer/3.3/FileManager.cs
r3500 r3557 42 42 if (newItemDialog == null) newItemDialog = new NewItemDialog(); 43 43 if (newItemDialog.ShowDialog() == DialogResult.OK) { 44 IView view = MainFormManager. CreateDefaultView(newItemDialog.Item);44 IView view = MainFormManager.MainForm.ShowContent(newItemDialog.Item); 45 45 if (view == null) MessageBox.Show("There is no view for the new item. It cannot be displayed.", "No View Available", MessageBoxButtons.OK, MessageBoxIcon.Error); 46 else view.Show();47 46 } 48 47 } … … 69 68 if (error != null) throw error; 70 69 Invoke(delegate() { 71 IView view = MainFormManager. CreateDefaultView(content);70 IView view = MainFormManager.MainForm.ShowContent(content); 72 71 if (view == null) MessageBox.Show("There is no view for the loaded item. It cannot be displayed.", "No View Available", MessageBoxButtons.OK, MessageBoxIcon.Error); 73 else view.Show();74 72 }); 75 73 } -
trunk/sources/HeuristicLab.Optimizer/3.3/HeuristicLabOptimizerPlugin.cs.frame
r3437 r3557 40 40 public override void Run() { 41 41 OptimizerMainForm mainForm = new OptimizerMainForm(typeof(IOptimizerUserInterfaceItemProvider)); 42 mainForm.Show ViewsInViewHost = true;42 mainForm.ShowContentInViewHost = true; 43 43 Application.Run(mainForm); 44 44 } -
trunk/sources/HeuristicLab.Optimizer/3.3/OptimizerMainForm.cs
r3483 r3557 53 53 waitingCursors = 0; 54 54 } 55 public OptimizerMainForm(Type userInterfaceItemType, bool show ViewsInViewHost)55 public OptimizerMainForm(Type userInterfaceItemType, bool showContentInViewHost) 56 56 : this(userInterfaceItemType) { 57 this.Show ViewsInViewHost = showViewsInViewHost;57 this.ShowContentInViewHost = showContentInViewHost; 58 58 } 59 59 -
trunk/sources/HeuristicLab.Optimizer/3.3/StartPage.cs
r3376 r3557 118 118 private void samplesListView_DoubleClick(object sender, EventArgs e) { 119 119 if (samplesListView.SelectedItems.Count == 1) 120 MainFormManager. CreateDefaultView(((IItem)samplesListView.SelectedItems[0].Tag).Clone()).Show();120 MainFormManager.MainForm.ShowContent((IContent)((IItem)samplesListView.SelectedItems[0].Tag).Clone()); 121 121 } 122 122 private void samplesListView_ItemDrag(object sender, ItemDragEventArgs e) {
Note: See TracChangeset
for help on using the changeset viewer.