1 /***
2 *
3 */
4 package org.telscenter.pas.steps;
5
6 import java.awt.BorderLayout;
7 import java.awt.Color;
8 import java.awt.FlowLayout;
9 import java.awt.event.ActionEvent;
10 import java.awt.event.ActionListener;
11 import java.awt.event.WindowAdapter;
12 import java.awt.event.WindowEvent;
13 import java.util.Collection;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Set;
17 import java.util.Map.Entry;
18
19 import javax.swing.Action;
20 import javax.swing.BorderFactory;
21 import javax.swing.ImageIcon;
22 import javax.swing.JButton;
23 import javax.swing.JDialog;
24 import javax.swing.JLabel;
25 import javax.swing.JPanel;
26 import javax.swing.JScrollPane;
27 import javax.swing.JTabbedPane;
28 import javax.swing.JTextArea;
29 import javax.swing.event.ChangeEvent;
30 import javax.swing.event.ChangeListener;
31
32 import net.sf.sail.jaxb.extension.BlockInteractionType;
33
34 import org.apache.commons.lang.StringUtils;
35 import org.imsglobal.xsd.imsqti_v2p0.ExtendedTextInteractionType;
36 import org.telscenter.pas.common.ui.CommonUI;
37 import org.telscenter.pas.common.ui.tab.PasTabbedPaneUI;
38 import org.telscenter.pas.common.ui.text.CurrentLineHighlighter;
39 import org.telscenter.pas.steps.actions.JaxbQtiNoteSaveAction;
40 import org.telscenter.pas.ui.dialog.PasDialogManager;
41 import org.telscenter.pas.ui.dialog.PasMessageDialogUI;
42 import org.telscenter.pas.ui.dialog.PasNoteMessageDialogUI;
43 import org.telscenter.pas.ui.icons.PasCommonIconProvider;
44 import org.telscenter.pas.ui.util.PasColors;
45
46 /***
47 * @author aperritano
48 *
49 */
50 public class JaxbQtiNoteUI extends JaxbQtiStepUI implements INoteUI {
51
52 private boolean noteOpen;
53
54 private boolean noteSaveConfirmed;
55
56 private boolean noteSavePartsConfirmed;
57
58 /***
59 *
60 */
61 public JaxbQtiNoteUI(JaxbQtiStep note) {
62 super(note);
63 }
64
65 /***
66 *
67 */
68 protected void initUI() {
69 assessment.setTabbed(true);
70 if (assessment.getAssessmentItem() == null
71 || assessment.getAssessmentItem().getItemBody()
72 .getBlockElementGroup().size() == 0) {
73 this.setLayout(new FlowLayout(FlowLayout.CENTER));
74 this.setOpaque(false);
75 JLabel noLabel = new JLabel("This Note has no items.");
76 noLabel.setOpaque(false);
77 this.add(noLabel, BorderLayout.CENTER);
78 return;
79 }
80
81 List<Object> interactions = assessment.getAssessmentItem().getItemBody().getBlockElementGroup();
82
83 this.setLayout(new BorderLayout(0, 0));
84 this.setBackground(PasColors.noteBackgroundColor);
85
86 tabbedPane = new JTabbedPane();
87 tabbedPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
88 tabbedPane.setBackground(PasColors.noteTabBackgrounColor);
89 tabbedPane.setUI(new PasTabbedPaneUI());
90 tabbedPane.addChangeListener(new ChangeListener() {
91
92 public void stateChanged(ChangeEvent e) {
93
94 if (nextTabButton != null || previousTabButton != null)
95 checkTab();
96
97 }
98 });
99
100 if (interactions.size() > 1) {
101 showTabButtons = true;
102 } else {
103 showTabButtons = false;
104 }
105
106 int i = 0;
107 for (Object interaction : interactions) {
108 JPanel itemPanel = createAssessmentItemPanel((BlockInteractionType) interaction);
109 itemPanel.setOpaque(true);
110 itemPanel
111 .setBackground(PasColors.noteTextInteractionFillPanelBackgrounColor);
112
113
114
115
116 JPanel wpanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
117 wpanel
118 .setBackground(PasColors.noteTextInteractionFillPanelBackgrounColor);
119
120
121 if (showTabButtons) {
122 wpanel.setBorder(BorderFactory.createEmptyBorder(2, 2, 0, 2));
123
124 } else {
125 wpanel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
126 }
127 wpanel.putClientProperty(ITEM_COMPLETED, new Boolean(false));
128 wpanel.add(itemPanel, BorderLayout.CENTER);
129
130 JScrollPane scrollPane = new JScrollPane();
131 scrollPane.getViewport().add(wpanel);
132 scrollPane
133 .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
134 scrollPane
135 .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
136 scrollPane.setBorder(BorderFactory.createEmptyBorder());
137 scrollPane
138 .setBackground(PasColors.noteTextInteractionFillPanelBackgrounColor);
139 scrollPane
140 .setBorder(BorderFactory.createLineBorder(Color.white, 2));
141 interactionsToTabindex.put((BlockInteractionType) interaction, new Integer(i));
142 tabbedPane.addTab("Part " + (i + 1), scrollPane);
143
144 i += 1;
145 }
146
147
148 Collection<JTextArea> textAreas = textInteractionsToTextareas.values();
149 for (JTextArea ta : textAreas) {
150 CurrentLineHighlighter.install(ta);
151 }
152
153 checkTabsAndPlaceHolder();
154
155 JPanel comboPanel = new JPanel(new BorderLayout(0, 0));
156 comboPanel.setOpaque(false);
157 comboPanel.add(tabbedPane, BorderLayout.CENTER);
158 comboPanel.setBorder(BorderFactory.createEmptyBorder(0, 2, 4, 2));
159
160 JPanel innerButtonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
161 innerButtonPanel
162 .setBackground(PasColors.noteTextInteractionFillPanelBackgrounColor);
163
164 previousTabButton = new JButton(
165 new PreviousTabAction("prev", new ImageIcon(
166 PasCommonIconProvider.getImage("previousTab.png"))));
167 previousTabButton.setHorizontalAlignment(JButton.RIGHT);
168 previousTabButton.setVerticalAlignment(JButton.TOP);
169 previousTabButton.setVerticalTextPosition(JButton.TOP);
170
171 nextTabButton = new JButton(new NextTabAction("next", new ImageIcon(
172 PasCommonIconProvider.getImage("nextTab.png"))));
173 nextTabButton.setHorizontalTextPosition(JButton.LEFT);
174 nextTabButton.setVerticalAlignment(JButton.TOP);
175 nextTabButton.setVerticalTextPosition(JButton.TOP);
176
177 this.checkTab();
178
179 innerButtonPanel.add(CommonUI.makeEnhancedButton(previousTabButton));
180 innerButtonPanel.add(CommonUI.makeEnhancedButton(nextTabButton));
181
182 JPanel shifterButtonsPanel = new JPanel(new BorderLayout(0, 0));
183 shifterButtonsPanel.setBackground(Color.WHITE);
184 shifterButtonsPanel.add(innerButtonPanel, BorderLayout.CENTER);
185 shifterButtonsPanel.setBorder(BorderFactory.createEmptyBorder(0, 2, 2,
186 2));
187
188 if (showTabButtons)
189 comboPanel.add(shifterButtonsPanel, BorderLayout.SOUTH);
190
191 this.add(comboPanel, BorderLayout.CENTER);
192
193
194
195 final JaxbQtiNoteSaveAction saveAction = getSaveAction();
196 JButton saveButton = new JButton(saveAction.getValue(Action.NAME)
197 .toString());
198 saveButton.setToolTipText("Save this note");
199 saveButton.addActionListener(new ActionListener() {
200
201 public void actionPerformed(ActionEvent e) {
202
203 if (isCompleted()) {
204 saveAction.actionPerformed(e);
205 } else {
206 saveAction.actionPerformed(e);
207
208 }
209
210 }
211 });
212 CommonUI.makeEnhancedButton(saveButton);
213
214 JButton hintButton = new JButton();
215 CommonUI.makeHintbutton(hintButton);
216 hintButton.setEnabled(assessment.hasHints());
217 hintButton.addActionListener(new ActionListener() {
218
219 public void actionPerformed(ActionEvent e) {
220
221 final JButton b = (JButton) e.getSource();
222 b.setSelected(true);
223 b.setEnabled(false);
224
225 JDialog showHintDialog = CommonUI.showHintDialog(assessment.getHintSet(), null);
226 showHintDialog.addWindowListener(new WindowAdapter() {
227
228 public void windowOpened(WindowEvent e) {
229
230 }
231
232 public void windowActivated(WindowEvent arg0) {
233
234
235 };
236
237 public void windowClosed(WindowEvent arg0) {
238 b.setEnabled(true);
239 }
240 });
241 }
242 });
243
244
245
246
247 JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 4, 2));
248
249 buttonPanel.add(hintButton);
250 buttonPanel.add(saveButton);
251
252 buttonPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 20));
253
254 buttonPanel.setBackground(PasColors.noteButtonPanelBackgroundColor);
255 this.add(buttonPanel, BorderLayout.SOUTH);
256 this.validate();
257
258 }
259
260 /***
261 *
262 */
263 protected void checkTabsAndPlaceHolder() {
264 if (!assessment.getResponses().isEmpty()) {
265
266 Set<Entry<String, Object>> assessmentEntries = assessment
267 .getResponses().entrySet();
268
269
270 List<Object> someInteractions = assessment.getAssessmentItem().getItemBody().getBlockElementGroup();
271
272 for (Map.Entry<String, Object> pairs : assessmentEntries) {
273 String responseKey = pairs.getKey();
274 String responseValue = (String) pairs.getValue();
275
276 responseValue = StringUtils.trimToNull(responseValue);
277 if (responseValue != null && responseValue != null) {
278 for (Object interaction : someInteractions) {
279
280 BlockInteractionType bi = (BlockInteractionType)interaction;
281
282 if (bi.getResponseIdentifier().equals(responseKey)) {
283 showTabChecked(interactionsToTabindex.get(bi)
284 .intValue());
285
286 if (bi instanceof ExtendedTextInteractionType)
287 disablePlaceHolderButton(bi);
288 }
289 }
290 }
291 }
292 }
293 }
294
295 /***
296 * @param bi
297 */
298 protected void disablePlaceHolderButton(BlockInteractionType bi) {
299 Set<Entry<JButton, ExtendedTextInteractionType>> entrySet = placeholderButtonsToTextInteractions
300 .entrySet();
301 for (Entry<JButton, ExtendedTextInteractionType> entry : entrySet) {
302 BlockInteractionType block = (BlockInteractionType) entry.getValue();
303 if (block.equals(bi)) {
304 JButton placeholderbutton = entry.getKey();
305 placeholderbutton.setEnabled(false);
306 }
307 }
308 }
309
310 public JDialog showNoteSaveCheckDialog() {
311 final PasNoteMessageDialogUI ui = new PasNoteMessageDialogUI(
312 getSaveAction());
313
314
315 ui.setMessage("Do you want to save this note before closing?");
316 return PasDialogManager.showPasMessageDialog("Question?", ui
317 .createDialogPanel(), null, true);
318 }
319
320 public JDialog showNotePartsCheckDialog() {
321 final PasMessageDialogUI ui = new PasMessageDialogUI(true);
322
323
324 ui.setMessage("You need to complete all note parts before saving");
325 return PasDialogManager.showPasMessageDialog("Warning", ui
326 .createDialogPanel(), null, true);
327 }
328
329 public JDialog showNoteAlreadyOpenDialog() {
330 final PasMessageDialogUI ui = new PasMessageDialogUI(true);
331
332
333 ui.setMessage("You can only have one note open at a time.");
334 return PasDialogManager.showPasMessageDialog("Warning", ui
335 .createDialogPanel(), null, true);
336 }
337
338 /***
339 * @return the noteOpen
340 */
341 public boolean isNoteOpen() {
342 return noteOpen;
343 }
344
345 /***
346 * @param noteOpen
347 * the noteOpen to set
348 */
349 public void setNoteOpen(boolean openedNote) {
350 this.noteOpen = openedNote;
351 }
352
353 /***
354 * TODO maybe get rid of this (made for incremental refactoring)
355 *
356 * @return
357 */
358 public JaxbQtiNoteSaveAction getSaveAction() {
359
360 return new JaxbQtiNoteSaveAction(assessment.getAssessmentItem(), assessment
361 .getResponses(), assessment.getResponseDeclarationToSocks());
362 }
363
364
365
366 public void setNoteSaveConfirmed(boolean noteSaveConfirmed){
367 this.noteSaveConfirmed = noteSaveConfirmed;
368 }
369
370
371 /***
372 * @return
373 */
374 public boolean getNoteSaveConfirmed() {
375
376 return this.noteSaveConfirmed;
377 }
378
379 /***
380 * @return
381 */
382 public boolean getNoteSavePartsConfirmed() {
383
384 return this.noteSavePartsConfirmed;
385 }
386
387 /***
388 * @param b
389 */
390 public void setNoteSavePartsConfirmed(boolean b) {
391
392 this.noteSavePartsConfirmed = b;
393 }
394
395 }