OSDN Git Service

828a5ca06bc388d71ed5eda94ea99191a6180862
[ring-lang-081/ring.git] / docs / en / target / codegenerator.txt
1 .. index:: 
2         single: Code Generator; Introduction
3
4 ============================================
5 Code Generator for wrapping C/C++ Libraries 
6 ============================================
7
8 In this chapter we will learn how to use the code generator to wrap C/C++ Libraries 
9 to use it in our Ring applications.
10
11 .. index:: 
12         pair: Code Generator; Using the tool
13
14 Using the tool
15 ==============
16
17 The code generator program is parsec.ring that can be executed as any ring code using the
18 ring language.
19
20 URL : https://github.com/ring-lang/ring/tree/master/extensions/codegen
21
22 for example to read a configuration file called test.cf to generate the source code file test.c
23 run parsec.ring as in the next command
24
25 .. code-block:: ring
26
27         ring parsec.ring test.cf test.c
28
29 .. index:: 
30         pair: Code Generator; Configuration file
31
32
33 Configuration file 
34 ==================
35
36 The configuration file (*.cf) is the input file that we pass to the code generator. This file 
37 determine the functions prototypes that we need to use from a C/C++ library.
38
39 Writing configuration files is simple according to the next rules
40
41 .. index:: 
42         pair: Code Generator; function prototype
43
44 Using the function prototype
45 ============================
46
47 * To generate code that wraps a C function, we just write the C function prototype.
48
49 Example:
50
51 .. code-block:: ring
52
53         ALLEGRO_DISPLAY *al_create_display(int w, int h)
54         void al_destroy_display(ALLEGRO_DISPLAY *display)
55         int al_get_new_display_flags(void)
56         void al_set_new_display_flags(int flags)
57         int al_get_new_display_option(int option, int *importance)
58
59 The previous example will guide the code generator to generate 5 functions that wraps the 
60 al_create_display(), al_destroy_display(), al_get_new_display_flags(), al_set_new_diplay_flas()
61 and al_get_new_display_option() functions.
62
63 The generated code will be as in the next example
64
65 .. code-block:: ring
66
67         RING_FUNC(ring_al_create_display)
68         {
69                 if ( RING_API_PARACOUNT != 2 ) {
70                         RING_API_ERROR(RING_API_MISS2PARA);
71                         return ;
72                 }
73                 if ( ! RING_API_ISNUMBER(1) ) {
74                         RING_API_ERROR(RING_API_BADPARATYPE);
75                         return ;
76                 }
77                 if ( ! RING_API_ISNUMBER(2) ) {
78                         RING_API_ERROR(RING_API_BADPARATYPE);
79                         return ;
80                 }
81                 RING_API_RETCPOINTER(al_create_display( (int ) RING_API_GETNUMBER(1),
82                                          (int ) RING_API_GETNUMBER(2)),"ALLEGRO_DISPLAY");
83         }
84
85
86         RING_FUNC(ring_al_destroy_display)
87         {
88           if ( RING_API_PARACOUNT != 1 ) {
89                 RING_API_ERROR(RING_API_MISS1PARA);
90                 return ;
91           }
92           if ( ! RING_API_ISPOINTER(1) ) {
93                 RING_API_ERROR(RING_API_BADPARATYPE);
94                 return ;
95           }
96           al_destroy_display((ALLEGRO_DISPLAY *) RING_API_GETCPOINTER(1,"ALLEGRO_DISPLAY"));
97         }
98
99
100         RING_FUNC(ring_al_get_new_display_flags)
101         {
102                 if ( RING_API_PARACOUNT != 0 ) {
103                         RING_API_ERROR(RING_API_BADPARACOUNT);
104                         return ;
105                 }
106                 RING_API_RETNUMBER(al_get_new_display_flags());
107         }
108
109
110         RING_FUNC(ring_al_set_new_display_flags)
111         {
112                 if ( RING_API_PARACOUNT != 1 ) {
113                         RING_API_ERROR(RING_API_MISS1PARA);
114                         return ;
115                 }
116                 if ( ! RING_API_ISNUMBER(1) ) {
117                         RING_API_ERROR(RING_API_BADPARATYPE);
118                         return ;
119                 }
120                 al_set_new_display_flags( (int ) RING_API_GETNUMBER(1));
121         }
122
123
124         RING_FUNC(ring_al_get_new_display_option)
125         {
126                 if ( RING_API_PARACOUNT != 2 ) {
127                         RING_API_ERROR(RING_API_MISS2PARA);
128                         return ;
129                 }
130                 if ( ! RING_API_ISNUMBER(1) ) {
131                         RING_API_ERROR(RING_API_BADPARATYPE);
132                         return ;
133                 }
134                 if ( ! RING_API_ISSTRING(2) ) {
135                         RING_API_ERROR(RING_API_BADPARATYPE);
136                         return ;
137                 }
138                 RING_API_RETNUMBER(al_get_new_display_option( (int ) RING_API_GETNUMBER(1),
139                                         RING_API_GETINTPOINTER(2)));
140                 RING_API_ACCEPTINTVALUE(2) ;
141         }
142
143 from the previous example we can see how much of time and effort is saved using the Code Generator.
144
145 .. index:: 
146         pair: Code Generator; Adding code to the generated code
147
148 Adding code to the generated code
149 =================================
150         
151 * To generate code directly type it between <code> and </code>
152
153 Example :
154
155 .. code-block:: ring
156
157         <code>
158                 /* some C code will be written here */
159         </code>
160
161 We use this feature when we need to do something without the help of the code generator. for
162 example including header files and defining constants using Macro.
163
164 .. index:: 
165         pair: Code Generator; Prefix for Functions Names
166
167 Prefix for Functions Names 
168 ==========================
169
170 * To determine a prefix in all of the functions names type it between <funcstart> and </funcstart>
171         for example when we wrap the Allegro game programming library and we need all of the library 
172         functions to start with "al" we type the next code in the configuration file
173
174 .. code-block:: ring
175
176         <funcstart>
177         al
178         </funcstart>
179
180 .. index:: 
181         pair: Code Generator; Wrap structures
182
183 Generate function to wrap structures
184 ====================================
185
186 * To generate functions that wrap structures (create/delete/get structure members)
187 just type the structures names between  <struct> and </struct> also after the structure name
188 you can type the structure members between { } separated by comma.
189
190 Example 
191
192 .. code-block:: ring
193
194         <struct>
195         ALLEGRO_COLOR
196         ALLEGRO_EVENT { type , keyboard.keycode , mouse.x , mouse.y }
197         </struct>
198
199 from the previous example we will generate two function to create/delete the structure ALLEGRO_COLOR
200 Also we will generate two functions to create/delete the structure ALLEGRO_EVENT and four functions
201 to get the structure ALLEGRO_EVENT members (type, keyboard.keycode, mouse.x, mouse.y).
202
203 .. index:: 
204         pair: Code Generator; Determine Structure Members Types
205
206 Determine Structure Members Types
207 =================================
208
209 You can determine the pointer name before the structure member name.
210
211 Example:
212
213 .. code-block:: none
214
215         SDL_Surface {flags,SDL_PixelFormat *format,w,h,pitch,void *pixels}
216
217 .. index:: 
218         pair: Code Generator; Defining Constants
219
220 Defining Constants
221 ==================
222
223 You can define constants using <constant> and </constant>
224
225 The generator will generate the required functions to get the constant values
226
227 And will define the constants to be used with the same name in Ring code using *.rh file that
228 will be generated too.
229
230 rh = Ring Header
231
232 Example:
233
234 .. code-block:: ring
235
236         <constant>
237         MIX_DEFAULT_FORMAT
238         SDL_QUIT
239         SDL_BUTTON_LEFT
240         SDL_BUTTON_MIDDLE
241         SDL_BUTTON_RIGHT
242         </constant>
243
244 .. note:: You will need to pass the *.rh file name to parsec.ring after the generated source file name.
245
246 Example:
247
248 .. code-block:: ring
249
250         ring ..\codegen\parsec.ring libsdl.cf ring_libsdl.c ring_libsdl.rh
251
252 .. index:: 
253         pair: Code Generator; Register New Functions
254
255 Register New Functions
256 ======================
257
258 We can register functions by typing the function prototype between <register> and </register>
259 We need this feature only when we don't provide the function prototype as input directly where
260 we need to write the code of this function.
261
262 Example:
263
264 .. code-block:: ring
265
266         <register>
267         void al_exit(void)
268         </register>
269
270         <code>
271         RING_FUNC(ring_al_exit)
272         {
273                 if ( RING_API_PARACOUNT != 0 ) {
274                         RING_API_ERROR(RING_API_BADPARACOUNT);
275                         return ;
276         }
277         exit(0);
278         }
279         </code>
280
281 In the previous example we register the al_exit() function. This function is not part of the Allegro
282 Library, it's just an extra function that we need to add. Then the code if this function is written
283 inside <code> and </code>. This function call the exit() function from the C language library.
284
285 .. index:: 
286         pair: Code Generator; Comments in configuration file
287
288 Writing comments in the configuration file
289 ==========================================
290
291 * To type comments just type it between <comment> and </comment>
292
293 Example:
294
295 .. code-block:: ring
296
297         <comment>
298         configuration files
299         </comment>
300
301 .. index:: 
302         pair: Code Generator; Executing code during code generation
303
304 Executing code during code generation
305 =====================================
306
307 * To ask from the code generator to execute Ring code during reading the configuration file, just 
308 write the code between <runcode> and </runcode>
309
310 Example:
311
312 .. code-block:: ring
313
314         <runcode>
315         aNumberTypes + "al_fixed"
316         </runcode>
317
318 The previoud line of code add the string "al_fixed" to the list aNumberTypes, This list contains 
319 types that can be considered as numbers when the code generator find it in the function prototype.
320
321 .. index:: 
322         pair: Code Generator; Enum and Numbers
323
324 Enum and Numbers
325 ================
326
327 We have the list aEnumTypes to use for adding each Enumeration we uses in the functions prototype.
328
329 Example:
330
331 .. code-block:: ring
332
333         <runcode>
334         aNumberTypes + "qreal"
335         aNumberTypes + "qint64"
336         aEnumTypes + "Qt::GestureType"
337         aEnumTypes + "Qt::GestureFlag"
338         </runcode>
339
340
341 .. index:: 
342         pair: Code Generator; Filtering using Expressions
343
344 Filtering using Expressions
345 ===========================
346
347 Using <filter> and </filter> we can include/exclude parts of the configuration file
348 based on a condition, for example 
349
350 .. code-block:: ring
351
352                 <filter> iswindows() 
353                         ... functions related to windows
354                 </filter>
355
356 .. index:: 
357         pair: Code Generator; Constants Type
358
359 Constants Type
360 ==============
361
362 The default type for constant is Number. 
363 But Some constants may be another type, for example (pointer : void *)
364
365 Before using <constant> and </constant> we can use <runcode> and </runcode>
366 to determine the constant type using two global variables used by the code generator.
367
368 The first variable is $nDefaultConstantType which can be
369 * C_CONSTANT_TYPE_NUMBER        
370 * C_CONSTANT_TYPE_STRING
371 * C_CONSTANT_TYPE_POINTER
372
373 If we are using C_CONSTANT_TYPE_POINTER then we will need the second global variable
374 which is $cDefaultConstantPointerType to determine the pointer type.
375
376 Example :
377
378 The next example uses this feature to define constants in the FreeGLUT library
379
380 .. code-block:: ring
381
382         <runcode>
383         $nDefaultConstantType = C_CONSTANT_TYPE_POINTER 
384         $cDefaultConstantPointerType = "void"
385         </runcode>
386         <constant>
387                 GLUT_STROKE_ROMAN  
388                 GLUT_STROKE_MONO_ROMAN
389                 GLUT_BITMAP_9_BY_15   
390                 GLUT_BITMAP_8_BY_13   
391                 GLUT_BITMAP_TIMES_ROMAN_10
392                 GLUT_BITMAP_TIMES_ROMAN_24 
393                 GLUT_BITMAP_HELVETICA_10   
394                 GLUT_BITMAP_HELVETICA_12   
395                 GLUT_BITMAP_HELVETICA_18   
396         </constant>
397
398 .. index:: 
399         pair: Code Generator; Configuration file for the Allegro library
400
401 Configuration file for the Allegro Library
402 ==========================================
403
404 The next configuration file enable us to use the Allegro library functions.
405 The configuration file size is less than 1000 lines. When the code generator take this file as input
406 the generated source code file in the C language will be 12000 lines of code!
407
408 We can see this configuration file as a complete example about using the code generator.
409 Also we can use it to know the functions that can be used from RingAllegro when you use it
410 to create 2D games!
411
412 .. code-block:: ring
413
414         <code>
415         #define ALLEGRO_NO_MAGIC_MAIN
416
417         #include <allegro5/allegro.h>
418         #include "allegro5/allegro_image.h"
419         #include <allegro5/allegro_font.h>
420         #include <allegro5/allegro_ttf.h>
421         #include <allegro5/allegro_audio.h>
422         #include <allegro5/allegro_acodec.h>
423         #include <allegro5/allegro_opengl.h>
424         #include <allegro5/allegro_direct3d.h>
425         #include <allegro5/allegro_color.h>
426         #include <allegro5/allegro_memfile.h>
427         #include "allegro5/allegro_native_dialog.h"
428         #include <allegro5/allegro_physfs.h>
429         #include <allegro5/allegro_primitives.h>
430         </code>
431
432         <funcstart>
433         al
434         </funcstart>
435
436         <struct>
437         ALLEGRO_EVENT { type , keyboard.keycode , mouse.x , mouse.y }
438         ALLEGRO_TIMEOUT
439         ALLEGRO_SAMPLE_ID
440         ALLEGRO_COLOR
441         </struct>
442
443         <register>
444         void al_exit(void)
445         </register>
446
447         <code>
448         RING_FUNC(ring_al_exit)
449         {
450                 if ( RING_API_PARACOUNT != 0 ) {
451                         RING_API_ERROR(RING_API_BADPARACOUNT);
452                         return ;
453                 }
454                 exit(0);
455         }
456         </code>
457
458         int al_init(void)
459
460         <comment>
461         configuration files
462         </comment>
463
464         <runcode>
465         aNumberTypes + "al_fixed"
466         </runcode>
467
468         ALLEGRO_CONFIG *al_create_config(void)
469         void al_destroy_config(ALLEGRO_CONFIG *config)
470         ALLEGRO_CONFIG *al_load_config_file(const char *filename)
471         ALLEGRO_CONFIG *al_load_config_file_f(ALLEGRO_FILE *file)
472         bool al_save_config_file(const char *filename, const ALLEGRO_CONFIG *config)
473         bool al_save_config_file_f(ALLEGRO_FILE *file, const ALLEGRO_CONFIG *config)
474         void al_add_config_section(ALLEGRO_CONFIG *config, const char *name)
475
476 .. note:: 
477         we just provided part of the configuration file, for complete copy check the Ring source
478         code distribution.
479
480 .. index:: 
481         pair: Code Generator; Threads Support
482
483 Threads Support
484 ===============
485
486 Next, another part of the configuration file, it's important because we can learn from it how to add
487 threads to our Ring applications by using a threads library.
488
489 The idea is using ring_vm_mutexfunctions() and ring_vm_runcodefromthread() to execute Ring code.
490
491 .. code-block:: ring
492
493         <comment>
494         Threads
495         </comment>
496
497         <code>
498         void *al_func_thread(ALLEGRO_THREAD *thread, void *pPointer) 
499         {  
500                 List *pList;
501                 VM *pVM;
502                 const char *cStr;
503                 pList = (List *) pPointer ;
504                 pVM = (VM *) ring_list_getpointer(pList,2);
505                 cStr = ring_list_getstring(pList,1);
506                 ring_vm_runcodefromthread(pVM,cStr);    
507                 ring_list_delete(pList);
508                 return NULL;
509         }
510
511         RING_FUNC(ring_al_create_thread)
512         {
513                 ALLEGRO_THREAD *pThread;
514                 List *pList;
515                 if ( RING_API_PARACOUNT != 1 ) {
516                         RING_API_ERROR(RING_API_MISS1PARA);
517                         return ;
518                 }
519                 if ( ! RING_API_ISSTRING(1) ) {
520                         RING_API_ERROR(RING_API_BADPARATYPE);
521                         return ;
522                 }       
523                 pList = ring_list_new(0);
524                 ring_list_addstring(pList,RING_API_GETSTRING(1));
525                 ring_list_addpointer(pList,pPointer);
526                 ring_vm_mutexfunctions((VM *) pPointer,al_create_mutex,
527                         al_lock_mutex,al_unlock_mutex,al_destroy_mutex);
528                 pThread = al_create_thread(al_func_thread, pList);
529                 al_start_thread(pThread);
530                 RING_API_RETCPOINTER(pThread,"ALLEGRO_THREAD"); 
531         }
532
533         RING_FUNC(ring_al_run_detached_thread)
534         {
535                 List *pList;
536                 if ( RING_API_PARACOUNT != 1 ) {
537                         RING_API_ERROR(RING_API_MISS1PARA);
538                         return ;
539                 }
540                 if ( ! RING_API_ISSTRING(1) ) {
541                         RING_API_ERROR(RING_API_BADPARATYPE);
542                         return ;
543                 }       
544                 pList = ring_list_new(0);
545                 ring_list_addstring(pList,RING_API_GETSTRING(1));
546                 ring_list_addpointer(pList,pPointer);
547                 ring_vm_mutexfunctions((VM *) pPointer,al_create_mutex,
548                         al_lock_mutex,al_unlock_mutex,al_destroy_mutex);
549                 al_run_detached_thread(al_func_thread, pList);
550         }
551         </code>
552
553         <register>
554         ALLEGRO_THREAD *al_create_thread(void)
555         void al_run_detached_thread(void)
556         </register>
557
558         void al_start_thread(ALLEGRO_THREAD *thread)
559         void al_join_thread(ALLEGRO_THREAD *thread, void **ret_value)
560         void al_set_thread_should_stop(ALLEGRO_THREAD *thread)
561         bool al_get_thread_should_stop(ALLEGRO_THREAD *thread)
562         void al_destroy_thread(ALLEGRO_THREAD *thread)
563         ALLEGRO_MUTEX *al_create_mutex(void)
564         ALLEGRO_MUTEX *al_create_mutex_recursive(void)
565         void al_lock_mutex(ALLEGRO_MUTEX *mutex)
566         void al_unlock_mutex(ALLEGRO_MUTEX *mutex)
567         void al_destroy_mutex(ALLEGRO_MUTEX *mutex)
568         ALLEGRO_COND *al_create_cond(void)
569         void al_destroy_cond(ALLEGRO_COND *cond)
570         void al_wait_cond(ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex)
571
572 .. index:: 
573         pair: Code Generator; Wrapping C++ Classes
574
575 Code Generator Rules for Wrapping C++ Classes
576 =============================================
577
578 * We can define classes between <class> and </class>
579 * Between <class> and <class> we set attributes like 
580   "name, nonew, para, parent, codename, passvmpointer, abstract and staticmethods"
581 * we set the attributes using the style attributename:value or attributename only if no values
582   are required
583 * The "name" attribute determine the class name in C++ code and this name will be the default name
584   in the Ring code
585 * The nonew instruction means that we don't need new/delete methods
586 * The parent attribute determine the parent class name
587 * The codename attribute determine another class name in C++ code 
588 * The passvmpoint instruction means passing the Ring VM pointer to the class constructor when 
589   we create new objects, this happens when we set the codename attribute to a class that we will define
590   and this class need the Virtual Machine pointer (for example to use it to execute Ring code from C++
591   code).
592 * The abstract instruction means that no new method is required for this class "no objects will be created".
593 * The staticmethods instruction means that method doesn't need an object to be called.
594 * Using <nodllstartup> we can avoid #include "ring.h", We need this to write our startup code. 
595 * Using <libinitfunc> we can change the function name that register the library functions
596 * Using <ignorecpointertype> we can ignore pointer type check   
597 * Using the aStringTypes list when can defined new types that treated like const char *
598 * Using the aBeforeReturn list when can define code that is inserted after the variable name when
599   we return that variable from a function
600 * Using the aNewMethodName list we can define another method name to be used in Ring code when we
601   call the C++ method. this feature is required because some C++ method may be identical to Ring
602   Keywords like "load","next","end" and "done".
603 * in method prototype - when we use @ in the method name, we mean that we have the same method with 
604   different parameters (As in C++)
605
606 .. index:: 
607         pair: Code Generator; Using configuration file that wrap C++ library
608
609 Using configuration file that wrap C++ Library
610 ==============================================
611
612 To run the code generator to generate code for using C++ library in the Ring application, we can do
613 that as we did with using C libraries but here we will generate *.cpp file instead of *.c file. Also
614 we will determine another file to be generated (*.ring). This file will contains classes in Ring code
615 that wraps C++ functions for using C++ classes and objects.
616
617 .. code-block:: ring
618
619         ring parsec.ring generator\qt.cf ring_qt.cpp ring_qt.ring
620
621
622 .. index:: 
623         pair: Code Generator; Qt configuration file
624
625 Configuration file for the Qt Framework
626 =======================================
627
628 The next configuration file is used to wrap many Qt classes 
629 The configuration file is around 3500 lines and generate C++ code around 56000 lines and generate 
630 also Ring code around 9000 lines.
631
632 .. code-block:: ring
633
634         <nodllstartup>
635
636         <libinitfunc> ring_qt_start
637
638         <ignorecpointertype>
639
640         <code>
641
642         extern "C" {
643                 #include "ring.h"
644         }
645
646         #include "ring_qt.h"
647         #include "gpushbutton.h"
648         #include "gaction.h"
649         #include "glineedit.h"
650         #include "gtextedit.h"
651         #include "glistwidget.h"
652         #include "gtreeview.h"
653         #include "gtreewidget.h"
654         #include "gcombobox.h"
655         #include "gtabwidget.h"
656         #include "gtablewidget.h"
657         #include "gprogressbar.h"
658         #include "gspinbox.h"
659         #include "gslider.h"
660         #include "gdial.h"
661         #include "gwebview.h"
662         #include "gcheckbox.h"
663         #include "gradiobutton.h"
664         #include "gbuttongroup.h"
665         #include "gvideowidget.h"
666         #include "gtimer.h"
667         #include "gtcpserver.h"
668         #include "giodevice.h"
669         #include "gabstractsocket.h"
670         #include "gtcpsocket.h"
671         #include "gcolordialog.h"
672         #include "gallevents.h"
673         #include <QApplication>
674         #include <QObject>
675         #include <QWidget>
676         #include <QLabel>
677         #include <QPixmap>
678         #include <QIcon>
679         #include <QSize>
680         #include <QPushButton>
681         #include <QMainWindow>
682         #include <QVBoxLayout>
683         #include <QHBoxLayout>
684         #include <QLineEdit>
685         #include <QTextEdit>
686         #include <QListWidget>
687         #include <QTreeView>
688         #include <QDir>
689         #include <QFileSystemModel>
690         #include <QTreeWidget>
691         #include <QTreeWidgetItem>
692         #include <QComboBox>
693         #include <QVariant>
694         #include <QMenuBar>
695         #include <QMenu>
696         #include <QToolBar>
697         #include <QMainWindow>
698         #include <QStatusBar>
699         #include <QDockWidget>
700         #include <QTabWidget>
701         #include <QTableWidget>
702         #include <QTableWidgetItem>
703         #include <QSizePolicy>
704         #include <QFrame>
705         #include <QAbstractScrollArea>
706         #include <QAbstractItemView>
707         #include <QProgressBar>
708         #include <QSpinBox>
709         #include <QSlider>
710         #include <QAbstractSlider>
711         #include <QDateEdit>
712         #include <QDateTimeEdit>
713         #include <QAbstractSpinBox>
714         #include <QDial>
715         #include <QWebView>
716         #include <QUrl>
717         #include <QCheckBox>
718         #include <QRadioButton>
719         #include <QButtonGroup>
720         #include <QMediaPlayer>
721         #include <QMediaPlaylist>
722         #include <QVideoWidget>
723         #include <QPrinter>
724         #include <QAction>
725         #include <QEvent>
726         #include <QMessageBox>
727         #include <QTimer>
728         #include <QFileDialog>
729         #include <QPainter>
730         #include <QPicture>
731         #include <QPen>
732         #include <QColor>
733         #include <QPrinter>
734         #include <QFont>
735         #include <QWebSettings>
736         #include <QBrush>
737         #include <QByteArray>
738         #include <QIODevice>
739         #include <QAbstractSocket>
740         #include <QTcpSocket>
741         #include <QTcpServer>
742         #include <QNetworkProxy>
743         #include <QHostAddress>
744         #include <QHostInfo>
745         #include <QList>
746         #include <QFileInfo>
747         #include <QDirModel>
748         #include <QModelIndex>
749         #include <QFontDialog>
750         #include <QDialog>
751         #include <QTextCursor>
752         #include <QTextBlock>
753         #include <QTextDocumentFragment>
754         #include <QColorDialog>
755         #include <QHeaderView>
756         #include <QStringList>
757         #include <QKeySequence>
758         #include <QLCDNumber>
759         #include <QInputDialog>
760         #include <QDesktopWidget>
761         #include <QRect>
762         #include <QTextDocument>
763
764         extern "C" {
765
766                 #define RING_DLL __declspec(dllexport)
767
768                 RING_DLL void ringlib_init(RingState *pRingState)
769                 {
770
771                         new QApplication(pRingState->argc,pRingState->argv);
772                         ring_qt_start(pRingState) ;
773                 }
774
775         }
776         </code>
777
778
779         <runcode>
780         aStringTypes + "QString"
781         aBeforeReturn + ["QString",".toStdString().c_str()"]
782         aNewMethodName + ["QWebView","load","loadpage"]
783         aNewMethodName + ["QMediaPlaylist","load","loadfile"]
784         aNewMethodName + ["QMediaPlaylist","next","movenext"]
785         aNewMethodName + ["QPainter","end","endpaint"]
786         aNewMethodName + ["QPicture","load","loadfile"]
787         aNewMethodName + ["QLineEdit","end","endtext"]
788         aNewMethodName + ["QDialog","done","donedialog"]
789         aNewMethodName + ["QTextDocument","end","enddoc"]
790         aNewMethodName + ["QTextBlock","next","nextblock"]
791         </runcode>
792
793         <class>
794         name: qApp
795         nonew
796         </class>
797
798         <register>
799         void exec(void)
800         void quit(void)
801         void processEvents(void)
802         </register>
803
804         <code>
805
806         RING_FUNC(ring_qApp_quit)
807         {
808                 qApp->quit();
809         }
810
811         RING_FUNC(ring_qApp_exec)
812         {
813                 qApp->exec();
814         }
815
816         RING_FUNC(ring_qApp_processEvents)
817         {
818                 qApp->processEvents();
819         }
820
821         </code>
822
823         <class>
824         name: QObject
825         para: void
826         </class>
827
828         bool blockSignals(bool block)
829         QObjectList children(void)
830         void dumpObjectInfo(void)
831         void dumpObjectTree(void)
832         bool inherits(const char *className)
833         void installEventFilter(QObject *filterObj)
834         bool isWidgetType(void)
835         void killTimer(int id)
836         void moveToThread(QThread *targetThread)
837         QString objectName(void)
838         QObject *parent(void)
839         QVariant property(const char *name)
840         void removeEventFilter(QObject *obj)
841         void setObjectName(QString)
842         void setParent(QObject *parent)
843         bool setProperty(const char *name, QVariant)
844         bool signalsBlocked(void)
845         int startTimer(int interval)
846         QThread *thread(void)
847         void deleteLater(void)
848
849         <class>
850         name: QWidget
851         para: void
852         parent: QObject
853         </class>
854
855         bool acceptDrops(void)
856         QString accessibleDescription(void)
857         QString accessibleName(void)
858         void activateWindow(void)
859         void addAction(QAction *action)
860         void adjustSize(void)
861         bool autoFillBackground(void)
862         int backgroundRole(void)
863         QSize baseSize(void)
864         QWidget *childAt(int x, int y)
865         QRect childrenRect(void)
866         QRegion childrenRegion(void)
867         void clearFocus(void)
868         void clearMask(void)
869         QMargins contentsMargins(void)
870         QRect contentsRect(void)
871         int contextMenuPolicy(void)
872         QCursor cursor(void)
873         int effectiveWinId(void)
874         void ensurePolished(void)
875         int focusPolicy(void)
876         QWidget *focusProxy(void)
877         QWidget *focusWidget(void)
878         QFont font(void)
879         QFontInfo fontInfo(void)
880         QFontMetrics fontMetrics(void)
881         int foregroundRole(void)
882         QRect frameGeometry(void)
883         QSize frameSize(void)
884         QRect geometry(void)
885         void getContentsMargins(int *left, int *top, int *right, int *bottom)
886         void grabGesture(int gesture, int flags)
887         void grabKeyboard(void)
888         void grabMouse(void)
889         int grabShortcut(QKeySequence , int context)
890         QGraphicsEffect *graphicsEffect(void)
891         QGraphicsProxyWidget *graphicsProxyWidget(void)
892         bool hasFocus(void)
893         bool hasMouseTracking(void)
894         int height(void)
895         int heightForWidth(int w)
896         int inputMethodHints(void)
897         QVariant inputMethodQuery(int query)
898         void insertAction(QAction *before, QAction *action)
899         bool isActiveWindow(void)
900         bool isAncestorOf(QWidget *child)
901         bool isEnabled(void)
902         bool isEnabledTo(QWidget *ancestor)
903         bool isFullScreen(void)
904         bool isHidden(void)
905         bool isMaximized(void)
906         bool isMinimized(void)
907         bool isModal(void)
908         bool isVisible(void)
909         bool isVisibleTo(QWidget *ancestor)
910         bool isWindow(void)
911         bool isWindowModified(void)
912         QLayout *layout(void)
913         int layoutDirection(void)
914         QLocale locale(void)
915         QPoint mapFrom(QWidget *parent, QPoint)
916         QPoint mapFromGlobal(QPoint)
917         QPoint mapFromParent(QPoint)
918         QPoint mapTo(QWidget *parent, QPoint)
919         QPoint mapToGlobal(QPoint pos)
920         QPoint mapToParent(QPoint pos)
921         QRegion mask(void)
922         int maximumHeight(void)
923         QSize maximumSize(void)
924         int maximumWidth(void)
925         int minimumHeight(void)
926         QSize minimumSize(void)
927         int minimumWidth(void)
928         void move(int x, int y)
929         QWidget *nativeParentWidget(void)
930         QWidget *nextInFocusChain(void)
931         QRect normalGeometry(void)
932         void overrideWindowFlags(int flags)
933         QPalette palette(void)
934         QWidget *parentWidget(void)
935         QPoint pos(void)
936         QWidget *previousInFocusChain(void)
937         QRect rect(void)
938         void releaseKeyboard(void)
939         void releaseMouse(void)
940         void releaseShortcut(int id)
941         void removeAction(QAction *action)
942         void render(QPaintDevice *target, QPoint,QRegion, int)
943         void repaint(int x, int y, int w, int h)
944         void resize(int w, int h)
945         bool restoreGeometry(QByteArray)
946         QByteArray saveGeometry(void)
947         void scroll(int dx, int dy)
948         void setAcceptDrops(bool on)
949         void setAccessibleDescription(QString)
950         void setAccessibleName(QString)
951         void setAttribute(int attribute, bool on)
952         void setAutoFillBackground(bool enabled)
953         void setBackgroundRole(int role)
954         void setBaseSize(int basew, int baseh)
955         void setContentsMargins(int left, int top, int right, int bottom)
956         void setContextMenuPolicy(int policy)
957         void setCursor(QCursor)
958         void setFixedHeight(int h)
959         void setFixedSize(int w, int h)
960         void setFixedWidth(int w)
961         void setFocus(int reason)
962         void setFocusPolicy(int policy)
963         void setFocusProxy(QWidget *w)
964         void setFont(QFont)
965         void setForegroundRole(int role)
966         void setGeometry(int x, int y, int w, int h)
967         void setGraphicsEffect(QGraphicsEffect *effect)
968         void setInputMethodHints(int hints)
969         void setLayout(QLayout *layout)
970         void setLayoutDirection(int direction)
971         void setLocale(QLocale)
972         void setMask(QBitmap)
973         void setMaximumHeight(int maxh)
974         void setMaximumSize(int maxw, int maxh)
975         void setMaximumWidth(int maxw)
976         void setMinimumHeight(int minh)
977         void setMinimumSize(int minw, int minh)
978         void setMinimumWidth(int minw)
979         void setMouseTracking(bool enable)
980         void setPalette(QPalette)
981         void setParent(QWidget *parent)
982         void setShortcutAutoRepeat(int id, bool enable)
983         void setShortcutEnabled(int id, bool enable)
984         void setSizeIncrement(int w, int h)
985         void setSizePolicy(int horizontal, int vertical)
986         void setStatusTip(QString)
987         void setStyle(QStyle *style)
988         void setToolTip(QString)
989         void setUpdatesEnabled(bool enable)
990         void setWhatsThis(QString)
991         void setWindowFilePath(QString)
992         void setWindowFlags(int type)
993         void setWindowIcon(QIcon)
994         void setWindowIconText(QString)
995         void setWindowModality(int windowModality)
996         void setWindowOpacity(double level)
997         void setWindowRole(QString)
998         void setWindowState(int windowState)
999         QSize size(void)
1000         QSize sizeIncrement(void)
1001         QSizePolicy sizePolicy(void)
1002         void stackUnder(QWidget *w)
1003         QString statusTip(void)
1004         QStyle *style(void)
1005         QString styleSheet(void)
1006         bool testAttribute(int attribute)
1007         QString toolTip(void)
1008         bool underMouse(void)
1009         void ungrabGesture(int gesture)
1010         void unsetCursor(void)
1011         void unsetLayoutDirection(void)
1012         void unsetLocale(void)
1013         void update(int x, int y, int w, int h)
1014         void updateGeometry(void)
1015         bool updatesEnabled(void)
1016         QRegion visibleRegion(void)
1017         QString whatsThis(void)
1018         int width(void)
1019         int winId(void)
1020         QWidget *window(void)
1021         QString windowFilePath(void)
1022         int windowFlags(void)
1023         QIcon windowIcon(void)
1024         QString windowIconText(void)
1025         int windowModality(void)
1026         double windowOpacity(void)
1027         QString windowRole(void)
1028         int windowState(void)
1029         QString windowTitle(void)
1030         int windowType(void)
1031         int x(void)
1032         int y(void)
1033         bool close(void)
1034         void hide(void)
1035         void lower(void)
1036         void raise(void)
1037         void setDisabled(bool disable)
1038         void setEnabled(bool)
1039         void setHidden(bool hidden)
1040         void setStyleSheet(QString)
1041         void setWindowModified(bool)
1042         void setWindowTitle(QString)
1043         void show(void)
1044         void showFullScreen(void)
1045         void showMaximized(void)
1046         void showMinimized(void)
1047         void showNormal(void)
1048         QWidget *find(int id)
1049         QWidget *keyboardGrabber(void)
1050         QWidget *mouseGrabber(void)
1051         void setTabOrder(QWidget *first, QWidget *second)
1052
1053         <class>
1054         name: QLabel
1055         para: QWidget *
1056         parent: QWidget
1057         </class>
1058
1059         int alignment(void)
1060         QWidget *buddy(void)
1061         bool hasScaledContents(void)
1062         bool hasSelectedText(void)
1063         int indent(void)
1064         int margin(void)
1065         QMovie *movie(void)
1066         bool openExternalLinks(void)
1067         QPicture *picture(void)
1068         QPixmap *pixmap(void)
1069         QString selectedText(void)
1070         int selectionStart(void)
1071         void setAlignment(int)
1072         void setBuddy(QWidget *buddy)
1073         void setIndent(int)
1074         void setMargin(int)
1075         void setOpenExternalLinks(bool open)
1076         void setScaledContents(bool)
1077         void setSelection(int start, int length)
1078         void setTextFormat(int)
1079         void setTextInteractionFlags(int flags)
1080         void setWordWrap(bool on)
1081         QString text(void)
1082         int textFormat(void)
1083         int textInteractionFlags(void)
1084         bool wordWrap(void)
1085         void clear(void)
1086         void setMovie(QMovie *movie)
1087         void setNum(double num)
1088         void setPicture(QPicture)
1089         void setPixmap(QPixmap)
1090         void setText(QString)
1091
1092         <class>
1093         name: QPushButton
1094         para: QWidget *
1095         parent: QWidget
1096         codename: GPushButton
1097         passvmpointer
1098         </class>
1099
1100         void setText(const char *)
1101         void setClickEvent(const char *)
1102         void setIcon(QIcon)
1103         void setIconSize(QSize)
1104
1105         <class>
1106         name: QLineEdit
1107         para: QWidget *
1108         parent: QWidget
1109         codename: GLineEdit
1110         passvmpointer
1111         </class>
1112
1113         int alignment(void)
1114         void backspace(void)
1115         QCompleter *completer(void)
1116         QMenu *createStandardContextMenu(void)
1117         void cursorBackward(bool mark, int steps)
1118         void cursorForward(bool mark, int steps)
1119         int cursorMoveStyle(void)
1120         int cursorPosition(void)
1121         int cursorPositionAt(QPoint)
1122         void cursorWordBackward(bool mark)
1123         void cursorWordForward(bool mark)
1124         void del(void)
1125         void deselect(void)
1126         QString displayText(void)
1127         bool dragEnabled(void)
1128         int echoMode(void)
1129         void end(bool mark)
1130         void getTextMargins(int *left, int *top, int *right, int *bottom)
1131         bool hasAcceptableInput(void)
1132         bool hasFrame(void)
1133         bool hasSelectedText(void)
1134         void home(bool mark)
1135         QString inputMask(void)
1136         void insert(QString)
1137         bool isModified(void)
1138         bool isReadOnly(void)
1139         bool isRedoAvailable(void)
1140         bool isUndoAvailable(void)
1141         int maxLength(void)
1142         QString placeholderText(void)
1143         QString selectedText(void)
1144         int selectionStart(void)
1145         void setAlignment(int flag)
1146         void setCompleter(QCompleter *c)
1147         void setCursorMoveStyle(int style)
1148         void setCursorPosition(int)
1149         void setDragEnabled(bool b)
1150         void setEchoMode(int)
1151         void setFrame(bool)
1152         void setInputMask(QString)
1153         void setMaxLength(int)
1154         void setModified(bool)
1155         void setPlaceholderText(QString)
1156         void setReadOnly(bool)
1157         void setSelection(int start, int length)
1158         void setTextMargins(int left, int top, int right, int bottom)
1159         void setValidator(QValidator *v)
1160         QString text(void)
1161         QMargins textMargins(void)
1162         QValidator *validator(void)
1163
1164         void clear(void)
1165         void copy(void) 
1166         void cut(void)
1167         void paste(void)
1168         void redo(void)
1169         void selectAll(void)
1170         void setText(QString)
1171         void undo(void)
1172
1173         void setTextChangedEvent(const char *)
1174         void setcursorPositionChangedEvent(const char *)
1175         void seteditingFinishedEvent(const char *)
1176         void setreturnPressedEvent(const char *)
1177         void setselectionChangedEvent(const char *)
1178         void settextEditedEvent(const char *)
1179
1180 .. note:: 
1181
1182         Most of the content of the previous configuration file is removed from this documentation, 
1183         for a complete version see the Ring source code distribution.
1184
1185 .. index:: 
1186         pair: Code Generator; Static Methods
1187
1188 Static Methods
1189 ==============
1190
1191 Starting from Ring 1.8 the code generator support the staticmethods option.
1192
1193 So the code generator can know that the class doesn't need an object to call the methods.
1194
1195 Example:
1196
1197 .. code-block:: none
1198
1199         <class>
1200         name: QStandardPaths
1201         para: void
1202         nonew
1203         staticmethods
1204         </class>
1205
1206         QString displayName(QStandardPaths::StandardLocation type)
1207         QString findExecutable(QString executableName, QStringList paths))
1208
1209 .. index:: 
1210         pair: Code Generator; Loading Files
1211
1212 Loading Files
1213 =============
1214
1215 Starting from Ring 1.9 the code generator support the <loadfile> command.
1216
1217 .. code-block:: ring
1218
1219         <loadfile> filename.cf
1220
1221 This is useful to separate the extension configuration file to many files
1222
1223 Example:
1224
1225 The file : qt_module_network.cf in the RingQt Extension
1226
1227 .. code-block:: ring
1228
1229         <comment>
1230                                         Module (network)
1231         </comment>
1232
1233         <loadfile> qabstractsocket.cf
1234         <loadfile> qnetworkproxy.cf
1235         <loadfile> qtcpsocket.cf
1236         <loadfile> qtcpserver.cf
1237         <loadfile> qhostaddress.cf
1238         <loadfile> qhostinfo.cf
1239         <loadfile> qnetworkrequest.cf
1240         <loadfile> qnetworkaccessmanager.cf
1241         <loadfile> qnetworkreply.cf
1242
1243 .. index:: 
1244         pair: Code Generator; Managed Classes
1245
1246 Managed Classes
1247 ===============
1248
1249 Starting from Ring 1.9 the code generator support the <managed> option when defining classes.
1250
1251 Using this option, the generator will use RING_API_RETMANAGEDCPOINTER() to return the C pointer.
1252
1253 So the Garbage Collector will manage these C pointers.
1254
1255 Example
1256
1257 .. code-block:: ring
1258
1259         <class>
1260         name: QFont
1261         para: QString, int, int, bool
1262         managed
1263         </class>
1264
1265
1266 .. index:: 
1267         pair: Code Generator; Configuration Files Examples
1268
1269 Configuration Files Examples
1270 ============================
1271
1272 You can learn from the next examples
1273
1274 * RingAllegro : https://github.com/ring-lang/ring/blob/master/extensions/ringallegro/allegro.cf
1275 * RingQt : https://github.com/ring-lang/ring/blob/master/extensions/ringqt/classes/qt.cf
1276 * RingLibSDL : https://github.com/ring-lang/ring/blob/master/extensions/ringsdl/libsdl.cf
1277
1278 After modifying the configuration file, You will need to generate the code, You can learn from
1279 the next examples
1280
1281 * RingAllegro : https://github.com/ring-lang/ring/blob/master/extensions/ringallegro/gencode.bat
1282 * RingQt : https://github.com/ring-lang/ring/blob/master/extensions/ringqt/gencode.bat
1283 * RingLibSDL : https://github.com/ring-lang/ring/blob/master/extensions/ringsdl/gencode.bat
1284
1285 After generating the code, You will need to build the library, You can learn from the next examples
1286
1287 * RingAllegro : https://github.com/ring-lang/ring/blob/master/extensions/ringallegro/buildvc.bat
1288 * RingQt : https://github.com/ring-lang/ring/blob/master/extensions/ringqt/buildmingw32.bat
1289 * RingLibSDL : https://github.com/ring-lang/ring/blob/master/extensions/ringsdl/buildvc.bat