1
2 /******************************************************************************
3 * MODULE : qt_widget.hpp
4 * DESCRIPTION: QT widget class
5 * COPYRIGHT : (C) 2008 Massimiliano Gubinelli
6 *******************************************************************************
7 * This software falls under the GNU general public license version 3 or later.
8 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
9 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
10 ******************************************************************************/
11
12 #ifndef QT_WIDGET_HPP
13 #define QT_WIDGET_HPP
14
15 #include "widget.hpp"
16 #include "message.hpp"
17 #include <QPointer>
18
19 class QWidget;
20 class QLayoutItem;
21 class QAction;
22 class QMenu;
23 class qt_widget;
24
25 /*! The base class of all TeXmacs widgets in the QT interface.
26
27 Every TeXmacs Widget is an entity which can be manipulated from within scheme.
28 The interface to this is provided by widget_rep, which we extend. The methods
29 here declared must be implemented by the QT wrappers.
30
31 We must distinguish between three stages of widget creation:
32
33 1) Scheme widgets: these are scheme trees describing the widgets. These trees
34 are the result of several macro expansions on the code given by the user in
35 scheme (see under progs/kernel/gui) and are wholly handled by the TeXmacs
36 core. The Qt side plays no role here.
37 2) Parsed widgets: the C++ interpretation of the scheme widget. Merely a
38 collection of qt_widget instances, without any (visible) QWidgets
39 instantiated.
40 3) Compiled widgets: The Qt rendering of the parsed widgets. The outermost
41 widget receives a message to display which possibly translates to the
42 instantiation of a QWidget using as_qwidget(). This call will in turn
43 call this method for children widgets and so on down the chain.
44
45 Additionally, we provide several methods to cope with the fact that TeXmacs
46 expects widgets to behave in three different ways: as embedded widgets,
47 as menus and as regular widgets, all of which are essentially different in QT.
48 Hence the need to construct the QT widgets differently on a request basis via
49 the four methods as_qaction(), as_qlayoutitem(), as_qwidget() and get_qmenu().
50 Reimplementations of these should cope with the basic differences these
51 concepts have in QT:
52
53 * as_qaction() returns a QAction, mainly to be inserted into a QMenuBar.
54 QWidgets should render themselves in an adequate fashion (i.e. with small
55 font, using popup buttons where appropriate, etc.)
56
57 * as_qlayoutitem() usually does one of two things: either embedding a QWidget
58 in a QLayouttItem, so as to add it to some QLayout, or creating a "pure"
59 QLayoutItem.
60
61 * as_qwidget() returns a regular QWidget, for example to be embedded in a
62 standalone window.
63
64 get_qmenu() returns the QMenu owned by the QAction returned by as_qaction().
65 This method also promotes the object upon which it was invoked to owner of the
66 QMenu. Again: calling wid->get_qmenu() creates the QMenu and leaves ownership
67 of it to wid.
68
69 In the first three cases a new instance of the QObject is created if neede
70 and ownership is transferred to the caller. One reason why the underlying
71 QWidget is NOT owned by the qt_widget is that several qt_widgets may have the
72 same underlying QWidget (UPD: which?). Another are the problems due to delayed
73 deletion of TeXmacs objects. The only exception to this rule are those
74 qt_widgets whose compiled widgets are windows to whom we leave the
75 responsibility of deletion. They are the outmost widget, typically a
76 QTMPlainWindow or a QTMWindow, who should be the parent of all the related
77 QWidgets.
78
79 Most of the UI items are implemented by qt_ui_element_rep, with some
80 exceptions. Creation from the TeXmacs side is done using the global functions
81 declared in Graphics/Gui/widget.hpp.
82 */
83 class qt_widget;
84
85 class qt_widget_rep : public widget_rep {
86 protected:
87 array<widget> children;
88 public:
89 long id;
90 QPointer<QWidget> qwid;
91
92 /*! A list of all supported widget types.
93 FIXME: This enum breaks the basic inheritance rules, since we have to
94 update the base class each time we implement a new subclass. It's also some
95 sort of bastardic and lame RTTI, which might be proof of bad design...
96 But it comes handy in a few places right now ;)
97 NOTE: please modify qt_widget_type_strings[] in type_as_string() accordingly!
98 */
99 enum types {
100 none = 0,
101 input_widget, file_chooser, window_widget, view_widget,
102 horizontal_menu, vertical_menu, horizontal_list, vertical_list,
103 tile_menu, minibar_menu, menu_separator, menu_group,
104 pulldown_button, pullright_button, menu_button, balloon_widget,
105 text_widget, xpm_widget, toggle_widget, enum_widget,
106 choice_widget, scrollable_widget, hsplit_widget, vsplit_widget,
107 aligned_widget, tabs_widget, icon_tabs_widget, wrapped_widget,
108 refresh_widget, refreshable_widget, glue_widget, resize_widget,
109 texmacs_widget, simple_widget, embedded_tm_widget, popup_widget,
110 field_widget, filtered_choice_widget, tree_view_widget
111 } ;
112
113 types type;
114
115 qt_widget_rep (types _type=none, QWidget* _qwid=0);
116 virtual ~qt_widget_rep ();
get_nickname()117 virtual inline string get_nickname () { return "popup"; }
118
119 virtual widget plain_window_widget (string name, command quit);
120 virtual widget make_popup_widget ();
121 virtual widget popup_window_widget (string s);
122
123 void add_child (widget a);
124 void add_children (array<widget> a);
125
126 ////////////////////// Qt semantics of abstract texmacs widgets
127
128 virtual QAction* as_qaction ();
129 virtual QWidget* as_qwidget ();
130 virtual QLayoutItem* as_qlayoutitem ();
131 virtual QMenu* get_qmenu ();
132
133
134 ////////////////////// Debugging
135
type_as_string()136 string type_as_string() {
137 static const char* qt_widget_type_strings[] = {
138 "none",
139 "input_widget", "file_chooser", "window_widget",
140 "view_widget", "horizontal_menu", "vertical_menu",
141 "horizontal_list", "vertical_list", "tile_menu",
142 "minibar_menu", "menu_separator", "menu_group",
143 "pulldown_button", "pullright_button", "menu_button",
144 "balloon_widget", "text_widget", "xpm_widget",
145 "toggle_widget", "enum_widget", "choice_widget",
146 "scrollable_widget", "hsplit_widget", "vsplit_widget",
147 "aligned_widget", "tabs_widget", "icon_tabs_widget",
148 "wrapped_widget", "refresh_widget", "refreshable_widget",
149 "glue_widget", "resize_widget", "texmacs_widget",
150 "simple_widget", "embedded_tm_widget", "popup_widget",
151 "field_widget", "filtered_choice_widget", "tree_view_widget"
152 };
153 return string (qt_widget_type_strings[type]) * "\t id: " * as_string (id);
154 }
155
156 ////////////////////// Handling of TeXmacs' messages
157
158 /// See widkit_wrapper.cpp for the reference list of slots. Based on the
159 /// handlers invoked by wk_widget_rep::send(), query() etc. we can decide
160 /// what slots must implement each qt_widget.
161 virtual void send (slot s, blackbox val);
162
query(slot s,int type_id)163 virtual blackbox query (slot s, int type_id) {
164 (void) type_id;
165 if (DEBUG_QT)
166 debug_qt << "qt_widget_rep::query(), unhandled " << slot_name (s)
167 << " for widget of type: " << type_as_string() << LF;
168 return blackbox ();
169 }
170
read(slot s,blackbox index)171 virtual widget read (slot s, blackbox index) {
172 (void) index;
173 if (DEBUG_QT)
174 debug_qt << "qt_widget_rep::read(), unhandled " << slot_name (s)
175 << " for widget of type: " << type_as_string() << LF;
176 return widget ();
177 }
178
write(slot s,blackbox index,widget w)179 virtual void write (slot s, blackbox index, widget w) {
180 (void) index; (void) w;
181 if (DEBUG_QT)
182 debug_qt << "qt_widget_rep::write(), unhandled " << slot_name (s)
183 << " for widget of type: " << type_as_string() << LF;
184 }
185
notify(slot s,blackbox new_val)186 virtual void notify (slot s, blackbox new_val) {
187 (void) new_val;
188 if (DEBUG_QT)
189 debug_qt << "qt_widget_rep::notify(), unhandled " << slot_name (s)
190 << " for widget of type: " << type_as_string() << LF;
191 }
192 };
193
194
195 /*! Reference counting mechanism.
196
197 Like elsewhere in TeXmacs, this is a wrapper around its corresponding
198 qt_widget_rep which implements reference counting.
199 See src/Kernel/Abstractions/basic.hpp
200 */
201 class qt_widget {
202 public:
203 ABSTRACT_NULL(qt_widget); // Automagically declared constructor, methods, etc.
204
operator ==(qt_widget w)205 inline bool operator == (qt_widget w) { return rep == w.rep; }
operator !=(qt_widget w)206 inline bool operator != (qt_widget w) { return rep != w.rep; }
207 };
208
209 // Automagically create definitions for the stuff declared inside qt_widget with
210 // the macro ABSTRACT_NULL(). See src/Kernel/Abstractions/basic.hpp
211 ABSTRACT_NULL_CODE(qt_widget);
212
213 // Needed for the ntuples (see ntuple.h)
214 tm_ostream& operator << (tm_ostream& out, qt_widget w);
215
216 /*! Casting form qt_widget to widget */
abstract(qt_widget w)217 inline widget abstract (qt_widget w) { return widget (w.rep); }
218
219 /*! Casting from widget to qt_widget */
concrete(widget w)220 inline qt_widget concrete (widget w) {
221 return qt_widget (static_cast<qt_widget_rep*> (w.rep));
222 }
223
224 #endif // defined QT_WIDGET_HPP
225