Repository: keepassxreboot/keepassxc (C++)

Issue:
QR code is stretched horizontally within its window
## Overview
Resizing the QR code display window horizontally distorts the QR code itself, i.e. it's not square anymore.

## Steps to Reproduce
1. Select "TOTP / Show QR Code" from the context menu of an entry.
2. Resize the window horizontally.

## Expected Behavior
The QR code should always be square, centered and as large as possible within the limits of its allocated window are. (If the window is resized _vertically_, the program behaves correctly.)

## Actual Behavior
The QR code is stretched horizontally, covering the whole width of the window. Scanning it with a smartphone camera will not work correctly.

## Context
KeePassXC - Version 2.7.4
Revision: 63b2394
Qt 5.15.3

[NOTE]: # ( Pick choices based on your environment )
Operating System: Linux
Desktop Env: Cinnamon
Windowing System: X11


Discussion: Cannot replicate on Windows so this must be a bug on macOS and Linux only...
I was able to reproduce it on Linux:
![stratched-qr-code](https://user-images.githubusercontent.com/121412908/214191703-2b0e4fde-937c-43ef-8ce4-a3ee06394732.png)
At the same time the vertical window sizing does not change the QR code proportion.
Let me check what can we do to fix it...
Does it need to be fixed? Just don't size the window in one dimension, use the corner resize. I tried to fix it and it seemed impossible no matter what I did. 
Right, let's have it as plan B.
For plan A I've got some result but need to find a solution to center the QR code to avoid much space on the right side:
![fixed-qr-code-not-centered](https://user-images.githubusercontent.com/121412908/214232987-7c630a41-0d45-479a-9543-cfbc92af5015.png)

Now I have a pretty simple solution for this variant:
![fixed-qr-code-centered](https://user-images.githubusercontent.com/121412908/214470114-3fcdfc17-908d-4339-8608-908dbf8998fd.png)

```c++
    auto svgWidgetLayout = new QBoxLayout(QBoxLayout::LeftToRight);
    svgWidgetLayout->addWidget(m_totpSvgWidget, 0, Qt::AlignCenter);
    m_verticalLayout->addLayout(svgWidgetLayout);
```

Is it ok to have fixed size QR code or it should be resized to fill window as well?
It is possible but required recalculation and resizing on the fly that may impact on smooth rendering.
Let me know...
The point of allowing the window to resize is so that the qr code resizes as well. If it stays a fixed size, then this didn't solve the problem. 
Sure, I will try...



Fix (patch):
diff --git a/src/gui/SquareSvgWidget.cpp b/src/gui/SquareSvgWidget.cpp
index 5a907e95bf..b39cee9798 100644
--- a/src/gui/SquareSvgWidget.cpp
+++ b/src/gui/SquareSvgWidget.cpp
@@ -16,6 +16,14 @@
  */
 
 #include "SquareSvgWidget.h"
+#include <QResizeEvent>
+
+SquareSvgWidget::SquareSvgWidget(QWidget* parent)
+    : QSvgWidget(parent)
+{
+    Q_ASSERT(parent);
+    setObjectName("squareSvgWidget");
+}
 
 bool SquareSvgWidget::hasHeightForWidth() const
 {
@@ -26,3 +34,24 @@ int SquareSvgWidget::heightForWidth(int width) const
 {
     return width;
 }
+
+// The overridden logic allows to keep the SVG image as square and centered by width and height.
+void SquareSvgWidget::resizeEvent(QResizeEvent*)
+{
+    QWidget* pWidget = parentWidget();
+    Q_ASSERT(pWidget);
+    if (pWidget) {
+        auto containerRect = pWidget->contentsRect();
+
+        auto containerWidth = containerRect.width();
+        auto containerHeight = containerRect.height();
+
+        auto squareSize = qMin(containerWidth, containerHeight);
+        auto halfSquareSize = squareSize >> 1;
+
+        auto startX = (containerWidth >> 1) - halfSquareSize;
+        auto startY = (containerHeight >> 1) - halfSquareSize;
+
+        setGeometry(startX, startY, squareSize, squareSize);
+    }
+}
diff --git a/src/gui/SquareSvgWidget.h b/src/gui/SquareSvgWidget.h
index c59548b749..479bd964df 100644
--- a/src/gui/SquareSvgWidget.h
+++ b/src/gui/SquareSvgWidget.h
@@ -23,11 +23,13 @@
 class SquareSvgWidget : public QSvgWidget
 {
 public:
-    SquareSvgWidget() = default;
+    explicit SquareSvgWidget(QWidget* parent);
     ~SquareSvgWidget() override = default;
 
     bool hasHeightForWidth() const override;
     int heightForWidth(int width) const override;
+
+    void resizeEvent(QResizeEvent* event) override;
 };
 
 #endif // KEEPASSX_SquareSvgWidget_H
diff --git a/src/gui/TotpExportSettingsDialog.cpp b/src/gui/TotpExportSettingsDialog.cpp
index 93921e29c8..fa40aa62af 100644
--- a/src/gui/TotpExportSettingsDialog.cpp
+++ b/src/gui/TotpExportSettingsDialog.cpp
@@ -29,25 +29,29 @@
 #include <QMessageBox>
 #include <QPushButton>
 #include <QShortcut>
+#include <QStackedWidget>
 
 TotpExportSettingsDialog::TotpExportSettingsDialog(DatabaseWidget* parent, Entry* entry)
     : QDialog(parent)
     , m_timer(new QTimer(this))
     , m_verticalLayout(new QVBoxLayout())
-    , m_totpSvgWidget(new SquareSvgWidget())
+    , m_totpSvgContainerWidget(new QStackedWidget())
+    , m_totpSvgWidget(new SquareSvgWidget(m_totpSvgContainerWidget))
     , m_countDown(new QLabel())
     , m_warningLabel(new QLabel())
     , m_buttonBox(new QDialogButtonBox(QDialogButtonBox::Close | QDialogButtonBox::Ok))
 {
+    setObjectName("entryQrCodeWidget");
+    m_totpSvgContainerWidget->addWidget(m_totpSvgWidget);
+
     m_verticalLayout->addWidget(m_warningLabel);
     m_verticalLayout->addItem(new QSpacerItem(0, 0));
-
-    m_verticalLayout->addStretch(0);
-    m_verticalLayout->addWidget(m_totpSvgWidget);
-    m_verticalLayout->addStretch(0);
+    m_verticalLayout->addWidget(m_totpSvgContainerWidget);
     m_verticalLayout->addWidget(m_countDown);
     m_verticalLayout->addWidget(m_buttonBox);
 
+    m_verticalLayout->setAlignment(m_buttonBox, Qt::AlignBottom);
+
     setLayout(m_verticalLayout);
     setAttribute(Qt::WA_DeleteOnClose);
 
diff --git a/src/gui/TotpExportSettingsDialog.h b/src/gui/TotpExportSettingsDialog.h
index 03bd98aad0..7a807cd0ce 100644
--- a/src/gui/TotpExportSettingsDialog.h
+++ b/src/gui/TotpExportSettingsDialog.h
@@ -44,6 +44,7 @@ private slots:
     QTimer* m_timer;
 
     QVBoxLayout* m_verticalLayout;
+    QStackedWidget* m_totpSvgContainerWidget;
     SquareSvgWidget* m_totpSvgWidget;
     QLabel* m_countDown;
     QLabel* m_warningLabel;