1 | /*************************************************************************** |
2 | kmag.cpp - description |
3 | ------------------- |
4 | begin : Mon Feb 12 23:45:41 EST 2001 |
5 | copyright : (C) 2001-2003 by Sarang Lakare |
6 | email : sarang#users.sourceforge.net |
7 | copyright : (C) 2003-2004 by Olaf Schmidt |
8 | email : ojschmidt@kde.org |
9 | copyright : (C) 2008 by Matthew Woehlke |
10 | email : mw_triad@users.sourceforge.net |
11 | copyright (C) 2010 Sebastian Sauer |
12 | email sebsauer@kdab.com |
13 | ***************************************************************************/ |
14 | |
15 | /*************************************************************************** |
16 | * * |
17 | * This program is free software; you can redistribute it and/or modify * |
18 | * it under the terms of the GNU General Public License as published by * |
19 | * the Free Software Foundation; either version 2 of the License, or * |
20 | * (at your option) any later version. * |
21 | * * |
22 | ***************************************************************************/ |
23 | |
24 | // include files for QT |
25 | #include <QtCore/QDir> |
26 | #include <QtCore/QPointer> |
27 | #include <QtGui/QPrintDialog> |
28 | #include <QtGui/QPainter> |
29 | #include <QtGui/QLayout> |
30 | #include <QtGui/QClipboard> |
31 | #include <QtGui/QContextMenuEvent> |
32 | #include <QtGui/QPixmap> |
33 | #include <QtGui/QDesktopWidget> |
34 | |
35 | // include files for KDE |
36 | #include <kxmlguiclient.h> |
37 | #include <ktoolbar.h> |
38 | #include <ktoggleaction.h> |
39 | #include <kactioncollection.h> |
40 | #include <kselectaction.h> |
41 | #include <kdeversion.h> |
42 | #include <kxmlguifactory.h> |
43 | #include <kicon.h> |
44 | #include <kapplication.h> |
45 | #include <kstandardshortcut.h> |
46 | #include <kshortcutsdialog.h> |
47 | #include <kiconloader.h> |
48 | #include <kmessagebox.h> |
49 | #include <kfiledialog.h> |
50 | #include <kmenubar.h> |
51 | #include <klocale.h> |
52 | #include <kconfig.h> |
53 | #include <kdebug.h> |
54 | #include <kstandardaction.h> |
55 | #include <khelpmenu.h> |
56 | #include <kimageio.h> |
57 | #include <kio/job.h> |
58 | #include <kio/netaccess.h> |
59 | #include <ktemporaryfile.h> |
60 | #include <kmenu.h> |
61 | #include <kedittoolbar.h> |
62 | #include <kglobal.h> |
63 | #include <kdeprintdialog.h> |
64 | |
65 | // application specific includes |
66 | #include "kmag.moc" |
67 | #include "kmagzoomview.h" |
68 | #include "kmagselrect.h" |
69 | |
70 | |
71 | KmagApp::KmagApp(QWidget* , const char* name) |
72 | : KXmlGuiWindow(0) // Qt::WStyle_MinMax | Qt::WType_TopLevel | Qt::WDestructiveClose | Qt::WStyle_ContextHelp | Qt::WindowCloseButtonHint | Qt::WStyle_StaysOnTop |
73 | , m_defaultMouseCursorType(2) |
74 | { |
75 | setObjectName( QLatin1String( name ) ); |
76 | setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); |
77 | config=KGlobal::config(); |
78 | |
79 | zoomArrayString << QLatin1String( "5:1" ) << QLatin1String( "2:1" ) << QLatin1String( "1:1" ) << QLatin1String( "1:1.5" ) << QLatin1String( "1:2" ) << QLatin1String( "1:3" ) << QLatin1String( "1:4" ) << QLatin1String( "1:5" ) |
80 | << QLatin1String( "1:6" ) << QLatin1String( "1:7" ) << QLatin1String( "1:8" ) << QLatin1String( "1:12" ) << QLatin1String( "1:16" ) << QLatin1String( "1:20" ); |
81 | |
82 | zoomArray << 0.2 <<0.5 << 1.0; |
83 | zoomArray << 1.5 << 2.0 << 3.0; |
84 | zoomArray << 4.0 << 5.0 << 6.0 << 7.0; |
85 | zoomArray << 8.0 << 12.0 << 16.0 << 20.0; |
86 | |
87 | 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" ); |
88 | |
89 | fpsArray.append(2); // very low |
90 | fpsArray.append(6); // low |
91 | fpsArray.append(10); // medium |
92 | fpsArray.append(15); // high |
93 | fpsArray.append(25); // very high |
94 | |
95 | colorArrayString << i18nc("No color-blindness simulation, i.e. 'normal' vision" , "&Normal" ) << i18n("&Protanopia" ) << i18n("&Deuteranopia" ) << i18n("&Tritanopia" ) << i18n("&Achromatopsia" ); |
96 | |
97 | colorArray.append(0); |
98 | colorArray.append(1); |
99 | colorArray.append(2); |
100 | colorArray.append(3); |
101 | colorArray.append(4); |
102 | |
103 | rotationArrayString << i18n("&No Rotation (0 Degrees)" ) << i18n("&Left (90 Degrees)" ) << i18n("&Upside Down (180 Degrees)" ) << i18n("&Right (270 Degrees)" ); |
104 | |
105 | rotationArray.append(0); // no rotation |
106 | rotationArray.append(90); // left |
107 | rotationArray.append(180); // upside down |
108 | rotationArray.append(270); // right |
109 | |
110 | // call inits to invoke all other construction parts |
111 | initView(); |
112 | initActions(); |
113 | initConnections(); |
114 | |
115 | // read options from config file |
116 | readOptions(); |
117 | |
118 | #ifndef QT_NO_PRINTER |
119 | m_printer = 0; |
120 | #endif // QT_NO_PRINTER |
121 | } |
122 | |
123 | /** |
124 | * Default destructor. |
125 | */ |
126 | KmagApp::~KmagApp() |
127 | { |
128 | m_zoomView->showSelRect(false); |
129 | |
130 | #ifndef QT_NO_PRINTER |
131 | delete m_printer; |
132 | #endif // QT_NO_PRINTER |
133 | } |
134 | |
135 | void KmagApp::initActions() |
136 | { |
137 | fileNewWindow = actionCollection()->addAction(QLatin1String( "new_window" )); |
138 | fileNewWindow->setIcon(KIcon(QLatin1String( "window-new" ))); |
139 | fileNewWindow->setText(i18n("New &Window" )); |
140 | connect(fileNewWindow, SIGNAL(triggered(bool)), SLOT(slotFileNewWindow())); |
141 | fileNewWindow->setShortcuts(KStandardShortcut::openNew()); |
142 | fileNewWindow->setToolTip(i18n("Open a new KMagnifier window" )); |
143 | |
144 | refreshSwitch = actionCollection()->addAction(QLatin1String( "start_stop_refresh" )); |
145 | refreshSwitch->setIcon(KIcon(QLatin1String( "process-stop" ))); |
146 | refreshSwitch->setText(i18n("&Stop" )); |
147 | connect(refreshSwitch, SIGNAL(triggered(bool)), SLOT(slotToggleRefresh())); |
148 | refreshSwitch->setShortcuts(KStandardShortcut::reload()); |
149 | refreshSwitch->setToolTip(i18n("Click to stop window refresh" )); |
150 | refreshSwitch->setWhatsThis(i18n("Clicking on this icon will <b>start</b> / <b>stop</b> " |
151 | "updating of the display. Stopping the update will zero the processing power " |
152 | "required (CPU usage)" )); |
153 | |
154 | m_pSnapshot = actionCollection()->addAction(QLatin1String( "snapshot" )); |
155 | m_pSnapshot->setIcon(KIcon(QLatin1String( "ksnapshot" ))); |
156 | m_pSnapshot->setText(i18n("&Save Snapshot As..." )); |
157 | connect(m_pSnapshot, SIGNAL(triggered(bool)), SLOT(saveZoomPixmap())); |
158 | m_pSnapshot->setShortcuts(KStandardShortcut::save()); |
159 | m_pSnapshot->setWhatsThis(i18n("Saves the zoomed view to an image file." )); |
160 | m_pSnapshot->setToolTip(i18n("Save image to a file" )); |
161 | |
162 | m_pPrint = actionCollection()->addAction(KStandardAction::Print, this, SLOT(slotFilePrint())); |
163 | m_pPrint->setWhatsThis(i18n("Click on this button to print the current zoomed view." )); |
164 | |
165 | m_pQuit = actionCollection()->addAction(KStandardAction::Quit, this, SLOT(slotFileQuit())); |
166 | m_pQuit->setToolTip(i18n("Quits the application" )); |
167 | m_pQuit->setWhatsThis (i18n("Quits the application" )); |
168 | |
169 | m_pCopy = actionCollection()->addAction(KStandardAction::Copy, this, SLOT(copyToClipBoard())); |
170 | m_pCopy->setWhatsThis(i18n("Click on this button to copy the current zoomed view to the clipboard which you can paste in other applications." )); |
171 | m_pCopy->setToolTip(i18n("Copy zoomed image to clipboard" )); |
172 | |
173 | m_pShowMenu = KStandardAction::showMenubar(this, SLOT(slotShowMenu()), actionCollection()); |
174 | |
175 | setStandardToolBarMenuEnabled(true); |
176 | |
177 | m_modeFollowMouse = new KToggleAction(KIcon(QLatin1String( "followmouse" )), i18n("&Follow Mouse Mode" ), this); |
178 | actionCollection()->addAction(QLatin1String( "mode_followmouse" ), m_modeFollowMouse); |
179 | connect(m_modeFollowMouse, SIGNAL(triggered(bool)), SLOT(slotModeChanged())); |
180 | m_modeFollowMouse->setShortcut(Qt::Key_F2); |
181 | m_modeFollowMouse->setIconText(i18n("Mouse" )); |
182 | m_modeFollowMouse->setToolTip(i18n("Magnify around the mouse cursor" )); |
183 | m_modeFollowMouse->setWhatsThis(i18n("If selected, the area around the mouse cursor is magnified" )); |
184 | |
185 | #ifdef QAccessibilityClient_FOUND |
186 | |
187 | m_modeFollowFocus = new KToggleAction(KIcon(QLatin1String( "view-restore" )), i18n("&Follow Focus Mode" ), this); |
188 | actionCollection()->addAction(QLatin1String( "mode_followfocus" ), m_modeFollowFocus); |
189 | connect(m_modeFollowFocus, SIGNAL(triggered(bool)), SLOT(slotModeChanged())); |
190 | m_modeFollowFocus->setShortcut(Qt::Key_F2); |
191 | m_modeFollowFocus->setIconText(i18n("Focus" )); |
192 | m_modeFollowFocus->setToolTip(i18n("Magnify around the keyboard focus" )); |
193 | m_modeFollowFocus->setWhatsThis(i18n("If selected, the area around the keyboard cursor is magnified" )); |
194 | |
195 | #endif |
196 | |
197 | m_modeSelWin = new KToggleAction(KIcon(QLatin1String( "window" )), i18n("Se&lection Window Mode" ), this); |
198 | actionCollection()->addAction(QLatin1String( "mode_selectionwindow" ), m_modeSelWin); |
199 | connect(m_modeSelWin, SIGNAL(triggered(bool)), SLOT(slotModeSelWin())); |
200 | m_modeSelWin->setShortcut(Qt::Key_F3); |
201 | m_modeSelWin->setIconText(i18n("Window" )); |
202 | m_modeSelWin->setToolTip(i18n("Show a window for selecting the magnified area" )); |
203 | |
204 | m_modeWholeScreen = new KToggleAction(KIcon(QLatin1String( "view-fullscreen" )), i18n("&Whole Screen Mode" ), this); |
205 | actionCollection()->addAction(QLatin1String( "mode_wholescreen" ), m_modeWholeScreen); |
206 | connect(m_modeWholeScreen, SIGNAL(triggered(bool)), SLOT(slotModeWholeScreen())); |
207 | m_modeWholeScreen->setShortcut(Qt::Key_F4); |
208 | m_modeWholeScreen->setIconText(i18n("Screen" )); |
209 | m_modeWholeScreen->setToolTip(i18n("Magnify the whole screen" )); |
210 | m_modeWholeScreen->setWhatsThis(i18n("Click on this button to fit the zoom view to the zoom window." )); |
211 | |
212 | m_hideCursor = new KToggleAction(KIcon(QLatin1String( "hidemouse" )), i18n("Hide Mouse &Cursor" ), this); |
213 | actionCollection()->addAction(QLatin1String( "hidecursor" ), m_hideCursor); |
214 | connect(m_hideCursor, SIGNAL(triggered(bool)), SLOT(slotToggleHideCursor())); |
215 | m_hideCursor->setShortcut(Qt::Key_F6); |
216 | #ifdef havesetCheckedStatef |
217 | m_hideCursor->setCheckedState(KGuiItem(i18n("Show Mouse &Cursor" ))); |
218 | #endif |
219 | m_hideCursor->setIconText(i18n("Hide" )); |
220 | m_hideCursor->setToolTip(i18n("Hide the mouse cursor" )); |
221 | |
222 | m_staysOnTop = new KToggleAction(KIcon(QLatin1String( "go-top" )), i18n("Stays On Top" ), this); |
223 | actionCollection()->addAction(QLatin1String( "staysontop" ), m_staysOnTop); |
224 | connect(m_staysOnTop, SIGNAL(triggered(bool)), SLOT(slotStaysOnTop())); |
225 | m_staysOnTop->setShortcut(Qt::Key_F7); |
226 | m_staysOnTop->setToolTip(i18n("The KMagnifier Window stays on top of other windows." )); |
227 | |
228 | m_pZoomIn = actionCollection()->addAction(KStandardAction::ZoomIn, this, SLOT(zoomIn())); |
229 | m_pZoomIn->setWhatsThis(i18n("Click on this button to <b>zoom-in</b> on the selected region." )); |
230 | |
231 | m_pZoomBox = new KSelectAction(i18n("&Zoom" ), this); |
232 | actionCollection()->addAction(QLatin1String( "zoom" ), m_pZoomBox); |
233 | m_pZoomBox->setItems(zoomArrayString); |
234 | m_pZoomBox->setWhatsThis(i18n("Select the zoom factor." )); |
235 | m_pZoomBox->setToolTip(i18n("Zoom factor" )); |
236 | |
237 | m_pZoomOut = actionCollection()->addAction(KStandardAction::ZoomOut, this, SLOT(zoomOut())); |
238 | m_pZoomOut->setWhatsThis(i18n("Click on this button to <b>zoom-out</b> on the selected region." )); |
239 | |
240 | m_pRotationBox = new KSelectAction(i18n("&Rotation" ),this); |
241 | actionCollection()->addAction(QLatin1String( "rotation" ), m_pRotationBox); |
242 | m_pRotationBox->setItems(rotationArrayString); |
243 | m_pRotationBox->setWhatsThis(i18n("Select the rotation degree." )); |
244 | m_pRotationBox->setToolTip(i18n("Rotation degree" )); |
245 | |
246 | // KHelpMenu *newHelpMenu = new KHelpMenu(this, KGlobal::mainComponent().aboutData()); |
247 | |
248 | m_keyConf = actionCollection()->addAction(KStandardAction::KeyBindings, this, SLOT(slotConfKeys())); |
249 | m_toolConf = actionCollection()->addAction(KStandardAction::ConfigureToolbars, this, SLOT(slotEditToolbars())); |
250 | |
251 | m_pFPSBox = new KSelectAction(i18n("&Refresh" ),this); |
252 | actionCollection()->addAction(QLatin1String( "fps_selector" ), m_pFPSBox); |
253 | m_pFPSBox->setItems(fpsArrayString); |
254 | m_pFPSBox->setWhatsThis(i18n("Select the refresh rate. The higher the rate, the more computing power (CPU) will be needed." )); |
255 | m_pFPSBox->setToolTip(i18n("Refresh rate" )); |
256 | |
257 | m_pColorBox = new KSelectAction(i18nc("Color-blindness simulation mode" , "&Color" ),this); |
258 | actionCollection()->addAction(QLatin1String( "color_mode" ), m_pColorBox); |
259 | m_pColorBox->setItems(colorArrayString); |
260 | m_pColorBox->setWhatsThis(i18n("Select a mode to simulate various types of color-blindness." )); |
261 | m_pColorBox->setToolTip(i18n("Color-blindness Simulation Mode" )); |
262 | |
263 | setupGUI(ToolBar | Keys | Save | Create); |
264 | } |
265 | |
266 | void KmagApp::initView() |
267 | { |
268 | m_zoomView = new KMagZoomView( this, "ZoomView" ); |
269 | //m_zoomView->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)7, (QSizePolicy::SizeType)7, m_zoomView->sizePolicy().hasHeightForWidth() ) ); |
270 | m_zoomView->setFrameShape( QFrame::NoFrame ); |
271 | |
272 | setCentralWidget(m_zoomView); |
273 | } |
274 | |
275 | |
276 | void KmagApp::slotChangeZoomBoxIndex(int index) |
277 | { |
278 | m_pZoomBox->setCurrentItem(index); |
279 | } |
280 | |
281 | void KmagApp::slotChangeRotationBoxIndex(int index) |
282 | { |
283 | m_pRotationBox->setCurrentItem(index); |
284 | } |
285 | |
286 | void KmagApp::slotChangeFPSIndex(int index) |
287 | { |
288 | m_pFPSBox->setCurrentItem(index); |
289 | } |
290 | |
291 | void KmagApp::slotChangeColorIndex(int index) |
292 | { |
293 | m_pColorBox->setCurrentItem(index); |
294 | } |
295 | |
296 | /** |
297 | * Initialize all connections. |
298 | */ |
299 | void KmagApp::initConnections() |
300 | { |
301 | // change in zoom value -> update the view |
302 | connect(this, SIGNAL(updateZoomValue(float)), m_zoomView, SLOT(setZoom(float))); |
303 | connect(this, SIGNAL(updateRotationValue(int)), m_zoomView, SLOT(setRotation(int))); |
304 | connect(this, SIGNAL(updateFPSValue(float)), m_zoomView, SLOT(setRefreshRate(float))); |
305 | connect(this, SIGNAL(updateColorValue(int)), m_zoomView, SLOT(setColorMode(int))); |
306 | |
307 | // change in zoom index -> update the selector |
308 | connect(this, SIGNAL(updateZoomIndex(int)), this, SLOT(slotChangeZoomBoxIndex(int))); |
309 | connect(this, SIGNAL(updateRotationIndex(int)), this, SLOT(slotChangeRotationBoxIndex(int))); |
310 | connect(this, SIGNAL(updateFPSIndex(int)), this, SLOT(slotChangeFPSIndex(int))); |
311 | connect(this, SIGNAL(updateColorIndex(int)), this, SLOT(slotChangeColorIndex(int))); |
312 | |
313 | // selector selects a zoom index -> set the zoom index |
314 | connect(m_pZoomBox, SIGNAL(triggered(int)), this, SLOT(setZoomIndex(int))); |
315 | connect(m_pRotationBox, SIGNAL(triggered(int)), this, SLOT(setRotationIndex(int))); |
316 | connect(m_pFPSBox, SIGNAL(triggered(int)), this, SLOT(setFPSIndex(int))); |
317 | connect(m_pColorBox, SIGNAL(triggered(int)), this, SLOT(setColorIndex(int))); |
318 | } |
319 | |
320 | /** |
321 | * Save options to config file. |
322 | */ |
323 | void KmagApp::saveOptions() |
324 | { |
325 | KConfigGroup cg( config, "General Options" ); |
326 | cg.writeEntry("Geometry" , size()); |
327 | cg.writeEntry("ZoomIndex" , m_zoomIndex); |
328 | cg.writeEntry("RotationIndex" , m_rotationIndex); |
329 | cg.writeEntry("FPSIndex" , m_fpsIndex); |
330 | cg.writeEntry("ColorIndex" , m_colorIndex); |
331 | cg.writeEntry("SelRect" , m_zoomView->getSelRectPos()); |
332 | cg.writeEntry("ShowMouse" , m_zoomView->getShowMouseType()); |
333 | cg.writeEntry("StaysOnTop" , m_staysOnTop->isChecked()); |
334 | |
335 | if (m_modeFollowMouse->isChecked()) |
336 | cg.writeEntry("Mode" , "followmouse" ); |
337 | #ifdef QAccessibilityClient_FOUND |
338 | else if (m_modeFollowFocus->isChecked()) |
339 | cg.writeEntry("Mode" , "followfocus" ); |
340 | #endif |
341 | else if (m_modeWholeScreen->isChecked()) |
342 | cg.writeEntry("Mode" , "wholescreen" ); |
343 | else if (m_modeSelWin->isChecked()) |
344 | cg.writeEntry("Mode" , "selectionwindow" ); |
345 | } |
346 | |
347 | |
348 | /** |
349 | * Read settings from config file. |
350 | */ |
351 | void KmagApp::readOptions() |
352 | { |
353 | QColor blue (0,0,128); |
354 | QColor yellow (255,255,0); |
355 | QColor white (255,255,255); |
356 | |
357 | KConfigGroup cgWM( config, "WM" ); |
358 | setTitleColors ( |
359 | cgWM.readEntry("inactiveBackground" , blue), |
360 | cgWM.readEntry("inactiveForeground" , white), |
361 | cgWM.readEntry("inactiveTitleBtnBg" , yellow)); |
362 | |
363 | KConfigGroup cg(config,"General Options" ); |
364 | |
365 | QSize defSize(460,390); |
366 | QSize size=cg.readEntry("Geometry" , defSize); |
367 | if(!size.isEmpty()) |
368 | { |
369 | resize(size); |
370 | } |
371 | |
372 | // set zoom - defaults to 2x |
373 | unsigned int zoomIndex = cg.readEntry("ZoomIndex" , 4); |
374 | setZoomIndex(zoomIndex); |
375 | emit updateZoomIndex(m_zoomIndex); |
376 | |
377 | unsigned int rotationIndex = cg.readEntry("RotationIndex" , 0); |
378 | setRotationIndex(rotationIndex); |
379 | emit updateRotationIndex(m_rotationIndex); |
380 | |
381 | unsigned int fpsIndex = cg.readEntry("FPSIndex" , 2); |
382 | setFPSIndex(fpsIndex); |
383 | emit updateFPSIndex(m_fpsIndex); |
384 | |
385 | unsigned int colorIndex = cg.readEntry("ColorIndex" , 0); |
386 | setColorIndex(colorIndex); |
387 | emit updateColorIndex(colorIndex); |
388 | /* |
389 | QString mode = cg.readEntry("Mode", "followmouse"); |
390 | if (mode == QLatin1String( "wholescreen" )) { |
391 | slotModeWholeScreen(); |
392 | } else if (mode == QLatin1String( "selectionwindow" )) { |
393 | slotModeSelWin(); |
394 | } else if (mode == QLatin1String( "followfocus" )) { |
395 | m_modeFollowFocus->setChecked(true); |
396 | slotModeChanged(); |
397 | } else { |
398 | m_modeFollowMouse->setChecked(true); |
399 | slotModeChanged(); |
400 | } |
401 | */ |
402 | QRect defaultRect(0,0,211,164); |
403 | m_zoomView->setSelRectPos(cg.readEntry("SelRect" , defaultRect)); |
404 | |
405 | m_mouseCursorType = cg.readEntry("ShowMouse" , m_defaultMouseCursorType); |
406 | m_zoomView->showMouse(m_mouseCursorType); |
407 | m_hideCursor->setChecked(!m_mouseCursorType); |
408 | |
409 | m_staysOnTop->setChecked(cg.readEntry("StaysOnTop" , true)); |
410 | slotStaysOnTop(); |
411 | |
412 | // XMLGui has already read and set up the menuBar for us |
413 | m_pShowMenu->setChecked(menuBar()->isVisible()); |
414 | } |
415 | |
416 | bool KmagApp::queryClose() |
417 | { |
418 | saveOptions(); |
419 | return (true); |
420 | } |
421 | |
422 | /** |
423 | * Called when mouse is clicked inside the window |
424 | * |
425 | * @param e |
426 | */ |
427 | void KmagApp::contextMenuEvent ( QContextMenuEvent * e ) |
428 | { |
429 | // show popup |
430 | KXMLGUIFactory *factory = this->factory(); |
431 | QMenu *popup = (QMenu *)factory->container(QLatin1String( "mainPopUp" ),this); |
432 | if (popup != 0) |
433 | popup->popup(e->globalPos()); |
434 | e->accept(); |
435 | } |
436 | |
437 | |
438 | ///////////////////////////////////////////////////////////////////// |
439 | // SLOT IMPLEMENTATION |
440 | ///////////////////////////////////////////////////////////////////// |
441 | |
442 | /** |
443 | * Shows/hides the mouse cursor |
444 | */ |
445 | void KmagApp::showMouseCursor(bool show) |
446 | { |
447 | if(show) { |
448 | if(m_mouseCursorType == 0) |
449 | m_mouseCursorType = m_defaultMouseCursorType; |
450 | m_zoomView->showMouse(m_mouseCursorType); |
451 | } else { |
452 | m_zoomView->showMouse(0); |
453 | } |
454 | } |
455 | |
456 | /** |
457 | * Zoom in. |
458 | */ |
459 | void KmagApp::zoomIn() |
460 | { |
461 | // set the new index .. checking will done inside setZoom |
462 | setZoomIndex(m_zoomIndex+1); |
463 | // signal change in zoom index |
464 | emit updateZoomIndex((int)m_zoomIndex); |
465 | } |
466 | |
467 | /** |
468 | * Zoom out. |
469 | */ |
470 | void KmagApp::zoomOut() |
471 | { |
472 | // set the new index .. checking will done inside setZoom |
473 | setZoomIndex(m_zoomIndex-1); |
474 | // signal change in zoom index |
475 | emit updateZoomIndex((int)m_zoomIndex); |
476 | } |
477 | /** |
478 | * Sets the zoom index to index |
479 | */ |
480 | void KmagApp::setZoomIndex(int index) |
481 | { |
482 | if(index < 0 || index >= (int)zoomArray.size()) { |
483 | // the index is invalid |
484 | kWarning() << "Invalid index!" ; |
485 | return; |
486 | } else if((int)m_zoomIndex == index) { |
487 | // do nothing! |
488 | return; |
489 | } else { |
490 | m_zoomIndex = index; |
491 | } |
492 | |
493 | if(m_zoomIndex == 0) { |
494 | // meaning that no more zooming-out is possible |
495 | // -> disable zoom-out icon |
496 | m_pZoomOut->setEnabled(false); |
497 | } else { // enable the icon |
498 | m_pZoomOut->setEnabled(true); |
499 | } |
500 | |
501 | if(m_zoomIndex == zoomArray.size()-1) { |
502 | // meaning that no more zooming-in is possible |
503 | // -> disable zoom-in icon |
504 | m_pZoomIn->setEnabled(false); |
505 | } else { // enable the icon |
506 | m_pZoomIn->setEnabled(true); |
507 | } |
508 | |
509 | // signal change in zoom value |
510 | emit updateZoomValue(zoomArray.at(m_zoomIndex)); |
511 | } |
512 | |
513 | /** |
514 | * Sets the rotation index to index |
515 | */ |
516 | void KmagApp::setRotationIndex(int index) |
517 | { |
518 | if(index < 0 || index >= (int)rotationArray.size()) { |
519 | // the index is invalid |
520 | kWarning() << "Invalid index!" ; |
521 | return; |
522 | } else if((int)m_rotationIndex == index) { |
523 | // do nothing! |
524 | return; |
525 | } else { |
526 | m_rotationIndex = index; |
527 | } |
528 | |
529 | // signal change in zoom value |
530 | emit updateRotationValue(rotationArray.at(m_rotationIndex)); |
531 | } |
532 | |
533 | /** |
534 | * Sets the fps index to index |
535 | */ |
536 | void KmagApp::setFPSIndex(int index) |
537 | { |
538 | if(index < 0 || index >= (int)fpsArray.size()) { |
539 | // the index is invalid |
540 | kWarning() << "Invalid index!" ; |
541 | return; |
542 | } else if((int)m_fpsIndex == index) { |
543 | // do nothing! |
544 | return; |
545 | } else { |
546 | m_fpsIndex = index; |
547 | } |
548 | |
549 | // signal change in fps value |
550 | emit updateFPSValue(fpsArray.at(m_fpsIndex)); |
551 | } |
552 | |
553 | /** |
554 | * Sets the color index to index |
555 | */ |
556 | void KmagApp::setColorIndex(int index) |
557 | { |
558 | if(index < 0 || index >= (int)colorArray.size()) { |
559 | // the index is invalid |
560 | kWarning() << "Invalid index!" ; |
561 | return; |
562 | } else if((int)m_colorIndex == index) { |
563 | // do nothing! |
564 | return; |
565 | } else { |
566 | m_colorIndex = index; |
567 | } |
568 | |
569 | // signal change in fps value |
570 | emit updateColorValue(colorArray.at(m_colorIndex)); |
571 | } |
572 | |
573 | /** |
574 | * Save the zoomed image |
575 | */ |
576 | void KmagApp::saveZoomPixmap() |
577 | { |
578 | bool toggled(false); |
579 | |
580 | // stop refresh temporarily |
581 | if (m_zoomView->getRefreshStatus()) { |
582 | slotToggleRefresh(); |
583 | toggled = true; |
584 | } |
585 | |
586 | KUrl url = KFileDialog::getSaveUrl(QString(), |
587 | KImageIO::pattern(KImageIO::Writing), |
588 | 0,i18n("Save Snapshot As" )); |
589 | |
590 | if(!url.fileName().isEmpty()) { |
591 | if(!url.isLocalFile()) { |
592 | // create a temp file.. save image to it.. copy over the n/w and then delete the temp file. |
593 | KTemporaryFile tempFile; |
594 | #ifdef __GNUC__ |
595 | #warning "kde4: port KImageIO::type \n"; |
596 | #endif |
597 | if(!tempFile.open() || !m_zoomView->getImage().save(tempFile.fileName(),"png" /*, KImageIO::type(url.fileName()).latin1()*/)) { |
598 | KMessageBox::error(0, i18n("Unable to save temporary file (before uploading to the network file you specified)." ), |
599 | i18n("Error Writing File" )); |
600 | } else { |
601 | if(!KIO::NetAccess::upload(tempFile.fileName(), url, this)) { |
602 | KMessageBox::error(0, i18n("Unable to upload file over the network." ), |
603 | i18n("Error Writing File" )); |
604 | } else { |
605 | KMessageBox::information(0, i18n("Current zoomed image saved to\n%1" , url.prettyUrl()), |
606 | i18n("Information" ), QLatin1String( "save_confirm" )); |
607 | } |
608 | } |
609 | |
610 | } else { |
611 | #ifdef __GNUC__ |
612 | #warning "kde4 : port KImageIO::type(...) \n"; |
613 | #endif |
614 | if(!m_zoomView->getImage().save(url.path(), "png" /*KImageIO::type(url.fileName()).latin1()*/)) { |
615 | KMessageBox::error(0, i18n("Unable to save file. Please check if you have permission to write to the directory." ), |
616 | i18n("Error Writing File" )); |
617 | } else { |
618 | KMessageBox::information(0, i18n("Current zoomed image saved to\n%1" , url.prettyUrl()), |
619 | i18n("Information" ), QLatin1String( "save_confirm" )); |
620 | } |
621 | } |
622 | } |
623 | if(toggled) { |
624 | slotToggleRefresh(); |
625 | } |
626 | } |
627 | |
628 | |
629 | void KmagApp::slotToggleRefresh() |
630 | { |
631 | m_zoomView->toggleRefresh(); |
632 | if(m_zoomView->getRefreshStatus()) { |
633 | refreshSwitch->setIcon(KIcon(QLatin1String( "process-stop" ))); |
634 | refreshSwitch->setText(i18n("Stop" )); |
635 | refreshSwitch->setToolTip(i18n("Click to stop window update" )); |
636 | } else { |
637 | refreshSwitch->setIcon(KIcon(QLatin1String( "system-run" ))); |
638 | refreshSwitch->setText(i18nc("Start updating the window" , "Start" )); |
639 | refreshSwitch->setToolTip(i18n("Click to start window update" )); |
640 | } |
641 | } |
642 | |
643 | |
644 | void KmagApp::slotModeWholeScreen() |
645 | { |
646 | m_zoomView->followMouse(false); |
647 | m_zoomView->setSelRectPos(QRect (0, 0, QApplication::desktop()->width(), QApplication::desktop()->height())); |
648 | m_zoomView->showSelRect(false); |
649 | m_zoomView->setFitToWindow (false); |
650 | m_modeFollowMouse->setChecked(false); |
651 | #ifdef QAccessibilityClient_FOUND |
652 | m_zoomView->followBoth(false); |
653 | m_zoomView->followFocus(false); |
654 | m_modeFollowFocus->setChecked(false); |
655 | #endif |
656 | m_modeWholeScreen->setChecked(true); |
657 | m_modeSelWin->setChecked(false); |
658 | } |
659 | |
660 | |
661 | void KmagApp::slotModeSelWin() |
662 | { |
663 | m_zoomView->followMouse(false); |
664 | m_zoomView->showSelRect(true); |
665 | m_zoomView->setFitToWindow (false); |
666 | m_modeFollowMouse->setChecked(false); |
667 | #ifdef QAccessibilityClient_FOUND |
668 | m_zoomView->followBoth(false); |
669 | m_zoomView->followFocus(false); |
670 | m_modeFollowFocus->setChecked(false); |
671 | #endif |
672 | m_modeWholeScreen->setChecked(false); |
673 | m_modeSelWin->setChecked(true); |
674 | } |
675 | |
676 | void KmagApp::slotModeChanged() |
677 | { |
678 | #ifdef QAccessibilityClient_FOUND |
679 | if(m_modeFollowMouse->isChecked() && m_modeFollowFocus->isChecked()) { |
680 | |
681 | //BOTH MODE |
682 | m_zoomView->followMouse(false); |
683 | m_zoomView->followBoth(true); |
684 | m_zoomView->followFocus(false); |
685 | m_zoomView->showSelRect(false); |
686 | m_zoomView->setFitToWindow (true); |
687 | m_modeWholeScreen->setChecked(false); |
688 | m_modeSelWin->setChecked(false); |
689 | return; |
690 | } |
691 | #endif |
692 | |
693 | if (m_modeFollowMouse->isChecked()) { |
694 | |
695 | //MOUSE MODE |
696 | m_zoomView->followMouse(true); |
697 | m_zoomView->showSelRect(false); |
698 | m_zoomView->setFitToWindow (true); |
699 | m_modeFollowMouse->setChecked(true); |
700 | #ifdef QAccessibilityClient_FOUND |
701 | m_zoomView->followBoth(false); |
702 | m_zoomView->followFocus(false); |
703 | m_modeFollowFocus->setChecked(false); |
704 | #endif |
705 | m_modeWholeScreen->setChecked(false); |
706 | m_modeSelWin->setChecked(false); |
707 | |
708 | #ifdef QAccessibilityClient_FOUND |
709 | } else if (m_modeFollowFocus->isChecked()) { |
710 | |
711 | //FOCUS MODE |
712 | m_zoomView->followBoth(false); |
713 | m_zoomView->followMouse(false); |
714 | m_zoomView->followFocus(true); |
715 | m_zoomView->showSelRect(false); |
716 | m_zoomView->setFitToWindow (true); |
717 | m_modeFollowMouse->setChecked(false); |
718 | m_modeFollowFocus->setChecked(true); |
719 | m_modeWholeScreen->setChecked(false); |
720 | m_modeSelWin->setChecked(false); |
721 | #endif |
722 | |
723 | } |
724 | } |
725 | |
726 | void KmagApp::slotToggleHideCursor() |
727 | { |
728 | showMouseCursor(!m_hideCursor->isChecked()); |
729 | } |
730 | |
731 | |
732 | void KmagApp::slotStaysOnTop() |
733 | { |
734 | if (m_staysOnTop->isChecked()) |
735 | setWindowFlags( windowFlags() | Qt::WindowStaysOnTopHint ); |
736 | else |
737 | setWindowFlags( windowFlags() & !Qt::WindowStaysOnTopHint ); |
738 | show(); |
739 | } |
740 | |
741 | |
742 | void KmagApp::slotFileNewWindow() |
743 | { |
744 | KmagApp *new_window= new KmagApp(); |
745 | new_window->show(); |
746 | } |
747 | |
748 | |
749 | void KmagApp::slotFilePrint() |
750 | { |
751 | #ifndef QT_NO_PRINTER |
752 | |
753 | bool toggled(false); |
754 | |
755 | if (m_printer == 0) { |
756 | m_printer = new QPrinter(); |
757 | } |
758 | |
759 | // stop refresh temporarily |
760 | if (m_zoomView->getRefreshStatus()) { |
761 | slotToggleRefresh(); |
762 | toggled = true; |
763 | } |
764 | |
765 | const QImage pixmap(m_zoomView->getImage()); |
766 | |
767 | // use some AI to get the best orientation |
768 | if(pixmap.width() > pixmap.height()) { |
769 | m_printer->setOrientation(QPrinter::Landscape); |
770 | } else { |
771 | m_printer->setOrientation(QPrinter::Portrait); |
772 | } |
773 | |
774 | QPrintDialog *printDialog = KdePrint::createPrintDialog(m_printer, this); |
775 | |
776 | if (printDialog->exec()) { |
777 | QPainter paint; |
778 | |
779 | if(!paint.begin(m_printer)) |
780 | { |
781 | delete printDialog; |
782 | return; |
783 | } |
784 | // draw the pixmap |
785 | paint.drawImage(0, 0, pixmap); |
786 | // end the painting |
787 | paint.end(); |
788 | } |
789 | |
790 | if(toggled) { |
791 | slotToggleRefresh(); |
792 | } |
793 | delete printDialog; |
794 | #endif // QT_NO_PRINTER |
795 | } |
796 | |
797 | void KmagApp::slotFileQuit() |
798 | { |
799 | saveOptions(); |
800 | // close the first window, the list makes the next one the first again. |
801 | // This ensures that queryClose() is called on each window to ask for closing |
802 | KMainWindow* w; |
803 | if (!memberList().isEmpty()) |
804 | { |
805 | for (int i = 0; i < memberList().size(); ++i) |
806 | { |
807 | w = memberList().at(i); |
808 | // only close the window if the closeEvent is accepted. If the user presses Cancel on the saveModified() dialog, |
809 | // the window and the application stay open. |
810 | if(!w->close()) |
811 | break; |
812 | #ifdef __GNUC__ |
813 | #warning "kde4: now memberList() is constant => we can't remove some element!" |
814 | #endif |
815 | //memberList()->removeRef(w); |
816 | } |
817 | } |
818 | } |
819 | |
820 | void KmagApp::copyToClipBoard() |
821 | { |
822 | QClipboard *cb=KApplication::clipboard(); |
823 | cb->setPixmap(QPixmap::fromImage(m_zoomView->getImage())); |
824 | } |
825 | |
826 | void KmagApp::slotShowMenu() |
827 | { |
828 | /////////////////////////////////////////////////////////////////// |
829 | // turn Menu on or off |
830 | if(!m_pShowMenu->isChecked()) |
831 | { |
832 | menuBar()->hide(); |
833 | } |
834 | else |
835 | { |
836 | menuBar()->show(); |
837 | } |
838 | } |
839 | |
840 | void KmagApp::slotConfKeys() |
841 | { |
842 | KShortcutsDialog::configure( actionCollection() ); |
843 | } |
844 | |
845 | void KmagApp::slotEditToolbars() |
846 | { |
847 | KConfigGroup cg( KGlobal::config(), "MainWindow" ); |
848 | saveMainWindowSettings( cg ); |
849 | QPointer<KEditToolBar> dlg = new KEditToolBar( actionCollection() ); |
850 | connect(dlg, SIGNAL(newToolBarConfig()), this, SLOT(slotNewToolbarConfig()) ); |
851 | if ( dlg->exec() ) |
852 | createGUI(); |
853 | delete dlg; |
854 | } |
855 | |
856 | |
857 | void KmagApp::slotNewToolbarConfig() |
858 | { |
859 | applyMainWindowSettings( KGlobal::config()->group( "MainWindow" ) ); |
860 | createGUI(); |
861 | } |
862 | |