This commit is contained in:
parent
8338b7fdc8
commit
2f2ec79575
4
Makefile
4
Makefile
@ -1,7 +1,7 @@
|
|||||||
# Compiler and flags
|
# Compiler and flags
|
||||||
CPPC = g++
|
CPPC = g++
|
||||||
CPPC_FLAGS = -std=c++23 -s -O3 -Wall -Wextra -Wno-write-strings -lncurses -lmenu -lform
|
CPPC_FLAGS = -std=c++23 -s -O3 -Wall -Wextra -Wno-write-strings -lncurses -lmenu -lform -lcups
|
||||||
DEBUG_FLAGS = -ggdb -std=c++23 -Wall -Wextra -Wno-write-strings -lncurses -lmenu -lform
|
DEBUG_FLAGS = -ggdb -std=c++23 -Wall -Wextra -Wno-write-strings -lncurses -lmenu -lform -lcups
|
||||||
|
|
||||||
|
|
||||||
SRC_PATH := src
|
SRC_PATH := src
|
||||||
|
189
src/cups.cpp
Normal file
189
src/cups.cpp
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
#include <cups/cups.h>
|
||||||
|
#include <menu.h>
|
||||||
|
#include <ncurses.h>
|
||||||
|
#include <cstring>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a menu of available printers and prints content to the selected one
|
||||||
|
* @param content The text content to print
|
||||||
|
* @return true if printing was successful, false otherwise
|
||||||
|
*/
|
||||||
|
bool printDocument(const std::string& content) {
|
||||||
|
// Initialize variables
|
||||||
|
bool success = false;
|
||||||
|
cups_dest_t* dests = nullptr;
|
||||||
|
int num_dests = 0;
|
||||||
|
ITEM** menu_items = nullptr;
|
||||||
|
MENU* menu = nullptr;
|
||||||
|
WINDOW* menu_win = nullptr;
|
||||||
|
std::vector<char*> item_names;
|
||||||
|
std::vector<char*> item_descriptions;
|
||||||
|
|
||||||
|
// Write content to a temporary file
|
||||||
|
std::string tempFileName = "/tmp/print_temp_ParaDocs.txt";
|
||||||
|
std::ofstream tempFile(tempFileName);
|
||||||
|
if (!tempFile) {
|
||||||
|
return false; // Failed to create temp file
|
||||||
|
}
|
||||||
|
tempFile << content;
|
||||||
|
tempFile.close();
|
||||||
|
|
||||||
|
// Get printer destinations from CUPS
|
||||||
|
num_dests = cupsGetDests(&dests);
|
||||||
|
if (num_dests <= 0) {
|
||||||
|
remove(tempFileName.c_str());
|
||||||
|
return false; // No printers available
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize ncurses
|
||||||
|
initscr();
|
||||||
|
start_color();
|
||||||
|
cbreak();
|
||||||
|
noecho();
|
||||||
|
keypad(stdscr, TRUE);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Allocate memory for menu items
|
||||||
|
menu_items = new ITEM*[num_dests + 1];
|
||||||
|
|
||||||
|
// Prepare menu items for each printer
|
||||||
|
for (int i = 0; i < num_dests; i++) {
|
||||||
|
// Create display name
|
||||||
|
std::string display_name;
|
||||||
|
if (dests[i].instance) {
|
||||||
|
display_name = std::string(dests[i].name) + "/" + dests[i].instance;
|
||||||
|
} else {
|
||||||
|
display_name = dests[i].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate memory for name string
|
||||||
|
char* name_str = new char[display_name.length() + 1];
|
||||||
|
std::strcpy(name_str, display_name.c_str());
|
||||||
|
item_names.push_back(name_str);
|
||||||
|
|
||||||
|
// Get description if available
|
||||||
|
const char* desc =
|
||||||
|
cupsGetOption("printer-info", dests[i].num_options, dests[i].options);
|
||||||
|
std::string description = desc ? desc : "";
|
||||||
|
|
||||||
|
// Allocate memory for description string
|
||||||
|
char* desc_str = new char[description.length() + 1];
|
||||||
|
std::strcpy(desc_str, description.c_str());
|
||||||
|
item_descriptions.push_back(desc_str);
|
||||||
|
|
||||||
|
// Create menu item
|
||||||
|
menu_items[i] = new_item(name_str, desc_str);
|
||||||
|
if (!menu_items[i]) {
|
||||||
|
throw std::runtime_error("Failed to create menu item");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
menu_items[num_dests] = nullptr; // NULL-terminate the array
|
||||||
|
|
||||||
|
// Create the menu
|
||||||
|
menu = new_menu(menu_items);
|
||||||
|
if (!menu) {
|
||||||
|
throw std::runtime_error("Failed to create menu");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up menu window
|
||||||
|
int rows, cols;
|
||||||
|
getmaxyx(stdscr, rows, cols);
|
||||||
|
menu_win = newwin(rows - 4, cols - 4, 2, 2);
|
||||||
|
keypad(menu_win, TRUE);
|
||||||
|
|
||||||
|
// Set menu window and sub window
|
||||||
|
set_menu_win(menu, menu_win);
|
||||||
|
set_menu_sub(menu, derwin(menu_win, rows - 6, cols - 6, 1, 1));
|
||||||
|
set_menu_format(menu, rows - 8, 1);
|
||||||
|
set_menu_mark(menu, " * ");
|
||||||
|
|
||||||
|
// Post the menu with instructions
|
||||||
|
mvprintw(0, 0, "Select a printer and press Enter:");
|
||||||
|
mvprintw(rows - 2, 0, "Press q to cancel");
|
||||||
|
refresh();
|
||||||
|
post_menu(menu);
|
||||||
|
wrefresh(menu_win);
|
||||||
|
|
||||||
|
// Menu interaction loop
|
||||||
|
int c;
|
||||||
|
while ((c = wgetch(menu_win)) != 'q') {
|
||||||
|
switch (c) {
|
||||||
|
case KEY_DOWN:
|
||||||
|
menu_driver(menu, REQ_DOWN_ITEM);
|
||||||
|
break;
|
||||||
|
case KEY_UP:
|
||||||
|
menu_driver(menu, REQ_UP_ITEM);
|
||||||
|
break;
|
||||||
|
case 10: // Enter key
|
||||||
|
{
|
||||||
|
ITEM* cur = current_item(menu);
|
||||||
|
int index = item_index(cur);
|
||||||
|
|
||||||
|
// Print the document to the selected printer
|
||||||
|
int job_id =
|
||||||
|
cupsPrintFile(dests[index].name, tempFileName.c_str(),
|
||||||
|
"Document from application",
|
||||||
|
dests[index].num_options, dests[index].options);
|
||||||
|
|
||||||
|
if (job_id > 0) {
|
||||||
|
success = true;
|
||||||
|
mvprintw(rows - 1, 0, "Printing job %d submitted successfully",
|
||||||
|
job_id);
|
||||||
|
} else {
|
||||||
|
mvprintw(rows - 1, 0, "Error: %s", cupsLastErrorString());
|
||||||
|
}
|
||||||
|
refresh();
|
||||||
|
napms(2000); // Display message for 2 seconds
|
||||||
|
c = 'q'; // Exit the loop
|
||||||
|
goto exit_menu;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wrefresh(menu_win);
|
||||||
|
}
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
mvprintw(0, 0, "Error: %s", e.what());
|
||||||
|
refresh();
|
||||||
|
napms(2000);
|
||||||
|
}
|
||||||
|
exit_menu:
|
||||||
|
|
||||||
|
// Clean up resources
|
||||||
|
if (menu) {
|
||||||
|
unpost_menu(menu);
|
||||||
|
free_menu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (menu_items) {
|
||||||
|
for (int i = 0; i < num_dests && menu_items[i]; i++) {
|
||||||
|
free_item(menu_items[i]);
|
||||||
|
}
|
||||||
|
delete[] menu_items;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free allocated strings
|
||||||
|
for (char* str : item_names) {
|
||||||
|
delete[] str;
|
||||||
|
}
|
||||||
|
for (char* str : item_descriptions) {
|
||||||
|
delete[] str;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (menu_win) {
|
||||||
|
delwin(menu_win);
|
||||||
|
}
|
||||||
|
|
||||||
|
// End ncurses
|
||||||
|
endwin();
|
||||||
|
|
||||||
|
// Remove temp file
|
||||||
|
remove(tempFileName.c_str());
|
||||||
|
|
||||||
|
// Free CUPS destinations
|
||||||
|
cupsFreeDests(num_dests, dests);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
9
src/cups.h
Normal file
9
src/cups.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#include <string>
|
||||||
|
|
||||||
|
#ifndef PARADOCS_CUPS_H_
|
||||||
|
#define PARADOCS_CUPS_H_
|
||||||
|
|
||||||
|
|
||||||
|
bool printDocument(const std::string& content);
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user