diff --git a/src/ColumnDisplayFormatDialog.cpp b/src/ColumnDisplayFormatDialog.cpp index 66699a776..2c4b18372 100644 --- a/src/ColumnDisplayFormatDialog.cpp +++ b/src/ColumnDisplayFormatDialog.cpp @@ -36,38 +36,51 @@ ColumnDisplayFormatDialog::ColumnDisplayFormatDialog(DBBrowserDB& db, const sqlb ui->comboDisplayFormat->addItem(tr("Upper case"), "upper"); ui->comboDisplayFormat->insertSeparator(ui->comboDisplayFormat->count()); ui->comboDisplayFormat->addItem(tr("Binary GUID to text"), "guid"); + ui->comboDisplayFormat->addItem(tr("SpatiaLite Geometry to SVG"), "geomToSVG"); ui->comboDisplayFormat->insertSeparator(ui->comboDisplayFormat->count()); ui->comboDisplayFormat->addItem(tr("Custom"), "custom"); ui->labelDisplayFormat->setText(ui->labelDisplayFormat->text().arg(column_name)); - formatFunctions["decimal"] = "printf('%d', " + sqlb::escapeIdentifier(column_name) + ")"; - formatFunctions["exponent"] = "printf('%e', " + sqlb::escapeIdentifier(column_name) + ")"; - formatFunctions["hexblob"] = "hex(" + sqlb::escapeIdentifier(column_name) + ")"; - formatFunctions["hex"] = "printf('0x%x', " + sqlb::escapeIdentifier(column_name) + ")"; - formatFunctions["octal"] = "printf('%o', " + sqlb::escapeIdentifier(column_name) + ")"; - formatFunctions["round"] = "round(" + sqlb::escapeIdentifier(column_name) + ")"; - formatFunctions["appleDate"] = "datetime('2001-01-01', " + sqlb::escapeIdentifier(column_name) + " || ' seconds')"; - formatFunctions["javaEpoch"] = "strftime('%Y-%m-%d %H:%M:%S.', " + sqlb::escapeIdentifier(column_name) + - "/1000, 'unixepoch') || (" + sqlb::escapeIdentifier(column_name) + "%1000)"; - formatFunctions["dotNetTicks"] = "datetime(" + sqlb::escapeIdentifier(column_name) + " / 10000000 - 62135596800, 'unixepoch')"; - formatFunctions["julian"] = "datetime(" + sqlb::escapeIdentifier(column_name) + ")"; - formatFunctions["epoch"] = "datetime(" + sqlb::escapeIdentifier(column_name) + ", 'unixepoch')"; - formatFunctions["epochLocalTime"] = "datetime(" + sqlb::escapeIdentifier(column_name) + ", 'unixepoch', 'localtime')"; - formatFunctions["winDate"] = "datetime('1899-12-30', " + sqlb::escapeIdentifier(column_name) + " || ' days')"; - formatFunctions["ddmmyyyyDate"] = "strftime('%d/%m/%Y', " + sqlb::escapeIdentifier(column_name) + ")"; - formatFunctions["lower"] = "lower(" + sqlb::escapeIdentifier(column_name) + ")"; - formatFunctions["upper"] = "upper(" + sqlb::escapeIdentifier(column_name) + ")"; - formatFunctions["guid"] = "substr(hex(" + sqlb::escapeIdentifier(column_name) + "), 7, 2) || " + - "substr(hex(" + sqlb::escapeIdentifier(column_name) + "), 5, 2) || " + - "substr(hex(" + sqlb::escapeIdentifier(column_name) + "), 3, 2) || " + - "substr(hex(" + sqlb::escapeIdentifier(column_name) + "), 1, 2) || '-' || " + - "substr(hex(" + sqlb::escapeIdentifier(column_name) + "), 11, 2) || " + - "substr(hex(" + sqlb::escapeIdentifier(column_name) + "), 9, 2) || '-' || " + - "substr(hex(" + sqlb::escapeIdentifier(column_name) + "), 15, 2) || " + - "substr(hex(" + sqlb::escapeIdentifier(column_name) + "), 13, 2) || '-' || " + - "substr(hex(" + sqlb::escapeIdentifier(column_name) + "), 17, 4) || '-' || " + - "substr(hex(" + sqlb::escapeIdentifier(column_name) + "), 21, 12)"; + const QString e_column_name = sqlb::escapeIdentifier(column_name); + + formatFunctions["decimal"] = "printf('%d', " + e_column_name + ")"; + formatFunctions["exponent"] = "printf('%e', " + e_column_name + ")"; + formatFunctions["hexblob"] = "hex(" + e_column_name + ")"; + formatFunctions["hex"] = "printf('0x%x', " + e_column_name + ")"; + formatFunctions["octal"] = "printf('%o', " + e_column_name + ")"; + formatFunctions["round"] = "round(" + e_column_name + ")"; + formatFunctions["appleDate"] = "datetime('2001-01-01', " + e_column_name + " || ' seconds')"; + formatFunctions["javaEpoch"] = "strftime('%Y-%m-%d %H:%M:%S.', " + e_column_name + + "/1000, 'unixepoch') || (" + e_column_name + "%1000)"; + formatFunctions["dotNetTicks"] = "datetime(" + e_column_name + " / 10000000 - 62135596800, 'unixepoch')"; + formatFunctions["julian"] = "datetime(" + e_column_name + ")"; + formatFunctions["epoch"] = "datetime(" + e_column_name + ", 'unixepoch')"; + formatFunctions["epochLocalTime"] = "datetime(" + e_column_name + ", 'unixepoch', 'localtime')"; + formatFunctions["winDate"] = "datetime('1899-12-30', " + e_column_name + " || ' days')"; + formatFunctions["ddmmyyyyDate"] = "strftime('%d/%m/%Y', " + e_column_name + ")"; + formatFunctions["lower"] = "lower(" + e_column_name + ")"; + formatFunctions["upper"] = "upper(" + e_column_name + ")"; + formatFunctions["guid"] = "substr(hex(" + e_column_name + "), 7, 2) || " + + "substr(hex(" + e_column_name + "), 5, 2) || " + + "substr(hex(" + e_column_name + "), 3, 2) || " + + "substr(hex(" + e_column_name + "), 1, 2) || '-' || " + + "substr(hex(" + e_column_name + "), 11, 2) || " + + "substr(hex(" + e_column_name + "), 9, 2) || '-' || " + + "substr(hex(" + e_column_name + "), 15, 2) || " + + "substr(hex(" + e_column_name + "), 13, 2) || '-' || " + + "substr(hex(" + e_column_name + "), 17, 4) || '-' || " + + "substr(hex(" + e_column_name + "), 21, 12)"; + formatFunctions["geomToSVG"] = QString( +R"('' +|| '' +|| '')").arg(e_column_name); // Set the current format, if it's empty set the default format if(current_format.isEmpty()) diff --git a/src/ImageViewer.cpp b/src/ImageViewer.cpp index 97cb7db53..5c78c66a7 100644 --- a/src/ImageViewer.cpp +++ b/src/ImageViewer.cpp @@ -1,16 +1,21 @@ #include "ImageViewer.h" #include "ui_ImageViewer.h" -#include -#include +#include #include +#include +#include +#include #include ImageViewer::ImageViewer(QWidget* parent) : QWidget(parent), - ui(new Ui::ImageViewer) + ui(new Ui::ImageViewer), + m_image_size(0, 0), + m_pan_mode{false} { ui->setupUi(this); + ui->scrollArea->installEventFilter(this); connect(ui->buttonOriginalSize, &QToolButton::clicked, this, [this]{ scaleImage(100); }); ui->labelView->addAction(ui->actionPrintImage); @@ -28,16 +33,58 @@ void ImageViewer::resetImage() void ImageViewer::setImage(const QImage& image) { + auto widget_size = ui->scrollArea->size(); + m_image_size = image.size(); + ui->labelView->setMaximumSize(m_image_size.scaled(widget_size, Qt::KeepAspectRatio)); + ui->labelView->setPixmap(QPixmap::fromImage(image)); // If the image is larger than the viewport scale it to fit the viewport. // If the image is smaller than the viewport show it in its original size. - if(image.size().width() > ui->labelView->size().width() || image.size().height() > ui->labelView->size().height()) + if(!isQSizeCovered(m_image_size)) ui->buttonFitToWindow->setChecked(true); else scaleImage(100); } +bool ImageViewer::isQSizeCovered(QSize rect) +{ + auto widget_size = ui->scrollArea->size(); + return widget_size.width() >= rect.width() && widget_size.height() >= rect.height(); +} + +bool ImageViewer::eventFilter(QObject *obj, QEvent *e) { + auto e_type = e->type(); + if (ui->buttonFitToWindow->isChecked()) { + if (e_type == QEvent::Resize) + scaleToFitWindow(true); + } else if (e_type >= QEvent::MouseButtonPress && e_type <= QEvent::MouseMove) { + auto *mouse_event = static_cast(e); + if (e_type == QEvent::MouseButtonPress && mouse_event->button() == Qt::LeftButton && + !isQSizeCovered(ui->labelView->size())) { + m_mouse_down = mouse_event->globalPos(); + m_pan_mode = true; + ui->scrollArea->setCursor(Qt::ClosedHandCursor); + } else if (e_type == QEvent::MouseMove && m_pan_mode) { + auto dx = mouse_event->globalX() - m_mouse_down.x(); + auto dy = mouse_event->globalY() - m_mouse_down.y(); + if (dx != 0) { + ui->scrollArea->horizontalScrollBar()->setValue(ui->scrollArea->horizontalScrollBar()->value() - dx); + m_mouse_down.setX(mouse_event->globalX()); + } + + if (dy != 0) { + ui->scrollArea->verticalScrollBar()->setValue(ui->scrollArea->verticalScrollBar()->value() - dy); + m_mouse_down.setY(mouse_event->globalY()); + } + } else if (e_type == QEvent::MouseButtonRelease && mouse_event->button() == Qt::LeftButton) { + m_pan_mode = false; + ui->scrollArea->setCursor(Qt::ArrowCursor); + } + } + return false; +} + void ImageViewer::openPrintImageDialog() { QPrinter printer; @@ -68,8 +115,11 @@ void ImageViewer::scaleToFitWindow(bool enabled) ui->scrollArea->setWidgetResizable(enabled); // When disabling the fit to window scaling, revert back to the original image size - if(!enabled) + if(!enabled) { scaleImage(100); + } else { + ui->labelView->setMaximumSize(m_image_size.scaled(ui->scrollArea->size(), Qt::KeepAspectRatio)); + } } void ImageViewer::scaleImage(int scale) @@ -78,16 +128,13 @@ void ImageViewer::scaleImage(int scale) ui->sliderScale->setValue(scale); // Update our scale factor - qreal factor_change = (scale / 100.0) / m_scale_factor; - m_scale_factor = scale / 100.0; + auto scale_factor = scale / 100.0; // Resize the image -#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) - QPixmap pixmap = *ui->labelView->pixmap(); -#else - QPixmap pixmap = ui->labelView->pixmap(Qt::ReturnByValue); -#endif - ui->labelView->resize(m_scale_factor * pixmap.size()); + auto max_size_old = ui->labelView->maximumSize(); + ui->labelView->setMaximumSize(m_image_size * scale_factor); + ui->labelView->resize(ui->labelView->maximumSize()); + auto factor_change = ui->labelView->maximumSize().width() / static_cast(max_size_old.width()); // Uncheck the fit to window button ui->buttonFitToWindow->setChecked(false); diff --git a/src/ImageViewer.h b/src/ImageViewer.h index 720b4a394..748919208 100644 --- a/src/ImageViewer.h +++ b/src/ImageViewer.h @@ -27,8 +27,12 @@ private slots: private: Ui::ImageViewer* ui; + QSize m_image_size; + bool m_pan_mode; + QPoint m_mouse_down; - qreal m_scale_factor; + bool eventFilter(QObject *obj, QEvent *e) override; + bool isQSizeCovered(QSize rect); }; #endif diff --git a/src/ImageViewer.ui b/src/ImageViewer.ui index 177af8563..64535c6ed 100644 --- a/src/ImageViewer.ui +++ b/src/ImageViewer.ui @@ -31,6 +31,9 @@ + + Qt::AlignCenter +