/*
* Copyright 2017 Smith AR < audoban @ openmailbox . org >
* Michail Vourlakos < mvourlakos @ gmail . com >
*
* 2019 Michail Vourlakos < mvourlakos @ gmail . com >
*
* This file is part of Latte - Dock
*
* Latte - Dock is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation ; either version 2 of
* the License , or ( at your option ) any later version .
*
* Latte - Dock is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "manager.h"
// local
# include "importer.h"
# include "launcherssignals.h"
# include "../infoview.h"
# include "../screenpool.h"
# include "../data/layoutdata.h"
# include "../layout/abstractlayout.h"
# include "../layout/centrallayout.h"
# include "../settings/dialogs/settingsdialog.h"
# include "../settings/universalsettings.h"
# include "../templates/templatesmanager.h"
// Qt
# include <QDir>
# include <QFile>
# include <QMessageBox>
// KDE
# include <KLocalizedString>
# include <KNotification>
namespace Latte {
namespace Layouts {
const int MultipleLayoutsPresetId = 10 ;
Manager : : Manager ( QObject * parent )
: QObject ( parent ) ,
m_importer ( new Importer ( this ) ) ,
m_launchersSignals ( new LaunchersSignals ( this ) )
{
m_corona = qobject_cast < Latte : : Corona * > ( parent ) ;
//! needs to be created AFTER corona assignment
m_synchronizer = new Synchronizer ( this ) ;
if ( m_corona ) {
connect ( m_corona - > universalSettings ( ) , & UniversalSettings : : currentLayoutNameChanged , this , & Manager : : currentLayoutNameChanged ) ;
connect ( m_synchronizer , & Synchronizer : : centralLayoutsChanged , this , & Manager : : centralLayoutsChanged ) ;
connect ( m_synchronizer , & Synchronizer : : currentLayoutNameChanged , this , & Manager : : currentLayoutNameChanged ) ;
connect ( m_synchronizer , & Synchronizer : : currentLayoutIsSwitching , this , & Manager : : currentLayoutIsSwitching ) ;
connect ( m_synchronizer , & Synchronizer : : layoutsChanged , this , & Manager : : layoutsChanged ) ;
connect ( m_synchronizer , & Synchronizer : : menuLayoutsChanged , this , & Manager : : menuLayoutsChanged ) ;
}
}
Manager : : ~ Manager ( )
{
m_importer - > deleteLater ( ) ;
m_launchersSignals - > deleteLater ( ) ;
//! no needed because Latte:Corona is calling it at better place
// unload();
m_synchronizer - > deleteLater ( ) ;
}
void Manager : : load ( )
{
QDir layoutsDir ( QDir : : homePath ( ) + " /.config/latte " ) ;
bool firstRun = ! layoutsDir . exists ( ) ;
int configVer = m_corona - > universalSettings ( ) - > version ( ) ;
qDebug ( ) < < " Universal Settings version : " < < configVer ;
if ( firstRun ) {
m_corona - > universalSettings ( ) - > setVersion ( 2 ) ;
m_corona - > universalSettings ( ) - > setCurrentLayoutName ( i18n ( " My Layout " ) ) ;
//startup create what is necessary....
if ( ! layoutsDir . exists ( ) ) {
QDir ( QDir : : homePath ( ) + " /.config " ) . mkdir ( " latte " ) ;
}
m_corona - > templatesManager ( ) - > newLayout ( i18n ( " My Layout " ) , i18n ( Templates : : DEFAULTLAYOUTTEMPLATENAME ) ) ;
importPresets ( false ) ;
} else if ( configVer < 2 & & ! firstRun ) {
m_corona - > universalSettings ( ) - > setVersion ( 2 ) ;
bool isOlderVersion = m_importer - > updateOldConfiguration ( ) ;
if ( isOlderVersion ) {
qDebug ( ) < < " Latte is updating its older configuration... " ;
importPresets ( false ) ;
} else {
m_corona - > universalSettings ( ) - > setCurrentLayoutName ( i18n ( " My Layout " ) ) ;
}
}
//! Check if the multiple-layouts hidden file is present, add it if it isnt
if ( ! QFile ( QDir : : homePath ( ) + " /.config/latte/ " + Layout : : MULTIPLELAYOUTSHIDDENNAME + " .layout.latte " ) . exists ( ) ) {
importPreset ( MultipleLayoutsPresetId , false ) ;
}
qDebug ( ) < < " Latte is loading its layouts... " ;
m_synchronizer - > loadLayouts ( ) ;
}
void Manager : : unload ( )
{
m_synchronizer - > unloadLayouts ( ) ;
}
Latte : : Corona * Manager : : corona ( )
{
return m_corona ;
}
Importer * Manager : : importer ( )
{
return m_importer ;
}
LaunchersSignals * Manager : : launchersSignals ( ) const
{
return m_launchersSignals ;
}
Synchronizer * Manager : : synchronizer ( ) const
{
return m_synchronizer ;
}
QString Manager : : currentLayoutName ( ) const
{
return m_synchronizer - > currentLayoutName ( ) ;
}
QStringList Manager : : layouts ( ) const
{
return m_synchronizer - > layouts ( ) ;
}
QStringList Manager : : menuLayouts ( ) const
{
return m_synchronizer - > menuLayouts ( ) ;
}
void Manager : : setMenuLayouts ( QStringList layouts )
{
m_synchronizer - > setMenuLayouts ( layouts ) ;
}
MemoryUsage : : LayoutsMemory Manager : : memoryUsage ( ) const
{
return m_corona - > universalSettings ( ) - > layoutsMemoryUsage ( ) ;
}
void Manager : : setMemoryUsage ( MemoryUsage : : LayoutsMemory memoryUsage )
{
m_corona - > universalSettings ( ) - > setLayoutsMemoryUsage ( memoryUsage ) ;
}
QStringList Manager : : centralLayoutsNames ( )
{
return m_synchronizer - > centralLayoutsNames ( ) ;
}
QStringList Manager : : sharedLayoutsNames ( )
{
return m_synchronizer - > sharedLayoutsNames ( ) ;
}
QStringList Manager : : storedSharedLayouts ( ) const
{
return m_synchronizer - > storedSharedLayouts ( ) ;
}
CentralLayout * Manager : : currentLayout ( ) const
{
return m_synchronizer - > currentLayout ( ) ;
}
bool Manager : : switchToLayout ( QString layoutName , int previousMemoryUsage )
{
return m_synchronizer - > switchToLayout ( layoutName , previousMemoryUsage ) ;
}
void Manager : : loadLayoutOnStartup ( QString layoutName )
{
QStringList layouts = m_importer - > checkRepairMultipleLayoutsLinkedFile ( ) ;
//! Latte didn't close correctly, maybe a crash
if ( layouts . size ( ) > 0 ) {
QMessageBox * msg = new QMessageBox ( ) ;
msg - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
msg - > setIcon ( QMessageBox : : Warning ) ;
msg - > setWindowTitle ( i18n ( " Multiple Layouts Warning " ) ) ;
msg - > setText ( i18n ( " Latte did not close properly in the previous session. The following layout(s) <b>[%0]</b> were updated for consistency!!! " ) . arg ( layouts . join ( " , " ) ) ) ;
msg - > setStandardButtons ( QMessageBox : : Ok ) ;
msg - > open ( ) ;
}
m_synchronizer - > switchToLayout ( layoutName ) ;
}
void Manager : : loadLatteLayout ( QString layoutPath )
{
qDebug ( ) < < " -------------------------------------------------------------------- " ;
qDebug ( ) < < " -------------------------------------------------------------------- " ;
if ( m_corona - > containments ( ) . size ( ) > 0 ) {
qDebug ( ) < < " LOAD LATTE LAYOUT ::: There are still containments present !!!! :: " < < m_corona - > containments ( ) . size ( ) ;
}
if ( ! layoutPath . isEmpty ( ) & & m_corona - > containments ( ) . size ( ) = = 0 ) {
cleanupOnStartup ( layoutPath ) ;
qDebug ( ) < < " LOADING CORONA LAYOUT: " < < layoutPath ;
m_corona - > loadLayout ( layoutPath ) ;
}
}
void Manager : : cleanupOnStartup ( QString path )
{
KSharedConfigPtr filePtr = KSharedConfig : : openConfig ( path ) ;
KConfigGroup actionGroups = KConfigGroup ( filePtr , " ActionPlugins " ) ;
QStringList deprecatedActionGroup ;
for ( const auto & actId : actionGroups . groupList ( ) ) {
QString pluginId = actionGroups . group ( actId ) . readEntry ( " RightButton;NoModifier " , " " ) ;
if ( pluginId = = " org.kde.contextmenu " ) {
deprecatedActionGroup < < actId ;
}
}
for ( const auto & pId : deprecatedActionGroup ) {
qDebug ( ) < < " !!!!!!!!!!!!!!!! !!!!!!!!!!!! !!!!!!! REMOVING :::: " < < pId ;
actionGroups . group ( pId ) . deleteGroup ( ) ;
}
KConfigGroup containmentGroups = KConfigGroup ( filePtr , " Containments " ) ;
QStringList removeContaimentsList ;
for ( const auto & cId : containmentGroups . groupList ( ) ) {
QString pluginId = containmentGroups . group ( cId ) . readEntry ( " plugin " , " " ) ;
if ( pluginId = = " org.kde.desktopcontainment " ) { //!must remove ghost containments first
removeContaimentsList < < cId ;
}
}
for ( const auto & cId : removeContaimentsList ) {
containmentGroups . group ( cId ) . deleteGroup ( ) ;
}
}
void Manager : : showAboutDialog ( )
{
m_corona - > aboutApplication ( ) ;
}
void Manager : : clearUnloadedContainmentsFromLinkedFile ( QStringList containmentsIds , bool bypassChecks )
{
if ( ! m_corona | | ( memoryUsage ( ) = = MemoryUsage : : SingleLayout & & ! bypassChecks ) ) {
return ;
}
auto containments = m_corona - > config ( ) - > group ( " Containments " ) ;
for ( const auto & conId : containmentsIds ) {
qDebug ( ) < < " unloads ::: " < < conId ;
KConfigGroup containment = containments . group ( conId ) ;
containment . deleteGroup ( ) ;
}
}
void Manager : : importPresets ( bool includeDefault )
{
int start = 1 ;
if ( ! includeDefault ) {
start = 2 ;
}
for ( int i = start ; i < = 4 ; + + i ) {
importPreset ( i , false ) ;
}
}
void Manager : : importPreset ( int presetNo , bool newInstanceIfPresent )
{
QDir configDir ( QDir : : homePath ( ) + " /.config " ) ;
if ( ! QDir ( configDir . absolutePath ( ) + " /latte " ) . exists ( ) ) {
configDir . mkdir ( " latte " ) ;
}
QByteArray presetNameOrig = QString ( " preset " + QString : : number ( presetNo ) ) . toUtf8 ( ) ;
QString presetPath = m_corona - > kPackage ( ) . filePath ( presetNameOrig ) ;
QString presetName = Layout : : AbstractLayout : : layoutName ( presetPath ) ;
QByteArray presetNameChars = presetName . toUtf8 ( ) ;
presetName = i18n ( presetNameChars ) ;
//! hide the multiple layouts layout file from user
presetName = ( presetNo = = MultipleLayoutsPresetId ) ? " . " + presetName : presetName ;
QString newLayoutFile = " " ;
if ( newInstanceIfPresent ) {
newLayoutFile = QDir : : homePath ( ) + " /.config/latte/ " + m_importer - > uniqueLayoutName ( presetName ) + " .layout.latte " ;
} else {
newLayoutFile = QDir : : homePath ( ) + " /.config/latte/ " + presetName + " .layout.latte " ;
}
if ( ! QFile ( newLayoutFile ) . exists ( ) ) {
QFile ( presetPath ) . copy ( newLayoutFile ) ;
QFileInfo newFileInfo ( newLayoutFile ) ;
if ( newFileInfo . exists ( ) & & ! newFileInfo . isWritable ( ) ) {
QFile ( newLayoutFile ) . setPermissions ( QFileDevice : : ReadUser | QFileDevice : : WriteUser | QFileDevice : : ReadGroup | QFileDevice : : ReadOther ) ;
}
}
}
void Manager : : showLatteSettingsDialog ( int firstPage , bool toggleCurrentPage )
{
if ( ! m_latteSettingsDialog ) {
m_latteSettingsDialog = new Latte : : Settings : : Dialog : : SettingsDialog ( nullptr , m_corona ) ;
}
m_latteSettingsDialog - > show ( ) ;
if ( m_latteSettingsDialog - > isMinimized ( ) ) {
m_latteSettingsDialog - > showNormal ( ) ;
}
if ( toggleCurrentPage ) {
m_latteSettingsDialog - > toggleCurrentPage ( ) ;
} else {
m_latteSettingsDialog - > setCurrentPage ( firstPage ) ;
}
m_latteSettingsDialog - > activateWindow ( ) ;
}
void Manager : : hideLatteSettingsDialog ( )
{
if ( m_latteSettingsDialog ) {
m_latteSettingsDialog - > deleteLater ( ) ;
m_latteSettingsDialog = nullptr ;
}
}
void Manager : : showInfoWindow ( QString info , int duration , QStringList activities )
{
for ( const auto screen : qGuiApp - > screens ( ) ) {
InfoView * infoView = new InfoView ( m_corona , info , screen ) ;
infoView - > show ( ) ;
infoView - > setOnActivities ( activities ) ;
QTimer : : singleShot ( duration , [ this , infoView ] ( ) {
infoView - > deleteLater ( ) ;
} ) ;
}
}
}
}