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"