Skip to content
Snippets Groups Projects
Select Git revision
  • c1b26acae295034e7aab2414ba50047cc889cafe
  • master default protected
  • android-7.1.2_r28_klist
  • oreo-mr1-iot-release
  • sdk-release
  • pie-cts-dev
  • pie-cts-release
  • pie-vts-release
  • nougat-iot-release
  • pie-gsi
  • pie-platform-release
  • pie-r2-release
  • pie-r2-s1-release
  • pie-release
  • pie-dev
  • oreo-m4-s4-release
  • o-mr1-iot-preview-8
  • oreo-m2-s2-release
  • oreo-m2-s1-release
  • oreo-m6-s2-release
  • oreo-m6-s3-release
  • android-o-mr1-iot-release-1.0.4
  • android-9.0.0_r8
  • android-9.0.0_r7
  • android-9.0.0_r6
  • android-9.0.0_r5
  • android-8.1.0_r46
  • android-8.1.0_r45
  • android-n-iot-release-smart-display-r2
  • android-vts-8.1_r5
  • android-cts-8.1_r8
  • android-cts-8.0_r12
  • android-cts-7.1_r20
  • android-cts-7.0_r24
  • android-cts-6.0_r31
  • android-o-mr1-iot-release-1.0.3
  • android-cts-9.0_r1
  • android-8.1.0_r43
  • android-8.1.0_r42
  • android-n-iot-release-smart-display
  • android-p-preview-5
41 results

parser.h

Blame
  • canvas.cpp 11.67 KiB
    #include <QAction>
    #include <QStringListIterator>
    #include <QKeySequence>
    #include <QString>
    #include <QPainter>
    #include <QApplication>
    #include <QDesktopWidget>
    #include <QTimer>
    #include <QLabel>
    #include <iostream>
    #include "canvas.h"
    #include "viewer.h"
    #include "layout/layout.h"
    #include "layout/singlelayout.h"
    #include "layout/gridlayout.h"
    #include "layout/presenterlayout.h"
    #include "resourcemanager.h"
    #include "search.h"
    #include "gotoline.h"
    #include "config.h"
    #include "beamerwindow.h"
    #include "util.h"
    
    using namespace std;
    
    
    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);
    	}
    }
    
    Canvas::~Canvas() {
    	delete page_overlay;
    	delete goto_line;
    	delete single_layout;
    	delete grid_layout;
    	delete presenter_layout;
    }
    
    bool Canvas::is_valid() const {
    	return valid;
    }
    
    void Canvas::reload(bool clamp) {
    	cur_layout->rebuild(clamp);
    	goto_line->set_page_count(viewer->get_res()->get_page_count());
    	update();
    }
    
    void Canvas::setup_keys(QWidget *base) {
    	add_action(base, "Keys/goto_page", SLOT(focus_goto()), this);
    
    	add_action(base, "Keys/set_single_layout", SLOT(set_single_layout()), this);
    	add_action(base, "Keys/set_grid_layout", SLOT(set_grid_layout()), this);
    	add_action(base, "Keys/set_presenter_layout", SLOT(set_presenter_layout()), this);
    
    	add_action(base, "Keys/toggle_overlay", SLOT(toggle_overlay()), this);
    	add_action(base, "Keys/swap_selection_and_panning_buttons", SLOT(swap_selection_and_panning_buttons()), this);
    }
    
    Layout *Canvas::get_layout() const {
    	return cur_layout;
    }
    
    void Canvas::update_page_overlay() {
    	QString overlay_text = CFG::get_instance()->get_value("Settings/page_overlay_text").toString()
    		.arg(cur_layout->get_page() + 1)
    		.arg(viewer->get_res()->get_page_count());
    	page_overlay->setText(overlay_text);
    	page_overlay->adjustSize();
    	page_overlay->move(width() - page_overlay->width(), height() - page_overlay->height());
    }
    
    void Canvas::paintEvent(QPaintEvent * /*event*/) {
    #ifdef DEBUG
    	cerr << "redraw" << endl;
    #endif
    	QPainter painter(this);
    	if (viewer->isFullScreen()) {
    		painter.fillRect(rect(), background_fullscreen);
    	} else {
    		painter.fillRect(rect(), background);
    	}
    	cur_layout->render(&painter);
    }
    
    void Canvas::mousePressEvent(QMouseEvent *event) {
    	if ((click_link_button != Qt::NoButton && event->button() == click_link_button)
    			|| (drag_view_button != Qt::NoButton && event->button() == drag_view_button)) {
    		mx = event->x();
    		my = event->y();
    		mx_down = mx;
    		my_down = my;
    	}
    	if (drag_view_button != Qt::NoButton && event->button() == drag_view_button) {
    		if (cursor().shape() != Qt::PointingHandCursor) { // TODO
    			setCursor(Qt::ClosedHandCursor);
    		}
    	}
    	if (select_text_button != Qt::NoButton && event->button() == select_text_button) {
    		if (triple_click_possible) {
    			cur_layout->select(event->x(), event->y(), Selection::StartLine);
    			triple_click_possible = false;
    		} else {
    			cur_layout->select(event->x(), event->y(), Selection::Start);
    		}
    
    		if (cursor().shape() != Qt::PointingHandCursor) { // TODO
    			setCursor(Qt::IBeamCursor);
    		}
    	}
    }
    
    void Canvas::mouseReleaseEvent(QMouseEvent *event) {
    	if (event->button() == Qt::LeftButton && event->modifiers() == Qt::ControlModifier) {
    		// emit synctex signal
    		pair<int, QPointF> location = cur_layout->get_location_at(event->x(), event->y());
    		// scale from [0,1] to points
    		location.second.rx() *= viewer->get_res()->get_page_width(location.first, false);
    		location.second.ry() *= viewer->get_res()->get_page_height(location.first, false);
    
    		emit synchronize_editor(location.first, (int) ROUND(location.second.x()), (int) ROUND(location.second.y()));
    	} else if (click_link_button != Qt::NoButton && event->button() == click_link_button) {
    		if (mx_down == event->x() && my_down == event->y()) {
    			pair<int, QPointF> location = cur_layout->get_location_at(mx_down, my_down);
    			cur_layout->activate_link(location.first, location.second.x(), location.second.y());
    		}
    	}
    
    	if (drag_view_button == Qt::LeftButton) {
    		setCursor(Qt::OpenHandCursor);
    	} else {
    		setCursor(Qt::IBeamCursor);
    	}
    
    	if (select_text_button != Qt::NoButton && event->button() == select_text_button) {
    		cur_layout->copy_selection_text();
    	}
    }
    
    void Canvas::mouseMoveEvent(QMouseEvent *event) {
    	if (drag_view_button != Qt::NoButton && event->buttons() & drag_view_button) {
    		cur_layout->scroll_smooth(event->x() - mx, event->y() - my);
    		mx = event->x();
    		my = event->y();
    	}
    	if (select_text_button != Qt::NoButton && event->buttons() & select_text_button) {
    		cur_layout->select(event->x(), event->y(), Selection::End);
    
    		// scrolling by dragging the selection
    		// TODO only scrolls when the mouse is moved
    		int margin = min(10, min(width() / 10, height() / 10));
    		if (event->x() < margin) {
    			cur_layout->scroll_smooth(min(margin - event->x(), margin) * 2, 0);
    		}
    		if (event->x() > width() - margin) {
    			cur_layout->scroll_smooth(max(width() - event->x() - margin, -margin) * 2, 0);
    		}
    		if (event->y() < margin) {
    			cur_layout->scroll_smooth(0, min(margin - event->y(), margin) * 2);
    		}
    		if (event->y() > height() - margin) {
    			cur_layout->scroll_smooth(0, max(height() - event->y() - margin, -margin) * 2);
    		}
    	}
    }
    
    void Canvas::wheelEvent(QWheelEvent *event) {
    	int d = event->delta();
    	switch (QApplication::keyboardModifiers()) {
    		// scroll
    		case Qt::NoModifier:
    			if (event->orientation() == Qt::Vertical) {
    				if (cur_layout->supports_smooth_scrolling()) {
    					cur_layout->scroll_smooth(0, d);
    				} else {
    					cur_layout->scroll_page(-d / mouse_wheel_factor);
    				}
    			} else {
    				cur_layout->scroll_smooth(d, 0);
    			}
    			break;
    
    		// zoom
    		case Qt::ControlModifier:
    			cur_layout->set_zoom(d / mouse_wheel_factor);
    			break;
    	}
    }
    
    void Canvas::mouseDoubleClickEvent(QMouseEvent * event) {
    	if (drag_view_button != Qt::NoButton && event->button() == drag_view_button) {
    		cur_layout->goto_page_at(event->x(), event->y());
    	}
    	if (select_text_button != Qt::NoButton && event->button() == select_text_button) {
    		// enable triple click, disable after timeout
    		triple_click_possible = true;
    		QTimer::singleShot(QApplication::doubleClickInterval(), this, SLOT(disable_triple_click()));
    
    		cur_layout->select(event->x(), event->y(), Selection::StartWord);
    	}
    }
    
    void Canvas::resizeEvent(QResizeEvent *event) {
    	cur_layout->resize(event->size().width(), event->size().height());
    	goto_line->move(0, height() - goto_line->height());
    	page_overlay->move(width() - page_overlay->width(), height() - page_overlay->height());
    }
    
    // primitive actions
    void Canvas::set_single_layout() {
    	single_layout->activate(cur_layout);
    	cur_layout = single_layout;
    	update();
    	viewer->get_beamer()->hide();
    	viewer->show_progress(false);
    	viewer->activateWindow();
    }
    
    void Canvas::set_grid_layout() {
    	grid_layout->activate(cur_layout);
    	grid_layout->rebuild();
    	cur_layout = grid_layout;
    	update();
    	viewer->get_beamer()->hide();
    	viewer->show_progress(false);
    	viewer->activateWindow();
    }
    
    void Canvas::set_presenter_layout() {
    	presenter_layout->activate(cur_layout);
    	presenter_layout->rebuild();
    	cur_layout = presenter_layout;
    	update();
    
    	// TODO move beamer to second screen
    //	QDesktopWidget *desktop = QApplication::desktop();
    //	if (desktop->screenCount() > 1) {
    //		int primary_screen = desktop->primaryScreen();
    //		int cur_screen = desktop->screenNumber(viewer);
    //		cout << "primary: " << primary_screen << ", current: " << cur_screen << endl;
    //	}
    	viewer->get_beamer()->get_layout()->scroll_page(cur_layout->get_page(), false);
    	viewer->get_beamer()->show();
    	viewer->show_progress(true);
    }
    
    void Canvas::toggle_overlay() {
    	page_overlay->setVisible(!page_overlay->isVisible());
    }
    
    void Canvas::focus_goto() {
    	goto_line->activateWindow();
    	goto_line->show();
    	goto_line->setFocus();
    	goto_line->setText(QString::number(cur_layout->get_page() + 1));
    	goto_line->selectAll();
    	goto_line->move(0, height() - goto_line->height()); // TODO this is only necessary because goto_line->height() is wrong in the beginning
    }
    
    void Canvas::disable_triple_click() {
    	triple_click_possible = false;
    }
    
    void Canvas::swap_selection_and_panning_buttons() {
    	Qt::MouseButton tmp = drag_view_button;
    	drag_view_button = select_text_button;
    	select_text_button = tmp;
    
    	if (drag_view_button == Qt::LeftButton) {
    		setCursor(Qt::OpenHandCursor);
    	} else {
    		setCursor(Qt::IBeamCursor);
    	}
    }
    
    
    void Canvas::set_search_visible(bool visible) {
    	cur_layout->set_search_visible(visible);
    	update();
    }
    
    void Canvas::page_rendered(int page) {
    	if (cur_layout->page_visible(page)) {
    		update();
    	}
    }
    
    void Canvas::goto_page() {
    	int page = goto_line->text().toInt() - 1;
    	goto_line->hide();
    	setFocus(Qt::OtherFocusReason);
    	cur_layout->scroll_page_top_jump(page, false);
    }