8 """ |
8 """ |
9 |
9 |
10 from __future__ import unicode_literals # __IGNORE_WARNING__ |
10 from __future__ import unicode_literals # __IGNORE_WARNING__ |
11 |
11 |
12 from PyQt4.QtCore import pyqtSignal, Qt, QPoint, QRect, QSize |
12 from PyQt4.QtCore import pyqtSignal, Qt, QPoint, QRect, QSize |
13 from PyQt4.QtGui import QUndoCommand, QImage, QWidget, QColor, QPixmap, QSizePolicy, \ |
13 from PyQt4.QtGui import QUndoCommand, QImage, QWidget, QColor, QPixmap, \ |
14 QUndoStack, qRgba, QPainter, QApplication, QCursor, QBrush, QDialog, qGray, qAlpha |
14 QSizePolicy, QUndoStack, qRgba, QPainter, QApplication, QCursor, \ |
|
15 QBrush, QDialog, qGray, qAlpha |
15 |
16 |
16 from E5Gui import E5MessageBox |
17 from E5Gui import E5MessageBox |
17 |
18 |
18 from .cursors import cursors_rc # __IGNORE_WARNING__ |
19 from .cursors import cursors_rc # __IGNORE_WARNING__ |
19 |
20 |
63 """ |
65 """ |
64 Class implementing the icon editor grid. |
66 Class implementing the icon editor grid. |
65 |
67 |
66 @signal canRedoChanged(bool) emitted after the redo status has changed |
68 @signal canRedoChanged(bool) emitted after the redo status has changed |
67 @signal canUndoChanged(bool) emitted after the undo status has changed |
69 @signal canUndoChanged(bool) emitted after the undo status has changed |
68 @signal clipboardImageAvailable(bool) emitted to signal the availability of an |
70 @signal clipboardImageAvailable(bool) emitted to signal the availability |
69 image to be pasted |
71 of an image to be pasted |
70 @signal colorChanged(QColor) emitted after the drawing color was changed |
72 @signal colorChanged(QColor) emitted after the drawing color was changed |
71 @signal imageChanged(bool) emitted after the image was modified |
73 @signal imageChanged(bool) emitted after the image was modified |
72 @signal positionChanged(int, int) emitted after the cursor poition was changed |
74 @signal positionChanged(int, int) emitted after the cursor poition was |
|
75 changed |
73 @signal previewChanged(QPixmap) emitted to signal a new preview pixmap |
76 @signal previewChanged(QPixmap) emitted to signal a new preview pixmap |
74 @signal selectionAvailable(bool) emitted to signal a change of the selection |
77 @signal selectionAvailable(bool) emitted to signal a change of the |
|
78 selection |
75 @signal sizeChanged(int, int) emitted after the size has been changed |
79 @signal sizeChanged(int, int) emitted after the size has been changed |
76 @signal zoomChanged(int) emitted to signal a change of the zoom value |
80 @signal zoomChanged(int) emitted to signal a change of the zoom value |
77 """ |
81 """ |
78 canRedoChanged = pyqtSignal(bool) |
82 canRedoChanged = pyqtSignal(bool) |
79 canUndoChanged = pyqtSignal(bool) |
83 canUndoChanged = pyqtSignal(bool) |
192 pix.setMask(mask) |
196 pix.setMask(mask) |
193 self.__rubberCursor = QCursor(pix, 1, 16) |
197 self.__rubberCursor = QCursor(pix, 1, 16) |
194 |
198 |
195 def __initUndoTexts(self): |
199 def __initUndoTexts(self): |
196 """ |
200 """ |
197 Private method to initialize texts to be associated with undo commands for |
201 Private method to initialize texts to be associated with undo commands |
198 the various drawing tools. |
202 for the various drawing tools. |
199 """ |
203 """ |
200 self.__undoTexts = { |
204 self.__undoTexts = { |
201 self.Pencil: self.trUtf8("Set Pixel"), |
205 self.Pencil: self.trUtf8("Set Pixel"), |
202 self.Rubber: self.trUtf8("Erase Pixel"), |
206 self.Rubber: self.trUtf8("Erase Pixel"), |
203 self.Line: self.trUtf8("Draw Line"), |
207 self.Line: self.trUtf8("Draw Line"), |
221 def setDirty(self, dirty, setCleanState=False): |
225 def setDirty(self, dirty, setCleanState=False): |
222 """ |
226 """ |
223 Public slot to set the dirty flag. |
227 Public slot to set the dirty flag. |
224 |
228 |
225 @param dirty flag indicating the new modification status (boolean) |
229 @param dirty flag indicating the new modification status (boolean) |
226 @param setCleanState flag indicating to set the undo stack to clean (boolean) |
230 @param setCleanState flag indicating to set the undo stack to clean |
|
231 (boolean) |
227 """ |
232 """ |
228 self.__dirty = dirty |
233 self.__dirty = dirty |
229 self.imageChanged.emit(dirty) |
234 self.imageChanged.emit(dirty) |
230 |
235 |
231 if not dirty and setCleanState: |
236 if not dirty and setCleanState: |
288 if self.__curTool in [self.RectangleSelection, self.CircleSelection]: |
293 if self.__curTool in [self.RectangleSelection, self.CircleSelection]: |
289 self.__selecting = True |
294 self.__selecting = True |
290 else: |
295 else: |
291 self.__selecting = False |
296 self.__selecting = False |
292 |
297 |
293 if self.__curTool in [self.RectangleSelection, self.CircleSelection, self.Line, |
298 if self.__curTool in [self.RectangleSelection, self.CircleSelection, |
294 self.Rectangle, self.FilledRectangle, |
299 self.Line, self.Rectangle, self.FilledRectangle, |
295 self.Circle, self.FilledCircle, |
300 self.Circle, self.FilledCircle, |
296 self.Ellipse, self.FilledEllipse]: |
301 self.Ellipse, self.FilledEllipse]: |
297 self.setCursor(self.__aimCursor) |
302 self.setCursor(self.__aimCursor) |
298 elif self.__curTool == self.Fill: |
303 elif self.__curTool == self.Fill: |
299 self.setCursor(self.__fillCursor) |
304 self.setCursor(self.__fillCursor) |
408 |
413 |
409 if self.__zoom >= 3 and self.__gridEnabled: |
414 if self.__zoom >= 3 and self.__gridEnabled: |
410 painter.setPen(self.palette().windowText().color()) |
415 painter.setPen(self.palette().windowText().color()) |
411 i = 0 |
416 i = 0 |
412 while i <= self.__image.width(): |
417 while i <= self.__image.width(): |
413 painter.drawLine(self.__zoom * i, 0, |
418 painter.drawLine( |
414 self.__zoom * i, self.__zoom * self.__image.height()) |
419 self.__zoom * i, 0, |
|
420 self.__zoom * i, self.__zoom * self.__image.height()) |
415 i += 1 |
421 i += 1 |
416 j = 0 |
422 j = 0 |
417 while j <= self.__image.height(): |
423 while j <= self.__image.height(): |
418 painter.drawLine(0, self.__zoom * j, |
424 painter.drawLine( |
419 self.__zoom * self.__image.width(), self.__zoom * j) |
425 0, self.__zoom * j, |
|
426 self.__zoom * self.__image.width(), self.__zoom * j) |
420 j += 1 |
427 j += 1 |
421 |
428 |
422 col = QColor("#aaa") |
429 col = QColor("#aaa") |
423 painter.setPen(Qt.DashLine) |
430 painter.setPen(Qt.DashLine) |
424 for i in range(0, self.__image.width()): |
431 for i in range(0, self.__image.width()): |
426 rect = self.__pixelRect(i, j) |
433 rect = self.__pixelRect(i, j) |
427 if evt.region().intersects(rect): |
434 if evt.region().intersects(rect): |
428 color = QColor.fromRgba(self.__image.pixel(i, j)) |
435 color = QColor.fromRgba(self.__image.pixel(i, j)) |
429 painter.fillRect(rect, QBrush(Qt.white)) |
436 painter.fillRect(rect, QBrush(Qt.white)) |
430 painter.fillRect(QRect(rect.topLeft(), rect.center()), col) |
437 painter.fillRect(QRect(rect.topLeft(), rect.center()), col) |
431 painter.fillRect(QRect(rect.center(), rect.bottomRight()), col) |
438 painter.fillRect(QRect(rect.center(), rect.bottomRight()), |
|
439 col) |
432 painter.fillRect(rect, QBrush(color)) |
440 painter.fillRect(rect, QBrush(color)) |
433 |
441 |
434 if self.__isMarked(i, j): |
442 if self.__isMarked(i, j): |
435 painter.drawRect(rect.adjusted(0, 0, -1, -1)) |
443 painter.drawRect(rect.adjusted(0, 0, -1, -1)) |
436 |
444 |
440 """ |
448 """ |
441 Private method to determine the rectangle for a given pixel coordinate. |
449 Private method to determine the rectangle for a given pixel coordinate. |
442 |
450 |
443 @param i x-coordinate of the pixel in the image (integer) |
451 @param i x-coordinate of the pixel in the image (integer) |
444 @param j y-coordinate of the pixel in the image (integer) |
452 @param j y-coordinate of the pixel in the image (integer) |
445 return rectangle for the given pixel coordinates (QRect) |
453 @return rectangle for the given pixel coordinates (QRect) |
446 """ |
454 """ |
447 if self.__zoom >= 3 and self.__gridEnabled: |
455 if self.__zoom >= 3 and self.__gridEnabled: |
448 return QRect(self.__zoom * i + 1, self.__zoom * j + 1, |
456 return QRect(self.__zoom * i + 1, self.__zoom * j + 1, |
449 self.__zoom - 1, self.__zoom - 1) |
457 self.__zoom - 1, self.__zoom - 1) |
450 else: |
458 else: |
451 return QRect(self.__zoom * i, self.__zoom * j, self.__zoom, self.__zoom) |
459 return QRect(self.__zoom * i, self.__zoom * j, |
|
460 self.__zoom, self.__zoom) |
452 |
461 |
453 def mousePressEvent(self, evt): |
462 def mousePressEvent(self, evt): |
454 """ |
463 """ |
455 Protected method to handle mouse button press events. |
464 Protected method to handle mouse button press events. |
456 |
465 |
535 self.__currentUndoCmd.setAfterImage(self.__image) |
544 self.__currentUndoCmd.setAfterImage(self.__image) |
536 self.__currentUndoCmd = None |
545 self.__currentUndoCmd = None |
537 |
546 |
538 if self.__curTool not in [self.Pencil, self.Rubber, |
547 if self.__curTool not in [self.Pencil, self.Rubber, |
539 self.Fill, self.ColorPicker, |
548 self.Fill, self.ColorPicker, |
540 self.RectangleSelection, self.CircleSelection]: |
549 self.RectangleSelection, |
|
550 self.CircleSelection]: |
541 cmd = IconEditCommand(self, self.__undoTexts[self.__curTool], |
551 cmd = IconEditCommand(self, self.__undoTexts[self.__curTool], |
542 self.__image) |
552 self.__image) |
543 if self.__drawTool(evt.pos(), False): |
553 if self.__drawTool(evt.pos(), False): |
544 self.__undoStack.push(cmd) |
554 self.__undoStack.push(cmd) |
545 cmd.setAfterImage(self.__image) |
555 cmd.setAfterImage(self.__image) |
583 |
593 |
584 @param pos widget position of the paste rectangle (QPoint) |
594 @param pos widget position of the paste rectangle (QPoint) |
585 """ |
595 """ |
586 self.__markImage.fill(self.NoMarkColor.rgba()) |
596 self.__markImage.fill(self.NoMarkColor.rgba()) |
587 if self.__pasteRect.isValid(): |
597 if self.__pasteRect.isValid(): |
588 self.__updateImageRect(self.__pasteRect.topLeft(), |
598 self.__updateImageRect( |
589 self.__pasteRect.bottomRight() + QPoint(1, 1)) |
599 self.__pasteRect.topLeft(), |
|
600 self.__pasteRect.bottomRight() + QPoint(1, 1)) |
590 |
601 |
591 x, y = self.__imageCoordinates(pos) |
602 x, y = self.__imageCoordinates(pos) |
592 isize = self.__image.size() |
603 isize = self.__image.size() |
593 if x + self.__clipboardSize.width() <= isize.width(): |
604 if x + self.__clipboardSize.width() <= isize.width(): |
594 sx = self.__clipboardSize.width() |
605 sx = self.__clipboardSize.width() |
609 self.__updateImageRect(self.__pasteRect.topLeft(), |
620 self.__updateImageRect(self.__pasteRect.topLeft(), |
610 self.__pasteRect.bottomRight() + QPoint(1, 1)) |
621 self.__pasteRect.bottomRight() + QPoint(1, 1)) |
611 |
622 |
612 def __drawTool(self, pos, mark): |
623 def __drawTool(self, pos, mark): |
613 """ |
624 """ |
614 Public method to perform a draw operation depending of the current tool. |
625 Public method to perform a draw operation depending of the current |
|
626 tool. |
615 |
627 |
616 @param pos widget coordinate to perform the draw operation at (QPoint) |
628 @param pos widget coordinate to perform the draw operation at (QPoint) |
617 @param mark flag indicating a mark operation (boolean) |
629 @param mark flag indicating a mark operation (boolean) |
618 @param flag indicating a successful draw (boolean) |
630 @return flag indicating a successful draw (boolean) |
619 """ |
631 """ |
620 self.__unMark() |
632 self.__unMark() |
621 |
633 |
622 if mark: |
634 if mark: |
623 self.__endPos = QPoint(pos) |
635 self.__endPos = QPoint(pos) |
660 r = max(abs(start.x() - end.x()), abs(start.y() - end.y())) |
672 r = max(abs(start.x() - end.x()), abs(start.y() - end.y())) |
661 if self.__curTool in [self.FilledCircle, self.CircleSelection]: |
673 if self.__curTool in [self.FilledCircle, self.CircleSelection]: |
662 painter.setBrush(QBrush(drawColor)) |
674 painter.setBrush(QBrush(drawColor)) |
663 painter.drawEllipse(start, r, r) |
675 painter.drawEllipse(start, r, r) |
664 if self.__selecting: |
676 if self.__selecting: |
665 self.__selRect = QRect(start.x() - r, start.y() - r, 2 * r + 1, 2 * r + 1) |
677 self.__selRect = QRect(start.x() - r, start.y() - r, |
|
678 2 * r + 1, 2 * r + 1) |
666 self.__selectionAvailable = True |
679 self.__selectionAvailable = True |
667 self.selectionAvailable.emit(True) |
680 self.selectionAvailable.emit(True) |
668 |
681 |
669 elif self.__curTool in [self.Ellipse, self.FilledEllipse]: |
682 elif self.__curTool in [self.Ellipse, self.FilledEllipse]: |
670 r1 = abs(start.x() - end.x()) |
683 r1 = abs(start.x() - end.x()) |
712 |
725 |
713 def __updateRect(self, pos1, pos2): |
726 def __updateRect(self, pos1, pos2): |
714 """ |
727 """ |
715 Private slot to update parts of the widget. |
728 Private slot to update parts of the widget. |
716 |
729 |
717 @param pos1 top, left position for the update in widget coordinates (QPoint) |
730 @param pos1 top, left position for the update in widget coordinates |
718 @param pos2 bottom, right position for the update in widget coordinates (QPoint) |
731 (QPoint) |
|
732 @param pos2 bottom, right position for the update in widget |
|
733 coordinates (QPoint) |
719 """ |
734 """ |
720 self.__updateImageRect(QPoint(*self.__imageCoordinates(pos1)), |
735 self.__updateImageRect(QPoint(*self.__imageCoordinates(pos1)), |
721 QPoint(*self.__imageCoordinates(pos2))) |
736 QPoint(*self.__imageCoordinates(pos2))) |
722 |
737 |
723 def __updateImageRect(self, ipos1, ipos2): |
738 def __updateImageRect(self, ipos1, ipos2): |
724 """ |
739 """ |
725 Private slot to update parts of the widget. |
740 Private slot to update parts of the widget. |
726 |
741 |
727 @param ipos1 top, left position for the update in image coordinates (QPoint) |
742 @param ipos1 top, left position for the update in image coordinates |
728 @param ipos2 bottom, right position for the update in image coordinates (QPoint) |
743 (QPoint) |
|
744 @param ipos2 bottom, right position for the update in image |
|
745 coordinates (QPoint) |
729 """ |
746 """ |
730 r1 = self.__pixelRect(ipos1.x(), ipos1.y()) |
747 r1 = self.__pixelRect(ipos1.x(), ipos1.y()) |
731 r2 = self.__pixelRect(ipos2.x(), ipos2.y()) |
748 r2 = self.__pixelRect(ipos2.x(), ipos2.y()) |
732 |
749 |
733 left = min(r1.x(), r2.x()) |
750 left = min(r1.x(), r2.x()) |
816 |
833 |
817 @param cut flag indicating to cut the selection (boolean) |
834 @param cut flag indicating to cut the selection (boolean) |
818 @return image of the selection (QImage) |
835 @return image of the selection (QImage) |
819 """ |
836 """ |
820 if cut: |
837 if cut: |
821 cmd = IconEditCommand(self, self.trUtf8("Cut Selection"), self.__image) |
838 cmd = IconEditCommand(self, self.trUtf8("Cut Selection"), |
|
839 self.__image) |
822 |
840 |
823 img = QImage(self.__selRect.size(), QImage.Format_ARGB32) |
841 img = QImage(self.__selRect.size(), QImage.Format_ARGB32) |
824 img.fill(qRgba(0, 0, 0, 0)) |
842 img.fill(qRgba(0, 0, 0, 0)) |
825 for i in range(0, self.__selRect.width()): |
843 for i in range(0, self.__selRect.width()): |
826 for j in range(0, self.__selRect.height()): |
844 for j in range(0, self.__selRect.height()): |
827 if self.__image.rect().contains(self.__selRect.x() + i, |
845 if self.__image.rect().contains(self.__selRect.x() + i, |
828 self.__selRect.y() + j): |
846 self.__selRect.y() + j): |
829 if self.__isMarked(self.__selRect.x() + i, self.__selRect.y() + j): |
847 if self.__isMarked( |
830 img.setPixel(i, j, self.__image.pixel(self.__selRect.x() + i, |
848 self.__selRect.x() + i, self.__selRect.y() + j): |
831 self.__selRect.y() + j)) |
849 img.setPixel(i, j, self.__image.pixel( |
|
850 self.__selRect.x() + i, self.__selRect.y() + j)) |
832 if cut: |
851 if cut: |
833 self.__image.setPixel(self.__selRect.x() + i, |
852 self.__image.setPixel(self.__selRect.x() + i, |
834 self.__selRect.y() + j, |
853 self.__selRect.y() + j, |
835 qRgba(0, 0, 0, 0)) |
854 qRgba(0, 0, 0, 0)) |
836 |
855 |
863 |
882 |
864 def editPaste(self, pasting=False): |
883 def editPaste(self, pasting=False): |
865 """ |
884 """ |
866 Public slot to paste an image from the clipboard. |
885 Public slot to paste an image from the clipboard. |
867 |
886 |
868 @param pasting flag indicating part two of the paste operation (boolean) |
887 @param pasting flag indicating part two of the paste operation |
|
888 (boolean) |
869 """ |
889 """ |
870 img, ok = self.__clipboardImage() |
890 img, ok = self.__clipboardImage() |
871 if ok: |
891 if ok: |
872 if img.width() > self.__image.width() or img.height() > self.__image.height(): |
892 if img.width() > self.__image.width() or \ |
|
893 img.height() > self.__image.height(): |
873 res = E5MessageBox.yesNo(self, |
894 res = E5MessageBox.yesNo(self, |
874 self.trUtf8("Paste"), |
895 self.trUtf8("Paste"), |
875 self.trUtf8("""<p>The clipboard image is larger than the current """ |
896 self.trUtf8( |
876 """image.<br/>Paste as new image?</p>""")) |
897 """<p>The clipboard image is larger than the""" |
|
898 """ current image.<br/>Paste as new image?</p>""")) |
877 if res: |
899 if res: |
878 self.editPasteAsNew() |
900 self.editPasteAsNew() |
879 return |
901 return |
880 elif not pasting: |
902 elif not pasting: |
881 self.__isPasting = True |
903 self.__isPasting = True |
882 self.__clipboardSize = img.size() |
904 self.__clipboardSize = img.size() |
883 else: |
905 else: |
884 cmd = IconEditCommand(self, self.trUtf8("Paste Clipboard"), self.__image) |
906 cmd = IconEditCommand(self, self.trUtf8("Paste Clipboard"), |
|
907 self.__image) |
885 self.__markImage.fill(self.NoMarkColor.rgba()) |
908 self.__markImage.fill(self.NoMarkColor.rgba()) |
886 painter = QPainter(self.__image) |
909 painter = QPainter(self.__image) |
887 painter.setPen(self.penColor()) |
910 painter.setPen(self.penColor()) |
888 painter.setCompositionMode(self.__compositingMode) |
911 painter.setCompositionMode(self.__compositingMode) |
889 painter.drawImage(self.__pasteRect.x(), self.__pasteRect.y(), img, 0, 0, |
912 painter.drawImage( |
890 self.__pasteRect.width() + 1, self.__pasteRect.height() + 1) |
913 self.__pasteRect.x(), self.__pasteRect.y(), img, 0, 0, |
|
914 self.__pasteRect.width() + 1, |
|
915 self.__pasteRect.height() + 1) |
891 |
916 |
892 self.__undoStack.push(cmd) |
917 self.__undoStack.push(cmd) |
893 cmd.setAfterImage(self.__image) |
918 cmd.setAfterImage(self.__image) |
894 |
919 |
895 self.__updateImageRect(self.__pasteRect.topLeft(), |
920 self.__updateImageRect( |
896 self.__pasteRect.bottomRight() + QPoint(1, 1)) |
921 self.__pasteRect.topLeft(), |
|
922 self.__pasteRect.bottomRight() + QPoint(1, 1)) |
897 else: |
923 else: |
898 E5MessageBox.warning(self, |
924 E5MessageBox.warning(self, |
899 self.trUtf8("Pasting Image"), |
925 self.trUtf8("Pasting Image"), |
900 self.trUtf8("""Invalid image data in clipboard.""")) |
926 self.trUtf8("""Invalid image data in clipboard.""")) |
901 |
927 |
903 """ |
929 """ |
904 Public slot to paste the clipboard as a new image. |
930 Public slot to paste the clipboard as a new image. |
905 """ |
931 """ |
906 img, ok = self.__clipboardImage() |
932 img, ok = self.__clipboardImage() |
907 if ok: |
933 if ok: |
908 cmd = IconEditCommand(self, self.trUtf8("Paste Clipboard as New Image"), |
934 cmd = IconEditCommand( |
909 self.__image) |
935 self, self.trUtf8("Paste Clipboard as New Image"), |
|
936 self.__image) |
910 self.setIconImage(img) |
937 self.setIconImage(img) |
911 self.setDirty(True) |
938 self.setDirty(True) |
912 self.__undoStack.push(cmd) |
939 self.__undoStack.push(cmd) |
913 cmd.setAfterImage(self.__image) |
940 cmd.setAfterImage(self.__image) |
914 |
941 |
947 from .IconSizeDialog import IconSizeDialog |
974 from .IconSizeDialog import IconSizeDialog |
948 dlg = IconSizeDialog(self.__image.width(), self.__image.height()) |
975 dlg = IconSizeDialog(self.__image.width(), self.__image.height()) |
949 res = dlg.exec_() |
976 res = dlg.exec_() |
950 if res == QDialog.Accepted: |
977 if res == QDialog.Accepted: |
951 newWidth, newHeight = dlg.getData() |
978 newWidth, newHeight = dlg.getData() |
952 if newWidth != self.__image.width() or newHeight != self.__image.height(): |
979 if newWidth != self.__image.width() or \ |
953 cmd = IconEditCommand(self, self.trUtf8("Resize Image"), self.__image) |
980 newHeight != self.__image.height(): |
954 img = self.__image.scaled(newWidth, newHeight, Qt.IgnoreAspectRatio, |
981 cmd = IconEditCommand(self, self.trUtf8("Resize Image"), |
955 Qt.SmoothTransformation) |
982 self.__image) |
|
983 img = self.__image.scaled( |
|
984 newWidth, newHeight, Qt.IgnoreAspectRatio, |
|
985 Qt.SmoothTransformation) |
956 self.setIconImage(img) |
986 self.setIconImage(img) |
957 self.setDirty(True) |
987 self.setDirty(True) |
958 self.__undoStack.push(cmd) |
988 self.__undoStack.push(cmd) |
959 cmd.setAfterImage(self.__image) |
989 cmd.setAfterImage(self.__image) |
960 |
990 |
973 |
1003 |
974 def grayScale(self): |
1004 def grayScale(self): |
975 """ |
1005 """ |
976 Public slot to convert the image to gray preserving transparency. |
1006 Public slot to convert the image to gray preserving transparency. |
977 """ |
1007 """ |
978 cmd = IconEditCommand(self, self.trUtf8("Convert to Grayscale"), self.__image) |
1008 cmd = IconEditCommand(self, self.trUtf8("Convert to Grayscale"), |
|
1009 self.__image) |
979 for x in range(self.__image.width()): |
1010 for x in range(self.__image.width()): |
980 for y in range(self.__image.height()): |
1011 for y in range(self.__image.height()): |
981 col = self.__image.pixel(x, y) |
1012 col = self.__image.pixel(x, y) |
982 if col != qRgba(0, 0, 0, 0): |
1013 if col != qRgba(0, 0, 0, 0): |
983 gray = qGray(col) |
1014 gray = qGray(col) |
984 self.__image.setPixel(x, y, qRgba(gray, gray, gray, qAlpha(col))) |
1015 self.__image.setPixel( |
|
1016 x, y, qRgba(gray, gray, gray, qAlpha(col))) |
985 self.update() |
1017 self.update() |
986 self.setDirty(True) |
1018 self.setDirty(True) |
987 self.__undoStack.push(cmd) |
1019 self.__undoStack.push(cmd) |
988 cmd.setAfterImage(self.__image) |
1020 cmd.setAfterImage(self.__image) |
989 |
1021 |