aboutsummaryrefslogtreecommitdiff
path: root/src-qt5/desktop-utils/lumina-archiver/MainUI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src-qt5/desktop-utils/lumina-archiver/MainUI.cpp')
-rw-r--r--src-qt5/desktop-utils/lumina-archiver/MainUI.cpp324
1 files changed, 324 insertions, 0 deletions
diff --git a/src-qt5/desktop-utils/lumina-archiver/MainUI.cpp b/src-qt5/desktop-utils/lumina-archiver/MainUI.cpp
new file mode 100644
index 00000000..52831706
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-archiver/MainUI.cpp
@@ -0,0 +1,324 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2016, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "MainUI.h"
+#include "ui_MainUI.h"
+
+#include <QMessageBox>
+#include <QFileDialog>
+#include <LuminaXDG.h>
+#include <LUtils.h>
+
+#define TAREXT (
+MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){
+ ui->setupUi(this);
+ this->setWindowTitle(tr("Archive Manager"));
+ BACKEND = new Backend(this);
+ connect(BACKEND, SIGNAL(ProcessStarting()), this, SLOT(ProcStarting()) );
+ connect(BACKEND, SIGNAL(ProcessFinished(bool, QString)), this, SLOT(ProcFinished(bool, QString)) );
+ connect(BACKEND, SIGNAL(ProgressUpdate(int, QString)), this, SLOT(ProcUpdate(int, QString)) );
+
+ //Add a spacer between toolbar items
+ QWidget *spacer = new QWidget(this);
+ spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ ui->toolBar->insertWidget(ui->actionAdd_File, spacer);
+
+ //Connect the UI signals/slots
+ connect(ui->action_New, SIGNAL(triggered()), this, SLOT(NewArchive()) );
+ connect(ui->action_Open, SIGNAL(triggered()), this, SLOT(OpenArchive()) );
+ connect(ui->action_Quit, SIGNAL(triggered()), this, SLOT(close()) );
+ connect(ui->actionAdd_File, SIGNAL(triggered()), this, SLOT(addFiles()) );
+ connect(ui->actionRemove_File, SIGNAL(triggered()), this, SLOT(remFiles()) );
+ connect(ui->actionExtract_All, SIGNAL(triggered()), this, SLOT(extractFiles()) );
+ connect(ui->actionExtract_Sel, SIGNAL(triggered()), this, SLOT(extractSelection()) );
+ connect(ui->actionAdd_Dirs, SIGNAL(triggered()), this, SLOT(addDirs()) );
+ connect(ui->tree_contents, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(ViewFile(QTreeWidgetItem*)) );
+ ui->progressBar->setVisible(false);
+ ui->label_progress->setVisible(false);
+ ui->label_progress_icon->setVisible(false);
+ ui->actionAdd_File->setEnabled(false);
+ ui->actionRemove_File->setEnabled(false);
+ ui->actionExtract_All->setEnabled(false);
+ ui->actionAdd_Dirs->setEnabled(false);
+ loadIcons();
+ ui->tree_contents->setHeaderLabels( QStringList() << tr("File") << tr("MimeType") << tr("Size")+" " );
+}
+
+MainUI::~MainUI(){
+
+}
+
+void MainUI::LoadArguments(QStringList args){
+ for(int i=0; i<args.length(); i++){
+ if(QFile::exists(args[i])){
+ ui->label_progress->setText(tr("Opening Archive..."));
+ BACKEND->loadFile(args[i]);
+ break;
+ }
+ }
+}
+
+void MainUI::loadIcons(){
+ this->setWindowIcon( LXDG::findIcon("utilities-file-archiver","") );
+ ui->action_New->setIcon( LXDG::findIcon("file-new", "document-new") );
+ ui->action_Open->setIcon( LXDG::findIcon("file-open","document-open") );
+ ui->action_Quit->setIcon( LXDG::findIcon("application-exit", "dialog-close") );
+ ui->actionAdd_File->setIcon( LXDG::findIcon("archive-insert", "") );
+ ui->actionAdd_Dirs->setIcon( LXDG::findIcon("archive-insert-directory","") );
+ ui->actionRemove_File->setIcon( LXDG::findIcon("archive-remove","") );
+ ui->actionExtract_All->setIcon( LXDG::findIcon("archive-extract","") );
+ ui->actionExtract_Sel->setIcon( LXDG::findIcon("archive-extract","") );
+}
+
+//===================
+// PRIVATE
+//===================
+QTreeWidgetItem* MainUI::findItem(QString path, QTreeWidgetItem *start){
+ if(start==0){
+ for(int i=0; i<ui->tree_contents->topLevelItemCount(); i++){
+ if(ui->tree_contents->topLevelItem(i)->whatsThis(0) == path){ return ui->tree_contents->topLevelItem(i); }
+ else if(path.startsWith(ui->tree_contents->topLevelItem(i)->whatsThis(0)+"/")){ return findItem(path, ui->tree_contents->topLevelItem(i)); }
+ }
+ }else{
+ for(int i=0; i<start->childCount(); i++){
+ if(start->child(i)->whatsThis(0) == path){ return start->child(i); }
+ else if(path.startsWith(start->child(i)->whatsThis(0)+"/")){ return findItem(path, start->child(i)); }
+ }
+ }
+ //qDebug() << "Could not find item:" << path;
+ return 0; //nothing found
+}
+
+bool MainUI::cleanItems(QStringList list, QTreeWidgetItem *start){
+ bool changed = false;
+ if(start==0){
+ for(int i=0; i<ui->tree_contents->topLevelItemCount(); i++){
+ changed = changed || cleanItems(list, ui->tree_contents->topLevelItem(i));
+ if(!list.contains(ui->tree_contents->topLevelItem(i)->whatsThis(0)) ){
+ delete ui->tree_contents->topLevelItem(i);
+ changed = true;
+ }
+ }
+ }else{
+ for(int i=0; i<start->childCount(); i++){
+ changed = changed || cleanItems(list, start->child(i));
+ if(!list.contains(start->child(i)->whatsThis(0)) ){
+ delete start->child(i);
+ changed = true;
+ }
+ }
+ }
+ return changed;
+}
+
+//Functions for setting the valid file extensions ("tar" limitations)
+QString MainUI::CreateFileTypes(){
+ QStringList types;
+ types << QString(tr("All Types %1")).arg("(*.tar.gz *.tar.xz *.tar.bz *.tar.bz2 *.tar.lzma *.tar *.zip *.tgz *.txz *.tbz *.tbz2 *.tlz *.cpio *.pax *.ar *.shar *.7z)");
+ types << tr("Uncompressed Archive (*.tar)");
+ types << tr("GZip Compressed Archive (*.tar.gz *.tgz)");
+ types << tr("BZip Compressed Archive (*.tar.bz *.tbz)");
+ types << tr("BZip2 Compressed Archive (*.tar.bz2 *.tbz2)");
+ types << tr("LMZA Compressed Archive (*.tar.lzma *.tlz)");
+ types << tr("XZ Compressed Archive (*.tar.xz *.txz)");
+ types << tr("CPIO Archive (*.cpio)");
+ types << tr("PAX Archive (*.pax)");
+ types << tr("AR Archive (*.ar)");
+ types << tr("SHAR Archive (*.shar)");
+ types << tr("Zip Archive (*.zip)");
+ types << tr("7-Zip Archive (*.7z)");
+ return types.join(";;");
+}
+
+QString MainUI::OpenFileTypes(){
+ QStringList types;
+ types << QString(tr("All Types %1")).arg("(*.tar.gz *.tar.xz *.tar.bz *.tar.bz2 *.tar.lzma *.tar *.zip *.tgz *.txz *.tbz *.tbz2 *.tlz *.cpio *.pax *.ar *.shar *.7z *.iso *.xar *.jar *.rpm)");
+ types << tr("Uncompressed Archive (*.tar)");
+ types << tr("GZip Compressed Archive (*.tar.gz *.tgz)");
+ types << tr("BZip Compressed Archive (*.tar.bz *.tbz)");
+ types << tr("BZip2 Compressed Archive (*.tar.bz2 *.tbz2)");
+ types << tr("XZ Compressed Archive (*.tar.xz *.txz)");
+ types << tr("LMZA Compressed Archive (*.tar.lzma *.tlz)");
+ types << tr("CPIO Archive (*.cpio)");
+ types << tr("PAX Archive (*.pax)");
+ types << tr("AR Archive (*.ar)");
+ types << tr("SHAR Archive (*.shar)");
+ types << tr("Zip Archive (*.zip)");
+ types << tr("7-Zip Archive (*.7z)");
+ types << tr("READ-ONLY: ISO image (*.iso)");
+ types << tr("READ-ONLY: XAR archive (*.xar)");
+ types << tr("READ-ONLY: Java archive (*.jar)");
+ types << tr("READ-ONLY: RedHat Package (*.rpm)");
+ return types.join(";;");
+}
+
+//===================
+// PRIVATE SLOTS
+//===================
+void MainUI::NewArchive(){
+ QString file = QFileDialog::getSaveFileName(this, tr("Create Archive"), QDir::homePath(), CreateFileTypes() );
+ if(file.isEmpty()){ return; }
+ if(QFile::exists(file)){
+ if( !QFile::remove(file) ){ QMessageBox::warning(this, tr("Error"), QString(tr("Could not overwrite file:"))+"\n"+file); }
+ }
+ ui->label_progress->setText(""); //just clear it (this action is instant)
+ BACKEND->loadFile(file);
+}
+
+void MainUI::OpenArchive(){
+ QString file = QFileDialog::getOpenFileName(this, tr("Open Archive"), QDir::homePath(), OpenFileTypes() );
+ if(file.isEmpty()){ return; }
+ ui->label_progress->setText(tr("Opening Archive..."));
+ BACKEND->loadFile(file);
+}
+
+void MainUI::addFiles(){
+ QStringList files = QFileDialog::getOpenFileNames(this, tr("Add to Archive"), QDir::homePath() );
+ if(files.isEmpty()){ return; }
+ ui->label_progress->setText(tr("Adding Items..."));
+ BACKEND->startAdd(files);
+}
+
+void MainUI::addDirs(){
+ QString dirs = QFileDialog::getExistingDirectory(this, tr("Add to Archive"), QDir::homePath() );
+ if(dirs.isEmpty()){ return; }
+ ui->label_progress->setText(tr("Adding Items..."));
+ BACKEND->startAdd(QStringList() << dirs);
+}
+
+void MainUI::remFiles(){
+ QList<QTreeWidgetItem*> sel = ui->tree_contents->selectedItems();
+ QStringList items;
+ for(int i=0; i<sel.length(); i++){
+ items << sel[i]->whatsThis(0);
+ }
+ items.removeDuplicates();
+ ui->label_progress->setText(tr("Removing Items..."));
+ BACKEND->startRemove(items);
+}
+
+void MainUI::extractFiles(){
+ QString dir = QFileDialog::getExistingDirectory(this, tr("Extract Into Directory"), QDir::homePath() );
+ if(dir.isEmpty()){ return; }
+ ui->label_progress->setText(tr("Extracting..."));
+ BACKEND->startExtract(dir, true);
+}
+
+void MainUI::extractSelection(){
+ if(ui->tree_contents->currentItem()==0){ return; } //nothing selected
+ QList<QTreeWidgetItem*> sel = ui->tree_contents->selectedItems();
+ if(sel.isEmpty()){ sel << ui->tree_contents->currentItem(); }
+ QStringList selList;
+ for(int i=0; i<sel.length(); i++){ selList << sel[i]->whatsThis(0); }
+ selList.removeDuplicates();
+ QString dir = QFileDialog::getExistingDirectory(this, tr("Extract Into Directory"), QDir::homePath() );
+ if(dir.isEmpty()){ return; }
+ ui->label_progress->setText(tr("Extracting..."));
+ BACKEND->startExtract(dir, true, selList);
+}
+
+void MainUI::ViewFile(QTreeWidgetItem *it){
+ if(it->childCount()>0){ return; } //directory - not viewable
+ ui->label_progress->setText(tr("Extracting..."));
+ BACKEND->startViewFile(it->whatsThis(0));
+}
+
+void MainUI::UpdateTree(){
+ this->setEnabled(false);
+ ui->tree_contents->setHeaderLabels( QStringList() << tr("File") << tr("MimeType") << tr("Size")+" " );
+ QStringList files = BACKEND->heirarchy();
+ files.sort();
+ //Remove any entries for file no longer in the archive
+ bool changed = cleanItems(files);
+ //qDebug() << "Found Files:" << files;
+ for(int i=0; i<files.length(); i++){
+ if(0 != findItem(files[i]) ){ continue; } //already in the tree widget
+ QString mime = LXDG::findAppMimeForFile(files[i].section("/",-1), false); //first match only
+ QTreeWidgetItem *it = new QTreeWidgetItem();
+ it->setText(0, files[i].section("/",-1) );
+ if(!BACKEND->isLink(files[i])){
+ it->setText(1, LXDG::findAppMimeForFile(files[i].section("/",-1), false) );
+ it->setText(2, LUtils::BytesToDisplaySize( BACKEND->size(files[i])) );
+ }else{
+ it->setText(1, QString(tr("Link To: %1")).arg(BACKEND->linkTo(files[i]) ) );
+ }
+ it->setWhatsThis(0, files[i]);
+ if(BACKEND->isDir(files[i])){
+ it->setIcon(0, LXDG::findIcon("folder",""));
+ it->setText(1,""); //clear the mimetype
+ }else if(BACKEND->isLink(files[i])){
+ it->setIcon(0, LXDG::findIcon("emblem-symbolic-link","") );
+ }else{
+ it->setIcon(0, LXDG::findMimeIcon(files[i].section("/",-1)) );
+ }
+ //Now find which item to add this too
+ if(files[i].contains("/")){
+ QTreeWidgetItem *parent = findItem(files[i].section("/",0,-2));
+ QList<QTreeWidgetItem*> list = ui->tree_contents->findItems(files[i].section("/",-3,-2), Qt::MatchExactly, 0);
+ if(parent==0){ ui->tree_contents->addTopLevelItem(it); }
+ else{ parent->addChild(it); }
+ }else{
+ ui->tree_contents->addTopLevelItem(it);
+ QApplication::processEvents();
+ }
+ changed = true;
+ }
+
+ if(changed){
+ int wid = ui->tree_contents->fontMetrics().width("W")*5;
+ ui->tree_contents->setColumnWidth(2, wid);
+ for(int i=1; i<2; i++){ui->tree_contents->resizeColumnToContents(i); QApplication::processEvents(); wid+= ui->tree_contents->columnWidth(i); }
+ //qDebug() << "Set column 0 width:" << wid << ui->tree_contents->viewport()->width();
+ ui->tree_contents->setColumnWidth(0, ui->tree_contents->viewport()->width()-wid);
+ }
+ ui->tree_contents->sortItems(0, Qt::AscendingOrder); //sort by name
+ ui->tree_contents->sortItems(1,Qt::AscendingOrder); //sort by mimetype (put dirs first - still organized by name)
+
+ this->setEnabled(true);
+ ui->tree_contents->setEnabled(true);
+}
+
+//Backend Handling
+void MainUI::ProcStarting(){
+ ui->progressBar->setRange(0,0);
+ ui->progressBar->setValue(0);
+ ui->progressBar->setVisible(true);
+ ui->label_progress->setVisible(!ui->label_progress->text().isEmpty());
+ ui->label_progress_icon->setVisible(false);
+ ui->tree_contents->setEnabled(false);
+ ui->label_archive->setText(BACKEND->currentFile());
+}
+
+void MainUI::ProcFinished(bool success, QString msg){
+ UpdateTree();
+ ui->progressBar->setRange(0,0);
+ ui->progressBar->setValue(0);
+ ui->progressBar->setVisible(false);
+ ui->label_progress->setText(msg);
+ ui->label_progress->setVisible(!msg.isEmpty());
+ ui->label_progress_icon->setVisible(!msg.isEmpty());
+ if(success){ ui->label_progress_icon->setPixmap( LXDG::findIcon("task-complete","").pixmap(32,32) );}
+ else{ ui->label_progress_icon->setPixmap( LXDG::findIcon("task-attention","").pixmap(32,32) );}
+ if(ui->label_archive->text()!=BACKEND->currentFile()){
+ ui->label_archive->setText(BACKEND->currentFile());
+ this->setWindowTitle(BACKEND->currentFile().section("/",-1));
+ ui->tree_contents->clear();
+ }
+ QFileInfo info(BACKEND->currentFile());
+ bool canmodify = info.isWritable();
+ if(!info.exists()){ canmodify = QFileInfo(BACKEND->currentFile().section("/",0,-2)).isWritable(); }
+ canmodify = canmodify && BACKEND->canModify(); //also include the file type limitations
+ ui->actionAdd_File->setEnabled(canmodify);
+ ui->actionRemove_File->setEnabled(canmodify && info.exists());
+ ui->actionExtract_All->setEnabled(info.exists());
+ ui->actionAdd_Dirs->setEnabled(canmodify);
+}
+
+void MainUI::ProcUpdate(int percent, QString txt){
+ ui->progressBar->setMaximum( percent<0 ? 0 : 100 );
+ ui->progressBar->setValue(percent);
+ if(!txt.isEmpty()){ ui->label_progress->setText(txt); }
+}
bgstack15