예제 #1
0
Viewer::Viewer(const QString &file, QWidget *parent) :
		QWidget(parent),
		res(NULL),
		splitter(NULL),
		toc(NULL),
		canvas(NULL),
		search_bar(NULL),
		layout(NULL),
		sig_notifier(NULL),
		beamer(NULL),
		valid(true) {
	res = new ResourceManager(file, this);
	if (!res->is_valid()) {
		if (CFG::get_instance()->get_most_current_value("Settings/quit_on_init_fail").toBool()) {
			valid = false;
			return;
		}
	}

	search_bar = new SearchBar(file, this, this);
	if (!search_bar->is_valid()) {
		if (CFG::get_instance()->get_most_current_value("Settings/quit_on_init_fail").toBool()) {
			valid = false;
			return;
		}
	}

	// setup signal handling
	if (socketpair(AF_UNIX, SOCK_STREAM, 0, sig_fd) == -1) {
		cerr << "socketpair: " << strerror(errno) << endl;
		valid = false;
		return;
	}
	sig_notifier = new QSocketNotifier(sig_fd[1], QSocketNotifier::Read, this);
	connect(sig_notifier, SIGNAL(activated(int)), this, SLOT(signal_slot()),
			Qt::UniqueConnection);

	struct sigaction usr;
	usr.sa_handler = Viewer::signal_handler;
	sigemptyset(&usr.sa_mask);
	usr.sa_flags = SA_RESTART;

	if (sigaction(SIGUSR1, &usr, 0) > 0) {
		cerr << "sigaction: " << strerror(errno) << endl;
		valid = false;
		return;
	}

	setup_keys(this);
	beamer = new BeamerWindow(this);
	setup_keys(beamer);

	splitter = new Splitter(this);
	toc = new Toc(this, splitter);

	canvas = new Canvas(this, splitter); // beamer must already exist
	if (!canvas->is_valid()) {
		valid = false;
		return;
	}
	res->connect_canvas();
	canvas->update_page_overlay(); // set initial position

	splitter->addWidget(toc);
	splitter->addWidget(canvas);
	splitter->setSizes(QList<int>() << (width() / 4) << (width() * 3 / 4)); // TODO config option

	toc->hide();

	// load config options
	CFG *config = CFG::get_instance();
	smooth_scroll_delta = config->get_value("Settings/smooth_scroll_delta").toInt();
	screen_scroll_factor = config->get_value("Settings/screen_scroll_factor").toFloat();

	layout = new QVBoxLayout();
	layout->setContentsMargins(0, 0, 0, 0);
	layout->setSpacing(0);

	// initialize info bar
	QIcon::setThemeName(CFG::get_instance()->get_value("Settings/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();

	presenter_progress.setMinimum(1);
 	presenter_progress.setMaximum(res->get_page_count());
 	presenter_progress.setValue(canvas->get_layout()->get_page() + 1);
//	presenter_progress.setFormat("%v/%m");
 	presenter_progress.setTextVisible(true);

	layout->addWidget(splitter);
	layout->addWidget(&presenter_progress);
	layout->addWidget(search_bar);
	setLayout(layout);

	QFileInfo info(res->get_file());
	setWindowTitle(QString::fromUtf8("%1 \u2014 katarakt").arg(info.fileName()));
	setMinimumSize(50, 50);
	resize(500, 500);

	search_bar->hide();
	info_password.setFocus(Qt::OtherFocusReason); // only works if shown

	// apply start options
	if (res->is_valid()) {
		canvas->get_layout()->scroll_page(config->get_tmp_value("start_page").toInt(), false);
	}
	if (CFG::get_instance()->get_tmp_value("fullscreen").toBool()) {
		toggle_fullscreen();
	}

	// enable transparency, but only in the right places
	setAttribute(Qt::WA_TranslucentBackground);
	presenter_progress.setAutoFillBackground(true);
	search_bar->setAutoFillBackground(true);
	info_widget.setAutoFillBackground(true);
	toc->setAutoFillBackground(true);
	// the splitter handle has to be opaque, canvas has to be transparent
	// problem: either both are transparent or none is
	// these functions don't help, the splitter handle is still transparent (depending on theme)
//	splitter->handle(0)->setAttribute(Qt::WA_TranslucentBackground, false);
//	splitter->handle(0)->setBackgroundRole(QPalette::Window);
//	splitter->handle(0)->setAutoFillBackground(true);
}
예제 #2
0
Canvas::Canvas(Viewer *v, QWidget *parent) :
		QWidget(parent),
		viewer(v),
		triple_click_possible(false),
		valid(true) {
	setFocusPolicy(Qt::StrongFocus);

	// load config options
	CFG *config = CFG::get_instance();

	{
		bool ok;
		unsigned int color = config->get_value("Settings/background_color").toString().toUInt(&ok, 16);
		if (ok) {
			background.setRgba(color);
		} else {
			cerr << "failed to parse background_color" << endl;
		}
	}
	{
		bool ok;
		unsigned int color = config->get_value("Settings/background_color_fullscreen").toString().toUInt(&ok, 16);
		if (ok) {
			background_fullscreen.setRgba(color);
		} else {
			cerr << "failed to parse background_color_fullscreen" << endl;
		}
	}
	mouse_wheel_factor = config->get_value("Settings/mouse_wheel_factor").toInt();

	switch (config->get_value("Settings/click_link_button").toInt()) {
		case 1: click_link_button = Qt::LeftButton; break;
		case 2: click_link_button = Qt::RightButton; break;
		case 3: click_link_button = Qt::MidButton; break;
		case 4: click_link_button = Qt::XButton1; break;
		case 5: click_link_button = Qt::XButton2; break;
		default: click_link_button = Qt::NoButton;
	}

	switch (config->get_value("Settings/drag_view_button").toInt()) {
		case 1: drag_view_button = Qt::LeftButton; break;
		case 2: drag_view_button = Qt::RightButton; break;
		case 3: drag_view_button = Qt::MidButton; break;
		case 4: drag_view_button = Qt::XButton1; break;
		case 5: drag_view_button = Qt::XButton2; break;
		default: drag_view_button = Qt::NoButton;
	}

	switch (config->get_value("Settings/select_text_button").toInt()) {
		case 1: select_text_button = Qt::LeftButton; break;
		case 2: select_text_button = Qt::RightButton; break;
		case 3: select_text_button = Qt::MidButton; break;
		case 4: select_text_button = Qt::XButton1; break;
		case 5: select_text_button = Qt::XButton2; break;
		default: select_text_button = Qt::NoButton;
	}

	single_layout = new SingleLayout(viewer, 0);
	grid_layout = new GridLayout(viewer, 0);
	presenter_layout = new PresenterLayout(viewer, 1);

	QString default_layout = config->get_value("Settings/default_layout").toString();
	if (default_layout == "grid") {
		cur_layout = grid_layout;
	} else if (default_layout == "presenter") {
		cur_layout = presenter_layout;
	} else { // "single" and everything else
		cur_layout = single_layout;
	}

	setup_keys(this);

	if (drag_view_button == Qt::LeftButton) {
		setCursor(Qt::OpenHandCursor);
	} else {
		setCursor(Qt::IBeamCursor);
	}

	// prints the string representation of a key
//	cerr << QKeySequence(Qt::Key_Equal).toString().toUtf8().constData() << endl;

	goto_line = new GotoLine(viewer->get_res()->get_page_count(), this);
	goto_line->move(0, height() - goto_line->height()); // TODO goto_line->height() reports the wrong size
	goto_line->hide();
	connect(goto_line, SIGNAL(returnPressed()), this, SLOT(goto_page()), Qt::UniqueConnection);

	page_overlay = new QLabel(this);
	page_overlay->setMargin(1);
	page_overlay->setAutoFillBackground(true);
	page_overlay->show();

	// setup beamer
	BeamerWindow *beamer = viewer->get_beamer();
	setup_keys(beamer);
	if (cur_layout == presenter_layout) {
		beamer->show();
		viewer->show_progress(true);
	} else {
		beamer->hide();
		viewer->show_progress(false);
	}
}