6 import java
.awt
.event
.ActionEvent
;
7 import java
.awt
.event
.ActionListener
;
8 import java
.beans
.PropertyChangeListener
;
10 import java
.text
.SimpleDateFormat
;
12 import com
.topcoder
.client
.contestant
.ProblemComponentModel
;
13 import com
.topcoder
.shared
.language
.*;
14 import com
.topcoder
.shared
.problem
.*;
15 import com
.topcoder
.shared
.problem
.Renderer
;
16 import com
.topcoder
.client
.contestApplet
.common
.Common
;
17 import com
.topcoder
.client
.contestApplet
.common
.LocalPreferences
;
20 * @author Charles McGarvey
21 * The TopCoder Arena editor plug-in providing support for Vim.
23 * Distributable under the terms and conditions of the 2-clause BSD license;
24 * see the file COPYING for a complete text of the license.
29 * The name and version of this plugin.
31 public final static String version
= "VimCoder 0.1";
34 * The website of the plugin project.
36 public final static String website
= "http://www.dogcows.com/vimcoder";
40 * The first part of the command used to invoke the Vim server.
42 private static String vimCommand
= "gvim";
45 * The path to the main VimCoder directory.
47 private static File rootDir
= new File("~/.vimcoder");
51 * The panel given to the Arena applet when it is requested.
56 * The text widget where log messages are appended.
58 private JTextArea logArea
;
61 * The current editor object (or null if there is none).
63 private Editor editor
;
66 * The configuration panel.
68 private JDialog configDialog
;
72 * The key for the vim command preference.
74 private final static String VIMCOMMAND
= "com.dogcows.VimCoder.config.vimcommand";
77 * The key for the root directory preference.
79 private final static String ROOTDIR
= "com.dogcows.VimCoder.config.rootdir";
82 * The preferences object for storing plugin settings.
84 private static LocalPreferences prefs
= LocalPreferences
.getInstance();
88 * Get the command for invoking vim.
89 * @return The command.
91 public static String
getVimCommand()
97 * Get the storage directory.
98 * @return The directory.
100 public static File
getStorageDirectory()
107 * Instantiate the entry point of the editor plugin. Sets up the log widget
112 logArea
= new JTextArea();
113 logArea
.setForeground(Color
.GREEN
);
114 logArea
.setBackground(Color
.BLACK
);
115 logArea
.setEditable(false);
116 Font font
= new Font("Courier", Font
.PLAIN
, 12);
117 if (font
!= null) logArea
.setFont(font
);
119 panel
= new JPanel(new BorderLayout());
120 panel
.add(new JScrollPane(logArea
), BorderLayout
.CENTER
);
125 * Called by the Arena when the plugin is about to be used.
127 public void startUsing()
129 Runnable task
= new Runnable()
136 if (SwingUtilities
.isEventDispatchThread())
142 SwingUtilities
.invokeLater(task
);
148 * Called by the Arena when the plugin is no longer needed.
150 public void stopUsing()
156 * Called by the Arena to obtain the editor panel which we will use to show
158 * @return The editor panel.
160 public JPanel
getEditorPanel()
166 * Called by the Arena to obtain the current source. This happens when the
167 * user is saving, compiling, and/or submitting.
168 * @return The current source code.
169 * @throws Exception If the source file edited by Vim couldn't be read.
171 public String
getSource() throws Exception
175 String source
= editor
.getSource();
176 logInfo("Source code uploaded to server.");
179 catch (Exception exception
)
181 logError("Failed to get source code: " +
182 exception
.getLocalizedMessage());
188 * Called by the Arena to pass the source it has.
189 * @param source The source code.
191 public void setSource(String source
)
195 editor
.setSource(source
);
196 logInfo("Source code downloaded from server.");
198 catch (Exception exception
)
200 logError("Failed to save the source given by the server: " +
201 exception
.getLocalizedMessage());
207 * Called by the Arena to pass along information about the current problem.
208 * @param component A container for the particulars of the problem.
209 * @param language The currently selected language.
210 * @param renderer A helper object to help format the problem statement.
212 public void setProblemComponent(ProblemComponentModel component
,
218 editor
= new Editor(component
, language
, renderer
);
220 catch (Exception exception
)
222 logError("An error occured while loading the problem: " +
223 exception
.getLocalizedMessage());
228 * Called by the Arena when it's time to show our configuration panel.
230 public void configure()
234 configDialog
= new JDialog();
235 Container pane
= configDialog
.getContentPane();
237 pane
.setPreferredSize(new Dimension(550, 135));
238 pane
.setLayout(new GridBagLayout());
239 pane
.setForeground(Common
.FG_COLOR
);
240 pane
.setBackground(Common
.WPB_COLOR
);
241 GridBagConstraints c
= new GridBagConstraints();
243 JLabel vimCommandLabel
= new JLabel("Vim Command:");
244 vimCommandLabel
.setForeground(Common
.FG_COLOR
);
245 vimCommandLabel
.setAlignmentX(1.0f);
246 c
.fill
= GridBagConstraints
.HORIZONTAL
;
249 c
.insets
= new Insets(5, 5, 5, 5);
250 pane
.add(vimCommandLabel
, c
);
252 final JTextField vimCommandField
= new JTextField(vimCommand
, 25);
256 pane
.add(vimCommandField
, c
);
258 JLabel rootDirLabel
= new JLabel("Storage Directory:");
259 rootDirLabel
.setForeground(Common
.FG_COLOR
);
263 pane
.add(rootDirLabel
, c
);
265 final JTextField rootDirField
= new JTextField(rootDir
.getPath(), 25);
269 pane
.add(rootDirField
, c
);
271 JButton browseButton
= new JButton("Browse");
272 c
.fill
= GridBagConstraints
.NONE
;
276 c
.anchor
= GridBagConstraints
.BASELINE_LEADING
;
277 pane
.add(browseButton
, c
);
279 JButton closeButton
= new JButton("Close");
280 c
.fill
= GridBagConstraints
.HORIZONTAL
;
283 c
.anchor
= GridBagConstraints
.PAGE_END
;
284 pane
.add(closeButton
, c
);
286 JButton saveButton
= new JButton("Save");
290 pane
.add(saveButton
, c
);
292 browseButton
.addActionListener(new ActionListener()
294 public void actionPerformed(ActionEvent actionEvent
)
296 JFileChooser chooser
= new JFileChooser();
297 chooser
.setCurrentDirectory(new File("."));
298 chooser
.setDialogTitle("Choose Storage Directory");
299 chooser
.setFileSelectionMode(JFileChooser
.DIRECTORIES_ONLY
);
300 chooser
.setAcceptAllFileFilterUsed(false);
302 if (chooser
.showOpenDialog(configDialog
) == JFileChooser
.APPROVE_OPTION
)
304 rootDirField
.setText(chooser
.getSelectedFile().getPath());
309 closeButton
.addActionListener(new ActionListener()
311 public void actionPerformed(ActionEvent actionEvent
)
313 configDialog
.dispose();
317 saveButton
.addActionListener(new ActionListener()
319 public void actionPerformed(ActionEvent actionEvent
)
321 prefs
.setProperty(VIMCOMMAND
, vimCommandField
.getText());
322 prefs
.setProperty(ROOTDIR
, rootDirField
.getText());
323 configDialog
.dispose();
327 configDialog
.setTitle("VimCoder Preferences");
329 configDialog
.setLocationByPlatform(true);
330 configDialog
.setModalityType(Dialog
.DEFAULT_MODALITY_TYPE
);
331 configDialog
.setDefaultCloseOperation(WindowConstants
.DISPOSE_ON_CLOSE
);
332 configDialog
.setVisible(true);
337 * Load the local preferences related to this plugin.
339 private void loadConfiguration()
341 String vc
= prefs
.getProperty(VIMCOMMAND
);
342 if (vc
!= null) vimCommand
= vc
;
344 String dir
= prefs
.getProperty(ROOTDIR
);
345 if (dir
!= null) rootDir
= new File(dir
);
350 * A generic logging function, appends text to the text area. A timestamp
351 * is also prepended to the next text.
352 * @param what The text to append.
354 private void log(final String what
)
356 Runnable task
= new Runnable()
360 SimpleDateFormat format
= new SimpleDateFormat("kk:mm:ss");
361 logArea
.append(format
.format(new Date()) + ", " + what
);
364 if (SwingUtilities
.isEventDispatchThread())
370 SwingUtilities
.invokeLater(task
);
375 * Output non-critical messages to the log.
376 * @param what The text of the message.
378 private void logInfo(String what
)
380 log(" INFO: " + what
+ System
.getProperty("line.separator"));
384 * Output potentially important messages to the log.
385 * @param what The text of the message.
387 private void logWarning(String what
)
389 log(" WARN: " + what
+ System
.getProperty("line.separator"));
393 * Output critical messages and errors to the log.
394 * @param what The text of the message.
396 private void logError(String what
)
398 log("ERROR: " + what
+ System
.getProperty("line.separator"));