Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: cac86d97047d5eac2c27eaec594fb1794ffe2af2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*****************************************************************************
 * Copyright (c) 2010, 2015 LIFL, CEA LIST, Christian W. Damus, and others.
 *
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *  Cedric Dumoulin (LIFL) cedric.dumoulin@lifl.fr - Initial API and implementation
 *  Christian W. Damus (CEA) - bug 433371
 *  Christian W. Damus - bug 469188
 *
 *****************************************************************************/

package org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.utils;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageManager;
import org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.internal.PageManagerImpl;
import org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.internal.PageManagerImpl.SashModelOperation;
import org.eclipse.papyrus.infra.core.sasheditor.editor.ICloseablePart;
import org.eclipse.papyrus.infra.core.sasheditor.editor.IPage;
import org.eclipse.papyrus.infra.core.sasheditor.editor.ISashWindowsContainer;
import org.eclipse.papyrus.infra.core.sashwindows.di.PageRef;
import org.eclipse.papyrus.infra.core.sashwindows.di.SashModel;
import org.eclipse.papyrus.infra.core.sashwindows.di.SashWindowsMngr;
import org.eclipse.papyrus.infra.core.sashwindows.di.TabFolder;
import org.eclipse.papyrus.infra.core.sashwindows.di.util.DiSwitch;


/**
 * Class providing a utility methods allowing to get the real Model from the {@link IPage#getRawModel()}.
 * The utility takes into account the bug 309943.
 *
 * @author cedric dumoulin
 *
 */
public class IPageUtils {

	/**
	 * Get the real model rather than the PageRef. This method is a trick to temporally solve the bug 309943.
	 *
	 * @param page
	 * @return
	 */
	public static Object getRawModel(IPage page) {

		if (page == null) {
			return null;
		}

		Object pageModel = page.getRawModel();
		// Get the real model because of bug
		if (pageModel instanceof PageRef) {
			return ((PageRef) pageModel).getPageIdentifier();
		}
		// do not use trick
		return pageModel;
	}

	/**
	 * Lookup the IPage model corresponding to the identifier from the {@link ISashWindowsContainer}.
	 * The identifier can be either a {@link PageRef} or a emf Diagram. <br>
	 * This method can be used as a hack to bug 401107
	 *
	 * @param container
	 * @param identifier
	 * @return The corresponding IPage, or null if not found.
	 */
	public static IPage lookupModelPage(ISashWindowsContainer container, Object identifier) {

		LookupIPageVisitor visitor = new LookupIPageVisitor(identifier);
		container.visit(visitor);
		return visitor.getResult();
	}

	/**
	 * Obtains a command that will close all of the pages in the given {@code pageManager} that reference the specified {@code pageIdentifier},
	 * regardless of whether they still reference that identifier at the time of execution (this is the "memoization").
	 *
	 * @param domain
	 *            the editing domain in which the command will be executed
	 * @param pageManager
	 *            the page manager for which to construct the command
	 * @param pageIdentifier
	 *            the identifier of the page(s) to be removed
	 *
	 * @return the memoized close-all-pages command, or {@code null} if there are no pages to close
	 */
	public static Command getMemoizedCloseAllPagesCommand(final TransactionalEditingDomain domain, final IPageManager pageManager, final Object pageIdentifier) {
		Command result = null;

		final PageManagerImpl pageMan = (PageManagerImpl) pageManager;

		final Map<PageRef, TabFolder> pages = execute(pageMan, new SashModelOperation<Map<PageRef, TabFolder>>() {

			@Override
			public Map<PageRef, TabFolder> execute(SashWindowsMngr sashWindowsManager) {
				return new DiSwitch<Map<PageRef, TabFolder>>() {

					private Map<PageRef, TabFolder> pages = new HashMap<PageRef, TabFolder>();

					@Override
					public Map<PageRef, TabFolder> defaultCase(EObject object) {
						for (EObject next : object.eContents()) {
							doSwitch(next);
						}
						return pages;
					}

					@Override
					public Map<PageRef, TabFolder> casePageRef(PageRef object) {
						if (object.getPageIdentifier() == pageIdentifier) {
							pages.put(object, object.getParent());
						}
						return pages;
					}
				}.doSwitch(sashWindowsManager.getSashModel());
			}
		});


		if (!pages.isEmpty()) {
			final SashModelOperation<Void> removeOp = new SashModelOperation<Void>() {

				@Override
				public Void execute(SashWindowsMngr sashWindowsManager) {
					SashModel sashModel = sashWindowsManager.getSashModel();
					for (Map.Entry<PageRef, TabFolder> next : pages.entrySet()) {
						PageRef page = next.getKey();
						TabFolder folder = next.getValue();

						folder.getChildren().remove(page);
						sashModel.removeEmptyFolder(folder);
					}
					return null;
				}
			};

			result = new RecordingCommand(domain, "Remove Editor Page(s)") { //$NON-NLS-1$

				@Override
				protected void doExecute() {
					IPageUtils.execute(pageMan, removeOp);
				}
			};
		}

		return result;
	}

	private static <T> T execute(PageManagerImpl pageManager, SashModelOperation<T> sashOperation) {
		try {
			return pageManager.execute(sashOperation);
		} catch (IllegalAccessException e) {
			// Won't happen because this is our own operation
			throw new IllegalAccessError(e.getLocalizedMessage());
		}
	}

	/**
	 * Queries whether the user should be permitted to close a {@code page}.
	 * 
	 * @param page
	 *            a page
	 * @return whether it can be closed
	 */
	public static boolean canClose(IPage page) {
		ICloseablePart closeable = (page instanceof IAdaptable)
				? ((IAdaptable) page).getAdapter(ICloseablePart.class)
				: null;

		return (closeable == null) || closeable.canClose();
	}
}

Back to the top