diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.form b/Mage.Client/src/main/java/mage/client/MageFrame.form
index 1b50b9288ca..808b56ba8a6 100644
--- a/Mage.Client/src/main/java/mage/client/MageFrame.form
+++ b/Mage.Client/src/main/java/mage/client/MageFrame.form
@@ -61,6 +61,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -77,7 +90,7 @@
-
+
@@ -95,7 +108,7 @@
-
+
@@ -157,7 +170,7 @@
-
+
diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java
index a15029bccb4..a79c5ef8888 100644
--- a/Mage.Client/src/main/java/mage/client/MageFrame.java
+++ b/Mage.Client/src/main/java/mage/client/MageFrame.java
@@ -35,7 +35,6 @@
package mage.client;
import mage.Constants;
-import mage.interfaces.Action;
import mage.cards.Card;
import mage.cards.decks.Deck;
import mage.client.cards.CardsStorage;
@@ -62,7 +61,8 @@ import mage.client.util.SettingsManager;
import mage.client.util.gui.ArrowBuilder;
import mage.components.ImagePanel;
import mage.game.match.MatchOptions;
-import mage.interfaces.*;
+import mage.interfaces.Action;
+import mage.interfaces.MageClient;
import mage.interfaces.callback.CallbackClient;
import mage.interfaces.callback.ClientCallback;
import mage.remote.Connection;
@@ -611,143 +611,157 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
- // //GEN-BEGIN:initComponents
- private void initComponents() {
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
- desktopPane = new MageJDesktop();
- mageToolbar = new javax.swing.JToolBar();
- btnConnect = new javax.swing.JButton();
- jSeparator4 = new javax.swing.JToolBar.Separator();
- btnGames = new javax.swing.JButton();
- jSeparator3 = new javax.swing.JToolBar.Separator();
- btnDeckEditor = new javax.swing.JButton();
- jSeparator2 = new javax.swing.JToolBar.Separator();
- btnCollectionViewer = new javax.swing.JButton();
- jSeparator5 = new javax.swing.JToolBar.Separator();
- btnPreferences = new javax.swing.JButton();
- jSeparator6 = new javax.swing.JToolBar.Separator();
- btnAbout = new javax.swing.JButton();
- jSeparator1 = new javax.swing.JToolBar.Separator();
- btnExit = new javax.swing.JButton();
- lblStatus = new javax.swing.JLabel();
+ desktopPane = new MageJDesktop();
+ mageToolbar = new javax.swing.JToolBar();
+ btnSendFeedback = new javax.swing.JButton();
+ jSeparator4 = new javax.swing.JToolBar.Separator();
+ btnConnect = new javax.swing.JButton();
+ jSeparator3 = new javax.swing.JToolBar.Separator();
+ btnGames = new javax.swing.JButton();
+ jSeparator1 = new javax.swing.JToolBar.Separator();
+ btnDeckEditor = new javax.swing.JButton();
+ jSeparator2 = new javax.swing.JToolBar.Separator();
+ btnCollectionViewer = new javax.swing.JButton();
+ jSeparator5 = new javax.swing.JToolBar.Separator();
+ btnPreferences = new javax.swing.JButton();
+ jSeparator6 = new javax.swing.JToolBar.Separator();
+ btnAbout = new javax.swing.JButton();
+ jSeparator7 = new javax.swing.JToolBar.Separator();
+ btnExit = new javax.swing.JButton();
+ lblStatus = new javax.swing.JLabel();
- setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
- setMinimumSize(new Dimension(600, 400));
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ setMinimumSize(new java.awt.Dimension(1024, 768));
- desktopPane.setBackground(new java.awt.Color(204, 204, 204));
+ desktopPane.setBackground(new java.awt.Color(204, 204, 204));
- mageToolbar.setFloatable(false);
- mageToolbar.setRollover(true);
+ mageToolbar.setFloatable(false);
+ mageToolbar.setRollover(true);
- btnConnect.setText("Connect");
- btnConnect.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
- btnConnect.setFocusable(false);
- btnConnect.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
- btnConnect.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
- btnConnect.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- btnConnectActionPerformed(evt);
- }
- });
- mageToolbar.add(btnConnect);
- mageToolbar.add(jSeparator4);
+ btnSendFeedback.setText("Feedback");
+ btnSendFeedback.setFocusable(false);
+ btnSendFeedback.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ btnSendFeedback.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+ btnSendFeedback.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnSendFeedbackActionPerformed(evt);
+ }
+ });
+ mageToolbar.add(btnSendFeedback);
+ mageToolbar.add(jSeparator4);
- btnGames.setText("Games");
- btnGames.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
- btnGames.setFocusable(false);
- btnGames.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
- btnGames.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
- btnGames.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- btnGamesActionPerformed(evt);
- }
- });
- mageToolbar.add(btnGames);
- mageToolbar.add(jSeparator3);
+ btnConnect.setText("Connect");
+ btnConnect.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
+ btnConnect.setFocusable(false);
+ btnConnect.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ btnConnect.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+ btnConnect.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnConnectActionPerformed(evt);
+ }
+ });
+ mageToolbar.add(btnConnect);
+ mageToolbar.add(jSeparator3);
- btnDeckEditor.setText("Deck Editor");
- btnDeckEditor.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
- btnDeckEditor.setFocusable(false);
- btnDeckEditor.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
- btnDeckEditor.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
- btnDeckEditor.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- btnDeckEditorActionPerformed(evt);
- }
- });
- mageToolbar.add(btnDeckEditor);
- mageToolbar.add(jSeparator2);
+ btnGames.setText("Games");
+ btnGames.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
+ btnGames.setFocusable(false);
+ btnGames.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ btnGames.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+ btnGames.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnGamesActionPerformed(evt);
+ }
+ });
+ mageToolbar.add(btnGames);
+ mageToolbar.add(jSeparator1);
- btnCollectionViewer.setText("Collection Viewer");
- btnCollectionViewer.setFocusable(false);
- btnCollectionViewer.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
- btnCollectionViewer.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
- btnCollectionViewer.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- btnCollectionViewerActionPerformed(evt);
- }
- });
- mageToolbar.add(btnCollectionViewer);
- mageToolbar.add(jSeparator5);
+ btnDeckEditor.setText("Deck Editor");
+ btnDeckEditor.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
+ btnDeckEditor.setFocusable(false);
+ btnDeckEditor.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ btnDeckEditor.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+ btnDeckEditor.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnDeckEditorActionPerformed(evt);
+ }
+ });
+ mageToolbar.add(btnDeckEditor);
+ mageToolbar.add(jSeparator2);
- btnPreferences.setText("Preferences");
- btnPreferences.setFocusable(false);
- btnPreferences.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
- btnPreferences.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
- btnPreferences.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- btnPreferencesActionPerformed(evt);
- }
- });
- mageToolbar.add(btnPreferences);
- mageToolbar.add(jSeparator6);
+ btnCollectionViewer.setText("Collection Viewer");
+ btnCollectionViewer.setFocusable(false);
+ btnCollectionViewer.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ btnCollectionViewer.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+ btnCollectionViewer.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnCollectionViewerActionPerformed(evt);
+ }
+ });
+ mageToolbar.add(btnCollectionViewer);
+ mageToolbar.add(jSeparator5);
- btnAbout.setText("About");
- btnAbout.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
- btnAbout.setFocusable(false);
- btnAbout.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
- btnAbout.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
- btnAbout.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- btnAboutActionPerformed(evt);
- }
- });
- mageToolbar.add(btnAbout);
- mageToolbar.add(jSeparator1);
+ btnPreferences.setText("Preferences");
+ btnPreferences.setFocusable(false);
+ btnPreferences.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ btnPreferences.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+ btnPreferences.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnPreferencesActionPerformed(evt);
+ }
+ });
+ mageToolbar.add(btnPreferences);
+ mageToolbar.add(jSeparator6);
- btnExit.setText("Exit");
- btnExit.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
- btnExit.setFocusable(false);
- btnExit.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
- btnExit.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
- btnExit.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- btnExitActionPerformed(evt);
- }
- });
- mageToolbar.add(btnExit);
+ btnAbout.setText("About");
+ btnAbout.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
+ btnAbout.setFocusable(false);
+ btnAbout.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ btnAbout.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+ btnAbout.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnAboutActionPerformed(evt);
+ }
+ });
+ mageToolbar.add(btnAbout);
+ mageToolbar.add(jSeparator7);
- lblStatus.setText("Not connected ");
- mageToolbar.add(Box.createHorizontalGlue());
- mageToolbar.add(lblStatus);
+ btnExit.setText("Exit");
+ btnExit.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
+ btnExit.setFocusable(false);
+ btnExit.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ btnExit.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+ btnExit.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnExitActionPerformed(evt);
+ }
+ });
+ mageToolbar.add(btnExit);
- javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
- getContentPane().setLayout(layout);
- layout.setHorizontalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(desktopPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1144, Short.MAX_VALUE)
- .addComponent(mageToolbar, javax.swing.GroupLayout.DEFAULT_SIZE, 1144, Short.MAX_VALUE)
- );
- layout.setVerticalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addComponent(mageToolbar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addGap(0, 0, 0)
- .addComponent(desktopPane, javax.swing.GroupLayout.DEFAULT_SIZE, 880, Short.MAX_VALUE))
- );
+ lblStatus.setText("Not connected ");
+ mageToolbar.add(Box.createHorizontalGlue());
+ mageToolbar.add(lblStatus);
- pack();
- }// //GEN-END:initComponents
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(desktopPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1144, Short.MAX_VALUE)
+ .addComponent(mageToolbar, javax.swing.GroupLayout.DEFAULT_SIZE, 1144, Short.MAX_VALUE)
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(mageToolbar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(desktopPane, javax.swing.GroupLayout.DEFAULT_SIZE, 880, Short.MAX_VALUE))
+ );
+
+ pack();
+ }// //GEN-END:initComponents
private void btnDeckEditorActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDeckEditorActionPerformed
showDeckEditor(DeckEditorMode.Constructed, null, null, 0);
@@ -813,6 +827,14 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
PreferencesDialog.main(new String[]{});
}//GEN-LAST:event_btnPreferencesActionPerformed
+ private void btnSendFeedbackActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSendFeedbackActionPerformed
+ if (!session.isConnected()) {
+ JOptionPane.showMessageDialog(null, "You may send us feedback only when connected to server.", "Information", JOptionPane.INFORMATION_MESSAGE);
+ return;
+ }
+ FeedbackDialog.main(new String[]{});
+ }//GEN-LAST:event_btnSendFeedbackActionPerformed
+
public void exitApp() {
if (session.isConnected()) {
if (JOptionPane.showConfirmDialog(this, "You are currently connected. Are you sure you want to disconnect?", "Confirm disconnect", JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) {
@@ -954,24 +976,26 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
});
}
- // Variables declaration - do not modify//GEN-BEGIN:variables
- private javax.swing.JButton btnAbout;
- private javax.swing.JButton btnCollectionViewer;
- private javax.swing.JButton btnConnect;
- private javax.swing.JButton btnDeckEditor;
- private javax.swing.JButton btnExit;
- private javax.swing.JButton btnGames;
- private javax.swing.JButton btnPreferences;
- private static javax.swing.JDesktopPane desktopPane;
- private javax.swing.JToolBar.Separator jSeparator1;
- private javax.swing.JToolBar.Separator jSeparator2;
- private javax.swing.JToolBar.Separator jSeparator3;
- private javax.swing.JToolBar.Separator jSeparator4;
- private javax.swing.JToolBar.Separator jSeparator5;
- private javax.swing.JToolBar.Separator jSeparator6;
- private javax.swing.JLabel lblStatus;
- private javax.swing.JToolBar mageToolbar;
- // End of variables declaration//GEN-END:variables
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton btnAbout;
+ private javax.swing.JButton btnCollectionViewer;
+ private javax.swing.JButton btnConnect;
+ private javax.swing.JButton btnDeckEditor;
+ private javax.swing.JButton btnExit;
+ private javax.swing.JButton btnGames;
+ private javax.swing.JButton btnPreferences;
+ private javax.swing.JButton btnSendFeedback;
+ private static javax.swing.JDesktopPane desktopPane;
+ private javax.swing.JToolBar.Separator jSeparator1;
+ private javax.swing.JToolBar.Separator jSeparator2;
+ private javax.swing.JToolBar.Separator jSeparator3;
+ private javax.swing.JToolBar.Separator jSeparator4;
+ private javax.swing.JToolBar.Separator jSeparator5;
+ private javax.swing.JToolBar.Separator jSeparator6;
+ private javax.swing.JToolBar.Separator jSeparator7;
+ private javax.swing.JLabel lblStatus;
+ private javax.swing.JToolBar mageToolbar;
+ // End of variables declaration//GEN-END:variables
private static final long serialVersionUID = -9104885239063142218L;
private ImagePanel backgroundPane;
diff --git a/Mage.Client/src/main/java/mage/client/dialog/FeedbackDialog.form b/Mage.Client/src/main/java/mage/client/dialog/FeedbackDialog.form
new file mode 100644
index 00000000000..43875f57d71
--- /dev/null
+++ b/Mage.Client/src/main/java/mage/client/dialog/FeedbackDialog.form
@@ -0,0 +1,258 @@
+
+
+
diff --git a/Mage.Client/src/main/java/mage/client/dialog/FeedbackDialog.java b/Mage.Client/src/main/java/mage/client/dialog/FeedbackDialog.java
new file mode 100644
index 00000000000..4ea1a6d53b4
--- /dev/null
+++ b/Mage.Client/src/main/java/mage/client/dialog/FeedbackDialog.java
@@ -0,0 +1,328 @@
+/*
+* Copyright 2012 BetaSteward_at_googlemail.com. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are
+* permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice, this list
+* of conditions and the following disclaimer in the documentation and/or other materials
+* provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+* The views and conclusions contained in the software and documentation are those of the
+* authors and should not be interpreted as representing official policies, either expressed
+* or implied, of BetaSteward_at_googlemail.com.
+*/
+
+package mage.client.dialog;
+
+import mage.client.MageFrame;
+import org.apache.log4j.Logger;
+
+import javax.swing.*;
+
+/**
+ * Feedback dialog.
+ *
+ * @author noxx
+ */
+public class FeedbackDialog extends javax.swing.JDialog {
+
+ private static final transient Logger log = Logger.getLogger(PreferencesDialog.class);
+
+ private String[] feedbackTypes = {"", "Bug or \"something doesn't work\"",
+ "Feature or \"I need that function\"",
+ "Thank you or \"Devs, you are so cool!\"",
+ "Question or \"I'm so curious about\""};
+
+ /** Creates new form PreferencesDialog */
+ public FeedbackDialog(java.awt.Frame parent, boolean modal) {
+ super(parent, modal);
+ initComponents();
+ cbFeedbackType.setModel(new DefaultComboBoxModel(feedbackTypes));
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ jTabbedPane1 = new javax.swing.JTabbedPane();
+ jPanel6 = new javax.swing.JPanel();
+ pnlProxy = new javax.swing.JPanel();
+ lblProxyServer = new javax.swing.JLabel();
+ txtIdeaTitle = new javax.swing.JTextField();
+ lblProxyPort = new javax.swing.JLabel();
+ txtEmail = new javax.swing.JTextField();
+ lblProxyUserName = new javax.swing.JLabel();
+ cbFeedbackType = new javax.swing.JComboBox();
+ lblProxyType = new javax.swing.JLabel();
+ jScrollPane1 = new javax.swing.JScrollPane();
+ txtFeedbackMessage = new javax.swing.JTextArea();
+ jLabel2 = new javax.swing.JLabel();
+ jLabel3 = new javax.swing.JLabel();
+ jLabel1 = new javax.swing.JLabel();
+ sendButton = new javax.swing.JButton();
+ cancelButton = new javax.swing.JButton();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+ setTitle("Feedback");
+
+ lblProxyServer.setText("Enter your idea*");
+
+ lblProxyPort.setText("Your email:");
+
+ lblProxyUserName.setText("Describe your idea*");
+
+ lblProxyType.setText("Category");
+
+ txtFeedbackMessage.setColumns(20);
+ txtFeedbackMessage.setFont(new java.awt.Font("Tahoma", 0, 11));
+ txtFeedbackMessage.setRows(5);
+ txtFeedbackMessage.setText("(300 characters max)");
+ jScrollPane1.setViewportView(txtFeedbackMessage);
+
+ jLabel2.setFont(new java.awt.Font("Tahoma", 2, 11));
+ jLabel2.setText("(optional)");
+
+ jLabel3.setFont(new java.awt.Font("Tahoma", 2, 11));
+ jLabel3.setText("(optional)");
+
+ javax.swing.GroupLayout pnlProxyLayout = new javax.swing.GroupLayout(pnlProxy);
+ pnlProxy.setLayout(pnlProxyLayout);
+ pnlProxyLayout.setHorizontalGroup(
+ pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnlProxyLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
+ .addComponent(lblProxyUserName, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lblProxyType, javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lblProxyServer, javax.swing.GroupLayout.Alignment.LEADING))
+ .addComponent(lblProxyPort))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlProxyLayout.createSequentialGroup()
+ .addComponent(cbFeedbackType, 0, 243, Short.MAX_VALUE)
+ .addGap(26, 26, 26)
+ .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(20, 20, 20))
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlProxyLayout.createSequentialGroup()
+ .addGroup(pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addGroup(pnlProxyLayout.createSequentialGroup()
+ .addComponent(txtEmail, javax.swing.GroupLayout.DEFAULT_SIZE, 238, Short.MAX_VALUE)
+ .addGap(32, 32, 32)
+ .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(9, 9, 9))
+ .addComponent(txtIdeaTitle, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 325, Short.MAX_VALUE)
+ .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 325, Short.MAX_VALUE))
+ .addContainerGap())))
+ );
+ pnlProxyLayout.setVerticalGroup(
+ pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnlProxyLayout.createSequentialGroup()
+ .addGroup(pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(lblProxyServer)
+ .addComponent(txtIdeaTitle, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(cbFeedbackType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lblProxyType)
+ .addComponent(jLabel2))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lblProxyUserName)
+ .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 85, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(jLabel3)
+ .addComponent(txtEmail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lblProxyPort))
+ .addContainerGap(21, Short.MAX_VALUE))
+ );
+
+ jLabel1.setFont(new java.awt.Font("Arial", 1, 14));
+ jLabel1.setForeground(new java.awt.Color(255, 153, 51));
+ jLabel1.setText("I suggest you...");
+
+ javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6);
+ jPanel6.setLayout(jPanel6Layout);
+ jPanel6Layout.setHorizontalGroup(
+ jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel6Layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(pnlProxy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(jLabel1))
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+ jPanel6Layout.setVerticalGroup(
+ jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel6Layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(jLabel1)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(pnlProxy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap(41, Short.MAX_VALUE))
+ );
+
+ jTabbedPane1.addTab("Give feedback", jPanel6);
+
+ sendButton.setText("Send");
+ sendButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ sendButtonActionPerformed(evt);
+ }
+ });
+
+ cancelButton.setText("Cancel");
+ cancelButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ cancelButtonActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 469, Short.MAX_VALUE)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addContainerGap(324, Short.MAX_VALUE)
+ .addComponent(sendButton)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(cancelButton)
+ .addGap(17, 17, 17))
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 292, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(cancelButton)
+ .addComponent(sendButton))
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+
+ jTabbedPane1.getAccessibleContext().setAccessibleName("Feedback");
+
+ pack();
+ }// //GEN-END:initComponents
+
+ private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
+ dialog.setVisible(false);
+ }//GEN-LAST:event_cancelButtonActionPerformed
+
+ private void sendButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sendButtonActionPerformed
+ String title = txtIdeaTitle.getText().trim();
+ if (title.isEmpty()) {
+ JOptionPane.showMessageDialog(null, "\"Enter your idea\" is a mandatory field", "Warning", JOptionPane.INFORMATION_MESSAGE);
+ return;
+ }
+ if (title.length() > 100) {
+ JOptionPane.showMessageDialog(null, "\"Enter your idea\" value is too long (100 characters max)", "Warning", JOptionPane.INFORMATION_MESSAGE);
+ return;
+ }
+ String type = cleanUpType(cbFeedbackType.getSelectedItem().toString());
+ String message = txtFeedbackMessage.getText().trim();
+ if (message.isEmpty()) {
+ JOptionPane.showMessageDialog(null, "\"Describe your idea\" is a mandatory field.", "Warning", JOptionPane.INFORMATION_MESSAGE);
+ return;
+ }
+ if (message.length() > 300) {
+ JOptionPane.showMessageDialog(null, "\"Describe your idea\" value is too long (300 characters max)", "Warning", JOptionPane.INFORMATION_MESSAGE);
+ }
+ String email = cleanUpType(cbFeedbackType.getSelectedItem().toString());
+ if (MageFrame.getSession().sendFeedback(title, type, message, email)) {
+ JOptionPane.showMessageDialog(null, "Feedback was sent. Thank you!", "Success", JOptionPane.INFORMATION_MESSAGE);
+ reset();
+ } else {
+ JOptionPane.showMessageDialog(null, "Couldn't sent feedback.", "Error", JOptionPane.ERROR_MESSAGE);
+ }
+ }//GEN-LAST:event_sendButtonActionPerformed
+
+ private String cleanUpType(String type) {
+ if (type == null || type.isEmpty()) {
+ return "";
+ }
+ if (type.toLowerCase().startsWith("bug")) {
+ return "bug";
+ }
+ if (type.toLowerCase().startsWith("feature")) {
+ return "feature";
+ }
+ if (type.toLowerCase().startsWith("thank")) {
+ return "thank";
+ }
+ if (type.toLowerCase().startsWith("question")) {
+ return "question";
+ }
+ return "";
+ }
+
+ private void reset() {
+ jTabbedPane1.setSelectedIndex(0);
+ txtIdeaTitle.setText("");
+ txtFeedbackMessage.setText("");
+ txtEmail.setText("");
+ }
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String args[]) {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ if (!dialog.isVisible()) {
+ dialog.setLocation(300, 200);
+ dialog.setVisible(true);
+ } else {
+ dialog.requestFocus();
+ }
+ }
+ });
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton cancelButton;
+ private javax.swing.JComboBox cbFeedbackType;
+ private javax.swing.JLabel jLabel1;
+ private javax.swing.JLabel jLabel2;
+ private javax.swing.JLabel jLabel3;
+ private javax.swing.JPanel jPanel6;
+ private javax.swing.JScrollPane jScrollPane1;
+ private javax.swing.JTabbedPane jTabbedPane1;
+ private javax.swing.JLabel lblProxyPort;
+ private javax.swing.JLabel lblProxyServer;
+ private javax.swing.JLabel lblProxyType;
+ private javax.swing.JLabel lblProxyUserName;
+ private javax.swing.JPanel pnlProxy;
+ private javax.swing.JButton sendButton;
+ private javax.swing.JTextField txtEmail;
+ private javax.swing.JTextArea txtFeedbackMessage;
+ private javax.swing.JTextField txtIdeaTitle;
+ // End of variables declaration//GEN-END:variables
+
+ private static final FeedbackDialog dialog = new FeedbackDialog(new javax.swing.JFrame(), true);
+
+ static {
+ dialog.setResizable(false);
+ }
+}
diff --git a/Mage.Common/src/mage/db/EntityManager.java b/Mage.Common/src/mage/db/EntityManager.java
index 131daa217e5..c04fa485e05 100644
--- a/Mage.Common/src/mage/db/EntityManager.java
+++ b/Mage.Common/src/mage/db/EntityManager.java
@@ -1,5 +1,6 @@
package mage.db;
+import mage.db.model.Feedback;
import mage.db.model.Log;
import org.apache.log4j.Logger;
@@ -19,12 +20,18 @@ public enum EntityManager implements Storage {
private static final String MAGE_JDBC_URL = "jdbc:sqlite:db/mage.db";
+ private static final String MAGE_JDBC_URL_FEEDBACK_DB = "jdbc:sqlite:db/feedback.db";
+
private static String QUERY_SAVE_LOG = "insert into logs values (?, ?, ?, ?, ?, ?, ?, ?)";
private static String QUERY_GET_ALL_LOGS = "select * from logs";
+ private static String QUERY_SAVE_FEEDBACK = "insert into feedbacks values (?, ?, ?, ?, ?, ?, ?, ?)";
+ private static String QUERY_GET_ALL_FEEDBACKS = "select * from feedbacks";
+
static {
try {
init();
+ initFeedbackDB();
} catch (Exception e) {
log.fatal(e);
e.printStackTrace();
@@ -69,6 +76,10 @@ public enum EntityManager implements Storage {
}
}
+ /**
+ * Get all logs
+ * @return
+ */
@Override
public List getAllLogs() {
List logs = new ArrayList();
@@ -88,7 +99,6 @@ public enum EntityManager implements Storage {
}
args.add(arg);
}
- log.setArguments(args);
logs.add(log);
}
rs.close();
@@ -106,6 +116,86 @@ public enum EntityManager implements Storage {
return logs;
}
+ /**
+ * Inserts feedback entry to DB.
+ *
+ *
+ * @param username
+ * @param title
+ * @param type
+ * @param message
+ * @param email
+ * @param host
+ * @param created
+ * @throws SQLException
+ */
+ public void insertFeedback(String username, String title, String type, String message, String email, String host, java.util.Date created) throws SQLException {
+ Connection conn = DriverManager.getConnection(MAGE_JDBC_URL_FEEDBACK_DB);
+
+ try {
+ PreparedStatement prep = conn.prepareStatement(QUERY_SAVE_FEEDBACK);
+
+ prep.setString(1, username);
+ prep.setString(2, title);
+ prep.setString(3, type);
+ prep.setString(4, message);
+ prep.setString(5, email);
+ prep.setString(6, host);
+ prep.setDate(7, new java.sql.Date(created.getTime()));
+ prep.setString(8, "new");
+
+ prep.execute();
+ } finally {
+ try {
+ if (conn != null) conn.close();
+ } catch (Exception e) {
+ // swallow
+ }
+ }
+ }
+
+ /**
+ * Get all feedbacks
+ * @return
+ */
+ @Override
+ public List getAllFeedbacks() {
+ List feedbacks = new ArrayList();
+
+ try {
+ Connection conn = DriverManager.getConnection(MAGE_JDBC_URL_FEEDBACK_DB);
+ try {
+ Statement stat = conn.createStatement();
+ ResultSet rs = stat.executeQuery(QUERY_GET_ALL_FEEDBACKS);
+ while (rs.next()) {
+ Feedback feedback = new Feedback();
+
+ feedback.setUsername(rs.getString(1));
+ feedback.setTitle(rs.getString(2));
+ feedback.setType(rs.getString(3));
+ feedback.setMessage(rs.getString(4));
+ feedback.setEmail(rs.getString(5));
+ feedback.setHost(rs.getString(6));
+ feedback.setCreatedDate(rs.getDate(7));
+ feedback.setStatus(rs.getString(8));
+
+ feedbacks.add(feedback);
+ }
+ rs.close();
+ } finally {
+ try {
+ if (conn != null) conn.close();
+ } catch (Exception e) {
+ // swallow
+ }
+ }
+ } catch (SQLException e) {
+ log.fatal("SQL Exception: ", e);
+ }
+
+ return feedbacks;
+ }
+
/**
* Inits database. Creates tables if they don't exist.
*
@@ -128,6 +218,22 @@ public enum EntityManager implements Storage {
}
}
+ protected static void initFeedbackDB() throws Exception {
+ Class.forName("org.sqlite.JDBC");
+ checkDBFolderExistance();
+ Connection conn = DriverManager.getConnection(MAGE_JDBC_URL_FEEDBACK_DB);
+ try {
+ Statement stat = conn.createStatement();
+ stat.executeUpdate("create table if not exists feedbacks (username, title, type, message, email, host, created_dt, status);");
+ } finally {
+ try {
+ conn.close();
+ } catch (Exception e) {
+ // swallow
+ }
+ }
+ }
+
/**
* Reinits database. Drops all tables and then creates them from scratch.
* BE CAREFUL! THIS METHOD WILL DESTROY ALL DATA.
diff --git a/Mage.Common/src/mage/db/EntityManagerTest.java b/Mage.Common/src/mage/db/EntityManagerTest.java
index 613ac98a097..5b74b09ff29 100644
--- a/Mage.Common/src/mage/db/EntityManagerTest.java
+++ b/Mage.Common/src/mage/db/EntityManagerTest.java
@@ -1,5 +1,6 @@
package mage.db;
+import mage.db.model.Feedback;
import mage.db.model.Log;
import java.text.DateFormat;
@@ -29,5 +30,14 @@ public class EntityManagerTest {
System.out.println("]");
System.out.println(" --------------");
}
+
+ System.out.println("********************************");
+
+ List feedbackList = EntityManager.instance.getAllFeedbacks();
+ System.out.println("feedbacks found: " + feedbackList.size());
+ for (Feedback feedback : feedbackList) {
+ System.out.println(feedback.toString());
+ System.out.println("--------------");
+ }
}
}
diff --git a/Mage.Common/src/mage/db/Storage.java b/Mage.Common/src/mage/db/Storage.java
index a3095870462..f4c4dc8255e 100644
--- a/Mage.Common/src/mage/db/Storage.java
+++ b/Mage.Common/src/mage/db/Storage.java
@@ -1,14 +1,18 @@
package mage.db;
+import mage.db.model.Feedback;
import mage.db.model.Log;
import java.util.Date;
import java.util.List;
/**
- *
+ * Storage interface for saving and fetching entities.
+ * @author noxx
*/
public interface Storage {
void insertLog(String key, Date date, String... args) throws Exception;
List getAllLogs();
+ void insertFeedback(String username, String title, String type, String message, String email, String host, java.util.Date created) throws Exception;
+ List getAllFeedbacks();
}
diff --git a/Mage.Common/src/mage/db/model/Feedback.java b/Mage.Common/src/mage/db/model/Feedback.java
new file mode 100644
index 00000000000..3f84353c491
--- /dev/null
+++ b/Mage.Common/src/mage/db/model/Feedback.java
@@ -0,0 +1,102 @@
+package mage.db.model;
+
+import java.util.Date;
+
+/**
+ * Feedback entity.
+ *
+ * @author noxx
+ */
+public class Feedback {
+
+ private String username;
+ private String title;
+ private String type;
+ private String message;
+ private String email;
+ private String host;
+
+ private Date createdDate;
+
+ private String status;
+
+ public Feedback() {
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public Date getCreatedDate() {
+ return createdDate;
+ }
+
+ public void setCreatedDate(Date createdDate) {
+ this.createdDate = createdDate;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getHost() {
+ return host;
+ }
+
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ String msg = message != null && message.length() > 5 ? message.substring(0, 5) : message;
+ sb.append("Feedback [username=").append(username)
+ .append(", host=").append(host)
+ .append(", title=").append(title)
+ .append(", type=").append(type)
+ .append(", message=").append(msg)
+ .append("...]");
+ return sb.toString();
+ }
+}
diff --git a/Mage.Common/src/mage/interfaces/MageServer.java b/Mage.Common/src/mage/interfaces/MageServer.java
index 3dd9c192e65..dcdc9228883 100644
--- a/Mage.Common/src/mage/interfaces/MageServer.java
+++ b/Mage.Common/src/mage/interfaces/MageServer.java
@@ -125,4 +125,7 @@ public interface MageServer {
// messages of the day
public Object getServerMessagesCompressed(String sessionId) throws MageException;
+
+ // feedback
+ public void sendFeedbackMessage(String sessionId, String username, String title, String type, String message, String email) throws MageException;
}
diff --git a/Mage.Common/src/mage/remote/Session.java b/Mage.Common/src/mage/remote/Session.java
index 82c8edaf1d5..3b1657484be 100644
--- a/Mage.Common/src/mage/remote/Session.java
+++ b/Mage.Common/src/mage/remote/Session.java
@@ -252,6 +252,18 @@ public class Session {
client.showError("Network error. You have been disconnected");
}
+ public synchronized boolean sendFeedback(String title, String type, String message, String email) {
+ if (isConnected()) {
+ try {
+ server.sendFeedbackMessage(sessionId, connection.getUsername(), title, type, message, email);
+ return true;
+ } catch (MageException e) {
+ logger.error(e);
+ }
+ }
+ return false;
+ }
+
class CallbackHandler implements InvokerCallbackHandler {
@Override
public void handleCallback(Callback callback) throws HandleCallbackException {
diff --git a/Mage.Server/src/main/java/mage/server/MageServerImpl.java b/Mage.Server/src/main/java/mage/server/MageServerImpl.java
index f08665dd8a8..f5acdcacc72 100644
--- a/Mage.Server/src/main/java/mage/server/MageServerImpl.java
+++ b/Mage.Server/src/main/java/mage/server/MageServerImpl.java
@@ -42,6 +42,7 @@ import mage.remote.MageVersionException;
import mage.server.draft.DraftManager;
import mage.server.game.*;
import mage.server.services.LogKeys;
+import mage.server.services.impl.FeedbackServiceImpl;
import mage.server.services.impl.LogServiceImpl;
import mage.server.tournament.TournamentFactory;
import mage.server.tournament.TournamentManager;
@@ -61,7 +62,7 @@ import java.util.concurrent.ExecutorService;
/**
*
- * @author BetaSteward_at_googlemail.com
+ * @author BetaSteward_at_googlemail.com, noxx
*/
public class MageServerImpl implements MageServer {
@@ -707,6 +708,19 @@ public class MageServerImpl implements MageServer {
});
}
+ @Override
+ public void sendFeedbackMessage(final String sessionId, final String username, final String title, final String type, final String message, final String email) throws MageException {
+ if (title != null && message != null) {
+ execute("sendFeedbackMessage", sessionId, new Action() {
+ public void execute() {
+ String host = SessionManager.getInstance().getSession(sessionId).getHost();
+ FeedbackServiceImpl.instance.feedback(username, title, type, message, email, host);
+ LogServiceImpl.instance.log(LogKeys.KEY_FEEDBACK_ADDED, sessionId, username, host);
+ }
+ });
+ }
+ }
+
public void sendBroadcastMessage(final String sessionId, final String message) throws MageException {
if (message != null) {
execute("sendBroadcastMessage", sessionId, new Action() {
diff --git a/Mage.Server/src/main/java/mage/server/services/FeedbackService.java b/Mage.Server/src/main/java/mage/server/services/FeedbackService.java
new file mode 100644
index 00000000000..c3fe97a0ad2
--- /dev/null
+++ b/Mage.Server/src/main/java/mage/server/services/FeedbackService.java
@@ -0,0 +1,14 @@
+package mage.server.services;
+
+/**
+ * Responsible for gathering feedback from users and storing them in DB.
+ *
+ * @author noxx
+ */
+public interface FeedbackService {
+
+ /**
+ * Saves feedback.
+ */
+ void feedback(String username, String title, String type, String message, String email, String host);
+}
diff --git a/Mage.Server/src/main/java/mage/server/services/LogKeys.java b/Mage.Server/src/main/java/mage/server/services/LogKeys.java
index 6626f48ed4a..a45b5703c4e 100644
--- a/Mage.Server/src/main/java/mage/server/services/LogKeys.java
+++ b/Mage.Server/src/main/java/mage/server/services/LogKeys.java
@@ -28,4 +28,6 @@ public interface LogKeys {
public static final String KEY_WRONG_VERSION = "wrongVersion";
public static final String KEY_NOT_ADMIN = "notAdminRestrictedOperation";
+
+ public static final String KEY_FEEDBACK_ADDED = "feedbackAdded";
}
diff --git a/Mage.Server/src/main/java/mage/server/services/impl/FeedbackServiceImpl.java b/Mage.Server/src/main/java/mage/server/services/impl/FeedbackServiceImpl.java
new file mode 100644
index 00000000000..1f26af508fb
--- /dev/null
+++ b/Mage.Server/src/main/java/mage/server/services/impl/FeedbackServiceImpl.java
@@ -0,0 +1,26 @@
+package mage.server.services.impl;
+
+import mage.db.EntityManager;
+import mage.server.services.FeedbackService;
+import org.apache.log4j.Logger;
+
+import java.util.Calendar;
+
+/**
+ * @author noxx
+ */
+public enum FeedbackServiceImpl implements FeedbackService {
+ instance;
+
+ private static Logger log = Logger.getLogger(FeedbackServiceImpl.class);
+
+ @Override
+ public void feedback(String username, String title, String type, String message, String email, String host) {
+ Calendar cal = Calendar.getInstance();
+ try {
+ EntityManager.instance.insertFeedback(username, title, type, message, email, host, cal.getTime());
+ } catch (Exception e) {
+ log.fatal(e);
+ }
+ }
+}