author | warmi <warmi> | 2002-08-15 03:19:32 (UTC) |
---|---|---|
committer | warmi <warmi> | 2002-08-15 03:19:32 (UTC) |
commit | acdedf093413a37a3e2c1ab5b12c1ab0a95b670b (patch) (unidiff) | |
tree | e5ffc814ae6b7e0787b24347e3e98c16fa3ca68c | |
parent | 92640e4094075342138796065040441210348c76 (diff) | |
download | opie-acdedf093413a37a3e2c1ab5b12c1ab0a95b670b.zip opie-acdedf093413a37a3e2c1ab5b12c1ab0a95b670b.tar.gz opie-acdedf093413a37a3e2c1ab5b12c1ab0a95b670b.tar.bz2 |
Bunch of new GUI features ( brightness control, ability to view unscaled images ..)
Qte image handling issues are still not fixed though.
-rw-r--r-- | noncore/multimedia/showimg/showimg.cpp | 1019 |
1 files changed, 753 insertions, 266 deletions
diff --git a/noncore/multimedia/showimg/showimg.cpp b/noncore/multimedia/showimg/showimg.cpp index 24218e6..d7d53ec 100644 --- a/noncore/multimedia/showimg/showimg.cpp +++ b/noncore/multimedia/showimg/showimg.cpp | |||
@@ -14,544 +14,1031 @@ | |||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | 14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
15 | ** | 15 | ** |
16 | ** Contact info@trolltech.com if any conditions of this licensing are | 16 | ** Contact info@trolltech.com if any conditions of this licensing are |
17 | ** not clear to you. | 17 | ** not clear to you. |
18 | ** | 18 | ** |
19 | **********************************************************************/ | 19 | **********************************************************************/ |
20 | 20 | ||
21 | // | 21 | // |
22 | // Full-screen and rotation options contributed by Robert Wittams <robert@wittams.com> | 22 | // Full-screen and rotation options contributed by Robert Wittams <robert@wittams.com> |
23 | // | 23 | // |
24 | 24 | ||
25 | #include "showimg.h" | 25 | #include "showimg.h" |
26 | 26 | #include "ImageFileSelector.h" | |
27 | |||
28 | #include <qpe/config.h> | ||
27 | #include <qpe/resource.h> | 29 | #include <qpe/resource.h> |
28 | #include <qpe/fileselector.h> | 30 | #include <qpe/fileselector.h> |
29 | #include <qpe/applnk.h> | 31 | #include <qpe/applnk.h> |
30 | 32 | #include <qfileinfo.h> | |
33 | #include <math.h> | ||
31 | #include <qpe/qpemenubar.h> | 34 | #include <qpe/qpemenubar.h> |
32 | #include <qwidgetstack.h> | 35 | #include <qwidgetstack.h> |
33 | #include <qpe/qpetoolbar.h> | 36 | #include <qpe/qpetoolbar.h> |
34 | #include <qaction.h> | 37 | #include <qaction.h> |
35 | #include <qfiledialog.h> | 38 | #include <qfiledialog.h> |
36 | #include <qmessagebox.h> | 39 | #include <qmessagebox.h> |
37 | #include <qpopupmenu.h> | 40 | #include <qpopupmenu.h> |
41 | #include <qscrollview.h> | ||
38 | #include <qlabel.h> | 42 | #include <qlabel.h> |
39 | #include <qpainter.h> | 43 | #include <qpainter.h> |
40 | #include <qkeycode.h> | 44 | #include <qkeycode.h> |
41 | #include <qapplication.h> | 45 | #include <qapplication.h> |
42 | #include <qclipboard.h> | 46 | #include <qclipboard.h> |
43 | #include <qtimer.h> | 47 | #include <qtimer.h> |
48 | #include <qspinbox.h> | ||
44 | 49 | ||
45 | 50 | ||
46 | ImagePane::ImagePane( QWidget *parent ) : QWidget( parent ) | 51 | |
52 | ControlsDialog::ControlsDialog(const QString &caption,QImage image,int *brightness,QWidget *parent):QDialog(parent,0,true) | ||
47 | { | 53 | { |
48 | vb = new QVBoxLayout( this ); | 54 | setCaption(caption); |
49 | 55 | ||
50 | image = new ImageWidget( this ); | 56 | if ( parent ) |
51 | connect(image, SIGNAL( clicked() ), this, SLOT( imageClicked() )); | 57 | { |
58 | setPalette(parent->palette()); | ||
59 | } | ||
52 | 60 | ||
53 | vb->addWidget( image ); | 61 | b=brightness; |
62 | img=image; | ||
63 | |||
64 | setMinimumSize(140,80); | ||
65 | |||
66 | QGridLayout *gl= new QGridLayout(this,2,2,4,4); | ||
67 | |||
68 | pixmap =new ImageWidget(this);; | ||
69 | QPixmap pm; | ||
70 | pm.convertFromImage(img); | ||
71 | pixmap->setPixmap(pm); | ||
72 | pixmap->setMinimumSize(pm.width(),pm.height()); | ||
73 | gl->addMultiCellWidget(pixmap,0,0,0,2,AlignCenter); | ||
74 | QLabel *l=new QLabel(tr("Brightness")+":",this); | ||
75 | gl->addWidget(l,1,0,AlignLeft); | ||
76 | spb=new QSpinBox(-100,100,2,this); | ||
77 | gl->addWidget(spb,1,1,AlignRight); | ||
78 | |||
79 | spb->setValue(0); | ||
80 | |||
81 | connect(spb,SIGNAL(valueChanged(int)),this, SLOT(bValueChanged(int))); | ||
54 | 82 | ||
55 | status = new QLabel( this ); | ||
56 | status->setFixedHeight( fontMetrics().height() + 4 ); | ||
57 | vb->addWidget( status ); | ||
58 | } | 83 | } |
59 | 84 | ||
60 | void ImagePane::setPixmap( const QPixmap &pm ) | 85 | void ControlsDialog::bValueChanged(int value) |
61 | { | 86 | { |
62 | image->setPixmap( pm ); | 87 | QImage nImage=img; |
63 | image->repaint( false ); | 88 | nImage.detach(); |
89 | ImageViewer::intensity(nImage, (float)value/100); | ||
90 | QPixmap pm; | ||
91 | pm.convertFromImage(nImage); | ||
92 | pixmap->setPixmap(pm); | ||
93 | pixmap->repaint(false); | ||
94 | |||
95 | |||
64 | } | 96 | } |
65 | 97 | ||
66 | void ImagePane::imageClicked() | 98 | void ControlsDialog::accept() |
67 | { | 99 | { |
68 | emit clicked(); | 100 | *b=spb->value(); |
101 | done(1); | ||
69 | } | 102 | } |
70 | 103 | ||
71 | void ImagePane::showStatus() | 104 | |
105 | |||
106 | InfoDialog::InfoDialog(const QString &caption, const QStringList text,QWidget *parent):QDialog(parent,0,true) | ||
72 | { | 107 | { |
73 | delete vb; | 108 | setCaption(caption); |
74 | vb = new QVBoxLayout( this ); | 109 | |
75 | vb->addWidget( image ); | 110 | if ( parent ) |
76 | status->show(); | 111 | { |
77 | vb->addWidget( status ); | 112 | setPalette(parent->palette()); |
113 | } | ||
114 | |||
115 | const char *labels[]={"File Name","Format","File Size","Size","Colors","Alpha"}; | ||
116 | |||
117 | setMinimumSize(180,80); | ||
118 | int num=ImageViewer::LAST+1; | ||
119 | if ( text[ImageViewer::ALPHA].isEmpty() ) | ||
120 | num--; | ||
121 | QGridLayout *gl= new QGridLayout(this,num,2,4,2); | ||
122 | QLabel *l; | ||
123 | int count=0; | ||
124 | for ( int i=0;i<num;i++ ) | ||
125 | { | ||
126 | if ( i==1 ) | ||
127 | { | ||
128 | QFrame *frm=new QFrame(this); | ||
129 | frm->setFrameStyle(QFrame::HLine|QFrame::Sunken); | ||
130 | gl->addMultiCellWidget(frm,i,i,0,1); | ||
131 | } | ||
132 | else | ||
133 | { | ||
134 | l=new QLabel(tr(labels[count])+":",this); | ||
135 | gl->addWidget(l,i,0,AlignLeft); | ||
136 | l=new QLabel(text[count],this); | ||
137 | gl->addWidget(l,i,1,AlignRight); | ||
138 | count++; | ||
139 | } | ||
140 | |||
141 | } | ||
142 | |||
78 | } | 143 | } |
79 | 144 | ||
145 | void InfoDialog::displayInfo(const QString &caption, const QStringList text, QWidget *parent) | ||
146 | { | ||
147 | InfoDialog *dlg=new InfoDialog(caption,text,parent); | ||
148 | dlg->exec(); | ||
149 | delete dlg; | ||
150 | } | ||
151 | |||
80 | 152 | ||
81 | void ImagePane::hideStatus() | 153 | ImagePane::ImagePane( QWidget *parent ) : QWidget( parent ) |
82 | { | 154 | { |
83 | delete vb; | ||
84 | vb = new QVBoxLayout( this ); | 155 | vb = new QVBoxLayout( this ); |
156 | |||
157 | image = new QScrollView(this,0,WResizeNoErase|WNorthWestGravity); | ||
158 | pic=new ImageWidget(image); | ||
159 | image->addChild(pic); | ||
160 | |||
161 | connect(pic, SIGNAL( clicked() ), this, SLOT( imageClicked() )); | ||
162 | |||
85 | vb->addWidget( image ); | 163 | vb->addWidget( image ); |
86 | status->hide(); | 164 | |
87 | } | 165 | } |
88 | 166 | ||
167 | void ImagePane::setPixmap( const QPixmap &pm ) | ||
168 | { | ||
169 | pic->setPixmap( pm ); | ||
170 | pic->resize(pm.width(),pm.height()); | ||
171 | image->updateScrollBars (); | ||
172 | pic->repaint(false); | ||
173 | } | ||
174 | |||
175 | void ImagePane::imageClicked() | ||
176 | { | ||
177 | emit clicked(); | ||
178 | } | ||
89 | //=========================================================================== | 179 | //=========================================================================== |
90 | /* | 180 | /* |
91 | Draws the portion of the scaled pixmap that needs to be updated | 181 | Draws the portion of the scaled pixmap that needs to be updated |
92 | */ | 182 | */ |
93 | 183 | ||
94 | void ImageWidget::paintEvent( QPaintEvent *e ) | 184 | void ImageWidget::paintEvent( QPaintEvent *e ) |
95 | { | 185 | { |
96 | QPainter painter(this); | 186 | QPainter painter(this); |
97 | 187 | ||
98 | painter.setClipRect(e->rect()); | 188 | painter.setClipRect(e->rect()); |
99 | painter.setBrush( black ); | 189 | painter.fillRect(0,0,width(),height(),QColor(0,0,0)); |
100 | painter.drawRect( 0, 0, width(), height() ); | ||
101 | 190 | ||
102 | if ( pixmap.size() != QSize( 0, 0 ) ) { // is an image loaded? | 191 | if ( pixmap.size() != QSize( 0, 0 ) ) |
103 | painter.drawPixmap((width() - pixmap.width()) / 2, (height() - pixmap.height()) / 2, pixmap); | 192 | { // is an image loaded? |
193 | painter.drawPixmap((width() - pixmap.width()) / 2, (height() - pixmap.height()) / 2, pixmap); | ||
104 | } | 194 | } |
105 | } | 195 | } |
106 | 196 | ||
107 | void ImageWidget::mouseReleaseEvent(QMouseEvent *) | 197 | void ImageWidget::mouseReleaseEvent(QMouseEvent *) |
108 | { | 198 | { |
109 | emit clicked(); | 199 | emit clicked(); |
110 | } | 200 | } |
111 | 201 | ||
112 | |||
113 | //=========================================================================== | 202 | //=========================================================================== |
114 | 203 | ||
115 | ImageViewer::ImageViewer( QWidget *parent, const char *name, int wFlags ) | 204 | ImageViewer::ImageViewer( QWidget *parent, const char *name, int wFlags ) |
116 | : QMainWindow( parent, name, wFlags ), filename( 0 ), | 205 | : QMainWindow( parent, name, wFlags ), filename( 0 ), bFromDocView( FALSE ) |
117 | pickx( -1 ), picky( -1 ), clickx( -1 ), clicky( -1 ), bFromDocView( FALSE ) | ||
118 | { | 206 | { |
119 | setCaption( tr("Image Viewer") ); | 207 | setCaption( tr("Image Viewer") ); |
120 | setIcon( Resource::loadPixmap( "ImageViewer" ) ); | 208 | setIcon( Resource::loadPixmap( "ImageViewer" ) ); |
121 | 209 | ||
210 | |||
211 | Config cfg("Image Viewer"); | ||
212 | cfg.setGroup("Image Viewer"); | ||
213 | |||
214 | showThumbView=cfg.readBoolEntry("ShowThumbnails",false); | ||
215 | isSized=cfg.readBoolEntry("SizeToScreen",true); | ||
216 | |||
122 | isFullScreen = FALSE; | 217 | isFullScreen = FALSE; |
123 | 218 | ||
124 | setToolBarsMovable( FALSE ); | 219 | setToolBarsMovable( FALSE ); |
125 | 220 | ||
126 | toolBar = new QPEToolBar( this ); | 221 | toolBar = new QPEToolBar( this ); |
127 | toolBar->setHorizontalStretchable( TRUE ); | 222 | toolBar->setHorizontalStretchable( TRUE ); |
128 | 223 | ||
129 | menubar = new QPEMenuBar( toolBar ); | 224 | menuBar = new QPEMenuBar( toolBar ); |
225 | |||
226 | current=menuBar; | ||
227 | |||
228 | |||
229 | |||
230 | fileMenuFile = new QPopupMenu(this); | ||
231 | //menuBarmenubarFile->insertItem( tr("File"), fileMenu ); | ||
232 | fileMenuFile->insertItem(tr("Open"), this, SLOT(openFile()), 0); | ||
233 | |||
234 | viewMenuFile = new QPopupMenu( this ); | ||
235 | //menubarFile->insertItem( tr("View"), viewMenu ); | ||
236 | viewMenuFile->insertItem( tr("Thumbnail View"), this, SLOT(switchThumbView()), 0, SHOW_THUMBNAILS ); | ||
237 | |||
238 | viewMenuFile->setItemChecked ( SHOW_THUMBNAILS, showThumbView ); | ||
239 | |||
240 | |||
241 | |||
242 | |||
243 | optionsMenuFile = new QPopupMenu( this); | ||
244 | //menubarFile->insertItem( tr("Options"),optionsMenu ); | ||
245 | optionsMenuFile->insertItem( tr("Slideshow") ); | ||
246 | optionsMenuFile->insertSeparator(); | ||
247 | optionsMenuFile->insertItem( tr("Preferences..")); | ||
248 | optionsMenuFile->insertItem( tr("Help")); | ||
249 | |||
250 | |||
251 | |||
130 | 252 | ||
131 | QStrList fmt = QImage::outputFormats(); | 253 | QStrList fmt = QImage::outputFormats(); |
132 | 254 | ||
133 | QPopupMenu *edit = new QPopupMenu( menubar ); | ||
134 | QPopupMenu *view = new QPopupMenu( menubar ); | ||
135 | 255 | ||
136 | menubar->insertItem(tr("Edit"), edit ); | 256 | fileMenuView = new QPopupMenu( this ); |
137 | menubar->insertItem(tr("View"), view ); | 257 | //menubarView->insertItem( tr("File"),fileMenu ); |
258 | fileMenuView->insertItem( tr("Image Info ..."),this, SLOT(displayInfoDialog()),0 ); | ||
259 | fileMenuView->insertSeparator(); | ||
260 | |||
261 | viewMenuView = new QPopupMenu(this ); | ||
262 | viewMenuView->setCheckable ( true ); | ||
138 | 263 | ||
139 | edit->insertItem(tr("Horizontal flip"), this, SLOT(hFlip()), 0); | 264 | //menubarView->insertItem( tr("View"),viewMenu ); |
140 | edit->insertItem(tr("Vertical flip"), this, SLOT(vFlip()), 0); | 265 | viewMenuView->insertItem(tr("Horizontal flip"), this, SLOT(hFlip()), 0); |
266 | viewMenuView->insertItem(tr("Vertical flip"), this, SLOT(vFlip()), 0); | ||
141 | 267 | ||
142 | stack = new QWidgetStack( this ); | 268 | stack = new QWidgetStack( this ); |
143 | stack->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); | 269 | stack->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); |
144 | setCentralWidget( stack ); | 270 | setCentralWidget( stack ); |
145 | 271 | ||
146 | imagePanel = new ImagePane( stack ); | 272 | |
273 | imagePanel = new ImagePane( stack ); | ||
147 | connect(imagePanel, SIGNAL(clicked()), this, SLOT(normalView())); | 274 | connect(imagePanel, SIGNAL(clicked()), this, SLOT(normalView())); |
148 | 275 | ||
149 | fileSelector = new FileSelector("image/*", stack, "fs"); | 276 | |
150 | fileSelector->setNewVisible(FALSE); | 277 | ImageFileSelector::CURRENT_VIEW cv; |
151 | fileSelector->setCloseVisible(FALSE); | 278 | if(showThumbView) |
279 | cv=ImageFileSelector::THUMBNAIL; | ||
280 | else | ||
281 | cv=ImageFileSelector::DETAILED; | ||
282 | |||
283 | qDebug("cv = %d",cv); | ||
284 | |||
285 | fileSelector = new ImageFileSelector( cv,stack, "fs"); | ||
286 | |||
287 | //switchThumbView(); | ||
288 | |||
289 | |||
290 | //fileSelector = new ImageFileSelector("image/*", stack, "fs"); | ||
291 | //fileSelector->setNewVisible(FALSE); | ||
292 | //fileSelector->setCloseVisible(FALSE); | ||
152 | connect( fileSelector, SIGNAL( closeMe() ), this, SLOT( closeFileSelector() ) ); | 293 | connect( fileSelector, SIGNAL( closeMe() ), this, SLOT( closeFileSelector() ) ); |
153 | connect( fileSelector, SIGNAL( fileSelected( const DocLnk &) ), this, SLOT( openFile( const DocLnk & ) ) ); | 294 | connect( fileSelector, SIGNAL( fileSelected( const DocLnk &) ), this, SLOT( openFile( const DocLnk & ) ) ); |
154 | 295 | ||
155 | toolBar = new QPEToolBar( this ); | 296 | iconToolBar = new QPEToolBar(this); |
156 | 297 | ||
157 | QAction *a; | 298 | QAction *a; |
158 | 299 | ||
159 | a = new QAction( tr( "Open" ), Resource::loadPixmap( "fileopen" ), QString::null, 0, this, 0 ); | 300 | a = new QAction( tr( "Open ..." ), Resource::loadPixmap( "fileopen" ), QString::null, 0, this, 0 ); |
160 | connect( a, SIGNAL( activated() ), this, SLOT( open() ) ); | 301 | connect( a, SIGNAL( activated() ), this, SLOT( open() ) ); |
161 | a->addTo( toolBar ); | 302 | a->addTo( fileMenuView); |
303 | a->addTo( iconToolBar ); | ||
162 | 304 | ||
163 | a = new QAction( tr( "Rotate 180" ), Resource::loadPixmap( "repeat" ), QString::null, 0, this, 0 ); | ||
164 | connect( a, SIGNAL( activated() ), this, SLOT( rot180() ) ); | ||
165 | a->addTo( toolBar ); | ||
166 | a->addTo( edit ); | ||
167 | 305 | ||
168 | a = new QAction( tr( "Rotate 90"), Resource::loadPixmap( "rotate90" ), QString::null, 0, this, 0); | 306 | a = new QAction( tr( "Rotate 90"), Resource::loadPixmap( "rotate90" ), QString::null, 0, this, 0); |
169 | connect( a, SIGNAL( activated() ), this, SLOT( rot90() ) ); | 307 | connect( a, SIGNAL( activated() ), this, SLOT( rot90() ) ); |
170 | a->addTo( toolBar ); | 308 | a->addTo( iconToolBar ); |
171 | a->addTo( edit ); | 309 | a->addTo( viewMenuView ); |
310 | |||
311 | a = new QAction( tr( "Rotate 180" ), Resource::loadPixmap( "repeat" ), QString::null, 0, this, 0 ); | ||
312 | connect( a, SIGNAL( activated() ), this, SLOT( rot180() ) ); | ||
313 | a->addTo( iconToolBar ); | ||
314 | a->addTo( viewMenuView ); | ||
315 | |||
316 | |||
317 | a = new QAction( tr( "Rotate 270"), Resource::loadPixmap( "rotate270" ), QString::null, 0, this, 0); | ||
318 | connect( a, SIGNAL( activated() ), this, SLOT( rot270() ) ); | ||
319 | //a->addTo( iconToolBar ); | ||
320 | a->addTo( viewMenuView ); | ||
321 | |||
322 | |||
323 | |||
324 | viewMenuView->insertSeparator(); | ||
325 | viewMenuView->insertItem(tr("Brightness ..."), this, SLOT(displayControlsDialog()), 0); | ||
326 | viewMenuView->insertItem(tr("Black And White"), this, SLOT(blackAndWhite()), 0,BLACKANDWHITE); | ||
327 | viewMenuView->insertSeparator(); | ||
328 | |||
329 | |||
330 | sss = new QAction( tr( "Scale to Screen"), Resource::loadPixmap( "scale" ), QString::null, 0, this, 0,true); | ||
331 | connect( sss, SIGNAL( activated() ), this, SLOT( switchSizeToScreen() ) ); | ||
332 | sss->addTo( iconToolBar ); | ||
333 | sss->addTo( viewMenuView ); | ||
334 | |||
335 | sss->setOn(isSized); | ||
336 | viewMenuView->insertSeparator(); | ||
337 | |||
172 | 338 | ||
173 | a = new QAction( tr( "Fullscreen" ), Resource::loadPixmap( "fullscreen" ), QString::null, 0, this, 0 ); | 339 | a = new QAction( tr( "Fullscreen" ), Resource::loadPixmap( "fullscreen" ), QString::null, 0, this, 0 ); |
174 | connect( a, SIGNAL( activated() ), this, SLOT( fullScreen() ) ); | 340 | connect( a, SIGNAL( activated() ), this, SLOT( fullScreen() ) ); |
175 | a->addTo( toolBar ); | 341 | a->addTo( iconToolBar ); |
176 | a->addTo( view); | 342 | a->addTo( viewMenuView); |
343 | |||
344 | switchToFileSelector(); | ||
177 | 345 | ||
178 | stack->raiseWidget( fileSelector ); | 346 | setMouseTracking( TRUE ); |
179 | 347 | ||
180 | setMouseTracking( TRUE ); | 348 | |
181 | } | 349 | } |
182 | 350 | ||
183 | ImageViewer::~ImageViewer() | 351 | ImageViewer::~ImageViewer() |
184 | { | 352 | { |
353 | Config cfg("Image Viewer"); | ||
354 | cfg.setGroup("Image Viewer"); | ||
355 | |||
356 | cfg.writeEntry("ShowThumbnails",(int)showThumbView); | ||
357 | cfg.writeEntry("SizeToScreen",(int)isSized); | ||
358 | |||
185 | delete imagePanel; // in case it is fullscreen | 359 | delete imagePanel; // in case it is fullscreen |
186 | } | 360 | } |
187 | 361 | ||
362 | void ImageViewer::switchSizeToScreen() | ||
363 | { | ||
364 | isSized=!isSized; | ||
365 | sss->setOn(isSized); | ||
366 | updateImage(); | ||
367 | } | ||
368 | |||
369 | void ImageViewer::updateImage() | ||
370 | { | ||
371 | if ( isSized ) | ||
372 | { | ||
373 | imagePanel->setPixmap(pmScaled); | ||
374 | } | ||
375 | else | ||
376 | { | ||
377 | imagePanel->setPixmap(pm); | ||
378 | } | ||
379 | } | ||
380 | |||
381 | void ImageViewer::switchThumbView() | ||
382 | { | ||
383 | |||
384 | showThumbView=!showThumbView; | ||
385 | viewMenuFile->setItemChecked ( SHOW_THUMBNAILS, showThumbView ); | ||
386 | fileSelector->switchView(); | ||
387 | |||
388 | } | ||
389 | |||
390 | void ImageViewer::switchToFileSelector() | ||
391 | { | ||
392 | stack->raiseWidget(fileSelector); | ||
393 | menuBar->clear(); | ||
394 | menuBar->insertItem( tr("File"), fileMenuFile ); | ||
395 | menuBar->insertItem( tr("View"), viewMenuFile ); | ||
396 | menuBar->insertItem( tr("Options"), optionsMenuFile ); | ||
397 | iconToolBar->hide(); | ||
398 | imagePanel->disable(); | ||
399 | |||
400 | } | ||
401 | |||
402 | void ImageViewer::switchToImageView() | ||
403 | { | ||
404 | stack->raiseWidget(imagePanel); | ||
405 | |||
406 | menuBar->clear(); | ||
407 | menuBar->insertItem( tr("File"), fileMenuView ); | ||
408 | menuBar->insertItem( tr("View"), viewMenuView ); | ||
409 | viewMenuView->setItemEnabled(BLACKANDWHITE,true); | ||
410 | iconToolBar->show(); | ||
411 | |||
412 | imagePanel->setPosition(0,0); | ||
413 | |||
414 | } | ||
415 | |||
416 | |||
188 | void ImageViewer::setDocument(const QString& fileref) | 417 | void ImageViewer::setDocument(const QString& fileref) |
189 | { | 418 | { |
190 | delayLoad = fileref; | 419 | delayLoad = fileref; |
191 | stack->raiseWidget(imagePanel); | 420 | switchToImageView(); |
192 | QTimer::singleShot( 0, this, SLOT(doDelayedLoad()) ); | 421 | QTimer::singleShot( 0, this, SLOT(doDelayedLoad()) ); |
193 | } | 422 | } |
194 | 423 | ||
195 | void ImageViewer::doDelayedLoad() | 424 | void ImageViewer::doDelayedLoad() |
196 | { | 425 | { |
197 | show(delayLoad); | 426 | show(delayLoad); |
198 | } | 427 | } |
199 | 428 | ||
200 | void ImageViewer::show() | 429 | void ImageViewer::show() |
201 | { | 430 | { |
202 | normalView(); | 431 | normalView(); |
203 | QMainWindow::show(); | 432 | QMainWindow::show(); |
204 | } | 433 | } |
205 | 434 | ||
206 | void ImageViewer::show(const QString& fileref) | 435 | void ImageViewer::show(const QString& fileref) |
207 | { | 436 | { |
208 | bFromDocView = TRUE; | 437 | bFromDocView = TRUE; |
209 | closeFileSelector(); | 438 | closeFileSelector(); |
210 | DocLnk link(fileref); | 439 | DocLnk link(fileref); |
211 | if ( link.isValid() ) { | 440 | if ( link.isValid() ) |
212 | openFile(link); | 441 | { |
213 | } else { | 442 | openFile(link); |
214 | filename = fileref; | 443 | } |
215 | updateCaption( fileref ); | 444 | else |
216 | loadImage( fileref ); | 445 | { |
446 | filename = fileref; | ||
447 | updateCaption( fileref ); | ||
448 | loadImage( fileref ); | ||
217 | } | 449 | } |
218 | } | 450 | } |
219 | 451 | ||
220 | void ImageViewer::openFile( const DocLnk &file ) | 452 | void ImageViewer::openFile( const DocLnk &file ) |
221 | { | 453 | { |
222 | closeFileSelector(); | 454 | closeFileSelector(); |
223 | DocLnk link(file); | 455 | DocLnk link(file); |
224 | updateCaption( link.name() ); | 456 | updateCaption( link.name() ); |
225 | loadImage( link.file() ); | 457 | loadImage( link.file() ); |
226 | } | 458 | } |
227 | 459 | ||
228 | void ImageViewer::open() | 460 | void ImageViewer::open() |
229 | { | 461 | { |
230 | stack->raiseWidget(fileSelector); | 462 | switchToFileSelector(); |
231 | } | 463 | } |
232 | 464 | ||
233 | void ImageViewer::closeFileSelector() | 465 | void ImageViewer::closeFileSelector() |
234 | { | 466 | { |
235 | stack->raiseWidget(imagePanel); | 467 | switchToImageView(); |
236 | } | 468 | } |
237 | 469 | ||
238 | void ImageViewer::updateCaption( QString name ) | 470 | void ImageViewer::updateCaption( QString name ) |
239 | { | 471 | { |
240 | int sep = name.findRev( '/' ); | 472 | int sep = name.findRev( '/' ); |
241 | if ( sep >= 0 ) | 473 | if ( sep >= 0 ) |
242 | name = name.mid( sep+1 ); | 474 | name = name.mid( sep+1 ); |
243 | setCaption( name + tr(" - Image Viewer") ); | 475 | setCaption( name + tr(" - Image Viewer") ); |
244 | } | 476 | } |
245 | 477 | ||
246 | /* | 478 | /* |
247 | This function loads an image from a file. | 479 | This function loads an image from a file. |
248 | */ | 480 | */ |
249 | 481 | ||
250 | void ImageViewer::loadImage( const char *fileName ) | 482 | void ImageViewer::loadImage( const char *fileName ) |
251 | { | 483 | { |
252 | filename = fileName; | 484 | filename = fileName; |
253 | if ( filename ) { | 485 | if ( filename ) |
254 | QApplication::setOverrideCursor( waitCursor ); // this might take time | 486 | { |
255 | imagePanel->statusLabel()->setText( tr("Loading image...") ); | 487 | QApplication::setOverrideCursor( waitCursor ); // this might take time |
256 | qApp->processEvents(); | 488 | //imagePanel->statusLabel()->setText( tr("Loading image...") ); |
257 | bool ok = image.load(filename, 0); | 489 | qApp->processEvents(); |
258 | pickx = -1; | 490 | bool ok = image.load(filename, 0); |
259 | clickx = -1; | 491 | if ( ok ) |
260 | if ( ok ) | 492 | { |
261 | ok = reconvertImage(); | 493 | ok = reconvertImage(); |
262 | if ( !ok ) { | 494 | updateImageInfo(filename); |
263 | pm.resize(0,0); // couldn't load image | 495 | } |
264 | update(); | 496 | if ( !ok ) |
265 | } | 497 | { |
266 | QApplication::restoreOverrideCursor();// restore original cursor | 498 | pm.resize(0,0); // couldn't load image |
267 | } | 499 | update(); |
268 | updateStatus(); | 500 | } |
269 | imagePanel->setPixmap( pmScaled ); | 501 | QApplication::restoreOverrideCursor(); // restore original cursor |
270 | stack->raiseWidget(imagePanel); | 502 | } |
503 | switchToImageView(); | ||
504 | updateImage(); | ||
505 | |||
271 | } | 506 | } |
272 | 507 | ||
273 | bool ImageViewer::loadSelected() | 508 | bool ImageViewer::loadSelected() |
274 | { | 509 | { |
275 | bool ok = false; | 510 | bool ok = false; |
276 | if ( stack->visibleWidget() == fileSelector ) { | 511 | if ( stack->visibleWidget() == fileSelector ) |
277 | const DocLnk *link = fileSelector->selected(); | 512 | { |
278 | if ( link ) { | 513 | const DocLnk *link = fileSelector->selected(); |
279 | if ( link->file() != filename ) { | 514 | if ( link ) |
280 | updateCaption( link->name() ); | 515 | { |
281 | filename = link->file(); | 516 | if ( link->file() != filename ) |
282 | imagePanel->statusLabel()->setText( tr("Loading image...") ); | 517 | { |
283 | qApp->processEvents(); | 518 | updateCaption( link->name() ); |
284 | ok = image.load(filename, 0); | 519 | filename = link->file(); |
285 | if ( ok ) | 520 | qApp->processEvents(); |
286 | ok = reconvertImage(); | 521 | ok = image.load(filename, 0); |
287 | if ( !ok ) | 522 | if ( ok ) |
288 | pm.resize(0,0); | 523 | { |
289 | } | 524 | updateImageInfo(filename); |
290 | } | 525 | ok = reconvertImage(); |
291 | } | 526 | } |
292 | if ( !image.isNull() ) { | 527 | if ( !ok ) |
293 | ok = true; | 528 | pm.resize(0,0); |
294 | closeFileSelector(); | 529 | } |
530 | } | ||
531 | } | ||
532 | if ( !image.isNull() ) | ||
533 | { | ||
534 | ok = true; | ||
535 | closeFileSelector(); | ||
295 | } | 536 | } |
296 | 537 | ||
297 | return ok; | 538 | return ok; |
298 | } | 539 | } |
299 | 540 | ||
300 | bool ImageViewer::reconvertImage() | 541 | bool ImageViewer::reconvertImage() |
301 | { | 542 | { |
302 | bool success = FALSE; | 543 | bool success = FALSE; |
303 | 544 | ||
304 | if ( image.isNull() ) return FALSE; | 545 | if ( image.isNull() ) return FALSE; |
305 | 546 | ||
306 | QApplication::setOverrideCursor( waitCursor ); // this might take time | 547 | QApplication::setOverrideCursor( waitCursor ); // this might take time |
307 | if ( pm.convertFromImage(image /*, conversion_flags */ ) ) | 548 | if ( pm.convertFromImage(image /*, conversion_flags */ ) ) |
308 | { | 549 | { |
309 | pmScaled = QPixmap(); | 550 | pmScaled = QPixmap(); |
310 | scale(); | 551 | scale(); |
311 | success = TRUE; // load successful | 552 | success = TRUE; // load successful |
312 | } else { | 553 | } |
313 | pm.resize(0,0); // couldn't load image | 554 | else |
555 | { | ||
556 | pm.resize(0,0); // couldn't load image | ||
314 | } | 557 | } |
315 | QApplication::restoreOverrideCursor();// restore original cursor | 558 | QApplication::restoreOverrideCursor(); // restore original cursor |
316 | 559 | ||
317 | return success; // TRUE if loaded OK | 560 | return success; // TRUE if loaded OK |
318 | } | 561 | } |
319 | 562 | ||
320 | 563 | ||
321 | int ImageViewer::calcHeight() | 564 | int ImageViewer::calcHeight() |
322 | { | 565 | { |
323 | if ( !isFullScreen) | 566 | if ( !isFullScreen ) |
324 | return height() - menubar->heightForWidth( width() ) | 567 | return imagePanel->paneHeight(); |
325 | - imagePanel->statusLabel()->height(); | ||
326 | else | 568 | else |
327 | return qApp->desktop()->height(); | 569 | return qApp->desktop()->height(); |
328 | } | 570 | } |
329 | /* | 571 | /* |
330 | This functions scales the pixmap in the member variable "pm" to fit the | 572 | This functions scales the pixmap in the member variable "pm" to fit the |
331 | widget size and puts the resulting pixmap in the member variable "pmScaled". | 573 | widget size and puts the resulting pixmap in the member variable "pmScaled". |
332 | */ | 574 | */ |
333 | |||
334 | void ImageViewer::scale() | 575 | void ImageViewer::scale() |
335 | { | 576 | { |
336 | int h = calcHeight(); | 577 | int h = calcHeight(); |
337 | if ( image.isNull() ) return; | 578 | if ( image.isNull() ) return; |
338 | 579 | ||
339 | QApplication::setOverrideCursor( waitCursor ); // this might take time | 580 | QApplication::setOverrideCursor( waitCursor ); // this might take time |
340 | if ( width() == pm.width() && h == pm.height() ) { // no need to scale if widget | 581 | if ( imagePanel->paneWidth() == pm.width() && h == pm.height() ) |
341 | pmScaled = pm; // size equals pixmap size | 582 | { // no need to scale if widget |
342 | } else { | 583 | pmScaled = pm; // size equals pixmap size |
343 | double hs = (double)h / (double)image.height(); | 584 | } |
344 | double ws = (double)width() / (double)image.width(); | 585 | else |
345 | double scaleFactor = (hs > ws) ? ws : hs; | 586 | { |
346 | int smoothW = (int)(scaleFactor * image.width()); | 587 | double hs = (double)h / (double)image.height(); |
347 | int smoothH = (int)(scaleFactor * image.height()); | 588 | double ws = (double)imagePanel->paneWidth() / (double)image.width(); |
589 | double scaleFactor = (hs > ws) ? ws : hs; | ||
590 | int smoothW = (int)(scaleFactor * image.width()); | ||
591 | int smoothH = (int)(scaleFactor * image.height()); | ||
348 | 592 | ||
349 | pmScaled.convertFromImage( image.smoothScale( smoothW, smoothH ) /*, conversion_flags */ ); | 593 | pmScaled.convertFromImage( image.smoothScale( smoothW, smoothH ) /*, conversion_flags */ ); |
350 | } | 594 | } |
351 | QApplication::restoreOverrideCursor();// restore original cursor | 595 | QApplication::restoreOverrideCursor(); // restore original cursor |
352 | } | 596 | } |
353 | 597 | ||
354 | /* | 598 | /* |
355 | The resize event handler, if a valid pixmap was loaded it will call | 599 | The resize event handler, if a valid pixmap was loaded it will call |
356 | scale() to fit the pixmap to the new widget size. | 600 | scale() to fit the pixmap to the new widget size. |
357 | */ | 601 | */ |
358 | 602 | ||
359 | void ImageViewer::resizeEvent( QResizeEvent * ) | 603 | void ImageViewer::resizeEvent( QResizeEvent * ) |
360 | { | 604 | { |
361 | imagePanel->statusLabel()->setGeometry(0, height() - imagePanel->statusLabel()->height(), | ||
362 | width(), imagePanel->statusLabel()->height()); | ||
363 | 605 | ||
364 | if ( pm.size() == QSize( 0, 0 ) ) // we couldn't load the image | 606 | if ( pm.size() == QSize( 0, 0 ) ) // we couldn't load the image |
365 | return; | 607 | return; |
366 | 608 | ||
367 | int h = calcHeight(); | 609 | int h = calcHeight(); |
368 | 610 | ||
369 | if ( width() != pmScaled.width() || h != pmScaled.height()) | 611 | if ( imagePanel->paneWidth() != pmScaled.width() || h != pmScaled.height() ) |
370 | { // if new size, | 612 | { // if new size, |
371 | scale(); // scale pmScaled to window | 613 | scale(); // scale pmScaled to window |
372 | updateStatus(); | ||
373 | } | 614 | } |
374 | if ( image.hasAlphaBuffer() ) | 615 | if ( image.hasAlphaBuffer() ) |
375 | erase(); | 616 | erase(); |
376 | } | 617 | } |
377 | 618 | ||
378 | void ImageViewer::convertEvent( QMouseEvent* e, int& x, int& y) | ||
379 | { | ||
380 | if ( pm.size() != QSize( 0, 0 ) ) { | ||
381 | int h = height() - menubar->heightForWidth( width() ) - imagePanel->statusLabel()->height(); | ||
382 | int nx = e->x() * image.width() / width(); | ||
383 | int ny = (e->y()-menubar->heightForWidth( width() )) * image.height() / h; | ||
384 | if (nx != x || ny != y ) { | ||
385 | x = nx; | ||
386 | y = ny; | ||
387 | updateStatus(); | ||
388 | } | ||
389 | } | ||
390 | } | ||
391 | 619 | ||
392 | void ImageViewer::mousePressEvent( QMouseEvent *e ) | 620 | void ImageViewer::hFlip() |
393 | { | 621 | { |
394 | convertEvent(e, clickx, clicky); | 622 | setImage(image.mirror(TRUE,FALSE)); |
395 | } | 623 | } |
396 | 624 | ||
397 | void ImageViewer::mouseMoveEvent( QMouseEvent *e ) | 625 | void ImageViewer::vFlip() |
398 | { | 626 | { |
399 | convertEvent( e, pickx, picky ); | 627 | setImage(image.mirror(FALSE,TRUE)); |
400 | } | 628 | } |
401 | 629 | ||
402 | void ImageViewer::hFlip() | 630 | void ImageViewer::rot180() |
403 | { | 631 | { |
404 | if ( loadSelected() ) | 632 | |
405 | setImage(image.mirror(TRUE,FALSE)); | 633 | setImage(image.mirror(TRUE,TRUE)); |
406 | } | 634 | } |
407 | 635 | ||
408 | void ImageViewer::vFlip() | 636 | void ImageViewer::rot90() |
409 | { | 637 | { |
410 | if ( loadSelected() ) | 638 | QImage oldimage; |
411 | setImage(image.mirror(FALSE,TRUE)); | 639 | oldimage = image.convertDepth(32); |
412 | } | 640 | setImage(rotate(oldimage,Rotate90)); |
413 | 641 | ||
414 | void ImageViewer::rot180() | 642 | } |
643 | void ImageViewer::rot270() | ||
415 | { | 644 | { |
416 | if ( loadSelected() ) | 645 | |
417 | setImage(image.mirror(TRUE,TRUE)); | 646 | QImage oldimage; |
647 | oldimage = image.convertDepth(32); | ||
648 | setImage(rotate(oldimage,Rotate270)); | ||
649 | |||
418 | } | 650 | } |
419 | 651 | ||
420 | void ImageViewer::rot90() | 652 | void ImageViewer::blackAndWhite() |
421 | { | 653 | { |
422 | if ( loadSelected() ) { | ||
423 | QImage oldimage, newimage; | ||
424 | uchar *oldbits, *newbits; | ||
425 | int i, j, p; | ||
426 | int w, h; | ||
427 | 654 | ||
428 | oldimage = image.convertDepth(32); | 655 | viewMenuView->setItemEnabled(BLACKANDWHITE,false); |
429 | w = oldimage.height(); | 656 | setImage(toGray(image,false)); |
430 | h = oldimage.width(); | 657 | |
431 | newimage = QImage( w, h, 32); | ||
432 | 658 | ||
433 | oldbits = oldimage.bits(); | 659 | } |
434 | newbits = newimage.bits(); | 660 | |
661 | void ImageViewer::displayControlsDialog() | ||
662 | { | ||
663 | int w=80; | ||
664 | int h=w; | ||
665 | QImage small; | ||
435 | 666 | ||
436 | for (i=0; i < w ; i++) | 667 | if ( image.width()<w ||image.height()<h ) |
437 | for (j=0; j < h; j++) | 668 | small=image.smoothScale(w,h); |
438 | for (p = 0 ; p < 4 ; p++) | 669 | else |
439 | newbits[(j * w + i) * 4 + p] = oldbits[ ((i + 1) * h - j ) * 4 + p]; | 670 | small=image.copy(0,0,w,h); |
440 | 671 | ||
441 | setImage(newimage); | 672 | int newB=0; |
673 | ControlsDialog *dlg=new ControlsDialog("Image Viewer",small,&newB,this); | ||
674 | dlg->exec(); | ||
675 | if ( newB ) | ||
676 | { | ||
677 | intensity(image,(float)newB/100); | ||
678 | setImage(image); | ||
442 | } | 679 | } |
680 | |||
443 | } | 681 | } |
444 | 682 | ||
445 | 683 | ||
684 | void ImageViewer::displayInfoDialog() | ||
685 | { | ||
686 | |||
687 | QStringList ls; | ||
688 | |||
689 | for ( int i=0;i<LAST;i++ ) | ||
690 | ls.append(imageInfo[i]); | ||
446 | 691 | ||
692 | InfoDialog::displayInfo("Image Viewer",ls,this); | ||
693 | } | ||
447 | void ImageViewer::normalView() | 694 | void ImageViewer::normalView() |
448 | { | 695 | { |
449 | if ( !imagePanel->parentWidget() ) { | 696 | if ( !imagePanel->parentWidget() ) |
450 | isFullScreen = FALSE; | 697 | { |
451 | stack->addWidget( imagePanel, 1 ); | 698 | |
452 | //imagePanel->reparent(stack,0,QPoint(0,0),FALSE); | 699 | isFullScreen = FALSE; |
453 | //imagePanel->resize(width(), calcHeight()); | 700 | stack->addWidget( imagePanel, 1 ); |
454 | scale(); | 701 | switchToImageView(); |
455 | updateStatus(); | 702 | if ( isSized ) |
456 | imagePanel->setPixmap( pmScaled ); | 703 | scale(); |
457 | imagePanel->showStatus(); | 704 | |
458 | //imagePanel->show(); | 705 | updateImage(); |
459 | stack->raiseWidget( imagePanel ); | 706 | |
460 | } | 707 | } |
461 | } | 708 | } |
462 | 709 | ||
463 | void ImageViewer::fullScreen() | 710 | void ImageViewer::fullScreen() |
464 | { | 711 | { |
465 | // Full-screen and rotation options | 712 | // Full-screen option |
466 | // contributed by Robert Wittams <robert@wittams.com> | 713 | // contributed by Robert Wittams <robert@wittams.com> |
467 | 714 | if ( imagePanel->parentWidget() && loadSelected() ) | |
468 | if ( imagePanel->parentWidget() && loadSelected() ) { | 715 | { |
469 | isFullScreen = TRUE; | 716 | isFullScreen = TRUE; |
470 | imagePanel->reparent(0,QPoint(0,0)); | 717 | imagePanel->reparent(0,QPoint(0,0)); |
471 | imagePanel->resize(qApp->desktop()->width(), qApp->desktop()->height()); | 718 | imagePanel->resize(qApp->desktop()->width(), qApp->desktop()->height()); |
472 | 719 | ||
473 | scale(); | 720 | if ( isSized ) |
474 | updateStatus(); | 721 | scale(); |
475 | imagePanel->hideStatus(); | 722 | updateImage(); |
476 | imagePanel->setPixmap( pmScaled ); | 723 | imagePanel->showFullScreen(); |
477 | imagePanel->showFullScreen(); | ||
478 | } | 724 | } |
479 | } | 725 | } |
480 | 726 | ||
481 | void ImageViewer::setImage(const QImage& newimage) | 727 | void ImageViewer::setImage(const QImage& newimage) |
482 | { | 728 | { |
483 | image = newimage; | 729 | image = newimage; |
484 | pickx = -1; | ||
485 | clickx = -1; | ||
486 | reconvertImage(); | 730 | reconvertImage(); |
487 | imagePanel->setPixmap( pmScaled ); | 731 | updateImage(); |
488 | updateStatus(); | 732 | } |
489 | } | 733 | |
490 | 734 | void ImageViewer::updateImageInfo(QString &filePath) | |
491 | void ImageViewer::updateStatus() | 735 | { |
492 | { | 736 | |
493 | if ( pm.size() == QSize( 0, 0 ) ) { | 737 | for ( int i=0;i<LAST;i++ ) |
494 | if ( filename ) | 738 | { |
495 | imagePanel->statusLabel()->setText( tr("Could not load image") ); | 739 | imageInfo[i]=""; |
496 | else | 740 | } |
497 | imagePanel->statusLabel()->setText( tr("No image - select Open from File menu.") ); | 741 | |
498 | } else { | 742 | imageInfo[FORMAT]=QImage::imageFormat (filePath ); |
499 | QString message("%1x%2"); | 743 | QFileInfo fi(filePath); |
500 | message = message.arg(image.width()).arg(image.height()); | 744 | imageInfo[PATH]=fi.fileName(); |
501 | if ( pm.size() != pmScaled.size() ) | 745 | imageInfo[FILE_SIZE]=QString::number(fi.size())+" (bytes)"; |
502 | message += QString(" [%1x%2]").arg(pmScaled.width()).arg(pmScaled.height()); | 746 | QString message("%1x%2"); |
503 | if (image.valid(pickx,picky)) { | 747 | imageInfo[SIZE]=QString("%1x%2"); |
504 | QString moremsg; | 748 | imageInfo[SIZE]=imageInfo[SIZE].arg(image.width()).arg(image.height()); |
505 | moremsg.sprintf("(%d,%d)=#%0*x ", | 749 | if ( image.numColors() > 0 ) |
506 | pickx, picky, | 750 | { |
507 | image.hasAlphaBuffer() ? 8 : 6, | 751 | imageInfo[COLORS]=tr("%1 colors").arg(image.numColors()); |
508 | image.pixel(pickx,picky)); | 752 | } |
509 | message += moremsg; | 753 | else if ( image.depth() >= 16 ) |
510 | } | 754 | { |
511 | if ( image.numColors() > 0 ) { | 755 | imageInfo[COLORS]=tr(" True color"); |
512 | if (image.valid(pickx,picky)) { | 756 | } |
513 | message += tr(", %1/%2 colors") | 757 | if ( image.hasAlphaBuffer() ) |
514 | .arg(image.pixelIndex(pickx,picky)) | 758 | { |
515 | .arg(image.numColors()); | 759 | if ( image.depth() == 8 ) |
516 | } else { | 760 | { |
517 | message += tr(", %1 colors").arg(image.numColors()); | 761 | int i; |
518 | } | 762 | bool alpha[256]; |
519 | } else if ( image.depth() >= 16 ) { | 763 | int nalpha=0; |
520 | message += tr(" True color"); | 764 | |
521 | } | 765 | for ( i=0; i<256; i++ ) |
522 | if ( image.hasAlphaBuffer() ) { | 766 | alpha[i] = FALSE; |
523 | if ( image.depth() == 8 ) { | 767 | |
524 | int i; | 768 | for ( i=0; i<image.numColors(); i++ ) |
525 | bool alpha[256]; | 769 | { |
526 | int nalpha=0; | 770 | int alevel = image.color(i) >> 24; |
527 | 771 | if ( !alpha[alevel] ) | |
528 | for (i=0; i<256; i++) | 772 | { |
529 | alpha[i] = FALSE; | 773 | alpha[alevel] = TRUE; |
530 | 774 | nalpha++; | |
531 | for (i=0; i<image.numColors(); i++) { | 775 | } |
532 | int alevel = image.color(i) >> 24; | 776 | } |
533 | if (!alpha[alevel]) { | 777 | imageInfo[ALPHA]=tr("%1 alpha levels").arg(nalpha); |
534 | alpha[alevel] = TRUE; | 778 | } |
535 | nalpha++; | 779 | else |
536 | } | 780 | { |
537 | } | 781 | imageInfo[ALPHA]=tr("8-bit alpha channel"); |
538 | message += tr(", %1 alpha levels").arg(nalpha); | 782 | } |
539 | } else { | ||
540 | // Too many pixels to bother counting. | ||
541 | message += tr(", 8-bit alpha channel"); | ||
542 | } | ||
543 | } | ||
544 | imagePanel->statusLabel()->setText(message); | ||
545 | } | 783 | } |
784 | |||
546 | } | 785 | } |
547 | 786 | ||
548 | void ImageViewer::closeEvent( QCloseEvent *e ) | 787 | void ImageViewer::closeEvent( QCloseEvent *e ) |
549 | { | 788 | { |
550 | if ( stack->visibleWidget() == imagePanel && !bFromDocView ) { | 789 | if ( stack->visibleWidget() == imagePanel && !bFromDocView ) |
551 | e->ignore(); | 790 | { |
552 | open(); | 791 | e->ignore(); |
553 | } else { | 792 | open(); |
554 | bFromDocView = FALSE; | 793 | } |
555 | e->accept(); | 794 | else |
795 | { | ||
796 | bFromDocView = FALSE; | ||
797 | e->accept(); | ||
798 | } | ||
799 | } | ||
800 | |||
801 | // Intensity,toGray and rotate code courtesy of KDE project. | ||
802 | |||
803 | |||
804 | QImage& ImageViewer::intensity(QImage &image, float percent) | ||
805 | { | ||
806 | |||
807 | int segColors = image.depth() > 8 ? 256 : image.numColors(); | ||
808 | unsigned char *segTbl = new unsigned char[segColors]; | ||
809 | int pixels = image.depth() > 8 ? image.width()*image.height() : | ||
810 | image.numColors(); | ||
811 | unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() : | ||
812 | (unsigned int *)image.colorTable(); | ||
813 | |||
814 | bool brighten = (percent >= 0); | ||
815 | if ( percent < 0 ) | ||
816 | percent = -percent; | ||
817 | |||
818 | if ( brighten ) | ||
819 | { // keep overflow check out of loops | ||
820 | for ( int i=0; i < segColors; ++i ) | ||
821 | { | ||
822 | int tmp = (int)(i*percent); | ||
823 | if ( tmp > 255 ) | ||
824 | tmp = 255; | ||
825 | segTbl[i] = tmp; | ||
826 | } | ||
827 | } | ||
828 | else | ||
829 | { | ||
830 | for ( int i=0; i < segColors; ++i ) | ||
831 | { | ||
832 | int tmp = (int)(i*percent); | ||
833 | if ( tmp < 0 ) | ||
834 | tmp = 0; | ||
835 | segTbl[i] = tmp; | ||
836 | } | ||
837 | } | ||
838 | |||
839 | if ( brighten ) | ||
840 | { // same here | ||
841 | for ( int i=0; i < pixels; ++i ) | ||
842 | { | ||
843 | int r = qRed(data[i]); | ||
844 | int g = qGreen(data[i]); | ||
845 | int b = qBlue(data[i]); | ||
846 | int a = qAlpha(data[i]); | ||
847 | r = r + segTbl[r] > 255 ? 255 : r + segTbl[r]; | ||
848 | g = g + segTbl[g] > 255 ? 255 : g + segTbl[g]; | ||
849 | b = b + segTbl[b] > 255 ? 255 : b + segTbl[b]; | ||
850 | data[i] = qRgba(r, g, b,a); | ||
851 | } | ||
852 | } | ||
853 | else | ||
854 | { | ||
855 | for ( int i=0; i < pixels; ++i ) | ||
856 | { | ||
857 | int r = qRed(data[i]); | ||
858 | int g = qGreen(data[i]); | ||
859 | int b = qBlue(data[i]); | ||
860 | int a = qAlpha(data[i]); | ||
861 | r = r - segTbl[r] < 0 ? 0 : r - segTbl[r]; | ||
862 | g = g - segTbl[g] < 0 ? 0 : g - segTbl[g]; | ||
863 | b = b - segTbl[b] < 0 ? 0 : b - segTbl[b]; | ||
864 | data[i] = qRgba(r, g, b, a); | ||
865 | } | ||
866 | } | ||
867 | delete [] segTbl; | ||
868 | |||
869 | return image; | ||
870 | } | ||
871 | |||
872 | QImage& ImageViewer::toGray(QImage &img, bool fast) | ||
873 | { | ||
874 | if ( img.width() == 0 || img.height() == 0 ) | ||
875 | return img; | ||
876 | |||
877 | if ( fast ) | ||
878 | { | ||
879 | if ( img.depth() == 32 ) | ||
880 | { | ||
881 | register uchar * r(img.bits()); | ||
882 | register uchar * g(img.bits() + 1); | ||
883 | register uchar * b(img.bits() + 2); | ||
884 | |||
885 | uchar * end(img.bits() + img.numBytes()); | ||
886 | |||
887 | while ( r != end ) | ||
888 | { | ||
889 | |||
890 | *r = *g = *b = (((*r + *g) >> 1) + *b) >> 1; // (r + b + g) / 3 | ||
891 | |||
892 | r += 4; | ||
893 | g += 4; | ||
894 | b += 4; | ||
895 | } | ||
896 | } | ||
897 | else | ||
898 | { | ||
899 | for ( int i = 0; i < img.numColors(); i++ ) | ||
900 | { | ||
901 | register uint r = qRed(img.color(i)); | ||
902 | register uint g = qGreen(img.color(i)); | ||
903 | register uint b = qBlue(img.color(i)); | ||
904 | |||
905 | register uint gray = (((r + g) >> 1) + b) >> 1; | ||
906 | img.setColor(i, qRgba(gray, gray, gray, qAlpha(img.color(i)))); | ||
907 | } | ||
908 | } | ||
909 | } | ||
910 | else | ||
911 | { | ||
912 | int pixels = img.depth() > 8 ? img.width()*img.height() : | ||
913 | img.numColors(); | ||
914 | unsigned int *data = img.depth() > 8 ? (unsigned int *)img.bits() : | ||
915 | (unsigned int *)img.colorTable(); | ||
916 | int val, i; | ||
917 | for ( i=0; i < pixels; ++i ) | ||
918 | { | ||
919 | val = qGray(data[i]); | ||
920 | data[i] = qRgba(val, val, val, qAlpha(data[i])); | ||
921 | } | ||
922 | } | ||
923 | return img; | ||
924 | } | ||
925 | |||
926 | |||
927 | QImage ImageViewer::rotate(QImage &img, RotateDirection r) | ||
928 | { | ||
929 | QImage dest; | ||
930 | int x, y; | ||
931 | if ( img.depth() > 8 ) | ||
932 | { | ||
933 | unsigned int *srcData, *destData; | ||
934 | switch ( r ) | ||
935 | { | ||
936 | case Rotate90: | ||
937 | dest.create(img.height(), img.width(), img.depth()); | ||
938 | for ( y=0; y < img.height(); ++y ) | ||
939 | { | ||
940 | srcData = (unsigned int *)img.scanLine(y); | ||
941 | for ( x=0; x < img.width(); ++x ) | ||
942 | { | ||
943 | destData = (unsigned int *)dest.scanLine(x); | ||
944 | destData[img.height()-y-1] = srcData[x]; | ||
945 | } | ||
946 | } | ||
947 | break; | ||
948 | case Rotate180: | ||
949 | dest.create(img.width(), img.height(), img.depth()); | ||
950 | for ( y=0; y < img.height(); ++y ) | ||
951 | { | ||
952 | srcData = (unsigned int *)img.scanLine(y); | ||
953 | destData = (unsigned int *)dest.scanLine(img.height()-y-1); | ||
954 | for ( x=0; x < img.width(); ++x ) | ||
955 | destData[img.width()-x-1] = srcData[x]; | ||
956 | } | ||
957 | break; | ||
958 | case Rotate270: | ||
959 | dest.create(img.height(), img.width(), img.depth()); | ||
960 | for ( y=0; y < img.height(); ++y ) | ||
961 | { | ||
962 | srcData = (unsigned int *)img.scanLine(y); | ||
963 | for ( x=0; x < img.width(); ++x ) | ||
964 | { | ||
965 | destData = (unsigned int *)dest.scanLine(img.width()-x-1); | ||
966 | destData[y] = srcData[x]; | ||
967 | } | ||
968 | } | ||
969 | break; | ||
970 | default: | ||
971 | dest = img; | ||
972 | break; | ||
973 | } | ||
974 | } | ||
975 | else | ||
976 | { | ||
977 | unsigned char *srcData, *destData; | ||
978 | unsigned int *srcTable, *destTable; | ||
979 | switch ( r ) | ||
980 | { | ||
981 | case Rotate90: | ||
982 | dest.create(img.height(), img.width(), img.depth()); | ||
983 | dest.setNumColors(img.numColors()); | ||
984 | srcTable = (unsigned int *)img.colorTable(); | ||
985 | destTable = (unsigned int *)dest.colorTable(); | ||
986 | for ( x=0; x < img.numColors(); ++x ) | ||
987 | destTable[x] = srcTable[x]; | ||
988 | for ( y=0; y < img.height(); ++y ) | ||
989 | { | ||
990 | srcData = (unsigned char *)img.scanLine(y); | ||
991 | for ( x=0; x < img.width(); ++x ) | ||
992 | { | ||
993 | destData = (unsigned char *)dest.scanLine(x); | ||
994 | destData[img.height()-y-1] = srcData[x]; | ||
995 | } | ||
996 | } | ||
997 | break; | ||
998 | case Rotate180: | ||
999 | dest.create(img.width(), img.height(), img.depth()); | ||
1000 | dest.setNumColors(img.numColors()); | ||
1001 | srcTable = (unsigned int *)img.colorTable(); | ||
1002 | destTable = (unsigned int *)dest.colorTable(); | ||
1003 | for ( x=0; x < img.numColors(); ++x ) | ||
1004 | destTable[x] = srcTable[x]; | ||
1005 | for ( y=0; y < img.height(); ++y ) | ||
1006 | { | ||
1007 | srcData = (unsigned char *)img.scanLine(y); | ||
1008 | destData = (unsigned char *)dest.scanLine(img.height()-y-1); | ||
1009 | for ( x=0; x < img.width(); ++x ) | ||
1010 | destData[img.width()-x-1] = srcData[x]; | ||
1011 | } | ||
1012 | break; | ||
1013 | case Rotate270: | ||
1014 | dest.create(img.height(), img.width(), img.depth()); | ||
1015 | dest.setNumColors(img.numColors()); | ||
1016 | srcTable = (unsigned int *)img.colorTable(); | ||
1017 | destTable = (unsigned int *)dest.colorTable(); | ||
1018 | for ( x=0; x < img.numColors(); ++x ) | ||
1019 | destTable[x] = srcTable[x]; | ||
1020 | for ( y=0; y < img.height(); ++y ) | ||
1021 | { | ||
1022 | srcData = (unsigned char *)img.scanLine(y); | ||
1023 | for ( x=0; x < img.width(); ++x ) | ||
1024 | { | ||
1025 | destData = (unsigned char *)dest.scanLine(img.width()-x-1); | ||
1026 | destData[y] = srcData[x]; | ||
1027 | } | ||
1028 | } | ||
1029 | break; | ||
1030 | default: | ||
1031 | dest = img; | ||
1032 | break; | ||
1033 | } | ||
1034 | |||
556 | } | 1035 | } |
1036 | return (dest); | ||
1037 | |||
1038 | |||
557 | } | 1039 | } |
1040 | |||
1041 | |||
1042 | |||
1043 | |||
1044 | |||