//=========================================== // Lumina-DE source code // Copyright (c) 2016, Ken Moore // Available under the 3-clause BSD license // See the LICENSE file for full details //=========================================== #include "7ZBackend.h" #include <QFile> #include <QDebug> ZBackend::ZBackend(QObject *parent) : QObject(parent){ //Setup the backend process PROC.setProcessChannelMode(QProcess::MergedChannels); PROC.setProgram("7z"); connect(&PROC, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(procFinished(int, QProcess::ExitStatus)) ); connect(&PROC, SIGNAL(readyReadStandardOutput()), this, SLOT(processData()) ); connect(&PROC, SIGNAL(started()), this, SIGNAL(ProcessStarting()) ); LIST = STARTING = false; } ZBackend::~ZBackend(){ } //=============== // PUBLIC //=============== void ZBackend::loadFile(QString path, QString pass){ filepath = path; flags.clear(); //contents.clear(); //Now determine the flags which are used for this type of file (for later use) if(!pass.isEmpty()){ flags << "-p"+pass; } //add password entry //Look for some special file extensions which 7z can't seem to detect itself QStringList ext = path.section("/",-1).section(".",1,-1).split("."); if(ext.contains("tar")){ flags << "-ttar"; } flags << filepath; //add the actual archive path if(QFile::exists(path)){ startList(); } else{ contents.clear(); emit ProcessFinished(); } } QString ZBackend::currentFile(){ return filepath; } bool ZBackend::isWorking(){ return (PROC.state() != QProcess::Running); } //Listing routines QStringList ZBackend::heirarchy(){ return contents.keys(); } double ZBackend::size(QString file){ if(!contents.contains(file)){ return -1; } return contents.value(file)[1].toDouble(); } double ZBackend::csize(QString file){ if(!contents.contains(file)){ return -1; } return contents.value(file)[2].toDouble(); } bool ZBackend::isDir(QString file){ if(!contents.contains(file)){ return false; } return contents.value(file)[0].startsWith("D"); } //Modification routines void ZBackend::startAdd(QStringList paths){ QStringList args; args << "a" << flags << paths; STARTING=true; PROC.start("7z", args); } void ZBackend::startRemove(QStringList paths){ QStringList args; args << "d" << flags << paths; STARTING=true; PROC.start("7z", args); } void ZBackend::startExtract(QString path, bool preservepaths){ QStringList args; args << (preservepaths ? "x" : "e") << flags << "-o"+path; STARTING=true; PROC.start("7z", args); } //=============== // PUBLIC SLOTS //=============== //=============== // PRIVATE //=============== void ZBackend::parseLines(QStringList lines){ if(STARTING){ //Ignore all the p7zip header info while(STARTING && !lines.isEmpty()){ if(lines[0]=="--"){ STARTING = false; } //found the end of the headers lines.removeAt(0); } } for(int i=0; i<lines.length(); i++){ if(lines[i].simplified().isEmpty() || lines[i].contains(" = ") || lines[i].contains("----") ){ continue; } if(LIST){ if(lines[i].contains(" Attr ") || lines[i].contains(", ") ){ continue; } //headers QStringList info = lines[i].split(" ",QString::SkipEmptyParts); //Format: [date, time, attr, size, compressed size, name] if(info.length()<6){ continue; } //invalid line while(info.length()>6){ info[5] = info[5]+" "+info[6]; info.removeAt(6); } //Filename has spaces in it contents.insert(info[5], QStringList() << info[2] << info[3] << info[4]); //Save the } } } void ZBackend::startList(){ contents.clear(); QStringList args; args << "l"; //list (lowercase L) LIST = STARTING=true; PROC.start("7z", QStringList() << args << flags); } //=============== // PRIVATE SLOTS //=============== void ZBackend::procFinished(int retcode, QProcess::ExitStatus){ processData(); //qDebug() << "Process Finished:" << PROC.arguments() << retcode; LIST = STARTING = false; if(PROC.arguments().contains("l")){ emit ProcessFinished(); }else{ if(retcode==0){ QStringList args = PROC.arguments(); for(int i=0; i<args.length(); i++){ if(args[i].startsWith("-o")){ QProcess::startDetached("xdg-open \""+ args[i].section("-o",1,-1)+"\""); } //just extracted to a dir - open it now } } startList(); } } void ZBackend::processData(){ //Read the process static QString data; QString read = data+PROC.readAllStandardOutput(); if(read.endsWith("\n")){ data.clear(); } else{ data = read.section("\n",-1); read = read.section("\n",0,-2); } QStringList lines = read.split("\n",QString::SkipEmptyParts); if(LIST){ parseLines(lines); } //qDebug() << lines; emit ProgressUpdate(-1, ""); }