/* ****************************************************************************** * Copyright (c) 2006-2012 XMind Ltd. and others. * * This file is a part of XMind 3. XMind releases 3 and * above are dual-licensed under the Eclipse Public License (EPL), * which is available at http://www.eclipse.org/legal/epl-v10.html * and the GNU Lesser General Public License (LGPL), * which is available at http://www.gnu.org/licenses/lgpl.html * See http://www.xmind.net/license.html for details. * * Contributors: * XMind Ltd. - initial API and implementation *******************************************************************************/ package org.xmind.ui.tabfolder; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.ITextOperationTarget; import org.eclipse.jface.util.SafeRunnable; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabItem; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.ui.contexts.IContextActivation; import org.eclipse.ui.contexts.IContextService; import org.eclipse.ui.services.IServiceLocator; import org.xmind.ui.texteditor.FloatingTextEditor; import org.xmind.ui.texteditor.IFloatingTextEditorListener; import org.xmind.ui.texteditor.TextEvent; public class PageTitleEditor extends IFloatingTextEditorListener.Stub implements Listener { private CTabFolder tabFolder; private FloatingTextEditor editor; private CTabItem sourceItem; private List<IPageTitleChangedListener> listeners = null; private String contextId; private IServiceLocator serviceLocator; private IContextService cs; private IContextActivation ca; public PageTitleEditor(CTabFolder tabFolder) { this.tabFolder = tabFolder; this.editor = new FloatingTextEditor(tabFolder, SWT.BORDER | SWT.SINGLE); hookControl(tabFolder); hookEditor(editor); } public String getContextId() { return contextId; } public IServiceLocator getServiceLocator() { return serviceLocator; } public void setContextId(IServiceLocator serviceLocator, String contextId) { this.serviceLocator = serviceLocator; this.contextId = contextId; } public FloatingTextEditor getEditor() { return editor; } protected void hookControl(CTabFolder tabFolder) { tabFolder.addListener(SWT.MouseDoubleClick, this); } protected void hookEditor(FloatingTextEditor editor) { editor.addFloatingTextEditorListener(this); } private void startEditing(Event e) { CTabItem item = tabFolder.getItem(new Point(e.x, e.y)); if (item != null) startEditing(tabFolder.indexOf(item)); } public void startEditing(int pageIndex) { startEditing(tabFolder.getItem(pageIndex)); } private void startEditing(CTabItem item) { cancelEditing(); this.sourceItem = item; if (item == null) return; Rectangle bounds = item.getBounds(); String text = item.getText(); editor.setInitialLocation(new Point(bounds.x, bounds.y)); editor.setInitialSize(new Point(bounds.width, bounds.height)); editor.setInput(new Document(text)); editor.open(); if (editor.canDoOperation(ITextOperationTarget.SELECT_ALL)) { editor.doOperation(ITextOperationTarget.SELECT_ALL); } } public void cancelEditing() { editor.close(); } public void finishEditing() { editor.close(true); } public void handleEvent(Event event) { switch (event.type) { case SWT.MouseDoubleClick: startEditing(event); break; case SWT.FocusOut: if (editor != null && editor.getControl() != null && !editor.getControl().isDisposed()) { editor.getTextViewer().getTextWidget().removeListener( SWT.FocusOut, this); editor.close(true); } } } public void addPageTitleChangedListener(IPageTitleChangedListener listener) { if (listeners == null) listeners = new ArrayList<IPageTitleChangedListener>(); listeners.add(listener); } public void removePageTitleChangedListener( IPageTitleChangedListener listener) { if (listeners == null) return; listeners.remove(listener); } protected void firePageTitleChanged(final int pageIndex, final String newValue) { if (listeners == null) return; for (final Object l : listeners.toArray()) { SafeRunner.run(new SafeRunnable() { public void run() throws Exception { ((IPageTitleChangedListener) l).pageTitleChanged(pageIndex, newValue); } }); } } public void editingCanceled(TextEvent e) { deactivateContext(); sourceItem = null; } public void editingFinished(TextEvent e) { deactivateContext(); if (sourceItem == null) return; int pageIndex = tabFolder.indexOf(sourceItem); if (pageIndex >= 0) { firePageTitleChanged(pageIndex, e.text); } sourceItem = null; } public void textChanged(TextEvent e) { updateEditorBounds(); } public void editingStarted(TextEvent e) { super.editingStarted(e); activateContext(); editor.getTextViewer().getTextWidget().addListener(SWT.FocusOut, this); } private void activateContext() { if (getContextId() != null && getServiceLocator() != null) { cs = (IContextService) getServiceLocator().getService( IContextService.class); if (cs != null) { ca = cs.activateContext(getContextId()); } } } private void deactivateContext() { if (cs != null && ca != null) { cs.deactivateContext(ca); } cs = null; ca = null; } private void updateEditorBounds() { //TODO update page title editor bounds } }