All checks were successful
Build ptprnt / build (push) Successful in 3m50s
Reviewed-on: moritz/ptouch-prnt#15
192 lines
6.5 KiB
C++
192 lines
6.5 KiB
C++
/*
|
|
ptrnt - print labels on linux
|
|
Copyright (C) 2023-2025 Moritz Martinius
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
#include "PtouchPrint.hpp"
|
|
|
|
#include <fmt/core.h>
|
|
#include <spdlog/sinks/basic_file_sink.h>
|
|
#include <spdlog/sinks/stdout_color_sinks.h>
|
|
#include <spdlog/spdlog.h>
|
|
|
|
#include "cli/CliParser.hpp"
|
|
#include "cli/interface/ICliParser.hpp"
|
|
#include "constants.hpp"
|
|
#include "core/PrinterDriverFactory.hpp"
|
|
#include "core/PrinterService.hpp"
|
|
#include "core/interface/IPrinterService.hpp"
|
|
#include "graphics/LabelBuilder.hpp"
|
|
|
|
namespace ptprnt {
|
|
|
|
PtouchPrint::PtouchPrint(const char* versionString)
|
|
: PtouchPrint(versionString, std::make_unique<cli::CliParser>(ptprnt::APP_DESC, versionString),
|
|
std::make_unique<core::PrinterService>()) {}
|
|
|
|
PtouchPrint::PtouchPrint(const char* versionString, std::unique_ptr<cli::ICliParser> cliParser,
|
|
std::unique_ptr<core::IPrinterService> printerService)
|
|
: mVersionString(versionString), mCliParser(std::move(cliParser)), mPrinterService(std::move(printerService)) {}
|
|
|
|
PtouchPrint::~PtouchPrint() = default;
|
|
|
|
int PtouchPrint::init(int argc, char** argv) {
|
|
// Parse CLI arguments
|
|
int parseResult = mCliParser->parse(argc, argv);
|
|
if (parseResult != 0) {
|
|
// Pass through: positive = clean exit (help/version), negative = error
|
|
return parseResult;
|
|
}
|
|
|
|
// Setup logging based on CLI flags
|
|
setupLogger();
|
|
|
|
// Initialize printer service
|
|
if (!mPrinterService->initialize()) {
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int PtouchPrint::run() {
|
|
spdlog::info("ptprnt version {}", mVersionString);
|
|
|
|
const auto& options = mCliParser->getOptions();
|
|
|
|
// Handle --list-all-drivers
|
|
if (options.listDrivers) {
|
|
return handleListDrivers() ? 0 : -1;
|
|
}
|
|
|
|
// Handle printing
|
|
return handlePrinting() ? 0 : -1;
|
|
}
|
|
|
|
void PtouchPrint::setupLogger() {
|
|
const auto& options = mCliParser->getOptions();
|
|
|
|
spdlog::level::level_enum level = spdlog::level::warn;
|
|
if (options.trace) {
|
|
level = spdlog::level::trace;
|
|
} else if (options.verbose) {
|
|
level = spdlog::level::debug;
|
|
}
|
|
|
|
auto consoleSink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
|
|
consoleSink->set_level(level);
|
|
consoleSink->set_pattern("%^%L:%$ %v");
|
|
|
|
auto fileSink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("ptprnt.log", true);
|
|
fileSink->set_level(spdlog::level::trace);
|
|
fileSink->set_pattern("%Y-%m-%d %H:%m:%S:%e [pid:%P tid:%t] [%^%l%$] %v (%@)");
|
|
|
|
std::vector<spdlog::sink_ptr> sinks{consoleSink, fileSink};
|
|
auto logger = std::make_shared<spdlog::logger>("default_logger", sinks.begin(), sinks.end());
|
|
logger->set_level(spdlog::level::trace);
|
|
spdlog::set_default_logger(logger);
|
|
}
|
|
|
|
bool PtouchPrint::handleListDrivers() {
|
|
auto driverFactory = std::make_unique<PrinterDriverFactory>();
|
|
auto drivers = driverFactory->listAllDrivers();
|
|
|
|
fmt::print("Available printer drivers:\n");
|
|
for (const auto& driver : drivers) {
|
|
fmt::print(" - {}\n", driver);
|
|
}
|
|
fmt::print("\nUse with: -p <driver_name> or --printer <driver_name>\n");
|
|
return true;
|
|
}
|
|
|
|
bool PtouchPrint::handlePrinting() {
|
|
const auto& options = mCliParser->getOptions();
|
|
|
|
// Select printer
|
|
auto printer = mPrinterService->selectPrinter(options.printerSelection);
|
|
if (!printer) {
|
|
spdlog::error("Failed to select printer");
|
|
return false;
|
|
}
|
|
|
|
// Get printer status
|
|
auto status = printer->getPrinterStatus();
|
|
spdlog::info("Detected tape width is {}mm", status.tapeWidthMm);
|
|
|
|
// Check if there are any commands
|
|
if (options.commands.empty()) {
|
|
spdlog::warn("No command specified, nothing to do...");
|
|
return true;
|
|
}
|
|
|
|
// Build label using LabelBuilder
|
|
graphics::LabelBuilder labelBuilder(printer->getPrinterInfo().pixelLines);
|
|
|
|
for (const auto& [cmdType, value] : options.commands) {
|
|
switch (cmdType) {
|
|
case cli::CommandType::Text:
|
|
labelBuilder.addText(value);
|
|
break;
|
|
case cli::CommandType::Font:
|
|
spdlog::debug("Setting font to {}", value);
|
|
labelBuilder.setFontFamily(value);
|
|
break;
|
|
case cli::CommandType::FontSize:
|
|
spdlog::debug("Setting font size to {}", std::stod(value));
|
|
labelBuilder.setFontSize(std::stod(value));
|
|
break;
|
|
case cli::CommandType::HAlign: {
|
|
spdlog::debug("Setting text horizontal alignment to {}", value);
|
|
auto hPos = HALignPositionMap.find(value);
|
|
if (hPos == HALignPositionMap.end()) {
|
|
spdlog::warn("Invalid horizontal alignment specified!");
|
|
labelBuilder.setHAlign(HAlignPosition::UNKNOWN);
|
|
} else {
|
|
labelBuilder.setHAlign(hPos->second);
|
|
}
|
|
break;
|
|
}
|
|
case cli::CommandType::VAlign: {
|
|
spdlog::debug("Setting text vertical alignment to {}", value);
|
|
auto vPos = VALignPositionMap.find(value);
|
|
if (vPos == VALignPositionMap.end()) {
|
|
spdlog::warn("Invalid vertical alignment specified!");
|
|
labelBuilder.setVAlign(VAlignPosition::UNKNOWN);
|
|
} else {
|
|
labelBuilder.setVAlign(vPos->second);
|
|
}
|
|
break;
|
|
}
|
|
case cli::CommandType::None:
|
|
[[fallthrough]];
|
|
default:
|
|
spdlog::warn("This command is currently not supported.");
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Build and print the label
|
|
auto label = labelBuilder.build();
|
|
if (!mPrinterService->printLabel(std::move(label))) {
|
|
spdlog::error("An error occurred while printing");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
} // namespace ptprnt
|