1from __future__ import absolute_import
2# #START_LICENSE###########################################################
3#
4#
5# This file is part of the Environment for Tree Exploration program
6# (ETE).  http://etetoolkit.org
7#
8# ETE is free software: you can redistribute it and/or modify it
9# under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# ETE is distributed in the hope that it will be useful, but WITHOUT
14# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
16# License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with ETE.  If not, see <http://www.gnu.org/licenses/>.
20#
21#
22#                     ABOUT THE ETE PACKAGE
23#                     =====================
24#
25# ETE is distributed under the GPL copyleft license (2008-2015).
26#
27# If you make use of ETE in published work, please cite:
28#
29# Jaime Huerta-Cepas, Joaquin Dopazo and Toni Gabaldon.
30# ETE: a python Environment for Tree Exploration. Jaime BMC
31# Bioinformatics 2010,:24doi:10.1186/1471-2105-11-24
32#
33# Note that extra references to the specific methods implemented in
34# the toolkit may be available in the documentation.
35#
36# More info at http://etetoolkit.org. Contact: huerta@embl.de
37#
38#
39# #END_LICENSE#############################################################
40import types
41import signal
42
43from .qt import *
44
45from .qt4_gui import _GUI, _PropertiesDialog, _BasicNodeActions
46
47from . import layouts
48from .main import save
49from .qt4_render import _TreeScene, render, get_tree_img_map, init_tree_style
50
51__all__ = ["show_tree", "render_tree"]
52
53_QApp = None
54GUI_TIMEOUT = None
55
56def exit_gui(a, b):
57    _QApp.exit(0)
58
59def init_scene(t, layout, ts):
60    global _QApp
61
62    ts = init_tree_style(t, ts)
63    if layout:
64        ts.layout_fn  = layout
65
66    if not _QApp:
67        _QApp = QApplication(["ETE"])
68
69    scene  = _TreeScene()
70	#ts._scale = None
71    return scene, ts
72
73def show_tree(t, layout=None, tree_style=None, win_name=None):
74    """ Interactively shows a tree."""
75    scene, img = init_scene(t, layout, tree_style)
76    tree_item, n2i, n2f = render(t, img)
77    scene.init_values(t, img, n2i, n2f)
78
79    tree_item.setParentItem(scene.master_item)
80    scene.addItem(scene.master_item)
81
82    mainapp = _GUI(scene)
83    if win_name:
84        mainapp.setObjectName(win_name)
85
86    mainapp.show()
87    mainapp.on_actionFit2tree_triggered()
88    # Restore Ctrl-C behavior
89    signal.signal(signal.SIGINT, signal.SIG_DFL)
90    if GUI_TIMEOUT is not None:
91        signal.signal(signal.SIGALRM, exit_gui)
92        signal.alarm(GUI_TIMEOUT)
93
94    _QApp.exec_()
95
96def render_tree(t, imgName, w=None, h=None, layout=None,
97                tree_style = None, header=None, units="px",
98                dpi=90):
99    """ Render tree image into a file."""
100    global _QApp
101    for nid, n in enumerate(t.traverse("preorder")):
102        n.add_feature("_nid", nid)
103    scene, img = init_scene(t, layout, tree_style)
104    tree_item, n2i, n2f = render(t, img)
105
106    scene.init_values(t, img, n2i, n2f)
107    tree_item.setParentItem(scene.master_item)
108    scene.master_item.setPos(0,0)
109    scene.addItem(scene.master_item)
110    if imgName.startswith("%%inline"):
111        imgmap = save(scene, imgName, w=w, h=h, units=units, dpi=dpi)
112    else:
113        x_scale, y_scale = save(scene, imgName, w=w, h=h, units=units, dpi=dpi)
114        imgmap = get_tree_img_map(n2i, x_scale, y_scale)
115    return imgmap
116
117
118class RenderThread(QThread):
119    def __init__(self, tree, layout, tree_style, w, h, dpi, units, rformat):
120        self.tree = tree
121        self.layout = layout
122        self.tree_style = tree_style
123        self.w = w
124        self.h = h
125        self.dpi = dpi
126        self.units = units
127        self.return_format = rformat
128        self.result = None
129
130        QThread.__init__(self)
131
132    def run(self):
133        scene, img = init_scene(self.tree, self.layout, self.tree_style)
134        tree_item, n2i, n2f = render(self.tree, img)
135
136        scene.init_values(self.tree, img, n2i, n2f)
137
138        tree_item.setParentItem(scene.master_item)
139        scene.master_item.setPos(0, 0)
140        scene.addItem(scene.master_item)
141        x_scale, y_scale, imgdata = save(scene, self.return_format, w=self.w,
142                                         h=self.h, units=self.units, dpi=self.dpi)
143        if 'PNG' in self.return_format:
144            img_map = get_tree_img_map(n2i, x_scale, y_scale)
145        else:
146            img_map = {}
147
148        self.result = [imgdata, img_map]
149
150
151def get_img(t, w=None, h=None, layout=None, tree_style = None,
152            header=None, units="px", dpi=90, return_format="%%return"):
153    global _QApp
154    if not _QApp:
155        _QApp = QApplication(["ETE"])
156
157    r = RenderThread(t, layout, tree_style, w, h, dpi, units, return_format)
158    r.start()
159    r.wait()
160    return r.result
161