00001 #include <sstream>
00002
00003 #include "gui.h"
00004 #include "imageUtil.h"
00005 #include "fileUtil.h"
00006
00007 using namespace std;
00008
00010 static QString getPSNRmessage(const QImage &img1,const QImage &img2) {
00011 vector<Real> psnr= Color::getPSNR(img1,img2);
00012 return QObject::tr("gray PSNR: %3 dB\nR,G,B: %4,%5,%6 dB") .arg(psnr[3],0,'f',2)
00013 .arg(psnr[0],0,'f',2) .arg(psnr[1],0,'f',2) .arg(psnr[2],0,'f',2);
00014 }
00015
00016
00018 ImageViewer::ImageViewer(QApplication &app,QTranslator &trans)
00019 : modules_settings( IRoot::newCompatibleModule() ), modules_encoding(0)
00020 , zoom(0), translator(trans), lastPath(QDir::current().filePath("x"))
00021 , readAct(this), writeAct(this), compareAct(this), exitAct(this)
00022 , settingsAct(this), encodeAct(this), saveAct(this)
00023 , loadAct(this), clearAct(this), iterateAct(this), zoomIncAct(this), zoomDecAct(this)
00024 , loadLangAct(this), useLangAct(this) {
00025
00026 if ( translator.load( "lang-"+QLocale::system().name(), app.applicationDirPath() ) )
00027 app.installTranslator(&translator);
00028
00029 imageLabel= new QLabel(this);
00030 imageLabel->setBackgroundRole(QPalette::Dark);
00031 imageLabel->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored);
00032
00033 QScrollArea *scrollArea= new QScrollArea(this);
00034 scrollArea->setBackgroundRole(QPalette::Dark);
00035 scrollArea->setWidget(imageLabel);
00036 setCentralWidget(scrollArea);
00037
00038 setStatusBar(new QStatusBar(this));
00039
00040 createActions();
00041 createMenus();
00042 updateActions();
00043 translateUi();
00044
00045 resize(800,600);
00046 }
00047
00049 void ImageViewer::createActions() {
00050
00051 #define A(name) \
00052 aConnect( &name##Act, SIGNAL(triggered()), this, SLOT(name()) );
00053 #define AS(name,signal) \
00054 aConnect( &name##Act, SIGNAL(triggered()), this, SLOT(signal()) );
00055 #define AT(name) \
00056 aConnect( &name##Act, SIGNAL(toggled(bool)), this, SLOT(name(bool)) );
00057
00058 A(read)
00059 A(write)
00060 A(compare)
00061 AS(exit,close)
00062
00063 A(settings)
00064 A(encode)
00065 A(save)
00066
00067 A(load)
00068 A(clear)
00069 A(iterate)
00070 A(zoomInc)
00071 A(zoomDec)
00072
00073 A(loadLang)
00074 AT(useLang)
00075
00076 #undef A
00077 #undef AS
00078 #undef AT
00079
00080 useLangAct.setCheckable(true);
00081 useLangAct.setChecked( !translator.isEmpty() );
00082 }
00083 void ImageViewer::createMenus() {
00084 imageMenu.addAction(&readAct);
00085 imageMenu.addAction(&writeAct);
00086 imageMenu.addSeparator();
00087 imageMenu.addAction(&compareAct);
00088 imageMenu.addSeparator();
00089 imageMenu.addAction(&exitAct);
00090
00091 compMenu.addAction(&settingsAct);
00092 compMenu.addAction(&encodeAct);
00093 compMenu.addAction(&saveAct);
00094
00095 decompMenu.addAction(&loadAct);
00096 decompMenu.addAction(&clearAct);
00097 decompMenu.addAction(&iterateAct);
00098 decompMenu.addSeparator();
00099 decompMenu.addAction(&zoomIncAct);
00100 decompMenu.addAction(&zoomDecAct);
00101
00102 langMenu.addAction(&loadLangAct);
00103 langMenu.addAction(&useLangAct);
00104
00105 menuBar()->addMenu(&imageMenu);
00106 menuBar()->addMenu(&compMenu);
00107 menuBar()->addMenu(&decompMenu);
00108 menuBar()->addMenu(&langMenu);
00109
00110 }
00111 void ImageViewer::translateUi() {
00112 setWindowTitle(tr("Fractal Image Compressor"));
00113
00114 #define A(name,shortcut,text) \
00115 name##Act.setText(text); \
00116 name##Act.setShortcut(tr(shortcut));
00117 A(read, "Ctrl+R", tr("Read..."))
00118 A(write, "Ctrl+W", tr("Write..."))
00119 A(compare, "", tr("Compare to..."))
00120 A(exit, "Ctrl+Q", tr("Quit"))
00121
00122 A(settings, "", tr("Settings"))
00123 A(encode, " ", tr("Start encoding"))
00124 A(save, "Ctrl+S", tr("Save FCI..."))
00125
00126 A(load, "Ctrl+L", tr("Load FCI..."))
00127 A(clear, "Ctrl+C", tr("Clear image"))
00128 A(iterate, "Ctrl+I", tr("Iterate image"))
00129 A(zoomInc, "Ctrl++", tr("Increase zoom"))
00130 A(zoomDec, "Ctrl+-", tr("Decrease zoom"))
00131
00132 A(loadLang, "", tr("Load language..."))
00133 A(useLang, "", tr("Use language"))
00134 #undef A
00135
00136
00137 #define M(name,title) \
00138 name##Menu.setTitle(title);
00139 M(image, tr("&Image"));
00140 M(comp, tr("&Compression"));
00141 M(decomp, tr("&Decompression"));
00142 M(lang, tr("&Language"))
00143 #undef M
00144 }
00145 void ImageViewer::updateActions() {
00146 bool pixmapOk= imageLabel->pixmap();
00147 IRoot::Mode mode= modules_encoding ? modules_encoding->getMode() : IRoot::Clear;
00148
00149
00150 writeAct.setEnabled(pixmapOk);
00151 compareAct.setEnabled(pixmapOk);
00152
00153
00154
00155 encodeAct.setEnabled(pixmapOk);
00156 saveAct.setEnabled( mode != IRoot::Clear );
00157
00158
00159 clearAct.setEnabled ( mode != IRoot::Clear );
00160 iterateAct.setEnabled( mode != IRoot::Clear );
00161 zoomIncAct.setEnabled( mode != IRoot::Clear && zoom<3 );
00162 zoomDecAct.setEnabled( mode != IRoot::Clear && zoom>0 );
00163
00164 useLangAct.setEnabled( !translator.isEmpty() );
00165 }
00166
00168 void ImageViewer::read() {
00169
00170 QString fname= QFileDialog::getOpenFileName( this, tr("Read image file")
00171 , lastDir(), tr("PNG images (*.png)\nAll files (*.*)") );
00172 if (fname.isEmpty())
00173
00174 return;
00175 lastPath.setPath(fname);
00176
00177 QImage image(fname);
00178 if (image.isNull()) {
00179 QMessageBox::information( this, tr("Error"), tr("Cannot open %1.").arg(fname) );
00180 return;
00181 }
00182
00183 if ( image.format() != QImage::Format_RGB32 )
00184 image= image.convertToFormat(QImage::Format_RGB32);
00185
00186 changePixmap(QPixmap::fromImage(image));
00187 updateActions();
00188 }
00189 void ImageViewer::write() {
00190
00191 QString fname= QFileDialog::getSaveFileName( this, tr("Write image file")
00192 , lastDir(), tr("PNG images (*.png)\nAll files (*.*)") );
00193 if (fname.isEmpty())
00194 return;
00195 lastPath.setPath(fname);
00196
00197 if ( !imageLabel->pixmap()->save(fname) ) {
00198 QMessageBox::information( this, tr("Error"), tr("Cannot write file %1.").arg(fname) );
00199 return;
00200 }
00201 updateActions();
00202 }
00203 void ImageViewer::compare() {
00204
00205 QString fname= QFileDialog::getOpenFileName( this, tr("Compare to image"), lastDir()
00206 , tr("PNG images (*.png)\nJFIF images (*.jpg *.jpeg)\nAll files (*.*)") );
00207 if (fname.isEmpty())
00208 return;
00209 lastPath.setPath(fname);
00210
00211 QImage image(fname);
00212 if ( image.format() != QImage::Format_RGB32 )
00213 image= image.convertToFormat(QImage::Format_RGB32);
00214 if (image.isNull()) {
00215 QMessageBox::information( this, tr("Error"), tr("Cannot open %1.").arg(fname) );
00216 return;
00217 }
00218 if ( image.rect() != imageLabel->pixmap()->rect() ) {
00219 QMessageBox::information
00220 ( this, tr("Error"), tr("Images don't have the same dimensions.").arg(fname) );
00221 return;
00222 }
00223
00224 QString message= getPSNRmessage( image, imageLabel->pixmap()->toImage() );
00225 QMessageBox::information( this, tr("Comparison"), message );
00226 }
00227 void ImageViewer::settings() {
00228 IRoot *newSettings= modules_settings->clone();
00229 SettingsDialog dialog(this,newSettings);
00230 bool accepted= dialog.exec();
00231 newSettings= dialog.getSettings();
00232 if (accepted)
00233 swap(newSettings,modules_settings);
00234 delete newSettings;
00235 }
00236 void ImageViewer::encode() {
00237 EncodingProgress::create(this);
00238 }
00239 void ImageViewer::encDone() {
00240 int encMsecs;
00241 IRoot *modules_encoded= EncodingProgress::destroy(encMsecs);
00242
00243 if (modules_encoded) {
00244 zoom= 0;
00245
00246 delete modules_encoding;
00247 modules_encoding= modules_encoded;
00248
00249 QImage beforeImg= modules_encoding->toImage();
00250
00251 QTime decTime;
00252 decTime.start();
00253 modules_encoding->decodeAct(MTypes::Clear);
00254 modules_encoding->decodeAct(MTypes::Iterate,AutoIterationCount);
00255 int decMsecs= decTime.elapsed();
00256
00257 QImage afterImg= modules_encoding->toImage();
00258 changePixmap( QPixmap::fromImage(afterImg) );
00259
00260 QString message= tr("Time to encode: %1 seconds\nTime to decode: %2 seconds\n")
00261 .arg(encMsecs/1000.0) .arg(decMsecs/1000.0) + getPSNRmessage(beforeImg,afterImg);
00262 QMessageBox::information( this, tr("encoded"), message );
00263 encData.clear();
00264 }
00265
00266 updateActions();
00267 }
00268 void ImageViewer::save() {
00269
00270 QFileInfo finfo(lastPath.path());
00271 QString fname= finfo.dir().filePath( finfo.completeBaseName() + tr(".fci") );
00272 fname= QFileDialog::getSaveFileName
00273 ( this, tr("Save encoded image"), fname, tr("Fractal-compressed images (*.fci)") );
00274 if (fname.isEmpty())
00275 return;
00276 lastPath.setPath(fname);
00277 if ( !modules_encoding->toFile( fname.toStdString().c_str() ) )
00278 QMessageBox::information( this, tr("Error"), tr("Cannot write file %1.").arg(fname) );
00279 }
00280 void ImageViewer::load() {
00281 QString fname= QFileDialog::getOpenFileName
00282 ( this, tr("Load encoded image"), lastDir(), tr("Fractal-compressed images (*.fci)") );
00283 if (fname.isEmpty())
00284 return;
00285 lastPath.setPath(fname);
00286
00287 IRoot *modules_old= modules_encoding;
00288 modules_encoding= modules_settings->clone(Module::ShallowCopy);
00289
00290 string decData;
00291 bool error= !file2string( fname.toStdString().c_str(), decData );
00292 if (!error) {
00293 stringstream stream(decData);
00294 error= !modules_encoding->fromStream( stream, zoom );
00295 }
00296
00297 if (error) {
00298 QMessageBox::information( this, tr("Error"), tr("Cannot load file %1.").arg(fname) );
00299 swap(modules_encoding,modules_old);
00300 } else {
00301 swap(encData,decData);
00302 modules_encoding->decodeAct(Clear);
00303 modules_encoding->decodeAct(MTypes::Iterate,AutoIterationCount);
00304 changePixmap( QPixmap::fromImage(modules_encoding->toImage()) );
00305 updateActions();
00306 }
00307
00308 delete modules_old;
00309 }
00310 void ImageViewer::clear() {
00311 modules_encoding->decodeAct(Clear);
00312 changePixmap( QPixmap::fromImage(modules_encoding->toImage()) );
00313 updateActions();
00314 }
00315 void ImageViewer::iterate() {
00316 modules_encoding->decodeAct(Iterate);
00317 changePixmap( QPixmap::fromImage(modules_encoding->toImage()) );
00318 updateActions();
00319 }
00320 void ImageViewer::zoomInc() {
00321 ++zoom;
00322 if (!rezoom())
00323 --zoom, QMessageBox::information( this, tr("Error"), tr("Zooming failed.") );
00324 }
00325 void ImageViewer::zoomDec() {
00326 --zoom;
00327 ASSERT(zoom>=0);
00328 if (!rezoom())
00329 ++zoom, QMessageBox::information( this, tr("Error"), tr("Zooming failed.") );
00330 }
00331 void ImageViewer::loadLang() {
00332 QString fname= QFileDialog::getOpenFileName( this, tr("Load Language")
00333 , QApplication::applicationDirPath(), tr("Translation Definitions (*.qm)") );
00334 if (fname.isEmpty())
00335 return;
00336 if (translator.load(fname)) {
00337 useLangAct.setChecked(true);
00338 useLang(true);
00339 } else
00340 QMessageBox::warning( this, tr("Error"), tr("Cannot load %1.").arg(fname) );
00341 updateActions();
00342 }
00343 void ImageViewer::useLang(bool use) {
00344 if (use)
00345 QApplication::installTranslator(&translator);
00346 else
00347 QApplication::removeTranslator(&translator);
00348 translateUi();
00349 }
00350
00351 bool ImageViewer::rezoom() {
00352
00353 stringstream stream;
00354 if ( encData.empty() ) {
00355 if ( !modules_encoding->toStream(stream) )
00356 return false;
00357 encData= stream.str();
00358 } else
00359 stream.str(encData);
00360
00361 IRoot *newRoot= modules_settings->clone(Module::ShallowCopy);
00362 if ( newRoot->fromStream(stream,zoom) ) {
00363 delete modules_encoding;
00364 modules_encoding= newRoot;
00365 } else {
00366 delete newRoot;
00367 return false;
00368 }
00369
00370 modules_encoding->decodeAct(MTypes::Clear);
00371 modules_encoding->decodeAct(MTypes::Iterate,AutoIterationCount);
00372 changePixmap( QPixmap::fromImage(modules_encoding->toImage()) );
00373 updateActions();
00374 return true;
00375 }
00376
00377
00379
00380 SettingsDialog::SettingsDialog( ImageViewer *parent, IRoot *settingsHolder )
00381 : QDialog(parent,Qt::Dialog), settings(settingsHolder) {
00382 setWindowTitle(tr("Compression settings"));
00383 setModal(true);
00384
00385 QGridLayout *layout= new QGridLayout;
00386 setLayout(layout);
00387
00388 this->treeWidget= new QTreeWidget(this);
00389 treeWidget->setHeaderLabel(tr("Modules"));
00390 layout->addWidget(treeWidget,0,0);
00391
00392 this->setBox= new QGroupBox(this);
00393 layout->addWidget(setBox,0,1);
00394
00395 this->loadSaveButtons= new QDialogButtonBox
00396 ( QDialogButtonBox::Open|QDialogButtonBox::Save, Qt::Horizontal, this );
00397 aConnect( loadSaveButtons, SIGNAL(clicked(QAbstractButton*))
00398 , this, SLOT(loadSaveClick(QAbstractButton*)) );
00399 layout->addWidget(loadSaveButtons,1,0,Qt::AlignLeft);
00400
00401 QDialogButtonBox *buttons= new QDialogButtonBox
00402 ( QDialogButtonBox::Ok|QDialogButtonBox::Cancel, Qt::Horizontal, this );
00403 layout->addWidget(buttons,1,1);
00404 aConnect( buttons, SIGNAL(accepted()), this, SLOT(accept()) );
00405 aConnect( buttons, SIGNAL(rejected()), this, SLOT(reject()) );
00406
00407 QTreeWidgetItem *treeRoot= new QTreeWidgetItem;
00408 treeWidget->addTopLevelItem(treeRoot);
00409 treeRoot->setText( 0, tr("Root") );
00410
00411 aConnect( treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*))
00412 , this, SLOT(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)) );
00413
00414 initialize();
00415 }
00416 void SettingsDialog::initialize() {
00417 QTreeWidgetItem *treeRoot= treeWidget->topLevelItem(0);
00418 ASSERT( treeRoot && settings && setBox );
00419
00420 clearQtContainer( treeRoot->takeChildren() );
00421
00422 settings->adjustSettings(-1,treeRoot,setBox);
00423 treeWidget->setCurrentItem(treeRoot);
00424 treeWidget->expandAll();
00425 }
00426 void SettingsDialog::currentItemChanged(QTreeWidgetItem *curItem,QTreeWidgetItem*) {
00427
00428 ASSERT(curItem);
00429 Module *curMod= static_cast<Module*>( curItem->data(0,Qt::UserRole).value<void*>() );
00430 ASSERT(curMod);
00431
00432 clearQtContainer( setBox->children() );
00433 setBox->setTitle( tr("%1 module settings") .arg(QObject::tr(curMod->info().name)) );
00434 curMod->adjustSettings(-1,0,setBox);
00435 }
00436 void SettingsDialog::settingChanges(int which) {
00437 QTreeWidgetItem *tree= treeWidget->currentItem();
00438 Module *module= static_cast<Module*>( tree->data(0,Qt::UserRole).value<void*>() );
00439 module->adjustSettings(which,tree,setBox);
00440 }
00441 void SettingsDialog::loadSaveClick(QAbstractButton *button) {
00442 QDialogButtonBox::StandardButton test= loadSaveButtons->standardButton(button);
00443 switch ( test ) {
00444 case QDialogButtonBox::Open: {
00445
00446 QString fname= QFileDialog::getOpenFileName( this, tr("Load settings file")
00447 , parentViewer().lastDir(), tr("Fractal compression settings (*.fcs)") );
00448 if (fname.isEmpty())
00449 return;
00450
00451 IRoot *newSettings= settings->clone(Module::ShallowCopy);
00452 if ( newSettings->allSettingsFromFile(fname.toStdString().c_str()) ) {
00453 delete settings;
00454 settings= newSettings;
00455 initialize();
00456 } else {
00457 QMessageBox::information( this, tr("Error")
00458 , tr("Cannot load settings from %1.").arg(fname) );
00459 delete newSettings;
00460 }
00461 } break;
00462 case QDialogButtonBox::Save: {
00463
00464 QString fname= QFileDialog::getSaveFileName( this, tr("Save settings file")
00465 , parentViewer().lastDir()+"/settings.fcs"
00466 , tr("Fractal compression settings (*.fcs)") );
00467 if (fname.isEmpty())
00468 return;
00469
00470 if ( !settings->allSettingsToFile(fname.toStdString().c_str()) )
00471 QMessageBox::information( this, tr("Error")
00472 , tr("Cannot save settings into %1.").arg(fname) );
00473 } break;
00474 default:
00475 ASSERT(false);
00476 }
00477 }
00478
00480 namespace NOSPACE {
00481 QWidget* newSettingsWidget(Module::ChoiceType type,QWidget *parent) {
00482 QWidget *result=0;
00483 switch (type) {
00484 case Module::Int:
00485 case Module::IntLog2:
00486 result= new QSpinBox(parent);
00487 break;
00488 case Module::Float:
00489 result= new QDoubleSpinBox(parent);
00490 break;
00491 case Module::ModuleCombo:
00492 case Module::Combo:
00493 result= new QComboBox(parent);
00494 break;
00495 default:
00496 ASSERT(false);
00497 }
00498 return result;
00499 }
00500 }
00501 void Module::adjustSettings(int which,QTreeWidgetItem *myTree,QGroupBox *setBox) {
00502 if (which<0) {
00503 ASSERT(which==-1);
00504 if (myTree) {
00505
00506 ASSERT( myTree->childCount() == 0 );
00507 myTree->setData( 0, Qt::UserRole, QVariant::fromValue((void*)this) );
00508 if (!settings) {
00509 myTree->setFlags(0);
00510 return;
00511 }
00512
00513 const SettingTypeItem *setType= info().setType;
00514 const SettingItem *setItem= settings;
00515 for (; setType->type.type!=Stop; ++setItem,++setType)
00516 if ( setType->type.type == ModuleCombo ) {
00517
00518 ASSERT(setItem->m);
00519 if ( !setItem->m->info().setLength )
00520 continue;
00521 QTreeWidgetItem *childTree= new QTreeWidgetItem(myTree);
00522 childTree->setText( 0, QObject::tr(setType->label) );
00523 setItem->m->adjustSettings( -1, childTree, 0 );
00524 }
00525 }
00526 int setLength= info().setLength;
00527 if ( setBox && setLength ) {
00528
00529 clearQtContainer( setBox->children() );
00530 ASSERT( setBox->children().empty() );
00531
00532 QGridLayout *layout= new QGridLayout(setBox);
00533 setBox->setLayout(layout);
00534 const SettingTypeItem *typeItem= info().setType;
00535 for (int i=0; i<setLength; ++i,++typeItem) {
00536 QString desc= QObject::tr(typeItem->desc);
00537 QLabel *label= new QLabel( QObject::tr(typeItem->label), setBox );
00538 label->setToolTip(desc);
00539
00540 QWidget *widget= newSettingsWidget( typeItem->type.type, setBox );
00541 settingsType2widget( widget, *typeItem );
00542 settings2widget( widget, i );
00543 widget->setToolTip(desc);
00544 label->setBuddy(widget);
00545 layout->addWidget( label, i, 0 );
00546 layout->addWidget( widget, i, 1 );
00547
00548 SignalChanger *changer= new SignalChanger(i,widget,typeItem->type.type);
00549 aConnect( changer, SIGNAL(notify(int))
00550 , setBox->parent(), SLOT(settingChanges(int)) );
00551 }
00552 }
00553 } else {
00554
00555 ASSERT( which < info().setLength );
00556 QLayoutItem *item= setBox->layout()->itemAt(2*which+1);
00557 ASSERT(item);
00558 widget2settings( item->widget() , which );
00559
00560 const SettingTypeItem &setType= info().setType[which];
00561 if ( setType.type.type == ModuleCombo ) {
00562 ASSERT(myTree);
00563
00564 SettingItem &setItem= settings[which];
00565 int newId= (*setType.type.data.compatIDs)[setItem.val.i];
00566 if ( newId == setItem.m->info().id )
00567 return;
00568
00569 clearQtContainer( myTree->takeChildren() );
00570 delete setItem.m;
00571 setItem.m= ModuleFactory::newModule(newId);
00572 adjustSettings( -1, myTree, 0 );
00573 }
00574
00575 ModuleFactory::changeDefaultSettings(*this);
00576 }
00577 }
00578 void Module::widget2settings(const QWidget *widget,int which) {
00579 ASSERT( 0<=which && which<info().setLength );
00580 switch( info().setType[which].type.type ) {
00581 case Int:
00582 case IntLog2:
00583 settings[which].val.i= debugCast<const QSpinBox*>(widget)->value();
00584 break;
00585 case Float:
00586 settings[which].val.f= debugCast<const QDoubleSpinBox*>(widget)->value();
00587 break;
00588 case ModuleCombo:
00589 case Combo:
00590 settings[which].val.i= debugCast<const QComboBox*>(widget)->currentIndex();
00591 break;
00592 default:
00593 ASSERT(false);
00594 }
00595 }
00596 void Module::settings2widget(QWidget *widget,int which) {
00597 ASSERT( 0<=which && which<info().setLength );
00598 switch( info().setType[which].type.type ) {
00599 case Int:
00600 case IntLog2:
00601 debugCast<QSpinBox*>(widget)->setValue( settings[which].val.i );
00602 break;
00603 case Float:
00604 debugCast<QDoubleSpinBox*>(widget)->setValue( settings[which].val.f );
00605 break;
00606 case ModuleCombo:
00607 case Combo:
00608 debugCast<QComboBox*>(widget)->setCurrentIndex( settings[which].val.i );
00609 break;
00610 default:
00611 ASSERT(false);
00612 }
00613 }
00614 namespace NOSPACE {
00615 class ItemAdder {
00616 QComboBox *box;
00617 public:
00618 ItemAdder(QWidget *widget): box( debugCast<QComboBox*>(widget) ) {}
00619 void operator()(int i) {
00620 const Module::TypeInfo &info= ModuleFactory::prototype(i).info();
00621 box->addItem(QObject::tr(info.name));
00622 box->setItemData( box->count()-1, QObject::tr(info.desc), Qt::ToolTipRole );
00623 }
00624 };
00625 }
00626 void Module::settingsType2widget(QWidget *widget,const SettingTypeItem &typeItem) {
00627 ASSERT(widget);
00628 const SettingType &type= typeItem.type;
00629
00630 switch(type.type) {
00631 case IntLog2:
00632 debugCast<QSpinBox*>(widget)->setPrefix(QObject::tr("2^"));
00633
00634 case Int: {
00635 debugCast<QSpinBox*>(widget)->setRange( type.data.i[0], type.data.i[1] );
00636
00637 int range= type.data.i[1]-type.data.i[0];
00638 int step= (int)exp10(floor(log10(range/5)));
00639 if (!(step>0))
00640 step= 1;
00641 debugCast<QSpinBox*>(widget)->setSingleStep(step);
00642 break;
00643 }
00644 case Float: {
00645 debugCast<QDoubleSpinBox*>(widget)->setRange( type.data.f[0], type.data.f[1] );
00646
00647 float range= type.data.f[1]-type.data.f[0];
00648 debugCast<QDoubleSpinBox*>(widget)->setSingleStep( exp10(floor(log10(range/5))) );
00649 break;
00650 }
00651 case ModuleCombo: {
00652 const vector<int> &modules= *typeItem.type.data.compatIDs;
00653 for_each( modules, ItemAdder(widget) );
00654 break;
00655 }
00656 case Combo:
00657 debugCast<QComboBox*>(widget)->addItems( QObject::tr(type.data.text).split('\n') );
00658 break;
00659 default:
00660 ASSERT(false);
00661 }
00662 }
00663
00664
00665 #ifndef NDEBUG
00666 void ImageViewer::mousePressEvent(QMouseEvent *event) {
00667
00668 if ( !event || !modules_encoding
00669 || modules_encoding->getMode() == IRoot::Clear)
00670 return;
00671 const QPoint click= imageLabel->mapFrom( this, event->pos() );
00672
00673 QPixmap pixmap= *imageLabel->pixmap();
00674 if ( click.isNull() )
00675 return;
00676
00677 static QWidget *debugWidget= 0;
00678 delete debugWidget;
00679 debugWidget= modules_encoding->debugModule(pixmap,click);
00680 debugWidget->setParent(this);
00681 debugWidget->setWindowFlags(Qt::Dialog);
00682 debugWidget->show();
00683
00684 changePixmap(pixmap);
00685 }
00686 #endif
00687
00688
00689 EncodingProgress *EncodingProgress::instance= 0;