summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArno <am@disconnect.de>2014-07-08 08:13:30 +0200
committerArno <am@disconnect.de>2014-07-08 08:13:30 +0200
commitf76b42f192a82f777cf77f3eecfab9ca7e31e396 (patch)
tree40b15701fc3a5356e044de3ad6ca8274b0d592de
parentca9cdb39a8b3eafa8106fed84cce013f18b0a114 (diff)
downloadSheMov-f76b42f192a82f777cf77f3eecfab9ca7e31e396.tar.gz
SheMov-f76b42f192a82f777cf77f3eecfab9ca7e31e396.tar.bz2
SheMov-f76b42f192a82f777cf77f3eecfab9ca7e31e396.zip
Display unpack output in Dialog
This was a difficult one. Got lost in the Semantics of QThread once again, but just 2 days later it works :)
-rw-r--r--filesystemwidget.cpp32
-rw-r--r--filesystemwidget.h6
-rw-r--r--mappingtreewidget.cpp2
-rw-r--r--shemov.pro6
-rw-r--r--smdialog.cpp89
-rw-r--r--smdialog.h30
-rw-r--r--unpacker.cpp44
-rw-r--r--unpacker.h38
8 files changed, 226 insertions, 21 deletions
diff --git a/filesystemwidget.cpp b/filesystemwidget.cpp
index 983a40d..566919b 100644
--- a/filesystemwidget.cpp
+++ b/filesystemwidget.cpp
@@ -32,6 +32,7 @@
#include "smglobals.h"
#include "delegates.h"
#include "smdirmodel.h"
+#include "smdialog.h"
FilesystemWidget::FilesystemWidget(QWidget *parent) : QWidget(parent), mClipboardMode(None) {
mModel = new FileSystemModel(this);
@@ -78,6 +79,8 @@ FilesystemWidget::FilesystemWidget(QWidget *parent) : QWidget(parent), mClipboar
connect(mFileModel, SIGNAL(modelReset()), mFileView, SLOT(restoreSelection()));
mPicViewer = SmGlobals::instance()->pictureViewer();
+ mUnpackDlg = new UnpackDialog(this);
+ connect(mUnpackDlg, SIGNAL(workFinished()), this, SLOT(selectUnpackDir()));
QWidget *fileWidget = new QWidget;
mIconDirSplitter = new QSplitter(this);
@@ -478,29 +481,24 @@ void FilesystemWidget::preview(){
}
void FilesystemWidget::unpack(){
- QModelIndexList selectedIdxs = mFileView->selectionModel()->selectedIndexes();
+ QModelIndexList selectedIdxs = mFileView->selectionModel()->selectedRows();
+ mUnpackDlg->clearOutput();
+ mUnpackDlg->setCloseEnabled(false);
+ mUnpackDlg->show();
foreach(QModelIndex idx, selectedIdxs){
- if(!idx.column() == SmDirModel::NameRole){
- return;
- }
QString mimeType = idx.data(SmDirModel::TypeRole).toString();
if(mimeType == "application/zip" || mimeType == "application/x-rar"){
- QString prg = "/usr/bin/7z";
- QString archive = idx.data(SmDirModel::NameRole).toString();
QStringList args = QStringList() << "-o/home/am/movs/pics/7z" << "-y" << "e" << idx.data(SmDirModel::FullPathRole).toString();
- QString msg = QString(tr("Unpacking %1")).arg(archive);
- emit statusbarMessage(msg);
- int retval = QProcess::execute(prg, args);
- if(retval == 0){
- emit statusbarMessage(tr("Unpacking: success!"));
- }else{
- emit statusbarMessage(tr("Unpacking: failed!"));
- }
+ mUnpackDlg->appendCommand(args);
}
}
- QModelIndex lastIdx = mModel->index("/home/am/movs/pics/7z");
- if(lastIdx.isValid()){
- mDirView->selectionModel()->setCurrentIndex(mDirProxy->mapFromSource(lastIdx), QItemSelectionModel::ClearAndSelect);
+ mUnpackDlg->doIt();
+}
+
+void FilesystemWidget::selectUnpackDir(){
+ QModelIndex unpackDirIdx = mModel->index("/home/am/movs/pics/7z");
+ if(unpackDirIdx.isValid()){
+ mDirView->selectionModel()->setCurrentIndex(mDirProxy->mapFromSource(unpackDirIdx), QItemSelectionModel::ClearAndSelect);
}
}
diff --git a/filesystemwidget.h b/filesystemwidget.h
index e4b26e8..82c3b04 100644
--- a/filesystemwidget.h
+++ b/filesystemwidget.h
@@ -12,6 +12,8 @@
#include <QFileSystemModel>
#include <QSqlDatabase>
#include <QDateTime>
+#include <QMutex>
+#include <QThread>
class SmTreeView;
class FilesystemDirProxy;
@@ -24,6 +26,8 @@ class SheMovIconProvider;
class SmDirModel;
class QToolBar;
class QSplitter;
+class UnpackDialog;
+class Unpacker;
class FilesystemWidget : public QWidget {
Q_OBJECT
@@ -64,6 +68,7 @@ class FilesystemWidget : public QWidget {
void setWindowTitle();
void preview();
void unpack();
+ void selectUnpackDir();
private slots:
void dirExpanded(const QModelIndex &idx);
@@ -96,6 +101,7 @@ class FilesystemWidget : public QWidget {
QString mLastDir;
int mClipboardMode;
QSplitter *mIconDirSplitter;
+ UnpackDialog *mUnpackDlg;
};
class FileSystemModel : public QFileSystemModel {
diff --git a/mappingtreewidget.cpp b/mappingtreewidget.cpp
index be0c5a5..26f1b53 100644
--- a/mappingtreewidget.cpp
+++ b/mappingtreewidget.cpp
@@ -329,7 +329,7 @@ void MappingEditWidget::removeMapping(){
if(sel.isEmpty()){
return;
}
- QPersistentModelIndex firstIdx = sel.first();
+ QModelIndex firstIdx = sel.first();
if(firstIdx.isValid()){
mResultModel->removeRows(firstIdx.row(), 1, firstIdx.parent());
}
diff --git a/shemov.pro b/shemov.pro
index 07c6a14..78d795c 100644
--- a/shemov.pro
+++ b/shemov.pro
@@ -43,7 +43,8 @@ SOURCES = main.cpp \
archivecontroller.cpp \
delegates.cpp \
archivebrowser.cpp \
- archivebrowsermodel.cpp
+ archivebrowsermodel.cpp \
+ unpacker.cpp
HEADERS = \
filesystemdirproxy.h \
filesystemwidget.h \
@@ -82,6 +83,7 @@ HEADERS = \
archivecontroller.h \
delegates.h \
archivebrowser.h \
- archivebrowsermodel.h
+ archivebrowsermodel.h \
+ unpacker.h
LIBS += -lmagic -lXfixes -lX11
RESOURCES = shemov.qrc
diff --git a/smdialog.cpp b/smdialog.cpp
index 645d6d6..a15c22e 100644
--- a/smdialog.cpp
+++ b/smdialog.cpp
@@ -10,10 +10,12 @@
#include <QLabel>
#include <QPushButton>
#include <QFormLayout>
-#include <QHBoxLayout>
+#include <QTextEdit>
+#include <QTextBlock>
#include "smdialog.h"
#include "helper.h"
+#include "unpacker.h"
SmDialog::SmDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f) {}
@@ -58,3 +60,88 @@ int SeriesPartsDialog::partNo() const {
void SeriesPartsDialog::setPartno(int partNo){
mPartno->setValue(partNo);
}
+
+UnpackDialog::UnpackDialog(QWidget *parent, Qt::WindowFlags f) : SmDialog(parent, f){
+ QVBoxLayout *mainLayout = new QVBoxLayout;
+ mCurrentL = new QLabel(tr("Unpacking:"));
+ mCurrentL->setMinimumWidth(400);
+ mainLayout->addWidget(mCurrentL);
+ mOutput = new QTextEdit;
+ mOutput->setMinimumHeight(400);
+ mainLayout->addWidget(mOutput);
+ QHBoxLayout *buttonLayout = new QHBoxLayout;
+ mClose = new QPushButton(tr("Close"));
+ connect(mClose, SIGNAL(clicked()), this, SLOT(hide()));
+ buttonLayout->addStretch();
+ buttonLayout->addWidget(mClose);
+ buttonLayout->addStretch();
+ mainLayout->addLayout(buttonLayout);
+ setLayout(mainLayout);
+
+ mUnpacker = new Unpacker(this);
+ connect(mUnpacker, SIGNAL(outputRead(QByteArray)), this, SLOT(addProcOutput(QByteArray)));
+ connect(mUnpacker, SIGNAL(unpackStarted(QString)), this, SLOT(newPackage(QString)));
+ //connect(mUnpacker, SIGNAL(unpackStarted(QStringList)), this, SLOT(newPackage(QStringList)));
+ connect(mUnpacker, SIGNAL(unpackDone()), this, SLOT(unpackDone()));
+}
+
+void UnpackDialog::setCurrentLabel(const QString &cur){
+ mCurrentL->setText(cur);
+}
+
+void UnpackDialog::clearOutput(){
+ mOutput->clear();
+}
+
+void UnpackDialog::setCloseEnabled(bool enabled){
+ mClose->setEnabled(enabled);
+}
+
+void UnpackDialog::addOutput(const QString &msg, const QString &prepend){
+ QTextCursor cur = mOutput->textCursor();
+ QTextBlock block = cur.block();
+ if(!block.text().isEmpty()){
+ cur.insertBlock();
+ }
+ if(!prepend.isEmpty()){
+ QTextCharFormat fmtRed;
+ fmtRed.setForeground(QBrush(Qt::red));
+ cur.setCharFormat(fmtRed);
+ cur.insertText(prepend);
+ }
+ QTextCharFormat fmtBlack;
+ fmtBlack.setForeground(QBrush(Qt::black));
+ cur.setCharFormat(fmtBlack);
+ cur.insertText(msg);
+ mOutput->ensureCursorVisible();
+}
+
+void UnpackDialog::addProcOutput(const QByteArray &data){
+ QTextCursor cur = mOutput->textCursor();
+ QTextBlock block = cur.block();
+ if(!block.text().isEmpty()){
+ cur.insertBlock();
+ }
+ QString dataStr = QString(data);
+ cur.insertText(dataStr);
+ mOutput->ensureCursorVisible();
+}
+
+void UnpackDialog::appendCommand(const QStringList &cmd){
+ mCommandQueue.append(cmd);
+}
+
+void UnpackDialog::doIt(){
+ mUnpacker->setCommands(mCommandQueue);
+ mUnpacker->start();
+}
+
+void UnpackDialog::newPackage(const QString &package){
+ setCurrentLabel(package);
+ addOutput(" ", tr("\n[NEW ARCHIVE]"));
+}
+
+void UnpackDialog::unpackDone(){
+ setCloseEnabled(true);
+ emit workFinished();
+}
diff --git a/smdialog.h b/smdialog.h
index 4b2e935..144502f 100644
--- a/smdialog.h
+++ b/smdialog.h
@@ -13,6 +13,9 @@
class QLineEdit;
class QSpinBox;
class QPushButton;
+class QLabel;
+class QTextEdit;
+class Unpacker;
class SmDialog : public QDialog {
Q_OBJECT
@@ -40,4 +43,31 @@ class SeriesPartsDialog : public SmDialog {
};
+class UnpackDialog : public SmDialog {
+ Q_OBJECT
+ public:
+ explicit UnpackDialog(QWidget *parent = 0, Qt::WindowFlags f = 0);
+ void setCurrentLabel(const QString &cur);
+ void clearOutput();
+ void setCloseEnabled(bool enabled);
+
+ signals:
+ void workFinished();
+
+ public slots:
+ void addOutput(const QString &msg, const QString &prepend);
+ void addProcOutput(const QByteArray &data);
+ void appendCommand(const QStringList &cmd);
+ void doIt();
+ void newPackage(const QString &package);
+ void unpackDone();
+
+ private:
+ QLabel *mCurrentL;
+ QTextEdit *mOutput;
+ QPushButton *mClose;
+ QList<QStringList> mCommandQueue;
+ Unpacker *mUnpacker;
+};
+
#endif // SMDIALOG_H
diff --git a/unpacker.cpp b/unpacker.cpp
new file mode 100644
index 0000000..a6d9496
--- /dev/null
+++ b/unpacker.cpp
@@ -0,0 +1,44 @@
+/*
+ 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
+ 2 of the License, or (at your option) any later version.
+*/
+
+#include <QProcess>
+
+#include "unpacker.h"
+
+Unpacker::Unpacker(QObject *parent) : QThread(parent) {
+ mProgram = "/usr/bin/7z";
+}
+
+void Unpacker::setCommands(const QList<QStringList> &cmds){
+ QMutexLocker l(&mCmdMx);
+ mCommandQueue = cmds;
+}
+
+void Unpacker::run(){
+ QMutexLocker l(&mCmdMx);
+ while(!mCommandQueue.isEmpty()){
+ doUnpack();
+ }
+ emit unpackDone();
+}
+
+void Unpacker::doUnpack(){
+ QStringList job = mCommandQueue.first();
+ mCommandQueue.removeFirst();
+ QProcess unpackProc;
+ unpackProc.setProgram(mProgram);
+ unpackProc.setArguments(job);
+ unpackProc.start();
+ unpackProc.waitForReadyRead();
+ QString archiveP = job.last();
+ QString archiveN = archiveP.split("/").last();
+ QString extractMsg = QString(tr("<b>Extracting</b> %1")).arg(archiveN);
+ emit unpackStarted(extractMsg);
+ QByteArray output = unpackProc.readAllStandardOutput();
+ emit outputRead(output);
+ unpackProc.waitForFinished();
+}
diff --git a/unpacker.h b/unpacker.h
new file mode 100644
index 0000000..f53cca4
--- /dev/null
+++ b/unpacker.h
@@ -0,0 +1,38 @@
+/*
+ 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
+ 2 of the License, or (at your option) any later version.
+*/
+
+#ifndef UNPACKER_H
+#define UNPACKER_H
+
+#include <QThread>
+#include <QStringList>
+#include <QMutex>
+
+class QProcess;
+
+class Unpacker : public QThread {
+ Q_OBJECT
+ public:
+ explicit Unpacker(QObject *parent = 0);
+ void setCommands(const QList<QStringList> &cmds);
+
+ signals:
+ void unpackStarted(const QString &msg);
+ void outputRead(const QByteArray &output);
+ void unpackDone();
+
+ protected:
+ virtual void run();
+
+ private:
+ void doUnpack();
+ QList<QStringList> mCommandQueue;
+ QString mProgram;
+ QMutex mCmdMx;
+};
+
+#endif // UNPACKER_H