Bug 112536

Summary: kprinter fails to detect options for cups printer classes
Product: [Applications] kdeprint Reporter: Patrick Gosling <jpmg>
Component: generalAssignee: KDEPrint Devel Mailinglist <kde-print-devel>
Status: CLOSED FIXED    
Severity: wishlist CC: jlayt
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: openSUSE   
OS: Linux   
Latest Commit: Version Fixed In:
Attachments: fix for failure to load printer driver when "printer" is actually a class

Description Patrick Gosling 2005-09-13 15:28:32 UTC
Version:            (using KDE KDE 3.3.0)
Installed from:    SuSE RPMs
OS:                Linux

If a CUPS printer class is selected, rather than a printer, kprinter fails to determine an appropriate set of options.  This is sort of understandable - a printer class doesn't have a PPD file available for it;  indeed CUPS itself appears to be dodging thinking about this problem.

It's not completely clear to me what _should_ be done if two different printers with different PPDs are members of the same class;  however, it should be noted that the cups command "lpoptions -p classname -l" does something reasonable (although inspection reveals that it just queries the first available printer listed for the class).

In an ideal world, I suppose that both lpoptions and kprinter should work with the intersection of the PPDs for all available printers in the class - ie any options that are applicable to all the printers in the class should be made available to the user.

Indeed, I wonder if the correct solution isn't for CUPS to produce a virtual PPD for each class (since it would only have to do the work of calculating the intersection of PPDs each time the set of available printers in the class changed), accessible via "GET /classes/classname.ppd" by analogy with "GET /printers/printername.ppd" .
Comment 1 Patrick Gosling 2005-09-15 13:52:43 UTC
CUPS maintainers definitely don't like the idea of producing virtual ppds for classes;  their model is that classes are usually groups of nearly identical printers, (and, by implication, that the behaviour of "lpoptions -p classname -l" in just querying the first available printer, is reasonable).
Comment 2 Cristian Tibirna 2005-09-20 06:10:26 UTC
Kprinter is a frontend to CUPS (among others). If CUPS chooses to deal with classes as if they were groups of identical printers, kprinter will conform.

I also mark this report as a wishlist for the benefit of future onlookers.

Thank you for the contributions.
Comment 3 Michael Goffioul 2005-09-20 09:25:32 UTC
Cristian, there's still something to check: as the reporter said, the lpoptions utility returns a set of driver option, which are actually taken from the PPD file of the first printer of the class. However, I'm not sure that kdeprint even asks CUPS for a PPD file in the case of a class, I think it's only in the case of a real printer...

Indeed, in kdelibs/kdeprint/cups/kmcupsmanager.cpp: loadPrinteDriver(), you see that the driver is not requested for a class. IMO, this is something that can be done as in plain CUPS.

Michael.
Comment 4 Patrick Gosling 2005-11-11 17:09:29 UTC
Created attachment 13391 [details]
fix for failure to load printer driver when "printer" is actually a class

This attachment appears to fix the described problem.  It's a patch against
suse's kdelibs3-3.4.0-20.7 rpm and has been tested working on a suse-9.3
installation.
Comment 5 Patrick Gosling 2005-11-11 17:44:23 UTC
Re-opening just in case submitted patch is sufficient ...
Comment 6 Cristian Tibirna 2005-11-14 04:21:28 UTC
SVN commit 480261 by tibirna:

patch from Patrick Gosling (jpmg eng cam ac uk) for selecting the
PPD of first printer in a class.
BUG:112536


 M  +18 -1     kmcupsmanager.cpp  


--- branches/KDE/3.5/kdelibs/kdeprint/cups/kmcupsmanager.cpp #480260:480261
@@ -524,9 +524,26 @@
 
 DrMain* KMCupsManager::loadPrinterDriver(KMPrinter *p, bool)
 {
-	if (!p || p->isClass(true))
+	if (!p) 
 		return NULL;
 
+	if (p->isClass(true)) 
+	{
+		KMPrinter *first_class_member = NULL;
+		/* find the first printer in the class */
+ 		first_class_member = findPrinter(p->members().first());
+	  
+		if (first_class_member == NULL) 
+		{
+			/* we didn't find a printer in the class */
+			return NULL;
+		}
+		else
+		{
+			p = first_class_member;
+		}
+	}
+
 	QString	fname = downloadDriver(p);
 	DrMain	*driver(0);
 	if (!fname.isEmpty())
Comment 7 John Layt 2008-12-31 19:00:50 UTC
Closing old Resolved status bug.