/* Copyright (C) 2006 Chris Vine This program is distributed under the General Public Licence, version 2. For particulars of this and relevant disclaimers see the file COPYING distributed with the source files. */ #include // we only compile this file if GTK+ version is 2.10 or higher #if GTK_CHECK_VERSION(2,10,0) #include #include #include "print_manager.h" #ifdef ENABLE_NLS #include #endif namespace { // callback for internal use only void PrintDialogCB::print_selected(GtkDialog*, int id, void* data) { PrintDialog* instance_p = static_cast(data); if (id == GTK_RESPONSE_OK) instance_p->accepted(); else instance_p->rejected(); instance_p->close(); } } // anonymous namespace PrintDialog::PrintDialog(GtkWindow* parent_p): WinBase(gettext("efax-gtk: Print fax"), prog_config.window_icon_h, true, parent_p, GTK_WINDOW(gtk_print_unix_dialog_new(0, 0))) { gtk_window_set_type_hint(get_win(), GDK_WINDOW_TYPE_HINT_DIALOG); g_signal_connect(G_OBJECT(get_win()), "response", G_CALLBACK(PrintDialogCB::print_selected), this); gtk_window_set_position(get_win(), GTK_WIN_POS_CENTER_ON_PARENT); gtk_window_set_resizable(get_win(), false); GtkPrintCapabilities capabilities = GtkPrintCapabilities(0); capabilities = GtkPrintCapabilities(GTK_PRINT_CAPABILITY_GENERATE_PS); gtk_print_unix_dialog_set_manual_capabilities(GTK_PRINT_UNIX_DIALOG(get_win()), capabilities); gtk_widget_show_all(GTK_WIDGET(get_win())); } void PrintDialog::on_delete_event(void) { rejected(); close(); } GtkPrinter* PrintDialog::get_printer(void) const { return gtk_print_unix_dialog_get_selected_printer(GTK_PRINT_UNIX_DIALOG(get_win())); } GobjHandle PrintDialog::get_settings(void) const { return GobjHandle(gtk_print_unix_dialog_get_settings(GTK_PRINT_UNIX_DIALOG(get_win()))); } GtkPageSetup* PrintDialog::get_page_setup(void) const { return gtk_print_unix_dialog_get_page_setup(GTK_PRINT_UNIX_DIALOG(get_win())); } namespace { // callback for internal use only void PrintManagerCB::print_job_complete(GtkPrintJob*, void* data, GError* error) { if (error) { write_error(error->message); write_error("\n"); } static_cast(data)->unref(); } } // anonymous namespace PrintManager::~PrintManager(void) { Thread::Mutex::Lock lock(filename_mutex); if (manage && !filename.empty()) unlink(filename.c_str()); } IntrusivePtr PrintManager::create_manager(GtkWindow* parent, bool manage_file) { PrintManager* instance_p = new PrintManager; instance_p->print_notifier.connect(sigc::mem_fun(*instance_p, &PrintManager::show_dialog)); instance_p->parent_p = parent; instance_p->manage = manage_file; return IntrusivePtr(instance_p); } void PrintManager::set_filename(const char* filename_) { Thread::Mutex::Lock lock(filename_mutex); filename = filename_; } void PrintManager::print(void) { // take ownership of ourselves ref(); print_notifier(); } void PrintManager::show_dialog(void) { // hand back ownership to local scope so that if there is a problem // or an exception is thrown this method cleans itself up (we will // ref() again at the end of this method if all has gone well) IntrusivePtr temp(this); filename_mutex.lock(); if (filename.empty()) { filename_mutex.unlock(); write_error("No file has been specified for printing\n"); return; } filename_mutex.unlock(); // this method is called via the Notifier object, so it must be executing // in the main GUI thread - it is therefore safe to call any GTK+ functions // in this method and in PrintManager::print_file() dialog_p = new PrintDialog(parent_p); dialog_p->accepted.connect(sigc::mem_fun(*this, &PrintManager::print_file)); dialog_p->rejected.connect(sigc::mem_fun(*this, &PrintManager::unref)); // there is no memory leak -- the memory will be deleted when the PrintDialog object closes // regain ownership of ourselves ref(); } void PrintManager::print_file(void) { // hand back ownership to local scope so that if there is a problem // or an exception is thrown this method cleans itself up (we will // ref() again at the end of this method if all has gone well) IntrusivePtr temp(this); GtkPrinter* printer_p = dialog_p->get_printer(); if (!printer_p) { write_error(gettext("No valid printer selected\n")); } else { GobjHandle print_settings_h(dialog_p->get_settings()); GtkPageSetup* page_setup_p = dialog_p->get_page_setup(); GobjHandle print_job_h(gtk_print_job_new("efax-gtk print job", printer_p, print_settings_h, page_setup_p)); GError* error_p = 0; bool result; { // scope block for mutex lock Thread::Mutex::Lock lock(filename_mutex); result = gtk_print_job_set_source_file(print_job_h, filename.c_str(), &error_p); } if (!result) { if (error_p) { write_error(error_p->message); write_error("\n"); } } else { // regain ownership and print the job (the print // system will do the final unreference in the // PrintManagerCB::print_job_complete() function) gtk_print_job_send(print_job_h, PrintManagerCB::print_job_complete, this, 0); ref(); } } } #endif // GTK_CHECK_VERSION