diff --git a/build.xml b/build.xml
index 0ff32050b..96f19f8d5 100644
--- a/build.xml
+++ b/build.xml
@@ -1079,7 +1079,7 @@
bundle-globalshortcut,bundle-plugin-msofficecomm,bundle-libjitsi,
bundle-customcontactactions, bundle-phonenumbercontactsource,
bundle-demuxcontactsource, bundle-desktoputil,
- bundle-globaldisplaydetails"/>
+ bundle-globaldisplaydetails,bundle-plugin-propertieseditor"/>
@@ -2941,4 +2941,14 @@ javax.swing.event, javax.swing.border"/>
prefix="net/java/sip/communicator/impl/globaldisplaydetails" />
+
+
+
+
+
+
+
+
diff --git a/lib/felix.client.run.properties b/lib/felix.client.run.properties
index 7514ce040..44871116d 100644
--- a/lib/felix.client.run.properties
+++ b/lib/felix.client.run.properties
@@ -184,7 +184,8 @@ felix.auto.start.67= \
reference:file:sc-bundles/plugin-contactsourceconfig.jar \
reference:file:sc-bundles/plugin-certconfig.jar \
reference:file:sc-bundles/phonenumbercontactsource.jar \
- reference:file:sc-bundles/demuxcontactsource.jar
+ reference:file:sc-bundles/demuxcontactsource.jar \
+ reference:file:sc-bundles/propertieseditor.jar
# Level 68 is for profiler4j. Either don't use it or change the build.xml file
# accordingly.
diff --git a/resources/languages/resources.properties b/resources/languages/resources.properties
index 601863d19..96a10e60a 100644
--- a/resources/languages/resources.properties
+++ b/resources/languages/resources.properties
@@ -512,6 +512,7 @@ service.gui.UNKNOWN=Unknown user
service.gui.UNKNOWN_STATUS=Unknown state
service.gui.UNREGISTERED_MESSAGE=Unable to connect the following account: User name: {0}, Server name: {1}. You are currently offline.
service.gui.USE_PROVISIONING=Use online provisioning
+service.gui.VALUE=Value
service.gui.VIDEO_CALL=&Video call
service.gui.VIA=via
service.gui.VIA_SMS=Via SMS
@@ -1703,6 +1704,17 @@ plugin.certconfig.REVOCATION_OCSP_ENABLED=OCSP (Online Certificate Status Protoc
# Phone number contact source plugin
plugin.phonenumbercontactsource.DISPLAY_NAME=Phone numbers
+# properties editor
+plugin.propertieseditor.TITLE=Property Editor
+plugin.propertieseditor.NEW_PROPERTY_TITLE=Add new property
+plugin.propertieseditor.CHECK_BOX=Show this warning next time
+plugin.propertieseditor.DESCRIPTION=The following button allows modifying Jitsi configuration properties. \
+Changing these advanced settings can be harmful to the stability, security, \
+and performance of this application. You should only continue if you are sure \
+of what you are doing.
+plugin.propertieseditor.IM_AWARE=I am aware of the risks
+plugin.propertieseditor.NEED_RESTART=Note: some properties might need a restart before new settings will take effect.
+
#Thunderbird address book plugin
plugin.thunderbird.CONFIG_FORM_TITLE=Thunderbird
plugin.thunderbird.ENABLED=Enabled
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactSearchFieldUI.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactSearchFieldUI.java
new file mode 100644
index 000000000..256d70e71
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactSearchFieldUI.java
@@ -0,0 +1,98 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.gui.main.contactlist;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+import javax.swing.plaf.*;
+import javax.swing.text.*;
+
+import net.java.sip.communicator.impl.gui.main.call.*;
+import net.java.sip.communicator.plugin.desktoputil.plaf.*;
+import net.java.sip.communicator.util.*;
+import net.java.sip.communicator.util.skin.*;
+
+/**
+ *
+ * @author Marin Dzhigarov
+ */
+public class ContactSearchFieldUI
+ extends SearchFieldUI
+ implements Skinnable
+{
+ /**
+ * Creates a UI for a SearchFieldUI.
+ *
+ * @param c the text field
+ * @return the UI
+ */
+ public static ComponentUI createUI(JComponent c)
+ {
+ return new ContactSearchFieldUI();
+ }
+
+ public ContactSearchFieldUI()
+ {
+ // Indicates if the big call button outside the search is enabled.
+ String callButtonEnabledString
+ = UtilActivator.getResources().getSettingsString(
+ "impl.gui.CALL_BUTTON_ENABLED");
+
+ if ((callButtonEnabledString != null)
+ && (callButtonEnabledString.length() > 0))
+ {
+ // If the outside call button is enabled the call button in this
+ // search field is disabled.
+ isCallButtonEnabled
+ = !Boolean.parseBoolean(callButtonEnabledString);
+ }
+
+ loadSkin();
+ }
+
+ /**
+ * Paints the background of the associated component.
+ *
+ * @param g the Graphics object used for painting
+ */
+ @Override
+ protected void customPaintBackground(Graphics g)
+ {
+ isCallButtonEnabled = CallManager.getTelephonyProviders().size() > 0;
+ super.customPaintBackground(g);
+ }
+
+ /**
+ * Creates a call when the mouse is clicked on the call icon.
+ *
+ * @param ev the mouse event that has prompted us to create the call.
+ */
+ @Override
+ protected void updateCallIcon(MouseEvent ev)
+ {
+ super.updateCallIcon(ev);
+
+
+ if ((ev.getID() == MouseEvent.MOUSE_CLICKED) && isCallIconVisible)
+ {
+ Rectangle callButtonRect = getCallButtonRect();
+ int x = ev.getX();
+ int y = ev.getY();
+
+ if (callButtonRect.contains(x, y))
+ {
+ JTextComponent c = getComponent();
+ String searchText = c.getText();
+
+ if (searchText != null)
+ CallManager.createCall(searchText, c);
+ }
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchField.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchField.java
index 42183c496..090207a94 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchField.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchField.java
@@ -25,6 +25,7 @@
*
* @author Yana Stamcheva
* @author Adam Netocny
+ * @author Marin Dzhigarov
*/
public class SearchField
extends SIPCommTextField
@@ -35,37 +36,38 @@ public class SearchField
/**
* Class id key used in UIDefaults.
*/
- private static final String uiClassID =
- SearchField.class.getName() + "FieldUI";
+ private static final String uiClassID
+ = SearchField.class.getName() + "FieldUI";
/**
* Adds the ui class to UIDefaults.
*/
static
{
- UIManager.getDefaults().put(uiClassID,
- SearchFieldUI.class.getName());
+ UIManager.getDefaults().put(
+ uiClassID,
+ ContactSearchFieldUI.class.getName());
}
/**
- * The main application window.
+ * The contact list on which we apply the filter.
*/
- private final MainFrame mainFrame;
+ private ContactList contactList;
/**
- * The contact list on which we apply the filter.
+ * The current filter query.
*/
- private ContactList contactList;
+ private FilterQuery currentFilterQuery = null;
/**
- * The filter to apply on search.
+ * The main application window.
*/
- private final ContactListSearchFilter searchFilter;
+ private final MainFrame mainFrame;
/**
- * The current filter query.
+ * The filter to apply on search.
*/
- private FilterQuery currentFilterQuery = null;
+ private final ContactListSearchFilter searchFilter;
/**
* Creates the SearchField.
@@ -85,10 +87,11 @@ public SearchField( MainFrame frame,
this.mainFrame = frame;
this.searchFilter = searchFilter;
- if(getUI() instanceof SearchFieldUI)
+ if (getUI() instanceof ContactSearchFieldUI)
{
- ((SearchFieldUI)getUI()).setDeleteButtonEnabled(true);
- ((SearchFieldUI)getUI()).setCallButtonEnabled(isCallButtonEnabled);
+ ((ContactSearchFieldUI) getUI()).setDeleteButtonEnabled(true);
+ ((ContactSearchFieldUI) getUI())
+ .setCallButtonEnabled(isCallButtonEnabled);
}
this.setBorder(null);
@@ -115,28 +118,6 @@ public void actionPerformed(ActionEvent e)
loadSkin();
}
- /**
- * Handles the change when a char has been inserted in the field.
- */
- public void textInserted()
- {
- // Should explicitly check if there's a text, because the default text
- // triggers also an insertUpdate event.
- String filterString = this.getText();
- if (filterString == null || filterString.length() <= 0)
- return;
-
- updateContactListView();
- }
-
- /**
- * Handles the change when a char has been removed from the field.
- */
- public void textRemoved()
- {
- updateContactListView();
- }
-
/**
* Do not need this for the moment.
* @param e the DocumentEvent that notified us
@@ -144,52 +125,6 @@ public void textRemoved()
@Override
public void changedUpdate(DocumentEvent e) {}
- /**
- * Schedules an update if necessary.
- */
- private void updateContactListView()
- {
- String filterString = getText();
-
- boolean isDefaultFilter = false;
-
- searchFilter.setFilterString(filterString.trim());
-
- // First finish the last filter.
- if (currentFilterQuery != null)
- filterQueryFinished(currentFilterQuery, true);
-
- if (filterString != null && filterString.length() > 0)
- {
- currentFilterQuery = contactList.applyFilter(searchFilter);
- }
- else
- {
- currentFilterQuery = contactList.applyDefaultFilter();
- isDefaultFilter = true;
- }
-
- if (currentFilterQuery != null && !currentFilterQuery.isCanceled())
- {
- // If we already have a result here we update the interface.
- // In the case of default filter we don't need to know if the
- // query has succeeded, as event if it isn't we would like to
- // remove the unknown contact view.
- if (isDefaultFilter || currentFilterQuery.isSucceeded())
- enableUnknownContactView(false);
- else
- // Otherwise we will listen for events for changes in status
- // of this query.
- currentFilterQuery.setQueryListener(this);
- }
- else
- {
- // If the query is null or is canceled, we would simply check the
- // contact list content.
- filterQueryFinished(currentFilterQuery, !contactList.isEmpty());
- }
- }
-
/**
* Sets the unknown contact view to the main contact list window.
*
@@ -208,16 +143,6 @@ public void run()
});
}
- /**
- * Sets the contact list, in which the search is performed.
- *
- * @param contactList the contact list in which the search is performed
- */
- public void setContactList(ContactList contactList)
- {
- this.contactList = contactList;
- }
-
/**
* Indicates that the given query has finished with failure, i.e.
* no results for the filter were found.
@@ -231,6 +156,24 @@ public void filterQueryFailed(FilterQuery query)
filterQueryFinished(query, false);
}
+ /**
+ * Performs all needed updates when a filter query has finished.
+ *
+ * @param query the query that has finished
+ * @param hasResults indicates if the query has results
+ */
+ private void filterQueryFinished(FilterQuery query, boolean hasResults)
+ {
+ // If the unknown contact view was previously enabled, but we
+ // have found matching contacts we enter the normal view.
+ enableUnknownContactView(!hasResults);
+
+ if (hasResults)
+ contactList.selectFirstContact();
+
+ query.setQueryListener(null);
+ }
+
/**
* Indicates that the given query has finished with success, i.e.
* the filter has returned results.
@@ -244,15 +187,6 @@ public void filterQuerySucceeded(FilterQuery query)
filterQueryFinished(query, true);
}
- /**
- * Reloads text field UI defs.
- */
- public void loadSkin()
- {
- if(getUI() instanceof SearchFieldUI)
- ((SearchFieldUI)getUI()).loadSkin();
- }
-
/**
* Returns the name of the L&F class that renders this component.
*
@@ -267,20 +201,89 @@ public String getUIClassID()
}
/**
- * Performs all needed updates when a filter query has finished.
+ * Reloads text field UI defs.
+ */
+ public void loadSkin()
+ {
+ if (getUI() instanceof ContactSearchFieldUI)
+ ((ContactSearchFieldUI) getUI()).loadSkin();
+ }
+
+ /**
+ * Sets the contact list, in which the search is performed.
*
- * @param query the query that has finished
- * @param hasResults indicates if the query has results
+ * @param contactList the contact list in which the search is performed
*/
- private void filterQueryFinished(FilterQuery query, boolean hasResults)
+ public void setContactList(ContactList contactList)
{
- // If the unknown contact view was previously enabled, but we
- // have found matching contacts we enter the normal view.
- enableUnknownContactView(!hasResults);
+ this.contactList = contactList;
+ }
- if (hasResults)
- contactList.selectFirstContact();
+ /**
+ * Handles the change when a char has been inserted in the field.
+ */
+ public void textInserted()
+ {
+ // Should explicitly check if there's a text, because the default text
+ // triggers also an insertUpdate event.
+ String filterString = this.getText();
+ if (filterString == null || filterString.length() <= 0)
+ return;
- query.setQueryListener(null);
+ updateContactListView();
+ }
+
+ /**
+ * Handles the change when a char has been removed from the field.
+ */
+ public void textRemoved()
+ {
+ updateContactListView();
+ }
+
+ /**
+ * Schedules an update if necessary.
+ */
+ private void updateContactListView()
+ {
+ String filterString = getText();
+
+ boolean isDefaultFilter = false;
+
+ searchFilter.setFilterString(filterString.trim());
+
+ // First finish the last filter.
+ if (currentFilterQuery != null)
+ filterQueryFinished(currentFilterQuery, true);
+
+ if (filterString != null && filterString.length() > 0)
+ {
+ currentFilterQuery = contactList.applyFilter(searchFilter);
+ }
+ else
+ {
+ currentFilterQuery = contactList.applyDefaultFilter();
+ isDefaultFilter = true;
+ }
+
+ if (currentFilterQuery != null && !currentFilterQuery.isCanceled())
+ {
+ // If we already have a result here we update the interface.
+ // In the case of default filter we don't need to know if the
+ // query has succeeded, as event if it isn't we would like to
+ // remove the unknown contact view.
+ if (isDefaultFilter || currentFilterQuery.isSucceeded())
+ enableUnknownContactView(false);
+ else
+ // Otherwise we will listen for events for changes in status
+ // of this query.
+ currentFilterQuery.setQueryListener(this);
+ }
+ else
+ {
+ // If the query is null or is canceled, we would simply check the
+ // contact list content.
+ filterQueryFinished(currentFilterQuery, !contactList.isEmpty());
+ }
}
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFieldUI.java b/src/net/java/sip/communicator/plugin/desktoputil/plaf/SearchFieldUI.java
similarity index 82%
rename from src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFieldUI.java
rename to src/net/java/sip/communicator/plugin/desktoputil/plaf/SearchFieldUI.java
index 2b0297b67..53b7d842b 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFieldUI.java
+++ b/src/net/java/sip/communicator/plugin/desktoputil/plaf/SearchFieldUI.java
@@ -4,7 +4,7 @@
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
-package net.java.sip.communicator.impl.gui.main.contactlist;
+package net.java.sip.communicator.plugin.desktoputil.plaf;
import java.awt.*;
import java.awt.event.*;
@@ -13,13 +13,11 @@
import javax.swing.plaf.*;
import javax.swing.text.*;
-import net.java.sip.communicator.impl.gui.*;
-import net.java.sip.communicator.impl.gui.main.call.*;
import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.plugin.desktoputil.plaf.*;
-import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.skin.*;
+import org.jitsi.service.resources.*;
+
/**
* The SearchTextFieldUI is the one responsible for the search field
* look & feel. It draws a search icon inside the field and adjusts the bounds
@@ -27,15 +25,22 @@
*
* @author Yana Stamcheva
* @author Adam Netocny
+ * @author Marin Dzhigarov
*/
public class SearchFieldUI
extends SIPCommTextFieldUI
implements Skinnable
{
/**
- * The icon indicating that this is a search field.
+ * Creates a UI for a SearchFieldUI.
+ *
+ * @param c the text field
+ * @return the UI
*/
- private ImageIcon searchIcon;
+ public static ComponentUI createUI(JComponent c)
+ {
+ return new SearchFieldUI();
+ }
/**
* The default icon of the call button.
@@ -43,9 +48,9 @@ public class SearchFieldUI
private Image callIcon;
/**
- * The separator icon shown between the call icon and the close.
+ * The pressed icon of the call button.
*/
- private Image separatorIcon;
+ private Image callPressedIcon;
/**
* The roll over icon of the call button.
@@ -53,76 +58,49 @@ public class SearchFieldUI
private Image callRolloverIcon;
/**
- * The pressed icon of the call button.
+ * The call button tool tip string.
*/
- private Image callPressedIcon;
+ private final String callString = DesktopUtilActivator.getResources()
+ .getI18NString("service.gui.CALL");
/**
- * Indicates if the mouse is currently over the call button.
+ * Indicates if the call button is enabled in this search field.
*/
- private boolean isCallMouseOver = false;
+ protected boolean isCallButtonEnabled = true;
/**
- * Indicates if the mouse is currently over the call button.
+ * Indicates if the call icon is currently visible.
*/
- private boolean isCallMousePressed = false;
+ protected boolean isCallIconVisible = false;
/**
- * The call button tool tip string.
+ * Indicates if the mouse is currently over the call button.
*/
- private final String callString
- = GuiActivator.getResources().getI18NString("service.gui.CALL");
+ private boolean isCallMouseOver = false;
/**
- * Indicates if the call icon is currently visible.
+ * Indicates if the mouse is currently over the call button.
*/
- private boolean isCallIconVisible = false;
+ private boolean isCallMousePressed = false;
/**
- * Indicates if the call button is enabled in this search field.
+ * The icon indicating that this is a search field.
*/
- private boolean isCallButtonEnabled = true;
+ private ImageIcon searchIcon;
/**
- * Creates a SIPCommTextFieldUI.
+ * The separator icon shown between the call icon and the close.
*/
- public SearchFieldUI()
- {
- // Indicates if the big call button outside the search is enabled.
- String callButtonEnabledString = UtilActivator.getResources()
- .getSettingsString("impl.gui.CALL_BUTTON_ENABLED");
-
- if (callButtonEnabledString != null
- && callButtonEnabledString.length() > 0)
- {
- // If the outside call button is enabled the call button in this
- // search field is disabled.
- isCallButtonEnabled
- = !new Boolean(callButtonEnabledString).booleanValue();
- }
-
- loadSkin();
- }
+ private Image separatorIcon;
/**
- * Enables/disabled the call button in the search field.
- *
- * @param isEnabled indicates if the call button is enabled
+ * Creates a GenericSearchFieldUI.
*/
- public void setCallButtonEnabled(boolean isEnabled)
+ public SearchFieldUI()
{
- this.isCallButtonEnabled = isEnabled;
- }
+ isCallButtonEnabled = false;
- /**
- * Implements parent paintSafely method and enables antialiasing.
- * @param g the Graphics object that notified us
- */
- @Override
- protected void paintSafely(Graphics g)
- {
- customPaintBackground(g);
- super.paintSafely(g);
+ loadSkin();
}
/**
@@ -144,11 +122,10 @@ protected void customPaintBackground(Graphics g)
int dy = (c.getY() + c.getHeight()) / 2
- searchIcon.getIconHeight()/2;
- g2.drawImage(searchIcon.getImage(), 3, dy + 1, null);
+ g2.drawImage(searchIcon.getImage(), 3, dy, null);
if (c.getText() != null
&& c.getText().length() > 0
- && CallManager.getTelephonyProviders().size() > 0
&& isCallButtonEnabled)
{
// Paint call button.
@@ -180,6 +157,25 @@ else if (isCallMouseOver)
}
}
+ /**
+ * Calculates the call button rectangle.
+ *
+ * @return the call button rectangle
+ */
+ protected Rectangle getCallButtonRect()
+ {
+ Component c = getComponent();
+ Rectangle rect = c.getBounds();
+
+ int dx = getDeleteButtonRect().x - callRolloverIcon.getWidth(null) - 8;
+ int dy = (rect.y + rect.height) / 2 - callRolloverIcon.getHeight(null)/2;
+
+ return new Rectangle( dx,
+ dy,
+ callRolloverIcon.getWidth(null),
+ callRolloverIcon.getHeight(null));
+ }
+
/**
* If we are in the case of disabled delete button, we simply call the
* parent implementation of this method, otherwise we recalculate the editor
@@ -210,6 +206,32 @@ protected Rectangle getVisibleEditorRect()
return null;
}
+ /**
+ * Reloads UI icons.
+ */
+ @Override
+ public void loadSkin()
+ {
+ super.loadSkin();
+
+ ResourceManagementService r = DesktopUtilActivator.getResources();
+
+ searchIcon = r.getImage("service.gui.icons.SEARCH_ICON");
+ if (isCallButtonEnabled)
+ {
+ callIcon
+ = r.getImage("service.gui.buttons.SEARCH_CALL_ICON").getImage();
+ callRolloverIcon
+ = r.getImage("service.gui.buttons.SEARCH_CALL_ROLLOVER_ICON")
+ .getImage();
+ callPressedIcon
+ = r.getImage("service.gui.buttons.SEARCH_CALL_PRESSED_ICON")
+ .getImage();
+ separatorIcon
+ = r.getImage("service.gui.icons.SEARCH_SEPARATOR").getImage();
+ }
+ }
+
/**
* Updates the call button when the mouse was clicked.
* @param e the MouseEvent that notified us of the click
@@ -223,6 +245,19 @@ public void mouseClicked(MouseEvent e)
updateCallIcon(e);
}
+ /**
+ * Updates the delete icon when the mouse is dragged over.
+ * @param e the MouseEvent that notified us
+ */
+ @Override
+ public void mouseDragged(MouseEvent e)
+ {
+ super.mouseDragged(e);
+
+ if(isCallButtonEnabled)
+ updateCallIcon(e);
+ }
+
/**
* Updates the call button when the mouse is enters the component area.
* @param e the MouseEvent that notified us
@@ -249,6 +284,19 @@ public void mouseExited(MouseEvent e)
updateCallIcon(e);
}
+ /**
+ * Updates the delete icon when the mouse is moved over.
+ * @param e the MouseEvent that notified us
+ */
+ @Override
+ public void mouseMoved(MouseEvent e)
+ {
+ super.mouseMoved(e);
+
+ if(isCallButtonEnabled)
+ updateCallIcon(e);
+ }
+
@Override
public void mousePressed(MouseEvent e)
{
@@ -268,29 +316,24 @@ public void mouseReleased(MouseEvent e)
}
/**
- * Updates the delete icon when the mouse is dragged over.
- * @param e the MouseEvent that notified us
+ * Implements parent paintSafely method and enables antialiasing.
+ * @param g the Graphics object that notified us
*/
@Override
- public void mouseDragged(MouseEvent e)
+ protected void paintSafely(Graphics g)
{
- super.mouseDragged(e);
-
- if(isCallButtonEnabled)
- updateCallIcon(e);
+ customPaintBackground(g);
+ super.paintSafely(g);
}
/**
- * Updates the delete icon when the mouse is moved over.
- * @param e the MouseEvent that notified us
+ * Enables/disabled the call button in the search field.
+ *
+ * @param isEnabled indicates if the call button is enabled
*/
- @Override
- public void mouseMoved(MouseEvent e)
+ public void setCallButtonEnabled(boolean isEnabled)
{
- super.mouseMoved(e);
-
- if(isCallButtonEnabled)
- updateCallIcon(e);
+ this.isCallButtonEnabled = isEnabled;
}
/**
@@ -301,7 +344,7 @@ public void mouseMoved(MouseEvent e)
* @param evt the mouse event that has prompted us to update the delete
* icon.
*/
- private void updateCallIcon(MouseEvent evt)
+ protected void updateCallIcon(MouseEvent evt)
{
int x = evt.getX();
int y = evt.getY();
@@ -336,12 +379,6 @@ private void updateCallIcon(MouseEvent evt)
// Update the default cursor.
getComponent().setCursor(Cursor.getDefaultCursor());
-
- // Perform call action when the call button is clicked.
- if (evt.getID() == MouseEvent.MOUSE_CLICKED)
- {
- CallManager.createCall(searchText, c);
- }
}
else
{
@@ -359,63 +396,4 @@ private void updateCallIcon(MouseEvent evt)
getComponent().repaint();
}
-
- /**
- * Calculates the call button rectangle.
- *
- * @return the call button rectangle
- */
- protected Rectangle getCallButtonRect()
- {
- Component c = getComponent();
- Rectangle rect = c.getBounds();
-
- int dx = getDeleteButtonRect().x - callRolloverIcon.getWidth(null) - 8;
- int dy = (rect.y + rect.height) / 2 - callRolloverIcon.getHeight(null)/2;
-
- return new Rectangle( dx,
- dy,
- callRolloverIcon.getWidth(null),
- callRolloverIcon.getHeight(null));
- }
-
- /**
- * Reloads UI icons.
- */
- @Override
- public void loadSkin()
- {
- super.loadSkin();
-
- searchIcon = UtilActivator.getResources()
- .getImage("service.gui.icons.SEARCH_ICON");
-
- if (isCallButtonEnabled)
- {
- callIcon = UtilActivator.getResources()
- .getImage("service.gui.buttons.SEARCH_CALL_ICON").getImage();
-
- callRolloverIcon = UtilActivator.getResources()
- .getImage("service.gui.buttons.SEARCH_CALL_ROLLOVER_ICON")
- .getImage();
-
- callPressedIcon = UtilActivator.getResources()
- .getImage("service.gui.buttons.SEARCH_CALL_PRESSED_ICON")
- .getImage();
-
- separatorIcon = UtilActivator.getResources()
- .getImage("service.gui.icons.SEARCH_SEPARATOR").getImage();
- }
- }
-
- /**
- * Creates a UI for a SearchFieldUI.
- *
- * @param c the text field
- * @return the UI
- */
- public static ComponentUI createUI(JComponent c)
- {
- return new SearchFieldUI();
- }
}
diff --git a/src/net/java/sip/communicator/plugin/propertieseditor/ButtonsPanel.java b/src/net/java/sip/communicator/plugin/propertieseditor/ButtonsPanel.java
new file mode 100644
index 000000000..cd667dea7
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/propertieseditor/ButtonsPanel.java
@@ -0,0 +1,158 @@
+/*
+ * Jitsi, 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.propertieseditor;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.plugin.desktoputil.*;
+
+import org.jitsi.service.configuration.*;
+import org.jitsi.service.resources.*;
+
+/**
+ * The panel containing all buttons for the PropertiesEditorPanel.
+ *
+ * @author Marin Dzhigarov
+ */
+public class ButtonsPanel
+ extends TransparentPanel
+ implements ActionListener
+{
+
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 1L;
+
+ private ConfigurationService confService
+ = PropertiesEditorActivator.getConfigurationService();
+
+ private ResourceManagementService resourceManagementService
+ = PropertiesEditorActivator.getResourceManagementService();
+
+ /**
+ * The delete button.
+ */
+ private JButton deleteButton = new JButton(
+ resourceManagementService.getI18NString("service.gui.DELETE"));
+
+ /**
+ * The new button.
+ */
+ private JButton newButton = new JButton(
+ resourceManagementService.getI18NString("service.gui.NEW"));
+
+ /**
+ * The panel, containing all buttons.
+ */
+ private JPanel buttonsPanel
+ = new TransparentPanel(new GridLayout(0, 1, 8, 8));
+
+ /**
+ * The props table.
+ */
+ private JTable propsTable;
+
+ /**
+ * Instance of the search box panel.
+ */
+ private SearchField searchField;
+
+ /**
+ * Creates an instance of ButtonsPanel.
+ * @param propsTable the table containing all properties.
+ * @param searchBox the search box panel containing the search box text
+ * field.
+ */
+ public ButtonsPanel(JTable propsTable, SearchField searchField)
+ {
+ this.propsTable = propsTable;
+
+ this.searchField = searchField;
+
+ this.setLayout(new BorderLayout());
+
+ this.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
+
+ this.newButton.setOpaque(false);
+ this.deleteButton.setOpaque(false);
+
+ this.buttonsPanel.add(newButton);
+ this.buttonsPanel.add(deleteButton);
+
+ this.add(buttonsPanel, BorderLayout.NORTH);
+
+ this.newButton.addActionListener(this);
+ this.deleteButton.addActionListener(this);
+
+ //default as nothing is selected
+ defaultButtonState();
+ }
+
+ /**
+ * Default state of buttons, as nothing is selected
+ */
+ public void defaultButtonState()
+ {
+ enableDeleteButton(false);
+ }
+
+ /**
+ * Enable or disable the delete button.
+ *
+ * @param enable TRUE - to enable the delete button, FALSE - to disable it
+ */
+ public void enableDeleteButton(boolean enable)
+ {
+ this.deleteButton.setEnabled(enable);
+ }
+
+ /**
+ * Performs corresponding actions, when a button is pressed.
+ * @param e the ActionEvent that notified us
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ JButton sourceButton = (JButton) e.getSource();
+
+ if (sourceButton.equals(newButton))
+ {
+ NewPropertyDialog dialog = new NewPropertyDialog();
+
+ dialog.pack();
+ dialog.setLocation(
+ Toolkit.getDefaultToolkit().getScreenSize().width/2
+ - dialog.getWidth()/2,
+ Toolkit.getDefaultToolkit().getScreenSize().height/2
+ - dialog.getHeight()/2
+ );
+
+ dialog.setVisible(true);
+
+ } else if (sourceButton.equals(deleteButton))
+ {
+ int viewRow = propsTable.getSelectedRow();
+ int modelRow =
+ propsTable.convertRowIndexToModel(viewRow);
+ String selectedProperty
+ = (String)propsTable.getModel().getValueAt(modelRow, 0);
+ confService.removeProperty(selectedProperty);
+ propsTable.clearSelection();
+ defaultButtonState();
+ /**
+ * Resets the text in the search box text field in order to fire
+ * a new value change event for the FilterRow to update the view.
+ */
+ String text = searchField.getText();
+ searchField.setText(text);
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/propertieseditor/Constants.java b/src/net/java/sip/communicator/plugin/propertieseditor/Constants.java
new file mode 100644
index 000000000..e903b43c3
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/propertieseditor/Constants.java
@@ -0,0 +1,21 @@
+/*
+ * Jitsi, 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.propertieseditor;
+
+/**
+ * The Constants of this package.
+ *
+ * @author Marin Dzhigarov
+ *
+ */
+public class Constants
+{
+ /**
+ * Property indicating whether or not to show the WarningPanel
+ */
+ public static String SHOW_WARNING_MSG_PROP =
+ "net.java.sip.communicator.plugin.propertieseditor.showWarningMsg";
+}
diff --git a/src/net/java/sip/communicator/plugin/propertieseditor/NewPropertyDialog.java b/src/net/java/sip/communicator/plugin/propertieseditor/NewPropertyDialog.java
new file mode 100644
index 000000000..4025070dc
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/propertieseditor/NewPropertyDialog.java
@@ -0,0 +1,179 @@
+/*
+ * Jitsi, 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.propertieseditor;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+import javax.swing.event.*;
+
+import net.java.sip.communicator.plugin.desktoputil.*;
+
+import org.jitsi.service.configuration.*;
+import org.jitsi.service.resources.*;
+
+/**
+ * @author Marin Dzhigarov
+ */
+public class NewPropertyDialog
+ extends SIPCommDialog
+ implements ActionListener
+{
+
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 1L;
+
+ private ConfigurationService confService = PropertiesEditorActivator
+ .getConfigurationService();
+
+ private ResourceManagementService resourceManagementService =
+ PropertiesEditorActivator.getResourceManagementService();
+
+ /**
+ * The ok button.
+ */
+ private JButton okButton = new JButton(
+ resourceManagementService.getI18NString("service.gui.OK"));
+
+ /**
+ * The cancel button.
+ */
+ private JButton cancelButton = new JButton(
+ resourceManagementService.getI18NString("service.gui.CANCEL"));
+
+ /**
+ * The property name text field.
+ */
+ private JTextField propertyNameTextField = new JTextField();
+
+ /**
+ * The property value text field.
+ */
+ private JTextField propertyValueTextField = new JTextField();
+
+ /**
+ * The property name label.
+ */
+ private JLabel propertyNameLabel = new JLabel(
+ resourceManagementService.getI18NString("service.gui.NAME") + ": ");
+
+ /**
+ * The property value label.
+ */
+ private JLabel propertyValueLabel = new JLabel(
+ resourceManagementService.getI18NString("service.gui.VALUE") + ": ");
+
+ /**
+ * The panel containing all buttons.
+ */
+ private JPanel buttonsPanel = new TransparentPanel(new FlowLayout(
+ FlowLayout.CENTER));
+
+ /**
+ * The panel containing the property value and name panels.
+ */
+ private JPanel dataPanel = new TransparentPanel(new GridBagLayout());
+
+ /**
+ * Creates an instance of NewPropertyDialog.
+ */
+ public NewPropertyDialog()
+ {
+ setTitle(resourceManagementService
+ .getI18NString("plugin.propertieseditor.NEW_PROPERTY_TITLE"));
+ JPanel fields = new TransparentPanel(new BorderLayout());
+ fields.setPreferredSize(new Dimension(450, 150));
+
+ this.getContentPane().add(fields);
+
+ fields.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
+ fields.add(dataPanel, BorderLayout.NORTH);
+ fields.add(buttonsPanel, BorderLayout.SOUTH);
+
+ this.buttonsPanel.add(okButton);
+ this.buttonsPanel.add(cancelButton);
+ okButton.setEnabled(false);
+
+ this.okButton.addActionListener(this);
+ this.cancelButton.addActionListener(this);
+
+ GridBagConstraints first = new GridBagConstraints();
+ first.gridx = 0;
+ first.gridy = 0;
+ first.weightx = 0;
+ first.anchor = GridBagConstraints.LINE_START;
+ first.gridwidth = 1;
+ first.insets = new Insets(2, 4, 2, 4);
+ first.fill = GridBagConstraints.HORIZONTAL;
+
+ GridBagConstraints second = new GridBagConstraints();
+ second.gridx = 1;
+ second.gridy = 0;
+ second.weightx = 2;
+ second.anchor = GridBagConstraints.LINE_START;
+ second.gridwidth = 1; // GridBagConstraints.REMAINDER;
+ second.insets = first.insets;
+ second.fill = GridBagConstraints.HORIZONTAL;
+
+ dataPanel.add(propertyNameLabel, first);
+ dataPanel.add(propertyNameTextField, second);
+
+ first.gridy = ++second.gridy;
+
+ dataPanel.add(propertyValueLabel, first);
+ dataPanel.add(propertyValueTextField, second);
+
+ propertyNameTextField.getDocument().addDocumentListener(
+ new DocumentListener()
+ {
+ public void insertUpdate(DocumentEvent e)
+ {
+ okButton.setEnabled(true);
+ }
+
+ public void removeUpdate(DocumentEvent e)
+ {
+ if (propertyNameTextField.getText().length() == 0)
+ okButton.setEnabled(false);
+ }
+
+ public void changedUpdate(DocumentEvent e)
+ {
+ }
+ });
+ }
+
+ /**
+ * Performs corresponding actions, when a button is pressed.
+ *
+ * @param e the ActionEvent that notified us
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ JButton sourceButton = (JButton) e.getSource();
+
+ if (sourceButton.equals(okButton))
+ {
+ confService.setProperty(propertyNameTextField.getText(),
+ propertyValueTextField.getText());
+ }
+ dispose();
+ }
+
+ /**
+ * Presses programmatically the cancel button, when Esc key is pressed.
+ *
+ * @param isEscaped indicates if the Esc button was pressed on close
+ */
+ protected void close(boolean isEscaped)
+ {
+ cancelButton.doClick();
+ }
+
+}
\ No newline at end of file
diff --git a/src/net/java/sip/communicator/plugin/propertieseditor/PropertiesEditorActivator.java b/src/net/java/sip/communicator/plugin/propertieseditor/PropertiesEditorActivator.java
new file mode 100644
index 000000000..a96394341
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/propertieseditor/PropertiesEditorActivator.java
@@ -0,0 +1,129 @@
+/*
+ * Jitsi, 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.propertieseditor;
+
+import org.jitsi.service.configuration.*;
+import org.jitsi.service.resources.ResourceManagementService;
+
+import java.util.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.util.*;
+import org.osgi.framework.*;
+
+/**
+ * The BundleActivator of the PropertiesEditor plugin.
+ *
+ * @author Marin Dzhigarov
+ * @author Pawel Domas
+ */
+public class PropertiesEditorActivator
+ implements BundleActivator
+{
+
+ /**
+ * The bundle context.
+ */
+ public static BundleContext bundleContext;
+
+ /**
+ * Starts this bundle and adds the
+ *
PropertiesEditorPanel contained in it to the configuration
+ * window obtained from the UIService.
+ * @param bc the BundleContext
+ * @throws Exception if one of the operation executed in the start method
+ * fails
+ */
+ public void start(BundleContext bc) throws Exception
+ {
+ bundleContext = bc;
+ Dictionary properties = new Hashtable();
+ properties.put(ConfigurationForm.FORM_TYPE,
+ ConfigurationForm.ADVANCED_TYPE);
+ bundleContext.registerService(
+ ConfigurationForm.class.getName(),
+ new LazyConfigurationForm(
+ StartingPanel.class.getName(),
+ getClass().getClassLoader(),
+ "",
+ "plugin.propertieseditor.TITLE",
+ 1002, true),
+ properties);
+ }
+
+ /**
+ * Stops this bundles.
+ * @param bc the BundleContext
+ * @throws Exception if one of the operation executed in the stop method
+ * fails
+ */
+ public void stop(BundleContext bc) throws Exception {}
+
+ /**
+ * The ui service
+ */
+ private static UIService uiService;
+
+ /**
+ * Returns the UIService obtained from the bundle context.
+ *
+ * @return the UIService obtained from the bundle context.
+ */
+ public static UIService getUIService()
+ {
+ if (uiService == null)
+ {
+ ServiceReference uiReference =
+ bundleContext.getServiceReference(UIService.class.getName());
+
+ uiService =
+ (UIService) bundleContext.getService(uiReference);
+ }
+
+ return uiService;
+ }
+
+ /**
+ * The configuration service.
+ */
+ private static ConfigurationService configService;
+
+ /**
+ * Returns the ConfigurationService obtained from the bundle context.
+ *
+ * @return the ConfigurationService obtained from the bundle context.
+ */
+ public static ConfigurationService getConfigurationService()
+ {
+ if (configService == null)
+ {
+ configService = ServiceUtils.getService(
+ bundleContext,
+ ConfigurationService.class);
+ }
+ return configService;
+ }
+
+ /**
+ * The resource management service.
+ */
+ private static ResourceManagementService resourceManagementService;
+
+
+ /**
+ * Returns the ResourceManagementService obtained from the bundle context.
+ *
+ * @return the ResourceManagementService obtained from the bundle context.
+ */
+ public static ResourceManagementService getResourceManagementService() {
+ if (resourceManagementService == null) {
+ resourceManagementService = ServiceUtils.getService(
+ bundleContext,
+ ResourceManagementService.class);
+ }
+ return resourceManagementService;
+ }
+}
\ No newline at end of file
diff --git a/src/net/java/sip/communicator/plugin/propertieseditor/PropertiesEditorPanel.java b/src/net/java/sip/communicator/plugin/propertieseditor/PropertiesEditorPanel.java
new file mode 100644
index 000000000..a589fb234
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/propertieseditor/PropertiesEditorPanel.java
@@ -0,0 +1,137 @@
+/*
+ * Jitsi, 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.propertieseditor;
+
+import java.awt.*;
+
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+
+import net.java.sip.communicator.plugin.desktoputil.*;
+
+import org.jitsi.service.resources.*;
+
+/**
+ * @author Marin Dzhigarov
+ * @author Pawel Domas
+ *
+ */
+public class PropertiesEditorPanel
+ extends TransparentPanel
+
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 1L;
+
+ private ResourceManagementService resourceManagementService =
+ PropertiesEditorActivator.getResourceManagementService();
+
+ /**
+ * The panel containing the props table and the buttons panel
+ */
+ private JPanel centerPanel;
+
+ /**
+ * The props table.
+ */
+ private JTable propsTable;
+
+ /**
+ * The buttons panel.
+ */
+ private ButtonsPanel buttonsPanel;
+
+ /**
+ * Creates an instance PropertiesEditorPanel.
+ */
+ public PropertiesEditorPanel()
+ {
+ super(new BorderLayout());
+ setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
+
+ /**
+ * Instantiates the properties table and adds selection model and
+ * listener and adds a row sorter to the table model
+ */
+ propsTable = new JTable(getTableModel());
+ propsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ PropsListSelectionListener selectionListener =
+ new PropsListSelectionListener();
+ propsTable.getSelectionModel().addListSelectionListener(
+ selectionListener);
+ propsTable.getColumnModel().getSelectionModel()
+ .addListSelectionListener(selectionListener);
+ TableRowSorter sorter =
+ new TableRowSorter(propsTable.getModel());
+ propsTable.setRowSorter(sorter);
+
+ JScrollPane scrollPane = new JScrollPane(propsTable);
+
+ SearchField searchField = new SearchField("", sorter);
+ buttonsPanel = new ButtonsPanel(propsTable, searchField);
+
+ centerPanel = new TransparentPanel(new BorderLayout());
+ centerPanel.add(scrollPane, BorderLayout.CENTER);
+ centerPanel.add(buttonsPanel, BorderLayout.EAST);
+
+ JLabel needRestart =
+ new JLabel(
+ resourceManagementService
+ .getI18NString("plugin.propertieseditor.NEED_RESTART"));
+ needRestart.setForeground(Color.RED);
+
+ TransparentPanel searchPanel =
+ new TransparentPanel(new BorderLayout(5, 0));
+ searchPanel.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5));
+ searchPanel.add(searchField, BorderLayout.CENTER);
+
+ add(searchPanel, BorderLayout.NORTH);
+ add(centerPanel, BorderLayout.CENTER);
+ add(needRestart, BorderLayout.SOUTH);
+ }
+
+ /**
+ * The table model of the props table.
+ */
+ private PropsTableModel tableModel;
+
+ /**
+ * Returns the table model of the props table.
+ *
+ * @return The PropsTableModel of the props table.
+ */
+ private PropsTableModel getTableModel()
+ {
+ if (tableModel == null)
+ tableModel = new PropsTableModel();
+ return tableModel;
+ }
+
+ /**
+ * Listens for events triggered when a selection is made in the props list.
+ */
+ private class PropsListSelectionListener
+ implements ListSelectionListener
+ {
+
+ public void valueChanged(ListSelectionEvent e)
+ {
+ int selectedRow = propsTable.getSelectedRow();
+
+ if (selectedRow == -1)
+ {
+ buttonsPanel.defaultButtonState();
+ return;
+ }
+
+ buttonsPanel.enableDeleteButton(true);
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/propertieseditor/PropsTableModel.java b/src/net/java/sip/communicator/plugin/propertieseditor/PropsTableModel.java
new file mode 100644
index 000000000..cc0e4036d
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/propertieseditor/PropsTableModel.java
@@ -0,0 +1,139 @@
+/*
+ * Jitsi, 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.propertieseditor;
+
+import java.beans.*;
+
+import javax.swing.event.*;
+import javax.swing.table.*;
+import org.jitsi.service.configuration.*;
+
+/**
+ * @author Marin Dzhigarov
+ * @author Pawel Domas
+ *
+ */
+public class PropsTableModel
+ implements TableModel,
+ PropertyChangeListener
+{
+
+ /**
+ * The configuration service.
+ */
+ private ConfigurationService confService = PropertiesEditorActivator.getConfigurationService();
+
+ /**
+ * Creates an instance of PropsTableModel.
+ */
+ PropsTableModel() {}
+
+ public void Register()
+ {
+ confService.addPropertyChangeListener(this);
+ }
+ public void Unregister()
+ {
+ confService.removePropertyChangeListener(this);
+ }
+
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ for (TableModelListener l : listeners.getListeners(TableModelListener.class))
+ {
+ l.tableChanged(new TableModelEvent(this));
+ }
+ }
+
+ public int getRowCount()
+ {
+ return confService.getAllPropertyNames().size();
+ }
+
+ /**
+ * Returns the count of table columns.
+ * @return int the count of table columns
+ */
+ public int getColumnCount()
+ {
+ return 2;
+ }
+
+ /**
+ * Returns the column name given column index.
+ * @param columnIndex The column index.
+ * @return The column name.
+ */
+ public String getColumnName(int columnIndex)
+ {
+ if(columnIndex == 0)
+ {
+ return "Property";
+ } else
+ {
+ return "Value";
+ }
+ }
+
+ /**
+ * Returns the class of the column given a column index
+ */
+ public Class> getColumnClass(int columnIndex)
+ {
+ return String.class;
+ }
+
+ /**
+ * Returns true if the given cell is edittable.
+ * Edittable cells in this model are cells with column index 1.
+ * @param rowIndex The row index.
+ * @param columnIndex The column index.
+ * @return True if the column index is 1
+ */
+ public boolean isCellEditable(int rowIndex, int columnIndex)
+ {
+ return columnIndex == 1;
+ }
+
+ /**
+ * Returns the value in the cell given by row and column.
+ */
+ public Object getValueAt(int rowIndex, int columnIndex)
+ {
+ if (columnIndex == 0)
+ {
+ return confService.getAllPropertyNames().get(rowIndex);
+ } else
+ {
+ return confService.getProperty(confService.getAllPropertyNames().get(rowIndex));
+ }
+ }
+
+ /**
+ * Sets aValue at a cell with coordinates [rowIndex, columnIndex]
+ * @param aValue The given value.
+ * @param rowIndex The row index that the value will be set to.
+ * @param columnIndex The column index that the value will be set to.
+ */
+ public void setValueAt(Object aValue, int rowIndex, int columnIndex)
+ {
+ String property = confService.getAllPropertyNames().get(rowIndex);
+ confService.setProperty(property, aValue);
+ }
+
+ private EventListenerList listeners = new EventListenerList();
+
+ public void addTableModelListener(TableModelListener l)
+ {
+ listeners.add(TableModelListener.class, l);
+ }
+
+ public void removeTableModelListener(TableModelListener l)
+ {
+ listeners.remove(TableModelListener.class, l);
+ }
+}
\ No newline at end of file
diff --git a/src/net/java/sip/communicator/plugin/propertieseditor/SearchField.java b/src/net/java/sip/communicator/plugin/propertieseditor/SearchField.java
new file mode 100644
index 000000000..a79f29bbc
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/propertieseditor/SearchField.java
@@ -0,0 +1,158 @@
+/*
+ * Jitsi, 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.propertieseditor;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+
+import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.plugin.desktoputil.plaf.*;
+import net.java.sip.communicator.util.*;
+import net.java.sip.communicator.util.skin.*;
+
+/**
+ * The field used for searching in the properties table.
+ *
+ * @author Marin Dzhigarov
+ *
+ */
+public class SearchField
+ extends SIPCommTextField
+ implements Skinnable
+{
+
+ /**
+ * Serial Version UID.
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Class id key used in UIDefaults.
+ */
+ private static final String uiClassID = SearchField.class.getName()
+ + "FieldUI";
+
+ /**
+ * The object used for logging.
+ */
+ private Logger logger = Logger.getLogger(SearchField.class);
+
+ TableRowSorter sorter;
+
+ /**
+ * Adds the ui class to UIDefaults.
+ */
+ static
+ {
+ UIManager.getDefaults().put(uiClassID,
+ SearchFieldUI.class.getName());
+ }
+
+ /**
+ * Creates an instance SearchField.
+ *
+ * @param text the text we would like to enter by default
+ * @param sorter the sorter which will be used for filtering.
+ */
+ public SearchField(String text, final TableRowSorter sorter)
+ {
+ super(text);
+
+ if (getUI() instanceof SearchFieldUI)
+ {
+ ((SearchFieldUI) getUI()).setDeleteButtonEnabled(true);
+ ((SearchFieldUI) getUI()).setCallButtonEnabled(false);
+ }
+
+ this.setBorder(null);
+ this.setOpaque(false);
+ this.setPreferredSize(new Dimension(100, 25));
+ this.setDragEnabled(true);
+
+ InputMap imap =
+ getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
+ imap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "escape");
+ ActionMap amap = getActionMap();
+ amap.put("escape", new AbstractAction()
+ {
+ /**
+ * Serial Version UID.
+ */
+ private static final long serialVersionUID = 1L;
+
+ public void actionPerformed(ActionEvent e)
+ {
+ setText("");
+ }
+ });
+
+ getDocument().addDocumentListener(new DocumentListener()
+ {
+ public void insertUpdate(DocumentEvent e)
+ {
+ RowFilter rf = null;
+ try
+ {
+ rf = RowFilter.regexFilter(getText(), 0);
+ }
+ catch (java.util.regex.PatternSyntaxException exception)
+ {
+ logger.info("Failed to compile regex.", exception);
+ return;
+ }
+ sorter.setRowFilter(rf);
+ }
+
+ public void removeUpdate(DocumentEvent e)
+ {
+ RowFilter rf = null;
+ try
+ {
+ rf = RowFilter.regexFilter(getText(), 0);
+ }
+ catch (java.util.regex.PatternSyntaxException exception)
+ {
+ logger.info("Failed to compile regex.", exception);
+ return;
+ }
+ sorter.setRowFilter(rf);
+ }
+
+ public void changedUpdate(DocumentEvent e)
+ {
+ }
+ });
+
+ loadSkin();
+ }
+
+ /**
+ * Returns the name of the L&F class that renders this component.
+ *
+ * @return the string "TreeUI"
+ * @see JComponent#getUIClassID
+ * @see UIDefaults#getUI
+ */
+ public String getUIClassID()
+ {
+ return uiClassID;
+ }
+
+ /**
+ * Reloads text field UI defs.
+ */
+ public void loadSkin()
+ {
+ if (getUI() instanceof SearchFieldUI)
+ {
+ ((SearchFieldUI) getUI()).loadSkin();
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/propertieseditor/StartingPanel.java b/src/net/java/sip/communicator/plugin/propertieseditor/StartingPanel.java
new file mode 100644
index 000000000..5027dccea
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/propertieseditor/StartingPanel.java
@@ -0,0 +1,60 @@
+/*
+ * Jitsi, 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.propertieseditor;
+
+import java.awt.*;
+
+import net.java.sip.communicator.plugin.desktoputil.*;
+
+import org.jitsi.service.configuration.*;
+
+/**
+ * The StartingPanel wraps the WarningPanel and
+ * PropertiesEditorPanel. Its main purpose is to choose which one of
+ * the panels to set visible.
+ *
+ * @author Marin Dzhigarov
+ */
+public class StartingPanel
+ extends TransparentPanel
+{
+ /**
+ * Serial Version UID.
+ */
+ private static final long serialVersionUID = 1L;
+
+ private ConfigurationService confService = PropertiesEditorActivator
+ .getConfigurationService();
+
+ /*
+ * The WarningPanel
+ */
+ WarningPanel warningPanel = new WarningPanel(this);
+
+ /**
+ * The PropertiesEditorPanel
+ */
+ PropertiesEditorPanel propertiesEditorPanel = new PropertiesEditorPanel();
+
+ /**
+ * Creates an instance StartingPanel
+ */
+ public StartingPanel()
+ {
+ super(new BorderLayout());
+ boolean showWarning =
+ confService.getBoolean(Constants.SHOW_WARNING_MSG_PROP, true);
+
+ if (showWarning)
+ {
+ add(warningPanel, BorderLayout.CENTER);
+ }
+ else
+ {
+ add(propertiesEditorPanel, BorderLayout.CENTER);
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/propertieseditor/WarningPanel.java b/src/net/java/sip/communicator/plugin/propertieseditor/WarningPanel.java
new file mode 100644
index 000000000..bf126df12
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/propertieseditor/WarningPanel.java
@@ -0,0 +1,98 @@
+/*
+ * Jitsi, 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.propertieseditor;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.plugin.desktoputil.*;
+
+import org.jitsi.service.configuration.*;
+import org.jitsi.service.resources.*;
+
+/**
+ * The WarningPanel allows users to change Jitsi configuration
+ * properties at runtime. It wraps the PropertiesEditorPanel in order
+ * to provide some more explanations and make complex configurations available
+ * only to advanced users.
+ *
+ * @author Marin Dzhigarov
+ */
+public class WarningPanel
+ extends TransparentPanel
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 1L;
+
+ private ResourceManagementService resourceManagementService =
+ PropertiesEditorActivator.getResourceManagementService();
+
+ private ConfigurationService confService = PropertiesEditorActivator
+ .getConfigurationService();
+
+ private JCheckBox checkBox;
+
+ /**
+ * Creates an instance WarningPanel
+ *
+ * @param startingPanel
+ */
+ public WarningPanel(final StartingPanel startingPanel)
+ {
+ super(new BorderLayout());
+
+ this.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
+
+ JPanel mainPanel = new TransparentPanel(new BorderLayout(0, 10));
+ add(mainPanel, BorderLayout.NORTH);
+
+ JTextPane warningMsg = new JTextPane();
+ warningMsg.setEditable(false);
+ warningMsg.setOpaque(false);
+ warningMsg.setText(resourceManagementService
+ .getI18NString("plugin.propertieseditor.DESCRIPTION"));
+
+ checkBox =
+ new JCheckBox(
+ resourceManagementService
+ .getI18NString("plugin.propertieseditor.CHECK_BOX"));
+ checkBox.setOpaque(false);
+ checkBox.setSelected(true);
+
+ mainPanel.add(warningMsg, BorderLayout.NORTH);
+ mainPanel.add(checkBox, BorderLayout.CENTER);
+
+ JButton btn =
+ new JButton(
+ resourceManagementService
+ .getI18NString("plugin.propertieseditor.IM_AWARE"));
+ btn.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ confService.setProperty(Constants.SHOW_WARNING_MSG_PROP,
+ new Boolean(checkBox.isSelected()));
+
+ startingPanel.removeAll();
+ startingPanel.add(startingPanel.propertiesEditorPanel,
+ BorderLayout.CENTER);
+ startingPanel.propertiesEditorPanel.setVisible(true);
+ startingPanel.revalidate();
+ startingPanel.repaint();
+ }
+ });
+
+ JPanel buttonPanel =
+ new TransparentPanel(new FlowLayout(FlowLayout.CENTER));
+ buttonPanel.add(btn);
+
+ mainPanel.add(buttonPanel, BorderLayout.SOUTH);
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/propertieseditor/propertieseditor.manifest.mf b/src/net/java/sip/communicator/plugin/propertieseditor/propertieseditor.manifest.mf
new file mode 100644
index 000000000..10f68c24d
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/propertieseditor/propertieseditor.manifest.mf
@@ -0,0 +1,22 @@
+Bundle-Activator: net.java.sip.communicator.plugin.propertieseditor.PropertiesEditorActivator
+Bundle-Description: A panel that allows users to configure properties
+Bundle-Vendor: jitsi.org
+Bundle-Version: 0.0.1
+System-Bundle: yes
+Import-Package: org.osgi.framework,
+ org.jitsi.service.configuration,
+ org.jitsi.service.resources,
+ net.java.sip.communicator.service.resources,
+ net.java.sip.communicator.service.gui,
+ net.java.sip.communicator.service.gui.event,
+ net.java.sip.communicator.util,
+ net.java.sip.communicator.util.skin,
+ net.java.sip.communicator.plugin.desktoputil,
+ net.java.sip.communicator.plugin.desktoputil.event,
+ net.java.sip.communicator.plugin.desktoputil.plaf,
+ javax.swing,
+ javax.swing.event,
+ javax.swing.table,
+ javax.swing.text,
+ javax.swing.border,
+ javax.swing.plaf
diff --git a/src/net/java/sip/communicator/util/UtilActivator.java b/src/net/java/sip/communicator/util/UtilActivator.java
index 449b171ac..7c3b43e17 100644
--- a/src/net/java/sip/communicator/util/UtilActivator.java
+++ b/src/net/java/sip/communicator/util/UtilActivator.java
@@ -6,7 +6,6 @@
*/
package net.java.sip.communicator.util;
-//import java.awt.image.*;
import java.util.*;
import net.java.sip.communicator.service.gui.*;
|