Commit 15beff87 authored by Philipp Erhardt's avatar Philipp Erhardt
Browse files

Show graphical warning on error; File Open dialog

From now on katarakt doesn't simply quit. It stays open if there was an
error and it prompts the user for a password if required.
You should configure your icon theme for nice eye-candy :).
Additionally, press o to pick a new file to display.
parent c1070e23
......@@ -24,8 +24,13 @@ CFG::CFG() :
defaults["thumbnail_size"] = 32;
// search options
defaults["rect_expansion"] = 2;
// viewer options
defaults["icon_theme"] = "";
settings.endGroup();
tmp_values["start_page"] = 0;
tmp_values["fullscreen"] = false;
settings.beginGroup("keys");
// canvas keys
keys["set_presentation_layout"] = QStringList() << "1";
......@@ -61,6 +66,7 @@ CFG::CFG() :
keys["toggle_fullscreen"] = QStringList() << "F";
keys["close_search"] = QStringList() << "Esc";
keys["reload"] = QStringList() << "R";
keys["open"] = QStringList() << "O";
settings.endGroup();
}
......@@ -84,9 +90,6 @@ void CFG::set_defaults() {
}
settings.endGroup();
tmp_values["start_page"] = 0;
tmp_values["fullscreen"] = false;
settings.beginGroup("Keys");
QHashIterator<QString,QStringList> i2(keys);
while (i2.hasNext()) {
......
......@@ -164,6 +164,7 @@ void Worker::run() {
//==[ ResourceManager ]========================================================
ResourceManager::ResourceManager(QString file) :
doc(NULL),
center_page(0),
rotation(0) {
// load config options
......@@ -171,22 +172,27 @@ ResourceManager::ResourceManager(QString file) :
smooth_downscaling = config->get_value("smooth_downscaling").toBool();
thumbnail_size = config->get_value("thumbnail_size").toInt();
initialize(file);
initialize(file, QByteArray());
}
void ResourceManager::initialize(QString file) {
void ResourceManager::initialize(QString &file, const QByteArray &password) {
page_count = 0;
worker = NULL;
doc = Poppler::Document::load(file);
k_page = NULL;
doc = Poppler::Document::load(file, QByteArray(), password);
worker = new Worker();
worker->setResManager(this);
worker->start();
if (doc == NULL) {
// poppler already prints a debug message
// cerr << "failed to open file" << endl;
return;
}
if (doc->isLocked()) {
cerr << "missing password" << endl;
delete doc;
doc = NULL;
// poppler already prints a debug message
// cerr << "missing password" << endl;
return;
}
doc->setRenderHint(Poppler::Document::Antialiasing, true);
......@@ -195,6 +201,7 @@ void ResourceManager::initialize(QString file) {
// if (POPPLER_CHECK_VERSION(0, 18, 0)) { // TODO is there a working macro?
doc->setRenderHint(Poppler::Document::TextSlightHinting, true);
// }
// TODO there are more hints now
page_count = doc->numPages();
......@@ -209,10 +216,6 @@ void ResourceManager::initialize(QString file) {
k_page[i].height = p->pageSizeF().height();
delete p;
}
worker = new Worker();
worker->setResManager(this);
worker->start();
}
ResourceManager::~ResourceManager() {
......@@ -228,23 +231,27 @@ void ResourceManager::shutdown() {
garbageMutex.unlock();
requests.clear();
requestSemaphore.acquire(requestSemaphore.available());
if (doc == NULL) {
return;
}
delete doc;
delete[] k_page;
delete worker;
}
void ResourceManager::load(QString file) {
void ResourceManager::load(QString &file, const QByteArray &password) {
shutdown();
initialize(file);
initialize(file, password);
}
bool ResourceManager::is_valid() const {
return (doc != NULL);
}
bool ResourceManager::is_locked() const {
if (doc == NULL) {
return false;
}
return doc->isLocked();
}
void ResourceManager::connect_canvas(Canvas *c) const {
worker->connect_signal(c);
}
......
......@@ -64,10 +64,11 @@ public:
ResourceManager(QString file);
~ResourceManager();
void load(QString file);
void load(QString &file, const QByteArray &password);
// document opened correctly?
bool is_valid() const;
bool is_locked() const;
// page (meta)data
const KPage *get_page(int page, int newWidth);
......@@ -89,7 +90,7 @@ private:
void enqueue(int page, int width);
bool render(int offset);
void initialize(QString file);
void initialize(QString &file, const QByteArray &password);
void join_threads();
void shutdown();
......
......@@ -151,18 +151,21 @@ SearchBar::SearchBar(QString file, Viewer *v, QWidget *parent) :
layout->addWidget(progress);
setLayout(layout);
initialize(file);
initialize(file, QByteArray());
}
void SearchBar::initialize(QString file) {
void SearchBar::initialize(QString &file, const QByteArray &password) {
worker = NULL;
doc = Poppler::Document::load(file);
doc = Poppler::Document::load(file, QByteArray(), password);
if (doc == NULL) {
// poppler already prints a debug message
return;
}
if (doc->isLocked()) {
cerr << "missing password" << endl;
// poppler already prints a debug message
// cerr << "missing password" << endl;
delete doc;
doc = NULL;
return;
......@@ -194,9 +197,9 @@ void SearchBar::shutdown() {
delete worker;
}
void SearchBar::load(QString file) {
void SearchBar::load(QString &file, const QByteArray &password) {
shutdown();
initialize(file);
initialize(file, password);
// clear old search results if initialisation failed
if (!is_valid()) {
......
......@@ -51,7 +51,7 @@ public:
SearchBar(QString file, Viewer *v, QWidget *parent = 0);
~SearchBar();
void load(QString file);
void load(QString &file, const QByteArray &password);
bool is_valid() const;
void connect_canvas(Canvas *c) const;
void focus();
......@@ -70,7 +70,7 @@ private slots:
void set_text();
private:
void initialize(QString file);
void initialize(QString &file, const QByteArray &password);
void join_threads();
void shutdown();
......
......@@ -12,6 +12,7 @@ search_padding=0.2
smooth_downscaling=true
thumbnail_size=32
rect_expansion=2
icon_theme=
[Keys]
set_presentation_layout=1
......
#include <iostream>
#include <QFileInfo>
#include <QAction>
#include <QFileDialog>
#include <csignal>
#include <cerrno>
#include <unistd.h>
......@@ -32,8 +33,8 @@ Viewer::Viewer(QString _file, QWidget *parent) :
valid(true) {
res = new ResourceManager(file);
if (!res->is_valid()) {
valid = false;
return;
// valid = false;
// return;
}
canvas = new Canvas(this, this);
......@@ -45,8 +46,8 @@ Viewer::Viewer(QString _file, QWidget *parent) :
search_bar = new SearchBar(file, this, this);
if (!search_bar->is_valid()) {
valid = false;
return;
// valid = false;
// return;
}
search_bar->connect_canvas(canvas);
......@@ -75,10 +76,35 @@ Viewer::Viewer(QString _file, QWidget *parent) :
add_action("toggle_fullscreen", SLOT(toggle_fullscreen()));
add_action("close_search", SLOT(close_search()));
add_action("reload", SLOT(reload()));
add_action("open", SLOT(open()));
layout = new QVBoxLayout();
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
// initialize info bar
QIcon::setThemeName(CFG::get_instance()->get_value("icon_theme").toString());
info_label_icon.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
info_password.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
info_widget.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
info_label_text.setWordWrap(true);
info_label_text.setTextFormat(Qt::PlainText);
info_password.setEchoMode(QLineEdit::Password);
info_layout.addWidget(&info_label_icon);
info_layout.addWidget(&info_label_text);
info_layout.addWidget(&info_password);
info_widget.setLayout(&info_layout);
layout->addWidget(&info_widget);
connect(&info_password, SIGNAL(returnPressed()), this, SLOT(reload()),
Qt::UniqueConnection);
update_info_widget();
layout->addWidget(canvas);
layout->addWidget(search_bar);
setLayout(layout);
......@@ -105,7 +131,9 @@ Viewer::Viewer(QString _file, QWidget *parent) :
setMinimumSize(50, 50);
resize(500, 500);
show();
search_bar->hide();
info_password.setFocus(Qt::OtherFocusReason); // only works if shown
// apply start options
if (CFG::get_instance()->get_tmp_value("fullscreen").toBool()) {
......@@ -140,17 +168,53 @@ void Viewer::reload() {
cerr << "reloading file " << file.toUtf8().constData() << endl;
#endif
res->load(file);
// do not connect non-existing worker to canvas
if (res->is_valid()) {
res->connect_canvas(canvas);
}
res->load(file, info_password.text().toLatin1());
res->connect_canvas(canvas);
search_bar->load(file);
search_bar->load(file, info_password.text().toLatin1());
update_info_widget();
canvas->reload();
}
void Viewer::open() {
QString new_file = QFileDialog::getOpenFileName(this, "Open File", "", "PDF Files (*.pdf)");
if (!new_file.isNull()) {
file = new_file;
reload();
}
}
void Viewer::update_info_widget() {
if (!res->is_valid() || !search_bar->is_valid()) {
QIcon icon;
if (!res->is_locked()) {
icon = QIcon::fromTheme("dialog-error");
info_label_text.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
info_label_text.setText(
QString("Failed to open file '") + file + QString("'."));
info_password.hide();
} else {
icon = QIcon::fromTheme("dialog-password");
info_label_text.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
info_label_text.setText("password:");
info_password.show();
info_password.setFocus(Qt::OtherFocusReason);
info_password.clear();
}
info_label_icon.setPixmap(icon.pixmap(32, 32));
info_widget.show();
} else {
info_widget.hide();
}
}
ResourceManager *Viewer::get_res() const {
return res;
}
......
......@@ -5,6 +5,8 @@
#include <QVBoxLayout>
#include <QKeySequence>
#include <QSocketNotifier>
#include <QLabel>
#include <QLineEdit>
class ResourceManager;
......@@ -22,7 +24,6 @@ public:
bool is_valid() const;
void focus_search();
ResourceManager *get_res() const;
Canvas *get_canvas() const;
......@@ -33,8 +34,10 @@ public slots:
void toggle_fullscreen();
void close_search();
void reload();
void open();
private:
void update_info_widget();
void add_action(const char *action, const char *slot);
QString file;
......@@ -43,6 +46,13 @@ private:
SearchBar *search_bar;
QVBoxLayout *layout;
// info bar
QWidget info_widget;
QHBoxLayout info_layout;
QLabel info_label_icon;
QLabel info_label_text;
QLineEdit info_password;
// signal handling
static void signal_handler(int unused);
static int sig_fd[2];
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment