From 8b611efad816c0481a305467dbc3c32e91d9b8b9 Mon Sep 17 00:00:00 2001
From: Florian Bogner <f.bogner@pcsg.de>
Date: Fri, 5 May 2017 17:37:02 +0200
Subject: [PATCH] feat: Futher development

---
 ajax/activatePlugin.php              |   4 +-
 ajax/deactivatePlugin.php            |   4 +-
 ajax/getActivePlugins.php            |  12 +
 ajax/getPlugins.php                  |  11 +
 bin/Editor.js                        | 327 +++++++++++++++------------
 bin/Settings.js                      |   5 +
 bin/classes/Settings.js              |  39 ++++
 bin/controls/settings/Plugins.css    |   0
 bin/controls/settings/Plugins.html   |   0
 bin/controls/settings/Plugins.js     | 256 +++++++++++++++++++++
 checklist.md5                        |  14 ++
 composer.json                        |  57 +++--
 events.xml                           |   5 +
 locale.xml                           |  38 ++++
 src/QUI/Ckeditor/EventHandler.php    |  41 ++++
 src/QUI/Ckeditor/Plugins/Manager.php | 265 +++++++++++++++++++++-
 16 files changed, 889 insertions(+), 189 deletions(-)
 create mode 100644 ajax/getActivePlugins.php
 create mode 100644 ajax/getPlugins.php
 create mode 100644 bin/Settings.js
 create mode 100644 bin/classes/Settings.js
 create mode 100644 bin/controls/settings/Plugins.css
 create mode 100644 bin/controls/settings/Plugins.html
 create mode 100644 bin/controls/settings/Plugins.js
 create mode 100644 checklist.md5
 create mode 100644 events.xml
 create mode 100644 src/QUI/Ckeditor/EventHandler.php

diff --git a/ajax/activatePlugin.php b/ajax/activatePlugin.php
index 9612e3a..e25649f 100644
--- a/ajax/activatePlugin.php
+++ b/ajax/activatePlugin.php
@@ -3,7 +3,9 @@
 QUI::$Ajax->registerFunction(
     'package_quiqqer_ckeditor4_ajax_activatePlugin',
     function ($pluginName) {
-        $PluginManager = new \QUI\Ckeditor4\Plugins\Manager();
+        $PluginManager = new \QUI\Ckeditor\Plugins\Manager();
+
+        $PluginManager->activate($pluginName);
     },
     array('pluginName')
 );
\ No newline at end of file
diff --git a/ajax/deactivatePlugin.php b/ajax/deactivatePlugin.php
index a2e2b31..511487a 100644
--- a/ajax/deactivatePlugin.php
+++ b/ajax/deactivatePlugin.php
@@ -3,7 +3,9 @@
 QUI::$Ajax->registerFunction(
     'package_quiqqer_ckeditor4_ajax_deactivatePlugin',
     function ($pluginName) {
-        $PluginManager = new \QUI\Ckeditor4\Plugins\Manager();
+        $PluginManager = new \QUI\Ckeditor\Plugins\Manager();
+
+        $PluginManager->deactivate($pluginName);
     },
     array('pluginName')
 );
\ No newline at end of file
diff --git a/ajax/getActivePlugins.php b/ajax/getActivePlugins.php
new file mode 100644
index 0000000..4f663da
--- /dev/null
+++ b/ajax/getActivePlugins.php
@@ -0,0 +1,12 @@
+<?php
+
+QUI::$Ajax->registerFunction(
+    'package_quiqqer_ckeditor4_ajax_getActivePlugins',
+    function () {
+        $Manager = new \QUI\Ckeditor\Plugins\Manager();
+
+        return $Manager->getActivePlugins();
+    },
+    array()
+);
+
diff --git a/ajax/getPlugins.php b/ajax/getPlugins.php
new file mode 100644
index 0000000..a90c495
--- /dev/null
+++ b/ajax/getPlugins.php
@@ -0,0 +1,11 @@
+<?php
+
+QUI::$Ajax->registerFunction(
+    'package_quiqqer_ckeditor4_ajax_getPlugins',
+    function () {
+        $Pluginmanager = new \QUI\Ckeditor\Plugins\Manager();
+
+        return $Pluginmanager->getAllPlugins();
+    },
+    array()
+);
\ No newline at end of file
diff --git a/bin/Editor.js b/bin/Editor.js
index 1e2207e..dc1db83 100644
--- a/bin/Editor.js
+++ b/bin/Editor.js
@@ -22,12 +22,14 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
     'Ajax',
     'qui/utils/Math',
     'qui/utils/Elements',
+    'package/quiqqer/ckeditor4/bin/Settings',
 
     'css!package/quiqqer/ckeditor4/bin/Editor.css'
 
-], function (require, QUI, Editor, Locale, Ajax, QUIMath, QUIElements) {
+], function (require, QUI, Editor, Locale, Ajax, QUIMath, QUIElements, Settings) {
     "use strict";
 
+
     return new Class({
 
         Extends: Editor,
@@ -103,6 +105,7 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
          * @param {Object} data - Editor settings data
          */
         $loadInstance: function (data) {
+
             if (typeof window.CKEDITOR === 'undefined') {
                 return;
             }
@@ -112,9 +115,10 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
                 Textarea  = false,
                 size      = Container.getSize();
 
+
             if (!Container.getElement('textarea')) {
                 Textarea = new Element('textarea', {
-                    id    : this.getId(),
+                    id    : self.getId(),
                     styles: {
                         height: size.y,
                         width : size.x
@@ -208,24 +212,30 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
                 URL_OPT_DIR + 'quiqqer/ckeditor4/bin/defaultWysiwyg.css'
             );
 
-            window.CKEDITOR.replace(instance, {
-                skinName           : 'moono-lisa',
-                customConfig       : '',
-                language           : Locale.getCurrent(),
-                baseHref           : URL_DIR,
-                basePath           : URL_DIR,
-                height             : height,
-                width              : width,
-                toolbar            : toolbar,
-                allowedContent     : true,
-                extraAllowedContent: 'div(*)[*]{*}; iframe(*)[*]{*}; img(*)[*]{*}; script(*)[*]{*}',
-                stylesSet          : styles,
-                contentsCss        : data.cssFiles || [],
-                bodyClass          : data.bodyClass,
-                // templates_files : [URL_OPT_DIR +'base/bin/pcsgEditorPlugins/templates.php'],
-                baseFloatZIndex    : zIndex,
-                extraPlugins       : self.$parseToolbarToPlugins(toolbar)
+
+            Settings.getPlugins().then(function (plugins) {
+                var extraPlugins = plugins.join(",");
+
+                window.CKEDITOR.replace(instance, {
+                    skinName           : 'moono-lisa',
+                    customConfig       : '',
+                    language           : Locale.getCurrent(),
+                    baseHref           : URL_DIR,
+                    basePath           : URL_DIR,
+                    height             : height,
+                    width              : width,
+                    toolbar            : toolbar,
+                    allowedContent     : true,
+                    extraAllowedContent: 'div(*)[*]{*}; iframe(*)[*]{*}; img(*)[*]{*}; script(*)[*]{*}',
+                    stylesSet          : styles,
+                    contentsCss        : data.cssFiles || [],
+                    bodyClass          : data.bodyClass,
+                    // templates_files : [URL_OPT_DIR +'base/bin/pcsgEditorPlugins/templates.php'],
+                    baseFloatZIndex    : zIndex,
+                    extraPlugins       : extraPlugins
+                });
             });
+
         },
 
         /**
@@ -255,7 +265,8 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
                     this.$onInstanceReadyListener
                 );
             }
-        },
+        }
+        ,
 
         /**
          * event : instance ready
@@ -279,7 +290,8 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
             this.fireEvent('loaded', [this, instance.editor]);
 
             instance.editor.focus();
-        },
+        }
+        ,
 
         /**
          * event : on resize
@@ -290,7 +302,8 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
                 containerSize = Container.getSize();
 
             Instance.resize(containerSize.x, containerSize.y);
-        },
+        }
+        ,
 
         /**
          * Editor onSetContent Event
@@ -302,7 +315,8 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
             if (Editor.getInstance()) {
                 Editor.getInstance().setData(content);
             }
-        },
+        }
+        ,
 
         /**
          * Editor onGetContent Event
@@ -313,7 +327,8 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
             if (Editor.getInstance()) {
                 Editor.setAttribute('content', Editor.getInstance().getData());
             }
-        },
+        }
+        ,
 
         /**
          * Set the focus to the editor
@@ -322,7 +337,8 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
             if (this.getInstance()) {
                 this.getInstance().focus();
             }
-        },
+        }
+        ,
 
         /**
          * Switch to source mode
@@ -331,7 +347,8 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
             if (this.getInstance()) {
                 this.getInstance().setMode('source');
             }
-        },
+        }
+        ,
 
         /**
          * Switch to wysiwyg editor
@@ -340,7 +357,8 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
             if (this.getInstance()) {
                 this.getInstance().setMode('wysiwyg');
             }
-        },
+        }
+        ,
 
         /**
          * Hide the toolbar
@@ -351,7 +369,8 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
             if (Toolbar) {
                 Toolbar.setStyle('display', 'none');
             }
-        },
+        }
+        ,
 
         /**
          * show the toolbar
@@ -362,7 +381,8 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
             if (Toolbar) {
                 Toolbar.setStyle('display', null);
             }
-        },
+        }
+        ,
 
         /**
          * Set the height of the instance
@@ -375,7 +395,8 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
             }
 
             this.setAttribute('height', height);
-        },
+        }
+        ,
 
         /**
          * Set the height of the instance
@@ -388,7 +409,8 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
             }
 
             this.setAttribute('width', width);
-        },
+        }
+        ,
 
         /**
          * event : on add css
@@ -411,7 +433,8 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
 
                 Doc.head.appendChild(Link);
             }
-        },
+        }
+        ,
 
         /**
          * event : on Drop
@@ -423,105 +446,110 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
             for (var i = 0, len = params.length; i < len; i++) {
                 Instance.insertHtml("<img src=" + params[i].url + " />");
             }
-        },
-
-        /**
-         * Generate the extra plugins option in dependence of the toolbar
-         * @param toolbar
-         */
-        $parseToolbarToPlugins: function (toolbar) {
-            var extra      = [],
-                buttonList = [];
-
-            if (typeOf(toolbar) == 'array') {
-                buttonList = toolbar.flatten();
-            }
-
-            for (var i = 0, len = buttonList.length; i < len; i++) {
-                switch (buttonList[i]) {
-                    case 'Templates':
-                        extra.push('templates');
-                        break;
-
-                    case 'Find':
-                    case 'Replace':
-                        extra.push('find');
-                        break;
-
-                    case 'SelectAll':
-                        extra.push('selectall');
-                        break;
-
-                    case 'Form':
-                    case 'Checkbox':
-                    case 'Radio':
-                    case 'TextField':
-                    case 'Textarea':
-                    case 'Select':
-                    case 'Button':
-                    case 'ImageButton':
-                    case 'HiddenField':
-                        extra.push('forms');
-                        break;
-
-                    case 'CreateDiv':
-                        extra.push('div');
-                        break;
-
-                    case 'JustifyLeft':
-                    case 'JustifyCenter':
-                    case 'JustifyRight':
-                    case 'JustifyBlock':
-                        extra.push('justify');
-                        break;
-
-                    case 'BidiLtr':
-                    case 'BidiRtl':
-                        extra.push('bidi');
-                        break;
-
-                    case 'Language':
-                        extra.push('language');
-                        break;
-
-                    case 'Link':
-                    case 'Unlink':
-                    case 'Anchor':
-                        extra.push('link');
-                        break;
-
-                    case 'Flash':
-                        extra.push('flash');
-                        break;
-
-                    case 'Smiley':
-                        extra.push('smiley');
-                        break;
-
-                    case 'PageBreak':
-                        extra.push('pagebreak');
-                        break;
-
-                    case 'Iframe':
-                        extra.push('iframe');
-                        break;
-
-                    case 'Font':
-                    case 'FontSize':
-                        extra.push('font');
-                        break;
-
-                    case 'BGColor':
-                    case 'TextColor':
-                        extra.push('colorbutton');
-                        break;
-                }
-            }
-
-            extra = extra.unique();
-
-            return extra.join(',');
-        },
+        }
+        ,
+
+        // /**
+        //  * Generate the extra plugins option in dependence of the toolbar
+        //  * @param toolbar
+        //  */
+        // $parseToolbarToPlugins: function (toolbar) {
+        //     var extra      = [],
+        //         buttonList = [];
+        //
+        //     if (typeOf(toolbar) == 'array') {
+        //         buttonList = toolbar.flatten();
+        //     }
+        //
+        //     for (var i = 0, len = buttonList.length; i < len; i++) {
+        //         switch (buttonList[i]) {
+        //             case 'Templates':
+        //                 extra.push('templates');
+        //                 break;
+        //
+        //             case 'Find':
+        //             case 'Replace':
+        //                 extra.push('find');
+        //                 break;
+        //
+        //             case 'SelectAll':
+        //                 extra.push('selectall');
+        //                 break;
+        //
+        //             case 'Form':
+        //             case 'Checkbox':
+        //             case 'Radio':
+        //             case 'TextField':
+        //             case 'Textarea':
+        //             case 'Select':
+        //             case 'Button':
+        //             case 'ImageButton':
+        //             case 'HiddenField':
+        //                 extra.push('forms');
+        //                 break;
+        //
+        //             case 'CreateDiv':
+        //                 extra.push('div');
+        //                 break;
+        //
+        //             case 'JustifyLeft':
+        //             case 'JustifyCenter':
+        //             case 'JustifyRight':
+        //             case 'JustifyBlock':
+        //                 extra.push('justify');
+        //                 break;
+        //
+        //             case 'BidiLtr':
+        //             case 'BidiRtl':
+        //                 extra.push('bidi');
+        //                 break;
+        //
+        //             case 'Language':
+        //                 extra.push('language');
+        //                 break;
+        //
+        //             case 'Link':
+        //             case 'Unlink':
+        //             case 'Anchor':
+        //                 extra.push('link');
+        //                 break;
+        //
+        //             case 'Flash':
+        //                 extra.push('flash');
+        //                 break;
+        //
+        //             case 'Smiley':
+        //                 extra.push('smiley');
+        //                 break;
+        //
+        //             case 'PageBreak':
+        //                 extra.push('pagebreak');
+        //                 break;
+        //
+        //             case 'Iframe':
+        //                 extra.push('iframe');
+        //                 break;
+        //
+        //             case 'Font':
+        //             case 'FontSize':
+        //                 extra.push('font');
+        //                 break;
+        //
+        //             case 'BGColor':
+        //             case 'TextColor':
+        //                 extra.push('colorbutton');
+        //                 break;
+        //         }
+        //     }
+        //
+        //     //extra.push('wordcount');
+        //
+        //     extra = extra.unique();
+        //
+        //
+        //     return extra.join(',');
+        // }
+        // ,
 
         /**
          * edit the image dialog
@@ -552,18 +580,18 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
 
                 // image button
                 var UrlGroup = this.getContentElement('info', 'txtUrl')
-                                   .getElement()
+                    .getElement()
                     .$;
 
                 var UrlInput = UrlGroup.getElement('input[type="text"]');
 
                 var HeightInput = this.getContentElement('info', 'txtHeight')
-                                      .getElement().$
-                                      .getElement('input[type="text"]');
+                    .getElement().$
+                    .getElement('input[type="text"]');
 
                 var WidthInput = this.getContentElement('info', 'txtWidth')
-                                     .getElement().$
-                                     .getElement('input[type="text"]');
+                    .getElement().$
+                    .getElement('input[type="text"]');
 
 
                 if (!UrlGroup.getElement('.qui-button')) {
@@ -620,7 +648,7 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
 
                 // link button
                 var LinkGroup = this.getContentElement('Link', 'txtUrl')
-                                    .getElement()
+                    .getElement()
                     .$;
 
 
@@ -655,7 +683,8 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
             };
 
             return ev;
-        },
+        }
+        ,
 
         /**
          * edit the link dialog
@@ -688,10 +717,10 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
                 orgCommit.call(this, data);
 
                 Protokoll = dialogDefinition.dialog
-                                            .getContentElement('info', 'protocol')
-                                            .getElement()
-                                            .$
-                                            .getElement('select');
+                    .getContentElement('info', 'protocol')
+                    .getElement()
+                    .$
+                    .getElement('select');
 
                 data.url = {
                     protocol: Protokoll.value,
@@ -707,7 +736,7 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
                 oldOnShow.bind(this)();
 
                 var UrlGroup = this.getContentElement('info', 'url')
-                                   .getElement()
+                    .getElement()
                     .$;
 
                 if (UrlGroup.getElement('.qui-button')) {
@@ -717,9 +746,9 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
                 var UrlInput = UrlGroup.getElement('input[type="text"]');
 
                 Protokoll = this.getContentElement('info', 'protocol')
-                                .getElement()
-                                .$
-                                .getElement('select');
+                    .getElement()
+                    .$
+                    .getElement('select');
 
                 UrlInput.setStyles({
                     'float': 'left',
@@ -764,5 +793,7 @@ define('package/quiqqer/ckeditor4/bin/Editor', [
 
             return ev;
         }
-    });
-});
+    })
+        ;
+})
+;
diff --git a/bin/Settings.js b/bin/Settings.js
new file mode 100644
index 0000000..9297e93
--- /dev/null
+++ b/bin/Settings.js
@@ -0,0 +1,5 @@
+define('package/quiqqer/ckeditor4/bin/Settings', [
+    'package/quiqqer/ckeditor4/bin/classes/Settings'
+], function(Settings) {
+    return new Settings();
+});
\ No newline at end of file
diff --git a/bin/classes/Settings.js b/bin/classes/Settings.js
new file mode 100644
index 0000000..2d7d98f
--- /dev/null
+++ b/bin/classes/Settings.js
@@ -0,0 +1,39 @@
+define('package/quiqqer/ckeditor4/bin/classes/Settings', [
+
+    'qui/QUI',
+    'qui/classes/DOM',
+    'Ajax'
+
+], function (QUI, QUIDOM, QUIAjax) {
+    "use strict";
+
+    return new Class({
+
+        Extends: QUIDOM,
+
+        initialize: function () {
+            this.plugins = null;
+        },
+
+
+        getPlugins: function () {
+            var self = this;
+
+            if (this.plugins !== null) {
+                return Promise.resolve(this.plugins);
+            }
+
+            return new Promise(function (resolve, reject) {
+                QUIAjax.get("package_quiqqer_ckeditor4_ajax_getActivePlugins", function (result) {
+
+                    self.plugins = result;
+                    resolve(result);
+                }, {
+                    'package': 'quiqqer/ckeditor4',
+                    'onError': reject
+                });
+
+            });
+        }
+    });
+});
\ No newline at end of file
diff --git a/bin/controls/settings/Plugins.css b/bin/controls/settings/Plugins.css
new file mode 100644
index 0000000..e69de29
diff --git a/bin/controls/settings/Plugins.html b/bin/controls/settings/Plugins.html
new file mode 100644
index 0000000..e69de29
diff --git a/bin/controls/settings/Plugins.js b/bin/controls/settings/Plugins.js
new file mode 100644
index 0000000..f131dce
--- /dev/null
+++ b/bin/controls/settings/Plugins.js
@@ -0,0 +1,256 @@
+define('package/quiqqer/ckeditor4/bin/controls/settings/Plugins', [
+    'qui/QUI',
+    'qui/controls/Control',
+    'controls/grid/Grid',
+    'Ajax',
+    'Locale'
+], function (QUI, QUIControl, Grid, QUIAjax, QUILocale) {
+    "use strict";
+
+    return new Class(
+        {
+            Extends: QUIControl,
+            Type   : 'package/quiqqer/ckeditor4/bin/controls/settings/Plugins',
+
+            Binds: [
+                '$onCreate',
+                '$onResize',
+                '$onRefresh',
+                '$toggleState'
+            ],
+
+            options: {},
+
+            initialize: function (options) {
+                this.parent(options);
+
+                // Variablendklarationen
+                this.$Grid = null;
+
+
+                // Eventdeklarationen
+                this.addEvents({
+                    onCreate : this.$onCreate,
+                    onResize : this.$onResize,
+                    onRefresh: this.$onRefresh,
+                    onInject : this.$onCreate,
+                    onImport : this.$onCreate
+                });
+            },
+
+
+            $onCreate: function () {
+                var self = this;
+
+                var Container = new Element('div').inject(
+                    this.getElm()
+                );
+
+
+                this.$Grid = new Grid(Container, {
+                    buttons    : [{
+                        name    : 'state',
+                        text    : QUILocale.get(
+                            "quiqqer/ckeditor4",
+                            "editors.settings.plugins.table.button.activate"
+                        ),
+                        disabled: true,
+                        events  : {
+                            onClick: this.$toggleState
+                        }
+                    }],
+                    height     : "500",
+                    columnModel: [
+                        {
+                            header   : QUILocale.get(
+                                "quiqqer/ckeditor4",
+                                "editors.settings.plugins.table.header.state"
+                            ),
+                            dataIndex: 'icon',
+                            dataType : 'node',
+                            width    : 60
+                        },
+                        {
+                            header   : QUILocale.get(
+                                "quiqqer/ckeditor4",
+                                "editors.settings.plugins.table.header.name"
+                            ),
+                            dataIndex: 'name',
+                            dataType : 'string',
+                            width    : 400
+                        }
+                    ]
+                });
+                this.$Grid.addEvents({
+
+                    onDblClick: function () {
+                        this.$toggleState();
+                    }.bind(this),
+
+                    onClick: function () {
+
+                        var TableButtons = self.$Grid.getAttribute('buttons');
+
+                        var StateBtn = TableButtons.state;
+
+                        var data = self.$Grid.getSelectedData()[0];
+
+                        if (!data) {
+                            return;
+                        }
+
+
+                        if (data.state === 0) {
+                            StateBtn.setAttribute("text", QUILocale.get(
+                                "quiqqer/ckeditor4",
+                                "editors.settings.plugins.table.button.activate"
+                            ));
+                        }
+
+                        if (data.state === 1) {
+                            StateBtn.setAttribute("text", QUILocale.get(
+                                "quiqqer/ckeditor4",
+                                "editors.settings.plugins.table.button.deactivate"
+                            ));
+                        }
+
+                        if (StateBtn) {
+                            StateBtn.enable();
+                        }
+                    }
+
+                });
+
+
+                this.refresh();
+                this.$onResize();
+            },
+
+            /**
+             * event : on refresh
+             */
+            $onRefresh: function () {
+
+            },
+
+            /**
+             * event : on resize
+             */
+            $onResize: function () {
+                if (!this.$Grid || !this.$Elm) {
+                    return;
+                }
+
+                var size = this.$Elm.getSize();
+
+
+                this.$Grid.setHeight(size.y);
+                this.$Grid.setWidth(size.x);
+                this.$Grid.resize();
+            },
+
+            refresh: function () {
+                var self = this;
+
+                QUIAjax.get("package_quiqqer_ckeditor4_ajax_getPlugins", function (result) {
+
+                    for (var i = 0, len = result.length; i < len; i++) {
+
+                        if (result[i].state === 0) {
+                            result[i].icon = new Element("span", {
+                                'class': 'fa fa-times fa-2x'
+                            });
+
+                            continue;
+                        }
+
+                        if (result[i].state === 1) {
+                            result[i].icon = new Element("span", {
+                                'class': 'fa fa-check fa-2x'
+                            });
+
+                            continue;
+                        }
+                    }
+
+                    self.$Grid.setData({
+                        data: result
+                    });
+
+
+                }, {
+                    'package': "quiqqer/ckeditor4"
+                });
+            },
+
+            $toggleState: function () {
+                var self = this;
+                return new Promise(function (resolve) {
+                    if (!self.$Grid) {
+
+                        return resolve();
+                    }
+
+                    var data = self.$Grid.getSelectedData()[0];
+
+                    if (!data.name || data.state === null || data.state === 'undefined') {
+
+                        return;
+                    }
+
+
+                    if (data.state === 0) {
+                        self.$enablePlugin(data.name).then(function () {
+                                self.refresh();
+                                QUI.MessageHandler.addSuccess(QUILocale.get(
+                                    "quiqqer/ckeditor4",
+                                    "message.settings.plugins.activation.success"
+                                ));
+                            }
+                        ).catch(function () {
+                            QUI.MessageHandler.addSuccess("Failed");
+                        });
+                    }
+
+
+                    if (data.state === 1) {
+                        self.$disablePlugin(data.name).then(function () {
+                                self.refresh();
+                                QUI.MessageHandler.addSuccess(QUILocale.get(
+                                    "quiqqer/ckeditor4",
+                                    "message.settings.plugins.deactivation.success"
+                                ));
+                            }
+                        ).catch(function () {
+                            QUI.MessageHandler.addSuccess("Failed");
+                        });
+                    }
+
+                });
+            },
+
+            $disablePlugin: function (name) {
+
+                return new Promise(function (resolve, reject) {
+                    QUIAjax.post("package_quiqqer_ckeditor4_ajax_deactivatePlugin", resolve, {
+                        'package'   : 'quiqqer/ckeditor4',
+                        'pluginName': name,
+                        onError     : reject
+                    });
+                });
+            },
+
+            $enablePlugin: function (name) {
+                return new Promise(function (resolve, reject) {
+                    QUIAjax.post("package_quiqqer_ckeditor4_ajax_activatePlugin", resolve, {
+                        'package'   : 'quiqqer/ckeditor4',
+                        'pluginName': name,
+                        onError     : reject
+                    });
+                });
+            }
+
+
+        }
+    );
+});
\ No newline at end of file
diff --git a/checklist.md5 b/checklist.md5
new file mode 100644
index 0000000..e4b0510
--- /dev/null
+++ b/checklist.md5
@@ -0,0 +1,14 @@
+13f0c2edd87644aadb6e964afded3e0c  composer.json
+1475dd243ea98e1d4c3450c996cb4eeb  ajax/deactivatePlugin.php
+3e988b01f5e7459c133209c200d84a6f  bin/defaultWysiwyg.css
+429efbb96844210f0d0bf70499849138  ajax/uninstallPlugin.php
+57637cb7ef2e48295ba77cfacbf609af  src/QUI/Ckeditor/Plugins/Manager.php
+5b49bec76fe68e69db9130c55175a953  bin/Editor.js
+686eaf44c5fec33c30250447af6217b1  ajax/installPlugin.php
+7734c8b62d016457e71b57accb3c5350  bin/Editor.css
+adac1ee419a8d29538b4d6495b0a4c75  README.md
+ae791a7b288e8abf8ea9bee2719e22c9  locale.xml
+b234ee4d69f5fce4486a80fdaf4a4263  LICENSE
+c2d12d54ab678a2f95667c7ca421eb98  ajax/activatePlugin.php
+d7c5658381f5003dfe13b8c3fd3460ec  package.xml
+dd6c0092b186bfa7a9957ce495abaf7d  wysiwyg.xml
diff --git a/composer.json b/composer.json
index df8b2cf..009ee25 100644
--- a/composer.json
+++ b/composer.json
@@ -1,34 +1,29 @@
 {
-  "name": "quiqqer\/ckeditor4",
-  "type": "quiqqer-library",
-  "description": "CKEditor for the QUIQQER CMS - enable the ckeditor for quiqqer",
-  "version": "2.0.0-dev",
-  "license": "GPL-2.0+",
-  "authors": [
-    {
-      "name": "Henning Leutz",
-      "email": "leutz@pcsg.de",
-      "homepage": "http:\/\/www.pcsg.de",
-      "role": "Developer"
+    "name": "quiqqer\/ckeditor4",
+    "type": "quiqqer-library",
+    "description": "CKEditor for the QUIQQER CMS - enable the ckeditor for quiqqer",
+    "version": "2.0.0-dev",
+    "license": "GPL-2.0+",
+    "authors": [
+        {
+            "name": "Henning Leutz",
+            "email": "leutz@pcsg.de",
+            "homepage": "http:\/\/www.pcsg.de",
+            "role": "Developer"
+        }
+    ],
+    "support": {
+        "email": "support@pcsg.de"
+    },
+    "require": {
+        "quiqqer\/quiqqer": "*",
+        "quiqqer\/qui": ">=1|dev-master|dev-dev",
+        "ckeditor\/ckeditor": "4.6.*"
+    },
+    "autoload": {
+        "psr-4": {
+            "QUI\\Ckeditor\\": "src\/QUI\/Ckeditor\/",
+            "QUI\\Ckeditor\\Plugins\\": "src\/QUI\/Ckeditor\/Plugins\/"
+        }
     }
-  ],
-  "support": {
-    "email": "support@pcsg.de"
-  },
-  "require": {
-    "quiqqer\/quiqqer": "*",
-    "quiqqer\/qui": ">=1|dev-master|dev-dev",
-    "ckeditor\/ckeditor": "4.6.*"
-  },
-  "autoload": {
-    "psr-4": {
-      "QUI\\Ckeditor\\": "src\/QUI\/Ckeditor\/",
-      "QUI\\Ckeditor\\Plugins\\": "src\/QUI\/Ckeditor\/Plugins\/"
-    }
-  },
-  "extra": {
-    "branch-alias": {
-      "dev-dev": "2.0.0-dev"
-    }
-  }
 }
\ No newline at end of file
diff --git a/events.xml b/events.xml
new file mode 100644
index 0000000..52a0564
--- /dev/null
+++ b/events.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<events>
+    <event on="onPackageSetup" fire="\QUI\Ckeditor\EventHandler::onPackageSetup" />
+    <event on="onPackageUpdate" fire="\QUI\Ckeditor\EventHandler::onPackageUpdate" />
+</events>
diff --git a/locale.xml b/locale.xml
index f851090..3abdb30 100644
--- a/locale.xml
+++ b/locale.xml
@@ -10,5 +10,43 @@
             <de><![CDATA[Integration den CKEditor in QUIQQER.]]></de>
             <en><![CDATA[Integrate the CKEditor into QUIQQER.]]></en>
         </locale>
+        <locale name="exception.plugin.activate.plugin.not.found">
+            <de><![CDATA[Das angegeben Plugin wurde nicht gefunden.]]></de>
+            <en><![CDATA[The provided plugin was not found.]]></en>
+        </locale>
+        <locale name="exception.plugin.already.active">
+            <de><![CDATA[Das angegebene Plugin ist bereits aktiv]]></de>
+            <en><![CDATA[The plugin is active already.]]></en>
+        </locale>
+        <locale name="exception.plugin.activate.plugin.not.active">
+            <de><![CDATA[Das angegebene Plugin ist bereits deaktiviert]]></de>
+            <en><![CDATA[The given plugin is not active]]></en>
+        </locale>
+
+        <!--Settings -->
+        <locale name="editors.settings.plugins.table.header.state">
+            <de><![CDATA[Status]]></de>
+            <en><![CDATA[State]]></en>
+        </locale>
+        <locale name="editors.settings.plugins.table.header.name">
+            <de><![CDATA[Name]]></de>
+            <en><![CDATA[Name]]></en>
+        </locale>
+        <locale name="editors.settings.plugins.table.button.activate">
+            <de><![CDATA[Aktivieren]]></de>
+            <en><![CDATA[Activate]]></en>
+        </locale>
+        <locale name="editors.settings.plugins.table.button.deactivate">
+            <de><![CDATA[Deaktivieren]]></de>
+            <en><![CDATA[Deactivate]]></en>
+        </locale>
+        <locale name="message.settings.plugins.activation.success">
+            <de><![CDATA[Plugin erfolgreich aktiviert]]></de>
+            <en><![CDATA[Plugin enabled successfully]]></en>
+        </locale>
+        <locale name="message.settings.plugins.deactivation.success">
+            <de><![CDATA[Plugin erfolgreich deaktiviert]]></de>
+            <en><![CDATA[Plugin disabled successfully]]></en>
+        </locale>
     </groups>
 </locales>
\ No newline at end of file
diff --git a/src/QUI/Ckeditor/EventHandler.php b/src/QUI/Ckeditor/EventHandler.php
new file mode 100644
index 0000000..bdf2127
--- /dev/null
+++ b/src/QUI/Ckeditor/EventHandler.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace QUI\Ckeditor;
+
+
+use QUI\Ckeditor\Plugins\Manager;
+use QUI\Package\Package;
+use QUI\System\Log;
+
+class EventHandler
+{
+
+    /**
+     * @param Package $Package
+     */
+    public static function onPackageSetup($Package)
+    {
+        if ($Package->getName() != "quiqqer/ckeditor4") {
+            return;
+        }
+
+        $PluginManager = new Manager();
+
+        $PluginManager->installPluginsFromSource();
+    }
+
+    /**
+     * @param Package $Package
+     */
+    public static function onPackageUpdate($Package)
+    {
+        if ($Package->getName() != "quiqqer/ckeditor4") {
+            return;
+        }
+
+        $PluginManager = new Manager();
+
+        $PluginManager->updatePlugins();
+
+    }
+}
\ No newline at end of file
diff --git a/src/QUI/Ckeditor/Plugins/Manager.php b/src/QUI/Ckeditor/Plugins/Manager.php
index a4c8d6e..73d4f6f 100644
--- a/src/QUI/Ckeditor/Plugins/Manager.php
+++ b/src/QUI/Ckeditor/Plugins/Manager.php
@@ -3,33 +3,282 @@
 
 namespace QUI\Ckeditor\Plugins;
 
+use QUI\Exception;
+use QUI\Utils\Security\Orthos;
+use QUI\Utils\System\File;
+
 class Manager
 {
 
-    protected $pluginDir;
-    protected $pluginConfig;
+    protected $activePluginDir;
+    protected $installedPluginDir;
+
 
+    /**
+     * Manager constructor.
+     */
     public function __construct()
     {
-        $this->pluginDir = \QUI::getPackage("quiqqer/ckeditor4")->getVarDir()."/plugins";
-        $this->pluginConfig = "";
+        $this->activePluginDir    = \QUI::getPackage("quiqqer/ckeditor4")->getVarDir() . "/plugins/bin";
+        $this->installedPluginDir = \QUI::getPackage("quiqqer/ckeditor4")->getVarDir() . "/plugins/installed";
+
+
+        if (!is_dir($this->activePluginDir)) {
+            mkdir($this->activePluginDir, 0755, true);
+        }
+
+        if (!is_dir($this->installedPluginDir)) {
+            mkdir($this->installedPluginDir, 0755, true);
+        }
+    }
+
+    /**
+     * Activates the given plugin name
+     *
+     * @param $pluginName
+     *
+     * @throws Exception
+     */
+    public function activate($pluginName)
+    {
+        $pluginName = Orthos::clearPath($pluginName);
+        $pluginName = str_replace("/", "", $pluginName);
+
+        if (!is_dir($this->installedPluginDir . "/" . $pluginName)) {
+            throw new Exception(array("quiqqer/ckeditor4", "exception.plugin.activate.plugin.not.found"));
+        }
+
+        if (is_dir($this->activePluginDir . "/" . $pluginName)) {
+            throw new Exception(array("quiqqer/ckeditor4", "exception.plugin.already.active"));
+        }
+
+        rename($this->installedPluginDir . "/" . $pluginName, $this->activePluginDir . "/" . $pluginName);
     }
 
-    public function activate($pluginName){
+    /**
+     * Deactivates the given plugin name
+     *
+     * @param $pluginName
+     *
+     * @throws Exception
+     */
+    public function deactivate($pluginName)
+    {
+        $pluginName = Orthos::clearPath($pluginName);
+        $pluginName = str_replace("/", "", $pluginName);
+
+        if (!is_dir($this->activePluginDir . "/" . $pluginName)) {
+            throw new Exception(array("quiqqer/ckeditor4", "exception.plugin.activate.plugin.not.active"));
+        }
+
+        if (is_dir($this->installedPluginDir . "/" . $pluginName)) {
+            File::deleteDir($this->activePluginDir . "/" . $pluginName);
+
+            return;
+        }
+
+        rename($this->activePluginDir . "/" . $pluginName, $this->installedPluginDir . "/" . $pluginName);
+    }
+
+    /**
+     * Returns a list of all plugins and their details
+     * Format:
+     * array(
+     *  [0] => array(
+     *      ["name"] => "pluginname",
+     *      ["state"] => 0|1  (1 for active; 0 for inactive)
+     *  )
+     * )
+     *
+     * @return array
+     */
+    public function getAllPlugins()
+    {
+        $result = array();
+
+        foreach ($this->getActivePlugins() as $plugin) {
+            $result[] = array(
+                'name'  => $plugin,
+                'state' => 1
+            );
+        }
+
+        foreach ($this->getInstalledPlugins() as $plugin) {
+            $result[] = array(
+                'name'  => $plugin,
+                'state' => 0
+            );
+        }
+
+        return $result;
+    }
+
+    /**
+     * Returns all installed plugins
+     *
+     * @return string[] - array of plugin names
+     */
+    public function getInstalledPlugins()
+    {
+        $result = array();
+
+        $content = scandir($this->installedPluginDir);
+        if ($content === false) {
+            return array();
+        }
+
+        foreach ($content as $entry) {
+            if ($entry == "." || $entry == "..") {
+                continue;
+            }
+            $fullpath = $this->installedPluginDir . "/" . $entry;
+
+
+            if (!is_dir($fullpath)) {
+
+                continue;
+            }
+
 
+            $result[] = $entry;
+        }
+
+        return $result;
     }
 
-    public function deactivate($pluginName){
+    /**
+     * Returns all active plugins
+     *
+     * @return string[] - Array of active plugin names
+     */
+    public function getActivePlugins()
+    {
+        $result = array();
+
+        $content = scandir($this->activePluginDir);
+        if ($content === false) {
+            return array();
+        }
+
+        foreach ($content as $entry) {
+            if ($entry == "." || $entry == "..") {
+                continue;
+            }
+            $fullpath = $this->activePluginDir . "/" . $entry;
 
+            if (!is_dir($fullpath)) {
+
+                continue;
+            }
+
+            $result[] = $entry;
+        }
+
+        return $result;
     }
 
-    public function install($pluginName){
+    /**
+     * Installs the plugins from the source packages quiqqer/ckeditor4 and ckeditor4/ckeditor4
+     *
+     */
+    public function installPluginsFromSource()
+    {
+        $srcDirs = array(
+            OPT_DIR . "ckeditor/ckeditor/plugins",
+            OPT_DIR . "quiqqer/ckeditor4/plugins"
+
+        );
+
+        foreach ($srcDirs as $srcDir) {
+            $targetDir = $this->installedPluginDir;
+
+            if (!is_dir($srcDir)) {
+                return;
+            }
+
+            foreach (scandir($srcDir) as $entry) {
+
+                if ($entry == "." || $entry == "..") {
+                    continue;
+                }
+
+                if (!is_dir($srcDir . "/" . $entry)) {
+                    continue;
+                }
+
+                if (is_dir($targetDir . "/" . $entry)) {
+                    continue;
+                }
+
+                if (is_dir($this->activePluginDir . "/" . $entry)) {
+                    continue;
+                }
+
+                File::dircopy(
+                    $srcDir . "/" . $entry,
+                    $targetDir . "/" . $entry
+                );
+            }
+        }
 
     }
 
-    public function deinstall($pluginName){
+    /**
+     * Updates the plugins
+     */
+    public function updatePlugins()
+    {
+        $srcDirs = array(
+            OPT_DIR . "ckeditor/ckeditor/plugins",
+            OPT_DIR . "quiqqer/ckeditor4/plugins"
+
+        );
+
+        foreach ($srcDirs as $srcDir) {
+
+            if (!is_dir($srcDir)) {
+                return;
+            }
+
+
+            foreach (scandir($srcDir) as $entry) {
+
+                if ($entry == "." || $entry == "..") {
+                    continue;
+                }
 
+                if (!is_dir($srcDir . "/" . $entry)) {
+                    continue;
+                }
+
+                # Check if/where the plugin is installed
+                $targetDir = $this->installedPluginDir . "/" . $entry;
+                if (is_dir($this->activePluginDir . "/" . $entry)) {
+                    $targetDir = $this->activePluginDir . "/" . $entry;
+                }
+
+                if (is_dir($targetDir)) {
+                    File::deleteDir($targetDir);
+                }
+
+
+                File::dircopy(
+                    $srcDir . "/" . $entry,
+                    $targetDir
+                );
+            }
+        }
     }
 
 
+    /**
+     * Returns the plugin dir
+     *
+     * @return string
+     */
+    public function getPluginDir()
+    {
+        return \QUI::getPackage("quiqqer/ckeditor4")->getVarDir() . "/plugins";
+    }
+
 }
\ No newline at end of file
-- 
GitLab