diff --git a/build.xml b/build.xml index 338b101c6..e2d1c150b 100644 --- a/build.xml +++ b/build.xml @@ -743,7 +743,7 @@ - + @@ -751,8 +751,8 @@ - + @@ -852,6 +852,7 @@ bundle-growlnotification,bundle-audionotifier,bundle-plugin-splashscreen, bundle-systray,bundle-browserlauncher,bundle-gibberish, bundle-gibberish-slick,bundle-plugin-gibberishaccregwizz, + bundle-plugin-extended-callhistory-search, bundle-rss,bundle-plugin-rssaccregwizz, bundle-pluginmanager"/> @@ -1545,6 +1546,17 @@ javax.swing.event, javax.swing.border"/> prefix="net/java/sip/communicator/plugin/pluginmanager"/> + + + + + + + + + diff --git a/lib/felix.client.run.properties b/lib/felix.client.run.properties index 0ef41b046..22493d539 100644 --- a/lib/felix.client.run.properties +++ b/lib/felix.client.run.properties @@ -71,8 +71,8 @@ felix.auto.start.50= \ reference:file:sc-bundles/protocol-yahoo.jar \ reference:file:sc-bundles/protocol-gibberish.jar \ reference:file:sc-bundles/netaddr.jar \ - reference:file:sc-bundles/meta-cl.jar \ - reference:file:sc-bundles/protocol-rss.jar + reference:file:sc-bundles/protocol-rss.jar \ + reference:file:sc-bundles/meta-cl.jar felix.auto.start.60= \ reference:file:sc-bundles/history.jar \ @@ -94,8 +94,9 @@ felix.auto.start.60= \ reference:file:sc-bundles/msnaccregwizz.jar \ reference:file:sc-bundles/yahooaccregwizz.jar \ reference:file:sc-bundles/gibberishaccregwizz.jar \ - reference:file:sc-bundles/shutdown.jar \ - reference:file:sc-bundles/rssaccregwizz.jar + reference:file:sc-bundles/extendedcallhistorysearch.jar \ + reference:file:sc-bundles/rssaccregwizz.jar \ + reference:file:sc-bundles/shutdown.jar # Uncomment the following lines if you want to run the architect viewer # bundle. diff --git a/lib/installer-exclude/jcalendar-1.3.2.jar b/lib/installer-exclude/jcalendar-1.3.2.jar new file mode 100644 index 000000000..b5e5a2d82 Binary files /dev/null and b/lib/installer-exclude/jcalendar-1.3.2.jar differ diff --git a/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/AntialiasingManager.java b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/AntialiasingManager.java new file mode 100644 index 000000000..3763b9a2b --- /dev/null +++ b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/AntialiasingManager.java @@ -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 AntialiasingManager the developer could activate the + * antialiasing mechanism when painting. The method that do the job is + * the activateAntialiasing method. It takes a Graphics + * object and activates the antialiasing for it. + * + * @author Yana Stamcheva + */ +public class AntialiasingManager { + + /** + * Activates the antialiasing mechanism for the given Graphics + * object. + * @param g The Graphics object. + */ + public static void activateAntialiasing(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + } +} diff --git a/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/CallList.java b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/CallList.java new file mode 100644 index 000000000..4311ea8fd --- /dev/null +++ b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/CallList.java @@ -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 CallList 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) + {} +} diff --git a/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/CallListCellRenderer.java b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/CallListCellRenderer.java new file mode 100644 index 000000000..c77530fad --- /dev/null +++ b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/CallListCellRenderer.java @@ -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 ContactListCellRenderer is the custom cell renderer used in + * the SIP-Communicator's ContactList. 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 ListCellRenderer 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); + } + } +} diff --git a/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/CallListModel.java b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/CallListModel.java new file mode 100644 index 000000000..4a7d5d936 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/CallListModel.java @@ -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); + } + } +} diff --git a/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/Constants.java b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/Constants.java new file mode 100644 index 000000000..a3295ce58 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/Constants.java @@ -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 Font object used through this ui implementation. + */ + public static final Font FONT = new Font(Constants.FONT_NAME, Font.PLAIN, + new Integer(Constants.FONT_SIZE).intValue()); + + +} diff --git a/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/ExtendedCallHistorySearchActivator.java b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/ExtendedCallHistorySearchActivator.java new file mode 100644 index 000000000..80ccb9753 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/ExtendedCallHistorySearchActivator.java @@ -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 CallHistoryService. + */ + public static CallHistoryService getCallHistoryService() + { + ServiceReference callHistoryServiceRef = context + .getServiceReference(CallHistoryService.class.getName()); + + CallHistoryService callHistoryService = (CallHistoryService) context + .getService(callHistoryServiceRef); + + return callHistoryService; + } + +} diff --git a/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/ExtendedCallHistorySearchDialog.java b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/ExtendedCallHistorySearchDialog.java new file mode 100644 index 000000000..f6ac0f640 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/ExtendedCallHistorySearchDialog.java @@ -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 ExtendedCallHistorySearchDialog 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 ExtendedCallHistorySearchDialog. + */ + 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") + "..."); + } +} diff --git a/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/ExtendedCallHistorySearchItem.java b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/ExtendedCallHistorySearchItem.java new file mode 100644 index 000000000..af097ed7b --- /dev/null +++ b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/ExtendedCallHistorySearchItem.java @@ -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 ExtendedCallHistorySearchButton is the button that will be + * added in the Call List panel and from which the user would be able to access + * the ExtendCallHistorySearchDialog. + * + * @author Bourdon Maxime & Meyer Thomas + */ +public class ExtendedCallHistorySearchItem + extends JMenuItem + implements + ActionListener +{ + private ExtendedCallHistorySearchDialog callHistorySearchDialog = null; + + /** + * Creates an instance of ExtendedCallHistoryButton. + */ + 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); + } +} diff --git a/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/GuiCallParticipantRecord.java b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/GuiCallParticipantRecord.java new file mode 100644 index 000000000..361ef8ced --- /dev/null +++ b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/GuiCallParticipantRecord.java @@ -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 GuiCallParticipantRecord is meant to be used in the call history + * to represent a history call participant record. It wraps a + * CallParticipant or a CallParticipantRecord 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 GuiCallParticipantRecord 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 GuiCallParticipantRecord by specifying + * the corresponding CallParticipantRecord, which gives all the + * information for the participant and the call duration. + * + * @param participantRecord the corresponding CallParticipantRecord + * @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; + } +} diff --git a/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/GuiUtils.java b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/GuiUtils.java new file mode 100644 index 000000000..4b9b90e0f --- /dev/null +++ b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/GuiUtils.java @@ -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 StringUtils 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; + } +} diff --git a/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/Resources.java b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/Resources.java new file mode 100644 index 000000000..5e665afef --- /dev/null +++ b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/Resources.java @@ -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; + } +} diff --git a/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/extendedcallhistorysearch.manifest.mf b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/extendedcallhistorysearch.manifest.mf new file mode 100644 index 000000000..b73a13ff4 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/extendedcallhistorysearch.manifest.mf @@ -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 + + diff --git a/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/resources.properties b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/resources.properties new file mode 100644 index 000000000..017ff86f8 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/resources.properties @@ -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 diff --git a/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/resources/calendarIcon.png b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/resources/calendarIcon.png new file mode 100644 index 000000000..9cc115093 Binary files /dev/null and b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/resources/calendarIcon.png differ diff --git a/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/resources/history16x16.png b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/resources/history16x16.png new file mode 100644 index 000000000..67ba572f5 Binary files /dev/null and b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/resources/history16x16.png differ diff --git a/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/resources/incomingCall.png b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/resources/incomingCall.png new file mode 100644 index 000000000..f50b7058d Binary files /dev/null and b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/resources/incomingCall.png differ diff --git a/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/resources/outgoingCall.png b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/resources/outgoingCall.png new file mode 100644 index 000000000..6b9b53b7a Binary files /dev/null and b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/resources/outgoingCall.png differ diff --git a/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/resources/searchIcon.png b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/resources/searchIcon.png new file mode 100644 index 000000000..4eb16a3f4 Binary files /dev/null and b/src/net/java/sip/communicator/plugin/extendedcallhistorysearch/resources/searchIcon.png differ