aboutsummaryrefslogtreecommitdiff
path: root/lumina-fileinfo/dialog.cpp
diff options
context:
space:
mode:
authorKen Moore <moorekou@gmail.com>2015-04-21 00:12:51 -0400
committerKen Moore <moorekou@gmail.com>2015-04-21 00:12:51 -0400
commit6729dcd0cdafe09b061f9d7b36648388bbae4534 (patch)
tree7605ac7551ec061013e60aa9a73cc9380ebe3c9b /lumina-fileinfo/dialog.cpp
parentMake sure to check the list of watched files and reset it if something was re... (diff)
parenttest the return code of the command to mv file to refresh the icon. (diff)
downloadlumina-6729dcd0cdafe09b061f9d7b36648388bbae4534.tar.gz
lumina-6729dcd0cdafe09b061f9d7b36648388bbae4534.tar.bz2
lumina-6729dcd0cdafe09b061f9d7b36648388bbae4534.zip
Merge pull request #92 from william-os4y/deskEditor
I propose you the lumina-fileinfo
Diffstat (limited to 'lumina-fileinfo/dialog.cpp')
-rw-r--r--lumina-fileinfo/dialog.cpp359
1 files changed, 359 insertions, 0 deletions
diff --git a/lumina-fileinfo/dialog.cpp b/lumina-fileinfo/dialog.cpp
new file mode 100644
index 00000000..0c7c3a6a
--- /dev/null
+++ b/lumina-fileinfo/dialog.cpp
@@ -0,0 +1,359 @@
+#include "dialog.h"
+#include "ui_dialog.h"
+#include <QFileDialog>
+#include <QRegExp>
+#include <QTemporaryFile>
+#include <QMessageBox>
+#include "LuminaUtils.h"
+#include <LuminaOS.h>
+
+
+
+//this function is just like a regexp.
+//we just change the required lines and we don't touch to the rest of the file and copy it back.
+void Dialog::textReplace(QString &origin, QString from, QString to, QString topic)
+{
+ if (origin.contains(QRegExp("\n" + topic + "\\s*=\\s*" + from + "\n",Qt::CaseInsensitive))) {
+ origin.replace(QRegExp("\n" + topic + "\\s*=\\s*" + from + "\n",Qt::CaseInsensitive),"\n" + topic + "=" + to + "\n");
+ } else {
+ origin.append(topic + "=" + to + "\n");
+ }
+}
+
+//get the template from the user home directory or from the qrc files
+void Dialog::copyTemplate(QString templateType)
+{
+ if ((templateType == "-link") or (templateType == "-app")) {
+ if (QFile::exists(QDir::homePath() + "/.lumina/LuminaDE/fileinfo" + templateType + ".template")) {
+ //We take the template from homedir
+ QFile::copy(QDir::homePath() + "/.lumina/LuminaDE/fileinfo" + templateType + ".template", desktopFileName);
+ } else {
+ //last possibility is to use the qrc template.
+ //But based on the initialisation, this should never occurs
+ QFile::copy(":defaults/fileinfo" + templateType + ".template", desktopFileName);
+ }
+ } else {
+ //error message for developpers
+ qDebug() << "copyTemplate only accept '-link' or '-app' as parameter";
+ }
+}
+
+
+
+
+Dialog::Dialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::Dialog)
+{
+ ui->setupUi(this);
+ desktopType="Application"; //default value
+
+ //Setup all the icons using libLumina
+ this->setWindowIcon( LXDG::findIcon("preferences-desktop-default-applications","") );
+ ui->pbWorkingDir->setIcon( LXDG::findIcon("folder","") );
+ ui->pbCommand->setIcon( LXDG::findIcon("system-search","") );
+
+ //we copy qrc templates in the home dir of the user.
+ //this allow the user to adapt those template to is own whishes
+ QString templateFile = QDir::homePath() + "/.lumina/LuminaDE/fileinfo-link.template";
+ if (!QFile::exists(templateFile)) {
+ QFile::copy(":defaults/fileinfo-link.template", templateFile);
+ QFile(templateFile).setPermissions(QFileDevice::ReadUser|QFileDevice::WriteUser);
+ }
+ templateFile = QDir::homePath() + "/.lumina/LuminaDE/fileinfo-app.template";
+ if (!QFile::exists(templateFile)) {
+ QFile::copy(":defaults/fileinfo-app.template", templateFile);
+ QFile(templateFile).setPermissions(QFileDevice::ReadUser|QFileDevice::WriteUser);
+ }
+}
+
+
+Dialog::~Dialog()
+{
+ delete ui;
+}
+
+//Inform the user that required input parameters are missing
+void Dialog::MissingInputs()
+{
+ qDebug() << "We cannot continue without a desktop file !!!";
+ QMessageBox::critical(this, tr("Error"), tr("The application requires inputs: <-application>|<-link> desktopfile") );
+ exit(1);
+}
+
+
+//Initialise the layout of the screen.
+void Dialog::Initialise(QString param)
+{
+
+ //in case of "link", several objects are no required
+ if (param.startsWith("-link")) {
+ ui->cbRunInTerminal->setVisible(false);
+ ui->cbStartupNotification->setVisible(false);
+ ui->lCommand->setVisible(false);
+ ui->pbCommand->setVisible(false);
+ ui->lblCommand->setVisible(false);
+ ui->lblOptions->setVisible(false);
+ ui->lblWorkingDir->setText(tr("URL")); //we use the WorkingDir boxes for URL
+ desktopType="link";
+ }
+ if (param.startsWith("-app")) {
+ ui->cbRunInTerminal->setVisible(true);
+ ui->cbStartupNotification->setVisible(true);
+ ui->lCommand->setVisible(true);
+ ui->pbCommand->setVisible(true);
+ ui->lblCommand->setVisible(true);
+ ui->lblOptions->setVisible(true);
+ ui->lblWorkingDir->setText(tr("Working dir"));
+ desktopType="app";
+ }
+}
+
+
+
+
+//load the desktop file or the required template
+void Dialog::LoadDesktopFile(QString input)
+{
+ //if we have "-" as 1st char, it means that this is not a desktop file, but a parameter
+ desktopFileName = input;
+ if (input.startsWith("-")) {
+ QMessageBox::critical(this,tr("Error"),tr("The filename cannot start with a \"-\"."));
+ exit(1);
+ }
+
+ //if proposed file does not exist, than we will create one based on the templates
+ if (!QFile::exists(input)) {
+ if (desktopType=="link") {
+ copyTemplate("-link");
+ } else {
+ copyTemplate("-app");
+ }
+ }
+
+ //use the standard LXDG object and load the desktop file
+ bool ok = false;
+ DF = LXDG::loadDesktopFile(desktopFileName, ok);
+ if( ok ) {
+ if ((DF.type == XDGDesktop::LINK) && (desktopType!="link" )) {
+ //we open a desktop type "link" but it was not mentionned by parameters
+ Dialog::Initialise("-link");
+ }
+ ui->lName->setText(DF.name);
+ ui->lComment->setText(DF.comment);
+ ui->lCommand->setText(DF.exec);
+ //in case of "link" desktop, we populate the correct content in lWorkingDir
+ if (desktopType=="link") {
+ ui->lWorkingDir->setText(DF.url);
+ } else {
+ ui->lWorkingDir->setText(DF.path);
+ }
+ if (DF.startupNotify) ui->cbStartupNotification->setChecked(true); else ui->cbStartupNotification->setChecked(false);
+ if (DF.useTerminal) ui->cbRunInTerminal->setChecked(true); else ui->cbRunInTerminal->setChecked(false);
+ iconFileName="";
+ ui->pbIcon->setIcon(LXDG::findIcon(DF.icon,""));
+ } else {
+ QMessageBox::critical(this, tr("Error"), tr("Problem to read the desktop file called:") + desktopFileName );
+ exit(1);
+ }
+
+ //we load the file in memory and will adapt it before saving it to disk
+ QFile file(desktopFileName);
+ inMemoryFile="";
+ if (file.open(QFile::ReadOnly)) {
+ QTextStream fileData(&file);
+ inMemoryFile = fileData.readAll();
+ file.close();
+ //perform some validation checks
+ //TODO: put those Regex in a config file.
+ //this will allow checks improvements without compilation of the file
+ if ((inMemoryFile.contains(QRegExp(".*\\[Desktop Entry\\].*\n"))) &&
+ (inMemoryFile.contains(QRegExp("\n\\s*Type\\s*=.*\n"))) &&
+ (inMemoryFile.contains(QRegExp("\n\\s*Name\\s*=.*\n")))) {
+ //qDebug() << "sounds a good file";
+ } else {
+ //qDebug() << "wrong file!!!!";
+ QMessageBox msgBox;
+ msgBox.setIcon(QMessageBox::Question);
+ msgBox.setText(tr("There are some issues with this file !!!!"));
+ msgBox.setInformativeText(tr("Either you correct this file your self with an editor, or you start from scratch using the link or app template.\nPlease note that this process will update the file called:") + desktopFileName);
+ QPushButton *linkButton = msgBox.addButton("Link",QMessageBox::AcceptRole);
+ QPushButton *appButton = msgBox.addButton("App",QMessageBox::ResetRole);
+ QPushButton *cancelButton = msgBox.addButton("Cancel",QMessageBox::NoRole);
+ msgBox.exec();
+ if (msgBox.clickedButton() == linkButton) {
+ QFile::remove(desktopFileName);
+ copyTemplate("-link");
+ Initialise("-link");
+ LoadDesktopFile(desktopFileName);
+ }
+ if (msgBox.clickedButton() == appButton) {
+ QFile::remove(desktopFileName);
+ copyTemplate("-app");
+ Initialise("-app");
+ LoadDesktopFile(desktopFileName);
+ }
+ if (msgBox.clickedButton() == cancelButton) {
+ //we stop here
+ exit(0);
+ }
+ }
+ }
+}
+
+
+void Dialog::on_pbCommand_clicked()
+{
+ //the default directory is the user's home directory
+ QString commandFolder = QDir::homePath();
+ if (!ui->lCommand->text().isEmpty()) commandFolder = ui->lCommand->text().section('/', 0, -2);
+ if (commandFolder.isEmpty()) commandFolder = QDir::homePath();
+
+ QString fileName = QFileDialog::getOpenFileName(this,
+ tr("Open command"), commandFolder, tr("All Files (*)"));
+ if (!fileName.isEmpty()) {
+ ui->lCommand->setText(fileName);
+ ui->lCommand->setModified(true);
+ }
+}
+
+
+void Dialog::on_pbWorkingDir_clicked()
+{
+ //the default directory is /
+ QString workingDir = "/";
+ if (ui->lWorkingDir->text().isEmpty()) workingDir = "/";
+ else workingDir = ui->lWorkingDir->text();
+ QFileDialog::Options options = QFileDialog::DontResolveSymlinks | QFileDialog::ShowDirsOnly;
+ QString directory = QFileDialog::getExistingDirectory(this,
+ tr("Working Directory"),
+ workingDir,
+ options);
+ if (!directory.isEmpty()) {
+ ui->lWorkingDir->setText(directory);
+ ui->lWorkingDir->setModified(true);
+ }
+}
+
+//we save the changes to the destination file
+void Dialog::on_pbApply_clicked()
+{
+ QString from,to;
+ QString desktopTypeVal="Application";
+ if (DF.type == XDGDesktop::APP) { desktopTypeVal="Application"; }
+ else if (DF.type == XDGDesktop::LINK) { desktopTypeVal="Link"; }
+ else if (DF.type == XDGDesktop::DIR) { desktopTypeVal="Dir"; }
+ textReplace(inMemoryFile, desktopTypeVal, desktopType, "Type");
+
+ if (ui->lName->isModified()) { textReplace(inMemoryFile, DF.name, ui->lName->text(), "Name");}
+ if (ui->lComment->isModified()) { textReplace(inMemoryFile, DF.comment, ui->lComment->text(), "Comment");}
+ if (ui->lCommand->isModified()) { textReplace(inMemoryFile, DF.exec, ui->lCommand->text(),"Exec");}
+ if (desktopType=="link") {
+ //incase of "link" layout WorkingDir is corresponding to the URL
+ if (ui->lWorkingDir->isModified()) { textReplace(inMemoryFile, DF.url, ui->lWorkingDir->text(),"URL");}
+ } else {
+ if (ui->lWorkingDir->isModified()) { textReplace(inMemoryFile, DF.path, ui->lWorkingDir->text(),"Path");}
+ }
+ if (ui->cbStartupNotification->isChecked() != DF.startupNotify) {
+ if (DF.startupNotify) {from="true"; to="false";} else {from="false"; to="true";}
+ textReplace(inMemoryFile, from, to,"StartupNotify");
+ }
+ if (ui->cbRunInTerminal->isChecked() != DF.useTerminal) {
+ if (DF.useTerminal) {from="true"; to="false";} else {from="false"; to="true";}
+ textReplace(inMemoryFile, from, to,"Terminal");
+ }
+ if (!iconFileName.isEmpty()) {
+ from=DF.icon;
+ to=iconFileName;
+ textReplace(inMemoryFile, from, to,"Icon");
+ }
+
+ QFile file(desktopFileName);
+ if (file.open(QFile::ReadWrite)) {
+ file.seek(0);
+ file.write(inMemoryFile.toUtf8());
+
+ file.resize(file.pos());//remove possible trailing lines
+
+ file.close();
+ } else {
+ //problem to write to the disk
+ QMessageBox::critical(this, tr("Problem to write to disk"), tr("We have a problem to write the adapted desktop file to the disk. Can you re-try the modification after solving the issue with the disk ?"));
+ }
+
+ //hack required to update the icon on the desktop
+ QTemporaryFile tempFile ;
+ tempFile.setAutoRemove(false);
+ tempFile.setFileTemplate("/tmp/lumina-XXXXXX");
+ tempFile.open();
+ tempFile.close();
+
+ QString cmd = "mv";
+ cmd = cmd + " " + desktopFileName + " " + tempFile.fileName();
+ int ret = LUtils::runCmd(cmd);
+ if (ret !=0 ) {
+ qDebug() << "Problem to execute:" << cmd;
+ QMessageBox::critical(this, tr("Problem to write to disk"), tr("We have a problem to execute the following command:") + cmd);
+
+ }
+
+ cmd = "mv";
+ cmd = cmd + " " + tempFile.fileName() + " " + desktopFileName;
+ ret = LUtils::runCmd(cmd);
+ if (ret !=0 ) {
+ qDebug() << "Problem to execute:" << cmd;
+ QMessageBox::critical(this, tr("Problem to write to disk"), tr("We have a problem to execute the following command:") + cmd);
+ }
+}
+
+
+void Dialog::on_pbIcon_clicked()
+{
+ //the default directory is local/share/icons
+ QString iconFolder = LOS::AppPrefix()+"/share/icons";
+ if (!iconFileName.isEmpty()) iconFolder = iconFileName.section('/', 0, -2);
+ else if (!DF.icon.isEmpty()) iconFolder = DF.icon.section('/', 0, -2);
+ if (iconFolder.isEmpty()) iconFolder = LOS::AppPrefix()+"/share/icons";
+
+ QString fileName = QFileDialog::getOpenFileName(this,
+ tr("Open command"), iconFolder, tr("Image Files (*.png *.jpg *.bmp)"));
+ if (!fileName.isEmpty()) {
+ ui->pbIcon->setIcon(QPixmap(fileName));
+ iconFileName=fileName;
+ }
+}
+
+void Dialog::on_lName_textChanged(QString text)
+{
+ if (text != DF.name && inMemoryFile.contains(QRegExp("\nName\\[\\S+\\]\\s*=",Qt::CaseInsensitive))) {
+ QMessageBox msgBox;
+ msgBox.setText(tr("By modifying this value, you will loose all translated versions"));
+ msgBox.setInformativeText(tr("The field: Name is translated in several other languages. If you want to continue, you will loose all translated versions"));
+ msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
+ int answer = msgBox.exec();
+ if (answer==QMessageBox::Ok) {
+ //remove all translated versions. The lang cannot be null, but the value can be.
+ inMemoryFile.replace(QRegExp("\nName\\[\\S+\\]\\s*=[^\n]*",Qt::CaseInsensitive), "");
+ } else {
+ ui->lName->setText(DF.name);
+ }
+ }
+}
+
+void Dialog::on_lComment_textChanged(QString text)
+{
+ if (text != DF.name && inMemoryFile.contains(QRegExp("\nComment\\[\\S+\\]\\s*=",Qt::CaseInsensitive))) {
+ QMessageBox msgBox;
+ msgBox.setText(tr("By modifying this value, you will loose all translated versions"));
+ msgBox.setInformativeText(tr("The field: Comment is translated in several other languages. If you want to continue, you will loose all translated versions"));
+ msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
+ int answer = msgBox.exec();
+ if (answer==QMessageBox::Ok) {
+ //remove all translated versions. The lang cannot be null, but the value can be.
+ inMemoryFile.replace(QRegExp("\nComment\\[\\S+\\]\\s*=[^\n]*",Qt::CaseInsensitive), "");
+ } else {
+ ui->lName->setText(DF.comment);
+ }
+ }
+}
+
bgstack15