/** * TmxEditor.java * * Version information : * * Date:2013/5/17 * * Copyright notice : * 本文件及其附带的相关文件包含机密信息,仅限瀚特盛科技有限公司指定的,与本项目有关的内部人员和客户联络人员查阅和使用。 * 如果您不是本保密声明中指定的收件者,请立即销毁本文件,禁止对本文件或根据本文件中的内容采取任何其他行动, * 包括但不限于:泄露本文件中的信息、以任何方式制作本文件全部或部分内容之副本、将本文件或其相关副本提供给任何其他人。 */ package net.heartsome.cat.te.tmxeditor.editor; import java.lang.reflect.InvocationTargetException; import java.text.MessageFormat; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import net.heartsome.cat.common.bean.TmxSegement; import net.heartsome.cat.common.bean.TmxTU; import net.heartsome.cat.common.ui.utils.OpenMessageUtils; import net.heartsome.cat.te.core.TeCoreConstant; import net.heartsome.cat.te.core.bean.TmxEditorFilterBean; import net.heartsome.cat.te.core.bean.TmxPropertiesBean; import net.heartsome.cat.te.core.qa.QACommonFuction; import net.heartsome.cat.te.core.qa.QAConstant; import net.heartsome.cat.te.core.tmxdata.AbstractTmxDataAccess; import net.heartsome.cat.te.core.tmxdata.DatabaseDataAccess; import net.heartsome.cat.te.core.tmxdata.TmxLargeFileDataAccess; import net.heartsome.cat.te.tmxeditor.editor.nattable.TmxEditorImpWithNattable; import net.heartsome.cat.te.tmxeditor.editor.nattable.celleditor.CellEditor; import net.heartsome.cat.te.tmxeditor.editor.nattable.celleditor.TeActiveCellEditor; import net.heartsome.cat.te.tmxeditor.editor.nattable.search.FindReplaceDialog; import net.heartsome.cat.te.tmxeditor.resource.Messages; import net.sourceforge.nattable.edit.editor.ICellEditor; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.jface.action.Action; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.layout.LayoutConstants; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.events.FocusAdapter; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.TabFolder; import org.eclipse.swt.widgets.TabItem; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.actions.ActionFactory; /** * TmxEditor 编辑器的 viewer 层,编辑器的接口点。包括界面的初始化, nattable 的创建等。 * @author Jason, Robert * @version * @since JDK1.6 */ public class TmxEditor { private Composite parentComposite; private AbstractTmxDataAccess tmxDataAccess; /** 当前源语言 */ private String srcLangCode; /** 当前目标语言 */ private String tgtLangCode; private TmxEditorFilter editorFilter; private Combo srcLangCombo; private Combo tgtLangCombo; private Text srcSearchText; private Text tgtSearchText; private String tgtSearchTitle = Messages.getString("tmxeditor.filter.targetSearchText.label"); private String srcSearchTitle = Messages.getString("tmxeditor.filter.sourceSearchText.label"); private TmxEditorImpWithNattable tmxEditorImpWithNattable; private TmxEditorViewer viewPart; private FindReplaceAction findAction = new FindReplaceAction(); private FindReplaceDialog dialog; private KeyListener searchKeyListener = new KeyListener() { @Override public void keyReleased(KeyEvent e) { if (e.stateMask == SWT.NONE && e.keyCode == SWT.CR) { commit(); editorFilter.comboViewer.getCombo().select(0); beginToSeach(); } } @Override public void keyPressed(KeyEvent e) { } }; public TmxEditor(AbstractTmxDataAccess tmxDataAccess) { this.tmxDataAccess = tmxDataAccess; this.srcLangCode = tmxDataAccess.getCurrSrcLang(); this.tgtLangCode = tmxDataAccess.getCurrTgtLang(); } public void createContent(TmxEditorViewer viewPart, Composite container) { this.parentComposite = container; this.viewPart = viewPart; GridLayout containerGdLt = new GridLayout(1, true); containerGdLt.marginWidth = 0; containerGdLt.marginHeight = 0; containerGdLt.verticalSpacing = 5; containerGdLt.marginTop = 0; containerGdLt.marginLeft = 0; containerGdLt.marginRight = 0; container.setLayout(containerGdLt); // tab 设置,分为数据查询以及品质检查 TabFolder tab = new TabFolder(container, SWT.NONE); tab.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); TabItem editorItm = new TabItem(tab, SWT.NONE); editorItm.setText(Messages.getString("tmxeditor.filter.editor")); TabItem qaItm = new TabItem(tab, SWT.NONE); qaItm.setText(Messages.getString("tmxeditor.filter.qa")); Composite editorCmp = new Composite(tab, SWT.NONE); GridDataFactory.fillDefaults().grab(true, true).applyTo(editorCmp); GridLayoutFactory.fillDefaults().numColumns(2).applyTo(editorCmp); createEditorArea(editorCmp); editorItm.setControl(editorCmp); Composite qaCmp = new Composite(tab, SWT.NONE); GridDataFactory.fillDefaults().grab(true, true).applyTo(qaCmp); GridLayoutFactory.fillDefaults().numColumns(2).applyTo(qaCmp); createQaArea(qaCmp); qaItm.setControl(qaCmp); // create nattable composite Composite nattableComposite = new Composite(container, SWT.NONE); nattableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); createNattable(nattableComposite, srcLangCode, tgtLangCode); } private void createEditorArea(Composite editorCmp) { Group searchGroup = new Group(editorCmp, SWT.NONE); searchGroup.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); searchGroup.setText(Messages.getString("tmxeditor.fitler.searchGroup")); searchGroup.setLayout(new GridLayout(4, false)); // create language createLangUI(searchGroup); Group filterGroup = new Group(editorCmp, SWT.NONE); filterGroup.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); filterGroup.setText(Messages.getString("tmxeditor.filter.fitlerGroup")); GridLayout filterGroupGl = new GridLayout(1, false); filterGroupGl.marginWidth = 0; filterGroupGl.marginHeight = 0; filterGroup.setLayout(filterGroupGl); // create Filter createTmxFilter(filterGroup); } /** * 品质检查选项面板 --robert 2013-09-17 * @param qaCmp * ; */ private void createQaArea(Composite qaCmp) { final IPreferenceStore store = net.heartsome.cat.te.core.Activator.getDefault().getPreferenceStore(); // >左边 Group itemsGroup = new Group(qaCmp, SWT.NONE); itemsGroup.setText(Messages.getString("tmxeditor.QA.itemGroupTitle")); GridDataFactory.swtDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(itemsGroup); GridLayoutFactory.swtDefaults().numColumns(2).applyTo(itemsGroup); // >>第一层 composite Composite qaItemCmp = new Composite(itemsGroup, SWT.NONE); GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(qaItemCmp); GridLayoutFactory.fillDefaults().numColumns(3).spacing(SWT.DEFAULT, LayoutConstants.getSpacing().y - 4).margins(0, 0).applyTo(qaItemCmp); // >>>第一层 第一行 final Button tagConsistenceBtn = new Button(qaItemCmp, SWT.CHECK); tagConsistenceBtn.setText(QAConstant.QA_TagConsistenceText); final Button numberConsistenceBtn = new Button(qaItemCmp, SWT.CHECK); numberConsistenceBtn.setText(QAConstant.QA_NumberConsistenceText); final Button spaceOfParaCheckBtn = new Button(qaItemCmp, SWT.CHECK); spaceOfParaCheckBtn.setText(QAConstant.QA_SpaceOfParaCheckText); // >>>第一层 第二行 final Button tgtNullBtn = new Button(qaItemCmp, SWT.CHECK); tgtNullBtn.setText(QAConstant.QA_TgtNullText); final Button srcSameButTgtBtn = new Button(qaItemCmp, SWT.CHECK); srcSameButTgtBtn.setText(QAConstant.QA_SrcSameButTgtText); final Button tgtSameButSrcBtn = new Button(qaItemCmp, SWT.CHECK); tgtSameButSrcBtn.setText(QAConstant.QA_TgtSameButSrcText); // >>>第一层 第三行 final Button srcSameWithTgtBtn = new Button(qaItemCmp, SWT.CHECK); srcSameWithTgtBtn.setText(QAConstant.QA_SrcSameWithTgtText); new Label(qaItemCmp, SWT.NONE); new Label(qaItemCmp, SWT.NONE); // >>第二层 Composite qaBtnCmp = new Composite(itemsGroup, SWT.NONE); GridDataFactory.swtDefaults().align(SWT.LEFT, SWT.FILL).grab(false, true).applyTo(qaBtnCmp); GridLayoutFactory.fillDefaults().numColumns(1).margins(0, 0).applyTo(qaBtnCmp); final Button qaBtn = new Button(qaBtnCmp, SWT.NONE); qaBtn.setLayoutData(new GridData(SWT.LEFT, SWT.END, false, true)); qaBtn.setText(Messages.getString("tmxeditor.QA.qaExcuteBtnTitle")); // UNDO 这里因为还没有做 数据库的 qa,因此,当打开数据库时,qa 的按钮设置不可用状态 --robert 2013-10-15 if (tmxDataAccess instanceof TmxLargeFileDataAccess) { qaBtn.setEnabled(true); } else { qaBtn.setEnabled(false); } qaBtn.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { // 先将选择的值保存至缓存中。再执行品质检查 StringBuffer useableQAItemSB = new StringBuffer(); if (tagConsistenceBtn.getSelection()) { useableQAItemSB.append(QAConstant.QA_TagConsistence).append(";"); } if (numberConsistenceBtn.getSelection()) { useableQAItemSB.append(QAConstant.QA_NumberConsistence).append(";"); } if (spaceOfParaCheckBtn.getSelection()) { useableQAItemSB.append(QAConstant.QA_SpaceOfParaCheck).append(";"); } if (tgtNullBtn.getSelection()) { useableQAItemSB.append(QAConstant.QA_TgtNull).append(";"); } if (srcSameWithTgtBtn.getSelection()) { useableQAItemSB.append(QAConstant.QA_SrcSameWithTgt).append(";"); } if (srcSameButTgtBtn.getSelection()) { useableQAItemSB.append(QAConstant.QA_SrcSameButTgt).append(";"); } if (tgtSameButSrcBtn.getSelection()) { useableQAItemSB.append(QAConstant.QA_TgtSameButSrc).append(";"); } store.setValue(QAConstant.PREF_useableQAItemStr, useableQAItemSB.toString()); if (useableQAItemSB.length() <= 0) { OpenMessageUtils.openMessage(IStatus.INFO, Messages.getString("tmxeditor.tmxeditor.qaItemNull")); return; } commit(); tmxDataAccess.beginQA(srcLangCode, tgtLangCode, true, true); } }); // >右边 Group operateGroup = new Group(qaCmp, SWT.NONE); operateGroup.setText(Messages.getString("tmxeditor.QA.operateGroupTitle")); GridDataFactory.swtDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(operateGroup); GridLayoutFactory.swtDefaults().numColumns(2).applyTo(operateGroup); // >>第一行, 这两个忽略项。跟 过滤查询的保持参数一致。 final Button ignoreCaseBtn = new Button(operateGroup, SWT.CHECK); ignoreCaseBtn.setText(Messages.getString("tmxeditor.QA.igoureCaceBtnTitle")); ignoreCaseBtn.setSelection(store.getBoolean(TeCoreConstant.FILTER_ignoreCase)); ignoreCaseBtn.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { store.setValue(TeCoreConstant.FILTER_ignoreCase, ignoreCaseBtn.getSelection()); } @Override public void widgetDefaultSelected(SelectionEvent e) { store.setValue(TeCoreConstant.FILTER_ignoreCase, ignoreCaseBtn.getSelection()); } }); final Button ignoreTagBtn = new Button(operateGroup, SWT.CHECK); ignoreTagBtn.setText(Messages.getString("tmxeditor.QA.ignoreTagBtnTitle")); ignoreTagBtn.setToolTipText(Messages.getString("tmxeditor.QA.ignoreTagBtnToolTip")); ignoreTagBtn.setSelection(store.getBoolean(TeCoreConstant.FILTER_ignoreTag)); ignoreTagBtn.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { store.setValue(TeCoreConstant.FILTER_ignoreTag, ignoreTagBtn.getSelection()); } @Override public void widgetDefaultSelected(SelectionEvent e) { store.setValue(TeCoreConstant.FILTER_ignoreTag, ignoreTagBtn.getSelection()); } }); // 给品质检查所有选项设置值 List<String> itemsArray = QACommonFuction.getUseableQAItems(); tagConsistenceBtn.setSelection(itemsArray.contains(QAConstant.QA_TagConsistence)); numberConsistenceBtn.setSelection(itemsArray.contains(QAConstant.QA_NumberConsistence)); spaceOfParaCheckBtn.setSelection(itemsArray.contains(QAConstant.QA_SpaceOfParaCheck)); tgtNullBtn.setSelection(itemsArray.contains(QAConstant.QA_TgtNull)); srcSameWithTgtBtn.setSelection(itemsArray.contains(QAConstant.QA_SrcSameWithTgt)); srcSameButTgtBtn.setSelection(itemsArray.contains(QAConstant.QA_SrcSameButTgt)); tgtSameButSrcBtn.setSelection(itemsArray.contains(QAConstant.QA_TgtSameButSrc)); // 当切换 tabfolder 时,给两个忽略项设置动态变化,因为 qa 与过滤器共用一套过滤参数。 final TabFolder tab = (TabFolder) (qaCmp.getParent()); tab.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { if (tab.getSelectionIndex() == 1) { ignoreCaseBtn.setSelection(store.getBoolean(TeCoreConstant.FILTER_ignoreCase)); ignoreTagBtn.setSelection(store.getBoolean(TeCoreConstant.FILTER_ignoreTag)); } } @Override public void widgetDefaultSelected(SelectionEvent e) { if (tab.getSelectionIndex() == 1) { ignoreCaseBtn.setSelection(store.getBoolean(TeCoreConstant.FILTER_ignoreCase)); ignoreTagBtn.setSelection(store.getBoolean(TeCoreConstant.FILTER_ignoreTag)); } } }); } /** * 如果srcLang为null,则说明当前编辑的对象是无源语言的TMX文件或者是TMXDB, <br> * 需要根据目标语言来初始化源语言和目标语言选择组件。<br> * 需要初始化{@link this#srcLangCode} 和 {@link this#tgtLangCode} * @param srcLang * @param tgtLang **/ private void createLangUI(Composite container) { // 所有语言的集合 List<String> allLangList = new LinkedList<String>(); allLangList.add(srcLangCode); allLangList.addAll(tmxDataAccess.getLangList()); Label srcLangLabel = new Label(container, SWT.NONE); srcLangLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); srcLangLabel.setText(Messages.getString("tmxeditor.filter.srcLang")); srcLangCombo = new Combo(container, SWT.READ_ONLY); GridData srcLangCombgd = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1); srcLangCombgd.widthHint = 80; srcLangCombo.setLayoutData(srcLangCombgd); srcLangCombo.setItems(allLangList.toArray(new String[] {})); srcLangCombo.select(allLangList.indexOf(srcLangCode)); srcSearchText = new Text(container, SWT.BORDER); srcSearchText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); new Label(container, SWT.NONE); Label tgtLangLabel = new Label(container, SWT.NONE); tgtLangLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); tgtLangLabel.setText(Messages.getString("tmxeditor.filter.tgtLang")); tgtLangCombo = new Combo(container, SWT.READ_ONLY); tgtLangCombo.setLayoutData(srcLangCombgd); tgtLangCombo.setItems(allLangList.toArray(new String[] {})); tgtLangCombo.select(allLangList.indexOf(tgtLangCode)); tgtSearchText = new Text(container, SWT.BORDER); tgtSearchText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); srcSearchText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_GRAY)); srcSearchText.setText(srcSearchTitle); srcSearchText.addKeyListener(searchKeyListener); srcSearchText.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { Text text = (Text) e.widget; if (srcSearchTitle.equals(text.getText())) { text.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); text.setText(""); } } @Override public void focusLost(FocusEvent e) { Text text = (Text) e.widget; if ("".equals(text.getText())) { text.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_GRAY)); text.setText(srcSearchTitle); } } }); Button searchBtn = new Button(container, SWT.NONE); GridData gd_button = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1); gd_button.widthHint = 70; searchBtn.setLayoutData(gd_button); searchBtn.setText(Messages.getString("tmxeditor.filter.searchBtn")); searchBtn.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { editorFilter.comboViewer.getCombo().select(0); beginToSeach(); } }); tgtSearchText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_GRAY)); tgtSearchText.setText(tgtSearchTitle); tgtSearchText.addKeyListener(searchKeyListener); tgtSearchText.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { Text text = (Text) e.widget; if (tgtSearchTitle.equals(text.getText())) { text.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); text.setText(""); } } @Override public void focusLost(FocusEvent e) { Text text = (Text) e.widget; if ("".equals(text.getText())) { text.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_GRAY)); text.setText(tgtSearchTitle); } } }); } private TmxEditorFilter createTmxFilter(Composite container) { editorFilter = new TmxEditorFilter(); editorFilter.createFilterUI(container); editorFilter.comboViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { tgtSearchText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_GRAY)); tgtSearchText.setText(tgtSearchTitle); srcSearchText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_GRAY)); srcSearchText.setText(srcSearchTitle); beginToSeach(); } }); return null; } /** * 当品质检查结果视图中双击某行定位之前,先将所有过滤查询数据清空,并让过滤条件重置为所有文本段的选项。 --robert 2013-10-10 */ public void resetFilterBeforLocation(String srcLang, String tgtLang) { srcLangCombo.select(Arrays.asList(srcLangCombo.getItems()).indexOf(srcLang)); tgtLangCombo.select(Arrays.asList(tgtLangCombo.getItems()).indexOf(tgtLang)); tgtSearchText.setText(""); srcSearchText.setText(""); editorFilter.comboViewer.getCombo().select(0); beginToSeach(); } /** * 开始查询 */ public void beginToSeach() { String srcLang = srcLangCombo.getText(); String tgtLang = tgtLangCombo.getText(); if (srcLang.equals(tgtLang)) { OpenMessageUtils.openMessage(IStatus.WARNING, Messages.getString("tmxeditor.tmxeditor.warn.msg1")); return; } srcLangCode = srcLang; tgtLangCode = tgtLang; doFilter(editorFilter.getCurrentFilter()); } private void doFilter(final TmxEditorFilterBean filter) { TeActiveCellEditor.commit(); final String srcSearchStr = getSearchText(srcSearchText); final String tgtSearchStr = getSearchText(tgtSearchText); IRunnableWithProgress progress = new IRunnableWithProgress() { @Override public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { tmxDataAccess.loadDisplayTuIdentifierByFilter(monitor, filter, srcLangCode, tgtLangCode, srcSearchStr, tgtSearchStr); } }; try { new ProgressMonitorDialog(Display.getDefault().getActiveShell()).run(true, true, progress); } catch (Exception e) { e.printStackTrace(); } tmxEditorImpWithNattable.setSrcSearchStr(srcSearchStr); tmxEditorImpWithNattable.setTgtSearchStr(tgtSearchStr); tmxEditorImpWithNattable.getTable().setFocus(); tmxEditorImpWithNattable.refrush(); tmxEditorImpWithNattable.selectCell(getTgtColumnIndex(), 0); } private String getSearchText(Text searchTextWidget) { String text = searchTextWidget.getText(); if (text == null || text.equals(tgtSearchTitle) || text.equals(srcSearchTitle)) { return ""; } return text; } private void createNattable(Composite container, String srcLang, String tgtLang) { container.setLayout(new FillLayout()); tmxEditorImpWithNattable = new TmxEditorImpWithNattable(tmxDataAccess); tmxEditorImpWithNattable.createContents(container); tmxEditorImpWithNattable.getTable().addFocusListener(new FocusListener() { @Override public void focusLost(FocusEvent e) { } @Override public void focusGained(FocusEvent e) { TmxEditor.this.viewPart.getViewSite().getActionBars() .setGlobalActionHandler(ActionFactory.FIND.getId(), findAction); findAction.updateEnabledState(); } }); // 将 TmxEidotrImpWithNattable 提供的选择事件提供器注册给 viewer if (viewPart != null) { viewPart.getSite().setSelectionProvider(tmxEditorImpWithNattable.getSelectionProvider()); } } public void saveAs() { Display.getDefault().syncExec(new Runnable() { @Override public void run() { commit(); } }); ExportDialog dlg = new ExportDialog(parentComposite.getShell(), this); dlg.open(); } public void save(IProgressMonitor monitor) throws Exception { Display.getDefault().syncExec(new Runnable() { @Override public void run() { commit(); } }); tmxDataAccess.save(monitor); tmxDataAccess.setDirty(false); Display.getDefault().syncExec(new Runnable() { @Override public void run() { tmxEditorImpWithNattable.redraw(); tmxEditorImpWithNattable.refreshSelectionedRow(); } }); } public boolean isDirty() { if (tmxDataAccess != null) { return tmxDataAccess.isDirty(); } return false; } public boolean closeTmxEditor() { commit(); int _choice = -1; if (isDirty() || tmxDataAccess.isSourceExist()) { String message = Messages.getString("tmxeditor.tmxeditor.savechangs"); String[] buttons = new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.CANCEL_LABEL }; MessageDialog d = new MessageDialog(parentComposite.getShell(), Messages.getString("tmxeditor.all.dialog.info"), null, message, MessageDialog.QUESTION, buttons, 0) { protected int getShellStyle() { return super.getShellStyle() | SWT.SHEET; } }; _choice = d.open(); } if (_choice == 2) { return false; } final int choice = _choice; final String[] msgs = new String[1]; IRunnableWithProgress r = new IRunnableWithProgress() { @Override public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { monitor.beginTask(Messages.getString("tmxeditor.tmxEditorViewer.savelabel"), 1); try { if (choice == 0) { tmxDataAccess.save(monitor); } tmxDataAccess.closeTmxDataAccess(new SubProgressMonitor(monitor, 1)); } catch (Exception e) { msgs[0] = e.getMessage(); } monitor.done(); } }; try { new ProgressMonitorDialog(Display.getDefault().getActiveShell()).run(true, true, r); } catch (Exception e) { e.printStackTrace(); } if (msgs[0] != null) { String msg = Messages.getString("tmxeditor.tmxeditor.savefailmsg"); msg = MessageFormat.format(msg, msgs[0]); if (!OpenMessageUtils.openConfirmMessage(msg)) { return false; } } // 关闭时移除选择事件提供器 if (viewPart != null) { viewPart.getSite().setSelectionProvider(null); } tmxEditorImpWithNattable.dispose(); tmxEditorImpWithNattable = null; this.tmxDataAccess = null; if (dialog != null) { dialog.close(); } findAction.updateEnabledState(); return true; } public void refreshUI() { if (tmxEditorImpWithNattable != null) { tmxEditorImpWithNattable.refrush(); } } /** * 根据 TmxDataAccess 中现有的数据,从新创建界面,包括过滤面板和编辑器 ; */ public void reCreateUI() { if (this.parentComposite != null && !this.parentComposite.isDisposed() && this.viewPart != null) { int index = editorFilter.comboViewer.getCombo().getSelectionIndex(); String srcText = getSearchText(srcSearchText); String tgtText = getSearchText(tgtSearchText); Control[] childs = this.parentComposite.getChildren(); for (Control c : childs) { if (c != null && !c.isDisposed()) { c.dispose(); } } this.srcLangCode = tmxDataAccess.getCurrSrcLang(); this.tgtLangCode = tmxDataAccess.getCurrTgtLang(); createContent(viewPart, parentComposite); if (srcText.length() != 0) { srcSearchText.setText(srcText); srcSearchText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); } if (tgtText.length() != 0) { tgtSearchText.setText(tgtText); srcSearchText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); } editorFilter.comboViewer.getCombo().select(index); viewPart.notifyOpenEvent(tmxDataAccess); this.parentComposite.pack(); this.parentComposite.layout(); this.parentComposite.getParent().layout(); } } /** * 重置过滤器 ; */ public void resetFileter() { editorFilter.comboViewer.getCombo().select(0); } public void addTu(TmxTU tu) { int[] rows = tmxEditorImpWithNattable.getSelectedRows(); int selRow = 0; if (rows.length != 0) { selRow = rows[0]; } List<String> disTuIds = tmxDataAccess.getDisplayTuIdentifiers(); String tuIdentifer = null; if (disTuIds.size() != 0) { tuIdentifer = disTuIds.get(selRow); } commit(); String id = tmxDataAccess.addTu(tu, tuIdentifer); if (id != null) { int currRow = selRow; if (tuIdentifer == null || tmxDataAccess instanceof DatabaseDataAccess) { disTuIds.add(id); currRow = disTuIds.size() - 1; } else { disTuIds.add(currRow, id); } tmxEditorImpWithNattable.refrush(); tmxEditorImpWithNattable.selectCell(getSrcColumnIndex(), currRow); tmxEditorImpWithNattable.resizeRowsHeight(); tmxEditorImpWithNattable.editSelectedCell(); tmxDataAccess.setDirty(true); } } public void deleteSelectedTu() { int[] rows = tmxEditorImpWithNattable.getSelectedRows(); if (rows.length == 0) { return; } Arrays.sort(rows); List<String> disTuIds = tmxDataAccess.getDisplayTuIdentifiers(); if (disTuIds.size() == 0) { return; } String[] selTuIds = new String[rows.length]; for (int i = 0; i < selTuIds.length; i++) { selTuIds[i] = disTuIds.get(rows[i]); } TeActiveCellEditor.close(); tmxDataAccess.deleteTus(selTuIds, null); int firstRow = rows[0]; int j = 0; for (int r : rows) { disTuIds.remove(r - j); j++; } refreshUI(); while (firstRow > -1) { if (disTuIds.size() > firstRow) { tmxEditorImpWithNattable.selectCell(getTgtColumnIndex(), firstRow); tmxEditorImpWithNattable.resizeRowsHeight(); tmxEditorImpWithNattable.editSelectedCell(); break; } firstRow--; } tmxDataAccess.setDirty(true); } /** * 支持进度条显示的清除内部标记 * @author Austen * @param monitor * ; */ public void cleartInnerTag(IProgressMonitor monitor) { monitor.beginTask(Messages.getString("tmxeditor.tmxeditor.deleteIngerTag.taskName"), 5); int total = tmxDataAccess.getDisplayTuIdentifiers().size(); int step = total > 500 ? (total / 500) + 1 : 1; IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 5); subMonitor.beginTask("", total > 500 ? 500 : total); List<String> cleanList = new LinkedList<String>(); TmxTU tu = null; int i = 0; for (String identifier : tmxDataAccess.getDisplayTuIdentifiers()) { tu = tmxDataAccess.getTuByIdentifier(identifier); if (tu.getSource() != null) { if (tu.getSource().getFullText().length() != tu.getSource().getPureText().length()) { cleanList.add(identifier); } } try { tu.getSegments().get(0).getAttributes(); } catch (NullPointerException e) { System.out.println(identifier); } if (i++ % step == 0) { subMonitor.worked(1); } } subMonitor.done(); monitor.done(); } public List<String> getSplitePoints() { return null; } public TmxPropertiesBean getTmxProperties(boolean isReload) { return tmxDataAccess.loadTmxProperties(); } /** * 删除重复的TU,原文和译文相同。删除时如果TU中只有2个TUV,则直接删除TU;如果TU中有超过2个TUV则只删除当前TUV ; */ public void cleartDuplicatedTU(IProgressMonitor monitor, boolean ignoreTag, boolean ignoreCase) { boolean deleteTgtEmpty = tmxDataAccess.deleteDupaicate(monitor, ignoreTag, ignoreCase); if (!tmxDataAccess.isDirty()) { tmxDataAccess.setDirty(deleteTgtEmpty); } } /** * 删除空的TU,是指将当前过滤结果中译文为空串的TUV删除,删除时如果TU中只有2个TUV,则直接删除TU;如果TU中有超过2个TUV则只删除当前TUV ; */ public void clearEmptyTU(IProgressMonitor monitor,boolean ignoreTag) { boolean deleteTgtEmpty = tmxDataAccess.deleteTgtEmpty(monitor,ignoreTag); if (!tmxDataAccess.isDirty()) { tmxDataAccess.setDirty(deleteTgtEmpty); } } /** * 删除相同原文不同译文的TU,删除时如果TU中只有2个TUV,则直接删除TU;如果TU中有超过2个TUV则只删除当前TUV ; * @param monitor * @param ignoreTag */ public void cleartDuplicatedSrcDiffTgtTU(IProgressMonitor monitor, boolean ignoreTag, boolean ignoreCase) { boolean deleteTgtEmpty = tmxDataAccess.deleteSameSrcDiffTgt(monitor, ignoreTag, ignoreCase); if (!tmxDataAccess.isDirty()) { tmxDataAccess.setDirty(deleteTgtEmpty); } } public void clearEndsSpaces(IProgressMonitor monitor ) { boolean deleteTgtEmpty = tmxDataAccess.deleteEndsSpaces(monitor); if (!tmxDataAccess.isDirty()) { tmxDataAccess.setDirty(deleteTgtEmpty); } } /** * 始终重新加载后台数据 * @param monitor * @param reFreshUI * ; :是否刷新前台界面, */ public void loadDataAndReFreshUI(final IProgressMonitor monitor, final boolean reFreshUI) { final String srcSearchStr = getSearchText(srcSearchText); final String tgtSearchStr = getSearchText(tgtSearchText); Display.getDefault().syncExec(new Runnable() { @Override public void run() { tmxDataAccess.loadDisplayTuIdentifierByFilter(monitor, editorFilter.getCurrentFilter(), srcLangCode, tgtLangCode, srcSearchStr, tgtSearchStr); if (reFreshUI) { tmxEditorImpWithNattable.refrush(); // tmxEditorImpWithNattable.selectCell(getTgtColumnIndex(), 0); } } }); } public AbstractTmxDataAccess getTmxDataAccess() { return this.tmxDataAccess; } public TmxSegement getSelectedTuv() { return null; } public String getSrcLang() { return this.srcLangCode; } public String getTgtLang() { return this.tgtLangCode; } public void jumptoRow(int rowIndex) { } public int getSrcColumnIndex() { return 1; } public int getTgtColumnIndex() { return 2; } public void commit() { TeActiveCellEditor.commit(); } class FindReplaceAction extends Action { public FindReplaceAction() { setEnabled(false); } @Override public void runWithEvent(Event event) { if (dialog == null) { dialog = new FindReplaceDialog(viewPart.getSite().getShell()); } dialog.setTmxDataAccess(tmxDataAccess); dialog.setTmxEditorImpWithNattable(tmxEditorImpWithNattable); dialog.open(); ICellEditor iCellEditor = TeActiveCellEditor.getCellEditor(); if (iCellEditor != null && iCellEditor instanceof CellEditor) { CellEditor cellEditor = (CellEditor) iCellEditor; String selText = cellEditor.getTextViewer().getSelectionText(); dialog.setFindText(selText); } } void updateEnabledState() { if (tmxEditorImpWithNattable != null) { setEnabled(true); return; } setEnabled(false); } } public TmxEditorImpWithNattable getTmxEditorImpWithNattable() { return tmxEditorImpWithNattable; } /** * 获取选中行的id标示 * @return ; */ public String[] getSelectIdentifiers() { int[] selectedRows = tmxEditorImpWithNattable.getSelectedRows(); if (null == selectedRows || selectedRows.length == 0) { return new String[0]; } List<String> displayTuIdentifiers = this.tmxDataAccess.getDisplayTuIdentifiers(); if (null == displayTuIdentifiers || displayTuIdentifiers.isEmpty()) { return new String[0]; } String[] ids = new String[selectedRows.length]; int currentSelectLineNumber = 0; for (int i = 0; i < selectedRows.length; i++) { currentSelectLineNumber = selectedRows[i]; if (currentSelectLineNumber >= displayTuIdentifiers.size()) { return new String[0]; } ids[i] = displayTuIdentifiers.get(currentSelectLineNumber); } return ids; } }