diff --git a/.vscode/settings.json b/.vscode/settings.json index 351793d..8fd89e6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -88,6 +88,9 @@ }, "clangd.onConfigChanged": "restart", "cSpell.words": [ + "fontsize", + "halign", + "libusb", "ptrnt" ], } \ No newline at end of file diff --git a/src/PtouchPrint.cpp b/src/PtouchPrint.cpp index 36d0079..93cefed 100644 --- a/src/PtouchPrint.cpp +++ b/src/PtouchPrint.cpp @@ -1,4 +1,4 @@ -/* +/* ptrnt - print labels on linux Copyright (C) 2023-2025 Moritz Martinius @@ -18,191 +18,159 @@ */ #include "PtouchPrint.hpp" -#include -#include #include -#include -#include -#include -#include #include #include #include -#include -#include -#include -#include -#include - -#include "CLI/Option.hpp" -#include "PrinterDriverFactory.hpp" +#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" -#include "graphics/interface/ILabel.hpp" -#include "libusbwrap/UsbDeviceFactory.hpp" namespace ptprnt { -PtouchPrint::PtouchPrint(const char* versionString) : mVersionString{versionString} {} +PtouchPrint::PtouchPrint(const char* versionString) + : PtouchPrint(versionString, std::make_unique(ptprnt::APP_DESC, versionString), + std::make_unique()) {} + +PtouchPrint::PtouchPrint(const char* versionString, std::unique_ptr cliParser, + std::unique_ptr printerService) + : mVersionString(versionString), mCliParser(std::move(cliParser)), mPrinterService(std::move(printerService)) {} + +PtouchPrint::~PtouchPrint() = default; int PtouchPrint::init(int argc, char** argv) { - setupCliParser(); + // Parse CLI arguments + int parseResult = mCliParser->parse(argc, argv); + if (parseResult != 0) { + // Pass through: positive = clean exit (help/version), negative = error + return parseResult; + } - try { - mApp.parse(argc, argv); - } catch (const CLI::ParseError& e) { - mApp.exit(e); + // Setup logging based on CLI flags + setupLogger(); + + // Initialize printer service + if (!mPrinterService->initialize()) { return -1; } - // Set log level based on flags - if (mTraceFlag) { - setupLogger(spdlog::level::trace); - } else if (mVerboseFlag) { - setupLogger(spdlog::level::debug); - } else { - setupLogger(spdlog::level::warn); - } - - if (!mUsbDeviceFactory.init()) { - spdlog::error("Could not initialize libusb"); - return -1; - } return 0; } int PtouchPrint::run() { spdlog::info("ptprnt version {}", mVersionString); - // Handle --list-all-drivers flag - if (mListDriversFlag) { - auto driverFactory = std::make_unique(); - auto drivers = driverFactory->listAllDrivers(); + const auto& options = mCliParser->getOptions(); - fmt::print("Available printer drivers:\n"); - for (const auto& driver : drivers) { - fmt::print(" - {}\n", driver); - } - fmt::print("\nUse with: -p or --printer \n"); - return 0; + // Handle --list-all-drivers + if (options.listDrivers) { + return handleListDrivers() ? 0 : -1; } - // Determine which printer to use - std::shared_ptr printer = nullptr; + // Handle printing + return handlePrinting() ? 0 : -1; +} - if (mPrinterSelection != "auto") { - // Explicit printer selection by name - auto driverFactory = std::make_unique(); - printer = driverFactory->createByName(mPrinterSelection); +void PtouchPrint::setupLogger() { + const auto& options = mCliParser->getOptions(); - if (!printer) { - spdlog::error("Failed to create printer driver '{}'", mPrinterSelection); - spdlog::info("Use --list-all-drivers to see available drivers"); - return -1; - } - - spdlog::info("Using explicitly selected printer: {}", mPrinterSelection); - - // FakePrinter doesn't need USB device attachment - if (mPrinterSelection == "FakePrinter" || mPrinterSelection == "fake") { - printer->attachUsbDevice(nullptr); - } else { - // Real printer needs USB device - const auto printerUsbId = printer->getUsbId(); - auto devices = mUsbDeviceFactory.findDevices(printerUsbId.first, printerUsbId.second); - - if (devices.empty()) { - spdlog::error("No USB device found for printer {}. Is it connected and powered on?", mPrinterSelection); - return -1; - } - - if (devices.size() > 1) { - spdlog::warn("Found more than one device of the same printer on bus. Using first one."); - } - - if (!printer->attachUsbDevice(std::move(devices[0]))) { - spdlog::error("Failed to attach USB device to printer"); - return -1; - } - } - } else { - // Auto-detect printer from USB devices - mDetectedPrinters = getCompatiblePrinters(); - auto numFoundPrinters = mDetectedPrinters.size(); - - if (numFoundPrinters == 0) { - spdlog::error("No compatible printers found, please make sure that they are turned on and connected"); - spdlog::info("Tip: Use -p FakePrinter for testing without hardware"); - return -1; - } else if (numFoundPrinters > 1) { - spdlog::warn("Found more than one compatible printer. Use -p to select explicitly."); - return -1; - } - - printer = mDetectedPrinters[0]; - const auto printerUsbId = printer->getUsbId(); - auto devices = mUsbDeviceFactory.findDevices(printerUsbId.first, printerUsbId.second); - - if (devices.size() != 1) { - spdlog::warn("Found more than one device of the same printer on bus. Currently not supported"); - return -1; - } - - if (!printer->attachUsbDevice(std::move(devices[0]))) { - spdlog::error("Failed to attach USB device to printer"); - return -1; - } + 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(); + consoleSink->set_level(level); + consoleSink->set_pattern("%^%L:%$ %v"); + + auto fileSink = std::make_shared("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 sinks{consoleSink, fileSink}; + auto logger = std::make_shared("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(); + auto drivers = driverFactory->listAllDrivers(); + + fmt::print("Available printer drivers:\n"); + for (const auto& driver : drivers) { + fmt::print(" - {}\n", driver); + } + fmt::print("\nUse with: -p or --printer \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); - if (0 == mCommands.size()) { + // Check if there are any commands + if (options.commands.empty()) { spdlog::warn("No command specified, nothing to do..."); - return 0; + return true; } - // Use LabelBuilder to construct the label + // Build label using LabelBuilder graphics::LabelBuilder labelBuilder(printer->getPrinterInfo().pixelLines); - for (const auto& [cmd, value] : mCommands) { - switch (cmd) { - case CliCmdType::Text: + for (const auto& [cmdType, value] : options.commands) { + switch (cmdType) { + case cli::CommandType::Text: labelBuilder.addText(value); break; - case CliCmdType::Font: + case cli::CommandType::Font: spdlog::debug("Setting font to {}", value); labelBuilder.setFontFamily(value); break; - case CliCmdType::FontSize: + case cli::CommandType::FontSize: spdlog::debug("Setting font size to {}", std::stod(value)); labelBuilder.setFontSize(std::stod(value)); break; - case CliCmdType::HAlign: + 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); - } + 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 CliCmdType::VAlign: + } + 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); - } + 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 CliCmdType::None: + } + case cli::CommandType::None: [[fallthrough]]; default: spdlog::warn("This command is currently not supported."); @@ -210,114 +178,14 @@ int PtouchPrint::run() { } } + // Build and print the label auto label = labelBuilder.build(); - if (!printer->printLabel(std::move(label))) { - spdlog::error("An error occured while printing"); - return -1; + if (!mPrinterService->printLabel(std::move(label))) { + spdlog::error("An error occurred while printing"); + return false; } - return 0; + return true; } -std::vector> PtouchPrint::getCompatiblePrinters() { - - auto usbDevs = mUsbDeviceFactory.findAllDevices(); - auto driverFactory = std::make_unique(); - std::vector> foundPrinterDrivers{}; - - for (auto& usbDev : usbDevs) { - auto driver = driverFactory->create(usbDev->getUsbId()); - if (driver != nullptr) { - foundPrinterDrivers.push_back(driver); - } - } - return foundPrinterDrivers; -} - -void PtouchPrint::setupLogger(spdlog::level::level_enum lvl) { - auto consoleSink = std::make_shared(); - consoleSink->set_level(lvl); - if (spdlog::level::level_enum::debug == lvl || spdlog::level::level_enum::trace == lvl) { - // This will enable file and line number for debug and trace macros - // TODO: line number and functions only work with macros - consoleSink->set_pattern("%^%L:%$ %v"); - } else { - consoleSink->set_pattern("%^%L:%$ %v"); - } - - auto fileSink = std::make_shared("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 sinks{consoleSink, fileSink}; - auto logger = std::make_shared("default_logger", sinks.begin(), sinks.end()); - logger->set_level(spdlog::level::trace); - spdlog::set_default_logger(logger); -} - -// TODO: CLI parsing should be a seperate class/file -void PtouchPrint::setupCliParser() { - auto printVersion = [this](std::size_t) { - fmt::print("ptprnt version: {}\n", mVersionString); - }; - - // General options - mApp.add_flag("-v,--verbose", mVerboseFlag, "Enable verbose output"); - mApp.add_flag("--trace", mTraceFlag, "Enable trace output (shows USB communication)"); - mApp.add_flag("-V,--version", printVersion, "Prints the ptprnt's version"); - - // Printer selection - mApp.add_option("-p,--printer", mPrinterSelection, - "Select printer driver (default: auto). Use --list-all-drivers to see available options") - ->default_val("auto"); - - mApp.add_flag("--list-all-drivers", mListDriversFlag, "List all available printer drivers and exit"); - - // Text printing options - mApp.add_option("-t,--text", - "Text to print (can be used multple times, use formatting options before to " - "influence text layout)") - ->group("Printing") - ->multi_option_policy(CLI::MultiOptionPolicy::TakeAll) - ->trigger_on_parse() - ->each([this](std::string text) { mCommands.emplace_back(CliCmdType::Text, text); }); - mApp.add_option("-f,--font", "Font used for the following text occurences") - ->group("Text printing ") - ->multi_option_policy(CLI::MultiOptionPolicy::TakeFirst) - ->trigger_on_parse() - ->each([this](std::string font) { mCommands.emplace_back(CliCmdType::Font, font); }); - mApp.add_option("-s,--fontsize", "Font size of the following text occurences") - ->group("Text printing ") - ->multi_option_policy(CLI::MultiOptionPolicy::TakeFirst) - ->trigger_on_parse() - ->each([this](std::string size) { mCommands.emplace_back(CliCmdType::FontSize, size); }); - mApp.add_option("--valign", "Vertical alignment of the following text occurences") - ->group("Text printing ") - ->multi_option_policy(CLI::MultiOptionPolicy::TakeFirst) - ->trigger_on_parse() - ->transform([](std::string in) -> std::string { - std::unordered_set validValignOptions{"top", "middle", "bottom"}; - std::ranges::transform(in, in.begin(), [](unsigned char c) { return std::tolower(c); }); - if (validValignOptions.find(in) == validValignOptions.end()) { - return {""}; - } - return in; - }) - ->each([this](std::string valign) { mCommands.emplace_back(CliCmdType::VAlign, valign); }); - mApp.add_option("--halign", "Vertical alignment of the following text occurences") - ->group("Text printing ") - ->multi_option_policy(CLI::MultiOptionPolicy::TakeFirst) - ->trigger_on_parse() - ->transform([](std::string in) -> std::string { - std::unordered_set validValignOptions{"left", "center", "right", "justify"}; - std::transform(in.begin(), in.end(), in.begin(), [](unsigned char c) { return std::tolower(c); }); - if (validValignOptions.find(in) == validValignOptions.end()) { - return {""}; - } - return in; - }) - ->each([this](std::string halign) { mCommands.emplace_back(CliCmdType::HAlign, halign); }); - - // Image options - mApp.add_option("-i,--image", "Image to print. Excludes all text printing ")->group("Image printing"); -} -} // namespace ptprnt \ No newline at end of file +} // namespace ptprnt diff --git a/src/PtouchPrint.hpp b/src/PtouchPrint.hpp index 911eea8..38c5c97 100644 --- a/src/PtouchPrint.hpp +++ b/src/PtouchPrint.hpp @@ -1,4 +1,4 @@ -/* +/* ptrnt - print labels on linux Copyright (C) 2023-2025 Moritz Martinius @@ -19,49 +19,75 @@ #pragma once -#include -#include -#include +#include +#include -#include "constants.hpp" -#include "interface/IPrinterDriver.hpp" -#include "libusbwrap/UsbDeviceFactory.hpp" +namespace ptprnt::cli { +class ICliParser; +} + +namespace ptprnt::core { +class IPrinterService; +} namespace ptprnt { -enum class CliCmdType { None = 0, Text = 1, FontSize = 2, Font = 3, VAlign = 4, HAlign = 5 }; -using CliCmd = std::pair; +/** + * @brief Main application class for ptprnt + * + * Acts as a thin glue layer coordinating CLI parsing and core printer functionality. + * Separates CLI frontend concerns from the core library. + * + * Uses interfaces (ICliParser, IPrinterService) to enable dependency injection + * and facilitate unit testing with mocks. + */ class PtouchPrint { public: + /** + * @brief Construct the application with default implementations + * @param versionString Version string to display + */ PtouchPrint(const char* versionString); - ~PtouchPrint() = default; - // This is basically a singelton application class, no need to copy or move + /** + * @brief Construct with custom implementations (for testing) + * @param versionString Version string to display + * @param cliParser Custom CLI parser implementation + * @param printerService Custom printer service implementation + */ + PtouchPrint(const char* versionString, std::unique_ptr cliParser, + std::unique_ptr printerService); + + ~PtouchPrint(); // Must be defined in .cpp where complete types are visible + + // This is basically a singleton application class, no need to copy or move PtouchPrint(const PtouchPrint&) = delete; PtouchPrint& operator=(const PtouchPrint&) = delete; PtouchPrint(PtouchPrint&&) = delete; PtouchPrint& operator=(PtouchPrint&&) = delete; + /** + * @brief Initialize the application + * @param argc Argument count + * @param argv Argument values + * @return 0 on success, non-zero on error + */ int init(int argc, char** argv); + + /** + * @brief Run the application + * @return 0 on success, non-zero on error + */ int run(); private: - // methods - void setupLogger(spdlog::level::level_enum lvl); - void setupCliParser(); - std::vector> getCompatiblePrinters(); + void setupLogger(); + bool handleListDrivers(); + bool handlePrinting(); - // member variables - CLI::App mApp{ptprnt::APP_DESC}; - libusbwrap::UsbDeviceFactory mUsbDeviceFactory{}; - std::vector> mDetectedPrinters{}; - std::vector mCommands{}; - std::string mVersionString = ""; - - // CLI flags and options - bool mVerboseFlag = false; - bool mTraceFlag = false; - std::string mPrinterSelection = "auto"; - bool mListDriversFlag = false; + std::string mVersionString; + std::unique_ptr mCliParser; + std::unique_ptr mPrinterService; }; -} // namespace ptprnt \ No newline at end of file + +} // namespace ptprnt diff --git a/src/cli/CliParser.cpp b/src/cli/CliParser.cpp new file mode 100644 index 0000000..275b1b3 --- /dev/null +++ b/src/cli/CliParser.cpp @@ -0,0 +1,94 @@ +/* + ptrnt - print labels on linux + Copyright (C) 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 . + + */ + +#include "CliParser.hpp" + +#include + +namespace ptprnt::cli { + +CliParser::CliParser(std::string appDescription, std::string versionString) + : mApp(std::move(appDescription)), mVersionString(std::move(versionString)) { + setupParser(); +} + +int CliParser::parse(int argc, char** argv) { + try { + mApp.parse(argc, argv); + } catch (const CLI::CallForHelp& e) { + // User requested help - display it and signal clean exit + mApp.exit(e); + return 1; // Signal: exit cleanly + } catch (const CLI::CallForVersion&) { + // User requested version - already displayed by callback + return 1; // Signal: exit cleanly + } catch (const CLI::ParseError& e) { + // Parse error - display error message + mApp.exit(e); + return -1; // Signal: error + } + return 0; +} + +void CliParser::setupParser() { + // Version callback + auto printVersion = [this](std::size_t) { + fmt::print("ptprnt version: {}\n", mVersionString); + throw CLI::CallForVersion(); + }; + + // General options + mApp.add_flag("-v,--verbose", mOptions.verbose, "Enable verbose output"); + mApp.add_flag("--trace", mOptions.trace, "Enable trace output (shows USB communication)"); + mApp.add_flag("-V,--version", printVersion, "Prints the ptprnt's version"); + + // Printer selection + mApp.add_option("-p,--printer", mOptions.printerSelection, + "Select printer driver (default: auto). Use --list-all-drivers to see available options") + ->default_val("auto"); + + mApp.add_flag("--list-all-drivers", mOptions.listDrivers, "List all available printer drivers and exit"); + + // Text printing options + // Note: CLI11 options are processed in order when using ->each() with callbacks + mApp.add_option( + "-t,--text", + "Text to print (can be used multiple times, use formatting options before to influence text layout)") + ->multi_option_policy(CLI::MultiOptionPolicy::TakeAll) + ->each([this](const std::string& text) { mOptions.commands.emplace_back(CommandType::Text, text); }); + + // Text formatting options + mApp.add_option("-f,--font", "Font used for the following text occurrences") + ->multi_option_policy(CLI::MultiOptionPolicy::TakeAll) + ->each([this](const std::string& font) { mOptions.commands.emplace_back(CommandType::Font, font); }); + + mApp.add_option("-s,--fontsize", "Font size of the following text occurrences") + ->multi_option_policy(CLI::MultiOptionPolicy::TakeAll) + ->each([this](const std::string& size) { mOptions.commands.emplace_back(CommandType::FontSize, size); }); + + mApp.add_option("--valign", "Vertical alignment of the following text occurrences") + ->multi_option_policy(CLI::MultiOptionPolicy::TakeAll) + ->each([this](const std::string& align) { mOptions.commands.emplace_back(CommandType::VAlign, align); }); + + mApp.add_option("--halign", "Horizontal alignment of the following text occurrences") + ->multi_option_policy(CLI::MultiOptionPolicy::TakeAll) + ->each([this](const std::string& align) { mOptions.commands.emplace_back(CommandType::HAlign, align); }); +} + +} // namespace ptprnt::cli diff --git a/src/cli/CliParser.hpp b/src/cli/CliParser.hpp new file mode 100644 index 0000000..d4b83cd --- /dev/null +++ b/src/cli/CliParser.hpp @@ -0,0 +1,75 @@ +/* + ptrnt - print labels on linux + Copyright (C) 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 . + + */ + +#pragma once + +#include + +#include + +#include "interface/ICliParser.hpp" + +namespace ptprnt::cli { + +/** + * @brief CLI argument parser for ptprnt + * + * Concrete implementation of ICliParser using CLI11. + * Handles all command-line argument parsing. + * Separates CLI concerns from core library functionality. + */ +class CliParser : public ICliParser { + public: + /** + * @brief Construct a CLI parser + * @param appDescription Application description for help text + * @param versionString Version string to display + */ + CliParser(std::string appDescription, std::string versionString); + + ~CliParser() override = default; + + CliParser(const CliParser&) = delete; + CliParser& operator=(const CliParser&) = delete; + CliParser(CliParser&&) = delete; + CliParser& operator=(CliParser&&) = delete; + + /** + * @brief Parse command line arguments + * @param argc Argument count + * @param argv Argument values + * @return 0 on success, positive value if should exit immediately (help/version), negative on error + */ + int parse(int argc, char** argv) override; + + /** + * @brief Get the parsed options + * @return Reference to parsed options + */ + [[nodiscard]] const CliOptions& getOptions() const override { return mOptions; } + + private: + void setupParser(); + + CLI::App mApp; + std::string mVersionString; + CliOptions mOptions; +}; + +} // namespace ptprnt::cli diff --git a/src/cli/interface/ICliParser.hpp b/src/cli/interface/ICliParser.hpp new file mode 100644 index 0000000..aa1b278 --- /dev/null +++ b/src/cli/interface/ICliParser.hpp @@ -0,0 +1,73 @@ +/* + ptrnt - print labels on linux + Copyright (C) 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 . + + */ + +#pragma once + +#include +#include + +namespace ptprnt::cli { + +/** + * @brief Types of CLI commands that can be issued + */ +enum class CommandType { None = 0, Text = 1, FontSize = 2, Font = 3, VAlign = 4, HAlign = 5 }; + +/** + * @brief A command with its type and value + */ +using Command = std::pair; + +/** + * @brief Parsed CLI options and commands + */ +struct CliOptions { + bool verbose{false}; + bool trace{false}; + bool listDrivers{false}; + std::string printerSelection{"auto"}; + std::vector commands{}; +}; + +/** + * @brief Interface for CLI argument parsing + * + * This interface allows for mocking CLI parsing in unit tests + * and provides a clear contract for CLI parser implementations. + */ +class ICliParser { + public: + virtual ~ICliParser() = default; + + /** + * @brief Parse command line arguments + * @param argc Argument count + * @param argv Argument values + * @return 0 on success, positive value if should exit immediately (help/version), negative on error + */ + virtual int parse(int argc, char** argv) = 0; + + /** + * @brief Get the parsed options + * @return Reference to parsed options + */ + [[nodiscard]] virtual const CliOptions& getOptions() const = 0; +}; + +} // namespace ptprnt::cli diff --git a/src/PrinterDriverFactory.cpp b/src/core/PrinterDriverFactory.cpp similarity index 98% rename from src/PrinterDriverFactory.cpp rename to src/core/PrinterDriverFactory.cpp index 29cd109..766c718 100644 --- a/src/PrinterDriverFactory.cpp +++ b/src/core/PrinterDriverFactory.cpp @@ -1,6 +1,6 @@ /* ptrnt - print labels on linux - Copyright (C) 2024-2025 Moritz Martinius + Copyright (C) 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 diff --git a/src/PrinterDriverFactory.hpp b/src/core/PrinterDriverFactory.hpp similarity index 95% rename from src/PrinterDriverFactory.hpp rename to src/core/PrinterDriverFactory.hpp index a20cd7b..e37edd2 100644 --- a/src/PrinterDriverFactory.hpp +++ b/src/core/PrinterDriverFactory.hpp @@ -1,6 +1,6 @@ /* ptrnt - print labels on linux - Copyright (C) 2024-2025 Moritz Martinius + Copyright (C) 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 @@ -21,7 +21,7 @@ #include #include -#include "interface/IPrinterDriver.hpp" +#include "printers/interface/IPrinterDriver.hpp" #include "libusbwrap/LibUsbTypes.hpp" namespace ptprnt { diff --git a/src/core/PrinterService.cpp b/src/core/PrinterService.cpp new file mode 100644 index 0000000..535c4cb --- /dev/null +++ b/src/core/PrinterService.cpp @@ -0,0 +1,95 @@ +/* + ptrnt - print labels on linux + Copyright (C) 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 . + + */ + +#include "PrinterService.hpp" + +#include + +#include "core/PrinterDriverFactory.hpp" + +namespace ptprnt::core { + +PrinterService::PrinterService() = default; + +bool PrinterService::initialize() { + if (!mUsbDeviceFactory.init()) { + spdlog::error("Could not initialize libusb"); + return false; + } + return true; +} + +std::vector> PrinterService::detectPrinters() { + spdlog::debug("Detecting printers..."); + + auto usbDevs = mUsbDeviceFactory.findAllDevices(); + auto driverFactory = std::make_unique(); + mDetectedPrinters.clear(); + + for (auto& usbDev : usbDevs) { + auto driver = driverFactory->create(usbDev->getUsbId()); + if (driver != nullptr) { + mDetectedPrinters.push_back(driver); + } + } + + spdlog::debug("Found {} compatible printer(s)", mDetectedPrinters.size()); + return mDetectedPrinters; +} + +std::shared_ptr PrinterService::selectPrinter(const std::string& printerName) { + // If a specific printer is requested by name (not "auto"), try to create it directly + if (printerName != "auto") { + auto driverFactory = std::make_unique(); + auto printer = driverFactory->createByName(printerName); + if (printer) { + mCurrentPrinter = printer; + spdlog::info("Using explicitly selected printer: {}", printerName); + return mCurrentPrinter; + } + spdlog::error("Printer driver '{}' not found", printerName); + return nullptr; + } + + // Auto mode: detect USB printers + if (mDetectedPrinters.empty()) { + detectPrinters(); + } + + if (mDetectedPrinters.empty()) { + spdlog::error("No compatible printers detected"); + return nullptr; + } + + // Auto-select first detected printer + mCurrentPrinter = mDetectedPrinters.front(); + spdlog::info("Auto-selected printer: {}", mCurrentPrinter->getName()); + return mCurrentPrinter; +} + +bool PrinterService::printLabel(std::unique_ptr label) { + if (!mCurrentPrinter) { + spdlog::error("No printer selected"); + return false; + } + + return mCurrentPrinter->printLabel(std::move(label)); +} + +} // namespace ptprnt::core diff --git a/src/core/PrinterService.hpp b/src/core/PrinterService.hpp new file mode 100644 index 0000000..b4ea55f --- /dev/null +++ b/src/core/PrinterService.hpp @@ -0,0 +1,89 @@ +/* + ptrnt - print labels on linux + Copyright (C) 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 . + + */ + +#pragma once + +#include +#include +#include + +#include "interface/IPrinterService.hpp" +#include "libusbwrap/UsbDeviceFactory.hpp" +#include "printers/interface/IPrinterDriver.hpp" + +namespace ptprnt::core { + +/** + * @brief Core service for printer operations + * + * Concrete implementation of IPrinterService. + * Provides the core library functionality for: + * - Detecting printers + * - Selecting printers + * - Building and printing labels + */ +class PrinterService : public IPrinterService { + public: + PrinterService(); + ~PrinterService() override = default; + + PrinterService(const PrinterService&) = delete; + PrinterService& operator=(const PrinterService&) = delete; + PrinterService(PrinterService&&) = delete; + PrinterService& operator=(PrinterService&&) = delete; + + /** + * @brief Initialize USB device factory + * @return true on success, false on failure + */ + bool initialize() override; + + /** + * @brief Detect all compatible printers + * @return Vector of detected printers + */ + std::vector> detectPrinters() override; + + /** + * @brief Select a printer by name or auto-detect + * @param printerName Printer driver name, or "auto" for first detected + * @return Printer driver, or nullptr if not found + */ + std::shared_ptr selectPrinter(const std::string& printerName) override; + + /** + * @brief Get the currently selected printer + * @return Current printer, or nullptr if none selected + */ + [[nodiscard]] std::shared_ptr getCurrentPrinter() const override { return mCurrentPrinter; } + + /** + * @brief Print a label + * @param label The label to print + * @return true on success, false on failure + */ + bool printLabel(std::unique_ptr label) override; + + private: + libusbwrap::UsbDeviceFactory mUsbDeviceFactory; + std::vector> mDetectedPrinters; + std::shared_ptr mCurrentPrinter; +}; + +} // namespace ptprnt::core diff --git a/src/core/interface/IPrinterService.hpp b/src/core/interface/IPrinterService.hpp new file mode 100644 index 0000000..7f02511 --- /dev/null +++ b/src/core/interface/IPrinterService.hpp @@ -0,0 +1,74 @@ +/* + ptrnt - print labels on linux + Copyright (C) 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 . + + */ + +#pragma once + +#include +#include +#include + +#include "graphics/interface/ILabel.hpp" +#include "printers/interface/IPrinterDriver.hpp" + +namespace ptprnt::core { + +/** + * @brief Interface for core printer service operations + * + * This interface allows for mocking printer operations in unit tests + * and provides a clear contract for printer service implementations. + */ +class IPrinterService { + public: + virtual ~IPrinterService() = default; + + /** + * @brief Initialize the printer service + * @return true on success, false on failure + */ + virtual bool initialize() = 0; + + /** + * @brief Detect all compatible printers + * @return Vector of detected printers + */ + virtual std::vector> detectPrinters() = 0; + + /** + * @brief Select a printer by name or auto-detect + * @param printerName Printer driver name, or "auto" for first detected + * @return Printer driver, or nullptr if not found + */ + virtual std::shared_ptr selectPrinter(const std::string& printerName) = 0; + + /** + * @brief Get the currently selected printer + * @return Current printer, or nullptr if none selected + */ + [[nodiscard]] virtual std::shared_ptr getCurrentPrinter() const = 0; + + /** + * @brief Print a label + * @param label The label to print + * @return true on success, false on failure + */ + virtual bool printLabel(std::unique_ptr label) = 0; +}; + +} // namespace ptprnt::core diff --git a/src/graphics/Label.cpp b/src/graphics/Label.cpp index c4d112f..22e4515 100644 --- a/src/graphics/Label.cpp +++ b/src/graphics/Label.cpp @@ -1,6 +1,6 @@ /* ptrnt - print labels on linux - Copyright (C) 2023-2025 Moritz Martinius + Copyright (C) 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 diff --git a/src/graphics/Label.hpp b/src/graphics/Label.hpp index cee53e3..524ab92 100644 --- a/src/graphics/Label.hpp +++ b/src/graphics/Label.hpp @@ -1,6 +1,6 @@ /* ptrnt - print labels on linux - Copyright (C) 2023-2025 Moritz Martinius + Copyright (C) 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 diff --git a/src/graphics/interface/ILabel.hpp b/src/graphics/interface/ILabel.hpp index 5c5c059..b25cc5a 100644 --- a/src/graphics/interface/ILabel.hpp +++ b/src/graphics/interface/ILabel.hpp @@ -1,6 +1,6 @@ /* ptrnt - print labels on linux - Copyright (C) 2024-2025 Moritz Martinius + Copyright (C) 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 diff --git a/src/libusbwrap/LibUsbTypes.hpp b/src/libusbwrap/LibUsbTypes.hpp index f11c79b..6ed01d5 100644 --- a/src/libusbwrap/LibUsbTypes.hpp +++ b/src/libusbwrap/LibUsbTypes.hpp @@ -1,6 +1,6 @@ /* ptrnt - print labels on linux - Copyright (C) 2023-2024 Moritz Martinius + 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 diff --git a/src/libusbwrap/UsbDevice.cpp b/src/libusbwrap/UsbDevice.cpp index dd22aee..c480947 100644 --- a/src/libusbwrap/UsbDevice.cpp +++ b/src/libusbwrap/UsbDevice.cpp @@ -1,6 +1,6 @@ /* ptrnt - print labels on linux - Copyright (C) 2023-2024 Moritz Martinius + 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 diff --git a/src/libusbwrap/UsbDevice.hpp b/src/libusbwrap/UsbDevice.hpp index 475b1a3..c89aadf 100644 --- a/src/libusbwrap/UsbDevice.hpp +++ b/src/libusbwrap/UsbDevice.hpp @@ -1,6 +1,6 @@ /* ptrnt - print labels on linux - Copyright (C) 2023-2024 Moritz Martinius + 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 diff --git a/src/libusbwrap/UsbDeviceFactory.hpp b/src/libusbwrap/UsbDeviceFactory.hpp index 558a077..d8f7efa 100644 --- a/src/libusbwrap/UsbDeviceFactory.hpp +++ b/src/libusbwrap/UsbDeviceFactory.hpp @@ -1,6 +1,6 @@ /* ptrnt - print labels on linux - Copyright (C) 2023 Moritz Martinius + 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 diff --git a/src/libusbwrap/interface/IUsbDevice.hpp b/src/libusbwrap/interface/IUsbDevice.hpp index fe80de7..5b1572c 100644 --- a/src/libusbwrap/interface/IUsbDevice.hpp +++ b/src/libusbwrap/interface/IUsbDevice.hpp @@ -1,6 +1,6 @@ /* ptrnt - print labels on linux - Copyright (C) 2023-2024 Moritz Martinius + 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 @@ -22,7 +22,6 @@ #include #include -#include #include #include @@ -44,8 +43,9 @@ enum class Speed { class IUsbDevice { public: virtual ~IUsbDevice() = default; - virtual bool open() = 0; - virtual void close() = 0; + + virtual bool open() = 0; + virtual void close() = 0; // libusb wrappers virtual bool detachKernelDriver(int interfaceNo) = 0; diff --git a/src/libusbwrap/interface/IUsbDeviceFactory.hpp b/src/libusbwrap/interface/IUsbDeviceFactory.hpp index 725edad..a4d6ea0 100644 --- a/src/libusbwrap/interface/IUsbDeviceFactory.hpp +++ b/src/libusbwrap/interface/IUsbDeviceFactory.hpp @@ -1,6 +1,6 @@ /* ptrnt - print labels on linux - Copyright (C) 2023 Moritz Martinius + 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 diff --git a/src/main.cpp b/src/main.cpp index 19a160a..0367062 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,6 @@ /* ptrnt - print labels on linux - Copyright (C) 2022-2023 Moritz Martinius + Copyright (C) 2022-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 @@ -22,7 +22,10 @@ int main(int argc, char** argv) { ptprnt::PtouchPrint ptouchprnt(PROJ_VERSION); int ret = ptouchprnt.init(argc, argv); if (ret != 0) { - return ret; + // Non-zero from init means don't continue + // Positive values = clean exit (help/version) + // Negative values = error + return ret > 0 ? 0 : ret; } return ptouchprnt.run(); } diff --git a/src/meson.build b/src/meson.build index 70420c1..596422f 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,30 +1,34 @@ -ptprnt_hpps = files ( - 'libusbwrap/interface/IUsbDeviceFactory.hpp', - 'libusbwrap/interface/IUsbDevice.hpp', - 'libusbwrap/UsbDeviceFactory.hpp', - 'libusbwrap/LibUsbTypes.hpp', - 'libusbwrap/UsbDevice.hpp', - 'interface/IPrinterDriver.hpp', - 'interface/IPrinterTypes.hpp', - 'printers/P700Printer.hpp', - 'printers/FakePrinter.hpp', - 'PtouchPrint.hpp', - 'PrinterDriverFactory.hpp', +ptprnt_hpps = files( + 'cli/CliParser.hpp', + 'core/PrinterDriverFactory.hpp', + 'core/PrinterService.hpp', 'graphics/Bitmap.hpp', 'graphics/Label.hpp', 'graphics/LabelBuilder.hpp', - 'graphics/Monochrome.hpp' + 'graphics/Monochrome.hpp', + 'libusbwrap/LibUsbTypes.hpp', + 'libusbwrap/UsbDevice.hpp', + 'libusbwrap/UsbDeviceFactory.hpp', + 'libusbwrap/interface/IUsbDevice.hpp', + 'libusbwrap/interface/IUsbDeviceFactory.hpp', + 'printers/FakePrinter.hpp', + 'printers/P700Printer.hpp', + 'printers/interface/IPrinterDriver.hpp', + 'printers/interface/IPrinterTypes.hpp', + 'PtouchPrint.hpp', ) -ptprnt_srcs = files ( - 'PtouchPrint.cpp', - 'PrinterDriverFactory.cpp', - 'printers/P700Printer.cpp', - 'printers/FakePrinter.cpp', +ptprnt_srcs = files( + 'cli/CliParser.cpp', + 'core/PrinterDriverFactory.cpp', + 'core/PrinterService.cpp', + 'graphics/Bitmap.cpp', 'graphics/Label.cpp', 'graphics/LabelBuilder.cpp', - 'graphics/Bitmap.cpp', 'graphics/Monochrome.cpp', - 'libusbwrap/UsbDeviceFactory.cpp', 'libusbwrap/UsbDevice.cpp', + 'libusbwrap/UsbDeviceFactory.cpp', + 'printers/FakePrinter.cpp', + 'printers/P700Printer.cpp', + 'PtouchPrint.cpp', ) \ No newline at end of file diff --git a/src/printers/FakePrinter.cpp b/src/printers/FakePrinter.cpp index caf3e67..6a5e329 100644 --- a/src/printers/FakePrinter.cpp +++ b/src/printers/FakePrinter.cpp @@ -19,27 +19,25 @@ #include "FakePrinter.hpp" -#include #include +#include -#include -#include -#include #include +#include #include #include +#include +#include -#include "../graphics/Monochrome.hpp" +#include "graphics/Monochrome.hpp" namespace ptprnt::printer { -const PrinterInfo FakePrinter::mInfo = { - .driverName = "FakePrinter", - .name = "Virtual Test Printer", - .version = "v1.0", - .usbId{0x0000, 0x0000}, // No USB ID - virtual printer created explicitly - .pixelLines = 128 -}; +const PrinterInfo FakePrinter::mInfo = {.driverName = "FakePrinter", + .name = "Virtual Test Printer", + .version = "v1.0", + .usbId{0x0000, 0x0000}, // No USB ID - virtual printer created explicitly + .pixelLines = 128}; const std::string_view FakePrinter::getDriverName() { return mInfo.driverName; @@ -80,8 +78,8 @@ bool FakePrinter::detachUsbDevice() { bool FakePrinter::printBitmap(const graphics::Bitmap& bitmap) { // Convert bitmap to MonochromeData and delegate - auto pixels = bitmap.getPixelsCpy(); - auto mono = graphics::Monochrome(pixels, bitmap.getWidth(), bitmap.getHeight()); + auto pixels = bitmap.getPixelsCpy(); + auto mono = graphics::Monochrome(pixels, bitmap.getWidth(), bitmap.getHeight()); auto monoData = mono.get(); return printMonochromeData(monoData); @@ -92,10 +90,10 @@ bool FakePrinter::printMonochromeData(const graphics::MonochromeData& data) { // Simulate the printing process by reconstructing the bitmap auto printed = simulatePrinting(data); - mLastPrint = std::make_unique>(std::move(printed)); + mLastPrint = std::make_unique>(std::move(printed)); - spdlog::info("FakePrinter: Successfully 'printed' label ({}x{} pixels)", - mLastPrint->getWidth(), mLastPrint->getHeight()); + spdlog::info("FakePrinter: Successfully 'printed' label ({}x{} pixels)", mLastPrint->getWidth(), + mLastPrint->getHeight()); // Save to timestamped PNG file std::string filename = generateTimestampedFilename(); @@ -120,7 +118,8 @@ bool FakePrinter::printLabel(const std::unique_ptr label) { // Transform to portrait orientation for printing monoData.transformTo(graphics::Orientation::PORTRAIT); - spdlog::debug("FakePrinter: Label surface is {}x{}, transformed to portrait", label->getWidth(), label->getHeight()); + spdlog::debug("FakePrinter: Label surface is {}x{}, transformed to portrait", label->getWidth(), + label->getHeight()); return printMonochromeData(monoData); } @@ -160,7 +159,7 @@ graphics::Bitmap FakePrinter::simulatePrinting(const graphics: // Now "print" this column by unpacking the bytes back to pixels for (size_t byteIdx = 0; byteIdx < columnBytes.size(); byteIdx++) { - uint8_t byte = columnBytes[byteIdx]; + uint8_t byte = columnBytes[byteIdx]; uint32_t baseRow = byteIdx * 8; for (int bit = 0; bit < 8 && (baseRow + bit) < data.height; bit++) { @@ -168,7 +167,7 @@ graphics::Bitmap FakePrinter::simulatePrinting(const graphics: uint32_t row = baseRow + bit; // Write to output bitmap - size_t pixelIdx = row * data.width + col; + size_t pixelIdx = row * data.width + col; pixels[pixelIdx] = pixelOn ? 255 : 0; // 255 = black, 0 = white } } @@ -177,8 +176,8 @@ graphics::Bitmap FakePrinter::simulatePrinting(const graphics: // Set the pixels in the result bitmap result.setPixels(pixels); - spdlog::debug("FakePrinter: Simulation complete, reconstructed {}x{} bitmap", - result.getWidth(), result.getHeight()); + spdlog::debug("FakePrinter: Simulation complete, reconstructed {}x{} bitmap", result.getWidth(), + result.getHeight()); return result; } @@ -201,8 +200,8 @@ bool FakePrinter::saveLastPrintToPng(const std::string& filename) const { bool FakePrinter::saveBitmapToPng(const graphics::Bitmap& bitmap, const std::string& filename) const { // Create Cairo surface from bitmap data - auto pixels = bitmap.getPixelsCpy(); - uint16_t width = bitmap.getWidth(); + auto pixels = bitmap.getPixelsCpy(); + uint16_t width = bitmap.getWidth(); uint16_t height = bitmap.getHeight(); // Cairo expects ARGB32 format, but we have ALPHA8 @@ -217,14 +216,9 @@ bool FakePrinter::saveBitmapToPng(const graphics::Bitmap& bitm } // Create Cairo surface - int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); - cairo_surface_t* surface = cairo_image_surface_create_for_data( - reinterpret_cast(argbPixels.data()), - CAIRO_FORMAT_ARGB32, - width, - height, - stride - ); + int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); + cairo_surface_t* surface = cairo_image_surface_create_for_data(reinterpret_cast(argbPixels.data()), + CAIRO_FORMAT_ARGB32, width, height, stride); if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { spdlog::error("FakePrinter: Failed to create Cairo surface: {}", @@ -248,14 +242,12 @@ bool FakePrinter::saveBitmapToPng(const graphics::Bitmap& bitm std::string FakePrinter::generateTimestampedFilename() const { // Get current time - auto now = std::chrono::system_clock::now(); + auto now = std::chrono::system_clock::now(); auto time = std::chrono::system_clock::to_time_t(now); // Format: fakelabel_YYYYMMDD_HHMMSS.png std::stringstream ss; - ss << "fakelabel_" - << std::put_time(std::localtime(&time), "%Y%m%d_%H%M%S") - << ".png"; + ss << "fakelabel_" << std::put_time(std::localtime(&time), "%Y%m%d_%H%M%S") << ".png"; return ss.str(); } diff --git a/src/printers/FakePrinter.hpp b/src/printers/FakePrinter.hpp index 12cd1ff..d8d61e4 100644 --- a/src/printers/FakePrinter.hpp +++ b/src/printers/FakePrinter.hpp @@ -19,15 +19,15 @@ #pragma once +#include #include #include -#include -#include "../interface/IPrinterDriver.hpp" -#include "../interface/IPrinterTypes.hpp" -#include "../libusbwrap/LibUsbTypes.hpp" -#include "../libusbwrap/interface/IUsbDevice.hpp" -#include "../graphics/Bitmap.hpp" +#include "graphics/Bitmap.hpp" +#include "interface/IPrinterDriver.hpp" +#include "interface/IPrinterTypes.hpp" +#include "libusbwrap/LibUsbTypes.hpp" +#include "libusbwrap/interface/IUsbDevice.hpp" namespace ptprnt::printer { @@ -40,7 +40,7 @@ namespace ptprnt::printer { */ class FakePrinter : public ::ptprnt::IPrinterDriver { public: - FakePrinter() = default; + FakePrinter() = default; ~FakePrinter() override = default; FakePrinter(const FakePrinter&) = delete; diff --git a/src/printers/P700Printer.cpp b/src/printers/P700Printer.cpp index b3f8e22..a8ec3ed 100644 --- a/src/printers/P700Printer.cpp +++ b/src/printers/P700Printer.cpp @@ -28,9 +28,9 @@ #include #include -#include "../graphics/Bitmap.hpp" -#include "../graphics/Monochrome.hpp" -#include "../libusbwrap/LibUsbTypes.hpp" +#include "graphics/Bitmap.hpp" +#include "graphics/Monochrome.hpp" +#include "libusbwrap/LibUsbTypes.hpp" #include "spdlog/fmt/bin_to_hex.h" namespace ptprnt::printer { diff --git a/src/printers/P700Printer.hpp b/src/printers/P700Printer.hpp index e14f500..af3cecd 100644 --- a/src/printers/P700Printer.hpp +++ b/src/printers/P700Printer.hpp @@ -17,6 +17,8 @@ */ +#pragma once + #include #include @@ -28,15 +30,13 @@ #include "libusbwrap/LibUsbTypes.hpp" #include "libusbwrap/interface/IUsbDevice.hpp" -#pragma once - namespace ptprnt::printer { namespace p700::commands { -const cmd_T INITIALIZE{0x1b, 0x40}; // ESC @ - Initialize -const cmd_T GET_STATUS{0x1b, 0x69, 0x53}; // ESC i S - Status query -const cmd_T PRINT_MODE{0x4d, 0x02}; // M 0x02 - Print mode -const cmd_T AUTO_STATUS{0x1b, 0x69, 0x61, 0x01}; // ESC i a - Auto status -const cmd_T MODE_SETTING{0x1b, 0x69, 0x4d, 0x40}; // ESC i M @ - Advanced mode +const cmd_T INITIALIZE{0x1b, 0x40}; // ESC @ - Initialize +const cmd_T GET_STATUS{0x1b, 0x69, 0x53}; // ESC i S - Status query +const cmd_T PRINT_MODE{0x4d, 0x02}; // M 0x02 - Print mode +const cmd_T AUTO_STATUS{0x1b, 0x69, 0x61, 0x01}; // ESC i a - Auto status +const cmd_T MODE_SETTING{0x1b, 0x69, 0x4d, 0x40}; // ESC i M @ - Advanced mode const cmd_T RASTER_START{0x1b, 0x69, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; const cmd_T INFO{0x1b, 0x69, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; const cmd_T PACKBITSON{0x02}; diff --git a/src/interface/IPrinterDriver.hpp b/src/printers/interface/IPrinterDriver.hpp similarity index 96% rename from src/interface/IPrinterDriver.hpp rename to src/printers/interface/IPrinterDriver.hpp index 48106fb..daae31b 100644 --- a/src/interface/IPrinterDriver.hpp +++ b/src/printers/interface/IPrinterDriver.hpp @@ -1,6 +1,6 @@ /* ptrnt - print labels on linux - Copyright (C) 2023-2025 Moritz Martinius + Copyright (C) 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 @@ -22,10 +22,10 @@ #include #include +#include "IPrinterTypes.hpp" #include "graphics/Bitmap.hpp" #include "graphics/Monochrome.hpp" #include "graphics/interface/ILabel.hpp" -#include "interface/IPrinterTypes.hpp" #include "libusbwrap/interface/IUsbDevice.hpp" namespace ptprnt { diff --git a/src/interface/IPrinterTypes.hpp b/src/printers/interface/IPrinterTypes.hpp similarity index 94% rename from src/interface/IPrinterTypes.hpp rename to src/printers/interface/IPrinterTypes.hpp index 908a482..061bcf9 100644 --- a/src/interface/IPrinterTypes.hpp +++ b/src/printers/interface/IPrinterTypes.hpp @@ -1,6 +1,6 @@ /* ptrnt - print labels on linux - Copyright (C) 2023-2024 Moritz Martinius + Copyright (C) 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 @@ -20,7 +20,6 @@ #pragma once #include -#include #include #include diff --git a/src/ptprnt.log b/src/ptprnt.log deleted file mode 100644 index e69de29..0000000 diff --git a/tests/meson.build b/tests/meson.build index 4d59e27..f2c6146 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -35,6 +35,4 @@ foreach test : tests ], ), ) -endforeach - - +endforeach \ No newline at end of file