Some code cleanup and changes due to GCC upgrade to 4.3.*.
[fic.git] / gui.cpp
blob59778aa171baa470c5c6cabc865eadf5acf85ef2
1 #include "gui.h"
2 #include "modules/colorModel.h" // using color coefficients for RGB->gray conversion
4 using namespace std;
6 //// Non-member functions
7 static vector<double> getColorPSNR(const QImage &a,const QImage &b) {
8 int width= a.width(), height= a.height();
9 int x, y;
10 QRgb *line1, *line2;
11 int sum, sumR, sumG, sumB;
12 sum= sumR= sumG= sumB= 0;
13 for (y=0; y<height; ++y) {
14 line1= (QRgb*)a.scanLine(y);
15 line2= (QRgb*)b.scanLine(y);
16 for (x=0; x<width; ++x) {
17 sum+= sqr( getGray(line1[x]) - getGray(line2[x]) );
18 sumR+= sqr( qRed(line1[x]) - qRed(line2[x]) );
19 sumG+= sqr( qGreen(line1[x]) - qGreen(line2[x]) );
20 sumB+= sqr( qBlue(line1[x]) - qBlue(line2[x]) );
23 vector<double> result(4);
24 result[0]= sumR;
25 result[1]= sumG;
26 result[2]= sumB;
27 result[3]= sum;
28 double mul= double(width*height) * double(sqr(255));
29 for (vector<double>::iterator it=result.begin(); it!=result.end(); ++it)
30 *it= 10.0 * log10(mul / *it);
31 return result;
33 static QString getPSNRmessage(const QImage &img1,const QImage &img2) {
34 vector<double> psnr= getColorPSNR(img1,img2);
35 return QObject::tr("gray PSNR: %3 dB\nR,G,B: %4,%5,%6 dB") .arg(psnr[3],0,'f',2)
36 .arg(psnr[0],0,'f',2) .arg(psnr[1],0,'f',2) .arg(psnr[2],0,'f',2);
40 //// Public members
41 ImageViewer::ImageViewer(QApplication &app)
42 : modules_settings( IRoot::newCompatibleModule() ), modules_encoding(0)
43 , zoom(0), lastPath(QDir::current().filePath("x"))
44 , readAct(this), writeAct(this), compareAct(this), exitAct(this)
45 , settingsAct(this), encodeAct(this), saveAct(this)
46 , loadAct(this), clearAct(this), iterateAct(this), zoomIncAct(this), zoomDecAct(this) {
47 // try to load guessed language translation
48 if ( translator.load( "lang-"+QLocale::system().name(), app.applicationDirPath() ) )
49 app.installTranslator(&translator);
50 // create a scrolling area with a label for viewing images
51 imageLabel= new QLabel(this);
52 imageLabel->setBackgroundRole(QPalette::Dark);
53 imageLabel->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored);
55 QScrollArea *scrollArea= new QScrollArea(this);
56 scrollArea->setBackgroundRole(QPalette::Dark);
57 scrollArea->setWidget(imageLabel);
58 setCentralWidget(scrollArea);
60 setStatusBar(new QStatusBar(this));
62 createActions();
63 createMenus();
64 translateUi();
65 updateActions();
67 resize(800,600);
70 //// Private methods
71 void ImageViewer::createActions() {
72 // create all actions and connect them to the appropriate slots
73 #define A(name) \
74 aConnect( &name##Act, SIGNAL(triggered()), this, SLOT(name()) );
75 #define AS(name,signal) \
76 aConnect( &name##Act, SIGNAL(triggered()), this, SLOT(signal()) );
77 A(read)
78 A(write)
79 A(compare)
80 AS(exit,close)
82 A(settings)
83 A(encode)
84 A(save)
86 A(load)
87 A(clear)
88 A(iterate)
89 A(zoomInc)
90 A(zoomDec)
92 #undef A
93 #undef AS
95 void ImageViewer::createMenus() {
96 imageMenu.addAction(&readAct);
97 imageMenu.addAction(&writeAct);
98 imageMenu.addSeparator();
99 imageMenu.addAction(&compareAct);
100 imageMenu.addSeparator();
101 imageMenu.addAction(&exitAct);
103 compMenu.addAction(&settingsAct);
104 compMenu.addAction(&encodeAct);
105 compMenu.addAction(&saveAct);
107 decompMenu.addAction(&loadAct);
108 decompMenu.addAction(&clearAct);
109 decompMenu.addAction(&iterateAct);
110 decompMenu.addSeparator();
111 decompMenu.addAction(&zoomIncAct);
112 decompMenu.addAction(&zoomDecAct);
114 menuBar()->addMenu(&imageMenu);
115 menuBar()->addMenu(&compMenu);
116 menuBar()->addMenu(&decompMenu);
117 //menuBar()->addMenu(langMenu);
118 //menuBar()->addMenu(helpMenu);
120 void ImageViewer::translateUi() {
121 setWindowTitle(tr("Fractal Image Compressor"));
122 // set action names and shortcuts
123 #define A(name,shortcut,text) \
124 name##Act.setText(tr(text)); \
125 name##Act.setShortcut(tr(shortcut));
126 A(read, "Ctrl+R", "Read...")
127 A(write, "Ctrl+W", "Write...")
128 A(compare, "", "Compare to...")
129 A(exit, "Ctrl+Q", "Quit")
131 A(settings, "", "Settings")
132 A(encode, " ", "Start encoding")
133 A(save, "Ctrl+S", "Save FIC...")
135 A(load, "Ctrl+L", "Load FIC...")
136 A(clear, "Ctrl+C", "Clear image")
137 A(iterate, "Ctrl+I", "Iterate image")
138 A(zoomInc, "Ctrl++", "Increase zoom")
139 A(zoomDec, "Ctrl+-", "Decrease zoom")
140 #undef A
142 // set the tiles of menu items
143 #define M(name,title) \
144 name##Menu.setTitle(tr(title));
145 M(image, "&Image");
146 M(comp, "&Compression");
147 M(decomp, "&Decompression");
148 #undef M
150 void ImageViewer::updateActions() {
151 bool pixmapOk= imageLabel->pixmap();
152 IRoot::Mode mode= modules_encoding ? modules_encoding->getMode() : IRoot::Clear;
154 //readAct.setEnabled(true);
155 writeAct.setEnabled(pixmapOk);
156 compareAct.setEnabled(pixmapOk);
157 //exitAct.setEnabled(true);
159 //settingsAct.setEnabled(true);
160 encodeAct.setEnabled(pixmapOk);
161 saveAct.setEnabled( mode != IRoot::Clear );
163 //loadAct.setEnabled(true);
164 clearAct.setEnabled ( mode != IRoot::Clear );
165 iterateAct.setEnabled( mode != IRoot::Clear );
166 zoomIncAct.setEnabled( mode != IRoot::Clear && zoom<3 );
167 zoomDecAct.setEnabled( mode != IRoot::Clear && zoom>0 );
170 //// Private slots
171 void ImageViewer::read() {
172 // get the file name
173 QString fname= QFileDialog::getOpenFileName( this, tr("Read image file")
174 , lastDir(), tr("PNG images (*.png)\nAll files (*.*)") );
175 if (fname.isEmpty())
176 // no file selected
177 return;
178 lastPath.setPath(fname);
179 // try to load, check for errors
180 QImage image(fname);
181 if (image.isNull()) {
182 QMessageBox::information( this, tr("Error"), tr("Cannot open %1.").arg(fname) );
183 return;
185 // convert to 32-bits
186 if (image.depth()<32)
187 image= image.convertToFormat(QImage::Format_RGB32);
188 // display it
189 changePixmap(QPixmap::fromImage(image));
190 updateActions();
192 void ImageViewer::write() {
193 // get the file name
194 QString fname= QFileDialog::getSaveFileName( this, tr("Write image file")
195 , lastDir(), tr("PNG images (*.png)\nAll files (*.*)") );
196 if (fname.isEmpty())
197 return;
198 lastPath.setPath(fname);
199 // try to save the image
200 if ( !imageLabel->pixmap()->save(fname) ) {
201 QMessageBox::information( this, tr("Error"), tr("Cannot write file %1.").arg(fname) );
202 return;
204 updateActions();
206 void ImageViewer::compare() {
207 // let the user choose a file
208 QString fname= QFileDialog::getOpenFileName
209 ( this, tr("Compare to image"), lastDir()
210 , tr("PNG images (*.png)\nJFIF images (*.jpg *.jpeg)\nAll files (*.*)") );
211 if (fname.isEmpty())
212 return;
213 lastPath.setPath(fname);
214 // open the file as an image, check it's got the same dimensions as the diplayed one
215 QImage image(fname);
216 image= image.convertToFormat(QImage::Format_RGB32);
217 if (image.isNull()) {
218 QMessageBox::information( this, tr("Error"), tr("Cannot open %1.").arg(fname) );
219 return;
221 if ( image.width()!=imageLabel->pixmap()->width()
222 || image.height()!=imageLabel->pixmap()->height() ) {
223 QMessageBox::information
224 ( this, tr("Error"), tr("Images don't have the same dimensions.").arg(fname) );
225 return;
227 // compute the PSNRs and display them
228 QString message= getPSNRmessage( image, imageLabel->pixmap()->toImage() );
229 QMessageBox::information( this, tr("Comparison"), message );
231 void ImageViewer::settings() {
232 IRoot *newSettings= clone(modules_settings);
233 SettingsDialog dialog(this,newSettings);
234 newSettings= dialog.getSettings();
235 if ( dialog.exec() )
236 // the dialog wasn't cancelled -> swap with the current and new settings
237 swap(newSettings,modules_settings);
238 delete newSettings;
240 void ImageViewer::encode() {
241 EncodingProgress::create(this);
243 void ImageViewer::encDone() {
244 int encMsecs;
245 IRoot *modules_encoded= EncodingProgress::destroy(encMsecs);
247 if (modules_encoded) { // encoding successful - iterate the image and display some info
248 // replace the old state
249 delete modules_encoding;
250 modules_encoding= modules_encoded;
251 // decode the image
252 QImage beforeImg= modules_encoding->toImage();
254 QTime decTime;
255 decTime.start();
256 modules_encoding->decodeAct(MTypes::Clear);
257 modules_encoding->decodeAct(MTypes::Iterate,AutoIterationCount);
258 int decMsecs= decTime.elapsed();
260 QImage afterImg= modules_encoding->toImage();
261 changePixmap( QPixmap::fromImage(afterImg) );
262 // show some info
263 QString message= tr("Time to encode: %1 seconds\nTime to decode: %2 seconds\n")
264 .arg(encMsecs/1000.0) .arg(decMsecs/1000.0) + getPSNRmessage(beforeImg,afterImg);
265 QMessageBox::information( this, tr("encoded"), message );
266 encData.clear();
269 updateActions();
271 void ImageViewer::save() {
272 // get a filename to suggest
273 QFileInfo finfo(lastPath.path());
274 QString fname= finfo.dir().filePath( finfo.completeBaseName() + tr(".fic") );
275 fname= QFileDialog::getSaveFileName
276 ( this, tr("Save encoded image"), fname, tr("FIC images (*.fic)") );
277 if (fname.isEmpty())
278 return;
279 lastPath.setPath(fname);
280 if ( !modules_encoding->toFile( fname.toStdString().c_str() ) )
281 QMessageBox::information( this, tr("Error"), tr("Cannot write file %1.").arg(fname) );
283 void ImageViewer::load() {
284 QString fname= QFileDialog::getOpenFileName
285 ( this, tr("Load encoded image"), lastDir(), tr("FIC images (*.fic)") );
286 if (fname.isEmpty())
287 return;
288 lastPath.setPath(fname);
289 // IRoot needs to be loaded from cleared state
290 IRoot *modules_old= modules_encoding;
291 modules_encoding= clone(modules_settings,Module::ShallowCopy);
293 string decData;
294 bool error= !file2string( fname.toStdString().c_str(), decData );
295 if (!error) {
296 stringstream stream(decData);
298 error= !modules_encoding->fromStream( stream, zoom );
301 if (error) {
302 QMessageBox::information( this, tr("Error"), tr("Cannot load file %1.").arg(fname) );
303 swap(modules_encoding,modules_old);
304 } else { // loading was successful
305 swap(encData,decData);
306 modules_encoding->decodeAct(Clear);
307 modules_encoding->decodeAct(MTypes::Iterate,AutoIterationCount);
308 changePixmap( QPixmap::fromImage(modules_encoding->toImage()) );
309 updateActions();
312 delete modules_old;
314 void ImageViewer::clear() {
315 modules_encoding->decodeAct(Clear);
316 changePixmap( QPixmap::fromImage(modules_encoding->toImage()) );
317 updateActions();
319 void ImageViewer::iterate() {
320 modules_encoding->decodeAct(Iterate);
321 changePixmap( QPixmap::fromImage(modules_encoding->toImage()) );
322 updateActions();
324 void ImageViewer::zoomInc() {
325 ++zoom;
326 if (!rezoom())
327 --zoom, QMessageBox::information( this, tr("Error"), tr("Zooming failed.") );
329 void ImageViewer::zoomDec() {
330 --zoom;
331 ASSERT(zoom>=0);
332 if (!rezoom())
333 ++zoom, QMessageBox::information( this, tr("Error"), tr("Zooming failed.") );
336 bool ImageViewer::rezoom() {
337 // create a stream that contains the "saved image"
338 stringstream stream;
339 if ( encData.empty() ) { // cache is empty - we have to create it (save the image)
340 if ( !modules_encoding->toStream(stream) )
341 return false;
342 encData= stream.str();
343 } else // reusing the cache
344 stream.str(encData);
345 // reload the image from the stream
346 IRoot *newRoot= clone(modules_settings,Module::ShallowCopy);
347 if ( newRoot->fromStream(stream,zoom) ) {
348 delete modules_encoding;
349 modules_encoding= newRoot;
350 } else {
351 delete newRoot;
352 return false;
354 // successfully reloaded -> auto-iterate the image and show it
355 modules_encoding->decodeAct(MTypes::Clear);
356 modules_encoding->decodeAct(MTypes::Iterate,AutoIterationCount);
357 changePixmap( QPixmap::fromImage(modules_encoding->toImage()) );
358 updateActions();
359 return true;
363 //// SettingsDialog class
365 SettingsDialog::SettingsDialog( ImageViewer *parent, IRoot *settingsHolder )
366 : QDialog(parent,Qt::Dialog), settings(settingsHolder) {
367 setWindowTitle(tr("Compression settings"));
368 setModal(true);
369 // create a grid layout for the dialog
370 QGridLayout *layout= new QGridLayout;
371 setLayout(layout);
372 // add a tree widget
373 this->treeWidget= new QTreeWidget(this);
374 treeWidget->setHeaderLabel(tr("Modules"));
375 layout->addWidget(treeWidget,0,0);
376 // add a group-box to display settings of a module
377 this->setBox= new QGroupBox(this);
378 layout->addWidget(setBox,0,1);
379 // add a load/save button-box and connect it to a slot of this dialog
380 this->loadSaveButtons= new QDialogButtonBox
381 ( QDialogButtonBox::Open|QDialogButtonBox::Save, Qt::Horizontal, this );
382 aConnect( loadSaveButtons, SIGNAL(clicked(QAbstractButton*))
383 , this, SLOT(loadSaveClick(QAbstractButton*)) );
384 layout->addWidget(loadSaveButtons,1,0,Qt::AlignLeft);
385 // add a button-box and connect the clicking actions
386 QDialogButtonBox *buttons= new QDialogButtonBox
387 ( QDialogButtonBox::Ok|QDialogButtonBox::Cancel, Qt::Horizontal, this );
388 layout->addWidget(buttons,1,1); // the right-bottom cell
389 aConnect( buttons, SIGNAL(accepted()), this, SLOT(accept()) );
390 aConnect( buttons, SIGNAL(rejected()), this, SLOT(reject()) );
391 // create the tree
392 QTreeWidgetItem *treeRoot= new QTreeWidgetItem;
393 treeWidget->addTopLevelItem(treeRoot);
394 treeRoot->setText( 0, tr("Root") );
396 aConnect( treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*))
397 , this, SLOT(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)) );
399 initialize();
401 void SettingsDialog::initialize() {
402 QTreeWidgetItem *treeRoot= treeWidget->topLevelItem(0);
403 ASSERT( treeRoot && settings && setBox );
404 clearContainer( treeRoot->takeChildren() );
405 settings->adjustSettings(-1,treeRoot,setBox);
406 treeWidget->setCurrentItem(treeRoot);
407 treeWidget->expandAll();
409 void SettingsDialog::currentItemChanged(QTreeWidgetItem *curItem,QTreeWidgetItem*) {
410 // get the module that should show its settings
411 ASSERT(curItem);
412 Module *curMod= static_cast<Module*>( curItem->data(0,Qt::UserRole).value<void*>() );
413 ASSERT(curMod);
414 // clear the settings box and make the module fill it
415 clearContainer( setBox->children() );
416 setBox->setTitle( tr("%1 module settings") .arg(curMod->info().name) );
417 curMod->adjustSettings(-1,0,setBox);
419 void SettingsDialog::settingChanges(int which) {
420 QTreeWidgetItem *tree= treeWidget->currentItem();
421 Module *module= static_cast<Module*>( tree->data(0,Qt::UserRole).value<void*>() );
422 module->adjustSettings(which,tree,setBox);
424 void SettingsDialog::loadSaveClick(QAbstractButton *button) {
425 QDialogButtonBox::StandardButton test= loadSaveButtons->standardButton(button);
426 switch ( test ) {
427 case QDialogButtonBox::Open: { // open-button has been clicked
428 // ask for the name to load from
429 QString fname= QFileDialog::getOpenFileName( this, tr("Load settings file")
430 , parentViewer().lastDir(), tr("FIC settings (*.fms)") );
431 if (fname.isEmpty())
432 return;
433 // try to load the settings
434 IRoot *newSettings= clone(settings,Module::ShallowCopy);
435 if ( newSettings->allSettingsFromFile(fname.toStdString().c_str()) ) {
436 delete settings;
437 settings= newSettings;
438 initialize();
439 } else {
440 QMessageBox::information( this, tr("Error")
441 , tr("Cannot load settings from %1.").arg(fname) );
442 delete newSettings;
444 } break;
445 case QDialogButtonBox::Save: { // save-button has been clicked
446 // ask for the name to save in
447 QString fname= QFileDialog::getSaveFileName( this, tr("Save settings file")
448 , parentViewer().lastDir(), tr("FIC settings (*.fms)") );
449 if (fname.isEmpty())
450 return;
451 // try to save the settings
452 if ( !settings->allSettingsToFile(fname.toStdString().c_str()) )
453 QMessageBox::information( this, tr("Error")
454 , tr("Cannot save settings into %1.").arg(fname) );
455 } break;
456 default:
457 ASSERT(false);
461 //// GUI-related Module members
462 namespace NOSPACE {
463 QWidget* newSettingsWidget(Module::ChoiceType type,QWidget *parent) {
464 QWidget *result=0;
465 switch (type) {
466 case Module::Int:
467 case Module::IntLog2:
468 result= new QSpinBox(parent);
469 break;
470 case Module::Float:
471 result= new QDoubleSpinBox(parent);
472 break;
473 case Module::ModuleCombo:
474 case Module::Combo:
475 result= new QComboBox(parent);
476 break;
477 default:
478 ASSERT(false);
479 }// switch
480 return result;
483 void Module::adjustSettings(int which,QTreeWidgetItem *myTree,QGroupBox *setBox) {
484 if (which<0) {
485 // no change has really happened
486 ASSERT(which==-1);
487 if (myTree) {
488 // I should create the subtree -> store this-pointer as data
489 ASSERT( myTree->childCount() == 0 );
490 myTree->setData( 0, Qt::UserRole, QVariant::fromValue((void*)this) );
491 if (!settings) {
492 myTree->setFlags(0);
493 return;
495 // find child modules and make them create their subtrees
496 const SettingsTypeItem *setType= info().setType;
497 const SettingsItem *setItem= settings;
498 for (; setType->type.type!=Stop; ++setItem,++setType)
499 if ( setType->type.type == ModuleCombo ) {
500 // it is a module -> label its subtree-root and recurse (polymorphically)
501 ASSERT(setItem->m);
502 if ( !setItem->m->info().setLength )
503 continue; // skipping modules with no settings
504 QTreeWidgetItem *childTree= new QTreeWidgetItem(myTree);
505 childTree->setText( 0, QObject::tr(setType->label) );
506 setItem->m->adjustSettings( -1, childTree, 0 );
509 int setLength= info().setLength;
510 if ( setBox && setLength ) {
511 // fill the group-box
512 QGridLayout *layout= new QGridLayout(setBox);
513 setBox->setLayout(layout);
514 const SettingsTypeItem *typeItem= info().setType;
515 for (int i=0; i<setLength; ++i,++typeItem) {
516 // add a line - one option
517 QString desc(typeItem->desc);
518 QLabel *label= new QLabel( typeItem->label, setBox );
519 label->setToolTip(desc);
521 QWidget *widget= newSettingsWidget( typeItem->type.type, setBox );
522 settingsType2widget( widget, *typeItem );
523 settings2widget( widget, i );
524 widget->setToolTip(desc);
525 label->setBuddy(widget);
526 layout->addWidget( label, i, 0 );
527 layout->addWidget( widget, i, 1 );
529 SignalChanger *changer= new SignalChanger(i,widget,typeItem->type.type);
530 aConnect( changer, SIGNAL(notify(int)) // assuming the setBox's
531 , setBox->parent(), SLOT(settingChanges(int)) ); // parent is SettingsDialog
532 }// for loop
533 }// filling the box
534 } else {
535 // which>=0... a setting has changed -> get the change from the widget
536 ASSERT( which < info().setLength );
537 QLayoutItem *item= setBox->layout()->itemAt(2*which+1);
538 ASSERT(item);
539 widget2settings( item->widget() , which );
540 // handle module-type settings
541 const SettingsTypeItem *setType= info().setType;
542 if ( setType[which].type.type == ModuleCombo ) {
543 ASSERT(myTree);
544 // get the new module id and check whether it has really changed
545 SettingsItem &setItem= settings[which];
546 int newId= (*setType->type.data.compatIDs)[setItem.val.i];
547 if ( newId == setItem.m->info().id )
548 return;
549 // replace the child module
550 clearContainer( myTree->takeChildren() );
551 delete setItem.m;
552 setItem.m= ModuleFactory::newModule(newId);
553 adjustSettings( -1, myTree, 0 );
555 // update module defaults
556 ModuleFactory::changeDefaultSettings(*this);
559 void Module::widget2settings(const QWidget *widget,int which) {
560 ASSERT( 0<=which && which<info().setLength );
561 switch( info().setType[which].type.type ) {
562 case Int:
563 case IntLog2:
564 settings[which].val.i= debugCast<const QSpinBox*>(widget)->value();
565 break;
566 case Float:
567 settings[which].val.f= debugCast<const QDoubleSpinBox*>(widget)->value();
568 break;
569 case ModuleCombo:
570 case Combo:
571 settings[which].val.i= debugCast<const QComboBox*>(widget)->currentIndex();
572 break;
573 default:
574 ASSERT(false);
575 }// switch
577 void Module::settings2widget(QWidget *widget,int which) {
578 ASSERT( 0<=which && which<info().setLength );
579 switch( info().setType[which].type.type ) {
580 case Int:
581 case IntLog2:
582 debugCast<QSpinBox*>(widget)->setValue( settings[which].val.i );
583 break;
584 case Float:
585 debugCast<QDoubleSpinBox*>(widget)->setValue( settings[which].val.f );
586 break;
587 case ModuleCombo:
588 case Combo:
589 debugCast<QComboBox*>(widget)->setCurrentIndex( settings[which].val.i );
590 break;
591 default:
592 ASSERT(false);
593 }// switch
595 namespace NOSPACE {
596 class ItemAdder {
597 QComboBox *box;
598 public:
599 ItemAdder(QWidget *widget): box( debugCast<QComboBox*>(widget) ) {}
600 void operator()(int i) {
601 box->addItem( ModuleFactory::moduleName(i) );
602 box->setItemData( box->count()-1
603 , QObject::tr(ModuleFactory::moduleDescription(i)), Qt::ToolTipRole );
607 void Module::settingsType2widget(QWidget *widget,const SettingsTypeItem &typeItem) {
608 ASSERT( widget );
609 switch( typeItem.type.type ) {
610 case IntLog2:
611 debugCast<QSpinBox*>(widget)->setPrefix(QObject::tr("2^"));
612 // fall through
613 case Int:
614 debugCast<QSpinBox*>(widget)->
615 setRange( typeItem.type.data.i[0], typeItem.type.data.i[1] );
616 break;
617 case Float:
618 debugCast<QDoubleSpinBox*>(widget)->
619 setRange( typeItem.type.data.f[0], typeItem.type.data.f[1] );
620 break;
621 case ModuleCombo: {
622 const vector<int> &modules= *typeItem.type.data.compatIDs;
623 for_each( modules.begin(), modules.end(), ItemAdder(widget) );
624 break;
626 case Combo:
627 debugCast<QComboBox*>(widget)->
628 addItems( QString(typeItem.type.data.text).split('\n') );
629 break;
630 default:
631 ASSERT(false);
632 }// switch
636 #ifndef NDEBUG
637 void ImageViewer::mousePressEvent(QMouseEvent *event) {
638 // check the event, get the clicking point coordinates relative to the image
639 if ( !event || !modules_encoding
640 || modules_encoding->getMode() == IRoot::Clear)
641 return;
642 const QPoint click= imageLabel->mapFrom( this, event->pos() );
643 // get the image
644 QPixmap pixmap= *imageLabel->pixmap();
645 if ( click.isNull() )
646 return;
648 static QWidget *debugWidget= 0;
649 delete debugWidget;
650 debugWidget= modules_encoding->debugModule(pixmap,click);
651 debugWidget->setParent(this);
652 debugWidget->setWindowFlags(Qt::Dialog);
653 debugWidget->show();
655 changePixmap(pixmap);
657 #endif
660 EncodingProgress *EncodingProgress::instance= 0;