1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package pl.edu.agh.cast.importer.wizard.page;
19
20 import java.lang.reflect.InvocationTargetException;
21 import java.util.HashMap;
22 import java.util.LinkedList;
23 import java.util.List;
24 import java.util.Map;
25
26 import org.apache.log4j.Logger;
27 import org.eclipse.core.runtime.IProgressMonitor;
28 import org.eclipse.jface.action.Action;
29 import org.eclipse.jface.action.IMenuListener;
30 import org.eclipse.jface.action.IMenuManager;
31 import org.eclipse.jface.action.MenuManager;
32 import org.eclipse.jface.action.Separator;
33 import org.eclipse.jface.dialogs.InputDialog;
34 import org.eclipse.jface.dialogs.ProgressMonitorDialog;
35 import org.eclipse.jface.operation.IRunnableWithProgress;
36 import org.eclipse.jface.viewers.TableViewer;
37 import org.eclipse.jface.window.Window;
38 import org.eclipse.osgi.util.NLS;
39 import org.eclipse.swt.SWT;
40 import org.eclipse.swt.events.KeyEvent;
41 import org.eclipse.swt.events.KeyListener;
42 import org.eclipse.swt.events.ModifyEvent;
43 import org.eclipse.swt.events.ModifyListener;
44 import org.eclipse.swt.events.SelectionAdapter;
45 import org.eclipse.swt.events.SelectionEvent;
46 import org.eclipse.swt.layout.GridData;
47 import org.eclipse.swt.layout.GridLayout;
48 import org.eclipse.swt.widgets.Button;
49 import org.eclipse.swt.widgets.Composite;
50 import org.eclipse.swt.widgets.Control;
51 import org.eclipse.swt.widgets.Event;
52 import org.eclipse.swt.widgets.Group;
53 import org.eclipse.swt.widgets.Label;
54 import org.eclipse.swt.widgets.Listener;
55 import org.eclipse.swt.widgets.Menu;
56 import org.eclipse.swt.widgets.Spinner;
57 import org.eclipse.swt.widgets.TableItem;
58 import org.eclipse.ui.IWorkbenchActionConstants;
59
60 import pl.edu.agh.cast.CastApplication;
61 import pl.edu.agh.cast.importer.base.data.DataRow;
62 import pl.edu.agh.cast.importer.base.data.IDataRow;
63 import pl.edu.agh.cast.importer.base.data.TabularData;
64 import pl.edu.agh.cast.importer.base.stat.AbstractErrorLogData;
65 import pl.edu.agh.cast.importer.base.stat.ErrorType;
66 import pl.edu.agh.cast.importer.base.stat.ErrorsLog;
67 import pl.edu.agh.cast.importer.base.stat.TokenErrorLogData;
68 import pl.edu.agh.cast.importer.wizard.Activator;
69 import pl.edu.agh.cast.importer.wizard.dialog.ErrorTypesDialog;
70 import pl.edu.agh.cast.importer.wizard.util.Messages;
71 import pl.edu.agh.cast.importer.wizard.utils.Images;
72 import pl.edu.agh.cast.importer.wizard.utils.TableViewerHelper;
73 import pl.edu.agh.cast.ui.util.MsgBoxHelper;
74
75
76
77
78
79
80 public class ValidationPageComposite extends Composite {
81
82 private static final String[] ERROR_TABLE_CAPTIONS = new String[] { Messages.ValidationPageComposite_ErrorCode,
83 Messages.ValidationPageComposite_Message, Messages.ValidationPageComposite_Row,
84 Messages.ValidationPageComposite_Column, Messages.ValidationPageComposite_ErroneousToken };
85
86 private static final int DEFAULT_LINES_IGNORED = 1;
87
88 private static final int DEFAULT_HEADER_IDX = 1;
89
90 private static final int IGNORED_ROWS_COUNT_START = 0;
91
92 private static final int NO_HEADER_IDX = -1;
93
94 private final Logger log = Activator.getLogger();
95
96 private ValidationPage mediator;
97
98 private TabularData data;
99
100 private ErrorsLog errorsLog;
101
102 private TableViewer errorsTableViewer;
103
104 private TableViewer previewTableViewer;
105
106 private Group filePreviewGroup;
107
108 private Spinner ignoreRowsCountSpinner;
109
110 private Spinner treatAsHeaderSpinner;
111
112 private Composite optionsComposite;
113
114 private Button deleteErrorsByTypeBtn;
115
116 private Group operationsGroup;
117
118 private Button deleteSelectedBtn;
119
120 private Composite bottomComposite;
121
122 private Group statsGroup;
123
124 private Button deleteAllBtn;
125
126 private Button undoBtn;
127
128 private Button redoBtn;
129
130 private Button ignoreRowsCountChBox;
131
132 private Button treatRowAsHeaderChBox;
133
134 private Label totalStatsLbl;
135
136 private Label warningStatsLbl;
137
138 private Label errorStatsLbl;
139
140 private int ignoredRowsCount = IGNORED_ROWS_COUNT_START;
141
142 private String[] emptyTokenReplacements;
143
144 private Map<Integer, List<DataRow>> emptyTokensCache;
145
146
147
148
149
150
151
152
153
154
155
156 public ValidationPageComposite(Composite parent, int style, ValidationPage mediator) {
157 super(parent, style);
158 this.mediator = mediator;
159 initGUI();
160 }
161
162 private void initGUI() {
163 GridLayout thisLayout = new GridLayout();
164 this.setLayout(thisLayout);
165 this.setSize(800, 600);
166
167
168 this.addListener(SWT.Traverse, new Listener() {
169 public void handleEvent(Event event) {
170 if (event.detail == SWT.TRAVERSE_RETURN) {
171 event.detail = SWT.TRAVERSE_TAB_NEXT;
172 }
173 }
174 });
175
176 filePreviewGroup = new Group(this, SWT.NONE);
177 GridLayout filePreviewGroupLayout = new GridLayout();
178 filePreviewGroup.setLayout(filePreviewGroupLayout);
179 GridData filePreviewGroupLData = new GridData(SWT.FILL, SWT.FILL, true, true);
180 filePreviewGroupLData.minimumWidth = 550;
181 filePreviewGroupLData.minimumHeight = 150;
182 filePreviewGroup.setLayoutData(filePreviewGroupLData);
183 filePreviewGroup.setText(Messages.ValidationPage_FilePreview);
184
185 previewTableViewer = new TableViewer(filePreviewGroup, SWT.BORDER | SWT.FULL_SELECTION | SWT.V_SCROLL
186 | SWT.H_SCROLL);
187 GridData previewTableViewerLData = new GridData(SWT.FILL, SWT.FILL, true, true);
188 previewTableViewerLData.minimumWidth = 500;
189 previewTableViewerLData.heightHint = 120;
190 previewTableViewer.getControl().setLayoutData(previewTableViewerLData);
191 previewTableViewer.getTable().setSize(-1, -1);
192
193 bottomComposite = new Composite(this, SWT.NONE);
194 GridData bottomCompositeLData = new GridData(SWT.FILL, SWT.FILL, true, true);
195 GridLayout bottomCompositeLayout = new GridLayout(2, false);
196 bottomComposite.setLayout(bottomCompositeLayout);
197 bottomComposite.setLayoutData(bottomCompositeLData);
198
199 statsGroup = new Group(bottomComposite, SWT.NONE);
200 GridLayout statsGroupLayout = new GridLayout();
201 statsGroupLayout.verticalSpacing = 2;
202 statsGroup.setLayout(statsGroupLayout);
203 GridData statsGroupLData = new GridData(SWT.FILL, SWT.FILL, false, true);
204 statsGroup.setLayoutData(statsGroupLData);
205 statsGroup.setText(Messages.ValidationPage_StatsGroupTitle);
206
207 errorsTableViewer = new TableViewer(bottomComposite, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI
208 | SWT.FULL_SELECTION);
209 GridData errorsTableViewerLData = new GridData(SWT.FILL, SWT.FILL, true, true);
210 errorsTableViewerLData.verticalSpan = 2;
211 errorsTableViewerLData.heightHint = 260;
212 errorsTableViewer.getControl().setLayoutData(errorsTableViewerLData);
213 errorsTableViewer.getTable().addSelectionListener(new SelectionAdapter() {
214 @Override
215 public void widgetSelected(SelectionEvent event) {
216 handleErrorsTableItemsSelection(event);
217 }
218 });
219 errorsTableViewer.getTable().addKeyListener(new KeyListener() {
220 public void keyPressed(KeyEvent event) {
221
222 }
223
224 public void keyReleased(KeyEvent event) {
225 if (event.character == SWT.DEL) {
226 handleDeleteSelectedRows();
227 }
228 }
229 });
230
231 operationsGroup = new Group(bottomComposite, SWT.NONE);
232 GridLayout operationsGroupLayout = new GridLayout(2, true);
233 operationsGroup.setLayout(operationsGroupLayout);
234 GridData operationsGroupLData = new GridData(SWT.FILL, SWT.FILL, false, false);
235 operationsGroup.setLayoutData(operationsGroupLData);
236
237 optionsComposite = new Composite(operationsGroup, SWT.NONE);
238 GridLayout optionsCompositeLayout = new GridLayout(2, false);
239 GridData optionsCompositeLData = new GridData(SWT.FILL, SWT.FILL, false, false);
240 optionsCompositeLData.horizontalSpan = 2;
241 optionsComposite.setLayout(optionsCompositeLayout);
242 optionsComposite.setLayoutData(optionsCompositeLData);
243
244 treatRowAsHeaderChBox = new Button(optionsComposite, SWT.CHECK);
245 GridData treatRowAsHeaderChBoxLData = new GridData();
246 treatRowAsHeaderChBox.setLayoutData(treatRowAsHeaderChBoxLData);
247 treatRowAsHeaderChBox.setText(Messages.ValidationPageComposite_TreatAsHeaderRow);
248 treatRowAsHeaderChBox.addSelectionListener(new SelectionAdapter() {
249 @Override
250 public void widgetSelected(SelectionEvent event) {
251 handleTreatRowAsHeaderChboxSelection();
252 }
253 });
254
255 treatAsHeaderSpinner = new Spinner(optionsComposite, SWT.BORDER);
256 treatAsHeaderSpinner.setMinimum(1);
257 treatAsHeaderSpinner.setSelection(DEFAULT_HEADER_IDX);
258 treatAsHeaderSpinner.setIncrement(1);
259 treatAsHeaderSpinner.setPageIncrement(100);
260 treatAsHeaderSpinner.pack();
261 treatAsHeaderSpinner.addModifyListener(new ModifyListener() {
262 public void modifyText(ModifyEvent event) {
263 handleTreatRowAsHeaderChboxSelection();
264 }
265 });
266
267 ignoreRowsCountChBox = new Button(optionsComposite, SWT.CHECK);
268 GridData ignoreRowsCountChkBoxLData = new GridData();
269 ignoreRowsCountChBox.setLayoutData(ignoreRowsCountChkBoxLData);
270 ignoreRowsCountChBox.setText(Messages.ValidationPage_IgnoreNumberOfRows);
271 ignoreRowsCountChBox.addSelectionListener(new SelectionAdapter() {
272 @Override
273 public void widgetSelected(SelectionEvent event) {
274 handleIgnoreRowsCountChboxSelection();
275 }
276 });
277
278 ignoreRowsCountSpinner = new Spinner(optionsComposite, SWT.BORDER);
279 ignoreRowsCountSpinner.setMinimum(1);
280 ignoreRowsCountSpinner.setSelection(DEFAULT_LINES_IGNORED);
281 ignoreRowsCountSpinner.setIncrement(1);
282 ignoreRowsCountSpinner.setPageIncrement(100);
283 ignoreRowsCountSpinner.pack();
284 ignoreRowsCountSpinner.addModifyListener(new ModifyListener() {
285 public void modifyText(ModifyEvent event) {
286 handleIgnoreRowsCountChboxSelection();
287 }
288 });
289
290 deleteSelectedBtn = new Button(operationsGroup, SWT.PUSH | SWT.CENTER);
291 GridData deleteSelectedBtnLData = new GridData(SWT.FILL, SWT.FILL, true, false);
292 deleteSelectedBtnLData.horizontalSpan = 2;
293 deleteSelectedBtn.setLayoutData(deleteSelectedBtnLData);
294 deleteSelectedBtn.setText(Messages.ValidationPage_DeleteSelected);
295 deleteSelectedBtn.addSelectionListener(new SelectionAdapter() {
296 @Override
297 public void widgetSelected(SelectionEvent event) {
298 handleDeleteSelectedRows();
299 }
300 });
301
302 deleteAllBtn = new Button(operationsGroup, SWT.PUSH | SWT.CENTER);
303 GridData deleteAllBtnLData = new GridData(SWT.FILL, SWT.FILL, true, false);
304 deleteAllBtnLData.horizontalSpan = 2;
305 deleteAllBtn.setLayoutData(deleteAllBtnLData);
306 deleteAllBtn.setText(Messages.ValidationPage_DeleteAll);
307 deleteAllBtn.addSelectionListener(new SelectionAdapter() {
308 @Override
309 public void widgetSelected(SelectionEvent event) {
310 handleDeleteAllRows();
311 }
312 });
313
314 deleteErrorsByTypeBtn = new Button(operationsGroup, SWT.PUSH | SWT.CENTER);
315 GridData deleteErrorsByTypeBtnLData = new GridData(SWT.FILL, SWT.FILL, true, false);
316 deleteErrorsByTypeBtnLData.horizontalSpan = 2;
317 deleteErrorsByTypeBtn.setLayoutData(deleteErrorsByTypeBtnLData);
318 deleteErrorsByTypeBtn.setText(Messages.ValidationPage_DeleteByType);
319 deleteErrorsByTypeBtn.addSelectionListener(new SelectionAdapter() {
320 @Override
321 public void widgetSelected(SelectionEvent event) {
322 handleDeleteErrorsByType();
323 }
324 });
325
326 undoBtn = new Button(operationsGroup, SWT.PUSH | SWT.CENTER);
327 GridData undoBtnLData = new GridData(SWT.FILL, SWT.FILL, true, true);
328 undoBtn.setLayoutData(undoBtnLData);
329 undoBtn.setText(Messages.ValidationPageComposite_Undo);
330 undoBtn.setEnabled(false);
331 undoBtn.addSelectionListener(new SelectionAdapter() {
332 @Override
333 public void widgetSelected(SelectionEvent event) {
334 handleUndoBtnPressed();
335 }
336 });
337
338 redoBtn = new Button(operationsGroup, SWT.PUSH | SWT.CENTER);
339 GridData redoBtnLData = new GridData(SWT.FILL, SWT.FILL, true, true);
340 redoBtn.setLayoutData(redoBtnLData);
341 redoBtn.setText(Messages.ValidationPageComposite_Redo);
342 redoBtn.setEnabled(false);
343 redoBtn.addSelectionListener(new SelectionAdapter() {
344 @Override
345 public void widgetSelected(SelectionEvent event) {
346 handleRedoBtnPressed();
347 }
348 });
349 }
350
351
352
353
354
355
356
357 private void handleErrorsTableItemsSelection(SelectionEvent event) {
358 if (event.item instanceof TableItem) {
359 AbstractErrorLogData error = (AbstractErrorLogData)event.item.getData();
360 IDataRow<?> row = error.getRow();
361
362 List<? extends IDataRow<?>> selectedRows = getRowsForSelectedErrors();
363
364 if (selectedRows != null) {
365 TableViewerHelper.setSelectedRows(previewTableViewer, selectedRows);
366 previewTableViewer.refresh(true);
367 previewTableViewer.reveal(row);
368 }
369 }
370 }
371
372 private void handleIgnoreRowsCountChboxSelection() {
373 if (isIgnoreRowsCountSet()) {
374 ignoreRowsCountSpinner.setEnabled(true);
375 int count = getIgnoredRowsCount();
376 if (count == -1) {
377 return;
378 }
379 ignoreFirstRows(count);
380 } else {
381 ignoreRowsCountSpinner.setEnabled(false);
382 ignoreFirstRows(0);
383 }
384 mediator.widgetModified();
385 }
386
387 private void handleTreatRowAsHeaderChboxSelection() {
388 if (isTreatRowAsHeaderSet()) {
389 treatAsHeaderSpinner.setEnabled(true);
390 int rowIdx = getTreatAsHeaderSelection();
391
392 data.setHeaderRowIdx(rowIdx);
393 errorsLog.setHeaderRowIdx(rowIdx);
394 TableViewerHelper.setHeaderRowIdx(previewTableViewer, rowIdx);
395
396 if (rowIdx >= 0) {
397 previewTableViewer.reveal(data.getRowByIndex(rowIdx));
398 }
399 } else {
400 treatAsHeaderSpinner.setEnabled(false);
401 data.setHeaderRowIdx(NO_HEADER_IDX);
402 errorsLog.setHeaderRowIdx(NO_HEADER_IDX);
403 TableViewerHelper.setHeaderRowIdx(previewTableViewer, NO_HEADER_IDX);
404 }
405 previewTableViewer.refresh(true);
406 errorsTableViewer.refresh(true);
407
408 mediator.widgetModified();
409 }
410
411 private void handleDeleteSelectedRows() {
412 int[] selectedErrors = getSelectedErrors();
413 if (selectedErrors == null || selectedErrors.length == 0) {
414 MsgBoxHelper.showWarningBox(this, Messages.ValidationPageComposite_DeleteSelectedRows,
415 Messages.ValidationPageComposite_DeleteSelectedRowsMsgBoxWarning);
416 return;
417 }
418
419 List<DataRow> rowsToDelete = getRowsForSelectedErrors();
420
421 StringBuilder rowIndicesMsg = new StringBuilder();
422 for (IDataRow<?> row : rowsToDelete) {
423 rowIndicesMsg.append("#");
424 rowIndicesMsg.append(row.getInputRowNumber() + 1);
425 rowIndicesMsg.append(", ");
426 }
427
428 rowIndicesMsg.delete(rowIndicesMsg.lastIndexOf(","), rowIndicesMsg.length());
429
430 if (MsgBoxHelper.showQuestionBox(this, Messages.ValidationPageComposite_DeleteSelectedRows, NLS.bind(
431 Messages.ValidationPageComposite_DeleteSelectedRowsMsgBoxQuestion, rowIndicesMsg.toString())) == SWT.YES) {
432 deleteRows(rowsToDelete, false);
433 updateStats();
434 updateUndoRedoState();
435
436 for (DataRow row : rowsToDelete) {
437 if (row.getInputRowNumber() == 0) {
438 disableIgnoreFirstRowsChBox();
439 break;
440 }
441 }
442
443 mediator.widgetModified();
444 }
445 }
446
447 private void handleDeleteAllRows() {
448 final List<DataRow> rowsToDelete = new LinkedList<DataRow>();
449 for (Integer rowIndex : errorsLog.keySet()) {
450 DataRow row = data.getRowByIndex(rowIndex);
451 rowsToDelete.add(row);
452 }
453
454 if (rowsToDelete == null || rowsToDelete.isEmpty()) {
455 MsgBoxHelper.showInfoBox(this, Messages.ValidationPageComposite_DeleteAllRows,
456 Messages.ValidationPageComposite_DeleteAllRowsMsgBoxWarning);
457 return;
458 }
459
460 if (MsgBoxHelper.showQuestionBox(this, Messages.ValidationPageComposite_DeleteAllRows,
461 Messages.ValidationPageComposite_DeleteAllRowsMsgBoxQuestion) == SWT.YES) {
462
463 IRunnableWithProgress rwp = new IRunnableWithProgress() {
464
465 @Override
466 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
467 monitor.beginTask(Messages.ValidationPageComposite_DeletingAllRows, IProgressMonitor.UNKNOWN);
468 getDisplay().syncExec(new Runnable() {
469
470 @Override
471 public void run() {
472 for (IDataRow<?> row : rowsToDelete) {
473 if (row.getInputRowNumber() == 0) {
474 disableIgnoreFirstRowsChBox();
475 }
476 }
477
478 data.removeRows(rowsToDelete);
479
480 errorsLog.clear();
481
482 previewTableViewer.refresh();
483 errorsTableViewer.refresh();
484
485
486 Object firstElem = previewTableViewer.getElementAt(0);
487 if (firstElem != null) {
488 previewTableViewer.reveal(firstElem);
489 }
490
491 updateStats();
492 updateUndoRedoState();
493 mediator.widgetModified();
494 }
495 });
496 monitor.done();
497 }
498 };
499
500 try {
501 new ProgressMonitorDialog(getShell()).run(true, false, rwp);
502 } catch (InvocationTargetException e) {
503 log.error(e.getMessage());
504 } catch (InterruptedException e) {
505 log.error(e.getMessage());
506 }
507 }
508 }
509
510 private void handleDeleteErrorsByType() {
511
512 ErrorTypesDialog dialog = new ErrorTypesDialog(this.getShell(), mediator);
513 dialog.open();
514
515 }
516
517 private void handleDeleteRowAction() {
518 int index = previewTableViewer.getTable().getSelectionIndex();
519 if (index < 0 || index >= previewTableViewer.getTable().getItemCount()) {
520 MsgBoxHelper.showWarningBox(this, Messages.ValidationPageComposite_DeleteRow,
521 Messages.ValidationPageComposite_DeleteRowMsgBoxWarning);
522 return;
523 }
524
525 DataRow row = (DataRow)previewTableViewer.getElementAt(index);
526 if (MsgBoxHelper.showQuestionBox(this, Messages.ValidationPageComposite_DeleteRow, NLS.bind(
527 Messages.ValidationPageComposite_DeleteRowMsgBoxQuestion, String.valueOf(row.getInputRowNumber() + 1))) == SWT.YES) {
528 List<DataRow> rowsToDelete = new LinkedList<DataRow>();
529 rowsToDelete.add(row);
530 deleteRows(rowsToDelete, false);
531 updateStats();
532 updateUndoRedoState();
533 mediator.widgetModified();
534 }
535 }
536
537 private void handleUndoBtnPressed() {
538 IRunnableWithProgress rwp = new IRunnableWithProgress() {
539
540 @Override
541 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
542 monitor.beginTask(Messages.ValidationPageComposite_UndoingOperation, IProgressMonitor.UNKNOWN);
543 getDisplay().syncExec(new Runnable() {
544
545 @Override
546 public void run() {
547 List<DataRow> rowsRestored = data.undoOperation();
548 for (DataRow row : rowsRestored) {
549 if (row.getInputRowNumber() == 0) {
550 ignoreRowsCountChBox.setEnabled(true);
551 }
552 }
553 errorsLog.undoOperation();
554 previewTableViewer.refresh();
555 errorsTableViewer.refresh();
556 redoBtn.setEnabled(true);
557
558 if (!data.isUndoAvailable()) {
559 undoBtn.setEnabled(false);
560 }
561 updateStats();
562 mediator.widgetModified();
563 }
564 });
565 monitor.done();
566 }
567 };
568
569 try {
570 new ProgressMonitorDialog(getShell()).run(true, false, rwp);
571 } catch (InvocationTargetException e) {
572 log.error(e.getMessage());
573 } catch (InterruptedException e) {
574 log.error(e.getMessage());
575 }
576 }
577
578 private void handleRedoBtnPressed() {
579 IRunnableWithProgress rwp = new IRunnableWithProgress() {
580
581 @Override
582 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
583 monitor.beginTask(Messages.ValidationPageComposite_RedoingOperation, IProgressMonitor.UNKNOWN);
584 getDisplay().syncExec(new Runnable() {
585
586 @Override
587 public void run() {
588 List<DataRow> rowsRemoved = data.redoOperation();
589 for (DataRow row : rowsRemoved) {
590 if (row.getInputRowNumber() == 0) {
591 disableIgnoreFirstRowsChBox();
592 }
593 }
594
595 errorsLog.redoOperation();
596 previewTableViewer.refresh();
597 errorsTableViewer.refresh();
598 undoBtn.setEnabled(true);
599
600 if (!data.isRedoAvailable()) {
601 redoBtn.setEnabled(false);
602 }
603 updateStats();
604 mediator.widgetModified();
605 }
606 });
607 monitor.done();
608 }
609 };
610
611 try {
612 new ProgressMonitorDialog(CastApplication.getDisplay().getActiveShell()).run(true, false, rwp);
613 } catch (InvocationTargetException e) {
614 log.error(e.getMessage());
615 } catch (InterruptedException e) {
616 log.error(e.getMessage());
617 }
618 }
619
620 private void handleEditTokenAction(TokenErrorLogData error) {
621 if (error == null) {
622 return;
623 }
624
625 int tokenIndex = error.getTokenIndex();
626
627 DataRow row = (DataRow)error.getRow();
628 InputDialog dialog = new InputDialog(this.getShell(), Messages.ValidationPageComposite_EditValue,
629 Messages.ValidationPageComposite_EnterNewValue, String.valueOf(row.get(tokenIndex)), null);
630 if (dialog.open() == Window.OK) {
631 changeRowValue(row, tokenIndex, dialog.getValue());
632 rowContentChanged(row);
633 }
634 }
635
636
637
638
639
640
641
642 public void deleteRowsWithErrors(List<AbstractErrorLogData> errorsToDelete) {
643 if (errorsToDelete == null || errorsToDelete.isEmpty()) {
644 throw new IllegalArgumentException("Cannot remove null or empty errors.");
645 }
646
647 List<DataRow> rowsToDelete = new LinkedList<DataRow>();
648 for (AbstractErrorLogData errorLogData : errorsToDelete) {
649 DataRow row = (DataRow)errorLogData.getRow();
650 if (row != null && !rowsToDelete.contains(row)) {
651 rowsToDelete.add(row);
652 }
653 }
654 deleteRows(rowsToDelete, false);
655 updateStats();
656 updateUndoRedoState();
657 mediator.widgetModified();
658 }
659
660 private void deleteRows(List<DataRow> rows, boolean ignored) {
661 if (rows == null || rows.isEmpty()) {
662 throw new IllegalArgumentException("Cannot remove null or empty rows.");
663 }
664
665
666 data.removeRows(rows, ignored);
667
668 Map<Integer, List<AbstractErrorLogData>> errorsToDelete = new HashMap<Integer, List<AbstractErrorLogData>>();
669 for (IDataRow<?> row : rows) {
670 if (errorsLog != null) {
671 List<AbstractErrorLogData> deletedRowErrors = errorsLog.get(row.getInputRowNumber());
672 errorsToDelete.put(row.getInputRowNumber(), deletedRowErrors);
673 }
674
675 if (!ignored && row.getInputRowNumber() == 0) {
676 disableIgnoreFirstRowsChBox();
677 }
678 }
679
680
681 errorsLog.removeErrors(errorsToDelete, ignored);
682
683 previewTableViewer.refresh();
684 errorsTableViewer.refresh();
685 }
686
687
688
689
690
691
692
693
694
695 public void replaceEmptyTokens(String newValue, int columnIndex) {
696 if (emptyTokenReplacements == null || newValue == null || newValue.trim().length() == 0) {
697 return;
698 }
699
700 List<DataRow> rowsWithEmptyTokens = new LinkedList<DataRow>();
701 for (DataRow row : data) {
702 while (columnIndex >= row.size()) {
703 row.add(null);
704 }
705
706 Object oldValue = row.get(columnIndex - 1);
707 if (oldValue == null) {
708 changeRowValue(row, columnIndex - 1, newValue.trim());
709 rowsWithEmptyTokens.add(row);
710 }
711 }
712
713 saveToEmptyTokensCache(columnIndex, rowsWithEmptyTokens);
714 emptyTokenReplacements[columnIndex - 1] = newValue;
715 TableViewerHelper.setEmptyTokensReplacements(previewTableViewer, emptyTokensCache);
716 errorsTableViewer.refresh();
717 previewTableViewer.refresh();
718 updateStats();
719 }
720
721
722
723
724
725
726
727 public void restoreEmptyTokens(int columnIndex) {
728 if (emptyTokensCache == null || !emptyTokensCache.containsKey(columnIndex)) {
729 return;
730 }
731
732 List<DataRow> rows = emptyTokensCache.get(columnIndex);
733 for (DataRow row : rows) {
734 changeRowValue(row, columnIndex - 1, null);
735 }
736
737 emptyTokensCache.remove(columnIndex);
738 emptyTokenReplacements[columnIndex - 1] = null;
739 TableViewerHelper.setEmptyTokensReplacements(previewTableViewer, emptyTokensCache);
740 errorsTableViewer.refresh();
741 previewTableViewer.refresh();
742 updateStats();
743 }
744
745 private void saveToEmptyTokensCache(int columnIndex, List<DataRow> rows) {
746 if (emptyTokensCache == null) {
747 emptyTokensCache = new HashMap<Integer, List<DataRow>>();
748 }
749
750 emptyTokensCache.put(columnIndex, rows);
751 }
752
753
754
755
756
757
758
759
760
761 private void initErrorsTable() {
762 TableViewerHelper.initErrorTable(errorsTableViewer, ERROR_TABLE_CAPTIONS, true, 2);
763 if (errorsLog != null) {
764 errorsTableViewer.setInput(errorsLog);
765 } else {
766 errorsTableViewer.setInput(null);
767 disableErrorControls();
768 }
769 errorsTableViewer.getTable().setLinesVisible(true);
770 errorsTableViewer.getTable().setHeaderVisible(true);
771 errorsTableViewer.getTable().setMenu(createPopupMenu(errorsTableViewer.getTable()));
772 TableViewerHelper.adjustColumnWidth(errorsTableViewer);
773 errorsTableViewer.refresh();
774 }
775
776 private void initPreviewTable(TabularData tabData) {
777 TableViewerHelper.initTable(previewTableViewer, null, false, true, tabData, errorsLog, this);
778 previewTableViewer.getTable().setLinesVisible(true);
779 previewTableViewer.getTable().setHeaderVisible(true);
780 previewTableViewer.getTable().setMenu(createDataTableViewerPopupMenu(previewTableViewer.getTable()));
781 TableViewerHelper.adjustColumnWidth(previewTableViewer);
782 previewTableViewer.refresh();
783 }
784
785 private void updateStats() {
786 int rowsCount = 0;
787 int erroneousRowsCount = 0;
788 int errorsCount = 0;
789 int warningsCount = 0;
790
791 if (data != null) {
792 rowsCount = data.size();
793 }
794
795 if (errorsLog != null) {
796 erroneousRowsCount = errorsLog.getErroneousRowsCount();
797 errorsCount = errorsLog.getErrorsCount();
798 warningsCount = errorsLog.getWarningsCount();
799 }
800
801 if (totalStatsLbl != null) {
802 totalStatsLbl.dispose();
803 }
804
805 if (errorStatsLbl != null) {
806 errorStatsLbl.dispose();
807 }
808
809 if (warningStatsLbl != null) {
810 warningStatsLbl.dispose();
811 }
812
813 totalStatsLbl = new Label(statsGroup, SWT.WRAP);
814 totalStatsLbl.setText(NLS.bind(Messages.ValidationPageComposite_NumberOfRows, String.valueOf(rowsCount), String
815 .valueOf(erroneousRowsCount)));
816
817 errorStatsLbl = new Label(statsGroup, SWT.NONE);
818 errorStatsLbl.setText(NLS.bind(Messages.ValidationPageComposite_NumberOfParseErrors, String
819 .valueOf(errorsCount)));
820
821 warningStatsLbl = new Label(statsGroup, SWT.NONE);
822 warningStatsLbl.setText(NLS.bind(Messages.ValidationPageComposite_NumberOfParseWarnings, String
823 .valueOf(warningsCount)));
824
825 statsGroup.layout();
826
827 updateTitleBar();
828 }
829
830
831
832
833 private void updateTitleBar() {
834 if (errorsLog == null) {
835 mediator.setImageDescriptor(Images.getInstance().getDescriptor(Images.CLEAR));
836 } else if (errorsLog.getErrorsCount() > 0) {
837 mediator.setImageDescriptor(Images.getInstance().getDescriptor(Images.ERROR));
838 } else if (errorsLog.getWarningsCount() > 0) {
839 mediator.setImageDescriptor(Images.getInstance().getDescriptor(Images.WARNING));
840 } else {
841 mediator.setImageDescriptor(Images.getInstance().getDescriptor(Images.CLEAR));
842 }
843 }
844
845 private void disableErrorControls() {
846 deleteAllBtn.setEnabled(false);
847 deleteSelectedBtn.setEnabled(false);
848 deleteErrorsByTypeBtn.setEnabled(false);
849 }
850
851 private void updateUndoRedoState() {
852 undoBtn.setEnabled(true);
853 redoBtn.setEnabled(false);
854 }
855
856
857
858
859
860
861
862
863
864 public void refreshPage(TabularData tabData, ErrorsLog errors) {
865 if (tabData != null) {
866 this.data = tabData;
867 this.emptyTokenReplacements = new String[data.getColumnsCount()];
868 this.errorsLog = errors;
869
870 initPreviewTable(data);
871 initErrorsTable();
872
873 updateStats();
874 resetIgnoreRowsCount();
875 resetTreatRowAsHeader();
876 handleTreatRowAsHeaderChboxSelection();
877 }
878 }
879
880 private void ignoreFirstRows(int count) {
881 if (count < 0) {
882 throw new IllegalArgumentException("Cannot ignore a negative number of lines.");
883 }
884
885 int rowCount = count - ignoredRowsCount;
886 if (rowCount == 0) {
887 return;
888 } else if (rowCount > 0) {
889
890 List<DataRow> rowsToRemove = new LinkedList<DataRow>();
891 for (int i = 0; i < rowCount; i++) {
892 rowsToRemove.add(data.get(i));
893 }
894
895 deleteRows(rowsToRemove, true);
896 } else {
897
898 List<DataRow> rowsRestored = data.restoreIgnoredRows(-rowCount);
899 for (DataRow row : rowsRestored) {
900 errorsLog.restoreIgnoredError(row.getInputRowNumber());
901 }
902 }
903 ignoredRowsCount += rowCount;
904
905 previewTableViewer.refresh();
906 errorsTableViewer.refresh();
907
908 updateStats();
909 }
910
911 private void disableIgnoreFirstRowsChBox() {
912 ignoreRowsCountChBox.setEnabled(false);
913 ignoreRowsCountChBox.setSelection(false);
914 }
915
916 private void resetIgnoreRowsCount() {
917 ignoreRowsCountChBox.setSelection(false);
918 ignoreRowsCountSpinner.setSelection(DEFAULT_LINES_IGNORED);
919 ignoreRowsCountSpinner.setMaximum(data.size());
920 ignoreRowsCountSpinner.setEnabled(false);
921 ignoredRowsCount = IGNORED_ROWS_COUNT_START;
922 }
923
924 private void resetTreatRowAsHeader() {
925 treatRowAsHeaderChBox.setSelection(true);
926 treatAsHeaderSpinner.setSelection(DEFAULT_HEADER_IDX);
927 treatAsHeaderSpinner.setMaximum(data.size());
928 treatAsHeaderSpinner.setEnabled(true);
929 }
930
931
932
933
934
935
936
937 public void rowContentChanged(DataRow row) {
938 previewTableViewer.update(row, null);
939 previewTableViewer.refresh();
940 errorsTableViewer.refresh();
941 updateStats();
942 mediator.widgetModified();
943 }
944
945
946
947
948
949
950
951
952
953
954
955 public void changeRowValue(DataRow row, int index, String value) {
956 mediator.getImportProcess().changeRowValue(row, index, value);
957 }
958
959
960
961
962
963
964
965
966
967 private Menu createDataTableViewerPopupMenu(Control control) {
968 final Action deleteAction = new Action() {
969 @Override
970 public void run() {
971 handleDeleteRowAction();
972 }
973 };
974 deleteAction.setText(Messages.ValidationPageComposite_DeleteRow);
975
976 final MenuManager popupMenu = new MenuManager();
977 popupMenu.add(deleteAction);
978
979 return popupMenu.createContextMenu(control);
980 }
981
982 private Menu createPopupMenu(Control control) {
983
984
985 final Action deleteSelected = new Action() {
986 @Override
987 public void run() {
988 handleDeleteSelectedRows();
989 }
990 };
991 deleteSelected.setText(Messages.ValidationPage_DeleteSelected);
992
993 final Action deleteByTypeSelected = new Action() {
994 @Override
995 public void run() {
996 int[] selected = getSelectedErrors();
997 if (selected.length == 1) {
998 ErrorType errorType = ((AbstractErrorLogData)errorsTableViewer.getElementAt(selected[0]))
999 .getErrorType();
1000 deleteRowsWithErrors(errorsLog.getErrorsByType(errorType));
1001
1002 }
1003 }
1004 };
1005 deleteByTypeSelected.setText(Messages.ValidationPage_DeleteByType);
1006
1007 final Action editSelected = new Action() {
1008 @Override
1009 public void run() {
1010 int[] selected = getSelectedErrors();
1011 if (selected.length == 1) {
1012 AbstractErrorLogData error = (AbstractErrorLogData)errorsTableViewer.getElementAt(selected[0]);
1013 if (error instanceof TokenErrorLogData) {
1014 TokenErrorLogData tokenError = (TokenErrorLogData)error;
1015 handleEditTokenAction(tokenError);
1016 }
1017 }
1018 }
1019 };
1020 editSelected.setText(Messages.ValidationPageComposite_Edit);
1021
1022 final Action treatRowAsHeader = new Action() {
1023 @Override
1024 public void run() {
1025 int[] selected = getSelectedErrors();
1026 if (selected.length == 1) {
1027 List<DataRow> rows = getRowsForSelectedErrors();
1028 if (rows != null && rows.size() == 1) {
1029 treatRowAsHeaderChBox.setSelection(true);
1030 int rowIdx = rows.get(0).getInputRowNumber();
1031
1032 treatAsHeaderSpinner.setSelection(rowIdx + 1);
1033 optionsComposite.layout(true);
1034 handleTreatRowAsHeaderChboxSelection();
1035 }
1036 }
1037 }
1038 };
1039 treatRowAsHeader.setText(Messages.ValidationPageComposite_TreatAsHeader);
1040
1041 final MenuManager popupMenu = new MenuManager();
1042 popupMenu.setRemoveAllWhenShown(true);
1043 popupMenu.addMenuListener(new IMenuListener() {
1044 public void menuAboutToShow(IMenuManager manager) {
1045 int[] selectedErrors = getSelectedErrors();
1046 if (selectedErrors.length > 0) {
1047 manager.add(deleteSelected);
1048
1049 if (selectedErrors.length == 1) {
1050 manager.add(deleteByTypeSelected);
1051 manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
1052 AbstractErrorLogData error = (AbstractErrorLogData)errorsTableViewer
1053 .getElementAt(selectedErrors[0]);
1054 if (error instanceof TokenErrorLogData) {
1055 TokenErrorLogData tokenError = (TokenErrorLogData)error;
1056 if (tokenError.getTokenIndex() >= 0) {
1057 try {
1058 tokenError.getRow().get(tokenError.getTokenIndex());
1059 manager.add(editSelected);
1060 } catch (IndexOutOfBoundsException e) {
1061
1062
1063 }
1064 }
1065 }
1066 manager.add(treatRowAsHeader);
1067 }
1068 }
1069 }
1070 });
1071 return popupMenu.createContextMenu(control);
1072 }
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082 public boolean isDataEmpty() {
1083 return data != null && data.isEmpty();
1084 }
1085
1086 public boolean isErrorsPresent() {
1087 return (errorsLog.getErrorsCount() > 0) ? true : false;
1088 }
1089
1090 private int[] getSelectedErrors() {
1091 return errorsTableViewer.getTable().getSelectionIndices();
1092 }
1093
1094 private List<DataRow> getRowsForSelectedErrors() {
1095 int[] selectedErrorsIndices = getSelectedErrors();
1096 List<DataRow> selectedRows = null;
1097 if (selectedErrorsIndices != null && selectedErrorsIndices.length > 0) {
1098 selectedRows = new LinkedList<DataRow>();
1099
1100 for (int selectedErrorIdx : selectedErrorsIndices) {
1101 AbstractErrorLogData selectedError = (AbstractErrorLogData)errorsTableViewer
1102 .getElementAt(selectedErrorIdx);
1103 DataRow erroneousRow = (DataRow)selectedError.getRow();
1104 if (erroneousRow != null && !selectedRows.contains(erroneousRow)) {
1105 selectedRows.add(erroneousRow);
1106 }
1107 }
1108 }
1109 return selectedRows;
1110 }
1111
1112 private boolean isIgnoreRowsCountSet() {
1113 return ignoreRowsCountChBox.getSelection();
1114 }
1115
1116 private boolean isTreatRowAsHeaderSet() {
1117 return treatRowAsHeaderChBox.getSelection();
1118 }
1119
1120 private int getIgnoredRowsCount() {
1121 return ignoreRowsCountSpinner.getSelection();
1122 }
1123
1124 private int getTreatAsHeaderSelection() {
1125 int rowIdx = treatAsHeaderSpinner.getSelection();
1126 String rowIdxMsg = treatAsHeaderSpinner.getText();
1127
1128 String errorMessage = null;
1129
1130 try {
1131 int rowIdxMsgValue = Integer.parseInt(rowIdxMsg);
1132 if (rowIdxMsgValue < treatAsHeaderSpinner.getMinimum()
1133 || rowIdxMsgValue > treatAsHeaderSpinner.getMaximum() || data.getRowByIndex(rowIdx - 1) == null) {
1134 errorMessage = Messages.ValidationPageComposite_RowNonExistentMsgBoxWarning;
1135 }
1136 } catch (Exception e) {
1137 }
1138
1139 if (errorMessage != null) {
1140 treatAsHeaderSpinner.setForeground(treatAsHeaderSpinner.getDisplay().getSystemColor(SWT.COLOR_RED));
1141 treatAsHeaderSpinner.setToolTipText(errorMessage);
1142 return -1;
1143 } else {
1144 treatAsHeaderSpinner.setToolTipText("");
1145 treatAsHeaderSpinner.setForeground(null);
1146 }
1147
1148 return rowIdx - 1;
1149 }
1150
1151
1152
1153
1154
1155
1156
1157
1158 public String getEmptyTokenReplacement(int columnIndex) {
1159 if (emptyTokenReplacements == null) {
1160 return null;
1161 }
1162
1163 return emptyTokenReplacements[columnIndex];
1164 }
1165
1166
1167 }