diff -Nru gambas3-3.8.3/acinclude.m4 gambas3-3.8.4/acinclude.m4 --- gambas3-3.8.3/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/app/acinclude.m4 gambas3-3.8.4/app/acinclude.m4 --- gambas3-3.8.3/app/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/app/desktop/gambas3.appdata.xml gambas3-3.8.4/app/desktop/gambas3.appdata.xml --- gambas3-3.8.3/app/desktop/gambas3.appdata.xml 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/desktop/gambas3.appdata.xml 2015-12-22 04:46:12.000000000 +0000 @@ -5,13 +5,15 @@ GPL-2.0+ IDE for the Gambas development environment -

- Gambas is a development environment based on a Basic interpreter, similar to Visual Basic. This application provides a graphical IDE to assist in the creation of programs with Gambas. -

+

Gambas is a free development environment and a full powerful development platform based on a Basic interpreter with object extensions, as easy as Visual Basic. This application provides a graphical IDE, with a database manager, an image editor, and a report designer, to assist in the creation of programs with Gambas.

http://gambas.sourceforge.net/2014-07-26.png http://gambas.sourceforge.net/ gambas@users.sourceforge.net + + HiDpiIcon + ModernToolkit + diff -Nru gambas3-3.8.3/app/src/gambas3/img/broken.svg gambas3-3.8.4/app/src/gambas3/img/broken.svg --- gambas3-3.8.3/app/src/gambas3/img/broken.svg 1970-01-01 00:00:00.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/img/broken.svg 2015-12-22 04:46:12.000000000 +0000 @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff -Nru gambas3-3.8.3/app/src/gambas3/.lang/es_ES.po gambas3-3.8.4/app/src/gambas3/.lang/es_ES.po --- gambas3-3.8.3/app/src/gambas3/.lang/es_ES.po 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.lang/es_ES.po 2015-12-22 04:46:12.000000000 +0000 @@ -2,6 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: gambas3 3.8.90\n" +"POT-Creation-Date: 2015-09-29 17:11 UTC\n" "PO-Revision-Date: 2015-09-26 11:58 UTC\n" "Last-Translator: Jesus \n" "Language: es_ES\n" @@ -181,10 +182,12 @@ msgid "Classes" msgstr "Clases" +#: CComponent.class:1645 FCreateFile.class:132 FDebugInfo.class:51 #: FMain.form:785 msgid "Class" msgstr "Clase" +#: CComponent.class:1647 FConnectionEditor.class:295 FMakeInstall.form:284 #: FProjectProperty.form:356 FPublish.form:125 FSoftwareFarm.form:312 msgid "Description" msgstr "Descripción" @@ -201,7 +204,7 @@ msgid "Author" msgstr "Autor" -#: CComponent.class:1687 FProjectProperty.form:368 +#: CComponent.class:1687 FAbout.class:192 FProjectProperty.form:368 msgid "Authors" msgstr "Autores" @@ -681,7 +684,8 @@ msgid "here" msgstr "aquí" -#: FSearch.class:97 FSelectIcon.form:31 Project.module:1825 +#: CProjectTree.class:285 FHelpShortcut.form:22 FMain.form:372 FSearch.class:97 +#: FSelectIcon.form:31 Project.module:1825 msgid "Project" msgstr "Proyecto" @@ -749,6 +753,25 @@ msgid "Unable to install source directory" msgstr "Imposible instalar el directorio de fuentes" +#: CWaitingAnimation.class:63 FColorChooser.form:76 FComponentChooser.form:98 +#: FConflict.class:209 FConnectionEditor.class:431 FCrash.form:96 +#: FCreateFile.form:227 FDebugExpr.form:46 FDebugInfo.form:270 +#: FEditor.class:2235 FExportData.class:126 FFarmConfig.form:38 +#: FFarmLogin.form:126 FFarmRegister.form:141 FFarmRequest.form:43 +#: FFieldChooser.form:144 FFileProperty.class:142 FFontChooser.form:40 +#: FForm.class:3216 FGotoLine.form:23 FHelpBrowser.form:60 +#: FImageEditor.class:394 FImageOffsetSelection.form:33 FImageQuality.form:30 +#: FImageResize.form:49 FImageRotate.form:32 FList.form:121 FMain.class:226 +#: FMakeInstall.class:333 FMenu.form:404 FNewConnection.form:301 +#: FNewTable.form:86 FNewTranslation.form:21 FOption.class:717 +#: FPasteSpecial.form:86 FPasteTable.form:107 FProjectChooser.form:73 +#: FProjectProperty.form:976 FProjectVersion.class:211 FProxy.form:57 +#: FPublish.class:271 FReportBorderChooser.form:48 +#: FReportBoxShadowChooser.form:27 FReportBrushChooser.form:36 +#: FReportCoordChooser.form:26 FReportPaddingChooser.form:75 FSave.form:28 +#: FSaveProjectAs.form:76 FSearch.class:893 FSelectComponent.form:39 +#: FSelectExtraFile.form:43 FSelectIcon.form:87 FSnippet.form:57 +#: FSoftwareFarm.class:480 FTableChooser.form:68 FText.form:41 #: FTextEditor.class:673 FTranslate.class:562 Project.module:502 msgid "Cancel" msgstr "Cancelar" @@ -778,9 +801,24 @@ msgstr "en &1:&2." #: Design.module:392 -msgid "The program has returned\nthe value: &1" -msgstr "El programa retornó\nel valor: &1" +msgid "" +"The program has returned\n" +"the value: &1" +msgstr "" +"El programa retornó\n" +"el valor: &1" +#: Design.module:458 FColorChooser.form:70 FConnectionEditor.class:637 +#: FCrash.form:90 FCreateFile.form:233 FFarmConfig.form:33 FFarmLogin.form:121 +#: FFieldChooser.form:138 FFontChooser.form:34 FGotoLine.form:17 +#: FImageOffsetSelection.form:27 FImageQuality.form:24 FImageResize.form:103 +#: FImageRotate.form:26 FList.form:115 FMakeInstall.class:266 FMenu.form:399 +#: FNewConnection.form:295 FNewTable.form:80 FNewTranslation.form:15 +#: FPasteSpecial.form:80 FProjectProperty.form:970 FProxy.form:63 +#: FReportBorderChooser.form:54 FReportBoxShadowChooser.form:33 +#: FReportBrushChooser.form:42 FReportCoordChooser.form:32 +#: FReportPaddingChooser.form:69 FSelectComponent.form:34 +#: FSelectExtraFile.form:37 FSelectIcon.form:82 FSnippet.form:51 #: FTableChooser.form:62 FText.form:35 msgid "OK" msgstr "-" @@ -789,31 +827,45 @@ msgid "Output terminal" msgstr "Terminal de salida" -#: Design.module:924 +#: Design.module:927 msgid "No terminal emulator found." msgstr "No se encontró emulador de terminal." -#: FAbout.class:202 +#: FAbout.class:212 FAboutOld.class:205 msgid "Financial support" msgstr "Apoyo económico" -#: FAbout.class:246 -msgid "Thanks to" -msgstr "Gracias a" - -#: FAbout.form:20 FMain.form:1125 FWelcome.class:73 +#: FAbout.form:12 FAboutOld.form:20 FMain.form:1125 FWelcome.class:73 msgid "About Gambas" msgstr "Acerca de Gambas" -#: FAbout.form:48 -msgid "Gambas
\nAlmost
\nMeans
\nB A S I C !" -msgstr "-" +#: FAbout.form:25 FAboutOld.form:60 +msgid "" +"

Licence

\n" +"\n" +"

This program is FREE SOFTWARE; you can redistribute it AND/OR modify it under the terms of the GNU General Public License as published by the Free Software Foundation ; either version 2, or (at your option) any later version.

\n" +"\n" +"

This program is distributed in the hope that it will be useful but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

\n" +msgstr "" +"

Licencia

\n" +"\n" +"

This program is FREE SOFTWARE; you can redistribute it AND/OR modify it under the terms of the GNU General Public License as published by the Free Software Foundation ; either version 2, or (at your option) any later version.

\n" +"\n" +"

This program is distributed in the hope that it will be useful but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

\n" -#: FAbout.form:61 -msgid "

Licence

\n\n

This program is FREE SOFTWARE; you can redistribute it AND/OR modify it under the terms of the GNU General Public License as published by the Free Software Foundation ; either version 2, or (at your option) any later version.

\n\n

This program is distributed in the hope that it will be useful but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

\n" -msgstr "

Licencia

\n\n

This program is FREE SOFTWARE; you can redistribute it AND/OR modify it under the terms of the GNU General Public License as published by the Free Software Foundation ; either version 2, or (at your option) any later version.

\n\n

This program is distributed in the hope that it will be useful but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

\n" +#: FAboutOld.class:245 +msgid "Thanks to" +msgstr "Gracias a" -#: FAbout.form:67 +#: FAboutOld.form:47 +msgid "" +"Gambas
\n" +"Almost
\n" +"Means
\n" +"B A S I C !" +msgstr "-" + +#: FAboutOld.form:66 msgid "

Authors

\n" msgstr "

Autores

\n" @@ -885,6 +937,8 @@ msgid "Show deprecated components" msgstr "Mostrar componentes obsoletos" +#: FComponentChooser.form:104 FConnectionEditor.form:110 FEditor.form:344 +#: FForm.form:427 FHelpBrowser.form:66 FImageEditor.form:339 FMain.form:331 #: FTextEditor.form:306 FTranslate.form:77 msgid "Reload" msgstr "Recargar" @@ -906,8 +960,12 @@ msgstr "&Editar" #: FConflict.class:23 -msgid "This file is in conflict with the revision #&1.\nYou must resolve the conflict in order to use the file." -msgstr "Este archivo está en conflicto con la revisión #&1.\nDebe resolver el conflicto para usar el archivo." +msgid "" +"This file is in conflict with the revision #&1.\n" +"You must resolve the conflict in order to use the file." +msgstr "" +"Este archivo está en conflicto con la revisión #&1.\n" +"Debe resolver el conflicto para usar el archivo." #: FConflict.class:109 msgid "Unable to load file:" @@ -917,13 +975,18 @@ msgid "Text" msgstr "Texto" +#: FConflict.class:153 FCreateFile.class:142 FMain.form:816 #: FReportBrushChooser.form:49 Project.module:224 msgid "Image" msgstr "Imagen" #: FConflict.class:209 -msgid "The file has been modified.\nDo you really want to close the dialog?" -msgstr "Los archivos han sido modificados.\n¿Realmente quiere cerrar el dialogo?" +msgid "" +"The file has been modified.\n" +"Do you really want to close the dialog?" +msgstr "" +"Los archivos han sido modificados.\n" +"¿Realmente quiere cerrar el dialogo?" #: FConflict.class:237 msgid "Some conflicts are not yet resolved." @@ -934,8 +997,12 @@ msgstr "Incapaz de resolver conflicto." #: FConflict.class:271 -msgid "The file has been modified.\nDo you really want to open another file?" -msgstr "Los archivos han sido modificados.\n¿Realmente quiere abrir otro archivo?" +msgid "" +"The file has been modified.\n" +"Do you really want to open another file?" +msgstr "" +"Los archivos han sido modificados.\n" +"¿Realmente quiere abrir otro archivo?" #: FConflict.class:279 msgid "Conflict files" @@ -945,34 +1012,50 @@ msgid "Version conflict" msgstr "Conflicto de versión" -#: FOutput.form:63 FProjectVersion.form:234 FTextEditor.form:134 +#: FConflict.form:70 FConnectionEditor.form:379 FEditor.form:159 FForm.form:185 +#: FImageEditor.form:129 FMain.form:901 FMenu.form:111 FOutput.form:63 +#: FProjectVersion.form:234 FTextEditor.form:134 msgid "Cut" msgstr "Cortar" -#: FProjectVersion.form:240 FSystemInfo.form:62 FTextEditor.form:141 +#: FConflict.form:76 FConnectionEditor.form:149 FEditor.form:166 FForm.form:192 +#: FImageEditor.form:137 FList.form:92 FMain.form:908 FMakeInstall.form:893 +#: FMenu.form:117 FOutput.form:70 FProjectVersion.form:240 FSystemInfo.form:62 +#: FTextEditor.form:141 msgid "Copy" msgstr "Copiar" -#: FProjectVersion.form:246 FTextEditor.form:148 +#: FConflict.form:82 FConnectionEditor.form:157 FEditor.form:173 FForm.form:205 +#: FImageEditor.form:144 FList.form:98 FMain.form:915 FMenu.form:123 +#: FOutput.form:77 FPasteTable.form:101 FProjectVersion.form:246 +#: FTextEditor.form:148 msgid "Paste" msgstr "Pegar" +#: FConflict.form:88 FConnectionEditor.form:407 FEditor.form:142 +#: FFieldChooser.form:127 FForm.form:168 FImageEditor.form:110 FList.form:104 +#: FOption.form:903 FOutput.form:46 FProjectVersion.form:252 #: FTextEditor.form:117 msgid "Undo" msgstr "Deshacer" -#: FProjectVersion.form:258 FTextEditor.form:124 +#: FConflict.form:94 FConnectionEditor.form:414 FEditor.form:149 FForm.form:175 +#: FImageEditor.form:118 FOutput.form:53 FProjectVersion.form:258 +#: FTextEditor.form:124 msgid "Redo" msgstr "Rehacer" +#: FConflict.form:100 FEditor.form:513 FMenu.form:133 FProjectVersion.form:264 #: FTextEditor.form:436 msgid "Indent" msgstr "Indentar" +#: FConflict.form:106 FEditor.form:521 FMenu.form:139 FProjectVersion.form:270 #: FTextEditor.form:444 msgid "Unindent" msgstr "Desindentar" +#: FConflict.form:141 FMain.form:324 FOpenProject.form:35 #: FProjectChooser.form:85 msgid "Open" msgstr "Abrir" @@ -981,6 +1064,8 @@ msgid "Open..." msgstr "Abrir..." +#: FConflict.form:149 FConnectionEditor.form:102 FEditor.form:350 +#: FForm.form:433 FImageEditor.form:346 FMain.form:340 FMenu.class:72 #: FSaveProjectAs.form:82 FTextEditor.form:312 msgid "Save" msgstr "Guardar" @@ -989,14 +1074,20 @@ msgid "Solve" msgstr "Resolver" +#: FConflict.form:166 FDebugInfo.form:278 FEditor.form:337 +#: FFileProperty.form:75 FForm.form:420 FImageEditor.form:353 FMain.form:357 +#: FPatch.form:88 FProjectVersion.form:322 FSystemInfo.form:68 #: FTextEditor.form:319 FTips.form:83 FTranslate.form:309 msgid "Close" msgstr "Cerrar" +#: FConnectionEditor.class:46 FCreateFile.form:78 FDebugInfo.class:38 +#: FMakeInstall.form:235 FNewConnection.form:68 FNewTable.form:33 #: FOption.form:258 msgid "Name" msgstr "Nombre" +#: FConnectionEditor.class:51 FCreateFile.form:129 FCreateProjectOld.form:98 #: FDebugInfo.class:76 FNewConnection.form:82 FNewTable.form:48 FProxy.form:27 msgid "Type" msgstr "Tipo" @@ -1057,7 +1148,7 @@ msgid "Boolean" msgstr "Boolean" -#: MConnection.module:124 +#: FConnectionEditor.class:763 FProjectVersion.class:290 MConnection.module:124 msgid "Date" msgstr "Fecha" @@ -1145,6 +1236,8 @@ msgid "Delete table" msgstr "Borrar tabla" +#: FConnectionEditor.form:133 FMain.form:1033 FMakeInstall.form:734 +#: FOption.form:1121 FProjectProperty.form:562 FPublish.form:268 #: FSoftwareFarm.form:411 msgid "Remove" msgstr "Eliminar" @@ -1169,6 +1262,7 @@ msgid "Import text file" msgstr "Importar archivo de texto" +#: FConnectionEditor.form:165 FImportTable.form:48 FOption.form:1129 #: FTranslate.form:329 msgid "Import" msgstr "Importar" @@ -1181,14 +1275,17 @@ msgid "Fields" msgstr "Campos" +#: FConnectionEditor.form:233 FMain.class:2108 FMakeInstall.form:728 #: FOption.form:1352 FProjectProperty.form:638 FPublish.form:158 msgid "Add" msgstr "Añadir" +#: FConnectionEditor.form:247 FList.form:76 FMakeInstall.form:746 #: FPublish.form:280 msgid "Down" msgstr "Abajo" +#: FConnectionEditor.form:254 FList.form:70 FMakeInstall.form:740 #: FPublish.form:274 msgid "Up" msgstr "Arriba" @@ -1213,6 +1310,7 @@ msgid "New query" msgstr "Nueva consulta" +#: FConnectionEditor.form:365 FCreateFile.form:53 FMain.form:761 #: FOption.form:1107 FTranslate.form:72 msgid "New" msgstr "Nuevo" @@ -1221,6 +1319,7 @@ msgid "Remove query" msgstr "Eliminar consulta" +#: FConnectionEditor.form:452 FDebugExpr.form:28 FEditor.form:138 #: FForm.form:164 FImageEditor.form:105 FOption.form:1114 FTextEditor.form:113 msgid "Edit" msgstr "Editar" @@ -1233,6 +1332,8 @@ msgid "Export" msgstr "Exportar" +#: FConnectionEditor.form:485 FForm.form:212 FList.form:64 FMain.form:929 +#: FMenu.form:101 FNewConnection.class:349 FOption.class:882 #: FSoftwareFarm.class:581 FTranslate.form:82 msgid "Delete" msgstr "Borrar" @@ -1325,6 +1426,7 @@ msgid "New file" msgstr "Nuevo archivo" +#: FCreateFile.form:88 FCreateProjectOld.form:274 FImportTable.form:58 #: FMakePatch.form:66 FProjectProperty.form:733 FSearch.form:100 msgid "Options" msgstr "Opciones" @@ -1421,6 +1523,7 @@ msgid "Project is translatable" msgstr "El proyecto es traducible" +#: FCreateProject.form:159 FCreateProjectOld.form:426 FProjectChooser.form:80 #: ProjectBox.class:291 msgid "Open in another window" msgstr "Abrir en otra ventana" @@ -1458,8 +1561,12 @@ msgstr "Aplicación Web CGI" #: FCreateProjectOld.form:259 -msgid "Application stored in a\nSubversion repository" -msgstr "Aplicación almacenada en\nun repositorio Subversion" +msgid "" +"Application stored in a\n" +"Subversion repository" +msgstr "" +"Aplicación almacenada en\n" +"un repositorio Subversion" #: FCreateProjectOld.form:288 msgid "Internationalization" @@ -1569,6 +1676,7 @@ msgid "native code" msgstr "código nativo" +#: FDebugInfo.class:560 FImageProperty.form:368 FList.form:86 #: FMakeInstall.form:752 FOption.class:717 FOutput.form:84 FPublish.form:170 msgid "Clear" msgstr "Limpiar" @@ -1677,9 +1785,16 @@ msgid "Stack backtrace" msgstr "Trazado de la pila" +#: FEditor.class:2235 FImageEditor.class:394 FMain.class:2596 #: FTextEditor.class:673 -msgid "The file has been modified.\n\nAll your changes will be lost." -msgstr "El archivo ha sido modificado.\n\nTodos sus cambios se perderán." +msgid "" +"The file has been modified.\n" +"\n" +"All your changes will be lost." +msgstr "" +"El archivo ha sido modificado.\n" +"\n" +"Todos sus cambios se perderán." #: FEditor.class:2695 FTextEditor.class:1085 msgid "(Declarations)" @@ -1830,8 +1945,14 @@ msgstr "&Sobrescribir" #: FExportData.class:126 -msgid "This file already exists.\n\nDo you want to overwrite it?" -msgstr "Este archivo ya existe.\n\n¿Realmente quiere sobrescribirlo?" +msgid "" +"This file already exists.\n" +"\n" +"Do you want to overwrite it?" +msgstr "" +"Este archivo ya existe.\n" +"\n" +"¿Realmente quiere sobrescribirlo?" #: FExportData.form:31 FImportTable.form:101 msgid "Delimiter character" @@ -1865,10 +1986,12 @@ msgid "Server" msgstr "Servidor" +#: FFarmLogin.form:59 FFarmRegister.form:61 FNewConnection.form:141 #: FProjectVersion.form:127 FProxy.form:42 msgid "User" msgstr "Usuario" +#: FFarmLogin.form:74 FFarmRegister.form:76 FNewConnection.form:155 #: FProjectVersion.form:142 FProxy.form:47 msgid "Password" msgstr "Contraseña" @@ -1894,8 +2017,14 @@ msgstr "Imposible registrar el usuario." #: FFarmRegister.class:40 -msgid "You have been successfully registered.\n\nYou will receive a confirmation e-mail soon." -msgstr "Has sido registrado correctamente.\n\nRecibirás un e-mail de confirmación en breve." +msgid "" +"You have been successfully registered.\n" +"\n" +"You will receive a confirmation e-mail soon." +msgstr "" +"Has sido registrado correctamente.\n" +"\n" +"Recibirás un e-mail de confirmación en breve." #: FFarmRegister.form:28 FPublish.form:319 FSoftwareFarm.form:117 msgid "Register" @@ -1910,8 +2039,14 @@ msgstr "Correo Electrónico" #: FFarmRegister.form:121 -msgid "A confirmation mail will be sent to the specified e-mail address. Click on the link included in that mail to activate your account.\n

\nYour e-mail will not be stored on the publishing server." -msgstr "Se ha enviado un correo de confirmación al e-mail especificado. Haz clic en el enlace incluido en el correo para activar tu cuenta.\n

\nLos e-mail no se almacenan en el servidor." +msgid "" +"A confirmation mail will be sent to the specified e-mail address. Click on the link included in that mail to activate your account.\n" +"

\n" +"Your e-mail will not be stored on the publishing server." +msgstr "" +"Se ha enviado un correo de confirmación al e-mail especificado. Haz clic en el enlace incluido en el correo para activar tu cuenta.\n" +"

\n" +"Los e-mail no se almacenan en el servidor." #: FFieldChooser.class:54 FTableChooser.class:66 msgid "Unable to open connection." @@ -1973,6 +2108,7 @@ msgid "This file has not been modified since the last commit." msgstr "Este archivo no ha sido modificado desde el último commit." +#: FFileProperty.class:142 FMakeInstall.class:333 FProjectVersion.class:211 #: FSave.form:21 Project.module:3519 msgid "Continue" msgstr "Continuar" @@ -2014,8 +2150,14 @@ msgstr "No se pueden pegar datos." #: FForm.class:3216 -msgid "The form has been modified.\n\nAll your changes will be lost." -msgstr "El formulario ha sido modificado.\n\nTodos sus cambios se perderán." +msgid "" +"The form has been modified.\n" +"\n" +"All your changes will be lost." +msgstr "" +"El formulario ha sido modificado.\n" +"\n" +"Todos sus cambios se perderán." #: FForm.form:131 msgid "Select" @@ -2770,8 +2912,14 @@ msgstr "Nueva carpeta" #: FMain.class:961 -msgid "The GNU translation tools are not installed on your system.\n\nPlease install them to be able to do the translation." -msgstr "Las herramientas de traducción de GNU no están instaladas en su sistema.\n\nInstalelas para poder hacer la traducción." +msgid "" +"The GNU translation tools are not installed on your system.\n" +"\n" +"Please install them to be able to do the translation." +msgstr "" +"Las herramientas de traducción de GNU no están instaladas en su sistema.\n" +"\n" +"Instalelas para poder hacer la traducción." #: FMain.class:1666 msgid "Unable to drop file into the project." @@ -2797,7 +2945,7 @@ msgid "Profile for &1 project" msgstr "Perfil para el proyecto &1" -#: FMain.class:2468 FProperty.class:1009 +#: FMain.class:2468 FProperty.class:1011 msgid "Select a file" msgstr "Seleccione un archivo" @@ -3378,8 +3526,12 @@ msgstr "-" #: FMakeInstall.form:670 -msgid "Enter the mimetypes handled by your application there.\nPlease enter one mimetype by line.\n" -msgstr "Ingrese el tipo MIME manejado por su aplicación.\nIngrese un tipo MIME por línea.\n" +msgid "" +"Enter the mimetypes handled by your application there.\n" +"Please enter one mimetype by line.\n" +msgstr "" +"Ingrese el tipo MIME manejado por su aplicación.\n" +"Ingrese un tipo MIME por línea.\n" #: FMakeInstall.form:682 msgid "Additional configuration" @@ -3414,8 +3566,12 @@ msgstr "Pruebas adicionales de autoconf" #: FMakeInstall.form:839 -msgid "Add extra tests for the configuration process.\n

Leave this blank if you don't need it, or if you don't know anything about autoconf scripts." -msgstr "Agregar pruebas extra para el proceso de configuración.\n

Deje esto en blanco si no lo necesita, o si no conoce nada sobre scripts autoconf." +msgid "" +"Add extra tests for the configuration process.\n" +"

Leave this blank if you don't need it, or if you don't know anything about autoconf scripts." +msgstr "" +"Agregar pruebas extra para el proceso de configuración.\n" +"

Deje esto en blanco si no lo necesita, o si no conoce nada sobre scripts autoconf." #: FMakeInstall.form:847 msgid "Destination directory" @@ -4413,31 +4569,31 @@ msgid "Incorrect property value." msgstr "Valor incorrecto de la propiedad." -#: FProperty.class:624 +#: FProperty.class:626 msgid "The name of the control." msgstr "El nombre del control." -#: FProperty.class:635 +#: FProperty.class:637 msgid "The event group that the control belongs to." msgstr "El grupo de eventos al que el control pertenece." -#: FProperty.class:649 +#: FProperty.class:651 msgid "If the form and controls dimensions must follow the size of the default font." msgstr "Si las dimensiones del formulario y los controles deben seguir el tamaño de la fuente por defecto." -#: FProperty.class:653 +#: FProperty.class:655 msgid "If the control is public." msgstr "Si el control es público." -#: FProperty.class:657 +#: FProperty.class:659 msgid "If the Text property must be translated." msgstr "Si la propiedad Text debe ser traducida." -#: FProperty.class:678 +#: FProperty.class:680 msgid "This property is virtual: it is only implemented in the IDE, and has no existence at runtime." msgstr "Esta propiedad es virtual: está sólo implementa en el IDE, y no tiene existencia en tiempo de ejecución." -#: FProperty.class:803 +#: FProperty.class:805 msgid "None" msgstr "Ninguno" @@ -6686,8 +6842,14 @@ msgstr "Este proyecto no existe." #: Project.module:483 -msgid "Unable to find Gambas IDE executable in directory:\n\n&1" -msgstr "Incapaz de encontrar el ejecutable de la IDE de Gambas en el directorio:\n\n&1" +msgid "" +"Unable to find Gambas IDE executable in directory:\n" +"\n" +"&1" +msgstr "" +"Incapaz de encontrar el ejecutable de la IDE de Gambas en el directorio:\n" +"\n" +"&1" #: Project.module:496 msgid "This is not a Gambas project." @@ -6702,8 +6864,14 @@ msgstr "Convertir" #: Project.module:502 -msgid "This is a Gambas 2.0 project.\n\nDo you want to convert it?" -msgstr "Este es un proyecto Gambas 2.0\n\n¿Desea convertirlo?" +msgid "" +"This is a Gambas 2.0 project.\n" +"\n" +"Do you want to convert it?" +msgstr "" +"Este es un proyecto Gambas 2.0\n" +"\n" +"¿Desea convertirlo?" #: Project.module:520 msgid "Do not open" @@ -6714,8 +6882,14 @@ msgstr "Abrir de todos modos" #: Project.module:520 -msgid "This project seems to be already opened.\n\nOpening the same project twice can lead to data loss." -msgstr "Este proyecto parece estar ya abierto.\n\nAbrir el proyecto dos veces puede hacer que se pierdan datos." +msgid "" +"This project seems to be already opened.\n" +"\n" +"Opening the same project twice can lead to data loss." +msgstr "" +"Este proyecto parece estar ya abierto.\n" +"\n" +"Abrir el proyecto dos veces puede hacer que se pierdan datos." #: Project.module:526 msgid "It cannot be converted." @@ -6794,8 +6968,12 @@ msgstr "en &1." #: Project.module:2530 -msgid "Some project source files are in conflict.\nPlease solve them if you want to compile the project." -msgstr "Algunos archivos fuente del proyecto están en conflicto.\nSolucionelos si quiere compilar el proyecto." +msgid "" +"Some project source files are in conflict.\n" +"Please solve them if you want to compile the project." +msgstr "" +"Algunos archivos fuente del proyecto están en conflicto.\n" +"Solucionelos si quiere compilar el proyecto." #: Project.module:2534 msgid "Compiling project" @@ -7008,4 +7186,3 @@ #: WikiMarkdown.class:187 msgid "This symbol does not exist." msgstr "Este símbolo no existe." - diff -Nru gambas3-3.8.3/app/src/gambas3/.lang/zh.po gambas3-3.8.4/app/src/gambas3/.lang/zh.po --- gambas3-3.8.3/app/src/gambas3/.lang/zh.po 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.lang/zh.po 2015-12-22 04:46:12.000000000 +0000 @@ -282,6 +282,7 @@ msgid "" msgstr "" "Project-Id-Version: gambas3 3.6.90\n" +"POT-Creation-Date: 2015-09-29 17:11 UTC\n" "PO-Revision-Date: 2014-12-16 10:55 UTC\n" "Last-Translator: Benoît Minisini \n" "Language: zh\n" @@ -313,495 +314,596 @@ msgid "Next bookmark" msgstr "下一个书签" -#: CClassInfo.class:602 +#: CClassInfo.class:599 msgid "Static properties" msgstr "静态属性" -#: CClassInfo.class:603 FDebugInfo.class:981 +#: CClassInfo.class:600 FDebugInfo.class:990 msgid "Static variables" msgstr "静态变量" -#: CClassInfo.class:604 +#: CClassInfo.class:601 msgid "Static methods" msgstr "静态方法" -#: CClassInfo.class:605 +#: CClassInfo.class:602 msgid "Constants" msgstr "常数" -#: CClassInfo.class:622 FMain.form:485 FProperty.form:24 +#: CClassInfo.class:619 FMain.form:474 FProperty.form:23 msgid "Properties" msgstr "属性" -#: CClassInfo.class:623 +#: CClassInfo.class:620 msgid "Variables" msgstr "变量" -#: CClassInfo.class:624 +#: CClassInfo.class:621 msgid "Methods" msgstr "方法" -#: CClassInfo.class:625 +#: CClassInfo.class:622 msgid "Events" msgstr "事件" -#: CClassInfo.class:647 +#: CClassInfo.class:644 msgid "This class reimplements &1" msgstr "该类重载于&1" -#: CClassInfo.class:649 +#: CClassInfo.class:646 msgid "This class inherits &1" msgstr "该类继承于&1" -#: CClassInfo.class:655 +#: CClassInfo.class:652 msgid "in &1" msgstr "在&1中" -#: CClassInfo.class:663 +#: CClassInfo.class:660 msgid "This class can be used like an object by creating an hidden instance on demand." msgstr "在需要时,通过创建一个隐含的实例,该类可以像对象一样使用。" -#: CClassInfo.class:668 +#: CClassInfo.class:665 msgid "This class is &1." msgstr "该类是&1。" -#: CClassInfo.class:668 +#: CClassInfo.class:665 msgid "creatable" msgstr "可创建" -#: CClassInfo.class:673 +#: CClassInfo.class:670 msgid "This class is static." msgstr "该类是静态类。" -#: CClassInfo.class:675 +#: CClassInfo.class:672 msgid "This class is not creatable." msgstr "该类不可创建。" -#: CClassInfo.class:681 +#: CClassInfo.class:678 msgid "This class can be used as a &1." msgstr "该类可以作为&1使用。" -#: CClassInfo.class:681 +#: CClassInfo.class:678 msgid "function" msgstr "函数" -#: CClassInfo.class:686 +#: CClassInfo.class:683 msgid "This class acts like a &1 / &2 array." msgstr "该类的行为像一个&1/&2数组。" -#: CClassInfo.class:686 +#: CClassInfo.class:683 msgid "read" msgstr "可读" -#: CClassInfo.class:686 +#: CClassInfo.class:683 msgid "write" msgstr "可写" -#: CClassInfo.class:688 +#: CClassInfo.class:685 msgid "This class acts like a &1 array." msgstr "该类行为像一个&1数组。" -#: CClassInfo.class:688 +#: CClassInfo.class:685 msgid "write-only" msgstr "只写" -#: CClassInfo.class:691 Project.module:1687 +#: CClassInfo.class:688 Project.module:1705 msgid "read-only" msgstr "只读" -#: CClassInfo.class:696 +#: CClassInfo.class:693 msgid "This class is &1 with the FOR EACH keyword." msgstr "用FOR EACH关键字&1该类。" -#: CClassInfo.class:696 +#: CClassInfo.class:693 msgid "enumerable" msgstr "可枚举" -#: CClassInfo.class:847 +#: CClassInfo.class:844 msgid "This class reimplements" msgstr "该类重载于" -#: CClassInfo.class:849 +#: CClassInfo.class:846 msgid "This class inherits" msgstr "该类继承于" -#: CClassInfo.class:864 +#: CClassInfo.class:861 msgid "This class is virtual." msgstr "该类是虚类" -#: CClassInfo.class:866 +#: CClassInfo.class:863 msgid "This class can be used like an object by creating a hidden instance on demand." msgstr "在需要时,通过创建一个隐含的实例,该类可以像对象一样使用。" -#: CClassInfo.class:891 +#: CClassInfo.class:888 msgid "static function" msgstr "静态函数" -#: CClassInfo.class:898 +#: CClassInfo.class:895 msgid "This class acts like a &1 / &2 static array." msgstr "该类的行为像一个&1/&2静态数组" -#: CClassInfo.class:900 +#: CClassInfo.class:897 msgid "This class acts like a &1 static array." msgstr "该类的行为像一个&1静态数组" -#: CClassInfo.class:912 +#: CClassInfo.class:909 msgid "This class is &1 with the &2 keyword." msgstr "用&2关键字&1该类。" -#: CClassInfo.class:912 +#: CClassInfo.class:909 msgid "statically enumerable" msgstr "静态可枚举" -#: CComponent.class:84 +#: CComponent.class:489 +msgid "Loading information on component &1..." +msgstr "正在加载&1组件信息..." + +#: CComponent.class:1601 FFileProperty.class:166 FProjectProperty.class:950 +msgid "Classes" +msgstr "类" + +#: CComponent.class:1645 FCreateFile.class:132 FDebugInfo.class:51 +#: FMain.form:785 +msgid "Class" +msgstr "类" + +#: CComponent.class:1647 FConnectionEditor.class:295 FMakeInstall.form:284 +#: FProjectProperty.form:356 FPublish.form:125 FSoftwareFarm.form:312 +msgid "Description" +msgstr "描述" + +#: CComponent.class:1674 +#, fuzzy +msgid "This component is not stable yet." +msgstr "该组件不存在。" + +#: CComponent.class:1676 +#, fuzzy +msgid "This component is deprecated." +msgstr "该组件被隐藏" + +#: CComponent.class:1685 FProjectVersion.class:287 +msgid "Author" +msgstr "作者" + +#: CComponent.class:1687 FAbout.class:192 FProjectProperty.form:368 +msgid "Authors" +msgstr "作者" + +#: CComponent.class:1697 +msgid "Implements" +msgstr "实施" + +#: CComponent.class:1709 CLibraryInfo.class:158 LibraryItem.class:60 +msgid "Requires" +msgstr "需要" + +#: CComponent.class:1724 +msgid "Excludes" +msgstr "排除" + +#: CDocumentation.class:48 msgid "Internal native classes" msgstr "内部本地类 " -#: CComponent.class:85 +#: CDocumentation.class:49 msgid "Program arguments parser" msgstr "程序参数分析" -#: CComponent.class:86 +#: CDocumentation.class:50 msgid "Cairo graphic library" msgstr "Cairo图形库" -#: CComponent.class:87 +#: CDocumentation.class:51 msgid "Chart drawing" msgstr "绘制图表" -#: CComponent.class:88 +#: CDocumentation.class:52 msgid "Polygon management based on Clipper library" msgstr "基于Clipper库的多边形管理" -#: CComponent.class:89 +#: CDocumentation.class:53 msgid "Complex numbers management" msgstr "复数管理" -#: CComponent.class:90 +#: CDocumentation.class:54 msgid "Compression & decompression" msgstr "压缩和解压缩" -#: CComponent.class:91 +#: CDocumentation.class:55 +msgid "bzlib2 compression driver" +msgstr "" + +#: CDocumentation.class:56 +msgid "zlib compression driver" +msgstr "" + +#: CDocumentation.class:57 msgid "MD5/DES/SHA crypting" msgstr "MD5/DES/SHA加密" -#: CComponent.class:92 +#: CDocumentation.class:58 msgid "More data containers" msgstr "更多数据容器" -#: CComponent.class:93 FCreateProject.form:294 +#: CDocumentation.class:59 FCreateProjectOld.form:294 msgid "Database access" msgstr "数据库存取" -#: CComponent.class:95 +#: CDocumentation.class:61 msgid "Data bound controls" msgstr "数据范围控制" -#: CComponent.class:96 +#: CDocumentation.class:62 msgid "MySQL database driver" msgstr "MySQL数据库驱动" -#: CComponent.class:97 +#: CDocumentation.class:63 msgid "ODBC database driver" msgstr "ODBC数据库驱动" -#: CComponent.class:98 +#: CDocumentation.class:64 msgid "PostgreSQL database driver" msgstr "PostgreSQL数据库驱动" -#: CComponent.class:99 +#: CDocumentation.class:65 msgid "SQLite 2 database driver" msgstr "SQLite 2数据库驱动" -#: CComponent.class:100 +#: CDocumentation.class:66 msgid "SQLite 3 database driver" msgstr "SQLite 3数据库驱动" -#: CComponent.class:101 +#: CDocumentation.class:67 msgid "Application debugger helper" msgstr "应用程序调试助手" -#: CComponent.class:102 +#: CDocumentation.class:68 msgid "Desktop management component" msgstr "桌面管理组件" -#: CComponent.class:103 +#: CDocumentation.class:69 msgid "X-Window library support" msgstr "X-Window库支持" -#: CComponent.class:104 +#: CDocumentation.class:70 msgid "Gnome keyring support for desktop management component" msgstr "桌面管理组件的Gnome钥匙圈支持" -#: CComponent.class:105 +#: CDocumentation.class:71 msgid "D-Bus interface" msgstr "D-Bus界面" -#: CComponent.class:106 +#: CDocumentation.class:72 msgid "Expression evaluator" msgstr "表达式分析器" -#: CComponent.class:107 +#: CDocumentation.class:73 msgid "Syntax highlighter routines" msgstr "语法高亮例程" -#: CComponent.class:108 +#: CDocumentation.class:74 msgid "More controls for graphical components" msgstr "图形组件的更多控件" -#: CComponent.class:109 +#: CDocumentation.class:75 msgid "Enhanced standard dialogs" msgstr "标准对话框增强" -#: CComponent.class:110 +#: CDocumentation.class:76 +msgid "Text editor with syntax highlighting" +msgstr "" + +#: CDocumentation.class:77 msgid "Multi Document Interface" msgstr "多文档界面" -#: CComponent.class:111 +#: CDocumentation.class:78 msgid "Default icon theme" msgstr "默认图标主题" -#: CComponent.class:112 +#: CDocumentation.class:79 msgid "GNU Multiple Precision Arithmetic Library" msgstr "GNU多倍精度运算库" -#: CComponent.class:113 +#: CDocumentation.class:80 msgid "GNU Scientific Library" msgstr "GNU科学库" -#: CComponent.class:114 +#: CDocumentation.class:81 msgid "GTK+2 toolkit" msgstr "GTK+2工具箱" -#: CComponent.class:115 +#: CDocumentation.class:82 msgid "OpenGL with GTK+ toolkit" msgstr "OpenGL 编程(使用GTK+工具箱) " -#: CComponent.class:116 +#: CDocumentation.class:83 msgid "GTK+3 toolkit" msgstr "GTK+3工具箱" -#: CComponent.class:117 +#: CDocumentation.class:84 msgid "QT/GTK+ switcher component" msgstr "QT/GTK+组件切换器" -#: CComponent.class:118 +#: CDocumentation.class:85 msgid "OpenGL with QT/GTK+ switcher component" msgstr "OpenGL 编程(QT/GTK+组件切换器) " -#: CComponent.class:119 +#: CDocumentation.class:86 +#, fuzzy +msgid "QT4/QT5 switcher component" +msgstr "QT/GTK+组件切换器" + +#: CDocumentation.class:87 +#, fuzzy +msgid "QT4/QT5 WebKit switcher component" +msgstr "QT/GTK+组件切换器" + +#: CDocumentation.class:88 +#, fuzzy +msgid "System tray icon management component" +msgstr "桌面管理组件" + +#: CDocumentation.class:89 msgid "Embedded HTTP server" msgstr "嵌入式HTTP服务" -#: CComponent.class:120 +#: CDocumentation.class:90 msgid "Image management" msgstr "图像管理" -#: CComponent.class:121 +#: CDocumentation.class:91 msgid "Image filtering component" msgstr "图像过滤组件" -#: CComponent.class:122 +#: CDocumentation.class:92 msgid "Image routines from the Imlib2 library" msgstr "来自Imlib2库的图像程序" -#: CComponent.class:123 FPropertyComponent.form:176 +#: CDocumentation.class:93 FProjectProperty.form:500 msgid "Image loading and saving" msgstr "图像加载和保存" -#: CComponent.class:124 +#: CDocumentation.class:94 msgid "Filesystem events monitoring" msgstr "文件系统事件监视" -#: CComponent.class:125 +#: CDocumentation.class:95 msgid "XML tools based on libxml" msgstr "基于libxml的XML工具" -#: CComponent.class:126 +#: CDocumentation.class:96 msgid "Flexible logging system" msgstr "弹性日志系统" -#: CComponent.class:127 +#: CDocumentation.class:97 msgid "Online map viewer" msgstr "在线地图查看" -#: CComponent.class:128 +#: CDocumentation.class:98 msgid "Gambas Markdown markup syntax" msgstr "Gambas简化标记语法" -#: CComponent.class:129 +#: CDocumentation.class:99 msgid "GStreamer multimedia component" msgstr "GStreamer多媒体组件" -#: CComponent.class:130 +#: CDocumentation.class:100 msgid "Multimedia controls" msgstr "多媒体控件" -#: CComponent.class:131 +#: CDocumentation.class:101 msgid "Memcached client" msgstr "Memcached客户端" -#: CComponent.class:132 +#: CDocumentation.class:102 msgid "MIME format management based on GMime library" msgstr "基于GMime库的MIME格式管理" -#: CComponent.class:133 +#: CDocumentation.class:103 msgid "MySQL specific routines" msgstr "MySQL专用程序" -#: CComponent.class:134 +#: CDocumentation.class:104 msgid "NCurses library" msgstr "NCurses库" -#: CComponent.class:135 FCreateProject.form:300 +#: CDocumentation.class:105 FCreateProjectOld.form:300 msgid "Network programming" msgstr "网络编程" -#: CComponent.class:136 +#: CDocumentation.class:106 msgid "Network high-level protocols management" msgstr "高级网络协议管理" -#: CComponent.class:137 +#: CDocumentation.class:107 msgid "POP3 client" msgstr "POP3客户端" -#: CComponent.class:138 +#: CDocumentation.class:108 msgid "SMTP client" msgstr "SMTP客户机" -#: CComponent.class:139 +#: CDocumentation.class:109 msgid "OpenAL 3D audio library" msgstr "OpenAL 3D音频库" -#: CComponent.class:140 +#: CDocumentation.class:110 msgid "3D programming with OpenGL" msgstr "OpenGL 3D编程" -#: CComponent.class:141 +#: CDocumentation.class:111 msgid "OpenGL utility component" msgstr "OpenGL公用组件" -#: CComponent.class:142 +#: CDocumentation.class:112 msgid "OpenGL shaders management" msgstr "OpenGL渲染管理" -#: CComponent.class:143 +#: CDocumentation.class:113 msgid "Simple OpenGL game engine based on MD2 format" msgstr "基于MD2格式的简单OpenGL游戏引擎" -#: CComponent.class:144 +#: CDocumentation.class:114 msgid "OpenSSL library routines" msgstr "OpenSSL库程序" -#: CComponent.class:145 +#: CDocumentation.class:115 msgid "GNU command option parser" msgstr "GNU风格命令行参数分析程序" -#: CComponent.class:146 +#: CDocumentation.class:116 msgid "Perl-compatible Regular Expression Matching" msgstr "Perl兼容的正则表达式匹配" -#: CComponent.class:147 +#: CDocumentation.class:117 msgid "PDF renderer based on Poppler library" msgstr "基于Poppler库的PDF演示器" -#: CComponent.class:148 +#: CDocumentation.class:118 msgid "QT4 toolkit" msgstr "QT4工具箱" -#: CComponent.class:149 +#: CDocumentation.class:119 msgid "QT4 toolkit extension" msgstr "QT4扩展工具箱" -#: CComponent.class:150 +#: CDocumentation.class:120 msgid "QT4 WebKit component" msgstr "QT4 WebKit组件" -#: CComponent.class:151 +#: CDocumentation.class:121 msgid "OpenGL with QT4 toolkit" msgstr "OpenGL 编程(使用QT4工具包) " -#: CComponent.class:152 +#: CDocumentation.class:122 +#, fuzzy +msgid "QT5 toolkit" +msgstr "QT4工具箱" + +#: CDocumentation.class:123 +#, fuzzy +msgid "QT5 WebKit component" +msgstr "QT4 WebKit组件" + +#: CDocumentation.class:124 +#, fuzzy +msgid "OpenGL with QT5 toolkit" +msgstr "OpenGL 编程(使用QT4工具包) " + +#: CDocumentation.class:125 msgid "Report designer" msgstr "报表设计器" -#: CComponent.class:153 +#: CDocumentation.class:127 +msgid "Scanner management library based on SANE" +msgstr "" + +#: CDocumentation.class:128 msgid "SDL library" msgstr "SDL库" -#: CComponent.class:154 +#: CDocumentation.class:129 msgid "SDL sound & CD-ROM management" msgstr "SDL声音和CD-ROM管理" -#: CComponent.class:155 +#: CDocumentation.class:130 +#, fuzzy +msgid "SDL2 component" +msgstr "GUI组件" + +#: CDocumentation.class:131 +#, fuzzy +msgid "SDL2 audio component" +msgstr "OpenGL公用组件" + +#: CDocumentation.class:132 msgid "Application settings management" msgstr "应用程序设置管理" -#: CComponent.class:156 +#: CDocumentation.class:133 msgid "Signals management" msgstr "信号管理" -#: CComponent.class:157 +#: CDocumentation.class:134 msgid "Utility component" msgstr "公用组件" -#: CComponent.class:158 +#: CDocumentation.class:135 +#, fuzzy +msgid "Web applications utility component" +msgstr "Web应用程序工具" + +#: CDocumentation.class:136 msgid "Video capture" msgstr "视频截取" -#: CComponent.class:159 +#: CDocumentation.class:137 msgid "Visual Basic compatibility" msgstr "Visual Basic兼容" -#: CComponent.class:160 +#: CDocumentation.class:138 msgid "XML tools" msgstr "XML工具" -#: CComponent.class:161 +#: CDocumentation.class:139 msgid "HTML generator" msgstr "HTML生成器" -#: CComponent.class:162 +#: CDocumentation.class:140 msgid "XML-RPC protocol" msgstr "XML-RPC协议" -#: CComponent.class:163 +#: CDocumentation.class:141 msgid "XSLT tools based on libxslt and libxml" msgstr "基于libxslt和libxml的XSLT工具" -#: CComponent.class:164 +#: CDocumentation.class:142 msgid "Web applications tools" msgstr "Web应用程序工具" -#: CComponent.class:170 FPropertyComponent.form:164 +#: CDocumentation.class:148 FProjectProperty.form:488 msgid "Graphical form management" msgstr "图形化表单管理" -#: CComponent.class:171 FPropertyComponent.form:170 +#: CDocumentation.class:149 FProjectProperty.form:494 msgid "Event loop management" msgstr "事件循环管理" -#: CComponent.class:173 FPropertyComponent.form:186 +#: CDocumentation.class:151 FProjectProperty.form:511 msgid "OpenGL display" msgstr "OpenGL显示" -#: CComponent.class:174 +#: CDocumentation.class:152 msgid "Complex numbers" msgstr "复数" -#: CComponent.class:175 FPropertyComponent.form:192 +#: CDocumentation.class:153 FProjectProperty.form:517 msgid "XML management" msgstr "XML管理" -#: CComponent.class:473 -msgid "Loading information on component &1..." -msgstr "正在加载&1组件信息..." - -#: CComponent.class:1584 FFileProperty.class:165 FProjectProperty.class:1385 -msgid "Classes" -msgstr "类" - -#: CInsertColor.class:118 FEditor.form:266 FTextEditor.form:207 +#: CInsertColor.class:118 FEditor.form:307 FTextEditor.form:277 msgid "Insert color" msgstr "插入颜色" @@ -817,15 +919,11 @@ msgid "WARNING! Library not found." msgstr "警告!未找到库。" -#: CLibraryInfo.class:157 ComponentItem.class:174 LibraryItem.class:58 +#: CLibraryInfo.class:157 LibraryItem.class:58 msgid "Provides" msgstr "提供" -#: LibraryItem.class:60 -msgid "Requires" -msgstr "需要" - -#: CModule.class:28 FEditor.form:391 FForm.form:442 FMain.form:820 +#: CModule.class:28 FEditor.form:392 FForm.form:442 FMain.form:792 msgid "Form" msgstr "窗口" @@ -841,7 +939,7 @@ msgid "Gambas web pages" msgstr "Gambas WEB页面" -#: CModule.class:29 FMain.form:827 +#: CModule.class:29 FMain.form:799 msgid "WebPage" msgstr "WEB页面" @@ -853,7 +951,7 @@ msgid "Gambas reports" msgstr "Gambas报表" -#: CModule.class:30 FMain.form:834 +#: CModule.class:30 FMain.form:806 msgid "Report" msgstr "报表" @@ -861,39 +959,44 @@ msgid "Reports" msgstr "报表" -#: CProfile.class:111 +#: CProfile.class:114 msgid "Evaluator" msgstr "求值程序" -#: CProfile.class:113 +#: CProfile.class:116 msgid "Event loop" msgstr "事件循环" -#: CProjectList.class:33 FCreateProject.form:426 FProjectChooser.form:70 -msgid "Open in another window" -msgstr "在另一个窗口打开" +#: CProjectList.class:102 +msgid "Examples are stored on the Gambas farm server. Click &1 to access the farm server and download them..." +msgstr "" + +#: CProjectList.class:102 +msgid "here" +msgstr "" -#: FSearch.class:97 FSelectIcon.form:31 Project.module:1807 +#: CProjectTree.class:285 FHelpShortcut.form:22 FMain.form:372 FSearch.class:97 +#: FSelectIcon.form:31 Project.module:1825 msgid "Project" msgstr "工程" -#: CProjectTree.class:288 Project.module:1808 +#: CProjectTree.class:288 Project.module:1826 msgid "Sources" msgstr "源代码" -#: CProjectTree.class:290 Project.module:1809 +#: CProjectTree.class:290 Project.module:1827 msgid "Connections" msgstr "连接" -#: CProjectTree.class:298 Project.module:1810 +#: CProjectTree.class:298 Project.module:1828 msgid "Public" msgstr "公共" -#: CProjectTree.class:299 Project.module:1811 +#: CProjectTree.class:299 Project.module:1829 msgid "Data" msgstr "数据" -#: CRecentProject.class:68 FMain.class:654 +#: CRecentProject.class:68 FMain.class:669 msgid "Today" msgstr "今天" @@ -913,110 +1016,100 @@ msgid "This month" msgstr "本月" -#: CSoftware.class:284 +#: CSoftware.class:294 msgid "Download cancelled" msgstr "取消下载" -#: CSoftware.class:293 +#: CSoftware.class:303 msgid "The checksum of the downloaded package is invalid." msgstr "下载包的checksum非法。" -#: CSoftware.class:309 +#: CSoftware.class:319 msgid "Unable to uncompress source archive." msgstr "不能解压缩源码包。" -#: CSoftware.class:328 +#: CSoftware.class:338 msgid "The following components are required:" msgstr "需要下列组件:" -#: CSoftware.class:346 +#: CSoftware.class:362 msgid "Unable to compile the project." msgstr "不能编译工程。" -#: CSoftware.class:353 +#: CSoftware.class:369 msgid "Unable to make executable." msgstr "不能生成可执行文件。" -#: CSoftware.class:369 +#: CSoftware.class:427 msgid "Unable to install source directory" msgstr "不能安装源目录" -#: FTranslate.class:556 Project.module:488 +#: CWaitingAnimation.class:63 FColorChooser.form:76 FComponentChooser.form:98 +#: FConflict.class:209 FConnectionEditor.class:431 FCrash.form:96 +#: FCreateFile.form:227 FDebugExpr.form:46 FDebugInfo.form:270 +#: FEditor.class:2235 FExportData.class:126 FFarmConfig.form:38 +#: FFarmLogin.form:126 FFarmRegister.form:141 FFarmRequest.form:43 +#: FFieldChooser.form:144 FFileProperty.class:142 FFontChooser.form:40 +#: FForm.class:3216 FGotoLine.form:23 FHelpBrowser.form:60 +#: FImageEditor.class:394 FImageOffsetSelection.form:33 FImageQuality.form:30 +#: FImageResize.form:49 FImageRotate.form:32 FList.form:121 FMain.class:226 +#: FMakeInstall.class:333 FMenu.form:404 FNewConnection.form:301 +#: FNewTable.form:86 FNewTranslation.form:21 FOption.class:717 +#: FPasteSpecial.form:86 FPasteTable.form:107 FProjectChooser.form:73 +#: FProjectProperty.form:976 FProjectVersion.class:211 FProxy.form:57 +#: FPublish.class:271 FReportBorderChooser.form:48 +#: FReportBoxShadowChooser.form:27 FReportBrushChooser.form:36 +#: FReportCoordChooser.form:26 FReportPaddingChooser.form:75 FSave.form:28 +#: FSaveProjectAs.form:76 FSearch.class:893 FSelectComponent.form:39 +#: FSelectExtraFile.form:43 FSelectIcon.form:87 FSnippet.form:57 +#: FSoftwareFarm.class:480 FTableChooser.form:68 FText.form:41 +#: FTextEditor.class:673 FTranslate.class:562 Project.module:502 msgid "Cancel" msgstr "取消" -#: CWelcome.class:41 +#: CWelcome.class:85 msgid "The Gambas font is published under the SIL Open Font License." msgstr "Gambas字体发布遵循SIL开放字体许可协议。" -#: CWelcome.class:41 +#: CWelcome.class:85 msgid "This program is published under the GNU General Public License." msgstr "本程序发布遵循GNU通用公共许可协议。" -#: FPropertyComponent.form:82 -msgid "Experimental" -msgstr "实验性的" - -#: FPropertyComponent.form:82 -msgid "Not finished but stable" -msgstr "稳定非最终版" - -#: ComponentItem.class:143 FProjectProperty.class:1291 -msgid "Deprecated" -msgstr "废弃" - -#: ComponentItem.class:146 -msgid "Authors" -msgstr "作者" - -#: ComponentItem.class:155 -msgid "Excludes" -msgstr "排除" - -#: ComponentItem.class:161 -msgid "Implements" -msgstr "实施" - -#: ComponentItem.class:242 -msgid "This component is required by the following library:

&1" -msgstr "下列库需要该组件:

&1" - -#: ComponentItem.class:244 -msgid "This component is required by the following libraries:

&1" -msgstr "下列库需要该组件:

&1" - -#: ComponentItem.class:253 -msgid "This component is required by:

&1" -msgstr "

&1需要该组件" - -#: ComponentItem.class:254 -msgid "Keep" -msgstr "保留" - -#: ComponentItem.class:254 FDebugInfo.form:157 -msgid "Remove all" -msgstr "全部删除" - -#: Design.module:187 Project.module:2286 +#: Design.module:187 Project.module:2303 msgid "first" msgstr "第一步" -#: Design.module:189 Project.module:2288 +#: Design.module:189 Project.module:2305 msgid "second" msgstr "第二步" -#: Design.module:191 Project.module:2290 +#: Design.module:191 Project.module:2307 msgid "third" msgstr "第三步" -#: Design.module:286 Project.module:2349 +#: Design.module:286 Project.module:2366 msgid "in &1:&2." msgstr "在&1:&2中。" #: Design.module:392 -msgid "The program has returned\nthe value: &1" -msgstr "程序返回\n的值为:&1" +msgid "" +"The program has returned\n" +"the value: &1" +msgstr "" +"程序返回\n" +"的值为:&1" +#: Design.module:458 FColorChooser.form:70 FConnectionEditor.class:637 +#: FCrash.form:90 FCreateFile.form:233 FFarmConfig.form:33 FFarmLogin.form:121 +#: FFieldChooser.form:138 FFontChooser.form:34 FGotoLine.form:17 +#: FImageOffsetSelection.form:27 FImageQuality.form:24 FImageResize.form:103 +#: FImageRotate.form:26 FList.form:115 FMakeInstall.class:266 FMenu.form:399 +#: FNewConnection.form:295 FNewTable.form:80 FNewTranslation.form:15 +#: FPasteSpecial.form:80 FProjectProperty.form:970 FProxy.form:63 +#: FReportBorderChooser.form:54 FReportBoxShadowChooser.form:33 +#: FReportBrushChooser.form:42 FReportCoordChooser.form:32 +#: FReportPaddingChooser.form:69 FSelectComponent.form:34 +#: FSelectExtraFile.form:37 FSelectIcon.form:82 FSnippet.form:51 #: FTableChooser.form:62 FText.form:35 msgid "OK" msgstr "确定" @@ -1025,287 +1118,398 @@ msgid "Output terminal" msgstr "输出终端" -#: Design.module:924 +#: Design.module:927 msgid "No terminal emulator found." msgstr "没有找到终端仿真器。" -#: FAbout.class:190 +#: FAbout.class:212 FAboutOld.class:205 msgid "Financial support" msgstr "资金支持" -#: FAbout.class:234 -msgid "Thanks to" -msgstr "鸣谢" - -#: FAbout.form:20 FMain.form:1148 FWelcome.class:67 +#: FAbout.form:12 FAboutOld.form:20 FMain.form:1125 FWelcome.class:73 msgid "About Gambas" msgstr "(A)关于Gambas" -#: FAbout.form:48 -msgid "Gambas
\nAlmost
\nMeans
\nB A S I C !" -msgstr "-" +#: FAbout.form:25 FAboutOld.form:60 +msgid "" +"

Licence

\n" +"\n" +"

This program is FREE SOFTWARE; you can redistribute it AND/OR modify it under the terms of the GNU General Public License as published by the Free Software Foundation ; either version 2, or (at your option) any later version.

\n" +"\n" +"

This program is distributed in the hope that it will be useful but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

\n" +msgstr "" +"

许可协议

\n" +"\n" +"

该软件是自由软件;你可以再次分发它,并且/或者在自由软件基金会发布的《GNU公共许可协议》条款下修改它; 可以是用版本号2,也可以有你指定任一个更新的版本号。

\n" +"\n" +"

发布本软件是希望它能有用,而且不需要任何授权;甚至不需要为了某种目的而出售或安装的隐含授权。 更多细节请阅读《GNU公共许可协议》。

\n" -#: FAbout.form:61 -msgid "

Licence

\n\n

This program is FREE SOFTWARE; you can redistribute it AND/OR modify it under the terms of the GNU General Public License as published by the Free Software Foundation ; either version 2, or (at your option) any later version.

\n\n

This program is distributed in the hope that it will be useful but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

\n" -msgstr "

许可协议

\n\n

该软件是自由软件;你可以再次分发它,并且/或者在自由软件基金会发布的《GNU公共许可协议》条款下修改它; 可以是用版本号2,也可以有你指定任一个更新的版本号。

\n\n

发布本软件是希望它能有用,而且不需要任何授权;甚至不需要为了某种目的而出售或安装的隐含授权。 更多细节请阅读《GNU公共许可协议》。

\n" +#: FAboutOld.class:245 +msgid "Thanks to" +msgstr "鸣谢" + +#: FAboutOld.form:47 +msgid "" +"Gambas
\n" +"Almost
\n" +"Means
\n" +"B A S I C !" +msgstr "-" -#: FAbout.form:67 +#: FAboutOld.form:66 msgid "

Authors

\n" msgstr "

作者

\n" -#: FColorChooser.form:15 +#: FColorChooser.form:16 msgid "Select a color" msgstr "选择颜色" -#: FColorChooser.form:28 +#: FColorChooser.form:28 FSoftwareFarm.class:49 msgid "System" msgstr "系统" -#: FColorChooser.form:35 +#: FColorChooser.form:36 msgid "Free" msgstr "剩余" +#: FComponentChooser.class:321 FProjectProperty.form:404 +msgid "Not finished but stable" +msgstr "稳定非最终版" + +#: FComponentChooser.class:323 FProjectProperty.form:404 +msgid "Experimental" +msgstr "实验性的" + +#: FComponentChooser.class:325 +msgid "Stable" +msgstr "稳定版" + +#: FComponentChooser.class:327 FProjectProperty.form:404 +msgid "Deprecated" +msgstr "废弃" + +#: FComponentChooser.class:540 +msgid "This component is required by the following library:

&1" +msgstr "下列库需要该组件:

&1" + +#: FComponentChooser.class:542 +msgid "This component is required by the following libraries:

&1" +msgstr "下列库需要该组件:

&1" + +#: FComponentChooser.class:551 +msgid "This component is required by:

&1" +msgstr "

&1需要该组件" + +#: FComponentChooser.class:552 +msgid "Keep" +msgstr "保留" + +#: FComponentChooser.class:552 FDebugInfo.form:164 +msgid "Remove all" +msgstr "全部删除" + +#: FComponentChooser.class:657 +msgid "These components are incompatible:
&1." +msgstr "这些组件存在冲突:
&1。" + +#: FComponentChooser.class:670 +msgid "The &1 component needs one of the following components:
&2." +msgstr " &1组件需要下列组件之一 :
&2。" + +#: FComponentChooser.class:677 +msgid "The &1 component needs the &2 component." +msgstr "&1组件需要&2组件。" + +#: FComponentChooser.form:26 FSelectComponent.form:12 +#, fuzzy +msgid "Select a component" +msgstr "选择字体" + +#: FComponentChooser.form:56 +#, fuzzy +msgid "Show deprecated components" +msgstr "显示输出类" + +#: FComponentChooser.form:104 FConnectionEditor.form:110 FEditor.form:344 +#: FForm.form:427 FHelpBrowser.form:66 FImageEditor.form:339 FMain.form:331 +#: FTextEditor.form:306 FTranslate.form:77 +msgid "Reload" +msgstr "重载" + +#: FComponentChooser.form:115 FHelpBrowser.form:84 FImageEditor.form:297 +msgid "Zoom in" +msgstr "放大" + +#: FComponentChooser.form:121 FHelpBrowser.form:90 FImageEditor.form:305 +msgid "Zoom out" +msgstr "缩小" + +#: FComponentChooser.form:127 FHelpBrowser.form:96 +msgid "No zoom" +msgstr "无缩放" + #: FConflict.class:23 msgid "&Edit" msgstr "(&E)编辑" #: FConflict.class:23 -msgid "This file is in conflict with the revision #&1.\nYou must resolve the conflict in order to use the file." -msgstr "该文件和修订版#&1有冲突。\n你必须解决冲突以便使用文件。" +msgid "" +"This file is in conflict with the revision #&1.\n" +"You must resolve the conflict in order to use the file." +msgstr "" +"该文件和修订版#&1有冲突。\n" +"你必须解决冲突以便使用文件。" -#: FConflict.class:116 +#: FConflict.class:109 msgid "Unable to load file:" msgstr "不能加载文件:" -#: FConflict.class:158 FDebugInfo.class:70 FImageEditor.form:598 +#: FConflict.class:151 FDebugInfo.class:70 FImageEditor.form:595 msgid "Text" msgstr "文本" -#: FReportBrushChooser.form:49 Project.module:219 +#: FConflict.class:153 FCreateFile.class:142 FMain.form:816 +#: FReportBrushChooser.form:49 Project.module:224 msgid "Image" msgstr "图像" -#: FConflict.class:218 -msgid "The file has been modified.\nDo you really want to close the dialog?" -msgstr "文件已被修改。\n确定关闭对话框吗?" +#: FConflict.class:209 +msgid "" +"The file has been modified.\n" +"Do you really want to close the dialog?" +msgstr "" +"文件已被修改。\n" +"确定关闭对话框吗?" -#: FConflict.class:246 +#: FConflict.class:237 msgid "Some conflicts are not yet resolved." msgstr "一些冲突仍未解决。" -#: FConflict.class:252 +#: FConflict.class:243 msgid "Unable to resolve the conflict." msgstr "无法解决冲突。" -#: FConflict.class:281 -msgid "The file has been modified.\nDo you really want to open another file?" -msgstr "文件已被修改。\n确定打开另一个文件吗?" +#: FConflict.class:271 +msgid "" +"The file has been modified.\n" +"Do you really want to open another file?" +msgstr "" +"文件已被修改。\n" +"确定打开另一个文件吗?" -#: FConflict.class:289 +#: FConflict.class:279 msgid "Conflict files" msgstr "冲突文件" -#: FConflict.form:32 +#: FConflict.form:31 msgid "Version conflict" msgstr "版本冲突" -#: FOutput.form:63 FProjectVersion.form:234 FTextEditor.form:121 +#: FConflict.form:70 FConnectionEditor.form:379 FEditor.form:159 FForm.form:185 +#: FImageEditor.form:129 FMain.form:901 FMenu.form:111 FOutput.form:63 +#: FProjectVersion.form:234 FTextEditor.form:134 msgid "Cut" msgstr "剪切" -#: FTextEditor.form:128 +#: FConflict.form:76 FConnectionEditor.form:149 FEditor.form:166 FForm.form:192 +#: FImageEditor.form:137 FList.form:92 FMain.form:908 FMakeInstall.form:893 +#: FMenu.form:117 FOutput.form:70 FProjectVersion.form:240 FSystemInfo.form:62 +#: FTextEditor.form:141 msgid "Copy" msgstr "复制" -#: FProjectVersion.form:246 FTextEditor.form:135 +#: FConflict.form:82 FConnectionEditor.form:157 FEditor.form:173 FForm.form:205 +#: FImageEditor.form:144 FList.form:98 FMain.form:915 FMenu.form:123 +#: FOutput.form:77 FPasteTable.form:101 FProjectVersion.form:246 +#: FTextEditor.form:148 msgid "Paste" msgstr "粘贴" -#: FTextEditor.form:104 +#: FConflict.form:88 FConnectionEditor.form:407 FEditor.form:142 +#: FFieldChooser.form:127 FForm.form:168 FImageEditor.form:110 FList.form:104 +#: FOption.form:903 FOutput.form:46 FProjectVersion.form:252 +#: FTextEditor.form:117 msgid "Undo" msgstr "撤消" -#: FProjectVersion.form:258 FTextEditor.form:111 +#: FConflict.form:94 FConnectionEditor.form:414 FEditor.form:149 FForm.form:175 +#: FImageEditor.form:118 FOutput.form:53 FProjectVersion.form:258 +#: FTextEditor.form:124 msgid "Redo" msgstr "重做" -#: FTextEditor.form:363 +#: FConflict.form:100 FEditor.form:513 FMenu.form:133 FProjectVersion.form:264 +#: FTextEditor.form:436 msgid "Indent" msgstr "缩进" -#: FTextEditor.form:371 +#: FConflict.form:106 FEditor.form:521 FMenu.form:139 FProjectVersion.form:270 +#: FTextEditor.form:444 msgid "Unindent" msgstr "无缩进" -#: FProjectChooser.form:75 +#: FConflict.form:141 FMain.form:324 FOpenProject.form:35 +#: FProjectChooser.form:85 msgid "Open" msgstr "打开" -#: FConflict.form:151 +#: FConflict.form:143 msgid "Open..." msgstr "打开..." -#: FSaveProjectAs.form:82 FTextEditor.form:266 +#: FConflict.form:149 FConnectionEditor.form:102 FEditor.form:350 +#: FForm.form:433 FImageEditor.form:346 FMain.form:340 FMenu.class:72 +#: FSaveProjectAs.form:82 FTextEditor.form:312 msgid "Save" msgstr "保存" -#: FConflict.form:168 +#: FConflict.form:160 msgid "Solve" msgstr "(V)解决" -#: FTips.form:83 FTranslate.form:304 +#: FConflict.form:166 FDebugInfo.form:278 FEditor.form:337 +#: FFileProperty.form:75 FForm.form:420 FImageEditor.form:353 FMain.form:357 +#: FPatch.form:88 FProjectVersion.form:322 FSystemInfo.form:68 +#: FTextEditor.form:319 FTips.form:83 FTranslate.form:309 msgid "Close" msgstr "关闭" -#: FOption.form:256 +#: FConnectionEditor.class:46 FCreateFile.form:78 FDebugInfo.class:38 +#: FMakeInstall.form:235 FNewConnection.form:68 FNewTable.form:33 +#: FOption.form:258 msgid "Name" msgstr "名称" -#: FDebugInfo.class:76 FNewConnection.form:79 FNewTable.form:48 FProxy.form:27 +#: FConnectionEditor.class:51 FCreateFile.form:129 FCreateProjectOld.form:98 +#: FDebugInfo.class:76 FNewConnection.form:82 FNewTable.form:48 FProxy.form:27 msgid "Type" msgstr "类型" -#: FConnectionEditor.class:55 +#: FConnectionEditor.class:56 msgid "Length" msgstr "长度" -#: FConnectionEditor.class:60 +#: FConnectionEditor.class:61 msgid "Default value" msgstr "缺省值" -#: FConnectionEditor.class:65 +#: FConnectionEditor.class:66 msgid "Collation" msgstr "整理" -#: FConnectionEditor.class:76 FDebugExpr.class:470 FHelpBrowser.form:52 +#: FConnectionEditor.class:77 FDebugExpr.class:483 FHelpBrowser.form:52 msgid "Index" msgstr "索引" -#: FConnectionEditor.class:81 +#: FConnectionEditor.class:82 msgid "Unique" msgstr "无重复" -#: FConnectionEditor.class:86 FImportTable.class:357 +#: FConnectionEditor.class:87 FImportTable.class:352 msgid "Field" msgstr "字段" -#: FPublish.form:140 FSoftwareFarm.form:178 -msgid "Description" -msgstr "描述" - -#: FConnectionEditor.class:321 +#: FConnectionEditor.class:326 msgid "Unable to connect to database." msgstr "不能连接到数据库。" -#: FConnectionEditor.class:427 FSave.form:35 +#: FConnectionEditor.class:431 FSave.form:35 msgid "Do not save" msgstr "不要保存" -#: FConnectionEditor.class:427 +#: FConnectionEditor.class:431 msgid "The table '&1' has been modified. Do you want to save it?" msgstr "表'&1'已被修改。是否保存?" -#: FConnectionEditor.class:581 +#: FConnectionEditor.class:585 msgid "Unable to load table '&1'." msgstr "不能加载表'&1'。" -#: FConnectionEditor.class:636 +#: FConnectionEditor.class:644 msgid "Unable to run query." msgstr "不能运行查询。" -#: FConnectionEditor.class:668 +#: FConnectionEditor.class:676 msgid "unlimited" msgstr "无限制" -#: FConnectionEditor.class:755 MConnection.module:128 +#: FConnectionEditor.class:763 MConnection.module:132 msgid "Blob" msgstr "-" -#: FConnectionEditor.class:755 MConnection.module:122 MErrorMessage.module:46 +#: FConnectionEditor.class:763 MConnection.module:126 MErrorMessage.module:46 msgid "Boolean" msgstr "布尔值" -#: MConnection.module:120 +#: FConnectionEditor.class:763 FProjectVersion.class:290 MConnection.module:124 msgid "Date" msgstr "日期" -#: FConnectionEditor.class:755 MConnection.module:118 +#: FConnectionEditor.class:763 MConnection.module:122 msgid "Float" msgstr "浮点数" -#: FConnectionEditor.class:755 MConnection.module:114 +#: FConnectionEditor.class:763 MConnection.module:118 msgid "Integer" msgstr "整数" -#: FConnectionEditor.class:755 MConnection.module:116 +#: FConnectionEditor.class:763 MConnection.module:120 msgid "Long" msgstr "长整数" -#: FConnectionEditor.class:755 MConnection.module:126 +#: FConnectionEditor.class:763 MConnection.module:130 msgid "Serial" msgstr "序列" -#: FConnectionEditor.class:755 MConnection.module:124 MErrorMessage.module:155 +#: FConnectionEditor.class:763 MConnection.module:128 MErrorMessage.module:159 msgid "String" msgstr "字符串" -#: FConnectionEditor.class:844 +#: FConnectionEditor.class:852 msgid "This name is already in used." msgstr "该名称已经被使用。" -#: FConnectionEditor.class:869 +#: FConnectionEditor.class:877 msgid "Please enter a number." msgstr "请输入一个数。" -#: FConnectionEditor.class:874 +#: FConnectionEditor.class:882 msgid "The length must be greater than 1 and lower than 255." msgstr "长度必须大于1并小于255。" -#: FConnectionEditor.class:898 +#: FConnectionEditor.class:906 msgid "Type mismatch." msgstr "类型错误" -#: FConnectionEditor.class:950 +#: FConnectionEditor.class:958 msgid "This name already exists." msgstr "该名称已经存在。" -#: FConnectionEditor.class:1038 +#: FConnectionEditor.class:1046 msgid "This field is used in an index." msgstr "该字段被用于一个索引。" -#: FConnectionEditor.class:1389 +#: FConnectionEditor.class:1397 msgid "The table '&1' has no primary key." msgstr "表'&1'没有主键。" -#: FConnectionEditor.class:1521 +#: FConnectionEditor.class:1529 msgid "Cannot write table '&1'." msgstr "不能写入表'&1'。" -#: FConnectionEditor.class:1633 +#: FConnectionEditor.class:1641 msgid "Do you really want to delete table '&1'?" msgstr "你确定要删除表'&1'?" -#: FConnectionEditor.class:1645 +#: FConnectionEditor.class:1653 msgid "Cannot delete table '&1'." msgstr "不能删除表'&1'。" -#: FConnectionEditor.class:1681 -msgid "Select the CSV file to import" -msgstr "选择导入的CSV文件" - -#: FConnectionEditor.class:1682 FSearch.form:172 FTranslate.class:1206 -msgid "All files" -msgstr "所有文件" - -#: FConnectionEditor.class:1682 FExportData.class:21 -msgid "CSV files" -msgstr "CSV文件" - -#: FConnectionEditor.class:1705 +#: FConnectionEditor.class:1706 msgid "Do you really want to remove the selected rows?" msgstr "你确定要删除选中的行?" -#: FConnectionEditor.class:1866 +#: FConnectionEditor.class:1867 msgid "Do you really want to remove this query?" msgstr "确定要删除该查询吗?" @@ -1313,10 +1517,6 @@ msgid "Connection editor" msgstr "连接编辑器" -#: FTextEditor.form:260 FTranslate.form:72 -msgid "Reload" -msgstr "重载" - #: FConnectionEditor.form:117 msgid "Show system tables" msgstr "显示系统表" @@ -1329,7 +1529,9 @@ msgid "Delete table" msgstr "删除表" -#: FPublish.form:237 FSoftwareFarm.form:113 +#: FConnectionEditor.form:133 FMain.form:1033 FMakeInstall.form:734 +#: FOption.form:1121 FProjectProperty.form:562 FPublish.form:268 +#: FSoftwareFarm.form:411 msgid "Remove" msgstr "删除" @@ -1337,7 +1539,7 @@ msgid "Rename table" msgstr "重命名表" -#: FConnectionEditor.form:141 FMain.form:950 +#: FConnectionEditor.form:141 FMain.form:922 msgid "Rename" msgstr "(R)重命名" @@ -1353,7 +1555,8 @@ msgid "Import text file" msgstr "导入文本文件" -#: FTranslate.form:324 +#: FConnectionEditor.form:165 FImportTable.form:48 FOption.form:1129 +#: FTranslate.form:329 msgid "Import" msgstr "导入" @@ -1365,15 +1568,18 @@ msgid "Fields" msgstr "字段" -#: FPublish.form:172 +#: FConnectionEditor.form:233 FMain.class:2108 FMakeInstall.form:728 +#: FOption.form:1352 FProjectProperty.form:638 FPublish.form:158 msgid "Add" msgstr "添加" -#: FPublish.form:249 +#: FConnectionEditor.form:247 FList.form:76 FMakeInstall.form:746 +#: FPublish.form:280 msgid "Down" msgstr "下" -#: FPublish.form:243 +#: FConnectionEditor.form:254 FList.form:70 FMakeInstall.form:740 +#: FPublish.form:274 msgid "Up" msgstr "上" @@ -1397,7 +1603,8 @@ msgid "New query" msgstr "新建查询" -#: FOption.form:1242 FTranslate.form:67 +#: FConnectionEditor.form:365 FCreateFile.form:53 FMain.form:761 +#: FOption.form:1107 FTranslate.form:72 msgid "New" msgstr "新建" @@ -1405,7 +1612,8 @@ msgid "Remove query" msgstr "删除查询" -#: FImageEditor.form:108 FOption.form:1249 FTextEditor.form:100 +#: FConnectionEditor.form:452 FDebugExpr.form:28 FEditor.form:138 +#: FForm.form:164 FImageEditor.form:105 FOption.form:1114 FTextEditor.form:113 msgid "Edit" msgstr "编辑(E)" @@ -1413,11 +1621,13 @@ msgid "Export to CSV file" msgstr "导出到CSV文件" -#: FConnectionEditor.form:461 FTranslate.form:85 +#: FConnectionEditor.form:461 FTranslate.form:90 msgid "Export" msgstr "导出(E)" -#: FSoftwareFarm.class:552 FTranslate.form:77 +#: FConnectionEditor.form:485 FForm.form:212 FList.form:64 FMain.form:929 +#: FMenu.form:101 FNewConnection.class:349 FOption.class:882 +#: FSoftwareFarm.class:581 FTranslate.form:82 msgid "Delete" msgstr "删除" @@ -1425,7 +1635,7 @@ msgid "Gambas 3 project conversion" msgstr "Gambas3工程转换" -#: FCrash.class:73 FTranslate.class:1121 Project.module:4525 +#: FCrash.class:73 FTranslate.class:1130 Project.module:4564 msgid "The '&1' command has failed." msgstr "'&1'命令失败。" @@ -1477,27 +1687,23 @@ msgid "Javascript files" msgstr "Java脚本文件" -#: FCreateFile.class:131 FMain.form:806 +#: FCreateFile.class:131 FMain.form:778 msgid "Module" msgstr "模块" -#: FCreateFile.class:132 FDebugInfo.class:51 FMain.form:813 -msgid "Class" -msgstr "类" - #: FCreateFile.class:143 msgid "Text file" msgstr "文本文件" -#: FCreateFile.class:144 FMain.form:851 +#: FCreateFile.class:144 FMain.form:823 msgid "HTML file" msgstr "HTML文件" -#: FCreateFile.class:145 FMain.form:858 +#: FCreateFile.class:145 FMain.form:830 msgid "Style sheet" msgstr "样式表" -#: FCreateFile.class:146 FMain.form:865 +#: FCreateFile.class:146 FMain.form:837 msgid "Javascript file" msgstr "Java脚本文件" @@ -1505,7 +1711,7 @@ msgid "(No parent)" msgstr "无父类" -#: FCreateFile.class:483 +#: FCreateFile.class:489 msgid "Cannot add file." msgstr "无法添加文件。" @@ -1513,7 +1719,8 @@ msgid "New file" msgstr "新建文件" -#: FSearch.form:100 +#: FCreateFile.form:88 FCreateProjectOld.form:274 FImportTable.form:58 +#: FMakePatch.form:66 FProjectProperty.form:733 FSearch.form:100 msgid "Options" msgstr "选项" @@ -1549,151 +1756,186 @@ msgid "Create symbolic links" msgstr "创建符号链接" -#: FCreateProject.class:127 +#: FCreateProject.class:85 FCreateProjectOld.class:127 msgid "Project checkout has failed." msgstr "工程校检失败。" -#: FCreateProject.class:187 +#: FCreateProject.class:141 FCreateProjectOld.class:187 msgid "Cannot create project!" msgstr "无法创建工程!" -#: FCreateProject.class:235 +#: FCreateProject.class:168 +#, fuzzy +msgid "Please choose a template" +msgstr "请选择菜单位置。" + +#: FCreateProject.class:196 FCreateProjectOld.class:235 msgid "Please enter the location of the repository." msgstr "请输入存储的位置。" -#: FCreateProject.class:260 +#: FCreateProject.class:221 FCreateProjectOld.class:260 msgid "The project has been successfully created." msgstr "创建工程成功。" -#: FCreateProject.form:66 FMain.form:264 +#: FCreateProject.form:31 FCreateProjectOld.form:66 FMain.form:253 msgid "New project" msgstr "新建工程" -#: FCreateProject.form:82 FProjectProperty.form:235 +#: FCreateProject.form:47 FCreateProjectOld.form:82 FProjectProperty.form:295 msgid "Project type" msgstr "工程类型" -#: FCreateProject.form:123 +#: FCreateProject.form:82 +#, fuzzy +msgid "Parent directory" +msgstr "工程目录" + +#: FCreateProject.form:90 +#, fuzzy +msgid "Project details" +msgstr "工程标题" + +#: FCreateProject.form:99 FCreateProjectOld.form:375 +msgid "Project name" +msgstr "工程名" + +#: FCreateProject.form:110 FCreateProjectOld.form:386 FSaveProjectAs.form:48 +msgid "The project name is the name of the project directory." +msgstr "工程目录的名称为工程名。" + +#: FCreateProject.form:121 FCreateProjectOld.form:397 FSaveProjectAs.form:59 +msgid "The project final directory is :" +msgstr "工程最终目录为:" + +#: FCreateProject.form:134 FCreateProjectOld.form:410 +msgid "Project title" +msgstr "工程标题" + +#: FCreateProject.form:145 FCreateProjectOld.form:421 +msgid "The project title is the true name of the application." +msgstr "应用程序的真实名称是工程名。" + +#: FCreateProject.form:154 FProjectProperty.form:843 +msgid "Project is translatable" +msgstr "工程是可翻译的" + +#: FCreateProject.form:159 FCreateProjectOld.form:426 FProjectChooser.form:80 +#: ProjectBox.class:291 +msgid "Open in another window" +msgstr "在另一个窗口打开" + +#: FCreateProject.form:171 FCreateProjectOld.form:438 FProjectVersion.form:171 +msgid "Repository" +msgstr "存储于" + +#: FCreateProject.form:182 FCreateProjectOld.form:449 +msgid "The project repository is directly sent to the 'svn checkout' command." +msgstr "工程软件库是使用'svn checkout'命令直接发送。" + +#: FCreateProjectOld.form:123 msgid "Graphical application" msgstr "图形界面应用程序" -#: FCreateProject.form:145 +#: FCreateProjectOld.form:145 msgid "QT graphical application" msgstr "QT图形界面应用程序" -#: FCreateProject.form:167 +#: FCreateProjectOld.form:167 msgid "GTK+ graphical application" msgstr "GTK+图形界面应用程序" -#: FCreateProject.form:189 +#: FCreateProjectOld.form:189 msgid "Command-line application" msgstr "命令行应用程序" -#: FCreateProject.form:211 +#: FCreateProjectOld.form:211 msgid "SDL application" msgstr "SDL应用程序" -#: FCreateProject.form:233 +#: FCreateProjectOld.form:233 msgid "CGI Web application" msgstr "CGI Web应用程序" -#: FCreateProject.form:259 -msgid "Application stored in a\nSubversion repository" +#: FCreateProjectOld.form:259 +msgid "" +"Application stored in a\n" +"Subversion repository" msgstr "存储于子版本仓库的应用程序" -#: FCreateProject.form:288 +#: FCreateProjectOld.form:288 msgid "Internationalization" msgstr "国际化" -#: FCreateProject.form:306 +#: FCreateProjectOld.form:306 msgid "Settings files management" msgstr "设置文件管理" -#: FCreateProject.form:312 +#: FCreateProjectOld.form:312 msgid "Regular expressions" msgstr "正则表达式" -#: FCreateProject.form:318 +#: FCreateProjectOld.form:318 msgid "XML / XSLT programming" msgstr "XML/XSLT编程" -#: FCreateProject.form:324 +#: FCreateProjectOld.form:324 msgid "OpenGL programming" msgstr "OpenGL编程" -#: FCreateProject.form:330 +#: FCreateProjectOld.form:330 msgid "Image processing" msgstr "图像处理" -#: FCreateProject.form:336 +#: FCreateProjectOld.form:336 msgid "Scientific computing" msgstr "科学计算" -#: FCreateProject.form:342 +#: FCreateProjectOld.form:342 msgid "Visual Basic™ conversion help" msgstr "Visual Basic™转换帮助" -#: FCreateProject.form:352 +#: FCreateProjectOld.form:352 msgid "Component programming" msgstr "组件编程" -#: FCreateProject.form:358 +#: FCreateProjectOld.form:358 msgid "Project parent directory" msgstr "工程父目录" -#: FCreateProject.form:366 +#: FCreateProjectOld.form:366 msgid "Project information" msgstr "工程信息" -#: FCreateProject.form:375 -msgid "Project name" -msgstr "工程名" - -#: FCreateProject.form:386 FSaveProjectAs.form:48 -msgid "The project name is the name of the project directory." -msgstr "工程目录的名称为工程名。" - -#: FCreateProject.form:397 FSaveProjectAs.form:59 -msgid "The project final directory is :" -msgstr "工程最终目录为:" - -#: FCreateProject.form:410 -msgid "Project title" -msgstr "工程标题" - -#: FCreateProject.form:421 -msgid "The project title is the true name of the application." -msgstr "应用程序的真实名称是工程名。" - -#: FCreateProject.form:438 FProjectVersion.form:171 -msgid "Repository" -msgstr "存储于" - -#: FCreateProject.form:449 -msgid "The project repository is directly sent to the 'svn checkout' command." -msgstr "工程软件库是使用'svn checkout'命令直接发送。" - #: FDebugExpr.class:4 msgid "not available" msgstr "不可用" -#: FDebugExpr.class:472 FDebugInfo.class:39 FProjectProperty.class:143 +#: FDebugExpr.class:485 FDebugInfo.class:39 FProjectProperty.class:139 msgid "Value" msgstr "值" -#: FDebugExpr.class:476 +#: FDebugExpr.class:489 msgid "Key" msgstr "-" -#: FDebugExpr.class:482 +#: FDebugExpr.class:495 msgid "Symbol" msgstr "符号" -#: FDebugExpr.form:31 -msgid "Show all symbols" -msgstr "显示所有标识" +#: FDebugExpr.form:33 FDebugInfo.form:124 +msgid "Watch" +msgstr "监视" -#: FDebugExpr.form:48 +#: FDebugExpr.form:38 +#, fuzzy +msgid "Print to console" +msgstr "分离控制台" + +#: FDebugExpr.form:64 +msgid "Show all symbols" +msgstr "显示所有标识" + +#: FDebugExpr.form:81 msgid "No element" msgstr "无元素" @@ -1701,15 +1943,15 @@ msgid "Expression" msgstr "表达式" -#: FDebugInfo.class:53 FProfile.class:632 +#: FDebugInfo.class:53 FProfile.class:639 msgid "Function" msgstr "函数" -#: FOption.form:647 +#: FDebugInfo.class:55 FImageEditor.form:565 FImportTable.class:55 msgid "Line" msgstr "行" -#: FDebugInfo.class:62 FMain.form:260 FTranslate.class:69 +#: FDebugInfo.class:62 FMain.form:249 FTranslate.class:69 msgid "File" msgstr "文件" @@ -1721,254 +1963,277 @@ msgid "Col." msgstr "列。" -#: FDebugInfo.class:92 FImportTable.class:58 +#: FDebugInfo.class:92 FImportTable.class:57 msgid "Message" msgstr "消息" -#: FDebugInfo.class:173 +#: FDebugInfo.class:174 msgid "native code" msgstr "本地代码" -#: FMakeInstall.form:662 FOption.class:713 FOutput.form:84 FPublish.form:184 +#: FDebugInfo.class:560 FImageProperty.form:368 FList.form:86 +#: FMakeInstall.form:752 FOption.class:717 FOutput.form:84 FPublish.form:170 msgid "Clear" msgstr "清除" -#: FDebugInfo.class:559 +#: FDebugInfo.class:560 msgid "Do you want to clear the expression list ?" msgstr "你确定要清除此表达式列表?" -#: FDebugInfo.class:981 +#: FDebugInfo.class:990 msgid "Dynamic variables" msgstr "动态变量" -#: FDebugInfo.class:1402 +#: FDebugInfo.class:1416 msgid "Warnings" msgstr "警告" -#: FDebugInfo.form:49 FMain.form:506 +#: FDebugInfo.form:51 FMain.form:487 msgid "Debug" msgstr "调试" -#: FDebugInfo.form:60 FMain.form:659 FOption.form:447 FSearch.class:93 +#: FDebugInfo.form:62 FMain.form:639 FOption.form:628 FSearch.class:93 msgid "Console" msgstr "控制台" -#: FDebugInfo.form:69 +#: FDebugInfo.form:71 msgid "Local variables" msgstr "局部变量" -#: FDebugInfo.form:78 +#: FDebugInfo.form:80 msgid "Column view" msgstr "列查看" -#: FDebugInfo.form:85 +#: FDebugInfo.form:87 msgid "Copy to clipboard" msgstr "复制到剪贴板" -#: FDebugInfo.form:87 +#: FDebugInfo.form:89 msgid "Copy local variables" msgstr "复制本地变量" -#: FDebugInfo.form:105 +#: FDebugInfo.form:107 msgid "Current object" msgstr "当前对象" -#: FDebugInfo.form:122 -msgid "Watch" -msgstr "监视" - -#: FDebugInfo.form:135 +#: FDebugInfo.form:142 msgid "Add expression" msgstr "添加表达式" -#: FDebugInfo.form:148 +#: FDebugInfo.form:155 msgid "Remove current expression" msgstr "删除当前表达式" -#: FDebugInfo.form:155 +#: FDebugInfo.form:162 msgid "Remove all expressions" msgstr "删除所有表达式" -#: FDebugInfo.form:163 -msgid "Display ME" -msgstr "显示我" +#: FDebugInfo.form:170 +#, fuzzy +msgid "Display expression" +msgstr "正则表达式(X)" -#: FDebugInfo.form:165 +#: FDebugInfo.form:172 msgid "Display" msgstr "显示" -#: FDebugInfo.form:189 MTheme.module:6 +#: FDebugInfo.form:178 +msgid "Display ME" +msgstr "显示我" + +#: FDebugInfo.form:196 MTheme.module:6 msgid "Breakpoints" msgstr "断点" -#: FDebugInfo.form:197 +#: FDebugInfo.form:204 msgid "Remove current breakpoint" msgstr "删除当前断点" -#: FDebugInfo.form:205 +#: FDebugInfo.form:212 msgid "Remove all breakpoints" msgstr "删除所有断点" -#: FDebugInfo.form:238 +#: FDebugInfo.form:245 msgid "Tasks" msgstr "任务" -#: FDebugInfo.form:252 +#: FDebugInfo.form:259 msgid "Search list" msgstr "搜索列表" -#: FDebugInfo.form:261 +#: FDebugInfo.form:268 msgid "Cancel current search" msgstr "取消当前搜索" -#: FDebugInfo.form:277 +#: FDebugInfo.form:285 msgid "Search again" msgstr "重新搜索" -#: FDebugInfo.form:284 +#: FDebugInfo.form:292 msgid "Show search window" msgstr "显示搜索窗口" -#: FDebugInfo.form:324 FSearch.class:502 FTranslate.class:518 +#: FDebugInfo.form:332 FSearch.class:502 FTranslate.class:524 msgid "Search string cannot be found." msgstr "找不到你要查找的字符串" -#: FDebugInfo.form:342 +#: FDebugInfo.form:350 msgid "Stack backtrace" msgstr "堆栈回溯" -#: FTextEditor.class:656 -msgid "The file has been modified.\n\nAll your changes will be lost." -msgstr "此文件己被修改.\n\n你所做的改变将会丢失." +#: FEditor.class:2235 FImageEditor.class:394 FMain.class:2596 +#: FTextEditor.class:673 +msgid "" +"The file has been modified.\n" +"\n" +"All your changes will be lost." +msgstr "" +"此文件己被修改.\n" +"\n" +"你所做的改变将会丢失." -#: FEditor.class:2777 FTextEditor.class:1067 +#: FEditor.class:2695 FTextEditor.class:1085 msgid "(Declarations)" msgstr "(声明)" -#: FEditor.form:97 +#: FEditor.form:100 msgid "Go to" msgstr "转到" -#: FEditor.form:102 FGotoLine.form:12 FTextEditor.form:81 +#: FEditor.form:105 FGotoLine.form:12 FTextEditor.form:94 msgid "Go to line" msgstr "转到第...行" -#: FEditor.form:107 FTextEditor.form:86 +#: FEditor.form:110 FTextEditor.form:99 msgid "Bookmarks" msgstr "书签" -#: FEditor.form:112 +#: FEditor.form:115 msgid "Find definition" msgstr "查找定义" -#: FEditor.form:119 +#: FEditor.form:122 msgid "Open form" msgstr "打开窗口" -#: FEditor.form:173 FImageEditor.form:157 FTextEditor.form:145 +#: FEditor.form:129 FMain.form:955 +#, fuzzy +msgid "Run this class" +msgstr "父类" + +#: FEditor.form:183 FImageEditor.form:154 FTextEditor.form:158 msgid "Select All" msgstr "(A)全选" -#: FEditor.form:183 FOutput.form:94 FTextEditor.form:155 +#: FEditor.form:193 FOutput.form:94 FTextEditor.form:168 msgid "Find next" msgstr "查找下一个" -#: FEditor.form:190 FOutput.form:101 FTextEditor.form:162 +#: FEditor.form:200 FOutput.form:101 FTextEditor.form:175 msgid "Find previous" msgstr "查找上一个" -#: FEditor.form:199 FMain.form:1394 +#: FEditor.form:209 FMain.form:1366 msgid "Run until current line" msgstr "运行到当前行" -#: FEditor.form:206 +#: FEditor.form:216 msgid "Toggle breakpoint" msgstr "使用断点" -#: FEditor.form:213 +#: FEditor.form:223 msgid "Watch expression" msgstr "监视表达式" -#: FEditor.form:221 FTextEditor.form:171 +#: FEditor.form:231 FImageEditor.form:292 FMain.form:616 FTextEditor.form:184 +msgid "View" +msgstr "查看" + +#: FEditor.form:235 FTextEditor.form:188 +#, fuzzy +msgid "Automatic word wrap" +msgstr "自动格式化" + +#: FEditor.form:242 FTextEditor.form:195 +msgid "No split" +msgstr "不拆分" + +#: FEditor.form:248 FTextEditor.form:201 +msgid "Horizontal split" +msgstr "水平拆分" + +#: FEditor.form:255 FTextEditor.form:208 +msgid "Vertical split" +msgstr "垂直拆分" + +#: FEditor.form:262 FTextEditor.form:234 msgid "Advanced" msgstr "高级" -#: FEditor.form:225 FTextEditor.form:182 +#: FEditor.form:266 FTextEditor.form:245 msgid "Lower case" msgstr "小写" -#: FEditor.form:232 FTextEditor.form:175 +#: FEditor.form:273 FTextEditor.form:238 msgid "Upper case" msgstr "大写" -#: FEditor.form:242 +#: FEditor.form:283 msgid "Comment" msgstr "注释" -#: FEditor.form:249 +#: FEditor.form:290 msgid "Uncomment" msgstr "取消注释" -#: FEditor.form:259 FPasteSpecial.form:19 +#: FEditor.form:300 FPasteSpecial.form:19 FTextEditor.form:270 msgid "Paste special" msgstr "特别粘贴" -#: FEditor.form:272 +#: FEditor.form:313 msgid "Format code" msgstr "格式化代码" -#: FEditor.form:278 +#: FEditor.form:319 msgid "Sort procedures" msgstr "排序程序" -#: FEditor.form:285 FImageEditor.form:295 FMain.form:636 FTextEditor.form:225 -msgid "View" -msgstr "查看" - -#: FEditor.form:289 FTextEditor.form:229 -msgid "No split" -msgstr "不拆分" - -#: FEditor.form:295 FTextEditor.form:235 -msgid "Horizontal split" -msgstr "水平拆分" - -#: FEditor.form:302 FTextEditor.form:242 -msgid "Vertical split" -msgstr "垂直拆分" - -#: FEditor.form:313 FForm.form:413 FImageEditor.form:334 FTextEditor.form:253 +#: FEditor.form:330 FForm.form:413 FImageEditor.form:331 FTextEditor.form:299 msgid "Locked" msgstr "锁定" -#: FEditor.form:343 FPasteSpecial.form:51 +#: FEditor.form:360 FPasteSpecial.form:60 FTextEditor.form:329 msgid "Paste as string" msgstr "粘贴为字符串" -#: FEditor.form:348 FPasteSpecial.form:56 +#: FEditor.form:365 FPasteSpecial.form:65 FTextEditor.form:334 msgid "Paste as multi-line string" msgstr "粘贴为多行字符串" -#: FEditor.form:353 FPasteSpecial.form:41 +#: FEditor.form:370 FPasteSpecial.form:50 FTextEditor.form:339 msgid "Paste as comments" msgstr "粘贴为注释" -#: FEditor.form:369 FHelpShortcut.form:24 FOption.form:431 +#: FEditor.form:386 FHelpShortcut.form:24 FOption.form:612 msgid "Editor" msgstr "编辑者" -#: FEditor.form:398 FImageEditor.form:412 FTextEditor.form:311 +#: FEditor.form:415 FImageEditor.form:409 FTextEditor.form:384 msgid "Lock / unlock file" msgstr "锁定/解锁文件" -#: FEditor.form:512 +#: FEditor.form:546 msgid "Make code pretty" msgstr "美化代码" -#: FEditor.form:577 FTextEditor.form:453 +#: FEditor.form:611 FTextEditor.form:535 msgid "Procedure list" msgstr "过程列表" +#: FExportData.class:21 FImportTable.class:47 +msgid "CSV files" +msgstr "CSV文件" + #: FExportData.class:113 msgid "Unable to export data." msgstr "不能导出数据。" @@ -1978,14 +2243,20 @@ msgstr "覆盖(&O)" #: FExportData.class:126 -msgid "This file already exists.\n\nDo you want to overwrite it?" -msgstr "该文件已经存在。\n\n是否覆盖?" +msgid "" +"This file already exists.\n" +"\n" +"Do you want to overwrite it?" +msgstr "" +"该文件已经存在。\n" +"\n" +"是否覆盖?" -#: FExportData.form:31 FImportTable.form:100 +#: FExportData.form:31 FImportTable.form:101 msgid "Delimiter character" msgstr "定界字符" -#: FExportData.form:42 FImportTable.form:111 +#: FExportData.form:42 FImportTable.form:112 msgid "Enclose character" msgstr "包围字符" @@ -1997,81 +2268,85 @@ msgid "Export selected records only" msgstr "仅导出选中的记录" -#: FFarmConfig.class:39 -msgid "Please enter your login." -msgstr "输入登陆用户名。" - -#: FFarmConfig.class:46 -msgid "Please enter your password." -msgstr "输入登陆密码。" - -#: FFarmConfig.class:81 -msgid "Please enter a valid e-mail address." -msgstr "请输入有效的电子邮件地址。" - -#: FFarmConfig.class:87 -msgid "Confirm password does not match." -msgstr "确认密码不匹配。" - -#: FFarmConfig.class:93 -msgid "Unable to register user." -msgstr "不能注册用户。" - -#: FFarmConfig.class:93 -msgid "You have been successfully registered.\n\nYou will receive a confirmation e-mail soon." -msgstr "已成功注册。\n\n马上会收到一封确认电子邮件。" +#: FFarmConfig.form:12 +#, fuzzy +msgid "Farm servers" +msgstr "服务器" -#: FFarmConfig.class:128 +#: FFarmLogin.class:29 msgid "Authentication failed." msgstr "验证失败。" -#: FFarmConfig.form:39 -msgid "Configuration" -msgstr "配置" - -#: FFarmConfig.form:51 FOption.form:239 FPublish.form:279 -msgid "Identity" -msgstr "身份" +#: FFarmLogin.form:26 FPublish.form:312 FSoftwareFarm.form:110 +msgid "Login" +msgstr "登陆" -#: FFarmConfig.form:64 FPublish.form:263 +#: FFarmLogin.form:38 FFarmRegister.form:40 msgid "Server" msgstr "服务器" -#: FFarmConfig.form:80 -msgid "Login" -msgstr "登陆" +#: FFarmLogin.form:59 FFarmRegister.form:61 FNewConnection.form:141 +#: FProjectVersion.form:127 FProxy.form:42 +msgid "User" +msgstr "用户" -#: FProxy.form:47 +#: FFarmLogin.form:74 FFarmRegister.form:76 FNewConnection.form:155 +#: FProjectVersion.form:142 FProxy.form:47 msgid "Password" msgstr "密码" -#: FFarmConfig.form:116 FNewConnection.form:172 FProjectVersion.form:155 +#: FFarmLogin.form:95 FNewConnection.form:175 FProjectVersion.form:155 msgid "Remember password" msgstr "记住口令" -#: FFarmConfig.form:137 -msgid "Register >>" -msgstr "注册>>" +#: FFarmLogin.form:111 +#, fuzzy +msgid "Be anonymous" +msgstr "匿名" -#: FFarmConfig.form:160 FMakeInstall.form:202 FOption.form:272 -msgid "E-mail" -msgstr "电子邮件" +#: FFarmRegister.class:28 +msgid "Please enter a valid e-mail address." +msgstr "请输入有效的电子邮件地址。" -#: FFarmConfig.form:175 -msgid "Confirm password" -msgstr "确认密码" +#: FFarmRegister.class:34 +msgid "Confirm password does not match." +msgstr "确认密码不匹配。" + +#: FFarmRegister.class:40 +msgid "Unable to register user." +msgstr "不能注册用户。" -#: FFarmConfig.form:189 -msgid "A confirmation mail will be sent to the specified e-mail address. Click on the link included in that mail to activate your account.\n

\nYour e-mail will not be stored on the publishing server." -msgstr "一封确认邮件将被发送到指定的电子邮箱地址。单击该邮件中的链接以便激活账户。\n

\n该电子邮箱将不会被存储于发布服务器。" +#: FFarmRegister.class:40 +msgid "" +"You have been successfully registered.\n" +"\n" +"You will receive a confirmation e-mail soon." +msgstr "" +"已成功注册。\n" +"\n" +"马上会收到一封确认电子邮件。" -#: FFarmConfig.form:204 +#: FFarmRegister.form:28 FPublish.form:319 FSoftwareFarm.form:117 msgid "Register" msgstr "注册" -#: FFarmConfig.form:215 -msgid "Servers" -msgstr "服务器" +#: FFarmRegister.form:92 +msgid "Confirm password" +msgstr "确认密码" + +#: FFarmRegister.form:108 FMakeInstall.form:250 FOption.form:274 +msgid "E-mail" +msgstr "电子邮件" + +#: FFarmRegister.form:121 +msgid "" +"A confirmation mail will be sent to the specified e-mail address. Click on the link included in that mail to activate your account.\n" +"

\n" +"Your e-mail will not be stored on the publishing server." +msgstr "" +"一封确认邮件将被发送到指定的电子邮箱地址。单击该邮件中的链接以便激活账户。\n" +"

\n" +"该电子邮箱将不会被存储于发布服务器。" #: FFieldChooser.class:54 FTableChooser.class:66 msgid "Unable to open connection." @@ -2089,11 +2364,11 @@ msgid "Select a field" msgstr "选择一个字段" -#: FFieldChooser.form:38 FTableChooser.form:30 +#: FFieldChooser.form:39 FTableChooser.form:30 msgid "Connection" msgstr "连接" -#: FFieldChooser.form:50 FImportTable.form:155 FPasteTable.form:67 +#: FFieldChooser.form:51 FImportTable.form:156 FPasteTable.form:67 msgid "Table" msgstr "表" @@ -2117,39 +2392,40 @@ msgid "Versioning" msgstr "版本" -#: FFileProperty.class:92 FProjectProperty.form:804 FTranslate.form:310 +#: FFileProperty.class:92 FProjectProperty.form:949 FTranslate.form:315 msgid "Statistics" msgstr "统计" -#: FFileProperty.class:124 +#: FFileProperty.class:125 msgid "This file is locked, and will be deleted on the next commit." msgstr "该文件已被锁定,并将在下次提交时被删除。" -#: FFileProperty.class:126 +#: FFileProperty.class:127 msgid "This file is not versioned, and must be added to the repository." msgstr "该文件未被版本记录,必须添加到软件库。" -#: FFileProperty.class:129 +#: FFileProperty.class:130 msgid "This file has not been modified since the last commit." msgstr "该文件自最近的提交后没有被修改。" -#: FSave.form:21 Project.module:3495 +#: FFileProperty.class:142 FMakeInstall.class:333 FProjectVersion.class:211 +#: FSave.form:21 Project.module:3519 msgid "Continue" msgstr "继续" -#: FFileProperty.class:141 FProjectVersion.class:209 +#: FFileProperty.class:142 FProjectVersion.class:211 msgid "You are going to cancel your changes!" msgstr "改变将被取消!" -#: FFileProperty.class:164 FProjectProperty.class:1384 +#: FFileProperty.class:165 FProjectProperty.class:949 msgid "Modules" msgstr "模块" -#: FFileProperty.class:169 FProjectProperty.class:1392 +#: FFileProperty.class:170 FProjectProperty.class:957 msgid "Lines of code" msgstr "代码行" -#: FFileProperty.form:65 FPatch.form:93 FProjectVersion.form:83 +#: FFileProperty.form:64 FPatch.form:76 FProjectVersion.form:83 msgid "Revert" msgstr "(R)还原" @@ -2157,17 +2433,33 @@ msgid "Select a font" msgstr "选择字体" -#: FForm.class:142 +#: FForm.class:143 msgid "Bad form file" msgstr "错误的表单文件" -#: FForm.class:1305 +#: FForm.class:267 +#, fuzzy +msgid "Unknown control: &1" +msgstr "未知的标识符:&1" + +#: FForm.class:1320 msgid "Component missing for control &1" msgstr "对于控件&1缺失组件" -#: FForm.class:3187 -msgid "The form has been modified.\n\nAll your changes will be lost." -msgstr "窗口己被修改。\n\n将会丢弃所有改变。" +#: FForm.class:1823 +#, fuzzy +msgid "Cannot paste data." +msgstr "不能创建元数据表。" + +#: FForm.class:3216 +msgid "" +"The form has been modified.\n" +"\n" +"All your changes will be lost." +msgstr "" +"窗口己被修改。\n" +"\n" +"将会丢弃所有改变。" #: FForm.form:131 msgid "Select" @@ -2181,12 +2473,13 @@ msgid "Change into" msgstr "变成" -#: FForm.form:148 FMain.form:896 FTextEditor.form:91 +#: FForm.form:148 FMain.form:868 FTextEditor.form:104 msgid "Open code" msgstr "打开代码" #: FForm.form:155 -msgid "Run that form" +#, fuzzy +msgid "Run this form" msgstr "运行表单" #: FForm.form:199 @@ -2225,11 +2518,11 @@ msgid "First" msgstr "第一页(F)" -#: FForm.form:273 FSearch.form:198 FTips.form:71 +#: FForm.form:273 FSearch.form:199 FTips.form:71 msgid "Previous" msgstr "上一个(P)" -#: FForm.form:280 FSearch.form:192 FTips.form:77 +#: FForm.form:280 FSearch.form:193 FTips.form:77 msgid "Next" msgstr "(N)下一个" @@ -2305,7 +2598,7 @@ msgid "Menu editor" msgstr "菜单编辑器" -#: FForm.form:464 FTextEditor.form:304 +#: FForm.form:448 FTextEditor.form:361 msgid "Code" msgstr "代码" @@ -2333,15 +2626,15 @@ msgid "Move tab last" msgstr "移动标签页到末尾" -#: FForm.form:707 FOption.form:220 +#: FForm.form:707 FOption.form:224 msgid "Bold" msgstr "粗体" -#: FForm.form:715 FOption.form:224 +#: FForm.form:715 msgid "Italic" msgstr "斜体" -#: FForm.form:723 FOption.form:228 +#: FForm.form:723 FOption.form:229 msgid "Underline" msgstr "下划线" @@ -2353,11 +2646,11 @@ msgid "Smaller font" msgstr "更小字体" -#: FForm.form:747 FOption.form:371 +#: FForm.form:747 FOption.form:552 msgid "Default font" msgstr "默认字体" -#: FForm.form:755 FOption.form:647 MTheme.module:6 +#: FForm.form:755 FOption.form:1136 MTheme.module:6 msgid "Background" msgstr "背景" @@ -2365,43 +2658,43 @@ msgid "Foreground" msgstr "前景" -#: FFormStack.form:15 FMain.form:1713 +#: FFormStack.form:15 FMain.form:1661 msgid "Hierarchy" msgstr "层次" -#: FFormStack.form:23 +#: FFormStack.form:22 msgid "Click on a form to display the hierarchy of its controls..." msgstr "点选窗口以显示它的控件的层次..." -#: FFormStack.form:32 +#: FFormStack.form:31 msgid "Move top" msgstr "升到顶层" -#: FFormStack.form:38 FMenu.form:145 +#: FFormStack.form:37 FMenu.form:145 msgid "Move up" msgstr "上移" -#: FFormStack.form:44 FMenu.form:151 +#: FFormStack.form:43 FMenu.form:151 msgid "Move down" msgstr "下移" -#: FFormStack.form:50 +#: FFormStack.form:49 msgid "Move bottom" msgstr "降到底层" -#: FHelpBrowser.class:23 FProjectProperty.form:715 +#: FHelpBrowser.class:24 FProjectProperty.form:860 msgid "Default language" msgstr "缺省语言" -#: FHelpBrowser.form:29 FMain.form:1119 +#: FHelpBrowser.form:29 FMain.form:1096 msgid "Help browser" msgstr "(H)帮助浏览器" -#: FHelpBrowser.form:40 FMain.form:686 FProfile.form:48 +#: FHelpBrowser.form:40 FMain.form:666 FProfile.form:48 msgid "Go back" msgstr "后退" -#: FHelpBrowser.form:46 FMain.form:693 FProfile.form:54 +#: FHelpBrowser.form:46 FMain.form:673 FProfile.form:54 msgid "Go forward" msgstr "前进" @@ -2409,18 +2702,6 @@ msgid "Show help tree" msgstr "显示帮助树" -#: FHelpBrowser.form:84 FImageEditor.form:300 -msgid "Zoom in" -msgstr "放大" - -#: FHelpBrowser.form:90 FImageEditor.form:308 -msgid "Zoom out" -msgstr "缩小" - -#: FHelpBrowser.form:96 -msgid "No zoom" -msgstr "无缩放" - #: FHelpBrowser.form:115 msgid "Print" msgstr "打印" @@ -2433,142 +2714,134 @@ msgid "Debugger" msgstr "调试器" -#: FHelpShortcut.form:28 FProjectProperty.form:687 FTranslate.form:108 +#: FHelpShortcut.form:28 FProjectProperty.form:832 FTranslate.form:112 msgid "Translation" msgstr "翻译成:" -#: FImageEditor.form:163 +#: FImageEditor.form:160 msgid "Hide selection" msgstr "隐藏选中" -#: FImageEditor.form:170 MTheme.module:6 +#: FImageEditor.form:167 MTheme.module:6 msgid "Selection" msgstr "选择" -#: FImageEditor.form:175 +#: FImageEditor.form:172 msgid "Invert selection" msgstr "反转选中" -#: FImageEditor.form:183 +#: FImageEditor.form:180 msgid "Duplicate selection" msgstr "复制选中" -#: FImageEditor.form:191 FImageOffsetSelection.form:12 +#: FImageEditor.form:188 FImageOffsetSelection.form:12 msgid "Offset selection" msgstr "偏移选中" -#: FImageEditor.form:198 +#: FImageEditor.form:195 msgid "Shape grid" msgstr "形状栅格" -#: FImageEditor.form:236 +#: FImageEditor.form:233 msgid "Action" msgstr "动作" -#: FImageEditor.form:241 +#: FImageEditor.form:238 msgid "Crop" msgstr "裁剪" -#: FImageEditor.form:249 FImageProperty.form:294 +#: FImageEditor.form:246 FImageProperty.form:293 msgid "Horizontal flip" msgstr "水平翻转" -#: FImageEditor.form:256 FImageProperty.form:288 +#: FImageEditor.form:253 FImageProperty.form:287 msgid "Vertical flip" msgstr "垂直翻转" -#: FImageEditor.form:263 FImageProperty.form:282 +#: FImageEditor.form:260 FImageProperty.form:281 msgid "Rotate counter-clockwise" msgstr "逆时针旋转" -#: FImageEditor.form:271 FImageProperty.form:276 +#: FImageEditor.form:268 FImageProperty.form:275 msgid "Rotate clockwise" msgstr "顺时针旋转" -#: FImageEditor.form:282 +#: FImageEditor.form:279 msgid "Resize" msgstr "改变大小" -#: FImageEditor.form:289 +#: FImageEditor.form:286 msgid "Rotate" msgstr "旋转" -#: FImageEditor.form:316 +#: FImageEditor.form:313 msgid "Zoom normal" msgstr "正常缩放" -#: FImageEditor.form:324 +#: FImageEditor.form:321 msgid "Zoom fit" msgstr "自适应缩放" -#: FImageEditor.form:366 +#: FImageEditor.form:363 msgid "Save as JPEG" msgstr "保存为JPEG" -#: FImageEditor.form:372 +#: FImageEditor.form:369 msgid "Save as PNG" msgstr "保存为PNG" -#: FImageEditor.form:378 +#: FImageEditor.form:375 msgid "Save as BMP" msgstr "保存为BMP" -#: FImageEditor.form:385 +#: FImageEditor.form:382 msgid "Save as TIFF" msgstr "保存为TIFF" -#: FImageEditor.form:392 +#: FImageEditor.form:389 msgid "Image editor" msgstr "图像编辑器" -#: FImageEditor.form:474 +#: FImageEditor.form:471 msgid "Drawing grid" msgstr "绘制栅格" -#: FImageEditor.form:484 +#: FImageEditor.form:481 msgid "Resize or stretch image" msgstr "改变大小或拉伸图像" -#: FImageEditor.form:494 FImageRotate.form:11 +#: FImageEditor.form:491 FImageRotate.form:11 msgid "Rotate image" msgstr "旋转图像" -#: FImageEditor.form:537 +#: FImageEditor.form:534 msgid "Move" msgstr "移动" -#: FImageEditor.form:548 +#: FImageEditor.form:545 msgid "Draw" msgstr "绘图" -#: FImageEditor.form:558 +#: FImageEditor.form:555 msgid "Erase" msgstr "擦除" -#: FImageEditor.form:578 +#: FImageEditor.form:575 msgid "Rectangle" msgstr "矩形" -#: FImageEditor.form:588 +#: FImageEditor.form:585 msgid "Ellipse" msgstr "椭圆形" -#: FImageEditor.form:608 +#: FImageEditor.form:605 msgid "Magic wand" msgstr "魔杖" -#: FImageEditor.form:618 +#: FImageEditor.form:622 msgid "Edit selection" msgstr "编辑选中" -#: FImageEditor.form:662 -msgid "Stroke" -msgstr "笔划" - -#: FImageEditor.form:669 -msgid "Fill" -msgstr "填充" - #: FImageOffsetSelection.form:22 FImageResize.form:127 msgid "px" msgstr "px" @@ -2577,167 +2850,194 @@ msgid "Duplicate" msgstr "复制" -#: FImageProperty.class:797 +#: FImageProperty.class:775 msgid "System clipboard" msgstr "系统剪贴板" -#: FImageProperty.class:1254 +#: FImageProperty.class:1226 msgid "Arrow" msgstr "箭头" -#: FImageProperty.class:1255 +#: FImageProperty.class:1228 msgid "Arrow #2" msgstr "箭头2" -#: FImageProperty.class:1256 +#: FImageProperty.class:1229 msgid "Triangle" msgstr "三角形" -#: FImageProperty.class:1257 +#: FImageProperty.class:1230 msgid "Square triangle" msgstr "直角三角形" -#: FImageProperty.class:1258 +#: FImageProperty.class:1231 msgid "Pentagon" msgstr "五边形" -#: FImageProperty.class:1259 +#: FImageProperty.class:1232 msgid "Hexagon" msgstr "六边形" -#: FImageProperty.form:131 FReportBrushChooser.form:49 +#: FImageProperty.form:131 FOption.form:216 FReportBrushChooser.form:49 msgid "Color" msgstr "颜色" -#: FImageProperty.form:162 +#: FImageProperty.form:161 msgid "Gradient" msgstr "梯度" -#: FImageProperty.form:178 FReportBrushChooser.form:49 +#: FImageProperty.form:177 FReportBrushChooser.form:49 msgid "Linear gradient" msgstr "线性梯度" -#: FImageProperty.form:185 FReportBrushChooser.form:49 +#: FImageProperty.form:184 FReportBrushChooser.form:49 msgid "Radial gradient" msgstr "径向梯度" -#: FImageProperty.form:209 FReportBrushChooser.form:111 +#: FImageProperty.form:208 FReportBrushChooser.form:111 msgid "Add gradient stop" msgstr "添加梯度固定点" -#: FImageProperty.form:215 FReportBrushChooser.form:117 +#: FImageProperty.form:214 FReportBrushChooser.form:117 msgid "Remove gradient stop" msgstr "移除梯度固定点" -#: FImageProperty.form:221 FReportBrushChooser.form:123 +#: FImageProperty.form:220 FReportBrushChooser.form:123 msgid "Select gradient stop color..." msgstr "选择梯度固定点颜色..." -#: FImageProperty.form:227 FReportBrushChooser.form:129 +#: FImageProperty.form:226 FReportBrushChooser.form:129 msgid "Invert gradient" msgstr "反转梯度" -#: FImageProperty.form:249 FReportBrushChooser.form:145 +#: FImageProperty.form:248 FReportBrushChooser.form:145 msgid "Radius" msgstr "半径" -#: FImageProperty.form:316 +#: FImageProperty.form:315 msgid "Clipboard" msgstr "剪贴板" -#: FImageProperty.form:328 +#: FImageProperty.form:327 msgid "Shapes" msgstr "形状" -#: FImageProperty.form:356 +#: FImageProperty.form:352 +msgid "Stroke" +msgstr "笔划" + +#: FImageProperty.form:360 +msgid "Fill" +msgstr "填充" + +#: FImageProperty.form:376 +#, fuzzy +msgid "Colorize" +msgstr "颜色" + +#: FImageProperty.form:384 +#, fuzzy +msgid "Desaturate" +msgstr "特效" + +#: FImageProperty.form:392 +#, fuzzy +msgid "Make transparent" +msgstr "保存翻译" + +#: FImageProperty.form:411 msgid "Opacity" msgstr "不透明" -#: FImageProperty.form:375 FSelectIcon.form:54 FTranslate.class:70 +#: FImageProperty.form:430 FSelectIcon.form:54 FTranslate.class:70 msgid "Size" msgstr "大小" -#: FImageProperty.form:392 +#: FImageProperty.form:447 msgid "Tolerance" msgstr "容差" -#: FImageProperty.form:419 +#: FImageProperty.form:466 +msgid "Roundness" +msgstr "" + +#: FImageProperty.form:492 msgid "Effects" msgstr "效果" -#: FImageProperty.form:429 +#: FImageProperty.form:502 msgid "Brightness" msgstr "亮度" -#: FImageProperty.form:447 +#: FImageProperty.form:520 msgid "Contrast" msgstr "对比度" -#: FImageProperty.form:465 +#: FImageProperty.form:538 msgid "Gamma" msgstr "反衬度" -#: FImageProperty.form:483 +#: FImageProperty.form:556 msgid "Lightness" msgstr "明度" -#: FImageProperty.form:501 +#: FImageProperty.form:574 msgid "Hue" msgstr "色调" -#: FImageProperty.form:519 +#: FImageProperty.form:592 msgid "Saturation" msgstr "饱和度" -#: FImageProperty.form:537 +#: FImageProperty.form:610 msgid "Blur" msgstr "模糊" -#: FImageProperty.form:559 FImportTable.form:187 +#: FImageProperty.form:632 FImportTable.form:188 msgid "Preview" msgstr "预览" -#: FImageProperty.form:571 FOption.form:1318 FProjectProperty.form:395 +#: FImageProperty.form:644 FOption.form:1366 FProjectProperty.form:589 msgid "Reset" msgstr "重置" -#: FImageProperty.form:578 FMain.form:447 FPatch.form:86 +#: FImageProperty.form:651 FMain.form:436 FPatch.form:69 msgid "Apply" msgstr "应用" -#: FImageProperty.form:604 +#: FImageProperty.form:677 msgid "Centered" msgstr "居中" -#: FImageProperty.form:613 +#: FImageProperty.form:686 msgid "Right align" msgstr "右端对齐" -#: FImageProperty.form:622 +#: FImageProperty.form:695 msgid "Left align" msgstr "左端对齐" -#: FImageProperty.form:636 +#: FImageProperty.form:709 msgid "Top align" msgstr "顶端对齐" -#: FImageProperty.form:646 +#: FImageProperty.form:719 msgid "Middle align" msgstr "居中对齐" -#: FImageProperty.form:655 +#: FImageProperty.form:728 msgid "Baseline align" msgstr "基线对齐" -#: FImageProperty.form:664 +#: FImageProperty.form:737 msgid "Bottom align" msgstr "底端对齐" -#: FImageProperty.form:696 +#: FImageProperty.form:769 msgid "Grid resolution" msgstr "网格分辨率" -#: FImageProperty.form:710 +#: FImageProperty.form:783 msgid "Subdivision" msgstr "细分" @@ -2777,86 +3077,86 @@ msgid "°" msgstr "-" -#: FImportTable.class:133 +#: FImportTable.class:47 FSearch.form:173 FTranslate.class:1215 +msgid "All files" +msgstr "所有文件" + +#: FImportTable.class:128 msgid "(Automatic key)" msgstr "(自动Key)" -#: FImportTable.class:271 +#: FImportTable.class:265 msgid "Field_&1" msgstr "字段_&1" -#: FImportTable.class:385 +#: FImportTable.class:380 msgid "Not enough values" msgstr "没有足够的值" -#: FImportTable.class:387 +#: FImportTable.class:382 msgid "Too many values" msgstr "太多的值" -#: FImportTable.class:411 +#: FImportTable.class:407 msgid "Cancelled by user" msgstr "用户取消" -#: FImportTable.class:420 +#: FImportTable.class:416 msgid "No record imported." msgstr "无导入记录。" -#: FImportTable.class:422 +#: FImportTable.class:418 msgid "One record imported." msgstr "一条导入记录。" -#: FImportTable.class:424 +#: FImportTable.class:420 msgid "&1 records imported." msgstr "&1导入记录。" -#: FImportTable.form:38 +#: FImportTable.form:35 msgid "Import file" msgstr "导入文件" -#: FImportTable.form:50 -msgid "File properties" -msgstr "文件属性" +#: FImportTable.form:52 +msgid "Select the CSV file to import" +msgstr "选择导入的CSV文件" -#: FImportTable.form:67 FPasteTable.form:40 +#: FImportTable.form:68 FPasteTable.form:40 msgid "Source" msgstr "源" -#: FImportTable.form:77 +#: FImportTable.form:78 msgid "Charset" msgstr "字符集" -#: FImportTable.form:88 +#: FImportTable.form:89 FTextEditor.form:215 msgid "End of line" msgstr "行结束符" -#: FImportTable.form:123 +#: FImportTable.form:124 msgid "Strip useless white spaces" msgstr "剔除无用的空白" -#: FImportTable.form:128 +#: FImportTable.form:129 msgid "Ignore first lines" msgstr "忽略首行" -#: FImportTable.form:138 +#: FImportTable.form:139 msgid "Line(s)" msgstr "行" -#: FImportTable.form:145 FPasteTable.form:51 +#: FImportTable.form:146 FPasteTable.form:51 msgid "Destination" msgstr "目的" -#: FImportTable.form:170 +#: FImportTable.form:171 msgid "The first line contains field names" msgstr "第一行包含字段名" -#: FImportTable.form:175 +#: FImportTable.form:176 msgid "Key field" msgstr "Key字段" -#: FImportTable.form:195 -msgid "Messages" -msgstr "消息" - #: FList.class:103 msgid "Item &1" msgstr "条目&1" @@ -2869,483 +3169,473 @@ msgid "Edit list property" msgstr "编辑列表属性" -#: FList.form:58 FMenu.form:85 FProjectProperty.form:520 +#: FList.form:58 FMenu.form:85 FProjectProperty.form:712 msgid "Insert" msgstr "插入" -#: FMain.class:214 +#: FMain.class:226 msgid "Do you really want to delete this link ?" msgstr "确定删除该链接吗?" -#: FMain.class:217 +#: FMain.class:229 msgid "Do you really want to delete this directory ?" msgstr "你确定要删除此目录?" -#: FMain.class:229 +#: FMain.class:241 msgid "Do you really want to delete this file ?" msgstr "你确定要删除此文件?" -#: FMain.class:236 +#: FMain.class:248 msgid "Cannot delete file or directory" msgstr "无法复制文件&1" -#: FMain.class:254 +#: FMain.class:266 msgid "File or directory does not exist anymore." msgstr "文件或目录不再存在。" -#: FMain.class:675 +#: FMain.class:690 msgid "Sort history" msgstr "排序历史" -#: FMain.class:679 FOpenProject.form:77 FWelcome.form:31 +#: FMain.class:694 FOpenProject.form:77 FWelcome.form:33 msgid "Sort by date" msgstr "按日期排序" -#: FMain.class:679 FOpenProject.form:86 FWelcome.form:39 +#: FMain.class:694 FOpenProject.form:86 FWelcome.form:41 msgid "Sort by name" msgstr "按名称排序" -#: FMain.class:679 FOpenProject.form:94 FWelcome.form:46 +#: FMain.class:694 FOpenProject.form:94 FWelcome.form:48 msgid "Sort by path" msgstr "按路径排序" -#: FMain.class:691 +#: FMain.class:706 msgid "&Clear history" msgstr "(&C)清除历史" -#: FMain.class:875 +#: FMain.class:890 msgid "New folder" msgstr "新建目录" -#: FMain.class:946 -msgid "The GNU translation tools are not installed on your system.\n\nPlease install them to be able to do the translation." -msgstr "系统没有安装GNU翻译工具。\n\n请安装它们以便进行翻译。" - -#: FMain.class:1184 FPropertyComponent.class:163 -msgid "Library properties" -msgstr "库属性" +#: FMain.class:961 +msgid "" +"The GNU translation tools are not installed on your system.\n" +"\n" +"Please install them to be able to do the translation." +msgstr "" +"系统没有安装GNU翻译工具。\n" +"\n" +"请安装它们以便进行翻译。" -#: FMain.class:1656 +#: FMain.class:1666 msgid "Unable to drop file into the project." msgstr "不能将文件拖入工程。" -#: FMain.class:1774 +#: FMain.class:1784 msgid "All backup or generated files will be removed from the project directory." msgstr "从工程目录中删除所有备份文件和生成的文件。" -#: FMain.class:1774 +#: FMain.class:1784 msgid "Clean" msgstr "清理" -#: FMain.class:2083 +#: FMain.class:2108 msgid "Do you really want to add every file to the repository?" msgstr "确定添加所有文件到软件库吗?" -#: FMain.class:2219 +#: FMain.class:2230 msgid "Choose a profile" msgstr "选取一个profile" -#: FMain.class:2220 +#: FMain.class:2231 msgid "Profile for &1 project" msgstr "&1工程的profile" -#: FMain.class:2457 FProperty.class:976 +#: FMain.class:2468 FProperty.class:1011 msgid "Select a file" msgstr "选择一个文件" -#: FMain.class:2469 +#: FMain.class:2480 msgid "This file is located inside the project." msgstr "该文件位于工程内部。" -#: FMain.class:2585 FMenu.class:72 +#: FMain.class:2596 FMenu.class:72 msgid "Ignore" msgstr "忽略" -#: FMain.form:271 FWelcome.class:62 +#: FMain.form:260 FWelcome.class:67 msgid "Open project" msgstr "打开工程" -#: FMain.form:277 +#: FMain.form:266 msgid "Open recent" msgstr "打开最近的" -#: FMain.form:285 +#: FMain.form:274 msgid "Open example" msgstr "(E)打开范例" -#: FMain.form:294 FWelcome.class:66 +#: FMain.form:283 FWelcome.class:72 msgid "Open file" msgstr "打开文件" -#: FMain.form:303 +#: FMain.form:292 msgid "Save project" msgstr "保存工程" -#: FMain.form:311 FSaveProjectAs.form:18 +#: FMain.form:300 FSaveProjectAs.form:18 msgid "Save project as" msgstr "另存工程" -#: FMain.form:322 FMakeInstall.class:307 FSave.class:28 FWelcome.class:68 +#: FMain.form:311 FMakeInstall.class:266 FSave.class:28 FWelcome.class:74 msgid "Quit" msgstr "退出" -#: FMain.form:358 +#: FMain.form:347 msgid "Save as" msgstr "另存" -#: FMain.form:388 +#: FMain.form:377 msgid "Compile" msgstr "编译" -#: FMain.form:395 +#: FMain.form:384 msgid "Compile All" msgstr "(A)全部编译" -#: FMain.form:405 +#: FMain.form:394 msgid "Translate" msgstr "翻译" -#: FMain.form:414 +#: FMain.form:403 msgid "Make" msgstr "编译" -#: FMain.form:418 +#: FMain.form:407 msgid "Executable" msgstr "(X)可执行文件" -#: FMain.form:425 FMakePatch.form:53 +#: FMain.form:414 FMakePatch.form:53 msgid "Source archive" msgstr "(S)源归档文件" -#: FMain.form:432 +#: FMain.form:421 msgid "Installation package" msgstr "(I)安装包" -#: FMain.form:439 +#: FMain.form:428 msgid "Patch" msgstr "补丁" -#: FMain.form:442 +#: FMain.form:431 msgid "Create" msgstr "创建" -#: FMain.form:454 FPublish.form:63 +#: FMain.form:443 FPublish.form:64 msgid "Publish" msgstr "发布" -#: FMain.form:463 FProjectVersion.form:95 +#: FMain.form:452 FProjectVersion.form:95 msgid "Clean up" msgstr "清理" -#: FMain.form:469 +#: FMain.form:458 msgid "Refresh" msgstr "(R)刷新" -#: FMain.form:475 +#: FMain.form:464 msgid "Put on version control" msgstr "置于版本控制" -#: FMain.form:492 FPropertyComponent.form:43 -msgid "Component properties" -msgstr "组件属性" - -#: FMain.form:500 +#: FMain.form:481 msgid "Version control" msgstr "版本控制" -#: FMain.form:511 +#: FMain.form:492 msgid "Run" msgstr "运行" -#: FMain.form:518 +#: FMain.form:499 msgid "Use terminal emulator" msgstr "使用终端仿真器" -#: FMain.form:524 FProjectProperty.form:775 +#: FMain.form:505 FProjectProperty.form:920 msgid "Redirect standard error output" msgstr "重定向标准错误输出" -#: FMain.form:530 FProjectProperty.form:793 +#: FMain.form:511 FProjectProperty.form:938 msgid "Use embedded HTTP server" msgstr "使用嵌入式HTTP服务" -#: FMain.form:536 FProjectProperty.form:741 +#: FMain.form:517 FProjectProperty.form:886 msgid "Activate profiling" msgstr "激活profile" -#: FMain.form:542 +#: FMain.form:523 msgid "GUI component" msgstr "GUI组件" -#: FMain.form:546 +#: FMain.form:527 msgid "Current desktop" msgstr "当前桌面" -#: FMain.form:576 +#: FMain.form:541 +msgid "QT5" +msgstr "" + +#: FMain.form:563 msgid "Pause" msgstr "暂停" -#: FMain.form:583 +#: FMain.form:570 msgid "Stop" msgstr "停止" -#: FMain.form:590 +#: FMain.form:577 msgid "Step" msgstr "步进" -#: FMain.form:597 +#: FMain.form:584 msgid "Forward" msgstr "前进" -#: FMain.form:604 +#: FMain.form:591 msgid "Finish" msgstr "(H)结束" -#: FMain.form:610 -msgid "Break on each error" -msgstr "出错即中断" - -#: FMain.form:620 +#: FMain.form:600 msgid "Open profile" msgstr "打开profile" -#: FMain.form:626 +#: FMain.form:606 msgid "Clear all breakpoints" msgstr "(A)清除全部断点" -#: FMain.form:631 +#: FMain.form:611 msgid "Close all debug windows" msgstr "(D)关闭所有调试窗口" -#: FMain.form:669 +#: FMain.form:649 msgid "Status bar" msgstr "状态条" -#: FMain.form:676 +#: FMain.form:656 msgid "Hide menubar" msgstr "隐藏菜单条" -#: FMain.form:700 +#: FMain.form:680 msgid "Close all windows" msgstr "(A)关闭所有窗口" -#: FMain.form:706 +#: FMain.form:686 msgid "Tools" msgstr "工具" -#: FMain.form:710 +#: FMain.form:690 msgid "Find" msgstr "查找(F)" -#: FMain.form:716 FSearch.form:76 +#: FMain.form:696 FSearch.form:76 msgid "Replace" msgstr "替换" -#: FMain.form:726 +#: FMain.form:706 msgid "Browse project" msgstr "(B)浏览工程" -#: FMain.form:733 +#: FMain.form:713 msgid "Open a terminal" msgstr "(O)打开一个终端" -#: FMain.form:740 +#: FMain.form:720 msgid "Send project by mail" msgstr "通过电子邮件发送工程" -#: FMain.form:746 FScreenshot.form:12 -msgid "Take screenshot" -msgstr "" - -#: FMain.form:753 +#: FMain.form:726 msgid "Update all forms" msgstr "刷新全部窗体" -#: FMain.form:762 FWelcome.class:65 +#: FMain.form:735 FWelcome.class:71 msgid "Software farm" msgstr "软件农场" -#: FMain.form:771 FOption.form:773 +#: FMain.form:744 FOption.form:828 msgid "Shortcuts" msgstr "快捷键" -#: FMain.form:777 FOption.form:198 +#: FMain.form:750 FOption.form:204 msgid "Preferences" msgstr "首选项" -#: FMain.form:791 +#: FMain.form:764 msgid "Directory" msgstr "目录" -#: FMain.form:796 +#: FMain.form:769 msgid "Project link" msgstr "工程链接" -#: FMain.form:873 +#: FMain.form:845 msgid "Other" msgstr "其它(O)" -#: FMain.form:880 FOpenProject.form:44 +#: FMain.form:852 FOpenProject.form:44 msgid "Recent" msgstr "最近" -#: FMain.form:901 +#: FMain.form:873 msgid "Open in file manager" msgstr "在文件管理器中打开" -#: FMain.form:906 +#: FMain.form:878 msgid "Open with" msgstr "用...打开" -#: FMain.form:914 +#: FMain.form:886 msgid "Compress all" msgstr "全部压缩" -#: FMain.form:920 +#: FMain.form:892 msgid "Uncompress all" msgstr "全部解压缩" -#: FMain.form:967 +#: FMain.form:939 msgid "Copy file path" msgstr "(H)复制文件路径" -#: FMain.form:976 +#: FMain.form:948 msgid "Startup class" msgstr "(S)启动类" -#: FMain.form:985 +#: FMain.form:963 msgid "Add to repository" msgstr "添加到软件库" -#: FMain.form:990 FSoftwareFarm.form:352 +#: FMain.form:968 FSoftwareFarm.form:197 msgid "Filter" msgstr "过滤器" -#: FMain.form:993 +#: FMain.form:971 msgid "Show exported classes" msgstr "显示输出类" -#: FMain.form:998 +#: FMain.form:976 msgid "Show added files" msgstr "显示添加的文件" -#: FMain.form:1003 +#: FMain.form:981 msgid "Show files in conflict" msgstr "显示冲突文件" -#: FMain.form:1012 +#: FMain.form:989 msgid "Show all" msgstr "全部显示" -#: FMain.form:1018 +#: FMain.form:995 msgid "Add everything to repository" msgstr "全部添加到软件库" -#: FMain.form:1034 FNewConnection.class:143 +#: FMain.form:1011 FNewConnection.class:145 msgid "New connection" msgstr "新建连接" -#: FMain.form:1110 FOutput.form:205 +#: FMain.form:1087 FOutput.form:204 msgid "?" msgstr "帮助" -#: FMain.form:1127 FTips.form:18 +#: FMain.form:1104 FTips.form:18 msgid "Tips of the day" msgstr "今日知识" -#: FMain.form:1133 +#: FMain.form:1110 msgid "Keyboard shortcuts" msgstr "快捷键" -#: FMain.form:1142 +#: FMain.form:1119 msgid "System informations" msgstr "系统信息" -#: FMain.form:1200 FProjectProperty.form:125 +#: FMain.form:1178 FProjectProperty.form:148 msgid "Project properties" msgstr "工程属性" -#: FMain.form:1207 +#: FMain.form:1185 msgid "Project version control" msgstr "工程版本控制" -#: FMain.form:1221 +#: FMain.form:1193 msgid "Refresh project" msgstr "刷新工程" -#: FMain.form:1248 FMakeExecutable.form:15 +#: FMain.form:1220 FMakeExecutable.form:15 msgid "Make executable" msgstr "制作可执行文件" -#: FMain.form:1263 +#: FMain.form:1235 msgid "Make source archive" msgstr "生成源归档文件" -#: FMain.form:1271 FMakeInstall.form:113 +#: FMain.form:1243 FMakeInstall.form:129 msgid "Make installation package" msgstr "生成安装包" -#: FMain.form:1293 +#: FMain.form:1265 msgid "Properties sheet" msgstr "属性页" -#: FMain.form:1302 +#: FMain.form:1274 msgid "Toolbox" msgstr "工具箱" -#: FMain.form:1320 FOutput.form:165 FSearch.form:62 +#: FMain.form:1292 FOutput.form:165 FSearch.form:62 msgid "Search" msgstr "搜索" -#: FMain.form:1344 +#: FMain.form:1316 msgid "Compile all" msgstr "全部编译" -#: FMain.form:1386 +#: FMain.form:1358 msgid "Finish current function" msgstr "结束当前函数或过程" -#: FMain.form:1411 +#: FMain.form:1374 msgid "Show menubar" msgstr "显示菜单条" -#: FMain.form:1421 +#: FMain.form:1384 msgid "Browse project..." msgstr "浏览工程..." -#: FMain.form:1473 +#: FMain.form:1436 msgid "&File" msgstr "(&F)文件" -#: FMain.form:1484 +#: FMain.form:1447 msgid "&Project" msgstr "(&P)工程" -#: FMain.form:1495 +#: FMain.form:1458 msgid "&Debug" msgstr "(&D)调试" -#: FMain.form:1506 +#: FMain.form:1469 msgid "&View" msgstr "(&V)视图" -#: FMain.form:1517 +#: FMain.form:1480 msgid "&Tools" msgstr "(&T)工具" -#: FMain.form:1528 +#: FMain.form:1491 msgid "&?" msgstr "(&H)帮助" -#: FMain.form:1537 FPublish.form:50 +#: FMain.form:1500 FPublish.form:51 msgid "Publish software" msgstr "发布软件" -#: FMain.form:1612 FProjectProperty.form:345 -msgid "Reset filter" -msgstr "重置过滤器" - -#: FMakeExecutable.class:18 FProjectProperty.class:1118 +#: FMakeExecutable.class:18 FProjectProperty.class:774 msgid "Gambas applications" msgstr "Gambas应用程序" @@ -3365,243 +3655,261 @@ msgid "Create a shortcut on the desktop" msgstr "创建桌面快捷方式" -#: FMakeInstall.class:108 +#: FMakeInstall.class:125 msgid "Package" msgstr "包" -#: FMakeInstall.class:109 +#: FMakeInstall.class:126 msgid "Min. version" msgstr "最低版本" -#: FMakeInstall.class:110 +#: FMakeInstall.class:127 msgid "Max. version" msgstr "最大版本" -#: FMakeInstall.class:116 +#: FMakeInstall.class:133 msgid "File or directory" msgstr "文件或目录" -#: FMakeInstall.class:307 Package.module:199 +#: FMakeInstall.class:266 Package.module:275 msgid "The packages have been successfully created." msgstr "建包成功." -#: FMakeInstall.class:343 +#: FMakeInstall.class:314 msgid "Please enter your name." msgstr "请输入你的姓名" -#: FMakeInstall.class:348 +#: FMakeInstall.class:319 msgid "Please enter your e-mail address." msgstr "请输入你的电子邮件地址" -#: FMakeInstall.class:361 +#: FMakeInstall.class:333 msgid "There is no CHANGELOG entry for this release." msgstr "本次发布没有更新日志。" -#: FMakeInstall.class:368 +#: FMakeInstall.class:340 msgid "Please enter the first CHANGELOG entry." msgstr "请输入第一个更改记录项." -#: FMakeInstall.class:379 +#: FMakeInstall.class:351 msgid "Please choose at least one target distribution." msgstr "请选择至少一个分派目标。" -#: FMakeInstall.class:417 +#: FMakeInstall.class:389 msgid "Please choose the package group for each target distribution." msgstr "请为每个分派目标选择包所属的组。" -#: FMakeInstall.class:419 +#: FMakeInstall.class:391 msgid "Please choose a package group." msgstr "请选择包所属的组。" -#: FMakeInstall.class:429 +#: FMakeInstall.class:401 msgid "Please choose the menu location for each target distribution." msgstr "请为每个分派目标选择菜单位置。" -#: FMakeInstall.class:431 +#: FMakeInstall.class:403 msgid "Please choose a menu location." msgstr "请选择菜单位置。" -#: FMakeInstall.class:450 +#: FMakeInstall.class:422 msgid "Cannot found extra file: &1" msgstr "不能找到附加文件:&1" -#: FMakeInstall.class:455 +#: FMakeInstall.class:428 msgid "Please choose a target directory for each extra file." msgstr "请选择每个附加文件的目标目录。" -#: FMakeInstall.class:469 +#: FMakeInstall.class:436 +msgid "Debian packaging system cannot handle spaces in file names." +msgstr "" + +#: FMakeInstall.class:442 +msgid "Debian packaging system cannot handle spaces in directories." +msgstr "" + +#: FMakeInstall.class:458 msgid "The package cannot be stored inside the project directory." msgstr "包无法保存在工程目录。" -#: FMakeInstall.class:507 +#: FMakeInstall.class:506 msgid "Initial release" msgstr "首次发布" -#: FMakeInstall.class:753 +#: FMakeInstall.class:763 msgid "Menus" msgstr "菜单" -#: FMakeInstall.class:821 +#: FMakeInstall.class:831 msgid "Groups" msgstr "组" -#: FMakeInstall.class:939 +#: FMakeInstall.class:955 msgid "Incorrect characters" msgstr "错误的字符" -#: FMakeInstall.class:1012 +#: FMakeInstall.class:1028 msgid "Do you really want to remove all extra dependencies?" msgstr "你确定要移除所有附加从属部分吗?" -#: FMakeInstall.class:1111 +#: FMakeInstall.class:1127 msgid "Do you really want to remove all extra files?" msgstr "你确定要移除所有附加文件吗?" -#: FMakeInstall.class:1167 +#: FMakeInstall.class:1175 msgid "Select the destination directory" msgstr "选择目的目录" -#: FMakeInstall.form:128 +#: FMakeInstall.form:142 +msgid "Create package" +msgstr "创建包" + +#: FMakeInstall.form:146 msgid "Package information" msgstr "包信息" -#: FMakeInstall.form:134 +#: FMakeInstall.form:152 msgid "Package name" msgstr "安装包名称" -#: FMakeInstall.form:153 FOption.form:344 -msgid "Prefix package name with the vendor name" -msgstr "安装包名称前缀销售商名称" +#: FMakeInstall.form:173 FOption.form:362 +msgid "Add vendor prefix or name to package names" +msgstr "" -#: FMakeInstall.form:160 +#: FMakeInstall.form:180 msgid "Package version" msgstr "安装包版本" -#: FMakeInstall.form:175 -msgid "Maintainer information" -msgstr "维护者信息" - -#: FSoftwareFarm.form:313 +#: FMakeInstall.form:197 FOption.form:296 FPublish.form:83 msgid "Vendor name" msgstr "销售商名称" -#: FMakeInstall.form:234 FOption.form:328 +#: FMakeInstall.form:212 FOption.form:312 +#, fuzzy +msgid "Vendor prefix" +msgstr "销售商名称" + +#: FMakeInstall.form:225 +msgid "Maintainer information" +msgstr "维护者信息" + +#: FMakeInstall.form:265 FOption.form:346 msgid "URL" msgstr "URL" -#: FMakeInstall.form:271 +#: FMakeInstall.form:302 msgid "License" msgstr "许可" -#: FMakeInstall.form:282 +#: FMakeInstall.form:313 msgid "Changelog" msgstr "变更日志" -#: FMakeInstall.form:288 -msgid "Please enter the changes of your project." -msgstr "请输入工程的变化。" - -#: FMakeInstall.form:309 +#: FMakeInstall.form:333 msgid "Target distribution" msgstr "目标发行版" -#: FMakeInstall.form:510 +#: FMakeInstall.form:600 msgid "Self-extractible" msgstr "自解压缩" -#: FMakeInstall.form:515 +#: FMakeInstall.form:605 msgid "Package group" msgstr "包组" -#: FMakeInstall.form:535 +#: FMakeInstall.form:625 msgid "Menu entry" msgstr "菜单条目" -#: FMakeInstall.form:557 +#: FMakeInstall.form:647 msgid "Categories" msgstr "类别" -#: FMakeInstall.form:566 +#: FMakeInstall.form:656 msgid "Desktop configuration file" msgstr "桌面配置文件" -#: FMakeInstall.form:572 +#: FMakeInstall.form:662 msgid "Mimetypes" msgstr "MIME 类型" -#: FMakeInstall.form:580 -msgid "Enter the mimetypes handled by your application there.\nPlease enter one mimetype by line.\n" -msgstr "输入被应用程序处理的mime类型。\n请输入一个mimie类型行。\n" +#: FMakeInstall.form:670 +msgid "" +"Enter the mimetypes handled by your application there.\n" +"Please enter one mimetype by line.\n" +msgstr "" +"输入被应用程序处理的mime类型。\n" +"请输入一个mimie类型行。\n" -#: FMakeInstall.form:592 +#: FMakeInstall.form:682 msgid "Additional configuration" msgstr "附加配置" -#: FMakeInstall.form:600 +#: FMakeInstall.form:690 msgid "The following will be added to the end of the desktop configuration file." msgstr "下列内容将被添加到桌面配置文件末尾。" -#: FMakeInstall.form:608 +#: FMakeInstall.form:698 msgid "Extra dependencies" msgstr "附加从属部分" -#: FMakeInstall.form:612 +#: FMakeInstall.form:702 msgid "Same dependencies for all targets" msgstr "对所有目标使用相同的从属部分" -#: FMakeInstall.form:668 +#: FMakeInstall.form:758 msgid "Extra files" msgstr "附加文件" -#: FMakeInstall.form:672 +#: FMakeInstall.form:762 msgid "Same files for all targets" msgstr "对所有目标使用相同的文件" -#: FMakeInstall.form:685 +#: FMakeInstall.form:775 msgid "Extra files must be located in the Project folder of the current project, i.e. the .hidden directory of the project on the disk." msgstr "附加文件必须被放在当前工程的工程文件夹中,例如磁盘上工程的.hidden目录。" -#: FMakeInstall.form:743 +#: FMakeInstall.form:833 msgid "Extra autoconf tests" msgstr "附加autoconf测试" -#: FMakeInstall.form:749 -msgid "Add extra tests for the configuration process.\n

Leave this blank if you don't need it, or if you don't know anything about autoconf scripts." -msgstr "为配置进程添加附加测试。\n

如果你不需要或者对autoconf脚本一窍不通的就保留这个空白。" +#: FMakeInstall.form:839 +msgid "" +"Add extra tests for the configuration process.\n" +"

Leave this blank if you don't need it, or if you don't know anything about autoconf scripts." +msgstr "" +"为配置进程添加附加测试。\n" +"

如果你不需要或者对autoconf脚本一窍不通的就保留这个空白。" -#: FMakeInstall.form:757 +#: FMakeInstall.form:847 msgid "Destination directory" msgstr "目的目录" -#: FMakeInstall.form:766 +#: FMakeInstall.form:856 msgid "Create directories for each distribution" msgstr "为每个发布创建目录" -#: FMakeInstall.form:769 -msgid "Create package" -msgstr "创建包" - -#: FMakeInstall.form:775 -msgid "All needed information have been collected. You can now create the installation packages for your application...\n

Click on the OK button to create the packages.\n

Click on the Previous button if you had made a mistake.\n

Click on the Cancel button to cancel the operation.\n\n" -msgstr "已采集到所有需要的信息。你现在可以为你的应用程序创建安装包...\n

单击OK 按钮创建安装包。\n

如果发生错误,单击Previous按钮。\n

单击Cancel按钮取消操作。\n\n" +#: FMakeInstall.form:887 +#, fuzzy +msgid "Commands output" +msgstr "命令超时" -#: FMakePatch.class:24 +#: FMakePatch.class:19 msgid "Please select the origin archive." msgstr "请选择原始归档。" -#: FMakePatch.class:33 +#: FMakePatch.class:28 msgid "Please select the origin project." msgstr "请选择原始工程。" -#: FMakePatch.class:71 +#: FMakePatch.class:66 msgid "Please enter the patch file name." msgstr "请输入补丁文件名。" -#: FMakePatch.class:82 +#: FMakePatch.class:77 msgid "Patch has been successfully generated." msgstr "成功生成补丁。" -#: FMakePatch.class:87 +#: FMakePatch.class:82 msgid "Unable to generate the patch." msgstr "不能生成补丁。" @@ -3641,7 +3949,7 @@ msgid "*.gz;*.bz2;*.xz" msgstr "-" -#: FMakePatch.form:98 Project.module:4564 +#: FMakePatch.form:98 Project.module:4603 msgid "Source packages" msgstr "源代码包" @@ -3681,7 +3989,7 @@ msgid "This menu is too deep !" msgstr "此菜单太深!" -#: FMenu.class:1001 Project.module:5433 +#: FMenu.class:996 Project.module:5429 msgid "modified" msgstr "修改过" @@ -3701,70 +4009,70 @@ msgid "Delete menu" msgstr "删除菜单" -#: FMenu.form:374 +#: FMenu.form:376 msgid "Click on Insert to add a new menu." msgstr "点击插入以添加新菜单." -#: FNewConnection.class:88 +#: FNewConnection.class:90 msgid "Please enter the name of the database." msgstr "请输入数据库的名称" -#: FNewConnection.class:129 +#: FNewConnection.class:131 msgid "Please enter password" msgstr "请输入口令" -#: FNewConnection.class:131 +#: FNewConnection.class:133 msgid "Connection properties" msgstr "连接属性" -#: FNewConnection.class:162 +#: FNewConnection.class:164 msgid "Select a directory" msgstr "选择一个目录" -#: FNewConnection.class:210 +#: FNewConnection.class:212 msgid "Create database '&1'" msgstr "(C)创建数据库'&1'" -#: FNewConnection.class:214 +#: FNewConnection.class:216 msgid "Delete database '&1'" msgstr "(D)删除数据库'&1'" -#: FNewConnection.class:338 +#: FNewConnection.class:340 msgid "Unable to create database." msgstr "不能创建数据库。" -#: FNewConnection.class:347 +#: FNewConnection.class:349 msgid "Do you really want to delete the database '&1'?" msgstr "你确定要删除数据库'&1'?" -#: FNewConnection.class:358 +#: FNewConnection.class:360 msgid "Unable to delete database." msgstr "不能删除数据库。" -#: FNewConnection.form:95 FProxy.form:32 +#: FNewConnection.form:98 FProxy.form:32 msgid "Host" msgstr "主机" -#: FNewConnection.form:120 +#: FNewConnection.form:123 msgid "Path" msgstr "路径" -#: FNewConnection.form:138 FProjectVersion.form:127 FProxy.form:42 -msgid "User" -msgstr "用户" - -#: FNewConnection.form:187 Project.module:216 +#: FNewConnection.form:190 Project.module:221 msgid "Database" msgstr "数据库" -#: FNewConnection.form:244 +#: FNewConnection.form:247 msgid "Ignore database charset" msgstr "忽略数据库字符集" -#: FNewConnection.form:258 +#: FNewConnection.form:261 msgid "Display metadata" msgstr "显示元数据" +#: FNewConnection.form:275 +msgid "Remember database structure" +msgstr "" + #: FNewTable.class:33 msgid "Create table" msgstr "创建表" @@ -3773,7 +4081,7 @@ msgid "Please enter the name of the new table." msgstr "请输入新建表的名称。" -#: FNewTable.class:59 MConnection.module:298 +#: FNewTable.class:59 MConnection.module:302 msgid "Table '&1' already exists." msgstr "表'&1'已经存在。" @@ -3785,7 +4093,7 @@ msgid "Select a project" msgstr "选择一个工程" -#: FOpenProject.form:109 +#: FOpenProject.form:109 FSoftwareFarm.class:41 FWelcome.class:69 msgid "Examples" msgstr "例子" @@ -3833,351 +4141,348 @@ msgid "Visual" msgstr "可视化的" -#: FOption.class:81 -msgid "Select a theme" -msgstr "选择主题" - #: FOption.class:82 +msgid "Custom" +msgstr "" + +#: FOption.class:84 msgid "Desktop" msgstr "桌面" -#: FOption.class:83 FTranslate.class:134 +#: FOption.class:85 FTranslate.class:134 msgid "(Default)" msgstr "(默认)" -#: FOption.class:156 +#: FOption.class:169 msgid "Define..." msgstr "定义..." -#: FOption.class:191 +#: FOption.class:219 msgid "Gambas highlight theme files" msgstr "Gambas突出主题文件" -#: FOption.class:192 +#: FOption.class:220 msgid "Export a theme file" msgstr "导出主题到文件" -#: FOption.class:363 +#: FOption.class:391 msgid "Select a theme file" msgstr "选择主题文件" -#: FOption.class:386 +#: FOption.class:414 msgid "You need to restart the application to see your changes." msgstr "需要重启应用程序使改变生效。" -#: FOption.class:713 +#: FOption.class:717 msgid "Do you really want to clear the documentation cache?" msgstr "确定要清除文档缓存吗?" -#: FOption.class:722 +#: FOption.class:726 msgid "Unable to clear documentation cache." msgstr "不能清除文档缓存。" -#: FOption.class:878 +#: FOption.class:882 msgid "Do you really want to delete this snippet?" msgstr "确定要删除该片段吗?" -#: FOption.class:1050 +#: FOption.class:1066 msgid "Do you really want to reset the list to its default value?" msgstr "确定要重置列表到默认值吗?" -#: FOption.class:1123 +#: FOption.class:1145 msgid "Do you really want to install the Gambas font to your personal font directory?" msgstr "确定要安装Gambas字体到私人字体目录吗?" -#: FOption.class:1123 FSoftwareFarm.form:93 +#: FOption.class:1145 FSoftwareFarm.form:382 msgid "Install" msgstr "安装" -#: FOption.class:1231 +#: FOption.class:1255 msgid "Unable to download documentation." msgstr "不能下载文档。" -#: FOption.class:1238 +#: FOption.class:1265 msgid "Unable to uncompress documentation." msgstr "不能解压缩文档。" -#: FOption.class:1263 +#: FOption.class:1274 +#, fuzzy +msgid "Unable to install documentation." +msgstr "不能下载文档。" + +#: FOption.class:1299 msgid "Network is not available." msgstr "网络不可用。" -#: FOption.class:1268 +#: FOption.class:1304 msgid "Documentation is up to date." msgstr "文档已是最新。" -#: FOption.class:1273 +#: FOption.class:1309 msgid "'wget' is not found." msgstr "没找到'wget'。" -#: FOption.class:1278 +#: FOption.class:1314 msgid "A new documentation is available!" msgstr "有新文档可用!" -#: FOption.class:1283 MHelp.module:875 +#: FOption.class:1319 MHelp.module:897 msgid "Documentation is not available." msgstr "文档不可用。" -#: FOption.form:209 -msgid "Foreground color" -msgstr "前景色" - -#: FOption.form:213 -msgid "Background color" -msgstr "背景颜色" +#: FOption.form:241 +msgid "Identity" +msgstr "身份" -#: FOption.form:283 +#: FOption.form:285 msgid "Package maintainer" msgstr "包维护者" -#: FOption.form:310 +#: FOption.form:328 msgid "Default license" msgstr "默认许可协议" -#: FOption.form:350 FProjectProperty.form:645 FPropertyComponent.form:99 +#: FOption.form:368 FProjectProperty.form:421 msgid "No" msgstr "否" -#: FOption.form:350 FProjectProperty.form:645 FPropertyComponent.form:99 +#: FOption.form:368 FProjectProperty.form:421 msgid "Yes" msgstr "是" -#: FOption.form:354 +#: FOption.form:372 msgid "Interface" msgstr "接口" -#: FOption.form:360 -msgid "Fonts" -msgstr "字体" - -#: FOption.form:387 -msgid "Global size" -msgstr "全局尺寸" - -#: FOption.form:409 -msgid "Title size" -msgstr "标题尺寸" - -#: FOption.form:463 -msgid "Install Gambas font for code edition" -msgstr "为代码编辑器安装Gambas字体" - -#: FOption.form:470 Project.module:220 -msgid "Miscellaneous" -msgstr "其它" +#: FOption.form:389 +msgid "Icon theme" +msgstr "图标主题" -#: FOption.form:481 +#: FOption.form:406 msgid "Sort properties" msgstr "属性排序" -#: FOption.form:498 +#: FOption.form:423 msgid "Minimize at runtime" msgstr "运行时最小化" -#: FOption.form:515 +#: FOption.form:440 msgid "Use utility windows" msgstr "使用公用窗口" -#: FOption.form:532 +#: FOption.form:457 msgid "Toolbox size" msgstr "工具箱大小" -#: FOption.form:538 FProjectProperty.form:242 +#: FOption.form:463 FProjectProperty.form:305 msgid "Normal" msgstr "普通" -#: FOption.form:538 +#: FOption.form:463 msgid "Small" msgstr "小" -#: FOption.form:550 +#: FOption.form:475 msgid "Restore files when loading a project" msgstr "加载工程时恢复文件" -#: FOption.form:567 +#: FOption.form:492 msgid "Show tooltips" msgstr "显示工具提示" -#: FOption.form:584 +#: FOption.form:509 msgid "Show file name in window title" msgstr "在窗口标题栏显示文件名" -#: FOption.form:610 +#: FOption.form:526 +msgid "Quiet external commands" +msgstr "使外部命令安静" + +#: FOption.form:535 +msgid "Fonts" +msgstr "字体" + +#: FOption.form:568 +msgid "Global size" +msgstr "全局尺寸" + +#: FOption.form:590 +msgid "Title size" +msgstr "标题尺寸" + +#: FOption.form:644 +msgid "Install Gambas font for code edition" +msgstr "为代码编辑器安装Gambas字体" + +#: FOption.form:665 msgid "Default tab size" msgstr "默认的TAB大小" -#: FOption.form:628 FProjectProperty.form:620 +#: FOption.form:683 FProjectProperty.form:765 msgid "space(s)" msgstr "个空格" -#: FOption.form:641 +#: FOption.form:696 msgid "Procedure separation" msgstr "过程分隔" -#: FOption.form:647 -msgid "Blend" -msgstr "混合" - -#: FOption.form:647 FProperty.class:778 FPublish.class:34 -msgid "None" -msgstr "无" - -#: FOption.form:659 +#: FOption.form:713 msgid "Highlight current line" msgstr "突出显示当前行" -#: FOption.form:676 +#: FOption.form:730 msgid "Highlight modified lines" msgstr "突出修改行" -#: FOption.form:693 +#: FOption.form:747 msgid "Show line numbers" msgstr "显示行号" -#: FOption.form:710 -msgid "Show spaces at end of line with dots" -msgstr "用点显示行尾空格" - -#: FOption.form:727 +#: FOption.form:764 msgid "Procedure folding" msgstr "折叠过程" -#: FOption.form:744 +#: FOption.form:782 msgid "Fold procedures by default" msgstr "缺省折叠过程代码" -#: FOption.form:761 +#: FOption.form:799 +msgid "Automatic word wrap by default" +msgstr "" + +#: FOption.form:816 +msgid "Show spaces at end of line with dots" +msgstr "用点显示行尾空格" + +#: FOption.form:840 msgid "Keywords in upper case" msgstr "大写关键字" -#: FOption.form:783 +#: FOption.form:856 msgid "Configure shortcuts" msgstr "配置快捷键" -#: FOption.form:788 +#: FOption.form:861 msgid "Theme" msgstr "主题" -#: FOption.form:805 -msgid "Icon theme" -msgstr "图标主题" - -#: FOption.form:821 +#: FOption.form:877 msgid "Color theme" msgstr "颜色主题" -#: FOption.form:835 +#: FOption.form:891 msgid "Import theme" msgstr "导入主题" -#: FOption.form:841 +#: FOption.form:897 msgid "Export theme" msgstr "导出主题" -#: FOption.form:882 -msgid "Help & applications" -msgstr "帮助与应用" - -#: FOption.form:888 MTheme.module:6 -msgid "Help" -msgstr "帮助" - -#: FOption.form:899 -msgid "Display property help" -msgstr "显示属性帮助" - -#: FOption.form:916 -msgid "Show documentation in popups" -msgstr "在弹出窗口显示文档。" - -#: FOption.form:933 -msgid "Always display optional messages" -msgstr "总是显示可选信息" - -#: FOption.form:950 -msgid "Use offline help" -msgstr "使用离线帮助" - -#: FOption.form:968 -msgid "Download documentation" -msgstr "下载文档" - -#: FOption.form:986 -msgid "Clear documentation cache" -msgstr "清除文档缓存" - -#: FOption.form:998 FProxy.form:20 -msgid "Proxy configuration" -msgstr "代理配置" - -#: FOption.form:1006 -msgid "Applications" -msgstr "程序" - -#: FOption.form:1017 -msgid "Browser" -msgstr "浏览器" - -#: FOption.form:1034 -msgid "Terminal" -msgstr "终端" - -#: FOption.form:1051 -msgid "Quiet external commands" -msgstr "使外部命令安静" +#: FOption.form:910 +msgid "Adapt colors to dark themes" +msgstr "" -#: FOption.form:1060 +#: FOption.form:925 msgid "Code formatting" msgstr "代码格式化" -#: FOption.form:1066 +#: FOption.form:931 msgid "Automatic formatting" msgstr "自动格式化" -#: FOption.form:1077 +#: FOption.form:942 msgid "Control structure automatic completion" msgstr "控制结构自动完成" -#: FOption.form:1094 +#: FOption.form:959 msgid "Local variable automatic declaration" msgstr "局部变量自动声明" -#: FOption.form:1111 +#: FOption.form:976 msgid "Comments automatic insertion" msgstr "自动插入注释" -#: FOption.form:1123 +#: FOption.form:988 msgid "Explicit formating" msgstr "显式格式化" -#: FOption.form:1134 +#: FOption.form:999 msgid "Format on load & save" msgstr "加载和保存时格式化" -#: FOption.form:1151 +#: FOption.form:1016 msgid "Indent local variable declaration" msgstr "缩进局部变量声明" -#: FOption.form:1168 +#: FOption.form:1033 msgid "Remove useless spaces at end of line" msgstr "删除行尾无用空格。" -#: FOption.form:1185 +#: FOption.form:1050 msgid "Keep successive void lines" msgstr "保留连续的空行" -#: FOption.form:1194 +#: FOption.form:1059 msgid "Code snippets" msgstr "代码片段" -#: FOption.form:1210 +#: FOption.form:1075 msgid "Activate code snippets" msgstr "激活代码片段" -#: FOption.form:1271 +#: FOption.form:1158 +msgid "Help & applications" +msgstr "帮助与应用" + +#: FOption.form:1164 MTheme.module:6 +msgid "Help" +msgstr "帮助" + +#: FOption.form:1175 +msgid "Display property help" +msgstr "显示属性帮助" + +#: FOption.form:1192 +msgid "Show documentation in popups" +msgstr "在弹出窗口显示文档。" + +#: FOption.form:1209 +msgid "Always display optional messages" +msgstr "总是显示可选信息" + +#: FOption.form:1226 +msgid "Use offline help" +msgstr "使用离线帮助" + +#: FOption.form:1244 +msgid "Download documentation" +msgstr "下载文档" + +#: FOption.form:1262 +msgid "Clear documentation cache" +msgstr "清除文档缓存" + +#: FOption.form:1274 FProxy.form:20 +msgid "Proxy configuration" +msgstr "代理配置" + +#: FOption.form:1282 +msgid "Applications" +msgstr "程序" + +#: FOption.form:1293 +msgid "Browser" +msgstr "浏览器" + +#: FOption.form:1310 +msgid "Terminal" +msgstr "终端" + +#: FOption.form:1319 msgid "Source archives" msgstr "源归档" -#: FOption.form:1284 +#: FOption.form:1332 msgid "These files will be ignored when making source archives." msgstr "生成源归档时这些文件将被忽略。" @@ -4213,18 +4518,18 @@ msgid "Unable to paste text." msgstr "不能粘贴文本。" -#: FPasteSpecial.form:35 +#: FPasteSpecial.form:31 +msgid "Clipboard contents" +msgstr "剪贴板内容" + +#: FPasteSpecial.form:44 msgid "Paste normally" msgstr "正常粘贴" -#: FPasteSpecial.form:46 +#: FPasteSpecial.form:55 msgid "Paste with PRINT" msgstr "用PRINT粘贴" -#: FPasteSpecial.form:85 -msgid "Clipboard contents" -msgstr "剪贴板内容" - #: FPasteTable.class:57 msgid "Please enter a table name." msgstr "请输入表名。" @@ -4241,11 +4546,11 @@ msgid "That file does not look like a patch file!" msgstr "文件看来不像是一个补丁文件!" -#: FPatch.form:22 +#: FPatch.form:18 msgid "Patch the current project" msgstr "给当前工程打补丁" -#: FPatch.form:40 +#: FPatch.form:31 msgid "Select patch" msgstr "选择补丁" @@ -4261,31 +4566,31 @@ msgid "Total time &1 μs" msgstr "总计时间&1微秒(μs)" -#: FProfile.class:427 +#: FProfile.class:424 msgid "Unable to load profile file: &1" msgstr "不能加载profile:&1" -#: FProfile.class:634 +#: FProfile.class:641 msgid "Calls" msgstr "调用" -#: FProfile.class:636 +#: FProfile.class:644 msgid "Duration" msgstr "持续时间" -#: FProfile.class:638 -msgid "Self" -msgstr "自身" - -#: FProfile.class:640 +#: FProfile.class:647 msgid "Average" msgstr "普通" -#: FProfile.class:1024 +#: FProfile.class:650 +msgid "Self" +msgstr "自身" + +#: FProfile.class:1049 msgid "Profile files" msgstr "profile文件" -#: FProfile.class:1031 +#: FProfile.class:1056 msgid "Unable to save profile." msgstr "不能保存profile" @@ -4309,159 +4614,185 @@ msgid "Callers" msgstr "调用方" -#: FProjectChooser.class:19 -msgid "Installed softwares" -msgstr "已安装软件" - -#: FProjectProperty.class:112 -msgid "Not translatable" -msgstr "未翻译" - -#: FProjectProperty.class:140 +#: FProjectProperty.class:136 msgid "Variable" msgstr "变量" -#: FProjectProperty.class:269 +#: FProjectProperty.class:244 msgid "Snapping value is incorrect." msgstr "锁定值不正确" -#: FProjectProperty.class:423 Project.module:3494 -msgid "Some components are missing: &1" -msgstr "部份组件缺失:&1" - -#: FProjectProperty.class:549 -msgid "These components are incompatible:
&1." -msgstr "这些组件存在冲突:
&1。" - -#: FProjectProperty.class:562 -msgid "The &1 component needs one of the following components:
&2." -msgstr " &1组件需要下列组件之一 :
&2。" - -#: FProjectProperty.class:569 -msgid "The &1 component needs the &2 component." -msgstr "&1组件需要&2组件。" - -#: FProjectProperty.class:1117 +#: FProjectProperty.class:773 msgid "Select a Gambas application" msgstr "选择Gambas应用:" -#: FProjectProperty.class:1129 +#: FProjectProperty.class:785 msgid "&1 does not export any class." msgstr "&1未输出任何类。" -#: FProjectProperty.class:1137 +#: FProjectProperty.class:793 msgid "&1 is already used as a library." msgstr "&1已经作为库使用。" -#: FProjectProperty.class:1289 -msgid "Stable" -msgstr "稳定版" - -#: FProjectProperty.class:1395 +#: FProjectProperty.class:960 msgid "Executable size" msgstr "可执行文件大小" -#: FProjectProperty.class:1395 +#: FProjectProperty.class:960 msgid "bytes" msgstr "字节" -#: FProjectProperty.form:204 FPropertyComponent.form:60 +#: FProjectProperty.class:977 +#, fuzzy +msgid "Information about component" +msgstr "正在加载&1组件信息..." + +#: FProjectProperty.class:983 +msgid "Information about library" +msgstr "" + +#: FProjectProperty.form:187 +msgid "GB_GUI_BUSY=1" +msgstr "" + +#: FProjectProperty.form:193 +msgid "GB_X11_INIT_THREADS=1" +msgstr "" + +#: FProjectProperty.form:208 +msgid "GB_DB_DEBUG=1" +msgstr "" + +#: FProjectProperty.form:269 msgid "General" msgstr "通用" -#: FProjectProperty.form:242 +#: FProjectProperty.form:305 msgid "Component" msgstr "组件" -#: FProjectProperty.form:242 +#: FProjectProperty.form:305 msgid "Library" msgstr "库" -#: FProjectProperty.form:248 FPublish.class:56 +#: FProjectProperty.form:312 FPublish.class:89 msgid "Version" msgstr "版本" -#: FProjectProperty.form:274 +#: FProjectProperty.form:338 msgid "Get from 'VERSION' file" msgstr "从'VERSION'文件获取" -#: FProjectProperty.form:281 +#: FProjectProperty.form:345 msgid "Title" msgstr "标题" -#: FProjectProperty.form:304 -msgid "Author(s)" -msgstr "作者" +#: FProjectProperty.form:378 +#, fuzzy +msgid "Information" +msgstr "系统信息" + +#: FProjectProperty.form:398 +msgid "Progress" +msgstr "" + +#: FProjectProperty.form:404 +msgid "Finished and stable" +msgstr "稳定的最终版" + +#: FProjectProperty.form:415 +msgid "This component is hidden" +msgstr "该组件被隐藏" + +#: FProjectProperty.form:432 +msgid "Compatible until version" +msgstr "兼容直到版本" + +#: FProjectProperty.form:461 +#, fuzzy +msgid "Include information from" +msgstr "包信息" + +#: FProjectProperty.form:473 +#, fuzzy +msgid "Required features" +msgstr "需要" + +#: FProjectProperty.form:529 +msgid "Required and excluded components" +msgstr "" + +#: FProjectProperty.form:550 +#, fuzzy +msgid "Require" +msgstr "需要" -#: FProjectProperty.form:314 FPropertyComponent.form:200 +#: FProjectProperty.form:556 +#, fuzzy +msgid "Exclude" +msgstr "排除" + +#: FProjectProperty.form:568 +msgid "Remove All" +msgstr "全部移除" + +#: FProjectProperty.form:575 msgid "Components" msgstr "组件" -#: FProjectProperty.form:353 +#: FProjectProperty.form:584 msgid "Show only components used in project" msgstr "只显示工程中使用过的组件" -#: FProjectProperty.form:384 -msgid "About component" -msgstr "(C)关于组件" - -#: FProjectProperty.form:416 +#: FProjectProperty.form:599 msgid "Libraries" msgstr "库" -#: FProjectProperty.form:435 +#: FProjectProperty.form:620 msgid "WARNING! The project executable and the libraries it depends on must be stored inside the same directory. Otherwise the libraries will not be found." msgstr "警告!工程可执行文件及其依赖库必须被存储在同一目录内,否则将找不到库。" -#: FProjectProperty.form:490 +#: FProjectProperty.form:670 msgid "Environment" msgstr "环境" -#: FProjectProperty.form:500 -msgid "Arguments" -msgstr "表达式" - -#: FProjectProperty.form:554 -msgid "Environment variables" -msgstr "环境变量" - -#: FProjectProperty.form:574 +#: FProjectProperty.form:685 msgid "&Insert" msgstr "(&I)插入" -#: FProjectProperty.form:597 +#: FProjectProperty.form:697 +msgid "Arguments" +msgstr "表达式" + +#: FProjectProperty.form:742 msgid "Edition" msgstr "版本" -#: FProjectProperty.form:608 +#: FProjectProperty.form:753 msgid "Tab size" msgstr "TAB大小" -#: FProjectProperty.form:628 +#: FProjectProperty.form:773 msgid "Compilation" msgstr "编译" -#: FProjectProperty.form:639 +#: FProjectProperty.form:784 msgid "Module symbols are public by default" msgstr "模块符号缺省是公用的" -#: FProjectProperty.form:656 +#: FProjectProperty.form:801 msgid "Form controls are public" msgstr "窗口控件是公用的" -#: FProjectProperty.form:673 +#: FProjectProperty.form:818 msgid "Activate warnings" msgstr "激活警告" -#: FProjectProperty.form:698 -msgid "Project is translatable" -msgstr "工程是可翻译的" - -#: FProjectProperty.form:730 +#: FProjectProperty.form:875 msgid "Debugging" msgstr "调试" -#: FProjectProperty.form:758 +#: FProjectProperty.form:903 msgid "Use a terminal emulator" msgstr "使用终端仿真器" @@ -4477,34 +4808,30 @@ msgid "Remote" msgstr "远程" -#: FProjectVersion.class:92 +#: FProjectVersion.class:94 msgid "Please enter a user name." msgstr "请输入用户名。" -#: FProjectVersion.class:103 +#: FProjectVersion.class:105 msgid "Please enter the journal." msgstr "请输入日志。" -#: FProjectVersion.class:114 +#: FProjectVersion.class:116 msgid "The project could not be committed." msgstr "工程不能被提交。" -#: FProjectVersion.class:194 +#: FProjectVersion.class:196 msgid "Unable to update project from repository." msgstr "不能从软件库更新工程。" -#: FProjectVersion.class:196 +#: FProjectVersion.class:198 msgid "Project has been updated from repository successfully." msgstr "从软件库更新工程成功。" -#: FProjectVersion.class:282 +#: FProjectVersion.class:284 msgid "Revision" msgstr "修订版" -#: FProjectVersion.class:285 -msgid "Author" -msgstr "作者" - #: FProjectVersion.form:53 msgid "Project Version Control" msgstr "工程版本控制" @@ -4541,78 +4868,54 @@ msgid "Changes" msgstr "改变" -#: FProperty.class:367 +#: FProperty.class:381 msgid "Forbidden characters in control name." msgstr "控件名中有禁止使用的字符." -#: FProperty.class:372 +#: FProperty.class:386 msgid "This name is already in use." msgstr "此名己使用." -#: FProperty.class:382 +#: FProperty.class:396 msgid "Forbidden characters in control group." msgstr "控件组中有禁止使用的字符." -#: FProperty.class:454 +#: FProperty.class:468 msgid "Incorrect property value." msgstr "错误的属性值." -#: FProperty.class:607 +#: FProperty.class:626 msgid "The name of the control." msgstr "控件名称。" -#: FProperty.class:618 +#: FProperty.class:637 msgid "The event group that the control belongs to." msgstr "控件属于的事件组。" -#: FProperty.class:632 +#: FProperty.class:651 msgid "If the form and controls dimensions must follow the size of the default font." msgstr "是否窗体和控件面积必须符合缺省字体的大小。" -#: FProperty.class:636 +#: FProperty.class:655 msgid "If the control is public." msgstr "是否控件是公共的。" -#: FProperty.class:640 +#: FProperty.class:659 msgid "If the Text property must be translated." msgstr "是否文本属性必须被翻译。" -#: FProperty.class:661 +#: FProperty.class:680 msgid "This property is virtual: it is only implemented in the IDE, and has no existence at runtime." msgstr "该属性是虚拟的:其仅在IDE中实现,并不存在于运行时。" -#: FProperty.form:48 +#: FProperty.class:805 +msgid "None" +msgstr "无" + +#: FProperty.form:47 msgid "Lock property" msgstr "锁定属性" -#: FPropertyComponent.form:75 -msgid "Component advancement" -msgstr "组件升级" - -#: FPropertyComponent.form:82 -msgid "Finished and stable" -msgstr "稳定的最终版" - -#: FPropertyComponent.form:93 -msgid "This component is hidden" -msgstr "该组件被隐藏" - -#: FPropertyComponent.form:110 -msgid "Compatible until version" -msgstr "兼容直到版本" - -#: FPropertyComponent.form:135 -msgid "Exported classes" -msgstr "输出类" - -#: FPropertyComponent.form:149 -msgid "Features" -msgstr "特效" - -#: FPropertyComponent.form:235 -msgid "Remove All" -msgstr "全部移除" - #: FProxy.form:37 msgid "Port" msgstr "端口" @@ -4633,65 +4936,96 @@ msgid "SOCKS5 proxy" msgstr "SOCKS5代理" -#: FPublish.class:54 +#: FPublish.class:10 +msgid "You cannot publish a software whose version is \"0.0\"." +msgstr "" + +#: FPublish.class:87 msgid "Software" msgstr "软件" -#: FPublish.class:141 +#: FPublish.class:162 msgid "The project has been successfully published." msgstr "工程已成功发布。" -#: FPublish.class:141 +#: FPublish.class:162 msgid "Unable to publish project." msgstr "不能发布工程。" -#: FPublish.class:210 +#: FPublish.class:233 msgid "Spaces are not allowed." msgstr "不允许空格。" -#: FPublish.class:216 +#: FPublish.class:239 msgid "Incorrect version number." msgstr "错误的版本号。" -#: FPublish.class:248 +#: FPublish.class:271 msgid "Do you really want to remove all tags?" msgstr "确定要移除所有标记吗?" -#: FPublish.form:67 +#: FPublish.class:326 +#, fuzzy +msgid "Select a screenshot file" +msgstr "选择主题文件" + +#: FPublish.class:327 +#, fuzzy +msgid "Screenshot files" +msgstr "屏幕截图" + +#: FPublish.form:68 msgid "Software description" msgstr "" -#: FPublish.form:97 +#: FPublish.form:98 FSoftwareFarm.form:330 msgid "Web site" msgstr "网站" -#: FPublish.form:112 -msgid "Screenshot" -msgstr "屏幕截图" - -#: FPublish.form:128 +#: FPublish.form:113 msgid "Create menu entry" msgstr "" -#: FPublish.form:149 FSoftwareFarm.form:202 +#: FPublish.form:134 FSoftwareFarm.form:182 msgid "Tags" msgstr "标签" -#: FPublish.form:178 +#: FPublish.form:164 msgid "Sort" msgstr "排序" -#: FPublish.form:190 +#: FPublish.form:176 +msgid "Screenshot" +msgstr "屏幕截图" + +#: FPublish.form:181 +msgid "Keep the screenshot stored on the server" +msgstr "" + +#: FPublish.form:188 +msgid "Delete the screenshot stored on the server" +msgstr "" + +#: FPublish.form:194 +msgid "Upload a new screenshot taken from the clipboard" +msgstr "" + +#: FPublish.form:200 +msgid "Upload a new screenshot taken from the following file:" +msgstr "" + +#: FPublish.form:222 msgid "Dependencies" msgstr "依赖" -#: FPublish.form:198 +#: FPublish.form:230 msgid "Require Gambas version" msgstr "需要Gambas版本" -#: FPublish.form:302 FSoftwareFarm.form:284 -msgid "Configure" -msgstr "配置" +#: FPublish.form:295 +#, fuzzy +msgid "Publish as" +msgstr "发布" #: FReportBorderChooser.form:43 msgid "Configure border" @@ -4709,6 +5043,15 @@ msgid "Corner" msgstr "边角" +#: FReportBoxShadowChooser.form:23 +#, fuzzy +msgid "Configure shadow" +msgstr "配置刷子" + +#: FReportBoxShadowChooser.form:40 +msgid "Shadow" +msgstr "" + #: FReportBrushChooser.form:31 msgid "Configure brush" msgstr "配置刷子" @@ -4757,6 +5100,10 @@ msgid "New project name" msgstr "新工程名" +#: FScreenshot.form:12 +msgid "Take screenshot" +msgstr "" + #: FSearch.class:504 msgid "Search string replaced once." msgstr "你要替换的字符串被替换了一次." @@ -4765,15 +5112,15 @@ msgid "Search string replaced &1 times." msgstr "你要替换的字符串被替换了&1次." -#: FSearch.class:756 +#: FSearch.class:603 msgid "One match" msgstr "1个匹配" -#: FSearch.class:758 +#: FSearch.class:605 msgid "&1 matches" msgstr "&1个匹配" -#: FSearch.class:887 +#: FSearch.class:893 msgid "Do you really want to replace every string?" msgstr "确定要替换所有字符串吗?" @@ -4793,39 +5140,39 @@ msgid "Regular expression" msgstr "正则表达式(X)" -#: FSearch.form:121 +#: FSearch.form:122 msgid "Highlight result" msgstr "结果高亮" -#: FSearch.form:126 +#: FSearch.form:127 msgid "Ignore strings" msgstr "忽略字符串" -#: FSearch.form:131 +#: FSearch.form:132 msgid "Ignore comments" msgstr "忽略注释" -#: FSearch.form:146 +#: FSearch.form:147 msgid "Search in" msgstr "搜索于" -#: FSearch.form:153 +#: FSearch.form:154 msgid "Current procedure" msgstr "当前过程" -#: FSearch.form:159 +#: FSearch.form:160 msgid "Current file" msgstr "当前文件" -#: FSearch.form:166 +#: FSearch.form:167 msgid "Source files" msgstr "源文件" -#: FSearch.form:205 +#: FSearch.form:206 msgid "Browse" msgstr "浏览" -#: FSearch.form:217 +#: FSearch.form:218 msgid "Replace all" msgstr "全部替换" @@ -4869,107 +5216,173 @@ msgid "Trigger string" msgstr "触发字符串" -#: FSoftwareFarm.class:122 +#: FSoftwareFarm.class:39 Project.module:223 +msgid "Games" +msgstr "游戏" + +#: FSoftwareFarm.class:40 +#, fuzzy +msgid "Development" +msgstr "网站开发" + +#: FSoftwareFarm.class:42 +#, fuzzy +msgid "Education" +msgstr "版本" + +#: FSoftwareFarm.class:43 +msgid "Graphics" +msgstr "" + +#: FSoftwareFarm.class:44 +msgid "Audio" +msgstr "" + +#: FSoftwareFarm.class:45 Project.module:230 +msgid "Video" +msgstr "视频" + +#: FSoftwareFarm.class:46 +msgid "Office" +msgstr "" + +#: FSoftwareFarm.class:47 +#, fuzzy +msgid "Accessories" +msgstr "禁止访问" + +#: FSoftwareFarm.class:48 +#, fuzzy +msgid "Internet" +msgstr "接口" + +#: FSoftwareFarm.class:53 +#, fuzzy +msgid "All software" +msgstr "删除软件" + +#: FSoftwareFarm.class:152 msgid "No software found." msgstr "未找到软件" -#: FSoftwareFarm.class:142 +#: FSoftwareFarm.class:171 msgid "Request cancelled." msgstr "请求取消。" -#: FSoftwareFarm.class:276 +#: FSoftwareFarm.class:309 msgid "Cancel my vote" msgstr "取消投票" -#: FSoftwareFarm.class:283 -msgid "Uninstall" -msgstr "卸载" - -#: FSoftwareFarm.class:286 +#: FSoftwareFarm.class:316 msgid "Upgrade" msgstr "升级" -#: FSoftwareFarm.class:475 -msgid "Do you really want to upgrade &1?" +#: FSoftwareFarm.class:320 +msgid "Uninstall" +msgstr "卸载" + +#: FSoftwareFarm.class:480 +#, fuzzy +msgid "Do you really want to download &1?" msgstr "确定要升级&1吗?" -#: FSoftwareFarm.class:478 -msgid "Unable to upgrade &1:" +#: FSoftwareFarm.class:483 +#, fuzzy +msgid "Unable to download &1:" msgstr "不能升级&1:" #: FSoftwareFarm.class:485 +#, fuzzy +msgid "&1 has been successfully downloaded." +msgstr "成功生成补丁。" + +#: FSoftwareFarm.class:500 +#, fuzzy +msgid "Do you really want to upgrade to &1?" +msgstr "确定要升级&1吗?" + +#: FSoftwareFarm.class:503 +#, fuzzy +msgid "Unable to upgrade to &1:" +msgstr "不能升级&1:" + +#: FSoftwareFarm.class:510 msgid "Do you really want to uninstall &1?" msgstr "确定要卸载&1吗?" -#: FSoftwareFarm.class:488 -msgid "Unable to remove &1:" +#: FSoftwareFarm.class:513 +#, fuzzy +msgid "Unable to remove &1:" msgstr "不能删除&1:" -#: FSoftwareFarm.class:490 +#: FSoftwareFarm.class:515 msgid "&1 has been successfully removed." msgstr "" -#: FSoftwareFarm.class:496 +#: FSoftwareFarm.class:521 msgid "Do you really want to install &1?" msgstr "确定要安装&1吗?" -#: FSoftwareFarm.class:499 -msgid "Unable to install &1:" +#: FSoftwareFarm.class:524 +#, fuzzy +msgid "Unable to install &1:" msgstr "不能安装&1:" -#: FSoftwareFarm.class:501 +#: FSoftwareFarm.class:526 msgid "&1 has been successfully installed." msgstr "" -#: FSoftwareFarm.class:521 +#: FSoftwareFarm.class:546 msgid "Unable to modify your vote." msgstr "不能修改投票。" -#: FSoftwareFarm.class:552 +#: FSoftwareFarm.class:581 msgid "Do you really want to delete &1 from the farm server?" msgstr "确定从软件农场服务器要删除&1吗?" -#: FSoftwareFarm.form:65 +#: FSoftwareFarm.form:63 msgid "Gambas Software Farm" msgstr "Gambas软件农场" -#: FSoftwareFarm.form:100 -msgid "Vote" -msgstr "选票" - -#: FSoftwareFarm.form:195 -msgid "Developer web site" -msgstr "网站开发" - -#: FSoftwareFarm.form:244 -msgid "Farm" -msgstr "软件农场" - -#: FSoftwareFarm.form:300 +#: FSoftwareFarm.form:156 msgid "Show" msgstr "显示" -#: FSoftwareFarm.form:306 +#: FSoftwareFarm.form:162 msgid "Installed" msgstr "已安装" -#: FSoftwareFarm.form:306 +#: FSoftwareFarm.form:162 msgid "Most downloaded" msgstr "最多下载" -#: FSoftwareFarm.form:306 +#: FSoftwareFarm.form:162 msgid "Most popular" msgstr "最流行" -#: FSoftwareFarm.form:306 +#: FSoftwareFarm.form:162 msgid "Most recent" msgstr "最新" -#: FSystemInfo.form:17 +#: FSoftwareFarm.form:167 +#, fuzzy +msgid "Show filters" +msgstr "显示添加的文件" + +#: FSoftwareFarm.form:389 +#, fuzzy +msgid "Download" +msgstr "下" + +#: FSoftwareFarm.form:398 +msgid "Vote" +msgstr "选票" + +#: FSystemInfo.form:15 msgid "System information" msgstr "系统信息" -#: FSystemInfo.form:41 +#: FSystemInfo.form:35 msgid "Please copy these informations in all your bug reports." msgstr "请将这些信息复制到每一个漏洞报告中。" @@ -4985,35 +5398,47 @@ msgid "Use a fixed font" msgstr "使用固定字体" -#: FTextEditor.class:868 +#: FTextEditor.class:887 msgid "Original file has been saved in the Project folder." msgstr "原始文件已被保存于工程文件夹内。" -#: FTextEditor.class:868 +#: FTextEditor.class:887 msgid "The file has been compressed from &1 to &2 bytes (&3)." msgstr "文件被从&1字节压缩到&2字节(&3)。" -#: FTextEditor.class:874 +#: FTextEditor.class:893 msgid "Unable to compress file." msgstr "不能压缩文件。" -#: FTextEditor.form:192 +#: FTextEditor.form:218 +msgid "Unix" +msgstr "" + +#: FTextEditor.form:223 +msgid "Windows" +msgstr "" + +#: FTextEditor.form:228 +msgid "MAC" +msgstr "" + +#: FTextEditor.form:255 msgid "Sort ascent" msgstr "升序" -#: FTextEditor.form:198 +#: FTextEditor.form:261 msgid "Sort descent" msgstr "降序" -#: FTextEditor.form:213 +#: FTextEditor.form:283 msgid "Compress file" msgstr "压缩文件" -#: FTextEditor.form:219 +#: FTextEditor.form:289 msgid "Uncompress file" msgstr "解压缩文件" -#: FTextEditor.form:282 +#: FTextEditor.form:355 msgid "Text editor" msgstr "文本编辑器" @@ -5041,431 +5466,441 @@ msgid "Translation files" msgstr "翻译文件" -#: FTranslate.class:284 +#: FTranslate.class:287 msgid "Cannot read translation file for language '&1'" msgstr "无法读'&1'语言的翻译文件" -#: FTranslate.class:446 +#: FTranslate.class:449 msgid "Cannot save translation." msgstr "无法保存翻译!" -#: FTranslate.class:556 +#: FTranslate.class:562 msgid "Do you really want to delete this translation ?" msgstr "你确定要删除此翻译?" -#: FTranslate.class:652 +#: FTranslate.class:658 msgid "Do you really want to reload this translation ?" msgstr "你确定要加载此翻译?" -#: FTranslate.class:666 +#: FTranslate.class:672 msgid "Export a translation" msgstr "导出一个翻译" -#: FTranslate.class:852 +#: FTranslate.class:861 msgid "Please select the translation file to import." msgstr "请选择导入的翻译文件。" -#: FTranslate.class:890 +#: FTranslate.class:899 msgid "No translation were picked up." msgstr "没有翻译被采纳。" -#: FTranslate.class:892 +#: FTranslate.class:901 msgid "One translation was picked up." msgstr "一个翻译被采纳。" -#: FTranslate.class:894 +#: FTranslate.class:903 msgid "&1 translations were picked up." msgstr "&1翻译被采纳。" -#: FTranslate.class:902 +#: FTranslate.class:911 msgid "Cannot import translation file." msgstr "无法导入翻译文件." -#: FTranslate.class:951 +#: FTranslate.class:960 msgid "Translated string symbols do not match untranslated string ones." msgstr "翻译后的字符串符号与未翻译的字符串不匹配." -#: FTranslate.class:964 +#: FTranslate.class:973 msgid "Everything seems to be correct." msgstr "看起来一切正常," -#: FTranslate.class:987 +#: FTranslate.class:996 msgid "&1 strings. Everything is translated!" msgstr "&1个字符串,已完全翻译!" -#: FTranslate.class:989 +#: FTranslate.class:998 msgid "&1 strings. One is not translated. &3% done." msgstr "&1个字符串,尚有一个未翻译,已完成&3%。" -#: FTranslate.class:991 +#: FTranslate.class:1000 msgid "&1 strings. &2 are not translated. &3% done." msgstr "&1个字符串,&2个未翻译,已完成&3%。" -#: FTranslate.form:57 +#: FTranslate.form:61 msgid "Project translation" msgstr "翻译工程" -#: FTranslate.form:88 +#: FTranslate.form:93 msgid "Untranslated strings" msgstr "未翻译字符串" -#: FTranslate.form:92 +#: FTranslate.form:97 msgid "Translated strings" msgstr "已翻译字符串" -#: FTranslate.form:96 +#: FTranslate.form:101 msgid "All strings" msgstr "所有字符串" -#: FTranslate.form:159 +#: FTranslate.form:163 msgid "Save translation" msgstr "保存翻译" -#: FTranslate.form:165 +#: FTranslate.form:169 msgid "Clear this translation" msgstr "清除该翻译" -#: FTranslate.form:171 +#: FTranslate.form:175 msgid "This string must not be translated" msgstr "该字符串不必翻译" -#: FTranslate.form:177 +#: FTranslate.form:181 msgid "Copy untranslated string" msgstr "复制未翻译字符串" -#: FTranslate.form:183 +#: FTranslate.form:187 msgid "Verify the translation" msgstr "校验翻译" -#: FTranslate.form:189 +#: FTranslate.form:193 msgid "Find next untranslated string" msgstr "查找下一个未翻译字符串" -#: FTranslate.form:195 +#: FTranslate.form:199 msgid "Find previous untranslated string" msgstr "查找上一个未翻译字符串" -#: FTranslate.form:347 +#: FTranslate.form:356 msgid "Import all translations recursively" msgstr "依次导入所有翻译" -#: FTranslate.form:352 +#: FTranslate.form:362 +#, fuzzy +msgid "Replace existing translations" +msgstr "清除该翻译" + +#: FTranslate.form:378 msgid "Import a translation file" msgstr "导入翻译文件" -#: FWelcome.class:61 +#: FWelcome.class:66 msgid "New project..." msgstr "新建工程..." -#: FWelcome.class:63 +#: FWelcome.class:68 msgid "Recent projects" msgstr "最近的工程" -#: FWelcome.form:23 +#: FWelcome.class:70 Project.module:6185 +#, fuzzy +msgid "Installed software" +msgstr "已安装软件" + +#: FWelcome.form:25 msgid "Welcome to Gambas 3" msgstr "欢迎使用Gambas 3" -#: FarmIdentity.class:133 +#: FarmIdentity.class:135 msgid "Anonymous" msgstr "匿名" -#: FarmRequest.class:123 +#: FarmRequest.class:125 msgid "No answer." msgstr "" -#: FarmRequest.class:163 +#: FarmRequest.class:165 msgid "Register user" msgstr "注册用户" -#: FarmRequest.class:221 +#: FarmRequest.class:232 msgid "Publish project" msgstr "发布工程" -#: FarmRequest.class:329 +#: FarmRequest.class:351 msgid "Download software" msgstr "下载软件" -#: FarmRequest.class:355 +#: FarmRequest.class:377 msgid "Delete software" msgstr "删除软件" -#: Language.module:7 +#: Language.module:8 msgid "Afrikaans (South Africa)" msgstr "南非荷兰语 (南非)" -#: Language.module:9 +#: Language.module:11 msgid "Arabic (Egypt)" msgstr "Arabic (Egypt)" -#: Language.module:10 +#: Language.module:12 msgid "Arabic (Tunisia)" msgstr "Arabic (Tunisia)" -#: Language.module:12 +#: Language.module:15 msgid "Azerbaijani (Azerbaijan)" msgstr "阿塞拜疆语(阿塞拜疆)" -#: Language.module:14 +#: Language.module:18 msgid "Bulgarian (Bulgaria)" msgstr "Bulgarian (Bulgaria)" -#: Language.module:16 +#: Language.module:21 msgid "Catalan (Catalonia, Spain)" msgstr "Catalan (Catalonia, Spain)" -#: Language.module:19 +#: Language.module:25 msgid "Welsh (United Kingdom)" msgstr "Welsh (英国)" -#: Language.module:21 +#: Language.module:28 msgid "Czech (Czech Republic)" msgstr "捷克语(捷克共和国)" -#: Language.module:23 +#: Language.module:31 msgid "Danish (Denmark)" msgstr "Danish (Denmark)" -#: Language.module:25 +#: Language.module:34 msgid "German (Germany)" msgstr "德语(德国)" -#: Language.module:26 +#: Language.module:35 msgid "German (Belgium)" msgstr "德语(Belgium)" -#: Language.module:28 +#: Language.module:38 msgid "Greek (Greece)" msgstr "希腊语(希腊)" -#: Language.module:30 +#: Language.module:41 msgid "English (common)" msgstr "英语(通用)" -#: Language.module:31 +#: Language.module:42 msgid "English (United Kingdom)" msgstr "英语(英国)" -#: Language.module:32 +#: Language.module:43 msgid "English (U.S.A.)" msgstr "英语(美国)" -#: Language.module:33 +#: Language.module:44 msgid "English (Australia)" msgstr "英语(澳大利亚)" -#: Language.module:34 +#: Language.module:45 msgid "English (Canada)" msgstr "英语(加拿大)" -#: Language.module:36 +#: Language.module:48 msgid "Esperanto (Anywhere!)" msgstr "世界语(任何地方)" -#: Language.module:38 +#: Language.module:51 msgid "Spanish (common)" msgstr "西班牙语(普通的)" -#: Language.module:39 +#: Language.module:52 msgid "Spanish (Spain)" msgstr "西班牙语(西班牙)" -#: Language.module:40 +#: Language.module:53 msgid "Spanish (Argentina)" msgstr "西班牙语(阿根廷)" -#: Language.module:42 +#: Language.module:56 msgid "Estonian (Estonia)" msgstr "爱沙尼亚语(爱沙尼亚)" -#: Language.module:44 +#: Language.module:59 msgid "Basque (Basque country)" msgstr "巴斯克语(巴斯克地区)" -#: Language.module:46 +#: Language.module:62 msgid "Farsi (Iran)" msgstr "波斯语(伊朗)" -#: Language.module:48 +#: Language.module:65 msgid "Finnish (Finland)" msgstr "芬兰语(芬兰)" -#: Language.module:50 +#: Language.module:68 msgid "French (France)" msgstr "法语(France)" -#: Language.module:51 +#: Language.module:69 msgid "French (Belgium)" msgstr "法语(Belgium)" -#: Language.module:52 +#: Language.module:70 msgid "French (Canada)" msgstr "法语(Canada)" -#: Language.module:53 +#: Language.module:71 msgid "French (Switzerland)" msgstr "法语(Switzerland)" -#: Language.module:55 +#: Language.module:74 msgid "Galician (Spain)" msgstr "Galician (Spain)" -#: Language.module:57 +#: Language.module:77 msgid "Hebrew (Israel)" msgstr "希伯来语 (以色列)" -#: Language.module:59 +#: Language.module:80 msgid "Hindi (India)" msgstr "印地语(印度)" -#: Language.module:61 +#: Language.module:83 msgid "Hungarian (Hungary)" msgstr "Hungarian (Hungary)" -#: Language.module:63 +#: Language.module:86 msgid "Croatian (Croatia)" msgstr "Croatian (Croatia)" -#: Language.module:65 +#: Language.module:89 msgid "Indonesian (Indonesia)" msgstr "印度尼西亚语 (印度尼西亚)" -#: Language.module:67 +#: Language.module:92 msgid "Irish (Ireland)" msgstr "Irish (Ireland)" -#: Language.module:69 +#: Language.module:95 msgid "Icelandic (Iceland)" msgstr "冰岛语 (冰岛)" -#: Language.module:71 +#: Language.module:98 msgid "Italian (Italy)" msgstr "意大利语(意大利)" -#: Language.module:73 +#: Language.module:101 msgid "Japanese (Japan)" msgstr "日本语(日本)" -#: Language.module:75 +#: Language.module:104 msgid "Khmer (Cambodia)" msgstr "高棉语(柬埔寨)" -#: Language.module:77 +#: Language.module:107 msgid "Korean (Korea)" msgstr "朝鲜语(朝鲜)" -#: Language.module:79 +#: Language.module:110 msgid "Latin" msgstr "拉丁" -#: Language.module:81 +#: Language.module:113 msgid "Lithuanian (Lithuania)" msgstr "立陶宛语(立陶宛)" -#: Language.module:83 +#: Language.module:116 msgid "Malayalam (India)" msgstr "马拉雅拉姆语(印度)" -#: Language.module:85 +#: Language.module:119 msgid "Macedonian (Republic of Macedonia)" msgstr "马其顿语(马其顿共和国)" -#: Language.module:87 +#: Language.module:122 msgid "Dutch (Netherlands)" msgstr "荷兰语(Netherlands)" -#: Language.module:88 +#: Language.module:123 msgid "Dutch (Belgium)" msgstr "荷兰语(Belgium)" -#: Language.module:90 +#: Language.module:126 msgid "Norwegian (Norway)" msgstr "挪威语(挪威)" -#: Language.module:92 +#: Language.module:129 msgid "Punjabi (India)" msgstr "旁遮普语(印度)" -#: Language.module:94 +#: Language.module:132 msgid "Polish (Poland)" msgstr "波兰语(波兰)" -#: Language.module:96 +#: Language.module:135 msgid "Portuguese (Portugal)" msgstr "Portuguese (Portugal)" -#: Language.module:97 +#: Language.module:136 msgid "Portuguese (Brazil)" msgstr "Portuguese (Brazil)" -#: Language.module:99 +#: Language.module:139 msgid "Valencian (Valencian Community, Spain)" msgstr "巴伦西亚语(巴伦西亚社区,西班牙)" -#: Language.module:101 +#: Language.module:142 msgid "Romanian (Romania)" msgstr "罗马尼亚语(罗马尼亚)" -#: Language.module:103 +#: Language.module:145 msgid "Russian (Russia)" msgstr "俄语(俄罗斯)" -#: Language.module:105 +#: Language.module:148 msgid "Slovenian (Slovenia)" msgstr "Slovenian (Slovenia)" -#: Language.module:107 +#: Language.module:151 msgid "Albanian (Albania)" msgstr "阿尔巴尼亚语(阿尔巴尼亚)" -#: Language.module:109 +#: Language.module:154 msgid "Serbian (Serbia & Montenegro)" msgstr "塞尔维亚语(塞尔维亚和黑山)" -#: Language.module:111 +#: Language.module:157 msgid "Swedish (Sweden)" msgstr "瑞士语(瑞士)" -#: Language.module:113 +#: Language.module:160 msgid "Turkish (Turkey)" msgstr "土耳其语(土耳其)" -#: Language.module:115 +#: Language.module:163 msgid "Ukrainian (Ukrain)" msgstr "乌克兰语(乌克兰)" -#: Language.module:117 +#: Language.module:166 msgid "Vietnamese (Vietnam)" msgstr "越语(越南)" -#: Language.module:119 +#: Language.module:169 msgid "Wallon (Belgium)" msgstr "Wallon (Belgium)" -#: Language.module:121 +#: Language.module:172 msgid "Simplified chinese (China)" msgstr "简体中文(中华人民共和国)" -#: Language.module:122 +#: Language.module:173 msgid "Traditional chinese (Taiwan)" msgstr "繁体中文(中华人民共和国台湾省)" -#: Language.module:167 +#: Language.module:220 msgid "Unknown" msgstr "未知的" -#: MConnection.module:55 +#: MConnection.module:59 msgid "Unable to retrieve password." msgstr "不能检索的密码。" -#: MConnection.module:70 +#: MConnection.module:74 msgid "Unable to save password." msgstr "不能保存口令。" -#: MConnection.module:311 +#: MConnection.module:315 msgid "Cannot create table '&1'." msgstr "不能创建表'&1'。" -#: MConnection.module:471 +#: MConnection.module:475 msgid "Cannot create metadata table." msgstr "不能创建元数据表。" @@ -5766,742 +6201,771 @@ msgstr "要求比较操作" #: MErrorMessage.module:79 +#, fuzzy +msgid "Component name must be a string" +msgstr "别名必须是字符串" + +#: MErrorMessage.module:80 msgid "Component not found: &1" msgstr "组件未找到:&1" -#: MErrorMessage.module:80 +#: MErrorMessage.module:81 +#, fuzzy +msgid "Constant string expected" +msgstr "预计的字符串" + +#: MErrorMessage.module:82 msgid "Contents already declared" msgstr "常数已经被声明" -#: MErrorMessage.module:81 +#: MErrorMessage.module:83 msgid "Default case already defined" msgstr "默认情况下已被定义" -#: MErrorMessage.module:82 +#: MErrorMessage.module:84 msgid "Default case must be the last one" msgstr "默认情况下必须是最新的" -#: MErrorMessage.module:83 +#: MErrorMessage.module:85 msgid "Device is full" msgstr "设备满" -#: MErrorMessage.module:84 +#: MErrorMessage.module:86 msgid "Directory is not empty" msgstr "目录非空" -#: MErrorMessage.module:85 +#: MErrorMessage.module:87 msgid "Division by zero" msgstr "被零除" -#: MErrorMessage.module:86 +#: MErrorMessage.module:88 msgid "Dynamic symbols cannot be used in static function" msgstr "在静态函数中不能使用动态标识" -#: MErrorMessage.module:87 +#: MErrorMessage.module:89 msgid "Embedded array" msgstr "嵌入式数组" -#: MErrorMessage.module:88 +#: MErrorMessage.module:90 msgid "Embedded arrays are forbidden here" msgstr "这里禁止嵌入式数组" -#: MErrorMessage.module:89 +#: MErrorMessage.module:91 msgid "End of file" msgstr "文件结束" -#: MErrorMessage.module:90 +#: MErrorMessage.module:92 msgid "Equality or inequality operator expected" msgstr "需要比较操作符" -#: MErrorMessage.module:91 +#: MErrorMessage.module:93 msgid "Expression too complex" msgstr "表达式太复杂" -#: MErrorMessage.module:92 +#: MErrorMessage.module:94 msgid "Expression too complex. Too many operands" msgstr "表达式太复杂,太多操作数。" -#: MErrorMessage.module:93 +#: MErrorMessage.module:95 +#, fuzzy +msgid "Extern library name must be a string" +msgstr "库名必须是字符串" + +#: MErrorMessage.module:96 msgid "File already exists" msgstr "文件已存在" -#: MErrorMessage.module:94 +#: MErrorMessage.module:97 msgid "File is a directory" msgstr "文件是目录" -#: MErrorMessage.module:95 +#: MErrorMessage.module:98 msgid "File is locked" msgstr "文件已锁定" -#: MErrorMessage.module:96 +#: MErrorMessage.module:99 msgid "File name is too long" msgstr "文件名太长" -#: MErrorMessage.module:97 +#: MErrorMessage.module:100 msgid "File or directory does not exist" msgstr "文件或目录不存在" -#: MErrorMessage.module:98 +#: MErrorMessage.module:101 msgid "Forbidden GOSUB" msgstr "禁止GOSUB" -#: MErrorMessage.module:99 +#: MErrorMessage.module:102 msgid "Forbidden GOTO" msgstr "禁止GOTO" -#: MErrorMessage.module:100 +#: MErrorMessage.module:103 msgid "Illegal instruction" msgstr "非法指令" -#: MErrorMessage.module:101 +#: MErrorMessage.module:104 msgid "Internal compiler error: bad stack usage computed!" msgstr "内部编译器错误: 错误的堆栈使用估计!" -#: MErrorMessage.module:102 +#: MErrorMessage.module:105 msgid "Invalid assignment" msgstr "无效的对齐" -#: MErrorMessage.module:103 +#: MErrorMessage.module:106 msgid "Invalid date" msgstr "无效的日期" -#: MErrorMessage.module:104 +#: MErrorMessage.module:107 msgid "Invalid object" msgstr "无效的对象" -#: MErrorMessage.module:105 +#: MErrorMessage.module:108 msgid "Invalid path" msgstr "无效的路径" -#: MErrorMessage.module:106 +#: MErrorMessage.module:109 +msgid "IsMissing() requires a function argument" +msgstr "" + +#: MErrorMessage.module:110 msgid "Jump is too far" msgstr "跳转太远" -#: MErrorMessage.module:107 +#: MErrorMessage.module:111 msgid "Label '&1' not declared" msgstr "标签'&1'未找到" -#: MErrorMessage.module:108 +#: MErrorMessage.module:112 msgid "Library name must be a string" msgstr "库名必须是字符串" -#: MErrorMessage.module:109 +#: MErrorMessage.module:113 msgid "Loop variable already in use" msgstr "循环变量已经使用" -#: MErrorMessage.module:110 +#: MErrorMessage.module:114 msgid "Loop variable must be local" msgstr "循环变量必须是局部的" -#: MErrorMessage.module:111 +#: MErrorMessage.module:115 msgid "ME cannot be used in a static function" msgstr "ME不能用于静态函数" -#: MErrorMessage.module:112 +#: MErrorMessage.module:116 msgid "Mathematic error" msgstr "数学错误" -#: MErrorMessage.module:113 +#: MErrorMessage.module:117 msgid "Missing #Endif" msgstr "缺失#Endif" -#: MErrorMessage.module:114 +#: MErrorMessage.module:118 msgid "Missing ']'" msgstr "缺失']'" -#: MErrorMessage.module:115 +#: MErrorMessage.module:119 msgid "Missing '}'" msgstr "缺失'}'" -#: MErrorMessage.module:116 +#: MErrorMessage.module:120 msgid "Missing operator" msgstr "缺失操作符" -#: MErrorMessage.module:117 +#: MErrorMessage.module:121 msgid "Missing right brace" msgstr "缺失右括号" -#: MErrorMessage.module:118 +#: MErrorMessage.module:122 msgid "NEW cannot have arguments passed by reference" msgstr "NEW不能通过引用传递参数" -#: MErrorMessage.module:119 +#: MErrorMessage.module:123 msgid "No instantiation method" msgstr "无方法实例" -#: MErrorMessage.module:120 +#: MErrorMessage.module:124 msgid "No parent class" msgstr "无父类" -#: MErrorMessage.module:121 +#: MErrorMessage.module:125 msgid "No return value" msgstr "无返回值" -#: MErrorMessage.module:122 +#: MErrorMessage.module:126 msgid "No startup method" msgstr "无启动方法" -#: MErrorMessage.module:123 +#: MErrorMessage.module:127 msgid "Non terminated string" msgstr "无结束字符串" -#: MErrorMessage.module:124 +#: MErrorMessage.module:128 msgid "Not a directory: &1" msgstr "不是目录:&1" -#: MErrorMessage.module:125 +#: MErrorMessage.module:129 msgid "Not a function" msgstr "不是函数" -#: MErrorMessage.module:126 +#: MErrorMessage.module:130 msgid "Not a procedure" msgstr "不是过程" -#: MErrorMessage.module:127 +#: MErrorMessage.module:131 msgid "Not an array" msgstr "不是数组" -#: MErrorMessage.module:128 +#: MErrorMessage.module:132 msgid "Not an enumeration" msgstr "不是枚举" -#: MErrorMessage.module:129 +#: MErrorMessage.module:133 msgid "Not an object" msgstr "不是对象" -#: MErrorMessage.module:130 +#: MErrorMessage.module:134 msgid "Not enough argument to New()" msgstr "New()没有足够参数" -#: MErrorMessage.module:131 +#: MErrorMessage.module:135 msgid "Not enough arguments" msgstr "没有足够参数" -#: MErrorMessage.module:132 +#: MErrorMessage.module:136 msgid "Not enough arguments to &1()" msgstr "&1()没有足够参数" -#: MErrorMessage.module:133 +#: MErrorMessage.module:137 msgid "Not implemented yet" msgstr "仍未实现" -#: MErrorMessage.module:134 +#: MErrorMessage.module:138 msgid "Not supported" msgstr "不支持" -#: MErrorMessage.module:135 +#: MErrorMessage.module:139 msgid "Null object" msgstr "空对象" -#: MErrorMessage.module:136 +#: MErrorMessage.module:140 msgid "Number" msgstr "数字" -#: MErrorMessage.module:137 +#: MErrorMessage.module:141 msgid "Number or date" msgstr "数字或日期" -#: MErrorMessage.module:138 +#: MErrorMessage.module:142 msgid "Number, Date or String" msgstr "数字、日期或字符串" -#: MErrorMessage.module:139 +#: MErrorMessage.module:143 msgid "Number, String or Object" msgstr "数字、字符串或对象" -#: MErrorMessage.module:140 +#: MErrorMessage.module:144 msgid "Object" msgstr "对象" -#: MErrorMessage.module:141 +#: MErrorMessage.module:145 msgid "Out of bounds" msgstr "越界" -#: MErrorMessage.module:142 +#: MErrorMessage.module:146 msgid "Out of memory" msgstr "内存耗尽" -#: MErrorMessage.module:143 +#: MErrorMessage.module:147 msgid "Out of range" msgstr "超出范围" -#: MErrorMessage.module:144 +#: MErrorMessage.module:148 msgid "Overflow" msgstr "溢出" -#: MErrorMessage.module:145 +#: MErrorMessage.module:149 msgid "Overriding an already inherited class is forbidden" msgstr "禁止覆盖一个已经被继承的类" -#: MErrorMessage.module:146 +#: MErrorMessage.module:150 msgid "Pointer" msgstr "指针" -#: MErrorMessage.module:147 +#: MErrorMessage.module:151 msgid "Read error" msgstr "读取出错" -#: MErrorMessage.module:148 +#: MErrorMessage.module:152 msgid "Return value datatype not specified in function declaration" msgstr "函数声明未指定返回值数据类型" -#: MErrorMessage.module:149 +#: MErrorMessage.module:153 msgid "STOP instruction encountered" msgstr "遇到STOP指令" -#: MErrorMessage.module:150 +#: MErrorMessage.module:154 msgid "SUPER cannot be used alone" msgstr "SUPER不能被单独使用" -#: MErrorMessage.module:151 +#: MErrorMessage.module:155 msgid "Serialization error" msgstr "串行化错误" -#: MErrorMessage.module:152 +#: MErrorMessage.module:156 msgid "Stack overflow" msgstr "堆栈溢出" -#: MErrorMessage.module:153 +#: MErrorMessage.module:157 msgid "Standard type" msgstr "标准类型" -#: MErrorMessage.module:154 +#: MErrorMessage.module:158 msgid "Stream is closed" msgstr "流已关闭" -#: MErrorMessage.module:156 +#: MErrorMessage.module:160 msgid "String expected" msgstr "预计的字符串" -#: MErrorMessage.module:157 +#: MErrorMessage.module:161 msgid "Structures must be public" msgstr "结构体必须是公共的" -#: MErrorMessage.module:158 +#: MErrorMessage.module:162 msgid "Subroutine arguments cannot be passed by reference" msgstr "子程序参数不能被通过引用传递。" -#: MErrorMessage.module:159 +#: MErrorMessage.module:163 msgid "Syntax error" msgstr "语法错误" -#: MErrorMessage.module:160 +#: MErrorMessage.module:164 msgid "Syntax error at function declaration" msgstr "函数声明语法错误" -#: MErrorMessage.module:161 +#: MErrorMessage.module:165 msgid "Syntax error in event name" msgstr "事件名语法错误" -#: MErrorMessage.module:162 +#: MErrorMessage.module:166 msgid "Syntax error in file open mode" msgstr "文件打开模式语法错误" -#: MErrorMessage.module:163 +#: MErrorMessage.module:167 msgid "Syntax error in return type" msgstr "返回类型语法错误" -#: MErrorMessage.module:164 +#: MErrorMessage.module:168 msgid "Syntax error. &1 expected" msgstr "语法错误,要求&1。" -#: MErrorMessage.module:165 +#: MErrorMessage.module:169 msgid "Syntax error. '...' must be the last argument" msgstr "语法错误,'...'必须是最后的参数" -#: MErrorMessage.module:166 +#: MErrorMessage.module:170 msgid "Syntax error. Bad property type" msgstr "语法错误,错误的属性类型" -#: MErrorMessage.module:167 +#: MErrorMessage.module:171 msgid "Syntax error. CASE or DEFAULT expected after SELECT" msgstr "语法错误,CASE或DEFAULT要在SELECT之后" -#: MErrorMessage.module:168 +#: MErrorMessage.module:172 msgid "Syntax error. CLASS needs an identifier" msgstr "语法错误,CLASS需要标识符" -#: MErrorMessage.module:169 +#: MErrorMessage.module:173 msgid "Syntax error. Cannot use this syntax in assignment" msgstr "语法错误,不能在对齐中使用该语法" -#: MErrorMessage.module:170 +#: MErrorMessage.module:174 msgid "Syntax error. INHERITS needs a class name" msgstr "语法错误,INHERITS需要类名" -#: MErrorMessage.module:171 +#: MErrorMessage.module:175 msgid "Syntax error. Identifier expected." msgstr "语法错误,要求标识符" -#: MErrorMessage.module:172 +#: MErrorMessage.module:176 msgid "Syntax error. Invalid identifier in function name" msgstr "语法错误,函数名中有无效的标识符" -#: MErrorMessage.module:173 +#: MErrorMessage.module:177 msgid "Syntax error. Invalid identifier in property name" msgstr "语法错误,属性名中有无效的标识符" -#: MErrorMessage.module:174 +#: MErrorMessage.module:178 msgid "Syntax error. Invalid optional parameter" msgstr "语法错误,无效的可选参数" -#: MErrorMessage.module:175 +#: MErrorMessage.module:179 msgid "Syntax error. Invalid return type" msgstr "语法错误,无效的返回类型" -#: MErrorMessage.module:176 +#: MErrorMessage.module:180 msgid "Syntax error. Invalid type description of &1 argument" msgstr "语法错误,&1参数的类型描述无效" -#: MErrorMessage.module:177 +#: MErrorMessage.module:181 msgid "Syntax error. Invalid type description of &1 field" msgstr "语法错误,&1字段的类型描述无效" -#: MErrorMessage.module:178 +#: MErrorMessage.module:182 msgid "Syntax error. Needless arguments" msgstr "语法错误,不需要的参数" -#: MErrorMessage.module:179 +#: MErrorMessage.module:183 msgid "Syntax error. Point syntax used outside of WITH / END WITH" msgstr "语法错误,点语法被用于WITH/END WITH之外" -#: MErrorMessage.module:180 +#: MErrorMessage.module:184 msgid "Syntax error. STRUCT needs an identifier" msgstr "语法错误,STRUCT需要标识符" -#: MErrorMessage.module:181 +#: MErrorMessage.module:185 msgid "Syntax error. The &1 argument is not a valid identifier" msgstr "语法错误,&1参数不是有效标识符" -#: MErrorMessage.module:182 +#: MErrorMessage.module:186 msgid "Syntax error. The &1 field is not a valid identifier" msgstr "语法错误,&1字段不是有效标识符" -#: MErrorMessage.module:183 +#: MErrorMessage.module:187 msgid "Syntax error. VarPtr() takes only one identifier" msgstr "语法错误, VarPtr()仅接受一个标识符" -#: MErrorMessage.module:184 +#: MErrorMessage.module:188 msgid "System error #&1: &2" msgstr "系统错误#&1:&2" -#: MErrorMessage.module:185 +#: MErrorMessage.module:189 msgid "The '!' operator must be followed by an identifier" msgstr "'!'运算符必须紧跟一个标识符" -#: MErrorMessage.module:186 +#: MErrorMessage.module:190 msgid "The '.' operator must be followed by an identifier" msgstr "'.'运算符必须紧跟一个标识符" -#: MErrorMessage.module:187 +#: MErrorMessage.module:191 msgid "The function must take a fixed number of arguments" msgstr "函数必须接受固定数量的参数" -#: MErrorMessage.module:188 +#: MErrorMessage.module:192 msgid "The special method &1 cannot be a function" msgstr "指定的方法&1不能是函数" -#: MErrorMessage.module:189 +#: MErrorMessage.module:193 msgid "The special method &1 cannot be implemented" msgstr "指定的方法&1不能被实现" -#: MErrorMessage.module:190 +#: MErrorMessage.module:194 msgid "The special method &1 cannot be static" msgstr "指定的方法&1不能是静态的" -#: MErrorMessage.module:191 +#: MErrorMessage.module:195 msgid "The special method &1 must be a function" msgstr "指定的方法&1必须是函数" -#: MErrorMessage.module:192 +#: MErrorMessage.module:196 msgid "The special method &1 must be public" msgstr "指定的方法&1必须是公共的" -#: MErrorMessage.module:193 +#: MErrorMessage.module:197 msgid "The special method &1 must be static" msgstr "指定的方法&1必须是静态的" -#: MErrorMessage.module:194 +#: MErrorMessage.module:198 msgid "The special method &1 must return a boolean" msgstr "指定的方法&1必须是返回布尔值" -#: MErrorMessage.module:195 +#: MErrorMessage.module:199 msgid "The special method &1 must take a variable number of arguments only" msgstr "指定的方法&1必须仅接受可变数量的参数" -#: MErrorMessage.module:196 +#: MErrorMessage.module:200 msgid "The special method &1 must take at least one argument" msgstr "指定的方法&1必须接受至少一个参数" -#: MErrorMessage.module:197 +#: MErrorMessage.module:201 msgid "The special method &1 takes no arguments" msgstr "指定方法&1不接受参数" -#: MErrorMessage.module:198 +#: MErrorMessage.module:202 msgid "The special method must return an integer" msgstr "指定方法必须返回一个整数" -#: MErrorMessage.module:199 +#: MErrorMessage.module:203 msgid "The special method must take exactly one argument" msgstr "指定方法必须精确接受一个参数" -#: MErrorMessage.module:200 +#: MErrorMessage.module:204 msgid "The special method must take exactly two arguments" msgstr "指定方法必须精确接受两个参数" -#: MErrorMessage.module:201 +#: MErrorMessage.module:205 msgid "The special method signature is incorrect" msgstr "指定的方法签名错误" -#: MErrorMessage.module:202 +#: MErrorMessage.module:206 msgid "This expression cannot be a statement" msgstr "表达式不能是一个语句" -#: MErrorMessage.module:203 +#: MErrorMessage.module:207 msgid "This expression cannot be passed by reference" msgstr "表达式不能被引用传递" -#: MErrorMessage.module:204 +#: MErrorMessage.module:208 msgid "Too many arguments" msgstr "太多的参数" -#: MErrorMessage.module:205 +#: MErrorMessage.module:209 msgid "Too many arguments to &1()" msgstr "太多的参数给&1()" -#: MErrorMessage.module:206 +#: MErrorMessage.module:210 msgid "Too many array declarations" msgstr "太多的数组声明" -#: MErrorMessage.module:207 +#: MErrorMessage.module:211 msgid "Too many constants" msgstr "太多的常量" -#: MErrorMessage.module:208 +#: MErrorMessage.module:212 msgid "Too many different classes used" msgstr "使用太多不同的类" -#: MErrorMessage.module:209 +#: MErrorMessage.module:213 msgid "Too many dimensions" msgstr "太多的维度" -#: MErrorMessage.module:210 +#: MErrorMessage.module:214 msgid "Too many dynamic variables" msgstr "太多的动态变量" -#: MErrorMessage.module:211 +#: MErrorMessage.module:215 msgid "Too many events" msgstr "太多的事件" -#: MErrorMessage.module:212 +#: MErrorMessage.module:216 msgid "Too many expressions in CASE" msgstr "在CASE中太多的表达式" -#: MErrorMessage.module:213 +#: MErrorMessage.module:217 msgid "Too many external functions" msgstr "太多的外部函数" -#: MErrorMessage.module:214 +#: MErrorMessage.module:218 msgid "Too many functions" msgstr "太多的函数" -#: MErrorMessage.module:215 +#: MErrorMessage.module:219 msgid "Too many imbricated #If...#Endif" msgstr "太多的#If...#Endif层疊" -#: MErrorMessage.module:216 +#: MErrorMessage.module:220 msgid "Too many labels" msgstr "太多的标签" -#: MErrorMessage.module:217 +#: MErrorMessage.module:221 msgid "Too many local variables" msgstr "太多的局部变量" -#: MErrorMessage.module:218 +#: MErrorMessage.module:222 msgid "Too many nested control structures." msgstr "太多的嵌套控制结构。" -#: MErrorMessage.module:219 +#: MErrorMessage.module:223 msgid "Too many property synonymous" msgstr "太多的同义属性" -#: MErrorMessage.module:220 +#: MErrorMessage.module:224 msgid "Too many simultaneous new strings" msgstr "同时新建太多的字符串" -#: MErrorMessage.module:221 +#: MErrorMessage.module:225 msgid "Too many static variables" msgstr "太多的静态变量" -#: MErrorMessage.module:222 +#: MErrorMessage.module:226 msgid "Too many unknown symbols" msgstr "太多的未知标识" -#: MErrorMessage.module:223 +#: MErrorMessage.module:227 msgid "Trailing backslash" msgstr "反斜线" -#: MErrorMessage.module:224 +#: MErrorMessage.module:228 msgid "Type mismatch" msgstr "类型错误" -#: MErrorMessage.module:225 +#: MErrorMessage.module:229 msgid "Type mismatch: wanted &1, got &2 instead" msgstr "类型错误:需要&1,却是&2" -#: MErrorMessage.module:226 +#: MErrorMessage.module:230 msgid "Unable to create closure" msgstr "无法创建封闭的包" -#: MErrorMessage.module:227 +#: MErrorMessage.module:231 msgid "Unable to get file position" msgstr "不能获取文件位置" -#: MErrorMessage.module:228 +#: MErrorMessage.module:232 msgid "Unable to load class file" msgstr "不能加载类文件。" -#: MErrorMessage.module:229 +#: MErrorMessage.module:233 msgid "Unable to prepare function description" msgstr "不能准备函数说明" -#: MErrorMessage.module:230 +#: MErrorMessage.module:234 msgid "Unexpected &1" msgstr "意外的&1" -#: MErrorMessage.module:231 +#: MErrorMessage.module:235 msgid "Unexpected end of line" msgstr "意外的行结尾" -#: MErrorMessage.module:232 +#: MErrorMessage.module:236 msgid "Unexpected string" msgstr "意外的字符串" -#: MErrorMessage.module:233 +#: MErrorMessage.module:237 msgid "Unknown error" msgstr "未知错误" -#: MErrorMessage.module:234 +#: MErrorMessage.module:238 msgid "Unknown file extension" msgstr "未知文件扩展名" -#: MErrorMessage.module:235 +#: MErrorMessage.module:239 msgid "Unknown identifier: &1" msgstr "未知的标识符:&1" -#: MErrorMessage.module:236 +#: MErrorMessage.module:240 msgid "Unknown operator" msgstr "未知操作" -#: MErrorMessage.module:237 +#: MErrorMessage.module:241 msgid "Unknown symbol '&2' in class '&1'" msgstr "在‘&1’类中存在未知的标识:'&2'" -#: MErrorMessage.module:238 +#: MErrorMessage.module:242 msgid "Unknown user or group" msgstr "未知用户或组" -#: MErrorMessage.module:239 +#: MErrorMessage.module:243 msgid "Unsupported datatype" msgstr "不支持的数据类型" -#: MErrorMessage.module:240 +#: MErrorMessage.module:244 msgid "Unsupported string conversion" msgstr "不支持的字符串转换" -#: MErrorMessage.module:241 +#: MErrorMessage.module:245 msgid "Useless LOCK" msgstr "不使用LOCK" -#: MErrorMessage.module:242 +#: MErrorMessage.module:246 msgid "VarPtr() argument must be a dynamic, a static or a local variable" msgstr "VarPtr()参数必须是动态的、静态的或局部变量" -#: MErrorMessage.module:243 +#: MErrorMessage.module:247 msgid "Variant" msgstr "变体" -#: MErrorMessage.module:244 +#: MErrorMessage.module:248 msgid "Void key" msgstr "空键" -#: MErrorMessage.module:245 +#: MErrorMessage.module:249 msgid "Write error" msgstr "写入出错" -#: MErrorMessage.module:246 +#: MErrorMessage.module:250 msgid "cannot find component" msgstr "不能找到组件" -#: MErrorMessage.module:247 +#: MErrorMessage.module:251 msgid "cannot find library" msgstr "不能找到库" -#: MErrorMessage.module:248 +#: MErrorMessage.module:252 +#, fuzzy +msgid "class name hidden by global declaration: &1" +msgstr "常量被局部声明:&1屏蔽" + +#: MErrorMessage.module:253 +#, fuzzy +msgid "class name hidden by local declaration: &1" +msgstr "常量被局部声明:&1屏蔽" + +#: MErrorMessage.module:254 msgid "constant hidden by local declaration: &1" msgstr "常量被局部声明:&1屏蔽" -#: MErrorMessage.module:249 +#: MErrorMessage.module:255 msgid "extern function hidden by local declaration: &1" msgstr "外部函数被局部声明:&1屏蔽" -#: MErrorMessage.module:250 +#: MErrorMessage.module:256 msgid "function hidden by local declaration: &1" msgstr "函数被局部声明:&1屏蔽" -#: MErrorMessage.module:251 +#: MErrorMessage.module:257 msgid "global variable hidden by local declaration: &1" msgstr "全局变量被局部变量:&1屏蔽" -#: MErrorMessage.module:252 +#: MErrorMessage.module:258 msgid "unknown error" msgstr "未知错误" -#: MErrorMessage.module:253 +#: MErrorMessage.module:259 msgid "unused argument: &1" msgstr "未使用的参数:&1" -#: MErrorMessage.module:254 +#: MErrorMessage.module:260 msgid "unused extern function: &1" msgstr "未使用的外部函数:&1" -#: MErrorMessage.module:255 +#: MErrorMessage.module:261 msgid "unused function: &1" msgstr "未使用的函数:&1" -#: MErrorMessage.module:256 +#: MErrorMessage.module:262 msgid "unused global variable: &1" msgstr "未使用的全局变量:&1" -#: MErrorMessage.module:257 +#: MErrorMessage.module:263 msgid "unused variable: &1" msgstr "未使用的变量:&1" -#: MErrorMessage.module:261 +#: MErrorMessage.module:267 msgid "cannot open slave pseudo-terminal: " msgstr "不能打开从属虚拟终端:" -#: MErrorMessage.module:262 +#: MErrorMessage.module:268 msgid "cannot initialize pseudo-terminal: " msgstr "不能初始化虚拟终端:" -#: MErrorMessage.module:263 +#: MErrorMessage.module:269 msgid "cannot plug standard input: " msgstr "不能阻塞标准输入:" -#: MErrorMessage.module:264 +#: MErrorMessage.module:270 msgid "cannot plug standard output and standard error: " msgstr "不能阻塞标准输出和标准错误输出:" -#: MErrorMessage.module:265 +#: MErrorMessage.module:271 msgid "cannot run executable: " msgstr "不能运行可执行文件:" -#: MHelp.module:292 +#: MHelp.module:313 msgid "No help found." msgstr "没有找到帮助。" -#: MHelp.module:954 Wiki.module:797 +#: MHelp.module:976 Wiki.module:799 msgid "This page does not exist." msgstr "该页面不存在。" @@ -6589,67 +7053,67 @@ msgid "Symbols" msgstr "符号" -#: Package.module:67 +#: Package.module:76 msgid "'&1' is missing." msgstr "'&1'丢失。" -#: Package.module:76 +#: Package.module:85 msgid "'&1' and '&2' are missing." msgstr "'&1'和'&2'丢失。" -#: Package.module:172 +#: Package.module:247 msgid "Saving CHANGELOG file." msgstr "保存修改日志" -#: Package.module:542 +#: Package.module:618 msgid "Making &1 support package..." msgstr "生成&1支持包..." -#: Package.module:580 +#: Package.module:668 msgid "Creating package for &1." msgstr "为&1创建一个代码包." -#: Package.module:611 +#: Package.module:699 msgid "The package build has failed." msgstr "建包失败." -#: Package.module:643 +#: Package.module:762 msgid "Making build directory." msgstr "建立工作目录。" -#: Package.module:671 +#: Package.module:790 msgid "Creating desktop file..." msgstr "创建桌面文件..." -#: Package.module:679 +#: Package.module:798 msgid "Sources are being debianizated." msgstr "源代码正被debian化。" -#: Package.module:858 +#: Package.module:983 msgid "Creating package..." msgstr "创建源代码包..." -#: Package.module:867 +#: Package.module:991 msgid "'dpkg-buildpackage' has failed." msgstr "'dpkg-buildpackage' 失败。" -#: Package.module:1123 +#: Package.module:1271 msgid "Initializing ~/RPM directory." msgstr "初始化~/RPM目录" -#: Package.module:1143 +#: Package.module:1291 msgid "Creating source package." msgstr "创建代码包." -#: Package.module:1167 +#: Package.module:1315 msgid "Creating .spec file." msgstr "创建.spec文件." -#: Package.module:1417 +#: Package.module:1573 msgid "'rpmbuild' has returned the following error code:" msgstr "'rpmbuild'返回错误代码:" -#: Package.module:1813 +#: Package.module:1976 msgid "'tar' has returned the following error code:" msgstr "'tar' 返回错误代码:" @@ -6665,330 +7129,356 @@ msgid "Patch didn't apply:\n" msgstr "补丁未应用:\n" -#: Project.module:214 +#: Project.module:219 msgid "Automation" msgstr "自动" -#: Project.module:215 +#: Project.module:220 msgid "Basic" msgstr "基本" -#: Project.module:217 +#: Project.module:222 msgid "Drawing" msgstr "绘制" -#: Project.module:218 -msgid "Games" -msgstr "游戏" +#: Project.module:225 +msgid "Miscellaneous" +msgstr "其它" -#: Project.module:221 +#: Project.module:226 msgid "Networking" msgstr "网络" -#: Project.module:222 +#: Project.module:227 msgid "OpenGL" msgstr "OpenGL" -#: Project.module:223 +#: Project.module:228 msgid "Printing" msgstr "打印" -#: Project.module:224 +#: Project.module:229 msgid "Sound" msgstr "声音" -#: Project.module:225 -msgid "Video" -msgstr "视频" - -#: Project.module:226 +#: Project.module:231 msgid "Controls" msgstr "控件" -#: Project.module:227 +#: Project.module:232 msgid "Multimedia" msgstr "多媒体" -#: Project.module:228 +#: Project.module:233 msgid "Web" msgstr "-" -#: Project.module:345 +#: Project.module:361 msgid "File not found!" msgstr "文件未找到!" -#: Project.module:457 +#: Project.module:471 msgid "This project does not exist." msgstr "该工程不存在。" -#: Project.module:469 -msgid "Unable to find Gambas IDE executable in directory:\n\n&1" -msgstr "不能在目录中找到Gambas IDE可执行文件:\n\n&1" +#: Project.module:483 +msgid "" +"Unable to find Gambas IDE executable in directory:\n" +"\n" +"&1" +msgstr "" +"不能在目录中找到Gambas IDE可执行文件:\n" +"\n" +"&1" -#: Project.module:482 +#: Project.module:496 msgid "This is not a Gambas project." msgstr "这不是一个Gambas工程。" -#: Project.module:485 +#: Project.module:499 msgid "This is a Gambas 1.0 project. Use Gambas 2 to convert it." msgstr "这是Gambas1.0工程。用Gambas2.0进行转换。" -#: Project.module:488 +#: Project.module:502 msgid "Convert" msgstr "转换" -#: Project.module:488 -msgid "This is a Gambas 2.0 project.\n\nDo you want to convert it?" -msgstr "这是Gambas2.0工程。\n是否转换?" +#: Project.module:502 +msgid "" +"This is a Gambas 2.0 project.\n" +"\n" +"Do you want to convert it?" +msgstr "" +"这是Gambas2.0工程。\n" +"是否转换?" -#: Project.module:506 +#: Project.module:520 msgid "Do not open" msgstr "不要打开" -#: Project.module:506 +#: Project.module:520 msgid "Open after all" msgstr "继续打开" -#: Project.module:506 -msgid "This project seems to be already opened.\n\nOpening the same project twice can lead to data loss." -msgstr "该工程看来已经打开。\n\n两次打开同一工程将导致数据丢失。" +#: Project.module:520 +msgid "" +"This project seems to be already opened.\n" +"\n" +"Opening the same project twice can lead to data loss." +msgstr "" +"该工程看来已经打开。\n" +"\n" +"两次打开同一工程将导致数据丢失。" -#: Project.module:512 +#: Project.module:526 msgid "It cannot be converted." msgstr "不能被转换" -#: Project.module:512 +#: Project.module:526 msgid "This project is read-only." msgstr "此工程是只读的." -#: Project.module:529 +#: Project.module:543 msgid "Copying project inside a temporary directory..." msgstr "复制工程到一个临时目录内..." -#: Project.module:532 +#: Project.module:546 msgid "Unable to create temporary directory" msgstr "不能创建临时目录" -#: Project.module:557 +#: Project.module:571 msgid "Converting project structure..." msgstr "转换工程结构..." -#: Project.module:588 +#: Project.module:602 msgid "Applying conversion..." msgstr "应用转换..." -#: Project.module:594 +#: Project.module:608 msgid "Unable to apply conversion" msgstr "不能应用转换" -#: Project.module:708 +#: Project.module:721 msgid "Some libraries used by the project are missing." msgstr "工程使用的某些库缺失。" -#: Project.module:727 +#: Project.module:740 msgid "Cannot open project file :\n" msgstr "无法打开工程文件:\n" -#: Project.module:1289 +#: Project.module:1308 msgid "Files" msgstr "文件" -#: Project.module:1492 +#: Project.module:1510 msgid "The following classes have circular inheritance:" msgstr "下列类存在循环继承:" -#: Project.module:1696 +#: Project.module:1714 msgid "ALPHA VERSION, USE AT YOUR OWN RISK!" msgstr "α版,用者自担风险!" -#: Project.module:1698 +#: Project.module:1716 msgid "DEVELOPMENT VERSION, USE AT YOUR OWN RISK!" msgstr "开发版,用者自担风险!" -#: Project.module:2022 +#: Project.module:2039 msgid "Loading &1..." msgstr "加载&1..." -#: Project.module:2079 +#: Project.module:2096 msgid "Cannot open a binary file." msgstr "不能打开二进制文件。" -#: Project.module:2115 +#: Project.module:2133 msgid "Cannot open file." msgstr "无法打开文件." -#: Project.module:2292 +#: Project.module:2309 msgid "&1th" msgstr "第&1" -#: Project.module:2345 +#: Project.module:2362 msgid "in form definition" msgstr "在窗体定义中" -#: Project.module:2352 +#: Project.module:2369 msgid "in &1." msgstr "在&1中。" -#: Project.module:2513 -msgid "Some project source files are in conflict.\nPlease solve them if you want to compile the project." -msgstr "工程某些源文件冲突。\n请解决这个问题,以便编译工程。" +#: Project.module:2530 +msgid "" +"Some project source files are in conflict.\n" +"Please solve them if you want to compile the project." +msgstr "" +"工程某些源文件冲突。\n" +"请解决这个问题,以便编译工程。" -#: Project.module:2517 +#: Project.module:2534 msgid "Compiling project" msgstr "编译工程" -#: Project.module:2760 +#: Project.module:2777 msgid "File already exists." msgstr "文件己存在" -#: Project.module:2792 +#: Project.module:2809 msgid "Directory already exists." msgstr "目录己存在." -#: Project.module:2804 +#: Project.module:2821 msgid "Cannot link template file." msgstr "不能链接模板文件。" -#: Project.module:2810 +#: Project.module:2827 msgid "Cannot copy template file." msgstr "无法复制样板文件" -#: Project.module:3031 +#: Project.module:3051 msgid "Making executable..." msgstr "制作可执行文件..." -#: Project.module:3078 +#: Project.module:3098 msgid "Cannot make executable." msgstr "无法生成可执行文件。" -#: Project.module:3672 +#: Project.module:3518 +msgid "Some components are missing: &1" +msgstr "部份组件缺失:&1" + +#: Project.module:3697 msgid "Cannot write project file." msgstr "无法写工程文件." -#: Project.module:3721 +#: Project.module:3746 msgid "Unable to create desktop shortcut." msgstr "无法创建桌面快捷方式。" -#: Project.module:3976 +#: Project.module:4015 msgid "The directory will be removed at the next commit." msgstr "在下一次提交时目录将被移除。" -#: Project.module:3993 +#: Project.module:4032 msgid "You must define a startup class or form!" msgstr "你必须定义一个自动运行的类或窗口" -#: Project.module:4024 +#: Project.module:4063 msgid "Please type a name." msgstr "请输入一个名字." -#: Project.module:4028 +#: Project.module:4067 msgid "This name contains a forbidden character:" msgstr "该名称包含禁用字符:" -#: Project.module:4032 +#: Project.module:4071 msgid "The name cannot begins with a dot." msgstr "名称不能用\".\"开头。" -#: Project.module:4036 +#: Project.module:4075 msgid "This name is already used. Choose another one." msgstr "此名己使用,请另选项一个." -#: Project.module:4072 +#: Project.module:4111 msgid "A class name must begin with a letter or an underscore, followed by any letter or digit." msgstr "类的名字必须用字母或者下划线开头,由字母和数字组成。" -#: Project.module:4120 +#: Project.module:4159 msgid "Destination already exists." msgstr "目地已经存在。" -#: Project.module:4332 +#: Project.module:4371 msgid "Unable to rename '&1'" msgstr "无法更名'&1'" -#: Project.module:4448 +#: Project.module:4487 msgid "Please type a project name." msgstr "请输入一个工程名." -#: Project.module:4456 +#: Project.module:4495 msgid "The project name cannot begin with a dot." msgstr "工程名称不能用“.”开头。" -#: Project.module:4459 +#: Project.module:4498 msgid "Non-ASCII characters are forbidden in a project name." msgstr "工程名称禁止使用非ASCII字符。" -#: Project.module:4460 +#: Project.module:4499 msgid "The following characters are forbidden in a project name: ? * / \\ SPACE" msgstr "下列字符禁止用于工程名称: ? * / \\ SPACE" -#: Project.module:4467 +#: Project.module:4506 msgid "This project already exists." msgstr "此工程己存在." -#: Project.module:4470 +#: Project.module:4509 msgid "The project directory already exists." msgstr "工程目录已经存在。" -#: Project.module:4472 +#: Project.module:4511 msgid "The project directory cannot be created because a file with the same name already exists." msgstr "由于有同名的文件存在,无法创建工程目录。" -#: Project.module:4536 +#: Project.module:4575 msgid "Unable to create source archive." msgstr "不能创建源码包。" -#: Project.module:4563 +#: Project.module:4602 msgid "Create source package" msgstr "创建代码包" -#: Project.module:4865 +#: Project.module:4859 msgid "Cannot copy file &1." msgstr "无法复制文件&1." -#: Project.module:4913 +#: Project.module:4907 msgid "Cannot create link &1." msgstr "无法创建连接&1。" -#: Project.module:4928 +#: Project.module:4922 msgid "Cannot move a directory inside itself." msgstr "无法将目录移动进它自己。" -#: Project.module:4996 +#: Project.module:4990 msgid "Cannot move file &1." msgstr "无法移动文件&1." -#: Project.module:5208 +#: Project.module:5202 msgid "The following files couldn't be removed:" msgstr "下列文件不能删除:" -#: Project.module:5647 +#: Project.module:5643 msgid "Project cleanup..." msgstr "工程清理..." -#: Project.module:5653 +#: Project.module:5649 msgid "Project files conversion..." msgstr "工程文件转换..." -#: Project.module:5683 +#: Project.module:5679 msgid "Unable to convert &1" msgstr "不能转换&1" -#: Project.module:5947 +#: Project.module:5974 msgid "The &1 program is not installed on your system." msgstr "系统未安装&1程序" -#: Project.module:5949 +#: Project.module:5976 msgid "The following programs are not installed on your system: &1." msgstr "系统未安装下列程序:&1" -#: Project.module:6037 +#: Project.module:6068 msgid "Unable to read component description file." msgstr "不能读取组件描述文件。" -#: Project.module:6086 +#: Project.module:6129 msgid "Cannot write component description file." msgstr "无法写组件描述文件。" +#: Project.module:6185 +#, fuzzy +msgid "Project templates" +msgstr "工程类型" + #: Save.module:39 msgid "Cannot save file !" msgstr "无法保存文件!" @@ -7013,11 +7503,11 @@ msgid "command timeout" msgstr "命令超时" -#: Wiki.module:520 +#: Wiki.module:522 msgid "There are &1 classes and &2 symbols in all Gambas components." msgstr "&1类和&2代号位于所有Gambas组件中。" -#: Wiki.module:799 +#: Wiki.module:801 msgid "This page does not exist in that language." msgstr "所要求语言的该页面不存在。" @@ -7029,11 +7519,95 @@ msgid "This component does not exist." msgstr "该组件不存在。" -#: WikiMarkdown.class:167 +#: WikiMarkdown.class:174 msgid "This class does not exist." msgstr "该类不存在。" -#: WikiMarkdown.class:180 +#: WikiMarkdown.class:187 msgid "This symbol does not exist." msgstr "该标识不存在。" +#~ msgid "Farm" +#~ msgstr "软件农场" + +#~ msgid "Configure" +#~ msgstr "配置" + +#~ msgid "Exported classes" +#~ msgstr "输出类" + +#~ msgid "Component advancement" +#~ msgstr "组件升级" + +#~ msgid "Environment variables" +#~ msgstr "环境变量" + +#~ msgid "About component" +#~ msgstr "(C)关于组件" + +#~ msgid "Author(s)" +#~ msgstr "作者" + +#~ msgid "Not translatable" +#~ msgstr "未翻译" + +#~ msgid "Blend" +#~ msgstr "混合" + +#~ msgid "Background color" +#~ msgstr "背景颜色" + +#~ msgid "Foreground color" +#~ msgstr "前景色" + +#~ msgid "Select a theme" +#~ msgstr "选择主题" + +#~ msgid "" +#~ "All needed information have been collected. You can now create the installation packages for your application...\n" +#~ "

Click on the OK button to create the packages.\n" +#~ "

Click on the Previous button if you had made a mistake.\n" +#~ "

Click on the Cancel button to cancel the operation.\n" +#~ "\n" +#~ msgstr "" +#~ "已采集到所有需要的信息。你现在可以为你的应用程序创建安装包...\n" +#~ "

单击OK 按钮创建安装包。\n" +#~ "

如果发生错误,单击Previous按钮。\n" +#~ "

单击Cancel按钮取消操作。\n" +#~ "\n" + +#~ msgid "Please enter the changes of your project." +#~ msgstr "请输入工程的变化。" + +#~ msgid "Prefix package name with the vendor name" +#~ msgstr "安装包名称前缀销售商名称" + +#~ msgid "Reset filter" +#~ msgstr "重置过滤器" + +#~ msgid "Break on each error" +#~ msgstr "出错即中断" + +#~ msgid "Component properties" +#~ msgstr "组件属性" + +#~ msgid "Library properties" +#~ msgstr "库属性" + +#~ msgid "Messages" +#~ msgstr "消息" + +#~ msgid "File properties" +#~ msgstr "文件属性" + +#~ msgid "Register >>" +#~ msgstr "注册>>" + +#~ msgid "Configuration" +#~ msgstr "配置" + +#~ msgid "Please enter your password." +#~ msgstr "输入登陆密码。" + +#~ msgid "Please enter your login." +#~ msgstr "输入登陆用户名。" diff -Nru gambas3-3.8.3/app/src/gambas3/.project gambas3-3.8.4/app/src/gambas3/.project --- gambas3-3.8.3/app/src/gambas3/.project 2015-11-08 16:47:24.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.project 2015-12-22 04:46:12.000000000 +0000 @@ -3,7 +3,7 @@ Title=Gambas 3 Startup=Project Icon=img/logo/logo-ide.png -Version=3.8.1 +Version=3.8.4 VersionFile=1 Component=gb.image Component=gb.gui.qt diff -Nru gambas3-3.8.3/app/src/gambas3/.src/Component/CDocumentation.class gambas3-3.8.4/app/src/gambas3/.src/Component/CDocumentation.class --- gambas3-3.8.3/app/src/gambas3/.src/Component/CDocumentation.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.src/Component/CDocumentation.class 2015-12-22 04:46:12.000000000 +0000 @@ -375,7 +375,7 @@ hModule.ParentClass = sParent hModule.ParentComponent = sComponent If Not hModule.AutoCreatable Then hModule.AutoCreatable = IsAutoCreatable(hModule.ParentClass) - cClassSymbol = GetClassSymbols(sComponent &/ sParent) + cClassSymbol = GetClassSymbols(sParent, sComponent) If cClassSymbol Then For Each hSymbol In cClassSymbol cSymbol[hSymbol.Name] = hSymbol diff -Nru gambas3-3.8.3/app/src/gambas3/.src/Editor/Code/FEditor.class gambas3-3.8.4/app/src/gambas3/.src/Editor/Code/FEditor.class --- gambas3-3.8.3/app/src/gambas3/.src/Editor/Code/FEditor.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.src/Editor/Code/FEditor.class 2015-12-22 04:46:12.000000000 +0000 @@ -857,7 +857,7 @@ Else If Key.Control Then - If Key.Code = Key.F12 Then + If Key.Code = Key.F12 And If Key.Shift Then For Each sLine In Split(File.Load("/proc/self/maps"), "\n") If InStr(sLine, "[heap]") Then diff -Nru gambas3-3.8.3/app/src/gambas3/.src/Editor/Code/FTextEditor.class gambas3-3.8.4/app/src/gambas3/.src/Editor/Code/FTextEditor.class --- gambas3-3.8.3/app/src/gambas3/.src/Editor/Code/FTextEditor.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.src/Editor/Code/FTextEditor.class 2015-12-22 04:46:12.000000000 +0000 @@ -1170,7 +1170,7 @@ Private Sub GotoProc(iLine As Integer) - $hEditor.Goto(0, iLine) + $hEditor.GotoCenter(0, iLine) End diff -Nru gambas3-3.8.3/app/src/gambas3/.src/Editor/Connection/FConnectionEditor.class gambas3-3.8.4/app/src/gambas3/.src/Editor/Connection/FConnectionEditor.class --- gambas3-3.8.3/app/src/gambas3/.src/Editor/Connection/FConnectionEditor.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.src/Editor/Connection/FConnectionEditor.class 2015-12-22 04:46:12.000000000 +0000 @@ -281,7 +281,7 @@ ' Endif - lblTitle.Text = " " & $sTitle & " " + btnTitle.Text = $sTitle $bMetadata = hConfig["Connection/DisplayMetadata"] $bTemplate = hConfig["Connection/RememberTemplate"] @@ -1859,10 +1859,11 @@ End -Public Sub tabRequest_Arrange() +Public Sub panRequest_Arrange() - edtRequest.Move(tabRequest.X + tabRequest.ClientX, tabRequest.Y + tabRequest.ClientY, tabRequest.ClientW, tabRequest.ClientH) - edtRequest.Raise + tabRequest.H = tabRequest.ClientY + 'edtRequest.Move(tabRequest.X + tabRequest.ClientX, tabRequest.Y + tabRequest.ClientY, tabRequest.ClientW, tabRequest.ClientH) + 'edtRequest.Lower End diff -Nru gambas3-3.8.3/app/src/gambas3/.src/Editor/Connection/FConnectionEditor.form gambas3-3.8.4/app/src/gambas3/.src/Editor/Connection/FConnectionEditor.form --- gambas3-3.8.3/app/src/gambas3/.src/Editor/Connection/FConnectionEditor.form 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.src/Editor/Connection/FConnectionEditor.form 2015-12-22 04:46:12.000000000 +0000 @@ -3,88 +3,80 @@ { Form Form MoveScaled(0,0,123,92) Arrangement = Arrange.Vertical - { HBox2 HBox - MoveScaled(1,0,102,4) - { btnTitle ToolButton - MoveScaled(0,0,4,4) - Picture = Picture["img/16/database.png"] - } - { lblTitle Label - MoveScaled(5,0,25,4) - Expand = True - } - } - { Separator4 Separator - MoveScaled(6,6,13,0) - } { panToolBar ToolBar - MoveScaled(3,6,75,4) + MoveScaled(4,0,87,4) Key = "connection" Text = ("Connection editor") Separator = True + { btnTitle ToolButton + MoveScaled(0,0,4,4) + Action = ".database" + AutoResize = True + Picture = Picture["img/16/database.png"] + } { btnSave ToolButton mnuSave Name = "btnSave" - MoveScaled(0,0,4,4) + MoveScaled(4,0,4,4) ToolTip = ("Save") Action = ".save" Picture = Picture["icon:/small/save"] } { btnReload ToolButton mnuReload Name = "btnReload" - MoveScaled(4,0,4,4) + MoveScaled(8,0,4,4) ToolTip = ("Reload") Action = ".reload" Picture = Picture["icon:/small/refresh"] } { btnShowSystem ToolButton - MoveScaled(8,0,4,4) + MoveScaled(12,0,4,4) ToolTip = ("Show system tables") Action = ".show-system" Picture = Picture["img/16/system-table.png"] Toggle = True } { btnNewTable ToolButton - MoveScaled(12,0,4,4) + MoveScaled(16,0,4,4) ToolTip = ("New table") Picture = Picture["icon:/small/new"] } { btnKill ToolButton - MoveScaled(16,0,7,4) + MoveScaled(21,0,7,4) ToolTip = ("Delete table") AutoResize = True Text = ("Remove") Picture = Picture["icon:/small/delete"] } { btnRename ToolButton - MoveScaled(24,0,9,4) + MoveScaled(30,0,9,4) ToolTip = ("Rename table") AutoResize = True Text = ("Rename") & "..." Picture = Picture["icon:/small/edit"] } { btnCopyTable ToolButton - MoveScaled(33,0,4,4) + MoveScaled(41,0,4,4) ToolTip = ("Copy table") AutoResize = True Text = ("Copy") Picture = Picture["icon:/small/copy"] } { btnPasteTable ToolButton - MoveScaled(37,0,4,4) + MoveScaled(46,0,4,4) ToolTip = ("Paste table") AutoResize = True Text = ("Paste") & "..." Picture = Picture["icon:/small/paste"] } { btnImport ToolButton - MoveScaled(44,0,12,4) + MoveScaled(52,0,12,4) ToolTip = ("Import text file") AutoResize = True Text = ("Import") & "..." Picture = Picture["icon:/small/open"] } { btnRequest ToolButton - MoveScaled(56,0,16,4) + MoveScaled(64,0,16,4) ToolTip = ("SQL queries") AutoResize = True Text = ("SQL queries") @@ -234,7 +226,7 @@ Index = 0 } { panRequest VBox - MoveScaled(4,5,61,24) + MoveScaled(2,10,61,24) Visible = False Background = Color.Background { tlbData2 ToolBar @@ -262,7 +254,7 @@ } { btnClear ToolButton MoveScaled(32,0,4,4) - ToolTip = ("Cut") + ToolTip = ("Clear") Picture = Picture["icon:/small/clear"] } { btnCut ToolButton mnuCut @@ -297,8 +289,7 @@ } } { tabRequest TabPanel - MoveScaled(3,5,33,16) - Expand = True + MoveScaled(3,5,33,7) Border = False Index = 0 Text = ("") @@ -306,7 +297,7 @@ } { edtRequest TextEditor MoveScaled(18,15,40,7) - Ignore = True + Expand = True Border = False Highlight = "SQL" } @@ -397,6 +388,10 @@ # Gambas Action File 3.0 { Actions + { Action database + Text = "" + Picture = "img/16/database.png" + } { Action reload Text = "Reload" Picture = "icon:/small/refresh" @@ -414,7 +409,7 @@ { Toolbars { Toolbar connection Text = "Connection editor" - List = "save,reload,show-system" - Default = "save,reload,show-system,$btnNewTable,$btnKill,$btnRename,$btnCopyTable,$btnPasteTable,$btnImport,$btnRequest" + List = "database,save,reload,show-system" + Default = "database,save,reload,show-system,$btnNewTable,$btnKill,$btnRename,$btnCopyTable,$btnPasteTable,$btnImport,$btnRequest" } } diff -Nru gambas3-3.8.3/app/src/gambas3/.src/Editor/Form/CControl.class gambas3-3.8.4/app/src/gambas3/.src/Editor/Form/CControl.class --- gambas3-3.8.3/app/src/gambas3/.src/Editor/Form/CControl.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.src/Editor/Form/CControl.class 2015-12-22 04:46:12.000000000 +0000 @@ -67,10 +67,6 @@ Dim hPict As Picture Dim hImage As Image Dim sPath As String - Dim sText As String - Dim X, Y As Float - Dim iInd As Integer - Dim I As Integer Dim hClass As CClassInfo Dim W As Integer Dim F As Integer @@ -352,18 +348,16 @@ Private Sub InitControl() - Dim hProp As CPropertyInfo - $cValue["#X"] = 0 $cValue["#Y"] = 0 $cValue["#Width"] = 0 $cValue["#Height"] = 0 - If DrawWith Then - For Each hProp In Project.Documentation.Classes[Kind].Properties - If Not hProp.Coord Then SetProperty(hProp.Name, hProp.DefaultValue) - Next - Endif + ' If DrawWith Then + ' For Each hProp In Project.Documentation.Classes[Kind].Properties + ' If Not hProp.Coord Then SetProperty(hProp.Name, hProp.DefaultValue) + ' Next + ' Endif End @@ -497,7 +491,7 @@ If TypeOf(vRealVal) = gb.String Then If Not IsNull(Val(vRealVal)) Then - vRealVal = Val(vRealVal) + vRealVal = CInt(Val(vRealVal)) Else vRealVal = FColorChooser.FromString(vRealVal) 'Object.GetProperty(Color, vRealVal) Endif @@ -564,7 +558,7 @@ ' valeur par défaut ? - 'IF sProp = "Background" THEN STOP + 'If sProp = "Background" Then Stop If Not hProp.Required Then If Not IsNull(vDefault) Then @@ -737,6 +731,8 @@ Private Function ConvertToString(vVal As Variant, hProp As CPropertyInfo) As String + Dim sVal As String + Select Case hProp.Type Case "b" @@ -763,8 +759,10 @@ Case "Color" vVal = CStr(vVal) - If Not IsNull(Val(vVal)) Then - Return "&H" & Hex$(vVal, 6) & "&" + If IsLong(vVal) Then + sVal = Hex$(vVal, 8) + If sVal Begins "00" Then sVal = Mid$(sVal, 3) + Return "&H" & sVal & "&" Else Return vVal Endif @@ -891,7 +889,7 @@ ' Control and group names can be void If Not sName Then Return - If Not IsLetter(Left(sName)) Then Return True + If Not IsLetter(Left(sName)) And Left(sName) <> "_" Then Return True For iInd = 2 To Len(sName) If InStr("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_", UCase(Mid$(sName, iInd, 1))) = 0 Then diff -Nru gambas3-3.8.3/app/src/gambas3/.src/Editor/Form/FForm.class gambas3-3.8.4/app/src/gambas3/.src/Editor/Form/FForm.class --- gambas3-3.8.3/app/src/gambas3/.src/Editor/Form/FForm.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.src/Editor/Form/FForm.class 2015-12-22 04:46:12.000000000 +0000 @@ -415,12 +415,12 @@ Else - Try vValue = CFloat(sValue) - If Not Error Then Goto SET_PROPERTY - Try vValue = CInt(Val(sValue)) If Not Error Then Goto SET_PROPERTY + Try vValue = CFloat(sValue) + If Not Error Then Goto SET_PROPERTY + For Each sProp In CControl.COMPLEX_STRING_PROPERTIES If sValue Begins sProp Then diff -Nru gambas3-3.8.3/app/src/gambas3/.src/Editor/Form/FProperty.class gambas3-3.8.4/app/src/gambas3/.src/Editor/Form/FProperty.class --- gambas3-3.8.3/app/src/gambas3/.src/Editor/Form/FProperty.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.src/Editor/Form/FProperty.class 2015-12-22 04:46:12.000000000 +0000 @@ -795,7 +795,7 @@ Case "ReportCoord" hEditor = crdProperty - + Case "Angle" hEditor = txtAngle diff -Nru gambas3-3.8.3/app/src/gambas3/.src/Editor/Image/CImageSelection.class gambas3-3.8.4/app/src/gambas3/.src/Editor/Image/CImageSelection.class --- gambas3-3.8.3/app/src/gambas3/.src/Editor/Image/CImageSelection.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.src/Editor/Image/CImageSelection.class 2015-12-22 04:46:12.000000000 +0000 @@ -381,14 +381,14 @@ ' End -Public Sub Rectangle(X As Integer, Y As Integer, W As Integer, H As Integer, Optional R As Integer) +Public Sub Rectangle(X As Float, Y As Float, W As Float, H As Float, Optional R As Integer) Dim A As Integer Dim XC, YC As Float If W = 0 Or If H = 0 Then Return - R = Min(R, Min(W, H) \ 2) + R = Min(R, CInt(Min(W, H) / 2)) If R <= 0 Then @@ -508,7 +508,7 @@ End -Public Sub Ellipse(X As Integer, Y As Integer, W As Integer, H As Integer) +Public Sub Ellipse(X As Float, Y As Float, W As Float, H As Float) Dim A As Integer Dim XC, YC, WC, HC As Float @@ -650,14 +650,20 @@ Dim hRect As RectF Dim I As Integer + Dim hRectShape As RectF If Shapes.Count = 0 Then Return New RectF If Current >= 0 And If Not bAll Then Return Shapes[Current].GetExtents() - hRect = Shapes[0].GetExtents() - For I = 1 To Shapes.Max - hRect = hRect.Union(Shapes[I].GetExtents()) + For I = 0 To Shapes.Max + hRectShape = Shapes[I].GetExtents() + If Not hRectShape Then Continue + If Not hRect Then + hRect = hRectShape + Else + hRect = hRect.Union(hRectShape) + Endif Next Return hRect @@ -668,6 +674,7 @@ Dim hExt As RectF = GetExtents(bAll) + If Not hExt Then Return Return Rect(Floor(hExt.X), Floor(hExt.Y), Ceil(hExt.Right) - Floor(hExt.X), Ceil(hExt.Bottom) - Floor(hExt.Y)) End @@ -718,6 +725,8 @@ Dim hMatrix As New PaintMatrix Dim hExt As RectF = GetExtents() + If Not hExt Then Return + hMatrix.Translate(hExt.X + hExt.W / 2, hExt.Y + hExt.H / 2) hMatrix.Scale(-1, 1) hMatrix.Translate(- (hExt.X + hExt.W / 2), - (hExt.Y + hExt.H / 2)) @@ -730,6 +739,8 @@ Dim hMatrix As New PaintMatrix Dim hExt As RectF = GetExtents() + If Not hExt Then Return + hMatrix.Translate(hExt.X + hExt.W / 2, hExt.Y + hExt.H / 2) hMatrix.Scale(1, -1) hMatrix.Translate(- (hExt.X + hExt.W / 2), - (hExt.Y + hExt.H / 2)) @@ -742,6 +753,8 @@ Dim hMatrix As New PaintMatrix Dim hExt As RectF = GetExtents() + If Not hExt Then Return + hMatrix.Translate(hExt.X + hExt.W / 2, hExt.Y + hExt.H / 2) hMatrix.Rotate(fAngle) hMatrix.Translate(- (hExt.X + hExt.W / 2), - (hExt.Y + hExt.H / 2)) @@ -754,6 +767,8 @@ Dim hMatrix As New PaintMatrix Dim hExt As RectF = GetExtents() + If Not hExt Then Return + If bTopLeft Then hMatrix.Translate(hExt.X, hExt.Y) Else @@ -907,8 +922,11 @@ Dim hShape As CImageShape Dim DX, DY As Float Dim hMatrix As New PaintMatrix + Dim hExt As RectF = GetExtents() + + If Not hExt Then Return - With GetExtents() + With hExt DX = .W / 2 DY = .H / 2 End With diff -Nru gambas3-3.8.3/app/src/gambas3/.src/Editor/Image/FImageEditor.class gambas3-3.8.4/app/src/gambas3/.src/Editor/Image/FImageEditor.class --- gambas3-3.8.3/app/src/gambas3/.src/Editor/Image/FImageEditor.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.src/Editor/Image/FImageEditor.class 2015-12-22 04:46:12.000000000 +0000 @@ -1094,10 +1094,10 @@ If Y1 > Y2 Then Swap Y1, Y2 If X2 - X1 >= 0.25 And If Y2 - Y1 >= 0.25 Then - X1 = Floor(X1) - X2 = Ceil(X2) - Y1 = Floor(Y1) - Y2 = Ceil(Y2) + 'X1 = Floor(X1) + 'X2 = Ceil(X2) + 'Y1 = Floor(Y1) + 'Y2 = Ceil(Y2) WW = X2 - X1 HH = Y2 - Y1 Else @@ -1108,11 +1108,11 @@ If $sTool = "ellipse" Then If $bShift Then - WW *= Sqr(2) - HH *= Sqr(2) - $hSelect.Ellipse(CInt($hLastPoint.X) - WW, CInt($hLastPoint.Y) - HH, WW * 2, HH * 2) + 'WW *= 2 'Sqr(2) + 'HH *= 2 'Sqr(2) + $hSelect.Ellipse($hLastPoint.X - WW, $hLastPoint.Y - HH, WW * 2, HH * 2) Else - $hSelect.Ellipse(CInt(Min($hLastPoint.X, $hCurrentPoint.X)), CInt(Min($hLastPoint.Y, $hCurrentPoint.Y)), WW, HH) + $hSelect.Ellipse(Min($hLastPoint.X, $hCurrentPoint.X), Min($hLastPoint.Y, $hCurrentPoint.Y), WW, HH) Endif Else diff -Nru gambas3-3.8.3/app/src/gambas3/.src/Family/CFamily.class gambas3-3.8.4/app/src/gambas3/.src/Family/CFamily.class --- gambas3-3.8.3/app/src/gambas3/.src/Family/CFamily.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.src/Family/CFamily.class 2015-12-22 04:46:12.000000000 +0000 @@ -14,6 +14,8 @@ Public ActionValue As Variant +Static Private $hBroken As SvgImage + Private $hTimer As Timer Private $hCurrentIcon As Control Private $bTrigger As Boolean @@ -444,3 +446,17 @@ End +Static Public Sub PaintBroken() + + Dim W As Integer + + If Not $hBroken Then $hBroken = SvgImage.Load("img/broken.svg") + W = Min(Paint.W, Paint.H) + $hBroken.Resize(W, W) + Paint.MoveTo((Paint.W - W) / 2, (Paint.H - W) / 2) + $hBroken.Paint + Paint.Background = Color.SetAlpha(Color.Red, 128) + Paint.Rectangle(0.5, 0.5, Paint.W - 1, Paint.H - 1) + Paint.Stroke + +End diff -Nru gambas3-3.8.3/app/src/gambas3/.src/Family/CFamilyReport.class gambas3-3.8.4/app/src/gambas3/.src/Family/CFamilyReport.class --- gambas3-3.8.3/app/src/gambas3/.src/Family/CFamilyReport.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.src/Family/CFamilyReport.class 2015-12-22 04:46:12.000000000 +0000 @@ -246,6 +246,7 @@ Dim X, Y, W, H, W2, H2 As Float Dim fVal As Float Dim sPath As String + Dim hImage As Image Dim hSvgImage As SvgImage Dim hRect As Rect @@ -379,34 +380,49 @@ sPath = hCtrl["Image"] If Not sPath Then Return True + If hCtrl["#Image"] <> sPath Then hCtrl["#Image"] = sPath + hCtrl["#ImageObject"] = Null Try hCtrl["#ImageObject"] = Image.Load(Project.Dir &/ sPath) - If Error Then - FMain.ShowMessage(Error.Text, "warning") - Endif Endif - hRect = New Rect(X, Y, W, H) - StretchImage(hRect, hCtrl["Stretch"], Classes["Align"][hCtrl["Alignment"]].Value, hCtrl["#ImageObject"].W, hCtrl["#ImageObject"].H) - Try Draw.Image(hCtrl["#ImageObject"], hRect.X, hRect.Y, hRect.W, hRect.H) + hImage = hCtrl["#ImageObject"] + If hImage Then + hRect = New Rect(X, Y, W, H) + StretchImage(hRect, hCtrl["Stretch"], Classes["Align"][hCtrl["Alignment"]].Value, hImage.W, hImage.H) + Paint.DrawImage(hImage, hRect.X, hRect.Y, hRect.W, hRect.H) + Else + CFamily.PaintBroken + Endif Case "ReportSvgImage" sPath = hCtrl["Image"] If Not sPath Then Return True + If hCtrl["#Image"] <> sPath Then hCtrl["#Image"] = sPath - hCtrl["#ImageObject"] = SvgImage.Load(Project.Dir &/ sPath) - hCtrl["#ImageW"] = hCtrl["#ImageObject"].Width - hCtrl["#ImageH"] = hCtrl["#ImageObject"].Height + hCtrl["#ImageObject"] = Null + Try hSvgImage = SvgImage.Load(Project.Dir &/ sPath) + If Not Error Then + hCtrl["#ImageObject"] = hSvgImage + hCtrl["#ImageW"] = hSvgImage.Width + hCtrl["#ImageH"] = hSvgImage.Height + Endif Endif + hSvgImage = hCtrl["#ImageObject"] - hRect = New Rect(X, Y, W, H) - StretchImage(hRect, hCtrl["Stretch"], Classes["Align"][hCtrl["Alignment"]].Value, hCtrl["#ImageW"], hCtrl["#ImageH"]) - hSvgImage.Resize(hRect.W, hRect.H) - Paint.MoveTo(hRect.X, hRect.Y) - hSvgImage.Paint + + If hSvgImage Then + hRect = New Rect(X, Y, W, H) + StretchImage(hRect, hCtrl["Stretch"], Classes["Align"][hCtrl["Alignment"]].Value, hCtrl["#ImageW"], hCtrl["#ImageH"]) + hSvgImage.Resize(hRect.W, hRect.H) + Paint.MoveTo(hRect.X, hRect.Y) + hSvgImage.Paint + Else + CFamily.PaintBroken + Endif Case Else diff -Nru gambas3-3.8.3/app/src/gambas3/.src/Family/CFamilyWebForm.class gambas3-3.8.4/app/src/gambas3/.src/Family/CFamilyWebForm.class --- gambas3-3.8.3/app/src/gambas3/.src/Family/CFamilyWebForm.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.src/Family/CFamilyWebForm.class 2015-12-22 04:46:12.000000000 +0000 @@ -42,9 +42,7 @@ Public Sub DrawControl(hCCtrl As CControl) As Boolean - Dim iBorder As Integer Dim hCtrl As Control = hCCtrl.Control - Dim hParent As CControl 'Debug hCCtrl.Name @@ -68,7 +66,7 @@ End -Public Sub ActionDialog(sAction As String) As Boolean +Public Sub ActionDialog((sAction) As String) As Boolean ' Dim vColor As Variant ' @@ -87,7 +85,7 @@ End -Public Sub ActionExec(hCtrl As CControl, sAction As String) +Public Sub ActionExec((hCtrl) As CControl, (sAction) As String) ' Select Case sAction ' diff -Nru gambas3-3.8.3/app/src/gambas3/.src/Packager/Package.module gambas3-3.8.4/app/src/gambas3/.src/Packager/Package.module --- gambas3-3.8.3/app/src/gambas3/.src/Packager/Package.module 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.src/Packager/Package.module 2015-12-22 04:46:12.000000000 +0000 @@ -26,7 +26,7 @@ Private $sDescription As String Private $sSavePath As String -Private $bSupportPackage As Boolean +Private $sSupportPackage As String Private MIN_VERSION As String Private Const MAX_VERSION As String = "3.99.0" @@ -38,15 +38,16 @@ Private $sFormatEqual As String Private Const QT4_SUPPORT As String = "qt4" -Private QT4_SUPPORT_PACKAGES As String[] = ["gb.qt4:gb.gui", "gb.qt4.opengl:gb.gui.opengl"] +Private QT4_SUPPORT_PACKAGES As String[] = ["gb.qt4:gb.gui", "gb.qt4:gb.gui.qt", "gb.qt4.opengl:gb.gui.opengl", "gb.qt4.webkit:gb.gui.qt.webkit"] Private Const QT5_SUPPORT As String = "qt5" -Private QT5_SUPPORT_PACKAGES As String[] = ["gb.qt5:gb.gui", "gb.qt5.opengl:gb.gui.opengl"] +Private QT5_SUPPORT_PACKAGES As String[] = ["gb.qt5:gb.gui", "gb.qt5:gb.gui.qt", "gb.qt5.opengl:gb.gui.opengl", "gb.qt5.webkit:gb.gui.qt.webkit"] Private Const GTK_SUPPORT As String = "gtk" Private GTK_SUPPORT_PACKAGES As String[] = ["gb.gtk:gb.gui", "gb.gtk.opengl:gb.gui.opengl"] Private Const GTK3_SUPPORT As String = "gtk3" Private GTK3_SUPPORT_PACKAGES As String[] = ["gb.gtk3:gb.gui"] ', "gb.gtk.opengl:gb.gui.opengl"] Private Const DEBIAN_STANDARD As String = "3.9.6" +Private Const DEBIAN_DEBHELPER_VERSION As String = "9" Public Sub CheckProgram() @@ -227,7 +228,13 @@ $sDescription = "Missing description" Endif - $bSupportPackage = Project.Components.Exist("gb.gui") + With Project.Components + If .Exist("gb.gui") Then + $sSupportPackage = "gb.gui" + Else If .Exist("gb.gui.qt") Then + $sSupportPackage = "gb.gui.qt" + Endif + End With End @@ -625,16 +632,20 @@ Dim sSupport As String Dim aPackage As String[] - sSupport = GTK_SUPPORT - aPackage = GTK_SUPPORT_PACKAGES - AddLog("\n============ " & Subst(("Making &1 support package..."), "GTK+")) - GoSub MAKE_PACKAGE - - If Not Project.Components.Exist("gb.gui.opengl") Then - sSupport = GTK3_SUPPORT - aPackage = GTK3_SUPPORT_PACKAGES - AddLog("\n============ " & Subst(("Making &1 support package..."), "GTK+3")) + If $sSupportPackage = "gb.gui" Then + + sSupport = GTK_SUPPORT + aPackage = GTK_SUPPORT_PACKAGES + AddLog("\n============ " & Subst(("Making &1 support package..."), "GTK+")) GoSub MAKE_PACKAGE + + If Not Project.Components.Exist("gb.gui.opengl") Then + sSupport = GTK3_SUPPORT + aPackage = GTK3_SUPPORT_PACKAGES + AddLog("\n============ " & Subst(("Making &1 support package..."), "GTK+3")) + GoSub MAKE_PACKAGE + Endif + Endif sSupport = QT4_SUPPORT @@ -704,7 +715,7 @@ End Select - If $bSupportPackage Then MakeSupportPackage(sSys) + If $sSupportPackage Then MakeSupportPackage(sSys) Catch @@ -826,7 +837,7 @@ 'debian/compat hFile = Open sPackagePath &/ "debian/compat" For Create - Print #hFile, "5" + Print #hFile, DEBIAN_DEBHELPER_VERSION Close #hFile 'debian/menu @@ -885,7 +896,7 @@ Print #hFile, "Section: contrib/"; Project.Groups[sSys] Print #hFile, "Priority: optional" Print #hFile, "Maintainer: "; Project.Maintainer; " <"; Project.Address; ">" - Print #hFile, "Build-Depends: debhelper (>= 5.0.0), gambas"; System.Version; "-dev (>= "; MIN_VERSION; "), gambas"; System.Version; "-dev (<< "; MAX_VERSION; ")"; + Print #hFile, "Build-Depends: debhelper (>= "; DEBIAN_DEBHELPER_VERSION; "), gambas"; System.Version; "-dev (>= "; MIN_VERSION; "), gambas"; System.Version; "-dev (<< "; MAX_VERSION; ")"; ' For Each sLib In GetDependencies() ' aVer = GetComponentMinMaxVersion(sLib) ' sLib = ComponentToPackageName(sLib) @@ -1055,7 +1066,7 @@ 'debian/compat hFile = Open sPackagePath &/ "debian/compat" For Create - Print #hFile, "7" + Print #hFile, DEBIAN_DEBHELPER_VERSION Close #hFile 'debian/control @@ -1064,7 +1075,7 @@ Print #hFile, "Section: contrib/"; Project.Groups[sSys] Print #hFile, "Priority: optional" Print #hFile, "Maintainer: "; Project.Maintainer; " <"; Project.Address; ">" - Print #hFile, "Build-Depends: debhelper (>= 7)" + Print #hFile, "Build-Depends: debhelper (>= "; DEBIAN_DEBHELPER_VERSION; ")" Print #hFile, "Standards-Version: "; DEBIAN_STANDARD Print #hFile Print #hFile, "Package: "; sPackageName diff -Nru gambas3-3.8.3/app/src/gambas3/.src/Project/Farm/CSoftware.class gambas3-3.8.4/app/src/gambas3/.src/Project/Farm/CSoftware.class --- gambas3-3.8.3/app/src/gambas3/.src/Project/Farm/CSoftware.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.src/Project/Farm/CSoftware.class 2015-12-22 04:46:12.000000000 +0000 @@ -101,6 +101,14 @@ End +Public Sub Abort() + + Try $hRequest.Abort + Try $hRequestIcon.Abort + +End + + Public Sub Request_Finished() diff -Nru gambas3-3.8.3/app/src/gambas3/.src/Project/Farm/FarmRequestManager.module gambas3-3.8.4/app/src/gambas3/.src/Project/Farm/FarmRequestManager.module --- gambas3-3.8.3/app/src/gambas3/.src/Project/Farm/FarmRequestManager.module 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.src/Project/Farm/FarmRequestManager.module 2015-12-22 04:46:12.000000000 +0000 @@ -12,7 +12,9 @@ 'hRequest.Debug = True hObs = New Observer(hRequest) As "Request" $aRequest.Add(hRequest) + 'Debug "Add "; hRequest If $aRequest.Count <= MAX_REQUEST Then + 'Debug "Submit "; hRequest hRequest.Submit Endif @@ -22,9 +24,11 @@ Dim iPos As Integer + 'Debug "Remove "; hRequest iPos = $aRequest.FindByRef(hRequest) If iPos >= 0 Then If iPos = 0 Then + 'Debug "Stop "; hRequest hRequest.Stop Else $aRequest.Remove(iPos) @@ -38,12 +42,16 @@ Dim iPos As Integer + 'Debug "Finished "; Last + If $aRequest.Count = 0 Then Return + 'Debug "Remove "; Last iPos = $aRequest.FindByRef(Last) If iPos >= 0 Then $aRequest.Remove(iPos) If $aRequest.Count >= MAX_REQUEST Then + 'Debug "Submit "; $aRequest[MAX_REQUEST - 1] $aRequest[MAX_REQUEST - 1].Submit Endif Endif @@ -71,8 +79,10 @@ aClear = $aRequest.Copy() $aRequest.Clear + 'Debug "Clear" For I = 0 To Min(aClear.Max, MAX_REQUEST) + 'Debug "Stop "; aClear[I] aClear[I].Stop Next diff -Nru gambas3-3.8.3/app/src/gambas3/.src/Project/Farm/FFarmLogin.class gambas3-3.8.4/app/src/gambas3/.src/Project/Farm/FFarmLogin.class --- gambas3-3.8.3/app/src/gambas3/.src/Project/Farm/FFarmLogin.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.src/Project/Farm/FFarmLogin.class 2015-12-22 04:46:12.000000000 +0000 @@ -36,7 +36,6 @@ $hIdentity.Password = txtPassword.Text 'Settings["/Farm"] = cmbFarm.Text - FarmIdentity.RememberPassword = CBool(chkRememberPassword.Value) FarmIdentity.SaveSettings Me.Close(True) @@ -104,3 +103,10 @@ btnOK.Value = True End + +Public Sub chkRememberPassword_Click() + + FarmIdentity.RememberPassword = CBool(chkRememberPassword.Value) + FarmIdentity.SaveSettings + +End diff -Nru gambas3-3.8.3/app/src/gambas3/.src/Project/Farm/FSoftwareFarm.class gambas3-3.8.4/app/src/gambas3/.src/Project/Farm/FSoftwareFarm.class --- gambas3-3.8.3/app/src/gambas3/.src/Project/Farm/FSoftwareFarm.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.src/Project/Farm/FSoftwareFarm.class 2015-12-22 04:46:12.000000000 +0000 @@ -10,6 +10,7 @@ Private $hIdentity As FarmIdentity Private $hTimerArrange As Timer +Private $hObs As Observer Public Sub Run() @@ -369,7 +370,7 @@ imvScreenshot.Image = Null panScreenshot.Hide If .DownloadScreenshot() Then - Software_Screenshot + UpdateScreenshot Else spnScreenshot.Show spnScreenshot.Raise @@ -382,8 +383,8 @@ End -Public Sub Software_Screenshot() - +Private Sub UpdateScreenshot() + spnScreenshot.Hide If $hSoft.Screenshot Then Try imvScreenshot.Image = $hSoft.Screenshot @@ -395,6 +396,13 @@ End +Public Sub Software_Screenshot() + + If $hSoft <> Last Then Return + UpdateScreenshot + +End + Public Sub SoftwareBox_Click() @@ -552,6 +560,7 @@ Public Sub Software_Change() + If $hSoft <> Last Then Return UpdateSoftware End @@ -613,8 +622,6 @@ Public Sub wizFarm_Change() - Dim hObs As Observer - btnGoBack.Enabled = wizFarm.Index > 0 Select Case wizFarm.Index @@ -625,13 +632,17 @@ Case WIZ_FARM - $hSoft = Null + If $hSoft Then + $hSoft.Abort + $hSoft = Null + Endif + imvScreenshot.Image = Null Case WIZ_SOFTWARE If Not $hSoft.Observed Then - hObs = New Observer($hSoft) As "Software" + $hObs = New Observer($hSoft) As "Software" $hSoft.Observed = True Endif diff -Nru gambas3-3.8.3/app/src/gambas3/.src/Project.module gambas3-3.8.4/app/src/gambas3/.src/Project.module --- gambas3-3.8.3/app/src/gambas3/.src/Project.module 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas3/.src/Project.module 2015-12-22 04:46:12.000000000 +0000 @@ -3037,19 +3037,39 @@ aVer = Split(Trim(sVer), ".") - iMajor = aVer[0] - Try iMinor = aVer[1] + If aVer.Count = 0 Then Goto BAD_VERSION + + Try iMajor = aVer[0] + If Error Or If iMajor < 0 Then Goto BAD_VERSION + + If aVer.Count >= 2 Then + Try iMinor = aVer[1] + If Error Or If iMinor < 0 Then Goto BAD_VERSION + Else + iMinor = 0 + Endif + + If aVer.Count >= 3 Then + Try iRelease = aVer[2] + If Error Or If iRelease < 0 Then Goto BAD_VERSION + Else + iRelease = 0 + Endif MajorVersion = iMajor MinorVersion = iMinor - - Try iRelease = aVer[2] - If Not Error Then ReleaseVersion = iRelease + ReleaseVersion = iRelease If bWriteProject Then sVer = FormatVersion() If sVer <> sOldVer Then WriteProject Endif + + Return + +BAD_VERSION: + + FMain.ShowError(Subst(("The contents of VERSION file at &1 is incorrect."), "" & sDir & "")) End @@ -5283,7 +5303,7 @@ aTest = ["seamonkey"] Case "chromium" - aTest = ["chromium-browser"] + aTest = ["chromium", "chromium-browser"] Case Else diff -Nru gambas3-3.8.3/app/src/gambas-wiki/gambas3-ide.project gambas3-3.8.4/app/src/gambas-wiki/gambas3-ide.project --- gambas3-3.8.3/app/src/gambas-wiki/gambas3-ide.project 2015-11-08 16:47:24.000000000 +0000 +++ gambas3-3.8.4/app/src/gambas-wiki/gambas3-ide.project 2015-12-22 04:46:12.000000000 +0000 @@ -3,7 +3,7 @@ Title=Gambas 3 Startup=Project Icon=img/logo/logo-ide.png -Version=3.8.1 +Version=3.8.4 VersionFile=1 Component=gb.image Component=gb.gui.qt diff -Nru gambas3-3.8.3/comp/acinclude.m4 gambas3-3.8.4/comp/acinclude.m4 --- gambas3-3.8.3/comp/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/comp/src/gb.desktop/.settings gambas3-3.8.4/comp/src/gb.desktop/.settings --- gambas3-3.8.3/comp/src/gb.desktop/.settings 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.desktop/.settings 2015-12-22 04:46:12.000000000 +0000 @@ -17,18 +17,15 @@ LastCommit="[GB.DESKTOP]\n* BUG: Change the Mime loading code so it not fail on the first readed glob2 file\n and read all the available files.\n---- Cette ligne et les suivantes seront ignorées ----\n\nM .project\nM .settings\nM .src/DesktopMime.class\nM .src/Tests/Form11.form\nA .src/Tests/Module1.module\nM .startup" [OpenFile] -File[1]=".src/Tests/Form1.form" -Active=10 +File[1]=".src/DesktopMime.class:0.90" +Active=5 File[2]=".src/Tests/Form11.form" -Count=10 -File[3]=".src/Tests/Form11.class:0.0" -File[4]=".src/DesktopWindow.class:0.169" -File[5]=".src/Desktop.class:0.6" -File[6]=".src/Tests/Form2.form" -File[7]=".src/Tests/Module1.module:0.0" -File[8]=".src/Main.module:0.157" -File[9]=".src/_Desktop_Passwords.class:0.0" -File[10]="xdg-utils/xdg-copy:21.203" +Count=7 +File[3]=".src/Main.module:18.10" +File[4]=".src/DesktopFile.class:0.347" +File[5]=".src/Desktop.class:12.83" +File[6]=".src/DesktopWatcher.class:2.33" +File[7]="xdg-utils/xdg-open:0.0" [VersionControl] User="gambix" diff -Nru gambas3-3.8.3/comp/src/gb.desktop/.src/DesktopWatcher.class gambas3-3.8.4/comp/src/gb.desktop/.src/DesktopWatcher.class --- gambas3-3.8.3/comp/src/gb.desktop/.src/DesktopWatcher.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.desktop/.src/DesktopWatcher.class 2015-12-22 04:46:12.000000000 +0000 @@ -31,6 +31,8 @@ Dim hWin As DesktopWindow + 'Debug "DesktopWatcher: Window = ";; Window;; " RootWindow = "; X11.RootWindow;; " Property = ";; X11.GetAtomName({Property}) + If Window = X11.RootWindow Then Select Case {Property} @@ -46,8 +48,7 @@ Case Atom["_NET_DESKTOP_GEOMETRY"] Raise Geometry End Select - 'Print "DesktopWatcher: Window = ";; Window;; " Property = ";; X11.GetAtomName({Property}) - + Else hWin = Desktop.Windows.FromHandle(Window) diff -Nru gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-copy gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-copy --- gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-copy 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-copy 1970-01-01 00:00:00.000000000 +0000 @@ -1,303 +0,0 @@ -#!/bin/sh -#--------------------------------------------- -# xdg-copy -# -# Utility script to copy files specified by URLs, including -# downloading and uploading from/to remote sites. -# -# Refer to the usage() function below for usage. -# -# Copyright 2006, Kevin Krammer -# Copyright 2006, Jeremy White -# -# LICENSE: -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the "Software"), -# to deal in the Software without restriction, including without limitation -# the rights to use, copy, modify, merge, publish, distribute, sublicense, -# and/or sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. -# -#--------------------------------------------- - -manualpage() -{ -cat << _MANUALPAGE -Name - - xdg-copy -- command line tool for copying files between desktop URIs - -Synopsis - - xdg-copy source destination - - xdg-copy { --help | --manual | --version } - -Description - - xdg-copy copies source to destination and provides visual feedback to the - user during the operation. Both source and destination can either be a - file or URL. Supported URL types are file, ftp, http and https. Additional - URL types may be supported depending on the desktop environment. - - xdg-copy is for use inside a desktop session only. It is not recommended - to use xdg-copy as root. - -Options - - --help - Show command synopsis. - - --manual - Show this manualpage. - - --version - Show the xdg-utils version information. - -Exit Codes - - An exit code of 0 indicates success while a non-zero exit code indicates - failure. The following failure codes can be returned: - - 1 - Error in command line syntax. - - 2 - One of the files passed on the command line did not exist. - - 3 - A required tool could not be found. - - 4 - The action failed. - -Examples - - xdg-copy "http://portland.freedesktop.org/png/freedesktop-logo.png" . - - xdg-copy "/tmp/foobar.png" "/home/user/foobar-copy.png" -_MANUALPAGE -} - -usage() -{ -cat << _USAGE - xdg-copy -- command line tool for copying files between desktop URIs - -Synopsis - - xdg-copy source destination - - xdg-copy { --help | --manual | --version } - -_USAGE -} - -#@xdg-utils-common@ - -#---------------------------------------------------------------------------- -# Common utility functions included in all XDG wrapper scripts -#---------------------------------------------------------------------------- - -#------------------------------------------------------------- -# Exit script on successfully completing the desired operation - -exit_success() -{ - if [ $# -gt 0 ]; then - echo "$@" - echo - fi - - exit 0 -} - - -#----------------------------------------- -# Exit script on malformed arguments, not enough arguments -# or missing required option. -# prints usage information - -exit_failure_syntax() -{ - if [ $# -gt 0 ]; then - echo "xdg-copy: $@" >&2 - echo "Try 'xdg-copy --help' for more information." >&2 - else - usage - echo "Use 'man xdg-copy' or 'xdg-copy --manual' for additional info." - fi - - exit 1 -} - -#------------------------------------------------------------- -# Exit script on missing file specified on command line - -exit_failure_file_missing() -{ - if [ $# -gt 0 ]; then - echo "xdg-copy: $@" >&2 - fi - - exit 2 -} - -#------------------------------------------------------------- -# Exit script on failure to locate necessary tool applications - -exit_failure_operation_impossible() -{ - if [ $# -gt 0 ]; then - echo "xdg-copy: $@" >&2 - fi - - exit 3 -} - -#------------------------------------------------------------- -# Exit script on failure returned by a tool application - -exit_failure_operation_failed() -{ - if [ $# -gt 0 ]; then - echo "xdg-copy: $@" >&2 - fi - - exit 4 -} - - -#---------------------------------------- -# Checks for shared commands, e.g. --help - -check_common_commands() -{ - while [ $# -gt 0 ] ; do - parm=$1 - shift - - case $parm in - --help) - usage - echo "Use 'man xdg-copy' or 'xdg-copy --manual' for additional info." - exit_success - ;; - - --manual) - manualpage - exit_success - ;; - - --version) - echo "xdg-copy 1.0beta1" - exit_success - ;; - esac - done -} - -check_common_commands "$@" - -#-------------------------------------- -# Checks for known desktop environments -# set variable DE to the desktop environments name, lowercase - -detectDE() -{ - if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; - elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; - elif xprop -root _DT_SAVE_MODE | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; - fi -} - -#---------------------------------------------------------------------------- - - - -copy_kde() -{ - kfmclient copy "$1" "$2" - - if [ $? -eq 0 ]; then - exit_success - else - exit_failure_operation_failed - fi -} - -copy_gnome() -{ - if gvfs-copy --help 2>/dev/null 1>&2; then - gvfs-copy "$1" "$2" - else - gnomevfs-copy "$1" "$2" - fi - - if [ $? -eq 0 ]; then - exit_success - else - exit_failure_operation_failed - fi -} - -[ x"$1" != x"" ] || exit_failure_syntax - -source= -dest= -while [ $# -gt 0 ] ; do - parm=$1 - shift - - case $parm in - -*) - exit_failure_syntax "unexpected option '$parm'" - ;; - - *) - if [ -n "$dest" ] ; then - exit_failure_syntax "unexpected argument '$parm'" - fi - if [ -n "$source" ] ; then - dest=$parm - else - source=$parm - fi - ;; - esac -done - -if [ -z "${source}" ] ; then - exit_failure_syntax "source argument missing" -fi -if [ -z "${dest}" ] ; then - exit_failure_syntax "destination argument missing" -fi - -detectDE - -case "$DE" in - kde) - copy_kde "$source" "$dest" - ;; - - gnome) - copy_gnome "$source" "$dest" - ;; - - *) - exit_failure_operation_impossible "no method available for copying '$source' to '$dest'" - ;; -esac diff -Nru gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-desktop-icon gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-desktop-icon --- gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-desktop-icon 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-desktop-icon 2015-12-22 04:46:12.000000000 +0000 @@ -36,15 +36,16 @@ usage() { cat << _USAGE -xdg-desktop-icon - command line tool for (un)installing icons to the desktop + xdg-desktop-icon - command line tool for (un)installing icons + to the desktop Synopsis -xdg-desktop-icon install [--novendor] FILE + xdg-desktop-icon install [--novendor] FILE -xdg-desktop-icon uninstall FILE + xdg-desktop-icon uninstall FILE -xdg-desktop-icon { --help | --manual | --version } + xdg-desktop-icon { --help | --manual | --version } _USAGE } @@ -54,136 +55,160 @@ cat << _MANUALPAGE Name -xdg-desktop-icon - command line tool for (un)installing icons to the desktop + xdg-desktop-icon - command line tool for (un)installing icons + to the desktop Synopsis -xdg-desktop-icon install [--novendor] FILE + xdg-desktop-icon install [--novendor] FILE -xdg-desktop-icon uninstall FILE + xdg-desktop-icon uninstall FILE -xdg-desktop-icon { --help | --manual | --version } + xdg-desktop-icon { --help | --manual | --version } Description -The xdg-desktop-icon program can be used to install an application launcher or -other file on the desktop of the current user. - -An application launcher is represented by a *.desktop file. Desktop files are -defined by the freedesktop.org Desktop Entry Specification. The most important -aspects of *.desktop files are summarized below. + The xdg-desktop-icon program can be used to install an + application launcher or other file on the desktop of the + current user. + + An application launcher is represented by a *.desktop file. + Desktop files are defined by the freedesktop.org Desktop Entry + Specification. The most important aspects of *.desktop files + are summarized below. Commands -install - Installs FILE to the desktop of the current user. FILE can be a *.desktop - file or any other type of file. -uninstall - Removes FILE from the desktop of the current user. + install + Installs FILE to the desktop of the current user. FILE + can be a *.desktop file or any other type of file. + + uninstall + Removes FILE from the desktop of the current user. Options ---novendor + --novendor + Normally, xdg-desktop-icon checks to ensure that a + *.desktop file to be installed has a vendor prefix. This + option can be used to disable that check. + + A vendor prefix consists of alpha characters ([a-zA-Z]) + and is terminated with a dash ("-"). Companies and + organizations are encouraged to use a word or phrase, + preferably the organizations name, for which they hold a + trademark as their vendor prefix. The purpose of the + vendor prefix is to prevent name conflicts. - Normally, xdg-desktop-icon checks to ensure that a *.desktop file to be - installed has a vendor prefix. This option can be used to disable that - check. - - A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated - with a dash ("-"). Companies and organizations are encouraged to use a word - or phrase, preferably the organizations name, for which they hold a - trademark as their vendor prefix. The purpose of the vendor prefix is to - prevent name conflicts. - ---help - Show command synopsis. ---manual - Show this manualpage. ---version - Show the xdg-utils version information. + --help + Show command synopsis. -Desktop Files + --manual + Show this manual page. -An application launcher can be added to the desktop by installing a *.desktop -file. A *.desktop file consists of a [Desktop Entry] header followed by several -Key=Value lines. - -A *.desktop file can provide a name and description for an application in -several different languages. This is done by adding a language code as used by -LC_MESSAGES in square brackets behind the Key. This way one can specify -different values for the same Key depending on the currently selected language. - -The following keys are often used: - -Value=1.0 - This is a mandatory field to indicate that the *.desktop file follows the - 1.0 version of the specification. -Type=Application - This is a mandatory field that indicates that the *.desktop file describes - an application launcher. -Name=Application Name - The name of the application. For example Mozilla -GenericName=Generic Name - A generic description of the application. For example Web Browser -Comment=Comment - Optional field to specify a tooltip for the application. For example Visit - websites on the Internet -Icon=Icon File - The icon to use for the application. This can either be an absolute path to - an image file or an icon-name. If an icon-name is provided an image lookup - by name is done in the user's current icon theme. The xdg-icon-resource - command can be used to install image files into icon themes. The advantage - of using an icon-name instead of an absolute path is that with an icon-name - the application icon can be provided in several different sizes as well as - in several differently themed styles. -Exec=Command Line - The command line to start the application. If the application can open - files the %f placeholder should be specified. When a file is dropped on the - application launcher the %f is replaced with the file path of the dropped - file. If multiple files can be specified on the command line the %F - placeholder should be used instead of %f. If the application is able to - open URLs in addition to local files then %u or %U can be used instead of - %f or %F. + --version + Show the xdg-utils version information. -For a complete oveview of the *.desktop file format please visit http:// -www.freedesktop.org/wiki/Standards/desktop-entry-spec +Desktop Files + + An application launcher can be added to the desktop by + installing a *.desktop file. A *.desktop file consists of a + [Desktop Entry] header followed by several Key=Value lines. + + A *.desktop file can provide a name and description for an + application in several different languages. This is done by + adding a language code as used by LC_MESSAGES in square + brackets behind the Key. This way one can specify different + values for the same Key depending on the currently selected + language. + + The following keys are often used: + + Type=Application + This is a mandatory field that indicates that the + *.desktop file describes an application launcher. + + Name=Application Name + The name of the application. For example Mozilla + + GenericName=Generic Name + A generic description of the application. For example + Web Browser + + Comment=Comment + Optional field to specify a tooltip for the application. + For example Visit websites on the Internet + + Icon=Icon File + The icon to use for the application. This can either be + an absolute path to an image file or an icon-name. If an + icon-name is provided an image lookup by name is done in + the user's current icon theme. The xdg-icon-resource + command can be used to install image files into icon + themes. The advantage of using an icon-name instead of + an absolute path is that with an icon-name the + application icon can be provided in several different + sizes as well as in several differently themed styles. + + Exec=Command Line + The command line to start the application. If the + application can open files the %f placeholder should be + specified. When a file is dropped on the application + launcher the %f is replaced with the file path of the + dropped file. If multiple files can be specified on the + command line the %F placeholder should be used instead + of %f. If the application is able to open URLs in + addition to local files then %u or %U can be used + instead of %f or %F. + + For a complete overview of the *.desktop file format please + visit + http://www.freedesktop.org/wiki/Specifications/desktop-entry-sp + ec Environment Variables -xdg-desktop-icon honours the following environment variables: + xdg-desktop-icon honours the following environment variables: -XDG_UTILS_DEBUG_LEVEL - Setting this environment variable to a non-zero numerical value makes - xdg-desktop-icon do more verbose reporting on stderr. Setting a higher - value increases the verbosity. + XDG_UTILS_DEBUG_LEVEL + Setting this environment variable to a non-zero + numerical value makes xdg-desktop-icon do more verbose + reporting on stderr. Setting a higher value increases + the verbosity. Exit Codes -An exit code of 0 indicates success while a non-zero exit code indicates -failure. The following failure codes can be returned: + An exit code of 0 indicates success while a non-zero exit code + indicates failure. The following failure codes can be returned: + + 1 + Error in command line syntax. + + 2 + One of the files passed on the command line did not + exist. -1 - Error in command line syntax. -2 - One of the files passed on the command line did not exist. -3 - A required tool could not be found. -4 - The action failed. -5 - No permission to read one of the files passed on the command line. + 3 + A required tool could not be found. + + 4 + The action failed. + + 5 + No permission to read one of the files passed on the + command line. See Also -xdg-icon-resource(1) + xdg-icon-resource(1) Examples -The company ShinyThings Inc. has developed an application named "WebMirror" and -would like to add a launcher for for on the desktop. The company will use -"shinythings" as its vendor id. In order to add the application to the desktop -there needs to be a .desktop file for the application: - + The company ShinyThings Inc. has developed an application named + "WebMirror" and would like to add a launcher for for on the + desktop. The company will use "shinythings" as its vendor id. + In order to add the application to the desktop there needs to + be a .desktop file for the application: shinythings-webmirror.desktop: [Desktop Entry] @@ -196,15 +221,13 @@ Name=WebMirror Name[nl]=WebSpiegel -Now the xdg-desktop-icon tool can be used to add the webmirror.desktop file to -the desktop: - + Now the xdg-desktop-icon tool can be used to add the + webmirror.desktop file to the desktop: xdg-desktop-icon install ./shinythings-webmirror.desktop -To add a README file to the desktop as well, the following command can be used: - + To add a README file to the desktop as well, the following + command can be used: xdg-desktop-icon install ./shinythings-README - _MANUALPAGE } @@ -222,6 +245,64 @@ echo "$@" >&2 } +# This handles backslashes but not quote marks. +first_word() +{ + read first rest + echo "$first" +} + +#------------------------------------------------------------- +# map a binary to a .desktop file +binary_to_desktop_file() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + binary="`which "$1"`" + binary="`readlink -f "$binary"`" + base="`basename "$binary"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] || continue + [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue + for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do + [ -r "$file" ] || continue + # Check to make sure it's worth the processing. + grep -q "^Exec.*$base" "$file" || continue + # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop"). + grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + if [ x"`readlink -f "$command"`" = x"$binary" ]; then + # Fix any double slashes that got added path composition + echo "$file" | sed -e 's,//*,/,g' + return + fi + done + done +} + +#------------------------------------------------------------- +# map a .desktop file to a binary +## FIXME: handle vendor dir case +desktop_file_to_binary() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + desktop="`basename "$1"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] && [ -d "$dir/applications" ] || continue + file="$dir/applications/$desktop" + [ -r "$file" ] || continue + # Remove any arguments (%F, %f, %U, %u, etc.). + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + readlink -f "$command" + return + done +} + #------------------------------------------------------------- # Exit script on successfully completing the desired operation @@ -330,7 +411,7 @@ [ -n "$file_label" ] || file_label="filename" file=`basename "$1"` case "$file" in - [a-zA-Z]*-*) + [[:alpha:]]*-*) return ;; esac @@ -352,7 +433,7 @@ fi else DIR=`dirname "$1"` - if [ ! -w "$DIR" -o ! -x "$DIR" ]; then + if [ ! -w "$DIR" ] || [ ! -x "$DIR" ]; then exit_failure_file_permission_write "no permission to create file '$1'" fi fi @@ -380,7 +461,7 @@ ;; --version) - echo "xdg-desktop-icon 1.1.0 rc1" + echo "xdg-desktop-icon 1.1.0 rc3" exit_success ;; esac @@ -404,12 +485,86 @@ detectDE() { - if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; - elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; - elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; - elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; - elif [ x"$DESKTOP_SESSION" == x"LXDE" ]; then DE=lxde; - else DE="" + # see https://bugs.freedesktop.org/show_bug.cgi?id=34164 + unset GREP_OPTIONS + + if [ -n "${XDG_CURRENT_DESKTOP}" ]; then + case "${XDG_CURRENT_DESKTOP}" in + # only recently added to menu-spec, pre-spec X- still in use + Cinnamon|X-Cinnamon) + DE=cinnamon; + ;; + ENLIGHTENMENT) + DE=enlightenment; + ;; + # GNOME, GNOME-Classic:GNOME, or GNOME-Flashback:GNOME + GNOME*) + DE=gnome; + ;; + KDE) + DE=kde; + ;; + LXDE) + DE=lxde; + ;; + MATE) + DE=mate; + ;; + XFCE) + DE=xfce + ;; + X-Generic) + DE=generic + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # classic fallbacks + if [ x"$KDE_FULL_SESSION" != x"" ]; then DE=kde; + elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; + elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then DE=mate; + elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; + elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; + elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce + elif echo $DESKTOP | grep -q '^Enlightenment'; then DE=enlightenment; + fi + fi + + if [ x"$DE" = x"" ]; then + # fallback to checking $DESKTOP_SESSION + case "$DESKTOP_SESSION" in + gnome) + DE=gnome; + ;; + LXDE|Lubuntu) + DE=lxde; + ;; + MATE) + DE=mate; + ;; + xfce|xfce4|'Xfce Session') + DE=xfce; + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # fallback to uname output for other platforms + case "$(uname 2>/dev/null)" in + CYGWIN*) + DE=cygwin; + ;; + Darwin) + DE=darwin; + ;; + esac + fi + + if [ x"$DE" = x"gnome" ]; then + # gnome-default-applications-properties is only available in GNOME 2.x + # but not in GNOME 3.x + which gnome-default-applications-properties > /dev/null 2>&1 || DE="gnome3" fi } @@ -420,7 +575,6 @@ kfmclient_fix_exit_code() { - [ x"$KDE_SESSION_VERSION" = x"4" ] && return 0; version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'` major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'` minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'` @@ -519,7 +673,7 @@ umask $save_umask fi # Is the KDE desktop dir != $HOME/Desktop ? - if [ x`readlink -f "$desktop_dir"` != x`readlink -f "$desktop_dir_kde"` ]; then + if [ "x`readlink -f "$desktop_dir"`" != "x`readlink -f "$desktop_dir_kde"`" ]; then # If so, don't create $HOME/Desktop if it doesn't exist [ -w "$desktop_dir" ] || desktop_dir= else diff -Nru gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-desktop-menu gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-desktop-menu --- gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-desktop-menu 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-desktop-menu 2015-12-22 04:46:12.000000000 +0000 @@ -37,254 +37,295 @@ cat << _MANUALPAGE Name -xdg-desktop-menu - command line tool for (un)installing desktop menu items + xdg-desktop-menu - command line tool for (un)installing desktop + menu items Synopsis -xdg-desktop-menu install [--noupdate] [--novendor] [--mode mode] directory-file -(s) desktop-file(s) + xdg-desktop-menu install [--noupdate] [--novendor] [--mode + mode] directory-file(s) desktop-file(s) -xdg-desktop-menu uninstall [--noupdate] [--mode mode] directory-file(s) -desktop-file(s) + xdg-desktop-menu uninstall [--noupdate] [--mode mode] + directory-file(s) desktop-file(s) -xdg-desktop-menu forceupdate [--mode mode] + xdg-desktop-menu forceupdate [--mode mode] -xdg-desktop-menu { --help | --manual | --version } + xdg-desktop-menu { --help | --manual | --version } Description -The xdg-desktop-menu program can be used to install new menu entries to the -desktop's application menu. + The xdg-desktop-menu program can be used to install new menu + entries to the desktop's application menu. -The application menu works according to the XDG Desktop Menu Specification at -http://www.freedesktop.org/Standards/menu-spec + The application menu works according to the XDG Desktop Menu + Specification at + http://www.freedesktop.org/wiki/Specifications/menu-spec Commands -install + install + Install one or more applications in a submenu of the + desktop menu system. + + desktop-file: A desktop file represents a single menu + entry in the menu. Desktop files are defined by the + freedesktop.org Desktop Entry Specification. The most + important aspects of *.desktop files are summarized + below. + + Menu entries can be added to the menu system in two + different ways. They can either be added to a predefined + submenu in the menu system based on one or more category + keywords, or they can be added to a new submenu. + + To add a menu entry to a predefined submenu the desktop + file that represents the menu entry must have a + Categories= entry that lists one or more keywords. The + menu item will be included in an appropriate submenu + based on the included keywords. + + To add menu items to a new submenu the desktop-files + must be preceded by a directory-file that describes the + submenu. If multiple desktop-files are specified, all + entries will be added to the same menu. If entries are + installed to a menu that has been created with a + previous call to xdg-desktop-menu the entries will be + installed in addition to any already existing entries. + + directory-file: The *.directory file indicated by + directory-file represents a submenu. The directory file + provides the name and icon for a submenu. The name of + the directory file is used to identify the submenu. + + If multiple directory files are provided each file will + represent a submenu within the menu that precedes it, + creating a nested menu hierarchy (sub-sub-menus). The + menu entries themselves will be added to the last + submenu. + + Directory files follow the syntax defined by the + freedesktop.org Desktop Entry Specification. + + uninstall + Remove applications or submenus from the desktop menu + system previously installed with xdg-desktop-menu + install. + + A submenu and the associated directory file is only + removed when the submenu no longer contains any menu + entries. - Install one or more applications in a submenu of the desktop menu system. + forceupdate + Force an update of the menu system. - desktop-file: A desktop file represents a single menu entry in the menu. - Desktop files are defined by the freedesktop.org Desktop Entry - Specification. The most important aspects of *.desktop files are summarized - below. + This command is only useful if the last call to + xdg-desktop-menu included the --noupdate option. - Menu entries can be added to the menu system in two different ways. They - can either be added to a predefined submenu in the menu system based on one - or more category keywords, or they can be added to a new submenu. - - To add a menu entry to a predefined submenu the desktop file that - represents the menu entry must have a Categories= entry that lists one or - more keywords. The menu item will be included in an appropriate submenu - based on the included keywords. - - To add menu items to a new submenu the desktop-files must be preceded by a - directory-file that describes the submenu. If multiple desktop-files are - specified, all entries will be added to the same menu. If entries are - installed to a menu that has been created with a previous call to - xdg-desktop-menu the entries will be installed in addition to any already - existing entries. - - directory-file: The *.directory file indicated by directory-file represents - a submenu. The directory file provides the name and icon for a submenu. The - name of the directory file is used to identify the submenu. - - If multiple directory files are provided each file will represent a submenu - within the menu that preceeds it, creating a nested menu hierarchy - (sub-sub-menus). The menu entries themselves will be added to the last - submenu. - - Directory files follow the syntax defined by the freedesktop.org Desktop - Entry Specification. - -uninstall - - Remove applications or submenus from the desktop menu system previously - installed with xdg-desktop-menu install. - - A submenu and the associated directory file is only removed when the - submenu no longer contains any menu entries. - -forceupdate +Options - Force an update of the menu system. + --noupdate + Postpone updating the menu system. If multiple updates + to the menu system are made in sequence this flag can be + used to indicate that additional changes will follow and + that it is not necessary to update the menu system right + away. + + --novendor + Normally, xdg-desktop-menu checks to ensure that any + *.directory and *.desktop files to be installed has a + vendor prefix. This option can be used to disable that + check. + + A vendor prefix consists of alpha characters ([a-zA-Z]) + and is terminated with a dash ("-"). Companies and + organizations are encouraged to use a word or phrase, + preferably the organizations name, for which they hold a + trademark as their vendor prefix. The purpose of the + vendor prefix is to prevent name conflicts. + + --mode mode + mode can be user or system. In user mode the file is + (un)installed for the current user only. In system mode + the file is (un)installed for all users on the system. + Usually only root is allowed to install in system mode. + + The default is to use system mode when called by root + and to use user mode when called by a non-root user. - This command is only useful if the last call to xdg-desktop-menu included - the --noupdate option. + --help + Show command synopsis. -Options + --manual + Show this manual page. ---noupdate - Postpone updating the menu system. If multiple updates to the menu system - are made in sequence this flag can be used to indicate that additional - changes will follow and that it is not necassery to update the menu system - right away. ---novendor - - Normally, xdg-desktop-menu checks to ensure that any *.directory and - *.desktop files to be installed has a vendor prefix. This option can be - used to disable that check. - - A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated - with a dash ("-"). Companies and organizations are encouraged to use a word - or phrase, preferably the organizations name, for which they hold a - trademark as their vendor prefix. The purpose of the vendor prefix is to - prevent name conflicts. - ---mode mode - - mode can be user or system. In user mode the file is (un)installed for the - current user only. In system mode the file is (un)installed for all users - on the system. Usually only root is allowed to install in system mode. - - The default is to use system mode when called by root and to use user mode - when called by a non-root user. - ---help - Show command synopsis. ---manual - Show this manualpage. ---version - Show the xdg-utils version information. + --version + Show the xdg-utils version information. Desktop Files -An application item in the application menu is represented by a *.desktop file. -A *.desktop file consists of a [Desktop Entry] header followed by several Key= -Value lines. - -A *.desktop file can provide a name and description for an application in -several different languages. This is done by adding a language code as used by -LC_MESSAGES in square brackets behind the Key. This way one can specify -different values for the same Key depending on the currently selected language. - -The following keys are often used: - -Value=1.0 - This is a mandatory field to indicate that the *.desktop file follows the - 1.0 version of the specification. -Type=Application - This is a mandatory field that indicates that the *.desktop file describes - an application launcher. -Name=Application Name - The name of the application. For example Mozilla -GenericName=Generic Name - A generic description of the application. For example Web Browser -Comment=Comment - Optional field to specify a tooltip for the application. For example Visit - websites on the Internet -Icon=Icon File - The icon to use for the application. This can either be an absolute path to - an image file or an icon-name. If an icon-name is provided an image lookup - by name is done in the user's current icon theme. The xdg-icon-resource - command can be used to install image files into icon themes. The advantage - of using an icon-name instead of an absolute path is that with an icon-name - the application icon can be provided in several different sizes as well as - in several differently themed styles. -Exec=Command Line - The command line to start the application. If the application can open - files the %f placeholder should be specified. When a file is dropped on the - application launcher the %f is replaced with the file path of the dropped - file. If multiple files can be specified on the command line the %F - placeholder should be used instead of %f. If the application is able to - open URLs in addition to local files then %u or %U can be used instead of - %f or %F. -Categories=Categories - - A list of categories separated by semi-colons. A category is a keyword that - describes and classifies the application. By default applications are - organized in the application menu based on category. When menu entries are - explicitly assigned to a new submenu it is not necassery to list any - categories. - - When using categories it is recommended to include one of the following - categories: AudioVideo, Development, Education, Game, Graphics, Network, - Office, Settings, System, Utility. - - See Appendix A of the XDG Desktop Menu Specification for information about - additional categories. http://standards.freedesktop.org/menu-spec/ - menu-spec-1.0.html - -MimeType=Mimetypes - A list of mimetypes separated by semi-colons. This field is used to - indicate which file types the application is able to open. - -For a complete oveview of the *.desktop file format please visit http:// -www.freedesktop.org/wiki/Standards/desktop-entry-spec + An application item in the application menu is represented by a + *.desktop file. A *.desktop file consists of a [Desktop Entry] + header followed by several Key=Value lines. + + A *.desktop file can provide a name and description for an + application in several different languages. This is done by + adding a language code as used by LC_MESSAGES in square + brackets behind the Key. This way one can specify different + values for the same Key depending on the currently selected + language. + + The following keys are often used: + + Type=Application + This is a mandatory field that indicates that the + *.desktop file describes an application launcher. + + Name=Application Name + The name of the application. For example Mozilla + + GenericName=Generic Name + A generic description of the application. For example + Web Browser + + Comment=Comment + Optional field to specify a tooltip for the application. + For example Visit websites on the Internet + + Icon=Icon File + The icon to use for the application. This can either be + an absolute path to an image file or an icon-name. If an + icon-name is provided an image lookup by name is done in + the user's current icon theme. The xdg-icon-resource + command can be used to install image files into icon + themes. The advantage of using an icon-name instead of + an absolute path is that with an icon-name the + application icon can be provided in several different + sizes as well as in several differently themed styles. + + Exec=Command Line + The command line to start the application. If the + application can open files the %f placeholder should be + specified. When a file is dropped on the application + launcher the %f is replaced with the file path of the + dropped file. If multiple files can be specified on the + command line the %F placeholder should be used instead + of %f. If the application is able to open URLs in + addition to local files then %u or %U can be used + instead of %f or %F. + + Categories=Categories + A list of categories separated by semi-colons. A + category is a keyword that describes and classifies the + application. By default applications are organized in + the application menu based on category. When menu + entries are explicitly assigned to a new submenu it is + not necessary to list any categories. + + When using categories it is recommended to include one + of the following categories: AudioVideo, Development, + Education, Game, Graphics, Network, Office, Settings, + System, Utility. + + See Appendix A of the XDG Desktop Menu Specification for + information about additional categories: + http://standards.freedesktop.org/menu-spec/menu-spec-1.0 + .html#category-registry + + MimeType=Mimetypes + A list of mimetypes separated by semi-colons. This field + is used to indicate which file types the application is + able to open. + + For a complete overview of the *.desktop file format please + visit + http://www.freedesktop.org/wiki/Specifications/desktop-entry-sp + ec Directory Files -The appearance of submenu in the application menu is provided by a *.directory -file. In particular it provides the title of the submenu and a possible icon. A -*.directory file consists of a [Desktop Entry] header followed by several Key= -Value lines. - -A *.directory file can provide a title (name) for the submenu in several -different languages. This is done by adding a language code as used by -LC_MESSAGES in square brackets behind the Key. This way one can specify -different values for the same Key depending on the currently selected language. - -The following keys are relevqnt for submenus: - -Value=1.0 - This is a mandatory field to indicate that the *.directory file follows the - 1.0 version of the Desktop Entry specification. -Type=Directory - This is a mandatory field that indicates that the *.directory file - describes a submenu. -Name=Menu Name - The title of submenu. For example Mozilla -Comment=Comment - Optional field to specify a tooltip for the submenu. -Icon=Icon File - The icon to use for the submenu. This can either be an absolute path to an - image file or an icon-name. If an icon-name is provided an image lookup by - name is done in the user's current icon theme. The xdg-icon-resource - command can be used to install image files into icon themes. The advantage - of using an icon-name instead of an absolute path is that with an icon-name - the submenu icon can be provided in several different sizes as well as in - several differently themed styles. + The appearance of submenu in the application menu is provided + by a *.directory file. In particular it provides the title of + the submenu and a possible icon. A *.directory file consists of + a [Desktop Entry] header followed by several Key=Value lines. + + A *.directory file can provide a title (name) for the submenu + in several different languages. This is done by adding a + language code as used by LC_MESSAGES in square brackets behind + the Key. This way one can specify different values for the same + Key depending on the currently selected language. + + The following keys are relevant for submenus: + + Type=Directory + This is a mandatory field that indicates that the + *.directory file describes a submenu. + + Name=Menu Name + The title of submenu. For example Mozilla + + Comment=Comment + Optional field to specify a tooltip for the submenu. + + Icon=Icon File + The icon to use for the submenu. This can either be an + absolute path to an image file or an icon-name. If an + icon-name is provided an image lookup by name is done in + the user's current icon theme. The xdg-icon-resource + command can be used to install image files into icon + themes. The advantage of using an icon-name instead of + an absolute path is that with an icon-name the submenu + icon can be provided in several different sizes as well + as in several differently themed styles. Environment Variables -xdg-desktop-menu honours the following environment variables: + xdg-desktop-menu honours the following environment variables: -XDG_UTILS_DEBUG_LEVEL - Setting this environment variable to a non-zero numerical value makes - xdg-desktop-menu do more verbose reporting on stderr. Setting a higher - value increases the verbosity. -XDG_UTILS_INSTALL_MODE - This environment variable can be used by the user or administrator to - override the installation mode. Valid values are user and system. + XDG_UTILS_DEBUG_LEVEL + Setting this environment variable to a non-zero + numerical value makes xdg-desktop-menu do more verbose + reporting on stderr. Setting a higher value increases + the verbosity. + + XDG_UTILS_INSTALL_MODE + This environment variable can be used by the user or + administrator to override the installation mode. Valid + values are user and system. Exit Codes -An exit code of 0 indicates success while a non-zero exit code indicates -failure. The following failure codes can be returned: + An exit code of 0 indicates success while a non-zero exit code + indicates failure. The following failure codes can be returned: + + 1 + Error in command line syntax. + + 2 + One of the files passed on the command line did not + exist. + + 3 + A required tool could not be found. + + 4 + The action failed. -1 - Error in command line syntax. -2 - One of the files passed on the command line did not exist. -3 - A required tool could not be found. -4 - The action failed. -5 - No permission to read one of the files passed on the command line. + 5 + No permission to read one of the files passed on the + command line. See Also -xdg-desktop-icon(1), xdg-icon-resource(1), xdg-mime(1) + xdg-desktop-icon(1), xdg-icon-resource(1), xdg-mime(1), Desktop + entry specification, Desktop menu specification Examples -The company ShinyThings Inc. has developed an application named "WebMirror" and -would like to add it to the application menu. The company will use -"shinythings" as its vendor id. In order to add the application to the menu -there needs to be a .desktop file with a suitable Categories entry: - + The company ShinyThings Inc. has developed an application named + "WebMirror" and would like to add it to the application menu. + The company will use "shinythings" as its vendor id. In order + to add the application to the menu there needs to be a .desktop + file with a suitable Categories entry: shinythings-webmirror.desktop: [Desktop Entry] @@ -299,22 +340,23 @@ Categories=Network;WebDevelopment; -Now the xdg-desktop-menu tool can be used to add the -shinythings-webmirror.desktop file to the desktop application menu: - + Now the xdg-desktop-menu tool can be used to add the + shinythings-webmirror.desktop file to the desktop application + menu: xdg-desktop-menu install ./shinythings-webmirror.desktop -Note that for the purpose of this example the menu items are available in two -languages, English and Dutch. The language code for Dutch is nl. - -In the next example the company ShinyThings Inc. will add its own submenu to -the desktop application menu consisting of a "WebMirror" menu item and a -"WebMirror Admin Tool" menu item. - -First the company needs to create two .desktop files that describe the two menu -items. Since the items are to be added to a new submenu it is not necassery to -include a Categories= line: - + Note that for the purpose of this example the menu items are + available in two languages, English and Dutch. The language + code for Dutch is nl. + + In the next example the company ShinyThings Inc. will add its + own submenu to the desktop application menu consisting of a + "WebMirror" menu item and a "WebMirror Admin Tool" menu item. + + First the company needs to create two .desktop files that + describe the two menu items. Since the items are to be added to + a new submenu it is not necessary to include a Categories= + line: shinythings-webmirror.desktop: [Desktop Entry] @@ -340,9 +382,8 @@ Name=WebMirror Admin Tool Name[nl]=WebSpiegel Administratie Tool -In addition a .directory file needs to be created to provide a title and icon -for the sub-menu itself: - + In addition a .directory file needs to be created to provide a + title and icon for the sub-menu itself: shinythings-webmirror.directory: [Desktop Entry] @@ -353,53 +394,58 @@ Name=WebMirror Name[nl]=WebSpiegel -These file can now be installed with: - + These file can now be installed with: xdg-desktop-menu install ./shinythings-webmirror.directory \ - ./shinythings-webmirror.desktop ./shinythings-webmirror-admin.desktop - -The menu entries could also be installed one by one: + ./shinythings-webmirror.desktop ./shinythings-webmirror-admin.desk +top + The menu entries could also be installed one by one: xdg-desktop-menu install --noupdate ./shinythings-webmirror.directory \ ./shinythings-webmirror.desktop xdg-desktop-menu install --noupdate ./shinythings-webmirror.directory \ ./shinythings-webmirror-admin.desktop xdg-desktop-menu forceupdate -Although the result is the same it is slightly more efficient to install all -files at the same time. - -The *.desktop and *.directory files reference icons with the names webmirror, -webmirror-admin and webmirror-menu which should also be installed. In this -example the icons are installed in two different sizes, once with a size of -22x22 pixels and once with a size of 64x64 pixels: - -xdg-icon-resource install --size 22 ./wmicon-22.png shinythings-webmirror -xdg-icon-resource install --size 22 ./wmicon-menu-22.png shinythings-webmirror-menu -xdg-icon-resource install --size 22 ./wmicon-admin-22.png shinythings-webmirror-admin -xdg-icon-resource install --size 64 ./wmicon-64.png shinythings-webmirror -xdg-icon-resource install --size 64 ./wmicon-menu-64.png shinythings-webmirror-menu -xdg-icon-resource install --size 64 ./wmicon-admin-64.png shinythings-webmirror-admin + Although the result is the same it is slightly more efficient + to install all files at the same time. + The *.desktop and *.directory files reference icons with the + names webmirror, webmirror-admin and webmirror-menu which + should also be installed. In this example the icons are + installed in two different sizes, once with a size of 22x22 + pixels and once with a size of 64x64 pixels: +xdg-icon-resource install --size 22 ./wmicon-22.png shinythings-webmirro +r +xdg-icon-resource install --size 22 ./wmicon-menu-22.png shinythings-web +mirror-menu +xdg-icon-resource install --size 22 ./wmicon-admin-22.png shinythings-we +bmirror-admin +xdg-icon-resource install --size 64 ./wmicon-64.png shinythings-webmirro +r +xdg-icon-resource install --size 64 ./wmicon-menu-64.png shinythings-web +mirror-menu +xdg-icon-resource install --size 64 ./wmicon-admin-64.png shinythings-we +bmirror-admin _MANUALPAGE } usage() { cat << _USAGE -xdg-desktop-menu - command line tool for (un)installing desktop menu items + xdg-desktop-menu - command line tool for (un)installing desktop + menu items Synopsis -xdg-desktop-menu install [--noupdate] [--novendor] [--mode mode] directory-file -(s) desktop-file(s) + xdg-desktop-menu install [--noupdate] [--novendor] [--mode + mode] directory-file(s) desktop-file(s) -xdg-desktop-menu uninstall [--noupdate] [--mode mode] directory-file(s) -desktop-file(s) + xdg-desktop-menu uninstall [--noupdate] [--mode mode] + directory-file(s) desktop-file(s) -xdg-desktop-menu forceupdate [--mode mode] + xdg-desktop-menu forceupdate [--mode mode] -xdg-desktop-menu { --help | --manual | --version } + xdg-desktop-menu { --help | --manual | --version } _USAGE } @@ -418,6 +464,64 @@ echo "$@" >&2 } +# This handles backslashes but not quote marks. +first_word() +{ + read first rest + echo "$first" +} + +#------------------------------------------------------------- +# map a binary to a .desktop file +binary_to_desktop_file() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + binary="`which "$1"`" + binary="`readlink -f "$binary"`" + base="`basename "$binary"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] || continue + [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue + for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do + [ -r "$file" ] || continue + # Check to make sure it's worth the processing. + grep -q "^Exec.*$base" "$file" || continue + # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop"). + grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + if [ x"`readlink -f "$command"`" = x"$binary" ]; then + # Fix any double slashes that got added path composition + echo "$file" | sed -e 's,//*,/,g' + return + fi + done + done +} + +#------------------------------------------------------------- +# map a .desktop file to a binary +## FIXME: handle vendor dir case +desktop_file_to_binary() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + desktop="`basename "$1"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] && [ -d "$dir/applications" ] || continue + file="$dir/applications/$desktop" + [ -r "$file" ] || continue + # Remove any arguments (%F, %f, %U, %u, etc.). + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + readlink -f "$command" + return + done +} + #------------------------------------------------------------- # Exit script on successfully completing the desired operation @@ -526,7 +630,7 @@ [ -n "$file_label" ] || file_label="filename" file=`basename "$1"` case "$file" in - [a-zA-Z]*-*) + [[:alpha:]]*-*) return ;; esac @@ -548,7 +652,7 @@ fi else DIR=`dirname "$1"` - if [ ! -w "$DIR" -o ! -x "$DIR" ]; then + if [ ! -w "$DIR" ] || [ ! -x "$DIR" ]; then exit_failure_file_permission_write "no permission to create file '$1'" fi fi @@ -576,7 +680,7 @@ ;; --version) - echo "xdg-desktop-menu 1.1.0 rc1" + echo "xdg-desktop-menu 1.1.0 rc3" exit_success ;; esac @@ -600,12 +704,86 @@ detectDE() { - if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; - elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; - elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; - elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; - elif [ x"$DESKTOP_SESSION" == x"LXDE" ]; then DE=lxde; - else DE="" + # see https://bugs.freedesktop.org/show_bug.cgi?id=34164 + unset GREP_OPTIONS + + if [ -n "${XDG_CURRENT_DESKTOP}" ]; then + case "${XDG_CURRENT_DESKTOP}" in + # only recently added to menu-spec, pre-spec X- still in use + Cinnamon|X-Cinnamon) + DE=cinnamon; + ;; + ENLIGHTENMENT) + DE=enlightenment; + ;; + # GNOME, GNOME-Classic:GNOME, or GNOME-Flashback:GNOME + GNOME*) + DE=gnome; + ;; + KDE) + DE=kde; + ;; + LXDE) + DE=lxde; + ;; + MATE) + DE=mate; + ;; + XFCE) + DE=xfce + ;; + X-Generic) + DE=generic + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # classic fallbacks + if [ x"$KDE_FULL_SESSION" != x"" ]; then DE=kde; + elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; + elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then DE=mate; + elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; + elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; + elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce + elif echo $DESKTOP | grep -q '^Enlightenment'; then DE=enlightenment; + fi + fi + + if [ x"$DE" = x"" ]; then + # fallback to checking $DESKTOP_SESSION + case "$DESKTOP_SESSION" in + gnome) + DE=gnome; + ;; + LXDE|Lubuntu) + DE=lxde; + ;; + MATE) + DE=mate; + ;; + xfce|xfce4|'Xfce Session') + DE=xfce; + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # fallback to uname output for other platforms + case "$(uname 2>/dev/null)" in + CYGWIN*) + DE=cygwin; + ;; + Darwin) + DE=darwin; + ;; + esac + fi + + if [ x"$DE" = x"gnome" ]; then + # gnome-default-applications-properties is only available in GNOME 2.x + # but not in GNOME 3.x + which gnome-default-applications-properties > /dev/null 2>&1 || DE="gnome3" fi } @@ -616,7 +794,6 @@ kfmclient_fix_exit_code() { - [ x"$KDE_SESSION_VERSION" = x"4" ] && return 0; version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'` major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'` minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'` @@ -687,7 +864,7 @@ # App already listed as default continue; fi - default_file="$1/defaults.list" + default_file="$(readlink -f "$1/defaults.list")" DEBUG 1 "Updating $default_file" grep -v "$MIME=" $default_file > ${default_file}.new 2> /dev/null if ! grep "[Default Applications]" ${default_file}.new > /dev/null; then @@ -757,7 +934,7 @@ return fi - if [ $action = "install" -a -f "/etc/xdg/menus/gnome-applications.menu" ] ; then + if [ $action = "install" ] && [ -f "/etc/xdg/menus/gnome-applications.menu" ] ; then # Work around for Debian Gnome gnome_xdg_dir=`echo "$xdg_dir" | sed -e 's^/applications-merged^/gnome-applications-merged^'` if [ ! -e "$gnome_xdg_dir" ] ; then @@ -766,7 +943,7 @@ eval 'ln -s "applications-merged" "$gnome_xdg_dir"'$xdg_redirect_output fi fi - if [ $action = "install" -a -f "/etc/mandrake-release" ] ; then + if [ $action = "install" ] && [ -f "/etc/mandrake-release" ] ; then # Work around for Mandriva 2006 mandrake_xdg_dir=`echo "$xdg_dir" | sed -e 's^/applications-merged^/applications-mdk-merged^'` if [ ! -e "$mandrake_xdg_dir" ] ; then @@ -775,7 +952,7 @@ eval 'ln -s "applications-merged" "$mandrake_xdg_dir"'$xdg_redirect_output fi fi - if [ $action = "install" -a x"$mode" = x"user" -a -d "/etc/xdg/menus/kde-applications-merged" ] ; then + if [ $action = "install" -a x"$mode" = x"user" ] && [ -d "/etc/xdg/menus/kde-applications-merged" ] ; then # Work around for Fedora Core 5 + patched KDE kde_xdg_dir=`echo "$xdg_dir" | sed -e 's^/applications-merged^/kde-applications-merged^'` if [ ! -e "$kde_xdg_dir" ] ; then @@ -784,7 +961,7 @@ eval 'ln -s "applications-merged" "$kde_xdg_dir"'$xdg_redirect_output fi fi - if [ $action = "install" -a x"$mode" = x"system" -a -d "/etc/xdg/menus/kde-applications-merged" -a ! -d "/etc/xdg/menus/applications-merged" ] ; then + if [ $action = "install" -a x"$mode" = x"system" ] && [ -d "/etc/xdg/menus/kde-applications-merged" ] && [ ! -d "/etc/xdg/menus/applications-merged" ] ; then # Work around for Kubuntu 6.06 kde_xdg_dir=`echo "$xdg_dir" | sed -e 's^/applications-merged^/kde-applications-merged^'` DEBUG 1 "Kubuntu Workaround: Link '$xdg_dir' to 'kde-applications-merged'" @@ -830,12 +1007,14 @@ done # Files to uninstall are listed in $tmpfile # Existing files are in $orig_desktop_files + if [ ! -z "$orig_desktop_files" ]; then for desktop_file in $orig_desktop_files; do if ! grep '^'$desktop_file'$' $tmpfile > /dev/null 2> /dev/null; then # Keep this file, it's not in the uninstall list new_desktop_files="$new_desktop_files $desktop_file" fi done + fi fi rm -f "$tmpfile" @@ -892,7 +1071,7 @@ test "${TMPDIR+set}" = set || TMPDIR=/tmp tmpfile=`mktemp $TMPDIR/tmp.XXXXXXXXXX` for menu_file in $xdg_dir/*; do - if grep 'generated and managed by xdg-desktop-menu' $menu_file > /dev/null 2> /dev/null; then + if grep 'generated and managed by xdg-desktop-menu' "$menu_file" > /dev/null 2> /dev/null; then awk ' # List all files within tags BEGIN { @@ -902,7 +1081,7 @@ if (match($0,/>/)) { print substr($0,RSTART+1) } -}' $menu_file >> $tmpfile +}' "$menu_file" >> $tmpfile fi done orig_directory_files="$directory_files" diff -Nru gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-email gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-email --- gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-email 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-email 2015-12-22 04:46:12.000000000 +0000 @@ -39,95 +39,111 @@ cat << _MANUALPAGE Name -xdg-email - command line tool for sending mail using the user's preferred -e-mail composer + xdg-email - command line tool for sending mail using the user's + preferred e-mail composer Synopsis -xdg-email [--utf8] [--cc address] [--bcc address] [--subject text] [--body text -] [--attach file] [ mailto-uri | address(es) ] + xdg-email [--utf8] [--cc address] [--bcc address] [--subject + text] [--body text] [--attach file] [ mailto-uri | address(es) + ] -xdg-email { --help | --manual | --version } + xdg-email { --help | --manual | --version } Description -xdg-email opens the user's preferred e-mail composer in order to send a mail to -address(es) or mailto-uri. RFC2368 defines mailto: URIs. xdg-email limits -support to, cc, subject and body fields in mailto-uri, all other fields are -silently ignored. address(es) must follow the syntax of RFC822. Multiple -addresses may be provided as separate arguments. - -All information provided on the command line is used to prefill corresponding -fields in the user's e-mail composer. The user will have the opportunity to -change any of this information before actually sending the e-mail. + xdg-email opens the user's preferred e-mail composer in order + to send a mail to address(es) or mailto-uri. RFC2368 defines + mailto: URIs. xdg-email limits support to, cc, subject and body + fields in mailto-uri, all other fields are silently ignored. + address(es) must follow the syntax of RFC822. Multiple + addresses may be provided as separate arguments. + + All information provided on the command line is used to prefill + corresponding fields in the user's e-mail composer. The user + will have the opportunity to change any of this information + before actually sending the e-mail. -xdg-email is for use inside a desktop session only. It is not recommended to -use xdg-email as root. - -See http://portland.freedesktop.org/EmailConfig for information on how the user -can change the e-mail composer that is used. + xdg-email is for use inside a desktop session only. It is not + recommended to use xdg-email as root. Options ---utf8 - Indicates that all command line options that follow are in utf8. Without - this option, command line options are expected to be encoded according to - locale. If the locale already specifies utf8 this option has no effect. - This option does not affect mailto URIs that are passed on the command - line. ---cc address - Specify a recipient to be copied on the e-mail. ---bcc address - Specify a recipient to be blindly copied on the e-mail. ---subject text - Specify a subject for the e-mail. ---body text - Specify a body for the e-mail. Since the user will be able to make changes - before actually sending the e-mail, this can be used to provide the user - with a template for the e-mail. text may contain linebreaks. ---attach file - - Specify an attachment for the e-mail. file must point to an existing file. - - Some e-mail applications require the file to remain present after xdg-email - returns. - ---help - Show command synopsis. ---manual - Show this manualpage. ---version - Show the xdg-utils version information. + --utf8 + Indicates that all command line options that follow are + in utf8. Without this option, command line options are + expected to be encoded according to locale. If the + locale already specifies utf8 this option has no effect. + This option does not affect mailto URIs that are passed + on the command line. + + --cc address + Specify a recipient to be copied on the e-mail. + + --bcc address + Specify a recipient to be blindly copied on the e-mail. + + --subject text + Specify a subject for the e-mail. + + --body text + Specify a body for the e-mail. Since the user will be + able to make changes before actually sending the e-mail, + this can be used to provide the user with a template for + the e-mail. text may contain linebreaks. + + --attach file + Specify an attachment for the e-mail. file must point to + an existing file. + + Some e-mail applications require the file to remain + present after xdg-email returns. + + --help + Show command synopsis. + + --manual + Show this manual page. + + --version + Show the xdg-utils version information. Environment Variables -xdg-email honours the following environment variables: + xdg-email honours the following environment variables: -XDG_UTILS_DEBUG_LEVEL - Setting this environment variable to a non-zero numerical value makes - xdg-email do more verbose reporting on stderr. Setting a higher value - increases the verbosity. + XDG_UTILS_DEBUG_LEVEL + Setting this environment variable to a non-zero + numerical value makes xdg-email do more verbose + reporting on stderr. Setting a higher value increases + the verbosity. Exit Codes -An exit code of 0 indicates success while a non-zero exit code indicates -failure. The following failure codes can be returned: + An exit code of 0 indicates success while a non-zero exit code + indicates failure. The following failure codes can be returned: + + 1 + Error in command line syntax. -1 - Error in command line syntax. -2 - One of the files passed on the command line did not exist. -3 - A required tool could not be found. -4 - The action failed. -5 - No permission to read one of the files passed on the command line. + 2 + One of the files passed on the command line did not + exist. -Configuration + 3 + A required tool could not be found. -Visit http://portland.freedesktop.org/EmailConfig for information how to -configure xdg-email to use the email client of your choice. + 4 + The action failed. + + 5 + No permission to read one of the files passed on the + command line. + +See Also + + xdg-open(1), xdg-mime(1), MIME applications associations + specification, RFC 6068 - The 'mailto' URI Scheme Examples @@ -139,23 +155,24 @@ 'jwhite@example.com' xdg-email --subject 'Your password is about to expire' \ - 'jwhite@example.com' 'bastian@example.com' 'whipple@example.com' - + 'jwhite@example.com' 'bastian@example.com' 'whipple@example.co +m' _MANUALPAGE } usage() { cat << _USAGE -xdg-email - command line tool for sending mail using the user's preferred -e-mail composer + xdg-email - command line tool for sending mail using the user's + preferred e-mail composer Synopsis -xdg-email [--utf8] [--cc address] [--bcc address] [--subject text] [--body text -] [--attach file] [ mailto-uri | address(es) ] + xdg-email [--utf8] [--cc address] [--bcc address] [--subject + text] [--body text] [--attach file] [ mailto-uri | address(es) + ] -xdg-email { --help | --manual | --version } + xdg-email { --help | --manual | --version } _USAGE } @@ -174,6 +191,64 @@ echo "$@" >&2 } +# This handles backslashes but not quote marks. +first_word() +{ + read first rest + echo "$first" +} + +#------------------------------------------------------------- +# map a binary to a .desktop file +binary_to_desktop_file() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + binary="`which "$1"`" + binary="`readlink -f "$binary"`" + base="`basename "$binary"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] || continue + [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue + for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do + [ -r "$file" ] || continue + # Check to make sure it's worth the processing. + grep -q "^Exec.*$base" "$file" || continue + # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop"). + grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + if [ x"`readlink -f "$command"`" = x"$binary" ]; then + # Fix any double slashes that got added path composition + echo "$file" | sed -e 's,//*,/,g' + return + fi + done + done +} + +#------------------------------------------------------------- +# map a .desktop file to a binary +## FIXME: handle vendor dir case +desktop_file_to_binary() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + desktop="`basename "$1"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] && [ -d "$dir/applications" ] || continue + file="$dir/applications/$desktop" + [ -r "$file" ] || continue + # Remove any arguments (%F, %f, %U, %u, etc.). + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + readlink -f "$command" + return + done +} + #------------------------------------------------------------- # Exit script on successfully completing the desired operation @@ -282,7 +357,7 @@ [ -n "$file_label" ] || file_label="filename" file=`basename "$1"` case "$file" in - [a-zA-Z]*-*) + [[:alpha:]]*-*) return ;; esac @@ -304,7 +379,7 @@ fi else DIR=`dirname "$1"` - if [ ! -w "$DIR" -o ! -x "$DIR" ]; then + if [ ! -w "$DIR" ] || [ ! -x "$DIR" ]; then exit_failure_file_permission_write "no permission to create file '$1'" fi fi @@ -332,7 +407,7 @@ ;; --version) - echo "xdg-email 1.1.0 rc1" + echo "xdg-email 1.1.0 rc3" exit_success ;; esac @@ -356,12 +431,86 @@ detectDE() { - if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; - elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; - elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; - elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; - elif [ x"$DESKTOP_SESSION" == x"LXDE" ]; then DE=lxde; - else DE="" + # see https://bugs.freedesktop.org/show_bug.cgi?id=34164 + unset GREP_OPTIONS + + if [ -n "${XDG_CURRENT_DESKTOP}" ]; then + case "${XDG_CURRENT_DESKTOP}" in + # only recently added to menu-spec, pre-spec X- still in use + Cinnamon|X-Cinnamon) + DE=cinnamon; + ;; + ENLIGHTENMENT) + DE=enlightenment; + ;; + # GNOME, GNOME-Classic:GNOME, or GNOME-Flashback:GNOME + GNOME*) + DE=gnome; + ;; + KDE) + DE=kde; + ;; + LXDE) + DE=lxde; + ;; + MATE) + DE=mate; + ;; + XFCE) + DE=xfce + ;; + X-Generic) + DE=generic + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # classic fallbacks + if [ x"$KDE_FULL_SESSION" != x"" ]; then DE=kde; + elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; + elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then DE=mate; + elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; + elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; + elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce + elif echo $DESKTOP | grep -q '^Enlightenment'; then DE=enlightenment; + fi + fi + + if [ x"$DE" = x"" ]; then + # fallback to checking $DESKTOP_SESSION + case "$DESKTOP_SESSION" in + gnome) + DE=gnome; + ;; + LXDE|Lubuntu) + DE=lxde; + ;; + MATE) + DE=mate; + ;; + xfce|xfce4|'Xfce Session') + DE=xfce; + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # fallback to uname output for other platforms + case "$(uname 2>/dev/null)" in + CYGWIN*) + DE=cygwin; + ;; + Darwin) + DE=darwin; + ;; + esac + fi + + if [ x"$DE" = x"gnome" ]; then + # gnome-default-applications-properties is only available in GNOME 2.x + # but not in GNOME 3.x + which gnome-default-applications-properties > /dev/null 2>&1 || DE="gnome3" fi } @@ -372,7 +521,6 @@ kfmclient_fix_exit_code() { - [ x"$KDE_SESSION_VERSION" = x"4" ] && return 0; version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'` major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'` minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'` @@ -396,12 +544,12 @@ fi MAILTO=$(echo "$MAILTO" | sed 's/&/\n/g') - TO=$(echo "$MAILTO" | grep '^to=' | sed 's/^to=//' | awk '{ printf "%s,",$0 }') - CC=$(echo "$MAILTO" | grep '^cc=' | sed 's/^cc=//' | awk '{ printf "%s,",$0 }') - BCC=$(echo "$MAILTO" | grep '^bcc=' | sed 's/^bcc=//' | awk '{ printf "%s,",$0 }') + TO=$(/bin/echo -e $(echo "$MAILTO" | grep '^to=' | sed 's/^to=//;s/%\(..\)/\\x\1/g' | awk '{ printf "%s,",$0 }')) + CC=$(/bin/echo -e $(echo "$MAILTO" | grep '^cc=' | sed 's/^cc=//;s/%\(..\)/\\x\1/g' | awk '{ printf "%s,",$0 }')) + BCC=$(/bin/echo -e $(echo "$MAILTO" | grep '^bcc=' | sed 's/^bcc=//;s/%\(..\)/\\x\1/g' | awk '{ printf "%s,",$0 }')) SUBJECT=$(echo "$MAILTO" | grep '^subject=' | tail -n 1) BODY=$(echo "$MAILTO" | grep '^body=' | tail -n 1) - ATTACH=$(echo "$MAILTO" | sed 's/^attach=/\n\nfile:\/\//g' | awk '/^file:/ { printf "%s,",$0 }' | sed 's/,$//') + ATTACH=$(/bin/echo -e $(echo "$MAILTO" | grep '^attach=' | sed 's/^attach=//;s/%\(..\)/\\x\1/g' | awk '{ printf "%s,",$0 }' | sed 's/,$//')) if [ -z "$TO" ] ; then NEWMAILTO= @@ -437,34 +585,73 @@ open_kde() { - local client kde_email_profile_name - kde_email_profile_name=`kreadconfig --file emaildefaults --group Defaults --key Profile` - client=`kreadconfig --file emaildefaults --group PROFILE_"$kde_email_profile_name" --key EmailClient | cut -d ' ' -f 1` - echo $client | grep thunderbird > /dev/null 2>&1 - if [ $? -eq 0 ] ; then - run_thunderbird "$client" "$1" + if [ -n "$KDE_SESSION_VERSION" ] && [ "$KDE_SESSION_VERSION" -ge 5 ]; then + local kreadconfig=kreadconfig$KDE_SESSION_VERSION + else + local kreadconfig=kreadconfig fi - if [ -f /etc/SuSE-release ] ; then - # Workaround for SUSE 10.0 - [ -z "$client" ] && client="kmail" - if ! which "$client" > /dev/null 2> /dev/null; then - DEBUG 3 "KDE has $client configured as email client which isn't installed" - if which gnome-open > /dev/null 2> /dev/null && which evolution > /dev/null 2> /dev/null; then - DEBUG 3 "Try gnome-open instead" - open_gnome "$1" + if which $kreadconfig >/dev/null 2>&1; then + local profile=$($kreadconfig --file emaildefaults \ + --group Defaults --key Profile) + if [ -n "$profile" ]; then + local client=$($kreadconfig --file emaildefaults \ + --group "PROFILE_$profile" \ + --key EmailClient \ + | cut -d ' ' -f 1) + + if echo "$client" | grep -Eq 'thunderbird|icedove'; then + run_thunderbird "$client" "$1" fi fi fi - DEBUG 1 "Running kmailservice \"$1\"" - if [ x"$KDE_SESSION_VERSION" = x"4" ]; then - KMAILSERVICE=`kde4-config --locate kmailservice --path exe 2>/dev/null` - else - KMAILSERVICE=`which kmailservice 2>/dev/null` - fi - # KDE uses locale's encoding when decoding the URI, so set it to UTF-8 - LC_ALL=C.UTF-8 $KMAILSERVICE "$1" - kfmclient_fix_exit_code $? + + local command + case "$KDE_SESSION_VERSION" in + '') command=kmailservice ;; + 4) command=kde-open ;; + *) command=kde-open$KDE_SESSION_VERSION ;; + esac + + if which $command >/dev/null 2>&1; then + DEBUG 1 "Running $command \"$1\"" + if [ "$KDE_SESSION_VERSION" = 3 ]; then + # KDE3 uses locale's encoding when decoding the URI, + # so set it to UTF-8 + LC_ALL=C.UTF-8 $command "$1" + else + $command "$1" + fi + else + DEBUG 1 "$command missing; trying generic mode instead." + open_generic "$1" + fi + + if [ $? = 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_gnome3() +{ + local client + local desktop + desktop=`xdg-mime query default "x-scheme-handler/mailto"` + client=`desktop_file_to_binary "$desktop"` + echo $client | grep -E 'thunderbird|icedove' > /dev/null 2>&1 + if [ $? -eq 0 ] ; then + run_thunderbird "$client" "$1" + fi + + if gvfs-open --help 2>/dev/null 1>&2; then + DEBUG 1 "Running gvfs-open \"$1\"" + gvfs-open "$1" + else + DEBUG 1 "Running gnome-open \"$1\"" + gnome-open "$1" + fi if [ $? -eq 0 ]; then exit_success @@ -477,7 +664,7 @@ { local client client=`gconftool-2 --get /desktop/gnome/url-handlers/mailto/command | cut -d ' ' -f 1` || "" - echo $client | grep thunderbird > /dev/null 2>&1 + echo $client | grep -E 'thunderbird|icedove' > /dev/null 2>&1 if [ $? -eq 0 ] ; then run_thunderbird "$client" "$1" fi @@ -510,8 +697,42 @@ fi } +open_envvar() +{ + local OLDIFS="$IFS" + IFS=: + for i in $MAILER; do + IFS="$OLDIFS" + + eval "$i" '"$1"' + + if [ $? -eq 0 ]; then + exit_success + fi + done + + exit_failure_operation_failed +} + open_generic() { + local client + local desktop + desktop=`xdg-mime query default "x-scheme-handler/mailto"` + client=`desktop_file_to_binary "$desktop"` + echo $client | grep -E 'thunderbird|icedove' > /dev/null 2>&1 + if [ $? -eq 0 ] ; then + run_thunderbird "$client" "$1" + fi + + xdg-open "$1" + local ret=$? + + # 3 means exit_failure_operation_impossible + if [ $ret != 3 ]; then + exit $ret + fi + IFS=":" for browser in $BROWSER; do if [ x"$browser" != x"" ]; then @@ -534,7 +755,15 @@ url_encode() { -result=$(echo "$1" | $utf8 | awk ' +# The shell needs the default internal field separator +# otherwise it would search for $utf8 as a command in whole. +IFS=" " +str=$(echo "$1" | $utf8) +local ORIG_LANG="$LANG" +local ORIG_LC_ALL="$LC_ALL" +LANG=C +LC_ALL=C +result=$(echo "$str" | awk ' BEGIN { for ( i=1; i<=255; ++i ) ord [ sprintf ("%c", i) "" ] = i + 0 e = "" @@ -548,9 +777,7 @@ c = substr ($0, i, 1) if ( ord [c] > 127 ) { e = e "%" sprintf("%02X", ord [c]) - } else if ( ord[c] == 45 ) { - e = e c - } else if ( c ~ /[@a-zA-Z0-9.\\\/]/ ) { + } else if ( c ~ /[@a-zA-Z0-9.\-\\\/]/ ) { e = e c } else { e = e "%" sprintf("%02X", ord [c]) @@ -561,6 +788,8 @@ print e } ') +LANG="$ORIG_LANG" +LC_ALL="$ORIG_LC_ALL" } options= @@ -626,7 +855,7 @@ fi check_input_file "$1" file=`readlink -f "$1"` # Normalize path - if [ -z "$file" -o ! -f "$file" ] ; then + if [ -z "$file" ] || [ ! -f "$file" ] ; then exit_failure_file_missing "file '$1' does not exist" fi @@ -698,15 +927,23 @@ DE=generic fi +if [ x"$MAILER" != x"" ]; then + DE=envvar +fi + # if BROWSER variable is not set, check some well known browsers instead if [ x"$BROWSER" = x"" ]; then - BROWSER=links2:links:lynx:w3m + BROWSER=www-browser:links2:elinks:links:lynx:w3m if [ -n "$DISPLAY" ]; then - BROWSER=firefox:mozilla:epiphany:konqueror:chromium-browser:google-chrome:$BROWSER + BROWSER=x-www-browser:firefox:iceweasel:seamonkey:mozilla:epiphany:konqueror:chromium-browser:google-chrome:$BROWSER fi fi case "$DE" in + envvar) + open_envvar "${mailto}" + ;; + kde) open_kde "${mailto}" ;; @@ -715,16 +952,15 @@ open_gnome "${mailto}" ;; -# BB 01Nov13: Fix to stop default web browser being run - lxde) - open_gnome "${mailto}" + gnome3|cinnamon|lxde|mate) + open_gnome3 "${mailto}" ;; - + xfce) open_xfce "${mailto}" ;; - generic|lxde) + generic) open_generic "${mailto}" ;; diff -Nru gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-file-dialog gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-file-dialog --- gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-file-dialog 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-file-dialog 1970-01-01 00:00:00.000000000 +0000 @@ -1,603 +0,0 @@ -#!/bin/sh -#--------------------------------------------- -# xdg-file-dialog -# -# Utility script to file selection dialogs -# on XDG compliant systems. -# -# Refer to the usage() function below for usage. -# -# Copyright 2006, Kevin Krammer -# -# LICENSE: -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the "Software"), -# to deal in the Software without restriction, including without limitation -# the rights to use, copy, modify, merge, publish, distribute, sublicense, -# and/or sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. -# -#--------------------------------------------- - -manualpage() -{ -cat << _MANUALPAGE -Name - - xdg-file-dialog -- command line tool for providing file and directory - selection dialogs - -Synopsis - - xdg-file-dialog openfilename [--title TITLE] [FILENAME] - - xdg-file-dialog openfilenamelist [--title TITLE] [FILENAME] - - xdg-file-dialog savefilename [--title TITLE] [FILENAME] - - xdg-file-dialog directory [--title TITLE] [DIRNAME] - - xdg-file-dialog { --help | --manual | --version } - -Description - - The xdg-file-dialog program can be used to let the native file selection - dialog handle file and directory input. - - xdg-file-dialog is for use inside a desktop session only. It is not - recommended to use xdg-file-dialog as root. - -Commands - - openfilename - Returns the filename with path for a file to read from. FILENAME - can optionally be used to specify path and filename of a - preselection. - - openfilenamelist - Returns one or more filenames with path for files to read from, - each on a new line. FILENAME can optionally be used to specify - path and filename of a preselection. - - savefilename - Returns the filename with path for file to write to. FILENAME can - optionally be used to specify path and filename of a preselection. - - directory - Returns the path for an exsiting directory. DIRNAME can optionally - be used to specify a path of a preselection. - -Options - - --title TITLE - Sets the dialog's title (caption) to the specified text. - - --help - Show command synopsis. - - --manual - Show this manualpage. - - --version - Show the xdg-utils version information. - -Exit Codes - - An exit code of 0 indicates success while a non-zero exit code indicates - failure. The following failure codes can be returned: - - 1 - Error in command line syntax. - - 2 - One of the files passed on the command line did not exist. - - 3 - A required tool could not be found. - - 4 - The action failed. - -Examples - - xdg-file-dialog savefilename /tmp/foobar.png - - Asks for a save file name starting in directory /tmp and suggesting - foobar.png as the filename - - xdg-file-dialog directory --title "Select a target folder" /tmp - - Asks for a directory name starting in directory /tmp using the text - "Select a target folder" as the dialog's title/caption. -_MANUALPAGE -} - -usage() -{ -cat << _USAGE - xdg-file-dialog -- command line tool for providing file and directory - selection dialogs - -Synopsis - - xdg-file-dialog openfilename [--title TITLE] [FILENAME] - - xdg-file-dialog openfilenamelist [--title TITLE] [FILENAME] - - xdg-file-dialog savefilename [--title TITLE] [FILENAME] - - xdg-file-dialog directory [--title TITLE] [DIRNAME] - - xdg-file-dialog { --help | --manual | --version } - -_USAGE -} - -#@xdg-utils-common@ - -#---------------------------------------------------------------------------- -# Common utility functions included in all XDG wrapper scripts -#---------------------------------------------------------------------------- - -#------------------------------------------------------------- -# Exit script on successfully completing the desired operation - -exit_success() -{ - if [ $# -gt 0 ]; then - echo "$@" - echo - fi - - exit 0 -} - - -#----------------------------------------- -# Exit script on malformed arguments, not enough arguments -# or missing required option. -# prints usage information - -exit_failure_syntax() -{ - if [ $# -gt 0 ]; then - echo "xdg-file-dialog: $@" >&2 - echo "Try 'xdg-file-dialog --help' for more information." >&2 - else - usage - echo "Use 'man xdg-file-dialog' or 'xdg-file-dialog --manual' for additional info." - fi - - exit 1 -} - -#------------------------------------------------------------- -# Exit script on missing file specified on command line - -exit_failure_file_missing() -{ - if [ $# -gt 0 ]; then - echo "xdg-file-dialog: $@" >&2 - fi - - exit 2 -} - -#------------------------------------------------------------- -# Exit script on failure to locate necessary tool applications - -exit_failure_operation_impossible() -{ - if [ $# -gt 0 ]; then - echo "xdg-file-dialog: $@" >&2 - fi - - exit 3 -} - -#------------------------------------------------------------- -# Exit script on failure returned by a tool application - -exit_failure_operation_failed() -{ - if [ $# -gt 0 ]; then - echo "xdg-file-dialog: $@" >&2 - fi - - exit 4 -} - - -#---------------------------------------- -# Checks for shared commands, e.g. --help - -check_common_commands() -{ - while [ $# -gt 0 ] ; do - parm=$1 - shift - - case $parm in - --help) - usage - echo "Use 'man xdg-file-dialog' or 'xdg-file-dialog --manual' for additional info." - exit_success - ;; - - --manual) - manualpage - exit_success - ;; - - --version) - echo "xdg-file-dialog 1.0beta1" - exit_success - ;; - esac - done -} - -check_common_commands "$@" - -#-------------------------------------- -# Checks for known desktop environments -# set variable DE to the desktop environments name, lowercase - -detectDE() -{ - if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; - elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; - elif xprop -root _DT_SAVE_MODE | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; - fi -} - -#---------------------------------------------------------------------------- - - - -open_kde() -{ - DIALOG=`which kdialog` - if [ $? -eq 0 ]; then - if [ x"$TITLE" != x"" ]; then - $DIALOG --title "$TITLE" --getopenfilename "$1" "" - else - $DIALOG --getopenfilename "$1" "" - fi - - if [ $? -eq 0 ]; then - exit_success - else - exit_failure_operation_failed - fi - else - exit_failure_operation_impossible - fi -} - -open_zenity() -{ - DIALOG=`which zenity` - if [ $? -eq 0 ]; then - if [ x"$1" != x"" ]; then - cd `dirname "$1"` 2>/dev/null - FILENAME=`basename "$1"` - if [ x"$FILENAME" != x"" ]; then - FILENAME="--filename=""$FILENAME" - fi - fi - - if [ x"$FILENAME" != x"" ]; then - if [ x"$TITLE" != x"" ]; then - $DIALOG --title "$TITLE" --file-selection "$FILENAME" - else - $DIALOG --file-selection "$FILENAME" - fi - else - if [ x"$TITLE" != x"" ]; then - $DIALOG --title "$TITLE" --file-selection - else - $DIALOG --file-selection - fi - fi - - if [ $? -eq 0 ]; then - exit_success - else - exit_failure_operation_failed - fi - else - exit_failure_operation_impossible - fi -} - -open_multi_kde() -{ - DIALOG=`which kdialog` - if [ $? -eq 0 ]; then - if [ x"$TITLE" != x"" ]; then - $DIALOG --title "$TITLE" --multiple --separate-output \ - --getopenfilename "$1" "" - else - $DIALOG --multiple --separate-output --getopenfilename "$1" "" - fi - - if [ $? -eq 0 ]; then - exit_success - else - exit_failure_operation_failed - fi - else - exit_failure_operation_impossible - fi -} - -open_multi_zenity() -{ - DIALOG=`which zenity` - if [ $? -eq 0 ]; then - if [ x"$1" != x"" ]; then - cd `dirname "$1"` 2>/dev/null - FILENAME=`basename "$1"` - if [ x"$FILENAME" != x"" ]; then - FILENAME="--filename=""$FILENAME" - fi - fi - - if [ x"$FILENAME" != x"" ]; then - if [ x"$TITLE" != x"" ]; then - LIST=`$DIALOG --title "$TITLE" --multiple --file-selection "$FILENAME"` - else - LIST=`$DIALOG --multiple --file-selection "$FILENAME"` - fi - else - if [ x"$TITLE" != x"" ]; then - LIST=`$DIALOG --title "$TITLE" --multiple --file-selection` - else - LIST=`$DIALOG --multiple --file-selection` - fi - fi - - if [ $? -eq 0 ]; then - echo "$LIST" | sed s#'|'#\\n#g - exit_success - else - exit_failure_operation_failed - fi - else - exit_failure_operation_impossible - fi -} - -save_kde() -{ - DIALOG=`which kdialog` - if [ $? -eq 0 ]; then - if [ x"$TITLE" != x"" ]; then - $DIALOG --title "$TITLE" --getsavefilename "$1" "" - else - $DIALOG --getsavefilename "$1" "" - fi - - if [ $? -eq 0 ]; then - exit_success - else - exit_failure_operation_failed - fi - else - exit_failure_operation_impossible - fi -} - -save_zenity() -{ - DIALOG=`which zenity` - if [ $? -eq 0 ]; then - if [ x"$1" != x"" ]; then - cd `dirname "$1"` 2>/dev/null - FILENAME=`basename "$1"` - if [ x"$FILENAME" != x"" ]; then - FILENAME="--filename=""$FILENAME" - fi - fi - - if [ x"$FILENAME" != x"" ]; then - if [ x"$TITLE" != x"" ]; then - $DIALOG --title "$TITLE" --save --file-selection "$FILENAME" - else - $DIALOG --save --file-selection "$FILENAME" - fi - else - if [ x"$TITLE" != x"" ]; then - $DIALOG --title "$TITLE" --save --file-selection - else - $DIALOG --save --file-selection - fi - fi - - if [ $? -eq 0 ]; then - exit_success - else - exit_failure_operation_failed - fi - else - exit_failure_operation_impossible - fi -} - -directory_kde() -{ - DIALOG=`which kdialog` - if [ $? -eq 0 ]; then - if [ x"$TITLE" != x"" ]; then - $DIALOG --title "$TITLE" --getexistingdirectory "$1" "" - else - $DIALOG --getexistingdirectory "$1" "" - fi - - if [ $? -eq 0 ]; then - exit_success - else - exit_failure_operation_failed - fi - else - exit_failure_operation_impossible - fi -} - -directory_zenity() -{ - DIALOG=`which zenity` - if [ $? -eq 0 ]; then - if [ x"$1" != x"" ]; then - cd "$1" 2>/dev/null - fi - - if [ x"$TITLE" != x"" ]; then - $DIALOG --title "$TITLE" --directory --file-selection - else - $DIALOG --directory --file-selection - fi - - if [ $? -eq 0 ]; then - exit_success - else - exit_failure_operation_failed - fi - else - exit_failure_operation_impossible - fi -} - -[ x"$1" != x"" ] || exit_failure_syntax - -TITLE= -action= -filename= - -case $1 in - openfilename) - action=openfilename - ;; - - openfilenamelist) - action=openfilenamelist - ;; - - savefilename) - action=savefilename - ;; - - directory) - action=directory - ;; - - *) - exit_failure_syntax "unknown command '$1'" - ;; -esac - -shift - -while [ $# -gt 0 ] ; do - parm=$1 - shift - - case $parm in - --title) - if [ -z "$1" ] ; then - exit_failure_syntax "TITLE argument missing for --title" - fi - TITLE="$1" - shift - ;; - - -*) - exit_failure_syntax "unexpected option '$parm'" - ;; - - *) - if [ -n "$filename" ] ; then - exit_failure_syntax "unexpected argument '$parm'" - fi - filename="$parm" - ;; - esac -done - -# Shouldn't happen -if [ -z "$action" ] ; then - exit_failure_syntax "command argument missing" -fi - -detectDE - -if [ "$action" = "openfilename" ]; then - case "$DE" in - kde) - open_kde "$filename" - ;; - - gnome|xfce) - open_zenity "$filename" - ;; - - *) - exit_failure_operation_impossible "no method available for opening a filename dialog" - ;; - esac -elif [ "$action" = "openfilenamelist" ]; then - case "$DE" in - kde) - open_multi_kde "$filename" - ;; - - gnome|xfce) - open_multi_zenity "$filename" - ;; - - *) - exit_failure_operation_impossible "no method available for opening a filename dialog" - ;; - esac -elif [ "$action" = "savefilename" ]; then - case "$DE" in - kde) - save_kde "$filename" - ;; - - gnome|xfce) - save_zenity "$filename" - ;; - - *) - exit_failure_operation_impossible "no method available for opening a filename dialog" - ;; - esac -elif [ "$action" = "directory" ]; then - case "$DE" in - kde) - directory_kde "$filename" - ;; - - gnome|xfce) - directory_zenity "$filename" - ;; - - *) - exit_failure_operation_impossible "no method available for opening a directory dialog" - ;; - esac -fi diff -Nru gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-icon-resource gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-icon-resource --- gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-icon-resource 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-icon-resource 2015-12-22 04:46:12.000000000 +0000 @@ -38,164 +38,199 @@ cat << _MANUALPAGE Name -xdg-icon-resource - command line tool for (un)installing icon resources + xdg-icon-resource - command line tool for (un)installing icon + resources Synopsis -xdg-icon-resource install [--noupdate] [--novendor] [--theme theme] [--context -context] [--mode mode] --size size icon-file [icon-name] + xdg-icon-resource install [--noupdate] [--novendor] [--theme + theme] [--context context] [--mode mode] --size size icon-file + [icon-name] -xdg-icon-resource uninstall [--noupdate] [--theme theme] [--context context] -[--mode mode] --size size icon-name + xdg-icon-resource uninstall [--noupdate] [--theme theme] + [--context context] [--mode mode] --size size icon-name -xdg-icon-resource forceupdate [--theme theme] [--mode mode] + xdg-icon-resource forceupdate [--theme theme] [--mode mode] -xdg-icon-resource { --help | --manual | --version } + xdg-icon-resource { --help | --manual | --version } Description -The xdg-icon-resource program can be used to install icon resources into the -desktop icon system in order to illustrate menu entries, to depict desktop -icons or to graphically represent file types. - -The desktop icon system identifies icons by name. Depending on the required -size, the choice of icon theme and the context in which the icon is used, the -desktop icon system locates an appropriate icon resource to depict an icon. -Icon resources can be XPM files or PNG files. - -The desktop icon system works according to the XDG Icon Theme Specification at -http://www.freedesktop.org/Standards/icon-theme-spec + The xdg-icon-resource program can be used to install icon + resources into the desktop icon system in order to illustrate + menu entries, to depict desktop icons or to graphically + represent file types. + + The desktop icon system identifies icons by name. Depending on + the required size, the choice of icon theme and the context in + which the icon is used, the desktop icon system locates an + appropriate icon resource to depict an icon. Icon resources can + be XPM files or PNG files. + + The desktop icon system works according to the XDG Icon Theme + Specification at + http://www.freedesktop.org/wiki/Specifications/icon-theme-spec Commands -install - Installs the icon file indicated by icon-file to the desktop icon system - under the name icon-name. Icon names do not have an extension. If icon-name - is not provided the name is derived from icon-file. The icon file must have - .png or .xpm as extension. If a corresponding .icon file exists in the same - location as icon-file it will be installed as well. -uninstall - Removes the icon indicated by icon-name from the desktop icon system. Note - that icon names do not have an extension. -forceupdate - Force an update of the desktop icon system. This is only useful if the last - call to xdg-icon-resource included the --noupdate option. + install + Installs the icon file indicated by icon-file to the + desktop icon system under the name icon-name. Icon names + do not have an extension. If icon-name is not provided + the name is derived from icon-file. The icon file must + have .png or .xpm as extension. If a corresponding .icon + file exists in the same location as icon-file it will be + installed as well. + + uninstall + Removes the icon indicated by icon-name from the desktop + icon system. Note that icon names do not have an + extension. + + forceupdate + Force an update of the desktop icon system. This is only + useful if the last call to xdg-icon-resource included + the --noupdate option. Options ---noupdate - Postpone updating the desktop icon system. If multiple icons are added in - sequence this flag can be used to indicate that additional changes will - follow and that it is not necassery to update the desktop icon system right - away. ---novendor - - Normally, xdg-icon-resource checks to ensure that an icon file to be - installed in the apps context has a proper vendor prefix. This option can - be used to disable that check. - - A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated - with a dash ("-"). Companies and organizations are encouraged to use a word - or phrase, preferably the organizations name, for which they hold a - trademark as their vendor prefix. The purpose of the vendor prefix is to - prevent name conflicts. - ---theme theme - Installs or removes the icon file as part of theme. If no theme is - specified the icons will be installed as part of the default hicolor theme. - Applications may install icons under multiple themes but should at least - install icons for the default hicolor theme. ---context context - Specifies the context for the icon. Icons to be used in the application - menu and as desktop icon should use apps as context which is the default - context. Icons to be used as file icons should use mimetypes as context. - Other common contexts are actions, devices, emblems, filesystems and stock. ---size size - Specifies the size of the icon. All icons must be square. Common sizes for - icons in the apps context are: 16, 22, 32, 48, 64 and 128. Common sizes for - icons in the mimetypes context are: 16, 22, 32, 48, 64 and 128 ---mode mode - - mode can be user or system. In user mode the file is (un)installed for the - current user only. In system mode the file is (un)installed for all users - on the system. Usually only root is allowed to install in system mode. - - The default is to use system mode when called by root and to use user mode - when called by a non-root user. - ---help - Show command synopsis. ---manual - Show this manualpage. ---version - Show the xdg-utils version information. + --noupdate + Postpone updating the desktop icon system. If multiple + icons are added in sequence this flag can be used to + indicate that additional changes will follow and that it + is not necessary to update the desktop icon system right + away. + + --novendor + Normally, xdg-icon-resource checks to ensure that an + icon file to be installed in the apps context has a + proper vendor prefix. This option can be used to disable + that check. + + A vendor prefix consists of alpha characters ([a-zA-Z]) + and is terminated with a dash ("-"). Companies and + organizations are encouraged to use a word or phrase, + preferably the organizations name, for which they hold a + trademark as their vendor prefix. The purpose of the + vendor prefix is to prevent name conflicts. + + --theme theme + Installs or removes the icon file as part of theme. If + no theme is specified the icons will be installed as + part of the default hicolor theme. Applications may + install icons under multiple themes but should at least + install icons for the default hicolor theme. + + --context context + Specifies the context for the icon. Icons to be used in + the application menu and as desktop icon should use apps + as context which is the default context. Icons to be + used as file icons should use mimetypes as context. + Other common contexts are actions, devices, emblems, + filesystems and stock. + + --size size + Specifies the size of the icon. All icons must be + square. Common sizes for icons in the apps context are: + 16, 22, 32, 48, 64 and 128. Common sizes for icons in + the mimetypes context are: 16, 22, 32, 48, 64 and 128 + + --mode mode + mode can be user or system. In user mode the file is + (un)installed for the current user only. In system mode + the file is (un)installed for all users on the system. + Usually only root is allowed to install in system mode. + + The default is to use system mode when called by root + and to use user mode when called by a non-root user. + + --help + Show command synopsis. + + --manual + Show this manual page. + + --version + Show the xdg-utils version information. Environment Variables -xdg-icon-resource honours the following environment variables: + xdg-icon-resource honours the following environment variables: -XDG_UTILS_DEBUG_LEVEL - Setting this environment variable to a non-zero numerical value makes - xdg-icon-resource do more verbose reporting on stderr. Setting a higher - value increases the verbosity. -XDG_UTILS_INSTALL_MODE - This environment variable can be used by the user or administrator to - override the installation mode. Valid values are user and system. + XDG_UTILS_DEBUG_LEVEL + Setting this environment variable to a non-zero + numerical value makes xdg-icon-resource do more verbose + reporting on stderr. Setting a higher value increases + the verbosity. + + XDG_UTILS_INSTALL_MODE + This environment variable can be used by the user or + administrator to override the installation mode. Valid + values are user and system. Exit Codes -An exit code of 0 indicates success while a non-zero exit code indicates -failure. The following failure codes can be returned: + An exit code of 0 indicates success while a non-zero exit code + indicates failure. The following failure codes can be returned: -1 - Error in command line syntax. -2 - One of the files passed on the command line did not exist. -3 - A required tool could not be found. -4 - The action failed. -5 - No permission to read one of the files passed on the command line. + 1 + Error in command line syntax. -See Also + 2 + One of the files passed on the command line did not + exist. -xdg-desktop-icon(1), xdg-desktop-menu(1), xdg-mime(1) + 3 + A required tool could not be found. -Examples + 4 + The action failed. -To install an icon resource to depict a launcher for the application myfoobar, -the company ShinyThings Inc. can use: + 5 + No permission to read one of the files passed on the + command line. -xdg-icon-resource install --size 64 shinythings-myfoobar.png +See Also -To install an icon for a new application/x-foobar file type one can use: + xdg-desktop-icon(1), xdg-desktop-menu(1), xdg-mime(1), Icon + theme specification -xdg-icon-resource install --context mimetypes --size 48 ./mime-foobar-48.png application-x-foobar -xdg-icon-resource install --context mimetypes --size 64 ./mime-foobar-64.png application-x-foobar +Examples + + To install an icon resource to depict a launcher for the + application myfoobar, the company ShinyThings Inc. can use: +xdg-icon-resource install --size 64 shinythings-myfoobar.png -This will install two icons with the name application-x-foobar but with -different sizes. + To install an icon for a new application/x-foobar file type one + can use: +xdg-icon-resource install --context mimetypes --size 48 ./mime-foobar-48 +.png application-x-foobar +xdg-icon-resource install --context mimetypes --size 64 ./mime-foobar-64 +.png application-x-foobar + This will install two icons with the name application-x-foobar + but with different sizes. _MANUALPAGE } usage() { cat << _USAGE -xdg-icon-resource - command line tool for (un)installing icon resources + xdg-icon-resource - command line tool for (un)installing icon + resources Synopsis -xdg-icon-resource install [--noupdate] [--novendor] [--theme theme] [--context -context] [--mode mode] --size size icon-file [icon-name] + xdg-icon-resource install [--noupdate] [--novendor] [--theme + theme] [--context context] [--mode mode] --size size icon-file + [icon-name] -xdg-icon-resource uninstall [--noupdate] [--theme theme] [--context context] -[--mode mode] --size size icon-name + xdg-icon-resource uninstall [--noupdate] [--theme theme] + [--context context] [--mode mode] --size size icon-name -xdg-icon-resource forceupdate [--theme theme] [--mode mode] + xdg-icon-resource forceupdate [--theme theme] [--mode mode] -xdg-icon-resource { --help | --manual | --version } + xdg-icon-resource { --help | --manual | --version } _USAGE } @@ -214,6 +249,64 @@ echo "$@" >&2 } +# This handles backslashes but not quote marks. +first_word() +{ + read first rest + echo "$first" +} + +#------------------------------------------------------------- +# map a binary to a .desktop file +binary_to_desktop_file() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + binary="`which "$1"`" + binary="`readlink -f "$binary"`" + base="`basename "$binary"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] || continue + [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue + for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do + [ -r "$file" ] || continue + # Check to make sure it's worth the processing. + grep -q "^Exec.*$base" "$file" || continue + # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop"). + grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + if [ x"`readlink -f "$command"`" = x"$binary" ]; then + # Fix any double slashes that got added path composition + echo "$file" | sed -e 's,//*,/,g' + return + fi + done + done +} + +#------------------------------------------------------------- +# map a .desktop file to a binary +## FIXME: handle vendor dir case +desktop_file_to_binary() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + desktop="`basename "$1"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] && [ -d "$dir/applications" ] || continue + file="$dir/applications/$desktop" + [ -r "$file" ] || continue + # Remove any arguments (%F, %f, %U, %u, etc.). + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + readlink -f "$command" + return + done +} + #------------------------------------------------------------- # Exit script on successfully completing the desired operation @@ -322,7 +415,7 @@ [ -n "$file_label" ] || file_label="filename" file=`basename "$1"` case "$file" in - [a-zA-Z]*-*) + [[:alpha:]]*-*) return ;; esac @@ -344,7 +437,7 @@ fi else DIR=`dirname "$1"` - if [ ! -w "$DIR" -o ! -x "$DIR" ]; then + if [ ! -w "$DIR" ] || [ ! -x "$DIR" ]; then exit_failure_file_permission_write "no permission to create file '$1'" fi fi @@ -372,7 +465,7 @@ ;; --version) - echo "xdg-icon-resource 1.1.0 rc1" + echo "xdg-icon-resource 1.1.0 rc3" exit_success ;; esac @@ -396,12 +489,86 @@ detectDE() { - if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; - elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; - elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; - elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; - elif [ x"$DESKTOP_SESSION" == x"LXDE" ]; then DE=lxde; - else DE="" + # see https://bugs.freedesktop.org/show_bug.cgi?id=34164 + unset GREP_OPTIONS + + if [ -n "${XDG_CURRENT_DESKTOP}" ]; then + case "${XDG_CURRENT_DESKTOP}" in + # only recently added to menu-spec, pre-spec X- still in use + Cinnamon|X-Cinnamon) + DE=cinnamon; + ;; + ENLIGHTENMENT) + DE=enlightenment; + ;; + # GNOME, GNOME-Classic:GNOME, or GNOME-Flashback:GNOME + GNOME*) + DE=gnome; + ;; + KDE) + DE=kde; + ;; + LXDE) + DE=lxde; + ;; + MATE) + DE=mate; + ;; + XFCE) + DE=xfce + ;; + X-Generic) + DE=generic + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # classic fallbacks + if [ x"$KDE_FULL_SESSION" != x"" ]; then DE=kde; + elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; + elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then DE=mate; + elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; + elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; + elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce + elif echo $DESKTOP | grep -q '^Enlightenment'; then DE=enlightenment; + fi + fi + + if [ x"$DE" = x"" ]; then + # fallback to checking $DESKTOP_SESSION + case "$DESKTOP_SESSION" in + gnome) + DE=gnome; + ;; + LXDE|Lubuntu) + DE=lxde; + ;; + MATE) + DE=mate; + ;; + xfce|xfce4|'Xfce Session') + DE=xfce; + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # fallback to uname output for other platforms + case "$(uname 2>/dev/null)" in + CYGWIN*) + DE=cygwin; + ;; + Darwin) + DE=darwin; + ;; + esac + fi + + if [ x"$DE" = x"gnome" ]; then + # gnome-default-applications-properties is only available in GNOME 2.x + # but not in GNOME 3.x + which gnome-default-applications-properties > /dev/null 2>&1 || DE="gnome3" fi } @@ -412,7 +579,6 @@ kfmclient_fix_exit_code() { - [ x"$KDE_SESSION_VERSION" = x"4" ] && return 0; version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'` major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'` minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'` @@ -599,7 +765,7 @@ fi if [ -z "$mode" ] ; then - if [ `whoami` = "root" ] ; then + if [ "`whoami`" = "root" ] ; then mode="system" else mode="user" @@ -618,13 +784,13 @@ xdg_system_dirs="$XDG_DATA_DIRS" [ -n "$xdg_system_dirs" ] || xdg_system_dirs="/usr/local/share/:/usr/share/" for x in `echo "$xdg_system_dirs" | sed 's/:/ /g'`; do - if [ -w $x/$xdg_dir_name ] ; then + if [ -w "$x/$xdg_dir_name" ] ; then xdg_global_prefix="$x/icons" xdg_global_dir="$x/$xdg_dir_name" break fi done -[ -w $xdg_global_dir ] || xdg_global_dir= +[ -w "$xdg_global_dir" ] || xdg_global_dir= dot_icon_dir= dot_base_dir= @@ -648,8 +814,8 @@ fi update_icon_database $xdg_base_dir if [ -n "$dot_icon_dir" ] ; then - if [ -d "$dot_icon_dir/" -a ! -L "$dot_icon_dir" ] ; then - update_icon_database $dot_base_dir + if [ -d "$dot_icon_dir/" ] && [ ! -L "$dot_icon_dir" ] ; then + update_icon_database "$dot_base_dir" fi fi exit_success @@ -672,7 +838,7 @@ xdg_size_name="${size}x${size}" if [ x"$action" = x"install" ] ; then - case $icon_file in + case "$icon_file" in *.xpm) extension="xpm" ;; @@ -686,7 +852,7 @@ fi if [ -n "$icon_name" ] ; then - case $icon_name in + case "$icon_name" in *.png) exit_failure_syntax "icon name should not include an extension" ;; @@ -730,8 +896,8 @@ fi done DEBUG 2 "kde_global_prefix: $kde_global_prefix" - [ $needed -eq "1" ] && DEBUG 2 "need_kde_icon_path RETURN $needed (not needed)" - [ $needed -eq "0" ] && DEBUG 2 "need_kde_icon_path RETURN $needed (needed)" + [ $needed -eq 1 ] && DEBUG 2 "need_kde_icon_path RETURN $needed (not needed)" + [ $needed -eq 0 ] && DEBUG 2 "need_kde_icon_path RETURN $needed (needed)" return $needed } @@ -775,7 +941,7 @@ # Start GNOME legacy workaround section need_gnome_mime= -[ $context = "mimetypes" ] && need_gnome_mime=true +[ "$context" = "mimetypes" ] && need_gnome_mime=true # End GNOME legacy workaround section [ -n "$icon_name" ] || icon_name=`basename "$icon_file" | sed 's/\.[a-z][a-z][a-z]$//'` @@ -788,18 +954,19 @@ icon_icon_name="$icon_name.icon" DEBUG 1 "$action icon in $xdg_dir" -[ $action = "install" -a -f $icon_icon_file ] && DEBUG 1 "install $icon_icon_name meta file in $xdg_dir" +[ "$action" = "install" ] && [ -f "$icon_icon_file" ] && DEBUG 1 "install $icon_icon_name meta file in $xdg_dir" [ -n "$kde_dir" ] && DEBUG 1 "$action symlink in $kde_dir (KDE 3.x support)" [ -n "$need_gnome_mime" ] && DEBUG 1 "$action gnome-mime-$icon_name symlink (GNOME 2.x support)" -[ $action = "install" -a -n "$dot_icon_dir" ] && DEBUG 1 "$action ~/.icons symlink (GNOME 2.8 support)" +[ "$action" = "install" -a -n "$dot_icon_dir" ] && DEBUG 1 "$action ~/.icons symlink (GNOME 2.8 support)" -case $action in +case "$action" in install) save_umask=`umask` umask $my_umask - for icon_dir in $xdg_dir $dot_icon_dir; do - mkdir -p $icon_dir + for icon_dir in "$xdg_dir" "$dot_icon_dir"; do + [ -z "$icon_dir" ] && continue + mkdir -p "$icon_dir" eval 'cp "$icon_file" "$icon_dir/$icon_name.$extension"'$xdg_redirect_output if [ -f "$icon_icon_file" ] ; then eval 'cp "$icon_icon_file" "$icon_dir/$icon_icon_name"'$xdg_redirect_output @@ -809,7 +976,7 @@ fi done if [ -n "$kde_dir" ] ; then - mkdir -p $kde_dir + mkdir -p "$kde_dir" eval 'ln -s "$xdg_dir/$icon_name.$extension" "$kde_dir/$icon_name.$extension"'$xdg_redirect_output fi @@ -817,7 +984,8 @@ ;; uninstall) - for icon_dir in $xdg_dir $dot_icon_dir; do + for icon_dir in "$xdg_dir" "$dot_icon_dir"; do + [ -z "$icon_dir" ] && continue rm -f "$icon_dir/$icon_name.xpm" "$icon_dir/$icon_name.png" rm -f "$icon_dir/$icon_icon_name" if [ -n "$need_gnome_mime" ] ; then @@ -835,8 +1003,8 @@ if [ x"$update" = x"yes" ] ; then update_icon_database "$xdg_base_dir" if [ -n "$dot_icon_dir" ] ; then - if [ -d "$dot_icon_dir/" -a ! -L "$dot_icon_dir" ] ; then - update_icon_database $dot_base_dir + if [ -d "$dot_icon_dir/" ] && [ ! -L "$dot_icon_dir" ] ; then + update_icon_database "$dot_base_dir" fi fi fi diff -Nru gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-mime gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-mime --- gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-mime 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-mime 2015-12-22 04:46:12.000000000 +0000 @@ -39,162 +39,187 @@ cat << _MANUALPAGE Name -xdg-mime - command line tool for querying information about file type handling -and adding descriptions for new file types + xdg-mime - command line tool for querying information about + file type handling and adding descriptions for new file types Synopsis -xdg-mime query { filetype | default } ... + xdg-mime query { filetype | default } ... -xdg-mime default application mimetype(s) + xdg-mime default application mimetype(s) -xdg-mime install [--mode mode] [--novendor] mimetypes-file + xdg-mime install [--mode mode] [--novendor] mimetypes-file -xdg-mime uninstall [--mode mode] mimetypes-file + xdg-mime uninstall [--mode mode] mimetypes-file -xdg-mime { --help | --manual | --version } + xdg-mime { --help | --manual | --version } Description -The xdg-mime program can be used to query information about file types and to -add descriptions for new file types. + The xdg-mime program can be used to query information about + file types and to add descriptions for new file types. Commands -query + query + Returns information related to file types. - Returns information related to file types. + The query option is for use inside a desktop session + only. It is not recommended to use xdg-mime query as + root. + + The following queries are supported: + + query filetype FILE: Returns the file type of FILE in + the form of a MIME type. + + query default mimetype: Returns the default application + that the desktop environment uses for opening files of + type mimetype. The default application is identified by + its *.desktop file. + + default + Ask the desktop environment to make application the + default application for opening files of type mimetype. + An application can be made the default for several file + types by specifying multiple mimetypes. + + application is the desktop file id of the application + and has the form vendor-name.desktop application must + already be installed in the desktop menu before it can + be made the default handler. The application's desktop + file must list support for all the MIME types that it + wishes to be the default handler for. + + Requests to make an application a default handler may be + subject to system policy or approval by the end-user. + xdg-mime query can be used to verify whether an + application is the actual default handler for a specific + file type. + + The default option is for use inside a desktop session + only. It is not recommended to use xdg-mime default as + root. + + install + Adds the file type descriptions provided in + mimetypes-file to the desktop environment. + mimetypes-file must be a XML file that follows the + freedesktop.org Shared MIME-info Database specification + and that has a mime-info element as its document root. + For each new file type one or more icons with name + type-subtype must be installed with the + xdg-icon-resource command in the mimetypes context. For + example the filetype + application/vnd.oasis.opendocument.text requires an icon + named application-vnd.oasis.opendocument.text to be + installed (unless the file type recommends another icon + name). + + uninstall + Removes the file type descriptions provided in + mimetypes-file and previously added with xdg-mime + install from the desktop environment. mimetypes-file + must be a XML file that follows the freedesktop.org + Shared MIME-info Database specification and that has a + mime-info element as its document root. - The query option is for use inside a desktop session only. It is not - recommended to use xdg-mime query as root. - - The following queries are supported: +Options - query filetype FILE: Returns the file type of FILE in the form of a MIME - type. - - query default mimetype: Returns the default application that the desktop - environment uses for opening files of type mimetype. The default - application is identified by its *.desktop file. - -default - - Ask the desktop environment to make application the default application for - opening files of type mimetype. An application can be made the default for - several file types by specifying multiple mimetypes. - - application is the desktop file id of the application and has the form - vendor-name.desktop application must already be installed in the desktop - menu before it can be made the default handler. The aplication's desktop - file must list support for all the MIME types that it wishes to be the - default handler for. - - Requests to make an application a default handler may be subject to system - policy or approval by the end-user. xdg-mime query can be used to verify - whether an application is the actual default handler for a specific file - type. - - The default option is for use inside a desktop session only. It is not - recommended to use xdg-mime default as root. - -install - Adds the file type descriptions provided in mimetypes-file to the desktop - environment. mimetypes-file must be a XML file that follows the - freedesktop.org Shared MIME-info Database specification and that has a - mime-info element as its document root. For each new file type one or more - icons with name type-subtype must be installed with the xdg-icon-resource - command in the mimetypes context. For example the filetype application/ - vnd.oasis.opendocument.text requires an icon named - application-vnd.oasis.opendocument.text to be installed (unless the file - type recommends another icon name). -uninstall - Removes the file type descriptions provided in mimetypes-file and - previously added with xdg-mime install from the desktop environment. - mimetypes-file must be a XML file that follows the freedesktop.org Shared - MIME-info Database specification and that has a mime-info element as its - document root. + --mode mode + mode can be user or system. In user mode the file is + (un)installed for the current user only. In system mode + the file is (un)installed for all users on the system. + Usually only root is allowed to install in system mode. + + The default is to use system mode when called by root + and to use user mode when called by a non-root user. + + --novendor + Normally, xdg-mime checks to ensure that the + mimetypes-file to be installed has a proper vendor + prefix. This option can be used to disable that check. + + A vendor prefix consists of alpha characters ([a-zA-Z]) + and is terminated with a dash ("-"). Companies and + organizations are encouraged to use a word or phrase, + preferably the organizations name, for which they hold a + trademark as their vendor prefix. The purpose of the + vendor prefix is to prevent name conflicts. -Options + --help + Show command synopsis. ---mode mode + --manual + Show this manual page. - mode can be user or system. In user mode the file is (un)installed for the - current user only. In system mode the file is (un)installed for all users - on the system. Usually only root is allowed to install in system mode. - - The default is to use system mode when called by root and to use user mode - when called by a non-root user. - ---novendor - - Normally, xdg-mime checks to ensure that the mimetypes-file to be installed - has a proper vendor prefix. This option can be used to disable that check. - - A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated - with a dash ("-"). Companies and organizations are encouraged to use a word - or phrase, preferably the organizations name, for which they hold a - trademark as their vendor prefix. The purpose of the vendor prefix is to - prevent name conflicts. - ---help - Show command synopsis. ---manual - Show this manualpage. ---version - Show the xdg-utils version information. + --version + Show the xdg-utils version information. Environment Variables -xdg-mime honours the following environment variables: + xdg-mime honours the following environment variables: -XDG_UTILS_DEBUG_LEVEL - Setting this environment variable to a non-zero numerical value makes - xdg-mime do more verbose reporting on stderr. Setting a higher value - increases the verbosity. -XDG_UTILS_INSTALL_MODE - This environment variable can be used by the user or administrator to - override the installation mode. Valid values are user and system. + XDG_UTILS_DEBUG_LEVEL + Setting this environment variable to a non-zero + numerical value makes xdg-mime do more verbose reporting + on stderr. Setting a higher value increases the + verbosity. + + XDG_UTILS_INSTALL_MODE + This environment variable can be used by the user or + administrator to override the installation mode. Valid + values are user and system. Exit Codes -An exit code of 0 indicates success while a non-zero exit code indicates -failure. The following failure codes can be returned: + An exit code of 0 indicates success while a non-zero exit code + indicates failure. The following failure codes can be returned: + + 1 + Error in command line syntax. -1 - Error in command line syntax. -2 - One of the files passed on the command line did not exist. -3 - A required tool could not be found. -4 - The action failed. -5 - No permission to read one of the files passed on the command line. + 2 + One of the files passed on the command line did not + exist. + + 3 + A required tool could not be found. + + 4 + The action failed. + + 5 + No permission to read one of the files passed on the + command line. See Also -xdg-icon-resource(1), xdg-desktop-menu(1) + xdg-icon-resource(1), xdg-desktop-menu(1), Shared MIME database + specification, MIME applications associations specification Examples xdg-mime query filetype /tmp/foobar.png -Prints the MIME type of the file /tmp/foobar.png, in this case image/png + Prints the MIME type of the file /tmp/foobar.png, in this case + image/png xdg-mime query default image/png -Prints the .desktop filename of the application which is registered to open PNG -files. + Prints the .desktop filename of the application which is + registered to open PNG files. xdg-mime install shinythings-shiny.xml -Adds a file type description for "shiny"-files. "shinythings-" is used as the -vendor prefix. The file type description could look as folows. - + Adds a file type description for "shiny"-files. "shinythings-" + is used as the vendor prefix. The file type description could + look as follows. shinythings-shiny.xml: - + Shiny new file type @@ -202,30 +227,30 @@ -An icon for this new file type must also be installed, for example with: - -xdg-icon-resource install --context mimetypes --size 64 shiny-file-icon.png text-x-shiny - + An icon for this new file type must also be installed, for + example with: +xdg-icon-resource install --context mimetypes --size 64 shiny-file-icon. +png text-x-shiny _MANUALPAGE } usage() { cat << _USAGE -xdg-mime - command line tool for querying information about file type handling -and adding descriptions for new file types + xdg-mime - command line tool for querying information about + file type handling and adding descriptions for new file types Synopsis -xdg-mime query { filetype | default } ... + xdg-mime query { filetype | default } ... -xdg-mime default application mimetype(s) + xdg-mime default application mimetype(s) -xdg-mime install [--mode mode] [--novendor] mimetypes-file + xdg-mime install [--mode mode] [--novendor] mimetypes-file -xdg-mime uninstall [--mode mode] mimetypes-file + xdg-mime uninstall [--mode mode] mimetypes-file -xdg-mime { --help | --manual | --version } + xdg-mime { --help | --manual | --version } _USAGE } @@ -244,6 +269,64 @@ echo "$@" >&2 } +# This handles backslashes but not quote marks. +first_word() +{ + read first rest + echo "$first" +} + +#------------------------------------------------------------- +# map a binary to a .desktop file +binary_to_desktop_file() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + binary="`which "$1"`" + binary="`readlink -f "$binary"`" + base="`basename "$binary"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] || continue + [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue + for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do + [ -r "$file" ] || continue + # Check to make sure it's worth the processing. + grep -q "^Exec.*$base" "$file" || continue + # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop"). + grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + if [ x"`readlink -f "$command"`" = x"$binary" ]; then + # Fix any double slashes that got added path composition + echo "$file" | sed -e 's,//*,/,g' + return + fi + done + done +} + +#------------------------------------------------------------- +# map a .desktop file to a binary +## FIXME: handle vendor dir case +desktop_file_to_binary() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + desktop="`basename "$1"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] && [ -d "$dir/applications" ] || continue + file="$dir/applications/$desktop" + [ -r "$file" ] || continue + # Remove any arguments (%F, %f, %U, %u, etc.). + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + readlink -f "$command" + return + done +} + #------------------------------------------------------------- # Exit script on successfully completing the desired operation @@ -352,7 +435,7 @@ [ -n "$file_label" ] || file_label="filename" file=`basename "$1"` case "$file" in - [a-zA-Z]*-*) + [[:alpha:]]*-*) return ;; esac @@ -374,7 +457,7 @@ fi else DIR=`dirname "$1"` - if [ ! -w "$DIR" -o ! -x "$DIR" ]; then + if [ ! -w "$DIR" ] || [ ! -x "$DIR" ]; then exit_failure_file_permission_write "no permission to create file '$1'" fi fi @@ -402,7 +485,7 @@ ;; --version) - echo "xdg-mime 1.1.0 rc1" + echo "xdg-mime 1.1.0 rc3" exit_success ;; esac @@ -426,12 +509,86 @@ detectDE() { - if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; - elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; - elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; - elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; - elif [ x"$DESKTOP_SESSION" == x"LXDE" ]; then DE=lxde; - else DE="" + # see https://bugs.freedesktop.org/show_bug.cgi?id=34164 + unset GREP_OPTIONS + + if [ -n "${XDG_CURRENT_DESKTOP}" ]; then + case "${XDG_CURRENT_DESKTOP}" in + # only recently added to menu-spec, pre-spec X- still in use + Cinnamon|X-Cinnamon) + DE=cinnamon; + ;; + ENLIGHTENMENT) + DE=enlightenment; + ;; + # GNOME, GNOME-Classic:GNOME, or GNOME-Flashback:GNOME + GNOME*) + DE=gnome; + ;; + KDE) + DE=kde; + ;; + LXDE) + DE=lxde; + ;; + MATE) + DE=mate; + ;; + XFCE) + DE=xfce + ;; + X-Generic) + DE=generic + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # classic fallbacks + if [ x"$KDE_FULL_SESSION" != x"" ]; then DE=kde; + elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; + elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then DE=mate; + elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; + elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; + elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce + elif echo $DESKTOP | grep -q '^Enlightenment'; then DE=enlightenment; + fi + fi + + if [ x"$DE" = x"" ]; then + # fallback to checking $DESKTOP_SESSION + case "$DESKTOP_SESSION" in + gnome) + DE=gnome; + ;; + LXDE|Lubuntu) + DE=lxde; + ;; + MATE) + DE=mate; + ;; + xfce|xfce4|'Xfce Session') + DE=xfce; + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # fallback to uname output for other platforms + case "$(uname 2>/dev/null)" in + CYGWIN*) + DE=cygwin; + ;; + Darwin) + DE=darwin; + ;; + esac + fi + + if [ x"$DE" = x"gnome" ]; then + # gnome-default-applications-properties is only available in GNOME 2.x + # but not in GNOME 3.x + which gnome-default-applications-properties > /dev/null 2>&1 || DE="gnome3" fi } @@ -442,7 +599,6 @@ kfmclient_fix_exit_code() { - [ x"$KDE_SESSION_VERSION" = x"4" ] && return 0; version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'` major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'` minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'` @@ -459,11 +615,7 @@ detectDE if [ x"$DE" = x"kde" ] ; then DEBUG 1 "Running kbuildsycoca" - if [ x"$KDE_SESSION_VERSION" = x"4" ]; then - eval 'kbuildsycoca4'$xdg_redirect_output - else - eval 'kbuildsycoca'$xdg_redirect_output - fi + eval 'kbuildsycoca${KDE_SESSION_VERSION}'$xdg_redirect_output fi fi for x in `echo "$PATH:/opt/gnome/bin" | sed 's/:/ /g'`; do @@ -477,14 +629,20 @@ info_kde() { - if [ x"$KDE_SESSION_VERSION" = x"4" ]; then - DEBUG 1 "Running kmimetypefinder \"$1\"" - KMIMETYPEFINDER=`which kmimetypefinder 2>/dev/null` - $KMIMETYPEFINDER "$1" 2>/dev/null | head -n 1 + if [ -n "${KDE_SESSION_VERSION}" ]; then + case "${KDE_SESSION_VERSION}" in + 4) + DEBUG 1 "Running kmimetypefinder \"$1\"" + kmimetypefinder "$1" 2>/dev/null | head -n 1 + ;; + 5) + DEBUG 1 "Running kmimetypefinder${KDE_SESSION_VERSION} \"$1\"" + kmimetypefinder${KDE_SESSION_VERSION} "$1" 2>/dev/null | head -n 1 + ;; + esac else DEBUG 1 "Running kfile \"$1\"" - KFILE=`which kfile 2>/dev/null` - $KFILE "$1" 2> /dev/null | head -n 1 | cut -d "(" -f 2 | cut -d ")" -f 1 + kfile "$1" 2> /dev/null | head -n 1 | cut -d "(" -f 2 | cut -d ")" -f 1 fi if [ $? -eq 0 ]; then @@ -496,14 +654,12 @@ info_gnome() { - file=`readlink -f "$1"` # Normalize path - if gvfs-info --help 2>/dev/null 1>&2; then - DEBUG 1 "Running gvfs-info \"$file\"" - gvfs-info "$file" 2> /dev/null | grep standard::content-type | cut -d' ' -f4 - else - DEBUG 1 "Running gnomevfs-info \"$file\"" - gnomevfs-info --slow-mime "$file" 2> /dev/null | grep "^MIME" | cut -d ":" -f 2 | sed s/"^ "// + DEBUG 1 "Running gvfs-info \"$1\"" + gvfs-info "$1" 2> /dev/null | grep standard::content-type | cut -d' ' -f4 + elif gnomevfs-info --help 2>/dev/null 1>&2; then + DEBUG 1 "Running gnomevfs-info \"$1\"" + gnomevfs-info --slow-mime "$1" 2> /dev/null | grep "^MIME" | cut -d ":" -f 2 | sed s/"^ "// fi if [ $? -eq 0 ]; then @@ -515,8 +671,13 @@ info_generic() { - DEBUG 1 "Running file -i \"$1\"" - /usr/bin/file -i "$1" 2> /dev/null | cut -d ":" -f 2 | sed s/"^ "// + if mimetype --version >/dev/null 2>&1; then + DEBUG 1 "Running mimetype --brief --dereference \"$1\"" + mimetype --brief --dereference "$1" + else + DEBUG 1 "Running file --brief --dereference --mime-type \"$1\"" + /usr/bin/file --brief --dereference --mime-type "$1" 2> /dev/null + fi if [ $? -eq 0 ]; then exit_success @@ -562,9 +723,9 @@ DEBUG 2 "make_default_kde $vendor $mimetype" DEBUG 1 "Updating $default_file" mkdir -p "$default_dir" - [ -f $default_file ] || touch $default_file + [ -f "$default_file" ] || touch "$default_file" if [ x"$KDE_SESSION_VERSION" = x"4" ]; then - [ -f $default_file ] || touch $default_file + [ -f "$default_file" ] || touch "$default_file" awk -v application="$vendor" -v mimetype="$mimetype" ' BEGIN { prefix=mimetype "=" @@ -621,7 +782,7 @@ blanks-- } } -' $default_file > ${default_file}.new && mv ${default_file}.new $default_file +' "$default_file" > "${default_file}.new" && mv "${default_file}.new" "$default_file" eval 'kbuildsycoca4'$xdg_redirect_output else awk -v application="$vendor" -v mimetype="$mimetype" ' @@ -648,7 +809,7 @@ print "Preference=1" print "ServiceType=" mimetype } -' $default_file > ${default_file}.new && mv ${default_file}.new $default_file +' "$default_file" > "${default_file}.new" && mv "${default_file}.new" "$default_file" fi } @@ -656,47 +817,205 @@ { # $1 is vendor-name.desktop # $2 is mime/type - # Add $2=$1 to XDG_DATA_HOME/applications/defaults.list + # Add $2=$1 to XDG_DATA_HOME/applications/mimeapps.list xdg_user_dir="$XDG_DATA_HOME" [ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share" - default_file="$xdg_user_dir/applications/defaults.list" + default_file="$xdg_user_dir/applications/mimeapps.list" DEBUG 2 "make_default_generic $1 $2" DEBUG 1 "Updating $default_file" - grep -v "$2=" $default_file > ${default_file}.new 2> /dev/null - if ! grep "[Default Applications]" ${default_file}.new > /dev/null; then - echo "[Default Applications]" >> ${default_file}.new + [ -f "$default_file" ] || touch "$default_file" + awk -v mimetype="$2" -v application="$1" ' + BEGIN { + prefix=mimetype "=" + indefault=0 + added=0 + blanks=0 + found=0 + } + { + suppress=0 + if (index($0, "[Default Applications]") == 1) { + indefault=1 + found=1 + } else if (index($0, "[") == 1) { + if (!added && indefault) { + print prefix application + added=1 + } + indefault=0 + } else if ($0 == "") { + suppress=1 + blanks++ + } else if (indefault && !added && index($0, prefix) == 1) { + $0=prefix application + added=1 + } + if (!suppress) { + while (blanks > 0) { + print "" + blanks-- + } + print $0 + } + } + END { + if (!added) { + if (!found) { + print "" + print "[Default Applications]" + } + print prefix application + } + while (blanks > 0) { + print "" + blanks-- + } + } +' "$default_file" > "${default_file}.new" && mv "${default_file}.new" "$default_file" +} + +search_desktop_file() +{ + local MIME="$1" + local dir="$2" + + grep -l "$MIME;" "$dir/"*.desktop 2>/dev/null + + for f in $dir/*/; do + [ -d "$f" ] && search_desktop_file "$MIME" "$f" + done +} + +defapp_fallback() +{ + MIME="$1" + + xdg_user_dir="$XDG_DATA_HOME" + [ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share" + + xdg_system_dirs="$XDG_DATA_DIRS" + [ -n "$xdg_system_dirs" ] || xdg_system_dirs=/usr/local/share/:/usr/share/ + + preference=-1 + desktop_file="" + for d in `echo "$xdg_user_dir:$xdg_system_dirs" | sed 's/:/ /g'`; do + for x in `search_desktop_file "$MIME" "$d/applications"`; do + pref=0`awk -F"=" '/InitialPreference=/ {print($2)}' "$x"` + DEBUG 2 " Checking $x" + + if [ $pref -gt $preference ]; then + DEBUG 2 " Select $x [ $preference => $pref ]" + preference=$pref + desktop_file=$x + fi + done + done + + if [ -n "$desktop_file" ] ; then + echo `basename $desktop_file` + exit_success fi - echo $2=$1 >> ${default_file}.new - mv ${default_file}.new $default_file +} + +check_mimeapps_list() +{ + local mimetype="$1" dir="$2" + local desktop oldifs="$IFS" + + IFS=: + for desktop in $XDG_CURRENT_DESKTOP ''; do + IFS="$oldifs" + if [ -n "$desktop" ]; then + local prefix=$(echo "$desktop-" | tr '[:upper:]' '[:lower:]') + else + local prefix= + fi + local mimeapps_list="$dir/${prefix}mimeapps.list" + if [ -f "$mimeapps_list" ] ; then + DEBUG 2 "Checking $mimeapps_list" + local result=$(awk -v mimetype="$mimetype" ' + BEGIN { + prefix=mimetype "=" + indefault=0 + found=0 + } + { + if (index($0, "[Default Applications]") == 1) { + indefault=1 + } else if (index($0, "[") == 1) { + indefault=0 + } else if (!found && indefault && index($0, prefix) == 1) { + print substr($0, length(prefix) +1, length) + found=1 + } + } +' "$mimeapps_list") + if [ -n "$result" ]; then + echo "$result" + exit_success + fi + fi + done } defapp_generic() { MIME="$1" + xdg_config_home="$XDG_CONFIG_HOME" + [ -n "$xdg_config_home" ] || xdg_config_home="$HOME/.config" + xdg_config_dirs="$XDG_CONFIG_DIRS" + [ -n "$xdg_config_dirs" ] || xdg_config_dirs="/etc/xdg" xdg_user_dir="$XDG_DATA_HOME" [ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share" - xdg_user_dir="$xdg_user_dir/$xdg_dir_name" xdg_system_dirs="$XDG_DATA_DIRS" [ -n "$xdg_system_dirs" ] || xdg_system_dirs=/usr/local/share/:/usr/share/ + local oldifs="$IFS" dir + + IFS=: + for dir in $xdg_config_home $xdg_config_dirs; do + IFS="$oldifs" + check_mimeapps_list "$MIME" "$dir" + done + + IFS=: + for dir in $xdg_user_dir $xdg_system_dirs; do + IFS="$oldifs" + check_mimeapps_list "$MIME" "$dir/applications" + done + for x in `echo "$xdg_user_dir:$xdg_system_dirs" | sed 's/:/ /g'`; do - DEBUG 2 "Checking $x/applications/defaults.list" - trader_result=`grep "$MIME=" $x/applications/defaults.list 2> /dev/null | cut -d '=' -f 2 | cut -d ';' -f 1` - if [ -n "$trader_result" ] ; then - echo $trader_result - exit_success - fi + for prefix in "$XDG_MENU_PREFIX" ""; do + DEBUG 2 "Checking $x/applications/${prefix}defaults.list and $x/applications/${prefix}mimeinfo.cache" + trader_result=`grep "$MIME=" $x/applications/${prefix}defaults.list $x/applications/${prefix}mimeinfo.cache 2> /dev/null | head -n 1 | cut -d '=' -f 2 | cut -d ';' -f 1` + if [ -n "$trader_result" ] ; then + echo $trader_result + exit_success + fi + done done + + defapp_fallback $MIME exit_success } defapp_kde() { MIME="$1" - if [ x"$KDE_SESSION_VERSION" = x"4" ]; then - KTRADER=`which ktraderclient 2> /dev/null` - MIMETYPE="--mimetype" - SERVICETYPE="--servicetype" + + if [ -n "${KDE_SESSION_VERSION}" ]; then + case "${KDE_SESSION_VERSION}" in + 4) + KTRADER=`which ktraderclient 2> /dev/null` + MIMETYPE="--mimetype" + SERVICETYPE="--servicetype" + ;; + 5) + KTRADER=`which ktraderclient${KDE_SESSION_VERSION} 2> /dev/null` + MIMETYPE="--mimetype" + SERVICETYPE="--servicetype" + ;; + esac else KTRADER=`which ktradertest 2> /dev/null` fi @@ -752,6 +1071,7 @@ ;; esac check_input_file "$filename" + filename=`readlink -f -- "$filename"` ;; default) @@ -845,7 +1165,7 @@ info_kde "$filename" ;; - gnome) + gnome*|cinnamon|lxde|mate|xfce) info_gnome "$filename" ;; diff -Nru gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-open gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-open --- gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-open 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-open 2015-12-22 04:46:12.000000000 +0000 @@ -38,71 +38,85 @@ cat << _MANUALPAGE Name -xdg-open - opens a file or URL in the user's preferred application + xdg-open - opens a file or URL in the user's preferred + application Synopsis -xdg-open { file | URL } + xdg-open { file | URL } -xdg-open { --help | --manual | --version } + xdg-open { --help | --manual | --version } Description -xdg-open opens a file or URL in the user's preferred application. If a URL is -provided the URL will be opened in the user's preferred web browser. If a file -is provided the file will be opened in the preferred application for files of -that type. xdg-open supports file, ftp, http and https URLs. + xdg-open opens a file or URL in the user's preferred + application. If a URL is provided the URL will be opened in the + user's preferred web browser. If a file is provided the file + will be opened in the preferred application for files of that + type. xdg-open supports file, ftp, http and https URLs. -xdg-open is for use inside a desktop session only. It is not recommended to use -xdg-open as root. + xdg-open is for use inside a desktop session only. It is not + recommended to use xdg-open as root. Options ---help - Show command synopsis. ---manual - Show this manualpage. ---version - Show the xdg-utils version information. + --help + Show command synopsis. + + --manual + Show this manual page. + + --version + Show the xdg-utils version information. Exit Codes -An exit code of 0 indicates success while a non-zero exit code indicates -failure. The following failure codes can be returned: + An exit code of 0 indicates success while a non-zero exit code + indicates failure. The following failure codes can be returned: + + 1 + Error in command line syntax. + + 2 + One of the files passed on the command line did not + exist. + + 3 + A required tool could not be found. + + 4 + The action failed. -1 - Error in command line syntax. -2 - One of the files passed on the command line did not exist. -3 - A required tool could not be found. -4 - The action failed. +See Also + + xdg-mime(1), xdg-settings(1), MIME applications associations + specification Examples xdg-open 'http://www.freedesktop.org/' -Opens the Freedesktop.org website in the user's default browser + Opens the freedesktop.org website in the user's default + browser. xdg-open /tmp/foobar.png -Opens the PNG image file /tmp/foobar.png in the user's default image viewing -application. - + Opens the PNG image file /tmp/foobar.png in the user's default + image viewing application. _MANUALPAGE } usage() { cat << _USAGE -xdg-open - opens a file or URL in the user's preferred application + xdg-open - opens a file or URL in the user's preferred + application Synopsis -xdg-open { file | URL } + xdg-open { file | URL } -xdg-open { --help | --manual | --version } + xdg-open { --help | --manual | --version } _USAGE } @@ -121,6 +135,64 @@ echo "$@" >&2 } +# This handles backslashes but not quote marks. +first_word() +{ + read first rest + echo "$first" +} + +#------------------------------------------------------------- +# map a binary to a .desktop file +binary_to_desktop_file() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + binary="`which "$1"`" + binary="`readlink -f "$binary"`" + base="`basename "$binary"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] || continue + [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue + for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do + [ -r "$file" ] || continue + # Check to make sure it's worth the processing. + grep -q "^Exec.*$base" "$file" || continue + # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop"). + grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + if [ x"`readlink -f "$command"`" = x"$binary" ]; then + # Fix any double slashes that got added path composition + echo "$file" | sed -e 's,//*,/,g' + return + fi + done + done +} + +#------------------------------------------------------------- +# map a .desktop file to a binary +## FIXME: handle vendor dir case +desktop_file_to_binary() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + desktop="`basename "$1"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] && [ -d "$dir/applications" ] || continue + file="$dir/applications/$desktop" + [ -r "$file" ] || continue + # Remove any arguments (%F, %f, %U, %u, etc.). + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + readlink -f "$command" + return + done +} + #------------------------------------------------------------- # Exit script on successfully completing the desired operation @@ -229,7 +301,7 @@ [ -n "$file_label" ] || file_label="filename" file=`basename "$1"` case "$file" in - [a-zA-Z]*-*) + [[:alpha:]]*-*) return ;; esac @@ -251,7 +323,7 @@ fi else DIR=`dirname "$1"` - if [ ! -w "$DIR" -o ! -x "$DIR" ]; then + if [ ! -w "$DIR" ] || [ ! -x "$DIR" ]; then exit_failure_file_permission_write "no permission to create file '$1'" fi fi @@ -279,7 +351,7 @@ ;; --version) - echo "xdg-open 1.1.0 rc1" + echo "xdg-open 1.1.0 rc3" exit_success ;; esac @@ -303,13 +375,86 @@ detectDE() { - if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; - elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; - elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then DE=mate; - elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; - elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; - elif [ x"$DESKTOP_SESSION" == x"LXDE" ]; then DE=lxde; - else DE="" + # see https://bugs.freedesktop.org/show_bug.cgi?id=34164 + unset GREP_OPTIONS + + if [ -n "${XDG_CURRENT_DESKTOP}" ]; then + case "${XDG_CURRENT_DESKTOP}" in + # only recently added to menu-spec, pre-spec X- still in use + Cinnamon|X-Cinnamon) + DE=cinnamon; + ;; + ENLIGHTENMENT) + DE=enlightenment; + ;; + # GNOME, GNOME-Classic:GNOME, or GNOME-Flashback:GNOME + GNOME*) + DE=gnome; + ;; + KDE) + DE=kde; + ;; + LXDE) + DE=lxde; + ;; + MATE) + DE=mate; + ;; + XFCE) + DE=xfce + ;; + X-Generic) + DE=generic + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # classic fallbacks + if [ x"$KDE_FULL_SESSION" != x"" ]; then DE=kde; + elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; + elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then DE=mate; + elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; + elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; + elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce + elif echo $DESKTOP | grep -q '^Enlightenment'; then DE=enlightenment; + fi + fi + + if [ x"$DE" = x"" ]; then + # fallback to checking $DESKTOP_SESSION + case "$DESKTOP_SESSION" in + gnome) + DE=gnome; + ;; + LXDE|Lubuntu) + DE=lxde; + ;; + MATE) + DE=mate; + ;; + xfce|xfce4|'Xfce Session') + DE=xfce; + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # fallback to uname output for other platforms + case "$(uname 2>/dev/null)" in + CYGWIN*) + DE=cygwin; + ;; + Darwin) + DE=darwin; + ;; + esac + fi + + if [ x"$DE" = x"gnome" ]; then + # gnome-default-applications-properties is only available in GNOME 2.x + # but not in GNOME 3.x + which gnome-default-applications-properties > /dev/null 2>&1 || DE="gnome3" fi } @@ -320,7 +465,6 @@ kfmclient_fix_exit_code() { - [ x"$KDE_SESSION_VERSION" = x"4" ] && return 0; version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'` major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'` minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'` @@ -332,24 +476,76 @@ } # This handles backslashes but not quote marks. -first_word() +last_word() { read first rest - echo "$first" + echo "$rest" } -open_kde() +# Get the value of a key in a desktop file's Desktop Entry group. +# Example: Use get_key foo.desktop Exec +# to get the values of the Exec= key for the Desktop Entry group. +get_key() +{ + local file="${1}" + local key="${2}" + local desktop_entry="" + + IFS_="${IFS}" + IFS="" + while read line + do + case "$line" in + "[Desktop Entry]") + desktop_entry="y" + ;; + # Reset match flag for other groups + "["*) + desktop_entry="" + ;; + "${key}="*) + # Only match Desktop Entry group + if [ -n "${desktop_entry}" ] + then + echo "${line}" | cut -d= -f 2- + fi + esac + done < "${file}" + IFS="${IFS_}" +} + +# Returns true if argument is a file:// URL or path +is_file_url_or_path() { - if kde-open -v 2>/dev/null 1>&2; then - kde-open -noninteractive "$1" + if echo "$1" | grep -q '^file://' \ + || ! echo "$1" | egrep -q '^[[:alpha:]+\.\-]+:'; then + return 0 else - if [ x"$KDE_SESSION_VERSION" = x"4" ]; then - kfmclient openURL "$1" - else - kfmclient exec "$1" - kfmclient_fix_exit_code $? + return 1 + fi +} + +# If argument is a file URL, convert it to a (percent-decoded) path. +# If not, leave it as it is. +file_url_to_path() +{ + local file="$1" + if echo "$file" | grep -q '^file:///'; then + file=${file#file://} + file=${file%%#*} + file=$(echo "$file" | sed -r 's/\?.*$//') + local printf=printf + if [ -x /usr/bin/printf ]; then + printf=/usr/bin/printf fi + file=$($printf "$(echo "$file" | sed -e 's@%\([a-f0-9A-F]\{2\}\)@\\x\1@g')") fi + echo "$file" +} + +open_cygwin() +{ + cygstart "$1" if [ $? -eq 0 ]; then exit_success @@ -358,12 +554,63 @@ fi } -open_gnome() +open_darwin() { - if gvfs-open --help 2>/dev/null 1>&2; then + open "$1" + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_kde() +{ + if [ -n "${KDE_SESSION_VERSION}" ]; then + case "${KDE_SESSION_VERSION}" in + 4) + kde-open "$1" + ;; + 5) + kde-open${KDE_SESSION_VERSION} "$1" + ;; + esac + else + kfmclient exec "$1" + kfmclient_fix_exit_code $? + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_gnome3() +{ + if gvfs-open --help >/dev/null 2>&1; then gvfs-open "$1" else + open_generic "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_gnome() +{ + if gvfs-open --help >/dev/null 2>&1; then + gvfs-open "$1" + elif gnome-open --help >/dev/null 2>&1; then gnome-open "$1" + else + open_generic "$1" fi if [ $? -eq 0 ]; then @@ -399,9 +646,92 @@ fi } +open_enlightenment() +{ + enlightenment_open "$1" + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +#----------------------------------------- +# Recursively search .desktop file + +search_desktop_file() +{ + local default="$1" + local dir="$2" + local target="$3" + + local file="" + # look for both vendor-app.desktop, vendor/app.desktop + if [ -r "$dir/$default" ]; then + file="$dir/$default" + elif [ -r "$dir/`echo $default | sed -e 's|-|/|'`" ]; then + file="$dir/`echo $default | sed -e 's|-|/|'`" + fi + + if [ -r "$file" ] ; then + command="$(get_key "${file}" "Exec" | first_word)" + command_exec=`which $command 2>/dev/null` + icon="$(get_key "${file}" "Icon")" + # FIXME: Actually LC_MESSAGES should be used as described in + # http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s04.html + localised_name="$(get_key "${file}" "Name")" + set -- $(get_key "${file}" "Exec" | last_word) + # We need to replace any occurrence of "%f", "%F" and + # the like by the target file. We examine each + # argument and append the modified argument to the + # end then shift. + local args=$# + local replaced=0 + while [ $args -gt 0 ]; do + case $1 in + %[c]) + replaced=1 + arg="${localised_name}" + shift + set -- "$@" "$arg" + ;; + %[fFuU]) + replaced=1 + arg="$target" + shift + set -- "$@" "$arg" + ;; + %[i]) + replaced=1 + shift + set -- "$@" "--icon" "$icon" + ;; + *) + arg="$1" + shift + set -- "$@" "$arg" + ;; + esac + args=$(( $args - 1 )) + done + [ $replaced -eq 1 ] || set -- "$@" "$target" + "$command_exec" "$@" + + if [ $? -eq 0 ]; then + exit_success + fi + fi + + for d in $dir/*/; do + [ -d "$d" ] && search_desktop_file "$default" "$d" "$target" + done +} + + open_generic_xdg_mime() { - filetype=`xdg-mime query filetype "$1" | sed "s/;.*//"` + filetype="$2" default=`xdg-mime query default "$filetype"` if [ -n "$default" ] ; then xdg_user_dir="$XDG_DATA_HOME" @@ -410,48 +740,73 @@ xdg_system_dirs="$XDG_DATA_DIRS" [ -n "$xdg_system_dirs" ] || xdg_system_dirs=/usr/local/share/:/usr/share/ +DEBUG 3 "$xdg_user_dir:$xdg_system_dirs" for x in `echo "$xdg_user_dir:$xdg_system_dirs" | sed 's/:/ /g'`; do - local file="$x/applications/$default" - if [ -r "$file" ] ; then - command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" - command_exec=`which $command 2>/dev/null` - if [ -x "$command_exec" ] ; then - $command_exec "$1" - if [ $? -eq 0 ]; then - exit_success - fi - fi - fi + search_desktop_file "$default" "$x/applications/" "$1" done fi } -open_generic() +open_generic_xdg_file_mime() +{ + filetype=`xdg-mime query filetype "$1" | sed "s/;.*//"` + open_generic_xdg_mime "$1" "$filetype" +} + +open_generic_xdg_x_scheme_handler() +{ + scheme="`echo $1 | sed -n 's/\(^[[:alnum:]+\.-]*\):.*$/\1/p'`" + if [ -n $scheme ]; then + filetype="x-scheme-handler/$scheme" + open_generic_xdg_mime "$1" "$filetype" + fi +} + +open_envvar() { - # Paths or file:// URLs - if (echo "$1" | grep -q '^file://' || - ! echo "$1" | egrep -q '^[a-zA-Z+\.\-]+:'); then - - local file="$1" - - # Decode URLs - if echo "$file" | grep -q '^file:///'; then - file=${file#file://} - file="$(printf "$(echo "$file" | sed -e 's@%\([a-f0-9A-F]\{2\}\)@\\x\1@g')")" + local oldifs="$IFS" + local browser browser_with_arg + + IFS=":" + for browser in $BROWSER; do + IFS="$oldifs" + + if [ -z "$browser" ]; then + continue fi + + if echo "$browser" | grep -q %s; then + $(printf "$browser" "$1") + else + $browser "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + fi + done +} + +open_generic() +{ + if is_file_url_or_path "$1"; then + local file="$(file_url_to_path "$1")" + check_input_file "$file" - open_generic_xdg_mime "$file" + if [ -n "$DISPLAY" ]; then + filetype=`xdg-mime query filetype "$file" | sed "s/;.*//"` + open_generic_xdg_mime "$file" "$filetype" + fi - if [ -f /etc/debian_version ] && - which run-mailcap 2>/dev/null 1>&2; then + if which run-mailcap 2>/dev/null 1>&2; then run-mailcap --action=view "$file" if [ $? -eq 0 ]; then exit_success fi fi - if mimeopen -v 2>/dev/null 1>&2; then + if [ -n "$DISPLAY" ] && mimeopen -v 2>/dev/null 1>&2; then mimeopen -L -n "$file" if [ $? -eq 0 ]; then exit_success @@ -459,25 +814,23 @@ fi fi - IFS=":" - for browser in $BROWSER; do - if [ x"$browser" != x"" ]; then - - browser_with_arg=`printf "$browser" "$1" 2>/dev/null` - if [ $? -ne 0 ]; then - browser_with_arg=$browser; - fi + if [ -n "$BROWSER" ]; then + open_envvar "$1" + fi - if [ x"$browser_with_arg" = x"$browser" ]; then - "$browser" "$1"; - else eval '$browser_with_arg'$xdg_redirect_output; - fi + if [ -n "$DISPLAY" ]; then + open_generic_xdg_x_scheme_handler "$1" + fi - if [ $? -eq 0 ]; then - exit_success; - fi + # if BROWSER variable is not set, check some well known browsers instead + if [ x"$BROWSER" = x"" ]; then + BROWSER=www-browser:links2:elinks:links:lynx:w3m + if [ -n "$DISPLAY" ]; then + BROWSER=x-www-browser:firefox:iceweasel:seamonkey:mozilla:epiphany:konqueror:chromium-browser:google-chrome:$BROWSER fi - done + fi + + open_envvar "$1" exit_failure_operation_impossible "no method available for opening '$1'" } @@ -485,18 +838,15 @@ open_lxde() { # pcmanfm only knows how to handle file:// urls and filepaths, it seems. - if (echo "$1" | grep -q '^file://' || - ! echo "$1" | egrep -q '^[a-zA-Z+\.\-]+:') - then - local file="$(echo "$1" | sed 's%^file://%%')" + if is_file_url_or_path "$1"; then + local file="$(file_url_to_path "$1")" # handle relative paths - if ! echo "$file" | grep -q '^/'; then + if ! echo "$file" | grep -q ^/; then file="$(pwd)/$file" fi pcmanfm "$file" - else open_generic "$1" fi @@ -539,19 +889,27 @@ DE=generic fi -# if BROWSER variable is not set, check some well known browsers instead -if [ x"$BROWSER" = x"" ]; then - BROWSER=links2:links:lynx:w3m - if [ -n "$DISPLAY" ]; then - BROWSER=firefox:mozilla:epiphany:konqueror:chromium-browser:google-chrome:$BROWSER - fi -fi +DEBUG 2 "Selected DE $DE" + +# sanitize BROWSER (avoid caling ourselves in particular) +case "${BROWSER}" in + *:"xdg-open"|"xdg-open":*) + BROWSER=$(echo $BROWSER | sed -e 's|:xdg-open||g' -e 's|xdg-open:||g') + ;; + "xdg-open") + BROWSER= + ;; +esac case "$DE" in kde) open_kde "$url" ;; + gnome3|cinnamon) + open_gnome3 "$url" + ;; + gnome) open_gnome "$url" ;; @@ -568,6 +926,18 @@ open_lxde "$url" ;; + enlightenment) + open_enlightenment "$url" + ;; + + cygwin) + open_cygwin "$url" + ;; + + darwin) + open_darwin "$url" + ;; + generic) open_generic "$url" ;; diff -Nru gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-screensaver gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-screensaver --- gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-screensaver 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-screensaver 2015-12-22 04:46:12.000000000 +0000 @@ -35,102 +35,116 @@ cat << _MANUALPAGE Name -xdg-screensaver - command line tool for controlling the screensaver + xdg-screensaver - command line tool for controlling the + screensaver Synopsis -xdg-screensaver suspend WindowID + xdg-screensaver suspend WindowID -xdg-screensaver resume WindowID + xdg-screensaver resume WindowID -xdg-screensaver { activate | lock | reset | status } + xdg-screensaver { activate | lock | reset | status } -xdg-screensaver { --help | --manual | --version } + xdg-screensaver { --help | --manual | --version } Description -xdg-screensaver provides commands to control the screensaver. + xdg-screensaver provides commands to control the screensaver. -xdg-screensaver is for use inside a desktop session only. It is not recommended -to use xdg-screensaver as root. + xdg-screensaver is for use inside a desktop session only. It is + not recommended to use xdg-screensaver as root. Commands -suspend WindowID - - Suspends the screensaver and monitor power management. WindowID must be the - X Window ID of an existing window of the calling application. The window - must remain in existance for the duration of the suspension. - - WindowID can be represented as either a decimal number or as a hexadecimal - number consisting of the prefix 0x followed by one or more hexadecimal - digits. - - The screensaver can be suspended in relation to multiple windows at the - same time. In that case screensaver operation is only restored once the - screensaver has been resumed in relation to each of the windows - -resume WindowID - Resume the screensaver and monitor power management after being suspended. - WindowID must be the same X Window ID that was passed to a previous call of - xdg-screensaver suspend -activate - Turns the screensaver on immediately. This may result in the screen getting - locked, depending on existing system policies. -lock - Lock the screen immediately. -reset - Turns the screensaver off immediately. If the screen was locked the user - may be asked to authenticate first. -status - Prints enabled to stdout if the screensaver is enabled to turn on after a - period of inactivity and prints disabled if the screensaver is not enabled. + suspend WindowID + Suspends the screensaver and monitor power management. + WindowID must be the X Window ID of an existing window + of the calling application. The window must remain in + existence for the duration of the suspension. + + WindowID can be represented as either a decimal number + or as a hexadecimal number consisting of the prefix 0x + followed by one or more hexadecimal digits. + + The screensaver can be suspended in relation to multiple + windows at the same time. In that case screensaver + operation is only restored once the screensaver has been + resumed in relation to each of the windows + + resume WindowID + Resume the screensaver and monitor power management + after being suspended. WindowID must be the same X + Window ID that was passed to a previous call of + xdg-screensaver suspend + + activate + Turns the screensaver on immediately. This may result in + the screen getting locked, depending on existing system + policies. + + lock + Lock the screen immediately. + + reset + Turns the screensaver off immediately. If the screen was + locked the user may be asked to authenticate first. + + status + Prints enabled to stdout if the screensaver is enabled + to turn on after a period of inactivity and prints + disabled if the screensaver is not enabled. Options ---help - Show command synopsis. ---manual - Show this manualpage. ---version - Show the xdg-utils version information. + --help + Show command synopsis. + + --manual + Show this manual page. + + --version + Show the xdg-utils version information. Exit Codes -An exit code of 0 indicates success while a non-zero exit code indicates -failure. The following failure codes can be returned: + An exit code of 0 indicates success while a non-zero exit code + indicates failure. The following failure codes can be returned: + + 1 + Error in command line syntax. + + 3 + A required tool could not be found. -1 - Error in command line syntax. -3 - A required tool could not be found. -4 - The action failed. + 4 + The action failed. Examples xdg-screensaver suspend 0x1c00007 -Causes the screensaver to be disabled till xdg-screensaver resume 0x1c00007 is -called. 0x1c00007 must be the X Window ID of an existing window. - + Causes the screensaver to be disabled till xdg-screensaver + resume 0x1c00007 is called. 0x1c00007 must be the X Window ID + of an existing window. _MANUALPAGE } usage() { cat << _USAGE -xdg-screensaver - command line tool for controlling the screensaver + xdg-screensaver - command line tool for controlling the + screensaver Synopsis -xdg-screensaver suspend WindowID + xdg-screensaver suspend WindowID -xdg-screensaver resume WindowID + xdg-screensaver resume WindowID -xdg-screensaver { activate | lock | reset | status } + xdg-screensaver { activate | lock | reset | status } -xdg-screensaver { --help | --manual | --version } + xdg-screensaver { --help | --manual | --version } _USAGE } @@ -149,6 +163,64 @@ echo "$@" >&2 } +# This handles backslashes but not quote marks. +first_word() +{ + read first rest + echo "$first" +} + +#------------------------------------------------------------- +# map a binary to a .desktop file +binary_to_desktop_file() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + binary="`which "$1"`" + binary="`readlink -f "$binary"`" + base="`basename "$binary"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] || continue + [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue + for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do + [ -r "$file" ] || continue + # Check to make sure it's worth the processing. + grep -q "^Exec.*$base" "$file" || continue + # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop"). + grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + if [ x"`readlink -f "$command"`" = x"$binary" ]; then + # Fix any double slashes that got added path composition + echo "$file" | sed -e 's,//*,/,g' + return + fi + done + done +} + +#------------------------------------------------------------- +# map a .desktop file to a binary +## FIXME: handle vendor dir case +desktop_file_to_binary() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + desktop="`basename "$1"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] && [ -d "$dir/applications" ] || continue + file="$dir/applications/$desktop" + [ -r "$file" ] || continue + # Remove any arguments (%F, %f, %U, %u, etc.). + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + readlink -f "$command" + return + done +} + #------------------------------------------------------------- # Exit script on successfully completing the desired operation @@ -257,7 +329,7 @@ [ -n "$file_label" ] || file_label="filename" file=`basename "$1"` case "$file" in - [a-zA-Z]*-*) + [[:alpha:]]*-*) return ;; esac @@ -279,7 +351,7 @@ fi else DIR=`dirname "$1"` - if [ ! -w "$DIR" -o ! -x "$DIR" ]; then + if [ ! -w "$DIR" ] || [ ! -x "$DIR" ]; then exit_failure_file_permission_write "no permission to create file '$1'" fi fi @@ -307,7 +379,7 @@ ;; --version) - echo "xdg-screensaver 1.1.0 rc1" + echo "xdg-screensaver 1.1.0 rc3" exit_success ;; esac @@ -331,12 +403,86 @@ detectDE() { - if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; - elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; - elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; - elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; - elif [ x"$DESKTOP_SESSION" == x"LXDE" ]; then DE=lxde; - else DE="" + # see https://bugs.freedesktop.org/show_bug.cgi?id=34164 + unset GREP_OPTIONS + + if [ -n "${XDG_CURRENT_DESKTOP}" ]; then + case "${XDG_CURRENT_DESKTOP}" in + # only recently added to menu-spec, pre-spec X- still in use + Cinnamon|X-Cinnamon) + DE=cinnamon; + ;; + ENLIGHTENMENT) + DE=enlightenment; + ;; + # GNOME, GNOME-Classic:GNOME, or GNOME-Flashback:GNOME + GNOME*) + DE=gnome; + ;; + KDE) + DE=kde; + ;; + LXDE) + DE=lxde; + ;; + MATE) + DE=mate; + ;; + XFCE) + DE=xfce + ;; + X-Generic) + DE=generic + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # classic fallbacks + if [ x"$KDE_FULL_SESSION" != x"" ]; then DE=kde; + elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; + elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then DE=mate; + elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; + elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; + elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce + elif echo $DESKTOP | grep -q '^Enlightenment'; then DE=enlightenment; + fi + fi + + if [ x"$DE" = x"" ]; then + # fallback to checking $DESKTOP_SESSION + case "$DESKTOP_SESSION" in + gnome) + DE=gnome; + ;; + LXDE|Lubuntu) + DE=lxde; + ;; + MATE) + DE=mate; + ;; + xfce|xfce4|'Xfce Session') + DE=xfce; + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # fallback to uname output for other platforms + case "$(uname 2>/dev/null)" in + CYGWIN*) + DE=cygwin; + ;; + Darwin) + DE=darwin; + ;; + esac + fi + + if [ x"$DE" = x"gnome" ]; then + # gnome-default-applications-properties is only available in GNOME 2.x + # but not in GNOME 3.x + which gnome-default-applications-properties > /dev/null 2>&1 || DE="gnome3" fi } @@ -347,7 +493,6 @@ kfmclient_fix_exit_code() { - [ x"$KDE_SESSION_VERSION" = x"4" ] && return 0; version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'` major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'` minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'` @@ -412,33 +557,46 @@ fi if [ "$1" = "reset" ] ; then if xset -q | grep 'DPMS is Enabled' > /dev/null 2> /dev/null; then + xset -dpms + xset +dpms xset dpms force on fi fi case "$DE" in kde) - if [ x"$KDE_SESSION_VERSION" = x"4" ]; then - screensaver_freedesktop "$1" + if [ -n "${KDE_SESSION_VERSION}" ]; then + screensaver_freedesktop "$1" else - screensaver_kde "$1" + screensaver_kde3 "$1" fi ;; - gnome_screensaver) screensaver_gnome_screensaver "$1" ;; + mate_screensaver) + screensaver_mate_screensaver "$1" + ;; + xscreensaver) screensaver_xscreensaver "$1" ;; - '') - screensaver_xserver "$1" + xautolock_screensaver) + xautolock_screensaver "$1" + ;; + + xfce) + [ -n "$DISPLAY" ] && screensaver_xserver "$1" + ;; + + ''|generic) + [ -n "$DISPLAY" ] && screensaver_xserver "$1" ;; esac - if [ "$1" = "suspend" ] ; then + if [ -n "$DISPLAY" -a "$1" = "suspend" ] ; then # Save DPMS state if xset -q | grep 'DPMS is Enabled' > /dev/null 2> /dev/null; then test "${TMPDIR+set}" = set || TMPDIR=/tmp @@ -541,7 +699,7 @@ echo "$window_id:$xprop_pid" >> $tmpfile $MV "$tmpfile" "$screensaver_file" unlockfile - # Wait for xprop to edit, it means that the window disappeared + # Wait for xprop to exit, it means that the window disappeared wait $xprop_pid # Clean up the administration and resume the screensaver cleanup_suspend @@ -625,13 +783,13 @@ org.freedesktop.ScreenSaver.GetActive \ | grep boolean | cut -d ' ' -f 5` result=$? - if [ x"$status" = "xtrue" ]; then + if [ x"$status" = "xtrue" -o x"$status" = "xfalse" ]; then echo "enabled" - elif [ x"$status" = "xfalse" ]; then - echo "disabled" - else + elif [ x"$result" != "x0" ]; then echo "ERROR: dbus org.freedesktop.ScreenSaver.GetActive returned '$status'" >&2 return 1 + else + echo "disabled" fi ;; @@ -642,7 +800,7 @@ esac } -screensaver_kde() +screensaver_kde3() { case "$1" in suspend) @@ -763,15 +921,57 @@ screensaver_gnome_screensaver() { -# TODO -# There seems to be a DBUS interface for gnome-screensaver -# See http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2006-April/042579.html and -# http://cvs.gnome.org/viewcvs/gnome-screensaver/src/gs-listener-dbus.c?rev=1.36&view=log -# A problem seems to be that Inhibit is tied to the lifetime of the DBUS appname and -# this can not be used from a script +# DBUS interface for gnome-screensaver +# http://people.gnome.org/~mccann/gnome-screensaver/docs/gnome-screensaver.html case "$1" in suspend) - screensaver_suspend_loop gnome-screensaver-command --poke + perl -e ' +use strict; +use warnings; +use IO::File; +use Net::DBus; +use X11::Protocol; + +my ($window_id, $screensaver_file) = @ARGV; + +# Find window name to pass to session manager. +my $x = X11::Protocol->new(); +my $named_window_id = hex($window_id); +my $window_name; +while (1) { + ($window_name) = $x->GetProperty($named_window_id, $x->atom("WM_NAME"), + $x->atom("STRING"), 0, 1000, 0); + last if defined($window_name) && $window_name ne ""; + (undef, $named_window_id) = $x->QueryTree($named_window_id); + if (!defined($named_window_id)) { + $window_name = "?"; + last; + } +} + +# Inhibit idle detection (flags = 8) with window name and ID. +# We have no reason so just send the window name again. +my $bus = Net::DBus->session(); +my $sm_svc = $bus->get_service("org.gnome.SessionManager"); +my $sm = $sm_svc->get_object("/org/gnome/SessionManager", + "org.gnome.SessionManager"); +$sm->Inhibit($window_name, hex($window_id), $window_name, 8); + +# Wait until removed from the status file. +while (1) { + sleep(10); + my $status = new IO::File($screensaver_file, "r") + or exit 0; + my $found; + while (<$status>) { + if (/^$window_id:/) { + $found = 1; + last; + } + } + exit 0 unless $found; +} +' $window_id $screensaver_file & result=0 ;; @@ -781,29 +981,129 @@ ;; activate) - gnome-screensaver-command --activate > /dev/null 2> /dev/null + dbus-send --session \ + --dest=org.gnome.ScreenSaver \ + --type=method_call \ + /org/gnome/ScreenSaver \ + org.gnome.ScreenSaver.SetActive \ + boolean:true \ + 2> /dev/null result=$? ;; lock) - gnome-screensaver-command --lock > /dev/null 2> /dev/null + dbus-send --session \ + --dest=org.gnome.ScreenSaver \ + --type=method_call \ + /org/gnome/ScreenSaver \ + org.gnome.ScreenSaver.Lock \ + 2> /dev/null result=$? ;; reset) # Turns the screensaver off right now - gnome-screensaver-command --deactivate > /dev/null 2> /dev/null + dbus-send --session \ + --dest=org.gnome.ScreenSaver \ + --type=method_call \ + /org/gnome/ScreenSaver \ + org.gnome.ScreenSaver.SimulateUserActivity \ + 2> /dev/null result=$? ;; status) - result=0 - if [ -f "$screensaver_file" ] ; then + status=`dbus-send --session \ + --dest=org.gnome.ScreenSaver \ + --type=method_call \ + --print-reply \ + --reply-timeout=2000 \ + /org/gnome/ScreenSaver \ + org.gnome.ScreenSaver.GetActive \ + | grep boolean | cut -d ' ' -f 5` + result=$? + if [ x"$status" = "xtrue" -o x"$status" = "xfalse" ]; then + echo "enabled" + elif [ x"$result" != "x0" ]; then + echo "ERROR: dbus org.gnome.ScreenSaver.GetActive returned '$status'" >&2 + return 1 + else echo "disabled" - elif gnome-screensaver-command --query > /dev/null 2> /dev/null; then + fi + ;; + + *) + echo "ERROR: Unknown command '$1" >&2 + return 1 + ;; + esac +} + +screensaver_mate_screensaver() +{ +# DBUS interface for mate-screensaver +# This is same as gnome's for now but may change in the future as MATE +# does not follow gnome's developement necessarily. + case "$1" in + suspend) + screensaver_suspend_loop \ + dbus-send --session \ + --dest=org.mate.ScreenSaver \ + --type=method_call \ + /org/mate/ScreenSaver \ + org.mate.ScreenSaver.SimulateUserActivity \ + 2> /dev/null + result=$? + ;; + + resume) + # Automatic resume when $screensaver_file disappears + result=0 + ;; + + activate) + dbus-send --session \ + --dest=org.mate.ScreenSaver \ + --type=method_call \ + /org/mate/ScreenSaver \ + org.mate.ScreenSaver.SetActive \ + boolean:true \ + 2> /dev/null + result=$? + ;; + + lock) + mate-screensaver-command --lock > /dev/null 2> /dev/null + result=$? + ;; + + reset) + # Turns the screensaver off right now + dbus-send --session \ + --dest=org.mate.ScreenSaver \ + --type=method_call \ + /org/mate/ScreenSaver \ + org.mate.ScreenSaver.SimulateUserActivity \ + 2> /dev/null + result=$? + ;; + + status) + status=`dbus-send --session \ + --dest=org.mate.ScreenSaver \ + --type=method_call \ + --print-reply \ + --reply-timeout=2000 \ + /org/mate/ScreenSaver \ + org.mate.ScreenSaver.GetActive \ + | grep boolean | cut -d ' ' -f 5` + result=$? + if [ x"$status" = "xtrue" -o x"$status" = "xfalse" ]; then echo "enabled" + elif [ x"$result" != "x0" ]; then + echo "ERROR: dbus org.mate.ScreenSaver.GetActive returned '$status'" >&2 + return 1 else - # Something is wrong echo "disabled" fi ;; @@ -860,6 +1160,51 @@ esac } +xautolock_screensaver() +{ + case "$1" in + suspend) + xset s off && xautolock -disable > /dev/null + result=$? + ;; + + resume) + xset s default && xautolock -enable > /dev/null + result=$? + ;; + + activate) + xautolock -enable + result=$? + ;; + + lock) + xautolock -locknow + result=$? + ;; + + reset) + xautolock -restart + result=$? + ;; + + status) + xautolock -unlocknow >/dev/null + result=$? + if [ $result -eq 0 ]; then + echo "enabled" + else + echo "disabled" + fi + ;; + + *) + echo "ERROR: Unknown command '$1" >&2 + return 1 + ;; + esac +} + [ x"$1" != x"" ] || exit_failure_syntax action= @@ -917,7 +1262,11 @@ # Consider "xscreensaver" a separate DE xscreensaver-command -version 2> /dev/null | grep XScreenSaver > /dev/null && DE="xscreensaver" # Consider "gnome-screensaver" a separate DE -gnome-screensaver-command -q > /dev/null 2>&1 && DE="gnome_screensaver" +dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.ScreenSaver > /dev/null 2>&1 && DE="gnome_screensaver" +# Consider "mate-screensaver" a separate DE +dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.mate.ScreenSaver > /dev/null 2>&1 && DE="mate_screensaver" +# Consider "xautolock" a separate DE +xautolock -enable > /dev/null 2>&1 && DE="xautolock_screensaver" if [ "$action" = "resume" ] ; then do_resume diff -Nru gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-settings gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-settings --- gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-settings 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-settings 2015-12-22 04:46:12.000000000 +0000 @@ -35,82 +35,110 @@ cat << _MANUALPAGE Name -xdg-settings - get various settings from the desktop environment + xdg-settings - get various settings from the desktop + environment Synopsis -xdg-settings { get | check | set } {property} [value] + xdg-settings { get | check | set } {property} [subproperty] + [value] -xdg-settings { --help | --list | --manual | --version } + xdg-settings { --help | --list | --manual | --version } Description -xdg-settings gets various settings from the desktop environment. For instance, -desktop environments often provide proxy configuration and default web browser -settings. Using xdg-settings these parameters can be extracted for use by -applications that do not use the desktop environment's libraries (which would -use the settings natively). + xdg-settings gets various settings from the desktop + environment. For instance, desktop environments often provide + proxy configuration and default web browser settings. Using + xdg-settings these parameters can be extracted for use by + applications that do not use the desktop environment's + libraries (which would use the settings natively). -xdg-settings is for use inside a desktop session only. It is not recommended to -use xdg-settings as root. + xdg-settings is for use inside a desktop session only. It is + not recommended to use xdg-settings as root. Options ---help - Show command synopsis. ---list - List all properties xdg-settings knows about. ---manual - Show this manualpage. ---version - Show the xdg-utils version information. + --help + Show command synopsis. + + --list + List all properties xdg-settings knows about. + + --manual + Show this manual page. + + --version + Show the xdg-utils version information. + +Properties + + When using xdg-settings to get, check or set a destkop setting, + properties and possibly sub-properties are used to specify the + setting to be changed. + + Some properties (such as default-web-browser) fully describe + the setting to be changed. Other properties (such as + default-url-scheme-handler) require more information (in this + case the actual scheme to set the default handler for) which + must be provided in a sub-property. Exit Codes -An exit code of 0 indicates success while a non-zero exit code indicates -failure. The following failure codes can be returned: + An exit code of 0 indicates success while a non-zero exit code + indicates failure. The following failure codes can be returned: -1 - Error in command line syntax. -2 - One of the files passed on the command line did not exist. -3 - A required tool could not be found. -4 - The action failed. + 1 + Error in command line syntax. -Examples + 2 + One of the files passed on the command line did not + exist. -Get the desktop file name of the current default web browser + 3 + A required tool could not be found. - xdg-settings get default-web-browser + 4 + The action failed. +See Also -Check whether the default web browser is firefox.desktop, which can be false -even if "get default-web-browser" says that is the current value (if only some -of the underlying settings actually reflect that value) + xdg-mime(1), xdg-open(1), MIME applications associations + specification - xdg-settings check default-web-browser firefox.desktop +Examples + Get the desktop file name of the current default web browser + xdg-settings get default-web-browser -Set the default web browser to google-chrome.desktop + Check whether the default web browser is firefox.desktop, which + can be false even if "get default-web-browser" says that is the + current value (if only some of the underlying settings actually + reflect that value) + xdg-settings check default-web-browser firefox.desktop + Set the default web browser to google-chrome.desktop xdg-settings set default-web-browser google-chrome.desktop - + Set the default mailto URL scheme handler to be + evolution.desktop + xdg-settings set default-url-scheme-handler mailto evolution.des +ktop _MANUALPAGE } usage() { cat << _USAGE -xdg-settings - get various settings from the desktop environment + xdg-settings - get various settings from the desktop + environment Synopsis -xdg-settings { get | check | set } {property} [value] + xdg-settings { get | check | set } {property} [subproperty] + [value] -xdg-settings { --help | --list | --manual | --version } + xdg-settings { --help | --list | --manual | --version } _USAGE } @@ -129,6 +157,64 @@ echo "$@" >&2 } +# This handles backslashes but not quote marks. +first_word() +{ + read first rest + echo "$first" +} + +#------------------------------------------------------------- +# map a binary to a .desktop file +binary_to_desktop_file() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + binary="`which "$1"`" + binary="`readlink -f "$binary"`" + base="`basename "$binary"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] || continue + [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue + for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do + [ -r "$file" ] || continue + # Check to make sure it's worth the processing. + grep -q "^Exec.*$base" "$file" || continue + # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop"). + grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + if [ x"`readlink -f "$command"`" = x"$binary" ]; then + # Fix any double slashes that got added path composition + echo "$file" | sed -e 's,//*,/,g' + return + fi + done + done +} + +#------------------------------------------------------------- +# map a .desktop file to a binary +## FIXME: handle vendor dir case +desktop_file_to_binary() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + desktop="`basename "$1"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] && [ -d "$dir/applications" ] || continue + file="$dir/applications/$desktop" + [ -r "$file" ] || continue + # Remove any arguments (%F, %f, %U, %u, etc.). + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + readlink -f "$command" + return + done +} + #------------------------------------------------------------- # Exit script on successfully completing the desired operation @@ -237,7 +323,7 @@ [ -n "$file_label" ] || file_label="filename" file=`basename "$1"` case "$file" in - [a-zA-Z]*-*) + [[:alpha:]]*-*) return ;; esac @@ -259,7 +345,7 @@ fi else DIR=`dirname "$1"` - if [ ! -w "$DIR" -o ! -x "$DIR" ]; then + if [ ! -w "$DIR" ] || [ ! -x "$DIR" ]; then exit_failure_file_permission_write "no permission to create file '$1'" fi fi @@ -287,7 +373,7 @@ ;; --version) - echo "xdg-settings 1.1.0 rc1" + echo "xdg-settings 1.1.0 rc3" exit_success ;; esac @@ -311,12 +397,86 @@ detectDE() { - if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; - elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; - elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; - elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; - elif [ x"$DESKTOP_SESSION" == x"LXDE" ]; then DE=lxde; - else DE="" + # see https://bugs.freedesktop.org/show_bug.cgi?id=34164 + unset GREP_OPTIONS + + if [ -n "${XDG_CURRENT_DESKTOP}" ]; then + case "${XDG_CURRENT_DESKTOP}" in + # only recently added to menu-spec, pre-spec X- still in use + Cinnamon|X-Cinnamon) + DE=cinnamon; + ;; + ENLIGHTENMENT) + DE=enlightenment; + ;; + # GNOME, GNOME-Classic:GNOME, or GNOME-Flashback:GNOME + GNOME*) + DE=gnome; + ;; + KDE) + DE=kde; + ;; + LXDE) + DE=lxde; + ;; + MATE) + DE=mate; + ;; + XFCE) + DE=xfce + ;; + X-Generic) + DE=generic + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # classic fallbacks + if [ x"$KDE_FULL_SESSION" != x"" ]; then DE=kde; + elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; + elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then DE=mate; + elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; + elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; + elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce + elif echo $DESKTOP | grep -q '^Enlightenment'; then DE=enlightenment; + fi + fi + + if [ x"$DE" = x"" ]; then + # fallback to checking $DESKTOP_SESSION + case "$DESKTOP_SESSION" in + gnome) + DE=gnome; + ;; + LXDE|Lubuntu) + DE=lxde; + ;; + MATE) + DE=mate; + ;; + xfce|xfce4|'Xfce Session') + DE=xfce; + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # fallback to uname output for other platforms + case "$(uname 2>/dev/null)" in + CYGWIN*) + DE=cygwin; + ;; + Darwin) + DE=darwin; + ;; + esac + fi + + if [ x"$DE" = x"gnome" ]; then + # gnome-default-applications-properties is only available in GNOME 2.x + # but not in GNOME 3.x + which gnome-default-applications-properties > /dev/null 2>&1 || DE="gnome3" fi } @@ -327,7 +487,6 @@ kfmclient_fix_exit_code() { - [ x"$KDE_SESSION_VERSION" = x"4" ] && return 0; version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'` major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'` minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'` @@ -356,59 +515,6 @@ # {{{ default browser # {{{ utility functions -# This handles backslashes but not quote marks. -first_word() -{ - read first rest - echo "$first" -} - -binary_to_desktop_file() -{ - search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" - binary="`which "$1"`" - binary="`readlink -f "$binary"`" - base="`basename "$binary"`" - IFS=: - for dir in $search; do - unset IFS - [ "$dir" ] || continue - [ -d "$dir/applications" -o -d "$dir/applnk" ] || continue - for file in "$dir"/applications/*.desktop "$dir"/applnk/*.desktop; do - [ -r "$file" ] || continue - # Check to make sure it's worth the processing. - grep -q "^Exec.*$base" "$file" || continue - # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop"). - grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue - command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" - command="`which "$command"`" - if [ x"`readlink -f "$command"`" = x"$binary" ]; then - # Fix any double slashes that got added path composition - echo "$file" | sed -e 's,//*,/,g' - return - fi - done - done -} - -desktop_file_to_binary() -{ - search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" - desktop="`basename "$1"`" - IFS=: - for dir in $search; do - unset IFS - [ "$dir" -a -d "$dir/applications" ] || continue - file="$dir/applications/$desktop" - [ -r "$file" ] || continue - # Remove any arguments (%F, %f, %U, %u, etc.). - command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" - command="`which "$command"`" - readlink -f "$command" - return - done -} - # In order to remove an application from the automatically-generated list of # applications for handling a given MIME type, the desktop environment may copy # the global .desktop file into the user's .local directory, and remove that @@ -419,21 +525,26 @@ # This function is hard-coded for text/html but it could be adapted if needed. fix_local_desktop_file() { + if test -z "$2" ; then + MIME="text/html" + else + MIME="$2" + fi apps="${XDG_DATA_HOME:-$HOME/.local/share}/applications" # No local desktop file? [ ! -f "$apps/$1" ] && return - MIME="`grep "^MimeType=" "$apps/$1" | cut -d= -f 2-`" - case "$MIME" in - text/html\;*|*\;text/html\;*|*\;text/html\;|*\;text/html) - # Already has text/html? Great! + MIMETYPES="`grep "^MimeType=" "$apps/$1" | cut -d= -f 2-`" + case "$MIMETYPES" in + $MIME\;*|*\;$MIME\;*|*\;$MIME\;|*\;$MIME) + # Already has the mime-type? Great! return 0 ;; esac - # Add text/html to the list + # Add the mime-type to the list temp="`mktemp "$apps/$1.XXXXXX"`" || return grep -v "^MimeType=" "$apps/$1" >> "$temp" - echo "MimeType=text/html;$MIME" >> "$temp" + echo "MimeType=$MIME;$MIMETYPES" >> "$temp" oldlines="`wc -l < "$apps/$1"`" newlines="`wc -l < "$temp"`" @@ -467,27 +578,67 @@ get_browser_mime() { + if test -z "$1" ; then + MIME="text/html" + else + MIME="$1" + fi xdg_mime_fixup - xdg-mime query default text/html + xdg-mime query default "$MIME" } set_browser_mime() { xdg_mime_fixup - orig="`get_browser_mime`" + if test -z "$2" ; then + MIME="text/html" + else + MIME="$2" + fi + orig="`get_browser_mime $MIME`" # Fixing the local desktop file can actually change the default browser all # by itself, so we fix it only after querying to find the current default. - fix_local_desktop_file "$1" || return + fix_local_desktop_file "$1" "$MIME" || return mkdir -p "${XDG_DATA_HOME:-$HOME/.local/share}/applications" - xdg-mime default "$1" text/html || return + xdg-mime default "$1" "$MIME" || return if [ x"`get_browser_mime`" != x"$1" ]; then # Put back the original value - xdg-mime default "$orig" text/html + xdg-mime default "$orig" "$MIME" exit_failure_operation_failed fi } # }}} MIME utilities +# {{{ KDE utilities + +# Reads the KDE configuration setting, compensating for a bug in some versions of kreadconfig. +read_kde_config() +{ + configfile="$1" + configsection="$2" + configkey="$3" + if [ x"${KDE_SESSION_VERSION}" = x"5" ]; then + application="`kreadconfig5 --file $configfile --group $configsection --key $configkey`" + else + application="`kreadconfig --file $configfile --group $configsection --key $configkey`" + fi + if [ x"$application" != x ]; then + echo "$application" + else + if [ x"${KDE_SESSION_VERSION}" = x"4" ]; then + # kreadconfig in KDE 4 may not notice Key[$*]=... localized settings, so + # check by hand if it didn't find anything (oddly kwriteconfig works + # fine though). + configfile_dir=`kde${KDE_SESSION_VERSION}-config --path config | cut -d ':' -f 1` + configfile_path="$configfile_dir/$configfile" + [ ! -f "$configfile_path" ] && return + # This will only take the first value if there is more than one. + grep "^$configkey"'\[$[^]=]*\]=' "$configfile_path" | head -n 1 | cut -d= -f 2- + fi + fi +} + +# }}} KDE utilities # {{{ KDE # Resolves the KDE browser setting to a binary: if prefixed with !, simply removes it; @@ -521,22 +672,9 @@ esac } -# Reads the KDE browser setting, compensating for a bug in some versions of kreadconfig. read_kde_browser() { - browser="`kreadconfig --file kdeglobals --group General --key BrowserApplication`" - if [ x"$browser" != x ]; then - echo "$browser" - else - # kreadconfig in KDE 4 may not notice Key[$*]=... localized settings, so - # check by hand if it didn't find anything (oddly kwriteconfig works - # fine though). - kdeglobals_dir=`kde${KDE_SESSION_VERSION}-config --path config | cut -d ':' -f 1` - kdeglobals="$kdeglobals_dir/kdeglobals" - [ ! -f "$kdeglobals" ] && return - # This will only take the first value if there is more than one. - grep '^BrowserApplication\[$[^]=]*\]=' "$kdeglobals" | head -n 1 | cut -d= -f 2- - fi + read_kde_config kdeglobals General BrowserApplication } get_browser_kde() @@ -578,7 +716,11 @@ set_browser_kde() { set_browser_mime "$1" || return - kwriteconfig --file kdeglobals --group General --key BrowserApplication "$1" + if [ x"${KDE_SESSION_VERSION}" = x"5" ]; then + kwriteconfig5 --file kdeglobals --group General --key BrowserApplication "$1" + else + kwriteconfig --file kdeglobals --group General --key BrowserApplication "$1" + fi } # }}} KDE @@ -652,6 +794,45 @@ } # }}} GNOME +# {{{ GNOME 3.x + +get_browser_gnome3() +{ + get_browser_mime "x-scheme-handler/http" +} + +check_browser_gnome3() +{ + desktop="$1" + check="`desktop_file_to_binary "$1"`" + if [ -z "$check" ]; then + echo no + exit_success + fi + # Check HTTP and HTTPS, but not about: and unknown:. + for protocol in http https; do + browser="`get_browser_mime "x-scheme-handler/$protocol"`" + if [ x"$browser" != x"$desktop" ]; then + echo no + exit_success + fi + done + echo yes + exit_success +} + +set_browser_gnome3() +{ + binary="`desktop_file_to_binary "$1"`" + [ "$binary" ] || exit_failure_file_missing + set_browser_mime "$1" || return + + # Set the default browser. + for protocol in http https about unknown; do + set_browser_mime "$1" "x-scheme-handler/$protocol" || return + done +} +# }}} GNOME 3.x # {{{ xfce get_browser_xfce() @@ -660,7 +841,7 @@ IFS=: for dir in $search; do unset IFS - [ "$dir" -a -d "$dir/xfce4" ] || continue + [ "$dir" ] && [ -d "$dir/xfce4" ] || continue file="$dir/xfce4/helpers.rc" [ -r "$file" ] || continue grep -q "^WebBrowser=" "$file" || continue @@ -693,7 +874,7 @@ IFS=: for dir in $search; do unset IFS - [ "$dir" -a -d "$dir/xfce4/helpers" ] || continue + [ "$dir" ] && [ -d "$dir/xfce4/helpers" ] || continue file="$dir/xfce4/helpers/$1" # We have the file, no need to create it. [ -r "$file" ] && return @@ -701,19 +882,21 @@ IFS=: for dir in $search; do unset IFS - [ "$dir" -a -d "$dir/applications" ] || continue + [ "$dir" ] && [ -d "$dir/applications" ] || continue file="$dir/applications/$1" if [ -r "$file" ]; then # Found a file to convert. target="${XDG_DATA_HOME:-$HOME/.local/share}/xfce4/helpers" mkdir -p "$target" - grep -v "^Type=" "$file" > "$target/$1" - echo "Type=X-XFCE-Helper" >> "$target/$1" + # Copy file up to first "Exec=" line. + sed -e 's/^Type=.*/Type=X-XFCE-Helper/' -e '/^Exec[=[]/,$d' "$file" > "$target/$1" echo "X-XFCE-Category=WebBrowser" >> "$target/$1" # Change %F, %f, %U, and %u to "%s". - command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | sed -e 's/%[FfUu]/"%s"/g'`" + command=$(grep -E '^Exec(\[[^]=]*])?=' "$file" | cut -d= -f 2- | sed -e 's/%[FfUu]/"%s"/g' | head -1) echo "X-XFCE-Commands=`echo "$command" | first_word`" >> "$target/$1" echo "X-XFCE-CommandsWithParameter=$command" >> "$target/$1" + # Copy rest of file (from first "Exec=" line to end-of-file). + sed -n -e 's/^Type=.*/Type=X-XFCE-Helper/' -e '/^Exec[=[]/,$p' "$file" >> "$target/$1" return fi done @@ -751,17 +934,304 @@ } # }}} xfce +# {{{ generic + +get_browser_generic() +{ + if [ -n "$BROWSER" ]; then + local browser=$(binary_to_desktop_file "${BROWSER%%:*}") + if [ -n "$browser" ]; then + echo "$(basename "$browser")" + return 0 + fi + fi + + if get_browser_mime x-scheme-handler/http; then + return 0 + fi + + # Debian and derivatives have x-www-browser + local browser=$(binary_to_desktop_file x-www-browser) + if [ -n "$browser" ]; then + echo "$(basename "$browser")" + return 0 + fi + + return 4 +} + +check_browser_generic() +{ + local desktop="$1" + + # Check HTTP + if [ "$desktop" != "$(get_browser_generic)" ]; then + echo no + exit_success + fi + + # Check text/html + if [ "$desktop" != "$(get_browser_mime)" ]; then + echo no + exit_success + fi + + # Check HTTPS + if [ "$desktop" != "$(get_url_scheme_handler_generic https)" ]; then + echo no + exit_success + fi + + echo yes + exit_success +} + +set_browser_generic() +{ + if [ -n "$BROWSER" ]; then + exit_failure_operation_failed \ + "\$BROWSER is set and can't be changed with xdg-settings" + fi + + binary=$(desktop_file_to_binary "$1") + [ -n "$binary" ] || exit_failure_file_missing + + set_browser_mime "$1" text/html || return + + for protocol in http https about unknown; do + set_browser_mime "$1" "x-scheme-handler/$protocol" || return + done +} +# }}} generic # }}} default browser +# {{{ default url scheme handler + +exit_unimplemented_default_handler() +{ + exit_failure_operation_impossible "default-url-scheme-handler not implemented for $DE" +} + +# {{{ KDE + +# Recent versions of KDE support default scheme handler applications using the +# mime type of x-scheme-handler/scheme. Older versions will not support this +# but do have support for setting a default mail handler. There is also a +# system in KDE where .protocol files can be used, however this is not +# supported by this script. When reading a scheme handler we will use the +# default mail handler for the mailto scheme, otherwise we will use the mime +# type x-scheme-handler/scheme. + +get_url_scheme_handler_kde() +{ + if [ "$1" = "mailto" ]; then + handler="`read_kde_config emaildefaults PROFILE_Default EmailClient | first_word`" + echo "handler is $handler" + if [ x"$handler" != x ]; then + binary_to_desktop_file "$handler" + else + get_browser_mime "x-scheme-handler/$1" + fi + else + get_browser_mime "x-scheme-handler/$1" + fi +} + +check_url_scheme_handler_kde() +{ + check="`desktop_file_to_binary "$2"`" + if [ -z "$check" ]; then + echo no + exit_success + fi + if [ x"$1" = "mailto" ]; then + binary="`read_kde_config emaildefaults PROFILE_Default EmailClient`" + if [ x"$binary" != x"$check" ]; then + echo no + exit_success + fi + fi + handler="`get_browser_mime x-scheme-handler/$1`" + binary="`desktop_file_to_binary "$handler"`" + if [ x"$binary" != x"$check" ]; then + echo no + exit_success + fi + echo yes + exit_success +} + +set_url_scheme_handler_kde() +{ + set_browser_mime "$2" "x-scheme-handler/$1" || return + if [ "$1" = "mailto" ]; then + binary="`desktop_file_to_binary "$2"`" + if [ x"${KDE_SESSION_VERSION}" = x"5" ]; then + kwriteconfig5 --file emaildefaults --group PROFILE_Default --key EmailClient "$binary" + else + kwriteconfig --file emaildefaults --group PROFILE_Default --key EmailClient "$binary" + fi + fi +} + +# }}} KDE +# {{{ GNOME + +get_url_scheme_handler_gnome() +{ + binary="`gconftool-2 --get /desktop/gnome/url-handlers/$1/command | first_word`" + if [ x"$binary" != x"" ]; then + # gconftool gives the binary (maybe with %s etc. afterward), + # but we want the desktop file name, not the binary. So, we + # have to find the desktop file to which it corresponds. + desktop="`binary_to_desktop_file "$binary"`" + basename "$desktop" + fi +} + +check_url_scheme_handler_gnome() +{ + check="`desktop_file_to_binary "$2"`" + if [ -z "$check" ]; then + echo no + exit_success + fi + binary="`gconftool-2 --get /desktop/gnome/url-handlers/$1/command | first_word`" + if [ x"$binary" != x"$check" ]; then + echo no + exit_success + fi + echo yes + exit_success +} + +set_url_scheme_handler_gnome() +{ + binary="`desktop_file_to_binary "$2"`" + [ "$binary" ] || exit_failure_file_missing + + gconftool-2 --type string --set /desktop/gnome/url-handlers/$1/command "$binary %s" + gconftool-2 --type bool --set /desktop/gnome/url-handlers/$1/needs_terminal false + gconftool-2 --type bool --set /desktop/gnome/url-handlers/$1/enabled true +} + +# }}} GNOME +# {{{ GNOME 3.x + +get_url_scheme_handler_gnome3() +{ + get_browser_mime "x-scheme-handler/$1" +} + +check_url_scheme_handler_gnome3() +{ + desktop="$2" + check="`desktop_file_to_binary "$2"`" + if [ -z "$check" ]; then + echo no + exit_success + fi + browser="`get_browser_mime "x-scheme-handler/$1"`" + if [ x"$browser" != x"$desktop" ]; then + echo no + exit_success + fi + echo yes + exit_success +} + +set_url_scheme_handler_gnome3() +{ + binary="`desktop_file_to_binary "$2"`" + [ "$binary" ] || exit_failure_file_missing + set_browser_mime "$2" || return + + # Set the default browser. + set_browser_mime "$2" "x-scheme-handler/$1" || return +} + +# }}} GNOME 3.x +# {{{ xfce + +get_url_scheme_handler_xfce() +{ + exit_unimplemented_default_handler "$1" +} + +check_url_scheme_handler_xfce() +{ + exit_unimplemented_default_handler "$1" +} + +set_url_scheme_handler_xfce() +{ + exit_unimplemented_default_handler "$1" +} + +# }}} xfce +# {{{ generic + +get_url_scheme_handler_generic() +{ + if [ -n "$BROWSER" ] && ([ "$1" = http ] || [ "$1" = https ]); then + get_browser_generic + else + get_browser_mime "x-scheme-handler/$1" + fi +} + +check_url_scheme_handler_generic() +{ + local scheme="$1" desktop="$2" + + if [ -z "$(desktop_file_to_binary "$desktop")" ]; then + echo no + exit_success + fi + + local browser=$(get_url_scheme_handler_generic "$scheme") + if [ "$browser" != "$desktop" ]; then + echo no + exit_success + fi + echo yes + exit_success +} + +set_url_scheme_handler_generic() +{ + local scheme="$1" desktop="$2" + + if [ -n "$BROWSER" ] && \ + ([ "$scheme" = http ] || [ "$scheme" = https ]); then + exit_failure_operation_failed \ + "\$BROWSER is set and can't be changed with xdg-settings" + fi + + if [ -z "$(desktop_file_to_binary "$desktop")" ]; then + exit_failure_file_missing + fi + + set_browser_mime "$desktop" "x-scheme-handler/$scheme" +} + +# }}} generic +# }}} default protocol handler + dispatch_specific() { + local handler=$1; shift # The PROP comments in this function are used to generate the output of # the --list option. The formatting is important. Make sure to line up the # property descriptions with spaces so that it will look nice. if [ x"$op" = x"get" ]; then case "$parm" in default-web-browser) # PROP: Default web browser - get_browser_$DE + get_browser_$handler + ;; + + default-url-scheme-handler) # PROP: Default handler for URL scheme + get_url_scheme_handler_$handler "$1" ;; *) @@ -772,7 +1242,12 @@ case "$parm" in default-web-browser) check_desktop_filename "$1" - check_browser_$DE "$1" + check_browser_$handler "$1" + ;; + + default-url-scheme-handler) + check_desktop_filename "$2" + check_url_scheme_handler_$handler "$1" "$2" ;; *) @@ -780,11 +1255,17 @@ ;; esac else # set - [ $# -eq 1 ] || exit_failure_syntax "unexpected/missing argument" case "$parm" in default-web-browser) + [ $# -eq 1 ] || exit_failure_syntax "unexpected/missing argument" check_desktop_filename "$1" - set_browser_$DE "$1" + set_browser_$handler "$1" + ;; + + default-url-scheme-handler) + [ $# -eq 2 ] || exit_failure_syntax "unexpected/missing argument" + check_desktop_filename "$2" + set_url_scheme_handler_$handler "$1" "$2" ;; *) @@ -800,45 +1281,6 @@ fi } -dispatch_generic() -{ - # We only know how to get or check the default web browser. - [ x"$op" != x"get" -a x"$op" != x"check" ] && exit_failure_operation_impossible - [ x"$parm" != x"default-web-browser" ] && exit_failure_operation_impossible - - # First look in $BROWSER - if [ x"$BROWSER" != x ]; then - binary="`which "${BROWSER%%:*}"`" - else - # Debian and Ubuntu (and others?) have x-www-browser. - binary="`which x-www-browser`" - fi - - [ "$binary" ] || exit_failure_operation_failed - - binary="`readlink -f "$binary"`" - - [ "$binary" ] || exit_failure_operation_failed - - if [ x"$op" = x"get" ]; then - desktop="`binary_to_desktop_file "$binary"`" - basename "$desktop" - else - # $op = "check" - check="`desktop_file_to_binary "$1"`" - if [ -z "$check" ]; then - echo no - exit_success - fi - if [ x"$binary" != x"$check" ]; then - echo no - exit_success - fi - echo yes - fi - exit_success -} - if [ x"$1" = x"--list" ]; then echo "Known properties:" # Extract the property names from dispatch_specific() above. @@ -860,13 +1302,29 @@ detectDE +if [ -z "$DE" ]; then + DE=generic +fi + case "$DE" in - kde|gnome|xfce) - dispatch_specific "$@" + kde) + dispatch_specific kde "$@" + ;; + + gnome) + dispatch_specific gnome "$@" + ;; + + gnome3|cinnamon|lxde|mate) + dispatch_specific gnome3 "$@" + ;; + + xfce) + dispatch_specific xfce "$@" ;; generic) - dispatch_generic "$@" + dispatch_specific generic "$@" ;; *) diff -Nru gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-su gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-su --- gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-su 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-su 1970-01-01 00:00:00.000000000 +0000 @@ -1,438 +0,0 @@ -#!/bin/sh -#--------------------------------------------- -# xdg-su -# -# Utility script to run a command as an alternate user, generally -# the root user, with a graphical prompt for the root -# password if needed -# -# Refer to the usage() function below for usage. -# -# Copyright 2006, Jeremy White -# Copyright 2006, Kevin Krammer -# -# LICENSE: -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the "Software"), -# to deal in the Software without restriction, including without limitation -# the rights to use, copy, modify, merge, publish, distribute, sublicense, -# and/or sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. -# -#--------------------------------------------- - -manualpage() -{ -cat << _MANUALPAGE -Name - -xdg-su - run a GUI program as root after prompting for the root password - -Synopsis - -xdg-su [-u user] -c command - -xdg-su { --help | --manual | --version } - -Description - -xdg-su provides a graphical dialog that prompts the user for a password to run -command as user or as root if no user was specified. - -xdg-su is for use inside a desktop session only. - -xdg-su discards any stdout and stderr output from command. - -Options - --u user - run command as user. The default is to run as root. ---help - Show command synopsis. ---manual - Show this manualpage. ---version - Show the xdg-utils version information. - -Exit Codes - -An exit code of 0 indicates success while a non-zero exit code indicates -failure. The following failure codes can be returned: - -1 - Error in command line syntax. -2 - One of the files passed on the command line did not exist. -3 - A required tool could not be found. -4 - The action failed. - -See Also - -su(1) - -Examples - -xdg-su -u root -c "/opt/shinythings/bin/install-GUI --install fast" - -Runs the /opt/shinythings/bin/install-GUI command with root permissions. - -_MANUALPAGE -} - -usage() -{ -cat << _USAGE -xdg-su - run a GUI program as root after prompting for the root password - -Synopsis - -xdg-su [-u user] -c command - -xdg-su { --help | --manual | --version } - -_USAGE -} - -#@xdg-utils-common@ - -#---------------------------------------------------------------------------- -# Common utility functions included in all XDG wrapper scripts -#---------------------------------------------------------------------------- - -DEBUG() -{ - [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt $1 ] && return 0; - shift - echo "$@" >&2 -} - -#------------------------------------------------------------- -# Exit script on successfully completing the desired operation - -exit_success() -{ - if [ $# -gt 0 ]; then - echo "$@" - echo - fi - - exit 0 -} - - -#----------------------------------------- -# Exit script on malformed arguments, not enough arguments -# or missing required option. -# prints usage information - -exit_failure_syntax() -{ - if [ $# -gt 0 ]; then - echo "xdg-su: $@" >&2 - echo "Try 'xdg-su --help' for more information." >&2 - else - usage - echo "Use 'man xdg-su' or 'xdg-su --manual' for additional info." - fi - - exit 1 -} - -#------------------------------------------------------------- -# Exit script on missing file specified on command line - -exit_failure_file_missing() -{ - if [ $# -gt 0 ]; then - echo "xdg-su: $@" >&2 - fi - - exit 2 -} - -#------------------------------------------------------------- -# Exit script on failure to locate necessary tool applications - -exit_failure_operation_impossible() -{ - if [ $# -gt 0 ]; then - echo "xdg-su: $@" >&2 - fi - - exit 3 -} - -#------------------------------------------------------------- -# Exit script on failure returned by a tool application - -exit_failure_operation_failed() -{ - if [ $# -gt 0 ]; then - echo "xdg-su: $@" >&2 - fi - - exit 4 -} - -#------------------------------------------------------------ -# Exit script on insufficient permission to read a specified file - -exit_failure_file_permission_read() -{ - if [ $# -gt 0 ]; then - echo "xdg-su: $@" >&2 - fi - - exit 5 -} - -#------------------------------------------------------------ -# Exit script on insufficient permission to read a specified file - -exit_failure_file_permission_write() -{ - if [ $# -gt 0 ]; then - echo "xdg-su: $@" >&2 - fi - - exit 6 -} - -check_input_file() -{ - if [ ! -e "$1" ]; then - exit_failure_file_missing "file '$1' does not exist" - fi - if [ ! -r "$1" ]; then - exit_failure_file_permission_read "no permission to read file '$1'" - fi -} - -check_vendor_prefix() -{ - file=`basename "$1"` - case "$file" in - [a-zA-Z]*-*) - return - ;; - esac - - echo "xdg-su: filename '$file' does not have a proper vendor prefix" >&2 - echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2 - echo 'with a dash ("-"). An example filename is '"'example-$file'" >&2 - echo "Use --novendor to override or 'xdg-su --manual' for additional info." >&2 - exit 1 -} - -check_output_file() -{ - # if the file exists, check if it is writeable - # if it does not exists, check if we are allowed to write on the directory - if [ -e "$1" ]; then - if [ ! -w "$1" ]; then - exit_failure_file_permission_write "no permission to write to file '$1'" - fi - else - DIR=`dirname "$1"` - if [ ! -w "$DIR" -o ! -x "$DIR" ]; then - exit_failure_file_permission_write "no permission to create file '$1'" - fi - fi -} - -#---------------------------------------- -# Checks for shared commands, e.g. --help - -check_common_commands() -{ - while [ $# -gt 0 ] ; do - parm="$1" - shift - - case "$parm" in - --help) - usage - echo "Use 'man xdg-su' or 'xdg-su --manual' for additional info." - exit_success - ;; - - --manual) - manualpage - exit_success - ;; - - --version) - echo "xdg-su 1.0beta2" - exit_success - ;; - esac - done -} - -check_common_commands "$@" -if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then - # Be silent - xdg_redirect_output=" > /dev/null 2> /dev/null" -else - # All output to stderr - xdg_redirect_output=" >&2" -fi - -#-------------------------------------- -# Checks for known desktop environments -# set variable DE to the desktop environments name, lowercase - -detectDE() -{ - if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; - elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; - elif xprop -root _DT_SAVE_MODE | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; - fi -} - -#---------------------------------------------------------------------------- - - - -su_kde() -{ - if [ x"$KDE_SESSION_VERSION" = x"4" ]; then - KDESU=`kde4-config --locate kdesu --path exe 2>/dev/null` - else - KDESU=`which kdesu 2>/dev/null` - fi - if [ $? -eq 0 ] ; then - if [ -z "$user" ] ; then - $KDESU -c "$cmd" - else - $KDESU -u "$user" -c "$cmd" - fi - - if [ $? -eq 0 ]; then - exit_success - else - exit_failure_operation_failed - fi - else - su_generic - fi -} - -su_gnome() -{ - GSU=`which gnomesu 2>/dev/null` - if [ $? -ne 0 ] ; then - GSU=`which xsu 2>/dev/null` - fi - if [ $? -eq 0 ] ; then - if [ -z "$user" ] ; then - $GSU -c "$cmd" - else - $GSU -u "$user" -c "$cmd" - fi - - if [ $? -eq 0 ]; then - exit_success - else - exit_failure_operation_failed - fi - else - su_generic - fi -} - -su_generic() -{ - if [ -z "$user" ] ; then - xterm -geom 60x5 -T "xdg-su: $cmd" -e su -c "$cmd" - else - xterm -geom 60x5 -T "xdg-su: $cmd" -e su -c "$cmd" "$user" - fi - - if [ $? -eq 0 ]; then - exit_success - else - exit_failure_operation_failed - fi -} - -[ x"$1" != x"" ] || exit_failure_syntax - -user= -cmd= -while [ $# -gt 0 ] ; do - parm="$1" - shift - - case "$parm" in - -u) - if [ -z "$1" ] ; then - exit_failure_syntax "user argument missing for -u" - fi - user="$1" - shift - ;; - - -c) - if [ -z "$1" ] ; then - exit_failure_syntax "command argument missing for -c" - fi - cmd="$1" - shift - ;; - - -*) - exit_failure_syntax "unexpected option '$parm'" - ;; - - *) - exit_failure_syntax "unexpected argument '$parm'" - ;; - esac -done - -if [ -z "${cmd}" ] ; then - exit_failure_syntax "command missing" -fi - -detectDE - -if [ x"$DE" = x"" ]; then - XSU=`which xsu 2>/dev/null` - if [ $? -eq 0 ] ; then - DE=generic - fi -fi - -case "$DE" in - kde) - su_kde - ;; - - gnome) - su_gnome - ;; - - generic) - su_generic - ;; - - *) - [ x"$user" = x"" ] && user=root - exit_failure_operation_impossible "no graphical method available for invoking '$cmd' as '$user'" - ;; -esac diff -Nru gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-terminal gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-terminal --- gambas3-3.8.3/comp/src/gb.desktop/xdg-utils/xdg-terminal 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.desktop/xdg-utils/xdg-terminal 1970-01-01 00:00:00.000000000 +0000 @@ -1,484 +0,0 @@ -#!/bin/sh -#--------------------------------------------- -# xdg-terminal -# -# Utility script to open the registered terminal emulator -# -# Refer to the usage() function below for usage. -# -# Copyright 2009-2010, Fathi Boudra -# Copyright 2009-2010, Rex Dieter -# Copyright 2006, Kevin Krammer -# -# LICENSE: -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the "Software"), -# to deal in the Software without restriction, including without limitation -# the rights to use, copy, modify, merge, publish, distribute, sublicense, -# and/or sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. -# -#--------------------------------------------- - -manualpage() -{ -cat << _MANUALPAGE -Name - -xdg-terminal - opens the user's preferred terminal emulator application - -Synopsis - -xdg-terminal [command] - -xdg-terminal { --help | --manual | --version } - -Description - -xdg-terminal opens the user's preferred terminal emulator application. If a -command is provided the command will be executed by the shell within the newly -opened terminal window. - -xdg-terminal is for use inside a desktop session only. It is not recommended to -use xdg-terminal as root. - -Options - ---help - Show command synopsis. ---manual - Show this manualpage. ---version - Show the xdg-utils version information. - -Exit Codes - -An exit code of 0 indicates success while a non-zero exit code indicates -failure. The following failure codes can be returned: - -1 - Error in command line syntax. -3 - A required tool could not be found. -4 - The action failed. - -Examples - -xdg-terminal - -Opens the user's default terminal emulator, just starting an interactive shell. - -xdg-terminal top - -Opens the user's default terminal emulator and lets it run the top executable. - -_MANUALPAGE -} - -usage() -{ -cat << _USAGE -xdg-terminal - opens the user's preferred terminal emulator application - -Synopsis - -xdg-terminal [command] - -xdg-terminal { --help | --manual | --version } - -_USAGE -} - -#@xdg-utils-common@ - -#---------------------------------------------------------------------------- -# Common utility functions included in all XDG wrapper scripts -#---------------------------------------------------------------------------- - -DEBUG() -{ - [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0; - [ ${XDG_UTILS_DEBUG_LEVEL} -lt $1 ] && return 0; - shift - echo "$@" >&2 -} - -#------------------------------------------------------------- -# Exit script on successfully completing the desired operation - -exit_success() -{ - if [ $# -gt 0 ]; then - echo "$@" - echo - fi - - exit 0 -} - - -#----------------------------------------- -# Exit script on malformed arguments, not enough arguments -# or missing required option. -# prints usage information - -exit_failure_syntax() -{ - if [ $# -gt 0 ]; then - echo "xdg-terminal: $@" >&2 - echo "Try 'xdg-terminal --help' for more information." >&2 - else - usage - echo "Use 'man xdg-terminal' or 'xdg-terminal --manual' for additional info." - fi - - exit 1 -} - -#------------------------------------------------------------- -# Exit script on missing file specified on command line - -exit_failure_file_missing() -{ - if [ $# -gt 0 ]; then - echo "xdg-terminal: $@" >&2 - fi - - exit 2 -} - -#------------------------------------------------------------- -# Exit script on failure to locate necessary tool applications - -exit_failure_operation_impossible() -{ - if [ $# -gt 0 ]; then - echo "xdg-terminal: $@" >&2 - fi - - exit 3 -} - -#------------------------------------------------------------- -# Exit script on failure returned by a tool application - -exit_failure_operation_failed() -{ - if [ $# -gt 0 ]; then - echo "xdg-terminal: $@" >&2 - fi - - exit 4 -} - -#------------------------------------------------------------ -# Exit script on insufficient permission to read a specified file - -exit_failure_file_permission_read() -{ - if [ $# -gt 0 ]; then - echo "xdg-terminal: $@" >&2 - fi - - exit 5 -} - -#------------------------------------------------------------ -# Exit script on insufficient permission to write a specified file - -exit_failure_file_permission_write() -{ - if [ $# -gt 0 ]; then - echo "xdg-terminal: $@" >&2 - fi - - exit 6 -} - -check_input_file() -{ - if [ ! -e "$1" ]; then - exit_failure_file_missing "file '$1' does not exist" - fi - if [ ! -r "$1" ]; then - exit_failure_file_permission_read "no permission to read file '$1'" - fi -} - -check_vendor_prefix() -{ - file_label="$2" - [ -n "$file_label" ] || file_label="filename" - file=`basename "$1"` - case "$file" in - [a-zA-Z]*-*) - return - ;; - esac - - echo "xdg-terminal: $file_label '$file' does not have a proper vendor prefix" >&2 - echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2 - echo 'with a dash ("-"). An example '"$file_label"' is '"'example-$file'" >&2 - echo "Use --novendor to override or 'xdg-terminal --manual' for additional info." >&2 - exit 1 -} - -check_output_file() -{ - # if the file exists, check if it is writeable - # if it does not exists, check if we are allowed to write on the directory - if [ -e "$1" ]; then - if [ ! -w "$1" ]; then - exit_failure_file_permission_write "no permission to write to file '$1'" - fi - else - DIR=`dirname "$1"` - if [ ! -w "$DIR" -o ! -x "$DIR" ]; then - exit_failure_file_permission_write "no permission to create file '$1'" - fi - fi -} - -#---------------------------------------- -# Checks for shared commands, e.g. --help - -check_common_commands() -{ - while [ $# -gt 0 ] ; do - parm="$1" - shift - - case "$parm" in - --help) - usage - echo "Use 'man xdg-terminal' or 'xdg-terminal --manual' for additional info." - exit_success - ;; - - --manual) - manualpage - exit_success - ;; - - --version) - echo "xdg-terminal 1.0.2" - exit_success - ;; - esac - done -} - -check_common_commands "$@" - -[ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL; -if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then - # Be silent - xdg_redirect_output=" > /dev/null 2> /dev/null" -else - # All output to stderr - xdg_redirect_output=" >&2" -fi - -#-------------------------------------- -# Checks for known desktop environments -# set variable DE to the desktop environments name, lowercase - -detectDE() -{ - if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; - elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; - elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; - elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; - elif [ x"$DESKTOP_SESSION" == x"LXDE" ]; then DE=lxde; - else DE="" - fi -} - -#---------------------------------------------------------------------------- -# kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4 -# It also always returns 1 in KDE 3.4 and earlier -# Simply return 0 in such case - -kfmclient_fix_exit_code() -{ - version=`kde${KDE_SESSION_VERSION}-config --version 2>/dev/null | grep '^KDE'` - major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'` - minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'` - release=`echo $version | sed 's/KDE.*: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/'` - test "$major" -gt 3 && return $1 - test "$minor" -gt 5 && return $1 - test "$release" -gt 4 && return $1 - return 0 -} - -terminal_kde() -{ - terminal=`kreadconfig --file kdeglobals --group General --key TerminalApplication --default konsole` - - terminal_exec=`which $terminal 2>/dev/null` - - if [ -x "$terminal_exec" ]; then - if [ x"$1" == x"" ]; then - $terminal_exec - else - $terminal_exec -e "$1" - fi - - if [ $? -eq 0 ]; then - exit_success - else - exit_failure_operation_failed - fi - else - exit_failure_operation_impossible "configured terminal program '$terminal' not found or not executable" - fi -} - -terminal_gnome() -{ - term_exec_key="/desktop/gnome/applications/terminal/exec" - term_exec_arg_key="/desktop/gnome/applications/terminal/exec_arg" - - term_exec=`gconftool-2 --get ${term_exec_key}` - term_exec_arg=`gconftool-2 --get ${term_exec_arg_key}` - - terminal_exec=`which $term_exec 2>/dev/null` - - if [ -x "$terminal_exec" ]; then - if [ x"$1" == x"" ]; then - $terminal_exec - else - if [ x"$term_exec_arg" == x"" ]; then - $terminal_exec "$1" - else - $terminal_exec "$term_exec_arg" "$1" - fi - fi - - if [ $? -eq 0 ]; then - exit_success - else - exit_failure_operation_failed - fi - else - exit_failure_operation_impossible "configured terminal program '$term_exec' not found or not executable" - fi -} - -terminal_xfce() -{ - if [ x"$1" == x"" ]; then - exo-open --launch TerminalEmulator - else - exo-open --launch TerminalEmulator "$1" - fi - - if [ $? -eq 0 ]; then - exit_success - else - exit_failure_operation_failed - fi -} - -terminal_generic() -{ - # if $TERM is not set, try xterm - if [ x"$TERM" == x"" ]; then - TERM=xterm - fi - - terminal_exec=`which $TERM >/dev/null 2>/dev/null` - - if [ -x "$terminal_exec" ]; then - if [ $? -eq 0 ]; then - exit_success - else - exit_failure_operation_failed - fi - else - exit_failure_operation_impossible "configured terminal program '$TERM' not found or not executable" - fi -} - -terminal_lxde() -{ - if which lxterminal &>/dev/null; then - if [ x"$1" == x"" ]; then - lxterminal - else - lxterminal -e "$1" - fi - else - terminal_generic "$1" - fi -} - -#[ x"$1" != x"" ] || exit_failure_syntax - -command= -while [ $# -gt 0 ] ; do - parm="$1" - shift - - case "$parm" in - -*) - exit_failure_syntax "unexpected option '$parm'" - ;; - - *) - if [ -n "$command" ] ; then - exit_failure_syntax "unexpected argument '$parm'" - fi - command="$parm" - ;; - esac -done - -detectDE - -if [ x"$DE" = x"" ]; then - # if TERM variable is not set, try xterm - if [ x"$TERM" = x"" ]; then - TERM=xterm - fi - DE=generic -fi - -case "$DE" in - kde) - terminal_kde "$command" - ;; - - gnome) - terminal_gnome "$command" - ;; - - xfce) - terminal_xfce "$command" - ;; - - lxde) - terminal_lxde "$command" - ;; - - generic) - terminal_generic "$command" - ;; - - *) - exit_failure_operation_impossible "no terminal emulator available" - ;; -esac diff -Nru gambas3-3.8.3/comp/src/gb.form/map/icon.map gambas3-3.8.4/comp/src/gb.form/map/icon.map --- gambas3-3.8.3/comp/src/gb.form/map/icon.map 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.form/map/icon.map 2015-12-22 04:46:12.000000000 +0000 @@ -1,18 +1,18 @@ access apps/preferences-desktop-accessibility add actions/list-add apply actions/dialog-apply;actions/dialog-ok-apply -archive [-breeze*]$(mime)/file-types-small/package-x-generic;$(mime)/package-x-generic;apps/utilities-file-archiver +archive $(mime)/package-x-generic;apps/utilities-file-archiver attach status/mail-attachment;actions/mail-attachment -audio [-breeze*]$(mime)/file-types-small/audio-x-generic;$(mime)/audio-x-generic +audio $(mime)/audio-x-generic battery devices/battery book [-breeze*]actions/address-book-new;apps/accessories-dictionary;# -bookmark [-breeze*]places/user-folders-small/bookmarks;places/bookmarks;actions/bookmark-new;places/user-bookmarks +bookmark places/bookmarks;actions/bookmark-new;places/user-bookmarks bottom actions/go-bottom calculator apps/accessories-calculator calendar actions/office-calendar;apps/evolution-calendar;actions/view-pim-calendar camera devices/camera-photo cancel actions/dialog-cancel -cdrom [-breeze*]devices/sidebars/media-optical;devices/media-optical +cdrom devices/media-optical clear actions/edit-clear-locationbar-rtl;actions/edit-clear clock apps/clock;actions/chronometer close actions/window-close @@ -24,9 +24,9 @@ copy actions/edit-copy cut actions/edit-cut delete actions/edit-delete -desktop [-breeze*]places/user-folders-small/user-desktop;places/user-desktop +desktop places/user-desktop development categories/applications-development -directory [-breeze*]places/user-folders-small/folder;places/folder +directory places/folder disconnect actions/network-disconnect down actions/go-down download [elementary]actions/media-import-audio-cd;emblems/emblem-downloads;actions/download @@ -36,7 +36,7 @@ erase actions/draw-eraser error status/dialog-error exec actions/system-run -file [-breeze*]$(mime)/file-types-small/application-x-zerosize;$(mime)/empty;$(mime)/application-x-zerosize +file [-breeze*]actions/document-new;$(mime)/empty;$(mime)/application-x-zerosize file-manager [-breeze*]apps/toolbar/system-file-manager;apps/system-file-manager fill actions/fill-color filter actions/view-filter @@ -55,13 +55,13 @@ grid actions/view-grid;actions/games-config-board group [-breeze*]actions/user-group-new;apps/system-users halt actions/process-stop -harddisk [-breeze*]devices/sidebars/drive-harddisk;devices/drive-harddisk +harddisk devices/drive-harddisk hardware devices/audio-card -help [-breeze*]apps/toolbar/system-help;apps/help-browser +help [breeze*]apps/system-help;apps/help-browser home actions/go-home -html [-breeze*]$(mime)/file-types-small/text-html;$(mime)/text-html +html $(mime)/text-html identity apps/user-info;apps/preferences-desktop-user -image [-breeze*]$(mime)/file-types-small/image-x-generic;$(mime)/image-x-generic +image $(mime)/image-x-generic important emblems/emblem-important indent actions/format-indent-more info status/dialog-information @@ -86,7 +86,7 @@ microphone devices/audio-input-microphone monitor [-breeze*]actions/view-statistics;apps/utilities-system-monitor mouse devices/input-mouse -multimedia [breeze*]apps/categories/applications-multimedia;categories/applications-multimedia +multimedia categories/applications-multimedia muted status/audio-volume-muted network status/network-connect;places/network-workgroup new actions/document-new @@ -96,13 +96,13 @@ office [elementary]categories/applications-other;categories/applications-office ok actions/dialog-ok open actions/document-open -open-recent [-breeze*]actions/toolbar/document-open-recent;actions/document-open-recent +open-recent actions/document-open-recent options categories/preferences-system;actions/configure package apps/system-software-install;apps/preferences-desktop-default-applications paste actions/edit-paste pause actions/media-playback-pause pda devices/pda -pdf [-breeze*]$(mime)/file-types-small/application-pdf;$(mime)/application-pdf +pdf $(mime)/application-pdf pen actions/draw-freehand people apps/system-users phone [-breeze*]devices/smartphone;devices/phone @@ -110,7 +110,7 @@ previous actions/go-previous;actions/go-previous-view print actions/document-print printer devices/printer -program [-breeze*]$(mime)/file-types-small/application-x-executable;$(mime)/application-x-executable +program $(mime)/application-x-executable properties actions/document-properties question status/dialog-question;actions/svn-status;# quit actions/application-exit @@ -129,11 +129,11 @@ save-as actions/document-save-as science categories/applications-science screen devices/video-display -script [-breeze*]$(mime)/file-types-small/text-x-script;$(mime)/text-x-script +script $(mime)/text-x-script security status/security-medium select actions/select-rectangular select-all actions/edit-select-all -server [-breeze*]places/user-folders-small/network-server;places/network-server +server places/network-server shortcut apps/accessories-character-map sort-ascent actions/view-sort-ascending sort-descent actions/view-sort-descending @@ -143,8 +143,8 @@ sun status/weather-clear system devices/computer tablet devices/input-tablet -terminal [breeze*]apps/toolbar/utilities-terminal;apps/utilities-terminal -text [-breeze*]$(mime)/file-types-small/text-x-generic;$(mime)/text-x-generic;$(mime)/text-plain +terminal apps/utilities-terminal +text $(mime)/text-x-generic;$(mime)/text-plain text-bold actions/format-text-bold text-center actions/format-justify-center text-fill actions/format-justify-fill @@ -155,13 +155,13 @@ text-underline actions/format-text-underline tools [elementary]categories/applications-developmenent;[+breeze*]categories/applications-system;actions/applications-system;categories/applications-system top actions/go-top -trash [-breeze*]places/user-folders-small/user-trash;places/user-trash +trash places/user-trash undo actions/edit-undo unindent actions/format-indent-less unlock actions/object-unlocked up actions/go-up user [breeze*]actions/user-identity;stock/stock_person;status/avatar-default -video [-breeze*]$(mime)/file-types-small/video-x-generic;$(mime)/video-x-generic +video $(mime)/video-x-generic view-detail actions/view-list-details view-icon actions/view-list-icons view-normal actions/view-close diff -Nru gambas3-3.8.3/comp/src/gb.form/.src/Main.module gambas3-3.8.4/comp/src/gb.form/.src/Main.module --- gambas3-3.8.3/comp/src/gb.form/.src/Main.module 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.form/.src/Main.module 2015-12-22 04:46:12.000000000 +0000 @@ -201,8 +201,8 @@ Public Sub Main() - 'Application.Theme = "KDE5" - Stock["64/linux"].Save("~/picture.png") + 'Application.Theme = "breeze" + Stock["32/directory"].Save("~/test.png") End diff -Nru gambas3-3.8.3/comp/src/gb.form/.src/Message/MessageView.class gambas3-3.8.4/comp/src/gb.form/.src/Message/MessageView.class --- gambas3-3.8.3/comp/src/gb.form/.src/Message/MessageView.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.form/.src/Message/MessageView.class 2015-12-22 04:46:12.000000000 +0000 @@ -57,11 +57,15 @@ Dim fTime As Float + If $sText = Text Then Return + If Me.Visible Then + $aText.Add(Text) $aIcon.Add(Icon) UpdateButton Return + Endif $sText = Text @@ -120,6 +124,9 @@ $aText.Remove(0) $aIcon.Remove(0) Open($sText, $hIcon) + Else + $sText = "" + $hIcon = Null Endif End diff -Nru gambas3-3.8.3/comp/src/gb.form/.src/Stock.class gambas3-3.8.4/comp/src/gb.form/.src/Stock.class --- gambas3-3.8.3/comp/src/gb.form/.src/Stock.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.form/.src/Stock.class 2015-12-22 04:46:12.000000000 +0000 @@ -415,6 +415,7 @@ Dim sDir As String Dim sSubDir As String Dim sMime As String + Dim bBreak As Boolean For Each sFile In Split(sFile, ";") @@ -429,8 +430,9 @@ If iSize > 32 Then Continue sTheme = Mid$(sTheme, 2) Endif - If File.Name(File.Dir(sTemplate)) Not Like sTheme Then Continue + If File.Dir(sTemplate) Not Like "*/" & sTheme & "/*" Then Continue sFile = Mid$(sFile, iPos + 1) + bBreak = True Endif Endif @@ -486,6 +488,8 @@ If hPict Then Return hPict Endif + If bBreak Then Break + Next End diff -Nru gambas3-3.8.3/comp/src/gb.form.editor/.src/CDocument.class gambas3-3.8.4/comp/src/gb.form.editor/.src/CDocument.class --- gambas3-3.8.3/comp/src/gb.form.editor/.src/CDocument.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.form.editor/.src/CDocument.class 2015-12-22 04:46:12.000000000 +0000 @@ -1286,4 +1286,4 @@ Next -End \ No newline at end of file +End diff -Nru gambas3-3.8.3/comp/src/gb.form.editor/.src/FTestEditor.class gambas3-3.8.4/comp/src/gb.form.editor/.src/FTestEditor.class --- gambas3-3.8.3/comp/src/gb.form.editor/.src/FTestEditor.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.form.editor/.src/FTestEditor.class 2015-12-22 04:46:12.000000000 +0000 @@ -2,9 +2,10 @@ Private Sub Reload() - 'TextEditor1.Highlight = "gambas" - 'TextEditor1.Load("~/gambas/3.0/issues/754/test/.src/Main.module") - TextEditor1.Load("~/BUG.776") + TextEditor1.Highlight = "gambas" + TextEditor1.Load("~/gambas/3.0/issues/839/test-OutOfBoundsLongCode/.src/MMain.module") + 'TextEditor1.Load("~/BUG.776") + 'TextEditor1.Load("~/gambas/3.0/test/test4/.src/MSort.module") End diff -Nru gambas3-3.8.3/comp/src/gb.form.editor/.src/FTestEditor.form gambas3-3.8.4/comp/src/gb.form.editor/.src/FTestEditor.form --- gambas3-3.8.3/comp/src/gb.form.editor/.src/FTestEditor.form 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.form.editor/.src/FTestEditor.form 2015-12-22 04:46:12.000000000 +0000 @@ -26,10 +26,10 @@ } } { Panel1 VSplit - MoveScaled(10,10,38,52) + MoveScaled(10,10,76,52) Expand = True { TextEditor1 TextEditor - MoveScaled(13,5,21,33) + MoveScaled(13,5,47,23) Font = Font["Gambas,10"] Border = False TabSize = 8 diff -Nru gambas3-3.8.3/comp/src/gb.form.editor/.src/TextEditor.class gambas3-3.8.4/comp/src/gb.form.editor/.src/TextEditor.class --- gambas3-3.8.3/comp/src/gb.form.editor/.src/TextEditor.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.form.editor/.src/TextEditor.class 2015-12-22 04:46:12.000000000 +0000 @@ -63,6 +63,8 @@ Private Const MATCH_STRING As String = "()[]{}" Static Private $cShortcut As Collection +Static Private $bRemoteDisplayChecked As Boolean +Static Private $bRemoteDisplay As Boolean Public _Views As TextEditor[] @@ -161,6 +163,12 @@ Static Private $cGlobalCacheText As New Collection Private $cCacheText As Collection Private $sCacheTextKey As String + +Private $cCacheLine As New Collection +Private $iLastScrollX As Integer +Private $hTimerCacheLine As Timer +Private $iCacheLineH As Integer + Private $bUpdateHeightAllowed As Boolean Private $bPrint As Boolean @@ -168,6 +176,8 @@ Public Sub _new() + Dim sDisplay As String + If Not $cShortcut Then $cShortcut = [ "CTRL+A": "SelectAll", @@ -181,6 +191,12 @@ "CTRL+Z": "Undo"] Endif + If Not $bRemoteDisplayChecked Then + sDisplay = Env["DISPLAY"] + If sDisplay And If Left(sDisplay) <> ":" Then $bRemoteDisplay = True + $bRemoteDisplayChecked = True + Endif + $hPanel = New Panel(Me) As "ViewPanel" $hPanel.Arrangement = Arrange.Fill $hPanel.Border = Border.Plain @@ -195,7 +211,9 @@ $hTimerCursor = New Timer As "TimerCursor" $hTimerCursor.Delay = 500 - $hTimerCursor.Start + + $hTimerCacheLine = New Timer As "TimerCacheLine" + $hTimerCacheLine.Delay = 5000 $hRows = New _TextEditor_Rows As "Rows" $hStyles = New _TextEditor_Styles As "Styles" @@ -250,11 +268,13 @@ $fCharWidth = $hFont.TextWidth(sText) / Len(sText) Endif - $sCacheTextKey = $hFont.ToString() - $cCacheText = $cGlobalCacheText[$sCacheTextKey] - If Not $cCacheText Then - $cCacheText = New Collection - $cGlobalCacheText[$sCacheTextKey] = $cCacheText + If Not $bRemoteDisplay Then + $sCacheTextKey = $hFont.ToString() + $cCacheText = $cGlobalCacheText[$sCacheTextKey] + If Not $cCacheText Then + $cCacheText = New Collection + $cGlobalCacheText[$sCacheTextKey] = $cCacheText + Endif Endif _ClearCachePos @@ -283,9 +303,13 @@ CalcSizes $cCachePos.Clear - $cCacheText.Clear $cCacheView.Clear + If Not $bRemoteDisplay Then + ClearCacheText + ClearCacheLine + Endif + $bShowCursor = True GotoCenter(0, 0) @@ -575,7 +599,7 @@ 'Paint.Background = iCol DrawText(sStr, X, XX, YY) Else If Trim(sStr) Then - If iLen <= 16 Then + If Not $bRemoteDisplay And If iLen <= 16 Then sKey = Chr$(iState) & sStr hImage = $cCacheText[sKey] If Not hImage Then @@ -1298,7 +1322,9 @@ 'Y = ViewToReal(Y) 'Goto($X, Max(0, Y), Key.Shift) If Not Key.Control And If Not Key.Alt And If Not Key.Meta Then - GotoXY($X0 + $MW - $hView.ScrollX, $hRows._GetRowY($Y) + $XY.Y - $hView.ClientH - $hView.ScrollY, Key.Shift) + If GotoXY($X0 + $MW - $hView.ScrollX, $hRows._GetRowY($Y) + $XY.Y - $hView.ClientH - $hView.ScrollY, Key.Shift) Then + Goto(0, 0, Key.Shift) + Endif Endif Case Key.PageDown @@ -1311,7 +1337,9 @@ 'Goto($X, $hDoc.Max, Key.Shift) 'Endif If Not Key.Control And If Not Key.Alt And If Not Key.Meta Then - GotoXY($X0 + $MW - $hView.ScrollX, $hRows._GetRowY($Y) + $XY.Y + $hView.ClientH - $hView.ScrollY, Key.Shift) + If GotoXY($X0 + $MW - $hView.ScrollX, $hRows._GetRowY($Y) + $XY.Y + $hView.ClientH - $hView.ScrollY, Key.Shift) Then + Goto(-1, $hDoc.Max, Key.Shift) + Endif Endif @@ -1444,6 +1472,13 @@ _RefreshLine($Y) If NX <> $X Or If NY <> $Y Then + + If Not Mark Then + _RefreshLine(NY) + Else + _RefreshLine(Min(NY, $Y), Max(NY, $Y) - Min(NY, $Y) + 1) + Endif + $X = NX $Y = NY $XY = LinePos($Y, $X) @@ -1458,7 +1493,6 @@ $SY = $Y $SXY = $XY Else - Refresh Clipboard.Current = Clipboard.Selection Copy() Clipboard.Current = Clipboard.Default @@ -1466,7 +1500,6 @@ $bShowCursor = True If Not $bReadOnly Then $hTimerCursor.Start - _RefreshLine($Y) '$hView.EnsureVisible($XX, $hRows._GetRowY($Y), $MW + 3, $hRows._GetRowHeight($Y)) @@ -1638,6 +1671,10 @@ Else CollapseAll Endif + Else + Goto(0, Y) + Raise Margin + Stop Event Endif Endif Endif @@ -1694,10 +1731,6 @@ If $hTimerScroll Then $hTimerScroll.Stop $hTimerScroll = Null - Else - If Mouse.Left And If Mouse.Normal And If Mouse.X < $MW And If Mouse.X >= $iPosIcon Then - Raise Margin - Endif Endif If Mouse.Middle Then @@ -1898,6 +1931,9 @@ Y = Min($Y, $hDoc.Max) X = Min($X, $hDoc.LineLength[Y]) If X <> $X Or If Y <> $Y Then Goto(X, Y) + + $SX = $X + $SY = $Y If Not $cLineLayout Then @@ -2155,10 +2191,30 @@ End -Public Sub _RefreshLine(Y As Integer) +Public Sub _RefreshLine(Y As Integer, Optional N As Integer = 1) - If Y < 0 Then Return - $hView.RefreshRect(0, $hRows._GetRowY(Y), $hView.ScrollW, $hRows._GetRowHeight(Y)) + Dim I As Integer + Dim hPict As Picture + + If Y < 0 Or If Y > $hDoc.Max Or If N <= 0 Then Return + + N = Min(N, $hDoc.Count - Y) + + If Not $bRemoteDisplay Then + For I = Y To Y + N - 1 + hPict = $cCacheLine[I] + If hPict Then + $iCacheLineH -= hPict.H + $cCacheLine.Remove(I) + Endif + Next + Endif + + If N = 1 Then + $hView.RefreshRect(0, $hRows._GetRowY(Y), $hView.ScrollW, $hRows._GetRowHeight(Y)) + Else + $hView.RefreshRect(0, $hRows._GetRowY(Y), $hView.ScrollW, $hRows._GetRowY(Y + N) - $hRows._GetRowY(Y)) + Endif End @@ -2357,6 +2413,7 @@ _UpdateAllHeight Endif + ClearCacheLine $hView.ResizeContents($iWidth, $hRows._GetHeight()) End @@ -2370,7 +2427,9 @@ Dim hRect As Rect Dim aRow As Integer[] Dim iMaxRow As Integer - Dim W As Integer + Dim W, NL As Integer + 'Dim hImage As Image + Dim hPict As Picture If Not $bUpdateHeightAllowed Then $bUpdateHeightAllowed = True @@ -2388,9 +2447,10 @@ 'Debug Me.Font.ToString();; Draw.Font.ToString() + NL = $hView.ClientH \ $hRows.H + 1 + hClip = Paint.ClipRect - 'Debug hClip.Y;; hClip.H - Paint.FillRect(hClip.X, hClip.Y, hClip.W, hClip.H, $iBackground) + If $hDoc.Count < NL Then Paint.FillRect(hClip.X, hClip.Y, hClip.W, hClip.H, $iBackground) iRow = $hRows._FindRowFromPos($hView.ScrollY + hClip.Y) If iRow < 0 Then Return @@ -2426,19 +2486,47 @@ aRow[I] = _ViewToReal(iRow + I) Next - W = $MW - If $bShowModified Then W -= 4 - If W > 0 Then Paint.FillRect(XX + $hView.ScrollX, hClip.Y, W, hClip.H, Color.SetAlpha($iLimitColor, &HC0)) - Y = YY For I = 0 To iMaxRow - Paint.Save - H = $hRows._GetRowHeight(aRow[I]) - DrawLine(XX, Y, $iWidth, H, aRow[I]) - Paint.Restore + iRow = aRow[I] + H = $hRows._GetRowHeight(iRow) + + If H >= $hView.ClientH Or If $bRemoteDisplay Then + Paint.Save + DrawLine(XX, Y, $iWidth, H, iRow) + Paint.Restore + Else + hPict = $cCacheLine[iRow] + If Not hPict Then + hPict = New Picture($iWidth, H) + hPict.Fill($iBackground) + Paint.Begin(hPict) + Paint.Font = $hFont + DrawLine(0, 0, $iWidth, H, iRow) + Paint.End + $cCacheLine[iRow] = hPict + $iCacheLineH += H + Paint.DrawPicture(hPict, XX, Y) + + While $iCacheLineH > $hView.ClientH + For Each hPict In $cCacheLine + $iCacheLineH -= hPict.H + $cCacheLine.Remove($cCacheLine.Key) + Break + Next + Wend + + Else + Paint.DrawPicture(hPict, XX, Y) + Endif + Endif Y += H Next + W = $MW + If $bShowModified Then W -= 4 + If W > 0 Then Paint.FillRect(XX + $hView.ScrollX, hClip.Y, W, hClip.H, Color.Merge($iLimitColor, $iBackground, 0.8)) + If $MW Then Paint.Font = $hFontNumber @@ -2454,6 +2542,9 @@ Endif + $hTimerCacheLine.Stop + $hTimerCacheLine.Start + 'PrintCache End @@ -2536,6 +2627,11 @@ Public Sub View_Scroll() + If $hView.ScrollX <> $iLastScrollX Then + ClearCacheLine + $iLastScrollX = $hView.ScrollX + Endif + Raise Scroll End @@ -2813,6 +2909,8 @@ Public Sub View_GotFocus() + $hTimerCursor.Start + If Not $bFirstFocus Then $bFirstFocus = True EnsureVisible(True) @@ -2832,7 +2930,9 @@ Public Sub View_LostFocus() + $hTimerCursor.Stop $hDoc.HighlightFrom($Y) + $hTimerCacheLine.Trigger End @@ -2895,14 +2995,14 @@ End -Private Sub GotoXY(X As Integer, Y As Integer, bMark As Boolean) +Private Sub GotoXY(X As Integer, Y As Integer, bMark As Boolean) As Boolean Dim L As Integer Dim RY As Integer Dim X0 As Integer L = PosToLine(Y) - If L < 0 Then Return + If L < 0 Then Return True RY = $hRows.RelativeY X0 = $X0 @@ -3480,7 +3580,7 @@ Public Sub Refresh() - 'Debug System.Backtrace.Join(" ") + ClearCacheLine $hView.Refresh End @@ -4469,7 +4569,7 @@ Public Sub Styles_Change() $bStyleChanged = True - $cCacheText.Clear + ClearCacheText End @@ -4539,3 +4639,25 @@ Goto(Max(0, $X + DX), Max(0, $Y + DY)) End + +Public Sub TimerCacheLine_Timer() + + ClearCacheLine + $hTimerCacheLine.Stop + +End + +Private Sub ClearCacheLine() + + If $bRemoteDisplay Then Return + $cCacheLine.Clear + $iCacheLineH = 0 + +End + +Private Sub ClearCacheText() + + If $bRemoteDisplay Then Return + $cCacheText.Clear + +End diff -Nru gambas3-3.8.3/comp/src/gb.gui.base/.project gambas3-3.8.4/comp/src/gb.gui.base/.project --- gambas3-3.8.3/comp/src/gb.gui.base/.project 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.gui.base/.project 2015-12-22 04:46:12.000000000 +0000 @@ -1,7 +1,7 @@ # Gambas Project File 3.0 # Compiled with Gambas 3.8.90 Title=gb.gui.base -Startup=FAbout +Startup=FGridView Version=3.8.90 VersionFile=1 Component=gb.image diff -Nru gambas3-3.8.3/comp/src/gb.gui.base/.src/GridView/GridView.class gambas3-3.8.4/comp/src/gb.gui.base/.src/GridView/GridView.class --- gambas3-3.8.3/comp/src/gb.gui.base/.src/GridView/GridView.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.gui.base/.src/GridView/GridView.class 2015-12-22 04:46:12.000000000 +0000 @@ -928,6 +928,7 @@ Dim iMouse As Integer Dim F As Integer = _GetFrameWidth() Dim bInRowHeader As Boolean + Dim HW As Integer If Me.Design Then Return If Not Me.Enabled Then Return @@ -967,6 +968,7 @@ $iRowResize = -1 $iColResize = -1 + HW = (Desktop.Scale * 3) \ 4 bInRowHeader = InRowHeader(MX) @@ -974,7 +976,7 @@ If $hRows.Resizable Then For I = 0 To $aRowY.Max - If MY >= ($aRowY[I] - 1) And If MY <= ($aRowY[I] + 2) Then + If MY >= ($aRowY[I] - HW) And If MY <= ($aRowY[I] + HW) Then If I + $iFirstRow Then iMouse = Mouse.SizeS $iRowResize = I + $iFirstRow - 1 @@ -1005,7 +1007,7 @@ ' Next For I = 1 To $hColumns.Count - 1 With $hColumns[I] - If $hColumns[I].Resizable And If X >= (.X - 1) And If X <= (.X + 2) Then + If $hColumns[I].Resizable And If X >= (.X - HW) And If X <= (.X + HW) Then iMouse = Mouse.SizeE $iColResize = I $iDimResize = $hColumns[$iColResize].Width @@ -1016,7 +1018,7 @@ Else For I = 1 To $hColumns.Count - 1 With $hColumns[I] - If $hColumns[I - 1].Resizable And If X >= (.X - 1) And If X <= (.X + 2) Then + If $hColumns[I - 1].Resizable And If X >= (.X - HW) And If X <= (.X + HW) Then iMouse = Mouse.SizeE $iColResize = I - 1 $iDimResize = $hColumns[$iColResize].Width @@ -1027,13 +1029,13 @@ Endif If System.RightToLeft Then - If $iColResize < 0 And If $hColumns[0].Resizable And If X >= ($hColumns._GetWidth() - 1) And If X <= ($hColumns._GetWidth() + 2) Then + If $iColResize < 0 And If $hColumns[0].Resizable And If X >= ($hColumns._GetWidth() - HW) And If X <= ($hColumns._GetWidth() + HW) Then iMouse = Mouse.SizeE $iColResize = 0 $iDimResize = $hColumns[$iColResize].Width Endif Else - If $iColResize < 0 And If $hColumns[$hColumns.Count - 1].Resizable And If X >= ($hColumns._GetWidth() - 1) And If X <= ($hColumns._GetWidth() + 2) Then + If $iColResize < 0 And If $hColumns[$hColumns.Count - 1].Resizable And If X >= ($hColumns._GetWidth() - HW) And If X <= ($hColumns._GetWidth() + HW) Then iMouse = Mouse.SizeE $iColResize = $hColumns.Count - 1 $iDimResize = $hColumns[$iColResize].Width diff -Nru gambas3-3.8.3/comp/src/gb.gui.base/.src/Test/FGridView.form gambas3-3.8.4/comp/src/gb.gui.base/.src/Test/FGridView.form --- gambas3-3.8.3/comp/src/gb.gui.base/.src/Test/FGridView.form 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.gui.base/.src/Test/FGridView.form 2015-12-22 04:46:12.000000000 +0000 @@ -26,6 +26,7 @@ Mode = Select.Multiple Padding = 0 ShowCursor = True + Header = GridView.Both Sorted = True } { TextBox1 TextBox diff -Nru gambas3-3.8.3/comp/src/gb.net.smtp/.src/Main.module gambas3-3.8.4/comp/src/gb.net.smtp/.src/Main.module --- gambas3-3.8.3/comp/src/gb.net.smtp/.src/Main.module 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.net.smtp/.src/Main.module 2015-12-22 04:46:12.000000000 +0000 @@ -18,9 +18,27 @@ ' hClient.Add(File.Load("~/TexteDehorsilpleut.odt"), "application/vnd.oasis.opendocument.text", "Dehors il pleut.odt") ' hClient.Add(File.Load("~/balloon.png"), "image/png", "balloon.png") ' hClient.Send - + Dim hMsg As New SmtpClient + ' Dim sChallenge As String + ' Dim sKey As String + ' Dim sCommand As String + ' Dim sResult As String + ' + ' sChallenge = "'abc'" + ' sKey = "benoit" + ' + ' sCommand = "echo -n " & Shell$(sChallenge) & " | openssl md5 -hmac " & Shell$(sKey) + ' Shell sCommand To sResult + ' Print sResult + ' + ' sCommand = "openssl md5 -hmac " & Shell$(sKey) & " << EOF\n'abc'" + ' Shell sCommand To sResult + ' Print sResult + ' + ' Return + hMsg.Debug = True hMsg.To.Add("benoit@minisini.fr") hMsg.Subject = "Test mail headers 5" diff -Nru gambas3-3.8.3/comp/src/gb.net.smtp/.src/SmtpClient.class gambas3-3.8.4/comp/src/gb.net.smtp/.src/SmtpClient.class --- gambas3-3.8.3/comp/src/gb.net.smtp/.src/SmtpClient.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.net.smtp/.src/SmtpClient.class 2015-12-22 04:46:12.000000000 +0000 @@ -309,21 +309,55 @@ End Private Sub Authenticate() - - Dim sData As String - + + Dim sChallenge64, sChallenge, sKey, sCommand, sResponse, sDigestHex As String + If Not $sUser Then Return - - sData = $hSession.Send("AUTH PLAIN") - If $hSession.LastCode <> "334" Then Error.Raise("Unsupported authentication method") - - sData = $hSession.Send(Base64$($sUser & Chr$(0) & $sUser & Chr$(0) & $sPassword), True) - If $hSession.LastCode <> "235" Then Error.Raise("Authentication failed") - + + ' AUTH LOGIN + $hSession.Send("AUTH LOGIN") + If $hSession.LastCode = "334" Then + $hSession.Send(Base64$($sUser)) + If $hSession.LastCode = "334" Then + $hSession.Send(Base64$($sPassword)) + If $hSession.LastCode = "235" Then Return + Endif + Endif + + ' AUTH PLAIN + $hSession.Send("AUTH PLAIN") + If $hSession.LastCode <> "334" Then + $hSession.Send("AUTH PLAIN " & Base64$($sUser & Chr$(0) & $sUser & Chr$(0) & $sPassword), True) + Else + $hSession.Send(Base64$($sUser & Chr$(0) & $sUser & Chr$(0) & $sPassword), True) + Endif + If $hSession.LastCode = "235" Then Return + + ' CRAM-MD5 + $hSession.Send("AUTH CRAM-MD5") + 'If $hSession.LastCode = "334" Then Print "LastAnswer = "; $hSession.LastAnswer + + sChallenge64 = Split($hSession.LastAnswer, " ")[1] + sChallenge = UnBase64(sChallenge64) + sKey = $sPassword + + 'sCommand = "echo -n " & Shell$(sChallenge) & " | openssl md5 -hmac " & Shell$(sKey) + sCommand = "openssl md5 -hmac " & Shell$(sKey) & " << EOF\n" & sChallenge + Shell sCommand To sDigestHex + + sDigestHex = Trim(Split(sDigestHex, "=")[1]) + sResponse = Base64($sUser & sDigestHex) + + $hSession.Send(sResponse) + If $hSession.LastCode = "235" Then Return + + ' Nothing worked? + Error.Raise("Authentication failed") + Catch - + Error.Raise("Unable to authenticate: " & Error.Text) - + End Private Sub SendRecipients() diff -Nru gambas3-3.8.3/comp/src/gb.report2/.src/Viewer/ReportView.class gambas3-3.8.4/comp/src/gb.report2/.src/Viewer/ReportView.class --- gambas3-3.8.3/comp/src/gb.report2/.src/Viewer/ReportView.class 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/comp/src/gb.report2/.src/Viewer/ReportView.class 2015-12-22 04:46:12.000000000 +0000 @@ -69,7 +69,7 @@ Paint.AntiAlias = True If $bGrayScale Then - hImg = New Image(Width, Height) + hImg = New Image(Width, Height, Color.White) Paint.Begin(hImg) Endif diff -Nru gambas3-3.8.3/debian/bzr-builder.manifest gambas3-3.8.4/debian/bzr-builder.manifest --- gambas3-3.8.3/debian/bzr-builder.manifest 2015-11-08 16:47:24.000000000 +0000 +++ gambas3-3.8.4/debian/bzr-builder.manifest 2015-12-22 04:46:25.000000000 +0000 @@ -1,4 +1,4 @@ -# bzr-builder format 0.3 deb-version {debupstream}-4.45 -lp:~gambas-team/+junk/gambas-3.8branch revid:svn-v4:02bb98e2-b625-4c1b-a9b2-7bc90b9017ea:gambas/branches/3.8:7451 -nest debian-common lp:~gambas-team/+junk/gambas3-stable-common debian revid:sebikul@gmail.com-20151108164335-tteeqtlhlxra8mxg +# bzr-builder format 0.3 deb-version {debupstream}-4.47 +lp:~gambas-team/+junk/gambas-3.8branch revid:svn-v4:02bb98e2-b625-4c1b-a9b2-7bc90b9017ea:gambas/branches/3.8:7528 +nest debian-common lp:~gambas-team/+junk/gambas3-stable-common debian revid:sebikul@gmail.com-20151222040346-m2oc9otds2l56qra merge debian lp:~gambas-team/+junk/gambas3-stable-wily revid:sebikul@gmail.com-20150828232941-3ta134bgywt473y3 diff -Nru gambas3-3.8.3/debian/changelog gambas3-3.8.4/debian/changelog --- gambas3-3.8.3/debian/changelog 2015-11-08 16:47:24.000000000 +0000 +++ gambas3-3.8.4/debian/changelog 2015-12-22 04:46:25.000000000 +0000 @@ -1,11 +1,11 @@ -gambas3 (3.8.3-4.45~ubuntu15.10.1) wily; urgency=low +gambas3 (3.8.4-4.47~ubuntu15.10.1) wily; urgency=low * Auto build. - -- sebikul Sun, 08 Nov 2015 16:47:24 +0000 + -- sebikul Tue, 22 Dec 2015 04:46:25 +0000 -gambas3 (3.8.3) saucy; urgency=low +gambas3 (3.8.4) saucy; urgency=low - * Gambas 3.8.3 + * Gambas 3.8.4 -- Sebastian Kulesz Sat, 23 Nov 2013 14:36:48 +0100 diff -Nru gambas3-3.8.3/gb.cairo/acinclude.m4 gambas3-3.8.4/gb.cairo/acinclude.m4 --- gambas3-3.8.3/gb.cairo/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.cairo/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.compress.bzlib2/acinclude.m4 gambas3-3.8.4/gb.compress.bzlib2/acinclude.m4 --- gambas3-3.8.3/gb.compress.bzlib2/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.compress.bzlib2/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.compress.zlib/acinclude.m4 gambas3-3.8.4/gb.compress.zlib/acinclude.m4 --- gambas3-3.8.3/gb.compress.zlib/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.compress.zlib/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.crypt/acinclude.m4 gambas3-3.8.4/gb.crypt/acinclude.m4 --- gambas3-3.8.3/gb.crypt/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.crypt/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.db.mysql/acinclude.m4 gambas3-3.8.4/gb.db.mysql/acinclude.m4 --- gambas3-3.8.3/gb.db.mysql/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.db.mysql/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.db.odbc/acinclude.m4 gambas3-3.8.4/gb.db.odbc/acinclude.m4 --- gambas3-3.8.3/gb.db.odbc/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.db.odbc/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.db.postgresql/acinclude.m4 gambas3-3.8.4/gb.db.postgresql/acinclude.m4 --- gambas3-3.8.3/gb.db.postgresql/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.db.postgresql/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.db.postgresql/src/main.c gambas3-3.8.4/gb.db.postgresql/src/main.c --- gambas3-3.8.3/gb.db.postgresql/src/main.c 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.db.postgresql/src/main.c 2015-12-22 04:46:12.000000000 +0000 @@ -456,6 +456,11 @@ if (bc) date.year = (-date.year); + // 4713-01-01 BC is used for null dates + + if (date.year == -4713 && date.month == 1 && date.day == 1) + date.year = date.month = date.day = 0; + GB.MakeDate(&date, (GB_DATE *)&conv); val->type = GB_T_DATE; @@ -867,24 +872,36 @@ date = GB.SplitDate((GB_DATE *)arg); - bc = date->year < 0; - - l = sprintf(_buffer, "'%04d-%02d-%02d %02d:%02d:%02d", - abs(date->year), date->month, date->day, - date->hour, date->min, date->sec); + // Gambas year is between -4801 and +9999 + // PostgreSQL year is between -4713 and +294276 + // So let's use -4713 for representing null dates. - add(_buffer, l); - - if (date->msec) + if (date->year == 0) { - l = sprintf(_buffer, ".%03d", date->msec); + l = sprintf(_buffer, "'4713-01-01 %02d:%02d:%02d BC'", date->hour, date->min, date->sec); add(_buffer, l); } + else + { + bc = date->year < 0; - if (bc) - add(" BC", 3); + l = sprintf(_buffer, "'%04d-%02d-%02d %02d:%02d:%02d", + abs(date->year), date->month, date->day, + date->hour, date->min, date->sec); - add("'", 1); + add(_buffer, l); + + if (date->msec) + { + l = sprintf(_buffer, ".%03d", date->msec); + add(_buffer, l); + } + + if (bc) + add(" BC", 3); + + add("'", 1); + } return TRUE; diff -Nru gambas3-3.8.3/gb.db.sqlite2/acinclude.m4 gambas3-3.8.4/gb.db.sqlite2/acinclude.m4 --- gambas3-3.8.3/gb.db.sqlite2/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.db.sqlite2/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.db.sqlite3/acinclude.m4 gambas3-3.8.4/gb.db.sqlite3/acinclude.m4 --- gambas3-3.8.3/gb.db.sqlite3/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.db.sqlite3/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.dbus/acinclude.m4 gambas3-3.8.4/gb.dbus/acinclude.m4 --- gambas3-3.8.3/gb.dbus/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.dbus/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.desktop.gnome.keyring/acinclude.m4 gambas3-3.8.4/gb.desktop.gnome.keyring/acinclude.m4 --- gambas3-3.8.3/gb.desktop.gnome.keyring/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.desktop.gnome.keyring/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.desktop.x11/acinclude.m4 gambas3-3.8.4/gb.desktop.x11/acinclude.m4 --- gambas3-3.8.3/gb.desktop.x11/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.desktop.x11/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.desktop.x11/src/x11.c gambas3-3.8.4/gb.desktop.x11/src/x11.c --- gambas3-3.8.3/gb.desktop.x11/src/x11.c 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.desktop.x11/src/x11.c 2015-12-22 04:46:12.000000000 +0000 @@ -1,23 +1,23 @@ /*************************************************************************** - x11.c + x11.c - (c) 2000-2013 Benoît Minisini + (c) 2000-2013 Benoît Minisini - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, USA. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. ***************************************************************************/ @@ -46,7 +46,11 @@ Atom X11_atom_net_wm_window_type_normal; Atom X11_atom_net_wm_window_type_utility; Atom X11_atom_net_wm_desktop; +Atom X11_atom_net_wm_user_time; Atom X11_atom_net_current_desktop; +Atom X11_atom_net_workarea = None; +Atom X11_atom_motif_wm_hints = None; +Atom X11_atom_net_system_tray = None; Atom X11_UTF8_STRING; @@ -74,6 +78,7 @@ struct { int count; Atom atoms[MAX_WINDOW_PROP]; + bool changed; } X11_PROPERTY; @@ -103,7 +108,8 @@ X11_atom_net_wm_window_type = XInternAtom(_display, "_NET_WM_WINDOW_TYPE", True); X11_atom_net_wm_window_type_normal = XInternAtom(_display, "_NET_WM_WINDOW_TYPE_NORMAL", True); X11_atom_net_wm_window_type_utility = XInternAtom(_display, "_NET_WM_WINDOW_TYPE_UTILITY", True); - + X11_atom_net_wm_user_time = XInternAtom(_display, "_NET_WM_USER_TIME", True); + X11_UTF8_STRING = XInternAtom(X11_display, "UTF8_STRING", True); _atom_init = TRUE; @@ -136,8 +142,8 @@ char *X11_get_property(Window wid, Atom prop, Atom *type, int *format, int *pcount) { uchar *data; - unsigned long count; - unsigned long after; + unsigned long count; + unsigned long after; unsigned long offset; int size, offset_size; @@ -147,24 +153,24 @@ False, AnyPropertyType, type, format, &count, &after, &data) != Success) return NULL; - + *pcount += count; - + size = sizeof_format(*format); offset_size = *format == 32 ? sizeof(int32_t) : ( *format == 16 ? sizeof(short) : 1 ); - + //fprintf(stderr, "X11_get_property: format = %d size = %d count = %ld after = %ld\n", *format, size, count, after); - + GB.FreeString(&_property_value); _property_value = GB.NewString((char *)data, count * size); XFree(data); - + offset = count * offset_size / sizeof(int32_t); - + while (after) { //fprintf(stderr, "X11_get_property: offset = %ld read = %ld\n", offset, Min(after, PROPERTY_NEXT_READ) / sizeof(int32_t)); - + if (XGetWindowProperty(_display, wid, prop, offset, Min(after, PROPERTY_NEXT_READ) / sizeof(int32_t), False, AnyPropertyType, type, format, &count, &after, &data) != Success) @@ -172,13 +178,13 @@ *pcount += count; offset += count * offset_size / sizeof(int32_t); - + //fprintf(stderr, "X11_get_property: format = %d size = %d count = %ld after = %ld next offset = %ld\n", *format, size, count, after, offset); - + _property_value = GB.AddString(_property_value, (char *)data, count * size); XFree(data); } - + return _property_value; } @@ -199,7 +205,7 @@ { Atom type; int format; - + return X11_get_property(wid, prop, &type, &format, count); } @@ -214,7 +220,7 @@ False, AnyPropertyType, &type, format, &count, &after, &data) != Success) return None; - + XFree(data); return type; } @@ -223,7 +229,7 @@ #if OS_64BITS long padded_data[count]; int i; - + if (format == 32) { for (i = 0; i < count; i++) @@ -241,7 +247,7 @@ Atom X11_intern_atom(const char *name, bool create) { int val = atoi(name); - + if (val) return (Atom)val; else @@ -254,6 +260,7 @@ char *data; _window_prop.count = 0; + _window_prop.changed = FALSE; data = get_property(win, prop, &length); @@ -261,15 +268,16 @@ length = MAX_WINDOW_PROP; _window_prop.count = length; - memcpy(_window_prop.atoms, data, length * sizeof(Atom)); + if (data) + memcpy(_window_prop.atoms, data, length * sizeof(Atom)); } static void save_window_state(Window win, Atom prop) { - if (_window_prop.count > 0) + if (_window_prop.changed) { - XChangeProperty(_display, win, prop, XA_ATOM, 32, PropModeReplace, - (unsigned char *)_window_prop.atoms, _window_prop.count); + //fprintf(stderr, "XChangeProperty: %ld %ld\n", (long)win, (long)prop); + XChangeProperty(_display, win, prop, XA_ATOM, 32, PropModeReplace, (unsigned char *)_window_prop.atoms, _window_prop.count); } } @@ -298,6 +306,7 @@ } _window_prop.atoms[_window_prop.count++] = prop; + _window_prop.changed = TRUE; } static void clear_window_state(Atom prop) @@ -313,6 +322,7 @@ for (; i < _window_prop.count; i++) _window_prop.atoms[i] = _window_prop.atoms[i + 1]; + _window_prop.changed = TRUE; return; } } @@ -325,23 +335,23 @@ if (X11_ready) return FALSE; - + GB.Component.GetInfo("DISPLAY", POINTER(&_display)); _root = DefaultRootWindow(_display); - + X11_ready = _display != NULL; - + if (!X11_ready) { fprintf(stderr, "WARNING: X11_init() has failed\n"); return TRUE; } - + init_atoms(); - + _has_test_extension = XTestQueryExtension(_display, &event_base, &error_base, &major_version, &minor_version); - + return FALSE; } @@ -361,13 +371,13 @@ int mask = (SubstructureRedirectMask | SubstructureNotifyMask); //fprintf(stderr, "X11_send_client_message: dest = %ld window = %ld message = %ld format = %d count = %d\n", dest, window, message, format, count); - + e.xclient.type = ClientMessage; e.xclient.message_type = message; e.xclient.display = X11_display; e.xclient.window = window; e.xclient.format = format; - + memset(&e.xclient.data.l[0], 0, sizeof(long) * 5); if (data) { @@ -521,10 +531,10 @@ void X11_get_window_title(Window window, char **result, int *length) { static Atom _net_wm_name = 0; - + if (!_net_wm_name) _net_wm_name = XInternAtom(_display, "_NET_WM_NAME", True); - + *result = get_property(window, _net_wm_name, length); } @@ -600,6 +610,7 @@ { XChangeProperty(_display, window, X11_atom_net_wm_desktop, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&desktop, 1); + XFlush(_display); } } @@ -607,36 +618,42 @@ int X11_window_get_desktop(Window window) { int length; - unsigned long *data; + char *data = NULL; + int desktop = 0; - data = (unsigned long *)get_property(window, X11_atom_net_wm_desktop, &length); + data = get_property(window, X11_atom_net_wm_desktop, &length); + if (data) + desktop = *((int *)data); - return data ? *data : 0; + return desktop; } int X11_get_current_desktop() { int length; - unsigned long *data; + char *data; + int desktop = 0; - data = (unsigned long *)get_property(_root, X11_atom_net_current_desktop, &length); + data = get_property(_root, X11_atom_net_current_desktop, &length); + if (data) + desktop = *((int *)data); - return data ? *data : 0; + return desktop; } static void init_keycode() { int i, j; //, k; KeyCode *pm, *p; - + if (_init_keycode) return; XDisplayKeycodes(_display, &_min_keycode, &_max_keycode); - + _keycode_map = XGetKeyboardMapping(_display, _min_keycode, _max_keycode - _min_keycode + 1, &_keysyms_per_keycode); _modifier_map = XGetModifierMapping(_display); - + p = _modifier_map->modifiermap; for (i = 0; i < 8; i++) { @@ -652,20 +669,20 @@ p++; } } - + //fprintf(stderr, "SHIFT: %d ALTGR: %d\n", _shift_keycode[0], _alt_gr_keycode[0]); - + _init_keycode = TRUE; } static void send_modifiers(KeyCode *codes, bool press) { int i; - + for (i = 0; i < _modifier_map->max_keypermod; i++) { if (codes[i]) - XTestFakeKeyEvent(_display, codes[i], press, CurrentTime); + XTestFakeKeyEvent(_display, codes[i], press, CurrentTime); } } @@ -673,9 +690,9 @@ { KeySym *sym; int i; - + sym = &_keycode_map[(code - _min_keycode) * _keysyms_per_keycode]; - + for (i = 0; i < _keysyms_per_keycode; i++) { if (keysym == sym[i]) @@ -684,7 +701,7 @@ break; } } - + switch(i) { case 1: @@ -706,17 +723,17 @@ { KeySym keysym; KeyCode code; - + if (!_has_test_extension) return "No XTEST extension"; - + if (!_init_keycode) init_keycode(); - + //fprintf(stderr, "X11_send_key: '%s' %d\n", key, XStringToKeysym(key)); - + if (strlen(key) == 1) - { + { if (*key == '\n') keysym = XK_Return; else if (*key == '\t') @@ -728,10 +745,10 @@ } else keysym = XStringToKeysym(key); - + if (keysym == NoSymbol) return "Unknown key"; - + code = XKeysymToKeycode(_display, keysym); if (code) { @@ -739,13 +756,13 @@ handle_modifier(code, keysym, TRUE); XTestFakeKeyEvent(_display, code, press, CurrentTime); - + if (press) handle_modifier(code, keysym, FALSE); } - + usleep(1000); - + return NULL; } @@ -754,7 +771,7 @@ static int count = 0; void (*set_event_filter)(void *) = NULL; - + if (enable) count++; else @@ -789,7 +806,7 @@ GB_T_INTEGER, e->xconfigure.y, GB_T_INTEGER, e->xconfigure.width, GB_T_INTEGER, e->xconfigure.height); - + GB.Call(&_x11_configure_notify_func, 5, TRUE); } @@ -802,15 +819,15 @@ Window p; int transx, transy; XWindowAttributes wattr; - + *wx = *wy = *ww = *wh = 0; - + if (!XTranslateCoordinates(_display, win, _root, 0, 0, &transx, &transy, &p)) return; - + if (!XGetWindowAttributes(_display, win, &wattr)) return; - + *wx = transx - wattr.border_width; *wy = transy - wattr.border_width; *ww = wattr.width + wattr.border_width * 2; diff -Nru gambas3-3.8.3/gb.gmp/acinclude.m4 gambas3-3.8.4/gb.gmp/acinclude.m4 --- gambas3-3.8.3/gb.gmp/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.gmp/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.gsl/acinclude.m4 gambas3-3.8.4/gb.gsl/acinclude.m4 --- gambas3-3.8.3/gb.gsl/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.gsl/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.gtk/acinclude.m4 gambas3-3.8.4/gb.gtk/acinclude.m4 --- gambas3-3.8.3/gb.gtk/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.gtk/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.gtk/src/gapplication.cpp gambas3-3.8.4/gb.gtk/src/gapplication.cpp --- gambas3-3.8.3/gb.gtk/src/gapplication.cpp 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.gtk/src/gapplication.cpp 2015-12-22 04:46:12.000000000 +0000 @@ -45,9 +45,9 @@ static bool _debug_keypress = false; /************************************************************************** - + Global event handler - + **************************************************************************/ static bool _focus_change = false; @@ -74,7 +74,7 @@ /*static bool raise_key_event_to_parent_window(gControl *control, int type) { gMainWindow *win; - + while (control->parent()) { win = control->parent()->window(); @@ -84,10 +84,10 @@ if (win->onKeyEvent(win, type)) return true; } - + control = win; } - + return false; }*/ @@ -97,9 +97,9 @@ #if DEBUG_ENTER_LEAVE fprintf(stderr, "check_crossing_event: %d / %d\n", event->crossing.detail, event->crossing.mode); #endif - + return true; - + if ((event->crossing.mode == GDK_CROSSING_NORMAL || event->crossing.mode == GDK_CROSSING_STATE_CHANGED)) // || event->crossing.mode == GDK_CROSSING_UNGRAB || event->crossing.mode == GDK_CROSSING_GTK_UNGRAB)) return true; @@ -116,7 +116,7 @@ gControl *child; int x, y; int cx, cy, cw, ch; - + if (gApplication::_control_grab) return gApplication::_control_grab; @@ -134,19 +134,19 @@ //fprintf(stderr, "find_child: %s\n", control->name()); control = control->topLevel(); - + while (control->isContainer()) { control->getScreenPos(&x, &y); cont = (gContainer *)control; - + cx = cont->clientX(); cy = cont->clientY(); cw = cont->clientWidth(); ch = cont->clientHeight(); - + //fprintf(stderr, "client area of %s: %d %d %d %d\n", control->name(), cx, cy, cw, ch); - + x = rx - x; y = ry - y; if (x < cx || y < cy || x >= (cx + cw) || y >= (cy + ch)) @@ -154,16 +154,16 @@ //fprintf(stderr, "outside of client area of %s\n", control->name()); return NULL; } - + child = cont->find(x, y); if (!child) break; - + control = child; } //fprintf(stderr, "-> %s\n", control->name()); - + return control; } @@ -174,9 +174,9 @@ #if DEBUG_ENTER_LEAVE fprintf(stderr, "checkHoveredControl: %s\n", control->name()); #endif - + gControl *leave = gApplication::_enter; - + while (leave && leave != control && !leave->isAncestorOf(control)) { #if DEBUG_ENTER_LEAVE @@ -185,11 +185,11 @@ leave->emitLeaveEvent(); leave = leave->parent(); } - + #if DEBUG_ENTER_LEAVE fprintf(stderr, "checkHoveredControl: _enter <- %s\n", control ? control->name() : "ø"); #endif - + if (control) { #if DEBUG_ENTER_LEAVE @@ -245,14 +245,14 @@ } } } - + /*if (event->type == GDK_GRAB_BROKEN) { if (gApplication::_in_popup) fprintf(stderr, "**** GDK_GRAB_BROKEN inside popup: %s %swindow = %p grab_window = %p popup_window = %p\n", event->grab_broken.keyboard ? "keyboard" : "pointer", event->grab_broken.implicit ? "implicit " : "", event->grab_broken.window, event->grab_broken.grab_window, gApplication::_popup_grab_window); }*/ - + if (!((event->type >= GDK_MOTION_NOTIFY && event->type <= GDK_FOCUS_CHANGE) || event->type == GDK_SCROLL)) goto __HANDLE_EVENT; @@ -319,7 +319,7 @@ // grab = gApplication::_popup_grab; } //gdk_window_get_user_data(gApplication::_popup_grab_window, (gpointer *)&grab); - + if (grab) { control = gt_get_control(grab); @@ -328,17 +328,17 @@ if (!control) goto __HANDLE_EVENT; } - + //if (event->type == GDK_BUTTON_RELEASE) // fprintf(stderr, "GDK_BUTTON_RELEASE #2\n"); - + if (event->type == GDK_FOCUS_CHANGE) { control = NULL; //if (GTK_IS_WINDOW(widget)) control = gt_get_control(widget); //fprintf(stderr, "GDK_FOCUS_CHANGE: widget = %p %d : %s %d\n", widget, GTK_IS_WINDOW(widget), control ? control->name() : NULL, event->focus_change.in); - + //if (GTK_IS_WINDOW(widget)) { control = gt_get_control(widget); @@ -358,10 +358,10 @@ // Must continue, otherwise things are broken by some styles //return; } - + goto __HANDLE_EVENT; } - + if (grab && widget != grab && !gtk_widget_is_ancestor(widget, grab)) { //fprintf(stderr, "-> widget = grab\n"); @@ -369,7 +369,7 @@ } //fprintf(stderr, "grab = %p widget = %p %d\n", grab, widget, grab && !gtk_widget_is_ancestor(widget, grab)); - + while (widget) { control = gt_get_control(widget); @@ -377,7 +377,7 @@ break; widget = gtk_widget_get_parent(widget); } - + /*if (event->type == GDK_BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE || event->type == GDK_MOTION_NOTIFY) { fprintf(stderr, "[%s] widget = %p grab = %p _popup_grab = %p _button_grab = %p\n", @@ -397,54 +397,54 @@ goto __HANDLE_EVENT; __FOUND_WIDGET: - + //fprintf(stderr, "control = %p %s\n", control, control->name()); - + /*switch ((int)event->type) { case GDK_ENTER_NOTIFY: fprintf(stderr, "ENTER: %p %s\n", control, control ? control->name() : 0); break; - + case GDK_LEAVE_NOTIFY: fprintf(stderr, "LEAVE: %p %s\n", control, control ? control->name() : 0); break; }*/ - + //group = get_window_group(widget); //if (group != gApplication::currentGroup()) // goto __HANDLE_EVENT; - + cancel = false; - + gApplication::updateLastEvent(event); - + switch ((int)event->type) { case GDK_ENTER_NOTIFY: - + control = find_child(control, (int)event->crossing.x_root, (int)event->crossing.y_root); if (!control) goto __HANDLE_EVENT; - + #if DEBUG_ENTER_LEAVE fprintf(stderr, "GDK_ENTER_NOTIFY: %s (%s) %d %d %p %p\n", control->name(), gApplication::_enter ? gApplication::_enter->name() : "ø", (int)event->crossing.x_root, (int)event->crossing.y_root, event->crossing.window, event->crossing.subwindow); #endif - + if (button_grab) { gApplication::_enter_after_button_grab = control; break; } - + if (gApplication::_leave) { if (gApplication::_leave == control || gApplication::_leave->isAncestorOf(control)) gApplication::_leave = NULL; } - + gApplication::checkHoveredControl(control); - + /* if (gApplication::_leave == control) { @@ -465,18 +465,18 @@ }*/ break; - + case GDK_LEAVE_NOTIFY: - + #if DEBUG_ENTER_LEAVE fprintf(stderr, "GDK_LEAVE_NOTIFY: %s %p %p\n", control->name(), event->crossing.window, event->crossing.subwindow); #endif - + if (button_grab) break; - + //control = find_child(control, (int)event->button.x_root, (int)event->button.y_root); - + gApplication::_leave = control; /* if (gdk_events_pending() && gApplication::_leave == NULL) @@ -495,7 +495,7 @@ { if (gApplication::_leave == control) gApplication::_leave = NULL; - + #if DEBUG_ENTER_LEAVE fprintf(stderr, "leave: %s\n", control->name()); #endif @@ -503,12 +503,12 @@ } } */ - + //if (widget != control->border && widget != control->widget) // goto __RETURN; - + break; - + case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_BUTTON_RELEASE: @@ -518,14 +518,14 @@ goto __HANDLE_EVENT; bool menu = false; - + switch ((int)event->type) { case GDK_BUTTON_PRESS: type = gEvent_MousePress; break; case GDK_2BUTTON_PRESS: type = gEvent_MouseDblClick; break; default: type = gEvent_MouseRelease; break; } - + if (event->type != GDK_BUTTON_RELEASE) { if (control->canFocus() && !control->hasFocus()) @@ -534,11 +534,11 @@ gApplication::setButtonGrab(control); } - + __BUTTON_TRY_PROXY: - + cancel = false; - + if (control->onMouseEvent) { if (control->canRaise(control, type)) @@ -548,31 +548,31 @@ ys = (int)event->button.y_root; x = xs - xc; y = ys - yc; - + gMouse::validate(); gMouse::setEvent(event); //gMouse::setValid(1,(int)event->x,(int)event->y,event->button,event->state,data->screenX(),data->screenY()); gMouse::setMouse(x, y, xs, ys, event->button.button, event->button.state); switch ((int)event->type) { - case GDK_BUTTON_PRESS: + case GDK_BUTTON_PRESS: gMouse::setStart(x, y); cancel = control->onMouseEvent(control, gEvent_MousePress); break; - - case GDK_2BUTTON_PRESS: - cancel = control->onMouseEvent(control, gEvent_MouseDblClick); + + case GDK_2BUTTON_PRESS: + cancel = control->onMouseEvent(control, gEvent_MouseDblClick); break; - - case GDK_BUTTON_RELEASE: - cancel = control->onMouseEvent(control, gEvent_MouseRelease); + + case GDK_BUTTON_RELEASE: + cancel = control->onMouseEvent(control, gEvent_MouseRelease); break; } - + gMouse::invalidate(); } } - + if (type == gEvent_MousePress && control->isTopLevel()) { gMainWindow *win = ((gMainWindow *)control); @@ -583,7 +583,7 @@ ys = (int)event->button.y_root; x = xs - xc; y = ys - yc; - + if (x < 0 || y < 0 || x >= win->width() || y >= win->height()) win->close(); } @@ -592,14 +592,14 @@ { gApplication::exitLoop(control); } - + #if GTK_CHECK_VERSION(3, 4, 0) if (gdk_event_triggers_context_menu(event)) #else if (event->button.button == 3 && event->type == GDK_BUTTON_PRESS) #endif menu = true; - + if (!cancel) { if (control->_proxy_for) @@ -609,7 +609,7 @@ goto __BUTTON_TRY_PROXY; } } - + if (menu) { control = save_control; @@ -623,7 +623,7 @@ control = control->_proxy_for; } } - + if (cancel) { gMouse::resetTranslate(); @@ -636,10 +636,10 @@ gMouse::resetTranslate(); goto __RETURN; } - + break; } - + case GDK_MOTION_NOTIFY: gdk_event_request_motions(&event->motion); @@ -647,13 +647,13 @@ save_control = control = find_child(control, (int)event->motion.x_root, (int)event->motion.y_root, button_grab); if (!control) goto __HANDLE_EVENT; - + //fprintf(stderr, "GDK_MOTION_NOTIFY: (%p %s) grab = %p\n", control, control->name(), button_grab); - + gApplication::checkHoveredControl(control); - + __MOTION_TRY_PROXY: - + if (control->onMouseEvent && (control->canRaise(control, gEvent_MouseMove) || control->canRaise(control, gEvent_MouseDrag)) && (control->isTracking() || (event->motion.state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)))) { @@ -662,15 +662,15 @@ ys = (int)event->motion.y_root; x = xs - xc; y = ys - yc; - + gMouse::validate(); gMouse::setEvent(event); gMouse::setMouse(x, y, xs, ys, 0, event->motion.state); - + //fprintf(stderr, "pressure = %g\n", gMouse::getAxis(GDK_AXIS_PRESSURE)); - + cancel = control->onMouseEvent(control, gEvent_MouseMove); - + //if (data->acceptDrops() && gDrag::checkThreshold(data, gMouse::x(), gMouse::y(), gMouse::startX(), gMouse::startY())) if (!cancel && (event->motion.state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) //&& (abs(gMouse::x() - gMouse::y()) + abs(gMouse::startX() - gMouse::startY())) > 8) @@ -680,7 +680,7 @@ cancel = control->onMouseEvent(control, gEvent_MouseDrag); } gMouse::invalidate(); - + if (cancel) goto __RETURN; } @@ -691,15 +691,15 @@ //fprintf(stderr, "MOVE: try %s\n", control->name()); goto __MOTION_TRY_PROXY; } - + gMouse::resetTranslate(); //if (widget != save_control->border && widget != save_control->widget) // goto __RETURN; - + break; - + case GDK_SCROLL: - + save_control = control = find_child(control, (int)event->scroll.x_root, (int)event->scroll.y_root); if (!control) goto __HANDLE_EVENT; @@ -709,7 +709,7 @@ if (control->onMouseEvent && control->canRaise(control, gEvent_MouseWheel)) { int dir, dt, ort; - + control->getScreenPos(&xc, &yc); xs = (int)event->scroll.x_root; ys = (int)event->scroll.y_root; @@ -738,7 +738,7 @@ case GDK_SCROLL_RIGHT: dt = 1; ort = 0; break; case GDK_SCROLL_UP: default: dt = 1; ort = 1; break; } - + gMouse::validate(); gMouse::setEvent(event); gMouse::setMouse(x, y, xs, ys, 0, event->scroll.state); @@ -752,19 +752,19 @@ gMouse::resetTranslate(); goto __RETURN; } - + if (control->_proxy_for) { control = control->_proxy_for; goto __SCROLL_TRY_PROXY; } - + if (widget != save_control->border && widget != save_control->widget) { gMouse::resetTranslate(); goto __RETURN; } - + break; case GDK_KEY_PRESS: @@ -779,11 +779,11 @@ gKey::_last_key_release = event->key.keyval; goto __HANDLE_EVENT; } - + __HANDLE_EVENT: gtk_main_do_event(event); - + __RETURN: if (!gdk_events_pending()) // && event->type != GDK_ENTER_NOTIFY && event->type != GDK_LEAVE_NOTIFY) @@ -794,12 +794,12 @@ #if DEBUG_ENTER_LEAVE fprintf(stderr, "post leave: %s\n", gApplication::_leave->name()); #endif - + if (gApplication::_enter == gApplication::_leave) gApplication::_enter = NULL; - + gApplication::_leave->emitLeaveEvent(); - + gApplication::_leave = NULL; } } @@ -855,10 +855,10 @@ void gApplication::grabPopup() { //fprintf(stderr, "grabPopup: %p\n", _popup_grab); - + if (!_popup_grab) return; - + gt_grab(_popup_grab, TRUE, GDK_CURRENT_TIME); } @@ -964,21 +964,21 @@ void gApplication::init(int *argc, char ***argv) { appEvents=0; - + gtk_init(argc, argv); session_manager_init(argc, argv); g_signal_connect(gnome_master_client(), "save-yourself", G_CALLBACK(master_client_save_yourself), NULL); g_signal_connect(gnome_master_client(), "die", G_CALLBACK(master_client_die), NULL); gdk_event_handler_set((GdkEventFunc)gambas_handle_event, NULL, NULL); - + gKey::init(); - + onEnterEventLoop = do_nothing; onLeaveEventLoop = do_nothing; _group = gtk_window_group_new(); - + _loop_owner = 0; char *env = getenv("GB_GTK_DEBUG_KEYPRESS"); @@ -1002,7 +1002,7 @@ void gApplication::exit() { session_manager_exit(); - + if (_title) g_free(_title); @@ -1019,23 +1019,23 @@ { GList *iter; int ct=1; - + if (!gControl::controlList()) return 0; - + iter=g_list_first(gControl::controlList()); while (iter->next) { ct++; iter=iter->next; } - + return ct; } gControl* gApplication::controlItem(GtkWidget *wid) { gControl *control; - + while (wid) { control = gt_get_control(wid); @@ -1043,14 +1043,14 @@ return control; wid = gtk_widget_get_parent(wid); } - + return NULL; } gControl* gApplication::controlItem(int index) { GList *iter; - + if (!gControl::controlList()) return NULL; iter=g_list_nth(gControl::controlList(),index); if (!iter) return NULL; @@ -1088,10 +1088,10 @@ { GList *iter; gControl *control; - + if (gContainer::_arrangement_level) return true; - + _dirty = false; //g_debug(">>>> update_geometry"); iter = g_list_first(gControl::controlList()); @@ -1102,7 +1102,7 @@ iter = iter->next; } //g_debug("<<<<"); - + return false; } @@ -1110,7 +1110,7 @@ { if (_dirty) return; - + _dirty = true; g_timeout_add(0, (GSourceFunc)update_geometry, NULL); } @@ -1127,22 +1127,22 @@ gControl *control = _enter; GtkWindowGroup *oldGroup = _group; _group = gtk_window_group_new(); - + _enter = _leave = NULL; - + while (control) { control->emit(SIGNAL(control->onEnterLeave), gEvent_Leave); control = control->parent(); } - + return oldGroup; } void gApplication::exitGroup(GtkWindowGroup *oldGroup) { g_object_unref(_group); - _group = oldGroup; + _group = oldGroup; } void gApplication::enterLoop(void *owner, bool showIt, GtkWindow *modal) @@ -1150,14 +1150,14 @@ void *old_owner = _loop_owner; int l = _loopLevel; //GtkWindowGroup *oldGroup; - + if (showIt) ((gControl *)owner)->show(); //oldGroup = enterGroup(); - + _loopLevel++; _loop_owner = owner; - + (*onEnterEventLoop)(); do { @@ -1165,7 +1165,7 @@ } while (_loopLevel > l); (*onLeaveEventLoop)(); - + _loop_owner = old_owner; //exitGroup(oldGroup); @@ -1178,27 +1178,27 @@ //GtkWindowGroup *oldGroup; GtkWindow *window = GTK_WINDOW(owner->border); GtkWidget *old_popup_grab; - + _in_popup++; - + // Remove possible current button grab gApplication::setButtonGrab(NULL); // //oldGroup = enterGroup(); - + gtk_window_set_modal(window, true); gdk_window_set_override_redirect(gtk_widget_get_window(owner->border), true); owner->show(); - + old_popup_grab = _popup_grab; _popup_grab = owner->border; - + if (_in_popup == 1) gApplication::grabPopup(); - + _loopLevel++; _loop_owner = owner; - + (*onEnterEventLoop)(); do { @@ -1206,16 +1206,16 @@ } while (_loopLevel > l); (*onLeaveEventLoop)(); - + gApplication::ungrabPopup(); _popup_grab = old_popup_grab; - + _loop_owner = old_owner; gdk_window_set_override_redirect(gtk_widget_get_window(owner->border), false); gtk_window_set_modal(window, false); //exitGroup(oldGroup); - + _in_popup--; } @@ -1223,7 +1223,7 @@ { if (!hasLoop(owner)) return; - + if (_loopLevel > 0) _loopLevel--; } @@ -1250,7 +1250,7 @@ static void post_focus_change(void *) { gControl *current, *control, *next; - + if (!_focus_change) return; @@ -1271,15 +1271,15 @@ control->onFocusEvent(control, gEvent_FocusOut); control = next; } - + current = gApplication::activeControl(); if (current == gApplication::_old_active_control) break; - + gApplication::_old_active_control = current; //fprintf(stderr, "_old_active_control = %s\n", current ? current->name() : NULL); gMainWindow::setActiveWindow(current); - + control = gApplication::activeControl(); while (control) { @@ -1289,7 +1289,7 @@ control = next; } } - + _focus_change = FALSE; } @@ -1302,7 +1302,7 @@ { if (_focus_change) return; - + _focus_change = TRUE; GB.Post((void (*)())post_focus_change, NULL); } @@ -1327,7 +1327,7 @@ //GtkStyle* st; gint trough_border; gint slider_width; - + //st = gtk_rc_get_style_by_paths(gtk_settings_get_default(), NULL, "OsBar", G_TYPE_NONE); if (g_type_from_name("OsBar")) @@ -1336,7 +1336,7 @@ if (!env || *env != '0') return 1; } - + gt_get_style_property(GTK_TYPE_SCROLLBAR, "slider-width", &slider_width); gt_get_style_property(GTK_TYPE_SCROLLBAR, "trough-border", &trough_border); @@ -1346,9 +1346,9 @@ int gApplication::getScrollbarSpacing() { gint v; - + gt_get_style_property(GTK_TYPE_SCROLLED_WINDOW, "scrollbar-spacing", &v); - + return v; } @@ -1462,12 +1462,20 @@ void gApplication::setEventFilter(X11_EVENT_FILTER filter) { static X11_EVENT_FILTER save_filter = NULL; + static GdkEventMask save_mask = (GdkEventMask)0; if (save_filter) + { gdk_window_remove_filter(NULL, (GdkFilterFunc)x11_event_filter, (gpointer)save_filter); + gdk_window_set_events(gdk_get_default_root_window(), save_mask); + } if (filter) + { + save_mask = gdk_window_get_events(gdk_get_default_root_window()); + gdk_window_set_events(gdk_get_default_root_window(), (GdkEventMask)(save_mask | GDK_PROPERTY_CHANGE_MASK | GDK_STRUCTURE_MASK)); gdk_window_add_filter(NULL, (GdkFilterFunc)x11_event_filter, (gpointer)filter); + } save_filter = filter; } diff -Nru gambas3-3.8.3/gb.gtk/src/gdrawingarea.cpp gambas3-3.8.4/gb.gtk/src/gdrawingarea.cpp --- gambas3-3.8.3/gb.gtk/src/gdrawingarea.cpp 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.gtk/src/gdrawingarea.cpp 2015-12-22 04:46:12.000000000 +0000 @@ -38,6 +38,8 @@ *****************************************************************************************/ +int gDrawingArea::_in_any_draw_event = 0; + #ifdef GTK3 static gboolean cb_draw(GtkWidget *wid, cairo_t *cr, gDrawingArea *data) { @@ -53,8 +55,10 @@ if (data->onExpose) { + gDrawingArea::_in_any_draw_event++; data->_in_draw_event = true; data->onExpose(data, cr); + gDrawingArea::_in_any_draw_event--; data->_in_draw_event = false; } data->drawBorder(cr); @@ -75,6 +79,7 @@ if (data->onExpose) { + gDrawingArea::_in_any_draw_event++; data->_in_draw_event = true; /*GdkRectangle *rect; @@ -87,6 +92,7 @@ g_free(rect);*/ data->onExpose(data, e->region, wid->allocation.x, wid->allocation.y); + gDrawingArea::_in_any_draw_event--; data->_in_draw_event = false; } data->drawBorder(e); diff -Nru gambas3-3.8.3/gb.gtk/src/gdrawingarea.h gambas3-3.8.4/gb.gtk/src/gdrawingarea.h --- gambas3-3.8.3/gb.gtk/src/gdrawingarea.h 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.gtk/src/gdrawingarea.h 2015-12-22 04:46:12.000000000 +0000 @@ -39,8 +39,9 @@ void setCached(bool vl); void setNoBackground(bool vl); void setUseTablet(bool vl); - + bool inDrawEvent() const { return _in_draw_event; } + static bool inAnyDrawEvent() { return _in_any_draw_event; } //"Methods" void clear(); @@ -65,7 +66,7 @@ void updateEventMask(); void setCache(); void updateUseTablet(); - + #ifdef GTK3 cairo_surface_t *buffer; #else @@ -79,6 +80,7 @@ unsigned _in_draw_event : 1; unsigned _no_background : 1; unsigned _use_tablet : 1; + static int _in_any_draw_event; }; #endif diff -Nru gambas3-3.8.3/gb.gtk/src/main.cpp gambas3-3.8.4/gb.gtk/src/main.cpp --- gambas3-3.8.3/gb.gtk/src/main.cpp 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.gtk/src/main.cpp 2015-12-22 04:46:12.000000000 +0000 @@ -205,11 +205,11 @@ int EXPORT GB_INIT(void) { char *env; - + env = getenv("GB_GUI_BUSY"); if (env && atoi(env)) MAIN_debug_busy = true; - + GB.Hook(GB_HOOK_QUIT, (void *)my_quit); _old_hook_main = GB.Hook(GB_HOOK_MAIN, (void *)my_main); GB.Hook(GB_HOOK_WAIT, (void *)my_wait); @@ -226,7 +226,7 @@ GB.GetInterface("gb.image", IMAGE_INTERFACE_VERSION, &IMAGE); IMAGE.SetDefaultFormat(GB_IMAGE_RGBA); DRAW_init(); - + CWatcher::init(); CLASS_Control = GB.FindClass("Control"); @@ -241,11 +241,11 @@ CLASS_Printer = GB.FindClass("Printer"); CLASS_Image = GB.FindClass("Image"); CLASS_SvgImage = GB.FindClass("SvgImage"); - + #if !defined(GLIB_VERSION_2_36) g_type_init(); #endif /* !defined(GLIB_VERSION_2_36) */ - + my_lang(GB.System.Language(), GB.System.IsRightToLeft()); return -1; @@ -301,7 +301,7 @@ void EXPORT GB_SIGNAL(int signal, void *param) { static GtkWidget *save_popup_grab = NULL; - + switch(signal) { case GB_SIGNAL_DEBUG_BREAK: @@ -311,14 +311,14 @@ gApplication::ungrabPopup(); } break; - + case GB_SIGNAL_DEBUG_FORWARD: //while (qApp->activePopupWidget()) // delete qApp->activePopupWidget(); if (gdk_display_get_default()) gdk_display_sync(gdk_display_get_default()); break; - + case GB_SIGNAL_DEBUG_CONTINUE: GB.Post((GB_CALLBACK)activate_main_window, 0); if (save_popup_grab) @@ -336,19 +336,19 @@ void my_quit (void) { GB_FUNCTION func; - + while (gtk_events_pending()) gtk_main_iteration(); - + if (GB.ExistClass("TrayIcons")) { if (!GB.GetFunction(&func, (void *)GB.FindClass("TrayIcons"), "DeleteAll", NULL, NULL)) GB.Call(&func, 0, FALSE); } - + if (!GB.GetFunction(&func, (void *)GB.FindClass("_Gui"), "_Quit", NULL, NULL)) GB.Call(&func, 0, FALSE); - + CWINDOW_delete_all(); gControl::cleanRemovedControls(); @@ -370,10 +370,10 @@ { static bool init = false; char *env; - + if (init) return; - + env = getenv("GB_X11_INIT_THREADS"); if (env && atoi(env)) XInitThreads(); @@ -381,10 +381,10 @@ gApplication::init(argc, argv); gApplication::setDefaultTitle(GB.Application.Title()); gDesktop::init(); - + gApplication::onEnterEventLoop = GB.Debug.EnterEventLoop; gApplication::onLeaveEventLoop = GB.Debug.LeaveEventLoop; - + MAIN_scale = gDesktop::scale(); #ifdef GDK_WINDOWING_X11 X11_init(gdk_x11_display_get_xdisplay(gdk_display_get_default()), gdk_x11_get_default_root_xwindow()); @@ -417,10 +417,10 @@ gboolean my_timer_function(GB_TIMER *timer) { - if (timer->id) + if (timer->id) { GB.RaiseTimer(timer); - + if (timer->id) { MyTimerId *id = (MyTimerId *)timer->id; @@ -436,7 +436,7 @@ //fprintf(stderr, "elapsed = %d delay = %d next = %d\n", elapsed, timer->delay, next); } } - + return false; } @@ -476,7 +476,7 @@ { gControl::cleanRemovedControls(); _must_check_quit = true; - + for(;;) { if (_must_check_quit) @@ -491,12 +491,18 @@ } my_quit(); - + return 0; } static void my_wait(int duration) { + if (gDrawingArea::inAnyDrawEvent()) + { + GB.Error("Wait is forbidden during a repaint event"); + return; + } + if (duration > 0 && gKey::valid()) { #ifdef GTK3 @@ -536,7 +542,7 @@ gControl *iter; MAIN_rtl = rtl; - + if (rtl) gtk_widget_set_default_direction(GTK_TEXT_DIR_RTL); else @@ -566,9 +572,9 @@ if (gtk_events_pending ()) gtk_main_iteration_do (false); } - else + else gtk_main_iteration_do(true); - + gApplication::_loopLevel--; if (_post_check) @@ -576,7 +582,7 @@ _post_check = false; GB.CheckPost(); } - + gControl::cleanRemovedControls(); } diff -Nru gambas3-3.8.3/gb.gtk/src/x11.c gambas3-3.8.4/gb.gtk/src/x11.c --- gambas3-3.8.3/gb.gtk/src/x11.c 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.gtk/src/x11.c 2015-12-22 04:46:12.000000000 +0000 @@ -111,14 +111,14 @@ {NULL} }; -typedef +typedef struct { unsigned long flags; unsigned long functions; unsigned long decorations; long input_mode; unsigned long status; - } + } MwmHints; static void init_atoms() @@ -140,17 +140,17 @@ X11_atom_net_wm_user_time = XInternAtom(_display, "_NET_WM_USER_TIME", True); X11_atom_net_supported = XInternAtom(_display, "_NET_SUPPORTED", True); - + _atom_init = TRUE; } static Atom get_atom(int index) { X11_ATOM *a = &_atoms[index]; - + if (!a->atom) a->atom = XInternAtom(_display, a->name, True); - + return a->atom; } @@ -158,7 +158,7 @@ { int i = 0; X11_ATOM *p = _atoms; - + while (p->name) { if (!p->atom) @@ -209,24 +209,24 @@ False, AnyPropertyType, type, format, &count, &after, &data) != Success) return NULL; - + *pcount += count; - + size = *format == 32 ? sizeof(long) : ( *format == 16 ? sizeof(short) : 1 ); offset_size = *format == 32 ? sizeof(int32_t) : ( *format == 16 ? sizeof(short) : 1 ); - + //fprintf(stderr, "X11_get_property: format = %d size = %d count = %ld after = %ld\n", *format, size, count, after); - + GB.FreeString(&_property_value); _property_value = GB.NewString((char *)data, count * size); XFree(data); - + offset = count * offset_size / sizeof(int32_t); - + while (after) { //fprintf(stderr, "X11_get_property: offset = %ld read = %ld\n", offset, Min(after, PROPERTY_NEXT_READ) / sizeof(int32_t)); - + if (XGetWindowProperty(_display, wid, prop, offset, Min(after, PROPERTY_NEXT_READ) / sizeof(int32_t), False, AnyPropertyType, type, format, &count, &after, &data) != Success) @@ -234,13 +234,13 @@ *pcount += count; offset += count * offset_size / sizeof(int32_t); - + //fprintf(stderr, "X11_get_property: format = %d size = %d count = %ld after = %ld next offset = %ld\n", *format, size, count, after, offset); - + _property_value = GB.AddString(_property_value, (char *)data, count * size); XFree(data); } - + return _property_value; } @@ -248,7 +248,7 @@ { Atom type; int format; - + return X11_get_property(wid, prop, &type, &format, count); } @@ -267,7 +267,8 @@ length = MAX_WINDOW_PROP; _window_prop.count = length; - memcpy(_window_prop.atoms, data, length * sizeof(Atom)); + if (data) + memcpy(_window_prop.atoms, data, length * sizeof(Atom)); } static void save_window_state(Window win, Atom prop) @@ -338,7 +339,7 @@ data = get_property(_root, X11_atom_net_supported, &count); if (!data) return; - + GB.NewArray(&_supported, sizeof(Atom), count); memcpy(_supported, data, sizeof(Atom) * count); } @@ -393,7 +394,7 @@ { _window = window; _window_visible = visible; - + if (!visible) load_window_state(window, X11_atom_net_wm_state); } @@ -402,7 +403,7 @@ { if (!_window_visible) save_window_state(_window, X11_atom_net_wm_state); - + XFlush(_display); _window = (Window)0; } @@ -552,34 +553,34 @@ int X11_window_get_desktop(Window window) { - int length = 0; + int length; char *data = NULL; int desktop = 0; data = get_property(window, X11_atom_net_wm_desktop, &length); - if (data) desktop = *((int *)data); - + return desktop; } int X11_get_current_desktop() { - int length = 0; + int length; char *data; - int desktop; + int desktop = 0; data = get_property(_root, X11_atom_net_current_desktop, &length); + if (data) + desktop = *((int *)data); - desktop = *((int *)data); return desktop; } int X11_get_window_type(Window window) { int index; - + load_window_state(window, X11_atom_net_wm_window_type); index = find_atom(_window_prop.atoms[0]); if (index < 0) @@ -603,7 +604,7 @@ void X11_set_window_decorated(Window window, bool decorated) { // Motif structures - + MwmHints *hints; MwmHints new_hints; @@ -612,7 +613,7 @@ int format; ulong nitems; ulong bytes_after; - + if (X11_atom_motif_wm_hints == None) X11_atom_motif_wm_hints = XInternAtom(_display, "_MOTIF_WM_HINTS", True); @@ -620,7 +621,7 @@ X11_atom_motif_wm_hints, 0, sizeof(MwmHints)/sizeof(long), False, AnyPropertyType, &type, &format, &nitems, &bytes_after, &data); - + if (type == None) { hints = &new_hints; @@ -632,17 +633,17 @@ } else hints = (MwmHints *)data; - + hints->flags |= (1 << 1); - hints->decorations = decorated ? 1 : 0; - + hints->decorations = decorated ? 1 : 0; + XChangeProperty(_display, window, X11_atom_motif_wm_hints, X11_atom_motif_wm_hints, 32, PropModeReplace, (uchar *)hints, sizeof (MwmHints)/sizeof(long)); - + if (hints != &new_hints) XFree(hints); - + XFlush(_display); } @@ -675,7 +676,7 @@ X11_atom_net_workarea, 0, 4, False, XA_CARDINAL, &ret, &format, &nitems, &after, &data); - if (e == Success && ret == XA_CARDINAL && format == 32 && nitems == 4) + if (e == Success && ret == XA_CARDINAL && format == 32 && nitems == 4) { long *workarea = (long *)data; *x = workarea[0]; @@ -683,18 +684,18 @@ *w = workarea[2]; *h = workarea[3]; err = FALSE; - } + } if (data) XFree(data); - + return err; } bool X11_is_supported_by_WM(Atom atom) { int i; - + if (_supported) { for (i = 0; i < GB.Count(_supported); i++) @@ -714,10 +715,10 @@ if (!_net_moveresize_window) _net_moveresize_window = XInternAtom(_display, "_NET_MOVERESIZE_WINDOW", True); - + if (!X11_is_supported_by_WM(_net_moveresize_window)) return TRUE; - + e.xclient.type = ClientMessage; e.xclient.message_type = _net_moveresize_window; e.xclient.display = _display; @@ -729,20 +730,20 @@ e.xclient.data.l[3] = w; e.xclient.data.l[4] = h; XSendEvent(_display, _root, FALSE, (SubstructureNotifyMask | SubstructureRedirectMask), &e); - + return FALSE; } static Atom get_net_system_tray(void) { char buf[64]; - + if (X11_atom_net_system_tray == None) { sprintf(buf, "_NET_SYSTEM_TRAY_S%d", XScreenNumberOfScreen(DefaultScreenOfDisplay(_display))); X11_atom_net_system_tray = XInternAtom(_display, buf, 0); } - + return X11_atom_net_system_tray; } @@ -772,7 +773,7 @@ XUngrabServer(_display); XFlush(_display); - + if (xmanager == None) return TRUE; @@ -795,7 +796,7 @@ XSendEvent(_display, xmanager, 0, NoEventMask, (XEvent *)&ev); XSync(_display, 0); usleep(10000); - + return FALSE; } #endif diff -Nru gambas3-3.8.3/gb.gtk3/acinclude.m4 gambas3-3.8.4/gb.gtk3/acinclude.m4 --- gambas3-3.8.3/gb.gtk3/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.gtk3/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.gtk3/src/gapplication.cpp gambas3-3.8.4/gb.gtk3/src/gapplication.cpp --- gambas3-3.8.3/gb.gtk3/src/gapplication.cpp 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.gtk3/src/gapplication.cpp 2015-12-22 04:46:12.000000000 +0000 @@ -45,9 +45,9 @@ static bool _debug_keypress = false; /************************************************************************** - + Global event handler - + **************************************************************************/ static bool _focus_change = false; @@ -74,7 +74,7 @@ /*static bool raise_key_event_to_parent_window(gControl *control, int type) { gMainWindow *win; - + while (control->parent()) { win = control->parent()->window(); @@ -84,10 +84,10 @@ if (win->onKeyEvent(win, type)) return true; } - + control = win; } - + return false; }*/ @@ -97,9 +97,9 @@ #if DEBUG_ENTER_LEAVE fprintf(stderr, "check_crossing_event: %d / %d\n", event->crossing.detail, event->crossing.mode); #endif - + return true; - + if ((event->crossing.mode == GDK_CROSSING_NORMAL || event->crossing.mode == GDK_CROSSING_STATE_CHANGED)) // || event->crossing.mode == GDK_CROSSING_UNGRAB || event->crossing.mode == GDK_CROSSING_GTK_UNGRAB)) return true; @@ -116,7 +116,7 @@ gControl *child; int x, y; int cx, cy, cw, ch; - + if (gApplication::_control_grab) return gApplication::_control_grab; @@ -134,19 +134,19 @@ //fprintf(stderr, "find_child: %s\n", control->name()); control = control->topLevel(); - + while (control->isContainer()) { control->getScreenPos(&x, &y); cont = (gContainer *)control; - + cx = cont->clientX(); cy = cont->clientY(); cw = cont->clientWidth(); ch = cont->clientHeight(); - + //fprintf(stderr, "client area of %s: %d %d %d %d\n", control->name(), cx, cy, cw, ch); - + x = rx - x; y = ry - y; if (x < cx || y < cy || x >= (cx + cw) || y >= (cy + ch)) @@ -154,16 +154,16 @@ //fprintf(stderr, "outside of client area of %s\n", control->name()); return NULL; } - + child = cont->find(x, y); if (!child) break; - + control = child; } //fprintf(stderr, "-> %s\n", control->name()); - + return control; } @@ -174,9 +174,9 @@ #if DEBUG_ENTER_LEAVE fprintf(stderr, "checkHoveredControl: %s\n", control->name()); #endif - + gControl *leave = gApplication::_enter; - + while (leave && leave != control && !leave->isAncestorOf(control)) { #if DEBUG_ENTER_LEAVE @@ -185,11 +185,11 @@ leave->emitLeaveEvent(); leave = leave->parent(); } - + #if DEBUG_ENTER_LEAVE fprintf(stderr, "checkHoveredControl: _enter <- %s\n", control ? control->name() : "ø"); #endif - + if (control) { #if DEBUG_ENTER_LEAVE @@ -245,14 +245,14 @@ } } } - + /*if (event->type == GDK_GRAB_BROKEN) { if (gApplication::_in_popup) fprintf(stderr, "**** GDK_GRAB_BROKEN inside popup: %s %swindow = %p grab_window = %p popup_window = %p\n", event->grab_broken.keyboard ? "keyboard" : "pointer", event->grab_broken.implicit ? "implicit " : "", event->grab_broken.window, event->grab_broken.grab_window, gApplication::_popup_grab_window); }*/ - + if (!((event->type >= GDK_MOTION_NOTIFY && event->type <= GDK_FOCUS_CHANGE) || event->type == GDK_SCROLL)) goto __HANDLE_EVENT; @@ -319,7 +319,7 @@ // grab = gApplication::_popup_grab; } //gdk_window_get_user_data(gApplication::_popup_grab_window, (gpointer *)&grab); - + if (grab) { control = gt_get_control(grab); @@ -328,17 +328,17 @@ if (!control) goto __HANDLE_EVENT; } - + //if (event->type == GDK_BUTTON_RELEASE) // fprintf(stderr, "GDK_BUTTON_RELEASE #2\n"); - + if (event->type == GDK_FOCUS_CHANGE) { control = NULL; //if (GTK_IS_WINDOW(widget)) control = gt_get_control(widget); //fprintf(stderr, "GDK_FOCUS_CHANGE: widget = %p %d : %s %d\n", widget, GTK_IS_WINDOW(widget), control ? control->name() : NULL, event->focus_change.in); - + //if (GTK_IS_WINDOW(widget)) { control = gt_get_control(widget); @@ -358,10 +358,10 @@ // Must continue, otherwise things are broken by some styles //return; } - + goto __HANDLE_EVENT; } - + if (grab && widget != grab && !gtk_widget_is_ancestor(widget, grab)) { //fprintf(stderr, "-> widget = grab\n"); @@ -369,7 +369,7 @@ } //fprintf(stderr, "grab = %p widget = %p %d\n", grab, widget, grab && !gtk_widget_is_ancestor(widget, grab)); - + while (widget) { control = gt_get_control(widget); @@ -377,7 +377,7 @@ break; widget = gtk_widget_get_parent(widget); } - + /*if (event->type == GDK_BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE || event->type == GDK_MOTION_NOTIFY) { fprintf(stderr, "[%s] widget = %p grab = %p _popup_grab = %p _button_grab = %p\n", @@ -397,54 +397,54 @@ goto __HANDLE_EVENT; __FOUND_WIDGET: - + //fprintf(stderr, "control = %p %s\n", control, control->name()); - + /*switch ((int)event->type) { case GDK_ENTER_NOTIFY: fprintf(stderr, "ENTER: %p %s\n", control, control ? control->name() : 0); break; - + case GDK_LEAVE_NOTIFY: fprintf(stderr, "LEAVE: %p %s\n", control, control ? control->name() : 0); break; }*/ - + //group = get_window_group(widget); //if (group != gApplication::currentGroup()) // goto __HANDLE_EVENT; - + cancel = false; - + gApplication::updateLastEvent(event); - + switch ((int)event->type) { case GDK_ENTER_NOTIFY: - + control = find_child(control, (int)event->crossing.x_root, (int)event->crossing.y_root); if (!control) goto __HANDLE_EVENT; - + #if DEBUG_ENTER_LEAVE fprintf(stderr, "GDK_ENTER_NOTIFY: %s (%s) %d %d %p %p\n", control->name(), gApplication::_enter ? gApplication::_enter->name() : "ø", (int)event->crossing.x_root, (int)event->crossing.y_root, event->crossing.window, event->crossing.subwindow); #endif - + if (button_grab) { gApplication::_enter_after_button_grab = control; break; } - + if (gApplication::_leave) { if (gApplication::_leave == control || gApplication::_leave->isAncestorOf(control)) gApplication::_leave = NULL; } - + gApplication::checkHoveredControl(control); - + /* if (gApplication::_leave == control) { @@ -465,18 +465,18 @@ }*/ break; - + case GDK_LEAVE_NOTIFY: - + #if DEBUG_ENTER_LEAVE fprintf(stderr, "GDK_LEAVE_NOTIFY: %s %p %p\n", control->name(), event->crossing.window, event->crossing.subwindow); #endif - + if (button_grab) break; - + //control = find_child(control, (int)event->button.x_root, (int)event->button.y_root); - + gApplication::_leave = control; /* if (gdk_events_pending() && gApplication::_leave == NULL) @@ -495,7 +495,7 @@ { if (gApplication::_leave == control) gApplication::_leave = NULL; - + #if DEBUG_ENTER_LEAVE fprintf(stderr, "leave: %s\n", control->name()); #endif @@ -503,12 +503,12 @@ } } */ - + //if (widget != control->border && widget != control->widget) // goto __RETURN; - + break; - + case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_BUTTON_RELEASE: @@ -518,14 +518,14 @@ goto __HANDLE_EVENT; bool menu = false; - + switch ((int)event->type) { case GDK_BUTTON_PRESS: type = gEvent_MousePress; break; case GDK_2BUTTON_PRESS: type = gEvent_MouseDblClick; break; default: type = gEvent_MouseRelease; break; } - + if (event->type != GDK_BUTTON_RELEASE) { if (control->canFocus() && !control->hasFocus()) @@ -534,11 +534,11 @@ gApplication::setButtonGrab(control); } - + __BUTTON_TRY_PROXY: - + cancel = false; - + if (control->onMouseEvent) { if (control->canRaise(control, type)) @@ -548,31 +548,31 @@ ys = (int)event->button.y_root; x = xs - xc; y = ys - yc; - + gMouse::validate(); gMouse::setEvent(event); //gMouse::setValid(1,(int)event->x,(int)event->y,event->button,event->state,data->screenX(),data->screenY()); gMouse::setMouse(x, y, xs, ys, event->button.button, event->button.state); switch ((int)event->type) { - case GDK_BUTTON_PRESS: + case GDK_BUTTON_PRESS: gMouse::setStart(x, y); cancel = control->onMouseEvent(control, gEvent_MousePress); break; - - case GDK_2BUTTON_PRESS: - cancel = control->onMouseEvent(control, gEvent_MouseDblClick); + + case GDK_2BUTTON_PRESS: + cancel = control->onMouseEvent(control, gEvent_MouseDblClick); break; - - case GDK_BUTTON_RELEASE: - cancel = control->onMouseEvent(control, gEvent_MouseRelease); + + case GDK_BUTTON_RELEASE: + cancel = control->onMouseEvent(control, gEvent_MouseRelease); break; } - + gMouse::invalidate(); } } - + if (type == gEvent_MousePress && control->isTopLevel()) { gMainWindow *win = ((gMainWindow *)control); @@ -583,7 +583,7 @@ ys = (int)event->button.y_root; x = xs - xc; y = ys - yc; - + if (x < 0 || y < 0 || x >= win->width() || y >= win->height()) win->close(); } @@ -592,14 +592,14 @@ { gApplication::exitLoop(control); } - + #if GTK_CHECK_VERSION(3, 4, 0) if (gdk_event_triggers_context_menu(event)) #else if (event->button.button == 3 && event->type == GDK_BUTTON_PRESS) #endif menu = true; - + if (!cancel) { if (control->_proxy_for) @@ -609,7 +609,7 @@ goto __BUTTON_TRY_PROXY; } } - + if (menu) { control = save_control; @@ -623,7 +623,7 @@ control = control->_proxy_for; } } - + if (cancel) { gMouse::resetTranslate(); @@ -636,10 +636,10 @@ gMouse::resetTranslate(); goto __RETURN; } - + break; } - + case GDK_MOTION_NOTIFY: gdk_event_request_motions(&event->motion); @@ -647,13 +647,13 @@ save_control = control = find_child(control, (int)event->motion.x_root, (int)event->motion.y_root, button_grab); if (!control) goto __HANDLE_EVENT; - + //fprintf(stderr, "GDK_MOTION_NOTIFY: (%p %s) grab = %p\n", control, control->name(), button_grab); - + gApplication::checkHoveredControl(control); - + __MOTION_TRY_PROXY: - + if (control->onMouseEvent && (control->canRaise(control, gEvent_MouseMove) || control->canRaise(control, gEvent_MouseDrag)) && (control->isTracking() || (event->motion.state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)))) { @@ -662,15 +662,15 @@ ys = (int)event->motion.y_root; x = xs - xc; y = ys - yc; - + gMouse::validate(); gMouse::setEvent(event); gMouse::setMouse(x, y, xs, ys, 0, event->motion.state); - + //fprintf(stderr, "pressure = %g\n", gMouse::getAxis(GDK_AXIS_PRESSURE)); - + cancel = control->onMouseEvent(control, gEvent_MouseMove); - + //if (data->acceptDrops() && gDrag::checkThreshold(data, gMouse::x(), gMouse::y(), gMouse::startX(), gMouse::startY())) if (!cancel && (event->motion.state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) //&& (abs(gMouse::x() - gMouse::y()) + abs(gMouse::startX() - gMouse::startY())) > 8) @@ -680,7 +680,7 @@ cancel = control->onMouseEvent(control, gEvent_MouseDrag); } gMouse::invalidate(); - + if (cancel) goto __RETURN; } @@ -691,15 +691,15 @@ //fprintf(stderr, "MOVE: try %s\n", control->name()); goto __MOTION_TRY_PROXY; } - + gMouse::resetTranslate(); //if (widget != save_control->border && widget != save_control->widget) // goto __RETURN; - + break; - + case GDK_SCROLL: - + save_control = control = find_child(control, (int)event->scroll.x_root, (int)event->scroll.y_root); if (!control) goto __HANDLE_EVENT; @@ -709,7 +709,7 @@ if (control->onMouseEvent && control->canRaise(control, gEvent_MouseWheel)) { int dir, dt, ort; - + control->getScreenPos(&xc, &yc); xs = (int)event->scroll.x_root; ys = (int)event->scroll.y_root; @@ -738,7 +738,7 @@ case GDK_SCROLL_RIGHT: dt = 1; ort = 0; break; case GDK_SCROLL_UP: default: dt = 1; ort = 1; break; } - + gMouse::validate(); gMouse::setEvent(event); gMouse::setMouse(x, y, xs, ys, 0, event->scroll.state); @@ -752,19 +752,19 @@ gMouse::resetTranslate(); goto __RETURN; } - + if (control->_proxy_for) { control = control->_proxy_for; goto __SCROLL_TRY_PROXY; } - + if (widget != save_control->border && widget != save_control->widget) { gMouse::resetTranslate(); goto __RETURN; } - + break; case GDK_KEY_PRESS: @@ -779,11 +779,11 @@ gKey::_last_key_release = event->key.keyval; goto __HANDLE_EVENT; } - + __HANDLE_EVENT: gtk_main_do_event(event); - + __RETURN: if (!gdk_events_pending()) // && event->type != GDK_ENTER_NOTIFY && event->type != GDK_LEAVE_NOTIFY) @@ -794,12 +794,12 @@ #if DEBUG_ENTER_LEAVE fprintf(stderr, "post leave: %s\n", gApplication::_leave->name()); #endif - + if (gApplication::_enter == gApplication::_leave) gApplication::_enter = NULL; - + gApplication::_leave->emitLeaveEvent(); - + gApplication::_leave = NULL; } } @@ -855,10 +855,10 @@ void gApplication::grabPopup() { //fprintf(stderr, "grabPopup: %p\n", _popup_grab); - + if (!_popup_grab) return; - + gt_grab(_popup_grab, TRUE, GDK_CURRENT_TIME); } @@ -964,21 +964,21 @@ void gApplication::init(int *argc, char ***argv) { appEvents=0; - + gtk_init(argc, argv); session_manager_init(argc, argv); g_signal_connect(gnome_master_client(), "save-yourself", G_CALLBACK(master_client_save_yourself), NULL); g_signal_connect(gnome_master_client(), "die", G_CALLBACK(master_client_die), NULL); gdk_event_handler_set((GdkEventFunc)gambas_handle_event, NULL, NULL); - + gKey::init(); - + onEnterEventLoop = do_nothing; onLeaveEventLoop = do_nothing; _group = gtk_window_group_new(); - + _loop_owner = 0; char *env = getenv("GB_GTK_DEBUG_KEYPRESS"); @@ -1002,7 +1002,7 @@ void gApplication::exit() { session_manager_exit(); - + if (_title) g_free(_title); @@ -1019,23 +1019,23 @@ { GList *iter; int ct=1; - + if (!gControl::controlList()) return 0; - + iter=g_list_first(gControl::controlList()); while (iter->next) { ct++; iter=iter->next; } - + return ct; } gControl* gApplication::controlItem(GtkWidget *wid) { gControl *control; - + while (wid) { control = gt_get_control(wid); @@ -1043,14 +1043,14 @@ return control; wid = gtk_widget_get_parent(wid); } - + return NULL; } gControl* gApplication::controlItem(int index) { GList *iter; - + if (!gControl::controlList()) return NULL; iter=g_list_nth(gControl::controlList(),index); if (!iter) return NULL; @@ -1088,10 +1088,10 @@ { GList *iter; gControl *control; - + if (gContainer::_arrangement_level) return true; - + _dirty = false; //g_debug(">>>> update_geometry"); iter = g_list_first(gControl::controlList()); @@ -1102,7 +1102,7 @@ iter = iter->next; } //g_debug("<<<<"); - + return false; } @@ -1110,7 +1110,7 @@ { if (_dirty) return; - + _dirty = true; g_timeout_add(0, (GSourceFunc)update_geometry, NULL); } @@ -1127,22 +1127,22 @@ gControl *control = _enter; GtkWindowGroup *oldGroup = _group; _group = gtk_window_group_new(); - + _enter = _leave = NULL; - + while (control) { control->emit(SIGNAL(control->onEnterLeave), gEvent_Leave); control = control->parent(); } - + return oldGroup; } void gApplication::exitGroup(GtkWindowGroup *oldGroup) { g_object_unref(_group); - _group = oldGroup; + _group = oldGroup; } void gApplication::enterLoop(void *owner, bool showIt, GtkWindow *modal) @@ -1150,14 +1150,14 @@ void *old_owner = _loop_owner; int l = _loopLevel; //GtkWindowGroup *oldGroup; - + if (showIt) ((gControl *)owner)->show(); //oldGroup = enterGroup(); - + _loopLevel++; _loop_owner = owner; - + (*onEnterEventLoop)(); do { @@ -1165,7 +1165,7 @@ } while (_loopLevel > l); (*onLeaveEventLoop)(); - + _loop_owner = old_owner; //exitGroup(oldGroup); @@ -1178,27 +1178,27 @@ //GtkWindowGroup *oldGroup; GtkWindow *window = GTK_WINDOW(owner->border); GtkWidget *old_popup_grab; - + _in_popup++; - + // Remove possible current button grab gApplication::setButtonGrab(NULL); // //oldGroup = enterGroup(); - + gtk_window_set_modal(window, true); gdk_window_set_override_redirect(gtk_widget_get_window(owner->border), true); owner->show(); - + old_popup_grab = _popup_grab; _popup_grab = owner->border; - + if (_in_popup == 1) gApplication::grabPopup(); - + _loopLevel++; _loop_owner = owner; - + (*onEnterEventLoop)(); do { @@ -1206,16 +1206,16 @@ } while (_loopLevel > l); (*onLeaveEventLoop)(); - + gApplication::ungrabPopup(); _popup_grab = old_popup_grab; - + _loop_owner = old_owner; gdk_window_set_override_redirect(gtk_widget_get_window(owner->border), false); gtk_window_set_modal(window, false); //exitGroup(oldGroup); - + _in_popup--; } @@ -1223,7 +1223,7 @@ { if (!hasLoop(owner)) return; - + if (_loopLevel > 0) _loopLevel--; } @@ -1250,7 +1250,7 @@ static void post_focus_change(void *) { gControl *current, *control, *next; - + if (!_focus_change) return; @@ -1271,15 +1271,15 @@ control->onFocusEvent(control, gEvent_FocusOut); control = next; } - + current = gApplication::activeControl(); if (current == gApplication::_old_active_control) break; - + gApplication::_old_active_control = current; //fprintf(stderr, "_old_active_control = %s\n", current ? current->name() : NULL); gMainWindow::setActiveWindow(current); - + control = gApplication::activeControl(); while (control) { @@ -1289,7 +1289,7 @@ control = next; } } - + _focus_change = FALSE; } @@ -1302,7 +1302,7 @@ { if (_focus_change) return; - + _focus_change = TRUE; GB.Post((void (*)())post_focus_change, NULL); } @@ -1327,7 +1327,7 @@ //GtkStyle* st; gint trough_border; gint slider_width; - + //st = gtk_rc_get_style_by_paths(gtk_settings_get_default(), NULL, "OsBar", G_TYPE_NONE); if (g_type_from_name("OsBar")) @@ -1336,7 +1336,7 @@ if (!env || *env != '0') return 1; } - + gt_get_style_property(GTK_TYPE_SCROLLBAR, "slider-width", &slider_width); gt_get_style_property(GTK_TYPE_SCROLLBAR, "trough-border", &trough_border); @@ -1346,9 +1346,9 @@ int gApplication::getScrollbarSpacing() { gint v; - + gt_get_style_property(GTK_TYPE_SCROLLED_WINDOW, "scrollbar-spacing", &v); - + return v; } @@ -1462,12 +1462,20 @@ void gApplication::setEventFilter(X11_EVENT_FILTER filter) { static X11_EVENT_FILTER save_filter = NULL; + static GdkEventMask save_mask = (GdkEventMask)0; if (save_filter) + { gdk_window_remove_filter(NULL, (GdkFilterFunc)x11_event_filter, (gpointer)save_filter); + gdk_window_set_events(gdk_get_default_root_window(), save_mask); + } if (filter) + { + save_mask = gdk_window_get_events(gdk_get_default_root_window()); + gdk_window_set_events(gdk_get_default_root_window(), (GdkEventMask)(save_mask | GDK_PROPERTY_CHANGE_MASK | GDK_STRUCTURE_MASK)); gdk_window_add_filter(NULL, (GdkFilterFunc)x11_event_filter, (gpointer)filter); + } save_filter = filter; } diff -Nru gambas3-3.8.3/gb.gtk3/src/gdrawingarea.cpp gambas3-3.8.4/gb.gtk3/src/gdrawingarea.cpp --- gambas3-3.8.3/gb.gtk3/src/gdrawingarea.cpp 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.gtk3/src/gdrawingarea.cpp 2015-12-22 04:46:12.000000000 +0000 @@ -38,6 +38,8 @@ *****************************************************************************************/ +int gDrawingArea::_in_any_draw_event = 0; + #ifdef GTK3 static gboolean cb_draw(GtkWidget *wid, cairo_t *cr, gDrawingArea *data) { @@ -53,8 +55,10 @@ if (data->onExpose) { + gDrawingArea::_in_any_draw_event++; data->_in_draw_event = true; data->onExpose(data, cr); + gDrawingArea::_in_any_draw_event--; data->_in_draw_event = false; } data->drawBorder(cr); @@ -75,6 +79,7 @@ if (data->onExpose) { + gDrawingArea::_in_any_draw_event++; data->_in_draw_event = true; /*GdkRectangle *rect; @@ -87,6 +92,7 @@ g_free(rect);*/ data->onExpose(data, e->region, wid->allocation.x, wid->allocation.y); + gDrawingArea::_in_any_draw_event--; data->_in_draw_event = false; } data->drawBorder(e); diff -Nru gambas3-3.8.3/gb.gtk3/src/gdrawingarea.h gambas3-3.8.4/gb.gtk3/src/gdrawingarea.h --- gambas3-3.8.3/gb.gtk3/src/gdrawingarea.h 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.gtk3/src/gdrawingarea.h 2015-12-22 04:46:12.000000000 +0000 @@ -39,8 +39,9 @@ void setCached(bool vl); void setNoBackground(bool vl); void setUseTablet(bool vl); - + bool inDrawEvent() const { return _in_draw_event; } + static bool inAnyDrawEvent() { return _in_any_draw_event; } //"Methods" void clear(); @@ -65,7 +66,7 @@ void updateEventMask(); void setCache(); void updateUseTablet(); - + #ifdef GTK3 cairo_surface_t *buffer; #else @@ -79,6 +80,7 @@ unsigned _in_draw_event : 1; unsigned _no_background : 1; unsigned _use_tablet : 1; + static int _in_any_draw_event; }; #endif diff -Nru gambas3-3.8.3/gb.gtk3/src/main.cpp gambas3-3.8.4/gb.gtk3/src/main.cpp --- gambas3-3.8.3/gb.gtk3/src/main.cpp 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.gtk3/src/main.cpp 2015-12-22 04:46:12.000000000 +0000 @@ -205,11 +205,11 @@ int EXPORT GB_INIT(void) { char *env; - + env = getenv("GB_GUI_BUSY"); if (env && atoi(env)) MAIN_debug_busy = true; - + GB.Hook(GB_HOOK_QUIT, (void *)my_quit); _old_hook_main = GB.Hook(GB_HOOK_MAIN, (void *)my_main); GB.Hook(GB_HOOK_WAIT, (void *)my_wait); @@ -226,7 +226,7 @@ GB.GetInterface("gb.image", IMAGE_INTERFACE_VERSION, &IMAGE); IMAGE.SetDefaultFormat(GB_IMAGE_RGBA); DRAW_init(); - + CWatcher::init(); CLASS_Control = GB.FindClass("Control"); @@ -241,11 +241,11 @@ CLASS_Printer = GB.FindClass("Printer"); CLASS_Image = GB.FindClass("Image"); CLASS_SvgImage = GB.FindClass("SvgImage"); - + #if !defined(GLIB_VERSION_2_36) g_type_init(); #endif /* !defined(GLIB_VERSION_2_36) */ - + my_lang(GB.System.Language(), GB.System.IsRightToLeft()); return -1; @@ -301,7 +301,7 @@ void EXPORT GB_SIGNAL(int signal, void *param) { static GtkWidget *save_popup_grab = NULL; - + switch(signal) { case GB_SIGNAL_DEBUG_BREAK: @@ -311,14 +311,14 @@ gApplication::ungrabPopup(); } break; - + case GB_SIGNAL_DEBUG_FORWARD: //while (qApp->activePopupWidget()) // delete qApp->activePopupWidget(); if (gdk_display_get_default()) gdk_display_sync(gdk_display_get_default()); break; - + case GB_SIGNAL_DEBUG_CONTINUE: GB.Post((GB_CALLBACK)activate_main_window, 0); if (save_popup_grab) @@ -336,19 +336,19 @@ void my_quit (void) { GB_FUNCTION func; - + while (gtk_events_pending()) gtk_main_iteration(); - + if (GB.ExistClass("TrayIcons")) { if (!GB.GetFunction(&func, (void *)GB.FindClass("TrayIcons"), "DeleteAll", NULL, NULL)) GB.Call(&func, 0, FALSE); } - + if (!GB.GetFunction(&func, (void *)GB.FindClass("_Gui"), "_Quit", NULL, NULL)) GB.Call(&func, 0, FALSE); - + CWINDOW_delete_all(); gControl::cleanRemovedControls(); @@ -370,10 +370,10 @@ { static bool init = false; char *env; - + if (init) return; - + env = getenv("GB_X11_INIT_THREADS"); if (env && atoi(env)) XInitThreads(); @@ -381,10 +381,10 @@ gApplication::init(argc, argv); gApplication::setDefaultTitle(GB.Application.Title()); gDesktop::init(); - + gApplication::onEnterEventLoop = GB.Debug.EnterEventLoop; gApplication::onLeaveEventLoop = GB.Debug.LeaveEventLoop; - + MAIN_scale = gDesktop::scale(); #ifdef GDK_WINDOWING_X11 X11_init(gdk_x11_display_get_xdisplay(gdk_display_get_default()), gdk_x11_get_default_root_xwindow()); @@ -417,10 +417,10 @@ gboolean my_timer_function(GB_TIMER *timer) { - if (timer->id) + if (timer->id) { GB.RaiseTimer(timer); - + if (timer->id) { MyTimerId *id = (MyTimerId *)timer->id; @@ -436,7 +436,7 @@ //fprintf(stderr, "elapsed = %d delay = %d next = %d\n", elapsed, timer->delay, next); } } - + return false; } @@ -476,7 +476,7 @@ { gControl::cleanRemovedControls(); _must_check_quit = true; - + for(;;) { if (_must_check_quit) @@ -491,12 +491,18 @@ } my_quit(); - + return 0; } static void my_wait(int duration) { + if (gDrawingArea::inAnyDrawEvent()) + { + GB.Error("Wait is forbidden during a repaint event"); + return; + } + if (duration > 0 && gKey::valid()) { #ifdef GTK3 @@ -536,7 +542,7 @@ gControl *iter; MAIN_rtl = rtl; - + if (rtl) gtk_widget_set_default_direction(GTK_TEXT_DIR_RTL); else @@ -566,9 +572,9 @@ if (gtk_events_pending ()) gtk_main_iteration_do (false); } - else + else gtk_main_iteration_do(true); - + gApplication::_loopLevel--; if (_post_check) @@ -576,7 +582,7 @@ _post_check = false; GB.CheckPost(); } - + gControl::cleanRemovedControls(); } diff -Nru gambas3-3.8.3/gb.gtk3/src/x11.c gambas3-3.8.4/gb.gtk3/src/x11.c --- gambas3-3.8.3/gb.gtk3/src/x11.c 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.gtk3/src/x11.c 2015-12-22 04:46:12.000000000 +0000 @@ -111,14 +111,14 @@ {NULL} }; -typedef +typedef struct { unsigned long flags; unsigned long functions; unsigned long decorations; long input_mode; unsigned long status; - } + } MwmHints; static void init_atoms() @@ -140,17 +140,17 @@ X11_atom_net_wm_user_time = XInternAtom(_display, "_NET_WM_USER_TIME", True); X11_atom_net_supported = XInternAtom(_display, "_NET_SUPPORTED", True); - + _atom_init = TRUE; } static Atom get_atom(int index) { X11_ATOM *a = &_atoms[index]; - + if (!a->atom) a->atom = XInternAtom(_display, a->name, True); - + return a->atom; } @@ -158,7 +158,7 @@ { int i = 0; X11_ATOM *p = _atoms; - + while (p->name) { if (!p->atom) @@ -209,24 +209,24 @@ False, AnyPropertyType, type, format, &count, &after, &data) != Success) return NULL; - + *pcount += count; - + size = *format == 32 ? sizeof(long) : ( *format == 16 ? sizeof(short) : 1 ); offset_size = *format == 32 ? sizeof(int32_t) : ( *format == 16 ? sizeof(short) : 1 ); - + //fprintf(stderr, "X11_get_property: format = %d size = %d count = %ld after = %ld\n", *format, size, count, after); - + GB.FreeString(&_property_value); _property_value = GB.NewString((char *)data, count * size); XFree(data); - + offset = count * offset_size / sizeof(int32_t); - + while (after) { //fprintf(stderr, "X11_get_property: offset = %ld read = %ld\n", offset, Min(after, PROPERTY_NEXT_READ) / sizeof(int32_t)); - + if (XGetWindowProperty(_display, wid, prop, offset, Min(after, PROPERTY_NEXT_READ) / sizeof(int32_t), False, AnyPropertyType, type, format, &count, &after, &data) != Success) @@ -234,13 +234,13 @@ *pcount += count; offset += count * offset_size / sizeof(int32_t); - + //fprintf(stderr, "X11_get_property: format = %d size = %d count = %ld after = %ld next offset = %ld\n", *format, size, count, after, offset); - + _property_value = GB.AddString(_property_value, (char *)data, count * size); XFree(data); } - + return _property_value; } @@ -248,7 +248,7 @@ { Atom type; int format; - + return X11_get_property(wid, prop, &type, &format, count); } @@ -267,7 +267,8 @@ length = MAX_WINDOW_PROP; _window_prop.count = length; - memcpy(_window_prop.atoms, data, length * sizeof(Atom)); + if (data) + memcpy(_window_prop.atoms, data, length * sizeof(Atom)); } static void save_window_state(Window win, Atom prop) @@ -338,7 +339,7 @@ data = get_property(_root, X11_atom_net_supported, &count); if (!data) return; - + GB.NewArray(&_supported, sizeof(Atom), count); memcpy(_supported, data, sizeof(Atom) * count); } @@ -393,7 +394,7 @@ { _window = window; _window_visible = visible; - + if (!visible) load_window_state(window, X11_atom_net_wm_state); } @@ -402,7 +403,7 @@ { if (!_window_visible) save_window_state(_window, X11_atom_net_wm_state); - + XFlush(_display); _window = (Window)0; } @@ -552,34 +553,34 @@ int X11_window_get_desktop(Window window) { - int length = 0; + int length; char *data = NULL; int desktop = 0; data = get_property(window, X11_atom_net_wm_desktop, &length); - if (data) desktop = *((int *)data); - + return desktop; } int X11_get_current_desktop() { - int length = 0; + int length; char *data; - int desktop; + int desktop = 0; data = get_property(_root, X11_atom_net_current_desktop, &length); + if (data) + desktop = *((int *)data); - desktop = *((int *)data); return desktop; } int X11_get_window_type(Window window) { int index; - + load_window_state(window, X11_atom_net_wm_window_type); index = find_atom(_window_prop.atoms[0]); if (index < 0) @@ -603,7 +604,7 @@ void X11_set_window_decorated(Window window, bool decorated) { // Motif structures - + MwmHints *hints; MwmHints new_hints; @@ -612,7 +613,7 @@ int format; ulong nitems; ulong bytes_after; - + if (X11_atom_motif_wm_hints == None) X11_atom_motif_wm_hints = XInternAtom(_display, "_MOTIF_WM_HINTS", True); @@ -620,7 +621,7 @@ X11_atom_motif_wm_hints, 0, sizeof(MwmHints)/sizeof(long), False, AnyPropertyType, &type, &format, &nitems, &bytes_after, &data); - + if (type == None) { hints = &new_hints; @@ -632,17 +633,17 @@ } else hints = (MwmHints *)data; - + hints->flags |= (1 << 1); - hints->decorations = decorated ? 1 : 0; - + hints->decorations = decorated ? 1 : 0; + XChangeProperty(_display, window, X11_atom_motif_wm_hints, X11_atom_motif_wm_hints, 32, PropModeReplace, (uchar *)hints, sizeof (MwmHints)/sizeof(long)); - + if (hints != &new_hints) XFree(hints); - + XFlush(_display); } @@ -675,7 +676,7 @@ X11_atom_net_workarea, 0, 4, False, XA_CARDINAL, &ret, &format, &nitems, &after, &data); - if (e == Success && ret == XA_CARDINAL && format == 32 && nitems == 4) + if (e == Success && ret == XA_CARDINAL && format == 32 && nitems == 4) { long *workarea = (long *)data; *x = workarea[0]; @@ -683,18 +684,18 @@ *w = workarea[2]; *h = workarea[3]; err = FALSE; - } + } if (data) XFree(data); - + return err; } bool X11_is_supported_by_WM(Atom atom) { int i; - + if (_supported) { for (i = 0; i < GB.Count(_supported); i++) @@ -714,10 +715,10 @@ if (!_net_moveresize_window) _net_moveresize_window = XInternAtom(_display, "_NET_MOVERESIZE_WINDOW", True); - + if (!X11_is_supported_by_WM(_net_moveresize_window)) return TRUE; - + e.xclient.type = ClientMessage; e.xclient.message_type = _net_moveresize_window; e.xclient.display = _display; @@ -729,20 +730,20 @@ e.xclient.data.l[3] = w; e.xclient.data.l[4] = h; XSendEvent(_display, _root, FALSE, (SubstructureNotifyMask | SubstructureRedirectMask), &e); - + return FALSE; } static Atom get_net_system_tray(void) { char buf[64]; - + if (X11_atom_net_system_tray == None) { sprintf(buf, "_NET_SYSTEM_TRAY_S%d", XScreenNumberOfScreen(DefaultScreenOfDisplay(_display))); X11_atom_net_system_tray = XInternAtom(_display, buf, 0); } - + return X11_atom_net_system_tray; } @@ -772,7 +773,7 @@ XUngrabServer(_display); XFlush(_display); - + if (xmanager == None) return TRUE; @@ -795,7 +796,7 @@ XSendEvent(_display, xmanager, 0, NoEventMask, (XEvent *)&ev); XSync(_display, 0); usleep(10000); - + return FALSE; } #endif diff -Nru gambas3-3.8.3/gb.httpd/acinclude.m4 gambas3-3.8.4/gb.httpd/acinclude.m4 --- gambas3-3.8.3/gb.httpd/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.httpd/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.image.imlib/acinclude.m4 gambas3-3.8.4/gb.image.imlib/acinclude.m4 --- gambas3-3.8.3/gb.image.imlib/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.image.imlib/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.image.io/acinclude.m4 gambas3-3.8.4/gb.image.io/acinclude.m4 --- gambas3-3.8.3/gb.image.io/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.image.io/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.jit/acinclude.m4 gambas3-3.8.4/gb.jit/acinclude.m4 --- gambas3-3.8.3/gb.jit/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.jit/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.libxml/acinclude.m4 gambas3-3.8.4/gb.libxml/acinclude.m4 --- gambas3-3.8.3/gb.libxml/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.libxml/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.media/acinclude.m4 gambas3-3.8.4/gb.media/acinclude.m4 --- gambas3-3.8.3/gb.media/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.media/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.mime/acinclude.m4 gambas3-3.8.4/gb.mime/acinclude.m4 --- gambas3-3.8.3/gb.mime/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.mime/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.ncurses/acinclude.m4 gambas3-3.8.4/gb.ncurses/acinclude.m4 --- gambas3-3.8.3/gb.ncurses/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.ncurses/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.net/acinclude.m4 gambas3-3.8.4/gb.net/acinclude.m4 --- gambas3-3.8.3/gb.net/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.net/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.net.curl/acinclude.m4 gambas3-3.8.4/gb.net.curl/acinclude.m4 --- gambas3-3.8.3/gb.net.curl/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.net.curl/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.openal/acinclude.m4 gambas3-3.8.4/gb.openal/acinclude.m4 --- gambas3-3.8.3/gb.openal/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.openal/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.opengl/acinclude.m4 gambas3-3.8.4/gb.opengl/acinclude.m4 --- gambas3-3.8.3/gb.opengl/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.opengl/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.openssl/acinclude.m4 gambas3-3.8.4/gb.openssl/acinclude.m4 --- gambas3-3.8.3/gb.openssl/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.openssl/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.pcre/acinclude.m4 gambas3-3.8.4/gb.pcre/acinclude.m4 --- gambas3-3.8.3/gb.pcre/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.pcre/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.pdf/acinclude.m4 gambas3-3.8.4/gb.pdf/acinclude.m4 --- gambas3-3.8.3/gb.pdf/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.pdf/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.qt4/acinclude.m4 gambas3-3.8.4/gb.qt4/acinclude.m4 --- gambas3-3.8.3/gb.qt4/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.qt4/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.qt4/src/CDrawingArea.cpp gambas3-3.8.4/gb.qt4/src/CDrawingArea.cpp --- gambas3-3.8.3/gb.qt4/src/CDrawingArea.cpp 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.qt4/src/CDrawingArea.cpp 2015-12-22 04:46:12.000000000 +0000 @@ -58,6 +58,8 @@ ***************************************************************************/ +int MyDrawingArea::_in_any_draw_event = 0; + MyDrawingArea::MyDrawingArea(QWidget *parent) : MyContainer(parent) { drawn = 0; @@ -165,7 +167,8 @@ //qDebug("paint: %d %d %d %d", r.x(), r.y(), r.width(), r.height()); _in_draw_event = true; - + _in_any_draw_event++; + PAINT_begin(THIS); p = PAINT_get_current(); @@ -210,6 +213,7 @@ PAINT_end(); _in_draw_event = false; + _in_any_draw_event--; } void MyDrawingArea::createBackground(int w, int h) diff -Nru gambas3-3.8.3/gb.qt4/src/CDrawingArea.h gambas3-3.8.4/gb.qt4/src/CDrawingArea.h --- gambas3-3.8.3/gb.qt4/src/CDrawingArea.h 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.qt4/src/CDrawingArea.h 2015-12-22 04:46:12.000000000 +0000 @@ -64,9 +64,9 @@ int drawn; QPixmap *cache; - + virtual void setVisible(bool visible); - + //void setTransparent(bool); //bool isTransparent(void) { return transparent; } @@ -86,16 +86,17 @@ void setAllowFocus(bool f); bool isAllowFocus() const { return focusPolicy() != Qt::NoFocus; } - + void redraw(QRect &r, bool frame = false); - + bool hasNoBackground() const { return _no_background; } void setNoBackground(bool on); void updateNoBackground(); - + void setDrawEvent(int event) { _draw_event = event; } bool inDrawEvent() const { return _in_draw_event; } - + static bool inAnyDrawEvent() { return _in_any_draw_event > 0; } + void createBackground(int w, int h); #ifndef QT5 bool hasCacheBackground() const { return _cached && _background; } @@ -103,11 +104,11 @@ bool hasCacheBackground() const { return _cached && !_background_pixmap.isNull(); } #endif void deleteBackground(); - + QPixmap *getBackgroundPixmap(); public slots: - + void setBackground(); //bool isTransparent() { return _transparent; } //void setTransparent(bool on); @@ -139,6 +140,7 @@ bool _no_background; bool _in_draw_event; int _draw_event; + static int _in_any_draw_event; }; #endif diff -Nru gambas3-3.8.3/gb.qt4/src/cpaint_impl.cpp gambas3-3.8.4/gb.qt4/src/cpaint_impl.cpp --- gambas3-3.8.3/gb.qt4/src/cpaint_impl.cpp 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.qt4/src/cpaint_impl.cpp 2015-12-22 04:46:12.000000000 +0000 @@ -61,7 +61,7 @@ public: QPainterPath *path; GB_RECT *rect; - + ClipInfo() { path = NULL; rect = NULL; } ~ClipInfo() { delete path; delete rect; } };*/ @@ -78,7 +78,7 @@ //QList *clipStack; } QT_PAINT_EXTRA; - + #define EXTRA(d) ((QT_PAINT_EXTRA *)d->extra) #define COLOR_TO_INT(color) ((color).rgba() ^ 0xFF000000) @@ -96,39 +96,39 @@ static bool init_painting(GB_PAINT *d, QPaintDevice *device) { QPen pen; - + d->area.width = device->width(); d->area.height = device->height(); d->resolutionX = device->physicalDpiX(); d->resolutionY = device->physicalDpiY(); - - if (!PAINTER(d)) + + if (!PAINTER(d)) { if (device->paintingActive()) { GB.Error("Device already being painted"); return TRUE; } - + EXTRA(d)->painter = new QPainter(device); } - + #ifndef QT5 MyPaintEngine *engine = (MyPaintEngine *)device->paintEngine(); engine->patchFeatures(); #endif - + //EXTRA(d)->path = NULL; //EXTRA(d)->clip = NULL; //EXTRA(d)->clipRect = NULL; - + EXTRA(d)->init = new QTransform(); *(EXTRA(d)->init) = PAINTER(d)->worldTransform(); - + PAINTER(d)->setRenderHints(QPainter::Antialiasing, true); PAINTER(d)->setRenderHints(QPainter::TextAntialiasing, true); PAINTER(d)->setRenderHints(QPainter::SmoothPixmapTransform, true); - + pen = PAINTER(d)->pen(); pen.setCapStyle(Qt::FlatCap); pen.setJoinStyle(Qt::MiterJoin); @@ -136,7 +136,7 @@ pen.setWidthF(1.0); PAINTER(d)->setPen(pen); PAINTER(d)->setBrush(Qt::black); - + return FALSE; } @@ -184,35 +184,35 @@ { void *device = d->device; QPaintDevice *target = NULL; - + if (GB.Is(device, CLASS_Picture)) { QPixmap *pixmap = ((CPICTURE *)device)->pixmap; - + if (pixmap->isNull()) { GB.Error("Bad picture"); return TRUE; } - + target = pixmap; } else if (GB.Is(device, CLASS_Image)) { QImage *image = CIMAGE_get((CIMAGE *)device); - + if (image->isNull()) { GB.Error("Bad image"); return TRUE; } - + target = image; } else if (GB.Is(device, CLASS_DrawingArea)) { MyDrawingArea *wid; - + wid = (MyDrawingArea *)(((CWIDGET *)device)->widget); if (wid->isCached()) @@ -226,18 +226,18 @@ GB.Error("Cannot paint outside of Draw event handler"); return TRUE; } - + target = wid; } - + wid->drawn++; - + if (init_painting(d, target)) return TRUE; - + if (wid->isCached()) PAINTER(d)->initFrom(wid); - + d->area.width = wid->width(); d->area.height = wid->height(); return FALSE; @@ -245,13 +245,13 @@ else if (GB.Is(device, CLASS_Printer)) { CPRINTER *printer = (CPRINTER *)device; - + if (!printer->printing) { GB.Error("Printer is not printing"); return TRUE; } - + target = printer->printer; } else if (GB.Is(device, CLASS_SvgImage)) @@ -264,7 +264,7 @@ return TRUE; } } - + return init_painting(d, target); } @@ -276,14 +276,14 @@ if (GB.Is(device, CLASS_DrawingArea)) { MyDrawingArea *wid; - + wid = (MyDrawingArea *)(((CWIDGET *)device)->widget); if (wid) { if (wid->isCached()) wid->refreshBackground(); - + wid->drawn--; } } @@ -298,7 +298,7 @@ delete dx->clipStack->takeLast(); delete dx->clipStack; }*/ - + delete dx->init; delete dx->path; //delete dx->clip; @@ -309,12 +309,12 @@ { //QT_PAINT_EXTRA *dx = EXTRA(d); //ClipInfo *ci; - + PAINTER(d)->save(); - + /*if (!dx->clipStack) dx->clipStack = new QList; - + ci = new ClipInfo; if (dx->clip) ci->path = new QPainterPath(*dx->clip); @@ -323,23 +323,23 @@ ci->rect = new GB_RECT; *ci->rect = *dx->clipRect; } - + dx->clipStack->append(ci);*/ } static void Restore(GB_PAINT *d) { //QT_PAINT_EXTRA *dx = EXTRA(d); - + PAINTER(d)->restore(); - + /*if (dx->clipStack && !dx->clipStack->isEmpty()) { ClipInfo *ci = dx->clipStack->takeLast(); - + delete dx->clip; dx->clip = ci->path ? new QPainterPath(*(ci->path)) : NULL; - + delete dx->clipRect; if (ci->rect) { @@ -348,11 +348,11 @@ } else dx->clipRect = NULL; - + delete ci; }*/ } - + static void Antialias(GB_PAINT *d, int set, int *antialias) { if (set) @@ -373,7 +373,7 @@ if (set) { QFont f; - + if (*font) f = QFont(*((CFONT *)(*font))->font); else if ((GB.Is(d->device, CLASS_DrawingArea))) @@ -396,9 +396,9 @@ switch (EXTRA(d)->fillRule) { case GB_PAINT_FILL_RULE_WINDING: - PATH(d)->setFillRule(Qt::WindingFill); + PATH(d)->setFillRule(Qt::WindingFill); break; - case GB_PAINT_FILL_RULE_EVEN_ODD: + case GB_PAINT_FILL_RULE_EVEN_ODD: default: PATH(d)->setFillRule(Qt::OddEvenFill); } @@ -429,22 +429,22 @@ EXTRA(d)->clipRect = NULL; } }*/ - + static void Clip(GB_PAINT *d, int preserve) { CHECK_PATH(d); PAINTER(d)->setClipPath(*PATH(d), PAINTER(d)->hasClipping() ? Qt::IntersectClip : Qt::ReplaceClip); - + /*QPainterPath path = PAINTER(d)->worldTransform().map(*PATH(d)); - + if (CLIP(d)) path = CLIP(d)->intersected(path); - + delete EXTRA(d)->clip; EXTRA(d)->clip = new QPainterPath(path); delete_clip_rect(d);*/ - + PRESERVE_PATH(d, preserve); } @@ -463,9 +463,9 @@ ext->x1 = ext->x2 = ext->y1 = ext->y2 = 0.0; return; } - + QRectF rect = transform.inverted().mapRect(path->boundingRect()); - + ext->x1 = (float)rect.left(); ext->y1 = (float)rect.top(); ext->x2 = (float)rect.right(); @@ -490,7 +490,7 @@ static void Fill(GB_PAINT *d, int preserve) { CHECK_PATH(d); - + //if (!CLIP(d)) PAINTER(d)->fillPath(*PATH(d), PAINTER(d)->brush()); /*else @@ -499,14 +499,14 @@ path = path.intersected(*PATH(d)); PAINTER(d)->fillPath(path, PAINTER(d)->brush()); }*/ - + PRESERVE_PATH(d, preserve); } static void Stroke(GB_PAINT *d, int preserve) { CHECK_PATH(d); - + if (PAINTER(d)->pen().widthF() > 0.0) { //if (!CLIP(d)) @@ -515,23 +515,23 @@ { QPainterPathStroker stroker; QPen pen = PAINTER(d)->pen(); - + stroker.setCapStyle(pen.capStyle()); stroker.setDashOffset(pen.dashOffset()); stroker.setDashPattern(pen.dashPattern()); stroker.setJoinStyle(pen.joinStyle()); stroker.setMiterLimit(pen.miterLimit()); stroker.setWidth(pen.widthF()); - + QPainterPath path = PAINTER(d)->worldTransform().inverted().map(*CLIP(d)); path = path.intersected(stroker.createStroke(*PATH(d))); PAINTER(d)->fillPath(path, PAINTER(d)->brush()); }*/ } - + PRESERVE_PATH(d, preserve); } - + static void PathExtents(GB_PAINT *d, GB_EXTENTS *ext) { get_path_extents(PATH(d), ext, PAINTER(d)->transform()); @@ -622,7 +622,7 @@ static void DashOffset(GB_PAINT *d, int set, float *offset) { QPen pen = PAINTER(d)->pen(); - + if (set) { pen.setDashOffset((qreal)*offset); @@ -634,7 +634,7 @@ } } - + static void FillRule(GB_PAINT *d, int set, int *value) { if (set) @@ -658,7 +658,7 @@ static void LineCap(GB_PAINT *d, int set, int *value) { QPen pen = PAINTER(d)->pen(); - + if (set) { switch (*value) @@ -687,7 +687,7 @@ static void LineJoin(GB_PAINT *d, int set, int *value) { QPen pen = PAINTER(d)->pen(); - + if (set) { switch (*value) @@ -741,7 +741,7 @@ static void Operator(GB_PAINT *d, int set, int *value) { QPainter::CompositionMode mode; - + if (set) { switch (*value) @@ -797,22 +797,22 @@ PATH(d)->closeSubpath(); } - + static void Arc(GB_PAINT *d, float xc, float yc, float radius, float angle, float length, bool pie) { CREATE_PATH(d); QRectF rect; rect.setCoords((qreal)(xc - radius), (qreal)(yc - radius), (qreal)(xc + radius), (qreal)(yc + radius)); - + angle = - angle; length = - length; - + if (pie) PATH(d)->moveTo(xc, yc); else PATH(d)->arcMoveTo(rect, to_deg(angle)); - + PATH(d)->arcTo(rect, to_deg(angle), to_deg(length)); if (pie) @@ -825,15 +825,15 @@ QRectF rect; rect.setCoords((qreal)x, (qreal)y, (qreal)x + width, (qreal)y + height); - + angle = - angle; length = - length; - + if (pie) PATH(d)->moveTo(x + width / 2, y + height / 2); else PATH(d)->arcMoveTo(rect, to_deg(angle)); - + PATH(d)->arcTo(rect, to_deg(angle), to_deg(length)); if (pie) //PATH(d)->lineTo(x + width / 2, y + height / 2); @@ -852,7 +852,7 @@ ResetClip(d); Rectangle(d, x, y, w, h); Clip(d, FALSE); - + /*rect = new GB_RECT; rect->x = x; rect->y = y; @@ -860,7 +860,7 @@ rect->h = h; EXTRA(d)->clipRect = rect;*/ } - + static void GetCurrentPoint(GB_PAINT *d, float *x, float *y) { if (!PATH(d)) @@ -869,7 +869,7 @@ *y = 0; return; } - + QPointF pt = PATH(d)->currentPosition(); *x = (float)pt.x(); *y = (float)pt.y(); @@ -928,41 +928,41 @@ static void draw_text(GB_PAINT *d, bool rich, const char *text, int len, float w, float h, int align, bool draw) { QPointF pos; - + GetCurrentPoint(d, &_draw_x, &_draw_y); - + if (w < 0 && h < 0) _draw_y -= PAINTER(d)->fontMetrics().ascent(); - + if (draw) { begin_clipping(d); - + if (rich) - DRAW_rich_text(PAINTER(d), QString::fromUtf8(text, len), _draw_x, _draw_y, w, h, CCONST_alignment(align, ALIGN_TOP_NORMAL, true)); + DRAW_rich_text(PAINTER(d), QString::fromUtf8(text, len), _draw_x, _draw_y, w, h, CCONST_alignment(align, ALIGN_TOP_NORMAL, true)); else - DRAW_text(PAINTER(d), QString::fromUtf8(text, len), _draw_x, _draw_y, w, h, CCONST_alignment(align, ALIGN_TOP_NORMAL, true)); - + DRAW_text(PAINTER(d), QString::fromUtf8(text, len), _draw_x, _draw_y, w, h, CCONST_alignment(align, ALIGN_TOP_NORMAL, true)); + end_clipping(d); } else { CREATE_PATH(d); - + _draw_path = PATH(d); MyPaintDevice device; QPainter p(&device); - + p.setFont(PAINTER(d)->font()); p.setPen(PAINTER(d)->pen()); p.setBrush(PAINTER(d)->brush()); - + if (rich) - DRAW_rich_text(&p, QString::fromUtf8(text, len), 0, 0, w, h, CCONST_alignment(align, ALIGN_TOP_NORMAL, true)); + DRAW_rich_text(&p, QString::fromUtf8(text, len), 0, 0, w, h, CCONST_alignment(align, ALIGN_TOP_NORMAL, true)); else - DRAW_text(&p, QString::fromUtf8(text, len), 0, 0, w, h, CCONST_alignment(align, ALIGN_TOP_NORMAL, true)); - + DRAW_text(&p, QString::fromUtf8(text, len), 0, 0, w, h, CCONST_alignment(align, ALIGN_TOP_NORMAL, true)); + p.end(); _draw_path = NULL; } @@ -983,19 +983,19 @@ QPainterPath path; MyPaintDevice device; QPainter p(&device); - + p.setFont(PAINTER(d)->font()); _draw_path = &path; GetCurrentPoint(d, &_draw_x, &_draw_y); _draw_y -= PAINTER(d)->fontMetrics().ascent(); - + if (rich) - DRAW_rich_text(&p, QString::fromUtf8(text, len), 0, 0, width, -1, CCONST_alignment(ALIGN_TOP_NORMAL, ALIGN_TOP_NORMAL, true)); + DRAW_rich_text(&p, QString::fromUtf8(text, len), 0, 0, width, -1, CCONST_alignment(ALIGN_TOP_NORMAL, ALIGN_TOP_NORMAL, true)); else - DRAW_text(&p, QString::fromUtf8(text, len), 0, 0, -1, -1, CCONST_alignment(ALIGN_TOP_NORMAL, ALIGN_TOP_NORMAL, true)); - + DRAW_text(&p, QString::fromUtf8(text, len), 0, 0, -1, -1, CCONST_alignment(ALIGN_TOP_NORMAL, ALIGN_TOP_NORMAL, true)); + p.end(); - + get_path_extents(&path, ext, QTransform()); _draw_path = NULL; } @@ -1012,7 +1012,7 @@ static void TextSize(GB_PAINT *d, const char *text, int len, float *w, float *h) { - QString s = QString::fromUtf8((const char *)text, len); + QString s = QString::fromUtf8((const char *)text, len); *w = get_text_width(PAINTER(d), s); *h = get_text_height(PAINTER(d), s); } @@ -1020,14 +1020,14 @@ static void RichTextSize(GB_PAINT *d, const char *text, int len, float sw, float *w, float *h) { QTextDocument rt; - + rt.setDocumentMargin(0); rt.setHtml(QString::fromUtf8((const char *)text, len)); rt.setDefaultFont(PAINTER(d)->font()); - + if (sw > 0) rt.setTextWidth(sw); - + *w = rt.idealWidth(); *h = rt.size().height(); } @@ -1035,7 +1035,7 @@ static void Matrix(GB_PAINT *d, int set, GB_TRANSFORM matrix) { QTransform *t = (QTransform *)matrix; - + if (set) { if (t) @@ -1047,7 +1047,7 @@ *t = PAINTER(d)->worldTransform(); } - + static void SetBrush(GB_PAINT *d, GB_BRUSH brush) { QBrush *b = (QBrush *)brush; @@ -1112,15 +1112,15 @@ { QImage *img = CIMAGE_get((CIMAGE *)image); QRectF rect(x, y, w, h); - + begin_clipping(d); - + PAINTER(d)->setOpacity(opacity); - + if (source) { bool smooth = PAINTER(d)->testRenderHint(QPainter::SmoothPixmapTransform); - + if (w >= source->w && h >= source->h && w == (int)w && h == (int)h && ((int)w % source->w) == 0 && ((int)h % source->h) == 0) PAINTER(d)->setRenderHint(QPainter::SmoothPixmapTransform, false); @@ -1131,25 +1131,25 @@ } else PAINTER(d)->drawImage(rect, *img); - + PAINTER(d)->setOpacity(1.0); - + end_clipping(d); } - + static void DrawPicture(GB_PAINT *d, GB_PICTURE picture, float x, float y, float w, float h, GB_RECT *source) { QPixmap *pix = ((CPICTURE *)picture)->pixmap; QRectF rect(x, y, w, h); QRectF srect; - + if (source) srect = QRectF(source->x, source->y, source->w, source->h); else srect = QRectF(0, 0, pix->width(), pix->height()); begin_clipping(d); - + PAINTER(d)->drawPixmap(rect, *pix, srect); end_clipping(d); @@ -1158,7 +1158,7 @@ static void GetPictureInfo(GB_PAINT *d, GB_PICTURE picture, GB_PICTURE_INFO *info) { QPixmap *p = ((CPICTURE *)picture)->pixmap; - + info->width = p->width(); info->height = p->height(); } @@ -1184,7 +1184,7 @@ static void BrushImage(GB_BRUSH *brush, GB_IMAGE image) { QImage img(*CIMAGE_get((CIMAGE *)image)); - + img.detach(); QBrush *br = new QBrush(img); *brush = (GB_BRUSH)br; @@ -1194,10 +1194,10 @@ { QLinearGradient gradient; int i; - + gradient.setStart((qreal)x0, (qreal)y0); gradient.setFinalStop((qreal)x1, (qreal)y1); - + for (i = 0; i < nstop; i++) gradient.setColorAt((qreal)positions[i], CCOLOR_make(colors[i])); @@ -1220,11 +1220,11 @@ { QRadialGradient gradient; int i; - + gradient.setCenter((qreal)cx, (qreal)cy); gradient.setRadius((qreal)r); gradient.setFocalPoint((qreal)fx, (qreal)fy); - + for (i = 0; i < nstop; i++) gradient.setColorAt((qreal)positions[i], CCOLOR_make(colors[i])); @@ -1247,7 +1247,7 @@ { QBrush *b = (QBrush *)brush; QTransform *t = (QTransform *)matrix; - + if (set) { if (t) @@ -1319,7 +1319,7 @@ { QTransform *t = (QTransform *)matrix; QTransform *t2 = (QTransform *)matrix2; - + *t = *t * *t2; } @@ -1337,7 +1337,7 @@ } -GB_PAINT_DESC PAINT_Interface = +GB_PAINT_DESC PAINT_Interface = { // Size of the GB_PAINT structure extra data sizeof(QT_PAINT_EXTRA), @@ -1464,19 +1464,19 @@ } } -bool MyPaintEngine::begin(QPaintDevice *pdev) +bool MyPaintEngine::begin(QPaintDevice *pdev) { setActive(true); - return true; + return true; } -bool MyPaintEngine::end() +bool MyPaintEngine::end() { setActive(false); return true; } -void MyPaintEngine::updateState(const QPaintEngineState &state) +void MyPaintEngine::updateState(const QPaintEngineState &state) { //qDebug("MyPaintEngine::updateState: %04X", (int)state.state()); } @@ -1551,8 +1551,8 @@ } QPaintEngine *MyPaintDevice::paintEngine() const -{ - return &engine; +{ + return &engine; } int MyPaintDevice::metric(PaintDeviceMetric m) const diff -Nru gambas3-3.8.3/gb.qt4/src/CWindow.cpp gambas3-3.8.4/gb.qt4/src/CWindow.cpp --- gambas3-3.8.3/gb.qt4/src/CWindow.cpp 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.qt4/src/CWindow.cpp 2015-12-22 04:46:12.000000000 +0000 @@ -124,7 +124,7 @@ window->menuBar->setFocus(); QKeyEvent e(QEvent::KeyPress, Qt::Key_Escape, Qt::NoModifier); qApp->sendEvent(window->menuBar, &e); - if (save) + if (save) save->setFocus(); } } @@ -164,7 +164,7 @@ if (THIS->picture) background = *(THIS->picture->pixmap); - + if (background.isNull()) { clear_mask(THIS); @@ -187,7 +187,7 @@ THIS->container->setPixmap(THIS->picture->pixmap); } - + THIS->container->update(); } @@ -195,13 +195,13 @@ { //if (THIS->opening) // return true; - + if (THIS->opened) return false; - + CWIDGET_clear_flag(THIS, WF_CLOSED); THIS->opened = true; - + if (!THIS->minw && !THIS->minh) { THIS->minw = THIS->w; @@ -222,7 +222,7 @@ THIS->opened = false; return true; } - + THIS->opened = true; THIS->hidden = false; return false; @@ -261,7 +261,7 @@ QPoint p; QWidget *newParentWidget; bool moved = THIS->moved; - + if (move) { p.setX(x); @@ -292,14 +292,14 @@ } else CWIDGET_move(THIS, p.x(), p.y()); - + THIS->moved = moved; } void CWINDOW_ensure_active_window() { void *_object = CWINDOW_Active; - + if (THIS) WINDOW->activateWindow(); } @@ -342,7 +342,7 @@ if (CWINDOW_Embedder && !CWINDOW_Embedded) { client = new QX11EmbedWidget; - + win = new MyMainWindow(client, name, true); container = new MyContainer(win); container->raise(); @@ -402,7 +402,7 @@ if (THIS->toplevel || THIS->xembed) { CWindow::insertTopLevel(THIS); - + /*if (CWINDOW_Main == 0) { #if DEBUG_WINDOW @@ -463,7 +463,7 @@ //else // THIS->hidden = TRUE; #endif - + THIS->showMenuBar = true; END_METHOD @@ -473,7 +473,7 @@ if (!GB.Parent(_object)) GB.Attach(_object, _object, "Form"); - + CWIDGET_set_name((CWIDGET *)THIS, GB.GetClassName((void *)THIS)); END_METHOD @@ -482,10 +482,10 @@ BEGIN_METHOD_VOID(CFORM_main) CWINDOW *form = (CWINDOW *)GB.AutoCreate(GB.GetClass(NULL), 0); - + if (!form->hidden) Window_Show(form, NULL); - + END_METHOD @@ -554,7 +554,7 @@ static bool do_close(CWINDOW *_object, int ret, bool destroyed = false) { bool closed; - + #if DEBUG_WINDOW qDebug("do_close: (%s %p) %d %d", GB.GetClassName(THIS), THIS, THIS->closing, CWIDGET_test_flag(THIS, WF_CLOSED)); #endif @@ -611,7 +611,7 @@ } #if 0 - if (closed || destroyed) + if (closed || destroyed) { if (CWINDOW_Active == THIS) CWINDOW_activate(CWidget::get(WIDGET->parentWidget())); @@ -663,7 +663,7 @@ if (emit_open_event(THIS)) return; - + if (!THIS->toplevel) { CWIDGET_set_visible((CWIDGET *)THIS, true); @@ -687,7 +687,7 @@ BEGIN_METHOD_VOID(Window_Hide) THIS->hidden = true; - + if (THIS->toplevel && WINDOW->isModal()) { do_close(THIS, 0); @@ -721,12 +721,12 @@ BEGIN_METHOD(Window_ShowPopup, GB_INTEGER x; GB_INTEGER y) QPoint pos; - + if (MISSING(x) || MISSING(y)) pos = QCursor::pos(); else pos = QPoint(VARG(x), VARG(y)); - + THIS->ret = 0; if (THIS->toplevel) @@ -855,7 +855,7 @@ else { CPICTURE *new_pict = (CPICTURE *)VPROP(GB_OBJECT); - + if (new_pict != THIS->picture) { CPICTURE *old = THIS->picture; @@ -884,7 +884,7 @@ else { bool new_masked = VPROP(GB_BOOLEAN); - + if (new_masked != THIS->masked) { THIS->masked = new_masked; @@ -942,14 +942,14 @@ BEGIN_PROPERTY(Window_Stacking) int p; - + if (!THIS->toplevel) { if (READ_PROPERTY) GB.ReturnInteger(0); return; } - + if (READ_PROPERTY) { GB.ReturnInteger(THIS->stacking); @@ -975,7 +975,7 @@ GB.ReturnBoolean(FALSE); return; } - + if (READ_PROPERTY) { GB.ReturnBoolean(THIS->stacking == 1); @@ -985,7 +985,7 @@ THIS->stacking = VPROP(GB_BOOLEAN) ? 1 : 0; WINDOW->initProperties(PROP_STACKING); } - + END_PROPERTY @@ -997,7 +997,7 @@ GB.ReturnBoolean(FALSE); return; } - + if (READ_PROPERTY) { GB.ReturnBoolean(THIS->skipTaskbar); @@ -1019,7 +1019,7 @@ GB.ReturnBoolean(FALSE); return; } - + if (READ_PROPERTY) GB.ReturnBoolean(THIS->sticky); else @@ -1074,7 +1074,7 @@ else { bool show = !!VPROP(GB_BOOLEAN); - + if (show) Window_Show(_object, _param); else @@ -1143,7 +1143,7 @@ BEGIN_METHOD(Window_Controls_get, GB_STRING name) CWIDGET *control = WINDOW->names[GB.ToZeroString(ARG(name))]; - + if (!control || CWIDGET_check(control)) GB.ReturnNull(); else @@ -1303,7 +1303,7 @@ END_PROPERTY BEGIN_METHOD_VOID(Window_Activate) - + if (THIS->toplevel && WINDOW->isVisible() && !WINDOW->isHidden()) WINDOW->activateWindow(); @@ -1322,7 +1322,7 @@ GB_METHOD("Show", NULL, CWINDOW_menu_show, NULL), GB_METHOD("Hide", NULL, CWINDOW_menu_hide, NULL), GB_PROPERTY("Visible", "b", CWINDOW_menu_visible), - + GB_END_DECLARE }; @@ -1417,7 +1417,7 @@ GB_PROPERTY("AutoResize", "b", Container_AutoResize), GB_PROPERTY("Invert", "b", Container_Invert), GB_PROPERTY("Indent", "b", Container_Indent), - + //GB_PROPERTY("Type", "i", CWINDOW_type), GB_PROPERTY("Utility", "b", Window_Utility), GB_PROPERTY("Border", "b", Window_Border), @@ -1441,7 +1441,7 @@ GB_EVENT("Title", NULL, NULL, &EVENT_Title), GB_EVENT("Icon", NULL, NULL, &EVENT_Icon), GB_EVENT("Font", NULL, NULL, &EVENT_Font), - + //GB_INTERFACE("Draw", &DRAW_Interface), GB_END_DECLARE @@ -1468,7 +1468,7 @@ GB_STATIC_METHOD("Main", NULL, CFORM_main, NULL), GB_STATIC_METHOD("Load", NULL, CFORM_load, "[(Parent)Control;]"), GB_METHOD("_new", NULL, CFORM_new, NULL), - + FORM_DESCRIPTION, GB_END_DECLARE @@ -1493,7 +1493,7 @@ _utility = false; _state = windowState(); _screen = -1; - + //setAttribute(Qt::WA_KeyCompression, true); //setAttribute(Qt::WA_InputMethodEnabled, true); setAttribute(Qt::WA_QuitOnClose, false); @@ -1512,18 +1512,18 @@ #if DEBUG_WINDOW qDebug("~MyMainWindow: %s %s %p", GB.GetClassName(THIS), THIS->widget.name, THIS); #endif - + do_close(THIS, 0, true); if (CWINDOW_Active == THIS) CWINDOW_Active = 0; - + if (CWINDOW_LastActive == THIS) CWINDOW_LastActive = 0; - + if (sg) delete sg; - + GB.Detach(THIS); if (THIS->menuBar) @@ -1536,7 +1536,7 @@ } CWindow::removeTopLevel(THIS); - + _deleted = true; //qDebug("~MyMainWindow %p (end)", this); @@ -1553,7 +1553,7 @@ //CWINDOW_activate((CWIDGET *)THIS); GB.Ref(THIS); GB.Post((void (*)())activate_later, (intptr_t)THIS); - + } else*/ if (e->type() == QEvent::WindowDeactivate) { @@ -1562,7 +1562,7 @@ CWINDOW_activate(NULL); } } - + return QWidget::event(e); } #endif @@ -1570,11 +1570,11 @@ void MyMainWindow::showEvent(QShowEvent *e) { CWINDOW *_object = (CWINDOW *)CWidget::get(this); - + //qDebug("showEvent: %s\n", GB.GetClassName(THIS)); - + emit_open_event(THIS); - + //CWINDOW_fix_menubar(THIS); if (_activate) @@ -1604,11 +1604,11 @@ //qDebug("initProperties: %d", which); X11_flush(); - + if (which & (PROP_STACKING | PROP_SKIP_TASKBAR)) { X11_window_change_begin(effectiveWinId(), isVisible()); - + if (which & PROP_STACKING) { X11_window_change_property(X11_atom_net_wm_state_above, THIS->stacking == 1); @@ -1617,19 +1617,19 @@ } if (which & PROP_SKIP_TASKBAR) X11_window_change_property(X11_atom_net_wm_state_skip_taskbar, THIS->skipTaskbar); - + X11_window_change_end(); } - + //if (which == PROP_ALL) // X11_set_window_type(effectiveWinId(), _type); - + if (which & PROP_BORDER) X11_set_window_decorated(effectiveWinId(), _border); - + if (which & PROP_STICKY) X11_window_set_desktop(effectiveWinId(), isVisible(), THIS->sticky ? 0xFFFFFFFF : X11_get_current_desktop()); - + X11_flush(); #endif } @@ -1650,19 +1650,19 @@ //CWIDGET *_object = CWidget::get(this); //CWIDGET *_parent = parent ? CWidget::get(parent) : 0; //qDebug("present: %p %s: parent = %p %s", THIS, _object->name, _parent, _parent ? _parent->name : ""); - + if (parent) _screen = QApplication::desktop()->screenNumber(parent); else _screen = -1; - + if (!isVisible()) { //X11_window_startup(WINDOW->effectiveWinId(), THIS->x, THIS->y, THIS->w, THIS->h); if (isUtility() && _resizable) setMinimumSize(THIS->minw, THIS->minh); - + setAttribute(Qt::WA_ShowWithoutActivating, THIS->noTakeFocus); #ifndef QT5 @@ -1672,7 +1672,7 @@ } initProperties(PROP_ALL); #endif - + if (getState() & Qt::WindowMinimized) showMinimized(); else if (getState() & Qt::WindowFullScreen) @@ -1681,7 +1681,7 @@ showMaximized(); else show(); - + #ifdef QT5 //qDebug("createWinId: %p", (void *)effectiveWinId()); if (THIS->noTakeFocus) @@ -1692,7 +1692,7 @@ #else initProperties(PROP_SKIP_TASKBAR); #endif - + /*if (isUtility() && _resizable) setSizeGrip(true); else @@ -1701,17 +1701,17 @@ else { //_activate = true; - + if (getState() & Qt::WindowMinimized) { setState(windowState() & ~Qt::WindowMinimized); //qDebug("_activate set #2"); } } - + if (!THIS->noTakeFocus) // && (parent || hasBorder())) activateWindow(); - + if (parent) X11_set_transient_for(effectiveWinId(), parent->effectiveWinId()); @@ -1725,11 +1725,11 @@ //qDebug("showActivate: %s %d", THIS->widget.name, isToolbar()); // Reparent the window if, for example, there is an already modal window displayed - + if (CWINDOW_Current && THIS != CWINDOW_Current) { newParentWidget = CWINDOW_Current->widget.widget; - + if (!isVisible()) { if (newParentWidget && parentWidget() != newParentWidget) @@ -1748,7 +1748,7 @@ if (!newParentWidget && CWINDOW_Main && THIS != CWINDOW_Main) newParentWidget = CWidget::getTopLevel((CWIDGET *)CWINDOW_Main)->widget.widget; } - + present(newParentWidget); setEventLoop(); } @@ -1758,7 +1758,7 @@ #ifdef DEBUG_WINDOW qDebug("on_error_show_modal"); #endif - + // info->that can be NULL if the dialog is destroyed during the event loop if (info->that) @@ -1770,7 +1770,7 @@ MyApplication::eventLoop = info->old; CWINDOW_Current = info->save; - + if (info->that && info->that->isPersistent()) { info->that->setSizeGrip(false); @@ -1793,11 +1793,11 @@ return; CWIDGET_finish_focus(); - + info.that = this; info.old = MyApplication::eventLoop; info.save = CWINDOW_Current; - + MyApplication::eventLoop = &eventLoop; setWindowModality(Qt::ApplicationModal); @@ -1809,42 +1809,42 @@ } _enterLoop = false; // Do not call exitLoop() if we do not entered the loop yet! - + parent = CWINDOW_Current; if (!parent) parent = CWINDOW_Main; - + present(parent ? CWidget::getTopLevel((CWIDGET *)parent)->widget.widget : 0); setEventLoop(); - + THIS->loopLevel++; CWINDOW_Current = THIS; - + _enterLoop = true; - + GB.Debug.EnterEventLoop(); handler.handler = (GB_CALLBACK)on_error_show_modal; handler.arg1 = (intptr_t)&info; - + GB.OnErrorBegin(&handler); - + eventLoop.exec(); - + GB.OnErrorEnd(&handler); - + GB.Debug.LeaveEventLoop(); //eventLoop.processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::DeferredDeletion, 0); - + MyApplication::eventLoop = info.old; CWINDOW_Current = info.save; - + if (persistent) { setSizeGrip(false); setWindowModality(Qt::NonModal); } - + CWINDOW_ensure_active_window(); } @@ -1878,20 +1878,20 @@ raise(); setEventLoop(); //QTimer::singleShot(50, this, SLOT(activateLater())); - + THIS->loopLevel++; CWINDOW_Current = THIS; //handle_focus(THIS); //activateWindow(); - + save_popup = CWIDGET_enter_popup(); - + _enterLoop = true; - + QEventLoop eventLoop; QEventLoop *old; - + old = MyApplication::eventLoop; MyApplication::eventLoop = &eventLoop; GB.Debug.EnterEventLoop(); @@ -1900,18 +1900,18 @@ MyApplication::eventLoop = old; //eventLoop.exec(); //eventLoop.processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::DeferredDeletion, 0); - + CWINDOW_Current = save; - + if (persistent) { setWindowModality(Qt::NonModal); setWindowFlags(Qt::Window | flags); THIS->popup = false; } - + CWIDGET_leave_popup(save_popup); - + //CWIDGET_check_hovered(); } @@ -1972,25 +1972,27 @@ { if (_border == b) return; - + _border = b; if (!isWindow()) return; - + if (effectiveWinId()) { //qDebug("effectiveWinId"); initProperties(PROP_BORDER); X11_window_remap(effectiveWinId()); } - //doReparent(parentWidget(), pos()); +#ifndef QT5 + doReparent(parentWidget(), pos()); +#endif } void MyMainWindow::setResizable(bool b) { if (_resizable == b) return; - + _resizable = b; if (!isWindow()) return; @@ -2000,12 +2002,12 @@ void MyMainWindow::setUtility(bool b) { Qt::WindowFlags flags; - + if (_utility == b) return; - + _utility = b; - + doReparent(parentWidget(), pos()); } @@ -2106,7 +2108,7 @@ XEMBED->resize(THIS->w, THIS->h); #endif #endif - + //qDebug("resizeEvent %ld %ld isHidden:%s shown:%s ", THIS->w, THIS->h, isHidden() ? "1" : "0", shown ? "1" : "0"); //qDebug("THIS->h = %ld THIS->container->height() = %ld height() = %ld", THIS->h, THIS->container->height(), height()); @@ -2120,11 +2122,11 @@ CWINDOW *_object = (CWINDOW *)CWidget::getReal(this); QPushButton *test = 0; CWIDGET *ob; - + e->ignore(); //qDebug("MyMainWindow::keyPressEvent: (%p '%s' %s)", this, this ? this->caption().latin1() : 0, GB.GetClassName(CWidget::get(this))); - + if ((e->modifiers() == Qt::NoModifier || (e->modifiers() & Qt::KeypadModifier && e->key() == Qt::Key_Enter ))) { switch (e->key()) @@ -2229,14 +2231,14 @@ { CWINDOW *win; int i; - + for (i = 0; i < CWindow::list.count(); i++) { win = CWindow::list.at(i); if (win->opened) return false; } - + return true; } @@ -2252,7 +2254,7 @@ #if DEBUG_WINDOW qDebug("closeEvent: CWINDOW_Current = %p / %d <-> %p / %d", CWINDOW_Current, CWINDOW_Current ? CWINDOW_Current->loopLevel : -1, THIS, THIS->loopLevel); #endif - + if (THIS->opened) { // If a window is not opened, then it can be closed whatever the loop level is @@ -2324,7 +2326,7 @@ #endif THIS->opened = false; MAIN_check_quit(); - + return; IGNORE: @@ -2364,18 +2366,18 @@ THIS->embedded = !THIS->toplevel; f &= ~Qt::WindowType_Mask; - + if (THIS->toplevel) { if (_utility) f |= Qt::Tool; else f |= Qt::Window; - + if (!old_toplevel) CWindow::insertTopLevel(THIS); } - else + else { if (old_toplevel) { @@ -2385,12 +2387,12 @@ } } - //qDebug("doReparent: %s %p: visible = %d opened = %d hidden = %d isVisible = %d isHidden = %d shown = %d", + //qDebug("doReparent: %s %p: visible = %d opened = %d hidden = %d isVisible = %d isHidden = %d shown = %d", // THIS->widget.name, THIS, THIS->widget.flag.visible, THIS->opened, THIS->hidden, isVisible(), isHidden(), THIS->widget.flag.shown); - + //if (!THIS->hidden) showIt = true; //hide(); - + hidden = THIS->hidden || !WIDGET->isVisible(); if (parent != parentWidget() || f != windowFlags()) { @@ -2398,10 +2400,10 @@ setParent(parent, f); //qDebug("setParent %d", f != windowFlags()); } - + move(pos); //qDebug("doReparent: (%s %p) (%d %d) -> (%d %d)", GB.GetClassName(THIS), THIS, pos.x(), pos.y(), WIDGET->x(), WIDGET->y()); - + if (!THIS->embedded) { #ifndef NO_X_WINDOW @@ -2412,7 +2414,7 @@ setWindowIcon(icon); } - + if (!_resizable && _border && isWindow()) { setMinimumSize(width(), height()); @@ -2423,26 +2425,12 @@ setMinimumSize(0, 0); setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); } - - //qDebug("--> isVisible = %d isHidden = %d", isVisible(), isHidden()); - - /*if (THIS->embedded && !THIS->hidden) - { - qDebug("doReparent: %s %p: show_later", THIS->widget.name, THIS); - #if DEBUG_WINDOW - qDebug("post show_later %s %p", GB.GetClassName(THIS), THIS); - #endif - GB.Ref(THIS); - //GB.Post((void (*)())show_later, (intptr_t)THIS); - show_later(THIS); - //WIDGET->show(); - }*/ - + /*if (parentWidget()) qDebug("doReparent (%s %p): new parent = (%s %p)", THIS->widget.name, THIS, CWidget::get(parentWidget())->name, CWidget::get(parentWidget())); else qDebug("doReparent (%s %p): new parent = 0", THIS->widget.name, THIS);*/ - + if (reparented) { if (!hidden) @@ -2454,7 +2442,7 @@ { if (_screen >= 0) return _screen; - + if (CWINDOW_Active) return QApplication::desktop()->screenNumber(CWINDOW_Active->widget.widget); else if (CWINDOW_Main) @@ -2480,19 +2468,19 @@ QMenuBar *menuBar = THIS->menuBar; bool arrange = false; QRect geom; - + //qDebug("THIS->menuBar = %p menuBar() = %p", THIS->menuBar, menuBar()); if (menuBar && THIS->showMenuBar && !THIS->hideMenuBar) { int h = menuBar->sizeHint().height(); - + if (h == 0) h = menuBar->height(); - + menuBar->show(); geom = QRect(0, h, this->width(), this->height() - h); - + if (THIS->container->geometry() != geom) { arrange = true; @@ -2508,18 +2496,18 @@ menuBar->lower(); } //qDebug("configure: %s (%d %d)", GB.GetClassName(THIS), this->width(), this->height()); - + geom = QRect(0, 0, this->width(), this->height()); - + if (THIS->container->geometry() != geom) { arrange = true; THIS->container->setGeometry(geom); } - + THIS->container->raise(); } - + if (arrange) CCONTAINER_arrange(THIS); @@ -2533,7 +2521,7 @@ { if (_deleted) return; - + names.remove(name); if (control) names.insert(name, control); @@ -2542,12 +2530,12 @@ void MyMainWindow::resize(int w, int h) { bool save = _resizable; - + if (!_resizable && _border) setResizable(true); - + QWidget::resize(w, h); - + if (_resizable != save) setResizable(save); } @@ -2555,12 +2543,12 @@ void MyMainWindow::setGeometry(int x, int y, int w, int h) { bool save = _resizable; - + if (!_resizable && _border) setResizable(true); - + QWidget::setGeometry(x, y, w, h); - + if (_resizable != save) setResizable(save); } @@ -2569,7 +2557,7 @@ void MyMainWindow::changeEvent(QEvent *e) { QWidget::changeEvent(e); - + if (e->type() == QEvent::StyleChange || e->type() == QEvent::FontChange) { configure(); @@ -2666,7 +2654,7 @@ CWINDOW *active; //qDebug("CWINDOW_activate: %s", ob ? ob->name : NULL); - + if (ob) { active = CWidget::getWindow(ob); @@ -2692,7 +2680,7 @@ GB.Raise(CWINDOW_Active, EVENT_Deactivate, 0); CWINDOW_Active = 0; } - + if (active) GB.Raise(active, EVENT_Activate, 0); @@ -2721,7 +2709,7 @@ void CWINDOW_set_cancel_button(CWINDOW *win, QPushButton *button, bool on) { - //qDebug("CWINDOW_set_cancel_button: (%s %p) (%s %p) %d", GB.GetClassName(win), win, GB.GetClassName(CWidget::get(button)), CWidget::get(button), on); + //qDebug("CWINDOW_set_cancel_button: (%s %p) (%s %p) %d", GB.GetClassName(win), win, GB.GetClassName(CWidget::get(button)), CWidget::get(button), on); if (on) { win->cancelButton = button; @@ -2746,18 +2734,18 @@ if (THIS->toplevel && !THIS->popup && (!THIS->moved || w->isModal())) w->center(); - + //handle_focus(THIS); emit_open_event(THIS); - + //qDebug("eventFilter: Show: %s %d (%d) focus = %p", GB.GetClassName(THIS), !WINDOW->isHidden(), e->spontaneous(), THIS->focus); - + post_show_event(THIS); //CWINDOW_define_mask(THIS); - + GB.Raise(THIS, EVENT_Show, 0); if (!e->spontaneous()) - CACTION_raise(THIS); + CACTION_raise(THIS); } else if (e->type() == QEvent::Hide) // && !e->spontaneous()) { @@ -2832,7 +2820,7 @@ { if (!THIS->toplevel) return; - + list.append(THIS); count = list.count(); @@ -2848,7 +2836,7 @@ list.removeAll(THIS); count = list.count(); - + #if DEBUG_WINDOW qDebug("removeTopLevel: count = %d (%p %s %s)", count, THIS, THIS->widget.name, THIS->embedded ? "E" : "W"); #endif @@ -2860,7 +2848,7 @@ { int i; CMENU *menu; - + if (THIS->menuBar) { for (i = 0; i < THIS->menuBar->actions().count(); i++) @@ -2870,7 +2858,7 @@ return menu; } } - + return NULL; } diff -Nru gambas3-3.8.3/gb.qt4/src/main.cpp gambas3-3.8.4/gb.qt4/src/main.cpp --- gambas3-3.8.3/gb.qt4/src/main.cpp 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.qt4/src/main.cpp 2015-12-22 04:46:12.000000000 +0000 @@ -296,13 +296,13 @@ for(;;) { ptr = &CWIDGET_destroy_list; - + for(;;) { ob = *ptr; if (!ob) return ret; - + //if (MAIN_loop_level <= ob->level && !ob->flag.notified) if (!ob->flag.notified) { @@ -383,11 +383,11 @@ if (!_application_keypress) return false; - + if (e->type() == QEvent::KeyPress) { QKeyEvent *kevent = (QKeyEvent *)e; - + CKEY_clear(true); GB.FreeString(&CKEY_info.text); @@ -414,9 +414,9 @@ GB.Call(&_application_keypress_func, 0, FALSE); cancel = GB.Stopped(); - + CKEY_clear(false); - + return cancel; } @@ -446,7 +446,7 @@ { QWidget *widget = (QWidget *)o; CWIDGET *control; - + if (widget->isWindow()) { if (e->type() == QEvent::WindowActivate) @@ -476,9 +476,9 @@ { if (o->isWidgetType()) { - CWIDGET *ob = CWidget::get(o); + CWIDGET *ob = CWidget::get(o); bool old, res; - + if (ob) { old = QT_Notify(ob, true); @@ -487,7 +487,7 @@ return res; } } - + return QApplication::notify(o, e); }*/ @@ -512,7 +512,7 @@ b = !b; if (b == _tooltip_disable) return; - + _tooltip_disable = b; setEventFilter(b); } @@ -568,14 +568,14 @@ class MyNativeEventFilter: public QAbstractNativeEventFilter { public: - + static MyNativeEventFilter manager; - + virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) { xcb_generic_event_t *ev = static_cast(message); int type = ev->response_type & ~0x80; - + switch(type) { case XCB_KEY_PRESS: @@ -583,16 +583,16 @@ MAIN_x11_last_key_code = ((xcb_key_press_event_t *)ev)->detail; break; } - + if (_x11_event_filter) { XEvent xev; - + CLEAR(&xev); xev.xany.type = type; xev.xany.display = QX11Info::display(); xev.xany.send_event = ev->response_type & 0x80 ? 1 : 0; - + switch (type) { //case XCB_KEY_PRESS: @@ -608,7 +608,7 @@ xev.xexpose.count = e->count; break; } - + case XCB_VISIBILITY_NOTIFY: { xcb_visibility_notify_event_t *e = (xcb_visibility_notify_event_t *)ev; @@ -616,7 +616,7 @@ xev.xvisibility.state = e->state; break; } - + case XCB_DESTROY_NOTIFY: { xcb_destroy_notify_event_t *e = (xcb_destroy_notify_event_t *)ev; @@ -624,7 +624,7 @@ xev.xdestroywindow.window = e->window; break; } - + case XCB_MAP_NOTIFY: { xcb_map_notify_event_t *e = (xcb_map_notify_event_t *)ev; @@ -633,7 +633,7 @@ xev.xmap.override_redirect = e->override_redirect; break; } - + case XCB_UNMAP_NOTIFY: { xcb_unmap_notify_event_t *e = (xcb_unmap_notify_event_t *)ev; @@ -654,7 +654,7 @@ xev.xreparent.override_redirect = e->override_redirect; break; } - + case XCB_CONFIGURE_NOTIFY: { xcb_configure_notify_event_t *e = (xcb_configure_notify_event_t *)ev; @@ -698,7 +698,7 @@ xev.xselectionrequest.time = e->time; break; } - + case XCB_SELECTION_NOTIFY: { xcb_selection_notify_event_t *e = (xcb_selection_notify_event_t *)ev; @@ -709,7 +709,7 @@ xev.xselection.time = e->time; break; } - + case XCB_CLIENT_MESSAGE: { xcb_client_message_event_t *e = (xcb_client_message_event_t *)ev; @@ -719,15 +719,15 @@ memcpy(&xev.xclient.data, &e->data, 20); break; } - + default: //qDebug("gb.qt5: warning: unhandled xcb event: %d", type); return false; } - + (*_x11_event_filter)(&xev); } - + return false; } }; @@ -743,10 +743,10 @@ MAIN_x11_last_key_code = e->xkey.keycode; else if (e->type == XKeyRelease) MAIN_x11_last_key_code = e->xkey.keycode; - + if (_x11_event_filter) (*_x11_event_filter)(e); - + return false; } @@ -777,8 +777,8 @@ { MAIN_mouseGrabber = QWidget::mouseGrabber(); MAIN_keyboardGrabber = QWidget::keyboardGrabber(); - - if (MAIN_mouseGrabber) + + if (MAIN_mouseGrabber) { //qDebug("releaseMouse"); MAIN_mouseGrabber->releaseMouse(); @@ -788,7 +788,7 @@ //qDebug("releaseKeyboard"); MAIN_keyboardGrabber->releaseKeyboard(); } - + #ifndef NO_X_WINDOW if (qApp->activePopupWidget()) { @@ -807,7 +807,7 @@ MAIN_mouseGrabber->grabMouse(); MAIN_mouseGrabber = 0; } - + if (MAIN_keyboardGrabber) { //qDebug("grabKeyboard"); @@ -827,19 +827,19 @@ static void check_quit_now(intptr_t param) { static bool exit_called = false; - + if (must_quit() && !exit_called) { if (QApplication::instance()) { GB_FUNCTION func; - + if (GB.ExistClass("TrayIcons")) { if (!GB.GetFunction(&func, (void *)GB.FindClass("TrayIcons"), "DeleteAll", NULL, NULL)) GB.Call(&func, 0, FALSE); } - + #ifndef QT5 qApp->syncX(); #endif @@ -855,7 +855,7 @@ { if (_check_quit_posted) return; - + GB.Post((GB_CALLBACK)check_quit_now, 0); _check_quit_posted = true; } @@ -885,9 +885,9 @@ /*QX11Info::setAppDpiX(0, 92); QX11Info::setAppDpiY(0, 92);*/ - + /*fcntl(ConnectionNumber(qt_xdisplay()), F_SETFD, FD_CLOEXEC);*/ - + if (::strcmp(qApp->style()->metaObject()->className(), "Breeze::Style") == 0) { char *env = getenv("GB_QT_NO_BREEZE_FIX"); @@ -897,8 +897,8 @@ qApp->setStyle(new FixBreezeStyle); } } - - + + MAIN_update_scale(qApp->desktop()->font()); qApp->installEventFilter(&CWidget::manager); @@ -907,7 +907,7 @@ #endif MyApplication::setEventFilter(true); - + if (GB.GetFunction(&_application_keypress_func, (void *)GB.Application.StartupClass(), "Application_KeyPress", "", "") == 0) { _application_keypress = true; @@ -917,9 +917,9 @@ //qt_x11_set_global_double_buffer(false); qApp->setQuitOnLastWindowClosed(false); - + MyApplication::initClipboard(); - + init = true; } @@ -940,19 +940,19 @@ { int pos; QString locale(lang); - + pos = locale.lastIndexOf("."); if (pos >= 0) locale = locale.left(pos); - + if (_translator) { qApp->removeTranslator(_translator); delete _translator; _translator = NULL; } - + _translator = new QTranslator(); - + if (!try_to_load_translation(locale)) goto __INSTALL_TRANSLATOR; @@ -966,10 +966,10 @@ delete _translator; _translator = NULL; - + //if (strcmp(lang, "C")) // qDebug("gb.qt4: warning: unable to load Qt translation: %s", lang); - + goto __SET_DIRECTION; __INSTALL_TRANSLATOR: @@ -1031,13 +1031,13 @@ static void hook_quit() { GB_FUNCTION func; - + CWINDOW_close_all(true); CWINDOW_delete_all(true); qApp->sendPostedEvents(); //processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::DeferredDeletion, 0); qApp->sendPostedEvents(0, QEvent::DeferredDelete); - + if (!GB.GetFunction(&func, (void *)GB.FindClass("_Gui"), "_Quit", NULL, NULL)) GB.Call(&func, 0, FALSE); } @@ -1046,7 +1046,7 @@ static void hook_loop() { //qDebug("**** ENTERING EVENT LOOP"); - + qApp->sendPostedEvents(); //qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::DeferredDeletion, 0); @@ -1056,13 +1056,19 @@ qApp->exec(); else MAIN_check_quit(); - + hook_quit(); } static void hook_wait(int duration) { + if (MyDrawingArea::inAnyDrawEvent()) + { + GB.Error("Wait is forbidden during a repaint event"); + return; + } + MAIN_in_wait++; if (duration > 0) { @@ -1086,7 +1092,7 @@ t->deleteLater(); timer->id = 0; } - + if (on) timer->id = (intptr_t)(new MyTimer(timer)); } @@ -1124,7 +1130,7 @@ CWatch::stop(); msg = "This application has raised an unexpected
error and must abort.


"; - + if (code > 0) { msg = msg + "[%1] %2.
%3"; @@ -1148,7 +1154,7 @@ static void QT_InitWidget(QWidget *widget, void *object, int fill_bg) { - ((CWIDGET *)object)->flag.fillBackground = fill_bg; + ((CWIDGET *)object)->flag.fillBackground = fill_bg; CWIDGET_new(widget, object); } @@ -1242,7 +1248,7 @@ QMenu *QT_FindMenu(void *parent, const char *name) { CMENU *menu = NULL; - + if (parent && GB.Is(parent, CLASS_Control)) { CWINDOW *window = CWidget::getWindow((CWIDGET *)parent); @@ -1296,9 +1302,9 @@ }; #ifdef QT5 -void *GB_QT5_1[] EXPORT = +void *GB_QT5_1[] EXPORT = #else -void *GB_QT4_1[] EXPORT = +void *GB_QT4_1[] EXPORT = #endif { (void *)1, @@ -1355,17 +1361,17 @@ int EXPORT GB_INIT(void) { char *env; - + // Do not disable GLib support - + env = getenv("KDE_FULL_SESSION"); if (env && !strcasecmp(env, "true")) putenv((char *)"QT_NO_GLIB=1"); - + env = getenv("GB_GUI_BUSY"); if (env && atoi(env)) MAIN_debug_busy = true; - + //putenv((char *)"QT_SLOW_TOPLEVEL_RESIZE=1"); _old_hook_main = GB.Hook(GB_HOOK_MAIN, (void *)hook_main); @@ -1384,7 +1390,7 @@ GB.GetInterface("gb.image", IMAGE_INTERFACE_VERSION, &IMAGE); IMAGE.SetDefaultFormat(GB_IMAGE_BGRP); DRAW_init(); - + CLASS_Control = GB.FindClass("Control"); CLASS_Container = GB.FindClass("Container"); CLASS_UserControl = GB.FindClass("UserControl"); @@ -1464,13 +1470,13 @@ static void activate_main_window(intptr_t value) { CWINDOW *active; - + active = CWINDOW_Active; if (!active) active = CWINDOW_LastActive; - + if (!active) return; - + MyMainWindow *win = (MyMainWindow *)active->widget.widget; if (win && !win->isWindow()) win = (MyMainWindow *)win->window(); @@ -1488,13 +1494,13 @@ { if (!qApp) return; - + switch(signal) { case GB_SIGNAL_DEBUG_BREAK: release_grab(); break; - + case GB_SIGNAL_DEBUG_FORWARD: //while (qApp->activePopupWidget()) // delete qApp->activePopupWidget(); @@ -1502,7 +1508,7 @@ qApp->syncX(); #endif break; - + case GB_SIGNAL_DEBUG_CONTINUE: GB.Post((GB_CALLBACK)activate_main_window, 0); unrelease_grab(); diff -Nru gambas3-3.8.3/gb.qt4/src/x11.c gambas3-3.8.4/gb.qt4/src/x11.c --- gambas3-3.8.3/gb.qt4/src/x11.c 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.qt4/src/x11.c 2015-12-22 04:46:12.000000000 +0000 @@ -111,14 +111,14 @@ {NULL} }; -typedef +typedef struct { unsigned long flags; unsigned long functions; unsigned long decorations; long input_mode; unsigned long status; - } + } MwmHints; static void init_atoms() @@ -140,17 +140,17 @@ X11_atom_net_wm_user_time = XInternAtom(_display, "_NET_WM_USER_TIME", True); X11_atom_net_supported = XInternAtom(_display, "_NET_SUPPORTED", True); - + _atom_init = TRUE; } static Atom get_atom(int index) { X11_ATOM *a = &_atoms[index]; - + if (!a->atom) a->atom = XInternAtom(_display, a->name, True); - + return a->atom; } @@ -158,7 +158,7 @@ { int i = 0; X11_ATOM *p = _atoms; - + while (p->name) { if (!p->atom) @@ -209,24 +209,24 @@ False, AnyPropertyType, type, format, &count, &after, &data) != Success) return NULL; - + *pcount += count; - + size = *format == 32 ? sizeof(long) : ( *format == 16 ? sizeof(short) : 1 ); offset_size = *format == 32 ? sizeof(int32_t) : ( *format == 16 ? sizeof(short) : 1 ); - + //fprintf(stderr, "X11_get_property: format = %d size = %d count = %ld after = %ld\n", *format, size, count, after); - + GB.FreeString(&_property_value); _property_value = GB.NewString((char *)data, count * size); XFree(data); - + offset = count * offset_size / sizeof(int32_t); - + while (after) { //fprintf(stderr, "X11_get_property: offset = %ld read = %ld\n", offset, Min(after, PROPERTY_NEXT_READ) / sizeof(int32_t)); - + if (XGetWindowProperty(_display, wid, prop, offset, Min(after, PROPERTY_NEXT_READ) / sizeof(int32_t), False, AnyPropertyType, type, format, &count, &after, &data) != Success) @@ -234,13 +234,13 @@ *pcount += count; offset += count * offset_size / sizeof(int32_t); - + //fprintf(stderr, "X11_get_property: format = %d size = %d count = %ld after = %ld next offset = %ld\n", *format, size, count, after, offset); - + _property_value = GB.AddString(_property_value, (char *)data, count * size); XFree(data); } - + return _property_value; } @@ -248,7 +248,7 @@ { Atom type; int format; - + return X11_get_property(wid, prop, &type, &format, count); } @@ -267,7 +267,8 @@ length = MAX_WINDOW_PROP; _window_prop.count = length; - memcpy(_window_prop.atoms, data, length * sizeof(Atom)); + if (data) + memcpy(_window_prop.atoms, data, length * sizeof(Atom)); } static void save_window_state(Window win, Atom prop) @@ -338,7 +339,7 @@ data = get_property(_root, X11_atom_net_supported, &count); if (!data) return; - + GB.NewArray(&_supported, sizeof(Atom), count); memcpy(_supported, data, sizeof(Atom) * count); } @@ -393,7 +394,7 @@ { _window = window; _window_visible = visible; - + if (!visible) load_window_state(window, X11_atom_net_wm_state); } @@ -402,7 +403,7 @@ { if (!_window_visible) save_window_state(_window, X11_atom_net_wm_state); - + XFlush(_display); _window = (Window)0; } @@ -552,34 +553,34 @@ int X11_window_get_desktop(Window window) { - int length = 0; + int length; char *data = NULL; int desktop = 0; data = get_property(window, X11_atom_net_wm_desktop, &length); - if (data) desktop = *((int *)data); - + return desktop; } int X11_get_current_desktop() { - int length = 0; + int length; char *data; - int desktop; + int desktop = 0; data = get_property(_root, X11_atom_net_current_desktop, &length); + if (data) + desktop = *((int *)data); - desktop = *((int *)data); return desktop; } int X11_get_window_type(Window window) { int index; - + load_window_state(window, X11_atom_net_wm_window_type); index = find_atom(_window_prop.atoms[0]); if (index < 0) @@ -603,7 +604,7 @@ void X11_set_window_decorated(Window window, bool decorated) { // Motif structures - + MwmHints *hints; MwmHints new_hints; @@ -612,7 +613,7 @@ int format; ulong nitems; ulong bytes_after; - + if (X11_atom_motif_wm_hints == None) X11_atom_motif_wm_hints = XInternAtom(_display, "_MOTIF_WM_HINTS", True); @@ -620,7 +621,7 @@ X11_atom_motif_wm_hints, 0, sizeof(MwmHints)/sizeof(long), False, AnyPropertyType, &type, &format, &nitems, &bytes_after, &data); - + if (type == None) { hints = &new_hints; @@ -632,17 +633,17 @@ } else hints = (MwmHints *)data; - + hints->flags |= (1 << 1); - hints->decorations = decorated ? 1 : 0; - + hints->decorations = decorated ? 1 : 0; + XChangeProperty(_display, window, X11_atom_motif_wm_hints, X11_atom_motif_wm_hints, 32, PropModeReplace, (uchar *)hints, sizeof (MwmHints)/sizeof(long)); - + if (hints != &new_hints) XFree(hints); - + XFlush(_display); } @@ -675,7 +676,7 @@ X11_atom_net_workarea, 0, 4, False, XA_CARDINAL, &ret, &format, &nitems, &after, &data); - if (e == Success && ret == XA_CARDINAL && format == 32 && nitems == 4) + if (e == Success && ret == XA_CARDINAL && format == 32 && nitems == 4) { long *workarea = (long *)data; *x = workarea[0]; @@ -683,18 +684,18 @@ *w = workarea[2]; *h = workarea[3]; err = FALSE; - } + } if (data) XFree(data); - + return err; } bool X11_is_supported_by_WM(Atom atom) { int i; - + if (_supported) { for (i = 0; i < GB.Count(_supported); i++) @@ -714,10 +715,10 @@ if (!_net_moveresize_window) _net_moveresize_window = XInternAtom(_display, "_NET_MOVERESIZE_WINDOW", True); - + if (!X11_is_supported_by_WM(_net_moveresize_window)) return TRUE; - + e.xclient.type = ClientMessage; e.xclient.message_type = _net_moveresize_window; e.xclient.display = _display; @@ -729,20 +730,20 @@ e.xclient.data.l[3] = w; e.xclient.data.l[4] = h; XSendEvent(_display, _root, FALSE, (SubstructureNotifyMask | SubstructureRedirectMask), &e); - + return FALSE; } static Atom get_net_system_tray(void) { char buf[64]; - + if (X11_atom_net_system_tray == None) { sprintf(buf, "_NET_SYSTEM_TRAY_S%d", XScreenNumberOfScreen(DefaultScreenOfDisplay(_display))); X11_atom_net_system_tray = XInternAtom(_display, buf, 0); } - + return X11_atom_net_system_tray; } @@ -772,7 +773,7 @@ XUngrabServer(_display); XFlush(_display); - + if (xmanager == None) return TRUE; @@ -795,7 +796,7 @@ XSendEvent(_display, xmanager, 0, NoEventMask, (XEvent *)&ev); XSync(_display, 0); usleep(10000); - + return FALSE; } #endif diff -Nru gambas3-3.8.3/gb.qt5/acinclude.m4 gambas3-3.8.4/gb.qt5/acinclude.m4 --- gambas3-3.8.3/gb.qt5/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.qt5/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.qt5/src/CDrawingArea.cpp gambas3-3.8.4/gb.qt5/src/CDrawingArea.cpp --- gambas3-3.8.3/gb.qt5/src/CDrawingArea.cpp 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.qt5/src/CDrawingArea.cpp 2015-12-22 04:46:12.000000000 +0000 @@ -58,6 +58,8 @@ ***************************************************************************/ +int MyDrawingArea::_in_any_draw_event = 0; + MyDrawingArea::MyDrawingArea(QWidget *parent) : MyContainer(parent) { drawn = 0; @@ -165,7 +167,8 @@ //qDebug("paint: %d %d %d %d", r.x(), r.y(), r.width(), r.height()); _in_draw_event = true; - + _in_any_draw_event++; + PAINT_begin(THIS); p = PAINT_get_current(); @@ -210,6 +213,7 @@ PAINT_end(); _in_draw_event = false; + _in_any_draw_event--; } void MyDrawingArea::createBackground(int w, int h) diff -Nru gambas3-3.8.3/gb.qt5/src/CDrawingArea.h gambas3-3.8.4/gb.qt5/src/CDrawingArea.h --- gambas3-3.8.3/gb.qt5/src/CDrawingArea.h 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.qt5/src/CDrawingArea.h 2015-12-22 04:46:12.000000000 +0000 @@ -64,9 +64,9 @@ int drawn; QPixmap *cache; - + virtual void setVisible(bool visible); - + //void setTransparent(bool); //bool isTransparent(void) { return transparent; } @@ -86,16 +86,17 @@ void setAllowFocus(bool f); bool isAllowFocus() const { return focusPolicy() != Qt::NoFocus; } - + void redraw(QRect &r, bool frame = false); - + bool hasNoBackground() const { return _no_background; } void setNoBackground(bool on); void updateNoBackground(); - + void setDrawEvent(int event) { _draw_event = event; } bool inDrawEvent() const { return _in_draw_event; } - + static bool inAnyDrawEvent() { return _in_any_draw_event > 0; } + void createBackground(int w, int h); #ifndef QT5 bool hasCacheBackground() const { return _cached && _background; } @@ -103,11 +104,11 @@ bool hasCacheBackground() const { return _cached && !_background_pixmap.isNull(); } #endif void deleteBackground(); - + QPixmap *getBackgroundPixmap(); public slots: - + void setBackground(); //bool isTransparent() { return _transparent; } //void setTransparent(bool on); @@ -139,6 +140,7 @@ bool _no_background; bool _in_draw_event; int _draw_event; + static int _in_any_draw_event; }; #endif diff -Nru gambas3-3.8.3/gb.qt5/src/cpaint_impl.cpp gambas3-3.8.4/gb.qt5/src/cpaint_impl.cpp --- gambas3-3.8.3/gb.qt5/src/cpaint_impl.cpp 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.qt5/src/cpaint_impl.cpp 2015-12-22 04:46:12.000000000 +0000 @@ -61,7 +61,7 @@ public: QPainterPath *path; GB_RECT *rect; - + ClipInfo() { path = NULL; rect = NULL; } ~ClipInfo() { delete path; delete rect; } };*/ @@ -78,7 +78,7 @@ //QList *clipStack; } QT_PAINT_EXTRA; - + #define EXTRA(d) ((QT_PAINT_EXTRA *)d->extra) #define COLOR_TO_INT(color) ((color).rgba() ^ 0xFF000000) @@ -96,39 +96,39 @@ static bool init_painting(GB_PAINT *d, QPaintDevice *device) { QPen pen; - + d->area.width = device->width(); d->area.height = device->height(); d->resolutionX = device->physicalDpiX(); d->resolutionY = device->physicalDpiY(); - - if (!PAINTER(d)) + + if (!PAINTER(d)) { if (device->paintingActive()) { GB.Error("Device already being painted"); return TRUE; } - + EXTRA(d)->painter = new QPainter(device); } - + #ifndef QT5 MyPaintEngine *engine = (MyPaintEngine *)device->paintEngine(); engine->patchFeatures(); #endif - + //EXTRA(d)->path = NULL; //EXTRA(d)->clip = NULL; //EXTRA(d)->clipRect = NULL; - + EXTRA(d)->init = new QTransform(); *(EXTRA(d)->init) = PAINTER(d)->worldTransform(); - + PAINTER(d)->setRenderHints(QPainter::Antialiasing, true); PAINTER(d)->setRenderHints(QPainter::TextAntialiasing, true); PAINTER(d)->setRenderHints(QPainter::SmoothPixmapTransform, true); - + pen = PAINTER(d)->pen(); pen.setCapStyle(Qt::FlatCap); pen.setJoinStyle(Qt::MiterJoin); @@ -136,7 +136,7 @@ pen.setWidthF(1.0); PAINTER(d)->setPen(pen); PAINTER(d)->setBrush(Qt::black); - + return FALSE; } @@ -184,35 +184,35 @@ { void *device = d->device; QPaintDevice *target = NULL; - + if (GB.Is(device, CLASS_Picture)) { QPixmap *pixmap = ((CPICTURE *)device)->pixmap; - + if (pixmap->isNull()) { GB.Error("Bad picture"); return TRUE; } - + target = pixmap; } else if (GB.Is(device, CLASS_Image)) { QImage *image = CIMAGE_get((CIMAGE *)device); - + if (image->isNull()) { GB.Error("Bad image"); return TRUE; } - + target = image; } else if (GB.Is(device, CLASS_DrawingArea)) { MyDrawingArea *wid; - + wid = (MyDrawingArea *)(((CWIDGET *)device)->widget); if (wid->isCached()) @@ -226,18 +226,18 @@ GB.Error("Cannot paint outside of Draw event handler"); return TRUE; } - + target = wid; } - + wid->drawn++; - + if (init_painting(d, target)) return TRUE; - + if (wid->isCached()) PAINTER(d)->initFrom(wid); - + d->area.width = wid->width(); d->area.height = wid->height(); return FALSE; @@ -245,13 +245,13 @@ else if (GB.Is(device, CLASS_Printer)) { CPRINTER *printer = (CPRINTER *)device; - + if (!printer->printing) { GB.Error("Printer is not printing"); return TRUE; } - + target = printer->printer; } else if (GB.Is(device, CLASS_SvgImage)) @@ -264,7 +264,7 @@ return TRUE; } } - + return init_painting(d, target); } @@ -276,14 +276,14 @@ if (GB.Is(device, CLASS_DrawingArea)) { MyDrawingArea *wid; - + wid = (MyDrawingArea *)(((CWIDGET *)device)->widget); if (wid) { if (wid->isCached()) wid->refreshBackground(); - + wid->drawn--; } } @@ -298,7 +298,7 @@ delete dx->clipStack->takeLast(); delete dx->clipStack; }*/ - + delete dx->init; delete dx->path; //delete dx->clip; @@ -309,12 +309,12 @@ { //QT_PAINT_EXTRA *dx = EXTRA(d); //ClipInfo *ci; - + PAINTER(d)->save(); - + /*if (!dx->clipStack) dx->clipStack = new QList; - + ci = new ClipInfo; if (dx->clip) ci->path = new QPainterPath(*dx->clip); @@ -323,23 +323,23 @@ ci->rect = new GB_RECT; *ci->rect = *dx->clipRect; } - + dx->clipStack->append(ci);*/ } static void Restore(GB_PAINT *d) { //QT_PAINT_EXTRA *dx = EXTRA(d); - + PAINTER(d)->restore(); - + /*if (dx->clipStack && !dx->clipStack->isEmpty()) { ClipInfo *ci = dx->clipStack->takeLast(); - + delete dx->clip; dx->clip = ci->path ? new QPainterPath(*(ci->path)) : NULL; - + delete dx->clipRect; if (ci->rect) { @@ -348,11 +348,11 @@ } else dx->clipRect = NULL; - + delete ci; }*/ } - + static void Antialias(GB_PAINT *d, int set, int *antialias) { if (set) @@ -373,7 +373,7 @@ if (set) { QFont f; - + if (*font) f = QFont(*((CFONT *)(*font))->font); else if ((GB.Is(d->device, CLASS_DrawingArea))) @@ -396,9 +396,9 @@ switch (EXTRA(d)->fillRule) { case GB_PAINT_FILL_RULE_WINDING: - PATH(d)->setFillRule(Qt::WindingFill); + PATH(d)->setFillRule(Qt::WindingFill); break; - case GB_PAINT_FILL_RULE_EVEN_ODD: + case GB_PAINT_FILL_RULE_EVEN_ODD: default: PATH(d)->setFillRule(Qt::OddEvenFill); } @@ -429,22 +429,22 @@ EXTRA(d)->clipRect = NULL; } }*/ - + static void Clip(GB_PAINT *d, int preserve) { CHECK_PATH(d); PAINTER(d)->setClipPath(*PATH(d), PAINTER(d)->hasClipping() ? Qt::IntersectClip : Qt::ReplaceClip); - + /*QPainterPath path = PAINTER(d)->worldTransform().map(*PATH(d)); - + if (CLIP(d)) path = CLIP(d)->intersected(path); - + delete EXTRA(d)->clip; EXTRA(d)->clip = new QPainterPath(path); delete_clip_rect(d);*/ - + PRESERVE_PATH(d, preserve); } @@ -463,9 +463,9 @@ ext->x1 = ext->x2 = ext->y1 = ext->y2 = 0.0; return; } - + QRectF rect = transform.inverted().mapRect(path->boundingRect()); - + ext->x1 = (float)rect.left(); ext->y1 = (float)rect.top(); ext->x2 = (float)rect.right(); @@ -490,7 +490,7 @@ static void Fill(GB_PAINT *d, int preserve) { CHECK_PATH(d); - + //if (!CLIP(d)) PAINTER(d)->fillPath(*PATH(d), PAINTER(d)->brush()); /*else @@ -499,14 +499,14 @@ path = path.intersected(*PATH(d)); PAINTER(d)->fillPath(path, PAINTER(d)->brush()); }*/ - + PRESERVE_PATH(d, preserve); } static void Stroke(GB_PAINT *d, int preserve) { CHECK_PATH(d); - + if (PAINTER(d)->pen().widthF() > 0.0) { //if (!CLIP(d)) @@ -515,23 +515,23 @@ { QPainterPathStroker stroker; QPen pen = PAINTER(d)->pen(); - + stroker.setCapStyle(pen.capStyle()); stroker.setDashOffset(pen.dashOffset()); stroker.setDashPattern(pen.dashPattern()); stroker.setJoinStyle(pen.joinStyle()); stroker.setMiterLimit(pen.miterLimit()); stroker.setWidth(pen.widthF()); - + QPainterPath path = PAINTER(d)->worldTransform().inverted().map(*CLIP(d)); path = path.intersected(stroker.createStroke(*PATH(d))); PAINTER(d)->fillPath(path, PAINTER(d)->brush()); }*/ } - + PRESERVE_PATH(d, preserve); } - + static void PathExtents(GB_PAINT *d, GB_EXTENTS *ext) { get_path_extents(PATH(d), ext, PAINTER(d)->transform()); @@ -622,7 +622,7 @@ static void DashOffset(GB_PAINT *d, int set, float *offset) { QPen pen = PAINTER(d)->pen(); - + if (set) { pen.setDashOffset((qreal)*offset); @@ -634,7 +634,7 @@ } } - + static void FillRule(GB_PAINT *d, int set, int *value) { if (set) @@ -658,7 +658,7 @@ static void LineCap(GB_PAINT *d, int set, int *value) { QPen pen = PAINTER(d)->pen(); - + if (set) { switch (*value) @@ -687,7 +687,7 @@ static void LineJoin(GB_PAINT *d, int set, int *value) { QPen pen = PAINTER(d)->pen(); - + if (set) { switch (*value) @@ -741,7 +741,7 @@ static void Operator(GB_PAINT *d, int set, int *value) { QPainter::CompositionMode mode; - + if (set) { switch (*value) @@ -797,22 +797,22 @@ PATH(d)->closeSubpath(); } - + static void Arc(GB_PAINT *d, float xc, float yc, float radius, float angle, float length, bool pie) { CREATE_PATH(d); QRectF rect; rect.setCoords((qreal)(xc - radius), (qreal)(yc - radius), (qreal)(xc + radius), (qreal)(yc + radius)); - + angle = - angle; length = - length; - + if (pie) PATH(d)->moveTo(xc, yc); else PATH(d)->arcMoveTo(rect, to_deg(angle)); - + PATH(d)->arcTo(rect, to_deg(angle), to_deg(length)); if (pie) @@ -825,15 +825,15 @@ QRectF rect; rect.setCoords((qreal)x, (qreal)y, (qreal)x + width, (qreal)y + height); - + angle = - angle; length = - length; - + if (pie) PATH(d)->moveTo(x + width / 2, y + height / 2); else PATH(d)->arcMoveTo(rect, to_deg(angle)); - + PATH(d)->arcTo(rect, to_deg(angle), to_deg(length)); if (pie) //PATH(d)->lineTo(x + width / 2, y + height / 2); @@ -852,7 +852,7 @@ ResetClip(d); Rectangle(d, x, y, w, h); Clip(d, FALSE); - + /*rect = new GB_RECT; rect->x = x; rect->y = y; @@ -860,7 +860,7 @@ rect->h = h; EXTRA(d)->clipRect = rect;*/ } - + static void GetCurrentPoint(GB_PAINT *d, float *x, float *y) { if (!PATH(d)) @@ -869,7 +869,7 @@ *y = 0; return; } - + QPointF pt = PATH(d)->currentPosition(); *x = (float)pt.x(); *y = (float)pt.y(); @@ -928,41 +928,41 @@ static void draw_text(GB_PAINT *d, bool rich, const char *text, int len, float w, float h, int align, bool draw) { QPointF pos; - + GetCurrentPoint(d, &_draw_x, &_draw_y); - + if (w < 0 && h < 0) _draw_y -= PAINTER(d)->fontMetrics().ascent(); - + if (draw) { begin_clipping(d); - + if (rich) - DRAW_rich_text(PAINTER(d), QString::fromUtf8(text, len), _draw_x, _draw_y, w, h, CCONST_alignment(align, ALIGN_TOP_NORMAL, true)); + DRAW_rich_text(PAINTER(d), QString::fromUtf8(text, len), _draw_x, _draw_y, w, h, CCONST_alignment(align, ALIGN_TOP_NORMAL, true)); else - DRAW_text(PAINTER(d), QString::fromUtf8(text, len), _draw_x, _draw_y, w, h, CCONST_alignment(align, ALIGN_TOP_NORMAL, true)); - + DRAW_text(PAINTER(d), QString::fromUtf8(text, len), _draw_x, _draw_y, w, h, CCONST_alignment(align, ALIGN_TOP_NORMAL, true)); + end_clipping(d); } else { CREATE_PATH(d); - + _draw_path = PATH(d); MyPaintDevice device; QPainter p(&device); - + p.setFont(PAINTER(d)->font()); p.setPen(PAINTER(d)->pen()); p.setBrush(PAINTER(d)->brush()); - + if (rich) - DRAW_rich_text(&p, QString::fromUtf8(text, len), 0, 0, w, h, CCONST_alignment(align, ALIGN_TOP_NORMAL, true)); + DRAW_rich_text(&p, QString::fromUtf8(text, len), 0, 0, w, h, CCONST_alignment(align, ALIGN_TOP_NORMAL, true)); else - DRAW_text(&p, QString::fromUtf8(text, len), 0, 0, w, h, CCONST_alignment(align, ALIGN_TOP_NORMAL, true)); - + DRAW_text(&p, QString::fromUtf8(text, len), 0, 0, w, h, CCONST_alignment(align, ALIGN_TOP_NORMAL, true)); + p.end(); _draw_path = NULL; } @@ -983,19 +983,19 @@ QPainterPath path; MyPaintDevice device; QPainter p(&device); - + p.setFont(PAINTER(d)->font()); _draw_path = &path; GetCurrentPoint(d, &_draw_x, &_draw_y); _draw_y -= PAINTER(d)->fontMetrics().ascent(); - + if (rich) - DRAW_rich_text(&p, QString::fromUtf8(text, len), 0, 0, width, -1, CCONST_alignment(ALIGN_TOP_NORMAL, ALIGN_TOP_NORMAL, true)); + DRAW_rich_text(&p, QString::fromUtf8(text, len), 0, 0, width, -1, CCONST_alignment(ALIGN_TOP_NORMAL, ALIGN_TOP_NORMAL, true)); else - DRAW_text(&p, QString::fromUtf8(text, len), 0, 0, -1, -1, CCONST_alignment(ALIGN_TOP_NORMAL, ALIGN_TOP_NORMAL, true)); - + DRAW_text(&p, QString::fromUtf8(text, len), 0, 0, -1, -1, CCONST_alignment(ALIGN_TOP_NORMAL, ALIGN_TOP_NORMAL, true)); + p.end(); - + get_path_extents(&path, ext, QTransform()); _draw_path = NULL; } @@ -1012,7 +1012,7 @@ static void TextSize(GB_PAINT *d, const char *text, int len, float *w, float *h) { - QString s = QString::fromUtf8((const char *)text, len); + QString s = QString::fromUtf8((const char *)text, len); *w = get_text_width(PAINTER(d), s); *h = get_text_height(PAINTER(d), s); } @@ -1020,14 +1020,14 @@ static void RichTextSize(GB_PAINT *d, const char *text, int len, float sw, float *w, float *h) { QTextDocument rt; - + rt.setDocumentMargin(0); rt.setHtml(QString::fromUtf8((const char *)text, len)); rt.setDefaultFont(PAINTER(d)->font()); - + if (sw > 0) rt.setTextWidth(sw); - + *w = rt.idealWidth(); *h = rt.size().height(); } @@ -1035,7 +1035,7 @@ static void Matrix(GB_PAINT *d, int set, GB_TRANSFORM matrix) { QTransform *t = (QTransform *)matrix; - + if (set) { if (t) @@ -1047,7 +1047,7 @@ *t = PAINTER(d)->worldTransform(); } - + static void SetBrush(GB_PAINT *d, GB_BRUSH brush) { QBrush *b = (QBrush *)brush; @@ -1112,15 +1112,15 @@ { QImage *img = CIMAGE_get((CIMAGE *)image); QRectF rect(x, y, w, h); - + begin_clipping(d); - + PAINTER(d)->setOpacity(opacity); - + if (source) { bool smooth = PAINTER(d)->testRenderHint(QPainter::SmoothPixmapTransform); - + if (w >= source->w && h >= source->h && w == (int)w && h == (int)h && ((int)w % source->w) == 0 && ((int)h % source->h) == 0) PAINTER(d)->setRenderHint(QPainter::SmoothPixmapTransform, false); @@ -1131,25 +1131,25 @@ } else PAINTER(d)->drawImage(rect, *img); - + PAINTER(d)->setOpacity(1.0); - + end_clipping(d); } - + static void DrawPicture(GB_PAINT *d, GB_PICTURE picture, float x, float y, float w, float h, GB_RECT *source) { QPixmap *pix = ((CPICTURE *)picture)->pixmap; QRectF rect(x, y, w, h); QRectF srect; - + if (source) srect = QRectF(source->x, source->y, source->w, source->h); else srect = QRectF(0, 0, pix->width(), pix->height()); begin_clipping(d); - + PAINTER(d)->drawPixmap(rect, *pix, srect); end_clipping(d); @@ -1158,7 +1158,7 @@ static void GetPictureInfo(GB_PAINT *d, GB_PICTURE picture, GB_PICTURE_INFO *info) { QPixmap *p = ((CPICTURE *)picture)->pixmap; - + info->width = p->width(); info->height = p->height(); } @@ -1184,7 +1184,7 @@ static void BrushImage(GB_BRUSH *brush, GB_IMAGE image) { QImage img(*CIMAGE_get((CIMAGE *)image)); - + img.detach(); QBrush *br = new QBrush(img); *brush = (GB_BRUSH)br; @@ -1194,10 +1194,10 @@ { QLinearGradient gradient; int i; - + gradient.setStart((qreal)x0, (qreal)y0); gradient.setFinalStop((qreal)x1, (qreal)y1); - + for (i = 0; i < nstop; i++) gradient.setColorAt((qreal)positions[i], CCOLOR_make(colors[i])); @@ -1220,11 +1220,11 @@ { QRadialGradient gradient; int i; - + gradient.setCenter((qreal)cx, (qreal)cy); gradient.setRadius((qreal)r); gradient.setFocalPoint((qreal)fx, (qreal)fy); - + for (i = 0; i < nstop; i++) gradient.setColorAt((qreal)positions[i], CCOLOR_make(colors[i])); @@ -1247,7 +1247,7 @@ { QBrush *b = (QBrush *)brush; QTransform *t = (QTransform *)matrix; - + if (set) { if (t) @@ -1319,7 +1319,7 @@ { QTransform *t = (QTransform *)matrix; QTransform *t2 = (QTransform *)matrix2; - + *t = *t * *t2; } @@ -1337,7 +1337,7 @@ } -GB_PAINT_DESC PAINT_Interface = +GB_PAINT_DESC PAINT_Interface = { // Size of the GB_PAINT structure extra data sizeof(QT_PAINT_EXTRA), @@ -1464,19 +1464,19 @@ } } -bool MyPaintEngine::begin(QPaintDevice *pdev) +bool MyPaintEngine::begin(QPaintDevice *pdev) { setActive(true); - return true; + return true; } -bool MyPaintEngine::end() +bool MyPaintEngine::end() { setActive(false); return true; } -void MyPaintEngine::updateState(const QPaintEngineState &state) +void MyPaintEngine::updateState(const QPaintEngineState &state) { //qDebug("MyPaintEngine::updateState: %04X", (int)state.state()); } @@ -1551,8 +1551,8 @@ } QPaintEngine *MyPaintDevice::paintEngine() const -{ - return &engine; +{ + return &engine; } int MyPaintDevice::metric(PaintDeviceMetric m) const diff -Nru gambas3-3.8.3/gb.qt5/src/CWindow.cpp gambas3-3.8.4/gb.qt5/src/CWindow.cpp --- gambas3-3.8.3/gb.qt5/src/CWindow.cpp 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.qt5/src/CWindow.cpp 2015-12-22 04:46:12.000000000 +0000 @@ -124,7 +124,7 @@ window->menuBar->setFocus(); QKeyEvent e(QEvent::KeyPress, Qt::Key_Escape, Qt::NoModifier); qApp->sendEvent(window->menuBar, &e); - if (save) + if (save) save->setFocus(); } } @@ -164,7 +164,7 @@ if (THIS->picture) background = *(THIS->picture->pixmap); - + if (background.isNull()) { clear_mask(THIS); @@ -187,7 +187,7 @@ THIS->container->setPixmap(THIS->picture->pixmap); } - + THIS->container->update(); } @@ -195,13 +195,13 @@ { //if (THIS->opening) // return true; - + if (THIS->opened) return false; - + CWIDGET_clear_flag(THIS, WF_CLOSED); THIS->opened = true; - + if (!THIS->minw && !THIS->minh) { THIS->minw = THIS->w; @@ -222,7 +222,7 @@ THIS->opened = false; return true; } - + THIS->opened = true; THIS->hidden = false; return false; @@ -261,7 +261,7 @@ QPoint p; QWidget *newParentWidget; bool moved = THIS->moved; - + if (move) { p.setX(x); @@ -292,14 +292,14 @@ } else CWIDGET_move(THIS, p.x(), p.y()); - + THIS->moved = moved; } void CWINDOW_ensure_active_window() { void *_object = CWINDOW_Active; - + if (THIS) WINDOW->activateWindow(); } @@ -342,7 +342,7 @@ if (CWINDOW_Embedder && !CWINDOW_Embedded) { client = new QX11EmbedWidget; - + win = new MyMainWindow(client, name, true); container = new MyContainer(win); container->raise(); @@ -402,7 +402,7 @@ if (THIS->toplevel || THIS->xembed) { CWindow::insertTopLevel(THIS); - + /*if (CWINDOW_Main == 0) { #if DEBUG_WINDOW @@ -463,7 +463,7 @@ //else // THIS->hidden = TRUE; #endif - + THIS->showMenuBar = true; END_METHOD @@ -473,7 +473,7 @@ if (!GB.Parent(_object)) GB.Attach(_object, _object, "Form"); - + CWIDGET_set_name((CWIDGET *)THIS, GB.GetClassName((void *)THIS)); END_METHOD @@ -482,10 +482,10 @@ BEGIN_METHOD_VOID(CFORM_main) CWINDOW *form = (CWINDOW *)GB.AutoCreate(GB.GetClass(NULL), 0); - + if (!form->hidden) Window_Show(form, NULL); - + END_METHOD @@ -554,7 +554,7 @@ static bool do_close(CWINDOW *_object, int ret, bool destroyed = false) { bool closed; - + #if DEBUG_WINDOW qDebug("do_close: (%s %p) %d %d", GB.GetClassName(THIS), THIS, THIS->closing, CWIDGET_test_flag(THIS, WF_CLOSED)); #endif @@ -611,7 +611,7 @@ } #if 0 - if (closed || destroyed) + if (closed || destroyed) { if (CWINDOW_Active == THIS) CWINDOW_activate(CWidget::get(WIDGET->parentWidget())); @@ -663,7 +663,7 @@ if (emit_open_event(THIS)) return; - + if (!THIS->toplevel) { CWIDGET_set_visible((CWIDGET *)THIS, true); @@ -687,7 +687,7 @@ BEGIN_METHOD_VOID(Window_Hide) THIS->hidden = true; - + if (THIS->toplevel && WINDOW->isModal()) { do_close(THIS, 0); @@ -721,12 +721,12 @@ BEGIN_METHOD(Window_ShowPopup, GB_INTEGER x; GB_INTEGER y) QPoint pos; - + if (MISSING(x) || MISSING(y)) pos = QCursor::pos(); else pos = QPoint(VARG(x), VARG(y)); - + THIS->ret = 0; if (THIS->toplevel) @@ -855,7 +855,7 @@ else { CPICTURE *new_pict = (CPICTURE *)VPROP(GB_OBJECT); - + if (new_pict != THIS->picture) { CPICTURE *old = THIS->picture; @@ -884,7 +884,7 @@ else { bool new_masked = VPROP(GB_BOOLEAN); - + if (new_masked != THIS->masked) { THIS->masked = new_masked; @@ -942,14 +942,14 @@ BEGIN_PROPERTY(Window_Stacking) int p; - + if (!THIS->toplevel) { if (READ_PROPERTY) GB.ReturnInteger(0); return; } - + if (READ_PROPERTY) { GB.ReturnInteger(THIS->stacking); @@ -975,7 +975,7 @@ GB.ReturnBoolean(FALSE); return; } - + if (READ_PROPERTY) { GB.ReturnBoolean(THIS->stacking == 1); @@ -985,7 +985,7 @@ THIS->stacking = VPROP(GB_BOOLEAN) ? 1 : 0; WINDOW->initProperties(PROP_STACKING); } - + END_PROPERTY @@ -997,7 +997,7 @@ GB.ReturnBoolean(FALSE); return; } - + if (READ_PROPERTY) { GB.ReturnBoolean(THIS->skipTaskbar); @@ -1019,7 +1019,7 @@ GB.ReturnBoolean(FALSE); return; } - + if (READ_PROPERTY) GB.ReturnBoolean(THIS->sticky); else @@ -1074,7 +1074,7 @@ else { bool show = !!VPROP(GB_BOOLEAN); - + if (show) Window_Show(_object, _param); else @@ -1143,7 +1143,7 @@ BEGIN_METHOD(Window_Controls_get, GB_STRING name) CWIDGET *control = WINDOW->names[GB.ToZeroString(ARG(name))]; - + if (!control || CWIDGET_check(control)) GB.ReturnNull(); else @@ -1303,7 +1303,7 @@ END_PROPERTY BEGIN_METHOD_VOID(Window_Activate) - + if (THIS->toplevel && WINDOW->isVisible() && !WINDOW->isHidden()) WINDOW->activateWindow(); @@ -1322,7 +1322,7 @@ GB_METHOD("Show", NULL, CWINDOW_menu_show, NULL), GB_METHOD("Hide", NULL, CWINDOW_menu_hide, NULL), GB_PROPERTY("Visible", "b", CWINDOW_menu_visible), - + GB_END_DECLARE }; @@ -1417,7 +1417,7 @@ GB_PROPERTY("AutoResize", "b", Container_AutoResize), GB_PROPERTY("Invert", "b", Container_Invert), GB_PROPERTY("Indent", "b", Container_Indent), - + //GB_PROPERTY("Type", "i", CWINDOW_type), GB_PROPERTY("Utility", "b", Window_Utility), GB_PROPERTY("Border", "b", Window_Border), @@ -1441,7 +1441,7 @@ GB_EVENT("Title", NULL, NULL, &EVENT_Title), GB_EVENT("Icon", NULL, NULL, &EVENT_Icon), GB_EVENT("Font", NULL, NULL, &EVENT_Font), - + //GB_INTERFACE("Draw", &DRAW_Interface), GB_END_DECLARE @@ -1468,7 +1468,7 @@ GB_STATIC_METHOD("Main", NULL, CFORM_main, NULL), GB_STATIC_METHOD("Load", NULL, CFORM_load, "[(Parent)Control;]"), GB_METHOD("_new", NULL, CFORM_new, NULL), - + FORM_DESCRIPTION, GB_END_DECLARE @@ -1493,7 +1493,7 @@ _utility = false; _state = windowState(); _screen = -1; - + //setAttribute(Qt::WA_KeyCompression, true); //setAttribute(Qt::WA_InputMethodEnabled, true); setAttribute(Qt::WA_QuitOnClose, false); @@ -1512,18 +1512,18 @@ #if DEBUG_WINDOW qDebug("~MyMainWindow: %s %s %p", GB.GetClassName(THIS), THIS->widget.name, THIS); #endif - + do_close(THIS, 0, true); if (CWINDOW_Active == THIS) CWINDOW_Active = 0; - + if (CWINDOW_LastActive == THIS) CWINDOW_LastActive = 0; - + if (sg) delete sg; - + GB.Detach(THIS); if (THIS->menuBar) @@ -1536,7 +1536,7 @@ } CWindow::removeTopLevel(THIS); - + _deleted = true; //qDebug("~MyMainWindow %p (end)", this); @@ -1553,7 +1553,7 @@ //CWINDOW_activate((CWIDGET *)THIS); GB.Ref(THIS); GB.Post((void (*)())activate_later, (intptr_t)THIS); - + } else*/ if (e->type() == QEvent::WindowDeactivate) { @@ -1562,7 +1562,7 @@ CWINDOW_activate(NULL); } } - + return QWidget::event(e); } #endif @@ -1570,11 +1570,11 @@ void MyMainWindow::showEvent(QShowEvent *e) { CWINDOW *_object = (CWINDOW *)CWidget::get(this); - + //qDebug("showEvent: %s\n", GB.GetClassName(THIS)); - + emit_open_event(THIS); - + //CWINDOW_fix_menubar(THIS); if (_activate) @@ -1604,11 +1604,11 @@ //qDebug("initProperties: %d", which); X11_flush(); - + if (which & (PROP_STACKING | PROP_SKIP_TASKBAR)) { X11_window_change_begin(effectiveWinId(), isVisible()); - + if (which & PROP_STACKING) { X11_window_change_property(X11_atom_net_wm_state_above, THIS->stacking == 1); @@ -1617,19 +1617,19 @@ } if (which & PROP_SKIP_TASKBAR) X11_window_change_property(X11_atom_net_wm_state_skip_taskbar, THIS->skipTaskbar); - + X11_window_change_end(); } - + //if (which == PROP_ALL) // X11_set_window_type(effectiveWinId(), _type); - + if (which & PROP_BORDER) X11_set_window_decorated(effectiveWinId(), _border); - + if (which & PROP_STICKY) X11_window_set_desktop(effectiveWinId(), isVisible(), THIS->sticky ? 0xFFFFFFFF : X11_get_current_desktop()); - + X11_flush(); #endif } @@ -1650,19 +1650,19 @@ //CWIDGET *_object = CWidget::get(this); //CWIDGET *_parent = parent ? CWidget::get(parent) : 0; //qDebug("present: %p %s: parent = %p %s", THIS, _object->name, _parent, _parent ? _parent->name : ""); - + if (parent) _screen = QApplication::desktop()->screenNumber(parent); else _screen = -1; - + if (!isVisible()) { //X11_window_startup(WINDOW->effectiveWinId(), THIS->x, THIS->y, THIS->w, THIS->h); if (isUtility() && _resizable) setMinimumSize(THIS->minw, THIS->minh); - + setAttribute(Qt::WA_ShowWithoutActivating, THIS->noTakeFocus); #ifndef QT5 @@ -1672,7 +1672,7 @@ } initProperties(PROP_ALL); #endif - + if (getState() & Qt::WindowMinimized) showMinimized(); else if (getState() & Qt::WindowFullScreen) @@ -1681,7 +1681,7 @@ showMaximized(); else show(); - + #ifdef QT5 //qDebug("createWinId: %p", (void *)effectiveWinId()); if (THIS->noTakeFocus) @@ -1692,7 +1692,7 @@ #else initProperties(PROP_SKIP_TASKBAR); #endif - + /*if (isUtility() && _resizable) setSizeGrip(true); else @@ -1701,17 +1701,17 @@ else { //_activate = true; - + if (getState() & Qt::WindowMinimized) { setState(windowState() & ~Qt::WindowMinimized); //qDebug("_activate set #2"); } } - + if (!THIS->noTakeFocus) // && (parent || hasBorder())) activateWindow(); - + if (parent) X11_set_transient_for(effectiveWinId(), parent->effectiveWinId()); @@ -1725,11 +1725,11 @@ //qDebug("showActivate: %s %d", THIS->widget.name, isToolbar()); // Reparent the window if, for example, there is an already modal window displayed - + if (CWINDOW_Current && THIS != CWINDOW_Current) { newParentWidget = CWINDOW_Current->widget.widget; - + if (!isVisible()) { if (newParentWidget && parentWidget() != newParentWidget) @@ -1748,7 +1748,7 @@ if (!newParentWidget && CWINDOW_Main && THIS != CWINDOW_Main) newParentWidget = CWidget::getTopLevel((CWIDGET *)CWINDOW_Main)->widget.widget; } - + present(newParentWidget); setEventLoop(); } @@ -1758,7 +1758,7 @@ #ifdef DEBUG_WINDOW qDebug("on_error_show_modal"); #endif - + // info->that can be NULL if the dialog is destroyed during the event loop if (info->that) @@ -1770,7 +1770,7 @@ MyApplication::eventLoop = info->old; CWINDOW_Current = info->save; - + if (info->that && info->that->isPersistent()) { info->that->setSizeGrip(false); @@ -1793,11 +1793,11 @@ return; CWIDGET_finish_focus(); - + info.that = this; info.old = MyApplication::eventLoop; info.save = CWINDOW_Current; - + MyApplication::eventLoop = &eventLoop; setWindowModality(Qt::ApplicationModal); @@ -1809,42 +1809,42 @@ } _enterLoop = false; // Do not call exitLoop() if we do not entered the loop yet! - + parent = CWINDOW_Current; if (!parent) parent = CWINDOW_Main; - + present(parent ? CWidget::getTopLevel((CWIDGET *)parent)->widget.widget : 0); setEventLoop(); - + THIS->loopLevel++; CWINDOW_Current = THIS; - + _enterLoop = true; - + GB.Debug.EnterEventLoop(); handler.handler = (GB_CALLBACK)on_error_show_modal; handler.arg1 = (intptr_t)&info; - + GB.OnErrorBegin(&handler); - + eventLoop.exec(); - + GB.OnErrorEnd(&handler); - + GB.Debug.LeaveEventLoop(); //eventLoop.processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::DeferredDeletion, 0); - + MyApplication::eventLoop = info.old; CWINDOW_Current = info.save; - + if (persistent) { setSizeGrip(false); setWindowModality(Qt::NonModal); } - + CWINDOW_ensure_active_window(); } @@ -1878,20 +1878,20 @@ raise(); setEventLoop(); //QTimer::singleShot(50, this, SLOT(activateLater())); - + THIS->loopLevel++; CWINDOW_Current = THIS; //handle_focus(THIS); //activateWindow(); - + save_popup = CWIDGET_enter_popup(); - + _enterLoop = true; - + QEventLoop eventLoop; QEventLoop *old; - + old = MyApplication::eventLoop; MyApplication::eventLoop = &eventLoop; GB.Debug.EnterEventLoop(); @@ -1900,18 +1900,18 @@ MyApplication::eventLoop = old; //eventLoop.exec(); //eventLoop.processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::DeferredDeletion, 0); - + CWINDOW_Current = save; - + if (persistent) { setWindowModality(Qt::NonModal); setWindowFlags(Qt::Window | flags); THIS->popup = false; } - + CWIDGET_leave_popup(save_popup); - + //CWIDGET_check_hovered(); } @@ -1972,25 +1972,27 @@ { if (_border == b) return; - + _border = b; if (!isWindow()) return; - + if (effectiveWinId()) { //qDebug("effectiveWinId"); initProperties(PROP_BORDER); X11_window_remap(effectiveWinId()); } - //doReparent(parentWidget(), pos()); +#ifndef QT5 + doReparent(parentWidget(), pos()); +#endif } void MyMainWindow::setResizable(bool b) { if (_resizable == b) return; - + _resizable = b; if (!isWindow()) return; @@ -2000,12 +2002,12 @@ void MyMainWindow::setUtility(bool b) { Qt::WindowFlags flags; - + if (_utility == b) return; - + _utility = b; - + doReparent(parentWidget(), pos()); } @@ -2106,7 +2108,7 @@ XEMBED->resize(THIS->w, THIS->h); #endif #endif - + //qDebug("resizeEvent %ld %ld isHidden:%s shown:%s ", THIS->w, THIS->h, isHidden() ? "1" : "0", shown ? "1" : "0"); //qDebug("THIS->h = %ld THIS->container->height() = %ld height() = %ld", THIS->h, THIS->container->height(), height()); @@ -2120,11 +2122,11 @@ CWINDOW *_object = (CWINDOW *)CWidget::getReal(this); QPushButton *test = 0; CWIDGET *ob; - + e->ignore(); //qDebug("MyMainWindow::keyPressEvent: (%p '%s' %s)", this, this ? this->caption().latin1() : 0, GB.GetClassName(CWidget::get(this))); - + if ((e->modifiers() == Qt::NoModifier || (e->modifiers() & Qt::KeypadModifier && e->key() == Qt::Key_Enter ))) { switch (e->key()) @@ -2229,14 +2231,14 @@ { CWINDOW *win; int i; - + for (i = 0; i < CWindow::list.count(); i++) { win = CWindow::list.at(i); if (win->opened) return false; } - + return true; } @@ -2252,7 +2254,7 @@ #if DEBUG_WINDOW qDebug("closeEvent: CWINDOW_Current = %p / %d <-> %p / %d", CWINDOW_Current, CWINDOW_Current ? CWINDOW_Current->loopLevel : -1, THIS, THIS->loopLevel); #endif - + if (THIS->opened) { // If a window is not opened, then it can be closed whatever the loop level is @@ -2324,7 +2326,7 @@ #endif THIS->opened = false; MAIN_check_quit(); - + return; IGNORE: @@ -2364,18 +2366,18 @@ THIS->embedded = !THIS->toplevel; f &= ~Qt::WindowType_Mask; - + if (THIS->toplevel) { if (_utility) f |= Qt::Tool; else f |= Qt::Window; - + if (!old_toplevel) CWindow::insertTopLevel(THIS); } - else + else { if (old_toplevel) { @@ -2385,12 +2387,12 @@ } } - //qDebug("doReparent: %s %p: visible = %d opened = %d hidden = %d isVisible = %d isHidden = %d shown = %d", + //qDebug("doReparent: %s %p: visible = %d opened = %d hidden = %d isVisible = %d isHidden = %d shown = %d", // THIS->widget.name, THIS, THIS->widget.flag.visible, THIS->opened, THIS->hidden, isVisible(), isHidden(), THIS->widget.flag.shown); - + //if (!THIS->hidden) showIt = true; //hide(); - + hidden = THIS->hidden || !WIDGET->isVisible(); if (parent != parentWidget() || f != windowFlags()) { @@ -2398,10 +2400,10 @@ setParent(parent, f); //qDebug("setParent %d", f != windowFlags()); } - + move(pos); //qDebug("doReparent: (%s %p) (%d %d) -> (%d %d)", GB.GetClassName(THIS), THIS, pos.x(), pos.y(), WIDGET->x(), WIDGET->y()); - + if (!THIS->embedded) { #ifndef NO_X_WINDOW @@ -2412,7 +2414,7 @@ setWindowIcon(icon); } - + if (!_resizable && _border && isWindow()) { setMinimumSize(width(), height()); @@ -2423,26 +2425,12 @@ setMinimumSize(0, 0); setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); } - - //qDebug("--> isVisible = %d isHidden = %d", isVisible(), isHidden()); - - /*if (THIS->embedded && !THIS->hidden) - { - qDebug("doReparent: %s %p: show_later", THIS->widget.name, THIS); - #if DEBUG_WINDOW - qDebug("post show_later %s %p", GB.GetClassName(THIS), THIS); - #endif - GB.Ref(THIS); - //GB.Post((void (*)())show_later, (intptr_t)THIS); - show_later(THIS); - //WIDGET->show(); - }*/ - + /*if (parentWidget()) qDebug("doReparent (%s %p): new parent = (%s %p)", THIS->widget.name, THIS, CWidget::get(parentWidget())->name, CWidget::get(parentWidget())); else qDebug("doReparent (%s %p): new parent = 0", THIS->widget.name, THIS);*/ - + if (reparented) { if (!hidden) @@ -2454,7 +2442,7 @@ { if (_screen >= 0) return _screen; - + if (CWINDOW_Active) return QApplication::desktop()->screenNumber(CWINDOW_Active->widget.widget); else if (CWINDOW_Main) @@ -2480,19 +2468,19 @@ QMenuBar *menuBar = THIS->menuBar; bool arrange = false; QRect geom; - + //qDebug("THIS->menuBar = %p menuBar() = %p", THIS->menuBar, menuBar()); if (menuBar && THIS->showMenuBar && !THIS->hideMenuBar) { int h = menuBar->sizeHint().height(); - + if (h == 0) h = menuBar->height(); - + menuBar->show(); geom = QRect(0, h, this->width(), this->height() - h); - + if (THIS->container->geometry() != geom) { arrange = true; @@ -2508,18 +2496,18 @@ menuBar->lower(); } //qDebug("configure: %s (%d %d)", GB.GetClassName(THIS), this->width(), this->height()); - + geom = QRect(0, 0, this->width(), this->height()); - + if (THIS->container->geometry() != geom) { arrange = true; THIS->container->setGeometry(geom); } - + THIS->container->raise(); } - + if (arrange) CCONTAINER_arrange(THIS); @@ -2533,7 +2521,7 @@ { if (_deleted) return; - + names.remove(name); if (control) names.insert(name, control); @@ -2542,12 +2530,12 @@ void MyMainWindow::resize(int w, int h) { bool save = _resizable; - + if (!_resizable && _border) setResizable(true); - + QWidget::resize(w, h); - + if (_resizable != save) setResizable(save); } @@ -2555,12 +2543,12 @@ void MyMainWindow::setGeometry(int x, int y, int w, int h) { bool save = _resizable; - + if (!_resizable && _border) setResizable(true); - + QWidget::setGeometry(x, y, w, h); - + if (_resizable != save) setResizable(save); } @@ -2569,7 +2557,7 @@ void MyMainWindow::changeEvent(QEvent *e) { QWidget::changeEvent(e); - + if (e->type() == QEvent::StyleChange || e->type() == QEvent::FontChange) { configure(); @@ -2666,7 +2654,7 @@ CWINDOW *active; //qDebug("CWINDOW_activate: %s", ob ? ob->name : NULL); - + if (ob) { active = CWidget::getWindow(ob); @@ -2692,7 +2680,7 @@ GB.Raise(CWINDOW_Active, EVENT_Deactivate, 0); CWINDOW_Active = 0; } - + if (active) GB.Raise(active, EVENT_Activate, 0); @@ -2721,7 +2709,7 @@ void CWINDOW_set_cancel_button(CWINDOW *win, QPushButton *button, bool on) { - //qDebug("CWINDOW_set_cancel_button: (%s %p) (%s %p) %d", GB.GetClassName(win), win, GB.GetClassName(CWidget::get(button)), CWidget::get(button), on); + //qDebug("CWINDOW_set_cancel_button: (%s %p) (%s %p) %d", GB.GetClassName(win), win, GB.GetClassName(CWidget::get(button)), CWidget::get(button), on); if (on) { win->cancelButton = button; @@ -2746,18 +2734,18 @@ if (THIS->toplevel && !THIS->popup && (!THIS->moved || w->isModal())) w->center(); - + //handle_focus(THIS); emit_open_event(THIS); - + //qDebug("eventFilter: Show: %s %d (%d) focus = %p", GB.GetClassName(THIS), !WINDOW->isHidden(), e->spontaneous(), THIS->focus); - + post_show_event(THIS); //CWINDOW_define_mask(THIS); - + GB.Raise(THIS, EVENT_Show, 0); if (!e->spontaneous()) - CACTION_raise(THIS); + CACTION_raise(THIS); } else if (e->type() == QEvent::Hide) // && !e->spontaneous()) { @@ -2832,7 +2820,7 @@ { if (!THIS->toplevel) return; - + list.append(THIS); count = list.count(); @@ -2848,7 +2836,7 @@ list.removeAll(THIS); count = list.count(); - + #if DEBUG_WINDOW qDebug("removeTopLevel: count = %d (%p %s %s)", count, THIS, THIS->widget.name, THIS->embedded ? "E" : "W"); #endif @@ -2860,7 +2848,7 @@ { int i; CMENU *menu; - + if (THIS->menuBar) { for (i = 0; i < THIS->menuBar->actions().count(); i++) @@ -2870,7 +2858,7 @@ return menu; } } - + return NULL; } diff -Nru gambas3-3.8.3/gb.qt5/src/main.cpp gambas3-3.8.4/gb.qt5/src/main.cpp --- gambas3-3.8.3/gb.qt5/src/main.cpp 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.qt5/src/main.cpp 2015-12-22 04:46:12.000000000 +0000 @@ -296,13 +296,13 @@ for(;;) { ptr = &CWIDGET_destroy_list; - + for(;;) { ob = *ptr; if (!ob) return ret; - + //if (MAIN_loop_level <= ob->level && !ob->flag.notified) if (!ob->flag.notified) { @@ -383,11 +383,11 @@ if (!_application_keypress) return false; - + if (e->type() == QEvent::KeyPress) { QKeyEvent *kevent = (QKeyEvent *)e; - + CKEY_clear(true); GB.FreeString(&CKEY_info.text); @@ -414,9 +414,9 @@ GB.Call(&_application_keypress_func, 0, FALSE); cancel = GB.Stopped(); - + CKEY_clear(false); - + return cancel; } @@ -446,7 +446,7 @@ { QWidget *widget = (QWidget *)o; CWIDGET *control; - + if (widget->isWindow()) { if (e->type() == QEvent::WindowActivate) @@ -476,9 +476,9 @@ { if (o->isWidgetType()) { - CWIDGET *ob = CWidget::get(o); + CWIDGET *ob = CWidget::get(o); bool old, res; - + if (ob) { old = QT_Notify(ob, true); @@ -487,7 +487,7 @@ return res; } } - + return QApplication::notify(o, e); }*/ @@ -512,7 +512,7 @@ b = !b; if (b == _tooltip_disable) return; - + _tooltip_disable = b; setEventFilter(b); } @@ -568,14 +568,14 @@ class MyNativeEventFilter: public QAbstractNativeEventFilter { public: - + static MyNativeEventFilter manager; - + virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) { xcb_generic_event_t *ev = static_cast(message); int type = ev->response_type & ~0x80; - + switch(type) { case XCB_KEY_PRESS: @@ -583,16 +583,16 @@ MAIN_x11_last_key_code = ((xcb_key_press_event_t *)ev)->detail; break; } - + if (_x11_event_filter) { XEvent xev; - + CLEAR(&xev); xev.xany.type = type; xev.xany.display = QX11Info::display(); xev.xany.send_event = ev->response_type & 0x80 ? 1 : 0; - + switch (type) { //case XCB_KEY_PRESS: @@ -608,7 +608,7 @@ xev.xexpose.count = e->count; break; } - + case XCB_VISIBILITY_NOTIFY: { xcb_visibility_notify_event_t *e = (xcb_visibility_notify_event_t *)ev; @@ -616,7 +616,7 @@ xev.xvisibility.state = e->state; break; } - + case XCB_DESTROY_NOTIFY: { xcb_destroy_notify_event_t *e = (xcb_destroy_notify_event_t *)ev; @@ -624,7 +624,7 @@ xev.xdestroywindow.window = e->window; break; } - + case XCB_MAP_NOTIFY: { xcb_map_notify_event_t *e = (xcb_map_notify_event_t *)ev; @@ -633,7 +633,7 @@ xev.xmap.override_redirect = e->override_redirect; break; } - + case XCB_UNMAP_NOTIFY: { xcb_unmap_notify_event_t *e = (xcb_unmap_notify_event_t *)ev; @@ -654,7 +654,7 @@ xev.xreparent.override_redirect = e->override_redirect; break; } - + case XCB_CONFIGURE_NOTIFY: { xcb_configure_notify_event_t *e = (xcb_configure_notify_event_t *)ev; @@ -698,7 +698,7 @@ xev.xselectionrequest.time = e->time; break; } - + case XCB_SELECTION_NOTIFY: { xcb_selection_notify_event_t *e = (xcb_selection_notify_event_t *)ev; @@ -709,7 +709,7 @@ xev.xselection.time = e->time; break; } - + case XCB_CLIENT_MESSAGE: { xcb_client_message_event_t *e = (xcb_client_message_event_t *)ev; @@ -719,15 +719,15 @@ memcpy(&xev.xclient.data, &e->data, 20); break; } - + default: //qDebug("gb.qt5: warning: unhandled xcb event: %d", type); return false; } - + (*_x11_event_filter)(&xev); } - + return false; } }; @@ -743,10 +743,10 @@ MAIN_x11_last_key_code = e->xkey.keycode; else if (e->type == XKeyRelease) MAIN_x11_last_key_code = e->xkey.keycode; - + if (_x11_event_filter) (*_x11_event_filter)(e); - + return false; } @@ -777,8 +777,8 @@ { MAIN_mouseGrabber = QWidget::mouseGrabber(); MAIN_keyboardGrabber = QWidget::keyboardGrabber(); - - if (MAIN_mouseGrabber) + + if (MAIN_mouseGrabber) { //qDebug("releaseMouse"); MAIN_mouseGrabber->releaseMouse(); @@ -788,7 +788,7 @@ //qDebug("releaseKeyboard"); MAIN_keyboardGrabber->releaseKeyboard(); } - + #ifndef NO_X_WINDOW if (qApp->activePopupWidget()) { @@ -807,7 +807,7 @@ MAIN_mouseGrabber->grabMouse(); MAIN_mouseGrabber = 0; } - + if (MAIN_keyboardGrabber) { //qDebug("grabKeyboard"); @@ -827,19 +827,19 @@ static void check_quit_now(intptr_t param) { static bool exit_called = false; - + if (must_quit() && !exit_called) { if (QApplication::instance()) { GB_FUNCTION func; - + if (GB.ExistClass("TrayIcons")) { if (!GB.GetFunction(&func, (void *)GB.FindClass("TrayIcons"), "DeleteAll", NULL, NULL)) GB.Call(&func, 0, FALSE); } - + #ifndef QT5 qApp->syncX(); #endif @@ -855,7 +855,7 @@ { if (_check_quit_posted) return; - + GB.Post((GB_CALLBACK)check_quit_now, 0); _check_quit_posted = true; } @@ -885,9 +885,9 @@ /*QX11Info::setAppDpiX(0, 92); QX11Info::setAppDpiY(0, 92);*/ - + /*fcntl(ConnectionNumber(qt_xdisplay()), F_SETFD, FD_CLOEXEC);*/ - + if (::strcmp(qApp->style()->metaObject()->className(), "Breeze::Style") == 0) { char *env = getenv("GB_QT_NO_BREEZE_FIX"); @@ -897,8 +897,8 @@ qApp->setStyle(new FixBreezeStyle); } } - - + + MAIN_update_scale(qApp->desktop()->font()); qApp->installEventFilter(&CWidget::manager); @@ -907,7 +907,7 @@ #endif MyApplication::setEventFilter(true); - + if (GB.GetFunction(&_application_keypress_func, (void *)GB.Application.StartupClass(), "Application_KeyPress", "", "") == 0) { _application_keypress = true; @@ -917,9 +917,9 @@ //qt_x11_set_global_double_buffer(false); qApp->setQuitOnLastWindowClosed(false); - + MyApplication::initClipboard(); - + init = true; } @@ -940,19 +940,19 @@ { int pos; QString locale(lang); - + pos = locale.lastIndexOf("."); if (pos >= 0) locale = locale.left(pos); - + if (_translator) { qApp->removeTranslator(_translator); delete _translator; _translator = NULL; } - + _translator = new QTranslator(); - + if (!try_to_load_translation(locale)) goto __INSTALL_TRANSLATOR; @@ -966,10 +966,10 @@ delete _translator; _translator = NULL; - + //if (strcmp(lang, "C")) // qDebug("gb.qt4: warning: unable to load Qt translation: %s", lang); - + goto __SET_DIRECTION; __INSTALL_TRANSLATOR: @@ -1031,13 +1031,13 @@ static void hook_quit() { GB_FUNCTION func; - + CWINDOW_close_all(true); CWINDOW_delete_all(true); qApp->sendPostedEvents(); //processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::DeferredDeletion, 0); qApp->sendPostedEvents(0, QEvent::DeferredDelete); - + if (!GB.GetFunction(&func, (void *)GB.FindClass("_Gui"), "_Quit", NULL, NULL)) GB.Call(&func, 0, FALSE); } @@ -1046,7 +1046,7 @@ static void hook_loop() { //qDebug("**** ENTERING EVENT LOOP"); - + qApp->sendPostedEvents(); //qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::DeferredDeletion, 0); @@ -1056,13 +1056,19 @@ qApp->exec(); else MAIN_check_quit(); - + hook_quit(); } static void hook_wait(int duration) { + if (MyDrawingArea::inAnyDrawEvent()) + { + GB.Error("Wait is forbidden during a repaint event"); + return; + } + MAIN_in_wait++; if (duration > 0) { @@ -1086,7 +1092,7 @@ t->deleteLater(); timer->id = 0; } - + if (on) timer->id = (intptr_t)(new MyTimer(timer)); } @@ -1124,7 +1130,7 @@ CWatch::stop(); msg = "This application has raised an unexpected
error and must abort.


"; - + if (code > 0) { msg = msg + "[%1] %2.
%3"; @@ -1148,7 +1154,7 @@ static void QT_InitWidget(QWidget *widget, void *object, int fill_bg) { - ((CWIDGET *)object)->flag.fillBackground = fill_bg; + ((CWIDGET *)object)->flag.fillBackground = fill_bg; CWIDGET_new(widget, object); } @@ -1242,7 +1248,7 @@ QMenu *QT_FindMenu(void *parent, const char *name) { CMENU *menu = NULL; - + if (parent && GB.Is(parent, CLASS_Control)) { CWINDOW *window = CWidget::getWindow((CWIDGET *)parent); @@ -1296,9 +1302,9 @@ }; #ifdef QT5 -void *GB_QT5_1[] EXPORT = +void *GB_QT5_1[] EXPORT = #else -void *GB_QT4_1[] EXPORT = +void *GB_QT4_1[] EXPORT = #endif { (void *)1, @@ -1355,17 +1361,17 @@ int EXPORT GB_INIT(void) { char *env; - + // Do not disable GLib support - + env = getenv("KDE_FULL_SESSION"); if (env && !strcasecmp(env, "true")) putenv((char *)"QT_NO_GLIB=1"); - + env = getenv("GB_GUI_BUSY"); if (env && atoi(env)) MAIN_debug_busy = true; - + //putenv((char *)"QT_SLOW_TOPLEVEL_RESIZE=1"); _old_hook_main = GB.Hook(GB_HOOK_MAIN, (void *)hook_main); @@ -1384,7 +1390,7 @@ GB.GetInterface("gb.image", IMAGE_INTERFACE_VERSION, &IMAGE); IMAGE.SetDefaultFormat(GB_IMAGE_BGRP); DRAW_init(); - + CLASS_Control = GB.FindClass("Control"); CLASS_Container = GB.FindClass("Container"); CLASS_UserControl = GB.FindClass("UserControl"); @@ -1464,13 +1470,13 @@ static void activate_main_window(intptr_t value) { CWINDOW *active; - + active = CWINDOW_Active; if (!active) active = CWINDOW_LastActive; - + if (!active) return; - + MyMainWindow *win = (MyMainWindow *)active->widget.widget; if (win && !win->isWindow()) win = (MyMainWindow *)win->window(); @@ -1488,13 +1494,13 @@ { if (!qApp) return; - + switch(signal) { case GB_SIGNAL_DEBUG_BREAK: release_grab(); break; - + case GB_SIGNAL_DEBUG_FORWARD: //while (qApp->activePopupWidget()) // delete qApp->activePopupWidget(); @@ -1502,7 +1508,7 @@ qApp->syncX(); #endif break; - + case GB_SIGNAL_DEBUG_CONTINUE: GB.Post((GB_CALLBACK)activate_main_window, 0); unrelease_grab(); diff -Nru gambas3-3.8.3/gb.qt5/src/x11.c gambas3-3.8.4/gb.qt5/src/x11.c --- gambas3-3.8.3/gb.qt5/src/x11.c 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.qt5/src/x11.c 2015-12-22 04:46:12.000000000 +0000 @@ -111,14 +111,14 @@ {NULL} }; -typedef +typedef struct { unsigned long flags; unsigned long functions; unsigned long decorations; long input_mode; unsigned long status; - } + } MwmHints; static void init_atoms() @@ -140,17 +140,17 @@ X11_atom_net_wm_user_time = XInternAtom(_display, "_NET_WM_USER_TIME", True); X11_atom_net_supported = XInternAtom(_display, "_NET_SUPPORTED", True); - + _atom_init = TRUE; } static Atom get_atom(int index) { X11_ATOM *a = &_atoms[index]; - + if (!a->atom) a->atom = XInternAtom(_display, a->name, True); - + return a->atom; } @@ -158,7 +158,7 @@ { int i = 0; X11_ATOM *p = _atoms; - + while (p->name) { if (!p->atom) @@ -209,24 +209,24 @@ False, AnyPropertyType, type, format, &count, &after, &data) != Success) return NULL; - + *pcount += count; - + size = *format == 32 ? sizeof(long) : ( *format == 16 ? sizeof(short) : 1 ); offset_size = *format == 32 ? sizeof(int32_t) : ( *format == 16 ? sizeof(short) : 1 ); - + //fprintf(stderr, "X11_get_property: format = %d size = %d count = %ld after = %ld\n", *format, size, count, after); - + GB.FreeString(&_property_value); _property_value = GB.NewString((char *)data, count * size); XFree(data); - + offset = count * offset_size / sizeof(int32_t); - + while (after) { //fprintf(stderr, "X11_get_property: offset = %ld read = %ld\n", offset, Min(after, PROPERTY_NEXT_READ) / sizeof(int32_t)); - + if (XGetWindowProperty(_display, wid, prop, offset, Min(after, PROPERTY_NEXT_READ) / sizeof(int32_t), False, AnyPropertyType, type, format, &count, &after, &data) != Success) @@ -234,13 +234,13 @@ *pcount += count; offset += count * offset_size / sizeof(int32_t); - + //fprintf(stderr, "X11_get_property: format = %d size = %d count = %ld after = %ld next offset = %ld\n", *format, size, count, after, offset); - + _property_value = GB.AddString(_property_value, (char *)data, count * size); XFree(data); } - + return _property_value; } @@ -248,7 +248,7 @@ { Atom type; int format; - + return X11_get_property(wid, prop, &type, &format, count); } @@ -267,7 +267,8 @@ length = MAX_WINDOW_PROP; _window_prop.count = length; - memcpy(_window_prop.atoms, data, length * sizeof(Atom)); + if (data) + memcpy(_window_prop.atoms, data, length * sizeof(Atom)); } static void save_window_state(Window win, Atom prop) @@ -338,7 +339,7 @@ data = get_property(_root, X11_atom_net_supported, &count); if (!data) return; - + GB.NewArray(&_supported, sizeof(Atom), count); memcpy(_supported, data, sizeof(Atom) * count); } @@ -393,7 +394,7 @@ { _window = window; _window_visible = visible; - + if (!visible) load_window_state(window, X11_atom_net_wm_state); } @@ -402,7 +403,7 @@ { if (!_window_visible) save_window_state(_window, X11_atom_net_wm_state); - + XFlush(_display); _window = (Window)0; } @@ -552,34 +553,34 @@ int X11_window_get_desktop(Window window) { - int length = 0; + int length; char *data = NULL; int desktop = 0; data = get_property(window, X11_atom_net_wm_desktop, &length); - if (data) desktop = *((int *)data); - + return desktop; } int X11_get_current_desktop() { - int length = 0; + int length; char *data; - int desktop; + int desktop = 0; data = get_property(_root, X11_atom_net_current_desktop, &length); + if (data) + desktop = *((int *)data); - desktop = *((int *)data); return desktop; } int X11_get_window_type(Window window) { int index; - + load_window_state(window, X11_atom_net_wm_window_type); index = find_atom(_window_prop.atoms[0]); if (index < 0) @@ -603,7 +604,7 @@ void X11_set_window_decorated(Window window, bool decorated) { // Motif structures - + MwmHints *hints; MwmHints new_hints; @@ -612,7 +613,7 @@ int format; ulong nitems; ulong bytes_after; - + if (X11_atom_motif_wm_hints == None) X11_atom_motif_wm_hints = XInternAtom(_display, "_MOTIF_WM_HINTS", True); @@ -620,7 +621,7 @@ X11_atom_motif_wm_hints, 0, sizeof(MwmHints)/sizeof(long), False, AnyPropertyType, &type, &format, &nitems, &bytes_after, &data); - + if (type == None) { hints = &new_hints; @@ -632,17 +633,17 @@ } else hints = (MwmHints *)data; - + hints->flags |= (1 << 1); - hints->decorations = decorated ? 1 : 0; - + hints->decorations = decorated ? 1 : 0; + XChangeProperty(_display, window, X11_atom_motif_wm_hints, X11_atom_motif_wm_hints, 32, PropModeReplace, (uchar *)hints, sizeof (MwmHints)/sizeof(long)); - + if (hints != &new_hints) XFree(hints); - + XFlush(_display); } @@ -675,7 +676,7 @@ X11_atom_net_workarea, 0, 4, False, XA_CARDINAL, &ret, &format, &nitems, &after, &data); - if (e == Success && ret == XA_CARDINAL && format == 32 && nitems == 4) + if (e == Success && ret == XA_CARDINAL && format == 32 && nitems == 4) { long *workarea = (long *)data; *x = workarea[0]; @@ -683,18 +684,18 @@ *w = workarea[2]; *h = workarea[3]; err = FALSE; - } + } if (data) XFree(data); - + return err; } bool X11_is_supported_by_WM(Atom atom) { int i; - + if (_supported) { for (i = 0; i < GB.Count(_supported); i++) @@ -714,10 +715,10 @@ if (!_net_moveresize_window) _net_moveresize_window = XInternAtom(_display, "_NET_MOVERESIZE_WINDOW", True); - + if (!X11_is_supported_by_WM(_net_moveresize_window)) return TRUE; - + e.xclient.type = ClientMessage; e.xclient.message_type = _net_moveresize_window; e.xclient.display = _display; @@ -729,20 +730,20 @@ e.xclient.data.l[3] = w; e.xclient.data.l[4] = h; XSendEvent(_display, _root, FALSE, (SubstructureNotifyMask | SubstructureRedirectMask), &e); - + return FALSE; } static Atom get_net_system_tray(void) { char buf[64]; - + if (X11_atom_net_system_tray == None) { sprintf(buf, "_NET_SYSTEM_TRAY_S%d", XScreenNumberOfScreen(DefaultScreenOfDisplay(_display))); X11_atom_net_system_tray = XInternAtom(_display, buf, 0); } - + return X11_atom_net_system_tray; } @@ -772,7 +773,7 @@ XUngrabServer(_display); XFlush(_display); - + if (xmanager == None) return TRUE; @@ -795,7 +796,7 @@ XSendEvent(_display, xmanager, 0, NoEventMask, (XEvent *)&ev); XSync(_display, 0); usleep(10000); - + return FALSE; } #endif diff -Nru gambas3-3.8.3/gb.sdl/acinclude.m4 gambas3-3.8.4/gb.sdl/acinclude.m4 --- gambas3-3.8.3/gb.sdl/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.sdl/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.sdl2/acinclude.m4 gambas3-3.8.4/gb.sdl2/acinclude.m4 --- gambas3-3.8.3/gb.sdl2/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.sdl2/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.sdl.sound/acinclude.m4 gambas3-3.8.4/gb.sdl.sound/acinclude.m4 --- gambas3-3.8.3/gb.sdl.sound/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.sdl.sound/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.v4l/acinclude.m4 gambas3-3.8.4/gb.v4l/acinclude.m4 --- gambas3-3.8.3/gb.v4l/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.v4l/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/gb.xml/acinclude.m4 gambas3-3.8.4/gb.xml/acinclude.m4 --- gambas3-3.8.3/gb.xml/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/gb.xml/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/main/acinclude.m4 gambas3-3.8.4/main/acinclude.m4 --- gambas3-3.8.3/main/acinclude.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/main/acinclude.m4 2015-12-22 04:46:12.000000000 +0000 @@ -81,7 +81,7 @@ AC_DEFINE(GAMBAS_VERSION_STRING, "GB_VERSION_MAJOR", Gambas version string) AC_DEFINE(GAMBAS_FULL_VERSION_STRING, "GB_VERSION_MAJOR.GB_VERSION_MINOR", Gambas full version string) - AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080003, [Full Gambas version]) + AC_DEFINE(GAMBAS_FULL_VERSION, 0x03080004, [Full Gambas version]) AC_DEFINE(GAMBAS_PCODE_VERSION, 0x03080000, [Gambas bytecode version]) AC_DEFINE(GAMBAS_PCODE_VERSION_MIN, 0x03000000, [Minimum Gambas bytecode version]) diff -Nru gambas3-3.8.3/main/gbx/gbx_api.c gambas3-3.8.4/main/gbx/gbx_api.c --- gambas3-3.8.3/main/gbx/gbx_api.c 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/main/gbx/gbx_api.c 2015-12-22 04:46:12.000000000 +0000 @@ -188,7 +188,7 @@ (void *)NUMBER_from_string, (void *)GB_NumberToString, (void *)LOCAL_gettext, - + (void *)STRING_subst, (void *)STRING_subst_add, (void *)STRING_make, @@ -288,14 +288,14 @@ (void *)STRING_start_len, (void *)STRING_end, (void *)STRING_make, - + (void *)DEBUG_get_current_position, (void *)DEBUG_enter_event_loop, (void *)DEBUG_leave_event_loop, - + (void *)SIGNAL_register, (void *)SIGNAL_unregister, - + (void *)LIST_insert, (void *)LIST_remove, @@ -330,17 +330,17 @@ { (void *)EXEC_release, (void *)RELEASE_many, - + (void *)EXEC_push_unknown, (void *)EXEC_push_array, - + (void *)EXEC_pop_unknown, (void *)EXEC_pop_array, - + (void *)CENUM_create, (void *)EXEC_enum_first, (void *)EXEC_enum_next, - + (void *)EXEC_new, (void *)EXEC_enter_quick, (void *)EXEC_enter, @@ -351,15 +351,15 @@ (void *)EXEC_leave_keep, (void *)EXEC_leave_drop, (void *)EXEC_function_loop, - + (void *)EXEC_special, (void *)EXEC_object_variant, (void *)EXEC_object_other, - + (void *)EXTERN_get_function_info, (void *)EXTERN_call, (void *)EXTERN_make_callback, - + (void *)STRING_new, (void *)STRING_new_temp_value, (void *)STRING_free_real, @@ -367,21 +367,21 @@ (void *)STRING_compare, (void *)STRING_equal_ignore_case_same, (void *)STRING_conv, - + (void *)OBJECT_comp_value, (void *)COMPARE_object, (void *)CLASS_inherits, (void *)OBJECT_create, (void *)CLASS_free, (void *)SYMBOL_find, - + (void *)CARRAY_get_array_class, (void *)CARRAY_get_data_multi, (void *)CARRAY_create_static, (void *)CSTRUCT_create_static, - + (void *)REGEXP_scan, - + (void *)VALUE_convert, (void *)VALUE_to_string, (void *)VALUE_convert_float, @@ -389,12 +389,12 @@ (void *)VALUE_convert_string, (void *)VALUE_is_null, (void *)VALUE_undo_variant, - + (void *)NUMBER_from_string, (void *)NUMBER_int_to_string, - + (void *)LOCAL_format_number, - + (void *)DATE_to_string, (void *)DATE_from_string, (void *)DATE_comp, @@ -402,10 +402,10 @@ (void *)DATE_now, (void *)DATE_add, (void *)DATE_diff, - + (void *)randomize, (void *)rnd, - + (void *)THROW, (void *)ERROR_panic, (void *)ERROR_propagate, @@ -413,9 +413,9 @@ (void *)ERROR_set_last, (void *)ERROR_lock, (void *)ERROR_unlock, - + (void *)TYPE_get_name, - + (void *)SUBR_not, (void *)SUBR_and_, (void *)SUBR_cat, @@ -480,13 +480,13 @@ (void *)SUBR_quote, (void *)SUBR_unquote, (void *)SUBR_ptr, - + (void *)CLASS_load_from_jit, (void *)CLASS_run_inits, - + (void *)DEBUG_get_current_position, (void *)NULL, // Later set to DEBUG.Profile.Add - + (void *)EXEC_quit, NULL }; @@ -501,7 +501,7 @@ #define CATCH_ERROR \ bool ret = FALSE; \ TRY - + #define END_CATCH_ERROR \ CATCH \ { \ @@ -514,7 +514,7 @@ #define CATCH_ERROR_INT \ int ret = 0; \ TRY - + #define END_CATCH_ERROR_INT \ CATCH \ { \ @@ -527,7 +527,7 @@ bool GB_GetInterface(const char *name, int version, void *iface) { GB_LoadComponent(name); - + if (LIBRARY_get_interface_by_name(name, version, iface)) ERROR_panic("Cannot find interface of library '%s'", name); @@ -715,9 +715,9 @@ EXEC.native = FALSE; EXEC.index = (int)(intptr_t)desc->property.read; //EXEC.func = &class->load->func[(long)desc->property.read]; - + EXEC_function_keep(); - + TEMP = *RP; UNBORROW(RP); RP->type = T_VOID; @@ -836,10 +836,10 @@ if (OBJECT_parent(obs) && obs->event && obs->event[event_id]) return TRUE; } - + if (!OBJECT_parent(object)) return FALSE; - + event_tab = OBJECT_event(object)->event; func_id = event_tab[event_id]; @@ -850,14 +850,14 @@ static int get_event_func_id(ushort *event_tab, int event_id) { int func_id; - + if (!event_tab) return 0; - + func_id = event_tab[event_id]; if (!func_id) return 0; - + return func_id; } @@ -868,11 +868,11 @@ CLASS_DESC_METHOD *desc; void *old_last; bool result; - + func_id--; if (OBJECT_is_class(observer)) - class = (CLASS *)observer; //OBJECT_class(object); + class = (CLASS *)observer; //OBJECT_class(object); else class = OBJECT_class(observer); @@ -881,7 +881,7 @@ old_last = EVENT_Last; EVENT_Last = object; //OBJECT_REF(object, "raise_event"); - + // if (arg) // { // EXEC_dup(nparam); @@ -893,7 +893,7 @@ // va_end(args); // } - stop_event = GAMBAS_StopEvent; + stop_event = GAMBAS_StopEvent; GAMBAS_StopEvent = FALSE; EXEC_public_desc(class, observer, desc, nparam); @@ -905,9 +905,9 @@ if (GAMBAS_StopEvent) result = TRUE; - + GAMBAS_StopEvent = stop_event; - + //OBJECT_UNREF(object, "raise_event"); EVENT_Last = old_last; @@ -923,12 +923,12 @@ static void error_GB_Raise() { void *object = (void *)ERROR_handler->arg1; - + RELEASE_MANY(SP, (int)(ERROR_handler->arg2)); OBJECT_UNREF(object); - + _raise_event_level--; - + if (_GB_Raise_handler && _GB_Raise_handler->level == _raise_event_level) { (*_GB_Raise_handler->callback)(_GB_Raise_handler->data); @@ -967,9 +967,9 @@ arg = nparam < 0; nparam = abs(nparam); - + _raise_event_level++; - + ON_ERROR_2(error_GB_Raise, object, nparam) { if (!arg) @@ -978,11 +978,11 @@ push(nparam, args); va_end(args); } - + result = FALSE; - + // Observers before - + LIST_for_each(obs, OBJECT_event(object)->observer) { parent = OBJECT_active_parent(obs); @@ -992,41 +992,39 @@ continue; //if (obs->object != object) // continue; - + func_id = get_event_func_id(obs->event, event_id); if (!func_id) continue; - + if (!OBJECT_is_valid(parent)) { OBJECT_detach((OBJECT *)obs); continue; } - + EXEC_dup(nparam); result = raise_event(parent, object, func_id, nparam); - + if (result) goto __RETURN; } - + // Parent - + parent = OBJECT_active_parent(object); if (parent) { func_id = get_event_func_id(OBJECT_event(object)->event, event_id); + #if DEBUG_EVENT + CLASS *class = OBJECT_class(object); + fprintf(stderr, "GB_Raise(%p, %d, %s)\n", object, event_id, class->event[event_id].name); + fprintf(stderr, "func_id = %d parent = (%s %p)\n", func_id, parent->class->name, parent); + if (OBJECT_is_locked(parent)) + fprintf(stderr, "parent is locked!\n"); + #endif if (func_id) { - #if DEBUG_EVENT - CLASS *class = OBJECT_class(object); - printf("GB_Raise(%p, %d, %s)\n", object, event_id, class->event[event_id].name); - printf("func_id = %d parent = (%s %p)\n", func_id, parent->class->name, parent); - if (OBJECT_is_locked(parent)) - printf("parent is locked!\n"); - fflush(NULL); - #endif - if (!OBJECT_is_valid(parent)) OBJECT_detach(object); else @@ -1038,9 +1036,9 @@ } } } - + // Observers after - + LIST_for_each(obs, OBJECT_event(object)->observer) { parent = OBJECT_active_parent(obs); @@ -1050,32 +1048,32 @@ continue; //if (obs->object != object) // continue; - + func_id = get_event_func_id(obs->event, event_id); if (!func_id) continue; - + if (!OBJECT_is_valid(parent)) { OBJECT_detach((OBJECT *)obs); continue; } - + EXEC_dup(nparam); result = raise_event(parent, object, func_id, nparam); if (result) goto __RETURN; } - + __RETURN: - + RELEASE_MANY(SP, nparam); - OBJECT_UNREF(object); + OBJECT_UNREF(object); } END_ERROR _raise_event_level--; - + return result; } @@ -1105,7 +1103,7 @@ } CLASS_load(class); - + index = CLASS_find_symbol(class, name); if (index == NO_SYMBOL) { @@ -1183,9 +1181,9 @@ CLASS *class = (CLASS *)_class; int len = strlen(_name); char name[len + 4]; - + CLASS_load(class); - + strcpy(name, "_@"); strcat(name, _name); @@ -1221,7 +1219,7 @@ EXEC_public_desc(func->desc->class, func->object, func->desc, nparam); _event_stopped = GAMBAS_StopEvent; GAMBAS_StopEvent = stop_event; - + if (release) EXEC_release_return_value(); else @@ -1300,7 +1298,7 @@ for (i = 0; i < 4; i++) arg[i] = va_arg(args, char *); - + va_end(args); ERROR_define(error, arg); @@ -1383,7 +1381,7 @@ #endif OBJECT_UNREF(*object); } - + #if TRACE_MEMORY CP = save; #endif @@ -1657,7 +1655,7 @@ void GB_ReturnVariant(GB_VARIANT_VALUE *val) { TEMP._variant.type = T_VARIANT; - + if (!val) { TEMP._variant.vtype = T_NULL; @@ -1937,10 +1935,10 @@ void *GB_Create(void *class, const char *name, void *parent) { void *object; - + object = OBJECT_new(class, name, parent); OBJECT_UNREF_KEEP(object); - + return object; } @@ -1961,7 +1959,7 @@ nparam = (int)(intptr_t)parent; parent = NULL; } - + return OBJECT_create(class, name, parent, nparam); } else @@ -1971,7 +1969,7 @@ bool GB_CheckObject(void *object) { CLASS *class; - + if (object == NULL) { GB_Error((char *)E_NULL); @@ -2019,9 +2017,9 @@ void *GB_Eval(void *expr, void *func) { bool err = EVAL_expression((EXPRESSION *)expr, (EVAL_FUNCTION)func); - + EXEC_set_native_error(err); - + if (err) return NULL; else @@ -2189,16 +2187,16 @@ char *GB_SystemDomainName(void) { char host[256], domain[256]; - + if (gethostname(host, sizeof(host) - 1)) return ""; - + if (getdomainname(domain, sizeof(domain) - 1)) return ""; - + if ((strlen(host) + strlen(domain)) > COMMON_BUF_MAX) return ""; - + *COMMON_buffer = 0; if (*domain && strcmp(domain, "(none)")) { @@ -2206,7 +2204,7 @@ strcat(COMMON_buffer, "."); } strcat(COMMON_buffer, host); - + return COMMON_buffer; } @@ -2318,7 +2316,7 @@ char *pattern; int len_pattern; char *str; - + TRY { if (recursive) @@ -2349,7 +2347,7 @@ GAMBAS_Error = TRUE; } END_TRY; - + return ret; } #endif @@ -2398,7 +2396,7 @@ static void project_file_found(const char *path) { FILE_STAT info; - + FILE_stat(path, &info, FALSE); (*_browse_project_func)(path, info.size); } @@ -2406,7 +2404,7 @@ void GB_BrowseProject(GB_BROWSE_PROJECT_CALLBACK func) { ARCHIVE *arch = NULL; - + ARCHIVE_get_current(&arch); if (!arch || (arch == ARCHIVE_main && !EXEC_arch)) { @@ -2466,7 +2464,7 @@ double stop, time; DEBUG_enter_event_loop(); - + if (delay == 0) { HOOK_DEFAULT(wait, WATCH_wait)(0); @@ -2474,7 +2472,7 @@ else { wait = delay / 1000.0; - + DATE_timer(&stop, FALSE); stop += wait; @@ -2488,7 +2486,7 @@ wait = stop - time; if (wait <= 0.0) break; - + rem.tv_sec = 0; rem.tv_nsec = 1000000; nanosleep(&rem, &rem); @@ -2501,7 +2499,7 @@ bool GB_Serialize(const char *path, GB_VALUE *value) { STREAM stream; - + CATCH_ERROR { STREAM_open(&stream, path, ST_CREATE); @@ -2514,7 +2512,7 @@ bool GB_UnSerialize(const char *path, GB_VALUE *value) { STREAM stream; - + CATCH_ERROR { STREAM_open(&stream, path, ST_READ); diff -Nru gambas3-3.8.3/main/gbx/gbx_c_class.c gambas3-3.8.4/main/gbx/gbx_c_class.c --- gambas3-3.8.3/main/gbx/gbx_c_class.c 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/main/gbx/gbx_c_class.c 2015-12-22 04:46:12.000000000 +0000 @@ -687,7 +687,7 @@ } } - GB_ReturnBoolean(GB_Raise(object, desc->event.index, np)); + GB_ReturnBoolean(GB_Raise(object, desc->event.index, -np)); return; __UNKNOWN_EVENT: diff -Nru gambas3-3.8.3/main/gbx/gbx_exec_loop.c gambas3-3.8.4/main/gbx/gbx_exec_loop.c --- gambas3-3.8.3/main/gbx/gbx_exec_loop.c 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/main/gbx/gbx_exec_loop.c 2015-12-22 04:46:12.000000000 +0000 @@ -80,8 +80,12 @@ //---- Subroutine dispatch table -------------------------------------------- -static void *SubrTable[] = +static const void *SubrTable[] = { + /* 00 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + /* 10 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + /* 20 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + /* 28 */ NULL, _SUBR_compn, NULL, NULL, /* 2C */ NULL, NULL, SUBR_near, SUBR_case, /* 30 */ _SUBR_add, _SUBR_sub, _SUBR_mul, _SUBR_div, @@ -503,7 +507,7 @@ _SUBR_CODE: //fprintf(stderr, "gbx3: %02X: %s\n", (code >> 8), DEBUG_get_current_position()); - (*(EXEC_FUNC_CODE)SubrTable[(code >> 8) - 0x28])(code); + (*(EXEC_FUNC_CODE)SubrTable[code >> 8])(code); //if (PCODE_is_void(code)) // POP(); @@ -547,7 +551,7 @@ _SUBR: - (*(EXEC_FUNC)SubrTable[(code >> 8) - 0x28])(); + (*(EXEC_FUNC)SubrTable[code >> 8])(); goto _NEXT; /*-----------------------------------------------*/ diff -Nru gambas3-3.8.3/main/gbx/gbx_local.c gambas3-3.8.4/main/gbx/gbx_local.c --- gambas3-3.8.3/main/gbx/gbx_local.c 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/main/gbx/gbx_local.c 2015-12-22 04:46:12.000000000 +0000 @@ -191,7 +191,7 @@ { if (*dst) strcat(dst, sep); - + strcat(dst, src); } @@ -360,10 +360,10 @@ { if (!*str || !str[1]) return str[0]; - + if ((uchar)str[0] == 0xC2 && (uchar)str[1] == 0xA0 && str[2] == 0) return ' '; - + return '?'; } @@ -384,7 +384,7 @@ free_local_info(); /* local encoding */ - + if (!LOCAL_is_UTF8) STRING_free(&LOCAL_encoding); @@ -405,7 +405,7 @@ /* Numeric information */ info = localeconv(); - + //fprintf(stderr, "'%s' '%s' %d %d\n", info->thousands_sep, info->mon_thousands_sep, *info->thousands_sep, *info->grouping); //fprintf(stderr, "'%s' '%s'\n", nl_langinfo(THOUSANDS_SEP), nl_langinfo(MON_THOUSANDS_SEP)); @@ -423,7 +423,7 @@ STRING_ref(LOCAL_local.intl_currency_symbol);*/ // Date format - + p = nl_langinfo(D_FMT); //fprintf(stderr, "date format: %s\n", p); dp = LOCAL_local.date_order; @@ -432,7 +432,7 @@ p = "%m/%d/%y"; else if (strcmp(p, "%F") == 0) p = "%Y-%m-%d"; - + for (;;) { c = *p++; @@ -446,7 +446,7 @@ { if (c == 'E' || c == 'O') c = *p++; - + switch (c) { case 'y': case 'Y': @@ -456,7 +456,7 @@ stradd_sep(LOCAL_local.short_date, "yyyy", "/"); stradd_sep(LOCAL_local.general_date, "yyyy", "/"); break; - + case 'b': case 'B': case 'h': case 'm': *dp++ = LO_MONTH; stradd_sep(LOCAL_local.long_date, "mmmm", " "); @@ -464,7 +464,7 @@ stradd_sep(LOCAL_local.short_date, "mm", "/"); stradd_sep(LOCAL_local.general_date, "mm", "/"); break; - + case 'd': case 'e': *dp++ = LO_DAY; stradd_sep(LOCAL_local.long_date, "dddd d", " "); @@ -476,7 +476,7 @@ continue; } } - + if (dp != LOCAL_local.date_order && LOCAL_local.date_sep == 0) LOCAL_local.date_sep = STRING_utf8_to_unicode(p - 1, STRING_utf8_get_char_length(c)); } @@ -486,10 +486,10 @@ p = nl_langinfo(T_FMT); //fprintf(stderr, "time format: %s\n", p); tp = LOCAL_local.time_order; - + if (strcmp(p, "%T") == 0 || strcmp(p, "%R") == 0 || strcmp(p, "%r") == 0) p = "%H:%M:%S"; - + got_second = FALSE; for (;;) @@ -505,7 +505,7 @@ { if (c == 'E' || c == 'O') c = *p++; - + switch(c) { case 'H': case 'I': case 'k': case 'l': @@ -535,9 +535,9 @@ if (tp != LOCAL_local.time_order && LOCAL_local.time_sep == 0) LOCAL_local.time_sep = STRING_utf8_to_unicode(p - 1, STRING_utf8_get_char_length(c)); } - + // Fix missing seconds - + if (!got_second) { *tp++ = LO_SECOND; @@ -545,11 +545,11 @@ } // Fix the french date separator - + lang = LOCAL_get_lang(); if (strcmp(lang, "fr") == 0 || strncmp(lang, "fr_", 3) == 0) LOCAL_local.date_sep = '/'; - + stradd_sep(LOCAL_local.general_date, LOCAL_local.long_time, " "); am_pm = nl_langinfo(AM_STR); if (am_pm && *am_pm) @@ -577,13 +577,13 @@ strcpy(LOCAL_local.general_currency, "($#,##0."); strncat(LOCAL_local.general_currency, "########", Min(8, info->frac_digits)); strcat(LOCAL_local.general_currency, ")"); - + strcpy(LOCAL_local.intl_currency, "($$#,##0."); strncat(LOCAL_local.intl_currency, "########", Min(8, info->int_frac_digits)); strcat(LOCAL_local.intl_currency, ")"); init_currency_flag(info); - + LOCAL_local.true_str = STRING_new_zero(LOCAL_gettext(LOCAL_default.true_str)); LOCAL_local.len_true_str = STRING_length(LOCAL_local.true_str); LOCAL_local.false_str = STRING_new_zero(LOCAL_gettext(LOCAL_default.false_str)); @@ -621,7 +621,7 @@ lang = "en_US"; _lang = STRING_new_zero(lang); } - + return _lang; } @@ -675,7 +675,7 @@ break; } } - + var = getenv("GB_REVERSE"); if (var && !(var[0] == '0' && var[1] == 0)) rtl = !rtl; @@ -716,12 +716,12 @@ int pos_first_digit; bool intl_currency; - + if (local) local_current = &LOCAL_local; else local_current = &LOCAL_default; - + switch(fmt_type) { case LF_USER: @@ -1007,15 +1007,15 @@ if (!exposant) ndigit += number_exp; ndigit = MinMax(ndigit, 0, MAX_FLOAT_DIGIT); //fprintf(stderr, "number_mant = %.24g number_exp = %d ndigit = %d\n", number_mant, number_exp, ndigit); - + power = pow10_uint64_p(ndigit + 1); - + mantisse = number_mant * power; if ((mantisse % 10) >= 5) mantisse += 10; - + //fprintf(stderr, "-> power = %" PRId64 " mantisse = %" PRId64 "\n", power, mantisse); - + if (mantisse >= power) { ndigit = sprintf(buf, ".%" PRId64, mantisse); @@ -1026,7 +1026,7 @@ { ndigit = sprintf(buf, "0.%" PRId64, mantisse); } - + ndigit--; buf[ndigit] = 0; @@ -1207,13 +1207,13 @@ static char temp[8] = { 0 }; int i, n; bool minus = FALSE; - + if (value < 0) { value = (-value); minus = TRUE; } - + n = 0; for (i = 7; i >= 0; i--) { @@ -1231,14 +1231,14 @@ value /= 10; } } - + if (minus) { i--; temp[i] = '-'; n++; } - + add_string(&temp[i], n, NULL); } @@ -1253,13 +1253,13 @@ return FALSE; date_token = *token == 'd' || *token == 'm' || *token == 'y'; - + if ((date_token && DATE_SERIAL_has_no_date(date))) // || (!date_token && DATE_SERIAL_has_no_time(date))) { *token = 0; return TRUE; } - + switch (*token) { case 'd': @@ -1323,9 +1323,9 @@ } break; - + case 't': - + if (count <= 2) { time_t t = (time_t)0L; @@ -1453,7 +1453,7 @@ if (pos == pos_ampm) { add_date_token(&vdate, &token, token_count); - + /* passage en struct tm */ date_tm.tm_sec = date->sec; @@ -1504,7 +1504,7 @@ } -void LOCAL_load_translation(ARCHIVE *arch) +static void LOCAL_load_translation(ARCHIVE *arch) { char *domain = NULL; char *lang_list; @@ -1597,7 +1597,7 @@ dst = FILE_cat(FILE_make_temp(NULL, NULL), "tr", NULL); mkdir(dst, S_IRWXU); - + dst = FILE_cat(FILE_make_temp(NULL, NULL), "tr", lang, NULL); mkdir(dst, S_IRWXU); @@ -1627,7 +1627,7 @@ __ERROR: // If the *.mo was not copied, then the following functions will failed - + #ifdef DEBUG_LANG fprintf(stderr, "bindtextdomain: %s\n", bindtextdomain(domain, FILE_cat(FILE_make_temp(NULL, NULL), "tr", NULL))); @@ -1685,7 +1685,7 @@ fprintf(stderr, "dgettext(\"%s\", \"%s\") -> \"%s\"\n", arch->domain, msgid, tr); #endif } - + if (tr == msgid) { if (!_translation_loaded) @@ -1707,12 +1707,12 @@ int LOCAL_get_first_day_of_week() { const char *lang; - + if (LOCAL_first_day_of_week >= 0) return LOCAL_first_day_of_week; - + lang = LOCAL_get_lang(); - + if (strcmp(lang, "en") == 0 || strncmp(lang, "en_", 3) == 0 || strcmp(lang, "C") == 0) return 0; else diff -Nru gambas3-3.8.3/main/gbx/gbx_local.h gambas3-3.8.4/main/gbx/gbx_local.h --- gambas3-3.8.3/main/gbx/gbx_local.h 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/main/gbx/gbx_local.h 2015-12-22 04:46:12.000000000 +0000 @@ -111,7 +111,7 @@ const char *LOCAL_get_lang(void); void LOCAL_set_lang(const char *lang); const char *LOCAL_gettext(const char *msgid); -void LOCAL_load_translation(ARCHIVE *arch); +//void LOCAL_load_translation(ARCHIVE *arch); int LOCAL_get_first_day_of_week(); void LOCAL_set_first_day_of_week(char day); diff -Nru gambas3-3.8.3/main/share/gb_file_temp.h gambas3-3.8.4/main/share/gb_file_temp.h --- gambas3-3.8.3/main/share/gb_file_temp.h 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/main/share/gb_file_temp.h 2015-12-22 04:46:12.000000000 +0000 @@ -62,6 +62,7 @@ static bool file_dir_arch = FALSE; static int file_attr; static char *file_rdir_path = NULL; +static bool _temp_used = FALSE; #endif @@ -142,6 +143,8 @@ { static int count = 0; + _temp_used = TRUE; + if (len) { if (pattern) @@ -174,8 +177,10 @@ void FILE_remove_temp_file(void) { - FILE_recursive_dir(FILE_make_temp(NULL, NULL), NULL, remove_temp_file, 0, FALSE); + if (_temp_used) + FILE_recursive_dir(FILE_make_temp(NULL, NULL), NULL, remove_temp_file, 0, FALSE); rmdir(FILE_make_temp(NULL, NULL)); + _temp_used = FALSE; } void FILE_remove_temp_file_pid(pid_t pid) @@ -188,12 +193,13 @@ void FILE_init(void) { struct stat info; - + + _temp_used = TRUE; FILE_remove_temp_file(); - + snprintf(file_buffer, sizeof(file_buffer), FILE_TEMP_PREFIX, (int)getuid()); (void)mkdir(file_buffer, S_IRWXU); - + if (lstat(file_buffer, &info) == 0 && S_ISDIR(info.st_mode) && chown(file_buffer, getuid(), getgid()) == 0 && chmod(file_buffer, S_IRWXU) == 0) { snprintf(file_buffer, sizeof(file_buffer), FILE_TEMP_DIR, (int)getuid(), (int)getpid()); @@ -223,7 +229,7 @@ d++; s++; } - + return d; } @@ -294,7 +300,7 @@ } va_end(args); - + file_buffer_length = p - file_buffer; return file_buffer; } @@ -317,15 +323,15 @@ static void init_file_buffer(const char *path) { int len; - + if (path == file_buffer) return; - + len = strlen(path); - + if (len > PATH_MAX) THROW(E_TOOLONG); - + strcpy(file_buffer, path); file_buffer_length = len; } @@ -429,7 +435,7 @@ path = FILE_get_name(path); init_file_buffer(path); - + p = rindex(file_buffer, '.'); if (p) *p = 0; @@ -503,7 +509,7 @@ ret = stat(path, &buf); else ret = lstat(path, &buf); - + if (ret) THROW_SYSTEM(errno, path); @@ -535,7 +541,7 @@ char *FILE_mode_to_string(mode_t mode) { char *str = file_buffer; - + str[0] = mode & S_IRUSR ? 'r' : '-'; str[1] = mode & S_IWUSR ? 'w' : '-'; str[2] = (mode & S_ISUID @@ -552,9 +558,9 @@ ? (mode & S_IXOTH ? 't' : 'T') : (mode & S_IXOTH ? 'x' : '-')); str[9] = 0; - + file_buffer_length = 9; - + return str; } @@ -572,17 +578,17 @@ { S_IXOTH | S_ISVTX, { '-', 'x', 'T', 't' }, { 0, S_IXOTH, S_ISVTX, S_IXOTH | S_ISVTX } }, { 0 } }; - + unsigned char c, test; FILE_MODE_DECODE *d = decode; int i; - + while (d->mask) { c = *str++; if (!c) break; - + for (i = 0; i < 3; i++) { test = d->test[i]; @@ -594,10 +600,10 @@ break; } } - + d++; } - + return mode; } @@ -616,7 +622,7 @@ { struct passwd *pwd; uid_t uid; - + if (FILE_is_relative(path)) THROW(E_ACCESS); @@ -632,7 +638,7 @@ THROW(E_USER); uid = pwd->pw_uid; } - + if (chown(path, uid, (gid_t)-1)) THROW_SYSTEM(errno, path); } @@ -642,7 +648,7 @@ { struct group *grp; gid_t gid; - + if (FILE_is_relative(path)) THROW(E_ACCESS); @@ -658,7 +664,7 @@ THROW(E_USER); gid = grp->gr_gid; } - + if (chown(path, (uid_t)-1, gid)) THROW_SYSTEM(errno, path); } @@ -728,7 +734,7 @@ { init_file_buffer(file_path); p += file_buffer_length; - + if (p[-1] != '/' && (file_buffer[1] || file_buffer[0] != '/')) *p++ = '/'; } @@ -742,16 +748,16 @@ dir_exit(); return TRUE; } - + name = entry->d_name; - + if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) continue; len_entry = strlen(name); if ((len_entry + file_buffer_length) > PATH_MAX) continue; - + if (file_attr) { #ifdef _DIRENT_HAVE_D_TYPE @@ -809,7 +815,7 @@ STRING_free(&file_rdir_path); file_rdir_path = STRING_new_zero(dir); - + FILE_dir_first(dir, NULL, attr != GB_STAT_DIRECTORY ? 0 : GB_STAT_DIRECTORY); while (!FILE_dir_next(&file, &len)) { @@ -826,7 +832,7 @@ is_dir = info.type == GB_STAT_DIRECTORY; } #endif - + if (is_dir) push_path(&dir_list, path); else @@ -1058,17 +1064,17 @@ struct stat info; fprintf(stderr, "FILE_copy: %s -> %s\n", src, dst); - + if (stat(src, &info)) return TRUE; - + src_fd = open(src, O_RDONLY); if (src_fd < 0) { fprintf(stderr, "open src failed\n"); return TRUE; } - + dst_fd = creat(dst, info.st_mode); if (dst_fd < 0) { @@ -1078,7 +1084,7 @@ errno = save_errno; return TRUE; } - + ALLOC(&buf, MAX_IO); for(;;) @@ -1099,11 +1105,11 @@ return TRUE; } } - + close(src_fd); close(dst_fd); IFREE(buf); - + return FALSE; } diff -Nru gambas3-3.8.3/.pc/applied-patches gambas3-3.8.4/.pc/applied-patches --- gambas3-3.8.3/.pc/applied-patches 2015-11-08 16:47:24.000000000 +0000 +++ gambas3-3.8.4/.pc/applied-patches 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -fix_ide_version.patch diff -Nru gambas3-3.8.3/.pc/fix_ide_version.patch/app/src/gambas3/.project gambas3-3.8.4/.pc/fix_ide_version.patch/app/src/gambas3/.project --- gambas3-3.8.3/.pc/fix_ide_version.patch/app/src/gambas3/.project 2015-11-08 16:47:24.000000000 +0000 +++ gambas3-3.8.4/.pc/fix_ide_version.patch/app/src/gambas3/.project 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -# Gambas Project File 3.0 -# Compiled with Gambas 3.8.90 -Title=Gambas 3 -Startup=Project -Icon=img/logo/logo-ide.png -Version=3.8.90 -VersionFile=1 -Component=gb.image -Component=gb.gui.qt -Component=gb.form -Component=gb.clipper -Component=gb.db -Component=gb.db.form -Component=gb.debug -Component=gb.desktop.x11 -Component=gb.desktop -Component=gb.eval -Component=gb.eval.highlight -Component=gb.form.dialog -Component=gb.form.editor -Component=gb.settings -Component=gb.form.mdi -Component=gb.form.stock -Component=gb.gui.qt.webkit -Component=gb.net -Component=gb.net.curl -Component=gb.markdown -Component=gb.util -Description="Integrated Development Environment for Gambas" -Authors="Benoît Minisini\nFabien Bodard\nCharlie Reinl\nJosé Luis Redrejo\nRobert Rowe\nTobias Boege" -TabSize=2 -Translate=1 -Language=en -Maintainer=gambas -Vendor=gambas -Address=gambas@users.sourceforge.net -License=General Public License -PackageName=gambas3-3.6.90 -CreateEachDirectory=1 -Packager=1 -Systems=slackware -ExtraAutoconfTest="\n" -Menus=slackware:"Amusement" -Categories=slackware:"Amusement" -Groups=slackware:"Development/Languages" -Menus=ubuntu:"Applications/Amateur Radio" -Categories=ubuntu:"Audio;AudioVideo" -Groups=ubuntu:"devel" -Tags=Database,Development,GUIDesigner,IDE,MySQL,PostgreSQL,SQLite -WebSite=http://gambas.sourceforge.net diff -Nru gambas3-3.8.3/.pc/.quilt_patches gambas3-3.8.4/.pc/.quilt_patches --- gambas3-3.8.3/.pc/.quilt_patches 2015-11-08 16:47:24.000000000 +0000 +++ gambas3-3.8.4/.pc/.quilt_patches 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -/home/buildd/build-RECIPEBRANCHBUILD-1016366/chroot-autobuild/home/buildd/work/tree/gambas3-3.8.3/debian/patches diff -Nru gambas3-3.8.3/.pc/.quilt_series gambas3-3.8.4/.pc/.quilt_series --- gambas3-3.8.3/.pc/.quilt_series 2015-11-08 16:47:24.000000000 +0000 +++ gambas3-3.8.4/.pc/.quilt_series 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -/home/buildd/build-RECIPEBRANCHBUILD-1016366/chroot-autobuild/home/buildd/work/tree/gambas3-3.8.3/debian/patches/series diff -Nru gambas3-3.8.3/.pc/.version gambas3-3.8.4/.pc/.version --- gambas3-3.8.3/.pc/.version 2015-11-08 16:47:24.000000000 +0000 +++ gambas3-3.8.4/.pc/.version 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -2 diff -Nru gambas3-3.8.3/VERSION gambas3-3.8.4/VERSION --- gambas3-3.8.3/VERSION 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/VERSION 2015-12-22 04:46:12.000000000 +0000 @@ -1 +1 @@ -3.8.3 \ No newline at end of file +3.8.4 \ No newline at end of file diff -Nru gambas3-3.8.3/version.m4 gambas3-3.8.4/version.m4 --- gambas3-3.8.3/version.m4 2015-11-08 16:47:15.000000000 +0000 +++ gambas3-3.8.4/version.m4 2015-12-22 04:46:12.000000000 +0000 @@ -1,9 +1,9 @@ ## Package version and e-mail for bugs are defined here -m4_define([GB_VERSION], [3.8.3]) +m4_define([GB_VERSION], [3.8.4]) m4_define([GB_MAIL], [gambas@users.sourceforge.net]) m4_define([GB_URL], [http://gambas.sourceforge.net]) m4_define([GB_VERSION_MAJOR], [3]) m4_define([GB_VERSION_MINOR], [8]) -m4_define([GB_VERSION_RELEASE], [3]) +m4_define([GB_VERSION_RELEASE], [4])