1 """GUI support for user scripting.
2
3 Copyright 2014 Research Foundation State University of New York
4 This file is part of QUB Express.
5
6 QUB Express is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 QUB Express is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License,
17 named LICENSE.txt, in the QUB Express program directory. If not, see
18 <http://www.gnu.org/licenses/>.
19
20 """
21
22 import os
23 import gobject
24 import gtk
25
26 import qubx.faces
27 import qubx.GTK
28 import qubx.pyenv
29 import qubx.pyenvGTK
30 import qubx.settings
31 import qubx.tree
32 from qubx.GTK import pack_item, pack_label, pack_button, pack_space, pack_scrolled, build_menuitem
33 from qubx.util_types import *
34
35
37 """Displays a narrative with hypertext-style links. Each link triggers a script.
38
39 @ivar view: a L{qubx.pyenvGTK.ScriptedLinkView}
40 @ivar OnSwitchPage: L{qubx.util_types.WeakEvent}(Workflow, page_number, previous page_number)
41 @ivar OnStartOver: L{qubx.util_types.WeakEvent}(Workflow)
42 """
43
44 __explore_featured = ['view', 'OnSwitchPage', 'OnStartOver', 'page_number', 'page_count', 'start_over',
45 'prev_page', 'next_page', 'insert_page', 'append_page', 'remove_page']
46
48 """Each additional argument is a tuple/list suitable as arguments for L{qubx.pyenvGTK.ScriptedLinkView.write}.
49 @param name: onscreen name of workflow
50 """
51 super(Workflow, self).__init__(name)
52 self.set_size_request(300, 500)
53 self.__ref = Reffer()
54 self.__page_number = 0
55 self.__pages = list(args)
56 self.view = qubx.pyenvGTK.ScriptedLinkView(name, *(args[0]))
57 pack_scrolled(self.view, self, expand=True)
58 pack_space(self, y=8)
59 qubx.GTK.SetFixedWidth(self.view, qubx.toolspace.Appearance.font_size)
60 qubx.toolspace.Appearance.OnSetFontSize += self.__ref(self.__onSetFontSize)
61 self.panButtons = pack_item(gtk.HBox(), self)
62 pack_space(self, y=8)
63 pack_space(self.panButtons, x=8)
64 self.btnStart = pack_button('Start over', self.panButtons, self.start_over)
65 pack_space(self.panButtons, expand=True)
66 self.btnPrev = pack_button('Prev', self.panButtons, self.prev_page)
67 pack_space(self.panButtons, expand=True)
68 self.btnNext = pack_button('Next', self.panButtons, self.next_page)
69 pack_space(self.panButtons, expand=True)
70 self.__update_buttons()
71 self.OnSwitchPage = WeakEvent()
72 self.OnStartOver = WeakEvent()
73 page_number = property(lambda self: self.__page_number, lambda self, x: self.set_page_number(x), doc="index of onscreen page")
74 page_count = property(lambda self: len(self.__pages), doc="total number of pages")
83 - def set_page_number(self, x):
84 if x == self.__page_number:
85 return
86 prev = self.__page_number
87 self.__page_number = x
88 self.view.clear()
89 self.view.write(*self.__pages[x])
90 self.__update_buttons()
91 self.OnSwitchPage(self, x, prev)
95 - def prev_page(self, *args):
96 self.page_number = self.__page_number - 1
97 - def next_page(self, *args):
98 self.page_number = self.__page_number + 1
99 - def insert_page(self, i, page):
100 if not (self.__page_number < i <= len(self.__pages)):
101 raise IndexError
102 self.__pages.insert(i, page)
103 self.__update_buttons()
104 - def append_page(self, page):
105 self.insert_page(len(self.__pages), page)
106 - def remove_page(self, i):
107 if not (self.__page_number < i < len(self.__pages)):
108 raise IndexError
109 del self.__pages[i]
110 self.__update_buttons()
113
114
116 sample = Workflow(
117 "Sample",
118
119 [
120 """This is an example of a workflow script.
121
122 Links can trigger a """,
123 ("function", lambda: sample.next_page()),
124
125 """,
126 or they can trigger a textual """,
127 ("script", """doze(3)
128 QubX.Models.request_show()"""),
129 """.
130 """],
131
132 [
133 """We'll start with two pages, but then """,
134 ("add some more", lambda: sample.append_page(["""This is an auto-generated page.
135
136 """,
137 ("Remove next page", lambda: sample.remove_page(sample.page_number+1)),
138 """(can only remove pages from the future)"""
139 ])
140 )]
141 )
142
143 sample.ref = Reffer()
144 def on_switch_page(workflow, ix, prev):
145 print 'switched from page %i to page %i' % (prev, ix)
146 sample.OnSwitchPage += sample.ref(on_switch_page)
147 def on_start_over(workflow):
148
149 while workflow.page_count > 2:
150 workflow.remove_page(2)
151 sample.OnStartOver += sample.ref(on_start_over)
152
153 qubx.global_namespace.QubX.Workflows.append_face(sample)
154 gobject.idle_add(sample.request_show)
155