/*******************************************************************************
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package hr.fer.zemris.vhdllab.view;
import hr.fer.zemris.vhdllab.entity.File;
import hr.fer.zemris.vhdllab.platform.manager.editor.Editor;
import hr.fer.zemris.vhdllab.platform.manager.editor.EditorContainer;
import hr.fer.zemris.vhdllab.platform.manager.editor.EditorContainerListener;
import hr.fer.zemris.vhdllab.platform.manager.editor.EditorListener;
import hr.fer.zemris.vhdllab.platform.ui.command.RedoCommand;
import hr.fer.zemris.vhdllab.platform.ui.command.UndoCommand;
import java.awt.Component;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.richclient.application.PageComponentContext;
import org.springframework.richclient.application.support.AbstractView;
import org.springframework.richclient.command.CommandGroup;
import org.springframework.richclient.command.CommandManager;
import org.springframework.richclient.command.support.GlobalCommandIds;
import org.springframework.richclient.core.Guarded;
public class TabbedEditorsView extends AbstractView implements
EditorContainerListener {
protected boolean addingTab;
protected JTabbedPane tabbedPane;
@Autowired
protected EditorContainer container;
private Map<File, Editor> editors = new HashMap<File, Editor>();
@Override
protected void registerLocalCommandExecutors(PageComponentContext context) {
context.register(GlobalCommandIds.UNDO, new UndoCommand());
context.register(GlobalCommandIds.REDO, new RedoCommand());
}
@Override
protected JComponent createControl() {
CommandManager commandManager = getActiveWindow().getCommandManager();
CommandGroup commandGroup = commandManager.createCommandGroup(
"editorsMenu", new Object[] { "saveCommand", "saveAllCommand",
"separator", "closeCommand", "closeOtherCommand",
"closeAllCommand" });
tabbedPane = new JTabbedPane(JTabbedPane.TOP,
JTabbedPane.WRAP_TAB_LAYOUT);
tabbedPane.setComponentPopupMenu(commandGroup.createPopupMenu());
tabbedPane.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (!addingTab) {
int index = tabbedPane.getSelectedIndex();
container.setSelected(index);
}
}
});
return tabbedPane;
}
@Override
public void editorAdded(Editor editor) {
addingTab = true;
editors.put(editor.getFile(), editor);
String title = editor.getTitle();
String tooltip = editor.getCaption();
Object[] args = new Object[] { editor.getFileName(),
editor.getProjectName() };
title = MessageFormat.format(title, args);
tooltip = MessageFormat.format(tooltip, args);
Icon editorIcon = getIconSource().getIcon("editor.icon");
tabbedPane.addTab(title, editorIcon, editor.getControl(), tooltip);
editor.getEventPublisher().addListener(new EditorModifiedListener());
updateEditorCommandEnabledState();
addingTab = false;
}
@Override
public void editorRemoved(Editor editor) {
tabbedPane.remove(editor.getControl());
editors.remove(editor.getFile());
updateEditorCommandEnabledState();
}
@Override
public void editorSelected(Editor editor) {
if (editor != null) {
tabbedPane.setSelectedComponent(editor.getControl());
updateEditorCommandEnabledState();
}
}
private void updateEditorCommandEnabledState() {
updateState("closeCommand", tabbedPane.getSelectedComponent() != null);
updateState("closeAllCommand", tabbedPane.getTabCount() > 0);
updateState("closeOtherCommand", tabbedPane.getTabCount() > 1);
Component selectedComponent = tabbedPane.getSelectedComponent();
boolean saveEnabled = false;
boolean saveAllEnabled = false;
if (selectedComponent != null) {
for (Editor editor : editors.values()) {
if (editor.isModified()) {
saveEnabled = editor.getControl() == selectedComponent;
saveAllEnabled = true;
}
}
}
updateState("saveCommand", saveEnabled);
updateState("saveAllCommand", saveAllEnabled);
}
private void updateState(String commandId, boolean enabled) {
CommandManager commandManager = getActiveWindow().getCommandManager();
Object command = commandManager.getCommand(commandId);
if (command instanceof Guarded) {
((Guarded) command).setEnabled(enabled);
}
}
protected void onEditorModified(File file, boolean modified) {
resetEditorTitle(file, modified);
updateEditorCommandEnabledState();
}
private void resetEditorTitle(File file, boolean modified) {
int index = container.indexOf(editors.get(file));
if (index != -1) {
String title = tabbedPane.getTitleAt(index);
if (modified) {
title = "*" + title;
} else {
title = title.substring(1); // omit leading * character
}
tabbedPane.setTitleAt(index, title);
}
}
protected class EditorModifiedListener implements EditorListener {
@Override
public void modified(File file, boolean flag) {
onEditorModified(file, flag);
}
}
}