/* * DBeaver - Universal Database Manager * Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jkiss.dbeaver.ui.editors.binary.dialogs; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.graphics.FontMetrics; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.layout.*; import org.eclipse.swt.widgets.*; import org.jkiss.dbeaver.core.CoreMessages; import org.jkiss.dbeaver.ui.editors.binary.HexManager; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Go to dialog. Remembers previous state. * * @author Jordi */ public class GoToDialog extends Dialog { private static final Pattern patternDecDigits = Pattern.compile("[0-9]+"); //$NON-NLS-1$ private static final Pattern patternHexDigits = Pattern.compile("[0-9a-fA-F]+"); //$NON-NLS-1$ private Shell dialogShell = null; // @jve:decl-index=0:visual-constraint="100,50" private Button hexRadioButton = null; private Button decRadioButton = null; private Button showButton = null; private Button gotoButton = null; private Composite textComposite = null; private Text text = null; private Label label = null; private Label label2 = null; private long finalResult = -1L; private long buttonPressed = 0; private boolean lastHexButtonSelected = true; private String lastLocationText = ""; private long limit = -1L; private long tempResult = -1L; private final SelectionAdapter defaultSelectionAdapter = new SelectionAdapter() { @Override public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { text.setFocus(); } }; public GoToDialog(Shell aShell) { super(aShell); } /** * This method initializes composite */ private void createRadixPanel() { RowLayout rowLayout1 = new RowLayout(); // rowLayout1.marginHeight = 5; rowLayout1.marginTop = 2; rowLayout1.marginBottom = 2; //rowLayout1.marginWidth = 5; rowLayout1.type = SWT.VERTICAL; Composite composite = new Composite(textComposite, SWT.NONE); composite.setLayout(rowLayout1); SelectionAdapter hexTextSelectionAdapter = new SelectionAdapter() { @Override public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { text.setText(text.getText()); // generate event lastHexButtonSelected = e.widget == hexRadioButton; } }; // Besides the crashes: the user always knows which number is entering, don't need any automatic // conversion. What does sometimes happen is one enters the right number and the wrong binary or dec was // selected. In that case automatic conversion is the wrong thing to do and very annoying. hexRadioButton = new Button(composite, SWT.RADIO); hexRadioButton.setText("Hex"); //$NON-NLS-1$ hexRadioButton.addSelectionListener(defaultSelectionAdapter); hexRadioButton.addSelectionListener(hexTextSelectionAdapter); decRadioButton = new Button(composite, SWT.RADIO); decRadioButton.setText("Dec"); //$NON-NLS-1$ decRadioButton.addSelectionListener(defaultSelectionAdapter); decRadioButton.addSelectionListener(hexTextSelectionAdapter);//decTextSelectionAdapter); } /** * Save the result and close dialog */ private void saveResultAndClose() { lastLocationText = text.getText(); finalResult = tempResult; dialogShell.close(); } public long getButtonPressed() { return buttonPressed; } /** * This method initializes composite2 */ private void createButtonsPanel() { RowLayout rowLayout1 = new RowLayout(); rowLayout1.type = org.eclipse.swt.SWT.VERTICAL; rowLayout1.marginHeight = 10; rowLayout1.marginWidth = 10; rowLayout1.fill = true; Composite composite2 = new Composite(dialogShell, SWT.NONE); FormData formData = new FormData(); formData.left = new FormAttachment(textComposite); formData.right = new FormAttachment(100); composite2.setLayoutData(formData); composite2.setLayout(rowLayout1); showButton = new Button(composite2, SWT.NONE); showButton.setText(CoreMessages.dialog_go_to_button_show_location); showButton.addSelectionListener(defaultSelectionAdapter); showButton.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { @Override public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { buttonPressed = 1; saveResultAndClose(); } }); gotoButton = new Button(composite2, SWT.NONE); gotoButton.setText(CoreMessages.dialog_go_to_button_go_to_location); gotoButton.addSelectionListener(defaultSelectionAdapter); gotoButton.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { @Override public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { buttonPressed = 2; saveResultAndClose(); } }); Button closeButton = new Button(composite2, SWT.NONE); closeButton.setText(CoreMessages.dialog_go_to_button_close); closeButton.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { @Override public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { dialogShell.close(); } }); dialogShell.setDefaultButton(showButton); } /** * This method initializes textComposite */ private void createTextPanel() { GridLayout gridLayout = new GridLayout(); gridLayout.numColumns = 2; textComposite = new Composite(dialogShell, SWT.NONE); textComposite.setLayout(gridLayout); createRadixPanel(); text = new Text(textComposite, SWT.BORDER | SWT.SINGLE); text.setTextLimit(30); int columns = 35; GC gc = new GC(text); FontMetrics fm = gc.getFontMetrics(); int width = columns * fm.getAverageCharWidth(); gc.dispose(); text.setLayoutData(new GridData(width, SWT.DEFAULT)); text.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { String newText = text.getText(); int radix = 10; Matcher numberMatcher; if (hexRadioButton.getSelection()) { numberMatcher = patternHexDigits.matcher(newText); radix = 16; } else { numberMatcher = patternDecDigits.matcher(newText); } tempResult = -1; if (numberMatcher.matches()) tempResult = Long.parseLong(newText, radix); if (tempResult >= 0L && tempResult <= limit) { showButton.setEnabled(true); gotoButton.setEnabled(true); label2.setText(""); //$NON-NLS-1$ } else { showButton.setEnabled(false); gotoButton.setEnabled(false); if ("".equals(newText)) //$NON-NLS-1$ label2.setText(""); //$NON-NLS-1$ else if (tempResult < 0) label2.setText(CoreMessages.dialog_go_to_label_not_number); else label2.setText(CoreMessages.dialog_go_to_label_out_of_range); } } }); FormData formData = new FormData(); formData.top = new FormAttachment(label); textComposite.setLayoutData(formData); } /** * This method initializes dialogShell */ private void createDialogShell() { dialogShell = new Shell(getParent(), SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM); dialogShell.setText(CoreMessages.dialog_go_to_title); FormLayout formLayout = new FormLayout(); formLayout.marginHeight = 3; formLayout.marginWidth = 3; dialogShell.setLayout(formLayout); label = new Label(dialogShell, SWT.NONE); FormData formData = new FormData(); formData.left = new FormAttachment(0, 5); formData.right = new FormAttachment(100); label.setLayoutData(formData); createTextPanel(); createButtonsPanel(); label2 = new Label(dialogShell, SWT.CENTER); FormData formData2 = new FormData(); formData2.left = new FormAttachment(0); formData2.right = new FormAttachment(100); formData2.top = new FormAttachment(textComposite); formData2.bottom = new FormAttachment(100, -10); label2.setLayoutData(formData2); } public long open(long aLimit) { limit = aLimit; finalResult = -1L; buttonPressed = 0; if (dialogShell == null || dialogShell.isDisposed()) { createDialogShell(); } dialogShell.pack(); HexManager.reduceDistance(getParent(), dialogShell); if (lastHexButtonSelected) { hexRadioButton.setSelection(true); } else { decRadioButton.setSelection(true); } label.setText( NLS.bind(CoreMessages.dialog_go_to_label_enter_location_number, limit, Long.toHexString(limit))); text.setText(lastLocationText); text.selectAll(); text.setFocus(); dialogShell.open(); Display display = getParent().getDisplay(); while (!dialogShell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } return finalResult; } }