2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
42
package org.netbeans.modules.options.codetemplates;
44
import java.awt.Component;
45
import java.awt.event.ActionEvent;
46
import java.awt.event.ActionListener;
47
import java.awt.event.KeyEvent;
48
import java.awt.event.KeyListener;
49
import java.util.ArrayList;
50
import java.util.Collections;
51
import java.util.List;
52
import javax.swing.AbstractButton;
53
import javax.swing.JEditorPane;
54
import javax.swing.JLabel;
55
import javax.swing.JPanel;
56
import javax.swing.JTabbedPane;
57
import javax.swing.KeyStroke;
58
import javax.swing.ListSelectionModel;
59
import javax.swing.SwingUtilities;
60
import javax.swing.event.ListSelectionEvent;
61
import javax.swing.event.ListSelectionListener;
62
import javax.swing.table.TableColumn;
63
import javax.swing.text.JTextComponent;
64
import org.netbeans.api.editor.EditorRegistry;
65
import org.netbeans.editor.BaseDocument;
66
import org.netbeans.spi.options.OptionsPanelController;
67
import org.openide.DialogDisplayer;
68
import org.openide.NotifyDescriptor;
69
import org.openide.NotifyDescriptor.InputLine;
70
import org.openide.awt.Mnemonics;
71
import org.openide.text.CloneableEditorSupport;
72
import org.openide.util.NbBundle;
75
* Implementation of one panel in Options Dialog.
79
public class CodeTemplatesPanel extends JPanel implements
80
ActionListener, ListSelectionListener, KeyListener {
82
private CodeTemplatesModel model;
85
* Creates new form CodeTemplatesPanel.
87
public CodeTemplatesPanel () {
90
setName(loc("Code_Templates_Tab")); //NOI18N
91
loc(lLanguage, "Language"); //NOI18N
92
loc(lTemplates, "Templates"); //NOI18N
93
loc(bNew, "New"); //NOI18N
94
loc(bRemove, "Remove"); //NOI18N
95
loc(lExplandTemplateOn, "ExpandTemplateOn"); //NOI18N
96
loc(tabPane, 0, "Expanded_Text", epExpandedText); //NOI18N
97
loc(tabPane, 1, "Description", epDescription); //NOI18N
98
tabPane.getAccessibleContext().setAccessibleName(loc("AN_tabPane")); //NOI18N
99
tabPane.getAccessibleContext().setAccessibleDescription(loc("AD_tabPane")); //NOI18N
101
cbExpandTemplateOn.addItem(loc("SPACE")); //NOI18N
102
cbExpandTemplateOn.addItem(loc("S-SPACE")); //NOI18N
103
cbExpandTemplateOn.addItem(loc("TAB")); //NOI18N
104
cbExpandTemplateOn.addItem(loc("ENTER")); //NOI18N
106
bRemove.setEnabled (false);
107
tTemplates.getTableHeader().setReorderingAllowed(false);
108
tTemplates.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
110
epExpandedText.addKeyListener(this);
111
epDescription.addKeyListener(this);
114
private static String loc (String key) {
115
return NbBundle.getMessage (CodeTemplatesPanel.class, key);
118
private static void loc(Component c, String key) {
119
if (!(c instanceof JLabel)) {
120
c.getAccessibleContext().setAccessibleName(loc("AN_" + key)); //NOI18N
121
c.getAccessibleContext().setAccessibleDescription(loc("AD_" + key)); //NOI18N
123
if (c instanceof AbstractButton) {
124
Mnemonics.setLocalizedText((AbstractButton) c, loc("CTL_" + key)); //NOI18N
126
Mnemonics.setLocalizedText((JLabel) c, loc("CTL_" + key)); //NOI18N
130
private static void loc(JTabbedPane p, int tabIdx, String key, JEditorPane ep) {
131
JLabel label = new JLabel(); // Only for setting tab names
133
String tabName = loc("CTL_" + key); //NOI18N
134
Mnemonics.setLocalizedText(label, tabName);
135
p.setTitleAt(tabIdx, label.getText());
137
int idx = Mnemonics.findMnemonicAmpersand(tabName);
138
if (idx != -1 && idx + 1 < tabName.length()) {
139
char ch = Character.toUpperCase(tabName.charAt(idx + 1));
140
p.setMnemonicAt(tabIdx, ch);
141
ep.setFocusAccelerator(ch);
145
// OptionsCategory.Panel ...................................................
148
model = new CodeTemplatesModel ();
150
cbLanguage.removeActionListener (this);
151
bNew.removeActionListener (this);
152
bRemove.removeActionListener (this);
153
cbExpandTemplateOn.removeActionListener (this);
154
tTemplates.getSelectionModel ().removeListSelectionListener (this);
156
cbLanguage.removeAllItems ();
157
List<String> languages = new ArrayList<String>(model.getLanguages ());
158
Collections.sort (languages);
159
for(String l : languages) {
160
cbLanguage.addItem(l);
162
KeyStroke expander = model.getExpander ();
163
if (KeyStroke.getKeyStroke (KeyEvent.VK_SPACE, KeyEvent.SHIFT_MASK).equals (expander))
164
cbExpandTemplateOn.setSelectedIndex (1);
166
if (KeyStroke.getKeyStroke (KeyEvent.VK_TAB, 0).equals (expander))
167
cbExpandTemplateOn.setSelectedIndex (2);
169
if (KeyStroke.getKeyStroke (KeyEvent.VK_ENTER, 0).equals (expander))
170
cbExpandTemplateOn.setSelectedIndex (3);
172
cbExpandTemplateOn.setSelectedIndex (0);
174
cbLanguage.addActionListener (this);
175
bNew.addActionListener (this);
176
bRemove.addActionListener (this);
177
cbExpandTemplateOn.addActionListener (this);
178
tTemplates.getSelectionModel ().addListSelectionListener (this);
180
// Pre-select a language
181
String defaultSelectedLang = null;
182
JTextComponent pane = EditorRegistry.lastFocusedComponent();
184
String mimeType = (String)pane.getDocument().getProperty("mimeType"); // NOI18N
185
if (mimeType != null) {
186
defaultSelectedLang = model.findLanguage(mimeType);
189
if (defaultSelectedLang == null) {
190
defaultSelectedLang = model.findLanguage("text/x-java"); //NOI18N
192
if (defaultSelectedLang == null) {
193
defaultSelectedLang = model.findLanguage("text/x-ruby"); //NOI18N
195
if (defaultSelectedLang == null) {
196
defaultSelectedLang = model.findLanguage("text/x-c++"); //NOI18N
198
if (defaultSelectedLang == null && model.getLanguages().size() > 0) {
199
defaultSelectedLang = model.getLanguages().get(0);
201
if (defaultSelectedLang != null) {
202
cbLanguage.setSelectedItem(defaultSelectedLang);
206
void applyChanges () {
208
saveCurrentTemplate ();
209
model.saveChanges ();
216
boolean dataValid () {
220
boolean isChanged () {
221
if (model == null) return false;
222
return model.isChanged ();
225
// ActionListener ..........................................................
227
public void actionPerformed (ActionEvent e) {
228
if (e.getSource () == cbLanguage) {
229
saveCurrentTemplate ();
230
final String language = (String) cbLanguage.getSelectedItem ();
231
final CodeTemplatesModel.TM tableModel = model.getTableModel (language);
233
tTemplates.setModel (tableModel);
234
TableColumn c1 = tTemplates.getTableHeader().getColumnModel().getColumn(0);
236
c1.setPreferredWidth(100);
237
c1.setResizable(true);
239
TableColumn c2 = tTemplates.getTableHeader().getColumnModel().getColumn(1);
241
c2.setPreferredWidth(250);
242
c2.setResizable(true);
244
TableColumn c3 = tTemplates.getTableHeader().getColumnModel().getColumn(2);
246
c3.setPreferredWidth(250);
247
c3.setResizable(true);
249
SwingUtilities.invokeLater (new Runnable () {
251
epDescription.setEditorKit(CloneableEditorSupport.getEditorKit("text/html")); //NOI18N
252
epExpandedText.setEditorKit(CloneableEditorSupport.getEditorKit(model.getMimeType (language)));
253
if (tableModel.getRowCount () > 0) {
255
tTemplates.getSelectionModel ().setSelectionInterval (0, 0);
262
if (e.getSource () == bNew) {
263
saveCurrentTemplate ();
264
InputLine descriptor = new InputLine (
265
loc ("CTL_Enter_template_name"),
266
loc ("CTL_New_template_dialog_title")
268
if (DialogDisplayer.getDefault().notify(descriptor) == InputLine.OK_OPTION ) {
269
String newAbbrev = descriptor.getInputText().trim();
271
if (newAbbrev.length() == 0) {
272
DialogDisplayer.getDefault ().notify (
273
new NotifyDescriptor.Message (
274
loc ("CTL_Empty_template_name"),
275
NotifyDescriptor.ERROR_MESSAGE
279
CodeTemplatesModel.TM tableModel = (CodeTemplatesModel.TM)tTemplates.getModel();
280
int i, rows = tableModel.getRowCount ();
281
for (i = 0; i < rows; i++) {
282
String abbrev = (String) tableModel.getAbbreviation(i);
283
if (newAbbrev.equals (abbrev)) {
284
DialogDisplayer.getDefault ().notify (
285
new NotifyDescriptor.Message (
286
loc ("CTL_Duplicate_template_name"),
287
NotifyDescriptor.ERROR_MESSAGE
295
int rowIdx = tableModel.addCodeTemplate(newAbbrev);
296
tTemplates.getSelectionModel().setSelectionInterval(rowIdx, rowIdx);
300
SwingUtilities.invokeLater (new Runnable () {
302
// Scroll to the bottom
303
spTemplates.getVerticalScrollBar().setValue(
304
spTemplates.getVerticalScrollBar().getMaximum());
306
// Show the extpanded text and place the focus in it
307
tabPane.setSelectedIndex(0);
308
epExpandedText.requestFocus ();
312
} else if (e.getSource () == bRemove) {
313
CodeTemplatesModel.TM tableModel = (CodeTemplatesModel.TM)tTemplates.getModel();
314
int index = tTemplates.getSelectedRow ();
315
tableModel.removeCodeTemplate(index);
318
if (index < tTemplates.getModel ().getRowCount ()) {
319
tTemplates.getSelectionModel ().setSelectionInterval(index, index);
320
} else if (tTemplates.getModel ().getRowCount () > 0) {
321
tTemplates.getSelectionModel ().setSelectionInterval (
322
tTemplates.getModel ().getRowCount () - 1,
323
tTemplates.getModel ().getRowCount () - 1
326
bRemove.setEnabled (false);
328
} else if (e.getSource () == cbExpandTemplateOn) {
329
switch (cbExpandTemplateOn.getSelectedIndex ()) {
331
model.setExpander (KeyStroke.getKeyStroke (KeyEvent.VK_SPACE, 0));
334
model.setExpander (KeyStroke.getKeyStroke (KeyEvent.VK_SPACE, KeyEvent.SHIFT_MASK));
337
model.setExpander (KeyStroke.getKeyStroke (KeyEvent.VK_TAB, 0));
340
model.setExpander (KeyStroke.getKeyStroke (KeyEvent.VK_ENTER, 0));
346
public void valueChanged (ListSelectionEvent e) {
347
// new line in code templates table has been selected
348
int index = tTemplates.getSelectedRow ();
350
epDescription.setText(""); //NOI18N
351
epExpandedText.setText(""); //NOI18N
352
bRemove.setEnabled (false);
357
saveCurrentTemplate ();
359
// Show details of the newly selected code tenplate
360
CodeTemplatesModel.TM tableModel = (CodeTemplatesModel.TM)tTemplates.getModel();
361
epDescription.setText(tableModel.getDescription(index));
362
epExpandedText.setText(tableModel.getText(index));
363
bRemove.setEnabled(true);
367
private int lastIndex = -1;
369
private void saveCurrentTemplate() {
374
CodeTemplatesModel.TM tableModel = (CodeTemplatesModel.TM)tTemplates.getModel();
375
tableModel.setDescription(lastIndex, epDescription.getText());
376
tableModel.setText(lastIndex, epExpandedText.getText());
378
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
381
public void keyTyped(KeyEvent e) {
384
public void keyPressed(KeyEvent e) {
385
// XXX: hack for #113802
386
if (e.getKeyCode() == 32) {
391
public void keyReleased(KeyEvent e) {
394
// UI form .................................................................
396
/** This method is called from within the constructor to
397
* initialize the form.
398
* WARNING: Do NOT modify this code. The content of this method is
399
* always regenerated by the Form Editor.
401
// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
402
private void initComponents() {
404
lLanguage = new javax.swing.JLabel();
405
cbLanguage = new javax.swing.JComboBox();
406
lTemplates = new javax.swing.JLabel();
407
spTemplates = new javax.swing.JScrollPane();
408
tTemplates = new javax.swing.JTable();
409
bNew = new javax.swing.JButton();
410
bRemove = new javax.swing.JButton();
411
lExplandTemplateOn = new javax.swing.JLabel();
412
cbExpandTemplateOn = new javax.swing.JComboBox();
413
tabPane = new javax.swing.JTabbedPane();
414
spExpandedText = new javax.swing.JScrollPane();
415
epExpandedText = new javax.swing.JEditorPane();
416
spDescription = new javax.swing.JScrollPane();
417
epDescription = new javax.swing.JEditorPane();
419
lLanguage.setLabelFor(cbLanguage);
420
lLanguage.setText("Language:");
422
cbLanguage.setNextFocusableComponent(tTemplates);
424
lTemplates.setLabelFor(tTemplates);
425
lTemplates.setText("Templates:");
427
tTemplates.setModel(new javax.swing.table.DefaultTableModel(
435
"Abbreviation", "Expanded Text", "Description"
438
Class[] types = new Class [] {
439
java.lang.String.class, java.lang.String.class, java.lang.String.class
441
boolean[] canEdit = new boolean [] {
445
public Class getColumnClass(int columnIndex) {
446
return types [columnIndex];
449
public boolean isCellEditable(int rowIndex, int columnIndex) {
450
return canEdit [columnIndex];
453
tTemplates.setFocusCycleRoot(true);
454
spTemplates.setViewportView(tTemplates);
457
bNew.setNextFocusableComponent(bRemove);
459
bRemove.setText("Remove");
461
lExplandTemplateOn.setLabelFor(cbExpandTemplateOn);
462
lExplandTemplateOn.setText("Expand Template on:");
464
cbExpandTemplateOn.setNextFocusableComponent(bNew);
466
tabPane.setTabLayoutPolicy(javax.swing.JTabbedPane.SCROLL_TAB_LAYOUT);
467
tabPane.setFocusCycleRoot(true);
468
tabPane.setNextFocusableComponent(cbExpandTemplateOn);
470
spExpandedText.setViewportView(epExpandedText);
472
tabPane.addTab("tab1", spExpandedText);
474
spDescription.setViewportView(epDescription);
476
tabPane.addTab("tab2", spDescription);
478
org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
479
this.setLayout(layout);
480
layout.setHorizontalGroup(
481
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
482
.add(layout.createSequentialGroup()
483
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
484
.add(layout.createSequentialGroup()
486
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
487
.add(cbLanguage, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
489
.add(layout.createSequentialGroup()
490
.add(lExplandTemplateOn)
491
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
492
.add(cbExpandTemplateOn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
493
.add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
494
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
495
.add(org.jdesktop.layout.GroupLayout.LEADING, tabPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE)
496
.add(spTemplates, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE))
497
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
498
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING, false)
499
.add(bRemove, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
500
.add(bNew, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 122, Short.MAX_VALUE))
504
layout.setVerticalGroup(
505
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
506
.add(layout.createSequentialGroup()
507
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
509
.add(cbLanguage, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
510
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
512
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
513
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
514
.add(layout.createSequentialGroup()
516
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
518
.add(spTemplates, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 109, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
519
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
520
.add(tabPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 218, Short.MAX_VALUE)
521
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
522
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
523
.add(lExplandTemplateOn)
524
.add(cbExpandTemplateOn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
526
}// </editor-fold>//GEN-END:initComponents
528
// Variables declaration - do not modify//GEN-BEGIN:variables
529
private javax.swing.JButton bNew;
530
private javax.swing.JButton bRemove;
531
private javax.swing.JComboBox cbExpandTemplateOn;
532
private javax.swing.JComboBox cbLanguage;
533
private javax.swing.JEditorPane epDescription;
534
private javax.swing.JEditorPane epExpandedText;
535
private javax.swing.JLabel lExplandTemplateOn;
536
private javax.swing.JLabel lLanguage;
537
private javax.swing.JLabel lTemplates;
538
private javax.swing.JScrollPane spDescription;
539
private javax.swing.JScrollPane spExpandedText;
540
private javax.swing.JScrollPane spTemplates;
541
private javax.swing.JTable tTemplates;
542
private javax.swing.JTabbedPane tabPane;
543
// End of variables declaration//GEN-END:variables