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
.BasicSettingPage
;
16 import cz
.cvut
.promod
.gui
.settings
.SettingsDialog
;
17 import cz
.cvut
.promod
.gui
.support
.utils
.DockableFrameWrapper
;
18 import cz
.cvut
.promod
.gui
.support
.utils
.NotationGuiHolder
;
19 import cz
.cvut
.promod
.plugin
.extension
.Extension
;
20 import cz
.cvut
.promod
.plugin
.notationSpecificPlugIn
.DockableFrameData
;
21 import cz
.cvut
.promod
.plugin
.notationSpecificPlugIn
.module
.Module
;
22 import cz
.cvut
.promod
.plugin
.notationSpecificPlugIn
.notation
.Notation
;
23 import cz
.cvut
.promod
.plugin
.notationSpecificPlugIn
.notation
.NotationWorkspaceData
;
24 import cz
.cvut
.promod
.plugin
.notationSpecificPlugIn
.notation
.utils
.NotationWorkspaceDataDefault
;
25 import cz
.cvut
.promod
.plugin
.notationSpecificPlugIn
.notation
.workspace
.UpdatableWorkspaceComponent
;
26 import cz
.cvut
.promod
.services
.ModelerSession
;
27 import cz
.cvut
.promod
.services
.actionService
.actionUtils
.ProModAction
;
28 import cz
.cvut
.promod
.services
.menuService
.MenuControlService
;
29 import cz
.cvut
.promod
.services
.menuService
.MenuService
;
30 import cz
.cvut
.promod
.services
.menuService
.utils
.ModelerMenuItem
;
31 import cz
.cvut
.promod
.services
.menuService
.utils
.MenuItemPosition
;
32 import cz
.cvut
.promod
.services
.pluginLoaderService
.utils
.NotationSpecificPlugins
;
33 import cz
.cvut
.promod
.services
.pluginLoaderService
.utils
.PluginLoadErrors
;
34 import cz
.cvut
.promod
.resources
.Resources
;
35 import org
.apache
.log4j
.Logger
;
38 import javax
.swing
.tree
.TreePath
;
40 import java
.awt
.event
.*;
41 import java
.beans
.PropertyChangeEvent
;
42 import java
.beans
.PropertyChangeListener
;
43 import java
.util
.Collection
;
44 import java
.util
.LinkedList
;
45 import java
.util
.List
;
48 * ProMod, master thesis project
49 * User: Petr Zverina, petr.zverina@gmail.com
50 * Date: 16:09:42, 10.10.2009
54 * Basic class of the host application.
56 public class Modeler
extends ModelerView
{
58 private static final Logger LOG
= Logger
.getLogger(Modeler
.class);
60 public static final String ACTION_NEW_PROJECT_DIALOG
= "modeler.action.new.project";
61 public static final String ACTION_EXIT
= "modeler.action.exit";
62 public static final String ACTION_PROJECT_LOAD
= "modeler.action.project.load";
63 public static final String ACTION_PROJECT_SAVE
= "modeler.action.project.save";
64 public static final String ACTION_SWITH_USER
= "modeler.action.switch.user";
65 public static final String ACTION_PROJECT_NAVIG_SHOW
= "modeler.action.navigation";
66 public static final String ACTION_SETTINGS_SHOW
= "modeler.action.settings";
67 public static final String ACTION_PLUGINS_OVERVIEW_SHOW
= "modeler.action.plugins.overview";
69 public static final String LOAD_SYNC_TITLE_ERROR_LABEL
=
70 ModelerSession
.getCommonResourceBundle().getString("modeler.action.project.load.error.sync.title");
71 public static final String LOAD_SYNC_MESSAGE_ERROR_LABEL
=
72 ModelerSession
.getCommonResourceBundle().getString("modeler.action.project.load.error.sync.message");
73 public static final String USER_CHANGE_DIALOG_TITLE_LABEL
=
74 ModelerSession
.getCommonResourceBundle().getString("modeler.user.service");
75 public static final String USER_CHANGE_DIALOG_LABEL
=
76 ModelerSession
.getCommonResourceBundle().getString("modeler.user.name");
77 public static final String OK_LABEL
=
78 ModelerSession
.getCommonResourceBundle().getString("modeler.ok");
79 public static final String YES_LABEL
=
80 ModelerSession
.getCommonResourceBundle().getString("modeler.yes");
81 public static final String NO_LABEL
=
82 ModelerSession
.getCommonResourceBundle().getString("modeler.no");
83 public static final String CANCEL_LABEL
=
84 ModelerSession
.getCommonResourceBundle().getString("modeler.cancel");
85 public static final String USER_CHANGE_DIALOG_INVALID_LABEL
=
86 ModelerSession
.getCommonResourceBundle().getString("modeler.user.invalid.name");
87 public static final String SAVE_ALL_LABEL
=
88 ModelerSession
.getCommonResourceBundle().getString("modeler.exit.save.all");
89 public static final String SKIP_ALL_LABEL
=
90 ModelerSession
.getCommonResourceBundle().getString("modeler.exit.skip.all");
91 public static final String PROMOD_EXIT_LABEL
=
92 ModelerSession
.getCommonResourceBundle().getString("modeler.exit");
93 public static final String UNSAVED_CHANGE_LABEL
=
94 ModelerSession
.getCommonResourceBundle().getString("modeler.exit.diagram.unsaved.change");
95 public static final String SETTINGS_LABEL
=
96 ModelerSession
.getCommonResourceBundle().getString("modeler.settings");
97 public static final String FILE_LABEL
=
98 ModelerSession
.getCommonResourceBundle().getString("modeler.menu.file");
99 public static final String PROJECT_LABEL
=
100 ModelerSession
.getCommonResourceBundle().getString("modeler.menu.project");
101 public static final String EDIT_LABEL
=
102 ModelerSession
.getCommonResourceBundle().getString("modeler.menu.edit");
103 public static final String WINDOW_LABEL
=
104 ModelerSession
.getCommonResourceBundle().getString("modeler.menu.window");
105 public static final String PLUGINS_OVERVIEW_LABEL
=
106 ModelerSession
.getCommonResourceBundle().getString("modeler.plugins.overview");
108 public static final Object
[] EXIT_DIALOG_OPTIONS
= {
109 YES_LABEL
,NO_LABEL
, SAVE_ALL_LABEL
, SKIP_ALL_LABEL
, CANCEL_LABEL
};
111 public static enum ExitDialogReturnValues
{CONTINUE
, STOP
, CANCEL
}
113 private final ModelerModel model
;
117 ModelerSession
.setFrame(this);
119 this.model
= new ModelerModel();
125 initProjectNavigation();
131 * Initialize actions that belong to the 'virtual' "modeler" notation.
133 private void initActions(){
134 ModelerSession
.getActionService().registerAction(
135 ModelerModel
.MODELER_IDENTIFIER
,
136 ACTION_PLUGINS_OVERVIEW_SHOW
,
137 new ProModAction(PLUGINS_OVERVIEW_LABEL
, null, KeyStroke
.getKeyStroke(
138 KeyEvent
.VK_O
, java
.awt
.event
.InputEvent
.SHIFT_MASK
| java
.awt
.event
.InputEvent
.CTRL_MASK
)){
139 public void actionPerformed(ActionEvent event
) {
140 new PluginsOverviewDialogDialog();
145 ModelerSession
.getActionService().registerAction(
146 ModelerModel
.MODELER_IDENTIFIER
,
147 ACTION_PLUGINS_OVERVIEW_SHOW
,
148 new ProModAction(PLUGINS_OVERVIEW_LABEL
, null, KeyStroke
.getKeyStroke(
149 KeyEvent
.VK_O
, java
.awt
.event
.InputEvent
.SHIFT_MASK
| java
.awt
.event
.InputEvent
.CTRL_MASK
)){
150 public void actionPerformed(ActionEvent event
) {
151 new PluginsOverviewDialogDialog();
156 ModelerSession
.getActionService().registerAction(
157 ModelerModel
.MODELER_IDENTIFIER
,
158 ACTION_SETTINGS_SHOW
,
159 new ProModAction(SETTINGS_LABEL
, null, KeyStroke
.getKeyStroke(
160 KeyEvent
.VK_S
, java
.awt
.event
.InputEvent
.ALT_MASK
| java
.awt
.event
.InputEvent
.CTRL_MASK
)){
161 public void actionPerformed(ActionEvent event
) {
162 SettingsDialog
.showOptionsDialog(model
.getSettingPagesModel());
167 ModelerSession
.getActionService().registerAction(
168 ModelerModel
.MODELER_IDENTIFIER
,
170 new ProModAction(USER_CHANGE_DIALOG_LABEL
, null, null){
171 public void actionPerformed(ActionEvent event
) {
172 new SimpleTextFieldDialog(
173 USER_CHANGE_DIALOG_TITLE_LABEL
,
174 USER_CHANGE_DIALOG_LABEL
,
178 new SimpleTextFieldDialogExecutor(){
179 public String
execute(final String text
) {
180 if(text
!= null && !text
.isEmpty()){
181 ModelerSession
.getUserService().setUser(text
);
185 return USER_CHANGE_DIALOG_INVALID_LABEL
;
188 ModelerSession
.getFrame(),
193 ModelerSession
.getActionService().registerAction(
194 ModelerModel
.MODELER_IDENTIFIER
,
195 ACTION_NEW_PROJECT_DIALOG
,
196 new ProModAction(ModelerSession
.getCommonResourceBundle().getString(
197 ACTION_NEW_PROJECT_DIALOG
),
198 Resources
.getIcon(Resources
.MODELER
+ Resources
.NEW_PROJECT_ICON
),
199 KeyStroke
.getKeyStroke(KeyEvent
.VK_N
, ActionEvent
.CTRL_MASK
)){
200 public void actionPerformed(ActionEvent event
) {
201 new NewProjectDialog();
205 ModelerSession
.getActionService().registerAction(
206 ModelerModel
.MODELER_IDENTIFIER
,
208 new ProModAction(ModelerSession
.getCommonResourceBundle().getString(ACTION_EXIT
), null, null){
209 public void actionPerformed(ActionEvent event
) {
214 ModelerSession
.getActionService().registerAction(
215 ModelerModel
.MODELER_IDENTIFIER
,
216 ACTION_PROJECT_NAVIG_SHOW
,
217 new ProModAction(ModelerSession
.getCommonResourceBundle().getString(ACTION_PROJECT_NAVIG_SHOW
), null, null){
218 public void actionPerformed(ActionEvent event
) {
219 swapProjectNavigationVisibility();
221 // update control components selection
222 putValue(Action
.SELECTED_KEY
, projectNavigationDockableFrame
.isAvailable());
223 projectNavigatorButton
.setSelected(projectNavigationDockableFrame
.isAvailable());
229 ModelerSession
.getActionService().registerAction(
230 ModelerModel
.MODELER_IDENTIFIER
,
232 new ProModAction(ModelerSession
.getCommonResourceBundle().getString(ACTION_PROJECT_SAVE
),
233 Resources
.getIcon(Resources
.MODELER
+ Resources
.SAVE_ALL_ICON
),
234 KeyStroke
.getKeyStroke(
235 KeyEvent
.VK_S
, java
.awt
.event
.InputEvent
.CTRL_MASK
)){
236 public void actionPerformed(ActionEvent event
) {
237 LOG
.debug("Action save invoked.");
239 final TreePath projectTreePath
= ModelerSession
.getProjectService().getSelectedProjectPath();
241 if(projectTreePath
== null){
244 final boolean syncResult
= ModelerSession
.getProjectControlService().synchronize(
245 projectTreePath
, true, true, false, false);
248 JOptionPane
.showMessageDialog(
249 ModelerSession
.getFrame(),
250 LOAD_SYNC_MESSAGE_ERROR_LABEL
,
251 LOAD_SYNC_TITLE_ERROR_LABEL
,
252 JOptionPane
.ERROR_MESSAGE
);
258 ModelerSession
.getActionService().registerAction(
259 ModelerModel
.MODELER_IDENTIFIER
,
261 new LoadDialogAction(ModelerSession
.getCommonResourceBundle().getString(
262 ACTION_PROJECT_LOAD
),
263 Resources
.getIcon(Resources
.MODELER
+ Resources
.OPEN_ICON
),
264 KeyStroke
.getKeyStroke(KeyEvent
.VK_O
, ActionEvent
.CTRL_MASK
)));
268 * Changed the project navigation visibility.
270 private void swapProjectNavigationVisibility(){
271 if( projectNavigationDockableFrame
.isAvailable() ){
272 dockingManager
.setFrameUnavailable(projectNavigationDockableFrame
.getName());
274 final String currentNotation
= ModelerSession
.getProjectService().getSelectedProjectNotationIndentifier();
276 final NotationGuiHolder specification
= model
.getNotationGuiHolder(currentNotation
);
278 if( specification
!= null ){
279 final List
<DockableFrame
> visibleDockableFrames
= new LinkedList
<DockableFrame
>();
281 for( final DockableFrame dockableFrame
: specification
.getListOfFrames(NotationGuiHolder
.Position
.LEFT
) ){
282 if( dockableFrame
.isAvailable() ){
283 visibleDockableFrames
.add((dockableFrame
));
284 specification
.getButton(dockableFrame
.getName(), NotationGuiHolder
.Position
.LEFT
).doClick();
288 dockingManager
.setFrameAvailable(projectNavigationDockableFrame
.getName());
290 for( final DockableFrame dockableFrame
: visibleDockableFrames
){
291 specification
.getButton(dockableFrame
.getName(), NotationGuiHolder
.Position
.LEFT
).doClick();
294 dockingManager
.setFrameAvailable(projectNavigationDockableFrame
.getName());
300 * Performs the terminating sequence.
302 private void modelerExit() {
303 LOG
.info("Modeler is shutting down.");
305 if(!checkForUnsavedChanges()){
306 LOG
.info("ProMod shut-down has been canceled by user");
312 // finishing notations & modules
313 for(final String notationIdentifier
: ModelerSession
.getNotationService().getNotationsIdentifiers()){
314 final NotationSpecificPlugins notationSpecificPlugins
= ModelerSession
.getNotationService().getNotationSpecificPlugins(notationIdentifier
);
316 notationSpecificPlugins
.getNotation().finish();
318 for(final Module module
: notationSpecificPlugins
.getModules()){
323 // finishing extensions
324 for(Extension extension
: ModelerSession
.getExtensionService().getExtensions()){
333 * Looks for unsaved changes in projects.
335 * @return true if ProMod is supposed to be terminated, false if the ProMod termination has been canceled
337 private boolean checkForUnsavedChanges() {
338 for(final TreePath projectTreePath
: ModelerSession
.getProjectService().getProjectPaths()){
339 if(ExitDialogReturnValues
.CANCEL
.equals(
340 projectNavigationDockableFrame
.checkForUnsavedChanges(projectTreePath
, projectTreePath
)
342 // ProMod termination has been canceled by user
351 * Performs the context switching mechanism.
353 private void updateView(){
354 String newNotationIdentifier
= ModelerSession
.getProjectService().getSelectedProjectNotationIndentifier();
355 final String oldNotationIdentifier
= model
.getSelectedNotation();
357 //if no diagram is selected, use default modeler view
358 if(newNotationIdentifier
== null){
359 newNotationIdentifier
= ModelerModel
.MODELER_IDENTIFIER
;
362 updateProjectDiagram(false); // order of over method invocation with respect to possible automatic sync. mechanisms
363 updateWorkspaceComponent(oldNotationIdentifier
, false);
365 if(!newNotationIdentifier
.equals(oldNotationIdentifier
)){
366 updateModelerView(newNotationIdentifier
);
367 ModelerSession
.getActionControlService().updateActionsVisibility(newNotationIdentifier
);
368 updateMainMenusVisibility(newNotationIdentifier
);
369 updateDockableFramesVisibility(newNotationIdentifier
, oldNotationIdentifier
);
372 updateWorkspaceComponent(newNotationIdentifier
, true); // order of over method invocation with respect to possible automatic sync. mechanisms
373 updateProjectDiagram(true);
375 model
.setSelectedNotation(newNotationIdentifier
);
379 * Updates the project diagram.
381 * @param update if true, update will be performed, otherwise over will be performed
383 private void updateProjectDiagram(final boolean update
) {
384 if(ModelerSession
.getProjectService().getSelectedDiagram() != null){
386 ModelerSession
.getProjectService().getSelectedDiagram().getDiagramModel().update();
388 ModelerSession
.getProjectService().getSelectedDiagram().getDiagramModel().over();
394 * Updates the main menu items visibility.
396 * @param newNotationIdentifier is the identifier of active notation
398 private void updateMainMenusVisibility(final String newNotationIdentifier
) {
399 final JMenuBar menuBar
= getJMenuBar();
403 for(int i
= 0; i
< menuBar
.getMenuCount(); i
++){
404 final JMenuItem menuItem
= menuBar
.getMenu(i
);
405 boolean isVisible
= updateMenuItemVisibility(menuItem
, newNotationIdentifier
);
408 menuItem
.setEnabled(true);
410 menuItem
.setEnabled(false);
418 * Recursively goes through the menu structure and ensures that only items related to the currently selected notation
421 * @param parentMenuItem is the menu where the recursion begins
422 * @param newNotationIdentifier is the identifier of selected notation
424 * @return true if the parentMenuItem is supposed to be disabled, false otherwise
426 private boolean updateMenuItemVisibility(final JMenuItem parentMenuItem
, final String newNotationIdentifier
) {
427 boolean isEnabled
= false;
429 parentMenuItem
.setVisible(true); // always start with all items visible
431 if(parentMenuItem
instanceof JMenu
){
433 final JMenu menu
= (JMenu
) parentMenuItem
;
434 for(int i
= 0; i
< menu
.getItemCount(); i
++){
435 final JMenuItem menuItem
= menu
.getItem(i
);
437 if(menuItem
!= null){ //separator is returned like a null item
438 isEnabled
|= updateMenuItemVisibility(menuItem
, newNotationIdentifier
);
442 menu
.setEnabled(isEnabled
);
446 // menu item, hide relatives (menu items with the same text)
447 final boolean menuItemEnabled
= parentMenuItem
.isEnabled();
449 if(parentMenuItem
instanceof ModelerMenuItem
&& !menuItemEnabled
){
450 final ModelerMenuItem menuItem
= (ModelerMenuItem
) parentMenuItem
;
452 final List
<ModelerMenuItem
> relatives
= menuItem
.getListOfRelatives();
453 if(relatives
!= null){
454 if(relatives
.isEmpty()){
455 parentMenuItem
.setVisible(false);
457 if(isAnotherRelativeVisible(relatives
)){
458 parentMenuItem
.setVisible(false);
464 return menuItemEnabled
;
468 * Checks the list of relatives (relative are items in the menu under the same root with the same text on it) and
469 * decides whether this any of relative items is visible or not.
471 * @param relatives is the list of relative items
472 * @return true if any another relative item is visible, false otherwise
474 private boolean isAnotherRelativeVisible(final List
<ModelerMenuItem
> relatives
) {
475 if(relatives
== null || relatives
.isEmpty()){
479 for(ModelerMenuItem modelerMenuItem
: relatives
){
480 if(modelerMenuItem
instanceof JMenuItem
){
481 final JMenuItem menuItem
= (JMenuItem
) modelerMenuItem
;
482 if(menuItem
.isEnabled()){
492 * Performs the context switch.
494 * @param newNotationIdentifier is the identifier of active notation.
496 private void updateModelerView(final String newNotationIdentifier
) {
497 if(newNotationIdentifier
!= null){
498 cardLayoutLeftSidePane
.show(leftSidePane
, newNotationIdentifier
);
499 cardLayoutRightSidePane
.show(rightSidePane
, newNotationIdentifier
);
500 cardLayoutBottomSidePane
.show(bottomSidePane
, newNotationIdentifier
);
501 cardLayoutTopSidePane
.show(topSidePane
, newNotationIdentifier
);
503 cardLayoutWorkspacePane
.show(workspacePane
, newNotationIdentifier
);
505 cardLayoutToolBar
.show(toolBarPane
, newNotationIdentifier
);
507 cardLayoutStatusBar
.show(statusBarPane
, newNotationIdentifier
);
510 LOG
.error("Modeler view update error. Notation name cannot be null.");
515 * Performs the update() or ever() methods on workspace component if this component implements the
516 * UpdatableWorkspaceComponent interface.
518 * @param notationIdentifier is the identifier of the notation to which the workspace component belongs
519 * @param update is true when update() method is supposed to be invoked, the over() methods is invoked otherwise
521 private void updateWorkspaceComponent(final String notationIdentifier
, final boolean update
) {
522 if(notationIdentifier
!= null && !ModelerModel
.MODELER_IDENTIFIER
.equals(notationIdentifier
)){
523 final JComponent workspaceComponent
;
525 workspaceComponent
= model
.getNotationGuiHolder(notationIdentifier
).getNotationWorkspace().getWorkspaceComponentSingleton();
527 if(workspaceComponent
instanceof UpdatableWorkspaceComponent
){
528 final UpdatableWorkspaceComponent updatableWorkspaceComponent
= (UpdatableWorkspaceComponent
)workspaceComponent
;
531 updatableWorkspaceComponent
.update();
533 ModelerSession
.clearFrameTitleText();
534 updatableWorkspaceComponent
.over();
538 } catch (NullPointerException exception
){
539 LOG
.error("Not workspace provided, notationIdentifier: " + notationIdentifier
);
545 * Updates the dockable frame visibility.
547 * @param newNotationIdentifier is the identifier of active notation
548 * @param oldNotationIdentifier is the identifier of previous notation.
550 private void updateDockableFramesVisibility(final String newNotationIdentifier
, final String oldNotationIdentifier
) {
551 if(newNotationIdentifier
== null || newNotationIdentifier
.equals(oldNotationIdentifier
)){
552 // should never happened
553 LOG
.debug("UpdateDockableFramesVisibility method has been invoked, even though newNotationIdentifier is the same as oldNotationIdentifier.");
556 if(!ModelerModel
.MODELER_IDENTIFIER
.equals(oldNotationIdentifier
) && oldNotationIdentifier
!= null){
557 model
.getNotationGuiHolder(oldNotationIdentifier
).unable();
560 if(!ModelerModel
.MODELER_IDENTIFIER
.equals(newNotationIdentifier
)){
561 model
.getNotationGuiHolder(newNotationIdentifier
).enable();
566 * Initialize main menu.
568 private void initMainMenu() {
569 final MenuControlService mainMenuControlService
;
571 mainMenuControlService
= (MenuControlService
) ModelerSession
.getMenuService();
572 } catch(ClassCastException exception
){
573 LOG
.error("Main menu initialization not possible.", exception
);
577 setJMenuBar(mainMenuControlService
.getMenuBar());
579 // insert common menu items
581 ModelerSession
.getMenuService().insertMainMenuItem(ModelerSession
.getActionService().getAction(
582 ModelerModel
.MODELER_IDENTIFIER
, ACTION_EXIT
),
583 new MenuItemPosition(FILE_LABEL
), MenuService
.MenuSeparator
.BEFORE
587 ModelerSession
.getMenuService().insertMainMenuItem(ModelerSession
.getActionService().getAction(
588 ModelerModel
.MODELER_IDENTIFIER
, ACTION_NEW_PROJECT_DIALOG
),
589 new MenuItemPosition(PROJECT_LABEL
, MenuItemPosition
.PlacementStyle
.FIRST
)
592 ModelerSession
.getMenuService().insertMainMenuItem(ModelerSession
.getActionService().getAction(
593 ModelerModel
.MODELER_IDENTIFIER
, ACTION_PROJECT_SAVE
),
594 new MenuItemPosition(PROJECT_LABEL
), MenuService
.MenuSeparator
.BEFORE
596 ModelerSession
.getMenuService().insertMainMenuItem(ModelerSession
.getActionService().getAction(
597 ModelerModel
.MODELER_IDENTIFIER
, ACTION_PROJECT_LOAD
),
598 new MenuItemPosition(PROJECT_LABEL
)
602 ModelerSession
.getMenuService().insertMainMenuItem(ModelerSession
.getActionService().getAction(
603 ModelerModel
.MODELER_IDENTIFIER
, ACTION_SETTINGS_SHOW
),
604 new MenuItemPosition(EDIT_LABEL
)
608 ModelerSession
.getMenuService().insertMainMenuItem(ModelerSession
.getActionService().getAction(
609 ModelerModel
.MODELER_IDENTIFIER
, ACTION_PROJECT_NAVIG_SHOW
),
610 new MenuItemPosition(WINDOW_LABEL
), true
612 ModelerSession
.getMenuService().insertMainMenuItem(ModelerSession
.getActionService().getAction(
613 ModelerModel
.MODELER_IDENTIFIER
, ACTION_PLUGINS_OVERVIEW_SHOW
),
614 new MenuItemPosition(WINDOW_LABEL
)
619 * Initialize the event handling.
621 private void initEventHandling(){
622 ModelerSession
.getUserService().getUserValueModel().addValueChangeListener(
623 new PropertyChangeListener(){
624 public void propertyChange(PropertyChangeEvent evt
) {
625 loggedUserLabel
.setText(ModelerSession
.getUserService().getUser());
630 switchUserButton
.addActionListener(new ActionListener(){
631 public void actionPerformed(ActionEvent e
) {
632 ModelerSession
.getActionService().getAction(ModelerModel
.MODELER_IDENTIFIER
, ACTION_SWITH_USER
).actionPerformed(null);
636 ModelerSession
.getProjectService().getSelectedItem().addValueChangeListener(new PropertyChangeListener(){
637 public void propertyChange(PropertyChangeEvent evt
) {
642 // listener of window's closing button (cross button)
643 this.addWindowListener(new WindowAdapter(){
645 public void windowClosing(WindowEvent e
){
647 ModelerSession
.getActionService().getAction(ModelerModel
.MODELER_IDENTIFIER
, ACTION_EXIT
).actionPerformed(null);
651 projectNavigatorButton
.addActionListener(ModelerSession
.getActionService().getAction(ModelerModel
.MODELER_IDENTIFIER
, ACTION_PROJECT_NAVIG_SHOW
));
655 * Installs the plugins into the gui.
657 public void deployNotationSpecificPlugIns( ){
658 for(final String notationIdentifier
: ModelerSession
.getNotationService().getNotationsIdentifiers()){
659 final NotationSpecificPlugins notationSpecificPlugins
= ModelerSession
.getNotationService().getNotationSpecificPlugins(notationIdentifier
);
661 installNotationsAndModules(notationSpecificPlugins
);
666 * Shows the application frame window.
668 public void showFrame(){
669 // update view to initial state
672 dockingManager
.loadLayoutData();
674 dockingManager
.setFrameUnavailable(projectNavigationDockableFrame
.getName());
676 for( final NotationGuiHolder notationGuiHolder
: model
.getNotationGuiHolders() ){
677 for( final DockableFrameWrapper wrapper
: notationGuiHolder
.getAllDockableFrameFacades() ){
678 dockingManager
.setFrameAvailable(wrapper
.getDockableFrame().getName());
679 dockingManager
.setFrameUnavailable(wrapper
.getDockableFrame().getName());
685 projectNavigatorButton
.doClick();
691 * Decides whether there were any errors during plugins loading and if there were any, then show a visual report
692 * about these errors.
694 private void showLoadingErrors(){
695 final List
<PluginLoadErrors
> errors
= ModelerSession
.getNotationService().getErrors();
698 LOG
.error("Nullary loading error info.");
702 if(!errors
.isEmpty()){
703 new LoadErrorsDialog(errors
);
708 * Installs the notations ad modules.
710 * @param notationSpecificPlugins is the holder of notations and it's modules
712 private void installNotationsAndModules(final NotationSpecificPlugins notationSpecificPlugins
){
713 final NotationGuiHolder notationGuiHolder
= new NotationGuiHolder(
714 notationSpecificPlugins
.getNotation().getIdentifier(),
718 model
.addNotationGuiHolder(notationGuiHolder
);
720 final Collection
<DockableFrameData
> dockableFramesData
= notationSpecificPlugins
.getDockableFramesData();
722 if( dockableFramesData
!= null ){
723 for( final DockableFrameData item
: dockableFramesData
){
725 final DockableFrame frame
= createDockableFrame(
726 item
.getDockableFrameComponent(),
727 item
.getInitialPosition(),
728 item
.getDockableFrameTitle(),
729 item
.isMaximizable(),
730 item
.getInitialState());
732 final JMenu menu
= ModelerSession
.getComponentFactoryService().createMenu(
733 ModelerSession
.getCommonResourceBundle().getString("modeler.dockable.frame.move"));
735 final JMenuItem moveToLeftMenuItem
= ModelerSession
.getComponentFactoryService().createMenuItem(
736 ModelerSession
.getCommonResourceBundle().getString("modeler.dockable.frame.move.left"));
737 moveToLeftMenuItem
.addActionListener(new MenuItemMoveListener(notationGuiHolder
, frame
, NotationGuiHolder
.Position
.LEFT
));
739 final JMenuItem moveToRightMenuItem
= ModelerSession
.getComponentFactoryService().createMenuItem(
740 ModelerSession
.getCommonResourceBundle().getString("modeler.dockable.frame.move.right"));
741 moveToRightMenuItem
.addActionListener(new MenuItemMoveListener(notationGuiHolder
, frame
, NotationGuiHolder
.Position
.RIGHT
));
743 final JMenuItem moveToTopMenuItem
= ModelerSession
.getComponentFactoryService().createMenuItem(
744 ModelerSession
.getCommonResourceBundle().getString("modeler.dockable.frame.move.top"));
745 moveToTopMenuItem
.addActionListener(new MenuItemMoveListener(notationGuiHolder
, frame
, NotationGuiHolder
.Position
.TOP
));
747 final JMenuItem moveToBottomMenuItem
= ModelerSession
.getComponentFactoryService().createMenuItem(
748 ModelerSession
.getCommonResourceBundle().getString("modeler.dockable.frame.move.bottom"));
749 moveToBottomMenuItem
.addActionListener(new MenuItemMoveListener(notationGuiHolder
, frame
, NotationGuiHolder
.Position
.BOTTOM
));
751 final JPopupMenu popupMenu
= ModelerSession
.getComponentFactoryService().createPopupMenu();
753 if(item
.getAllowedDockableFramePositions() != null){
754 boolean insertMenu
= false;
756 for(final NotationGuiHolder
.Position position
: NotationGuiHolder
.Position
.values()){
757 if(item
.getAllowedDockableFramePositions().contains(position
)){
760 menu
.add(moveToLeftMenuItem
);
764 menu
.add(moveToRightMenuItem
);
768 menu
.add(moveToTopMenuItem
);
772 menu
.add(moveToBottomMenuItem
);
776 LOG
.error("No such a choice for allowed position of dockable frame.");
786 final JideButton button
;
787 switch (item
.getInitialPosition()){
790 button
= ModelerSession
.getComponentFactoryService().createJideButton(item
.getDockableFrameTitle(),
791 item
.getButtonIcon(),
797 button
= ModelerSession
.getComponentFactoryService().createJideButton(item
.getDockableFrameTitle(),
798 item
.getButtonIcon(),
802 button
.addActionListener(new SideButtonListener(notationGuiHolder
, dockingManager
, frame
));
803 button
.addMouseListener(new ButtonPopupAdapter(button
, popupMenu
));
805 frame
.addDockableFrameListener(new DockFrameListener(notationGuiHolder
, dockingManager
));
807 notationGuiHolder
.addFrameWithButton(
813 moveToBottomMenuItem
,
815 item
.getInitialPosition(),
816 item
.getInitialState());
820 final String notationIdentifier
= notationSpecificPlugins
.getNotation().getIdentifier();
822 // insert notation workspace
823 if( notationSpecificPlugins
.getNotation().getNotationWorkspaceData() != null ){
824 notationGuiHolder
.setNotationWorkspace(notationSpecificPlugins
.getNotation().getNotationWorkspaceData());
826 notationGuiHolder
.setNotationWorkspace(new NotationWorkspaceDataDefault(notationIdentifier
));
828 LOG
.error("No workspace definition provided. Default panel has been inserted instead. " +
829 "Notation identifier: " + notationIdentifier
);
832 // insert notation specific tool bar
833 addToolBarPane(notationIdentifier
, ModelerSession
.getToolBarControlService().getCommandBar(notationIdentifier
));
835 // insert notation specific status bar
836 addStatusBar(notationIdentifier
, ModelerSession
.getStatusBarControlService().getStatusBar(notationIdentifier
));
838 deployWorkspace(notationIdentifier
);
839 deployButtons(notationIdentifier
);
843 * Installs the workspace component.
845 * @param notationIdentifier is the identifier of associated notation
847 private void deployWorkspace( final String notationIdentifier
){
848 final NotationWorkspaceData notationWorkspaceData
= model
.getNotationGuiHolder(notationIdentifier
).getNotationWorkspace();
850 final JComponent workspaceComponent
= notationWorkspaceData
.getWorkspaceComponentSingleton();
852 if(!(workspaceComponent
instanceof UpdatableWorkspaceComponent
)){
853 LOG
.warn("The obtained workspace component for notation (" + notationIdentifier
+ ") doesn't implement the UpdatableWorkspaceComponent inytercae. " +
854 "Any methods of this interface won't be never invoked for this workspace component.");
857 addMainWindowPane(notationIdentifier
, workspaceComponent
);
863 * @param notationIdentifier is the notation identifier.
865 private void deployButtons( final String notationIdentifier
){
866 final NotationGuiHolder spec
= model
.getNotationGuiHolder(notationIdentifier
);
868 addSidePane(notationIdentifier
, rightSidePane
, spec
.getListOfButtons(
869 NotationGuiHolder
.Position
.RIGHT
), true);
871 addSidePane(notationIdentifier
, leftSidePane
, spec
.getListOfButtons(
872 NotationGuiHolder
.Position
.LEFT
), true);
874 addSidePane(notationIdentifier
, bottomSidePane
, spec
.getListOfButtons(
875 NotationGuiHolder
.Position
.BOTTOM
), false);
877 addSidePane(notationIdentifier
, topSidePane
, spec
.getListOfButtons(
878 NotationGuiHolder
.Position
.TOP
), false);
882 * Initializes the common settings dialog.
884 public void initSettingsDialog() {
885 LOG
.info("Initializing settings dialog.");
887 for(final Notation notation
: ModelerSession
.getNotationService().getNotations()){
888 final NotationSpecificPlugins notationSpecificPlugins
=
889 ModelerSession
.getNotationService().getNotationSpecificPlugins(notation
.getIdentifier());
891 // init notation's settings screens
892 List
<AbstractDialogPage
> pages
= notationSpecificPlugins
.getNotation().getSettingPages();
895 LOG
.info("Notation " + notation
.getIdentifier() + " provides nullary setting pages list.");
896 pages
= new LinkedList
<AbstractDialogPage
>();
900 pages
.add(0, new BasicSettingPage(notation
.getFullName()));
902 final AbstractDialogPage parentPage
= pages
.get(0);
904 installPagesParent(pages
, parentPage
);
906 model
.addSettingPages(pages
);
908 // init module's settings screens
909 for(final Module module
: notationSpecificPlugins
.getModules()){
910 pages
= module
.getSettingPages();
913 installPagesParent(pages
, parentPage
);
915 model
.addSettingPages(pages
);
918 LOG
.info("Module " + module
.getIdentifier() + " provides nullary setting pages list.");
923 // init extension's settings screens
924 for(final Extension extension
: ModelerSession
.getExtensionService().getExtensions()){
925 List
<AbstractDialogPage
> pages
= extension
.getSettingPages();
928 LOG
.info("Extension " + extension
.getIdentifier() + " provides nullary setting pages list.");
929 pages
= new LinkedList
<AbstractDialogPage
>();
933 pages
.add(0, new BasicSettingPage(extension
.getName()));
935 final AbstractDialogPage parentPage
= pages
.get(0);
937 installPagesParent(pages
, parentPage
);
939 model
.addSettingPages(pages
);
944 * Sets the proper parent to all settings pages. If the parent of the page is already set then nothing is changed.
946 * @param pages is the page
947 * @param parentDialogPage is the parent of the page
949 private void installPagesParent(final List
<AbstractDialogPage
> pages
, final AbstractDialogPage parentDialogPage
) {
950 if(pages
.size() > 1){
951 pages
.get(1).setParentPage(parentDialogPage
);
954 for(final AbstractDialogPage page
: pages
){
955 if(page
.getParent() == null && page
!= parentDialogPage
){
956 page
.setParentPage(parentDialogPage
);
962 * Performs dockable frame moves.
964 private class MenuItemMoveListener
implements ActionListener
{
966 private final NotationGuiHolder notationGuiHolder
;
967 private final DockableFrame dockableFrame
;
968 private final NotationGuiHolder
.Position directionOfMovement
;
970 public MenuItemMoveListener( final NotationGuiHolder notationGuiHolder
,
971 final DockableFrame correspondingFrame
,
972 final NotationGuiHolder
.Position directionOfMovement
){
973 this.notationGuiHolder
= notationGuiHolder
;
974 this.dockableFrame
= correspondingFrame
;
975 this.directionOfMovement
= directionOfMovement
;
978 public void actionPerformed( ActionEvent e
){
980 final String notationIdentifier
= notationGuiHolder
.getNotationIdentifier();
981 final String dockableFrameName
= dockableFrame
.getName();
983 NotationGuiHolder
.Position oldPosition
= notationGuiHolder
.getPosition(dockableFrameName
);
985 notationGuiHolder
.moveButtonAndFrame(dockableFrameName
, directionOfMovement
);
987 final JPanel oldPanel
;
988 final CardLayout oldCardLayout
;
990 switch (oldPosition
){
992 oldPanel
= leftSidePane
;
993 oldCardLayout
= cardLayoutLeftSidePane
;
997 oldPanel
= rightSidePane
;
998 oldCardLayout
= cardLayoutRightSidePane
;
1002 oldPanel
= topSidePane
;
1003 oldCardLayout
= cardLayoutTopSidePane
;
1007 oldPanel
= bottomSidePane
;
1008 oldCardLayout
= cardLayoutBottomSidePane
;
1014 oldCardLayout
= null;
1015 LOG
.error("No such a position for dockable frame.");
1018 addSidePane(notationIdentifier
, oldPanel
, notationGuiHolder
.getListOfButtons(oldPosition
), isVertical
);
1019 oldCardLayout
.show(oldPanel
, notationIdentifier
);
1022 final JPanel newPanel
;
1023 final NotationGuiHolder
.Position newPosition
;
1024 final CardLayout newCardLayout
;
1025 switch(directionOfMovement
){
1027 newPanel
= leftSidePane
;
1028 newPosition
= NotationGuiHolder
.Position
.LEFT
;
1030 newCardLayout
= cardLayoutLeftSidePane
;
1033 newPanel
= rightSidePane
;
1034 newPosition
= NotationGuiHolder
.Position
.RIGHT
;
1036 newCardLayout
= cardLayoutRightSidePane
;
1039 newPanel
= bottomSidePane
;
1040 newPosition
= NotationGuiHolder
.Position
.BOTTOM
;
1042 newCardLayout
= cardLayoutBottomSidePane
;
1045 newPanel
= topSidePane
;
1046 newPosition
= NotationGuiHolder
.Position
.TOP
;
1048 newCardLayout
= cardLayoutTopSidePane
;
1054 newCardLayout
= null;
1055 LOG
.error("No such a position for dockable frame.");
1058 addSidePane(notationIdentifier
, newPanel
, notationGuiHolder
.getListOfButtons(newPosition
), isVertical
);
1059 newCardLayout
.show(newPanel
, notationIdentifier
);
1061 } catch(IllegalArgumentException exception
){
1062 LOG
.error("Illegal position or unknown frame during low level navigation movement.", exception
);