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