comparison src/viewer_swing/java/com/glavsoft/viewer/swing/gui/OptionsDialog.java @ 0:daa24f8a557b

TightVNC original
author YU
date Thu, 11 Sep 2014 07:30:03 +0900
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:daa24f8a557b
1 // Copyright (C) 2010, 2011, 2012, 2013 GlavSoft LLC.
2 // All rights reserved.
3 //
4 //-------------------------------------------------------------------------
5 // This file is part of the TightVNC software. Please visit our Web site:
6 //
7 // http://www.tightvnc.com/
8 //
9 // This program is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation; either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License along
20 // with this program; if not, write to the Free Software Foundation, Inc.,
21 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 //-------------------------------------------------------------------------
23 //
24
25 package com.glavsoft.viewer.swing.gui;
26
27 import com.glavsoft.rfb.encoding.EncodingType;
28 import com.glavsoft.rfb.protocol.LocalPointer;
29 import com.glavsoft.rfb.protocol.ProtocolSettings;
30 import com.glavsoft.viewer.swing.LocalMouseCursorShape;
31 import com.glavsoft.viewer.UiSettings;
32
33 import javax.swing.*;
34 import java.awt.*;
35 import java.awt.event.*;
36 import java.util.HashMap;
37 import java.util.Map;
38
39 /**
40 * Options dialog
41 */
42 @SuppressWarnings("serial")
43 public class OptionsDialog extends JDialog {
44 private JSlider jpegQuality;
45 private JSlider compressionLevel;
46 private JCheckBox viewOnlyCheckBox;
47 private ProtocolSettings settings;
48 private UiSettings uiSettings;
49 private JCheckBox sharedSession;
50
51 private RadioButtonSelectedState<LocalPointer> mouseCursorTrackSelected;
52 private Map<LocalPointer, JRadioButton> mouseCursorTrackMap;
53 private JCheckBox useCompressionLevel;
54 private JCheckBox useJpegQuality;
55 private JLabel jpegQualityPoorLabel;
56 private JLabel jpegQualityBestLabel;
57 private JLabel compressionLevelFastLabel;
58 private JLabel compressionLevelBestLabel;
59 private JCheckBox allowCopyRect;
60 private JComboBox encodings;
61 private JCheckBox disableClipboardTransfer;
62 private JComboBox colorDepth;
63 private RadioButtonSelectedState<LocalMouseCursorShape> mouseCursorShapeSelected;
64 private HashMap<LocalMouseCursorShape, JRadioButton> mouseCursorShapeMap;
65
66 public OptionsDialog(Window owner) {
67 super(owner, "Connection Options", ModalityType.DOCUMENT_MODAL);
68 final WindowAdapter onClose = new WindowAdapter() {
69 @Override
70 public void windowClosing(WindowEvent e) {
71 setVisible(false);
72 }
73 };
74 addWindowListener(onClose);
75
76 JPanel optionsPane = new JPanel(new GridLayout(0, 2));
77 add(optionsPane, BorderLayout.CENTER);
78
79 optionsPane.add(createLeftPane());
80 optionsPane.add(createRightPane());
81
82 addButtons(onClose);
83
84 pack();
85 }
86
87 public void initControlsFromSettings(ProtocolSettings settings, UiSettings uiSettings, boolean isOnConnect) {
88 this.settings = settings;
89 this.uiSettings = uiSettings;
90
91 viewOnlyCheckBox.setSelected(settings.isViewOnly());
92
93 int i = 0; boolean isNotSetEncoding = true;
94 while ( encodings.getItemAt(i) != null) {
95 EncodingType item = ((EncodingSelectItem)encodings.getItemAt(i)).type;
96 if (item.equals(settings.getPreferredEncoding())) {
97 encodings.setSelectedIndex(i);
98 isNotSetEncoding = false;
99 break;
100 }
101 ++i;
102 }
103 if (isNotSetEncoding) {
104 encodings.setSelectedItem(0);
105 }
106
107 sharedSession.setSelected(settings.isShared());
108 sharedSession.setEnabled(isOnConnect);
109
110 mouseCursorTrackMap.get(settings.getMouseCursorTrack()).setSelected(true);
111 mouseCursorTrackSelected.setSelected(settings.getMouseCursorTrack());
112 mouseCursorShapeMap.get(uiSettings.getMouseCursorShape()).setSelected(true);
113 mouseCursorShapeSelected.setSelected(uiSettings.getMouseCursorShape());
114
115 int depth = settings.getColorDepth();
116 i = 0; boolean isNotSet = true;
117 while ( colorDepth.getItemAt(i) != null) {
118 int itemDepth = ((ColorDepthSelectItem)colorDepth.getItemAt(i)).depth;
119 if (itemDepth == depth) {
120 colorDepth.setSelectedIndex(i);
121 isNotSet = false;
122 break;
123 }
124 ++i;
125 }
126 if (isNotSet) {
127 colorDepth.setSelectedItem(0);
128 }
129
130 useCompressionLevel.setSelected(settings.getCompressionLevel() > 0);
131 compressionLevel.setValue(Math.abs(settings.getCompressionLevel()));
132 setCompressionLevelPaneEnable();
133
134 useJpegQuality.setSelected(settings.getJpegQuality() > 0);
135 jpegQuality.setValue(Math.abs(settings.getJpegQuality()));
136 setJpegQualityPaneEnable();
137
138 allowCopyRect.setSelected(settings.isAllowCopyRect());
139 disableClipboardTransfer.setSelected( ! settings.isAllowClipboardTransfer());
140 }
141
142 private void setSettingsFromControls() {
143 settings.setViewOnly(viewOnlyCheckBox.isSelected());
144 settings.setPreferredEncoding(((EncodingSelectItem)encodings.getSelectedItem()).type);
145
146 settings.setSharedFlag(sharedSession.isSelected());
147 settings.setMouseCursorTrack(mouseCursorTrackSelected.getSelected());
148 uiSettings.setMouseCursorShape(mouseCursorShapeSelected.getSelected());
149
150 settings.setColorDepth(((ColorDepthSelectItem) colorDepth.getSelectedItem()).depth);
151
152 settings.setCompressionLevel(useCompressionLevel.isSelected() ?
153 compressionLevel.getValue() :
154 - Math.abs(settings.getCompressionLevel()));
155 settings.setJpegQuality(useJpegQuality.isSelected() ?
156 jpegQuality.getValue() :
157 - Math.abs(settings.getJpegQuality()));
158 settings.setAllowCopyRect(allowCopyRect.isSelected());
159 settings.setAllowClipboardTransfer( ! disableClipboardTransfer.isSelected());
160 settings.fireListeners();
161 }
162
163 private Component createLeftPane() {
164 Box box = Box.createVerticalBox();
165 box.setAlignmentX(LEFT_ALIGNMENT);
166
167 box.add(createEncodingsPanel());
168
169 box.add(Box.createVerticalGlue());
170 return box;
171 }
172
173 private Component createRightPane() {
174 Box box = Box.createVerticalBox();
175 box.setAlignmentX(LEFT_ALIGNMENT);
176
177 box.add(createRestrictionsPanel());
178 box.add(createMouseCursorPanel());
179 box.add(createLocalShapePanel());
180
181 sharedSession = new JCheckBox("Request shared session");
182 box.add(new JPanel(new FlowLayout(FlowLayout.LEFT)).add(sharedSession));
183
184 box.add(Box.createVerticalGlue());
185 return box;
186 }
187
188 private JPanel createRestrictionsPanel() {
189 JPanel restrictionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
190 restrictionsPanel.setBorder(
191 BorderFactory.createTitledBorder(
192 BorderFactory.createEtchedBorder(), "Restrictions"));
193
194 Box restrictionsBox = Box.createVerticalBox();
195 restrictionsBox.setAlignmentX(LEFT_ALIGNMENT);
196 restrictionsPanel.add(restrictionsBox);
197 viewOnlyCheckBox = new JCheckBox("View only (inputs ignored)");
198 viewOnlyCheckBox.setAlignmentX(LEFT_ALIGNMENT);
199 restrictionsBox.add(viewOnlyCheckBox);
200
201 disableClipboardTransfer = new JCheckBox("Disable clipboard transfer");
202 disableClipboardTransfer.setAlignmentX(LEFT_ALIGNMENT);
203 restrictionsBox.add(disableClipboardTransfer);
204
205 return restrictionsPanel;
206 }
207
208 private JPanel createEncodingsPanel() {
209 JPanel encodingsPanel = new JPanel();
210 encodingsPanel.setAlignmentX(LEFT_ALIGNMENT);
211 encodingsPanel.setLayout(new BoxLayout(encodingsPanel, BoxLayout.Y_AXIS));
212 encodingsPanel.setBorder(
213 BorderFactory.createTitledBorder(
214 BorderFactory.createEtchedBorder(), "Format and Encodings"));
215
216 JPanel encPane = new JPanel(new FlowLayout(FlowLayout.LEFT));
217 encPane.setAlignmentX(LEFT_ALIGNMENT);
218 encPane.add(new JLabel("Preferred encoding: "));
219
220 encodings = new JComboBox();
221 encodings.addItem(new EncodingSelectItem(EncodingType.TIGHT));
222 encodings.addItem(new EncodingSelectItem(EncodingType.HEXTILE));
223
224 // encodings.addItem(new EncodingSelectItem(EncodingType.RRE));
225 // encodings.addItem(new EncodingSelectItem(EncodingType.ZLIB));
226
227 encodings.addItem(new EncodingSelectItem(EncodingType.ZRLE));
228 encodings.addItem(new EncodingSelectItem(EncodingType.RAW_ENCODING));
229 encPane.add(encodings);
230 encodingsPanel.add(encPane);
231
232 encodingsPanel.add(createColorDepthPanel());
233
234 addCompressionLevelPane(encodingsPanel);
235 addJpegQualityLevelPane(encodingsPanel);
236
237 allowCopyRect = new JCheckBox("Allow CopyRect encoding");
238 allowCopyRect.setAlignmentX(LEFT_ALIGNMENT);
239 encodingsPanel.add(allowCopyRect);
240
241 return encodingsPanel;
242 }
243
244 private static class EncodingSelectItem {
245 final EncodingType type;
246 public EncodingSelectItem(EncodingType type) {
247 this.type = type;
248 }
249 @Override
250 public String toString() {
251 return type.getName();
252 }
253 }
254
255 private static class ColorDepthSelectItem {
256 final int depth;
257 final String title;
258 public ColorDepthSelectItem(int depth, String title) {
259 this.depth = depth;
260 this.title = title;
261 }
262 @Override
263 public String toString() {
264 return title;
265 }
266 }
267
268 private JPanel createColorDepthPanel() {
269 JPanel colorDepthPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
270 colorDepthPanel.setAlignmentX(LEFT_ALIGNMENT);
271 colorDepthPanel.add(new JLabel("Color format: "));
272
273 colorDepth = new JComboBox();
274 colorDepth.addItem(new ColorDepthSelectItem(ProtocolSettings.COLOR_DEPTH_SERVER_SETTINGS,
275 "Server's default"));
276 colorDepth.addItem(new ColorDepthSelectItem(ProtocolSettings.COLOR_DEPTH_24,
277 "16 777 216 colors"));
278 colorDepth.addItem(new ColorDepthSelectItem(ProtocolSettings.COLOR_DEPTH_16,
279 "65 536 colors"));
280 colorDepth.addItem(new ColorDepthSelectItem(ProtocolSettings.COLOR_DEPTH_8,
281 "256 colors"));
282 colorDepth.addItem(new ColorDepthSelectItem(ProtocolSettings.COLOR_DEPTH_6,
283 "64 colors"));
284 colorDepth.addItem(new ColorDepthSelectItem(ProtocolSettings.COLOR_DEPTH_3,
285 "8 colors"));
286
287 colorDepthPanel.add(colorDepth);
288 colorDepth.addItemListener(new ItemListener() {
289 @Override
290 public void itemStateChanged(ItemEvent e) {
291 setJpegQualityPaneEnable();
292 }
293 });
294 return colorDepthPanel;
295 }
296
297 private void addJpegQualityLevelPane(JPanel encodingsPanel) {
298 useJpegQuality = new JCheckBox("Allow JPEG, set quality level:");
299 useJpegQuality.setAlignmentX(LEFT_ALIGNMENT);
300 encodingsPanel.add(useJpegQuality);
301
302 JPanel jpegQualityPane = new JPanel();
303 jpegQualityPane.setAlignmentX(LEFT_ALIGNMENT);
304 jpegQualityPoorLabel = new JLabel("poor");
305 jpegQualityPane.add(jpegQualityPoorLabel);
306 jpegQuality = new JSlider(1, 9, 9);
307 jpegQualityPane.add(jpegQuality);
308 jpegQuality.setPaintTicks(true);
309 jpegQuality.setMinorTickSpacing(1);
310 jpegQuality.setMajorTickSpacing(1);
311 jpegQuality.setPaintLabels(true);
312 jpegQuality.setSnapToTicks(true);
313 jpegQuality.setFont(
314 jpegQuality.getFont().deriveFont((float) 8));
315 jpegQualityBestLabel = new JLabel("best");
316 jpegQualityPane.add(jpegQualityBestLabel);
317 encodingsPanel.add(jpegQualityPane);
318
319 jpegQualityPoorLabel.setFont(jpegQualityPoorLabel.getFont().deriveFont((float) 10));
320 jpegQualityBestLabel.setFont(jpegQualityBestLabel.getFont().deriveFont((float) 10));
321
322 useJpegQuality.addActionListener(new ActionListener() {
323 @Override
324 public void actionPerformed(ActionEvent e) {
325 setJpegQualityPaneEnable();
326 }
327 });
328 }
329
330 protected void setJpegQualityPaneEnable() {
331 if (useJpegQuality != null && colorDepth != null) {
332 int depth = ((ColorDepthSelectItem)colorDepth.getSelectedItem()).depth;
333 setEnabled(whetherJpegQualityPaneBeEnabled(depth), useJpegQuality);
334 setEnabled(useJpegQuality.isSelected() && whetherJpegQualityPaneBeEnabled(depth),
335 jpegQuality, jpegQualityPoorLabel, jpegQualityBestLabel);
336 }
337 }
338
339 private boolean whetherJpegQualityPaneBeEnabled(int depth) {
340 return ProtocolSettings.COLOR_DEPTH_16 == depth ||
341 ProtocolSettings.COLOR_DEPTH_24 == depth ||
342 ProtocolSettings.COLOR_DEPTH_SERVER_SETTINGS == depth;
343 }
344
345 private void addCompressionLevelPane(JPanel encodingsPanel) {
346 useCompressionLevel = new JCheckBox("Custom compression level:");
347 useCompressionLevel.setAlignmentX(LEFT_ALIGNMENT);
348 encodingsPanel.add(useCompressionLevel);
349
350 JPanel compressionLevelPane = new JPanel();
351 compressionLevelPane.setAlignmentX(LEFT_ALIGNMENT);
352 compressionLevelFastLabel = new JLabel("fast");
353 compressionLevelPane.add(compressionLevelFastLabel);
354 compressionLevel = new JSlider(1, 9, 1);
355 compressionLevelPane.add(compressionLevel);
356 compressionLevel.setPaintTicks(true);
357 compressionLevel.setMinorTickSpacing(1);
358 compressionLevel.setMajorTickSpacing(1);
359 compressionLevel.setPaintLabels(true);
360 compressionLevel.setSnapToTicks(true);
361 compressionLevel.setFont(compressionLevel.getFont().deriveFont((float) 8));
362 compressionLevelBestLabel = new JLabel("best");
363 compressionLevelPane.add(compressionLevelBestLabel);
364 encodingsPanel.add(compressionLevelPane);
365
366 compressionLevelFastLabel.setFont(compressionLevelFastLabel.getFont().deriveFont((float) 10));
367 compressionLevelBestLabel.setFont(compressionLevelBestLabel.getFont().deriveFont((float) 10));
368
369 useCompressionLevel.addActionListener(new ActionListener() {
370 @Override
371 public void actionPerformed(ActionEvent e) {
372 setEnabled(useCompressionLevel.isSelected(),
373 compressionLevel, compressionLevelFastLabel, compressionLevelBestLabel);
374 }
375 });
376 setCompressionLevelPaneEnable();
377 }
378
379 protected void setCompressionLevelPaneEnable() {
380 setEnabled(useCompressionLevel.isSelected(),
381 compressionLevel, compressionLevelFastLabel, compressionLevelBestLabel);
382 }
383 private void setEnabled(boolean isEnabled, JComponent ... comp) {
384 for (JComponent c : comp) {
385 c.setEnabled(isEnabled);
386 }
387 }
388
389 private JPanel createLocalShapePanel() {
390 JPanel localCursorShapePanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
391 // localCursorShapePanel.setLayout(new BoxLayout(localCursorShapePanel, BoxLayout.Y_AXIS));
392 localCursorShapePanel.setBorder(
393 BorderFactory.createTitledBorder(
394 BorderFactory.createEtchedBorder(), "Local cursor shape"));
395 Box localCursorShapeBox = Box.createVerticalBox();
396 localCursorShapePanel.add(localCursorShapeBox);
397
398 ButtonGroup mouseCursorShapeTrackGroup = new ButtonGroup();
399 mouseCursorShapeSelected = new RadioButtonSelectedState<LocalMouseCursorShape>();
400 mouseCursorShapeMap = new HashMap<LocalMouseCursorShape, JRadioButton>();
401
402 addRadioButton("Dot cursor", LocalMouseCursorShape.DOT,
403 mouseCursorShapeSelected, mouseCursorShapeMap, localCursorShapeBox,
404 mouseCursorShapeTrackGroup);
405
406 addRadioButton("Small dot cursor", LocalMouseCursorShape.SMALL_DOT,
407 mouseCursorShapeSelected, mouseCursorShapeMap, localCursorShapeBox,
408 mouseCursorShapeTrackGroup);
409
410 addRadioButton("System default cursor", LocalMouseCursorShape.SYSTEM_DEFAULT,
411 mouseCursorShapeSelected, mouseCursorShapeMap, localCursorShapeBox,
412 mouseCursorShapeTrackGroup);
413
414 addRadioButton("No local cursor", LocalMouseCursorShape.NO_CURSOR,
415 mouseCursorShapeSelected, mouseCursorShapeMap, localCursorShapeBox,
416 mouseCursorShapeTrackGroup);
417
418 return localCursorShapePanel;
419 }
420
421 private JPanel createMouseCursorPanel() {
422 JPanel mouseCursorPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
423 mouseCursorPanel.setBorder(
424 BorderFactory.createTitledBorder(
425 BorderFactory.createEtchedBorder(), "Mouse Cursor"));
426 Box mouseCursorBox = Box.createVerticalBox();
427 mouseCursorPanel.add(mouseCursorBox);
428
429 ButtonGroup mouseCursorTrackGroup = new ButtonGroup();
430
431 mouseCursorTrackSelected = new RadioButtonSelectedState<LocalPointer>();
432 mouseCursorTrackMap = new HashMap<LocalPointer, JRadioButton>();
433
434 addRadioButton("Track remote cursor locally", LocalPointer.ON,
435 mouseCursorTrackSelected, mouseCursorTrackMap, mouseCursorBox,
436 mouseCursorTrackGroup);
437 addRadioButton("Let remote server deal with mouse cursor",
438 LocalPointer.OFF,
439 mouseCursorTrackSelected, mouseCursorTrackMap, mouseCursorBox,
440 mouseCursorTrackGroup);
441 addRadioButton("Don't show remote cursor", LocalPointer.HIDE,
442 mouseCursorTrackSelected, mouseCursorTrackMap, mouseCursorBox,
443 mouseCursorTrackGroup);
444 return mouseCursorPanel;
445 }
446
447 private static class RadioButtonSelectedState<T> {
448 private T state;
449
450 public void setSelected(T state) {
451 this.state = state;
452 }
453
454 public T getSelected() {
455 return state;
456 }
457
458 }
459
460 private <T> JRadioButton addRadioButton(String text, final T state,
461 final RadioButtonSelectedState<T> selected,
462 Map<T, JRadioButton> state2buttonMap, JComponent component, ButtonGroup group) {
463 JRadioButton radio = new JRadioButton(text);
464 radio.addActionListener(new ActionListener() {
465 @Override
466 public void actionPerformed(ActionEvent e) {
467 selected.setSelected(state);
468 }
469 });
470 component.add(radio);
471 group.add(radio);
472 state2buttonMap.put(state, radio);
473 return radio;
474 }
475
476 private void addButtons(final WindowListener onClose) {
477 JPanel buttonPanel = new JPanel();
478 JButton loginButton = new JButton("Ok");
479 buttonPanel.add(loginButton);
480 loginButton.addActionListener(new ActionListener() {
481 @Override
482 public void actionPerformed(ActionEvent e) {
483 setSettingsFromControls();
484 setVisible(false);
485 }
486 });
487
488 JButton closeButton = new JButton("Cancel");
489 buttonPanel.add(closeButton);
490 closeButton.addActionListener(new ActionListener() {
491 @Override
492 public void actionPerformed(ActionEvent e) {
493 onClose.windowClosing(null);
494 }
495 });
496 add(buttonPanel, BorderLayout.SOUTH);
497 }
498
499 }