diff --git a/src/Data.cpp b/src/Data.cpp index ffda72e4..ba41efdc 100644 --- a/src/Data.cpp +++ b/src/Data.cpp @@ -1,6 +1,9 @@ #include "Data.h" +#include +#include #include + #include // Note that these aren't all possible BOMs. But they are probably the most common ones. @@ -88,6 +91,19 @@ QByteArray removeBom(QByteArray& data) } } +QString isImageData(const QByteArray& data) +{ + // Check if it's an image. First do a quick test by calling canRead() which only checks the first couple of bytes or so. Only if + // that returned true, do a more sophisticated test of the data. This way we get both, good performance and proper data checking. + QBuffer imageBuffer(const_cast(&data)); + QImageReader readerBuffer(&imageBuffer); + QString imageFormat = readerBuffer.format(); + if(readerBuffer.canRead() && !readerBuffer.read().isNull()) + return imageFormat; + else + return QString(); +} + QStringList toStringList(const QList& list) { QStringList strings; for (const QByteArray &item : list) { diff --git a/src/Data.h b/src/Data.h index a725d196..037076d3 100644 --- a/src/Data.h +++ b/src/Data.h @@ -21,6 +21,9 @@ bool startsWithBom(const QByteArray& data); // with a BOM an empty byte array is returned and the original data is not modified. QByteArray removeBom(QByteArray& data); +// Check if a byte array contains an image. Returns the name of the image format for images or a null string for non-image data. +QString isImageData(const QByteArray& data); + QStringList toStringList(const QList& list); QByteArray encodeString(const QByteArray& str, const QString& encoding); diff --git a/src/EditDialog.cpp b/src/EditDialog.cpp index f09540d8..11b052d4 100644 --- a/src/EditDialog.cpp +++ b/src/EditDialog.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -856,12 +855,9 @@ int EditDialog::checkDataType(const QByteArray& bArrdata) return Null; } - // Check if it's an image. First do a quick test by calling canRead() which only checks the first couple of bytes or so. Only if - // that returned true, do a more sophisticated test of the data. This way we get both, good performance and proper data checking. - QBuffer imageBuffer(&cellData); - QImageReader readerBuffer(&imageBuffer); - QString imageFormat = readerBuffer.format(); - if(readerBuffer.canRead() && !readerBuffer.read().isNull()) + // Check if it's an image + QString imageFormat = isImageData(cellData); + if(!imageFormat.isNull()) return imageFormat == "svg" ? SVG : Image; // Check if it's text only diff --git a/src/PreferencesDialog.cpp b/src/PreferencesDialog.cpp index 1ce272d0..18000b1f 100644 --- a/src/PreferencesDialog.cpp +++ b/src/PreferencesDialog.cpp @@ -109,6 +109,7 @@ void PreferencesDialog::loadSettings() ui->spinSymbolLimit->setValue(Settings::getValue("databrowser", "symbol_limit").toInt()); ui->spinCompleteThreshold->setValue(Settings::getValue("databrowser", "complete_threshold").toInt()); + ui->checkShowImagesInline->setChecked(Settings::getValue("databrowser", "image_preview").toBool()); ui->txtNull->setText(Settings::getValue("databrowser", "null_text").toString()); ui->txtBlob->setText(Settings::getValue("databrowser", "blob_text").toString()); ui->editFilterEscape->setText(Settings::getValue("databrowser", "filter_escape").toString()); @@ -217,6 +218,7 @@ void PreferencesDialog::saveSettings() Settings::setValue("databrowser", "font", ui->comboDataBrowserFont->currentText()); Settings::setValue("databrowser", "fontsize", ui->spinDataBrowserFontSize->value()); + Settings::setValue("databrowser", "image_preview", ui->checkShowImagesInline->isChecked()); saveColorSetting(ui->fr_null_fg, "null_fg"); saveColorSetting(ui->fr_null_bg, "null_bg"); saveColorSetting(ui->fr_reg_fg, "reg_fg"); diff --git a/src/PreferencesDialog.ui b/src/PreferencesDialog.ui index 089c639c..443929fc 100644 --- a/src/PreferencesDialog.ui +++ b/src/PreferencesDialog.ui @@ -821,6 +821,23 @@ Can be set to 0 for disabling completion. + + + + Show images in cell + + + checkShowImagesInline + + + + + + + Enable this option to show a preview of BLOBs containing image data in the cells. This can affect the performance of the data browser, however. + + + @@ -1866,10 +1883,12 @@ Can be set to 0 for disabling completion. + tabWidget comboDefaultLocation locationEdit setLocationButton languageComboBox + appStyleCombo toolbarStyleComboMain toolbarStyleComboStructure toolbarStyleComboBrowse @@ -1877,6 +1896,7 @@ Can be set to 0 for disabling completion. toolbarStyleComboEditCell checkUseRemotes checkUpdates + buttonManageFileExtension encodingComboBox foreignKeysCheckBox checkHideSchemaLinebreaks @@ -1886,6 +1906,9 @@ Can be set to 0 for disabling completion. editDatabaseDefaultSqlText comboDataBrowserFont spinDataBrowserFontSize + spinSymbolLimit + spinCompleteThreshold + checkShowImagesInline fr_null_fg fr_null_bg txtNull @@ -1902,20 +1925,25 @@ Can be set to 0 for disabling completion. spinEditorFontSize spinLogFontSize spinTabSize + wrapComboBox + quoteComboBox checkAutoCompletion + checkCompleteUpper checkErrorIndicators checkHorizontalTiling listExtensions buttonAddExtension buttonRemoveExtension checkRegexDisabled - editRemoteCloneDirectory - buttonRemoteBrowseCloneDirectory - tableCaCerts + checkAllowLoadExtension + tabCertificates tableClientCerts buttonClientCertAdd buttonClientCertRemove - tabWidget + buttonProxy + editRemoteCloneDirectory + buttonRemoteBrowseCloneDirectory + tableCaCerts @@ -1992,12 +2020,12 @@ Can be set to 0 for disabling completion. setVisible(bool) - 365 - 207 + 344 + 230 - 108 - 280 + 119 + 273 @@ -2008,8 +2036,8 @@ Can be set to 0 for disabling completion. setVisible(bool) - 365 - 207 + 344 + 230 365 @@ -2024,8 +2052,8 @@ Can be set to 0 for disabling completion. activateRemoteTab(bool) - 161 - 172 + 231 + 393 382 @@ -2040,8 +2068,8 @@ Can be set to 0 for disabling completion. addClientCertificate() - 578 - 315 + 722 + 110 596 @@ -2056,8 +2084,8 @@ Can be set to 0 for disabling completion. removeClientCertificate() - 578 - 353 + 722 + 139 597 @@ -2072,8 +2100,8 @@ Can be set to 0 for disabling completion. chooseRemoteCloneDirectory() - 567 - 54 + 732 + 538 595 @@ -2088,12 +2116,12 @@ Can be set to 0 for disabling completion. setEnabled(bool) - 474 - 464 + 642 + 450 - 474 - 492 + 642 + 480 @@ -2104,8 +2132,8 @@ Can be set to 0 for disabling completion. on_buttonBox_clicked(QAbstractButton*) - 385 - 591 + 394 + 584 385 @@ -2120,8 +2148,8 @@ Can be set to 0 for disabling completion. configureProxy() - 385 - 591 + 225 + 506 385 diff --git a/src/Settings.cpp b/src/Settings.cpp index 8c262c95..67aa490c 100644 --- a/src/Settings.cpp +++ b/src/Settings.cpp @@ -208,6 +208,8 @@ QVariant Settings::getDefaultValue(const std::string& group, const std::string& return 5000; if(name == "complete_threshold") return 1000; + if(name == "image_preview") + return false; if(name == "indent_compact") return false; if(name == "auto_switch_mode") diff --git a/src/sqlitetablemodel.cpp b/src/sqlitetablemodel.cpp index 1cf04cdf..3cacebf9 100644 --- a/src/sqlitetablemodel.cpp +++ b/src/sqlitetablemodel.cpp @@ -390,6 +390,16 @@ QVariant SqliteTableModel::data(const QModelIndex &index, int role) const .arg(QKeySequence(Qt::CTRL).toString(QKeySequence::NativeText)); else return QString(); + } else if(role == Qt::DecorationRole) { + if(!row_available) + return QVariant(); + + if(Settings::getValue("databrowser", "image_preview").toBool() && !isImageData(cached_row->at(column)).isNull()) + { + QImage img; + img.loadFromData(cached_row->at(column)); + return QPixmap::fromImage(img); + } } return QVariant();