mainview: make all context menus generated at run time with the same style

By giving a base context menu, all context menus are generated at run time
and kept the same style. Some issues are fixed along with the patch.

Gitlab: #8
Gitlab: #35
Change-Id: Ieb812420fcb44c33d161a62c8574f6705dc5e1a9
diff --git a/src/mainview/components/CallViewContextMenu.qml b/src/mainview/components/CallViewContextMenu.qml
index 2deeeaa..5b2272a 100644
--- a/src/mainview/components/CallViewContextMenu.qml
+++ b/src/mainview/components/CallViewContextMenu.qml
@@ -17,6 +17,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
+
 import QtQuick 2.14
 import QtQuick.Controls 2.14
 import QtGraphicalEffects 1.12
@@ -24,61 +25,125 @@
 
 import "../../commoncomponents"
 
+import "../../commoncomponents/js/contextmenugenerator.js" as ContextMenuGenerator
 import "../js/videodevicecontextmenuitemcreation.js" as VideoDeviceContextMenuItemCreation
 import "../js/selectscreenwindowcreation.js" as SelectScreenWindowCreation
+import "../js/screenrubberbandcreation.js" as ScreenRubberBandCreation
 
-Menu {
+Item {
     id: root
 
-    property int generalMenuSeparatorCount: 0
-    property int commonBorderWidth: 1
-
-    signal pluginItemClicked
-
-    font.pointSize: JamiTheme.textFontSize+3
-
     property bool isSIP: false
     property bool isPaused: false
     property bool isAudioOnly: false
     property bool isRecording: false
 
+    signal pluginItemClicked
     signal transferCallButtonClicked
 
-    function activate() {
+    function openMenu(){
+        if (isSIP){
+            ContextMenuGenerator.addMenuItem(isPaused ? qsTr("Resume call") : qsTr("Hold call"),
+                                             isPaused ?
+                                                 "qrc:/images/icons/play_circle_outline-24px.svg" :
+                                                 "qrc:/images/icons/pause_circle_outline-24px.svg",
+                                             function (){
+                                                 CallAdapter.holdThisCallToggle()
+                                             })
+            ContextMenuGenerator.addMenuItem(qsTr("Sip Input Panel"),
+                                             "qrc:/images/icons/ic_keypad.svg",
+                                             function (){
+                                                 sipInputPanel.open()
+                                             })
+            ContextMenuGenerator.addMenuItem(qsTr("Transfer call"),
+                                             "qrc:/images/icons/phone_forwarded-24px.svg",
+                                             function (){
+                                                 root.transferCallButtonClicked()
+                                             })
+
+            ContextMenuGenerator.addMenuSeparator()
+        }
+
+        if (!isAudioOnly) {
+            ContextMenuGenerator.addMenuItem(isRecording ? qsTr("Stop recording") :
+                                                           qsTr("Start recording"),
+                                             "qrc:/images/icons/ic_video_call_24px.svg",
+                                             function (){
+                                                  CallAdapter.recordThisCallToggle()
+                                             })
+            ContextMenuGenerator.addMenuItem(videoCallPage.isFullscreen ? qsTr("Exit full screen") :
+                                                                          qsTr("Full screen mode"),
+                                             videoCallPage.isFullscreen ?
+                                                 "qrc:/images/icons/close_fullscreen-24px.svg" :
+                                                 "qrc:/images/icons/open_in_full-24px.svg",
+                                             function (){
+                                                  videoCallPageRect.needToShowInFullScreen()
+                                             })
+
+            ContextMenuGenerator.addMenuSeparator()
+
+            generateDeviceMenuItem()
+
+            ContextMenuGenerator.addMenuSeparator()
+
+            ContextMenuGenerator.addMenuItem(qsTr("Share entire screen"),
+                                             "qrc:/images/icons/screen_share-24px.svg",
+                                             function (){
+                                                 if (Qt.application.screens.length === 1) {
+                                                     AvAdapter.shareEntireScreen(0)
+                                                 } else {
+                                                     SelectScreenWindowCreation.createSelectScreenWindowObject()
+                                                     SelectScreenWindowCreation.showSelectScreenWindow()
+                                                 }
+                                             })
+            ContextMenuGenerator.addMenuItem(qsTr("Share screen area"),
+                                             "qrc:/images/icons/screen_share-24px.svg",
+                                             function (){
+                                                 if (Qt.application.screens.length === 1) {
+                                                     ScreenRubberBandCreation.createScreenRubberBandWindowObject(
+                                                                 null, 0)
+                                                     ScreenRubberBandCreation.showScreenRubberBandWindow()
+                                                 } else {
+                                                     SelectScreenWindowCreation.createSelectScreenWindowObject(true)
+                                                     SelectScreenWindowCreation.showSelectScreenWindow()
+                                                 }
+                                             })
+            ContextMenuGenerator.addMenuItem(qsTr("Share file"),
+                                             "qrc:/images/icons/insert_photo-24px.svg",
+                                             function (){
+                                                  jamiFileDialog.open()
+                                             })
+        }
+
+        ContextMenuGenerator.addMenuItem(qsTr("Toggle plugin"),
+                                         "qrc:/images/icons/extension_24dp.svg",
+                                         function (){
+                                              root.pluginItemClicked()
+                                         })
+
+        root.height = ContextMenuGenerator.getMenu().height
+        root.width = ContextMenuGenerator.getMenu().width
+        ContextMenuGenerator.getMenu().open()
+    }
+
+    function generateDeviceMenuItem() {
         var deviceContextMenuInfoMap = AvAdapter.populateVideoDeviceContextMenuItem()
+
         /*
          * Somehow, the map size is undefined, so use this instead.
          */
         var mapSize = deviceContextMenuInfoMap["size"]
 
-        var count = 2
+        if (mapSize === 0)
+            VideoDeviceContextMenuItemCreation.createVideoDeviceContextMenuItemObjects(
+                        qsTr("No video device"), false)
+
         for (var deviceName in deviceContextMenuInfoMap) {
-            if (deviceName === "size" || root.isAudioOnly)
+            if (deviceName === "size")
                 continue
-            if (videoDeviceItem.itemName === "No video device") {
-                videoDeviceItem.checkable = true
-                videoDeviceItem.itemName = deviceName
-                videoDeviceItem.checked = deviceContextMenuInfoMap[deviceName]
-                if (count === mapSize)
-                    root.open()
-            } else {
-                VideoDeviceContextMenuItemCreation.createVideoDeviceContextMenuItemObjects(
-                            deviceName, deviceContextMenuInfoMap[deviceName],
-                            count === mapSize)
-            }
-            count++
+            VideoDeviceContextMenuItemCreation.createVideoDeviceContextMenuItemObjects(
+                        deviceName, deviceContextMenuInfoMap[deviceName])
         }
-        root.open()
-    }
-
-    Component.onCompleted: {
-        VideoDeviceContextMenuItemCreation.setVideoContextMenuObject(root)
-    }
-
-
-    onClosed: {
-        videoDeviceItem.itemName = "No video device"
-        VideoDeviceContextMenuItemCreation.removeCreatedItems()
     }
 
     JamiFileDialog {
@@ -92,187 +157,13 @@
         }
     }
 
-    /*
-     * All GeneralMenuItems should remain the same width / height.
-     */
-    GeneralMenuItem {
-        id: holdCallButton
+    Component.onCompleted: {
+        ContextMenuGenerator.createBaseContextMenuObjects(root)
+        VideoDeviceContextMenuItemCreation.setVideoContextMenuObject(ContextMenuGenerator.getMenu())
 
-        visible: isSIP
-        height: isSIP? undefined : 0
-
-        itemName: isPaused? qsTr("Resume call") : qsTr("Hold call")
-        iconSource: isPaused? "qrc:/images/icons/play_circle_outline-24px.svg" : "qrc:/images/icons/pause_circle_outline-24px.svg"
-        leftBorderWidth: commonBorderWidth
-        rightBorderWidth: commonBorderWidth
-
-        onClicked: {
-            CallAdapter.holdThisCallToggle()
-            root.close()
-        }
-    }
-
-    GeneralMenuItem {
-        id: showSipInputPanelButton
-
-        visible: isSIP
-        height: isSIP? undefined : 0
-
-        itemName: qsTr("Sip Input Panel")
-        iconSource: "qrc:/images/icons/ic_keypad.svg"
-        leftBorderWidth: commonBorderWidth
-        rightBorderWidth: commonBorderWidth
-
-        onClicked: {
-            root.close()
-            sipInputPanel.open()
-        }
-    }
-
-    GeneralMenuItem {
-        id: transferCallButton
-
-        visible: isSIP
-        height: isSIP? undefined : 0
-
-        itemName: qsTr("Transfer call")
-        iconSource: "qrc:/images/icons/phone_forwarded-24px.svg"
-        leftBorderWidth: commonBorderWidth
-        rightBorderWidth: commonBorderWidth
-
-        onClicked: {
-            root.transferCallButtonClicked()
-            root.close()
-        }
-    }
-
-    GeneralMenuSeparator {
-        preferredWidth: startRecordingItem.preferredWidth
-        preferredHeight: commonBorderWidth
-
-        visible: isSIP
-        height: isSIP? undefined : 0
-
-        Component.onCompleted: {
-            generalMenuSeparatorCount++
-        }
-    }
-
-    GeneralMenuItem {
-        id: startRecordingItem
-
-        itemName: isRecording? qsTr("Stop recording") : qsTr("Start recording")
-        iconSource: "qrc:/images/icons/ic_video_call_24px.svg"
-        leftBorderWidth: commonBorderWidth
-        rightBorderWidth: commonBorderWidth
-
-        onClicked: {
-            root.close()
-            CallAdapter.recordThisCallToggle()
-        }
-    }
-
-    GeneralMenuItem {
-        id: fullScreenItem
-
-        itemName: videoCallPage.isFullscreen ? qsTr("Exit full screen") : qsTr(
-                                     "Full screen mode")
-        iconSource: videoCallPage.isFullscreen ? "qrc:/images/icons/close_fullscreen-24px.svg" : "qrc:/images/icons/open_in_full-24px.svg"
-        leftBorderWidth: commonBorderWidth
-        rightBorderWidth: commonBorderWidth
-
-        onClicked: {
-            root.close()
-            videoCallPageRect.needToShowInFullScreen()
-        }
-    }
-
-    GeneralMenuSeparator {
-        preferredWidth: startRecordingItem.preferredWidth
-        preferredHeight: commonBorderWidth
-
-        Component.onCompleted: {
-            generalMenuSeparatorCount++
-        }
-    }
-
-    VideoCallPageContextMenuDeviceItem {
-        id: videoDeviceItem
-        visible: !isAudioOnly
-        height: !isAudioOnly? undefined : 0
-
-        contextMenuPreferredWidth: root.implicitWidth
-    }
-
-    GeneralMenuSeparator {
-        preferredWidth: startRecordingItem.preferredWidth
-        preferredHeight: commonBorderWidth
-        visible: !isAudioOnly
-        height: !isAudioOnly? undefined : 0
-
-        Component.onCompleted: {
-            generalMenuSeparatorCount++
-        }
-    }
-
-    GeneralMenuItem {
-        id: shareEntireScreenItem
-
-        itemName: qsTr("Share entire screen")
-        iconSource: "qrc:/images/icons/screen_share-24px.svg"
-        leftBorderWidth: commonBorderWidth
-        rightBorderWidth: commonBorderWidth
-        visible: !isAudioOnly
-        height: !isAudioOnly? undefined : 0
-
-        onClicked: {
-            root.close()
-            if (Qt.application.screens.length === 1) {
-                AvAdapter.shareEntireScreen(0)
-            } else {
-                SelectScreenWindowCreation.createSelectScreenWindowObject()
-                SelectScreenWindowCreation.showSelectScreenWindow()
-            }
-        }
-    }
-
-    GeneralMenuItem {
-        id: shareScreenAreaItem
-
-        itemName: qsTr("Share screen area")
-        iconSource: "qrc:/images/icons/screen_share-24px.svg"
-        leftBorderWidth: commonBorderWidth
-        rightBorderWidth: commonBorderWidth
-        visible: !isAudioOnly
-        height: !isAudioOnly? undefined : 0
-
-        onClicked: {
-            root.close()
-            if (Qt.application.screens.length === 1) {
-                ScreenRubberBandCreation.createScreenRubberBandWindowObject(
-                            null, 0)
-                ScreenRubberBandCreation.showScreenRubberBandWindow()
-            } else {
-                SelectScreenWindowCreation.createSelectScreenWindowObject(true)
-                SelectScreenWindowCreation.showSelectScreenWindow()
-            }
-        }
-    }
-
-    GeneralMenuItem {
-        id: shareFileItem
-
-        itemName: qsTr("Share file")
-        iconSource: "qrc:/images/icons/insert_photo-24px.svg"
-        leftBorderWidth: commonBorderWidth
-        rightBorderWidth: commonBorderWidth
-        visible: !isAudioOnly
-        height: !isAudioOnly? undefined : 0
-
-        onClicked: {
-            root.close()
-            jamiFileDialog.open()
-        }
+        ContextMenuGenerator.getMenu().closed.connect(function (){
+            VideoDeviceContextMenuItemCreation.removeCreatedItems()
+        })
     }
 
     /* TODO: In the future we want to implement this
@@ -289,31 +180,5 @@
             root.close()
         }
     }*/
-
-    GeneralMenuItem {
-        id: pluginItem
-
-        itemName: qsTr("Toggle plugin")
-        iconSource: "qrc:/images/icons/extension_24dp.svg"
-        leftBorderWidth: commonBorderWidth
-        rightBorderWidth: commonBorderWidth
-
-        onClicked: {
-            root.pluginItemClicked()
-            root.close()
-        }
-    }
-
-    background: Rectangle {
-        implicitWidth: startRecordingItem.preferredWidth
-        implicitHeight: startRecordingItem.preferredHeight
-                        * (root.count
-                          - (isSIP? 0 : 2)
-                          - (isAudioOnly? 6 : 0)
-                          - generalMenuSeparatorCount)
-
-        border.width: commonBorderWidth
-        border.color: JamiTheme.tabbarBorderColor
-    }
 }