From 7f48d3c37172b21cbbe221c25c07deaca112ad5a Mon Sep 17 00:00:00 2001 From: Kolan Sh Date: Sun, 27 Dec 2015 19:06:08 +0300 Subject: [PATCH] First release ;-) --- .gitmodules | 6 + AUTHORS | 1 + CMakeLists.txt | 24 + COPYING | 165 +++ INSTALL | 85 ++ MAINTAINERS | 2 + README | 2 +- cmake/backbone | 1 + config/CMakeLists.txt | 5 + config/Config.vapi | 6 + config/config.h.in | 3 + config/ws.backbone.laview.desktop.gschema.xml | 23 + cpack/CMakeLists.txt | 14 + pkg-config/CMakeLists.txt | 6 + po/CMakeLists.txt | 1 + po/de/CMakeLists.txt | 1 + po/de/laview-desktop.po | 196 +++ po/laview-desktop.pot | 196 +++ po/ru/CMakeLists.txt | 1 + po/ru/laview-desktop.po | 197 +++ res/CMakeLists.txt | 7 + res/about.svg | 262 ++++ res/laview-desktop.desktop.in | 9 + res/laview-desktop.gresource.xml | 8 + res/laview-desktop.ico | Bin 0 -> 67646 bytes res/laview-desktop.png | Bin 0 -> 13754 bytes res/laview-desktop.rc | 1 + src/AboutWindow.vala | 37 + src/AppCore.vala | 10 + src/AppDirs.vala | 31 + src/CMakeLists.txt | 16 + src/MainWindow.vala | 256 ++++ src/PreferencesWindow.vala | 77 ++ src/Resources.vala | 11 + src/Settings.vala | 15 + src/SubprocessDialog.vala | 69 + src/Utils.vala | 72 ++ src/main.vala | 72 ++ test/CMakeLists.txt | 0 ui/CMakeLists.txt | 1 + ui/glade/CMakeLists.txt | 2 + ui/glade/laview-desktop.glade | 1134 +++++++++++++++++ util/backbone | 1 + valadoc_env | 2 + 44 files changed, 3027 insertions(+), 1 deletion(-) create mode 100644 .gitmodules create mode 100644 AUTHORS create mode 100644 CMakeLists.txt create mode 100644 COPYING create mode 100644 INSTALL create mode 100644 MAINTAINERS create mode 160000 cmake/backbone create mode 100644 config/CMakeLists.txt create mode 100644 config/Config.vapi create mode 100644 config/config.h.in create mode 100644 config/ws.backbone.laview.desktop.gschema.xml create mode 100644 cpack/CMakeLists.txt create mode 100644 pkg-config/CMakeLists.txt create mode 100644 po/CMakeLists.txt create mode 100644 po/de/CMakeLists.txt create mode 100644 po/de/laview-desktop.po create mode 100644 po/laview-desktop.pot create mode 100644 po/ru/CMakeLists.txt create mode 100644 po/ru/laview-desktop.po create mode 100644 res/CMakeLists.txt create mode 100644 res/about.svg create mode 100644 res/laview-desktop.desktop.in create mode 100644 res/laview-desktop.gresource.xml create mode 100644 res/laview-desktop.ico create mode 100644 res/laview-desktop.png create mode 100644 res/laview-desktop.rc create mode 100644 src/AboutWindow.vala create mode 100644 src/AppCore.vala create mode 100644 src/AppDirs.vala create mode 100644 src/CMakeLists.txt create mode 100644 src/MainWindow.vala create mode 100644 src/PreferencesWindow.vala create mode 100644 src/Resources.vala create mode 100644 src/Settings.vala create mode 100644 src/SubprocessDialog.vala create mode 100644 src/Utils.vala create mode 100644 src/main.vala create mode 100644 test/CMakeLists.txt create mode 100644 ui/CMakeLists.txt create mode 100644 ui/glade/CMakeLists.txt create mode 100644 ui/glade/laview-desktop.glade create mode 160000 util/backbone create mode 100644 valadoc_env diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..309b0cd --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "cmake/backbone"] + path = cmake/backbone + url = git@git.backbone.ws:cmake/backbone.git +[submodule "util/backbone"] + path = util/backbone + url = git@git.backbone.ws:cmake/backbone-utils.git diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..609258d --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Kolan Sh diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..eb3daa8 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,24 @@ +PROJECT (LAviewDesktop C) + +CMAKE_MINIMUM_REQUIRED (VERSION 2.8) + +SET (PROJECT_LOWERCASE_NAME "laview-desktop") +SET (PROJECT_DESCRIPTION "LAview Desktop Application.") + +SET (MAJOR 0) +SET (MINOR 0) +SET (PATCH 0) + +LIST (APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/backbone) + +ADD_SUBDIRECTORY (config) +ADD_SUBDIRECTORY (src) +ADD_SUBDIRECTORY (po) +ADD_SUBDIRECTORY (pkg-config) +ADD_SUBDIRECTORY (test) +ADD_SUBDIRECTORY (cpack) +ADD_SUBDIRECTORY (ui) +ADD_SUBDIRECTORY (res) + +# enable testing +ENABLE_TESTING () diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..65c5ca8 --- /dev/null +++ b/COPYING @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..067530d --- /dev/null +++ b/INSTALL @@ -0,0 +1,85 @@ + Requirements + ------------ + + Build-Time Dependencies + +LAview-Core: https://redmine.backbone.ws/projects/laview-core +GTK+-3:http://www.gtk.org/ +CMake: http://www.cmake.org +NSIS (W32): http://nsis.sourceforge.net + + Run-Time Dependencies + +GTK+-3:http://www.gtk.org/ +LAview-Core: https://redmine.backbone.ws/projects/laview-core + + Operation Systems + + * GNU/Linux (Gentoo, Debian, etc.) + * MS Windows (Windows 5.1 aka XP) + * BSD-based (FreeBSD, OpenBSD, NetBSD, Mac OS X) + +If you need support of one more OS, be free in writing of patches and sending +pull-requests to the mainstream. + + + Compilation + ----------- + + Compilation under GNU/Linux + +$ mkdir build-gcc && cd build-gcc +$ cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr +$ make -j$((`getconf _NPROCESSORS_ONLN`+1)) + + Compilation under MS Windows + +$ mkdir build-mingw && cd build-mingw +$ cmake -G "MSYS Makefiles" .. -DCMAKE_BUILD_TYPE=Release +$ make -j$((NUMBER_OF_PROCESSORS + 1)) + + Compilation under BSD-based Systems. + +TODO: add description here. + + + Packing/Installation + -------------------- + + Packing/Installation under GNU/Linux + +$ cpack +Install using System Package Manager. + + Packing/Installation under MS Windows + +$ cpack +Install using generated by NSIS executable. + + Packing/Installation under BSD-based + +$ cpack +Install using System Package Manager. + + + Testing + ------- + + Testing under GNU/Linux + +$ ctest -j$((`getconf _NPROCESSORS_ONLN`+1)) + +Automated tests for memory leaks: +$ ctest -j$((NUMBER_OF_PROCESSORS + 1)) -D NightlyMemCheck && grep definitely Testing/Temporary/LastDynamicAnalysis_*.log + + Testing under MS Windows + +$ ctest -j$((NUMBER_OF_PROCESSORS + 1)) +Automated tests for memory leaks are not available as far as Valgrind not +present on this platform. + + Testing under BSD-based + +$ ctest +Automated tests for memory leaks are not available as far as Valgrind not +present on this platform. diff --git a/MAINTAINERS b/MAINTAINERS new file mode 100644 index 0000000..f2b408a --- /dev/null +++ b/MAINTAINERS @@ -0,0 +1,2 @@ +Kolan Sh +email: backbone@backbone.ws diff --git a/README b/README index 92cf5e3..54f23d0 100644 --- a/README +++ b/README @@ -1 +1 @@ -Desktop LAview Application. +LAview Desktop Application. diff --git a/cmake/backbone b/cmake/backbone new file mode 160000 index 0000000..126f4cc --- /dev/null +++ b/cmake/backbone @@ -0,0 +1 @@ +Subproject commit 126f4cc3fecf5f9c8ad3dd55edc164801f64482a diff --git a/config/CMakeLists.txt b/config/CMakeLists.txt new file mode 100644 index 0000000..fed903d --- /dev/null +++ b/config/CMakeLists.txt @@ -0,0 +1,5 @@ +SET (GSchemaFile "ws.backbone.laview.desktop") +INCLUDE (GSchemaCommonRules) + +CONFIGURE_FILE ("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" + "${CMAKE_CURRENT_BINARY_DIR}/config.h") diff --git a/config/Config.vapi b/config/Config.vapi new file mode 100644 index 0000000..24a890f --- /dev/null +++ b/config/Config.vapi @@ -0,0 +1,6 @@ +[CCode (cheader_filename = "config.h")] +namespace Config { + static const int VERSION_MAJOR; + static const int VERSION_MINOR; + static const int VERSION_PATCH; +} diff --git a/config/config.h.in b/config/config.h.in new file mode 100644 index 0000000..3c66f33 --- /dev/null +++ b/config/config.h.in @@ -0,0 +1,3 @@ +#define CONFIG_VERSION_MAJOR @MAJOR@ +#define CONFIG_VERSION_MINOR @MINOR@ +#define CONFIG_VERSION_PATCH @PATCH@ diff --git a/config/ws.backbone.laview.desktop.gschema.xml b/config/ws.backbone.laview.desktop.gschema.xml new file mode 100644 index 0000000..5b04dfa --- /dev/null +++ b/config/ws.backbone.laview.desktop.gschema.xml @@ -0,0 +1,23 @@ + + + + + "Hello, earthlings" + A greeting + Greeting of the invading martians + + + + 99 + Bottles of beer + Number of bottles of beer on the wall + + + + false + Is the light switched on? + State of an imaginary light switch. + + + + diff --git a/cpack/CMakeLists.txt b/cpack/CMakeLists.txt new file mode 100644 index 0000000..19d42ae --- /dev/null +++ b/cpack/CMakeLists.txt @@ -0,0 +1,14 @@ +SET (CONTACT "backbone@backbone.ws") +SET (DEBIAN_DEPENDENCIES "laview-core-0 >= 0.0.0") +SET (DEBIAN_SECTION "TeX") +SET (REDHAT_DEPENDENCIES "laview-core-0 >= 0.0.0") +SET (REDHAT_SECTION "Applications/Publishing") +SET (LICENSE "LGPLv3+") +SET (WIN32_UNINSTALL_NAME "LAvDesk") # <= 8 symbols for the name + +SET (CPACK_PACKAGE_EXECUTABLES "${PROJECT_LOWERCASE_NAME}-${MAJOR};LAview Desktop") +SET (CPACK_NSIS_INSTALLED_ICON_NAME bin\\\\${PROJECT_LOWERCASE_NAME}-${MAJOR}.exe) +SET (CPACK_CREATE_DESKTOP_LINKS "${PROJECT_LOWERCASE_NAME}-${MAJOR}") +SET (CPACK_NSIS_MENU_LINKS "https://redmine.backbone.ws/projects/laview/wiki" "Homepage for LAview Desktop") + +INCLUDE (CPackCommonRules) diff --git a/pkg-config/CMakeLists.txt b/pkg-config/CMakeLists.txt new file mode 100644 index 0000000..d349889 --- /dev/null +++ b/pkg-config/CMakeLists.txt @@ -0,0 +1,6 @@ +INCLUDE (PkgConfigCommonRules) + +CONFIGURE_FILE ( + "${CMAKE_SOURCE_DIR}/cmake/backbone/templates/pkg-config.pc.in" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_LOWERCASE_NAME}-${MAJOR}.pc" +) diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt new file mode 100644 index 0000000..c191c1b --- /dev/null +++ b/po/CMakeLists.txt @@ -0,0 +1 @@ +INCLUDE (GettextCommonRules) diff --git a/po/de/CMakeLists.txt b/po/de/CMakeLists.txt new file mode 100644 index 0000000..0b6020c --- /dev/null +++ b/po/de/CMakeLists.txt @@ -0,0 +1 @@ +INCLUDE (GettextLangRules) diff --git a/po/de/laview-desktop.po b/po/de/laview-desktop.po new file mode 100644 index 0000000..1a3abfa --- /dev/null +++ b/po/de/laview-desktop.po @@ -0,0 +1,196 @@ +# German translations for laview-desktop package. +# Copyright (C) 2015 THE laview-desktop'S COPYRIGHT HOLDER +# This file is distributed under the same license as the laview-desktop package. +# , 2015. +# +msgid "" +msgstr "" +"Project-Id-Version: laview-desktop\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-27 19:03+0300\n" +"PO-Revision-Date: 2015-10-24 20:19+0300\n" +"Last-Translator: \n" +"Language-Team: German\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:1 +msgid "\"Hello, earthlings\"" +msgstr "" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:2 +msgid "A greeting" +msgstr "" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:3 +msgid "Greeting of the invading martians" +msgstr "" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:4 +msgid "Bottles of beer" +msgstr "" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:5 +msgid "Number of bottles of beer on the wall" +msgstr "" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:6 +msgid "Is the light switched on?" +msgstr "" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:7 +msgid "State of an imaginary light switch." +msgstr "" + +#: src/MainWindow.vala:84 +msgid "Select templates" +msgstr "" + +#: src/MainWindow.vala:86 +msgid "_Cancel" +msgstr "" + +#: src/MainWindow.vala:87 +msgid "_Open" +msgstr "" + +#: src/main.vala:33 +msgid "Show the application's version" +msgstr "" + +#: src/main.vala:52 +msgid "[FILE]" +msgstr "" + +#: src/main.vala:64 +#, c-format +msgid "Error: %s\n" +msgstr "" + +#: src/main.vala:65 +#, c-format +msgid "Run '%s --help' to see a full list of available command line options.\n" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:1 +msgid "Kolan Sh (backbone@backbone.ws)" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:2 +msgid "LaTeX View or View Data in LaTeX." +msgstr "" + +#: ui/glade/laview-desktop.glade.h:3 +msgid "LAview" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:4 +msgid "Kolan Sh" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:5 +msgid "LAview Preferences" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:6 +msgid "Paths" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:7 +msgid "LyX path on Windows" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:8 +msgid "pdfLaTeX path on Windows" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:9 +msgid "Common" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:10 +msgid "Protocol Plugins" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:11 +msgid "Protocol plugins" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:12 +msgid "Data Plugins" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:13 +msgid "Data plugins" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:14 +msgid "LAview Desktop" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:15 +msgid "_Template" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:16 +msgid "_Document" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:17 +msgid "_Application" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:18 +msgid "_Help" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:19 +msgid "Create a new template" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:20 +msgid "Open a template" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:21 +msgid "Change selected template" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:22 +msgid "Delete selected template" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:23 +msgid "Document object preparing" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:24 +msgid "View and print the document" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:25 +msgid "Edit the result document" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:26 +msgid "Application preferences" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:27 +msgid "Help and reference" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:28 +msgid "Close the application" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:29 +msgid "Templates" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:30 +msgid "Document Objects" +msgstr "" diff --git a/po/laview-desktop.pot b/po/laview-desktop.pot new file mode 100644 index 0000000..93e18f7 --- /dev/null +++ b/po/laview-desktop.pot @@ -0,0 +1,196 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the laview-desktop package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: laview-desktop\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-27 19:04+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:1 +msgid "\"Hello, earthlings\"" +msgstr "" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:2 +msgid "A greeting" +msgstr "" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:3 +msgid "Greeting of the invading martians" +msgstr "" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:4 +msgid "Bottles of beer" +msgstr "" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:5 +msgid "Number of bottles of beer on the wall" +msgstr "" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:6 +msgid "Is the light switched on?" +msgstr "" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:7 +msgid "State of an imaginary light switch." +msgstr "" + +#: src/MainWindow.vala:84 +msgid "Select templates" +msgstr "" + +#: src/MainWindow.vala:86 +msgid "_Cancel" +msgstr "" + +#: src/MainWindow.vala:87 +msgid "_Open" +msgstr "" + +#: src/main.vala:33 +msgid "Show the application's version" +msgstr "" + +#: src/main.vala:52 +msgid "[FILE]" +msgstr "" + +#: src/main.vala:64 +#, c-format +msgid "Error: %s\n" +msgstr "" + +#: src/main.vala:65 +#, c-format +msgid "Run '%s --help' to see a full list of available command line options.\n" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:1 +msgid "Kolan Sh (backbone@backbone.ws)" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:2 +msgid "LaTeX View or View Data in LaTeX." +msgstr "" + +#: ui/glade/laview-desktop.glade.h:3 +msgid "LAview" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:4 +msgid "Kolan Sh" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:5 +msgid "LAview Preferences" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:6 +msgid "Paths" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:7 +msgid "LyX path on Windows" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:8 +msgid "pdfLaTeX path on Windows" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:9 +msgid "Common" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:10 +msgid "Protocol Plugins" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:11 +msgid "Protocol plugins" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:12 +msgid "Data Plugins" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:13 +msgid "Data plugins" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:14 +msgid "LAview Desktop" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:15 +msgid "_Template" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:16 +msgid "_Document" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:17 +msgid "_Application" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:18 +msgid "_Help" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:19 +msgid "Create a new template" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:20 +msgid "Open a template" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:21 +msgid "Change selected template" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:22 +msgid "Delete selected template" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:23 +msgid "Document object preparing" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:24 +msgid "View and print the document" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:25 +msgid "Edit the result document" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:26 +msgid "Application preferences" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:27 +msgid "Help and reference" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:28 +msgid "Close the application" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:29 +msgid "Templates" +msgstr "" + +#: ui/glade/laview-desktop.glade.h:30 +msgid "Document Objects" +msgstr "" diff --git a/po/ru/CMakeLists.txt b/po/ru/CMakeLists.txt new file mode 100644 index 0000000..0b6020c --- /dev/null +++ b/po/ru/CMakeLists.txt @@ -0,0 +1 @@ +INCLUDE (GettextLangRules) diff --git a/po/ru/laview-desktop.po b/po/ru/laview-desktop.po new file mode 100644 index 0000000..c3d622b --- /dev/null +++ b/po/ru/laview-desktop.po @@ -0,0 +1,197 @@ +# Russian translations for laview-desktop package. +# Copyright (C) 2015 THE laview-desktop'S COPYRIGHT HOLDER +# This file is distributed under the same license as the laview-desktop package. +# , 2015. +# +msgid "" +msgstr "" +"Project-Id-Version: laview-desktop\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-27 19:03+0300\n" +"PO-Revision-Date: 2015-10-24 20:19+0300\n" +"Last-Translator: \n" +"Language-Team: Russian\n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:1 +msgid "\"Hello, earthlings\"" +msgstr "\"Привет, земляне\"" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:2 +msgid "A greeting" +msgstr "Приветствие" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:3 +msgid "Greeting of the invading martians" +msgstr "Приветствие вторгнувшихся марсиан" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:4 +msgid "Bottles of beer" +msgstr "Бутылки пива" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:5 +msgid "Number of bottles of beer on the wall" +msgstr "Число бутылок пива на стене" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:6 +msgid "Is the light switched on?" +msgstr "Включен ли свет?" + +#: config/ws.backbone.laview.desktop.gschema.xml.h:7 +msgid "State of an imaginary light switch." +msgstr "Состояние воображаемого выключателя света." + +#: src/MainWindow.vala:84 +msgid "Select templates" +msgstr "Выберите шаблоны" + +#: src/MainWindow.vala:86 +msgid "_Cancel" +msgstr "_Отмена" + +#: src/MainWindow.vala:87 +msgid "_Open" +msgstr "_Открыть" + +#: src/main.vala:33 +msgid "Show the application's version" +msgstr "Показать версию приложения" + +#: src/main.vala:52 +msgid "[FILE]" +msgstr "[ФАЙЛ]" + +#: src/main.vala:64 +#, c-format +msgid "Error: %s\n" +msgstr "Ошибка: %s\n" + +#: src/main.vala:65 +#, c-format +msgid "Run '%s --help' to see a full list of available command line options.\n" +msgstr "Запустите '%s --help', чтобы увидеть весь список доступных опций.\n" + +#: ui/glade/laview-desktop.glade.h:1 +msgid "Kolan Sh (backbone@backbone.ws)" +msgstr "Николай Ш (backbone@backbone.ws)" + +#: ui/glade/laview-desktop.glade.h:2 +msgid "LaTeX View or View Data in LaTeX." +msgstr "LaTeX вид или Представление данных в LaTeX." + +#: ui/glade/laview-desktop.glade.h:3 +msgid "LAview" +msgstr "LAview" + +#: ui/glade/laview-desktop.glade.h:4 +msgid "Kolan Sh" +msgstr "Николай Ш" + +#: ui/glade/laview-desktop.glade.h:5 +msgid "LAview Preferences" +msgstr "Параметры LAview" + +#: ui/glade/laview-desktop.glade.h:6 +msgid "Paths" +msgstr "Пути" + +#: ui/glade/laview-desktop.glade.h:7 +msgid "LyX path on Windows" +msgstr "Путь к LyX под Windows" + +#: ui/glade/laview-desktop.glade.h:8 +msgid "pdfLaTeX path on Windows" +msgstr "Путь к pdfLaTeX под Windows" + +#: ui/glade/laview-desktop.glade.h:9 +msgid "Common" +msgstr "Общие" + +#: ui/glade/laview-desktop.glade.h:10 +msgid "Protocol Plugins" +msgstr "Плагины протоколов" + +#: ui/glade/laview-desktop.glade.h:11 +msgid "Protocol plugins" +msgstr "Плагины протоколов" + +#: ui/glade/laview-desktop.glade.h:12 +msgid "Data Plugins" +msgstr "Плагины данных" + +#: ui/glade/laview-desktop.glade.h:13 +msgid "Data plugins" +msgstr "Плагины данных" + +#: ui/glade/laview-desktop.glade.h:14 +msgid "LAview Desktop" +msgstr "Рабочее окно LAview" + +#: ui/glade/laview-desktop.glade.h:15 +msgid "_Template" +msgstr "_Шаблон" + +#: ui/glade/laview-desktop.glade.h:16 +msgid "_Document" +msgstr "_Документ" + +#: ui/glade/laview-desktop.glade.h:17 +msgid "_Application" +msgstr "_Приложение" + +#: ui/glade/laview-desktop.glade.h:18 +msgid "_Help" +msgstr "_Помощь" + +#: ui/glade/laview-desktop.glade.h:19 +msgid "Create a new template" +msgstr "Создать новый шаблон" + +#: ui/glade/laview-desktop.glade.h:20 +msgid "Open a template" +msgstr "Открыть шаблон" + +#: ui/glade/laview-desktop.glade.h:21 +msgid "Change selected template" +msgstr "Изменить выбранный шаблон" + +#: ui/glade/laview-desktop.glade.h:22 +msgid "Delete selected template" +msgstr "Удалить выбранный шаблон" + +#: ui/glade/laview-desktop.glade.h:23 +msgid "Document object preparing" +msgstr "Подготовка объекта документа" + +#: ui/glade/laview-desktop.glade.h:24 +msgid "View and print the document" +msgstr "Просмотр и печать документа" + +#: ui/glade/laview-desktop.glade.h:25 +msgid "Edit the result document" +msgstr "Редактировать полученный документ" + +#: ui/glade/laview-desktop.glade.h:26 +msgid "Application preferences" +msgstr "Параметры приложения" + +#: ui/glade/laview-desktop.glade.h:27 +msgid "Help and reference" +msgstr "Помощь и справка" + +#: ui/glade/laview-desktop.glade.h:28 +msgid "Close the application" +msgstr "Закрыть приложение" + +#: ui/glade/laview-desktop.glade.h:29 +msgid "Templates" +msgstr "Шаблоны" + +#: ui/glade/laview-desktop.glade.h:30 +msgid "Document Objects" +msgstr "Объекты документа" diff --git a/res/CMakeLists.txt b/res/CMakeLists.txt new file mode 100644 index 0000000..5b562a0 --- /dev/null +++ b/res/CMakeLists.txt @@ -0,0 +1,7 @@ +INCLUDE (GResourceCommonRules) + +CONFIGURE_FILE ("${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_LOWERCASE_NAME}.desktop.in" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_LOWERCASE_NAME}-${MAJOR}.desktop") +INSTALL (FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_LOWERCASE_NAME}-${MAJOR}.desktop" + DESTINATION "share/applications") +INSTALL (FILES "laview-desktop.png" DESTINATION "share/pixmaps") diff --git a/res/about.svg b/res/about.svg new file mode 100644 index 0000000..bd12d95 --- /dev/null +++ b/res/about.svg @@ -0,0 +1,262 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/laview-desktop.desktop.in b/res/laview-desktop.desktop.in new file mode 100644 index 0000000..122e7c1 --- /dev/null +++ b/res/laview-desktop.desktop.in @@ -0,0 +1,9 @@ +[Desktop Entry] +Name=LAview Desktop @MAJOR@.@MINOR@.@PATCH@ +Comment=LAview Desktop Application +Exec=laview-desktop-@MAJOR@ %u +Icon=laview-desktop +Terminal=false +Type=Application +MimeType=laview/lyx; +Categories=Office; diff --git a/res/laview-desktop.gresource.xml b/res/laview-desktop.gresource.xml new file mode 100644 index 0000000..9dca2f5 --- /dev/null +++ b/res/laview-desktop.gresource.xml @@ -0,0 +1,8 @@ + + + + about.svg + + + + diff --git a/res/laview-desktop.ico b/res/laview-desktop.ico new file mode 100644 index 0000000000000000000000000000000000000000..03bbdfb0ba83cee837d90905863cd0f37f805790 GIT binary patch literal 67646 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 literal 0 HcmV?d00001 diff --git a/res/laview-desktop.png b/res/laview-desktop.png new file mode 100644 index 0000000000000000000000000000000000000000..157c4bd0a2196b7f395223ade538f862fffe9578 GIT binary patch literal 13754 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 E55{+|+5i9m literal 0 HcmV?d00001 diff --git a/res/laview-desktop.rc b/res/laview-desktop.rc new file mode 100644 index 0000000..6d8da22 --- /dev/null +++ b/res/laview-desktop.rc @@ -0,0 +1 @@ +IDR_MAINFRAME ICON "laview-desktop.ico" diff --git a/src/AboutWindow.vala b/src/AboutWindow.vala new file mode 100644 index 0000000..d686768 --- /dev/null +++ b/src/AboutWindow.vala @@ -0,0 +1,37 @@ +namespace LAview.Desktop { + + using Gtk; + + /** + * About dialog. + */ + public class AboutDialogWindow { + AboutDialog dialog; + + public AboutDialogWindow (Window parent) throws Error { + var builder = new Builder (); + builder.add_from_file (AppDirs.ui_dir + "/laview-desktop.glade"); + builder.connect_signals (this); + + dialog = builder.get_object ("aboutdialog_window") as AboutDialog; + dialog.set_destroy_with_parent (true); + dialog.set_transient_for (parent); + dialog.set_modal (true); + dialog.delete_event.connect ((source) => {return true;}); + + dialog.version = @" $(Config.VERSION_MAJOR).$(Config.VERSION_MINOR).$(Config.VERSION_PATCH)"; + + dialog.response.connect ((response_id) => { + if (response_id == Gtk.ResponseType.CANCEL || response_id == Gtk.ResponseType.DELETE_EVENT) { + dialog.hide_on_delete (); + } + }); + + dialog.logo = new Gdk.Pixbuf.from_resource_at_scale ("/ws/backbone/laview/desktop/about.svg", 256, 256, true); + } + + public void show_all () { + dialog.show_all (); + } + } +} diff --git a/src/AppCore.vala b/src/AppCore.vala new file mode 100644 index 0000000..cb8a9bc --- /dev/null +++ b/src/AppCore.vala @@ -0,0 +1,10 @@ +namespace LAview.Desktop { + + class AppCore { + public static LAview.Core.Core core; + + public static void init (string[] args) throws Error { + core = new LAview.Core.Core(); + } + } +} diff --git a/src/AppDirs.vala b/src/AppDirs.vala new file mode 100644 index 0000000..bf33f3e --- /dev/null +++ b/src/AppDirs.vala @@ -0,0 +1,31 @@ +namespace LAview.Desktop { + + class AppDirs { + private const string DEFAULT_DATA_DIR = ".texreport-gtk"; + + public static File exec_file; + public static File exec_dir; + public static File common_dir; + public static string resource_dir; + public static string ui_dir; + public static string locale_dir; + public static string settings_dir; + + public static void init (string[] args) { + exec_file = File.new_for_path (Environment.find_program_in_path (args[0])); + exec_dir = exec_file.get_parent (); + common_dir = exec_dir.get_parent (); + resource_dir = Path.build_path (Path.DIR_SEPARATOR_S, common_dir.get_path(), + "share/laview-desktop-"+Config.VERSION_MAJOR.to_string()); + ui_dir = resource_dir + "/ui"; + locale_dir = Path.build_path (Path.DIR_SEPARATOR_S, common_dir.get_path(), "share/locale"); + settings_dir = Path.build_path (Path.DIR_SEPARATOR_S, common_dir.get_path(), "share/glib-2.0/schemas"); + string w32dhack_sdir = settings_dir+"/laview-desktop-"+Config.VERSION_MAJOR.to_string(); + if (File.new_for_path(w32dhack_sdir+"/gschemas.compiled").query_exists ()) + settings_dir = w32dhack_sdir; + } + + public static void terminate () { + } + } +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..0b30aea --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,16 @@ +SET (BinName laview-desktop-${MAJOR}) +FILE (GLOB_RECURSE BinSources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.vala) +SET (BinPackages gtk+-3.0 gee-0.8 gobject-plugin-iface-0 laview-core-iface-0 laview-core-0 posix) +SET (BinPkgModules gtk+-3.0 gee-0.8 laview-core-0) +SET (BinCustomVapis ${CMAKE_SOURCE_DIR}/config/Config.vapi) +INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/config") +SET (BinInstall ON) +SET (BinExtraSources "${CMAKE_SOURCE_DIR}/res/laview-desktop.rc") +IF (WIN32) + SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mwindows") + SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--export-all-symbols") + SET (BinValaOpts -D WINDOWS) +ELSE (WIN32) + SET (BinValaOpts -D UNIX) +ENDIF (WIN32) +INCLUDE (ValaBinCommonRules) diff --git a/src/MainWindow.vala b/src/MainWindow.vala new file mode 100644 index 0000000..099d49c --- /dev/null +++ b/src/MainWindow.vala @@ -0,0 +1,256 @@ +namespace LAview.Desktop { + + using Gtk, LAview, Core; + + /** + * Main LAview Desktop window. + */ + public class MainWindow { + + Window window; + PreferencesDialog pref_dialog; + AboutDialogWindow about_dialog; + SubprocessDialog subprocess_dialog; + Gtk.Statusbar statusbar; + Gtk.ListStore liststore_templates; + Gtk.ListStore liststore_doc_objects; + TreeView treeview_templates; + TreeView treeview_objects; + + public MainWindow () throws Error { + var builder = new Builder (); + builder.add_from_file (AppDirs.ui_dir + "/laview-desktop.glade"); + builder.connect_signals (this); + + window = builder.get_object ("main_window") as Window; + statusbar = builder.get_object ("statusbar") as Statusbar; + liststore_templates = builder.get_object ("liststore_templates") as Gtk.ListStore; + liststore_doc_objects = builder.get_object ("liststore_objects") as Gtk.ListStore; + treeview_templates = builder.get_object ("treeview_templates") as TreeView; + treeview_objects = builder.get_object ("treeview_objects") as TreeView; + window.title = "LAview Desktop" + + @" $(Config.VERSION_MAJOR).$(Config.VERSION_MINOR).$(Config.VERSION_PATCH)"; + + pref_dialog = new PreferencesDialog (window); + subprocess_dialog = new SubprocessDialog (window); + about_dialog = new AboutDialogWindow (window); + + fill_liststore_templates (); + } + + void fill_liststore_templates () { + var templates = AppCore.core.get_templates_readable_names (); + liststore_templates.clear(); + Gtk.TreeIter iter = Gtk.TreeIter(); + foreach (var t in templates) { + liststore_templates.append (out iter); + liststore_templates.set (iter, 0, t); + } + } + + void statusbar_show (string str) { + var context_id = statusbar.get_context_id ("common_context"); + statusbar.push (context_id, str); + } + + public void show_all () { + window.show_all (); + statusbar_show ("We're ready, Commander! Select or create a template. :-)"); + } + + [CCode (instance_pos = -1)] + public void menu_about_activate (Gtk.ImageMenuItem item) { + about_dialog.show_all (); + } + + [CCode (instance_pos = -1)] + public void action_new_activate (Gtk.Action action) { + string[] argv = { AppCore.core.lyx_path, "--execute", "buffer-new" }; + try { + var subprocess = new SubprocessLauncher( SubprocessFlags.STDIN_PIPE + | SubprocessFlags.STDOUT_PIPE + | SubprocessFlags.STDERR_PIPE); + subprocess.spawnv(argv); + } catch (Error err) { + var msg = new MessageDialog (window, DialogFlags.MODAL, MessageType.ERROR, + ButtonsType.CLOSE, @"Error: $(err.message)."); + msg.response.connect ((response_id) => { msg.destroy (); } ); + msg.show (); + } + } + + [CCode (instance_pos = -1)] + public void action_open_activate (Gtk.Action action) { + FileChooserDialog chooser = new Gtk.FileChooserDialog (_("Select templates"), window, + FileChooserAction.OPEN, + _("_Cancel"), ResponseType.CANCEL, + _("_Open"), ResponseType.ACCEPT); + chooser.select_multiple = true; + FileFilter filter = new FileFilter (); + chooser.set_filter (filter); + filter.add_mime_type ("application/x-tex"); + filter.add_mime_type ("application/x-latex"); + filter.add_mime_type ("application/x-lyx"); + filter.add_pattern ("*.tex"); + filter.add_pattern ("*.latex"); + filter.add_pattern ("*.lyx"); + + if (chooser.run () == ResponseType.ACCEPT) { + SList paths = chooser.get_filenames (); + + foreach (unowned string path in paths) + AppCore.core.add_template (path); + + fill_liststore_templates (); + } + + chooser.close (); + } + + void edit_lyx_files (string[] paths) { + string[] args = { AppCore.core.lyx_path, "--remote" }; + foreach (var p in paths) args += p; + try { + var subprocess = new SubprocessLauncher( SubprocessFlags.STDIN_PIPE + | SubprocessFlags.STDOUT_PIPE + | SubprocessFlags.STDERR_PIPE); + subprocess.spawnv(args); + } catch (Error err) { + var msg = new MessageDialog (window, DialogFlags.MODAL, MessageType.ERROR, + ButtonsType.CLOSE, @"Error: $(err.message)."); + msg.response.connect ((response_id) => { msg.destroy (); } ); + msg.show (); + } + } + + int[] get_template_indices () { + var selection = treeview_templates.get_selection (); + var selected_rows = selection.get_selected_rows (null); + int[] indices = {}; + foreach (var r in selected_rows) { + indices += r.get_indices()[0]; + } + return indices; + } + + [CCode (instance_pos = -1)] + public void action_edit_template_activate (Gtk.Action action) { + edit_selected_templates (); + } + + [CCode (instance_pos = -1)] + public void action_delete_activate (Gtk.Action action) { + var indices = get_template_indices (); + for (int i = indices.length; i > 0; ) + AppCore.core.remove_template (indices[--i]); + fill_liststore_templates (); + } + + int[] get_objects_indices () { + var selection = treeview_objects.get_selection (); + var selected_rows = selection.get_selected_rows (null); + int[] indices = {}; + foreach (var r in selected_rows) { + indices += r.get_indices()[0]; + } + return indices; + } + + [CCode (instance_pos = -1)] + public void action_compose_activate (Gtk.Action action) { + var t_indices = get_template_indices (); + var o_indices = get_objects_indices (); + if (t_indices.length != 0 && o_indices.length != 0) { + AppCore.core.compose_object (t_indices[0], o_indices[0]); + } + statusbar_show ("After composing all objects print the document."); + } + + [CCode (instance_pos = -1)] + public void action_edit_result_activate (Gtk.Action action) { + var indices = get_template_indices(); + if (indices.length != 0) { + var lyx_path = AppCore.core.get_lyx_file_path (indices[0]); + edit_lyx_files ({ lyx_path }); + } + } + + void post_print () { + var indices = get_template_indices(); + var pdf_file = AppCore.core.get_pdf_file_path (indices[0]); + Utils.open_document (pdf_file, window); + } + + [CCode (instance_pos = -1)] + public void action_print_activate (Gtk.Action action) { + var indices = get_template_indices(); + if (indices.length != 0) { + try { + subprocess_dialog.show_all (AppCore.core.print_document (indices[0]), + "=== Print to PDF file... ===\n", + post_print); + } catch (Error err) { + var msg = new MessageDialog (window, DialogFlags.MODAL, MessageType.ERROR, + ButtonsType.CLOSE, @"Error: $(err.message)."); + msg.response.connect ((response_id) => { msg.destroy (); } ); + msg.show (); + } + } + } + + [CCode (instance_pos = -1)] + public void action_preferences_activate (Gtk.Action action) { + pref_dialog.show_all (); + } + + [CCode (instance_pos = -1)] + public void action_ref_activate (Gtk.Action action) { + try { + show_uri (null, "https://redmine.backbone.ws/projects/laview/wiki", Gdk.CURRENT_TIME); + } catch (Error err) { + var msg = new MessageDialog (window, DialogFlags.MODAL, MessageType.ERROR, + ButtonsType.CLOSE, @"Error: $(err.message)."); + msg.response.connect ((response_id) => { msg.destroy (); } ); + msg.show (); + } + } + + void edit_selected_templates () { + var indices = get_template_indices (); + if (indices.length != 0) { + string[] paths = {}; + foreach (var i in indices) { + paths += AppCore.core.get_template_path_by_index (i); + } + edit_lyx_files (paths); + } + } + + [CCode (instance_pos = -1)] + public void templates_row_activated (Gtk.TreeView treeview, + Gtk.TreePath path, + Gtk.TreeViewColumn column) { + edit_selected_templates (); + } + + [CCode (instance_pos = -1)] + public void templates_cursor_changed (Gtk.TreeView treeview) { + var indices = get_template_indices (); + if (indices.length != 0) { + var doc_objects = AppCore.core.get_objects_list (indices[0]); + liststore_doc_objects.clear(); + Gtk.TreeIter iter = Gtk.TreeIter(); + foreach (var t in doc_objects) { + liststore_doc_objects.append (out iter); + liststore_doc_objects.set (iter, 0, t); + } + } + statusbar_show ("Document analized, select an object and set it's properties."); + } + + [CCode (instance_pos = -1)] + public void objects_cursor_changed (Gtk.TreeView treeview) { + statusbar_show ("Press 'Properties' button to compose the object."); + } + } +} diff --git a/src/PreferencesWindow.vala b/src/PreferencesWindow.vala new file mode 100644 index 0000000..75022c1 --- /dev/null +++ b/src/PreferencesWindow.vala @@ -0,0 +1,77 @@ +namespace LAview.Desktop { + + using Gtk; + + /** + * Preferences window. + */ + public class PreferencesDialog { + Dialog dialog; + Gtk.ListStore liststore_data; + Gtk.ListStore liststore_protocols; + FileChooserButton filechooserbutton_lyx; + FileChooserButton filechooserbutton_pdflatex; + + public PreferencesDialog (Window parent) throws Error { + var builder = new Builder (); + builder.add_from_file (AppDirs.ui_dir + "/laview-desktop.glade"); + builder.connect_signals (this); + + dialog = builder.get_object ("preferences_window") as Dialog; + dialog.set_transient_for (parent); + dialog.set_modal (true); + dialog.delete_event.connect ((source) => {return true;}); + liststore_data = builder.get_object ("liststore_data") as Gtk.ListStore; + liststore_protocols = builder.get_object ("liststore_protocols") as Gtk.ListStore; + filechooserbutton_lyx = builder.get_object ("filechooserbutton_lyx") as FileChooserButton; + filechooserbutton_pdflatex = builder.get_object ("filechooserbutton_pdflatex") as FileChooserButton; + + fill_liststore_data (); + fill_liststore_protocols (); + + filechooserbutton_lyx.set_filename (AppCore.core.lyx_path); + filechooserbutton_pdflatex.set_filename (AppCore.core.pdflatex_path); + } + + void fill_liststore_data () { + var data_plugins = AppCore.core.get_data_plugins (); + + liststore_data.clear(); + TreeIter iter = TreeIter(); + foreach (var p in data_plugins.entries) { + liststore_data.append (out iter); + liststore_data.set (iter, 0, p.value.get_readable_name ()); + } + } + + void fill_liststore_protocols () { + var protocol_plugins = AppCore.core.get_protocol_plugins (); + + liststore_protocols.clear(); + TreeIter iter = TreeIter(); + foreach (var p in protocol_plugins.entries) { + liststore_protocols.append (out iter); + liststore_protocols.set (iter, 0, p.value.get_readable_name ()); + } + } + + public void show_all () { + dialog.show_all (); + } + + [CCode (instance_pos = -1)] + public void button_close_clicked (Button button) { + dialog.hide (); + } + + [CCode (instance_pos = -1)] + public void lyx_file_set (FileChooserButton chooser) { + AppCore.core.lyx_path = chooser.get_filename (); + } + + [CCode (instance_pos = -1)] + public void pdflatex_file_set (FileChooserButton chooser) { + AppCore.core.pdflatex_path = chooser.get_filename (); + } + } +} diff --git a/src/Resources.vala b/src/Resources.vala new file mode 100644 index 0000000..75e495a --- /dev/null +++ b/src/Resources.vala @@ -0,0 +1,11 @@ +namespace LAview.Desktop { + class Resources { + public static Resource resource; + + public static void init (string[] args) throws Error { + var resource_file = AppDirs.resource_dir+"/laview-desktop.gresource"; + resource = Resource.load (resource_file); + resource._register(); + } + } +} diff --git a/src/Settings.vala b/src/Settings.vala new file mode 100644 index 0000000..fb43e15 --- /dev/null +++ b/src/Settings.vala @@ -0,0 +1,15 @@ +namespace LAview.Desktop { + + class AppSettings { + //public static GLib.Settings settings; + + public static void init (string[] args) throws Error { + SettingsSchemaSource sss = new SettingsSchemaSource.from_directory (AppDirs.settings_dir, null, false); + //SettingsSchema schema = sss.lookup ("ws.backbone.laview.desktop-"+Config.VERSION_MAJOR.to_string(), false); + if (sss.lookup == null) + throw new FileError.NOENT ("Schema ID not found"); + + //settings = new Settings.full (schema, null, null); + } + } +} diff --git a/src/SubprocessDialog.vala b/src/SubprocessDialog.vala new file mode 100644 index 0000000..45ed139 --- /dev/null +++ b/src/SubprocessDialog.vala @@ -0,0 +1,69 @@ +namespace LAview.Desktop { + + using Gtk; + + /** + * Subprocess window. + */ + public class SubprocessDialog { + Dialog dialog; + TextView textview_stderrout; + Subprocess sp; + unowned PostProcessDelegate ppdelegate; + + public delegate void PostProcessDelegate (); + + public SubprocessDialog (Window parent) throws Error { + var builder = new Builder (); + builder.add_from_file (AppDirs.ui_dir + "/laview-desktop.glade"); + builder.connect_signals (this); + + dialog = builder.get_object ("subprocess_dialog") as Dialog; + dialog.set_transient_for (parent); + dialog.set_modal (true); + dialog.delete_event.connect ((source) => {return true;}); + textview_stderrout = builder.get_object ("textview_stderrout") as TextView; + } + + async void subprocess_async () { + try { + var ds_out = new DataInputStream(sp.get_stdout_pipe()); + try { + for (string s = yield ds_out.read_line_async(); s != null; s = yield ds_out.read_line_async()) + textview_stderrout.buffer.text += s + "\n"; + } catch (IOError err) { + assert_not_reached(); + } + if ((sp.wait_check()) == false) throw new IOError.FAILED("Error running subprocess."); + ppdelegate (); + dialog.hide (); + + } catch (Error err) { + textview_stderrout.buffer.text += @"Error: $(err.message)"; + if (sp != null) { + var ds_err = new DataInputStream(sp.get_stderr_pipe()); + try { + for (string s = yield ds_err.read_line_async(); s != null; s = yield ds_err.read_line_async()) + textview_stderrout.buffer.text += s + "\n"; + } catch (IOError err) { + assert_not_reached(); + } + } + } + } + + public void show_all (Subprocess sp, string message, PostProcessDelegate ppdelegate) { + this.sp = sp; + textview_stderrout.buffer.text = message; + this.ppdelegate = ppdelegate; + dialog.show_all (); + subprocess_async.begin (); + } + + [CCode (instance_pos = -1)] + public void button_stop_clicked (Button button) { + sp.force_exit (); + dialog.hide (); + } + } +} diff --git a/src/Utils.vala b/src/Utils.vala new file mode 100644 index 0000000..24c8668 --- /dev/null +++ b/src/Utils.vala @@ -0,0 +1,72 @@ +namespace LAview.Desktop { + + namespace Utils { + + using Gtk; + + /** + * Resolve a path beginning with "~" + * Look at: https://github.com/ssokolow/gvrun/blob/master/process_runner.vala#L86 + */ + #if (linux || UNIX || __unix__) + static string expand_tilde (string path) { + if (!path.has_prefix ("~")) return path; // Just pass paths through if they don't start with ~ + + // Split the ~user portion from the path (Use / for the path if not present) + string parts[2]; + if (!(Path.DIR_SEPARATOR_S in path)) { + parts = { path.substring(1), Path.DIR_SEPARATOR_S }; + } else { + string trimmed = path.substring(1); + parts = trimmed.split(Path.DIR_SEPARATOR_S, 2); + } + warn_if_fail(parts.length == 2); + + // Handle both "~" and "~user" forms + string home_path; + if (parts[0] == "") { + home_path = Environment.get_variable("HOME") ?? Environment.get_home_dir(); + } else { + unowned Posix.Passwd _pw = Posix.getpwnam(parts[0]); + home_path = (_pw == null) ? null : _pw.pw_dir; + } + + // Fail safely if we couldn't look up a homedir + if (home_path == null) { + warning("Could not get homedir for user: %s", parts[0].length > 0 ? parts[0] : ""); + return path; + } else { + return home_path + Path.DIR_SEPARATOR_S + parts[1]; + } + } + #endif + + /** + * Open document. + * Idea borrowed from: https://github.com/ssokolow/gvrun/blob/master/process_runner.vala + */ + void open_document (string path, Window? parent_window = null) { + #if (UNIX) + const string[] OPENERS = {"xdg-open", "mimeopen", "open"}; + foreach (var opener in OPENERS) { + if (Environment.find_program_in_path (opener) != null) { + try { + string[] argv = { opener, expand_tilde (path) }; + Process.spawn_async(null, argv, null, SpawnFlags.SEARCH_PATH, null, null); + } catch (SpawnError err) { + var msg = new MessageDialog (parent_window, DialogFlags.MODAL, MessageType.ERROR, + ButtonsType.CLOSE, @"Error: $(err.message)."); + msg.response.connect ((response_id) => { msg.destroy (); } ); + msg.show (); + } + break; + } + } + #elif (WINDOWS) + Posix.system (@"start $path"); + #else + assert_not_reached (); + #endif + } + } +} diff --git a/src/main.vala b/src/main.vala new file mode 100644 index 0000000..b140d9b --- /dev/null +++ b/src/main.vala @@ -0,0 +1,72 @@ +extern const string GETTEXT_PACKAGE; + +namespace LAview.Desktop { + + using Gtk, LAview.Desktop; + + namespace CommandlineOptions { + // bool no_startup_progress = false; + // string data_dir = null; + bool show_version = false; + // bool no_runtime_monitoring = false; + + OptionEntry[]? entries = null; + + OptionEntry[] get_options() { + if (entries != null) + return entries; + + // OptionEntry datadir = { "datadir", 'd', 0, OptionArg.FILENAME, &data_dir, + // N_("Path to LAview-Desktop's private data"), N_("DIRECTORY") }; + // entries += datadir; + + // OptionEntry no_monitoring = { "no-runtime-monitoring", 0, 0, OptionArg.NONE, &no_runtime_monitoring, + // N_("Do not monitor library directory at runtime for changes"), null }; + // entries += no_monitoring; + + // OptionEntry no_startup = { "no-startup-progress", 0, 0, OptionArg.NONE, + // &no_startup_progress, + // N_("Don't display startup progress meter"), null }; + // entries += no_startup; + + OptionEntry version = { "version", 'V', 0, OptionArg.NONE, &show_version, + N_("Show the application's version"), null }; + entries += version; + + OptionEntry terminator = { null, 0, 0, 0, null, null, null }; + entries += terminator; + + return entries; + } + } + + void main (string[] args) { + + try { + + AppDirs.init (args); + AppSettings.init (args); + AppCore.init (args); + Resources.init (args); + + Gtk.init_with_args (ref args, _("[FILE]"), CommandlineOptions.get_options (), GETTEXT_PACKAGE); + + // Internationalization + Intl.bindtextdomain (GETTEXT_PACKAGE, AppDirs.locale_dir); + Intl.bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + + var main_window = new MainWindow (); + main_window.show_all (); + + Gtk.main (); + + } catch (Error e) { + stderr.printf (_("Error: %s\n"), e.message); + stderr.printf (_("Run '%s --help' to see a full list of available command line options.\n"), args[0]); + } + + AppDirs.terminate(); + + return; + } +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..e69de29 diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt new file mode 100644 index 0000000..fc14716 --- /dev/null +++ b/ui/CMakeLists.txt @@ -0,0 +1 @@ +ADD_SUBDIRECTORY (glade) diff --git a/ui/glade/CMakeLists.txt b/ui/glade/CMakeLists.txt new file mode 100644 index 0000000..548088d --- /dev/null +++ b/ui/glade/CMakeLists.txt @@ -0,0 +1,2 @@ +SET (GladeFile ${PROJECT_LOWERCASE_NAME}) +INCLUDE (GladeCommonRules) diff --git a/ui/glade/laview-desktop.glade b/ui/glade/laview-desktop.glade new file mode 100644 index 0000000..01cfc9c --- /dev/null +++ b/ui/glade/laview-desktop.glade @@ -0,0 +1,1134 @@ + + + + + + False + dialog + LAview Desktop + Kolan Sh (backbone@backbone.ws) + LaTeX View or View Data in LaTeX. + https://redmine.backbone.ws/projects/laview + LAview + Kolan Sh + Kolan Sh + Kolan Sh + Kolan Sh + image-missing + lgpl-3-0 + + + False + vertical + 2 + + + False + end + + + False + False + 0 + + + + + + + + + + + + drive-optical + True + + + + + + True + + + + + + True + + + + + + True + + + + + + True + + + + + + True + + + + + + True + + + + + + True + + + + + + True + + + + + + + *.lyx + *.tex + + + + + + + + + + + + + + + + + + + + + + 640 + 480 + False + LAview Preferences + dialog + + + False + vertical + 2 + + + False + end + + + gtk-close + True + True + True + True + + + + True + True + 0 + + + + + False + False + 0 + + + + + True + True + True + True + + + True + False + 8 + 8 + 8 + 8 + + + True + False + + + True + False + Paths + 0 + + + + + + 0 + 0 + 2 + + + + + True + False + LyX path on Windows + 0 + + + 0 + 1 + + + + + True + False + pdfLaTeX path on Windows + 0 + + + 0 + 2 + + + + + True + False + True + + + + 1 + 1 + + + + + True + False + True + + + + 1 + 2 + + + + + + + + + True + False + Common + + + False + + + + + True + False + vertical + + + True + True + in + + + True + True + liststore_protocols + + + + + + Protocol Plugins + + + + 0 + + + + + + + + + True + True + 0 + + + + + 1 + + + + + True + False + Protocol plugins + + + 1 + False + + + + + True + False + vertical + + + True + True + in + + + True + True + liststore_data + + + + + + Data Plugins + + + + 0 + + + + + + + + + True + True + 0 + + + + + 2 + + + + + True + False + Data plugins + + + 2 + False + + + + + True + True + 1 + + + + + + + + + + + + + 640 + 480 + False + 3 + 4 + LAview Desktop + + + + True + False + vertical + + + True + False + + + False + True + False + _Template + True + + + True + False + + + gtk-new + False + action_new + True + False + True + True + True + + + + + gtk-open + False + action_open + True + False + True + True + True + + + + + gtk-edit + False + action_edit_template + True + False + True + True + True + + + + + gtk-delete + False + action_delete + True + False + True + True + True + + + + + False + True + False + + + + + gtk-quit + False + True + False + True + True + True + + + + + + + + + + False + True + False + _Document + True + + + True + False + + + gtk-properties + False + action_prepare + True + False + 0.97999999999999998 + True + True + True + + + + + gtk-print + False + action_print + True + False + True + True + True + + + + + gtk-edit + False + action_edit_result + True + False + True + True + True + + + + + + + + + False + True + False + _Application + True + + + True + False + + + gtk-preferences + False + action_preferences + True + False + True + True + True + + + + + + + + + False + True + False + _Help + True + + + True + False + + + gtk-help + False + action_ref + True + False + True + True + True + + + + + gtk-about + False + True + False + True + True + True + + + + + + + + + + False + True + 0 + + + + + True + False + both + + + False + action_new + True + False + Create a new template + True + gtk-new + + + False + True + + + + + False + action_open + True + False + Open a template + True + gtk-open + + + False + True + + + + + False + action_edit_template + True + False + Change selected template + _Template + True + gtk-edit + + + False + True + + + + + False + action_delete + True + False + Delete selected template + True + gtk-delete + + + False + True + + + + + True + False + + + False + False + + + + + False + action_prepare + True + False + Document object preparing + True + gtk-properties + + + False + True + + + + + False + action_print + True + False + View and print the document + True + gtk-print + + + False + True + + + + + False + action_edit_result + True + False + Edit the result document + _Document + True + gtk-edit + + + False + True + + + + + True + False + + + False + False + + + + + False + action_preferences + True + False + Application preferences + True + gtk-preferences + + + False + True + + + + + False + action_ref + True + False + Help and reference + True + gtk-help + + + False + True + + + + + True + False + + + False + False + + + + + True + False + Close the application + True + gtk-quit + + + + False + True + + + + + False + True + 1 + + + + + True + False + True + + + True + False + vertical + + + True + True + 2 + in + + + True + True + liststore_templates + + + + + multiple + + + + + Templates + + + + 0 + + + + + + + + + True + True + 0 + + + + + True + False + 3 + 3 + immediate + True + + + gtk-new + False + action_new + True + True + True + True + True + + + True + True + 0 + + + + + gtk-open + False + action_open + True + True + True + True + True + + + True + True + 1 + + + + + gtk-edit + False + action_edit_template + True + True + True + True + True + + + True + True + 2 + + + + + gtk-delete + False + action_delete + True + True + True + immediate + True + True + + + True + True + 3 + + + + + False + True + 1 + + + + + True + True + 0 + + + + + True + False + vertical + + + True + True + 2 + in + + + True + True + liststore_objects + + + + + + + Document Objects + + + + 0 + + + + + + + + + True + True + 0 + + + + + True + False + 3 + 3 + True + + + gtk-properties + False + action_prepare + True + True + True + True + True + 0.44999998807907104 + True + + + True + True + 0 + + + + + gtk-print + False + action_print + True + True + True + True + True + + + True + True + 1 + + + + + gtk-edit + False + action_edit_result + True + True + True + True + True + + + False + True + 2 + + + + + False + True + 1 + + + + + True + True + 1 + + + + + True + True + 2 + + + + + True + False + vertical + 2 + + + False + True + end + 3 + + + + + + + 640 + 480 + False + dialog + + + False + vertical + 2 + + + False + end + + + gtk-stop + True + True + True + True + True + + + + True + True + 0 + + + + + False + False + 0 + + + + + True + True + in + + + True + True + False + False + False + + + + + True + True + 1 + + + + + + diff --git a/util/backbone b/util/backbone new file mode 160000 index 0000000..11c998a --- /dev/null +++ b/util/backbone @@ -0,0 +1 @@ +Subproject commit 11c998aca2aa1b787286b336e579e5a4e31f471a diff --git a/valadoc_env b/valadoc_env new file mode 100644 index 0000000..0a8c6c7 --- /dev/null +++ b/valadoc_env @@ -0,0 +1,2 @@ +BASEDIR=src config +PKGS=gtk+-3.0 laview-core-0 laview-core-iface-0 gobject-plugin-iface-0 gobject-plugin-loader-0 gmodule-2.0 gee-0.8