Browse Source

Merge remote-tracking branch 'refs/remotes/DMDirc/master'

pull/449/head
Greg Holmes 8 years ago
parent
commit
6acd49b5cd
68 changed files with 911 additions and 788 deletions
  1. 0
    3
      activewindow/build.gradle
  2. 0
    32
      activewindow/plugin.config
  3. 0
    85
      activewindow/src/com/dmdirc/addons/activewindow/ActiveCommand.java
  4. 0
    67
      activewindow/src/com/dmdirc/addons/activewindow/ActiveWindowManager.java
  5. 0
    68
      activewindow/src/com/dmdirc/addons/activewindow/ActiveWindowMessageSink.java
  6. 0
    89
      activewindow/test/com/dmdirc/addons/activewindow/ActiveCommandTest.java
  7. 0
    80
      activewindow/test/com/dmdirc/addons/activewindow/ActiveWindowMessageSinkTest.java
  8. 2
    2
      audio/src/com/dmdirc/addons/audio/AudioCommand.java
  9. 2
    3
      build.gradle
  10. 4
    8
      calc/src/com/dmdirc/addons/calc/CalcCommand.java
  11. 4
    1
      channelwho/test/com/dmdirc/addons/channelwho/ChannelWhoManagerTest.java
  12. 8
    7
      channelwho/test/com/dmdirc/addons/channelwho/ConnectionHandlerTest.java
  13. 73
    79
      conditional_execute/src/com/dmdirc/addons/conditional_execute/ConditionalExecuteCommand.java
  14. 11
    3
      conditional_execute/test/com/dmdirc/addons/conditional_execute/ConditionalExecuteCommandTest.java
  15. 0
    4
      dcc/src/com/dmdirc/addons/dcc/ChatContainer.java
  16. 3
    11
      dcc/src/com/dmdirc/addons/dcc/DCCCommand.java
  17. 0
    4
      dcc/src/com/dmdirc/addons/dcc/DCCFrameContainer.java
  18. 0
    6
      dcc/src/com/dmdirc/addons/dcc/DCCManager.java
  19. 1
    1
      dcop/src/com/dmdirc/addons/dcop/DcopCommand.java
  20. 2
    2
      debug/src/com/dmdirc/addons/debug/Debug.java
  21. 0
    3
      debug/src/com/dmdirc/addons/debug/RawWindow.java
  22. 6
    7
      debug/src/com/dmdirc/addons/debug/RawWindowFactory.java
  23. 5
    4
      debug/src/com/dmdirc/addons/debug/commands/Benchmark.java
  24. 6
    2
      debug/src/com/dmdirc/addons/debug/commands/EventBusViewer.java
  25. 10
    8
      debug/test/com/dmdirc/addons/debug/DebugTest.java
  26. 3
    3
      dns/src/com/dmdirc/addons/dns/DNSCommand.java
  27. 4
    4
      exec/src/com/dmdirc/addons/exec/ExecCommand.java
  28. 4
    0
      logging/res/META-INF/format.yml
  29. 26
    2
      logging/src/com/dmdirc/addons/logging/HistoricalLineRestoredEvent.java
  30. 7
    8
      logging/src/com/dmdirc/addons/logging/LoggingCommand.java
  31. 13
    12
      logging/src/com/dmdirc/addons/logging/LoggingManager.java
  32. 2
    3
      nma/src/com/dmdirc/addons/nma/NotifyMyAndroidCommand.java
  33. 5
    8
      notifications/src/com/dmdirc/addons/notifications/NotificationCommand.java
  34. 6
    7
      nowplaying/src/com/dmdirc/addons/nowplaying/NowPlayingCommand.java
  35. 5
    6
      osd/src/com/dmdirc/addons/osd/OsdCommand.java
  36. 3
    3
      parserdebug/src/com/dmdirc/addons/parserdebug/ParserDebugCommand.java
  37. 4
    20
      redirect/src/com/dmdirc/addons/redirect/FakeWriteableFrameContainer.java
  38. 1
    6
      redirect/src/com/dmdirc/addons/redirect/RedirectCommand.java
  39. 28
    32
      scriptplugin/src/com/dmdirc/addons/scriptplugin/ScriptCommand.java
  40. 4
    0
      tabcompletion_bash/res/META-INF/format.yml
  41. 19
    27
      tabcompletion_bash/src/com/dmdirc/addons/tabcompletion_bash/BashDisambiguationEvent.java
  42. 2
    2
      tabcompletion_bash/src/com/dmdirc/addons/tabcompletion_bash/BashStyle.java
  43. 6
    7
      time/src/com/dmdirc/addons/time/TimerCommand.java
  44. 22
    16
      time/test/com/dmdirc/addons/time/TimerCommandTest.java
  45. 2
    1
      ui_swing/plugin.config
  46. 25
    9
      ui_swing/src/com/dmdirc/addons/ui_swing/UIUtilities.java
  47. 1
    2
      ui_swing/src/com/dmdirc/addons/ui_swing/commands/PopInCommand.java
  48. 1
    2
      ui_swing/src/com/dmdirc/addons/ui_swing/commands/PopOutCommand.java
  49. 1
    2
      ui_swing/src/com/dmdirc/addons/ui_swing/dialogs/channelsetting/TopicDisplayPane.java
  50. 1
    4
      ui_swing/src/com/dmdirc/addons/ui_swing/dialogs/channelsetting/TopicLabel.java
  51. 1
    0
      ui_swing/src/com/dmdirc/addons/ui_swing/dialogs/globalautocommand/GlobalAutoCommandDialog.java
  52. 31
    2
      ui_swing/src/com/dmdirc/addons/ui_swing/textpane/BackgroundPainter.java
  53. 1
    1
      ui_swing/src/com/dmdirc/addons/ui_swing/textpane/TextPane.java
  54. 2
    2
      ui_swing/test/com/dmdirc/addons/ui_swing/components/GenericTableModelTest.java
  55. 4
    0
      ui_web2/build.gradle
  56. 32
    0
      ui_web2/plugin.config
  57. 1
    0
      ui_web2/res/META-INF/services/org.eclipse.jetty.http.HttpFieldPreEncoder
  58. 26
    0
      ui_web2/res/jetty-logging.properties
  59. 10
    0
      ui_web2/res/www/index.html
  60. 20
    0
      ui_web2/res/www/js/socket.js
  61. 74
    0
      ui_web2/src/com/dmdirc/addons/ui_web2/InitialStateProducer.java
  62. 22
    7
      ui_web2/src/com/dmdirc/addons/ui_web2/WebServer.java
  63. 88
    0
      ui_web2/src/com/dmdirc/addons/ui_web2/WebSocketController.java
  64. 72
    0
      ui_web2/src/com/dmdirc/addons/ui_web2/WebSocketHandler.java
  65. 78
    0
      ui_web2/src/com/dmdirc/addons/ui_web2/WebUiModule.java
  66. 12
    11
      ui_web2/src/com/dmdirc/addons/ui_web2/WebUiPlugin.java
  67. 52
    0
      ui_web2/src/com/dmdirc/addons/ui_web2/serialisers/BackBufferSerializer.java
  68. 53
    0
      ui_web2/src/com/dmdirc/addons/ui_web2/serialisers/WindowModelSerialiser.java

+ 0
- 3
activewindow/build.gradle View File

1
-dependencies {
2
-  compile plugin('ui_swing')
3
-}

+ 0
- 32
activewindow/plugin.config View File

1
-# This is a DMDirc configuration file.
2
-
3
-# This section indicates which sections below take key/value
4
-# pairs, rather than a simple list. It should be placed above
5
-# any sections that take key/values.
6
-keysections:
7
-  metadata
8
-  updates
9
-  version
10
-  requires
11
-
12
-metadata:
13
-  author=Greboid <greg@dmdirc.com>
14
-  mainclass=com.dmdirc.addons.activewindow.ActiveWindowPlugin
15
-  description=Provides an active window command to the swing UI
16
-  name=activewindow
17
-  nicename=Active Window
18
-
19
-updates:
20
-  id=66
21
-
22
-requires:
23
-  parent=ui_swing
24
-
25
-version:
26
-  friendly=1.0
27
-
28
-provides:
29
-  active command
30
-
31
-required-services:
32
-  swing ui

+ 0
- 85
activewindow/src/com/dmdirc/addons/activewindow/ActiveCommand.java View File

1
-/*
2
- * Copyright (c) 2006-2015 DMDirc Developers
3
- *
4
- * Permission is hereby granted, free of charge, to any person obtaining a copy
5
- * of this software and associated documentation files (the "Software"), to deal
6
- * in the Software without restriction, including without limitation the rights
7
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- * copies of the Software, and to permit persons to whom the Software is
9
- * furnished to do so, subject to the following conditions:
10
- *
11
- * The above copyright notice and this permission notice shall be included in
12
- * all copies or substantial portions of the Software.
13
- *
14
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
- * SOFTWARE.
21
- */
22
-
23
-package com.dmdirc.addons.activewindow;
24
-
25
-import com.dmdirc.addons.ui_swing.interfaces.ActiveFrameManager;
26
-import com.dmdirc.commandparser.BaseCommandInfo;
27
-import com.dmdirc.commandparser.CommandArguments;
28
-import com.dmdirc.commandparser.CommandInfo;
29
-import com.dmdirc.commandparser.CommandType;
30
-import com.dmdirc.commandparser.commands.Command;
31
-import com.dmdirc.commandparser.commands.IntelligentCommand;
32
-import com.dmdirc.commandparser.commands.context.CommandContext;
33
-import com.dmdirc.interfaces.CommandController;
34
-import com.dmdirc.interfaces.WindowModel;
35
-import com.dmdirc.ui.input.AdditionalTabTargets;
36
-import com.dmdirc.ui.input.TabCompleterUtils;
37
-
38
-import javax.annotation.Nonnull;
39
-import javax.inject.Inject;
40
-
41
-/**
42
- * Executes another command as if it were executed in the active window.
43
- */
44
-public class ActiveCommand extends Command implements IntelligentCommand {
45
-
46
-    /** A command info object for this command. */
47
-    public static final CommandInfo INFO = new BaseCommandInfo("active",
48
-            "active <command> - executes the command as though it had been "
49
-            + "executed in the active window", CommandType.TYPE_GLOBAL);
50
-    /** Active frame manager. */
51
-    private final ActiveFrameManager activeFrameManager;
52
-    /** Tab-completer utilities. */
53
-    private final TabCompleterUtils tabUtils;
54
-
55
-    /**
56
-     * Creates a new active command.
57
-     *
58
-     * @param controller          The controller to use for command information.
59
-     * @param activeFrameManager The active window manager
60
-     */
61
-    @Inject
62
-    public ActiveCommand(
63
-            final CommandController controller,
64
-            final ActiveFrameManager activeFrameManager,
65
-            final TabCompleterUtils tabUtils) {
66
-        super(controller);
67
-
68
-        this.activeFrameManager = activeFrameManager;
69
-        this.tabUtils = tabUtils;
70
-    }
71
-
72
-    @Override
73
-    public void execute(@Nonnull final WindowModel origin,
74
-            final CommandArguments args, final CommandContext context) {
75
-        activeFrameManager.getActiveFrame().ifPresent(f -> f.getContainer().getCommandParser()
76
-                .parseCommand(f.getContainer(), args.getArgumentsAsString()));
77
-    }
78
-
79
-    @Override
80
-    public AdditionalTabTargets getSuggestions(final int arg,
81
-            final IntelligentCommandContext context) {
82
-        return tabUtils.getIntelligentResults(arg, context, 0);
83
-    }
84
-
85
-}

+ 0
- 67
activewindow/src/com/dmdirc/addons/activewindow/ActiveWindowManager.java View File

1
-/*
2
- * Copyright (c) 2006-2015 DMDirc Developers
3
- *
4
- * Permission is hereby granted, free of charge, to any person obtaining a copy
5
- * of this software and associated documentation files (the "Software"), to deal
6
- * in the Software without restriction, including without limitation the rights
7
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- * copies of the Software, and to permit persons to whom the Software is
9
- * furnished to do so, subject to the following conditions:
10
- *
11
- * The above copyright notice and this permission notice shall be included in
12
- * all copies or substantial portions of the Software.
13
- *
14
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
- * SOFTWARE.
21
- */
22
-
23
-package com.dmdirc.addons.activewindow;
24
-
25
-import com.dmdirc.ui.messages.sink.MessageSinkManager;
26
-
27
-import javax.inject.Inject;
28
-
29
-/**
30
- * Manages the active window sink.
31
- */
32
-public class ActiveWindowManager {
33
-
34
-    /** The message sink to register and unregister. */
35
-    private final ActiveWindowMessageSink sink;
36
-    /** The manager to add and remove the sink from. */
37
-    private final MessageSinkManager sinkManager;
38
-
39
-    /**
40
-     * Creates a new instance of {@link ActiveWindowManager}.
41
-     *
42
-     * @param sinkManager The manager to add and remove sinks from.
43
-     * @param sink        The sink to be added and removed.
44
-     */
45
-    @Inject
46
-    public ActiveWindowManager(
47
-            final MessageSinkManager sinkManager,
48
-            final ActiveWindowMessageSink sink) {
49
-        this.sink = sink;
50
-        this.sinkManager = sinkManager;
51
-    }
52
-
53
-    /**
54
-     * Registers the sink with the manager.
55
-     */
56
-    public void register() {
57
-        sinkManager.addSink(sink);
58
-    }
59
-
60
-    /**
61
-     * Unregisters the sink from the manager.
62
-     */
63
-    public void unregister() {
64
-        sinkManager.removeSink(sink);
65
-    }
66
-
67
-}

+ 0
- 68
activewindow/src/com/dmdirc/addons/activewindow/ActiveWindowMessageSink.java View File

1
-/*
2
- * Copyright (c) 2006-2015 DMDirc Developers
3
- *
4
- * Permission is hereby granted, free of charge, to any person obtaining a copy
5
- * of this software and associated documentation files (the "Software"), to deal
6
- * in the Software without restriction, including without limitation the rights
7
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- * copies of the Software, and to permit persons to whom the Software is
9
- * furnished to do so, subject to the following conditions:
10
- *
11
- * The above copyright notice and this permission notice shall be included in
12
- * all copies or substantial portions of the Software.
13
- *
14
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
- * SOFTWARE.
21
- */
22
-
23
-package com.dmdirc.addons.activewindow;
24
-
25
-import com.dmdirc.addons.ui_swing.interfaces.ActiveFrameManager;
26
-import com.dmdirc.interfaces.WindowModel;
27
-import com.dmdirc.ui.messages.sink.MessageSink;
28
-import com.dmdirc.ui.messages.sink.MessageSinkManager;
29
-
30
-import java.util.Date;
31
-import java.util.regex.Pattern;
32
-
33
-import javax.inject.Inject;
34
-
35
-/**
36
- * A message sink which passes messages onto the active swing window.
37
- */
38
-public class ActiveWindowMessageSink implements MessageSink {
39
-
40
-    /** The pattern to use to match this sink. */
41
-    private static final Pattern PATTERN = Pattern.compile("active");
42
-    /** Active frame manager. */
43
-    private final ActiveFrameManager activeFrameManager;
44
-
45
-    /**
46
-     * Creates a new ActiveWindowMessageSink for the specified mainframe.
47
-     *
48
-     * @param activeFrameManager Active frame manager.
49
-     */
50
-    @Inject
51
-    public ActiveWindowMessageSink(final ActiveFrameManager activeFrameManager) {
52
-        this.activeFrameManager = activeFrameManager;
53
-    }
54
-
55
-    @Override
56
-    public Pattern getPattern() {
57
-        return PATTERN;
58
-    }
59
-
60
-    @Override
61
-    public void handleMessage(final MessageSinkManager dispatcher,
62
-            final WindowModel source, final String[] patternMatches,
63
-            final Date date, final String messageType, final Object... args) {
64
-        activeFrameManager.getActiveFrame()
65
-                .ifPresent(f -> f.getContainer().addLine(messageType, date, args));
66
-    }
67
-
68
-}

+ 0
- 89
activewindow/test/com/dmdirc/addons/activewindow/ActiveCommandTest.java View File

1
-/*
2
- * Copyright (c) 2006-2015 DMDirc Developers
3
- *
4
- * Permission is hereby granted, free of charge, to any person obtaining a copy
5
- * of this software and associated documentation files (the "Software"), to deal
6
- * in the Software without restriction, including without limitation the rights
7
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- * copies of the Software, and to permit persons to whom the Software is
9
- * furnished to do so, subject to the following conditions:
10
- *
11
- * The above copyright notice and this permission notice shall be included in
12
- * all copies or substantial portions of the Software.
13
- *
14
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
- * SOFTWARE.
21
- */
22
-
23
-package com.dmdirc.addons.activewindow;
24
-
25
-import com.dmdirc.addons.ui_swing.components.frames.TextFrame;
26
-import com.dmdirc.addons.ui_swing.interfaces.ActiveFrameManager;
27
-import com.dmdirc.commandparser.CommandArguments;
28
-import com.dmdirc.commandparser.commands.IntelligentCommand.IntelligentCommandContext;
29
-import com.dmdirc.commandparser.commands.context.CommandContext;
30
-import com.dmdirc.commandparser.parsers.CommandParser;
31
-import com.dmdirc.interfaces.CommandController;
32
-import com.dmdirc.interfaces.WindowModel;
33
-import com.dmdirc.ui.input.TabCompleterUtils;
34
-
35
-import java.util.Optional;
36
-
37
-import org.junit.Before;
38
-import org.junit.Test;
39
-import org.junit.runner.RunWith;
40
-import org.mockito.Mock;
41
-import org.mockito.runners.MockitoJUnitRunner;
42
-
43
-import static org.mockito.Mockito.never;
44
-import static org.mockito.Mockito.verify;
45
-import static org.mockito.Mockito.when;
46
-
47
-@RunWith(MockitoJUnitRunner.class)
48
-public class ActiveCommandTest {
49
-
50
-    @Mock private IntelligentCommandContext intelligentCommandContext;
51
-    @Mock private CommandParser commandParser;
52
-    @Mock private CommandController commandController;
53
-    @Mock private ActiveFrameManager activeFrameManager;
54
-    @Mock private TabCompleterUtils tabCompleterUtils;
55
-    @Mock private WindowModel frameContainer;
56
-    @Mock private TextFrame textFrame;
57
-    @Mock private CommandArguments commandArguments;
58
-    @Mock private CommandContext commandContext;
59
-    private ActiveCommand activeCommand;
60
-
61
-    @Before
62
-    public void setUp() throws Exception {
63
-        when(textFrame.getContainer()).thenReturn(frameContainer);
64
-        when(frameContainer.getCommandParser()).thenReturn(commandParser);
65
-        when(commandArguments.getArgumentsAsString()).thenReturn("some arguments");
66
-        activeCommand = new ActiveCommand(commandController, activeFrameManager, tabCompleterUtils);
67
-    }
68
-
69
-    @Test
70
-    public void testExecute_NoActive() throws Exception {
71
-        when(activeFrameManager.getActiveFrame()).thenReturn(Optional.empty());
72
-        activeCommand.execute(frameContainer, commandArguments, commandContext);
73
-        verify(commandParser, never())
74
-                .parseCommand(frameContainer, commandArguments.getArgumentsAsString());
75
-    }
76
-
77
-    @Test
78
-    public void testExecute_Active() throws Exception {
79
-        when(activeFrameManager.getActiveFrame()).thenReturn(Optional.of(textFrame));
80
-        activeCommand.execute(frameContainer, commandArguments, commandContext);
81
-        verify(commandParser).parseCommand(frameContainer, commandArguments.getArgumentsAsString());
82
-    }
83
-
84
-    @Test
85
-    public void testGetSuggestions() throws Exception {
86
-        activeCommand.getSuggestions(1, intelligentCommandContext);
87
-        verify(tabCompleterUtils).getIntelligentResults(1, intelligentCommandContext, 0);
88
-    }
89
-}

+ 0
- 80
activewindow/test/com/dmdirc/addons/activewindow/ActiveWindowMessageSinkTest.java View File

1
-/*
2
- * Copyright (c) 2006-2015 DMDirc Developers
3
- *
4
- * Permission is hereby granted, free of charge, to any person obtaining a copy
5
- * of this software and associated documentation files (the "Software"), to deal
6
- * in the Software without restriction, including without limitation the rights
7
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- * copies of the Software, and to permit persons to whom the Software is
9
- * furnished to do so, subject to the following conditions:
10
- *
11
- * The above copyright notice and this permission notice shall be included in
12
- * all copies or substantial portions of the Software.
13
- *
14
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
- * SOFTWARE.
21
- */
22
-
23
-package com.dmdirc.addons.activewindow;
24
-
25
-import com.dmdirc.addons.ui_swing.components.frames.TextFrame;
26
-import com.dmdirc.addons.ui_swing.interfaces.ActiveFrameManager;
27
-import com.dmdirc.interfaces.WindowModel;
28
-import com.dmdirc.ui.messages.sink.MessageSinkManager;
29
-
30
-import java.util.Date;
31
-import java.util.Optional;
32
-import java.util.regex.Pattern;
33
-
34
-import org.junit.Before;
35
-import org.junit.Test;
36
-import org.junit.runner.RunWith;
37
-import org.mockito.Mock;
38
-import org.mockito.runners.MockitoJUnitRunner;
39
-
40
-import static junit.framework.TestCase.assertEquals;
41
-import static org.mockito.Mockito.never;
42
-import static org.mockito.Mockito.verify;
43
-import static org.mockito.Mockito.when;
44
-
45
-@RunWith(MockitoJUnitRunner.class)
46
-public class ActiveWindowMessageSinkTest {
47
-
48
-    private static final Pattern PATTERN = Pattern.compile("active");
49
-    @Mock private ActiveFrameManager activeFrameManager;
50
-    @Mock private MessageSinkManager messageSinkManager;
51
-    @Mock private WindowModel frameContainer;
52
-    @Mock private TextFrame textFrame;
53
-    @Mock private Date date;
54
-    private ActiveWindowMessageSink sink;
55
-
56
-    @Before
57
-    public void setUp() throws Exception {
58
-        sink = new ActiveWindowMessageSink(activeFrameManager);
59
-        when(textFrame.getContainer()).thenReturn(frameContainer);
60
-    }
61
-
62
-    @Test
63
-    public void testGetPattern() throws Exception {
64
-        assertEquals(PATTERN.toString(), sink.getPattern().toString());
65
-    }
66
-
67
-    @Test
68
-    public void testHandleMessage_NoActive() throws Exception {
69
-        when(activeFrameManager.getActiveFrame()).thenReturn(Optional.empty());
70
-        sink.handleMessage(messageSinkManager, frameContainer, null, date, "type", "message");
71
-        verify(frameContainer, never()).addLine("type", date, "message");
72
-    }
73
-
74
-    @Test
75
-    public void testHandleMessage_Active() throws Exception {
76
-        when(activeFrameManager.getActiveFrame()).thenReturn(Optional.of(textFrame));
77
-        sink.handleMessage(messageSinkManager, frameContainer, null, date, "type", "message");
78
-        verify(frameContainer).addLine("type", date, "message");
79
-    }
80
-}

+ 2
- 2
audio/src/com/dmdirc/addons/audio/AudioCommand.java View File

64
             if (AudioPlayer.isValid(file)) {
64
             if (AudioPlayer.isValid(file)) {
65
                 new AudioPlayer(file).play();
65
                 new AudioPlayer(file).play();
66
             } else {
66
             } else {
67
-                sendLine(origin, args.isSilent(), FORMAT_ERROR, "Invalid file type");
67
+                showError(origin, args.isSilent(), "Invalid file type");
68
             }
68
             }
69
         } else {
69
         } else {
70
-            sendLine(origin, args.isSilent(), FORMAT_ERROR, "File does not exist");
70
+            showError(origin, args.isSilent(), "File does not exist");
71
         }
71
         }
72
     }
72
     }
73
 
73
 

+ 2
- 3
build.gradle View File

30
 
30
 
31
     repositories {
31
     repositories {
32
         mavenCentral()
32
         mavenCentral()
33
-        maven {
34
-            url 'http://artifactory.dmdirc.com/artifactory/repo'
35
-        }
33
+        maven { url 'http://artifactory.dmdirc.com/artifactory/repo' }
34
+        maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
36
     }
35
     }
37
 
36
 
38
     dependencies {
37
     dependencies {

+ 4
- 8
calc/src/com/dmdirc/addons/calc/CalcCommand.java View File

64
             int offset = 0;
64
             int offset = 0;
65
             boolean showexpr = false;
65
             boolean showexpr = false;
66
 
66
 
67
-            if (args.getArguments().length > 0 && args.getArguments()[0]
68
-                    .equals("--showexpr")) {
67
+            if (args.getArguments().length > 0 && "--showexpr".equals(args.getArguments()[0])) {
69
                 showexpr = true;
68
                 showexpr = true;
70
                 offset++;
69
                 offset++;
71
             }
70
             }
75
             final Parser parser = new Parser(lexer);
74
             final Parser parser = new Parser(lexer);
76
             final Evaluator evaluator = new Evaluator(parser.parse());
75
             final Evaluator evaluator = new Evaluator(parser.parse());
77
             final Number result = evaluator.evaluate();
76
             final Number result = evaluator.evaluate();
78
-            sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
79
-                    (showexpr ? input + " = " : "") + result);
77
+            showOutput(origin, args.isSilent(), (showexpr ? input + " = " : "") + result);
80
         } catch (ParseException ex) {
78
         } catch (ParseException ex) {
81
-            sendLine(origin, args.isSilent(), FORMAT_ERROR,
82
-                    "Unable to parse expression: " + ex.getMessage());
79
+            showError(origin, args.isSilent(), "Unable to parse expression: " + ex.getMessage());
83
         } catch (ArithmeticException ex) {
80
         } catch (ArithmeticException ex) {
84
-            sendLine(origin, args.isSilent(), FORMAT_ERROR,
85
-                    "Unable to calculate expression: " + ex.getMessage());
81
+            showError(origin, args.isSilent(), "Unable to calculate expression: " + ex.getMessage());
86
         }
82
         }
87
     }
83
     }
88
 
84
 

+ 4
- 1
channelwho/test/com/dmdirc/addons/channelwho/ChannelWhoManagerTest.java View File

30
 
30
 
31
 import com.google.common.collect.Lists;
31
 import com.google.common.collect.Lists;
32
 
32
 
33
+import java.net.URI;
34
+
33
 import org.junit.Before;
35
 import org.junit.Before;
34
 import org.junit.Test;
36
 import org.junit.Test;
35
 import org.junit.runner.RunWith;
37
 import org.junit.runner.RunWith;
76
 
78
 
77
     @Test
79
     @Test
78
     public void testServerConnectionEvent() throws Exception {
80
     public void testServerConnectionEvent() throws Exception {
79
-        instance.handleServerConnectingEvent(new ServerConnectingEvent(connection2));
81
+        instance.handleServerConnectingEvent(
82
+                new ServerConnectingEvent(connection2, URI.create("irc://foo.bar")));
80
         verify(connectionHandlerFactory).get(connection);
83
         verify(connectionHandlerFactory).get(connection);
81
     }
84
     }
82
 
85
 

+ 8
- 7
channelwho/test/com/dmdirc/addons/channelwho/ConnectionHandlerTest.java View File

55
 import static org.mockito.Matchers.any;
55
 import static org.mockito.Matchers.any;
56
 import static org.mockito.Matchers.anyLong;
56
 import static org.mockito.Matchers.anyLong;
57
 import static org.mockito.Matchers.eq;
57
 import static org.mockito.Matchers.eq;
58
+import static org.mockito.Mockito.doReturn;
58
 import static org.mockito.Mockito.never;
59
 import static org.mockito.Mockito.never;
59
 import static org.mockito.Mockito.verify;
60
 import static org.mockito.Mockito.verify;
60
 import static org.mockito.Mockito.when;
61
 import static org.mockito.Mockito.when;
67
     @Mock private WindowModel windowModel;
68
     @Mock private WindowModel windowModel;
68
     @Mock private DMDircMBassador eventBus;
69
     @Mock private DMDircMBassador eventBus;
69
     @Mock private ScheduledExecutorService scheduledExecutorService;
70
     @Mock private ScheduledExecutorService scheduledExecutorService;
70
-    @Mock private ScheduledFuture scheduledFuture;
71
+    @Mock private ScheduledFuture<?> scheduledFuture;
71
     @Mock private ConnectionManager connectionManager;
72
     @Mock private ConnectionManager connectionManager;
72
     @Mock private Connection connection;
73
     @Mock private Connection connection;
73
     @Mock private GroupChat groupChat;
74
     @Mock private GroupChat groupChat;
81
 
82
 
82
     @Before
83
     @Before
83
     public void setUp() throws Exception {
84
     public void setUp() throws Exception {
84
-        when(scheduledExecutorService.scheduleAtFixedRate(any(Runnable.class), anyLong(), anyLong(),
85
-                any())).thenReturn(scheduledFuture);
85
+        doReturn(scheduledFuture).when(scheduledExecutorService)
86
+                .scheduleAtFixedRate(any(Runnable.class), anyLong(), anyLong(), any());
86
         when(windowModel.getEventBus()).thenReturn(eventBus);
87
         when(windowModel.getEventBus()).thenReturn(eventBus);
87
         when(connection.getWindowModel()).thenReturn(windowModel);
88
         when(connection.getWindowModel()).thenReturn(windowModel);
88
         when(config.getBinder()).thenReturn(configBinder);
89
         when(config.getBinder()).thenReturn(configBinder);
108
         instance.load();
109
         instance.load();
109
         verify(configBinder).bind(instance, ConnectionHandler.class);
110
         verify(configBinder).bind(instance, ConnectionHandler.class);
110
         verify(eventBus).subscribe(instance);
111
         verify(eventBus).subscribe(instance);
111
-        verify(scheduledExecutorService).scheduleAtFixedRate(any(Runnable.class), eq(5l), eq(5l),
112
+        verify(scheduledExecutorService).scheduleAtFixedRate(any(Runnable.class), eq(5L), eq(5L),
112
                 eq(TimeUnit.MILLISECONDS));
113
                 eq(TimeUnit.MILLISECONDS));
113
     }
114
     }
114
 
115
 
124
     public void testHandleWhoInterval() throws Exception {
125
     public void testHandleWhoInterval() throws Exception {
125
         instance.handleWhoInterval(10);
126
         instance.handleWhoInterval(10);
126
         verify(scheduledFuture).cancel(false);
127
         verify(scheduledFuture).cancel(false);
127
-        verify(scheduledExecutorService).scheduleAtFixedRate(any(Runnable.class), eq(5l), eq(5l),
128
+        verify(scheduledExecutorService).scheduleAtFixedRate(any(Runnable.class), eq(5L), eq(5L),
128
                 eq(TimeUnit.MILLISECONDS));
129
                 eq(TimeUnit.MILLISECONDS));
129
-        verify(scheduledExecutorService).scheduleAtFixedRate(any(Runnable.class), eq(10l), eq(10l),
130
+        verify(scheduledExecutorService).scheduleAtFixedRate(any(Runnable.class), eq(10L), eq(10L),
130
                 eq(TimeUnit.MILLISECONDS));
131
                 eq(TimeUnit.MILLISECONDS));
131
     }
132
     }
132
 
133
 
148
 
149
 
149
     @Test
150
     @Test
150
     public void testHandleAwayEvent_WithReason() throws Exception {
151
     public void testHandleAwayEvent_WithReason() throws Exception {
151
-        when(channelUserAwayEvent.getReason()).thenReturn(Optional.ofNullable("reason"));
152
+        when(channelUserAwayEvent.getReason()).thenReturn(Optional.of("reason"));
152
         instance.load();
153
         instance.load();
153
         instance.handleAwayEvent(channelUserAwayEvent);
154
         instance.handleAwayEvent(channelUserAwayEvent);
154
         verify(channelUserAwayEvent, never())
155
         verify(channelUserAwayEvent, never())

+ 73
- 79
conditional_execute/src/com/dmdirc/addons/conditional_execute/ConditionalExecuteCommand.java View File

72
             final String arg = arguments[i].toLowerCase();
72
             final String arg = arguments[i].toLowerCase();
73
             final String nextArg = i + 1 < arguments.length ? arguments[i + 1] : "";
73
             final String nextArg = i + 1 < arguments.length ? arguments[i + 1] : "";
74
 
74
 
75
-            if (arg.equalsIgnoreCase("--help")) {
76
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Usage:");
77
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "");
78
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, cmdname + " <args>");
79
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, cmdname
75
+            if ("--help".equalsIgnoreCase(arg)) {
76
+                showOutput(origin, args.isSilent(), "Usage:");
77
+                showOutput(origin, args.isSilent(), "");
78
+                showOutput(origin, args.isSilent(), cmdname + " <args>");
79
+                showOutput(origin, args.isSilent(), cmdname
80
                         + " --namespace <name> <namespace commands>");
80
                         + " --namespace <name> <namespace commands>");
81
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, cmdname
81
+                showOutput(origin, args.isSilent(), cmdname
82
                         + " --namespace <name> [--inverse] </commandToRun <command args>>");
82
                         + " --namespace <name> [--inverse] </commandToRun <command args>>");
83
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "");
84
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
83
+                showOutput(origin, args.isSilent(), "");
84
+                showOutput(origin, args.isSilent(),
85
                         "Commands can only be specified if no other non-namespace args are given.");
85
                         "Commands can only be specified if no other non-namespace args are given.");
86
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "");
87
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
86
+                showOutput(origin, args.isSilent(), "");
87
+                showOutput(origin, args.isSilent(),
88
                         "When trying to run a command, the namespace will be checked to see if the command can be run.");
88
                         "When trying to run a command, the namespace will be checked to see if the command can be run.");
89
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
89
+                showOutput(origin, args.isSilent(),
90
                         "The checks performed are as follows:");
90
                         "The checks performed are as follows:");
91
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
91
+                showOutput(origin, args.isSilent(),
92
                         "   1) Does the namespace exist? if not, run the command and create the namespace.");
92
                         "   1) Does the namespace exist? if not, run the command and create the namespace.");
93
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
93
+                showOutput(origin, args.isSilent(),
94
                         "   2) Is the namespace inhibited? - Do not run the command.");
94
                         "   2) Is the namespace inhibited? - Do not run the command.");
95
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
95
+                showOutput(origin, args.isSilent(),
96
                         "   3) Is the namespace in forced mode? - Run the command.");
96
                         "   3) Is the namespace in forced mode? - Run the command.");
97
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
97
+                showOutput(origin, args.isSilent(),
98
                         "   4) If --inverse is specified, are we under the limit time? Run the command");
98
                         "   4) If --inverse is specified, are we under the limit time? Run the command");
99
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
99
+                showOutput(origin, args.isSilent(),
100
                         "   5) If --inverse is not specified, are we over the limit time? Run the command");
100
                         "   5) If --inverse is not specified, are we over the limit time? Run the command");
101
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "   6) Do not run the command.");
102
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "");
103
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "General Arguments.");
104
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
101
+                showOutput(origin, args.isSilent(), "   6) Do not run the command.");
102
+                showOutput(origin, args.isSilent(), "");
103
+                showOutput(origin, args.isSilent(), "General Arguments.");
104
+                showOutput(origin, args.isSilent(),
105
                         "  --list                   - List all current namespaces and their status");
105
                         "  --list                   - List all current namespaces and their status");
106
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
106
+                showOutput(origin, args.isSilent(),
107
                         "  --help                   - Print this help.");
107
                         "  --help                   - Print this help.");
108
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
108
+                showOutput(origin, args.isSilent(),
109
                         "  --reset                  - Remove all namespaces.");
109
                         "  --reset                  - Remove all namespaces.");
110
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "");
111
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Useful things:");
112
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
110
+                showOutput(origin, args.isSilent(), "");
111
+                showOutput(origin, args.isSilent(), "Useful things:");
112
+                showOutput(origin, args.isSilent(),
113
                         "  --namespace <name>       - Namespace to modify. If the namespace does not exist, it will be created. Namespaces are not remembered across sessions.");
113
                         "  --namespace <name>       - Namespace to modify. If the namespace does not exist, it will be created. Namespaces are not remembered across sessions.");
114
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "");
115
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Arguments related to a namespace:");
116
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
114
+                showOutput(origin, args.isSilent(), "");
115
+                showOutput(origin, args.isSilent(), "Arguments related to a namespace:");
116
+                showOutput(origin, args.isSilent(),
117
                         "  --settime <time>         - Set the limit time on this namespace. Time can be either a time in seconds, 'now' for now, or 'nowifless' to set to now only if it is currently less.");
117
                         "  --settime <time>         - Set the limit time on this namespace. Time can be either a time in seconds, 'now' for now, or 'nowifless' to set to now only if it is currently less.");
118
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
118
+                showOutput(origin, args.isSilent(),
119
                         "  --delay <seconds>        - Increase the 'limit' time on this namespace by <seconds> seconds");
119
                         "  --delay <seconds>        - Increase the 'limit' time on this namespace by <seconds> seconds");
120
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
120
+                showOutput(origin, args.isSilent(),
121
                         "  --inhibit                - Prevent any attempts at running commands in this namespace from executing");
121
                         "  --inhibit                - Prevent any attempts at running commands in this namespace from executing");
122
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
122
+                showOutput(origin, args.isSilent(),
123
                         "  --force                  - Any future attempts at running commands in this namespace will always execute");
123
                         "  --force                  - Any future attempts at running commands in this namespace will always execute");
124
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
124
+                showOutput(origin, args.isSilent(),
125
                         "  --allow                  - Disable '--force' or '--inhibit' and resume normal operation.");
125
                         "  --allow                  - Disable '--force' or '--inhibit' and resume normal operation.");
126
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
126
+                showOutput(origin, args.isSilent(),
127
                         "  --remove                 - Remove this namespace.");
127
                         "  --remove                 - Remove this namespace.");
128
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
128
+                showOutput(origin, args.isSilent(),
129
                         "  --status                 - Show the status of this namespace.");
129
                         "  --status                 - Show the status of this namespace.");
130
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "");
131
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Arguments when running a command:");
132
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
130
+                showOutput(origin, args.isSilent(), "");
131
+                showOutput(origin, args.isSilent(), "Arguments when running a command:");
132
+                showOutput(origin, args.isSilent(),
133
                         "  --inverse              - Inverse the match against the 'limit' time.");
133
                         "  --inverse              - Inverse the match against the 'limit' time.");
134
                 return;
134
                 return;
135
-            } else if (arg.equalsIgnoreCase("--list")) {
135
+            } else if ("--list".equalsIgnoreCase(arg)) {
136
                 if (namespaces.isEmpty()) {
136
                 if (namespaces.isEmpty()) {
137
-                    sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
137
+                    showOutput(origin, args.isSilent(),
138
                             "There are currently no known namespaces.");
138
                             "There are currently no known namespaces.");
139
                 } else {
139
                 } else {
140
-                    sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Current namespaces: ");
140
+                    showOutput(origin, args.isSilent(), "Current namespaces: ");
141
                     for (final Map.Entry<String, ConditionalExecuteNamespace> e : namespaces.
141
                     for (final Map.Entry<String, ConditionalExecuteNamespace> e : namespaces.
142
                             entrySet()) {
142
                             entrySet()) {
143
-                        sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "    " + e.getValue().
144
-                                toString());
143
+                        showOutput(origin, args.isSilent(),"    " + e.getValue());
145
                     }
144
                     }
146
                 }
145
                 }
147
                 return;
146
                 return;
148
-            } else if (arg.equalsIgnoreCase("--reset")) {
147
+            } else if ("--reset".equalsIgnoreCase(arg)) {
149
                 namespaces.clear();
148
                 namespaces.clear();
150
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "All namespaces removed.");
149
+                showOutput(origin, args.isSilent(), "All namespaces removed.");
151
                 return;
150
                 return;
152
             } else if (namespace == null) {
151
             } else if (namespace == null) {
153
-                if (arg.equalsIgnoreCase("--namespace")) {
152
+                if ("--namespace".equalsIgnoreCase(arg)) {
154
                     if (nextArg.isEmpty()) {
153
                     if (nextArg.isEmpty()) {
155
-                        sendLine(origin, args.isSilent(), FORMAT_ERROR,
156
-                                "Error: You must specify a namespace.");
154
+                        showError(origin, args.isSilent(), "Error: You must specify a namespace.");
157
                         return;
155
                         return;
158
                     } else {
156
                     } else {
159
                         if (!namespaces.containsKey(nextArg.toLowerCase())) {
157
                         if (!namespaces.containsKey(nextArg.toLowerCase())) {
166
                         i++;
164
                         i++;
167
                     }
165
                     }
168
                 } else {
166
                 } else {
169
-                    sendLine(origin, args.isSilent(), FORMAT_ERROR,
167
+                    showError(origin, args.isSilent(),
170
                             "Error: You must specify a namespace first.");
168
                             "Error: You must specify a namespace first.");
171
                     return;
169
                     return;
172
                 }
170
                 }
173
-            } else if (arg.equalsIgnoreCase("--inhibit")) {
171
+            } else if ("--inhibit".equalsIgnoreCase(arg)) {
174
                 namespace.inhibit();
172
                 namespace.inhibit();
175
                 manipulated = true;
173
                 manipulated = true;
176
-            } else if (arg.equalsIgnoreCase("--force")) {
174
+            } else if ("--force".equalsIgnoreCase(arg)) {
177
                 namespace.force();
175
                 namespace.force();
178
                 manipulated = true;
176
                 manipulated = true;
179
-            } else if (arg.equalsIgnoreCase("--allow")) {
177
+            } else if ("--allow".equalsIgnoreCase(arg)) {
180
                 namespace.reset();
178
                 namespace.reset();
181
                 manipulated = true;
179
                 manipulated = true;
182
-            } else if (arg.equalsIgnoreCase("--settime")) {
180
+            } else if ("--settime".equalsIgnoreCase(arg)) {
183
                 if (nextArg.isEmpty()) {
181
                 if (nextArg.isEmpty()) {
184
-                    sendLine(origin, args.isSilent(), FORMAT_ERROR,
185
-                            "Error: You must provide a time to use.");
182
+                    showError(origin, args.isSilent(), "Error: You must provide a time to use.");
186
                     return;
183
                     return;
187
-                } else if (nextArg.equalsIgnoreCase("now")) {
184
+                } else if ("now".equalsIgnoreCase(nextArg)) {
188
                     namespace.setLimit(System.currentTimeMillis());
185
                     namespace.setLimit(System.currentTimeMillis());
189
                     i++;
186
                     i++;
190
                     manipulated = true;
187
                     manipulated = true;
191
-                } else if (nextArg.equalsIgnoreCase("nowifless")) {
188
+                } else if ("nowifless".equalsIgnoreCase(nextArg)) {
192
                     if (namespace.getLimitTime() < System.currentTimeMillis()) {
189
                     if (namespace.getLimitTime() < System.currentTimeMillis()) {
193
                         namespace.setLimit(System.currentTimeMillis());
190
                         namespace.setLimit(System.currentTimeMillis());
194
                     }
191
                     }
200
                         i++;
197
                         i++;
201
                         manipulated = true;
198
                         manipulated = true;
202
                     } catch (final NumberFormatException nfe) {
199
                     } catch (final NumberFormatException nfe) {
203
-                        sendLine(origin, args.isSilent(), FORMAT_ERROR, "Error: Invalid time: "
204
-                                + nextArg);
200
+                        showError(origin, args.isSilent(), "Error: Invalid time: " + nextArg);
205
                         return;
201
                         return;
206
                     }
202
                     }
207
                 }
203
                 }
208
-            } else if (arg.equalsIgnoreCase("--delay")) {
204
+            } else if ("--delay".equalsIgnoreCase(arg)) {
209
                 if (nextArg.isEmpty()) {
205
                 if (nextArg.isEmpty()) {
210
-                    sendLine(origin, args.isSilent(), FORMAT_ERROR,
211
-                            "Error: You must provide a delay to use.");
206
+                    showError(origin, args.isSilent(),  "Error: You must provide a delay to use.");
212
                     return;
207
                     return;
213
                 } else {
208
                 } else {
214
                     try {
209
                     try {
216
                         i++;
211
                         i++;
217
                         manipulated = true;
212
                         manipulated = true;
218
                     } catch (final NumberFormatException nfe) {
213
                     } catch (final NumberFormatException nfe) {
219
-                        sendLine(origin, args.isSilent(), FORMAT_ERROR, "Error: Invalid delay: "
220
-                                + nextArg);
214
+                        showError(origin, args.isSilent(), "Error: Invalid delay: " + nextArg);
221
                         return;
215
                         return;
222
                     }
216
                     }
223
                 }
217
                 }
224
-            } else if (arg.equalsIgnoreCase("--remove")) {
218
+            } else if ("--remove".equalsIgnoreCase(arg)) {
225
                 namespaces.remove(namespace.getName());
219
                 namespaces.remove(namespace.getName());
226
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Removed namespace '" + namespace.
227
-                        getName() + "'");
220
+                showOutput(origin, args.isSilent(),
221
+                        "Removed namespace '" + namespace.getName() + '\'');
228
                 return;
222
                 return;
229
-            } else if (arg.equalsIgnoreCase("--status")) {
223
+            } else if ("--status".equalsIgnoreCase(arg)) {
230
                 // Show the current status, in case some manipulations occurred prior to this.
224
                 // Show the current status, in case some manipulations occurred prior to this.
231
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, namespaces.get(namespace.getName()));
225
+                showOutput(origin, args.isSilent(), namespaces.get(namespace.getName()).toString());
232
                 return;
226
                 return;
233
-            } else if (arg.equalsIgnoreCase("--inverse")) {
227
+            } else if ("--inverse".equalsIgnoreCase(arg)) {
234
                 inverse = true;
228
                 inverse = true;
235
             } else if (manipulated) {
229
             } else if (manipulated) {
236
-                sendLine(origin, args.isSilent(), FORMAT_ERROR,
230
+                showError(origin, args.isSilent(),
237
                         "You can't run commands and manipulate the namespace at the same time, ignored.");
231
                         "You can't run commands and manipulate the namespace at the same time, ignored.");
238
             } else {
232
             } else {
239
                 // Command to run!
233
                 // Command to run!
246
 
240
 
247
         // If we get here, we either manipulated something, or should show the usage text.
241
         // If we get here, we either manipulated something, or should show the usage text.
248
         if (manipulated) {
242
         if (manipulated) {
249
-            sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Namespace updated.");
250
-            sendLine(origin, args.isSilent(), FORMAT_OUTPUT, namespace.toString());
243
+            showOutput(origin, args.isSilent(), "Namespace updated.");
244
+            showOutput(origin, args.isSilent(), namespace.toString());
251
             namespaces.put(namespace.getName(), namespace);
245
             namespaces.put(namespace.getName(), namespace);
252
         } else {
246
         } else {
253
-            sendLine(origin, args.isSilent(), FORMAT_ERROR, "Usage:");
254
-            sendLine(origin, args.isSilent(), FORMAT_ERROR, "");
255
-            sendLine(origin, args.isSilent(), FORMAT_ERROR, cmdname + " <args>");
256
-            sendLine(origin, args.isSilent(), FORMAT_ERROR, cmdname
247
+            showError(origin, args.isSilent(), "Usage:");
248
+            showError(origin, args.isSilent(), "");
249
+            showError(origin, args.isSilent(), cmdname + " <args>");
250
+            showError(origin, args.isSilent(), cmdname
257
                     + " --namespace <name> <namespace commands>");
251
                     + " --namespace <name> <namespace commands>");
258
-            sendLine(origin, args.isSilent(), FORMAT_ERROR, cmdname
252
+            showError(origin, args.isSilent(), cmdname
259
                     + " --namespace <name> [--inverse] </commandToRun <command args>>");
253
                     + " --namespace <name> [--inverse] </commandToRun <command args>>");
260
-            sendLine(origin, args.isSilent(), FORMAT_ERROR, "");
261
-            sendLine(origin, args.isSilent(), FORMAT_ERROR, "For more information, see " + cmdname
254
+            showError(origin, args.isSilent(), "");
255
+            showError(origin, args.isSilent(), "For more information, see " + cmdname
262
                     + " --help");
256
                     + " --help");
263
         }
257
         }
264
     }
258
     }

+ 11
- 3
conditional_execute/test/com/dmdirc/addons/conditional_execute/ConditionalExecuteCommandTest.java View File

22
 
22
 
23
 package com.dmdirc.addons.conditional_execute;
23
 package com.dmdirc.addons.conditional_execute;
24
 
24
 
25
+import com.dmdirc.DMDircMBassador;
25
 import com.dmdirc.commandparser.CommandArguments;
26
 import com.dmdirc.commandparser.CommandArguments;
26
 import com.dmdirc.commandparser.commands.context.CommandContext;
27
 import com.dmdirc.commandparser.commands.context.CommandContext;
27
 import com.dmdirc.commandparser.parsers.CommandParser;
28
 import com.dmdirc.commandparser.parsers.CommandParser;
29
+import com.dmdirc.events.CommandErrorEvent;
28
 import com.dmdirc.interfaces.CommandController;
30
 import com.dmdirc.interfaces.CommandController;
29
 import com.dmdirc.interfaces.WindowModel;
31
 import com.dmdirc.interfaces.WindowModel;
30
 
32
 
31
 import org.junit.Before;
33
 import org.junit.Before;
32
 import org.junit.Test;
34
 import org.junit.Test;
33
 import org.junit.runner.RunWith;
35
 import org.junit.runner.RunWith;
36
+import org.mockito.ArgumentCaptor;
37
+import org.mockito.Captor;
34
 import org.mockito.Mock;
38
 import org.mockito.Mock;
35
 import org.mockito.runners.MockitoJUnitRunner;
39
 import org.mockito.runners.MockitoJUnitRunner;
36
 
40
 
41
+import static org.junit.Assert.assertTrue;
37
 import static org.mockito.Matchers.anyString;
42
 import static org.mockito.Matchers.anyString;
38
-import static org.mockito.Matchers.contains;
39
 import static org.mockito.Matchers.eq;
43
 import static org.mockito.Matchers.eq;
40
 import static org.mockito.Matchers.same;
44
 import static org.mockito.Matchers.same;
41
 import static org.mockito.Mockito.never;
45
 import static org.mockito.Mockito.never;
49
     @Mock private CommandParser commandParser;
53
     @Mock private CommandParser commandParser;
50
     @Mock private WindowModel container;
54
     @Mock private WindowModel container;
51
     @Mock private CommandContext context;
55
     @Mock private CommandContext context;
56
+    @Mock private DMDircMBassador eventbus;
57
+    @Captor private ArgumentCaptor<CommandErrorEvent> errorEventCaptor;
52
     private ConditionalExecuteCommand command;
58
     private ConditionalExecuteCommand command;
53
 
59
 
54
     @Before
60
     @Before
57
         when(commandController.getSilenceChar()).thenReturn('/');
63
         when(commandController.getSilenceChar()).thenReturn('/');
58
         when(container.getCommandParser()).thenReturn(commandParser);
64
         when(container.getCommandParser()).thenReturn(commandParser);
59
         when(container.isWritable()).thenReturn(true);
65
         when(container.isWritable()).thenReturn(true);
66
+        when(container.getEventBus()).thenReturn(eventbus);
60
 
67
 
61
         command = new ConditionalExecuteCommand(commandController);
68
         command = new ConditionalExecuteCommand(commandController);
62
     }
69
     }
166
         verify(commandParser, never()).parseCommand(same(container), anyString());
173
         verify(commandParser, never()).parseCommand(same(container), anyString());
167
     }
174
     }
168
 
175
 
169
-    private void verifyErrorOutput(final String substring) {
170
-        verify(container).addLine(eq("commandError"), contains(substring));
176
+    private void verifyErrorOutput(final CharSequence substring) {
177
+        verify(eventbus).publishAsync(errorEventCaptor.capture());
178
+        assertTrue(errorEventCaptor.getValue().getMessage().contains(substring));
171
     }
179
     }
172
 
180
 
173
 }
181
 }

+ 0
- 4
dcc/src/com/dmdirc/addons/dcc/ChatContainer.java View File

34
 import com.dmdirc.ui.core.components.WindowComponent;
34
 import com.dmdirc.ui.core.components.WindowComponent;
35
 import com.dmdirc.ui.input.TabCompleterFactory;
35
 import com.dmdirc.ui.input.TabCompleterFactory;
36
 import com.dmdirc.ui.messages.BackBufferFactory;
36
 import com.dmdirc.ui.messages.BackBufferFactory;
37
-import com.dmdirc.ui.messages.sink.MessageSinkManager;
38
 import com.dmdirc.util.EventUtils;
37
 import com.dmdirc.util.EventUtils;
39
 
38
 
40
 import java.util.Arrays;
39
 import java.util.Arrays;
66
      * @param nick                My Current Nickname
65
      * @param nick                My Current Nickname
67
      * @param targetNick          Nickname of target
66
      * @param targetNick          Nickname of target
68
      * @param tabCompleterFactory The factory to use to create tab completers.
67
      * @param tabCompleterFactory The factory to use to create tab completers.
69
-     * @param messageSinkManager  The sink manager to use to dispatch messages.
70
      * @param eventBus            The bus to dispatch events on.
68
      * @param eventBus            The bus to dispatch events on.
71
      */
69
      */
72
     public ChatContainer(
70
     public ChatContainer(
79
             final String nick,
77
             final String nick,
80
             final String targetNick,
78
             final String targetNick,
81
             final TabCompleterFactory tabCompleterFactory,
79
             final TabCompleterFactory tabCompleterFactory,
82
-            final MessageSinkManager messageSinkManager,
83
             final DMDircMBassador eventBus) {
80
             final DMDircMBassador eventBus) {
84
         super(parent, title, "dcc-chat-inactive", configManager, backBufferFactory,
81
         super(parent, title, "dcc-chat-inactive", configManager, backBufferFactory,
85
                 new DCCCommandParser(configManager, commandController, eventBus),
82
                 new DCCCommandParser(configManager, commandController, eventBus),
86
-                messageSinkManager,
87
                 tabCompleterFactory,
83
                 tabCompleterFactory,
88
                 eventBus,
84
                 eventBus,
89
                 Arrays.asList(
85
                 Arrays.asList(

+ 3
- 11
dcc/src/com/dmdirc/addons/dcc/DCCCommand.java View File

49
 import com.dmdirc.ui.input.TabCompleterFactory;
49
 import com.dmdirc.ui.input.TabCompleterFactory;
50
 import com.dmdirc.ui.input.TabCompletionType;
50
 import com.dmdirc.ui.input.TabCompletionType;
51
 import com.dmdirc.ui.messages.BackBufferFactory;
51
 import com.dmdirc.ui.messages.BackBufferFactory;
52
-import com.dmdirc.ui.messages.sink.MessageSinkManager;
53
 
52
 
54
 import java.awt.Window;
53
 import java.awt.Window;
55
 import java.io.File;
54
 import java.io.File;
74
     private final Window mainWindow;
73
     private final Window mainWindow;
75
     /** Window management. */
74
     /** Window management. */
76
     private final WindowManager windowManager;
75
     private final WindowManager windowManager;
77
-    /** The sink manager to use to dispatch messages. */
78
-    private final MessageSinkManager messageSinkManager;
79
     /** The factory to use for tab completers. */
76
     /** The factory to use for tab completers. */
80
     private final TabCompleterFactory tabCompleterFactory;
77
     private final TabCompleterFactory tabCompleterFactory;
81
     /** The bus to dispatch events on. */
78
     /** The bus to dispatch events on. */
90
             final CommandController controller,
87
             final CommandController controller,
91
             @MainWindow final Window mainWindow,
88
             @MainWindow final Window mainWindow,
92
             final DCCManager plugin,
89
             final DCCManager plugin,
93
-            final MessageSinkManager messageSinkManager,
94
             final WindowManager windowManager,
90
             final WindowManager windowManager,
95
             final TabCompleterFactory tabCompleterFactory,
91
             final TabCompleterFactory tabCompleterFactory,
96
             final DMDircMBassador eventBus,
92
             final DMDircMBassador eventBus,
98
         super(controller);
94
         super(controller);
99
         this.mainWindow = mainWindow;
95
         this.mainWindow = mainWindow;
100
         myPlugin = plugin;
96
         myPlugin = plugin;
101
-        this.messageSinkManager = messageSinkManager;
102
         this.windowManager = windowManager;
97
         this.windowManager = windowManager;
103
         this.tabCompleterFactory = tabCompleterFactory;
98
         this.tabCompleterFactory = tabCompleterFactory;
104
         this.eventBus = eventBus;
99
         this.eventBus = eventBus;
138
                 sendFile(target, origin, connection, true,
133
                 sendFile(target, origin, connection, true,
139
                         args.getArgumentsAsString(2));
134
                         args.getArgumentsAsString(2));
140
             } else {
135
             } else {
141
-                sendLine(origin, args.isSilent(), FORMAT_ERROR,
142
-                        "Unknown DCC Type: '" + type + "'");
136
+                showError(origin, args.isSilent(), "Unknown DCC Type: '" + type + '\'');
143
             }
137
             }
144
         } else {
138
         } else {
145
             showUsage(origin, true, INFO.getName(), INFO.getHelp());
139
             showUsage(origin, true, INFO.getName(), INFO.getHelp());
171
                     myNickname,
165
                     myNickname,
172
                     target,
166
                     target,
173
                     tabCompleterFactory,
167
                     tabCompleterFactory,
174
-                    messageSinkManager,
175
                     eventBus);
168
                     eventBus);
176
             windowManager.addWindow(myPlugin.getContainer(), window);
169
             windowManager.addWindow(myPlugin.getContainer(), window);
177
             parser.sendCTCP(target, "DCC", "CHAT chat " + DCC.ipToLong(
170
             parser.sendCTCP(target, "DCC", "CHAT chat " + DCC.ipToLong(
178
-                    myPlugin.getListenIP(parser)) + " " + chat.getPort());
171
+                    myPlugin.getListenIP(parser)) + ' ' + chat.getPort());
179
             eventBus.publish(new DccChatRequestSentEvent(connection, target));
172
             eventBus.publish(new DccChatRequestSentEvent(connection, target));
180
             sendLine(origin, isSilent, "DCCChatStarting", target, chat.getHost(), chat.getPort());
173
             sendLine(origin, isSilent, "DCCChatStarting", target, chat.getHost(), chat.getPort());
181
             window.addLine("DCCChatStarting", target, chat.getHost(), chat.getPort());
174
             window.addLine("DCCChatStarting", target, chat.getHost(), chat.getPort());
229
             eventBus.publish(new DccSendRequestEvent(connection, target, selectedFile.
222
             eventBus.publish(new DccSendRequestEvent(connection, target, selectedFile.
230
                     getAbsolutePath()));
223
                     getAbsolutePath()));
231
 
224
 
232
-            sendLine(origin, isSilent, FORMAT_OUTPUT,
233
-                    "Starting DCC Send with: " + target);
225
+            showOutput(origin, isSilent, "Starting DCC Send with: " + target);
234
 
226
 
235
             send.setFileName(selectedFile.getAbsolutePath());
227
             send.setFileName(selectedFile.getAbsolutePath());
236
             send.setFileSize(selectedFile.length());
228
             send.setFileSize(selectedFile.length());

+ 0
- 4
dcc/src/com/dmdirc/addons/dcc/DCCFrameContainer.java View File

30
 import com.dmdirc.interfaces.config.AggregateConfigProvider;
30
 import com.dmdirc.interfaces.config.AggregateConfigProvider;
31
 import com.dmdirc.ui.input.TabCompleterFactory;
31
 import com.dmdirc.ui.input.TabCompleterFactory;
32
 import com.dmdirc.ui.messages.BackBufferFactory;
32
 import com.dmdirc.ui.messages.BackBufferFactory;
33
-import com.dmdirc.ui.messages.sink.MessageSinkManager;
34
 
33
 
35
 import java.util.Collection;
34
 import java.util.Collection;
36
 import java.util.Optional;
35
 import java.util.Optional;
53
      * @param icon                The icon to use
52
      * @param icon                The icon to use
54
      * @param configManager       Config manager
53
      * @param configManager       Config manager
55
      * @param parser              Command parser to use for this window
54
      * @param parser              Command parser to use for this window
56
-     * @param messageSinkManager  The sink manager to use to dispatch messages.
57
      * @param tabCompleterFactory The factory to use to create tab completers.
55
      * @param tabCompleterFactory The factory to use to create tab completers.
58
      * @param eventBus            The bus to dispatch events on.
56
      * @param eventBus            The bus to dispatch events on.
59
      * @param components          The UI components that this frame requires
57
      * @param components          The UI components that this frame requires
65
             final AggregateConfigProvider configManager,
63
             final AggregateConfigProvider configManager,
66
             final BackBufferFactory backBufferFactory,
64
             final BackBufferFactory backBufferFactory,
67
             final CommandParser parser,
65
             final CommandParser parser,
68
-            final MessageSinkManager messageSinkManager,
69
             final TabCompleterFactory tabCompleterFactory,
66
             final TabCompleterFactory tabCompleterFactory,
70
             final DMDircMBassador eventBus,
67
             final DMDircMBassador eventBus,
71
             final Collection<String> components) {
68
             final Collection<String> components) {
72
         super(parent, icon, title, title, configManager, backBufferFactory,
69
         super(parent, icon, title, title, configManager, backBufferFactory,
73
                 tabCompleterFactory.getTabCompleter(configManager),
70
                 tabCompleterFactory.getTabCompleter(configManager),
74
-                messageSinkManager,
75
                 eventBus,
71
                 eventBus,
76
                 components);
72
                 components);
77
         initBackBuffer();
73
         initBackBuffer();

+ 0
- 6
dcc/src/com/dmdirc/addons/dcc/DCCManager.java View File

61
 import com.dmdirc.ui.WindowManager;
61
 import com.dmdirc.ui.WindowManager;
62
 import com.dmdirc.ui.input.TabCompleterFactory;
62
 import com.dmdirc.ui.input.TabCompleterFactory;
63
 import com.dmdirc.ui.messages.BackBufferFactory;
63
 import com.dmdirc.ui.messages.BackBufferFactory;
64
-import com.dmdirc.ui.messages.sink.MessageSinkManager;
65
 
64
 
66
 import com.google.common.collect.Sets;
65
 import com.google.common.collect.Sets;
67
 
66
 
100
     private PlaceholderContainer container;
99
     private PlaceholderContainer container;
101
     /** Config manager to read settings from. */
100
     /** Config manager to read settings from. */
102
     private final AggregateConfigProvider config;
101
     private final AggregateConfigProvider config;
103
-    /** The sink manager to use to dispatch messages. */
104
-    private final MessageSinkManager messageSinkManager;
105
     /** Window Management. */
102
     /** Window Management. */
106
     private final WindowManager windowManager;
103
     private final WindowManager windowManager;
107
     /** The command controller to use. */
104
     /** The command controller to use. */
127
             final IdentityController identityController,
124
             final IdentityController identityController,
128
             @GlobalConfig final AggregateConfigProvider globalConfig,
125
             @GlobalConfig final AggregateConfigProvider globalConfig,
129
             final CommandController commandController,
126
             final CommandController commandController,
130
-            final MessageSinkManager messageSinkManager,
131
             final WindowManager windowManager,
127
             final WindowManager windowManager,
132
             final TabCompleterFactory tabCompleterFactory,
128
             final TabCompleterFactory tabCompleterFactory,
133
             final SwingWindowFactory windowFactory,
129
             final SwingWindowFactory windowFactory,
137
             @Directory(DirectoryType.BASE) final String baseDirectory,
133
             @Directory(DirectoryType.BASE) final String baseDirectory,
138
             final BackBufferFactory backBufferFactory) {
134
             final BackBufferFactory backBufferFactory) {
139
         this.mainWindow = mainWindow;
135
         this.mainWindow = mainWindow;
140
-        this.messageSinkManager = messageSinkManager;
141
         this.windowManager = windowManager;
136
         this.windowManager = windowManager;
142
         this.commandController = commandController;
137
         this.commandController = commandController;
143
         this.tabCompleterFactory = tabCompleterFactory;
138
         this.tabCompleterFactory = tabCompleterFactory;
476
                 myNickname,
471
                 myNickname,
477
                 nickname,
472
                 nickname,
478
                 tabCompleterFactory,
473
                 tabCompleterFactory,
479
-                messageSinkManager,
480
                 eventBus);
474
                 eventBus);
481
         windowManager.addWindow(getContainer(), f);
475
         windowManager.addWindow(getContainer(), f);
482
         f.addLine("DCCChatStarting", nickname, chat.getHost(), chat.getPort());
476
         f.addLine("DCCChatStarting", nickname, chat.getHost(), chat.getPort());

+ 1
- 1
dcop/src/com/dmdirc/addons/dcop/DcopCommand.java View File

73
 
73
 
74
         final List<String> res = executor.getDcopResult(arguments[0], arguments[1], arguments[2]);
74
         final List<String> res = executor.getDcopResult(arguments[0], arguments[1], arguments[2]);
75
         for (String line : res) {
75
         for (String line : res) {
76
-            sendLine(origin, args.isSilent(), FORMAT_OUTPUT, line);
76
+            showOutput(origin, args.isSilent(), line);
77
         }
77
         }
78
     }
78
     }
79
 
79
 

+ 2
- 2
debug/src/com/dmdirc/addons/debug/Debug.java View File

89
         } else {
89
         } else {
90
             final DebugCommand command = commands.get(args.getArguments()[0]);
90
             final DebugCommand command = commands.get(args.getArguments()[0]);
91
             if (command == null) {
91
             if (command == null) {
92
-                sendLine(origin, args.isSilent(), FORMAT_ERROR,
93
-                        "Unknown debug action.");
92
+                showError(origin, args.isSilent(), "Unknown debug action.");
94
             } else {
93
             } else {
95
                 final CommandArguments newArgs = new CommandArguments(
94
                 final CommandArguments newArgs = new CommandArguments(
96
                         controller,
95
                         controller,
110
      * @param type     The type of message to send
109
      * @param type     The type of message to send
111
      * @param args     The arguments of the message
110
      * @param args     The arguments of the message
112
      */
111
      */
112
+    @Deprecated
113
     public void proxySendLine(final WindowModel target,
113
     public void proxySendLine(final WindowModel target,
114
             final boolean isSilent, final String type, final Object... args) {
114
             final boolean isSilent, final String type, final Object... args) {
115
         sendLine(target, isSilent, type, args);
115
         sendLine(target, isSilent, type, args);

+ 0
- 3
debug/src/com/dmdirc/addons/debug/RawWindow.java View File

32
 import com.dmdirc.ui.core.components.WindowComponent;
32
 import com.dmdirc.ui.core.components.WindowComponent;
33
 import com.dmdirc.ui.input.TabCompleterFactory;
33
 import com.dmdirc.ui.input.TabCompleterFactory;
34
 import com.dmdirc.ui.messages.BackBufferFactory;
34
 import com.dmdirc.ui.messages.BackBufferFactory;
35
-import com.dmdirc.ui.messages.sink.MessageSinkManager;
36
 
35
 
37
 import java.util.Arrays;
36
 import java.util.Arrays;
38
 import java.util.Optional;
37
 import java.util.Optional;
48
 
47
 
49
     public RawWindow(
48
     public RawWindow(
50
             final Connection connection,
49
             final Connection connection,
51
-            final MessageSinkManager messageSinkManager,
52
             final TabCompleterFactory tabCompleterFactory,
50
             final TabCompleterFactory tabCompleterFactory,
53
             final BackBufferFactory backBufferFactory) {
51
             final BackBufferFactory backBufferFactory) {
54
         super(connection.getWindowModel(), "raw", "Raw", "(Raw log)",
52
         super(connection.getWindowModel(), "raw", "Raw", "(Raw log)",
57
                 tabCompleterFactory.getTabCompleter(connection.getWindowModel().getTabCompleter(),
55
                 tabCompleterFactory.getTabCompleter(connection.getWindowModel().getTabCompleter(),
58
                         connection.getWindowModel().getConfigManager(),
56
                         connection.getWindowModel().getConfigManager(),
59
                         CommandType.TYPE_QUERY, CommandType.TYPE_CHAT),
57
                         CommandType.TYPE_QUERY, CommandType.TYPE_CHAT),
60
-                messageSinkManager,
61
                 connection.getWindowModel().getEventBus(),
58
                 connection.getWindowModel().getEventBus(),
62
                 Arrays.asList(WindowComponent.TEXTAREA.getIdentifier(),
59
                 Arrays.asList(WindowComponent.TEXTAREA.getIdentifier(),
63
                         WindowComponent.INPUTFIELD.getIdentifier()));
60
                         WindowComponent.INPUTFIELD.getIdentifier()));

+ 6
- 7
debug/src/com/dmdirc/addons/debug/RawWindowFactory.java View File

28
 import com.dmdirc.ui.WindowManager;
28
 import com.dmdirc.ui.WindowManager;
29
 import com.dmdirc.ui.input.TabCompleterFactory;
29
 import com.dmdirc.ui.input.TabCompleterFactory;
30
 import com.dmdirc.ui.messages.BackBufferFactory;
30
 import com.dmdirc.ui.messages.BackBufferFactory;
31
-import com.dmdirc.ui.messages.sink.MessageSinkManager;
32
 
31
 
33
 import javax.inject.Inject;
32
 import javax.inject.Inject;
34
 import javax.inject.Singleton;
33
 import javax.inject.Singleton;
41
 
40
 
42
     private final TabCompleterFactory tabCompleterFactory;
41
     private final TabCompleterFactory tabCompleterFactory;
43
     private final CommandController commandController;
42
     private final CommandController commandController;
44
-    private final MessageSinkManager messageSinkManager;
45
     private final BackBufferFactory backBufferFactory;
43
     private final BackBufferFactory backBufferFactory;
46
     private final WindowManager windowManager;
44
     private final WindowManager windowManager;
47
 
45
 
48
     @Inject
46
     @Inject
49
-    public RawWindowFactory(final TabCompleterFactory tabCompleterFactory,
50
-            final CommandController commandController, final MessageSinkManager messageSinkManager,
51
-            final BackBufferFactory backBufferFactory, final WindowManager windowManager) {
47
+    public RawWindowFactory(
48
+            final TabCompleterFactory tabCompleterFactory,
49
+            final CommandController commandController,
50
+            final BackBufferFactory backBufferFactory,
51
+            final WindowManager windowManager) {
52
         this.tabCompleterFactory = tabCompleterFactory;
52
         this.tabCompleterFactory = tabCompleterFactory;
53
         this.commandController = commandController;
53
         this.commandController = commandController;
54
-        this.messageSinkManager = messageSinkManager;
55
         this.backBufferFactory = backBufferFactory;
54
         this.backBufferFactory = backBufferFactory;
56
         this.windowManager = windowManager;
55
         this.windowManager = windowManager;
57
     }
56
     }
58
 
57
 
59
     public RawWindow getRawWindow(final Connection connection) {
58
     public RawWindow getRawWindow(final Connection connection) {
60
         final RawWindow rawWindow = new RawWindow(connection,
59
         final RawWindow rawWindow = new RawWindow(connection,
61
-                messageSinkManager, tabCompleterFactory,  backBufferFactory);
60
+                tabCompleterFactory,  backBufferFactory);
62
         rawWindow.setCommandParser(new ServerCommandParser(
61
         rawWindow.setCommandParser(new ServerCommandParser(
63
                 connection.getWindowModel().getConfigManager(),
62
                 connection.getWindowModel().getConfigManager(),
64
                 commandController,
63
                 commandController,

+ 5
- 4
debug/src/com/dmdirc/addons/debug/commands/Benchmark.java View File

26
 import com.dmdirc.addons.debug.DebugCommand;
26
 import com.dmdirc.addons.debug.DebugCommand;
27
 import com.dmdirc.commandparser.CommandArguments;
27
 import com.dmdirc.commandparser.CommandArguments;
28
 import com.dmdirc.commandparser.commands.context.CommandContext;
28
 import com.dmdirc.commandparser.commands.context.CommandContext;
29
+import com.dmdirc.events.CommandOutputEvent;
29
 import com.dmdirc.interfaces.WindowModel;
30
 import com.dmdirc.interfaces.WindowModel;
30
 
31
 
31
 import javax.annotation.Nonnull;
32
 import javax.annotation.Nonnull;
67
             final long start = System.nanoTime();
68
             final long start = System.nanoTime();
68
 
69
 
69
             for (int j = 0; j < 5000; j++) {
70
             for (int j = 0; j < 5000; j++) {
70
-                origin.addLine(FORMAT_OUTPUT,
71
-                        "This is a benchmark. Lorem ipsum doler...");
71
+                origin.getEventBus().publishAsync(new CommandOutputEvent(origin,
72
+                        "This is a benchmark. Lorem ipsum doler..."));
72
             }
73
             }
73
 
74
 
74
             final long end = System.nanoTime();
75
             final long end = System.nanoTime();
77
         }
78
         }
78
 
79
 
79
         for (int i = 0; i < results.length; i++) {
80
         for (int i = 0; i < results.length; i++) {
80
-            origin.addLine(FORMAT_OUTPUT, "Iteration " + i + ": " + results[i]
81
-                    + " nanoseconds.");
81
+            origin.getEventBus().publishAsync(new CommandOutputEvent(origin,
82
+                    "Iteration " + i + ": " + results[i] + " nanoseconds."));
82
         }
83
         }
83
     }
84
     }
84
 
85
 

+ 6
- 2
debug/src/com/dmdirc/addons/debug/commands/EventBusViewer.java View File

30
 import com.dmdirc.commandparser.CommandArguments;
30
 import com.dmdirc.commandparser.CommandArguments;
31
 import com.dmdirc.commandparser.commands.context.CommandContext;
31
 import com.dmdirc.commandparser.commands.context.CommandContext;
32
 import com.dmdirc.events.ClientLineAddedEvent;
32
 import com.dmdirc.events.ClientLineAddedEvent;
33
+import com.dmdirc.events.CommandOutputEvent;
33
 import com.dmdirc.events.DMDircEvent;
34
 import com.dmdirc.events.DMDircEvent;
35
+import com.dmdirc.events.DisplayableEvent;
34
 import com.dmdirc.events.FrameClosingEvent;
36
 import com.dmdirc.events.FrameClosingEvent;
35
 import com.dmdirc.interfaces.WindowModel;
37
 import com.dmdirc.interfaces.WindowModel;
36
 import com.dmdirc.interfaces.config.AggregateConfigProvider;
38
 import com.dmdirc.interfaces.config.AggregateConfigProvider;
128
         @Handler
130
         @Handler
129
         public void handleEvent(final DMDircEvent event) {
131
         public void handleEvent(final DMDircEvent event) {
130
             if (event instanceof ClientLineAddedEvent
132
             if (event instanceof ClientLineAddedEvent
131
-                    && ((ClientLineAddedEvent) event).getFrameContainer() == target) {
133
+                    && ((ClientLineAddedEvent) event).getFrameContainer() == target
134
+                    || event instanceof CommandOutputEvent
135
+                    && ((DisplayableEvent) event).getSource() == target) {
132
                 // Don't add a line every time we add a line to our output window.
136
                 // Don't add a line every time we add a line to our output window.
133
                 // Things will explode otherwise.
137
                 // Things will explode otherwise.
134
                 return;
138
                 return;
154
                 }
158
                 }
155
             }
159
             }
156
 
160
 
157
-            target.addLine(FORMAT_OUTPUT, output.toString());
161
+            target.getEventBus().publishAsync(new CommandOutputEvent(target, output.toString()));
158
         }
162
         }
159
 
163
 
160
     }
164
     }

+ 10
- 8
debug/test/com/dmdirc/addons/debug/DebugTest.java View File

22
 
22
 
23
 package com.dmdirc.addons.debug;
23
 package com.dmdirc.addons.debug;
24
 
24
 
25
+import com.dmdirc.DMDircMBassador;
25
 import com.dmdirc.commandparser.CommandArguments;
26
 import com.dmdirc.commandparser.CommandArguments;
26
 import com.dmdirc.commandparser.commands.context.CommandContext;
27
 import com.dmdirc.commandparser.commands.context.CommandContext;
28
+import com.dmdirc.events.CommandErrorEvent;
27
 import com.dmdirc.interfaces.CommandController;
29
 import com.dmdirc.interfaces.CommandController;
28
 import com.dmdirc.interfaces.WindowModel;
30
 import com.dmdirc.interfaces.WindowModel;
29
 
31
 
37
 import org.mockito.Mock;
39
 import org.mockito.Mock;
38
 import org.mockito.runners.MockitoJUnitRunner;
40
 import org.mockito.runners.MockitoJUnitRunner;
39
 
41
 
40
-import static org.mockito.Matchers.anyObject;
41
-import static org.mockito.Matchers.anyString;
42
+import static org.mockito.Matchers.any;
42
 import static org.mockito.Matchers.argThat;
43
 import static org.mockito.Matchers.argThat;
43
-import static org.mockito.Matchers.eq;
44
+import static org.mockito.Matchers.isA;
44
 import static org.mockito.Matchers.same;
45
 import static org.mockito.Matchers.same;
45
 import static org.mockito.Mockito.never;
46
 import static org.mockito.Mockito.never;
46
 import static org.mockito.Mockito.verify;
47
 import static org.mockito.Mockito.verify;
54
     @Mock private CommandController controller;
55
     @Mock private CommandController controller;
55
     @Mock private DebugCommand debugCommand;
56
     @Mock private DebugCommand debugCommand;
56
     @Mock private CommandContext commandContext;
57
     @Mock private CommandContext commandContext;
58
+    @Mock private DMDircMBassador eventbus;
57
     private Debug debug;
59
     private Debug debug;
58
 
60
 
59
     @Before
61
     @Before
60
     public void setup() {
62
     public void setup() {
61
         when(controller.getCommandChar()).thenReturn('/');
63
         when(controller.getCommandChar()).thenReturn('/');
62
         when(debugCommand.getName()).thenReturn("test");
64
         when(debugCommand.getName()).thenReturn("test");
65
+        when(container.getEventBus()).thenReturn(eventbus);
63
     }
66
     }
64
 
67
 
65
     /** Checks the debug command with no arguments shows usage. */
68
     /** Checks the debug command with no arguments shows usage. */
69
         when(arguments.isCommand()).thenReturn(true);
72
         when(arguments.isCommand()).thenReturn(true);
70
         when(arguments.getArguments()).thenReturn(new String[0]);
73
         when(arguments.getArguments()).thenReturn(new String[0]);
71
         debug.execute(container, arguments, null);
74
         debug.execute(container, arguments, null);
72
-        verify(container).addLine(eq("commandUsage"), anyString(),
73
-                eq("debug"), anyObject());
75
+        verify(eventbus).publishAsync(isA(CommandErrorEvent.class));
74
     }
76
     }
75
 
77
 
76
     /** Checks the debug command with an invalid subcommand shows an error. */
78
     /** Checks the debug command with an invalid subcommand shows an error. */
81
         when(arguments.getArguments()).thenReturn(new String[]{"test"});
83
         when(arguments.getArguments()).thenReturn(new String[]{"test"});
82
 
84
 
83
         debug.execute(container, arguments, null);
85
         debug.execute(container, arguments, null);
84
-        verify(container).addLine(eq("commandError"), anyString());
86
+        verify(eventbus).publishAsync(isA(CommandErrorEvent.class));
85
     }
87
     }
86
 
88
 
87
     /** Checks the debug command executes a subcommand with no args. */
89
     /** Checks the debug command executes a subcommand with no args. */
95
 
97
 
96
         debug.execute(container, arguments, commandContext);
98
         debug.execute(container, arguments, commandContext);
97
 
99
 
98
-        verify(container, never()).addLine(anyString(), anyString());
100
+        verify(eventbus, never()).publishAsync(any());
99
         verify(debugCommand).execute(same(container), eqLine("/test"),
101
         verify(debugCommand).execute(same(container), eqLine("/test"),
100
                 same(commandContext));
102
                 same(commandContext));
101
     }
103
     }
111
 
113
 
112
         debug.execute(container, arguments, commandContext);
114
         debug.execute(container, arguments, commandContext);
113
 
115
 
114
-        verify(container, never()).addLine(anyString(), anyString());
116
+        verify(eventbus, never()).publishAsync(any());
115
         verify(debugCommand).execute(same(container), eqLine("/test 1 2 3"),
117
         verify(debugCommand).execute(same(container), eqLine("/test 1 2 3"),
116
                 same(commandContext));
118
                 same(commandContext));
117
     }
119
     }

+ 3
- 3
dns/src/com/dmdirc/addons/dns/DNSCommand.java View File

71
             return;
71
             return;
72
         }
72
         }
73
 
73
 
74
-        sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Resolving: " + args.getArguments()[0]);
74
+        showOutput(origin, args.isSilent(), "Resolving: " + args.getArguments()[0]);
75
         new Timer("DNS Command Timer").schedule(new TimerTask() {
75
         new Timer("DNS Command Timer").schedule(new TimerTask() {
76
 
76
 
77
             @Override
77
             @Override
85
             final String arg) {
85
             final String arg) {
86
         try {
86
         try {
87
             final InetAddress address = InetAddresses.forString(arg);
87
             final InetAddress address = InetAddresses.forString(arg);
88
-            sendLine(origin, isSilent, FORMAT_OUTPUT, "Resolved: "
88
+            showOutput(origin, isSilent, "Resolved: "
89
                     + arg + ": " + address.getCanonicalHostName());
89
                     + arg + ": " + address.getCanonicalHostName());
90
         } catch (IllegalArgumentException ex) {
90
         } catch (IllegalArgumentException ex) {
91
-            sendLine(origin, isSilent, FORMAT_OUTPUT, "Resolved: "
91
+            showOutput(origin, isSilent, "Resolved: "
92
                     + arg + ": " + getIPs(arg));
92
                     + arg + ": " + getIPs(arg));
93
         }
93
         }
94
     }
94
     }

+ 4
- 4
exec/src/com/dmdirc/addons/exec/ExecCommand.java View File

72
             // This checks the command to execute has correct quotes
72
             // This checks the command to execute has correct quotes
73
             // (if necessary). Without this /exec "command arg1 arg2 would error.
73
             // (if necessary). Without this /exec "command arg1 arg2 would error.
74
             if (commandArray.length == 0) {
74
             if (commandArray.length == 0) {
75
-                sendLine(origin, args.isSilent(), FORMAT_ERROR,
75
+                showError(origin, args.isSilent(),
76
                         "Could not execute: Invalid file name provided");
76
                         "Could not execute: Invalid file name provided");
77
             } else if (!new File(commandArray[0]).exists()) {
77
             } else if (!new File(commandArray[0]).exists()) {
78
-                sendLine(origin, args.isSilent(), FORMAT_ERROR,
78
+                showError(origin, args.isSilent(),
79
                         "Could not execute: " + commandArray[0] + " does not exist.");
79
                         "Could not execute: " + commandArray[0] + " does not exist.");
80
             } else {
80
             } else {
81
                 final Process p = Runtime.getRuntime().exec(commandArray);
81
                 final Process p = Runtime.getRuntime().exec(commandArray);
88
                     final List<String> errorOutput = CharStreams.readLines(
88
                     final List<String> errorOutput = CharStreams.readLines(
89
                             new InputStreamReader(p.getErrorStream()));
89
                             new InputStreamReader(p.getErrorStream()));
90
                     for (String line : execOutput) {
90
                     for (String line : execOutput) {
91
-                        sendLine(origin, args.isSilent(), FORMAT_OUTPUT, line);
91
+                        showOutput(origin, args.isSilent(), line);
92
                     }
92
                     }
93
                     for (String line : errorOutput) {
93
                     for (String line : errorOutput) {
94
-                        sendLine(origin, args.isSilent(), FORMAT_ERROR, line);
94
+                        showError(origin, args.isSilent(), line);
95
                     }
95
                     }
96
                 }
96
                 }
97
             }
97
             }

+ 4
- 0
logging/res/META-INF/format.yml View File

1
+---
2
+HistoricalLineRestoredEvent:
3
+  format: "{{line}}"
4
+  timestamp: no

activewindow/src/com/dmdirc/addons/activewindow/package-info.java → logging/src/com/dmdirc/addons/logging/HistoricalLineRestoredEvent.java View File

20
  * SOFTWARE.
20
  * SOFTWARE.
21
  */
21
  */
22
 
22
 
23
+package com.dmdirc.addons.logging;
24
+
25
+import com.dmdirc.events.BaseDisplayableEvent;
26
+import com.dmdirc.interfaces.WindowModel;
27
+
23
 /**
28
 /**
24
- * Provides an active window command to the swing UI.
29
+ * Event raised when a line from the log is restored into a window.
25
  */
30
  */
26
-package com.dmdirc.addons.activewindow;
31
+public class HistoricalLineRestoredEvent extends BaseDisplayableEvent {
32
+
33
+    private final String line;
34
+
35
+    public HistoricalLineRestoredEvent(final long timestamp, final WindowModel source,
36
+            final String line) {
37
+        super(timestamp, source);
38
+        this.line = line;
39
+    }
40
+
41
+    public HistoricalLineRestoredEvent(final WindowModel source, final String line) {
42
+        super(source);
43
+        this.line = line;
44
+    }
45
+
46
+    public String getLine() {
47
+        return line;
48
+    }
49
+
50
+}

+ 7
- 8
logging/src/com/dmdirc/addons/logging/LoggingCommand.java View File

67
         if (args.getArguments().length > 0) {
67
         if (args.getArguments().length > 0) {
68
             if ("history".equalsIgnoreCase(args.getArguments()[0])) {
68
             if ("history".equalsIgnoreCase(args.getArguments()[0])) {
69
                 if (!manager.showHistory(origin)) {
69
                 if (!manager.showHistory(origin)) {
70
-                    sendLine(origin, args.isSilent(), FORMAT_ERROR,
71
-                            "Unable to open history for this window.");
70
+                    showError(origin, args.isSilent(), "Unable to open history for this window.");
72
                 }
71
                 }
73
             } else if ("help".equalsIgnoreCase(args.getArguments()[0])) {
72
             } else if ("help".equalsIgnoreCase(args.getArguments()[0])) {
74
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, LOGGING
73
+                showOutput(origin, args.isSilent(), LOGGING
75
                         + " history          - Open the history of this window, if available.");
74
                         + " history          - Open the history of this window, if available.");
76
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, LOGGING
75
+                showOutput(origin, args.isSilent(), LOGGING
77
                         + " help             - Show this help.");
76
                         + " help             - Show this help.");
78
             } else {
77
             } else {
79
-                sendLine(origin, args.isSilent(), FORMAT_ERROR, "Unknown command '" + args.
80
-                        getArguments()[0] + "'. Use " + LOGGING + " help for a list of commands.");
78
+                showError(origin, args.isSilent(), "Unknown command '"
79
+                        + args.getArguments()[0] + "'. Use " + LOGGING
80
+                        + " help for a list of commands.");
81
             }
81
             }
82
         } else {
82
         } else {
83
-            sendLine(origin, args.isSilent(), FORMAT_ERROR, "Use " + LOGGING
84
-                    + " help for a list of commands.");
83
+            showError(origin, args.isSilent(), "Use " + LOGGING + " help for a list of commands.");
85
         }
84
         }
86
     }
85
     }
87
 
86
 

+ 13
- 12
logging/src/com/dmdirc/addons/logging/LoggingManager.java View File

205
 
205
 
206
         synchronized (openFiles) {
206
         synchronized (openFiles) {
207
             final Collection<String> old = new ArrayList<>(openFiles.size());
207
             final Collection<String> old = new ArrayList<>(openFiles.size());
208
-            for (Map.Entry<String, OpenFile> entry : openFiles.entrySet()) {
209
-                if (entry.getValue().lastUsedTime < oldestTime) {
210
-                    StreamUtils.close(entry.getValue().writer);
211
-                    old.add(entry.getKey());
212
-                }
213
-            }
208
+            openFiles.entrySet().stream()
209
+                    .filter(entry -> entry.getValue().lastUsedTime < oldestTime)
210
+                    .forEach(entry -> {
211
+                        StreamUtils.close(entry.getValue().writer);
212
+                        old.add(entry.getKey());
213
+                    });
214
 
214
 
215
             openFiles.keySet().removeAll(old);
215
             openFiles.keySet().removeAll(old);
216
         }
216
         }
280
 
280
 
281
         appendLine(filename, "*** Topic is: %s", event.getTopic().getTopic());
281
         appendLine(filename, "*** Topic is: %s", event.getTopic().getTopic());
282
         appendLine(filename, "*** Set at: %s on %s by %s",
282
         appendLine(filename, "*** Set at: %s on %s by %s",
283
-                timeFormat.format(1000 * event.getTopic().getTime()),
284
-                dateFormat.format(1000 * event.getTopic().getTime()),
283
+                timeFormat.format(event.getTopic().getDate()),
284
+                dateFormat.format(event.getTopic().getDate()),
285
                         event.getTopic().getClient()
285
                         event.getTopic().getClient()
286
                                 .map(GroupChatUser::getNickname).orElse("Unknown"));
286
                                 .map(GroupChatUser::getNickname).orElse("Unknown"));
287
     }
287
     }
410
 
410
 
411
         final Path testFile = Paths.get(filename);
411
         final Path testFile = Paths.get(filename);
412
         if (Files.exists(testFile)) {
412
         if (Files.exists(testFile)) {
413
-            try {
414
-                final ReverseFileReader file = new ReverseFileReader(testFile);
413
+            try (final ReverseFileReader file = new ReverseFileReader(testFile)) {
415
                 // Because the file includes a newline char at the end, an empty line
414
                 // Because the file includes a newline char at the end, an empty line
416
                 // is returned by getLines. To counter this, we call getLines(1) and do
415
                 // is returned by getLines. To counter this, we call getLines(1) and do
417
                 // nothing with the output.
416
                 // nothing with the output.
418
                 file.getLines(1);
417
                 file.getLines(1);
419
                 final Stack<String> lines = file.getLines(backbufferLines);
418
                 final Stack<String> lines = file.getLines(backbufferLines);
420
                 while (!lines.empty()) {
419
                 while (!lines.empty()) {
421
-                    frame.addLine(getColouredString(colour, lines.pop()));
420
+                    frame.getEventBus().publishAsync(new HistoricalLineRestoredEvent(frame,
421
+                            getColouredString(colour, lines.pop())));
422
                 }
422
                 }
423
                 file.close();
423
                 file.close();
424
-                frame.addLine(getColouredString(colour, "--- End of backbuffer\n"));
424
+                frame.getEventBus().publishAsync(new HistoricalLineRestoredEvent(frame,
425
+                        getColouredString(colour, "--- End of backbuffer\n")));
425
             } catch (IOException | SecurityException e) {
426
             } catch (IOException | SecurityException e) {
426
                 LOG.info(USER_ERROR, "Unable to show backbuffer (Filename: {}): {}", filename,
427
                 LOG.info(USER_ERROR, "Unable to show backbuffer (Filename: {}): {}", filename,
427
                         e.getMessage(), e);
428
                         e.getMessage(), e);

+ 2
- 3
nma/src/com/dmdirc/addons/nma/NotifyMyAndroidCommand.java View File

85
         new Thread(() -> {
85
         new Thread(() -> {
86
             try {
86
             try {
87
                 client.notify(parts[0], parts[1]);
87
                 client.notify(parts[0], parts[1]);
88
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Notification sent");
88
+                showOutput(origin, args.isSilent(), "Notification sent");
89
             } catch (IOException ex) {
89
             } catch (IOException ex) {
90
                 LOG.info("Exception when trying to notify NMA", ex);
90
                 LOG.info("Exception when trying to notify NMA", ex);
91
-                sendLine(origin, args.isSilent(), FORMAT_ERROR, "Unable to send: " + ex.
92
-                        getMessage());
91
+                showError(origin, args.isSilent(), "Unable to send: " + ex.getMessage());
93
             }
92
             }
94
         }, "NMA Thread").start();
93
         }, "NMA Thread").start();
95
     }
94
     }

+ 5
- 8
notifications/src/com/dmdirc/addons/notifications/NotificationCommand.java View File

79
                 final NotificationHandler handler = manager.getHandler(sourceName);
79
                 final NotificationHandler handler = manager.getHandler(sourceName);
80
 
80
 
81
                 if (handler == null) {
81
                 if (handler == null) {
82
-                    sendLine(origin, args.isSilent(), FORMAT_ERROR,
83
-                            "Method not found.");
82
+                    showError(origin, args.isSilent(), "Method not found.");
84
                 } else {
83
                 } else {
85
                     handler.showNotification("DMDirc", args.getArgumentsAsString(2));
84
                     handler.showNotification("DMDirc", args.getArgumentsAsString(2));
86
                 }
85
                 }
87
             } else {
86
             } else {
88
-                sendLine(origin, args.isSilent(), FORMAT_ERROR,
87
+                showError(origin, args.isSilent(),
89
                         "You must specify a method when using --method.");
88
                         "You must specify a method when using --method.");
90
             }
89
             }
91
         } else if (manager.hasActiveHandler()) {
90
         } else if (manager.hasActiveHandler()) {
92
             manager.getPreferredHandler().showNotification("DMDirc", args.getArgumentsAsString(0));
91
             manager.getPreferredHandler().showNotification("DMDirc", args.getArgumentsAsString(0));
93
         } else {
92
         } else {
94
-            sendLine(origin, args.isSilent(), FORMAT_ERROR,
95
-                    "No active notification methods available.");
93
+            showError(origin, args.isSilent(), "No active notification methods available.");
96
         }
94
         }
97
     }
95
     }
98
 
96
 
107
         final Collection<String> handlers = manager.getHandlerNames();
105
         final Collection<String> handlers = manager.getHandlerNames();
108
 
106
 
109
         if (handlers.isEmpty()) {
107
         if (handlers.isEmpty()) {
110
-            sendLine(origin, isSilent, FORMAT_ERROR, "No notification "
111
-                    + "methods available.");
108
+            showError(origin, isSilent, "No notification methods available.");
112
         } else {
109
         } else {
113
             final String[] headers = {"Method"};
110
             final String[] headers = {"Method"};
114
             final String[][] data = new String[handlers.size()][1];
111
             final String[][] data = new String[handlers.size()][1];
118
                 i++;
115
                 i++;
119
             }
116
             }
120
 
117
 
121
-            sendLine(origin, isSilent, FORMAT_OUTPUT, doTable(headers, data));
118
+            showOutput(origin, isSilent, doTable(headers, data));
122
         }
119
         }
123
     }
120
     }
124
 
121
 

+ 6
- 7
nowplaying/src/com/dmdirc/addons/nowplaying/NowPlayingCommand.java View File

101
                 final MediaSource source = manager.getSource(sourceName);
101
                 final MediaSource source = manager.getSource(sourceName);
102
 
102
 
103
                 if (source == null) {
103
                 if (source == null) {
104
-                    sendLine(origin, args.isSilent(), FORMAT_ERROR, "Source not found.");
104
+                    showError(origin, args.isSilent(), "Source not found.");
105
                 } else {
105
                 } else {
106
                     if (source.getState() == MediaSourceState.CLOSED) {
106
                     if (source.getState() == MediaSourceState.CLOSED) {
107
-                        sendLine(origin, args.isSilent(), FORMAT_ERROR, "Source is not running.");
107
+                        showError(origin, args.isSilent(), "Source is not running.");
108
                     } else {
108
                     } else {
109
                         target.getWindowModel().getCommandParser().parseCommand(origin,
109
                         target.getWindowModel().getCommandParser().parseCommand(origin,
110
                                 getInformation(source, args.getArgumentsAsString(2)));
110
                                 getInformation(source, args.getArgumentsAsString(2)));
111
                     }
111
                     }
112
                 }
112
                 }
113
             } else {
113
             } else {
114
-                sendLine(origin, args.isSilent(), FORMAT_ERROR,
114
+                showError(origin, args.isSilent(),
115
                         "You must specify a source when using --source.");
115
                         "You must specify a source when using --source.");
116
             }
116
             }
117
         } else {
117
         } else {
120
                         getInformation(manager.getBestSource(), args.
120
                         getInformation(manager.getBestSource(), args.
121
                                 getArgumentsAsString(0)));
121
                                 getArgumentsAsString(0)));
122
             } else {
122
             } else {
123
-                sendLine(origin, args.isSilent(), FORMAT_ERROR,
124
-                        "No running media sources available.");
123
+                showError(origin, args.isSilent(), "No running media sources available.");
125
             }
124
             }
126
         }
125
         }
127
     }
126
     }
138
         final List<MediaSource> sources = manager.getSources();
137
         final List<MediaSource> sources = manager.getSources();
139
 
138
 
140
         if (sources.isEmpty()) {
139
         if (sources.isEmpty()) {
141
-            sendLine(origin, isSilent, FORMAT_ERROR, "No media sources available.");
140
+            showError(origin, isSilent, "No media sources available.");
142
         } else {
141
         } else {
143
             final String[] headers = {"Source", "Status", "Information"};
142
             final String[] headers = {"Source", "Status", "Information"};
144
             final String[][] data = new String[sources.size()][3];
143
             final String[][] data = new String[sources.size()][3];
158
                 i++;
157
                 i++;
159
             }
158
             }
160
 
159
 
161
-            sendLine(origin, isSilent, FORMAT_OUTPUT, doTable(headers, data));
160
+            showOutput(origin, isSilent, doTable(headers, data));
162
         }
161
         }
163
     }
162
     }
164
 
163
 

+ 5
- 6
osd/src/com/dmdirc/addons/osd/OsdCommand.java View File

86
         } else if (args.getArguments().length > 0
86
         } else if (args.getArguments().length > 0
87
                 && "--timeout".equalsIgnoreCase(args.getArguments()[0])) {
87
                 && "--timeout".equalsIgnoreCase(args.getArguments()[0])) {
88
             if (args.getArguments().length < 2) {
88
             if (args.getArguments().length < 2) {
89
-                sendLine(origin, args.isSilent(), FORMAT_ERROR, "You "
90
-                        + "must specify a valid number for the OSD timeout.");
89
+                showError(origin, args.isSilent(),
90
+                        "You must specify a valid number for the OSD timeout.");
91
                 return;
91
                 return;
92
             }
92
             }
93
 
93
 
95
                 showOSD(Integer.parseInt(args.getArguments()[1]), null,
95
                 showOSD(Integer.parseInt(args.getArguments()[1]), null,
96
                         args.getArgumentsAsString(2));
96
                         args.getArgumentsAsString(2));
97
             } catch (NumberFormatException ex) {
97
             } catch (NumberFormatException ex) {
98
-                sendLine(origin, args.isSilent(), FORMAT_ERROR, "You "
99
-                        + "must specify a valid number for the OSD timeout.");
98
+                showError(origin, args.isSilent(),
99
+                        "You must specify a valid number for the OSD timeout.");
100
             }
100
             }
101
         } else {
101
         } else {
102
             showOSD(-1, null, args.getArgumentsAsString());
102
             showOSD(-1, null, args.getArgumentsAsString());
111
         if (arg == 0) {
111
         if (arg == 0) {
112
             res.add("--close");
112
             res.add("--close");
113
             res.add("--timeout");
113
             res.add("--timeout");
114
-        } else if (arg > 0 && context.getPreviousArgs().get(0)
115
-                .equals("--close")) {
114
+        } else if (arg > 0 && "--close".equals(context.getPreviousArgs().get(0))) {
116
             res.excludeAll();
115
             res.excludeAll();
117
         }
116
         }
118
 
117
 

+ 3
- 3
parserdebug/src/com/dmdirc/addons/parserdebug/ParserDebugCommand.java View File

82
         final Optional<Parser> parser = connection.getParser();
82
         final Optional<Parser> parser = connection.getParser();
83
 
83
 
84
         if (!parser.isPresent()) {
84
         if (!parser.isPresent()) {
85
-            sendLine(origin, isSilent, FORMAT_ERROR, "Unable to get a parser for this window.");
85
+            showError(origin, isSilent, "Unable to get a parser for this window.");
86
             return;
86
             return;
87
         }
87
         }
88
         if (parserDebugManager.containsParser(parser.get())) {
88
         if (parserDebugManager.containsParser(parser.get())) {
89
             parserDebugManager.removeParser(parser.get(), false);
89
             parserDebugManager.removeParser(parser.get(), false);
90
-            sendLine(origin, isSilent, FORMAT_OUTPUT, "Removed callback");
90
+            showOutput(origin, isSilent, "Removed callback");
91
         } else {
91
         } else {
92
             parserDebugManager.addParser(parser.get(), connection);
92
             parserDebugManager.addParser(parser.get(), connection);
93
-            sendLine(origin, isSilent, FORMAT_OUTPUT, "Added callback");
93
+            showOutput(origin, isSilent, "Added callback");
94
         }
94
         }
95
     }
95
     }
96
 
96
 

+ 4
- 20
redirect/src/com/dmdirc/addons/redirect/FakeWriteableFrameContainer.java View File

28
 import com.dmdirc.interfaces.WindowModel;
28
 import com.dmdirc.interfaces.WindowModel;
29
 import com.dmdirc.ui.messages.BackBufferFactory;
29
 import com.dmdirc.ui.messages.BackBufferFactory;
30
 import com.dmdirc.ui.messages.Formatter;
30
 import com.dmdirc.ui.messages.Formatter;
31
-import com.dmdirc.ui.messages.sink.MessageSinkManager;
32
 
31
 
33
 import java.util.Collections;
32
 import java.util.Collections;
34
 import java.util.Date;
33
 import java.util.Date;
47
      */
46
      */
48
     public FakeWriteableFrameContainer(
47
     public FakeWriteableFrameContainer(
49
             final WindowModel target,
48
             final WindowModel target,
50
-            final MessageSinkManager messageSinkManager,
51
             final DMDircMBassador eventBus,
49
             final DMDircMBassador eventBus,
52
             final BackBufferFactory backBufferFactory) {
50
             final BackBufferFactory backBufferFactory) {
53
         super(target, target.getIcon(), target.getName(), target.getTitle(),
51
         super(target, target.getIcon(), target.getName(), target.getTitle(),
54
                 target.getConfigManager(), backBufferFactory,
52
                 target.getConfigManager(), backBufferFactory,
55
-                target.getTabCompleter(), messageSinkManager, eventBus,
56
-                Collections.<String>emptyList());
53
+                target.getTabCompleter(), eventBus, Collections.<String>emptyList());
57
         this.target = target;
54
         this.target = target;
58
         initBackBuffer();
55
         initBackBuffer();
59
         setCommandParser(target.getCommandParser());
56
         setCommandParser(target.getCommandParser());
60
     }
57
     }
61
 
58
 
62
-    @Override
63
-    @Deprecated
64
-    public void addLine(final String line, final boolean timestamp) {
65
-        addLine(line);
66
-    }
67
-
68
     @Override
59
     @Override
69
     public void sendLine(final String line) {
60
     public void sendLine(final String line) {
70
         target.sendLine(line);
61
         target.sendLine(line);
71
     }
62
     }
72
 
63
 
73
     @Override
64
     @Override
65
+    @Deprecated
74
     public void addLine(final String type, final Date timestamp, final Object... args) {
66
     public void addLine(final String type, final Date timestamp, final Object... args) {
75
         addLine(type, args);
67
         addLine(type, args);
76
     }
68
     }
77
 
69
 
78
     @Override
70
     @Override
71
+    @Deprecated
79
     public void addLine(final String type, final Object... args) {
72
     public void addLine(final String type, final Object... args) {
80
         sendLine(Formatter.formatMessage(getConfigManager(), type, args));
73
         sendLine(Formatter.formatMessage(getConfigManager(), type, args));
81
     }
74
     }
82
 
75
 
83
     @Override
76
     @Override
84
-    public void addLine(final StringBuffer type, final Date timestamp, final Object... args) {
85
-        addLine(type, args);
86
-    }
87
-
88
-    @Override
89
-    public void addLine(final StringBuffer type, final Object... args) {
90
-        addLine(type.toString(), args);
91
-    }
92
-
93
-    @Override
77
+    @Deprecated
94
     public void addLine(final String line, final Date timestamp) {
78
     public void addLine(final String line, final Date timestamp) {
95
         addLine(line);
79
         addLine(line);
96
     }
80
     }

+ 1
- 6
redirect/src/com/dmdirc/addons/redirect/RedirectCommand.java View File

36
 import com.dmdirc.ui.input.AdditionalTabTargets;
36
 import com.dmdirc.ui.input.AdditionalTabTargets;
37
 import com.dmdirc.ui.input.TabCompleterUtils;
37
 import com.dmdirc.ui.input.TabCompleterUtils;
38
 import com.dmdirc.ui.messages.BackBufferFactory;
38
 import com.dmdirc.ui.messages.BackBufferFactory;
39
-import com.dmdirc.ui.messages.sink.MessageSinkManager;
40
 
39
 
41
 import javax.annotation.Nonnull;
40
 import javax.annotation.Nonnull;
42
 import javax.inject.Inject;
41
 import javax.inject.Inject;
52
             "redirect <command> - sends the output of the command to a "
51
             "redirect <command> - sends the output of the command to a "
53
             + "channel or query window",
52
             + "channel or query window",
54
             CommandType.TYPE_CHAT);
53
             CommandType.TYPE_CHAT);
55
-    /** The sink manager to use to dispatch messages. */
56
-    private final MessageSinkManager messageSinkManager;
57
     /** The bus to dispatch events on. */
54
     /** The bus to dispatch events on. */
58
     private final DMDircMBassador eventBus;
55
     private final DMDircMBassador eventBus;
59
     private final BackBufferFactory backBufferFactory;
56
     private final BackBufferFactory backBufferFactory;
66
     @Inject
63
     @Inject
67
     public RedirectCommand(
64
     public RedirectCommand(
68
             final CommandController controller,
65
             final CommandController controller,
69
-            final MessageSinkManager messageSinkManager,
70
             final DMDircMBassador eventBus,
66
             final DMDircMBassador eventBus,
71
             final BackBufferFactory backBufferFactory,
67
             final BackBufferFactory backBufferFactory,
72
             final TabCompleterUtils tabCompleterUtils) {
68
             final TabCompleterUtils tabCompleterUtils) {
73
         super(controller);
69
         super(controller);
74
-        this.messageSinkManager = messageSinkManager;
75
         this.eventBus = eventBus;
70
         this.eventBus = eventBus;
76
         this.backBufferFactory = backBufferFactory;
71
         this.backBufferFactory = backBufferFactory;
77
         this.tabCompleterUtils = tabCompleterUtils;
72
         this.tabCompleterUtils = tabCompleterUtils;
83
         final Chat target = ((ChatCommandContext) context).getChat();
78
         final Chat target = ((ChatCommandContext) context).getChat();
84
         target.getWindowModel().getCommandParser().parseCommand(
79
         target.getWindowModel().getCommandParser().parseCommand(
85
                 new FakeWriteableFrameContainer(target.getWindowModel(),
80
                 new FakeWriteableFrameContainer(target.getWindowModel(),
86
-                        messageSinkManager, eventBus, backBufferFactory),
81
+                        eventBus, backBufferFactory),
87
                 args.getArgumentsAsString());
82
                 args.getArgumentsAsString());
88
     }
83
     }
89
 
84
 

+ 28
- 32
scriptplugin/src/com/dmdirc/addons/scriptplugin/ScriptCommand.java View File

99
 
99
 
100
         if (sargs.length > 0 && ("rehash".equalsIgnoreCase(sargs[0]) ||
100
         if (sargs.length > 0 && ("rehash".equalsIgnoreCase(sargs[0]) ||
101
                 "reload".equalsIgnoreCase(sargs[0]))) {
101
                 "reload".equalsIgnoreCase(sargs[0]))) {
102
-            sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Reloading scripts");
102
+            showOutput(origin, args.isSilent(), "Reloading scripts");
103
             scriptManager.rehash();
103
             scriptManager.rehash();
104
         } else if (sargs.length > 0 && "load".equalsIgnoreCase(sargs[0])) {
104
         } else if (sargs.length > 0 && "load".equalsIgnoreCase(sargs[0])) {
105
             if (sargs.length > 1) {
105
             if (sargs.length > 1) {
106
                 final String filename = args.getArgumentsAsString(1);
106
                 final String filename = args.getArgumentsAsString(1);
107
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Loading: " + filename + " ["
107
+                showOutput(origin, args.isSilent(), "Loading: " + filename + " ["
108
                         + scriptManager.loadScript(scriptDirectory + filename) + ']');
108
                         + scriptManager.loadScript(scriptDirectory + filename) + ']');
109
             } else {
109
             } else {
110
-                sendLine(origin, args.isSilent(), FORMAT_ERROR, "You must specify a script to load");
110
+                showError(origin, args.isSilent(), "You must specify a script to load");
111
             }
111
             }
112
         } else if (sargs.length > 0 && "unload".equalsIgnoreCase(sargs[0])) {
112
         } else if (sargs.length > 0 && "unload".equalsIgnoreCase(sargs[0])) {
113
             if (sargs.length > 1) {
113
             if (sargs.length > 1) {
114
                 final String filename = args.getArgumentsAsString(1);
114
                 final String filename = args.getArgumentsAsString(1);
115
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Unloading: " + filename + " ["
115
+                showOutput(origin, args.isSilent(), "Unloading: " + filename + " ["
116
                         + scriptManager.loadScript(scriptDirectory + filename) + ']');
116
                         + scriptManager.loadScript(scriptDirectory + filename) + ']');
117
             } else {
117
             } else {
118
-                sendLine(origin, args.isSilent(), FORMAT_ERROR,
119
-                        "You must specify a script to unload");
118
+                showError(origin, args.isSilent(), "You must specify a script to unload");
120
             }
119
             }
121
         } else if (sargs.length > 0 && "eval".equalsIgnoreCase(sargs[0])) {
120
         } else if (sargs.length > 0 && "eval".equalsIgnoreCase(sargs[0])) {
122
             if (sargs.length > 1) {
121
             if (sargs.length > 1) {
123
                 final String script = args.getArgumentsAsString(1);
122
                 final String script = args.getArgumentsAsString(1);
124
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Evaluating: " + script);
123
+                showOutput(origin, args.isSilent(), "Evaluating: " + script);
125
                 try {
124
                 try {
126
                     final ScriptEngineWrapper wrapper;
125
                     final ScriptEngineWrapper wrapper;
127
                     if (globalConfig.hasOptionString(domain, "eval.baseFile")) {
126
                     if (globalConfig.hasOptionString(domain, "eval.baseFile")) {
138
                     wrapper.getScriptEngine().put("cmd_origin", origin);
137
                     wrapper.getScriptEngine().put("cmd_origin", origin);
139
                     wrapper.getScriptEngine().put("cmd_isSilent", args.isSilent());
138
                     wrapper.getScriptEngine().put("cmd_isSilent", args.isSilent());
140
                     wrapper.getScriptEngine().put("cmd_args", sargs);
139
                     wrapper.getScriptEngine().put("cmd_args", sargs);
141
-                    sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Result: " + wrapper.
142
-                            getScriptEngine().eval(script));
140
+                    showOutput(origin, args.isSilent(), "Result: "
141
+                            + wrapper.getScriptEngine().eval(script));
143
                 } catch (ScriptException e) {
142
                 } catch (ScriptException e) {
144
-                    sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Exception: " + e + " -> " + e.
145
-                            getMessage());
143
+                    showOutput(origin, args.isSilent(), "Exception: " + e + " -> "
144
+                            + e.getMessage());
146
 
145
 
147
                     if (globalConfig.getOptionBool(domain, "eval.showStackTrace")) {
146
                     if (globalConfig.getOptionBool(domain, "eval.showStackTrace")) {
148
                         final String[] stacktrace = getTrace(e);
147
                         final String[] stacktrace = getTrace(e);
149
                         for (String line : stacktrace) {
148
                         for (String line : stacktrace) {
150
-                            sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Stack trace: " + line);
149
+                            showOutput(origin, args.isSilent(), "Stack trace: " + line);
151
                         }
150
                         }
152
                     }
151
                     }
153
 
152
 
154
                 }
153
                 }
155
             } else {
154
             } else {
156
-                sendLine(origin, args.isSilent(), FORMAT_ERROR,
157
-                        "You must specify some script to eval.");
155
+                showError(origin, args.isSilent(), "You must specify some script to eval.");
158
             }
156
             }
159
         } else if (sargs.length > 0 && "savetobasefile".equalsIgnoreCase(sargs[0])) {
157
         } else if (sargs.length > 0 && "savetobasefile".equalsIgnoreCase(sargs[0])) {
160
             if (sargs.length > 2) {
158
             if (sargs.length > 2) {
161
                 final String[] bits = sargs[1].split("/");
159
                 final String[] bits = sargs[1].split("/");
162
                 final String functionName = bits[0];
160
                 final String functionName = bits[0];
163
                 final String script = args.getArgumentsAsString(2);
161
                 final String script = args.getArgumentsAsString(2);
164
-                sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Saving as '" + functionName
162
+                showOutput(origin, args.isSilent(), "Saving as '" + functionName
165
                         + "': " + script);
163
                         + "': " + script);
166
                 if (globalConfig.hasOptionString(domain, "eval.baseFile")) {
164
                 if (globalConfig.hasOptionString(domain, "eval.baseFile")) {
167
                     try {
165
                     try {
181
                             writer.flush();
179
                             writer.flush();
182
                         }
180
                         }
183
                     } catch (IOException ioe) {
181
                     } catch (IOException ioe) {
184
-                        sendLine(origin, args.isSilent(), FORMAT_ERROR, "IOException: " + ioe.
185
-                                getMessage());
182
+                        showError(origin, args.isSilent(), "IOException: " + ioe.getMessage());
186
                     }
183
                     }
187
                 } else {
184
                 } else {
188
-                    sendLine(origin, args.isSilent(), FORMAT_ERROR,
185
+                    showError(origin, args.isSilent(),
189
                             "No baseFile specified, please /set " + domain
186
                             "No baseFile specified, please /set " + domain
190
                             + " eval.baseFile filename (stored in scripts dir of profile)");
187
                             + " eval.baseFile filename (stored in scripts dir of profile)");
191
                 }
188
                 }
192
             } else if (sargs.length > 1) {
189
             } else if (sargs.length > 1) {
193
-                sendLine(origin, args.isSilent(), FORMAT_ERROR,
194
-                        "You must specify some script to save.");
190
+                showError(origin, args.isSilent(), "You must specify some script to save.");
195
             } else {
191
             } else {
196
-                sendLine(origin, args.isSilent(), FORMAT_ERROR,
192
+                showError(origin, args.isSilent(),
197
                         "You must specify a function name and some script to save.");
193
                         "You must specify a function name and some script to save.");
198
             }
194
             }
199
         } else if (sargs.length > 0 && "help".equalsIgnoreCase(sargs[0])) {
195
         } else if (sargs.length > 0 && "help".equalsIgnoreCase(sargs[0])) {
200
-            sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
196
+            showOutput(origin, args.isSilent(),
201
                     "This command allows you to interact with the script plugin");
197
                     "This command allows you to interact with the script plugin");
202
-            sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "-------------------");
203
-            sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
198
+            showOutput(origin, args.isSilent(), "-------------------");
199
+            showOutput(origin, args.isSilent(),
204
                     "reload/rehash                  - Reload all loaded scripts");
200
                     "reload/rehash                  - Reload all loaded scripts");
205
-            sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
201
+            showOutput(origin, args.isSilent(),
206
                     "load <script>                  - load scripts/<script> (file name relative to scripts dir)");
202
                     "load <script>                  - load scripts/<script> (file name relative to scripts dir)");
207
-            sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
203
+            showOutput(origin, args.isSilent(),
208
                     "unload <script>                - unload <script> (full file name)");
204
                     "unload <script>                - unload <script> (full file name)");
209
-            sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
205
+            showOutput(origin, args.isSilent(),
210
                     "eval <script>                  - evaluate the code <script> and return the result");
206
                     "eval <script>                  - evaluate the code <script> and return the result");
211
-            sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
207
+            showOutput(origin, args.isSilent(),
212
                     "savetobasefile <name> <script> - save the code <script> to the eval basefile ("
208
                     "savetobasefile <name> <script> - save the code <script> to the eval basefile ("
213
                     + domain + ".eval.basefile)");
209
                     + domain + ".eval.basefile)");
214
-            sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
210
+            showOutput(origin, args.isSilent(),
215
                     "                                 as the function <name> (name/foo/bar will save it as 'name' with foo and");
211
                     "                                 as the function <name> (name/foo/bar will save it as 'name' with foo and");
216
-            sendLine(origin, args.isSilent(), FORMAT_OUTPUT,
212
+            showOutput(origin, args.isSilent(),
217
                     "                                 bar as arguments.");
213
                     "                                 bar as arguments.");
218
-            sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "-------------------");
214
+            showOutput(origin, args.isSilent(), "-------------------");
219
         } else {
215
         } else {
220
-            sendLine(origin, args.isSilent(), FORMAT_ERROR, "Unknown subcommand.");
216
+            showError(origin, args.isSilent(), "Unknown subcommand.");
221
         }
217
         }
222
     }
218
     }
223
 
219
 

+ 4
- 0
tabcompletion_bash/res/META-INF/format.yml View File

1
+---
2
+BashDisambiguationEvent:
3
+  format: "Multiple possibilities: {{matches}}."
4
+  colour: 14

activewindow/test/com/dmdirc/addons/activewindow/ActiveWindowManagerTest.java → tabcompletion_bash/src/com/dmdirc/addons/tabcompletion_bash/BashDisambiguationEvent.java View File

20
  * SOFTWARE.
20
  * SOFTWARE.
21
  */
21
  */
22
 
22
 
23
-package com.dmdirc.addons.activewindow;
23
+package com.dmdirc.addons.tabcompletion_bash;
24
 
24
 
25
-import com.dmdirc.ui.messages.sink.MessageSinkManager;
25
+import com.dmdirc.events.BaseDisplayableEvent;
26
+import com.dmdirc.interfaces.WindowModel;
26
 
27
 
27
-import org.junit.Before;
28
-import org.junit.Test;
29
-import org.junit.runner.RunWith;
30
-import org.mockito.Mock;
31
-import org.mockito.runners.MockitoJUnitRunner;
32
-
33
-import static org.mockito.Mockito.verify;
34
-
35
-@RunWith(MockitoJUnitRunner.class)
36
-public class ActiveWindowManagerTest {
28
+/**
29
+ * Event raised when multiple potential results match a bash-style completion attempt.
30
+ */
31
+public class BashDisambiguationEvent extends BaseDisplayableEvent {
37
 
32
 
38
-    @Mock private MessageSinkManager messageSinkManager;
39
-    @Mock private ActiveWindowMessageSink activeWindowMessageSink;
40
-    private ActiveWindowManager activeWindowManager;
33
+    private final String matches;
41
 
34
 
42
-    @Before
43
-    public void setUp() throws Exception {
44
-        activeWindowManager = new ActiveWindowManager(messageSinkManager, activeWindowMessageSink);
35
+    public BashDisambiguationEvent(final long timestamp, final WindowModel source,
36
+            final String matches) {
37
+        super(timestamp, source);
38
+        this.matches = matches;
45
     }
39
     }
46
 
40
 
47
-    @Test
48
-    public void testRegister() throws Exception {
49
-        activeWindowManager.register();
50
-        verify(messageSinkManager).addSink(activeWindowMessageSink);
41
+    public BashDisambiguationEvent(final WindowModel source, final String matches) {
42
+        super(source);
43
+        this.matches = matches;
51
     }
44
     }
52
 
45
 
53
-    @Test
54
-    public void testUnregister() throws Exception {
55
-        activeWindowManager.unregister();
56
-        verify(messageSinkManager).removeSink(activeWindowMessageSink);
46
+    public String getMatches() {
47
+        return matches;
57
     }
48
     }
58
-}
49
+
50
+}

+ 2
- 2
tabcompletion_bash/src/com/dmdirc/addons/tabcompletion_bash/BashStyle.java View File

88
 
88
 
89
             final String sub = getBestSubstring(res);
89
             final String sub = getBestSubstring(res);
90
             if (sub.equalsIgnoreCase(word) && tabCount >= 2) {
90
             if (sub.equalsIgnoreCase(word) && tabCount >= 2) {
91
-                window.addLine("tabCompletion", res.toString());
92
-
91
+                window.getEventBus().publishAsync(
92
+                        new BashDisambiguationEvent(window, res.toString()));
93
                 return null;
93
                 return null;
94
             } else {
94
             } else {
95
                 return new TabCompletionResult(
95
                 return new TabCompletionResult(

+ 6
- 7
time/src/com/dmdirc/addons/time/TimerCommand.java View File

109
         }
109
         }
110
 
110
 
111
         if (interval < 1) {
111
         if (interval < 1) {
112
-            sendLine(origin, args.isSilent(), FORMAT_ERROR, "Cannot use intervals below 1");
112
+            showError(origin, args.isSilent(), "Cannot use intervals below 1");
113
             return;
113
             return;
114
         }
114
         }
115
 
115
 
116
         manager.addTimer(repetitions, interval, command, origin);
116
         manager.addTimer(repetitions, interval, command, origin);
117
-
118
-        sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Command scheduled.");
117
+        showOutput(origin, args.isSilent(), "Command scheduled.");
119
     }
118
     }
120
 
119
 
121
     private void doCancel(final WindowModel origin, final boolean isSilent, final String arg) {
120
     private void doCancel(final WindowModel origin, final boolean isSilent, final String arg) {
128
         }
127
         }
129
         if (manager.hasTimerWithID(timerKey)) {
128
         if (manager.hasTimerWithID(timerKey)) {
130
             manager.getTimerByID(timerKey).cancelTimer();
129
             manager.getTimerByID(timerKey).cancelTimer();
131
-            sendLine(origin, isSilent, FORMAT_OUTPUT, "Timer cancelled");
130
+            showOutput(origin, isSilent, "Timer cancelled");
132
         } else {
131
         } else {
133
-            sendLine(origin, isSilent, FORMAT_ERROR, "There is currently no timer with that ID");
132
+            showError(origin, isSilent, "There is currently no timer with that ID");
134
         }
133
         }
135
     }
134
     }
136
 
135
 
137
     private void doList(final WindowModel origin, final boolean isSilent) {
136
     private void doList(final WindowModel origin, final boolean isSilent) {
138
         final Set<Entry<Integer, TimedCommand>> timerList = manager.listTimers();
137
         final Set<Entry<Integer, TimedCommand>> timerList = manager.listTimers();
139
         if (timerList.isEmpty()) {
138
         if (timerList.isEmpty()) {
140
-            sendLine(origin, isSilent, FORMAT_ERROR, "There are currently no active timers");
139
+            showError(origin, isSilent, "There are currently no active timers");
141
         } else {
140
         } else {
142
             for (Entry<Integer, TimedCommand> entry : timerList) {
141
             for (Entry<Integer, TimedCommand> entry : timerList) {
143
-                sendLine(origin, isSilent, FORMAT_OUTPUT,
142
+                showOutput(origin, isSilent,
144
                         "Timer ID: " + entry.getKey() + " - " + entry.getValue().getCommand());
143
                         "Timer ID: " + entry.getKey() + " - " + entry.getValue().getCommand());
145
             }
144
             }
146
         }
145
         }

+ 22
- 16
time/test/com/dmdirc/addons/time/TimerCommandTest.java View File

22
 
22
 
23
 package com.dmdirc.addons.time;
23
 package com.dmdirc.addons.time;
24
 
24
 
25
+import com.dmdirc.DMDircMBassador;
25
 import com.dmdirc.commandparser.CommandArguments;
26
 import com.dmdirc.commandparser.CommandArguments;
26
 import com.dmdirc.commandparser.commands.IntelligentCommand.IntelligentCommandContext;
27
 import com.dmdirc.commandparser.commands.IntelligentCommand.IntelligentCommandContext;
27
 import com.dmdirc.commandparser.commands.context.CommandContext;
28
 import com.dmdirc.commandparser.commands.context.CommandContext;
29
+import com.dmdirc.events.CommandErrorEvent;
30
+import com.dmdirc.events.CommandOutputEvent;
28
 import com.dmdirc.interfaces.CommandController;
31
 import com.dmdirc.interfaces.CommandController;
29
 import com.dmdirc.interfaces.WindowModel;
32
 import com.dmdirc.interfaces.WindowModel;
30
 import com.dmdirc.ui.input.AdditionalTabTargets;
33
 import com.dmdirc.ui.input.AdditionalTabTargets;
36
 import org.junit.Before;
39
 import org.junit.Before;
37
 import org.junit.Test;
40
 import org.junit.Test;
38
 import org.junit.runner.RunWith;
41
 import org.junit.runner.RunWith;
42
+import org.mockito.ArgumentCaptor;
43
+import org.mockito.Captor;
39
 import org.mockito.Mock;
44
 import org.mockito.Mock;
40
 import org.mockito.runners.MockitoJUnitRunner;
45
 import org.mockito.runners.MockitoJUnitRunner;
41
 
46
 
42
 import static junit.framework.TestCase.assertEquals;
47
 import static junit.framework.TestCase.assertEquals;
43
 import static org.mockito.Matchers.anyInt;
48
 import static org.mockito.Matchers.anyInt;
44
-import static org.mockito.Matchers.eq;
45
 import static org.mockito.Mockito.never;
49
 import static org.mockito.Mockito.never;
46
 import static org.mockito.Mockito.times;
50
 import static org.mockito.Mockito.times;
47
 import static org.mockito.Mockito.verify;
51
 import static org.mockito.Mockito.verify;
53
     @Mock private TimerManager timerManager;
57
     @Mock private TimerManager timerManager;
54
     @Mock private CommandController commandController;
58
     @Mock private CommandController commandController;
55
     @Mock private WindowModel frameContainer;
59
     @Mock private WindowModel frameContainer;
60
+    @Mock private DMDircMBassador eventbus;
56
     @Mock private CommandContext commandContext;
61
     @Mock private CommandContext commandContext;
57
     @Mock private IntelligentCommandContext intelligentCommandContext;
62
     @Mock private IntelligentCommandContext intelligentCommandContext;
58
     @Mock private CommandArguments commandArguments;
63
     @Mock private CommandArguments commandArguments;
59
     @Mock private TimedCommand timer;
64
     @Mock private TimedCommand timer;
65
+    @Captor private ArgumentCaptor<CommandOutputEvent> outputEventCaptor;
66
+    @Captor private ArgumentCaptor<CommandErrorEvent> errorEventCaptor;
60
 
67
 
61
     private TimerCommand instance;
68
     private TimerCommand instance;
62
 
69
 
66
         when(commandArguments.isSilent()).thenReturn(false);
73
         when(commandArguments.isSilent()).thenReturn(false);
67
         when(timerManager.getTimerByID(anyInt())).thenReturn(timer);
74
         when(timerManager.getTimerByID(anyInt())).thenReturn(timer);
68
         when(commandController.getCommandChar()).thenReturn('/');
75
         when(commandController.getCommandChar()).thenReturn('/');
76
+        when(frameContainer.getEventBus()).thenReturn(eventbus);
69
     }
77
     }
70
 
78
 
71
     private void mockCommandArguments(final String one, final String two) {
79
     private void mockCommandArguments(final String one, final String two) {
128
         mockCommandArguments("--list", "", "");
136
         mockCommandArguments("--list", "", "");
129
         instance.execute(frameContainer, commandArguments, commandContext);
137
         instance.execute(frameContainer, commandArguments, commandContext);
130
         verify(timerManager, times(1)).listTimers();
138
         verify(timerManager, times(1)).listTimers();
131
-        verify(frameContainer).addLine("commandError", "There are currently no active timers");
139
+        verify(eventbus).publishAsync(errorEventCaptor.capture());
140
+        assertEquals("There are currently no active timers", errorEventCaptor.getValue().getMessage());
132
     }
141
     }
133
 
142
 
134
     @Test
143
     @Test
138
         mockCommandArguments("--list", "", "");
147
         mockCommandArguments("--list", "", "");
139
         instance.execute(frameContainer, commandArguments, commandContext);
148
         instance.execute(frameContainer, commandArguments, commandContext);
140
         verify(timerManager, times(1)).listTimers();
149
         verify(timerManager, times(1)).listTimers();
141
-        verify(frameContainer).addLine("commandOutput", "Timer ID: 1 - null");
150
+        verify(eventbus).publishAsync(outputEventCaptor.capture());
151
+        assertEquals("Timer ID: 1 - null", outputEventCaptor.getValue().getMessage());
142
     }
152
     }
143
 
153
 
144
     @Test
154
     @Test
145
     public void testExecute_incorrect() throws Exception {
155
     public void testExecute_incorrect() throws Exception {
146
         mockCommandArguments("woop", "woop");
156
         mockCommandArguments("woop", "woop");
147
         instance.execute(frameContainer, commandArguments, commandContext);
157
         instance.execute(frameContainer, commandArguments, commandContext);
148
-        verify(frameContainer, times(1)).addLine(eq("commandUsage"), eq('/'),
149
-                eq(TimerCommand.INFO.getName()), eq(TimerCommand.INFO.getHelp()));
158
+        verify(eventbus).publishAsync(errorEventCaptor.capture());
150
     }
159
     }
151
 
160
 
152
     @Test
161
     @Test
153
     public void testExecute_no_args() throws Exception {
162
     public void testExecute_no_args() throws Exception {
154
         when(commandArguments.getArguments()).thenReturn(new String[0]);
163
         when(commandArguments.getArguments()).thenReturn(new String[0]);
155
         instance.execute(frameContainer, commandArguments, commandContext);
164
         instance.execute(frameContainer, commandArguments, commandContext);
156
-        verify(frameContainer, times(1)).addLine(eq("commandUsage"), eq('/'),
157
-                eq(TimerCommand.INFO.getName()), eq(TimerCommand.INFO.getHelp()));
165
+        verify(eventbus).publishAsync(errorEventCaptor.capture());
158
     }
166
     }
159
 
167
 
160
     @Test
168
     @Test
161
     public void testExecute_too_few_args() throws Exception {
169
     public void testExecute_too_few_args() throws Exception {
162
         mockCommandArguments("woop", "woop");
170
         mockCommandArguments("woop", "woop");
163
         instance.execute(frameContainer, commandArguments, commandContext);
171
         instance.execute(frameContainer, commandArguments, commandContext);
164
-        verify(frameContainer, times(1)).addLine(eq("commandUsage"), eq('/'),
165
-                eq(TimerCommand.INFO.getName()), eq(TimerCommand.INFO.getHelp()));
172
+        verify(eventbus).publishAsync(errorEventCaptor.capture());
166
     }
173
     }
167
 
174
 
168
     @Test
175
     @Test
169
     public void testExecute_repetitions_not_number() throws Exception {
176
     public void testExecute_repetitions_not_number() throws Exception {
170
         mockCommandArguments("woop", "woop", "woop");
177
         mockCommandArguments("woop", "woop", "woop");
171
         instance.execute(frameContainer, commandArguments, commandContext);
178
         instance.execute(frameContainer, commandArguments, commandContext);
172
-        verify(frameContainer, times(1)).addLine(eq("commandUsage"), eq('/'),
173
-                eq(TimerCommand.INFO.getName()), eq(TimerCommand.INFO.getHelp()));
179
+        verify(eventbus).publishAsync(errorEventCaptor.capture());
174
     }
180
     }
175
 
181
 
176
     @Test
182
     @Test
177
     public void testExecute_interval_not_number() throws Exception {
183
     public void testExecute_interval_not_number() throws Exception {
178
         mockCommandArguments("1", "woop", "woop");
184
         mockCommandArguments("1", "woop", "woop");
179
         instance.execute(frameContainer, commandArguments, commandContext);
185
         instance.execute(frameContainer, commandArguments, commandContext);
180
-        verify(frameContainer, times(1)).addLine(eq("commandUsage"), eq('/'),
181
-                eq(TimerCommand.INFO.getName()), eq(TimerCommand.INFO.getHelp()));
186
+        verify(eventbus).publishAsync(errorEventCaptor.capture());
182
     }
187
     }
183
 
188
 
184
     @Test
189
     @Test
185
     public void testExecute_interval_invalid() throws Exception {
190
     public void testExecute_interval_invalid() throws Exception {
186
         mockCommandArguments("1", "0", "woop");
191
         mockCommandArguments("1", "0", "woop");
187
         instance.execute(frameContainer, commandArguments, commandContext);
192
         instance.execute(frameContainer, commandArguments, commandContext);
188
-        verify(frameContainer, times(1))
189
-                .addLine(eq("commandError"), eq("Cannot use intervals below 1"));
193
+        verify(eventbus).publishAsync(errorEventCaptor.capture());
194
+        assertEquals("Cannot use intervals below 1", errorEventCaptor.getValue().getMessage());
190
     }
195
     }
191
 
196
 
192
     @Test
197
     @Test
194
         mockCommandArguments("1", "1", "woop");
199
         mockCommandArguments("1", "1", "woop");
195
         instance.execute(frameContainer, commandArguments, commandContext);
200
         instance.execute(frameContainer, commandArguments, commandContext);
196
         verify(timerManager).addTimer(1, 1, "woop", frameContainer);
201
         verify(timerManager).addTimer(1, 1, "woop", frameContainer);
197
-        verify(frameContainer, times(1)).addLine(eq("commandOutput"), eq("Command scheduled."));
202
+        verify(eventbus).publishAsync(outputEventCaptor.capture());
203
+        assertEquals("Command scheduled.", outputEventCaptor.getValue().getMessage());
198
     }
204
     }
199
 
205
 
200
     @Test
206
     @Test

+ 2
- 1
ui_swing/plugin.config View File

33
     showfulltopic=false
33
     showfulltopic=false
34
     hideEmptyTopicBar=false
34
     hideEmptyTopicBar=false
35
     textpanebackground=
35
     textpanebackground=
36
-    textpanebackgroundoption=STRETCH
36
+    textpanebackgroundoption=SCALE
37
+    textpanebackgroundopacity=1
37
     desktopbackground=dmdirc://com/dmdirc/res/background.png
38
     desktopbackground=dmdirc://com/dmdirc/res/background.png
38
     desktopbackgroundoption=CENTER
39
     desktopbackgroundoption=CENTER
39
     showjrewarning=true
40
     showjrewarning=true

+ 25
- 9
ui_swing/src/com/dmdirc/addons/ui_swing/UIUtilities.java View File

28
 import com.dmdirc.addons.ui_swing.components.SupplierLoggingSwingWorker;
28
 import com.dmdirc.addons.ui_swing.components.SupplierLoggingSwingWorker;
29
 import com.dmdirc.util.colours.Colour;
29
 import com.dmdirc.util.colours.Colour;
30
 
30
 
31
+import java.awt.AlphaComposite;
31
 import java.awt.Color;
32
 import java.awt.Color;
33
+import java.awt.Composite;
32
 import java.awt.Font;
34
 import java.awt.Font;
33
 import java.awt.FontMetrics;
35
 import java.awt.FontMetrics;
34
 import java.awt.Graphics2D;
36
 import java.awt.Graphics2D;
457
      * @param bounds           Bounds to paint within
459
      * @param bounds           Bounds to paint within
458
      * @param backgroundImage  background image
460
      * @param backgroundImage  background image
459
      * @param backgroundOption How to draw the background
461
      * @param backgroundOption How to draw the background
462
+     * @param opacity          Opacity of the image
460
      */
463
      */
461
     public static void paintBackground(final Graphics2D g,
464
     public static void paintBackground(final Graphics2D g,
462
             final Rectangle bounds,
465
             final Rectangle bounds,
463
             final Image backgroundImage,
466
             final Image backgroundImage,
464
-            final BackgroundOption backgroundOption) {
467
+            final BackgroundOption backgroundOption,
468
+            final float opacity) {
465
         if (backgroundImage == null) {
469
         if (backgroundImage == null) {
466
             paintNoBackground(g, bounds);
470
             paintNoBackground(g, bounds);
467
         } else {
471
         } else {
468
             switch (backgroundOption) {
472
             switch (backgroundOption) {
469
                 case TILED:
473
                 case TILED:
470
-                    paintTiledBackground(g, bounds, backgroundImage);
474
+                    paintTiledBackground(g, bounds, backgroundImage, opacity);
471
                     break;
475
                     break;
472
                 case SCALE:
476
                 case SCALE:
473
-                    paintStretchedBackground(g, bounds, backgroundImage);
477
+                    paintStretchedBackground(g, bounds, backgroundImage, opacity);
474
                     break;
478
                     break;
475
                 case SCALE_ASPECT_RATIO:
479
                 case SCALE_ASPECT_RATIO:
476
-                    paintStretchedAspectRatioBackground(g, bounds, backgroundImage);
480
+                    paintStretchedAspectRatioBackground(g, bounds, backgroundImage, opacity);
477
                     break;
481
                     break;
478
                 case CENTER:
482
                 case CENTER:
479
-                    paintCenterBackground(g, bounds, backgroundImage);
483
+                    paintCenterBackground(g, bounds, backgroundImage, opacity);
480
                     break;
484
                     break;
481
                 default:
485
                 default:
482
                     break;
486
                     break;
489
     }
493
     }
490
 
494
 
491
     private static void paintStretchedBackground(final Graphics2D g,
495
     private static void paintStretchedBackground(final Graphics2D g,
492
-            final Rectangle bounds, final Image backgroundImage) {
496
+            final Rectangle bounds, final Image backgroundImage, final float opacity) {
497
+        final Composite originalComposite = g.getComposite();
498
+        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity));
493
         g.drawImage(backgroundImage, 0, 0, bounds.width, bounds.height, null);
499
         g.drawImage(backgroundImage, 0, 0, bounds.width, bounds.height, null);
500
+        g.setComposite(originalComposite);
494
     }
501
     }
495
 
502
 
496
     private static void paintCenterBackground(final Graphics2D g,
503
     private static void paintCenterBackground(final Graphics2D g,
497
-            final Rectangle bounds, final Image backgroundImage) {
504
+            final Rectangle bounds, final Image backgroundImage, final float opacity) {
498
         final int x = bounds.width / 2 - backgroundImage.getWidth(null) / 2;
505
         final int x = bounds.width / 2 - backgroundImage.getWidth(null) / 2;
499
         final int y = bounds.height / 2 - backgroundImage.getHeight(null) / 2;
506
         final int y = bounds.height / 2 - backgroundImage.getHeight(null) / 2;
507
+        final Composite originalComposite = g.getComposite();
508
+        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity));
500
         g.drawImage(backgroundImage, x, y, backgroundImage.getWidth(null),
509
         g.drawImage(backgroundImage, x, y, backgroundImage.getWidth(null),
501
                 backgroundImage.getHeight(null), null);
510
                 backgroundImage.getHeight(null), null);
511
+        g.setComposite(originalComposite);
502
     }
512
     }
503
 
513
 
504
     private static void paintStretchedAspectRatioBackground(final Graphics2D g,
514
     private static void paintStretchedAspectRatioBackground(final Graphics2D g,
505
-            final Rectangle bounds, final Image backgroundImage) {
515
+            final Rectangle bounds, final Image backgroundImage, final float opacity) {
506
         final double widthratio = bounds.width
516
         final double widthratio = bounds.width
507
                 / (double) backgroundImage.getWidth(null);
517
                 / (double) backgroundImage.getWidth(null);
508
         final double heightratio = bounds.height
518
         final double heightratio = bounds.height
513
 
523
 
514
         final int x = bounds.width / 2 - width / 2;
524
         final int x = bounds.width / 2 - width / 2;
515
         final int y = bounds.height / 2 - height / 2;
525
         final int y = bounds.height / 2 - height / 2;
526
+        final Composite originalComposite = g.getComposite();
527
+        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity));
516
         g.drawImage(backgroundImage, x, y, width, height, null);
528
         g.drawImage(backgroundImage, x, y, width, height, null);
529
+        g.setComposite(originalComposite);
517
     }
530
     }
518
 
531
 
519
     private static void paintTiledBackground(final Graphics2D g,
532
     private static void paintTiledBackground(final Graphics2D g,
520
-            final Rectangle bounds, final Image backgroundImage) {
533
+            final Rectangle bounds, final Image backgroundImage, final float opacity) {
521
         final int width = backgroundImage.getWidth(null);
534
         final int width = backgroundImage.getWidth(null);
522
         final int height = backgroundImage.getHeight(null);
535
         final int height = backgroundImage.getHeight(null);
523
 
536
 
526
             return;
539
             return;
527
         }
540
         }
528
 
541
 
542
+        final Composite originalComposite = g.getComposite();
543
+        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity));
529
         for (int x = 0; x < bounds.width; x += width) {
544
         for (int x = 0; x < bounds.width; x += width) {
530
             for (int y = 0; y < bounds.height; y += height) {
545
             for (int y = 0; y < bounds.height; y += height) {
531
                 g.drawImage(backgroundImage, x, y, width, height, null);
546
                 g.drawImage(backgroundImage, x, y, width, height, null);
532
             }
547
             }
533
         }
548
         }
549
+        g.setComposite(originalComposite);
534
     }
550
     }
535
 
551
 
536
     /**
552
     /**

+ 1
- 2
ui_swing/src/com/dmdirc/addons/ui_swing/commands/PopInCommand.java View File

70
         UIUtilities.invokeLater(() -> {
70
         UIUtilities.invokeLater(() -> {
71
             final TextFrame swingWindow = windowFactory.getSwingWindow(origin);
71
             final TextFrame swingWindow = windowFactory.getSwingWindow(origin);
72
             if (swingWindow == null) {
72
             if (swingWindow == null) {
73
-                sendLine(origin, args.isSilent(), FORMAT_ERROR, "There is"
74
-                        + " currently no window to pop in.");
73
+                showError(origin, args.isSilent(), "There is currently no window to pop in.");
75
             } else {
74
             } else {
76
                 swingWindow.setPopout(false);
75
                 swingWindow.setPopout(false);
77
             }
76
             }

+ 1
- 2
ui_swing/src/com/dmdirc/addons/ui_swing/commands/PopOutCommand.java View File

70
         UIUtilities.invokeLater(() -> {
70
         UIUtilities.invokeLater(() -> {
71
             final TextFrame swingWindow = windowFactory.getSwingWindow(origin);
71
             final TextFrame swingWindow = windowFactory.getSwingWindow(origin);
72
             if (swingWindow == null) {
72
             if (swingWindow == null) {
73
-                sendLine(origin, args.isSilent(), FORMAT_ERROR, "There is"
74
-                        + " currently no window to pop out.");
73
+                showError(origin, args.isSilent(), "There is currently no window to pop out.");
75
             } else {
74
             } else {
76
                 swingWindow.setPopout(true);
75
                 swingWindow.setPopout(true);
77
             }
76
             }

+ 1
- 2
ui_swing/src/com/dmdirc/addons/ui_swing/dialogs/channelsetting/TopicDisplayPane.java View File

41
 import java.awt.Color;
41
 import java.awt.Color;
42
 import java.awt.datatransfer.Clipboard;
42
 import java.awt.datatransfer.Clipboard;
43
 import java.awt.event.KeyEvent;
43
 import java.awt.event.KeyEvent;
44
-import java.util.Date;
45
 import java.util.Optional;
44
 import java.util.Optional;
46
 
45
 
47
 import javax.swing.JLabel;
46
 import javax.swing.JLabel;
164
         if (topic.isPresent()) {
163
         if (topic.isPresent()) {
165
             topicWho.setText("Topic set by " + topic.get().getClient()
164
             topicWho.setText("Topic set by " + topic.get().getClient()
166
                     .map(GroupChatUser::getNickname).orElse("Unknown")
165
                     .map(GroupChatUser::getNickname).orElse("Unknown")
167
-                    + "<br> on " + new Date(1000 * topic.get().getTime()));
166
+                    + "<br> on " + topic.get().getDate());
168
             topicText.setText(topic.get().getTopic());
167
             topicText.setText(topic.get().getTopic());
169
         } else {
168
         } else {
170
             topicWho.setText("No topic set.");
169
             topicWho.setText("No topic set.");

+ 1
- 4
ui_swing/src/com/dmdirc/addons/ui_swing/dialogs/channelsetting/TopicLabel.java View File

29
 import com.dmdirc.interfaces.GroupChatUser;
29
 import com.dmdirc.interfaces.GroupChatUser;
30
 
30
 
31
 import java.awt.Color;
31
 import java.awt.Color;
32
-import java.util.Date;
33
 
32
 
34
 import javax.swing.JEditorPane;
33
 import javax.swing.JEditorPane;
35
 import javax.swing.JPanel;
34
 import javax.swing.JPanel;
49
 
48
 
50
     /** A version number for this class. */
49
     /** A version number for this class. */
51
     private static final long serialVersionUID = 1;
50
     private static final long serialVersionUID = 1;
52
-    /** How many milliseconds in a second. */
53
-    private static final int MILLIS_IN_SECOND = 1000;
54
     /** Topic this label represents. */
51
     /** Topic this label represents. */
55
     private final Topic topic;
52
     private final Topic topic;
56
     /** The group chat to which this label belongs. */
53
     /** The group chat to which this label belongs. */
138
         }
135
         }
139
         add(label, "wmax 450, grow, push, wrap, gapleft 5, pad 0");
136
         add(label, "wmax 450, grow, push, wrap, gapleft 5, pad 0");
140
 
137
 
141
-        label = new TextLabel("on " + new Date(topic.getTime() * MILLIS_IN_SECOND));
138
+        label = new TextLabel("on " + topic.getDate());
142
         add(label, "wmax 450, grow, push, wrap, gapleft 5, pad 0");
139
         add(label, "wmax 450, grow, push, wrap, gapleft 5, pad 0");
143
 
140
 
144
         add(new JSeparator(), "newline, span, growx, pushx");
141
         add(new JSeparator(), "newline, span, growx, pushx");

+ 1
- 0
ui_swing/src/com/dmdirc/addons/ui_swing/dialogs/globalautocommand/GlobalAutoCommandDialog.java View File

74
     }
74
     }
75
 
75
 
76
     private void layoutComponents() {
76
     private void layoutComponents() {
77
+        setTitle("Global Perform");
77
         setLayout(new MigLayout("fill"));
78
         setLayout(new MigLayout("fill"));
78
         add(new TextLabel("These commands will be executed when the client starts."),
79
         add(new TextLabel("These commands will be executed when the client starts."),
79
                 "wrap, span 2");
80
                 "wrap, span 2");

+ 31
- 2
ui_swing/src/com/dmdirc/addons/ui_swing/textpane/BackgroundPainter.java View File

60
      */
60
      */
61
     @Nonnull
61
     @Nonnull
62
     private final String optionKey;
62
     private final String optionKey;
63
+    /**
64
+     * Key in the domain to get image opacity level.
65
+     */
66
+    @Nonnull
67
+    private final String opacityKey;
68
+
63
     /** The URL builder to use to find icons. */
69
     /** The URL builder to use to find icons. */
64
     private final URLBuilder urlBuilder;
70
     private final URLBuilder urlBuilder;
65
     /**
71
     /**
74
      * Background option type.
80
      * Background option type.
75
      */
81
      */
76
     private BackgroundOption backgroundOption;
82
     private BackgroundOption backgroundOption;
83
+    /**
84
+     * Background opacity.
85
+     */
86
+    private float opacity;
77
 
87
 
78
     /**
88
     /**
79
      * Creates a new background painter.
89
      * Creates a new background painter.
83
      * @param domain        Domain to retrieve settings from
93
      * @param domain        Domain to retrieve settings from
84
      * @param imageKey      Key for background image
94
      * @param imageKey      Key for background image
85
      * @param optionKey     Key for background type
95
      * @param optionKey     Key for background type
96
+     * @param opacityKey    Key for the opacity
86
      */
97
      */
87
     public BackgroundPainter(
98
     public BackgroundPainter(
88
             final AggregateConfigProvider configManager,
99
             final AggregateConfigProvider configManager,
89
             final URLBuilder urlBuilder,
100
             final URLBuilder urlBuilder,
90
             @Nonnull final String domain, @Nonnull final String imageKey,
101
             @Nonnull final String domain, @Nonnull final String imageKey,
91
-            @Nonnull final String optionKey) {
102
+            @Nonnull final String optionKey, @Nonnull final String opacityKey) {
92
         this.configManager = configManager;
103
         this.configManager = configManager;
93
         this.urlBuilder = urlBuilder;
104
         this.urlBuilder = urlBuilder;
94
         this.domain = domain;
105
         this.domain = domain;
95
         this.imageKey = imageKey;
106
         this.imageKey = imageKey;
96
         this.optionKey = optionKey;
107
         this.optionKey = optionKey;
108
+        this.opacityKey = opacityKey;
97
         configManager.getBinder().bind(this, BackgroundPainter.class);
109
         configManager.getBinder().bind(this, BackgroundPainter.class);
98
     }
110
     }
99
 
111
 
112
         return optionKey;
124
         return optionKey;
113
     }
125
     }
114
 
126
 
127
+    @Nonnull
128
+    protected String getOpacityKey() {
129
+        return opacityKey;
130
+    }
131
+
115
     protected void setBackgroundImage(final Image backgroundImage) {
132
     protected void setBackgroundImage(final Image backgroundImage) {
116
         this.backgroundImage = backgroundImage;
133
         this.backgroundImage = backgroundImage;
117
     }
134
     }
144
         }
161
         }
145
     }
162
     }
146
 
163
 
164
+    @ConfigBinding(domain = "plugin-ui_swing", key = "textpanebackgroundopacity")
165
+    public void updateOpacity(final String opacity) {
166
+        try {
167
+            this.opacity = Float.valueOf(opacity);
168
+            if (this.opacity < 0 || this.opacity > 1) {
169
+                this.opacity = 1;
170
+            }
171
+        } catch (IllegalArgumentException ex) {
172
+            this.opacity = 1;
173
+        }
174
+    }
175
+
147
     @Override
176
     @Override
148
     public void paint(final Graphics graphics, final JComponent component) {
177
     public void paint(final Graphics graphics, final JComponent component) {
149
         final Graphics2D g2 = (Graphics2D) graphics;
178
         final Graphics2D g2 = (Graphics2D) graphics;
150
         g2.setColor(component.getBackground());
179
         g2.setColor(component.getBackground());
151
         g2.fill(g2.getClipBounds());
180
         g2.fill(g2.getClipBounds());
152
         UIUtilities.paintBackground(g2, component.getBounds(),
181
         UIUtilities.paintBackground(g2, component.getBounds(),
153
-                backgroundImage, backgroundOption);
182
+                backgroundImage, backgroundOption, opacity);
154
         super.paint(graphics, component);
183
         super.paint(graphics, component);
155
     }
184
     }
156
 
185
 

+ 1
- 1
ui_swing/src/com/dmdirc/addons/ui_swing/textpane/TextPane.java View File

115
         setLayout(new MigLayout("fill, hidemode 3"));
115
         setLayout(new MigLayout("fill, hidemode 3"));
116
         backgroundPainter = new BackgroundPainter(frame.getContainer().getConfigManager(),
116
         backgroundPainter = new BackgroundPainter(frame.getContainer().getConfigManager(),
117
                 urlBuilder, configDomain, "textpanebackground",
117
                 urlBuilder, configDomain, "textpanebackground",
118
-                "textpanebackgroundoption");
118
+                "textpanebackgroundoption", "textpanebackgroundopacity");
119
         canvas = new TextPaneCanvas(this,
119
         canvas = new TextPaneCanvas(this,
120
                 new CachingDocument<>(document, new AttributedStringMessageMaker()));
120
                 new CachingDocument<>(document, new AttributedStringMessageMaker()));
121
         final JLayer<JComponent> layer = new JLayer<>(canvas);
121
         final JLayer<JComponent> layer = new JLayer<>(canvas);

+ 2
- 2
ui_swing/test/com/dmdirc/addons/ui_swing/components/GenericTableModelTest.java View File

39
 import org.mockito.Mock;
39
 import org.mockito.Mock;
40
 import org.mockito.runners.MockitoJUnitRunner;
40
 import org.mockito.runners.MockitoJUnitRunner;
41
 
41
 
42
-import static junit.framework.Assert.assertEquals;
43
-import static junit.framework.Assert.assertSame;
42
+import static org.junit.Assert.assertEquals;
44
 import static org.junit.Assert.assertFalse;
43
 import static org.junit.Assert.assertFalse;
44
+import static org.junit.Assert.assertSame;
45
 import static org.junit.Assert.assertTrue;
45
 import static org.junit.Assert.assertTrue;
46
 import static org.mockito.Mockito.verify;
46
 import static org.mockito.Mockito.verify;
47
 
47
 

+ 4
- 0
ui_web2/build.gradle View File

1
+dependencies {
2
+  bundle group: 'com.sparkjava', name: 'spark-core', version: '2.3'
3
+  bundle group: 'com.google.code.gson', name: 'gson', 'version': '2.5'
4
+}

+ 32
- 0
ui_web2/plugin.config View File

1
+# This is a DMDirc configuration file.
2
+
3
+# This section indicates which sections below take key/value
4
+# pairs, rather than a simple list. It should be placed above
5
+# any sections that take key/values.
6
+keysections:
7
+  metadata
8
+  updates
9
+  version
10
+  defaults
11
+
12
+metadata:
13
+  author=Chris <chris@dmdirc.com>
14
+  mainclass=com.dmdirc.addons.ui_web2.WebUiPlugin
15
+  description=Web-based DMDirc user interface
16
+  name=ui_web2
17
+  nicename=Web UI
18
+
19
+updates:
20
+  id=81
21
+
22
+version:
23
+  friendly=0.0
24
+
25
+provides:
26
+  #web ui
27
+
28
+defaults:
29
+  port=4567
30
+
31
+exports:
32
+

+ 1
- 0
ui_web2/res/META-INF/services/org.eclipse.jetty.http.HttpFieldPreEncoder View File

1
+org.eclipse.jetty.http.Http1FieldPreEncoder

+ 26
- 0
ui_web2/res/jetty-logging.properties View File

1
+#
2
+# Copyright (c) 2006-2016 DMDirc Developers
3
+#
4
+# Permission is hereby granted, free of charge, to any person obtaining a copy
5
+# of this software and associated documentation files (the "Software"), to deal
6
+# in the Software without restriction, including without limitation the rights
7
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+# copies of the Software, and to permit persons to whom the Software is
9
+# furnished to do so, subject to the following conditions:
10
+#
11
+# The above copyright notice and this permission notice shall be included in
12
+# all copies or substantial portions of the Software.
13
+#
14
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+# SOFTWARE.
21
+#
22
+
23
+# Configure Jetty for StdErrLog Logging
24
+org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StrErrLog
25
+# Overall Logging Level is INFO
26
+org.eclipse.jetty.LEVEL=DEBUG

+ 10
- 0
ui_web2/res/www/index.html View File

1
+<!DOCTYPE html>
2
+<html>
3
+  <head>
4
+    <title>DMDirc</title>
5
+      <script src="js/socket.js"></script>
6
+  </head>
7
+  <body>
8
+    HELLO WORLD
9
+  </body>
10
+</html>

+ 20
- 0
ui_web2/res/www/js/socket.js View File

1
+socket = null;
2
+
3
+function getAddress() {
4
+    var loc = window.location;
5
+    var uri = loc.protocol === "https:" ? "wss:" : "ws:";
6
+    uri += "//" + loc.host + "/ws";
7
+    return uri;
8
+}
9
+
10
+function connect() {
11
+    socket = new WebSocket(getAddress());
12
+
13
+    socket.onmessage = function(event) {
14
+      console.log(event.data);
15
+    }
16
+}
17
+
18
+function send(data) {
19
+    socket.send(JSON.stringify(data));
20
+}

+ 74
- 0
ui_web2/src/com/dmdirc/addons/ui_web2/InitialStateProducer.java View File

1
+/*
2
+ * Copyright (c) 2006-2015 DMDirc Developers
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.addons.ui_web2;
24
+
25
+import com.dmdirc.addons.ui_web2.serialisers.BackBufferSerializer;
26
+import com.dmdirc.addons.ui_web2.serialisers.WindowModelSerialiser;
27
+import com.dmdirc.interfaces.WindowModel;
28
+import com.dmdirc.ui.WindowManager;
29
+import com.dmdirc.ui.messages.BackBuffer;
30
+
31
+import com.google.gson.Gson;
32
+import com.google.gson.GsonBuilder;
33
+
34
+import java.util.Collection;
35
+import java.util.Collections;
36
+
37
+import javax.inject.Inject;
38
+
39
+/**
40
+ * Handles compiling the initial burst of state that will be sent to new web clients.
41
+ */
42
+public class InitialStateProducer {
43
+
44
+    private final Gson serialiser;
45
+    private final WindowManager windowManager;
46
+
47
+    @Inject
48
+    public InitialStateProducer(final WindowManager windowManager) {
49
+        serialiser = new GsonBuilder()
50
+                .registerTypeHierarchyAdapter(WindowModel.class, new WindowModelSerialiser())
51
+                .registerTypeAdapter(BackBuffer.class, new BackBufferSerializer())
52
+                .create();
53
+        this.windowManager = windowManager;
54
+    }
55
+
56
+    public String getInitialState() {
57
+        final InitialState state = new InitialState(windowManager.getRootWindows());
58
+        return serialiser.toJson(state);
59
+    }
60
+
61
+    private static class InitialState {
62
+
63
+        private final Collection<WindowModel> windows;
64
+
65
+        private InitialState(final Collection<WindowModel> windows) {
66
+            this.windows = windows;
67
+        }
68
+
69
+        public Collection<WindowModel> getWindows() {
70
+            return Collections.unmodifiableCollection(windows);
71
+        }
72
+    }
73
+
74
+}

activewindow/src/com/dmdirc/addons/activewindow/ActiveWindowModule.java → ui_web2/src/com/dmdirc/addons/ui_web2/WebServer.java View File

20
  * SOFTWARE.
20
  * SOFTWARE.
21
  */
21
  */
22
 
22
 
23
-package com.dmdirc.addons.activewindow;
23
+package com.dmdirc.addons.ui_web2;
24
 
24
 
25
-import com.dmdirc.addons.ui_swing.injection.SwingModule;
26
-
27
-import dagger.Module;
25
+import spark.Spark;
28
 
26
 
29
 /**
27
 /**
30
- * DI module for the active window plugin.
28
+ * Web server used by the web UI.
31
  */
29
  */
32
-@Module(injects = {ActiveWindowManager.class, ActiveCommand.class}, addsTo = SwingModule.class)
33
-public class ActiveWindowModule {
30
+public class WebServer {
31
+
32
+    private final int port;
33
+
34
+    public WebServer(final int port) {
35
+        this.port = port;
36
+    }
37
+
38
+    public void start() {
39
+        Spark.port(port);
40
+        Spark.webSocket("/ws", WebSocketHandler.class);
41
+        Spark.staticFileLocation("/www");
42
+        Spark.get("/test", (request, response) -> "HELLO");
43
+    }
44
+
45
+    public void stop() {
46
+        Spark.stop();
47
+    }
48
+
34
 }
49
 }

+ 88
- 0
ui_web2/src/com/dmdirc/addons/ui_web2/WebSocketController.java View File

1
+/*
2
+ * Copyright (c) 2006-2015 DMDirc Developers
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.addons.ui_web2;
24
+
25
+import java.io.IOException;
26
+import java.util.Collection;
27
+import java.util.concurrent.CopyOnWriteArrayList;
28
+
29
+import javax.inject.Inject;
30
+import javax.inject.Singleton;
31
+
32
+import org.eclipse.jetty.websocket.api.Session;
33
+
34
+/**
35
+ * Manages events raised by the {@link WebSocketHandler}.
36
+ *
37
+ * <p>This serves as a bridge between the {@link WebSocketHandler}, which cannot have dependencies
38
+ * passed in sanely due to the framework, and the rest of the plugin/client.
39
+ */
40
+@Singleton
41
+public class WebSocketController {
42
+
43
+    private final Collection<Session> sessions = new CopyOnWriteArrayList<>();
44
+    private final InitialStateProducer initialStateProducer;
45
+
46
+    @Inject
47
+    public WebSocketController(final InitialStateProducer initialStateProducer) {
48
+        this.initialStateProducer = initialStateProducer;
49
+    }
50
+
51
+    void sessionConnected(final Session session) {
52
+        sessions.add(session);
53
+        sendMessage(session, initialStateProducer.getInitialState());
54
+    }
55
+
56
+    void sessionClosed(final Session session, final int statusCode, final String reason) {
57
+        sessions.remove(session);
58
+    }
59
+
60
+    void messageReceived(final Session session, final String message) {
61
+        // Echo the message back for testing
62
+        sendMessage(session, message);
63
+    }
64
+
65
+    /**
66
+     * Sends a message to a specific session.
67
+     *
68
+     * @param session The session to send a message to.
69
+     * @param message The message to be sent.
70
+     */
71
+    public void sendMessage(final Session session, final String message) {
72
+        try {
73
+            WebSocketHandler.sendMessage(session, message);
74
+        } catch (IOException ex) {
75
+            // TODO: Raise an error...
76
+        }
77
+    }
78
+
79
+    /**
80
+     * Sends a message to all connected sessions.
81
+     *
82
+     * @param message The message to be sent.
83
+     */
84
+    public void sendMessage(final String message) {
85
+        sessions.forEach(s -> sendMessage(s, message));
86
+    }
87
+
88
+}

+ 72
- 0
ui_web2/src/com/dmdirc/addons/ui_web2/WebSocketHandler.java View File

1
+/*
2
+ * Copyright (c) 2006-2015 DMDirc Developers
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.addons.ui_web2;
24
+
25
+import java.io.IOException;
26
+
27
+import org.eclipse.jetty.websocket.api.Session;
28
+import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
29
+import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
30
+import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
31
+import org.eclipse.jetty.websocket.api.annotations.WebSocket;
32
+
33
+/**
34
+ * Handles websocket connections.
35
+ */
36
+@WebSocket
37
+public class WebSocketHandler {
38
+
39
+    /** Controller to use. */
40
+    @SuppressWarnings("StaticNonFinalField")
41
+    private static WebSocketController controller;
42
+
43
+    /**
44
+     * Sets the controller that manages ALL instances of {@link WebSocketHandler}.
45
+     *
46
+     * @param controller Controller to use.
47
+     */
48
+    @SuppressWarnings("StaticMethodOnlyUsedInOneClass")
49
+    public static void setController(final WebSocketController controller) {
50
+        WebSocketHandler.controller = controller;
51
+    }
52
+
53
+    @OnWebSocketConnect
54
+    public void connected(final Session session) {
55
+        controller.sessionConnected(session);
56
+    }
57
+
58
+    @OnWebSocketClose
59
+    public void closed(final Session session, final int statusCode, final String reason) {
60
+        controller.sessionClosed(session, statusCode, reason);
61
+    }
62
+
63
+    @OnWebSocketMessage
64
+    public void message(final Session session, final String message) {
65
+        controller.messageReceived(session, message);
66
+    }
67
+
68
+    public static void sendMessage(final Session session, final String message) throws IOException {
69
+        session.getRemote().sendString(message);
70
+    }
71
+
72
+}

+ 78
- 0
ui_web2/src/com/dmdirc/addons/ui_web2/WebUiModule.java View File

1
+/*
2
+ * Copyright (c) 2006-2015 DMDirc Developers
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.addons.ui_web2;
24
+
25
+import com.dmdirc.ClientModule;
26
+import com.dmdirc.ClientModule.GlobalConfig;
27
+import com.dmdirc.interfaces.config.AggregateConfigProvider;
28
+import com.dmdirc.plugins.PluginDomain;
29
+import com.dmdirc.plugins.PluginInfo;
30
+
31
+import javax.inject.Singleton;
32
+
33
+import dagger.Module;
34
+import dagger.Provides;
35
+
36
+/**
37
+ * Dagger module that provides Web UI-specific dependencies.
38
+ */
39
+@Module(
40
+        addsTo = ClientModule.class,
41
+        injects = WebServer.class,
42
+        library = true
43
+)
44
+@SuppressWarnings("TypeMayBeWeakened")
45
+public class WebUiModule {
46
+
47
+    private final PluginInfo pluginInfo;
48
+    private final String domain;
49
+
50
+    public WebUiModule(final PluginInfo pluginInfo, final String domain) {
51
+        this.pluginInfo = pluginInfo;
52
+        this.domain = domain;
53
+    }
54
+
55
+    @Provides
56
+    @PluginDomain(WebUiPlugin.class)
57
+    public String getSettingsDomain() {
58
+        return domain;
59
+    }
60
+
61
+    @Provides
62
+    @PluginDomain(WebUiPlugin.class)
63
+    public PluginInfo getPluginInfo() {
64
+        return pluginInfo;
65
+    }
66
+
67
+    @Provides
68
+    @Singleton
69
+    public WebServer getWebServer(
70
+            @PluginDomain(WebUiPlugin.class) final String domain,
71
+            @GlobalConfig final AggregateConfigProvider globalConfig,
72
+            final WebSocketController controller) {
73
+        WebSocketHandler.setController(controller);
74
+        final int port = globalConfig.getOptionInt(domain, "port");
75
+        return new WebServer(port);
76
+    }
77
+
78
+}

activewindow/src/com/dmdirc/addons/activewindow/ActiveWindowPlugin.java → ui_web2/src/com/dmdirc/addons/ui_web2/WebUiPlugin.java View File

20
  * SOFTWARE.
20
  * SOFTWARE.
21
  */
21
  */
22
 
22
 
23
-package com.dmdirc.addons.activewindow;
23
+package com.dmdirc.addons.ui_web2;
24
 
24
 
25
 import com.dmdirc.plugins.PluginInfo;
25
 import com.dmdirc.plugins.PluginInfo;
26
-import com.dmdirc.plugins.implementations.BaseCommandPlugin;
26
+import com.dmdirc.plugins.implementations.BasePlugin;
27
 
27
 
28
 import dagger.ObjectGraph;
28
 import dagger.ObjectGraph;
29
 
29
 
30
-/** Plugin to provide an active window command to the Swing UI. */
31
-public class ActiveWindowPlugin extends BaseCommandPlugin {
30
+/**
31
+ * Web UI plugin.
32
+ */
33
+public class WebUiPlugin extends BasePlugin {
32
 
34
 
33
-    /** Manager to use for the active window sink. */
34
-    private ActiveWindowManager activeWindowManager;
35
+    private WebServer webServer;
35
 
36
 
36
     @Override
37
     @Override
37
     public void load(final PluginInfo pluginInfo, final ObjectGraph graph) {
38
     public void load(final PluginInfo pluginInfo, final ObjectGraph graph) {
38
         super.load(pluginInfo, graph);
39
         super.load(pluginInfo, graph);
39
 
40
 
40
-        setObjectGraph(graph.plus(new ActiveWindowModule()));
41
-        registerCommand(ActiveCommand.class, ActiveCommand.INFO);
41
+        setObjectGraph(graph.plus(new WebUiModule(pluginInfo, pluginInfo.getDomain())));
42
+        getObjectGraph().validate();
42
 
43
 
43
-        activeWindowManager = getObjectGraph().get(ActiveWindowManager.class);
44
+        webServer = getObjectGraph().get(WebServer.class);
44
     }
45
     }
45
 
46
 
46
     @Override
47
     @Override
47
     public void onLoad() {
48
     public void onLoad() {
48
         super.onLoad();
49
         super.onLoad();
49
-        activeWindowManager.register();
50
+        webServer.start();
50
     }
51
     }
51
 
52
 
52
     @Override
53
     @Override
53
     public void onUnload() {
54
     public void onUnload() {
54
         super.onUnload();
55
         super.onUnload();
55
-        activeWindowManager.unregister();
56
+        webServer.stop();
56
     }
57
     }
57
 
58
 
58
 }
59
 }

+ 52
- 0
ui_web2/src/com/dmdirc/addons/ui_web2/serialisers/BackBufferSerializer.java View File

1
+/*
2
+ * Copyright (c) 2006-2015 DMDirc Developers
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.addons.ui_web2.serialisers;
24
+
25
+import com.dmdirc.ui.messages.BackBuffer;
26
+import com.dmdirc.ui.messages.IRCDocument;
27
+
28
+import com.google.gson.JsonArray;
29
+import com.google.gson.JsonElement;
30
+import com.google.gson.JsonSerializationContext;
31
+import com.google.gson.JsonSerializer;
32
+
33
+import java.lang.reflect.Type;
34
+
35
+/**
36
+ * Serializes {@link BackBuffer}s.
37
+ */
38
+public class BackBufferSerializer implements JsonSerializer<BackBuffer> {
39
+
40
+    @Override
41
+    public JsonElement serialize(final BackBuffer src, final Type typeOfSrc,
42
+            final JsonSerializationContext context) {
43
+        final JsonArray res = new JsonArray();
44
+        final IRCDocument document = src.getDocument();
45
+        for (int i = 0; i < document.getNumLines(); i++) {
46
+            // TODO: Pass on foreground and background colours
47
+            res.add(document.getLine(i).getText());
48
+        }
49
+        return res;
50
+    }
51
+
52
+}

+ 53
- 0
ui_web2/src/com/dmdirc/addons/ui_web2/serialisers/WindowModelSerialiser.java View File

1
+/*
2
+ * Copyright (c) 2006-2015 DMDirc Developers
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.addons.ui_web2.serialisers;
24
+
25
+import com.dmdirc.interfaces.WindowModel;
26
+
27
+import com.google.gson.JsonElement;
28
+import com.google.gson.JsonObject;
29
+import com.google.gson.JsonSerializationContext;
30
+import com.google.gson.JsonSerializer;
31
+
32
+import java.lang.reflect.Type;
33
+
34
+/**
35
+ * Serialises {@link WindowModel}s.
36
+ */
37
+public class WindowModelSerialiser implements JsonSerializer<WindowModel> {
38
+
39
+    @Override
40
+    public JsonElement serialize(final WindowModel src, final Type typeOfSrc,
41
+            final JsonSerializationContext context) {
42
+        final JsonObject res = new JsonObject();
43
+        res.addProperty("name", src.getName());
44
+        res.addProperty("icon", src.getIcon());
45
+        res.addProperty("title", src.getTitle());
46
+        res.addProperty("writable", src.isWritable());
47
+        res.add("children", context.serialize(src.getChildren()));
48
+        res.add("components", context.serialize(src.getComponents()));
49
+        res.add("backbuffer", context.serialize(src.getBackBuffer()));
50
+        return res;
51
+    }
52
+
53
+}

Loading…
Cancel
Save