Skip to content
67 changes: 40 additions & 27 deletions src/ColumnDisplayFormatDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"('<svg xmlns="http://www.w3.org/2000/svg">'
|| '<path d="'
|| AsSVG(
ScaleCoords(
ST_Translate(%1, -St_MinX(%1), -St_MaxY(%1), 0)
, 639 / (MAX(St_MaxX(%1) - St_MinX(%1), St_MaxY(%1) - St_MinY(%1))))
, 1, 5)
|| '" stroke="darkblue" fill="#b5cfed" stroke-width="1"/>'
|| '</svg>')").arg(e_column_name);

// Set the current format, if it's empty set the default format
if(current_format.isEmpty())
Expand Down
73 changes: 60 additions & 13 deletions src/ImageViewer.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
#include "ImageViewer.h"
#include "ui_ImageViewer.h"

#include <QPrinter>
#include <QPrintPreviewDialog>
#include <QMouseEvent>
#include <QPainter>
#include <QPrintPreviewDialog>
#include <QPrinter>
#include <QResizeEvent>
#include <QScrollBar>

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);
Expand All @@ -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<QMouseEvent*>(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;
Expand Down Expand Up @@ -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)
Expand All @@ -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<double>(max_size_old.width());

// Uncheck the fit to window button
ui->buttonFitToWindow->setChecked(false);
Expand Down
6 changes: 5 additions & 1 deletion src/ImageViewer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 3 additions & 0 deletions src/ImageViewer.ui
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
</property>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<widget class="QLabel" name="labelView">
<property name="geometry">
<rect>
Expand Down