Skip to content

Commit

Permalink
playing with an image viewer
Browse files Browse the repository at this point in the history
  • Loading branch information
chick committed Apr 29, 2014
1 parent b104399 commit 2ade9aa
Show file tree
Hide file tree
Showing 8 changed files with 302 additions and 74 deletions.
2 changes: 1 addition & 1 deletion ast_tool_box/controllers/code_presenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def apply_codegen_transform(ast_root, argument_list):
argument_values = [eval(x) for x in argument_values]

tree_copy = copy.deepcopy(code_item.ast_tree)
new_code = apply_codegen_transform(tree_copy)
new_code = apply_codegen_transform(tree_copy, argument_values)
new_code_item = code_model.GeneratedCodeItem(
new_code,
parent_link=code_model.CodeTransformLink(code_item=code_item, transform_item=transform_item),
Expand Down
35 changes: 5 additions & 30 deletions ast_tool_box/controllers/transform_presenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,36 +77,6 @@ def count(self):
"""return current transforms"""
return len(list(self.transform_items()))

# def __getitem__(self, item):
# if isinstance(item, int):
# return self.transform_items[item]
# elif isinstance(item, str):
# return self.transforms_by_name[item]

# def get_valid_index(self, index):
# """
# convenience method for checking index
# if index is a string make it an int
# None returned if failed to convert or index out of range
# """
# if not isinstance(index, int):
# try:
# index = int(index)
# except ValueError:
# return None
#
# if index >= 0:
# if index < len(self.transform_items):
# return index
# return None

# def get_instance_by_name(self, transform_name):
# transform_item = self.transforms_by_name[transform_name]
# return transform_item.get_instance()

# def __iter__(self):
# return iter(self.transform_items)

def load_file(self, file_name):
print("loading %s" % file_name)
if not os.path.isfile(file_name):
Expand All @@ -129,6 +99,11 @@ def load_files(self, file_names):

self.transform_pane.transform_tree_widget.build(self.transform_collections)

def update_file(self, transform_collection):
TransformPresenter.delete_module(transform_collection.package_name)
transform_collection.update()
self.transform_pane.transform_tree_widget.rebuild(transform_collection)

@staticmethod
def delete_module(module_name):
Util.clear_classes_in_package(module_name)
Expand Down
5 changes: 5 additions & 0 deletions ast_tool_box/transformers/identity_transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ def __init__(self, **kwargs):
self.args = kwargs


class Chick7Transform(Chick2Transform):
def __init__(self, **kwargs):
self.args = kwargs


class NoisyIdentityTransform(ast.NodeTransformer):
def __init__(self):
super(NoisyIdentityTransform, self).__init__()
Expand Down
2 changes: 1 addition & 1 deletion ast_tool_box/views/code_views/code_pane.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ def add_code_item(self, code_item):
widget = EditorPane()
widget.setPlainText(code_item.code)
elif isinstance(code_item, AstTreeItem):
widget = AstTreePane(self.code_presenter, code_item.code)
widget = AstTreePane(self.code_presenter, code_item.code, tab_name=code_item.code_name)
elif isinstance(code_item, GeneratedCodeItem):
widget = EditorPane()
widget.setPlainText(code_item.code)
Expand Down
26 changes: 21 additions & 5 deletions ast_tool_box/views/editor_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ def __init__(self, parent_panel=None):

if self.parent_panel:
self.textChanged.connect(self.parent_panel.text_changed)
self.undoAvailable.connect(self.parent_panel.enable_undo)
self.redoAvailable.connect(self.parent_panel.enable_redo)

self.highlighter = Highlighter(self.document())

Expand All @@ -45,6 +47,7 @@ class EditorPanel(QtGui.QGroupBox):
def __init__(self, transform_pane=None):
super(EditorPanel, self).__init__("Editor")
self.transform_pane = transform_pane
self.transform_collection = None

layout = QtGui.QVBoxLayout()
button_panel = QtGui.QDialogButtonBox(QtCore.Qt.Horizontal)
Expand Down Expand Up @@ -73,16 +76,24 @@ def text_changed(self):

def undo(self):
self.editor.undo()
if not self.editor.undoAvailable():
self.undo_button.setEnabled(False)
# if not self.editor.undoAvailable():
# self.undo_button.setEnabled(False)
self.redo_button.setEnabled(True)

@QtCore.Slot(bool)
def enable_undo(self, value):
self.undo_button.setEnabled(value)

def redo(self):
self.editor.redo()
if not self.editor.redoAvailable():
self.redo_button.setEnabled(False)
# if not self.editor.redoAvailable():
# self.redo_button.setEnabled(False)
self.undo_button.setEnabled(True)

@QtCore.Slot(bool)
def enable_redo(self, value):
self.redo_button.setEnabled(value)

def save(self):
print("Got save file for %s" % self.editor.file_name)
file_text = self.editor.toPlainText()
Expand All @@ -91,7 +102,12 @@ def save(self):
self.editor.setPlainText(file_text)
self.save_button.setEnabled(False)
if self.transform_pane:
self.transform_pane.transform_presenter.reload_transforms()
if self.transform_collection:
print("calling update file")
self.transform_pane.transform_presenter.update_file(self.transform_collection)
else:
print("calling reload transforms")
self.transform_pane.transform_presenter.reload_transforms()

def set_read_only(self, value):
if value:
Expand Down
196 changes: 196 additions & 0 deletions ast_tool_box/views/image_viewer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
#!/usr/bin/env python

#############################################################################
##
## Copyright (C) 2005-2005 Trolltech AS. All rights reserved.
##
## This file is part of the example classes of the Qt Toolkit.
##
## This file may be used under the terms of the GNU General Public
## License version 2.0 as published by the Free Software Foundation
## and appearing in the file LICENSE.GPL included in the packaging of
## this file. Please review the following information to ensure GNU
## General Public Licensing requirements will be met:
## http://www.trolltech.com/products/qt/opensource.html
##
## If you are unsure which license is appropriate for your use, please
## review the following information:
## http://www.trolltech.com/products/qt/licensing.html or contact the
## sales department at [email protected].
##
## This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
## WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
##
#############################################################################

from PySide import QtCore, QtGui


class ImageViewer(QtGui.QGroupBox):
def __init__(self, file_name="", tab_name="image"):
super(ImageViewer, self).__init__(tab_name)

self.file_name = file_name

self.printer = QtGui.QPrinter()
self.scaleFactor = 0.0

self.imageLabel = QtGui.QLabel()
self.imageLabel.setBackgroundRole(QtGui.QPalette.Base)
self.imageLabel.setSizePolicy(QtGui.QSizePolicy.Ignored,
QtGui.QSizePolicy.Ignored)
self.imageLabel.setScaledContents(True)

self.scrollArea = QtGui.QScrollArea()
self.scrollArea.setBackgroundRole(QtGui.QPalette.Dark)
self.scrollArea.setWidget(self.imageLabel)
self.setCentralWidget(self.scrollArea)

self.createActions()
self.createMenus()

self.setWindowTitle("Image Viewer")
self.resize(500, 400)

def open(self):
file_name, _ = QtGui.QFileDialog.getOpenFileName(self, "Open File", QtCore.QDir.currentPath())
print("file %s" % file_name)
if file_name:
image = QtGui.QImage(file_name)
if image.isNull():
QtGui.QMessageBox.information(self, "Image Viewer Cannot load %s." % file_name)
return

self.imageLabel.setPixmap(QtGui.QPixmap.fromImage(image))
self.scaleFactor = 1.0

self.printAct.setEnabled(True)
self.fitToWindowAct.setEnabled(True)
self.updateActions()

if not self.fitToWindowAct.isChecked():
self.imageLabel.adjustSize()

def print_(self):
dialog = QtGui.QPrintDialog(self.printer, self)
if dialog.exec_():
painter = QtGui.QPainter(self.printer)
rect = painter.viewport()
size = self.imageLabel.pixmap().size()
size.scale(rect.size(), QtCore.Qt.KeepAspectRatio)
painter.setViewport(rect.x(), rect.y(), size.width(), size.height())
painter.setWindow(self.imageLabel.pixmap().rect())
painter.drawPixmap(0, 0, self.imageLabel.pixmap())

def zoomIn(self):
self.scaleImage(1.25)

def zoomOut(self):
self.scaleImage(0.8)

def normalSize(self):
self.imageLabel.adjustSize()
self.scaleFactor = 1.0

def fitToWindow(self):
fitToWindow = self.fitToWindowAct.isChecked()
self.scrollArea.setWidgetResizable(fitToWindow)
if not fitToWindow:
self.normalSize()

self.updateActions()

def about(self):
QtGui.QMessageBox.about(self, "About Image Viewer",
"<p>The <b>Image Viewer</b> example shows how to combine "
"QLabel and QScrollArea to display an image. QLabel is "
"typically used for displaying text, but it can also display "
"an image. QScrollArea provides a scrolling view around "
"another widget. If the child widget exceeds the size of the "
"frame, QScrollArea automatically provides scroll bars.</p>"
"<p>The example demonstrates how QLabel's ability to scale "
"its contents (QLabel.scaledContents), and QScrollArea's "
"ability to automatically resize its contents "
"(QScrollArea.widgetResizable), can be used to implement "
"zooming and scaling features.</p>"
"<p>In addition the example shows how to use QPainter to "
"print an image.</p>")

def createActions(self):
self.openAct = QtGui.QAction("&Open...", self, shortcut="Ctrl+O",
triggered=self.open)

self.printAct = QtGui.QAction("&Print...", self, shortcut="Ctrl+P",
enabled=False, triggered=self.print_)

self.exitAct = QtGui.QAction("E&xit", self, shortcut="Ctrl+Q",
triggered=self.close)

self.zoomInAct = QtGui.QAction("Zoom &In (25%)", self,
shortcut="Ctrl++", enabled=False, triggered=self.zoomIn)

self.zoomOutAct = QtGui.QAction("Zoom &Out (25%)", self,
shortcut="Ctrl+-", enabled=False, triggered=self.zoomOut)

self.normalSizeAct = QtGui.QAction("&Normal Size", self,
shortcut="Ctrl+S", enabled=False, triggered=self.normalSize)

self.fitToWindowAct = QtGui.QAction("&Fit to Window", self,
enabled=False, checkable=True, shortcut="Ctrl+F",
triggered=self.fitToWindow)

self.aboutAct = QtGui.QAction("&About", self, triggered=self.about)

self.aboutQtAct = QtGui.QAction("About &Qt", self,
triggered=QtGui.qApp.aboutQt)

def createMenus(self):
self.fileMenu = QtGui.QMenu("&File", self)
self.fileMenu.addAction(self.openAct)
self.fileMenu.addAction(self.printAct)
self.fileMenu.addSeparator()
self.fileMenu.addAction(self.exitAct)

self.viewMenu = QtGui.QMenu("&View", self)
self.viewMenu.addAction(self.zoomInAct)
self.viewMenu.addAction(self.zoomOutAct)
self.viewMenu.addAction(self.normalSizeAct)
self.viewMenu.addSeparator()
self.viewMenu.addAction(self.fitToWindowAct)

self.helpMenu = QtGui.QMenu("&Help", self)
self.helpMenu.addAction(self.aboutAct)
self.helpMenu.addAction(self.aboutQtAct)

self.menuBar().addMenu(self.fileMenu)
self.menuBar().addMenu(self.viewMenu)
self.menuBar().addMenu(self.helpMenu)

def updateActions(self):
self.zoomInAct.setEnabled(not self.fitToWindowAct.isChecked())
self.zoomOutAct.setEnabled(not self.fitToWindowAct.isChecked())
self.normalSizeAct.setEnabled(not self.fitToWindowAct.isChecked())

def scaleImage(self, factor):
self.scaleFactor *= factor
self.imageLabel.resize(self.scaleFactor * self.imageLabel.pixmap().size())

self.adjustScrollBar(self.scrollArea.horizontalScrollBar(), factor)
self.adjustScrollBar(self.scrollArea.verticalScrollBar(), factor)

self.zoomInAct.setEnabled(self.scaleFactor < 3.0)
self.zoomOutAct.setEnabled(self.scaleFactor > 0.333)

def adjustScrollBar(self, scrollBar, factor):
scrollBar.setValue(int(factor * scrollBar.value()
+ ((factor - 1) * scrollBar.pageStep()/2)))


if __name__ == '__main__':

import sys

app = QtGui.QApplication(sys.argv)
imageViewer = ImageViewer()
imageViewer.show()
sys.exit(app.exec_())
8 changes: 8 additions & 0 deletions ast_tool_box/views/transform_views/transform_pane.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,11 @@ def load_editor_from(self, widget_item):
read_only = False

transform_item = widget_item.source
file_item = None
if isinstance(transform_item, TransformThing):
if transform_item.transform_file:
file_item = transform_item.transform_file
print("file_item set to %s" % file_item)
file_name = file_item.file_name
if not file_item.source_text:
source_text = transform_item.source_text
Expand Down Expand Up @@ -126,6 +128,12 @@ def load_editor_from(self, widget_item):
title += " READ ONLY"
self.editor_panel.setTitle(title)

if file_item:
print("set editor from has a file_item %s" % file_item)
self.editor_panel.transform_collection = file_item
else:
print("set_editor_from does not have a file_item")

self.editor.setCenterOnScroll(True)
text_cursor = self.editor.textCursor()
text_block = self.editor.document().findBlockByLineNumber(line_number - 1)
Expand Down
Loading

0 comments on commit 2ade9aa

Please sign in to comment.