📄 mergedialog.java
字号:
final int j = i; // labels are imported as is: if the label name does not // exist, import it. If it does, ignore it. if (importItem instanceof ItemLabel) { ItemLabel importLabel = (ItemLabel) importItem; if (!existingEntries.contains(importLabel)) { addToMergedEntries(importLabel); } continue; } // pattern: if we need an answer (keep/replace), // use asyncExec to enable the buttons (since we're in // a non-UI thread, wait for the button listener // give us an answer using the answerQueue and act // accordingly (keep/replace entry) PasswordEntry importPasswordEntry = (PasswordEntry) importItem; PasswordEntry existingPasswordEntry = existingEntries.getPasswordEntry(importPasswordEntry .getName()); final boolean getAnswer = existingPasswordEntry != null && !existingPasswordEntry .equals(importPasswordEntry); updateUIFromNonUIThread(j, getAnswer, importPasswordEntry, existingPasswordEntry); if (existingPasswordEntry == null) { // same named entry doesn't exist, just add addToMergedEntries(importPasswordEntry); // TODO: somehow addedItemsCnt reverts to 1 in the // middle of processing... addedItemsCnt++; } else if (existingPasswordEntry.equals(importPasswordEntry)) { // skip same entries: already exist } else // same name, different attributes -> ask == true // wait for the user to respond { try { // wait for user: can't do this within asyncExec as // this will block the UI thread. println("answerQueue.take()"); Answer answer = answerQueue.take(); println("answerQueue.take() return: answer = " + answer); if (answer == Answer.Keep) { // do nothing, it's already there keptItemsCnt++; } else // replace { // TODO: does not appear to work... println("Removing: " + existingPasswordEntry.getName()); mergedEntries.remove(existingPasswordEntry); addToMergedEntries(importPasswordEntry); replacedItemsCnt++; } } catch (InterruptedException e) { println("answerQueue.take() interrupted (cancel pressed?), aborting"); aborted = true; break; } } } // Need to know whether the action is aborted (usually due // to the Cancel button being pressed: in this case, the // dialog might alread be disposed off: so don't touch the // buttons in this case if (!aborted) { enableOKButtonFromNonUIThread(); } println("Thread.run: end of run()"); } private void enableOKButtonFromNonUIThread() { shell.getDisplay().asyncExec(new Runnable() { public void run() { enableOK(true); } }); } /** * Updates the UI with the progress, indicated by j and optionally * enables the keep/replace buttons (if user input is needed). Note * that if getAnswer is set to true, the caller is reponsible to * block on getting an answer from the answer queue. * * @param j * @param getAnswer * @param importPasswordEntry */ private void updateUIFromNonUIThread(final int j, final boolean getAnswer, final PasswordEntry importPasswordEntry, final PasswordEntry existingPasswordEntry) { shell.getDisplay().syncExec(new Runnable() { public void run() { if (progressBar.isDisposed()) { println("updateUIFromNonUIThread: progress bar is already disposed"); return; } progressBar.setSelection(j); addedItemsLabel.setText("" + addedItemsCnt); keptItemsLabel.setText("" + keptItemsCnt); replacedItemsLabel.setText("" + replacedItemsCnt); clearExisting(); showImportPasswordEntry(importPasswordEntry); if (getAnswer) { showExistingPasswordEntry(existingPasswordEntry); highLightEntries(importPasswordEntry, existingPasswordEntry); // allow choice enableButtons(); // TODO: use rules to decide which button should // get focus, so it will default when enter is // pressed: // If new.updated > existing.updated: replace? // if new.id != existing.id // or new.password != existing.id : keep? // -> create method: determineDefault(new, exist) keepButton.setFocus(); } } }); } }; workThread.start(); } private void println(String s) { System.out.println(Thread.currentThread().getName() + ": " + s); } private void enableButtons() { keepButton.setEnabled(true); replaceButton.setEnabled(true); } private void disableButtons() { keepButton.setEnabled(false); replaceButton.setEnabled(false); } /** * Disables the OK button as only after all imported entries have been * processed, the dialog can be dismissed. * * @param parent * @return */ @Override protected Control createButtonBar(Composite parent) { Control c = super.createButtonBar(parent); enableOK(false); return c; } private void enableOK(boolean enable) { getButton(IDialogConstants.OK_ID).setEnabled(enable); } /** * Checks whether the work thread is still alive. If alive, the workThread * is interrupted and waited for to die (1 second max) */ @Override protected void cancelPressed() { // Note: I believe this only works when the workThread is waiting // on user input (e.g. answerQueue.take() // For really large password list to process, the work thread // should listen for a cancel/stop command for each entry // iteration. if (workThread != null && workThread.isAlive()) { workThread.interrupt(); try { println("cancelPressed: waiting for thread to exit"); workThread.join(1000); println("cancelPressed: thread done"); } catch (InterruptedException e) { // this shouldn't happen as by the time we get to join, // the workThread already would have exited e.printStackTrace(); } } super.cancelPressed(); } private void clearExisting() { this.tiName.setText(INDEX_EXISTING, ""); this.tiId.setText(INDEX_EXISTING, ""); this.tiPassword.setText(INDEX_EXISTING, ""); this.tiDescription.setText(INDEX_EXISTING, ""); this.tiUsage.setText(INDEX_EXISTING, ""); this.tiCreated.setText(INDEX_EXISTING, ""); this.tiLastUpdated.setText(INDEX_EXISTING, ""); this.tiLastUsed.setText(INDEX_EXISTING, ""); this.tiUrl.setText(INDEX_EXISTING, ""); tiId.setBackground(systemRowColor); tiPassword.setBackground(systemRowColor); tiDescription.setBackground(systemRowColor); tiUsage.setBackground(systemRowColor); tiCreated.setBackground(systemRowColor); tiLastUpdated.setBackground(systemRowColor); tiLastUsed.setBackground(systemRowColor); tiUrl.setBackground(systemRowColor); } private void showExistingPasswordEntry(PasswordEntry passwordEntry) { showPasswordEntry(INDEX_EXISTING, passwordEntry); } private void showImportPasswordEntry(PasswordEntry passwordEntry) { showPasswordEntry(INDEX_IMPORTED, passwordEntry); } private void showPasswordEntry(int tableItemIndex, PasswordEntry passwordEntry) { tiName.setText(tableItemIndex, passwordEntry.getName()); tiId.setText(tableItemIndex, passwordEntry.getId()); tiPassword.setText(tableItemIndex, passwordEntry.getPassword()); tiDescription.setText(tableItemIndex, passwordEntry.getDescription()); tiUsage.setText(tableItemIndex, "" + passwordEntry.getUsageCnt()); tiCreated.setText(tableItemIndex, "" + passwordEntry.getCreated()); tiLastUpdated.setText(tableItemIndex, "" + passwordEntry.getLastUpdated()); tiLastUsed.setText(tableItemIndex, "" + passwordEntry.getLastUsed()); tiUrl.setText(tableItemIndex, "" + passwordEntry.getUrl()); } private void highLightEntries(PasswordEntry importPe, PasswordEntry existingPe) { if (!stringEquals(importPe.getId(), existingPe.getId())) { tiId.setBackground(colorRed); } if (!stringEquals(importPe.getPassword(), existingPe.getPassword())) { tiPassword.setBackground(colorRed); } if (!stringEquals(importPe.getDescription(), existingPe .getDescription())) { tiDescription.setBackground(colorYellow); } if (importPe.getUsageCnt() != existingPe.getUsageCnt()) { tiUsage.setBackground(colorYellow); } if (!dateEquals(importPe.getCreated(), existingPe.getCreated())) { tiCreated.setBackground(colorYellow); } if (!dateEquals(importPe.getLastUpdated(), existingPe.getLastUpdated())) { tiLastUpdated.setBackground(colorYellow); } if (!dateEquals(importPe.getLastUsed(), existingPe.getLastUsed())) { tiLastUsed.setBackground(colorYellow); } if (!stringEquals(importPe.getUrl(), existingPe.getUrl())) { tiUrl.setBackground(colorYellow); } } private boolean stringEquals(String s1, String s2) { if (s1 == null && s2 == null) { return true; } else if (s1 == null || s2 == null) { return false; } else { return s1.equals(s2); } } private boolean dateEquals(Date s1, Date s2) { if (s1 == null && s2 == null) { return true; } else if (s1 == null || s2 == null) { return false; } else { return s1.equals(s2); } } public ItemContainer getMergedEntries() { return mergedEntries; } private void addToMergedEntries(ManagerItem item) { if (item == null) { throw new NullPointerException("item is null"); } mergedEntries.add(item); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -