X-Git-Url: http://git.maemo.org/git/?p=presencevnc;a=blobdiff_plain;f=src%2Fmainwindow.cpp;h=ce3afc54c55f890788630fae0c547f70915d3c83;hp=b69182f6f2cac17799c0bdeef44bf67fdd5a4a84;hb=8a12c6cc92f27a423f0d9b740e11a7cc8cf8bc92;hpb=b65b14653f1737633bba662828874a5478316e40 diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index b69182f..ce3afc5 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1,346 +1,430 @@ /* - Presence VNC - Copyright (C) 2010 Christian Pulvermacher - - 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. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ + Presence VNC + Copyright (C) 2010 Christian Pulvermacher + + 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #include "connectdialog.h" #include "fullscreenexitbutton.h" #include "keymenu.h" #include "mainwindow.h" #include "preferences.h" +#include "scrollarea.h" #include "vncview.h" #ifdef Q_WS_MAEMO_5 #include #include +#include + +#include +#include #include #include #endif -MainWindow::MainWindow(QString url, int quality): - QMainWindow(0), - vnc_view(0), - scroll_area(new ScrollArea(0)) +MainWindow::MainWindow(QString url, int quality, int listen_port, bool view_only): + QMainWindow(0), + vnc_view(0), + scroll_area(new ScrollArea(0)), + input_toolbuttons(new QActionGroup(this)), + key_menu(0) { - setWindowTitle("Presence VNC"); + setWindowTitle("Presence VNC"); +#ifdef Q_WS_MAEMO_5 + setContextMenuPolicy(Qt::NoContextMenu); + setAttribute(Qt::WA_Maemo5StackedWindow); +#endif - migrateConfiguration(); - QSettings settings; + migrateConfiguration(); + //set up toolbar + toolbar = new QToolBar(0); + input_toolbuttons->addAction(toolbar->addAction(QChar(0x2026), this, SLOT(showKeyMenu()))); //"..." button + input_toolbuttons->addAction(toolbar->addAction(tr("Tab"), this, SLOT(sendTab()))); + input_toolbuttons->addAction(toolbar->addAction(tr("Esc"), this, SLOT(sendEsc()))); + input_toolbuttons->addAction(toolbar->addAction(tr("PgUp"), this, SLOT(sendPgUp()))); + input_toolbuttons->addAction(toolbar->addAction(tr("PgDn"), this, SLOT(sendPgDn()))); #ifdef Q_WS_MAEMO_5 - setAttribute(Qt::WA_Maemo5StackedWindow); + input_toolbuttons->addAction(toolbar->addAction(QIcon("/usr/share/icons/hicolor/48x48/hildon/chat_enter.png"), "", this, SLOT(sendReturn()))); + input_toolbuttons->addAction(toolbar->addAction(QIcon("/usr/share/icons/hicolor/48x48/hildon/control_keyboard.png"), "", this, SLOT(showInputPanel()))); #endif - //set up toolbar - toolbar = new QToolBar(0); - toolbar->addAction(QChar(0x2026), this, SLOT(showKeyMenu())); //"..." button - toolbar->addAction(tr("Tab"), this, SLOT(sendTab())); - toolbar->addAction(tr("Esc"), this, SLOT(sendEsc())); - toolbar->addAction(tr("PgUp"), this, SLOT(sendPgUp())); - toolbar->addAction(tr("PgDn"), this, SLOT(sendPgDn())); + QSettings settings; + zoom_slider = new QSlider(Qt::Horizontal, 0); + zoom_slider->setRange(0, 100); + connect(zoom_slider, SIGNAL(valueChanged(int)), + this, SLOT(setZoomLevel(int))); + connect(zoom_slider, SIGNAL(sliderReleased()), + this, SLOT(zoomSliderReleased())); + zoom_slider->setValue(settings.value("zoomlevel", 95).toInt()); + toolbar->addWidget(zoom_slider); + #ifdef Q_WS_MAEMO_5 - toolbar->addAction(QIcon("/usr/share/icons/hicolor/48x48/hildon/chat_enter.png"), "", this, SLOT(sendReturn())); - toolbar->addAction(QIcon("/usr/share/icons/hicolor/48x48/hildon/control_keyboard.png"), "", this, SLOT(showInputPanel())); + toolbar->addAction(QIcon("/usr/share/icons/hicolor/48x48/hildon/general_fullsize.png"), "", this, SLOT(toggleFullscreen())); +#else + toolbar->addAction(tr("Toggle Fullscreen"), this, SLOT(toggleFullscreen())); #endif - - //move fullscreen button to the right - QWidget *spacer = new QWidget(); - spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - toolbar->addWidget(spacer); - - toolbar->addAction(QIcon("/usr/share/icons/hicolor/48x48/hildon/general_fullsize.png"), "", this, SLOT(toggleFullscreen())); - addToolBar(toolbar); - toolbar->setVisible(settings.value("show_toolbar", true).toBool()); - - //set up menu - QAction *connect_action = new QAction(tr("Connect"), this); - disconnect_action = new QAction(tr("Disconnect"), this); - scaling = new QAction(tr("Fit to Screen"), this); - scaling->setCheckable(true); - scaling->setChecked(settings.value("rescale", true).toBool()); - show_toolbar = new QAction(tr("Show Toolbar"), this); - show_toolbar->setCheckable(true); - show_toolbar->setChecked(settings.value("show_toolbar", true).toBool()); - QAction *pref_action = new QAction(tr("Preferences"), this); - QAction *about_action = new QAction(tr("About"), this); + addToolBar(toolbar); + toolbar->setVisible(settings.value("show_toolbar", true).toBool()); + toolbar->setEnabled(false); + + //set up menu + QAction *connect_action = new QAction(tr("Connect"), this); + disconnect_action = new QAction(tr("Disconnect"), this); + show_toolbar = new QAction(tr("Show toolbar"), this); + show_toolbar->setCheckable(true); + show_toolbar->setChecked(settings.value("show_toolbar", true).toBool()); + QAction *pref_action = new QAction(tr("Preferences"), this); + QAction *about_action = new QAction(tr("About"), this); #ifdef Q_WS_MAEMO_5 - menuBar()->addAction(connect_action); - menuBar()->addAction(disconnect_action); - menuBar()->addAction(scaling); - menuBar()->addAction(show_toolbar); - menuBar()->addAction(pref_action); - menuBar()->addAction(about_action); + menuBar()->addAction(connect_action); + menuBar()->addAction(disconnect_action); + menuBar()->addAction(show_toolbar); + menuBar()->addAction(pref_action); + menuBar()->addAction(about_action); #else - QMenu* session_menu = menuBar()->addMenu(tr("&Session")); - session_menu->addAction(connect_action); - session_menu->addAction(disconnect_action); - session_menu->addSeparator(); - //session_menu->addAction(pref_action); - //session_menu->addSeparator(); - session_menu->addAction(tr("&Quit"), this, SLOT(close())); - - QMenu* view_menu = menuBar()->addMenu(tr("&View")); - view_menu->addAction(scaling); - view_menu->addAction(show_toolbar); - - QMenu* help_menu = menuBar()->addMenu(tr("&Help")); - help_menu->addAction(about_action); + QMenu* session_menu = menuBar()->addMenu(tr("&Session")); + session_menu->addAction(connect_action); + session_menu->addAction(disconnect_action); + session_menu->addSeparator(); + session_menu->addAction(pref_action); + session_menu->addSeparator(); + session_menu->addAction(tr("&Quit"), this, SLOT(close())); + + QMenu* view_menu = menuBar()->addMenu(tr("&View")); + view_menu->addAction(show_toolbar); + + QMenu* help_menu = menuBar()->addMenu(tr("&Help")); + help_menu->addAction(about_action); #endif - connect(about_action, SIGNAL(triggered()), - this, SLOT(about())); - connect(pref_action, SIGNAL(triggered()), - this, SLOT(showPreferences())); - connect(connect_action, SIGNAL(triggered()), - this, SLOT(showConnectDialog())); - connect(disconnect_action, SIGNAL(triggered()), - this, SLOT(disconnectFromHost())); - connect(show_toolbar, SIGNAL(toggled(bool)), - toolbar, SLOT(setVisible(bool))); - connect(show_toolbar, SIGNAL(toggled(bool)), - this, SLOT(forceResizeDelayed())); - - setCentralWidget(scroll_area); - new FullScreenExitButton(this); - - grabZoomKeys(true); - reloadSettings(); - - if(url.isNull()) { - disconnect_action->setEnabled(false); - toolbar->setEnabled(false); - showConnectDialog(); - } else { - vnc_view = new VncView(this, url, RemoteView::Quality(quality)); - connect(scaling, SIGNAL(toggled(bool)), - vnc_view, SLOT(enableScaling(bool))); - connect(vnc_view, SIGNAL(statusChanged(RemoteView::RemoteStatus)), - this, SLOT(statusChanged(RemoteView::RemoteStatus))); - scroll_area->setWidget(vnc_view); - vnc_view->start(); - vnc_view->enableScaling(scaling->isChecked()); - } + connect(about_action, SIGNAL(triggered()), + this, SLOT(about())); + connect(pref_action, SIGNAL(triggered()), + this, SLOT(showPreferences())); + connect(connect_action, SIGNAL(triggered()), + this, SLOT(showConnectDialog())); + connect(disconnect_action, SIGNAL(triggered()), + this, SLOT(disconnectFromHost())); + connect(show_toolbar, SIGNAL(toggled(bool)), + toolbar, SLOT(setVisible(bool))); + connect(show_toolbar, SIGNAL(toggled(bool)), + this, SLOT(updateScreenSpaceDelayed())); +#ifdef Q_WS_MAEMO_5 + QDBusConnection::systemBus().connect("", MCE_SIGNAL_PATH, MCE_SIGNAL_IF, MCE_DISPLAY_SIG, + this, SLOT(displayStateChanged(QString))); +#endif + + setCentralWidget(scroll_area); + + FullScreenExitButton* fullscreen_exit_button = new FullScreenExitButton(this); + connect(fullscreen_exit_button, SIGNAL(clicked()), + this, SLOT(toggleFullscreen())); + + grabZoomKeys(true); + reloadSettings(); + + if(url.isEmpty() and listen_port == 0) { + disconnect_action->setEnabled(false); + showConnectDialog(); + } else { + connectToHost(url, quality, listen_port, view_only); + } } void MainWindow::grabZoomKeys(bool grab) { #ifdef Q_WS_MAEMO_5 - unsigned long val = (grab)?1:0; - Atom atom = XInternAtom(QX11Info::display(), "_HILDON_ZOOM_KEY_ATOM", False); - if(!atom) { - qWarning("Couldn't get zoom key atom"); - return; - } - XChangeProperty(QX11Info::display(), winId(), atom, XA_INTEGER, - 32, PropModeReplace, reinterpret_cast(&val), 1); + unsigned long val = (grab)?1:0; + Atom atom = XInternAtom(QX11Info::display(), "_HILDON_ZOOM_KEY_ATOM", False); + if(!atom) { + qWarning("Couldn't get zoom key atom"); + return; + } + XChangeProperty(QX11Info::display(), winId(), atom, XA_INTEGER, + 32, PropModeReplace, reinterpret_cast(&val), 1); #endif } -void MainWindow::closeEvent(QCloseEvent*) { - grabZoomKeys(false); +void MainWindow::closeEvent(QCloseEvent*) +{ + grabZoomKeys(false); - QSettings settings; - settings.setValue("show_toolbar", show_toolbar->isChecked()); - settings.setValue("rescale", scaling->isChecked()); - settings.sync(); + QSettings settings; + settings.setValue("show_toolbar", show_toolbar->isChecked()); + settings.setValue("zoomlevel", zoom_slider->value()); + settings.sync(); - hide(); + hide(); - disconnectFromHost(); + disconnectFromHost(); } -void MainWindow::about() { - QMessageBox::about(this, tr("About Presence VNC"), - tr("

Presence VNC 0.5

\ -

A touchscreen friendly VNC client

\ -

https://garage.maemo.org/projects/presencevnc

\ -

©2010 Christian Pulvermacher <pulvermacher@gmx.de>

\ -

Based on KRDC, © 2007-2008 Urs Wolfer

\ -

and LibVNCServer, © 2001-2003 Johannes E. Schindelin

\ -

This program is free software; License: GNU GPL 2 or later.

")); +void MainWindow::about() +{ + QMessageBox::about(this, tr("About Presence VNC"), + tr("

Presence VNC 0.8

\ +

A touchscreen friendly VNC client

\ +

http://presencevnc.garage.maemo.org/

\ +

©2010 Christian Pulvermacher <pulvermacher@gmx.de>
\ + Based on KRDC, © 2007-2008 Urs Wolfer
\ + and LibVNCServer, © 2001-2003 Johannes E. Schindelin

\ +

This program is free software; License: GNU GPL 2 or later.

")); } void MainWindow::showConnectDialog() { - ConnectDialog *connect_dialog = new ConnectDialog(this); - connect(connect_dialog, SIGNAL(connectToHost(QString)), - this, SLOT(connectToHost(QString))); - connect_dialog->exec(); + ConnectDialog *connect_dialog = new ConnectDialog(this); + connect(connect_dialog, SIGNAL(connectToHost(QString, int, int, bool)), + this, SLOT(connectToHost(QString, int, int, bool))); + connect_dialog->exec(); + //ConnectDialog cleans up after itself } -void MainWindow::connectToHost(QString url) +void MainWindow::connectToHost(QString url, int quality, int listen_port, bool view_only) { - disconnectFromHost(); - - vnc_view = new VncView(this, url, RemoteView::Quality(2)); - - connect(scaling, SIGNAL(toggled(bool)), - vnc_view, SLOT(enableScaling(bool))); - connect(vnc_view, SIGNAL(statusChanged(RemoteView::RemoteStatus)), - this, SLOT(statusChanged(RemoteView::RemoteStatus))); - scroll_area->setWidget(vnc_view); - vnc_view->start(); - vnc_view->enableScaling(scaling->isChecked()); - disconnect_action->setEnabled(true); - toolbar->setEnabled(true); + disconnectFromHost(); + + vnc_view = new VncView(this, url, RemoteView::Quality(quality), listen_port); + vnc_view->setViewOnly(view_only); + + connect(vnc_view, SIGNAL(statusChanged(RemoteView::RemoteStatus)), + this, SLOT(statusChanged(RemoteView::RemoteStatus))); + scroll_area->setWidget(vnc_view); + vnc_view->start(); + setWindowTitle(QString("Presence VNC - %1").arg(vnc_view->host()) + (view_only?tr(" [View Only]"):"")); + + disconnect_action->setEnabled(true); + + //reset key menu + delete key_menu; + key_menu = new KeyMenu(this); } void MainWindow::disconnectFromHost() { - if(!vnc_view) - return; + if(!vnc_view) + return; - scroll_area->setWidget(0); + setWindowTitle("Presence VNC"); + disconnect_action->setEnabled(false); + toolbar->setEnabled(false); + scroll_area->setWidget(0); - vnc_view->disconnect(); //remove all signal-slot connections - delete vnc_view; - vnc_view = 0; - disconnect_action->setEnabled(false); - toolbar->setEnabled(false); + delete vnc_view; + vnc_view = 0; } void MainWindow::statusChanged(RemoteView::RemoteStatus status) { - static RemoteView::RemoteStatus old_status = RemoteView::Disconnected; + static RemoteView::RemoteStatus old_status = RemoteView::Disconnected; - switch(status) { - case RemoteView::Connecting: + switch(status) { + case RemoteView::Connecting: #ifdef Q_WS_MAEMO_5 - setAttribute(Qt::WA_Maemo5ShowProgressIndicator, true); + setAttribute(Qt::WA_Maemo5ShowProgressIndicator, true); #endif - break; - case RemoteView::Connected: + break; + case RemoteView::Connected: #ifdef Q_WS_MAEMO_5 - setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false); + setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false); #endif - if(!scaling->isChecked()) { - //ugly hack to force a refresh (forceFullRepaint() doesn't repaint?? -> vnc_view hidden???) - vnc_view->resize(scroll_area->size()); - vnc_view->enableScaling(false); - } - break; - case RemoteView::Disconnecting: - if(old_status != RemoteView::Disconnected) { //Disconnecting also occurs while connecting, so check last state + toolbar->setEnabled(true); + + //disable key input buttons in view only mode + input_toolbuttons->setEnabled(!vnc_view->viewOnly()); + + vnc_view->setZoomLevel(zoom_slider->value()); + vnc_view->useFastTransformations(false); + vnc_view->repaint(); + break; + case RemoteView::Disconnecting: + if(old_status == RemoteView::Disconnected) //Disconnecting also occurs while connecting, so check last state + break; + + if(disconnect_action->isEnabled()) //don't show when manually disconnecting + scroll_area->showMessage(tr("Connection lost")); + + //clean up + scroll_area->setWidget(0); + vnc_view = 0; + setWindowTitle("Presence VNC"); + disconnect_action->setEnabled(false); + toolbar->setEnabled(false); + + //exit fullscreen mode + if(windowState() & Qt::WindowFullScreen) + setWindowState(windowState() ^ Qt::WindowFullScreen); + break; + case RemoteView::Disconnected: #ifdef Q_WS_MAEMO_5 - QMaemo5InformationBox::information(this, tr("Connection lost")); + setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false); #endif - - //clean up - scroll_area->setWidget(0); - vnc_view = 0; - disconnect_action->setEnabled(false); - toolbar->setEnabled(false); - - //exit fullscreen mode - if(windowState() & Qt::WindowFullScreen) - setWindowState(windowState() ^ Qt::WindowFullScreen); - } - break; - case RemoteView::Disconnected: -#ifdef Q_WS_MAEMO_5 - setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false); -#endif - if(old_status == RemoteView::Disconnecting) { - scroll_area->setWidget(0); //remove widget - } - break; - } - - old_status = status; + if(old_status == RemoteView::Disconnecting) { + scroll_area->setWidget(0); //remove widget + } + break; + default: //avoid compiler warnings + break; + } + + old_status = status; } -//when rescaling is enabled, this resizes the widget to use available screen space +//updates available screen space for current zoom level //necessary when rotating, showing fullscreen, etc. -void MainWindow::forceResize() +void MainWindow::updateScreenSpace() { - if(vnc_view and scaling->isChecked()) { - vnc_view->resize(scroll_area->size()); - } -} + if(vnc_view) { + vnc_view->setZoomLevel(); + } +} -void MainWindow::forceResizeDelayed() +void MainWindow::updateScreenSpaceDelayed() { - QTimer::singleShot(500, this, SLOT(forceResize())); + QTimer::singleShot(500, this, SLOT(updateScreenSpace())); } void MainWindow::toggleFullscreen() { - bool in_fullscreen = windowState() & Qt::WindowFullScreen; + bool in_fullscreen = windowState() & Qt::WindowFullScreen; - //hide menu/toolbar in fullscreen (new state is !in_fullscreen) - toolbar->setVisible(show_toolbar->isChecked() and in_fullscreen); + //hide menu/toolbar in fullscreen (new state is !in_fullscreen) + toolbar->setVisible(show_toolbar->isChecked() and in_fullscreen); #ifndef Q_WS_MAEMO_5 - //menu bar is invisible by default on maemo - menuBar()->setVisible(in_fullscreen); + //menu bar is invisible by default on maemo + menuBar()->setVisible(in_fullscreen); #endif - setWindowState(windowState() ^ Qt::WindowFullScreen); - forceResizeDelayed(); + setWindowState(windowState() ^ Qt::WindowFullScreen); + updateScreenSpaceDelayed(); } void MainWindow::showKeyMenu() { - static KeyMenu *key_menu = new KeyMenu(this); - key_menu->exec(); - - vnc_view->sendKeySequence(key_menu->getKeySequence()); + key_menu->exec(); + vnc_view->sendKeySequence(key_menu->getKeySequence()); } void MainWindow::showPreferences() { - Preferences *p = new Preferences(this); - p->exec(); - delete p; + Preferences *p = new Preferences(this); + p->exec(); + delete p; - reloadSettings(); + reloadSettings(); } void MainWindow::reloadSettings() { - QSettings settings; + QSettings settings; + zoom_to_cursor = settings.value("zoom_to_cursor", true).toBool(); + #ifdef Q_WS_MAEMO_5 - int rotation = settings.value("screen_rotation", 0).toInt(); - setAttribute(Qt::WA_Maemo5AutoOrientation, rotation == 0); - setAttribute(Qt::WA_Maemo5LandscapeOrientation, rotation == 1); - setAttribute(Qt::WA_Maemo5PortraitOrientation, rotation == 2); + int rotation = settings.value("screen_rotation", 0).toInt(); + setAttribute(Qt::WA_Maemo5AutoOrientation, rotation == 0); + setAttribute(Qt::WA_Maemo5LandscapeOrientation, rotation == 1); + setAttribute(Qt::WA_Maemo5PortraitOrientation, rotation == 2); #endif - if(vnc_view) - vnc_view->reloadSettings(); + if(vnc_view) + vnc_view->reloadSettings(); } void MainWindow::resizeEvent(QResizeEvent *event) { - QMainWindow::resizeEvent(event); + QMainWindow::resizeEvent(event); + + updateScreenSpace(); + if(vnc_view) + vnc_view->setZoomLevel(zoom_slider->value()); - forceResize(); +#ifdef Q_WS_MAEMO_5 + //hide zoom slider in portrait mode + zoom_slider->setVisible(height() < width()); +#endif } void MainWindow::showInputPanel() { #ifdef Q_WS_MAEMO_5 - //TODO: when hardware keyboard is open, this will only cause the IM to mess up 'real' key events - vnc_view->setAttribute(Qt::WA_InputMethodEnabled, true); - vnc_view->setInputMethodHints(Qt::ImhPreferLowercase); //without this, IM starts with caps lock + //TODO: when hardware keyboard is open, this will only cause the IM to mess up 'real' key events + vnc_view->setAttribute(Qt::WA_InputMethodEnabled, true); + vnc_view->setInputMethodHints(Qt::ImhNoAutoUppercase); //without this, IM starts with caps lock - QEvent event(QEvent::RequestSoftwareInputPanel); - QApplication::sendEvent(vnc_view, &event); + QEvent event(QEvent::RequestSoftwareInputPanel); + QApplication::sendEvent(vnc_view, &event); #endif } + +void MainWindow::setZoomLevel(int level) +{ + if(!vnc_view) + return; + + const qreal old_factor = vnc_view->zoomFactor(); + QPoint center = vnc_view->visibleRegion().boundingRect().center(); + + vnc_view->setZoomLevel(level); + + const qreal new_factor = vnc_view->zoomFactor(); + + //scroll to center, if zoom level actually changed + if(old_factor != new_factor) { + if(zoom_to_cursor) + center = new_factor * vnc_view->cursorPosition(); + else //zoom to center of visible region + center = center * (double(new_factor)/old_factor); + + scroll_area->ensureVisible(center.x(), center.y(), + vnc_view->visibleRegion().boundingRect().width()/2, + vnc_view->visibleRegion().boundingRect().height()/2); + + vnc_view->useFastTransformations(zoom_slider->isSliderDown()); + vnc_view->update(); + + scroll_area->showMessage(tr("Zoom: %1\%").arg(qRound(100*new_factor))); + } +} + +void MainWindow::zoomSliderReleased() +{ + static QTime time; + if(!time.isNull() and time.elapsed() < 500) //double clicked + zoom_slider->setValue(95); //100% + + time.restart(); + + //stopped zooming, reenable high quality + vnc_view->useFastTransformations(false); +} + +void MainWindow::displayStateChanged(QString state) +{ + const bool display_on = (state != "off"); + if(vnc_view) + vnc_view->setDisplayOff(!display_on); +} + +void MainWindow::sendTab() { vnc_view->sendKey(Qt::Key_Tab); } +void MainWindow::sendEsc() { vnc_view->sendKey(Qt::Key_Escape); } +void MainWindow::sendPgUp() { vnc_view->sendKey(Qt::Key_PageUp); } +void MainWindow::sendPgDn() { vnc_view->sendKey(Qt::Key_PageDown); } +void MainWindow::sendReturn() { vnc_view->sendKey(Qt::Key_Return); }