Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 12141 Details for
Bug 67113
[mavigation] Outline view pane update issue
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
The Browser.java to use when trying to reproduce the bug.
Browser.java (text/plain), 96.82 KB, created by
Victor Costan
on 2004-06-15 10:22:04 EDT
(
hide
)
Description:
The Browser.java to use when trying to reproduce the bug.
Filename:
MIME Type:
Creator:
Victor Costan
Created:
2004-06-15 10:22:04 EDT
Size:
96.82 KB
patch
obsolete
>/* > * LAPIS lightweight structured text processing system Copyright (C) 1998-2002 Carnegie Mellon University, > * Copyright (C) 2003 Massachusetts Institute of Technology. All rights reserved. This library 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, version 2. LAPIS homepage: > * http://graphics.lcs.mit.edu/lapis/ > */ > >package lapis.swing; > >import java.awt.Component; >import java.awt.Cursor; >import java.awt.Dimension; >import java.awt.Frame; >import java.awt.Insets; >import java.awt.Point; >import java.awt.Toolkit; >import java.awt.Window; >import java.awt.event.ActionEvent; >import java.awt.event.FocusAdapter; >import java.awt.event.FocusEvent; >import java.awt.event.FocusListener; >import java.awt.event.KeyEvent; >import java.awt.event.MouseAdapter; >import java.awt.event.MouseEvent; >import java.awt.event.MouseListener; >import java.awt.event.WindowAdapter; >import java.awt.event.WindowEvent; >import java.io.File; >import java.io.IOException; >import java.net.URL; >import java.util.Enumeration; >import java.util.HashSet; >import java.util.Iterator; >import java.util.Set; >import java.util.Vector; > >import javax.swing.AbstractAction; >import javax.swing.Action; >import javax.swing.ButtonGroup; >import javax.swing.ComboBoxModel; >import javax.swing.JButton; >import javax.swing.JComboBox; >import javax.swing.JComponent; >import javax.swing.JEditorPane; >import javax.swing.JFrame; >import javax.swing.JLabel; >import javax.swing.JMenu; >import javax.swing.JMenuBar; >import javax.swing.JMenuItem; >import javax.swing.JOptionPane; >import javax.swing.JPopupMenu; >import javax.swing.JRadioButtonMenuItem; >import javax.swing.JScrollPane; >import javax.swing.JSplitPane; >import javax.swing.JTabbedPane; >import javax.swing.JToggleButton; >import javax.swing.JToolBar; >import javax.swing.KeyStroke; >import javax.swing.SwingConstants; >import javax.swing.SwingUtilities; >import javax.swing.event.HyperlinkListener; >import javax.swing.event.MenuListener; >import javax.swing.event.PopupMenuListener; >import javax.swing.event.UndoableEditEvent; >import javax.swing.event.UndoableEditListener; >import javax.swing.text.BadLocationException; > >import lapis.Arguments; >import lapis.Document; >import lapis.DocumentFactory; >import lapis.DocumentVersion; >import lapis.Interpreter; >import lapis.Main; >import lapis.MutableRegionSet; >import lapis.NamedRegionSet; >import lapis.PatternLibrary; >import lapis.Region; >import lapis.RegionEnumeration; >import lapis.RegionSet; >import lapis.SingleDocVersions; >import lapis.Tool; >import lapis.Toolbox; >import lapis.swing.cluster.ClusterFindReplacePane; >import lapis.tc.TC; >import lapis.ui.ICommandManager; >import lapis.ui.ICoordinator; >import lapis.ui.IEditor; >import lapis.ui.IPane; >import lapis.ui.IPatternManager; >import lapis.ui.ISelectionManager; >import lapis.ui.IStatusManager; >import xlapis.net.URLUtil; >import xlapis.progress.BasicProgressGenerator; >import xlapis.progress.swing.SwingProgressBar; >import xlapis.swing.AcceleratedAction; >import xlapis.swing.AcceleratedMenu; >import xlapis.swing.ActionAdapters; >import xlapis.swing.Animation; >import xlapis.swing.CoalescingUndo; >import xlapis.swing.DisappearingTabbedPane; >import xlapis.swing.FlashingLabel; >import xlapis.swing.HistoryComboBoxModel; >import xlapis.swing.Layout; >import xlapis.swing.Win; >import xlapis.util.History; >import xlapis.util.SafeIteratorSet; >import xlapis.util.Str; >import xlapis.util.Thr; > >public class Browser extends JFrame implements Tool, ICoordinator, ISelectionManager { > public static xlapis.util.Debug debug = xlapis.util.Debug.QUIET; > > //////////////////// > //////////////////// Static initialization > //////////////////// > > static { > SwingCompatibility.disableBuggyFocusManager(); > SwingConfig.restoreLookAndFeel(); > } > > //////////////////// > //////////////////// UI components > //////////////////// > > /** menu and toolbar */ > protected JMenuBar menubar; > protected JToolBar toolbar; > > /** busy animation (a spinning L) */ > protected Animation animation; > > /** Tools menu (stored here because new tools can be added dynamically) */ > protected JMenu toolMenu; > > /** NamedRegionSet mode switches: menu items and toolbar buttons */ > protected JRadioButtonMenuItem manualRadioButtonMenuItem; > protected JRadioButtonMenuItem simulEditRadioButtonMenuItem; > protected ButtonGroup selectionMenuGroup; > > protected JToggleButton manualToggleButton; > protected JToggleButton simulEditToggleButton; > protected ButtonGroup selectionButtonGroup; > > /** Command (URL, filename, Tcl command) */ > protected JComboBox command; > > /** Content type (text, HTML, Java, etc.) */ > protected JComboBox view; > > /** Browser panes */ > private IEditor stdoutPane; > private IEditor stderrPane; > private BrowserScrollPane stdoutScrollPane; > private BrowserScrollPane stderrScrollPane; > > /** Horizontal splitter between browser panes */ > private JSplitPane browserSplitter; > > /** Sidebar */ > protected DisappearingTabbedPane sidebar; > > /** Sidebar pane containing pattern box and pattern library tree */ > protected IPatternManager patternPane; > > /** Vertical splitter between sidebar and browserSplitter */ > protected JSplitPane sidebarSplitter; > > /** Status bar components: progress, status message, feedback button */ > protected SwingProgressBar progressBar; > protected FlashingLabel statusBar; > protected JButton feedbackButton; > > //////////////////// > //////////////////// Auxilliary windows > //////////////////// > > /** Outlier finder (null until first requested) */ > protected OutlierFinder outlierFinder; > > /** Debugging windows (null until first requested) */ > protected DocumentProperties docProps; > protected RegionSetDisplay regionSetDisplay; > > //////////////////// > //////////////////// Unchanging, non-UI objects > //////////////////// > > /** Manual selection mode */ > private final ManualMode manualSelection = new ManualMode(this); > > /** Progress manager */ > protected final BasicProgressGenerator progress = new BasicProgressGenerator(this, true); > > /** Background activity manager */ > private final BackgroundThreads backgroundThreads = new BackgroundThreads(this, progress); > > /** Listeners attached to this browser */ > protected final Set browserListeners = new SafeIteratorSet(); > protected final Set selectionListeners = new SafeIteratorSet(); > > //////////////////// > //////////////////// Mutable state > //////////////////// > > /** Page history (History[Document]) */ > History pageHistory; > > /** Command history (History[String]) */ > protected HistoryComboBoxModel commandHistory; > > /** Interpreter used to evaluate commands. */ > protected Interpreter interpreter; > > /** Browser pane with the focus (either stdoutPane or stderrPane) */ > protected IEditor activePane; > > /** Current selection */ > protected NamedRegionSet selection; > > /** Current selection mode */ > protected SelectionMode selectionMode = manualSelection; > > /** > * If true, Browser ignores caret changes from BrowserPane. Used to prevent selection from changing > * while we're calling replace() or other methods that move the caret as a side-effect. > */ > protected boolean fIgnoreCaretChanges = false; > > /** Enumeration through selection, or null if none in progress */ > protected RegionEnumeration findEnumerator; > > /** reference counts for setBusy() and setHourglass */ > protected int busyCount; > protected int hourglassCount; > > //////////////////// > //////////////////// Help viewer (shared among all browsers) > //////////////////// > > protected static Browser helpViewer; > > //////////////////// > //////////////////// Actions & listeners defined elsewhere > //////////////////// > > private final Action newAction = new FileAction.New(this); > private final Action newBrowserAction = new FileAction.NewBrowser(this); > private final Action openAction = new FileAction.Open(this); > protected final Action saveAction = new FileAction.Save(this); > protected final Action saveAsAction = new FileAction.SaveAs(this); > protected final Action closeAction = new FileAction.Close(this); > private final Action exitAction = new FileAction.Exit(this); > > protected final Action extractAction = new ToolAction.Extract(this); > protected final Action sortAction = new ToolAction.Sort(this); > protected final Action keepAction = new ToolAction.Keep(this); > protected final Action omitAction = new ToolAction.Omit(this); > protected final Action replaceAction = new ToolAction.Replace(this); > protected final Action calcAction = new ToolAction.Calc(this); > > private final HyperlinkListener hyperlinkListener = new BrowserAction.Hyperlink(this); > protected final Toolbox.ToolBoxListener toolboxListener = new ToolAction.ToolboxChange(this); > > protected final Action commandAction = new BrowserAction.Command(this); > protected final Action homeAction = new BrowserAction.Home(this); > private final BrowserAction.Back backAction = new BrowserAction.Back(this); > private final BrowserAction.Forward forwardAction = new BrowserAction.Forward(this); > private final Action reloadAction = new BrowserAction.Reload(this); > private final PopupMenuListener goMenuListener = new BrowserAction.HistoryMenuListener(this); > > protected final EditAction.Cut cutAction = new EditAction.Cut(this); > protected final EditAction.Copy copyAction = new EditAction.Copy(this); > protected final EditAction.Paste pasteAction = new EditAction.Paste(this); > protected final EditAction.Delete deleteAction = new EditAction.Delete(this); > protected final EditAction.SelectAll selectAllAction = new EditAction.SelectAll(this); > protected final EditAction.Undo undoAction = new EditAction.Undo(this); > protected final EditAction.Redo redoAction = new EditAction.Redo(this); > protected final MenuListener editMenuListener = new EditAction.EditMenuListener(this, cutAction, > copyAction, pasteAction, deleteAction, undoAction, redoAction); > > protected final Action downcaseAction = new TransformAction.Downcase(this); > protected final Action upcaseAction = new TransformAction.Upcase(this); > protected final Action sentenceCaseAction = new TransformAction.SentenceCase(this); > protected final Action titleCaseAction = new TransformAction.TitleCase(this); > protected final Action toggleCaseAction = new TransformAction.ToggleCase(this); > > protected final Action preferencesAction = new PreferencesDialog.Preferences(this); > > protected final Action manualAction = new ManualMode.ManualAction(this); > protected final Action simulEditAction = new SimulEditMode.SimulEditAction(this); > > protected final SimulEditMode.IgnoreOutlierAction ignoreOutlierAction = new SimulEditMode.IgnoreOutlierAction( > this); > > protected final ViewAsOutlierAction viewAsOutlierAction = new ViewAsOutlierAction(); > > protected final UnselectAction unselectAction = new UnselectAction(); > > protected final Action findReplaceAction = new FindReplacePane.FindReplaceAction(this); > protected final Action clusterFindReplaceAction = new ClusterFindReplacePane.ClusterFindReplaceAction( > this); > > // private final Action miniBrowserAction = > // new MiniBrowser.MiniBrowserAction(this); > > //////////////////// > //////////////////// Constructor > //////////////////// > > /** > * Make a new Browser. > */ > public Browser() { > super("LAPIS"); > > debug.println("created new browser window"); > Main.windowCreated(this); > > // set window icon > setIconImage(SwingConfig.makeImage("lapis-icon.gif")); > > // Handle window-close operation > setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); > addWindowListener(new WindowAdapter() { > public void windowClosing(WindowEvent evt) { > dispose(); > } > }); > > Toolbox toolbox = Toolbox.getDefaultToolbox(); > toolbox.addToolBoxListener(toolboxListener); > > // Create and lay out the window's components > makeGUI(); > > // Set default window size and position > Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); > d.width -= 100; > d.height -= 100; > setSize(d); > Win.center(this, null); > > // Restore saved window size and position, if any > restoreWindowPositions(); > > // Activate stdout pane > activatePane(stdoutPane, false); > > // Clear the selection > clearSelection(); > > // Reset progress UI > clearBusy(); > clearHourglass(); > clearStatus(); > } > > // new constructor with default access for MultiDocBrowser > protected Browser(String name) { > super(name); > Main.windowCreated(this); > > // set window icon > setIconImage(SwingConfig.makeImage("lapis-icon.gif")); > > // Handle window-close operation > setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); > addWindowListener(new WindowAdapter() { > public void windowClosing(WindowEvent evt) { > dispose(); > } > }); > } > > protected void makePageHistory() { > int pageHistorySize = Integer.parseInt(Main.getConfig().get("shell.page-history-size")); > pageHistory = new History(pageHistorySize); > } > > protected void makePatternPane() { > patternPane = new PatternPane(this); > } > > protected void makeSidebarSplitter() { > sidebarSplitter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, browserSplitter, sidebar); > sidebarSplitter.setOneTouchExpandable(true); > sidebarSplitter.setContinuousLayout(false); > sidebarSplitter.setResizeWeight(0.5); > } > //////////////////// > //////////////////// Making UI components > //////////////////// > protected Layout mainLayout; > > //public void makeGUI (boolean bpdecorations) { > public void makeGUI() { > // Set layout manager > mainLayout = Layout.vertical((JComponent) getContentPane()); > > // Create the page history > makePageHistory(); > //int pageHistorySize = Integer.parseInt > // (Main.getConfig ().get ("shell.page-history-size")); > //pageHistory = new History (pageHistorySize); > > // Create the menubar > menubar = makeMenuBar(); > setJMenuBar(menubar); > > // Create the toolbar and busy animation > toolbar = makeToolBar(); > > animation = new Animation(SwingConfig.makeImage("busy-animated.gif"), SwingConfig > .makeImage("busy-frozen.gif"), false); > > mainLayout.add(Layout.horizontal().add(toolbar).addGlue().add(animation, Layout.FIXED_SIZE, > new Insets(5, 2, 5, 2)).done(), Layout.FIXED_HEIGHT); > > // add Toolbox tools to menu and toolbar > for(Enumeration tools = Toolbox.getDefaultToolbox().tools(); tools.hasMoreElements();) { > Toolbox.Info info = (Toolbox.Info) tools.nextElement(); > addToToolBar(info); > } > > // Create the Command/View As controls > int cmdHistorySize = Integer.parseInt(Main.getConfig().get("browser.command-history-size")); > commandHistory = new HistoryComboBoxModel(cmdHistorySize); > command = new JComboBox(commandHistory); > command.setEditable(true); > CommandEditor editor = new CommandEditor(); > command.setEditor(editor); > editor.addActionListener(commandAction); > > view = new JComboBox(); > view.addItem(new ViewType("Plain Text", "text/plain")); > view.addItem(new ViewType("Web Page", "text/html")); > view.addActionListener(changeViewAction); > > mainLayout.add(Layout.gridbag().setContainerInsets(1, 1, 1, 1).add(new JLabel("Command: "), > Layout.FIXED_WIDTH).add(command).add(new JLabel(" View As: "), Layout.FIXED_WIDTH).add( > view, Layout.FIXED_WIDTH).done(), Layout.FIXED_HEIGHT); > > // Create the browser pane and its decorations > > //if(bpdecorations) > > makeBrowserPaneDecorations(); > > // stdoutPane = makeBrowserPane (); > // stdoutScrollPane = new BrowserScrollPane (stdoutPane, "Output:"); > // stdoutScrollPane.setTitled (false); > // > // // Create the error pane and its decorations > // stderrPane = makeBrowserPane (); > // stderrScrollPane = new BrowserScrollPane (stderrPane, "Error:"); > // stderrScrollPane.setTitled (true); > // > // // Horizontal splitter separating stdout & stderr panes > // browserSplitter = > // new JSplitPane (JSplitPane.VERTICAL_SPLIT, > // stdoutScrollPane, > // stderrScrollPane); > // browserSplitter.setOneTouchExpandable (true); > // browserSplitter.setContinuousLayout (false); > // browserSplitter.setResizeWeight (1.0); > > // Sidebar, with initially one tab: the pattern pane > > makePatternPane(); > > ((JComponent) getContentPane()).registerKeyboardAction(nextMatchAction, KeyStroke.getKeyStroke( > KeyEvent.VK_F3, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); > > JTabbedPane tabs = new JTabbedPane(SwingConstants.TOP); > SwingCompatibility.setScrollTabLayoutPolicy(tabs); > sidebar = new DisappearingTabbedPane(tabs); > sidebar.addTab("Patterns", (JComponent) patternPane.getUIComponent()); > > makeSidebarSplitter(); > // Vertical splitter separating sidebar from browser panes > // sidebarSplitter = new JSplitPane (JSplitPane.HORIZONTAL_SPLIT, > // browserSplitter, sidebar); > // sidebarSplitter.setOneTouchExpandable (true); > // sidebarSplitter.setContinuousLayout (false); > // sidebarSplitter.setResizeWeight (0.5); > > mainLayout.add(sidebarSplitter); > > // Create the status panel > //if( bpdecorations ) > //if( browser.getClass( ).getName( ).equals("lapis.swing.Browser") ) > //{ > progressBar = new BrowserProgressBar(this); > progress.addProgressListener(progressBar); > > statusBar = new FlashingLabel("Initializing..."); > > feedbackButton = new JButton("Feedback"); > feedbackButton.addActionListener(feedbackAction); > > mainLayout.add(Layout.horizontal().setContainerInsets(1, 1, 1, 1).add(progressBar, > Layout.FIXED_SIZE).add(statusBar, new Insets(0, 3, 0, 0)).addGlue().add(feedbackButton, > Layout.FIXED_WIDTH).done(), Layout.FIXED_HEIGHT); > //} > } > > protected void makeBrowserPaneDecorations() { > stdoutPane = makeEditorPane(); > // TODO: (P3) change requirement to IEditor ? > stdoutScrollPane = new BrowserScrollPane((BrowserPane) stdoutPane.getUIComponent(), "Output:"); > stdoutScrollPane.setTitled(false); > > // Create the error pane and its decorations > stderrPane = makeEditorPane(); > // TODO: (P3) change requirement to IEditor ? > stderrScrollPane = new BrowserScrollPane((BrowserPane) stderrPane.getUIComponent(), "Error:"); > stderrScrollPane.setTitled(true); > > // Horizontal splitter separating stdout & stderr panes > browserSplitter = new JSplitPane(JSplitPane.VERTICAL_SPLIT, stdoutScrollPane, stderrScrollPane); > browserSplitter.setOneTouchExpandable(true); > browserSplitter.setContinuousLayout(false); > browserSplitter.setResizeWeight(1.0); > } > > protected void makeToolMenu(JMenuBar menubar) { > toolMenu = new AcceleratedMenu("&Tools"); > toolMenu.add(extractAction); > toolMenu.add(sortAction); > toolMenu.add(keepAction); > toolMenu.add(omitAction); > toolMenu.add(replaceAction); > toolMenu.add(calcAction); > toolMenu.addSeparator(); > menubar.add(toolMenu); > } > > public JMenuBar makeMenuBar() { > JMenuBar menubar = new JMenuBar(); > JMenuItem item; > > JMenu fileMenu = new AcceleratedMenu("&File"); > fileMenu.add(ActionAdapters.toMenuAction(newAction)); > fileMenu.add(ActionAdapters.toMenuAction(openAction)); > fileMenu.add(ActionAdapters.toMenuAction(saveAction)); > fileMenu.add(saveAsAction); > fileMenu.addSeparator(); > fileMenu.add(newBrowserAction); > fileMenu.add(closeAction); > fileMenu.add(exitAction); > menubar.add(fileMenu); > > JMenu editMenu = new AcceleratedMenu("&Edit"); > editMenu.add(undoAction); > editMenu.add(redoAction); > editMenu.addSeparator(); > editMenu.add(ActionAdapters.toMenuAction(cutAction)); > editMenu.add(ActionAdapters.toMenuAction(copyAction)); > editMenu.add(ActionAdapters.toMenuAction(pasteAction)); > editMenu.add(deleteAction); > editMenu.add(selectAllAction); > > JMenu caseMenu = new AcceleratedMenu("C&hange Case"); > caseMenu.add(downcaseAction); > caseMenu.add(upcaseAction); > caseMenu.add(sentenceCaseAction); > caseMenu.add(titleCaseAction); > caseMenu.add(toggleCaseAction); > editMenu.add(caseMenu); > > editMenu.addMenuListener(editMenuListener); > > editMenu.addSeparator(); > editMenu.add(findReplaceAction); > editMenu.add(clusterFindReplaceAction); > > editMenu.addSeparator(); > editMenu.add(preferencesAction); > menubar.add(editMenu); > > JMenu goMenu = new AcceleratedMenu("&Go"); > > backAction.setEnabled(false); > forwardAction.setEnabled(false); > goMenu.add(ActionAdapters.toMenuAction(backAction)); > goMenu.add(ActionAdapters.toMenuAction(forwardAction)); > goMenu.add(ActionAdapters.toMenuAction(reloadAction)); > goMenu.add(ActionAdapters.toMenuAction(homeAction)); > goMenu.add(ActionAdapters.toMenuAction(stopAction)); > goMenu.addSeparator(); > goMenu.getPopupMenu().addPopupMenuListener(goMenuListener); > > menubar.add(goMenu); > > JMenu selectionMenu = new AcceleratedMenu("&Selection"); > selectionMenuGroup = new ButtonGroup(); > selectionMenu.add(manualRadioButtonMenuItem = ActionAdapters.toRadioButtonMenuItem(manualAction, > selectionMenuGroup)); > selectionMenu.add(simulEditRadioButtonMenuItem = ActionAdapters.toRadioButtonMenuItem( > simulEditAction, selectionMenuGroup)); > manualRadioButtonMenuItem.setSelected(true); > > selectionMenu.addSeparator(); > selectionMenu.add(findOutliersAction); > selectionMenu.add(patternEditorAction); > menubar.add(selectionMenu); > > JMenu scriptMenu = new AcceleratedMenu("S&cripts"); > scriptMenu.add(scriptEditorAction); > scriptMenu.add(historyScriptAction); > menubar.add(scriptMenu); > > makeToolMenu(menubar); > > // toolMenu = new AcceleratedMenu ("&Tools"); > // toolMenu.add (extractAction); > // toolMenu.add (sortAction); > // toolMenu.add (keepAction); > // toolMenu.add (omitAction); > // toolMenu.add (replaceAction); > // toolMenu.add (calcAction); > // toolMenu.addSeparator (); > // menubar.add (toolMenu); > > JMenu debugMenu = new AcceleratedMenu("&Debug"); > debugMenu.add(documentPropertiesAction); > debugMenu.add(regionSetDisplayAction); > debugMenu.add(highlightOptionAction); > menubar.add(debugMenu); > > JMenu helpMenu = new AcceleratedMenu("&Help"); > helpMenu.add(new HelpAction("Quick Start Tutorial", "doc/quickstart.html")); > helpMenu.add(new HelpAction("Pattern Language Reference", "doc/patterns/reference.html")); > helpMenu.add(new HelpAction("Command Reference", "doc/commands/reference.html")); > helpMenu.addSeparator(); > helpMenu.add(new HelpAction("LAPIS Website", "http://graphics.lcs.mit.edu/lapis/")); > helpMenu.add(feedbackAction); > helpMenu.addSeparator(); > helpMenu.add(aboutAction); > menubar.add(helpMenu); > > return menubar; > } > > protected void addBackButton(JToolBar toolbar) { > JButton backButton = toolbar.add(ActionAdapters.toToolbarAction(backAction)); > backAction.attachMenu(backButton); > //backButton.setEnabled(true); > } > > protected void addForwardButton(JToolBar toolbar) { > JButton forwardButton = toolbar.add(ActionAdapters.toToolbarAction(forwardAction)); > forwardAction.attachMenu(forwardButton); > } > > protected void addToolBarActions(JToolBar toolbar) { > toolbar.add(ActionAdapters.toToolbarAction(reloadAction)); > toolbar.add(ActionAdapters.toToolbarAction(newAction)); > toolbar.add(ActionAdapters.toToolbarAction(openAction)); > toolbar.add(ActionAdapters.toToolbarAction(saveAction)); > } > > // protected void addReloadAction( JToolBar toolbar ) > // { > // JButton reloadButton = > // toolbar.add(ActionAdapters.toToolbarAction(reloadAction)); > // reloadAction.attachMenu(reloadButton); > // } > > public JToolBar makeToolBar() { > JToolBar toolbar = new JToolBar(JToolBar.HORIZONTAL); > toolbar.setFloatable(false); > > addBackButton(toolbar); > addForwardButton(toolbar); > // JButton backButton = > // toolsbar.add (ActionAdapters.toToolbarAction (backAction)); > // backAction.attachMenu (backButton); > // backButton.setEnabled(true); > // > // JButton forwardButton = > // toolbar.add (ActionAdapters.toToolbarAction (forwardAction)); > // forwardAction.attachMenu (forwardButton); > > //toolbar.add (ActionAdapters.toToolbarAction (reloadAction)); > toolbar.add(ActionAdapters.toToolbarAction(homeAction)); > > JButton stopButton = toolbar.add(ActionAdapters.toToolbarAction(stopAction)); > stopButton.setIcon(SwingConfig.makeIcon("stop.gif")); > stopButton.setDisabledIcon(SwingConfig.makeIcon("gray-stop.gif")); > > toolbar.addSeparator(); > > addToolBarActions(toolbar); > > //toolbar.add (ActionAdapters.toToolbarAction (newAction)); > //toolbar.add (ActionAdapters.toToolbarAction (openAction)); > //toolbar.add (ActionAdapters.toToolbarAction (saveAction)); > > toolbar.addSeparator(); > > toolbar.add(ActionAdapters.toToolbarAction(cutAction)); > toolbar.add(ActionAdapters.toToolbarAction(copyAction)); > toolbar.add(ActionAdapters.toToolbarAction(pasteAction)); > > toolbar.addSeparator(); > > selectionButtonGroup = new ButtonGroup(); > toolbar.add(manualToggleButton = ActionAdapters > .toToggleButton(manualAction, selectionButtonGroup)); > toolbar.add(simulEditToggleButton = ActionAdapters.toToggleButton(simulEditAction, > selectionButtonGroup)); > manualToggleButton.setSelected(true); > > return toolbar; > } > > // adds new tool to ToolBar and ToolMenu > public void addToToolBar(Toolbox.Info info) { > debug.println("Adding " + info.getName() + " to toolbar."); > Action a = new ToolAction.ToolboxAction(this, info); > if(info.getOnMenu()) > toolMenu.add(a); > if(info.getOnToolbar()) > toolbar.add(a); > } > > // removes specified tool from ToolBar and Tool Menu > public void removeFromTools(Toolbox.Info info) { > > debug.println("removing " + info.getName() + " from toolbar."); > if(info.getOnMenu()) { > removeFromToolMenu(info); > } > if(info.getOnToolbar()) { > removeFromToolBar(info); > } > } > > /** > * removes specified Tool from ToolMenu returns the index of the Tool removed if tool exists in Menu > * else returns -1 > */ > > private int removeFromToolMenu(Toolbox.Info info) { > Component[] components = toolMenu.getMenuComponents(); > debug.println("" + components.length + " components on toolMenu"); > for(int i = 0; i < components.length; i++) { > > if(components[i] instanceof JMenuItem) { > debug.println(((JMenuItem) components[i]).getText()); > if(info.getName().equals(((JMenuItem) components[i]).getText())) { > toolMenu.remove(i); > return i; > } > } else { > debug.println(components[i].getClass().getName()); > } > } > return -1; > } > > /** > * @removes specified Tool from ToolBar > * @returns the index of the Tool removed if tool exists in Menu else returns -1 > */ > > private int removeFromToolBar(Toolbox.Info info) { > Component[] components = toolbar.getComponents(); > for(int i = 0; i < components.length; i++) { > if(components[i] instanceof JButton) { > // debug.println(((JButton)components[i]).getText()); > if(info.getName().equals(((JButton) components[i]).getText())) { > toolbar.remove(i); > return i; > } > } > } > return -1; > > } > > public void undo(ActionEvent e) { > undoAction.actionPerformed(e); > } > > /** > * changes the action associated with the Tool name. Tool should remain in the same place on both the > * ToolMenu and the ToolBar > */ > > public void changeInTool(Toolbox.Info info) { > debug.println("changing " + info.getName() + " on toolbar."); > Action a = new ToolAction.ToolboxAction(this, info); > if(info.getOnMenu()) { > int i = removeFromToolMenu(info); > if(i != -1) > toolMenu.insert(a, i); > else > toolMenu.add(a); > } > if(info.getOnToolbar()) { > int i = removeFromToolBar(info); > if(i != -1) > toolbar.add(new JButton(a), i); > else > toolbar.add(a); > } > > } > > public IEditor makeEditorPane() { > // TODO: (P4) not nice > IEditor editor = new EditorPane(this); > BrowserPane bp = (BrowserPane) editor.getUIComponent(); > bp.addHyperlinkListener(hyperlinkListener); > bp.addMouseListener(rightClickListener); > bp.addFocusListener(paneFocusListener); > return editor; > } > > //////////////////// > //////////////////// Configuration > //////////////////// > > protected void doSaveSplitter() { > SwingConfig.saveSplitter("browser.errorSplitter", browserSplitter); > } > > /** > * Save this browser's window location, size, and splitter positions. > * @effects stores location and size information in Main.config and then saves the config to disk. > */ > public void saveWindowPositions() { > if(SwingConfig.inDemoMode()) > return; // don't overwrite existing settings > > SwingConfig.saveLocation("browser.location", this); > SwingConfig.saveSize("browser.size", this); > SwingConfig.saveSplitter("browser.midSplitter", sidebarSplitter); > > doSaveSplitter(); > // TODO: (P2) not nice, should definetly be in the interface > ((PatternPane) patternPane).saveWindowPositions(); > try { > Main.getConfig().save(); > } catch(IOException e) { > debug.report(e); > } > } > > /** > * Load window location, size, and splitter positions from configuration. > * @effects moves and resizes window according to saved location and size found in Main.config. > */ > public void restoreWindowPositions() { > SwingConfig.restoreLocation("browser.location", this); > SwingConfig.restoreSize("browser.size", this); > SwingConfig.restoreSplitter("browser.midSplitter", sidebarSplitter); > SwingConfig.restoreSplitter("browser.errorSplitter", browserSplitter); > // TODO: (P2) not nice, should definetly be in the interface > ((PatternPane) patternPane).restoreWindowPositions(); > } > > //////////////////// > //////////////////// Closing the browser > //////////////////// > > public void dispose() { > if(!FileAction.okToClear(this, documentsInHistory())) > return; > > saveWindowPositions(); > > disposeIfNonNull(outlierFinder); > disposeIfNonNull(docProps); > disposeIfNonNull(regionSetDisplay); > > if(this == helpViewer) > helpViewer = null; > > super.dispose(); > > Main.windowDisposed(Browser.this); > } > > /** > * @return an enumeration of all the Documents in this browser's page history, in no particular order > */ > protected Enumeration documentsInHistory() { > return getPageHistory().elements(); > } > > private void disposeIfNonNull(Window w) { > if(w != null) > w.dispose(); > } > > //////////////////// > //////////////////// Debugging > //////////////////// > > protected Action documentPropertiesAction = new AcceleratedAction("&Document Properties") { > public void actionPerformed(ActionEvent evt) { > if(docProps == null) { > docProps = new DocumentProperties(); > addBrowserListener(docProps); > Win.position(docProps, Browser.this, 1.5, 0.1); > } > docProps.setVisible(true); > docProps.setDocument(getDocument()); > } > }; > > protected Action regionSetDisplayAction = new AcceleratedAction("&Region Set") { > public void actionPerformed(ActionEvent evt) { > if(regionSetDisplay == null) { > regionSetDisplay = new RegionSetDisplay(); > addSelectionListener(regionSetDisplay); > Win.position(regionSetDisplay, Browser.this, -1.5, 0.5); > } > regionSetDisplay.setVisible(true); > regionSetDisplay.setSelection(getSelection()); > } > }; > > protected Action highlightOptionAction = new AcceleratedAction("&Highlight Options") { > public void actionPerformed(ActionEvent evt) { > // TODO: (P3) change this to something nicer ? > BrowserPane browserPane = (BrowserPane) getActiveEditor().getUIComponent(); > browserPane.getFindAndReplaceHighlighter().showOptionDialog(Browser.this); > } > }; > > //////////////////// > //////////////////// Help & feedback > //////////////////// > > public class HelpAction extends AcceleratedAction { > URL url; > > public HelpAction(String caption, String href) { > super(caption); > url = Main.makeURL(href); > } > > public void actionPerformed(ActionEvent evt) { > if(helpViewer == null) { > helpViewer = new Browser(); > Win.position(helpViewer, Browser.this, 1.15, 1.15); > } > > helpViewer.setVisible(true); > helpViewer.getCommandManager().doCommand(url.toString(), null, true); > } > } > > protected Action aboutAction = new AcceleratedAction("&About LAPIS") { > public void actionPerformed(ActionEvent evt) { > try { > URL aboutURL = Main.makeURL("doc/messages/about.html"); > JEditorPane aboutMsg = new JEditorPane(aboutURL); > aboutMsg.setOpaque(false); > aboutMsg.setEditable(false); > JScrollPane aboutScroll = new JScrollPane(aboutMsg); > aboutScroll.setPreferredSize(new Dimension(500, 400)); > > switch(JOptionPane.showOptionDialog(Browser.this, aboutScroll, "About LAPIS", > JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, new String[] {"OK", > "Feedback"}, "OK")) { > case JOptionPane.CLOSED_OPTION: > case 0: // OK > break; > case 1: // Send Feedback > FeedbackForm.showFeedbackForm(Browser.this); > break; > } > > } catch(IOException e) { > FeedbackForm.showExceptionDialog(Browser.this, e); > } > } > }; > > protected Action feedbackAction = new AcceleratedAction("&Feedback and Bug Reports") { > public void actionPerformed(ActionEvent evt) { > FeedbackForm.showFeedbackForm(Browser.this); > } > }; > > //////////////////// > //////////////////// Status bar > //////////////////// > > /** > * Set status bar message. > * @param message Message to display in status bar > * @effects Displays <em>message</em> in status bar. > */ > public void setStatus(String message) { > if(statusBar != null) > statusBar.setText(message); > } > > /** > * Flash the status bar message. > * @effects Causes status bar to flash briefly to call attention to itself. > */ > public void flashStatus() { > statusBar.startFlashing(); > } > > /** > * Clears status bar message. > * @effects Displays no message in status bar. > */ > public void clearStatus() { > if(SwingUtilities.isEventDispatchThread()) { > setStatus(" "); > progressBar.setValue(0); > } else > SwingUtilities.invokeLater(new Runnable() { > public void run() { > setStatus(" "); > progressBar.setValue(0); > } > }); > } > > //////////////////// > //////////////////// Jumping to a URL > //////////////////// > > /** > * Jump to a URL in the background. > * @param url URL to visit > * @effects fetches URL in a background thread. If the fetch succeeds, the resulting page becomes the > * new current document. > */ > public void gotoURL(URL url) { > String cmd = getCommandManager().getInterpreter().quote(url.toString()); > getCommandManager().doCommand(cmd, null, true); > } > > //////////////////// > //////////////////// Getting browser state > //////////////////// > > /** > * Get the current document. > */ > public SwingDocument getDocument() { > IEditor editor = getActiveEditor(); > if(editor == null) > return null; > > return (SwingDocument) editor.getDocument(); > } > > /** > * Get the browser document factory. > */ > public DocumentFactory getFactory() { > return SwingDocument.defaultFactory; > } > > protected Tool makeViewTool() { > return new ViewNow(this); > } > > /** > * Get the browser's page history. > */ > public History getPageHistory() { > return pageHistory; > } > > /** > * Set the browser's history. > */ > public void setPageHistory(History history) { > pageHistory = new History(history); > // TODO: (P3) is this the right thing to do ? > getCommandManager().getInterpreter().setVar(Interpreter.HISTORY_VAR, pageHistory); > } > > /** > * Get URL that generated browser contents. > * @return URL or null if contents not generated by a URL. > */ > public URL getURL() { > SwingDocument doc = getDocument(); > return (doc != null) ? (URL) doc.getProperty(SwingDocument.URLProperty) : null; > } > > /** > * Get active browser pane. > * @return BrowserPane that most recently had the focus. > */ > public IEditor getActiveEditor() { > return activePane; > } > > /** > * Get last pattern entered in pattern box. > * @return contents of pattern box as a string > */ > public String getPattern() { > return patternPane.getPattern(); > } > > /** > * Set pattern in pattern box. > * @param pattern String that should appear in pattern box. > * @param addToHistory true if pattern should be added to the end of the pattern history too. > * @effects sets content of pattern box to <em>pattern</em>, and if <em>addToHistory</em> is > * true, also adds it to the drop-down history. > */ > public void setPattern(String pattern, boolean addToHistory) { > patternPane.setPattern(pattern, addToHistory); > } > > //////////////////// > //////////////////// Visiting new pages in browser > //////////////////// > > /** > * Set the current document. Unlike most methods on Browser, this one can be safely called from any > * thread. > * @param newdoc Document to set > * @effects Browser shows <em>newdoc</em> and adds it to the page history. If <em>newdoc</em> is > * not a SwingDocument, it is copied into a new SwingDocument and the SwingDocument is used > * instead. > */ > public void setDocument(Document newdoc) { > // Convert to a SwingDocument if necessary > final SwingDocument doc = convertToSwingDocument(newdoc); > > getCommandManager().getInterpreter().setVar(Interpreter.DOCUMENT_VAR, doc); > > debug.println("show " + doc); > > SwingDocument olddoc = getDocument(); > if(doc == olddoc) > return; > > if(SwingUtilities.isEventDispatchThread()) > doSetDocument(doc); > else > try { > debug.println("invokeAndWait"); > SwingUtilities.invokeAndWait(new Runnable() { > public void run() { > doSetDocument(doc); > } > }); > } catch(InterruptedException e) { > debug.report(e); > } catch(java.lang.reflect.InvocationTargetException e) { > debug.report(e); > } > } > > private void doSetDocument(SwingDocument doc) { > // Prepare to change current document > loadingDocument(doc); > > SwingDocument error = (SwingDocument) doc.getProperty(Document.StderrProperty); > if(error != null) { > // Load both stdout and error panes, and activate whichever > // one corresponds > SwingDocument stdout = (SwingDocument) doc.getProperty(Document.StdoutProperty); > stdoutPane.setDocument(stdout); > load(stdoutPane, stdout); > > stderrPane.setDocument(error); > load(stderrPane, error); > > activatePane((doc == error) ? stderrPane : stdoutPane, true); > > } else { > // No error document, so just load and activate stdout pane > stdoutPane.setDocument(doc); > load(stdoutPane, doc); > activatePane(stdoutPane, false); > } > } > > /** > * Makes sure document content is loaded. Can be called from any thread. > */ > private void load(final IEditor pane, final SwingDocument doc) { > if(doc.isLoaded()) { > // document is already loaded > debug.println("already loaded " + doc); > if(pane == stdoutPane) > loadedDocument(doc, stdoutPane); > } else { > // load document in background > debug.println("loading " + doc); > getCommandManager().runTask(new RunnableWithExceptions() { > public void run() { > // TODO: (P3) ugly > final BrowserPane bp = (BrowserPane) pane.getUIComponent(); > doc.load(bp.getEditorKit()); > SwingUtilities.invokeLater(new Runnable() { > public void run() { > bp.loadedDocument(doc); > if(pane == stdoutPane) > loadedDocument(doc, stdoutPane); > } > }); > } > }); > } > } > > protected SwingDocument convertToSwingDocument(Document doc) { > if(doc == null || doc instanceof SwingDocument) > return (SwingDocument) doc; > > SwingDocument sdoc = (SwingDocument) getFactory().make(doc); > > // convert stdout & error document as well > Document stdout = (Document) sdoc.getProperty(Document.StdoutProperty); > if(stdout != null) { > sdoc.putProperty(Document.StdoutProperty, (stdout == doc) ? sdoc : getFactory().make(stdout)); > } > Document error = (Document) sdoc.getProperty(Document.StderrProperty); > if(error != null) { > sdoc.putProperty(Document.StderrProperty, (error == doc) ? sdoc : getFactory().make(error)); > } > > // Replace document in history, if it's found there. > replaceDocumentInHistory(doc); > // History history = getPageHistory (); > // if (history.get () == doc) { > // debug.println ("replacing " + doc + " with " + sdoc); > // if( browser.getClass().getName().equals("lapis.swing.Browser")) > // history.replace (sdoc); > // else > // ((MultiDocHistory)history).replace(sdoc, ((MultiDocBrowser)browser).getDocumentList( )); > // } > > return sdoc; > } > > protected void replaceDocumentInHistory(Document doc) { > SwingDocument sdoc = (SwingDocument) getFactory().make(doc); > > History history = getPageHistory(); > if(history.get() == doc) { > debug.println("replacing " + doc + " with " + sdoc); > history.replace(sdoc); > //((MultiDocHistory)history).replace(sdoc, ((MultiDocBrowser)browser).getDocumentList( )); > } > } > > protected void loadingDocument(SwingDocument doc) { > Thr.check(); > > // update status bar > setStatus("Loading " + doc + "..."); > > // Put new doc in the history, if necessary > History history = getPageHistory(); > if(!history.contains(doc)) { > Enumeration droppedDocs = history.forwardElements(); > > if(droppedDocs.hasMoreElements()) { > // newer documents are going to be removed > // from the history. If any are dirty, > // prompt user to save them. > if(!FileAction.okToClear(this, droppedDocs)) > history.add(doc); > else > history.put(doc); > } else { > if(history.isFull()) { > // oldest document is going to disappear. > // check if it's dirty, and expand the history if so. > Document oldest = (Document) history.elements().nextElement(); > if(FileAction.isDirty(oldest)) > history.expand(); > } > > history.put(doc); > } > } > > // Enable/disable navigation actions > backAction.setEnabled(history.canBack()); > forwardAction.setEnabled(history.canForward()); > > // Update content-type > updateContentType(doc); > > // Update title bar (no TitleProperty available yet, but URLProperty > // is) > setTitle(doc); > > // Update command bar > getCommandManager().setCommand(doc.toString(), true); > > // Switch to manual selection mode > // getSelectionMode ().loadingDocument (doc); > > // Clear the selection > clearSelection(); > > // fire event to document listeners > for(Iterator g = browserListeners.iterator(); g.hasNext();) > ((BrowserListener) g.next()).loadingDocument(this, doc); > } > > /** > * Called after the current document has been fully loaded. Always called from event-handling thread. > */ > protected void loadedDocument(SwingDocument doc, IEditor bp) { > Thr.check(); > > // Jump to # anchor specified by URL > URL url = (URL) doc.getProperty(Document.URLProperty); > if(url != null) { > final String ref = url.getRef(); > if(ref != null) > SwingUtilities.invokeLater(new Runnable() { > public void run() { > // TODO: (P3) ugly > BrowserPane browserPane = (BrowserPane) stdoutPane.getUIComponent(); > browserPane.scrollToReference(ref); > } > }); > } > > // Change directory to document's directory > File f = FileAction.getFile(doc); > if(f != null) { > if(!f.isDirectory()) > f = new File(f.getParent()); > debug.println("changing directory to " + f); > getCommandManager().getInterpreter().setVar(Interpreter.CURRENT_DIRECTORY_VAR, f); > } > > // Update title bar -- TitleProperty (if any) is available now > // since document is loaded. > setTitle(doc); > > // Clear the selection again > doClearSelection(); > > // Finish status bar > clearStatus(); > clearHourglass(); > setStatus("Document loaded."); > > // fire event to document listeners > for(Iterator g = browserListeners.iterator(); g.hasNext();) > ((BrowserListener) g.next()).loadedDocument(this, doc); > } > > protected void doClearSelection() { > clearSelection(); > } > > /** > * Set window title bar appropriately for a document. > * @param doc Document to use > * @effects Sets window title to the HTML title, URL, or filename of <em>doc</em>. > */ > public void setTitle(Document doc) { > String title = (String) doc.getProperty(SwingDocument.TitleProperty); > if(title == null) > title = doc.toString(); > setTitle((title != null) ? "LAPIS - " + title : "LAPIS"); > } > > /** > * Sleep until document contents have been fully loaded. > * @effects Blocks until the current document has been fully read from disk, network, or process. > * Returns immediately if current document is already loaded. > */ > public void waitUntilLoaded() { > SwingDocument doc = getDocument(); > while(!doc.isLoaded()) > try { > Thread.sleep(100); > } catch(InterruptedException e) { > throw new ThreadDeath(); > } > } > > /** > * Attach a listener for document-loading events. > * @param listener listener to add > * @effects listener is notified of future document-loading events > */ > public void addBrowserListener(BrowserListener listener) { > browserListeners.add(listener); > } > > /** > * Remove a listener that was listening for document-loading events. > * @param listener listener to remove > * @effects listener is no longer notified of document-loading events > */ > public void removeBrowserListener(BrowserListener listener) { > browserListeners.remove(listener); > } > > //////////////////// > //////////////////// Switching between browser and error pane > //////////////////// > > protected FocusListener paneFocusListener = new FocusAdapter() { > public void focusGained(FocusEvent event) { > // TODO: (P3) is there a more direct way ? > paneGotFocus(((BrowserPane) event.getSource()).getEditor()); > } > }; > > private void paneGotFocus(IEditor pane) { > if(pane == activePane) > return; > > debug.println("focus on " + ((pane == stdoutPane) ? "stdout" : "error")); > > // Clear the old pane's selection > clearSelection(); > > // Activate the new pane > activatePane(pane, stderrScrollPane.isVisible()); > > // Update the UI to match new pane > SwingDocument doc = getDocument(); > updateContentType(doc); > getPageHistory().replace(doc); > } > > private void activatePane(IEditor pane, boolean showErrorPane) { > // show or hide error panel, adjusting error splitter accordingly > int[] locations = getErrorSplitterLocations(); > > stdoutScrollPane.setTitled(showErrorPane); > stdoutScrollPane.setActivated(pane == stdoutPane); > stderrScrollPane.setActivated(pane == stderrPane); > stderrScrollPane.setVisible(showErrorPane); > > browserSplitter.setDividerLocation(locations[showErrorPane ? 0 : 1]); > browserSplitter.setLastDividerLocation(locations[0]); > > activePane = pane; > } > > private int[] getErrorSplitterLocations() { > int bottom = browserSplitter.getHeight() - browserSplitter.getInsets().bottom > - browserSplitter.getDividerSize(); > > int middle = browserSplitter.getDividerLocation(); > > if(Math.abs(middle - bottom) < 15) > middle = browserSplitter.getLastDividerLocation(); > > browserSplitter.setLastDividerLocation(middle); > > return new int[] {middle, bottom}; > } > > //////////////////// > //////////////////// Running and stopping background activities > //////////////////// > > /** > * Action invoked by Stop command. Stops downloading or parsing. > */ > protected Action stopAction = new AcceleratedAction("&Stop", "Stop the current page load") { > public void actionPerformed(ActionEvent evt) { > // TODO: (P5) is this the proper way to stop ONE page ? > getCommandManager().stopAllTasks(); > setStatus("Stopped."); > } > }; > > //////////////////// > //////////////////// Starting and stopping busy animation and hourglass > //////////////////// > > /** > * Turn the busy animation (the spinning L icon) on and off. Multiple callers may request the busy > * animation. This method uses a reference count to keep the icon spinning as long as at least one > * caller still wants it enabled. > * @param enabled true to start the animation, false to stop it > * @effects If <em>enabled</em> is true, starts the busy animation and increments a request count. > * If <em>enabled</em> is false, decrements the request count, and stops the busy animation > * if the count reaches zero. > */ > public void setBusy(boolean enabled) { > if(enabled) > ++busyCount; > else if(--busyCount > 0) > return; // somebody still wants the busy showing > else > busyCount = 0; > > animation.setAnimating(enabled); > stopAction.setEnabled(enabled); > } > > /** > * Stops the busy animation (the spinning L icon) and clears its reference count. > */ > public void clearBusy() { > busyCount = 1; > setBusy(false); > } > > /** > * Turn the wait mouse cursor (an hourglass or watch) on and off. Multiple callers may request the > * wait cursor. This method uses a reference count to keep the wait cursor set as long as at least one > * caller still wants it enabled. > * @param enabled true for the wait cursor, false for the normal cursor > * @effects If <em>enabled</em> is true, sets the wait cursor and increments a request count. If > * <em>enabled</em> is false, decrements the request count, and reverts to the normal > * cursor if the count reaches zero. > */ > public void setHourglass(boolean enabled) { > if(enabled) > ++hourglassCount; > else if(--hourglassCount > 0) > return; // somebody still wants the hourglass showing > else > hourglassCount = 0; > > Cursor c = enabled ? Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR) : Cursor > .getPredefinedCursor(Cursor.TEXT_CURSOR); > > // TODO: (P3) not nice > ((BrowserPane) stdoutPane.getUIComponent()).setCursor(c); > ((BrowserPane) stderrPane.getUIComponent()).setCursor(c); > } > > /** > * Reverts to the normal cursor and clears its reference count. > */ > public void clearHourglass() { > hourglassCount = 1; > setHourglass(false); > } > > //////////////////// > //////////////////// Changing the view (text, html, etc.) > //////////////////// > > public static class ViewType { > public String uiName; // name for UI purposes (e.g. "Text") > public String contentType; // content type (e.g. "text/plain") > > public ViewType(String uiName, String contentType) { > this.uiName = uiName; > this.contentType = contentType; > } > > public String toString() { > return uiName; > } > } > > protected void updateContentType(SwingDocument doc) { > setViewContentType(view, (String) doc.getProperty(SwingDocument.MIMEProperty)); > } > > /** > * Action invoked when user selects a different view from the drop-down list. > */ > protected Action changeViewAction = new AbstractAction() { > public void actionPerformed(ActionEvent evt) { > if(!view.isPopupVisible()) > // if popup menu isn't visible, then > // this action was triggered by code, not > // by the user. Don't do anything. > return; > > ViewType vt = (ViewType) view.getSelectedItem(); > if(vt == null) > return; > > setContentType(vt.contentType); > } > }; > > /** > * Get content type of current document. > * @return MIME content type, e.g. "text/plain" or "text/html". May be null if content type is > * unknown. > */ > public String getContentType() { > SwingDocument doc = getDocument(); > if(doc == null) > return null; > return (String) doc.getProperty(SwingDocument.MIMEProperty); > } > > /** > * Set content type of current document. > * @param contentType MIME content type, e.g. "text/plain" or "text/html". > * @effects if current document's content type is the same as <em>contentType</em>, nothing > * happens. Otherwise, a new document is created of the desired <em>contentType</em>, the > * the curent document is copied into it, and the new document replaces the current document > * in the browser and in the page history. > */ > public void setContentType(String contentType) { > SwingDocument olddoc = getDocument(); > if(olddoc == null) > return; > > // Check whether content type is actually changing > String oldContentType = (String) olddoc.getProperty(SwingDocument.MIMEProperty); > if(contentType.equals(oldContentType)) > return; > > // Re-create document with desired content type > olddoc.putProperty(SwingDocument.MIMEProperty, contentType); > SwingDocument newdoc = (SwingDocument) getFactory().make(olddoc); > debug.println("converted " + olddoc.getClass() + " to " + contentType + " to get " > + newdoc.getClass()); > > // If olddoc was generated by a program, fix up its > // stdout and stderr properties > SwingDocument stdout = (SwingDocument) olddoc.getProperty(Document.StdoutProperty); > SwingDocument stderr = (SwingDocument) olddoc.getProperty(Document.StderrProperty); > if(stdout == olddoc) { > newdoc.putProperty(Document.StdoutProperty, newdoc); > stderr.putProperty(Document.StdoutProperty, newdoc); > } else if(stderr == olddoc) { > newdoc.putProperty(Document.StderrProperty, newdoc); > stdout.putProperty(Document.StderrProperty, newdoc); > newdoc = stdout; > } > > // Replace document in history. > replaceAndSetDocument(newdoc); > // getPageHistory ().replace (newdoc); > // //Set the converted document > // setDocument (newdoc); > > // ((MultiDocHistory)getPageHistory()).replace(newdoc, ((MultiDocBrowser)browser).getDocumentList( > // )); > // ((MultiDocBrowser)browser).setDocument(newdoc, ((MultiDocBrowser)browser).getDocumentList( )); > // Hang on to the selection > NamedRegionSet oldSelection = getSelection(); > > getActiveEditor().grabFocus(); > > // Restore the original selection > //setSelection (oldSelection); > transformSelection(oldSelection); > } > > protected void replaceAndSetDocument(SwingDocument newdoc) { > getPageHistory().replace(newdoc); > //Set the converted document > setDocument(newdoc); > } > > /* > * Set the view drop-down list to match a loaded document's content type. > */ > private static void setViewContentType(JComboBox view, String contentType) { > int selection = 0; // use Text as default if we can't find contentType > > try { > ComboBoxModel model = view.getModel(); > int n = model.getSize(); > for(int i = 0; i < n; ++i) { > ViewType vt = (ViewType) model.getElementAt(i); > if(vt.contentType.equals(contentType)) { > selection = i; > break; > } > } > } catch(NullPointerException e) { > } > > view.setSelectedIndex(selection); > } > > //////////////////// > //////////////////// Tabs on sidebar > //////////////////// > > /** > * Add a tab to the sidebar. > * @param name Name to display in tab > * @param comp Component for tab > * @effects adds <em>comp</em> as a new tab in the sidebar > */ > public void addSidebarTab(String name, JComponent comp) { > if(!sidebar.containsComp(comp)) > sidebar.addTab(name, comp); > sidebar.setSelectedComponent(comp); > resetSidebarSplitter(); > } > > /** > * Remove a tab from the sidebar. > * @param comp Component to remove > * @effects if f <em>comp</em> is a tab in the sidebar, removes it. Otherwise does nothing. > */ > public void removeSidebarTab(JComponent comp) { > sidebar.remove(comp); > } > > /** > * resets the sidebar Splitter to the width of the largest pane in the sidebar if the width is > * currently too small, else leaves the splitter alone. > * @effects sidebarSplitter > */ > > private void resetSidebarSplitter() { > if((sidebar.getMinimumSize().width + 15) > (sidebarSplitter.getWidth() - sidebarSplitter > .getDividerLocation())) { > sidebarSplitter.setDividerLocation(sidebarSplitter.getWidth() > - (sidebar.getMinimumSize().width + 15)); > } > } > > /* > * Search sidebar tabs for the first instance of the specified class. Return null if not found. > */ > private Object findSidebarInstanceOf(Class cls) { > for(Iterator i = sidebar.components(); i.hasNext();) { > Object o = i.next(); > if(cls.isInstance(o)) > return o; > } > return null; > } > > //////////////////// > //////////////////// NamedRegionSet > //////////////////// > > /** > * Set the current selection. > * @param sel new selection > * @effects sets selection in active pane to <em>sel</em> > */ > public void setSelection(NamedRegionSet ns) { > // TODO: support multiple documents > ns = (NamedRegionSet) ns.convert(new SingleDocVersions(getDocument().getVersion())); > this.selection = ns; > changedSelection(); > } > > protected void transformSelection(NamedRegionSet sel) { > this.selection = new NamedRegionSet(RegionSet.EMPTY, sel.getPattern()); > } > > /** > * Clears the selection. > * @effects sets current selection to empty region sets > */ > public void clearSelection() { > debug.println("clear"); > setSelection(new NamedRegionSet(RegionSet.EMPTY)); > } > > /** > * Get the current selection. > * @return current selection > */ > public NamedRegionSet getSelection() { > return selection; > } > > protected Set getSelectionNames() { > TC pattern = selection.getPattern(); > > if(pattern == null) > return null; > > Set set = pattern.getNames(); > if(set == null) > return null; > debug.println(set.toString()); > Set set2 = new HashSet(); > Iterator i = set.iterator(); > while(i.hasNext()) { > Object test = i.next(); > if(test instanceof String) { > String name = (String) test; > debug.println(name); > String name2; > try { > name2 = PatternLibrary.getDocumentLibrary(this.getDocument()).lookup(name); > } catch(PatternLibrary.LookupException e) { > name2 = null; > } > if(name2 == null) > return null; > else > set2.add(name2); > } > } > return set2; > } > > /** > * Called when the selection changes. > */ > protected void changedSelection() { > // debugging > if(debug.printEnabled() && !selection.isEmpty()) > debug.print("selection changed:\n" + selection.highlight(getDocument())); > > // TODO: (P3) not nice > ((PatternPane) patternPane).tree.setSelectedNames(this.getSelectionNames()); > debug.println("selection Names: " + this.getSelectionNames()); > > // TODO: (P3) not nice > BrowserPane browserPane = (BrowserPane) getActiveEditor().getUIComponent(); > > // Reset the next-match search > if(findEnumerator != null) { > findEnumerator = null; > browserPane.getFinderHighlighter().setSelection(null); > } > > // Highlight the matches in the browser pane > browserPane.selectionHighlighter.setSelection(selection); > > // Display number of matches in status bar > int n = selection.getSize(); > if(browserPane.feedbackHighlighter.getSelection() != null) > ++n; > > ((PatternPane) patternPane).setMatchCount(n); > > // Enable or disable tools > boolean nonempty = !selection.isEmpty(); > keepAction.setEnabled(nonempty); > omitAction.setEnabled(nonempty); > sortAction.setEnabled(nonempty); > replaceAction.setEnabled(nonempty); > extractAction.setEnabled(nonempty); > calcAction.setEnabled(nonempty); > > downcaseAction.setEnabled(nonempty); > upcaseAction.setEnabled(nonempty); > sentenceCaseAction.setEnabled(nonempty); > titleCaseAction.setEnabled(nonempty); > toggleCaseAction.setEnabled(nonempty); > > // fire event to selection listeners > for(Iterator g = selectionListeners.iterator(); g.hasNext();) > ((SelectionListener) g.next()).changedSelection(this, selection); > } > > /** > * Action invoked when user clicks on Unselect on context menu. Unselects the region under the cursor. > */ > protected class UnselectAction extends AcceleratedAction { > /** Region that was right-clicked on */ > private Region clickedRegion = null; > > public UnselectAction() { > super("Unselect"); > setEnabled(false); > } > > public void setRegion(Region clickedRegion) { > this.clickedRegion = clickedRegion; > setEnabled(clickedRegion != null); > } > > public void actionPerformed(ActionEvent evt) { > if(clickedRegion == null) > return; > > getSelectionMode().unselectRegion(clickedRegion); > } > } > > /** > * Action invoked when user clicks on Clear NamedRegionSet on context menu. Clears entire selection. > */ > protected Action clearSelectionAction = new AcceleratedAction("Unselect All") { > public void actionPerformed(ActionEvent evt) { > clearSelection(); > } > }; > > /** > * Attach a listener for selection-change events. > * @param listener listener to add > * @effects listener is notified of future selection changes in this browser > */ > public void addSelectionListener(SelectionListener listener) { > selectionListeners.add(listener); > } > > /** > * Remove a listener that was listening for selection-change events. > * @param listener listener to remove > * @effects listener is no longer notified of selection changes in this browser > */ > public void removeSelectionListener(SelectionListener listener) { > selectionListeners.remove(listener); > } > > //////////////////// > //////////////////// NamedRegionSet mode > //////////////////// > > /** > * Get current selection mode. > * @return selection mode > */ > public SelectionMode getSelectionMode() { > return selectionMode; > } > > /** > * Get this browser's manual selection mode. > * @return selection mode to use for manual selection > */ > public ManualMode getManualSelectionMode() { > return manualSelection; > } > > /** > * Set current selection mode. > * @param newMode new selection mode > * @effects sets selection mode to newMode > */ > public void setSelectionMode(SelectionMode newMode) { > SelectionMode oldMode = selectionMode; > > oldMode.leavingMode(newMode); > > if(oldMode instanceof BrowserListener) > removeBrowserListener((BrowserListener) oldMode); > if(oldMode instanceof SelectionListener) > removeSelectionListener((SelectionListener) oldMode); > > selectionMode = newMode; > > if(newMode instanceof BrowserListener) > addBrowserListener((BrowserListener) newMode); > if(newMode instanceof SelectionListener) > addSelectionListener((SelectionListener) newMode); > > newMode.enteringMode(oldMode); > > // TODO: (P3) not nice > BrowserPane browserPane = (BrowserPane) getActiveEditor().getUIComponent(); > browserPane.updateFocus(browserPane.haveFocus); > > if(newMode instanceof SimulEditMode) { > simulEditRadioButtonMenuItem.setSelected(true); > simulEditToggleButton.setSelected(true); > } else { > manualRadioButtonMenuItem.setSelected(true); > manualToggleButton.setSelected(true); > } > } > > //////////////////// > //////////////////// Stepping through selection > //////////////////// > > /** > * Step to next match in selection. > */ > protected Action nextMatchAction = new AcceleratedAction("&Next Match", KeyEvent.VK_F3, 0, > "Jump to the next highlight in selection [F3]") { > public void actionPerformed(ActionEvent event) { > findNext(); > } > }; > > private void findNext() { > NamedRegionSet sel = getSelection(); > if(sel.isEmpty()) { > getToolkit().beep(); > setStatus("No regions are selected."); > return; > } > > Region r; > if(findEnumerator == null) { > findEnumerator = sel.regions(); > r = findEnumerator.first(); > } else > r = findEnumerator.next(); > > debug.println("next match = " + r); > if(r == null) { > getToolkit().beep(); > setStatus("No more regions in selection."); > } else { > // highlight match > // TODO: (P3) not nice > BrowserPane browserPane = (BrowserPane) getActiveEditor().getUIComponent(); > browserPane.getFinderHighlighter().setSelection(new NamedRegionSet(r)); > browserPane.scrollRegionToVisible(r); > } > } > > //////////////////// > //////////////////// Right-click menu > //////////////////// > > /** > * Action invoked when user right-clicks on the browser pane. Pops up a menu showing region set names > * that coincide with the current selection. > */ > private MouseListener rightClickListener = new MouseAdapter() { > public void mousePressed(MouseEvent evt) { > if(SwingUtilities.isRightMouseButton(evt)) > showPopupMenu((Component) evt.getSource(), evt.getX(), evt.getY()); > } > }; > > protected void showPopupMenu(Component source, int x, int y) { > JPopupMenu menu = new JPopupMenu(); > > // TODO: (P3) not nice > BrowserPane browserPane = (BrowserPane) getActiveEditor().getUIComponent(); > Region containsClick = (Region) browserPane.pointToRegion(new Point(x, y)).contains(); > > // test whether user clicked on an outlier record > NamedRegionSet outlierRecords = browserPane.outlierRecordHighlighter.getSelection(); > if(outlierRecords != null && !outlierRecords.isEmpty()) { > Region clickedRecord = outlierRecords.regions(containsClick).first(); > ignoreOutlierAction.setRecord(clickedRecord); > menu.add(ignoreOutlierAction); > } > > // test whether user clicked on an outlier example > if(outlierFinder != null && outlierFinder.isVisible()) { > Region clickedExample = outlierFinder.allExamples.regions(containsClick).first(); > viewAsOutlierAction.setExample(clickedExample); > menu.add(viewAsOutlierAction); > } > > // test whether clicked on a selected region > Region clickedRegion = getSelection().regions(containsClick).first(); > unselectAction.setRegion(clickedRegion); > menu.add(unselectAction); > > menu.add(clearSelectionAction); > > menu.addSeparator(); > menu.add(cutAction); > menu.add(copyAction); > menu.add(pasteAction); > menu.add(deleteAction); > > menu.show(source, x, y); > } > > //////////////////// > //////////////////// Outliers > //////////////////// > > /** > * Action invoked when user clicks on Find Unusual Matches menu item. Pops up a FindOutliers window > */ > protected Action findOutliersAction = new AcceleratedAction("&Unusual Matches", KeyEvent.VK_F9, 0) { > public void actionPerformed(ActionEvent evt) { > if(outlierFinder == null) { > outlierFinder = new OutlierFinder(Browser.this); > addBrowserListener(outlierFinder); > addSelectionListener(outlierFinder); > } > outlierFinder.setVisible(true); > } > }; > > /** > * Action invoked when user clicks on Find Unusual Matches menu item. Pops up a FindOutliers window > */ > public class ViewAsOutlierAction extends AcceleratedAction { > /** Positive or negative example that was right-clicked on */ > private Region clickedExample = null; > > public ViewAsOutlierAction() { > super("Locate in Unusual Matches Window"); > setEnabled(false); > } > > public void setExample(Region clickedExample) { > this.clickedExample = clickedExample; > setEnabled(clickedExample != null); > } > > public void actionPerformed(ActionEvent evt) { > if(outlierFinder == null || !outlierFinder.isVisible() || clickedExample == null) > return; > outlierFinder.jumpTo(clickedExample); > } > } > > //////////////////// > //////////////////// Pattern Editing > //////////////////// > > /** > * Action invoked when user selects Pattern Editor menu option. Pops up a new TCFileEditor window. > */ > protected Action patternEditorAction = new AcceleratedAction("Pattern &Editor") { > public void actionPerformed(ActionEvent evt) { > TCFileEditor tcEditor = getOrMakeTCEditor(); > sidebar.setSelectedComponent(tcEditor); > } > }; > > /** > * Get the current TCFileEditor, or create it if it doesn't exist. > */ > private TCFileEditor getOrMakeTCEditor() { > TCFileEditor tcEditor = (TCFileEditor) findSidebarInstanceOf(TCFileEditor.class); > if(tcEditor == null) { > tcEditor = new TCFileEditor(Browser.this); > tcEditor.setText("# \n# This is a pattern editor.\n#\n\n"); > tcEditor.setDirty(false); > addSidebarTab("Pattern Editor", tcEditor); > } > return tcEditor; > } > > //////////////////// > //////////////////// Scripting > //////////////////// > > /** > * Action invoked when user selects Script Editor menu item. Pops up a new TclFileEditor window. > */ > protected Action scriptEditorAction = new AcceleratedAction("Script &Editor") { > public void actionPerformed(ActionEvent evt) { > TclFileEditor tclEditor = getOrMakeTclEditor(); > sidebar.setSelectedComponent(tclEditor); > } > }; > > /** > * A Tcl comment to help differentiate the script editor panel from a pattern editor panel. > */ > private String tclComment = "# \n# This is a Tcl script editor.\n#\n\n"; > > /** > * Get the current TclFileEditor, or create it if it doesn't exist. > */ > private TclFileEditor getOrMakeTclEditor() { > TclFileEditor tclEditor = (TclFileEditor) findSidebarInstanceOf(TclFileEditor.class); > if(tclEditor == null) { > tclEditor = new TclFileEditor(Browser.this); > tclEditor.setText(tclComment); > addSidebarTab("Script Editor", tclEditor); > } > return tclEditor; > } > > /** > * Action invoked by History to Script command. > */ > protected Action historyScriptAction = new AcceleratedAction("Convert &History to Script") { > public void actionPerformed(ActionEvent evt) { > TclFileEditor tclEditor = getOrMakeTclEditor(); > tclEditor.setText(tclComment + convertHistoryToScript()); > tclEditor.setFile(null); > tclEditor.setDirty(false); > sidebar.setSelectedComponent(tclEditor); > } > }; > > /** > * Convert bookmark history to script. > */ > String convertHistoryToScript() { > History history = getPageHistory(); > String script = ""; > for(Enumeration e = history.elements(); e.hasMoreElements();) { > Document doc = (Document) e.nextElement(); > String cmd = doc.toString(); > script += cmd + "\n"; > } > return script; > } > > //////////////////// > //////////////////// Tool interface for Browser itself > //////////////////// > > /** > * Invoke browser with command-line arguments. > * @param args arguments for browser > * @effects uses the arguments to initialize this browser, then makes this browser visible. > */ > public Document invoke(Arguments args) throws Exception { > if(interpreter == null) > commandManager.setInterpreter(args.getInterpreter()); > > setVisible(true); > > String href = null; > String script = null; > > args.setUsage("Usage: Browser [options]\n" + "\n" + "Options:\n" > + " -help Display this message\n"); > while(args.hasMoreElements()) { > String name = args.nextName(); > if("e".equals(name)) { > script = args.nextString(); > } else if("f".equals(name)) { > script = "source {" + args.nextString() + "}"; > } else if("href".equals(name)) { > href = URLUtil.HrefToURL(args.nextString()).toString(); > } else > args.consume(name); > } > > // prepend href to script > if(href != null) > script = (script != null) ? href + "\nview\n" + script : href; > > Document doc = args.getInput(); > > if(doc != null) > setDocument(doc); > > else if(script == null) > script = Main.makeURLFromProperty("browser.homepage").toString(); > > if(script != null) > getCommandManager().doCommand(script, null, true); > > getActiveEditor().grabFocus(); > return getDocument(); > } > > // retrival of cluster pane for testing > public ClusterFindReplacePane getClusterPane() { > ClusterFindReplacePane cfrp = new ClusterFindReplacePane(this); > if(sidebar.containsComp(cfrp)) > sidebar.add(cfrp); > return cfrp; > > } > > public void replace(NamedRegionSet selection, TransferableSelection mss, String content, > boolean leaveSelected) { > > Vector v = null; > > if(mss != null) { > v = mss.getStrings(); > // if (v.size() != 1 && selection.getSize() != 1 && v.size() != > // selection.getSize()) { //selection.size is jus tthe number of regions. > // FeedbackForm.showMessageDialog( > // browser, > // "Can't paste the " + v.size() + " clipboard items to the " + selection.getSize() + " > // selected > // regions.\n", > // "Wrong Number of Selected Regions", > // JOptionPane.ERROR_MESSAGE); > // return; > // } > if(v.size() != 1 && selection.getSize() != 1 && v.size() != selection.getSize()) { //selection.size > // is > // jus > // tthe > // number > // of > // regions. > FeedbackForm.showMessageDialog(this, "Can't paste the " + v.size() > + " clipboard items to the " + selection.getSize() + " selected regions.\n", > "Wrong Number of Selected Regions", JOptionPane.ERROR_MESSAGE); > return; > } > > } > > int len = 0; > if(content != null && (len = content.length()) == 0) > content = null; > > SwingDocument doc = (SwingDocument) getDocument(); > RegionSet selectedRegions = doc.getCookedView().getVersion().convert( > selection.getSingleDocRegionSet(doc)); > > MultipleSelectionEdit msedit = new MultipleSelectionEdit(this); > UndoableEditListener ul = CoalescingUndo.getUndoableEditListener(doc); > ul.undoableEditHappened(new UndoableEditEvent(this, msedit)); > > fIgnoreCaretChanges = true; > try { > try { > int[] points = new int[selectedRegions.getSize() * 2]; > int pindex = 0; > DocumentVersion oldver = doc.getVersion(); > //MutableRegionSet afterwards = new MutableRegionSet(); > RegionEnumeration re = selectedRegions.regions(); > int adjust = 0; > int i = 0; > int after = 0; > for(Region r = re.firstFast(); r != null; r = re.nextFast()) { > if(mss != null) { > content = (String) v.elementAt(i); > ++i; > if(i >= v.size()) > i = 0; > len = content.length(); > } > > int before = r.getStartLow() + adjust; > > if(r.getStartLow() < r.getEndHigh()) > doc.remove(before, r.getEndHigh() - r.getStartLow()); > if(len > 0) > doc.insertString(before, content, null); > > adjust += len - (r.getEndHigh() - r.getStartLow()); > after = r.getEndHigh() + adjust; > > if(leaveSelected) { > //afterwards.insert(before, after, doc); > points[pindex] = before; > points[pindex + 1] = after; > } else { > //afterwards.insert(after, after, doc); > points[pindex] = after; > points[pindex + 1] = after; > } > pindex += 2; > } > > int[] points_2 = null; > if(mss != null && i == 1) { > points_2 = new int[(v.size() - 1) * 2]; > pindex = 0; > // user pasted N items to 1 location: > // we've already pasted the first item, > // now finish pasting the other N-1, > // leaving a cursor after each paste > doc.insertString(after, "\n", null); > ++adjust; > ++after; > for(int n = v.size(); i < n; ++i) { > content = (String) v.elementAt(i); > len = content.length() + 1; > doc.insertString(after, content + "\n", null); > adjust += len; > after += len; > //afterwards.insert(after - 1, after - 1, doc); > points_2[pindex] = after - 1; > points_2[pindex + 1] = after - 1; > } > } > > MutableRegionSet afterwards = new MutableRegionSet(); > for(pindex = 0; pindex < points.length; pindex += 2) > afterwards.insert(points[pindex], points[pindex + 1], doc.getCookedView() > .getVersion()); > if(points_2 != null) > for(pindex = 0; pindex < points_2.length; pindex += 2) > afterwards.insert(points_2[pindex], points_2[pindex], doc.getCookedView() > .getVersion()); > > RegionSet rsAfterwards = afterwards; > rsAfterwards = doc.getVersion().convert(rsAfterwards.getSingleDocRegionSet(doc)); > > //NamedRegionSet newSelection = new NamedRegionSet(doc, rsAfterwards); > NamedRegionSet newSelection = new NamedRegionSet(rsAfterwards); > this.setSelection(newSelection); > > selectionMode.replaced(selection, newSelection, mss, content); > > } catch(BadLocationException e) { > debug.report(e); > getToolkit().beep(); > } > } finally { > msedit.end(); > fIgnoreCaretChanges = false; > } > } > > /** > * Called when caret moves in active browser pane. > * @param r new position of caret > */ > public void movedCaret(Region r) { > if(fIgnoreCaretChanges) > return; // do nothing > clearSelection(); > getSelectionMode().selectRegion(r); > // TODO: (P3) not nice > BrowserPane browserPane = (BrowserPane) activePane.getUIComponent(); > browserPane.scrollRegionToVisible(r, false); > } > > //////////////// > // implementation of ICoordinator-specific methods (Victor Costan) > //////////////// > private BrowserCommandManager commandManager = new BrowserCommandManager(this); > > public Frame getMainWindow() { > return this; > } > > public IPatternManager getPatternPane() { > return patternPane; > } > > public void closeEditor() { > this.dispose(); > } > > public void dispatchCaretMovedInEditor(Region r) { > this.movedCaret(r); > } > > public void ignoreCaretChanges(boolean flagValue) { > this.fIgnoreCaretChanges = flagValue; > } > > public void addDocumentListener(BrowserListener listener) { > this.addBrowserListener(listener); > } > > public void removeDocumentListener(BrowserListener listener) { > this.removeDocumentListener(listener); > } > > public ICommandManager getCommandManager() { > return commandManager; > } > > public ISelectionManager getSelectionManager() { > return this; > } > > public IStatusManager getStatusManager() { > // TODO Auto-generated method stub > return null; > } > > public void addSidebarTab(String label, IPane pane) { > this.addSidebarTab(label, (JComponent) pane.getUIComponent()); > } > > public void removeSidebarPane(IPane pane) { > this.removeSidebarTab((JComponent) pane.getUIComponent()); > } > > public void caretMoved(Region newPosition) { > this.movedCaret(newPosition); > } > > public ICoordinator getCoordinator() { > return this; > } > > public void replaceSelection(NamedRegionSet selection, String contents, boolean makeSelected) { > this.replace(selection, null, contents, makeSelected); > > } > > public void replaceSelection(NamedRegionSet selection, TransferableSelection sourceSelection, > boolean makeSelected) { > this.replace(selection, sourceSelection, null, makeSelected); > } > > //////////////////////////////////////////////////////////////////////////////////////// > // Browser implementation of ICommandManager > //////////////////////////////////////////////////////////////////////////////////////// > > private class BrowserCommandManager implements ICommandManager { > private ICoordinator coordinator; > private Interpreter interpreter; > // TODO: (P1) get command in this class > > // IPane interface > > public Object getUIComponent() { > return command; > } > public void dispose() { } > public void grabFocus() { > command.grabFocus(); > } > > public BrowserCommandManager(ICoordinator coordinator) { > this.coordinator = coordinator; > } > > > /** > * Get the browser's interpreter. > */ > public Interpreter getInterpreter() { > if(interpreter == null) { > try { > String interpreterClass = Main.getConfig().get("interpreter"); > Interpreter interp = (Interpreter) Class.forName(interpreterClass).newInstance(); > setInterpreter(interp); > } catch(Exception e) { > debug.report(e); > } > } > return interpreter; > } > > /** > * Set the interpreter. > * @param interpreter the interpreter to use in this > * @requires interpreter != <code>null</code>, old interpreter is <code>null</code> > */ > private void setInterpreter(Interpreter interpreter) { > // TODO: (P5) does this ever happen ? > if(this.interpreter == interpreter) > return; > > assert(interpreter != null); > > this.interpreter = interpreter; > interpreter.setVar(Interpreter.FACTORY_VAR, getFactory()); > > // Copy history from interpreter to browser > setPageHistory((History) interpreter.getVar(Interpreter.HISTORY_VAR)); > > // TODO: (P1) binds belong to the concrete class, not to the abstract implementation > > // Bind browser-specific tools > interpreter.bindTool("select", new Select(coordinator)); > interpreter.bindTool("scrollto", new ScrollTo(coordinator)); > interpreter.bindTool("view", Browser.this.makeViewTool()); > > // Hacks for find & replace experiment > interpreter.bindTool("save-clusters", new SaveClusters(coordinator)); > interpreter.bindTool("highlight-replacements", new HighlightReplacements(coordinator)); > > } > > public String getCommand() { > // TODO: (P4) do we always want this ? > Document doc = coordinator.getActiveEditor().getDocument(); > return (doc != null) ? (String) doc.getProperty(Document.CommandProperty) : null; > } > > public void setCommand(String cmd, boolean addToHistory) { > command.getEditor().setItem(cmd); > if(addToHistory && !commandHistory.contains(cmd)) > commandHistory.add(cmd); > } > > public synchronized void runTask(RunnableWithExceptions r) { > backgroundThreads.run(r); > } > > /** > * Stop all background tasks. > * @effects Kills all tasks started with {@link #run}. Also kills the external process generating the > * current document, if any. > */ > public synchronized void stopAllTasks() { > // Kill process associated with current document, if any > Document doc = getDocument(); > if(doc != null) { > Process process = (Process) doc.getProperty(Document.ProcessProperty); > if(process != null) > process.destroy(); > } > > // Interrupt all background threads, forcing I/O operations to throw > // errors and Thr.check() to throw ThreadDeath > backgroundThreads.stop(); > > // Reset progress UI > clearBusy(); > clearStatus(); > } > > /** > * Evaluate a script in the background. > * @param script script code to evaluate (may be multiple lines) > * @effects evaluates script on browser's current document in a background thread. If the script > * returns a result, that result becomes the new current document. > */ > public void eval(final String script) { > // TODO: (P3) is it a good ideea to not be able to run more than one script command at once ? > // TODO: (P3) might want to get eval to create tasks instead of stopping everything > stopAllTasks(); > > setStatus("Evaluating command..."); > > final Document input = getDocument(); > runTask(new RunnableWithExceptions() { > public void run() throws Exception { > final Document output = evalNow(script, input); > clearStatus(); > SwingUtilities.invokeLater(new Runnable() { > public void run() { > if(output != null) { > setDocument(output); > } else { > setStatus("Command returned no data."); > flashStatus(); > } > } > }); > } > }); > } > > /** > * Evaluate a script immediately (not in the background). > * @param script script code to evaluate > * @param input Document to use as input for the script > * @effects evaluates <em>script</em> on <em>input</em>. If the script returns a result, that > * result becomes the new current document. > */ > public Document evalNow(String script, Document input) throws Exception { > Interpreter interp = getCommandManager().getInterpreter(); > > debug.println("eval " + script); > > // Set the interpreter's input document > interp.setVar(Interpreter.DOCUMENT_VAR, input); > > // Evaluate the script and get its output > Object obj = interp.eval(script); > Thr.check(); > > Document output = null; > if(obj != null) { > if(obj instanceof Document) > output = (Document) obj; > else { > String s = obj.toString(); > if(s.length() > 0) > output = getFactory().make(s); > else > output = null; > } > > if(output != null) { > // Attach script to output document, so that > // Reload can rerun this later > if(output.getProperty(Document.CommandProperty) == null) > output.putProperty(Document.CommandProperty, Str.replace(script.trim(), "\n", " ; ")); > } > } > > return output; > } > > public Document doCommand(String script, Document inputDocument, boolean backgroundTask) { > // TODO: (P1) proper implementation of this once we test all usage scenarios > if(backgroundTask) { > if(inputDocument != null) throw new RuntimeException("Victor screwed refactoring!"); > eval(script); > return null; > } > else { > if(inputDocument == null) throw new RuntimeException("Victor screwed refactoring!"); > try { > return evalNow(script, inputDocument); > } > catch(Exception e) { > // TODO: (P1) how was this supposed to be handled, again ? > return null; > } > } > } > } >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 67113
: 12141