From f7f46ebdf0ace19f37791aab89ceba0d6016088d Mon Sep 17 00:00:00 2001 From: Valentina Kiryushkina Date: Mon, 21 Mar 2016 15:14:48 +0300 Subject: [PATCH] Update tweeting api in study plugins * Create separate extension point to configure twitter * Show tweet panel before asking to authorize * Add input verifier to twitter panel --- .../student/resources/META-INF/plugin.xml | 1 + .../learning/StudyBasePluginConfigurator.java | 42 --- .../edu/learning/StudyPluginConfigurator.java | 46 --- .../StudyTwitterPluginConfigurator.java | 59 ++++ .../jetbrains/edu/learning/StudyUtils.java | 16 +- .../learning/twitter/StudyTwitterAction.java | 36 +-- .../learning/twitter/StudyTwitterUtils.java | 281 ++++++++++++------ 7 files changed, 268 insertions(+), 213 deletions(-) create mode 100644 python/educational-core/student/src/com/jetbrains/edu/learning/StudyTwitterPluginConfigurator.java diff --git a/python/educational-core/student/resources/META-INF/plugin.xml b/python/educational-core/student/resources/META-INF/plugin.xml index 9d5142d93775..1ccf94d72337 100644 --- a/python/educational-core/student/resources/META-INF/plugin.xml +++ b/python/educational-core/student/resources/META-INF/plugin.xml @@ -36,6 +36,7 @@ + diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyBasePluginConfigurator.java b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyBasePluginConfigurator.java index b269cde639b9..74410d74ce84 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyBasePluginConfigurator.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyBasePluginConfigurator.java @@ -7,10 +7,8 @@ import com.intellij.openapi.fileEditor.FileEditorManagerListener; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.jetbrains.edu.learning.actions.*; -import com.jetbrains.edu.learning.courseFormat.StudyStatus; import com.jetbrains.edu.learning.courseFormat.Task; import com.jetbrains.edu.learning.courseFormat.TaskFile; -import com.jetbrains.edu.learning.twitter.StudyTwitterUtils; import com.jetbrains.edu.learning.ui.StudyToolWindow; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -100,44 +98,4 @@ public abstract class StudyBasePluginConfigurator implements StudyPluginConfigur public StudyAfterCheckAction[] getAfterCheckActions() { return null; } - - @NotNull - @Override - public String getConsumerKey(@NotNull Project project) { - return ""; - } - - @NotNull - @Override - public String getConsumerSecret(@NotNull Project project) { - return ""; - } - - @Override - public void storeTwitterTokens(@NotNull Project project, @NotNull String accessToken, @NotNull String tokenSecret) { - // do nothing - } - - @NotNull - @Override - public String getTwitterTokenSecret(@NotNull Project project) { - return ""; - } - - @NotNull - @Override - public String getTwitterAccessToken(@NotNull Project project) { - return ""; - } - - @Override - public boolean askToTweet(@NotNull Project project, Task solvedTask, StudyStatus statusBeforeCheck) { - return false; - } - - @Nullable - @Override - public StudyTwitterUtils.TwitterDialogPanel getTweetDialogPanel(@NotNull Task solvedTask) { - return null; - } } diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyPluginConfigurator.java b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyPluginConfigurator.java index 4aa1f272acb5..09cddf9b8e28 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyPluginConfigurator.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyPluginConfigurator.java @@ -5,10 +5,7 @@ import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.fileEditor.FileEditorManagerListener; import com.intellij.openapi.project.Project; import com.jetbrains.edu.learning.actions.StudyAfterCheckAction; -import com.jetbrains.edu.learning.courseFormat.StudyStatus; -import com.jetbrains.edu.learning.courseFormat.Task; import com.jetbrains.edu.learning.settings.ModifiableSettingsPanel; -import com.jetbrains.edu.learning.twitter.StudyTwitterUtils; import com.jetbrains.edu.learning.ui.StudyToolWindow; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -21,7 +18,6 @@ public interface StudyPluginConfigurator { /** * Provide action group that should be placed on the tool window toolbar. - * @return */ @NotNull DefaultActionGroup getActionGroup(Project project); @@ -37,7 +33,6 @@ public interface StudyPluginConfigurator { FileEditorManagerListener getFileEditorManagerListener(@NotNull final Project project, @NotNull final StudyToolWindow toolWindow); /** - * * @return parameter for CodeMirror script. Available languages: @see <@linktourl http://codemirror.net/mode/> */ @NotNull String getDefaultHighlightingMode(); @@ -49,47 +44,6 @@ public interface StudyPluginConfigurator { @Nullable ModifiableSettingsPanel getSettingsPanel(); - - /** - * To implement tweeting you should register you app in twitter. For registered application twitter provide - * consumer key and consumer secret, that are used for authorize by OAuth. - * @return consumer key for current educational plugin - */ - @NotNull String getConsumerKey(@NotNull final Project project); - - /** - * To implement tweeting you should register you app in twitter. For registered application twitter provide - * consumer key and consumer secret, that are used for authorize by OAuth. - * @return consumer secret for current educational plugin - */ - @NotNull String getConsumerSecret(@NotNull final Project project); - - /** - * The plugin implemented tweeting should define policy when user will be asked to tweet. - *@param statusBeforeCheck @return - */ - boolean askToTweet(@NotNull final Project project, Task solvedTask, StudyStatus statusBeforeCheck); - - /** - * Stores access token and token secret, obtained by authorizing PyCharm. - */ - void storeTwitterTokens(@NotNull final Project project, @NotNull final String accessToken, @NotNull final String tokenSecret); - - /** - * @return stored access token - */ - @NotNull String getTwitterAccessToken(@NotNull Project project); - - /** - * @return stored token secret - */ - @NotNull String getTwitterTokenSecret(@NotNull Project project); - - /** - * @return panel that will be shown to user in ask to tweet dialog. - */ - @Nullable - StudyTwitterUtils.TwitterDialogPanel getTweetDialogPanel(@NotNull Task solvedTask); boolean accept(@NotNull final Project project); } diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyTwitterPluginConfigurator.java b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyTwitterPluginConfigurator.java new file mode 100644 index 000000000000..ea9b8b4caa55 --- /dev/null +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyTwitterPluginConfigurator.java @@ -0,0 +1,59 @@ +package com.jetbrains.edu.learning; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.project.Project; +import com.jetbrains.edu.learning.courseFormat.StudyStatus; +import com.jetbrains.edu.learning.courseFormat.Task; +import com.jetbrains.edu.learning.twitter.StudyTwitterUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface StudyTwitterPluginConfigurator { + ExtensionPointName EP_NAME = ExtensionPointName.create("Edu.studyTwitterPluginConfigurator"); + + /** + * To implement tweeting you should register you app in twitter. For registered application twitter provide + * consumer key and consumer secret, that are used for authorize by OAuth. + * @return consumer key for current educational plugin + */ + @NotNull + String getConsumerKey(@NotNull final Project project); + + /** + * To implement tweeting you should register you app in twitter. For registered application twitter provide + * consumer key and consumer secret, that are used for authorize by OAuth. + * @return consumer secret for current educational plugin + */ + @NotNull String getConsumerSecret(@NotNull final Project project); + + /** + * The plugin implemented tweeting should define policy when user will be asked to tweet. + *@param statusBeforeCheck @return + */ + boolean askToTweet(@NotNull final Project project, Task solvedTask, StudyStatus statusBeforeCheck); + + /** + * Stores access token and token secret, obtained by authorizing PyCharm. + */ + void storeTwitterTokens(@NotNull final Project project, @NotNull final String accessToken, @NotNull final String tokenSecret); + + /** + * @return stored access token + */ + @NotNull String getTwitterAccessToken(@NotNull Project project); + + /** + * @return stored token secret + */ + @NotNull String getTwitterTokenSecret(@NotNull Project project); + + /** + * @return panel that will be shown to user in ask to tweet dialog. + */ + @Nullable + StudyTwitterUtils.TwitterDialogPanel getTweetDialogPanel(@NotNull Task solvedTask); + + void setAskToTweet(@NotNull Project project, boolean askToTweet); + + boolean accept(@NotNull final Project project); +} diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyUtils.java b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyUtils.java index 940d94ce6b53..d783afb54c2e 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyUtils.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyUtils.java @@ -36,12 +36,12 @@ import com.intellij.ui.JBColor; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.content.Content; import com.intellij.util.ui.UIUtil; +import com.jetbrains.edu.learning.checker.StudyExecutor; +import com.jetbrains.edu.learning.checker.StudyTestRunner; import com.jetbrains.edu.learning.core.EduAnswerPlaceholderDeleteHandler; import com.jetbrains.edu.learning.core.EduAnswerPlaceholderPainter; import com.jetbrains.edu.learning.core.EduNames; import com.jetbrains.edu.learning.core.EduUtils; -import com.jetbrains.edu.learning.checker.StudyExecutor; -import com.jetbrains.edu.learning.checker.StudyTestRunner; import com.jetbrains.edu.learning.courseFormat.*; import com.jetbrains.edu.learning.editor.StudyEditor; import com.jetbrains.edu.learning.ui.StudyProgressToolWindowFactory; @@ -460,6 +460,18 @@ public class StudyUtils { return null; } + @Nullable + public static StudyTwitterPluginConfigurator getTwitterConfigurator(@NotNull final Project project) { + StudyTwitterPluginConfigurator[] extensions = StudyTwitterPluginConfigurator.EP_NAME.getExtensions(); + for (StudyTwitterPluginConfigurator extension: extensions) { + if (extension.accept(project)) { + return extension; + } + } + return null; + } + + public static String getTaskText(@NotNull final Project project) { VirtualFile[] files = FileEditorManager.getInstance(project).getSelectedFiles(); TaskFile taskFile = null; diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/twitter/StudyTwitterAction.java b/python/educational-core/student/src/com/jetbrains/edu/learning/twitter/StudyTwitterAction.java index dd74afa0d273..b07a411d0b56 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/twitter/StudyTwitterAction.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/twitter/StudyTwitterAction.java @@ -2,14 +2,11 @@ package com.jetbrains.edu.learning.twitter; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; -import com.jetbrains.edu.learning.StudyPluginConfigurator; -import com.jetbrains.edu.learning.StudyUtils; +import com.jetbrains.edu.learning.StudyTwitterPluginConfigurator; import com.jetbrains.edu.learning.actions.StudyAfterCheckAction; import com.jetbrains.edu.learning.courseFormat.StudyStatus; import com.jetbrains.edu.learning.courseFormat.Task; import org.jetbrains.annotations.NotNull; -import twitter4j.Twitter; -import twitter4j.TwitterException; /** * Action that provide tweeting functionality to plugin. @@ -20,30 +17,17 @@ import twitter4j.TwitterException; */ public class StudyTwitterAction extends StudyAfterCheckAction { Logger LOG = Logger.getInstance(StudyTwitterAction.class); + private StudyTwitterPluginConfigurator myConfigurator; + + public StudyTwitterAction(@NotNull final StudyTwitterPluginConfigurator configurator) { + myConfigurator = configurator; + } + @Override public void run(@NotNull Project project, @NotNull Task solvedTask, StudyStatus statusBeforeCheck) { - try { - StudyPluginConfigurator configurator = StudyUtils.getConfigurator(project); - if (configurator == null) { - LOG.warn("Plugin configurator not found"); - return; - } - - if (configurator.askToTweet(project, solvedTask, statusBeforeCheck)) { - boolean isAuthorized = !configurator.getTwitterAccessToken(project).isEmpty(); - Twitter twitter = StudyTwitterUtils.getTwitter(configurator.getConsumerKey(project), configurator.getConsumerSecret(project)); - StudyTwitterUtils.configureTwitter(twitter, project, isAuthorized); - StudyTwitterUtils.TwitterDialogPanel panel = configurator.getTweetDialogPanel(solvedTask); - if (panel != null) { - StudyTwitterUtils.showPostTweetDialogAndPostTweet(twitter, panel); - } - else { - LOG.warn("Plugin didn't provide twitter panel"); - } - } - } - catch (TwitterException e) { - LOG.warn(e.getMessage()); + + if (myConfigurator.askToTweet(project, solvedTask, statusBeforeCheck)) { + StudyTwitterUtils.createTwitterDialogAndShow(project, myConfigurator, solvedTask); } } } diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/twitter/StudyTwitterUtils.java b/python/educational-core/student/src/com/jetbrains/edu/learning/twitter/StudyTwitterUtils.java index 3fdab6b6a761..1192e7bea612 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/twitter/StudyTwitterUtils.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/twitter/StudyTwitterUtils.java @@ -4,13 +4,17 @@ import com.intellij.ide.BrowserUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.DialogBuilder; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.InputValidatorEx; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.DocumentAdapter; import com.intellij.ui.components.JBScrollPane; -import com.jetbrains.edu.learning.StudyPluginConfigurator; +import com.jetbrains.edu.learning.StudyTwitterPluginConfigurator; import com.jetbrains.edu.learning.StudyUtils; +import com.jetbrains.edu.learning.courseFormat.Task; +import org.apache.http.HttpStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import twitter4j.StatusUpdate; @@ -24,6 +28,7 @@ import twitter4j.conf.ConfigurationBuilder; import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; +import java.awt.*; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -32,32 +37,10 @@ import java.io.InputStream; public class StudyTwitterUtils { private static final Logger LOG = Logger.getInstance(StudyTwitterUtils.class); - - /** - * Configure twitter instance: authorize if needed or set access token and token secret provided by configurator. - * @param twitter - * @param project - * @param isAuthorized - * @throws TwitterException - */ - public static void configureTwitter(@NotNull final Twitter twitter, @NotNull final Project project, - final boolean isAuthorized) throws TwitterException { - if (!isAuthorized) { - authorize(project, twitter); - } - else { - StudyPluginConfigurator configurator = StudyUtils.getConfigurator(project); - if (configurator != null) { - getTwitterForAuthorizedApp(twitter, configurator.getTwitterAccessToken(project), configurator.getTwitterTokenSecret(project)); - } - } - } - + /** * Set consumer key and secret. - * @param consumerKey - * @param consumerSecret - * @return + * @return Twitter instance with consumer key and secret set. */ @NotNull public static Twitter getTwitter(@NotNull final String consumerKey, @NotNull final String consumerSecret) { @@ -69,116 +52,222 @@ public class StudyTwitterUtils { /** * Set access token and token secret in Twitter instance - * @param twitter - * @param accessToken - * @param tokenSecret */ - private static void getTwitterForAuthorizedApp(Twitter twitter, @NotNull String accessToken, - @NotNull String tokenSecret) { + private static void setAuthInfoInTwitter(Twitter twitter, @NotNull String accessToken, + @NotNull String tokenSecret) { AccessToken token = new AccessToken(accessToken, tokenSecret); twitter.setOAuthAccessToken(token); } - /** - * Authorize user and save tokens by StudyPluginConfigurator#storeTwitterTokens - * @param project - * @param twitter - * @throws TwitterException - */ - public static void authorize(@NotNull final Project project, @NotNull final Twitter twitter) throws TwitterException { - RequestToken requestToken = twitter.getOAuthRequestToken(); - BrowserUtil.browse(requestToken.getAuthorizationURL()); - + public static void createTwitterDialogAndShow(@NotNull Project project, + @NotNull final StudyTwitterPluginConfigurator configurator, + @NotNull Task task) { ApplicationManager.getApplication().invokeLater(() -> { - String pin = Messages.showInputDialog("Twitter PIN:", "Twitter Authorization", null, "", null); - try { - AccessToken token; - if (pin != null && pin.length() > 0) { - token = twitter.getOAuthAccessToken(requestToken, pin); + DialogWrapper.DoNotAskOption doNotAskOption = createDoNotAskOption(project, configurator); + StudyTwitterUtils.TwitterDialogPanel panel = configurator.getTweetDialogPanel(task); + if (panel != null) { + TwitterDialogWrapper wrapper = new TwitterDialogWrapper(project, panel, doNotAskOption); + wrapper.setDoNotAskOption(doNotAskOption); + panel.addTextFieldVerifier(createTextFieldLengthDocumentListener(wrapper, panel)); + + if (wrapper.showAndGet()) { + try { + boolean isAuthorized = !configurator.getTwitterAccessToken(project).isEmpty(); + Twitter twitter = getTwitter(configurator.getConsumerKey(project), configurator.getConsumerSecret(project)); + if (!isAuthorized) { + authorizeAndUpdateStatus(project, twitter, panel); + } + else { + setAuthInfoInTwitter(twitter, configurator.getTwitterAccessToken(project), configurator.getTwitterTokenSecret(project)); + updateStatus(panel, twitter); + } + } + catch (TwitterException | IOException e) { + LOG.warn(e.getMessage()); + Messages.showErrorDialog("Status wasn\'t updated. Please, check internet connection and try again", "Twitter"); + } } else { - token = twitter.getOAuthAccessToken(); - } - StudyPluginConfigurator configurator = StudyUtils.getConfigurator(project); - if (configurator != null) { - configurator.storeTwitterTokens(project, token.getToken(), token.getTokenSecret()); - } - else { - LOG.warn("Plugin configurator not found"); - } - } - catch (TwitterException e) { - if (401 == e.getStatusCode()) { - LOG.warn("Unable to get the access token."); - } - else { - LOG.warn(e.getMessage()); + LOG.warn("Panel is null"); } } }); } + + private static DialogWrapper.DoNotAskOption createDoNotAskOption(@NotNull final Project project, + @NotNull final StudyTwitterPluginConfigurator configurator) { + return new DialogWrapper.DoNotAskOption() { + @Override + public boolean isToBeShown() { + return true; + } + + @Override + public void setToBeShown(boolean toBeShown, int exitCode) { + if (exitCode == DialogWrapper.CANCEL_EXIT_CODE || exitCode == DialogWrapper.OK_EXIT_CODE) { + configurator.setAskToTweet(project, toBeShown); + } + } + + @Override + public boolean canBeHidden() { + return true; + } + + @Override + public boolean shouldSaveOptionsOnCancel() { + return true; + } + + @NotNull + @Override + public String getDoNotShowMessage() { + return "Never ask me to tweet"; + } + }; + } + + /** + * Post on twitter media and text from panel + * @param panel shown to user and used to provide data to post + */ + public static void updateStatus(StudyTwitterUtils.TwitterDialogPanel panel, Twitter twitter) throws IOException, TwitterException { + StatusUpdate update = new StatusUpdate(panel.getMessage()); + InputStream e = panel.getMediaSource(); + if (e != null) { + File imageFile = FileUtil.createTempFile("twitter_media", panel.getMediaExtension()); + FileUtil.copy(e, new FileOutputStream(imageFile)); + update.media(imageFile); + } + + twitter.updateStatus(update); + BrowserUtil.browse("https://twitter.com/"); + } + /** * Show twitter dialog, asking user to tweet about his achievements. Post tweet with provided by panel * media and text. * As a result of succeeded tweet twitter website is opened in default browser. - * @param twitter - * @param twitterDialogPanel */ - public static void showPostTweetDialogAndPostTweet(@NotNull Twitter twitter, @NotNull final TwitterDialogPanel twitterDialogPanel) { + public static void authorizeAndUpdateStatus(@NotNull final Project project, @NotNull final Twitter twitter, + @NotNull final StudyTwitterUtils.TwitterDialogPanel panel) throws TwitterException { + RequestToken requestToken = twitter.getOAuthRequestToken(); + BrowserUtil.browse(requestToken.getAuthorizationURL()); + ApplicationManager.getApplication().invokeLater(() -> { - DialogBuilder builder = new DialogBuilder(); - twitterDialogPanel.addTextFieldVerifier(createTextFieldLengthDocumentListener(builder, twitterDialogPanel)); - builder.title("Twitter"); - builder.addOkAction().setText("Tweet"); - builder.addCancelAction(); - builder.setCenterPanel(new JBScrollPane(twitterDialogPanel)); - builder.resizable(true); - if (builder.showAndGet()) { - StatusUpdate update = new StatusUpdate(twitterDialogPanel.getMessage()); + String pin = createAndShowPinDialog(); + if (pin != null) { try { - InputStream inputStream = twitterDialogPanel.getMediaSource(); - if (inputStream != null) { - File imageFile = FileUtil.createTempFile("twitter_media", "gif"); - - FileUtil.copy(inputStream, new FileOutputStream(imageFile)); - update.media(imageFile); + AccessToken token = twitter.getOAuthAccessToken(requestToken, pin); + StudyTwitterPluginConfigurator configurator = StudyUtils.getTwitterConfigurator(project); + if (configurator != null) { + configurator.storeTwitterTokens(project, token.getToken(), token.getTokenSecret()); + updateStatus(panel, twitter); + } + else { + LOG.warn("No twitter configurator is provided for the plugin"); } - twitter.updateStatus(update); - BrowserUtil.browse("https://twitter.com/"); } - catch (IOException | TwitterException e) { + catch (TwitterException e) { + if (e.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) { + LOG.warn("Unable to get the access token."); + LOG.warn(e.getMessage()); + } + } + catch (IOException e) { LOG.warn(e.getMessage()); - Messages.showErrorDialog("Status wasn't updated. Please, check internet connection and try again", "Twitter"); } } }); } + public static String createAndShowPinDialog() { + return Messages.showInputDialog("Twitter PIN:", "Twitter Authorization", null, "", new InputValidatorEx() { + @Nullable + @Override + public String getErrorText(String inputString) { + inputString = inputString.trim(); + if (inputString.isEmpty()) { + return "PIN shouldn't be empty."; + } + if (!isNumeric(inputString)) { + return "PIN should be numeric."; + } + return null; + } + + @Override + public boolean checkInput(String inputString) { + return getErrorText(inputString) == null; + } + + @Override + public boolean canClose(String inputString) { + return true; + } + + private boolean isNumeric(@NotNull final String string) { + for (char c: string.toCharArray()) { + if (!StringUtil.isDecimalDigit(c)) { + return false; + } + } + return true; + } + }); + } + /** * Listener updates label indicating remaining symbols number like in twitter. - * @param builder - * @param panel - * @return */ - public static DocumentListener createTextFieldLengthDocumentListener(@NotNull DialogBuilder builder, @NotNull final TwitterDialogPanel panel) { + private static DocumentListener createTextFieldLengthDocumentListener(@NotNull TwitterDialogWrapper builder, @NotNull final StudyTwitterUtils.TwitterDialogPanel panel) { return new DocumentAdapter() { @Override protected void textChanged(DocumentEvent e) { int length = e.getDocument().getLength(); if (length > 140 || length == 0) { - builder.setOkActionEnabled(false); + builder.setOKActionEnabled(false); panel.getRemainSymbolsLabel().setText("" + String.valueOf(140 - length) + ""); - } - else { - builder.setOkActionEnabled(true); + } else { + builder.setOKActionEnabled(true); panel.getRemainSymbolsLabel().setText(String.valueOf(140 - length)); } - + } }; } + /** + * Dialog wrapper class with DoNotAsl option for asking user to tweet. + * */ + private static class TwitterDialogWrapper extends DialogWrapper { + private StudyTwitterUtils.TwitterDialogPanel myPanel; + + TwitterDialogWrapper(@Nullable Project project, @NotNull StudyTwitterUtils.TwitterDialogPanel panel, DoNotAskOption doNotAskOption) { + super(project); + setTitle("Twitter"); + setDoNotAskOption(doNotAskOption); + setOKButtonText("Tweet"); + setCancelButtonText("No"); + setResizable(true); + Dimension preferredSize = panel.getPreferredSize(); + setSize((int) preferredSize.getHeight(), (int) preferredSize.getWidth()); + myPanel = panel; + init(); + } + + public void setOKActionEnabled(boolean isEnabled) { + super.setOKActionEnabled(isEnabled); + } + + @Nullable + @Override + protected JComponent createCenterPanel() { + return new JBScrollPane(myPanel); + } + } + /** * Class provides structure for twitter dialog panel */ @@ -186,25 +275,23 @@ public class StudyTwitterUtils { /** * Provides tweet text - * @return */ @NotNull public abstract String getMessage(); /** - * * @return Input stream of media should be posted or null if there's nothing to post */ @Nullable public abstract InputStream getMediaSource(); + + @Nullable public abstract String getMediaExtension(); /** - * * @return label that will be used to show remained symbol number */ @NotNull public abstract JLabel getRemainSymbolsLabel(); /** * Api to add document listener to field containing tweet text - * @param documentListener */ public abstract void addTextFieldVerifier(@NotNull final DocumentListener documentListener);