zheng
3 years ago
873 changed files with 52904 additions and 6158 deletions
@ -0,0 +1,12 @@
|
||||
package com.fr.common.exception; |
||||
|
||||
/** |
||||
* @author hades |
||||
* @version 11.0 |
||||
* Created by hades on 2021/12/7 |
||||
*/ |
||||
public interface ThrowableHandler { |
||||
|
||||
boolean process(Throwable e); |
||||
|
||||
} |
@ -0,0 +1,193 @@
|
||||
package com.fr.design; |
||||
|
||||
import com.fr.concurrent.NamedThreadFactory; |
||||
import com.fr.general.CloudCenter; |
||||
import com.fr.general.CloudCenterConfig; |
||||
import com.fr.general.http.HttpToolbox; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.ProductConstants; |
||||
import com.fr.stable.StableUtils; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.stable.xml.XMLPrintWriter; |
||||
import com.fr.stable.xml.XMLReaderHelper; |
||||
import com.fr.stable.xml.XMLTools; |
||||
import com.fr.stable.xml.XMLable; |
||||
import com.fr.stable.xml.XMLableReader; |
||||
import com.fr.third.javax.xml.stream.XMLStreamException; |
||||
import com.fr.third.org.apache.commons.io.FileUtils; |
||||
|
||||
import java.io.ByteArrayOutputStream; |
||||
import java.io.File; |
||||
import java.io.FileInputStream; |
||||
import java.io.FileNotFoundException; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.nio.charset.StandardCharsets; |
||||
import java.util.HashMap; |
||||
import java.util.Iterator; |
||||
import java.util.Map; |
||||
import java.util.concurrent.ExecutorService; |
||||
import java.util.concurrent.Executors; |
||||
|
||||
/** |
||||
* Created by kerry on 2021/10/22 |
||||
*/ |
||||
public class DesignerCloudURLManager implements XMLable { |
||||
private static final String CLOUD_URL_INFO = "cloudUrl.info"; |
||||
private static final String ROOT_XML_TAG = "CloudUrlInfoList"; |
||||
private static final String CHILD_XML_TAG = "CloudUrlInfo"; |
||||
private final Map<String, String> urlMap = new HashMap<>(); |
||||
|
||||
public static DesignerCloudURLManager getInstance() { |
||||
return DesignerCloudURLManager.HOLDER.singleton; |
||||
} |
||||
|
||||
private final ExecutorService executorService = Executors.newSingleThreadExecutor(new NamedThreadFactory("TestCloudConnectThread")); |
||||
|
||||
private volatile boolean testResult; |
||||
|
||||
|
||||
private static class HOLDER { |
||||
private static final DesignerCloudURLManager singleton = new DesignerCloudURLManager(); |
||||
} |
||||
|
||||
private DesignerCloudURLManager() { |
||||
loadURLXMLFile(); |
||||
} |
||||
|
||||
public String acquireUrlByKind(String key) { |
||||
String url = urlMap.getOrDefault(key, StringUtils.EMPTY); |
||||
if (StringUtils.isEmpty(url)) { |
||||
//本地缓存中为空时,直接从云中心获取,获取完成后异步更新本地缓存文件
|
||||
String latestUrl = CloudCenter.getInstance().acquireConf(key, StringUtils.EMPTY); |
||||
executorService.submit(() -> { |
||||
updateURLXMLFile(key, latestUrl); |
||||
}); |
||||
return latestUrl; |
||||
} |
||||
//本地缓存不为空时,直接返回对应 url,同时异步更新
|
||||
executorService.submit(() -> { |
||||
String latestUrl = CloudCenter.getInstance().acquireConf(key, StringUtils.EMPTY); |
||||
updateURLXMLFile(key, latestUrl); |
||||
}); |
||||
return url; |
||||
} |
||||
|
||||
private synchronized void updateURLXMLFile(String key, String url) { |
||||
if (StringUtils.isNotEmpty(url) && (!urlMap.containsKey(key) || !url.equals(urlMap.get(key)))) { |
||||
urlMap.put(key, url); |
||||
saveURLXMLFile(); |
||||
} |
||||
} |
||||
|
||||
|
||||
public void testConnect() { |
||||
executorService.submit(() -> { |
||||
testResult = isOnline(); |
||||
}); |
||||
} |
||||
|
||||
public boolean isConnected() { |
||||
return testResult; |
||||
} |
||||
|
||||
public boolean isOnline() { |
||||
if (CloudCenterConfig.getInstance().isOnline()) { |
||||
String ping = acquireUrlByKind("ping"); |
||||
if (StringUtils.isNotEmpty(ping)) { |
||||
try { |
||||
return StringUtils.isEmpty(HttpToolbox.get(ping)); |
||||
} catch (Exception ignore) { |
||||
} |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 加载本地 url 管理文件 |
||||
*/ |
||||
private void loadURLXMLFile() { |
||||
if (!getInfoFile().exists()) { |
||||
return; |
||||
} |
||||
XMLableReader reader = null; |
||||
try (InputStream in = new FileInputStream(getInfoFile())) { |
||||
// XMLableReader 还是应该考虑实现 Closable 接口的,这样就能使用 try-with 语句了
|
||||
reader = XMLReaderHelper.createXMLableReader(in, XMLPrintWriter.XML_ENCODER); |
||||
if (reader == null) { |
||||
return; |
||||
} |
||||
reader.readXMLObject(this); |
||||
} catch (FileNotFoundException e) { |
||||
// do nothing
|
||||
} catch (XMLStreamException | IOException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} finally { |
||||
try { |
||||
if (reader != null) { |
||||
reader.close(); |
||||
} |
||||
} catch (XMLStreamException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private File getInfoFile() { |
||||
|
||||
File file = new File(StableUtils.pathJoin(ProductConstants.getEnvHome(), CLOUD_URL_INFO)); |
||||
try { |
||||
if (!file.exists()) { |
||||
file.createNewFile(); |
||||
} |
||||
} catch (Exception ex) { |
||||
FineLoggerFactory.getLogger().error(ex.getMessage(), ex); |
||||
} |
||||
return file; |
||||
} |
||||
|
||||
/** |
||||
* 保存到本地 URL 管理文件中,存放在 .Finereport110 中 |
||||
*/ |
||||
void saveURLXMLFile() { |
||||
try { |
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(); |
||||
XMLTools.writeOutputStreamXML(this, out); |
||||
out.flush(); |
||||
out.close(); |
||||
String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8); |
||||
FileUtils.writeStringToFile(getInfoFile(), fileContent, StandardCharsets.UTF_8); |
||||
} catch (Exception ex) { |
||||
FineLoggerFactory.getLogger().error(ex.getMessage()); |
||||
} |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void readXML(XMLableReader reader) { |
||||
String tagName = reader.getTagName(); |
||||
if (tagName.equals(CHILD_XML_TAG)) { |
||||
String key = reader.getAttrAsString("key", StringUtils.EMPTY); |
||||
String value = reader.getAttrAsString("url", StringUtils.EMPTY); |
||||
this.urlMap.put(key, value); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void writeXML(XMLPrintWriter xmlPrintWriter) { |
||||
xmlPrintWriter.startTAG(ROOT_XML_TAG); |
||||
Iterator<Map.Entry<String, String>> iterable = urlMap.entrySet().iterator(); |
||||
while (iterable.hasNext()) { |
||||
Map.Entry<String, String> entry = iterable.next(); |
||||
xmlPrintWriter.startTAG(CHILD_XML_TAG).attr("key", entry.getKey()).attr("url", entry.getValue()).end(); |
||||
} |
||||
xmlPrintWriter.end(); |
||||
} |
||||
|
||||
@Override |
||||
public Object clone() throws CloneNotSupportedException { |
||||
return null; |
||||
} |
||||
} |
@ -0,0 +1,47 @@
|
||||
package com.fr.design.actions.file; |
||||
|
||||
import com.fr.base.BaseUtils; |
||||
import com.fr.design.actions.UpdateAction; |
||||
import com.fr.design.menu.MenuKeySet; |
||||
import com.fr.locale.InterProviderFactory; |
||||
import com.fr.nx.app.designer.transform.ui.BatchTransformPane; |
||||
|
||||
import javax.swing.KeyStroke; |
||||
import java.awt.Dialog; |
||||
import java.awt.event.ActionEvent; |
||||
|
||||
/** |
||||
* Created by kerry on 2019-12-10 |
||||
*/ |
||||
public class BatchCompileAction extends UpdateAction { |
||||
public BatchCompileAction() { |
||||
this.setMenuKeySet(COMPILE); |
||||
this.setName(getMenuKeySet().getMenuKeySetName() + "..."); |
||||
this.setMnemonic(getMenuKeySet().getMnemonic()); |
||||
this.setSmallIcon(BaseUtils.readIcon("/com/fr/nx/app/designer/transform/batch_transform.png")); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
BatchTransformPane batchTransformPane = new BatchTransformPane(); |
||||
Dialog dialog = batchTransformPane.showDialog(); |
||||
dialog.setVisible(true); |
||||
} |
||||
|
||||
private static final MenuKeySet COMPILE = new MenuKeySet() { |
||||
@Override |
||||
public char getMnemonic() { |
||||
return 'C'; |
||||
} |
||||
|
||||
@Override |
||||
public String getMenuName() { |
||||
return InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Batch_Transform"); |
||||
} |
||||
|
||||
@Override |
||||
public KeyStroke getKeyStroke() { |
||||
return null; |
||||
} |
||||
}; |
||||
} |
@ -0,0 +1,49 @@
|
||||
package com.fr.design.actions.server; |
||||
|
||||
import com.fr.base.BaseUtils; |
||||
import com.fr.design.actions.UpdateAction; |
||||
import com.fr.design.menu.MenuKeySet; |
||||
import com.fr.design.utils.DesignUtils; |
||||
import com.fr.locale.InterProviderFactory; |
||||
import com.fr.nx.app.web.URLConstants; |
||||
import com.fr.stable.StableUtils; |
||||
|
||||
import javax.swing.KeyStroke; |
||||
import java.awt.event.ActionEvent; |
||||
|
||||
/** |
||||
* @author Maksim |
||||
* Created in 2020/11/5 11:44 上午 |
||||
*/ |
||||
public class LocalAnalyzerAction extends UpdateAction { |
||||
|
||||
public LocalAnalyzerAction() { |
||||
this.setMenuKeySet(ANALYZER); |
||||
this.setName(getMenuKeySet().getMenuKeySetName()); |
||||
this.setMnemonic(getMenuKeySet().getMnemonic()); |
||||
this.setSmallIcon(BaseUtils.readIcon("/com/fr/nx/app/designer/transform/analyzer.png")); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
String path = StableUtils.pathJoin("/nx", URLConstants.ANALYZE_VIEW); |
||||
DesignUtils.visitEnvServerByParameters(path, new String[]{}, new String[]{}); |
||||
} |
||||
|
||||
private static final MenuKeySet ANALYZER = new MenuKeySet() { |
||||
@Override |
||||
public char getMnemonic() { |
||||
return 'R'; |
||||
} |
||||
|
||||
@Override |
||||
public String getMenuName() { |
||||
return InterProviderFactory.getProvider().getLocText("Fine-Plugin-Engine_Analyzer_Menu_Name"); |
||||
} |
||||
|
||||
@Override |
||||
public KeyStroke getKeyStroke() { |
||||
return null; |
||||
} |
||||
}; |
||||
} |
@ -0,0 +1,32 @@
|
||||
package com.fr.design.border; |
||||
|
||||
import com.fr.design.constants.UIConstants; |
||||
|
||||
import javax.swing.BorderFactory; |
||||
import javax.swing.border.TitledBorder; |
||||
import java.awt.Color; |
||||
|
||||
public class UITitledMatteBorder extends TitledBorder { |
||||
public static UITitledMatteBorder createTitledTopBorder(String title, Color color) { |
||||
return new UITitledMatteBorder(title, 1, 0, 0, 0, color); |
||||
} |
||||
|
||||
public static UITitledMatteBorder createTitledBorder(String title, Color color) { |
||||
return new UITitledMatteBorder(title, 1, 1, 1, 1, color); |
||||
} |
||||
|
||||
public static UITitledMatteBorder createTitledBorder(String title, int top, int left, int bottom, int right, Color color) { |
||||
return new UITitledMatteBorder(title, top, left, bottom, right, color); |
||||
} |
||||
|
||||
private UITitledMatteBorder(String title, int top, int left, int bottom, int right, Color color) { |
||||
super( |
||||
BorderFactory.createMatteBorder(top, left, bottom, right, UIConstants.TITLED_BORDER_COLOR), |
||||
title, |
||||
TitledBorder.LEADING, |
||||
TitledBorder.TOP, |
||||
null, |
||||
color |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,180 @@
|
||||
package com.fr.design.cell; |
||||
|
||||
import com.fr.base.CellBorderSourceFlag; |
||||
import com.fr.base.CellBorderStyle; |
||||
import com.fr.base.Style; |
||||
import com.fr.design.mainframe.theme.utils.DefaultThemedTemplateCellElementCase; |
||||
import com.fr.general.IOUtils; |
||||
import com.fr.report.cell.TemplateCellElement; |
||||
|
||||
import javax.swing.JPanel; |
||||
import java.awt.AlphaComposite; |
||||
import java.awt.Color; |
||||
import java.awt.Composite; |
||||
import java.awt.Dimension; |
||||
import java.awt.Graphics; |
||||
import java.awt.Graphics2D; |
||||
import java.awt.GridLayout; |
||||
import java.awt.Rectangle; |
||||
import java.awt.RenderingHints; |
||||
import java.awt.image.BufferedImage; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/9/3 |
||||
*/ |
||||
public class CellRectangleStylePreviewPane extends JPanel { |
||||
|
||||
private static final BufferedImage transparentBackgroundImage = IOUtils.readImage("/com/fr/design/images/transparent_background.png"); |
||||
private final float transparentBackgroundWidth; |
||||
private final float transparentBackgroundHeight; |
||||
|
||||
private static final int ROW_COUNT = 2; |
||||
private static final int COLUMN_COUNT = 2; |
||||
|
||||
private final TemplateCellElement[][] cellElementGrid = new TemplateCellElement[ROW_COUNT][COLUMN_COUNT]; |
||||
private final int[][] borderSourceFlags = new int[ROW_COUNT][COLUMN_COUNT]; |
||||
private final CellStylePreviewPane[][] cellStylePreviewPaneGrid = new CellStylePreviewPane[ROW_COUNT][COLUMN_COUNT]; |
||||
|
||||
public CellRectangleStylePreviewPane(boolean supportInnerBorder) { |
||||
transparentBackgroundWidth = transparentBackgroundImage.getWidth(null); |
||||
transparentBackgroundHeight = transparentBackgroundImage.getHeight(null); |
||||
|
||||
setLayout(new GridLayout(2, 2)); |
||||
setOpaque(false); |
||||
setBackground(null); |
||||
|
||||
for (int r = 0; r < ROW_COUNT; r++) { |
||||
for (int c = 0; c < COLUMN_COUNT; c++) { |
||||
CellStylePreviewPane pane = new CellStylePreviewPane(c, r, COLUMN_COUNT, ROW_COUNT, false, false); |
||||
TemplateCellElement cellElement = DefaultThemedTemplateCellElementCase.createInstance(c, r); |
||||
int flags = CellBorderSourceFlag.INVALID_BORDER_SOURCE; |
||||
if (supportInnerBorder) { |
||||
flags = CellBorderSourceFlag.ALL_BORDER_SOURCE_OUTER; |
||||
if (r != 0) { |
||||
flags |= CellBorderSourceFlag.TOP_BORDER_SOURCE_INNER; |
||||
} |
||||
if (r != ROW_COUNT - 1) { |
||||
flags |= CellBorderSourceFlag.BOTTOM_BORDER_SOURCE_INNER; |
||||
} |
||||
if (c != 0) { |
||||
flags |= CellBorderSourceFlag.LEFT_BORDER_SOURCE_INNER; |
||||
} |
||||
if (c != COLUMN_COUNT - 1) { |
||||
flags |= CellBorderSourceFlag.RIGHT_BORDER_SOURCE_INNER; |
||||
} |
||||
} |
||||
|
||||
|
||||
pane.setStyle(cellElement.getStyle()); |
||||
add(pane); |
||||
|
||||
cellElementGrid[r][c] = cellElement; |
||||
borderSourceFlags[r][c] = flags; |
||||
cellStylePreviewPaneGrid[r][c] = pane; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public void setPlainText(String text) { |
||||
cellStylePreviewPaneGrid[0][1].setPaintText(text); |
||||
cellStylePreviewPaneGrid[1][1].setPaintText(text); |
||||
repaint(); |
||||
} |
||||
|
||||
public void setStyle(Style style, CellBorderStyle borderStyle) { |
||||
for (int i = 0; i < ROW_COUNT; i++) { |
||||
for (int j = 0; j < COLUMN_COUNT; j++) { |
||||
CellStylePreviewPane pane = cellStylePreviewPaneGrid[i][j]; |
||||
TemplateCellElement cellElement = cellElementGrid[i][j]; |
||||
int flag = borderSourceFlags[i][j]; |
||||
cellElement.setStyle(CellBorderSourceFlag.deriveBorderedStyle(style, borderStyle, flag)); |
||||
|
||||
pane.setStyle(cellElement.getStyle()); |
||||
} |
||||
} |
||||
repaint(); |
||||
} |
||||
|
||||
@Override |
||||
public void setPreferredSize(Dimension preferredSize) { |
||||
super.setPreferredSize(preferredSize); |
||||
int hw = preferredSize.width / 2; |
||||
int hh = preferredSize.height / 2; |
||||
cellStylePreviewPaneGrid[0][0].setPreferredSize(new Dimension(hw, hh)); |
||||
cellStylePreviewPaneGrid[0][1].setPreferredSize(new Dimension(hw, hh)); |
||||
cellStylePreviewPaneGrid[1][0].setPreferredSize(new Dimension(hw, hh)); |
||||
cellStylePreviewPaneGrid[1][1].setPreferredSize(new Dimension(hw, hh)); |
||||
} |
||||
|
||||
@Override |
||||
public Dimension getPreferredSize() { |
||||
Dimension d00 = cellStylePreviewPaneGrid[0][0].getPreferredSize(); |
||||
Dimension d01 = cellStylePreviewPaneGrid[0][1].getPreferredSize(); |
||||
Dimension d10 = cellStylePreviewPaneGrid[1][0].getPreferredSize(); |
||||
Dimension d11 = cellStylePreviewPaneGrid[1][1].getPreferredSize(); |
||||
|
||||
int width = Math.max(d00.width + d01.width, d10.width + d11.width); |
||||
int height = Math.max(d00.height + d10.height, d01.height + d11.height); |
||||
|
||||
return new Dimension(width, height); |
||||
} |
||||
|
||||
@Override |
||||
public void paint(Graphics g) { |
||||
Graphics2D g2d = (Graphics2D) g; |
||||
g2d.clearRect(0, 0, getWidth(), getHeight()); |
||||
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); |
||||
|
||||
paintTransparentBackground((Graphics2D) g, cellElementGrid[0][0].getStyle()); |
||||
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); |
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); |
||||
|
||||
super.paint(g); |
||||
} |
||||
|
||||
@Override |
||||
public Rectangle getBounds() { |
||||
return super.getBounds(); |
||||
} |
||||
|
||||
private void paintTransparentBackground(Graphics2D g2d, Style style) { |
||||
float alpha = computeTransparentBackgroundAlpha(style); |
||||
|
||||
float scaleWidth = 1.0F * getWidth() / transparentBackgroundWidth; |
||||
float scaleHeight = 1.0F * getHeight() / transparentBackgroundHeight; |
||||
float maxScale = Math.max(scaleWidth, scaleHeight); |
||||
|
||||
if (maxScale <= 1) { |
||||
scaleWidth = scaleHeight = 1; |
||||
} else { |
||||
scaleHeight = scaleWidth = maxScale; |
||||
} |
||||
|
||||
Composite oldComposite = g2d.getComposite(); |
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); |
||||
g2d.drawImage(transparentBackgroundImage, 0, 0, (int) (transparentBackgroundWidth * scaleWidth), (int) (transparentBackgroundHeight * scaleHeight), null); |
||||
g2d.setComposite(oldComposite); |
||||
} |
||||
|
||||
private float computeTextColorBrightness(Style style) { |
||||
Color fontColor = style.getFRFont().getForeground(); |
||||
return fontColor.getRed() * 0.299F + fontColor.getGreen() * 0.587F + fontColor.getBlue() * 0.114F; |
||||
} |
||||
|
||||
private float computeTransparentBackgroundAlpha(Style style) { |
||||
float textBrightness = computeTextColorBrightness(style); |
||||
|
||||
float alpha = 1.0F; |
||||
if (textBrightness < 50) { |
||||
alpha = 0.2F; |
||||
} else if (textBrightness < 160){ |
||||
alpha = 0.5F; |
||||
} |
||||
return alpha; |
||||
} |
||||
} |
@ -0,0 +1,220 @@
|
||||
package com.fr.design.cell; |
||||
|
||||
import com.fr.base.BaseUtils; |
||||
import com.fr.base.GraphHelper; |
||||
import com.fr.base.NameStyle; |
||||
import com.fr.base.ScreenResolution; |
||||
import com.fr.base.Style; |
||||
import com.fr.general.FRFont; |
||||
import com.fr.general.IOUtils; |
||||
import com.fr.stable.Constants; |
||||
import com.fr.stable.unit.PT; |
||||
|
||||
import javax.swing.JPanel; |
||||
import java.awt.AlphaComposite; |
||||
import java.awt.Color; |
||||
import java.awt.Composite; |
||||
import java.awt.Dimension; |
||||
import java.awt.Font; |
||||
import java.awt.FontMetrics; |
||||
import java.awt.Graphics; |
||||
import java.awt.Graphics2D; |
||||
import java.awt.RenderingHints; |
||||
import java.awt.image.BufferedImage; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/9/3 |
||||
*/ |
||||
public class CellStylePreviewPane extends JPanel { |
||||
|
||||
public static final int MINIMUM_HEIGHT = 40; |
||||
private static final BufferedImage transparentBackgroundImage = IOUtils.readImage("/com/fr/design/images/transparent_background.png"); |
||||
private final float transparentBackgroundWidth; |
||||
private final float transparentBackgroundHeight; |
||||
private String paintText = "Report"; |
||||
private Style style = Style.DEFAULT_STYLE; |
||||
|
||||
private final int column; |
||||
private final int row; |
||||
private final int columnSpan; |
||||
private final int rowSpan; |
||||
|
||||
private final boolean autoClearCanvas; |
||||
private final boolean paintingMosaic; |
||||
|
||||
public CellStylePreviewPane(int column, int row, int columnSpan, int rowSpan, boolean autoClearCanvas, boolean paintingMosaic) { |
||||
this.column = column; |
||||
this.row = row; |
||||
this.columnSpan = columnSpan; |
||||
this.rowSpan = rowSpan; |
||||
this.autoClearCanvas = autoClearCanvas; |
||||
this.paintingMosaic = paintingMosaic; |
||||
transparentBackgroundWidth = transparentBackgroundImage.getWidth(null); |
||||
transparentBackgroundHeight = transparentBackgroundImage.getHeight(null); |
||||
setPreferredSize(new Dimension(0, 0)); |
||||
} |
||||
|
||||
public void setPaintText(String paintText) { |
||||
this.paintText = paintText; |
||||
repaint(); |
||||
} |
||||
|
||||
public void setStyle(Style style) { |
||||
this.style = style; |
||||
repaint(); |
||||
} |
||||
|
||||
public void setStyle(NameStyle style) { |
||||
paintText = style.getName(); |
||||
setStyle(style.getRealStyle()); |
||||
} |
||||
|
||||
@Override |
||||
public void paint(Graphics g) { |
||||
Graphics2D g2d = (Graphics2D) g; |
||||
if (autoClearCanvas) { |
||||
g2d.clearRect(0, 0, getWidth(), getHeight()); |
||||
} |
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); |
||||
|
||||
if (paintingMosaic) { |
||||
paintTransparentBackground(g2d, style); |
||||
} |
||||
|
||||
paintCellStyle(g2d, style); |
||||
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); |
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); |
||||
} |
||||
|
||||
private void paintTransparentBackground(Graphics2D g2d, Style style) { |
||||
float alpha = computeTransparentBackgroundAlpha(style); |
||||
|
||||
float scaleWidth = 1.0F * getWidth() / transparentBackgroundWidth; |
||||
float scaleHeight = 1.0F * getHeight() / transparentBackgroundHeight; |
||||
float maxScale = Math.max(scaleWidth, scaleHeight); |
||||
|
||||
if (maxScale <= 1) { |
||||
scaleWidth = scaleHeight = 1; |
||||
} else { |
||||
scaleHeight = scaleWidth = maxScale; |
||||
} |
||||
|
||||
Composite oldComposite = g2d.getComposite(); |
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); |
||||
g2d.drawImage(transparentBackgroundImage, 0, 0, (int) (transparentBackgroundWidth * scaleWidth), (int) (transparentBackgroundHeight * scaleHeight), null); |
||||
g2d.setComposite(oldComposite); |
||||
} |
||||
|
||||
private float computeTextColorBrightness(Style style) { |
||||
Color fontColor = style.getFRFont().getForeground(); |
||||
return fontColor.getRed() * 0.299F + fontColor.getGreen() * 0.587F + fontColor.getBlue() * 0.114F; |
||||
} |
||||
|
||||
private float computeTransparentBackgroundAlpha(Style style) { |
||||
float textBrightness = computeTextColorBrightness(style); |
||||
|
||||
float alpha = 1.0F; |
||||
if (textBrightness < 50) { |
||||
alpha = 0.2F; |
||||
} else if (textBrightness < 160){ |
||||
alpha = 0.5F; |
||||
} |
||||
return alpha; |
||||
} |
||||
|
||||
private void paintCellStyle(Graphics2D g2d, Style style) { |
||||
int resolution = ScreenResolution.getScreenResolution(); |
||||
|
||||
int width = getWidth(); |
||||
int height = getHeight(); |
||||
|
||||
if (style == Style.DEFAULT_STYLE) { |
||||
// 如果是默认的style,就只写"Report"上去
|
||||
Style.paintContent(g2d, paintText, style, width, height, resolution); |
||||
return; |
||||
} |
||||
|
||||
Style.paintBackground(g2d, style, width, height); |
||||
|
||||
Style.paintContent(g2d, paintText, style, width, height, resolution); |
||||
|
||||
paintCellBorder(g2d, style); |
||||
} |
||||
|
||||
protected void paintCellBorder(Graphics2D g2d, Style style) { |
||||
float adjustLeft = 0; |
||||
float adjustTop = 0; |
||||
float adjustRight = 0; |
||||
float adjustBottom = 0; |
||||
if (column == 0) { |
||||
adjustLeft = computeHalfSize4StyledBorder(style.getBorderLeft()); |
||||
} |
||||
if (row == 0) { |
||||
adjustTop = computeHalfSize4StyledBorder(style.getBorderTop()); |
||||
} |
||||
if (column == columnSpan - 1) { |
||||
adjustRight = -computeHalfSize4StyledBorder(style.getBorderRight()); |
||||
} |
||||
if (row == rowSpan - 1) { |
||||
adjustBottom = -computeHalfSize4StyledBorder(style.getBorderBottom()); |
||||
} |
||||
|
||||
g2d.translate(adjustLeft, adjustTop); |
||||
Style.paintBorder(g2d, style, getWidth() - adjustLeft + adjustRight, getHeight() - adjustTop + adjustBottom); |
||||
g2d.translate(-adjustLeft, -adjustTop); |
||||
} |
||||
|
||||
private float computeHalfSize4StyledBorder(int border) { |
||||
float size = GraphHelper.getLineStyleSize(border) / 2.0F; |
||||
|
||||
if (border == Constants.LINE_DOUBLE) { |
||||
size += GraphHelper.getLineStyleSize(Constants.LINE_THIN) / 2.0F; |
||||
} else if (border == Constants.LINE_DOUBLE_DOT) { |
||||
size += GraphHelper.getLineStyleSize(Constants.LINE_DOT) / 2.0F; |
||||
} |
||||
|
||||
return size; |
||||
} |
||||
|
||||
@Override |
||||
public Dimension getPreferredSize() { |
||||
Dimension size = super.getPreferredSize(); |
||||
int width = size.width; |
||||
int height = size.height; |
||||
|
||||
if (height != 0) { |
||||
// 使用者设置了一个高度
|
||||
return size; |
||||
} else if (width == 0) { |
||||
// 使用者未设置任何尺寸
|
||||
return new Dimension(width, MINIMUM_HEIGHT); |
||||
} else { |
||||
// 使用者设置了宽度,但未设置高度
|
||||
return getAutoWrapContentPreferredSize(width, height); |
||||
} |
||||
} |
||||
|
||||
private Dimension getAutoWrapContentPreferredSize(int width, int height) { |
||||
int resolution = ScreenResolution.getScreenResolution(); |
||||
|
||||
// 计算文本区域高度
|
||||
final FRFont frFont = style.getFRFont(); |
||||
final Font rfont = frFont.applyResolutionNP(resolution); |
||||
final FontMetrics metrics = GraphHelper.getFontMetrics(rfont); |
||||
final int textLineHeight = metrics.getHeight(); |
||||
final double textLineSpacing = PT.pt2pix(style.getLineSpacing(), resolution); |
||||
|
||||
List<?> textLineList = BaseUtils.getLineTextList(paintText, style, rfont, height, width, resolution); |
||||
|
||||
double textLinesHeight = textLineList.size() * textLineHeight + Math.max(0, textLineList.size() - 1) * textLineSpacing; |
||||
|
||||
height = (int) Math.max(MINIMUM_HEIGHT, textLinesHeight); |
||||
|
||||
return new Dimension(width, height); |
||||
} |
||||
} |
@ -0,0 +1,52 @@
|
||||
package com.fr.design.config; |
||||
|
||||
import com.fr.general.IOUtils; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.StableUtils; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import java.io.BufferedInputStream; |
||||
import java.io.FileInputStream; |
||||
import java.io.FileNotFoundException; |
||||
import java.io.InputStream; |
||||
import java.util.Properties; |
||||
|
||||
public class DesignerProperties { |
||||
private static DesignerProperties holder = null; |
||||
private boolean supportLoginEntry = true; |
||||
|
||||
public DesignerProperties() { |
||||
String filePath = StableUtils.pathJoin(StableUtils.getInstallHome(), "/config/config.properties"); |
||||
InputStream is = null; |
||||
try { |
||||
is = new BufferedInputStream(new FileInputStream(filePath)); |
||||
Properties ps = new Properties(); |
||||
ps.load(is); |
||||
this.initProperties(ps); |
||||
} catch (FileNotFoundException e) { |
||||
// ignore
|
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().error(e, e.getMessage()); |
||||
} finally { |
||||
IOUtils.close(is); |
||||
} |
||||
} |
||||
|
||||
public static DesignerProperties getInstance() { |
||||
if (holder == null) { |
||||
holder = new DesignerProperties(); |
||||
} |
||||
return holder; |
||||
} |
||||
|
||||
private void initProperties(Properties ps) { |
||||
String supportLoginEntry = ps.getProperty("supportLoginEntry"); |
||||
if (StringUtils.isNotEmpty(supportLoginEntry)) { |
||||
this.supportLoginEntry = Boolean.valueOf(supportLoginEntry); |
||||
} |
||||
} |
||||
|
||||
public boolean isSupportLoginEntry() { |
||||
return supportLoginEntry; |
||||
} |
||||
} |
@ -0,0 +1,27 @@
|
||||
package com.fr.design.data; |
||||
|
||||
public class NameChangeBean { |
||||
private String oldName; |
||||
private String changedName; |
||||
|
||||
public NameChangeBean(String oldName, String changedName) { |
||||
this.oldName = oldName; |
||||
this.changedName = changedName; |
||||
} |
||||
|
||||
public String getOldName() { |
||||
return oldName; |
||||
} |
||||
|
||||
public void setOldName(String oldName) { |
||||
this.oldName = oldName; |
||||
} |
||||
|
||||
public String getChangedName() { |
||||
return changedName; |
||||
} |
||||
|
||||
public void setChangedName(String changedName) { |
||||
this.changedName = changedName; |
||||
} |
||||
} |
@ -0,0 +1,136 @@
|
||||
package com.fr.design.data; |
||||
|
||||
import com.fr.base.io.IOFile; |
||||
import com.fr.design.file.HistoryTemplateListCache; |
||||
import com.fr.design.mainframe.JTemplate; |
||||
import com.fr.esd.core.strategy.config.StrategyConfig; |
||||
import com.fr.esd.core.strategy.config.StrategyConfigHelper; |
||||
import com.fr.esd.core.strategy.config.service.StrategyConfigService; |
||||
import com.fr.esd.core.strategy.persistence.StrategyConfigsAttr; |
||||
import com.fr.esd.event.DSMapping; |
||||
import com.fr.esd.event.DsNameTarget; |
||||
import com.fr.esd.event.StrategyEventsNotifier; |
||||
import com.fr.esd.event.xml.XMLSavedHook; |
||||
import com.fr.file.FILE; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.workspace.WorkContext; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.HashSet; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* @author rinoux |
||||
* @version 10.0 |
||||
* Created by rinoux on 2020/10/28 |
||||
*/ |
||||
public class StrategyConfigAttrUtils { |
||||
|
||||
/** |
||||
* 获取当前编辑模版的数据集缓存配置属性 |
||||
* |
||||
* @return |
||||
*/ |
||||
private static StrategyConfigsAttr getStrategyConfigsAttr() { |
||||
StrategyConfigsAttr attr; |
||||
JTemplate<?, ?> jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
||||
if (jTemplate != null) { |
||||
IOFile ioFile = (IOFile) jTemplate.getTarget(); |
||||
|
||||
attr = ioFile.getAttrMark(StrategyConfigsAttr.ATTR_MARK); |
||||
if (attr == null) { |
||||
attr = new StrategyConfigsAttr(); |
||||
ioFile.addAttrMark(attr); |
||||
} |
||||
|
||||
//新建模版此时不存在,不需要注册钩子
|
||||
if (attr.getXmlSavedHook() == null && WorkContext.getWorkResource().exist(jTemplate.getPath())) { |
||||
attr.setXmlSavedHook(new StrategyConfigsAttrSavedHook(jTemplate.getPath(), attr)); |
||||
} |
||||
return attr; |
||||
} else { |
||||
throw new IllegalStateException("[ESD]No editing template found."); |
||||
} |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 获取模版数据集配置 |
||||
* |
||||
* @param dsName |
||||
* @return |
||||
*/ |
||||
public static StrategyConfig getStrategyConfig(String dsName) { |
||||
|
||||
return getStrategyConfigsAttr().getStrategyConfig(dsName); |
||||
} |
||||
|
||||
/** |
||||
* 移除模版数据集配置 |
||||
* |
||||
* @param dsName |
||||
* @return |
||||
*/ |
||||
public static StrategyConfig removeStrategyConfig(String dsName) { |
||||
|
||||
return getStrategyConfigsAttr().removeStrategyConfig(dsName); |
||||
} |
||||
|
||||
/** |
||||
* 添加模版数据集配置 |
||||
* |
||||
* @param strategyConfig |
||||
*/ |
||||
public static void addStrategyConfig(StrategyConfig strategyConfig) { |
||||
|
||||
getStrategyConfigsAttr().addStrategyConfig(strategyConfig); |
||||
} |
||||
|
||||
|
||||
private static class StrategyConfigsAttrSavedHook implements XMLSavedHook<StrategyConfigsAttr> { |
||||
|
||||
private static final long serialVersionUID = -8843201977112289321L; |
||||
|
||||
private final String tplPath; |
||||
private final Map<String, StrategyConfig> origStrategyConfigs; |
||||
|
||||
public StrategyConfigsAttrSavedHook(String tplPath, StrategyConfigsAttr raw) { |
||||
this.tplPath = tplPath; |
||||
this.origStrategyConfigs = new HashMap<>(); |
||||
this.initOrigStrategyConfigs(raw); |
||||
} |
||||
|
||||
|
||||
private void initOrigStrategyConfigs(StrategyConfigsAttr raw) { |
||||
origStrategyConfigs.clear(); |
||||
raw.getStrategyConfigs().forEach((k, v) -> { |
||||
try { |
||||
origStrategyConfigs.put(k, v.clone()); |
||||
} catch (CloneNotSupportedException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
@Override |
||||
public void doAfterSaved(StrategyConfigsAttr saved) { |
||||
|
||||
FineLoggerFactory.getLogger().info("[ESD]Write StrategyConfigsAttr done, now check change."); |
||||
Set<String> dsNames = new HashSet<>(); |
||||
dsNames.addAll(origStrategyConfigs.keySet()); |
||||
dsNames.addAll(saved.getStrategyConfigs().keySet()); |
||||
|
||||
if (StringUtils.isNotEmpty(tplPath)) { |
||||
dsNames.forEach(dsName -> { |
||||
if (StringUtils.isNotEmpty(dsName)) { |
||||
StrategyEventsNotifier.compareAndFireConfigEvents(origStrategyConfigs.get(dsName), saved.getStrategyConfig(dsName), new DSMapping(tplPath, new DsNameTarget(dsName))); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
initOrigStrategyConfigs(saved); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,226 @@
|
||||
package com.fr.design.data.datapane; |
||||
|
||||
import com.fr.design.beans.BasicBeanPane; |
||||
import com.fr.design.gui.ibutton.UIRadioButton; |
||||
import com.fr.design.gui.icheckbox.UICheckBox; |
||||
import com.fr.design.gui.ilable.ActionLabel; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.gui.itextfield.UITextField; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
import com.fr.design.utils.gui.GUICoreUtils; |
||||
import com.fr.esd.common.CacheConstants; |
||||
import com.fr.esd.core.strategy.config.StrategyConfig; |
||||
import com.fr.esd.core.strategy.config.StrategyConfigHelper; |
||||
import com.fr.esd.util.ESDUtils; |
||||
import com.fr.locale.InterProviderFactory; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import javax.swing.AbstractAction; |
||||
import javax.swing.JPanel; |
||||
import java.awt.BorderLayout; |
||||
import java.awt.Color; |
||||
import java.awt.Component; |
||||
import java.awt.Desktop; |
||||
import java.awt.event.ActionEvent; |
||||
import java.awt.event.ActionListener; |
||||
import java.net.URI; |
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author rinoux |
||||
* @version 10.0 |
||||
* Created by rinoux on 2020/7/22 |
||||
*/ |
||||
public class ESDStrategyConfigPane extends BasicBeanPane<StrategyConfig> { |
||||
private static final String CRON_HELP_URL = "http://help.fanruan.com/finereport/doc-view-693.html"; |
||||
|
||||
private UIRadioButton selectAutoUpdate; |
||||
private UIRadioButton selectBySchema; |
||||
private UICheckBox shouldEvolve; |
||||
private UILabel updateIntervalCheckTips; |
||||
private UITextField updateInterval; |
||||
private UITextField schemaTime; |
||||
private ActionLabel actionLabel; |
||||
private UILabel schemaTimeCheckTips; |
||||
private final boolean global; |
||||
private StrategyConfig strategyConfig; |
||||
|
||||
|
||||
public ESDStrategyConfigPane(boolean global) { |
||||
this.global = global; |
||||
init(); |
||||
} |
||||
|
||||
private void init() { |
||||
setLayout(FRGUIPaneFactory.createM_BorderLayout()); |
||||
|
||||
this.selectAutoUpdate = new UIRadioButton(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Every_Interval")); |
||||
|
||||
this.updateInterval = new UITextField(4); |
||||
this.shouldEvolve = new UICheckBox(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Auto_Evolved_Strategy"), false); |
||||
this.shouldEvolve.setEnabled(false); |
||||
this.updateIntervalCheckTips = new UILabel(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Error_Interval_Format")); |
||||
this.updateIntervalCheckTips.setForeground(Color.RED); |
||||
this.updateIntervalCheckTips.setVisible(false); |
||||
|
||||
this.selectBySchema = new UIRadioButton(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Cron")); |
||||
this.schemaTime = new UITextField(10); |
||||
this.schemaTimeCheckTips = new UILabel(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Error_Time_Format")); |
||||
this.schemaTimeCheckTips.setVisible(false); |
||||
this.schemaTimeCheckTips.setForeground(Color.RED); |
||||
|
||||
|
||||
this.selectAutoUpdate.addActionListener(new AbstractAction() { |
||||
public void actionPerformed(ActionEvent e) { |
||||
ESDStrategyConfigPane.this.selectBySchema.setSelected(!ESDStrategyConfigPane.this.selectAutoUpdate.isSelected()); |
||||
ESDStrategyConfigPane.this.schemaTime.setEnabled(false); |
||||
ESDStrategyConfigPane.this.updateInterval.setEnabled(true); |
||||
ESDStrategyConfigPane.this.shouldEvolve.setEnabled(true); |
||||
} |
||||
}); |
||||
|
||||
this.selectBySchema.addActionListener(new AbstractAction() { |
||||
public void actionPerformed(ActionEvent e) { |
||||
ESDStrategyConfigPane.this.selectAutoUpdate.setSelected(!ESDStrategyConfigPane.this.selectBySchema.isSelected()); |
||||
ESDStrategyConfigPane.this.schemaTime.setEnabled(true); |
||||
ESDStrategyConfigPane.this.updateInterval.setEnabled(false); |
||||
ESDStrategyConfigPane.this.shouldEvolve.setEnabled(false); |
||||
} |
||||
}); |
||||
|
||||
JPanel pane = FRGUIPaneFactory.createVerticalTitledBorderPane(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Cache_Update_Strategy")); |
||||
add(pane, BorderLayout.NORTH); |
||||
|
||||
JPanel row1 = GUICoreUtils.createFlowPane(new Component[]{ |
||||
this.selectAutoUpdate, |
||||
this.updateInterval, |
||||
new UILabel(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Minute_Update_Cache")), |
||||
this.shouldEvolve, |
||||
this.updateIntervalCheckTips |
||||
}, 0, 5); |
||||
pane.add(row1); |
||||
|
||||
ActionLabel actionLabel = new ActionLabel(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Cron_Help")); |
||||
actionLabel.addActionListener(new ActionListener() { |
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
try { |
||||
Desktop.getDesktop().browse(new URI(CRON_HELP_URL)); |
||||
} catch (Exception exp) { |
||||
FineLoggerFactory.getLogger().error(exp.getMessage(), e); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
JPanel row2 = GUICoreUtils.createFlowPane(new Component[]{ |
||||
this.selectBySchema, |
||||
this.schemaTime, |
||||
actionLabel, |
||||
this.schemaTimeCheckTips |
||||
}, 0, 5); |
||||
pane.add(row2); |
||||
} |
||||
|
||||
|
||||
public void populateBean(StrategyConfig ob) { |
||||
|
||||
if (ob == null && !global) { |
||||
ob = StrategyConfigHelper.createStrategyConfig(true, false, true); |
||||
} |
||||
this.strategyConfig = ob; |
||||
|
||||
this.updateInterval.setText(ob.getUpdateInterval() <= 0 ? "0" : String.valueOf(ob.getUpdateInterval() / (double) CacheConstants.MILLIS_OF_MINUTE)); |
||||
this.schemaTime.setText(StringUtils.join(",", ob.getUpdateSchema().toArray(new String[0]))); |
||||
this.shouldEvolve.setSelected(ob.shouldEvolve()); |
||||
this.selectBySchema.setSelected(ob.isScheduleBySchema()); |
||||
this.selectAutoUpdate.setSelected(!ob.isScheduleBySchema()); |
||||
|
||||
if (global) { |
||||
//使用全局配置,禁用面板编辑
|
||||
disablePane(); |
||||
} else { |
||||
setSchemaEnable(!this.selectAutoUpdate.isSelected()); |
||||
} |
||||
} |
||||
|
||||
|
||||
private void disablePane() { |
||||
this.selectAutoUpdate.setEnabled(false); |
||||
this.updateInterval.setEnabled(false); |
||||
this.shouldEvolve.setEnabled(false); |
||||
|
||||
this.selectBySchema.setEnabled(false); |
||||
this.schemaTime.setEnabled(false); |
||||
} |
||||
|
||||
private void setSchemaEnable(boolean enable) { |
||||
this.updateInterval.setEnabled(!enable); |
||||
this.shouldEvolve.setEnabled(!enable); |
||||
|
||||
this.schemaTime.setEnabled(enable); |
||||
} |
||||
|
||||
|
||||
public StrategyConfig updateBean() { |
||||
StrategyConfig config = null; |
||||
if (!this.global) { |
||||
try { |
||||
//这里是new的config
|
||||
config = this.strategyConfig.clone(); |
||||
|
||||
if (this.selectBySchema.isSelected()) { |
||||
List<String> schemaTimes = new ArrayList<>(); |
||||
String text = this.schemaTime.getText(); |
||||
|
||||
if (ESDUtils.checkUpdateTimeSchema(text)) { |
||||
if (ESDUtils.isCronExpression(text)) { |
||||
schemaTimes.add(text); |
||||
} else { |
||||
Collections.addAll(schemaTimes, text.split(",")); |
||||
} |
||||
} else { |
||||
this.schemaTimeCheckTips.setVisible(true); |
||||
throw new IllegalArgumentException("[ESD]Update schema time format error."); |
||||
} |
||||
config.setScheduleBySchema(true); |
||||
config.setUpdateSchema(schemaTimes); |
||||
} else { |
||||
String interval = this.updateInterval.getText(); |
||||
if (checkUpdateInterval(interval)) { |
||||
long intervalMillis = StringUtils.isEmpty(interval) ? 0 : (long) (Double.parseDouble(interval) * CacheConstants.MILLIS_OF_MINUTE); |
||||
config.setUpdateInterval(intervalMillis); |
||||
} else { |
||||
this.updateIntervalCheckTips.setVisible(true); |
||||
throw new IllegalArgumentException("[ESD]Error update interval format."); |
||||
} |
||||
|
||||
config.setShouldEvolve(this.shouldEvolve.isSelected()); |
||||
config.setScheduleBySchema(false); |
||||
} |
||||
} catch (CloneNotSupportedException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
} |
||||
|
||||
return config; |
||||
} |
||||
|
||||
|
||||
private boolean checkUpdateInterval(String intervalValue) { |
||||
try { |
||||
return !StringUtils.isEmpty(intervalValue) && !(Double.parseDouble(intervalValue) <= 0); |
||||
} catch (NumberFormatException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
|
||||
protected String title4PopupWindow() { |
||||
return InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Cache_Strategy_Config_Title"); |
||||
} |
||||
} |
@ -0,0 +1,147 @@
|
||||
package com.fr.design.data.datapane.connect; |
||||
|
||||
import com.fr.data.impl.JDBCDatabaseConnection; |
||||
import com.fr.data.pool.DBCPConnectionPoolAttr; |
||||
import com.fr.design.dialog.BasicPane; |
||||
import com.fr.design.editor.editor.IntegerEditor; |
||||
import com.fr.design.gui.icombobox.UIComboBox; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.gui.itextfield.UITextField; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
import com.fr.design.layout.TableLayout; |
||||
import com.fr.design.layout.TableLayoutHelper; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import javax.swing.JPanel; |
||||
import javax.swing.SwingConstants; |
||||
import java.awt.Color; |
||||
import java.awt.Component; |
||||
import java.awt.Dimension; |
||||
import java.awt.event.FocusEvent; |
||||
import java.awt.event.FocusListener; |
||||
|
||||
/** |
||||
* @author xiqiu |
||||
* @date 2021/11/22 |
||||
* @description |
||||
*/ |
||||
public class AdvancePane extends BasicPane { |
||||
private IntegerEditor DBCP_MAX_ACTIVE = new IntegerEditor(); |
||||
private UIComboBox DBCP_TESTONBORROW = new UIComboBox(new String[]{Toolkit.i18nText("Fine-Design_Basic_No"), Toolkit.i18nText("Fine-Design_Basic_Yes")}); |
||||
private IntegerEditor DBCP_MAX_WAIT = new IntegerEditor(); |
||||
private SpecialUITextField DBCP_VALIDATION_QUERY = new SpecialUITextField(); |
||||
|
||||
|
||||
public AdvancePane() { |
||||
|
||||
DBCP_VALIDATION_QUERY.addFocusListener(new JTextFieldHintListener(DBCP_VALIDATION_QUERY)); |
||||
; |
||||
double p = TableLayout.PREFERRED; |
||||
DBCP_VALIDATION_QUERY.setColumns(15); |
||||
double[] rowSizeDbcp = {p, p, p, p}; |
||||
double[] columnDbcp = {p, p}; |
||||
Component[][] comps = { |
||||
{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Max_Active") + ":", SwingConstants.RIGHT), DBCP_MAX_ACTIVE}, |
||||
{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Validation_Query") + ":", SwingConstants.RIGHT), DBCP_VALIDATION_QUERY}, |
||||
{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Test_On_Borrow") + ":", SwingConstants.RIGHT), DBCP_TESTONBORROW}, |
||||
{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Connection_Pool_Max_Wait_Time") + ":", SwingConstants.RIGHT), DBCP_MAX_WAIT} |
||||
}; |
||||
|
||||
JPanel contextPane = TableLayoutHelper.createGapTableLayoutPane(comps, rowSizeDbcp, columnDbcp, 11, 11); |
||||
this.add(contextPane); |
||||
this.setPreferredSize(new Dimension(630, 120)); |
||||
this.setLayout(FRGUIPaneFactory.createLeftZeroVgapNormalHgapLayout()); |
||||
} |
||||
|
||||
|
||||
public void populate(JDBCDatabaseConnection jdbcDatabase) { |
||||
DBCPConnectionPoolAttr dbcpAttr = jdbcDatabase.getDbcpAttr(); |
||||
if (dbcpAttr == null) { |
||||
dbcpAttr = new DBCPConnectionPoolAttr(); |
||||
jdbcDatabase.setDbcpAttr(dbcpAttr); |
||||
} |
||||
this.DBCP_MAX_ACTIVE.setValue(dbcpAttr.getMaxActive()); |
||||
this.DBCP_MAX_WAIT.setValue(dbcpAttr.getMaxWait()); |
||||
this.DBCP_VALIDATION_QUERY.setText(dbcpAttr.getValidationQuery()); |
||||
this.DBCP_TESTONBORROW.setSelectedIndex(dbcpAttr.isTestOnBorrow() ? 1 : 0); |
||||
|
||||
} |
||||
|
||||
public void update(JDBCDatabaseConnection jdbcDatabase) { |
||||
DBCPConnectionPoolAttr dbcpAttr = jdbcDatabase.getDbcpAttr(); |
||||
if (dbcpAttr == null) { |
||||
dbcpAttr = new DBCPConnectionPoolAttr(); |
||||
jdbcDatabase.setDbcpAttr(dbcpAttr); |
||||
} |
||||
dbcpAttr.setMaxActive(this.DBCP_MAX_ACTIVE.getValue().intValue()); |
||||
dbcpAttr.setMaxWait(this.DBCP_MAX_WAIT.getValue().intValue()); |
||||
dbcpAttr.setValidationQuery(this.DBCP_VALIDATION_QUERY.getText()); |
||||
dbcpAttr.setTestOnBorrow(this.DBCP_TESTONBORROW.getSelectedIndex() == 0 ? false : true); |
||||
} |
||||
|
||||
@Override |
||||
protected String title4PopupWindow() { |
||||
return Toolkit.i18nText("Fine-Design_Basic_Advanced_Setup"); |
||||
} |
||||
|
||||
|
||||
private class JTextFieldHintListener implements FocusListener { |
||||
private SpecialUITextField textField; |
||||
|
||||
public JTextFieldHintListener(SpecialUITextField jTextField) { |
||||
this.textField = jTextField; |
||||
} |
||||
|
||||
@Override |
||||
public void focusGained(FocusEvent e) { |
||||
//获取焦点时,清空提示内容
|
||||
String temp = textField.getText(); |
||||
textField.setForeground(Color.BLACK); |
||||
textField.setTextOrigin(temp); |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void focusLost(FocusEvent e) { |
||||
//失去焦点时,没有输入内容,显示提示内容
|
||||
String temp = textField.getTextOrigin(); |
||||
textField.setText(temp); |
||||
} |
||||
} |
||||
|
||||
private class SpecialUITextField extends UITextField { |
||||
|
||||
@Override |
||||
public String getText() { |
||||
String text = super.getText(); |
||||
if (isUseless(text)) { |
||||
return StringUtils.EMPTY; |
||||
} |
||||
return text; |
||||
} |
||||
|
||||
@Override |
||||
public void setText(String text) { |
||||
if (isUseless(text)) { |
||||
this.setForeground(Color.GRAY); |
||||
super.setText(Toolkit.i18nText("Fine-Design_Dbcp_Default_Query")); |
||||
} else { |
||||
this.setForeground(Color.BLACK); |
||||
super.setText(text); |
||||
} |
||||
} |
||||
|
||||
public String getTextOrigin() { |
||||
return super.getText(); |
||||
} |
||||
|
||||
public void setTextOrigin(String text) { |
||||
super.setText(text); |
||||
} |
||||
|
||||
private boolean isUseless(String text) { |
||||
return text == null || text.isEmpty() || Toolkit.i18nText("Fine-Design_Dbcp_Default_Query").equals(text); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,48 @@
|
||||
package com.fr.design.data.datapane.connect; |
||||
|
||||
import com.fr.design.dialog.BasicDialog; |
||||
import com.fr.design.dialog.DialogActionAdapter; |
||||
import com.fr.design.editlock.EditLockUtils; |
||||
import com.fr.design.mainframe.DesignerContext; |
||||
import com.fr.file.ConnectionConfig; |
||||
import com.fr.report.LockItem; |
||||
|
||||
/** |
||||
* @author hades |
||||
* @version 11.0 |
||||
* Created by hades on 2021/9/8 |
||||
*/ |
||||
public class ConnectionListDialogActionAdapter extends DialogActionAdapter { |
||||
|
||||
private final ConnectionManagerPane connectionManagerPane; |
||||
private final BasicDialog connectionListDialog; |
||||
private final ConnectionConfig connectionConfig; |
||||
|
||||
public ConnectionListDialogActionAdapter(ConnectionManagerPane connectionManagerPane, |
||||
BasicDialog connectionListDialog, |
||||
ConnectionConfig connectionConfig) { |
||||
this.connectionManagerPane = connectionManagerPane; |
||||
this.connectionListDialog = connectionListDialog; |
||||
this.connectionConfig = connectionConfig; |
||||
} |
||||
|
||||
@Override |
||||
public void doOk() { |
||||
if (!connectionManagerPane.isNamePermitted()) { |
||||
connectionListDialog.setDoOKSucceed(false); |
||||
return; |
||||
} |
||||
connectionManagerPane.update(connectionConfig); |
||||
DesignerContext.getDesignerBean("databasename").refreshBeanElement(); |
||||
// 关闭定义数据连接页面,为其解锁
|
||||
EditLockUtils.unlock(LockItem.CONNECTION); |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void doCancel() { |
||||
// 关闭定义数据连接页面,为其解锁
|
||||
super.doCancel(); |
||||
EditLockUtils.unlock(LockItem.CONNECTION); |
||||
} |
||||
} |
@ -0,0 +1,37 @@
|
||||
package com.fr.design.data.tabledata.strategy; |
||||
|
||||
import com.fr.esd.core.strategy.config.StrategyConfig; |
||||
import com.fr.esd.query.StrategicTableData; |
||||
|
||||
/** |
||||
* @author rinoux |
||||
* @version 10.0 |
||||
* Created by rinoux on 2021/3/19 |
||||
*/ |
||||
public abstract class StrategyConfigHandler<T extends StrategicTableData> { |
||||
|
||||
private final T tableData; |
||||
|
||||
public StrategyConfigHandler(T tableData) { |
||||
this.tableData = tableData; |
||||
} |
||||
|
||||
protected T getTableData() { |
||||
return tableData; |
||||
} |
||||
|
||||
/** |
||||
* 查找配置 |
||||
* |
||||
* @return 缓存配置 |
||||
*/ |
||||
public abstract StrategyConfig find(); |
||||
|
||||
|
||||
/** |
||||
* 保存配置 |
||||
* |
||||
* @param config 缓存配置 |
||||
*/ |
||||
public abstract void save(T saved, StrategyConfig config); |
||||
} |
@ -0,0 +1,33 @@
|
||||
package com.fr.design.data.tabledata.tabledatapane.db; |
||||
|
||||
import com.fr.design.i18n.Toolkit; |
||||
|
||||
public enum StrategyConfigFrom { |
||||
GLOBAL(0, Toolkit.i18nText("Fine-Design_ESD_Use_Global_Settings")), |
||||
|
||||
INDIVIDUAL(1, Toolkit.i18nText("Fine-Design_ESD_Use_Individual_Settings")); |
||||
|
||||
int index; |
||||
|
||||
String displayText; |
||||
|
||||
StrategyConfigFrom(int index, String displayText) { |
||||
this.index = index; |
||||
this.displayText = displayText; |
||||
} |
||||
|
||||
|
||||
public int getIndex() { |
||||
return this.index; |
||||
} |
||||
|
||||
|
||||
public String getDisplayText() { |
||||
return this.displayText; |
||||
} |
||||
|
||||
|
||||
public String toString() { |
||||
return getDisplayText(); |
||||
} |
||||
} |
@ -0,0 +1,7 @@
|
||||
package com.fr.design.event; |
||||
|
||||
import java.awt.*; |
||||
|
||||
public interface ComponentChangeListener { |
||||
void initListener(Container changedComponent); |
||||
} |
@ -0,0 +1,6 @@
|
||||
package com.fr.design.event; |
||||
|
||||
|
||||
public interface ComponentChangeObserver { |
||||
void registerChangeListener(ComponentChangeListener uiChangeableListener); |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,48 @@
|
||||
package com.fr.design.formula; |
||||
|
||||
import com.fr.design.formula.exception.FormulaExceptionTipsProcessor; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.parser.FRParser; |
||||
import com.fr.script.checker.FunctionCheckerDispatcher; |
||||
import com.fr.script.checker.result.FormulaCheckResult; |
||||
import com.fr.script.checker.result.FormulaCoordinates; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.stable.script.Expression; |
||||
import com.fr.stable.script.Node; |
||||
import com.fr.third.antlr.TokenStreamRecognitionException; |
||||
|
||||
import java.io.StringReader; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/9/28 |
||||
*/ |
||||
public class FormulaChecker { |
||||
public static final String VALID_FORMULA = Toolkit.i18nText("Fine-Design_Basic_FormulaD_Valid_Formula"); |
||||
public static final String INVALID_FORMULA = Toolkit.i18nText("Fine-Design_Basic_FormulaD_Invalid_Formula"); |
||||
private static FormulaExceptionTipsProcessor processor = FormulaExceptionTipsProcessor.getProcessor(); |
||||
|
||||
public static FormulaCheckResult check(String formulaText) { |
||||
if (StringUtils.isEmpty(formulaText) || formulaText.equals(Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Tips"))) { |
||||
return new FormulaCheckResult(true, VALID_FORMULA, FormulaCoordinates.INVALID, true); |
||||
} |
||||
//过滤一些空格等符号
|
||||
StringReader in = new StringReader(formulaText); |
||||
//此lexer为公式校验定制
|
||||
FRFormulaLexer lexer = new FRFormulaLexer(in); |
||||
FRParser parser = new FRParser(lexer); |
||||
|
||||
try { |
||||
Expression expression = parser.parse(); |
||||
Node node = expression.getConditionalExpression(); |
||||
boolean valid = FunctionCheckerDispatcher.getInstance().getFunctionChecker(node).checkFunction(formulaText, node); |
||||
return new FormulaCheckResult(valid, valid ? Toolkit.i18nText("Fine-Design_Basic_FormulaD_Valid_Formula") : |
||||
Toolkit.i18nText("Fine-Design_Basic_FormulaD_Invalid_Formula"), FormulaCoordinates.INVALID, true); |
||||
} catch (Exception e) { |
||||
if (e instanceof TokenStreamRecognitionException) { |
||||
return processor.getExceptionTips(((TokenStreamRecognitionException) e).recog); |
||||
} |
||||
return processor.getExceptionTips(e); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,11 @@
|
||||
package com.fr.design.formula; |
||||
|
||||
public class FormulaCheckerException extends Exception { |
||||
public FormulaCheckerException() { |
||||
|
||||
} |
||||
|
||||
public FormulaCheckerException(String message) { |
||||
super(message); |
||||
} |
||||
} |
@ -0,0 +1,54 @@
|
||||
package com.fr.design.formula; |
||||
|
||||
import com.fr.parser.BinaryExpression; |
||||
import com.fr.parser.DatasetFunctionCall; |
||||
import com.fr.parser.FunctionCall; |
||||
import com.fr.stable.script.Node; |
||||
|
||||
import java.util.Arrays; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/8/30 |
||||
*/ |
||||
public class UnsupportedFormulaScanner { |
||||
public final static String[] UNSUPPORTED_FORMULAS = new String[]{"PROPORTION", "TOIMAGE", |
||||
"WEBIMAGE", "SORT", "CROSSLAYERTOTAL", "CIRCULAR", "LAYERTOTAL", "MOM", "HIERARCHY", |
||||
"FILENAME", "FILESIZE", "FILETYPE", "TREELAYER", "GETUSERDEPARTMENTS", "GETUSERJOBTITLES"}; |
||||
|
||||
private String unSupportFormula = ""; |
||||
|
||||
public boolean travelFormula(Node node) { |
||||
if (node instanceof FunctionCall) { |
||||
if (isUnsupportedFomula(((FunctionCall) node).getName())) { |
||||
unSupportFormula = ((FunctionCall) node).getName(); |
||||
return false; |
||||
} else { |
||||
for (Node argument : ((FunctionCall) node).getArguments()) { |
||||
if (!travelFormula(argument)) { |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
} else if (node instanceof BinaryExpression) { |
||||
for (Node array : ((BinaryExpression) node).getNodes()) { |
||||
if (!travelFormula(array)) { |
||||
return false; |
||||
} |
||||
} |
||||
} else if (node instanceof DatasetFunctionCall) { |
||||
DatasetFunctionCall datasetFunctionCall = (DatasetFunctionCall) node; |
||||
unSupportFormula = datasetFunctionCall.getSourceName() + "." + datasetFunctionCall.getFnName() + "()"; |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
public String getUnSupportFormula() { |
||||
return unSupportFormula; |
||||
} |
||||
|
||||
private static boolean isUnsupportedFomula(String formula) { |
||||
return Arrays.asList(UNSUPPORTED_FORMULAS).contains(formula.toUpperCase()); |
||||
} |
||||
} |
@ -0,0 +1,48 @@
|
||||
package com.fr.design.formula.exception; |
||||
|
||||
import com.fr.design.formula.FormulaChecker; |
||||
import com.fr.design.formula.exception.function.FormulaCheckWrongFunction; |
||||
import com.fr.design.formula.exception.function.MismatchedCharFunction; |
||||
import com.fr.design.formula.exception.function.MismatchedTokenFunction; |
||||
import com.fr.design.formula.exception.function.NoViableAltForCharFunction; |
||||
import com.fr.design.formula.exception.function.NoViableAltFunction; |
||||
import com.fr.script.checker.exception.FunctionCheckWrongException; |
||||
import com.fr.script.checker.result.FormulaCheckResult; |
||||
import com.fr.script.checker.result.FormulaCoordinates; |
||||
import com.fr.third.antlr.MismatchedCharException; |
||||
import com.fr.third.antlr.MismatchedTokenException; |
||||
import com.fr.third.antlr.NoViableAltException; |
||||
import com.fr.third.antlr.NoViableAltForCharException; |
||||
|
||||
import java.util.Map; |
||||
import java.util.concurrent.ConcurrentHashMap; |
||||
import java.util.function.Function; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/10/26 |
||||
*/ |
||||
public class FormulaExceptionTipsProcessor { |
||||
private static final Map<Class, Function<Exception, FormulaCheckResult>> EXCEPTION_TIPS = new ConcurrentHashMap<>(); |
||||
|
||||
private static final FormulaExceptionTipsProcessor PROCESSOR = new FormulaExceptionTipsProcessor(); |
||||
|
||||
static { |
||||
EXCEPTION_TIPS.put(FunctionCheckWrongException.class, FormulaCheckWrongFunction.getFunction()); |
||||
EXCEPTION_TIPS.put(MismatchedCharException.class, MismatchedCharFunction.getFunction()); |
||||
EXCEPTION_TIPS.put(MismatchedTokenException.class, MismatchedTokenFunction.getFunction()); |
||||
EXCEPTION_TIPS.put(NoViableAltException.class, NoViableAltFunction.getFunction()); |
||||
EXCEPTION_TIPS.put(NoViableAltForCharException.class, NoViableAltForCharFunction.getFunction()); |
||||
|
||||
} |
||||
|
||||
public FormulaCheckResult getExceptionTips(Exception e) { |
||||
return EXCEPTION_TIPS.getOrDefault(e.getClass(), |
||||
e1 -> new FormulaCheckResult(false, FormulaChecker.INVALID_FORMULA, FormulaCoordinates.INVALID, false)) |
||||
.apply(e); |
||||
} |
||||
|
||||
public static FormulaExceptionTipsProcessor getProcessor() { |
||||
return PROCESSOR; |
||||
} |
||||
} |
@ -0,0 +1,14 @@
|
||||
package com.fr.design.formula.exception.function; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/10/28 |
||||
*/ |
||||
public class FormulaCheckConstants { |
||||
public static final String COLON = ":"; |
||||
public static final String LEFT = "("; |
||||
public static final String COMMON = ","; |
||||
public static final String RIGHT = ")"; |
||||
public static final String BLANK = " "; |
||||
public static final String SINGLE_QUOTES = "'"; |
||||
} |
@ -0,0 +1,80 @@
|
||||
package com.fr.design.formula.exception.function; |
||||
|
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.script.checker.exception.FunctionCheckWrongException; |
||||
import com.fr.script.checker.result.FormulaCheckResult; |
||||
import com.fr.script.checker.result.FormulaCoordinates; |
||||
import com.fr.script.rules.FunctionParameterType; |
||||
import com.fr.script.rules.FunctionRule; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import java.util.List; |
||||
import java.util.function.Function; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/10/26 |
||||
*/ |
||||
public class FormulaCheckWrongFunction implements Function<Exception, FormulaCheckResult> { |
||||
private final static FormulaCheckWrongFunction FUNCTION = new FormulaCheckWrongFunction(); |
||||
|
||||
@Override |
||||
public FormulaCheckResult apply(Exception e) { |
||||
if (e instanceof FunctionCheckWrongException) { |
||||
FunctionCheckWrongException ce = (FunctionCheckWrongException) e; |
||||
List<FunctionRule> rules = ce.getRules(); |
||||
String functionName = ce.getFunctionName(); |
||||
StringBuilder errorMsg = new StringBuilder(functionName + Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Error_Tips") + FormulaCheckConstants.COLON); |
||||
for (int i = 0; i < rules.size(); i++) { |
||||
errorMsg.append(FormulaCheckConstants.LEFT); |
||||
if (rules.get(i).getParameterList().isEmpty()) { |
||||
errorMsg.append(Toolkit.i18nText("Fine-Design_Basic_Formula_No_Param")); |
||||
} |
||||
for (FunctionParameterType functionParameterType : rules.get(i).getParameterList()) { |
||||
errorMsg.append(getTypeString(functionParameterType)).append(FormulaCheckConstants.COMMON); |
||||
} |
||||
if (FormulaCheckConstants.COMMON.equals(errorMsg.charAt(errorMsg.length() - 1) + StringUtils.EMPTY)) { |
||||
errorMsg.deleteCharAt(errorMsg.length() - 1); |
||||
} |
||||
errorMsg.append(FormulaCheckConstants.RIGHT); |
||||
if (i != rules.size() - 1) { |
||||
errorMsg.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Or")); |
||||
} |
||||
} |
||||
return new FormulaCheckResult(false, errorMsg.toString(), new FormulaCoordinates(1, indexPosition(ce.getFormulaText(), ce.getNode().toString())), true); |
||||
} |
||||
return new FormulaCheckResult(false, StringUtils.EMPTY, new FormulaCoordinates(-1, -1), true); |
||||
} |
||||
|
||||
private static String getTypeString(FunctionParameterType type) { |
||||
switch (type) { |
||||
case NUMBER: |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Number"); |
||||
case STRING: |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_String"); |
||||
case ANY: |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Any"); |
||||
case DATE: |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Date"); |
||||
case BOOLEAN: |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Boolean"); |
||||
case ARRAY: |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Array"); |
||||
} |
||||
return StringUtils.EMPTY; |
||||
} |
||||
|
||||
public static Function<Exception, FormulaCheckResult> getFunction() { |
||||
return FUNCTION; |
||||
} |
||||
|
||||
private int indexPosition(String formulaText, String invalidFormula) { |
||||
//处理一下自己FunctionCall自己拼的逗号逻辑
|
||||
if (invalidFormula.contains(",")) { |
||||
invalidFormula = invalidFormula.substring(0, invalidFormula.indexOf(",")); |
||||
} |
||||
int index = formulaText.indexOf(invalidFormula); |
||||
return index; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,95 @@
|
||||
package com.fr.design.formula.exception.function; |
||||
|
||||
import com.fr.design.formula.FormulaChecker; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.script.checker.result.FormulaCheckResult; |
||||
import com.fr.script.checker.result.FormulaCoordinates; |
||||
import com.fr.third.antlr.MismatchedCharException; |
||||
|
||||
import java.util.function.Function; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/10/28 |
||||
*/ |
||||
public class MismatchedCharFunction implements Function<Exception, FormulaCheckResult> { |
||||
private final static MismatchedCharFunction FUNCTION = new MismatchedCharFunction(); |
||||
|
||||
@Override |
||||
public FormulaCheckResult apply(Exception e) { |
||||
if (e instanceof MismatchedCharException) { |
||||
MismatchedCharException charException = (MismatchedCharException) e; |
||||
FormulaCoordinates formulaCoordinates = new FormulaCoordinates(charException.line, charException.column - 1); |
||||
return new FormulaCheckResult(false, getMessage(charException), formulaCoordinates, false); |
||||
} |
||||
return new FormulaCheckResult(false, FormulaChecker.INVALID_FORMULA, FormulaCoordinates.INVALID, false); |
||||
} |
||||
|
||||
public static Function<Exception, FormulaCheckResult> getFunction() { |
||||
return FUNCTION; |
||||
} |
||||
|
||||
private String getMessage(MismatchedCharException charException) { |
||||
StringBuffer sb = new StringBuffer(); |
||||
switch (charException.mismatchType) { |
||||
case 1: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": "); |
||||
appendCharName(sb, charException.expecting); |
||||
break; |
||||
case 2: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting_Anything") + ": ") |
||||
.append(FormulaCheckConstants.BLANK) |
||||
.append(FormulaCheckConstants.SINGLE_QUOTES); |
||||
appendCharName(sb, charException.expecting); |
||||
sb.append("';").append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_GotItAnyway")); |
||||
break; |
||||
case 3: |
||||
case 4: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ").append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Token")); |
||||
if (charException.mismatchType == 4) { |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Not")); |
||||
} |
||||
|
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_In_Range")).append(": "); |
||||
appendCharName(sb, charException.expecting); |
||||
sb.append(".."); |
||||
appendCharName(sb, charException.upper); |
||||
break; |
||||
case 5: |
||||
case 6: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ") |
||||
.append(charException.mismatchType == 6 ? Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Not") : FormulaCheckConstants.BLANK) |
||||
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ONE_OF")).append(" ("); |
||||
int[] elems = charException.set.toArray(); |
||||
|
||||
for (int i = 0; i < elems.length; ++i) { |
||||
appendCharName(sb, elems[i]); |
||||
} |
||||
break; |
||||
default: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Mismatched_Char")); |
||||
} |
||||
|
||||
return sb.toString(); |
||||
} |
||||
|
||||
private void appendCharName(StringBuffer sb, int c) { |
||||
switch (c) { |
||||
case 9: |
||||
sb.append("'\\t'"); |
||||
break; |
||||
case 10: |
||||
sb.append("'\\n'"); |
||||
break; |
||||
case 13: |
||||
sb.append("'\\r'"); |
||||
break; |
||||
case 65535: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Mismatched_EOF")); |
||||
break; |
||||
default: |
||||
sb.append((char) c); |
||||
} |
||||
|
||||
} |
||||
} |
@ -0,0 +1,110 @@
|
||||
package com.fr.design.formula.exception.function; |
||||
|
||||
import com.fr.design.formula.FormulaChecker; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.script.checker.result.FormulaCheckResult; |
||||
import com.fr.script.checker.result.FormulaCoordinates; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.third.antlr.MismatchedTokenException; |
||||
|
||||
import java.lang.reflect.Field; |
||||
import java.util.function.Function; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/10/28 |
||||
*/ |
||||
public class MismatchedTokenFunction implements Function<Exception, FormulaCheckResult> { |
||||
private final static MismatchedTokenFunction FUNCTION = new MismatchedTokenFunction(); |
||||
public static final String NULL_STRING = "null"; |
||||
|
||||
@Override |
||||
public FormulaCheckResult apply(Exception e) { |
||||
if (e instanceof MismatchedTokenException) { |
||||
MismatchedTokenException charException = (MismatchedTokenException) e; |
||||
FormulaCoordinates formulaCoordinates = new FormulaCoordinates(charException.line, charException.column - 1); |
||||
return new FormulaCheckResult(false, getMessage(charException), formulaCoordinates, false); |
||||
} |
||||
return new FormulaCheckResult(false, FormulaChecker.INVALID_FORMULA, FormulaCoordinates.INVALID, false); |
||||
} |
||||
|
||||
public static Function<Exception, FormulaCheckResult> getFunction() { |
||||
return FUNCTION; |
||||
} |
||||
|
||||
public String getMessage(MismatchedTokenException exception) { |
||||
StringBuilder sb = new StringBuilder(); |
||||
Object fieldValue = getFieldValue(exception, "tokenText"); |
||||
String tokenText = fieldValue == null ? NULL_STRING : fieldValue.toString(); |
||||
switch (exception.mismatchType) { |
||||
case 1: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ") |
||||
.append(tokenName(exception.expecting, exception)); |
||||
break; |
||||
case 2: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting_Anything") + ": ") |
||||
.append(tokenName(exception.expecting, exception)) |
||||
.append("; ") |
||||
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_GotItAnyway")); |
||||
break; |
||||
case 3: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ") |
||||
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Token")) |
||||
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_In_Range")) |
||||
.append(": ") |
||||
.append(tokenName(exception.expecting, exception)) |
||||
.append("..") |
||||
.append(tokenName(exception.upper, exception)); |
||||
break; |
||||
case 4: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ") |
||||
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Token")) |
||||
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Not")) |
||||
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_In_Range")) |
||||
.append(": ") |
||||
.append(tokenName(exception.expecting, exception)) |
||||
.append("..") |
||||
.append(tokenName(exception.upper, exception)); |
||||
break; |
||||
case 5: |
||||
case 6: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ") |
||||
.append(exception.mismatchType == 6 ? Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Not") : FormulaCheckConstants.BLANK) |
||||
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ONE_OF")).append("("); |
||||
int[] elms = exception.set.toArray(); |
||||
|
||||
for (int i = 0; i < elms.length; ++i) { |
||||
sb.append(' '); |
||||
sb.append(tokenName(elms[i], exception)); |
||||
} |
||||
|
||||
break; |
||||
default: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Mismatched_Token")); |
||||
} |
||||
|
||||
return sb.toString(); |
||||
} |
||||
|
||||
private String tokenName(int tokenType, MismatchedTokenException exception) { |
||||
if (tokenType == 0) { |
||||
return "<Set of tokens>"; |
||||
} else { |
||||
String[] tokenNames = (String[]) getFieldValue(exception, "tokenNames"); |
||||
return tokenType >= 0 && tokenType < tokenNames.length ? TranslateTokenUtils.translateToken(tokenNames[tokenType]) : "<" + tokenType + ">"; |
||||
} |
||||
} |
||||
|
||||
|
||||
private Object getFieldValue(Object object, String fieldName) { |
||||
try { |
||||
Field field = object.getClass().getDeclaredField(fieldName); |
||||
field.setAccessible(true); |
||||
return field.get(object); |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().warn(e.getMessage(), e); |
||||
return StringUtils.EMPTY; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,44 @@
|
||||
package com.fr.design.formula.exception.function; |
||||
|
||||
import com.fr.design.formula.FormulaChecker; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.script.checker.result.FormulaCheckResult; |
||||
import com.fr.script.checker.result.FormulaCoordinates; |
||||
import com.fr.third.antlr.NoViableAltForCharException; |
||||
|
||||
import java.util.function.Function; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/10/28 |
||||
*/ |
||||
public class NoViableAltForCharFunction implements Function<Exception, FormulaCheckResult> { |
||||
private final static NoViableAltForCharFunction FUNCTION = new NoViableAltForCharFunction(); |
||||
|
||||
@Override |
||||
public FormulaCheckResult apply(Exception e) { |
||||
if (e instanceof NoViableAltForCharException) { |
||||
NoViableAltForCharException charException = (NoViableAltForCharException) e; |
||||
FormulaCoordinates formulaCoordinates = new FormulaCoordinates(charException.line, charException.column - 1); |
||||
return new FormulaCheckResult(false, getMessage(charException), formulaCoordinates, false); |
||||
} |
||||
return new FormulaCheckResult(false, FormulaChecker.INVALID_FORMULA, FormulaCoordinates.INVALID, false); |
||||
} |
||||
|
||||
public static Function<Exception, FormulaCheckResult> getFunction() { |
||||
return FUNCTION; |
||||
} |
||||
|
||||
public String getMessage(NoViableAltForCharException exception) { |
||||
String mesg = Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Unexpected_Char") + ": "; |
||||
if (exception.foundChar >= ' ' && exception.foundChar <= '~') { |
||||
mesg = mesg + '\''; |
||||
mesg = mesg + exception.foundChar; |
||||
mesg = mesg + '\''; |
||||
} else { |
||||
mesg = mesg + exception.foundChar; |
||||
} |
||||
|
||||
return mesg; |
||||
} |
||||
} |
@ -0,0 +1,41 @@
|
||||
package com.fr.design.formula.exception.function; |
||||
|
||||
import com.fr.design.formula.FormulaChecker; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.script.checker.result.FormulaCheckResult; |
||||
import com.fr.script.checker.result.FormulaCoordinates; |
||||
import com.fr.third.antlr.NoViableAltException; |
||||
import com.fr.third.antlr.TreeParser; |
||||
|
||||
import java.util.function.Function; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/10/28 |
||||
*/ |
||||
public class NoViableAltFunction implements Function<Exception, FormulaCheckResult> { |
||||
private final static NoViableAltFunction FUNCTION = new NoViableAltFunction(); |
||||
|
||||
@Override |
||||
public FormulaCheckResult apply(Exception e) { |
||||
if (e instanceof NoViableAltException) { |
||||
NoViableAltException altException = (NoViableAltException) e; |
||||
FormulaCoordinates formulaCoordinates = new FormulaCoordinates(altException.line, altException.column - 1); |
||||
return new FormulaCheckResult(false, getMessage(altException), formulaCoordinates, false); |
||||
} |
||||
return new FormulaCheckResult(false, FormulaChecker.INVALID_FORMULA, FormulaCoordinates.INVALID, false); |
||||
} |
||||
|
||||
public static Function<Exception, FormulaCheckResult> getFunction() { |
||||
return FUNCTION; |
||||
} |
||||
|
||||
public String getMessage(NoViableAltException exception) { |
||||
if (exception.token != null) { |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Unexpected_Token") + ": " + exception.token.getText(); |
||||
} else { |
||||
return exception.node == TreeParser.ASTNULL ? Toolkit.i18nText("Fine-Design_Basic_Formula_Check_End_Of_Subtree") : |
||||
Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Unexpected_AST_Node") + ": " + exception.node.toString(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,96 @@
|
||||
package com.fr.design.formula.exception.function; |
||||
|
||||
import com.fr.design.i18n.Toolkit; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/11/30 |
||||
*/ |
||||
public class TranslateTokenUtils { |
||||
public static String translateToken(String token) { |
||||
switch (token) { |
||||
case ("RPAREN"): |
||||
return ")"; |
||||
case ("LPAREN"): |
||||
return "("; |
||||
case ("COMMA"): |
||||
return ","; |
||||
case ("COLON"): |
||||
return ":"; |
||||
case ("EOF"): |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Mismatched_EOF"); |
||||
case ("DOT"): |
||||
return "."; |
||||
case ("FLOT_NUM"): |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Float_Number"); |
||||
case ("LOR"): |
||||
return "||"; |
||||
case ("LAND"): |
||||
return "&&"; |
||||
case ("EQUAL"): |
||||
return "="; |
||||
case ("EQUAL2"): |
||||
return "="; |
||||
case ("NOT_EQUAL"): |
||||
return "!="; |
||||
case ("NOT_EQUAL2"): |
||||
return "!="; |
||||
case ("GE"): |
||||
return ">="; |
||||
case ("LE"): |
||||
return "<="; |
||||
case ("LT"): |
||||
return "<"; |
||||
case ("PLUS"): |
||||
return "+"; |
||||
case ("MINUS"): |
||||
return "-"; |
||||
case ("STAR"): |
||||
return "*"; |
||||
case ("DIV"): |
||||
return "/"; |
||||
case ("MOD"): |
||||
return "%"; |
||||
case ("POWER"): |
||||
return "^"; |
||||
case ("LNOT"): |
||||
return "!"; |
||||
case ("WAVE"): |
||||
return "~"; |
||||
case ("LBRACK"): |
||||
return "["; |
||||
case ("SEMI"): |
||||
return ";"; |
||||
case ("RBRACK"): |
||||
return "]"; |
||||
case ("LCURLY"): |
||||
return "{"; |
||||
case ("RCURLY"): |
||||
return "}"; |
||||
case ("DCOLON"): |
||||
return ";"; |
||||
case ("INT_NUM"): |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Integer"); |
||||
case ("CR_ADRESS"): |
||||
return "\n"; |
||||
case ("SHARP"): |
||||
return "#"; |
||||
case ("AT"): |
||||
return "@"; |
||||
case ("QUESTION"): |
||||
return "?"; |
||||
case ("BOR"): |
||||
return "||"; |
||||
case ("BAND"): |
||||
return "&&"; |
||||
case ("Char"): |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Character"); |
||||
case ("DIGIT"): |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Digital"); |
||||
case ("XDIGIT"): |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Hexadecimal_Digital"); |
||||
default: |
||||
return token; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,19 @@
|
||||
package com.fr.design.fun; |
||||
|
||||
import com.fr.stable.fun.mark.Mutable; |
||||
|
||||
|
||||
public interface PcFitProvider extends Mutable { |
||||
String XML_TAG = "PcFitProvider"; |
||||
int CURRENT_LEVEL = 1; |
||||
|
||||
//设计器上看到的选项
|
||||
String getContentDisplayValue(); |
||||
|
||||
//返回给前端的值
|
||||
int getContentDisplayKey(); |
||||
|
||||
//设计器上的提示信息
|
||||
String getContentDisplayTip(); |
||||
|
||||
} |
@ -0,0 +1,19 @@
|
||||
package com.fr.design.fun.impl; |
||||
|
||||
import com.fr.design.fun.PcFitProvider; |
||||
import com.fr.stable.fun.mark.API; |
||||
|
||||
|
||||
@API(level = PcFitProvider.CURRENT_LEVEL) |
||||
public abstract class AbstractPcFitProvider implements PcFitProvider { |
||||
|
||||
@Override |
||||
public int currentAPILevel() { |
||||
return CURRENT_LEVEL; |
||||
} |
||||
|
||||
@Override |
||||
public String mark4Provider() { |
||||
return getClass().getName(); |
||||
} |
||||
} |
@ -0,0 +1,28 @@
|
||||
package com.fr.design.fun.impl; |
||||
|
||||
import com.fr.file.FILE; |
||||
import com.fr.intelli.record.Focus; |
||||
import com.fr.intelli.record.Original; |
||||
import com.fr.record.analyzer.EnableMetrics; |
||||
|
||||
/** |
||||
* Created by rinoux on 2016/12/16. |
||||
*/ |
||||
@EnableMetrics |
||||
public class DesignerStartWithEmptyFile extends AbstractDesignerStartOpenFileProcessor { |
||||
|
||||
private static final DesignerStartWithEmptyFile INSTANCE = new DesignerStartWithEmptyFile(); |
||||
|
||||
private DesignerStartWithEmptyFile() { |
||||
} |
||||
|
||||
public static DesignerStartWithEmptyFile getInstance() { |
||||
return INSTANCE; |
||||
} |
||||
|
||||
@Override |
||||
@Focus(id = "com.fr.dzstartemptyfile", text = "Fine_Design_Start_Empty_File", source = Original.REPORT) |
||||
public FILE fileToShow() { |
||||
return null; |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,22 @@
|
||||
package com.fr.design.gui.autocomplete; |
||||
|
||||
import javax.swing.Icon; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/11/5 |
||||
*/ |
||||
public class FormulaCompletion extends BasicCompletion { |
||||
private Icon icon; |
||||
|
||||
public FormulaCompletion(CompletionProvider provider, String replacementText, Icon icon) { |
||||
super(provider, replacementText); |
||||
this.icon = icon; |
||||
} |
||||
|
||||
@Override |
||||
public Icon getIcon() { |
||||
return icon; |
||||
} |
||||
|
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,47 @@
|
||||
package com.fr.design.gui.frpane; |
||||
|
||||
import java.awt.Component; |
||||
import java.awt.Container; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/9/17 |
||||
*/ |
||||
public class AttributeChangeUtils { |
||||
private static AbstractAttrNoScrollPane findNearestAttrNoScrollPaneAncestor(Component c) { |
||||
for(Container p = c.getParent(); p != null; p = p.getParent()) { |
||||
if (p instanceof AbstractAttrNoScrollPane) { |
||||
return (AbstractAttrNoScrollPane) p; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static void changeComposedUI(Component composedComponent, boolean fireMiddleStateChanged, UIChangeAction action) { |
||||
AbstractAttrNoScrollPane attrPane = findNearestAttrNoScrollPaneAncestor(composedComponent); |
||||
boolean oldAutoFire = true; |
||||
|
||||
if (!fireMiddleStateChanged) { |
||||
// 禁止属性面板自动处理属性更新
|
||||
if (attrPane != null) { |
||||
oldAutoFire = attrPane.isAutoFireAttributesChanged(); |
||||
attrPane.setAutoFireAttributesChanged(false); |
||||
} |
||||
} |
||||
|
||||
// 更新UI
|
||||
action.changeComposedUI(); |
||||
|
||||
if (!fireMiddleStateChanged) { |
||||
// 恢复属性面板自动处理属性更新
|
||||
if (attrPane != null) { |
||||
attrPane.setAutoFireAttributesChanged(oldAutoFire); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public interface UIChangeAction { |
||||
void changeComposedUI(); |
||||
} |
||||
} |
@ -0,0 +1,36 @@
|
||||
package com.fr.design.gui.ibutton; |
||||
|
||||
import com.fr.design.gui.ipoppane.PopupHider; |
||||
import com.fr.design.style.color.ColorControlWindow; |
||||
|
||||
import javax.swing.Icon; |
||||
|
||||
|
||||
public class UINoThemeColorButton extends UIColorButton{ |
||||
|
||||
public UINoThemeColorButton(Icon icon) { |
||||
super(icon); |
||||
} |
||||
|
||||
protected ColorControlWindow initColorControlWindow(){ |
||||
return new NoThemeColorControlWindow(this); |
||||
} |
||||
|
||||
private class NoThemeColorControlWindow extends ColorControlWindow{ |
||||
|
||||
|
||||
public NoThemeColorControlWindow(PopupHider popupHider) { |
||||
super(popupHider); |
||||
} |
||||
|
||||
protected boolean supportThemeColor(){ |
||||
return false; |
||||
} |
||||
|
||||
|
||||
@Override |
||||
protected void colorChanged() { |
||||
UINoThemeColorButton.this.setColor(this.getColor()); |
||||
} |
||||
} |
||||
} |
@ -1,77 +0,0 @@
|
||||
package com.fr.design.gui.icombobox; |
||||
|
||||
import com.fr.log.FineLoggerFactory; |
||||
|
||||
import javax.swing.JTree; |
||||
import javax.swing.SwingWorker; |
||||
import javax.swing.tree.TreeCellRenderer; |
||||
import java.util.concurrent.FutureTask; |
||||
|
||||
/** |
||||
* 模糊搜索前需执行完前置任务的TreeComboBox |
||||
* @author Lucian.Chen |
||||
* @version 10.0 |
||||
* Created by Lucian.Chen on 2021/4/14 |
||||
*/ |
||||
public class SearchPreTaskTreeComboBox extends FRTreeComboBox { |
||||
|
||||
/** |
||||
* 模糊搜索前任务 |
||||
*/ |
||||
private FutureTask<Void> preSearchTask; |
||||
|
||||
public SearchPreTaskTreeComboBox(JTree tree, TreeCellRenderer renderer, boolean editable) { |
||||
super(tree, renderer, editable); |
||||
} |
||||
|
||||
public FutureTask<Void> getPreSearchTask() { |
||||
return preSearchTask; |
||||
} |
||||
|
||||
public void setPreSearchTask(FutureTask<Void> preSearchTask) { |
||||
this.preSearchTask = preSearchTask; |
||||
} |
||||
|
||||
protected UIComboBoxEditor createEditor() { |
||||
return new SearchPreTaskComboBoxEditor(this); |
||||
} |
||||
|
||||
private class SearchPreTaskComboBoxEditor extends FrTreeSearchComboBoxEditor { |
||||
|
||||
public SearchPreTaskComboBoxEditor(FRTreeComboBox comboBox) { |
||||
super(comboBox); |
||||
} |
||||
|
||||
protected void changeHandler() { |
||||
if (isSetting()) { |
||||
return; |
||||
} |
||||
setPopupVisible(true); |
||||
new SwingWorker<Void, Void>() { |
||||
@Override |
||||
protected Void doInBackground() { |
||||
FutureTask<Void> task = getPreSearchTask(); |
||||
try { |
||||
// 确保模糊搜索前任务执行完成后,再进行模糊搜索
|
||||
if (task != null) { |
||||
task.get(); |
||||
} |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
if (task != null) { |
||||
// 任务执行后置空,否则会被别的操作重复触发
|
||||
setPreSearchTask(null); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
protected void done() { |
||||
// 模糊搜索
|
||||
search(); |
||||
} |
||||
}.execute(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,217 @@
|
||||
package com.fr.design.gui.icombobox; |
||||
|
||||
import com.fr.data.core.DataCoreUtils; |
||||
import com.fr.data.core.db.TableProcedure; |
||||
import com.fr.data.impl.Connection; |
||||
import com.fr.design.DesignerEnvManager; |
||||
import com.fr.design.data.datapane.ChoosePane; |
||||
import com.fr.design.dialog.FineJOptionPane; |
||||
import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode; |
||||
import com.fr.design.mainframe.DesignerContext; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.ArrayUtils; |
||||
import com.fr.stable.Filter; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import javax.swing.JOptionPane; |
||||
import javax.swing.JTree; |
||||
import javax.swing.SwingWorker; |
||||
import javax.swing.tree.DefaultMutableTreeNode; |
||||
import javax.swing.tree.DefaultTreeModel; |
||||
import javax.swing.tree.TreeCellRenderer; |
||||
import javax.swing.tree.TreeNode; |
||||
import javax.swing.tree.TreePath; |
||||
import java.awt.event.MouseEvent; |
||||
import java.util.Enumeration; |
||||
|
||||
/** |
||||
* 实现模糊搜索表名的FRTreeComboBox |
||||
* FRTreeComboBox:搜索后滚动到首个匹配节点 |
||||
* SearchFRTreeComboBox:显示所有匹配的节点 |
||||
* |
||||
* @author Lucian.Chen |
||||
* @version 10.0 |
||||
* Created by Lucian.Chen on 2021/4/14 |
||||
*/ |
||||
public class TableSearchTreeComboBox extends FRTreeComboBox { |
||||
// 持有父容器,需要实时获取其他组件值
|
||||
private final ChoosePane parent; |
||||
|
||||
public TableSearchTreeComboBox(ChoosePane parent, JTree tree, TreeCellRenderer renderer) { |
||||
super(tree, renderer); |
||||
this.parent = parent; |
||||
setUI(new TableSearchTreeComboBoxUI()); |
||||
} |
||||
|
||||
protected UIComboBoxEditor createEditor() { |
||||
return new TableSearchComboBoxEditor(this); |
||||
} |
||||
|
||||
@Override |
||||
protected String pathToString(TreePath path) { |
||||
Object obj = ((DefaultMutableTreeNode) path.getLastPathComponent()).getUserObject(); |
||||
if (obj instanceof TableProcedure) { |
||||
return ((TableProcedure) obj).getName(); |
||||
} |
||||
return super.pathToString(path); |
||||
} |
||||
|
||||
@Override |
||||
public void setSelectedItemString(String _name) { |
||||
super.setSelectedItemString(_name); |
||||
// 会因为连续两次选中的值一致,导致未触发编辑框联动
|
||||
this.getEditor().setItem(_name); |
||||
} |
||||
|
||||
/** |
||||
* 执行模糊搜索 |
||||
*/ |
||||
private void searchExecute() { |
||||
UIComboBoxEditor searchEditor = (UIComboBoxEditor) this.getEditor(); |
||||
new SwingWorker<Void, Void>() { |
||||
@Override |
||||
protected Void doInBackground() { |
||||
processTableDataNames( |
||||
parent.getDSName(), |
||||
parent.getConnection(), |
||||
parent.getSchema(), |
||||
createFilter((String) searchEditor.getItem())); |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
protected void done() { |
||||
expandTree(); |
||||
// 输入框获取焦点
|
||||
searchEditor.getEditorComponent().requestFocus(); |
||||
} |
||||
}.execute(); |
||||
} |
||||
|
||||
private TableNameFilter createFilter(String text) { |
||||
return StringUtils.isEmpty(text) ? EMPTY_FILTER : new TableNameFilter(text); |
||||
} |
||||
|
||||
/** |
||||
* 查询数据库表,并构建节点目录 |
||||
* |
||||
* @param databaseName 数据库名 |
||||
* @param connection 数据连接 |
||||
* @param schema 模式 |
||||
* @param filter 模糊搜索过滤器 |
||||
*/ |
||||
private void processTableDataNames(String databaseName, Connection connection, String schema, TableNameFilter filter) { |
||||
if (tree == null) { |
||||
return; |
||||
} |
||||
DefaultMutableTreeNode rootTreeNode = (DefaultMutableTreeNode) tree.getModel().getRoot(); |
||||
rootTreeNode.removeAllChildren(); |
||||
|
||||
if (connection == null) { |
||||
return; |
||||
} |
||||
try { |
||||
schema = StringUtils.isEmpty(schema) ? null : schema; |
||||
TableProcedure[] sqlTableArray = DataCoreUtils.getTables(connection, TableProcedure.TABLE, schema, DesignerEnvManager.getEnvManager().isOracleSystemSpace()); |
||||
if (ArrayUtils.isNotEmpty(sqlTableArray)) { |
||||
ExpandMutableTreeNode tableTreeNode = new ExpandMutableTreeNode(databaseName + "-" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_SQL_Table")); |
||||
rootTreeNode.add(tableTreeNode); |
||||
addArrayNode(tableTreeNode, sqlTableArray, filter); |
||||
} |
||||
TableProcedure[] sqlViewArray = DataCoreUtils.getTables(connection, TableProcedure.VIEW, schema, DesignerEnvManager.getEnvManager().isOracleSystemSpace()); |
||||
if (ArrayUtils.isNotEmpty(sqlViewArray)) { |
||||
ExpandMutableTreeNode viewTreeNode = new ExpandMutableTreeNode(databaseName + "-" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_SQL_View")); |
||||
rootTreeNode.add(viewTreeNode); |
||||
addArrayNode(viewTreeNode, sqlViewArray, filter); |
||||
} |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Failed"), |
||||
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Failed"), JOptionPane.ERROR_MESSAGE); |
||||
} |
||||
} |
||||
|
||||
private void addArrayNode(ExpandMutableTreeNode rootNode, TableProcedure[] sqlArray, TableNameFilter filter) { |
||||
if (sqlArray != null) { |
||||
for (TableProcedure procedure : sqlArray) { |
||||
if (filter.accept(procedure)) { |
||||
ExpandMutableTreeNode viewChildTreeNode = new ExpandMutableTreeNode(procedure); |
||||
rootNode.add(viewChildTreeNode); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 展开节点 |
||||
*/ |
||||
private void expandTree() { |
||||
((DefaultTreeModel) tree.getModel()).reload(); |
||||
// daniel 展开所有tree
|
||||
TreeNode root = (TreeNode) tree.getModel().getRoot(); |
||||
TreePath parent = new TreePath(root); |
||||
TreeNode node = (TreeNode) parent.getLastPathComponent(); |
||||
for (Enumeration e = node.children(); e.hasMoreElements(); ) { |
||||
TreeNode n = (TreeNode) e.nextElement(); |
||||
TreePath path = parent.pathByAddingChild(n); |
||||
tree.expandPath(path); |
||||
} |
||||
} |
||||
|
||||
private static final TableNameFilter EMPTY_FILTER = new TableNameFilter() { |
||||
public boolean accept(TableProcedure procedure) { |
||||
return true; |
||||
} |
||||
}; |
||||
|
||||
/** |
||||
* 表名模糊搜索实现 |
||||
*/ |
||||
private static class TableNameFilter implements Filter<TableProcedure> { |
||||
private String searchFilter; |
||||
|
||||
public TableNameFilter() { |
||||
} |
||||
|
||||
public TableNameFilter(String searchFilter) { |
||||
this.searchFilter = searchFilter.toLowerCase().trim(); |
||||
} |
||||
|
||||
// 表名匹配
|
||||
@Override |
||||
public boolean accept(TableProcedure procedure) { |
||||
return procedure.getName().toLowerCase().contains(searchFilter); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 重写FRTreeComboBoxUI,实现点击下拉时触发模糊搜索 |
||||
*/ |
||||
private class TableSearchTreeComboBoxUI extends FRTreeComboBoxUI { |
||||
|
||||
@Override |
||||
public void mouseClicked(MouseEvent e) { |
||||
searchExecute(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 重写输入框编辑器,实现输入框模糊搜索逻辑 |
||||
*/ |
||||
private class TableSearchComboBoxEditor extends FrTreeSearchComboBoxEditor { |
||||
|
||||
public TableSearchComboBoxEditor(FRTreeComboBox comboBox) { |
||||
super(comboBox); |
||||
} |
||||
|
||||
@Override |
||||
protected void changeHandler() { |
||||
if (isSetting()) { |
||||
return; |
||||
} |
||||
setPopupVisible(true); |
||||
this.item = textField.getText(); |
||||
searchExecute(); |
||||
} |
||||
} |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue