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.3";
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
;
50 if (System
.getProperty("os.name").toLowerCase().equals("win"))
52 vimCommand
= "C:\\WINDOWS\\gvim.bat";
54 rootDir
= new File(System
.getProperty("user.home") +
55 System
.getProperty("file.separator") + ".vimcoder");
60 * The panel given to the Arena applet when it is requested.
65 * The text widget where log messages are appended.
67 private JTextArea logArea
;
70 * The current editor object (or null if there is none).
72 private Editor editor
;
75 * The configuration panel.
77 private JDialog configDialog
;
81 * The key for the vim command preference.
83 private final static String VIMCOMMAND
= "com.dogcows.VimCoder.config.vimcommand";
86 * The key for the root directory preference.
88 private final static String ROOTDIR
= "com.dogcows.VimCoder.config.rootdir";
91 * The preferences object for storing plugin settings.
93 private static LocalPreferences prefs
= LocalPreferences
.getInstance();
97 * Get the command for invoking vim.
98 * @return The command.
100 public static String
getVimCommand()
106 * Get the storage directory.
107 * @return The directory.
109 public static File
getStorageDirectory()
116 * Instantiate the entry point of the editor plugin. Sets up the log widget
121 logArea
= new JTextArea();
122 logArea
.setForeground(Color
.GREEN
);
123 logArea
.setBackground(Color
.BLACK
);
124 logArea
.setEditable(false);
125 Font font
= new Font("Courier", Font
.PLAIN
, 12);
126 if (font
!= null) logArea
.setFont(font
);
128 panel
= new JPanel(new BorderLayout());
129 panel
.add(new JScrollPane(logArea
), BorderLayout
.CENTER
);
134 * Called by the Arena when the plugin is about to be used.
136 public void startUsing()
138 Runnable task
= new Runnable()
145 if (SwingUtilities
.isEventDispatchThread())
151 SwingUtilities
.invokeLater(task
);
157 * Called by the Arena when the plugin is no longer needed.
159 public void stopUsing()
165 * Called by the Arena to obtain the editor panel which we will use to show
167 * @return The editor panel.
169 public JPanel
getEditorPanel()
175 * Called by the Arena to obtain the current source. This happens when the
176 * user is saving, compiling, and/or submitting.
177 * @return The current source code.
178 * @throws Exception If the source file edited by Vim couldn't be read.
180 public String
getSource() throws Exception
184 String source
= editor
.getSource();
185 logInfo("Source code uploaded to server.");
188 catch (Exception exception
)
190 logError("Failed to get source code: " +
191 exception
.getLocalizedMessage());
197 * Called by the Arena to pass the source it has.
198 * @param source The source code.
200 public void setSource(String source
)
204 editor
.setSource(source
);
205 logInfo("Source code downloaded from server.");
207 catch (Exception exception
)
209 logError("Failed to save the source given by the server: " +
210 exception
.getLocalizedMessage());
216 * Called by the Arena to pass along information about the current problem.
217 * @param component A container for the particulars of the problem.
218 * @param language The currently selected language.
219 * @param renderer A helper object to help format the problem statement.
221 public void setProblemComponent(ProblemComponentModel component
,
227 editor
= new Editor(component
, language
, renderer
);
229 catch (Exception exception
)
231 logError("An error occured while loading the problem: " +
232 exception
.getLocalizedMessage());
237 * Called by the Arena when it's time to show our configuration panel.
239 public void configure()
243 configDialog
= new JDialog();
244 Container pane
= configDialog
.getContentPane();
246 pane
.setPreferredSize(new Dimension(550, 135));
247 pane
.setLayout(new GridBagLayout());
248 pane
.setForeground(Common
.FG_COLOR
);
249 pane
.setBackground(Common
.WPB_COLOR
);
250 GridBagConstraints c
= new GridBagConstraints();
252 JLabel rootDirLabel
= new JLabel("Storage Directory:", SwingConstants
.RIGHT
);
253 rootDirLabel
.setForeground(Common
.FG_COLOR
);
254 c
.fill
= GridBagConstraints
.HORIZONTAL
;
255 c
.insets
= new Insets(5, 5, 5, 5);
259 pane
.add(rootDirLabel
, c
);
261 final JTextField rootDirField
= new JTextField(rootDir
.getPath(), 25);
264 pane
.add(rootDirField
, c
);
266 JButton browseButton
= new JButton("Browse");
269 c
.anchor
= GridBagConstraints
.BASELINE_LEADING
;
270 pane
.add(browseButton
, c
);
272 JLabel vimCommandLabel
= new JLabel("Vim Command:", SwingConstants
.RIGHT
);
273 vimCommandLabel
.setForeground(Common
.FG_COLOR
);
274 c
.fill
= GridBagConstraints
.HORIZONTAL
;
277 pane
.add(vimCommandLabel
, c
);
279 final JTextField vimCommandField
= new JTextField(vimCommand
, 25);
283 pane
.add(vimCommandField
, c
);
285 JButton closeButton
= new JButton("Cancel");
286 c
.fill
= GridBagConstraints
.NONE
;
290 c
.anchor
= GridBagConstraints
.EAST
;
291 pane
.add(closeButton
, c
);
293 JButton saveButton
= new JButton("Save");
294 c
.fill
= GridBagConstraints
.HORIZONTAL
;
297 c
.anchor
= GridBagConstraints
.EAST
;
298 pane
.add(saveButton
, c
);
299 configDialog
.getRootPane().setDefaultButton(saveButton
);
301 browseButton
.addActionListener(new ActionListener()
303 public void actionPerformed(ActionEvent actionEvent
)
305 JFileChooser chooser
= new JFileChooser();
306 chooser
.setCurrentDirectory(new File("."));
307 chooser
.setDialogTitle("Choose Storage Directory");
308 chooser
.setFileSelectionMode(JFileChooser
.DIRECTORIES_ONLY
);
309 chooser
.setAcceptAllFileFilterUsed(false);
311 if (chooser
.showOpenDialog(configDialog
) == JFileChooser
.APPROVE_OPTION
)
313 rootDirField
.setText(chooser
.getSelectedFile().getPath());
318 closeButton
.addActionListener(new ActionListener()
320 public void actionPerformed(ActionEvent actionEvent
)
322 configDialog
.dispose();
326 saveButton
.addActionListener(new ActionListener()
328 public void actionPerformed(ActionEvent actionEvent
)
330 prefs
.setProperty(VIMCOMMAND
, vimCommandField
.getText());
331 prefs
.setProperty(ROOTDIR
, rootDirField
.getText());
332 configDialog
.dispose();
336 configDialog
.setTitle("VimCoder Preferences");
338 configDialog
.setLocationByPlatform(true);
339 configDialog
.setModalityType(Dialog
.DEFAULT_MODALITY_TYPE
);
340 configDialog
.setDefaultCloseOperation(WindowConstants
.DISPOSE_ON_CLOSE
);
341 configDialog
.setVisible(true);
346 * Load the local preferences related to this plugin.
348 private void loadConfiguration()
350 String vc
= prefs
.getProperty(VIMCOMMAND
);
351 if (vc
!= null) vimCommand
= vc
;
353 String dir
= prefs
.getProperty(ROOTDIR
);
354 if (dir
!= null) rootDir
= new File(dir
);
359 * A generic logging function, appends text to the text area. A timestamp
360 * is also prepended to the next text.
361 * @param what The text to append.
363 private void log(final String what
)
365 Runnable task
= new Runnable()
369 SimpleDateFormat format
= new SimpleDateFormat("kk:mm:ss");
370 logArea
.append(format
.format(new Date()) + ", " + what
);
373 if (SwingUtilities
.isEventDispatchThread())
379 SwingUtilities
.invokeLater(task
);
384 * Output non-critical messages to the log.
385 * @param what The text of the message.
387 private void logInfo(String what
)
389 log(" INFO: " + 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"));