Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
/*
* Platformer Game Engine by Wohlstand, a free platform for game making
* Copyright (c) 2014-2023 Vitaly Novichkov <admin@wohlnet.ru>
*
* This program 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 3 of the License, or
* any later version.
*
* This program 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 <QString>
#include <QFile>
#include <QDir>
#include <QTextStream>
#include <QSettings>
#include <QApplication>
#include <QtDebug>
#include <QProcess>
#include <QtConcurrent>
#include <QProgressDialog>
#include <QFutureWatcher>
#include <PGE_File_Formats/file_formats.h>
#include "app_path.h"
#include "installer.h"
Installer::Installer(QObject *parent):
QObject(parent)
{}
Installer::~Installer()
{}
void Installer::moveFromAppToUser()
{
if(AppPathManager::userAppDir() == ApplicationPath) return;
QDir app(ApplicationPath);
QStringList find;
find << "pge_editor.ini" << "*counters.ini";
QStringList files = app.entryList(find);
for(QString &f : files)
QFile::copy(ApplicationPath + "/" + f, AppPathManager::userAppDir() + "/" + f);
QSettings setup(AppPathManager::settingsFile(), QSettings::IniFormat);
setup.setIniCodec("UTF-8");
setup.beginGroup("logging");
setup.remove("log-path");
setup.endGroup();
for(QString &f : files)
QFile(ApplicationPath + "/" + f).remove();
}
#if defined(__linux__)
static bool xCopyFile(const QString &src, const QString &target)
{
QFile tmp;
tmp.setFileName(target);
if(tmp.exists())
tmp.remove();
bool ret = QFile::copy(src, target);
if(!ret)
qWarning() << "Failed to copy file" << src << "into" << target;
else
qDebug() << "File " << src << "was successfully copiled into" << target;
return ret;
}
static bool xRunCommand(QString command, const QStringList &args)
{
QProcess xdg;
xdg.setProgram(command);
xdg.setArguments(args);
xdg.start();
xdg.waitForFinished();
QString printed = xdg.readAll();
if(!printed.isEmpty())
qDebug() << printed;
bool ret = (xdg.exitCode() == 0);
if(!ret)
qWarning() << "Command" << command << "with arguments" << args << "finished with failure";
else
qDebug() << "Command" << command << "with arguments" << args << "successfully finished";
return ret;
}
static bool xInstallIconResource(QString context, int iconSize, QString iconName, QString mimeName)
{
QStringList args;
args << "install";
args << "--context";
args << context;
if(context == "apps")
args << "--novendor";
args << "--size";
args << QString::number(iconSize);
args << QDir::home().absolutePath() + "/.local/share/icons/" + iconName.arg(iconSize);
args << mimeName;
return xRunCommand("xdg-icon-resource", args);
}
static bool xIconSize(int iconSize)
{
bool success = true;
QString home = QDir::home().absolutePath();
if(success) success = xCopyFile(QString(":/_files/_files/file_lvl/file_lvl_%1.png")
.arg(iconSize),
QString("%1/.local/share/icons/smbx64-level-%2.png")
.arg(home).arg(iconSize));
if(success) success = xCopyFile(QString(":/_files/_files/file_lvlx/file_lvlx_%1.png")
.arg(iconSize),
QString("%1/.local/share/icons/pgex-level-%2.png")
.arg(home).arg(iconSize));
if(success) success = xCopyFile(QString(":/_files/_files/file_wld/file_wld_%1.png")
.arg(iconSize),
QString("%1/.local/share/icons/smbx64-world-%2.png")
.arg(home).arg(iconSize));
if(success) success = xCopyFile(QString(":/_files/_files/file_wldx/file_wldx_%1.png")
.arg(iconSize),
QString("%1/.local/share/icons/pgex-world-%2.png")
.arg(home).arg(iconSize));
if(success) success = xCopyFile(QString(":images/cat_builder/cat_builder_%1.png")
.arg(iconSize),
QString("%1/.local/share/icons/PgeEditor-%2.png")
.arg(home).arg(iconSize));
if(success) success = xInstallIconResource("mimetypes", iconSize, "smbx64-level-%1.png", "x-application-smbx64-level");
if(success) success = xInstallIconResource("mimetypes", iconSize, "smbx64-world-%1.png", "x-application-smbx64-world");
if(success) success = xInstallIconResource("mimetypes", iconSize, "pgex-level-%1.png", "x-application-pgex-level");
if(success) success = xInstallIconResource("mimetypes", iconSize, "pgex-world-%1.png", "x-application-pgex-world");
if(success) success = xInstallIconResource("apps", iconSize, "PgeEditor-%1.png", "PgeEditor");
return success;
}
#endif
bool Installer::associateFiles(QWidget *parent)
{
if(!parent)
return associateFiles_thread();
else
{
QFutureWatcher<bool> watcher;
QProgressDialog waiter(parent);
waiter.setWindowTitle(tr("Please wait..."));
waiter.setLabelText(tr("Please wait..."));
waiter.setModal(true);
waiter.setValue(0);
waiter.setMaximum(0);
waiter.setCancelButton(nullptr);
waiter.show();
QObject::connect(&watcher, &QFutureWatcher<bool>::finished, &waiter, &QProgressDialog::cancel);
QFuture<bool> reply = QtConcurrent::run(&Installer::associateFiles_thread);
watcher.setFuture(reply);
waiter.exec();
reply.waitForFinished();
return reply.result();
}
}
bool Installer::associateFiles_thread()
{
bool success = true;
#if defined(_WIN32)
//QSettings registry_hkcr("HKEY_CLASSES_ROOT", QSettings::NativeFormat);
QSettings registry_hkcu("HKEY_CURRENT_USER", QSettings::NativeFormat);
// add template
//WriteToLog(QtDebugMsg, registry_hkcu.value("Software/Microsoft/Windows/CurrentVersion/Explorer/Shell Folders/Templates").toString().replace("\\","/")+QString("/sample.lvl"));
//WriteToLog(QtDebugMsg, registry_hkcu.value("Software/Microsoft/Windows/CurrentVersion/Explorer/Shell Folders/Templates").toString().replace("\\","/")+QString("/sample.wld"));
//registry_hkcr
//QFile l(QProcessEnvironment::systemEnvironment().value("windir","C:\\Windows").replace("\\","/")+QString("/ShellNew/sample.lvl"));
//QFile w(QProcessEnvironment::systemEnvironment().value("windir","C:\\Windows").replace("\\","/")+QString("/ShellNew/sample.wld"));
QFile l(registry_hkcu.value("Software/Microsoft/Windows/CurrentVersion/Explorer/Shell Folders/Templates").toString().replace("\\", "/") + QString("/sample.lvl"));
QFile w(registry_hkcu.value("Software/Microsoft/Windows/CurrentVersion/Explorer/Shell Folders/Templates").toString().replace("\\", "/") + QString("/sample.wld"));
QFile lx(registry_hkcu.value("Software/Microsoft/Windows/CurrentVersion/Explorer/Shell Folders/Templates").toString().replace("\\", "/") + QString("/sample.lvlx"));
QFile wx(registry_hkcu.value("Software/Microsoft/Windows/CurrentVersion/Explorer/Shell Folders/Templates").toString().replace("\\", "/") + QString("/sample.wldx"));
success = l.open(QIODevice::WriteOnly);
QString raw;
if(success)
{
LevelData indata;
FileFormats::CreateLevelData(indata);
FileFormats::WriteSMBX64LvlFileRaw(indata, raw, 64);
l.write(QByteArray(raw.toStdString().c_str()));
l.close();
}
success = w.open(QIODevice::WriteOnly);
if(success)
{
WorldData indata;
FileFormats::CreateWorldData(indata);
FileFormats::WriteSMBX64WldFileRaw(indata, raw, 64);
w.write(QByteArray(raw.toStdString().c_str()));
w.close();
}
success = lx.open(QIODevice::WriteOnly);
if(success)
{
LevelData indata;
FileFormats::CreateLevelData(indata);
FileFormats::WriteExtendedLvlFileRaw(indata, raw);
l.write(QByteArray(raw.toStdString().c_str()));
l.close();
}
success = wx.open(QIODevice::WriteOnly);
if(success)
{
WorldData indata;
FileFormats::CreateWorldData(indata);
FileFormats::WriteExtendedWldFileRaw(indata, raw);
w.write(QByteArray(raw.toStdString().c_str()));
w.close();
}
// file extension(s)
registry_hkcu.setValue("Software/Classes/.lvlx/Default", "PGEWohlstand.Level"); //Reserved
registry_hkcu.setValue("Software/Classes/.wldx/Default", "PGEWohlstand.World"); //Reserved
registry_hkcu.setValue("Software/Classes/.lvl/Default", "SMBX64.Level");
registry_hkcu.setValue("Software/Classes/.wld/Default", "SMBX64.World");
registry_hkcu.setValue("Software/Classes/.lvlx/ShellNew/FileName", "sample.lvlx");
registry_hkcu.setValue("Software/Classes/.wldx/ShellNew/FileName", "sample.wldx");
registry_hkcu.setValue("Software/Classes/.lvl/ShellNew/FileName", "sample.lvl");
registry_hkcu.setValue("Software/Classes/.wld/ShellNew/FileName", "sample.wld");
//registry_hkcr.setValue(".lvlx/Default", "PGWWohlstand.Level");
//registry_hkcr.setValue(".wldx/Default", "PGWWohlstand.World");
registry_hkcu.setValue("Software/Classes/PGEWohlstand.Level/Default", tr("PGE Level file", "File Types"));
registry_hkcu.setValue("Software/Classes/PGEWohlstand.Level/DefaultIcon/Default", "\"" + QApplication::applicationFilePath().replace("/", "\\") + "\",1");
registry_hkcu.setValue("Software/Classes/PGEWohlstand.Level/Shell/Open/Command/Default", "\"" + QApplication::applicationFilePath().replace("/", "\\") + "\" \"%1\"");
registry_hkcu.setValue("Software/Classes/PGEWohlstand.Level/Shell/Play level/Command/Default", "\"" + QApplication::applicationDirPath().replace("/", "\\") + "\\pge_engine.exe\" \"%1\"");
registry_hkcu.setValue("Software/Classes/PGEWohlstand.World/Default", tr("PGE World Map", "File Types"));
registry_hkcu.setValue("Software/Classes/PGEWohlstand.World/DefaultIcon/Default", "\"" + QApplication::applicationFilePath().replace("/", "\\") + "\",2");
registry_hkcu.setValue("Software/Classes/PGEWohlstand.World/Shell/Open/Command/Default", "\"" + QApplication::applicationFilePath().replace("/", "\\") + "\" \"%1\"");
registry_hkcu.setValue("Software/Classes/PGEWohlstand.World/Shell/Play episode/Command/Default", "\"" + QApplication::applicationDirPath().replace("/", "\\") + "\\pge_engine.exe\" \"%1\"");
registry_hkcu.setValue("Software/Classes/SMBX64.Level/Default", tr("SMBX Level file", "File Types"));
registry_hkcu.setValue("Software/Classes/SMBX64.Level/DefaultIcon/Default", "\"" + QApplication::applicationFilePath().replace("/", "\\") + "\",3");
registry_hkcu.setValue("Software/Classes/SMBX64.Level/Shell/Open/Command/Default", "\"" + QApplication::applicationFilePath().replace("/", "\\") + "\" \"%1\"");
registry_hkcu.setValue("Software/Classes/SMBX64.Level/Shell/Play level/Command/Default", "\"" + QApplication::applicationDirPath().replace("/", "\\") + "\\pge_engine.exe\" \"%1\"");
registry_hkcu.setValue("Software/Classes/SMBX64.World/Default", tr("SMBX World Map", "File Types"));
registry_hkcu.setValue("Software/Classes/SMBX64.World/DefaultIcon/Default", "\"" + QApplication::applicationFilePath().replace("/", "\\") + "\",4");
registry_hkcu.setValue("Software/Classes/SMBX64.World/Shell/Open/Command/Default", "\"" + QApplication::applicationFilePath().replace("/", "\\") + "\" \"%1\"");
registry_hkcu.setValue("Software/Classes/SMBX64.World/Shell/Play episode/Command/Default", "\"" + QApplication::applicationDirPath().replace("/", "\\") + "\\pge_engine.exe\" \"%1\"");
// User variable(s)
registry_hkcu.setValue("Environment/QT_PLUGIN_PATH", "\"" + QString(ApplicationPath).replace("/", "\\") + "\"");
#elif defined(__APPLE__)
// only useful when other apps have taken precedence over our file extensions and you want to reset it
//Need write correct strings for allow associations for Mac OS:
/*
defaults write com.apple.LaunchServices LSHandlers -array-add '{
LSHandlerContentType = "com.apple.property-list";
LSHandlerRoleAll = "com.apple.dt.xcode"; }'
*/
QString x = QString("defaults write com.apple.LaunchServices LSHandlers -array-add '"
"<dict>"
"<key>LSHandlerContentTag</key>"
"<string>%1</string>"
"<key>LSHandlerContentTagClass</key>"
"<string>public.filename-extension</string>"
"<key>LSHandlerRoleAll</key>"
"<string>ru.wohlsoft.pge-editor</string>"
"</dict>"
"'");
int ret = system(x.arg("lvl").toStdString().c_str());
ret += system(x.arg("lvlx").toStdString().c_str());
ret += system(x.arg("wld").toStdString().c_str());
ret += system(x.arg("wldx").toStdString().c_str());
ret += system("/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill -domain local -domain system -domain user");
success = (ret == 0); // remove this when associator was created
#elif defined Q_OS_ANDROID
//Is not supported yet :P
success = false;
#elif defined(__linux__)
QString home = QDir::home().absolutePath();
// Here need correctly associate too
if(success) success = QDir().mkpath(home + "/.local/share/mime/packages");
if(success) success = QDir().mkpath(home + "/.local/share/applications");
if(success) success = QDir().mkpath(home + "/.local/share/icons");
xCopyFile(":/_files/_files/pge-project-mimeinfo.xml",
home + "/.local/share/mime/packages/pge-project-mimeinfo.xml");
if(success) success = xIconSize(16);
if(success) success = xIconSize(32);
if(success) success = xIconSize(48);
if(success) success = xIconSize(256);
QFile shortcut(":/_files/_files/pge_editor.desktop");
if(success) success = shortcut.open(QFile::ReadOnly | QFile::Text);
if(success)
{
QTextStream shtct(&shortcut);
QString shortcut_text = shtct.readAll();
QFile saveAs(home + "/.local/share/applications/pge_editor.desktop");
if(success) success = saveAs.open(QFile::WriteOnly | QFile::Text);
if(success) QTextStream(&saveAs) << shortcut_text.arg(ApplicationPath_x);
}
if(success) success = xRunCommand("xdg-mime", {"default", "pge_editor.desktop", "application/x-smbx64-level"});
if(success) success = xRunCommand("xdg-mime", {"default", "pge_editor.desktop", "application/x-smbx64-world"});
if(success) success = xRunCommand("xdg-mime", {"default", "pge_editor.desktop", "application/x-pgex-level"});
if(success) success = xRunCommand("xdg-mime", {"default", "pge_editor.desktop", "application/x-pgex-world"});
if(success) success = xRunCommand("update-desktop-database", {home + "/.local/share/applications"});
if(success) success = xRunCommand("update-mime-database", {home + "/.local/share/mime"});
#else
// Unsupported operating system
success = false;
#endif
return success;
}