cutter/src/common/Helpers.cpp

309 lines
8.5 KiB
C++
Raw Normal View History

2018-10-17 07:55:53 +00:00
#include "common/Helpers.h"
#include "Configuration.h"
2018-02-04 17:27:48 +00:00
#include <cmath>
#include <QPlainTextEdit>
#include <QTextEdit>
#include <QFileInfo>
2018-02-04 17:27:48 +00:00
#include <QtCore>
#include <QCryptographicHash>
2017-04-13 15:04:30 +00:00
#include <QTreeWidget>
#include <QString>
#include <QAbstractItemView>
#include <QAbstractButton>
#include <QDockWidget>
#include <QMenu>
#include <QComboBox>
2017-04-13 15:04:30 +00:00
static QAbstractItemView::ScrollMode scrollMode()
{
2017-04-13 15:04:30 +00:00
const bool use_scrollperpixel = true;
2021-01-24 14:50:13 +00:00
return use_scrollperpixel ? QAbstractItemView::ScrollPerPixel
: QAbstractItemView::ScrollPerItem;
2017-04-13 15:04:30 +00:00
}
2018-03-21 20:32:32 +00:00
namespace qhelpers {
QString formatBytecount(const uint64_t bytecount)
2017-04-13 15:04:30 +00:00
{
if (bytecount == 0) {
2018-03-21 20:32:32 +00:00
return "0";
}
const int exp = log(bytecount) / log(1024);
2021-01-24 14:50:13 +00:00
constexpr char suffixes[] = { ' ', 'k', 'M', 'G', 'T', 'P', 'E' };
2018-03-21 20:32:32 +00:00
QString str;
QTextStream stream(&str);
2021-01-24 14:50:13 +00:00
stream << qSetRealNumberPrecision(3) << bytecount / pow(1024, exp) << ' ' << suffixes[exp]
<< 'B';
2018-03-21 20:32:32 +00:00
return stream.readAll();
}
2018-02-04 17:27:48 +00:00
2018-03-21 20:32:32 +00:00
void adjustColumns(QTreeView *tv, int columnCount, int padding)
{
for (int i = 0; i != columnCount; ++i) {
tv->resizeColumnToContents(i);
if (padding > 0) {
int width = tv->columnWidth(i);
tv->setColumnWidth(i, width + padding);
2017-04-13 15:04:30 +00:00
}
}
2018-03-21 20:32:32 +00:00
}
2017-04-13 15:04:30 +00:00
2018-03-21 20:32:32 +00:00
void adjustColumns(QTreeWidget *tw, int padding)
{
adjustColumns(tw, tw->columnCount(), padding);
}
2018-03-21 20:32:32 +00:00
QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str, const QString &str2,
const QString &str3, const QString &str4, const QString &str5)
{
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
// Fill dummy hidden column
tempItem->setText(0, "0");
tempItem->setText(1, str);
if (!str2.isNull())
tempItem->setText(2, str2);
if (!str3.isNull())
tempItem->setText(3, str3);
if (!str4.isNull())
tempItem->setText(4, str4);
if (!str5.isNull())
tempItem->setText(5, str5);
tw->insertTopLevelItem(0, tempItem);
return tempItem;
}
/**
* @brief Select first item of a QAbstractItemView if not empty
* @param itemView
* @return true if first item was selected
*/
bool selectFirstItem(QAbstractItemView *itemView)
{
if (!itemView) {
return false;
}
auto model = itemView->model();
if (!model) {
return false;
}
if (model->hasIndex(0, 0)) {
itemView->setCurrentIndex(model->index(0, 0));
return true;
}
return false;
}
2018-03-21 20:32:32 +00:00
void setVerticalScrollMode(QAbstractItemView *tw)
{
tw->setVerticalScrollMode(scrollMode());
}
2018-03-21 20:32:32 +00:00
void setCheckedWithoutSignals(QAbstractButton *button, bool checked)
{
bool blocked = button->signalsBlocked();
button->blockSignals(true);
button->setChecked(checked);
button->blockSignals(blocked);
}
2018-03-21 20:32:32 +00:00
SizePolicyMinMax forceWidth(QWidget *widget, int width)
{
SizePolicyMinMax r;
r.sizePolicy = widget->sizePolicy();
r.min = widget->minimumWidth();
r.max = widget->maximumWidth();
QSizePolicy sizePolicy = r.sizePolicy;
sizePolicy.setHorizontalPolicy(QSizePolicy::Fixed);
widget->setSizePolicy(sizePolicy);
widget->setMinimumWidth(width);
widget->setMaximumWidth(width);
return r;
}
2018-03-21 20:32:32 +00:00
SizePolicyMinMax forceHeight(QWidget *widget, int height)
{
SizePolicyMinMax r;
r.sizePolicy = widget->sizePolicy();
r.min = widget->minimumHeight();
r.max = widget->maximumHeight();
QSizePolicy sizePolicy = r.sizePolicy;
sizePolicy.setVerticalPolicy(QSizePolicy::Fixed);
widget->setSizePolicy(sizePolicy);
widget->setMinimumHeight(height);
widget->setMaximumHeight(height);
return r;
}
2018-03-21 20:32:32 +00:00
void SizePolicyMinMax::restoreWidth(QWidget *widget)
{
widget->setSizePolicy(sizePolicy.horizontalPolicy(), widget->sizePolicy().verticalPolicy());
2018-03-21 20:32:32 +00:00
widget->setMinimumWidth(min);
widget->setMaximumWidth(max);
}
2018-03-21 20:32:32 +00:00
void SizePolicyMinMax::restoreHeight(QWidget *widget)
{
widget->setSizePolicy(widget->sizePolicy().horizontalPolicy(), sizePolicy.verticalPolicy());
2018-03-21 20:32:32 +00:00
widget->setMinimumHeight(min);
widget->setMaximumHeight(max);
}
2018-03-21 20:32:32 +00:00
int getMaxFullyDisplayedLines(QTextEdit *textEdit)
{
QFontMetrics fontMetrics(textEdit->document()->defaultFont());
return (textEdit->height()
2021-01-24 14:50:13 +00:00
- (textEdit->contentsMargins().top() + textEdit->contentsMargins().bottom()
2018-03-21 20:32:32 +00:00
+ (int)(textEdit->document()->documentMargin() * 2)))
2021-01-24 14:50:13 +00:00
/ fontMetrics.lineSpacing();
2018-03-21 20:32:32 +00:00
}
2018-03-21 20:32:32 +00:00
int getMaxFullyDisplayedLines(QPlainTextEdit *plainTextEdit)
{
QFontMetrics fontMetrics(plainTextEdit->document()->defaultFont());
return (plainTextEdit->height()
2021-01-24 14:50:13 +00:00
- (plainTextEdit->contentsMargins().top() + plainTextEdit->contentsMargins().bottom()
2018-03-21 20:32:32 +00:00
+ (int)(plainTextEdit->document()->documentMargin() * 2)))
2021-01-24 14:50:13 +00:00
/ fontMetrics.lineSpacing();
2018-03-21 20:32:32 +00:00
}
2018-03-21 20:32:32 +00:00
QByteArray applyColorToSvg(const QByteArray &data, QColor color)
{
2021-01-24 14:50:13 +00:00
static const QRegularExpression styleRegExp(
"(?:style=\".*fill:(.*?);.*?\")|(?:fill=\"(.*?)\")");
2018-03-21 20:32:32 +00:00
QString replaceStr = QString("#%1").arg(color.rgb() & 0xffffff, 6, 16, QLatin1Char('0'));
int replaceStrLen = replaceStr.length();
2018-03-21 20:32:32 +00:00
QString xml = QString::fromUtf8(data);
2018-03-21 20:32:32 +00:00
int offset = 0;
while (true) {
QRegularExpressionMatch match = styleRegExp.match(xml, offset);
if (!match.hasMatch()) {
break;
}
2018-03-21 20:32:32 +00:00
int captureIndex = match.captured(1).isNull() ? 2 : 1;
2021-01-24 14:50:13 +00:00
xml.replace(match.capturedStart(captureIndex), match.capturedLength(captureIndex),
replaceStr);
2018-03-21 20:32:32 +00:00
offset = match.capturedStart(captureIndex) + replaceStrLen;
}
2018-03-21 20:32:32 +00:00
return xml.toUtf8();
}
2017-12-03 16:26:01 +00:00
2018-03-21 20:32:32 +00:00
QByteArray applyColorToSvg(const QString &filename, QColor color)
{
QFile file(filename);
file.open(QIODevice::ReadOnly);
return applyColorToSvg(file.readAll(), color);
}
2017-12-03 16:26:01 +00:00
/**
2021-01-24 14:50:13 +00:00
* @brief finds the theme-specific icon path and calls `setter` functor providing a pointer of an
* object which has to be used and loaded icon
* @param supportedIconsNames list of <object ptr, icon name>
* @param setter functor which has to be called
2021-01-24 14:50:13 +00:00
* for example we need to set an action icon, the functor can be just [](void* o, const QIcon
* &icon) { static_cast<QAction*>(o)->setIcon(icon); }
*/
void setThemeIcons(QList<QPair<void *, QString>> supportedIconsNames,
std::function<void(void *, const QIcon &)> setter)
{
if (supportedIconsNames.isEmpty() || !setter) {
return;
}
const QString &iconsDirPath = QStringLiteral(":/img/icons/");
const QString &currTheme = Config()->getCurrentTheme()->name;
const QString &relativeThemeDir = currTheme.toLower() + "/";
QString iconPath;
foreach (const auto &p, supportedIconsNames) {
iconPath = iconsDirPath;
// Verify that indeed there is an alternative icon in this theme
// Otherwise, fallback to the regular icon folder
2021-01-24 14:50:13 +00:00
if (QFile::exists(iconPath + relativeThemeDir + p.second)) {
iconPath += relativeThemeDir;
}
setter(p.first, QIcon(iconPath + p.second));
}
}
void prependQAction(QAction *action, QMenu *menu)
{
auto actions = menu->actions();
if (actions.empty()) {
menu->addAction(action);
} else {
menu->insertAction(actions.first(), action);
}
}
qreal devicePixelRatio(const QPaintDevice *p)
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
return p->devicePixelRatioF();
#else
return p->devicePixelRatio();
#endif
}
void selectIndexByData(QComboBox *widget, QVariant data, int defaultIndex)
{
for (int i = 0; i < widget->count(); i++) {
if (widget->itemData(i) == data) {
widget->setCurrentIndex(i);
return;
}
}
widget->setCurrentIndex(defaultIndex);
}
void emitColumnChanged(QAbstractItemModel *model, int column)
{
if (model && model->rowCount()) {
2021-01-24 14:50:13 +00:00
emit model->dataChanged(model->index(0, column),
model->index(model->rowCount() - 1, column), { Qt::DisplayRole });
}
}
bool filterStringContains(const QString &string, const QSortFilterProxyModel *model)
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
return string.contains(model->filterRegExp());
#else
return string.contains(model->filterRegularExpression());
#endif
}
QPointF mouseEventPos(QMouseEvent *ev)
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
return ev->localPos();
#else
return ev->position();
#endif
}
QPoint mouseEventGlobalPos(QMouseEvent *ev)
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
return ev->globalPos();
#else
return ev->globalPosition().toPoint();
#endif
}
} // end namespace