diff --git a/src/common/actionmanager.cpp b/src/common/actionmanager.cpp
index da74828a..9a058b4f 100755
--- a/src/common/actionmanager.cpp
+++ b/src/common/actionmanager.cpp
@@ -447,6 +447,10 @@ void ActionManager::initialize()
a->m_iconName = "color_management";
A("edit_qty", QT_TR_NOOP("Quantity"), NeedSelection(1), FlagMenu);
A("edit_qty_set", QT_TR_NOOP("Set quantity..."));
+ A("edit_qty_add", QT_TR_NOOP("Add to quantity..."), NeedSelection(1));
+ a->m_iconName = "list-add";
+ A("edit_qty_subtract", QT_TR_NOOP("Subtract from quantity..."), NeedSelection(1));
+ a->m_iconName = "list-remove";
A("edit_qty_multiply", QT_TR_NOOP("Multiply quantity..."), QT_TR_NOOP("Ctrl+*", "Edit|Quantity|Multiply"), NeedSelection(1));
A("edit_qty_divide", QT_TR_NOOP("Divide quantity..."), QT_TR_NOOP("Ctrl+/", "Edit|Quantity|Divide"), NeedSelection(1));
A("edit_price", QT_TR_NOOP("Price"), NeedSelection(1), FlagMenu);
diff --git a/src/common/document.cpp b/src/common/document.cpp
index 3850a12a..6be1f3c6 100755
--- a/src/common/document.cpp
+++ b/src/common/document.cpp
@@ -341,6 +341,18 @@ Document::Document(DocumentModel *model, const QByteArray &columnsState, bool re
multiplyQuantity(*i);
}
} },
+ { "edit_qty_add", [this](bool) -> QCoro::Task<> {
+ if (auto i = co_await UIHelpers::getInteger(tr("Add this quantity to all selected items:"),
+ tr("+"), 1, 1, DocumentModel::maxQuantity)) {
+ addQuantity(*i);
+ }
+ } },
+ { "edit_qty_subtract", [this](bool) -> QCoro::Task<> {
+ if (auto i = co_await UIHelpers::getInteger(tr("Subtract this quantity from all selected items:"),
+ tr("-"), 1, 1, DocumentModel::maxQuantity)) {
+ addQuantity(-*i);
+ }
+ } },
{ "edit_bulk", [this](bool) -> QCoro::Task<> {
if (selectedLots().isEmpty())
co_return;
@@ -1335,7 +1347,35 @@ void Document::multiplyQuantity(int factor)
});
}
+void Document::addQuantity(int delta)
+{
+ if (delta == 0)
+ return;
+
+ int lotsOutOfRange = 0;
+ for (const Lot *item : std::as_const(m_selectedLots)) {
+ qint64 newQty = qint64(item->quantity()) + delta;
+ if (newQty > DocumentModel::maxQuantity || newQty < -DocumentModel::maxQuantity)
+ lotsOutOfRange++;
+ }
+
+ if (lotsOutOfRange) {
+ UIHelpers::information(tr("The quantities of %n lot(s) would exceed the allowed quantity range (%1 to %2) when %3 by %4.
Nothing has been modified.",
+ nullptr, lotsOutOfRange)
+ .arg(-DocumentModel::maxQuantity)
+ .arg(DocumentModel::maxQuantity)
+ .arg(delta > 0 ? tr("increased") : tr("decreased"))
+ .arg(qAbs(delta)));
+ return;
+ }
+
+ const char *actionName = delta > 0 ? "edit_qty_add" : "edit_qty_subtract";
+ applyTo(selectedLots(), actionName, [=](const auto &from, auto &to) {
+ (to = from).setQuantity(from.quantity() + delta);
+ return DocumentModel::LotChanged;
+ });
+}
void Document::setSale(int sale)
{
diff --git a/src/common/document.h b/src/common/document.h
index 8afd1321..9de38837 100755
--- a/src/common/document.h
+++ b/src/common/document.h
@@ -175,6 +175,7 @@ class Document : public QObject
void costAdjust(bool isFixed, double value);
void divideQuantity(int divisor);
void multiplyQuantity(int factor);
+ void addQuantity(int delta);
void setSale(int sale);
void setBulkQuantity(int qty);
void setQuantity(int quantity);
diff --git a/src/desktop/desktopapplication.cpp b/src/desktop/desktopapplication.cpp
index 358b8f6b..82c3c5ca 100755
--- a/src/desktop/desktopapplication.cpp
+++ b/src/desktop/desktopapplication.cpp
@@ -200,7 +200,7 @@ void DesktopApplication::init()
#if defined(Q_OS_MACOS)
if (SystemInfo::inst()->value(u"build.qt.version"_qs).toString() == u"6.4.3") {
const auto macos = QVersionNumber::fromString(QSysInfo::productVersion());
- if (macos >= QVersionNumber(13))
+ if (macos >= QVersionNumber(13)) {
QString text = tr("You are using the legacy version of BrickStore for old macOS 10, 11 "
"and 12 machines, but you are running macOS %1.")
.arg(QSysInfo::productVersion())
diff --git a/src/desktop/mainwindow.cpp b/src/desktop/mainwindow.cpp
index 412b4c78..c027c5e4 100755
--- a/src/desktop/mainwindow.cpp
+++ b/src/desktop/mainwindow.cpp
@@ -611,6 +611,8 @@ void MainWindow::setupMenuBar()
setupMenu("edit_qty", {
"edit_qty_set",
+ "edit_qty_add",
+ "edit_qty_subtract",
"edit_qty_multiply",
"edit_qty_divide",
});
@@ -1082,6 +1084,8 @@ QStringList MainWindow::defaultToolBarActionNames() const
u"-"_qs,
u"edit_additems"_qs,
u"edit_subtractitems"_qs,
+ u"edit_qty_add"_qs,
+ u"edit_qty_subtract"_qs,
u"edit_mergeitems"_qs,
u"edit_partoutitems"_qs,
u"-"_qs,
diff --git a/src/desktop/view.cpp b/src/desktop/view.cpp
index 272c84d9..2db60b92 100755
--- a/src/desktop/view.cpp
+++ b/src/desktop/view.cpp
@@ -689,7 +689,8 @@ void View::contextMenu(const QPoint &pos)
case DocumentModel::QuantityOrig:
case DocumentModel::QuantityDiff:
case DocumentModel::Quantity:
- actionNames = { "edit_qty_set", "edit_qty_multiply", "edit_qty_divide" };
+ actionNames = { "edit_qty_set", "edit_qty_add", "edit_qty_subtract", "-",
+ "edit_qty_multiply", "edit_qty_divide" };
break;
case DocumentModel::PriceOrig:
case DocumentModel::PriceDiff:
diff --git a/src/mobile/ViewEditMenu.qml b/src/mobile/ViewEditMenu.qml
index b025ac9c..535a5d09 100755
--- a/src/mobile/ViewEditMenu.qml
+++ b/src/mobile/ViewEditMenu.qml
@@ -65,6 +65,8 @@ AutoSizingMenu {
ActionMenuItem { actionName: "edit_subcond_incomplete"; visible: enabled && root.is(BS.Document.Condition) }
ActionMenuItem { actionName: "edit_color"; visible: enabled && root.is(BS.Document.Color) }
ActionMenuItem { actionName: "edit_qty_set"; visible: enabled && root.is(BS.Document.Quantity) }
+ ActionMenuItem { actionName: "edit_qty_add"; visible: enabled && root.is(BS.Document.Quantity) }
+ ActionMenuItem { actionName: "edit_qty_subtract"; visible: enabled && root.is(BS.Document.Quantity) }
ActionMenuItem { actionName: "edit_qty_multiply"; visible: enabled && root.is(BS.Document.Quantity) }
ActionMenuItem { actionName: "edit_qty_divide"; visible: enabled && root.is(BS.Document.Quantity) }
ActionMenuItem { actionName: "edit_price_set"; visible: enabled && root.is([ BS.Document.Price, BS.Document.Total ]) }