Ticket #2289: 2289.patch
File 2289.patch, 54.7 KB (added by diana, 15 years ago) |
---|
-
modules/org.sophie2.base.model.book/src/main/java/org/sophie2/base/model/book/actions/ToggleBackgroundLock.java
### Eclipse Workspace Patch 1.0 #P sophie
1 package org.sophie2.base.model.book.actions; 2 3 import org.sophie2.base.commons.util.ImmColor; 4 import org.sophie2.base.commons.util.ImmGradient; 5 import org.sophie2.base.model.book.BackgroundType; 6 import org.sophie2.base.model.book.interfaces.StyledElement; 7 import org.sophie2.base.model.resources.r4.ResourceRefR4; 8 import org.sophie2.base.model.resources.r4.changes.AutoAction; 9 import org.sophie2.base.model.resources.r4.changes.ResourceChanger; 10 import org.sophie2.base.skins.Message; 11 12 13 /** 14 * An {@link AutoAction} class for locking/unlocking the background. 15 * 16 * @author diana 17 * 18 */ 19 public final class ToggleBackgroundLock extends AutoAction { 20 21 private final BackgroundType type ; 22 private final ImmColor color; 23 private final ResourceRefR4 image; 24 private final ImmGradient gradient; 25 private final Float opacity; 26 private final Boolean input; 27 28 29 /** 30 * The default constructor. Creates a new instance of 31 *{@link ToggleBackgroundTemplatingAction} class. 32 * 33 @param description 34 * The description of the new {@link AutoAction}. 35 * @param significant 36 * The significance of the new {@link AutoAction}. 37 * @param type 38 * The {@link BackgroundType} of the background. 39 * @param color 40 * The color of the background. 41 * @param image 42 * The ref for the image of the background. 43 * @param gradient 44 * The {@link ImmGradient} of the background. 45 * @param opacity 46 * The opacity of the background. 47 * @param input 48 * Whether the background should be locked or unlocked. 49 */ 50 public ToggleBackgroundLock(Message description, boolean significant, BackgroundType type, 51 ImmColor color, ResourceRefR4 image, ImmGradient gradient, Float opacity, Boolean input) { 52 super(description, significant); 53 this.type = type; 54 this.color = color; 55 this.image = image; 56 this.gradient = gradient; 57 this.opacity = opacity; 58 this.input = input; 59 } 60 61 @Override 62 public void performAuto() { 63 ResourceChanger ch = getChanger(); 64 65 ch.setRaw(StyledElement.KEY_BACKGROUND__TYPE, this.type); 66 ch.setRaw(StyledElement.KEY_BACKGROUND__COLOR, this.color); 67 ch.setRaw(StyledElement.KEY_BACKGROUND__IMAGE, this.image); 68 ch.setRaw(StyledElement.KEY_BACKGROUND__GRADIENT, this.gradient); 69 ch.setRaw(StyledElement.KEY_BACKGROUND__OPACITY, this.opacity); 70 71 ch.setRaw(StyledElement.KEY_BACKGROUND__TYPE.getLockKey(), this.input); 72 ch.setRaw(StyledElement.KEY_BACKGROUND__COLOR.getLockKey(), this.input); 73 ch.setRaw(StyledElement.KEY_BACKGROUND__IMAGE.getLockKey(), this.input); 74 ch.setRaw(StyledElement.KEY_BACKGROUND__GRADIENT.getLockKey(), this.input); 75 ch.setRaw(StyledElement.KEY_BACKGROUND__OPACITY.getLockKey(), this.input); 76 77 } 78 79 } -
modules/org.sophie2.launcher/.classpath
1 <?xml version="1.0" encoding="UTF-8"?> 2 <classpath> 3 <classpathentry kind="src" output="target/classes" path="src/main/java"/> 4 <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/> 5 <classpathentry kind="src" output="target/test-classes" path="src/test/java"/> 6 <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"/> 7 <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/> 8 <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/> 9 <classpathentry kind="src" path="/org.sophie2.base.model.resources.r4"/> 10 <classpathentry kind="output" path="target/classes"/> 11 </classpath> 1 <?xml version="1.0" encoding="UTF-8"?> 2 <classpath> 3 <classpathentry kind="src" output="target/classes" path="src/main/java"/> 4 <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/> 5 <classpathentry kind="src" output="target/test-classes" path="src/test/java"/> 6 <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"/> 7 <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/> 8 <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/> 9 <classpathentry kind="output" path="target/classes"/> 10 </classpath> -
modules/org.sophie2.base.model.book/src/main/java/org/sophie2/base/model/book/actions/LockUnlockBorderAction.java
1 package org.sophie2.base.model.book.actions; 2 3 import org.sophie2.base.commons.util.ImmColor; 4 import org.sophie2.base.commons.util.position.ImmInsets; 5 import org.sophie2.base.model.book.interfaces.StyledElement; 6 import org.sophie2.base.model.resources.r4.changes.AutoAction; 7 import org.sophie2.base.model.resources.r4.changes.ResourceChanger; 8 import org.sophie2.base.skins.Message; 9 10 11 /** 12 * An {@link AutoAction} class for locking/unlocking the border. 13 * 14 * @author diana 15 */ 16 public final class LockUnlockBorderAction extends AutoAction { 17 18 private final ImmColor borderColor; 19 private final ImmInsets borderInsets; 20 private final Boolean input; 21 22 /** 23 * The default constructor. Creates a new instance of {@link LockUnlockBorderAction} class. 24 * 25 @param description 26 * The description of the new {@link AutoAction}. 27 * @param significant 28 * The significance of the new {@link AutoAction}. 29 * @param borderColor 30 * The color of the border. 31 * @param borderInsets 32 * The insets of the border. 33 * @param input 34 * Whether the border should be locked or unlocked. 35 */ 36 public LockUnlockBorderAction(Message description, boolean significant, 37 ImmColor borderColor, ImmInsets borderInsets, Boolean input) { 38 super(description, significant); 39 this.input = input; 40 this.borderColor = borderColor; 41 this.borderInsets = borderInsets; 42 } 43 44 @Override 45 public void performAuto() { 46 ResourceChanger ch = getChanger(); 47 ch.setRaw(StyledElement.KEY_BORDER__COLOR, this.borderColor); 48 ch.setRaw(StyledElement.KEY_BORDER__COLOR.getLockKey(), this.input); 49 ch.setRaw(StyledElement.KEY_BORDER__INSETS, this.borderInsets); 50 ch.setRaw(StyledElement.KEY_BORDER__INSETS.getLockKey(), this.input); 51 } 52 53 } -
modules/org.sophie2.dev/src/test/java/org/sophie2/dev/author/UndoRedoTextTest.java
1 package org.sophie2.dev.author; 2 3 import java.util.Arrays; 4 import java.util.List; 5 6 import javax.swing.SwingUtilities; 7 8 import org.junit.Before; 9 import org.junit.Test; 10 import org.sophie2.base.model.text.BaseModelTextModule; 11 import org.sophie2.base.model.text.TextChange; 12 import org.sophie2.base.model.text.TextReplaceChange; 13 import org.sophie2.base.model.text.elements.CommonAttr; 14 import org.sophie2.base.model.text.model.ImmHotText; 15 import org.sophie2.base.model.text.model.ImmTextInterval; 16 import org.sophie2.base.model.text.mvc.TextView; 17 import org.sophie2.base.model.text.mvc.TextView.EventIds; 18 import org.sophie2.base.model.text.mvc.TextView.Place; 19 import org.sophie2.base.skins.Message; 20 import org.sophie2.core.modularity.SophieModule; 21 import org.sophie2.core.mvc.LogicR3; 22 import org.sophie2.core.mvc.events.EventR3; 23 import org.sophie2.core.testing.SystemTest; 24 import org.sophie2.dev.testing.SystemTestBase; 25 import org.sophie2.main.app.halos.MainAppHalosModule; 26 import org.sophie2.main.app.layout.MainAppLayoutModule; 27 import org.sophie2.main.app.menus.MainAppMenusModule; 28 import org.sophie2.main.app.menus.edit.RedoItem; 29 import org.sophie2.main.app.menus.edit.UndoItem; 30 import org.sophie2.main.app.model.MainAppModelModule; 31 import org.sophie2.main.func.resources.MainFuncResourcesModule; 32 import org.sophie2.main.func.text.InsertTextItem; 33 import org.sophie2.main.func.text.TextFuncModule; 34 import org.sophie2.main.func.text.view.HeadTextFrameView; 35 import org.sophie2.main.func.text.view.TextFrameView; 36 37 /** 38 * Tests the undo/redo in sophie text. 39 * 40 * @author diana 41 * 42 */ 43 @SystemTest 44 public class UndoRedoTextTest extends SystemTestBase{ 45 46 private static final String FULL_TEXT = "This page tries to provide"; 47 private static final String REPLACE_TEXT = "Replace text"; 48 49 private UndoItem undoItem; 50 private RedoItem redoItem; 51 private HeadTextFrameView selectedFrameView; 52 53 @SuppressWarnings("unchecked") 54 @Override 55 protected List<Class<? extends SophieModule>> fillDependencies() { 56 57 List<Class<? extends SophieModule>> res = super.fillDependencies(); 58 List<Class<? extends SophieModule>> toAppend = 59 Arrays.asList( 60 MainAppMenusModule.class, 61 BaseModelTextModule.class, 62 MainAppHalosModule.class, 63 TextFuncModule.class, 64 MainAppLayoutModule.class, 65 MainAppModelModule.class, 66 MainFuncResourcesModule.class 67 ); 68 69 merge(res, toAppend); 70 71 return res; 72 } 73 74 @Override 75 @Before 76 protected void setUp() throws Exception { 77 super.setUp(); 78 SwingUtilities.invokeAndWait(new Runnable() { 79 80 @SuppressWarnings("synthetic-access") 81 public void run() { 82 createNewBook(); 83 InsertTextItem textItem = findMenu(InsertTextItem.class); 84 85 textItem.clicked(); 86 87 TextFrameView frameViewToSelect = 88 curPageWorkArea().getAll(TextFrameView.class).get(0); 89 curPageWorkArea().getSel().select(frameViewToSelect, false); 90 UndoRedoTextTest.this.selectedFrameView = 91 curPageWorkArea().getSel().getSingleSelected(HeadTextFrameView.class); 92 TextView view = UndoRedoTextTest.this.selectedFrameView.textView().get(); 93 94 for (int i = 0; i < FULL_TEXT.length(); ++ i) { 95 int caret = UndoRedoTextTest.this.selectedFrameView. 96 textView().get().getTextModel().getCaret(); 97 TextChange change = new TextReplaceChange(new ImmTextInterval(caret, caret), 98 new ImmHotText("" + FULL_TEXT.charAt(i), null)); 99 LogicR3.fire(new EventR3(view, 100 null, null, null, EventIds.CHANGE_TEXT, change, 101 Message.create(REPLACE_TEXT), false, Place.RIGHT)); 102 } 103 UndoRedoTextTest.this.undoItem = getAppMainWindow().findNearestElement(null, UndoItem.class); 104 UndoRedoTextTest.this.redoItem = getAppMainWindow().findNearestElement(null, RedoItem.class); 105 106 107 } 108 }); 109 } 110 /** 111 * Tests the basic undo/redo of text. 112 */ 113 @Test 114 public void xtestUndoRedo() { 115 this.undoItem.clicked(); 116 assertEquals("This page tries to ", this.selectedFrameView.textFlow().get().getRawText().toString()); 117 118 this.undoItem.clicked(); 119 assertEquals("This page tries to", this.selectedFrameView.textFlow().get().getRawText().toString()); 120 121 this.undoItem.clicked(); 122 assertEquals("This page tries ", this.selectedFrameView.textFlow().get().getRawText().toString()); 123 124 this.redoItem.clicked(); 125 assertEquals("This page tries to", this.selectedFrameView.textFlow().get().getRawText().toString()); 126 127 this.redoItem.clicked(); 128 assertEquals("This page tries to ", this.selectedFrameView.textFlow().get().getRawText().toString()); 129 130 this.redoItem.clicked(); 131 assertEquals("This page tries to provide", this.selectedFrameView.textFlow().get().getRawText().toString()); 132 133 } 134 135 /** 136 * Tests the undo/redo when changing the model text when inserting chars. 137 */ 138 @Test 139 public void testInsertUndoRedo() { 140 TextView view = UndoRedoTextTest.this.selectedFrameView.textView().get(); 141 142 String st1 = "asd"; 143 144 for (int i = 0 ; i < st1.length(); ++ i) { 145 TextChange firstChange = new TextReplaceChange(new ImmTextInterval(3 + i, 3 + i), 146 new ImmHotText("" + st1.charAt(i), null)); 147 LogicR3.fire(new EventR3(view, 148 null, null, null, EventIds.CHANGE_TEXT, firstChange, 149 Message.create(REPLACE_TEXT), false, Place.RIGHT)); 150 } 151 this.undoItem.clicked(); 152 assertEquals("This page tries to provide", 153 this.selectedFrameView.textFlow().get().getRawText().toString()); 154 155 this.redoItem.clicked(); 156 assertEquals("Thiasds page tries to provide", 157 this.selectedFrameView.textFlow().get().getRawText().toString()); 158 159 String st2 = "qwerty"; 160 161 for (int i = 0 ; i < st2.length(); ++ i) { 162 TextChange secondChange = new TextReplaceChange(new ImmTextInterval(10 + i, 10 + i), 163 new ImmHotText("" + st2.charAt(i), null)); 164 LogicR3.fire(new EventR3(view, 165 null, null, null, EventIds.CHANGE_TEXT, secondChange, 166 Message.create(REPLACE_TEXT), false, Place.RIGHT)); 167 } 168 169 this.undoItem.clicked(); 170 assertEquals("Thiasds page tries to provide", 171 this.selectedFrameView.textFlow().get().getRawText().toString()); 172 173 this.redoItem.clicked(); 174 assertEquals("Thiasds paqwertyge tries to provide", 175 this.selectedFrameView.textFlow().get().getRawText().toString()); 176 177 this.undoItem.clicked(); 178 assertEquals("Thiasds page tries to provide", 179 this.selectedFrameView.textFlow().get().getRawText().toString()); 180 181 this.undoItem.clicked(); 182 this.undoItem.clicked(); 183 assertEquals("This page tries to provide", 184 this.selectedFrameView.textFlow().get().getRawText().toString()); 185 186 } 187 188 /** 189 * Tests the undo/redo when changing the model text when deleting chars. 190 */ 191 @Test 192 public void testDeleteUndoRedo() { 193 TextView view = UndoRedoTextTest.this.selectedFrameView.textView().get(); 194 195 196 this.selectedFrameView.textView().get().getTextModel().setCaret(3); 197 this.selectedFrameView.textView().get().getTextModel().setMark(3); 198 for (int i = 0 ; i < 3; ++ i) { 199 LogicR3.fire(new EventR3(view, 200 null, null, null, EventIds.DELETE, Place.LEFT)); 201 } 202 this.undoItem.clicked(); 203 assertEquals("This page tries to provide", 204 this.selectedFrameView.textFlow().get().getRawText().toString()); 205 206 this.redoItem.clicked(); 207 assertEquals("s page tries to provide", 208 this.selectedFrameView.textFlow().get().getRawText().toString()); 209 210 211 this.selectedFrameView.textView().get().getTextModel().setCaret(13); 212 for (int i = 0 ; i < 7; ++ i) { 213 LogicR3.fire(new EventR3(view, 214 null, null, null, EventIds.DELETE, Place.LEFT)); 215 } 216 217 this.undoItem.clicked(); 218 assertEquals("s page tries to provide", 219 this.selectedFrameView.textFlow().get().getRawText().toString()); 220 221 this.redoItem.clicked(); 222 assertEquals("to provide", 223 this.selectedFrameView.textFlow().get().getRawText().toString()); 224 225 this.undoItem.clicked(); 226 assertEquals("s page tries to provide", 227 this.selectedFrameView.textFlow().get().getRawText().toString()); 228 229 this.undoItem.clicked(); 230 this.undoItem.clicked(); 231 assertEquals("This page tries to provide", 232 this.selectedFrameView.textFlow().get().getRawText().toString()); 233 234 } 235 /** 236 * Tests the undo of delete and insert. 237 */ 238 @Test 239 public void testInsertDelete() { 240 TextView view = UndoRedoTextTest.this.selectedFrameView.textView().get(); 241 String rawText = this.selectedFrameView.textFlow().get().getRawText().toString(); 242 243 this.selectedFrameView.textView().get().getTextModel().setCaret(5); 244 this.selectedFrameView.textView().get().getTextModel().setMark(15); 245 246 String st2 = "ASD"; 247 248 for (int i = 0 ; i < st2.length(); ++ i) { 249 int caret = this.selectedFrameView.textView().get().getTextModel().getCaret(); 250 int mark = this.selectedFrameView.textView().get().getTextModel().getMark(); 251 TextChange change = new TextReplaceChange(new ImmTextInterval(caret, mark), 252 new ImmHotText("" + st2.charAt(i), null)); 253 LogicR3.fire(new EventR3(view, 254 null, null, null, EventIds.CHANGE_TEXT, change, 255 Message.create(REPLACE_TEXT), false, Place.RIGHT)); 256 } 257 258 this.undoItem.clicked(); 259 String expectedStr = rawText.substring(0, 5) + "A" + rawText.substring(15, rawText.length()); 260 assertEquals(expectedStr, this.selectedFrameView.textFlow().get().getRawText().toString()); 261 262 this.undoItem.clicked(); 263 assertEquals(rawText, this.selectedFrameView.textFlow().get().getRawText().toString()); 264 } 265 266 /** 267 * Tests the undo of applying styles to text in sophie. 268 */ 269 @Test 270 public void testApplyingStylesUndo() { 271 TextView view = UndoRedoTextTest.this.selectedFrameView.textView().get(); 272 String rawTextStr = view.getTextModel().getRawText().toString(); 273 ImmTextInterval styledInterval = new ImmTextInterval(5, 15); 274 this.selectedFrameView.textView().get().getTextModel().setCaret(styledInterval.getBegin()); 275 this.selectedFrameView.textView().get().getTextModel().setMark(styledInterval.getEnd()); 276 277 LogicR3.fire(new EventR3(view, 278 null, null, null, EventIds.APPLY_STYLE, CommonAttr.BOLD, true)); 279 280 assertTrue(view.getTextModel().getRawText().getStyleValue(CommonAttr.BOLD, styledInterval)); 281 282 this.undoItem.clicked(); 283 assertEquals(rawTextStr, view.getTextModel().getRawText().toString()); 284 assertFalse(view.getTextModel().getRawText().getStyleValue(CommonAttr.BOLD, styledInterval)); 285 this.redoItem.clicked(); 286 287 LogicR3.fire(new EventR3(view, 288 null, null, null, EventIds.APPLY_STYLE, CommonAttr.ITALIC, true)); 289 assertTrue(view.getTextModel().getRawText().getStyleValue(CommonAttr.BOLD, styledInterval)); 290 assertTrue(view.getTextModel().getRawText().getStyleValue(CommonAttr.ITALIC, styledInterval)); 291 292 this.undoItem.clicked(); 293 assertTrue(view.getTextModel().getRawText().getStyleValue(CommonAttr.BOLD, styledInterval)); 294 assertFalse(view.getTextModel().getRawText().getStyleValue(CommonAttr.ITALIC, styledInterval)); 295 296 this.undoItem.clicked(); 297 assertSame(false, view.getTextModel().getRawText().getStyleValue(CommonAttr.BOLD, styledInterval)); 298 assertFalse(view.getTextModel().getRawText().getStyleValue(CommonAttr.ITALIC, styledInterval)); 299 } 300 301 302 } -
modules/org.sophie2.base.model.text/src/main/java/org/sophie2/base/model/text/mvc/BaseTextModel.java
47 47 return getBean().makeListProp("areas", ImmArea.class); 48 48 } 49 49 50 private RwProp<TextChange> lastChange() { 50 /** 51 * The last text change made on the model. 52 * 53 * @return 54 * Property. 55 */ 56 public RwProp<TextChange> lastChange() { 51 57 return getBean().makeValueProp("lastChange", TextChange.class, null); 52 58 } 53 59 … … 68 74 private TextChange lastChange = null; 69 75 private ImmText lastRawText = null; 70 76 71 @SuppressWarnings("synthetic-access")72 77 @Override 73 78 protected ImmText compute() { 74 79 … … 125 130 } 126 131 127 132 128 @SuppressWarnings("synthetic-access")129 133 private ImmText applyChange(ImmText rawText, 130 134 ImmList<TextProcessor<TextProcessorOptions, TextProcessorEffect>> processors, 131 135 List<ImmText> processed, List<TextProcessorOptions> opts, List<ImmText> sources) { … … 282 286 283 287 public int getCaret() { 284 288 return caret().get() <= getRawText().getEnd() ? 285 caret().get() : 0;289 caret().get() : getRawText().getEnd(); 286 290 } 287 291 288 292 public int getMark() { 289 293 return mark().get() <= getRawText().getEnd() ? 290 mark().get() : 0;294 mark().get() : getRawText().getEnd(); 291 295 } 292 296 293 297 public boolean isEditable() { -
modules/org.sophie2.main.func.text/src/main/java/org/sophie2/main/func/text/view/TextFrameLogic.java
361 361 HotStyleDef style = HotStyleDef.getEmpty().derive(styleValues); 362 362 TextChange change = new TextStyleChange(interval, style); 363 363 LogicR3.fire(headView.textView().get(), null, null, cause, 364 TextView.EventIds.CHANGE_TEXT , change, Message.create(LINK_VISITED), false);364 TextView.EventIds.CHANGE_TEXT_FORCED, change, Message.create(LINK_VISITED), false); 365 365 } 366 366 } 367 367 -
modules/org.sophie2.base.model.book/src/main/java/org/sophie2/base/model/book/StyledElementH.java
7 7 import org.sophie2.base.commons.util.ImmPattern; 8 8 import org.sophie2.base.commons.util.ImmPattern.PatternOptions; 9 9 import org.sophie2.base.commons.util.position.ImmInsets; 10 import org.sophie2.base.model.book.actions.LockUnlockBorderAction; 11 import org.sophie2.base.model.book.actions.ToggleBackgroundLock; 12 import org.sophie2.base.model.book.actions.ToggleBackgroundTemplatingAction; 13 import org.sophie2.base.model.book.actions.ToggleBorderTemplatingAction; 10 14 import org.sophie2.base.model.book.interfaces.StyledElement; 11 15 import org.sophie2.base.model.book.resource.ImageResourceR4; 12 16 import org.sophie2.base.model.resources.r4.ResourceRefR4; 13 17 import org.sophie2.base.model.resources.r4.access.ResourceAccess; 14 18 import org.sophie2.base.model.resources.r4.changes.AutoAction; 15 import org.sophie2.base.model.resources.r4.changes.ResourceChanger;16 19 import org.sophie2.base.skins.Message; 17 20 18 21 /** … … 195 198 newColor = StyledElement.KEY_BORDER__COLOR.get(this.access); 196 199 } 197 200 198 new AutoAction(Message.create(BORDER_TEMPLATING), true) { 199 @Override 200 public void performAuto() { 201 ResourceChanger ch = getChanger(); 202 203 ch.setRaw(StyledElement.KEY_BORDER__INSETS, newInsets); 204 ch.setRaw(StyledElement.KEY_BORDER__COLOR, newColor); 205 } 206 }.register(this.access); 201 new ToggleBorderTemplatingAction(Message.create(BORDER_TEMPLATING), 202 true, newInsets, newColor).register(this.access); 207 203 } 208 204 209 205 /** … … 217 213 final ImmColor borderColor = getBorderColor(); 218 214 final ImmInsets borderInsets = getBorderInsets(); 219 215 220 new AutoAction(Message.create(BORDER_LOCK), true) { 221 @Override 222 public void performAuto() { 223 ResourceChanger ch = getChanger(); 224 ch.setRaw(StyledElement.KEY_BORDER__COLOR, borderColor); 225 ch.setRaw(StyledElement.KEY_BORDER__COLOR.getLockKey(), input); 226 ch.setRaw(StyledElement.KEY_BORDER__INSETS, borderInsets); 227 ch.setRaw(StyledElement.KEY_BORDER__INSETS.getLockKey(), input); 228 } 229 }.register(this.access); 216 new LockUnlockBorderAction(Message.create(BORDER_LOCK), true, 217 borderColor, borderInsets, input).register(this.access); 230 218 } 231 219 232 220 /** … … 256 244 opacity = getBackgroundOpacity(); 257 245 } 258 246 259 new AutoAction(Message.create(BG_TEMPLATING), true) { 260 @Override 261 public void performAuto() { 262 ResourceChanger ch = getChanger(); 263 264 ch.setRaw(StyledElement.KEY_BACKGROUND__TYPE, type); 265 ch.setRaw(StyledElement.KEY_BACKGROUND__COLOR, color); 266 ch.setRaw(StyledElement.KEY_BACKGROUND__IMAGE, image); 267 ch.setRaw(StyledElement.KEY_BACKGROUND__GRADIENT, gradient); 268 ch.setRaw(StyledElement.KEY_BACKGROUND__OPACITY, opacity); 269 } 270 }.register(this.access); 247 new ToggleBackgroundTemplatingAction(Message.create(BG_TEMPLATING), true, 248 type, color, image, gradient, opacity).register(this.access); 271 249 } 272 250 273 251 /** … … 283 261 final ImmGradient gradient = getBackgroundGradient(); 284 262 final Float opacity = getBackgroundOpacity(); 285 263 286 new AutoAction(Message.create(BG_LOCK), true) { 287 @Override 288 public void performAuto() { 289 ResourceChanger ch = getChanger(); 290 291 ch.setRaw(StyledElement.KEY_BACKGROUND__TYPE, type); 292 ch.setRaw(StyledElement.KEY_BACKGROUND__COLOR, color); 293 ch.setRaw(StyledElement.KEY_BACKGROUND__IMAGE, image); 294 ch.setRaw(StyledElement.KEY_BACKGROUND__GRADIENT, gradient); 295 ch.setRaw(StyledElement.KEY_BACKGROUND__OPACITY, opacity); 296 297 ch.setRaw(StyledElement.KEY_BACKGROUND__TYPE.getLockKey(), input); 298 ch.setRaw(StyledElement.KEY_BACKGROUND__COLOR.getLockKey(), input); 299 ch.setRaw(StyledElement.KEY_BACKGROUND__IMAGE.getLockKey(), input); 300 ch.setRaw(StyledElement.KEY_BACKGROUND__GRADIENT.getLockKey(), input); 301 ch.setRaw(StyledElement.KEY_BACKGROUND__OPACITY.getLockKey(), input); 302 } 303 }.register(this.access); 264 new ToggleBackgroundLock(Message.create(BG_LOCK), true, 265 type, color, image, gradient, opacity, input).register(this.access); 304 266 } 305 267 306 268 } -
modules/org.sophie2.base.connectivity/src/main/java/org/sophie2/base/connectivity/resources/ResourceDirectoryH.java
5 5 import java.util.List; 6 6 import java.util.Map; 7 7 8 import org.sophie2.base.connectivity.actions.CreateDirAction; 8 9 import org.sophie2.base.model.resources.r4.ResourceRefList; 9 10 import org.sophie2.base.model.resources.r4.ResourceRefR4; 10 11 import org.sophie2.base.model.resources.r4.access.AccessOptions; … … 198 199 final ResourceRefR4 childRef = ResourceRefR4.makeChild(name); 199 200 final ResourceRefList subDirectories = parent.getResources(); 200 201 ResourceAccess parentAccess = parent.getAccess(); 201 new AutoAction(Message.create(CREATE_DIR, name), true) { 202 @Override 203 public void performAuto() { 204 ResourceDirectoryH.addSubDirectory(getChanger(), childRef, 205 subDirectories); 206 } 207 208 }.register(parentAccess); 202 new CreateDirAction(Message.create(CREATE_DIR, name), 203 true, childRef, subDirectories).register(parentAccess); 209 204 return ResourceH.getHelper(parentAccess.open(childRef, null), 210 205 ResourceDirectoryH.class); 211 206 } -
modules/org.sophie2.base.model.book/src/main/java/org/sophie2/base/model/book/actions/ToggleBackgroundTemplatingAction.java
1 package org.sophie2.base.model.book.actions; 2 3 import org.sophie2.base.commons.util.ImmColor; 4 import org.sophie2.base.commons.util.ImmGradient; 5 import org.sophie2.base.model.book.BackgroundType; 6 import org.sophie2.base.model.book.interfaces.StyledElement; 7 import org.sophie2.base.model.resources.r4.ResourceRefR4; 8 import org.sophie2.base.model.resources.r4.changes.AutoAction; 9 import org.sophie2.base.model.resources.r4.changes.ResourceChanger; 10 import org.sophie2.base.skins.Message; 11 12 /** 13 * An {@link AutoAction} class for changing the template mode of the background. 14 * 15 * @author diana 16 * 17 */ 18 public final class ToggleBackgroundTemplatingAction extends AutoAction { 19 20 private final BackgroundType type; 21 private final ImmColor color; 22 private final ResourceRefR4 image; 23 private final ImmGradient gradient; 24 private final Float opacity; 25 26 /** 27 * The default constructor. Creates a new instance of 28 *{@link ToggleBackgroundTemplatingAction} class. 29 * 30 @param description 31 * The description of the new {@link AutoAction}. 32 * @param significant 33 * The significance of the new {@link AutoAction}. 34 * @param type 35 * The {@link BackgroundType} of the template mode. 36 * @param color 37 * The color of the template mode. 38 * @param image 39 * Ref for the image of the template mode. 40 * @param gradient 41 * The {@link ImmGradient} for the template mode. 42 * @param opacity 43 * The opacity of the template mode. 44 */ 45 public ToggleBackgroundTemplatingAction(Message description, 46 boolean significant, BackgroundType type, 47 ImmColor color, ResourceRefR4 image, ImmGradient gradient, Float opacity) { 48 super(description, significant); 49 this.color = color; 50 this.image = image; 51 this.gradient = gradient; 52 this.opacity = opacity; 53 this.type = type; 54 55 } 56 57 @Override 58 public void performAuto() { 59 ResourceChanger ch = getChanger(); 60 61 ch.setRaw(StyledElement.KEY_BACKGROUND__TYPE, this.type); 62 ch.setRaw(StyledElement.KEY_BACKGROUND__COLOR, this.color); 63 ch.setRaw(StyledElement.KEY_BACKGROUND__IMAGE, this.image); 64 ch.setRaw(StyledElement.KEY_BACKGROUND__GRADIENT, this.gradient); 65 ch.setRaw(StyledElement.KEY_BACKGROUND__OPACITY, this.opacity); 66 } 67 68 } -
modules/org.sophie2.base.model.book/src/main/java/org/sophie2/base/model/book/actions/ToggleBorderTemplatingAction.java
1 package org.sophie2.base.model.book.actions; 2 3 import org.sophie2.base.commons.util.ImmColor; 4 import org.sophie2.base.commons.util.position.ImmInsets; 5 import org.sophie2.base.model.book.interfaces.StyledElement; 6 import org.sophie2.base.model.resources.r4.changes.AutoAction; 7 import org.sophie2.base.model.resources.r4.changes.ResourceChanger; 8 import org.sophie2.base.skins.Message; 9 10 11 /** 12 * An {@link AutoAction} class 13 * for changing the template mode of the border. 14 * 15 * @author diana 16 * 17 */ 18 public final class ToggleBorderTemplatingAction extends AutoAction { 19 20 private final ImmInsets newInsets; 21 private final ImmColor newColor; 22 23 /** 24 * The default constructor. Creates a new instance of {@link ToggleBorderTemplatingAction} class. 25 * 26 @param description 27 * The description of the new {@link AutoAction}. 28 * @param significant 29 * The significance of the new {@link AutoAction}. 30 * @param newInsets 31 * The new insets of the template mode. 32 * @param newColor 33 * The new color of the template mode. 34 */ 35 public ToggleBorderTemplatingAction(Message description, boolean significant, 36 ImmInsets newInsets, ImmColor newColor) { 37 super(description, significant); 38 this.newColor = newColor; 39 this.newInsets = newInsets; 40 } 41 42 @Override 43 public void performAuto() { 44 ResourceChanger ch = getChanger(); 45 46 ch.setRaw(StyledElement.KEY_BORDER__INSETS, this.newInsets); 47 ch.setRaw(StyledElement.KEY_BORDER__COLOR, this.newColor); 48 49 } 50 51 } -
modules/org.sophie2.main.func.text/src/main/java/org/sophie2/main/func/text/links/TextLinksHud.java
247 247 248 248 TextChange change = new TextStyleChange(interval, style); 249 249 LogicR3.fire(frameView.textView().get(), null, null, event, 250 TextView.EventIds.CHANGE_TEXT , change, Message.create(CHANGE_LINK_COLOR), true);250 TextView.EventIds.CHANGE_TEXT_FORCED, change, Message.create(CHANGE_LINK_COLOR), true); 251 251 252 252 return true; 253 253 } … … 316 316 TextChange change = new TextStyleChange(interval, style); 317 317 318 318 LogicR3.fire(frameView.textView().get(), 319 null, null, event, TextView.EventIds.CHANGE_TEXT , change, description, true);319 null, null, event, TextView.EventIds.CHANGE_TEXT_FORCED, change, description, true); 320 320 return true; 321 321 } 322 322 }; -
modules/org.sophie2.dev/src/test/java/org/sophie2/dev/author/CopyPasteTextTest.java
102 102 103 103 TextChange change = new TextReplaceChange(new ImmTextInterval(0, 0), ht); 104 104 LogicR3.fire(new EventR3(this.frameView.textView().get(), null, null, null, 105 TextView.EventIds.CHANGE_TEXT , change, Message.create("change text"), true));105 TextView.EventIds.CHANGE_TEXT_FORCED, change, Message.create("change text"), true)); 106 106 107 107 assertEquals(ht.toString(), 108 108 this.frameView.textFlow().get().getRawText().toString()); -
modules/org.sophie2.base.model.text/src/main/java/org/sophie2/base/model/text/mvc/TextModelLogic.java
65 65 SophieLog.trace("FLOW_MOUSE_OPERATION.handle"); 66 66 InputEventR3 eventId = event.getEventId(InputEventR3.class); 67 67 TextView source = event.getSource(TextView.class); 68 68 69 boolean handle = false; 69 70 if (eventId == InputEventR3.MOUSE_PRESSED 70 71 || eventId == InputEventR3.MOUSE_DRAGGED … … 194 195 public boolean handle(EventR3 event) { 195 196 TextView source = event.getSource(TextView.class); 196 197 TextModel textModel = source.getTextModel(); 197 198 if (textModel == null || !textModel.isEditable()) { 199 //This TextView is no longer in the flow. 200 return true; 201 } 198 202 Place place = event.getEventParam(0, Place.class); 199 203 if (place == Place.ALL) { 200 204 setSelection(source,textModel.getRawText().getBegin(), … … 229 233 230 234 TextView source = event.getSource(TextView.class); 231 235 TextModel textModel = source.getTextModel(); 236 if (textModel == null || !textModel.isEditable()) { 237 //This TextView is no longer in the flow. 238 return true; 239 } 232 240 ModifierSet modifiers = 233 241 event.getEventParam(InputEventR3.MODIFIERS_PARAM_INDEX, ModifierSet.class); 234 242 char keyChar = event.getEventParam(InputEventR3.CHAR_PARAM_INDEX, … … 253 261 TextChange change = new TextReplaceChange(new 254 262 ImmTextInterval(textModel.getCaret(), textModel.getMark()), txtToReplaceWith); 255 263 256 boolean result = fireChangeText(event, change );264 boolean result = fireChangeText(event, change, false, Place.RIGHT); 257 265 return result; 258 266 } 259 267 }, … … 280 288 } 281 289 ImmTextInterval interval = getSelectionEnds(textModel); 282 290 assert interval != null; 291 Place place = event.getEventParam(0, Place.class); 283 292 284 293 if (interval.isEmpty()) { 285 Place place = event.getEventParam(0, Place.class);286 294 CaretInfo point = getPos(source, place); 287 295 int destination = point.getCaretIndex(); 288 296 int areaIndex = point.getAreaIndex(); … … 291 299 interval = new ImmTextInterval(caretPos, destination); 292 300 LogicR3.fire(new EventR3(source, null, null, null, EventIds.SELECT_VIEW, areaIndex)); 293 301 } 302 boolean isSignificant = false; 303 int intervalLength = interval.getEnd() - interval.getBegin(); 304 if (intervalLength == 1 305 && CommonChar.isWordSeparator(textModel.getRawText().unitAt(interval.getBegin()).getChar())) { 306 isSignificant = true; 307 } 294 308 TextChange change = new TextReplaceChange(interval, ImmTextUtils.createEmptyText()); 295 boolean result = fireChangeText(event, change );309 boolean result = fireChangeText(event, change, isSignificant, place); 296 310 return result; 297 311 } 298 312 }, … … 545 559 * The event that requires setting text 546 560 * @param change 547 561 * The text change to be applied. 562 * @param isSignificant 563 * If the auto action will be significant or not. 564 * @param place 565 * The {@link Place} where deleting/inserting. 566 * 548 567 * @return whether the Set Event is handled 549 568 */ 550 final boolean fireChangeText(EventR3 event, TextChange change ) {569 final boolean fireChangeText(EventR3 event, TextChange change, boolean isSignificant, Place place) { 551 570 TextView source = event.getSource(TextView.class); 552 571 TextModel textModel = source.getTextModel(); 553 572 … … 558 577 ImmTextInterval interval = getSelectionEnds(textModel); 559 578 assert interval != null; 560 579 561 boolean handled = LogicR3.fire(createChange Text(562 change, Message.create(INSERT_A_CHARACTER), event, false));580 boolean handled = LogicR3.fire(createChangeSignificanceEvent( 581 change, Message.create(INSERT_A_CHARACTER), event, isSignificant, place)); 563 582 564 583 if (handled) { 565 584 … … 571 590 return handled; 572 591 } 573 592 593 private static EventR3 createChangeSignificanceEvent(TextChange change, Message description, EventR3 cause, 594 boolean forceSignificance, Place place) { 595 return createTextEvent(change, description, cause, forceSignificance, place, TextView.EventIds.CHANGE_TEXT); 596 } 597 private static EventR3 createTextEvent(TextChange change, Message description, EventR3 cause, 598 boolean forceSignificance, Place place, TextView.EventIds id) { 599 // Trim the params - the new event will not need them. 600 List<Object> fields = new ArrayList<Object>( 601 cause.getFields().subList(EventR3.SOURCE_INDEX, EventR3.PARAMS_INDEX)); 602 603 fields.set(EventR3.ID_INDEX, id); 604 fields.set(EventR3.CAUSE_INDEX, cause); 605 606 addEventParam(TextView.EventIds.CHANGE_PARAM_INDEX, change, fields); 607 addEventParam(TextView.EventIds.DESCRIPTION_PARAM_INDEX, description, fields); 608 addEventParam(TextView.EventIds.FORCE_SIGNIFICANCE_PARAM_INDEX, forceSignificance, fields); 609 610 if (place != null) { 611 addEventParam(TextView.EventIds.PLACE_PARAM_INDEX, place, fields); 612 } 613 return new EventR3(fields); 614 } 574 615 /** 575 616 * Creates an {@link EventR3} which sets a given text. 576 617 * @param change … … 586 627 */ 587 628 public static EventR3 createChangeText(TextChange change, Message description, EventR3 cause, 588 629 boolean forceSignificance) { 589 // Trim the params - the new event will not need them. 590 List<Object> fields = new ArrayList<Object>( 591 cause.getFields().subList(EventR3.SOURCE_INDEX, EventR3.PARAMS_INDEX)); 592 593 fields.set(EventR3.ID_INDEX, TextView.EventIds.CHANGE_TEXT); 594 fields.set(EventR3.CAUSE_INDEX, cause); 595 596 addEventParam(TextView.EventIds.CHANGE_PARAM_INDEX, change, fields); 597 addEventParam(TextView.EventIds.DESCRIPTION_PARAM_INDEX, description, fields); 598 addEventParam(TextView.EventIds.FORCE_SIGNIFICANCE_PARAM_INDEX, forceSignificance, fields); 599 600 return new EventR3(fields); 630 631 return createTextEvent(change, description, cause, forceSignificance, null, TextView.EventIds.CHANGE_TEXT_FORCED); 632 601 633 } 602 634 603 635 private static void addEventParam(int paramIndex, Object value, List<Object> fields) { -
modules/org.sophie2.base.model.text/src/main/java/org/sophie2/base/model/text/mvc/TextView.java
191 191 * @author milo, vlado 192 192 */ 193 193 public enum EventIds { 194 /** 195 * Fired only for the undo/redo (to make the final significance of the action). 196 */ 197 @EventParams({TextChange.class, Message.class, Boolean.class, Place.class}) 198 CHANGE_TEXT, 194 199 195 200 /** 196 201 * Modify the model text. 197 202 */ 198 203 @EventParams({TextChange.class, Message.class, Boolean.class}) 199 CHANGE_TEXT ,204 CHANGE_TEXT_FORCED, 200 205 201 206 /** 202 207 * Navigate to a given place. … … 264 269 public static final int CHANGE_PARAM_INDEX = 0; 265 270 266 271 /** 272 * The index of the {@link Place}. Needed in 273 * the undo/redo of text. 274 */ 275 public static final int PLACE_PARAM_INDEX = 3; 276 /** 267 277 * Index for the description of an operation. 268 278 */ 269 279 public static final int DESCRIPTION_PARAM_INDEX = 1; -
modules/org.sophie2.main.func.text/src/main/java/org/sophie2/main/func/text/utils/TextChainUtils.java
185 185 186 186 int lastPageAreas = getFramesOnPage(chainedFrameViews, null).size(); 187 187 188 // ImmText processedText = ImmTextUtils.concat(flow.getProcessedText(),189 // ImmTextUtils.createDefaultText());190 188 ImmText processedText = textModel.getProcessedText(); 191 189 int neededPages = textModel.getTextLayout().dryRun(processedText, lastPageAreas); 192 190 if (neededPages == 0) { … … 200 198 expandChain(chainedFrameViews, neededPages); 201 199 } else { 202 200 changesMade = reduceChain(chainedFrameViews); 201 changesMade = false; 203 202 } 204 203 chainMaster.massChanging().set(false); 205 204 -
modules/org.sophie2.base.model.text/src/main/java/org/sophie2/base/model/text/mvc/swing/SimpleTextLogic.java
22 22 23 23 public void defineFilter(EventFilterBuilder filter) { 24 24 filter.setSourceClass(SwingTextView.class); 25 filter.setEventId(TextView.EventIds.CHANGE_TEXT );25 filter.setEventId(TextView.EventIds.CHANGE_TEXT_FORCED); 26 26 } 27 27 28 28 public boolean handle(EventR3 event) { -
modules/org.sophie2.main.func.text/src/main/java/org/sophie2/main/func/text/links/TextLinkColorHud.java
383 383 HotStyleDef style = HotStyleDef.getEmpty().derive(styleValues); 384 384 TextChange change = new TextStyleChange(interval, style); 385 385 LogicR3.fire(frameView.textView().get(), null, null, event, 386 TextView.EventIds.CHANGE_TEXT , change, Message.create(CHANGE_NORMAL_LINK_COLOR), true);386 TextView.EventIds.CHANGE_TEXT_FORCED, change, Message.create(CHANGE_NORMAL_LINK_COLOR), true); 387 387 } 388 388 } 389 389 } -
modules/org.sophie2.dev/src/main/java/org/sophie2/dev/author/FakeAuthorMain.java
199 199 SophieLog.info("Registering visual points..."); 200 200 SophieLog.info(BaseVisualModule.get().getVisualPoint().extensions().get()); 201 201 202 sleep( 5000);202 sleep(10000); 203 203 204 204 while (AuthorModule.get().getMainWindow() == null) { 205 205 sleep(1000); -
modules/org.sophie2.base.connectivity/src/main/java/org/sophie2/base/connectivity/actions/CreateDirAction.java
1 package org.sophie2.base.connectivity.actions; 2 3 import org.sophie2.base.connectivity.resources.ResourceDirectoryH; 4 import org.sophie2.base.model.resources.r4.ResourceRefList; 5 import org.sophie2.base.model.resources.r4.ResourceRefR4; 6 import org.sophie2.base.model.resources.r4.changes.AutoAction; 7 import org.sophie2.base.skins.Message; 8 9 /** 10 * An {@link AutoAction} that adds a sub directory to a 11 * {@link ResourceRefList} with child resources. 12 * 13 * @author diana 14 * 15 */ 16 public final class CreateDirAction extends AutoAction { 17 18 private final ResourceRefR4 childRef; 19 private final ResourceRefList subDirectories; 20 21 /** 22 * Default constructor. Creates a new {@link CreateDirAction} instance. 23 * 24 * @param description 25 * The description of the new {@link AutoAction}. 26 * @param significant 27 * The significance of the new {@link AutoAction}. 28 * @param childRef 29 * Relative reference to the child directory. 30 * @param subDirectories 31 * Current {@link ResourceRefList} with resources of the parent 32 * directory. 33 */ 34 public CreateDirAction(Message description, boolean significant, 35 ResourceRefR4 childRef, ResourceRefList subDirectories) { 36 super(description, significant); 37 this.childRef = childRef; 38 this.subDirectories = subDirectories; 39 } 40 41 @Override 42 public void performAuto() { 43 ResourceDirectoryH.addSubDirectory(getChanger(), this.childRef, 44 this.subDirectories); 45 46 } 47 } -
modules/org.sophie2.main.func.text/src/main/java/org/sophie2/main/func/text/view/HotTextLogic.java
17 17 import org.sophie2.base.model.text.HotTextData; 18 18 import org.sophie2.base.model.text.TextChange; 19 19 import org.sophie2.base.model.text.TextReplaceChange; 20 import org.sophie2.base.model.text.TextStyleChange; 21 import org.sophie2.base.model.text.elements.CommonChar; 20 22 import org.sophie2.base.model.text.model.ImmHotText; 21 23 import org.sophie2.base.model.text.model.ImmText; 22 24 import org.sophie2.base.model.text.model.ImmTextInterval; … … 27 29 import org.sophie2.base.model.text.mvc.TextProcessorEffect; 28 30 import org.sophie2.base.model.text.mvc.TextProcessorOptions; 29 31 import org.sophie2.base.model.text.mvc.TextView; 32 import org.sophie2.base.model.text.mvc.TextView.Place; 30 33 import org.sophie2.base.skins.Message; 31 34 import org.sophie2.base.visual.BaseVisualElement; 32 35 import org.sophie2.base.visual.VisualElement; … … 99 102 }, 100 103 101 104 /** 102 * Updates the text of the model. 103 * Note that this will be done even if the text view is not editable. 105 * Handles the changing of the significance of the text replace action. 104 106 */ 105 107 ON_CHANGE_TEXT { 106 108 107 long lastSignificantTime = 0;108 109 109 public void defineFilter(EventFilterBuilder filter) { 110 110 filter.setSourceClass(SceneTextView.class); 111 111 filter.setEventId(TextView.EventIds.CHANGE_TEXT); 112 112 } 113 113 114 @SuppressWarnings("synthetic-access") 114 115 public boolean handle(EventR3 event) { 115 116 SceneTextView view = event.getSource(SceneTextView.class); 116 117 BaseBookView bookView = view.findParentElement(BaseBookView.class); … … 127 128 final Message description = event.getEventParam( 128 129 TextView.EventIds.DESCRIPTION_PARAM_INDEX, Message.class); 129 130 131 final Place place = event.getEventParam( 132 TextView.EventIds.PLACE_PARAM_INDEX, Place.class); 133 130 134 HotTextResourceH model = view.getModel(); 135 TextModel textModel = view.getTextModel(); 136 int newNumberInserted = - 100; 137 boolean significant = false; 131 138 139 if(!forceSignificance) { 140 if (change instanceof TextReplaceChange) { 141 ImmText substText = 142 ((TextReplaceChange)change).getSubstitutionText(); 143 if (substText.getEnd() == 1 && CommonChar.getWordSeparators(). 144 contains(substText.unitAt(0).getChar())) { 145 makeSignificantAction(description, model); 146 significant = true; 147 } else if (textModel instanceof ResourceTextModel) { 148 TextChange lastCh = ((ResourceTextModel) textModel).lastChange().get(); 149 if (lastCh instanceof TextReplaceChange 150 && change instanceof TextReplaceChange) { 151 TextReplaceChange lastReplChange = (TextReplaceChange) lastCh; 152 ImmTextInterval lastInterval = 153 lastReplChange.getSourceDamage(ImmTextUtils.createEmptyText()); 154 int lastIntervalLength = lastInterval.getEnd() - lastInterval.getBegin(); 155 int lastNumberInserted = lastReplChange.getSubstitutionText().getEnd() - 156 lastIntervalLength; 132 157 133 boolean significant = false; 158 TextReplaceChange newReplChange = (TextReplaceChange) change; 159 ImmTextInterval newInterval = 160 newReplChange.getSourceDamage(ImmTextUtils.createEmptyText()); 161 int newIntervalLength = newInterval.getEnd() - newInterval.getBegin(); 162 newNumberInserted = newReplChange.getSubstitutionText().getEnd() - newIntervalLength; 163 //handles: 164 //1)if inserting letters consequently one after another the all block of letters should be undo-ed. 165 //2)if deleting letters with backspace(left) and delete(right) the whole block should be removed on undo. 166 if ((lastInterval.getEnd() + 1 != newInterval.getBegin() && newNumberInserted > 0) 167 || newNumberInserted < 0 && ((lastInterval.getBegin() != newInterval.getEnd() && 168 place.equals(Place.LEFT)) 169 || (lastInterval.getBegin() != newInterval.getEnd() + 1 && 170 place.equals(Place.RIGHT)))) { 171 172 makeSignificantAction(description, model); 173 134 174 135 if(!forceSignificance) { 136 long currentTime = System.currentTimeMillis(); 137 if (currentTime - this.lastSignificantTime > 500) { 138 significant = true; 175 } else if (lastNumberInserted * newNumberInserted < 0) { 176 makeSignificantAction(description, model); 177 significant = true; 178 } 179 } 180 } 139 181 } 140 this.lastSignificantTime = currentTime;141 182 } else { 142 183 Change lastChange = model.getAccess().getHead().getLastChange(); 143 184 if ( lastChange != null && !lastChange.isSignificant() ) { 144 145 new AutoAction(description, true) {146 185 147 @Override 148 public void performAuto() { 149 //Nothing. Just a marker. 150 } 151 }.register(model.getAccess()); 186 makeSignificantAction(description, model); 152 187 } 153 significant = true;154 188 } 189 return LogicR3.fire( 190 TextModelLogic.createChangeText(change, description, event, significant)); 191 } 192 }, 155 193 194 /** 195 * Updates the text of the model. 196 * Note that this will be done even if the text view is not editable. 197 */ 198 ON_CHANGE_TEXT_FORCED { 199 200 201 public void defineFilter(EventFilterBuilder filter) { 202 filter.setSourceClass(SceneTextView.class); 203 filter.setEventId(TextView.EventIds.CHANGE_TEXT_FORCED); 204 } 205 206 @SuppressWarnings("synthetic-access") 207 public boolean handle(EventR3 event) { 208 SceneTextView view = event.getSource(SceneTextView.class); 209 BookView bookView = view.findParentElement(BookView.class); 210 if (bookView == null) { 211 return false; 212 } 213 214 final TextChange change = event.getEventParam( 215 TextView.EventIds.CHANGE_PARAM_INDEX, TextChange.class); 216 217 Boolean significance = event.getEventParam( 218 TextView.EventIds.FORCE_SIGNIFICANCE_PARAM_INDEX, Boolean.class); 219 220 final Message description = event.getEventParam( 221 TextView.EventIds.DESCRIPTION_PARAM_INDEX, Message.class); 222 223 HotTextResourceH model = view.getModel(); 156 224 TextModel textModel = view.getTextModel(); 225 226 157 227 final ImmText text = textModel.getRawText(); 158 228 Change lastChange = model.getAccess().getHead().getLastChange(); 229 if (change instanceof TextStyleChange && significance 230 && lastChange != null && !lastChange.isSignificant()) { 231 makeSignificantAction(description, model); 232 significance = false; 233 } 159 234 // FIXME I believe this is an ugly fix.. 160 235 // This logic should not know about specific subclasses.. 161 236 // Any suggestions? --kyli@2010-04-15 162 237 if (textModel instanceof ResourceTextModel) { 163 238 164 239 ((ResourceTextModel) textModel).changeModel( 165 change, model.getAccess(), text, significan t, Message.create(SET_TEXT));240 change, model.getAccess(), text, significance, description); 166 241 LogicR3.fire(new EventR3(view, null, null, null, TextModelLogic.EventIds.SELECT_VIEW, 167 242 textModel.getTextLayout().getCharPlace( 168 243 textModel.getCaret()).getAreaIndex())); … … 261 336 } 262 337 263 338 }, 264 339 265 340 /** 266 341 * Handles importing on text in drag'n'drop operation over TextFrame. 267 342 */ … … 287 362 if (transferable.getDndData(StringData.class) == null) { 288 363 return false; 289 364 } 290 365 291 366 PasteTextHandler handler = PasteTextHandler.get(); 292 367 handler.setTextView(textView); 293 368 preImport.setHandler(handler); 294 369 295 370 return true; 296 371 } 297 372 }, … … 419 494 * Used for skinning. 420 495 */ 421 496 public static final String SET_TEXT = "Set text"; 422 497 423 498 /** 424 499 * The color used to higlight search results. 425 500 */ … … 450 525 assert interval != null; 451 526 452 527 TextChange change = new TextReplaceChange(interval, textToInsert); 453 528 454 529 boolean handled = LogicR3.fire(textView, null, null, null, 455 TextView.EventIds.CHANGE_TEXT , change, Message.create(INSERT_TEXT), true);530 TextView.EventIds.CHANGE_TEXT_FORCED, change, Message.create(INSERT_TEXT), true); 456 531 457 532 return handled; 458 533 } … … 460 535 return false; 461 536 } 462 537 538 private static void makeSignificantAction(Message msg, HotTextResourceH model) { 539 new AutoAction(msg, true) { 540 541 @Override 542 public void performAuto() { 543 //marker for later undo/redo algorithm. 544 } 545 }.register(model.getAccess()); 546 } 463 547 /** 464 548 * Creates an {@link ImmText} instance from the contents of the given 465 549 * transferable if possible.