diff --git a/app/dbus/org.kde.LatteDock.xml b/app/dbus/org.kde.LatteDock.xml
index 6d56a829c..0cc45d1f4 100644
--- a/app/dbus/org.kde.LatteDock.xml
+++ b/app/dbus/org.kde.LatteDock.xml
@@ -15,6 +15,9 @@
+
+
+
diff --git a/app/lattecorona.cpp b/app/lattecorona.cpp
index de4c6f8ae..c9227ca9e 100644
--- a/app/lattecorona.cpp
+++ b/app/lattecorona.cpp
@@ -1166,6 +1166,14 @@ QStringList Corona::contextMenuData()
return data;
}
+void Corona::duplicateView(const uint &containmentId)
+{
+ auto view = m_layoutsManager->synchronizer()->viewForContainment((int)containmentId);
+ if (view) {
+ view->duplicateView();
+ }
+}
+
void Corona::removeView(const uint &containmentId)
{
auto view = m_layoutsManager->synchronizer()->viewForContainment((int)containmentId);
diff --git a/app/lattecorona.h b/app/lattecorona.h
index e73adf2e8..00d027c44 100644
--- a/app/lattecorona.h
+++ b/app/lattecorona.h
@@ -165,6 +165,7 @@ public slots:
void aboutApplication();
void activateLauncherMenu();
void loadDefaultLayout() override;
+ void duplicateView(const uint &containmentId);
void removeView(const uint &containmentId);
void setBackgroundFromBroadcast(QString activity, QString screenName, QString filename);
void setBroadcastedBackgroundsEnabled(QString activity, QString screenName, bool enabled);
diff --git a/app/layout/genericlayout.cpp b/app/layout/genericlayout.cpp
index 15076b4aa..9bb960ed4 100644
--- a/app/layout/genericlayout.cpp
+++ b/app/layout/genericlayout.cpp
@@ -1657,7 +1657,7 @@ void GenericLayout::syncToLayoutFile(bool removeLayoutId)
Layouts::Storage::self()->syncToLayoutFile(this, removeLayoutId);
}
-void GenericLayout::copyView(Plasma::Containment *containment)
+void GenericLayout::duplicateView(Plasma::Containment *containment)
{
//! Don't create LatteView when the containment is created because we must update its screen settings first
setBlockAutomaticLatteViewCreation(true);
diff --git a/app/layout/genericlayout.h b/app/layout/genericlayout.h
index 65f45cce4..3d001751f 100644
--- a/app/layout/genericlayout.h
+++ b/app/layout/genericlayout.h
@@ -124,7 +124,7 @@ public:
//! this function needs the layout to have first set the corona through initToCorona() function
virtual void addView(Plasma::Containment *containment, bool forceOnPrimary = false, int explicitScreen = -1, Layout::ViewsMap *occupied = nullptr);
- void copyView(Plasma::Containment *containment);
+ void duplicateView(Plasma::Containment *containment);
void recreateView(Plasma::Containment *containment, bool delayed = true);
bool latteViewExists(Plasma::Containment *containment);
diff --git a/app/view/view.cpp b/app/view/view.cpp
index d9e71cb07..537768ab9 100644
--- a/app/view/view.cpp
+++ b/app/view/view.cpp
@@ -449,9 +449,9 @@ void View::reconsiderScreen()
m_positioner->reconsiderScreen();
}
-void View::copyView()
+void View::duplicateView()
{
- m_layout->copyView(containment());
+ m_layout->duplicateView(containment());
}
void View::exportTemplate()
diff --git a/app/view/view.h b/app/view/view.h
index 85dfdd3a1..97d986540 100644
--- a/app/view/view.h
+++ b/app/view/view.h
@@ -268,7 +268,7 @@ public:
void releaseConfigView();
public slots:
- Q_INVOKABLE void copyView();
+ Q_INVOKABLE void duplicateView();
Q_INVOKABLE void exportTemplate();
Q_INVOKABLE void removeView();
diff --git a/containmentactions/contextmenu/menu.cpp b/containmentactions/contextmenu/menu.cpp
index 7f209b56f..6f076ae44 100644
--- a/containmentactions/contextmenu/menu.cpp
+++ b/containmentactions/contextmenu/menu.cpp
@@ -41,6 +41,7 @@ const char LAYOUTSNAME[] = "layouts";
const char PREFERENCESNAME[] = "preferences";
const char QUITLATTENAME[] = "quit latte";
const char ADDWIDGETSNAME[] = "add latte widgets";
+const char DUPLICATEVIEWNAME[] = "duplicate view";
const char EDITVIEWNAME[] = "edit view";
const char REMOVEVIEWNAME[] = "remove view";
@@ -142,6 +143,18 @@ void Menu::makeActions()
}
});
+ //! Duplicate Action
+ m_duplicateAction = new QAction(QIcon::fromTheme("edit-copy"), "Duplicate Dock", this);
+ m_duplicateAction->setVisible(containment()->isUserConfiguring());
+ connect(m_duplicateAction, &QAction::triggered, [=](){
+ QDBusInterface iface("org.kde.lattedock", "/Latte", "", QDBusConnection::sessionBus());
+
+ if (iface.isValid()) {
+ iface.call("duplicateView", containment()->id());
+ }
+ });
+ this->containment()->actions()->addAction(DUPLICATEVIEWNAME, m_duplicateAction);
+
//! Remove Action
m_removeAction = new QAction(QIcon::fromTheme("delete"), "Remove Dock", this);
m_removeAction->setVisible(containment()->isUserConfiguring());
@@ -184,6 +197,7 @@ QList Menu::contextualActions()
actions << m_separator2;
actions << m_addWidgetsAction;
+ actions << m_duplicateAction;
actions << m_configureAction;
actions << m_removeAction;
@@ -206,6 +220,9 @@ QList Menu::contextualActions()
const QString configureActionText = (viewType == DockView) ? i18nc("dock settings window", "&Edit Dock...") : i18nc("panel settings window", "&Edit Panel...");
m_configureAction->setText(configureActionText);
+ const QString duplicateActionText = (viewType == DockView) ? i18n("&Duplicate Dock") : i18n("&Duplicate Panel");
+ m_duplicateAction->setText(duplicateActionText);
+
const QString removeActionText = (viewType == DockView) ? i18n("&Remove Dock") : i18n("&Remove Panel");
m_removeAction->setText(removeActionText);
@@ -216,6 +233,8 @@ QAction *Menu::action(const QString &name)
{
if (name == ADDWIDGETSNAME) {
return m_addWidgetsAction;
+ } else if (name == DUPLICATEVIEWNAME) {
+ return m_duplicateAction;
} else if (name == EDITVIEWNAME) {
return m_configureAction;
} else if (name == LAYOUTSNAME) {
@@ -238,10 +257,12 @@ void Menu::onUserConfiguringChanged(const bool &configuring)
}
m_configureAction->setVisible(!configuring);
+ m_duplicateAction->setVisible(configuring);
m_removeAction->setVisible(configuring);
// because sometimes they are disabled unexpectedly, we should reenable them
m_configureAction->setEnabled(true);
+ m_duplicateAction->setEnabled(true);
m_removeAction->setEnabled(true);
}
diff --git a/containmentactions/contextmenu/menu.h b/containmentactions/contextmenu/menu.h
index f289dfc36..1a8eada7b 100644
--- a/containmentactions/contextmenu/menu.h
+++ b/containmentactions/contextmenu/menu.h
@@ -60,6 +60,7 @@ private:
QAction *m_addWidgetsAction{nullptr};
QAction *m_configureAction{nullptr};
+ QAction *m_duplicateAction{nullptr};
QAction *m_printAction{nullptr};
QAction *m_layoutsAction{nullptr};
QAction *m_preferenceAction{nullptr};
diff --git a/plasmoid/package/contents/ui/ContextMenu.qml b/plasmoid/package/contents/ui/ContextMenu.qml
index 651cb0abe..8498a7734 100644
--- a/plasmoid/package/contents/ui/ContextMenu.qml
+++ b/plasmoid/package/contents/ui/ContextMenu.qml
@@ -915,17 +915,25 @@ PlasmaComponents.ContextMenu {
PlasmaComponents.MenuItem {
id: addWidgets
action: appletAbilities.myView.isReady ? appletAbilities.myView.action("add latte widgets") : plasmoid.action("configure");
- visible: appletAbilities.myView.isReady
+ visible: appletAbilities.myView.isReady && action.visible
+ }
+
+ PlasmaComponents.MenuItem {
+ id: duplicateItem
+ action: appletAbilities.myView.isReady ? appletAbilities.myView.action("duplicate view") : plasmoid.action("configure")
+ visible: appletAbilities.myView.isReady && action.visible
}
PlasmaComponents.MenuItem {
id: configureItem
action: appletAbilities.myView.isReady ? appletAbilities.myView.action("edit view") : plasmoid.action("configure")
+ visible: appletAbilities.myView.isReady && action.visible
}
PlasmaComponents.MenuItem {
id: removeItem
action: appletAbilities.myView.isReady ? appletAbilities.myView.action("remove view") : plasmoid.action("remove")
+ visible: appletAbilities.myView.isReady && action.visible
}
//! BEGIN: Plasmoid actions when it isnt inside a Latte dock