[XCPD Test Modules] fixed QT-related deallocation calls
[google-summer-of-code-2011:xcpd.git] / src / components / selector_test.cpp
1 /*
2  * Copyright (C) 2011-2012 Joseph Simon <jsimon383@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General
15  * Public License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include "selector_test.h"
21
22 #include <QFileDialog>
23
24 #define SAMPLE_PPD_NAME "/test.ppd"
25
26
27
28 static int
29 populatePPDOptionCombo(ppd_file_t*, const char*, QComboBox*);
30
31 static void 
32 writeICCSelectionOptions(ppd_file_t*);
33
34 SelectorDialog::SelectorDialog(QWidget *parent) 
35    : QDialog(parent)
36
37 {
38   
39     this->setAttribute(Qt::WA_DeleteOnClose, true);
40     
41     setupUi(this); 
42         
43     cm_obj = xcpdCM_initialize();
44         
45     currentPreset = "";
46     userProfile = "";
47             
48     setResourceDir();
49     
50     populatePrinterList();
51     
52     currentPPD = loadTestPPD();
53     
54     // Fill initial combobox values.
55     //populatePPDOptionCombo(currentPPD, "ICCSelection", iccSelectCombo);
56     //ppdMarkOption(currentPPD, "ICCSelection", "AutoSet");
57     
58     selection_mode = XCPDCM_AUTOSELECT_MODE;
59     
60     refreshCurrentProfile(currentPPD);
61     refreshOptions(currentPPD);
62     
63     updateButton->hide();
64     
65     connect( closeBtn,
66              SIGNAL( clicked() ),
67              this,
68              SLOT( closeDialog() ));    
69     connect( iccSelectCombo,
70              SIGNAL( currentIndexChanged(const QString &) ),
71              this,
72              SLOT( iccOptionChanged(const QString &) ));  
73     connect( printerComboBox,
74              SIGNAL(currentIndexChanged(int)),
75              this,
76              SLOT(printerIndexChanged(int)));
77     connect( updateButton,
78              SIGNAL(clicked()),
79              this,
80              SLOT(updateSettings()));
81 }
82
83
84 //   **** SLOT-related functions ****
85
86
87 void  SelectorDialog::closeDialog()
88 {  
89     this->close(); 
90 }
91
92
93 void  SelectorDialog::printerIndexChanged(int index)
94 {
95      printer_name_index = index;
96      currentPPD = loadTestPPD();
97      
98      refreshOptions(currentPPD);
99 }
100
101
102 void  SelectorDialog::iccOptionChanged(const QString & text)
103 {
104   
105     if (text == "AutoSet"){
106       
107       // ppdMarkOption(ppd_copy, "ICCSelection", "AutoSet");
108       // markOptions(ppd_copy);
109       selection_mode = XCPDCM_AUTOSELECT_MODE;
110     }
111     else if (text == "ApplicationSet"){      
112       /* NOTE Nothing in place yet for getting a system profile,
113             so we just mark this option.          */
114       //ppdMarkOption(ppd_copy, "ICCSelection", "ApplicationSet");
115       selection_mode = XCPDCM_SYSTEMSELECT_MODE;
116     } 
117     else if (text == "ManualSet"){      
118       //ppdMarkOption(ppd_copy, "ICCSelection", "ManualSet");
119       selection_mode = XCPDCM_USERSELECT_MODE;
120     }
121     else
122       return;
123  /*         
124     // We disconnect this SLOT first so that the combobox changes will 
125     // not result in error.
126     disconnect( iccSelectCombo,SIGNAL( currentIndexChanged(const QString &) ),
127              this, SLOT( iccOptionChanged(const QString &) ));   
128
129     refreshCurrentProfile(ppd_copy);
130     
131     connect( iccSelectCombo,SIGNAL( currentIndexChanged(const QString &) ),
132              this, SLOT( iccOptionChanged(const QString &) ));      
133      
134     ppdClose(ppd_copy);*/
135
136 }
137
138 void  SelectorDialog::updateSettings()
139 {   
140       
141     ppd_file_t* ppd_copy = loadTestPPD();
142     refreshOptions(ppd_copy);
143   
144     if(selection_mode == XCPDCM_AUTOSELECT_MODE){
145         markOptions(ppd_copy);
146         refreshCurrentProfile(ppd_copy);
147     } 
148     else if(selection_mode == XCPDCM_USERSELECT_MODE){
149       //ppd_attr_t* profile_attr = ppdFindAttr(currentPPD, "userICCProfile", 0);
150       //strcpy(profile_attr->value, profileName.toLocal8Bit());
151       
152        QString profileName = QFileDialog::getOpenFileName(this,
153         tr("Open ICC Profile"), xcpdResourcePath, tr("ICC Files (*.icc)"));
154
155         char* user_profile = strdup(profileName.toLocal8Bit());  
156         xcpdCM_setProfile(user_profile, cm_obj);
157     }
158     
159     refreshCurrentProfile(ppd_copy);
160     
161     updateButton->hide(); 
162   
163 }
164
165 //   **** SELECTOR FUNCTIONS ****
166
167
168 void  SelectorDialog::populatePrinterList()
169 {
170     dests_n = cupsGetDests( &dests );
171     
172     int i;
173     for( i = 0; i < dests_n; i++ ){
174       printerComboBox->insertItem(i, dests[i].name, 0);
175     }
176     
177     printer_name_index = 0;
178 }
179
180
181 ppd_file_t*  SelectorDialog::loadTestPPD()
182 {
183     
184     ppd_file_t* ppd = 0;    
185     printer_name_index = printerComboBox->currentIndex();
186     
187     const char* ppdfilename = cupsGetPPD(dests[printer_name_index].name);
188     
189     ppd = ppdOpenFile(ppdfilename);  
190     return ppd;
191 }
192
193
194 void SelectorDialog::refreshOptions(ppd_file_t* ppd)
195 {    
196     populatePPDOptionCombo(ppd, "MediaType", mediaTypeCombo);
197     populatePPDOptionCombo(ppd, "Resolution", resolutionCombo);
198     populatePPDOptionCombo(ppd, "ColorModel", colorModelCombo);     
199 }
200
201
202 void SelectorDialog::markOptions(ppd_file_t* ppd)
203 {
204   
205     ppdMarkOption(ppd, "MediaType", 
206                   (mediaTypeCombo->currentText()).toLocal8Bit());
207     ppdMarkOption(ppd, "Resolution", 
208                   (resolutionCombo->currentText()).toLocal8Bit());
209     ppdMarkOption(ppd, "ColorModel", 
210                   (colorModelCombo->currentText()).toLocal8Bit());
211 }
212
213 // Change the "Recommended Profile" label according to printer.
214 void  SelectorDialog::refreshCurrentProfile(ppd_file_t* ppd)
215 {
216
217     char* current_printer = dests[printer_name_index].name;
218
219     xcpdcm_sstatus_t result = xcpdCM_setProfileFromPPD2(cm_obj, 
220                                                         ppd, 
221                                                         selection_mode);
222     
223     if(result != XCPDCM_SELECTOR_INVALID_PPD){      
224       showCalibrationResult(result);
225       
226       if(selection_mode != XCPDCM_AUTOSELECT_MODE)
227         refreshOptions(ppd);
228
229       char* profile_filename = xcpdCM_getProfile(cm_obj);  
230
231       if (profile_filename)
232          adjustedProfileLbl->setText(profile_filename);
233       else 
234          adjustedProfileLbl->setText("(Cannot find profile information.)");    
235     }
236 }
237
238
239 SelectorDialog::~SelectorDialog()
240 {
241     if (currentPPD)
242       ppdClose(currentPPD);
243     
244     xcpdCM_close(cm_obj);
245 }
246
247
248 void  SelectorDialog::setResourceDir()
249 {
250   
251     QDir resourceDir = QDir::current();
252     resourceDir.setCurrent("../../src/resources/");
253     
254     xcpdResourcePath = resourceDir.currentPath();  
255 }
256
257
258 void SelectorDialog::showCalibrationResult(xcpdcm_sstatus_t result)
259 {
260     
261     QString resultText;
262     
263     switch(result){      
264       case XCPDCM_SELECTOR_USERPROFILE_SET:
265         resultText = "User Profile Selected";
266         break;
267       case XCPDCM_SELECTOR_SYSTEMPROFILE_SET:
268         resultText = "Application Profile Selected";
269         break;
270       case XCPDCM_SELECTOR_AUTOPROFILE_SET:
271         resultText = "Automatic Profile Selected";
272         break;
273       case XCPDCM_SELECTOR_CUPSFALLBACK_SET:
274         resultText = "CUPS Fallback Profile Selected";
275         break;
276       case XCPDCM_SELECTOR_OYDEFAULT_SET:
277         resultText = "Oyranos Fallback Profile Selected";
278         break;
279       case XCPDCM_SELECTOR_NOPROFILE:
280         resultText = "No Profile Selected";
281         break;
282       case XCPDCM_SELECTOR_INVALID_PPD:
283         resultText = "INVALID PROFILE";
284         break;
285     }
286     
287     selectorResultLbl->setText(resultText);
288
289 }
290
291
292 void SelectorDialog::saveOptions(ppd_file_t* ppd)
293 {
294
295     const char* ppd_path = testPPDPath.toLocal8Bit();
296     FILE* fp = fopen(ppd_path, "r+");    
297
298     fclose(fp);
299 }
300
301
302 const char* SelectorDialog::copyPPDFile(const char* old_ppd)
303 {
304
305     const char* temp_ppd = copyPPDPath.toLocal8Bit();
306     
307     FILE* fp_old = fopen(old_ppd, "r");
308     FILE* fp_new = fopen(temp_ppd, "w");
309
310     char k;
311     int pdf_eof = 0;
312
313     while(!pdf_eof && fp_old)
314     {
315         k = fgetc(fp_old);
316
317         if(!feof(fp_old))          
318           fputc(k, fp_new);
319         else
320           pdf_eof++;
321     }
322
323
324     fclose(fp_new);
325     fclose(fp_old);
326
327   
328     return temp_ppd;
329 }
330
331
332
333 int
334 populatePPDOptionCombo(ppd_file_t* ppd, const char* option_string, 
335                        QComboBox* combo)
336 {
337     
338     int found = 0, choices_n = 0, i;
339     
340     combo->clear();    
341     
342     ppd_option_t* option = ppdFindOption(ppd, option_string);
343     
344     
345     if(option){
346       choices_n = option->num_choices;
347       
348       for(i = 0; i < choices_n; i++) {
349         combo->addItem(option->choices[i].choice, 0);
350       }
351                  
352       found = 1;
353     } 
354     else {
355       ppd_attr_t* attr = ppdFindAttr(ppd, option_string, 0);
356       
357       if (attr)
358         combo->addItem(attr->value);
359     }
360     
361     return found;
362 }