1 package cz
.cvut
.promod
.gui
;
3 import com
.jidesoft
.dialog
.AbstractDialogPage
;
4 import com
.jidesoft
.docking
.DockableFrame
;
5 import com
.jidesoft
.swing
.JideButton
;
6 import cz
.cvut
.promod
.actions
.LoadDialogAction
;
7 import cz
.cvut
.promod
.gui
.dialogs
.loadErrors
.LoadErrorsDialog
;
8 import cz
.cvut
.promod
.gui
.dialogs
.newProject
.NewProjectDialog
;
9 import cz
.cvut
.promod
.gui
.dialogs
.simpleTextFieldDialog
.SimpleTextFieldDialog
;
10 import cz
.cvut
.promod
.gui
.dialogs
.simpleTextFieldDialog
.SimpleTextFieldDialogExecutor
;
11 import cz
.cvut
.promod
.gui
.dialogs
.pluginsOverview
.PluginsOverviewDialogDialog
;
12 import cz
.cvut
.promod
.gui
.listeners
.ButtonPopupAdapter
;
13 import cz
.cvut
.promod
.gui
.listeners
.DockFrameListener
;
14 import cz
.cvut
.promod
.gui
.listeners
.SideButtonListener
;
15 import cz
.cvut
.promod
.gui
.settings
.utils
.BasicSettingPage
;
16 import cz
.cvut
.promod
.gui
.settings
.SettingPageData
;
17 import cz
.cvut
.promod
.gui
.settings
.SettingsDialog
;
18 import cz
.cvut
.promod
.gui
.settings
.utils
.SettingPage
;
19 import cz
.cvut
.promod
.gui
.support
.utils
.DockableFrameWrapper
;
20 import cz
.cvut
.promod
.gui
.support
.utils
.NotationGuiHolder
;
21 import cz
.cvut
.promod
.plugin
.extension
.Extension
;
22 import cz
.cvut
.promod
.plugin
.notationSpecificPlugIn
.DockableFrameData
;
23 import cz
.cvut
.promod
.plugin
.notationSpecificPlugIn
.module
.Module
;
24 import cz
.cvut
.promod
.plugin
.notationSpecificPlugIn
.notation
.Notation
;
25 import cz
.cvut
.promod
.plugin
.notationSpecificPlugIn
.notation
.NotationWorkspaceData
;
26 import cz
.cvut
.promod
.plugin
.notationSpecificPlugIn
.notation
.utils
.NotationWorkspaceDataDefault
;
27 import cz
.cvut
.promod
.plugin
.notationSpecificPlugIn
.notation
.workspace
.UpdatableWorkspaceComponent
;
28 import cz
.cvut
.promod
.services
.ModelerSession
;
29 import cz
.cvut
.promod
.services
.actionService
.actionUtils
.ProModAction
;
30 import cz
.cvut
.promod
.services
.menuService
.MenuControlService
;
31 import cz
.cvut
.promod
.services
.menuService
.MenuService
;
32 import cz
.cvut
.promod
.services
.menuService
.utils
.ModelerMenuItem
;
33 import cz
.cvut
.promod
.services
.menuService
.utils
.MenuItemPosition
;
34 import cz
.cvut
.promod
.services
.pluginLoaderService
.utils
.NotationSpecificPlugins
;
35 import cz
.cvut
.promod
.services
.pluginLoaderService
.utils
.PluginLoadErrors
;
36 import cz
.cvut
.promod
.resources
.Resources
;
37 import org
.apache
.log4j
.Logger
;
40 import javax
.swing
.tree
.TreePath
;
42 import java
.awt
.event
.*;
43 import java
.beans
.PropertyChangeEvent
;
44 import java
.beans
.PropertyChangeListener
;
45 import java
.util
.Collection
;
46 import java
.util
.LinkedList
;
47 import java
.util
.List
;
50 * ProMod, master thesis project
51 * User: Petr Zverina, petr.zverina@gmail.com
52 * Date: 16:09:42, 10.10.2009
56 * Basic class of the host application.
58 public class Modeler
extends ModelerView
{
60 private static final Logger LOG
= Logger
.getLogger(Modeler
.class);
62 public static final String ACTION_NEW_PROJECT_DIALOG
= "modeler.action.new.project";
63 public static final String ACTION_EXIT
= "modeler.action.exit";
64 public static final String ACTION_PROJECT_LOAD
= "modeler.action.project.load";
65 public static final String ACTION_PROJECT_SAVE
= "modeler.action.project.save";
66 public static final String ACTION_SWITH_USER
= "modeler.action.switch.user";
67 public static final String ACTION_PROJECT_NAVIG_SHOW
= "modeler.action.navigation";
68 public static final String ACTION_SETTINGS_SHOW
= "modeler.action.settings";
69 public static final String ACTION_PLUGINS_OVERVIEW_SHOW
= "modeler.action.plugins.overview";
71 public static final String LOAD_SYNC_TITLE_ERROR_LABEL
=
72 ModelerSession
.getCommonResourceBundle().getString("modeler.action.project.load.error.sync.title");
73 public static final String LOAD_SYNC_MESSAGE_ERROR_LABEL
=
74 ModelerSession
.getCommonResourceBundle().getString("modeler.action.project.load.error.sync.message");
75 public static final String USER_CHANGE_DIALOG_TITLE_LABEL
=
76 ModelerSession
.getCommonResourceBundle().getString("modeler.user.service");
77 public static final String USER_CHANGE_DIALOG_LABEL
=
78 ModelerSession
.getCommonResourceBundle().getString("modeler.user.name");
79 public static final String OK_LABEL
=
80 ModelerSession
.getCommonResourceBundle().getString("modeler.ok");
81 public static final String YES_LABEL
=
82 ModelerSession
.getCommonResourceBundle().getString("modeler.yes");
83 public static final String NO_LABEL
=
84 ModelerSession
.getCommonResourceBundle().getString("modeler.no");
85 public static final String CANCEL_LABEL
=
86 ModelerSession
.getCommonResourceBundle().getString("modeler.cancel");
87 public static final String USER_CHANGE_DIALOG_INVALID_LABEL
=
88 ModelerSession
.getCommonResourceBundle().getString("modeler.user.invalid.name");
89 public static final String SAVE_ALL_LABEL
=
90 ModelerSession
.getCommonResourceBundle().getString("modeler.exit.save.all");
91 public static final String SKIP_ALL_LABEL
=
92 ModelerSession
.getCommonResourceBundle().getString("modeler.exit.skip.all");
93 public static final String PROMOD_EXIT_LABEL
=
94 ModelerSession
.getCommonResourceBundle().getString("modeler.exit");
95 public static final String UNSAVED_CHANGE_LABEL
=
96 ModelerSession
.getCommonResourceBundle().getString("modeler.exit.diagram.unsaved.change");
97 public static final String SETTINGS_LABEL
=
98 ModelerSession
.getCommonResourceBundle().getString("modeler.settings");
99 public static final String FILE_LABEL
=
100 ModelerSession
.getCommonResourceBundle().getString("modeler.menu.file");
101 public static final String PROJECT_LABEL
=
102 ModelerSession
.getCommonResourceBundle().getString("modeler.menu.project");
103 public static final String EDIT_LABEL
=
104 ModelerSession
.getCommonResourceBundle().getString("modeler.menu.edit");
105 public static final String WINDOW_LABEL
=
106 ModelerSession
.getCommonResourceBundle().getString("modeler.menu.window");
107 public static final String PLUGINS_OVERVIEW_LABEL
=
108 ModelerSession
.getCommonResourceBundle().getString("modeler.plugins.overview");
110 public static final Object
[] EXIT_DIALOG_OPTIONS
= {
111 YES_LABEL
,NO_LABEL
, SAVE_ALL_LABEL
, SKIP_ALL_LABEL
, CANCEL_LABEL
};
113 public static enum ExitDialogReturnValues
{CONTINUE
, STOP
, CANCEL
}
115 private final ModelerModel model
;
119 ModelerSession
.setFrame(this);
121 this.model
= new ModelerModel();
127 initProjectNavigation();
133 * Initialize actions that belong to the 'virtual' "modeler" notation.
135 private void initActions(){
136 ModelerSession
.getActionService().registerAction(
137 ModelerModel
.MODELER_IDENTIFIER
,
138 ACTION_PLUGINS_OVERVIEW_SHOW
,
139 new ProModAction(PLUGINS_OVERVIEW_LABEL
, null, KeyStroke
.getKeyStroke(
140 KeyEvent
.VK_O
, java
.awt
.event
.InputEvent
.SHIFT_MASK
| java
.awt
.event
.InputEvent
.CTRL_MASK
)){
141 public void actionPerformed(ActionEvent event
) {
142 new PluginsOverviewDialogDialog();
147 ModelerSession
.getActionService().registerAction(
148 ModelerModel
.MODELER_IDENTIFIER
,
149 ACTION_PLUGINS_OVERVIEW_SHOW
,
150 new ProModAction(PLUGINS_OVERVIEW_LABEL
, null, KeyStroke
.getKeyStroke(
151 KeyEvent
.VK_O
, java
.awt
.event
.InputEvent
.SHIFT_MASK
| java
.awt
.event
.InputEvent
.CTRL_MASK
)){
152 public void actionPerformed(ActionEvent event
) {
153 new PluginsOverviewDialogDialog();
158 ModelerSession
.getActionService().registerAction(
159 ModelerModel
.MODELER_IDENTIFIER
,
160 ACTION_SETTINGS_SHOW
,
161 new ProModAction(SETTINGS_LABEL
, null, KeyStroke
.getKeyStroke(
162 KeyEvent
.VK_S
, java
.awt
.event
.InputEvent
.ALT_MASK
| java
.awt
.event
.InputEvent
.CTRL_MASK
)){
163 public void actionPerformed(ActionEvent event
) {
164 SettingsDialog
.showOptionsDialog(model
.getSettingPagesModel());
169 ModelerSession
.getActionService().registerAction(
170 ModelerModel
.MODELER_IDENTIFIER
,
172 new ProModAction(USER_CHANGE_DIALOG_LABEL
, null, null){
173 public void actionPerformed(ActionEvent event
) {
174 new SimpleTextFieldDialog(
175 USER_CHANGE_DIALOG_TITLE_LABEL
,
176 USER_CHANGE_DIALOG_LABEL
,
180 new SimpleTextFieldDialogExecutor(){
181 public String
execute(final String text
) {
182 if(text
!= null && !text
.isEmpty()){
183 ModelerSession
.getUserService().setUser(text
);
187 return USER_CHANGE_DIALOG_INVALID_LABEL
;
190 ModelerSession
.getFrame(),
195 ModelerSession
.getActionService().registerAction(
196 ModelerModel
.MODELER_IDENTIFIER
,
197 ACTION_NEW_PROJECT_DIALOG
,
198 new ProModAction(ModelerSession
.getCommonResourceBundle().getString(
199 ACTION_NEW_PROJECT_DIALOG
),
200 Resources
.getIcon(Resources
.MODELER
+ Resources
.NEW_PROJECT_ICON
),
201 KeyStroke
.getKeyStroke(KeyEvent
.VK_N
, ActionEvent
.CTRL_MASK
)){
202 public void actionPerformed(ActionEvent event
) {
203 new NewProjectDialog();
207 ModelerSession
.getActionService().registerAction(
208 ModelerModel
.MODELER_IDENTIFIER
,
210 new ProModAction(ModelerSession
.getCommonResourceBundle().getString(ACTION_EXIT
), null, null){
211 public void actionPerformed(ActionEvent event
) {
216 ModelerSession
.getActionService().registerAction(
217 ModelerModel
.MODELER_IDENTIFIER
,
218 ACTION_PROJECT_NAVIG_SHOW
,
219 new ProModAction(ModelerSession
.getCommonResourceBundle().getString(ACTION_PROJECT_NAVIG_SHOW
), null, null){
220 public void actionPerformed(ActionEvent event
) {
221 swapProjectNavigationVisibility();
223 // update control components selection
224 putValue(Action
.SELECTED_KEY
, projectNavigationDockableFrame
.isAvailable());
225 projectNavigatorButton
.setSelected(projectNavigationDockableFrame
.isAvailable());
231 ModelerSession
.getActionService().registerAction(
232 ModelerModel
.MODELER_IDENTIFIER
,
234 new ProModAction(ModelerSession
.getCommonResourceBundle().getString(ACTION_PROJECT_SAVE
),
235 Resources
.getIcon(Resources
.MODELER
+ Resources
.SAVE_ALL_ICON
),
236 KeyStroke
.getKeyStroke(
237 KeyEvent
.VK_S
, java
.awt
.event
.InputEvent
.CTRL_MASK
)){
238 public void actionPerformed(ActionEvent event
) {
239 LOG
.debug("Action save invoked.");
241 final TreePath projectTreePath
= ModelerSession
.getProjectService().getSelectedProjectPath();
243 if(projectTreePath
== null){
246 final boolean syncResult
= ModelerSession
.getProjectControlService().synchronize(
247 projectTreePath
, true, true, false, false);
250 JOptionPane
.showMessageDialog(
251 ModelerSession
.getFrame(),
252 LOAD_SYNC_MESSAGE_ERROR_LABEL
,
253 LOAD_SYNC_TITLE_ERROR_LABEL
,
254 JOptionPane
.ERROR_MESSAGE
);
260 ModelerSession
.getActionService().registerAction(
261 ModelerModel
.MODELER_IDENTIFIER
,
263 new LoadDialogAction(ModelerSession
.getCommonResourceBundle().getString(
264 ACTION_PROJECT_LOAD
),
265 Resources
.getIcon(Resources
.MODELER
+ Resources
.OPEN_ICON
),
266 KeyStroke
.getKeyStroke(KeyEvent
.VK_O
, ActionEvent
.CTRL_MASK
)));
270 * Changed the project navigation visibility.
272 private void swapProjectNavigationVisibility(){
273 if( projectNavigationDockableFrame
.isAvailable() ){
274 dockingManager
.setFrameUnavailable(projectNavigationDockableFrame
.getName());
276 final String currentNotation
= ModelerSession
.getProjectService().getSelectedProjectNotationIndentifier();
278 final NotationGuiHolder specification
= model
.getNotationGuiHolder(currentNotation
);
280 if( specification
!= null ){
281 final List
<DockableFrame
> visibleDockableFrames
= new LinkedList
<DockableFrame
>();
283 for( final DockableFrame dockableFrame
: specification
.getListOfFrames(NotationGuiHolder
.Position
.LEFT
) ){
284 if( dockableFrame
.isAvailable() ){
285 visibleDockableFrames
.add((dockableFrame
));
286 specification
.getButton(dockableFrame
.getName(), NotationGuiHolder
.Position
.LEFT
).doClick();
290 dockingManager
.setFrameAvailable(projectNavigationDockableFrame
.getName());
292 for( final DockableFrame dockableFrame
: visibleDockableFrames
){
293 specification
.getButton(dockableFrame
.getName(), NotationGuiHolder
.Position
.LEFT
).doClick();
296 dockingManager
.setFrameAvailable(projectNavigationDockableFrame
.getName());
302 * Performs the terminating sequence.
304 private void modelerExit() {
305 LOG
.info("Modeler is shutting down.");
307 if(!checkForUnsavedChanges()){
308 LOG
.info("ProMod shut-down has been canceled by user");
314 // finishing notations & modules
315 for(final String notationIdentifier
: ModelerSession
.getNotationService().getNotationsIdentifiers()){
316 final NotationSpecificPlugins notationSpecificPlugins
= ModelerSession
.getNotationService().getNotationSpecificPlugins(notationIdentifier
);
318 notationSpecificPlugins
.getNotation().finish();
320 for(final Module module
: notationSpecificPlugins
.getModules()){
325 // finishing extensions
326 for(Extension extension
: ModelerSession
.getExtensionService().getExtensions()){
335 * Looks for unsaved changes in projects.
337 * @return true if ProMod is supposed to be terminated, false if the ProMod termination has been canceled
339 private boolean checkForUnsavedChanges() {
340 for(final TreePath projectTreePath
: ModelerSession
.getProjectService().getProjectPaths()){
341 if(ExitDialogReturnValues
.CANCEL
.equals(
342 projectNavigationDockableFrame
.checkForUnsavedChanges(projectTreePath
, projectTreePath
)
344 // ProMod termination has been canceled by user
353 * Performs the context switching mechanism.
355 private void updateView(){
356 String newNotationIdentifier
= ModelerSession
.getProjectService().getSelectedProjectNotationIndentifier();
357 final String oldNotationIdentifier
= model
.getSelectedNotation();
359 //if no diagram is selected, use default modeler view
360 if(newNotationIdentifier
== null){
361 newNotationIdentifier
= ModelerModel
.MODELER_IDENTIFIER
;
364 updateProjectDiagram(false); // order of over method invocation with respect to possible automatic sync. mechanisms
365 updateWorkspaceComponent(oldNotationIdentifier
, false);
367 if(!newNotationIdentifier
.equals(oldNotationIdentifier
)){
368 updateModelerView(newNotationIdentifier
);
369 ModelerSession
.getActionControlService().updateActionsVisibility(newNotationIdentifier
);
370 updateMainMenusVisibility(newNotationIdentifier
);
371 updateDockableFramesVisibility(newNotationIdentifier
, oldNotationIdentifier
);
374 updateWorkspaceComponent(newNotationIdentifier
, true); // order of over method invocation with respect to possible automatic sync. mechanisms
375 updateProjectDiagram(true);
377 model
.setSelectedNotation(newNotationIdentifier
);
381 * Updates the project diagram.
383 * @param update if true, update will be performed, otherwise over will be performed
385 private void updateProjectDiagram(final boolean update
) {
386 if(ModelerSession
.getProjectService().getSelectedDiagram() != null){
388 ModelerSession
.getProjectService().getSelectedDiagram().getDiagramModel().update();
390 ModelerSession
.getProjectService().getSelectedDiagram().getDiagramModel().over();
396 * Updates the main menu items visibility.
398 * @param newNotationIdentifier is the identifier of active notation
400 private void updateMainMenusVisibility(final String newNotationIdentifier
) {
401 final JMenuBar menuBar
= getJMenuBar();
405 for(int i
= 0; i
< menuBar
.getMenuCount(); i
++){
406 final JMenuItem menuItem
= menuBar
.getMenu(i
);
407 boolean isVisible
= updateMenuItemVisibility(menuItem
, newNotationIdentifier
);
410 menuItem
.setEnabled(true);
412 menuItem
.setEnabled(false);
420 * Recursively goes through the menu structure and ensures that only items related to the currently selected notation
423 * @param parentMenuItem is the menu where the recursion begins
424 * @param newNotationIdentifier is the identifier of selected notation
426 * @return true if the parentMenuItem is supposed to be disabled, false otherwise
428 private boolean updateMenuItemVisibility(final JMenuItem parentMenuItem
, final String newNotationIdentifier
) {
429 boolean isEnabled
= false;
431 parentMenuItem
.setVisible(true); // always start with all items visible
433 if(parentMenuItem
instanceof JMenu
){
435 final JMenu menu
= (JMenu
) parentMenuItem
;
436 for(int i
= 0; i
< menu
.getItemCount(); i
++){
437 final JMenuItem menuItem
= menu
.getItem(i
);
439 if(menuItem
!= null){ //separator is returned like a null item
440 isEnabled
|= updateMenuItemVisibility(menuItem
, newNotationIdentifier
);
444 menu
.setEnabled(isEnabled
);
448 // menu item, hide relatives (menu items with the same text)
449 final boolean menuItemEnabled
= parentMenuItem
.isEnabled();
451 if(parentMenuItem
instanceof ModelerMenuItem
&& !menuItemEnabled
){
452 final ModelerMenuItem menuItem
= (ModelerMenuItem
) parentMenuItem
;
454 final List
<ModelerMenuItem
> relatives
= menuItem
.getListOfRelatives();
455 if(relatives
!= null){
456 if(relatives
.isEmpty()){
457 parentMenuItem
.setVisible(false);
459 if(isAnotherRelativeVisible(relatives
)){
460 parentMenuItem
.setVisible(false);
466 return menuItemEnabled
;
470 * Checks the list of relatives (relative are items in the menu under the same root with the same text on it) and
471 * decides whether this any of relative items is visible or not.
473 * @param relatives is the list of relative items
474 * @return true if any another relative item is visible, false otherwise
476 private boolean isAnotherRelativeVisible(final List
<ModelerMenuItem
> relatives
) {
477 if(relatives
== null || relatives
.isEmpty()){
481 for(ModelerMenuItem modelerMenuItem
: relatives
){
482 if(modelerMenuItem
instanceof JMenuItem
){
483 final JMenuItem menuItem
= (JMenuItem
) modelerMenuItem
;
484 if(menuItem
.isEnabled()){
494 * Performs the context switch.
496 * @param newNotationIdentifier is the identifier of active notation.
498 private void updateModelerView(final String newNotationIdentifier
) {
499 if(newNotationIdentifier
!= null){
500 cardLayoutLeftSidePane
.show(leftSidePane
, newNotationIdentifier
);
501 cardLayoutRightSidePane
.show(rightSidePane
, newNotationIdentifier
);
502 cardLayoutBottomSidePane
.show(bottomSidePane
, newNotationIdentifier
);
503 cardLayoutTopSidePane
.show(topSidePane
, newNotationIdentifier
);
505 cardLayoutWorkspacePane
.show(workspacePane
, newNotationIdentifier
);
507 cardLayoutToolBar
.show(toolBarPane
, newNotationIdentifier
);
509 cardLayoutStatusBar
.show(statusBarPane
, newNotationIdentifier
);
512 LOG
.error("Modeler view update error. Notation name cannot be null.");
517 * Performs the update() or ever() methods on workspace component if this component implements the
518 * UpdatableWorkspaceComponent interface.
520 * @param notationIdentifier is the identifier of the notation to which the workspace component belongs
521 * @param update is true when update() method is supposed to be invoked, the over() methods is invoked otherwise
523 private void updateWorkspaceComponent(final String notationIdentifier
, final boolean update
) {
524 if(notationIdentifier
!= null && !ModelerModel
.MODELER_IDENTIFIER
.equals(notationIdentifier
)){
525 final JComponent workspaceComponent
;
527 workspaceComponent
= model
.getNotationGuiHolder(notationIdentifier
).getNotationWorkspace().getWorkspaceComponentSingleton();
529 if(workspaceComponent
instanceof UpdatableWorkspaceComponent
){
530 final UpdatableWorkspaceComponent updatableWorkspaceComponent
= (UpdatableWorkspaceComponent
)workspaceComponent
;
533 updatableWorkspaceComponent
.update();
535 ModelerSession
.clearFrameTitleText();
536 updatableWorkspaceComponent
.over();
540 } catch (NullPointerException exception
){
541 LOG
.error("Not workspace provided, notationIdentifier: " + notationIdentifier
);
547 * Updates the dockable frame visibility.
549 * @param newNotationIdentifier is the identifier of active notation
550 * @param oldNotationIdentifier is the identifier of previous notation.
552 private void updateDockableFramesVisibility(final String newNotationIdentifier
, final String oldNotationIdentifier
) {
553 if(newNotationIdentifier
== null || newNotationIdentifier
.equals(oldNotationIdentifier
)){
554 // should never happened
555 LOG
.debug("UpdateDockableFramesVisibility method has been invoked, even though newNotationIdentifier is the same as oldNotationIdentifier.");
558 if(!ModelerModel
.MODELER_IDENTIFIER
.equals(oldNotationIdentifier
) && oldNotationIdentifier
!= null){
559 model
.getNotationGuiHolder(oldNotationIdentifier
).unable();
562 if(!ModelerModel
.MODELER_IDENTIFIER
.equals(newNotationIdentifier
)){
563 model
.getNotationGuiHolder(newNotationIdentifier
).enable();
568 * Initialize main menu.
570 private void initMainMenu() {
571 final MenuControlService mainMenuControlService
;
573 mainMenuControlService
= (MenuControlService
) ModelerSession
.getMenuService();
574 } catch(ClassCastException exception
){
575 LOG
.error("Main menu initialization not possible.", exception
);
579 setJMenuBar(mainMenuControlService
.getMenuBar());
581 // insert common menu items
583 ModelerSession
.getMenuService().insertMainMenuItem(ModelerSession
.getActionService().getAction(
584 ModelerModel
.MODELER_IDENTIFIER
, ACTION_EXIT
),
585 new MenuItemPosition(FILE_LABEL
), MenuService
.MenuSeparator
.BEFORE
589 ModelerSession
.getMenuService().insertMainMenuItem(ModelerSession
.getActionService().getAction(
590 ModelerModel
.MODELER_IDENTIFIER
, ACTION_NEW_PROJECT_DIALOG
),
591 new MenuItemPosition(PROJECT_LABEL
, MenuItemPosition
.PlacementStyle
.FIRST
)
594 ModelerSession
.getMenuService().insertMainMenuItem(ModelerSession
.getActionService().getAction(
595 ModelerModel
.MODELER_IDENTIFIER
, ACTION_PROJECT_SAVE
),
596 new MenuItemPosition(PROJECT_LABEL
), MenuService
.MenuSeparator
.BEFORE
598 ModelerSession
.getMenuService().insertMainMenuItem(ModelerSession
.getActionService().getAction(
599 ModelerModel
.MODELER_IDENTIFIER
, ACTION_PROJECT_LOAD
),
600 new MenuItemPosition(PROJECT_LABEL
)
604 ModelerSession
.getMenuService().insertMainMenuItem(ModelerSession
.getActionService().getAction(
605 ModelerModel
.MODELER_IDENTIFIER
, ACTION_SETTINGS_SHOW
),
606 new MenuItemPosition(EDIT_LABEL
)
610 ModelerSession
.getMenuService().insertMainMenuItem(ModelerSession
.getActionService().getAction(
611 ModelerModel
.MODELER_IDENTIFIER
, ACTION_PROJECT_NAVIG_SHOW
),
612 new MenuItemPosition(WINDOW_LABEL
), true
614 ModelerSession
.getMenuService().insertMainMenuItem(ModelerSession
.getActionService().getAction(
615 ModelerModel
.MODELER_IDENTIFIER
, ACTION_PLUGINS_OVERVIEW_SHOW
),
616 new MenuItemPosition(WINDOW_LABEL
)
621 * Initialize the event handling.
623 private void initEventHandling(){
624 ModelerSession
.getUserService().getUserValueModel().addValueChangeListener(
625 new PropertyChangeListener(){
626 public void propertyChange(PropertyChangeEvent evt
) {
627 loggedUserLabel
.setText(ModelerSession
.getUserService().getUser());
632 switchUserButton
.addActionListener(new ActionListener(){
633 public void actionPerformed(ActionEvent e
) {
634 ModelerSession
.getActionService().getAction(ModelerModel
.MODELER_IDENTIFIER
, ACTION_SWITH_USER
).actionPerformed(null);
638 ModelerSession
.getProjectService().getSelectedItem().addValueChangeListener(new PropertyChangeListener(){
639 public void propertyChange(PropertyChangeEvent evt
) {
644 // listener of window's closing button (cross button)
645 this.addWindowListener(new WindowAdapter(){
647 public void windowClosing(WindowEvent e
){
649 ModelerSession
.getActionService().getAction(ModelerModel
.MODELER_IDENTIFIER
, ACTION_EXIT
).actionPerformed(null);
653 projectNavigatorButton
.addActionListener(ModelerSession
.getActionService().getAction(ModelerModel
.MODELER_IDENTIFIER
, ACTION_PROJECT_NAVIG_SHOW
));
657 * Installs the plugins into the gui.
659 public void deployNotationSpecificPlugIns( ){
660 for(final String notationIdentifier
: ModelerSession
.getNotationService().getNotationsIdentifiers()){
661 final NotationSpecificPlugins notationSpecificPlugins
= ModelerSession
.getNotationService().getNotationSpecificPlugins(notationIdentifier
);
663 installNotationsAndModules(notationSpecificPlugins
);
668 * Shows the application frame window.
670 public void showFrame(){
671 // update view to initial state
674 dockingManager
.loadLayoutData();
676 dockingManager
.setFrameUnavailable(projectNavigationDockableFrame
.getName());
678 for( final NotationGuiHolder notationGuiHolder
: model
.getNotationGuiHolders() ){
679 for( final DockableFrameWrapper wrapper
: notationGuiHolder
.getAllDockableFrameFacades() ){
680 dockingManager
.setFrameAvailable(wrapper
.getDockableFrame().getName());
681 dockingManager
.setFrameUnavailable(wrapper
.getDockableFrame().getName());
687 projectNavigatorButton
.doClick();
693 * Decides whether there were any errors during plugins loading and if there were any, then show a visual report
694 * about these errors.
696 private void showLoadingErrors(){
697 final List
<PluginLoadErrors
> errors
= ModelerSession
.getNotationService().getErrors();
700 LOG
.error("Nullary loading error info.");
704 if(!errors
.isEmpty()){
705 new LoadErrorsDialog(errors
);
710 * Installs the notations ad modules.
712 * @param notationSpecificPlugins is the holder of notations and it's modules
714 private void installNotationsAndModules(final NotationSpecificPlugins notationSpecificPlugins
){
715 final NotationGuiHolder notationGuiHolder
= new NotationGuiHolder(
716 notationSpecificPlugins
.getNotation().getIdentifier(),
720 model
.addNotationGuiHolder(notationGuiHolder
);
722 final Collection
<DockableFrameData
> dockableFramesData
= notationSpecificPlugins
.getDockableFramesData();
724 if( dockableFramesData
!= null ){
725 for( final DockableFrameData item
: dockableFramesData
){
727 final DockableFrame frame
= createDockableFrame(
728 item
.getDockableFrameComponent(),
729 item
.getInitialPosition(),
730 item
.getDockableFrameTitle(),
731 item
.isMaximizable(),
732 item
.getInitialState());
734 final JMenu menu
= ModelerSession
.getComponentFactoryService().createMenu(
735 ModelerSession
.getCommonResourceBundle().getString("modeler.dockable.frame.move"));
737 final JMenuItem moveToLeftMenuItem
= ModelerSession
.getComponentFactoryService().createMenuItem(
738 ModelerSession
.getCommonResourceBundle().getString("modeler.dockable.frame.move.left"));
739 moveToLeftMenuItem
.addActionListener(new MenuItemMoveListener(notationGuiHolder
, frame
, NotationGuiHolder
.Position
.LEFT
));
741 final JMenuItem moveToRightMenuItem
= ModelerSession
.getComponentFactoryService().createMenuItem(
742 ModelerSession
.getCommonResourceBundle().getString("modeler.dockable.frame.move.right"));
743 moveToRightMenuItem
.addActionListener(new MenuItemMoveListener(notationGuiHolder
, frame
, NotationGuiHolder
.Position
.RIGHT
));
745 final JMenuItem moveToTopMenuItem
= ModelerSession
.getComponentFactoryService().createMenuItem(
746 ModelerSession
.getCommonResourceBundle().getString("modeler.dockable.frame.move.top"));
747 moveToTopMenuItem
.addActionListener(new MenuItemMoveListener(notationGuiHolder
, frame
, NotationGuiHolder
.Position
.TOP
));
749 final JMenuItem moveToBottomMenuItem
= ModelerSession
.getComponentFactoryService().createMenuItem(
750 ModelerSession
.getCommonResourceBundle().getString("modeler.dockable.frame.move.bottom"));
751 moveToBottomMenuItem
.addActionListener(new MenuItemMoveListener(notationGuiHolder
, frame
, NotationGuiHolder
.Position
.BOTTOM
));
753 final JPopupMenu popupMenu
= ModelerSession
.getComponentFactoryService().createPopupMenu();
755 if(item
.getAllowedDockableFramePositions() != null){
756 boolean insertMenu
= false;
758 for(final NotationGuiHolder
.Position position
: NotationGuiHolder
.Position
.values()){
759 if(item
.getAllowedDockableFramePositions().contains(position
)){
762 menu
.add(moveToLeftMenuItem
);
766 menu
.add(moveToRightMenuItem
);
770 menu
.add(moveToTopMenuItem
);
774 menu
.add(moveToBottomMenuItem
);
778 LOG
.error("No such a choice for allowed position of dockable frame.");
788 final JideButton button
;
789 switch (item
.getInitialPosition()){
792 button
= ModelerSession
.getComponentFactoryService().createJideButton(item
.getDockableFrameTitle(),
793 item
.getButtonIcon(),
799 button
= ModelerSession
.getComponentFactoryService().createJideButton(item
.getDockableFrameTitle(),
800 item
.getButtonIcon(),
804 button
.addActionListener(new SideButtonListener(notationGuiHolder
, dockingManager
, frame
));
805 button
.addMouseListener(new ButtonPopupAdapter(button
, popupMenu
));
807 frame
.addDockableFrameListener(new DockFrameListener(notationGuiHolder
, dockingManager
));
809 notationGuiHolder
.addFrameWithButton(
815 moveToBottomMenuItem
,
817 item
.getInitialPosition(),
818 item
.getInitialState());
822 final String notationIdentifier
= notationSpecificPlugins
.getNotation().getIdentifier();
824 // insert notation workspace
825 if( notationSpecificPlugins
.getNotation().getNotationWorkspaceData() != null ){
826 notationGuiHolder
.setNotationWorkspace(notationSpecificPlugins
.getNotation().getNotationWorkspaceData());
828 notationGuiHolder
.setNotationWorkspace(new NotationWorkspaceDataDefault(notationIdentifier
));
830 LOG
.error("No workspace definition provided. Default panel has been inserted instead. " +
831 "Notation identifier: " + notationIdentifier
);
834 // insert notation specific tool bar
835 addToolBarPane(notationIdentifier
, ModelerSession
.getToolBarControlService().getCommandBar(notationIdentifier
));
837 // insert notation specific status bar
838 addStatusBar(notationIdentifier
, ModelerSession
.getStatusBarControlService().getStatusBar(notationIdentifier
));
840 deployWorkspace(notationIdentifier
);
841 deployButtons(notationIdentifier
);
845 * Installs the workspace component.
847 * @param notationIdentifier is the identifier of associated notation
849 private void deployWorkspace( final String notationIdentifier
){
850 final NotationWorkspaceData notationWorkspaceData
= model
.getNotationGuiHolder(notationIdentifier
).getNotationWorkspace();
852 final JComponent workspaceComponent
= notationWorkspaceData
.getWorkspaceComponentSingleton();
854 if(!(workspaceComponent
instanceof UpdatableWorkspaceComponent
)){
855 LOG
.warn("The obtained workspace component for notation (" + notationIdentifier
+ ") doesn't implement the UpdatableWorkspaceComponent inytercae. " +
856 "Any methods of this interface won't be never invoked for this workspace component.");
859 addMainWindowPane(notationIdentifier
, workspaceComponent
);
865 * @param notationIdentifier is the notation identifier.
867 private void deployButtons( final String notationIdentifier
){
868 final NotationGuiHolder spec
= model
.getNotationGuiHolder(notationIdentifier
);
870 addSidePane(notationIdentifier
, rightSidePane
, spec
.getListOfButtons(
871 NotationGuiHolder
.Position
.RIGHT
), true);
873 addSidePane(notationIdentifier
, leftSidePane
, spec
.getListOfButtons(
874 NotationGuiHolder
.Position
.LEFT
), true);
876 addSidePane(notationIdentifier
, bottomSidePane
, spec
.getListOfButtons(
877 NotationGuiHolder
.Position
.BOTTOM
), false);
879 addSidePane(notationIdentifier
, topSidePane
, spec
.getListOfButtons(
880 NotationGuiHolder
.Position
.TOP
), false);
884 * Initializes the common settings dialog.
886 public void initSettingsDialog() {
887 LOG
.info("Initializing settings dialog.");
889 for(final Notation notation
: ModelerSession
.getNotationService().getNotations()){
890 final NotationSpecificPlugins notationSpecificPlugins
=
891 ModelerSession
.getNotationService().getNotationSpecificPlugins(notation
.getIdentifier());
893 // init notation's settings screens
894 SettingPageData settingInfo
= notationSpecificPlugins
.getNotation().getSettingPages();
895 List
<AbstractDialogPage
> pages
= new LinkedList
<AbstractDialogPage
>();
896 this.createPages(pages
, settingInfo
);
898 if(pages
.size() == 0){
899 LOG
.info("Notation " + notation
.getIdentifier() + " provides nullary setting pages list.");
902 pages
.add(0, new BasicSettingPage(notation
.getFullName()));
904 final AbstractDialogPage parentPage
= pages
.get(0);
906 installPagesParent(pages
, parentPage
);
908 model
.addSettingPages(pages
);
910 // init module's settings screens
911 for(final Module module
: notationSpecificPlugins
.getModules()){
912 settingInfo
= module
.getSettingPages();
914 this.createPages(pages
, settingInfo
);
917 installPagesParent(pages
, parentPage
);
919 model
.addSettingPages(pages
);
922 LOG
.info("Module " + module
.getIdentifier() + " provides nullary setting pages list.");
927 // init extension's settings screens
928 for(final Extension extension
: ModelerSession
.getExtensionService().getExtensions()){
929 SettingPageData settingInfo
= extension
.getSettingPages();
930 List
<AbstractDialogPage
> pages
= new LinkedList
<AbstractDialogPage
>();
931 this.createPages(pages
, settingInfo
);
934 LOG
.info("Extension " + extension
.getIdentifier() + " provides nullary setting pages list.");
935 pages
= new LinkedList
<AbstractDialogPage
>();
939 pages
.add(0, new BasicSettingPage(extension
.getName()));
941 final AbstractDialogPage parentPage
= pages
.get(0);
943 installPagesParent(pages
, parentPage
);
945 model
.addSettingPages(pages
);
949 private void createPages(List
<AbstractDialogPage
> pageList
, SettingPageData settingInfo
) {
950 SettingPage page
= new SettingPage(settingInfo
);
951 List
<SettingPageData
> children
= settingInfo
.getChildren();
952 for (SettingPageData child
: children
) {
953 this.createPages(pageList
, child
);
959 * Sets the proper parent to all settings pages. If the parent of the page is already set then nothing is changed.
961 * @param pages is the page
962 * @param parentDialogPage is the parent of the page
964 private void installPagesParent(final List
<AbstractDialogPage
> pages
, final AbstractDialogPage parentDialogPage
) {
965 if(pages
.size() > 1){
966 pages
.get(1).setParentPage(parentDialogPage
);
969 for(final AbstractDialogPage page
: pages
){
970 if(page
.getParent() == null && page
!= parentDialogPage
){
971 page
.setParentPage(parentDialogPage
);
977 * Performs dockable frame moves.
979 private class MenuItemMoveListener
implements ActionListener
{
981 private final NotationGuiHolder notationGuiHolder
;
982 private final DockableFrame dockableFrame
;
983 private final NotationGuiHolder
.Position directionOfMovement
;
985 public MenuItemMoveListener( final NotationGuiHolder notationGuiHolder
,
986 final DockableFrame correspondingFrame
,
987 final NotationGuiHolder
.Position directionOfMovement
){
988 this.notationGuiHolder
= notationGuiHolder
;
989 this.dockableFrame
= correspondingFrame
;
990 this.directionOfMovement
= directionOfMovement
;
993 public void actionPerformed( ActionEvent e
){
995 final String notationIdentifier
= notationGuiHolder
.getNotationIdentifier();
996 final String dockableFrameName
= dockableFrame
.getName();
998 NotationGuiHolder
.Position oldPosition
= notationGuiHolder
.getPosition(dockableFrameName
);
1000 notationGuiHolder
.moveButtonAndFrame(dockableFrameName
, directionOfMovement
);
1002 final JPanel oldPanel
;
1003 final CardLayout oldCardLayout
;
1005 switch (oldPosition
){
1007 oldPanel
= leftSidePane
;
1008 oldCardLayout
= cardLayoutLeftSidePane
;
1012 oldPanel
= rightSidePane
;
1013 oldCardLayout
= cardLayoutRightSidePane
;
1017 oldPanel
= topSidePane
;
1018 oldCardLayout
= cardLayoutTopSidePane
;
1022 oldPanel
= bottomSidePane
;
1023 oldCardLayout
= cardLayoutBottomSidePane
;
1029 oldCardLayout
= null;
1030 LOG
.error("No such a position for dockable frame.");
1033 addSidePane(notationIdentifier
, oldPanel
, notationGuiHolder
.getListOfButtons(oldPosition
), isVertical
);
1034 oldCardLayout
.show(oldPanel
, notationIdentifier
);
1037 final JPanel newPanel
;
1038 final NotationGuiHolder
.Position newPosition
;
1039 final CardLayout newCardLayout
;
1040 switch(directionOfMovement
){
1042 newPanel
= leftSidePane
;
1043 newPosition
= NotationGuiHolder
.Position
.LEFT
;
1045 newCardLayout
= cardLayoutLeftSidePane
;
1048 newPanel
= rightSidePane
;
1049 newPosition
= NotationGuiHolder
.Position
.RIGHT
;
1051 newCardLayout
= cardLayoutRightSidePane
;
1054 newPanel
= bottomSidePane
;
1055 newPosition
= NotationGuiHolder
.Position
.BOTTOM
;
1057 newCardLayout
= cardLayoutBottomSidePane
;
1060 newPanel
= topSidePane
;
1061 newPosition
= NotationGuiHolder
.Position
.TOP
;
1063 newCardLayout
= cardLayoutTopSidePane
;
1069 newCardLayout
= null;
1070 LOG
.error("No such a position for dockable frame.");
1073 addSidePane(notationIdentifier
, newPanel
, notationGuiHolder
.getListOfButtons(newPosition
), isVertical
);
1074 newCardLayout
.show(newPanel
, notationIdentifier
);
1076 } catch(IllegalArgumentException exception
){
1077 LOG
.error("Illegal position or unknown frame during low level navigation movement.", exception
);