| 
									
										
										
										
											2022-12-20 10:31:15 +00:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							| 
									
										
										
										
											2023-11-19 13:31:45 +01:00
										 |  |  | // Copyright (C) 2022-2023 Jon Beniston, M7RCE <jon@beniston.com>                //
 | 
					
						
							|  |  |  | // Copyright (C) 2023 Mohamed <mohamedadlyi@github.com>                          //
 | 
					
						
							| 
									
										
										
										
											2022-12-20 10:31:15 +00:00
										 |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // This program is free software; you can redistribute it and/or modify          //
 | 
					
						
							|  |  |  | // it under the terms of the GNU General Public License as published by          //
 | 
					
						
							|  |  |  | // the Free Software Foundation as version 3 of the License, or                  //
 | 
					
						
							|  |  |  | // (at your option) any later version.                                           //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful,               //
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
					
						
							|  |  |  | // GNU General Public License V3 for more details.                               //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU General Public License             //
 | 
					
						
							|  |  |  | // along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <QDebug>
 | 
					
						
							|  |  |  | #include <QApplication>
 | 
					
						
							|  |  |  | #include <QScreen>
 | 
					
						
							|  |  |  | #include <QTimer>
 | 
					
						
							|  |  |  | #include <QResizeEvent>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "dialogpositioner.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DialogPositioner::DialogPositioner(QWidget *dialog, bool center) : | 
					
						
							|  |  |  |     QObject(dialog), | 
					
						
							|  |  |  |     m_dialog(dialog), | 
					
						
							|  |  |  |     m_center(center) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     connect(dialog->screen(), &QScreen::orientationChanged, this, &DialogPositioner::orientationChanged); | 
					
						
							| 
									
										
										
										
											2023-03-13 03:11:22 +02:00
										 |  |  |     #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
 | 
					
						
							| 
									
										
										
										
											2022-12-20 10:31:15 +00:00
										 |  |  |     dialog->screen()->setOrientationUpdateMask(Qt::PortraitOrientation | 
					
						
							|  |  |  |                                                 | Qt::LandscapeOrientation | 
					
						
							|  |  |  |                                                 | Qt::InvertedPortraitOrientation | 
					
						
							|  |  |  |                                                 | Qt::InvertedLandscapeOrientation); | 
					
						
							| 
									
										
										
										
											2023-03-13 03:11:22 +02:00
										 |  |  |     #endif
 | 
					
						
							| 
									
										
										
										
											2022-12-20 10:31:15 +00:00
										 |  |  |     if (m_center) { | 
					
						
							|  |  |  |         DialogPositioner::centerDialog(m_dialog); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         DialogPositioner::positionDialog(m_dialog); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     dialog->installEventFilter(this); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DialogPositioner::orientationChanged(Qt::ScreenOrientation orientation) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     (void) orientation; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Need a delay before geometry() reflects new orientation
 | 
					
						
							|  |  |  |     // https://bugreports.qt.io/browse/QTBUG-109127
 | 
					
						
							|  |  |  |     QTimer::singleShot(200, [this]() { | 
					
						
							|  |  |  |         if (m_center) { | 
					
						
							|  |  |  |             DialogPositioner::centerDialog(m_dialog); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             DialogPositioner::positionDialog(m_dialog); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DialogPositioner::centerDialog(QWidget *dialog) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // Restrict size of dialog to size of desktop
 | 
					
						
							|  |  |  |     DialogPositioner::sizeToDesktop(dialog); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Position in center of screen
 | 
					
						
							|  |  |  |     QRect desktop = dialog->screen()->availableGeometry(); | 
					
						
							|  |  |  |     QSize size = dialog->size(); | 
					
						
							|  |  |  |     QPoint pos; | 
					
						
							|  |  |  |     pos.setX((desktop.width() - size.width()) / 2); | 
					
						
							|  |  |  |     pos.setY((desktop.height() - size.height()) / 2); | 
					
						
							|  |  |  |     dialog->move(pos); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DialogPositioner::positionDialog(QWidget *dialog) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // Restrict size of dialog to size of desktop
 | 
					
						
							|  |  |  |     DialogPositioner::sizeToDesktop(dialog); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Position so fully on screen
 | 
					
						
							|  |  |  |     QRect desktop = dialog->screen()->availableGeometry(); | 
					
						
							| 
									
										
										
										
											2023-09-29 08:43:29 +01:00
										 |  |  |     QRect geometry = dialog->frameGeometry(); | 
					
						
							| 
									
										
										
										
											2022-12-20 10:31:15 +00:00
										 |  |  |     QPoint pos = dialog->pos(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool move = false; | 
					
						
							| 
									
										
										
										
											2023-09-29 08:43:29 +01:00
										 |  |  |     if (pos.x() + geometry.width() > desktop.width()) | 
					
						
							| 
									
										
										
										
											2022-12-20 10:31:15 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-09-29 08:43:29 +01:00
										 |  |  |         pos.setX(desktop.width() - geometry.width()); | 
					
						
							| 
									
										
										
										
											2022-12-20 10:31:15 +00:00
										 |  |  |         move = true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-09-29 08:43:29 +01:00
										 |  |  |     if (pos.y() + geometry.height() > desktop.height()) | 
					
						
							| 
									
										
										
										
											2022-12-20 10:31:15 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-09-29 08:43:29 +01:00
										 |  |  |         pos.setY(desktop.height() - geometry.height()); | 
					
						
							| 
									
										
										
										
											2022-12-20 10:31:15 +00:00
										 |  |  |         move = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (move) { | 
					
						
							|  |  |  |         dialog->move(pos); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DialogPositioner::sizeToDesktop(QWidget *widget) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QRect desktop = widget->screen()->availableGeometry(); | 
					
						
							|  |  |  |     QSize size = widget->size(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool resize = false; | 
					
						
							|  |  |  |     if (size.width() > desktop.width()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         size.setWidth(desktop.width()); | 
					
						
							|  |  |  |         resize = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (size.height() > desktop.height()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         size.setHeight(desktop.height()); | 
					
						
							|  |  |  |         resize = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (resize) { | 
					
						
							|  |  |  |         widget->resize(size); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool DialogPositioner::eventFilter(QObject *obj, QEvent *event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (event->type() == QEvent::Show) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (m_center) { | 
					
						
							|  |  |  |             DialogPositioner::centerDialog(m_dialog); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             DialogPositioner::positionDialog(m_dialog); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return QObject::eventFilter(obj, event); | 
					
						
							|  |  |  | } |