PageRenderTime 79ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/src/mpv5/ui/dialogs/subcomponents/ControlPanel_Groups.java

http://mp-rechnungs-und-kundenverwaltung.googlecode.com/
Java | 536 lines | 429 code | 66 blank | 41 comment | 44 complexity | 89b66a232d4f1f9bbdc70e3ffb1f7d44 MD5 | raw file
Possible License(s): LGPL-3.0, Apache-2.0, GPL-3.0, GPL-2.0, AGPL-3.0, JSON, BSD-3-Clause
  1. /*
  2. This file is part of YaBS.
  3. YaBS is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. YaBS is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with YaBS. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /*
  15. * ContactPanel.java
  16. *
  17. * Created on Nov 20, 2008, 8:17:28 AM
  18. */
  19. package mpv5.ui.dialogs.subcomponents;
  20. import java.awt.Color;
  21. import java.awt.Component;
  22. import java.awt.event.MouseEvent;
  23. import java.io.File;
  24. import java.util.ArrayList;
  25. import java.util.Collections;
  26. import java.util.logging.Level;
  27. import java.util.logging.Logger;
  28. import javax.swing.JTextField;
  29. import javax.swing.tree.DefaultMutableTreeNode;
  30. import javax.swing.tree.TreeNode;
  31. import javax.swing.tree.TreeSelectionModel;
  32. import mpv5.data.PropertyStore;
  33. import mpv5.db.common.Context;
  34. import mpv5.db.common.DatabaseObject;
  35. import mpv5.db.common.DatabaseSearch;
  36. import mpv5.db.common.NodataFoundException;
  37. import mpv5.db.common.QueryCriteria;
  38. import mpv5.db.common.QueryCriteria2;
  39. import mpv5.db.common.QueryHandler;
  40. import mpv5.db.common.QueryParameter;
  41. import mpv5.globals.Messages;
  42. import mpv5.db.objects.Group;
  43. import mpv5.logging.Log;
  44. import mpv5.ui.dialogs.ControlApplet;
  45. import mpv5.ui.dialogs.Popup;
  46. import mpv5.ui.frames.MPView;
  47. import mpv5.ui.panels.DataPanel;
  48. import mpv5.usermanagement.MPSecurityManager;
  49. import mpv5.utils.arrays.ArrayUtilities;
  50. import mpv5.utils.export.Export;
  51. import mpv5.utils.models.MPTreeModel;
  52. import mpv5.utils.trees.TreeFormat;
  53. import mpv5.utils.ui.TextFieldUtils;
  54. /**
  55. *
  56. *
  57. */
  58. public class ControlPanel_Groups extends javax.swing.JPanel implements ControlApplet, DataPanel {
  59. private static final long serialVersionUID = 1L;
  60. private ControlPanel_Groups insta;
  61. private ArrayList<Object[]> arr;
  62. private Group dataOwner;
  63. private boolean root;
  64. /**
  65. * Creates new form ContactPanel
  66. */
  67. public ControlPanel_Groups() {
  68. if (MPSecurityManager.checkAdminAccess()) {
  69. initComponents();
  70. tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
  71. refresh();
  72. }
  73. }
  74. public ControlPanel_Groups(Group aThis) {
  75. if (MPSecurityManager.checkAdminAccess()) {
  76. initComponents();
  77. tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
  78. refresh();
  79. setDataOwner(aThis, true);
  80. }
  81. }
  82. public void showRequiredFields() {
  83. TextFieldUtils.blinkerRed(cname);
  84. TextFieldUtils.blinkerGrey(parents);
  85. }
  86. /**
  87. * This method is called from within the constructor to initialize the form.
  88. * WARNING: Do NOT modify this code. The content of this method is always
  89. * regenerated by the Form Editor.
  90. */
  91. @SuppressWarnings("unchecked")
  92. // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  93. private void initComponents() {
  94. buttonGroup1 = new javax.swing.ButtonGroup();
  95. jPanel1 = new javax.swing.JPanel();
  96. jScrollPane1 = new javax.swing.JScrollPane();
  97. tree = new javax.swing.JTree();
  98. jLabel1 = new javax.swing.JLabel();
  99. rightpane = new javax.swing.JPanel();
  100. cname = new mpv5.ui.beans.LabeledTextField();
  101. parents = new mpv5.ui.beans.LabeledTextField();
  102. jScrollPane3 = new javax.swing.JScrollPane();
  103. jTextArea2 = new javax.swing.JTextArea();
  104. jLabel2 = new javax.swing.JLabel();
  105. jScrollPane2 = new javax.swing.JScrollPane();
  106. desc = new javax.swing.JTextArea();
  107. jLabel3 = new javax.swing.JLabel();
  108. path = new mpv5.ui.beans.LabeledTextField();
  109. jPanel2 = new javax.swing.JPanel();
  110. jButton4 = new javax.swing.JButton();
  111. jButton3 = new javax.swing.JButton();
  112. jButton2 = new javax.swing.JButton();
  113. jButton1 = new javax.swing.JButton();
  114. java.util.ResourceBundle bundle = mpv5.i18n.LanguageManager.getBundle(); // NOI18N
  115. setBorder(javax.swing.BorderFactory.createTitledBorder(bundle.getString("ControlPanel_Groups.border.title"))); // NOI18N
  116. setName("Form"); // NOI18N
  117. setLayout(new java.awt.BorderLayout());
  118. jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder());
  119. jPanel1.setName("jPanel1"); // NOI18N
  120. jScrollPane1.setName("jScrollPane1"); // NOI18N
  121. javax.swing.tree.DefaultMutableTreeNode treeNode1 = new javax.swing.tree.DefaultMutableTreeNode("root");
  122. tree.setModel(new javax.swing.tree.DefaultTreeModel(treeNode1));
  123. tree.setToolTipText(bundle.getString("ControlPanel_Groups.tree.toolTipText")); // NOI18N
  124. tree.setLargeModel(true);
  125. tree.setName("tree"); // NOI18N
  126. tree.addMouseListener(new java.awt.event.MouseAdapter() {
  127. public void mouseClicked(java.awt.event.MouseEvent evt) {
  128. treeMouseClicked(evt);
  129. }
  130. });
  131. jScrollPane1.setViewportView(tree);
  132. jLabel1.setText(bundle.getString("ControlPanel_Groups.jLabel1.text")); // NOI18N
  133. jLabel1.setName("jLabel1"); // NOI18N
  134. javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
  135. jPanel1.setLayout(jPanel1Layout);
  136. jPanel1Layout.setHorizontalGroup(
  137. jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
  138. .addGroup(jPanel1Layout.createSequentialGroup()
  139. .addContainerGap()
  140. .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
  141. .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 133, Short.MAX_VALUE)
  142. .addComponent(jLabel1))
  143. .addContainerGap())
  144. );
  145. jPanel1Layout.setVerticalGroup(
  146. jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
  147. .addGroup(jPanel1Layout.createSequentialGroup()
  148. .addContainerGap()
  149. .addComponent(jLabel1)
  150. .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
  151. .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 292, Short.MAX_VALUE)
  152. .addContainerGap())
  153. );
  154. add(jPanel1, java.awt.BorderLayout.CENTER);
  155. rightpane.setBorder(javax.swing.BorderFactory.createTitledBorder(bundle.getString("ControlPanel_Groups.rightpane.border.title"))); // NOI18N
  156. rightpane.setName("rightpane"); // NOI18N
  157. cname.set_Label(bundle.getString("ControlPanel_Groups.cname._Label")); // NOI18N
  158. cname.setName("cname"); // NOI18N
  159. parents.set_Label(bundle.getString("ControlPanel_Groups.parents._Label")); // NOI18N
  160. parents.setEnabled(false);
  161. parents.setName("parents"); // NOI18N
  162. jScrollPane3.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
  163. jScrollPane3.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
  164. jScrollPane3.setName("jScrollPane3"); // NOI18N
  165. jTextArea2.setColumns(20);
  166. jTextArea2.setEditable(false);
  167. jTextArea2.setLineWrap(true);
  168. jTextArea2.setRows(5);
  169. jTextArea2.setText(bundle.getString("ControlPanel_Groups.jTextArea2.text")); // NOI18N
  170. jTextArea2.setWrapStyleWord(true);
  171. jTextArea2.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
  172. jTextArea2.setName("jTextArea2"); // NOI18N
  173. jScrollPane3.setViewportView(jTextArea2);
  174. jLabel2.setFont(new java.awt.Font("Dialog", 0, 12));
  175. jLabel2.setText(bundle.getString("ControlPanel_Groups.jLabel2.text")); // NOI18N
  176. jLabel2.setName("jLabel2"); // NOI18N
  177. jScrollPane2.setName("jScrollPane2"); // NOI18N
  178. desc.setColumns(20);
  179. desc.setRows(5);
  180. desc.setName("desc"); // NOI18N
  181. jScrollPane2.setViewportView(desc);
  182. jLabel3.setFont(new java.awt.Font("Dialog", 0, 12));
  183. jLabel3.setText(bundle.getString("ControlPanel_Groups.jLabel3.text")); // NOI18N
  184. jLabel3.setName("jLabel3"); // NOI18N
  185. path.set_Label(bundle.getString("ControlPanel_Groups.path._Label")); // NOI18N
  186. path.setName("path"); // NOI18N
  187. javax.swing.GroupLayout rightpaneLayout = new javax.swing.GroupLayout(rightpane);
  188. rightpane.setLayout(rightpaneLayout);
  189. rightpaneLayout.setHorizontalGroup(
  190. rightpaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
  191. .addGroup(rightpaneLayout.createSequentialGroup()
  192. .addContainerGap()
  193. .addGroup(rightpaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
  194. .addComponent(jLabel3)
  195. .addComponent(cname, javax.swing.GroupLayout.DEFAULT_SIZE, 312, Short.MAX_VALUE)
  196. .addComponent(jLabel2)
  197. .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 312, Short.MAX_VALUE)
  198. .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 312, Short.MAX_VALUE)
  199. .addComponent(parents, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 312, Short.MAX_VALUE)
  200. .addComponent(path, javax.swing.GroupLayout.DEFAULT_SIZE, 312, Short.MAX_VALUE))
  201. .addContainerGap())
  202. );
  203. rightpaneLayout.setVerticalGroup(
  204. rightpaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
  205. .addGroup(rightpaneLayout.createSequentialGroup()
  206. .addComponent(jLabel3)
  207. .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
  208. .addComponent(cname, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
  209. .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
  210. .addComponent(jLabel2)
  211. .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
  212. .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
  213. .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
  214. .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 51, javax.swing.GroupLayout.PREFERRED_SIZE)
  215. .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
  216. .addComponent(parents, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
  217. .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
  218. .addComponent(path, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
  219. .addContainerGap(42, Short.MAX_VALUE))
  220. );
  221. add(rightpane, java.awt.BorderLayout.EAST);
  222. jPanel2.setBackground(new java.awt.Color(255, 255, 255));
  223. jPanel2.setName("jPanel2"); // NOI18N
  224. jPanel2.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT));
  225. jButton4.setText(bundle.getString("ControlPanel_Groups.jButton4.text")); // NOI18N
  226. jButton4.setName("jButton4"); // NOI18N
  227. jButton4.addActionListener(new java.awt.event.ActionListener() {
  228. public void actionPerformed(java.awt.event.ActionEvent evt) {
  229. jButton4ActionPerformed(evt);
  230. }
  231. });
  232. jPanel2.add(jButton4);
  233. jButton3.setText(bundle.getString("ControlPanel_Groups.jButton3.text")); // NOI18N
  234. jButton3.setName("jButton3"); // NOI18N
  235. jButton3.addActionListener(new java.awt.event.ActionListener() {
  236. public void actionPerformed(java.awt.event.ActionEvent evt) {
  237. jButton3ActionPerformed(evt);
  238. }
  239. });
  240. jPanel2.add(jButton3);
  241. jButton2.setText(bundle.getString("ControlPanel_Groups.jButton2.text")); // NOI18N
  242. jButton2.setName("jButton2"); // NOI18N
  243. jButton2.addActionListener(new java.awt.event.ActionListener() {
  244. public void actionPerformed(java.awt.event.ActionEvent evt) {
  245. jButton2ActionPerformed(evt);
  246. }
  247. });
  248. jPanel2.add(jButton2);
  249. jButton1.setText(bundle.getString("ControlPanel_Groups.jButton1.text")); // NOI18N
  250. jButton1.setName("jButton1"); // NOI18N
  251. jButton1.addActionListener(new java.awt.event.ActionListener() {
  252. public void actionPerformed(java.awt.event.ActionEvent evt) {
  253. jButton1ActionPerformed(evt);
  254. }
  255. });
  256. jPanel2.add(jButton1);
  257. add(jPanel2, java.awt.BorderLayout.PAGE_END);
  258. }// </editor-fold>//GEN-END:initComponents
  259. private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton4ActionPerformed
  260. if (Popup.Y_N_dialog(Messages.REALLY_DELETE)) {
  261. if (dataOwner != null) {
  262. DatabaseObject dato = dataOwner;
  263. dato.getPanelData(this);
  264. if (dato.__getIDS().intValue() == 1 || !dato.delete()) {
  265. Popup.notice(Messages.NOT_POSSIBLE + "\n" + Messages.IN_USE);
  266. }
  267. }
  268. refresh();
  269. }
  270. }//GEN-LAST:event_jButton4ActionPerformed
  271. private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed
  272. reset();
  273. }//GEN-LAST:event_jButton3ActionPerformed
  274. private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
  275. if (dataOwner != null) {
  276. DatabaseObject dato = dataOwner;
  277. dato.getPanelData(this);
  278. //Issue 239 if the group id of the root group is not 0,
  279. //program will end up in an infinite loop during tree building
  280. if (dato.__getIDS().intValue() == 1) {
  281. dato.setGroupsids(0);
  282. }
  283. if (dato.save()) {
  284. } else {
  285. showRequiredFields();
  286. }
  287. }
  288. }//GEN-LAST:event_jButton2ActionPerformed
  289. private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
  290. if (dataOwner == null) {
  291. dataOwner = new Group();
  292. }
  293. DatabaseObject dato = dataOwner;
  294. if (QueryHandler.instanceOf().clone(Context.getGroup()).checkUniqueness(Context.getGroup().getUniqueColumns(), new JTextField[]{cname.getTextField()})) {
  295. dato.getPanelData(this);
  296. dato.setIDS(-1);
  297. if (dato.save()) {
  298. } else {
  299. showRequiredFields();
  300. }
  301. }
  302. refresh();
  303. }//GEN-LAST:event_jButton1ActionPerformed
  304. private void treeMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_treeMouseClicked
  305. evt.consume();
  306. DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
  307. if (node.isRoot()) {
  308. root = true;
  309. } else {
  310. root = false;
  311. }
  312. if (evt.getButton() == MouseEvent.BUTTON2 || evt.getButton() == MouseEvent.BUTTON3) {
  313. if (node != null) {
  314. Group g = (Group) node.getUserObject();
  315. parents.set_Text(g.__getCname());
  316. path.setText(getPath(node, 0));
  317. }
  318. } else {
  319. if (node != null) {
  320. Group g = (Group) node.getUserObject();
  321. setDataOwner(g, true);
  322. path.setText(getPath(node, 1));
  323. }
  324. }
  325. }//GEN-LAST:event_treeMouseClicked
  326. // Variables declaration - do not modify//GEN-BEGIN:variables
  327. private javax.swing.ButtonGroup buttonGroup1;
  328. private mpv5.ui.beans.LabeledTextField cname;
  329. private javax.swing.JTextArea desc;
  330. private javax.swing.JButton jButton1;
  331. private javax.swing.JButton jButton2;
  332. private javax.swing.JButton jButton3;
  333. private javax.swing.JButton jButton4;
  334. private javax.swing.JLabel jLabel1;
  335. private javax.swing.JLabel jLabel2;
  336. private javax.swing.JLabel jLabel3;
  337. private javax.swing.JPanel jPanel1;
  338. private javax.swing.JPanel jPanel2;
  339. private javax.swing.JScrollPane jScrollPane1;
  340. private javax.swing.JScrollPane jScrollPane2;
  341. private javax.swing.JScrollPane jScrollPane3;
  342. private javax.swing.JTextArea jTextArea2;
  343. private mpv5.ui.beans.LabeledTextField parents;
  344. private mpv5.ui.beans.LabeledTextField path;
  345. private javax.swing.JPanel rightpane;
  346. private javax.swing.JTree tree;
  347. // End of variables declaration//GEN-END:variables
  348. public String description_ = "";
  349. public String defaults_ = "";
  350. public String cname_ = "";
  351. public int ids_;
  352. public int groupsids_ = 1;
  353. public int intaddedby_ = 1;
  354. public java.util.Date dateadded_ = new java.util.Date();
  355. public String hierarchypath_ = "";
  356. @Override
  357. public void setValues(PropertyStore values) {
  358. throw new UnsupportedOperationException("Not supported yet.");
  359. }
  360. @Override
  361. public String getUname() {
  362. return "Groups";
  363. }
  364. @Override
  365. public void reset() {
  366. if (dataOwner != null && dataOwner.isExisting()) {
  367. DatabaseObject dato = dataOwner;
  368. dato.getPanelData(this);
  369. dato.reset();
  370. setDataOwner(dato, true);
  371. }
  372. }
  373. public void refresh() {
  374. Group root;
  375. try {
  376. root = (Group) DatabaseObject.getObject(Context.getGroup(), "groupsids", 0);
  377. } catch (NodataFoundException ex) {
  378. root = new Group(Messages.GROUPNAMES.toString());
  379. root.setIDS(-1);
  380. }
  381. tree.setModel(MPTreeModel.toTreeModel(root));
  382. TreeFormat.expandTree(tree);
  383. }
  384. public boolean collectData() {
  385. if (cname.getText().length() == 0) {
  386. return false;
  387. }
  388. cname_ = cname.get_Text();
  389. description_ = desc.getText();
  390. hierarchypath_ = path.getText();
  391. if (!root) {
  392. try {
  393. groupsids_ = DatabaseObject.getObject(Context.getGroup(), parents.get_Text()).__getIDS();
  394. } catch (NodataFoundException ex) {
  395. groupsids_ = 1;
  396. }
  397. if (ids_ == groupsids_) {
  398. groupsids_ = 1;
  399. }
  400. } else {
  401. groupsids_ = 0;
  402. }
  403. return true;
  404. }
  405. public DatabaseObject getDataOwner() {
  406. return dataOwner;
  407. }
  408. public void setDataOwner(DatabaseObject object, boolean p) {
  409. dataOwner = (Group) object;
  410. if (p) {
  411. dataOwner.setPanelData(this);
  412. this.exposeData();
  413. }
  414. }
  415. public void exposeData() {
  416. cname.set_Text(cname_);
  417. desc.setText(description_);
  418. path.setText(hierarchypath_);
  419. try {
  420. parents.set_Text(DatabaseObject.getObject(Context.getGroup(), groupsids_).__getCname());
  421. } catch (NodataFoundException ex) {
  422. // Log.Debug(this, ex);
  423. }
  424. // defaults.set_Text(defaults_);
  425. }
  426. public void paste(DatabaseObject... dbos) {
  427. for (DatabaseObject dbo : dbos) {
  428. if (dbo.getDbIdentity().equals(Context.getGroup().getDbIdentity())) {
  429. setDataOwner(dbo, true);
  430. } else {
  431. mpv5.YabsViewProxy.instance().addMessage(Messages.NOT_POSSIBLE.toString() + Messages.ACTION_PASTE, Color.RED);
  432. }
  433. }
  434. }
  435. public void showSearchBar(boolean show) {
  436. // throw new UnsupportedOperationException("Not supported yet.");
  437. }
  438. public Component getAndRemoveActionPanel() {
  439. this.remove(jPanel2);
  440. validate();
  441. return jPanel2;
  442. }
  443. @Override
  444. public void actionAfterSave() {
  445. }
  446. @Override
  447. public void actionAfterCreate() {
  448. }
  449. private String getPath(DefaultMutableTreeNode node, int shift) {
  450. TreeNode[] p = node.getPath();
  451. String path1 = "";
  452. for (int i = 0; i < p.length - shift; i++) {
  453. TreeNode treeNode = p[i];
  454. path1 += treeNode.toString() + File.separator;
  455. }
  456. return path1;
  457. }
  458. public void actionBeforeCreate() {
  459. }
  460. public void actionBeforeSave() {
  461. }
  462. public void mail() {
  463. }
  464. public void print() {
  465. mpv5.utils.export.Export.print(this);
  466. }
  467. }