diff --git a/build.xml b/build.xml index 3355f5b..916cecb 100644 --- a/build.xml +++ b/build.xml @@ -26,7 +26,7 @@ - + @@ -110,7 +110,7 @@ - + diff --git a/ivy.xml b/ivy.xml index fee153f..462dde6 100644 --- a/ivy.xml +++ b/ivy.xml @@ -14,5 +14,6 @@ + diff --git a/src/org/p2pvpn/gui/Calendar.java b/src/org/p2pvpn/gui/Calendar.java new file mode 100644 index 0000000..69f01c4 --- /dev/null +++ b/src/org/p2pvpn/gui/Calendar.java @@ -0,0 +1,86 @@ +/* + Copyright 2023-2024 Nikolay Borodin + + This file is part of Lanemu. + + Lanemu is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Lanemu is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with Lanemu. If not, see . +*/ +package org.p2pvpn.gui; +import com.github.lgooddatepicker.components.CalendarPanel; +import com.github.lgooddatepicker.zinternaltools.CustomPopup; +import com.github.lgooddatepicker.zinternaltools.CalendarSelectionEvent; +import com.github.lgooddatepicker.zinternaltools.YearMonthChangeEvent; +import com.github.lgooddatepicker.optionalusertools.CalendarListener; +import java.awt.Component; +import java.awt.Point; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Date; +import javax.swing.JSpinner; +import javax.swing.SwingUtilities; + +/** + * Calendar widget for the date entry field in InviteWindow. + * Uses internal library methods. + * @author monsterovich + */ +public class Calendar implements CalendarListener { + private final CalendarPanel calendarPanel; + private CustomPopup calendarPopup; + private final Component parentComponent; + private final JSpinner inputField; + + public Calendar(Component component, JSpinner field) { + parentComponent = component; + inputField = field; + + calendarPanel = new CalendarPanel(); + calendarPanel.addCalendarListener(this); + } + + void show() { + Date originalDate = (Date) inputField.getModel().getValue(); + calendarPanel.setSelectedDate(originalDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()); + + calendarPopup = + new CustomPopup( + calendarPanel, + SwingUtilities.getWindowAncestor(parentComponent), + null, + null); + + Point pointOnScreen = new Point(); + SwingUtilities.convertPointToScreen(pointOnScreen, parentComponent); + + calendarPopup.setLocation(pointOnScreen.x, pointOnScreen.y + parentComponent.getHeight() + 1); + calendarPopup.show(); + calendarPanel.requestFocus(); + } + + public void selectedDateChanged(CalendarSelectionEvent event) { + LocalDate calendarDate = event.getSource().getSelectedDate(); + if (calendarDate != null && event.isDuplicate()) { + Date originalDate = (Date) inputField.getModel().getValue(); + Date date = Date.from(calendarDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + date.setHours(originalDate.getHours()); + date.setMinutes(originalDate.getMinutes()); + inputField.getModel().setValue(date); + calendarPopup.hide(); + } + } + + public void yearMonthChanged(YearMonthChangeEvent event) { + + } +} diff --git a/src/org/p2pvpn/gui/InviteWindow.form b/src/org/p2pvpn/gui/InviteWindow.form index abef7ff..a4505be 100644 --- a/src/org/p2pvpn/gui/InviteWindow.form +++ b/src/org/p2pvpn/gui/InviteWindow.form @@ -31,29 +31,35 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + @@ -73,7 +79,10 @@ - + + + + @@ -204,5 +213,14 @@ + + + + + + + + + diff --git a/src/org/p2pvpn/gui/InviteWindow.java b/src/org/p2pvpn/gui/InviteWindow.java index 4aa2cde..c1e4f69 100644 --- a/src/org/p2pvpn/gui/InviteWindow.java +++ b/src/org/p2pvpn/gui/InviteWindow.java @@ -1,6 +1,6 @@ /* Copyright 2008, 2009 Wolfgang Ginolas - Copyright 2023 Nikolay Borodin + Copyright 2023-2024 Nikolay Borodin This file is part of Lanemu. @@ -16,7 +16,7 @@ You should have received a copy of the GNU Lesser General Public License along with Lanemu. If not, see . - */ +*/ package org.p2pvpn.gui; import java.awt.Toolkit; @@ -39,6 +39,7 @@ import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import org.p2pvpn.tools.AdvProperties; +import org.p2pvpn.gui.Calendar; /** * This window is shown, when the user wants to invite another persion. @@ -49,6 +50,8 @@ public class InviteWindow extends javax.swing.JDialog implements ClipboardOwner MainControl mainControl; JFileChooser fileChooser; + Calendar calendar; + /** * Creates new form InviteWindow @@ -77,6 +80,7 @@ public class InviteWindow extends javax.swing.JDialog implements ClipboardOwner }); menu.add(mitem); txtInvitation.setComponentPopupMenu(menu); + calendar = new Calendar(btnCalendar, spnExpiryDate); } /** @@ -110,6 +114,7 @@ public class InviteWindow extends javax.swing.JDialog implements ClipboardOwner lblNote = new javax.swing.JLabel(); radNever = new javax.swing.JRadioButton(); radDate = new javax.swing.JRadioButton(); + btnCalendar = new javax.swing.JButton(); setTitle("Generate Invitation"); @@ -177,6 +182,14 @@ public class InviteWindow extends javax.swing.JDialog implements ClipboardOwner grpDate.add(radDate); + btnCalendar.setText("..."); + btnCalendar.setToolTipText("Open calendar"); + btnCalendar.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnCalendarActionPerformed(evt); + } + }); + org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( @@ -185,24 +198,28 @@ public class InviteWindow extends javax.swing.JDialog implements ClipboardOwner .add(layout.createSequentialGroup() .addContainerGap() .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) - .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup() - .add(0, 338, Short.MAX_VALUE) - .add(btnClose)) .add(layout.createSequentialGroup() - .add(lblDate) - .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() - .add(radDate) + .add(lblDate) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) - .add(spnExpiryDate, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 251, Short.MAX_VALUE)) - .add(radNever))) - .add(layout.createSequentialGroup() - .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) - .add(chkNetwork) - .add(lblNote) - .add(btnGenerate)) - .add(0, 0, Short.MAX_VALUE))) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .add(radDate) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(spnExpiryDate, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 262, Short.MAX_VALUE)) + .add(radNever))) + .add(layout.createSequentialGroup() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(chkNetwork) + .add(lblNote) + .add(btnGenerate)) + .add(0, 0, Short.MAX_VALUE))) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(btnCalendar)) + .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup() + .add(0, 0, Short.MAX_VALUE) + .add(btnClose))) .addContainerGap()) ); layout.setVerticalGroup( @@ -217,7 +234,9 @@ public class InviteWindow extends javax.swing.JDialog implements ClipboardOwner .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING) .add(radDate) - .add(spnExpiryDate, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(spnExpiryDate, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(btnCalendar))) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(lblNote) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) @@ -232,6 +251,10 @@ public class InviteWindow extends javax.swing.JDialog implements ClipboardOwner pack(); }// //GEN-END:initComponents + private void btnCalendarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCalendarActionPerformed + calendar.show(); + }//GEN-LAST:event_btnCalendarActionPerformed + private void btnCloseActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_btnCloseActionPerformed setVisible(false); }// GEN-LAST:event_btnCloseActionPerformed @@ -293,6 +316,7 @@ public class InviteWindow extends javax.swing.JDialog implements ClipboardOwner } // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btnCalendar; private javax.swing.JButton btnClose; private javax.swing.JButton btnGenerate; private javax.swing.JButton btnSave;