/* ptrnt - print labels on linux Copyright (C) 2023 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 . */ #define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE #define SPDLOG_DEBUG_ON #define SPDLOG_TRACE_ON #include "PtouchPrint.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include "CLI/Option.hpp" #include "P700Printer.hpp" #include "graphics/Bitmap.hpp" #include "graphics/Image.hpp" #include "libusbwrap/UsbDeviceFactory.hpp" namespace ptprnt { PtouchPrint::PtouchPrint(const char* versionString) : mVersionString{versionString} {} int PtouchPrint::init(int argc, char** argv) { setupCliParser(); try { mApp.parse(argc, argv); } catch (const CLI::ParseError& e) { mApp.exit(e); return -1; } if (mVerboseFlag) { setupLogger(spdlog::level::debug); } else { setupLogger(spdlog::level::err); } if (!mUsbDeviceFactory.init()) { spdlog::error("Could not initialize libusb"); return -1; } mCompatiblePrinters = {std::make_shared()}; return 0; } int PtouchPrint::run() { spdlog::debug("ptprnt version {}", mVersionString); SPDLOG_TRACE("testing trace"); auto numFoundPrinters = getCompatiblePrinters(); if (numFoundPrinters == 0) { spdlog::error( "No compatible printers found, please make sure that they are turned on and connected"); return -1; } else if (numFoundPrinters > 1) { spdlog::warn("Found more than one compatible printer. Currently not supported."); return -1; } auto printer = mCompatiblePrinters[0]; auto devices = mUsbDeviceFactory.findDevices(printer->getVid(), printer->getPid()); if (devices.size() != 1) { spdlog::warn( "Found more than one device of the same printer on bus. Currently not supported"); return -1; } printer->attachUsbDevice(devices[0]); auto status = printer->getPrinterStatus(); spdlog::info("Detected tape width is {}mm", status.tapeWidthMm); auto bm = ptprnt::graphics::Bitmap(512, 128); //printer->printBitmap(bm); //printer->printText("wurst", 1); for (auto& cmd : mCommands) { spdlog::debug("Command: {}", cmd.second); if (cmd.first == CliCmdType::Text) { auto label{graphics::Image()}; label.createLabel(cmd.second); } } return 0; } unsigned int PtouchPrint::getCompatiblePrinters() { auto usbDevs = mUsbDeviceFactory.findAllDevices(); for (auto usbDev : usbDevs) { auto foundPrinterIt = std::find_if(mCompatiblePrinters.begin(), mCompatiblePrinters.end(), [usbDev](const std::shared_ptr& printer) { return printer->getPid() == usbDev->getPid() && printer->getVid() == usbDev->getVid(); }); if (foundPrinterIt == mCompatiblePrinters.end()) { continue; } auto foundPrinter = *foundPrinterIt; spdlog::info("Found Printer {}", foundPrinter->getName()); mDetectedPrinters.push_back(foundPrinter); } // we can delete all instantiated printers that are not compatible mCompatiblePrinters.clear(); return mDetectedPrinters.size(); } void PtouchPrint::setupLogger(spdlog::level::level_enum lvl) { auto consoleSink = std::make_shared(); consoleSink->set_level(lvl); 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); } 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("-V,--version", printVersion, "Prints the ptprnt's version"); // 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::TakeAll) ->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::TakeAll) ->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::TakeAll) ->trigger_on_parse() ->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::TakeAll) ->trigger_on_parse() ->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