📄 mergedialog.java
字号:
package com.s10r.manager.dialogs;import java.util.Date;import java.util.concurrent.BlockingQueue;import java.util.concurrent.SynchronousQueue;import org.eclipse.jface.dialogs.IDialogConstants;import org.eclipse.jface.dialogs.TitleAreaDialog;import org.eclipse.swt.SWT;import org.eclipse.swt.events.SelectionEvent;import org.eclipse.swt.events.SelectionListener;import org.eclipse.swt.graphics.Color;import org.eclipse.swt.graphics.RGB;import org.eclipse.swt.layout.GridData;import org.eclipse.swt.layout.GridLayout;import org.eclipse.swt.layout.RowLayout;import org.eclipse.swt.widgets.Button;import org.eclipse.swt.widgets.Composite;import org.eclipse.swt.widgets.Control;import org.eclipse.swt.widgets.Group;import org.eclipse.swt.widgets.Label;import org.eclipse.swt.widgets.ProgressBar;import org.eclipse.swt.widgets.Shell;import org.eclipse.swt.widgets.Table;import org.eclipse.swt.widgets.TableColumn;import org.eclipse.swt.widgets.TableItem;import com.s10r.manager.model.ItemContainer;import com.s10r.manager.model.ItemLabel;import com.s10r.manager.model.ManagerItem;import com.s10r.manager.model.PasswordEntry;/** * Merges the entries contained in the importedEntries list with the * existingEntries list. When a name conflict occurs, the user is shown the * existing and imported entry and can then choose to either keep the existing * entry or replace the existing entry with the imported entry. * * At the end of the process, the user can choose to accept the merge process by * selecting OK or cancel out of the entire merge by pressing cancel. * * Callers of this dialog should check the open return status, if this status * indicates OK, use the getMergedEntries method to obtain the list with the * merged entries. * * @author schoffem */public class MergeDialog extends TitleAreaDialog{ private static final int INDEX_IMPORTED = 2; private static final int INDEX_EXISTING = 1; /** * Shows progress in terms of how many of the imported password entries have * been processed. */ private ProgressBar progressBar; private Shell shell; private Button keepButton; private Button replaceButton; /** * Used to communicate the user input between the UI thread and the * workThread. */ private BlockingQueue<Answer> answerQueue = new SynchronousQueue<Answer>(); /** * This thread does the actual merging work and, if necessary, interacts * with the UI through the answerQueue to get user input (primarily to ask * whether to keep or replace password entries if entries imported already * exist under the same name). */ private Thread workThread; private Label addedItemsLabel; private Label replacedItemsLabel; private Label keptItemsLabel; private int replacedItemsCnt = 0; private int keptItemsCnt = 0; private int addedItemsCnt = 0; private ItemContainer existingEntries; private ItemContainer importEntries; private ItemContainer mergedEntries = new ItemContainer(); private TableItem tiName; private TableItem tiId; private TableItem tiPassword; private TableItem tiDescription; private TableItem tiUsage; private TableItem tiCreated; private TableItem tiLastUpdated; private TableItem tiLastUsed; private TableItem tiUrl; /** * Colors for highlighting entry differences */ private Color colorRed; private Color colorYellow; private Color systemRowColor; /** * Type used to communicate the user selecting between the UI thread * (responding to the keep and replace button) and the workThread * (performing the merge of the two lists). */ enum Answer { Keep, Replace }; public MergeDialog(Shell shell, String msg, ItemContainer existingEntries, ItemContainer inEntries) { super(shell); // hold on to the shell so we can access the Display later // for asyncExec calls in the workThread this.shell = shell; this.existingEntries = existingEntries; this.importEntries = inEntries; // start out with existing mergedEntries.addAll(existingEntries); setShellStyle(SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM | SWT.RESIZE); setTitleAreaColor(new RGB(255, 255, 255)); } @Override public void create() { super.create(); this.getShell().setText("Merge entries"); this.setTitle("Merge entries"); this .setMessage("Merge a file of password entries with the entries " + "existing in the active editor. Equivalent entries are skipped."); this.getShell().setSize(600, 550); // obtain colors for highlighting differences and reverting back // to the original background color colorRed = getShell().getDisplay().getSystemColor(SWT.COLOR_RED); colorYellow = getShell().getDisplay().getSystemColor(SWT.COLOR_YELLOW); systemRowColor = tiName.getBackground(); // super.create calls createDialogArea, so at this point we // should be able to start the merging work startWorkThread(); } @Override protected Control createDialogArea(Composite parent) { final Composite comp = new Composite(parent, SWT.NONE); // the parent uses a grid layout // so set the area layout data to fill in both // directions GridData data2 = new GridData(GridData.FILL_BOTH); comp.setLayoutData(data2); final GridLayout layout = new GridLayout(); layout.numColumns = 2; // layout.makeColumnsEqualWidth = true; comp.setLayout(layout); GridData data = new GridData(GridData.FILL, GridData.CENTER, true, false); data.horizontalSpan = 2; progressBar = new ProgressBar(comp, SWT.NONE); progressBar.setLayoutData(data); progressBar.setMaximum(importEntries.size()); Group statsGroup = new Group(comp, SWT.NONE); GridLayout gl = new GridLayout(); gl.numColumns = 2; statsGroup.setLayout(gl); statsGroup.setText("Statistics"); data = new GridData(GridData.FILL, GridData.CENTER, true, false); data.horizontalSpan = 2; statsGroup.setLayoutData(data); data = new GridData(SWT.BEGINNING, GridData.CENTER, false, false); Label addItemLabel = new Label(statsGroup, SWT.NONE); addItemLabel.setText("Added: "); addItemLabel.setLayoutData(data); data = new GridData(SWT.BEGINNING, GridData.CENTER, false, false); addedItemsLabel = new Label(statsGroup, SWT.NONE); addedItemsLabel.setText("0"); addedItemsLabel.setLayoutData(data); data = new GridData(SWT.BEGINNING, GridData.CENTER, false, false); Label keptLabel = new Label(statsGroup, SWT.NONE); keptLabel.setText("Kept: "); keptLabel.setLayoutData(data); data = new GridData(SWT.BEGINNING, GridData.CENTER, false, false); keptItemsLabel = new Label(statsGroup, SWT.NONE); keptItemsLabel.setText("0"); keptItemsLabel.setLayoutData(data); data = new GridData(SWT.LEFT, GridData.CENTER, true, false); Label replacedLabel = new Label(statsGroup, SWT.NONE); replacedLabel.setText("Replaced: "); replacedLabel.setLayoutData(data); data = new GridData(SWT.LEFT, GridData.CENTER, true, false); replacedItemsLabel = new Label(statsGroup, SWT.NONE); replacedItemsLabel.setText("0"); replacedItemsLabel.setLayoutData(data); createTable(comp); data = new GridData(SWT.RIGHT, GridData.CENTER, true, false); Composite comp2 = new Composite(comp, SWT.NONE); comp2.setLayoutData(data); RowLayout layout2 = new RowLayout(); layout2.pack = false; comp2.setLayout(layout2); keepButton = createButton(comp2, "Keep existing", Answer.Keep); replaceButton = createButton(comp2, "Replace", Answer.Replace); return comp; } private void createTable(Composite comp) { GridData data = new GridData(GridData.FILL, GridData.FILL, true, true); data.horizontalSpan = 2; Table table = new Table(comp, SWT.BORDER); table.setLayoutData(data); table.setHeaderVisible(true); TableColumn c1 = new TableColumn(table, SWT.NONE); c1.setText("Property"); c1.setWidth(100); TableColumn c2 = new TableColumn(table, SWT.NONE); c2.setText("Existing entry"); c2.setWidth(200); TableColumn c3 = new TableColumn(table, SWT.NONE); c3.setText("Imported entry"); c3.setWidth(200); tiName = new TableItem(table, SWT.NONE); tiName.setText(0, "Name"); tiId = new TableItem(table, SWT.NONE); tiId.setText(0, "Id"); tiPassword = new TableItem(table, SWT.NONE); tiPassword.setText(0, "Password"); tiDescription = new TableItem(table, SWT.NONE); tiDescription.setText(0, "Description"); tiUsage = new TableItem(table, SWT.NONE); tiUsage.setText(0, "Usage"); tiCreated = new TableItem(table, SWT.NONE); tiCreated.setText(0, "Created"); tiLastUpdated = new TableItem(table, SWT.NONE); tiLastUpdated.setText(0, "Last Updated"); tiLastUsed = new TableItem(table, SWT.NONE); tiLastUsed.setText(0, "Last Used"); tiUrl = new TableItem(table, SWT.NONE); tiUrl.setText(0, "URL"); } private Button createButton(final Composite comp, String buttonText, final Answer answer) { // GridData data = new GridData(SWT.RIGHT, GridData.CENTER, true, // false); Button button = new Button(comp, SWT.NONE); button.setText(buttonText); // button.setLayoutData(data); button.setEnabled(false); button.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent arg0) { println("widgetSelected, answering: " + answer); try { // workThread should always be listening for answer answerQueue.put(answer); disableButtons(); } catch (InterruptedException e) { e.printStackTrace(); } } public void widgetDefaultSelected(SelectionEvent arg0) { } }); return button; } /** * Starts the work thread that performs the merge. This thread will interact * with the UI through Display.syncExec to let the user resolve merge * conflicts (same name entry conflicts). When all imported entries have * been processed, this thread will exit. * * This thread can be aborted by calling interrupt on it from a different * thread (usually the UI thread) while it is blocking on answerQueue.take() * (if this thread needs user input). This allows this thread to be * terminated when the user presses cancel in the middle of a merge * operation. */ private void startWorkThread() { /* * This thread builds up a merged list of entries Only when the OK * button is pressed, the new list should replace the one in the current * editor. */ workThread = new Thread() { @Override public void run() { boolean aborted = false; int i = 0; for (ManagerItem importItem: importEntries.getItems()) { i = i + 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -