@ -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("/url", 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,154 @@ |
|||||||
|
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.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 DesignerStrategyConfigUtils { |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取当前编辑模版的数据集缓存配置属性 |
||||||
|
* |
||||||
|
* @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."); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 当前编辑的模版是否被批量开启 |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static boolean isEditingTemplateRecommended() { |
||||||
|
JTemplate<?, ?> jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
||||||
|
|
||||||
|
if (jTemplate != null) { |
||||||
|
FILE file = jTemplate.getEditingFILE(); |
||||||
|
if (file != null) { |
||||||
|
String path = file.getPath(); |
||||||
|
return StrategyConfigHelper.recommended(path); |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 获取模版数据集配置 |
||||||
|
* |
||||||
|
* @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,225 @@ |
|||||||
|
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 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; |
||||||
|
|
||||||
|
private static final String CRON_HELP_URL = "http://help.fanruan.com/finereport/doc-view-693.html"; |
||||||
|
|
||||||
|
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("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("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,41 @@ |
|||||||
|
package com.fr.design.preview; |
||||||
|
|
||||||
|
import com.fr.design.fun.impl.AbstractPreviewProvider; |
||||||
|
import com.fr.general.web.ParameterConstants; |
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import static com.fr.nx.app.web.v9.PagePlusActor.TYPE; |
||||||
|
|
||||||
|
public class PagePlusPreview extends AbstractPreviewProvider { |
||||||
|
private static final int CODE = 100; |
||||||
|
|
||||||
|
@Override |
||||||
|
public String nameForPopupItem() { |
||||||
|
return InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine-Page-Plus"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String iconPathForPopupItem() { |
||||||
|
return "com/fr/design/images/buttonicon/pages.png"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String iconPathForLarge() { |
||||||
|
return "com/fr/design/images/buttonicon/pageb24.png"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int previewTypeCode() { |
||||||
|
return CODE; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Map<String, Object> parametersForPreview() { |
||||||
|
Map<String, Object> map = new HashMap<String, Object>(); |
||||||
|
map.put(ParameterConstants.OP, TYPE); |
||||||
|
return map; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
package com.fr.design.preview; |
||||||
|
|
||||||
|
import com.fr.base.io.IOFile; |
||||||
|
import com.fr.design.fun.impl.AbstractPreviewProvider; |
||||||
|
|
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by loy on 2017/7/7. |
||||||
|
*/ |
||||||
|
public class WriteEnhancePreview extends AbstractPreviewProvider { |
||||||
|
@Override |
||||||
|
public String nameForPopupItem() { |
||||||
|
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Write_Enhance_Preview"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String iconPathForPopupItem() { |
||||||
|
return "com/fr/design/images/buttonicon/writes.png"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String iconPathForLarge() { |
||||||
|
return "com/fr/design/images/buttonicon/writeb24.png"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int previewTypeCode() { |
||||||
|
return IOFile.WRITE_ENHANCE_PREVIEW_TYPE; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Map<String, Object> parametersForPreview() { |
||||||
|
Map<String, Object> map = new HashMap<String, Object>(); |
||||||
|
map.put("op", "write_plus"); |
||||||
|
return map; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,60 @@ |
|||||||
|
package com.fr.nx.app.designer.cptx.io; |
||||||
|
|
||||||
|
import com.fr.common.annotations.Negative; |
||||||
|
import com.fr.file.FILE; |
||||||
|
import com.fr.nx.app.designer.utils.DesignerCptxFileUtils; |
||||||
|
import com.fr.nx.cptx.io.handle.impl.AbstractCptxIOProvider; |
||||||
|
import com.fr.nx.cptx.pack.util.CompiledReportInputStream; |
||||||
|
import com.fr.nx.cptx.pack.util.CompiledReportOutputStream; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InputStream; |
||||||
|
import java.io.OutputStream; |
||||||
|
|
||||||
|
/** |
||||||
|
* 用于设计器保存编译后的结果并缓存可web预览模版 |
||||||
|
* 没有可观的内存实现,内存实现方式复杂,赶发布,先提供简单的内存实现方式 |
||||||
|
* |
||||||
|
* @author: Maksim |
||||||
|
* @Date: Created in 2020/4/10 |
||||||
|
* @Description: 用于cptx写操作的Provider |
||||||
|
*/ |
||||||
|
@Negative(until = "2020-05-10") |
||||||
|
public class DesignReadWritableProvider extends AbstractCptxIOProvider { |
||||||
|
/** |
||||||
|
* 原文件 |
||||||
|
*/ |
||||||
|
private final FILE file; |
||||||
|
/** |
||||||
|
* 编译文件夹 |
||||||
|
*/ |
||||||
|
private final String compileDir; |
||||||
|
|
||||||
|
private CompiledReportOutputStream outputStream; |
||||||
|
|
||||||
|
public DesignReadWritableProvider(FILE file) { |
||||||
|
this.file = file; |
||||||
|
this.compileDir = DesignerCptxFileUtils.generateCompileDir(file); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public InputStream open() throws Exception { |
||||||
|
if (outputStream == null) { |
||||||
|
throw new IOException("can not read cptx template before compile"); |
||||||
|
} |
||||||
|
return new CompiledReportInputStream(outputStream.toByteArray()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 对于写操作,用到的只有这个方法,以流形式来操作 |
||||||
|
* |
||||||
|
* @return 保存的目标输出流 |
||||||
|
* @throws Exception e |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public OutputStream createTemp() throws Exception { |
||||||
|
outputStream = new CompiledReportOutputStream(file.asOutputStream(), compileDir); |
||||||
|
return outputStream; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,97 @@ |
|||||||
|
package com.fr.nx.app.designer.monitor; |
||||||
|
|
||||||
|
import com.fr.design.mainframe.errorinfo.ErrorInfo; |
||||||
|
import com.fr.intelli.record.MetricRegistry; |
||||||
|
import com.fr.json.JSON; |
||||||
|
import com.fr.json.JSONFactory; |
||||||
|
import com.fr.json.JSONObject; |
||||||
|
import com.fr.message.ErrorMessage; |
||||||
|
import com.fr.nx.app.designer.toolbar.TransformResult; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by loy on 2021/1/18. |
||||||
|
* |
||||||
|
* <p>设计器埋点记录相关 |
||||||
|
*/ |
||||||
|
public class DesignerMetricRecorder { |
||||||
|
|
||||||
|
private static final String ATTR_TEMPLATE_ID = "templateid"; |
||||||
|
private static final String ATTR_USERNAME = "username"; |
||||||
|
private static final String ATTR_UUID = "uuid"; |
||||||
|
private static final String ATTR_ACTIVE_KEY = "activekey"; |
||||||
|
private static final String ATTR_TEST_LOG = "testlog"; |
||||||
|
private static final String ATTR_REPORT_CONTENT = "reportcontent"; |
||||||
|
private static final String ATTR_ERROR_STACK = "errorstack"; |
||||||
|
private static final String IDENTIFICATION = "view_plus"; |
||||||
|
|
||||||
|
private DesignerMetricRecorder() { |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 模板转换失败的埋点 |
||||||
|
*/ |
||||||
|
public static void submitFailedTransform(TransformResult result, String templateID, String name, Exception e) { |
||||||
|
if (isPressureTesting()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
saveAsJSON(result, templateID, name, e); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 记录在设计器的错误信息收集中 |
||||||
|
*/ |
||||||
|
private static void saveToErrorInfo(TransformResult result, String templateID, String name, Exception e, String unsupportMessage) { |
||||||
|
JSONObject jo = JSONFactory.createJSON(JSON.OBJECT); |
||||||
|
jo.put(ATTR_USERNAME, IDENTIFICATION); |
||||||
|
jo.put(ATTR_UUID, IDENTIFICATION); |
||||||
|
jo.put(ATTR_ACTIVE_KEY, IDENTIFICATION); |
||||||
|
jo.put(ATTR_TEMPLATE_ID, templateID); |
||||||
|
jo.put(ATTR_REPORT_CONTENT, name); |
||||||
|
if (result == TransformResult.FAILED) { |
||||||
|
jo.put(ATTR_TEST_LOG, e); |
||||||
|
jo.put(ATTR_ERROR_STACK, e.getMessage()); |
||||||
|
} else { |
||||||
|
jo.put(ATTR_TEST_LOG, unsupportMessage); |
||||||
|
} |
||||||
|
new ErrorInfo().saveFileToCache(jo); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 记录在fine_record_error表中 |
||||||
|
*/ |
||||||
|
private static void saveToErrorMessage(TransformResult result, String templateID, String name, Exception e, String unsupportMessage) { |
||||||
|
String errorMessage = unsupportMessage; |
||||||
|
if (result == TransformResult.FAILED) { |
||||||
|
errorMessage = e.getStackTrace()[0].toString(); |
||||||
|
} |
||||||
|
ErrorMessage message = ErrorMessage.build(e == null ? errorMessage : e.getMessage(), errorMessage); |
||||||
|
message.setTname(name); |
||||||
|
message.setDisplayName(name); |
||||||
|
MetricRegistry.getMetric().submit(message); |
||||||
|
} |
||||||
|
|
||||||
|
private static void saveAsJSON(TransformResult result, String templateID, String name, Exception e) { |
||||||
|
saveToErrorInfo(result, templateID, name, e, null); |
||||||
|
saveToErrorMessage(result, templateID, name, e, null); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 预编译中不支持的功能的埋点 |
||||||
|
*/ |
||||||
|
public static void submitUnSupportTransform(TransformResult result, String templateID, String name, String unsupportMessage) { |
||||||
|
if (isPressureTesting()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
saveToErrorInfo(result, templateID, name, null, unsupportMessage); |
||||||
|
saveToErrorMessage(result, templateID, name, null, unsupportMessage); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 埋点对压测性能的影响控制参数 |
||||||
|
* |
||||||
|
* @return 是否压测 |
||||||
|
*/ |
||||||
|
public static boolean isPressureTesting() { |
||||||
|
return Boolean.parseBoolean(System.getProperty("monitorDebug")); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,116 @@ |
|||||||
|
package com.fr.nx.app.designer.toolbar; |
||||||
|
|
||||||
|
import com.fr.base.extension.FileExtension; |
||||||
|
import com.fr.design.actions.UpdateAction; |
||||||
|
import com.fr.design.file.HistoryTemplateListCache; |
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.design.mainframe.JTemplate; |
||||||
|
import com.fr.design.menu.MenuKeySet; |
||||||
|
import com.fr.file.FILE; |
||||||
|
import com.fr.file.FileNodeFILE; |
||||||
|
import com.fr.general.IOUtils; |
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
import com.fr.nx.app.designer.utils.CompileTransformUtil; |
||||||
|
|
||||||
|
import javax.swing.Icon; |
||||||
|
import javax.swing.JComponent; |
||||||
|
import javax.swing.KeyStroke; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.KeyEvent; |
||||||
|
|
||||||
|
import static com.fr.design.dialog.FineJOptionPane.showConfirmDialog; |
||||||
|
import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; |
||||||
|
import static javax.swing.JOptionPane.OK_CANCEL_OPTION; |
||||||
|
import static javax.swing.JOptionPane.OK_OPTION; |
||||||
|
import static javax.swing.JOptionPane.WARNING_MESSAGE; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2019-10-14 |
||||||
|
*/ |
||||||
|
public class CompileAction extends UpdateAction { |
||||||
|
public static final Icon TRANS_ICON = IOUtils.readIcon("/com/fr/nx/app/designer/transform.png"); |
||||||
|
|
||||||
|
private static final MenuKeySet COMPILE_ATTR = new MenuKeySet() { |
||||||
|
@Override |
||||||
|
public char getMnemonic() { |
||||||
|
return 'C'; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getMenuName() { |
||||||
|
return InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine-Transform-Tooltip"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public KeyStroke getKeyStroke() { |
||||||
|
return KeyStroke.getKeyStroke(KeyEvent.VK_T, DEFAULT_MODIFIER); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
public CompileAction() { |
||||||
|
initMenuStyle(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initMenuStyle() { |
||||||
|
this.setMenuKeySet(COMPILE_ATTR); |
||||||
|
this.setName(getMenuKeySet().getMenuKeySetName()); |
||||||
|
this.setMnemonic(getMenuKeySet().getMnemonic()); |
||||||
|
this.setSmallIcon(TRANS_ICON); |
||||||
|
this.setAccelerator(getMenuKeySet().getKeyStroke()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
JTemplate jtemplate = DesignerContext.getDesignerFrame().getSelectedJTemplate(); |
||||||
|
if (jtemplate == null || jtemplate.getEditingFILE() == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
FILE currentTemplate = jtemplate.getEditingFILE(); |
||||||
|
if(currentTemplate instanceof FileNodeFILE){ |
||||||
|
transformAndDisplay(jtemplate); |
||||||
|
}else { |
||||||
|
//模板不在报表环境下,提示保存
|
||||||
|
int selVal = showConfirmDialog( |
||||||
|
DesignerContext.getDesignerFrame(), |
||||||
|
InterProviderFactory.getProvider().getLocText("Fine-Plugin-Engine_Preview_Message"), |
||||||
|
InterProviderFactory.getProvider().getLocText("Fine-Plugin-Engine_Transformer_Tips"), |
||||||
|
OK_CANCEL_OPTION, |
||||||
|
WARNING_MESSAGE); |
||||||
|
|
||||||
|
if (OK_OPTION == selVal) { |
||||||
|
//保存成功才会执行编译
|
||||||
|
if (jtemplate.saveAsTemplate2Env()) { |
||||||
|
transformAndDisplay(jtemplate); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
//编译模板并展示
|
||||||
|
private void transformAndDisplay(JTemplate jtemplate){ |
||||||
|
String path = jtemplate.getEditingFILE().getPath(); |
||||||
|
TemplateTransformer transformer = TemplateTransformer.parse(path); |
||||||
|
FILE targetFile = CompileTransformUtil.getTargetFile(jtemplate, transformer); |
||||||
|
TransformResult result = transformer.transform(jtemplate, targetFile); |
||||||
|
jtemplate.fireJTemplateSaved(); |
||||||
|
result.display(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isEnabled() { |
||||||
|
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
||||||
|
String path = jt.getEditingFILE().getPath(); |
||||||
|
return FileExtension.CPTX.matchExtension(path) || FileExtension.CPT.matchExtension(path); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public JComponent createToolBarComponent() { |
||||||
|
UIButton transBtn = (UIButton) super.createToolBarComponent(); |
||||||
|
transBtn.set4ToolbarButton(); |
||||||
|
transBtn.setToolTipText(InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine-Transform-Tooltip")); |
||||||
|
return transBtn; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,221 @@ |
|||||||
|
package com.fr.nx.app.designer.toolbar; |
||||||
|
|
||||||
|
import com.fr.base.extension.FileExtension; |
||||||
|
import com.fr.design.file.HistoryTemplateListCache; |
||||||
|
import com.fr.design.file.MutilTempalteTabPane; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.design.mainframe.JTemplate; |
||||||
|
import com.fr.file.FILE; |
||||||
|
import com.fr.file.FileNodeFILE; |
||||||
|
import com.fr.file.filetree.FileNode; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.main.impl.WorkBook; |
||||||
|
import com.fr.nx.app.designer.monitor.DesignerMetricRecorder; |
||||||
|
import com.fr.nx.compile.CompileStatus; |
||||||
|
import com.fr.nx.compile.ReportCompiler; |
||||||
|
import com.fr.nx.compile.adapter.LegacyWorkBookAdapter; |
||||||
|
import com.fr.nx.compile.util.ReportCompileUtils; |
||||||
|
import com.fr.nx.cptx.CptxIOManager; |
||||||
|
import com.fr.nx.cptx.cache.CptxTemplatePool; |
||||||
|
import com.fr.nx.cptx.entry.CptxTemplate; |
||||||
|
import com.fr.nx.cptx.io.handle.CptxTemplateHandle; |
||||||
|
import com.fr.nx.app.designer.cptx.io.DesignReadWritableProvider; |
||||||
|
import com.fr.nx.cptx.monitor.CompileMonitorHandler; |
||||||
|
import com.fr.nx.cptx.utils.CptxFileUtils; |
||||||
|
import com.fr.nx.data.layer.LayerItem; |
||||||
|
import com.fr.nx.data.layer.LayerProps; |
||||||
|
import com.fr.nx.template.compile.CompiledReport; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import org.jetbrains.annotations.NotNull; |
||||||
|
|
||||||
|
import java.io.OutputStream; |
||||||
|
|
||||||
|
import static com.fr.base.extension.FileExtension.ALL; |
||||||
|
import static com.fr.base.extension.FileExtension.CPT; |
||||||
|
import static com.fr.base.extension.FileExtension.CPTX; |
||||||
|
|
||||||
|
/** |
||||||
|
* 模板转换器, 可以把cptx模板转为cpt, 或者cpt模板转为cptx. |
||||||
|
* 以后可以扩展支持frm frmx互相转换 |
||||||
|
*/ |
||||||
|
|
||||||
|
public enum TemplateTransformer { |
||||||
|
|
||||||
|
TO_CPTX(CPT) { |
||||||
|
@Override |
||||||
|
public TransformResult transform(JTemplate jtemplate, FILE file) { |
||||||
|
WorkBook workbook = (WorkBook) jtemplate.getTarget(); |
||||||
|
TransformResultInfo resultInfo = compileCPTX(workbook, file); |
||||||
|
if (needDoAfterTransformed(resultInfo.getResult())) { |
||||||
|
doAfterTransformed(file, jtemplate); |
||||||
|
} |
||||||
|
return resultInfo.getResult(); |
||||||
|
} |
||||||
|
}, |
||||||
|
TO_CPT(CPTX) { |
||||||
|
@Override |
||||||
|
public TransformResult transform(JTemplate jtemplate, FILE file) { |
||||||
|
WorkBook workbook = (WorkBook) jtemplate.getTarget(); |
||||||
|
try { |
||||||
|
workbook.export(file.asOutputStream()); |
||||||
|
doAfterTransformed(file, jtemplate); |
||||||
|
return TransformResult.SUCCESS; |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
return TransformResult.FAILED; |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
OTHER(ALL); |
||||||
|
private FileExtension extension; |
||||||
|
|
||||||
|
TemplateTransformer(FileExtension extension) { |
||||||
|
this.extension = extension; |
||||||
|
} |
||||||
|
|
||||||
|
public TransformResult transform(JTemplate jtemplate) { |
||||||
|
return transform(jtemplate, jtemplate.getEditingFILE()); |
||||||
|
} |
||||||
|
|
||||||
|
public TransformResult transform(JTemplate jtemplate, FILE newFile) { |
||||||
|
return TransformResult.UNSUPPORT; |
||||||
|
} |
||||||
|
|
||||||
|
public static TemplateTransformer parse(String path) { |
||||||
|
for (TemplateTransformer transformer : values()) { |
||||||
|
if (transformer.extension.matchExtension(path)) { |
||||||
|
return transformer; |
||||||
|
} |
||||||
|
} |
||||||
|
return OTHER; |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean needDoAfterTransformed(TransformResult result) { |
||||||
|
return ComparatorUtils.equals(TransformResult.SUCCESS, result) |
||||||
|
|| ComparatorUtils.equals(TransformResult.UNSUPPORT, result); |
||||||
|
} |
||||||
|
|
||||||
|
private static void doAfterTransformed(FILE file, JTemplate jtemplate) { |
||||||
|
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
||||||
|
if (ComparatorUtils.equals(file.getPath(), jt.getPath())) { |
||||||
|
HistoryTemplateListCache.getInstance().closeSelectedReport(jt); |
||||||
|
DesignerContext.getDesignerFrame().openTemplate(file); |
||||||
|
return; |
||||||
|
} |
||||||
|
MutilTempalteTabPane.getInstance().setIsCloseCurrent(true); |
||||||
|
MutilTempalteTabPane.getInstance().closeFormat(jt); |
||||||
|
MutilTempalteTabPane.getInstance().closeSpecifiedTemplate(jt); |
||||||
|
DesignerContext.getDesignerFrame().openTemplate(file); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static FILE createOutputFile(String oldPath, String oldSuffix, String newSuffix) { |
||||||
|
String newPath = generateNewPath(oldPath, oldSuffix, newSuffix); |
||||||
|
return new FileNodeFILE(new FileNode(newPath, false)); |
||||||
|
} |
||||||
|
|
||||||
|
private static String generateNewPath(String oldPath, String oldSuffix, String newSuffix) { |
||||||
|
if (StringUtils.isEmpty(oldPath) || StringUtils.isEmpty(oldSuffix) || StringUtils.isEmpty(newSuffix)) { |
||||||
|
return oldPath; |
||||||
|
} |
||||||
|
|
||||||
|
if (oldPath.endsWith(oldSuffix)) { |
||||||
|
return StringUtils.cutStringEndWith(oldPath, oldSuffix) + newSuffix; |
||||||
|
} |
||||||
|
return oldPath; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 编译和保存 |
||||||
|
* |
||||||
|
* @param workbook work |
||||||
|
* @param file file |
||||||
|
* @return 编译保存结果 |
||||||
|
*/ |
||||||
|
@NotNull |
||||||
|
public static TransformResultInfo compileCPTX(WorkBook workbook, FILE file) { |
||||||
|
//对于非工作目录的cptx,修改无需执行编译
|
||||||
|
if(!(file instanceof FileNodeFILE)){ |
||||||
|
try { |
||||||
|
OutputStream outputStream = file.asOutputStream(); |
||||||
|
workbook.export(outputStream); |
||||||
|
return TransformResultInfo.generateResult(TransformResult.SUCCESS).saved(true); |
||||||
|
}catch (Exception e){ |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
return TransformResultInfo.generateResult(TransformResult.FAILED).saved(false); |
||||||
|
} |
||||||
|
} |
||||||
|
boolean saved; |
||||||
|
CompiledReport report = null; |
||||||
|
CompileStatus compileStatus = CompileStatus.SUCCEED; |
||||||
|
if (workbook == null || file == null) { |
||||||
|
return TransformResultInfo |
||||||
|
.generateResult(TransformResult.FAILED, "work and file must not be null") |
||||||
|
.saved(false); |
||||||
|
} |
||||||
|
String failMessage = null; |
||||||
|
// 编译
|
||||||
|
ReportCompiler compiler; |
||||||
|
try { |
||||||
|
compiler = new ReportCompiler(new LegacyWorkBookAdapter(workbook)); |
||||||
|
long startTime = System.currentTimeMillis(); |
||||||
|
compiler.compile(); |
||||||
|
report = compiler.getCompiledReport(); |
||||||
|
// 折叠树埋点
|
||||||
|
LayerProps props = ReportCompileUtils.getLayerProps(report); |
||||||
|
LayerItem[] items; |
||||||
|
if (props != null && (items = props.getLayerItems()) != null) { |
||||||
|
CompileMonitorHandler.submitTreeCompileFocusPoint( |
||||||
|
startTime, file.getPath(), items.length, |
||||||
|
props.getExpandLayer(), true |
||||||
|
); |
||||||
|
} |
||||||
|
compileStatus = compiler.getStatus(); |
||||||
|
failMessage = compiler.getFailMessage(); |
||||||
|
long endTime = System.currentTimeMillis(); |
||||||
|
CompileMonitorHandler.submitCompileMessage(startTime, endTime, file.getPath(), ""); |
||||||
|
if (compileStatus != CompileStatus.SUCCEED) { |
||||||
|
DesignerMetricRecorder.submitUnSupportTransform( |
||||||
|
TransformResult.UNSUPPORT, |
||||||
|
workbook.getTemplateID(), |
||||||
|
file.getName(), |
||||||
|
compileStatus == CompileStatus.FAILED_UNSUPPORT ? failMessage : null |
||||||
|
); |
||||||
|
} |
||||||
|
} catch (Exception exception) { |
||||||
|
String templateID = workbook.getTemplateID(); |
||||||
|
String fileName = file.getName(); |
||||||
|
DesignerMetricRecorder.submitFailedTransform(TransformResult.FAILED, templateID, fileName, exception); |
||||||
|
FineLoggerFactory.getLogger().error(exception.getMessage(), exception); |
||||||
|
} |
||||||
|
|
||||||
|
// 构建编译结果,当前的 cptx template 是未经反序列化钩子处理过的 cptx 模版对象,不能直接用于模版预览
|
||||||
|
CptxTemplate template = CptxIOManager.createCptxTemplate(workbook, report, compileStatus, failMessage); |
||||||
|
// 保存
|
||||||
|
DesignReadWritableProvider cptx = new DesignReadWritableProvider(file); |
||||||
|
CptxTemplateHandle handle = CptxIOManager.create(template, cptx); |
||||||
|
try { |
||||||
|
saved = handle.save(); |
||||||
|
} catch (Exception exception) { |
||||||
|
// 存储cptx格式报错或者失败
|
||||||
|
FineLoggerFactory.getLogger().error(exception.getMessage(), exception); |
||||||
|
DesignerMetricRecorder.submitFailedTransform(TransformResult.FAILED, workbook.getTemplateID(), file.getName(), exception); |
||||||
|
return TransformResultInfo.generateResult(TransformResult.FAILED, failMessage).saved(false); |
||||||
|
} |
||||||
|
// 读取可 web 预览模版并缓存
|
||||||
|
try { |
||||||
|
// todo 是否考虑异步
|
||||||
|
String timestampedPath = CptxFileUtils.getTimestampedPath(file.getPath()); |
||||||
|
CptxTemplate previewCptxTemplate = CptxIOManager.open(cptx).getTemplate(); |
||||||
|
CptxTemplatePool.getInstance().addCptxTemplate(timestampedPath, previewCptxTemplate); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
if (report == null) { |
||||||
|
// 编译报错或者失败
|
||||||
|
return TransformResultInfo.generateResult(TransformResult.FAILED, failMessage).saved(saved); |
||||||
|
} |
||||||
|
return TransformResultInfo.generateResult(TransformResult.parse(compileStatus), failMessage).saved(saved); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
package com.fr.nx.app.designer.toolbar; |
||||||
|
|
||||||
|
import com.fr.design.file.TemplateTreePane; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
import com.fr.nx.compile.CompileStatus; |
||||||
|
|
||||||
|
import javax.swing.JOptionPane; |
||||||
|
|
||||||
|
public enum TransformResult { |
||||||
|
|
||||||
|
SUCCESS(InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine-Transform-Success")) { |
||||||
|
@Override |
||||||
|
public void display() { |
||||||
|
// 转换成功后, 刷新下目录树
|
||||||
|
TemplateTreePane.getInstance().refresh(); |
||||||
|
super.display(); |
||||||
|
} |
||||||
|
}, |
||||||
|
FAILED(InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine-Transform-Failed")), |
||||||
|
UNSUPPORT(InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine-Transform-Unsupport")){ |
||||||
|
@Override |
||||||
|
public void display() { |
||||||
|
JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), TransformResult.SUCCESS.toString()); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
private String msg; |
||||||
|
|
||||||
|
private TransformResult(String msg) { |
||||||
|
this.msg = msg; |
||||||
|
} |
||||||
|
|
||||||
|
// 展示结果
|
||||||
|
public void display() { |
||||||
|
JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), this.toString()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return this.msg; |
||||||
|
} |
||||||
|
|
||||||
|
public static TransformResult parse(CompileStatus status) { |
||||||
|
switch (status) { |
||||||
|
case SUCCEED: |
||||||
|
return TransformResult.SUCCESS; |
||||||
|
case FAILED_UNSUPPORT: |
||||||
|
return TransformResult.UNSUPPORT; |
||||||
|
default: |
||||||
|
return TransformResult.FAILED; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,64 @@ |
|||||||
|
package com.fr.nx.app.designer.toolbar; |
||||||
|
|
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-01-15 |
||||||
|
*/ |
||||||
|
public class TransformResultInfo { |
||||||
|
|
||||||
|
private boolean saved; |
||||||
|
private TransformResult result; |
||||||
|
private final String transformLog; |
||||||
|
|
||||||
|
public static TransformResultInfo generateResult(TransformResult result, String transformLog) { |
||||||
|
return new TransformResultInfo(result, transformLog); |
||||||
|
} |
||||||
|
|
||||||
|
public static TransformResultInfo generateResult(TransformResult result) { |
||||||
|
return new TransformResultInfo(result, StringUtils.EMPTY); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private TransformResultInfo(TransformResult result, String transformLog) { |
||||||
|
this.result = result; |
||||||
|
this.transformLog = transformLog; |
||||||
|
this.saved = false; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isSaved() { |
||||||
|
return saved; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSaved(boolean saved) { |
||||||
|
this.saved = saved; |
||||||
|
} |
||||||
|
|
||||||
|
public TransformResultInfo saved(boolean saved) { |
||||||
|
setSaved(saved); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public TransformResult getResult() { |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
public void setResult(TransformResult result) { |
||||||
|
this.result = result; |
||||||
|
} |
||||||
|
|
||||||
|
public String getTransformLog() { |
||||||
|
switch (this.result) { |
||||||
|
case FAILED: |
||||||
|
return transformLog + "\n" |
||||||
|
+ InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Transform_Failed_Tip"); |
||||||
|
case SUCCESS: |
||||||
|
return InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Transform_Success_Tip"); |
||||||
|
case UNSUPPORT: |
||||||
|
return transformLog + "\n" |
||||||
|
+ InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Transform_Unsupport_Tip"); |
||||||
|
} |
||||||
|
return transformLog; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
package com.fr.nx.app.designer.transform; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2019-12-10 |
||||||
|
*/ |
||||||
|
public class BatchTransformProgress { |
||||||
|
private double progress = 0.0D; |
||||||
|
private int total = 0; |
||||||
|
private int complete = 0; |
||||||
|
|
||||||
|
public BatchTransformProgress(int total) { |
||||||
|
this.total = total; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public double getProgress() { |
||||||
|
return this.progress; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void updateProgress() { |
||||||
|
this.complete++; |
||||||
|
this.progress = this.complete * 1D / this.total; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
package com.fr.nx.app.designer.transform; |
||||||
|
|
||||||
|
import com.fr.file.filetree.FileNode; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-02-14 |
||||||
|
*/ |
||||||
|
public class BatchTransformUtil { |
||||||
|
private BatchTransformUtil() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public static FileNode[] filterTransformedFile(FileNode[] fileNodes, List<FileNode> transformedList){ |
||||||
|
List<FileNode> list = new ArrayList<FileNode>(); |
||||||
|
for (FileNode fileNode : fileNodes) { |
||||||
|
if (!transformedList.contains(fileNode)) { |
||||||
|
list.add(fileNode); |
||||||
|
} |
||||||
|
} |
||||||
|
return list.toArray(new FileNode[list.size()]); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,71 @@ |
|||||||
|
package com.fr.nx.app.designer.transform; |
||||||
|
|
||||||
|
import com.fr.design.utils.concurrent.ThreadFactoryBuilder; |
||||||
|
import com.fr.file.filetree.FileNode; |
||||||
|
import com.fr.plugin.context.PluginContexts; |
||||||
|
import com.fr.nx.app.designer.toolbar.TransformResultInfo; |
||||||
|
import com.fr.nx.app.designer.utils.CompileTransformUtil; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.concurrent.ConcurrentHashMap; |
||||||
|
import java.util.concurrent.ExecutorService; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2019-12-10 |
||||||
|
*/ |
||||||
|
public class BatchTransformer { |
||||||
|
private BatchTransformProgress progress = new BatchTransformProgress(0); |
||||||
|
private Map<FileNode, TransformResultInfo> transformResults = new ConcurrentHashMap<FileNode, TransformResultInfo>(); |
||||||
|
private UpdateCallBack updateCallBack; |
||||||
|
private static final int MAXPOOLSIZE = 5; |
||||||
|
private static final String THREAD_NAME_TEMPLATE = "batchtransform-thread-%s"; |
||||||
|
private ExecutorService threadPoolExecutor = |
||||||
|
PluginContexts.currentContext().newFixedThreadPool(MAXPOOLSIZE, |
||||||
|
new ThreadFactoryBuilder().setNameFormat(THREAD_NAME_TEMPLATE).build()); |
||||||
|
|
||||||
|
public BatchTransformer(UpdateCallBack updateCallBack) { |
||||||
|
this.updateCallBack = updateCallBack; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void batchTransform(List<FileNode> fileNodes) { |
||||||
|
//先清理下
|
||||||
|
transformResults.clear(); |
||||||
|
progress = new BatchTransformProgress(fileNodes.size()); |
||||||
|
for (FileNode fileNode : fileNodes) { |
||||||
|
transform(fileNode); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void transform(final FileNode fileNode) { |
||||||
|
|
||||||
|
threadPoolExecutor.execute(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
TransformResultInfo transformResult = CompileTransformUtil.compileFile(fileNode); |
||||||
|
transformResults.put(fileNode, transformResult); |
||||||
|
updateTransformProgress(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private synchronized void updateTransformProgress() { |
||||||
|
progress.updateProgress(); |
||||||
|
updateCallBack.updateProgress(progress.getProgress()); |
||||||
|
} |
||||||
|
|
||||||
|
public void shutDown() { |
||||||
|
if (threadPoolExecutor != null) { |
||||||
|
threadPoolExecutor.shutdownNow(); |
||||||
|
} |
||||||
|
threadPoolExecutor = PluginContexts.currentContext().newFixedThreadPool(MAXPOOLSIZE, |
||||||
|
new ThreadFactoryBuilder().setNameFormat(THREAD_NAME_TEMPLATE).build()); |
||||||
|
updateCallBack.shutDown(); |
||||||
|
} |
||||||
|
|
||||||
|
public Map<FileNode, TransformResultInfo> getResults() { |
||||||
|
return transformResults; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
package com.fr.nx.app.designer.transform; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2019-12-10 |
||||||
|
*/ |
||||||
|
public interface UpdateCallBack { |
||||||
|
/** |
||||||
|
* 更新进度 |
||||||
|
* @param progress 进度 |
||||||
|
*/ |
||||||
|
void updateProgress(double progress); |
||||||
|
|
||||||
|
/** |
||||||
|
* 进度中断 |
||||||
|
*/ |
||||||
|
void shutDown(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 进度重置 |
||||||
|
*/ |
||||||
|
void reset(); |
||||||
|
} |
@ -0,0 +1,61 @@ |
|||||||
|
package com.fr.nx.app.designer.transform.ui; |
||||||
|
|
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.utils.gui.GUICoreUtils; |
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
|
||||||
|
import javax.swing.JDialog; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.Frame; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.awt.event.WindowAdapter; |
||||||
|
import java.awt.event.WindowEvent; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2019-12-19 |
||||||
|
*/ |
||||||
|
public class BatchTransformDialog extends JDialog implements ActionListener { |
||||||
|
private UIButton closeBtn; |
||||||
|
|
||||||
|
public BatchTransformDialog(Frame parent, JPanel contentPane) { |
||||||
|
super(parent, true); |
||||||
|
|
||||||
|
this.setTitle(InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Batch_Transform")); |
||||||
|
this.setResizable(false); |
||||||
|
JPanel defaultPane = FRGUIPaneFactory.createBorderLayout_L_Pane(); |
||||||
|
this.setContentPane(defaultPane); |
||||||
|
|
||||||
|
closeBtn = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Close")); |
||||||
|
closeBtn.addActionListener(this); |
||||||
|
JPanel buttonPanel = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); |
||||||
|
buttonPanel.add(closeBtn); |
||||||
|
|
||||||
|
defaultPane.add(contentPane, BorderLayout.CENTER); |
||||||
|
defaultPane.add(buttonPanel, BorderLayout.SOUTH); |
||||||
|
|
||||||
|
addWindowListener(new WindowAdapter() { |
||||||
|
public void windowClosing(WindowEvent e) { |
||||||
|
dialogExit(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
this.getRootPane().setDefaultButton(closeBtn); |
||||||
|
|
||||||
|
this.setSize(new Dimension(900, 600)); |
||||||
|
GUICoreUtils.centerWindow(this); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
dialogExit(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void dialogExit() { |
||||||
|
this.dispose(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,223 @@ |
|||||||
|
package com.fr.nx.app.designer.transform.ui; |
||||||
|
|
||||||
|
import com.fr.base.extension.FileExtension; |
||||||
|
import com.fr.design.dialog.BasicPane; |
||||||
|
import com.fr.design.file.NodeAuthProcessor; |
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.gui.icontainer.UIScrollPane; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.gui.itextfield.UITextField; |
||||||
|
import com.fr.design.gui.itree.filetree.FileNodeComparator; |
||||||
|
import com.fr.design.gui.itree.filetree.FileNodeConstants; |
||||||
|
import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.design.mainframe.DesignerFrame; |
||||||
|
import com.fr.file.filetree.FileNode; |
||||||
|
import com.fr.file.filetree.IOFileNodeFilter; |
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.nx.app.designer.toolbar.TransformResultInfo; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.tree.DefaultTreeModel; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Dialog; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.awt.event.KeyAdapter; |
||||||
|
import java.awt.event.KeyEvent; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.Iterator; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2019-12-10 |
||||||
|
*/ |
||||||
|
public class BatchTransformPane extends BasicPane { |
||||||
|
private UITextField searchField; |
||||||
|
private TransformFileTree tree; |
||||||
|
private Dialog showDialog; |
||||||
|
private TransformPreparePane preparePane; |
||||||
|
private TransformResultPane resultPane; |
||||||
|
|
||||||
|
|
||||||
|
public BatchTransformPane() { |
||||||
|
DesignerFrame designerFrame = DesignerContext.getDesignerFrame(); |
||||||
|
this.showDialog = new BatchTransformDialog(designerFrame, this); |
||||||
|
initPane(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initPane() { |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
initNorthPane(); |
||||||
|
initSouthPane(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initNorthPane() { |
||||||
|
UILabel northTip = new UILabel(InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Transform_Tip")); |
||||||
|
northTip.setForeground(Color.decode("#8F8F92")); |
||||||
|
northTip.setBorder(BorderFactory.createEmptyBorder(0, 550, 10, 10)); |
||||||
|
this.add(northTip, BorderLayout.NORTH); |
||||||
|
} |
||||||
|
|
||||||
|
private void initSouthPane() { |
||||||
|
preparePane = new TransformPreparePane(this.showDialog, this); |
||||||
|
tree = new TransformFileTree(preparePane); |
||||||
|
this.add(preparePane, BorderLayout.CENTER); |
||||||
|
initLeftPane(); |
||||||
|
initRightPane(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initLeftPane() { |
||||||
|
IOFileNodeFilter filter = new IOFileNodeFilter(new String[]{FileExtension.CPT.getSuffix()}); |
||||||
|
tree.setDigIn(true); |
||||||
|
tree.setFileNodeFilter(filter); |
||||||
|
UIScrollPane scrollPane = new UIScrollPane(tree); |
||||||
|
scrollPane.setPreferredSize(new Dimension(320, 442)); |
||||||
|
scrollPane.setBorder(BorderFactory.createEmptyBorder(12, 0, 0, 0)); |
||||||
|
tree.refreshEnv(); |
||||||
|
JPanel selectPane = FRGUIPaneFactory.createTitledBorderPaneCenter( |
||||||
|
InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Transform_Select_Template")); |
||||||
|
JPanel searchPane = initSearchPane(); |
||||||
|
JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
jPanel.add(searchPane, BorderLayout.NORTH); |
||||||
|
jPanel.add(scrollPane, BorderLayout.WEST); |
||||||
|
jPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); |
||||||
|
selectPane.add(jPanel); |
||||||
|
selectPane.setPreferredSize(new Dimension(330, 501)); |
||||||
|
this.add(selectPane, BorderLayout.WEST); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void initRightPane() { |
||||||
|
resultPane = new TransformResultPane(); |
||||||
|
this.add(resultPane, BorderLayout.EAST); |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel initSearchPane() { |
||||||
|
JPanel jPanel = FRGUIPaneFactory.createNormalFlowInnerContainer_M_Pane(); |
||||||
|
jPanel.setBorder(BorderFactory.createEmptyBorder()); |
||||||
|
searchField = new UITextField(); |
||||||
|
searchField.requestFocus(); |
||||||
|
searchField.addKeyListener(keyFieldKeyListener); |
||||||
|
searchField.setPreferredSize(new Dimension(261, 20)); |
||||||
|
jPanel.add(searchField); |
||||||
|
UIButton searchBtn = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Search")); |
||||||
|
searchBtn.addActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
search(); |
||||||
|
} |
||||||
|
}); |
||||||
|
searchBtn.setPreferredSize(new Dimension(44, 20)); |
||||||
|
jPanel.add(searchBtn); |
||||||
|
return jPanel; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private KeyAdapter keyFieldKeyListener = new KeyAdapter() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void keyPressed(KeyEvent e) { |
||||||
|
if (e.getKeyCode() == KeyEvent.VK_ENTER) { |
||||||
|
search(); |
||||||
|
e.consume(); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void search() { |
||||||
|
//重新构建TreeModel
|
||||||
|
filter(searchField.getText()); |
||||||
|
ExpandMutableTreeNode rootNode = (ExpandMutableTreeNode) tree.getModel().getRoot(); |
||||||
|
((DefaultTreeModel) tree.getModel()).reload(rootNode); |
||||||
|
// 展开所有isExpanded为true的TreeNode
|
||||||
|
rootNode.expandCurrentTreeNode(tree); |
||||||
|
} |
||||||
|
|
||||||
|
public void filter(String filterString) { |
||||||
|
NodeAuthProcessor.getInstance().refresh(); |
||||||
|
DefaultTreeModel defaultTreeModel = (DefaultTreeModel) tree.getModel(); |
||||||
|
ExpandMutableTreeNode rootTreeNode = (ExpandMutableTreeNode) defaultTreeModel.getRoot(); |
||||||
|
NodeAuthProcessor.getInstance().fixTreeNodeAuth(rootTreeNode); |
||||||
|
filter(rootTreeNode, filterString); |
||||||
|
defaultTreeModel.reload(rootTreeNode); |
||||||
|
} |
||||||
|
|
||||||
|
private void filter(ExpandMutableTreeNode rootTreeNode, String filterString) { |
||||||
|
rootTreeNode.removeAllChildren(); |
||||||
|
|
||||||
|
FileNode[] fns; |
||||||
|
fns = listFileNodes(rootTreeNode); |
||||||
|
|
||||||
|
ExpandMutableTreeNode[] subTreeNodes = NodeAuthProcessor.getInstance().parser2TreeNodeArray(fns); |
||||||
|
|
||||||
|
for (ExpandMutableTreeNode node : subTreeNodes) { |
||||||
|
filter(node, filterString); |
||||||
|
if (node.getChildCount() > 0 || (node.getChildCount() == 0 && node.toString().contains(filterString))) { |
||||||
|
node.setExpanded(true); |
||||||
|
rootTreeNode.add(node); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private FileNode[] listFileNodes(ExpandMutableTreeNode rootTreeNode) { |
||||||
|
if (rootTreeNode == null) { |
||||||
|
return new FileNode[0]; |
||||||
|
} |
||||||
|
|
||||||
|
Object object = rootTreeNode.getUserObject(); |
||||||
|
if (!(object instanceof FileNode)) { |
||||||
|
return new FileNode[0]; |
||||||
|
} |
||||||
|
|
||||||
|
FileNode[] fileNodes = null; |
||||||
|
try { |
||||||
|
fileNodes = tree.listFile(((FileNode) object).getEnvPath()); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
if (fileNodes == null) { |
||||||
|
fileNodes = new FileNode[0]; |
||||||
|
} |
||||||
|
Arrays.sort(fileNodes, new FileNodeComparator(FileNodeConstants.getSupportFileTypes())); |
||||||
|
return fileNodes; |
||||||
|
} |
||||||
|
|
||||||
|
public void resetFilePaths(Map<FileNode, TransformResultInfo> resultMap) { |
||||||
|
this.tree.resetSelectedPaths(); |
||||||
|
Iterator<FileNode> iterator = resultMap.keySet().iterator(); |
||||||
|
List<FileNode> list = new ArrayList<FileNode>(); |
||||||
|
while (iterator.hasNext()){ |
||||||
|
FileNode node = iterator.next(); |
||||||
|
list.add(node); |
||||||
|
} |
||||||
|
this.tree.addTransformedList(list); |
||||||
|
this.tree.refresh(); |
||||||
|
resultPane.populate(resultMap); |
||||||
|
} |
||||||
|
|
||||||
|
public void removeSelectedNode(FileNode fileNode) { |
||||||
|
String path = fileNode.getEnvPath(); |
||||||
|
this.tree.removeSelectedPath(path); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
protected String title4PopupWindow() { |
||||||
|
return InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Batch_Transform"); |
||||||
|
} |
||||||
|
|
||||||
|
public Dialog showDialog() { |
||||||
|
return this.showDialog; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,79 @@ |
|||||||
|
package com.fr.nx.app.designer.transform.ui; |
||||||
|
|
||||||
|
import com.fr.base.BaseUtils; |
||||||
|
import com.fr.design.constants.UIConstants; |
||||||
|
import com.fr.design.gui.ilist.UIList; |
||||||
|
import com.fr.design.gui.itree.filetree.FileTreeIcon; |
||||||
|
import com.fr.file.filetree.FileNode; |
||||||
|
|
||||||
|
import javax.swing.DefaultListModel; |
||||||
|
import javax.swing.Icon; |
||||||
|
import javax.swing.JList; |
||||||
|
import javax.swing.ListSelectionModel; |
||||||
|
import javax.swing.SwingUtilities; |
||||||
|
import java.awt.Rectangle; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.awt.event.MouseListener; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-01-13 |
||||||
|
*/ |
||||||
|
public class PrepareTransformFileList extends UIList { |
||||||
|
private TransformPreparePane transformingPane; |
||||||
|
private static final int DELETE_RANGE = 20; |
||||||
|
|
||||||
|
|
||||||
|
public PrepareTransformFileList(final TransformPreparePane transformingPane) { |
||||||
|
super(); |
||||||
|
this.transformingPane = transformingPane; |
||||||
|
this.setBackground(UIConstants.TREE_BACKGROUND); |
||||||
|
this.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); |
||||||
|
DefaultListModel listModel = new DefaultListModel(); |
||||||
|
this.setModel(listModel); |
||||||
|
this.setCellRenderer(new UIListControlCellRenderer() { |
||||||
|
@Override |
||||||
|
protected Icon getLeftLabelIcon(Object value) { |
||||||
|
if (value instanceof FileNode) { |
||||||
|
return FileTreeIcon.getIcon((FileNode) value); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected Icon getRightLabelIcon(Object value) { |
||||||
|
return BaseUtils.readIcon("/com/fr/nx/app/designer/transform/tab_close.png"); |
||||||
|
} |
||||||
|
}); |
||||||
|
this.addMouseListener(getListMouseListener()); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private MouseListener getListMouseListener() { |
||||||
|
return new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseReleased(MouseEvent evt) { |
||||||
|
JList list = (JList) evt.getSource(); |
||||||
|
int selectedIndex = list.getSelectedIndex(); |
||||||
|
Rectangle rectangle = list.getCellBounds(selectedIndex, selectedIndex); |
||||||
|
if (SwingUtilities.isLeftMouseButton(evt) |
||||||
|
&& pointInSelected(rectangle, evt.getX(), evt.getY())) { |
||||||
|
Object value = PrepareTransformFileList.this.getSelectedValue(); |
||||||
|
if (value != null) { |
||||||
|
transformingPane.removeSelectedNode((FileNode) value); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
private boolean pointInSelected(Rectangle rectangle, int x, int y) { |
||||||
|
if (rectangle == null) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
return x >= rectangle.x + rectangle.width - DELETE_RANGE && |
||||||
|
x <= rectangle.x + rectangle.width && |
||||||
|
y >= rectangle.y && y <= rectangle.y + rectangle.height; |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,204 @@ |
|||||||
|
package com.fr.nx.app.designer.transform.ui; |
||||||
|
|
||||||
|
import com.fr.base.FRContext; |
||||||
|
import com.fr.base.extension.FileExtension; |
||||||
|
import com.fr.design.gui.itree.checkboxtree.CheckBoxTree; |
||||||
|
import com.fr.design.gui.itree.checkboxtree.CheckBoxTreeCellRenderer; |
||||||
|
import com.fr.design.gui.itree.checkboxtree.CheckBoxTreeSelectionModel; |
||||||
|
import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode; |
||||||
|
import com.fr.design.remote.ui.tree.FileAuthorityTree; |
||||||
|
import com.fr.file.filetree.FileNode; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.nx.app.designer.transform.BatchTransformUtil; |
||||||
|
|
||||||
|
import javax.swing.tree.DefaultTreeModel; |
||||||
|
import javax.swing.tree.TreeCellRenderer; |
||||||
|
import javax.swing.tree.TreePath; |
||||||
|
import java.awt.AlphaComposite; |
||||||
|
import java.awt.Graphics; |
||||||
|
import java.awt.Graphics2D; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.beans.PropertyChangeEvent; |
||||||
|
import java.beans.PropertyChangeListener; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.HashSet; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-01-13 |
||||||
|
*/ |
||||||
|
public class TransformFileTree extends FileAuthorityTree { |
||||||
|
private TransformPreparePane preparePane; |
||||||
|
private static final float CHECKBOX_ENABLE_OPACITY = 0.4f; |
||||||
|
|
||||||
|
private List<FileNode> transformedList = new ArrayList<FileNode>(); |
||||||
|
|
||||||
|
public TransformFileTree(TransformPreparePane preparePane) { |
||||||
|
this.preparePane = preparePane; |
||||||
|
} |
||||||
|
|
||||||
|
public void addTransformedList(List<FileNode> removeList) { |
||||||
|
this.transformedList.addAll(removeList); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected CheckBoxTree.Handler createHandler() { |
||||||
|
return new CheckBoxTree.Handler(this) { |
||||||
|
@Override |
||||||
|
public void mousePressed(MouseEvent e) { |
||||||
|
super.mousePressed(e); |
||||||
|
TreePath treePath = this.getTreePathForMouseEvent(e); |
||||||
|
if (treePath == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
CheckBoxTreeSelectionModel selectionModel = _tree.getCheckBoxTreeSelectionModel(); |
||||||
|
boolean selected = selectionModel.isPathSelected(treePath, selectionModel.isDigIn()); |
||||||
|
ExpandMutableTreeNode lastPathComponent = (ExpandMutableTreeNode) treePath.getLastPathComponent(); |
||||||
|
List<FileNode> selectedFileNodes = filterBatchFileNode(lastPathComponent); |
||||||
|
preparePane.removeTransformNode(selectedFileNodes); |
||||||
|
if (selected) { |
||||||
|
preparePane.addTransformNode(selectedFileNodes); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private List<FileNode> filterBatchFileNode(ExpandMutableTreeNode treeNode) { |
||||||
|
List<FileNode> fileNodeList = new ArrayList<>(); |
||||||
|
int childCount = treeNode.getChildCount(); |
||||||
|
if (childCount > 0) { |
||||||
|
loadPendingChildTreeNode(treeNode); |
||||||
|
int expandChildCount = treeNode.getChildCount(); |
||||||
|
for (int i = 0; i < expandChildCount; i++) { |
||||||
|
fileNodeList.addAll(filterBatchFileNode((ExpandMutableTreeNode) treeNode.getChildAt(i))); |
||||||
|
} |
||||||
|
} else { |
||||||
|
FileNode fileNode = (FileNode) treeNode.getUserObject(); |
||||||
|
boolean locked = fileNodeLocked(treeNode); |
||||||
|
if (!fileNode.isDirectory() && !locked) { |
||||||
|
fileNodeList.add((FileNode) treeNode.getUserObject()); |
||||||
|
} |
||||||
|
} |
||||||
|
return fileNodeList; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private boolean fileNodeLocked(ExpandMutableTreeNode treeNode) { |
||||||
|
Object userObj = treeNode.getUserObject(); |
||||||
|
if (userObj instanceof FileNode) { |
||||||
|
FileNode node = (FileNode) userObj; |
||||||
|
String lock = node.getLock(); |
||||||
|
if (lock != null && !node.getUserID().equals(lock)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
public void resetSelectedPaths() { |
||||||
|
CheckBoxTreeSelectionModel selectionModel = this.getCheckBoxTreeSelectionModel(); |
||||||
|
selectionModel.clearSelection(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void selectCheckBoxPaths(String[] paths) { |
||||||
|
if (paths == null || paths.length == 0) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
DefaultTreeModel model = (DefaultTreeModel) this.getModel(); |
||||||
|
ExpandMutableTreeNode treeNode = (ExpandMutableTreeNode) model.getRoot(); |
||||||
|
List<TreePath> res = new ArrayList<>(); |
||||||
|
for (String path : paths) { |
||||||
|
TreePath treePath = getSelectedPath(treeNode, path); |
||||||
|
if (treePath != null) { |
||||||
|
res.add(treePath); |
||||||
|
} |
||||||
|
} |
||||||
|
// 勾选中这些结点
|
||||||
|
this.getCheckBoxTreeSelectionModel().setSelectionPaths(res.toArray(new TreePath[0])); |
||||||
|
} |
||||||
|
|
||||||
|
private TreePath getSelectedPath(ExpandMutableTreeNode treeNode, String path) { |
||||||
|
//可以只在选中的path中选择
|
||||||
|
for (int i = 0, len = treeNode.getChildCount(); i < len; i++) { |
||||||
|
ExpandMutableTreeNode childTreeNode = (ExpandMutableTreeNode) treeNode.getChildAt(i); |
||||||
|
if (childTreeNode.getChildCount() > 0) { |
||||||
|
loadPendingChildTreeNode(childTreeNode); |
||||||
|
TreePath treePath = getSelectedPath(childTreeNode, path); |
||||||
|
if (treePath != null) { |
||||||
|
return treePath; |
||||||
|
} |
||||||
|
} |
||||||
|
if (!(childTreeNode.getUserObject() instanceof FileNode)) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
FileNode fileNode = (FileNode) childTreeNode.getUserObject(); |
||||||
|
if (ComparatorUtils.equals(path, fileNode.getEnvPath())) { |
||||||
|
DefaultTreeModel model = (DefaultTreeModel) this.getModel(); |
||||||
|
return new TreePath(model.getPathToRoot(childTreeNode)); |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public void removeSelectedPath(String path) { |
||||||
|
if (path == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
DefaultTreeModel model = (DefaultTreeModel) this.getModel(); |
||||||
|
ExpandMutableTreeNode treeNode = (ExpandMutableTreeNode) model.getRoot(); |
||||||
|
TreePath selectedPath = getSelectedPath(treeNode, path); |
||||||
|
if (selectedPath != null) { |
||||||
|
this.getCheckBoxTreeSelectionModel().removeSelectionPath(selectedPath); |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public FileNode[] listFile(String path) { |
||||||
|
// 支持插件扩展, 先从env的filter拿, 再从插件拿
|
||||||
|
Set<FileExtension> supportTypes = new HashSet<FileExtension>(); |
||||||
|
for (String temp : this.filter.getSupportedTypes()) { |
||||||
|
supportTypes.add(FileExtension.parse(temp)); |
||||||
|
} |
||||||
|
FileNode[] fileNodes = FRContext.getFileNodes().list( |
||||||
|
path, |
||||||
|
supportTypes.toArray(new FileExtension[supportTypes.size()]) |
||||||
|
); |
||||||
|
return BatchTransformUtil.filterTransformedFile(fileNodes, transformedList); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isCheckBoxEnabled(TreePath path) { |
||||||
|
ExpandMutableTreeNode treeNode = (ExpandMutableTreeNode) path.getLastPathComponent(); |
||||||
|
return !fileNodeLocked(treeNode); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected CheckBoxTreeCellRenderer createCellRenderer(TreeCellRenderer renderer) { |
||||||
|
final CheckBoxTreeCellRenderer checkBoxTreeCellRenderer = new CheckBoxTreeCellRenderer(renderer) { |
||||||
|
@Override |
||||||
|
public void paint(Graphics g) { |
||||||
|
if (!_checkBox.isEnabled()) { |
||||||
|
AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, CHECKBOX_ENABLE_OPACITY); |
||||||
|
((Graphics2D) g).setComposite(composite); |
||||||
|
} |
||||||
|
super.paint(g); |
||||||
|
} |
||||||
|
}; |
||||||
|
addPropertyChangeListener(CELL_RENDERER_PROPERTY, new PropertyChangeListener() { |
||||||
|
@Override |
||||||
|
public void propertyChange(PropertyChangeEvent evt) { |
||||||
|
checkBoxTreeCellRenderer.setActualTreeRenderer((TreeCellRenderer) evt.getNewValue()); |
||||||
|
} |
||||||
|
}); |
||||||
|
return checkBoxTreeCellRenderer; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,130 @@ |
|||||||
|
package com.fr.nx.app.designer.transform.ui; |
||||||
|
|
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.gui.icontainer.UIScrollPane; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.file.filetree.FileNode; |
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
import com.fr.nx.app.designer.toolbar.TransformResultInfo; |
||||||
|
import com.fr.nx.app.designer.transform.BatchTransformer; |
||||||
|
import com.fr.nx.app.designer.transform.UpdateCallBack; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.Box; |
||||||
|
import javax.swing.DefaultListModel; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Dialog; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-01-13 |
||||||
|
*/ |
||||||
|
public class TransformPreparePane extends JPanel { |
||||||
|
private static final String INITIAL_DISPLAY_TEXT = "0"; |
||||||
|
private PrepareTransformFileList fileList; |
||||||
|
private List<FileNode> selectedFileNodes; |
||||||
|
private UpdateProgressDialog dialog; |
||||||
|
private BatchTransformer transformer; |
||||||
|
private UpdateCallBack updateProgressPane; |
||||||
|
private Dialog parentDialog; |
||||||
|
private UILabel transCountLabel; |
||||||
|
private BatchTransformPane batchTransformPane; |
||||||
|
private UIButton startTransform; |
||||||
|
|
||||||
|
public TransformPreparePane(Dialog parentDialog, BatchTransformPane batchTransformPane) { |
||||||
|
this.batchTransformPane = batchTransformPane; |
||||||
|
this.parentDialog = parentDialog; |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
updateProgressPane = new UpdateProgressPane(this); |
||||||
|
transformer = new BatchTransformer(updateProgressPane); |
||||||
|
fileList = new PrepareTransformFileList(this); |
||||||
|
selectedFileNodes = new ArrayList<>(); |
||||||
|
initPane(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initPane() { |
||||||
|
JPanel transformPane = FRGUIPaneFactory.createTitledBorderPaneCenter( |
||||||
|
InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Template_To_Transform")); |
||||||
|
transformPane.setPreferredSize(new Dimension(270, 501)); |
||||||
|
startTransform = new UIButton(InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Transform_Start")); |
||||||
|
startTransform.setEnabled(false); |
||||||
|
addStartTransformListener(startTransform); |
||||||
|
transCountLabel = new UILabel(INITIAL_DISPLAY_TEXT); |
||||||
|
JPanel northPane = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane(); |
||||||
|
northPane.add(startTransform); |
||||||
|
northPane.add(Box.createHorizontalStrut(160)); |
||||||
|
northPane.add(transCountLabel); |
||||||
|
transformPane.add(northPane, BorderLayout.NORTH); |
||||||
|
UIScrollPane scrollPane = new UIScrollPane(fileList); |
||||||
|
scrollPane.setPreferredSize(new Dimension(260, 442)); |
||||||
|
scrollPane.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); |
||||||
|
transformPane.add(scrollPane, BorderLayout.CENTER); |
||||||
|
this.add(transformPane, BorderLayout.CENTER); |
||||||
|
} |
||||||
|
|
||||||
|
private void addStartTransformListener(UIButton startTransform) { |
||||||
|
startTransform.addActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
//开始转换
|
||||||
|
transformer.batchTransform(selectedFileNodes); |
||||||
|
displayProgressPane(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void displayProgressPane() { |
||||||
|
dialog = new UpdateProgressDialog(transformer, parentDialog, (JPanel) updateProgressPane); |
||||||
|
dialog.setVisible(true); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
public void addTransformNode(List<FileNode> fileNodeList) { |
||||||
|
selectedFileNodes.addAll(fileNodeList); |
||||||
|
buildFileList(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public void removeTransformNode(List<FileNode> fileNodeList) { |
||||||
|
selectedFileNodes.removeAll(fileNodeList); |
||||||
|
buildFileList(); |
||||||
|
} |
||||||
|
|
||||||
|
public void removeSelectedNode(FileNode fileNode) { |
||||||
|
selectedFileNodes.remove(fileNode); |
||||||
|
buildFileList(); |
||||||
|
this.batchTransformPane.removeSelectedNode(fileNode); |
||||||
|
} |
||||||
|
|
||||||
|
private void buildFileList() { |
||||||
|
DefaultListModel listModel = new DefaultListModel(); |
||||||
|
int count = selectedFileNodes.size(); |
||||||
|
for (int i = count - 1; i >= 0; i--) { |
||||||
|
listModel.addElement(selectedFileNodes.get(i)); |
||||||
|
} |
||||||
|
this.fileList.setModel(listModel); |
||||||
|
startTransform.setEnabled(selectedFileNodes.size() > 0); |
||||||
|
transCountLabel.setText(String.valueOf(selectedFileNodes.size())); |
||||||
|
} |
||||||
|
|
||||||
|
public void complete() { |
||||||
|
dialog.dialogExit(); |
||||||
|
updateProgressPane.reset(); |
||||||
|
Map<FileNode, TransformResultInfo> resultMap = transformer.getResults(); |
||||||
|
resetFileNodeList(); |
||||||
|
this.batchTransformPane.resetFilePaths(resultMap); |
||||||
|
} |
||||||
|
|
||||||
|
private void resetFileNodeList(){ |
||||||
|
this.selectedFileNodes.clear(); |
||||||
|
buildFileList(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,70 @@ |
|||||||
|
package com.fr.nx.app.designer.transform.ui; |
||||||
|
|
||||||
|
import com.fr.base.BaseUtils; |
||||||
|
import com.fr.design.constants.UIConstants; |
||||||
|
import com.fr.design.gui.ilist.UIList; |
||||||
|
import com.fr.design.gui.itree.filetree.FileTreeIcon; |
||||||
|
import com.fr.file.filetree.FileNode; |
||||||
|
import com.fr.nx.app.designer.toolbar.TransformResultInfo; |
||||||
|
|
||||||
|
import javax.swing.DefaultListModel; |
||||||
|
import javax.swing.Icon; |
||||||
|
import javax.swing.ListSelectionModel; |
||||||
|
import java.util.Iterator; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-01-13 |
||||||
|
*/ |
||||||
|
public class TransformResultList extends UIList { |
||||||
|
private Map<FileNode, TransformResultInfo> resultMap; |
||||||
|
private static final Icon FAILED_ICON = BaseUtils.readIcon("/com/fr/nx/app/designer/transform/transform_failed.png"); |
||||||
|
private static final Icon SUCCESS_ICON = BaseUtils.readIcon("/com/fr/nx/app/designer/transform/transform_success.png"); |
||||||
|
private static final Icon UNSUPPORT_ICON = BaseUtils.readIcon("/com/fr/nx/app/designer/transform/transform_unsupport.png"); |
||||||
|
|
||||||
|
public TransformResultList() { |
||||||
|
super(); |
||||||
|
this.setBackground(UIConstants.TREE_BACKGROUND); |
||||||
|
this.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); |
||||||
|
DefaultListModel listModel = new DefaultListModel(); |
||||||
|
this.setModel(listModel); |
||||||
|
this.setCellRenderer(new UIListControlCellRenderer() { |
||||||
|
@Override |
||||||
|
protected Icon getLeftLabelIcon(Object value) { |
||||||
|
if (value instanceof FileNode) { |
||||||
|
return FileTreeIcon.getIcon((FileNode) value); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected Icon getRightLabelIcon(Object value) { |
||||||
|
if (value != null) { |
||||||
|
TransformResultInfo resultInfo = resultMap.get(value); |
||||||
|
switch (resultInfo.getResult()) { |
||||||
|
case FAILED: |
||||||
|
return FAILED_ICON; |
||||||
|
case SUCCESS: |
||||||
|
return SUCCESS_ICON; |
||||||
|
case UNSUPPORT: |
||||||
|
return UNSUPPORT_ICON; |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
public void populate(Map<FileNode, TransformResultInfo> resultMap) { |
||||||
|
this.resultMap = resultMap; |
||||||
|
DefaultListModel listModel = new DefaultListModel(); |
||||||
|
Iterator<Map.Entry<FileNode, TransformResultInfo>> iterator = resultMap.entrySet().iterator(); |
||||||
|
while (iterator.hasNext()) { |
||||||
|
Map.Entry<FileNode, TransformResultInfo> entry = iterator.next(); |
||||||
|
FileNode key = entry.getKey(); |
||||||
|
listModel.addElement(key); |
||||||
|
} |
||||||
|
this.setModel(listModel); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,110 @@ |
|||||||
|
package com.fr.nx.app.designer.transform.ui; |
||||||
|
|
||||||
|
import com.fr.design.gui.icontainer.UIScrollPane; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.gui.itextarea.UITextArea; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.file.filetree.FileNode; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
import com.fr.nx.app.designer.toolbar.TransformResult; |
||||||
|
import com.fr.nx.app.designer.toolbar.TransformResultInfo; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.event.ListSelectionEvent; |
||||||
|
import javax.swing.event.ListSelectionListener; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.util.Iterator; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-01-10 |
||||||
|
*/ |
||||||
|
public class TransformResultPane extends JPanel { |
||||||
|
private TransformResultList resultList; |
||||||
|
private UITextArea resultInfo; |
||||||
|
private Map<FileNode, TransformResultInfo> resultMap; |
||||||
|
private UILabel successTip; |
||||||
|
|
||||||
|
public TransformResultPane() { |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
initPane(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initPane() { |
||||||
|
JPanel resultPane = FRGUIPaneFactory.createTitledBorderPaneCenter( |
||||||
|
InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Transform_Result")); |
||||||
|
JPanel northPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
resultList = new TransformResultList(); |
||||||
|
addValueChangeListener(); |
||||||
|
UIScrollPane scrollPane = new UIScrollPane(resultList); |
||||||
|
scrollPane.setPreferredSize(new Dimension(260, 260)); |
||||||
|
scrollPane.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); |
||||||
|
successTip = new UILabel(""); |
||||||
|
successTip.setBorder(BorderFactory.createEmptyBorder(5, 150, 5, 10)); |
||||||
|
northPane.add(successTip, BorderLayout.NORTH); |
||||||
|
northPane.add(scrollPane, BorderLayout.CENTER); |
||||||
|
resultPane.add(northPane); |
||||||
|
|
||||||
|
JPanel resultInfoPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
resultInfoPane.setPreferredSize(new Dimension(270, 165)); |
||||||
|
resultInfoPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 10, 5)); |
||||||
|
UILabel transformLogLabel = new UILabel( |
||||||
|
InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Transform_Logs")); |
||||||
|
transformLogLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0)); |
||||||
|
resultInfoPane.add(transformLogLabel, BorderLayout.NORTH); |
||||||
|
resultInfo = new UITextArea(); |
||||||
|
resultInfo.setBackground(Color.white); |
||||||
|
resultInfo.setLineWrap(true); |
||||||
|
resultInfo.setWrapStyleWord(true); |
||||||
|
resultInfo.setEditable(false); |
||||||
|
UIScrollPane resultScrollPane = new UIScrollPane(resultInfo); |
||||||
|
resultInfoPane.add(resultScrollPane, BorderLayout.CENTER); |
||||||
|
this.add(resultPane, BorderLayout.NORTH); |
||||||
|
this.add(resultInfoPane, BorderLayout.CENTER); |
||||||
|
} |
||||||
|
|
||||||
|
private void addValueChangeListener() { |
||||||
|
resultList.addListSelectionListener(new ListSelectionListener() { |
||||||
|
@Override |
||||||
|
public void valueChanged(ListSelectionEvent e) { |
||||||
|
FileNode selectedValue = (FileNode) resultList.getSelectedValue(); |
||||||
|
if (resultInfo != null && selectedValue != null) { |
||||||
|
TransformResultInfo result = resultMap.get(selectedValue); |
||||||
|
resultInfo.setText(result.getTransformLog()); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
public void populate(Map<FileNode, TransformResultInfo> resultMap) { |
||||||
|
int count = getSuccessCount(resultMap); |
||||||
|
String tip = InterProviderFactory.getProvider().getLocText( |
||||||
|
"Fine-Plugin_Engine_Transform_Result_Tip", String.valueOf(count)); |
||||||
|
successTip.setText(tip); |
||||||
|
this.resultMap = resultMap; |
||||||
|
resultList.populate(resultMap); |
||||||
|
if (resultList.getModel().getSize() > 0) { |
||||||
|
resultList.setSelectedIndex(0); |
||||||
|
FileNode firstResult = (FileNode) resultList.getModel().getElementAt(0); |
||||||
|
resultInfo.setText(resultMap.get(firstResult).getTransformLog()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private int getSuccessCount(Map<FileNode, TransformResultInfo> resultMap) { |
||||||
|
int count = 0; |
||||||
|
Iterator<Map.Entry<FileNode, TransformResultInfo>> iterator = resultMap.entrySet().iterator(); |
||||||
|
while (iterator.hasNext()) { |
||||||
|
Map.Entry<FileNode, TransformResultInfo> entry = iterator.next(); |
||||||
|
TransformResultInfo resultInfo = entry.getValue(); |
||||||
|
if (ComparatorUtils.equals(TransformResult.SUCCESS, resultInfo.getResult())) { |
||||||
|
count++; |
||||||
|
} |
||||||
|
} |
||||||
|
return count; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,86 @@ |
|||||||
|
package com.fr.nx.app.designer.transform.ui; |
||||||
|
|
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import sun.swing.DefaultLookup; |
||||||
|
|
||||||
|
import javax.swing.Icon; |
||||||
|
import javax.swing.JList; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.ListCellRenderer; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Dimension; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-01-14 |
||||||
|
*/ |
||||||
|
public class UIListControlCellRenderer extends JPanel implements ListCellRenderer { |
||||||
|
private UILabel content; |
||||||
|
private UILabel controlLabel; |
||||||
|
private Color initialLabelForeground; |
||||||
|
|
||||||
|
public UIListControlCellRenderer() { |
||||||
|
initPane(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initPane() { |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
content = new UILabel(); |
||||||
|
initialLabelForeground = content.getForeground(); |
||||||
|
controlLabel = new UILabel(); |
||||||
|
controlLabel.setPreferredSize(new Dimension(16, 20)); |
||||||
|
this.add(content, BorderLayout.CENTER); |
||||||
|
this.add(controlLabel, BorderLayout.EAST); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { |
||||||
|
setComponentOrientation(list.getComponentOrientation()); |
||||||
|
Color bg = null; |
||||||
|
Color fg = null; |
||||||
|
|
||||||
|
JList.DropLocation dropLocation = list.getDropLocation(); |
||||||
|
if (dropLocation != null |
||||||
|
&& !dropLocation.isInsert() |
||||||
|
&& dropLocation.getIndex() == index) { |
||||||
|
|
||||||
|
bg = DefaultLookup.getColor(this, ui, "List.dropCellBackground"); |
||||||
|
fg = DefaultLookup.getColor(this, ui, "List.dropCellForeground"); |
||||||
|
|
||||||
|
isSelected = true; |
||||||
|
} |
||||||
|
|
||||||
|
if (isSelected) { |
||||||
|
setBackground(bg == null ? list.getSelectionBackground() : bg); |
||||||
|
setForeground(fg == null ? list.getSelectionForeground() : fg); |
||||||
|
content.setForeground(Color.WHITE); |
||||||
|
|
||||||
|
} else { |
||||||
|
setBackground(list.getBackground()); |
||||||
|
setForeground(list.getForeground()); |
||||||
|
content.setForeground(initialLabelForeground); |
||||||
|
} |
||||||
|
|
||||||
|
content.setText((value == null) ? StringUtils.EMPTY : value.toString()); |
||||||
|
Icon leftLabelIcon = getLeftLabelIcon(value); |
||||||
|
if (leftLabelIcon != null) { |
||||||
|
content.setIcon(leftLabelIcon); |
||||||
|
} |
||||||
|
Icon rightLabelIcon = getRightLabelIcon(value); |
||||||
|
if (rightLabelIcon != null) { |
||||||
|
controlLabel.setIcon(rightLabelIcon); |
||||||
|
} |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
protected Icon getLeftLabelIcon(Object value) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
protected Icon getRightLabelIcon(Object value) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,70 @@ |
|||||||
|
package com.fr.nx.app.designer.transform.ui; |
||||||
|
|
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.utils.gui.GUICoreUtils; |
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
import com.fr.nx.app.designer.transform.BatchTransformer; |
||||||
|
|
||||||
|
import javax.swing.JDialog; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Dialog; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.awt.event.WindowAdapter; |
||||||
|
import java.awt.event.WindowEvent; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2019-12-19 |
||||||
|
*/ |
||||||
|
public class UpdateProgressDialog extends JDialog implements ActionListener { |
||||||
|
|
||||||
|
private UIButton pauseBtn; |
||||||
|
private BatchTransformer transformer; |
||||||
|
|
||||||
|
public UpdateProgressDialog(BatchTransformer transformer, Dialog parent, JPanel contentPane) { |
||||||
|
super(parent, true); |
||||||
|
this.transformer = transformer; |
||||||
|
initPane(contentPane); |
||||||
|
} |
||||||
|
|
||||||
|
private void initPane(JPanel contentPane) { |
||||||
|
this.setTitle(InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Format_Transform")); |
||||||
|
this.setResizable(false); |
||||||
|
JPanel defaultPane = FRGUIPaneFactory.createBorderLayout_L_Pane(); |
||||||
|
this.setContentPane(defaultPane); |
||||||
|
|
||||||
|
pauseBtn = new UIButton(InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Transform_Suspend")); |
||||||
|
pauseBtn.addActionListener(this); |
||||||
|
JPanel buttonPanel = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); |
||||||
|
buttonPanel.add(pauseBtn); |
||||||
|
|
||||||
|
defaultPane.add(contentPane, BorderLayout.CENTER); |
||||||
|
defaultPane.add(buttonPanel, BorderLayout.SOUTH); |
||||||
|
|
||||||
|
addWindowListener(new WindowAdapter() { |
||||||
|
@Override |
||||||
|
public void windowClosing(WindowEvent e) { |
||||||
|
transformer.shutDown(); |
||||||
|
dialogExit(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
this.getRootPane().setDefaultButton(pauseBtn); |
||||||
|
|
||||||
|
this.setSize(new Dimension(262, 122)); |
||||||
|
GUICoreUtils.centerWindow(this); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
transformer.shutDown(); |
||||||
|
dialogExit(); |
||||||
|
} |
||||||
|
|
||||||
|
public void dialogExit() { |
||||||
|
this.dispose(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,72 @@ |
|||||||
|
package com.fr.nx.app.designer.transform.ui; |
||||||
|
|
||||||
|
|
||||||
|
import com.fr.base.BaseUtils; |
||||||
|
import com.fr.decision.update.data.UpdateConstants; |
||||||
|
import com.fr.design.dialog.BasicPane; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
import com.fr.nx.app.designer.transform.UpdateCallBack; |
||||||
|
import com.sun.java.swing.plaf.motif.MotifProgressBarUI; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.JProgressBar; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Dimension; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2019-12-11 |
||||||
|
*/ |
||||||
|
public class UpdateProgressPane extends BasicPane implements UpdateCallBack { |
||||||
|
private TransformPreparePane contentPane; |
||||||
|
private JProgressBar progressBar; |
||||||
|
|
||||||
|
public UpdateProgressPane(TransformPreparePane contentPane) { |
||||||
|
this.contentPane = contentPane; |
||||||
|
initPane(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initPane() { |
||||||
|
this.setPreferredSize(new Dimension(262, 60)); |
||||||
|
UILabel icon = new UILabel(BaseUtils.readIcon("/com/fr/nx/app/designer/transform/transforming.png")); |
||||||
|
icon.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10)); |
||||||
|
this.add(icon, BorderLayout.WEST); |
||||||
|
JPanel centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
UILabel title = new UILabel(InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Transforming")); |
||||||
|
title.setBorder(BorderFactory.createEmptyBorder(0, 0, 8, 0)); |
||||||
|
centerPane.add(title, BorderLayout.NORTH); |
||||||
|
progressBar = new JProgressBar(); |
||||||
|
progressBar.setUI(new MotifProgressBarUI()); |
||||||
|
progressBar.setForeground(UpdateConstants.BAR_COLOR); |
||||||
|
centerPane.add(progressBar, BorderLayout.CENTER); |
||||||
|
this.add(centerPane, BorderLayout.CENTER); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void updateProgress(double progress) { |
||||||
|
progressBar.setValue((int) (progress * 100)); |
||||||
|
if (ComparatorUtils.equals(progress, 1D)) { |
||||||
|
contentPane.complete(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void shutDown() { |
||||||
|
contentPane.complete(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void reset() { |
||||||
|
progressBar.setValue(0); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String title4PopupWindow() { |
||||||
|
return InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Transform_Suspend"); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
package com.fr.nx.app.designer.utils; |
||||||
|
|
||||||
|
import com.fr.design.mainframe.JTemplate; |
||||||
|
import com.fr.file.FILE; |
||||||
|
import com.fr.file.filetree.FileNode; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.main.impl.WorkBook; |
||||||
|
import com.fr.nx.app.designer.toolbar.TemplateTransformer; |
||||||
|
import com.fr.nx.app.designer.toolbar.TransformResult; |
||||||
|
import com.fr.nx.app.designer.toolbar.TransformResultInfo; |
||||||
|
import com.fr.workspace.WorkContext; |
||||||
|
|
||||||
|
import java.io.InputStream; |
||||||
|
|
||||||
|
import static com.fr.base.extension.FileExtension.CPT; |
||||||
|
import static com.fr.base.extension.FileExtension.CPTX; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2019-12-04 |
||||||
|
*/ |
||||||
|
public class CompileTransformUtil { |
||||||
|
|
||||||
|
|
||||||
|
public static TransformResultInfo compileFile(FileNode fileNode) { |
||||||
|
long start = System.currentTimeMillis(); |
||||||
|
InputStream in = WorkContext.getWorkResource().openStream(fileNode.getEnvPath()); |
||||||
|
WorkBook workBook = new WorkBook(); |
||||||
|
TransformResultInfo result = null; |
||||||
|
try { |
||||||
|
workBook.readStream(in); |
||||||
|
FILE file = TemplateTransformer.createOutputFile(fileNode.getEnvPath(), CPT.getSuffix(), CPTX.getSuffix()); |
||||||
|
result = TemplateTransformer.compileCPTX(workBook, file); |
||||||
|
} catch (Exception ignore) { |
||||||
|
result = TransformResultInfo.generateResult(TransformResult.FAILED); |
||||||
|
} |
||||||
|
long end = System.currentTimeMillis(); |
||||||
|
FineLoggerFactory.getLogger().debug(fileNode.getName() + " compile cost : " + (end - start) +" ms "); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static FILE getTargetFile(JTemplate jTemplate, TemplateTransformer transformer) { |
||||||
|
FILE file = null; |
||||||
|
if (ComparatorUtils.equals(TemplateTransformer.TO_CPTX, transformer)) { |
||||||
|
file = TemplateTransformer.createOutputFile(jTemplate.getEditingFILE().getPath(), |
||||||
|
CPT.getSuffix(), CPTX.getSuffix()); |
||||||
|
|
||||||
|
} else if (ComparatorUtils.equals(TemplateTransformer.TO_CPT, transformer)) { |
||||||
|
file = TemplateTransformer.createOutputFile(jTemplate.getEditingFILE().getPath(), |
||||||
|
CPTX.getSuffix(), CPT.getSuffix()); |
||||||
|
} |
||||||
|
return file; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,79 @@ |
|||||||
|
package com.fr.nx.app.designer.utils; |
||||||
|
|
||||||
|
import com.fr.file.FILE; |
||||||
|
import com.fr.general.CommonIOUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.main.impl.WorkBook; |
||||||
|
import com.fr.nx.marshal.impl.xml.DefaultXMLObjectUnmarshaler; |
||||||
|
import com.fr.nx.marshal.util.MarshalUtil; |
||||||
|
import com.fr.nx.cptx.entry.metadata.CptxMetadata; |
||||||
|
import com.fr.nx.cptx.io.handle.impl.OriginCptProvider; |
||||||
|
import com.fr.nx.cptx.marshal.util.CptxMarshalUtil; |
||||||
|
import com.fr.nx.cptx.utils.CptxFileUtils; |
||||||
|
import com.fr.stable.EncodeConstants; |
||||||
|
import com.fr.stable.StableUtils; |
||||||
|
import com.fr.stable.xml.XMLableReader; |
||||||
|
import com.fr.workspace.WorkContext; |
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream; |
||||||
|
import java.io.InputStream; |
||||||
|
import java.io.InputStreamReader; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by loy on 2021/1/18. |
||||||
|
* |
||||||
|
* <p>用于设计器的cptx的一些工具类 |
||||||
|
* <p> |
||||||
|
*/ |
||||||
|
public class DesignerCptxFileUtils { |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据file来获取cptx中的cpt |
||||||
|
* @param file |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static WorkBook getWorkBook(final FILE file){ |
||||||
|
try (InputStream input = file.asInputStream(); |
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { |
||||||
|
CommonIOUtils.copyBinaryTo(input, outputStream); |
||||||
|
OriginCptProvider provider = new OriginCptProvider(outputStream.toByteArray()); |
||||||
|
return CptxFileUtils.getWorkBook(provider); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取模板的元数据 |
||||||
|
* @param file |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static CptxMetadata getMetadata(FILE file){ |
||||||
|
try { |
||||||
|
String metadataPath = StableUtils.pathJoin(generateCompileDir(file), CptxMarshalUtil.NAME_METADATA); |
||||||
|
if(!WorkContext.getWorkResource().exist(metadataPath)){ |
||||||
|
return null; |
||||||
|
} |
||||||
|
InputStream metadataInput = WorkContext.getWorkResource().openStream(metadataPath); |
||||||
|
XMLableReader reader = XMLableReader.createXMLableReader( |
||||||
|
new InputStreamReader(metadataInput, EncodeConstants.ENCODING_UTF_8)); |
||||||
|
CptxMetadata metadata = (CptxMetadata) new DefaultXMLObjectUnmarshaler().unmarshal( |
||||||
|
MarshalUtil.createMarshalableExtra(CptxMetadata.class), reader); |
||||||
|
return metadata; |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据文件获取编译后的文件夹绝对路径,比如原文件位于reportlets/test/merge.cptx,转化后为evn://assets/engine/test/merge文件夹
|
||||||
|
* @param file |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static String generateCompileDir(FILE file){ |
||||||
|
String filePath = file.getPath(); |
||||||
|
return CptxFileUtils.generateCompileDir(filePath); |
||||||
|
} |
||||||
|
} |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 758 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 864 B |
After Width: | Height: | Size: 840 B |
After Width: | Height: | Size: 804 B |
After Width: | Height: | Size: 660 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,239 @@ |
|||||||
|
package com.fr.nx.app.designer.toolbar; |
||||||
|
|
||||||
|
import com.fr.base.Parameter; |
||||||
|
import com.fr.base.chart.BaseChartCollection; |
||||||
|
import com.fr.base.io.XMLEncryptKey; |
||||||
|
import com.fr.base.io.XMLEncryptUtils; |
||||||
|
import com.fr.base.iofile.IOFileAttrMarkManager; |
||||||
|
import com.fr.base.parameter.ParameterUI; |
||||||
|
import com.fr.chart.chartattr.ChartCollection; |
||||||
|
import com.fr.config.dao.DaoContext; |
||||||
|
import com.fr.config.dao.impl.LocalClassHelperDao; |
||||||
|
import com.fr.config.dao.impl.LocalEntityDao; |
||||||
|
import com.fr.config.dao.impl.LocalXmlEntityDao; |
||||||
|
import com.fr.file.MemFILE; |
||||||
|
import com.fr.form.DefaultFormOperator; |
||||||
|
import com.fr.form.FormOperator; |
||||||
|
import com.fr.form.main.ExtraFormClassManager; |
||||||
|
import com.fr.form.main.Form; |
||||||
|
import com.fr.form.main.FormHyperlink; |
||||||
|
import com.fr.form.main.parameter.FormParameterUI; |
||||||
|
import com.fr.form.parameter.FormSubmitButton; |
||||||
|
import com.fr.form.plugin.DefaultSwitcherImpl; |
||||||
|
import com.fr.general.xml.GeneralXMLTools; |
||||||
|
import com.fr.io.EncryptUtils; |
||||||
|
import com.fr.js.FormHyperlinkProvider; |
||||||
|
import com.fr.main.impl.WorkBook; |
||||||
|
import com.fr.nx.calculable.Calculable; |
||||||
|
import com.fr.nx.calculable.type.ConstantCalculable; |
||||||
|
import com.fr.nx.cell.CellKey; |
||||||
|
import com.fr.nx.cell.CellTemplate; |
||||||
|
import com.fr.nx.cptx.cache.CptxTemplatePool; |
||||||
|
import com.fr.nx.cptx.entry.CptxTemplate; |
||||||
|
import com.fr.nx.cptx.resource.ImageResourceRef; |
||||||
|
import com.fr.page.BaseSinglePagePrintable; |
||||||
|
import com.fr.page.BaseSingleReportCache; |
||||||
|
import com.fr.page.ClippedChartPage; |
||||||
|
import com.fr.page.ClippedECPage; |
||||||
|
import com.fr.page.ClippedPageProvider; |
||||||
|
import com.fr.page.PDF2Painter; |
||||||
|
import com.fr.page.PageGeneratorProvider; |
||||||
|
import com.fr.page.PagePainter; |
||||||
|
import com.fr.page.PagePainterProvider; |
||||||
|
import com.fr.page.PageSetChainProvider; |
||||||
|
import com.fr.page.PageSetProvider; |
||||||
|
import com.fr.page.PageXmlOperator; |
||||||
|
import com.fr.page.PageXmlProvider; |
||||||
|
import com.fr.page.PaperSettingProvider; |
||||||
|
import com.fr.page.ReportPage; |
||||||
|
import com.fr.page.ReportPageAttrProvider; |
||||||
|
import com.fr.page.ReportPageProvider; |
||||||
|
import com.fr.page.SheetPage; |
||||||
|
import com.fr.page.SinglePagePrintable; |
||||||
|
import com.fr.page.SingleReportCache; |
||||||
|
import com.fr.page.generator.PaginateReportPageGenerator; |
||||||
|
import com.fr.page.generator.PolyReportPageGenerator; |
||||||
|
import com.fr.page.generator.SheetPageGenerator; |
||||||
|
import com.fr.page.pageset.ArrayPageSet; |
||||||
|
import com.fr.page.pageset.PageSetChain; |
||||||
|
import com.fr.page.stable.PaperSetting; |
||||||
|
import com.fr.page.stable.ReportPageAttr; |
||||||
|
import com.fr.plugin.attr.CalculatorAttrMark; |
||||||
|
import com.fr.runtime.FineRuntime; |
||||||
|
import com.fr.stable.EssentialUtils; |
||||||
|
import com.fr.stable.bridge.BridgeMark; |
||||||
|
import com.fr.stable.bridge.StableFactory; |
||||||
|
import com.fr.stable.fun.WidgetSwitcher; |
||||||
|
import com.fr.stable.module.Module; |
||||||
|
import com.fr.stable.plugin.ExtraFormClassManagerProvider; |
||||||
|
import com.fr.transaction.Configurations; |
||||||
|
import com.fr.transaction.LocalConfigurationHelper; |
||||||
|
import com.fr.xml.ReportXMLUtils; |
||||||
|
import org.easymock.EasyMock; |
||||||
|
import org.easymock.IArgumentMatcher; |
||||||
|
import org.junit.Assert; |
||||||
|
import org.junit.Before; |
||||||
|
import org.junit.BeforeClass; |
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.runner.RunWith; |
||||||
|
import org.powermock.api.easymock.PowerMock; |
||||||
|
import org.powermock.core.classloader.annotations.PowerMockIgnore; |
||||||
|
import org.powermock.core.classloader.annotations.PrepareForTest; |
||||||
|
import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; |
||||||
|
import org.powermock.modules.junit4.PowerMockRunner; |
||||||
|
import org.powermock.reflect.Whitebox; |
||||||
|
|
||||||
|
import java.io.InputStream; |
||||||
|
|
||||||
|
@RunWith(PowerMockRunner.class) |
||||||
|
@PrepareForTest({CptxTemplatePool.class, XMLEncryptUtils.class}) |
||||||
|
@SuppressStaticInitializationFor({"com.fr.nx.cptx.cache.CptxTemplatePool", "com.fr.base.io.XMLEncryptUtils"}) |
||||||
|
@PowerMockIgnore({"com.sun.tools.attach.*", "sun.tools.attach.*"}) |
||||||
|
public class TemplateTransformerDebugTest { |
||||||
|
|
||||||
|
@BeforeClass |
||||||
|
public static void beforeClass() { |
||||||
|
System.setProperty("apple.awt.UIElement", "true"); |
||||||
|
StableFactory.registerXMLDescription(ReportPageAttrProvider.XML_TAG, new ReportPageAttr()); |
||||||
|
StableFactory.registerMarkedClass(ReportPageProvider.XML_TAG, ReportPage.class); |
||||||
|
StableFactory.registerMarkedClass(PaperSettingProvider.XML_TAG, PaperSetting.class); |
||||||
|
StableFactory.registerMarkedClass(ReportPageProvider.XML_TAG_4_SHEET, SheetPage.class); |
||||||
|
StableFactory.registerMarkedClass(PagePainterProvider.XML_TAG, PagePainter.class); |
||||||
|
StableFactory.registerMarkedClass(PageSetChainProvider.XML_TAG, PageSetChain.class); |
||||||
|
StableFactory.registerMarkedClass(PageXmlProvider.XML_TAG, PageXmlOperator.class); |
||||||
|
StableFactory.registerMarkedClass(BaseSinglePagePrintable.XML_TAG, SinglePagePrintable.class); |
||||||
|
StableFactory.registerMarkedClass(BaseSingleReportCache.XML_TAG, SingleReportCache.class); |
||||||
|
StableFactory.registerMarkedClass(PageSetProvider.XML_TAG_4_ARRAY, ArrayPageSet.class); |
||||||
|
StableFactory.registerMarkedClass(ClippedPageProvider.XML_TAG_EC, ClippedECPage.class); |
||||||
|
StableFactory.registerMarkedClass(ClippedPageProvider.XML_TAG_CHART, ClippedChartPage.class); |
||||||
|
StableFactory.registerMarkedClass(PageGeneratorProvider.XML_TAG_PAGE, PaginateReportPageGenerator.class); |
||||||
|
StableFactory.registerMarkedClass(PageGeneratorProvider.XML_TAG_POLY, PolyReportPageGenerator.class); |
||||||
|
StableFactory.registerMarkedClass(PageGeneratorProvider.XML_TAG_SHEET, SheetPageGenerator.class); |
||||||
|
StableFactory.registerMarkedClass(PagePainterProvider.XML_TAG_4_PDF, PDF2Painter.class); |
||||||
|
StableFactory.registerMarkedClass(BridgeMark.SUBMIT_BUTTON, FormSubmitButton.class); |
||||||
|
StableFactory.registerMarkedClass(FormOperator.MARK_STRING, DefaultFormOperator.class); |
||||||
|
StableFactory.registerMarkedClass(Module.FORM_MODULE, Form.class); |
||||||
|
StableFactory.registerMarkedClass(ParameterUI.FORM_XML_TAG, FormParameterUI.class); |
||||||
|
StableFactory.registerMarkedClass(FormHyperlinkProvider.XML_TAG, FormHyperlink.class); |
||||||
|
StableFactory.registerMarkedObject(WidgetSwitcher.XML_TAG, new DefaultSwitcherImpl()); |
||||||
|
StableFactory.registerMarkedClass(ExtraFormClassManagerProvider.XML_TAG, ExtraFormClassManager.class); |
||||||
|
StableFactory.registerXMLDescription(BaseChartCollection.XML_TAG, new ChartCollection()); |
||||||
|
StableFactory.registerXMLDescription(Parameter.XML_TAG, new Parameter()); |
||||||
|
FineRuntime.start(); |
||||||
|
GeneralXMLTools.Object_Tokenizer = new ReportXMLUtils.ReportObjectTokenizer(); |
||||||
|
GeneralXMLTools.Object_XML_Writer_Finder = new ReportXMLUtils.ReportObjectXMLWriterFinder(); |
||||||
|
DaoContext.setEntityDao(new LocalEntityDao()); |
||||||
|
DaoContext.setClassHelperDao(new LocalClassHelperDao()); |
||||||
|
DaoContext.setXmlEntityDao(new LocalXmlEntityDao()); |
||||||
|
Configurations.setHelper(new LocalConfigurationHelper()); |
||||||
|
|
||||||
|
IOFileAttrMarkManager.register(new CalculatorAttrMark()); |
||||||
|
} |
||||||
|
|
||||||
|
@Before |
||||||
|
public void before() { |
||||||
|
Whitebox.setInternalState(XMLEncryptUtils.class, "KEY", new XMLEncryptKey()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testUnsupportedCompile() { |
||||||
|
WorkBook workbook = readCpt("read-write-expand-order.cpt"); |
||||||
|
|
||||||
|
CptxTemplatePool pool = EasyMock.mock(CptxTemplatePool.class); |
||||||
|
PowerMock.mockStatic(CptxTemplatePool.class); |
||||||
|
EasyMock.expect(CptxTemplatePool.getInstance()).andReturn(pool).anyTimes(); |
||||||
|
|
||||||
|
PowerMock.replay(CptxTemplatePool.class); |
||||||
|
pool.addCptxTemplate(EasyMock.anyString(), matchUnsupportedWebPreviewCptxTemplate()); |
||||||
|
EasyMock.expectLastCall().once(); |
||||||
|
|
||||||
|
EasyMock.replay(pool); |
||||||
|
TemplateTransformer.compileCPTX(workbook, new MemFILE("read-write-expand-order.cpt")); |
||||||
|
|
||||||
|
EasyMock.verify(pool); |
||||||
|
PowerMock.verify(CptxTemplatePool.class); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testImageRefCompile() { |
||||||
|
WorkBook workbook = readCpt("read-write-image-ref.cpt"); |
||||||
|
|
||||||
|
CptxTemplatePool pool = EasyMock.mock(CptxTemplatePool.class); |
||||||
|
PowerMock.mockStatic(CptxTemplatePool.class); |
||||||
|
EasyMock.expect(CptxTemplatePool.getInstance()).andReturn(pool).anyTimes(); |
||||||
|
|
||||||
|
PowerMock.replay(CptxTemplatePool.class); |
||||||
|
pool.addCptxTemplate(EasyMock.anyString(), matchImageRefWebPreviewCptxTemplate()); |
||||||
|
EasyMock.expectLastCall().once(); |
||||||
|
|
||||||
|
EasyMock.replay(pool); |
||||||
|
TemplateTransformer.compileCPTX(workbook, new MemFILE("read-write-image-ref.cpt")); |
||||||
|
|
||||||
|
EasyMock.verify(pool); |
||||||
|
PowerMock.verify(CptxTemplatePool.class); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private CptxTemplate matchImageRefWebPreviewCptxTemplate() { |
||||||
|
EasyMock.reportMatcher(new IArgumentMatcher() { |
||||||
|
@Override |
||||||
|
public boolean matches(Object argument) { |
||||||
|
if (argument instanceof CptxTemplate) { |
||||||
|
CptxTemplate cptxTemplate = (CptxTemplate) argument; |
||||||
|
Assert.assertNotNull(cptxTemplate.getTemplate()); |
||||||
|
Assert.assertNotNull(cptxTemplate.getTemplate().getCompileResult()); |
||||||
|
Assert.assertEquals(1, cptxTemplate.getTemplate().getCompileResult().getCellBlocks().length); |
||||||
|
Assert.assertNotNull(cptxTemplate.getTemplate().getCompileResult().getCellBlocks()[0].getDataStructure()); |
||||||
|
Assert.assertNotNull(cptxTemplate.getTemplate().getCompileResult().getCellBlocks()[0].getDataStructure().getCells()); |
||||||
|
CellTemplate cellTemplate = cptxTemplate.getTemplate().getCompileResult().getCellBlocks()[0].getDataStructure().getCells().get(CellKey.fromString("A2")); |
||||||
|
Assert.assertNotNull(cellTemplate); |
||||||
|
Calculable calculable = cellTemplate.getCalculable(); |
||||||
|
ConstantCalculable constantCalculable = calculable.unWrap(ConstantCalculable.KEY); |
||||||
|
Assert.assertNotNull(constantCalculable); |
||||||
|
Assert.assertTrue(constantCalculable.get() instanceof ImageResourceRef); |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void appendTo(StringBuffer buffer) { |
||||||
|
buffer.append("cptx template should be previewed on the web side but not."); |
||||||
|
} |
||||||
|
}); |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
private CptxTemplate matchUnsupportedWebPreviewCptxTemplate() { |
||||||
|
EasyMock.reportMatcher(new IArgumentMatcher() { |
||||||
|
@Override |
||||||
|
public boolean matches(Object argument) { |
||||||
|
if (argument instanceof CptxTemplate) { |
||||||
|
CptxTemplate cptxTemplate = (CptxTemplate) argument; |
||||||
|
Assert.assertEquals("unsupported feature: sort after expand", |
||||||
|
cptxTemplate.getMetadata().getFailMessage()); |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void appendTo(StringBuffer buffer) { |
||||||
|
buffer.append("should find unsupported error message but not"); |
||||||
|
} |
||||||
|
}); |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
private static WorkBook readCpt(String subPath) { |
||||||
|
InputStream is = TemplateTransformerDebugTest.class.getClassLoader().getResourceAsStream("cpt/" + subPath); |
||||||
|
WorkBook wb = new WorkBook(); |
||||||
|
try { |
||||||
|
wb.readStream(EncryptUtils.decodeInputStream(is)); |
||||||
|
} catch (Exception e) { |
||||||
|
throw new RuntimeException(e); |
||||||
|
} |
||||||
|
return wb; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,85 @@ |
|||||||
|
package com.fr.nx.app.designer.toolbar; |
||||||
|
|
||||||
|
import com.fr.base.FRContext; |
||||||
|
import com.fr.base.operator.common.CommonOperator; |
||||||
|
import com.fr.file.FILE; |
||||||
|
import com.fr.file.filetree.FileNodes; |
||||||
|
import com.fr.invoke.Reflect; |
||||||
|
import org.easymock.EasyMock; |
||||||
|
import org.junit.Assert; |
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.runner.RunWith; |
||||||
|
import org.powermock.api.easymock.PowerMock; |
||||||
|
import org.powermock.core.classloader.annotations.PowerMockIgnore; |
||||||
|
import org.powermock.core.classloader.annotations.PrepareForTest; |
||||||
|
import org.powermock.modules.junit4.PowerMockRunner; |
||||||
|
|
||||||
|
import static com.fr.nx.app.designer.toolbar.TemplateTransformer.OTHER; |
||||||
|
import static com.fr.nx.app.designer.toolbar.TemplateTransformer.TO_CPT; |
||||||
|
import static com.fr.nx.app.designer.toolbar.TemplateTransformer.TO_CPTX; |
||||||
|
import static org.junit.Assert.assertEquals; |
||||||
|
import static org.junit.Assert.assertNull; |
||||||
|
|
||||||
|
@RunWith(PowerMockRunner.class) |
||||||
|
@PrepareForTest({FRContext.class}) |
||||||
|
@PowerMockIgnore({"sun.tools.attach.*", "com.sun.tools.*", "com.fr.license.*"}) |
||||||
|
public class TemplateTransformerTest { |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testParse() { |
||||||
|
assertEquals(TO_CPTX, TemplateTransformer.parse("/sdf/abc.cpt")); |
||||||
|
assertEquals(TO_CPT, TemplateTransformer.parse("/sdf/abc.cptx")); |
||||||
|
assertEquals(OTHER, TemplateTransformer.parse("/sdf/abc.frm")); |
||||||
|
assertEquals(OTHER, TemplateTransformer.parse(null)); |
||||||
|
assertEquals(OTHER, TemplateTransformer.parse("abc")); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testCompileFailed() { |
||||||
|
TransformResultInfo result = TemplateTransformer.compileCPTX(null, null); |
||||||
|
assertEquals(result.getResult(), TransformResult.FAILED); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testGenerateNewPath() { |
||||||
|
assertEquals(generateNewPath("/abc/dd.cpt", ".cpt", ".cptx"), "/abc/dd.cptx"); |
||||||
|
assertEquals(generateNewPath("/abc/dd.cptx", ".cpt", ".cptx"), "/abc/dd.cptx"); |
||||||
|
assertEquals(generateNewPath("/abc/dd.cptx", ".cptx", ".cpt"), "/abc/dd.cpt"); |
||||||
|
assertEquals(generateNewPath("/abc/dd.frm", ".cpt", ".cptx"), "/abc/dd.frm"); |
||||||
|
assertNull(generateNewPath(null, null, null)); |
||||||
|
assertEquals(generateNewPath("abc", null, null), "abc"); |
||||||
|
} |
||||||
|
|
||||||
|
private String generateNewPath(String oldPath, String oldSuffix, String newSuffix) { |
||||||
|
return Reflect.on(TemplateTransformer.class).call("generateNewPath", oldPath, oldSuffix, newSuffix).get(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testCreateOutputFile() { |
||||||
|
CommonOperator commonOperator = EasyMock.mock(CommonOperator.class); |
||||||
|
FileNodes fileNodes = EasyMock.mock(FileNodes.class); |
||||||
|
EasyMock.expect(fileNodes.getSupportedTypes()).andReturn(new String[]{"cptx"}).anyTimes(); |
||||||
|
PowerMock.mockStatic(FRContext.class); |
||||||
|
EasyMock.expect(FRContext.getCommonOperator()).andReturn(commonOperator).anyTimes(); |
||||||
|
EasyMock.expect(FRContext.getFileNodes()).andReturn(fileNodes).anyTimes(); |
||||||
|
EasyMock.expect(commonOperator.getWebRootPath()).andReturn("/WebInf/").anyTimes(); |
||||||
|
EasyMock.replay(commonOperator, fileNodes); |
||||||
|
PowerMock.replayAll(); |
||||||
|
FILE file1 = TemplateTransformer.createOutputFile("WorkBook1.cpt", ".cpt", ".cptx"); |
||||||
|
FILE file2 = TemplateTransformer.createOutputFile("WorkBook1.cpt", ".cptx", ".cpt"); |
||||||
|
assertEquals("WorkBook1.cptx", file1.getPath()); |
||||||
|
assertEquals("WorkBook1.cpt", file2.getPath()); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Test |
||||||
|
public void testNeedDoAfterTransformed() { |
||||||
|
Assert.assertTrue(needDoAfterTransformed(TransformResult.SUCCESS)); |
||||||
|
Assert.assertTrue(needDoAfterTransformed(TransformResult.UNSUPPORT)); |
||||||
|
Assert.assertFalse(needDoAfterTransformed(TransformResult.FAILED)); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean needDoAfterTransformed(TransformResult result) { |
||||||
|
return Reflect.on(TemplateTransformer.class).call("needDoAfterTransformed", result).get(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
package com.fr.nx.app.designer.toolbar; |
||||||
|
|
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
import org.junit.Assert; |
||||||
|
import org.junit.Test; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-01-15 |
||||||
|
*/ |
||||||
|
public class TransformResultInfoTest { |
||||||
|
@Test |
||||||
|
public void testGetTransformLog() { |
||||||
|
TransformResultInfo resultInfo1 = TransformResultInfo.generateResult(TransformResult.FAILED, "failed"); |
||||||
|
Assert.assertEquals("failed\n" + |
||||||
|
InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Transform_Failed_Tip"), |
||||||
|
resultInfo1.getTransformLog()); |
||||||
|
TransformResultInfo resultInfo2 = TransformResultInfo.generateResult(TransformResult.SUCCESS); |
||||||
|
Assert.assertEquals(InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Transform_Success_Tip"), |
||||||
|
resultInfo2.getTransformLog()); |
||||||
|
TransformResultInfo resultInfo3 = TransformResultInfo.generateResult(TransformResult.UNSUPPORT, "unsupport"); |
||||||
|
Assert.assertEquals("unsupport\n" + |
||||||
|
InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Transform_Unsupport_Tip"), |
||||||
|
resultInfo3.getTransformLog()); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testSaved() { |
||||||
|
TransformResultInfo resultInfo1 = TransformResultInfo.generateResult(TransformResult.FAILED, "failed").saved(false); |
||||||
|
Assert.assertFalse(resultInfo1.isSaved()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
package com.fr.nx.app.designer.transform; |
||||||
|
|
||||||
|
import org.junit.Assert; |
||||||
|
import org.junit.Test; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-01-15 |
||||||
|
*/ |
||||||
|
public class BatchTransformProgressTest { |
||||||
|
@Test |
||||||
|
public void testGetProgress(){ |
||||||
|
BatchTransformProgress batchTransformProgress = new BatchTransformProgress(100); |
||||||
|
Assert.assertEquals(0.0D, batchTransformProgress.getProgress(), 0.0D); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testUpdateProgress(){ |
||||||
|
BatchTransformProgress batchTransformProgress = new BatchTransformProgress(100); |
||||||
|
for (int i = 0; i < 80; i++) { |
||||||
|
batchTransformProgress.updateProgress(); |
||||||
|
} |
||||||
|
Assert.assertEquals(0.8D, batchTransformProgress.getProgress(), 0.0D); |
||||||
|
batchTransformProgress.updateProgress(); |
||||||
|
Assert.assertEquals(0.81D, batchTransformProgress.getProgress(), 0.0D); |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
package com.fr.nx.app.designer.transform; |
||||||
|
|
||||||
|
import com.fr.file.filetree.FileNode; |
||||||
|
import org.junit.Assert; |
||||||
|
import org.junit.Test; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-02-14 |
||||||
|
*/ |
||||||
|
public class BatchTransformUtilTest { |
||||||
|
@Test |
||||||
|
public void testFilterTransformedFile(){ |
||||||
|
FileNode[] fileNodes = new FileNode[]{ |
||||||
|
new FileNode("test1", false), new FileNode("test2", false) |
||||||
|
}; |
||||||
|
List<FileNode> transformedFileNodes = new ArrayList<FileNode>(); |
||||||
|
FileNode[] result1 = BatchTransformUtil.filterTransformedFile(fileNodes, transformedFileNodes); |
||||||
|
Assert.assertEquals(2, result1.length); |
||||||
|
|
||||||
|
transformedFileNodes.add( new FileNode("test1", false)); |
||||||
|
FileNode[] result2 = BatchTransformUtil.filterTransformedFile(fileNodes, transformedFileNodes); |
||||||
|
Assert.assertEquals(1, result2.length); |
||||||
|
|
||||||
|
transformedFileNodes.add( new FileNode("test2", false)); |
||||||
|
FileNode[] result3 = BatchTransformUtil.filterTransformedFile(fileNodes, transformedFileNodes); |
||||||
|
Assert.assertEquals(0, result3.length); |
||||||
|
|
||||||
|
transformedFileNodes.add( new FileNode("test3", false)); |
||||||
|
FileNode[] result4 = BatchTransformUtil.filterTransformedFile(fileNodes, transformedFileNodes); |
||||||
|
Assert.assertEquals(0, result4.length); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,124 @@ |
|||||||
|
package com.fr.nx.app.designer.transform; |
||||||
|
|
||||||
|
import org.junit.Before; |
||||||
|
import org.junit.Test; |
||||||
|
|
||||||
|
import java.util.concurrent.CountDownLatch; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-01-15 |
||||||
|
*/ |
||||||
|
// FIXME @kerry 打包失败,暂时先注释
|
||||||
|
//@RunWith(value = PowerMockRunner.class)
|
||||||
|
//@PrepareForTest({CompileTransformUtil.class, PluginContexts.class})
|
||||||
|
//@PowerMockIgnore({"sun.tools.attach.*", "com.sun.tools.*"})
|
||||||
|
public class BatchTransformerTest { |
||||||
|
|
||||||
|
private static final int MAXPOOLSIZE = 5; |
||||||
|
private static final int COREPOOLSIZE = 3; |
||||||
|
private static final String THREAD_NAME_TEMPLATE = "batchtransform-thread-%s"; |
||||||
|
|
||||||
|
@Before |
||||||
|
public void setUp() { |
||||||
|
// FineRuntime.start();
|
||||||
|
// ExecutorService threadPoolExecutor = new ThreadPoolExecutor(COREPOOLSIZE, MAXPOOLSIZE,
|
||||||
|
// 0L, TimeUnit.MILLISECONDS,
|
||||||
|
// new LinkedBlockingQueue<Runnable>(),
|
||||||
|
// new ThreadFactoryBuilder().setNameFormat(THREAD_NAME_TEMPLATE).build());
|
||||||
|
// PowerMock.mockStatic(PluginContexts.class);
|
||||||
|
// PluginContext pluginContext = EasyMock.mock(PluginContext.class);
|
||||||
|
// EasyMock.expect(pluginContext.newFixedThreadPool(
|
||||||
|
// EasyMock.anyInt(), EasyMock.anyObject(ThreadFactory.class)))
|
||||||
|
// .andReturn(threadPoolExecutor).anyTimes();
|
||||||
|
// EasyMock.expect(PluginContexts.currentContext()).andReturn(pluginContext).anyTimes();
|
||||||
|
//
|
||||||
|
// PowerMock.mockStatic(CompileTransformUtil.class);
|
||||||
|
// TransformResultInfo resultInfo = TransformResultInfo.generateResult(TransformResult.SUCCESS);
|
||||||
|
// EasyMock.expect(CompileTransformUtil.compileFile(EasyMock.anyObject(FileNode.class)))
|
||||||
|
// .andReturn(resultInfo).anyTimes();
|
||||||
|
// EasyMock.replay(pluginContext);
|
||||||
|
// PowerMock.replayAll();
|
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testBatchTransform() { |
||||||
|
// final CountDownLatch countDownLatch = new CountDownLatch(2);
|
||||||
|
// BatchTransformer transformer = new BatchTransformer(new MockUpdateCallBack(countDownLatch));
|
||||||
|
// List<FileNode> nodeList = new ArrayList<>();
|
||||||
|
// FileNode test1 = new FileNode("path1", false);
|
||||||
|
// FileNode test2 = new FileNode("path2", false);
|
||||||
|
// nodeList.add(test1);
|
||||||
|
// nodeList.add(test2);
|
||||||
|
// transformer.batchTransform(nodeList);
|
||||||
|
// try {
|
||||||
|
// countDownLatch.await(5, TimeUnit.SECONDS);
|
||||||
|
// } catch (InterruptedException e) {
|
||||||
|
// Assert.fail();
|
||||||
|
// }
|
||||||
|
// Map<FileNode, TransformResultInfo> transformResults = transformer.getResults();
|
||||||
|
// Assert.assertEquals(2, transformResults.size());
|
||||||
|
// Assert.assertEquals(TransformResult.SUCCESS, transformResults.get(test1).getResult());
|
||||||
|
// Assert.assertEquals(TransformResult.SUCCESS, transformResults.get(test2).getResult());
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testTransform() { |
||||||
|
// final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||||
|
// BatchTransformer transformer = new BatchTransformer(new MockUpdateCallBack(countDownLatch));
|
||||||
|
// FileNode test = new FileNode("path", false);
|
||||||
|
// Reflect.on(transformer).call("transform", test);
|
||||||
|
// try {
|
||||||
|
// countDownLatch.await(5, TimeUnit.SECONDS);
|
||||||
|
// } catch (InterruptedException e) {
|
||||||
|
// Assert.fail();
|
||||||
|
// }
|
||||||
|
// Map<FileNode, TransformResultInfo> transformResults = transformer.getResults();
|
||||||
|
// Assert.assertEquals(1, transformResults.size());
|
||||||
|
// Assert.assertEquals(TransformResult.SUCCESS, transformResults.get(test).getResult());
|
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testShutDown() { |
||||||
|
// final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||||
|
// BatchTransformer transformer = new BatchTransformer(new MockUpdateCallBack(countDownLatch));
|
||||||
|
// List<FileNode> nodeList = new ArrayList<>();
|
||||||
|
// FileNode test = new FileNode("path", false);
|
||||||
|
// nodeList.add(test);
|
||||||
|
// transformer.batchTransform(nodeList);
|
||||||
|
// transformer.shutDown();
|
||||||
|
// try {
|
||||||
|
// countDownLatch.await(3, TimeUnit.SECONDS);
|
||||||
|
// } catch (InterruptedException e) {
|
||||||
|
// Assert.fail();
|
||||||
|
// }
|
||||||
|
// Map<FileNode, TransformResultInfo> transformResults = transformer.getResults();
|
||||||
|
// Assert.assertEquals(1, transformResults.size());
|
||||||
|
// Assert.assertEquals(TransformResult.SUCCESS, transformResults.get(test).getResult());
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private class MockUpdateCallBack implements UpdateCallBack { |
||||||
|
private CountDownLatch countDownLatch; |
||||||
|
|
||||||
|
|
||||||
|
public MockUpdateCallBack(CountDownLatch countDownLatch) { |
||||||
|
this.countDownLatch = countDownLatch; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void updateProgress(double progress) { |
||||||
|
countDownLatch.countDown(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void shutDown() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void reset() { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
package com.fr.nx.app.designer.utils; |
||||||
|
|
||||||
|
import com.fr.base.FRContext; |
||||||
|
import com.fr.base.operator.common.CommonOperator; |
||||||
|
import com.fr.design.mainframe.JTemplate; |
||||||
|
import com.fr.file.FILE; |
||||||
|
import com.fr.file.filetree.FileNodes; |
||||||
|
import com.fr.nx.app.designer.toolbar.TemplateTransformer; |
||||||
|
import org.easymock.EasyMock; |
||||||
|
import org.junit.Assert; |
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.runner.RunWith; |
||||||
|
import org.powermock.api.easymock.PowerMock; |
||||||
|
import org.powermock.core.classloader.annotations.PowerMockIgnore; |
||||||
|
import org.powermock.core.classloader.annotations.PrepareForTest; |
||||||
|
import org.powermock.modules.junit4.PowerMockRunner; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2019-12-04 |
||||||
|
*/ |
||||||
|
@RunWith(PowerMockRunner.class) |
||||||
|
@PrepareForTest({FRContext.class}) |
||||||
|
@PowerMockIgnore({"sun.tools.attach.*", "com.sun.tools.*"}) |
||||||
|
public class CompileTransformUtilTest { |
||||||
|
@Test |
||||||
|
public void testGetTargetFile() { |
||||||
|
CommonOperator commonOperator = EasyMock.mock(CommonOperator.class); |
||||||
|
FileNodes fileNodes = EasyMock.mock(FileNodes.class); |
||||||
|
EasyMock.expect(fileNodes.getSupportedTypes()).andReturn(new String[]{"cptx"}).anyTimes(); |
||||||
|
PowerMock.mockStatic(FRContext.class); |
||||||
|
EasyMock.expect(FRContext.getCommonOperator()).andReturn(commonOperator).anyTimes(); |
||||||
|
EasyMock.expect(FRContext.getFileNodes()).andReturn(fileNodes).anyTimes(); |
||||||
|
EasyMock.expect(commonOperator.getWebRootPath()).andReturn("/WebInf/").anyTimes(); |
||||||
|
EasyMock.replay(commonOperator, fileNodes); |
||||||
|
PowerMock.replayAll(); |
||||||
|
JTemplate jTemplate1 = EasyMock.mock(JTemplate.class); |
||||||
|
FILE file1 = EasyMock.mock(FILE.class); |
||||||
|
EasyMock.expect(jTemplate1.getEditingFILE()).andReturn(file1).anyTimes(); |
||||||
|
EasyMock.expect(file1.getPath()).andReturn("WorkBook1.cpt").anyTimes(); |
||||||
|
EasyMock.replay(jTemplate1, file1); |
||||||
|
FILE targetFile = CompileTransformUtil.getTargetFile(jTemplate1, TemplateTransformer.TO_CPTX); |
||||||
|
Assert.assertEquals("WorkBook1.cptx", targetFile.getPath()); |
||||||
|
|
||||||
|
targetFile = CompileTransformUtil.getTargetFile(jTemplate1, TemplateTransformer.TO_CPT); |
||||||
|
Assert.assertEquals("WorkBook1.cpt", targetFile.getPath()); |
||||||
|
|
||||||
|
JTemplate jTemplate2 = EasyMock.mock(JTemplate.class); |
||||||
|
FILE file2 = EasyMock.mock(FILE.class); |
||||||
|
EasyMock.expect(jTemplate2.getEditingFILE()).andReturn(file2).anyTimes(); |
||||||
|
EasyMock.expect(file2.getPath()).andReturn("WorkBook1.cpt").anyTimes(); |
||||||
|
EasyMock.replay(jTemplate2, file2); |
||||||
|
targetFile = CompileTransformUtil.getTargetFile(jTemplate2, TemplateTransformer.TO_CPTX); |
||||||
|
Assert.assertEquals("WorkBook1.cptx", targetFile.getPath()); |
||||||
|
|
||||||
|
targetFile =CompileTransformUtil.getTargetFile(jTemplate2, TemplateTransformer.TO_CPT); |
||||||
|
Assert.assertEquals("WorkBook1.cpt", targetFile.getPath()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,83 @@ |
|||||||
|
package com.fr.design.actions; |
||||||
|
|
||||||
|
import com.fr.design.beans.BasicBeanPane; |
||||||
|
import com.fr.design.dialog.DialogActionAdapter; |
||||||
|
import com.fr.design.dialog.UIDialog; |
||||||
|
import com.fr.design.fit.DesignerUIModeConfig; |
||||||
|
import com.fr.design.fit.NewJForm; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.design.mainframe.JTemplate; |
||||||
|
import com.fr.design.menu.MenuKeySet; |
||||||
|
import com.fr.report.fit.FitProvider; |
||||||
|
import com.fr.report.fit.ReportFitAttr; |
||||||
|
|
||||||
|
import javax.swing.KeyStroke; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by Administrator on 2015/7/6 0006. |
||||||
|
*/ |
||||||
|
public class FormFitAttrAction extends JTemplateAction { |
||||||
|
private static final MenuKeySet REPORT_FIT_ATTR_ELEMENTCASE = new MenuKeySet() { |
||||||
|
@Override |
||||||
|
public char getMnemonic() { |
||||||
|
return 'T'; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getMenuName() { |
||||||
|
return DesignerUIModeConfig.getInstance().newUIMode() ? |
||||||
|
com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit_PC_Adaptive_Attr") : |
||||||
|
com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_PC_Element_Case_Fit_Attr"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public KeyStroke getKeyStroke() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
public FormFitAttrAction(JTemplate jTemplate) { |
||||||
|
super(jTemplate); |
||||||
|
initMenuStyle(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initMenuStyle() { |
||||||
|
this.setMenuKeySet(REPORT_FIT_ATTR_ELEMENTCASE); |
||||||
|
this.setName(getMenuKeySet().getMenuKeySetName() + "..."); |
||||||
|
this.setMnemonic(getMenuKeySet().getMnemonic()); |
||||||
|
this.setSmallIcon(DesignerUIModeConfig.getInstance().newUIMode() ? |
||||||
|
"/com/fr/design/images/reportfit/fit.png": |
||||||
|
"/com/fr/design/images/reportfit/fit"); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Action触发事件 |
||||||
|
* |
||||||
|
* @param e 事件 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
final JTemplate jwb = getEditingComponent(); |
||||||
|
if (jwb == null || !(jwb instanceof NewJForm)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
final FitProvider wbTpl = (FitProvider) jwb.getTarget(); |
||||||
|
ReportFitAttr fitAttr = wbTpl.getReportFitAttr(); |
||||||
|
NewJForm newJForm = (NewJForm) jwb; |
||||||
|
BasicBeanPane attrPane = newJForm.getJFormType().obtainAttrPane(newJForm); |
||||||
|
showFitDialog(fitAttr, jwb, wbTpl, attrPane); |
||||||
|
} |
||||||
|
|
||||||
|
private void showFitDialog(ReportFitAttr fitAttr, final JTemplate jwb, final FitProvider wbTpl, final BasicBeanPane<ReportFitAttr> attrPane) { |
||||||
|
attrPane.populateBean(fitAttr); |
||||||
|
UIDialog dialog = attrPane.showMediumWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { |
||||||
|
@Override |
||||||
|
public void doOk() { |
||||||
|
wbTpl.setReportFitAttr(attrPane.updateBean()); |
||||||
|
jwb.fireTargetModified(); |
||||||
|
} |
||||||
|
}); |
||||||
|
dialog.setVisible(true); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,115 @@ |
|||||||
|
package com.fr.design.actions; |
||||||
|
|
||||||
|
|
||||||
|
import com.fr.base.iofile.attr.MobileOnlyTemplateAttrMark; |
||||||
|
import com.fr.design.designer.creator.XLayoutContainer; |
||||||
|
import com.fr.design.designer.creator.XWAbsoluteBodyLayout; |
||||||
|
import com.fr.design.designer.creator.XWFitLayout; |
||||||
|
import com.fr.design.dialog.BasicDialog; |
||||||
|
import com.fr.design.dialog.DialogActionAdapter; |
||||||
|
import com.fr.design.fit.NewJForm; |
||||||
|
import com.fr.design.fit.common.AdaptiveSwitchUtil; |
||||||
|
import com.fr.design.fit.common.TemplateTool; |
||||||
|
import com.fr.design.form.mobile.FormMobileAttrPane; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.design.mainframe.FormArea; |
||||||
|
import com.fr.design.mainframe.FormDesigner; |
||||||
|
import com.fr.design.mainframe.JForm; |
||||||
|
import com.fr.design.mainframe.WidgetPropertyPane; |
||||||
|
import com.fr.file.FILE; |
||||||
|
import com.fr.form.main.Form; |
||||||
|
import com.fr.form.main.mobile.FormMobileAttr; |
||||||
|
import com.fr.record.analyzer.EnableMetrics; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by fanglei on 2016/11/14. |
||||||
|
*/ |
||||||
|
@EnableMetrics |
||||||
|
public class NewFormMobileAttrAction extends FormMobileAttrAction { |
||||||
|
|
||||||
|
public NewFormMobileAttrAction(JForm jf) { |
||||||
|
super(jf); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 执行动作 |
||||||
|
* |
||||||
|
* @return 是否执行成功 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
final JForm jf = getEditingComponent(); |
||||||
|
if (jf == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
final Form formTpl = jf.getTarget(); |
||||||
|
FormMobileAttr mobileAttr = formTpl.getFormMobileAttr(); |
||||||
|
|
||||||
|
final FormMobileAttrPane mobileAttrPane = new FormMobileAttrPane(); |
||||||
|
mobileAttrPane.populateBean(mobileAttr); |
||||||
|
|
||||||
|
final boolean oldMobileOnly = mobileAttr.isMobileOnly(); |
||||||
|
final boolean oldAdaptive = mobileAttr.isAdaptivePropertyAutoMatch(); |
||||||
|
BasicDialog dialog = mobileAttrPane.showWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { |
||||||
|
@Override |
||||||
|
public void doOk() { |
||||||
|
FormMobileAttr formMobileAttr = mobileAttrPane.updateBean(); |
||||||
|
if (formMobileAttr.isMobileOnly() && jf.getTarget().getAttrMark(MobileOnlyTemplateAttrMark.XML_TAG) == null) { |
||||||
|
// 如果是老模板,选择手机专属之后需要另存为
|
||||||
|
FILE editingFILE = jf.getEditingFILE(); |
||||||
|
if (editingFILE != null && editingFILE.exists()) { |
||||||
|
String fileName = editingFILE.getName().substring(0, editingFILE.getName().length() - jf.suffix().length()) + "_mobile"; |
||||||
|
if (!jf.saveAsTemplate(true, fileName)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
// 放到后面。如果提前 return 了,则仍然处于未设置状态,不要添加
|
||||||
|
jf.getTarget().addAttrMark(new MobileOnlyTemplateAttrMark()); |
||||||
|
} |
||||||
|
// 设置移动端属性并刷新界面
|
||||||
|
formTpl.setFormMobileAttr(formMobileAttr); // 会调整 body 的自适应布局,放到最后
|
||||||
|
boolean changeSize = (!oldMobileOnly && formMobileAttr.isMobileOnly()) || (oldMobileOnly && !formMobileAttr.isMobileOnly()); |
||||||
|
if (changeSize) { |
||||||
|
((FormArea)jf.getFormDesign().getParent()).onMobileAttrModified(); |
||||||
|
} |
||||||
|
//改变布局为自适应布局,只在移动端属性设置保存后改变一次
|
||||||
|
boolean changeLayout = !oldAdaptive && formMobileAttr.isAdaptivePropertyAutoMatch(); |
||||||
|
if (changeLayout) { |
||||||
|
jf.getFormDesign().getSelectionModel().setSelectedCreator(jf.getFormDesign().getRootComponent()); |
||||||
|
doChangeBodyLayout(); |
||||||
|
WidgetPropertyPane.getInstance().refreshDockingView(); |
||||||
|
} |
||||||
|
jf.fireTargetModified(); |
||||||
|
FILE editingFILE = jf.getEditingFILE(); |
||||||
|
if(editingFILE != null && editingFILE.exists()){ |
||||||
|
JForm jForm = getEditingComponent(); |
||||||
|
TemplateTool.saveForm(jForm); |
||||||
|
if (jForm instanceof NewJForm) { |
||||||
|
AdaptiveSwitchUtil.switch2OldUI(); |
||||||
|
} |
||||||
|
}else { |
||||||
|
AdaptiveSwitchUtil.switch2OldUIMode(); |
||||||
|
NewJForm mobileJForm = new NewJForm(jf.getTarget(), jf.getEditingFILE()); |
||||||
|
//设置临时的id,和新建的模板区分
|
||||||
|
mobileJForm.getTarget().setTemplateID(StringUtils.EMPTY); |
||||||
|
TemplateTool.resetTabPaneEditingTemplate(mobileJForm); |
||||||
|
TemplateTool.activeAndResizeTemplate(mobileJForm); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
dialog.setVisible(true); |
||||||
|
} |
||||||
|
|
||||||
|
private void doChangeBodyLayout(){ |
||||||
|
FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); |
||||||
|
XLayoutContainer rootLayout = formDesigner.getRootComponent(); |
||||||
|
if (rootLayout.getComponentCount() == 1 && rootLayout.getXCreator(0).acceptType(XWAbsoluteBodyLayout.class)) { |
||||||
|
rootLayout = (XWAbsoluteBodyLayout) rootLayout.getXCreator(0); |
||||||
|
} |
||||||
|
((XWFitLayout)formDesigner.getRootComponent()).switch2FitBodyLayout(rootLayout); |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,124 @@ |
|||||||
|
package com.fr.design.fit; |
||||||
|
|
||||||
|
import com.fr.base.ScreenResolution; |
||||||
|
import com.fr.design.fun.ReportLengthUNITProvider; |
||||||
|
import com.fr.design.unit.UnitConvertUtil; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.general.FRScreen; |
||||||
|
import com.fr.stable.Constants; |
||||||
|
|
||||||
|
import java.awt.Dimension; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-06-05 |
||||||
|
*/ |
||||||
|
public class DesignerUIModeConfig { |
||||||
|
private DesignerUIMode mode = DesignerUIMode.NEW_UI_MODE; |
||||||
|
|
||||||
|
private static class DesignerUIModeConfigHolder { |
||||||
|
private static final DesignerUIModeConfig designerUIModeConfig = new DesignerUIModeConfig(); |
||||||
|
} |
||||||
|
|
||||||
|
private DesignerUIModeConfig() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public static DesignerUIModeConfig getInstance() { |
||||||
|
return DesignerUIModeConfigHolder.designerUIModeConfig; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 判断是否是新ui模式 |
||||||
|
* |
||||||
|
* @return boolean |
||||||
|
*/ |
||||||
|
public boolean newUIMode() { |
||||||
|
return ComparatorUtils.equals(DesignerUIMode.NEW_UI_MODE, mode); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置新ui模式 |
||||||
|
*/ |
||||||
|
public void setNewUIMode() { |
||||||
|
this.mode = DesignerUIMode.NEW_UI_MODE; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置老ui模式 |
||||||
|
*/ |
||||||
|
public void setOldUIMode() { |
||||||
|
this.mode = DesignerUIMode.OLD_UI_MODE; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 解析不同模式下的尺寸单位 |
||||||
|
* |
||||||
|
* @param unitType 尺寸类型 |
||||||
|
* @return ReportLengthUNITProvider对象 |
||||||
|
*/ |
||||||
|
public ReportLengthUNITProvider parseLengthUNIT(int unitType) { |
||||||
|
return mode.parseLengthUNIT(unitType); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取不同模式下的屏幕分辨率 |
||||||
|
* |
||||||
|
* @return 分辨率 |
||||||
|
*/ |
||||||
|
public int getScreenResolution() { |
||||||
|
return mode.getScreenResolution(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据屏幕尺寸获取设计时的FRScreen |
||||||
|
* |
||||||
|
* @param screen 屏幕尺寸 |
||||||
|
* @return FRScreen |
||||||
|
*/ |
||||||
|
public FRScreen getDesignScreenByDimension(Dimension screen) { |
||||||
|
return mode.getDesignScreenByDimension(screen); |
||||||
|
} |
||||||
|
|
||||||
|
private enum DesignerUIMode { |
||||||
|
OLD_UI_MODE { |
||||||
|
@Override |
||||||
|
protected ReportLengthUNITProvider parseLengthUNIT(int unitType) { |
||||||
|
return UnitConvertUtil.parseLengthUNIT(unitType); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected FRScreen getDesignScreenByDimension(Dimension screen) { |
||||||
|
return FRScreen.getDesignScreenByDimension(screen); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getScreenResolution() { |
||||||
|
return ScreenResolution.getScreenResolution(); |
||||||
|
} |
||||||
|
}, |
||||||
|
NEW_UI_MODE { |
||||||
|
@Override |
||||||
|
protected ReportLengthUNITProvider parseLengthUNIT(int unitType) { |
||||||
|
return new PXReportLengthUNIT(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected FRScreen getDesignScreenByDimension(Dimension screen) { |
||||||
|
return FRScreen.p1440; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getScreenResolution() { |
||||||
|
return Constants.DEFAULT_WEBWRITE_AND_SCREEN_RESOLUTION; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
protected abstract ReportLengthUNITProvider parseLengthUNIT(int unitType); |
||||||
|
|
||||||
|
protected abstract FRScreen getDesignScreenByDimension(Dimension screen); |
||||||
|
|
||||||
|
protected abstract int getScreenResolution(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
package com.fr.design.fit; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-04-27 |
||||||
|
*/ |
||||||
|
public enum FitStateCompatible { |
||||||
|
DOUBLE_FIT(2, 0), |
||||||
|
HOR_FIT(1, 1), |
||||||
|
NO_FIT(3, 2); |
||||||
|
|
||||||
|
private final int newType; |
||||||
|
private final int oldType; |
||||||
|
|
||||||
|
FitStateCompatible(int oldType, int newType) { |
||||||
|
this.oldType = oldType; |
||||||
|
this.newType = newType; |
||||||
|
} |
||||||
|
|
||||||
|
public static int getNewTypeFromOld(int oldValue) { |
||||||
|
for (FitStateCompatible compatible : values()) { |
||||||
|
if (compatible.oldType == oldValue) { |
||||||
|
return compatible.newType; |
||||||
|
} |
||||||
|
} |
||||||
|
return DOUBLE_FIT.newType; |
||||||
|
} |
||||||
|
|
||||||
|
public static int getOldTypeFromNew(int newValue) { |
||||||
|
for (FitStateCompatible compatible : values()) { |
||||||
|
if (compatible.newType == newValue) { |
||||||
|
return compatible.oldType; |
||||||
|
} |
||||||
|
} |
||||||
|
return DOUBLE_FIT.oldType; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,133 @@ |
|||||||
|
package com.fr.design.fit; |
||||||
|
|
||||||
|
import com.fr.design.beans.BasicBeanPane; |
||||||
|
import com.fr.design.fit.common.AdaptiveSwitchUtil; |
||||||
|
import com.fr.form.fit.NewFormMarkAttr; |
||||||
|
import com.fr.form.fit.config.FormFitConfig; |
||||||
|
import com.fr.design.fit.menupane.FormFitAttrPane; |
||||||
|
import com.fr.design.fun.PreviewProvider; |
||||||
|
import com.fr.design.mainframe.JTemplate; |
||||||
|
import com.fr.design.preview.FormAdaptivePreview; |
||||||
|
import com.fr.design.preview.FormPreview; |
||||||
|
import com.fr.design.report.fit.menupane.ReportFitAttrPane; |
||||||
|
import com.fr.form.main.Form; |
||||||
|
import com.fr.report.fit.ReportFitAttr; |
||||||
|
|
||||||
|
public enum JFormType { |
||||||
|
OLD_TYPE(0, new FormPreview()) { |
||||||
|
@Override |
||||||
|
public void switchUI() { |
||||||
|
AdaptiveSwitchUtil.switch2OldUI(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void switchUIMode() { |
||||||
|
AdaptiveSwitchUtil.switch2OldUIMode(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ReportFitAttr obtainFitAttr() { |
||||||
|
return FormFitConfig.getInstance().getOldFitAttr(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void updateFitAttr(ReportFitAttr attr) { |
||||||
|
FormFitConfig.getInstance().setOldFitAttr(attr); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public BasicBeanPane obtainAttrPane(NewJForm newJForm) { |
||||||
|
return new ReportFitAttrPane(); |
||||||
|
} |
||||||
|
|
||||||
|
}, |
||||||
|
NEW_TYPE(1, new FormAdaptivePreview()) { |
||||||
|
@Override |
||||||
|
public void switchUI() { |
||||||
|
AdaptiveSwitchUtil.switch2NewUI(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void switchUIMode() { |
||||||
|
AdaptiveSwitchUtil.switch2NewUIMode(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ReportFitAttr obtainFitAttr() { |
||||||
|
return FormFitConfig.getInstance().getNewFitAttr(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void updateFitAttr(ReportFitAttr attr) { |
||||||
|
FormFitConfig.getInstance().setNewFitAttr(attr); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public BasicBeanPane obtainAttrPane(NewJForm newJForm) { |
||||||
|
return new FormFitAttrPane(newJForm); |
||||||
|
} |
||||||
|
}; |
||||||
|
private int type; |
||||||
|
private boolean newType; |
||||||
|
private PreviewProvider previewType; |
||||||
|
|
||||||
|
JFormType(int type, PreviewProvider previewType) { |
||||||
|
this.type = type; |
||||||
|
this.newType = (type == 1); |
||||||
|
this.previewType = previewType; |
||||||
|
} |
||||||
|
|
||||||
|
public int getType() { |
||||||
|
return type; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isNewType() { |
||||||
|
return newType; |
||||||
|
} |
||||||
|
|
||||||
|
public PreviewProvider getPreviewType() { |
||||||
|
return previewType; |
||||||
|
} |
||||||
|
|
||||||
|
public abstract void switchUI(); |
||||||
|
|
||||||
|
public abstract void switchUIMode(); |
||||||
|
|
||||||
|
public abstract ReportFitAttr obtainFitAttr(); |
||||||
|
|
||||||
|
public abstract void updateFitAttr(ReportFitAttr attr); |
||||||
|
|
||||||
|
public abstract BasicBeanPane obtainAttrPane(NewJForm newJForm); |
||||||
|
|
||||||
|
/** |
||||||
|
* @Description: 更新模板的标志位 |
||||||
|
* @param jTemplate |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/12/17 16:17 |
||||||
|
*/ |
||||||
|
public void updateJFromTemplateType(JTemplate jTemplate) { |
||||||
|
if (jTemplate instanceof NewJForm) { |
||||||
|
NewJForm newJForm = (NewJForm) jTemplate; |
||||||
|
Form form = newJForm.getTarget(); |
||||||
|
NewFormMarkAttr newFormMarkAttr = form.getAttrMark(NewFormMarkAttr.XML_TAG); |
||||||
|
if (newFormMarkAttr == null) { |
||||||
|
newFormMarkAttr = new NewFormMarkAttr(this.getType()); |
||||||
|
form.addAttrMark(newFormMarkAttr); |
||||||
|
} |
||||||
|
newFormMarkAttr.setType(this.getType()); |
||||||
|
newJForm.setJFormType(this); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @Description: 更新预览方式 |
||||||
|
* @param jTemplate |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/12/17 16:17 |
||||||
|
*/ |
||||||
|
public void updatePreviewType(JTemplate jTemplate) { |
||||||
|
jTemplate.setPreviewType(this.getPreviewType()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,285 @@ |
|||||||
|
package com.fr.design.fit; |
||||||
|
|
||||||
|
import com.fr.base.DynamicUnitList; |
||||||
|
import com.fr.design.actions.TemplateParameterAction; |
||||||
|
import com.fr.design.designer.beans.AdapterBus; |
||||||
|
import com.fr.design.designer.beans.LayoutAdapter; |
||||||
|
import com.fr.design.designer.beans.adapters.layout.FRFitLayoutAdapter; |
||||||
|
import com.fr.design.designer.beans.events.DesignerEditListener; |
||||||
|
import com.fr.design.designer.beans.events.DesignerEvent; |
||||||
|
import com.fr.design.designer.creator.*; |
||||||
|
import com.fr.design.fit.common.AdaptiveSwitchUtil; |
||||||
|
import com.fr.design.fit.common.LayoutTool; |
||||||
|
import com.fr.form.fit.NewFormMarkAttr; |
||||||
|
import com.fr.design.fit.common.TemplateTool; |
||||||
|
import com.fr.design.actions.FormFitAttrAction; |
||||||
|
import com.fr.design.actions.NewFormMobileAttrAction; |
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.preview.DeveloperPreview; |
||||||
|
import com.fr.design.preview.FormAdaptivePreview; |
||||||
|
import com.fr.design.fit.toolbar.SwitchAction; |
||||||
|
import com.fr.design.fun.PreviewProvider; |
||||||
|
import com.fr.design.mainframe.FormDesigner; |
||||||
|
import com.fr.design.mainframe.JForm; |
||||||
|
import com.fr.design.mainframe.WidgetPropertyPane; |
||||||
|
import com.fr.design.menu.ShortCut; |
||||||
|
import com.fr.design.preview.FormPreview; |
||||||
|
import com.fr.design.preview.MobilePreview; |
||||||
|
import com.fr.design.utils.ComponentUtils; |
||||||
|
import com.fr.file.FILE; |
||||||
|
import com.fr.form.FormElementCaseProvider; |
||||||
|
import com.fr.form.main.Form; |
||||||
|
import com.fr.form.main.mobile.FormMobileAttr; |
||||||
|
import com.fr.form.ui.ElementCaseEditor; |
||||||
|
import com.fr.stable.ArrayUtils; |
||||||
|
|
||||||
|
import javax.swing.JComponent; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.Rectangle; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-05-31 |
||||||
|
*/ |
||||||
|
public class NewJForm extends JForm { |
||||||
|
private static final int FUZZY_EDGE = 10; |
||||||
|
private static final int TITLE_HEIGHT = 36; |
||||||
|
private JFormType jFormType; |
||||||
|
|
||||||
|
public NewJForm() { |
||||||
|
super(); |
||||||
|
init(); |
||||||
|
changePaneSize(); |
||||||
|
} |
||||||
|
|
||||||
|
public NewJForm(Form form, FILE file) { |
||||||
|
super(form, file); |
||||||
|
if (DesignerUIModeConfig.getInstance().newUIMode()) { |
||||||
|
init(); |
||||||
|
} |
||||||
|
changePaneSize(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @Description:改变body的大小,主要针对新模式下打开老模板出现截断的情况 |
||||||
|
* @param |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/13 23:23 |
||||||
|
*/ |
||||||
|
private void changePaneSize() { |
||||||
|
if (mobileForm()) |
||||||
|
return; |
||||||
|
NewFormMarkAttr newFormMarkAttr = this.getTarget().getAttrMark(NewFormMarkAttr.XML_TAG); |
||||||
|
if (newFormMarkAttr.isNotSetOriginSize()) { |
||||||
|
newFormMarkAttr.setBodyHeight(LayoutTool.getBodyHeight(this)); |
||||||
|
newFormMarkAttr.setBodyWidth(LayoutTool.getBodyWidth(this)); |
||||||
|
return; |
||||||
|
} |
||||||
|
//这种是针对body为绝对布局时,可能出现截断的情况
|
||||||
|
if (LayoutTool.absoluteLayoutForm(this)) { |
||||||
|
int bodyHeight = newFormMarkAttr.getBodyHeight(); |
||||||
|
int bodyWidth = newFormMarkAttr.getBodyWidth(); |
||||||
|
Rectangle rectangle = LayoutTool.getAbsoluteBodySize(this); |
||||||
|
if (!isNewJFrom() && (rectangle.width != bodyWidth || rectangle.height != bodyHeight)) { |
||||||
|
TemplateTool.onlyChangeAbsoluteBodySize(bodyHeight, bodyWidth, this); |
||||||
|
} else if(isNewJFrom()){ |
||||||
|
if (rectangle.width > bodyWidth && rectangle.height > bodyHeight) { |
||||||
|
TemplateTool.onlyChangeAbsoluteBodySize(rectangle.height, rectangle.width, this); |
||||||
|
} else if (rectangle.width > bodyWidth) { |
||||||
|
TemplateTool.onlyChangeAbsoluteBodySize(bodyHeight, rectangle.width, this); |
||||||
|
} else if (rectangle.height > bodyHeight) { |
||||||
|
TemplateTool.onlyChangeAbsoluteBodySize(rectangle.height, bodyWidth, this); |
||||||
|
} |
||||||
|
} |
||||||
|
} else if (AdaptiveSwitchUtil.isSwitchJFromIng()) { |
||||||
|
//这种是针对body中有绝对画布块,导致截断的情况
|
||||||
|
double scale = LayoutTool.getContainerPercent(); |
||||||
|
if (isNewJFrom()) { |
||||||
|
LayoutTool.scaleAbsoluteBlockComponentsBounds(this.getFormDesign().getRootComponent(), 1 / scale); |
||||||
|
} else { |
||||||
|
LayoutTool.scaleAbsoluteBlockComponentsBounds(this.getFormDesign().getRootComponent(), scale); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public JFormType getJFormType() { |
||||||
|
return this.jFormType; |
||||||
|
} |
||||||
|
|
||||||
|
public void setJFormType(JFormType jFormType) { |
||||||
|
this.jFormType = jFormType; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 模板菜单 |
||||||
|
* |
||||||
|
* @return 返回菜单 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public ShortCut[] shortcut4TemplateMenu() { |
||||||
|
if (this.index == FORM_TAB) { |
||||||
|
return ArrayUtils.addAll(new ShortCut[]{new TemplateParameterAction(this), new NewFormMobileAttrAction(this), new FormFitAttrAction(this)}, new ShortCut[0]); |
||||||
|
} else { |
||||||
|
return ArrayUtils.addAll(new ShortCut[]{new TemplateParameterAction(this), new NewFormMobileAttrAction(this), new FormFitAttrAction(this)}, this.getElementCaseDesign().shortcut4TemplateMenu()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void init() { |
||||||
|
this.getFormDesign().addDesignerEditListener(new DesignerEditListener() { |
||||||
|
private Rectangle oldRec; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void fireCreatorModified(DesignerEvent evt) { |
||||||
|
if (evt.getAffectedCreator() == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
if (evt.getCreatorEventID() == DesignerEvent.CREATOR_RESIZED) { |
||||||
|
XComponent affectedCreator = evt.getAffectedCreator(); |
||||||
|
if (isElementCase((JComponent) affectedCreator)) { |
||||||
|
processAbsorbingEffect((XWTitleLayout) affectedCreator); |
||||||
|
} |
||||||
|
} |
||||||
|
if (evt.getCreatorEventID() == DesignerEvent.CREATOR_SELECTED) { |
||||||
|
XComponent affectedCreator = evt.getAffectedCreator(); |
||||||
|
oldRec = new Rectangle(affectedCreator.getBounds()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isElementCase(JComponent component) { |
||||||
|
return component.getComponents().length > 0 && component.getComponent(0) instanceof XElementCase; |
||||||
|
} |
||||||
|
|
||||||
|
private void processAbsorbingEffect(XWTitleLayout xwTitleLayout) { |
||||||
|
NewJForm.this.getFormDesign().repaint(); |
||||||
|
Dimension bound = new Dimension(xwTitleLayout.getSize()); |
||||||
|
ElementCaseEditor elementCaseEditor = (ElementCaseEditor) xwTitleLayout.toData().getBodyBoundsWidget().getWidget(); |
||||||
|
FormElementCaseProvider elementCase = elementCaseEditor.getElementCase(); |
||||||
|
if (oldRec.width != bound.width) { |
||||||
|
processColumnAbsorbingEffect(xwTitleLayout, elementCase.getColumnWidthList_DEC(), bound); |
||||||
|
oldRec.width = bound.width; |
||||||
|
} |
||||||
|
if (oldRec.height != bound.height) { |
||||||
|
processRowAbsorbingEffect(xwTitleLayout, elementCase.getRowHeightList_DEC(), bound); |
||||||
|
oldRec.height = bound.height; |
||||||
|
} |
||||||
|
NewJForm.this.getFormDesign().refreshDesignerUI(); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean hasTitle(XWTitleLayout xwTitleLayout) { |
||||||
|
return xwTitleLayout.getComponentCount() > 1; |
||||||
|
} |
||||||
|
|
||||||
|
private void processColumnAbsorbingEffect(XWTitleLayout xwTitleLayout, DynamicUnitList columnUnitList, Dimension bound) { |
||||||
|
int temp = 0; |
||||||
|
int resolution = DesignerUIModeConfig.getInstance().getScreenResolution();; |
||||||
|
int difference = 0; |
||||||
|
int i = 0; |
||||||
|
while (true) { |
||||||
|
if (i < columnUnitList.size()) { |
||||||
|
temp += columnUnitList.get(i++).toPixI(resolution); |
||||||
|
} else { |
||||||
|
//在处理吸附效果时,columnUnitList数组长度可能比实际显示的列数少,所以用默认值来补充
|
||||||
|
temp += columnUnitList.getDefaultUnit().toPixI(resolution); |
||||||
|
} |
||||||
|
if (bound.width - temp < 0) { |
||||||
|
break; |
||||||
|
} |
||||||
|
if (bound.width - temp < FUZZY_EDGE) { |
||||||
|
difference = bound.width - temp; |
||||||
|
bound.width = temp; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
fixLayout(xwTitleLayout, bound, difference, 0); |
||||||
|
} |
||||||
|
|
||||||
|
private void processRowAbsorbingEffect(XWTitleLayout xwTitleLayout, DynamicUnitList rowUnitList, Dimension bound) { |
||||||
|
int temp = hasTitle(xwTitleLayout) ? TITLE_HEIGHT : 0; |
||||||
|
int resolution =DesignerUIModeConfig.getInstance().getScreenResolution(); |
||||||
|
int difference = 0; |
||||||
|
int i = 0; |
||||||
|
while (true) { |
||||||
|
if (i < rowUnitList.size()) { |
||||||
|
temp += rowUnitList.get(i++).toPixI(resolution); |
||||||
|
} else { |
||||||
|
//在处理吸附效果时,rowUnitList数组长度可能比实际显示的行数少,所以用默认值来补充
|
||||||
|
temp += rowUnitList.getDefaultUnit().toPixI(resolution); |
||||||
|
} |
||||||
|
if (bound.height - temp < 0) { |
||||||
|
break; |
||||||
|
} |
||||||
|
if (bound.height - temp < FUZZY_EDGE) { |
||||||
|
difference = bound.height - temp; |
||||||
|
bound.height = temp; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
fixLayout(xwTitleLayout, bound, difference, 1); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void fixLayout(XWTitleLayout xwTitleLayout, Dimension bound, int difference, int row) { |
||||||
|
Rectangle backupBounds = getBound(xwTitleLayout); |
||||||
|
xwTitleLayout.setSize(bound); |
||||||
|
FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); |
||||||
|
LayoutAdapter adapter = AdapterBus.searchLayoutAdapter(formDesigner, xwTitleLayout); |
||||||
|
if (adapter instanceof FRFitLayoutAdapter) { |
||||||
|
FRFitLayoutAdapter layoutAdapter = (FRFitLayoutAdapter) adapter; |
||||||
|
layoutAdapter.setEdit(true); |
||||||
|
layoutAdapter.calculateBounds(backupBounds, xwTitleLayout.getBounds(), xwTitleLayout, row, difference); |
||||||
|
} |
||||||
|
XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(xwTitleLayout); |
||||||
|
if (parent != null && parent.toData() != null) { |
||||||
|
parent.toData().setBounds(xwTitleLayout.toData(), xwTitleLayout.getBounds()); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public Rectangle getBound(XWTitleLayout creator) { |
||||||
|
Rectangle bounds = new Rectangle(creator.getBounds()); |
||||||
|
if (creator.getParent() == null) { |
||||||
|
return bounds; |
||||||
|
} |
||||||
|
Rectangle rec = ComponentUtils.getRelativeBounds(creator.getParent()); |
||||||
|
bounds.x += rec.x; |
||||||
|
bounds.y += rec.y; |
||||||
|
return bounds; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public PreviewProvider[] supportPreview() { |
||||||
|
if (isNewJFrom()) { |
||||||
|
return new PreviewProvider[]{new FormAdaptivePreview(), new DeveloperPreview(), new MobilePreview()}; |
||||||
|
} |
||||||
|
return new PreviewProvider[]{new FormPreview(), new MobilePreview()}; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean mobileForm() { |
||||||
|
FormMobileAttr mobileAttr = this.getTarget().getFormMobileAttr(); |
||||||
|
if (mobileAttr.isMobileOnly() && mobileAttr.isAdaptivePropertyAutoMatch()) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
private SwitchAction switchAction; |
||||||
|
|
||||||
|
public UIButton[] createExtraButtons() { |
||||||
|
UIButton[] extraButtons = super.createExtraButtons(); |
||||||
|
switchAction = new SwitchAction(); |
||||||
|
return ArrayUtils.addAll(extraButtons, new UIButton[]{switchAction.getToolBarButton()}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public boolean isNewJFrom() { |
||||||
|
return jFormType == null || jFormType.isNewType(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
package com.fr.design.fit; |
||||||
|
|
||||||
|
import com.fr.stable.Constants; |
||||||
|
import com.fr.stable.unit.LEN_UNIT; |
||||||
|
|
||||||
|
public class PX extends LEN_UNIT { |
||||||
|
private static final long FU_SCALE = 36576L; |
||||||
|
|
||||||
|
public PX(float var1) { |
||||||
|
super(var1); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public boolean equals(Object var1) { |
||||||
|
return var1 instanceof PX && super.equals(var1); |
||||||
|
} |
||||||
|
|
||||||
|
protected long getMoreFUScale() { |
||||||
|
int dpi = DesignerUIModeConfig.getInstance().getScreenResolution(); |
||||||
|
return FU_SCALE / dpi; |
||||||
|
} |
||||||
|
|
||||||
|
public static double toPixWithResolution(double value, int resolution) { |
||||||
|
return value * resolution / Constants.FR_PAINT_RESOLUTION; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
package com.fr.design.fit; |
||||||
|
|
||||||
|
import com.fr.design.fun.impl.AbstractReportLengthUNITProvider; |
||||||
|
import com.fr.stable.unit.UNIT; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-04-09 |
||||||
|
*/ |
||||||
|
public class PXReportLengthUNIT extends AbstractReportLengthUNITProvider { |
||||||
|
public static final short UNIT_TYPE = 4; |
||||||
|
|
||||||
|
@Override |
||||||
|
public String unitText() { |
||||||
|
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Px"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int unitType() { |
||||||
|
return UNIT_TYPE; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public float unit2Value4Scale(UNIT value) { |
||||||
|
int resolution = DesignerUIModeConfig.getInstance().getScreenResolution(); |
||||||
|
return value.toPixF(resolution); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public UNIT float2UNIT(float value) { |
||||||
|
return new PX(value); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,91 @@ |
|||||||
|
package com.fr.design.fit.attrpane; |
||||||
|
|
||||||
|
import com.fr.design.designer.IntervalConstants; |
||||||
|
import com.fr.design.designer.creator.CRPropertyDescriptor; |
||||||
|
import com.fr.design.designer.creator.PropertyGroupPane; |
||||||
|
import com.fr.design.designer.creator.XCreator; |
||||||
|
import com.fr.design.designer.creator.XElementCase; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.layout.TableLayoutHelper; |
||||||
|
import com.fr.design.mainframe.widget.accessibles.AccessibleElementCaseToolBarEditor; |
||||||
|
import com.fr.design.widget.ui.designer.component.PaddingBoundPane; |
||||||
|
import com.fr.design.widget.ui.designer.layout.WTitleLayoutDefinePane; |
||||||
|
import com.fr.form.ui.ElementCaseEditor; |
||||||
|
import com.fr.form.web.FormToolBarManager; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.report.fit.ReportFitAttr; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Component; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-04-09 |
||||||
|
*/ |
||||||
|
public class ElementEditorExtendDefinePane extends WTitleLayoutDefinePane<ElementCaseEditor> { |
||||||
|
private PaddingBoundPane paddingBoundPane; |
||||||
|
private AccessibleElementCaseToolBarEditor elementCaseToolBarEditor; |
||||||
|
private PropertyGroupPane extraPropertyGroupPane; |
||||||
|
private PcFitExpandablePane pcFitExpandablePane; |
||||||
|
|
||||||
|
private static final String FIT_STATE_PC = "fitStateInPC"; |
||||||
|
|
||||||
|
public ElementEditorExtendDefinePane(XCreator xCreator) { |
||||||
|
super(xCreator); |
||||||
|
} |
||||||
|
|
||||||
|
protected JPanel createCenterPane() { |
||||||
|
JPanel centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
paddingBoundPane = new PaddingBoundPane(); |
||||||
|
elementCaseToolBarEditor = new AccessibleElementCaseToolBarEditor(); |
||||||
|
Component[][] components = new Component[][]{ |
||||||
|
new Component[]{paddingBoundPane, null}, |
||||||
|
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_EC_Toolbar")), elementCaseToolBarEditor}, |
||||||
|
}; |
||||||
|
JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W0, IntervalConstants.INTERVAL_L1); |
||||||
|
panel.setBorder(BorderFactory.createEmptyBorder(5, 0, 10, 0)); |
||||||
|
CRPropertyDescriptor[] extraTableEditor = removeOldFitEditor(((XElementCase) creator).getExtraTableEditor()); |
||||||
|
extraPropertyGroupPane = new PropertyGroupPane(extraTableEditor, creator); |
||||||
|
centerPane.add(panel, BorderLayout.NORTH); |
||||||
|
if (extraTableEditor.length > 0) { |
||||||
|
centerPane.add(extraPropertyGroupPane, BorderLayout.CENTER); |
||||||
|
} |
||||||
|
pcFitExpandablePane = new PcFitExpandablePane(this); |
||||||
|
centerPane.add(pcFitExpandablePane, BorderLayout.SOUTH); |
||||||
|
return centerPane; |
||||||
|
} |
||||||
|
|
||||||
|
private CRPropertyDescriptor[] removeOldFitEditor(CRPropertyDescriptor[] extraTableEditor) { |
||||||
|
List<CRPropertyDescriptor> list = new ArrayList<CRPropertyDescriptor>(); |
||||||
|
for (CRPropertyDescriptor crPropertyDescriptor : extraTableEditor) { |
||||||
|
if (!ComparatorUtils.equals(FIT_STATE_PC, crPropertyDescriptor.getName())) { |
||||||
|
list.add(crPropertyDescriptor); |
||||||
|
} |
||||||
|
} |
||||||
|
return list.toArray(new CRPropertyDescriptor[list.size()]); |
||||||
|
} |
||||||
|
|
||||||
|
protected ElementCaseEditor updateSubBean() { |
||||||
|
ElementCaseEditor elementCaseEditor = (ElementCaseEditor) creator.toData(); |
||||||
|
if (ComparatorUtils.equals(getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Padding_Duplicate"))) { |
||||||
|
paddingBoundPane.update(elementCaseEditor); |
||||||
|
} |
||||||
|
elementCaseEditor.setToolBars((FormToolBarManager[]) elementCaseToolBarEditor.getValue()); |
||||||
|
ReportFitAttr fitAttr = pcFitExpandablePane.update(); |
||||||
|
elementCaseEditor.setReportFitAttr(fitAttr); |
||||||
|
return elementCaseEditor; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
protected void populateSubBean(ElementCaseEditor ob) { |
||||||
|
paddingBoundPane.populate(ob); |
||||||
|
elementCaseToolBarEditor.setValue(ob.getToolBars()); |
||||||
|
extraPropertyGroupPane.populate(ob); |
||||||
|
pcFitExpandablePane.populate(ob.getReportFitAttr()); |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,161 @@ |
|||||||
|
package com.fr.design.fit.attrpane; |
||||||
|
|
||||||
|
import com.fr.base.io.IOFile; |
||||||
|
import com.fr.base.iofile.attr.WatermarkAttr; |
||||||
|
import com.fr.design.data.DataCreatorUI; |
||||||
|
import com.fr.design.designer.IntervalConstants; |
||||||
|
import com.fr.design.designer.creator.XCreator; |
||||||
|
import com.fr.design.designer.creator.XWFitLayout; |
||||||
|
import com.fr.design.designer.properties.items.FRLayoutTypeItems; |
||||||
|
import com.fr.design.designer.properties.items.Item; |
||||||
|
import com.fr.design.foldablepane.UIExpandablePane; |
||||||
|
import com.fr.design.gui.icombobox.UIComboBox; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.layout.TableLayout; |
||||||
|
import com.fr.design.layout.TableLayoutHelper; |
||||||
|
import com.fr.design.mainframe.WidgetPropertyPane; |
||||||
|
import com.fr.design.mainframe.widget.accessibles.AccessibleBodyWatermarkEditor; |
||||||
|
import com.fr.design.mainframe.widget.accessibles.AccessibleWLayoutBorderStyleEditor; |
||||||
|
import com.fr.design.utils.gui.UIComponentUtils; |
||||||
|
import com.fr.design.widget.FRWidgetFactory; |
||||||
|
import com.fr.design.widget.ui.designer.layout.FRAbsoluteLayoutDefinePane; |
||||||
|
import com.fr.form.ui.LayoutBorderStyle; |
||||||
|
import com.fr.form.ui.container.WAbsoluteBodyLayout; |
||||||
|
import com.fr.form.ui.container.WAbsoluteLayout; |
||||||
|
import com.fr.form.ui.container.WBodyLayoutType; |
||||||
|
import com.fr.report.core.ReportUtils; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.DefaultComboBoxModel; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Component; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-04-22 |
||||||
|
*/ |
||||||
|
public class FRAbsoluteBodyLayoutExtendDefinePane extends FRAbsoluteLayoutDefinePane { |
||||||
|
private static final int MAX_LABEL_WIDTH = 80; |
||||||
|
|
||||||
|
private AccessibleWLayoutBorderStyleEditor borderStyleEditor; |
||||||
|
private AccessibleBodyWatermarkEditor watermarkEditor; |
||||||
|
|
||||||
|
private UIComboBox layoutCombox; |
||||||
|
private WBodyLayoutType layoutType = WBodyLayoutType.ABSOLUTE; |
||||||
|
|
||||||
|
public FRAbsoluteBodyLayoutExtendDefinePane(XCreator xCreator) { |
||||||
|
super(xCreator); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void initComponent() { |
||||||
|
initCenterPane(); |
||||||
|
JPanel centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
borderStyleEditor = new AccessibleWLayoutBorderStyleEditor(); |
||||||
|
watermarkEditor = new AccessibleBodyWatermarkEditor(); |
||||||
|
JPanel jPanel = TableLayoutHelper.createGapTableLayoutPane( |
||||||
|
new Component[][]{ |
||||||
|
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style")), borderStyleEditor}, |
||||||
|
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_WaterMark")), watermarkEditor} |
||||||
|
}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W3, IntervalConstants.INTERVAL_L1); |
||||||
|
JPanel borderPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
jPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); |
||||||
|
borderPane.add(jPanel, BorderLayout.CENTER); |
||||||
|
UIExpandablePane advancedPane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Advanced"), 280, 20, borderPane); |
||||||
|
centerPane.add(advancedPane, BorderLayout.NORTH); |
||||||
|
this.add(centerPane, BorderLayout.NORTH); |
||||||
|
} |
||||||
|
|
||||||
|
private void initCenterPane(){ |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
initUIComboBox(); |
||||||
|
JPanel thirdPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
JPanel jPanel = createThirdPane(); |
||||||
|
jPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); |
||||||
|
thirdPane.add(jPanel, BorderLayout.CENTER); |
||||||
|
UIExpandablePane layoutExpandablePane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout"), 280, 20, thirdPane); |
||||||
|
this.add(layoutExpandablePane, BorderLayout.CENTER); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public JPanel createThirdPane() { |
||||||
|
initLayoutComboBox(); |
||||||
|
JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
double p = TableLayout.PREFERRED; |
||||||
|
double f = TableLayout.FILL; |
||||||
|
double[] rowSize = {p}; |
||||||
|
double[] colSize = {p, f}; |
||||||
|
|
||||||
|
UILabel layoutTypeLabel = FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Layout_Type")); |
||||||
|
JPanel northPane = TableLayoutHelper.createGapTableLayoutPane( |
||||||
|
new Component[][]{ |
||||||
|
new Component[]{layoutTypeLabel, UIComponentUtils.wrapWithBorderLayoutPane(layoutCombox)}}, |
||||||
|
rowSize, colSize, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); |
||||||
|
jPanel.add(northPane, BorderLayout.NORTH); |
||||||
|
return jPanel; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public void initLayoutComboBox() { |
||||||
|
Item[] items = FRLayoutTypeItems.ITEMS; |
||||||
|
DefaultComboBoxModel model = new DefaultComboBoxModel(); |
||||||
|
for (Item item : items) { |
||||||
|
model.addElement(item); |
||||||
|
} |
||||||
|
layoutCombox = new UIComboBox(model); |
||||||
|
layoutCombox.setSelectedIndex(1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String title4PopupWindow() { |
||||||
|
return "absoluteBodyLayout"; |
||||||
|
} |
||||||
|
|
||||||
|
public void populateSubPane(WAbsoluteLayout ob) { |
||||||
|
layoutCombox.setSelectedIndex(1); |
||||||
|
borderStyleEditor.setValue(ob.getBorderStyle()); |
||||||
|
watermarkEditor.setValue(ReportUtils.getWatermarkAttrFromTemplate(getCurrentIOFile())); |
||||||
|
} |
||||||
|
|
||||||
|
public WAbsoluteBodyLayout updateSubPane() { |
||||||
|
WAbsoluteBodyLayout layout = (WAbsoluteBodyLayout) creator.toData(); |
||||||
|
Item item = (Item) layoutCombox.getSelectedItem(); |
||||||
|
Object value = item.getValue(); |
||||||
|
int state = 0; |
||||||
|
if (value instanceof Integer) { |
||||||
|
state = (Integer) value; |
||||||
|
} |
||||||
|
|
||||||
|
if (layoutType == WBodyLayoutType.ABSOLUTE) { |
||||||
|
((XWFitLayout) creator.getBackupParent()).toData().resetStyle(); |
||||||
|
if (state == WBodyLayoutType.FIT.getTypeValue()) { |
||||||
|
XWFitLayout xwFitLayout = ((XWFitLayout)creator.getBackupParent()); |
||||||
|
xwFitLayout.switch2FitBodyLayout(creator); |
||||||
|
copyLayoutAttr(layout, xwFitLayout.toData()); |
||||||
|
} |
||||||
|
} |
||||||
|
layout.setBorderStyle((LayoutBorderStyle) borderStyleEditor.getValue()); |
||||||
|
updateWatermark(); |
||||||
|
return layout; |
||||||
|
} |
||||||
|
|
||||||
|
private void updateWatermark() { |
||||||
|
WatermarkAttr watermark = (WatermarkAttr) watermarkEditor.getValue(); |
||||||
|
if (watermark != null) { |
||||||
|
IOFile ioFile = getCurrentIOFile(); |
||||||
|
ioFile.addAttrMark(watermark); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private IOFile getCurrentIOFile() { |
||||||
|
return WidgetPropertyPane.getInstance().getEditingFormDesigner().getTarget(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DataCreatorUI dataUI() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
package com.fr.design.fit.attrpane; |
||||||
|
|
||||||
|
import com.fr.design.designer.creator.XCreator; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.widget.ui.designer.layout.AbstractFRLayoutDefinePane; |
||||||
|
import com.fr.form.ui.container.WAbsoluteLayout; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-04-22 |
||||||
|
*/ |
||||||
|
public class FRAbsoluteLayoutExtendDefinePane extends AbstractFRLayoutDefinePane<WAbsoluteLayout> { |
||||||
|
|
||||||
|
public FRAbsoluteLayoutExtendDefinePane(XCreator xCreator) { |
||||||
|
super(xCreator); |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void populateBean(WAbsoluteLayout ob) { |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public WAbsoluteLayout updateBean() { |
||||||
|
WAbsoluteLayout wAbsoluteLayout = (WAbsoluteLayout) creator.toData(); |
||||||
|
return wAbsoluteLayout; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,246 @@ |
|||||||
|
package com.fr.design.fit.attrpane; |
||||||
|
|
||||||
|
import com.fr.base.io.IOFile; |
||||||
|
import com.fr.base.iofile.attr.WatermarkAttr; |
||||||
|
import com.fr.design.data.DataCreatorUI; |
||||||
|
import com.fr.design.designer.IntervalConstants; |
||||||
|
import com.fr.design.designer.creator.XCreator; |
||||||
|
import com.fr.design.designer.creator.XLayoutContainer; |
||||||
|
import com.fr.design.designer.creator.XWAbsoluteBodyLayout; |
||||||
|
import com.fr.design.designer.creator.XWFitLayout; |
||||||
|
import com.fr.design.designer.creator.XWScaleLayout; |
||||||
|
import com.fr.design.designer.properties.items.FRLayoutTypeItems; |
||||||
|
import com.fr.design.designer.properties.items.Item; |
||||||
|
import com.fr.design.foldablepane.UIExpandablePane; |
||||||
|
import com.fr.design.gui.icombobox.UIComboBox; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.gui.ispinner.UISpinner; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.layout.TableLayout; |
||||||
|
import com.fr.design.layout.TableLayoutHelper; |
||||||
|
import com.fr.design.mainframe.FormDesigner; |
||||||
|
import com.fr.design.mainframe.FormSelectionUtils; |
||||||
|
import com.fr.design.mainframe.WidgetPropertyPane; |
||||||
|
import com.fr.design.mainframe.widget.accessibles.AccessibleBodyWatermarkEditor; |
||||||
|
import com.fr.design.mainframe.widget.accessibles.AccessibleWLayoutBorderStyleEditor; |
||||||
|
import com.fr.design.utils.gui.UIComponentUtils; |
||||||
|
import com.fr.design.widget.FRWidgetFactory; |
||||||
|
import com.fr.design.widget.ui.designer.component.PaddingBoundPane; |
||||||
|
import com.fr.design.widget.ui.designer.layout.AbstractFRLayoutDefinePane; |
||||||
|
import com.fr.form.ui.LayoutBorderStyle; |
||||||
|
import com.fr.form.ui.Widget; |
||||||
|
import com.fr.form.ui.container.WAbsoluteBodyLayout; |
||||||
|
import com.fr.form.ui.container.WAbsoluteLayout; |
||||||
|
import com.fr.form.ui.container.WBodyLayoutType; |
||||||
|
import com.fr.form.ui.container.WFitLayout; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.report.core.ReportUtils; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.DefaultComboBoxModel; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Dimension; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-04-22 |
||||||
|
*/ |
||||||
|
public class FRFitLayoutExtendDefinePane extends AbstractFRLayoutDefinePane<WFitLayout> { |
||||||
|
private static final int ADAPT_LABEL_MAX_WIDTH = 80; |
||||||
|
private XWFitLayout xWFitLayout; |
||||||
|
private WFitLayout wFitLayout; |
||||||
|
private UIComboBox layoutComboBox; |
||||||
|
private UISpinner componentIntervel; |
||||||
|
private PaddingBoundPane paddingBound; |
||||||
|
private AccessibleWLayoutBorderStyleEditor stylePane; |
||||||
|
private AccessibleBodyWatermarkEditor watermarkEditor; |
||||||
|
|
||||||
|
public FRFitLayoutExtendDefinePane(XCreator xCreator) { |
||||||
|
super(xCreator); |
||||||
|
this.xWFitLayout = (XWFitLayout) xCreator; |
||||||
|
wFitLayout = xWFitLayout.toData(); |
||||||
|
initComponent(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void initComponent() { |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
JPanel advancePane = createAdvancePane(); |
||||||
|
UIExpandablePane advanceExpandablePane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Advanced"), 280, 20, advancePane); |
||||||
|
this.add(advanceExpandablePane, BorderLayout.NORTH); |
||||||
|
UIExpandablePane layoutExpandablePane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout"), 280, 20, createLayoutPane()); |
||||||
|
this.add(layoutExpandablePane, BorderLayout.CENTER); |
||||||
|
} |
||||||
|
|
||||||
|
public JPanel createAdvancePane() { |
||||||
|
JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
stylePane = new AccessibleWLayoutBorderStyleEditor(); |
||||||
|
watermarkEditor = new AccessibleBodyWatermarkEditor(); |
||||||
|
paddingBound = new PaddingBoundPane(); |
||||||
|
JPanel jp2 = TableLayoutHelper.createGapTableLayoutPane( |
||||||
|
new Component[][]{ |
||||||
|
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style")), stylePane}, |
||||||
|
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_WaterMark")), watermarkEditor} |
||||||
|
}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W3, IntervalConstants.INTERVAL_L1); |
||||||
|
jp2.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); |
||||||
|
jPanel.add(paddingBound, BorderLayout.CENTER); |
||||||
|
jPanel.add(jp2, BorderLayout.NORTH); |
||||||
|
return jPanel; |
||||||
|
} |
||||||
|
|
||||||
|
public JPanel createLayoutPane() { |
||||||
|
JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
jPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); |
||||||
|
layoutComboBox = initUIComboBox(FRLayoutTypeItems.ITEMS); |
||||||
|
componentIntervel = new UISpinner(0, Integer.MAX_VALUE, 1, 0); |
||||||
|
JPanel componentIntervelPane = UIComponentUtils.wrapWithBorderLayoutPane(componentIntervel); |
||||||
|
|
||||||
|
UILabel intervalLabel = FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Component_Interval")); |
||||||
|
|
||||||
|
double f = TableLayout.FILL; |
||||||
|
double p = TableLayout.PREFERRED; |
||||||
|
double[] rowSize = {p, p}; |
||||||
|
double[] columnSize = {p, f}; |
||||||
|
int[][] rowCount = {{1, 1}, {1, 1}}; |
||||||
|
|
||||||
|
|
||||||
|
Component[][] components = new Component[][]{ |
||||||
|
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Layout_Type")), layoutComboBox}, |
||||||
|
new Component[]{intervalLabel, componentIntervelPane} |
||||||
|
}; |
||||||
|
JPanel centerPane = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); |
||||||
|
centerPane.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, 0, 0)); |
||||||
|
jPanel.add(centerPane, BorderLayout.CENTER); |
||||||
|
return jPanel; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public UIComboBox initUIComboBox(Item[] items) { |
||||||
|
DefaultComboBoxModel model = new DefaultComboBoxModel(); |
||||||
|
for (Item item : items) { |
||||||
|
model.addElement(item); |
||||||
|
} |
||||||
|
return new UIComboBox(model); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public String title4PopupWindow() { |
||||||
|
return "fitLayout"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void populateBean(WFitLayout ob) { |
||||||
|
FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); |
||||||
|
XLayoutContainer rootLayout = selectedBodyLayout(formDesigner); |
||||||
|
if (rootLayout != formDesigner.getRootComponent() |
||||||
|
&& formDesigner.getSelectionModel().getSelection().getSelectedCreator() == formDesigner.getRootComponent()) { |
||||||
|
formDesigner.getSelectionModel().setSelectedCreators( |
||||||
|
FormSelectionUtils.rebuildSelection(xWFitLayout, new Widget[]{selectedBodyLayout(formDesigner).toData()})); |
||||||
|
|
||||||
|
} |
||||||
|
paddingBound.populate(ob); |
||||||
|
layoutComboBox.setSelectedIndex(ob.getBodyLayoutType().getTypeValue()); |
||||||
|
componentIntervel.setValue(ob.getCompInterval()); |
||||||
|
stylePane.setValue(ob.getBorderStyle()); |
||||||
|
watermarkEditor.setValue(ReportUtils.getWatermarkAttrFromTemplate(getCurrentIOFile())); |
||||||
|
} |
||||||
|
|
||||||
|
private XLayoutContainer selectedBodyLayout(FormDesigner formDesigner) { |
||||||
|
XLayoutContainer rootLayout = formDesigner.getRootComponent(); |
||||||
|
if (rootLayout.getComponentCount() == 1 && rootLayout.getXCreator(0).acceptType(XWAbsoluteBodyLayout.class)) { |
||||||
|
rootLayout = (XWAbsoluteBodyLayout) rootLayout.getXCreator(0); |
||||||
|
} |
||||||
|
return rootLayout; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public WFitLayout updateBean() { |
||||||
|
WFitLayout layout = (WFitLayout) creator.toData(); |
||||||
|
if (ComparatorUtils.equals(getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Padding_Duplicate"))) { |
||||||
|
paddingBound.update(layout); |
||||||
|
} |
||||||
|
LayoutBorderStyle borderStyle = (LayoutBorderStyle) stylePane.getValue(); |
||||||
|
if (borderStyle != null) { |
||||||
|
layout.setBorderStyle(borderStyle); |
||||||
|
} |
||||||
|
updateWatermark(); |
||||||
|
Item item = (Item) layoutComboBox.getSelectedItem(); |
||||||
|
Object value = item.getValue(); |
||||||
|
int state = 0; |
||||||
|
if (value instanceof Integer) { |
||||||
|
state = (Integer) value; |
||||||
|
} |
||||||
|
//todo 验证下
|
||||||
|
layout.setLayoutType(WBodyLayoutType.parse(state)); |
||||||
|
try { |
||||||
|
if (state == WBodyLayoutType.ABSOLUTE.getTypeValue()) { |
||||||
|
WAbsoluteBodyLayout wAbsoluteBodyLayout = new WAbsoluteBodyLayout("body"); |
||||||
|
wAbsoluteBodyLayout.setCompState(WAbsoluteLayout.STATE_FIXED); |
||||||
|
Component[] components = xWFitLayout.getComponents(); |
||||||
|
xWFitLayout.removeAll(); |
||||||
|
layout.resetStyle(); |
||||||
|
XWAbsoluteBodyLayout xwAbsoluteBodyLayout = xWFitLayout.getBackupParent() == null ? new XWAbsoluteBodyLayout(wAbsoluteBodyLayout, new Dimension(0, 0)) : (XWAbsoluteBodyLayout) xWFitLayout.getBackupParent(); |
||||||
|
xWFitLayout.getLayoutAdapter().addBean(xwAbsoluteBodyLayout, 0, 0); |
||||||
|
for (Component component : components) { |
||||||
|
XCreator xCreator = (XCreator) component; |
||||||
|
//部分控件被ScaleLayout包裹着,绝对布局里面要放出来
|
||||||
|
if (xCreator.acceptType(XWScaleLayout.class)) { |
||||||
|
if (xCreator.getComponentCount() > 0 && ((XCreator) xCreator.getComponent(0)).shouldScaleCreator()) { |
||||||
|
component = xCreator.getComponent(0); |
||||||
|
component.setBounds(xCreator.getBounds()); |
||||||
|
} |
||||||
|
} |
||||||
|
xwAbsoluteBodyLayout.add(component); |
||||||
|
} |
||||||
|
copyLayoutAttr(wFitLayout, wAbsoluteBodyLayout); |
||||||
|
xWFitLayout.setBackupParent(xwAbsoluteBodyLayout); |
||||||
|
FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); |
||||||
|
formDesigner.getSelectionModel().setSelectedCreators( |
||||||
|
FormSelectionUtils.rebuildSelection(xWFitLayout, new Widget[]{wAbsoluteBodyLayout})); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
int intervelValue = (int) componentIntervel.getValue(); |
||||||
|
if (xWFitLayout.canAddInterval(intervelValue)) { |
||||||
|
// 设置完间隔后,要同步处理界面组件,容器刷新后显示出对应效果
|
||||||
|
setLayoutGap(intervelValue); |
||||||
|
} |
||||||
|
|
||||||
|
return layout; |
||||||
|
} |
||||||
|
|
||||||
|
private void updateWatermark() { |
||||||
|
WatermarkAttr watermark = (WatermarkAttr) watermarkEditor.getValue(); |
||||||
|
if (watermark != null) { |
||||||
|
IOFile ioFile = getCurrentIOFile(); |
||||||
|
ioFile.addAttrMark(watermark); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private IOFile getCurrentIOFile() { |
||||||
|
return WidgetPropertyPane.getInstance().getEditingFormDesigner().getTarget(); |
||||||
|
} |
||||||
|
|
||||||
|
private void setLayoutGap(int value) { |
||||||
|
int interval = wFitLayout.getCompInterval(); |
||||||
|
if (value != interval) { |
||||||
|
xWFitLayout.moveContainerMargin(); |
||||||
|
xWFitLayout.moveCompInterval(xWFitLayout.getAcualInterval()); |
||||||
|
wFitLayout.setCompInterval(value); |
||||||
|
xWFitLayout.addCompInterval(xWFitLayout.getAcualInterval()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DataCreatorUI dataUI() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,107 @@ |
|||||||
|
package com.fr.design.fit.attrpane; |
||||||
|
|
||||||
|
import com.fr.design.designer.IntervalConstants; |
||||||
|
import com.fr.design.fit.FitStateCompatible; |
||||||
|
import com.fr.design.gui.icombobox.UIComboBox; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.layout.TableLayoutHelper; |
||||||
|
import com.fr.design.widget.DataModify; |
||||||
|
import com.fr.report.fit.FitAttrState; |
||||||
|
import com.fr.report.fit.ReportFitAttr; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.event.ItemEvent; |
||||||
|
import java.awt.event.ItemListener; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-04-22 |
||||||
|
*/ |
||||||
|
public class PcFitExpandablePane extends JPanel { |
||||||
|
UIComboBox comboBox = new UIComboBox( |
||||||
|
new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit_Ec_Double_Fit"), |
||||||
|
com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit_Ec_Hor_Fit"), |
||||||
|
com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit_Ec_No_Fit")}); |
||||||
|
UILabel tipLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit_Ec_No_Fit_Tip")); |
||||||
|
|
||||||
|
public PcFitExpandablePane(DataModify attrPane) { |
||||||
|
init(attrPane); |
||||||
|
} |
||||||
|
|
||||||
|
public void init(final DataModify attrPane) { |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
JPanel pcFitPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
final JPanel borderPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
borderPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0)); |
||||||
|
tipLabel.setForeground(Color.gray); |
||||||
|
comboBox.addItemListener(new ItemListener() { |
||||||
|
@Override |
||||||
|
public void itemStateChanged(ItemEvent e) { |
||||||
|
tipLabel.setText(ScaleTipType.getScaleTip(comboBox.getSelectedIndex()).getTip()); |
||||||
|
} |
||||||
|
}); |
||||||
|
Component[][] components = new Component[][]{ |
||||||
|
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit_Ec_Content_Display_Type")), comboBox}, |
||||||
|
new Component[]{tipLabel, null}, |
||||||
|
}; |
||||||
|
JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W0, IntervalConstants.INTERVAL_W0); |
||||||
|
panel.setBorder(BorderFactory.createEmptyBorder(5, 0, 10, 0)); |
||||||
|
|
||||||
|
borderPane.add(panel, BorderLayout.CENTER); |
||||||
|
borderPane.add(tipLabel, BorderLayout.SOUTH); |
||||||
|
pcFitPane.add(borderPane, BorderLayout.CENTER); |
||||||
|
this.add(pcFitPane, BorderLayout.CENTER); |
||||||
|
} |
||||||
|
|
||||||
|
public ReportFitAttr update() { |
||||||
|
ReportFitAttr fitAttr = getReportFitAttr(); |
||||||
|
fitAttr.setFitStateInPC(FitStateCompatible.getOldTypeFromNew(comboBox.getSelectedIndex())); |
||||||
|
return fitAttr; |
||||||
|
} |
||||||
|
|
||||||
|
public void populate(ReportFitAttr fitAttr) { |
||||||
|
if (fitAttr == null) { |
||||||
|
fitAttr = getReportFitAttr(); |
||||||
|
} |
||||||
|
int selectIndex = FitStateCompatible.getNewTypeFromOld(fitAttr.fitStateInPC()); |
||||||
|
comboBox.setSelectedIndex(selectIndex); |
||||||
|
tipLabel.setText(ScaleTipType.getScaleTip(selectIndex).getTip()); |
||||||
|
} |
||||||
|
|
||||||
|
private ReportFitAttr getReportFitAttr() { |
||||||
|
ReportFitAttr fitAttr = new ReportFitAttr(); |
||||||
|
fitAttr.setFitStateInPC(FitAttrState.NOT_FIT.getState()); |
||||||
|
return fitAttr; |
||||||
|
} |
||||||
|
|
||||||
|
private enum ScaleTipType { |
||||||
|
EC_DOUBLE_FIT(0, com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit_Ec_Double_Fit_Tip")), |
||||||
|
EC_HOR_FIT(1, com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit_Ec_Hor_Fit_Tip")), |
||||||
|
EC_NO_FIT(2, com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit_Ec_No_Fit_Tip")); |
||||||
|
private int index; |
||||||
|
private String tip; |
||||||
|
|
||||||
|
ScaleTipType(int index, String tip) { |
||||||
|
this.index = index; |
||||||
|
this.tip = tip; |
||||||
|
} |
||||||
|
|
||||||
|
public String getTip() { |
||||||
|
return tip; |
||||||
|
} |
||||||
|
|
||||||
|
public static ScaleTipType getScaleTip(int selectIndex) { |
||||||
|
for (ScaleTipType tipType : values()) { |
||||||
|
if (selectIndex == tipType.index) { |
||||||
|
return tipType; |
||||||
|
} |
||||||
|
} |
||||||
|
return EC_NO_FIT; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,303 @@ |
|||||||
|
package com.fr.design.fit.attrpane; |
||||||
|
|
||||||
|
import com.fr.base.BaseUtils; |
||||||
|
import com.fr.design.ExtraDesignClassManager; |
||||||
|
import com.fr.design.data.DataCreatorUI; |
||||||
|
import com.fr.design.designer.IntervalConstants; |
||||||
|
import com.fr.design.designer.creator.CRPropertyDescriptor; |
||||||
|
import com.fr.design.designer.creator.PropertyGroupPane; |
||||||
|
import com.fr.design.designer.creator.XCreator; |
||||||
|
import com.fr.design.designer.creator.XWParameterLayout; |
||||||
|
import com.fr.design.designer.properties.PropertyTab; |
||||||
|
import com.fr.design.file.HistoryTemplateListPane; |
||||||
|
import com.fr.design.fit.DesignerUIModeConfig; |
||||||
|
import com.fr.design.fit.common.TemplateTool; |
||||||
|
import com.fr.design.foldablepane.UIExpandablePane; |
||||||
|
import com.fr.design.fun.ParameterExpandablePaneUIProvider; |
||||||
|
import com.fr.design.gui.ibutton.UIButtonGroup; |
||||||
|
import com.fr.design.gui.icheckbox.UICheckBox; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.gui.ispinner.UISpinner; |
||||||
|
import com.fr.design.gui.itextfield.UITextField; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.layout.TableLayout; |
||||||
|
import com.fr.design.layout.TableLayoutHelper; |
||||||
|
import com.fr.design.mainframe.FormDesigner; |
||||||
|
import com.fr.design.mainframe.FormSelection; |
||||||
|
import com.fr.design.mainframe.JTemplate; |
||||||
|
import com.fr.design.mainframe.widget.accessibles.AccessibleBackgroundEditor; |
||||||
|
import com.fr.design.utils.gui.LayoutUtils; |
||||||
|
import com.fr.design.utils.gui.UIComponentUtils; |
||||||
|
import com.fr.design.widget.ui.designer.AbstractDataModify; |
||||||
|
import com.fr.design.widget.ui.designer.component.UIBoundSpinner; |
||||||
|
import com.fr.form.ui.container.WParameterLayout; |
||||||
|
import com.fr.general.Background; |
||||||
|
import com.fr.report.stable.FormConstants; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.Icon; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Rectangle; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
public class RootDesignExtendDefinePane extends AbstractDataModify<WParameterLayout> { |
||||||
|
private XWParameterLayout root; |
||||||
|
private UISpinner designerWidth; |
||||||
|
private UISpinner paraHeight; |
||||||
|
private UICheckBox displayReport; |
||||||
|
private UICheckBox useParamsTemplate; |
||||||
|
private AccessibleBackgroundEditor background; |
||||||
|
private UIButtonGroup hAlignmentPane; |
||||||
|
private UITextField labelNameTextField; |
||||||
|
//是否是新设计模式下决策报表
|
||||||
|
private boolean newForm; |
||||||
|
private PropertyGroupPane extraPropertyGroupPane; |
||||||
|
|
||||||
|
public RootDesignExtendDefinePane(XCreator xCreator) { |
||||||
|
super(xCreator); |
||||||
|
newForm = TemplateTool.getCurrentEditingNewJForm() != null && DesignerUIModeConfig.getInstance().newUIMode(); |
||||||
|
this.root = (XWParameterLayout) xCreator; |
||||||
|
initComponent(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void initComponent() { |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
if (newForm) { |
||||||
|
paraHeight = new UIBoundSpinner(0, Integer.MAX_VALUE, 1, 0); |
||||||
|
} else { |
||||||
|
designerWidth = new UIBoundSpinner(1, Integer.MAX_VALUE, 1); |
||||||
|
} |
||||||
|
JPanel advancePane = createAdvancePane(); |
||||||
|
UIExpandablePane advanceExpandablePane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Advanced"), 280, 20, advancePane); |
||||||
|
this.add(advanceExpandablePane, BorderLayout.NORTH); |
||||||
|
JPanel layoutPane = createBoundsPane(); |
||||||
|
UIExpandablePane layoutExpandablePane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Size"), 280, 20, layoutPane); |
||||||
|
this.add(layoutExpandablePane, BorderLayout.CENTER); |
||||||
|
this.addExtraUIExpandablePaneFromPlugin(); |
||||||
|
} |
||||||
|
|
||||||
|
private void addExtraUIExpandablePaneFromPlugin() { |
||||||
|
Set<ParameterExpandablePaneUIProvider> pluginCreators = ExtraDesignClassManager.getInstance().getArray(ParameterExpandablePaneUIProvider.XML_TAG); |
||||||
|
JPanel panel = FRGUIPaneFactory.createYBoxEmptyBorderPane(); |
||||||
|
for (ParameterExpandablePaneUIProvider provider : pluginCreators) { |
||||||
|
UIExpandablePane uiExpandablePane = provider.createUIExpandablePane(); |
||||||
|
PropertyTab propertyTab = provider.addToWhichPropertyTab(); |
||||||
|
if (uiExpandablePane != null && propertyTab == PropertyTab.ATTR) { |
||||||
|
panel.add(uiExpandablePane); |
||||||
|
} |
||||||
|
} |
||||||
|
this.add(panel, BorderLayout.SOUTH); |
||||||
|
} |
||||||
|
|
||||||
|
public JPanel createBoundsPane() { |
||||||
|
double f = TableLayout.FILL; |
||||||
|
double p = TableLayout.PREFERRED; |
||||||
|
double[] rowSize = {p}; |
||||||
|
double[] columnSize = {p, f}; |
||||||
|
int[][] rowCount = {{1, 1}}; |
||||||
|
Component[] component = newForm ? new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit_Design_Height")), paraHeight} : |
||||||
|
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Desin_Width")), designerWidth}; |
||||||
|
Component[][] components = new Component[][]{component}; |
||||||
|
JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); |
||||||
|
JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); |
||||||
|
jPanel.add(panel); |
||||||
|
return jPanel; |
||||||
|
} |
||||||
|
|
||||||
|
public JPanel createAdvancePane() { |
||||||
|
if (newForm) { |
||||||
|
return getNewFormAdvancePane(); |
||||||
|
} else { |
||||||
|
return getTemplateAdvancePane(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @Description: 获取的非新决策报表AdvancePane |
||||||
|
* @param |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/11/05 15:36 |
||||||
|
*/ |
||||||
|
private JPanel getTemplateAdvancePane() { |
||||||
|
JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
labelNameTextField = new UITextField(); |
||||||
|
displayReport = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Display_Nothing_Before_Query")); |
||||||
|
UIComponentUtils.setLineWrap(displayReport); |
||||||
|
useParamsTemplate = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Use_Params_Template")); |
||||||
|
background = new AccessibleBackgroundEditor(); |
||||||
|
Icon[] hAlignmentIconArray = {BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_left_normal.png"), |
||||||
|
BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_center_normal.png"), |
||||||
|
BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_right_normal.png"),}; |
||||||
|
Integer[] hAlignment = new Integer[]{FormConstants.LEFTPOSITION, FormConstants.CENTERPOSITION, FormConstants.RIGHTPOSITION}; |
||||||
|
hAlignmentPane = new UIButtonGroup<Integer>(hAlignmentIconArray, hAlignment); |
||||||
|
hAlignmentPane.setAllToolTips(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_StyleAlignment_Left") |
||||||
|
, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_StyleAlignment_Center"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_StyleAlignment_Right")}); |
||||||
|
double f = TableLayout.FILL; |
||||||
|
double p = TableLayout.PREFERRED; |
||||||
|
double[] rowSize = {p, p, p, p, p}; |
||||||
|
double[] columnSize = {p, f}; |
||||||
|
int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}; |
||||||
|
Component[][] components = new Component[][]{ |
||||||
|
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Label_Name")), labelNameTextField}, |
||||||
|
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Base_Background")), background}, |
||||||
|
new Component[]{displayReport, null}, |
||||||
|
new Component[]{useParamsTemplate, null}, |
||||||
|
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Display_Position")), hAlignmentPane} |
||||||
|
}; |
||||||
|
JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W0, IntervalConstants.INTERVAL_L1); |
||||||
|
panel.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, IntervalConstants.INTERVAL_L1, 0)); |
||||||
|
CRPropertyDescriptor[] extraTableEditor = new CRPropertyDescriptor[0]; |
||||||
|
extraTableEditor = root.getExtraTableEditor(); |
||||||
|
extraPropertyGroupPane = new PropertyGroupPane(extraTableEditor, root); |
||||||
|
|
||||||
|
jPanel.add(panel, BorderLayout.NORTH); |
||||||
|
jPanel.add(extraPropertyGroupPane, BorderLayout.CENTER); |
||||||
|
return jPanel; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @Description: 获取新决策报表的AdvancePane |
||||||
|
* @param |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/11/05 15:36 |
||||||
|
*/ |
||||||
|
private JPanel getNewFormAdvancePane() { |
||||||
|
JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
labelNameTextField = new UITextField(); |
||||||
|
displayReport = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Display_Nothing_Before_Query")); |
||||||
|
UIComponentUtils.setLineWrap(displayReport); |
||||||
|
useParamsTemplate = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Use_Params_Template")); |
||||||
|
background = new AccessibleBackgroundEditor(); |
||||||
|
|
||||||
|
double f = TableLayout.FILL; |
||||||
|
double p = TableLayout.PREFERRED; |
||||||
|
double[] rowSize = {p, p, p, p}; |
||||||
|
double[] columnSize = {p, f}; |
||||||
|
int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}}; |
||||||
|
Component[][] components = new Component[][]{ |
||||||
|
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Label_Name")), labelNameTextField}, |
||||||
|
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Base_Background")), background}, |
||||||
|
new Component[]{displayReport, null}, |
||||||
|
new Component[]{useParamsTemplate, null} |
||||||
|
}; |
||||||
|
JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W0, IntervalConstants.INTERVAL_L1); |
||||||
|
panel.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, IntervalConstants.INTERVAL_L1, 0)); |
||||||
|
|
||||||
|
jPanel.add(panel, BorderLayout.NORTH); |
||||||
|
|
||||||
|
return jPanel; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String title4PopupWindow() { |
||||||
|
return "parameter"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void populateBean(WParameterLayout ob) { |
||||||
|
labelNameTextField.setText(ob.getLabelName()); |
||||||
|
background.setValue(ob.getBackground()); |
||||||
|
displayReport.setSelected(ob.isDelayDisplayContent()); |
||||||
|
useParamsTemplate.setSelected(ob.isUseParamsTemplate()); |
||||||
|
if (newForm) { |
||||||
|
FormDesigner designer = TemplateTool.getCurrentEditingNewJForm().getFormDesign(); |
||||||
|
paraHeight.setValue(designer.getParaHeight()); |
||||||
|
} else { |
||||||
|
designerWidth.setValue(ob.getDesignWidth()); |
||||||
|
hAlignmentPane.setSelectedItem(ob.getPosition()); |
||||||
|
|
||||||
|
if (extraPropertyGroupPane != null) { |
||||||
|
extraPropertyGroupPane.populate(ob); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public WParameterLayout updateBean() { |
||||||
|
if (newForm) { |
||||||
|
return updateNewFormBean(); |
||||||
|
} else { |
||||||
|
return updateTemplateBean(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @Description: 更新非新决策报表的bean |
||||||
|
* @param |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/11/05 15:36 |
||||||
|
*/ |
||||||
|
private WParameterLayout updateTemplateBean() { |
||||||
|
WParameterLayout wParameterLayout = (WParameterLayout) creator.toData(); |
||||||
|
wParameterLayout.setLabelName(labelNameTextField.getText()); |
||||||
|
if (isCompsOutOfDesignerWidth((int) designerWidth.getValue())) { |
||||||
|
designerWidth.setValue(wParameterLayout.getDesignWidth()); |
||||||
|
} else { |
||||||
|
wParameterLayout.setDesignWidth((int) designerWidth.getValue()); |
||||||
|
} |
||||||
|
wParameterLayout.setDelayDisplayContent(displayReport.isSelected()); |
||||||
|
wParameterLayout.setUseParamsTemplate(useParamsTemplate.isSelected()); |
||||||
|
JTemplate jTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); |
||||||
|
jTemplate.needAddTemplateIdAttr(useParamsTemplate.isSelected()); |
||||||
|
wParameterLayout.setBackground((Background) background.getValue()); |
||||||
|
wParameterLayout.setPosition((Integer) hAlignmentPane.getSelectedItem()); |
||||||
|
return wParameterLayout; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @Description: 更新新决策报表的bean |
||||||
|
* @param |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/11/05 15:36 |
||||||
|
*/ |
||||||
|
private WParameterLayout updateNewFormBean() { |
||||||
|
WParameterLayout wParameterLayout = (WParameterLayout) creator.toData(); |
||||||
|
wParameterLayout.setLabelName(labelNameTextField.getText()); |
||||||
|
|
||||||
|
wParameterLayout.setDelayDisplayContent(displayReport.isSelected()); |
||||||
|
wParameterLayout.setUseParamsTemplate(useParamsTemplate.isSelected()); |
||||||
|
JTemplate jTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); |
||||||
|
jTemplate.needAddTemplateIdAttr(useParamsTemplate.isSelected()); |
||||||
|
wParameterLayout.setBackground((Background) background.getValue()); |
||||||
|
//设置参数模板面板的高度
|
||||||
|
int height = (int) paraHeight.getTextField().getValue(); |
||||||
|
FormDesigner designer = TemplateTool.getCurrentEditingNewJForm().getFormDesign(); |
||||||
|
FormSelection selection = designer.getSelectionModel().getSelection(); |
||||||
|
XCreator creator = designer.getParaComponent(); |
||||||
|
Rectangle rectangle = creator.getBounds(); |
||||||
|
Rectangle newRectangle = new Rectangle(rectangle.x, rectangle.y, rectangle.width, height); |
||||||
|
creator.setBounds(newRectangle); |
||||||
|
if (paraHeight.getValue() != newRectangle.height) |
||||||
|
paraHeight.setValue(newRectangle.height); |
||||||
|
designer.setParaHeight(newRectangle.height); |
||||||
|
designer.getArea().doLayout(); |
||||||
|
LayoutUtils.layoutContainer(creator); |
||||||
|
selection.fixCreator(designer); |
||||||
|
designer.repaint(); |
||||||
|
return wParameterLayout; |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isCompsOutOfDesignerWidth(int designerWidth) { |
||||||
|
for (int i = 0; i < root.getComponentCount(); i++) { |
||||||
|
Component comp = root.getComponent(i); |
||||||
|
if (comp.getX() + comp.getWidth() > designerWidth) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DataCreatorUI dataUI() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,225 @@ |
|||||||
|
package com.fr.design.fit.common; |
||||||
|
|
||||||
|
import com.fr.design.data.DesignTableDataManager; |
||||||
|
import com.fr.design.fit.DesignerUIModeConfig; |
||||||
|
import com.fr.design.fit.NewJForm; |
||||||
|
import com.fr.design.fit.attrpane.ElementEditorExtendDefinePane; |
||||||
|
import com.fr.design.fit.attrpane.FRAbsoluteBodyLayoutExtendDefinePane; |
||||||
|
import com.fr.design.fit.attrpane.FRAbsoluteLayoutExtendDefinePane; |
||||||
|
import com.fr.design.fit.attrpane.FRFitLayoutExtendDefinePane; |
||||||
|
import com.fr.design.fit.attrpane.RootDesignExtendDefinePane; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.design.mainframe.JForm; |
||||||
|
import com.fr.design.mainframe.JTemplate; |
||||||
|
import com.fr.design.mainframe.JTemplateFactory; |
||||||
|
import com.fr.design.parameter.RootDesignDefinePane; |
||||||
|
import com.fr.design.preview.FormAdaptivePreview; |
||||||
|
import com.fr.design.preview.FormPreview; |
||||||
|
import com.fr.design.widget.Appearance; |
||||||
|
import com.fr.design.widget.FormWidgetDefinePaneFactoryBase; |
||||||
|
import com.fr.design.widget.ui.designer.layout.ElementEditorDefinePane; |
||||||
|
import com.fr.design.widget.ui.designer.layout.FRAbsoluteBodyLayoutDefinePane; |
||||||
|
import com.fr.design.widget.ui.designer.layout.FRAbsoluteLayoutDefinePane; |
||||||
|
import com.fr.design.widget.ui.designer.layout.FRFitLayoutDefinePane; |
||||||
|
import com.fr.file.FILE; |
||||||
|
import com.fr.file.MemFILE; |
||||||
|
import com.fr.form.ui.ElementCaseEditor; |
||||||
|
import com.fr.form.ui.Widget; |
||||||
|
import com.fr.form.ui.container.WAbsoluteBodyLayout; |
||||||
|
import com.fr.form.ui.container.WAbsoluteLayout; |
||||||
|
import com.fr.form.ui.container.WFitLayout; |
||||||
|
import com.fr.form.ui.container.WParameterLayout; |
||||||
|
import com.fr.form.ui.widget.CRBoundsWidget; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.report.fit.ReportFitAttr; |
||||||
|
|
||||||
|
import javax.swing.SwingUtilities; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-06-02 |
||||||
|
*/ |
||||||
|
public class AdaptiveSwitchUtil { |
||||||
|
|
||||||
|
private static int switchJFromIng = 0; |
||||||
|
|
||||||
|
private AdaptiveSwitchUtil() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public static void switch2NewUI() { |
||||||
|
switch2NewUIMode(); |
||||||
|
reload(); |
||||||
|
} |
||||||
|
|
||||||
|
public static void switch2NewUIMode() { |
||||||
|
DesignerUIModeConfig.getInstance().setNewUIMode(); |
||||||
|
FormWidgetDefinePaneFactoryBase.registerDefinePane(ElementCaseEditor.class, |
||||||
|
new Appearance(ElementEditorExtendDefinePane.class, "elementCaseEditor")); |
||||||
|
FormWidgetDefinePaneFactoryBase.registerDefinePane(WFitLayout.class, |
||||||
|
new Appearance(FRFitLayoutExtendDefinePane.class, "wFitLayout")); |
||||||
|
FormWidgetDefinePaneFactoryBase.registerDefinePane(WAbsoluteBodyLayout.class, |
||||||
|
new Appearance(FRAbsoluteBodyLayoutExtendDefinePane.class, "wAbsoluteBodyLayout")); |
||||||
|
FormWidgetDefinePaneFactoryBase.registerDefinePane(WAbsoluteLayout.class, |
||||||
|
new Appearance(FRAbsoluteLayoutExtendDefinePane.class, "wAbsoluteLayout")); |
||||||
|
FormWidgetDefinePaneFactoryBase.registerDefinePane(WParameterLayout.class, |
||||||
|
new Appearance(RootDesignExtendDefinePane.class, "wParameterLayout")); |
||||||
|
} |
||||||
|
|
||||||
|
public static void switch2OldUI() { |
||||||
|
switch2OldUIMode(); |
||||||
|
reload(); |
||||||
|
} |
||||||
|
|
||||||
|
public static void switch2OldUIMode() { |
||||||
|
DesignerUIModeConfig.getInstance().setOldUIMode(); |
||||||
|
FormWidgetDefinePaneFactoryBase.registerDefinePane(WAbsoluteLayout.class, |
||||||
|
new Appearance(FRAbsoluteLayoutDefinePane.class, "wAbsoluteLayout")); |
||||||
|
FormWidgetDefinePaneFactoryBase.registerDefinePane(ElementCaseEditor.class, |
||||||
|
new Appearance(ElementEditorDefinePane.class, "elementCaseEditor")); |
||||||
|
FormWidgetDefinePaneFactoryBase.registerDefinePane(WAbsoluteBodyLayout.class, |
||||||
|
new Appearance(FRAbsoluteBodyLayoutDefinePane.class, "wAbsoluteBodyLayout")); |
||||||
|
FormWidgetDefinePaneFactoryBase.registerDefinePane(WFitLayout.class, |
||||||
|
new Appearance(FRFitLayoutDefinePane.class, "wFitLayout")); |
||||||
|
FormWidgetDefinePaneFactoryBase.registerDefinePane(WParameterLayout.class, |
||||||
|
new Appearance(RootDesignDefinePane.class, "wParameterLayout")); |
||||||
|
} |
||||||
|
|
||||||
|
public static void reload() { |
||||||
|
SwingUtilities.invokeLater(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
synchronized (AdaptiveSwitchUtil.class) { |
||||||
|
try { |
||||||
|
if (DesignerContext.getDesignerFrame() == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
JTemplate<?, ?> old = TemplateTool.getCurrentEditingTemplate(); |
||||||
|
if (old == null || !(old instanceof JForm)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
JTemplate<?, ?> template = createNewJTemplate(old); |
||||||
|
if (template != null) { |
||||||
|
DesignTableDataManager.closeTemplate(old); |
||||||
|
TemplateTool.resetTabPaneEditingTemplate(template); |
||||||
|
TemplateTool.activeAndResizeTemplate(template); |
||||||
|
setPreviewType(); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage()); |
||||||
|
} finally { |
||||||
|
switchJFromIng = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @Description: 设置预览方式 |
||||||
|
* @return: 新创建的模板 |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/10/13 14:08 |
||||||
|
*/ |
||||||
|
private static void setPreviewType() { |
||||||
|
JTemplate jTemplate = TemplateTool.getCurrentEditingTemplate(); |
||||||
|
if (jTemplate != null) { |
||||||
|
if (DesignerUIModeConfig.getInstance().newUIMode()) { |
||||||
|
jTemplate.setPreviewType(new FormAdaptivePreview()); |
||||||
|
} else { |
||||||
|
jTemplate.setPreviewType(new FormPreview()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @Description: 创建模板 |
||||||
|
* @param old 以前的模板 |
||||||
|
* @return: 新创建的模板 |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/6 14:08 |
||||||
|
*/ |
||||||
|
public static JTemplate<?, ?> createNewJTemplate(JTemplate<?, ?> old) { |
||||||
|
JTemplate<?, ?> template; |
||||||
|
template = createNewJTemplateInternal(old); |
||||||
|
if (template instanceof NewJForm) { |
||||||
|
NewJForm jForm = ((NewJForm) template); |
||||||
|
//如果是从旧的设计模板转化为新的设计模式,并且不是全局配置的模板。则更新新模板的Pc端自适应属性
|
||||||
|
if (DesignerUIModeConfig.getInstance().newUIMode() && jForm.getTarget().getReportFitAttr() != null && isSwitchJFromIng()) { |
||||||
|
jForm.getTarget().setReportFitAttr(shiftReportFitAttr(old, jForm.getTarget().getReportFitAttr().isFitFont())); |
||||||
|
} |
||||||
|
TemplateTool.saveForm(jForm); |
||||||
|
} |
||||||
|
return template; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @Description: 创建模板核心方法 |
||||||
|
* @param old 以前的方法 |
||||||
|
* @return: 新创建的模板 |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/6 14:09 |
||||||
|
*/ |
||||||
|
private static JTemplate<?, ?> createNewJTemplateInternal(JTemplate<?, ?> old) { |
||||||
|
FILE file = old.getEditingFILE(); |
||||||
|
if ((file instanceof MemFILE) || !old.isSaved()) { |
||||||
|
if (old instanceof NewJForm) { |
||||||
|
TemplateTool.resetAbsoluteBodySize((NewJForm) old); |
||||||
|
} |
||||||
|
TemplateTool.saveForm(old); |
||||||
|
} |
||||||
|
return JTemplateFactory.createJTemplate(old.getEditingFILE()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @Description: 老模板切换到新模板的属性配置转换( |
||||||
|
* 1、绝对布局-适应区域--》双向自适应 |
||||||
|
* 2、自适应布局-双向自适应--》双向自适应 |
||||||
|
* 3、自适应布局-横向自适应--》横向自适应 |
||||||
|
* 4、绝对布局-固定大小--》不自适应 |
||||||
|
* ) |
||||||
|
* @param old |
||||||
|
* @param fitFont 字体是否自适应 |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/6 14:01 |
||||||
|
*/ |
||||||
|
private static ReportFitAttr shiftReportFitAttr(JTemplate old, boolean fitFont) { |
||||||
|
if (old instanceof JForm && DesignerUIModeConfig.getInstance().newUIMode()) { |
||||||
|
JForm jForm = (JForm) old; |
||||||
|
try { |
||||||
|
int layoutType = LayoutTool.getFormLayoutType(jForm); |
||||||
|
int compState = -1; |
||||||
|
//自适应布局
|
||||||
|
if (layoutType == 0) { |
||||||
|
compState = ((WFitLayout) jForm.getFormDesign().getRootComponent().toData()).getCompState(); |
||||||
|
if (compState == WFitLayout.STATE_FULL) { |
||||||
|
return new ReportFitAttr(2, fitFont); |
||||||
|
} else if (compState == WFitLayout.STATE_ORIGIN) { |
||||||
|
return new ReportFitAttr(1, fitFont); |
||||||
|
} |
||||||
|
} else if (layoutType == 1) {//绝对布局
|
||||||
|
Widget widget = ((CRBoundsWidget) jForm.getFormDesign().getRootComponent().toData().getWidget(0)).getWidget(); |
||||||
|
if (widget instanceof WAbsoluteLayout) { |
||||||
|
compState = ((WAbsoluteLayout) widget).getCompState(); |
||||||
|
} |
||||||
|
if (compState == WAbsoluteLayout.STATE_FIT) { |
||||||
|
return new ReportFitAttr(2, fitFont); |
||||||
|
} else if (compState == WAbsoluteLayout.STATE_FIXED) { |
||||||
|
return new ReportFitAttr(3, fitFont); |
||||||
|
} |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public static void setSwitchJFromIng(int switchJFromIng) { |
||||||
|
AdaptiveSwitchUtil.switchJFromIng = switchJFromIng; |
||||||
|
} |
||||||
|
|
||||||
|
public static boolean isSwitchJFromIng() { |
||||||
|
return switchJFromIng == 1; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
package com.fr.design.fit.common; |
||||||
|
|
||||||
|
import com.fr.design.designer.creator.XCreator; |
||||||
|
import com.fr.design.designer.creator.XElementCase; |
||||||
|
import com.fr.design.designer.creator.XLayoutContainer; |
||||||
|
import com.fr.form.FormElementCaseProvider; |
||||||
|
import com.fr.form.ui.ElementCaseEditor; |
||||||
|
|
||||||
|
import java.util.Iterator; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-06-12 |
||||||
|
*/ |
||||||
|
public class FormDesignerUtil { |
||||||
|
private FormDesignerUtil(){ |
||||||
|
|
||||||
|
} |
||||||
|
public static XElementCase getXelementCase(XLayoutContainer rootContainer, FormElementCaseProvider elementCaseProvider) { |
||||||
|
for (int i = 0; i < rootContainer.getComponentCount(); i++) { |
||||||
|
XCreator creator = rootContainer.getXCreator(i); |
||||||
|
if (creator instanceof XElementCase && elementCaseProvider == ((ElementCaseEditor) creator.toData()).getElementCase()) { |
||||||
|
return (XElementCase) creator; |
||||||
|
} |
||||||
|
if (creator instanceof XLayoutContainer) { |
||||||
|
XElementCase temp = getXelementCase((XLayoutContainer) creator, elementCaseProvider); |
||||||
|
if (temp != null) { |
||||||
|
return temp; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static void removeDeletedEC(List currentECList, List waitToProcessECList) { |
||||||
|
Iterator iterator = waitToProcessECList.iterator(); |
||||||
|
while (iterator.hasNext()) { |
||||||
|
Object editor = iterator.next(); |
||||||
|
if (!currentECList.contains(editor)) { |
||||||
|
iterator.remove(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,177 @@ |
|||||||
|
package com.fr.design.fit.common; |
||||||
|
|
||||||
|
import com.fr.design.designer.creator.XCreator; |
||||||
|
import com.fr.design.designer.creator.XLayoutContainer; |
||||||
|
import com.fr.design.designer.creator.XWAbsoluteBodyLayout; |
||||||
|
import com.fr.design.designer.creator.XWAbsoluteLayout; |
||||||
|
import com.fr.design.designer.creator.cardlayout.XWCardLayout; |
||||||
|
import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout; |
||||||
|
import com.fr.design.fit.NewJForm; |
||||||
|
import com.fr.design.mainframe.FormArea; |
||||||
|
import com.fr.design.mainframe.JForm; |
||||||
|
import com.fr.design.utils.gui.LayoutUtils; |
||||||
|
import com.fr.form.ui.container.WAbsoluteBodyLayout; |
||||||
|
import com.fr.form.ui.container.WFitLayout; |
||||||
|
import com.fr.form.ui.container.WLayout; |
||||||
|
import com.fr.form.ui.widget.CRBoundsWidget; |
||||||
|
import com.fr.general.FRScreen; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
|
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.Rectangle; |
||||||
|
import java.awt.Toolkit; |
||||||
|
|
||||||
|
/** |
||||||
|
* @description:布局工具类 |
||||||
|
* @author: Henry.Wang |
||||||
|
* @create: 2020/09/03 14:18 |
||||||
|
*/ |
||||||
|
public class LayoutTool { |
||||||
|
/** |
||||||
|
* @Description: 获取布局类型 |
||||||
|
* @param jForm |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/6 14:31 |
||||||
|
*/ |
||||||
|
public static int getFormLayoutType(JForm jForm) { |
||||||
|
JForm tempJForm = jForm; |
||||||
|
if (tempJForm == null) |
||||||
|
tempJForm = TemplateTool.getCurrentEditingNewJForm(); |
||||||
|
if (tempJForm == null || tempJForm.getFormDesign().getRootComponent() == null) |
||||||
|
return -1; |
||||||
|
return ((WFitLayout) tempJForm.getFormDesign().getRootComponent().toData()).getBodyLayoutType().getTypeValue(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @Description: 是否为绝对布局 |
||||||
|
* @param jForm |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/6 14:31 |
||||||
|
*/ |
||||||
|
public static boolean absoluteLayoutForm(NewJForm jForm) { |
||||||
|
if (getFormLayoutType(jForm) == 1) |
||||||
|
return true; |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @Description: 如果为绝对布局则获取XWAbsoluteBodyLayout,否则返回null |
||||||
|
* @param jForm |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/6 14:26 |
||||||
|
*/ |
||||||
|
public static XWAbsoluteBodyLayout getXWAbsoluteBodyLayout(NewJForm jForm) { |
||||||
|
NewJForm tempJForm = jForm; |
||||||
|
if (tempJForm == null) |
||||||
|
tempJForm = TemplateTool.getCurrentEditingNewJForm(); |
||||||
|
if (tempJForm != null) { |
||||||
|
if (absoluteLayoutForm(tempJForm)) { |
||||||
|
XLayoutContainer xLayoutContainer = tempJForm.getFormDesign().getRootComponent(); |
||||||
|
if (xLayoutContainer != null && xLayoutContainer.getComponentCount() > 0) { |
||||||
|
Component component = xLayoutContainer.getComponent(0); |
||||||
|
if (component instanceof XWAbsoluteBodyLayout) { |
||||||
|
return (XWAbsoluteBodyLayout) component; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @Description: 通过子组件的位置获取绝对布局body的尺寸。为什么不直接调用getRootComponent().toData().getContentHeight()呢?因为在截断的情况下就不不一致了 |
||||||
|
* @param newJForm |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/11 15:24 |
||||||
|
*/ |
||||||
|
public static Rectangle getAbsoluteBodySize(NewJForm newJForm) { |
||||||
|
int width = 0; |
||||||
|
int height = 0; |
||||||
|
XWAbsoluteBodyLayout xwAbsoluteBodyLayout = LayoutTool.getXWAbsoluteBodyLayout(newJForm); |
||||||
|
if (xwAbsoluteBodyLayout != null) { |
||||||
|
WAbsoluteBodyLayout wAbsoluteBodyLayout = xwAbsoluteBodyLayout.toData(); |
||||||
|
if (wAbsoluteBodyLayout.getWidgetCount() > 0) { |
||||||
|
for (int i = 0; i < wAbsoluteBodyLayout.getWidgetCount(); i++) { |
||||||
|
Rectangle rectangle = ((CRBoundsWidget) wAbsoluteBodyLayout.getWidget(i)).getBounds(); |
||||||
|
if (rectangle.x + rectangle.width > width) |
||||||
|
width = rectangle.x + rectangle.width; |
||||||
|
if (rectangle.y + rectangle.height > height) |
||||||
|
height = rectangle.y + rectangle.height; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return new Rectangle(0, 0, width, height); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static int getBodyHeight(NewJForm newJForm) { |
||||||
|
return newJForm.getFormDesign().getRootComponent().toData().getContentHeight(); |
||||||
|
} |
||||||
|
|
||||||
|
public static int getBodyWidth(NewJForm newJForm) { |
||||||
|
return newJForm.getFormDesign().getRootComponent().toData().getContentWidth(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @Description: 对绝对画布块里的组件进行缩放 |
||||||
|
* @param xCreator |
||||||
|
* @param scale 缩放比例 |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/10/26 20:39 |
||||||
|
*/ |
||||||
|
public static void scaleAbsoluteBlockComponentsBounds(XCreator xCreator, Double scale) { |
||||||
|
try { |
||||||
|
Component[] components = xCreator.getComponents(); |
||||||
|
for (Component component : components) { |
||||||
|
if (component instanceof XWCardMainBorderLayout) { |
||||||
|
XWCardLayout xwCardLayout = ((XWCardMainBorderLayout)component).getCardPart(); |
||||||
|
for (Component tabComponent : xwCardLayout.getComponents()) { |
||||||
|
scaleAbsoluteBlockComponentsBounds((XCreator) tabComponent, scale); |
||||||
|
scaleAbsoluteBlockComponentsBoundsInternal((XCreator) tabComponent, scale); |
||||||
|
} |
||||||
|
} else if (component instanceof XWAbsoluteLayout) { |
||||||
|
scaleAbsoluteBlockComponentsBounds((XCreator) component, scale); |
||||||
|
scaleAbsoluteBlockComponentsBoundsInternal((XCreator) component, scale); |
||||||
|
} |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage()); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public static void scaleAbsoluteBlockComponentsBoundsInternal(XCreator parentXCreator, Double scale) { |
||||||
|
if (parentXCreator instanceof XWAbsoluteLayout) { |
||||||
|
XWAbsoluteLayout xwAbsoluteLayout = (XWAbsoluteLayout) parentXCreator; |
||||||
|
Component[] absoluteComponents = xwAbsoluteLayout.getComponents(); |
||||||
|
for (Component absoluteComponent : absoluteComponents) { |
||||||
|
XCreator xCreator = (XCreator) absoluteComponent; |
||||||
|
Rectangle bounds = new Rectangle(absoluteComponent.getBounds()); |
||||||
|
Rectangle newBounds = new Rectangle((int) (bounds.x * scale), (int) (bounds.y * scale), (int) (bounds.width * scale), (int) (bounds.height * scale)); |
||||||
|
WLayout wAbsoluteLayout = xwAbsoluteLayout.toData(); |
||||||
|
wAbsoluteLayout.setBounds(xCreator.toData(), newBounds); |
||||||
|
xCreator.setBounds(newBounds); |
||||||
|
LayoutUtils.layoutContainer(xCreator); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @Description: 获取老预览时的缩放比例 |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/10/26 20:39 |
||||||
|
*/ |
||||||
|
public static double getContainerPercent(){ |
||||||
|
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); |
||||||
|
double screenValue = FRScreen.getFRScreenByDimension(screen).getValue(); |
||||||
|
return screenValue / FormArea.DEFAULT_SLIDER; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,835 @@ |
|||||||
|
/* |
||||||
|
* Copyright(c) 2001-2010, FineReport Inc, All Rights Reserved. |
||||||
|
*/ |
||||||
|
package com.fr.design.fit.common; |
||||||
|
|
||||||
|
import com.fr.base.AutoChangeLineAndDrawManager; |
||||||
|
import com.fr.base.BaseFormula; |
||||||
|
import com.fr.base.BaseUtils; |
||||||
|
import com.fr.base.GraphHelper; |
||||||
|
import com.fr.base.ImageProvider; |
||||||
|
import com.fr.base.Painter; |
||||||
|
import com.fr.base.Style; |
||||||
|
import com.fr.base.Utils; |
||||||
|
import com.fr.base.background.ColorBackground; |
||||||
|
import com.fr.base.chart.BaseChartCollection; |
||||||
|
import com.fr.base.chart.result.WebChartIDInfo; |
||||||
|
import com.fr.code.BarcodeImpl; |
||||||
|
import com.fr.code.bar.BarcodeException; |
||||||
|
import com.fr.code.bar.core.BarCodeUtils; |
||||||
|
import com.fr.code.bar.core.BarcodeAttr; |
||||||
|
import com.fr.data.DataUtils; |
||||||
|
import com.fr.data.PresentationType; |
||||||
|
import com.fr.data.condition.ListCondition; |
||||||
|
import com.fr.file.ResultChangeWhenExport; |
||||||
|
import com.fr.form.ui.Widget; |
||||||
|
import com.fr.general.Background; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.general.FRFont; |
||||||
|
import com.fr.general.ImageWithSuffix; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.plugin.ExtraClassManager; |
||||||
|
import com.fr.report.cell.CellElement; |
||||||
|
import com.fr.report.cell.FloatElement; |
||||||
|
import com.fr.report.cell.TemplateCellElement; |
||||||
|
import com.fr.report.cell.cellattr.CellExpandAttr; |
||||||
|
import com.fr.report.cell.cellattr.CellGUIAttr; |
||||||
|
import com.fr.report.cell.cellattr.core.CellUtils; |
||||||
|
import com.fr.report.cell.cellattr.core.ResultSubReport; |
||||||
|
import com.fr.report.cell.cellattr.core.group.DSColumn; |
||||||
|
import com.fr.report.core.Html2ImageUtils; |
||||||
|
import com.fr.report.core.ReportUtils; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import com.fr.stable.Constants; |
||||||
|
import com.fr.stable.CoreConstants; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.stable.bridge.ObjectHolder; |
||||||
|
import com.fr.stable.fun.AutoChangeLineAndDrawProcess; |
||||||
|
import com.fr.stable.fun.FontProcessor; |
||||||
|
import com.fr.stable.html.Tag; |
||||||
|
import com.fr.stable.unit.FU; |
||||||
|
import com.fr.stable.unit.PT; |
||||||
|
import com.fr.stable.unit.UNIT; |
||||||
|
import com.fr.stable.web.Repository; |
||||||
|
|
||||||
|
import javax.swing.ImageIcon; |
||||||
|
import java.awt.AlphaComposite; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Font; |
||||||
|
import java.awt.FontMetrics; |
||||||
|
import java.awt.Graphics2D; |
||||||
|
import java.awt.Image; |
||||||
|
import java.awt.Paint; |
||||||
|
import java.awt.Rectangle; |
||||||
|
import java.awt.font.TextAttribute; |
||||||
|
import java.awt.geom.GeneralPath; |
||||||
|
import java.awt.image.BufferedImage; |
||||||
|
import java.util.Hashtable; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* The util for paint. |
||||||
|
*/ |
||||||
|
public class PaintUtils { |
||||||
|
// Add by Denny
|
||||||
|
public static final int CELL_MARK_SIZE = 6; |
||||||
|
public static final Color CELL_HIGHT_LIGHT_MARK_COLOR = new Color(255, 0, 55); |
||||||
|
public static final Color CELL_PRESENT_MARK_COLOR = new Color(0, 255, 200); |
||||||
|
public static final Color CELL_PAGINATION_MARK_COLOR = new Color(55, 255, 0); |
||||||
|
public static final Color CELL_RESULT_MARK_COLOR = new Color(200, 0, 255); |
||||||
|
public static final Color CELL_CONDITION_FILTER_MARK_COLOR = new Color(255, 200, 0); |
||||||
|
public static final Color CELL_PARAMETER_FILTER_MARK_CONLR = new Color(0, 55, 255); |
||||||
|
|
||||||
|
public static final Color CELL_DIRECTION_MARK_COLOR = Color.gray; |
||||||
|
private static final int UNIT_SIZE = 4; |
||||||
|
|
||||||
|
//原值是15,矩形线条会缺失,加1px绘制没问题。这地方有水印,但是貌似不是水印影响,未找到线条被挡住的原因
|
||||||
|
private static final int WIDGET_WIDTH = 16; |
||||||
|
private static final int WIDGET_HEIGHT = 16; |
||||||
|
|
||||||
|
// Suppresses default constructor, ensuring non-instantiability.
|
||||||
|
private PaintUtils() { |
||||||
|
} |
||||||
|
|
||||||
|
// font attributes map cache
|
||||||
|
private static Hashtable fontAttributeMapCache = new Hashtable(); |
||||||
|
|
||||||
|
/* |
||||||
|
* 用于在Grid里面画CellElement的Content + Background |
||||||
|
* |
||||||
|
* 不画Border,是因为在Grid里面先画所有单元格的Content + Background,再画所有单元格的Border(peter认为这可以提高速度) |
||||||
|
*/ |
||||||
|
public static void paintGridCellContent(Graphics2D g2d, TemplateCellElement cell, int width, int height, int resolution) { |
||||||
|
int cell_mark_size = CELL_MARK_SIZE; |
||||||
|
// denny_Grid
|
||||||
|
// 左上角: 条件高亮, 形态
|
||||||
|
int leftUpCount = 0; |
||||||
|
int rightUpCount = 0; |
||||||
|
int leftDownCount = 0; |
||||||
|
GraphHelper.applyRenderingHints(g2d); |
||||||
|
if (paintHighlightGroupMarkWhenExsit(g2d, cell, leftUpCount)) { |
||||||
|
leftUpCount++; |
||||||
|
} |
||||||
|
if (paintPresentMarkWhenExsit(g2d, cell, leftUpCount)) { |
||||||
|
leftUpCount++; |
||||||
|
} |
||||||
|
if (paintPaginationMarkWhenExsit(g2d, cell, width, rightUpCount)) { |
||||||
|
rightUpCount++; |
||||||
|
} |
||||||
|
paintWidgetMarkWhenExsit(g2d, cell, width, height); |
||||||
|
paintExpandMarkWhenExsit(g2d, cell); |
||||||
|
Object value = cell.getValue(); |
||||||
|
if (value == null) {// 先判断是否是空.
|
||||||
|
return; |
||||||
|
} |
||||||
|
if (paintResultMarkWhenExsit(g2d, value, width, rightUpCount)) { |
||||||
|
rightUpCount++; |
||||||
|
} |
||||||
|
|
||||||
|
if (paintDSColumnParametermarkWhenExsit(g2d, value, height, leftDownCount)) { |
||||||
|
leftDownCount++; |
||||||
|
} |
||||||
|
|
||||||
|
if (paintDSColumnConditionmarkWhenExsit(g2d, value, height, leftDownCount)) { |
||||||
|
leftDownCount++; |
||||||
|
} |
||||||
|
// 画value,但因为是在Grid里面画,所以画Formula.content
|
||||||
|
if (value instanceof BaseFormula) { |
||||||
|
value = ((BaseFormula) value).getContent(); |
||||||
|
} |
||||||
|
if (value instanceof ImageWithSuffix) { |
||||||
|
value = ((ImageWithSuffix) value).getFineImage(); |
||||||
|
} |
||||||
|
if (value instanceof BaseChartCollection) { |
||||||
|
value = ((BaseChartCollection) value).createResultChartPainterWithOutDealFormula(Calculator.createCalculator(), WebChartIDInfo.createEmptyDesignerInfo(), width, height); |
||||||
|
} |
||||||
|
// Carl:当是子报表时,在格子里画一个子报表的图
|
||||||
|
/* |
||||||
|
* alex:TODO 此处在Grid里面画ChartCollection和SubReport都只画一个图表,这种做法,很不雅 |
||||||
|
*/ |
||||||
|
if (value instanceof ResultSubReport) { |
||||||
|
value = BaseUtils.readImage("/com/fr/base/images/report/painter/subReport.png"); |
||||||
|
GraphHelper.paintImage(g2d, width, height, (Image) value, Constants.IMAGE_CENTER, |
||||||
|
BaseUtils.getAlignment4Horizontal(cell.getStyle(), value), cell.getStyle().getVerticalAlignment(), |
||||||
|
width > 16 ? 16 : width, height > 16 ? 16 : height); |
||||||
|
} else { |
||||||
|
renderContent(g2d, value, cell.getStyle(), width, height, resolution); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private static void renderContent(Graphics2D g2d, Object value, Style style, int width, int height, int resolution) { |
||||||
|
if (value != null && width != 0 && height != 0) { |
||||||
|
if (style == null) { |
||||||
|
style = Style.DEFAULT_STYLE.deriveImageLayout(1); |
||||||
|
} |
||||||
|
|
||||||
|
if (value instanceof BaseFormula) { |
||||||
|
value = ((BaseFormula) value).getResult(); |
||||||
|
} |
||||||
|
|
||||||
|
if (value instanceof Painter) { |
||||||
|
((Painter)value).paint(g2d, width, height, resolution, style); |
||||||
|
} else if (value instanceof ImageProvider) { |
||||||
|
Style.paintImageContent(g2d, ((ImageProvider) value).getImage(), style, width, height, resolution); |
||||||
|
} else if (value instanceof Image) { |
||||||
|
Style.paintImageContent(g2d, (Image) value, style, width, height, resolution); |
||||||
|
} else { |
||||||
|
String var6 = Style.valueToText(value, style.getFormat()); |
||||||
|
NewFormStyle.paintCellStyleString2(g2d, width, height, var6, style, resolution); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private static boolean paintHighlightGroupMarkWhenExsit(Graphics2D g2d, TemplateCellElement cell, int left_up_count) { |
||||||
|
if (cell.getHighlightGroup() != null && cell.getHighlightGroup().size() > 0) { |
||||||
|
Paint oldPaint = g2d.getPaint(); |
||||||
|
|
||||||
|
g2d.setPaint(CELL_HIGHT_LIGHT_MARK_COLOR); |
||||||
|
GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 3); |
||||||
|
polyline.moveTo(0, 0); |
||||||
|
polyline.lineTo(0, CELL_MARK_SIZE); |
||||||
|
polyline.lineTo(CELL_MARK_SIZE, 0); |
||||||
|
GraphHelper.fill(g2d, polyline); |
||||||
|
|
||||||
|
g2d.setPaint(oldPaint); |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean paintPresentMarkWhenExsit(Graphics2D g2d, TemplateCellElement cell, int left_up_count) { |
||||||
|
if (cell.getPresent() != null) { |
||||||
|
Paint oldPaint = g2d.getPaint(); |
||||||
|
|
||||||
|
g2d.setPaint(CELL_PRESENT_MARK_COLOR); |
||||||
|
GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 3); |
||||||
|
polyline.moveTo(0 + left_up_count * CELL_MARK_SIZE, 0); |
||||||
|
polyline.lineTo(0 + left_up_count * CELL_MARK_SIZE, 6); |
||||||
|
polyline.lineTo(CELL_MARK_SIZE + left_up_count * CELL_MARK_SIZE, 0); |
||||||
|
GraphHelper.fill(g2d, polyline); |
||||||
|
|
||||||
|
g2d.setPaint(oldPaint); |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean paintPaginationMarkWhenExsit(Graphics2D g2d, TemplateCellElement cell, int width, int ringt_up_count) { |
||||||
|
// 右上角: 标记是否有分页
|
||||||
|
if (isRightTopMarker(cell)) { |
||||||
|
Paint oldPaint = g2d.getPaint(); |
||||||
|
|
||||||
|
g2d.setPaint(CELL_PAGINATION_MARK_COLOR); |
||||||
|
GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 3); |
||||||
|
polyline.moveTo(width - 1 - ringt_up_count * CELL_MARK_SIZE, 0); |
||||||
|
polyline.lineTo(width - 1 - ringt_up_count * CELL_MARK_SIZE, CELL_MARK_SIZE); |
||||||
|
polyline.lineTo(width - 1 - (ringt_up_count + 1) * CELL_MARK_SIZE, 0); |
||||||
|
GraphHelper.fill(g2d, polyline); |
||||||
|
|
||||||
|
g2d.setPaint(oldPaint); |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean isRightTopMarker(TemplateCellElement cell) { |
||||||
|
return cell.getCellPageAttr() != null && (cell.getCellPageAttr().isPageAfterColumn() |
||||||
|
|| cell.getCellPageAttr().isPageBeforeColumn() |
||||||
|
|| cell.getCellPageAttr().isPageAfterRow() |
||||||
|
|| cell.getCellPageAttr().isPageBeforeRow()); |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean paintResultMarkWhenExsit(Graphics2D g2d, Object value, int width, int ringt_up_count) { |
||||||
|
//右上角标记是否自定义显示
|
||||||
|
if (value instanceof DSColumn && ((DSColumn) value).getResult() != null) { |
||||||
|
if (!ComparatorUtils.equals(((DSColumn) value).getResult(), "$$$")) { |
||||||
|
Paint oldPaint = g2d.getPaint(); |
||||||
|
|
||||||
|
g2d.setPaint(CELL_RESULT_MARK_COLOR); |
||||||
|
GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 3); |
||||||
|
polyline.moveTo(width - ringt_up_count * CELL_MARK_SIZE - 1, 0); |
||||||
|
polyline.lineTo(width - ringt_up_count * CELL_MARK_SIZE - 1, CELL_MARK_SIZE); |
||||||
|
polyline.lineTo(width - (ringt_up_count + 1) * CELL_MARK_SIZE - 1, 0); |
||||||
|
GraphHelper.fill(g2d, polyline); |
||||||
|
|
||||||
|
g2d.setPaint(oldPaint); |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
private static void paintWidgetMarkWhenExsit(Graphics2D g2d, TemplateCellElement cell, int width, int height) { |
||||||
|
// 右下角:是否填报, 设置为4时,三角太小了,不知何故,设置为6
|
||||||
|
if (cell.getWidget() != null) { |
||||||
|
Widget widget = cell.getWidget(); |
||||||
|
Image img = ((ImageIcon) ReportUtils.createWidgetIcon(widget.getClass())).getImage(); |
||||||
|
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.67f)); |
||||||
|
g2d.drawImage(img, width - 15, height - 15, WIDGET_WIDTH, WIDGET_HEIGHT, null); |
||||||
|
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static void paintExpandMarkWhenExsit(Graphics2D g2d, TemplateCellElement cell) { |
||||||
|
CellExpandAttr cellExpandAttr = cell.getCellExpandAttr(); |
||||||
|
if (cellExpandAttr != null) { |
||||||
|
if (cellExpandAttr.getDirection() == Constants.TOP_TO_BOTTOM) { |
||||||
|
Paint oldPaint = g2d.getPaint(); |
||||||
|
g2d.setPaint(CELL_DIRECTION_MARK_COLOR); |
||||||
|
GraphHelper.drawLine(g2d, 2, 0, 2, 5); |
||||||
|
GraphHelper.drawLine(g2d, 2, 5, 0, 2); |
||||||
|
GraphHelper.drawLine(g2d, 2, 5, 4, 2); |
||||||
|
g2d.setPaint(oldPaint); |
||||||
|
} else if (cellExpandAttr.getDirection() == Constants.LEFT_TO_RIGHT) { |
||||||
|
Paint oldPaint = g2d.getPaint(); |
||||||
|
g2d.setPaint(CELL_DIRECTION_MARK_COLOR); |
||||||
|
GraphHelper.drawLine(g2d, 0, 2, 5, 2); |
||||||
|
GraphHelper.drawLine(g2d, 5, 2, 2, 0); |
||||||
|
GraphHelper.drawLine(g2d, 5, 2, 2, 4); |
||||||
|
g2d.setPaint(oldPaint); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean paintDSColumnConditionmarkWhenExsit(Graphics2D g2d, Object value, int height, int left_dowm_count) { |
||||||
|
// 左下角:数据列(DSColumn)相关:比如条件过滤
|
||||||
|
if (value instanceof DSColumn && ((DSColumn) value).getCondition() != null) { |
||||||
|
if (((DSColumn) value).getCondition() instanceof ListCondition && |
||||||
|
((ListCondition) ((DSColumn) value).getCondition()).getJoinConditionCount() == 0) { |
||||||
|
// do nothing
|
||||||
|
} else { |
||||||
|
Paint oldPaint = g2d.getPaint(); |
||||||
|
|
||||||
|
g2d.setPaint(CELL_CONDITION_FILTER_MARK_COLOR); |
||||||
|
GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 3); |
||||||
|
polyline.moveTo(0 + left_dowm_count * CELL_MARK_SIZE, height - 1); |
||||||
|
polyline.lineTo((left_dowm_count + 1) * CELL_MARK_SIZE + 1, height - 1); |
||||||
|
polyline.lineTo(0 + left_dowm_count * CELL_MARK_SIZE, height - 2 - CELL_MARK_SIZE); |
||||||
|
GraphHelper.fill(g2d, polyline); |
||||||
|
|
||||||
|
g2d.setPaint(oldPaint); |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean paintDSColumnParametermarkWhenExsit(Graphics2D g2d, Object value, int height, int left_dowm_count) { |
||||||
|
// 左下角:动态注入参数
|
||||||
|
if (value instanceof DSColumn && ((DSColumn) value).getParameters() != null) { |
||||||
|
if (((DSColumn) value).getParameters().length > 0) { |
||||||
|
Paint oldPaint = g2d.getPaint(); |
||||||
|
|
||||||
|
g2d.setPaint(CELL_PARAMETER_FILTER_MARK_CONLR); |
||||||
|
GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 3); |
||||||
|
polyline.moveTo(0 + left_dowm_count * CELL_MARK_SIZE, height - 1); |
||||||
|
polyline.lineTo((left_dowm_count + 1) * CELL_MARK_SIZE + 1, height - 1); |
||||||
|
polyline.lineTo(0 + left_dowm_count * CELL_MARK_SIZE, height - 2 - CELL_MARK_SIZE); |
||||||
|
GraphHelper.fill(g2d, polyline); |
||||||
|
|
||||||
|
g2d.setPaint(oldPaint); |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* 画悬浮元素 |
||||||
|
* |
||||||
|
* 仅根据宽度 + 高度画 |
||||||
|
*/ |
||||||
|
//b:此方法在grid和tohtml的时候都被调用,所以对formula会有冲突,暂时这么改,应该考虑分开的,也可以根据result来判断,但是那么写好像不妥
|
||||||
|
public static void paintFloatElement(Graphics2D g2d, FloatElement flotEl, int width, int height, int resolution) { |
||||||
|
Style.paintBackground(g2d, flotEl.getStyle(), width, height); |
||||||
|
|
||||||
|
Object value = flotEl.getValue(); |
||||||
|
if (value instanceof BaseFormula) { |
||||||
|
value = ((BaseFormula) value).getContent(); |
||||||
|
} |
||||||
|
if (value instanceof BaseChartCollection) { |
||||||
|
value = ((BaseChartCollection) value).createResultChartPainterWithOutDealFormula(Calculator.createCalculator(), WebChartIDInfo.createEmptyDesignerInfo(), width, height); |
||||||
|
} |
||||||
|
//图片需要切割一下
|
||||||
|
if (value instanceof Image) { |
||||||
|
value = CellUtils.value2ImageWithBackground(value, resolution, flotEl.getStyle(), width, height); |
||||||
|
} |
||||||
|
Style.paintContent(g2d, value, flotEl.getStyle(), width, height, resolution); |
||||||
|
|
||||||
|
Style.paintBorder(g2d, flotEl.getStyle(), width, height); |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* 画悬浮元素flotEl |
||||||
|
* |
||||||
|
* 也就是画三个东西:背景 + 内容 + 边框 |
||||||
|
*/ |
||||||
|
public static void paintFloatElement(Graphics2D g2d, FloatElement flotEl, Rectangle paintRectangle, Rectangle clipRectangle, int resolution) { |
||||||
|
// 画悬浮元素的背景
|
||||||
|
Style.paintBackground(g2d, flotEl.getStyle(), paintRectangle, clipRectangle); |
||||||
|
|
||||||
|
Object value = flotEl.getValue(); |
||||||
|
if (value instanceof ResultChangeWhenExport) { |
||||||
|
value = ((ResultChangeWhenExport) value).changeThis(); |
||||||
|
} |
||||||
|
// 画悬浮元素的内容
|
||||||
|
Style.paintContent(g2d, value, resolution, flotEl.getStyle(), paintRectangle, clipRectangle); |
||||||
|
// 画悬浮元素的边框
|
||||||
|
Style.paintBorder(g2d, flotEl.getStyle(), paintRectangle, clipRectangle); |
||||||
|
} |
||||||
|
|
||||||
|
public static void paintHTMLContent(Graphics2D g2d, String value, int resolution, Style style, Rectangle paintRectangle, Rectangle clipRectangle) { |
||||||
|
Style.paintContent(g2d, createHTMLContentBufferedImage(value, paintRectangle, 0, 0, style), resolution, style, paintRectangle, clipRectangle); |
||||||
|
} |
||||||
|
|
||||||
|
public static void paintTag(Painter painter, Repository repo, int width, int height, Style style, Tag tag) { |
||||||
|
painter.paintTag(repo, width, height, style, tag); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 如果用户希望以HTML方式展示String,这个时候先value变成图片 |
||||||
|
* |
||||||
|
* @param value 值 |
||||||
|
* @param paintRectangle 绘制范围 |
||||||
|
* @param x x坐标 |
||||||
|
* @param y y坐标 |
||||||
|
* @param style 当前格子样式 |
||||||
|
* @return BufferedImage 返回图片. |
||||||
|
*/ |
||||||
|
public static BufferedImage createHTMLContentBufferedImage(String value, Rectangle paintRectangle, int x, int y, Style style) { |
||||||
|
return Html2ImageUtils.createHTMLContentBufferedImage(value, paintRectangle, x, y, style); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* see <code>BaseUtils.getLineTextList</code>, 等于BaseUtils.getLineTextList().size() |
||||||
|
* Denny: 为了提高速度和性能,才单独拿出来的 |
||||||
|
* TODO: 重构 |
||||||
|
* |
||||||
|
* @param text 文本 |
||||||
|
* @param style 样式 |
||||||
|
* @param paintWidth 单元格宽度 |
||||||
|
* @return paintWidth 单位为PT |
||||||
|
*/ |
||||||
|
public static int getLineTextCount(String text, Style style, UNIT paintWidth) { |
||||||
|
if (style.getRotation() != 0) { |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
if (style.getTextStyle() != Style.TEXTSTYLE_WRAPTEXT) { |
||||||
|
return dealNotWrapTextCount(text.toCharArray()); |
||||||
|
} else {// 自动换行
|
||||||
|
return dealWrapTextCount(text, style, paintWidth); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static int dealNotWrapTextCount(char[] text_chars) { |
||||||
|
boolean remain_chars = false; |
||||||
|
int count = 0; |
||||||
|
for (int t = 0; t < text_chars.length; t++) { |
||||||
|
if (text_chars[t] == '\\') {// 判断是否是 "\n"
|
||||||
|
if (t + 1 < text_chars.length && text_chars[t + 1] == 'n') { |
||||||
|
// 是"\n"字符串,但不是换行符.
|
||||||
|
t++; |
||||||
|
count++; |
||||||
|
if (remain_chars) { |
||||||
|
remain_chars = false; |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (!remain_chars) { |
||||||
|
remain_chars = true; |
||||||
|
} |
||||||
|
} |
||||||
|
} else if (text_chars[t] == '\n' || (text_chars[t] == '\r' && t + 1 < text_chars.length - 1 && text_chars[t + 1] != '\n')) { |
||||||
|
count++; |
||||||
|
if (remain_chars) { |
||||||
|
remain_chars = false; |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (!remain_chars) { |
||||||
|
remain_chars = true; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 最后一个
|
||||||
|
if (remain_chars) { |
||||||
|
count++; |
||||||
|
} |
||||||
|
|
||||||
|
return count; |
||||||
|
} |
||||||
|
|
||||||
|
// 自动换行
|
||||||
|
//neil:style里面, 默认值padding right = 2时, 默认不生效, 这边算行高时也不要计算入内
|
||||||
|
//临时处理, 去掉左边框线, 因为浏览器计算时需要考虑左边框线宽度, 但这边还是存在问题的
|
||||||
|
//同样需要考虑的是导出和web端展示, padding计算方式也不一致.
|
||||||
|
private static int dealWrapTextCount(String text, Style style, UNIT unitWidth) { |
||||||
|
AutoChangeLineAndDrawProcess process = AutoChangeLineAndDrawManager.getProcess(); |
||||||
|
if (process != null) { |
||||||
|
return process.getAutoChangeLineCount(text, new ObjectHolder(style), unitWidth); |
||||||
|
} |
||||||
|
int count = 0; |
||||||
|
char[] text_chars = text.toCharArray(); |
||||||
|
FontMetrics fontMetrics = getFontMetrics(style); |
||||||
|
double paintWidth = unitWidth.toPixD(Constants.FR_PAINT_RESOLUTION); |
||||||
|
double width = paintWidth - style.getPaddingLeft() - (style.getPaddingRight() == Style.DEFAULT_PADDING ? 0 : style.getPaddingRight()) - style.getBorderLeftWidth(); |
||||||
|
boolean remain_lineText = false; |
||||||
|
int lineTextWidth = 0; |
||||||
|
int wordWidth = 0; |
||||||
|
for (int t = 0, len = text_chars.length; t < len; t++) { |
||||||
|
if (t != 0 && BaseUtils.isNumOrLetter(text_chars[t]) && BaseUtils.isNumOrLetter(text_chars[t - 1])) { |
||||||
|
if (wordWidth + fontMetrics.charWidth(text_chars[t]) > width) { |
||||||
|
if (lineTextWidth > 0) { |
||||||
|
count++; |
||||||
|
remain_lineText = false; |
||||||
|
lineTextWidth = 0; |
||||||
|
} |
||||||
|
count++; |
||||||
|
wordWidth = 0; |
||||||
|
} |
||||||
|
wordWidth += fontMetrics.charWidth(text_chars[t]); |
||||||
|
} else if (isSwitchLine(text_chars, t) || isLN(text_chars, t)) {// 判断是否是 "\n"
|
||||||
|
if (isLN(text_chars, t)) { |
||||||
|
t++;// 忽略'n'字符.// 是"\n"字符串,但不是换行符,依然需要换行.
|
||||||
|
} |
||||||
|
if (lineTextWidth + wordWidth > width && remain_lineText) { |
||||||
|
count += 2; |
||||||
|
} else { |
||||||
|
count++; |
||||||
|
} |
||||||
|
remain_lineText = false; |
||||||
|
lineTextWidth = 0; |
||||||
|
wordWidth = 0; |
||||||
|
} else { |
||||||
|
if (text_chars[t] == '\\' && t + 1 < text_chars.length && text_chars[t + 1] == '\\') {// 判断是否是转义字符'\'
|
||||||
|
t++;// _denny: 增加了转义字符'\\'用来表示\,使"\n"可以输入
|
||||||
|
} |
||||||
|
if (lineTextWidth + wordWidth > width && remain_lineText) { |
||||||
|
count++; |
||||||
|
lineTextWidth = isPunctuationAtLineHead(t, text_chars) ? dealLineWidthWithPunctuation(t, text_chars, fontMetrics) : 0; |
||||||
|
} |
||||||
|
remain_lineText = true; |
||||||
|
lineTextWidth += wordWidth; |
||||||
|
wordWidth = fontMetrics.charWidth(text_chars[t]); |
||||||
|
} |
||||||
|
} |
||||||
|
if (lineTextWidth + wordWidth > width && remain_lineText) { |
||||||
|
count += 2; |
||||||
|
} else { |
||||||
|
count++; |
||||||
|
} |
||||||
|
return count; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 标点符号是否在换行后的行首 |
||||||
|
*/ |
||||||
|
private static boolean isPunctuationAtLineHead(int t, char[] text_chars) { |
||||||
|
if (t > 1 && BaseUtils.isPunctuation(text_chars[t - 1])) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 防止有连续多个标点符号,要找一个非标点符号字符 |
||||||
|
* |
||||||
|
* @date 2014-4-17 |
||||||
|
*/ |
||||||
|
private static int dealLineWidthWithPunctuation(int t, char[] text_chars, FontMetrics fontMetrics) { |
||||||
|
if (t < 2) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
int lineWidth = 0; |
||||||
|
for (int index = t - 2; index >= 0; index--) { |
||||||
|
lineWidth += fontMetrics.charWidth(text_chars[index]); |
||||||
|
if (!BaseUtils.isPunctuation(text_chars[index])) { |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
return lineWidth; |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean isSwitchLine(char[] text_chars, int t) { |
||||||
|
return text_chars[t] == '\n' || (text_chars[t] == '\r' && t + 1 < text_chars.length - 1 && text_chars[t + 1] != '\n'); |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean isLN(char[] text_chars, int t) { |
||||||
|
return text_chars[t] == '\\' && t + 1 < text_chars.length && text_chars[t + 1] == 'n'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets the preferred width. |
||||||
|
*/ |
||||||
|
public static UNIT getPreferredWidth(CellElement cell, UNIT height) { |
||||||
|
if (cell == null) { |
||||||
|
return UNIT.ZERO; |
||||||
|
} |
||||||
|
|
||||||
|
Object value = cell.getShowValue(); |
||||||
|
// 只接受Text,Number,和SeparatorPainter
|
||||||
|
// got the text
|
||||||
|
if (value instanceof BaseFormula) { |
||||||
|
if (((BaseFormula) value).getResult() != null) { |
||||||
|
value = ((BaseFormula) value).getResult(); |
||||||
|
} else { |
||||||
|
value = StringUtils.EMPTY; |
||||||
|
} |
||||||
|
} |
||||||
|
Style style = cell.getStyle(); |
||||||
|
if (style == null) { |
||||||
|
style = Style.DEFAULT_STYLE; |
||||||
|
} |
||||||
|
CellGUIAttr cg = cell.getCellGUIAttr() == null ? new CellGUIAttr() : cell.getCellGUIAttr(); |
||||||
|
value = Utils.resolveOtherValue(value, cg.isShowAsImage(), PresentationType.EXPORT); |
||||||
|
String text = Style.valueToText(value, style.getFormat()); |
||||||
|
|
||||||
|
FontMetrics cellFM = getFontMetrics(style); |
||||||
|
//bug 12151 有边框线的单元格 自动调整列宽 会多一行
|
||||||
|
UNIT padding = new PT(style.getPaddingLeft() + style.getPaddingRight()); |
||||||
|
|
||||||
|
if (cg.isShowAsHTML()) { |
||||||
|
return Html2ImageUtils.getHtmlWidth(text, height, style); |
||||||
|
} |
||||||
|
|
||||||
|
return FU.valueOfPix(cellFM.stringWidth(text) + UNIT_SIZE, Constants.FR_PAINT_RESOLUTION).add(padding); |
||||||
|
} |
||||||
|
|
||||||
|
private static FontMetrics getFontMetrics(Style style) { |
||||||
|
Font font = style.getFRFont().applyResolutionNP(Constants.FR_PAINT_RESOLUTION); |
||||||
|
FontProcessor processor = ExtraClassManager.getInstance().getSingle(FontProcessor.MARK_STRING); |
||||||
|
if (processor != null) { |
||||||
|
font = processor.readExtraFont(font); |
||||||
|
} |
||||||
|
return GraphHelper.getFontMetrics(font); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Preferred height. (Got the shrink preferred height of CellElement). |
||||||
|
* 单位格的预计算高度 |
||||||
|
* |
||||||
|
* @param cellElement 单元格内容 |
||||||
|
* @param paintWidth 画的宽度 |
||||||
|
* @return UNIT 单位 |
||||||
|
*/ |
||||||
|
public static UNIT analyzeCellElementPreferredHeight(CellElement cellElement, UNIT paintWidth) { |
||||||
|
// 计算高度用显示值
|
||||||
|
Object value = cellElement.getShowValue(); |
||||||
|
// 只接受Text,Number,和SeparatorPainter
|
||||||
|
Style style = cellElement.getStyle(); |
||||||
|
// got the text
|
||||||
|
if (value instanceof BaseFormula) { |
||||||
|
if (((BaseFormula) value).getResult() != null) { |
||||||
|
value = ((BaseFormula) value).getResult(); |
||||||
|
} else { |
||||||
|
value = StringUtils.EMPTY; |
||||||
|
} |
||||||
|
} |
||||||
|
CellGUIAttr cg = cellElement.getCellGUIAttr() == null ? new CellGUIAttr() : cellElement.getCellGUIAttr(); |
||||||
|
if (!(value instanceof String) && !(value instanceof Integer)) { |
||||||
|
value = DataUtils.resolveOtherValue(value, cg.isShowAsImage(), cg.isShowAsDownload(), null, true); |
||||||
|
} |
||||||
|
String text = Style.valueToText(value, style.getFormat()); |
||||||
|
|
||||||
|
if (cg.isShowAsHTML()) { |
||||||
|
return Html2ImageUtils.getHtmlHeight(text, paintWidth, style); |
||||||
|
} |
||||||
|
|
||||||
|
return PaintUtils.analyzeCellElementPreferredHeight(text, style, paintWidth, cg.isShowAsHTML()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 单位格的预计算高度 |
||||||
|
* 单位PT |
||||||
|
* |
||||||
|
* @param text 文本 |
||||||
|
* @param style 格式 |
||||||
|
* @param paintWidth 画的宽度 |
||||||
|
* @param isShowAsHtml 是否以html展示 |
||||||
|
* @return 返回 单位 |
||||||
|
*/ |
||||||
|
private static UNIT analyzeCellElementPreferredHeight(String text, Style style, UNIT paintWidth, boolean isShowAsHtml) { |
||||||
|
if (style == null) { |
||||||
|
//peter:获取默认的Style.
|
||||||
|
style = Style.DEFAULT_STYLE; |
||||||
|
} |
||||||
|
|
||||||
|
// got the text
|
||||||
|
if (text == null || text.length() <= 0) { |
||||||
|
return PT.valueOf(0); |
||||||
|
} |
||||||
|
|
||||||
|
// 变成Line Text List.
|
||||||
|
if (style.getRotation() != 0) { // more easy to paint.
|
||||||
|
// attribute map.
|
||||||
|
return PT.valueOf((float) GraphHelper.stringDimensionWithRotation(text, style.getFRFont(), -style.getRotation(), |
||||||
|
CoreConstants.DEFAULT_FRC).getHeight()); |
||||||
|
} |
||||||
|
// 先获得FontMetics.
|
||||||
|
int lineCount = getLineTextCount(text, style, paintWidth); |
||||||
|
AutoChangeLineAndDrawProcess process = AutoChangeLineAndDrawManager.getProcess(); |
||||||
|
if (process != null) { |
||||||
|
//算了这两个接口分开做
|
||||||
|
return process.getLinedTextHeight(lineCount, new ObjectHolder(style)); |
||||||
|
} |
||||||
|
|
||||||
|
// carl:和paint那边一致,添上段前段后和行间距
|
||||||
|
PT lineSpacing = PT.valueOf(style.getSpacingAfter() + style.getSpacingBefore() + style.getLineSpacing() * lineCount); |
||||||
|
FontMetrics fontMetrics = getFontMetrics(style); |
||||||
|
int textHeight = fontMetrics.getHeight(); |
||||||
|
FU allTextHeight = FU.valueOfPix(textHeight * lineCount, Constants.FR_PAINT_RESOLUTION); |
||||||
|
return lineSpacing.add(allTextHeight);// 需要给底部添加Leading.
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 截取文字,只考虑了垂直方向,水平方向没意义且难度大. |
||||||
|
* |
||||||
|
* @param value 画的值 |
||||||
|
* @param style 字体样式格式. |
||||||
|
* @param blockArea 冻结的范围 |
||||||
|
* @param resolution 分辨率 |
||||||
|
* @return 返回的字符串 |
||||||
|
*/ |
||||||
|
public static String clipBlockValue(Object value, Style style, Rectangle primitiveArea, Rectangle blockArea, int resolution, boolean isShowAsHTML) { |
||||||
|
if (value == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
if (value instanceof BaseFormula) { |
||||||
|
value = ((BaseFormula) value).getResult(); |
||||||
|
} |
||||||
|
if (blockArea.y >= primitiveArea.height || blockArea.y + blockArea.height <= 0) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
//截取位置,相对于clipArea
|
||||||
|
int startY = blockArea.y > 0 ? blockArea.y : 0; |
||||||
|
int endY = blockArea.y + blockArea.height < primitiveArea.height ? blockArea.y + blockArea.height : primitiveArea.height; |
||||||
|
if (blockArea.x >= primitiveArea.width || blockArea.x + blockArea.width <= 0) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
if (isShowAsHTML) { |
||||||
|
return Html2ImageUtils.clipHtmlContent(value, style, primitiveArea, resolution, startY, endY); |
||||||
|
} |
||||||
|
List lineList = BaseUtils.getLineTextList((String) value, style, style.getFRFont().applyResolutionNP(resolution), primitiveArea.width, resolution); |
||||||
|
if (lineList.isEmpty()) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
double spacingBefore = PT.pt2pix(style.getSpacingBefore(), resolution); |
||||||
|
double spacingAfter = PT.pt2pix(style.getSpacingAfter(), resolution); |
||||||
|
double lineSpacing = PT.pt2pix(style.getLineSpacing(), resolution); |
||||||
|
double lineHeight = lineSpacing + GraphHelper.getFontMetrics(style.getFRFont().applyResolutionNP(resolution)).getHeight(); |
||||||
|
int textAllHeight = (int) (lineHeight * lineList.size() + spacingBefore + spacingAfter); |
||||||
|
//第一行文字距区域高度
|
||||||
|
int textStartY = (int) spacingBefore; |
||||||
|
|
||||||
|
if (style.getVerticalAlignment() == Constants.BOTTOM) { |
||||||
|
textStartY += (primitiveArea.height - textAllHeight); |
||||||
|
} |
||||||
|
if (endY <= textStartY || startY >= textStartY + lineHeight * lineList.size()) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
int lineStart = getLineStart(lineList, lineHeight, textStartY, startY);//截取区域起始行
|
||||||
|
int lineEnd = getLineEnd(lineList, lineHeight, endY, textStartY);//截取区域结束行
|
||||||
|
String text = ""; |
||||||
|
for (; lineStart <= lineEnd; lineStart++) { |
||||||
|
text += lineList.get(lineStart); |
||||||
|
} |
||||||
|
return text; |
||||||
|
} |
||||||
|
|
||||||
|
private static int getLineStart(List lineList, double lineHeight, int textStartY, int startY) { |
||||||
|
int lineStart = 0; |
||||||
|
for (int i = 0; i < lineList.size(); i++) { |
||||||
|
if (textStartY + lineHeight * (i) <= startY && textStartY + lineHeight * (i + 1) > startY) {//压线
|
||||||
|
if (startY - textStartY - lineHeight * (i) > lineHeight / 2) { |
||||||
|
lineStart = i + 1; |
||||||
|
} else { |
||||||
|
lineStart = i; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return lineStart; |
||||||
|
} |
||||||
|
|
||||||
|
private static int getLineEnd(List lineList, double lineHeight, int endY, int textStartY) { |
||||||
|
int lineEnd = lineList.size() - 1; |
||||||
|
for (int i = 0; i < lineList.size(); i++) { |
||||||
|
if (textStartY + lineHeight * (i) < endY && textStartY + lineHeight * (i + 1) >= endY) {//压线
|
||||||
|
//neil:仿宋,12号字, 行间距8为例, 转为px的行间距大小为10.666, 这边算出的应该有31.98行, 因此要进位
|
||||||
|
if (endY - textStartY - lineHeight * (i) >= lineHeight / 2) { |
||||||
|
lineEnd = i; |
||||||
|
} else { |
||||||
|
lineEnd = i - 1; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return lineEnd; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* paintBarcode |
||||||
|
*/ |
||||||
|
public static void paintBarcode(Graphics2D g2d, int width, int height, String text, Style style, BarcodeAttr barcodeAttr) { |
||||||
|
BarcodeImpl barcodeImpl; |
||||||
|
try { |
||||||
|
barcodeImpl = BarCodeUtils.getBarcodeImpl(barcodeAttr, text); |
||||||
|
} catch (BarcodeException exp) { |
||||||
|
try { |
||||||
|
//设置默认值.
|
||||||
|
barcodeImpl = BarCodeUtils.getBarcodeImpl(new BarcodeAttr(), null); |
||||||
|
} catch (BarcodeException e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//字体
|
||||||
|
if (style.getFRFont() != null) { |
||||||
|
barcodeImpl.setFont(style.getFRFont()); |
||||||
|
barcodeImpl.setForeground(style.getFRFont().getForeground()); |
||||||
|
} |
||||||
|
//背景
|
||||||
|
Background background = style.getBackground(); |
||||||
|
if (background != null && background instanceof ColorBackground) { |
||||||
|
barcodeImpl.setBackground(((ColorBackground) background).getColor()); |
||||||
|
} |
||||||
|
|
||||||
|
//根据宽度和高度来确定起始点
|
||||||
|
int pointX = (width - barcodeImpl.getWidth()) / 2; |
||||||
|
int pointY = (height - barcodeImpl.getHeight()) / 2; |
||||||
|
|
||||||
|
barcodeImpl.draw(g2d, pointX, pointY); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* create font attribute map, 创建属性map |
||||||
|
* |
||||||
|
* @param font 字体 |
||||||
|
* @return map 返回字体创建的Map |
||||||
|
*/ |
||||||
|
public static Map createFontAttributeMap(Font font) { |
||||||
|
Map returnFontAttributeMap = (Map) fontAttributeMapCache.get(font); |
||||||
|
if (returnFontAttributeMap == null) {// create
|
||||||
|
// returnFontAttributeMap.
|
||||||
|
returnFontAttributeMap = font.getAttributes(); |
||||||
|
fontAttributeMapCache.put(font, returnFontAttributeMap); |
||||||
|
} |
||||||
|
|
||||||
|
if (font instanceof FRFont) { |
||||||
|
FRFont frFont = (FRFont) font; |
||||||
|
|
||||||
|
// Strikethrough
|
||||||
|
if (frFont.isStrikethrough()) { |
||||||
|
returnFontAttributeMap.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return returnFontAttributeMap; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,214 @@ |
|||||||
|
package com.fr.design.fit.common; |
||||||
|
|
||||||
|
import com.fr.design.designer.beans.events.DesignerEvent; |
||||||
|
import com.fr.design.designer.creator.XLayoutContainer; |
||||||
|
import com.fr.design.designer.creator.XWAbsoluteBodyLayout; |
||||||
|
import com.fr.design.designer.creator.XWFitLayout; |
||||||
|
import com.fr.design.file.HistoryTemplateListCache; |
||||||
|
import com.fr.design.file.MutilTempalteTabPane; |
||||||
|
import com.fr.design.fit.DesignerUIModeConfig; |
||||||
|
import com.fr.design.fit.JFormType; |
||||||
|
import com.fr.design.fit.NewJForm; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.design.mainframe.FormArea; |
||||||
|
import com.fr.design.mainframe.FormDesigner; |
||||||
|
import com.fr.design.mainframe.JTemplate; |
||||||
|
import com.fr.event.Event; |
||||||
|
import com.fr.event.Listener; |
||||||
|
import com.fr.file.MemFILE; |
||||||
|
import com.fr.file.StashedFILE; |
||||||
|
import com.fr.form.fit.common.LightTool; |
||||||
|
import com.fr.form.fit.NewFormMarkAttr; |
||||||
|
import com.fr.form.ui.Widget; |
||||||
|
import com.fr.form.ui.widget.CRBoundsWidget; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
|
||||||
|
import java.awt.Rectangle; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* @description:模板工具类 |
||||||
|
* @author: Henry.Wang |
||||||
|
* @create: 2020/09/03 14:19 |
||||||
|
*/ |
||||||
|
public class TemplateTool { |
||||||
|
//和转换有关的所有代码都在这个监听器中
|
||||||
|
//在判断新老模式时,统一使用FormUIModeConfig.getInstance().newUIMode()进行判断
|
||||||
|
private static Listener<JTemplate> switchListener = new Listener<JTemplate>() { |
||||||
|
@Override |
||||||
|
public void on(Event event, JTemplate jTemplate) { |
||||||
|
JFormType currentType = JFormType.OLD_TYPE; |
||||||
|
if (AdaptiveSwitchUtil.isSwitchJFromIng()) { |
||||||
|
currentType = DesignerUIModeConfig.getInstance().newUIMode() ? JFormType.NEW_TYPE : JFormType.OLD_TYPE; |
||||||
|
} else { |
||||||
|
if (jTemplate instanceof NewJForm) { |
||||||
|
NewJForm newJForm = (NewJForm) jTemplate; |
||||||
|
if (newJForm.mobileForm()) { |
||||||
|
currentType = JFormType.OLD_TYPE; |
||||||
|
} else if (LightTool.containNewFormFlag(newJForm.getTarget()) || newJForm.getTarget().getTemplateID() == null) { |
||||||
|
currentType = JFormType.NEW_TYPE; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
//UI转换
|
||||||
|
currentType.switchUIMode(); |
||||||
|
//标志位转换
|
||||||
|
currentType.updateJFromTemplateType(jTemplate); |
||||||
|
//预览方式转换
|
||||||
|
currentType.updatePreviewType(jTemplate); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
public static Listener<JTemplate> getSwitchListener() { |
||||||
|
return switchListener; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param |
||||||
|
* @Description: 获取当前模板 |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/6 14:17 |
||||||
|
*/ |
||||||
|
public static JTemplate getCurrentEditingTemplate() { |
||||||
|
JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
||||||
|
return jTemplate; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param |
||||||
|
* @Description: 获取当前NewJForm类型的模板 |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/6 14:17 |
||||||
|
*/ |
||||||
|
public static NewJForm getCurrentEditingNewJForm() { |
||||||
|
JTemplate jTemplate = getCurrentEditingTemplate(); |
||||||
|
if (jTemplate instanceof NewJForm) |
||||||
|
return (NewJForm) jTemplate; |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param newJTemplate |
||||||
|
* @Description: 每次切换设计模式,都会生成新的JForm对象。但是TabPane关联的还是老的JForm对象,所以要重置关联的对象 |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/6 14:15 |
||||||
|
*/ |
||||||
|
public static void resetTabPaneEditingTemplate(JTemplate newJTemplate) { |
||||||
|
if (newJTemplate == null) |
||||||
|
return; |
||||||
|
List<JTemplate<?, ?>> jTemplateList = HistoryTemplateListCache.getInstance().getHistoryList(); |
||||||
|
for (int i = 0; i < jTemplateList.size(); i++) { |
||||||
|
JTemplate oldJTemplate = jTemplateList.get(i); |
||||||
|
if (oldJTemplate != null && ComparatorUtils.equals(oldJTemplate.getEditingFILE(), newJTemplate.getEditingFILE())) { |
||||||
|
jTemplateList.set(i, newJTemplate); |
||||||
|
MutilTempalteTabPane.getInstance().refreshOpenedTemplate(jTemplateList); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* @param jTemplate |
||||||
|
* @Description: 是否是新建的且没有操作的模板 |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/14 20:41 |
||||||
|
*/ |
||||||
|
public static boolean isNewTemplateWithoutModify(JTemplate jTemplate) { |
||||||
|
return ((jTemplate.getEditingFILE() instanceof MemFILE) && jTemplate.isSaved()) ? true : false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param template |
||||||
|
* @Description: 激活模板 |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/6 14:16 |
||||||
|
*/ |
||||||
|
public static void activeAndResizeTemplate(JTemplate template) { |
||||||
|
DesignerContext.getDesignerFrame().addAndActivateJTemplate(template); |
||||||
|
DesignerContext.getDesignerFrame().setVisible(true); |
||||||
|
DesignerContext.getDesignerFrame().resizeFrame(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param jTemplate |
||||||
|
* @Description:保存模板 |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/6 14:32 |
||||||
|
*/ |
||||||
|
public static void saveForm(JTemplate<?, ?> jTemplate) { |
||||||
|
//为空不保存
|
||||||
|
if (jTemplate == null) |
||||||
|
return; |
||||||
|
//不是NewJForm的模板不保存
|
||||||
|
if (!(jTemplate instanceof NewJForm)) |
||||||
|
return; |
||||||
|
//切换环境时产生的模板不保存
|
||||||
|
if (jTemplate.getEditingFILE() instanceof StashedFILE) |
||||||
|
return; |
||||||
|
//新建的且没有操作的模板不保存
|
||||||
|
if (TemplateTool.isNewTemplateWithoutModify(jTemplate)) |
||||||
|
return; |
||||||
|
jTemplate.stopEditing(); |
||||||
|
jTemplate.saveTemplate(); |
||||||
|
jTemplate.requestFocus(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param height |
||||||
|
* @param width |
||||||
|
* @param newJForm |
||||||
|
* @Description: 只改变绝对布局body的尺寸 |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/11 15:14 |
||||||
|
*/ |
||||||
|
public static void onlyChangeAbsoluteBodySize(int height, int width, NewJForm newJForm) { |
||||||
|
FormDesigner formDesigner = newJForm.getFormDesign(); |
||||||
|
FormArea formArea = formDesigner.getArea(); |
||||||
|
XLayoutContainer root = formDesigner.getRootComponent(); |
||||||
|
XWAbsoluteBodyLayout xwAbsoluteBodyLayout = LayoutTool.getXWAbsoluteBodyLayout(newJForm); |
||||||
|
if (root.acceptType(XWFitLayout.class) && xwAbsoluteBodyLayout != null) { |
||||||
|
XWFitLayout layout = (XWFitLayout) root; |
||||||
|
if (height == layout.toData().getContainerHeight() && width == layout.toData().getContainerWidth()) |
||||||
|
return; |
||||||
|
formArea.setWidthPaneValue(width); |
||||||
|
formArea.setHeightPaneValue(height); |
||||||
|
layout.setSize(width, height); |
||||||
|
xwAbsoluteBodyLayout.setSize(width, height); |
||||||
|
Widget widget = layout.toData().getWidget(0); |
||||||
|
if (widget instanceof CRBoundsWidget) { |
||||||
|
((CRBoundsWidget) widget).setBounds(new Rectangle(0, 0, width, height)); |
||||||
|
} |
||||||
|
layout.toData().setContainerWidth(width); |
||||||
|
layout.toData().setContainerHeight(height); |
||||||
|
formArea.doReCalculateRoot(width, height, layout); |
||||||
|
} |
||||||
|
formDesigner.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_EDITED); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param newJForm |
||||||
|
* @Description: 因为新老模板切换有截断的问题,所以body的尺寸会在调用onlyChangeAbsoluteBodySize之后发生改变。为了使模板文件中的尺寸不发生,要在模板保存时调用此函数 |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/11 15:20 |
||||||
|
*/ |
||||||
|
public static void resetAbsoluteBodySize(NewJForm newJForm) { |
||||||
|
if (LayoutTool.absoluteLayoutForm(newJForm)) { |
||||||
|
NewFormMarkAttr newFormMarkAttr = newJForm.getTarget().getAttrMark(NewFormMarkAttr.XML_TAG); |
||||||
|
XLayoutContainer root = newJForm.getFormDesign().getRootComponent(); |
||||||
|
if (newFormMarkAttr != null && root instanceof XWFitLayout) { |
||||||
|
((XWFitLayout) root).toData().setContainerWidth(newFormMarkAttr.getBodyWidth()); |
||||||
|
((XWFitLayout) root).toData().setContainerHeight(newFormMarkAttr.getBodyHeight()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,303 @@ |
|||||||
|
package com.fr.design.fit.menupane; |
||||||
|
|
||||||
|
import com.fr.config.Configuration; |
||||||
|
import com.fr.design.beans.BasicBeanPane; |
||||||
|
import com.fr.design.fit.FitStateCompatible; |
||||||
|
import com.fr.design.fit.JFormType; |
||||||
|
import com.fr.form.fit.FitType; |
||||||
|
import com.fr.form.fit.config.FormFitConfig; |
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.gui.ibutton.UIRadioButton; |
||||||
|
import com.fr.design.gui.icheckbox.UICheckBox; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
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.report.fit.ReportFitAttr; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.transaction.Configurations; |
||||||
|
import com.fr.transaction.Worker; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.ButtonGroup; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.SwingConstants; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Cursor; |
||||||
|
import java.awt.FlowLayout; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by Administrator on 2016/5/5/0005. |
||||||
|
*/ |
||||||
|
public class BrowserFitAttrPane extends BasicBeanPane<ReportFitAttr> { |
||||||
|
|
||||||
|
protected FontRadioGroup fontRadioGroup; |
||||||
|
protected FitRadioGroup fitRadionGroup; |
||||||
|
protected UICheckBox globalCheck; |
||||||
|
protected FitPreviewPane fitPreviewPane; |
||||||
|
protected ReportFitAttr localFitAttr; |
||||||
|
protected UIRadioButton horizonRadio; |
||||||
|
protected UIRadioButton doubleRadio; |
||||||
|
protected UIRadioButton notFitRadio; |
||||||
|
protected UIRadioButton fontFitRadio; |
||||||
|
protected UIRadioButton fontNotFitRadio; |
||||||
|
private UIButton editGlobalOps; |
||||||
|
private JPanel borderPane; |
||||||
|
private JPanel globalOpsPane; |
||||||
|
private JPanel fitOpsPane; |
||||||
|
private final JFormType jFormType; |
||||||
|
|
||||||
|
public BrowserFitAttrPane(JFormType jFormType, ReportFitAttr fitAttr) { |
||||||
|
this.jFormType = jFormType; |
||||||
|
if (fitAttr == null) { |
||||||
|
initComponents(jFormType.obtainFitAttr()); |
||||||
|
} else { |
||||||
|
initComponents(fitAttr); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected void initComponents(ReportFitAttr globalFitAttr) { |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
globalOpsPane = initGlobalOpsPane(globalFitAttr); |
||||||
|
this.add(globalOpsPane, BorderLayout.NORTH); |
||||||
|
fitOpsPane = initFitOpsPane(); |
||||||
|
} |
||||||
|
|
||||||
|
protected void initBorderPane(String title) { |
||||||
|
borderPane = FRGUIPaneFactory.createTitledBorderPaneCenter(title); |
||||||
|
borderPane.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 0)); |
||||||
|
borderPane.add(fitOpsPane, BorderLayout.WEST); |
||||||
|
fitPreviewPane = new FitPreviewPane(); |
||||||
|
borderPane.add(fitPreviewPane, BorderLayout.SOUTH); |
||||||
|
borderPane.add(getHintUILabel()); |
||||||
|
this.add(borderPane, BorderLayout.CENTER); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @Description: 获取提示信息 |
||||||
|
* @param |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/9 16:09 |
||||||
|
*/ |
||||||
|
private UILabel getHintUILabel() { |
||||||
|
String hint = globalCheck.isSelected() ? getFillBlank(3) + Toolkit.i18nText("Fine-Designer_Fit_Attr_Pane_Hint") : StringUtils.EMPTY; |
||||||
|
UILabel hintUILabel = new UILabel(hint); |
||||||
|
hintUILabel.setForeground(new Color(143, 143, 146)); |
||||||
|
return hintUILabel; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @Description: 获取空字符串 |
||||||
|
* @param n |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/9 16:09 |
||||||
|
*/ |
||||||
|
private String getFillBlank(int n) { |
||||||
|
String s = ""; |
||||||
|
for (int i = 0; i < n; i++) { |
||||||
|
s = s + " "; |
||||||
|
} |
||||||
|
return s; |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel initFitOpsPane() { |
||||||
|
double p = TableLayout.PREFERRED; |
||||||
|
double[] rowSize = {p, p}; |
||||||
|
double[] columnSize = {p, p, p, p, p}; |
||||||
|
|
||||||
|
ActionListener actionListener = getPreviewActionListener(); |
||||||
|
|
||||||
|
fontRadioGroup = new FontRadioGroup(); |
||||||
|
fontFitRadio = new UIRadioButton(Toolkit.i18nText("Fine-Designer_Fit") + getFillBlank(4)); |
||||||
|
fontFitRadio.setSelected(true); |
||||||
|
fontNotFitRadio = new UIRadioButton(Toolkit.i18nText("Fine-Designer_Fit-No") + getFillBlank(2)); |
||||||
|
addRadioToGroup(fontRadioGroup, fontFitRadio, fontNotFitRadio); |
||||||
|
fontRadioGroup.addActionListener(actionListener); |
||||||
|
|
||||||
|
fitRadionGroup = new FitRadioGroup(); |
||||||
|
horizonRadio = new UIRadioButton(FitType.HORIZONTAL_FIT.description()); |
||||||
|
doubleRadio = new UIRadioButton(FitType.DOUBLE_FIT.description()); |
||||||
|
notFitRadio = new UIRadioButton(FitType.NOT_FIT.description()); |
||||||
|
addRadioToGroup(fitRadionGroup, doubleRadio, horizonRadio, notFitRadio); |
||||||
|
fitRadionGroup.addActionListener(actionListener); |
||||||
|
|
||||||
|
|
||||||
|
JPanel fitOpsPane = TableLayoutHelper.createTableLayoutPane(initFitComponents(), rowSize, columnSize); |
||||||
|
fitOpsPane.setBorder(BorderFactory.createEmptyBorder(10, 13, 10, 10)); |
||||||
|
return fitOpsPane; |
||||||
|
} |
||||||
|
|
||||||
|
protected Component[][] initFitComponents() { |
||||||
|
UILabel fitFontLabel = new UILabel(Toolkit.i18nText("Fine-Designer_Fit-Font")); |
||||||
|
fitFontLabel.setHorizontalAlignment(SwingConstants.RIGHT); |
||||||
|
UILabel reportFitLabel = new UILabel(Toolkit.i18nText("Fine-Designer_Fit_Report_Scale_Method")); |
||||||
|
reportFitLabel.setHorizontalAlignment(SwingConstants.RIGHT); |
||||||
|
Component[][] components = new Component[][]{ |
||||||
|
new Component[]{fitFontLabel, createFontRadioGroupPane()}, |
||||||
|
new Component[]{reportFitLabel, createFitAttrRadioGroupPane()} |
||||||
|
}; |
||||||
|
return components; |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel createFontRadioGroupPane() { |
||||||
|
JPanel panel = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane(); |
||||||
|
panel.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 0)); |
||||||
|
panel.add(fontFitRadio); |
||||||
|
panel.add(fontNotFitRadio); |
||||||
|
return panel; |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel createFitAttrRadioGroupPane() { |
||||||
|
JPanel panel = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane(); |
||||||
|
panel.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 0)); |
||||||
|
panel.add(doubleRadio); |
||||||
|
panel.add(horizonRadio); |
||||||
|
panel.add(notFitRadio); |
||||||
|
return panel; |
||||||
|
} |
||||||
|
|
||||||
|
private void addRadioToGroup(ButtonGroup buttonGroup, UIRadioButton... radios) { |
||||||
|
for (UIRadioButton radio : radios) { |
||||||
|
buttonGroup.add(radio); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel initGlobalOpsPane(final ReportFitAttr globalFitAttr) { |
||||||
|
final JPanel globalOpsPane = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); |
||||||
|
globalCheck = new UICheckBox(Toolkit.i18nText("Fine-Designer_Fit-UseGlobal")); |
||||||
|
globalOpsPane.add(globalCheck); |
||||||
|
globalCheck.addActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
boolean isLocalConfig = !globalCheck.isSelected(); |
||||||
|
//勾选全局时,采用全局保存的自适应属性更新界面
|
||||||
|
if (!isLocalConfig) { |
||||||
|
ReportFitAttr attr = globalFitAttr; |
||||||
|
populateAttrPane(attr); |
||||||
|
remove(BrowserFitAttrPane.this.borderPane); |
||||||
|
initBorderPane(Toolkit.i18nText("Fine-Designer_Fit-Global")); |
||||||
|
} else { |
||||||
|
ReportFitAttr attr = localFitAttr; |
||||||
|
populateAttrPane(attr); |
||||||
|
remove(BrowserFitAttrPane.this.borderPane); |
||||||
|
initBorderPane(Toolkit.i18nText("Fine-Designer_Fit-Local")); |
||||||
|
} |
||||||
|
fontRadioGroup.setEnabled(isLocalConfig); |
||||||
|
fitRadionGroup.setEnabled(isLocalConfig); |
||||||
|
editGlobalOps.setVisible(!isLocalConfig); |
||||||
|
String fitOptions = getCurrentFitOptions(); |
||||||
|
fitPreviewPane.refreshPreview(fitOptions, fitRadionGroup.isEnabled()); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
editGlobalOps = new UIButton(Toolkit.i18nText("Fine-Designer_Fit-EditGlobal")); |
||||||
|
editGlobalOps.setVisible(false); |
||||||
|
editGlobalOps.addMouseListener(new MouseAdapter() { |
||||||
|
public void mouseClicked(MouseEvent evt) { |
||||||
|
fontRadioGroup.setEnabled(true); |
||||||
|
fitRadionGroup.setEnabled(true); |
||||||
|
String fitOptions = getCurrentFitOptions(); |
||||||
|
|
||||||
|
fitPreviewPane.refreshPreview(fitOptions, fitRadionGroup.isEnabled()); |
||||||
|
} |
||||||
|
|
||||||
|
public void mouseEntered(MouseEvent e) { |
||||||
|
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); |
||||||
|
} |
||||||
|
|
||||||
|
public void mouseExited(MouseEvent e) { |
||||||
|
setCursor(Cursor.getDefaultCursor()); |
||||||
|
} |
||||||
|
}); |
||||||
|
globalOpsPane.add(editGlobalOps); |
||||||
|
return globalOpsPane; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String title4PopupWindow() { |
||||||
|
return Toolkit.i18nText("Fine-Designer_Fit-AttrSet"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void populateBean(ReportFitAttr attr) { |
||||||
|
if (attr == null) { |
||||||
|
//如果为空, 就用全局的
|
||||||
|
attr = this.jFormType.obtainFitAttr(); |
||||||
|
populateGlobalComponents(); |
||||||
|
} else { |
||||||
|
initBorderPane(Toolkit.i18nText("Fine-Designer_Fit-Local")); |
||||||
|
} |
||||||
|
this.localFitAttr = attr; |
||||||
|
populateAttrPane(attr); |
||||||
|
} |
||||||
|
|
||||||
|
private void populateAttrPane(ReportFitAttr attr) { |
||||||
|
fontRadioGroup.selectFontFit((attr).isFitFont()); |
||||||
|
int fitState = FitStateCompatible.getNewTypeFromOld(attr.fitStateInPC()); |
||||||
|
fitRadionGroup.selectIndexButton(fitState); |
||||||
|
fitPreviewPane.refreshPreview(getCurrentFitOptions(), fitRadionGroup.isEnabled()); |
||||||
|
} |
||||||
|
|
||||||
|
protected void populateGlobalComponents() { |
||||||
|
globalCheck.setSelected(true); |
||||||
|
fontRadioGroup.setEnabled(false); |
||||||
|
fitRadionGroup.setEnabled(false); |
||||||
|
editGlobalOps.setVisible(true); |
||||||
|
initBorderPane(Toolkit.i18nText("Fine-Designer_Fit-Global")); |
||||||
|
} |
||||||
|
|
||||||
|
//有八种组合, 不过有意义的就是6种, 以此为key去缓存里找对应的预览图片
|
||||||
|
public String getCurrentFitOptions() { |
||||||
|
return fitRadionGroup.getSelectRadioIndex() + "" + fontRadioGroup.getSelectRadioIndex(); |
||||||
|
} |
||||||
|
|
||||||
|
private ActionListener getPreviewActionListener() { |
||||||
|
return new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
String fitOptions = getCurrentFitOptions(); |
||||||
|
fitPreviewPane.refreshPreview(fitOptions, fontRadioGroup.isEnabled()); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ReportFitAttr updateBean() { |
||||||
|
ReportFitAttr attr = new ReportFitAttr(); |
||||||
|
attr.setFitFont(fontRadioGroup.isFontFit()); |
||||||
|
int fitState = FitStateCompatible.getOldTypeFromNew(fitRadionGroup.getSelectRadioIndex()); |
||||||
|
attr.setFitStateInPC(fitState); |
||||||
|
|
||||||
|
// 直接用全局的
|
||||||
|
if (globalCheck.isSelected()) { |
||||||
|
updateGlobalConfig(attr); |
||||||
|
return null; |
||||||
|
} |
||||||
|
this.localFitAttr = attr; |
||||||
|
return attr; |
||||||
|
} |
||||||
|
|
||||||
|
private void updateGlobalConfig(final ReportFitAttr attr) { |
||||||
|
|
||||||
|
Configurations.update(new Worker() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
jFormType.updateFitAttr(attr); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Class<? extends Configuration>[] targets() { |
||||||
|
return new Class[]{FormFitConfig.class}; |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,76 @@ |
|||||||
|
package com.fr.design.fit.menupane; |
||||||
|
|
||||||
|
import com.fr.design.dialog.BasicPane; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.general.IOUtils; |
||||||
|
|
||||||
|
import javax.swing.ImageIcon; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by Administrator on 2016/5/5/0005. |
||||||
|
*/ |
||||||
|
public class FitPreviewPane extends BasicPane { |
||||||
|
private static final String DEFAULT_FONT_TAG = "00"; |
||||||
|
private static final String DEFAULT_TAG = "01"; |
||||||
|
private static final String HORIZON_FONT_TAG = "10"; |
||||||
|
private static final String HORIZON_TAG = "11"; |
||||||
|
private static final String DOUBLE_FONT_TAG = "20"; |
||||||
|
private static final String DOUBLE_TAG = "21"; |
||||||
|
private static final String NOT_FONT_TAG = "30"; |
||||||
|
private static final String NOT_TAG = "31"; |
||||||
|
|
||||||
|
private UILabel imageLabel; |
||||||
|
private Map<String, ImageIcon> cachedPreviewImage = new HashMap<String, ImageIcon>(); |
||||||
|
private Map<String, ImageIcon> globalCachedPreviewImage = new HashMap<String, ImageIcon>(); |
||||||
|
|
||||||
|
public FitPreviewPane() { |
||||||
|
//初始化缓存图片, 有些无意义的组合.
|
||||||
|
initCacheImage(); |
||||||
|
//初始化组件
|
||||||
|
initComponents(); |
||||||
|
this.setPreferredSize(new Dimension(540, 170)); |
||||||
|
} |
||||||
|
|
||||||
|
//默认和不自适应时,字体自适应不起效,只有6张图
|
||||||
|
private void initCacheImage() { |
||||||
|
globalCachedPreviewImage.put(DEFAULT_FONT_TAG, new ImageIcon(IOUtils.readImage("/com/fr/design/images/reportfit/preview/gray/" + DOUBLE_FONT_TAG + ".png"))); |
||||||
|
globalCachedPreviewImage.put(DEFAULT_TAG, new ImageIcon(IOUtils.readImage("/com/fr/design/images/reportfit/preview/gray/" + DOUBLE_TAG + ".png"))); |
||||||
|
globalCachedPreviewImage.put(HORIZON_FONT_TAG, new ImageIcon(IOUtils.readImage("/com/fr/design/images/reportfit/preview/gray/" + HORIZON_FONT_TAG + ".png"))); |
||||||
|
globalCachedPreviewImage.put(HORIZON_TAG, new ImageIcon(IOUtils.readImage("/com/fr/design/images/reportfit/preview/gray/" + HORIZON_TAG + ".png"))); |
||||||
|
globalCachedPreviewImage.put(DOUBLE_FONT_TAG, new ImageIcon(IOUtils.readImage("/com/fr/design/images/reportfit/preview/gray/" + NOT_FONT_TAG + ".png"))); |
||||||
|
globalCachedPreviewImage.put(DOUBLE_TAG, new ImageIcon(IOUtils.readImage("/com/fr/design/images/reportfit/preview/gray/" + NOT_FONT_TAG + ".png"))); |
||||||
|
|
||||||
|
cachedPreviewImage.put(DEFAULT_FONT_TAG, new ImageIcon(IOUtils.readImage("/com/fr/design/images/reportfit/preview/" + DOUBLE_FONT_TAG + ".png"))); |
||||||
|
cachedPreviewImage.put(DEFAULT_TAG, new ImageIcon(IOUtils.readImage("/com/fr/design/images/reportfit/preview/" + DOUBLE_TAG + ".png"))); |
||||||
|
cachedPreviewImage.put(HORIZON_FONT_TAG, new ImageIcon(IOUtils.readImage("/com/fr/design/images/reportfit/preview/" + HORIZON_FONT_TAG + ".png"))); |
||||||
|
cachedPreviewImage.put(HORIZON_TAG, new ImageIcon(IOUtils.readImage("/com/fr/design/images/reportfit/preview/" + HORIZON_TAG + ".png"))); |
||||||
|
cachedPreviewImage.put(DOUBLE_FONT_TAG, new ImageIcon(IOUtils.readImage("/com/fr/design/images/reportfit/preview/" + NOT_FONT_TAG + ".png"))); |
||||||
|
cachedPreviewImage.put(DOUBLE_TAG, new ImageIcon(IOUtils.readImage("/com/fr/design/images/reportfit/preview/" + NOT_FONT_TAG + ".png"))); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private void initComponents() { |
||||||
|
this.setLayout(FRGUIPaneFactory.createCenterFlowLayout()); |
||||||
|
imageLabel = new UILabel(); |
||||||
|
ImageIcon image = cachedPreviewImage.get(DEFAULT_TAG); |
||||||
|
imageLabel.setIcon(image); |
||||||
|
this.add(imageLabel, BorderLayout.CENTER); |
||||||
|
} |
||||||
|
|
||||||
|
public void refreshPreview(String index, boolean isEditedable) { |
||||||
|
ImageIcon newImageIcon = isEditedable ? cachedPreviewImage.get(index) : globalCachedPreviewImage.get(index); |
||||||
|
imageLabel.setIcon(newImageIcon); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String title4PopupWindow() { |
||||||
|
return com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit-Preview"); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,80 @@ |
|||||||
|
package com.fr.design.fit.menupane; |
||||||
|
|
||||||
|
import com.fr.design.gui.ibutton.UIRadioButton; |
||||||
|
|
||||||
|
import javax.swing.AbstractButton; |
||||||
|
import javax.swing.ButtonGroup; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* 自适应四个按钮选项的group |
||||||
|
* <p> |
||||||
|
* Created by Administrator on 2016/5/5/0005. |
||||||
|
*/ |
||||||
|
public class FitRadioGroup extends ButtonGroup { |
||||||
|
|
||||||
|
private List<UIRadioButton> radioButtons = new ArrayList<UIRadioButton>(); |
||||||
|
|
||||||
|
@Override |
||||||
|
public void add(AbstractButton button) { |
||||||
|
super.add(button); |
||||||
|
|
||||||
|
UIRadioButton radioButton = (UIRadioButton) button; |
||||||
|
radioButtons.add(radioButton); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置按钮状态 |
||||||
|
*/ |
||||||
|
public boolean isEnabled() { |
||||||
|
return radioButtons.get(0).isEnabled(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置按钮状态 |
||||||
|
*/ |
||||||
|
public void setEnabled(boolean enabled) { |
||||||
|
for (UIRadioButton radioButton : radioButtons) { |
||||||
|
radioButton.setEnabled(enabled); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取当前选中的按钮index |
||||||
|
* |
||||||
|
* @return 按钮index |
||||||
|
*/ |
||||||
|
public int getSelectRadioIndex() { |
||||||
|
for (int i = 0, len = radioButtons.size(); i < len; i++) { |
||||||
|
if (radioButtons.get(i).isSelected()) { |
||||||
|
return i; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 选中指定index的按钮 |
||||||
|
*/ |
||||||
|
public void selectIndexButton(int index) { |
||||||
|
if (index < 0 || index > radioButtons.size() - 1) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
UIRadioButton button = radioButtons.get(index); |
||||||
|
button.setSelected(true); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 给所有的按钮加上监听 |
||||||
|
*/ |
||||||
|
public void addActionListener(ActionListener actionListener) { |
||||||
|
for (UIRadioButton radioButton : radioButtons) { |
||||||
|
radioButton.addActionListener(actionListener); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
package com.fr.design.fit.menupane; |
||||||
|
|
||||||
|
/** |
||||||
|
* 字体的两个选项组成的group |
||||||
|
* <p> |
||||||
|
* Created by Administrator on 2016/5/5/0005. |
||||||
|
*/ |
||||||
|
public class FontRadioGroup extends FitRadioGroup { |
||||||
|
|
||||||
|
public void selectFontFit(boolean isFontFit) { |
||||||
|
selectIndexButton(isFontFit ? 0 : 1); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isFontFit() { |
||||||
|
return getSelectRadioIndex() == 0; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
package com.fr.design.fit.menupane; |
||||||
|
|
||||||
|
import com.fr.design.beans.BasicBeanPane; |
||||||
|
import com.fr.design.fit.NewJForm; |
||||||
|
import com.fr.report.fit.ReportFitAttr; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.BoxLayout; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by Administrator on 2015/7/6 0006. |
||||||
|
*/ |
||||||
|
public class FormFitAttrPane extends BasicBeanPane<ReportFitAttr> { |
||||||
|
|
||||||
|
private BrowserFitAttrPane attrPane; |
||||||
|
private NewJForm newJForm; |
||||||
|
|
||||||
|
public FormFitAttrPane(NewJForm newJForm) { |
||||||
|
this.newJForm = newJForm; |
||||||
|
initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initComponents() { |
||||||
|
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); |
||||||
|
this.setBorder(BorderFactory.createEmptyBorder(10, 10, 2, 10)); |
||||||
|
attrPane = new BrowserFitAttrPane(this.newJForm.getJFormType(),this.newJForm.getTarget().getReportFitAttr()); |
||||||
|
this.add(attrPane); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 展示界面 |
||||||
|
* |
||||||
|
* @param fitAttr 自适应属性 |
||||||
|
*/ |
||||||
|
public void populateBean(ReportFitAttr fitAttr) { |
||||||
|
attrPane.populateBean(fitAttr); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 提交数据 |
||||||
|
* |
||||||
|
* @return 界面上的更新数据 |
||||||
|
*/ |
||||||
|
public ReportFitAttr updateBean() { |
||||||
|
return attrPane.updateBean(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 标题 |
||||||
|
* |
||||||
|
* @return 标题 |
||||||
|
*/ |
||||||
|
protected String title4PopupWindow() { |
||||||
|
return com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit_PC_Adaptive_Attr"); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,287 @@ |
|||||||
|
package com.fr.design.fit.toolbar; |
||||||
|
|
||||||
|
import com.fr.design.actions.UpdateAction; |
||||||
|
import com.fr.design.dialog.FineJOptionPane; |
||||||
|
import com.fr.design.file.TemplateTreePane; |
||||||
|
import com.fr.design.fit.DesignerUIModeConfig; |
||||||
|
import com.fr.design.fit.NewJForm; |
||||||
|
import com.fr.design.fit.common.AdaptiveSwitchUtil; |
||||||
|
import com.fr.design.fit.common.TemplateTool; |
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.mainframe.BaseJForm; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.design.mainframe.JTemplate; |
||||||
|
import com.fr.design.menu.MenuKeySet; |
||||||
|
import com.fr.file.FILE; |
||||||
|
import com.fr.file.FILEChooserPane; |
||||||
|
import com.fr.file.FileFILE; |
||||||
|
import com.fr.file.FileNodeFILE; |
||||||
|
import com.fr.file.MemFILE; |
||||||
|
import com.fr.file.filetree.FileNode; |
||||||
|
import com.fr.general.IOUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
|
||||||
|
import javax.swing.Icon; |
||||||
|
import javax.swing.ImageIcon; |
||||||
|
import javax.swing.JComponent; |
||||||
|
import javax.swing.JLabel; |
||||||
|
import javax.swing.JOptionPane; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.KeyStroke; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Font; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.nio.file.Paths; |
||||||
|
|
||||||
|
import static javax.swing.JOptionPane.OK_CANCEL_OPTION; |
||||||
|
import static javax.swing.JOptionPane.WARNING_MESSAGE; |
||||||
|
import static javax.swing.JOptionPane.YES_NO_OPTION; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-06-02 |
||||||
|
*/ |
||||||
|
public class SwitchAction extends UpdateAction { |
||||||
|
|
||||||
|
private UIButton switchBtn; |
||||||
|
private static final Icon SWITCH_ICON = IOUtils.readIcon("/com/fr/design/form/images/icon_switch.png"); |
||||||
|
private static final String LOADING_ICON_PATH = "/com/fr/design/form/images/loading.png"; |
||||||
|
private static final MenuKeySet SWITCH_ATTR = new MenuKeySet() { |
||||||
|
@Override |
||||||
|
public char getMnemonic() { |
||||||
|
return 'C'; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getMenuName() { |
||||||
|
return Toolkit.i18nText("Fine-Designer_Fit_Switch_To_Old_UI"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public KeyStroke getKeyStroke() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
public SwitchAction() { |
||||||
|
initMenuStyle(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initMenuStyle() { |
||||||
|
this.setMenuKeySet(SWITCH_ATTR); |
||||||
|
this.setName(getMenuKeySet().getMenuKeySetName()); |
||||||
|
this.setMnemonic(getMenuKeySet().getMnemonic()); |
||||||
|
this.setSmallIcon(SWITCH_ICON); |
||||||
|
this.setAccelerator(getMenuKeySet().getKeyStroke()); |
||||||
|
switchBtn = (UIButton) this.createToolBarComponent(); |
||||||
|
switchBtn.set4ToolbarButton(); |
||||||
|
switchBtn.setIcon(SWITCH_ICON); |
||||||
|
Font oldFont = switchBtn.getFont(); |
||||||
|
switchBtn.setFont(new Font(oldFont.getName(),oldFont.getStyle(),12)); |
||||||
|
switchBtn.setForeground(new Color(0x33, 0x33, 0x34)); |
||||||
|
freshSwitchButton(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
//如果此时模板还在切换中,则直接返回
|
||||||
|
if (AdaptiveSwitchUtil.isSwitchJFromIng() || !saveCurrentEditingTemplate()) |
||||||
|
return; |
||||||
|
backToFormTab(); |
||||||
|
if (confirmSwitchDialog() && backUpOldModeJTemplate()) { |
||||||
|
AdaptiveSwitchUtil.setSwitchJFromIng(1); |
||||||
|
showLoadingJPanel(); |
||||||
|
if (DesignerUIModeConfig.getInstance().newUIMode()) { |
||||||
|
AdaptiveSwitchUtil.switch2OldUI(); |
||||||
|
} else { |
||||||
|
AdaptiveSwitchUtil.switch2NewUI(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @Description: 对未存储在磁盘的模板进行界面切换 |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/10/22 17:26 |
||||||
|
*/ |
||||||
|
public boolean saveCurrentEditingTemplate() { |
||||||
|
JTemplate jTemplate = TemplateTool.getCurrentEditingTemplate(); |
||||||
|
if (!(jTemplate.getEditingFILE() instanceof FileNodeFILE) || !jTemplate.getEditingFILE().exists()) { |
||||||
|
int returnVal = FineJOptionPane.showConfirmDialog( |
||||||
|
DesignerContext.getDesignerFrame(), |
||||||
|
Toolkit.i18nText("Fine-Design_Basic_Web_Preview_Message"), |
||||||
|
Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), |
||||||
|
OK_CANCEL_OPTION, |
||||||
|
WARNING_MESSAGE); |
||||||
|
if (returnVal == JOptionPane.YES_OPTION) { |
||||||
|
jTemplate.stopEditing(); |
||||||
|
if ((jTemplate.getEditingFILE() instanceof MemFILE) || !jTemplate.getEditingFILE().exists()) { |
||||||
|
return jTemplate.saveTemplate(); |
||||||
|
} else if (jTemplate.getEditingFILE() instanceof FileFILE) { |
||||||
|
return jTemplate.saveAsTemplate2Env(); |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @Description: 显示加载中界面 |
||||||
|
* @param |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/30 15:18 |
||||||
|
*/ |
||||||
|
public void showLoadingJPanel() { |
||||||
|
JComponent area = TemplateTool.getCurrentEditingNewJForm().getFormDesign().getArea(); |
||||||
|
JComponent formDesigner = TemplateTool.getCurrentEditingNewJForm().getFormDesign(); |
||||||
|
area.remove(formDesigner); |
||||||
|
|
||||||
|
JPanel loadingJPanel = new JPanel(new BorderLayout()); |
||||||
|
loadingJPanel.setBackground(Color.WHITE); |
||||||
|
loadingJPanel.setBounds(formDesigner.getBounds()); |
||||||
|
JLabel jLabel = new JLabel(new ImageIcon(this.getClass().getResource(LOADING_ICON_PATH)), JLabel.CENTER); |
||||||
|
loadingJPanel.add(jLabel, BorderLayout.CENTER); |
||||||
|
|
||||||
|
area.setLayout(null); |
||||||
|
area.add(loadingJPanel); |
||||||
|
DesignerContext.getDesignerFrame().setVisible(true); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* @Description: 如果是在报表块编辑状态进行切换时,会先回到表单页 |
||||||
|
* @param |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/30 15:20 |
||||||
|
*/ |
||||||
|
private void backToFormTab() { |
||||||
|
NewJForm newJForm = TemplateTool.getCurrentEditingNewJForm(); |
||||||
|
if (newJForm != null && newJForm.getEditingReportIndex() != BaseJForm.FORM_TAB) { |
||||||
|
newJForm.tabChanged(BaseJForm.FORM_TAB); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param |
||||||
|
* @Description: 备份老设计模式下的模板文件 |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/23 16:24 |
||||||
|
*/ |
||||||
|
private boolean backUpOldModeJTemplate() { |
||||||
|
JTemplate<?, ?> jTemplate = TemplateTool.getCurrentEditingTemplate(); |
||||||
|
if (jTemplate != null && !DesignerUIModeConfig.getInstance().newUIMode()) { |
||||||
|
FILE editingFILE = jTemplate.getEditingFILE(); |
||||||
|
if (editingFILE != null && editingFILE.exists()) { |
||||||
|
try { |
||||||
|
//待备份的文件名称
|
||||||
|
String fileName = editingFILE.getName().substring(0, editingFILE.getName().length() - jTemplate.suffix().length()) + "_bak"; |
||||||
|
//生成要备份的文件对象
|
||||||
|
FILE backUpFile = null; |
||||||
|
FileNodeFILE directory = getFileParentDirectory(jTemplate.getEditingFILE()); |
||||||
|
if (directory != null) |
||||||
|
backUpFile = new FileNodeFILE(directory, fileName + jTemplate.suffix(), false); |
||||||
|
//要备份的文件存在
|
||||||
|
if (backUpFile != null && backUpFile.exists()) { |
||||||
|
if (!confirmCoverFileDialog()) { |
||||||
|
FILEChooserPane fileChooser = FILEChooserPane.getInstance(true, true); |
||||||
|
fileChooser.setFileNameTextField(fileName, jTemplate.suffix()); |
||||||
|
fileChooser.setCurrentDirectory(directory); |
||||||
|
int chooseResult = fileChooser.showSaveDialog(DesignerContext.getDesignerFrame(), jTemplate.suffix()); |
||||||
|
if ((chooseResult == FILEChooserPane.CANCEL_OPTION) || |
||||||
|
(chooseResult == FILEChooserPane.JOPTIONPANE_CANCEL_OPTION)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
backUpFile = fileChooser.getSelectedFILE(); |
||||||
|
} |
||||||
|
} |
||||||
|
jTemplate.getTarget().export(backUpFile.asOutputStream()); |
||||||
|
TemplateTreePane.getInstance().refresh(); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage()); |
||||||
|
return false; |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param file |
||||||
|
* @Description: 获得当前文件的父目录 |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/23 16:50 |
||||||
|
*/ |
||||||
|
public static FileNodeFILE getFileParentDirectory(FILE file) { |
||||||
|
FileNodeFILE fileParent = null; |
||||||
|
if (file instanceof FileNodeFILE) { |
||||||
|
FileNodeFILE fileNodeFILE = (FileNodeFILE) file; |
||||||
|
FileNode fileNode = new FileNode(Paths.get(fileNodeFILE.getPath()).getParent().toString(), true); |
||||||
|
fileParent = new FileNodeFILE(fileNode, fileNodeFILE.getEnvPath()); |
||||||
|
} |
||||||
|
return fileParent; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param |
||||||
|
* @Description: 确认是否弹出框 |
||||||
|
* @return: 点击确定返回true |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/18 11:20 |
||||||
|
*/ |
||||||
|
private boolean confirmSwitchDialog() { |
||||||
|
Object message = DesignerUIModeConfig.getInstance().newUIMode() ? Toolkit.i18nText("Fine-Designer_Fit_Confirm_New_Old_Switch") : Toolkit.i18nText("Fine-Designer_Fit_Confirm_Old_New_Switch"); |
||||||
|
int returnVal = FineJOptionPane.showConfirmDialog( |
||||||
|
DesignerContext.getDesignerFrame(), |
||||||
|
message, |
||||||
|
Toolkit.i18nText("Fine-Design_Basic_Confirm"), |
||||||
|
YES_NO_OPTION); |
||||||
|
return returnVal == JOptionPane.YES_OPTION; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param |
||||||
|
* @Description: 是否覆盖文件 |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/9/23 17:00 |
||||||
|
*/ |
||||||
|
private boolean confirmCoverFileDialog() { |
||||||
|
int returnVal = FineJOptionPane.showConfirmDialog( |
||||||
|
DesignerContext.getDesignerFrame(), |
||||||
|
Toolkit.i18nText("Fine-Designer_Fit_Cover_File_Switch"), |
||||||
|
Toolkit.i18nText("Fine-Design_Basic_Confirm"), |
||||||
|
YES_NO_OPTION); |
||||||
|
return returnVal == JOptionPane.YES_OPTION; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param |
||||||
|
* @Description:更新按钮的状态 |
||||||
|
* @return: |
||||||
|
* @Author: Henry.Wang |
||||||
|
* @date: 2020/8/31 16:39 |
||||||
|
*/ |
||||||
|
public UIButton freshSwitchButton() { |
||||||
|
if (DesignerUIModeConfig.getInstance().newUIMode()) { |
||||||
|
switchBtn.setToolTipText(Toolkit.i18nText("Fine-Designer_Fit_Switch_To_Old_UI")); |
||||||
|
switchBtn.setText(Toolkit.i18nText("Fine-Designer_Fit_Switch_To_Old_Version")); |
||||||
|
} else { |
||||||
|
switchBtn.setToolTipText(Toolkit.i18nText("Fine-Designer_Fit_Switch_To_New_UI")); |
||||||
|
switchBtn.setText(Toolkit.i18nText("Fine-Designer_Fit_Switch_To_New_Version")); |
||||||
|
} |
||||||
|
return switchBtn; |
||||||
|
} |
||||||
|
|
||||||
|
public UIButton getToolBarButton() { |
||||||
|
return freshSwitchButton(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
package com.fr.design.preview; |
||||||
|
|
||||||
|
import com.fr.design.file.HistoryTemplateListCache; |
||||||
|
import com.fr.design.fun.impl.AbstractPreviewProvider; |
||||||
|
import com.fr.design.mainframe.JForm; |
||||||
|
import com.fr.design.mainframe.JTemplate; |
||||||
|
import com.fr.general.web.ParameterConstants; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-04-23 |
||||||
|
*/ |
||||||
|
public class DeveloperPreview extends AbstractPreviewProvider { |
||||||
|
private static final int PREVIEW_TYPE = 7; |
||||||
|
|
||||||
|
@Override |
||||||
|
public String nameForPopupItem() { |
||||||
|
return com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit_Developer_Preview"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String iconPathForPopupItem() { |
||||||
|
return "com/fr/design/form/images/developer_preview.png"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String iconPathForLarge() { |
||||||
|
return "com/fr/design/form/images/developer_preview24.png"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int previewTypeCode() { |
||||||
|
return PREVIEW_TYPE; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public Map<String, Object> parametersForPreview() { |
||||||
|
Map<String, Object> map = new HashMap<String, Object>(); |
||||||
|
map.put(ParameterConstants.OP, "developer_preview"); |
||||||
|
return map; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean accept(JTemplate jTemplate) { |
||||||
|
if (jTemplate == null) { |
||||||
|
jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
||||||
|
} |
||||||
|
return jTemplate instanceof JForm; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,54 @@ |
|||||||
|
package com.fr.design.preview; |
||||||
|
|
||||||
|
import com.fr.design.file.HistoryTemplateListCache; |
||||||
|
import com.fr.design.fun.impl.AbstractPreviewProvider; |
||||||
|
import com.fr.design.mainframe.JForm; |
||||||
|
import com.fr.design.mainframe.JTemplate; |
||||||
|
import com.fr.general.web.ParameterConstants; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 2020-04-23 |
||||||
|
*/ |
||||||
|
public class FormAdaptivePreview extends AbstractPreviewProvider { |
||||||
|
private static final int PREVIEW_TYPE = 6; |
||||||
|
public static final String PREVIEW_OP = "form_adaptive"; |
||||||
|
|
||||||
|
@Override |
||||||
|
public String nameForPopupItem() { |
||||||
|
return com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit_New_Form_Preview"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String iconPathForPopupItem() { |
||||||
|
return "com/fr/design/images/buttonicon/runs.png"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String iconPathForLarge() { |
||||||
|
return "com/fr/design/images/buttonicon/run24.png"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int previewTypeCode() { |
||||||
|
return PREVIEW_TYPE; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public Map<String, Object> parametersForPreview() { |
||||||
|
Map<String, Object> map = new HashMap<String, Object>(); |
||||||
|
map.put(ParameterConstants.OP, PREVIEW_OP); |
||||||
|
return map; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean accept(JTemplate jTemplate) { |
||||||
|
if (jTemplate == null) { |
||||||
|
jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
||||||
|
} |
||||||
|
return jTemplate instanceof JForm; |
||||||
|
} |
||||||
|
} |
After Width: | Height: | Size: 542 B |
After Width: | Height: | Size: 862 B |
After Width: | Height: | Size: 130 B |
After Width: | Height: | Size: 304 B |
After Width: | Height: | Size: 296 B |
After Width: | Height: | Size: 413 B |
After Width: | Height: | Size: 417 B |