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.colors;
44
import org.netbeans.modules.options.colors.spi.FontsColorsController;
45
import java.awt.Color;
46
import java.awt.Component;
48
import java.awt.Insets;
49
import java.awt.event.ActionEvent;
50
import java.awt.event.ActionListener;
51
import java.beans.PropertyChangeEvent;
52
import java.beans.PropertyChangeListener;
53
import java.beans.PropertyEditor;
54
import java.beans.PropertyEditorManager;
55
import java.util.ArrayList;
56
import java.util.Collection;
57
import java.util.Collections;
58
import java.util.Comparator;
59
import java.util.HashMap;
60
import java.util.HashSet;
61
import java.util.Iterator;
62
import java.util.List;
65
import java.util.Vector;
66
import javax.swing.AbstractButton;
67
import javax.swing.JComboBox;
68
import javax.swing.JComponent;
69
import javax.swing.JLabel;
70
import javax.swing.JPanel;
71
import javax.swing.ListSelectionModel;
72
import javax.swing.UIManager;
73
import javax.swing.event.ListSelectionEvent;
74
import javax.swing.event.ListSelectionListener;
75
import javax.swing.text.AttributeSet;
76
import javax.swing.text.SimpleAttributeSet;
77
import javax.swing.text.StyleConstants;
78
import org.netbeans.api.editor.settings.EditorStyleConstants;
79
import org.netbeans.modules.options.colors.ColorModel.Preview;
80
import org.openide.DialogDescriptor;
81
import org.openide.DialogDisplayer;
82
import org.openide.awt.Mnemonics;
83
import org.openide.util.NbBundle;
84
import org.openide.util.RequestProcessor;
85
import org.openide.util.RequestProcessor.Task;
91
public class SyntaxColoringPanel extends JPanel implements ActionListener,
92
PropertyChangeListener, FontsColorsController {
95
private Preview preview;
96
private Task selectTask;
97
private ColorModel colorModel = null;
98
private String currentLanguage;
99
private String currentProfile;
100
/** cache Map (String (profile name) > Map (String (language name) > Vector (AttributeSet))). */
101
private Map<String, Map<String, Vector<AttributeSet>>> profiles = new HashMap<String, Map<String, Vector<AttributeSet>>>();
102
/** Map (String (profile name) > Set (String (language name))) of names of changed languages. */
103
private Map<String, Set<String>> toBeSaved = new HashMap<String, Set<String>>();
104
private boolean listen = false;
106
/** Creates new form SyntaxColoringPanel1 */
107
public SyntaxColoringPanel () {
110
setName(loc("Syntax_coloring_tab")); //NOI18N
111
// 1) init components
112
cbLanguage.getAccessibleContext ().setAccessibleName (loc ("AN_Languages"));
113
cbLanguage.getAccessibleContext ().setAccessibleDescription (loc ("AD_Languages"));
114
lCategories.getAccessibleContext ().setAccessibleName (loc ("AN_Categories"));
115
lCategories.getAccessibleContext ().setAccessibleDescription (loc ("AD_Categories"));
116
bFont.getAccessibleContext ().setAccessibleName (loc ("AN_Font"));
117
bFont.getAccessibleContext ().setAccessibleDescription (loc ("AD_Font"));
118
cbForeground.getAccessibleContext ().setAccessibleName (loc ("AN_Foreground_Chooser"));
119
cbForeground.getAccessibleContext ().setAccessibleDescription (loc ("AD_Foreground_Chooser"));
120
// bForeground.getAccessibleContext ().setAccessibleName (loc ("AN_Foreground"));
121
// bForeground.getAccessibleContext ().setAccessibleDescription (loc ("AD_Foreground"));
122
cbBackground.getAccessibleContext ().setAccessibleName (loc ("AN_Background_Chooser"));
123
cbBackground.getAccessibleContext ().setAccessibleDescription (loc ("AD_Background_Chooser"));
124
// bBackground.getAccessibleContext ().setAccessibleName (loc ("AN_Background"));
125
// bBackground.getAccessibleContext ().setAccessibleDescription (loc ("AD_Background"));
126
cbEffects.getAccessibleContext ().setAccessibleName (loc ("AN_Efects_Color_Chooser"));
127
cbEffects.getAccessibleContext ().setAccessibleDescription (loc ("AD_Efects_Color_Chooser"));
128
cbEffectColor.getAccessibleContext ().setAccessibleName (loc ("AN_Efects_Color"));
129
cbEffectColor.getAccessibleContext ().setAccessibleDescription (loc ("AD_Efects_Color"));
130
ColorComboBox.init (cbBackground);
131
ColorComboBox.init (cbForeground);
132
ColorComboBox.init (cbEffectColor);
133
cbLanguage.addActionListener (this);
134
lCategories.setSelectionMode (ListSelectionModel.SINGLE_SELECTION);
135
lCategories.setVisibleRowCount (3);
136
lCategories.setCellRenderer (new CategoryRenderer ());
137
lCategories.addListSelectionListener (new ListSelectionListener () {
138
public void valueChanged (ListSelectionEvent e) {
140
selectTask.schedule (200);
143
tfFont.setEditable (false);
144
bFont.addActionListener (this);
145
bFont.setMargin (new Insets (0, 0, 0, 0));
146
// bForeground.addActionListener (this);
147
// bForeground.setMargin (new Insets (0, 0, 0, 0));
148
// bBackground.addActionListener (this);
149
// bBackground.setMargin (new Insets (0, 0, 0, 0));
150
cbForeground.addActionListener (this);
151
((JComponent)cbForeground.getEditor()).addPropertyChangeListener (this);
153
cbBackground.addActionListener (this);
154
((JComponent)cbBackground.getEditor()).addPropertyChangeListener (this);
156
cbEffects.addItem (loc ("CTL_Effects_None"));
157
cbEffects.addItem (loc ("CTL_Effects_Underlined"));
158
cbEffects.addItem (loc ("CTL_Effects_Wave_Underlined"));
159
cbEffects.addItem (loc ("CTL_Effects_Strike_Through"));
160
cbEffects.getAccessibleContext ().setAccessibleName (loc ("AN_Effects"));
161
cbEffects.getAccessibleContext ().setAccessibleDescription (loc ("AD_Effects"));
162
cbEffects.addActionListener (this);
163
cbEffectColor.addActionListener (this);
165
loc(bFont, "CTL_Font_button");
166
loc(lBackground, "CTL_Background_label");
167
loc(lCategory, "CTL_Category");
168
loc(lEffectColor, "CTL_Effects_color");
169
loc(lEffects, "CTL_Effects_label");
170
loc(lFont, "CTL_Font");
171
loc(lForeground, "CTL_Foreground_label");
172
loc(lLanguage, "CTL_Languages");
173
loc(lPreview, "CTL_Preview");
175
selectTask = new RequestProcessor ("SyntaxColoringPanel1").create (
186
/** This method is called from within the constructor to
187
* initialize the form.
188
* WARNING: Do NOT modify this code. The content of this method is
189
* always regenerated by the Form Editor.
191
// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
192
private void initComponents() {
194
lLanguage = new javax.swing.JLabel();
195
cbLanguage = new javax.swing.JComboBox();
196
lCategory = new javax.swing.JLabel();
197
spCategories = new javax.swing.JScrollPane();
198
lCategories = new javax.swing.JList();
199
lPreview = new javax.swing.JLabel();
200
spPreview = new javax.swing.JScrollPane();
201
pPreview = new javax.swing.JPanel();
202
lFont = new javax.swing.JLabel();
203
lForeground = new javax.swing.JLabel();
204
lBackground = new javax.swing.JLabel();
205
lEffects = new javax.swing.JLabel();
206
lEffectColor = new javax.swing.JLabel();
207
cbForeground = new javax.swing.JComboBox();
208
cbBackground = new javax.swing.JComboBox();
209
cbEffects = new javax.swing.JComboBox();
210
cbEffectColor = new javax.swing.JComboBox();
211
tfFont = new javax.swing.JTextField();
212
bFont = new javax.swing.JButton();
214
lLanguage.setLabelFor(cbLanguage);
215
lLanguage.setText("Language:");
217
lCategory.setLabelFor(lCategories);
218
lCategory.setText("Category:");
220
spCategories.setViewportView(lCategories);
222
lPreview.setText("Preview:");
224
spPreview.setBorder(javax.swing.BorderFactory.createEtchedBorder());
225
spPreview.setAutoscrolls(true);
227
pPreview.setAutoscrolls(true);
228
pPreview.setLayout(new java.awt.BorderLayout());
229
spPreview.setViewportView(pPreview);
231
lFont.setLabelFor(bFont);
232
lFont.setText("Font:");
234
lForeground.setLabelFor(cbForeground);
235
lForeground.setText("Foreground:");
237
lBackground.setLabelFor(cbBackground);
238
lBackground.setText("Background:");
240
lEffects.setLabelFor(cbEffects);
241
lEffects.setText("Effects:");
243
lEffectColor.setLabelFor(cbEffectColor);
244
lEffectColor.setText("Effect Color:");
246
bFont.setText("...");
247
bFont.setMargin(new java.awt.Insets(2, 2, 2, 2));
249
org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
250
this.setLayout(layout);
251
layout.setHorizontalGroup(
252
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
253
.add(layout.createSequentialGroup()
255
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
256
.add(spPreview, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 340, Short.MAX_VALUE)
257
.add(layout.createSequentialGroup()
259
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
260
.add(cbLanguage, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
262
.add(layout.createSequentialGroup()
263
.add(spCategories, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 201, Short.MAX_VALUE)
264
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
265
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
271
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
272
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
273
.add(layout.createSequentialGroup()
274
.add(tfFont, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 13, Short.MAX_VALUE)
275
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
277
.add(cbForeground, 0, 38, Short.MAX_VALUE)
278
.add(cbBackground, 0, 38, Short.MAX_VALUE)
279
.add(cbEffects, 0, 38, Short.MAX_VALUE)
280
.add(cbEffectColor, 0, 38, Short.MAX_VALUE))
281
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED))
285
layout.setVerticalGroup(
286
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
287
.add(layout.createSequentialGroup()
289
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
291
.add(cbLanguage, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
292
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
294
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
295
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
296
.add(layout.createSequentialGroup()
297
.add(spCategories, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 130, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
298
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
300
.add(layout.createSequentialGroup()
301
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
303
.add(tfFont, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
305
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
306
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
308
.add(cbForeground, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
309
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
310
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
312
.add(cbBackground, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
313
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
314
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
316
.add(cbEffects, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
317
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
318
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
320
.add(cbEffectColor, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))))
321
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
322
.add(spPreview, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 153, Short.MAX_VALUE)
325
}// </editor-fold>//GEN-END:initComponents
328
// Variables declaration - do not modify//GEN-BEGIN:variables
329
private javax.swing.JButton bFont;
330
private javax.swing.JComboBox cbBackground;
331
private javax.swing.JComboBox cbEffectColor;
332
private javax.swing.JComboBox cbEffects;
333
private javax.swing.JComboBox cbForeground;
334
private javax.swing.JComboBox cbLanguage;
335
private javax.swing.JLabel lBackground;
336
private javax.swing.JList lCategories;
337
private javax.swing.JLabel lCategory;
338
private javax.swing.JLabel lEffectColor;
339
private javax.swing.JLabel lEffects;
340
private javax.swing.JLabel lFont;
341
private javax.swing.JLabel lForeground;
342
private javax.swing.JLabel lLanguage;
343
private javax.swing.JLabel lPreview;
344
private javax.swing.JPanel pPreview;
345
private javax.swing.JScrollPane spCategories;
346
private javax.swing.JScrollPane spPreview;
347
private javax.swing.JTextField tfFont;
348
// End of variables declaration//GEN-END:variables
351
public void actionPerformed (ActionEvent evt) {
353
if (evt.getSource () == cbEffects) {
354
cbEffectColor.setEnabled (cbEffects.getSelectedIndex () > 0);
355
if (cbEffects.getSelectedIndex () == 0)
356
ColorComboBox.setColor (cbEffectColor, null);
359
if (evt.getSource () == cbLanguage) {
360
setCurrentLanguage ((String) cbLanguage.getSelectedItem ());
362
if (evt.getSource () == bFont) {
363
PropertyEditor pe = PropertyEditorManager.findEditor (Font.class);
364
AttributeSet category = getCurrentCategory ();
365
Font f = getFont (category);
367
DialogDescriptor dd = new DialogDescriptor (
368
pe.getCustomEditor (),
369
loc ("CTL_Font_Chooser") // NOI18N
371
DialogDisplayer.getDefault ().createDialog (dd).setVisible (true);
372
if (dd.getValue () == DialogDescriptor.OK_OPTION) {
373
f = (Font) pe.getValue ();
374
category = modifyFont (category, f);
375
replaceCurrrentCategory (category);
376
setToBeSaved (currentProfile, currentLanguage);
377
refreshUI (); // refresh font viewer
380
if (evt.getSource () instanceof JComboBox) {
385
public void propertyChange(PropertyChangeEvent evt) {
386
if (!listen || evt.getPropertyName() == null ) {
390
if (Preview.PROP_CURRENT_ELEMENT.equals(evt.getPropertyName())) {
391
String currentCategory = (String) evt.getNewValue();
392
Vector<AttributeSet> categories = getCategories(currentProfile, currentLanguage);
393
if (currentLanguage.equals(ColorModel.ALL_LANGUAGES)) {
394
String converted = (String) convertALC.get(currentCategory);
395
if (converted != null) {
396
currentCategory = converted;
400
for (int i = 0; i < categories.size(); i++) {
401
AttributeSet as = categories.get(i);
402
if (currentCategory.equals(as.getAttribute(StyleConstants.NameAttribute))) {
404
lCategories.setSelectedIndex(i);
405
lCategories.ensureIndexIsVisible(i);
410
} else if (ColorComboBox.PROP_COLOR.equals(evt.getPropertyName())) {
415
public void update (ColorModel colorModel) {
416
this.colorModel = colorModel;
417
currentProfile = colorModel.getCurrentProfile ();
418
currentLanguage = (String) colorModel.getLanguages ().
421
preview.removePropertyChangeListener
422
(Preview.PROP_CURRENT_ELEMENT, this);
423
Component component = colorModel.getSyntaxColoringPreviewComponent
425
preview = (Preview) component;
426
pPreview.removeAll ();
427
pPreview.add ("Center", component);
428
preview.addPropertyChangeListener
429
(Preview.PROP_CURRENT_ELEMENT, this);
431
List<String> languages = new ArrayList<String>(colorModel.getLanguages ());
432
Collections.sort (languages, new LanguagesComparator ());
433
Iterator it = languages.iterator ();
434
cbLanguage.removeAllItems ();
435
while (it.hasNext ())
436
cbLanguage.addItem (it.next ());
438
cbLanguage.setSelectedIndex (0);
441
public void cancel () {
442
toBeSaved = new HashMap<String, Set<String>>();
443
profiles = new HashMap<String, Map<String, Vector<AttributeSet>>>();
446
public void applyChanges() {
447
if (colorModel == null) return;
448
for(String profile : toBeSaved.keySet()) {
449
Set<String> toBeSavedLanguages = toBeSaved.get(profile);
450
Map<String, Vector<AttributeSet>> schemeMap = profiles.get(profile);
451
for(String languageName : toBeSavedLanguages) {
452
colorModel.setCategories(
455
schemeMap.get(languageName)
459
toBeSaved = new HashMap<String, Set<String>>();
460
profiles = new HashMap<String, Map<String, Vector<AttributeSet>>>();
463
public boolean isChanged () {
464
return !toBeSaved.isEmpty ();
467
public void setCurrentProfile (String currentProfile) {
468
String oldProfile = this.currentProfile;
469
this.currentProfile = currentProfile;
470
if (!colorModel.getProfiles ().contains (currentProfile))
471
cloneScheme (oldProfile, currentProfile);
472
Vector categories = getCategories (currentProfile, currentLanguage);
473
lCategories.setListData (categories);
475
lCategories.setSelectedIndex (0);
480
public void deleteProfile(String profile) {
481
Map<String, Vector<AttributeSet>> m = new HashMap<String, Vector<AttributeSet>>();
482
boolean custom = colorModel.isCustomProfile(profile);
483
for(String language : colorModel.getLanguages()) {
485
m.put(language, null);
487
m.put(language, getDefaults(profile, language));
490
profiles.put(profile, m);
491
toBeSaved.put(profile, new HashSet<String>(colorModel.getLanguages()));
497
public JComponent getComponent() {
501
// other methods ...........................................................
503
private void cloneScheme(String oldScheme, String newScheme) {
504
Map<String, Vector<AttributeSet>> m = new HashMap<String, Vector<AttributeSet>>();
505
for(String language : colorModel.getLanguages()) {
506
Vector<AttributeSet> v = getCategories(oldScheme, language);
507
m.put(language, new Vector<AttributeSet>(v));
508
setToBeSaved(newScheme, language);
510
profiles.put(newScheme, m);
513
Collection<AttributeSet> getAllLanguages() {
514
return getCategories(currentProfile, ColorModel.ALL_LANGUAGES);
517
Collection<AttributeSet> getSyntaxColorings() {
518
return getCategories(currentProfile, currentLanguage);
521
private void setCurrentLanguage (String language) {
522
currentLanguage = language;
524
// setup categories list
526
lCategories.setListData (getCategories (currentProfile, currentLanguage));
527
lCategories.setSelectedIndex (0);
532
private static String loc (String key) {
533
return NbBundle.getMessage (SyntaxColoringPanel.class, key);
536
private static void loc (Component c, String key) {
537
if (c instanceof AbstractButton)
538
Mnemonics.setLocalizedText (
543
Mnemonics.setLocalizedText (
550
* Called on user change.
551
* Updates data structures and preview panel.
553
private void updateData () {
554
int i = lCategories.getSelectedIndex ();
557
AttributeSet category = getCurrentCategory ();
558
Color underline = null,
560
strikethrough = null;
561
if (cbEffects.getSelectedIndex () == 1)
562
underline = ColorComboBox.getColor(cbEffectColor);
563
if (cbEffects.getSelectedIndex () == 2)
564
wave = ColorComboBox.getColor(cbEffectColor);
565
if (cbEffects.getSelectedIndex () == 3)
566
strikethrough = ColorComboBox.getColor(cbEffectColor);
568
SimpleAttributeSet c = new SimpleAttributeSet (category);
570
Color color = ColorComboBox.getColor(cbBackground);
572
c.addAttribute(StyleConstants.Background, color);
574
c.removeAttribute(StyleConstants.Background);
577
color = ColorComboBox.getColor(cbForeground);
579
c.addAttribute(StyleConstants.Foreground, color);
581
c.removeAttribute(StyleConstants.Foreground);
584
if (underline != null) {
585
c.addAttribute(StyleConstants.Underline, underline);
587
c.removeAttribute(StyleConstants.Underline);
590
if (strikethrough != null) {
591
c.addAttribute(StyleConstants.StrikeThrough, strikethrough);
593
c.removeAttribute(StyleConstants.StrikeThrough);
597
c.addAttribute(EditorStyleConstants.WaveUnderlineColor, wave);
599
c.removeAttribute(EditorStyleConstants.WaveUnderlineColor);
602
replaceCurrrentCategory(c);
603
setToBeSaved(currentProfile, currentLanguage);
607
private boolean blink = true;
608
private int blinkSequence = 0;
609
private RequestProcessor.Task task = new RequestProcessor
610
("SyntaxColoringPanel").create (new Runnable () {
613
if (blinkSequence == 0) return;
619
private void startBlinking () {
624
private void updatePreview () {
625
Collection<AttributeSet> syntaxColorings = getSyntaxColorings();
626
Collection<AttributeSet> allLanguages = getAllLanguages();
627
if ((blinkSequence % 2) == 1) {
628
if (ColorModel.ALL_LANGUAGES.equals(currentLanguage)) {
629
allLanguages = invertCategory(allLanguages, getCurrentCategory());
631
syntaxColorings = invertCategory(syntaxColorings, getCurrentCategory());
634
preview.setParameters (
637
Collections.<AttributeSet>emptySet(),
642
private Collection<AttributeSet> invertCategory (Collection<AttributeSet> c, AttributeSet category) {
643
if (category == null) return c;
644
ArrayList<AttributeSet> result = new ArrayList<AttributeSet> (c);
645
int i = result.indexOf (category);
646
SimpleAttributeSet as = new SimpleAttributeSet (category);
647
Color highlight = (Color) getValue (currentLanguage, category, StyleConstants.Background);
648
if (highlight == null) return result;
649
Color newColor = new Color (
650
255 - highlight.getRed (),
651
255 - highlight.getGreen (),
652
255 - highlight.getBlue ()
655
StyleConstants.Underline,
663
* Called when current category, profile or language has been changed.
664
* Updates all ui components.
666
private void refreshUI () {
668
AttributeSet category = getCurrentCategory ();
669
if (category == null) {
670
// no category selected > disable all elements
672
bFont.setEnabled (false);
673
cbEffects.setEnabled (false);
674
cbForeground.setEnabled (false);
675
cbForeground.setSelectedItem (new ColorValue (null, null));
676
cbBackground.setEnabled (false);
677
cbBackground.setSelectedItem (new ColorValue (null, null));
678
cbEffectColor.setEnabled (false);
679
cbEffectColor.setSelectedItem (new ColorValue (null, null));
683
bFont.setEnabled (true);
684
cbEffects.setEnabled (true);
685
cbForeground.setEnabled (true);
686
cbBackground.setEnabled (true);
689
Color inheritedForeground = (Color) getDefault
690
(currentLanguage, category, StyleConstants.Foreground);
691
if (inheritedForeground == null) inheritedForeground = Color.black;
692
ColorComboBox.setInheritedColor (cbForeground, inheritedForeground);
693
Color inheritedBackground = (Color) getDefault
694
(currentLanguage, category, StyleConstants.Background);
695
if (inheritedBackground == null) inheritedBackground = Color.white;
696
ColorComboBox.setInheritedColor (cbBackground, inheritedBackground);
698
String font = fontToString (category);
699
tfFont.setText (font);
700
ColorComboBox.setColor (
702
(Color) category.getAttribute (StyleConstants.Foreground)
704
ColorComboBox.setColor (
706
(Color) category.getAttribute (StyleConstants.Background)
709
if (category.getAttribute (StyleConstants.Underline) != null) {
710
cbEffects.setSelectedIndex (1);
711
cbEffectColor.setEnabled (true);
712
ColorComboBox.setColor (
714
(Color) category.getAttribute (StyleConstants.Underline)
717
if (category.getAttribute (EditorStyleConstants.WaveUnderlineColor) != null) {
718
cbEffects.setSelectedIndex (2);
719
cbEffectColor.setEnabled (true);
720
ColorComboBox.setColor (
722
(Color) category.getAttribute (EditorStyleConstants.WaveUnderlineColor)
725
if (category.getAttribute (StyleConstants.StrikeThrough) != null) {
726
cbEffects.setSelectedIndex (3);
727
cbEffectColor.setEnabled (true);
728
ColorComboBox.setColor (
730
(Color) category.getAttribute (StyleConstants.StrikeThrough)
733
cbEffects.setSelectedIndex (0);
734
cbEffectColor.setEnabled (false);
735
cbEffectColor.setSelectedItem (new ColorValue (null, null));
741
private void setToBeSaved(String currentProfile, String currentLanguage) {
742
Set<String> s = toBeSaved.get(currentProfile);
744
s = new HashSet<String>();
745
toBeSaved.put(currentProfile, s);
747
s.add(currentLanguage);
750
private Vector<AttributeSet> getCategories(String profile, String language) {
751
if (colorModel == null) return null;
752
Map<String, Vector<AttributeSet>> m = profiles.get(profile);
754
m = new HashMap<String, Vector<AttributeSet>>();
755
profiles.put(profile, m);
757
Vector<AttributeSet> v = m.get(language);
759
Collection<AttributeSet> c = colorModel.getCategories(profile, language);
761
c = Collections.<AttributeSet>emptySet(); // XXX OK?
763
List<AttributeSet> l = new ArrayList<AttributeSet>(c);
764
Collections.sort(l, new CategoryComparator());
765
v = new Vector<AttributeSet>(l);
771
private Map<String, Map<String, Vector<AttributeSet>>> defaults = new HashMap<String, Map<String, Vector<AttributeSet>>>();
773
* Returns original colors for given profile.
775
private Vector<AttributeSet> getDefaults(String profile, String language) {
776
Map<String, Vector<AttributeSet>> m = defaults.get(profile);
778
m = new HashMap<String, Vector<AttributeSet>>();
779
defaults.put(profile, m);
781
Vector<AttributeSet> v = m.get(language);
783
Collection<AttributeSet> c = colorModel.getDefaults(profile, language);
784
List<AttributeSet> l = new ArrayList<AttributeSet>(c);
785
Collections.sort(l, new CategoryComparator());
786
v = new Vector<AttributeSet>(l);
789
return new Vector<AttributeSet>(v);
792
private AttributeSet getCurrentCategory () {
793
int i = lCategories.getSelectedIndex ();
794
if (i < 0) return null;
795
return (AttributeSet) getCategories (currentProfile, currentLanguage).get (i);
798
private void replaceCurrrentCategory (AttributeSet newValues) {
799
int i = lCategories.getSelectedIndex ();
800
getCategories (currentProfile, currentLanguage).set (i, newValues);
803
private AttributeSet getCategory (
808
Vector v = getCategories (profile, language);
809
Iterator it = v.iterator ();
810
while (it.hasNext ()) {
811
AttributeSet c = (AttributeSet) it.next ();
812
if (c.getAttribute (StyleConstants.NameAttribute).equals (name))
818
private Object getValue (String language, AttributeSet category, Object key) {
819
if (category.isDefined (key))
820
return category.getAttribute (key);
821
return getDefault (language, category, key);
824
private Object getDefault (String language, AttributeSet category, Object key) {
825
String name = (String) category.getAttribute (EditorStyleConstants.Default);
826
if (name == null) name = "default";
828
// 1) search current language
829
if (!name.equals (category.getAttribute (StyleConstants.NameAttribute))
831
AttributeSet defaultAS = getCategory
832
(currentProfile, language, name);
833
if (defaultAS != null)
834
return getValue (language, defaultAS, key);
837
// 2) search default language
838
if (!language.equals (ColorModel.ALL_LANGUAGES)) {
839
AttributeSet defaultAS = getCategory
840
(currentProfile, ColorModel.ALL_LANGUAGES, name);
841
if (defaultAS != null)
842
return getValue (ColorModel.ALL_LANGUAGES, defaultAS, key);
845
if (key == StyleConstants.FontFamily) return "Monospaced"; // NOI18N
846
if (key == StyleConstants.FontSize) return getDefaultFontSize ();
850
private Font getFont (AttributeSet category) {
851
String name = (String) getValue (currentLanguage, category, StyleConstants.FontFamily);
852
if (name == null) name = "Monospaced"; // NOI18N
853
Integer size = (Integer) getValue (currentLanguage, category, StyleConstants.FontSize);
855
size = getDefaultFontSize ();
856
Boolean bold = (Boolean) getValue (currentLanguage, category, StyleConstants.Bold);
857
if (bold == null) bold = Boolean.FALSE;
858
Boolean italic = (Boolean) getValue (currentLanguage, category, StyleConstants.Italic);
859
if (italic == null) italic = Boolean.FALSE;
860
int style = bold.booleanValue () ? Font.BOLD : Font.PLAIN;
861
if (italic.booleanValue ()) style += Font.ITALIC;
862
return new Font (name, style, size.intValue ());
865
private AttributeSet modifyFont (AttributeSet category, Font f) {
866
String fontName = f.getName ();
867
Integer fontSize = new Integer (f.getSize ());
868
Boolean bold = Boolean.valueOf (f.isBold ());
869
Boolean italic = Boolean.valueOf (f.isItalic ());
870
boolean isDefault = "default".equals (
871
category.getAttribute (StyleConstants.NameAttribute)
873
if (fontName.equals (
874
getDefault (currentLanguage, category, StyleConstants.FontFamily)
877
if (fontSize.equals (
878
getDefault (currentLanguage, category, StyleConstants.FontSize)
881
if (bold.equals (getDefault (currentLanguage, category, StyleConstants.Bold))
885
if (bold.equals (Boolean.FALSE) &&
886
getDefault (currentLanguage, category, StyleConstants.Bold) == null
889
if (italic.equals (getDefault (currentLanguage, category, StyleConstants.Italic))
893
if (italic.equals (Boolean.FALSE) &&
894
getDefault (currentLanguage, category, StyleConstants.Italic) == null
897
SimpleAttributeSet c = new SimpleAttributeSet (category);
898
if (fontName != null)
900
StyleConstants.FontFamily,
904
c.removeAttribute (StyleConstants.FontFamily);
905
if (fontSize != null)
907
StyleConstants.FontSize,
911
c.removeAttribute (StyleConstants.FontSize);
918
c.removeAttribute (StyleConstants.Bold);
921
StyleConstants.Italic,
925
c.removeAttribute (StyleConstants.Italic);
930
private String fontToString (AttributeSet category) {
931
if ("default".equals (
932
category.getAttribute (StyleConstants.NameAttribute)
934
StringBuffer sb = new StringBuffer ();
935
sb.append (getValue (currentLanguage, category, StyleConstants.FontFamily));
937
sb.append (getValue (currentLanguage, category, StyleConstants.FontSize));
938
Boolean bold = (Boolean) getValue (currentLanguage, category, StyleConstants.Bold);
939
if (bold != null && bold.booleanValue ())
940
sb.append (' ').append (loc ("CTL_Bold")); // NOI18N
941
Boolean italic = (Boolean) getValue (currentLanguage, category, StyleConstants.Italic);
942
if (italic != null && italic.booleanValue ())
943
sb.append (' ').append (loc ("CTL_Italic")); // NOI18N
944
return sb.toString ();
947
StringBuffer sb = new StringBuffer ();
948
if (category.getAttribute (StyleConstants.FontFamily) != null)
949
sb.append ('+').append (category.getAttribute (StyleConstants.FontFamily));
952
if (category.getAttribute (StyleConstants.FontSize) != null)
953
sb.append ('+').append (category.getAttribute (StyleConstants.FontSize));
956
if (Boolean.TRUE.equals (category.getAttribute (StyleConstants.Bold)))
957
sb.append ('+').append (loc ("CTL_Bold")); // NOI18N
958
if (Boolean.FALSE.equals (category.getAttribute (StyleConstants.Bold)))
959
sb.append ('-').append (loc ("CTL_Bold")); // NOI18N
960
if (Boolean.TRUE.equals (category.getAttribute (StyleConstants.Italic)))
961
sb.append ('+').append (loc ("CTL_Italic")); // NOI18N
962
if (Boolean.FALSE.equals (category.getAttribute (StyleConstants.Italic)))
963
sb.append ('-').append (loc ("CTL_Italic")); // NOI18N
966
sb.insert (0, loc ("CTL_Inherited")); // NOI18N
967
return sb.toString ();
969
String result = sb.toString ();
970
return result.replace ('+', ' ');
974
private static Map<String, String> convertALC = new HashMap<String, String>();
977
convertALC.put("character", "char"); //NOI18N
978
convertALC.put("errors", "error"); //NOI18N
979
convertALC.put("literal", "keyword"); //NOI18N
980
convertALC.put("keyword-directive", "keyword"); //NOI18N
983
private static Integer defaultFontSize;
984
private static Integer getDefaultFontSize () {
985
if (defaultFontSize == null) {
986
defaultFontSize = (Integer) UIManager.get("customFontSize"); // NOI18N
987
if (defaultFontSize == null) {
988
int s = UIManager.getFont ("TextField.font").getSize (); // NOI18N
990
defaultFontSize = new Integer (s);
993
return defaultFontSize;
996
private static final class LanguagesComparator implements Comparator<String> {
997
public int compare(String o1, String o2) {
998
if (o1.equals(ColorModel.ALL_LANGUAGES))
999
return o2.equals(ColorModel.ALL_LANGUAGES) ? 0 : -1;
1000
return o1.compareTo(o2);