Package org.freeplane.features.note.mindmapmode

Source Code of org.freeplane.features.note.mindmapmode.MNoteController

/*
*  Freeplane - mind map editor
*  Copyright (C) 2008 Joerg Mueller, Daniel Polansky, Christian Foltin, Dimitry Polivaev
*
*  This file is created by Dimitry Polivaev in 2008.
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.freeplane.features.note.mindmapmode;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.net.URI;

import javax.swing.BorderFactory;
import javax.swing.InputMap;
import javax.swing.JEditorPane;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.html.StyleSheet;

import org.freeplane.core.resources.ResourceController;
import org.freeplane.core.undo.IActor;
import org.freeplane.core.util.LogUtils;
import org.freeplane.features.map.IMapSelection;
import org.freeplane.features.map.MapController;
import org.freeplane.features.map.MapModel;
import org.freeplane.features.map.NodeModel;
import org.freeplane.features.mode.Controller;
import org.freeplane.features.mode.ModeController;
import org.freeplane.features.nodestyle.NodeStyleController;
import org.freeplane.features.note.NoteController;
import org.freeplane.features.note.NoteModel;
import org.freeplane.features.spellchecker.mindmapmode.SpellCheckerController;
import org.freeplane.features.styles.MapStyle;
import org.freeplane.features.styles.MapStyleModel;
import org.freeplane.features.styles.mindmapmode.SetBooleanMapPropertyAction;
import org.freeplane.features.text.mindmapmode.FreeplaneToSHTMLPropertyChangeAdapter;
import org.freeplane.features.text.mindmapmode.MTextController;
import org.freeplane.features.url.UrlManager;

import com.lightdev.app.shtm.SHTMLEditorPane;
import com.lightdev.app.shtm.SHTMLPanel;

/**
* @author Dimitry Polivaev
*/
public class MNoteController extends NoteController {
  final class NoteDocumentListener implements DocumentListener {
    public void changedUpdate(final DocumentEvent arg0) {
      docEvent();
    }

    private void docEvent() {
      final Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
      if (focusOwner == null || !SwingUtilities.isDescendingFrom(focusOwner, htmlEditorPanel)) {
        return;
      }
      final ModeController modeController = Controller.getCurrentModeController();
      final MapController mapController = modeController.getMapController();
      final MapModel map = modeController.getController().getMap();
      mapController.setSaved(map, false);
    }

    public void insertUpdate(final DocumentEvent arg0) {
      docEvent();
    }

    public void removeUpdate(final DocumentEvent arg0) {
      docEvent();
    }
  }

  private static class SouthPanel extends JPanel {
    /**
     *
     */
    private static final long serialVersionUID = 1L;

    public SouthPanel() {
      super(new BorderLayout());
      setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));
    }

    @Override
    protected boolean processKeyBinding(final KeyStroke ks, final KeyEvent e, final int condition,
                                        final boolean pressed) {
      return super.processKeyBinding(ks, e, condition, pressed) || e.getKeyChar() == KeyEvent.VK_SPACE
              || e.getKeyChar() == KeyEvent.VK_ALT;
    }
  }

  private static SHTMLPanel htmlEditorPanel;
  public static final String RESOURCES_REMOVE_NOTES_WITHOUT_QUESTION = "remove_notes_without_question";
  public static final String RESOURCES_USE_DEFAULT_FONT_FOR_NOTES_TOO = "resources_use_default_font_for_notes_too";
  public static final String RESOURCES_USE_MARGIN_TOP_ZERO_FOR_NOTES = "resources_use_margin_top_zero_for_notes";
  static final String RESOURCES_USE_SPLIT_PANE = "use_split_pane";
  /**
   * Indicates, whether or not the main panel has to be refreshed with new
   * content. The typical content will be empty, so this state is saved here.
   */
  private boolean mLastContentEmpty = true;
  private final NoteManager noteManager;
  private SHTMLPanel noteViewerComponent;

  /**
   * @param modeController
   */
  public MNoteController(ModeController modeController) {
    super();
    noteManager = new NoteManager(this);
    createActions(modeController);
  }

  private void createActions(ModeController modeController) {
      modeController.addAction(new SelectNoteAction(this));
    modeController.addAction(new ShowHideNoteAction(this));
    modeController.addAction(new EditNoteInDialogAction());
    modeController.addAction(new SetNoteWindowPosition("top"));
    modeController.addAction(new SetNoteWindowPosition( "left"));
    modeController.addAction(new SetNoteWindowPosition("right"));
    modeController.addAction(new SetNoteWindowPosition("bottom"));
    modeController.addAction(new RemoveNoteAction(this));
    modeController.addAction(new SetBooleanMapPropertyAction(SHOW_NOTE_ICONS));
    }

  SHTMLPanel getHtmlEditorPanel() {
    if (htmlEditorPanel != null) {
      return htmlEditorPanel;
    }
    htmlEditorPanel = MTextController.getController().createSHTMLPanel(NoteModel.EDITING_PURPOSE);

    // make sure that SHTML gets notified of relevant config changes!
       ResourceController.getResourceController().addPropertyChangeListener(
          new FreeplaneToSHTMLPropertyChangeAdapter(htmlEditorPanel));

    htmlEditorPanel.setMinimumSize(new Dimension(100, 100));
    final SHTMLEditorPane editorPane = (SHTMLEditorPane) htmlEditorPanel.getEditorPane();

    for (InputMap inputMap = editorPane.getInputMap(); inputMap != null; inputMap = inputMap.getParent()){
      inputMap.remove(KeyStroke.getKeyStroke("ctrl pressed T"));
      inputMap.remove(KeyStroke.getKeyStroke("ctrl shift pressed T"));
      inputMap.remove(KeyStroke.getKeyStroke("ctrl pressed SPACE"));
    }

    editorPane.addFocusListener(new FocusListener() {
      private SpellCheckerController spellCheckerController = null;
      private boolean enabled = false;
      public void focusLost(final FocusEvent e) {
        if(! e.isTemporary()){
          spellCheckerController.enableAutoSpell(editorPane, false);
          enabled = false;
        }
      }

      public void focusGained(final FocusEvent e) {
        if(! enabled){
          initSpellChecker();
          spellCheckerController.enableAutoSpell(editorPane, true);
          enabled = true;
        }
      }

      private void initSpellChecker() {
        if (spellCheckerController != null) {
          return;
        }
        spellCheckerController = SpellCheckerController.getController();
        spellCheckerController.addSpellCheckerMenu(editorPane.getPopup());
        spellCheckerController.enableShortKey(editorPane, true);
      }
    });
    return htmlEditorPanel;
  }

  SHTMLPanel getNoteViewerComponent() {
    return noteViewerComponent;
  }

  void hideNotesPanel() {
    noteManager.saveNote();
    noteViewerComponent.setVisible(false);
    Controller.getCurrentModeController().getController().getViewController().removeSplitPane();
    ResourceController.getResourceController().setProperty(MNoteController.RESOURCES_USE_SPLIT_PANE, "false");
  }

  boolean isLastContentEmpty() {
    return mLastContentEmpty;
  }

  @Override
  protected void onWrite(final MapModel map) {
    final ModeController modeController = Controller.getCurrentModeController();
    final Controller controller = modeController.getController();
    final IMapSelection selection = controller.getSelection();
    if (selection == null) {
      return;
    }
    final NodeModel selected = selection.getSelected();
    noteManager.saveNote(selected);
  }

  void setLastContentEmpty(final boolean mLastContentEmpty) {
    this.mLastContentEmpty = mLastContentEmpty;
  }

  public void setNoteText(final NodeModel node, final String newText) {
    final String oldText = getNoteText(node);
    if (oldText == newText || null != oldText && oldText.equals(newText)) {
      return;
    }
    final IActor actor = new IActor() {
      public void act() {
        setText(newText);
      }

      public String getDescription() {
        return "setNoteText";
      }

      private void setText(final String text) {
        final boolean enabled = !(text == null || text.equals(""));
        if (enabled) {
          final NoteModel note = NoteModel.createNote(node);
          note.setHtml(text);
          node.addExtension(note);
        }
        else {
          if (null != node.getExtension(NoteModel.class)) {
            node.removeExtension(NoteModel.class);
          }
        }
        Controller.getCurrentModeController().getMapController().nodeChanged(node, NodeModel.NOTE_TEXT, oldText, text);
        if(noteManager != null)
          noteManager.updateEditor();
      }

      public void undo() {
        setText(oldText);
      }
    };
    Controller.getCurrentModeController().execute(actor, node.getMap());
  }

  private boolean shouldUseSplitPane() {
    return "true".equals(ResourceController.getResourceController().getProperty(
        MNoteController.RESOURCES_USE_SPLIT_PANE));
  }

  void showNotesPanel(final boolean requestFocus) {
    if (noteViewerComponent == null) {
      noteViewerComponent = getHtmlEditorPanel();
      noteManager.updateEditor();
    }
    final SouthPanel southPanel = new SouthPanel();
    southPanel.add(noteViewerComponent, BorderLayout.CENTER);
//    setDefaultFont();
    noteViewerComponent.setOpenHyperlinkHandler(new ActionListener() {
      public void actionPerformed(final ActionEvent pE) {
        try {
          String uriText = pE.getActionCommand();
          UrlManager.getController().loadURL(new URI(uriText));
        }
        catch (final Exception e) {
          LogUtils.severe(e);
        }
      }
    });
    noteViewerComponent.setVisible(true);
    ResourceController.getResourceController().setProperty(MNoteController.RESOURCES_USE_SPLIT_PANE, "true");
    Controller.getCurrentModeController().getController().getViewController().insertComponentIntoSplitPane(southPanel);
    if (requestFocus) {
      KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
      EventQueue.invokeLater(new Runnable() {
        public void run() {
          final SHTMLPanel htmlEditorPanel = getHtmlEditorPanel();
          htmlEditorPanel.getMostRecentFocusOwner().requestFocus();
          if (ResourceController.getResourceController().getBooleanProperty("goto_note_end_on_edit")) {
            final JEditorPane editorPane = htmlEditorPanel.getEditorPane();
            editorPane.setCaretPosition(editorPane.getDocument().getLength());
          }
        }
      });
    }
    southPanel.revalidate();
  }

  void setDefaultFont() {
      final StyleSheet styleSheet = noteViewerComponent.getDocument().getStyleSheet();
      styleSheet.removeStyle("body");
      styleSheet.removeStyle("p");
      // set default font for notes:
      final NodeStyleController style = Controller.getCurrentModeController().getExtension(
          NodeStyleController.class);
      MapModel map = Controller.getCurrentModeController().getController().getMap();
      if(map != null){
          final Font defaultFont;
          defaultFont = style.getDefaultFont(map, MapStyleModel.NOTE_STYLE);
          String rule = "body {";
          rule += "font-family: " + defaultFont.getFamily() + ";";
          rule += "font-size: " + defaultFont.getSize() + "pt;";
            if (defaultFont.isItalic()) {
                rule += "font-style: italic; ";
            }
            if (defaultFont.isBold()) {
                rule += "font-weight: bold; ";
            }
          rule += "}\n";
          styleSheet.addRule(rule);
      }
      if (ResourceController.getResourceController().getBooleanProperty(
          MNoteController.RESOURCES_USE_MARGIN_TOP_ZERO_FOR_NOTES)) {
      /* this is used for paragraph spacing. I put it here, too, as
       * the tooltip display uses the same spacing. But it is to be discussed.
       * fc, 23.3.2009.
       */
      String rule = "p {";
      rule += "margin-top:0;";
      rule += "}\n";
      styleSheet.addRule(rule);
    }
  }

  boolean isEditing() {
    final Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
        return focusOwner != null && noteViewerComponent != null && SwingUtilities.isDescendingFrom(focusOwner, noteViewerComponent);
  }

  void setFocusToMap() {
    final Controller controller = Controller.getCurrentModeController().getController();
    final NodeModel node = controller.getSelection().getSelected();
    controller.getMapViewManager().getComponent(node).requestFocusInWindow();
  }

  public void shutdownController() {
    Controller.getCurrentModeController().getMapController().removeNodeSelectionListener(noteManager);
    if (noteViewerComponent == null) {
      return;
    }
    noteViewerComponent.getActionMap().remove("jumpToMapAction");
    if (shouldUseSplitPane()) {
      hideNotesPanel();
      noteViewerComponent = null;
    }
  }

  public void startupController() {
    final ModeController modeController = Controller.getCurrentModeController();
    if (shouldUseSplitPane()) {
      showNotesPanel(false);
    }
    modeController.getMapController().addNodeSelectionListener(noteManager);
    noteManager.mNoteDocumentListener = new NoteDocumentListener();
  }

  boolean isNoteEditorShowing() {
    return ResourceController.getResourceController().getBooleanProperty(
        MNoteController.RESOURCES_USE_SPLIT_PANE);
  }

  public void setShowNotesInMap(final MapModel model, final boolean show) {
    MapStyle.getController().setProperty(model, SHOW_NOTES_IN_MAP, Boolean.toString(show));
  }
}
TOP

Related Classes of org.freeplane.features.note.mindmapmode.MNoteController

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.