Ticket #2456: presentation-mode-de.patch

File presentation-mode-de.patch, 24.1 KB (added by deni, 15 years ago)
  • modules/org.sophie2.base.menus/src/main/java/org/sophie2/base/menus/MenuBar.java

    ### Eclipse Workspace Patch 1.0
    #P sophie
     
    4040                        protected void setup(JMenuBar res) { 
    4141                                items().get(); // ensure this is available 
    4242                                res.setEnabled(true); 
    43                                 res.setVisible(true); 
     43                                res.setVisible(true);                            
    4444                                 
    45                                  
    4645                                res.removeAll(); 
    4746                                for(MenuMember m : items().get()) { 
    4847                                        assert m != null : "cannot add a separator (marked by null) in a menu bar"; 
  • modules/org.sophie2.main.layout.mydoggy/src/main/java/org/sophie2/main/layout/mydoggy/MDAppletWindow.java

     
    8181                                if (mainWindow().get() != null && mainWindow().get().menuBar().get() != null) { 
    8282                                        res.setJMenuBar(mainWindow().get().menuBar().get().swingMenuBar().get()); 
    8383                                } 
     84                                 
     85                                if (mainWindow().get().mainWindowOptions().get().isInPresentationMode()) { 
     86                                        res.getJMenuBar().setVisible(false); 
     87                                } else { 
     88                                        res.getJMenuBar().setVisible(true); 
     89                                } 
    8490                        } 
    8591 
    8692                        @SuppressWarnings("unused") 
  • modules/org.sophie2.main.app.menus/src/main/java/org/sophie2/main/app/menus/view/PresentationItem.java

     
     1package org.sophie2.main.app.menus.view; 
     2 
     3import java.awt.event.KeyEvent; 
     4 
     5import javax.swing.KeyStroke; 
     6 
     7import org.sophie2.base.commons.util.ImageUtil; 
     8import org.sophie2.base.commons.util.ImmImage; 
     9import org.sophie2.base.layout.model.MainWindowOptions.ScreenMode; 
     10import org.sophie2.base.menus.MenuMember; 
     11import org.sophie2.base.skins.SkinElementId; 
     12import org.sophie2.base.visual.BaseVisualElement; 
     13import org.sophie2.base.visual.skins.ElementPartCreator; 
     14import org.sophie2.base.visual.skins.SkinPartDef; 
     15import org.sophie2.base.visual.skins.VisualElementDef; 
     16import org.sophie2.main.app.menus.AppMenuItem; 
     17 
     18/** 
     19 * The <i>View -> Presentation Mode</i> menu item. 
     20 *  
     21 * @author deni 
     22 */ 
     23@SkinElementId("app.menus.view.presentation-menu-item") 
     24@VisualElementDef(parent=ViewMenu.class, sortKey="44-presentation-item") 
     25public class PresentationItem extends AppMenuItem { 
     26         
     27        @SuppressWarnings("unused") 
     28        @SkinPartDef 
     29        private static void defineSkin(ElementPartCreator part) { 
     30                part.add(BaseVisualElement.TITLE_PROP_ID, "Presentation Mode"); 
     31                part.add(BaseVisualElement.TOOL_TIP_PROP_ID, "Use Sophie in presentation mode"); 
     32                part.add(MenuMember.MNEMONIC_PROP_ID, KeyEvent.VK_P); 
     33                part.add(MenuMember.ACCELERATOR_PROP_ID, KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0)); 
     34                part.add(ICON_PROP_ID, ImageUtil.loadIcon("tick.png")); 
     35        } 
     36 
     37        @Override 
     38        protected boolean computeEnabled() { 
     39                return true; 
     40        } 
     41         
     42        @Override 
     43        protected ImmImage computeIcon() { 
     44                 
     45                if(getMainWindow() != null) { 
     46                        ScreenMode screenMode = getMainWindow().mainWindowOptions().get().getScreenMode(); 
     47                        Boolean isIconVisible = screenMode.equals(ScreenMode.PRESENTATION); 
     48         
     49                        if(isIconVisible) { 
     50                                return super.computeIcon(); 
     51                        } 
     52                } 
     53                 
     54                return null; 
     55        } 
     56} 
  • modules/org.sophie2.base.scene/src/main/java/org/sophie2/base/scene/BaseSceneVisual.java

     
    4242                } 
    4343                part.addInteraction("M_CONTROL TAB", EventIds.SELECT_NEXT_BOOK); 
    4444                part.addInteraction("M_CONTROL M_SHIFT TAB", EventIds.SELECT_PREVIOUS_BOOK); 
    45  
     45                 
     46                part.addInteraction("F5", EventIds.TOGGLE_PRESENTATION_MODE); 
    4647        } 
    4748 
    4849        /** 
     
    6667                 * Event to select previous book 
    6768                 */ 
    6869                @EventParams({}) 
    69                 SELECT_PREVIOUS_BOOK; 
     70                SELECT_PREVIOUS_BOOK, 
     71                 
     72                /** 
     73                 * Open/close presentation mode. 
     74                 */ 
     75                @EventParams({}) 
     76                TOGGLE_PRESENTATION_MODE; 
    7077        } 
    7178 
    7279        private static final int DEFAULT_PADDING_L = 18; 
  • modules/org.sophie2.base.layout/src/main/java/org/sophie2/base/layout/model/TabBar.java

     
    2020        public Prop<? extends MainWindow> parent() { 
    2121                return getBean().makeParentProp(MainWindow.class); 
    2222        } 
     23         
     24        @Override 
     25        public boolean computeVisible() { 
     26                return parent().get().mainWindowOptions().get().flapsShown(); 
     27        } 
    2328 
    24  
    2529} 
  • modules/org.sophie2.main.layout.mydoggy/src/main/java/org/sophie2/main/layout/mydoggy/MDMainWindow.java

     
    151151         *  
    152152         * @return The property. 
    153153         */ 
     154        @Own 
    154155        public Prop<MainWindow> mainWindow() { 
    155156                return getBean().makeFinalProp("mainWindow", MainWindow.class); 
    156157        } 
     
    665666         */ 
    666667        private void registerFlap(MDFlap mdFlap) { 
    667668                 
    668                 if (mdFlap == null) { 
     669                if (mdFlap == null || !mdFlap.visible().get()) { 
    669670                        // No flap, no tabs. 
     671                        toolWindowManager().get().unregisterAllToolWindow(); 
    670672                        return; 
    671                 } 
     673                }                
    672674                 
    673675                for (MDTab tab : mdFlap.subElements().get()) { 
    674676                        String tabTitle = tab.title().get(); 
    675677 
    676678                        ToolWindowAnchor anchor = tab.toolWindowAnchor().get() != null ?  
    677679                                        tab.toolWindowAnchor().get() : ToolWindowAnchor.LEFT; 
     680                                         
     681                        if (toolWindowManager().get().getToolWindow(tabTitle) == null) { 
    678682 
    679                                         if (toolWindowManager().get().getToolWindow(tabTitle) == null) { 
     683                                toolWindowManager().get().registerToolWindow(tabTitle, tabTitle, null,  
     684                                                tab.toolWindowManager().get(), anchor); 
    680685 
    681                                                 toolWindowManager().get().registerToolWindow(tabTitle, tabTitle, null,  
    682                                                                 tab.toolWindowManager().get(), anchor); 
     686                                SophieLog.debug("Registering tool window \"" + tabTitle + "\"!"); 
    683687 
    684                                                 SophieLog.debug("Registering tool window \"" + tabTitle + "\"!"); 
     688                                ToolWindow tabToolWindow = toolWindowManager().get().getToolWindow( 
     689                                                tabTitle); 
    685690 
    686                                                 ToolWindow tabToolWindow = toolWindowManager().get().getToolWindow( 
    687                                                                 tabTitle); 
     691                                MDToolWindowHelper.configureToolWindowDescriptors(tabToolWindow); 
     692                                        tabToolWindow.setAvailable(true); 
    688693 
    689                                                 MDToolWindowHelper.configureToolWindowDescriptors(tabToolWindow); 
    690                                                 tabToolWindow.setAvailable(true); 
     694                                tabToolWindow.setVisible(getDefaultVisibility(anchor)); 
    691695 
    692                                                 tabToolWindow.setVisible(getDefaultVisibility(anchor)); 
    693  
    694                                         } else { 
    695  
    696                                                 SophieLog.debug("Tool window \"" + tabTitle + "\" already registered!"); 
    697                                         } 
    698  
     696                        } else { 
     697                                SophieLog.debug("Tool window \"" + tabTitle + "\" already registered!"); 
     698                        }  
     699                         
    699700                } 
    700701 
    701702        } 
  • modules/org.sophie2.base.layout/src/main/java/org/sophie2/base/layout/impl/BaseLayoutEngine.java

     
    1919 */ 
    2020public abstract class BaseLayoutEngine extends BaseVisualElement implements     LayoutEngine { 
    2121 
    22         @Own 
    2322        public RwListProp<MainWindow> mainWindows() {  
    2423                return getBean().makeListProp("mainWindows", MainWindow.class);  
    2524        } 
  • modules/org.sophie2.main.app.menus/pom.xml

     
    102102                </dependency> 
    103103                <dependency> 
    104104                        <groupId>org.sophie2</groupId> 
     105                        <artifactId>org.sophie2.main.layout.mydoggy</artifactId> 
     106                        <version>2.0.6</version> 
     107                </dependency> 
     108                <dependency> 
     109                        <groupId>org.sophie2</groupId> 
    105110                        <artifactId>org.sophie2.main.func.file</artifactId> 
    106111                        <version>2.0.6</version> 
    107112                        <type>jar</type> 
  • modules/org.sophie2.main.app.menus/src/main/java/org/sophie2/main/app/menus/view/ViewMenuLogic.java

     
    11package org.sophie2.main.app.menus.view; 
    22 
     3import java.awt.Dimension; 
     4 
     5import org.sophie2.base.commons.util.position.ImmSize; 
    36import org.sophie2.base.layout.impl.DefaultMainWindow; 
    47import org.sophie2.base.layout.model.MainWindowOptions; 
     8import org.sophie2.base.layout.model.MainWindowOptions.ScreenMode; 
    59import org.sophie2.base.menus.MenuItem; 
     10import org.sophie2.base.scene.BaseSceneVisual; 
     11import org.sophie2.base.visual.VisualElement; 
    612import org.sophie2.core.modularity.SortKey; 
    713import org.sophie2.core.mvc.EventFilterBuilder; 
    814import org.sophie2.core.mvc.LogicR3; 
    915import org.sophie2.core.mvc.OperationDef; 
    1016import org.sophie2.core.mvc.events.EventR3; 
    1117import org.sophie2.main.app.commons.app.AppMainWindow; 
     18import org.sophie2.main.app.commons.book.BaseBookDocView; 
     19import org.sophie2.main.app.commons.book.BaseBookView; 
     20import org.sophie2.main.app.commons.book.panels.PreviewModePanel; 
    1221import org.sophie2.main.app.commons.util.AppViewUtil; 
     22import org.sophie2.main.layout.mydoggy.MDMainWindow; 
    1323 
    1424/** 
    1525 * Handles events fired by the {@link ViewMenu}. 
     
    4656                                        MainWindowOptions.ScreenMode.NORMAL); 
    4757                } 
    4858        }, 
     59         
     60        /** 
     61         * Handles a user request to go in presentation mode. Sets the appropriate 
     62         * {@link MainWindowOptions}. It is responsibility of the layout to actually 
     63         * display the presentation mode. 
     64         */ 
     65        @SortKey("rrt-set-presentation-mode") 
     66        ON_PRESENTATION_MODE_MENU { 
     67                public void defineFilter(EventFilterBuilder filter) { 
     68                        filter.setSourceClass(PresentationItem.class); 
     69                        filter.setEventId(MenuItem.EventIds.CLICKED); 
     70                } 
    4971 
     72                @SuppressWarnings("synthetic-access") 
     73                public boolean handle(EventR3 event) { 
     74                        PresentationItem source = event.getSource(PresentationItem.class); 
     75                        return togglePresentationMode(source); 
     76                } 
     77        }, 
     78         
     79        @SortKey("rru-set-presentation-mode") 
     80        ON_PRESENTATION_MODE_SCENE_VISUAL { 
     81                public void defineFilter(EventFilterBuilder filter) { 
     82                        filter.setSourceClass(BaseSceneVisual.class); 
     83                        filter.setEventId(BaseSceneVisual.EventIds.TOGGLE_PRESENTATION_MODE); 
     84                } 
     85 
     86                @SuppressWarnings("synthetic-access") 
     87                public boolean handle(EventR3 event) { 
     88                        System.out.println("ON_PRESENTATION_MODE_SCENE_VISUAL"); 
     89                        BaseSceneVisual source = event.getSource(BaseSceneVisual.class); 
     90                        return togglePresentationMode(source); 
     91                } 
     92        }, 
     93 
    5094        /** 
    5195         * Handles a user request to return to normal mode. 
    5296         */ 
     
    65109                                        DefaultMainWindow.EventIds.SET_SCREEN_MODE, 
    66110                                        MainWindowOptions.ScreenMode.NORMAL); 
    67111                } 
     112        }; 
     113         
     114        // used to save the current window, so it could be restored 
     115        // on closing presentation mode 
     116        private static BaseBookDocView lastCurrentDocView; 
     117         
     118        private static boolean togglePresentationMode(VisualElement source) { 
     119                BaseBookDocView bdw = AppViewUtil.getCurrentBookDocView(source); 
     120                if (bdw == null) { 
     121                        return false; 
     122                } 
     123                 
     124                AppMainWindow mainWindow = AppViewUtil.findMainWindow(source); 
     125                ScreenMode currentMode = mainWindow.mainWindowOptions().get().getScreenMode(); 
     126                if (!ScreenMode.PRESENTATION.equals(currentMode)) {                                              
     127                        lastCurrentDocView = bdw; 
     128                          
     129                        if (!bdw.bookView().get().getViewOptions().isPreviewMode()) { 
     130                                boolean previewOpened = LogicR3.fire(source, null, null, null,  
     131                                                PreviewModePanel.EventIds.OPEN_PREVIEW); 
     132                                assert previewOpened : "Could not open preview"; 
     133                        } 
     134                         
     135                        boolean handled = LogicR3.fire(mainWindow, null, null, null, 
     136                                        DefaultMainWindow.EventIds.SET_SCREEN_MODE, 
     137                                        MainWindowOptions.ScreenMode.PRESENTATION); 
     138                         
     139                        BaseBookDocView newBdw = (BaseBookDocView) mainWindow.currentDocument().get(); 
     140                        BaseBookView bookView = newBdw.bookView().get(); 
     141                        ImmSize pageSize = bookView.model().get().getPageSize(); 
     142                         
     143                        MDMainWindow mdWindow = mainWindow.findParentElement(MDMainWindow.class); 
     144                        Dimension windowSize = mdWindow.globalContainer().get().getSize(); 
     145                         
     146                        float widthRatio = (windowSize.width - 60) / pageSize.getWidth(); 
     147                        float heigthRatio = (windowSize.height - 60) / pageSize.getHeight(); 
     148                        float zoom = widthRatio < heigthRatio ? widthRatio : heigthRatio;                        
     149                        bookView.setViewOptions(bookView.getViewOptions().modifyZoom(zoom)); 
     150                         
     151                        return handled; 
     152                } 
     153                 
     154                if (bdw != lastCurrentDocView) {                         
     155                        boolean previewClosed = LogicR3.fire(source, null, null, null,  
     156                                        PreviewModePanel.EventIds.CLOSE_PREVIEW); 
     157                        assert previewClosed : "Could not close preview"; 
     158                         
     159                        mainWindow.currentDocument().set(lastCurrentDocView); 
     160                } 
     161                 
     162                return LogicR3.fire(mainWindow, null, null, null, 
     163                                DefaultMainWindow.EventIds.SET_SCREEN_MODE, 
     164                                MainWindowOptions.ScreenMode.NORMAL); 
    68165        } 
    69166} 
  • modules/org.sophie2.main.layout.mydoggy/src/main/java/org/sophie2/main/layout/mydoggy/MDFlap.java

     
    101101                } 
    102102                return getBean().makeProp(subElements.class); 
    103103        } 
     104         
     105        @Override 
     106        public boolean computeVisible() { 
     107                return parent().get().mainWindow().get().mainWindowOptions().get().flapsShown(); 
     108        } 
    104109} 
  • modules/org.sophie2.main.layout.mydoggy/src/main/java/org/sophie2/main/layout/mydoggy/MDFrameWindow.java

     
    191191                                // Adding menu 
    192192                                if (mainWindow != null && mainWindow.menuBar().get() != null) { 
    193193                                        gcf.setJMenuBar(mainWindow.menuBar().get().swingMenuBar().get()); 
     194                                 
     195                                        if (mainWindow.mainWindowOptions().get().isInPresentationMode()) { 
     196                                                gcf.getJMenuBar().setVisible(false); 
     197                                        } else { 
     198                                                gcf.getJMenuBar().setVisible(true); 
     199                                        } 
    194200                                } 
    195201                                 
    196202                        } 
  • modules/org.sophie2.main.app.menus/src/main/java/org/sophie2/main/app/menus/view/ViewMenu.java

     
    2020 */ 
    2121@SkinElementId("app.menus.view-menu") 
    2222@VisualElementDef(parent=AppMenuBar.class, sortKey="da-view-menu") 
    23 @RelatedChildren({NormalModeItem.class, FullScreenItem.class}) 
     23@RelatedChildren({NormalModeItem.class, FullScreenItem.class, PresentationItem.class}) 
    2424public class ViewMenu extends AppMenu{ 
    2525 
    2626        @SuppressWarnings("unused") 
  • modules/org.sophie2.main.layout.mydoggy/src/main/java/org/sophie2/main/layout/mydoggy/MDDocumentWindow.java

     
    2222import org.sophie2.base.layout.impl.DefaultDocView; 
    2323import org.sophie2.base.layout.model.DocView; 
    2424import org.sophie2.base.layout.model.MainWindow; 
     25import org.sophie2.base.layout.model.MainWindowOptions.ScreenMode; 
    2526import org.sophie2.base.visual.BaseVisualElement; 
    2627import org.sophie2.core.mvc.LogicR3; 
    2728import org.sophie2.core.prolib.annot.Setup; 
     
    200201                                        res.setContentPane(model().get().swingComponent().get()); 
    201202                                } 
    202203                        } 
     204                         
     205                        @SuppressWarnings("unused") 
     206                        @Setup 
     207                        protected void setUpTitleBarVisibility(JInternalFrame res) throws PropertyVetoException { 
     208                                 
     209                                if (parent().get() != null && parent().get().mainWindow().get() != null) { 
     210                                        BasicInternalFrameUI ui = (BasicInternalFrameUI)res.getUI(); 
     211                                        BasicInternalFrameTitlePane northPaneComponent =  
     212                                                (BasicInternalFrameTitlePane)ui.getNorthPane(); 
     213                                         
     214                                        ScreenMode mode =  
     215                                                parent().get().mainWindow().get().mainWindowOptions().get().getScreenMode(); 
     216                                        if (ScreenMode.PRESENTATION.equals(mode)) { 
     217                                                northPaneComponent.setVisible(false); 
     218                                                northPaneComponent.setPreferredSize(new Dimension(0, 0)); 
     219                                                res.setMaximum(true); 
     220                                        } else { 
     221                                                northPaneComponent.setVisible(true); 
     222                                                northPaneComponent.setPreferredSize(null); 
     223                                        } 
     224                                } 
     225                        } 
    203226 
    204227                        @SuppressWarnings("unused") 
    205228                        @Setup 
    206                         protected void setUpProperties(JInternalFrame res) { 
     229                        protected void setUpProperties(JInternalFrame res) {             
    207230                                res.setTitle(model().get().title().get()); 
    208231                                res.setToolTipText(model().get().toolTip().get()); 
    209232 
  • modules/org.sophie2.base.layout/src/main/java/org/sophie2/base/layout/model/MainWindowOptions.java

     
    135135                return !ScreenMode.NORMAL.equals(this.screenMode); 
    136136        } 
    137137         
     138        public boolean isInPresentationMode() { 
     139                return ScreenMode.PRESENTATION.equals(this.screenMode); 
     140        } 
     141         
    138142        /** 
    139143         * Indicates whether flaps should be shown. Useful for presentation mode, 
    140144         * but in other cases as well. 
  • modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/app/DocumentsLogic.java

     
    3737 
    3838                public boolean handle(EventR3 event) { 
    3939                        DefaultDocView documentWindow = event.getSource(DefaultDocView.class); 
     40                        System.out.println("Selected doc view " + documentWindow.title().get()); 
    4041                        return DefaultDocView.setCurrent(documentWindow); 
    4142                } 
    4243        }, 
  • modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/book/BookPanel.java

     
    44 
    55import javax.swing.JPanel; 
    66 
     7import org.sophie2.base.layout.model.MainWindowOptions.ScreenMode; 
    78import org.sophie2.base.skins.SkinElementId; 
    89import org.sophie2.base.visual.BaseVisualElement; 
    910import org.sophie2.core.prolib.annot.Own; 
     
    1213import org.sophie2.core.prolib.interfaces.ListProp; 
    1314import org.sophie2.core.prolib.interfaces.Prop; 
    1415import org.sophie2.core.prolib.list.ProList; 
     16import org.sophie2.main.app.commons.app.AppMainWindow; 
    1517import org.sophie2.main.app.commons.book.panels.BookPanelElement; 
     18import org.sophie2.main.app.commons.util.AppViewUtil; 
    1619 
    1720/** 
    1821 * The navigation,search and mode buttons, checks and fields in the 
     
    103106                } 
    104107                return getBean().makeProp(bookPanelElements.class); 
    105108        } 
     109         
     110        @Override 
     111        public boolean computeVisible() { 
     112                AppMainWindow mainWindow = AppViewUtil.findMainWindow(this); 
     113                if (mainWindow != null) { 
     114                        ScreenMode screenMode = mainWindow.mainWindowOptions().get().getScreenMode(); 
     115                        return !ScreenMode.PRESENTATION.equals(screenMode); 
     116                } 
     117                 
     118                return false; 
     119        } 
    106120} 
  • modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/book/panels/BookPanelLogic.java

     
    55import org.sophie2.base.bound.ComboInput; 
    66import org.sophie2.base.layout.impl.DefaultDocView; 
    77import org.sophie2.base.model.book.BookH; 
     8import org.sophie2.base.visual.VisualElement; 
    89import org.sophie2.core.logging.SophieLog; 
    910import org.sophie2.core.modularity.SortKey; 
    1011import org.sophie2.core.mvc.EventFilterBuilder; 
     
    2122import org.sophie2.main.app.commons.book.panels.NavigationPanel.NextPageButton; 
    2223import org.sophie2.main.app.commons.book.panels.NavigationPanel.PreviousPageButton; 
    2324import org.sophie2.main.app.commons.book.panels.OutlineFramesPanel.AddOutlineButton; 
    24 import org.sophie2.main.app.commons.book.panels.PreviewModePanel.ClosePreviewButton; 
    25 import org.sophie2.main.app.commons.book.panels.PreviewModePanel.OpenPreviewButton; 
    2625import org.sophie2.main.app.commons.book.panels.ZoomPercentagePanel.ZoomLevel; 
    2726import org.sophie2.main.app.commons.page.PageWorkArea; 
    2827import org.sophie2.main.app.commons.util.AppViewUtil; 
     
    240239 
    241240                public void defineFilter(EventFilterBuilder filter) { 
    242241                        filter.setEventId(PreviewModePanel.EventIds.OPEN_PREVIEW); 
    243                         filter.setSourceClass(OpenPreviewButton.class);                  
     242                        filter.setSourceClass(VisualElement.class);                      
    244243                } 
    245244 
    246245                public boolean handle(EventR3 event) { 
    247                         OpenPreviewButton source = event.getSource(OpenPreviewButton.class); 
    248                         PreviewModePanel panel = source.findParentElement(PreviewModePanel.class); 
    249                         AppMainWindow mainWindow = AppViewUtil.findMainWindow(panel); 
    250                         BaseBookDocView docView = AppViewUtil.getCurDocView(panel, BaseBookDocView.class); 
     246                        VisualElement source = event.getSource(VisualElement.class); 
     247                        AppMainWindow mainWindow = AppViewUtil.findMainWindow(source); 
     248                        BaseBookDocView docView = AppViewUtil.getCurDocView(source, BaseBookDocView.class); 
    251249                        assert docView != null : "There is no current book to open in preview mode.";            
    252250 
    253251                        if (docView.workArea().get().getRootPageView() == null) { 
     
    290288 
    291289                public void defineFilter(EventFilterBuilder filter) { 
    292290                        filter.setEventId(PreviewModePanel.EventIds.CLOSE_PREVIEW); 
    293                         filter.setSourceClass(ClosePreviewButton.class); 
     291                        filter.setSourceClass(VisualElement.class); 
    294292                } 
    295293 
    296294                public boolean handle(EventR3 event) { 
    297                         ClosePreviewButton source = event.getSource(ClosePreviewButton.class); 
    298                         PreviewModePanel panel = source.findParentElement(PreviewModePanel.class); 
    299                         BaseBookDocView docView = AppViewUtil.getCurDocView(panel, BaseBookDocView.class); 
     295                        VisualElement source = event.getSource(VisualElement.class); 
     296                        BaseBookDocView docView = AppViewUtil.getCurDocView(source, BaseBookDocView.class); 
    300297                        assert docView != null : "There is no current book to open in preview mode."; 
    301298 
    302299                        assert docView.bookView().get().getViewOptions().isPreviewMode() :