mirror of https://github.com/sipwise/jitsi.git
parent
d5c8bd2e5f
commit
4a3d23171f
Binary file not shown.
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
|
||||
package net.java.sip.communicator.plugin.extendedcallhistorysearch;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Through the <tt>AntialiasingManager</tt> the developer could activate the
|
||||
* antialiasing mechanism when painting. The method that do the job is
|
||||
* the <code>activateAntialiasing</code> method. It takes a <tt>Graphics</tt>
|
||||
* object and activates the antialiasing for it.
|
||||
*
|
||||
* @author Yana Stamcheva
|
||||
*/
|
||||
public class AntialiasingManager {
|
||||
|
||||
/**
|
||||
* Activates the antialiasing mechanism for the given <tt>Graphics</tt>
|
||||
* object.
|
||||
* @param g The <tt>Graphics</tt> object.
|
||||
*/
|
||||
public static void activateAntialiasing(Graphics g) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.plugin.extendedcallhistorysearch;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* The <tt>CallList</tt> is the component that contains history call records.
|
||||
*
|
||||
* @author Yana Stamcheva
|
||||
*/
|
||||
public class CallList
|
||||
extends JList
|
||||
implements MouseListener
|
||||
{
|
||||
public CallList()
|
||||
{
|
||||
this.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
|
||||
|
||||
this.getSelectionModel().setSelectionMode(
|
||||
ListSelectionModel.SINGLE_SELECTION);
|
||||
|
||||
this.setCellRenderer(new CallListCellRenderer());
|
||||
|
||||
this.setModel(new CallListModel());
|
||||
|
||||
this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
|
||||
this.addMouseListener(this);
|
||||
}
|
||||
|
||||
public void addItem(Object item)
|
||||
{
|
||||
((CallListModel)this.getModel()).addElement(item);
|
||||
}
|
||||
|
||||
public void addItem(Object item, int index)
|
||||
{
|
||||
((CallListModel)this.getModel()).addElement(index, item);
|
||||
}
|
||||
|
||||
public void removeAll()
|
||||
{
|
||||
((CallListModel)this.getModel()).removeAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes or opens a group of calls.
|
||||
*/
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.getClickCount() > 1) {
|
||||
|
||||
CallListModel listModel = (CallListModel) this.getModel();
|
||||
|
||||
Object element = listModel.getElementAt(this.getSelectedIndex());
|
||||
|
||||
if (element instanceof String) {
|
||||
if (listModel.isDateClosed(element)) {
|
||||
listModel.openDate(element);
|
||||
} else {
|
||||
listModel.closeDate(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void mouseEntered(MouseEvent e)
|
||||
{}
|
||||
|
||||
public void mouseExited(MouseEvent e)
|
||||
{}
|
||||
|
||||
public void mousePressed(MouseEvent e)
|
||||
{}
|
||||
|
||||
public void mouseReleased(MouseEvent e)
|
||||
{}
|
||||
}
|
||||
@ -0,0 +1,211 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
|
||||
package net.java.sip.communicator.plugin.extendedcallhistorysearch;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* The <tt>ContactListCellRenderer</tt> is the custom cell renderer used in
|
||||
* the SIP-Communicator's <tt>ContactList</tt>. It extends JPanel instead of
|
||||
* JLabel, which allows adding different buttons and icons to the contact cell.
|
||||
* The cell border and background are repainted.
|
||||
*
|
||||
* @author Yana Stamcheva
|
||||
*/
|
||||
public class CallListCellRenderer
|
||||
extends JPanel
|
||||
implements ListCellRenderer
|
||||
{
|
||||
|
||||
private JPanel dataPanel = new JPanel(new BorderLayout());
|
||||
|
||||
private JLabel nameLabel = new JLabel();
|
||||
|
||||
private JPanel timePanel = new JPanel(new BorderLayout(8, 0));
|
||||
|
||||
private JLabel timeLabel = new JLabel();
|
||||
|
||||
private JLabel durationLabel = new JLabel();
|
||||
|
||||
private JLabel iconLabel = new JLabel();
|
||||
|
||||
private Icon incomingIcon = Resources.getImage("incomingCall");
|
||||
|
||||
private Icon outgoingIcon = Resources.getImage("outgoingCall");
|
||||
|
||||
private boolean isSelected = false;
|
||||
|
||||
private boolean isLeaf = true;
|
||||
|
||||
private String direction;
|
||||
|
||||
/**
|
||||
* Initialize the panel containing the node.
|
||||
*/
|
||||
public CallListCellRenderer()
|
||||
{
|
||||
|
||||
super(new BorderLayout(5, 5));
|
||||
|
||||
this.setBackground(Color.WHITE);
|
||||
|
||||
this.setOpaque(true);
|
||||
|
||||
this.dataPanel.setOpaque(false);
|
||||
|
||||
this.timePanel.setOpaque(false);
|
||||
|
||||
this.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
|
||||
|
||||
this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
|
||||
this.nameLabel.setIconTextGap(2);
|
||||
|
||||
this.nameLabel.setFont(this.getFont().deriveFont(Font.BOLD));
|
||||
|
||||
this.dataPanel.add(nameLabel, BorderLayout.WEST);
|
||||
|
||||
this.add(dataPanel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the <tt>ListCellRenderer</tt> method.
|
||||
*
|
||||
* Returns this panel that has been configured to display the meta contact
|
||||
* and meta contact group cells.
|
||||
*/
|
||||
public Component getListCellRendererComponent(JList list, Object value,
|
||||
int index, boolean isSelected, boolean cellHasFocus)
|
||||
{
|
||||
|
||||
this.dataPanel.remove(timePanel);
|
||||
this.dataPanel.remove(timeLabel);
|
||||
this.dataPanel.remove(durationLabel);
|
||||
this.remove(iconLabel);
|
||||
|
||||
if (value instanceof GuiCallParticipantRecord)
|
||||
{
|
||||
|
||||
GuiCallParticipantRecord participant = (GuiCallParticipantRecord) value;
|
||||
|
||||
this.direction = participant.getDirection();
|
||||
|
||||
if (direction.equals(GuiCallParticipantRecord.INCOMING_CALL))
|
||||
iconLabel.setIcon(incomingIcon);
|
||||
else
|
||||
iconLabel.setIcon(outgoingIcon);
|
||||
|
||||
this.nameLabel.setText(participant.getParticipantName());
|
||||
|
||||
this.timeLabel.setText(Resources.getString("at") + " "
|
||||
+ GuiUtils.formatTime(participant.getStartTime()));
|
||||
|
||||
this.durationLabel.setText(Resources.getString("duration") + " "
|
||||
+ GuiUtils.formatTime(participant.getCallTime()));
|
||||
|
||||
// this.nameLabel.setIcon(listModel
|
||||
// .getMetaContactStatusIcon(contactItem));
|
||||
|
||||
this.timePanel.add(timeLabel, BorderLayout.WEST);
|
||||
this.timePanel.add(durationLabel, BorderLayout.EAST);
|
||||
this.dataPanel.add(timePanel, BorderLayout.EAST);
|
||||
|
||||
this.add(iconLabel, BorderLayout.WEST);
|
||||
|
||||
this.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
|
||||
|
||||
// We should set the bounds of the cell explicitely in order to
|
||||
// make getComponentAt work properly.
|
||||
this.setBounds(0, 0, list.getWidth() - 2, 25);
|
||||
|
||||
this.isLeaf = true;
|
||||
}
|
||||
else if (value instanceof String)
|
||||
{
|
||||
|
||||
String dateString = (String) value;
|
||||
|
||||
this.nameLabel.setText(dateString);
|
||||
|
||||
this.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
|
||||
|
||||
// We should set the bounds of the cell explicitely in order to
|
||||
// make getComponentAt work properly.
|
||||
this.setBounds(0, 0, list.getWidth() - 2, 20);
|
||||
|
||||
this.isLeaf = false;
|
||||
}
|
||||
|
||||
this.isSelected = isSelected;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paint a background for all groups and a round blue border and background
|
||||
* when a cell is selected.
|
||||
*/
|
||||
public void paintComponent(Graphics g)
|
||||
{
|
||||
super.paintComponent(g);
|
||||
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
|
||||
AntialiasingManager.activateAntialiasing(g2);
|
||||
|
||||
if (!this.isLeaf)
|
||||
{
|
||||
|
||||
GradientPaint p = new GradientPaint(0, 0,
|
||||
Constants.BLUE_GRAY_BORDER_COLOR, this.getWidth(), this
|
||||
.getHeight(), Constants.MOVER_END_COLOR);
|
||||
|
||||
g2.setPaint(p);
|
||||
g2.fillRoundRect(1, 1, this.getWidth(), this.getHeight() - 1, 7, 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (direction.equals(GuiCallParticipantRecord.INCOMING_CALL))
|
||||
{
|
||||
|
||||
GradientPaint p = new GradientPaint(0, 0,
|
||||
Constants.HISTORY_IN_CALL_COLOR, this.getWidth(), this
|
||||
.getHeight(), Constants.MOVER_END_COLOR);
|
||||
|
||||
g2.setPaint(p);
|
||||
g2.fillRoundRect(1, 1, this.getWidth(), this.getHeight() - 1,
|
||||
7, 7);
|
||||
}
|
||||
else if (direction.equals(GuiCallParticipantRecord.OUTGOING_CALL))
|
||||
{
|
||||
|
||||
GradientPaint p = new GradientPaint(0, 0,
|
||||
Constants.HISTORY_OUT_CALL_COLOR, this.getWidth(), this
|
||||
.getHeight(), Constants.MOVER_END_COLOR);
|
||||
|
||||
g2.setPaint(p);
|
||||
g2.fillRoundRect(1, 1, this.getWidth(), this.getHeight() - 1,
|
||||
7, 7);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.isSelected)
|
||||
{
|
||||
|
||||
g2.setColor(Constants.SELECTED_END_COLOR);
|
||||
g2.fillRoundRect(1, 0, this.getWidth(), this.getHeight(), 7, 7);
|
||||
|
||||
g2.setColor(Constants.BLUE_GRAY_BORDER_DARKER_COLOR);
|
||||
g2.setStroke(new BasicStroke(1.5f));
|
||||
g2.drawRoundRect(1, 0, this.getWidth() - 2, this.getHeight() - 1,
|
||||
7, 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.plugin.extendedcallhistorysearch;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* The data model of the Call list.
|
||||
*
|
||||
* @author Yana Stamcheva
|
||||
*/
|
||||
public class CallListModel extends AbstractListModel
|
||||
{
|
||||
private LinkedList callList = new LinkedList();
|
||||
|
||||
private Hashtable closedDates = new Hashtable();
|
||||
|
||||
/**
|
||||
* Closes the given date by hiding all containing calls.
|
||||
*
|
||||
* @param date The date to close.
|
||||
*/
|
||||
public void closeDate(Object date)
|
||||
{
|
||||
int startIndex = this.indexOf(date);
|
||||
int endIndex = startIndex;
|
||||
int currentSize = getSize();
|
||||
Collection c = new ArrayList();
|
||||
|
||||
for(int i = startIndex + 1; i < currentSize; i ++) {
|
||||
Object o = this.getElementAt(i);
|
||||
|
||||
if(o instanceof GuiCallParticipantRecord) {
|
||||
this.closedDates.put(o, date);
|
||||
c.add(o);
|
||||
endIndex++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
removeAll(c);
|
||||
fireIntervalRemoved(this, startIndex, endIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the given date by showing all containing calls.
|
||||
*
|
||||
* @param date The date to open.
|
||||
*/
|
||||
public void openDate(Object date)
|
||||
{
|
||||
int startIndex = this.indexOf(date);
|
||||
int endIndex = startIndex;
|
||||
Hashtable closedDatesCopy = (Hashtable)closedDates.clone();
|
||||
|
||||
if(closedDatesCopy.containsValue(date)) {
|
||||
Iterator dates = closedDatesCopy.entrySet().iterator();
|
||||
|
||||
while(dates.hasNext()) {
|
||||
Map.Entry entry = (Map.Entry)dates.next();
|
||||
Object callRecord = entry.getKey();
|
||||
Object callDate = entry.getValue();
|
||||
|
||||
if(callDate.equals(date)) {
|
||||
endIndex++;
|
||||
closedDates.remove(callRecord);
|
||||
this.addElement(endIndex, callRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
fireIntervalAdded(this, startIndex, endIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given date is closed.
|
||||
*
|
||||
* @param date The date to check.
|
||||
* @return True if the date is closed, false - otherwise.
|
||||
*/
|
||||
public boolean isDateClosed(Object date) {
|
||||
if (this.closedDates.containsValue(date))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getSize()
|
||||
{
|
||||
return callList.size();
|
||||
}
|
||||
|
||||
public Object getElementAt(int index)
|
||||
{
|
||||
if (index>=0)
|
||||
return callList.get(index);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addElement(Object item)
|
||||
{
|
||||
synchronized (callList) {
|
||||
this.callList.add(item);
|
||||
|
||||
int index = callList.indexOf(item);
|
||||
fireIntervalAdded(this, index, index);
|
||||
}
|
||||
}
|
||||
|
||||
public void addElement(int index, Object item)
|
||||
{
|
||||
synchronized (callList) {
|
||||
this.callList.add(index, item);
|
||||
fireIntervalAdded(this, index, index);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeElement(Object item)
|
||||
{
|
||||
synchronized (callList) {
|
||||
this.callList.remove(item);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAll(Collection c)
|
||||
{
|
||||
synchronized (callList) {
|
||||
callList.removeAll(c);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAll()
|
||||
{
|
||||
int currentSize = getSize();
|
||||
|
||||
while(callList.size() > 0) {
|
||||
synchronized (callList) {
|
||||
callList.removeLast();
|
||||
}
|
||||
}
|
||||
fireIntervalRemoved(this, 0, currentSize);
|
||||
}
|
||||
|
||||
public int indexOf(Object item)
|
||||
{
|
||||
synchronized (callList) {
|
||||
return callList.indexOf(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
|
||||
package net.java.sip.communicator.plugin.extendedcallhistorysearch;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import net.java.sip.communicator.util.*;
|
||||
|
||||
/**
|
||||
* All look and feel related constants are stored here.
|
||||
*
|
||||
* @author Yana Stamcheva
|
||||
*/
|
||||
|
||||
public class Constants {
|
||||
|
||||
private static Logger logger = Logger.getLogger(Constants.class);
|
||||
|
||||
/*
|
||||
* ===================================================================
|
||||
* ---------------------- CALLTYPE CONSTANTS -------------------------
|
||||
* ===================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* The incoming call flag.
|
||||
*/
|
||||
public static final int INCOMING_CALL = 1;
|
||||
|
||||
/**
|
||||
* The outgoing call flag.
|
||||
*/
|
||||
public static final int OUTGOING_CALL = 2;
|
||||
|
||||
/**
|
||||
* The Incoming & outcoming flag.
|
||||
*/
|
||||
public static final int INOUT_CALL = 3;
|
||||
|
||||
/*
|
||||
* ======================================================================
|
||||
* -------------------- FONTS AND COLOR CONSTANTS ------------------------
|
||||
* ======================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* The color used to paint the background of an incoming call history
|
||||
* record.
|
||||
*/
|
||||
public static final Color HISTORY_DATE_COLOR
|
||||
= new Color(255, 201, 102);
|
||||
|
||||
/**
|
||||
* The color used to paint the background of an incoming call history
|
||||
* record.
|
||||
*/
|
||||
public static final Color HISTORY_IN_CALL_COLOR
|
||||
= new Color(249, 255, 197);
|
||||
|
||||
/**
|
||||
* The color used to paint the background of an outgoing call history
|
||||
* record.
|
||||
*/
|
||||
public static final Color HISTORY_OUT_CALL_COLOR
|
||||
= new Color(243, 244, 247);
|
||||
|
||||
|
||||
/**
|
||||
* The end color used to paint a gradient selected background of some
|
||||
* components.
|
||||
*/
|
||||
public static final Color SELECTED_END_COLOR
|
||||
= new Color(209, 212, 225);
|
||||
|
||||
/**
|
||||
* The start color used to paint a gradient mouse over background of some
|
||||
* components.
|
||||
*/
|
||||
public static final Color MOVER_START_COLOR = new Color(230,
|
||||
230, 230);
|
||||
|
||||
/**
|
||||
* The end color used to paint a gradient mouse over background of some
|
||||
* components.
|
||||
*/
|
||||
public static final Color MOVER_END_COLOR = new Color(255,
|
||||
255, 255);
|
||||
|
||||
/**
|
||||
* Gray color used to paint some borders, like the button border for
|
||||
* example.
|
||||
*/
|
||||
public static final Color GRAY_COLOR = new Color(154, 154,
|
||||
154);
|
||||
|
||||
/**
|
||||
* A color between blue and gray used to paint some borders.
|
||||
*/
|
||||
public static final Color BLUE_GRAY_BORDER_COLOR = new Color(142, 160, 188);
|
||||
|
||||
/**
|
||||
* A color between blue and gray (darker than the other one), used to paint
|
||||
* some borders.
|
||||
*/
|
||||
public static final Color BLUE_GRAY_BORDER_DARKER_COLOR = new Color(131, 149,
|
||||
178);
|
||||
|
||||
|
||||
/*
|
||||
* ======================================================================
|
||||
* --------------------------- FONT CONSTANTS ---------------------------
|
||||
* ======================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* The name of the font used in this ui implementation.
|
||||
*/
|
||||
public static final String FONT_NAME = "Verdana";
|
||||
|
||||
/**
|
||||
* The size of the font used in this ui implementation.
|
||||
*/
|
||||
public static final String FONT_SIZE = "12";
|
||||
|
||||
/**
|
||||
* The default <tt>Font</tt> object used through this ui implementation.
|
||||
*/
|
||||
public static final Font FONT = new Font(Constants.FONT_NAME, Font.PLAIN,
|
||||
new Integer(Constants.FONT_SIZE).intValue());
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
|
||||
package net.java.sip.communicator.plugin.extendedcallhistorysearch;
|
||||
|
||||
import net.java.sip.communicator.service.callhistory.*;
|
||||
import net.java.sip.communicator.service.gui.*;
|
||||
|
||||
import org.osgi.framework.*;
|
||||
|
||||
/**
|
||||
* Call History Search PlugIn Activator
|
||||
*
|
||||
* @author Bourdon Maxime & Meyer Thomas
|
||||
*/
|
||||
public class ExtendedCallHistorySearchActivator
|
||||
implements BundleActivator
|
||||
{
|
||||
private static BundleContext context;
|
||||
|
||||
public void start(BundleContext bc) throws Exception
|
||||
{
|
||||
context = bc;
|
||||
ServiceReference uiServiceRef = bc.getServiceReference(
|
||||
UIService.class.getName());
|
||||
|
||||
UIService uiService = (UIService) bc.getService(uiServiceRef);
|
||||
|
||||
if (uiService.isContainerSupported(UIService.CONTAINER_TOOLS_MENU))
|
||||
{
|
||||
ExtendedCallHistorySearchItem extendedSearch
|
||||
= new ExtendedCallHistorySearchItem();
|
||||
|
||||
uiService.addComponent(UIService.CONTAINER_TOOLS_MENU,
|
||||
extendedSearch);
|
||||
}
|
||||
}
|
||||
|
||||
public void stop(BundleContext bc) throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of the <tt>CallHistoryService</tt>.
|
||||
*/
|
||||
public static CallHistoryService getCallHistoryService()
|
||||
{
|
||||
ServiceReference callHistoryServiceRef = context
|
||||
.getServiceReference(CallHistoryService.class.getName());
|
||||
|
||||
CallHistoryService callHistoryService = (CallHistoryService) context
|
||||
.getService(callHistoryServiceRef);
|
||||
|
||||
return callHistoryService;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,477 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
|
||||
package net.java.sip.communicator.plugin.extendedcallhistorysearch;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import net.java.sip.communicator.service.callhistory.*;
|
||||
|
||||
import com.toedter.calendar.*;
|
||||
|
||||
/**
|
||||
* The <tt>ExtendedCallHistorySearchDialog</tt> allows to search in call
|
||||
* history records, by specifying a period, or a call participant name, or type
|
||||
* of the call (incoming or outgoing).
|
||||
*
|
||||
* @author Maxime Bourdon & Thomas Meyer
|
||||
*/
|
||||
public class ExtendedCallHistorySearchDialog
|
||||
extends JDialog
|
||||
implements ActionListener,
|
||||
ItemListener
|
||||
{
|
||||
/* PANEL */
|
||||
private JPanel mainSearchPanel = new JPanel(new BorderLayout());
|
||||
|
||||
private JPanel mainPanel = new JPanel(new BorderLayout(3, 1));
|
||||
|
||||
private JPanel searchPanel = new JPanel(new GridBagLayout());
|
||||
|
||||
private JPanel callTypePanel = new JPanel(new GridBagLayout());
|
||||
|
||||
private JPanel callListResultPanel = new JPanel(new BorderLayout());
|
||||
|
||||
/* BUTTON */
|
||||
private JButton searchButton = new JButton(Resources.getString("search"),
|
||||
Resources.getImage("searchIcon"));
|
||||
|
||||
/* TEXT FIELD */
|
||||
private JTextField contactNameField = new JTextField();
|
||||
|
||||
/* LABEL */
|
||||
private JLabel contactNameLabel = new JLabel(Resources
|
||||
.getString("contactName") + ": ");
|
||||
|
||||
private JLabel sinceDateLabel
|
||||
= new JLabel(Resources.getString("since") + ": ");
|
||||
|
||||
private JLabel untilDateLabel
|
||||
= new JLabel(Resources.getString("until") + ": ");
|
||||
|
||||
private JLabel callTypeLabel
|
||||
= new JLabel(Resources.getString("callType") + ": ");
|
||||
|
||||
/* CHECKBOX */
|
||||
private JCheckBox inCheckBox = new JCheckBox(Resources
|
||||
.getString("incoming"), true);
|
||||
|
||||
private JCheckBox outCheckBox = new JCheckBox(Resources
|
||||
.getString("outgoing"), true);
|
||||
|
||||
/* SCROLL PANE */
|
||||
private JScrollPane scrollPane = new JScrollPane();
|
||||
|
||||
/* contraint grid */
|
||||
private GridBagConstraints constraintsGRbag = new GridBagConstraints();
|
||||
|
||||
Collection participants = null;
|
||||
|
||||
private CallList callList = new CallList();
|
||||
|
||||
/* Service */
|
||||
CallHistoryService callAccessService;
|
||||
|
||||
private Date lastDateFromHistory = null;
|
||||
|
||||
private Collection callListCollection;
|
||||
|
||||
private JDateChooser untilDC
|
||||
= new JDateChooser("dd/MM/yyyy", "##/##/####", ' ');
|
||||
|
||||
private JDateChooser sinceDC
|
||||
= new JDateChooser("dd/MM/yyyy", "##/##/####", ' ');
|
||||
|
||||
private int direction;
|
||||
|
||||
/**
|
||||
* Creates a new instance of <tt>ExtendedCallHistorySearchDialog</tt>.
|
||||
*/
|
||||
public ExtendedCallHistorySearchDialog()
|
||||
{
|
||||
this.mainPanel.setPreferredSize(new Dimension(650, 550));
|
||||
|
||||
this.setTitle(Resources.getString("advancedCallHistorySearch"));
|
||||
|
||||
this.initPanels();
|
||||
|
||||
this.initDateChooser();
|
||||
|
||||
this.searchPanel.setBorder(BorderFactory.createCompoundBorder(
|
||||
BorderFactory.createTitledBorder("Search"), BorderFactory
|
||||
.createEmptyBorder(5, 5, 5, 5)));
|
||||
|
||||
this.callTypePanel.setBorder(BorderFactory.createCompoundBorder(
|
||||
BorderFactory.createTitledBorder(""), BorderFactory
|
||||
.createEmptyBorder(5, 5, 5, 5)));
|
||||
|
||||
this.callListResultPanel.setBorder(BorderFactory.createCompoundBorder(
|
||||
BorderFactory.createTitledBorder(""), BorderFactory
|
||||
.createEmptyBorder(5, 5, 5, 5)));
|
||||
|
||||
this.getContentPane().add(mainPanel);
|
||||
this.pack();
|
||||
|
||||
/* action listener */
|
||||
searchButton.addActionListener(this);
|
||||
inCheckBox.addItemListener(this);
|
||||
outCheckBox.addItemListener(this);
|
||||
|
||||
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all calls from history and shows them in this dialog.
|
||||
*/
|
||||
public void loadHistoryCalls()
|
||||
{
|
||||
/* get the call list collection */
|
||||
callAccessService = ExtendedCallHistorySearchActivator
|
||||
.getCallHistoryService();
|
||||
callListCollection = callAccessService.findByEndDate(new Date());
|
||||
loadTableRecords(
|
||||
callListCollection, Constants.INOUT_CALL, null, new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the "until" date field to the current date.
|
||||
*/
|
||||
private void initDateChooser()
|
||||
{
|
||||
untilDC.getJCalendar().setWeekOfYearVisible(false);
|
||||
untilDC.getJCalendar().setDate(new Date());
|
||||
sinceDC.getJCalendar().setWeekOfYearVisible(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init panels display.
|
||||
*/
|
||||
private void initPanels()
|
||||
{
|
||||
this.getRootPane().setDefaultButton(searchButton);
|
||||
|
||||
this.mainSearchPanel.add(searchPanel, BorderLayout.NORTH);
|
||||
this.mainSearchPanel.add(callTypePanel, BorderLayout.CENTER);
|
||||
|
||||
this.mainPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
|
||||
this.mainPanel.add(mainSearchPanel, BorderLayout.NORTH);
|
||||
this.mainPanel.add(callListResultPanel, BorderLayout.CENTER);
|
||||
|
||||
/* SEARCH PANEL */
|
||||
constraintsGRbag.anchor = GridBagConstraints.WEST;
|
||||
constraintsGRbag.insets = new Insets(5, 5, 5, 5);
|
||||
constraintsGRbag.gridwidth = 1;
|
||||
constraintsGRbag.fill = GridBagConstraints.NONE;
|
||||
this.searchPanel.add(contactNameLabel, constraintsGRbag);
|
||||
|
||||
constraintsGRbag.gridwidth = GridBagConstraints.REMAINDER;
|
||||
constraintsGRbag.fill = GridBagConstraints.HORIZONTAL;
|
||||
constraintsGRbag.weightx = 1.0;
|
||||
constraintsGRbag.gridx = GridBagConstraints.RELATIVE;
|
||||
this.searchPanel.add(contactNameField, constraintsGRbag);
|
||||
|
||||
/* DATE */
|
||||
constraintsGRbag.anchor = GridBagConstraints.WEST;
|
||||
constraintsGRbag.gridwidth = 1;
|
||||
constraintsGRbag.gridy = 2;
|
||||
constraintsGRbag.fill = GridBagConstraints.NONE;
|
||||
this.searchPanel.add(sinceDateLabel, constraintsGRbag);
|
||||
|
||||
constraintsGRbag.gridwidth = GridBagConstraints.RELATIVE;
|
||||
constraintsGRbag.fill = GridBagConstraints.HORIZONTAL;
|
||||
constraintsGRbag.weightx = 1.0;
|
||||
this.searchPanel.add(sinceDC, constraintsGRbag);
|
||||
|
||||
constraintsGRbag.gridy = 3;
|
||||
constraintsGRbag.gridwidth = 1;
|
||||
constraintsGRbag.fill = GridBagConstraints.NONE;
|
||||
this.searchPanel.add(untilDateLabel, constraintsGRbag);
|
||||
|
||||
constraintsGRbag.fill = GridBagConstraints.HORIZONTAL;
|
||||
this.searchPanel.add(untilDC, constraintsGRbag);
|
||||
|
||||
/* BUTTON */
|
||||
constraintsGRbag.gridy = 4;
|
||||
constraintsGRbag.gridx = 3;
|
||||
constraintsGRbag.fill = GridBagConstraints.NONE;
|
||||
constraintsGRbag.anchor = GridBagConstraints.EAST;
|
||||
this.searchPanel.add(searchButton, constraintsGRbag);
|
||||
|
||||
/* CALL TYPE */
|
||||
constraintsGRbag.anchor = GridBagConstraints.WEST;
|
||||
constraintsGRbag.insets = new Insets(5, 5, 5, 5);
|
||||
constraintsGRbag.gridwidth = 1;
|
||||
constraintsGRbag.gridx = 1;
|
||||
constraintsGRbag.gridy = 1;
|
||||
this.callTypePanel.add(callTypeLabel, constraintsGRbag);
|
||||
constraintsGRbag.gridx = 2;
|
||||
this.callTypePanel.add(inCheckBox, constraintsGRbag);
|
||||
constraintsGRbag.gridx = 3;
|
||||
this.callTypePanel.add(outCheckBox, constraintsGRbag);
|
||||
|
||||
/* CALL LIST PANEL */
|
||||
this.scrollPane.getViewport().add(callList);
|
||||
this.callListResultPanel.add(scrollPane, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the appropriate history calls when user clicks on the search
|
||||
* button.
|
||||
*/
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
JButton sourceButton = (JButton) e.getSource();
|
||||
|
||||
if (sourceButton.equals(searchButton))
|
||||
{
|
||||
/* update the callList */
|
||||
new Thread()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
callListCollection = callAccessService
|
||||
.findByEndDate(new Date());
|
||||
|
||||
if (inCheckBox.isSelected() && outCheckBox.isSelected())
|
||||
{
|
||||
direction = Constants.INOUT_CALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inCheckBox.isSelected())
|
||||
direction = Constants.INCOMING_CALL;
|
||||
else
|
||||
{
|
||||
if (outCheckBox.isSelected())
|
||||
direction = Constants.OUTGOING_CALL;
|
||||
else
|
||||
direction = Constants.INOUT_CALL;
|
||||
}
|
||||
}
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
loadTableRecords(callListCollection, direction,
|
||||
sinceDC.getDate(), untilDC.getDate());
|
||||
}
|
||||
});
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove or add calls to the list of calls depending on the state of
|
||||
* incoming and outgoing checkboxes.
|
||||
*/
|
||||
public void itemStateChanged(ItemEvent e)
|
||||
{
|
||||
JCheckBox sourceCheckBox = (JCheckBox) e.getSource();
|
||||
|
||||
/* Incoming checkbox */
|
||||
if (sourceCheckBox.equals(inCheckBox)
|
||||
|| sourceCheckBox.equals(outCheckBox))
|
||||
{
|
||||
/* INCOMING box Checked */
|
||||
if (inCheckBox.isSelected())
|
||||
{
|
||||
/* OUTCOMING box checked */
|
||||
if (outCheckBox.isSelected() == true)
|
||||
{
|
||||
loadTableRecords(callListCollection,
|
||||
Constants.INOUT_CALL,
|
||||
sinceDC.getDate(), untilDC.getDate());
|
||||
}
|
||||
// only incoming is checked
|
||||
else
|
||||
{
|
||||
loadTableRecords(callListCollection,
|
||||
Constants.INCOMING_CALL,
|
||||
sinceDC.getDate(), untilDC.getDate());
|
||||
}
|
||||
}
|
||||
/* check the OUTCOMING box */
|
||||
else
|
||||
{
|
||||
// checked
|
||||
if (outCheckBox.isSelected() == true)
|
||||
{
|
||||
loadTableRecords(callListCollection,
|
||||
Constants.OUTGOING_CALL,
|
||||
sinceDC.getDate(), untilDC.getDate());
|
||||
}
|
||||
/* both are unchecked */
|
||||
else
|
||||
loadTableRecords(callListCollection,
|
||||
Constants.INOUT_CALL,
|
||||
sinceDC.getDate(), untilDC.getDate());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String processDate(Date date)
|
||||
{
|
||||
String resultString;
|
||||
long currentDate = System.currentTimeMillis();
|
||||
|
||||
if (GuiUtils.compareDates(date, new Date(currentDate)) == 0)
|
||||
{
|
||||
|
||||
resultString = Resources.getString("today");
|
||||
}
|
||||
else
|
||||
{
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.setTime(date);
|
||||
|
||||
resultString = GuiUtils.formatDate(date);
|
||||
}
|
||||
|
||||
return resultString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the callRecord direction equals the direction wanted by the user
|
||||
*
|
||||
* @param callType integer value (incoming = 1, outgoing = 2, in/out = 3)
|
||||
* @param callrecord A Callrecord
|
||||
* @return A string containing the callRecord direction if it equals the
|
||||
* callType Call, null if not
|
||||
*/
|
||||
private String checkCallType(int callType, CallRecord callRecord)
|
||||
{
|
||||
String direction = null;
|
||||
|
||||
// in
|
||||
if (callRecord.getDirection().equals(CallRecord.IN)
|
||||
&& ((callType == Constants.INCOMING_CALL)
|
||||
|| callType == Constants.INOUT_CALL))
|
||||
direction = GuiCallParticipantRecord.INCOMING_CALL;
|
||||
// out
|
||||
else if (callRecord.getDirection().equals(CallRecord.OUT)
|
||||
&& (callType == Constants.OUTGOING_CALL
|
||||
|| callType == Constants.INOUT_CALL))
|
||||
direction = GuiCallParticipantRecord.OUTGOING_CALL;
|
||||
|
||||
return direction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if sinceDate <= callStartDate <= beforeDate
|
||||
*
|
||||
* @param callStartDate
|
||||
* @param sinceDate
|
||||
* @param beforeDate
|
||||
* @return true if sinceDate <= callStartDate <= beforeDate false if not
|
||||
*/
|
||||
private boolean checkDate(Date callStartDate, Date sinceDate, Date untilDate)
|
||||
{
|
||||
/* Test callStartDate >= sinceDate */
|
||||
if (sinceDate != null)
|
||||
if (callStartDate.before(sinceDate))
|
||||
return false;
|
||||
|
||||
/* Test callStartDate <= beforeDate */
|
||||
if (untilDate != null)
|
||||
if (callStartDate.after(untilDate))
|
||||
return false;
|
||||
|
||||
/* sinceDate <= callStartDate <= beforeDate */
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the collection of call records in the table.
|
||||
*
|
||||
* @param historyCalls the collection of call records
|
||||
* @param calltype the type of the call - could be incoming or outgoing
|
||||
* @param since the start date of the search
|
||||
* @param before the end date of the search
|
||||
*/
|
||||
private void loadTableRecords(Collection historyCalls, int calltype,
|
||||
Date since, Date before)
|
||||
{
|
||||
boolean addMe = true;
|
||||
lastDateFromHistory = null;
|
||||
callList.removeAll();
|
||||
// callList = new CallList();
|
||||
Iterator lastCalls = historyCalls.iterator();
|
||||
|
||||
while (lastCalls.hasNext())
|
||||
{
|
||||
addMe = true;
|
||||
|
||||
CallRecord callRecord = (CallRecord) lastCalls.next();
|
||||
|
||||
/* DATE Checking */
|
||||
Date callStartDate = callRecord.getStartTime();
|
||||
|
||||
if (checkDate(callStartDate, since, before))
|
||||
{
|
||||
if (lastDateFromHistory == null)
|
||||
{
|
||||
callList.addItem(processDate(callStartDate));
|
||||
lastDateFromHistory = callStartDate;
|
||||
}
|
||||
else
|
||||
{
|
||||
int compareResult = GuiUtils.compareDates(callStartDate,
|
||||
lastDateFromHistory);
|
||||
|
||||
if (compareResult != 0)
|
||||
{
|
||||
callList.addItem(processDate(callStartDate));
|
||||
lastDateFromHistory = callStartDate;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
addMe = false;
|
||||
|
||||
/* PARTICIPANTS Checking */
|
||||
if (addMe)
|
||||
{
|
||||
Iterator participants = callRecord.getParticipantRecords()
|
||||
.iterator();
|
||||
|
||||
while (participants.hasNext() && addMe)
|
||||
{
|
||||
CallParticipantRecord participantRecord
|
||||
= (CallParticipantRecord) participants.next();
|
||||
|
||||
String participantName = participantRecord
|
||||
.getParticipantAddress();
|
||||
|
||||
if (participantName.matches(
|
||||
"(?i).*" + contactNameField.getText() + ".*"))
|
||||
{
|
||||
/* DIRECTION Checking */
|
||||
String direction;
|
||||
direction = checkCallType(calltype, callRecord);
|
||||
|
||||
if (direction != null)
|
||||
callList.addItem(new GuiCallParticipantRecord(
|
||||
participantRecord, direction));
|
||||
else
|
||||
addMe = false;
|
||||
}
|
||||
else
|
||||
addMe = false; // useless
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (callList.getModel().getSize() > 0)
|
||||
callList.addItem(Resources.getString("olderCalls") + "...");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
|
||||
package net.java.sip.communicator.plugin.extendedcallhistorysearch;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* The <tt>ExtendedCallHistorySearchButton</tt> is the button that will be
|
||||
* added in the Call List panel and from which the user would be able to access
|
||||
* the <tt>ExtendCallHistorySearchDialog</tt>.
|
||||
*
|
||||
* @author Bourdon Maxime & Meyer Thomas
|
||||
*/
|
||||
public class ExtendedCallHistorySearchItem
|
||||
extends JMenuItem
|
||||
implements
|
||||
ActionListener
|
||||
{
|
||||
private ExtendedCallHistorySearchDialog callHistorySearchDialog = null;
|
||||
|
||||
/**
|
||||
* Creates an instance of <tt>ExtendedCallHistoryButton</tt>.
|
||||
*/
|
||||
public ExtendedCallHistorySearchItem()
|
||||
{
|
||||
super(Resources.getString("advancedCallHistorySearch"));
|
||||
|
||||
this.setMnemonic(Resources.getMnemonic("advancedCallHistorySearch"));
|
||||
this.addActionListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches the extended call history dialog when user clicks on this button.
|
||||
*/
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
if (callHistorySearchDialog == null)
|
||||
{
|
||||
callHistorySearchDialog = new ExtendedCallHistorySearchDialog();
|
||||
callHistorySearchDialog.setLocation(Toolkit.getDefaultToolkit()
|
||||
.getScreenSize().width
|
||||
/ 2 - callHistorySearchDialog.getWidth() / 2, Toolkit
|
||||
.getDefaultToolkit().getScreenSize().height
|
||||
/ 2 - callHistorySearchDialog.getHeight() / 2);
|
||||
}
|
||||
|
||||
callHistorySearchDialog.loadHistoryCalls();
|
||||
|
||||
callHistorySearchDialog.setVisible(true);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.plugin.extendedcallhistorysearch;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import net.java.sip.communicator.service.callhistory.*;
|
||||
|
||||
/**
|
||||
* The <tt>GuiCallParticipantRecord</tt> is meant to be used in the call history
|
||||
* to represent a history call participant record. It wraps a
|
||||
* <tt>CallParticipant</tt> or a <tt>CallParticipantRecord</tt> object.
|
||||
*
|
||||
* @author Yana Stamcheva
|
||||
*/
|
||||
public class GuiCallParticipantRecord
|
||||
{
|
||||
public static final String INCOMING_CALL = "IncomingCall";
|
||||
|
||||
public static final String OUTGOING_CALL = "OutgoingCall";
|
||||
|
||||
private String direction;
|
||||
|
||||
private String participantName;
|
||||
|
||||
private Date startTime;
|
||||
|
||||
private Date callTime;
|
||||
|
||||
/**
|
||||
* Creates an instance of <tt>GuiCallParticipantRecord</tt> by specifying
|
||||
* the participant name, the call direction (incoming or outgoing), the
|
||||
* time at which the call has started and the duration of the call.
|
||||
*
|
||||
* @param participantName the name of the call participant
|
||||
* @param direction the direction of the call - INCOMING_CALL
|
||||
* or OUTGOING_CALL
|
||||
* @param startTime the time at which the call has started
|
||||
* @param callTime the duration of the call
|
||||
*/
|
||||
public GuiCallParticipantRecord(String participantName,
|
||||
String direction,
|
||||
Date startTime,
|
||||
Date callTime)
|
||||
{
|
||||
this.direction = direction;
|
||||
|
||||
this.participantName = participantName;
|
||||
|
||||
this.startTime = startTime;
|
||||
|
||||
this.callTime = callTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of <tt>GuiCallParticipantRecord</tt> by specifying
|
||||
* the corresponding <tt>CallParticipantRecord</tt>, which gives all the
|
||||
* information for the participant and the call duration.
|
||||
*
|
||||
* @param participantRecord the corresponding <tt>CallParticipantRecord</tt>
|
||||
* @param direction the call direction - INCOMING_CALL or OUTGOING_CALL
|
||||
*/
|
||||
public GuiCallParticipantRecord(CallParticipantRecord participantRecord,
|
||||
String direction)
|
||||
{
|
||||
this.direction = direction;
|
||||
|
||||
this.participantName = participantRecord.getParticipantAddress();
|
||||
|
||||
this.startTime = participantRecord.getStartTime();
|
||||
|
||||
this.callTime = GuiUtils.substractDates(
|
||||
participantRecord.getEndTime(), startTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the call direction - INCOMING_CALL or OUTGOING_CALL.
|
||||
*
|
||||
* @return the call direction - INCOMING_CALL or OUTGOING_CALL.
|
||||
*/
|
||||
public String getDirection()
|
||||
{
|
||||
return direction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the duration of the call.
|
||||
*
|
||||
* @return the duration of the call
|
||||
*/
|
||||
public Date getCallTime()
|
||||
{
|
||||
return callTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the participant.
|
||||
*
|
||||
* @return the name of the participant
|
||||
*/
|
||||
public String getParticipantName()
|
||||
{
|
||||
return participantName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time at which the call has started.
|
||||
*
|
||||
* @return the time at which the call has started
|
||||
*/
|
||||
public Date getStartTime()
|
||||
{
|
||||
return startTime;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
|
||||
package net.java.sip.communicator.plugin.extendedcallhistorysearch;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
|
||||
/**
|
||||
* The <tt>StringUtils</tt> class is used through this ui implementation for
|
||||
* some special operations with strings.
|
||||
*
|
||||
* @author Yana Stamcheva
|
||||
*/
|
||||
public class GuiUtils {
|
||||
|
||||
private static Calendar c1 = Calendar.getInstance();
|
||||
|
||||
private static Calendar c2 = Calendar.getInstance();
|
||||
|
||||
/**
|
||||
* Replaces some chars that are special in a regular expression.
|
||||
* @param text The initial text.
|
||||
* @return the formatted text
|
||||
*/
|
||||
public static String replaceSpecialRegExpChars(String text) {
|
||||
return text.replaceAll("([.()^&$*|])", "\\\\$1");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the width in pixels of a text.
|
||||
* @param c the component where the text is contained
|
||||
* @param text the text to measure
|
||||
* @return the width in pixels of a text.
|
||||
*/
|
||||
public static int getStringWidth(Component c, String text) {
|
||||
return SwingUtilities.computeStringWidth(c
|
||||
.getFontMetrics(Constants.FONT), text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the two dates. The comparison is based only on the day, month
|
||||
* and year values. Returns 0 if the two dates are equals, a value < 0 if
|
||||
* the first date is before the second one and > 0 if the first date is after
|
||||
* the second one.
|
||||
* @param date1 the first date to compare
|
||||
* @param date2 the second date to compare with
|
||||
* @return Returns 0 if the two dates are equals, a value < 0 if
|
||||
* the first date is before the second one and > 0 if the first date is after
|
||||
* the second one
|
||||
*/
|
||||
public static int compareDates(Date date1, Date date2)
|
||||
{
|
||||
c1.setTime(date1);
|
||||
c2.setTime(date2);
|
||||
|
||||
int day1 = c1.get(Calendar.DAY_OF_MONTH);
|
||||
int month1 = c1.get(Calendar.MONTH);
|
||||
int year1 = c1.get(Calendar.YEAR);
|
||||
|
||||
int day2 = c2.get(Calendar.DAY_OF_MONTH);
|
||||
int month2 = c2.get(Calendar.MONTH);
|
||||
int year2 = c2.get(Calendar.YEAR);
|
||||
|
||||
if((day1 == day2)
|
||||
&& (month1 == month2)
|
||||
&& (year1 == year2)) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
else if((day1 < day2)
|
||||
&& (month1 <= month2)
|
||||
&& (year1 <= year2)) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the given date. The result format is the following:
|
||||
* [Month] [Day], [Year]. For example: Dec 24, 2000.
|
||||
* @param date the date to format
|
||||
* @return the formatted date string
|
||||
*/
|
||||
public static String formatDate(Date date)
|
||||
{
|
||||
c1.setTime(date);
|
||||
|
||||
return GuiUtils.processMonth(c1.get(Calendar.MONTH) + 1) + " "
|
||||
+ GuiUtils.formatTime(c1.get(Calendar.DAY_OF_MONTH)) + ", "
|
||||
+ GuiUtils.formatTime(c1.get(Calendar.YEAR));
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the time for the given date. The result format is the following:
|
||||
* [Hour]:[Minute]:[Second]. For example: 12:25:30.
|
||||
* @param date the date to format
|
||||
* @return the formatted hour string
|
||||
*/
|
||||
public static String formatTime(Date date)
|
||||
{
|
||||
c1.setTime(date);
|
||||
|
||||
return GuiUtils.formatTime(c1.get(Calendar.HOUR_OF_DAY)) + ":"
|
||||
+ GuiUtils.formatTime(c1.get(Calendar.MINUTE)) + ":"
|
||||
+ GuiUtils.formatTime(c1.get(Calendar.SECOND)) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Substracts the two dates.
|
||||
* @param date1 the first date argument
|
||||
* @param date2 the second date argument
|
||||
* @return the date resulted from the substracting
|
||||
*/
|
||||
public static Date substractDates(Date date1, Date date2)
|
||||
{
|
||||
long d1 = date1.getTime();
|
||||
long d2 = date2.getTime();
|
||||
long difMil = d1-d2;
|
||||
long milPerDay = 1000*60*60*24;
|
||||
long milPerHour = 1000*60*60;
|
||||
long milPerMin = 1000*60;
|
||||
long milPerSec = 1000;
|
||||
|
||||
long days = difMil / milPerDay;
|
||||
int hour = (int)(( difMil - days*milPerDay ) / milPerHour);
|
||||
int min
|
||||
= (int)(( difMil - days*milPerDay - hour*milPerHour ) / milPerMin);
|
||||
int sec
|
||||
= (int)(( difMil - days*milPerDay - hour*milPerHour - min*milPerMin )
|
||||
/ milPerSec);
|
||||
|
||||
c1.clear();
|
||||
c1.set(Calendar.HOUR, hour);
|
||||
c1.set(Calendar.MINUTE, min);
|
||||
c1.set(Calendar.SECOND, sec);
|
||||
|
||||
return c1.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the month with its abbreviation.
|
||||
* @param month Value from 1 to 12, which indicates the month.
|
||||
* @return the corresponding month abbreviation
|
||||
*/
|
||||
private static String processMonth(int month)
|
||||
{
|
||||
String monthString = "";
|
||||
if(month == 1)
|
||||
monthString = Resources.getString("january");
|
||||
else if(month == 2)
|
||||
monthString = Resources.getString("february");
|
||||
else if(month == 3)
|
||||
monthString = Resources.getString("march");
|
||||
else if(month == 4)
|
||||
monthString = Resources.getString("april");
|
||||
else if(month == 5)
|
||||
monthString = Resources.getString("may");
|
||||
else if(month == 6)
|
||||
monthString = Resources.getString("june");
|
||||
else if(month == 7)
|
||||
monthString = Resources.getString("july");
|
||||
else if(month == 8)
|
||||
monthString = Resources.getString("august");
|
||||
else if(month == 9)
|
||||
monthString = Resources.getString("september");
|
||||
else if(month == 10)
|
||||
monthString = Resources.getString("october");
|
||||
else if(month == 11)
|
||||
monthString = Resources.getString("november");
|
||||
else if(month == 12)
|
||||
monthString = Resources.getString("december");
|
||||
|
||||
return monthString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a 0 in the beginning of one digit numbers.
|
||||
*
|
||||
* @param time The time parameter could be hours, minutes or seconds.
|
||||
* @return The formatted minutes string.
|
||||
*/
|
||||
private static String formatTime(int time)
|
||||
{
|
||||
String timeString = new Integer(time).toString();
|
||||
|
||||
String resultString = "";
|
||||
if (timeString.length() < 2)
|
||||
resultString = resultString.concat("0").concat(timeString);
|
||||
else
|
||||
resultString = timeString;
|
||||
|
||||
return resultString;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
|
||||
package net.java.sip.communicator.plugin.extendedcallhistorysearch;
|
||||
|
||||
import java.awt.image.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.imageio.*;
|
||||
import javax.swing.*;
|
||||
|
||||
import net.java.sip.communicator.util.*;
|
||||
/**
|
||||
* The Messages class manages the access to the internationalization
|
||||
* properties files.
|
||||
* @author Yana Stamcheva
|
||||
*/
|
||||
public class Resources {
|
||||
|
||||
private static Logger log = Logger.getLogger(Resources.class);
|
||||
|
||||
private static final String BUNDLE_NAME
|
||||
= "net.java.sip.communicator.plugin.extendedcallhistorysearch.resources";
|
||||
|
||||
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
|
||||
.getBundle(BUNDLE_NAME);
|
||||
|
||||
/**
|
||||
* Returns an internationalized string corresponding to the given key.
|
||||
* @param key The key of the string.
|
||||
* @return An internationalized string corresponding to the given key.
|
||||
*/
|
||||
public static String getString(String key)
|
||||
{
|
||||
String resourceString;
|
||||
try
|
||||
{
|
||||
resourceString = RESOURCE_BUNDLE.getString(key);
|
||||
|
||||
int mnemonicIndex = resourceString.indexOf('&');
|
||||
|
||||
if(mnemonicIndex > -1)
|
||||
{
|
||||
String firstPart = resourceString.substring(0, mnemonicIndex);
|
||||
String secondPart = resourceString.substring(mnemonicIndex + 1);
|
||||
|
||||
resourceString = firstPart.concat(secondPart);
|
||||
}
|
||||
}
|
||||
catch (MissingResourceException e)
|
||||
{
|
||||
resourceString = '!' + key + '!';
|
||||
}
|
||||
|
||||
return resourceString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an image from a given image identifier.
|
||||
* @param imageID The identifier of the image.
|
||||
* @return The image for the given identifier.
|
||||
*/
|
||||
public static ImageIcon getImage(String imageID) {
|
||||
BufferedImage image = null;
|
||||
|
||||
String path = Resources.getString(imageID);
|
||||
try {
|
||||
image = ImageIO.read(Resources.class.getClassLoader()
|
||||
.getResourceAsStream(path));
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to load image:" + path, e);
|
||||
}
|
||||
|
||||
return new ImageIcon(image);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an internationalized string corresponding to the given key.
|
||||
* @param key The key of the string.
|
||||
* @return An internationalized string corresponding to the given key.
|
||||
*/
|
||||
public static char getMnemonic(String key)
|
||||
{
|
||||
String resourceString;
|
||||
try {
|
||||
resourceString = RESOURCE_BUNDLE.getString(key);
|
||||
|
||||
int mnemonicIndex = resourceString.indexOf('&');
|
||||
|
||||
if(mnemonicIndex > -1)
|
||||
{
|
||||
return resourceString.charAt(mnemonicIndex + 1);
|
||||
}
|
||||
|
||||
}
|
||||
catch (MissingResourceException e)
|
||||
{
|
||||
return '!';
|
||||
}
|
||||
|
||||
return '!';
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an image from a given image identifier.
|
||||
* @param imageID The identifier of the image.
|
||||
* @return The image for the given identifier.
|
||||
*/
|
||||
public static byte[] getImageInBytes(String imageID) {
|
||||
byte[] image = new byte[100000];
|
||||
|
||||
String path = Resources.getString(imageID);
|
||||
try {
|
||||
Resources.class.getClassLoader()
|
||||
.getResourceAsStream(path).read(image);
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to load image:" + path, e);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
Bundle-Activator: net.java.sip.communicator.plugin.extendedcallhistorysearch.ExtendedCallHistorySearchActivator
|
||||
Bundle-Name: Extended Call History Search
|
||||
Bundle-Description: An Extended Call History Search
|
||||
Bundle-Vendor: sip-communicator.org
|
||||
Bundle-Version: 0.0.1
|
||||
Import-Package: org.osgi.framework,
|
||||
net.java.sip.communicator.util,
|
||||
net.java.sip.communicator.service.contactlist,
|
||||
net.java.sip.communicator.service.contactlist.event,
|
||||
net.java.sip.communicator.service.gui,
|
||||
net.java.sip.communicator.service.gui.event,
|
||||
net.java.sip.communicator.service.callhistory,
|
||||
net.java.sip.communicator.service.configuration,
|
||||
javax.swing,
|
||||
javax.swing.event,
|
||||
javax.swing.table,
|
||||
javax.swing.text,
|
||||
javax.accessibility,
|
||||
javax.swing.plaf,
|
||||
javax.swing.plaf.metal,
|
||||
javax.swing.plaf.basic,
|
||||
javax.imageio,
|
||||
javax.swing.filechooser,
|
||||
javax.swing.tree,
|
||||
javax.swing.border
|
||||
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
advancedCallHistorySearch=&Advanced call history search
|
||||
search=Search
|
||||
contactName=Contact Name
|
||||
since=Since
|
||||
until=Until
|
||||
callType=Call Type
|
||||
incoming=Incoming
|
||||
outgoing=Outgoing
|
||||
olderCalls=Older Calls
|
||||
duration=Duration
|
||||
at=at
|
||||
all=all
|
||||
today=Today
|
||||
january=Jan
|
||||
february=Feb
|
||||
march=Mar
|
||||
april=Apr
|
||||
may=May
|
||||
june=Jun
|
||||
july=Jul
|
||||
august=Aug
|
||||
september=Sep
|
||||
october=Oct
|
||||
november=Nov
|
||||
december=Dec
|
||||
|
||||
searchIcon=net/java/sip/communicator/plugin/extendedcallhistorysearch/resources/searchIcon.png
|
||||
historyMenuIcon=net/java/sip/communicator/plugin/extendedcallhistorysearch/resources/history16x16.png
|
||||
incomingCall=net/java/sip/communicator/plugin/extendedcallhistorysearch/resources/incomingCall.png
|
||||
outgoingCall=net/java/sip/communicator/plugin/extendedcallhistorysearch/resources/outgoingCall.png
|
||||
calendarIcon=net/java/sip/communicator/plugin/extendedcallhistorysearch/resources/calendarIcon.png
|
||||
|
After Width: | Height: | Size: 290 B |
|
After Width: | Height: | Size: 971 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 823 B |
Loading…
Reference in new issue