File indexing completed on 2024-04-28 03:40:28

0001 // SPDX-FileCopyrightText: 2001-2003 Sarang Lakare <sarang@users.sourceforge.net>
0002 // SPDX-FileCopyrightText: 2003-2004 Olaf Schmidt <ojschmidt@kde.org>
0003 // SPDX-FileCopyrightText: 2008 Matthew Woehlke <mw_triad@users.sourceforge.net>
0004 // SPDX-FileCopyrightText: 2010 Sebastian Sauer <sebsauer@kdab.com>
0005 // SPDX-License-Identifier: GPL-2.0-or-later
0006 
0007 #include "kmag.h"
0008 
0009 // include files for Qt
0010 #include <QApplication>
0011 #include <QClipboard>
0012 #include <QDebug>
0013 #include <QFileDialog>
0014 #include <QImageWriter>
0015 #include <QMenuBar>
0016 #include <QPainter>
0017 #include <QPrintDialog>
0018 #include <QScreen>
0019 #include <QTemporaryFile>
0020 
0021 // include files for KF5
0022 #include <KActionCollection>
0023 #include <KConfigGroup>
0024 #include <KEditToolBar>
0025 #include <KLocalizedString>
0026 #include <KMessageBox>
0027 #include <KSelectAction>
0028 #include <KShortcutsDialog>
0029 #include <KToggleAction>
0030 #include <KXMLGUIFactory>
0031 #include <KIO/FileCopyJob>
0032 
0033 // application specific includes
0034 #include "kmagselrect.h"
0035 
0036 
0037 KmagApp::KmagApp(QWidget*)
0038   : KXmlGuiWindow(nullptr) // Qt::WStyle_MinMax | Qt::WType_TopLevel | Qt::WDestructiveClose | Qt::WStyle_ContextHelp | Qt::WindowCloseButtonHint | Qt::WStyle_StaysOnTop
0039   , m_defaultMouseCursorType(2)
0040 {
0041   setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
0042   config=KSharedConfig::openConfig();
0043 
0044   zoomArrayString << QStringLiteral( "5:1" ) << QStringLiteral( "2:1" ) << QStringLiteral( "1:1" ) << QStringLiteral( "1:1.5" ) << QStringLiteral( "1:2" ) << QStringLiteral( "1:3" ) << QStringLiteral( "1:4" ) << QStringLiteral( "1:5" )
0045     << QStringLiteral( "1:6" ) << QStringLiteral( "1:7" ) << QStringLiteral( "1:8" ) << QStringLiteral( "1:12" ) << QStringLiteral( "1:16" ) << QStringLiteral( "1:20" );
0046 
0047   zoomArray << 0.2 <<0.5 << 1.0;
0048   zoomArray << 1.5 << 2.0 << 3.0;
0049   zoomArray << 4.0 << 5.0 << 6.0 << 7.0;
0050   zoomArray << 8.0 << 12.0 << 16.0 << 20.0;
0051 
0052   fpsArrayString << i18nc("Zoom at very low", "&Very Low") << i18nc("Zoom at low", "&Low") << i18nc("Zoom at medium", "&Medium") << i18nc("Zoom at high", "&High") << i18nc("Zoom at very high", "V&ery High");
0053 
0054   fpsArray.append(2); // very low
0055   fpsArray.append(6); // low
0056   fpsArray.append(10); // medium
0057   fpsArray.append(15); // high
0058   fpsArray.append(25); // very high
0059 
0060   colorArrayString << i18nc("No color-blindness simulation, i.e. 'normal' vision", "&Normal") << i18n("&Protanopia") << i18n("&Deuteranopia") << i18n("&Tritanopia") << i18n("&Achromatopsia");
0061 
0062   colorArray.append(0);
0063   colorArray.append(1);
0064   colorArray.append(2);
0065   colorArray.append(3);
0066   colorArray.append(4);
0067 
0068   rotationArrayString << i18n("&No Rotation (0 Degrees)") << i18n("&Left (90 Degrees)") << i18n("&Upside Down (180 Degrees)") << i18n("&Right (270 Degrees)");
0069 
0070   rotationArray.append(0); // no rotation
0071   rotationArray.append(90); // left
0072   rotationArray.append(180); // upside down
0073   rotationArray.append(270); // right
0074 
0075   // call inits to invoke all other construction parts
0076   initView();
0077   initActions();
0078   initConnections();
0079 
0080   // read options from config file
0081   readOptions();
0082 }
0083 
0084 /**
0085  * Default destructor.
0086  */
0087 KmagApp::~KmagApp()
0088 {
0089     m_zoomView->showSelRect(false);
0090 
0091     #ifndef QT_NO_PRINTER
0092     delete m_printer;
0093     #endif // QT_NO_PRINTER
0094 }
0095 
0096 void KmagApp::initActions()
0097 {
0098   fileNewWindow = actionCollection()->addAction(QStringLiteral( "new_window" ));
0099   fileNewWindow->setIcon(QIcon::fromTheme(QStringLiteral( "window-new" )));
0100   fileNewWindow->setText(i18n("New &Window"));
0101   connect(fileNewWindow, &QAction::triggered, this, &KmagApp::slotFileNewWindow);
0102   actionCollection()->setDefaultShortcuts(fileNewWindow, KStandardShortcut::openNew());
0103   fileNewWindow->setToolTip(i18n("Open a new KMagnifier window"));
0104 
0105   refreshSwitch = actionCollection()->addAction(QStringLiteral( "start_stop_refresh" ));
0106   refreshSwitch->setIcon(QIcon::fromTheme(QStringLiteral( "process-stop" )));
0107   refreshSwitch->setText(i18n("&Stop"));
0108   connect(refreshSwitch, &QAction::triggered, this, &KmagApp::slotToggleRefresh);
0109   actionCollection()->setDefaultShortcuts(refreshSwitch, KStandardShortcut::reload());
0110   refreshSwitch->setToolTip(i18n("Click to stop window refresh"));
0111   refreshSwitch->setWhatsThis(i18n("Clicking on this icon will <b>start</b> / <b>stop</b> "
0112                                    "updating of the display. Stopping the update will zero the processing power "
0113                                    "required (CPU usage)"));
0114 
0115   m_pSnapshot = actionCollection()->addAction(QStringLiteral( "snapshot" ));
0116   m_pSnapshot->setIcon(QIcon::fromTheme(QStringLiteral( "ksnapshot" )));
0117   m_pSnapshot->setText(i18n("&Save Snapshot As..."));
0118   connect(m_pSnapshot, &QAction::triggered, this, &KmagApp::saveZoomPixmap);
0119   actionCollection()->setDefaultShortcuts(m_pSnapshot, KStandardShortcut::save());
0120   m_pSnapshot->setWhatsThis(i18n("Saves the zoomed view to an image file."));
0121   m_pSnapshot->setToolTip(i18n("Save image to a file"));
0122 
0123   m_pPrint = actionCollection()->addAction(KStandardAction::Print, this, SLOT(slotFilePrint()));
0124   m_pPrint->setWhatsThis(i18n("Click on this button to print the current zoomed view."));
0125 
0126   m_pQuit = actionCollection()->addAction(KStandardAction::Quit, this, SLOT(slotFileQuit()));
0127   m_pQuit->setToolTip(i18n("Quits the application"));
0128   m_pQuit->setWhatsThis (i18n("Quits the application"));
0129 
0130   m_pCopy = actionCollection()->addAction(KStandardAction::Copy, this, SLOT(copyToClipBoard()));
0131   m_pCopy->setWhatsThis(i18n("Click on this button to copy the current zoomed view to the clipboard which you can paste in other applications."));
0132   m_pCopy->setToolTip(i18n("Copy zoomed image to clipboard"));
0133 
0134   m_pShowMenu = KStandardAction::showMenubar(this, SLOT(slotShowMenu()), actionCollection());
0135 
0136   setStandardToolBarMenuEnabled(true);
0137 
0138   m_modeFollowMouse = new KToggleAction(QIcon::fromTheme(QStringLiteral( "followmouse" )), i18n("&Follow Mouse Mode"), this);
0139   actionCollection()->addAction(QStringLiteral( "mode_followmouse" ), m_modeFollowMouse);
0140   connect(m_modeFollowMouse, &QAction::triggered, this, &KmagApp::slotModeChanged);
0141   actionCollection()->setDefaultShortcut(m_modeFollowMouse, Qt::Key_F2);
0142   m_modeFollowMouse->setIconText(i18n("Mouse"));
0143   m_modeFollowMouse->setToolTip(i18n("Magnify around the mouse cursor"));
0144   m_modeFollowMouse->setWhatsThis(i18n("If selected, the area around the mouse cursor is magnified"));
0145 
0146 #if HAVE_QACCESSIBILITYCLIENT
0147 
0148   m_modeFollowFocus = new KToggleAction(QIcon::fromTheme(QStringLiteral( "view-restore" )), i18n("&Follow Focus Mode"), this);
0149   actionCollection()->addAction(QStringLiteral( "mode_followfocus" ), m_modeFollowFocus);
0150   connect(m_modeFollowFocus, SIGNAL(triggered(bool)), SLOT(slotModeChanged()));
0151   actionCollection()->setDefaultShortcut(m_modeFollowFocus, Qt::Key_F8);
0152   m_modeFollowFocus->setIconText(i18n("Focus"));
0153   m_modeFollowFocus->setToolTip(i18n("Magnify around the keyboard focus"));
0154   m_modeFollowFocus->setWhatsThis(i18n("If selected, the area around the keyboard cursor is magnified"));
0155 
0156 #endif
0157 
0158   m_modeSelWin = new KToggleAction(QIcon::fromTheme(QStringLiteral( "window" )), i18n("Se&lection Window Mode"), this);
0159   actionCollection()->addAction(QStringLiteral( "mode_selectionwindow" ), m_modeSelWin);
0160   connect(m_modeSelWin, &QAction::triggered, this, &KmagApp::slotModeSelWin);
0161   actionCollection()->setDefaultShortcut(m_modeSelWin, Qt::Key_F3);
0162   m_modeSelWin->setIconText(i18n("Window"));
0163   m_modeSelWin->setToolTip(i18n("Show a window for selecting the magnified area"));
0164 
0165   m_modeWholeScreen = new KToggleAction(QIcon::fromTheme(QStringLiteral( "view-fullscreen" )), i18n("&Whole Screen Mode"), this);
0166   actionCollection()->addAction(QStringLiteral( "mode_wholescreen" ), m_modeWholeScreen);
0167   connect(m_modeWholeScreen, &QAction::triggered, this, &KmagApp::slotModeWholeScreen);
0168   actionCollection()->setDefaultShortcut(m_modeWholeScreen, Qt::Key_F4);
0169   m_modeWholeScreen->setIconText(i18n("Screen"));
0170   m_modeWholeScreen->setToolTip(i18n("Magnify the whole screen"));
0171   m_modeWholeScreen->setWhatsThis(i18n("Click on this button to fit the zoom view to the zoom window."));
0172 
0173   m_hideCursor = new KToggleAction(QIcon::fromTheme(QStringLiteral( "hidemouse" )), i18n("Hide Mouse &Cursor"), this);
0174   actionCollection()->addAction(QStringLiteral( "hidecursor" ), m_hideCursor);
0175   connect(m_hideCursor, &QAction::triggered, this, &KmagApp::slotToggleHideCursor);
0176   actionCollection()->setDefaultShortcut(m_hideCursor, Qt::Key_F6);
0177   #ifdef havesetCheckedStatef
0178   m_hideCursor->setCheckedState(KGuiItem(i18n("Show Mouse &Cursor")));
0179   #endif
0180   m_hideCursor->setIconText(i18n("Hide"));
0181   m_hideCursor->setToolTip(i18n("Hide the mouse cursor"));
0182 
0183   m_staysOnTop = new KToggleAction(QIcon::fromTheme(QStringLiteral( "go-top" )), i18n("Stays On Top"), this);
0184   actionCollection()->addAction(QStringLiteral( "staysontop" ), m_staysOnTop);
0185   connect(m_staysOnTop, &QAction::triggered, this, &KmagApp::slotStaysOnTop);
0186   actionCollection()->setDefaultShortcut(m_staysOnTop, Qt::Key_F7);
0187   m_staysOnTop->setToolTip(i18n("The KMagnifier Window stays on top of other windows."));
0188 
0189   m_pZoomIn = actionCollection()->addAction(KStandardAction::ZoomIn, this, SLOT(zoomIn()));
0190   m_pZoomIn->setWhatsThis(i18n("Click on this button to <b>zoom-in</b> on the selected region."));
0191 
0192   m_pZoomBox = new KSelectAction(i18n("&Zoom"), this);
0193   actionCollection()->addAction(QStringLiteral( "zoom" ), m_pZoomBox);
0194   m_pZoomBox->setItems(zoomArrayString);
0195   m_pZoomBox->setWhatsThis(i18n("Select the zoom factor."));
0196   m_pZoomBox->setToolTip(i18n("Zoom factor"));
0197 
0198   m_pZoomOut = actionCollection()->addAction(KStandardAction::ZoomOut, this, SLOT(zoomOut()));
0199   m_pZoomOut->setWhatsThis(i18n("Click on this button to <b>zoom-out</b> on the selected region."));
0200 
0201   m_pRotationBox = new KSelectAction(i18n("&Rotation"),this);
0202   actionCollection()->addAction(QStringLiteral( "rotation" ), m_pRotationBox);
0203   m_pRotationBox->setItems(rotationArrayString);
0204   m_pRotationBox->setWhatsThis(i18n("Select the rotation degree."));
0205   m_pRotationBox->setToolTip(i18n("Rotation degree"));
0206 
0207   m_keyConf = actionCollection()->addAction(KStandardAction::KeyBindings, this, SLOT(slotConfKeys()));
0208   m_toolConf = actionCollection()->addAction(KStandardAction::ConfigureToolbars, this, SLOT(slotEditToolbars()));
0209 
0210   m_pFPSBox = new KSelectAction(i18n("&Refresh"),this);
0211   actionCollection()->addAction(QStringLiteral( "fps_selector" ), m_pFPSBox);
0212   m_pFPSBox->setItems(fpsArrayString);
0213   m_pFPSBox->setWhatsThis(i18n("Select the refresh rate. The higher the rate, the more computing power (CPU) will be needed."));
0214   m_pFPSBox->setToolTip(i18n("Refresh rate"));
0215 
0216   m_pColorBox = new KSelectAction(i18nc("Color-blindness simulation mode", "&Color"),this);
0217   actionCollection()->addAction(QStringLiteral( "color_mode" ), m_pColorBox);
0218   m_pColorBox->setItems(colorArrayString);
0219   m_pColorBox->setWhatsThis(i18n("Select a mode to simulate various types of color-blindness."));
0220   m_pColorBox->setToolTip(i18n("Color-blindness Simulation Mode"));
0221 
0222   setupGUI(ToolBar | Keys | Save | Create);
0223 }
0224 
0225 void KmagApp::initView()
0226 {
0227   m_zoomView = new KMagZoomView( this, "ZoomView" );
0228 //m_zoomView->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)7, (QSizePolicy::SizeType)7, m_zoomView->sizePolicy().hasHeightForWidth() ) );
0229   m_zoomView->setFrameShape( QFrame::NoFrame );
0230 
0231   setCentralWidget(m_zoomView);
0232 }
0233 
0234 
0235 void KmagApp::slotChangeZoomBoxIndex(int index)
0236 {
0237    m_pZoomBox->setCurrentItem(index);
0238 }
0239 
0240 void KmagApp::slotChangeRotationBoxIndex(int index)
0241 {
0242   m_pRotationBox->setCurrentItem(index);
0243 }
0244 
0245 void KmagApp::slotChangeFPSIndex(int index)
0246 {
0247   m_pFPSBox->setCurrentItem(index);
0248 }
0249 
0250 void KmagApp::slotChangeColorIndex(int index)
0251 {
0252   m_pColorBox->setCurrentItem(index);
0253 }
0254 
0255 /**
0256  * Initialize all connections.
0257  */
0258 void KmagApp::initConnections()
0259 {
0260   // change in zoom value -> update the view
0261   connect(this, &KmagApp::updateZoomValue, m_zoomView, &KMagZoomView::setZoom);
0262   connect(this, &KmagApp::updateRotationValue, m_zoomView, &KMagZoomView::setRotation);
0263   connect(this, &KmagApp::updateFPSValue, m_zoomView, &KMagZoomView::setRefreshRate);
0264   connect(this, &KmagApp::updateColorValue, m_zoomView, &KMagZoomView::setColorMode);
0265 
0266   // change in zoom index -> update the selector
0267   connect(this, &KmagApp::updateZoomIndex, this, &KmagApp::slotChangeZoomBoxIndex);
0268   connect(this, &KmagApp::updateRotationIndex, this, &KmagApp::slotChangeRotationBoxIndex);
0269   connect(this, &KmagApp::updateFPSIndex, this, &KmagApp::slotChangeFPSIndex);
0270   connect(this, &KmagApp::updateColorIndex, this, &KmagApp::slotChangeColorIndex);
0271 
0272   // selector selects a zoom index -> set the zoom index
0273   connect(m_pZoomBox, &KSelectAction::indexTriggered, this, &KmagApp::setZoomIndex);
0274   connect(m_pRotationBox, &KSelectAction::indexTriggered, this, &KmagApp::setRotationIndex);
0275   connect(m_pFPSBox, &KSelectAction::indexTriggered, this, &KmagApp::setFPSIndex);
0276   connect(m_pColorBox, &KSelectAction::indexTriggered, this, &KmagApp::setColorIndex);
0277 }
0278 
0279 /**
0280  * Save options to config file.
0281  */
0282 void KmagApp::saveOptions()
0283 {
0284   KConfigGroup cg( config, QStringLiteral("General Options"));
0285   cg.writeEntry("Geometry", size());
0286   cg.writeEntry("ZoomIndex", m_zoomIndex);
0287   cg.writeEntry("RotationIndex", m_rotationIndex);
0288   cg.writeEntry("FPSIndex", m_fpsIndex);
0289   cg.writeEntry("ColorIndex", m_colorIndex);
0290   cg.writeEntry("SelRect", m_zoomView->getSelRectPos());
0291   cg.writeEntry("ShowMouse", m_zoomView->getShowMouseType());
0292   cg.writeEntry("StaysOnTop", m_staysOnTop->isChecked());
0293 
0294   if (m_modeFollowMouse->isChecked())
0295      cg.writeEntry("Mode", "followmouse");
0296 #if HAVE_QACCESSIBILITYCLIENT
0297   else if (m_modeFollowFocus->isChecked())
0298      cg.writeEntry("Mode", "followfocus");
0299 #endif
0300   else if (m_modeWholeScreen->isChecked())
0301      cg.writeEntry("Mode", "wholescreen");
0302   else if (m_modeSelWin->isChecked())
0303      cg.writeEntry("Mode", "selectionwindow");
0304 }
0305 
0306 
0307 /**
0308  * Read settings from config file.
0309  */
0310 void KmagApp::readOptions()
0311 {
0312   QColor blue (0,0,128);
0313   QColor yellow (255,255,0);
0314   QColor white (255,255,255);
0315 
0316   KConfigGroup cgWM( config, QStringLiteral("WM"));
0317   setTitleColors (
0318       cgWM.readEntry("inactiveBackground", blue),
0319       cgWM.readEntry("inactiveForeground", white),
0320       cgWM.readEntry("inactiveTitleBtnBg", yellow));
0321 
0322   KConfigGroup cg(config, QStringLiteral("General Options"));
0323 
0324   QSize defSize(460,390);
0325   QSize size=cg.readEntry("Geometry", defSize);
0326   if(!size.isEmpty())
0327   {
0328     resize(size);
0329   }
0330 
0331   // set zoom - defaults to 2x
0332   unsigned int zoomIndex = cg.readEntry("ZoomIndex", 4);
0333   setZoomIndex(zoomIndex);
0334   Q_EMIT updateZoomIndex(m_zoomIndex);
0335 
0336   unsigned int rotationIndex = cg.readEntry("RotationIndex", 0);
0337   setRotationIndex(rotationIndex);
0338   Q_EMIT updateRotationIndex(m_rotationIndex);
0339 
0340   unsigned int fpsIndex = cg.readEntry("FPSIndex", 2);
0341   setFPSIndex(fpsIndex);
0342   Q_EMIT updateFPSIndex(m_fpsIndex);
0343 
0344   unsigned int colorIndex = cg.readEntry("ColorIndex", 0);
0345   setColorIndex(colorIndex);
0346   Q_EMIT updateColorIndex(colorIndex);
0347 
0348   QString mode = cg.readEntry("Mode", "followmouse");
0349   if (mode == QLatin1String( "wholescreen" )) {
0350     slotModeWholeScreen();
0351   } else if (mode == QLatin1String( "selectionwindow" )) {
0352     slotModeSelWin();
0353   } else if (mode == QLatin1String( "followfocus" )) {
0354     m_modeFollowFocus->setChecked(true);
0355     slotModeChanged();
0356   } else {
0357     m_modeFollowMouse->setChecked(true);
0358     slotModeChanged();
0359   }
0360 
0361   QRect defaultRect(0,0,211,164);
0362   m_zoomView->setSelRectPos(cg.readEntry("SelRect", defaultRect));
0363 
0364   m_mouseCursorType = cg.readEntry("ShowMouse", m_defaultMouseCursorType);
0365   m_zoomView->showMouse(m_mouseCursorType);
0366   m_hideCursor->setChecked(!m_mouseCursorType);
0367 
0368   m_staysOnTop->setChecked(cg.readEntry("StaysOnTop", true));
0369   slotStaysOnTop();
0370 
0371   // XMLGui has already read and set up the menuBar for us
0372   m_pShowMenu->setChecked(menuBar()->isVisible());
0373 }
0374 
0375 bool KmagApp::queryClose()
0376 {
0377   saveOptions();
0378   return (true);
0379 }
0380 
0381 /**
0382  * Called when mouse is clicked inside the window
0383  *
0384  * @param e
0385  */
0386 void KmagApp::contextMenuEvent ( QContextMenuEvent * e )
0387 {
0388  // show popup
0389  KXMLGUIFactory *factory = this->factory();
0390  QMenu *popup = (QMenu *)factory->container(QStringLiteral( "mainPopUp" ),this);
0391  if (popup != nullptr)
0392    popup->popup(e->globalPos());
0393  e->accept();
0394 }
0395 
0396 
0397 /////////////////////////////////////////////////////////////////////
0398 // SLOT IMPLEMENTATION
0399 /////////////////////////////////////////////////////////////////////
0400 
0401 /**
0402  * Shows/hides the mouse cursor
0403  */
0404 void KmagApp::showMouseCursor(bool show)
0405 {
0406   if(show) {
0407     if(m_mouseCursorType == 0)
0408       m_mouseCursorType = m_defaultMouseCursorType;
0409     m_zoomView->showMouse(m_mouseCursorType);
0410   } else {
0411     m_zoomView->showMouse(0);
0412   }
0413 }
0414 
0415 /**
0416  * Zoom in.
0417  */
0418 void KmagApp::zoomIn()
0419 {
0420   // set the new index .. checking will done inside setZoom
0421   setZoomIndex(m_zoomIndex+1);
0422   // signal change in zoom index
0423   Q_EMIT updateZoomIndex((int)m_zoomIndex);
0424 }
0425 
0426 /**
0427  * Zoom out.
0428  */
0429 void KmagApp::zoomOut()
0430 {
0431   // set the new index .. checking will done inside setZoom
0432   setZoomIndex(m_zoomIndex-1);
0433   // signal change in zoom index
0434   Q_EMIT updateZoomIndex((int)m_zoomIndex);
0435 }
0436 /**
0437  * Sets the zoom index to index
0438  */
0439 void KmagApp::setZoomIndex(int index)
0440 {
0441   if(index < 0 || index >= (int)zoomArray.size()) {
0442     // the index is invalid
0443     qDebug() << "Invalid index!" ;
0444     return;
0445   } else if((int)m_zoomIndex == index) {
0446     // do nothing!
0447     return;
0448   } else {
0449     m_zoomIndex = index;
0450   }
0451 
0452   if(m_zoomIndex == 0) {
0453     // meaning that no more zooming-out is possible
0454     // -> disable zoom-out icon
0455     m_pZoomOut->setEnabled(false);
0456   } else { // enable the icon
0457     m_pZoomOut->setEnabled(true);
0458   }
0459 
0460   if((int)m_zoomIndex == zoomArray.size()-1) {
0461     // meaning that no more zooming-in is possible
0462     // -> disable zoom-in icon
0463     m_pZoomIn->setEnabled(false);
0464   } else { // enable the icon
0465     m_pZoomIn->setEnabled(true);
0466   }
0467 
0468   // signal change in zoom value
0469   Q_EMIT updateZoomValue(zoomArray.at(m_zoomIndex));
0470 }
0471 
0472 /**
0473  * Sets the rotation index to index
0474  */
0475 void KmagApp::setRotationIndex(int index)
0476 {
0477   if(index < 0 || index >= (int)rotationArray.size()) {
0478     // the index is invalid
0479     qDebug() << "Invalid index!" ;
0480     return;
0481   } else if((int)m_rotationIndex == index) {
0482     // do nothing!
0483     return;
0484   } else {
0485     m_rotationIndex = index;
0486   }
0487 
0488   // signal change in zoom value
0489   Q_EMIT updateRotationValue(rotationArray.at(m_rotationIndex));
0490 }
0491 
0492 /**
0493  * Sets the fps index to index
0494  */
0495 void KmagApp::setFPSIndex(int index)
0496 {
0497   if(index < 0 || index >= (int)fpsArray.size()) {
0498     // the index is invalid
0499     qDebug() << "Invalid index!" ;
0500     return;
0501   } else if((int)m_fpsIndex == index) {
0502     // do nothing!
0503     return;
0504   } else {
0505     m_fpsIndex = index;
0506   }
0507 
0508   // signal change in fps value
0509   Q_EMIT updateFPSValue(fpsArray.at(m_fpsIndex));
0510 }
0511 
0512 /**
0513  * Sets the color index to index
0514  */
0515 void KmagApp::setColorIndex(int index)
0516 {
0517   if(index < 0 || index >= (int)colorArray.size()) {
0518     // the index is invalid
0519     qDebug() << "Invalid index!" ;
0520     return;
0521   } else if((int)m_colorIndex == index) {
0522     // do nothing!
0523     return;
0524   } else {
0525     m_colorIndex = index;
0526   }
0527 
0528   // signal change in fps value
0529   Q_EMIT updateColorValue(colorArray.at(m_colorIndex));
0530 }
0531 
0532 /**
0533  * Save the zoomed image
0534  */
0535 void KmagApp::saveZoomPixmap()
0536 {
0537   bool toggled(false);
0538 
0539   // stop refresh temporarily
0540   if (m_zoomView->getRefreshStatus()) {
0541     slotToggleRefresh();
0542     toggled = true;
0543   }
0544 
0545   QStringList mimeTypes;
0546   const QList<QByteArray> supported = QImageWriter::supportedMimeTypes();
0547   for (const QByteArray& mimeType : supported) {
0548     mimeTypes.append(QString::fromLatin1(mimeType));
0549   }
0550 
0551   QFileDialog fileDialog(this);
0552   fileDialog.setWindowTitle(i18n("Save Snapshot As"));
0553   fileDialog.setAcceptMode(QFileDialog::AcceptSave);
0554   fileDialog.setDefaultSuffix(QStringLiteral("png"));
0555   fileDialog.setMimeTypeFilters(mimeTypes);
0556   QUrl url;
0557   if (fileDialog.exec() && !fileDialog.selectedUrls().isEmpty()) {
0558       url = fileDialog.selectedUrls().at(0);
0559   }
0560 
0561   if(!url.fileName().isEmpty()) {
0562     if(!url.isLocalFile()) {
0563       // create a temp file.. save image to it.. copy over the n/w and then delete the temp file.
0564       QTemporaryFile tempFile;
0565       if(!tempFile.open() || !m_zoomView->getImage().save(tempFile.fileName())) {
0566         KMessageBox::error(nullptr, i18n("Unable to save temporary file (before uploading to the network file you specified)."),
0567                           i18n("Error Writing File"));
0568       } else {
0569         KIO::FileCopyJob *job = KIO::file_copy(QUrl::fromLocalFile(tempFile.fileName()), url);
0570         if(!job) {
0571           KMessageBox::error(nullptr, i18n("Unable to upload file over the network."),
0572                             i18n("Error Writing File"));
0573         } else {
0574           KMessageBox::information(nullptr, i18n("Current zoomed image saved to\n%1", url.toDisplayString()),
0575                               i18n("Information"), QStringLiteral( "save_confirm" ));
0576         }
0577       }
0578 
0579     } else {
0580       if(!m_zoomView->getImage().save(url.path())) {
0581         KMessageBox::error(nullptr, i18n("Unable to save file. Please check if you have permission to write to the directory."),
0582                             i18n("Error Writing File"));
0583       } else {
0584         KMessageBox::information(nullptr, i18n("Current zoomed image saved to\n%1", url.toDisplayString()),
0585                                 i18n("Information"), QStringLiteral( "save_confirm" ));
0586       }
0587     }
0588   }
0589   if(toggled) {
0590     slotToggleRefresh();
0591   }
0592 }
0593 
0594 
0595 void KmagApp::slotToggleRefresh()
0596 {
0597   m_zoomView->toggleRefresh();
0598   if(m_zoomView->getRefreshStatus()) {
0599     refreshSwitch->setIcon(QIcon::fromTheme(QStringLiteral( "process-stop" )));
0600     refreshSwitch->setText(i18n("Stop"));
0601     refreshSwitch->setToolTip(i18n("Click to stop window update"));
0602   } else {
0603     refreshSwitch->setIcon(QIcon::fromTheme(QStringLiteral( "system-run" )));
0604     refreshSwitch->setText(i18nc("Start updating the window", "Start"));
0605     refreshSwitch->setToolTip(i18n("Click to start window update"));
0606   }
0607 }
0608 
0609 
0610 void KmagApp::slotModeWholeScreen()
0611 {
0612   m_zoomView->followMouse(false);
0613   m_zoomView->setSelRectPos(screen()->virtualGeometry());
0614   m_zoomView->showSelRect(false);
0615   m_zoomView->setFitToWindow (false);
0616   m_modeFollowMouse->setChecked(false);
0617 #if HAVE_QACCESSIBILITYCLIENT
0618   m_zoomView->followBoth(false);
0619   m_zoomView->followFocus(false);
0620   m_modeFollowFocus->setChecked(false);
0621 #endif
0622   m_modeWholeScreen->setChecked(true);
0623   m_modeSelWin->setChecked(false);
0624 }
0625 
0626 
0627 void KmagApp::slotModeSelWin()
0628 {
0629   m_zoomView->followMouse(false);
0630   m_zoomView->showSelRect(true);
0631   m_zoomView->setFitToWindow (false);
0632   m_modeFollowMouse->setChecked(false);
0633 #if HAVE_QACCESSIBILITYCLIENT
0634   m_zoomView->followBoth(false);
0635   m_zoomView->followFocus(false);
0636   m_modeFollowFocus->setChecked(false);
0637 #endif
0638   m_modeWholeScreen->setChecked(false);
0639   m_modeSelWin->setChecked(true);
0640 }
0641 
0642 void KmagApp::slotModeChanged()
0643 {
0644 #if HAVE_QACCESSIBILITYCLIENT
0645   if(m_modeFollowMouse->isChecked() && m_modeFollowFocus->isChecked()) {
0646 
0647     //BOTH MODE
0648     m_zoomView->followMouse(false);
0649     m_zoomView->followBoth(true);
0650     m_zoomView->followFocus(false);
0651     m_zoomView->showSelRect(false);
0652     m_zoomView->setFitToWindow (true);
0653     m_modeWholeScreen->setChecked(false);
0654     m_modeSelWin->setChecked(false);
0655     return;
0656   }
0657 #endif
0658 
0659   if (m_modeFollowMouse->isChecked()) {
0660 
0661     //MOUSE MODE
0662     m_zoomView->followMouse(true);
0663     m_zoomView->showSelRect(false);
0664     m_zoomView->setFitToWindow (true);
0665     m_modeFollowMouse->setChecked(true);
0666 #if HAVE_QACCESSIBILITYCLIENT
0667     m_zoomView->followBoth(false);
0668     m_zoomView->followFocus(false);
0669     m_modeFollowFocus->setChecked(false);
0670 #endif
0671     m_modeWholeScreen->setChecked(false);
0672     m_modeSelWin->setChecked(false);
0673 
0674 #if HAVE_QACCESSIBILITYCLIENT
0675   } else if (m_modeFollowFocus->isChecked()) {
0676 
0677     //FOCUS MODE
0678     m_zoomView->followBoth(false);
0679     m_zoomView->followMouse(false);
0680     m_zoomView->followFocus(true);
0681     m_zoomView->showSelRect(false);
0682     m_zoomView->setFitToWindow (true);
0683     m_modeFollowMouse->setChecked(false);
0684     m_modeFollowFocus->setChecked(true);
0685     m_modeWholeScreen->setChecked(false);
0686     m_modeSelWin->setChecked(false);
0687 #endif
0688 
0689   }
0690 }
0691 
0692 void KmagApp::slotToggleHideCursor()
0693 {
0694   showMouseCursor(!m_hideCursor->isChecked());
0695 }
0696 
0697 
0698 void KmagApp::slotStaysOnTop()
0699 {
0700   if (m_staysOnTop->isChecked())
0701       setWindowFlags( windowFlags() | Qt::WindowStaysOnTopHint );
0702   else
0703       setWindowFlags( windowFlags() & ~Qt::WindowStaysOnTopHint );
0704   show();
0705 }
0706 
0707 
0708 void KmagApp::slotFileNewWindow()
0709 {
0710   KmagApp *new_window= new KmagApp();
0711   new_window->show();
0712 }
0713 
0714 
0715 void KmagApp::slotFilePrint()
0716 {
0717 #ifndef QT_NO_PRINTER
0718 
0719   bool toggled(false);
0720 
0721   if (m_printer == nullptr) {
0722     m_printer = new QPrinter();
0723   }
0724 
0725   // stop refresh temporarily
0726   if (m_zoomView->getRefreshStatus()) {
0727     slotToggleRefresh();
0728     toggled = true;
0729   }
0730 
0731   const QImage pixmap(m_zoomView->getImage());
0732 
0733   // use some AI to get the best orientation
0734   if(pixmap.width() > pixmap.height()) {
0735     m_printer->setPageOrientation(QPageLayout::Landscape);
0736   } else {
0737     m_printer->setPageOrientation(QPageLayout::Portrait);
0738   }
0739 
0740   QPrintDialog *printDialog = new QPrintDialog(m_printer, this);
0741 
0742   if (printDialog->exec()) {
0743     QPainter paint;
0744 
0745     if(!paint.begin(m_printer))
0746     {
0747       delete printDialog;
0748       return;
0749     }
0750     // draw the pixmap
0751     paint.drawImage(0, 0, pixmap);
0752     // end the painting
0753     paint.end();
0754   }
0755 
0756   if(toggled) {
0757     slotToggleRefresh();
0758   }
0759   delete printDialog;
0760 #endif // QT_NO_PRINTER
0761 }
0762 
0763 void KmagApp::slotFileQuit()
0764 {
0765   saveOptions();
0766   // close the first window, the list makes the next one the first again.
0767   // This ensures that queryClose() is called on each window to ask for closing
0768   KMainWindow* w;
0769   if (!memberList().isEmpty())
0770   {
0771     for (int i = 0; i < memberList().size(); ++i)
0772     {
0773       w = memberList().at(i);
0774       // only close the window if the closeEvent is accepted. If the user presses Cancel on the saveModified() dialog,
0775       // the window and the application stay open.
0776       if(!w->close())
0777          break;
0778 #ifdef __GNUC__
0779 #warning "kde4: now memberList() is constant => we can't remove some element!"
0780 #endif
0781     //memberList()->removeRef(w);
0782     }
0783   }
0784 }
0785 
0786 void KmagApp::copyToClipBoard()
0787 {
0788   QClipboard *cb=QApplication::clipboard();
0789   cb->setPixmap(QPixmap::fromImage(m_zoomView->getImage()));
0790 }
0791 
0792 void KmagApp::slotShowMenu()
0793 {
0794   ///////////////////////////////////////////////////////////////////
0795   // turn Menu on or off
0796   if(!m_pShowMenu->isChecked())
0797   {
0798     menuBar()->hide();
0799   }
0800   else
0801   {
0802     menuBar()->show();
0803   }
0804 }
0805 
0806 void KmagApp::slotConfKeys()
0807 {
0808   KShortcutsDialog::showDialog(actionCollection(), KShortcutsEditor::LetterShortcutsAllowed, this);
0809 }
0810 
0811 void KmagApp::slotEditToolbars()
0812 {
0813   KConfigGroup cg( KSharedConfig::openConfig(), QStringLiteral("MainWindow") );
0814   saveMainWindowSettings( cg );
0815   QPointer<KEditToolBar> dlg = new KEditToolBar( actionCollection() );
0816   connect(dlg.data(), &KEditToolBar::newToolBarConfig, this, &KmagApp::slotNewToolbarConfig );
0817   if ( dlg->exec() )
0818     createGUI();
0819   delete dlg;
0820 }
0821 
0822 
0823 void KmagApp::slotNewToolbarConfig()
0824 {
0825   applyMainWindowSettings( KSharedConfig::openConfig()->group( QStringLiteral("MainWindow") ) );
0826   createGUI();
0827 }
0828 
0829 #include "moc_kmag.cpp"