layouts::storage,move copyView() function

pull/19/head
Michail Vourlakos 5 years ago
parent 53a0cb6574
commit d3c1f4d1a8

@ -406,7 +406,7 @@ void GenericLayout::setLastConfigViewFor(Latte::View *view)
emit lastConfigViewForChanged(view);
}
Latte::View *GenericLayout::viewForContainment(Plasma::Containment *containment)
Latte::View *GenericLayout::viewForContainment(Plasma::Containment *containment) const
{
if (m_containments.contains(containment) && m_latteViews.contains(containment)) {
return m_latteViews[containment];
@ -1682,7 +1682,20 @@ void GenericLayout::syncToLayoutFile(bool removeLayoutId)
void GenericLayout::copyView(Plasma::Containment *containment)
{
m_storage->copyView(containment);
//! Don't create LatteView when the containment is created because we must update its screen settings first
setBlockAutomaticLatteViewCreation(true);
Layouts::ViewDelayedCreationData result = Layouts::Storage::self()->copyView(this, containment);
if (result.containment) {
addView(result.containment, result.forceOnPrimary, result.explicitScreen);
if (result.reactToScreenChange) {
result.containment->reactToScreenChange();
}
}
//m_storage->copyView(containment);
setBlockAutomaticLatteViewCreation(false);
emit viewEdgeChanged();
}

@ -107,7 +107,7 @@ public:
const QList<Plasma::Containment *> *containments() const;
Latte::View *highestPriorityView();
Latte::View *viewForContainment(Plasma::Containment *containment);
Latte::View *viewForContainment(Plasma::Containment *containment) const;
virtual QList<Latte::View *> sortedLatteViews(QList<Latte::View *> views = QList<Latte::View *>());
virtual QList<Latte::View *> viewsWithPlasmaShortcuts();
virtual QList<Latte::View *> latteViews();

@ -60,173 +60,6 @@ void Storage::setStorageTmpDir(const QString &tmpDir)
m_storageTmpDir = tmpDir;
}
void Storage::copyView(Plasma::Containment *containment)
{
if (!containment || !m_layout->corona())
return;
qDebug() << "copying containment layout";
//! Setting mutable for create a containment
m_layout->corona()->setImmutability(Plasma::Types::Mutable);
QString temp1File = m_storageTmpDir + "/" + m_layout->name() + ".copy.view";
//! WE NEED A WAY TO COPY A CONTAINMENT!!!!
QFile copyFile(temp1File);
if (copyFile.exists())
copyFile.remove();
KSharedConfigPtr newFile = KSharedConfig::openConfig(temp1File);
KConfigGroup copied_conts = KConfigGroup(newFile, "Containments");
KConfigGroup copied_c1 = KConfigGroup(&copied_conts, QString::number(containment->id()));
containment->config().copyTo(&copied_c1);
//!investigate if there multiple systray(s) in the containment to copy also
//! systrayId, systrayAppletId
QHash<uint, QString> systraysInfo;
auto applets = containment->config().group("Applets");
for (const auto &applet : applets.groupList()) {
KConfigGroup appletSettings = applets.group(applet).group("Configuration");
int tSysId = appletSettings.readEntry("SystrayContainmentId", -1);
if (tSysId != -1) {
systraysInfo[tSysId] = applet;
qDebug() << "systray with id "<< tSysId << " was found in the containment... ::: " << tSysId;
}
}
if (systraysInfo.count() > 0) {
for(const auto systrayId : systraysInfo.keys()) {
Plasma::Containment *systray{nullptr};
for (const auto containment : m_layout->corona()->containments()) {
if (containment->id() == systrayId) {
systray = containment;
break;
}
}
if (systray) {
KConfigGroup copied_systray = KConfigGroup(&copied_conts, QString::number(systray->id()));
systray->config().copyTo(&copied_systray);
}
}
}
//! end of systray specific code
//! update ids to unique ones
QString temp2File = newUniqueIdsLayoutFromFile(temp1File);
//! Don't create LatteView when the containment is created because we must update
//! its screen settings first
m_layout->setBlockAutomaticLatteViewCreation(true);
//! Finally import the configuration
QList<Plasma::Containment *> importedDocks = importLayoutFile(temp2File);
Plasma::Containment *newContainment{nullptr};
if (importedDocks.size() == 1) {
newContainment = importedDocks[0];
}
if (!newContainment || !newContainment->kPackage().isValid()) {
qWarning() << "the requested containment plugin can not be located or loaded";
return;
}
auto config = newContainment->config();
//in multi-screen environment the copied dock is moved to alternative screens first
const auto screens = qGuiApp->screens();
auto dock = m_layout->viewForContainment(containment);
bool setOnExplicitScreen = false;
int dockScrId = -1;
int copyScrId = -1;
if (dock) {
dockScrId = dock->positioner()->currentScreenId();
qDebug() << "COPY DOCK SCREEN ::: " << dockScrId;
if (dockScrId != -1 && screens.count() > 1) {
for (const auto scr : screens) {
copyScrId = m_layout->corona()->screenPool()->id(scr->name());
//the screen must exist and not be the same with the original dock
if (copyScrId > -1 && copyScrId != dockScrId) {
QList<Plasma::Types::Location> fEdges = m_layout->freeEdges(copyScrId);
if (fEdges.contains((Plasma::Types::Location)containment->location())) {
///set this containment to an explicit screen
config.writeEntry("onPrimary", false);
config.writeEntry("lastScreen", copyScrId);
newContainment->setLocation(containment->location());
qDebug() << "COPY DOCK SCREEN NEW SCREEN ::: " << copyScrId;
setOnExplicitScreen = true;
break;
}
}
}
}
}
if (!setOnExplicitScreen) {
QList<Plasma::Types::Location> edges = m_layout->freeEdges(newContainment->screen());
if (edges.count() > 0) {
newContainment->setLocation(edges.at(0));
} else {
newContainment->setLocation(Plasma::Types::BottomEdge);
}
config.writeEntry("onPrimary", true);
config.writeEntry("lastScreen", dockScrId);
}
newContainment->config().sync();
if (setOnExplicitScreen && copyScrId > -1) {
qDebug() << "Copy Dock in explicit screen ::: " << copyScrId;
m_layout->addView(newContainment, false, copyScrId);
newContainment->reactToScreenChange();
} else {
qDebug() << "Copy Dock in current screen...";
m_layout->addView(newContainment, false, dockScrId);
}
m_layout->setBlockAutomaticLatteViewCreation(false);
}
QList<Plasma::Containment *> Storage::importLayoutFile(QString file)
{
KSharedConfigPtr filePtr = KSharedConfig::openConfig(file);
auto newContainments = m_layout->corona()->importLayout(KConfigGroup(filePtr, ""));
///Find latte and systray containments
qDebug() << " imported containments ::: " << newContainments.length();
QList<Plasma::Containment *> importedDocks;
//QList<Plasma::Containment *> systrays;
for (const auto containment : newContainments) {
if (Layouts::Storage::self()->isLatteContainment(containment)) {
qDebug() << "new latte containment id: " << containment->id();
importedDocks << containment;
}
}
return importedDocks;
}
void Storage::systraysInformation(QHash<int, QList<int>> &systrays, QList<int> &assignedSystrays, QList<int> &orphanSystrays)
{
systrays.clear();
@ -319,196 +152,5 @@ QList<int> Storage::viewsScreens()
return screens;
}
QString Storage::availableId(QStringList all, QStringList assigned, int base)
{
bool found = false;
int i = base;
while (!found && i < 32000) {
QString iStr = QString::number(i);
if (!all.contains(iStr) && !assigned.contains(iStr)) {
return iStr;
}
i++;
}
return QString("");
}
QString Storage::newUniqueIdsLayoutFromFile(QString file)
{
if (!m_layout->corona()) {
return QString();
}
QString tempFile = m_storageTmpDir + "/" + m_layout->name() + ".views.newids";
QFile copyFile(tempFile);
if (copyFile.exists()) {
copyFile.remove();
}
//! BEGIN updating the ids in the temp file
QStringList allIds;
allIds << m_layout->corona()->containmentsIds();
allIds << m_layout->corona()->appletsIds();
QStringList toInvestigateContainmentIds;
QStringList toInvestigateAppletIds;
QStringList toInvestigateSystrayContIds;
//! first is the systray containment id
QHash<QString, QString> systrayParentContainmentIds;
QHash<QString, QString> systrayAppletIds;
//qDebug() << "Ids:" << allIds;
//qDebug() << "to copy containments: " << toCopyContainmentIds;
//qDebug() << "to copy applets: " << toCopyAppletIds;
QStringList assignedIds;
QHash<QString, QString> assigned;
KSharedConfigPtr filePtr = KSharedConfig::openConfig(file);
KConfigGroup investigate_conts = KConfigGroup(filePtr, "Containments");
//! Record the containment and applet ids
for (const auto &cId : investigate_conts.groupList()) {
toInvestigateContainmentIds << cId;
auto appletsEntries = investigate_conts.group(cId).group("Applets");
toInvestigateAppletIds << appletsEntries.groupList();
//! investigate for systrays
for (const auto &appletId : appletsEntries.groupList()) {
KConfigGroup appletSettings = appletsEntries.group(appletId).group("Configuration");
int tSysId = appletSettings.readEntry("SystrayContainmentId", -1);
//! It is a systray !!!
if (tSysId != -1) {
QString tSysIdStr = QString::number(tSysId);
toInvestigateSystrayContIds << tSysIdStr;
systrayParentContainmentIds[tSysIdStr] = cId;
systrayAppletIds[tSysIdStr] = appletId;
qDebug() << "systray was found in the containment...";
}
}
}
//! Reassign containment and applet ids to unique ones
for (const auto &contId : toInvestigateContainmentIds) {
QString newId = availableId(allIds, assignedIds, 12);
assignedIds << newId;
assigned[contId] = newId;
}
for (const auto &appId : toInvestigateAppletIds) {
QString newId = availableId(allIds, assignedIds, 40);
assignedIds << newId;
assigned[appId] = newId;
}
qDebug() << "ALL CORONA IDS ::: " << allIds;
qDebug() << "FULL ASSIGNMENTS ::: " << assigned;
for (const auto &cId : toInvestigateContainmentIds) {
QString value = assigned[cId];
if (assigned.contains(value)) {
QString value2 = assigned[value];
if (cId != assigned[cId] && !value2.isEmpty() && cId == value2) {
qDebug() << "PROBLEM APPEARED !!!! FOR :::: " << cId << " .. fixed ..";
assigned[cId] = cId;
assigned[value] = value;
}
}
}
for (const auto &aId : toInvestigateAppletIds) {
QString value = assigned[aId];
if (assigned.contains(value)) {
QString value2 = assigned[value];
if (aId != assigned[aId] && !value2.isEmpty() && aId == value2) {
qDebug() << "PROBLEM APPEARED !!!! FOR :::: " << aId << " .. fixed ..";
assigned[aId] = aId;
assigned[value] = value;
}
}
}
qDebug() << "FIXED FULL ASSIGNMENTS ::: " << assigned;
//! update applet ids in their containment order and in MultipleLayouts update also the layoutId
for (const auto &cId : investigate_conts.groupList()) {
//! Update options that contain applet ids
//! (appletOrder) and (lockedZoomApplets) and (userBlocksColorizingApplets)
QStringList options;
options << "appletOrder" << "lockedZoomApplets" << "userBlocksColorizingApplets";
for (const auto &settingStr : options) {
QString order1 = investigate_conts.group(cId).group("General").readEntry(settingStr, QString());
if (!order1.isEmpty()) {
QStringList order1Ids = order1.split(";");
QStringList fixedOrder1Ids;
for (int i = 0; i < order1Ids.count(); ++i) {
fixedOrder1Ids.append(assigned[order1Ids[i]]);
}
QString fixedOrder1 = fixedOrder1Ids.join(";");
investigate_conts.group(cId).group("General").writeEntry(settingStr, fixedOrder1);
}
}
if (m_layout->corona()->layoutsManager()->memoryUsage() == MemoryUsage::MultipleLayouts) {
investigate_conts.group(cId).writeEntry("layoutId", m_layout->name());
}
}
//! must update also the systray id in its applet
for (const auto &systrayId : toInvestigateSystrayContIds) {
KConfigGroup systrayParentContainment = investigate_conts.group(systrayParentContainmentIds[systrayId]);
systrayParentContainment.group("Applets").group(systrayAppletIds[systrayId]).group("Configuration").writeEntry("SystrayContainmentId", assigned[systrayId]);
systrayParentContainment.sync();
}
investigate_conts.sync();
//! Copy To Temp 2 File And Update Correctly The Ids
KSharedConfigPtr file2Ptr = KSharedConfig::openConfig(tempFile);
KConfigGroup fixedNewContainmets = KConfigGroup(file2Ptr, "Containments");
for (const auto &contId : investigate_conts.groupList()) {
QString pluginId = investigate_conts.group(contId).readEntry("plugin", "");
if (pluginId != "org.kde.desktopcontainment") { //!don't add ghost containments
KConfigGroup newContainmentGroup = fixedNewContainmets.group(assigned[contId]);
investigate_conts.group(contId).copyTo(&newContainmentGroup);
newContainmentGroup.group("Applets").deleteGroup();
for (const auto &appId : investigate_conts.group(contId).group("Applets").groupList()) {
KConfigGroup appletGroup = investigate_conts.group(contId).group("Applets").group(appId);
KConfigGroup newAppletGroup = fixedNewContainmets.group(assigned[contId]).group("Applets").group(assigned[appId]);
appletGroup.copyTo(&newAppletGroup);
}
}
}
fixedNewContainmets.sync();
return tempFile;
}
}
}

@ -40,8 +40,6 @@ public:
Storage(GenericLayout *parent);
~Storage() override;
void copyView(Plasma::Containment *containment);
void setStorageTmpDir(const QString &tmpDir);
//! Functions used from Layout Reports
@ -52,16 +50,6 @@ public:
//! list<ViewData>
QList<ViewData> viewsData(const QHash<int, QList<int>> &systrays);
private:
//! STORAGE !////
QString availableId(QStringList all, QStringList assigned, int base);
//! provides a new file path based the provided file. The new file
//! has updated ids for containments and applets based on the corona
//! loaded ones
QString newUniqueIdsLayoutFromFile(QString file);
//! imports a layout file and returns the containments for the docks
QList<Plasma::Containment *> importLayoutFile(QString file);
private:
GenericLayout *m_layout;

@ -23,8 +23,10 @@
#include "importer.h"
#include "manager.h"
#include "../lattecorona.h"
#include "../screenpool.h"
#include "../layout/abstractlayout.h"
#include "../layout/storage.h"
#include "../view/view.h"
// Qt
#include <QDebug>
@ -407,6 +409,156 @@ QList<Plasma::Containment *> Storage::importLayoutFile(const Layout::GenericLayo
return importedDocks;
}
ViewDelayedCreationData Storage::copyView(const Layout::GenericLayout *layout, Plasma::Containment *containment)
{
if (!containment || !layout->corona()) {
return ViewDelayedCreationData();
}
qDebug() << "copying containment layout";
//! Setting mutable for create a containment
layout->corona()->setImmutability(Plasma::Types::Mutable);
QString temp1File = m_storageTmpDir.path() + "/" + layout->name() + ".copy.view";
//! WE NEED A WAY TO COPY A CONTAINMENT!!!!
QFile copyFile(temp1File);
if (copyFile.exists())
copyFile.remove();
KSharedConfigPtr newFile = KSharedConfig::openConfig(temp1File);
KConfigGroup copied_conts = KConfigGroup(newFile, "Containments");
KConfigGroup copied_c1 = KConfigGroup(&copied_conts, QString::number(containment->id()));
containment->config().copyTo(&copied_c1);
//!investigate if there multiple systray(s) in the containment to copy also
//! systrayId, systrayAppletId
QHash<uint, QString> systraysInfo;
auto applets = containment->config().group("Applets");
for (const auto &applet : applets.groupList()) {
KConfigGroup appletSettings = applets.group(applet).group("Configuration");
int tSysId = appletSettings.readEntry("SystrayContainmentId", -1);
if (tSysId != -1) {
systraysInfo[tSysId] = applet;
qDebug() << "systray with id "<< tSysId << " was found in the containment... ::: " << tSysId;
}
}
if (systraysInfo.count() > 0) {
for(const auto systrayId : systraysInfo.keys()) {
Plasma::Containment *systray{nullptr};
for (const auto containment : layout->corona()->containments()) {
if (containment->id() == systrayId) {
systray = containment;
break;
}
}
if (systray) {
KConfigGroup copied_systray = KConfigGroup(&copied_conts, QString::number(systray->id()));
systray->config().copyTo(&copied_systray);
}
}
}
//! end of systray specific code
//! update ids to unique ones
QString temp2File = newUniqueIdsLayoutFromFile(layout, temp1File);
//! Finally import the configuration
QList<Plasma::Containment *> importedDocks = importLayoutFile(layout, temp2File);
Plasma::Containment *newContainment{nullptr};
if (importedDocks.size() == 1) {
newContainment = importedDocks[0];
}
if (!newContainment || !newContainment->kPackage().isValid()) {
qWarning() << "the requested containment plugin can not be located or loaded";
return ViewDelayedCreationData();
}
auto config = newContainment->config();
//in multi-screen environment the copied dock is moved to alternative screens first
const auto screens = qGuiApp->screens();
auto dock = layout->viewForContainment(containment);
bool setOnExplicitScreen = false;
int dockScrId = -1;
int copyScrId = -1;
if (dock) {
dockScrId = dock->positioner()->currentScreenId();
qDebug() << "COPY DOCK SCREEN ::: " << dockScrId;
if (dockScrId != -1 && screens.count() > 1) {
for (const auto scr : screens) {
copyScrId = layout->corona()->screenPool()->id(scr->name());
//the screen must exist and not be the same with the original dock
if (copyScrId > -1 && copyScrId != dockScrId) {
QList<Plasma::Types::Location> fEdges = layout->freeEdges(copyScrId);
if (fEdges.contains((Plasma::Types::Location)containment->location())) {
///set this containment to an explicit screen
config.writeEntry("onPrimary", false);
config.writeEntry("lastScreen", copyScrId);
newContainment->setLocation(containment->location());
qDebug() << "COPY DOCK SCREEN NEW SCREEN ::: " << copyScrId;
setOnExplicitScreen = true;
break;
}
}
}
}
}
if (!setOnExplicitScreen) {
QList<Plasma::Types::Location> edges = layout->freeEdges(newContainment->screen());
if (edges.count() > 0) {
newContainment->setLocation(edges.at(0));
} else {
newContainment->setLocation(Plasma::Types::BottomEdge);
}
config.writeEntry("onPrimary", true);
config.writeEntry("lastScreen", dockScrId);
}
newContainment->config().sync();
ViewDelayedCreationData result;
if (setOnExplicitScreen && copyScrId > -1) {
qDebug() << "Copy Dock in explicit screen ::: " << copyScrId;
result.containment = newContainment;
result.forceOnPrimary = false;
result.explicitScreen = copyScrId;
result.reactToScreenChange = true;
} else {
qDebug() << "Copy Dock in current screen...";
result.containment = newContainment;
result.forceOnPrimary = false;
result.explicitScreen = dockScrId;
result.reactToScreenChange = false;
}
return result;
}
bool Storage::isBroken(const Layout::GenericLayout *layout, QStringList &errors) const
{
if (layout->file().isEmpty() || !QFile(layout->file()).exists()) {

@ -38,6 +38,14 @@ class GenericLayout;
namespace Latte {
namespace Layouts {
struct ViewDelayedCreationData
{
Plasma::Containment *containment{nullptr};
bool forceOnPrimary{false};
int explicitScreen{-1};
bool reactToScreenChange{false};
};
class Storage
{
@ -55,6 +63,7 @@ public:
void importToCorona(const Layout::GenericLayout *layout);
void syncToLayoutFile(const Layout::GenericLayout *layout, bool removeLayoutId);
ViewDelayedCreationData copyView(const Layout::GenericLayout *layout, Plasma::Containment *containment);
/// STATIC
//! Check if an applet config group is valid or belongs to removed applet

Loading…
Cancel
Save