/******************************************************************************* * Copyright (c) 2011, 2012 Anton Gorenkov * 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: * Anton Gorenkov - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.testsrunner.internal.ui.view.actions; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import org.eclipse.cdt.internal.ui.dialogs.StatusInfo; import org.eclipse.cdt.internal.ui.wizards.dialogfields.DialogField; import org.eclipse.cdt.internal.ui.wizards.dialogfields.IDialogFieldListener; import org.eclipse.cdt.internal.ui.wizards.dialogfields.IListAdapter; import org.eclipse.cdt.internal.ui.wizards.dialogfields.LayoutUtil; import org.eclipse.cdt.internal.ui.wizards.dialogfields.ListDialogField; import org.eclipse.cdt.internal.ui.wizards.dialogfields.StringDialogField; import org.eclipse.cdt.testsrunner.internal.TestsRunnerPlugin; import org.eclipse.cdt.testsrunner.internal.model.TestingSessionsManager; import org.eclipse.cdt.testsrunner.model.ITestingSession; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuCreator; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.StatusDialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Shell; /** * Shows the testing sessions history in drop down list. */ public class HistoryDropDownAction extends Action { /** * The dialog for testing sessions history management. Allows to browse, * activate and remove the selected testing sessions and to set testing * sessions history size limit. */ private class HistoryListDialog extends StatusDialog { /** Max value for the history size limit that may be set via the dialog. */ private static final int MAX_HISTORY_SIZE_LIMIT = 100; /** Testing sessions history list. */ private ListDialogField<ITestingSession> historyList; /** String field that allows to set testing sessions history size limit. */ private StringDialogField historySizeLimitField; /** Currently set testing sessions history size limit. */ private int historySizeLimit; /** The currently selected active testing session. */ private ITestingSession resultActiveSession; /** * Label provider for the dialog testing sessions list. */ private final class TestRunLabelProvider extends LabelProvider { @Override public String getText(Object element) { return ((ITestingSession)element).getName(); } } private HistoryListDialog(Shell shell) { super(shell); setHelpAvailable(false); setTitle(ActionsMessages.HistoryAction_dialog_title); createHistoryList(); createHistorySizeLimitField(); } @Override protected boolean isResizable() { return true; } /** * Fills the testing sessions history list. */ private void createHistoryList() { IListAdapter<ITestingSession> adapter = new IListAdapter<ITestingSession>() { @Override public void customButtonPressed(ListDialogField<ITestingSession> field, int index) { doCustomButtonPressed(index); } @Override public void selectionChanged(ListDialogField<ITestingSession> field) { doSelectionChanged(); } @Override public void doubleClicked(ListDialogField<ITestingSession> field) { doDoubleClicked(); } }; String[] buttonLabels = new String[] { ActionsMessages.HistoryAction_dialog_button_remove, ActionsMessages.HistoryAction_dialog_button_remove_all }; LabelProvider labelProvider = new TestRunLabelProvider(); historyList = new ListDialogField<ITestingSession>(adapter, buttonLabels, labelProvider); historyList.setLabelText(ActionsMessages.HistoryAction_dialog_list_title); historyList.setElements(testingSessionsManager.getSessions()); Object currentEntry = testingSessionsManager.getActiveSession(); ISelection sel = (currentEntry != null) ? new StructuredSelection(currentEntry) : new StructuredSelection(); historyList.selectElements(sel); } /** * Initializes history size limit field of the dialog. */ private void createHistorySizeLimitField() { historySizeLimitField = new StringDialogField(); historySizeLimitField.setLabelText(ActionsMessages.HistoryAction_dialog_limit_label); historySizeLimitField.setDialogFieldListener(new IDialogFieldListener() { @Override public void dialogFieldChanged(DialogField field) { String maxString = historySizeLimitField.getText(); boolean valid; try { historySizeLimit = Integer.parseInt(maxString); valid = historySizeLimit > 0 && historySizeLimit < MAX_HISTORY_SIZE_LIMIT; } catch (NumberFormatException e) { valid = false; } IStatus status = valid ? StatusInfo.OK_STATUS : new StatusInfo(IStatus.ERROR, MessageFormat.format(ActionsMessages.HistoryAction_dialog_limit_label_error, Integer.toString(MAX_HISTORY_SIZE_LIMIT) ) ); updateStatus(status); } }); historySizeLimitField.setText(Integer.toString(testingSessionsManager.getHistorySizeLimit())); } @Override protected Control createDialogArea(Composite parent) { initializeDialogUnits(parent); Composite composite = (Composite) super.createDialogArea(parent); Composite inner = new Composite(composite, SWT.NONE); inner.setLayoutData(new GridData(GridData.FILL_BOTH)); inner.setFont(composite.getFont()); LayoutUtil.doDefaultLayout(inner, new DialogField[] { historyList, new org.eclipse.cdt.internal.ui.wizards.dialogfields.Separator() }, true); LayoutUtil.setHeightHint(historyList.getListControl(null), convertHeightInCharsToPixels(12)); LayoutUtil.setHorizontalGrabbing(historyList.getListControl(null)); Composite additionalControls = new Composite(inner, SWT.NONE); additionalControls.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); LayoutUtil.doDefaultLayout(additionalControls, new DialogField[] { historySizeLimitField }, false); LayoutUtil.setHorizontalGrabbing(historySizeLimitField.getTextControl(null)); applyDialogFont(composite); return composite; } /** * Processes dialog custom button pressing. * * @param index index of the button */ private void doCustomButtonPressed(int index) { switch (index) { case 0: // remove historyList.removeElements(historyList.getSelectedElements()); historyList.selectFirstElement(); break; case 1: // remove all historyList.removeAllElements(); break; default: break; } } /** * Processes double click on the item in dialog. */ private void doDoubleClicked() { okPressed(); } /** * Processes the selection change in the dialog */ private void doSelectionChanged() { List<ITestingSession> selected = historyList.getSelectedElements(); if (selected.size() >= 1) { resultActiveSession = selected.get(0); } else { resultActiveSession = null; } historyList.enableButton(0, selected.size() != 0); } /** * Provides access to the active session currently selected by user. * * @return testing session */ public ITestingSession getResultActiveSession() { return resultActiveSession; } /** * Provides access to the testing sessions history list edited by user. * * @return list of testing sessions */ public List<ITestingSession> getResultSessions() { return historyList.getElements(); } /** * Provides access to value of history size limit specified by user. * * @return history size limit */ public int getResultHistorySizeLimit() { return historySizeLimit; } } /** * Represents a testing sessions history item. */ private class HistoryAction extends Action { /** Testing session of the history item. */ private final ITestingSession testingSession; public HistoryAction(int testingSessionIndex, ITestingSession testingSession) { super("", AS_RADIO_BUTTON); //$NON-NLS-1$ this.testingSession = testingSession; // Generate action text String label = testingSession.getName(); if (testingSessionIndex < 10) { // Add the numerical accelerator label = new StringBuilder().append('&').append(testingSessionIndex).append(' ').append(label).toString(); } setText(label); } @Override public void run() { if (isChecked()) { testingSessionsManager.setActiveSession(testingSession); } } } /** * Provides access to the history list management dialog. */ private class HistoryListAction extends Action { public HistoryListAction() { super(ActionsMessages.HistoryAction_history_item_show_text, AS_RADIO_BUTTON); } @Override public void run() { if (isChecked()) { runHistoryDialog(); } } } /** * Removes the terminated testing sessions from the history list. */ private class ClearAction extends Action { public ClearAction() { setText(ActionsMessages.HistoryAction_history_item_clear_text); boolean enabled = false; for (ITestingSession testingSession : testingSessionsManager.getSessions()) { if (testingSession.isFinished()) { enabled = true; break; } } setEnabled(enabled); } @Override public void run() { List<ITestingSession> remainingSessions = new ArrayList<ITestingSession>(); for (ITestingSession testingSession : testingSessionsManager.getSessions()) { if (!testingSession.isFinished()) { remainingSessions.add(testingSession); } } ITestingSession newActiveSession = remainingSessions.isEmpty() ? null : remainingSessions.get(0); testingSessionsManager.setActiveSession(newActiveSession); testingSessionsManager.setSessions(remainingSessions); } } /** * Represents the testing sessions history menu factory. */ private class HistoryMenuCreator implements IMenuCreator { @Override public Menu getMenu(Menu parent) { return null; } @Override public Menu getMenu(Control parent) { if (menu != null) { menu.dispose(); } final MenuManager manager = new MenuManager(); manager.setRemoveAllWhenShown(true); manager.addMenuListener(new IMenuListener() { @Override public void menuAboutToShow(IMenuManager manager2) { boolean checkOthers = addHistoryItems(manager2); Action others = new HistoryListAction(); others.setChecked(checkOthers); manager2.add(others); manager2.add(new Separator()); manager2.add(new ClearAction()); } private boolean addHistoryItems(IMenuManager manager) { boolean checkOthers = true; int sessionsCount = testingSessionsManager.getSessionsCount(); if (sessionsCount == 0) { return false; } int menuItemsCount = Math.min(sessionsCount, RESULTS_IN_DROP_DOWN_MENU); ITestingSession activeSession = testingSessionsManager.getActiveSession(); int testingSessionIndex = 0; for (ITestingSession testingSession : testingSessionsManager.getSessions()) { if (testingSessionIndex >= menuItemsCount) { break; } HistoryAction action = new HistoryAction(testingSessionIndex, testingSession); boolean check = (testingSession == activeSession); action.setChecked(check); if (check) { checkOthers = false; } manager.add(action); testingSessionIndex++; } return checkOthers; } }); menu = manager.createContextMenu(parent); return menu; } @Override public void dispose() { if (menu != null) { menu.dispose(); menu = null; } } } /** Defines how many history items should be showed in drop down history menu. */ public static final int RESULTS_IN_DROP_DOWN_MENU = 10; /** Accessor to the Testing Sessions Plug-in Manager. */ private TestingSessionsManager testingSessionsManager; /** Required for the history dialog. */ private Shell shell; /** Drop down menu */ private Menu menu; public HistoryDropDownAction(TestingSessionsManager testingSessionsManager, Shell shell) { super(ActionsMessages.HistoryAction_history_text); setToolTipText(ActionsMessages.HistoryAction_history_tooltip); setDisabledImageDescriptor(TestsRunnerPlugin.getImageDescriptor("dlcl16/history_list.gif")); //$NON-NLS-1$ setHoverImageDescriptor(TestsRunnerPlugin.getImageDescriptor("elcl16/history_list.gif")); //$NON-NLS-1$ setImageDescriptor(TestsRunnerPlugin.getImageDescriptor("elcl16/history_list.gif")); //$NON-NLS-1$ this.testingSessionsManager = testingSessionsManager; this.shell = shell; setMenuCreator(new HistoryMenuCreator()); } /** * Shows the testing sessions history dialog. */ private void runHistoryDialog() { HistoryListDialog dialog = new HistoryListDialog(shell); if (dialog.open() == Window.OK) { testingSessionsManager.setHistorySizeLimit(dialog.getResultHistorySizeLimit()); testingSessionsManager.setActiveSession(dialog.getResultActiveSession()); testingSessionsManager.setSessions(dialog.getResultSessions()); } } @Override public void run() { runHistoryDialog(); } }