Ticket #2438: 2438.patch

File 2438.patch, 12.9 KB (added by diana, 11 years ago)
  • modules/org.sophie2.base.model.text/src/main/java/org/sophie2/base/model/text/mvc/TextModelLogic.java

    ### Eclipse Workspace Patch 1.0
    #P sophie
     
    256256                        } 
    257257 
    258258                        inputString += String.valueOf(keyChar); 
    259                         ImmText txtToReplaceWith = new ImmHotText(inputString, textModel.inputStyle().get()); 
     259                        HotStyleDef styles = textModel.inputStyle().get(); 
     260                        ImmText txtToReplaceWith = new ImmHotText(inputString, styles); 
    260261                        SelectionInfo caretInfo = textModel.getSelectionInfo(); 
    261262                        TextChange change = new TextReplaceChange(new 
    262263                                        ImmTextInterval(caretInfo.getCaret(), caretInfo.getMarkIndex()), txtToReplaceWith); 
    263264 
    264265                        boolean result = fireChangeText(event, change, false, Place.RIGHT); 
    265266                         
     267                        if (result) { 
     268                                textModel.inputStyle().set(HotStyleDef.getEmpty()); 
     269                        } 
    266270                        return result; 
    267271                } 
    268272        }, 
     
    404408                        int caretPos = caretInfo.getCaret(); 
    405409                        int markPos = caretInfo.getMarkIndex(); 
    406410 
     411                        Map<HotAttr<?>, Object> styleValues = new HashMap<HotAttr<?>, Object>(); 
     412                        styleValues.put(attr, attrValue); 
     413                        HotStyleDef newStyles = textModel.inputStyle().get().derive(styleValues); 
    407414                        if (caretPos - markPos == 0) { 
    408                                 Map<HotAttr<?>, Object> styleValues = new HashMap<HotAttr<?>, Object>(); 
    409                                 styleValues.put(attr, attrValue); 
    410                                 textModel.inputStyle().set(textModel.inputStyle().get().derive(styleValues)); 
     415                                textModel.inputStyle().set(newStyles); 
    411416                                return true; 
    412417                        } 
    413418 
    414419                        ImmTextInterval selection = new ImmTextInterval(markPos,  
    415420                                        caretPos);                       
    416                         Map<HotAttr<?>, Object> styleValues = new HashMap<HotAttr<?>, Object>(); 
    417                         styleValues.put(attr, attrValue); 
    418                         HotStyleDef style = HotStyleDef.getEmpty().derive(styleValues); 
    419                         TextChange change =  new TextStyleChange(selection, style); 
     421//                      HotStyleDef style = HotStyleDef.getEmpty().derive(styleValues); 
     422                        TextChange change =  new TextStyleChange(selection, newStyles); 
    420423 
    421424                        boolean handled = LogicR3.fire( 
    422425                                        createChangeText(change, Message.create(APPLY_STYLE), event, true)); 
     
    507510                        HotAttr<?> attr = event.getEventParam( 
    508511                                        TextView.EventIds.ATTR_PARAM_INDEX, HotAttr.class); 
    509512                        assert attr.getValueClass().equals(Boolean.class); 
    510                         if (selection.getBegin() - selection.getEnd() == 0) { 
     513                        boolean emptySelection = selection.isEmpty(); 
     514                        if (emptySelection) { 
    511515 
    512516                                if (selection.getBegin() - text.getBegin() > 0) { 
    513517 
     
    520524                        || text.getStyleValue(attr, selection) == null ?  
    521525                                        (Boolean)attr.getDefaultValue() : (Boolean)text.getStyleValue(attr, selection); 
    522526                        Object attrValue = !oldValue && !(Boolean) textModel.inputStyle().get().getValue(attr); 
     527                         
    523528                        // Trim the params. 
    524529                        List<Object> fields = new ArrayList<Object>( 
    525530                                        event.getFields().subList(EventR3.SOURCE_INDEX, EventR3.PARAMS_INDEX)); 
  • modules/org.sophie2.dev/src/test/java/org/sophie2/dev/author/TestCtrlBText.java

     
     1package org.sophie2.dev.author; 
     2 
     3import java.util.Arrays; 
     4import java.util.EnumSet; 
     5import java.util.List; 
     6 
     7import javax.swing.SwingUtilities; 
     8 
     9import org.junit.Before; 
     10import org.junit.Test; 
     11import org.sophie2.base.model.resources.r4.ResourceRefR4; 
     12import org.sophie2.base.model.resources.r4.changes.AutoAction; 
     13import org.sophie2.base.model.text.BaseModelTextModule; 
     14import org.sophie2.base.model.text.elements.CommonAttr; 
     15import org.sophie2.base.model.text.model.ImmHotText; 
     16import org.sophie2.base.model.text.model.ImmText; 
     17import org.sophie2.base.model.text.model.ImmTextInterval; 
     18import org.sophie2.base.model.text.mvc.TextView.EventIds; 
     19import org.sophie2.base.skins.Message; 
     20import org.sophie2.base.visual.interaction.InputEventR3; 
     21import org.sophie2.base.visual.interaction.InputModifier; 
     22import org.sophie2.base.visual.interaction.ModifierSet; 
     23import org.sophie2.core.modularity.SophieModule; 
     24import org.sophie2.core.mvc.LogicR3; 
     25import org.sophie2.core.mvc.events.EventR3; 
     26import org.sophie2.core.testing.SystemTest; 
     27import org.sophie2.dev.testing.SystemTestBase; 
     28import org.sophie2.main.app.halos.MainAppHalosModule; 
     29import org.sophie2.main.app.layout.MainAppLayoutModule; 
     30import org.sophie2.main.app.menus.MainAppMenusModule; 
     31import org.sophie2.main.app.model.MainAppModelModule; 
     32import org.sophie2.main.func.resources.MainFuncResourcesModule; 
     33import org.sophie2.main.func.text.InsertTextItem; 
     34import org.sophie2.main.func.text.TextFuncModule; 
     35import org.sophie2.main.func.text.model.HeadTextFrameH; 
     36import org.sophie2.main.func.text.view.HeadTextFrameView; 
     37import org.sophie2.main.func.text.view.SceneTextView; 
     38import org.sophie2.main.func.text.view.TextFrameView; 
     39 
     40/** 
     41 * @author Diana 
     42 * 
     43 */ 
     44@SystemTest 
     45public class TestCtrlBText extends SystemTestBase { 
     46        /** 
     47         * Constant created for insertion of a full text frame. 
     48         * Constant created to be a parameter of a message of an {@link AutoAction}.  
     49         * Used for skinning. Used in the test. 
     50         */ 
     51        public static final String INSERT_FULL_TEXT_FRAME = "Insert a full text frame"; 
     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                        } 
     84                }); 
     85 
     86                try { 
     87                        Thread.sleep(10000); 
     88                } catch (InterruptedException e) { 
     89                        //nothing 
     90                } 
     91                final ImmText text = new ImmHotText( 
     92                                "asd", null); 
     93 
     94                SwingUtilities.invokeAndWait(new Runnable() { 
     95 
     96                        @SuppressWarnings("synthetic-access") 
     97                        public void run() { 
     98                                HeadTextFrameH.createTextFrameAction(curBook(), 
     99                                                curPageWorkArea().getRootPageView().model().get(), 
     100                                                text, ResourceRefR4.NONE_REF.toUri(), null, 
     101                                                Message.create(INSERT_FULL_TEXT_FRAME), true, false); 
     102 
     103                                TextFrameView frameViewToSelect = 
     104                                        curPageWorkArea().getAll(TextFrameView.class).get(0); 
     105                                curPageWorkArea().getSel().select(frameViewToSelect, false); 
     106 
     107                                final HeadTextFrameView selectedFrameView = 
     108                                        curPageWorkArea().getSel().getSingleSelected(HeadTextFrameView.class); 
     109                                assertNotNull(selectedFrameView); 
     110 
     111                        } 
     112                }); 
     113 
     114 
     115        } 
     116 
     117 
     118 
     119        /** 
     120         * Tests the insert/delete in chain. 
     121         *  
     122         * @throws Exception  
     123         *                      Upon error 
     124         */ 
     125        @Test 
     126        public void testCtrlB() throws Exception { 
     127 
     128                HeadTextFrameView selectedFrameView = 
     129                        curPageWorkArea().getSel().getSingleSelected(HeadTextFrameView.class); 
     130 
     131                selectedFrameView.textFlow().get().setSelectionInfo(3, 3); 
     132 
     133                SceneTextView selView = selectedFrameView.textView().get(); 
     134                LogicR3.fire(new EventR3(selView, null, null, null, EventIds.SWITCH_STYLE, 
     135                                CommonAttr.BOLD)); 
     136                assertTrue(selectedFrameView.textFlow().get().inputStyle().get().getValue(CommonAttr.BOLD)); 
     137                LogicR3.fire(new EventR3(selView, 
     138                                null, null, null, InputEventR3.KEY_TYPED,  
     139                                new ModifierSet(EnumSet.noneOf(InputModifier.class)), 'A')); 
     140 
     141                assertTrue(selectedFrameView.textFlow().get().getRawText().getStyleValue(CommonAttr.BOLD, 
     142                                new ImmTextInterval(3,4))); 
     143                LogicR3.fire(new EventR3(selView, null, null, null, EventIds.SWITCH_STYLE, 
     144                                CommonAttr.BOLD)); 
     145 
     146                assertFalse(selectedFrameView.textFlow().get().inputStyle().get().getValue(CommonAttr.BOLD)); 
     147                LogicR3.fire(new EventR3(selView, 
     148                                null, null, null, InputEventR3.KEY_TYPED,  
     149                                new ModifierSet(EnumSet.noneOf(InputModifier.class)), 'B')); 
     150                assertFalse(selectedFrameView.textFlow().get().getRawText().getStyleValue(CommonAttr.BOLD, 
     151                                new ImmTextInterval(4,5))); 
     152 
     153        } 
     154 
     155        /** 
     156         * Tests when pressing ctrl+b on empty text frame. 
     157         */ 
     158        @Test 
     159        public void testCtrlBException() { 
     160                InsertTextItem textItem = findMenu(InsertTextItem.class); 
     161                textItem.clicked(); 
     162 
     163                TextFrameView frameViewToSelect = 
     164                        curPageWorkArea().getAll(TextFrameView.class).get(1); 
     165                curPageWorkArea().getSel().select(frameViewToSelect, false); 
     166                HeadTextFrameView selectedFrameView = 
     167                        curPageWorkArea().getSel().getSingleSelected(HeadTextFrameView.class); 
     168                SceneTextView selView = selectedFrameView.textView().get(); 
     169                try { 
     170                        ModifierSet mSet = new ModifierSet(InputModifier.M_CONTROL); 
     171                        LogicR3.fire(new EventR3(selView, 
     172                                        null, null, null, InputEventR3.KEY_TYPED,  
     173                                        mSet, 'b')); 
     174                } catch (Exception e) { 
     175                        fail(); 
     176                } 
     177        } 
     178 
     179} 
  • modules/org.sophie2.base.model.text/src/main/java/org/sophie2/base/model/text/model/ImmHotText.java

     
    107107                        newStyles = unitAt(styleIndex).getStyle(); 
    108108                } 
    109109                if (! interval.isEmpty() && interval.getBegin() != getEnd()) { 
    110                         newStyles = newStyles.replaceDerive(this.unitAt(interval.getBegin()).getStyle()); 
     110                        newStyles = newStyles.derive(this.unitAt(interval.getBegin()).getStyle()); 
    111111                } 
    112112                // XXX I do not agree we should bypass invalid intervals --kyli 
    113113                for (int i = index; i < Math.min(interval.getEnd(), getEnd()); ++i) { 
     
    119119                if (newText.getEnd() >= 1) { 
    120120                        TextUnit unit = newText.unitAt(0); 
    121121                        HotStyleDef style = unit.getStyle(); 
    122                                 newStyle = newStyle.replaceDerive(style); 
     122                                newStyle = newStyle.derive(style); 
    123123                } 
    124124 
    125125                for (int i = 0; i < newText.getEnd(); ++i, ++index) { 
  • modules/org.sophie2.base.model.text/src/main/java/org/sophie2/base/model/text/style/HotStyleDef.java

     
    3737 
    3838        private static final Map<ImmMap<HotAttr<?>, Object>, HotStyleDef> usedStyles =  
    3939                new HashMap<ImmMap<HotAttr<?>,Object>, HotStyleDef>(); 
    40          
    41          
     40 
     41 
    4242        private HotStyleDef(ImmMap<HotAttr<?>, Object> values) { 
    4343                // Disable direct instantiation. 
    4444                ImmMap<HotAttr<?>, Object> allValues = values; 
    45                  
     45 
    4646                if (allValues == null) { 
    4747                        allValues = ImmTreeMap.<HotAttr<?>, Object>empty(); 
    4848                } 
     
    7272        public ImmMap<HotAttr<?>, Object> getValues() { 
    7373                return this.attrValues; 
    7474        } 
    75          
     75 
    7676        /** 
    7777         * Retrieves a default style. 
    7878         *  
     
    158158                                concat = concat.remove(key); 
    159159                        } 
    160160                } 
    161                  
    162161                return internDef(concat); 
    163162        } 
    164163 
     
    175174        public HotStyleDef derive(HotStyleDef style) { 
    176175 
    177176                ImmMap<HotAttr<?>, Object> concat =  this.attrValues; 
    178                  
     177 
    179178                Iterator<ImmMap.ImmEntry<HotAttr<?>, Object>> it = style.attrValues.iterator(); 
    180179                while (it.hasNext()) { 
    181180                        ImmMap.ImmEntry<HotAttr<?>, Object> entry = it.next(); 
     
    187186                                concat = concat.remove(entry.getKey()); 
    188187                        } 
    189188                } 
    190                  
    191189                return internDef(concat); 
    192190        } 
    193191 
     
    206204 
    207205                ImmMap<HotAttr<?>, Object> concat =  this.attrValues; //getNonDefaultKeys(this.attrValues); 
    208206                Iterator<ImmMap.ImmEntry<HotAttr<?>, Object>> it = style.attrValues.iterator(); //getNonDefaultKeys(style.attrValues).iterator(); 
    209                  
     207 
    210208                while (it.hasNext()) { 
    211209                        ImmMap.ImmEntry<HotAttr<?>, Object> entry = it.next(); 
    212210                        HotAttr<?> key = entry.getKey(); 
     
    246244                HotStyleDef otherStyle = (HotStyleDef) obj; 
    247245 
    248246                for (HotAttr<?> attr : allAttributes) { 
     247                        if (! (otherStyle.attrValues.contains(attr) && this.attrValues.contains(attr) || 
     248                                        (!otherStyle.attrValues.contains(attr) && !this.attrValues.contains(attr)))) { 
     249                                return false; 
     250                        } 
    249251                        if (! otherStyle.getValue(attr).equals(this.getValue(attr))) { 
    250252                                return false; 
    251253                        } 
     254 
    252255                } 
    253256                return true; 
    254257        } 
    255258 
    256          
     259 
    257260        @Override 
    258261        public int hashCode() { 
    259262                final int prime = 31;