Converted all CRLF to LF.
[indepmod/mmn.git] / IndependentModeler / src / cz / cvut / promod / gui / Modeler.java
blobe563f32a7d6b5c2b8eac71f991cadbebdad22b06
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;
37 import javax.swing.*;
38 import javax.swing.tree.TreePath;
39 import java.awt.*;
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;
47 /**
48 * ProMod, master thesis project
49 * User: Petr Zverina, petr.zverina@gmail.com
50 * Date: 16:09:42, 10.10.2009
53 /**
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;
116 public Modeler( ){
117 ModelerSession.setFrame(this);
119 this.model = new ModelerModel();
121 initActions();
123 initMainMenu();
125 initProjectNavigation();
127 initEventHandling();
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,
169 ACTION_SWITH_USER,
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,
176 OK_LABEL,
177 CANCEL_LABEL,
178 new SimpleTextFieldDialogExecutor(){
179 public String execute(final String text) {
180 if(text != null && !text.isEmpty()){
181 ModelerSession.getUserService().setUser(text);
182 return null;
185 return USER_CHANGE_DIALOG_INVALID_LABEL;
188 ModelerSession.getFrame(),
189 true
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,
207 ACTION_EXIT,
208 new ProModAction(ModelerSession.getCommonResourceBundle().getString(ACTION_EXIT), null, null){
209 public void actionPerformed(ActionEvent event) {
210 modelerExit();
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,
231 ACTION_PROJECT_SAVE,
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){
243 } else {
244 final boolean syncResult = ModelerSession.getProjectControlService().synchronize(
245 projectTreePath, true, true, false, false);
247 if (!syncResult){
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,
260 ACTION_PROJECT_LOAD,
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());
273 } else{
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();
293 } else{
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");
307 return;
310 setVisible(false);
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()){
319 module.finish();
323 // finishing extensions
324 for(Extension extension : ModelerSession.getExtensionService().getExtensions()){
325 extension.finish();
328 dispose();
329 System.exit(0);
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
343 return false;
347 return true;
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){
385 if(update){
386 ModelerSession.getProjectService().getSelectedDiagram().getDiagramModel().update();
387 } else {
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();
401 if(menuBar != null){
403 for(int i = 0; i < menuBar.getMenuCount(); i++){
404 final JMenuItem menuItem = menuBar.getMenu(i);
405 boolean isVisible = updateMenuItemVisibility(menuItem, newNotationIdentifier);
407 if(isVisible){
408 menuItem.setEnabled(true);
409 } else {
410 menuItem.setEnabled(false);
418 * Recursively goes through the menu structure and ensures that only items related to the currently selected notation
419 * will be enabled.
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);
443 return 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);
456 } else {
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()){
476 return false;
479 for(ModelerMenuItem modelerMenuItem : relatives){
480 if(modelerMenuItem instanceof JMenuItem){
481 final JMenuItem menuItem = (JMenuItem) modelerMenuItem;
482 if(menuItem.isEnabled()){
483 return true;
488 return false;
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);
509 } else {
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;
524 try{
525 workspaceComponent = model.getNotationGuiHolder(notationIdentifier).getNotationWorkspace().getWorkspaceComponentSingleton();
527 if(workspaceComponent instanceof UpdatableWorkspaceComponent){
528 final UpdatableWorkspaceComponent updatableWorkspaceComponent = (UpdatableWorkspaceComponent)workspaceComponent;
530 if(update){
531 updatableWorkspaceComponent.update();
532 } else {
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;
570 try{
571 mainMenuControlService = (MenuControlService) ModelerSession.getMenuService();
572 } catch(ClassCastException exception){
573 LOG.error("Main menu initialization not possible.", exception);
574 return;
577 setJMenuBar(mainMenuControlService.getMenuBar());
579 // insert common menu items
580 // 'file' menu
581 ModelerSession.getMenuService().insertMainMenuItem(ModelerSession.getActionService().getAction(
582 ModelerModel.MODELER_IDENTIFIER, ACTION_EXIT),
583 new MenuItemPosition(FILE_LABEL), MenuService.MenuSeparator.BEFORE
586 // 'project' menu
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)
601 // 'edit' Menu
602 ModelerSession.getMenuService().insertMainMenuItem(ModelerSession.getActionService().getAction(
603 ModelerModel.MODELER_IDENTIFIER, ACTION_SETTINGS_SHOW),
604 new MenuItemPosition(EDIT_LABEL)
607 // 'window' menu
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) {
638 updateView();
642 // listener of window's closing button (cross button)
643 this.addWindowListener(new WindowAdapter(){
644 @Override
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
670 updateView();
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());
683 setVisible(true);
685 projectNavigatorButton.doClick();
687 showLoadingErrors();
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();
697 if(errors == null){
698 LOG.error("Nullary loading error info.");
699 return;
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(),
715 dockingManager
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)){
758 switch (position){
759 case LEFT:
760 menu.add(moveToLeftMenuItem);
761 insertMenu = true;
762 break;
763 case RIGHT:
764 menu.add(moveToRightMenuItem);
765 insertMenu = true;
766 break;
767 case TOP:
768 menu.add(moveToTopMenuItem);
769 insertMenu = true;
770 break;
771 case BOTTOM:
772 menu.add(moveToBottomMenuItem);
773 insertMenu = true;
774 break;
775 default:
776 LOG.error("No such a choice for allowed position of dockable frame.");
781 if(insertMenu){
782 popupMenu.add(menu);
786 final JideButton button;
787 switch (item.getInitialPosition()){
788 case BOTTOM:
789 case TOP:
790 button = ModelerSession.getComponentFactoryService().createJideButton(item.getDockableFrameTitle(),
791 item.getButtonIcon(),
793 break;
794 default:
795 // case LEFT:
796 // case RIGHT:
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(
808 frame,
809 button,
810 popupMenu,
811 moveToLeftMenuItem,
812 moveToRightMenuItem,
813 moveToBottomMenuItem,
814 moveToTopMenuItem,
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());
825 } else {
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);
861 * Deploys buttons.
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();
894 if(pages == null){
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();
912 if(pages != null){
913 installPagesParent(pages, parentPage);
915 model.addSettingPages(pages);
917 } else {
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();
927 if(pages == null){
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 ){
979 try{
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;
989 boolean isVertical;
990 switch (oldPosition){
991 case LEFT:
992 oldPanel = leftSidePane;
993 oldCardLayout = cardLayoutLeftSidePane;
994 isVertical = true;
995 break;
996 case RIGHT:
997 oldPanel = rightSidePane;
998 oldCardLayout = cardLayoutRightSidePane;
999 isVertical = true;
1000 break;
1001 case TOP:
1002 oldPanel = topSidePane;
1003 oldCardLayout = cardLayoutTopSidePane;
1004 isVertical = false;
1005 break;
1006 case BOTTOM:
1007 oldPanel = bottomSidePane;
1008 oldCardLayout = cardLayoutBottomSidePane;
1009 isVertical = false;
1010 break;
1011 default:
1012 oldPanel = null;
1013 isVertical = true;
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){
1026 case LEFT:
1027 newPanel = leftSidePane;
1028 newPosition = NotationGuiHolder.Position.LEFT;
1029 isVertical = true;
1030 newCardLayout = cardLayoutLeftSidePane;
1031 break;
1032 case RIGHT:
1033 newPanel = rightSidePane;
1034 newPosition = NotationGuiHolder.Position.RIGHT;
1035 isVertical = true;
1036 newCardLayout = cardLayoutRightSidePane;
1037 break;
1038 case BOTTOM:
1039 newPanel = bottomSidePane;
1040 newPosition = NotationGuiHolder.Position.BOTTOM;
1041 isVertical = false;
1042 newCardLayout = cardLayoutBottomSidePane;
1043 break;
1044 case TOP:
1045 newPanel = topSidePane;
1046 newPosition = NotationGuiHolder.Position.TOP;
1047 isVertical = false;
1048 newCardLayout = cardLayoutTopSidePane;
1049 break;
1050 default:
1051 newPanel = null;
1052 newPosition = null;
1053 isVertical = true;
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);