aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/MachineView.xaml
blob: 013dca6ceabedeb7fa1271b2d121adde1e44eb8a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
<UserControl x:Class="Tango.MachineStudio.Common.Controls.MachineView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             xmlns:sharedConverters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI"
             xmlns:local="clr-namespace:Tango.MachineStudio.Common.Controls"
             mc:Ignorable="d" 
             d:DesignHeight="720" d:DesignWidth="1280">

    <UserControl.Resources>
        <sharedConverters:ColorToIntegerConverter x:Key="ColorToIntegerConverter" />

        <Style TargetType="Expander" BasedOn="{StaticResource {x:Type Expander}}">
            <Setter Property="HeaderTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <TextBlock Text="{Binding}" FontSize="13"></TextBlock>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>

    <Grid>
        <Viewbox MaxWidth="1200" Grid.Row="1" >
            <Grid VerticalAlignment="Top">

                <Image IsHitTestVisible="False" Source="../Images/machine-full-fx.png" MaxWidth="800" RenderOptions.BitmapScalingMode="Fant">
                    <Image.Effect>
                        <DropShadowEffect ShadowDepth="0" BlurRadius="20" Opacity="1" RenderingBias="Performance" Color="DimGray"></DropShadowEffect>
                    </Image.Effect>
                </Image>

                <Canvas ClipToBounds="False" x:Name="canvas">

                    <Grid x:Name="hardwareGrid" Width="118" Height="27" Canvas.Left="342" Canvas.Top="80" Background="#6B303030" IsHitTestVisible="True">
                        <Border BorderBrush="#6C6C6C" BorderThickness="1" IsHitTestVisible="False">
                            <StackPanel Orientation="Horizontal">
                                <Image Source="../Images/hardware.png" Width="10" VerticalAlignment="Center" Margin="5" RenderOptions.BitmapScalingMode="Fant"></Image>
                                <TextBlock Padding="2 0 2 0" VerticalAlignment="Center" TextAlignment="Center" Foreground="{StaticResource BorderBrushGainsboro}" IsHitTestVisible="False" FontSize="6" TextWrapping="Wrap">
                                            <Run Text="{Binding Configuration.HardwareVersion.Name}"></Run>
                                            <Run Text="{Binding Configuration.HardwareVersion.Version}"></Run>
                                </TextBlock>
                            </StackPanel>
                        </Border>
                    </Grid>

                    <TextBlock Canvas.Left="532" FontStyle="Italic" Foreground="Gray" Canvas.Top="-22">Hardware</TextBlock>
                    <Grid Width="97" Height="90" Canvas.Left="431" Canvas.Top="-13">
                        <Rectangle Stroke="Gray" VerticalAlignment="Top" StrokeThickness="1" StrokeDashArray="5" RenderTransformOrigin="0.5,0.5"/>
                        <Rectangle Stroke="Gray" HorizontalAlignment="Left" StrokeThickness="1" StrokeDashArray="5" RenderTransformOrigin="0.5,0.5"/>
                    </Grid>

                    <UniformGrid Width="310" Canvas.Top="295" Canvas.Left="420" Rows="1" Columns="8" TextElement.FontSize="9">
                        <TextBlock HorizontalAlignment="Center">1</TextBlock>
                        <TextBlock HorizontalAlignment="Center">2</TextBlock>
                        <TextBlock HorizontalAlignment="Center">3</TextBlock>
                        <TextBlock HorizontalAlignment="Center">4</TextBlock>
                        <TextBlock HorizontalAlignment="Center">5</TextBlock>
                        <TextBlock HorizontalAlignment="Center">6</TextBlock>
                        <TextBlock HorizontalAlignment="Center">7</TextBlock>
                        <TextBlock HorizontalAlignment="Center">8</TextBlock>
                    </UniformGrid>

                    <Grid x:Name="gridIds" Width="310" Height="195" Canvas.Top="314" Canvas.Left="420">
                        <ListBox ItemsSource="{Binding Configuration.IdsPacks}" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
                            <ListBox.ItemContainerStyle>
                                <Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
                                    <Setter Property="Padding" Value="0"></Setter>
                                    <Setter Property="VerticalContentAlignment" Value="Stretch"></Setter>
                                    <Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
                                </Style>
                            </ListBox.ItemContainerStyle>
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <UniformGrid Columns="8"></UniformGrid>
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <Grid>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="1*"/>
                                            <RowDefinition Height="30"/>
                                        </Grid.RowDefinitions>
                                        <UniformGrid Columns="1" Rows="2">
                                            <Grid Margin="2">
                                                <Image IsHitTestVisible="False" Source="../Images/dispenser.png" RenderOptions.BitmapScalingMode="Fant">
                                                    <Image.Style>
                                                        <Style TargetType="Image">
                                                            <Style.Triggers>
                                                                <DataTrigger Binding="{Binding Dispenser}" Value="{x:Null}">
                                                                    <Setter Property="Opacity" Value="0.2"></Setter>
                                                                </DataTrigger>
                                                            </Style.Triggers>
                                                        </Style>
                                                    </Image.Style>
                                                </Image>
                                                <Rectangle IsHitTestVisible="False" Margin="14 25 13 34">
                                                    <Rectangle.Fill>
                                                        <LinearGradientBrush StartPoint="0,0" EndPoint="0,0.8" Opacity="0.8">
                                                            <GradientStop Offset="0" Color="Transparent" />
                                                            <GradientStop Offset="1" Color="{Binding LiquidType.Color,Converter={StaticResource ColorToIntegerConverter}}"/>
                                                        </LinearGradientBrush>
                                                    </Rectangle.Fill>
                                                </Rectangle>
                                            </Grid>

                                            <Grid Margin="2">
                                                <Image IsHitTestVisible="False" Stretch="Fill" Source="../Images/mid-tank.png" RenderOptions.BitmapScalingMode="Fant">
                                                    <Image.Style>
                                                        <Style TargetType="Image">
                                                            <Style.Triggers>
                                                                <DataTrigger Binding="{Binding MidTankType}" Value="{x:Null}">
                                                                    <Setter Property="Opacity" Value="0.2"></Setter>
                                                                </DataTrigger>
                                                            </Style.Triggers>
                                                        </Style>
                                                    </Image.Style>
                                                </Image>
                                                <Rectangle IsHitTestVisible="False" Margin="4 25 4 1">
                                                    <Rectangle.Fill>
                                                        <LinearGradientBrush StartPoint="0,0" EndPoint="0,0.8" Opacity="0.8">
                                                            <GradientStop Offset="0" Color="Transparent" />
                                                            <GradientStop Offset="1" Color="{Binding LiquidType.Color,Converter={StaticResource ColorToIntegerConverter}}"/>
                                                        </LinearGradientBrush>
                                                    </Rectangle.Fill>
                                                </Rectangle>
                                            </Grid>
                                        </UniformGrid>

                                        <Grid Grid.Row="1" Margin="3" IsHitTestVisible="False">
                                            <Grid.Style>
                                                <Style TargetType="Grid">
                                                    <Style.Triggers>
                                                        <DataTrigger Binding="{Binding CartridgeType}" Value="{x:Null}">
                                                            <Setter Property="Opacity" Value="0.2"></Setter>
                                                        </DataTrigger>
                                                    </Style.Triggers>
                                                </Style>
                                            </Grid.Style>
                                            <Border BorderBrush="#252525" BorderThickness="1" CornerRadius="3">
                                                <Border.Background>
                                                    <LinearGradientBrush>
                                                        <GradientStop Color="#FF252525"/>
                                                        <GradientStop Color="#FF838383" Offset="1"/>
                                                    </LinearGradientBrush>
                                                </Border.Background>
                                            </Border>
                                            <Border BorderBrush="#252525" BorderThickness="1" CornerRadius="3">
                                                <Border.Background>
                                                    <LinearGradientBrush Opacity="0.7">
                                                        <GradientStop Offset="0" Color="Transparent" />
                                                        <GradientStop Offset="1" Color="{Binding LiquidType.Color,Converter={StaticResource ColorToIntegerConverter}}"/>
                                                    </LinearGradientBrush>
                                                </Border.Background>
                                            </Border>
                                        </Grid>
                                    </Grid>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ListBox>

                        <Grid Margin="0 50 0 0">
                            <Grid.Style>
                                <Style TargetType="Grid">
                                    <Setter Property="Visibility" Value="Hidden"></Setter>
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding Configuration.IdsPacks.Count}" Value="0">
                                            <Setter Property="Visibility" Value="Visible"></Setter>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </Grid.Style>
                            <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="20" FontWeight="Bold" Foreground="{StaticResource BorderBrushGainsboro}">NO IDS PACKS</TextBlock>
                        </Grid>

                        <Rectangle VerticalAlignment="Bottom" Stroke="DimGray" StrokeThickness="1">
                            <Rectangle.Effect>
                                <DropShadowEffect ShadowDepth="1" Opacity="1" Color="Black" />
                            </Rectangle.Effect>
                        </Rectangle>
                    </Grid>

                    <Grid x:Name="gridEmbedded" Width="70" Height="100" Canvas.Left="80" Canvas.Top="331" IsHitTestVisible="True" SnapsToDevicePixels="True">
                        <Image Source="../Images/ti-tm4c129x.png" RenderOptions.BitmapScalingMode="Fant"></Image>
                    </Grid>

                    <Grid Width="61" IsHitTestVisible="True" SnapsToDevicePixels="True" ClipToBounds="True" Height="42" Canvas.Left="85" Canvas.Top="385">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="1*" />
                        </Grid.RowDefinitions>

                        <StackPanel Orientation="Horizontal">
                            <Image Source="../Images/embedded.png" Width="10" VerticalAlignment="Center" Margin="1" RenderOptions.BitmapScalingMode="Fant"></Image>
                            <TextBlock VerticalAlignment="Center" Padding="1" Foreground="{StaticResource BorderBrushGainsboro}"  IsHitTestVisible="False" FontSize="5" TextAlignment="Center" TextWrapping="Wrap" Height="15" Margin="0,6,0,0" Width="47"><Run Text="{Binding Configuration.EmbeddedFirmwareVersion.Name}"/><Run Text=" "/><Run Text="{Binding Configuration.EmbeddedFirmwareVersion.Version}"/></TextBlock>
                        </StackPanel>
                    </Grid>

                    <TextBlock Canvas.Top="163" Canvas.Left="288" FontStyle="Italic" Foreground="Gray">Touch Panel</TextBlock>
                    <Grid Width="53" Height="55" Canvas.Top="184" Canvas.Left="279">
                        <Rectangle Stroke="Gray" VerticalAlignment="Bottom" StrokeThickness="1" StrokeDashArray="5" RenderTransformOrigin="0.5,0.5"/>
                        <Rectangle Stroke="Gray" HorizontalAlignment="Right" StrokeThickness="1" StrokeDashArray="5" RenderTransformOrigin="0.5,0.5"/>
                    </Grid>

                    <TextBlock Canvas.Top="441" Canvas.Left="156" FontStyle="Italic" Foreground="Gray">Embedded Firmware</TextBlock>
                    <Grid Width="82" Height="26" Canvas.Top="410" Canvas.Left="158">
                        <Rectangle Stroke="Gray" VerticalAlignment="Top" StrokeThickness="1" StrokeDashArray="5" RenderTransformOrigin="0.5,0.5"/>
                        <Rectangle Stroke="Gray" HorizontalAlignment="Right" StrokeThickness="1" StrokeDashArray="6" RenderTransformOrigin="0.5,0.5"/>
                    </Grid>

                    <TextBlock Canvas.Top="310" Canvas.Left="340" FontStyle="Italic" Foreground="Gray">Dispensers</TextBlock>
                    <Grid Width="53" Height="20" Canvas.Top="331" Canvas.Left="377">
                        <Rectangle Stroke="Gray" VerticalAlignment="Bottom" StrokeThickness="1" StrokeDashArray="5" RenderTransformOrigin="0.5,0.5"/>
                        <Rectangle Stroke="Gray" HorizontalAlignment="Left" StrokeThickness="1" StrokeDashArray="5" RenderTransformOrigin="0.5,0.5"/>
                    </Grid>

                    <TextBlock Canvas.Top="395" Canvas.Left="331" FontStyle="Italic" Foreground="Gray">Mid Tanks</TextBlock>
                    <Grid Width="62" Height="29" Canvas.Top="418" Canvas.Left="357">
                        <Rectangle Stroke="Gray" VerticalAlignment="Bottom" StrokeThickness="1" StrokeDashArray="5" RenderTransformOrigin="0.5,0.5"/>
                        <Rectangle Stroke="Gray" HorizontalAlignment="Left" StrokeThickness="1" StrokeDashArray="5" RenderTransformOrigin="0.5,0.5"/>
                    </Grid>

                    <TextBlock Canvas.Top="469" Canvas.Left="304" FontStyle="Italic" Foreground="Gray">Cartridges</TextBlock>
                    <Grid Width="87" Height="10" Canvas.Top="487" Canvas.Left="332">
                        <Rectangle Stroke="Gray" VerticalAlignment="Bottom" StrokeThickness="1" StrokeDashArray="5" RenderTransformOrigin="0.5,0.5"/>
                        <Rectangle Stroke="Gray" HorizontalAlignment="Left" StrokeThickness="1" StrokeDashArray="5" RenderTransformOrigin="0.5,0.5"/>
                    </Grid>

                    <Grid x:Name="gridTablet" Width="67" IsHitTestVisible="True" SnapsToDevicePixels="True" ClipToBounds="True" Height="90" Canvas.Left="188" Canvas.Top="198">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="1*" />
                            <RowDefinition Height="1*" />
                            <RowDefinition Height="1*" />
                        </Grid.RowDefinitions>

                        <StackPanel>
                            <Image Source="../Images/tablet.png" Width="10" Margin="2" RenderOptions.BitmapScalingMode="Fant"></Image>
                            <TextBlock Padding="2 0 2 0" Foreground="{StaticResource BorderBrushGainsboro}"  IsHitTestVisible="False" FontSize="6" TextAlignment="Center" TextWrapping="Wrap">
                                        <Run Text="{Binding Configuration.ApplicationDisplayPanelVersion.Name}"></Run>
                                        <Run Text="{Binding Configuration.ApplicationDisplayPanelVersion.Version}"></Run>
                            </TextBlock>
                        </StackPanel>


                        <StackPanel Grid.Row="3" >
                            <Image Source="../Images/application-firmware.png" Width="10" Margin="2" RenderOptions.BitmapScalingMode="Fant"></Image>
                            <TextBlock Padding="2 0 2 0" IsHitTestVisible="False" Foreground="{StaticResource BorderBrushGainsboro}" FontSize="6" TextAlignment="Center" TextWrapping="Wrap">
                                        <Run Text="{Binding Configuration.ApplicationFirmwareVersion.Name}"></Run>
                                        <Run Text="{Binding Configuration.ApplicationFirmwareVersion.Version}"></Run>
                            </TextBlock>
                        </StackPanel>

                        <StackPanel Grid.Row="1" >
                            <Image Source="../Images/android.png" Width="10" Margin="2" RenderOptions.BitmapScalingMode="Fant"></Image>
                            <TextBlock Padding="2 0 2 0" IsHitTestVisible="False" Foreground="{StaticResource BorderBrushGainsboro}" FontSize="6" TextAlignment="Center" TextWrapping="Wrap">
                                        <Run Text="{Binding Configuration.ApplicationOsVersion.Name}"></Run>
                                        <Run Text="{Binding Configuration.ApplicationOsVersion.Version}"></Run>
                            </TextBlock>
                        </StackPanel>
                    </Grid>
                </Canvas>
            </Grid>
        </Viewbox>
    </Grid>
</UserControl>
s="o">> sizeLimit) undostack.PopFront(); while (redostack.Count > sizeLimit) redostack.PopFront(); } /// <summary> /// If an undo group is open, gets the group descriptor of the current top-level /// undo group. /// If no undo group is open, gets the group descriptor from the previous undo group. /// </summary> /// <remarks>The group descriptor can be used to join adjacent undo groups: /// use a group descriptor to mark your changes, and on the second action, /// compare LastGroupDescriptor and use <see cref="StartContinuedUndoGroup"/> if you /// want to join the undo groups.</remarks> public object LastGroupDescriptor { get { return lastGroupDescriptor; } } /// <summary> /// Starts grouping changes. /// Maintains a counter so that nested calls are possible. /// </summary> public void StartUndoGroup() { StartUndoGroup(null); } /// <summary> /// Starts grouping changes. /// Maintains a counter so that nested calls are possible. /// </summary> /// <param name="groupDescriptor">An object that is stored with the undo group. /// If this is not a top-level undo group, the parameter is ignored.</param> public void StartUndoGroup(object groupDescriptor) { if (undoGroupDepth == 0) { actionCountInUndoGroup = 0; optionalActionCount = 0; lastGroupDescriptor = groupDescriptor; } undoGroupDepth++; //Util.LoggingService.Debug("Open undo group (new depth=" + undoGroupDepth + ")"); } /// <summary> /// Starts grouping changes, continuing with the previously closed undo group if possible. /// Maintains a counter so that nested calls are possible. /// If the call to StartContinuedUndoGroup is a nested call, it behaves exactly /// as <see cref="StartUndoGroup()"/>, only top-level calls can continue existing undo groups. /// </summary> /// <param name="groupDescriptor">An object that is stored with the undo group. /// If this is not a top-level undo group, the parameter is ignored.</param> public void StartContinuedUndoGroup(object groupDescriptor) { if (undoGroupDepth == 0) { actionCountInUndoGroup = (allowContinue && undostack.Count > 0) ? 1 : 0; optionalActionCount = 0; lastGroupDescriptor = groupDescriptor; } undoGroupDepth++; //Util.LoggingService.Debug("Continue undo group (new depth=" + undoGroupDepth + ")"); } /// <summary> /// Stops grouping changes. /// </summary> public void EndUndoGroup() { if (undoGroupDepth == 0) return; undoGroupDepth--; //Util.LoggingService.Debug("Close undo group (new depth=" + undoGroupDepth + ")"); if (undoGroupDepth == 0) { Debug.Assert(state == StateListen || actionCountInUndoGroup == 0); if (actionCountInUndoGroup == optionalActionCount) { // only optional actions: don't store them for (int i = 0; i < optionalActionCount; i++) { undostack.PopBack(); } } else if (actionCountInUndoGroup > 1) { // combine all actions within the group into a single grouped action undostack.PushBack(new UndoOperationGroup(undostack, actionCountInUndoGroup)); FileModified(-actionCountInUndoGroup + 1 + optionalActionCount); } //if (state == StateListen) { EnforceSizeLimit(); allowContinue = true; RecalcIsOriginalFile(); // can raise event //} } } /// <summary> /// Throws an InvalidOperationException if an undo group is current open. /// </summary> void ThrowIfUndoGroupOpen() { try { if (undoGroupDepth != 0) { undoGroupDepth = 0; throw new InvalidOperationException("No undo group should be open at this point"); } if (state != StateListen) { throw new InvalidOperationException("This method cannot be called while an undo operation is being performed"); } } catch { } } List<TextDocument> affectedDocuments; internal void RegisterAffectedDocument(TextDocument document) { if (affectedDocuments == null) affectedDocuments = new List<TextDocument>(); if (!affectedDocuments.Contains(document)) { affectedDocuments.Add(document); document.BeginUpdate(); } } void CallEndUpdateOnAffectedDocuments() { if (affectedDocuments != null) { foreach (TextDocument doc in affectedDocuments) { doc.EndUpdate(); } affectedDocuments = null; } } /// <summary> /// Call this method to undo the last operation on the stack /// </summary> public void Undo() { ThrowIfUndoGroupOpen(); if (undostack.Count > 0) { // disallow continuing undo groups after undo operation lastGroupDescriptor = null; allowContinue = false; // fetch operation to undo and move it to redo stack IUndoableOperation uedit = undostack.PopBack(); redostack.PushBack(uedit); state = StatePlayback; try { RunUndo(uedit); } finally { state = StateListen; FileModified(-1); CallEndUpdateOnAffectedDocuments(); } RecalcIsOriginalFile(); if (undostack.Count == 0) NotifyPropertyChanged("CanUndo"); if (redostack.Count == 1) NotifyPropertyChanged("CanRedo"); } } internal void RunUndo(IUndoableOperation op) { IUndoableOperationWithContext opWithCtx = op as IUndoableOperationWithContext; if (opWithCtx != null) opWithCtx.Undo(this); else op.Undo(); } /// <summary> /// Call this method to redo the last undone operation /// </summary> public void Redo() { ThrowIfUndoGroupOpen(); if (redostack.Count > 0) { lastGroupDescriptor = null; allowContinue = false; IUndoableOperation uedit = redostack.PopBack(); undostack.PushBack(uedit); state = StatePlayback; try { RunRedo(uedit); } finally { state = StateListen; FileModified(1); CallEndUpdateOnAffectedDocuments(); } RecalcIsOriginalFile(); if (redostack.Count == 0) NotifyPropertyChanged("CanRedo"); if (undostack.Count == 1) NotifyPropertyChanged("CanUndo"); } } internal void RunRedo(IUndoableOperation op) { IUndoableOperationWithContext opWithCtx = op as IUndoableOperationWithContext; if (opWithCtx != null) opWithCtx.Redo(this); else op.Redo(); } /// <summary> /// Call this method to push an UndoableOperation on the undostack. /// The redostack will be cleared if you use this method. /// </summary> public void Push(IUndoableOperation operation) { Push(operation, false); } /// <summary> /// Call this method to push an UndoableOperation on the undostack. /// However, the operation will be only stored if the undo group contains a /// non-optional operation. /// Use this method to store the caret position/selection on the undo stack to /// prevent having only actions that affect only the caret and not the document. /// </summary> public void PushOptional(IUndoableOperation operation) { if (undoGroupDepth == 0) throw new InvalidOperationException("Cannot use PushOptional outside of undo group"); Push(operation, true); } void Push(IUndoableOperation operation, bool isOptional) { if (operation == null) { throw new ArgumentNullException("operation"); } if (state == StateListen && sizeLimit > 0) { bool wasEmpty = undostack.Count == 0; bool needsUndoGroup = undoGroupDepth == 0; if (needsUndoGroup) StartUndoGroup(); undostack.PushBack(operation); actionCountInUndoGroup++; if (isOptional) optionalActionCount++; else FileModified(1); if (needsUndoGroup) EndUndoGroup(); if (wasEmpty) NotifyPropertyChanged("CanUndo"); ClearRedoStack(); } } /// <summary> /// Call this method, if you want to clear the redo stack /// </summary> public void ClearRedoStack() { if (redostack.Count != 0) { redostack.Clear(); NotifyPropertyChanged("CanRedo"); // if the "original file" marker is on the redo stack: remove it if (elementsOnUndoUntilOriginalFile < 0) elementsOnUndoUntilOriginalFile = int.MinValue; } } /// <summary> /// Clears both the undo and redo stack. /// </summary> public void ClearAll() { ThrowIfUndoGroupOpen(); actionCountInUndoGroup = 0; optionalActionCount = 0; if (undostack.Count != 0) { lastGroupDescriptor = null; allowContinue = false; undostack.Clear(); NotifyPropertyChanged("CanUndo"); } ClearRedoStack(); } internal void Push(TextDocument document, DocumentChangeEventArgs e) { if (state == StatePlayback) throw new InvalidOperationException("Document changes during undo/redo operations are not allowed."); if (state == StatePlaybackModifyDocument) state = StatePlayback; // allow only 1 change per expected modification else Push(new DocumentChangeOperation(document, e)); } /// <summary> /// Is raised when a property (CanUndo, CanRedo) changed. /// </summary> public event PropertyChangedEventHandler PropertyChanged; void NotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } }