00001 #ifndef GUI_HEADER_
00002 #define GUI_HEADER_
00003
00004 #include "headers.h"
00005
00006 #include <QAction>
00007 #include <QApplication>
00008 #include <QComboBox>
00009 #include <QDialogButtonBox>
00010 #include <QDoubleSpinBox>
00011 #include <QFileDialog>
00012 #include <QFileInfo>
00013 #include <QGridLayout>
00014 #include <QGroupBox>
00015 #include <QLabel>
00016 #include <QMainWindow>
00017 #include <QMenu>
00018 #include <QMenuBar>
00019 #include <QMessageBox>
00020 #include <QMouseEvent>
00021 #include <QProgressDialog>
00022 #include <QScrollArea>
00023 #include <QScrollBar>
00024 #include <QSpinBox>
00025 #include <QStatusBar>
00026 #include <QThread>
00027 #include <QTime>
00028 #include <QTimer>
00029 #include <QTranslator>
00030 #include <QTreeWidgetItem>
00031
00032 class ImageViewer;
00033 class SettingsDialog;
00034 class EncodingProgress;
00035
00037 class ImageViewer: public QMainWindow { Q_OBJECT
00038 friend class SettingsDialog;
00039 friend class EncodingProgress;
00040
00041 static const int AutoIterationCount= 10;
00042
00043 IRoot *modules_settings
00044 , *modules_encoding;
00045 int zoom;
00046 std::string encData;
00047
00048 QTranslator &translator;
00049 QLabel *imageLabel;
00050
00051 QDir lastPath;
00054 QAction
00055 readAct, writeAct, compareAct, exitAct,
00056 settingsAct, encodeAct, saveAct,
00057 loadAct, clearAct, iterateAct, zoomIncAct, zoomDecAct,
00058 loadLangAct, useLangAct;
00059
00061
00063 QMenu imageMenu, compMenu, decompMenu, langMenu;
00065 void createActions();
00066 void createMenus();
00067 void translateUi();
00068 void updateActions();
00069 void changePixmap(const QPixmap &pixmap) {
00070 imageLabel->setPixmap(pixmap);
00071 imageLabel->resize( pixmap.size() );
00072 }
00073 private slots:
00076 void read();
00077 void write();
00078 void compare();
00079 void settings();
00080 void encode();
00081 void save();
00082 void load();
00083 void clear();
00084 void iterate();
00085 void zoomInc();
00086 void zoomDec();
00087 void loadLang();
00088 void useLang(bool use);
00089
00090
00092 void encDone();
00093 public:
00095 ImageViewer(QApplication &app,QTranslator &trans);
00097 virtual ~ImageViewer()
00098 { delete modules_settings; delete modules_encoding; }
00099 private:
00101 bool rezoom();
00103 QString lastDir()
00104 { QDir dir(lastPath); return dir.cdUp() ? dir.path() : QDir::currentPath(); }
00105 #ifndef NDEBUG
00106 void mousePressEvent(QMouseEvent *event);
00107 #endif
00108 };
00109
00111 inline void aConnect( const QObject *sender, const char *signal, const QObject *receiver
00112 , const char *slot, Qt::ConnectionType type=Qt::AutoCompatConnection ) {
00113 DEBUG_ONLY( bool result= )
00114 QObject::connect(sender,signal,receiver,slot,type);
00115 ASSERT(result);
00116 }
00117
00119 class SettingsDialog: public QDialog { Q_OBJECT
00120 QGroupBox *setBox;
00121 QTreeWidget *treeWidget;
00122 QDialogButtonBox *loadSaveButtons;
00123 IRoot *settings;
00124
00126 ImageViewer& parentViewer() {
00127 ImageViewer *result= debugCast<ImageViewer*>(parent());
00128 ASSERT(result);
00129 return *result;
00130 }
00132 void initialize();
00133 private slots:
00135 void currentItemChanged(QTreeWidgetItem *current,QTreeWidgetItem *previous);
00137 void settingChanges(int which);
00139 void loadSaveClick(QAbstractButton *button);
00140 public:
00142 SettingsDialog(ImageViewer *parent,IRoot *settingsHolder);
00144 IRoot* getSettings() { return settings; }
00145 };
00146
00148 class SignalChanger: public QObject { Q_OBJECT
00149 int signal;
00150 public:
00153 SignalChanger( int whichSignal, QWidget *parent=0, Module::ChoiceType type=Module::Stop )
00154 : QObject(parent), signal(whichSignal) {
00155 if (!parent)
00156 return;
00157
00158 const char *signalString=0, *slotString=0;
00159 switch (type) {
00160 case Module::Int:
00161 case Module::IntLog2:
00162 signalString= SIGNAL(valueChanged(int));
00163 slotString= SLOT(notifyInt(int));
00164 break;
00165 case Module::Float:
00166 signalString= SIGNAL(valueChanged(double));
00167 slotString= SLOT(notifyDouble(double));
00168 break;
00169 case Module::ModuleCombo:
00170 case Module::Combo:
00171 signalString= SIGNAL(currentIndexChanged(int));
00172 slotString= SLOT(notifyInt(int));
00173 break;
00174 default:
00175 ASSERT(false);
00176 }
00177 aConnect( parent, signalString, this, slotString );
00178 }
00179 public slots:
00180 void notifyInt(int) { emit notify(signal); }
00181 void notifyDouble(double) { emit notify(signal); }
00182 signals:
00183 void notify(int);
00184 };
00185
00186
00187
00189 class EncodingProgress: public QProgressDialog { Q_OBJECT
00191 class EncThread: public QThread {
00192 IRoot *root;
00193 QImage image;
00194 bool success;
00195 UpdateInfo updateInfo;
00196 public:
00197 EncThread(IRoot *root_,const QImage &image_,const UpdateInfo &updateInfo_)
00198 : root(root_), image(image_), updateInfo(updateInfo_) {}
00199 virtual void run()
00200 { success= root->encode(image,updateInfo); }
00201 bool getSuccess() const
00202 { return success; }
00203 };
00204
00205 static EncodingProgress *instance;
00206
00207 bool terminate
00208 , updateMaxProgress
00209 , updateProgress;
00210 int progress
00211 , maxProgress;
00212
00213 IRoot *modules_encoding;
00214 UpdateInfo updateInfo;
00215
00216 QTimer updateTimer;
00217 QTime encTime;
00218 EncThread encThread;
00219
00220 private:
00222 static void incMaxProgress(int increment) {
00223 instance->maxProgress+= increment;
00224 instance->updateMaxProgress= true;
00225 }
00227 static void incProgress(int increment) {
00228 instance->progress+= increment;
00229
00230 instance->updateProgress= true;
00231 }
00232
00233 private slots:
00235 void setTerminate()
00236 { terminate= true; }
00238 void update() {
00239 if (updateMaxProgress) {
00240 setMaximum(maxProgress);
00241 updateMaxProgress= false;
00242 }
00243 if (updateProgress) {
00244 setValue(progress);
00245 updateProgress= false;
00246 }
00247 }
00248 private:
00250 EncodingProgress(ImageViewer *parent)
00251 : QProgressDialog( tr("Encoding..."), tr("Cancel"), 0, 100, parent, Qt::Dialog )
00252 , terminate(false), updateMaxProgress(false), updateProgress(false)
00253 , progress(0), maxProgress(0)
00254 , modules_encoding(parent->modules_settings->clone())
00255 , updateInfo( terminate, &incMaxProgress, &incProgress ), updateTimer(this)
00256 , encThread( modules_encoding, parent->imageLabel->pixmap()->toImage(), updateInfo ) {
00257 ASSERT(!instance);
00258 instance= this;
00259
00260 setWindowModality(Qt::ApplicationModal);
00261 setAutoClose(false);
00262 setAutoReset(false);
00263
00264 aConnect( this, SIGNAL(canceled()), this, SLOT(setTerminate()) );
00265
00266 aConnect( &updateTimer, SIGNAL(timeout()), this, SLOT(update()) );
00267 updateTimer.start(1000);
00268 encTime.start();
00269
00270 aConnect( &encThread, SIGNAL(finished()), parent, SLOT(encDone()) );
00271 encThread.start(QThread::LowPriority);
00272 }
00274 ~EncodingProgress() {
00275 ASSERT(this==instance);
00276 instance= 0;
00277 }
00278 public:
00280 static void create(ImageViewer *parent) {
00281 new EncodingProgress(parent);
00282 }
00284 static IRoot* destroy(int &elapsed) {
00285 ASSERT( instance && instance->encThread.isFinished() );
00286
00287 IRoot *result= instance->modules_encoding;
00288 if ( !instance->encThread.getSuccess() ) {
00289 delete result;
00290 result= 0;
00291 }
00292 elapsed= instance->encTime.elapsed();
00293
00294 delete instance;
00295 return result;
00296 }
00297 };
00298
00299 #endif // GUI_HEADER_