klatexformula-4.1.0/000755 000765 000024 00000000000 13660527435 015362 5ustar00philippestaff000000 000000 klatexformula-4.1.0/COPYING.txt000644 000765 000024 00000043131 13660527435 017235 0ustar00philippestaff000000 000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the 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 Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. klatexformula-4.1.0/INSTALL000644 000765 000024 00000000636 13660527435 016420 0ustar00philippestaff000000 000000 The very quick install guide ---------------------------- > mkdir build && cd build build> cmake .. <--- cmake step build> make build> sudo make install Password: The cmake step can be repeated with options to set cache variables, like build> cmake .. -DCMAKE_INSTALL_PREFIX=/usr For detailed up-to-date installation instructions, please see https://klatexformula.sourceforge.io/doc/install klatexformula-4.1.0/CMakeLists.txt000644 000765 000024 00000046001 13660527435 020123 0ustar00philippestaff000000 000000 # #################################### # # CMake project file for klatexformula # # #################################### # # $Id$ # #################################### # cmake_minimum_required(VERSION 3.1) PROJECT(klatexformula) # Set up CMAKE properly set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") if(APPLE) # find HomeBrew Qt5, if present set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "/usr/local/opt/qt5/lib/cmake") endif(APPLE) # Read project version file(READ "VERSION" klf_ver) string(STRIP "${klf_ver}" KLF_VERSION) message(STATUS "KLatexFormula Version ${KLF_VERSION}") option(KLF_WELCOME_MSG_SILENT "Don't display welcome message" OFF) if(NOT KLF_WELCOME_MSG_SILENT) message(STATUS " Welcome to the klatexformula build script. This CMake script will configure the klatexformula ${KLF_VERSION} build process for your system. Some settings will have to be detected. This script should be able to detect the correct settings for most systems. However, you may want to tune and even fine-tune this configuration in order to build and install the compenents you would like, and install them at your preferred locations. Each status message displays a default or detected value for a setting. In capital letters is given the corresponding CMake cache variable name, in case you want to change the setting. With command-line cmake, you can set a variable with: cmake -D= In most cases values are just 'ON' or 'OFF'. In some other cases they are paths. Non-absolute installation paths are understood as relative to CMAKE_INSTALL_PREFIX. But don't worry, most default values should be fine. Unless an error was reported during this script, you can type make and sudo make install to install klatexformula on your system. For more options and help: - look at the stored cache variable documentation (displayed eg. by cmake-gui and ccmake, or directly in the CMakeCache.txt file) - take a look at https://klatexformula.sourceforge.io/doc/install And have a lot of fun! ") message(STATUS "Displayed welcome message (KLF_WELCOME_MSG_SILENT)") else(NOT KLF_WELCOME_MSG_SILENT) message(STATUS "Skipped welcome message (KLF_WELCOME_MSG_SILENT)") endif(NOT KLF_WELCOME_MSG_SILENT) # Extract KLF Version from VERSION file set(klfversion_regex "([0-9]+)\\.([0-9]+)\\.([0-9]+)(.*)") string(REGEX REPLACE "${klfversion_regex}" "\\1" KLF_VERSION_MAJ "${KLF_VERSION}") string(REGEX REPLACE "${klfversion_regex}" "\\2" KLF_VERSION_MIN "${KLF_VERSION}") string(REGEX REPLACE "${klfversion_regex}" "\\3" KLF_VERSION_REL "${KLF_VERSION}") string(REGEX REPLACE "${klfversion_regex}" "\\4" KLF_VERSION_SUFFIX "${KLF_VERSION}") # The version that the libraries will be tagged with set(KLF_LIB_VERSION "${KLF_VERSION_MAJ}") include(KLFUtil) # Warn the user for defined cache variables that are not standard, # i.e. may be a user's typo -- recent CMake does that automatically #include(klfValidOptions) # Set some project settings # ------------------------- message(STATUS "") message(STATUS "[BUILD SETTINGS]") set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build configuration (Debug|Release|RelWithDebInfo)") if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build configuration (Debug|Release|RelWithDebInfo)" FORCE) endif() message(STATUS "CMake build type: ${CMAKE_BUILD_TYPE}") if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") set(klf_debug_dflt 1) else() set(klf_debug_dflt 0) endif() set(KLF_DEBUG "${klf_debug_dflt}" CACHE BOOL "Enable klf debugging messages (boolean)") if(KLF_DEBUG) message(STATUS "Debugging messages in KLF libraries and applciation are enabled (KLF_DEBUG)") else() message(STATUS "Debugging messages in KLF libraries and applciation are disabled (KLF_DEBUG)") endif() # experimental features -- currently no experimental features to enable # #option(KLF_EXPERIMENTAL # "DEVELOPERS ONLY. Enable experimental unstable features (NOT recommended for regular use!)" # off) #mark_as_advanced(KLF_EXPERIMENTAL) #if(KLF_EXPERIMENTAL) # KLFNote("WARNING: Experimental features are unstable and are meant only for developers!! Use at your own risk!!") # message(STATUS "Enabling experimental features (KLF_EXPERIMENTAL)") #endif(KLF_EXPERIMENTAL) set(KLF_EXPERIMENTAL 0) # # Find Qt 5 # find_package(Qt5Core REQUIRED) find_package(Qt5Gui REQUIRED) find_package(Qt5Widgets REQUIRED) find_package(Qt5Xml REQUIRED) get_target_property(Qt5Core_location Qt5::Core LOCATION) get_target_property(Qt5Gui_location Qt5::Gui LOCATION) get_target_property(Qt5Widgets_location Qt5::Widgets LOCATION) get_target_property(Qt5Xml_location Qt5::Xml LOCATION) message(STATUS "Found minimal Qt5 components (use CMAKE_PREFIX_PATH=/path/to/qt/lib/cmake): - ${Qt5Core_location} - ${Qt5Gui_location} - ${Qt5Widgets_location} - ${Qt5Xml_location}") # # Decide which window system to use. This is independent of OS, say, theoretically we # could compile an X11 version on a Mac (though not sure why we'd do it). # # This setting KLF_WS actually defines which additional features are included. You can # use make a fully ws-portable build with KLF_WS=other (disable all extra features). # if (APPLE) set(klf_ws_dflt "mac") elseif(UNIX) set(klf_ws_dflt "x11") elseif(WIN32) set(klf_ws_dflt "win") else() set(klf_ws_dflt "other") endif() set(KLF_WS "${klf_ws_dflt}" CACHE STRING "Which window system to use (mac,x11,win,other) -- used to enable some additional platform-specific features") if(KLF_WS STREQUAL "mac") message(STATUS "Enabling mac-specific features (KLF_WS=x11|mac|win|other)") elseif(KLF_WS STREQUAL "x11") message(STATUS "Enabling X11-specific features (KLF_WS=x11|mac|win|other)") elseif(KLF_WS STREQUAL "win") message(STATUS "Enabling windows-specific features (KLF_WS=x11|mac|win|other)") elseif(KLF_WS STREQUAL "other") message(STATUS "Not enabling any window system specific feature (KLF_WS=x11|mac|win|other)") else() message(FATAL_ERROR "Invalid setting for KLF_WS=${KLF_WS}. Please Select one of \"mac\", \"win\", \"x11\" or \"other\".") endif() # # by default, libraries are dynamic unless overridden by user options # set(klf_default_libraries_static 0) # # KLFTOOLS # # must be set to ON if you want to build anything at all. option(KLF_BUILD_TOOLS "Build klatexformula tools library (klftools). Necessary for everything else." 1) option(KLF_LIBKLFTOOLS_STATIC "Build a static klftools library" ${klf_default_libraries_static}) if(KLF_BUILD_TOOLS) message(STATUS "Will build the klftools library (KLF_BUILD_TOOLS)") if(KLF_LIBKLFTOOLS_STATIC) message(STATUS "Building a static KLatexFormula tools library (klftools) (KLF_LIBKLFTOOLS_STATIC)") else() message(STATUS "Building a shared KLatexFormula tools library (klftools) (KLF_LIBKLFTOOLS_STATIC)") endif() else() # message(FATAL_ERROR "There is nothing to build. You must set at least KLF_BUILD_TOOLS.") endif() if(KLF_LIBKLFTOOLS_STATIC) set(default_KLF_BUILD_TOOLSDESPLUGIN FALSE) else() set(default_KLF_BUILD_TOOLSDESPLUGIN TRUE) endif() set(KLF_BUILD_TOOLSDESPLUGIN "${default_KLF_BUILD_TOOLSDESPLUGIN}" CACHE BOOL "Build Qt Designer Plugin for klftools library widgets") if(KLF_BUILD_TOOLSDESPLUGIN) if(KLF_LIBKLFTOOLS_STATIC) message(FATAL_ERROR "Cannot build klftools designer plugin library with static klftools library (set KLF_BUILD_TOOLSDESPLUGIN=0 or KLF_LIBKLFTOOLS_STATIC=0)") endif() message(STATUS "Will build the klftools designer plugin library (KLF_BUILD_TOOLSDESPLUGIN)") else() message(STATUS "Will not build the klftools designer plugin library (KLF_BUILD_TOOLSDESPLUGIN)") endif() # # KLFBACKEND # option(KLF_BUILD_BACKEND "Build klatexformula backend library (klfbackend)" 1) option(KLF_LIBKLFBACKEND_STATIC "Compile static libklfbackend backend library instead of shared." ${klf_default_libraries_static}) if(KLF_BUILD_BACKEND) if (NOT KLF_BUILD_TOOLS) message(FATAL_ERROR "Cannot build klfbackend without klftools (set KLF_BUILD_BACKEND=0 or KLF_BUILD_TOOLS=1)") endif() message(STATUS "Will build the klfbackend library (KLF_BUILD_BACKEND)") if(KLF_LIBKLFBACKEND_STATIC) message(STATUS "Building a static KLFBackend library (KLF_LIBKLFBACKEND_STATIC)") else() message(STATUS "Building a shared KLFBackend library (KLF_LIBKLFBACKEND_STATIC)") endif() else() message(STATUS "Will not build the klfbackend library (KLF_BUILD_BACKEND)") endif() option(KLF_BUILD_BACKEND_AUTO "Build klatexformula autonomous backend library (klfbackend_auto)" 1) option(KLF_LIBKLFBACKEND_AUTO_STATIC "Compile static libklfbackend_auto backend library instead of shared." TRUE) if(KLF_BUILD_BACKEND_AUTO) message(STATUS "Will build autonomous klfbackend_auto without klftools dependency (KLF_BUILD_BACKEND_AUTO)") if(KLF_LIBKLFBACKEND_AUTO_STATIC) message(STATUS "Building a static klfbackend_auto autonomous library (KLF_LIBKLFBACKEND_AUTO_STATIC)") else() message(STATUS "Building a shared klfbackend_auto autonomous library (KLF_LIBKLFBACKEND_AUTO_STATIC)") endif() else() message(STATUS "Will not build autonomous klfbackend_auto without klftools dependency (KLF_BUILD_BACKEND_AUTO)") endif() # Extra search paths if(KLF_BUILD_BACKEND OR KLF_BUILD_BACKEND_AUTO) set(KLF_EXTRA_SEARCH_PATHS "" CACHE STRING "Extra paths in which klfbackend (and klatexformula) will search for latex/dvips/etc. executables. Separate paths with ';' on all platforms") message(STATUS "Will prepend \"${KLF_EXTRA_SEARCH_PATHS}\" to klfbackend/klatexformula's latex/dvips/gs search paths (KLF_EXTRA_SEARCH_PATHS)") endif() option(KLF_BUILD_GUI "Build klatexformula GUI application (klatexformula) [requires klftools and klfbackend]" 1) if(KLF_BUILD_GUI) if (NOT KLF_BUILD_TOOLS OR NOT KLF_BUILD_BACKEND) message(FATAL_ERROR "Cannot build the klatexformula GUI main application without klftools and klfbackend (set KLF_BUILD_BACKEND=1 and KLF_BUILD_TOOLS=1, or set KLF_BUILD_GUI=0)") endif() message(STATUS "Will build the main klatexformula program (GUI) (KLF_BUILD_GUI)") else() message(STATUS "Will not build the main klatexformula program (GUI) (KLF_BUILD_GUI)") endif() if(APPLE) # These settings override on Mac OS X if(CMAKE_OSX_ARCHITECTURES) set(display_CMAKE_OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}") else(CMAKE_OSX_ARCHITECTURES) set(display_CMAKE_OSX_ARCHITECTURES "(default)") endif(CMAKE_OSX_ARCHITECTURES) message(STATUS "Compiling for Mac OS X Architectures: ${display_CMAKE_OSX_ARCHITECTURES} (CMAKE_OSX_ARCHITECTURES)") if(KLF_TARGET_ARCH_64 OR klf_changed_KLF_TARGET_ARCH_64) KLFNote("Warning: KLF_TARGET_ARCH_64 ignored on Mac OS X. Use CMAKE_OSX_ARCHITECTURES instead.") endif(KLF_TARGET_ARCH_64 OR klf_changed_KLF_TARGET_ARCH_64) endif() # Mac OS X: building frameworks + bundles ? if(APPLE) option(KLF_MACOSX_BUNDLES "On Mac OS X: Build Bundles and Frameworks instead of UNIX-Style binaries" ON) option(KLF_MACOSX_BUNDLE_EXTRAS "[Mac OS X Bundles] Copy dependent libraries & resources into bundle, ready to be copied anywhere else and on other systems" ON) else() # no need to put these in cache, it's irrelevant # # However let's keep the KLF_MACOSX_BUNDLES setting independent from # APPLE. There may be systems on which we can create bundles, that # are not APPLE ??? not sure, but keep the possibility open. KLFSetIfNotDefined(KLF_MACOSX_BUNDLES OFF) KLFSetIfNotDefined(KLF_MACOSX_BUNDLE_EXTRAS OFF) endif() if(KLF_MACOSX_BUNDLES) if (KLF_MACOSX_BUNDLE_EXTRAS) message(STATUS "Will package library and framework dependencies into klatexformula app bundle (KLF_MACOSX_BUNDLE_EXTRAS)") else() message(STATUS "Will NOT package library and framework dependencies into klatexformula app bundle (KLF_MACOSX_BUNDLE_EXTRAS)") endif() set(default_KLF_BUNDLE_QT_PLUGINS Qt5::QCocoaIntegrationPlugin Qt5::QGifPlugin #Qt5::QDDSPlugin Qt5::QGifPlugin Qt5::QICNSPlugin Qt5::QICOPlugin Qt5::QJpegPlugin Qt5::QMacJp2Plugin #Qt5::QMinimalIntegrationPlugin #Qt5::QOffscreenIntegrationPlugin Qt5::QTgaPlugin Qt5::QTiffPlugin #Qt5::QTuioTouchPlugin #Qt5::QVirtualKeyboardPlugin Qt5::QWbmpPlugin Qt5::QWebpPlugin Qt5::QSQLiteDriverPlugin Qt5::QSvgPlugin Qt5::QSvgIconPlugin ) set(KLF_BUNDLE_QT_PLUGINS "${default_KLF_BUNDLE_QT_PLUGINS}" CACHE STRING "Qt plugin list (imported targets e.g. Qt5::QJpegPlugin) to package into app bundle") string(REGEX REPLACE ";" " " klf_display_bundle_qt_plugins "${KLF_BUNDLE_QT_PLUGINS}") message(STATUS "Will Package Qt Plugins in bundle (KLF_BUNDLE_QT_PLUGINS): ${klf_display_bundle_qt_plugins}") if(NOT "${KLF_BUNDLE_QT_PLUGINS}" STREQUAL "${default_KLF_BUNDLE_QT_PLUGINS}") KLFNote("You are bundling a list of qt plugins which differs from the default list. In case the default list has changed and want to restore the defaults, run \"cmake .. -UKLF_BUNDLE_QT_PLUGINS\".") endif() endif(KLF_MACOSX_BUNDLES) # Build DBUS support ? if(UNIX AND NOT APPLE) set(klf_use_dbus_dflt 1) else() set(klf_use_dbus_dflt 0) endif() option(KLF_USE_DBUS "Compiles D-Bus support into KLatexFormula GUI" ${klf_use_dbus_dflt}) if(KLF_USE_DBUS) message(STATUS "Building with D-BUS support (KLF_USE_DBUS)") else() message(STATUS "Building without D-BUS support (KLF_USE_DBUS)") endif() # DEVELOPER OPTION to test QAbstractItemModel-based models with ModelTest option(KLF_DEBUG_USE_MODELTEST "DEVELOPERS ONLY. Uses ModelTest (Qt's Labs) to test QAbstractItemModel-based models. VERY slow." FALSE) mark_as_advanced(KLF_DEBUG_USE_MODELTEST) if(KLF_DEBUG_USE_MODELTEST) message(STATUS "Will compile with QtLab's ModelTest for KLFLibModel testing (KLF_DEBUG_USE_MODELTEST)") endif(KLF_DEBUG_USE_MODELTEST) # Use system font rather than CMU font if available #KLFDeclareCacheVarOptionFollowComplexN(specificoption cachetype cachestring updatenotice calcoptvalue depvarlist) option(KLF_NO_CMU_FONT "Tells klatexformula to use system font instead of Computer Modern font" FALSE ) if(KLF_NO_CMU_FONT) message(STATUS "Will use system font instead of CMU font (KLF_NO_CMU_FONT)") else() message(STATUS "Will attempt to use Computer Modern unicode font (KLF_NO_CMU_FONT)") endif() # Include some extra data files/fonts into KLatexFormula if(KLF_NO_CMU_FONT) set(klf_def_incl_fonts "") elseif(KLF_WS STREQUAL "mac") set(klf_def_incl_fonts "data/cmunbbx.otf;data/cmunbmo.otf;data/cmunbmr.otf;data/cmunbso.otf;data/cmunbsr.otf;data/cmunbxo.otf") # CMU Bright else() set(klf_def_incl_fonts "data/cmunsi.otf;data/cmunso.otf;data/cmunss.otf;data/cmunsx.otf") # CMU Sans Serif endif() set(KLF_INCLUDE_FONTS "${klf_def_incl_fonts}" CACHE STRING "Include some extra fonts into KLF's internal resources (absolute or relative to src/)") if(KLF_INCLUDE_FONTS) string(REPLACE ";" "\n " klf_include_fonts_msg_list "${KLF_INCLUDE_FONTS}") message(STATUS "Will include fonts into klatexformula's resources (KLF_INCLUDE_FONTS):\n ${klf_include_fonts_msg_list}") else() message(STATUS "Will not include fonts into klatexformula's resources (KLF_INCLUDE_FONTS)") endif() # Use Sparkle framework under Mac OS X? if(KLF_WS STREQUAL "mac") option(KLF_USE_SPARKLE "Use Sparkle Framework for auto-updates on Mac OS X" OFF) # can only use if we are building a bundle if (NOT KLF_MACOSX_BUNDLES) message(FATAL_ERROR "Can only build with Sparkle framework when we are building a Mac OS X App bundle (use KLF_MACOSX_BUNDLES=1)") endif() if(KLF_USE_SPARKLE) set(KLF_SPARKLE_FEED_URL "http://klatexformula.sourceforge.net/sparklefeed.xml" CACHE STRING "URL for Sparkle to check for updates") set(KLF_SPARKLE_FRAMEWORK "Sparkle.framework" CACHE STRING "Path to the Sparkle Framework") set(KLF_SPARKLE_DSA_PUBKEY "" CACHE STRING "Path to the DSA public key for signing packages.") if(NOT EXISTS "${KLF_SPARKLE_FRAMEWORK}") message(FATAL_ERROR "Please specify the path to the Sparkle Framework in KLF_SPARKLE_FRAMEWORK, or disable the Sparkle framework with KLF_USE_SPARKLE=off.") endif() message(STATUS "Using sparkle framework with update URL ${KLF_SPARKLE_FEED_URL}") endif() endif() # Use WinSparkle framework under Windows? if(WIN32) option(KLF_USE_WINSPARKLE "Use WinSparkle for auto-updates on MS Windows" OFF) if(KLF_USE_WINSPARKLE) set(KLF_WINSPARKLE_FEED_URL "http://klatexformula.sourceforge.net/sparklefeed.xml" CACHE STRING "URL for WinSparkle to check for updates") set(KLF_WINSPARKLE_DIR "" CACHE STRING "Path to the WinSparkle Directory (with .h files & WinSparkle.dll file)") if(NOT EXISTS "${KLF_WINSPARKLE_DIR}") message(FATAL_ERROR "Please specify the path to the WinSparkle directory in KLF_WINSPARKLE_DIR, or disable the Sparkle framework with KLF_USE_WINSPARKLE=off.") endif() message(STATUS "Using WinSparkle with update URL ${KLF_WINSPARKLE_FEED_URL}") endif() endif() # Manpage generation from --help and --version help text if(NOT KLF_MACOSX_BUNDLES) if(NOT DEFINED HELP2MAN OR HELP2MAN STREQUAL "") find_program(HELP2MAN "help2man") endif() endif() if(HELP2MAN) message(STATUS "Manpage will be generated from --help text with help2man (HELP2MAN=OFF or /path/to/help2man)") elseif(NOT KLF_MACOSX_BUNDLES AND NOT WIN32 AND HELP2MAN STREQUAL "") KLFNote("help2man was not found. Manpage will not be generated. set explicitely HELP2MAN to /path/.../to/help2man if needed.") endif() if(NOT HELP2MAN) message(STATUS "Manpage will not be generated with help2man (HELP2MAN=OFF or /path/to/help2man)") endif() if(NOT DEFINED GZIP OR GZIP STREQUAL "") find_program(GZIP "gzip") endif() if(HELP2MAN) if(GZIP) message(STATUS "Manpage will be gzip'ed (GZIP=OFF or /path/to/gzip)") else() message(STATUS "Manpage will not be gzip'ed (GZIP=OFF or /path/to/gzip)") endif() endif(HELP2MAN) # Install Paths # ------------- message(STATUS "") message(STATUS "[INSTALLATION SETTINGS]") include(klfinstallpaths) # CPack # ----- include(klfcpack) # Some Basic Compilation Definitions # ---------------------------------- # Preprocessor instructions add_definitions(-DKLF_VERSION_STRING="${KLF_VERSION}" -DKLF_VERSION_MAJ=${KLF_VERSION_MAJ} -DKLF_VERSION_MIN=${KLF_VERSION_MIN} -DKLF_VERSION_REL=${KLF_VERSION_REL} -DKLF_SRC_BUILD) # Add warning flags for all build configurations set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wextra") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -Wall -Wextra") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -Wextra") if(KLF_DEBUG) add_definitions(-DKLF_DEBUG) else() # Instruct Qt to ignore qDebug() for RELEASE build configuration (if not KLF_DEBUG) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DQT_NO_DEBUG_OUTPUT") endif() if(KLF_EXPERIMENTAL) add_definitions(-DKLF_EXPERIMENTAL) endif() # Main subdirectory with all sources # ---------------------------------- add_subdirectory(src) message(STATUS "") message(STATUS "[ADDITIONAL SETTINGS]") # Doxygen # ------- include(klfdoxygen) message(STATUS "") message(STATUS "[DONE]") KLFNotifyNotices() message(STATUS "") klatexformula-4.1.0/cmake/000755 000765 000024 00000000000 13660527435 016442 5ustar00philippestaff000000 000000 klatexformula-4.1.0/AUTHORS000644 000765 000024 00000000353 13660527435 016433 0ustar00philippestaff000000 000000 Author: Philippe Faist With contributions from: - Pavel Fric, http://fripohled.blogspot.com/ -- Czech translation - Yuri Chornoivan, https://fedoraproject.org/wiki/User:Yurchor -- Ukranian translation klatexformula-4.1.0/Doxyfile.klfbackend.in000644 000765 000024 00000220410 13660527435 021557 0ustar00philippestaff000000 000000 # Doxyfile 1.7.3 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = "KLFBackend Library" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @KLF_VERSION@ # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = @KLF_APIDOC_DIR@@KLF_DOXYGEN_SF@/klfbackend # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = YES # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = NO # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this # tag. The format is ext=language, where ext is a file extension, and language # is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penalty. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will roughly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = YES # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = YES # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. The create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = src/klfbackend # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ *.c++ \ *.d \ *.java \ *.ii \ *.ixx \ *.ipp \ *.i++ \ *.inl \ *.h \ *.hh \ *.hxx \ *.hpp \ *.h++ \ *.idl \ *.odl \ *.cs \ *.php \ *.php3 \ *.inc \ *.m \ *.mm \ *.dox \ *.py \ *.f90 \ *.f \ *.vhd \ *.vhdl \ *.C \ *.CC \ *.C++ \ *.II \ *.I++ \ *.H \ *.HH \ *.H++ \ *.CS \ *.PHP \ *.PHP3 \ *.M \ *.MM \ *.PY \ *.F90 \ *.F \ *.VHD \ *.VHDL # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = */ui_*.h \ */qrc_*.cpp \ */moc_*.cpp \ *_p.h # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = * # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 2 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = KLF \ klf #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = @CMAKE_CURRENT_SOURCE_DIR@/apidoc/dox_header.html # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = @CMAKE_CURRENT_SOURCE_DIR@/apidoc/dox_footer@KLF_DOXYGEN_SF@.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = @CMAKE_CURRENT_SOURCE_DIR@/apidoc/dox_style.css # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the stylesheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 80 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [0,1..20]) # that doxygen will group on one line in the generated HTML documentation. # Note that a value of 0 will completely suppress the enum values from # appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = YES # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the # mathjax.org site, so you can quickly see the result without installing # MathJax, but it is strongly recommended to install a local copy of MathJax # before deployment. MATHJAX_RELPATH = http://www.mathjax.org/mathjax # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client # using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server # based approach is that it scales better to large projects and allows # full text search. The disadvantages are that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = YES # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = apidoc/qtcore.tags=http://qt-project.org/doc/qt-5/ \ apidoc/qtgui.tags=http://qt-project.org/doc/qt-5/ \ apidoc/qtxml.tags=http://qt-project.org/doc/qt-5/ \ apidoc/qtsql.tags=http://qt-project.org/doc/qt-5/ \ @KLF_APIDOC_DIR@/klftools.tag=../../klftools/html # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = @KLF_APIDOC_DIR@/klfbackend.tag # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = NO # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will write a font called Helvetica to the output # directory and reference it in all dot files that doxygen generates. # When you want a differently looking font you can specify the font name # using DOT_FONTNAME. You need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = Arial # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, svg, gif or svg. # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 1000 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = YES # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES klatexformula-4.1.0/descr_short.txt000644 000765 000024 00000000403 13660527435 020437 0ustar00philippestaff000000 000000 KLatexFormula is an easy-to-use graphical application for generating images from LaTeX equations. KLatexFormula is an easy-to-use graphical application for generating images (that you can drag and drop, copy and paste or save to disk) from LaTeX equations. klatexformula-4.1.0/apidoc/000755 000765 000024 00000000000 13660527435 016621 5ustar00philippestaff000000 000000 klatexformula-4.1.0/Doxyfile.klftools.in000644 000765 000024 00000220407 13660527435 021336 0ustar00philippestaff000000 000000 # Doxyfile 1.7.3 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = "KLFTools Library" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @KLF_VERSION@ # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = @KLF_APIDOC_DIR@@KLF_DOXYGEN_SF@/klftools # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = YES # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = NO # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this # tag. The format is ext=language, where ext is a file extension, and language # is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penalty. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will roughly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = YES # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = YES # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. The create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = src/klftools/ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ *.c++ \ *.d \ *.java \ *.ii \ *.ixx \ *.ipp \ *.i++ \ *.inl \ *.h \ *.hh \ *.hxx \ *.hpp \ *.h++ \ *.idl \ *.odl \ *.cs \ *.php \ *.php3 \ *.inc \ *.m \ *.mm \ *.dox \ *.py \ *.f90 \ *.f \ *.vhd \ *.vhdl \ *.C \ *.CC \ *.C++ \ *.II \ *.I++ \ *.H \ *.HH \ *.H++ \ *.CS \ *.PHP \ *.PHP3 \ *.M \ *.MM \ *.PY \ *.F90 \ *.F \ *.VHD \ *.VHDL # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = src/klftools/klftools_desplugin.h \ src/klftools/klftools_desplugin.cpp # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = */ui_*.h \ */qrc_*.cpp \ */moc_*.cpp \ *_p.h # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = Ui # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = * # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 3 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = KLF #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = @CMAKE_CURRENT_SOURCE_DIR@/apidoc/dox_header.html # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = @CMAKE_CURRENT_SOURCE_DIR@/apidoc/dox_footer@KLF_DOXYGEN_SF@.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = @CMAKE_CURRENT_SOURCE_DIR@/apidoc/dox_style.css # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the stylesheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 80 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [0,1..20]) # that doxygen will group on one line in the generated HTML documentation. # Note that a value of 0 will completely suppress the enum values from # appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = YES # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the # mathjax.org site, so you can quickly see the result without installing # MathJax, but it is strongly recommended to install a local copy of MathJax # before deployment. MATHJAX_RELPATH = http://www.mathjax.org/mathjax # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client # using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server # based approach is that it scales better to large projects and allows # full text search. The disadvantages are that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = YES # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = apidoc/qtcore.tags=http://qt-project.org/doc/qt-5/ \ apidoc/qtgui.tags=http://qt-project.org/doc/qt-5/ \ apidoc/qtxml.tags=http://qt-project.org/doc/qt-5/ \ apidoc/qtsql.tags=http://qt-project.org/doc/qt-5/ # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = @KLF_APIDOC_DIR@/klftools.tag # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will write a font called Helvetica to the output # directory and reference it in all dot files that doxygen generates. # When you want a differently looking font you can specify the font name # using DOT_FONTNAME. You need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = Arial # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, svg, gif or svg. # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 1000 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = YES # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES klatexformula-4.1.0/descr_long.txt000644 000765 000024 00000000672 13660527435 020247 0ustar00philippestaff000000 000000 KLatexFormula is an easy-to-use graphical user interface for generating images from LaTeX equations. These images can be dragged and dropped or copied and pasted into external applications (presentations, text documents, graphics...), or can be saved to disk in a variety of formats (PNG, JPG, BMP, EPS, PDF, etc.). In addition to the graphical user interface, a command-line interface and a C++ library is provided to perform the same job. klatexformula-4.1.0/README000644 000765 000024 00000003576 13660527435 016255 0ustar00philippestaff000000 000000 --------------------------- KLatexFormula - README file --------------------------- KLatexFormula is an easy-to-use graphical application for generating images (that you can drag and drop, copy and paste or save to disk) from LaTeX equations. DESCRIPTION ----------- This application provides an easy-to-use graphical user interface for generating images from LaTeX equations. These images can be dragged and dropped or copied and pasted into external applications (presentations, text documents, graphics...), or can be saved to disk in a variety of formats (PNG, JPG, BMP, EPS, PDF, etc.). In addition to the graphical user interface, a command-line interface and a C++ library is provided to perform the same job. INSTALLATION ------------ Installation instructions can be found at https://klatexformula.sourceforge.io/doc/install HELP & DOCUMENTATION -------------------- Documentation can be found at https://klatexformula.sourceforge.io/doc/ REPORTING BUGS AND PROVIDING FEEDBACK ------------------------------------- Please report bugs and wishes at https://sourceforge.net/p/klatexformula/bugs/ LEGAL INFORMATION ----------------- KLatexFormula is licensed under the GPL license (version 2 or at your option any later version), a copy of which is provided in the COPYING file. * This source tarball contains fonts (Computer Modern Unicode Fonts in otf format) provided by Andrey V. Panov. The original copyright notice is provided in the file CMUFONTS_COPYRIGHT. * This source tarball contains code from Qt/Trolltech: - src/modeltest.h - src/modeltest.cpp The original copyright notice is included in the first lines of those files. * This source tarball contains code from Qt/Nokia slightly modified by myself: - src/klftools/qtcolortriangle.h - src/klftools/qtcolortriangle.cpp The original copyright notice is included in the first lines of those files. klatexformula-4.1.0/CMUFONTS_COPYING000644 000765 000024 00000004410 13660527435 017732 0ustar00philippestaff000000 000000 This klatexformula source tarball contains fonts (Computer Modern Unicode Fonts in otf format) provided by Andrey V. Panov. Here is the original copyright notice: X11 License ----------- Andrey V. Panov (C) 2005 All rights reserved. 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, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, provided that the above copyright notice(s) and this permission notice appear in all copies of the Software and that both the above copyright notice(s) and this permission notice appear in supporting documentation. 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization of the copyright holder. -------------------------------------------------------------------------------- As a special exception, if you create a document which uses these fonts, and embed these fonts or unaltered portions of these fonts into the document, these fonts does not by itself cause the resulting document to be covered by the X11 License. This exception does not however invalidate any other reasons why the document might be covered by the X11 License. If you modify these fonts, you may extend this exception to your version of the fonts, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. klatexformula-4.1.0/.gitignore000644 000765 000024 00000000257 13660527435 017356 0ustar00philippestaff000000 000000 # # standard ignores # *~ build/ build-* # # Ignores imported from svn:ignore properties # # /src/i18n/ src/i18n/temp_xmltr_klf_fr.ts.cxx src/i18n/temp_tr_pro_klf_fr.ts.pro klatexformula-4.1.0/VERSION000644 000765 000024 00000000006 13660527435 016426 0ustar00philippestaff000000 000000 4.1.0 klatexformula-4.1.0/templates/000755 000765 000024 00000000000 13660527435 017360 5ustar00philippestaff000000 000000 klatexformula-4.1.0/src/000755 000765 000024 00000000000 13660527435 016151 5ustar00philippestaff000000 000000 klatexformula-4.1.0/extras/000755 000765 000024 00000000000 13660527435 016670 5ustar00philippestaff000000 000000 klatexformula-4.1.0/extras/KLFOpenOfficeorg/000755 000765 000024 00000000000 13660527435 021752 5ustar00philippestaff000000 000000 klatexformula-4.1.0/extras/emacs/000755 000765 000024 00000000000 13660527435 017760 5ustar00philippestaff000000 000000 klatexformula-4.1.0/extras/emacs/klfemacs.el000644 000765 000024 00000002104 13660527435 022064 0ustar00philippestaff000000 000000 ;; This file contains lisp definitions for klatexformula integration into (X)Emacs. ;; Typing Ctrl-C K will launch klatexformula with the current selected region. ;; INSTALLATION INSTRUCTIONS ;; Install this file: ;; - either into your ~/.xemacs/ or to ~/.klfemacs.el or ~/emacs-definitions/klfemacs.el or whatever name you want ;; - or into the global /usr/share/emacs/site-lisp or any other entry in your EMACSLOADPATH or load-path ;; Then include this file into your ~/.xemacs/custom.el or ~/.emacs: ;; - either directly with absolute location: ;; (load "~/.xemacs/klfemacs.el" t t) ;; - or referencing it using load-path search: ;; (load "klfemacs.el" t t) ;; ;; Alternatively, you may just copy and paste the code below directly into your ~/.xemacs/custom.el or ~/.emacs ;; or ~/.gnu-emacs-custom ;; (defun klf-region-run () "Run KLatexFormula" (interactive) (start-process "klatexformula" "*KLatexFormula*" "klatexformula" "--daemonize" "-I" "--latexinput" (buffer-substring (region-beginning) (region-end))) ) (global-set-key [(control c) (k)] 'klf-region-run) klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/000755 000765 000024 00000000000 13660527435 023613 5ustar00philippestaff000000 000000 klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOoSrc.odt000644 000765 000024 00000051743 13660527435 024175 0ustar00philippestaff000000 000000 PKv}>^2 ''mimetypeapplication/vnd.oasis.opendocument.textPKv}> Dialogs/dialog-lc.xmln0D wd\*MP9nC.D)U=V;3o'})[kC HMjCE,YVvrZl U`1RvSV+0$x}noxw8A4b~)0 @g9>zC4A3>QHT*7'H +Ol!Z^qnxWy PKv}>!RDialogs/Standard/dialog-lb.xml]A@ +fsD¶qnM~Z^\߻Vup(E\iL^},?"-χ\jX SN_m`XE]7EbYI{ Z{dLq^Xwk6ښqoI6j:v&V䡾Dialogs/KLFOOo/dialog-lb.xml] 0>EܻI*hD1clZh%ooj2t+q'J6 ui. ` YoO2;V*Vפp\6KDِEQ Y*>:V"W{GklheW%p rH.a153m-)ͦ BUC{ՍeO'u PKv}> content.xmlYo6~_AhJhEd-Z+MR2H*HJ[l;}wHiÕ&1I2,ǯ׋.UqT`DI UTi9Wp3`fn\LZ>z}cb-رW={p_j\UvXHj_=Sc7Fę%*Z[[Ӵ뤞%J"Ҏ0peGQ23NIb fX~ۧ$b`jq__خj*.rؽTat__)Qu az_ṇOk-=89 'X.84MR@εi.f@aq6tכd KceF" F2լTvLִ㶶NBsMQ(ЙawpzP׸vt&).,\#ąAsrޟ،3B3r:Y^ 0OW!d'pn5مD-I|bG V`BaS74K!ZoѰM-d63LXLfqa³Uܖ,l3 .WT# О LBza2- %?=3N2|*,i Sc8`v}ص1v={Ʋtu\YՏWñV `3ŚFafӖC{csLAx&h/X0<p&6d|س$N;Ӂρ<۶fi J'?lEL} Ui[jn) vqݮӆ;]uRg=#ޓdVIjοq,Ĺ, {$Vo݈5:yp5;Օ^o$Jvj:xh+E݃pq1ϊݑp%M)6V\XDp=_q|e{ye]ɧ}8kePY΋߮17Y%0AL2]s;ml'LI_D^wUí5CeL;ȨJk \ӼXg]Pi&7|"2GM1J,08!cIj-Fp0Pn}!.{?kϜP[،@5k411ddUqW:d*LP IGmT{xɢ5@B+E%QwWW |$1 hgcR~6%rE5:Tp8<]ATN=g!yMzhO4s? R6Y[Cet>24|vM6+gkHgH2ŒqeB8 DK965f7o,$%!_ yD[JCQ4JЏ8ιuӁ-PKWm-jPKv}>O manifest.rdfAN0E=i tA5I#OqH{{L  ޟq?={:t%OŎ3 ֝kK>&jSQ#iG*J~ aT<9[H<)H>'0V8JS]oWTj4$PSG -LGM 0ؠf{#S(9-PVT4`]z_=K{YX'Mڇ[.Dg_?z$,-ҾU-`jPKv}>!RBasic/Standard/script-lb.xml]A@ +fsD¶qnM~Z^\߻Vup(E\iL^},?"-χ\jX SN_m`XE]7EbYI{ Z{dLq^Xwk6ښqoI6j:v&V Basic/script-lc.xmln0D wd\*MP9nC.D)U=V;3o'})[kC HMjCE,YVvrZl U`1RvSV+0$x}noxw8A4b~)0 @g9>zC4A3>QHT*7'H +Ol!Z^qnxWy PKv}> -Basic/KLFOOo/KLFOOoMain.xmlZr<Be@Hڴ~ mؐ417rm9@_hclϑ,_IL#\t.:¯\rKfnTj%B]Y;m.//K)~ LYCuIiZxL&I5OE639u9jsV"%\U,&rQqW Y~PժDr9mޟtvjn<44092,9?#PB>pLp}pL[lI u.'̟At("T, ^ސ wX]sϡaґ0qHr$@q6o(B+]ri }j.բTqb9+ 64@;c.չ ~զÜ\3ǡ~bWeF CMԺ\0ev Ό[J\Ɖh3VBgisaڭ?AiG ;L0F bAjAy9edsY ŵ s~AIK߶ ܝf@7qu7ʁbDAj 0k3Fl)( ]p g ~ԑ<18ӫ`֪ZtY+zP|%%Y/_|F&;(k3`Lmѳ&ZA&Ǩ cbv7H|!17j0o7FHu2\I{$OYgs1x1?Txv,wQj&'2/D4׿z%]tlL5bGZ{s-.Qzd;3hƆBdCϥYW&T}+=;Geϧ| r76Na)ܖdj23Nu\-ig`'](P@a0pͱ#G9뭏A1dc0?76(6`A67| BҭH}]_)r=6=.-Ő4_w 9, ʴ׉!] ^pRcc::}lsc:_ˑ$+,L7KSzHӭUΔNrc7gxvKgv_8'>֎ R[s:BE-lKKj*H{QB!1&Sm4}X+HMHn3) 4)(~*FTRb+7*fŹbJYq _P-Jh,[S3ctr-}mӕN\IWhEcSޝW$ܶ0UH]DB2]5!{xWSrnrzR2)ٹܵ8w"mcZ!SʐgdlҧkevRU"&S7{v_o ]uh ug76gmNUUro);k5ZWqݶ |AR?juqtWԩ=r*95THn͖tޟ ?]\~xclZt2ٟo˼/~rV?8|˿=Fy pj0K QÜBC2^aB% FNL@FzPEļŵ{ēLē,&?{"tDp4U& b 6^# :Y>HPaԡ}J>9Ɲ#=j՝b]tqq ,!?X䥴Y _5 ,,ˇ ̦eZ[ G PSSFͷ8s(Xx=|T\OStZB<|CJ`a@aɔ =p/2py`!X6zii並{S #b w7GOTWn[Dc$Q/&qV;Ot`#k1U?D&pt2Ȧ L+*h7iYLzPG;S1 BxXKڑDP=eTiS[OaڤF0KPy]ͼPKv}>$]Basic/KLFOOo/script-lb.xmlmOMo0 +2ߩ&D4 4 aи,RWI_*g?YE>v styles.xmlZۏ?ʪ}3!0VUGJ2&qd;?81@vf0}}v ʊU'1KhY)2aqB"!#.WAŋ%Âes"2^Vhr/)3 ̮${9TXp˚ٕN8 +^OPPPKz>ŗU\a]z6f|F"++i$IF1F(9xu5სEU63b&b>874qxgW6ryߺ\P[r4 +k]U@!4"{ͩ$a/8[Y 8٩4\MWcIɸlI7(@gږVYy)e$;J (?/BԦ3GhH8(:f\J  F]ktB+5Z/LCA2dI:I:'( %$ħ _?kr(ɒ x-{N*L5`tdBɠ )k9K/XJ*c(Tc^OP^Ls ɝ :G4Nµ-8dM fl$5a_z7f dLHY͍G-F%BB`)8a5H_q# !t + Qh8 .q7z`g> @Lr&.řp_b5V.R$SF hBaYրc |i)(TXGr}HZfםubJ2]}6JPc1>I^AOHЯi4-pz$fU!9E "@$NZt&"X-cBd-XcH)Kq vJ՞,#{ҖQҴ٣"Rym(9mzEDN` A$@N L*bY5aC )P(BǮrӷ@yE9Ys,TVm6_NRmM>nEN3MSY J.v7y̡w͸m!u2\ o58OIm~!DmܪSk]&JJ0Oa×a!=3 JpTs:h/LߕBˠvO'YruCJ>=LJuԚ'ib\g5>kmSr{Bk Cm uUS{փ)XM>. [1ޞ8}fMӱ( P7޴Ҳw{ >$b<3z0~cp gwcƏ~oÝaԃ[`xg?`?~0^`c8"n;#< @<<}#$I"(YtSq}?j 9IyqR/:͠{+cn'ԃgWQ!)>A^!y3{bު-yh`PmhHMmy{WO곖Y)@{t\Qa:Д&ꛮy{nУr#z'h$b$oIS0>ϟO 9Q#g.~|D9޷S Ug'g|i{p<8҄$PiwԼl~}kKz?Bw๢.s!X:Zk͠tYNԇOu?PK+A+PKv}>meta.xml 2010-08-12T13:47:282011-04-03T17:43:44PT2H38M31S75LibreOffice/3.3$Unix LibreOffice_project/330m19$Build-8PKv}>)*Thumbnails/thumbnail.pngPNG  IHDRg?IDATxye+Ǝ E dHeNe5-:͔&9cj3cd!"!RQ \ +763;<{w}8<};63cG.srqI9Ƹc\R1.)cK1%rqI9Ƹc\R1.)cK1%r7I:tA)6R_ErL7I͜9o_޲e-2};㩧:sCTVV'O?_?9QMVT&M֭۵^ܷo߯K/t7xc6m⯝;wN$B?O.]ڴiS*rw>VTI]w5q_f\)hu@I /l߾m:vK{Eu!Ѧs9rH'?Iܯ~& \sׯݻ'}Qt6l0\}衇 0x3f=9vڵX=gqWsBVԧ-aÆng?Yx]vW7lp[O,^YfC ٺu+z?#7|-=GVpwy?+TSO=ްahnݺmݺhkWUU{ܶm[Ȉ;<eog*++wٳg&M\tE]y[.z'~ܽ{7زe ,Y$BRBÅd~R}ޔYx۷={1c6oތ:4w\*WJ.\ةS;R/~J!YH35kq 12g?;sLuyi挊wءjR4J4u*)nwypzCηlٲq3Ϥg' -ɸ-ʝA`$E6mpt''v2" 8hڴF32$ gh}J^$H]vE#X4" 5k8C"*R3ZR eT'Uß9ǵkyT\ի׊+>ϐM dU)f<+Rׯ5jj%Nzj򊛔;K(v(]R͛78q"Kם _BX9 %21_1gI(ƎL!GEǗ^zi\8$]Ż0aBJg`dcQ+5"c[#tC*٨tjt'h 1K*<-0c_|E@<_q\LE cbƢm"/L]=^ܔ.v0[ܖrqI9Ƹc\R1.)cK1tIiPSN9`a|TNб-G.ƍ۽{%h.JMҞ;7n6l؃>x%̟?wk߾}&M*++ɢiӦ|;G%ձc֭[Ϛ5QFgb9rҥhkС ?ݺuCa)LC%m۶ܹsN:~xq.]Zhp»[op]wM> /б}_?S 1tI!W^y套^>|FQqОk׮ ݪZ_v(B-'u)߿5LwڵkQY9`G} G@%p\26m`׮]|ݻW[doU8k,~_|Ç/_AR-Z}A>슊 mjh6Y#9C3lӠ_y:I&ZUF3fh֬oVB&P_%c>|xٲew_~ 3G7_w.gϞgF80j(E8qgn@ө CFP4]kJ .޳gOgjkL2GGc~wN˦Z$Vk߄&˚5kH3daʕax('!6 4)EݼyVQ*;v^zm۶-T0]P_5p9琔.m 2 -LHOt3hРAټysս3;hjQ#8ɁZ5[; Mb%^qdJ/O'>)/\%_H9g9"=ztg# c[ÖA@`rpA(8BLX6e׏ܹr6l@vOvdA+2ٝl0IfQi3\H4YՉ-eU_R֭#N*.9_g͚E;vaV۶mCLb%kҮ[b(x HI񠖆Ȃ1J9sL|mRwJC&+>ԧ4i," 8q)02{;| &*I<ࣁ8UUU+V5h ?xRvT9v HIf)ՠVuN-L|mR,MWҟcǎ ?%Pҳ LJ &9'NH*1!XwxKz (4a2VmL[gEswquP O:žlqY!oII8źThݘ._,$J&xI^))!C,^xڴixUz'e. O頥'ްH)Nj̙rnIys;-Z_rՄ%Uꑧ~֭[U[+ӓ»1oo;  _z)͏RNriAT+7^ډDWzud88VǏE/RG\RR&_Ps{UqR3tyv3(DhxRX_A ,3-15+h .jWhRU ~VioLOF |gF5e!Z"%̏RN_Jd".[oWz";@CTH˄O/zIYK[rHtTX&"f)GSM[jƋ"v5~w(g6gAk$H,>êU(^]PΝ;sbǭV'%ލ5+Lj~\Ҹ|^}J*ϕ(C0 ."FHP׆dq}R[aիqZE3MOeiGybJk?1ϵ"zfI H˨!b*&vw>tΜ9c^{5 Ѓ =³8s ,}2y)U#꤬Zm2> nc TK$'A .)qtxrS0,2GRNd bsυx6l0e+?RqN*>K&3'@K``j׮ݰags!yas`Uܡ)!W*`Wz\FXEh,'"%]l>?^Oȏb$@O'^u,ְ-߲2NR_,m41V#ŊX,u=lK)O^X:)<]@"+@*t[m12KwN+##Fq8K!+**pe& ʕ+ ),Ys#;FxȋΉ4!CZcEklTTV7$H9Ӄ6b$bFȟ G@H芄ALjF6>L=,`O)X8`&,DRi<6]3.i"Ыc!C;VJ{-q5H fxz&sĶjG2瀌 : snHkQΒg%% joN AJ\$eovkYQCz30 `45^:YdI!yf}[3G P#_89t+j|L\ | .mQEK*OAe bbŻC/ p^DD%z' KMz+Vyaϝ;iT=iӦ̩朓^ve*#'+H/QAƠH>}h'xʸ< Y ϟ*!jh"<Bcʿ' ~v򂯿zu*?F+\oW%K<OWy:R~g;LNdxa5 I'R< Y2^!v 盓%+ O!0rBjaP%4d$zjSEvӈCFBmrSNLN^0-z@&ءa~\eӾb6AsFXz< % D99J69'1^i79(|xJ`Ңa=RI?;%``!b3Bg.mj)|.0(dnktTk 3/sz"0Nkn{!qZq>#]Q'K*+NݻwWLKeeeHcX<"] '+&B>Q̞=;s$/i@%a/1 |rSr \j+01* Y9u|x] \&C>+mOr1aR#3NHC)FWrF/sɍXĮ#fJ= C `])Gt%Up$MaoΩjQR?ņ X?.[srqI9Ƹc\R1.)cK1%rqI9Ƹc\R1.)cK1%rqI9Ƹc\R1.)cK1%rqI9Ƹc\R1.)cK1%rqI9Ƹc\R1.)cK1%rqI9Ƹc\R1.)cK1%rqI9Ƹc\R1.)cK1%rqI9Ƹc\R1.)cK1%rqI9Ƹc\R1.)cK1%rqI9Ƹc\R1.)cK1%rqI9Ƹc\R1.)cK1%rqI9Ƹc\R1.)cK1%rqI9Ƹc\R1.)cK1%rqI9Ƹc\R1.)cK1%rqI9Ƹc\R1.)cK1%rqI9Ƹc\R1.)cK1%rqI9Ƹc\R1.)cK1%rqI9Ƹc\R1.)cK1%?@v~KIENDB`PKv}>'Configurations2/accelerator/current.xmlPKv}>Configurations2/progressbar/PKv}>Configurations2/floater/PKv}>Configurations2/popupmenu/PKv}>Configurations2/toolpanel/PKv}>Configurations2/menubar/PKv}>Configurations2/toolbar/PKv}>Configurations2/images/Bitmaps/PKv}>Configurations2/statusbar/PKv}> settings.xmlZrH}߯psƔMJcCk6H z4'u9-,#q Js7^❁ 0rv=;ޗ8!IҔ4C3z]FvKl \7$@7LRpr͍b8_\WWWώU=^")/dƤje9;[55뵂Oo֗i7lrXyy}lcV1(g^suyW{05{EWNC3+vD]}TIq1 s&g4L05J l)\hI2_X\2%ڟc;Tju˻ᖩ(nmӹ?sR9Ab^V9Sk>P|b]Tw*xxLlOBc0E|"FcpsT$L&"v]΍Ka rG 0v]a5f(xR.$aW_\  @AuF#0v~ů? sX07̨@I_s& LA`[:&A/ m-u؏q̾4LFNBA-/~⒩W>R(6+G*F qQD)[f=}Mi<+e]XDZX=jP]O09`9Y`PY)9ʙD.14]DPG`$Np,D)Vnq;ҾLpˀ)1+ Y]˰%|36LpJȾhR 'gw.Z[>WC4 `ցG l`37{&&Z ؋[=b7=6q9I_N(G{b#wMOqRv%4*_)^Kʟ~¯K@XFQ6)15qWھ$(ebn ߥFe< OhI:L؁!E%W@;m,RAWؔEuwŸ^f̠łdg(IB%EO_}.DIl7F 7.c1 2<2 Yѣ#V ,֐. cg{ ϖ6X*9GEb(7*;5rYBh( ^,:Y=d<ǘ 6V@-MuSi$ ݗ䧋l.%nAwek|gA)(ߗmɲqޮ"hFyGC?hPK˼=G!PKv}>META-INF/manifest.xmln y kdHrFJ\*0C}b?7M Nk~cm+i-ai;e~~jz 4΄ceћBP10bhH6֡鬌#jo&: Jc:SPa9$P)^Mg_"8Ŭu^Z&8i"}SD7| -AE`:ID |d jf̈́5{ė;zH'O+$H<ѝ~횟LYNOvYsh1dO >qc@ ȧ]gjMm& 5BF/ۺg8o!lK.t߉eZ.#?/{1񹼃xP4+Tf{F@@5|\2>g#DOx??*?PK  PKv}>^2 ''mimetypePKv}> MDialogs/dialog-lc.xmlPKv}>!R]Dialogs/Standard/dialog-lb.xmlPKv}>䡾ZDialogs/KLFOOo/dialog-lb.xmlPKv}>Wm-j Rcontent.xmlPKv}>O manifest.rdfPKv}>!R Basic/Standard/script-lb.xmlPKv}>  Basic/script-lc.xmlPKv}> - Basic/KLFOOo/KLFOOoMain.xmlPKv}>$]Basic/KLFOOo/script-lb.xmlPKv}>+A+ styles.xmlPKv}>!meta.xmlPKv}>)*%Thumbnails/thumbnail.pngPKv}>'CConfigurations2/accelerator/current.xmlPKv}>"DConfigurations2/progressbar/PKv}>\DConfigurations2/floater/PKv}>DConfigurations2/popupmenu/PKv}>DConfigurations2/toolpanel/PKv}>EConfigurations2/menubar/PKv}>8EConfigurations2/toolbar/PKv}>nEConfigurations2/images/Bitmaps/PKv}>EConfigurations2/statusbar/PKv}>˼=G! Esettings.xmlPKv}>  dKMETA-INF/manifest.xmlPKehMklatexformula-4.1.0/extras/KLFOpenOfficeorg/mkoxtzip.sh000755 000765 000024 00000000140 13660527435 024171 0ustar00philippestaff000000 000000 #!/bin/bash cd KLFOOo-oxt && zip -vr ../KLFOOo.oxt . --exclude '*.svn/' --exclude '*.svn/*' @ klatexformula-4.1.0/extras/KLFOpenOfficeorg/mkxmlbasic.pl000755 000765 000024 00000001044 13660527435 024443 0ustar00philippestaff000000 000000 #!/usr/bin/perl -w use XML::Writer; use IO::Handle; STDOUT->autoflush(1); my $xmlwriter = new XML::Writer; push @all, $_ while (<>); $allscript = join("", @all); print < EOHEADER $xmlwriter->startTag("script:module", "xmlns:script"=>"http://openoffice.org/2000/script", "script:name"=>"KLFOOoMain", "script:language"=>"StarBasic"); $xmlwriter->characters($allscript); $xmlwriter->endTag(); klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo.oxt000644 000765 000024 00000051127 13660527435 023545 0ustar00philippestaff000000 000000 PK >KLFOOo/UT ”M)Mux qdPKǎ>\fѷk P)KLFOOo/KLFOOoMain.xbaUT %M)Mux qdZrH fL@bq;[)!5X5R@^hclq&WFݧssFo]-rGfnSmhuPdΚe/'~y3mY0+t(]O:QkGtjTcV\v|03\P@պ*Qr yL ȱ:{S1@g)Q^I55~8 ̰d1Yh`r mr=#nA (pBpR: fm"cp2:+Jlәopt]zEQrndB"BWsh@'8$ @]n(ܷۀԿ=&[ Lj`]Ÿ t{A]iD~Wg!8g3D !wd9M&t֙;ғ]HB,|8  v8R%%U[ԇ(oal84xNRVF'q#DCT>?q/Yo,n51Zg4@v0[cC'SE"Gj6h sM3Q|d^d-1 9$0$5U@.itJ;L.F^ SRZs\je9[,؍RxEؽ̆| ط]ۥ2rߍ4KPKamh 'q* ^XJd:v1 d=WC=8FC)GWR?٩"VJ2!hF~L7vT,{}T#OYhQ|mi cIx`grJDzD4B'Mnv',Sc1q辐~ +=zg@?tf2f:ߏ9yfyhy``+DZ> 6C .bP#F'߈ FJ.lE.?{l Z{)7PE7͞a'\>ȡK28W.?4yhe,aEkkۂEEcMԞ_Uj%'6JD&hW@t q0JQC캣fo{&ظ$3W,1xD}/Q@+le5aGD?>'Kd TvƤC$ppq9nW`ŵYF=៱ه^8ipnH0dM|zx3^֗0@=>rJkjmѢ4y6.NCߞ/ƛR&R)IO$ /58]6ސF Fq'y. ϧxu5-ל3r-Br=&\Hf)~ٽH.w3e=m3bGs,vii=G :2 n9 !"?Sd M!?+op^̮cpx1=P@ lTW\!{T) ̂"AV[5d(z\&03n{_rMb해Gv9fx)ŏǀǧ Vء4$l#in䡾KLFOOo/dialog.xlbUT MMux qd] 0>EܻI*hD1clZh%ooj2t+q'J6 ui. ` YoO2;V*Vפp\6KDِEQ Y*>:V"W{GklheW%p rH.a153m-)ͦ BUC{ՍeO'u PKi>$]KLFOOo/script.xlbUT MMux qdmOMo0 +2ߩ&D4 4 aи,RWI_*g?YE>vdidescription.xmlUT M Mux qdMn0׉;ް Tͮl8xp$.|of^:Mp S[/?7R!m$BW7`l` ܺV~^89q{QbPK >Office/UT ”M)Mux qdPK > Office/UI/UT ”MIMux qdPKi>S)Office/UI/MathWindowState.xcuUT MMux qdeAo0 i`LU Ҥ!8)KMQ(4tL{N\ +PlXZaV a ~dN=sF{Bcwö*]Z-N V巴\fl`CUZvISJatO_:v1T9&鉓,0i}`.x[ cy37MvU*PKi>/he)Office/UI/CalcWindowState.xcuUT MMux qdeAo0 i`LU Ҧ!qnR$PKi8%*#[J8Py6M' 2JB8Ră QnWHa4sya9A?(Nu׏͟cMwc”@)ʨ^9px{}|l͜=(Ûak^Xv)'-Do0b\R I̠.Abڐßm;k_9?'PpD\fnϛݵ ~ PKi>WS) Office/UI/ImpressWindowState.xcuUT MMux qdeQMo0 =r2U)HT6e)8J?-?'b~֕S6',0/uf1~bh(m6Aq.]B@ޛs4q+h 0Ltޞh'ǿϷZvke )jcRجpōT?oW]fnK5.~hly$8Dx G2Q.e:Y0TX4Sz=+e :󉂹4V7m̾;?ƿPKi>$(Office/UI/BaseWindowState.xcuUT MMux qdeAo0 i`LU Ґ8)KMQ(40{N\ +PlXZaVLa,$Office/UI/StartModuleWindowState.xcuUT MMux qdeQMo0 =r2U)HhMYbJ6@ϥcdω*9%K(ԥ)r̆Ol: 02Ȅgl8G wRAј;(Jܙ QqWA4iGX.jlJ#k:HFcC+շ,F6MUWsFA 7K5/~Y;кHp)K|.fc9ڜ9T{:Qlir ȯ':ۓwh[3siPKi>\5+)Office/UI/DrawWindowState.xcuUT MMux qdeAo0 i`LU Ҵ!qnSR#'PKi8%*#-PlXZaV|*!Office/UI/BasicIDEWindowState.xcuUT MMux qdeQOk0?W;mt* #j֙3doiX=Լeא)R䯳T6+\ ^zHݱɉo1nY^Pypj@/ =4\3b@W\@6gGwg''qDȫ83M-m}C}ּ]o7F֏PKi>9)Office/UI/WriterWindowState.xcuUT MMux qdeQMo0 =PNeR&  vԔhm9¿_JcdÉ*99>0 mʜW32E ee{q nZATp JB鉃0|h.x7Սy;^;5PK >icons/UT ”M)Mux qdPKi>ݒ6icons/image1_16.bmpUT MMux qds5cf3 b(fdHSB0 ,_|@H999W\!ޖ͛7īwgϞ=ī&^ڵkW]mmmcmÆ D겳;}4N*,,5kᙖhѢl"Ϝ9x[0PKi>Sm{Vicons/image1_26.bmpUT MMux qdϋaEEl{1iJ0qڋPʕ"n)8R3Efyw51|뭙yw|}9z]>o]x|WxHT*H$rxsWm6)j6~P(HAvb|fVgy$tdw]tZM?~˥lx<\ɗ/˥h$; Beߗ#f "Nt:*ăZ-‰h8#V&`PTuxKbҒ)/b/5fZv8d0(=^s  ł9T8v[x􈿳JJX,o&7MKqSm{Vicons/image1_26h.bmpUT MMux qdϋaEEl{1iJ0qڋPʕ"n)8R3Efyw51|뭙yw|}9z]>o]x|WxHT*H$rxsWm6)j6~P(HAvb|fVgy$tdw]tZM?~˥lx<\ɗ/˥h$; Beߗ#f "Nt:*ăZ-‰h8#V&`PTuxKbҒ)/b/5fZv8d0(=^s  ł9T8v[x􈿳JJX,o&7MKqTTtVicons/image4_26.bmpUT MMux qdT=hQ `QJEP$T( b@ApP'ttwqQp$d(5FSF0!q߻wy{f* ?n.b??O&'B>[ 8z~uu%1[|QT~?0IIӻ. Fѻ;&|A  9t:Kz& Aէonn89Jp2AA6'''HjU<3sb;)bHR> v`F.*J>VNn@`[Q5 'Hj |lL&[7ؤPtBv=Jq,z DZכqkjmБ(cu BDJ(ZR'f6r5_[=%4q҇}9>>Zm4ASRwYTP(^FQ\\\rXL@?z}KeO}ڇ=}OPKi>Vicons/image3_26h.bmpUT MMux qdOH"Q,{ڋVO",uD:x:E%A;Hxmt ,D!-\YV1ٯjv 7O_h}DEoi{߼&QTO-|㉨X,FcU(83yy`pggroϴz6{!^8ƸQzuuH$N'BAT*B!5r O-l}T!jJƌF!fD"$I?0@XŤ///3BTTtVicons/image4_26h.bmpUT MMux qdT=hQ `QJEP$T( b@ApP'ttwqQp$d(5FSF0!q߻wy{f* ?n.b??O&'B>[ 8z~uu%1[|QT~?0IIӻ. Fѻ;&|A  9t:Kz& Aէonn89Jp2AA6'''HjU<3sb;)bHR> v`F.*J>VNn@`[Q5 'Hj |lL&[7ؤPtBv=Jq,z DZכqkjmБ(cu BDJ(ZR'f6r5_[=%4q҇}9>>Zm4ASRwYTP(^FQ\\\rXL@?z}KeO}ڇ=}OPKi>.sN6icons/image4_16.bmpUT MMux qds5cf3 b(fdHE!҈T?iҤعs̘1̙3uݺuKAAXѻw6nxbkiim߾}({VZ,իWg͚UTT^xRRRh&LݣG: 3={ӧ_~߸q#??/,, }  , R1L<9))Ç7o$F۷oEEE7oL|j.sN6icons/image4_16h.bmpUT MMux qds5cf3 b(fdHE!҈T?iҤعs̘1̙3uݺuKAAXѻw6nxbkiim߾}({VZ,իWg͚UTT^xRRRh&LݣG: 3={ӧ_~߸q#??/,, }  , R1L<9))Ç7o$F۷oEEE7oL|j96icons/image2_16h.bmpUT MMux qdmA/b#2BJ6"ւp 뷠 zw*(F͓8l0<>|>0>c|7>}rY  f^7!JPk6 ffd2+A[P(D~?nկV\.7Lpn#d2cdb1R)ѨhT*Zd2u:ToZKzĄI%PKi>ݒ6icons/image1_16h.bmpUT MMux qds5cf3 b(fdHSB0 ,_|@H999W\!ޖ͛7īwgϞ=ī&^ڵkW]mmmcmÆ D겳;}4N*,,5kᙖhѢl"Ϝ9x[0PKi>!MVicons/image2_26h.bmpUT MMux qdKHAXQRP= 4oh}G%$zKW4&ĄJ (c7ULgn?e2zͣ p<}T2y566ۤ|ÊLe<==]ZZJs+a3z@L&F`b|!Ae@)Uw"ccے= X,ԇ~!8S&immL'UeB{2T*l[$~@QH R!Qh|@8k>$^0&:C|#144!//ˌ7!>322wOMMMLL9t&󅅅rZZZ::::;;[[[9rTUUWn)n+***++F4kwPKi>T6icons/image3_16.bmpUT MMux qdRjP6A>B&>@oMI0K2 EQ d˒bB$Gn mK{ιPP0Ө3I H Mߦ(<.,0 󹠟iVf\.}<϶m0p,ˇáhDQ\.'Ig4jj:N-H)a4Mx$|Eu]:òtjZrߓD/F4\1Mww:8Je8E(>[p^q Ex|\`Wuz=I `3L&nw^!& Y 1]ۏPKi>3Vicons/image3_26.bmpUT MMux qd͕MHbQu72 0f W" BZZ&!]!. aAI4Eu2R+69MW0wϽw=߾cPCc2>R𞴾zoĻSl6l&ɾ KʣyTvxޟ`۝wtt$`899M( .Tnoo_Ahb* GNZZ?({pp0Z-t9mk|NJ%<+a!Bx``mnnb0O*xT6icons/image3_16h.bmpUT MMux qdRjP6A>B&>@oMI0K2 EQ d˒bB$Gn mK{ιPP0Ө3I H Mߦ(<.,0 󹠟iVf\.}<϶m0p,ˇáhDQ\.'Ig4jj:N-H)a4Mx$|Eu]:òtjZrߓD/F4\1Mww:8Je8E(>[p^q Ex|\`Wuz=I `3L&nw^!& Y 1]ۏPKi>96icons/image2_16.bmpUT MMux qdmA/b#2BJ6"ւp 뷠 zw*(F͓8l0<>|>0>c|7>}rY  f^7!JPk6 ffd2+A[P(D~?nկV\.7Lpn#d2cdb1R)ѨhT*Zd2u:ToZKzĄI%PKi>!MVicons/image2_26.bmpUT MMux qdKHAXQRP= 4oh}G%$zKW4&ĄJ (c7ULgn?e2zͣ p<}T2y566ۤ|ÊLe<==]ZZJs+a3z@L&F`b|!Ae@)Uw"ccے= X,ԇ~!8S&immL'UeB{2T*l[$~@QH R!Qh|@8k>$^0&:C|#144!//ˌ7!>322wOMMMLL9t&󅅅rZZZ::::;;[[[9rTUUWn)n+***++F4kwPK #> pkg-desc/UT M)Mux qdPK>h CzZ^pkg-desc/pkg-description.txtUT M%Mux qd%1 0 Ȩ }C-i h#!nK9;f*BZY}T|>"PU,Bfpa 9SBRzOPK > META-INF/UT הM)Mux qdPKi>kȪGMETA-INF/manifest.xmlUT MMux qdձj0=OajR섦iC2{D$'):y(v?H٪ourBȚݧw,A#"ll\d-1[\$c&MduZs3go۲94I@JCg\S_ W5 }p :ۦ& 555q%uMžúx yhD_SD?y65\3h9n8Te6uCO&~_PKi><0 Addons.xcuUT MMux qd[k"1-? BחuKwn*rLLtBЗ̹#0aw2oJSZo~jc{F:kJ(P~Pb <{Pi"z~b?Ik3Kf\h>W9Hʍ)xʁ7RX_PK > registration/UT הM)Mux qdPK >AKLFOOo/UT”Mux qdPKǎ>\fѷk P)AKLFOOo/KLFOOoMain.xbaUT%Mux qdPKi>䡾 KLFOOo/dialog.xlbUTMux qdPKi>$] KLFOOo/script.xlbUTMux qdPK>di#description.xmlUTMux qdPK >AgOffice/UT”Mux qdPK > AOffice/UI/UT”Mux qdPKi>S)Office/UI/MathWindowState.xcuUTMux qdPKi>/he)lOffice/UI/CalcWindowState.xcuUTMux qdPKi>WS) Office/UI/ImpressWindowState.xcuUTMux qdPKi>$(oOffice/UI/BaseWindowState.xcuUTMux qdPKi>La,$Office/UI/StartModuleWindowState.xcuUTMux qdPKi>\5+)xOffice/UI/DrawWindowState.xcuUTMux qdPKi>|*!Office/UI/BasicIDEWindowState.xcuUTMux qdPKi>9)}Office/UI/WriterWindowState.xcuUTMux qdPK >Aicons/UT”Mux qdPKi>ݒ6?icons/image1_16.bmpUTMux qdPKi>Sm{V>icons/image1_26.bmpUTMux qdPKi>Sm{V\icons/image1_26h.bmpUTMux qdPKi>TTtV{!icons/image4_26.bmpUTMux qdPKi>V<$icons/image3_26h.bmpUTMux qdPKi>TTtVh'icons/image4_26h.bmpUTMux qdPKi>.sN6**icons/image4_16.bmpUTMux qdPKi>.sN6+icons/image4_16h.bmpUTMux qdPKi>96,icons/image2_16h.bmpUTMux qdPKi>ݒ6 /icons/image1_16h.bmpUTMux qdPKi>!MV 0icons/image2_26h.bmpUTMux qdPKi>T63icons/image3_16.bmpUTMux qdPKi>3VG5icons/image3_26.bmpUTMux qdPKi>T6D8icons/image3_16h.bmpUTMux qdPKi>969icons/image2_16.bmpUTMux qdPKi>!MV<icons/image2_26.bmpUTMux qdPK #> A?pkg-desc/UTMux qdPK>h CzZ^?pkg-desc/pkg-description.txtUTMux qdPK > A@META-INF/UTהMux qdPKi>kȪG@META-INF/manifest.xmlUTMux qdPKi><0 JBAddons.xcuUTMux qdPK > ADregistration/UTהMux qdPK&&R Dklatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/Office/000755 000765 000024 00000000000 13660527435 025006 5ustar00philippestaff000000 000000 klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/META-INF/000755 000765 000024 00000000000 13660527435 024753 5ustar00philippestaff000000 000000 klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/description.xml000644 000765 000024 00000000736 13660527435 026666 0ustar00philippestaff000000 000000 klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/icons/000755 000765 000024 00000000000 13660527435 024726 5ustar00philippestaff000000 000000 klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/pkg-desc/000755 000765 000024 00000000000 13660527435 025310 5ustar00philippestaff000000 000000 klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/Addons.xcu000644 000765 000024 00000006370 13660527435 025552 0ustar00philippestaff000000 000000 com.sun.star.text.TextDocument,com.sun.star.drawing.DrawingDocument,com.sun.star.presentation.PresentationDocument vnd.sun.star.script:KLFOOo.KLFOOoMain.KLFLaunch?language=Basic&location=application %origin%/icons/image1 KLatexFormula _self com.sun.star.text.TextDocument,com.sun.star.drawing.DrawingDocument,com.sun.star.presentation.PresentationDocument vnd.sun.star.script:KLFOOo.KLFOOoMain.KLFRePaste?language=Basic&location=application %origin%/icons/image2 Re-Paste _self com.sun.star.text.TextDocument vnd.sun.star.script:KLFOOo.KLFOOoMain.KLFFormatForInline?language=Basic&location=application %origin%/icons/image3 Make In-line _self com.sun.star.text.TextDocument,com.sun.star.drawing.DrawingDocument,com.sun.star.presentation.PresentationDocument vnd.sun.star.script:KLFOOo.KLFOOoMain.KLFFixShapeAspectRatio?language=Basic&location=application %origin%/icons/image4 Fix Aspect Ratio _self klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/KLFOOo/000755 000765 000024 00000000000 13660527435 024644 5ustar00philippestaff000000 000000 klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/KLFOOo/dialog.xlb000644 000765 000024 00000000435 13660527435 026614 0ustar00philippestaff000000 000000 klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/KLFOOo/script.xlb000644 000765 000024 00000000535 13660527435 026662 0ustar00philippestaff000000 000000 klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/KLFOOo/KLFOOoMain.xba000644 000765 000024 00000024520 13660527435 027201 0ustar00philippestaff000000 000000 REM ***** BASIC ***** Sub Main MsgBox "klatexformula OpenOffice.org integration" End Sub ' Thank you OOoLatex for examples of OOoBasic usage, syntax and tricks ! ' http://ooolatex.sourceforge.net/ Sub KLFLaunch oDoc = ThisComponent oDocCtrl = oDoc.getCurrentController() If isEmpty(oDocCtrl.selection()) Then MsgBox "You have not selected anything" Exit Sub End If oSelection = oDocCtrl.getSelection() If oSelection.supportsService("com.sun.star.text.TextRanges") Then Dim curString As String nCount = oSelection.Count() If nCount <= 0 Then MsgBox "No text selected" Exit Sub End If For i = 0 to nCount - 1 curString = curString & oSelection.getByIndex(i).getString() Next i ' Run klatexformula with the selected string latexb64 = klfBase64Encode(curString) cmd = "klatexformula --noeval --interactive -B --latexinput=" & latexb64 & " --tborderoffset=0 --rborderoffset=0 --bborderoffset=0 --lborderoffset=0" Shell(cmd) Exit Sub End If If oSelection.getImplementationName() <> "com.sun.star.drawing.SvxShapeCollection" Then MsgBox "You have not selected a KLatexFormula equation" Exit Sub End If If oSelection.getCount() <> 1 Then MsgBox "Cannot edit multiple equations at once" Exit Sub End If oShape = oSelection.getByIndex(0) oAttributes = oShape.UserDefinedAttributes() isKlf = oAttributes.hasByName("IsKLF") If Not isKlf Then hasOOoLatexArgs = oAttributes.hasByName("OOoLatexArgs") If Not hasOOoLatexArgs Then MsgBox "The selected object is not a KLatexFormula equation." Exit Sub End If ' We have a OOoLatex object oooLatexArgs = oAttributes.getByName("OOoLatexArgs").Value() If oooLatexArgs = "" Then MsgBox "The selected object does not have any OOoLatex information." Exit Sub End If Dim args() args = Split(oooLatexArgs,"§",3) mathmode = "XFsgLi4uIFxd" ' \[ ... \] If args(1) = "inline" Then mathmode = "JCAuLi4gJA==" ' $ ... $ End If latexb64 = klfBase64Encode(args(2)) cmd = "klatexformula --interactive -B --latexinput=" & latexb64 & " -B --mathmode=" & mathmode Shell(cmd) Exit Sub End If ' We have a KLF object cmd = "klatexformula --interactive -B --latexinput=" & oAttributes.getByName("KLFInputLatexBase64").value() & " -B --preamble=" & oAttributes.getByName("KLFInputPreambleBase64").value() & " -B --mathmode=" & oAttributes.getByName("KLFInputMathModeBase64").value() & " -B --fgcolor=" & oAttributes.getByName("KLFInputFgColorBase64").value() & " -B --bgcolor=" & oAttributes.getByName("KLFInputBgColorBase64").Value() & " --dpi=" & oAttributes.getByName("KLFInputDPI").Value() & " --tborderoffset=" & oAttributes.getByName("KLFSettingsTBorderOffsetPsPt").Value() & " --rborderoffset=" & oAttributes.getByName("KLFSettingsRBorderOffsetPsPt").Value() & " --bborderoffset=" & oAttributes.getByName("KLFSettingsBBorderOffsetPsPt").Value() & " --lborderoffset=" & oAttributes.getByName("KLFSettingsLBorderOffsetPsPt").Value() Shell(cmd) Exit sub End Sub Sub KLFFixShapeAspectRatio oDoc = ThisComponent oDocCtrl = oDoc.getCurrentController() If isEmpty(oDocCtrl.selection()) Then MsgBox "Nothing is selected" Exit Sub End If oSelection = oDocCtrl.getSelection() If oSelection.getImplementationName() <> "com.sun.star.drawing.SvxShapeCollection" Then MsgBox "You have not selected a klatexformula equation." Exit Sub End If If oSelection.getCount() <> 1 Then MsgBox "Please select exactly one formula to fix aspect ratio" End If oShape = oSelection.getByIndex(0) ' Got Shape oAttributes = oShape.UserDefinedAttributes() Dim ratio as Single ratio = oAttributes.getByName("KLFImageAspectRatio").Value() Dim newSize newSize = createUnoStruct("com.sun.star.awt.Size") newSize.Width = oShape.size().Width newSize.Height = newSize.Width / ratio oShape.setSize(newSize) End Sub Sub KLFFormatForInline oDoc = ThisComponent oDocCtrl = oDoc.getCurrentController() If isEmpty(oDocCtrl.selection()) Then MsgBox "Nothing is selected" Exit Sub End If oSelection = oDocCtrl.getSelection() If oSelection.getImplementationName() <> "com.sun.star.drawing.SvxShapeCollection" Then MsgBox "You have not selected a klatexformula equation." Exit Sub End If If oSelection.getCount() <> 1 Then MsgBox "Please select exactly one formula to fix aspect ratio" Exit Sub End If oShape = oSelection.getByIndex(0) ' Got Shape oAttributes = oShape.UserDefinedAttributes() If Not oAttributes.hasByName("IsKLF") Then MsgBox "The object you selected is not a klatexformula equation." Exit Sub End If Dim bborderoffset as Integer bborderoffset = oAttributes.getByName("KLFSettingsBBorderOffsetPsPt").Value() If bborderoffset <> 0 Then MsgBox "Inline mode best works when the image border offsets are set to zero." & Chr(10) & _ "You can do this by re-opening KLatexFormula and adjusting your settings." End If Dim w as Single, h as Single w = oAttributes.getByName("KLFImageOrigWidthCm").Value() h = oAttributes.getByName("KLFImageOrigHeightCm").Value() Dim origSize origSize = createUnoStruct("com.sun.star.awt.Size") origSize.Width = w*1000 ' Units: 1/100 of mm origSize.Height = h*1000 ' Units: 1/100 of mm oShape.setSize(origSize) oShape.AnchorType = com.sun.star.text.TextContentAnchorType.AS_CHARACTER oShape.TopMargin = 0 oShape.BottomMargin = 0 oShape.VertOrient = com.sun.star.text.VertOrientation.CHAR_CENTER End Sub Sub KLFRePaste oDoc = ThisComponent oDocCtrl = oDoc.getCurrentController() 'MsgBox "Repaste!" If isEmpty(oDocCtrl.selection()) Then MsgBox "Nothing is selected" Exit Sub End If oSelection = oDocCtrl.getSelection() If oSelection.getImplementationName() <> "com.sun.star.drawing.SvxShapeCollection" Then MsgBox "You have not selected a klatexformula equation." Exit Sub End If If oSelection.getCount() <> 1 Then MsgBox "Please select exactly one formula to re-paste over" End If oShape = oSelection.getByIndex(0) ' Got Shape oAttributes = oShape.UserDefinedAttributes() 'Dim ratio as Single Dim imgW as Single Dim imgH as Single Dim dpi as Single Dim displaySizeFactorW as Single Dim displaySizeFactorH as Single Dim position dpi = oAttributes.getByName("KLFInputDPI").Value() imgW = oAttributes.getByName("KLFImageWidthPx").Value() imgW = imgW / dpi displaySizeFactorW = oShape.size().Width / imgW imgH = oAttributes.getByName("KLFImageHeightPx").Value() imgH = imgH / dpi displaySizeFactorH = oShape.size().Height / imgH position = createUnoStruct("com.sun.star.awt.Point") position.X = oShape.position().X position.Y = oShape.position().Y 'Dim saveAnchorType, saveTopMargin, saveBottomMargin, saveVertOrient 'saveAnchorType = oShape.AnchorType 'saveTopMargin = oShape.TopMargin 'saveBottomMargin = oShape.BottomMargin 'saveVertOrient = oShape.VertOrient Dim dispatcher dispatcher = createUnoService("com.sun.star.frame.DispatchHelper") ' Now Remove Old Object dispatcher.executeDispatch(oDoc.getCurrentController.getFrame(), ".uno:Delete", "", 0, Array()) ' And Paste New Object dispatcher.executeDispatch(oDoc.getCurrentController.getFrame(), ".uno:Paste", "", 0, Array()) oPastedSelection = oDocCtrl.getSelection() If oPastedSelection.getImplementationName() <> "com.sun.star.drawing.SvxShapeCollection" Then MsgBox "You have not pasted a klatexformula equation." Exit Sub End If If oPastedSelection.getCount() <> 1 Then MsgBox "Please paste only one object." Exit Sub End If oPastedShape = oPastedSelection.getByIndex(0) ' Set attributes correctly now Dim oPastedAttributes oPastedAttributes = oPastedShape.UserDefinedAttributes() Dim newWpx as Single, newHpx as Single, newDpi as Single, newW as Single, newH as Single newDpi = oPastedAttributes.getByName("KLFInputDPI").Value() newWpx = oPastedAttributes.getByName("KLFImageWidthPx").Value() newHpx = oPastedAttributes.getByName("KLFImageHeightPx").Value() newW = newWpx / newDpi newH = newHpx / newDpi Dim newSize newSize = createUnoStruct("com.sun.star.awt.Size") newSize.Width = displaySizeFactorW * newW newSize.Height = displaySizeFactorH * newH Dim newPosition newPosition = createUnoStruct("com.sun.star.awt.Point") newPosition.X = position.X newPosition.Y = position.Y oPastedShape.setSize(newSize) oPastedShape.setPosition(newPosition) 'oPastedShape.AnchorType = saveAnchorType 'oPastedShape.TopMargin = saveTopMargin 'oPastedShape.BottomMargin = saveBottomMargin 'oPastedShape.VertOrient = saveVertOrient End Sub ' Function Code taken from ' http://www.motobit.com/tips/detpg_Base64Encode/ ' Function klfBase64Encode(inData) 'rfc1521 '2001 Antonin Foller, Motobit Software, http://Motobit.cz Const Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" Dim cOut, sOut, I 'For each group of 3 bytes For I = 1 To Len(inData) Step 3 Dim nGroup, pOut, sGroup 'Create one long from this 3 bytes. nGroup = &H10000 * Asc(Mid(inData, I, 1)) + _ &H100 * klfMyASC(Mid(inData, I + 1, 1)) + klfMyASC(Mid(inData, I + 2, 1)) 'Oct splits the long To 8 groups with 3 bits nGroup = Oct(nGroup) 'Add leading zeros nGroup = String(8 - Len(nGroup), "0") & nGroup 'Convert To base64 pOut = Mid(Base64, CLng("&o" & Mid(nGroup, 1, 2)) + 1, 1) + _ Mid(Base64, CLng("&o" & Mid(nGroup, 3, 2)) + 1, 1) + _ Mid(Base64, CLng("&o" & Mid(nGroup, 5, 2)) + 1, 1) + _ Mid(Base64, CLng("&o" & Mid(nGroup, 7, 2)) + 1, 1) 'Add the part To OutPut string sOut = sOut + pOut 'Add a new line For Each 76 chars In dest (76*3/4 = 57) 'If (I + 2) Mod 57 = 0 Then sOut = sOut + vbCrLf Next Select Case Len(inData) Mod 3 Case 1: '8 bit final sOut = Left(sOut, Len(sOut) - 2) + "==" Case 2: '16 bit final sOut = Left(sOut, Len(sOut) - 1) + "=" End Select klfBase64Encode = sOut End Function Function klfMyASC(OneChar) If OneChar = "" Then klfMyASC = 0 Else klfMyASC = Asc(OneChar) End Function klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/pkg-desc/pkg-description.txt000644 000765 000024 00000000136 13660527435 031153 0ustar00philippestaff000000 000000 KLFOOo-1.0.3.oxt Copyright (c) 2011 KLatexFormula integration for OpenOffice.org/LibreOffice klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/icons/image4_26h.bmp000644 000765 000024 00000004126 13660527435 027256 0ustar00philippestaff000000 000000 BMV6(   VVVddd000TTTlll\\\zzz666tttNNNwww \\\pppBBB333hhhmmm ```VVV㌌===___!!!999<<<<<<<<<<<<<<<<<<===<<<(((===>>>fff```dddwww111&&&444>>>ڥWWW###333===iii푑SSS:::... ~~~klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/icons/image3_26.bmp000644 000765 000024 00000004126 13660527435 027105 0ustar00philippestaff000000 000000 BMV6(   Ҵͷ̿PPPܵ HHH񯯯%%%555lllZZZ======\\\uuuddd222 hhhҀΥ///ҟΥBBBzzzΥyyy%%%>>>Υdddzzz---ΥfffhhhOOOwwwJJJXXXlllΥ΢ЗWWWoooҸklatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/icons/image1_26.bmp000644 000765 000024 00000004126 13660527435 027103 0ustar00philippestaff000000 000000 BMV6( ›666 lll>>><<<옘000```SSS ~~~ eee000>>>{{{ooo DDD[[[BBB 999<<<***kkkBBBMMM;;; ```EEEklatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/icons/image4_16.bmp000644 000765 000024 00000001466 13660527435 027111 0ustar00philippestaff000000 000000 BM66(  QQQfff]]]||| ~~~KKK***```~~~IIIGGGnnnnnnnnnnnnaaa$$$oooVVV|||SSSbbbĄklatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/icons/image4_16h.bmp000644 000765 000024 00000001466 13660527435 027261 0ustar00philippestaff000000 000000 BM66(  QQQfff]]]||| ~~~KKK***```~~~IIIGGGnnnnnnnnnnnnaaa$$$oooVVV|||SSSbbbĄklatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/icons/image2_16.bmp000644 000765 000024 00000001466 13660527435 027107 0ustar00philippestaff000000 000000 BM66(22뗗ï貲թ򫬫议謬諫KKK謬譭qqq议FFF误aaa豱YYY貲OOO賳777444444333MMMzzz駧cccmmmmmmddd=== ???jjj\\\^^^jjjklatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/icons/image2_26.bmp000644 000765 000024 00000004126 13660527435 027104 0ustar00philippestaff000000 000000 BMV6( 11ƝϚcccƨԦ___ƣڎ׶\\\Ơ333 WWWƜ;;;ƙ[[[PPPƖƙƙƜ:::ƝTTT\\\ƛơƣƣƩnnnUUUƨ Ʃ䓓Ʃvvvsssvvvoooqqqpppnnnqqq{{{Dzuuu zzzAAAqqq UUUXXX]]]^^^ZZZ+++^^^bbbbbb```}}}###&&&+++...VVVtttrrrrrroooooooooklatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/icons/image3_26h.bmp000644 000765 000024 00000004126 13660527435 027255 0ustar00philippestaff000000 000000 BMV6(   Ҵͷ̿PPPܵ HHH񯯯Ϙ%%%̘555lllZZZ======\\\uuuddd222 hhhҀΥ///ҟΥBBBzzzΥyyy%%%>>>Υdddzzz---ΥfffhhhOOOwwwJJJXXXlllΥ΢ЗWWWoooҸklatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/icons/image2_26h.bmp000644 000765 000024 00000004126 13660527435 027254 0ustar00philippestaff000000 000000 BMV6( 11ƝϚcccƨԦ___ƣڎ׶\\\Ơ333 WWWƜ;;;ƙ[[[PPPƖƙƙƜ:::ƝTTT\\\ƛơƣƣƩnnnUUUƨ Ʃ䓓Ʃvvvsssvvvoooqqqpppnnnqqq{{{Dzuuu zzzAAAqqq UUUXXX]]]^^^ZZZ+++^^^bbbbbb```}}}###&&&+++...VVVtttrrrrrroooooooooklatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/icons/image1_16h.bmp000644 000765 000024 00000001466 13660527435 027256 0ustar00philippestaff000000 000000 BM66(eelllwwwooo(((LLL}}}[[[+++݉ >>>qqqfffkkkklatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/icons/image1_16.bmp000644 000765 000024 00000001466 13660527435 027106 0ustar00philippestaff000000 000000 BM66(eelllwwwooo(((LLL}}}[[[+++݉ >>>qqqfffkkkklatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/icons/image3_16h.bmp000644 000765 000024 00000001466 13660527435 027260 0ustar00philippestaff000000 000000 BM66(  ɓżȾ```GGG///...333(((QQQPPPGGGꌌklatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/icons/image4_26.bmp000644 000765 000024 00000004126 13660527435 027106 0ustar00philippestaff000000 000000 BMV6(   VVVddd000TTTlll\\\zzz666tttNNNwww \\\pppBBB333hhhmmm ```VVV㌌===___!!!999<<<<<<<<<<<<<<<<<<===<<<(((===>>>fff```dddwww111&&&444>>>ڥWWW###333===iii푑SSS:::... ~~~klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/icons/image2_16h.bmp000644 000765 000024 00000001466 13660527435 027257 0ustar00philippestaff000000 000000 BM66(22뗗ï貲թ򫬫议謬諫KKK謬譭qqq议FFF误aaa豱YYY貲OOO賳777444444333MMMzzz駧cccmmmmmmddd=== ???jjj\\\^^^jjjklatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/icons/image3_16.bmp000644 000765 000024 00000001466 13660527435 027110 0ustar00philippestaff000000 000000 BM66(  ɓżȾ```GGG///...333(((QQQPPPGGGꌌklatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/icons/image1_26h.bmp000644 000765 000024 00000004126 13660527435 027253 0ustar00philippestaff000000 000000 BMV6( ›666 lll>>><<<옘000```SSS ~~~ eee000>>>{{{ooo DDD[[[BBB 999<<<***kkkBBBMMM;;; ```EEEklatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/META-INF/manifest.xml000644 000765 000024 00000003107 13660527435 027304 0ustar00philippestaff000000 000000 klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/Office/UI/000755 000765 000024 00000000000 13660527435 025323 5ustar00philippestaff000000 000000 klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/Office/UI/ImpressWindowState.xcu000644 000765 000024 00000001027 13660527435 031657 0ustar00philippestaff000000 000000 KLFOOo toolbar klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/Office/UI/BaseWindowState.xcu000644 000765 000024 00000001024 13660527435 031104 0ustar00philippestaff000000 000000 KLFOOo toolbar klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/Office/UI/StartModuleWindowState.xcu000644 000765 000024 00000001033 13660527435 032475 0ustar00philippestaff000000 000000 KLFOOo toolbar klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/Office/UI/DrawWindowState.xcu000644 000765 000024 00000001024 13660527435 031127 0ustar00philippestaff000000 000000 KLFOOo toolbar klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/Office/UI/BasicIDEWindowState.xcu000644 000765 000024 00000001030 13660527435 031572 0ustar00philippestaff000000 000000 KLFOOo toolbar klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/Office/UI/MathWindowState.xcu000644 000765 000024 00000001024 13660527435 031123 0ustar00philippestaff000000 000000 KLFOOo toolbar klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/Office/UI/WriterWindowState.xcu000644 000765 000024 00000001026 13660527435 031510 0ustar00philippestaff000000 000000 KLFOOo toolbar klatexformula-4.1.0/extras/KLFOpenOfficeorg/KLFOOo-oxt/Office/UI/CalcWindowState.xcu000644 000765 000024 00000001024 13660527435 031074 0ustar00philippestaff000000 000000 KLFOOo toolbar klatexformula-4.1.0/src/klftools/000755 000765 000024 00000000000 13660527435 020006 5ustar00philippestaff000000 000000 klatexformula-4.1.0/src/klfmainwin.ui000644 000765 000024 00000167123 13660527435 020661 0ustar00philippestaff000000 000000 Philippe Faist KLatexFormula main window UI KLFMainWin 0 0 781 376 KLatexFormula :/pics/klatexformula-64.png:/pics/klatexformula-64.png 2 2 2 2 2 1 0 QFrame::NoFrame QFrame::Plain 0 4 4 4 4 0 0 Enter &LaTeX expression: Qt::AlignCenter false txtLatex Qt::Vertical true <p style="white-space: pre">Edit or paste LaTeX code here. Focus the editor with the <strong>F4</strong> key.</p> QTextEdit::AutoNone true true QTextEdit::WidgetWidth false false 2 0 0 Clear the above field Clicking this button is a utility to clear the LaTeX code entry field above :/pics/clearedit.svg:/pics/clearedit.svg 0 0 Clear the above field and set the default style Clicking this button is a utility to clear the LaTeX code entry field above :/pics/clear.svg:/pics/clear.svg 0 0 <p style="white-space: pre">Evaluate LaTeX Expression [<strong>Shift-Enter</strong>]</p> Render the above <i>LaTeX</i> formula as an image, which will be displayed in the label below. &Run LaTeX :/pics/evaluate.svg:/pics/evaluate.svg Shift+Return, Ctrl+Return true 0 0 <p style="white-space: pre">Show Latex Symbols palette [<strong>F7</strong>]</p> Clicking this button opens a dialog allowing you to view and select LaTeX symbols the codes of which you may not know by heart. :/pics/symbols.svg:/pics/symbols.svg F7 true 0 0 <p style="white-space: pre">Show Library [<strong>F8</strong>]</p> Clicking this button opens the KLatexFormula Library which includes History (previously evaluated formulas) and Archive where you can store tagged equations. :/pics/library.svg:/pics/library.svg F8 true 0 0 <p style="white-space: pre">Toggle shrinked/expanded mode [<strong>F5</strong>]</p> Switches to expanded mode or back to shrinked mode. In expanded mode you get to choose more options. :/pics/switchexpanded.svg:/pics/switchexpanded.svg F5 QFrame::NoFrame QFrame::Plain 1 1 1 1 6 0 0 0 &DRAG 0 0 &COPY Alt+Y 0 0 Save formula to disk &SAVE Qt::Vertical QSizePolicy::Expanding 20 5 99 0 280 75 true The resulting image will be displayed here Here you can see the image you get after evaluating your LaTeX code. false QFrame::NoFrame QFrame::Plain 0 0 false 0 0 0 0 0 0 0 Qt::Horizontal 5 5 0 0 <p style="white-space: pre">Show a larger preview [<strong>F2</strong>]</p> :/pics/showpreview.svg:/pics/showpreview.svg Qt::Horizontal QSizePolicy::Fixed 6 10 0 0 <p style="white-space: pre">Select the export profile to use for Copy and Drag operations</p> :/pics/exportprofile.svg:/pics/exportprofile.svg <p style="white-space: pre">Quit KLatexFormula [<strong>Ctrl-Q</strong>]</p> Exit KLatexFormula Quit :/pics/closehide.svg:/pics/closehide.svg 1 0 ShowHide 4 3 3 3 3 QTabWidget::North 0 LaTeX 11 6 11 6 11 Check this to use a LaTeX math mode Use &Math mode: true 0 0 true \[ ... \] $ ... $ \begin{align*} ... \end{align*} \begin{eqnarray*} ... \end{eqnarray*} Qt::Vertical 20 40 Font: Colors 4 5 4 Fore/Background: false 54 30 30 20 false false 54 30 30 20 true Transparent false Qt::Horizontal QSizePolicy::Fixed 3 20 Font Size: (default) pt 0 120 11 Qt::Horizontal Preamble 11 6 11 6 0 0 LaTeX preamble: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop false 0 0 8 false Image 10 6 6 Qt::Vertical 118 16 Override settings margins true 6 4 6 3 QFrame::NoFrame QFrame::Plain 3 3 3 3 0 2 Top: 2 -9999.000000000000000 9999.000000000000000 1.000000000000000 0.000000000000000 Left: 2 -9999.000000000000000 9999.000000000000000 1.000000000000000 0.000000000000000 Right: 2 -9999.000000000000000 9999.000000000000000 1.000000000000000 0.000000000000000 2 -9999.000000000000000 9999.000000000000000 1.000000000000000 0.000000000000000 Bottom: Postscript Point=pt=1;Millimeter=mm=2.835;Centimeter=cm=28.35;1/8 th inch=1/8 in=9;Inch=in=72 Units: 4 0 DPI Resolution: false 0 0 Presets 10 10000 50 1200 Scale Vector Formats: false % 99999.990000000005239 20.000000000000000 100.000000000000000 Qt::Horizontal Script 1 0 User Script: 2 0 View user script log ... Qt::Vertical QSizePolicy::Fixed 20 3 Qt::Vertical QSizePolicy::Fixed 10 2 0 0 :/pics/refresh.png:/pics/refresh.png 0 0 :/pics/info.png:/pics/info.png QFrame::NoFrame QFrame::Plain 0 0 true Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 0 0 110 170 <no user script selected or no input to script> Qt::AlignCenter true 5 Qt::Horizontal Qt::Horizontal 5 1 0 Load a previously saved style St&yle Alt+L 1 0 Edit KLatexFormula settings Settings... Alt+N Qt::Horizontal 40 20 0 0 Edit KLatexFormula settings :/pics/help.svg:/pics/help.svg F1 High Resolution (1200) Very good resolution Good Resolution (600) Pretty good resolution Medium Resolution (300) Medium resolution Low Resolution (150) Low resolution true Insert Symbol <p style="white-space: pre">Show Latex Symbols palette [<strong>F7</strong>]</p> true Show Library Show Library Browser Window :/pics/clearedit.png:/pics/clearedit.png Clear LaTeX Clear the LaTeX code field above :/pics/clear.png:/pics/clear.png Clear LaTeX and reset default style Clear the LaTeX field above, and reset the style to the default style KLFColorChooser QPushButton
klfcolorchooser.h
KLFLatexEdit QTextEdit
klflatexedit.h
KLFSideWidget QWidget
klfsidewidget.h
1
KLFUnitSpinBox QDoubleSpinBox
klfunitinput.h
setUnit(double) setUnitWithSuffix(double,QString)
KLFUnitChooser QComboBox
klfunitinput.h
unitChanged(double,QString) unitChanged(double)
KLFDisplayLabel QLabel
klfdisplaylabel.h
txtLatex btnClearLatex btnClearAll btnEvaluate btnSymbols btnLibrary btnExpand btnDrag btnCopy btnSave btnShowBigPreview btnSetExportProfile btnQuit tabsOptions colFg colBg chkMathMode cbxMathMode cbxLatexFont spnLatexFontSize txtPreamble btnDPIPresets spnDPI chkVectorScale spnVectorScale gbxOverrideMargins cbxMarginsUnit spnMarginTop spnMarginRight spnMarginBottom spnMarginLeft cbxUserScript btnUserScriptInfo btnUserScriptReload scrUserScriptInput btnShowUserScriptLog btnLoadStyle btnSettings btnHelp chkMathMode toggled(bool) cbxMathMode setEnabled(bool) 549 110 764 144 chkVectorScale toggled(bool) spnVectorScale setEnabled(bool) 561 68 561 68 cbxMarginsUnit unitChanged(double,QString) spnMarginTop setUnitWithSuffix(double,QString) 561 73 561 73 cbxMarginsUnit unitChanged(double,QString) spnMarginRight setUnitWithSuffix(double,QString) 561 73 561 73 cbxMarginsUnit unitChanged(double,QString) spnMarginBottom setUnitWithSuffix(double,QString) 561 73 561 73 cbxMarginsUnit unitChanged(double,QString) spnMarginLeft setUnitWithSuffix(double,QString) 561 73 561 73 btnClearAll clicked() aClearAll trigger() 99 201 -1 -1 btnClearLatex clicked() aClearLatex trigger() 39 201 -1 -1 btnSetExportProfile clicked() btnSetExportProfile showMenu() 415 307 424 314
klatexformula-4.1.0/src/klfsymboleditor.ui000644 000765 000024 00000022051 13660527435 021721 0ustar00philippestaff000000 000000 KLFSymbolEditor 0 0 403 503 Form 75 true Symbol Editor Qt::AlignCenter 0 Symbol Symbol Latex Code: Has square-bracketed argument Number of arguments: 0 10 LaTeX code for preview 0 0 Preamble <packages list> 0 0 0 Qt::Horizontal QSizePolicy::Preferred 59 20 0 0 Add Qt::Vertical QSizePolicy::Preferred 20 40 Qt::Vertical QSizePolicy::Preferred 20 20 0 0 Additional Preamble Definitions Qt::Horizontal 1 QLayout::SetFixedSize Preview: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 280 80 280 80 QFrame::Panel QFrame::Sunken Qt::PlainText Qt::Horizontal QSizePolicy::Preferred 18 20 QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset|QDialogButtonBox::Save KLFLatexEdit QTextEdit
klflatexedit.h
klatexformula-4.1.0/src/modeltest.h000644 000765 000024 00000004447 13660527435 020333 0ustar00philippestaff000000 000000 /**************************************************************************** ** ** Copyright (C) 2007 Trolltech ASA. All rights reserved. ** ** This file is part of the Qt Concurrent project on Trolltech Labs. ** ** This file may be used under the terms of the GNU General Public ** License version 2.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of ** this file. Please review the following information to ensure GNU ** General Public Licensing requirements will be met: ** http://www.trolltech.com/products/qt/opensource.html ** ** If you are unsure which license is appropriate for your use, please ** review the following information: ** http://www.trolltech.com/products/qt/licensing.html or contact the ** sales department at sales@trolltech.com. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ****************************************************************************/ #ifndef MODELTEST_H #define MODELTEST_H #ifdef KLF_DEBUG_USE_MODELTEST // for doxygen to skip these files #include #include #include class ModelTest : public QObject { Q_OBJECT public: ModelTest(QAbstractItemModel *model, QObject *parent = 0); private Q_SLOTS: void nonDestructiveBasicTest(); void rowCount(); void columnCount(); void hasIndex(); void index(); void parent(); void data(); protected Q_SLOTS: void runAllTests(); void layoutAboutToBeChanged(); void layoutChanged(); void rowsAboutToBeInserted(const QModelIndex &parent, int start, int end); void rowsInserted(const QModelIndex & parent, int start, int end); void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); void rowsRemoved(const QModelIndex & parent, int start, int end); private: void checkChildren(const QModelIndex &parent, int currentDepth = 0); QAbstractItemModel *model; struct Changing { QModelIndex parent; int oldSize; QVariant last; QVariant next; }; QStack insert; QStack remove; bool fetchingMore; QList changing; }; #endif #endif klatexformula-4.1.0/src/klfwhatsnewdialog.ui000644 000765 000024 00000013063 13660527435 022230 0ustar00philippestaff000000 000000 KLFWhatsNewDialog 0 0 563 408 What's New In This Version of KLatexFormula :/pics/klatexformula-64.png:/pics/klatexformula-64.png QDialog#KLFWhatsNewDialog .QWidget#wMain { background-image: url(:/pics/help_dialog_bg.svg); background-clip: padding; } QDialog#KLFWhatsNewDialog .QTextBrowser#txtDisplay { border: 1px solid black; color: rgb(0, 0, 0); background-color: rgba(255, 255, 255, 200); } false 1 1 1 5 1 10 0 10 0 0 0 0 1 0 Qt::Horizontal QSizePolicy::Fixed 150 20 400 300 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'.SF NS Text'; font-size:13pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:10pt;"><br /></p></body></html> false false Qt::Horizontal 273 20 200 0 OK :/pics/ok.png:/pics/ok.png true Qt::Horizontal QSizePolicy::Fixed 80 20 txtDisplay btnOk btnOk clicked() KLFWhatsNewDialog accept() 516 485 314 505 klatexformula-4.1.0/src/klflibview.h000644 000765 000024 00000135073 13660527435 020471 0ustar00philippestaff000000 000000 /*************************************************************************** * file klflibview.h * This file is part of the KLatexFormula Project. * Copyright (C) 2011 by Philippe Faist * philippe.faist at bluewin.ch * * * 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 of the License, 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., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ /* $Id$ */ #ifndef KLFLIBVIEW_H #define KLFLIBVIEW_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace KLFLib { enum RestoreMode { RestoreLatex = 0x0001, RestoreStyle = 0x0002, RestoreLatexAndStyle = RestoreLatex|RestoreStyle, RestoreAll = 0xFFFF }; }; //! A view widget to display a library resource's contents /** A base API for a widget that will display a KLFLibResourceEngine's contents. * For example one could create a QTreeView and display the contents in there * (that's what KLFLibDefaultView does...). * * \note This class subclasses QWidget because it makes uses of signals and slots. * Before editing this file to change that, think before removing that inheritance * or muting it to a QObject (subclasses will eventually want to inherit QWidget), * no multiple QObject inheritance please! * * \note Subclasses should emit the \ref resourceDataChanged() signal AFTER they * refresh after a resource data change. * * Note: The operationStartReportingProgress() signal is purposed for when long update * operations are necessary. It is to be used by subclasses exactly like in * KLFLibResourceEngine. * * \warning The design of this class with a \ref setResourceEngine() function makes it * unsafe to blindly assume a non-NULL resource engine pointer at all times. Check * the pointer before using it! See \ref validResourceEngine(). * * If the reimplementation of this view can be searched with a KLFSearchBar, reimplement * searchable() to return a KLFPosSearchable object for this view. */ class KLF_EXPORT KLFAbstractLibView : public QWidget { Q_OBJECT public: KLFAbstractLibView(QWidget *parent); virtual ~KLFAbstractLibView() { } virtual KLFLibResourceEngine * resourceEngine() const { return pResourceEngine; } //! Display Resource URL. NOT exactly like KLFLibResourceEngine::url() ! /** Returns an URL describing exactly what is shown to user, based on the resource * engine's URL. * * \warning This does not simply return resourceEngine()->url(). It returns * in the URL exactly the information that is displayed to user. For example, a * view that can handle displaying all sub-resources will NOT include the default * sub-resource in its URL, however a view displaying only the default sub-resource * will include a "klfDefaultSubResource" query item to distinguish it from another * view acting on the same base URL but displaying a different sub-resource. */ virtual QUrl url() const = 0; //! Compare this resource view's URL to another URL /** Compares the URL of the resource we are viewing with the URL \c other, and * returns an OR-ed combination of enum KlfUrlCompareFlag values of URL-comparision * tests that have turned out to be true (see KlfUrlCompareFlag for a list * of tests). * * This function is supposed to answer to the following questions, each a condition * as whether to return a URL comparation flag or not: * - flag \c KlfUrlCompareEqual: does this view show the same information as a view * whose URL would be \c other ? * - flag \c KlfUrlCompareLessSpecific: does this view show _MORE_ information than * the \c other view ("less specific information" <=> "shows more") ? * - flag \c KLFUrlCompareMoreSpecific: does this view show _LESS_ information than * the \c other view ? * - flag \c KLFUrlComapreBaseEqual: does this view show the same resource as the * \c other view, but possibly does not the same specific information, eg. not the * same sub-resource. * * The \c interestFlags is a binary OR'ed value of KlfUrlCompareFlag values of tests * to be performed. Any flag that is set in \c interestFlags indicates that the return * value of this function, when binary-AND'ed with that flag, is the result (T or F) * of the test the flag stands for. However, if a flag is not set in \c interestFlags, * its state in the return value by this function is undefined. * * See also klfUrlCompare(). */ virtual uint compareUrlTo(const QUrl& other, uint interestFlags = 0xFFFFFFFF) const = 0; //! Returns TRUE if a non-\c NULL resource engine has been set inline bool validResourceEngine() const { return pResourceEngine != NULL; } virtual void setResourceEngine(KLFLibResourceEngine *resource); /** Subclasses should return a list of entries that have been selected by the user. */ virtual KLFLibEntryList selectedEntries() const = 0; /** Subclasses should return a list of resource-entry-IDs that have been selected by * the user. */ virtual QList selectedEntryIds() const = 0; /** Subclasses may add items to the context menu by returning them in this function. * \param pos is the position relative to widget where the menu was requested. * * \note The view itself does not handle context menus. This function is provided * for whichever class uses this view to add these actions when that class creates * a context menu. * * The default implementation returns an empty list. */ virtual QList addContextMenuActions(const QPoint& pos); /** Saves the current GUI state (eg. column widths and order, etc.) */ virtual QVariantMap saveGuiState() const = 0; /** Restores the state described in \c state (which was previously, possibly in another * session, returned by \ref saveGuiState()) */ virtual bool restoreGuiState(const QVariantMap& state) = 0; /** Subclasses should reimplement this function to return a list of all known categories * to suggest to the user, eg. in a completion list for an editable combo box to edit * categories. */ virtual QStringList getCategorySuggestions() = 0; virtual KLFPosSearchable * searchable() { return NULL; } signals: /** Is emitted (by subclasses) when a latex entry is selected to be restored (eg. the entry was * double-clicked). * * \param entry is the data to restore * \param restoreflags provides information on which part of \c entry to restore. See the * possible flags in \ref KLFLib::RestoreMode. */ void requestRestore(const KLFLibEntry& entry, uint restoreflags = KLFLib::RestoreLatexAndStyle); /** Is emitted (by subclasses) when the view wants the main application (or the framework that uses * this class) to restore the given style \c style. No latex is to be restored. */ void requestRestoreStyle(const KLFStyle& style); /** Subclasses must emit this signal AFTER they have refreshed. */ void resourceDataChanged(const QList& entryIdList); /** Emitted when the selection has changed, eg. user selected or deselected some entries. */ void entriesSelected(const KLFLibEntryList& entries); /** Subclasses should emit this signal with lists of categories they come accross, * so that the editor can suggest these as completions upon editing category */ void moreCategorySuggestions(const QStringList& categorylist); /** Emitted by subclasses to announce the beginning of a long operation during which progress * will be reported through the given \c progressReporter. * * Should be used in the same way as KLFLibResourceEngine::operationStartReportingProgress(). */ void operationStartReportingProgress(KLFProgressReporter *progressReporter, const QString& descriptiveText); public slots: virtual void updateResourceEngine() = 0; virtual void updateResourceProp(int propId) = 0; virtual void updateResourceData(const QString& subres, int modifyType, const QList& entryIdList) = 0; /** Default implementation calls updateResourceEngine() */ virtual void updateResourceDefaultSubResourceChanged(const QString& newSubResource); /** Subclasses should reimplement to update the given property to the given value on all * library entries that are selected by the user. (They have to actually perform the change * in the resource, eg with KLFLibResourceEngine::changeEntries()). * * \note The view does not have to garantee that selection is preserved. */ // virtual bool writeEntryProperty(int property, const QVariant& value) = 0; /* * Provides a reasonable default implementation that should suit for most purposes. */ // virtual bool writeEntryCategory(const QString& category) // { return writeEntryProperty(KLFLibEntry::Category, category); } /* * Provides a reasonable default implementation that should suit for most purposes. */ // virtual bool writeEntryTags(const QString& tags) // { return writeEntryProperty(KLFLibEntry::Tags, tags); } // virtual bool deleteSelected(bool requireConfirm = true); // virtual bool insertEntries(const KLFLibEntryList& entries); /* * Provides a reasonable default implementation that should suit for most purposes. */ // virtual bool insertEntry(const KLFLibEntry& entry) // { return insertEntries(KLFLibEntryList() << entry); } /** Subclasses must reimplement to select the given entries in the view. * * \returns TRUE on success. If the operation was not possible (eg. one ID is invalid/not * displayed, view does not support multiple selections whilst idList.size()>1, etc.) then * this function should return FALSE. */ virtual bool selectEntries(const QList& idList) = 0; /** Collects the necessary information and emits \ref requestRestore() */ virtual void restore(uint restoreFlags = KLFLib::RestoreLatexAndStyle) = 0; /** Provides a reasonable default implementation that should suit for most purposes. */ virtual void restoreWithStyle() { restore(KLFLib::RestoreLatexAndStyle); } /** Provides a reasonable default implementation that should suit for most purposes. */ virtual void restoreLatexOnly() { restore(KLFLib::RestoreLatex); } /** Called by the owner of the view. This function fetches category suggestions * (by calling the virtual getCategorySuggestions() reimplemented by subclasses) * and emits the signal moreCategorySuggestions(). * * Subclasses need not reimplement this function. */ virtual void wantMoreCategorySuggestions(); private: KLFLibResourceEngine *pResourceEngine; }; // ----------------- class KLF_EXPORT KLFLibViewFactory : public QObject { Q_OBJECT public: KLFLibViewFactory(const QStringList& viewTypeIdentifiers, QObject *parent = NULL); virtual ~KLFLibViewFactory(); /** A list of view type identifiers that this factory can create. * * Individual view widget types are identified by their "view type identifiers". They * are not meant to be human-readable (eg. "LibModel+CategoryTree" or whatever) */ virtual QStringList viewTypeIdentifiers() { return pViewTypeIdentifiers; } /** A translated string to be shown to user (in a choice box for ex.) for * the given view widget type. (eg. tr("Tree View")) */ virtual QString viewTypeTitle(const QString& viewTypeIdent) const = 0; /** \returns Whether this factory can create the given view widget for the given engine. * * This function may return false, for example if this widget factory creates a specialized * kind of widget that can only work with a given engine. */ virtual bool canCreateLibView(const QString& viewTypeIdent, KLFLibResourceEngine *engine) = 0; /** Create a library view with the given widget \c parent. The view should reflect the contents * given by the resource engine \c resourceEngine . */ virtual KLFAbstractLibView * createLibView(const QString& viewTypeIdent, QWidget *parent, KLFLibResourceEngine *resourceEngine) = 0; /** Returns the default view type identifier. Create this view if you don't have any idea * which view you prefer. * * This actually returns the first view type identifier of the first registered factory. */ static QString defaultViewTypeIdentifier(); /** Returns the factory that can handle the URL scheme \c urlScheme, or NULL if no such * factory exists (ie. has been registered). */ static KLFLibViewFactory *findFactoryFor(const QString& viewTypeIdentifier); /** Returns a combined list of all view type identifiers that the installed factories support. * ie. returns a list of all view type idents. we're capable of creating. */ static QStringList allSupportedViewTypeIdentifiers(); /** Returns the full list of installed factories. */ static QList allFactories() { return pRegisteredFactories; } private: QStringList pViewTypeIdentifiers; static void registerFactory(KLFLibViewFactory *factory); static void unRegisterFactory(KLFLibViewFactory *factory); static QList pRegisteredFactories; }; // -------------------- //! Create Associated Widgets to resources for Open/Create/Save actions /** * Widget-types are associated User Interface widgets with the actions * "Open Resource", "Create Resource" and "Save Resource To New Location". The * typical example would be to show a file dialog to enter a file name for * file-based resources (eg. Sqlite database). * * Widget-types are not directly one-to-one mapped to url schemes, because * for example multiple schemes can be accessed with the same open resource * parameters (eg. a file name for both "klf+sqlite" and "klf+legacy"). Thus * each scheme tells with Widget-Type it requires to associate with * "open" or "create new" or "save to" actions (eg. wtype=="LocalFile" * or similar logical name). * * The widget type is given by the * \ref KLFLibEngineFactory::correspondingWidgetType "Engine Factory". * * See also \ref KLFLibBasicWidgetFactory and \ref KLFLibEngineFactory. */ class KLF_EXPORT KLFLibWidgetFactory : public QObject, public KLFFactoryBase { Q_OBJECT public: /** A generalized way of passing arbitrary parameters for creating * new resources. * * See \ref KLFLibEngineFactory::createResource(). * * Some parameters have special meaning to the system; see * \ref retrieveCreateParametersFromWidget(). */ typedef KLFLibEngineFactory::Parameters Parameters; /** Simple constructor. Pass the parent object of this factory as parameter. This * can be the application object \c qApp for example. */ KLFLibWidgetFactory(QObject *parent); /** Finds the factory in the list of registered factories that can handle * the widget-type \c wtype. */ static KLFLibWidgetFactory * findFactoryFor(const QString& wtype); /** Returns a concatenated list of all supported widget types all registered factories * support. */ static QStringList allSupportedWTypes(); //! List the supported widget types that this factory can create /** eg. \c "LocalFile", ... */ virtual QStringList supportedTypes() const = 0; //! The human-readable label for this type of input /** Returns a human-readable label that describes the kind of input the widget type * \c wtype provides (eg. \c "Local File", \c "Remote Database Connection", etc.) */ virtual QString widgetTypeTitle(const QString& wtype) const = 0; /** Create a widget of logical type \c wtype (eg. "LocalFile", ...) that will prompt to user * for various data needed to open some given kind of library resource. It could be a file * selection widget, or a text entry for a hostname, etc. The widget should present data * corresponding to \c defaultlocation as default location if that parameter is non-empty. * * The widget should have a void readyToOpen(bool isReady) signal, that is emitted * to synchronize the enabled state of the "open" button. The widget should also have a * \c "readyToOpen" Qt property (static or dynamic, doesn't matter), that can be retrieved * with QObject::property(), that contains the current status of if the widget is ready to * open. * * The create widget should be a child of \c wparent. */ virtual QWidget * createPromptUrlWidget(QWidget *wparent, const QString& wtype, QUrl defaultlocation = QUrl()) = 0; /** Get the URL edited by user, that are stored in user-interface widgets in \c widget GUI. * \c widget is never other than a QWidget returned by \ref createPromptUrlWidget(). */ virtual QUrl retrieveUrlFromWidget(const QString& wtype, QWidget *widget) = 0; /** \returns whether this widget type (\c wtype) can create user-interface widgets to create * new resources (eg. a new library sqlite file, etc.) */ virtual bool hasCreateWidget(const QString& wtype) const; /** create a widget that will prompt to user the different settings for the new resource * that is about to be created. Do not reimplement this function if hasCreateWidget() * returns false. Information to which URL to store the resource should be included * in these parameters! * * The created widget should be child of \c wparent. */ virtual QWidget *createPromptCreateParametersWidget(QWidget *wparent, const QString& wtype, const Parameters& defaultparameters = Parameters()); /** Get the parameters edited by user, that are stored in \c widget GUI. * * Some special parameters are recognized by the system: * - param["klfScheme"]=url-scheme is MANDATORY: it tells the caller which kind * of scheme the resource should be. * - param["klfRetry"]=true will cause the dialog not to exit but re-prompt user to * possibly change his input (could result from user clicking "No" in a "Overwrite?" * dialog presented in a possible reimplementation of this function). * - param["klfCancel"]=true will cause the "create resource" process to be cancelled. * - Not directly recognized by the system, but a common standard: param["klfDefaultSubResource"] * is the name of the default sub-resource to create if the resource supports sub-resources, * and param["klfDefaultSubResourceTitle"] its title, if the resource supports sub-resource * properties. * * If an empty Parameters() is returned, it is also interpreted as a cancel operation. * */ virtual Parameters retrieveCreateParametersFromWidget(const QString& wtype, QWidget *widget); /** Returns TRUE if this widget type (\c wtype) can create user-interface widgets to save an * existing open resource as a new name (eg. to another (new) library sqlite file, etc.) */ virtual bool hasSaveToWidget(const QString& wtype) const; /** Creates a widget to prompt the user to save the resource \c resource to a different location, * by default \c defaultUrl. * * The created widget should be child of \c wparent. */ virtual QWidget *createPromptSaveToWidget(QWidget *wparent, const QString& wtype, KLFLibResourceEngine *resource, const QUrl& defaultUrl); /** Returns the URL to "save to copy", from the data entered by user in the widget \c widget, * which was previously returned by \ref createPromptSaveToWidget(). */ virtual QUrl retrieveSaveToUrlFromWidget(const QString& wtype, QWidget *widget); private: static KLFFactoryManager pFactoryManager; }; // ----------------- class KLFLibModelCache; /** \brief Model for Item-Views displaying a library resource's contents * * The Model can morph into different forms, for simulating various common & useful * displays (chronological list (history), category/tags tree (archive), maybe icons * in the future, ...). * */ class KLF_EXPORT KLFLibModel : public QAbstractItemModel { Q_OBJECT public: enum FlavorFlag { LinearList = 0x0001, IconViewList = LinearList, CategoryTree = 0x0002, DisplayTypeMask = 0x000f, GroupSubCategories = 0x1000 }; KLFLibModel(KLFLibResourceEngine *resource, uint flavorFlags = LinearList|GroupSubCategories, QObject *parent = NULL); virtual ~KLFLibModel(); enum ItemKind { EntryKind, CategoryLabelKind }; enum { ItemKindItemRole = Qt::UserRole+768, // = 800 in Qt 4.4, nice in debugging messages ;-) EntryContentsTypeItemRole, EntryIdItemRole, FullEntryItemRole, CategoryLabelItemRole, FullCategoryPathItemRole }; /** For example use * \code * model->data(index, KLFLibModel::entryItemRole(KLFLibEntry::Latex)).toString() * \endcode * to get LaTeX string for model index \c index. */ static inline int entryItemRole(int propertyId) { return (Qt::UserRole+788) + propertyId; } // = 820+propId /** inverse operation of \ref entryItemRole */ static inline int entryPropIdForItemRole(int role) { return role - (Qt::UserRole+788); } // = role - 820 virtual void setResource(KLFLibResourceEngine *resource); virtual KLFLibResourceEngine * resource() { return pResource; } virtual QUrl url() const; /** sets the flavor flags given by \c flags. Only flags masked by \c modify_mask * are affected. Examples: * \code * // Display type set to LinearList. GroupSubCategories is unchanged. * m->setFlavorFlags(KLFLibModel::LinearList, KLFLibModel::DisplayTypeMask); * // Set, and respectively unset the group sub-categories flag (no change to other flags) * m->setFlavorFlags(KLFLibModel::GroupSubCategories, KLFLibModel::GroupSubCategories); * m->setFlavorFlags(0, KLFLibModel::GroupSubCategories); * \endcode */ virtual void setFlavorFlags(uint flags, uint modify_mask = 0xffffffff); virtual uint flavorFlags() const; inline uint displayType() const { return flavorFlags() & DisplayTypeMask; } /** ensures that the cache nodes of the given index list are not 'minimalist' */ virtual void prefetch(const QModelIndexList& index) const; virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; virtual Qt::ItemFlags flags(const QModelIndex& index) const; virtual bool hasChildren(const QModelIndex &parent = QModelIndex()) const; virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; virtual bool hasIndex(int row, int column, const QModelIndex &parent = QModelIndex()) const; virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; virtual QModelIndex parent(const QModelIndex &index) const; virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; virtual bool canFetchMore(const QModelIndex& parent) const; virtual void fetchMore(const QModelIndex& parent); virtual Qt::DropActions supportedDropActions() const; virtual QStringList mimeTypes() const; virtual QMimeData *mimeData(const QModelIndexList& indexes) const; virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex& parent); enum { DropWillAccept = 0x0001, DropWillCategorize = 0x0002, DropWillMove = 0x0004 }; virtual uint dropFlags(QDragMoveEvent *event, QAbstractItemView *view); virtual QImage dragImage(const QModelIndexList& indexes); virtual int entryColumnContentsPropertyId(int column) const; virtual int columnForEntryPropertyId(int entryPropertyId) const; virtual bool isDesendantOf(const QModelIndex& child, const QModelIndex& ancestor); virtual QStringList categoryList() const; virtual void updateData(const QList& entryIdList, int modifyType); //! Call repeatedly to walk all indexes (once each exactly, first column only) virtual QModelIndex walkNextIndex(const QModelIndex& cur); //! Call repeatedly to walk all indexes in model in reverse order virtual QModelIndex walkPrevIndex(const QModelIndex& cur); virtual KLFLib::entryId entryIdForIndex(const QModelIndex& index) const; virtual QModelIndex findEntryId(KLFLib::entryId eid) const; virtual QList entryIdForIndexList(const QModelIndexList& indexlist) const; virtual QModelIndexList findEntryIdList(const QList& eidlist) const; virtual int fetchBatchCount() const { return pFetchBatchCount; } //! notify the model that the entrySorter() settings were changed, and we need to re-sort. virtual void redoSort(); //! change the entrySorter accordingly and re-sort the model. virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder); //! The current KLFLibEntrySorter that sorts our items virtual KLFLibEntrySorter * entrySorter() { return pEntrySorter; } /** \warning The model will take ownership of the sorter and deleted in the destructor. */ virtual void setEntrySorter(KLFLibEntrySorter *entrySorter); signals: /** Announces the beginning of a long operation (used for updates in updateData()) */ void operationStartReportingProgress(KLFProgressReporter *progressReporter, const QString& descriptiveText); public slots: virtual QModelIndex searchFind(const QString& queryString, const QModelIndex& fromIndex = QModelIndex(), bool forward = true); virtual QModelIndex searchFindNext(bool forward); virtual void searchAbort(); // virtual bool changeEntries(const QModelIndexList& items, int property, const QVariant& value); // virtual bool insertEntries(const KLFLibEntryList& entries); // virtual bool deleteEntries(const QModelIndexList& items); virtual void completeRefresh(); /** how many items to fetch at a time when fetching preview and style (non-minimalist) */ virtual void setFetchBatchCount(int count) { pFetchBatchCount = count; } private: friend class KLFLibModelCache; KLFLibResourceEngine *pResource; unsigned int pFlavorFlags; int pFetchBatchCount; KLFLibModelCache *pCache; KLFLibEntrySorter *pEntrySorter; struct PersistentId { int kind; KLFLib::entryId entry_id; QString categorylabel_fullpath; int column; }; friend QDebug& operator<<(QDebug&, const PersistentId&); QList persistentIdList(const QModelIndexList& persistentindexlist); QModelIndexList newPersistentIndexList(const QList& persistentidlist); void startLayoutChange(bool withQtLayoutChangedSignal = true); void endLayoutChange(bool withQtLayoutChangedSignal = true); QModelIndexList pLytChgIndexes; QList pLytChgIds; void updateCacheSetupModel(); QString pSearchString; QModelIndex pSearchCurNode; bool pSearchAborted; bool dropCanInternal(const QMimeData *data); friend class KLFLibViewSearchable; KLF_DEBUG_DECLARE_ASSIGNABLE_REF_INSTANCE() ; }; // ----------------- class KLF_EXPORT KLFLibViewDelegate : public QAbstractItemDelegate { Q_OBJECT Q_PROPERTY(QSize previewSize READ previewSize WRITE setPreviewSize) ; public: /** Create a view delegate for displaying a KLFLibModel. * \param parent the (QObject-)parent of this object. */ KLFLibViewDelegate(QObject *parent); virtual ~KLFLibViewDelegate(); inline QSize previewSize() const { return pPreviewSize; } virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual bool editorEvent(QEvent *event,QAbstractItemModel *model, const QStyleOptionViewItem& option, const QModelIndex& index); virtual void paint(QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual void setEditorData(QWidget *editor, const QModelIndex& index) const; virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const; virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual void setSearchString(const QString& s) { pSearchString = s; } virtual void setSearchIndex(const QModelIndex& index) { pSearchIndex = index; } virtual void setSelectionModel(QItemSelectionModel *sm) { pSelModel = sm; } /** If the delegate paints items in a QTreeView, then pass a pointer to it here to display nice * selection markings under non-expanded tree items. Pass \c NULL to unset any previously set * QTreeView pointer. * * By default, the internal tree view pointer is set to NULL. */ virtual void setTheTreeView(QTreeView *theTreeView) { pTheTreeView = theTreeView; } // virtual void setIndexExpanded(const QModelIndex& index, bool isexpanded) { // pExpandedIndexes[QPersistentModelIndex(index)] = isexpanded; // } virtual bool autoBackgroundItems() const { return pAutoBackgroundItems; } virtual void setAutoBackgroundItems(bool autoBgItems) { pAutoBackgroundItems = autoBgItems; } virtual QColor autoBackgroundColor() const { return pAutoBackgroundColor; } virtual void setAutoBackgroundColor(const QColor& autoBgColor) { pAutoBackgroundColor = autoBgColor; } public slots: void setPreviewSize(const QSize& psize) { pPreviewSize = psize; } protected: struct PaintPrivate { QPainter *p; QBrush background; const QStyleOptionViewItem *option; bool isselected; QRect innerRectText; QRect innerRectImage; }; virtual void paintEntry(PaintPrivate *p, const QModelIndex& index) const; virtual void paintCategoryLabel(PaintPrivate *p, const QModelIndex& index) const; enum { PTF_HighlightSearch = 0x0001, PTF_HighlightSearchCurrent = 0x0002, PTF_SelUnderline = 0x0004, PTF_ForceRichTextRender = 0x0008, PTF_FontLarge = 0x0010, PTF_FontTT = 0x0020 }; virtual void paintText(PaintPrivate *p, const QString& text, uint flags = PTF_HighlightSearch) const; virtual bool indexHasSelectedDescendant(const QModelIndex& parent) const; virtual bool selectionIntersectsIndexChildren(const QItemSelection& selection, const QModelIndex& parent) const; /** implements the core of \ref indexHasSelectedDescendant. use that instead. */ virtual bool func_indexHasSelectedDescendant(const QModelIndex& parent, const QTime& timer, int timeLimitMs) const; private: QString pSearchString; QModelIndex pSearchIndex; QItemSelectionModel *pSelModel; QTreeView *pTheTreeView; //!< warning: this is possibly NULL! see \ref setTheTreeView() QSize pPreviewSize; bool pAutoBackgroundItems; QColor pAutoBackgroundColor; // QMap pExpandedIndexes; struct ColorRegion { ColorRegion(QTextCharFormat f = QTextCharFormat(), int s = -1, int l = 0) : fmt(f), start(s), len(l) { } QTextCharFormat fmt; int start; int len; bool operator<(const ColorRegion& other) const { return start < other.start; } }; friend QDebug& operator<<(QDebug&, const ColorRegion&); }; // ----------------- class KLFLibViewSearchable; /** An implementation of the KLFAbstractLibView viwer to view library resource contents in * so-called Category, List or Icon view modes. */ class KLF_EXPORT KLFLibDefaultView : public KLFAbstractLibView { Q_OBJECT Q_PROPERTY(bool autoBackgroundItems READ autoBackgroundItems WRITE setAutoBackgroundItems) ; Q_PROPERTY(QColor autoBackgroundColor READ autoBackgroundColor WRITE setAutoBackgroundColor) ; Q_PROPERTY(QListView::Flow iconViewFlow READ iconViewFlow WRITE setIconViewFlow) ; Q_PROPERTY(QSize previewSize READ previewSize WRITE setPreviewSize) ; public: enum ViewType { CategoryTreeView, ListTreeView, IconView }; KLFLibDefaultView(QWidget *parent, ViewType viewtype = CategoryTreeView); virtual ~KLFLibDefaultView(); virtual QUrl url() const; virtual uint compareUrlTo(const QUrl& other, uint interestFlags = 0xFFFFFFFF) const; inline QSize previewSize() const { return pDelegate->previewSize(); } bool groupSubCategories() const { return pGroupSubCategories; } virtual bool event(QEvent *e); virtual bool eventFilter(QObject *o, QEvent *e); virtual KLFLibEntryList selectedEntries() const; virtual QList selectedEntryIds() const; ViewType viewType() const { return pViewType; } virtual QList addContextMenuActions(const QPoint& pos); virtual QVariantMap saveGuiState() const; virtual bool restoreGuiState(const QVariantMap& state); //! The first index that is currently visible in the current scrolling position virtual QModelIndex currentVisibleIndex() const { return currentVisibleIndex(true); } //! The first (forward=TRUE) or last (forward=FALSE) currently visible index in scroll area virtual QModelIndex currentVisibleIndex(bool forward) const; bool autoBackgroundItems() const { return pDelegate->autoBackgroundItems(); } QColor autoBackgroundColor() const { return pDelegate->autoBackgroundColor(); } QListView::Flow iconViewFlow() const; virtual QStringList getCategorySuggestions(); virtual KLFPosSearchable * searchable(); public slots: // virtual bool writeEntryProperty(int property, const QVariant& value); // virtual bool deleteSelected(bool requireConfirmation = true); // virtual bool insertEntries(const KLFLibEntryList& entries); virtual bool selectEntries(const QList& idList); virtual void restore(uint restoreflags = KLFLib::RestoreLatexAndStyle); virtual void showColumns(int propIdColumn, bool show); virtual void sortBy(int propIdColumn, Qt::SortOrder sortorder); /** Selects all items in the view, fetching all necessary items (this can be slow). If \c expandItems * is TRUE, then all items in this view (category labels) are expanded (no effect if this view is * not a tree view). */ virtual void slotSelectAll(bool expandItems = false); virtual void slotRefresh(); virtual void slotRelayoutIcons(); void setPreviewSize(const QSize& size) { pDelegate->setPreviewSize(size); } void setAutoBackgroundItems(bool on) { pDelegate->setAutoBackgroundItems(on); } void setAutoBackgroundColor(const QColor& c) { pDelegate->setAutoBackgroundColor(c); } /** \brief Sets the icon view flow, see QListView::Flow. * * Has no effect if our view type is not icon view. */ void setIconViewFlow(QListView::Flow flow); /** \warning This function takes effect upon the next change of resource engine, ie the next * call of \ref KLFAbstractLibView::setResourceEngine() */ void setGroupSubCategories(bool yesOrNo) { pGroupSubCategories = yesOrNo; } void updateDisplay(); protected: virtual void updateResourceEngine(); virtual void updateResourceProp(int propId); virtual void expandRootNice(); virtual void updateResourceData(const QString& subRes, int modifyType, const QList& entryIdList); virtual void updateResourceOwnData(const QList& entryIdList); virtual void showEvent(QShowEvent *event); enum SelectAllFlags { ExpandItems = 0x01, NoSignals = 0x02 } ; protected slots: void slotViewSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected); /** Selects all children of \c parent (by default a QModelIndex(), so this function selects * all items). * * selectFlags is an OR'ed combination of SelectAllFlags. If ExpandItems is set then all items * in the view are expanded (no effect if the * view is not a tree view). */ virtual void slotSelectAll(const QModelIndex& parent, uint selectFlags); void slotViewItemClicked(const QModelIndex& index); void slotEntryDoubleClicked(const QModelIndex& index); void slotShowColumnSenderAction(bool showCol); // called from model void slotResourceModelReset(); void slotResourceDataChanged(const QModelIndex& topLeft, const QModelIndex& botRight); void slotPreviewSizeFromActionSender(); void slotPreviewSizeActionsRefreshChecked(); private: ViewType pViewType; QAbstractItemView *pView; KLFLibViewDelegate *pDelegate; KLFLibModel *pModel; KLFLibViewSearchable *pSearchable; bool pGroupSubCategories; QList pCommonActions; QList pShowColumnActions; QMenu *pPreviewSizeMenu; QList pIconViewActions; QList pViewActionsWithShortcut; bool pEventFilterNoRecurse; QModelIndexList selectedEntryIndexes() const; bool func_selectAll(const QModelIndex& parent, uint flags, QTime *tm, KLFDelayedPleaseWaitPopup *pleaseWait); friend class KLFLibViewSearchable; protected: KLF_DEBUG_DECLARE_REF_INSTANCE( QFileInfo(url().path()).fileName()+":" +(resourceEngine()?resourceEngine()->defaultSubResource():"[NULL]") +"|viewtype="+QString::number(pViewType) ) ; }; // ----------------- class KLF_EXPORT KLFLibDefaultViewFactory : public KLFLibViewFactory { Q_OBJECT public: KLFLibDefaultViewFactory(QObject *parent = NULL); virtual ~KLFLibDefaultViewFactory() { } virtual QString viewTypeTitle(const QString& viewTypeIdent) const; virtual bool canCreateLibView(const QString& /*viewTypeIdent*/, KLFLibResourceEngine */*engine*/) { return true; } virtual KLFAbstractLibView * createLibView(const QString& viewTypeIdent, QWidget *parent, KLFLibResourceEngine *resourceEngine); }; // ----------------- namespace Ui { class KLFLibOpenResourceDlg; class KLFLibCreateResourceDlg; class KLFLibResPropEditor; class KLFLibNewSubResDlg; }; /** \brief Dialog prompting user to choose a resource and a sub-resource to open. */ class KLF_EXPORT KLFLibOpenResourceDlg : public QDialog { Q_OBJECT public: KLFLibOpenResourceDlg(const QUrl& defaultlocation = QUrl(), QWidget *parent = 0); virtual ~KLFLibOpenResourceDlg(); virtual QUrl url() const; static QUrl queryOpenResource(const QUrl& defaultlocation = QUrl(), QWidget *parent = 0); protected slots: virtual void updateReadyToOpenFromSender(bool isready); virtual void updateReadyToOpen(); protected: virtual QUrl retrieveRawUrl() const; private: Ui::KLFLibOpenResourceDlg *pUi; QAbstractButton *btnGo; }; // -- class KLF_EXPORT KLFLibCreateResourceDlg : public QDialog { Q_OBJECT public: typedef KLFLibEngineFactory::Parameters Parameters; KLFLibCreateResourceDlg(const QString& defaultWtype, QWidget *parent = 0); virtual ~KLFLibCreateResourceDlg(); virtual Parameters getCreateParameters() const; static KLFLibResourceEngine *createResource(const QString& defaultWtype, QObject *resourceParent, QWidget *parent = 0); public slots: virtual void accept(); virtual void reject(); protected slots: virtual void updateReadyToCreateFromSender(bool isready); virtual void updateReadyToCreate(); private: Ui::KLFLibOpenResourceDlg *pUi; QAbstractButton *btnGo; Parameters pParam; }; // -- class KLF_EXPORT KLFLibResPropEditor : public QWidget { Q_OBJECT public: KLFLibResPropEditor(KLFLibResourceEngine *resource, QWidget *parent = 0); virtual ~KLFLibResPropEditor(); public slots: bool apply(); protected slots: void slotResourcePropertyChanged(int propId); void slotSubResourcePropertyChanged(const QString& subResource, int propId); void on_btnAdvanced_toggled(bool on); void advPropEdited(QStandardItem *item); void advSubResPropEdited(QStandardItem *item); void on_cbxSubResource_currentIndexChanged(int newSubResItemIndex); void updateResourceProperties(); void updateSubResourceProperties(); void updateSubResources(const QString& curSubResource = QString()); private: KLFLibResourceEngine *pResource; bool pSuppSubRes; bool pSuppSubResProps; Ui::KLFLibResPropEditor *U; QStandardItemModel *pPropModel; QStandardItemModel *pSubResPropModel; QString curSubResource() const; }; class KLF_EXPORT KLFLibResPropEditorDlg : public QDialog { Q_OBJECT public: KLFLibResPropEditorDlg(KLFLibResourceEngine *resource, QWidget *parent = 0); virtual ~KLFLibResPropEditorDlg(); public slots: void applyAndClose(); void cancelAndClose(); private: KLFLibResPropEditor *pEditor; }; class KLF_EXPORT KLFLibNewSubResDlg : public QDialog { Q_OBJECT public: KLFLibNewSubResDlg(KLFLibResourceEngine *resource, QWidget *parent = 0); virtual ~KLFLibNewSubResDlg(); QString newSubResourceName() const; QString newSubResourceTitle() const; /** Prompt to create a sub-resource in resource \c resource. Then actually create the * sub-resource and return the name of the sub-resource that was created. * * Returns a null string in case of error or if the operation was canceled. */ static QString createSubResourceIn(KLFLibResourceEngine *resource, QWidget *parent = 0); /** Choose a nice internal name for the given title. Only "nice" characters will be * used in the return value, namely \c "[A-Za-z0-9_]". * * If \c title only consists of allowed characters, it is returned unchanged. */ static QString makeSubResInternalName(const QString& title); private slots: void on_txtTitle_textChanged(const QString& text); void on_txtName_textChanged(const QString& text); private: Ui::KLFLibNewSubResDlg *u; bool isAutoName; }; /** \brief Interface for guessing file schemes * * This class provides the basic interface for customizing known local file types, and * guessing their corresponding schemes. * * To add a scheme guesser, just reimplement this function and create an instance of it. * It will register automatically. * * To query [all guessers instances] the scheme to use for a filename, use * \ref KLFLibBasicWidgetFactory::guessLocalFileScheme(). */ class KLF_EXPORT KLFLibLocalFileSchemeGuesser { public: KLFLibLocalFileSchemeGuesser(); virtual ~KLFLibLocalFileSchemeGuesser(); //! Guess the appropriate scheme for handling the given file /** Reimplentations of this function must guess what scheme fileName is to be opened * with. * * By \a scheme we mean the URL scheme, ie. the scheme that the correct subclass of * \ref KLFLibEngineFactory reports being capable of opening (eg. \c "klf+sqlite"). * * In reimplementations of this function, first the filename extension should be checked. If * it is not known, then the file can be peeked into for magic headers. * * If the scheme cannot be guessed, then the reimplementation should return an empty string. * * \note the \c fileName does not necessarily exist. (keep that in mind before reporting * an error that you can't open the file to read a magic header). In that case, a * simple test should be performed on the file extension. */ virtual QString guessScheme(const QString& fileName) const = 0; }; //! Provides some basic UIs to access resources /** * Provides the following widget types for opening/creating/saving resources: * - Local file (\c "LocalFile"). Don't forget to add new file types with * \ref addLocalFileType() (this can be done e.g. in other engine factories' * constructor). * - planned, not yet implemented: remote DB connection with hostname/user/pass * information collecting (tentative name \c "RemoteHostUserPass"). * * \note Sub-resources are handled in \ref KLFLibOpenResourceDlg. * * \todo TODO: remote connections to eg. DB .......... */ class KLF_EXPORT KLFLibBasicWidgetFactory : public KLFLibWidgetFactory { Q_OBJECT public: //! A known local file type for \c KLFLibBasicWidgetFactory-created widgets struct LocalFileType { QString scheme; //!< eg. \c "klf+sqlite" QString filepattern; //!< eg. \c "*.klf.db" QString filter; //!< eg. \c "Local Library Database File (*.klf.db)" }; KLFLibBasicWidgetFactory(QObject *parent = NULL); virtual ~KLFLibBasicWidgetFactory(); virtual QStringList supportedTypes() const; virtual QString widgetTypeTitle(const QString& wtype) const; virtual QWidget * createPromptUrlWidget(QWidget *parent, const QString& scheme, QUrl defaultlocation = QUrl()); virtual QUrl retrieveUrlFromWidget(const QString& scheme, QWidget *widget); virtual bool hasCreateWidget(const QString& /*wtype*/) const { return true; } /** See \ref KLFLibWidgetFactory. * * Default parameters that can be given in \c defaultparameters: * - \c "Url" (type QUrl): the URL to start with */ virtual QWidget * createPromptCreateParametersWidget(QWidget *parent, const QString& scheme, const Parameters& defaultparameters = Parameters()); /** The parameters returned by this function depends on the \c wtype. * * Widget-type \c "LocalFile" * - \c "Filename" : the selected local file name * - \c "klfRetry", \c "klfScheme" as documented in * \ref KLFLibWidgetFactory::retrieveCreateParametersFromWidget(). */ virtual Parameters retrieveCreateParametersFromWidget(const QString& wtype, QWidget *widget); /** This function should be called for example in KLFLibEngineFactory subclasses' constructor * to inform this widget factory of local file types that are known by the various engine * factories. This is then eg. used to provide a useful filter choice in file dialogs. */ static void addLocalFileType(const LocalFileType& fileType); static QList localFileTypes(); /** Queries all the instantiated KLFLibLocalFileSchemeGuesser objects to see if one can recognize * the file \c fileName. The first scheme match found is returned. An empty QString is returned * if no guesser succeeded to recognize \c fileName. */ static QString guessLocalFileScheme(const QString& fileName); protected: static QList pLocalFileTypes; static QList pSchemeGuessers; friend class KLFLibLocalFileSchemeGuesser; /** This function adds a scheme guesser, ie. a functional sub-class of * \ref KLFLibLocalFileSchemeGuesser. The instance is NOT deleted after use. * \c schemeguesser could for example also sub-class QObject and set \c qApp as parent. */ static void addLocalFileSchemeGuesser(KLFLibLocalFileSchemeGuesser *schemeguesser); static void removeLocalFileSchemeGuesser(KLFLibLocalFileSchemeGuesser *schemeguesser); }; #endif klatexformula-4.1.0/src/klatexformula-64.png000644 000765 000024 00000001353 13660527435 021766 0ustar00philippestaff000000 000000 PNG  IHDRAA^ pHYs  tEXtSoftwareAdobe ImageReadyqe<xIDATxZё@  ;J;P+{s;}& Yo$o_^6m._WnZu*i 1N't;{<\.o1:u90qWѡT2~OEѨ5M:eyb܊4x<(rr E^{?@2 ӗ˅֜j } \ J @H,paqa$h)Mt9)$ȁ{>=^ATedz׃HzxסgQBMAK$%X #Wܿ 'SP bݴ1HTJxW Pm rb '= r4XK(W7t!'aۉB$Ac1hZAMAKaS Z)Ii :cA \оb<$90@:|!VMEIz%ys&=G:A]n= u]stF;4ڣ`RQfQ%-,'`@%/QMӘ,˔gziNc~C5G$$Ij0ٞs3ô00t?\nkUIENDB`klatexformula-4.1.0/src/klfexporter.h000644 000765 000024 00000023476 13660527435 020703 0ustar00philippestaff000000 000000 /*************************************************************************** * file klfexporter.h * This file is part of the KLatexFormula Project. * Copyright (C) 2016 by Philippe Faist * philippe.faist at bluewin.ch * * * 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 of the License, 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., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ /* $Id$ */ #ifndef KLFEXPORTER_H #define KLFEXPORTER_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include class KLFExporterManager; struct KLFExporterPrivate; /** \brief Abstract exporter of KLF output to some given format * * This helper class can be subclassed to implement exporting klatexformula output in a given * data format. * * Formats are given internal names which can be chosen arbitrarily. * Exporters know nothing of mime types, */ class KLF_EXPORT KLFExporter { public: KLFExporter(); virtual ~KLFExporter(); //! Name of the exporter (e.g. "pdf") virtual QString exporterName() const = 0; /** \brief Whether this exporter is suitable for saving to data file. * * Most exporters are suitable because they export the data itself in some particular * format. Other exporters however may be designed only for copy-paste or drag-drop, * for example if they refer to a temporary file (e.g. text/uri-list). */ virtual bool isSuitableForFileSave() const { return true; } /** \brief List of formats this exporter can export to (e.g. "pdf", "svg", "eps", "png@150dpi") * * The format name can be chosen freely, and does not have to coincide with a mime type * and/or filename extension(s). */ virtual QStringList supportedFormats(const KLFBackend::klfOutput& klfoutput) const = 0; /** \brief Return TRUE if the given format is supported * * * The default implementation simply returns * supportedFormats(klfoutput).contains(format), and should suffice in most * cases; you don't need to reimplement this function. * * However, in case you have many formats and depending on your use case, there may be a * more clever way of finding out whether a given format is supported than going through * the list of all supported formats. In such a case you can reimplement this function. */ virtual bool supports(const QString & format, const KLFBackend::klfOutput& klfoutput) const { return supportedFormats(klfoutput).contains(format); } /** \brief A huaman-readable title for this exporter and format (e.g. "PDF Vector Graphics") */ virtual QString titleFor(const QString & format) = 0; /** \brief The filename extension suitable to save this format from this exporter * (e.g. ["jpg","jpeg"]) * * Subclasses should reimplement. The base implementation returns an empty string list * and is only suitable for exporters which are not suitable for file saving (\ref * isSuitableForFileSave()). */ virtual QStringList fileNameExtensionsFor(const QString & format); /** \brief Get the data corresponding to the given klf output * * The \a param argument may be used to specify additional parameters to the exporter. * * Subclasses should not forget to call \ref clearErrorString() to clear any previously * set error. */ virtual QByteArray getData(const QString& format, const KLFBackend::klfOutput& klfoutput, const QVariantMap& param = QVariantMap()) = 0; //! Returns an error string describing the last error. QString errorString() const; /** \brief Set the exporter manager where other exporters can be looked up * */ void setExporterManager(KLFExporterManager * exporterManager) ; protected: //! Subclasses should call this method at the beginning of getData() void clearErrorString(); //! Subclasses should use this method in getData() to signify that an error occurred void setErrorString(const QString & errorString); /** \brief Subclasses may access the exporter manager to look for other exporters * * Some exporters may rely on other exporters to generate intermediate formats. Use the * exporter manager to look up other exporters. * * \warning This function might return a \a NULL pointer if no exporter-manager was set * for this instance. * * \warning It is the exporter's responsibility to avoid cyclic dependencies, which * would result in infinite loops. */ KLFExporterManager * getExporterManager() const; private: KLF_DECLARE_PRIVATE(KLFExporter) ; }; struct KLFExporterNameAndFormat { KLFExporterNameAndFormat(QString exporterName_ = QString(), QString format_ = QString()) : exporterName(exporterName_), format(format_) { } QString exporterName; QString format; }; Q_DECLARE_METATYPE(KLFExporterNameAndFormat) ; typedef QList KLFExporterNameAndFormatList; QDataStream & operator<<(QDataStream & stream, const KLFExporterNameAndFormat & ef); QDataStream & operator>>(QDataStream & stream, KLFExporterNameAndFormat & ef); struct KLFExporterManagerPrivate; class KLFExporterManager { public: KLFExporterManager(); virtual ~KLFExporterManager(); //! The manager takes ownership of \a exporter and will delete it once the manager is destroyed. void registerExporter(KLFExporter *exporter); void unregisterExporter(KLFExporter *exporter); KLFExporter* exporterByName(const QString & exporterName) const; QList exporterList(); //! Whether the given exporter name and format is supported for the given output bool supportsExporterNameAndFormat(const QString & exporterName, const QString & format, const KLFBackend::klfOutput & output) const; //! Whether one of the provided exporter name and format will be available for the given output bool supportsOneOfExporterNamesAndFormats(const KLFExporterNameAndFormatList & exporterNamesAndFormats, const KLFBackend::klfOutput & output, KLFExporterNameAndFormat * whichExporterNameAndFormat = NULL) const; //! Attempt to get data from the given exporter and given format, returns empty if not found QByteArray getDataByExporterNameAndFormat(const QString & exporterName, const QString & format, const KLFBackend::klfOutput & output, const QVariantMap & params = QVariantMap()) ; /** * Provide a list of pairs of an exporter name and a format. * * Returns the first successfully retreived data. */ QByteArray getDataByExporterNamesAndFormats(const KLFExporterNameAndFormatList & exporterNamesAndFormats, const KLFBackend::klfOutput & output, const QVariantMap & params, KLFExporterNameAndFormat * whichExporterNameAndFormat = NULL) ; private: KLF_DECLARE_PRIVATE( KLFExporterManager ) ; }; // ----------------------------------------------------------------------------- // user script definitions: struct KLFExportTypeUserScriptInfoPrivate; class KLF_EXPORT KLFExportTypeUserScriptInfo : public KLFUserScriptInfo { public: KLFExportTypeUserScriptInfo(const QString& userScriptPath); virtual ~KLFExportTypeUserScriptInfo(); struct Format : public KLFPropertizedObject { Format(); Format(const QString& formatName_, const QString& formatTitle_, const QStringList& fileNameExtensions_); virtual ~Format(); enum { FormatName = 0, FormatTitle, FileNameExtensions }; QString formatName() const; QString formatTitle() const; QStringList fileNameExtensions() const; }; enum ExportTypeProperties { Formats = 0, InputExportersFormats, HasStdoutOutput, MimeExportProfilesXmlFile, }; QStringList formats() const; KLFExporterNameAndFormatList inputExportersFormats() const; bool hasStdoutOutput() const; QString mimeExportProfilesXmlFile() const; QList formatList() const; Format getFormat(const QString & formatName) const; QVariant klfExportTypeInfo(int propId) const; QVariant klfExportTypeInfo(const QString& key) const; QStringList klfExportTypeInfosList() const; private: KLF_DECLARE_PRIVATE(KLFExportTypeUserScriptInfo) ; }; /** \brief A stripped-down version of the latex string, suitable as a human-readable * expression in plain text * * For example, \c "\vec{a}_\mathrm{xyz} = -\frac{1}{2}" becomes e.g. * \c "\vec{a}_{xyz} = -(1/2)". */ QString klfLatexToPseudoTex(QString latex); #endif klatexformula-4.1.0/src/klfstylemanager.cpp000644 000765 000024 00000021544 13660527435 022053 0ustar00philippestaff000000 000000 /*************************************************************************** * file klfstylemanager.cpp * This file is part of the KLatexFormula Project. * Copyright (C) 2011 by Philippe Faist * philippe.faist@bluewin.ch * * * 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 of the License, 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., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ /* $Id$ */ #include #include #include #include #include #include #include #include #include #include #include "klfstylemanager.h" Qt::ItemFlags KLFStyleListModel::flags(const QModelIndex& index) const { if (!index.isValid() || index.row() >= rowCount() || index.model() != this) return Qt::ItemIsDropEnabled; // we allow drops outside the items return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled; } QString KLFStyleListModel::styleName(int row) const { return data(index(row), Qt::DisplayRole).toString(); } void KLFStyleListModel::setStyleName(int row, const QString& newname) { setData(index(row), newname, Qt::DisplayRole); } Qt::DropActions KLFStyleListModel::supportedDropActions() const { return Qt::CopyAction; } QStringList KLFStyleListModel::mimeTypes() const { QStringList types; types << "application/x-klf-stylename"; return types; } QMimeData *KLFStyleListModel::mimeData(const QModelIndexList& indexes) const { QMimeData *mimeData = new QMimeData(); // can only drag ONE stylename if (indexes.size() > 1 || indexes.size() <= 0) { return mimeData; } QByteArray encodedData; QDataStream stream(&encodedData, QIODevice::WriteOnly); stream << styleName(indexes[0].row()); mimeData->setData("application/x-klf-stylename", encodedData); return mimeData; } bool KLFStyleListModel::dropMimeData(const QMimeData *mdata, Qt::DropAction action, int row, int column, const QModelIndex &parent) { if (action == Qt::IgnoreAction) return true; if (parent.isValid()) return false; if (!mdata->hasFormat("application/x-klf-stylename")) return false; if (column > 0) return false; if (row == -1) row = rowCount(); QByteArray encodedData = mdata->data("application/x-klf-stylename"); QDataStream stream(&encodedData, QIODevice::ReadOnly); QString newItem; stream >> newItem; // find style already existant in this list int k; for (k = 0; k < rowCount() && styleName(k) != newItem; ++k) ; if (k >= rowCount()) { fprintf(stderr, "WARNING: Ignoring drop of style named `%s' which was not already in list!\n", newItem.toLocal8Bit().constData()); return false; } // remove row at position k removeRows(k, 1); if (row > k) --row; // and insert our text at the right position insertRows(row, 1); setStyleName(row, newItem); emit internalMoveCompleted(k, row); return true; } // ------------------ KLFStyleManager::KLFStyleManager(KLFStyleList *stydata, QWidget *parent) : QWidget(parent, #ifdef KLF_WS_MAC Qt::Sheet #else Qt::Dialog #endif ) { u = new Ui::KLFStyleManager; u->setupUi(this); setObjectName("KLFStyleManager"); _styptr = stydata; _drag_item = 0; _drag_init_pos = QPoint(-1,-1); /* mDropIndicatorItem = 0; */ mActionsPopup = new QMenu(this); /** \todo ............ DYNAMIC LANGUAGE CHANGE STRINGS .................. */ actPopupDelete = mActionsPopup->addAction("", this, SLOT(slotDelete())); actPopupMoveUp = mActionsPopup->addAction("", this, SLOT(slotMoveUp())); actPopupMoveDown = mActionsPopup->addAction("", this, SLOT(slotMoveDown())); actPopupRename = mActionsPopup->addAction("", this, SLOT(slotRename())); u->btnActions->setMenu(mActionsPopup); mStyleListModel = new KLFStyleListModel(this); u->lstStyles->setModel(mStyleListModel); // populate style list slotRefresh(); // and set menu items enabled or not refreshActionsEnabledState(); connect(u->btnClose, SIGNAL(clicked()), this, SLOT(hide())); u->lstStyles->installEventFilter(this); connect(u->lstStyles, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showActionsContextMenu(const QPoint&))); connect(mStyleListModel, SIGNAL(internalMoveCompleted(int, int)), this, SLOT(slotModelMoveCompleted(int, int))); connect(u->lstStyles->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(refreshActionsEnabledState())); retranslateUi(false); } void KLFStyleManager::retranslateUi(bool alsoBaseUi) { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME); if (alsoBaseUi) u->retranslateUi(this); actPopupDelete->setText(tr("Delete Style")); actPopupMoveUp->setText(tr("Move up")); actPopupMoveDown->setText(tr("Move down")); actPopupRename->setText(tr("Rename style")); } KLFStyleManager::~KLFStyleManager() { } void KLFStyleManager::refreshActionsEnabledState() { int curidx = currentRow(); if (curidx != -1) { actPopupDelete->setEnabled(true); actPopupRename->setEnabled(true); actPopupMoveUp->setEnabled(curidx > 0); actPopupMoveDown->setEnabled(curidx < mStyleListModel->rowCount()-1); } else { actPopupDelete->setEnabled(false); actPopupRename->setEnabled(false); actPopupMoveUp->setEnabled(false); actPopupMoveDown->setEnabled(false); } } void KLFStyleManager::showActionsContextMenu(const QPoint& pos) { mActionsPopup->exec(u->lstStyles->mapToGlobal(pos)); } int KLFStyleManager::currentRow() { QModelIndexList sel = u->lstStyles->selectionModel()->selectedRows(); if (sel.size() == 0) return -1; if (sel.size() >= 2) { qWarning("Multiple style names selected! Expected Single Selection Policy!\n"); return -1; } return sel[0].row(); } void KLFStyleManager::slotDelete() { int r = currentRow(); if ( r == -1 ) return; if ( QMessageBox::question(this, tr("Erase style?"), tr("Are you sure you want to erase selected style?"), QMessageBox::Yes|QMessageBox::No, QMessageBox::No) == QMessageBox::Yes ) { _styptr->removeAt(r); mStyleListModel->removeRows(r, 1); } emit refreshStyles(); refreshActionsEnabledState(); } void KLFStyleManager::slotRename() { int r = currentRow(); if ( r == -1 ) return; QString newname = QInputDialog::getText(this, tr("Rename style"), tr("Enter new style name:"), QLineEdit::Normal, _styptr->at(r).name); if ( ! newname.isEmpty() ) { _styptr->operator[](r).name = newname; mStyleListModel->setStyleName(r, newname); } emit refreshStyles(); refreshActionsEnabledState(); } void KLFStyleManager::slotMoveUp() { int r = currentRow(); if ( r < 1 || r >= mStyleListModel->rowCount() ) return; QString s = mStyleListModel->styleName(r); mStyleListModel->setStyleName(r, mStyleListModel->styleName(r-1)); mStyleListModel->setStyleName(r-1, s); slotModelMoveCompleted(r, r-1); emit refreshStyles(); refreshActionsEnabledState(); } void KLFStyleManager::slotMoveDown() { int r = currentRow(); if ( r < 0 || r > mStyleListModel->rowCount() - 1 ) return; QString s = mStyleListModel->styleName(r); mStyleListModel->setStyleName(r, mStyleListModel->styleName(r+1)); mStyleListModel->setStyleName(r+1, s); slotModelMoveCompleted(r, r+1); emit refreshStyles(); refreshActionsEnabledState(); } void KLFStyleManager::slotModelMoveCompleted(int prev, int newpos) { KLFStyle sty = _styptr->takeAt(prev); _styptr->insert(newpos, sty); QModelIndex i = mStyleListModel->index(newpos); u->lstStyles->selectionModel()->select(i, QItemSelectionModel::ClearAndSelect); u->lstStyles->setCurrentIndex(i); emit refreshStyles(); refreshActionsEnabledState(); } void KLFStyleManager::slotRefresh() { QStringList list; for (int i = 0; i < _styptr->size(); ++i) { list << _styptr->at(i).name; } mStyleListModel->setStringList(list); } klatexformula-4.1.0/src/CMakeLists.txt000644 000765 000024 00000052546 13660527435 020725 0ustar00philippestaff000000 000000 # ######################################## # # CMake project file for klatexformula/src # # ######################################## # # $Id$ # ######################################## # # Rely on CMake utilities for fixing up bundle dependencies # if(KLF_MACOSX_BUNDLES) include(BundleUtilities) #include(KLFMacBundle) endif(KLF_MACOSX_BUNDLES) # Set up -DKLF_WS_ -DKLF_WS="..." to indicate window system in use add_definitions("-DKLF_WS=\"${KLF_WS}\"") string(TOUPPER "${KLF_WS}" klf_ws_uc) add_definitions("-DKLF_WS_${klf_ws_uc}") # include these subprojects... add_subdirectory(klftools) add_subdirectory(klfbackend) # klatexformula main GUI program # ------------------------------ if(KLF_BUILD_GUI) find_package(Qt5Sql REQUIRED) find_package(Qt5UiTools REQUIRED) find_package(Qt5LinguistTools REQUIRED) find_package(Qt5Svg REQUIRED) if(KLF_USE_DBUS) find_package(Qt5DBus REQUIRED) endif() if(KLF_WS STREQUAL "x11") find_package(Qt5X11Extras REQUIRED) endif() if(KLF_WS STREQUAL "win") find_package(Qt5WinExtras REQUIRED) endif() if(KLF_WS STREQUAL "mac") find_package(Qt5MacExtras REQUIRED) endif() # Sources set(klatexformula_SRCS klfconfig.cpp klflatexsymbols.cpp klfstyle.cpp klflibentryeditor.cpp klflibbrowser.cpp klflib.cpp klflibview.cpp klflibdbengine.cpp klfliblegacyengine.cpp klfexporter.cpp klfmime.cpp klfmainwin.cpp klfsettings.cpp klfstylemanager.cpp klfmain.cpp klfcmdiface.cpp klfuiloader.cpp main.cpp klfapp.cpp ) # Headers with QObject classes (needs moc) set(klatexformula_MOCHEADERS klflatexsymbols.h klflatexsymbols_p.h klflibentryeditor.h klflibbrowser.h klflibbrowser_p.h klflib.h klflibview.h klflibview_p.h klflibdbengine.h klflibdbengine_p.h klfliblegacyengine.h klfliblegacyengine_p.h klfmime.h # klfmime_p.h # klfexporter.h klfexporter_p.h klfmainwin.h klfmainwin_p.h klfsettings.h klfsettings_p.h klfstylemanager.h klfcmdiface.h klfuiloader_p.h klfautoupdater.h klfapp.h ) # UI Forms set(klatexformula_UIS klflatexsymbols.ui klflibbrowser.ui klflibentryeditor.ui klflibopenresourcedlg.ui klflibrespropeditor.ui klfliblocalfilewidget.ui klflibnewsubresdlg.ui klfmainwin.ui klfsettings.ui klfstylemanager.ui klfaboutdialog.ui klfwhatsnewdialog.ui klflibexportdialog.ui ) # Translations set(klatexformula_TSS i18n/klf_fr.ts i18n/klf_cs.ts i18n/klf_uk.ts ) # Resources set(klatexformula_QRCS klfres.qrc ) add_executable(klatexformula ${klatexformula_SRCS}) target_include_directories(klatexformula PUBLIC "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/klftools" "${CMAKE_CURRENT_SOURCE_DIR}/klfbackend") # Uis, Mocs, Qrcs qt5_wrap_ui(klatexformula_UIS_H ${klatexformula_UIS}) qt5_wrap_cpp(klatexformula_MOC_CPPS ${klatexformula_MOCHEADERS}) qt5_add_resources(klatexformula_QRC_CPPS ${klatexformula_QRCS}) target_sources(klatexformula PRIVATE ${klatexformula_UIS_H} ${klatexformula_MOC_CPPS} ${klatexformula_QRC_CPPS}) target_link_libraries(klatexformula Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Xml Qt5::Sql Qt5::Svg Qt5::UiTools klfbackend klftools) # Translations qt5_add_translation(klatexformula_QMS ${klatexformula_TSS}) if (KLF_LIBKLFTOOLS_STATIC) # so that main.cpp knows that it has to initialize klftools' resource "klftools.qrc" manually target_compile_definitions(klatexformula PRIVATE -DKLF_LIBKLFTOOLS_STATIC) endif() set(klatexformula_post_build_commands ) set(klatexformula_bundle_include_libs ) # Adjustments for certain platforms and options -- special features if(KLF_WS STREQUAL "win") target_sources(klatexformula PRIVATE mswin/klfwinclipboard.cpp ) target_link_libraries(klatexformula Qt5::WinExtras) endif() if(KLF_USE_WINSPARKLE) target_compile_definitions(klatexformula PUBLIC -DKLF_USE_WINSPARKLE -DKLF_WINSPARKLE_FEED_URL=\"${KLF_WINSPARKLE_FEED_URL}\") target_include_directories(${KLF_WINSPARKLE_DIR}) qt5_wrap_cpp(klatexformula_MOC_CPPS_winsparkle mswin/klfwinsparkleupdater.h) target_sources(klatexformula PRIVATE mswin/klfwinsparkleupdater.cpp ${klatexformula_MOC_CPPS_winsparkle} ) target_link_libraries(klatexformula "${KLF_WINSPARKLE_DIR}/WinSparkle.dll") endif() if(KLF_WS STREQUAL "mac") target_sources(klatexformula PRIVATE macosx/klfmacclipboard.cpp macosx/klfmainwin_mac.mm macosx/klfcmdifacedispatch_mac.mm ) target_link_libraries(klatexformula Qt5::MacExtras) target_link_libraries(klatexformula "-framework Cocoa") endif() if(KLF_USE_SPARKLE) target_compile_definitions(klatexformula PRIVATE -DKLF_USE_SPARKLE -DKLF_SPARKLE_FEED_URL=\"${KLF_SPARKLE_FEED_URL}\") target_include_directories(klatexformula PRIVATE ${KLF_SPARKLE_FRAMEWORK}/Headers) qt5_wrap_cpp(klatexformula_MOC_CPPS_sparkle macosx/klfsparkleupdater.h) target_sources(klatexformula PRIVATE macosx/klfsparkleupdater.mm ${klatexformula_MOC_CPPS_sparkle} # also include in the bundle: "${KLF_SPARKLE_DSA_PUBKEY}" ) target_link_libraries(klatexformula ${KLF_SPARKLE_FRAMEWORK}) endif() if(KLF_MACOSX_BUNDLES) target_sources(klatexformula PRIVATE # more stuff we may want to import/copy privately in the App bundle macosx/qt.conf macosx/klatexformula.icns ${KLF_INCLUDE_FONTS} klatexformula-16.png klatexformula-32.png klatexformula-64.png klatexformula-128.png klatexformula-256.png klatexformula-512.png klatexformula-1024.png ) if (KLF_USE_SPARKLE) # this is needed for inside the info.plist get_filename_component(KLF_SPARKLE_DSA_PUBKEY_BASENAME "${KLF_SPARKLE_DSA_PUBKEY}" NAME) endif () # Set up the application bundle under Mac OS X set_target_properties(klatexformula PROPERTIES MACOSX_BUNDLE true OUTPUT_NAME klatexformula MACOSX_BUNDLE_ICON_FILE klatexformula.icns MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/macosx/Info.plist.in" MACOSX_BUNDLE_INFO_STRING "KLatexFormula version ${KLF_VERSION}" MACOSX_BUNDLE_GUI_IDENTIFIER "org.klatexformula.klatexformula" MACOSX_BUNDLE_LONG_VERSION_STRING "${KLF_VERSION}" MACOSX_BUNDLE_SHORT_VERSION_STRING "${KLF_VERSION}" MACOSX_BUNDLE_BUNDLE_VERSION "${KLF_VERSION}" MACOSX_BUNDLE_BUNDLE_COPYRIGHT "Copyright (C) 2016 Philippe Faist" ) set_source_files_properties( klatexformula-16.png klatexformula-32.png klatexformula-64.png klatexformula-128.png klatexformula-256.png klatexformula-512.png klatexformula-1024.png macosx/klatexformula.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources" ) if(KLF_INCLUDE_FONTS) set_source_files_properties(${KLF_INCLUDE_FONTS} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources/fonts" ) endif() if(KLF_USE_SPARKLE) set_source_files_properties("${KLF_SPARKLE_DSA_PUBKEY}" PROPERTIES MACOSX_PACKAGE_LOCATION Resources ) endif() if(KLF_MACOSX_BUNDLE_EXTRAS) if(KLF_BUNDLE_QT_PLUGINS) foreach(qtplugintgt ${KLF_BUNDLE_QT_PLUGINS}) get_target_property(qtplugintgt_loc ${qtplugintgt} LOCATION) get_filename_component(qtplugindirfull ${qtplugintgt_loc} DIRECTORY) get_filename_component(qtplugintgt_fname ${qtplugintgt_loc} NAME) get_filename_component(qtplugindirname ${qtplugindirfull} NAME) #message("${qtplugintgt}: ${qtplugintgt_loc} ${qtplugindirname}") set(klatexformula_post_build_commands ${klatexformula_post_build_commands} COMMAND "${CMAKE_COMMAND}" "-E" "make_directory" "${CMAKE_CURRENT_BINARY_DIR}/klatexformula.app/Contents/plugins/${qtplugindirname}" COMMAND "${CMAKE_COMMAND}" "-E" "copy" "${qtplugintgt_loc}" "${CMAKE_CURRENT_BINARY_DIR}/klatexformula.app/Contents/plugins/${qtplugindirname}" ) set(klatexformula_bundle_include_libs ${klatexformula_bundle_include_libs} "${CMAKE_CURRENT_BINARY_DIR}/klatexformula.app/Contents/plugins/${qtplugindirname}/${qtplugintgt_fname}" ) # insert @executable_path/../plugins/ if not already in dirs list if(NOT ";${klatexformula_bundle_include_dirs};" MATCHES ";@executable_path/../plugins/${qtplugindirname};") set(klatexformula_bundle_include_dirs ${klatexformula_bundle_include_dirs} "@executable_path/../plugins/${qtplugindirname}") endif() endforeach() endif(KLF_BUNDLE_QT_PLUGINS) set_source_files_properties( macosx/qt.conf PROPERTIES MACOSX_PACKAGE_LOCATION "Resources" ) set(APP_TO_FIXUP "${CMAKE_CURRENT_BINARY_DIR}/klatexformula.app") set(LIBS "${klatexformula_bundle_include_libs}") set(DIRS "${klatexformula_bundle_include_dirs}") configure_file("${CMAKE_SOURCE_DIR}/cmake/klf_fix_up_app_bundle.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/fix_up_klatexformula_app_bundle.cmake" @ONLY) set(klatexformula_post_build_commands ${klatexformula_post_build_commands} COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/fix_up_klatexformula_app_bundle.cmake" ) endif(KLF_MACOSX_BUNDLE_EXTRAS) endif(KLF_MACOSX_BUNDLES) if(KLF_WS STREQUAL "x11") target_link_libraries(klatexformula Qt5::X11Extras) target_sources(klatexformula PRIVATE x11/klfx11.cpp ) endif() if(KLF_USE_DBUS) target_compile_definitions(klatexformula PUBLIC -DKLF_USE_DBUS) qt5_wrap_cpp(klatexformula_MOC_CPPS_dbus klfdbus.h) target_sources(klatexformula PRIVATE klfdbus.cpp ${klatexformula_MOC_CPPS_dbus} ) target_link_libraries(klatexformula Qt5::DBus) endif() if(KLF_DEBUG_USE_MODELTEST) target_compile_definitions(klatexformula PRIVATE -DKLF_DEBUG_USE_MODELTEST) qt5_wrap_cpp(klatexformula_MOC_CPPS_modeltest modeltest.h) target_sources(klatexformula PRIVATE modeltest.cpp ${klatexformula_MOC_CPPS_modeltest} ) endif() if(KLF_NO_CMU_FONT) target_compile_definitions(klatexformula PRIVATE -DKLF_NO_CMU_FONT) endif() # Don't use CMAKE_INSTALL_PREFIX itself, as it is irrelevant for windows installers # we need relative path KLFMakeAbsInstallPath(abs_share_klf_data_dir KLF_INSTALL_SHARE_KLF_DATA_DIR) KLFRelativePath(klf_share_dir "${KLF_ABS_INSTALL_BIN_DIR}" "${abs_share_klf_data_dir}") if(KLF_MACOSX_BUNDLES OR IS_ABSOLUTE "${klf_share_dir}") set(klf_share_dir "") # let the program find out endif() if(klf_share_dir) KLFCMakeDebug("setting -DKLF_SHARE_DIR=\"${klf_share_dir}\"") target_compile_definitions(klatexformula PRIVATE -DKLF_SHARE_DIR="${klf_share_dir}") endif(klf_share_dir) # # extra data: create and include the klf_xtradata.qrc file # set(klf_xtradata_res "${CMAKE_CURRENT_BINARY_DIR}/klf_xtradata.qrc") file(WRITE "${klf_xtradata_res}" "\n ") # - add translations foreach(qm ${klatexformula_QMS}) get_filename_component(baseqmname "${qm}" NAME) file(APPEND "${klf_xtradata_res}" " ${qm}\n") endforeach(qm) file(APPEND "${klf_xtradata_res}" " \n") # - add fonts file(APPEND "${klf_xtradata_res}" " \n") # with bundles, we include the file itself in the bundle, not in qrc (see QTBUG-30917): if(NOT KLF_MACOSX_BUNDLES) foreach(fnt ${KLF_INCLUDE_FONTS}) get_filename_component(basefntname "${fnt}" NAME) if(NOT IS_ABSOLUTE "${fnt}") set(fnt "${CMAKE_CURRENT_SOURCE_DIR}/${fnt}") endif(NOT IS_ABSOLUTE "${fnt}") file(APPEND "${klf_xtradata_res}" " ${fnt}\n") endforeach(fnt) endif(NOT KLF_MACOSX_BUNDLES) file(APPEND "${klf_xtradata_res}" " \n") file(APPEND "${klf_xtradata_res}" "\n") qt5_add_resources(klatexformula_QRC_CPPS_xtradata "${klf_xtradata_res}") target_sources(klatexformula PRIVATE ${klatexformula_QRC_CPPS_xtradata}) # Stuff for windows if(WIN32) set(KLF_WIN_ICON "mswin\\\\klficon64.ico" CACHE STRING "Icon for klatexformula.exe program, relative to src/, with (escaped double-backslashes!)") file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/klatexformula.rc" "IDI_ICON1 ICON DISCARDABLE \"${KLF_WIN_ICON}\"\n") # windows .rc resource compilation for windows add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/klatexformula.rc.o" COMMAND windres.exe -I"${CMAKE_CURRENT_SOURCE_DIR}" -i"${CMAKE_CURRENT_BINARY_DIR}/klatexformula.rc" -o "${CMAKE_CURRENT_BINARY_DIR}/klatexformula.rc.o" ) target_sources(klatexformula PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/klatexformula.rc.o") # On debug versions, the application will open a console in which the debug output is shown. # Add the -mwindows only if we are not compiling in debug mode. # Add also a separate target klatexformula_cmdl to build the cmdl version, keeping the shell # window open. get_target_property(klatexformula_ALL_SRCS klatexformula SOURCES) add_executable(klatexformula_cmdl "${klatexformula_ALL_SRCS}") get_target_property(klatexformula_CFLAGS klatexformula COMPILE_DEFINITIONS) target_compile_definitions(klatexformula_cmdl PRIVATE "${klatexformula_CFLAGS}") target_include_directories(klatexformula_cmdl PUBLIC "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/klftools" "${CMAKE_CURRENT_SOURCE_DIR}/klfbackend") target_link_libraries(klatexformula_cmdl Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Xml Qt5::Sql Qt5::Svg Qt5::UiTools Qt5::WinExtras klfbackend klftools) if(NOT KLF_DEBUG) set_target_properties(klatexformula PROPERTIES LINK_FLAGS_RELEASE "-Wl,-subsystem,windows") set_target_properties(klatexformula_cmdl PROPERTIES LINK_FLAGS_RELEASE "-Wl,-subsystem,console") endif(NOT KLF_DEBUG) endif(WIN32) # # User scripts # file(GLOB_RECURSE klf_userscriptfiles RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" userscripts/*) foreach(usfile ${klf_userscriptfiles}) if(usfile MATCHES "\\.(py|rb|sh|pl|bat|xml|ui)$") # backup file -- ignore target_sources(klatexformula PRIVATE ${usfile} ) # e.g. usfiledir = userscripts/xxx.klfuserscript get_filename_component(usfiledir "${usfile}" DIRECTORY) set_source_files_properties(${usfile} PROPERTIES MACOSX_PACKAGE_LOCATION Resources/${usfiledir} ) if(NOT KLF_MACOSX_BUNDLES) install(FILES ${usfile} DESTINATION "${KLF_INSTALL_SHARE_KLF_DATA_DIR}/${usfiledir}") endif() endif() endforeach() # Make man page if(HELP2MAN) # generate the man page set(LDPATHDEFS "export LD_LIBRARY_PATH='${CMAKE_CURRENT_BINARY_DIR}:${CMAKE_CURRENT_BINARY_DIR}/klfbackend:${CMAKE_CURRENT_BINARY_DIR}/klftools':\"$LD_LIBRARY_PATH\" ") add_custom_command(OUTPUT "klatexformula.1" COMMAND "sh" "-c" "${LDPATHDEFS}; ${HELP2MAN} -h --help='\"&1\"' -v --version='\"&1:klatexformula %k\"' -n 'GUI and CLI to generate images from LaTeX formulas' --no-info $ -o '${CMAKE_CURRENT_BINARY_DIR}/klatexformula.1'" COMMENT "Generating man page for klatexformula" DEPENDS "${klatexformula}" VERBATIM ) if(GZIP) add_custom_command(OUTPUT "klatexformula.1.gz" COMMAND "${CMAKE_COMMAND}" -E copy "klatexformula.1" "klatexformula.1.bkp" COMMAND "${GZIP}" -f "klatexformula.1.bkp" COMMAND "${CMAKE_COMMAND}" -E copy "klatexformula.1.bkp.gz" "klatexformula.1.gz" WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" COMMENT "Compressing (gzip) manpage" DEPENDS "klatexformula.1" VERBATIM ) set(klatexformula_manpage_file "klatexformula.1.gz") set(klatexformula_cmdl_manpage_file "klatexformula_cmdl.1.gz") else(GZIP) set(klatexformula_manpage_file "klatexformula.1") set(klatexformula_cmdl_manpage_file "klatexformula_cmdl.1") endif(GZIP) add_custom_command(OUTPUT "${klatexformula_cmdl_manpage_file}" COMMAND "${CMAKE_COMMAND}" -E copy "${klatexformula_manpage_file}" "${klatexformula_cmdl_manpage_file}" WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" COMMENT "Copying ${klatexformula_manpage_file} to ${klatexformula_cmdl_manpage_file}" DEPENDS "${klatexformula_manpage_file}" VERBATIM ) add_custom_target(klatexformula_manpage ALL DEPENDS "${klatexformula_manpage_file}" "${klatexformula_cmdl_manpage_file}") if(KLF_INSTALL_SHARE_MAN1_DIR) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${klatexformula_manpage_file}" "${CMAKE_CURRENT_BINARY_DIR}/${klatexformula_cmdl_manpage_file}" DESTINATION "${KLF_INSTALL_SHARE_MAN1_DIR}") endif(KLF_INSTALL_SHARE_MAN1_DIR) endif(HELP2MAN) if(KLF_INSTALL_QTLIBS) if(NOT WIN32) message(FATAL_ERROR "Not supported on non-windows system.") endif() # Install Qt libs get_target_property(Qt5CoreDllPath Qt5::Core LOCATION) get_target_property(Qt5GuiDllPath Qt5::Gui LOCATION) get_target_property(Qt5WidgetsDllPath Qt5::Widgets LOCATION) get_target_property(Qt5XmlDllPath Qt5::Xml LOCATION) get_target_property(Qt5WinExtrasDllPath Qt5::WinExtras LOCATION) get_target_property(Qt5SvgDllPath Qt5::Svg LOCATION) get_target_property(Qt5SqlDllPath Qt5::Sql LOCATION) install(FILES "${Qt5CoreDllPath}" "${Qt5GuiDllPath}" "${Qt5WidgetsDllPath}" "${Qt5XmlDllPath}" "${Qt5WinExtrasDllPath}" "${Qt5SvgDllPath}" "${Qt5SqlDllPath}" ${KLF_INSTALL_QTLIBS_EXTRADEPS} DESTINATION "${KLF_INSTALL_LIB_DIR}" ) endif() if(WIN32 AND KLF_USE_WINSPARKLE) install(FILES "${KLF_WINSPARKLE_DIR}/WinSparkle.dll" DESTINATION "${KLF_INSTALL_LIB_DIR}") endif(WIN32 AND KLF_USE_WINSPARKLE) if(KLF_INSTALL_QTPLUGINS) foreach(qtplugintgt ${KLF_INSTALL_QTPLUGINS_LIST}) get_target_property(qtplugintgt_loc ${qtplugintgt} LOCATION) get_filename_component(qtplugindirfull ${qtplugintgt_loc} DIRECTORY) get_filename_component(qtplugintgt_fname ${qtplugintgt_loc} NAME) get_filename_component(qtplugindirname ${qtplugindirfull} NAME) install(FILES "${qtplugintgt_loc}" DESTINATION "${KLF_INSTALL_QTPLUGINS_DIR}/${qtplugindirname}") endforeach() endif(KLF_INSTALL_QTPLUGINS) if(NOT KLF_MACOSX_BUNDLES) if(KLF_INSTALL_KLATEXFORMULA_BIN) install(TARGETS klatexformula RUNTIME DESTINATION "${KLF_INSTALL_BIN_DIR}") endif() if(UNIX AND KLF_INSTALL_KLATEXFORMULA_CMDL) install(CODE "message(STATUS \"Creating Symlink [\$ENV{DESTDIR}]${KLF_ABS_INSTALL_BIN_DIR}/klatexformula_cmdl -> klatexformula\") execute_process(COMMAND \"${CMAKE_COMMAND}\" -E create_symlink \"klatexformula\" \"\$ENV{DESTDIR}${KLF_ABS_INSTALL_BIN_DIR}/klatexformula_cmdl\")" ) elseif(WIN32 AND KLF_INSTALL_KLATEXFORMULA_CMDL) install(TARGETS klatexformula_cmdl RUNTIME DESTINATION "${KLF_INSTALL_BIN_DIR}") endif() # install targets for user scripts # ......... endif() if(KLF_MACOSX_BUNDLES) install(TARGETS klatexformula BUNDLE DESTINATION "${KLF_INSTALL_BIN_DIR}") endif() # --- execute all post-build commands, in order --- if(klatexformula_post_build_commands) add_custom_command(TARGET klatexformula POST_BUILD ${klatexformula_post_build_commands} ) endif() # --- LINUX DESKTOP FILES --- if(KLF_INSTALL_DESKTOP) configure_file( "${CMAKE_SOURCE_DIR}/src/klatexformula.desktop.in" "${CMAKE_BINARY_DIR}/src/klatexformula.desktop" @ONLY) if(KLF_INSTALL_SHARE_APPLICATIONS_DIR) install(FILES "${CMAKE_BINARY_DIR}/src/klatexformula.desktop" DESTINATION "${KLF_INSTALL_SHARE_APPLICATIONS_DIR}" ) endif() if(KLF_INSTALL_SHARE_PIXMAPS_DIR) install(FILES klatexformula-128.png klatexformula-64.png klatexformula-32.png klatexformula-16.png DESTINATION "${KLF_INSTALL_SHARE_PIXMAPS_DIR}" ) endif() if(KLF_INSTALL_ICON_THEME) install(FILES klatexformula.svg DESTINATION "${KLF_INSTALL_ICON_THEME}/scalable/apps/") install(FILES klatexformula-128.png DESTINATION "${KLF_INSTALL_ICON_THEME}/128x128/apps/" RENAME "klatexformula.png") install(FILES klatexformula-64.png DESTINATION "${KLF_INSTALL_ICON_THEME}/64x64/apps/" RENAME "klatexformula.png") install(FILES klatexformula-32.png DESTINATION "${KLF_INSTALL_ICON_THEME}/32x32/apps/" RENAME "klatexformula.png") install(FILES klatexformula-16.png DESTINATION "${KLF_INSTALL_ICON_THEME}/16x16/apps/" RENAME "klatexformula.png") endif() if(KLF_INSTALL_SHARE_MIME_PACKAGES_DIR) install(FILES "${CMAKE_SOURCE_DIR}/src/klatexformula-mime.xml" DESTINATION "${KLF_INSTALL_SHARE_MIME_PACKAGES_DIR}") endif() if(KLF_INSTALL_POST_UPDATEMIMEDATABASE) install(CODE "message(STATUS \"Updating Mime Types Database (update-mime-database)\") execute_process(COMMAND update-mime-database \"${CMAKE_INSTALL_PREFIX}/share/mime\")" ) endif() endif() endif(KLF_BUILD_GUI) klatexformula-4.1.0/src/klfmime.h000644 000765 000024 00000024655 13660527435 017762 0ustar00philippestaff000000 000000 /*************************************************************************** * file klfmime.h * This file is part of the KLatexFormula Project. * Copyright (C) 2011 by Philippe Faist * philippe.faist at bluewin.ch * * * 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 of the License, 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., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ /* $Id$ */ #ifndef KLFMIME_H #define KLFMIME_H #include #include #include #include #include #include #include #include #include #include #include #include #include /** \brief An export profile grouping several MIME types and associated exporters to * generate the corresponding data */ class KLF_EXPORT KLFMimeExportProfile { public: struct ExportType { struct DefaultQtFormat { DefaultQtFormat(const QString& qtType_ = QString(), const QStringList& onlyOnWs_ = QStringList()) : qtType(qtType_), onlyOnWs(onlyOnWs_) { } QString qtType; QStringList onlyOnWs; }; ExportType(const QString & exporterName_ = QString(), const QString & exporterFormat_ = QString(), const QList& defaultQtFormats_ = QList(), const QStringList& mimeTypes_ = QStringList(), const QStringList& winFormats_ = QStringList(), const QStringList& macFlavors_ = QStringList()) : exporterName(exporterName_), exporterFormat(exporterFormat_), defaultQtFormats(defaultQtFormats_), mimeTypes(mimeTypes_), winFormats(winFormats_), macFlavors(macFlavors_) { } QString exporterName; QString exporterFormat; QList defaultQtFormats; QList defaultQtFormatsOnThisWs() const; QStringList mimeTypes; QStringList winFormats; QStringList macFlavors; }; KLFMimeExportProfile(const QString& pname, const QString& desc, const QList& exporttypes, const QString& insubmenu = QString()); // construct an invalid profile, with null name and description KLFMimeExportProfile(); QString profileName() const { return p_profileName; } QString description() const { return p_description; } QString inSubMenu() const { return p_inSubMenu; } /** List of formats to export when using this export profile. */ inline QList exportTypes() const { return p_exportTypes; } /** Number of export types. Equivalent to exportTypes().size() */ inline int exportTypesCount() const { return p_exportTypes.size(); } /** Returns export type at position \c n. \c n MUST be in the valid range \c 0 ... exportTypesCount(). */ inline ExportType exportType(int n) const { return p_exportTypes[n]; } /** A list of all the available mime types provided by this profile. * * This is the collected list of all mime types of all export types for which an * exporter exists in \a exporterManager which can export the \a output to. */ QStringList collectedAvailableMimeTypes(KLFExporterManager * exporterManager, const KLFBackend::klfOutput & output) const; /** A list of all the available windows formats provided by this profile. * * This is the collected list of all windows formats of all export types for which an * exporter exists in \a exporterManager which can export the \a output to. */ QStringList collectedAvailableWinFormats(KLFExporterManager * exporterManager, const KLFBackend::klfOutput & output) const; /** A list of all the available mac flavors provided by this profile. * * This is the collected list of all mac flavors of all export types for which an * exporter exists in \a exporterManager which can export the \a output to. */ QStringList collectedAvailableMacFlavors(KLFExporterManager * exporterManager, const KLFBackend::klfOutput & output) const; /** \brief The export type index of the first export type with an exporter and format * capable of generating the given mime type * * If a MIME type appears several times in a same profile, the first occurrence in an * available export type is used. An export type is unavailable if the exporter name * doesn't exist (e.g., if a user script can't be executed). * * Returns \a -1 if no such MIME type can be found. */ int indexOfAvailableMimeType(const QString & mimeType, KLFExporterManager * exporterManager, const KLFBackend::klfOutput & klfoutput) const; /** \brief The export type index of the first export type with an exporter and format * capable of generating the given windows format * * If a windows format type appears several times in a same profile, the first occurrence in an * available export type is used. An export type is unavailable if the exporter name * doesn't exist (e.g., if a user script can't be executed). * * Returns \a -1 if no such windows format can be found. */ int indexOfAvailableWinFormat(const QString & winFormat, KLFExporterManager * exporterManager, const KLFBackend::klfOutput & klfoutput) const; /** \brief The export type index of the first export type with an exporter and format * capable of generating the given mac flavor * * If a mac flavor appears several times in a same profile, the first occurrence in an * available export type is used. An export type is unavailable if the exporter name * doesn't exist (e.g., if a user script can't be executed). * * Returns \a -1 if no such mac flavor can be found. */ int indexOfAvailableMacFlavor(const QString & macFlavor, KLFExporterManager * exporterManager, const KLFBackend::klfOutput & klfoutput) const; /** \brief Load profiles from an XML description file * * The file should be an XML file of the format found in the \c * "conf/mime_export_profiles.d/xxx.xml" directory. */ static QList loadProfilesFromXmlFile(const QString & xmlFile); private: QString p_profileName; QString p_description; QList p_exportTypes; QString p_inSubMenu; }; struct KLFMimeExportProfileManagerPrivate; class KLFMimeExportProfileManager { public: KLFMimeExportProfileManager(); ~KLFMimeExportProfileManager(); QList exportProfileList(); void addExportProfile(const KLFMimeExportProfile& exportProfile); void addExportProfiles(const QList & initialProfileList); KLFMimeExportProfile findExportProfile(const QString& pname); static QList loadKlfExportProfileList(); private: KLF_DECLARE_PRIVATE(KLFMimeExportProfileManager) ; }; struct KLFMimeDataPrivate; /** A QMimeData subclass for Copy and Drag operations in KLFMainWin, that supports delayed * data processing, ie. that actually creates the requested data only on drop or paste, and * not when the operation is initiated. * * This function can be used as a regular QMimeData object to copy or drag any * KLFBackend::klfOutput data, with a given export profile. */ class KLF_EXPORT KLFMimeData : public QMimeData { Q_OBJECT public: KLFMimeData(const KLFMimeExportProfile& exportProfile, KLFExporterManager * exporterManager, const KLFBackend::klfOutput& output); virtual ~KLFMimeData(); QStringList formats() const; void transmitAllData(); static QList activeMimeDataInstances(); protected: QVariant retrieveData(const QString &mimetype, QVariant::Type type) const; private: KLF_DECLARE_PRIVATE( KLFMimeData ) ; }; #define KLF_MIME_PROXY_MAC_FLAVOR_PREFIX "application/x-klf-proxymacflavor-" #define KLF_MIME_PROXY_WIN_FORMAT_PREFIX "application/x-klf-proxywinformat-" /* struct KLFExportTypeUserScriptInfoPrivate; class KLF_EXPORT KLFExportTypeUserScriptInfo : public KLFUserScriptInfo { public: KLFExportTypeUserScriptInfo(const QString& scriptFileName, KLFBackend::klfSettings * settings); KLFExportTypeUserScriptInfo(const KLFExportTypeUserScriptInfo& copy); KLFExportTypeUserScriptInfo(const KLFUserScriptInfo& copy); virtual ~KLFExportTypeUserScriptInfo(); QStringList mimeTypes() const; QStringList outputFilenameExtensions() const; QStringList outputFormatDescriptions() const; QString inputDataType() const; int count() const; int findMimeType(const QString& mimeType) const; QString mimeType(int index) const; QString outputFilenameExtension(int index) const; QString outputFormatDescription(int index) const; bool wantStdinInput() const; bool hasStdoutOutput() const; private: KLF_DECLARE_PRIVATE(KLFExportTypeUserScriptInfo) ; }; struct KLFExportUserScriptPrivate; class KLF_EXPORT KLFExportUserScript { public: KLFExportUserScript(const QString& scriptFileName, KLFBackend::klfSettings * settings); ~KLFExportUserScript(); KLFExportTypeUserScriptInfo info() const; QStringList availableMimeTypes(const KLFBackend::klfOutput * output = NULL) const; QByteArray getData(const QString& mimeType, const KLFBackend::klfOutput& output); private: KLF_DECLARE_PRIVATE(KLFExportUserScript); }; */ #endif klatexformula-4.1.0/src/klflibentryeditor.ui000644 000765 000024 00000044153 13660527435 022253 0ustar00philippestaff000000 000000 KLFLibEntryEditor 0 0 326 556 1 Qt::Vertical QFrame::NoFrame QFrame::Plain 0 0 280 80 :/pix/pics/nopreview.png false 0 0 0 80 true false true false Qt::TextSelectableByMouse Qt::Horizontal 1 5 Qt::Horizontal 1 5 0 0 false QFrame::StyledPanel QFrame::Sunken 1 0 0 0 0 322 257 true Category and Tags &Category: false cbxCategory true true false Name / &Tags: false cbxTags true true false Qt::Horizontal QSizePolicy::Expanding 10 10 Apply Changes Qt::Vertical 20 40 0 0 322 257 true Style 6 Math Mode: Restore This Style Qt::Vertical 20 40 LaTeX Preamble: 0 0 0 40 true false true false Qt::TextSelectableByMouse QFrame::StyledPanel QFrame::Sunken Qt::PlainText Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true Qt::TextSelectableByMouse Qt::Horizontal QSizePolicy::Expanding 1 10 0 0 Colors: 0 0 QFrame::StyledPanel QFrame::Sunken 3 0 0 0 12 0 / Qt::AlignCenter 0 0 16 16 Background Color Y 0 0 16 16 Foreground Color X 50 16 QFrame::StyledPanel QFrame::Sunken 1200 Qt::PlainText Qt::AlignCenter 0 DPI Res.: Qt::Horizontal QSizePolicy::Fixed 5 10 QFrame::NoFrame QFrame::Raised 0 0 User Script: QFrame::StyledPanel QFrame::Sunken <user script...> 1 KLFLatexEdit QTextEdit
klflatexedit.h
KLFDisplayLabel QLabel
klfdisplaylabel.h
txtPreviewLatex cbxCategory cbxTags btnApplyChanges txtStyPreamble btnRestoreStyle
klatexformula-4.1.0/src/klatexformula-mime.xml000644 000765 000024 00000002164 13660527435 022501 0ustar00philippestaff000000 000000 KLatexFormula Library Export Exportation de Bibliothèque KLatexFormula KLatexFormula Library Resource (Sqlite DB) Ressource KLatexFormula (BD Sqlite) klatexformula-4.1.0/src/klfstyle.cpp000644 000765 000024 00000037205 13660527435 020521 0ustar00philippestaff000000 000000 /*************************************************************************** * file klfstyle.cpp * This file is part of the KLatexFormula Project. * Copyright (C) 2011 by Philippe Faist * philippe.faist at bluewin.ch * * * 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 of the License, 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., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ /* $Id$ */ #include #include #include #include #include "klfstyle.h" KLF_DECLARE_POBJ_TYPE(KLFStyle); KLFStyle::BBoxExpand::BBoxExpand(double t, double r, double b, double l) : KLFPropertizedObject("KLFStyle::BBoxExpand"), top(this, Top, "top", t), right(this, Right, "right", r), bottom(this, Bottom, "bottom", b), left(this, Left, "left", l) { } KLFStyle::BBoxExpand::BBoxExpand(const BBoxExpand& c) : KLFPropertizedObject("KLFStyle::BBoxExpand"), top(this, Top, "top", c.top), right(this, Right, "right", c.right), bottom(this, Bottom, "bottom", c.bottom), left(this, Left, "left", c.left) { } // ----- KLFStyle::KLFStyle(QString nm, unsigned long fgcol, unsigned long bgcol, const QString& mmode, const QString& pre, int dotsperinch, const BBoxExpand& bb, const QString& us, const QVariantMap& usinput) : KLFPropertizedObject("KLFStyle"), name(this, Name, "name", nm), fontname(this, FontName, "fontname", QString()), fg_color(this, FgColor, "fg_color", fgcol), bg_color(this, BgColor, "bg_color", bgcol), mathmode(this, MathMode, "mathmode", mmode), preamble(this, Preamble, "preamble", pre), fontsize(this, FontSize, "fontsize", -1), dpi(this, DPI, "dpi", dotsperinch), vectorscale(this, VectorScale, "vectorscale", 1.0), overrideBBoxExpand(this, OverrideBBoxExpand, "overrideBBoxExpand", bb), userScript(this, UserScript, "userScript", us), userScriptInput(this, UserScriptInput, "userScriptInput", usinput) { } KLFStyle::KLFStyle(const KLFBackend::klfInput& input) : KLFPropertizedObject("KLFStyle"), name(this, Name, "name", QString()), fontname(this, FontName, "fontname", QString()), fg_color(this, FgColor, "fg_color", input.fg_color), bg_color(this, BgColor, "bg_color", input.bg_color), mathmode(this, MathMode, "mathmode", input.mathmode), preamble(this, Preamble, "preamble", input.preamble), fontsize(this, FontSize, "fontsize", input.fontsize), dpi(this, DPI, "dpi", input.dpi), vectorscale(this, VectorScale, "vectorscale", input.vectorscale), overrideBBoxExpand(this, OverrideBBoxExpand, "overrideBBoxExpand", BBoxExpand()), userScript(this, UserScript, "userScript", input.userScript), userScriptInput(this, UserScriptInput, "userScriptInput", klfMapToVariantMap(input.userScriptParam)) { klfDbg("Note: Possible loss of information: KLFStyle(KLFBackend::klfInput)") ; } KLFStyle::KLFStyle(const KLFStyle& o) : KLFPropertizedObject("KLFStyle"), name(this, Name, "name", o.name), fontname(this, FontName, "fontname", o.fontname), fg_color(this, FgColor, "fg_color", o.fg_color), bg_color(this, BgColor, "bg_color", o.bg_color), mathmode(this, MathMode, "mathmode", o.mathmode), preamble(this, Preamble, "preamble", o.preamble), fontsize(this, FontSize, "fontsize", o.fontsize), dpi(this, DPI, "dpi", o.dpi), vectorscale(this, VectorScale, "vectorscale", o.vectorscale), overrideBBoxExpand(this, OverrideBBoxExpand, "overrideBBoxExpand", o.overrideBBoxExpand), userScript(this, UserScript, "userScript", o.userScript), userScriptInput(this, UserScriptInput, "userScriptInput", o.userScriptInput) { } QByteArray KLFStyle::typeNameFor(const QString& pname) const { klfDbg("pname is "<>(QDataStream& stream, KLFStyle::BBoxExpand& x) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; double t, r, b, l; stream >> t >> r >> b >> l; x.top = t; x.right = r; x.bottom = b; x.left = l; klfDbg("Read BBoxExpand from QDataStream: "< " < 0.001) { s += "\n%%% KLF_fontsize: " + QString::fromLatin1("%1").arg(fontsize, 0, 'f', 2); } if (fabs(vscale - 1.0) > 1e-5) { s += "\n%%% KLF_vectorscale: " + QString::fromLatin1("%1").arg(vscale, 0, 'f', 4); } return s; } static void set_xtra_from_preamble(KLFStyle * style) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; klfDbg("style="<<*style) ; QRegExp rx = QRegExp("\n%%%\\s*KLF_([a-zA-Z0-9_]*):\\s*(\\S[^\n]*)?"); QString p = style->preamble; int pos = 0; while ((pos = rx.indexIn(p, pos)) != -1) { QString what = rx.cap(1); QString value = rx.cap(2); klfDbg("KLFStyle: reading xtras: what="<overrideBBoxExpand = bb; p.replace(pos, rx.matchedLength(), ""); ++pos; continue; } if (what == "userScript") { style->userScript = QString::fromUtf8(klfEscapedToData(value.toLatin1())); klfDbg("read user script: "<userScript()) ; p.replace(pos, rx.matchedLength(), ""); continue; } if (what == "userScriptInput") { style->userScriptInput = klfLoadVariantFromText(value.toLatin1(), "QVariantMap", "XML").toMap(); klfDbg("user script input: "<userScriptInput()); p.replace(pos, rx.matchedLength(), ""); continue; } if (what == "fontname") { style->fontname = QString::fromUtf8(klfEscapedToData(value.toLatin1())); klfDbg("font name: "<fontname) ; p.replace(pos, rx.matchedLength(), ""); continue; } if (what == "fontsize") { style->fontsize = value.toDouble(); klfDbg("font size: "<fontsize) ; p.replace(pos, rx.matchedLength(), ""); continue; } if (what == "vectorscale") { style->vectorscale = value.toDouble(); klfDbg("vector scale: "<vectorscale) ; p.replace(pos, rx.matchedLength(), ""); continue; } klfWarning("Ignoring unknown preamble-xtra-information "<preamble = p; // with the xtra info removed } KLF_EXPORT QDataStream& operator<<(QDataStream& stream, const KLFStyle& style) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; klfDbg("style name = " << style.name() << "; by the way, style.overrideBBoxExpand is " << style.overrideBBoxExpand()) ; // yes, QIODevice inherits QObject and we can use dynamic properties... QString compat_klfversion = stream.device()->property("klfDataStreamAppVersion").toString(); if (klfVersionCompare(compat_klfversion, "3.1") <= 0) { KLFStyle::KLFLegacyStyle oldstyle = KLFStyle::KLFLegacyStyle::fromNewStyle(style); klfDbg("saving legacy style to stream: style="<>(QDataStream& stream, KLFStyle& style) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME+"(QDataStream,KLFStyle&)") ; QString compat_klfversion = stream.device()->property("klfDataStreamAppVersion").toString(); if (klfVersionCompare(compat_klfversion, "3.1") <= 0) { klfDbg("using klf compat version 3.1") ; KLFStyle::KLFLegacyStyle oldstyle; stream >> oldstyle; style = oldstyle.toNewStyle(); return stream; } else if (klfVersionCompare(compat_klfversion, "3.3") < 0) { klfDbg("using 3.1 < klf compat version < 3.3") ; quint32 fg, bg; quint16 dpi; QString name, mathmode, preamble; KLFStyle::BBoxExpand bb; stream >> name; stream >> fg >> bg >> mathmode >> preamble >> dpi; stream >> bb; style.name = name; style.mathmode = mathmode; style.preamble = preamble; style.fg_color = fg; style.bg_color = bg; style.fontsize = -1; style.dpi = dpi; style.vectorscale = 1.0; style.overrideBBoxExpand = bb; style.userScript = QString(); style.userScriptInput = QVariantMap(); set_xtra_from_preamble(&style); return stream; } else { // use Compressed XML klfDbg("using klf compat version 3.3") ; QByteArray data; stream >> data; klfDbg("loading from data="< #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include template inline bool klf_config_read_value(QSettings &s, const QString& baseName, T * target, const char * listOrMapType = NULL) { QVariant defVal = QVariant::fromValue(*target); QVariant valstrv = s.value(baseName, QVariant()); if (valstrv.isNull()) { klfDbg("No entry "<(); return true; } klfDbg("klf_config_read_value: read empty or invalid value for "< inline void klf_config_read(QSettings &s, const QString& baseName, KLFConfigProp *target, const char * listOrMapType = NULL) { T value = *target; if (klf_config_read_value(s, baseName, &value, listOrMapType)) *target = value; } template<> inline void klf_config_read(QSettings &s, const QString& baseName, KLFConfigProp *target, const char * /*listOrMapType*/) { qDebug("klf_config_read(%s)", qPrintable(baseName)); QTextFormat fmt = *target; klf_config_read_value(s, baseName, &fmt); *target = fmt.toCharFormat(); } template inline void klf_config_read_list(QSettings &s, const QString& baseName, KLFConfigProp > *target) { QVariantList vlist = klfListToVariantList(target->value()); klf_config_read_value(s, baseName, &vlist, QVariant::fromValue(T()).typeName()); *target = klfVariantListToList(vlist); } template inline void klf_config_write_value(QSettings &s, const QString& baseName, const T * value) { QVariant val = QVariant::fromValue(*value); QByteArray datastr = klfSaveVariantToText(val); s.setValue(baseName, QVariant::fromValue(QString::fromLocal8Bit(datastr))); } template inline void klf_config_write(QSettings &s, const QString& baseName, const KLFConfigProp * target) { T temp = *target; klf_config_write_value(s, baseName, &temp); } template<> inline void klf_config_write(QSettings &s, const QString& baseName, const KLFConfigProp * target) { klfDbg(", baseName="< inline void klf_config_write_list(QSettings &s, const QString& baseName, const KLFConfigProp > * target) { QVariantList vlist = klfListToVariantList(target->value()); klf_config_write_value(s, baseName, &vlist); } class KLFConfig; // /** \brief Utility class for plugins to access their configuration space in KLFConfig // * // * KLatexFormula stores its configuration via KLFConfig and the global \c klfconfig object. // * That structure relies on the config structure being known in advance and the named // * fields to appear publicly in the KLFConfig class. This scheme is obviously NOT possible // * for plugins, so a different approach is taken. // * // * Plugins are given a pointer to a \c KLFPluginConfigAccess object, which is an interface // * to access a special part of KLFConfig that stores plugin-related configuration in the // * form of QVariantMaps. (themselves written in an INI-based config file inside the plugin's // * local directory, at ~/.klatexformula/plugindata/<plugin>/<plugin>.conf) // * // * KLFConfig transparently takes care of reading the config for plugins at the beginning // * when launching KLatexFormula and storing the plugin configurations in their respective // * locations when quitting. // * // * Plugins can read values they have set in earlier sessions with readValue(). Default values // * can be defined with \ref makeDefaultValue(). // * // * Plugins can write changed settings with \ref writeValue(). // */ // class KLF_EXPORT KLFPluginConfigAccess // { // KLFConfig *_config; // QString _pluginname; // public: // KLFPluginConfigAccess(); // KLFPluginConfigAccess(KLFConfig *configObject, const QString& pluginName); // KLFPluginConfigAccess(const KLFPluginConfigAccess& other); // virtual ~KLFPluginConfigAccess(); // /** Returns the root directory in which KLatexFormula stores its stuff, usually // * ~/.klatexformula. // */ // virtual QString homeConfigDir() const; // /** Returns the directory (not necessarily existing) in which installed data that is // * shared among different users is stored. // * eg. system-wide installations of plugins/extensions can be placed in: // * share-dir/rccresources/*.rcc. // */ // virtual QString globalShareDir() const; // /** Returns a directory in which we can read/write temporary files, eg. "/tmp". // * // * This is actually the value of klfconfig.BackendSettings.tempDir */ // virtual QString tempDir() const; // /** Returns a path to a directory in which plugins can manage their data as they want. // * // * If the \c createIfNeeded argument is TRUE, then the directory is garanteed to exist, // * and an empty string is returned if, for whatever reason, the directory can't be // * created. // * // * If the \c createIfNeeded argument is FALSE, then the directory path is returned // * regardless of whether the directory exists or not. // * // * Note that a file named pluginName.conf is created to store the plugin's // * settings in that directory (the settings are stored automatically). // */ // virtual QString homeConfigPluginDataDir(bool createIfNeeded = true) const; // /** \brief read a value in the config // * // * Returns the value of the entry with key \c key. If no such entry exists, // * it is not created and an invalid QVariant() is returned. // */ // virtual QVariant readValue(const QString& key) const; // /** \brief write the value if inexistant in config // * // * equivalent to // * \code // * if (readValue(key).isNull()) // * writeValue(key, defaultValue); // * \endcode // * // * \return the value this key has after this function call, ie. \c defaultValue if no // * existing value was found, or the existing value if one already exists. A null QVariant // * is returned upon error. // */ // virtual QVariant makeDefaultValue(const QString& key, const QVariant& defaultValue); // /** \brief write a value to settings // * // * Saves the value of a setting, referenced by \c key, to the given \c value. // * // * If \c key hasn't been previously set, creates an entry for \c key with the // * given \c value. // */ // virtual void writeValue(const QString& key, const QVariant& value); // }; //! Structure that stores klatexformula's configuration in memory /** * This structure is more of a namespace than a class. Access it through the global * object \ref klfconfig. * * See also \ref KLFSettings for a graphical interface for editing these settings. */ class KLF_EXPORT KLFConfig : public KLFConfigBase { public: KLFConfig(); virtual ~KLFConfig(); QString homeConfigDir; QString globalShareDir; QString homeConfigSettingsFile; //!< current (now, "new" klatexformula.conf) settings file QString homeConfigSettingsFileIni; //!< OLD config file // QString homeConfigDirRCCResources; // QString homeConfigDirPlugins; // QString homeConfigDirPluginData; QString homeConfigDirI18n; QString homeConfigDirUserScripts; struct { KLFConfigProp thisVersionMajFirstRun; KLFConfigProp thisVersionMajMinFirstRun; KLFConfigProp thisVersionMajMinRelFirstRun; KLFConfigProp thisVersionExactFirstRun; /** The library file name, relative to homeConfigDir. */ KLFConfigProp libraryFileName; /** The lib scheme to use to store the library. This scheme will be given the full path * to the library in the URL path part. */ KLFConfigProp libraryLibScheme; } Core; struct { KLFConfigProp locale; //!< When setting this, don't forget to call QLocale::setDefault(). KLFConfigProp useSystemAppFont; KLFConfigProp applicationFont; KLFConfigProp latexEditFont; KLFConfigProp preambleEditFont; KLFConfigProp editorTabInsertsTab; KLFConfigProp editorWrapLines; KLFConfigProp previewTooltipMaxSize; KLFConfigProp labelOutputFixedSize; //!< No Longer used (3.3.0alpha) KLFConfigProp smallPreviewSize; //!< Size of preview to store e.g. in history/library items // KLFConfigProp savedWindowSize; KLFConfigProp detailsSideWidgetType; //!< "ShowHide","Drawer", or "Float" (or any custom type!) KLFConfigProp lastSaveDir; KLFConfigProp symbolsPerLine; KLFConfigProp symbolIncludeWithPreambleDefs; KLFConfigProp > userColorList; KLFConfigProp > colorChooseWidgetRecent; KLFConfigProp > colorChooseWidgetCustom; KLFConfigProp maxUserColors; KLFConfigProp enableToolTipPreview; KLFConfigProp enableRealTimePreview; KLFConfigProp realTimePreviewExceptBattery; KLFConfigProp autosaveLibraryMin; KLFConfigProp showHintPopups; KLFConfigProp clearLatexOnly; KLFConfigProp glowEffect; KLFConfigProp glowEffectColor; KLFConfigProp glowEffectRadius; KLFConfigProp customMathModes; KLFConfigProp emacsStyleBackspaceSearch; KLFConfigProp macBrushedMetalLook; } UI; struct { KLFConfigProp copyExportProfile; KLFConfigProp dragExportProfile; KLFConfigProp showExportProfilesLabel; KLFConfigProp menuExportProfileAffectsDrag; KLFConfigProp menuExportProfileAffectsCopy; KLFConfigProp oooExportScale; KLFConfigProp htmlExportDpi; KLFConfigProp htmlExportDisplayDpi; } ExportData; struct { KLFConfigProp enabled; KLFConfigProp highlightParensOnly; KLFConfigProp highlightLonelyParens; //KLFConfigProp matchParenTypes; KLFConfigProp fmtKeyword; KLFConfigProp fmtComment; KLFConfigProp fmtParenMatch; KLFConfigProp fmtParenMismatch; KLFConfigProp fmtLonelyParen; } SyntaxHighlighter; struct { KLFConfigProp tempDir; KLFConfigProp execLatex; KLFConfigProp execDvips; KLFConfigProp execGs; KLFConfigProp execEpstopdf; KLFConfigProp execenv; KLFConfigProp setTexInputs; KLFConfigProp lborderoffset; KLFConfigProp tborderoffset; KLFConfigProp rborderoffset; KLFConfigProp bborderoffset; KLFConfigProp calcEpsBoundingBox; KLFConfigProp outlineFonts; KLFConfigProp wantPDF; KLFConfigProp wantSVG; KLFConfigProp userScriptAddPath; KLFConfigProp userScriptInterpreters; } BackendSettings; struct { KLFConfigProp colorFound; KLFConfigProp colorNotFound; KLFConfigProp restoreURLs; KLFConfigProp confirmClose; KLFConfigProp groupSubCategories; KLFConfigProp iconViewFlow; KLFConfigProp historyTagCopyToArchive; KLFConfigProp lastFileDialogPath; KLFConfigProp treePreviewSizePercent; KLFConfigProp listPreviewSizePercent; KLFConfigProp iconPreviewSizePercent; } LibraryBrowser; // struct { // QMap > pluginConfig; // } Plugins; struct { QMap > userScriptConfig; } UserScripts; /** Not a saved setting. This is set in loadDefaults() */ QFont defaultCMUFont; /** Not a saved setting. This is set in loadDefaults() */ QFont defaultStdFont; /** Not a saved setting. This is set in loadDefaults() */ QFont defaultTTFont; // KLFPluginConfigAccess getPluginConfigAccess(const QString& name); /** call loadDefaults() before anything, at the beginning, to ensure that the values * in this structure are not undefined. (the constructor doesn't set any values). * * loadDefaults() will set reasonable default values for most settings, but will not * start detecting system settings, specifically look for system executables, possibly other * long detection tasks. To perform that, call detectMissingSettings(). * * In practice, main() calls, in order, loadDefaults(), readFromConfig(), and * detectMissingSettings(). * */ void loadDefaults(); int readFromConfig(); void detectMissingSettings(); int ensureHomeConfigDir(); int writeToConfig(); /** returns TRUE if the executable paths are valid. */ bool checkExePaths(); /** will be called before QApplication etc. are destroyed */ void prepareDestruction(); private: int readFromConfig_v2(const QString& fname); int readFromConfig_v1(); }; extern KLFConfig * klf_the_config; template inline T * klf_get_ptr_assert_not_null(T * ptr) { assert(ptr != NULL); return ptr; } #define klfconfig \ (*klf_get_ptr_assert_not_null(klf_the_config)) #define KLF_CONNECT_CONFIG_SH_LATEXEDIT(latexedit) \ klfconfig.SyntaxHighlighter.enabled \ .connectQObjectProperty((latexedit)->syntaxHighlighter(), "highlightEnabled") ; \ klfconfig.SyntaxHighlighter.highlightParensOnly \ .connectQObjectProperty((latexedit)->syntaxHighlighter(), "highlightParensOnly") ; \ klfconfig.SyntaxHighlighter.highlightLonelyParens \ .connectQObjectProperty((latexedit)->syntaxHighlighter(), "highlightLonelyParens") ; \ klfconfig.SyntaxHighlighter.fmtKeyword \ .connectQObjectProperty((latexedit)->syntaxHighlighter(), "fmtKeyword") ; \ klfconfig.SyntaxHighlighter.fmtComment \ .connectQObjectProperty((latexedit)->syntaxHighlighter(), "fmtComment") ; \ klfconfig.SyntaxHighlighter.fmtParenMatch \ .connectQObjectProperty((latexedit)->syntaxHighlighter(), "fmtParenMatch") ; \ klfconfig.SyntaxHighlighter.fmtParenMismatch \ .connectQObjectProperty((latexedit)->syntaxHighlighter(), "fmtParenMismatch") ; \ klfconfig.SyntaxHighlighter.fmtLonelyParen \ .connectQObjectProperty((latexedit)->syntaxHighlighter(), "fmtLonelyParen") ; #endif klatexformula-4.1.0/src/klatexformula.ai000644 000765 000024 00000465530 13660527435 021357 0ustar00philippestaff000000 000000 %PDF-1.5 % 1 0 obj <>/OCGs[5 0 R 23 0 R 47 0 R 81 0 R 107 0 R 135 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream application/pdf klatexformula Adobe Illustrator CS6 (Macintosh) 2016-12-26T21:29:06-08:00 2016-12-26T22:12:48-08:00 2016-12-26T22:12:48-08:00 256 192 JPEG /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAwAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 FXYq7FWCfm35x1fQdP0XTNCkSHXvM+qW+kWNzIglFssxJmuvTOz+ig6HapFajFUw/L22/MC2tNUg 853UV7Il/MNIul9ISvYinpNMII4IuRNeiD3xVleKuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Ku xV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV4T5/wDLd9r/APzkH5X0ZfMGpRR2ljd64yxfVP8A Qgf9GiNqGtnHxSJ8Xq8z4EHFXuFnbvb2kNvJPJdPEio1zNw9SQqKc39NUTkep4qB7YqrYq7FXYq7 FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXk3kdDrH5+ eftepyt9GtLDQbSXxLKLm5UeHGVRXFXrOKuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Kux V2KuxV2KuxV2KuxV2KuxV2KuxV2KuxVin5h+VfMHmGx01dD1qXRrvTr+G+cRs6R3UcVeVtM0RV+D 8t+vTp4KojyJ5Oi8r6XcwvP9c1PU7yfU9XvuPATXd03KRlSrcUUURFqaKBvirI8VdirsVdirsVdi rsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdir sVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirs VdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsV dirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVQM2s2EOmQ6lKzpaz+gIqo/MtdO kcS+nTkGZ5FFKbd8VR2KoXT9TstQWdrR2kW2nktZWKOg9WFuMgUuFDhW+EstRUEVqDiqKxVBSa5o 8erRaO97CuqzxmaKxLr6zRr1YJWvY/cfA4qjcVdirsVWTzwQRNNPIsUKCryOQqqPEk7DFW45I5Y1 kjYPG4qrqQQQe4IxVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVS7XZ RFbW7rZi+n+tW6wW5NKM0oVpejf3KFpOn7OKo26NyttKbVEkugjGBJWKRtJT4Q7qrlVJ6kKaeBxV LvK+iQaHodrpcRRnt1/0iSNQivO/xyvxHTm7FqYqmuKvP/y6sri680+c/MFxdG4SbVnsLRGjjHGK whjh2ZRy+GX1U679Tvir0DFXYq7FXi35k6xofmT83PKPk+81G2bQLKC81bWbdpo/TeeMGC0WTkSp aKarBG+kYq9I8geStP8AJflW08u6fc3F5aWhkaO4u3WSVvWkaU1Kqi9X2oMVZDirsVdirsVdiryr 89vzdv8AyVb6Tofl6KK483eY5xb6as3xRwqzLH6zqOpLuFQdCanfjQqvPPNv5o+d/wAvvzN8t+U0 12+803941sNdhvILSK1kN3JwC2aW8KTRtvUfGR0HxdlX0xirsVdirsVdirsVdirsVdirsVdirsVa d0RGd2CooJZiaAAbkknFXmOt/wDOS35L6PeNZzeYUuZ4yQ5s4ZrmMEbf3sSNG3+xY4qyfyZ+Z3kL zqjnyzrMGoSRDlLbjlFOq9OTQyhJAtTTlxpirKMVU7mb0LeWfg8vpIz+nEOTtxFeKL3Y9hiqS+SN DfSNAjjuI/T1G9kkv9TqVZjdXTmWXky7MVLcAfADtiqaapb3tzp1xBY3ZsLyRCsF4I0lMTno/pv8 LU8DiqD8reX4tA0WLTUlNxIJJri5uSvEy3F1M9xPJxqePOWViBU06Yqm2KuxV2KvFvJegaJrP59e f9QbTbR7HRLbT9Kt1MMZQyyp9YnYLTjyV1ox64q9pxV2KuxV2KuxV2KvljzMx83f85l6Tp/95a+X RAeXVVNnA19X6J5AvzxV9NzaLo8+oxanNYW8upW68YL14kadF32SQjmo+I9DiqMxV2KuxV2KuxV2 KuxV2KuxV2KuxV2Kvjf/AJym/OjVNa8x3HkLQbho9G0+QQamYTvd3Y2aJiN/Tib4ePd61rRcVe16 F5F8jfkz+VN1qt5pcF9f2Nl6+sXbIjzXVwwA9JXcNxjMjBEXoBuampKr481L80NXufPtt5x0nT7H QdQtZlltrfSofq8Rofsuqn94XFVcn7VTir9IMVdirsVdirAPKM+r655/8z6neiWOw0W6XStMjS6Y w1S3jkn5QqFRubTgknoVA/ZrirP8VdiqW6h5k0DTtSsdMv8AUILXUNT9T6hayuFeb0V5ScAevEdc Vee/8482ks/lrW/Nk6FZfN+t32qwluv1ZpPSgX/VohK+xxV6pirsVdirsVdirFPPHk3XPMRtG0vz VqHls23MSLYiJlm50+2JFJqvHah8cVfK/wCRHk/XvPH5l+a9YtPNN/YXFhyB16FY2uJ/rEzKnPns OccJO3hir6x8k+WNW8vafNban5hvfMU8snqC6vhGGQUA4II1G21d64qyLFXYq7FXYq7FXYq7FXYq 7FXYq7FUl87eYo/LXk/WdfkoRplnPcop/aeOMlE/2T0XFX5/flBpVx5m/N7y3bXJNzJc6nHd3jP8 RkWFjczFq9eSxtXFX6B+cPKumebPLOo+XdU5/UdShMMrRHi67hldCQRyVgGFRTxxV415E/5w/wDK HlzzFBrOqarPrgs5BNZ2TwrBCJFNUM1GkMnE70+EV61G2KvfcVdirsVQuqT39vp1xPp9qL69jQtb 2ZkEIlcdE9RgwWviRiqTeQdEvtJ0F/0inp6nqN5eanfRBg/pyXtw8wi5KSp9JHWOoNPh2xVkeKux Vjvmr8v/ACp5qns7jWrNprmwEqWtxFNNbyLHcLwmj5wPGxSRPhZTtTFU8s7O0srSCzs4Ut7S2jWK 3gjAVEjQcVVVGwAAoMVVsVdirsVdirsVSD8wNb/QXkbzBrIbg9hp9zPER19RImMYHuXoMVeKf84U aH9W8i63rLJxfUtQECt/NFaRKVPy5zuMVfRWKuxV2KuxV2KuxV2KuxV2KuxV2KuxV4z/AM5b66dM /Ju8tlYq+r3dtYqR1oGNy33rbkYq8I/5w30MX35qzai6kppGnTzI/YSzMkCj6Ukf7sVfbuKuxV2K uxV2KuxV2KuxV2KuxVKfMnmvy/5asUvdbuxawTSrbwDi8sss0n2IoYoleSR2psqKTiqp5c8yaJ5k 0eDWdEu1vdNueXo3CBlBKMUYFXCspVlIIYVxVMsVdirsVdiryD/nK7XP0X+TGpwq/CXVZ7axjPc8 pRM4+mOFhiqbf8456F+hvyY8swMvGW6t2vpCerfW5GnQ/wDIt1GKvScVdirsVdirsVdirsVdirsV dirsVeNeYP8AnLD8qdE1q90ic6hcXFhNJbXElvbqY/Uico4UvJGTRl60pirwn/nJT89PLH5i6Zoe n+XEu0gspp7i9F3GsVXKIkPEK8ldjJXwxVD/APONX5veRfy3TXp/MCXkl5qZt0t/qsSSKsUHqFql nj3ZpB92KvdbL/nMD8pLq7htgupxGZ1jEklsnEFjQV4ys33DFXt2KuxV2KuxV2KuxV2KuxV2KvCP NXnHSNY/Pzy1azW2pTaZ5a02+vLi2Gk6lI5uLsm0DG2Fs0jxhfsy8Cm+zVxV7L5d8uaF5c0iHSdD s47DTYCzQ20QIVTIxdjvU7sx64qmWKuxV2KoW81XS7KW3hvbyC2lu39K1jmkSNpXPRIwxBZvYYq+ df8AnMCS81q/8j+RtP8AivNWvXl9PfZyUt4GNO376SvyxV9F6Zp9vp2m2mn2w421nDHbwr4JEoRR 9wxVE4q7FXYq7FXYq7FXYq7FXYq7FXYqxq7/ACy/Le9upbu88qaNc3U7GSe4m0+1kkd2NSzu0ZZi T1JxV8V/85QweXrL82bvSdB0200u00y0toJLexgjto2ldPrDOViVFLUnAJ9qdsVfQX/OOH5V+Sbn 8otG1HXPLum6lqOotcXL3F7ZwTy8DM6RLzlRm48EBA98Veo235Yflpa3EdzbeUtGguIWDxTR6fao 6MpqGVljBBHiMVZNirsVdirsVdirsVdirsVdiryT8tlOrfnV+ZfmEj9zZvY6JZt1p9Xh5XK/8jAp xV63irsVdirsVfPH58/lF5g8w/mfoXmw219qvlqzgihvLLSvRe+jeCZ5aRxzywLxl5j41JK7/D0x VlflTyJr/mT80pvzP832B0tbK3Fj5V0OZ0knhi+LlcXPpl41kb1HKqGNORr9kYq9cxV2KuxV2Kux V2KuxV2KuxV2KuxV2KuxV+a35r63+nPzL8z6oG5x3GpXPoMe8Mchji/5JquKv0M8h6J+gvJOgaMV Kvp+n21vID15xxKrk+5atcVT3FXYq7FXYq7FXYq7FXYq7FWKebPzK8t+Vdc0jSNX9aOTV47ueO7V V+rQxWMfqyvPIzLxHHpQH6MVSH8gdD1Cw8jS6tqcLW+qeadQu9eu4ZBR0N7JWMNXv6So1O1cVek4 q7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FUq826yuh+VdY1pjQaZY3F3Xr/AHETSdP9 jir85Py70Ztf/MHy9pThpFv9Sto5z1PptMvqt9CVOKv0wxV2KuxV2KuxV2KuxV2KuxV2KqF3YWN4 EF3bRXIiYPGJUVwrjoy8gaH3xVXxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV5X /wA5Pa4NJ/JbXeL8JtQ9Gxh9/WmX1B/yKV8VfMf/ADiZof6T/ObT7gjkmk211fOO3939XUn5PcKf nir7wxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KvDv+ci/zI8wadqXl38vfK101lrv mqeOO4vojSaC2mmECekR9lpH5fH1AU061CrCvOWh+b/KP5xeWND/AC70jUIoh9Wm1DWWmvbgX4eQ i5+ttJIbb01QfF8IIO9Rtir6mxV2KuxV2KuxV2KuxV2KuxV2Kvmr/nN3XfR8s+W9CV9728mvZFHW lrEI1r7E3P4e2KpP/wA4P6ETN5p1512Vbaxgb/WLyyj/AIWPFX1birsVdirsVdirsVdirsVdirsV dirsVdirsVdirsVdirsVfLDlvNn/ADmiqn97ZeXhQf5As7Qt+F3Lir6nxV2KuxV2KuxV2KuxV2Ku xV2KuxV8T/8AOZmvfXfzOs9LRqx6Tp0SuvhNcO0rffGY8Ve5/wDOJfl79E/k7ZXTrxm1m6uL96jf jyFvH9BSAMPnir2XFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FWJ+evyt8heeTaP5r039 Ifo8SfVSbi5gCCTiX/uJIga8B9rFXyx/zjb+VfkX8wPNHm261fSzdeXrAoNNtfXuIhH9ZlkaL445 EkbjFFT4mPXffFX1j5J/Lzyf5H0+fT/K+n/o+0uZfrE8fqzTFpOITlyneVvsqNgaYqyLFXYq7FXY q7FXYq7FXYq7FXYq/On8276682/nR5gNkDc3F7qrWFio3MnpOLSAL/rCNaYq/QLyroNv5e8taVoV tvDpdpDaI383oxhOR92pU4qmmKuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KsV/NXXBoX5 a+ZtVD8JLfTbn0G8JnjMcX/JRlxV5V/zhhoYs/y11DVXSkuqalJxf+aG3jSNfukMmKvf8VdirsVd irsVdirsVdiqR+efM8flbydrPmKSP1hpdpLcpDWgd0U8EJHTk9BXFXwVd/n/APnDeeYRrX+Jr2K4 9QPHZQSMlmKGqx/VR+6Ze3xKSe5JxV91ea/NzeW/y7v/ADPqarb3Flp5uZID0Fy0Y4Qip/amYIN8 VfJv/OJX5eXPmTz+/my/Rn0zy+TMJX3Et/ID6S1PUxgmU+B4+OKvtnFXYq7FXYq7FXYq7FXYq7FX Yq7FXYq7FXYq7FXYq7FXYq8U/wCcvNd/Rv5PT2SvxfWL22s6DqVRjct9H+jgH5++Ksv/ACI0H9B/ lB5WsSvB3sUu5FPUPeE3LA+4MtMVZ5irsVdirsVdirsVdirsVSzzN5fsPMfl7UdB1AE2ep28ltMV +0FkUryX/KXqPfFXyZ5b/K7X/wApPNbX2vfl9N55gtpPW0nWdMeWURFNxI1qokHJaVHqKOJ3BOxx VlHnZvzh/POSy8v2nlq68neTo5Unv77VVaOSUgVVvTYRNIq1+BEBBahZh2Ve/eQvI+heSPK9n5d0 WPha2oJklb+8mlbeSaQ92c/cKAbAYqyDFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FWKe bPzU/L/ylqtjpPmHWYrDUdRobW3ZJZGKs3BWf00cRqW2DPQbHwOKvFv+cpra582+fPIH5e2RJmvp ZLm6C7lYpXWISkAHaOOKZj7Yq+kbeCG3gjt4EEcMKrHFGuwVVFFA+QGKr8VdirsVdirsVdirsVdi rsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVeN/mr+RVx5p/MDSPO1gLK+m sI4obnRtTknt7eUQSNJHIJrdJnrVqFGQqRiqe+R/yy1W185aj5/843NtfebL6MWtpDZh/qdhaKAB FAZQrszU+Jyo77bmqr0fFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FX//2Q== uuid:9E3E5C9A8C81DB118734DB58FDDE4BA7 xmp.did:0680117407206811822A82FE73F5DC9D uuid:85378e9b-2104-8344-9526-0678540bacd5 proof:pdf uuid:4df742e1-b560-f343-bc30-f4939a8dc13c xmp.did:048011740720681183D1F98A17CA7014 uuid:9E3E5C9A8C81DB118734DB58FDDE4BA7 proof:pdf saved xmp.iid:048011740720681183D1F98A17CA7014 2016-12-26T19:54:37-08:00 Adobe Illustrator CS6 (Macintosh) / saved xmp.iid:0680117407206811822A82FE73F5DC9D 2016-12-26T21:29:07-08:00 Adobe Illustrator CS6 (Macintosh) / Basic RGB Document 1 False False 256.000000 256.000000 Pixels Cyan Magenta Yellow Black Default Swatch Group 0 White RGB PROCESS 255 255 255 Black RGB PROCESS 0 0 0 RGB Red RGB PROCESS 255 0 0 RGB Yellow RGB PROCESS 255 255 0 RGB Green RGB PROCESS 0 255 0 RGB Cyan RGB PROCESS 0 255 255 RGB Blue RGB PROCESS 0 0 255 RGB Magenta RGB PROCESS 255 0 255 R=193 G=39 B=45 RGB PROCESS 193 39 45 R=237 G=28 B=36 RGB PROCESS 237 28 36 R=241 G=90 B=36 RGB PROCESS 241 90 36 R=247 G=147 B=30 RGB PROCESS 247 147 30 R=251 G=176 B=59 RGB PROCESS 251 176 59 R=252 G=238 B=33 RGB PROCESS 252 238 33 R=217 G=224 B=33 RGB PROCESS 217 224 33 R=140 G=198 B=63 RGB PROCESS 140 198 63 R=57 G=181 B=74 RGB PROCESS 57 181 74 R=0 G=146 B=69 RGB PROCESS 0 146 69 R=0 G=104 B=55 RGB PROCESS 0 104 55 R=34 G=181 B=115 RGB PROCESS 34 181 115 R=0 G=169 B=157 RGB PROCESS 0 169 157 R=41 G=171 B=226 RGB PROCESS 41 171 226 R=0 G=113 B=188 RGB PROCESS 0 113 188 R=46 G=49 B=146 RGB PROCESS 46 49 146 R=27 G=20 B=100 RGB PROCESS 27 20 100 R=102 G=45 B=145 RGB PROCESS 102 45 145 R=147 G=39 B=143 RGB PROCESS 147 39 143 R=158 G=0 B=93 RGB PROCESS 158 0 93 R=212 G=20 B=90 RGB PROCESS 212 20 90 R=237 G=30 B=121 RGB PROCESS 237 30 121 R=199 G=178 B=153 RGB PROCESS 199 178 153 R=153 G=134 B=117 RGB PROCESS 153 134 117 R=115 G=99 B=87 RGB PROCESS 115 99 87 R=83 G=71 B=65 RGB PROCESS 83 71 65 R=198 G=156 B=109 RGB PROCESS 198 156 109 R=166 G=124 B=82 RGB PROCESS 166 124 82 R=140 G=98 B=57 RGB PROCESS 140 98 57 R=117 G=76 B=36 RGB PROCESS 117 76 36 R=96 G=56 B=19 RGB PROCESS 96 56 19 R=66 G=33 B=11 RGB PROCESS 66 33 11 Cold 1 C=56 M=0 Y=20 K=0 RGB PROCESS 101 200 208 C=51 M=43 Y=0 K=0 RGB PROCESS 131 139 197 C=26 M=41 Y=0 K=0 RGB PROCESS 186 155 201 Grays 1 R=0 G=0 B=0 RGB PROCESS 0 0 0 R=26 G=26 B=26 RGB PROCESS 26 26 26 R=51 G=51 B=51 RGB PROCESS 51 51 51 R=77 G=77 B=77 RGB PROCESS 77 77 77 R=102 G=102 B=102 RGB PROCESS 102 102 102 R=128 G=128 B=128 RGB PROCESS 128 128 128 R=153 G=153 B=153 RGB PROCESS 153 153 153 R=179 G=179 B=179 RGB PROCESS 179 179 179 R=204 G=204 B=204 RGB PROCESS 204 204 204 R=230 G=230 B=230 RGB PROCESS 230 230 230 R=242 G=242 B=242 RGB PROCESS 242 242 242 Adobe PDF library 10.01 endstream endobj 3 0 obj <> endobj 49 0 obj <> endobj 50 0 obj <> endobj 28 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 64.0 64.0]/Type/Page>> endobj 51 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 128.0 128.0]/Type/Page>> endobj 52 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 128.0 128.0]/Type/Page>> endobj 53 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 256.0 256.0]/Type/Page>> endobj 54 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 256.0 256.0]/Type/Page>> endobj 55 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 512.0 512.0]/Type/Page>> endobj 56 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 512.0 512.0]/Type/Page>> endobj 109 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 1024.0 1024.0]/Type/Page>> endobj 147 0 obj <
>stream HdTˎ@ Wg? 8par$3iWr˥>=_~xpV^u|+g@?[Jm1ǰZ'3ZkI6=2H^nvD4^ƙl)y N,NU50Qh,(zɦ^ LO bBAΝ$CiνϩUq_1H2@Ĥ6N!ze1 4b:̊c(Y#( I V#vD 5'CX2p sTp'&#F1{Oaz/^&])nM%/N˅zk/qaCW2wj &D"5ѡ3ZYқ pPkS0' !e4?"ި(!zY-lI;AA90=PDJm_a=HtlZ޼gޔ͇X:$k'/\Ce3U=, !KƩCۂ{vnx 0LYtEumx^(/3i/\v endstream endobj 135 0 obj <> endobj 148 0 obj [/View/Design] endobj 149 0 obj <>>> endobj 140 0 obj <> endobj 139 0 obj [/ICCBased 150 0 R] endobj 150 0 obj <
>stream HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 N')].uJr  wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km endstream endobj 138 0 obj <> endobj 151 0 obj <> endobj 152 0 obj <>stream %!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 16.0 %%AI8_CreatorVersion: 16.0.0 %%For: (Philippe Faist) () %%Title: (klatexformula.ai) %%CreationDate: 12/26/16 10:12 PM %%Canvassize: 16383 %%BoundingBox: -425 -1053 1693 511 %%HiResBoundingBox: -424.7539 -1052.6367 1692.1826 510.0825 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 12.0 %AI12_BuildNumber: 682 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_Cropmarks: 141.0146 254.0825 397.0146 510.0825 %AI3_TemplateBox: 128.5 -128.5 128.5 -128.5 %AI3_TileBox: -18.9854 26.0825 557.0146 760.0825 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 6 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI9_OpenToView: -676 875 1 1688 952 18 1 0 -4 38 0 0 0 1 1 0 1 1 0 1 %AI5_OpenViewLayers: 7 %%PageOrigin:-272 -428 %AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 153 0 obj <>stream %%BoundingBox: -425 -1053 1693 511 %%HiResBoundingBox: -424.7539 -1052.6367 1692.1826 510.0825 %AI7_Thumbnail: 128 96 8 %%BeginData: 4300 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C45FDAAFFA852F87DFD7CFF7D527D52FD7CFF277DFD7DFF7D2752FD7C %FFA852F87DA8FD7CFFA827FD7EFF5227FD7EFF277DFD7EFF277DFD7EFFF8 %FD7EFF7D27FD7CFFA87D7D52FD7CFF522752FD7EFF7DFDFCFFFDFCFFFDFC %FFFDFCFFFDFCFFFDFCFFFDFCFFFDF7FFA8FD7CFFA8FFA87DFD04FF7DA8FD %07FFA87DFD10FFA8A8FD5EFFA8FD04FF7DFD08FF52A8FD0FFF7D2727A8FD %1BFFA8FD45FFA87DFD07FF7D52A8FD0FFFF8A852FD1AFF52277D27A8FD3F %FF7DFFFFFFA8FD08FFA87DFD0FFF7D27FD1BFF52F8FF7DF827FD37FFA8FD %06FFA8A8FFFFA8FD09FF7D7DFD0EFFA852F8A8FD19FFA8F852FF27F852FD %34FF52FD04F827A8FD09FF7D7DFD06FF7DA8FD0EFFA82752A8FD19FF52F8 %7DFFA87DFD33FFA8F8F827A8A8A8F8F8A8FD08FF7DFD06FF7D52FD10FF27 %7DFD1AFF27F8A8FD35FFA8F8F827FFFFFF7D27F827FD07FFA8A8FD18FFF8 %FD1BFFF8F8A8FD35FF27F8F8A8FFFF52FD04F8FD07FFA8A8FD17FF7D27FD %1AFFA8F827FD35FF7DF8F827A8FFFF27FD04F8FD11FFA87DFD0DFF7D27FD %18FFA87D7DF8277DA8A8FD32FF52F8F827FFFFFF27F8F8F852FD10FFA852 %A8FD0DFF2752FD18FF2727F8F82727277DFD31FFA8F8F8F87DFFFFFFA8F8 %2752FD11FFA827FD0EFF277DFD1AFF52F8A8FD34FF7DF8F8F87DFD18FF7D %7DFD0BFFA827A827FD1BFFF8F8A8FD34FF52F8F8F8FD19FF7D7DFD0BFFA8 %2727A8FD1AFFA8F8F8FD35FF27F8F827FD19FF52A8FD0CFFA8FD1CFFA8F8 %52FD34FFA8F8F8F827FD18FF7D7DFD2AFF52F852FD34FFA8F8F8F87DFD19 %FFA8FD2AFF52F87DFD34FF52F8F8F87DFD44FF27F8A8FD34FF52F8F8F8FD %44FFA8F8F8FD35FF27F8F827FD44FFA8F827FD30FFFD057D27F8F827A8FD %047DA8FD26FF7D2727FD15FF52F852FD2FFF52FD0EF827FD26FF277D52A8 %FD14FF52F8A8FD2FFFA8527D527D27F8F8F8277D527D527D7DFD25FFA8F8 %FD17FF27F8A8FD34FF52F8F8F8A8FD2BFF5227A8FD16FFF827FD35FF27F8 %F827FD2BFF7D27277DA8FD11FF7DA8FFA8F87DFD34FFA8F8F8F827FD2CFF %27A8FD12FF7DF8F8FF52F8A8FD34FFA8F8F8F852FD2BFFA827A8FD12FF52 %F87DFFF852FD35FF7DF8F8F852FD2BFFA8F8FD13FF7D27525252FD36FF52 %F8F8F8A8FD2BFF7D27FD14FFA87D7DFD37FF27F8F8F8A8FD2BFF5252FD4E %FF27F8F827FD2CFF277DFD4DFFA8F8F8F852FD2AFF7DA827FD4EFF7DF8F8 %F852FD29FFA8F85252FD4EFF52F8F8F87DFD2AFFA8A8FD4FFF27F8F8F8A8 %FD7BFF27F8F8F8FD7CFFF8F8F852FD7BFF7DF8F8F852FD4CFF7D52527DA8 %FD2AFF7DF8F8F8A8FD4BFF7DF87DA8F852FD2AFF27F8F8F8A8FD4BFFF827 %FF27F827FD2AFF27F8F8F8FD4BFF7DF87DFF7D27A8FD2AFFF8F8F852FD4B %FF52F87DFD2DFFA8F8F8F852FD4BFF27F8A8FD2DFF7DF8F8F8A8FD4BFFF8 %27FD2EFF52F8F8F8A8FD48FFA8FF7DF827FFA8FD2CFF27F8F827FD48FFA8 %27F827F82727F852FD2BFFF8F8F852FD49FFA8FF27F87DFFA8FD2BFF7DF8 %F8F87DFD4BFF27F8A8FD2DFF7DF8F8F8FD4CFFF8F8A8FD2DFF27F8F852FD %4BFFA8F827FD27FF7D7DA8FD04FF27F8F87DFD4BFF7DF852FD26FF27F8F8 %F8A8FFFFA8F8F827FD4CFF52F87DFD25FF52FD04F8A8FFFF7DF8F87DFD4C %FF27F8A8FD25FF27FD04F8A8FFFF27F827FD4DFFF8F8A8FD25FF52F8F827 %7DFFFFA8F8F8A8FD4CFFA8F827FD26FFA8F8F8A8FFFFA8F8F87DFD4DFF7D %F852FD27FFA8F8F82727F8F87DFD4EFF52F852FD29FF7D52277DA8FD4FFF %52F8A8FD7DFFF827FD7DFFA8F852FD79FF7DF827FF7DF8A8FD79FF27F852 %FF2752FD7AFF7DF87D5227A8FD7BFFA8527DFDC6FFFF %%EndData endstream endobj 154 0 obj <>stream %AI12_CompressedDatax]q%uίEX_  MKmXkECԾ:Q{GFNJ7??Y;no/߿zRz7o{~ަ1 ߼~{W{_}7~zگ7ŇW߽7/^i؎~eGϿLm:~~-^|2}og5۟,-%俼o>ޮV&7wg9;wivپ޽Wo?ݛw_o^?޼y/o^{4߼Ջvx&Ho_}?s qoXvX q_7>|k0!??~|GO}ՋdT*.N߾k>&ۿvzim>u~y{K8~o߼zwo_8!z^|7|L˿o_|: >_&o~ow^~ގncmWx`Ę5EzݿZ_{oq̛ߌ/~[_׿xn~"c_4`ۿm_lSovaO޿/mO~}.~a/oNj_՛o_|_=˱/qPӓpn ۯlj^|YWof[_/\xy |o~w޽Y:)>+o}z&3ww`|o޼_ϝ3_gWo&Ջ^|7ë˽}pˋ/ׯ_ч~io_xuy@o~W{-ؾ0ӿXyv_kO̕{x=Oo.?ڬo7]izs؏Vetm aYSmO΀ړ?j63 l>f/<|\EkX+xxV<Ͽzgۛlz&|ߔ3\+sϰόM?>rOO_ܔSKϸg ۘYcyVQճ:PT7s[ivf{hY{idz6s9<;,>?O2 sxx>Ӎbn󜃗䧯gs<}y: /^H]{tǹ>?3sσ IGfԅOd ٣Ni򒟚}M?@?v:>{?3xVyf*EeMM<ПggاsєccO-D]|=ԇb(=Ovŏ~b-;O7v;a9f7kfS)`Ovcvf\L8L <ߛSb %aӍqFyXw<=7O㰱7l 6^a/ { b8@zA=!l^c迗f"L3 3⣡Ax^}4P 9ʴc'Þ]Z{{4tSi `W2*Xss4a$;7{$n'hʲdQp h y   c@#4P|3 LحOtC&~?nF{?~R{|8=ˈR<<<){vOo(dJdj4=$5S8sr"T13eĬ58p<*$mi`k|!s! .8b탩.w<ӻjFqVz"i‘/y)͒=dS3ӏCʆ=:Cfqp2{v6<3:4 $f.Gl܎Ubj79ws\m5@ _.M'|Fx|\$Nuz{FW.m &G - `a3h@n|B;T|Pq ]յ]r'!4a7h)hbE5{'b:zv0!3|gè̂O1V3@TTf't2ݠFgɣK p{lSdo#cL?[deDq:r~h>0s~k~YEwog іf (R(PA``PˍѳhDԓ5lyvc7Bp$Bt#G4,|dY,D[X ٠i#sB 6:oXXZ"Qt0W4{f=g<_dyE4=@?(Eq " W#|WAxF0Jz|4 u1POz #+]Oٛ~1ն({[{ٵAigm\Mk4׾ޏ|;;;ϖIRL/i\KhWӇו˷ju9~s"oH\mefWf-3-i'9SO1ɾr=y˶nVskY_\u~!?za kbXSʦg˕W+Y(o]̬WSn3 #{1e-ZZ(n1Krzki$} f?e4oo+&.9J~"IuIU[ U~MTӪA]PeWvof F r/j?Lw ?iozB0J#e{3GgFR=O.Vr޽@=`znT5Xp5eaF^s7W)OU#%%-ĸj[n<0=^Y99 )Y*GjdE+PbfUUR+XJkY^Z,Ǜ'a½{RO6؊4wsٴғ@58aRP) Ms.#yF|y>PJ7.}l/}zd"UծY>0r܋-ϩ[BAMBHR%Ktjl::@ \!J(5Z*|>K=Į3J,u*T@v#,lMrnHdJ81pQVgHnVm,q#TcWϨǍkȓC`MSvt.eʄ)ztd}?AT4 h>(H%ׄu4|jͼNNdibb 6uZȩ{5ը(BLA))sINٰ1_|8rC3%61< aH3'`jxizi`{J9`d3n7@ng0ctN&Bp:7fd1}$Xgtv ;?7zF=;jMBxQ|0]eܘbhD<ϓ)#6ȍΥbi O &_~TUGUQ>Q-)"va?Ffڥw}?);Ǥ׾w?~ëvE VVVVVVVVV@K ?cX}V1$- fO.xޝey6ygTx?&=W_@R!o.]>+~ s"ݻ7??/ĂËdB_1vx2_ /Ǽ^0* ߿^6vn{Xv߆-62d(%vУaA|4'82D LvߎtgOҎ]ϻ;̴cNzn(wGC'3=L ml+ FRιuPhQNұOeV6%;kصVߥNo:0vf{Cλ rM|vl.q3wfviJ4.3kφ㚐O~Z4le%͆mNNC=ܪ]j^/st;p5Rp](w J%WQ댍02x45aOtrrv`P3KrƵƭ, ,:|#fwJZ߸^ ޸oSR3XFFƟv~cqe 9fC0O *gc@BjP{n3A= oȗ,r۳ⱋ 406ͨτسB]]3aw_˳ǡs\pW0y $)Bjf)8Sݚ~8 ԝ<`,lDN^IlA;0jXib1ucf0f̕i܉Q1!@x B{~rAPflBg<<&:ջ5Pٵq_daafffausU!֭%Q b~x蘕< NSq6$ 4;P,p8l{Poi6et ָlT( oTEﶡ7A62۳`Zi/x7&`>i|!8`|~2\e{7pP\ ꯹T0BS*sP*o,Ê5(D59V[ee4M5ƦLN6e4nBS5͜6cj7a+-F<>-`U5֋L;8v3i=ucͱ\ƒl5O4N7fOTaBMplw)CT #ܻpp~p#bݍ'N!Gzbq_g4 a3F} ;ՙ# BZ NPI6Y5ME q[sΤ/݋פ[fNyn 8`'wJ1Ƥ+2A˸!ǂ>\6N0.e4uh>A 2íڻ-v趇S-0 Ohs NlAᘴynfnAjV%&nx=j"ԭ5ٜ q@0ͤn]3e]8 `C`cbXp{yFP!J A;lkmq,ϻKȾ-SkS '.<<ƥ5bHڲ Cj6ژwݞ*Â"{,( 7pJ"?;f9Q q<^=>[ `oaF1.ϙ܋f1@Hg:'8KX3S6G!/qL[3eeSIhS3D^M5np(`J'֮wafaA@u@T8m@2,YK>8Nnx+給y401&ن=o1v:'1O LAa|!Ûc'Te rƻalF`s4IEXW{"3sR1. q(t '_dq{Bd#}CWDwtBvLzejwffD(d\灷!m Lh1 VN'G ߟm2ۀ[KGy\$֦rPyC L/9 nUΦs )xae3ȼAtEC'-n,o eVeJ:jeѺ"KZRDE.ce^aװ65fOEA*y/nhݧA},zWwʹeȄ'z}Cmc(iWkYl;@χԻbB40|J C{-t4y\| 8 1@^L v@oҌjN;\Âg`Ҟщ/Cy-۰SxvsT4bhe;N&(,. )aKL/ ɩeؘ#Ԟ>R8%QM{JhJHaml3"cA)_k(dP ם1009ɑ@l !RYH&AV:Ux91BHϓ[5:.Lߵ. /; رCRf]F3M¡#]3 f+\N>`p=J!G6zPf?"[fu! F&LJIrV}6)qdb)ϘPA% ,TB~Nia!19_ҘigkaF&/NDɿS9xYّ6#As0 k`t ];%MBc^Ujpepwf2sCPe 䐡YaZ#_aTBAHaN$&PB2ALf!ed e [Fn7G^bhW=gW0J!L9pXoLۃ;JWjC KqbSS 5+(@K> 0 I簕Ie(( ;3ɐDXiкiFj:S*  [eN~em  YӍ&X'BncE㝹ch%jTo`v"{!{QF":hL& evbt4J< 1㹐HBvoMGMY2f|\!lLz2LC,Gc<1!/gLWXGd07ڀPaH26.O^}(rW8@r2g:ӺUtVɛV -=U KgpT+>ô3Æ2o6׮X 0̑?a,"P(@{kRfhy,V`ppN&!YD΂Ɛ C`f[9Q3׼|x̂E-G#2 xA5YMU|zErDitF9M p Q1J_V8ӇѮnj0M>ဠ U[d|"?qNːoeO͜'5-v;y@|ppŖK* 59*QX|CQϼV7-YY#8pC@g`d Q.[gqPbj)K-J) h+F`ڇsB;iFF':Xh긶E7;yq %6[z~ !c>UOlt)uģG館ǜJ4>sD̿CLˏ`թJ!l̼*| q,QY{td|e 8e#dcਗb b"KdJXW#qݣJe7@f0U(tIk{jp՜I(^J\(m(<1"c6V*cݏ8l^CmQ-n2ǽh۝F^jw;!иV1@1Q0RMC^U nQ 8 WT Fcr|ż +=BM2/4!r 7^[y \"\LXR^ _ ]`zUԏҺT+1 J (dp2[VelGΫdOe1dO@ںYT#j#2 aX$U!"-@BX-rx8"RnESaJ(U%jCNg9dsab|< ЪO9}켡'Jt2U/U=8_ӑIL%nt0rpRCA7HE|Ї3+pE+lY/.ӔuOSWEnth]êfU)1cZQ7`\Da%z0 - %|e ?OO  (` rPn]9ߑntB)CK,ENk/"e `pp `0~Dd3=$?&g1uDX%^ !+ N9-X$h5EĭKVN)܀C!eLLųm8%u]b%LFeK٨3+MAn! z&nul'.$\l ó>3YT%bVr֓N{ A|5|ȱyRqY^#1vCTRrNǸ$wa,/9>wObTs2 sPŠmqSD)wz(2%=3oFQ?4x_KPt!K6j(Z O! Xx@ (B!v8b/!ua%Y 3ᐶ.3[ `Shxu<5-Nlry@hD^w͸-֣<[.!.M!50-bY;t>)L9326TĎtD.rgb(!Y6,HșKӦpzrF@ZQ% *U9%ah:; T!ETو\:b,áG&#!vx%"ZdU`TeX([ `igí&|w<0MLU6A55E4Xdbk}\ =֞f⬅}^$C [[ZWwE0hk7&, Y.0kTA~"9T-\?6p!\}a,F%"_Mc7D,&`>u3H e7P87Ud `4𺖝Jj(lMf%iFI4 .759Z0(`fqǨ2n-;2O3 Yw4U,W q[ 5 C- ֜= pJ#9 9Q4n*(qqEN,dlπmV`qDR?t8mVZ ԡsT`vdxK_$]`¼Vqwu ҽRwIet'GϾ^AoK` ۢecExo0AԬ/# LD<2(taR_Kee7D|@~Y$Y@S0۟0K_vQw@zs@ tpWO&9a R5Z}EXѢԣ 63˅el'Cqv%a0XOYg^}rhm)T!'PVvz&D\]fv"L"8[Pdb& Vr&N` zmTf0RZ,f?>:>N;'TVReH@% P" hDUY5#:x9΁_ |ub9^B;QKDnvӯOa^_fN%܆(QA}GOC!9oYqL !K!(EVj=y ;DAc183grS/rza ƏҔ^آ$83F,i#)貀BbYf/t5j.Y 2duv(;KΖSߥZ$?YuϤW R.CA\ϼD`[xd2 _@.+R+ LG5+WQa)4/r'Qp5]Tս杙ӧB6/!$!7TT{64NP)9쿬tgb7Τ+G?:U,̣d]$%҂ 䥬 @T!,;JDI50C@ˆ5ʧlgQA@NrUb7&ЂWCǼ;+$ 9>ٙZQ؅3ԓH^8؃mpD /@PyVQչ0(2R94=}w6T^յ%hv^WYFh\S\jq dC:=᥾T|:_&!9tt!1MMd(`U."pHh6 'HT Z4_ApDUMhdwDE#'uz+# Bt`nn!`]"Ld謢< 6ae yF+@6jl5?u'A!탔lNty9ԝIɟ؉fC(Eabb^Mξ7}vGyVlD0.d {xGISaYwmww&8^|좘,$APadb\ 7}2gP?:9)f ;TǠGঠM<3g) %P[4$t3P0/ߎg>pO K ȩb,yTv>v@G@qϰ/~W/> AGv|ݷ__w䧷?n>!(s?Fu@3!qXl$M{n2Eے׹sQ"ve,\vEŲ7\9m.R54lG;3Y8n. f=cr/y:ղryoAp"vBrVA[3L5X|)·B[zƮrcQ(yԆ+Qnys'`R7ΓvM\g47\)r\t2?E=qm\~^R6G!7D\ܸ -tQXp5."1#l̸\ĸ3F/^\5+.|$N Qt v9Iy!sέ+>hEr:\PnN j΅ۇhA۫SoL3Ak(;mEƈYΤS{W؅bw\Lwq4a' Ap߲ o9瑕mg> [zbK۹o#PW ߉O;թh4oܑ [ XKޘoEVN|VYA-Ŕulg ķtUq3;fނTr0F3G;-dLAwrvhNtu GtVV0N-[j)b܂sSܶ)V`mϱ6G-0$l )ng8O0!Ōhm $/c_ے$*En{ԶHqCivj[6˞9mlhlA\ZvC6۠}[ĖƇ}~b?!S6ck 1/$%QFȰעqlpע#[OpA2qmyjq![xUtH;g-$RkQRhrCtuFW^8FVk !q&UZ6 )Y(&vZx2 v&>Ei wP6 vP Y4G0.>;c hlvfZqNL LyV_`%lᨋ g,I vDn%-\3҂Wx#ʬԼi"w,D)R`-v)튉iѢ>lcЖТHEM=eOd;-,낁/|",W䳽M^Za?{Pzi_g.A3b^B&*HgpxcLVlyc)%:_!Q$xc| eG[R‹icS 栍3u&BJ;m,m,vTU"hcIڃw :(%5Vd\Xcysk,hwS=rˊ5orgE]H'gcR"XcYXcY #IcWLƒV˝4:9Hcq=i,rpk,Md< XJ;m,ic)!X/hc!am,)WՓ5J7-XXhcY@rXxT8NwX0*N!!AF;[:g,B㰓`#Eֆ5bRS>T)c396 cQHN¾b'$tǯ,X]Ŏе @|+X4`~!ewSwQ,o`q`Eiɝ(vYbbYbF Q+sP؟R%ѮbaD9)DQ҂^9(bșEvX>'feF!'] *bU%y1IJ!WL&bW9:bqbZA Ρ|$8b)lF98b!`a爅0eO (8b):cG,@G,h) P{;I0v Vvt<9;O,.Ol #E3Xb!#0Xb),p&[ܷN+nyM,մV;M,t&M,lވb%D<; (zD\wD@qiw(VdebNA sqvEKȡNs=@m 7n%rno m93l~്ֿn!qJXpvo#0W܇st[zGE,`!`/f\A mLe{g؂2hy;$H`&KualHJLRt{n  l:gYX%`=+E"eԯ`iZ, *g[į(f^dW=+Wbќ꬯(j:r0_+(eC(_`vW\Eƚ+TZzzthc{eG쐓 \c\^גk<kL8?'"oF 8:!})(^j'x%=dhN:I6]rgӒz'w.nWĜ\{DN ^̏o `;CZiB($Vw +c k,A #3cU7+1 ucYDnEtA :sSi:ʗ)]eyt wJW2&p10txte ateutUnʔ7JWfF+yxpQN]q ҃uі#Ui7Օ; = te/.m'tez L BWf1X]{脮T? t,}B< dqhϕ8 %HsTl| b>W\|h@(&"ozX\Lrh7xY5עٸ\` ra&hr40b(ndӱXKlL3tEd `sn‚̕y^q:452B]Y;k%ŵ{hv;+id8RΠ;f0X.k#pHK"ȳ|cob AzQ<"o%<[A1D nQmmQ_x[O\Jx\Y>YZeglz(9a+[X|qR;]+k/VFkVjWk"sQ{5*Vih"iE# .Zk|gsѳ Z_4 "Y=sq6-bW=YMSFL紬h"!ycepR '+_@=SB4WP7NB?G36 `KY,9bcEhU 2k\CbN0KQ̓c p2p k`uz;HX=N$Lނ52:־S)SN' ܝH({vUkNJ!y&2eXzU# Й kl CѪ/(XGt`%_3#NJ(v Vek`eF"YÑNO\qXXw-w<9#²L'$[sƲMξX?WمX#ԠTUżրkzltݵP`X-TvU&==7UWN[5tyU 13.UJKSr ^=1t}^eBN^1*WUlFãȠ^HEJWfBLpyw[lPDWyE.*0;*EnQx #i'^'.]2u;*1 ya+UxdA ī*,yEJ ^Uq;E<NJznA~;W`@(W)(Z=*jhz-SRbxPx6\aPS6"V*k#xwU=;*, ^Eyyx$c4xfx ;*xrr7līZ*ZZ;*H0^WU:"^E7Z8N Nī4oqU īī܊Wy䤢h5f3 oР^]{"tUyUMrE)YkK^j N _ }ܹWS=*{*kX⵿,ٔk`]e(UO95g]o+h U8fٛ.;8v$CЮr,yx[<-pU|%K]B@'g] ^W 7U>g8sNj5ɗ=މWR Uw)LPfx ,s $y:W!m1AIWW)azg^Ht̫ʱ̫W[ī>WīoBdxSEGH6B*rUX\īD *|CA*Tb]ȲwW̫Dϱ̫~)Z)sW3U6?䤪TzFʀ%]d3o vՋYu2p*ۏԃg#%.j(OtVvwUdot)WO%)X"\^[5Y Cmu‚*bsߥ(VyŴ@t8fu*,DYc1j>Q*dU'5ڂ&tr9RIjt;G*zY|`1V!W֝ i.~T,NƸbG A : t7*Γ+5\kdQ~fTxPyEzMJ Ί ~'ErD D"r #j!* QNgС$ >R/6-/*TaL#[cՃeɳ_z, AwxQV16kT5c ?Z\ttaZdqҹOsjt>첼0jqM|DrxOϖN{ UtpHOy QDxar˚Sfiwsf:5Ģ:ub:eGGD\,^xN5q,SJrHN\9N )E~K0f^Lqnءi ZH2MWkLAm-;8)Rv"[K.nSE ==a51twnS3AmIlxvbSpmIִyj +47{ׯWв%A`%Д!g3mު b0#O)h>0LGCH'p*S8j1B!LS;)8 awS)_Jkfw1Ա$ãà'^)LYj[`wӐiw &NZYF7ܥF]`.T ;o)`U\ʷ6yZv_`68K[]J@:ap+-9iwQi*|NW:\&Jl×qJǶU:TQܘJ'J_t8⊦tx!2XJZ;F^5+W8J)eQrC)ZS0&vyYYA3I;) rj3YԤÉU53:/)A;XIqAl RR o'%E^ԙOJ] AIz9H:脤C%`έ(SGh?sv!De^H Ǚ.4$hBv_yq "(HM 淝D )BMrlHHOgfYT=j %V[y,3989oH(H3og,g|:"ɞ'\CwRC#XOiFfqEJiAzS|y1QF %aY(TY;C鲍v"QCP=G$TF2cz+8GI1ˢGy)G (Zby Ԭ :_:}tdR)Xr;s8PB]5HO)&q P-eFq<C/;%8sL(AN@DpVpD[Hfj߼.F'?KNc *z`(d /zlfR/ҬlNj@ ;Yh7tٳq (Z)&¦ A|h.ȗ˱ON[fU5]sXe v˳wI z'=W -$`Xm\dA&{"PZ< NKc0A=w<|/vI BqZ@c[õ 9ewf!35 13 wbX4zpYZ@ih#=G k W0 ( y}ʨZ(lO!hnå]9BrZř3kH$a$Ly,.Ala°ߖ8>Nu@)؃="`D`1..q\Yxrd_ <)L6C$~@SEA#TfXSB}Jˇb)I4xOoT8r!]o@~.`oR6s` }<,W&l+ 3pQ22@T}̊누!Ċ4"AY:Y@vvÙZ HQZ;35,ķksLu$rnjݼ~8~ךP@;Q8S}a"%o!f5ܘ ;v QuNJMwa!^apgC) & -I{fzH. ZٞOIRR lIu: |JYRՍL%dD9KI݊|cb~Ԭ$L3)=ex'v^!gdA+r;,0K_ׄ]ȜNY@iɂ9bxC\!.V!HZXF8 W ۦк:p` U7|v%.$'ܨ@1"_')U PwSp\.{ʫg!U:| :j!"RMK)pHeMHg `q&v,J\,K]P \(X2ex:\CYIdRknMu&/5#;3b8s9>e(|}VUUl%8Pc.y  +ID\YbP6SP3&bu"qEΕU,#a 1~^"ikӯ=$Ac[%{#Ԃ#,\E'u(H&ei)!mN&,pT;䵴δYdCzEKJH EG9T3H_H]UDJ@ cGE)l5$=)vvMC'{ j@8Q 4 8,+&rC+BZ N "4|+1Ʃδ gx!^E"'^~DiP,u_`vⰌy}f؄3$n8$W_& NڄTA> <̗]H9=U؏LC*N=Mn,)#h: P#X&` ,8:@R1.HUNHĚNX٫8:7wxf:]<©^fsOɻ+MsK đv6q~FShX'yEIsu`б$X,eL1fyA^·PdHyd,ۀh̴C )3<"GHt8!~%qU&$M̤7W2rwE93c G\EI:FT!!"}@8DC¶$nx搜 v!|Fe\MMp'@@9Ir $- \ Cp &Q;鑳؄|8h*3֭KL:lvƇ; Ƨ-QفГ]1ٜ.ɗaEz2>&ѫ qc;)b9H&/];=ˌ:{tSݤ"<D3V3p$+&z.S\6$b+8g ,lE7!л"/K? {wMYM[⴩\:by%T&q`Θnz4 %5攓m |O)|@A~ X<ВP-Ke= \:ey9a)Tf !r |7\<46K 3K wZP > $^"M 5l#ş=`GM^aSl:3j՞rDM Q#A0PH+%A#aZaNBb>a2!Y[V<Tl@J9Σ\iKX~YTNł9}jjCWtH8zqK D$,u3,+K?SSx%gŞMGjv:!}:U<ieF ln:9p}j; TLv%׎Gr>-8'y*De`O_]h›\tɂ5Hzc_KiuW+vZw@ˢ\~ٮx6X3jGR|T;pGޘCunbD?@%R/۱FЛԞr@3E~XO+6Z-_6'l"60դ`][B`ŴFc~sH`k.{2F70Yli^TF)̇q) gT -keY6t,N@<a~D|T(e!UoGx^?TB֙fP4<ހ">3\Yۄ‚F)=쯱Z&"#ӳ(]z'21K ;3i%`)8pJkxn+tS:=1ι62t$1CS:=b8(R( 'ù<%gԎGpZnQCǛK&_I•GRhO1+NO@P 2n\II@}dzu!V "TjǶg7B8涒Ur*E@XU8c[r+:XN;{sgDZPӡ)z9ω-i,qдD 0&@KkOOE53<0̰|<r4vcTSeE*4+ī7ڈ gIhΚװr=@LLCY!F@ӡñ`pZ12iKLQɳ, {IGHج'3jlƅO!;/J ) -El8O* O@cag|]]ғ-xVʬfMo, ڑM/g9vyxsJ[+Ճ .By: r!p$GD(~jr8ME;Aɻ91^%{FDd"'%ҹZBLl!Y. dGIS5w4;)!#oP7V$qJF8Κw:Z߹:,2#׽U Y=; nAbVieC?#@\PlDj.G_Tz 6i!L;O?qh^-9lĪC2]".fzw:" =-Nx6u*dtoL4ţ1:'lӮs%C@ < Qp4Θ/'V?7d)8U:@xA.Vtymj:{OhHx] p&fDeGz9}"x d:RQU;L՘k* C#ٰj@|̒GJ̫۝ 鷤kB|2,?*UWP7p3'īZkM Z <"p.L?J\Ă!TU\KUh^: ԝ!J檱ّR#@ E)O;pLtI20ʥg"Y[W`LY)C7 ~stsqfT[1Nͦ*:y 9+Vlv{)u`Fx^b``Jך+M{ֻ@켰K<@Hpu%J`q آ9 jCi%ab?P cؒ7Ib_yfQcfGEpIw~{9δ$!yYU)JqM ~yر|xIe}K9F ErA#b-(u]ò!6S 1Ũ [ g4,ĞZZk"=^PiH]刧_=>FB>0t i蓌z5r ftcuΠ^r'CΌE9}igT,ı肠css.6?{ۙ`w4V!+ (7_RM;"$q;DiV#x>mzUU >*6ɶfXTvOI)WDZtʪ^ue{ Iɵ2Ts)3#A i-KR *N*.OL1K rRtxR\In7U:Kl!r` 3yƯJf9N`&~QXE^jJ~hIL!pTa>l8\!NR uHka懲DGQ/" `֎~x gg ; Y@}rH[I@Uy8G诗XqRn%"7FXs|$!y>b_$(k("AnˬX>idCŊ~Hv Q(SP% qZ_Q`fhP3%ɢVRrI[^q!C !ūqV6X~Bۛne89=E0l:Ae%XmҐXu٠Ty tI`t,Q x|JH&3Jj$FC78)r*2C+DAcJ[@(|IMB#nӈB$!IP&@eH80݌Y|R̄ۋE#7MziByBЎW\|'@#rQلKP[Mg勾dBXP$^\L>h hVa @E8V;)'ק'GaBeXP&['1lq=" 0(&iPI'!irQlZ/D˰ CVf 7'{ ՝$(-/fQxVV m"Rc՚I_<+)OsQ1XkЍ(s LW=]\ nFQ3Bs?HA2qgy1'7(b@AVc/H l&r J: b0+@ /˛1&25wol\yJƱ?D/e*?4sd{"Ш2'h9knDrM:̊[D,n"-M=7Ųg~}0p/9T*Œ&$4\0QSNy ^C#0xiFE VBn嫉 $`#Fs -#:ᑪ+ITeI:$:MpHT(bM! PEi:*ʬMGt&C tkv&;hc:JAL(4mr`UF%=8~YK[rqZpl}E&cOFKfnBҔ %:גߘT9 N |" ؀!DSy΃hb[B4CS":xq>+:4qslڜbC{kD<"C{*04yF 6%k&ɐ%3ߕNJD?溷 mDń$ +&4H$1K eQ#''A-MȄV8h꽄X#ݫCNX6@ASX"AS㙠0 *FY#L$T@wdj v8$)4N0AAř2 hzV+t @ "^y{X0c"402Wh^sx 4=zc.4@8ЈFqSzR%*C 4G\&}*hĦVgh<6{Xzb* 4"S*0wx# 4W`0{L 0д'vF/3 4q`( |" sR6P)ވ`XGh2@#  S8РAp4 ` MaH3 hD c9@R#v@&L h28-q\@S<8@J1"Y+4 n0*4 Q^ ДcT $]Vh^7ghTwiLFgz- >a?.*hPgf#`$ [s{ -p ՍV%3?aD Ka|FeoQghIYRRFM|f FQ X ø!>b>ۢ (VA>$$|FWgx i WgȜ@Ȳb>S:#s)3)gP#iaUg$2@AGbp,IRgPTSRg䜢>ő#37%Y~Hõ BVQ ) DaABR3plS&&pB(A  LE ?-NTeg"pyNϬ!ݐ_"Wg(+lgmgPxϠo,p>㋌X0>s4Q1 3O9_p!2?ӌiِ!ٞsY38)pMٸC'g60>Ø>ه>Cc϶*t"5u~&ENi? g93L\Apibi.iRQg }TH̔)͸w Nޯ4:~v@<Xn#3 99n1WgpL\&Q`Lk~Or)~&$[+y gD"/Ia R!ѩ̐".Y!L s3>q n"0>8xpbY>ziV&xÆEӈ )IK%9ly& sK0 s$žbxryGg1spτ3^K2yz lJLY%c=8#eƙެ 3+J (ڌ5W!;ȵ'b LsD>7+,7#s0ylưB7u$)NP9wWpT08G% ݞjf3E K,UHFъL )\3ARjњ$Ak&kjG(HᢥU247DRfR(MKy:Ci&*1jyCNP$)&`O)J3QggZ #J3ݢ|A(J3n4r1b4K0+Lb4#*a+F3]s@%Gf,&r$:hgf~d>.cwgAZ͠"A1dʌ [ 0a Rqh&Ei *HiʹII㰲yc-lv'TuEhf*ChЌp)B3Q&64ڴ4;fK8 6Wїc#2Mq/S;{9jL?QeNB#pจL) ˉmq"D'I!%4d@[Na`I oqiJ(2T諂LA%-04=$(IK_+2Sqc9)b,/p;2%a(rPLnLb; *2 Zѕ)cWn)rKZTO[Z+1(ZC*7q2c 7pUY}L^0 ʵhTn M 2Y#E^!4OB * u+v"4F-!ڐ߯&B*;p2B* 2QI1<Leb`S(`C\1.b*C$p:ST廢>2r5P`ʔ%jLbe 4"w \FL/7Sє +S)7DVd6'ƴ ,J} `ʃl@SJ M f"2 ,-XY32d(%^dB)°E; XHڰQ,eX"Ø(2H`2SSV,er^R& E2oHZI<0B)(e$e<109ARvVjD; )#lLG2")CTd#gh2Q8j`DRދG 8@E$e(>IWQ$eԀ s p9IW,eEHgk; p`)6 5b)#1R!rrg$erW 2EpE&ERgxF$e@(ʡHpkLyS%n2iwF eؖOVIdi^`֯IAPAAֈA%H hܬUIqnȮq(2G58IgAR&] HDO22[3ARfI'Hx'CѶX`CRbP,eI!zU KdLy 2}+ #4evgyժMy h3Uєα^Дu.);2uGĀ(s(1,N&r yBKbex8jQuY pL^Se<MwQHd8lِl( T:Ά x _QçPMdCEU e1)ER0FR $eL?Պ G7W%$e2p 爤 (œB"ETXHC+2l%(=B) VIAAdP0B)æ2E$eȲ^JEAԨg$e8a@R6#)cP.~DR&*o4ER& I)2Aӈ *JMJ\cHuCL$Ёo<Ű"(2 KΘp%eФ)#[-fp>5i0L5/llpɔXEKV,$CKZyK)(T2IPdJZIIEHAIZiWAR"F2%ɔ cDH&| 4O r#>24?#se{?k#6rl00##geXd;"SUtqE"&2cDva) 8sP™o32a׍pT\ѐ)nW!戅 kLR|0 /A3 '4` C3dgF Sd Ri,KIlC Q(9Ka#J [~ND1T~F>w=Ί7Svn>0 2*4Fj30C^lz%2&+I93"@ф p &LC '/XEg,,R% J!," C(snV}ր沈#L1UtE0=tq*0DZ1o;Pz ᵰײ|?N~z-8i?_,y{t髛\~ݯ.hFN߾_HgCϳ7k7zk0dP'7~՟Ë?\D}}?x7y~km<8}l??{zꤟ_^ҳ=ۏ$v\tT' hV2{| Pe5O."!ui9Re )\u~ kߏFn~[_Ifj70GQ:ّ.5y6v>, Pйޝ>{E [MP2Yx#HGiȪG9ɗ\a:P'dz1ѓ"Bx_,;~r?RKzG*B&>䖫~,-#|iu["(9= b!6ߔ`bpQy\56}[TK&!_g2㎄ܢ2qpN01Ap8~RWvڳ[\.$H#2t"}2 &N[B7pmN%I#n4;pަܳ Bέn\SU獶y>t#?FW<ق0TӼw$]]@4Apu\O:HuSCU&VUv-e]&үi7p #M慐S2H`KC3 _ l0&W8H0 ҅\*AD˓1“)Ahy8(3H}>!c4[+o9<"WjʴP[nrvU4Iʮ>K(r].הKNƍD>3zT7\(%ʣ֝r)$L[NΨY`=(|@#x䠇įRݩ_r@ 1{[*py烰3<&FQ Sfc}Df+f-z_)\zּ~dG׏zyoSv> 1dVkU8ăźX2728E3[~@KFc)5𾰐sne?)CӉ$;dPMD 0.|RKהxd "hy#3C 3p*k2FتzЫj8@b i{it l=>'4ڱy3\N-P}_в^.oY&= Y#BLxD&F<ϖja͈IW뷺5oOy3IdtF|gL&nYdck1}x|L2^K`YK0_p̒^mr DxxMvG> -y4슩^:phs7LmdHsbbݛu5lƺ|##Z b.0&@NEK /~ɇezfScN3Hn`Qfg%65s_ϴBw$eY#1wyG}&o#b)gQoI &iGhbȯIY ED[vL4Ĝa:3[dA,f)YނM2ՙ|NQlmyYNW-p)H DBB5],u?$?wkq Gۀ&x3,2䨻{W-M PHL"Y(nجp9lgoDsZ`󒏩kF &H-/pfשXU$ZR~n֬)/TI̓[Fin7 FZ!&àrU1R+svͺ[fk5 ě&;OV[bԅ!%:(~\ V:*;H7gyJaIZJ2RD?O(}] X/=dM&on#"O{&uܑUem.ĠTאg|[ {L0-oD/4u=Yeu6^N-%bVAB !mSs8jBYov$䔒Ʒmpi2S8Z$Rf3oCe rlM[Ү|s#r1?$8+%Y6234k5D5k!I\L,l{K%FRnPJV vU+L8^YEb"j(ZfɂzH2tK}hZBL6<#!O"T&Z0%)FtBoBnN$R }񵹴UbP&%0*y|Bs-3nxSP5tFgE9XNS:{쬻P]fq,NNY|0^ Ll!bP"Ԙ8 oPQ.3wFd}UuΖ? qBɱ= ,vD6 hYU9ngDd9mWԕUʨBŤj靲D4-BrzVg'rIIc^!0vdc`{wjf PMEE1 kuXh'<=JyhPrqa +QS۔$;!j;2kC[YpG2i/@.pS̭/n]!OFdQ 3T PbafYBEO U6 8. {Zd2,GB.*2܂!0(v$0MWU= Ex82 .U\kn$BmtUhަ]!5R}Nz(r;(VѷS8o"fBI[EMU1d 9nr~rZɪU֊ 2`W~ IdsŴc#[)<eRtduyg:L{Hbf+ ([DٿDRm6rb7v|@J)֪[Nʹ\oc"e0QmRL;f*K$c]Jգ^ @#̄a Ia"$ }TO U"*` ^&$('ǯz koF h7f^$GIQr<*,ѡr!~Rlb\YV]ԬR^M~6DVUoI$R!zW-ޫUvk%-8&aJq~wT#{P1)# D_)@FIRuæ$.LԐe &F_nŌ\3dS(DU7{AYlv% =Y16)hB̌RM02WyQxiȦeJ8a32CQEJ/Ot^4%5N!QA j}dQb iYʁn|`{hjA'PІ+dqKW ìI:Rf[۶hzI#i~hiegO"th-a! 5y2 !zI5uq ۦ϶=\L Q;A0Gu&Se7ciNo~@l>GJ.<]$ȋ .ʋD){kxL%/XAb"X0#}ߛh$2iXoX^+F!j^/C&‰& 5$a38qn5La!ZargW@[{ȳbBT$|(JFmOFQM}`%AfP)By9rX_.'9ȤSMC"0Lec}}އ5UMzw`YQ=7NUs>ZlMD$9>[ZS+`tnd_&Iɤ҈^*q$Vh#8#ji4q \Y%%BsG%?Eْr5d^J){r Q뤠 UF'U|xo6SIB73 NQ7+)g 'Kų8e!⤫YK=Dx"kp*2Z\ ѯ{c6QLWR5p"&rܫ }/PMPPZu* HN1"('Q%5~ݙ#\N +6ESۖldHj$Wdѳ%9)"p9A2"(KZ3 Pd77@ȉΪuM]GLV?"E$>(mz1oוg>q9 qKk *e3\SG WY7YUE "TA@hi5 Wa\\DrJAN2#!՟v/M!rν{;RuI~BM4% P1J˃er )f GQ#@SRsBĺpXy\"OT[_楉!8XalaaY ̡Ǧ͚^*\%}ǼJҮd)Y6akEd}v&1\5mrnYѲYi["oqqk#R Chm.o}ڳY䝸(P@ D+E~*G34}QLE3S͡L@5108&sK%ȫ! [Ok#% 4E6ꉭ3GJ/@I3iQuXL%䧢DeL5_=O{SoIAZDsGF @DKqm#К WnpV}͒H@KҜnR"6ضz}:EՈEf!.Lyw&ĥv,YIJg=r2Q%J9h8G7qt~G.wDԑVU[L59% s͢`hindR4UII%uD ä1ssˍF5UɁXyaJ;n,܀"G.$}V# M hAvoYvMU㊳f1!&V%llb&_)D )f=f LbɡzĢZ ksZLG3";[\I&5)p@ !^ jڮ2(DD<Ͷ7r><U)M\yV>U^W9>_&uT:K3H0yG4\ /=(RbK}_&113YjUKmbOo*G%)e.&֤?٨٦_MJdMJQ7F%5ۨ*Ru_mHRKg3ٕfVC(EJIMcB5 r7l$07#fh #:')!gHT'J<0ċTչLUhpCuEB: )R5e]ThD]9)X2]0堠LJ'A aI t1s{ީ/t@ϳ[u3h/.W)RMsBA@{_~T ˯'EXzV/s<W'G !Ƣc 0à;8h U@IfZ+b^O f dQ*⑐gLviP&h s43!jWnSS{o1ATׄ' jUZv.0tI2?sfEeS()+Ƃ78npQN\bԂ%bu)4+i&WtՊd쨊xRt:8H аEKO4`(8iew!C(Awtb0ȉ~Lw &*s?QoWOųpjP]NC.*`tU:H|@Q7$4R#q)q~aN$Inb$$s'?5f5+JU%MItT&Ƹ)": =`Ғ@- )k Hc6c$ٸ(ߚ򜘥Oɼ) Au,#VfzTL6%*ISMSj4?˧xTR8Y0Y)SvgbES^P}g`=G&K1v FW\{B5$Vg˂| !\._q-8r>q"g HKհj'zi6NidQciZ\I]d& e JĤ13cq gE}?K$K@LM~OQoGF ҽMŐUPF2[S3p!b4.a)4,Iro\Z&bIa \M EI5 p-1'U.McINH"g !c7`]W5KS(6:$UMʖ#jDI]kD 1S1CǎN^&3]Z`17vєk`5yLsiՐn`}4J*L넘DֆHf rYrp\9h-+Gн<2*ޯ!ởLfjiGT5D4B47lO}t_3(38i/^$BPMA,e$ $@JvEvuFm)rYP:I弡f`۱y;?OZYc'.\9~E1J.ihD$NuTBWxβba}e I W (cd 7?Pvw:0U i4@qC\pf¬jx.PGCwe1sK<řzQʑfASKUMYRYBt%N-Rkw>h.-دsa0--D5zjI? ,#*[:S&d`-NI}tݼ0-oDog@s!d Lq61"kerL=b&t\>4ލRɴ7A$+GD#P8_f97-1ME0JK9CܼO0&Hwɑ~$#e щ䆘:; #ERyi"V@á[dCsPW}cv"JKMpQ'SDoݮ6N_\.'䝾|d4j! K_} a;b|22.^~F2S|m1.Si<@+ ґ[v!H?~Vg )sPn;~.ЫO~˭#Ic{ɟΟѓnRN?:`D46F{/gOlOܪC_ MNz<0b3ݿK':Cӑ1xh(ߔ"kgK^[YBO~*1b11Ъ"ya#b-hIZ68?w@fשּׂ Ep$=zZ8m4rNϭU:;It%*O;r2K.ExvSpP'8gxzPL>Z$ґP?~KB?b o[ɴ/w2)<{u*| {}HyL{S0bw?{N廟cvBFlF.zc \3.r݌\dD;}!F|p<Ԕ ರi6G߼뛯Nnή.N-. }O{}w]ӳ/Pˎ+Z^'[q0(-6:RzJD|׫onG[kó{3Ͼ{ǿ_z~\{o8ݺ>[Y[O>;y}/|y3sSo4O.N:Yo|ٟ^޼t]ӳ+>=C|L_Wo^pp3zr}|[Nx>s0U?^wL=o z@nVd's?J_>9g'+#+#l7_h&qvymDśg7kvዯO_}S7oD[Ɲ S7wOV|u}^}RJdPWqtw:N5t5FE:OHbOE(XY;z{I҃w^@x$ O޾=;|~7Q^y۽\-| @V/Lի7=`wI“*xzQ~ysz<\}}G . |+k}wu6K;~/7[7vuߪ+?ˆi|r="^]c`<8c5ئp(#~yۦ.};eSxʒ?A>{cS7YqW_{<=K~b볛7hnѵEMAn=>BW[M}׷$Vi=rz)D'$O#,]V^]?>=QuoftyU`gVߥvX 7[1}yv~~ҕh[MVs/Ws/SD~꧕-Ox'@zώ=TyH"lV9%mݧӿrՃ-a':%ۖiQZ|ӓu/>ne+>{B.^cZ<b ;?˶]}Dr}}_lߝtqܛZ ~\uiu)]l|eְ`CR_V`X ?*g:o#@梭+3M9}֊c{uv~Nc!Rn@ySwal.|u}u>S+˗g7g\c셇OYƧ+ zܜ38NOrzû{V/W g>_WO0nגHu\_=fr|yv]rTnf6L;yra3h[L"]c ^cm_o7̊q3'O0n Enmݴ < W+#pk09yr3h[]iKD<5צ'8mu˱GIΜc0i._:$ 57>^y5;OfŻm1j޾!UǸM5nuFy,ӞK^ߗ{=QԖl6Ez5%VK~5oK:c7Mpvp_>f;|l~umWywlXáq3=rjH| Y{偬~'g@ܖMCn^_ެ~l]M7燣|W?>jiwYяy^?;|t~5Rv-?C$\K7޲ysƓ{@\'˳W޽==w{>_Oϯ~^ug??!|Օy,Vf_ufMf @<[ka=;3LpۦV=vvou/>=K_;짫/yvu~z// tH-kxF]y`}vJ#t#9vkVSݾVWߜt)&/>3kQm#ȲhoZcRj-nwƜ1ggsvƜ1ggLcnؘ#tvƜewƜŘSK mi#4MW2B*,ga[ ϱ:cl8<Ǔ,N9֍z[h+tvWƭȆ_Oj]=(ܠ;d'lP>ۇ'j՟_|ϻC}z+C 6K@dˁ\-}-@a@~Lի7t2O_Ů |[OXYؔyNp%7ӟ^D&O?<>קd>YA,+uߥrcduA53lTdg y۸3l_ߙ?v揭2b}sFNj㓛^O/83XPw9+>˫onN*7=\xwmVO߻˓յ[omwK9.Vߊx`;їvKkHa4\`ju]j513XPFS,]3-45!nƻG2Dv AϓB[cD[6/ߙ̯>d2hj͸qhFݬ(mc@O6?(::;oO|tvZN wW%wZN il j x;=p>ܩ;5p*Mɩkhz,k>H$y,sP)6CMZ =`Km7`C!l#l<Odx!m>9ϏOkz\~u oˡZkPrHqzkӴ+PG^KozY޿C}C7ߟ!,,V5%'zxuM{!z DsqU7k$z{t/eͺrq[n䕱N/kY7+>x՞Ao?&g>]{S3||H-V>Z3<]CD抁׵/ o,~Dψ4)v'=m>핞>m:~n ݷm<تM{PG>go0$n@V?x:{-?H볛kئt]Kߢg7g]]"~"~˾vcޞe0ݠOSKFoϒ|~l߶xHO: }q;-ǽ8IOFYuiufo[Oշ\m.x~u&2'(F=iXM|ݐ"+K)d@EdcSl+ڒϦoi0䧠O˳L­^}qVNܶ#wiϮ7)|sk 6Oc5y< w'mSyrM{O0}P~>|jj?Ft!iO>2]g&< wB4W42%gwaяǔWvӋ?\RVDJDy׫o{gӟ.?<Oz>wssugWٻgGugsu{q/{N{/~z4Mio߹~8z?~{OU> {DO%73>_ѩm7FG_KcCYp Tozw#wgd^~OH ?x ?_/{~ogO>77Cѳ?5.i[Y/Lhl/M w'=!ɷ:=?Y+φm55$G}9&;L*:|{ZLaX=͋~M,ƿy1}|﷝o~9= ?\nS`E}31/;=>74e:M$aun& A̻qCO^xo.fK{&~ o#kN'o΋Əa_Zɶi_ӿAwC'߷:ǽw.-7ޖo.]g+pV#/iЅu5VNVp^f?ͫ/?:]Aup' u@}nX.[Xlmѥ{[{-tN )SK~R+bzn8_7OP'P?=>yNWoQ݊rr}?{+}<\\9p|/_ן?6qxqh2kSL]TҦtLὅQ@篗;wdϿv=RWKm.]%&1@_3xAtTS[ӱt.{_ӓ뗽uv=Bñgzy鋯^}OU^vM_ޚA f[|MJ76ܰ:K" .wkOH%h}ZP j *Ⱦ˥$; r$G "Q\MB?9وJ/y߷R'83n$Ld܅]<5Cvd{fFw P!kH5vᄮJl3o-j8y }ǃCrjW4䃧xr%?B]H4-ĺA5Vv'5F{zג]'R\zqK֠%w}sNdޱJc؇+S_4X[%0a_駳AtDh# A_|,wW/z")It Z8to RFe}$&b"$xL"Op_>U-eNjU*0LhB_~:T7R;Uq7/oN'bNJD(SYXTc\x_OԷEBvJ 0MWK8}FbE.\8h=Y< eY\g%5E1 9:5{!c!O0cէ]Ykӈ7qƄ){Z3Ko/g" l~T<B8Ay?ibG|`5{{2_arP;_B;}'*X*jDp3|{. I[ qdLoEZXz 3LāsK[Sn3wfpn"w/~'{gܮxk,,jW ݿJzeOf>ݝ\㋮X as t\?Enpg}hP?4#/ Yx ^fԙDai{FkgG0SA<)5F;_Z hJ{tNЯI;ӟ:3L?uLq5@JZi3uKWDYQĩ 60>+ݝ4Nؽo05;L U[M-sgt=v4.Ibނ6W(.@yUQ0 z}C?mPJVO^맳27^HCۨw2﫾Gb-MӷWT&Z;$X"> (F^Rُ!YD]AӨ"H/'#"] R?vm~`ٞ~\DRmpѻ׷\)Q3=W ;.ϾĴ}:_..BLJcKLzL߭[Vk_VZS\&ds ,@!`0難Й'85 Є@d %o:N1׷r%~~}GYNgE*khL{'wr7{R %[7Kv !ڝ-'GMCaX*KN" }u5Œ ~>B8!;[VRؘнJ$];vpKgLޙ.jOtc;ӚcWgd]Df~W{ly5.ΩswJm 9]@ɵ%fCIzYO.~;%E'w>#+UVsY'H]WO!ٯFf)Үsu?94".1=ҟtI~cFBPkk7Bť|wD'Ѧ[:_&,7b'zk 2E`rK_󅅎.P޻u}\O 6h@ [\^I/uU=ЄwǖI~SwvфFFV痿YhkOj@c}GCHK쇣3(F t$_F$;!S^q %؆On`ahH.ΐؼ /K)N?F#-:nAb,] Z N?K63}s5ɟOl1aj"XgHz䇷H0~kF#mx~rܹL Kf*\ ]6S~X;S߮3][Ӈ2)~š_G~_ }b\WCre+|]rz1"-'؎r)ت?ɓgه _w*Bst*Dd ^܇؅'^@TWI\!TSg޺)NE(#]D; ɣE*O}I{<^Kn3gpWקZ v~%E~'H}_low?>rlJg]7?Wg{~뽿_tz}o{8D틽`;迸lv.|;7<>{u\};@ 3tfBv IHB(X8-˒,KVe :4Nᦿ|r>exǴG Ft[|]r힘9@4?@c듋&3h}1ChOx.S#@Wf~b )~B.iNqS&pֱ]âa-%$>A챏&ґ^7@7M"DZ*IL{k9tQ !OI]K')'AsAi2g9B.pm|xzaYثpMOxi̐"T|JOZ7@xءQss͘)yzɱZtғ tʯsŦ8oO&WiʰO`O! gwr]1ۊDN!tp"}+ $YA2xGCǂom(@9&n~a0g1;Ş٢>d?ǻ=s AݢJ6{EG֧§wm'Dz f ^C\k!fxEaD6<(\Ey<^ H<8OߡOv==#w MmqAo68 )eNۊ؆j;\>x1_mEqzRW0Bx8U n8zt"T/LJu:P];?ÊF:<'3wegW,0@ ]1[ԃ S}Go%LG҃Q ϞN$a'tc`0Gq8-4)x HC@l$ y1܏b/# xar {O V26> !QlTO8 o!ya`oe-K ">d yBn,$RDd"HzGC }sgpDn0G<@^rߏ$Mecљ`pl#f Vf"rlȤ& ɋ #>X/+$Zqɾ4p /$XNe >´W4&CW$bZG8;q(i~n8(Qx]^|PgYq@X~-^tP` bRLpd/C(AP,`=`2` y ^y]{4%_>ْ1'̏ 8dzDx4B!$) 9E+ H,OpGa,^xdtCo{N cp+?@Yap1xmư&+YXYg]<>Vxb`0딏G Nl-@r'(@^9F``t7YA _EGK e;-@a*s'IDyg^b7"qQ`T~_8@GQWE! -t|$b~8@~ NzdWC~z@K&,r }xI:nC/ӿA&`E33-i~UT)Czab 8C { 9 N67OP x)DXIKWLHLHa>z`8(8eRp!H ˁDGARBa4i$!<$^ K `d7S?\pjyzڣOſ/5ʻ?yoC?'ݐV$7)\X~SZDX6hJ.t^LKs@|^vN @$>$0c^4yx- =L|R } WF}.VPs ,zyhGK|a;dCxRZC`Ht{1N|Htl_h>D7A2M륥姯=b_ "}~F -!^W/ \[,\ctu ! =iPb8`t׆BmHx\:&T0|HvL룵,O|B1w`,A +~$POv7s@ =c66B vw,~AAlB PGoie"v,bU t\U|ܛ~:F< P7U yÿī4]K%-Ӏ;P"W!?UÿOuʖBt<DuJ6Ee?}z0h ˴cKRq= _J|=CU1> 2\z2|p1AjT޻/CRMf.fJ}xuj?.0PLW/_߼ LVk;L3 ^ ˂}KÚә{} #Ao|^2pi8/pa 6`3*'n>E%/6~t bۍ.ƇD#pg?# x˅ؕ폘"o7Qrg2{h;wѿyp E/?ŏS?w$.ğ؎?-`9qt,F>1iƁm;=yM7z}r>?soЧ@cгڦSmS^/o:p)r)Or-YYoptWݍ'{J`ey/G>{d"8G 80͏ۧ^w3`NDGRg#"ࡡ 1a QwzzOO͖4r<Au>yv]%w-{}0Ɨ{"<>/=87Y(,r+';Lp3nCtU<@:C߀@?:񲹩Qg=%Xb4/r\`@>E.?o(é?q:9=8,kiL\>X R+Fy%HXWӋwYߥjw= ) A28./6F$ 2TD9ΐ5ju %BMy\a=.̅<@2d%dRS`5\-mB \]>o܄AP|8nI.oتgqՎ}(,J?K{p^񰜯OpiG$Ra: Exx(ڬsn;v잀2;q -O|ز^FYy.gKg`xZ@`pcZAW}u5G e X-$gףnWfLRji9_)e;AsnO0M4,85;n0cxӉklRCUYv!؜B$W9#yS:DPơ(uKBddP]NF 7İU|ǀ6-*"Q)hZ95jC=` t!#"ͤIEQG+X89)׾ wH>ָ6믧N5x˥rb!.BCl~A[7%'L,iq{8zHf_O6O'Y81$ptXF4Da`h_cڟbcԼZu#r 9nwL3y \T/vmŏd+T\Kյ mBh ́lǻRtw{y<@zQGɷJ[Pј놊nH-EflJ6ۃA^l`|GTzMi(h(>dmZ Ɠ)-@L`z֠oHBI?. uMn'ʴ[ʴcЎvF*\Dh}}Sf;T*^aQQq yf//jr\nlYN; ޫV\$7`8zT8xYNPY/lV~R2۬I 95ܠΊ'mjJ,KP!%7d8C]-u}V:8)ƥ.,[o`K+/&_B!gLZT[*p]9WSbR@ k_ڎ=<4?ή݉97ߛ%j1P-$hL+@(7"Ƥ/v&O Vb4FN^kLmF{ju/#x\4?ϋ9VSOSo}[Ƴ콸lVGϦDڭX\O{*MW[6ѣpyfz̄3 E< }R" _=| օ`ር1V+5?oL"|YǷz[ޔC}`cOL@=cb[8  }CW+̥Mq41KqӥKM=2()/iVܩEՍr?ZmcsiS?|䄼5iuVHh }55E*^ ZZkڊ!^%g[ӪuO-ִ7֒AK[k C_;?V&' pfH1u|hP>#Sml۵-M뿴iΠTcڜq+[<ƵKlj&* sm#_h[kK>贯GZ,זOY[MC;h֠% )څ iWvSqeί r:m鷉ΔЛtkKgO>c:+Q tE {v_]rVo2E._J\EW=ֵ8Rjht< ݼݶ,s;yAGlP9=Nvz^Mϛ>Rs ,/u}W?N߯wQ'g)>5*ّٙ  ^mke~ VkHp!GƝ5 f =wjI83,GucDc4^_JF3/:)jL`1;͌bjl\1cWwx5~.Ϝ2|}WpeҎy1\B`7qhRX&GVL}l1Mw:qNklwfj?\P-3'9_i^ܙ[lP]yU3hDkqM*@ endstream endobj 155 0 obj <>stream -΄^-e -udC˨-Y E՜jJQe֪k1F[ΣM{mԯ2mG,l90L~϶w:͗= olbqNugFOtu|"qwGz;*ý7vSn.Ncqg,.'g#߽Nٹpg see,]`qۖ] \b+ZK@z}^wtW*|#zݿf/go?U=֞:ؠFz5ƈ/V7iXgxG<׹j01ۉ&$.jse !%kXɤEV}0ȟu*qvO$3y ]j3/E[>Vηg3x>+Rqw~ dݱ466Z-q"N;wIܟ%O"P;-K|&v7kI׋LƉR48 N^O*.W3Fm ͚nܶf̝}&2/E+3Ymzld?rn@1KUw,ͭli,Fq'z&?`=/Xo/4¬=-}1. LdﺥK sVV\.GdٚDHbMg/q*_^V^*gB'FTuGG70WY__?կ硦kFW,F6Sֺ]䏯뫗VZ>h|VۦV׳7pTdв Vl5b֮Z]E)ӱ&NZ7QMW*Z[BEyص|Gkx'o|ߚm^$Ag q ˤ1~^VQ4OOVoϹrZ鯼} _go'Na7sŪ1_ BjumP_mqM1QϨ6vU:0yKP}B~J8YLb$0}M._;#kЬ^gn7y|_JOg_l"`ZTܷlp_vx{]EWpc$20fs6*mصv}NKƻ룽{q3AbBT:~^ڷ T櫼Yof5Nm;KO{>0C=kT}`@0LkS7~:O~|5? k~'4;=.:pWZ{| {s|ڂ>mO>AipSXl.@xȸWc0݇ 1?QLi7V2^~Bg'04utLNz+Mzo/N5fg-4 ©#۸`2\.rSzqz)YS=(0J^]B(N0ᚠi ܺ?o?ĂDWB>XLIzɼr1p\[Uf?H)\iPHί@\?2q<շ\8l4~L<^EEBɻ@!)*^54ٿ_]P7y.g,EO`))n[ןcQɏQ9{&uݐdl*ȾƓ21&b_AQS G!K3, 7*kwwa&~UyCcRYSsa˽@Er U$TKH$4SדRZZn%k)z])7g`ݟ/U`sluG*vL*eۅJ/tOZ'$#O# ۠^DR *#^Vbz;s(3eWt-d99KS`=R\C_&MFc>:0C,Ž>/n1*iwl!1JgH#a2OPF]ϗ!9զ=J鏙I,15 I`_`k{fՖGoXpZS1cɎ&#"V(GoIbvH|oߦ/ ty~n7/<&Cԯ>GG1cCo͒yBḑ4/oxl$G[]BaIiFc1w߷(4>;{/5LX0#5F*C)ܾU/2 q0Uط|汯Cb<1N,}=nKN)}ԗ|{?lz8%T!r20C_NaSFkA,|&#6== 3tnti`D}hAN'~^>Lr* /4J|:["uhAy"5Y: Ai!{hɤx+x#i8Qj]Y8I)IىioM ~]Nz`䌪Xؖvl\Qƿ 8ⶰ;Wjѕڧ']D9^2ѪdK*9["GD}A/ƕTvaT0:&漷vCqnu@(7|?tW >;*4V`%׭H"#Scɖ=|Vw!G,Ĝfk7L_{v,ȱM;6/DD_"@ d٧\1bח[]g6Wm5FgŚ>S%Yma3&q@3/vdz w z>|h6D9*:`aELȼ6C&Tsfi=ctf9fL, i}s'c>ۺ-4%"> H|{1o4eyh&7kaf6=6Xm=؈aY x(,F)7t`u AZ 79RbA-ϼ J4j=8tKpGog`M 76 tie$ '/s fAXE͔Q1O,rq-޴%Nrγ,hz#J6$* ޘ%I@{ =*@ h^8rXJB(!T3)=4V/Q`p;ğޡ4y"FR=Rm {:^L,nE #lי/4Ƭ1&ǚ1:4mV՞6"i}MJ2Q匍l;`[VÒ~i8(ef3-kk29E{@s' =KÓlGX0}md(GB:T!56iаUzԕZ_Hy[3<1ƶt]Nz5!vg(]Ap{ 15F̚hhf7 `LoEwkhQz⛞dLIYG~vNN>;989OVڝN^̀A5#/Mޚ{߈#ŸKf6 f6VsiyrG}PXP&}#췓1 fm1~=G5izԘ[UTlr*=u;M<7.fD.9&0kNoiiZxxU?,z] tTkia1ؙ&hvÒ j{zap?xͲ$pz./ag7a '~߰THԪ1e^O KX=@$V&O-_wԜfJv{c}}so2bv'ҿI$rcJ3nHqLĄ~>0Wc@ s ;\I+Hh (}ͰL/F !BN`pZD`^Gw %FMN*ʹJ|چÁfHrgH ϵI!:jޭ /4<q%cV|yBw;zKSEKlz #~iiOk*; FT~A%~o)+ 4L5X1 g,LiCY?`fD?.)ҟFx(Zd g`A@Pigg~#HfݒXc港a*&4$&_sbqo#x*yW/l7<_YCO7 jV*d{nǧ87@. ; ] M2cp~@|xc`Lf [kG۵!'ޙ_ p+LßxnQ8C# ;R bLlyEsX !H ,6[r߉vq: eO~-Bq%`A{He_fGl_+<iRJ( phGl0iw6ӥ! .6J u')T(.kl'ͦid⽋K6M,vܓ 3, c;I]Ď6 *8z} ^:aع*i2 m֘in/l-ZX&{$^1oC" -5ɗ *DhHR .!ZOrĞ3|^=@MmRM*?R%NSc0~89۪VڷѻK[_u@@%E #a؍A:^Jv{s*kK'8jiFNm$ 1R(t#k6<Ѱ$jbě׷ujR;$NI8P4 ES~@X3L&LtjYd ~LrL.him#c]#_Z2FkhX~J`ܫ` iDZ˖E0@! DN/FSEaNi[t:`~ZX[ ֩M(pG#~VAK9g(_թkk2΀=r~񝅬ȋ6 9y#UF=];jK)=;2m Vvvg94?GA?[n5Q*5ʽ4Ҭ$~^y"B{BJ͋Y4ҰֲƝ4*舠Tc<ݛe R7wH=֞=LLG|A.KRc2bL)7wֈ '4NHQ.6 WSi6G4eKE)AZ8ɽcZg%ߗ lX%UY]}mOHOL}M>pIu9@HK'=ְcHkIkװ*I! )!+ٞbinIgR||ddJ鍋u9)emiY,n[|]x |;]EDO!oωC6Rqˍ7T$ZV̿ RJ[2rHSX@H!ƚ ~v/uIEZ7HL )w'ƺs7Eiۼ"mjTc<{kai%iۂN )m+;u)ih!#Ped~F]U~R`Ahε,wƆ]+UAũ>@_9~*Z4ַR߆%'i `h؟_VGvb) =n^*a)&3>9T9٧6QlD?]O '*O1p=h6iMMi:^eg.O0X2O9,cZBfmROyh/dҟ"CJ n٥v|GYA 8}DQ٬CD[kxA @z dS@p3yM h|82Ym ҍD' 8e>|U)%w).4h6:Έc&!90V2dGK"uߥnA1MD$(^":`:Oo%gʎOc<} ; s1<&5Bh~6?靅Jb)m,(vgr^Y'hd)/Iw`ܼ1|7[LwBCʊ%M;>. hE4>Іa,GA0Ҵ:b[nU"кbhpsYDlĜ&Hv$exW]&fh`ios)#"6\X{d=9}() 2b{shoy+85%Ua$Ň+5(.QY-PߗY5..3ĖzG0Uꀧ?ٓdIn|dgZdN~n{. %. !p xE%wݗKku<$J%+KV!Y̦K ٿMRq e n$J(T77h@(RlϕH}4F%/ݪww} Y.D@_CdxS:vҀ䝉LVaLC*Ŧ51r,^*EXY·`ͪ<|^<)?NzOn@*[s\su׈T- #RtߖSȕ߀aU$:_RNx*Jy[靅bI>@479ܻi(n^q} `딨|Ќ Ehq&QCN(Tc Up]}'cDXN*R@%~a=hOD$abJIk,x1M ]q2<@YhW}zv滠/ ^ G5F)k@4PF8xK9=e+/TZfI+L{X[{eF{iN̚(IN\δ0!̆Zt~]{Y4{օ`|vh]!y}cҾ{Q.da*^ o~tZ .s-cpv-HRPݫ PY" [ ta>$ 8,FW NaNaJt8}{}W-`n^$ֶrTLB,r;"0.U\4 v+xTӉ$(+y.} D$^Gyk2}3B)U,qѶ QPP :C&K&ػ4GhXN䈳hdzY[^K,9@rֹ}iϴ'?a\Z*:;Ϡe ݜCAdrd :l+s3ق)g ;r3قw)g)d ^CAC܎ɭ;l 2踝ŝ9ttC'HV03Rֶ| |&(EE$=ˁ6uR`ؔp7)d0W5`qExƧL9KRčI\ w̏·;Jg=:-ɇX-N;ցlgCHJ)g[loTD^ZyDg#8K<Y(=< ,A!Duxg^-g,{a"DPھgx^{!x]ݭe`Cz__d\|d$BE8Wܦ%f}~%Є^imVǹ &)_tqCe[DxcXԾKEʌԾnep!!dB8HbgB(Hp]-K"iAFV'3ez2I˱G¡x~ňGISn[ )wb_yG*" I*Rc*g]%Ð/ '+%>dcU/ǒ "^WGQJkx]G8JQ.NX.'7zሕP 91sJ\F+JGt&`}fj:>4}]T6<9YH&\d2."-Ka0K* w3-X峗0-4gRf k7rvR-4JvʼܗC4 s= 'NvJ\eBQ ΢솻DHB+ ;J=dwrݦٔEj*g#9cz|Wy,y k2%&̰C ,3jv!vWA+Vv,Q KfKBUZ5=QմyLjUDկ.:u)8R{}d%9#w.)U R"y! yE\ߥ"rq}B9I}TlD.PMKuFDwQ?NzɎ Ɇ-@%6?̵tRTsg6OP^Ϧʥ5Q>N/iO6,̚l:)Pn!F|e69 +M'K?&N*NeltRvfyzM'ecGM'K'st]-[餌StR' ug6Ś7eٖͦSO{DgʦbWg)X=,N:tRgIbM'%Gd]8yP6el:)bGe]zL6T.l=7PP_쪫xP{a ղ^Y ut:WD%A$$ɼhXdALֳ\D]R+ TTL%H1Щ.+uI:BV(I첌ȄZL#z {ю4 +{jYJ.sǻJI~K;rEUJ*erKS |*tw\e[5UfT](B]掱a ]}PNѶ{<, QO&͹<`hZ=.^OF7ϊxUtj"53 8T, aWAȺ7३cJ'[]ݘ%Lu!\u4u1~Lu4.[9ɾd>+ *\̾J8jJAEv5LvL˹Z<~ܭC #U#KM)R^Cm;?҅xԊ;q~-sP*U#bkuUj7Xxnsy@ùZ5 ]R7^Rp . *TypWոaJWZ wJw,Cј ww1H]{Jy/C w¼$5!TS k]_N0̑۽N.95]Zq^/,KC_ws<#yH>gSG>VĤt*wM~TT 2 Z.L [Me$&sSi15iLA^@q"PWܶs2hQ*$1#k}$&"X;QA^g29w/2 %.K|5 t*/V#"=}T]t׮T0U/Tsߘ[\9Kr\Ok\ZɄIDžƘz7ͷ߲UݗyeF9Kъvyc G*ȇvwU ]|8|ą2Yr(W~%d2[RvXV֒Ej\S:lR.Dગ!>ө )rZߗRH5FH`q9A^_'o1\AJ鍞+ΈR@5PH5RT͟V֕HVFsI<"n˴#l;~~%m U@7IM1w=b;a=BTsNe$ ׊NU.NvDtC"tZ%%JImشTeнPE')Z%;ugY5!hJYw'JISID^׎Zü,t,JK^T(-QS~|ӟXJ6ufm[ ; >.o:n8T^V{&SNٕq7%IY_ugFϲMx%Rw]ڵ F$XKXzM'ɭctbu|gb?e'U,Oȫudg,(˦tUU{x]忌JָKP}洚jL\TrRHTNGˉ:ATX.U1k}ˣ~“;)vU+yz2҅Cb7fT}\@tYjsdpx}@䵾9 P* ;LquYjs!nQ*|xQ|YOU{ Sl]J wPG w]ҭut7D]?eN~̧x7 u.s#)Gp;]zCWxCWD :rV u$zK]?tD[Fu]7S;K"-~nnR맼ՕTiW9WS|Q wqFu$LM^U?~u쎺~e :=]{}H]?~'YO9zW]S/2~ km TϦ Eu= T㻫Er\qVO!bں~ʖ<utx$-<{xi^|," ҐU$K7j\WOz_]?c1t]?.UJurUombSYOE)WMY"iy^dx^U?Un9rxH\O9ISļ) ~K!ŮyWQ$=( S6 ub|w]? U17Y A s&+uT0wBv맬8K}zxS*-R3FEʻvEinbytzlyoAehHD]S=_;bܯ Si hޅYZ}!wB&Z6se5'~Xnwrr]t5F˙WWѵzKYwh=e3k_mxbĭԏY/.flY~~ؚzv^Ғ|z=8Ȭ}m5m߶=LcX&QL`ɰe)S}Xv{'Rw^2-qM{q ,6ӹ2D_z+}n7RAX`Ҡ+h㪾֌;W۷E3k tNҍQ@N (ϗwݕtY,X3$RS,=c$}^]Dڋ 8:Xu{c6Ksߚ hmMklagd@s~wy9|oLGb^>ivŌR;~Tͺ3f^f]Bg޿,^+yv'ݱ~ZSֿG6c=^qD|g;}: sbUKEAͮdɱU1oGg?ʬ?mQtnWL̋_>xI>8x05V}4ߍɹgykVMqy& ^(|MY>{HpX1okpo,~_uhzVzБG;2$] ~=(\}X_9SITqз)YA7ce#{ =a9 #NهW{YҢLo/g8VݜleU>|a?O|^o\j'Ʌ='U\8n>yR.+yфvM̠ŝk\޿yڶ#|~|?`aU&c~t;c);Nn:&I#sjfnʭ{>/}mfco?=j-vgc~l~_7n-Mza7 f99q9~-fGz 8>ԿzcVv^"˗VA%QX9ꄙrd~hD0:\ GП7~ B FA+O&\y5>plc01BM6+s ޽[wny" +=xR[J5wE'}ڋT~kUatl>ܲ*sAc5qWIGQzϦ.ϰGI҇[D9;[Yxs/loQr_v.Lrc)і :[Mܾc$~KǢ:vw5MV/j}Ҁ8Fl ؝hK9h5JOo'F;JCl)鬉YwF5īqYwڑG-|z囐?ML }>^FLVVh>4qW5[Nȹb5y{=k5Yژ;/K7u5oTiju7KV[4[Og><]>v^8}G{VE{k,0e6ztf?|HjWu ̈́{5V wo+?y޳uR۳\7gџz|NjU!ƲgtON^3j{:=k)r2WuhNBvvp9P*vpF|Oѿb8Z M ijGEG3]INgzќl'>ڛ>@ܾN骼[uRl\z'R/!.3Νa8.Ʌ z(Qs>zs=;\AVzl;FX޳qjfb}#,姤N^>-,{3ӿ.jf-] s!ppe>?zBl}>yu%<Ϊ+?_X\|750Od̃A$/cz|:[}!. ~Db$O^L{y'"[pS-ݟ_oׂ͙gl..>TpzA$ASwvK8mRUX?Dє\=zknLHfJۖ;;ݹUY,/<:yzt2"E-(z}8 Q gxpp;mzQ-pONY2qM={ufRve)}̪W{"1 =[Lc|7i,.bGeG}3K4^^\ebY̌ӫQ:̑M&ӏK_9 ,?m|h[8S@ԯ6OK4G'-)my3 JUūOƒ$jnž~pT,|:ѭ2=3qll[ʖ>H>i[&piuE"LNu8NG<|-s_5flysVc~ 4xD;Μ12gC{-AA+#k(\^,o!#˧9$-3$3#τAs'VcR*y}iy##tjѽ `qb~›o5"ItjRstlBĐ\?i@,m/  I92mW/Y*WWC+0{*z5^;}쥻SL^;7[gl?mαnO)^sF>ph$82Mݭ.g ?gWK5;ؚPતğ4\F^bw\1}>:;'z 2 x~$%~}ɥ3W>?C#etl=~c67={t,hBzg$mQױ=`ҰH^y0}.J3Kq6[}fVatY1ʳp5Ɏ_$Mpx鄜zqK_+U~7{qvH#O{Q [N6a._a->K߮l̤o_mb-\>Eu2k=unw}a3 j.V(_ KjE6=NBn;j~)OG`[_R+}JBGk:R z ɾt)4|q"лW}٪'͒q*qJ_Pf7rM#f!E`Ҵ~T)e{eɿNOyhWOchB_o>8Y)Ng\Q9{^宁 S_8 lvJ*^􃅳KL{b^|zހPwχc_LK8́CԼZBh/--xWTo:;92 N灷wu cڈS[,zwzF2>heKT9JFD6bn6r&^TI1 GD.zĴ*,%uBR#YGYψP^67AKg#ݢL t˔\d2bŠPyL)HR@tOdJGd{6IYOҶKЪg2U7Q!i#]%{R}ЦWJ0D+KM-I3LѓAUO*RJٌz*UdGVMu,t̒1h=-^am^˞8'iYHVMKEOkc=EXrMsz& #LSKP7C$ŀ@\r e€sz5 hR )j]'-͑P'lQf41 jidM5j PzhzT 1C<Ji'.("B}%iNf#F}=!D/z/4WY@24DC$ ,Lr!f>rѓ,=̲|. ؑNL5Шs1yIO#d4T$SXBH"^hc!A qN]9]tNۃU΍ӆPRh% ;AdO(%1b.'MϣnBM !t؅BȰTLKJ$hI+:}DbTs ++h`|}$/E? % IQ #MMB4"RYj]G$F$i`D)g "E͜6el]z|ļJ cD!"4ei1RQ ]#B;33ZbyhiSL'dCz$DCh%G)RG$3(b! vوSJĤs:")E)`ZOfF#jC"͡2|lDvI,E6{j/dX)GRdZh7.3 @uC,L]GXA8&{ƶ\2L:5ΡTUF%, Y#]Uv4Xt^UaSbĹJuU$s/Sf]@N]t@hw1 gS IrN!q(2MYh3`6Մ;rFCVF=tK*5f9#ZU~ W Kp4Q0zp>U*#< .J Id:3q֫h+n<@."Q!\ 59\s9 JLE[s5FАz ?(R0w Ik - X䀠𦙡 O$ _=AƘ)Ft%$fM}rRk1dlW~R0p q'Ю]K [D-%v66.0x@v2|ƞ]!T HӶ*Uj8d[+ Qj::NΑ:h8y_e2 m}CZHЧRI9.$4{2S5̓;'p ;M@Z"I9wD!;8;CTS( XԈ"O!HDw)QJD΍K͎AvMpͱ HIQ٭L4i"riW28𨚎 :Zd?55>A817ٕtɮ5 )0eWx] 5EM~5&kScUf$kdYRuEFLg ՚Dkpδ(X.Rl[ ҭEo l:(eX.P.>lrn5t |:u5SY7QȺD `da|OM Y7B$e&Kvxud]2YW_4iWdjnRMJM@d1A%T6ɗɾ /mDMS_`Y ~DL4m1`>y" &KK/≹) (ǂ4&^k>yB Ǒٽ+4*h:>FE`,yZ p"̾{BS[pKF`ai᢮L@)SRQ ~N\ %Uрp|,I4 I W;E3HQ;5Q9n.ӾYhq=’.|kU RmkJ%JmJ6Orɥwؗh*DkأunFHs8FSeNѠJ)j+C%`/ \Cr5ٚ9l-lrŕa.$'I:٭cpo.$#XZIDTW[p %{tZp> ya6]2 /Р=lC̕c)"gze CmbV.5b G #"Cs=nI* "] ^dR;.ey{1装3Idz7,'R/Kdpkv׸u~(77-^t̓ӓW_OZ?wdϿ/T7Z  endstream endobj 146 0 obj <
>stream HdTA1 @{ر+B+<`\Xe/Qt϶@+NUvӗK}zpR[ڥ?owy|zU^z 筼UYTmԧEz-zx&)XI^e7<={\˦AEoՕZVqu¨ Ҩ"N@Ќ2u_'Q2BxdznFKfɻh2  ӚT;kI3y{$ pY %(]hl O2F'Uw!z?܇i[Np{S1$dJ[;'ZK5c.7(t1Ci#7R0:.i44 z@$bs 3JHbܛlޚOdzB Y-t' F0nۑ</s֘9/3'fzs $9J2ٕ{8a$̾(St Lr=_'>x"vR< n^Q^ʧg^_nV* endstream endobj 145 0 obj <
>stream HdTA1 @{ر+B+<`\Xe/Qt϶@+NUvӗK}zpR[ڥ?owy|zU^z 筼UYTmԧEz-zx&)XI^e7<={\˦AEoՕZVqu¨ Ҩ"N@Ќ2u_'Q2BxdznFKfɻh2  ӚT;kI3y{$ pY %(]hl O2F'Uw!z?܇i[Np{S1$dJ[;'ZK5c.7(t1Ci#7R0:.i44 z@$bs 3JHbܛlޚOdzB Y-t' F0nۑ</s֘9/3'fzs $9J2ٕ{8a$̾(St Lr=_'>x"vR< n^Q^ʧg^_nV* endstream endobj 144 0 obj <>stream H\Tˎ0 +ҵiӢX0^v8N fDJCrozzTBTַ?~^.+Wۇ+~_F IwOZJn+[sZˎ:Os#uer[eS lɄ;erAF&\#РtqkAŸ;6(k"cU;++X㡍"up[`Gp@k߰E"Է;j"at{TMc8B@@Z/\Q!(t<:!sds0r`q Ω}㊝;mU9z=smrxACi&?:f'T4mɂ/,V8!^ 8N$+!fmC})a[onPg!6(!J֤]$4` )t'& kO7;"P&–W>stream H\Tˎ0 +ҵiӢX0^v8N fDJCrozzTBTַ?~^.+Wۇ+~_F IwOZJn+[sZˎ:Os#uer[eS lɄ;erAF&\#РtqkAŸ;6(k"cU;++X㡍"up[`Gp@k߰E"Է;j"at{TMc8B@@Z/\Q!(t<:!sds0r`q Ω}㊝;mU9z=smrxACi&?:f'T4mɂ/,V8!^ 8N$+!fmC})a[onPg!6(!J֤]$4` )t'& kO7;"P&–W>stream H\TI1 @'i rI.3&?zq#0VYor/{Nd>K~?v^e~c+L#4rBx(0`w=BZ^ӆynBb״ vFҩ͋i,X=""SZ8"A;`."TN%SE34QUpw$%"ZP4wk꤭syp ;Ma@f xG?:-G=XÙiH3WFS 4X@y-jGK=v$*SȋZ#a@PEC2AKe2 Oc[Z!'1_< _06*"b7bl8>stream H\TI1 @'i rI.3&?zq#0VYor/{Nd>K~?v^e~c+L#4rBx(0`w=BZ^ӆynBb״ vFҩ͋i,X=""SZ8"A;`."TN%SE34QUpw$%"ZP4wk꤭syp ;Ma@f xG?:-G=XÙiH3WFS 4X@y-jGK=v$*SȋZ#a@PEC2AKe2 Oc[Z!'1_< _06*"b7bl8>stream HTTˎ0 +抒(צEObC?h{rEXC9Cۍo>}QzKz߿MOwC;L_aHQ jgw/xM:DV:g;-;m I7WaiTҋCX$jeoeE0 !ԋ{qlU|͎z'F@hڎ$FcP17ai!i1Cc.!sV<ւf|PjT& 8P<-O~/$l endstream endobj 7 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 256.0 256.0]/Type/Page>> endobj 8 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 16.0 16.0]/Type/Page>> endobj 25 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 32.0 32.0]/Type/Page>> endobj 26 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 32.0 32.0]/Type/Page>> endobj 27 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 64.0 64.0]/Type/Page>> endobj 160 0 obj <>stream HTTˎ0 +抒(צEObC?h{rEXC9Cۍo>}QzKz߿MOwC;L_aHQ jgw/xM:DV:g;-;m I7WaiTҋCX$jeoeE0 !ԋ{qlU|͎z'F@hڎ$FcP17ai!i1Cc.!sV<ւf|PjT& 8P<-O~/$l endstream endobj 159 0 obj <>stream H\K0 :/`FR"MŠh0$($ە./L>_)}Lw=~>stream H\K0 :/`FR"MŠh0$($ە./L>_)}Lw=~>stream HdSK1 xbǎ-bXp_7+.ەr˭^_n~x孴#|~/r}muזzpG?rrF2W |$R~VN]<֏p+&'U.暕i9t6s `c{ԡΝC(#33#nԠ2~HE=b5n ]?& ąVY@LFT@Cz)[$>!pt1GΧe"bfwn6=@ؚu \8$1# Ԕ$8 K(9.A˞cy8 ]d @EL8F )@:\'rr8?q>jdk߳ Z 0WE endstream endobj 156 0 obj <>stream H\TAn0 Iҵۢz$@:ՌIjH}vӵЧWJBۍ._ABgI;V`sQ$u.>uE&c'fujG6\O9 z'ܑkR':Gs.(BsIml Xac q ,pa m#ѹylaٓNB(k'U'Kh}['YWw@Ҁ?LH1(@`B>) q`Yy@D5ָbVs؉}%ppeJ0ňKukАk,< 0_ endstream endobj 5 0 obj <> endobj 23 0 obj <> endobj 47 0 obj <> endobj 81 0 obj <> endobj 107 0 obj <> endobj 121 0 obj [/View/Design] endobj 122 0 obj <>>> endobj 93 0 obj [/View/Design] endobj 94 0 obj <>>> endobj 67 0 obj [/View/Design] endobj 68 0 obj <>>> endobj 38 0 obj [/View/Design] endobj 39 0 obj <>>> endobj 14 0 obj [/View/Design] endobj 15 0 obj <>>> endobj 136 0 obj [135 0 R] endobj 161 0 obj <> endobj xref 0 162 0000000004 65535 f 0000000016 00000 n 0000000220 00000 n 0000040256 00000 n 0000000006 00000 f 0000154000 00000 n 0000000009 00000 f 0000149372 00000 n 0000149716 00000 n 0000000010 00000 f 0000000011 00000 f 0000000012 00000 f 0000000013 00000 f 0000000016 00000 f 0000154823 00000 n 0000154854 00000 n 0000000017 00000 f 0000000018 00000 f 0000000019 00000 f 0000000020 00000 f 0000000021 00000 f 0000000022 00000 f 0000000024 00000 f 0000154070 00000 n 0000000029 00000 f 0000150066 00000 n 0000150417 00000 n 0000150768 00000 n 0000040524 00000 n 0000000030 00000 f 0000000031 00000 f 0000000032 00000 f 0000000033 00000 f 0000000034 00000 f 0000000035 00000 f 0000000036 00000 f 0000000037 00000 f 0000000040 00000 f 0000154707 00000 n 0000154738 00000 n 0000000041 00000 f 0000000042 00000 f 0000000043 00000 f 0000000044 00000 f 0000000045 00000 f 0000000046 00000 f 0000000048 00000 f 0000154141 00000 n 0000000057 00000 f 0000040316 00000 n 0000040408 00000 n 0000040874 00000 n 0000041231 00000 n 0000041588 00000 n 0000041945 00000 n 0000042302 00000 n 0000042659 00000 n 0000000058 00000 f 0000000059 00000 f 0000000060 00000 f 0000000061 00000 f 0000000062 00000 f 0000000063 00000 f 0000000064 00000 f 0000000065 00000 f 0000000066 00000 f 0000000069 00000 f 0000154591 00000 n 0000154622 00000 n 0000000070 00000 f 0000000071 00000 f 0000000072 00000 f 0000000073 00000 f 0000000074 00000 f 0000000075 00000 f 0000000076 00000 f 0000000077 00000 f 0000000078 00000 f 0000000079 00000 f 0000000080 00000 f 0000000082 00000 f 0000154212 00000 n 0000000083 00000 f 0000000084 00000 f 0000000085 00000 f 0000000086 00000 f 0000000087 00000 f 0000000088 00000 f 0000000089 00000 f 0000000090 00000 f 0000000091 00000 f 0000000092 00000 f 0000000095 00000 f 0000154475 00000 n 0000154506 00000 n 0000000096 00000 f 0000000097 00000 f 0000000098 00000 f 0000000099 00000 f 0000000100 00000 f 0000000101 00000 f 0000000102 00000 f 0000000103 00000 f 0000000104 00000 f 0000000105 00000 f 0000000106 00000 f 0000000000 00000 f 0000154283 00000 n 0000000000 00000 f 0000043016 00000 n 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000154357 00000 n 0000154389 00000 n 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000044046 00000 n 0000154939 00000 n 0000148793 00000 n 0000047038 00000 n 0000044352 00000 n 0000044238 00000 n 0000148186 00000 n 0000147579 00000 n 0000146948 00000 n 0000146317 00000 n 0000145670 00000 n 0000145023 00000 n 0000043380 00000 n 0000044120 00000 n 0000044152 00000 n 0000044389 00000 n 0000047114 00000 n 0000047315 00000 n 0000048376 00000 n 0000052886 00000 n 0000118475 00000 n 0000153361 00000 n 0000152822 00000 n 0000152260 00000 n 0000151698 00000 n 0000151119 00000 n 0000154966 00000 n trailer <]>> startxref 155159 %%EOF klatexformula-4.1.0/src/klfmain.h000644 000765 000024 00000024321 13660527435 017745 0ustar00philippestaff000000 000000 /*************************************************************************** * file klfmain.h * This file is part of the KLatexFormula Project. * Copyright (C) 2011 by Philippe Faist * philippe.faist at bluewin.ch * * * 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 of the License, 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., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ /* $Id$ */ #ifndef KLFMAIN_H #define KLFMAIN_H #include #include #include #include #include #include #include #include #include // SOME DEFINITIONS #if defined(KLF_WS_WIN) #define KLF_DLL_EXT_LIST (QStringList()<<"*.dll") #elif defined(KLF_WS_MAC) #define KLF_DLL_EXT_LIST (QStringList()<<"*.so"<<"*.dylib") #else #define KLF_DLL_EXT_LIST (QStringList()<<"*.so") #endif class KLFMainWin; class QApplication; // SOME DECLARATIONS FOR ADD-ONS // class KLF_EXPORT KLFAddOnInfo // { // public: // /** Reads RCC file \c rccfpath and parses its rccinfo/info.xml, etc. // * sets all fields to correct values and \ref isfresh to \c isFresh . */ // KLFAddOnInfo(QString rccfpath, bool isFresh = false); // /** Create a copy of the add-on info structure \c other */ // KLFAddOnInfo(const KLFAddOnInfo& o); // struct KLF_EXPORT PluginSysInfo { // /** The directory in question */ // QString dir; // /** minimum Qt version required to load the plugin, in version string format (eg. "4.4"). An // * empty qtminversion disables version check. */ // QString qtminversion; // /** minimum KLatexFormula version required to load the plugin, in version string format (eg. // * "4.4"). An empty qtminversion disables version check. */ // QString klfminversion; // /** The required value of \ref KLFSysInfo::osString() */ // QString os; // /** The architecture(s) on which this plugin can run \ref KLFSysInfo::arch(). For // * Mac OS X universal binaries this can be comma-separated list of architectures. */ // QString arch; // bool isCompatibleWithCurrentSystem() const; // }; // ~KLFAddOnInfo(); // /** Directory in which the RCC file resides */ // QString dir() const; // /** Name of the RCC file (no path) */ // QString fname() const; // /** in principle: absdir(dir()) + "/" + fname() */ // QString fpath() const; // /** local file: can be removed (e.g. not in a global path /usr/share/... ) */ // bool islocal() const; // /** the info in the add-on's info.xml file */ // QString title() const; // /** the info in the add-on's info.xml file */ // QString author() const; // /** the info in the add-on's info.xml file */ // QString description() const; // /** the info in the add-on's info.xml file */ // QString klfminversion() const; // //! where in the resource tree this rcc resource data is mounted // QString rccmountroot() const; // /** The list of plugins provided by this add-on (list of files // * \c ":/plugins/[/]*.so|dll"). // * // * This list stores full file names relative to plugin dir in add-on (e.g. \c "libskin.so" or // * \c "linux-x86-klf3.1.1/libskin.so") . // * // * See also \ref localPluginList(). // */ // QStringList pluginList() const; // PluginSysInfo pluginSysInfo(const QString& plugin) const; // QString pluginLocalSubDirName(const QString& plugin) const; // /** A list of locally (ie. in ~/.klatexformula/plugins/) installed plugins coming // * from this add-on. // * // * The path is relative to ~/.klatexformula/plugins/. // * // * \note Only plugins for the current os/architecture is returned. */ // QStringList localPluginList() const; // /** The list of translation files provided by this add-on (list of files :/i18n/*.qm) // * This list stores full file names without the path (e.g. \c "klf_fr.qm") */ // QStringList translations() const; // /** The list of user scripts provided by the add-on. User scripts are located at // * :/userscripts/, and are installed to the main system (to be executable!). // * This lists the filenames only without the directory name. */ // QStringList userScripts() const; // /** Fresh file: add-on imported during this execution; ie. KLatexFormula needs to be restarted // * for this add-on to take effect. The constructor sets this value to \c FALSE, set it manually // * to \c TRUE if needed (e.g. in KLFSettings). */ // bool isfresh() const; // /** List of errors that occurred with this add-on (now only used for reporting plugin load errors) */ // QStringList errors() const; // /** \internal // * */ // void addError(const QString& s); // private: // class Private; // Private *d; // // friend void main_load_plugins(QApplication *app, KLFMainWin *mainWin); // void initPlugins(); // }; // KLF_EXPORT extern QList klf_addons; // KLF_EXPORT extern bool klf_addons_canimport; // KLF_EXPORT QDebug& operator<<(QDebug& str, const KLFAddOnInfo::PluginSysInfo& i); // // SOME DEFINITIONS FOR PLUGINS // class KLFPluginGenericInterface; // struct KLFPluginInfo // { // QString name; // QString author; // QString title; // QString description; // QString fpath; // QString fname; // KLFPluginGenericInterface * instance; // }; // KLF_EXPORT extern QList klf_plugins; /** \brief Small minimalist structure to store basic information about * available translations. * * Intended for settings dialog to read. * * To manage translation files, see \ref KLFI18nFile. */ struct KLF_EXPORT KLFTranslationInfo { KLFTranslationInfo() : hasnicetranslatedname(false) { } QString localename; QString translatedname; /** \brief TRUE if the translatedname was provided by translator itself * * and FALSE if the name was guessed. */ bool hasnicetranslatedname; }; /** a list of locale names available for KLatexFormula */ KLF_EXPORT extern QList klf_avail_translations; /** A list of instances of currently installed translators. */ KLF_EXPORT extern QList klf_translators; /** \brief Small structure to store information for a translation file (.qm) * * Intented as (temporary) helper to manage translation files. Used e.g. * in \ref klf_reload_translations(). * * To see a list of available translations accessible within the whole * program, see \ref KLFTranslationInfo and \ref klf_avail_translations. */ class KLF_EXPORT KLFI18nFile { public: QString fpath; /** \brief Translation file base name (e.g. 'klf' for klf_fr.qm) */ QString name; /** \brief Locale Name (e.g. "fr" or "fr_CH") */ QString locale; /** \brief how specific the locale is (e.g. ""->0 , "fr"->1, "fr_CH"->2 ) */ int locale_specificity; /** Initialize this structure to the translation file \c filepath. */ KLFI18nFile(QString filepath); }; KLF_EXPORT void klf_add_avail_translation(KLFI18nFile i18nfile); /** Call this at startup or upon language change */ KLF_EXPORT void klf_reload_translations(QCoreApplication *app, const QString& currentlocale); // eg. baseFileName="cmdl-help" extension=".txt" will look for // "cmdl-help_fr_CH.txt", "cmdl-help_fr.txt", "cmdl-help.txt" assuming current locale is "fr_CH" KLF_EXPORT QString klfFindTranslatedDataFile(const QString& baseFileName, const QString& extension); /** \brief Current datastream compatibility klatexformula version * * This value is updated to the new version of KLF whenever a change in the format of the * QDataStream's occur. * * This is used notably in local styles list and symbols cache. * * \note This does NOT affect legacy \c ".klf" library files */ #define KLF_DATA_STREAM_APP_VERSION "3.3" /* don't forget to update below too! */ /** \brief 'Major' version part of \ref KLF_DATA_STREAM_APP_VERSION. */ #define KLF_DATA_STREAM_APP_VERSION_MAJ 3 /** \brief 'Minor' version part of \ref KLF_DATA_STREAM_APP_VERSION. */ #define KLF_DATA_STREAM_APP_VERSION_MIN 3 /** \brief Obtain the KLF version stream operations on \c d have to be compatible with. * * \returns the KLatexFormula verison as a QString, eg. \c "2.1" */ inline QString klfDataStreamAppVersion(const QDataStream& d) { return d.device()->property("klfDataStreamAppVersion").toString(); } /** This function sets up the stream for writing data (for internal storage, eg. * styles list) * * This function will set the \c klfDataStreamAppVersion property on the QIODevice associated * with the given \c stream, in order that objects that are sent into the stream can know their * compatibility version by querying the stream with klfDataStreamAppVersion(). */ KLF_EXPORT void klfDataStreamWriteHeader(QDataStream& stream, const QString headermagic); /** Reads a stream in which a header was prepared with klfDataStreamWriteHeader(). * * The data stream is automatically set to the correct version according to the header * which we have read. */ KLF_EXPORT bool klfDataStreamReadHeader(QDataStream& stream, const QStringList possibleHeaders, QString * readHeader = NULL, QString * readCompatKLFVersion = NULL) ; // -- // user scripts KLF_EXPORT void klf_reload_user_scripts(); extern QStringList klf_user_scripts; #endif klatexformula-4.1.0/src/klfdbus.cpp000644 000765 000024 00000014025 13660527435 020311 0ustar00philippestaff000000 000000 /*************************************************************************** * file klfdbus.cpp * This file is part of the KLatexFormula Project. * Copyright (C) 2011 by Philippe Faist * philippe.faist at bluewin.ch * * * 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 of the License, 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., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ /* $Id$ */ #include "klfmainwin.h" #include "klfdbus.h" KLFDBusAppAdaptor::KLFDBusAppAdaptor(QApplication *application, KLFMainWin *mainWin) : QDBusAbstractAdaptor(application), app(application), _mainwin(mainWin) { } KLFDBusAppAdaptor::~KLFDBusAppAdaptor() { } void KLFDBusAppAdaptor::raiseWindow() { if ( ! _mainwin->isVisible() ) _mainwin->show(); _mainwin->setWindowState(_mainwin->windowState() & ~Qt::WindowMinimized); _mainwin->raise(); _mainwin->activateWindow(); } Q_NOREPLY void KLFDBusAppAdaptor::quit() { app->quit(); } void KLFDBusAppAdaptor::setInputData(const QString& key, const QString& svalue, int ivalue) { if (key == "latex") { _mainwin->slotSetLatex(svalue); } else if (key == "fgcolor") { _mainwin->slotSetFgColor(svalue); } else if (key == "bgcolor") { _mainwin->slotSetBgColor(svalue); } else if (key == "mathmode") { _mainwin->slotSetMathMode(svalue); } else if (key == "preamble") { _mainwin->slotSetPreamble(svalue); } else if (key == "userscript") { _mainwin->slotSetUserScript(svalue); } else if (key == "dpi") { _mainwin->slotSetDPI(ivalue); } } void KLFDBusAppAdaptor::setAlterSetting_i(int setting, int value) { _mainwin->alterSetting((KLFMainWin::altersetting_which)setting, value); } void KLFDBusAppAdaptor::setAlterSetting_s(int setting, const QString& value) { _mainwin->alterSetting((KLFMainWin::altersetting_which)setting, value); } void KLFDBusAppAdaptor::evaluateAndSave(const QString& output, const QString& fmt) { _mainwin->slotEvaluateAndSave(output, fmt); } void KLFDBusAppAdaptor::openFile(const QString& fileName) { klfDbg("opening file: "<openFile(fileName); } void KLFDBusAppAdaptor::openFiles(const QStringList& fileNameList) { klfDbg("opening files: "<openFiles(fileNameList); } void KLFDBusAppAdaptor::openData(const QByteArray& data) { klfDbg("opening data: length="<openLibFiles(files); } KLFDBusAppInterface::KLFDBusAppInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) { } KLFDBusAppInterface::~KLFDBusAppInterface() { } QDBusReply KLFDBusAppInterface::quit() { QList argumentList; return callWithArgumentList(QDBus::Block, QString("quit"), argumentList); } QDBusReply KLFDBusAppInterface::raiseWindow() { QList argumentList; return callWithArgumentList(QDBus::Block, QString("raiseWindow"), argumentList); } QDBusReply KLFDBusAppInterface::setInputData(const QString& key, const QString& svalue, int ivalue) { QList argumentList; argumentList << QVariant(key) << QVariant(svalue) << QVariant(ivalue); return callWithArgumentList(QDBus::Block, QString("setInputData"), argumentList); } QDBusReply KLFDBusAppInterface::setAlterSetting_i(int setting, int value) { QList argumentList; argumentList << QVariant(setting) << QVariant(value); return callWithArgumentList(QDBus::Block, QString("setAlterSetting_i"), argumentList); } QDBusReply KLFDBusAppInterface::setAlterSetting_s(int setting, const QString& value) { QList argumentList; argumentList << QVariant(setting) << QVariant(value); return callWithArgumentList(QDBus::Block, QString("setAlterSetting_s"), argumentList); } QDBusReply KLFDBusAppInterface::evaluateAndSave(const QString& output, const QString& fmt) { return callWithArgumentList( QDBus::Block, QString("evaluateAndSave"), QList() << QVariant(output) << QVariant(fmt) ); } QDBusReply KLFDBusAppInterface::openFile(const QString& fileName) { return callWithArgumentList( QDBus::Block, QString("openFile"), QList() << QVariant(fileName) ); } QDBusReply KLFDBusAppInterface::openFiles(const QStringList& fileNameList) { return callWithArgumentList( QDBus::Block, QString("openFiles"), QList() << QVariant(fileNameList) ); } QDBusReply KLFDBusAppInterface::openData(const QByteArray& data) { return callWithArgumentList( QDBus::Block, QString("openData"), QList() << QVariant(data) ); } QDBusReply KLFDBusAppInterface::importCmdlKLFFiles(const QStringList& fnames) { QList argumentList; argumentList << QVariant(fnames); return callWithArgumentList(QDBus::Block, QString("importCmdlKLFFiles"), argumentList); } klatexformula-4.1.0/src/klfuiloader.h000644 000765 000024 00000003415 13660527435 020626 0ustar00philippestaff000000 000000 /*************************************************************************** * file klfuiloader.h * This file is part of the KLatexFormula Project. * Copyright (C) 2012 by Philippe Faist * philippe.faist at bluewin.ch * * * 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 of the License, 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., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ /* $Id$ */ #ifndef KLFUILOADER_H #define KLFUILOADER_H #include #include /** \brief loads a widget given by a UI XML form description generated by Qt Designer. * the widget may contain some KLF-specific handy widgets. */ KLF_EXPORT QWidget * klfLoadUI(QIODevice * iodata, QWidget * parentWidget = NULL); #endif klatexformula-4.1.0/src/klfmainwin.cpp000644 000765 000024 00000440115 13660527435 021021 0ustar00philippestaff000000 000000 /*************************************************************************** * file klfmainwin.cpp * This file is part of the KLatexFormula Project. * Copyright (C) 2011 by Philippe Faist * philippe.faist at bluewin.ch * * * 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 of the License, 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., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ /* $Id$ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef KLF_USE_SPARKLE #include "macosx/klfsparkleupdater.h" #endif #ifdef KLF_USE_WINSPARKLE #include "mswin/klfwinsparkleupdater.h" #endif #include "klflibview.h" #include "klflibbrowser.h" #include "klflatexsymbols.h" #include "klfsettings.h" #include "klfmain.h" #include "klfstylemanager.h" #include "klfmime.h" #include "klfcmdiface.h" #include "klfuiloader.h" #include "klfexporter.h" #include "klfexporter_p.h" #include "klfmainwin.h" #include "klfmainwin_p.h" KLFMainWin::KLFMainWin() : QMainWindow() { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; KLF_INIT_PRIVATE(KLFMainWin) ; u = new Ui::KLFMainWin; u->setupUi(this); setObjectName("KLFMainWin"); setAttribute(Qt::WA_StyledBackground); d->mPopup = NULL; loadSettings(); d->firstshow = true; d->output.status = 0; d->output.errorstr = QString(); d->pCmdIface = new KLFCmdIface(this); d->pCmdIface->registerObject(this, QLatin1String("klfmainwin.klfapp.klf")); setProperty("defaultPalette", QVariant::fromValue(palette())); // try hiding the prompt label -- it takes up space and isn't useful u->lblPromptMain->setVisible(false); // load styless loadStyles(); klfDbg("Instantiating LaTeX symbols") ; d->mLatexSymbols = new KLFLatexSymbols(this, d->settings); u->txtLatex->setFont(klfconfig.UI.latexEditFont); u->txtPreamble->setFont(klfconfig.UI.preambleEditFont); u->txtLatex->setWrapLines(klfconfig.UI.editorWrapLines); u->txtLatex->setTabChangesFocus(!klfconfig.UI.editorTabInsertsTab); u->txtPreamble->setWrapLines(klfconfig.UI.editorWrapLines); u->txtPreamble->setTabChangesFocus(!klfconfig.UI.editorTabInsertsTab); d->slotSetViewControlsEnabled(false); d->slotSetSaveControlsEnabled(false); QMenu *DPIPresets = new QMenu(this); // 1200 DPI connect(u->aDPI1200, SIGNAL(triggered()), d, SLOT(slotPresetDPISender())); u->aDPI1200->setData(1200); DPIPresets->addAction(u->aDPI1200); // 600 DPI connect(u->aDPI600, SIGNAL(triggered()), d, SLOT(slotPresetDPISender())); u->aDPI600->setData(600); DPIPresets->addAction(u->aDPI600); // 300 DPI connect(u->aDPI300, SIGNAL(triggered()), d, SLOT(slotPresetDPISender())); u->aDPI300->setData(300); DPIPresets->addAction(u->aDPI300); // 150 DPI connect(u->aDPI150, SIGNAL(triggered()), d, SLOT(slotPresetDPISender())); u->aDPI150->setData(150); DPIPresets->addAction(u->aDPI150); // set menu to the button u->btnDPIPresets->setMenu(DPIPresets); klfDbg("Setting up LaTeX fonts") ; // latex fonts d->reloadLatexFontDefs(); u->cbxLatexFont->addItem(tr("Computer Modern (default font)"), QVariant(QString())); int k; for (k = 0; k < d->pLatexFontDefs.size(); ++k) { u->cbxLatexFont->addItem(d->pLatexFontDefs[k].title, QVariant(d->pLatexFontDefs[k].identifier)); } // no idea why this seems to be needed to get text on combo box to display: u->cbxLatexFont->setPalette(QPalette(Qt::white)); u->cbxUserScript->setPalette(QPalette(Qt::white)); u->cbxMarginsUnit->setPalette(QPalette(Qt::white)); connect(u->txtLatex->syntaxHighlighter(), SIGNAL(newSymbolTyped(const QString&)), d, SLOT(slotNewSymbolTyped(const QString&))); // u->lblOutput->setLabelFixedSize(klfconfig.UI.labelOutputFixedSize); u->lblOutput->setEnableToolTipPreview(klfconfig.UI.enableToolTipPreview); klfconfig.UI.glowEffect.connectQObjectProperty(u->lblOutput, "glowEffect"); klfconfig.UI.glowEffectColor.connectQObjectProperty(u->lblOutput, "glowEffectColor"); klfconfig.UI.glowEffectRadius.connectQObjectProperty(u->lblOutput, "glowEffectRadius"); connect(u->lblOutput, SIGNAL(labelDrag()), this, SLOT(slotDrag())); connect(u->btnShowBigPreview, SIGNAL(clicked()), this, SLOT(slotShowBigPreview())); int h; h = u->btnDrag->sizeHint().height(); u->btnDrag->setFixedHeight(h - 5); h = u->btnCopy->sizeHint().height(); u->btnCopy->setFixedHeight(h - 5); h = u->btnSave->sizeHint().height(); u->btnSave->setFixedHeight(h - 5); QGridLayout *lyt = new QGridLayout(u->lblOutput); lyt->setSpacing(0); lyt->setMargin(0); d->mExportMsgLabel = new QLabel(u->lblOutput); d->mExportMsgLabel->setObjectName("mExportMsgLabel"); KLFRelativeFont *exportmsglabelRelFont = new KLFRelativeFont(u->lblOutput, d->mExportMsgLabel); exportmsglabelRelFont->setRelPointSize(-1); d->mExportMsgLabel->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); d->mExportMsgLabel->setMargin(1); d->mExportMsgLabel->setAlignment(Qt::AlignRight|Qt::AlignBottom); QPalette pal = d->mExportMsgLabel->palette(); pal.setColor(QPalette::Window, QColor(180,180,180,200)); pal.setColor(QPalette::WindowText, QColor(0,0,0,255)); d->mExportMsgLabel->setPalette(pal); d->mExportMsgLabel->setAutoFillBackground(true); d->mExportMsgLabel->setProperty("defaultPalette", QVariant::fromValue(pal)); //u->lyt_frmOutput->addWidget(mExportMsgLabel, 5, 0, 1, 2, Qt::AlignRight|Qt::AlignBottom); lyt->addItem(new QSpacerItem(1, 1, QSizePolicy::Fixed, QSizePolicy::Expanding), 0, 1, 2, 1); // lyt->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Fixed), 1, 0, 1, 1); lyt->addWidget(d->mExportMsgLabel, 1, 0, 1, 2); d->pExportMsgLabelTimerId = -1; d->mExportMsgLabel->hide(); connect(u->frmDetails, SIGNAL(sideWidgetShown(bool)), d, SLOT(slotDetailsSideWidgetShown(bool))); klfDbg("setting up relative font...") ; KLFRelativeFont *rf = new KLFRelativeFont(this, u->frmDetails); #ifdef KLF_WS_MAC rf->setRelPointSize(-2); rf->setThorough(true); #else rf->setRelPointSize(-1); #endif // u->frmDetails->setSideWidgetManager(klfconfig.UI.detailsSideWidgetType); klfconfig.UI.detailsSideWidgetType.connectQObjectProperty(u->frmDetails, "sideWidgetManagerType"); u->frmDetails->showSideWidget(false); u->txtLatex->installEventFilter(this); u->txtLatex->setDropDataHandler(this); // configure syntax highlighting colors KLF_CONNECT_CONFIG_SH_LATEXEDIT(u->txtLatex) ; KLF_CONNECT_CONFIG_SH_LATEXEDIT(u->txtPreamble) ; u->btnEvaluate->installEventFilter(this); // for appropriate tooltips u->btnDrag->installEventFilter(this); u->btnCopy->installEventFilter(this); // Shortcut for quit new QShortcut(QKeySequence(tr("Ctrl+Q")), this, SLOT(quit()), SLOT(quit()), Qt::ApplicationShortcut); // Shortcut for activating editor // QShortcut *editorActivatorShortcut = new QShortcut(QKeySequence(Qt::Key_F4), this, SLOT(slotActivateEditor()), SLOT(slotActivateEditor()), Qt::ApplicationShortcut); // QShortcut *editorActivatorShortcut = new QShortcut(QKeySequence(Qt::Key_F4 | Qt::ShiftModifier), this, SLOT(slotActivateEditorSelectAll()), SLOT(slotActivateEditorSelectAll()), Qt::ApplicationShortcut); // shortcut for big preview new QShortcut(QKeySequence(Qt::Key_F2), this, SLOT(slotShowBigPreview()), SLOT(slotShowBigPreview()), Qt::WindowShortcut); // Shortcut for parens mod/type cycle d->mShortcutNextParenType = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_BracketLeft), this, SLOT(slotCycleParenTypes()), SLOT(slotCycleParenTypes()), Qt::WindowShortcut); new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_BracketRight), this, SLOT(slotCycleParenTypesBack()), SLOT(slotCycleParenTypesBack()), Qt::WindowShortcut); d->mShortcutNextParenModifierType = new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_BracketLeft), this, SLOT(slotCycleParenModifiers()), SLOT(slotCycleParenModifiers()), Qt::WindowShortcut); new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_BracketRight), this, SLOT(slotCycleParenModifiersBack()), SLOT(slotCycleParenModifiersBack()), Qt::WindowShortcut); // Create our style manager d->mStyleManager = new KLFStyleManager(& d->styles, this); connect(d->mStyleManager, SIGNAL(refreshStyles()), d, SLOT(refreshStylePopupMenus())); connect(this, SIGNAL(stylesChanged()), d->mStyleManager, SLOT(slotRefresh())); connect(this, SIGNAL(stylesChanged()), this, SLOT(saveStyles())); connect(d->mStyleManager, SIGNAL(refreshStyles()), this, SLOT(saveStyles())); loadDefaultStyle(); // initialize the margin unit selector u->cbxMarginsUnit->setCurrentUnitAbbrev("pt"); // set custom math modes u->cbxMathMode->addItems(klfconfig.UI.customMathModes); // load library d->mLibBrowser = new KLFLibBrowser(this); //#ifdef KLF_WS_MAC // // library browser relative font // KLFRelativeFont *rf_libbrowser = new KLFRelativeFont(this, mLibBrowser); // rf_libbrowser->setRelPointSize(-2); // rf_libbrowser->setThorough(true); // #endif d->refreshShowCorrectClearButton(); // -- MAJOR SIGNAL/SLOT CONNECTIONS -- klfDbg("Setting up some major signal/slot connections") ; connect(u->aClearLatex, SIGNAL(triggered()), this, SLOT(slotClearLatex())); connect(u->aClearAll, SIGNAL(triggered()), this, SLOT(slotClearAll())); connect(u->btnEvaluate, SIGNAL(clicked()), this, SLOT(slotEvaluate())); connect(u->btnSymbols, SIGNAL(toggled(bool)), this, SLOT(slotSymbols(bool))); connect(u->btnLibrary, SIGNAL(toggled(bool)), this, SLOT(slotLibrary(bool))); connect(u->btnExpand, SIGNAL(clicked()), this, SLOT(slotExpandOrShrink())); connect(u->btnCopy, SIGNAL(clicked()), this, SLOT(slotCopy())); connect(u->btnDrag, SIGNAL(released()), this, SLOT(slotDrag())); connect(u->btnSave, SIGNAL(clicked()), this, SLOT(slotSave())); connect(u->btnSettings, SIGNAL(clicked()), this, SLOT(slotSettings())); connect(u->btnQuit, SIGNAL(clicked()), this, SLOT(quit())); connect(d->mLibBrowser, SIGNAL(requestRestore(const KLFLibEntry&, uint)), this, SLOT(restoreFromLibrary(const KLFLibEntry&, uint))); connect(d->mLibBrowser, SIGNAL(requestRestoreStyle(const KLFStyle&)), this, SLOT(slotLoadStyle(const KLFStyle&))); connect(d->mLatexSymbols, SIGNAL(insertSymbol(const KLFLatexSymbol&)), this, SLOT(insertSymbol(const KLFLatexSymbol&))); connect(this, SIGNAL(klfConfigChanged()), d->mLatexSymbols, SLOT(slotKlfConfigChanged())); connect(u->cbxUserScript, SIGNAL(activated(int)), d, SLOT(slotUserScriptSet(int))); connect(u->btnUserScriptReload, SIGNAL(clicked()), this, SLOT(slotReloadUserScripts())); connect(u->btnShowUserScriptLog, SIGNAL(clicked()), this, SLOT(slotShowUserScriptLog())); connect(u->btnUserScriptInfo, SIGNAL(clicked()), d, SLOT(slotUserScriptShowInfo())); connect(this, SIGNAL(userInputChanged()), this, SIGNAL(userActivity())); // our help/about dialog connect(u->btnHelp, SIGNAL(clicked()), this, SLOT(showAbout())); // SMALL REAL-TIME PREVIEW GENERATOR THREAD klfDbg("Setting up real-time preview generator thread") ; d->pLatexPreviewThread = new KLFLatexPreviewThread(this); d->pContLatexPreview = new KLFContLatexPreview(d->pLatexPreviewThread); // klfconfig.UI.labelOutputFixedSize.connectQObjectProperty(pLatexPreviewThread, "previewSize"); klfconfig.UI.previewTooltipMaxSize.connectQObjectProperty(d->pContLatexPreview, "largePreviewSize"); d->pContLatexPreview->setInput(d->collectInput(false)); d->pContLatexPreview->setSettings(currentSettings()); klfDbg("about to set up more connections ...") ; connect(u->txtLatex, SIGNAL(insertContextMenuActions(const QPoint&, QList *)), d, SLOT(slotEditorContextMenuInsertActions(const QPoint&, QList *))); connect(u->txtLatex, SIGNAL(textChanged()), d, SLOT(updatePreviewThreadInput()), Qt::QueuedConnection); connect(u->cbxMathMode, SIGNAL(editTextChanged(const QString&)), d, SLOT(updatePreviewThreadInput()), Qt::QueuedConnection); connect(u->chkMathMode, SIGNAL(stateChanged(int)), d, SLOT(updatePreviewThreadInput()), Qt::QueuedConnection); connect(u->colFg, SIGNAL(colorChanged(const QColor&)), d, SLOT(updatePreviewThreadInput()), Qt::QueuedConnection); // connect(u->chkBgTransparent, SIGNAL(stateChanged(int)), d, SLOT(updatePreviewThreadInput()), // Qt::QueuedConnection); connect(u->colBg, SIGNAL(colorChanged(const QColor&)), d, SLOT(updatePreviewThreadInput()), Qt::QueuedConnection); connect(u->cbxUserScript, SIGNAL(activated(const QString&)), d, SLOT(updatePreviewThreadInput()), Qt::QueuedConnection); connect(u->cbxLatexFont, SIGNAL(activated(const QString&)), d, SLOT(updatePreviewThreadInput()), Qt::QueuedConnection); connect(u->spnLatexFontSize, SIGNAL(valueChanged(int)), d, SLOT(updatePreviewThreadInput()), Qt::QueuedConnection); connect(u->txtPreamble, SIGNAL(textChanged()), d, SLOT(updatePreviewThreadInput()), Qt::QueuedConnection); connect(u->spnDPI, SIGNAL(valueChanged(int)), d, SLOT(updatePreviewThreadInput()), Qt::QueuedConnection); connect(u->spnVectorScale, SIGNAL(valueChanged(double)), d, SLOT(updatePreviewThreadInput()), Qt::QueuedConnection); connect(u->gbxOverrideMargins, SIGNAL(toggled(bool)), d, SLOT(updatePreviewThreadSettings()), Qt::QueuedConnection); connect(u->spnMarginTop, SIGNAL(valueChanged(double)), d, SLOT(updatePreviewThreadSettings()), Qt::QueuedConnection); connect(u->spnMarginRight, SIGNAL(valueChanged(double)), d, SLOT(updatePreviewThreadSettings()), Qt::QueuedConnection); connect(u->spnMarginBottom, SIGNAL(valueChanged(double)), d, SLOT(updatePreviewThreadSettings()), Qt::QueuedConnection); connect(u->spnMarginLeft, SIGNAL(valueChanged(double)), d, SLOT(updatePreviewThreadSettings()), Qt::QueuedConnection); connect(u->cbxUserScript, SIGNAL(activated(const QString&)), d, SLOT(updatePreviewThreadSettings()), Qt::QueuedConnection); connect(d->pContLatexPreview, SIGNAL(previewError(const QString&, int)), d, SLOT(showRealTimeError(const QString&, int))); connect(d->pContLatexPreview, SIGNAL(previewAvailable(const QImage&, const QImage&, const QImage&)), d, SLOT(showRealTimePreview(const QImage&, const QImage&))); connect(d->pContLatexPreview, SIGNAL(previewReset()), d, SLOT(showRealTimeReset())); // MIME EXPORT PROFILES klfDbg("Loading mime export profiles") ; // the KLFMimeExportProfileManager is also responsible for instantiating appropriate // QMacPasteboardMime, QWinClipboard classes d->pMimeExportProfileManager.addExportProfiles( KLFMimeExportProfileManager::loadKlfExportProfileList() ); // LOAD USER SCRIPTS klfDbg("Loading user scripts") ; slotReloadUserScripts(); // need currentSettings() to set PYTHONPATH etc. correctly KLFBackend::klfSettings settings = currentSettings(); // and set up the default config, if the user script can provide a default config klfDbg("About to load default settings for user scripts, if necessary. Currently user script config = " << klfconfig.UserScripts.userScriptConfig) ; foreach( QString us, klf_user_scripts) { klfDbg("Considering user script " << us) ; if (!klfconfig.UserScripts.userScriptConfig.contains(us) || klfconfig.UserScripts.userScriptConfig.value(us).isEmpty()) { KLFUserScriptInfo usinfo(us); if (usinfo.canProvideDefaultSettings()) { // set defaults klfDbg("setting default config for user script " << us) ; klfconfig.UserScripts.userScriptConfig[usinfo.userScriptPath()] = usinfo.queryDefaultSettings( & settings ); klfDbg("user script config is now " << klfconfig.UserScripts.userScriptConfig[usinfo.userScriptPath()]) ; } } } // REGISTER OUR EXPORTERS d->pExporterManager = new KLFExporterManager; klfDbg("Registering exporters") ; registerExporter(new KLFBackendFormatsExporter(this)); registerExporter(new KLFTexExporter(this)); registerExporter(new KLFHtmlDataExporter(this)); registerExporter(new KLFOpenOfficeDrawExporter(this)); registerExporter(new KLFTempFileUriExporter(this)); registerExporter(new KLFTempImgRefHtmlExporter(this)); // now, create one instance of KLFUserScriptExporter per export type user script ... extern QStringList klf_user_scripts; for (int k = 0; k < klf_user_scripts.size(); ++k) { if (KLFUserScriptInfo(klf_user_scripts[k]).category() == QLatin1String("klf-export-type")) { QString usname = klf_user_scripts[k]; klfDbg("Loading exporter for user script " << usname) ; KLFExportTypeUserScriptInfo usinfo(usname); registerExporter(new KLFUserScriptExporter(usname, this)); // add any corresponding export profiles, as well. QString profilesXmlFile = usinfo.mimeExportProfilesXmlFile(); klfDbg("profilesXmlFile = " << profilesXmlFile) ; if (profilesXmlFile.size()) { klfDbg("Loading profiles from XML file " << profilesXmlFile) ; d->pMimeExportProfileManager.addExportProfiles( KLFMimeExportProfile::loadProfilesFromXmlFile(usinfo.relativeFile(profilesXmlFile)) ); } } } // REGISTER PLATFORM-SPECIFIC CLIPBOARD CONVERTERS #if defined(KLF_WS_MAC) d->macFlavorsConverter = new KLFMacPasteboardMime; #elif defined(KLF_WS_WIN) d->winFormatsConverter = new KLFWinClipboard; #else // no special needs on X11 #endif // CREATE SETTINGS DIALOG d->mSettingsDialog = new KLFSettings(this); // INSTALL SOME EVENT FILTERS... FOR show/hide EVENTS klfDbg("Installing some event filters") ; d->mLibBrowser->installEventFilter(this); d->mLatexSymbols->installEventFilter(this); d->mStyleManager->installEventFilter(this); d->mSettingsDialog->installEventFilter(this); // ADDITIONAL SETUP #ifdef KLF_WS_MAC klfDbg("Mac OS X main win features setup") ; // watch for QFileOpenEvent s on mac QApplication::instance()->installEventFilter(this); klfconfig.UI.macBrushedMetalLook.connectQObjectSlot(this, "setMacBrushedMetalLook"); // And add a native Mac OS X menu bar d->pMacOSXMenu = new QMenuBar(0); d->pMacOSXMenu->setNativeMenuBar(true); // this is a virtual menu... QMenu *filemenu = d->pMacOSXMenu->addMenu("File"); // ... because the 'Preferences' action is detected and is sent to the 'klatexformula' menu... // (and don't translate it, Qt will replace it by the default mac 'preferences' menu item) filemenu->addAction("Preferences", this, SLOT(slotSettings())); filemenu->addAction("About", this, SLOT(showAbout())); d->pCheckForUpdatesAction = new QAction(tr("Check for Updates"), this); d->pCheckForUpdatesAction->setMenuRole(QAction::ApplicationSpecificRole); filemenu->addAction(d->pCheckForUpdatesAction); QMenu *shortmenu = d->pMacOSXMenu->addMenu("Shortcuts"); // remember, on Qt/Mac Ctrl key is mapped to Command shortmenu->addAction(tr("LaTeX Symbols Palette"), this, SLOT(slotToggleSymbols()), QKeySequence("Ctrl+1")); shortmenu->addAction(tr("Equation Library Browser"), this, SLOT(slotToggleLibrary()), QKeySequence("Ctrl+2")); shortmenu->addAction(tr("Show Details"), this, SLOT(slotExpandOrShrink()), QKeySequence("Ctrl+D")); shortmenu->addAction(tr("Activate Editor"), this, SLOT(slotActivateEditor()), QKeySequence("Ctrl+L")); shortmenu->addAction(tr("Activate Editor and Select All"), this, SLOT(slotActivateEditorSelectAll()), QKeySequence("Ctrl+Shift+L")); shortmenu->addAction(tr("Show Big Preview"), this, SLOT(slotShowBigPreview()), QKeySequence("Ctrl+P")); // Shortcut for parens mod/type cycle // new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_BracketLeft), this, SLOT(slotCycleParenTypes()), // SLOT(slotCycleParenTypes()), Qt::WindowShortcut); // new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_BracketLeft), this, SLOT(slotCycleParenModifiers()), // SLOT(slotCycleParenModifiers()), Qt::WindowShortcut); // dock menu will be added once shown only, to avoid '...autoreleased without NSAutoreleasePool...' // annoying messages #else d->pMacOSXMenu = NULL; d->pCheckForUpdatesAction = NULL; #endif // INTERNAL FLAGS d->evaloutput_uptodate = true; // OTHER STUFF retranslateUi(false); connect(this, SIGNAL(applicationLocaleChanged(const QString&)), this, SLOT(retranslateUi())); connect(this, SIGNAL(applicationLocaleChanged(const QString&)), d->mLibBrowser, SLOT(retranslateUi())); connect(this, SIGNAL(applicationLocaleChanged(const QString&)), d->mSettingsDialog, SLOT(retranslateUi())); connect(this, SIGNAL(applicationLocaleChanged(const QString&)), d->mStyleManager, SLOT(retranslateUi())); // About Dialog & What's New dialog d->mAboutDialog = new KLFAboutDialog(this); d->mWhatsNewDialog = new KLFWhatsNewDialog(this); connect(d->mAboutDialog, SIGNAL(linkActivated(const QUrl&)), this, SLOT(helpLinkAction(const QUrl&))); connect(d->mWhatsNewDialog, SIGNAL(linkActivated(const QUrl&)), this, SLOT(helpLinkAction(const QUrl&))); d->mHelpLinkActions << KLFMainWinPrivate::HelpLinkAction("/whats_new", this, "showWhatsNew", false); d->mHelpLinkActions << KLFMainWinPrivate::HelpLinkAction("/about", this, "showAbout", false); d->mHelpLinkActions << KLFMainWinPrivate::HelpLinkAction("/popup_close", d, "slotPopupClose", false); d->mHelpLinkActions << KLFMainWinPrivate::HelpLinkAction("/popup", d, "slotPopupAction", true); d->mHelpLinkActions << KLFMainWinPrivate::HelpLinkAction("/settings", this, "showSettingsHelpLinkAction", true); if ( klfconfig.Core.thisVersionMajMinFirstRun && ! klfconfig.checkExePaths() ) { addWhatsNewText("

"+ tr("Your executable paths (latex, dvips, gs) seem not to be detected properly. " "Please adjust the settings in the settings dialog.", "[[additional text in what's-new-dialog in case of bad detected settings. this " "is HTML formatted text.]]") +"

"); } klfDbg("Font is "<" + tr("LaTeX' Computer Modern Sans Serif font is used as the default application font." " Don't like it? Choose your preferred application font.") .arg("klfaction:/settings?control=AppFonts") + "

"); } // and load the library d->mHistoryLibResource = NULL; d->loadedlibrary = true; loadLibrary(); registerDataOpener(new KLFBasicDataOpener(this)); // registerDataOpener(new KLFAddOnDataOpener(this)); registerDataOpener(new KLFTexDataOpener(this)); // and present a cool window size adjustSize(); } void KLFMainWin::retranslateUi(bool alsoBaseUi) { if (alsoBaseUi) u->retranslateUi(this); // version information as tooltip on the welcome widget u->lblPromptMain->setToolTip(tr("KLatexFormula %1").arg(QString::fromUtf8(KLF_VERSION_STRING))); d->refreshStylePopupMenus(); } KLFMainWin::~KLFMainWin() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; // flush data on all pending KLFMimeData instances klfDbg("flushing any data on any KLFMimeData instances so that no more delayed retrieval is required."); foreach (KLFMimeData * mimedata, KLFMimeData::activeMimeDataInstances()) { klfDbg("transmitting all data on mimedata with formats="<formats()) ; mimedata->transmitAllData(); } klfDbg("mime datas flushed."); klfDbg("about to save settings etc."); saveLibraryState(); saveSettings(); saveStyles(); klfDbg("deleting style menu...") ; if (d->mStyleMenu) delete d->mStyleMenu; klfDbg("deleting latex symbols...") ; if (d->mLatexSymbols) delete d->mLatexSymbols; klfDbg("deleting library browser...") ; if (d->mLibBrowser) delete d->mLibBrowser; // we aren't necessarily its parent klfDbg("deleting settings dialog...") ; if (d->mSettingsDialog) delete d->mSettingsDialog; klfDbg("deleting latex preview thread...") ; if (d->pContLatexPreview) delete d->pContLatexPreview; if (d->pLatexPreviewThread) delete d->pLatexPreviewThread; // Do not delete these -- segfault?? // // #if defined(KLF_WS_MAC) // if (d->macFlavorsConverter) { // delete d->macFlavorsConverter; // } // #elif defined(KLF_WS_WIN) // if (d->winFormatsConverter) { // delete d->winFormatsConverter; // } // #else // // no special needs on X11 // #endif delete d->pExporterManager; KLF_DELETE_PRIVATE ; klfDbg("deleting interface...") ; delete u; } void KLFMainWinPrivate::refreshExportTypesMenu() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; // Export profiles selection list pExportProfileQuickMenuActionList.clear(); int k; QList eplist = pMimeExportProfileManager.exportProfileList(); QMenu *menu = new QMenu(K->u->btnSetExportProfile); QActionGroup *actionGroup = new QActionGroup(menu); actionGroup->setExclusive(true); QSignalMapper *smapper = new QSignalMapper(menu); QMap submenuacts; QMap submenuactions; for (k = 0; k < eplist.size(); ++k) { QString submenu = eplist[k].inSubMenu(); QWidget *parentmenu = NULL; if (submenuactions.contains(submenu)) { parentmenu = submenuactions[submenu]; } else if (submenu.isEmpty()) { parentmenu = menu; } else { // create new submenu for this item QAction *smact = new QAction(submenu, menu); QMenu *smenu = new QMenu(menu); klfDbg("new submenu "<pExportProfileQuickMenuActionList[k]->data()) ; // found the one d->pExportProfileQuickMenuActionList[k]->setChecked(true); break; // by auto-exclusivity the other ones will be un-checked. } } } else { // uncheck all items (since there is not a unique one set, drag and copy differ) for (k = 0; k < d->pExportProfileQuickMenuActionList.size(); ++k) d->pExportProfileQuickMenuActionList[k]->setChecked(false); } u->btnSetExportProfile->setEnabled(klfconfig.ExportData.menuExportProfileAffectsDrag || klfconfig.ExportData.menuExportProfileAffectsCopy); d->pContLatexPreview->setEnabled( klfconfig.UI.enableRealTimePreview ); u->txtLatex->setWrapLines(klfconfig.UI.editorWrapLines); u->txtLatex->setTabChangesFocus(!klfconfig.UI.editorTabInsertsTab); u->txtPreamble->setWrapLines(klfconfig.UI.editorWrapLines); u->txtPreamble->setTabChangesFocus(!klfconfig.UI.editorTabInsertsTab); emit klfConfigChanged(); } void KLFMainWinPrivate::showExportMsgLabel(const QString& msg, int timeout) { mExportMsgLabel->show(); mExportMsgLabel->setPalette(mExportMsgLabel->property("defaultPalette").value()); mExportMsgLabel->setProperty("timeTotal", timeout); mExportMsgLabel->setProperty("timeRemaining", timeout); mExportMsgLabel->setProperty("timeInterval", 200); mExportMsgLabel->setText(msg); if (pExportMsgLabelTimerId == -1) { pExportMsgLabelTimerId = K->startTimer(mExportMsgLabel->property("timeInterval").toInt()); } } void KLFMainWinPrivate::refreshStylePopupMenus() { if (mStyleMenu == NULL) mStyleMenu = new QMenu(K); mStyleMenu->clear(); QAction *a; for (int i = 0; i < styles.size(); ++i) { a = mStyleMenu->addAction(styles[i].name); a->setData(i); connect(a, SIGNAL(triggered()), this, SLOT(slotLoadStyleAct())); } mStyleMenu->addSeparator(); mStyleMenu->addAction(//QIcon(":/pics/savestyle.png"), tr("Save Current Style"), K, SLOT(slotSaveStyle())); mStyleMenu->addAction(//QIcon(":/pics/savestyle.png"), tr("Save Current Style As Default"), K, SLOT(slotSaveStyleAsDefault())); mStyleMenu->addAction(//QIcon(":/pics/managestyles.png"), tr("Manage Styles"), K, SLOT(slotStyleManager()), 0 /* accel */); } static QString kdelocate(const char *fname) { QString candidate; QStringList env = QProcess::systemEnvironment(); QStringList kdehome = env.filter(QRegExp("^KDEHOME=")); if (kdehome.size() == 0) { candidate = QDir::homePath() + QString("/.kde/share/apps/klatexformula/") + QString::fromLocal8Bit(fname); } else { QString kdehomeval = kdehome[0]; kdehomeval.replace(QRegExp("^KDEHOME="), ""); candidate = kdehomeval + "/share/apps/klatexformula/" + QString::fromLocal8Bit(fname); } if (QFile::exists(candidate)) { return candidate; } return QString::null; } bool KLFMainWinPrivate::try_load_style_list(const QString& styfname) { if ( ! QFile::exists(styfname) ) return false; QFile fsty(styfname); if ( ! fsty.open(QIODevice::ReadOnly) ) return false; QDataStream str(&fsty); // data stream version is set in klfDataStreamReadHeader() QString readHeader; QString readCompatKLFVersion; bool r = klfDataStreamReadHeader(str, QStringList()<> styles; return true; } void KLFMainWin::loadStyles() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; d->styles = KLFStyleList(); // empty list to start with QStringList styfnamecandidates; styfnamecandidates << klfconfig.homeConfigDir + QString("/styles-klf%1").arg(KLF_DATA_STREAM_APP_VERSION) << klfconfig.homeConfigDir + QLatin1String("/styles") << QLatin1String("kde-locate"); // locate in KDE only if necessary in for loop below int k; bool result = false; for (k = 0; k < styfnamecandidates.size(); ++k) { QString fn = styfnamecandidates[k]; if (fn == QLatin1String("kde-locate")) fn = kdelocate("styles"); // try to load this file if ( (result = d->try_load_style_list(fn)) == true ) break; } // Don't fail if result is false, this is the case on first run (!) // if (!result) { // QMessageBox::critical(this, tr("Error"), tr("Error: Unable to load your style list!")); // } if (d->styles.isEmpty()) { // if stylelist is empty, populate with default style KLFStyle s1(tr("Default", "[[style name]]"), qRgb(0, 0, 0), qRgba(255, 255, 255, 0), "\\begin{align*} ... \\end{align*}", "\\usepackage{amsmath}\n\\usepackage{amssymb}\n\\usepackage{amsfonts}\n", 600); // KLFStyle s2(tr("Inline"), qRgb(0, 0, 0), qRgba(255, 255, 255, 0), "\\[ ... \\]", "", 150); // s2.overrideBBoxExpand = KLFStyle::BBoxExpand(0,0,0,0); d->styles.append(s1); // d->styles.append(s2); } d->mStyleMenu = 0; d->refreshStylePopupMenus(); u->btnLoadStyle->setMenu(d->mStyleMenu); } void KLFMainWin::saveStyles() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; klfconfig.ensureHomeConfigDir(); QString s = klfconfig.homeConfigDir + QString("/styles-klf%1").arg(KLF_DATA_STREAM_APP_VERSION); QFile f(s); if ( ! f.open(QIODevice::WriteOnly) ) { QMessageBox::critical(this, tr("Error"), tr("Error: Unable to write to styles file!\n%1").arg(s)); return; } QDataStream stream(&f); // stream version is set by klfDataStreamWriteHeader(): klfDataStreamWriteHeader(stream, "KLATEXFORMULA_STYLE_LIST"); stream << d->styles; } void KLFMainWin::loadLibrary() { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; // start by loading the saved library browser state. // Inside this function the value of klfconfig.LibraryBrowser.restoreURLs is taken // into account. loadLibrarySavedState(); // Locate a good library/history file. // KLFPleaseWaitPopup pwp(tr("Loading library, please wait..."), this); // pwp.showPleaseWait(); // the default library file QString localfname = klfconfig.Core.libraryFileName; if (QFileInfo(localfname).isRelative()) localfname.prepend(klfconfig.homeConfigDir + "/"); QString importfname; if ( ! QFile::exists(localfname) ) { // if unexistant, try to load: importfname = klfconfig.homeConfigDir + "/library"; // the 3.1 library file if ( ! QFile::exists(importfname) ) importfname = kdelocate("library"); // or the KDE KLF 2.1 library file if ( ! QFile::exists(importfname) ) importfname = kdelocate("history"); // or the KDE KLF 2.0 history file if ( ! QFile::exists(importfname) ) { // as last resort we load our default library bundled with KLatexFormula importfname = ":/data/defaultlibrary.klf"; } } // importfname is non-empty only if the local .klf.db library file is inexistant. QUrl localliburl = QUrl::fromLocalFile(localfname); localliburl.setScheme(klfconfig.Core.libraryLibScheme); QUrlQuery localliburlq(localliburl); localliburlq.addQueryItem("klfDefaultSubResource", "History"); localliburl.setQuery(localliburlq); // If the history is already open from library browser saved state, retrieve it // This is possibly NULL d->mHistoryLibResource = d->mLibBrowser->getOpenResource(localliburl); if (!QFile::exists(localfname)) { // create local library resource KLFLibEngineFactory *localLibFactory = KLFLibEngineFactory::findFactoryFor(localliburl.scheme()); if (localLibFactory == NULL) { qWarning()<mHistoryLibResource = localLibFactory->createResource(localliburl.scheme(), param, this); if (d->mHistoryLibResource == NULL) { qWarning()<mHistoryLibResource->setTitle(tr("Local Library")); d->mHistoryLibResource -> createSubResource(QLatin1String("Archive"), tr("Archive", "[[default sub-resource title for archive sub-resource]]")); if (d->mHistoryLibResource->supportedFeatureFlags() & KLFLibResourceEngine::FeatureSubResourceProps) { d->mHistoryLibResource->setSubResourceProperty(QLatin1String("History"), KLFLibResourceEngine::SubResPropViewType, QLatin1String("default+list")); d->mHistoryLibResource->setSubResourceProperty(QLatin1String("Archive"), KLFLibResourceEngine::SubResPropViewType, QLatin1String("default")); } else { d->mHistoryLibResource->setViewType(QLatin1String("default+list")); } } if (d->mHistoryLibResource == NULL) { d->mHistoryLibResource = KLFLibEngineFactory::openURL(localliburl, this); } if (d->mHistoryLibResource == NULL) { qWarning()<<"KLFMainWin::loadLibrary(): Can't open local history resource!\n\tURL="<mHistoryLibResource, SIGNAL(operationStartReportingProgress(KLFProgressReporter *, const QString&)), &pdlg, SLOT(startReportingProgress(KLFProgressReporter *))); pdlg.setAutoClose(false); pdlg.setAutoReset(false); // locate the import file and scheme QUrl importliburl = QUrl::fromLocalFile(importfname); QString scheme = KLFLibBasicWidgetFactory::guessLocalFileScheme(importfname); if (scheme.isEmpty()) { // assume .klf if not able to guess scheme = "klf+legacy"; } importliburl.setScheme(scheme); QUrlQuery importliburlq(importliburl); importliburlq.addQueryItem("klfReadOnly", "true"); importliburl.setQuery(importliburlq); // import library from an older version library file. KLFLibEngineFactory *factory = KLFLibEngineFactory::findFactoryFor(importliburl.scheme()); if (factory == NULL) { qWarning()<<"KLFMainWin::loadLibrary(): Can't find factory for URL="<openResource(importliburl, this); // import all sub-resources QStringList subResList = importres->subResourceList(); klfDbg( "\tImporting sub-resources: "< allentries = importres->allEntries(subres); klfDbg("Got "<mHistoryLibResource->hasSubResource(subres) ) { d->mHistoryLibResource->createSubResource(subres); } d->mHistoryLibResource->insertEntries(subres, insertentries); } } } // Open history sub-resource into library browser bool r; r = d->mLibBrowser->openResource(d->mHistoryLibResource, KLFLibBrowser::NoCloseRoleFlag|KLFLibBrowser::OpenNoRaise, QLatin1String("default+list")); if ( ! r ) { qWarning()<<"KLFMainWin::loadLibrary(): Can't open local history resource!\n\tURL="<mHistoryLibResource->subResourceList(); int k; for (k = 0; k < subresources.size(); ++k) { // if (subresources[k] == QLatin1String("History")) // already open // continue; // if a URL is already open, it won't open it a second time. QUrl url = localliburl; QUrlQuery urlq(url); urlq.removeAllQueryItems("klfDefaultSubResource"); urlq.addQueryItem("klfDefaultSubResource", subresources[k]); url.setQuery(urlq); uint flags = KLFLibBrowser::NoCloseRoleFlag|KLFLibBrowser::OpenNoRaise; QString sr = subresources[k].toLower(); if (sr == "history" || sr == tr("History").toLower()) flags |= KLFLibBrowser::HistoryRoleFlag; if (sr == "archive" || sr == tr("Archive").toLower()) flags |= KLFLibBrowser::ArchiveRoleFlag; d->mLibBrowser->openResource(url, flags); } } void KLFMainWin::loadLibrarySavedState() { QString fname = klfconfig.homeConfigDir + "/libbrowserstate.xml"; if ( ! QFile::exists(fname) ) { klfDbg("No saved library browser state found ("<mLibBrowser->loadGuiState(vstatemap, klfconfig.LibraryBrowser.restoreURLs); } void KLFMainWin::saveLibraryState() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; QString fname = klfconfig.homeConfigDir + "/libbrowserstate.xml"; QVariantMap statemap = d->mLibBrowser->saveGuiState(); QFile f(fname); if ( ! f.open(QIODevice::WriteOnly) ) { qWarning()<<"Can't open file "<openResource(mHistoryLibResource, KLFLibBrowser::NoCloseRoleFlag, QLatin1String("default+list")); if ( ! r ) qWarning()<setPlainText(..) slotSetLatex(entry.latexWithCategoryTagsComments()); } u->lblOutput->display(entry.preview(), entry.preview(), false); // u->frmOutput->setEnabled(false); d->slotSetViewControlsEnabled(true); d->slotSetSaveControlsEnabled(false); activateWindow(); raise(); u->txtLatex->setFocus(); emit userActivity(); } void KLFMainWinPrivate::slotLibraryButtonRefreshState(bool on) { K->u->btnLibrary->setChecked(on); } void KLFMainWin::insertSymbol(const KLFLatexSymbol& s) { // see if we need to insert the xtrapreamble QStringList cmds = s.preamble; int k; QString preambletext = u->txtPreamble->latex(); QString addtext; if (klfconfig.UI.symbolIncludeWithPreambleDefs) { for (k = 0; k < cmds.size(); ++k) { slotEnsurePreambleCmd(cmds[k]); } } // only after that actually insert the symbol, so as not to interfere with popup package suggestions. // if we have a selection, insert it into the symbol arguments QTextCursor cur = u->txtLatex->textCursor(); QString sel = cur.selectedText(); //.replace(QChar(0x2029), "\n"); // Qt's Unicode paragraph separators->\n cur.beginEditBlock(); QString insertsymbol = s.symbol; int nmoveleft = -1; if (s.symbol_option) insertsymbol += "[]"; if (s.symbol_numargs >= 0) { int n = s.symbol_numargs; if (sel.size()) { if (n > 0) { insertsymbol += "{"+sel+"}"; --n; } else { // insert before selection, with space insertsymbol += " "+sel; } } while (n-- > 0) { insertsymbol += "{}"; nmoveleft += 2; } } cur.insertText(insertsymbol); if (nmoveleft > 0) { cur.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, nmoveleft); } else { // select char next to what we inserted, to see if we need to add a space QTextCursor cur2 = cur; cur2.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 1); if (cur2.selectedText().size()) { int c = cur2.selectedText()[0].unicode(); if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { // have to insert space to separate from the ascii char that follows cur.insertText(" "); } } } cur.endEditBlock(); u->txtLatex->setTextCursor(cur); activateWindow(); raise(); u->txtLatex->setFocus(); } void KLFMainWin::insertDelimiter(const QString& delim, int charsBack) { u->txtLatex->insertDelimiter(delim, charsBack); } void KLFMainWinPrivate::getMissingCmdsFor(const QString& symbol, QStringList * missingCmds, QString *guiText, bool wantHtmlText) { if (missingCmds == NULL) { qWarning()<clear(); *guiText = QString(); if (symbol.isEmpty()) return; QList syms = mLatexSymbols->cache()->findSymbols(symbol); if (syms.isEmpty()) return; // choose the symbol that requires the least extra packages... int k, kbest = 0; for (k = 0; k < syms.size(); ++k) { if (syms[k].preamble.size() < syms[kbest].preamble.size()) kbest = k; } KLFLatexSymbol sym = syms[kbest]; QStringList cmds = sym.preamble; klfDbg("Got symbol for "<u->txtPreamble->latex(); QStringList packages; bool moreDefinitions = false; for (k = 0; k < cmds.size(); ++k) { if (curpreambletext.indexOf(cmds[k]) >= 0) continue; // this line is already included missingCmds->append(cmds[k]); QRegExp rx("\\\\usepackage.*\\{(\\w+)\\}"); klfDbg(" regexp="<\\1")); QString requiredtext; if (packages.size()) { if (packages.size() == 1) requiredtext += tr("package %1", "[[part of popup text, if one package only]]").arg(packages[0]); else requiredtext += tr("packages %1", "[[part of popup text, if multiple packages]]").arg(packages.join(", ")); } if (moreDefinitions) requiredtext += packages.size() ? tr(" and some more definitions", "[[part of hint popup text, when packages also need to be included]]") : tr("some definitions", "[[part of hint popup text, when no packages need to be included]]"); if (!wantHtmlText) requiredtext.replace(QRegExp("<[^>]*>"), ""); *guiText = requiredtext; } void KLFMainWinPrivate::slotNewSymbolTyped(const QString& symbol) { if (mPopup == NULL) mPopup = new KLFMainWinPopup(K); if (!klfconfig.UI.showHintPopups) return; QStringList cmds; QString requiredtext; getMissingCmdsFor(symbol, &cmds, &requiredtext); if (cmds.isEmpty()) // nothing to include return; QByteArray cmdsData = klfSaveVariantToText(QVariant(cmds)); QString msgkey = "preambleCmdStringList:"+QString::fromLatin1(cmdsData); QUrl urlaction; urlaction.setScheme("klfaction"); urlaction.setPath("/popup"); QUrl urlactionClose = urlaction; QUrlQuery urlactionq(urlaction); urlactionq.addQueryItem("preambleCmdStringList", QString::fromLatin1(cmdsData)); urlaction.setQuery(urlactionq); QUrlQuery urlactionCloseq(urlactionClose); urlactionCloseq.addQueryItem("removeMessageKey", msgkey); urlactionClose.setQuery(urlactionCloseq); mPopup->addMessage(msgkey, tr("Symbol %3 may require %2.") .arg(urlaction.toEncoded(), requiredtext, symbol) ); mPopup->show(); mPopup->raise(); } void KLFMainWinPrivate::slotPopupClose() { if (mPopup != NULL) { delete mPopup; mPopup = NULL; } } void KLFMainWinPrivate::slotPopupAction(const QUrl& url) { klfDbg("url="<hasMessages()) slotPopupClose(); return; } if (urlq.hasQueryItem("acceptAll")) { slotPopupAcceptAll(); return; } if (urlq.hasQueryItem("removeMessageKey")) { QString key = urlq.queryItemValue("removeMessageKey"); mPopup->removeMessage(key); if (!mPopup->hasMessages()) slotPopupClose(); return; } if (urlq.hasQueryItem("configDontShow")) { // don't show popups slotPopupClose(); klfconfig.UI.showHintPopups = false; K->saveSettings(); return; } } void KLFMainWinPrivate::slotPopupAcceptAll() { if (mPopup == NULL) return; // accept all messages, based on their key QStringList keys = mPopup->messageKeys(); int k; for (k = 0; k < keys.size(); ++k) { QString s = keys[k]; if (s.startsWith("preambleCmdStringList:")) { QByteArray data = s.mid(strlen("preambleCmdStringList:")).toLatin1(); QStringList cmds = klfLoadVariantFromText(data, "QStringList").toStringList(); int k; for (k = 0; k < cmds.size(); ++k) { K->slotEnsurePreambleCmd(cmds[k]); } continue; } qWarning()<latex(); KLFLatexSyntaxHighlighter *sh = latexEdit->syntaxHighlighter(); KLF_ASSERT_NOT_NULL(sh, "syntax highlighter is NULL! ", return QVariantMap(); ) ; QList blocks = sh->parsedBlocksForPos(curpos, KLFLatexSyntaxHighlighter::ParsedBlock::ParenMask); klfDbg("got blocks: "< otherblocks; if (block.parenotherpos >= 0) otherblocks = sh->parsedBlocksForPos(block.parenotherpos, KLFLatexSyntaxHighlighter::ParsedBlock::ParenMask); KLFLatexSyntaxHighlighter::ParsedBlock otherblock, openblock, closeblock; bool hasotherblock = false; for (int klj = 0; klj < otherblocks.size(); ++klj) { if (otherblocks[klj].parenotherpos == block.pos) { // found the other block otherblock = otherblocks[klj]; hasotherblock = true; if (block.parenisopening) { openblock = block; closeblock = otherblock; } else { openblock = otherblock; closeblock = block; } } } if (hasotherblock) { // all ok, exists vmap["hasotherparen"] = true; vmap["otherpos"] = otherblock.pos; vmap["otherlen"] = otherblock.len; vmap["othermod"] = otherblock.parenmodifier; vmap["otherstr"] = otherblock.parenstr; } vmap["openparenmod"] = openblock.parenmodifier; vmap["openparenstr"] = openblock.parenstr; vmap["closeparenmod"] = closeblock.parenmodifier; vmap["closeparenstr"] = closeblock.parenstr; KLF_ASSERT_CONDITION(open_paren_modifiers.size() == close_paren_modifiers.size(), "Open and Close paren modifiers list do NOT have same size !!!", return QVariantMap(); ) ; KLF_ASSERT_CONDITION(open_paren_types.size() == close_paren_types.size(), "Open and Close paren types list do NOT have same size !!!", return QVariantMap(); ) ; init_paren_modifiers_and_types(); // Qt's implicit sharing system should speed this up, this is probably not _that_ dumb... vmap["open_paren_modifiers"] = open_paren_modifiers; vmap["close_paren_modifiers"] = close_paren_modifiers; vmap["open_paren_types"] = open_paren_types; vmap["close_paren_types"] = close_paren_types; return vmap; } return QVariantMap(); } void KLFMainWinPrivate::slotEditorContextMenuInsertActions(const QPoint& pos, QList *actionList) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; KLFLatexEdit *latexEdit = qobject_cast(sender()); KLF_ASSERT_NOT_NULL( latexEdit, "KLFLatexEdit sender is NULL!", return ) ; // try to determine if we clicked on a symbol, and suggest to include the corresponding package QTextCursor cur = latexEdit->cursorForPosition(pos); QString text = latexEdit->latex(); int curpos = cur.position(); // matches a latex symbol like \symbol (backslash-word) or \; (backslash-anychar) QRegExp rxSym("\\\\" // literal backslash "(\\w+|.)" // word or character ); int i = text.lastIndexOf(rxSym, curpos); // search backwards from curpos if (i >= 0) { // matched somewhere before in text. See if we clicked on it int len = rxSym.matchedLength(); QString symbol = text.mid(i, len); QStringList cmds; QString guitext; getMissingCmdsFor(symbol, &cmds, &guitext, false); if (cmds.size()) { QAction * aInsCmds = new QAction(latexEdit); aInsCmds->setText(tr("Include missing definitions for %1").arg(symbol)); aInsCmds->setData(QVariant(cmds)); connect(aInsCmds, SIGNAL(triggered()), this, SLOT(slotInsertMissingPackagesFromActionSender())); *actionList << aInsCmds; } } /* QAction *insertSymbolAction = new QAction(QIcon(":/pics/symbols.png"), tr("Insert Symbol ...", "[[context menu entry]]"), latexEdit); connect(insertSymbolAction, SIGNAL(triggered()), this, SLOT(slotSymbols())); *actionList << insertSymbolAction; */ const QVariantMap vmap = parseLatexEditPosParenInfo(latexEdit, curpos); if (!vmap.isEmpty() && vmap.value("has_paren", false).toBool()) { QAction *amenumod = new QAction(latexEdit); QAction *amenutyp = new QAction(latexEdit); /** \bug here on Mac OS X "Ctrl" stays Ctrl and is not translated to "Cmd" */ amenumod->setText(tr("Paren Modifier (%1) ...") .arg(mShortcutNextParenModifierType->key().toString(QKeySequence::NativeText))); amenutyp->setText(tr("Change Paren (%1) ...") .arg(mShortcutNextParenType->key().toString(QKeySequence::NativeText))); QMenu *changemenumod = new QMenu(latexEdit); QMenu *changemenutyp = new QMenu(latexEdit); QStringList open_paren_modifiers = vmap["open_paren_modifiers"].toStringList(); QStringList close_paren_modifiers = vmap["close_paren_modifiers"].toStringList(); QStringList open_paren_types = vmap["open_paren_types"].toStringList(); QStringList close_paren_types = vmap["close_paren_types"].toStringList(); // now create our menus int kl; for (kl = 0; kl < open_paren_modifiers.size(); ++kl) { QString title = vmap["parenisopening"].toBool() ? open_paren_modifiers[kl] : close_paren_modifiers[kl]; if (title.isEmpty()) { title = tr("", "[[in editor context menu]]"); } else if (vmap["hasotherparen"].toBool()) { title = open_paren_modifiers[kl] + vmap["openparenstr"].toString() + " ... " + close_paren_modifiers[kl] + vmap["closeparenstr"].toString(); } QAction *a = changemenumod->addAction(title, this, SLOT(slotChangeParenFromActionSender())); QVariantMap data = vmap; data["newparenmod_index"] = kl; a->setData(data); } for (kl = 0; kl < open_paren_types.size(); ++kl) { QString title; if (vmap["hasotherparen"].toBool()) { title = vmap["openparenmod"].toString() + open_paren_types[kl] + " ... " + vmap["closeparenmod"].toString() + close_paren_types[kl]; } else { title = vmap["parenisopening"].toBool() ? open_paren_types[kl] : close_paren_types[kl]; } QAction *a = changemenutyp->addAction(title, this, SLOT(slotChangeParenFromActionSender())); QVariantMap data = vmap; data["newparenstr_index"] = kl; a->setData(data); } amenumod->setMenu(changemenumod); amenutyp->setMenu(changemenutyp); *actionList << amenutyp << amenumod; } // suggest to wrap selection into a delimiter QTextCursor textcur = latexEdit->textCursor(); if (textcur.hasSelection()) { QString s = textcur.selectedText(); klfDbg("has selection, will add an 'enclose in delimiter...' menu. Selected="<< s) ; // get a list of possible delimiters QAction *adelim = new QAction(latexEdit); adelim->setText(tr("Enclose in delimiter")); QMenu *menuDelim = new QMenu(latexEdit); int pos = textcur.position(); int anc = textcur.anchor(); if (pos > anc) { qSwap(pos, anc); } int len = anc - pos; QMenu *parenDelimMenu = new QMenu(latexEdit); QList pspecs = KLFLatexSyntaxHighlighter::ParsedBlock::parenSpecs.parenSpecList(); foreach (KLFLatexParenSpecs::ParenSpec p, pspecs) { QAction * a = parenDelimMenu->addAction(QString("%1 ... %2").arg(p.open, p.close), this, SLOT(slotEncloseRegionInDelimiterFromActionSender())); QVariantMap v; v["pos"] = pos; v["len"] = len; v["opendelim"] = p.open; v["closedelim"] = p.close; a->setData(QVariant(v)); } QAction *aMenuParenDelim = menuDelim->addAction(tr("Parenthesis-like", "[[in paren menu delimiter type]]")); aMenuParenDelim->setMenu(parenDelimMenu); adelim->setMenu(menuDelim); *actionList << adelim; } } void KLFMainWinPrivate::slotInsertMissingPackagesFromActionSender() { QAction * a = qobject_cast(sender()); if (a == NULL) { qWarning()<data(); QStringList cmds = data.toStringList(); int k; for (k = 0; k < cmds.size(); ++k) { K->slotEnsurePreambleCmd(cmds[k]); } } static inline bool latexGlueMaybeSpace(const QString& a, const QString& b) { if (QRegExp("\\w$").indexIn(a) != -1 && QRegExp("^\\w").indexIn(b) != -1) return true; return false; } void KLFMainWinPrivate::slotChangeParenFromActionSender() { QAction * a = qobject_cast(sender()); if (a == NULL) { qWarning()<data(); QVariantMap data = v.toMap(); slotChangeParenFromVariantMap(data); } void KLFMainWinPrivate::slotChangeParenFromVariantMap(const QVariantMap& data) { int pos = data["pos"].toInt(); int len = data["len"].toInt(); bool isopening = data.value("parenisopening", QVariant(false)).toBool(); QString mod = data["parenmod"].toString(); QString str = data["parenstr"].toString(); QString othermod, otherstr; int mod_index = data.value("newparenmod_index", QVariant(-1)).toInt(); int str_index = data.value("newparenstr_index", QVariant(-1)).toInt(); QStringList open_paren_modifiers = data["open_paren_modifiers"].toStringList(); QStringList close_paren_modifiers = data["close_paren_modifiers"].toStringList(); QStringList open_paren_types = data["open_paren_types"].toStringList(); QStringList close_paren_types = data["close_paren_types"].toStringList(); if (mod_index >= 0) { mod = open_paren_modifiers[mod_index]; othermod = close_paren_modifiers[mod_index]; if (!isopening) qSwap(mod, othermod); } if (str_index >= 0) { str = open_paren_types[str_index]; otherstr = close_paren_types[str_index]; if (!isopening) qSwap(str, otherstr); } QString s = mod + str; QString latextext = K->u->txtLatex->latex(); if (latexGlueMaybeSpace(s, latextext.mid(pos+len))) { // need to separate the paren symbol (e.g. \langle) with the following text, i.e. make // sure that we have "\langle x", not "\langlex" s += " "; } latexEditReplace(pos, len, s); // and correct the 'other' pos index by a delta, in case the 'other' pos index // is _after_ our first replacement... (yes, indexes have been shifted by our // first replacement) int delta = isopening ? s.length() - len : 0; bool hasother = data["hasotherparen"].toBool(); if (hasother) { int opos = data["otherpos"].toInt() + delta; int olen = data["otherlen"].toInt(); QString omod = data["othermod"].toString(); QString ostr = data["otherstr"].toString(); if (mod_index >= 0) omod = othermod; if (str_index >= 0) ostr = otherstr; QString os = omod + ostr; QString latextext = K->u->txtLatex->latex(); if (latexGlueMaybeSpace(os, latextext.mid(opos+olen))) { // need to separate the paren symbol (e.g. \langle) with the following text, i.e. make // sure that we have "\rangle x", not "\ranglex" os += " "; } latexEditReplace(opos, olen, os); } } void KLFMainWin::slotCycleParenModifiers(bool forward) { d->slotCycleParenModifiers(forward); } void KLFMainWinPrivate::slotCycleParenModifiers(bool forward) { int curpos = K->u->txtLatex->textCursor().position(); const QVariantMap vmap = parseLatexEditPosParenInfo(K->u->txtLatex, curpos); if (vmap.isEmpty() || !vmap.value("has_paren", false).toBool()) return; bool isopening = vmap["parenisopening"].toBool(); QString mod = vmap["parenmod"].toString(); const QStringList& paren_mod_list = isopening ? vmap["open_paren_modifiers"].toStringList() : vmap["close_paren_modifiers"].toStringList(); int mod_index = paren_mod_list.indexOf(mod); if (mod_index < 0) { qWarning()<slotCycleParenTypes(forward); } void KLFMainWinPrivate::slotCycleParenTypes(bool forward) { int curpos = K->u->txtLatex->textCursor().position(); const QVariantMap vmap = parseLatexEditPosParenInfo(K->u->txtLatex, curpos); if (vmap.isEmpty() || !vmap.value("has_paren", false).toBool()) return; bool isopening = vmap["parenisopening"].toBool(); QString str = vmap["parenstr"].toString(); const QStringList& paren_typ_list = isopening ? vmap["open_paren_types"].toStringList() : vmap["close_paren_types"].toStringList(); int str_index = paren_typ_list.indexOf(str); if (str_index < 0) { qWarning()<(sender()); if (a == NULL) { qWarning()<data(); QVariantMap data = v.toMap(); slotEncloseRegionInDelimiter(data); } void KLFMainWinPrivate::slotEncloseRegionInDelimiter(const QVariantMap& vmap) { int pos = vmap["pos"].toInt(); int len = vmap["len"].toInt(); QString opendelim = vmap["opendelim"].toString(); QString closedelim = vmap["closedelim"].toString(); QString text = K->u->txtLatex->latex().mid(pos, len); if (latexGlueMaybeSpace(opendelim, text)) opendelim += " "; if (latexGlueMaybeSpace(closedelim, K->u->txtLatex->latex().mid(pos+len))) closedelim += " "; latexEditReplace(pos, len, opendelim + text + closedelim); } void KLFMainWinPrivate::latexEditReplace(int pos, int len, const QString& text) { QTextCursor c = K->u->txtLatex->textCursor(); int cpos = c.position(); // account for changed text in cpos if (cpos > pos + len) cpos += (text.length() - len); else if (cpos > pos) cpos = pos + text.length(); // end of edited text c.setPosition(pos); c.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, len); c.removeSelectedText(); c.insertFragment(QTextDocumentFragment::fromPlainText(text)); c.setPosition(cpos); K->u->txtLatex->setTextCursor(c); } void KLFMainWinPrivate::slotUserScriptDisableInputs(KLFUserScriptInfo * infobase) { QStringList disableInputs = QStringList(); if (infobase != NULL) { disableInputs = KLFBackendEngineUserScriptInfo(infobase->userScriptPath()).disableInputs(); } bool disableall = disableInputs.contains("ALL", Qt::CaseInsensitive); bool disableallinput = disableInputs.contains("ALL_INPUT", Qt::CaseInsensitive); bool disableall_except = disableInputs.contains("EXCEPT", Qt::CaseInsensitive); #define WANT_DISABLE_ALL(x, disableall) \ ( (!disableall && disableInputs.contains(x, Qt::CaseInsensitive)) \ || (disableall && !disableall_except) \ || (disableall && disableall_except && !disableInputs.contains(x, Qt::CaseInsensitive)) ) #define WANT_DISABLE_INPUT(x) \ WANT_DISABLE_ALL(x, (disableall || disableallinput)) #define WANT_DISABLE_NORMAL(x) \ WANT_DISABLE_ALL(x, disableall) // names are the same as in klfbackend.cpp K->u->colFg->setDisabled(WANT_DISABLE_INPUT("FG_COLOR")); K->u->colBg->setDisabled(WANT_DISABLE_INPUT("BG_COLOR")); K->u->chkMathMode->setDisabled(WANT_DISABLE_INPUT("MATHMODE")); K->u->cbxMathMode->setDisabled(WANT_DISABLE_INPUT("MATHMODE") || !K->u->chkMathMode->isChecked()); K->u->txtPreamble->setDisabled(WANT_DISABLE_INPUT("PREAMBLE")); K->u->cbxLatexFont->setDisabled(WANT_DISABLE_INPUT("FONT")); K->u->spnLatexFontSize->setDisabled(WANT_DISABLE_INPUT("FONTSIZE")); K->u->spnDPI->setDisabled(WANT_DISABLE_NORMAL("DPI")); K->u->btnDPIPresets->setDisabled(WANT_DISABLE_NORMAL("DPI")); K->u->chkVectorScale->setDisabled(WANT_DISABLE_NORMAL("VECTORSCALE")); K->u->spnVectorScale->setDisabled(WANT_DISABLE_NORMAL("VECTORSCALE") || !K->u->chkVectorScale->isChecked()); K->u->gbxOverrideMargins->setDisabled(WANT_DISABLE_NORMAL("MARGINS")); } void KLFMainWinPrivate::slotUserScriptSet(int index) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; klfDbg("index="<", "[[popup info]]"); slotUserScriptDisableInputs(NULL); K->u->stkScriptInput->setCurrentWidget(K->u->wScriptInputEmptyPage); K->u->lblScriptInputEmptyPage->setText(tr("", "[[space for user script custom input]]")); K->u->btnUserScriptInfo->setIcon(QIcon(":/pics/info.png")); K->u->btnUserScriptInfo->setEnabled(false); return; } K->u->btnUserScriptInfo->setEnabled(true); // update user script info and settings widget KLFBackendEngineUserScriptInfo usinfo(K->u->cbxUserScript->itemData(index).toString()); if (usinfo.hasWarnings() || usinfo.hasErrors()) K->u->btnUserScriptInfo->setIcon(QIcon(":/pics/infowarn.png")); else K->u->btnUserScriptInfo->setIcon(QIcon(":/pics/info.png")); int textpointsize = QFontInfo(K->u->lblUserScript->font()).pointSize(); QString extracss = QString::fromLatin1("body { font-size: %1pt; }\n").arg(textpointsize-1) + QString::fromLatin1("p.msgerror { color: #a00000; font-size: %1pt;}\n").arg(textpointsize+1) + QString::fromLatin1("p.msgwarning { color: #a04000; font-size: %1pt; }\n").arg(textpointsize+1); userScriptCurrentInfo = usinfo.htmlInfo(extracss); slotUserScriptDisableInputs(&usinfo); K->u->lblScriptInputEmptyPage->setText(tr("", "[[space for user script custom input]]")); QString uifile = usinfo.inputFormUI(); if (!uifile.isEmpty()) { QString uifilefull = usinfo.relativeFile(uifile); QWidget * scriptinputwidget = getUserScriptInputWidget(uifilefull); K->u->stkScriptInput->setCurrentWidget(scriptinputwidget); klfDbg("Set script input UI. uifile="<u->stkScriptInput->setCurrentWidget(K->u->wScriptInputEmptyPage); } } QWidget * KLFMainWinPrivate::getUserScriptInputWidget(const QString& uifile) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; klfDbg("uifile = " << uifile) ; if (userScriptInputWidgets.contains(uifile)) { klfDbg("widget from cache.") ; return userScriptInputWidgets[uifile]; } QFile uif(uifile); uif.open(QFile::ReadOnly); QWidget * scriptinputwidget = klfLoadUI(&uif, K->u->stkScriptInput); uif.close(); KLF_ASSERT_NOT_NULL(scriptinputwidget, "Can't load script input widget "<u->wScriptInputEmptyPage) ; K->u->stkScriptInput->addWidget(scriptinputwidget); userScriptInputWidgets[uifile] = scriptinputwidget; return scriptinputwidget; } void KLFMainWinPrivate::slotUserScriptShowInfo() { QWhatsThis::showText(K->u->btnUserScriptInfo->mapToGlobal(QPoint(10,10)), userScriptCurrentInfo, K->u->btnUserScriptInfo); } void KLFMainWinPrivate::reloadLatexFontDefs() { // find collection of XML files QStringList fxmllist; // in the following directories QStringList fxmldirs; fxmldirs << klfconfig.homeConfigDir + "/conf/latexfontdefs.d/" << klfconfig.globalShareDir + "/conf/latexfontdefs.d/" << ":/conf/latexfontdefs.d/"; klfDbgT("starting to collect XML files from dirs "< 0) { klfWarning("Ignoring XML latex font definition file " << fn << " which requires KLF version " << minklfversion << "."); continue; } QDomNode n; for (n = root.firstChild(); ! n.isNull(); n = n.nextSibling()) { QDomElement e = n.toElement(); // try to convert the node to an element. if ( e.isNull() || n.nodeType() != QDomNode::ElementNode ) continue; if ( e.nodeName() != "font-def" ) { klfWarning("Parsing XML file "<") ; continue; } LatexFontDef thisfont; QDomNode efdetails; for (efdetails = e.firstChild(); ! efdetails.isNull(); efdetails = efdetails.nextSibling() ) { if ( efdetails.isNull() || efdetails.nodeType() != QDomNode::ElementNode ) continue; QDomElement eefdetails = efdetails.toElement(); klfDbg("read element "<translate("xmltr_latexfontdefs", eefdetails.text().toUtf8().constData(), "[[tag: ]]"); } else if ( eefdetails.nodeName() == "identifier" ) { if (!thisfont.identifier.isEmpty()) { klfWarning("File "<u->btnSymbols->setChecked(on); } void KLFMainWin::showAbout() { d->mAboutDialog->show(); } void KLFMainWin::showWhatsNew() { // center the widget on the desktop QSize desktopSize = QApplication::desktop()->screenGeometry(this).size(); QSize wS = d->mWhatsNewDialog->sizeHint(); d->mWhatsNewDialog->move(desktopSize.width()/2 - wS.width()/2, desktopSize.height()/2 - wS.height()/2); d->mWhatsNewDialog->show(); } void KLFMainWin::showSettingsHelpLinkAction(const QUrl& link) { klfDbg( ": link="<mSettingsDialog->show(); d->mSettingsDialog->showControl(QUrlQuery(link).queryItemValue("control")); } void KLFMainWin::helpLinkAction(const QUrl& link) { klfDbg( ": Link is "<mHelpLinkActions.size(); ++k) { if (d->mHelpLinkActions[k].path == link.path()) { // got one if (d->mHelpLinkActions[k].wantParam) QMetaObject::invokeMethod(d->mHelpLinkActions[k].reciever, d->mHelpLinkActions[k].memberFunc.constData(), Qt::QueuedConnection, Q_ARG(QUrl, link)); else QMetaObject::invokeMethod(d->mHelpLinkActions[k].reciever, d->mHelpLinkActions[k].memberFunc.constData(), Qt::QueuedConnection); calledOne = true; } } if (!calledOne) { klfWarning("no action found for link="<mWhatsNewDialog->addExtraText(htmlSnipplet); } void KLFMainWin::registerHelpLinkAction(const QString& path, QObject *object, const char * member, bool wantUrlParam) { d->mHelpLinkActions << KLFMainWinPrivate::HelpLinkAction(path, object, member, wantUrlParam); } void KLFMainWin::registerExporter(KLFExporter *exporter) { d->pExporterManager->registerExporter(exporter) ; } void KLFMainWin::unregisterExporter(KLFExporter *exporter) { d->pExporterManager->registerExporter(exporter); } void KLFMainWin::registerDataOpener(KLFAbstractDataOpener *dataopener) { KLF_ASSERT_NOT_NULL( dataopener, "Refusing to register NULL Data Opener object!", return ) ; d->pDataOpeners.append(dataopener); } void KLFMainWin::unregisterDataOpener(KLFAbstractDataOpener *dataopener) { d->pDataOpeners.removeAll(dataopener); } void KLFMainWin::setWidgetStyle(const QString& qtstyle) { // qDebug("setWidgetStyle(\"%s\")", qPrintable(qtstyle)); if (d->widgetstyle == qtstyle) { // qDebug("This style is already applied."); return; } if (qtstyle.isNull()) { // setting a null style resets internal widgetstyle name... d->widgetstyle = QString::null; return; } QStringList stylelist = QStyleFactory::keys(); if (stylelist.indexOf(qtstyle) == -1) { qWarning("Bad Style: %s. List of possible styles are:", qPrintable(qtstyle)); int k; for (k = 0; k < stylelist.size(); ++k) qWarning("\t%s", qPrintable(stylelist[k])); return; } // qDebug("Setting the style %s. are we visible?=%d", qPrintable(qtstyle), (int)QWidget::isVisible()); QStyle *s = QStyleFactory::create(qtstyle); // qDebug("Got style ptr=%p", (void*)s); if ( ! s ) { qWarning("Can't instantiate style %s!", qPrintable(qtstyle)); return; } d->widgetstyle = qtstyle; qApp->setStyle( s ); } void KLFMainWin::setQuitOnClose(bool quitOnClose) { d->ignore_close_event = ! quitOnClose; } bool KLFMainWin::executeURLCommandsFromFile(const QString& fname) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; klfDbg("fname="<pCmdIface->executeCommand(url); } else if (s == "_autoremovefile") { wantautoremove = true; } else { klfWarning("Unknown pragma: "<quit() (and can safely be called several // times in the quitting process) KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; if (d->is_quitting) { // already called. klfDbg("already quitting.") ; return; } d->is_quitting = true; u->frmDetails->showSideWidget(false); u->frmDetails->sideWidgetManager()->waitForShowHideActionFinished(); hide(); /** \bug ### go through all top-level widgets given by QApplication::topLevelWidgets or so ? */ if (d->mLibBrowser) d->mLibBrowser->hide(); if (d->mLatexSymbols) d->mLatexSymbols->hide(); if (d->mStyleManager) d->mStyleManager->hide(); if (d->mSettingsDialog) d->mSettingsDialog->hide(); if (!d->qapp_quit_called) { d->qapp_quit_called = true; qApp->quit(); } } bool KLFMainWin::event(QEvent *e) { klfDbg("e->type() == "<type()); if (e->type() == QEvent::ApplicationFontChange) { klfDbg("Application font change.") ; if (klfconfig.UI.useSystemAppFont) klfconfig.UI.applicationFont = QApplication::font(); // refresh the font setting... } return QWidget::event(e); } bool KLFMainWin::nativeEvent(const QByteArray & , void * , long * ) { // if we need to process native X11/Mac/Win events, do it here. return false; } void KLFMainWin::childEvent(QChildEvent *e) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; QWidget::childEvent(e); } bool KLFMainWin::eventFilter(QObject *obj, QEvent *e) { // even with QShortcuts, we still need this event handler (why?) if (obj == u->txtLatex) { if (e->type() == QEvent::KeyPress) { QKeyEvent *ke = (QKeyEvent*) e; if (ke->key() == Qt::Key_Return && (QApplication::keyboardModifiers() == Qt::ShiftModifier || QApplication::keyboardModifiers() == Qt::ControlModifier)) { slotEvaluate(); return true; } if (d->mPopup != NULL && ke->key() == Qt::Key_Return && QApplication::keyboardModifiers() == Qt::AltModifier) { d->slotPopupAcceptAll(); return true; } if (d->mPopup != NULL && ke->key() == Qt::Key_Escape) { d->slotPopupClose(); return true; } if (ke->key() == Qt::Key_F9) { slotExpand(true); u->tabsOptions->setCurrentWidget(u->tabLatexImage); u->txtPreamble->setFocus(); return true; } } } if (obj == u->txtLatex || obj == u->btnEvaluate) { if (e->type() == QEvent::KeyPress) { QKeyEvent *ke = (QKeyEvent*) e; QKeySequence seq = QKeySequence(ke->key() | ke->modifiers()); if (seq.matches(QKeySequence::Copy)) { // copy key shortcut. Check if editor received the event, and if there is a selection // in the editor. If there is a selection, let the editor copy it to clipboard. Otherwise // we will copy our output if (/*obj == u->txtLatex &&*/ u->txtLatex->textCursor().hasSelection()) { u->txtLatex->copy(); return true; } else { slotCopy(); return true; } } } } // ---- if ( obj == d->mLibBrowser && (e->type() == QEvent::Hide || e->type() == QEvent::Show) ) { d->slotLibraryButtonRefreshState(d->mLibBrowser->isVisible()); } if ( obj == d->mLatexSymbols && (e->type() == QEvent::Hide || e->type() == QEvent::Show) ) { d->slotSymbolsButtonRefreshState(d->mLatexSymbols->isVisible()); } // ---- if ( obj == QApplication::instance() ) { klfDbg("Application event: type="<type()) ; if ( e->type() == QEvent::Close && ! d->qapp_quit_called ) { // intercept close-event, which means that qApp->quit() was called directly d->qapp_quit_called = true; quit(); } } if ( obj == QApplication::instance() && e->type() == QEvent::FileOpen ) { // open a URL or file QFileOpenEvent *fe = (QFileOpenEvent*)e; klfDbg("QFileOpenEvent: Opening: "<file()<<"; URL="<url()) ; #if QT_VERSION >= 0x040600 // for QFileOpenEvent::url() if (fe->url().scheme() == "klfcommand") { // this is a KLFCmdIface-command d->pCmdIface->executeCommand(fe->url()); return true; } #endif openFile(fe->file()); return true; } // ---- if ( (obj == u->btnCopy || obj == u->btnDrag) && e->type() == QEvent::ToolTip ) { QString tooltipText; if (obj == u->btnCopy) { tooltipText = tr("Copy the formula to the clipboard. Current export profile: %1") .arg(d->pMimeExportProfileManager.findExportProfile(klfconfig.ExportData.copyExportProfile) .description()); } else if (obj == u->btnDrag) { tooltipText = tr("Click and keep mouse button pressed to drag your formula to another application. " "Current export profile: %1") .arg(d->pMimeExportProfileManager.findExportProfile(klfconfig.ExportData.dragExportProfile) .description()); } QToolTip::showText(((QHelpEvent*)e)->globalPos(), tooltipText, qobject_cast(obj)); return true; } return QWidget::eventFilter(obj, e); } void KLFMainWin::refreshAllWindowStyleSheets() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; QWidgetList wlist = QApplication::topLevelWidgets(); foreach (QWidget *w, wlist) { w->setStyleSheet(w->styleSheet()); } } void KLFMainWin::hideEvent(QHideEvent *e) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; klfDbg("...") ; QWidget::hideEvent(e); } void KLFMainWin::showEvent(QShowEvent *e) { if ( d->firstshow ) { d->firstshow = false; // if it's the first time we're run, // show the what's new if needed. if ( klfconfig.Core.thisVersionMajMinFirstRun ) { QMetaObject::invokeMethod(this, "showWhatsNew", Qt::QueuedConnection); } #ifdef KLF_WS_MAC // add a menu item in dock to paste from clipboard QMenu *adddockmenu = new QMenu; adddockmenu->addAction(tr("Paste Clipboard Contents", "[[Dock Menu Entry on MacOSX]]"), this, SLOT(pasteLatexFromClipboard())); extern void qt_mac_set_dock_menu(QMenu *); qt_mac_set_dock_menu(adddockmenu); #endif } QWidget::showEvent(e); } void KLFMainWin::timerEvent(QTimerEvent *e) { if (e->timerId() == d->pExportMsgLabelTimerId) { int total = d->mExportMsgLabel->property("timeTotal").toInt(); int remaining = d->mExportMsgLabel->property("timeRemaining").toInt(); int interval = d->mExportMsgLabel->property("timeInterval").toInt(); int fadepercent = (100 * remaining / total) * 3; // 0 ... 300 if (fadepercent < 100 && fadepercent >= 0) { QPalette pal = d->mExportMsgLabel->property("defaultPalette").value(); QColor c = pal.color(QPalette::Window); c.setAlpha(c.alpha() * fadepercent / 100); pal.setColor(QPalette::Window, c); QColor c2 = pal.color(QPalette::WindowText); c2.setAlpha(c2.alpha() * fadepercent / 100); pal.setColor(QPalette::WindowText, c2); d->mExportMsgLabel->setPalette(pal); } remaining -= interval; if (remaining < 0) { d->mExportMsgLabel->hide(); killTimer(d->pExportMsgLabelTimerId); d->pExportMsgLabelTimerId = -1; } else { d->mExportMsgLabel->setProperty("timeRemaining", QVariant(remaining)); } } } void KLFMainWin::alterSetting(int which, int ivalue) { d->settings_altered = true; switch (which) { case altersetting_LBorderOffset: d->settings.lborderoffset = ivalue; break; case altersetting_TBorderOffset: d->settings.tborderoffset = ivalue; break; case altersetting_RBorderOffset: d->settings.rborderoffset = ivalue; break; case altersetting_BBorderOffset: d->settings.bborderoffset = ivalue; break; case altersetting_CalcEpsBoundingBox: d->settings.calcEpsBoundingBox = (bool)ivalue; break; case altersetting_OutlineFonts: d->settings.outlineFonts = (bool)ivalue; break; case altersetting_WantSVG: d->settings.wantSVG = (bool)ivalue; break; case altersetting_WantPDF: d->settings.wantPDF = (bool)ivalue; break; default: qWarning()<settings_altered = true; switch (which) { case altersetting_TempDir: d->settings.tempdir = svalue; break; case altersetting_Latex: d->settings.latexexec = svalue; break; case altersetting_Dvips: d->settings.dvipsexec = svalue; break; case altersetting_Gs: d->settings.gsexec = svalue; break; case altersetting_Epstopdf: d->settings.epstopdfexec = svalue; break; case altersetting_LBorderOffset: d->settings.lborderoffset = svalue.toDouble(); break; case altersetting_TBorderOffset: d->settings.tborderoffset = svalue.toDouble(); break; case altersetting_RBorderOffset: d->settings.rborderoffset = svalue.toDouble(); break; case altersetting_BBorderOffset: d->settings.bborderoffset = svalue.toDouble(); break; default: qWarning()<mLibBrowser; } KLFLatexSymbols * KLFMainWin::latexSymbolsWidget() { return d->mLatexSymbols; } KLFStyleManager * KLFMainWin::styleManagerWidget() { return d->mStyleManager; } KLFSettings * KLFMainWin::settingsDialog() { return d->mSettingsDialog; } QMenu * KLFMainWin::styleMenu() { return d->mStyleMenu; } KLFConfig * KLFMainWin::klfConfig() { return & klfconfig; } QString KLFMainWin::widgetStyle() const { return d->widgetstyle; } KLFLatexEdit *KLFMainWin::latexEdit() { return u->txtLatex; } KLFLatexSyntaxHighlighter * KLFMainWin::syntaxHighlighter() { return u->txtLatex->syntaxHighlighter(); } KLFLatexSyntaxHighlighter * KLFMainWin::preambleSyntaxHighlighter() { return u->txtPreamble->syntaxHighlighter(); } void KLFMainWin::applySettings(const KLFBackend::klfSettings& s) { d->settings = s; d->settings_altered = false; d->updatePreviewThreadSettings(); } void KLFMainWinPrivate::displayError(const QString& error) { QMessageBox::critical(K, tr("Error"), error); } void KLFMainWinPrivate::updatePreviewThreadInput() { // recheck battery status, in case we have the proper setting on // TODO: write this & the setting klfDbg("laptop?: "<enabled(); if (enabled && onbattery) { // we need to stop the preview thread klfDbg("Disabling continuous preview because we're on battery power") ; pContLatexPreview->setEnabled(false); } else if (!enabled && !onbattery) { // we can restart the preview thread, as we're back on power. klfDbg("Re-enabling continuous preview because we're no longer on battery power") ; pContLatexPreview->setEnabled(true); } } bool inputchanged = pContLatexPreview->setInput(collectInput(false)); if (inputchanged) { emit K->userInputChanged(); } if (evaloutput_uptodate && !inputchanged) { // if we are in 'evaluated' mode, with a displayed result, then don't allow a window resize // to invalidate evaluated contents return; } bool sizechanged = pContLatexPreview->setPreviewSize(calcPreviewSize()); if (inputchanged || sizechanged) { evaloutput_uptodate = false; } } QSize KLFMainWinPrivate::calcPreviewSize() { return (QSizeF(K->u->lblOutput->size()) * K->devicePixelRatioF()).toSize(); } void KLFMainWinPrivate::updatePreviewThreadSettings() { KLFBackend::klfSettings s = K->currentSettings(); klfDbg("Updating preview thread's settings. currentSettings().execenv="<setSettings(s); } void KLFMainWin::setTxtLatexFont(const QFont& f) { u->txtLatex->setFont(f); } void KLFMainWin::setTxtPreambleFont(const QFont& f) { u->txtPreamble->setFont(f); } void KLFMainWin::setMacBrushedMetalLook(bool metallook) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; #ifdef KLF_WS_MAC klfDbg("On mac. metallook = " << metallook) ; // doesn't work ... :( //setUnifiedTitleAndToolBarOnMac(metallook); //setAttribute(Qt::WA_MacBrushedMetal, metallook); const char * pn = metallook ? "paletteMacBrushedMetalLook" : "paletteDefault"; u->txtLatex->setPalette(u->txtLatex->property(pn).value()); u->txtLatex->setStyleSheet(u->txtLatex->styleSheet()); if (u->frmDetails->sideWidgetManagerType() == QLatin1String("ShowHide")) { u->txtPreamble->setPalette(u->txtPreamble->property(pn).value()); u->txtPreamble->setStyleSheet(u->txtPreamble->styleSheet()); u->cbxMathMode->setPalette(u->txtPreamble->property(pn).value()); u->cbxMathMode->setStyleSheet(u->cbxMathMode->styleSheet()); u->cbxMathMode->lineEdit()->setPalette(u->txtPreamble->property(pn).value()); u->cbxMathMode->lineEdit()->setStyleSheet(u->cbxMathMode->lineEdit()->styleSheet()); } #else Q_UNUSED(metallook); if (metallook) { klfWarning("Mac brushed metal look is only implemented under Mac OS X !"); } #endif } void KLFMainWinPrivate::showRealTimeReset() { klfDbg("reset.") ; K->u->lblOutput->display(QImage(), QImage(), false); slotSetViewControlsEnabled(false); slotSetSaveControlsEnabled(false); } void KLFMainWinPrivate::showRealTimePreview(const QImage& preview, const QImage& largePreview) { klfDbg("preview.size=" << preview.size()<< " largepreview.size=" << largePreview.size()); if (evaloutput_uptodate) // we have clicked on 'Evaluate' button, use that image! return; K->u->lblOutput->display(preview, largePreview, false); slotSetViewControlsEnabled(true); slotSetSaveControlsEnabled(false); emit K->previewAvailable(preview, largePreview); } void KLFMainWinPrivate::showRealTimeError(const QString& errmsg, int errcode) { klfDbg("errormsg[0..99]="<u->lblOutput->displayError(s, /*labelenabled:*/false); slotSetViewControlsEnabled(false); slotSetSaveControlsEnabled(false); emit K->previewRealTimeError(errmsg, errcode); } QVariantMap KLFMainWinPrivate::collectUserScriptInput() const { // check for user script input QWidget * scriptInputWidget = K->u->stkScriptInput->currentWidget(); if (scriptInputWidget == K->u->wScriptInputEmptyPage) return QVariantMap(); QVariantMap data; // there's input for the user script QList inwidgets = scriptInputWidget->findChildren(QRegExp("^INPUT_.*")); Q_FOREACH (QWidget *inw, inwidgets) { QString n = inw->objectName(); KLF_ASSERT_CONDITION(n.startsWith("INPUT_"), "?!? \"found\" child widget "<inherits("KLFLatexEdit")) { userPropName = "plainText"; } else { QMetaProperty userProp = inw->metaObject()->userProperty(); KLF_ASSERT_CONDITION(userProp.isValid(), "user property of widget "<property(userPropName.constData()); data[n] = value; } klfDbg("userscriptinput is "<currentInputState(); // remember the math mode if the user clicked on 'Evaluate' (final==true) if (final && K->u->cbxMathMode->findText(input.mathmode) == -1) { K->u->cbxMathMode->addItem(input.mathmode); klfconfig.UI.customMathModes = QStringList() << klfconfig.UI.customMathModes() << input.mathmode; } return input; } void KLFMainWin::slotEvaluate() { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; // KLFBackend input KLFBackend::klfInput input; u->btnEvaluate->setEnabled(false); // don't allow user to click us while we're not done, and // additionally this gives visual feedback to the user input = d->collectInput(true); // this accounts for both user script configuration and overriding of bbox margins KLFBackend::klfSettings settings = currentSettings(); // **** and GO ! d->output = KLFBackend::getLatexFormula(input, settings); // **** // for 9.08 <= gs <= 9.14 if (d->output.status == KLFERR_GSPOSTPROC_NOOUTLINEFONTS) { QMessageBox mbox(this); mbox.setIcon(QMessageBox::Warning); mbox.setWindowTitle(tr("No Font Outlining")); mbox.setText(tr("Your version of ghostscript does not allow fonts to be outlined.")); mbox.setInformativeText( tr("This means that vector formats may not display well when pasted or dropped into other programs. " "I'll continue now without font outlining. To get font outlining, update or downgrade your " "ghostscript to gs <= 9.07 or gs >= 9.15. To suppress this warning, disable font outlining in " "\"Settings->Advanced->LaTeX & Image\".") ); mbox.addButton(QMessageBox::Ok); mbox.exec(); // re-run without font outlines settings.outlineFonts = false; d->output = KLFBackend::getLatexFormula(input, settings); } if (d->output.status < 0) { QString comment = ""; bool showSettingsPaths = false; if (d->output.status == KLFERR_LATEX_NORUN || d->output.status == KLFERR_DVIPS_NORUN || d->output.status == KLFERR_GSBBOX_NORUN || d->output.status == KLFERR_GSPOSTPROC_NORUN || d->output.status == KLFERR_GSPNG_NORUN || d->output.status == KLFERR_GSPDF_NORUN || d->output.status == KLFERR_GSSVG_NORUN) { comment = "\n"+tr("Are you sure you configured your system paths correctly in the settings dialog ?"); showSettingsPaths = true; } QMessageBox::critical(this, tr("Error"), d->output.errorstr+comment); u->lblOutput->displayClear(); d->slotSetViewControlsEnabled(false); d->slotSetSaveControlsEnabled(false); if (showSettingsPaths) { d->mSettingsDialog->show(); d->mSettingsDialog->showControl(KLFSettings::ExecutablePaths); } } if (d->output.status > 0) { QString s = d->output.errorstr; if (d->output.status == KLFERR_PROGERR_LATEX) { s = KLFProgErr::extractLatexError(d->output.errorstr) + "

" + s; } KLFProgErr::showError(this, s); d->slotSetViewControlsEnabled(false); d->slotSetSaveControlsEnabled(false); } if (d->output.status == 0) { // ALL OK d->evaloutput_uptodate = true; // scale to view size (klfconfig.UI.labelOutputFixedSize) QSize fsize = d->calcPreviewSize(); QImage scimg = d->output.result; if (d->output.result.width() > fsize.width() || d->output.result.height() > fsize.height()) { scimg = d->output.result.scaled(fsize, Qt::KeepAspectRatio, Qt::SmoothTransformation); } QImage tooltipimg = d->output.result; if ( klfconfig.UI.previewTooltipMaxSize != QSize(0, 0) ) { // QSize(0,0) meaning no resize QSize tooltipmaxsize = (QSizeF(klfconfig.UI.previewTooltipMaxSize) * devicePixelRatioF()).toSize(); if ( tooltipimg.width() > tooltipmaxsize.width() || tooltipimg.height() > tooltipmaxsize.height() ) { tooltipimg = d->output.result.scaled(tooltipmaxsize, Qt::KeepAspectRatio, Qt::SmoothTransformation); } } emit evaluateFinished(d->output); u->lblOutput->display(scimg, tooltipimg, true); // u->frmOutput->setEnabled(true); d->slotSetViewControlsEnabled(true); d->slotSetSaveControlsEnabled(true); QImage smallPreview = d->output.result; if (d->output.result.width() < klfconfig.UI.smallPreviewSize().width() && d->output.result.height() < klfconfig.UI.smallPreviewSize().height()) { // OK, keep full sized image } else if (scimg.size() == klfconfig.UI.smallPreviewSize) { // use already-scaled image, don't scale it twice ! smallPreview = scimg; } else { // scale to small-preview size smallPreview = d->output.result.scaled(klfconfig.UI.smallPreviewSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); } KLFLibEntry newentry = KLFLibEntry(input.latex, QDateTime::currentDateTime(), smallPreview, currentStyle()); // check that this is not already the last entry. Perform a query to check this. bool needInsertThisEntry = true; KLFLibResourceEngine::Query query; query.matchCondition = KLFLib::EntryMatchCondition::mkMatchAll(); query.skip = 0; query.limit = 1; query.orderPropId = KLFLibEntry::DateTime; query.orderDirection = Qt::DescendingOrder; query.wantedEntryProperties = QList() << KLFLibEntry::Latex << KLFLibEntry::Style << KLFLibEntry::Category << KLFLibEntry::Tags; KLFLibResourceEngine::QueryResult queryResult(KLFLibResourceEngine::QueryResult::FillRawEntryList); int num = d->mHistoryLibResource->query(d->mHistoryLibResource->defaultSubResource(), query, &queryResult); if (num >= 1) { KLFLibEntry e = queryResult.rawEntryList[0]; if (e.latex() == newentry.latex() && e.category() == newentry.category() && e.tags() == newentry.tags() && e.style() == newentry.style()) needInsertThisEntry = false; } if (needInsertThisEntry) { int eid = d->mHistoryLibResource->insertEntry(newentry); bool result = (eid >= 0); if ( ! result && d->mHistoryLibResource->locked() ) { int r = QMessageBox::warning(this, tr("Warning"), tr("Can't add the item to history library because the history " "resource is locked. Do you want to unlock it?"), QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes); if (r == QMessageBox::Yes) { d->mHistoryLibResource->setLocked(false); result = d->mHistoryLibResource->insertEntry(newentry); // retry inserting entry } } uint fl = d->mHistoryLibResource->supportedFeatureFlags(); if ( ! result && (fl & KLFLibResourceEngine::FeatureSubResources) && (fl & KLFLibResourceEngine::FeatureSubResourceProps) && d->mHistoryLibResource->subResourceProperty(d->mHistoryLibResource->defaultSubResource(), KLFLibResourceEngine::SubResPropLocked).toBool() ) { int r = QMessageBox::warning(this, tr("Warning"), tr("Can't add the item to history library because the history " "sub-resource is locked. Do you want to unlock it?"), QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes); if (r == QMessageBox::Yes) { d->mHistoryLibResource->setSubResourceProperty(d->mHistoryLibResource->defaultSubResource(), KLFLibResourceEngine::SubResPropLocked, false); result = d->mHistoryLibResource->insertEntry(newentry); // retry inserting entry } } if ( ! result && d->mHistoryLibResource->isReadOnly() ) { qWarning("KLFMainWin::slotEvaluate: History resource is READ-ONLY !! Should NOT!"); QMessageBox::critical(this, tr("Error"), tr("Can't add the item to history library because the history " "resource is opened in read-only mode. This should not happen! " "You will need to manually copy and paste your Latex code somewhere " "else to save it."), QMessageBox::Ok, QMessageBox::Ok); } if ( ! result ) { qWarning("KLFMainWin::slotEvaluate: History resource couldn't be written!"); QMessageBox::critical(this, tr("Error"), tr("An error occurred when trying to write the new entry into the " "history resource!" "You will need to manually copy and paste your Latex code somewhere " "else to save it."), QMessageBox::Ok, QMessageBox::Ok); } } } u->btnEvaluate->setEnabled(true); // re-enable our button u->btnEvaluate->setFocus(); } void KLFMainWin::slotClearLatex() { emit inputCleared(); u->txtLatex->clearLatex(); emit userActivity(); } void KLFMainWin::slotClearAll() { emit inputCleared(); slotClearLatex(); loadDefaultStyle(); emit userActivity(); } void KLFMainWin::slotToggleLibrary() { slotLibrary(!d->mLibBrowser->isVisible()); } void KLFMainWin::slotLibrary(bool showlib) { klfDbg("showlib="<mLibBrowser->setVisible(showlib); if (showlib) { // already shown, raise the window d->mLibBrowser->activateWindow(); d->mLibBrowser->raise(); } } void KLFMainWin::slotToggleSymbols() { slotSymbols(!d->mLatexSymbols->isVisible()); } void KLFMainWin::slotSymbols(bool showsymbs) { d->mLatexSymbols->setVisible(showsymbs); d->slotSymbolsButtonRefreshState(showsymbs); d->mLatexSymbols->activateWindow(); d->mLatexSymbols->raise(); } void KLFMainWin::slotExpandOrShrink() { slotExpand(!isExpandedMode()); } void KLFMainWin::slotExpand(bool expanded) { klfDbg("expanded="<cbxMathMode->setEditText(mathmode); } void KLFMainWin::slotSetPreamble(const QString& preamble) { u->txtPreamble->setLatex(preamble); } void KLFMainWin::slotSetUserScript(const QString& userScript) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; if (userScript.isEmpty()) { if (u->cbxUserScript->currentIndex() == 0) return; u->cbxUserScript->setCurrentIndex(0); d->slotUserScriptSet(0); return; } bool isscriptname = !userScript.contains(QString()+KLF_DIR_SEP); QString userscript = userScript; if (!isscriptname) userscript = QFileInfo(userScript).canonicalFilePath(); int k; bool ok = false; for (k = 0; k < u->cbxUserScript->count(); ++k) { QFileInfo ufi(u->cbxUserScript->itemData(k).toString()); if ( (isscriptname && ufi.fileName() == userscript) || (!isscriptname && ufi.canonicalFilePath() == userscript) ) { // found ok = true; u->cbxUserScript->setCurrentIndex(k); d->slotUserScriptSet(k); break; } } if (!ok) { QMessageBox::warning(this, tr("User Script Not Available"), tr("The user script %1 is not available.") .arg(userScript)); klfWarning("Can't find user script "<cbxUserScript->addItem(us.name(), QVariant(userScript)); // k = u->cbxUserScript->count()-1; // u->cbxUserScript->setCurrentIndex(k); // // not called by the slot connected to the combo box (??) // d->slotUserScriptSet(k); } void KLFMainWin::slotShowUserScriptLog() { KLFProgErr::showError(this, KLFUserScriptFilterProcess::getUserScriptLogHtml()); } void KLFMainWin::slotReloadUserScripts() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; QString curUserScript = u->cbxUserScript->itemData(u->cbxUserScript->currentIndex()).toString(); klf_reload_user_scripts(); QStringList userscripts = klf_user_scripts; klfDbg("userscripts: "<cbxUserScript->clear(); u->cbxUserScript->addItem(tr("", "[[no user script]]"), QVariant(QString())); for (int kkl = 0; kkl < userscripts.size(); ++kkl) { KLFUserScriptInfo scriptinfo = KLFUserScriptInfo::forceReloadScriptInfo( userscripts[kkl] ); klfDbg("Considering userscript "<cbxUserScript->addItem(scriptinfo.name(), QVariant(userscripts[kkl])); } } slotSetUserScript(curUserScript); } void KLFMainWin::slotEnsurePreambleCmd(const QString& line) { QTextCursor c = u->txtPreamble->textCursor(); // qDebug("Begin preamble edit: preamble text is %s", qPrintable(u->txtPreamble->latex())); c.beginEditBlock(); c.movePosition(QTextCursor::End); QString preambletext = u->txtPreamble->latex(); if (preambletext.indexOf(line) == -1) { QString addtext = ""; if (preambletext.length() > 0 && preambletext[preambletext.length()-1] != '\n') addtext = "\n"; addtext += line; c.insertText(addtext); preambletext += addtext; } c.endEditBlock(); } void KLFMainWin::slotSetDPI(int DPI) { u->spnDPI->setValue(DPI); } void KLFMainWin::slotSetFgColor(const QColor& fg) { u->colFg->setColor(fg); } void KLFMainWin::slotSetFgColor(const QString& s) { QColor fgcolor; fgcolor.setNamedColor(s); slotSetFgColor(fgcolor); } void KLFMainWin::slotSetBgColor(const QColor& bg) { klfDbg("Setting background color "<colBg->setColor(QColor()); // transparent else u->colBg->setColor(bg); } void KLFMainWin::slotSetBgColor(const QString& s) { QColor bgcolor; if (s == "-") bgcolor.setRgb(255, 255, 255, 0); // white transparent else bgcolor.setNamedColor(s); slotSetBgColor(bgcolor); } void KLFMainWin::slotEvaluateAndSave(const QString& output, const QString& format) { if ( u->txtLatex->latex().isEmpty() ) { qWarning()<output.result.isNull() ) { QMessageBox::critical(this, tr("Error"), tr("There is no image to save.")); } else { KLFBackend::saveOutputToFile(d->output, output, format.trimmed().toUpper()); } } emit userActivity(); } void KLFMainWin::pasteLatexFromClipboard(QClipboard::Mode mode) { QString cliptext = QApplication::clipboard()->text(mode); slotSetLatex(cliptext); // already in slotSetLatex() // emit userActivity(); } QList KLFMainWin::registeredExporters() { return d->pExporterManager->exporterList(); } QList KLFMainWin::registeredDataOpeners() { return d->pDataOpeners; } QList KLFMainWin::mimeExportProfileList() { return d->pMimeExportProfileManager.exportProfileList(); } static QString find_list_agreement(const QStringList& a, const QStringList& b) { // returns the first element in a that is also in b, or a null QString() if there are no // common elements. int i, j; for (i = 0; i < a.size(); ++i) for (j = 0; j < b.size(); ++j) if (a[i] == b[j]) return a[i]; return QString(); } bool KLFMainWin::canOpenFile(const QString& fileName) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; klfDbg("file name="<pDataOpeners.size(); ++k) { if (d->pDataOpeners[k]->canOpenFile(fileName)) { return true; } } klfDbg("cannot open file.") ; return false; } bool KLFMainWin::canOpenData(const QByteArray& data) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; klfDbg("data. length="<pDataOpeners.size(); ++k) { if (d->pDataOpeners[k]->canOpenData(data)) { return true; } } klfDbg("cannot open data.") ; return false; } bool KLFMainWin::canOpenData(const QMimeData *mimeData) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; QStringList formats = mimeData->formats(); klfDbg("mime data. formats="<pDataOpeners.size(); ++k) { mimetype = find_list_agreement(formats, d->pDataOpeners[k]->supportedMimeTypes()); if (!mimetype.isEmpty()) return true; // this opener can open the data } klfDbg("cannot open data: no appropriate opener found.") ; return false; } bool KLFMainWin::openFile(const QString& file) { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; klfDbg("file="<pDataOpeners.size(); ++k) { if (d->pDataOpeners[k]->openFile(file)) { emit fileOpened(file, d->pDataOpeners[k]); return true; } } QMessageBox::critical(this, tr("Error"), tr("Failed to load file %1.").arg(file)); slotClearLatex(); return false; } bool KLFMainWin::openFiles(const QStringList& fileList) { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; klfDbg("file list="<data(mimetype); if (d->pDataOpeners[k]->openData(data, mimetype)) { emit dataOpened(mimetype, data, d->pDataOpeners[k]); return OpenDataOk; } return OpenDataFailed; } } return OpenDataCantHandle; } bool KLFMainWin::openData(const QMimeData *mimeData, bool *openerFound) { int r = openDropData(mimeData); if (r == OpenDataOk) { if (openerFound != NULL) *openerFound = true; return true; } if (r == OpenDataCantHandle) { if (openerFound != NULL) *openerFound = false; return false; } // if (r == OpenDataFailed) { // only remaining case if (openerFound != NULL) *openerFound = true; return false; // } } bool KLFMainWin::openData(const QByteArray& data) { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; klfDbg("data, len="<pDataOpeners.size(); ++k) { if (d->pDataOpeners[k]->openData(data, QString())) { emit dataOpened(QString(), data, d->pDataOpeners[k]); return true; } } klfWarning("failed to open data.") ; slotClearLatex(); return false; } bool KLFMainWin::canOpenDropData(const QMimeData * data) { return canOpenData(data); } bool KLFMainWin::openLibFiles(const QStringList& files, bool showLibrary) { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; int k; bool imported = false; for (k = 0; k < files.size(); ++k) { bool ok = openLibFile(files[k], false); imported = imported || ok; klfDbg("imported file "<mLibBrowser->openResource(url); } klfDbg("subreslist is "<mLibBrowser->openResource(url2); loaded = loaded || thisloaded; } if (showLibrary && loaded) slotLibrary(true); return loaded; } void KLFMainWin::setApplicationLocale(const QString& locale) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; klf_reload_translations(qApp, locale); emit applicationLocaleChanged(locale); } void KLFMainWin::slotSetExportProfile(const QString& exportProfile) { if (klfconfig.ExportData.menuExportProfileAffectsCopy) klfconfig.ExportData.copyExportProfile = exportProfile; if (klfconfig.ExportData.menuExportProfileAffectsDrag) klfconfig.ExportData.dragExportProfile = exportProfile; saveSettings(); } void KLFMainWin::slotDrag() { // abort if we don't have anything to copy/drag. Use btnDrag's enabled status as a witness // for that. (not the best idea, but whatever....) if (!u->btnDrag->isEnabled()) { klfDbg("Nothing to copy.") ; return; } if ( d->output.result.isNull() ) return; void aboutToDragData(); QDrag *drag = new QDrag(this); KLFMimeData *mime = new KLFMimeData( d->pMimeExportProfileManager.findExportProfile(klfconfig.ExportData.dragExportProfile), d->pExporterManager, d->output ); // connect(mime, SIGNAL(droppedData(const QString&)), this, SIGNAL(draggedDataWasDropped(const QString&))); drag->setMimeData(mime); QSize sz = QSize(200, 100); QImage img = d->output.result; if (img.width() > sz.width() || img.height() > sz.height()) img = img.scaled(sz, Qt::KeepAspectRatio, Qt::SmoothTransformation); // imprint the export type on the drag pixmap QString exportProfileText = d->pMimeExportProfileManager.findExportProfile( klfconfig.ExportData.dragExportProfile ).description(); { QPainter painter(&img); QFont smallfont = QFont("Helvetica", 6); smallfont.setPixelSize(11); painter.setFont(smallfont); painter.setRenderHint(QPainter::TextAntialiasing, false); QRect rall = QRect(QPoint(0,0), img.size()); QRect bb = painter.boundingRect(rall, Qt::AlignBottom|Qt::AlignRight, exportProfileText); klfDbg("BB is "<setPixmap(p); drag->setDragCursor(p, Qt::MoveAction); drag->setHotSpot(QPoint(p.width()/2, p.height())); drag->exec(Qt::CopyAction); } void KLFMainWin::slotCopy() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; // abort if we don't have anything to copy. Use btnCopy's enabled status as a witness // for that. (not the best idea, but whatever....) if (!u->btnCopy->isEnabled()) { klfDbg("Nothing to copy.") ; return; } emit aboutToCopyData(); KLFMimeData *mimedata = new KLFMimeData( d->pMimeExportProfileManager.findExportProfile(klfconfig.ExportData.copyExportProfile), d->pExporterManager, d->output ); klfDbg("created mime data object.") ; // On Mac, Qt's clipboard support doesn't allow to query the data later and // gets all data now (that works only for drag & drop) (WHY?!?!?!?!?!?). But // I can't see any other solution... QApplication::clipboard()->setMimeData(mimedata, QClipboard::Clipboard); klfDbg("set MIME data.") ; KLFMimeExportProfile profile = d->pMimeExportProfileManager.findExportProfile( klfconfig.ExportData.copyExportProfile ); d->showExportMsgLabel(tr("Copied as %1").arg(profile.description())); emit copiedData(profile.profileName()); } void KLFMainWin::slotSave(const QString& suggestfname) { // make sure we are allowed to save if (!u->btnSave->isEnabled()) { // we are not allowed to save! klfWarning("There is nothing to save!") ; return; } // notify that we are about to save to file emit aboutToSaveAs(); // application-long persistent selectedfilter static QString selectedfilter; // prepare list of filters & available formats QStringList filterformatlist; QMap formatsByFilterName; QMap exporterByFilterName; int k, j, ll; QList exporters = d->pExporterManager->exporterList(); for (k = 0; k < exporters.size(); ++k) { KLFExporter * exporter = exporters[k]; if (!exporter->isSuitableForFileSave()) { continue; } QStringList xoformats = exporter->supportedFormats(d->output); for (j = 0; j < xoformats.size(); ++j) { QString fmt = xoformats[j]; QStringList exts = exporter->fileNameExtensionsFor(fmt); QString patterns; for (ll = 0; ll < exts.size(); ++ll) { if (ll > 0) { patterns += " "; } patterns += "*." + exts[ll].toLower(); } QString f = QString("%1 (%2)").arg(exporter->titleFor(fmt)).arg(patterns); filterformatlist.push_back(f); formatsByFilterName[f] = fmt; exporterByFilterName[f] = exporter; } } // finally, join all filters together and show the file dialog. QString filterformat = filterformatlist.join(";;"); QString fname, format; QString suggestion = suggestfname; if (suggestion.isEmpty()) { suggestion = klfconfig.UI.lastSaveDir; } if (suggestion.isEmpty()) { QStringList docpaths = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation); if (docpaths.isEmpty()) { suggestion = ""; } else { suggestion = docpaths[0]; } } fname = QFileDialog::getSaveFileName(this, tr("Save Latex Output"), suggestion, filterformat, &selectedfilter); if (fname.isEmpty()) { klfDbg("Aborted by user.") ; return; } klfDbg("Selected filter = " << selectedfilter) ; QFileInfo fi(fname); // save this path as default to suggest next time klfconfig.UI.lastSaveDir = fi.absolutePath(); // selected filter should match to an exporter if ( exporterByFilterName.contains(selectedfilter) ) { // use an external output-saver QString formatname = formatsByFilterName[selectedfilter]; KLFExporter * exporter = exporterByFilterName[selectedfilter]; if (exporter == NULL) { klfWarning("Internal error: exporter is NULL!"); return; } klfDbg( "Saving using exporter `" << exporter->exporterName() << "' with format `" << formatname << "'" ) ; QByteArray data = exporter->getData(formatname, d->output); if (data.isEmpty()) { QMessageBox::critical(this, tr("Error saving file"), tr("Error exporting the data: %1").arg(exporter->errorString())); return; } { QFile fout(fname); bool ok = fout.open(QIODevice::WriteOnly); if (!ok) { QMessageBox::critical(this, tr("Error saving file"), tr("Can't write to file %1: %2").arg(fname).arg(fout.errorString())); return; } fout.write(data); fout.close(); } emit savedToFile(fname, formatname, exporter); return; } klfWarning("Invalid selected filter: " << selectedfilter << "!") ; QMessageBox::critical(this, tr("Error saving file"), tr("Internal error: can't determine save format")); } void KLFMainWin::slotActivateEditor() { raise(); activateWindow(); u->txtLatex->setFocus(); } void KLFMainWin::slotActivateEditorSelectAll() { slotActivateEditor(); u->txtLatex->selectAll(); } void KLFMainWin::slotShowBigPreview() { if ( ! u->btnShowBigPreview->isEnabled() ) return; QString text = tr("

%1

" "This preview can be opened with the F2 key. Hit " "Esc to close.

") .arg(u->lblOutput->bigPreviewText()) .arg(QFontInfo(qApp->font()).pointSize()-1); QWhatsThis::showText(u->btnEvaluate->pos(), text, u->lblOutput); } void KLFMainWinPrivate::slotPresetDPISender() { QAction *a = qobject_cast(sender()); KLF_ASSERT_NOT_NULL(a, "Action sender is NULL!", return ; ) ; K->slotSetDPI(a->data().toInt()); } bool KLFMainWin::isExpandedMode() const { return u->frmDetails->sideWidgetVisible(); } KLFStyle KLFMainWin::currentStyle() const { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; KLFStyle sty; sty.name = QString::null; int idx = u->cbxLatexFont->currentIndex(); if (idx >= 0) { sty.fontname = u->cbxLatexFont->itemData(idx).toString(); } else { sty.fontname = QString(); } sty.fg_color = u->colFg->color().rgb(); QColor bgc = u->colBg->color(); if (bgc.isValid()) sty.bg_color = qRgba(bgc.red(), bgc.green(), bgc.blue(), 255); else sty.bg_color = qRgba(255, 255, 255, 0); sty.mathmode = (u->chkMathMode->isChecked() ? u->cbxMathMode->currentText() : "..."); sty.preamble = u->txtPreamble->latex(); sty.fontsize = u->spnLatexFontSize->value(); if (sty.fontsize < 0.001) sty.fontsize = -1; sty.dpi = u->spnDPI->value(); sty.vectorscale = 1.0; if (u->chkVectorScale->isChecked()) sty.vectorscale = u->spnVectorScale->value() / 100.0; if (u->gbxOverrideMargins->isChecked()) { KLFStyle::BBoxExpand bbox( u->spnMarginTop->valueInRefUnit(), u->spnMarginRight->valueInRefUnit(), u->spnMarginBottom->valueInRefUnit(), u->spnMarginLeft->valueInRefUnit() ); sty.overrideBBoxExpand = bbox; } sty.userScript = QFileInfo(u->cbxUserScript->itemData(u->cbxUserScript->currentIndex()).toString()).fileName(); sty.userScriptInput = d->collectUserScriptInput(); klfDbg("Returning style; bgcol="<spnMarginTop->valueInRefUnit(); settings.rborderoffset = u->spnMarginRight->valueInRefUnit(); settings.bborderoffset = u->spnMarginBottom->valueInRefUnit(); settings.lborderoffset = u->spnMarginLeft->valueInRefUnit(); } klfDbg("settings.execenv = "<output; } KLFBackend::klfInput KLFMainWin::currentInputState() const { // KLFBackend input KLFBackend::klfInput input; if (u->chkVectorScale->isChecked()) input.vectorscale = u->spnVectorScale->value() / 100.0; else input.vectorscale = 1.0; input.latex = u->txtLatex->latex(); klfDbg("latex="<cbxUserScript->itemData(u->cbxUserScript->currentIndex()).toString(); QVariantMap userScriptInput = d->collectUserScriptInput(); for (QVariantMap::const_iterator usparam = userScriptInput.begin(); usparam != userScriptInput.end(); ++usparam) { input.userScriptParam[usparam.key()] = usparam.value().toString(); } if (u->chkMathMode->isChecked()) { input.mathmode = u->cbxMathMode->currentText(); } else { input.mathmode = "..."; } int fsval = u->spnLatexFontSize->value(); if (fsval <= 0) input.fontsize = -1; else input.fontsize = fsval; input.preamble = u->txtPreamble->latex(); if (u->cbxLatexFont->isEnabled()) { int idx = u->cbxLatexFont->currentIndex(); if (idx > 0) { // find corresponding font in list int k; for (k = 0; k < d->pLatexFontDefs.size(); ++k) { if (d->pLatexFontDefs[k].identifier == u->cbxLatexFont->itemData(idx).toString()) { input.preamble += d->pLatexFontDefs[k].latexdefs; break; } } if (k == d->pLatexFontDefs.size()) { klfWarning("Couldn't find font "<cbxLatexFont->currentText()<<" !"); } } } input.fg_color = u->colFg->color().rgb(); QColor bgcolor = u->colBg->color(); if (bgcolor.isValid()) input.bg_color = bgcolor.rgb(); else input.bg_color = qRgba(255, 255, 255, 0); klfDbg("input.bg_color="<spnDPI->value(); return input; } QFont KLFMainWin::txtLatexFont() const { return u->txtLatex->font(); } QFont KLFMainWin::txtPreambleFont() const { return u->txtPreamble->font(); } QString KLFMainWin::currentInputLatex() const { return u->txtLatex->latex(); } void KLFMainWinPrivate::slotLoadStyleAct() { QAction *a = qobject_cast(sender()); if (a) { K->slotLoadStyle(a->data().toInt()); } } void KLFMainWinPrivate::slotDetailsSideWidgetShown(bool shown) { if (K->u->frmDetails->sideWidgetManagerType() == QLatin1String("ShowHide")) { if (shown) K->u->btnExpand->setIcon(QIcon(":/pics/switchshrinked.svg")); else K->u->btnExpand->setIcon(QIcon(":/pics/switchexpanded.svg")); } else if (K->u->frmDetails->sideWidgetManagerType() == QLatin1String("Drawer")) { if (shown) K->u->btnExpand->setIcon(QIcon(":/pics/switchshrinked_drawer.svg")); else K->u->btnExpand->setIcon(QIcon(":/pics/switchexpanded_drawer.svg")); } else { // "Float", or any possible custom side widget type if (shown) K->u->btnExpand->setIcon(QIcon(":/pics/hidetoolwindow.png")); else K->u->btnExpand->setIcon(QIcon(":/pics/showtoolwindow.png")); } } void KLFMainWin::slotLoadStyle(const KLFStyle& style) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; klfDbg("style: "<colFg->setColor(cfg); if (cbg.alpha() < 100) cbg = QColor(); // transparent klfDbg("setting color: "<colBg->setColor(cbg); u->chkMathMode->setChecked(style.mathmode().simplified() != "..."); if (style.mathmode().simplified() != "...") u->cbxMathMode->setEditText(style.mathmode); if (style.fontsize < 0.001) { u->spnLatexFontSize->setValue(0); } else { u->spnLatexFontSize->setValue((int)(style.fontsize + 0.5)); } // to preserve text edit undo/redo, don't use txtPreamble->setText(): slotSetPreamble(style.preamble); u->spnDPI->setValue(style.dpi); u->spnVectorScale->setValue(style.vectorscale * 100.0); u->chkVectorScale->setChecked(fabs(style.vectorscale - 1.0) > 0.00001); int idx; for (idx = 0; idx < u->cbxLatexFont->count(); ++idx) { if (u->cbxLatexFont->itemData(idx).toString() == style.fontname) { u->cbxLatexFont->setCurrentIndex(idx); break; } } if (idx == u->cbxLatexFont->count()) { // didn't find font QMessageBox::warning(this, tr("Can't find font"), tr("Sorry, I don't know about font `%1'.").arg(style.fontname)); } if (style.overrideBBoxExpand().valid()) { u->gbxOverrideMargins->setChecked(true); u->spnMarginTop->setValueInRefUnit(style.overrideBBoxExpand().top); u->spnMarginRight->setValueInRefUnit(style.overrideBBoxExpand().right); u->spnMarginBottom->setValueInRefUnit(style.overrideBBoxExpand().bottom); u->spnMarginLeft->setValueInRefUnit(style.overrideBBoxExpand().left); } else { u->gbxOverrideMargins->setChecked(false); } klfDbg("About to load us="<stkScriptInput->currentWidget(); if (scriptInputWidget != u->wScriptInputEmptyPage) { klfDbg("Setting user script input widgets to corresponding values...") ; QVariantMap data = style.userScriptInput(); // find the input widgets QList inwidgets = scriptInputWidget->findChildren(QRegExp("^INPUT_.*")); Q_FOREACH (QWidget *inw, inwidgets) { QString n = inw->objectName(); KLF_ASSERT_CONDITION(n.startsWith("INPUT_"), "?!? \"found\" child widget "<inherits("KLFLatexEdit")) { userPropName = "plainText"; } else if (inw->inherits("QComboBox") and inw->property("editable").toBool() == false) { // special handling for setting a string in a non-editable combo box, // need to call setCurrentIndex() QString strvalue = value.toString(); QComboBox * comboboxwidget = dynamic_cast(inw); const int idx = comboboxwidget->findText(strvalue); KLF_ASSERT_CONDITION(idx != -1, "Invalid value "<metaObject()->userProperty(); KLF_ASSERT_CONDITION(userProp.isValid(), "user property of widget "<setProperty(userPropName.constData(), value); } } } void KLFMainWin::slotLoadStyle(int n) { if (n < 0 || n >= (int)d->styles.size()) return; // let's not try to load an inexistant style... slotLoadStyle(d->styles[n]); } void KLFMainWin::slotSaveStyle() { KLFStyle sty; QString name = QInputDialog::getText(this, tr("Enter Style Name"), tr("Enter new style name:")); if (name.isEmpty()) { return; } // check to see if style exists already int found_i = -1; for (int kl = 0; found_i == -1 && kl < d->styles.size(); ++kl) { if (d->styles[kl].name().trimmed() == name.trimmed()) { found_i = kl; // style exists already int r = QMessageBox::question(this, tr("Overwrite Style"), tr("Style name already exists. Do you want to overwrite?"), QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel, QMessageBox::No); switch (r) { case QMessageBox::No: slotSaveStyle(); // recurse, ask for new name. return; // and stop this function execution of course! case QMessageBox::Yes: break; // continue normally default: return; // forget everything; "Cancel" } } } sty = currentStyle(); sty.name = name; if (found_i == -1) d->styles.append(sty); else d->styles[found_i] = sty; d->refreshStylePopupMenus(); // auto-save our style list saveStyles(); emit stylesChanged(); } void KLFMainWin::slotSaveStyleAsDefault() { KLFStyle sty; sty = currentStyle(); QString defname = tr("Default", "[[style name]]"); sty.name = defname; // check to see if style exists already (it should) int found_i = -1; for (int kl = 0; found_i == -1 && kl < d->styles.size(); ++kl) { if (d->styles[kl].name().trimmed() == defname.trimmed()) found_i = kl; } if (found_i == -1) d->styles.append(sty); else d->styles[found_i] = sty; d->refreshStylePopupMenus(); // auto-save our style list saveStyles(); emit stylesChanged(); } void KLFMainWin::slotStyleManager() { d->mStyleManager->show(); } void KLFMainWin::slotSettings() { d->mSettingsDialog->show(); } void KLFMainWinPrivate::slotSetViewControlsEnabled(bool enabled) { emit K->userViewControlsActive(enabled); K->u->btnShowBigPreview->setEnabled(enabled); } void KLFMainWinPrivate::slotSetSaveControlsEnabled(bool enabled) { emit K->userSaveControlsActive(enabled); K->u->btnSetExportProfile->setEnabled(enabled); K->u->btnDrag->setEnabled(enabled); K->u->btnCopy->setEnabled(enabled); K->u->btnSave->setEnabled(enabled); } void KLFMainWin::closeEvent(QCloseEvent *event) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; // close side widget and wait for it u->frmDetails->showSideWidget(false); u->frmDetails->sideWidgetManager()->waitForShowHideActionFinished(); if (d->ignore_close_event) { // simple hide, not close hide(); event->ignore(); return; } event->accept(); quit(); } klatexformula-4.1.0/src/klflibbrowser.cpp000644 000765 000024 00000173317 13660527435 021540 0ustar00philippestaff000000 000000 /*************************************************************************** * file klflibbrowser.cpp * This file is part of the KLatexFormula Project. * Copyright (C) 2011 by Philippe Faist * philippe.faist at bluewin.ch * * * 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 of the License, 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., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ /* $Id$ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "klfconfig.h" #include #include "klflibbrowser_p.h" #include "klflibbrowser.h" #include #include "klfliblegacyengine.h" KLFLibBrowser::KLFLibBrowser(QWidget *parent) : QWidget( #if defined(KLF_WS_WIN) || defined(KLF_WS_MAC) 0 /* parent */ #else parent /* 0 */ #endif , #if defined(KLF_WS_MAC) Qt::Dialog /* to forbid windows from tabbing together */ #else Qt::Window #endif ) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; Q_UNUSED(parent) ; u = new Ui::KLFLibBrowser; u->setupUi(this); u->tabResources->setContextMenuPolicy(Qt::CustomContextMenu); KLF_DEBUG_ASSIGN_REF_INSTANCE(u->searchBar, "libbrowser-searchbar") ; u->searchBar->registerShortcuts(this); // set found/not-found colors klfconfig.LibraryBrowser.colorFound.connectQObjectProperty(u->searchBar, "colorFound"); klfconfig.LibraryBrowser.colorNotFound.connectQObjectProperty(u->searchBar, "colorNotFound"); pResourceMenu = new QMenu(u->tabResources); // connect actions connect(u->aRename, SIGNAL(triggered()), this, SLOT(slotResourceRename())); connect(u->aRenameSubRes, SIGNAL(triggered()), this, SLOT(slotResourceRenameSubResource())); connect(u->aProperties, SIGNAL(triggered()), this, SLOT(slotResourceProperties())); connect(u->aNewSubRes, SIGNAL(triggered()), this, SLOT(slotResourceNewSubRes())); connect(u->aDelSubRes, SIGNAL(triggered()), this, SLOT(slotResourceDelSubRes())); connect(u->aSaveTo, SIGNAL(triggered()), this, SLOT(slotResourceSaveTo())); connect(u->aNew, SIGNAL(triggered()), this, SLOT(slotResourceNew())); connect(u->aOpen, SIGNAL(triggered()), this, SLOT(slotResourceOpen())); connect(u->aOpenExampleLibrary, SIGNAL(triggered()), this, SLOT(slotResourceOpenExampleLibrary())); connect(u->aClose, SIGNAL(triggered()), this, SLOT(slotResourceClose())); // and add them to menu pResourceMenu->addAction((new KLFLibBrowserTabMenu(u->tabResources))->menuAction()); pResourceMenu->addSeparator(); pResourceMenu->addAction(u->aRename); pResourceMenu->addAction(u->aRenameSubRes); pResourceMenu->addAction(u->aProperties); pResourceMenu->addSeparator(); pResourceMenu->addAction(u->aViewType); pResourceMenu->addSeparator(); pResourceMenu->addAction(u->aNewSubRes); pResourceMenu->addAction(u->aOpenSubRes); pResourceMenu->addAction(u->aDelSubRes); pResourceMenu->addSeparator(); pResourceMenu->addAction(u->aNew); pResourceMenu->addAction(u->aOpen); pResourceMenu->addAction(u->aOpenExampleLibrary); /// \todo .......... save as copy action ............ // pResourceMenu->addAction(u->aSaveTo); pResourceMenu->addAction(u->aClose); slotRefreshResourceActionsEnabled(); pTabCornerButton = new QPushButton(u->tabResources); pTabCornerButton->setMenu(pResourceMenu); u->tabResources->setCornerWidget(pTabCornerButton); connect(u->tabResources, SIGNAL(currentChanged(int)), this, SLOT(slotTabResourceShown(int))); connect(u->tabResources, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(slotShowTabContextMenu(const QPoint&))); // RESTORE QMenu * restoreMenu = new QMenu(this); connect(u->aRestoreWithStyle, SIGNAL(triggered()), this, SLOT(slotRestoreWithStyle())); connect(u->aRestoreLatexOnly, SIGNAL(triggered()), this, SLOT(slotRestoreLatexOnly())); restoreMenu->addAction(u->aRestoreWithStyle); restoreMenu->addAction(u->aRestoreLatexOnly); u->btnRestore->setMenu(restoreMenu); connect(u->btnRestore, SIGNAL(clicked()), this, SLOT(slotRestoreWithStyle())); connect(u->btnDelete, SIGNAL(clicked()), this, SLOT(slotDeleteSelected())); connect(u->aDelete, SIGNAL(triggered()), u->btnDelete, SLOT(animateClick())); // IMPORT/EXPORT pImportExportMenu = new QMenu(this); pImportExportMenu->addAction(u->aOpenAll); pImportExportMenu->addAction(u->aExport); pImportExportMenu->addAction(u->aExportSelection); u->btnImportExport->setMenu(pImportExportMenu); connect(u->aOpenAll, SIGNAL(triggered()), this, SLOT(slotOpenAll())); connect(u->aExport, SIGNAL(triggered()), this, SLOT(slotExport())); connect(u->aExportSelection, SIGNAL(triggered()), this, SLOT(slotExportSelection())); // CATEGORY/TAGS connect(u->wEntryEditor, SIGNAL(metaInfoChanged(const QMap&)), this, SLOT(slotMetaInfoChanged(const QMap&))); connect(u->wEntryEditor, SIGNAL(restoreStyle(const KLFStyle&)), this, SIGNAL(requestRestoreStyle(const KLFStyle&))); // OPEN / NEW BUTTONS IN WELCOME TAB connect(u->btnOpenRes, SIGNAL(clicked()), this, SLOT(slotResourceOpen())); connect(u->btnCreateRes, SIGNAL(clicked()), this, SLOT(slotResourceNew())); // SHORTCUTS // cut/copy/paste (void)new QShortcut(QKeySequence::Delete, this, SLOT(slotDeleteSelected())); (void)new QShortcut(QKeySequence::Cut, this, SLOT(slotCut())); (void)new QShortcut(QKeySequence::Copy, this, SLOT(slotCopy())); (void)new QShortcut(QKeySequence::Paste, this, SLOT(slotPaste())); retranslateUi(false); // start with no entries selected slotEntriesSelected(QList()); } void KLFLibBrowser::retranslateUi(bool alsoBaseUi) { if (alsoBaseUi) u->retranslateUi(this); u->wEntryEditor->retranslateUi(alsoBaseUi); pResourceMenu->setTitle(tr("Resource Actions", "[[menu title]]")); u->searchBar->setFocusOutText(" "+tr("Hit Ctrl-F, Ctrl-S or / to search within the current resource")); pTabCornerButton->setText(tr("Resource")); } KLFLibBrowser::~KLFLibBrowser() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; int k; for (k = 0; k < pLibViews.size(); ++k) { KLFLibResourceEngine * engine = pLibViews[k]->resourceEngine(); delete pLibViews[k]; delete engine; } delete u; } bool KLFLibBrowser::eventFilter(QObject *obj, QEvent *ev) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; if (obj->property("resourceTitleEditor").toBool() == true) { if (ev->type() == QEvent::FocusOut) { obj->deleteLater(); // if lost focus, cancel... // don't eat event } if (ev->type() == QEvent::KeyPress) { QKeyEvent *ke = (QKeyEvent*)ev; if (ke->key() == Qt::Key_Escape) { obj->deleteLater(); return true; } } } if (ev->type() == QEvent::Hide && obj->property("klf_libbrowser_pdlg_want_hideautodelete").toBool() == true) { // this object is a resource-operation progress dialog that was just hidden klfDbg( ": progress dialog was hidden, deleting." ) ; obj->deleteLater(); return true; // return false; // continue with event handling } return QWidget::eventFilter(obj, ev); } int KLFLibBrowser::currentUrlIndex() { KLFLibBrowserViewContainer *viewc = curView(); if (viewc == NULL) return -1; return pLibViews.indexOf(viewc); } QUrl KLFLibBrowser::currentUrl() { int i = currentUrlIndex(); if (i < 0 || i >= pLibViews.size()) return QUrl(); return pLibViews[i]->url(); } QList KLFLibBrowser::openUrls() const { QList urls; int k; for (k = 0; k < pLibViews.size(); ++k) { urls << pLibViews[k]->url(); } return urls; } KLFLibResourceEngine * KLFLibBrowser::getOpenResource(const QUrl& url) { KLFLibBrowserViewContainer * viewc = findOpenUrl(url); if (viewc == NULL) return NULL; return viewc->resourceEngine(); } KLFAbstractLibView * KLFLibBrowser::getView(const QUrl& url) { KLFLibBrowserViewContainer * viewc = findOpenUrl(url); if (viewc == NULL) return NULL; return viewc->view(); } KLFAbstractLibView * KLFLibBrowser::getView(KLFLibResourceEngine *resource) { KLFLibBrowserViewContainer * viewc = findOpenResource(resource); if (viewc == NULL) return NULL; return viewc->view(); } QVariantMap KLFLibBrowser::saveGuiState() { QVariantMap v; // first save the list of open URLs QList myurllist = openUrls(); QUrl currenturl = currentUrl(); QList urllist; // will hold URL's as QUrl's QList viewstatelist; // will hold variantMap's QList resroleflagslist; // will hold quint32's int k; for (k = 0; k < myurllist.size(); ++k) { KLFLibBrowserViewContainer *viewc = findOpenUrl(myurllist[k]); if (viewc == NULL) { qWarning()<<"Should NOT HAPPEN! viewc is NULL in KLFLibBrowser::saveGuiState()! URL-List=\n" <saveGuiState(); urllist << QVariant::fromValue(myurllist[k]); viewstatelist << QVariant::fromValue(viewState); resroleflagslist << QVariant::fromValue(viewc->resourceRoleFlags()); } v["UrlList"] = QVariant::fromValue(urllist); v["ViewStateList"] = QVariant::fromValue(viewstatelist); v["ResourceRoleFlagsList"] = QVariant::fromValue(resroleflagslist); v["CurrentUrl"] = QVariant::fromValue(currenturl); v["WidgetSize"] = QVariant::fromValue(size()); return v; } void KLFLibBrowser::loadGuiState(const QVariantMap& v, bool openURLs) { QUrl currenturl = v["CurrentUrl"].toUrl(); QList urllist = v["UrlList"].toList(); QList viewstatelist = v["ViewStateList"].toList(); QList resroleflagslist = v["ResourceRoleFlagsList"].toList(); QSize widgetsize = v["WidgetSize"].value(); int k; for (k = 0; k < urllist.size(); ++k) { QUrl url = urllist[k].toUrl(); quint32 flags = resroleflagslist[k].value(); klfDbg( "LibBrowser::loadGuiState: Opening url "<tabResources->setCurrentWidget(curviewc); klfDbg( "Loaded GUI state." ) ; if (widgetsize.width() > 0 && widgetsize.height() > 0) resize(widgetsize); } // static QString KLFLibBrowser::displayTitle(KLFLibResourceEngine *resource) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; KLF_ASSERT_NOT_NULL( resource, "Resource is NULL!", return QString() ) ; QString basestr; if (resource->supportedFeatureFlags() & KLFLibResourceEngine::FeatureSubResources) { QString subresourcetitle = resource->defaultSubResource(); if (resource->supportedFeatureFlags() & KLFLibResourceEngine::FeatureSubResourceProps) subresourcetitle = resource->subResourceProperty(resource->defaultSubResource(), KLFLibResourceEngine::SubResPropTitle).toString(); basestr = QString("%1 - %2").arg(resource->title(), subresourcetitle); } else { basestr = resource->title(); } if (!resource->canModifyData(KLFLibResourceEngine::AllActionsData)) { // basestr = "# "+basestr; // this is confusing } return basestr; } KLFLibBrowserViewContainer * KLFLibBrowser::findOpenUrl(const QUrl& url) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; klfDbg( "\turl is "<resourceEngine() == resource) return pLibViews[k]; return NULL; } KLFLibBrowserViewContainer * KLFLibBrowser::curView() { return qobject_cast(u->tabResources->currentWidget()); } KLFAbstractLibView * KLFLibBrowser::curLibView() { KLFLibBrowserViewContainer *v = curView(); if (v == NULL) return NULL; return v->view(); } KLFLibBrowserViewContainer * KLFLibBrowser::viewForTabIndex(int tab) { return qobject_cast(u->tabResources->widget(tab)); } QList KLFLibBrowser::findByRoleFlags(uint testflags, uint mask) { klfDbg("Looking for flags "< list; int k; for (k = 0; k < pLibViews.size(); ++k) { if ((pLibViews[k]->resourceRoleFlags() & mask) == testflags) { klfDbg("Adding #"<tabResources->setCurrentWidget(openview); updateResourceRoleFlags(openview, resourceRoleFlags); return true; } KLFLibEngineFactory * factory = KLFLibEngineFactory::findFactoryFor(url.scheme()); if ( factory == NULL ) { qWarning()<openResource(url, this); if ( resource == NULL ) { qWarning()<tabResources->setCurrentWidget(openview); updateResourceRoleFlags(openview, resourceRoleFlags); return true; } resource->setParent(this); klfDbgT(": created resource. about to create view container.") ; // now create appropriate view for this resource KLFLibBrowserViewContainer *viewc = new KLFLibBrowserViewContainer(resource, u->tabResources); klfDbgT(": adding tab page....") ; int i = u->tabResources->addTab(viewc, displayTitle(resource)); if ((resourceRoleFlags & OpenNoRaise) == 0) u->tabResources->setCurrentWidget(viewc); u->tabResources ->refreshTabReadOnly(i, !resource->canModifyData(KLFLibResourceEngine::AllActionsData)); pLibViews.append(viewc); setStyleSheet(styleSheet()); updateResourceRoleFlags(viewc, resourceRoleFlags); // get informed about selection changes connect(viewc, SIGNAL(entriesSelected(const KLFLibEntryList& )), this, SLOT(slotEntriesSelected(const KLFLibEntryList& ))); // and of new category suggestions connect(viewc, SIGNAL(moreCategorySuggestions(const QStringList&)), this, SLOT(slotAddCategorySuggestions(const QStringList&))); connect(viewc, SIGNAL(requestRestore(const KLFLibEntry&, uint)), this, SIGNAL(requestRestore(const KLFLibEntry&, uint))); connect(viewc, SIGNAL(requestRestoreStyle(const KLFStyle&)), this, SIGNAL(requestRestoreStyle(const KLFStyle&))); connect(viewc, SIGNAL(requestOpenUrl(const QString&)), this, SLOT(openResource(const QString&))); connect(viewc, SIGNAL(resourceDataChanged(const QList&)), this, SLOT(slotResourceDataChanged(const QList&))); connect(resource, SIGNAL(resourcePropertyChanged(int)), this, SLOT(slotResourcePropertyChanged(int))); connect(resource, SIGNAL(subResourcePropertyChanged(const QString&, int)), this, SLOT(slotSubResourcePropertyChanged(const QString&, int))); connect(resource, SIGNAL(defaultSubResourceChanged(const QString&)), this, SLOT(slotDefaultSubResourceChanged(const QString&))); // progress reporting originating from resource (eg. database operations) connect(resource, SIGNAL(operationStartReportingProgress(KLFProgressReporter *, const QString&)), this, SLOT(slotStartProgress(KLFProgressReporter *, const QString&))); // progress reporting originating from view (eg. model updates) connect(viewc, SIGNAL(viewOperationStartReportingProgress(KLFProgressReporter *, const QString&)), this, SLOT(slotStartProgress(KLFProgressReporter *, const QString&))); // supply a context menu to view connect(viewc, SIGNAL(viewContextMenuRequested(const QPoint&)), this, SLOT(slotShowContextMenu(const QPoint&))); // create a list of view types to attempt to open, in a given priority order QStringList viewtypeident_try; // * the argument to this function viewtypeident_try << viewTypeIdentifier; if ((resource->supportedFeatureFlags() & KLFLibResourceEngine::FeatureSubResources) && (resource->supportedFeatureFlags() & KLFLibResourceEngine::FeatureSubResourceProps)) { // * the sub-resource view type property (if applicable) viewtypeident_try << resource->subResourceProperty(resource->defaultSubResource(), KLFLibResourceEngine::SubResPropViewType).toString(); } // * the resource view type property viewtypeident_try << resource->viewType(); // * the suggested view type for this resource (as given by engine itself) viewtypeident_try << resource->suggestedViewTypeIdentifier(); // * the default view type suggested by the factory viewtypeident_try << KLFLibViewFactory::defaultViewTypeIdentifier(); // * a "default" view type (last resort, hoping it exists!) viewtypeident_try << QLatin1String("default"); klfDbgT(": created resource. about to test view types.") ; klfDbg( "\tView types: "<canCreateLibView(viewtypeident_try[k], resource) ) { klfDbg( "incompatible view type identifier "<url()<<"." ) ; continue; } bool r = viewc->openView(viewtypeident_try[k]); if (!r) { klfDbg( "can't create view! viewtypeident="<view()->wantMoreCategorySuggestions(); // hide welcome page if it's shown if ((i = u->tabResources->indexOf(u->tabWelcome)) != -1) u->tabResources->removeTab(i); klfDbgT(": end of function") ; return true; } bool KLFLibBrowser::openResourceFromGuiState(const QUrl& url, const QVariantMap& guiState) { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; // peek into GUI state to open the correct view QString vti = guiState.value(QLatin1String("CurrentViewTypeIdentifier")).toString(); klfDbg("view-type-identifier is "<loadGuiState(guiState); return true; } bool KLFLibBrowser::closeResource(const QUrl& url) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; KLFLibBrowserViewContainer * w = findOpenUrl(url); if (w == NULL) return false; return slotResourceClose(w); } void KLFLibBrowser::updateResourceRoleFlags(KLFLibBrowserViewContainer *viewc, uint resroleflags) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; KLF_ASSERT_NOT_NULL(viewc, "the viewc parameter is null!", return; ) ; if (resroleflags & NoChangeFlag) return; // only store flags that don't act 'now' resroleflags = resroleflags & ~NowMask; klfDbg("updating flags for resource="<url()<<"; flags after mask=" <resourceRoleFlags(); if (fl & xflag) { // unset it pLibViews[k]->setResourceRoleFlags(fl & ~xflag); } } } } // now we can set the appropriate flags on the requested resource view viewc->setResourceRoleFlags(resroleflags); } void KLFLibBrowser::slotTabResourceShown(int tabIndex) { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; klfDbg( "\t tabIndex="<(u->tabResources->widget(tabIndex)); if (viewc == NULL || tabIndex < 0) { emit resourceTabChanged(QUrl()); return; } // redirect searches to the correct view u->searchBar->setSearchTarget(viewc); klfDbg("setting up view type menu...") ; // set up view type menu appropriately QList actions = viewc->viewTypeActions(); QMenu *viewTypeMenu = u->aViewType->menu(); if (viewTypeMenu == NULL) { viewTypeMenu = new QMenu(this); u->aViewType->setMenu(viewTypeMenu); KLF_DEBUG_WATCH_OBJECT(viewTypeMenu) ; } viewTypeMenu->clear(); int k; for (k = 0; k < actions.size(); ++k) { viewTypeMenu->addAction(actions[k]); } QMenu * openSubResMenu = u->aOpenSubRes->menu(); if (openSubResMenu == NULL) { openSubResMenu = new QMenu(this); u->aOpenSubRes->setMenu(openSubResMenu); KLF_DEBUG_WATCH_OBJECT(openSubResMenu) ; } openSubResMenu->clear(); QList openSubResActions = viewc->openSubResourceActions(); for (k = 0; k < openSubResActions.size(); ++k) { openSubResMenu->addAction(openSubResActions[k]); } if (openSubResActions.size() > 0) u->aOpenSubRes->setEnabled(true); else u->aOpenSubRes->setEnabled(false); // refresh selection-related displays KLFAbstractLibView *view = viewc->view(); if (view != NULL) slotEntriesSelected(view->selectedEntries()); slotRefreshResourceActionsEnabled(); emit resourceTabChanged(viewc->url()); } void KLFLibBrowser::slotShowTabContextMenu(const QPoint& pos) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; int tab = u->tabResources->getTabAtPoint(pos); if (tab != -1) { u->tabResources->setCurrentIndex(tab); } pResourceMenu->popup(u->tabResources->mapToGlobal(pos)); } void KLFLibBrowser::slotResourceRename() { slotResourceRename(false); } void KLFLibBrowser::slotResourceRenameSubResource() { slotResourceRename(true); } void KLFLibBrowser::slotResourceRename(bool renamingSubResource) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; klfDbg("renamingSubResource="<tabResources->currentIndex(); KLFLibBrowserViewContainer * viewc = curView(); if (tab < 0 || viewc == NULL) return; klfDbg( ": Rename! renamingSubResource="<resourceEngine(); if ( ! renamingSubResource && ! res->canModifyProp(KLFLibResourceEngine::PropTitle) ) return; if ( renamingSubResource && ( !(res->supportedFeatureFlags() & KLFLibResourceEngine::FeatureSubResources) || !(res->supportedFeatureFlags() & KLFLibResourceEngine::FeatureSubResourceProps) || !(res->canModifySubResourceProperty(res->defaultSubResource(), KLFLibResourceEngine::SubResPropTitle)) ) ) return; QLineEdit * editor = new QLineEdit(u->tabResources); editor->setGeometry(u->tabResources->getTabRect(tab)); editor->show(); if (!renamingSubResource) editor->setText(res->title()); else editor->setText(res->subResourceProperty(res->defaultSubResource(), KLFLibResourceEngine::SubResPropTitle).toString()); editor->setFocus(); editor->setProperty("tabURL", viewc->url()); editor->setProperty("resourceTitleEditor", true); editor->setProperty("needsBackground", true); editor->setProperty("renamingSubResource", renamingSubResource); editor->setStyleSheet(""); editor->installEventFilter(this); // kill editor if tab changes connect(u->tabResources, SIGNAL(currentChanged(int)), editor, SLOT(deleteLater())); connect(editor, SIGNAL(returnPressed()), this, SLOT(slotResourceRenameFinished())); } void KLFLibBrowser::slotResourceRenameFinished() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; QObject * editor = sender(); if (editor == NULL) { qWarning("KLFLibBrowser::slotResourceRenameFinished: no sender!"); return; } bool isRenamingSubResource = editor->property("renamingSubResource").toBool(); QUrl url = editor->property("tabURL").toUrl(); KLFLibBrowserViewContainer * viewc = findOpenUrl(url); if (viewc == NULL) { qWarning()<resourceEngine(); QString text = editor->property("text").toString(); if (!isRenamingSubResource) res->setTitle(text); else res->setSubResourceProperty(res->defaultSubResource(), KLFLibResourceEngine::SubResPropTitle, QVariant::fromValue(text)); editor->deleteLater(); } bool KLFLibBrowser::slotResourceClose(KLFLibBrowserViewContainer *view, bool force) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; if (view == NULL) view = curView(); if (view == NULL) return false; if (!force && view->resourceRoleFlags() & NoCloseRoleFlag) // sorry, can't close. return false; klfDbg( "Close! resflags="<resourceRoleFlags() ) ; int tabindex = u->tabResources->indexOf(view); if (tabindex < 0) { qWarning("KLFLibBrowser::closeResource(url): can't find view in tab widget?!?\n" "\turl=%s, viewwidget=%p", qPrintable(view->url().toString()), (void*)view); return false; } if (!force && klfconfig.LibraryBrowser.confirmClose) { // ask user for confirmation QMessageBox::StandardButton btn = QMessageBox::question(this, tr("Close Resource"), tr("Do you want to close this resource?"), QMessageBox::Yes|QMessageBox::Cancel, QMessageBox::Yes); if (btn != QMessageBox::Yes) return false; } u->tabResources->removeTab(tabindex); int index = pLibViews.indexOf(view); pLibViews.removeAt(index); // delete view and engine KLFLibResourceEngine *resource = view->resourceEngine(); delete view; delete resource; if (u->tabResources->count() == 0) u->tabResources->addTab(u->tabWelcome, QIcon(":/pics/library.png"), tr("Library Browser")); return true; } void KLFLibBrowser::slotResourceProperties() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; KLFLibBrowserViewContainer *view = curView(); if (view == NULL) { qWarning("KLFLibBrowser::slotResourceProperties: NULL View!"); return; } KLFLibResPropEditorDlg * dialog = new KLFLibResPropEditorDlg(view->resourceEngine(), this); dialog->show(); } bool KLFLibBrowser::slotResourceNewSubRes() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; KLFLibBrowserViewContainer *view = curView(); if (view == NULL) { qWarning("KLFLibBrowser::slotResourceProperties: NULL View!"); return false; } KLFLibResourceEngine *res = view->view()->resourceEngine(); QString name = KLFLibNewSubResDlg::createSubResourceIn(res, this); if (name.isEmpty()) return false; // see remark in comment below QUrl url = res->url(); QUrlQuery urlq(url); urlq.removeAllQueryItems("klfDefaultSubResource"); urlq.addQueryItem("klfDefaultSubResource", name); url.setQuery(urlq); klfDbg( "KLFLibBrowser::slotRes.New.S.Res(): Create sub-resource named "<view(); KLF_ASSERT_NOT_NULL(view , "NULL View in container "<resourceEngine(); KLF_ASSERT_NOT_NULL(res , "NULL resource for view="<supportedFeatureFlags() & KLFLibResourceEngine::FeatureSubResources , "Sub-resources are not supported in resource "<url()<<"!" " Cannot delete sub-resource!", return false; ) ; if (res->subResourceList().size() <= 1) { QMessageBox::warning(this, tr("Error"), tr("You may not delete the last remaining sub-resource of this resource.")); klfDbg("Attempted to delete last remaining sub-resource"<defaultSubResource()<<" of resource " <url()<<". Not allowed.") ; return false; } QString curSubResource = res->defaultSubResource(); QString curSubResTitle = curSubResource; if (res->supportedFeatureFlags() & KLFLibResourceEngine::FeatureSubResourceProps) { QString t = res->subResourceProperty(curSubResource, KLFLibResourceEngine::SubResPropTitle).toString(); if (!t.isEmpty()) curSubResTitle = t; } // remove the current sub-resource: first ask user confirmation QMessageBox::StandardButton btn = QMessageBox::question(this, tr("Delete Sub-Resource", "[[msgbox title]]"), tr("Do you really want to delete the sub-resource %1, " "with all its contents, from resource %2?") .arg(curSubResTitle, displayTitle(res)), QMessageBox::Yes|QMessageBox::Cancel, QMessageBox::Cancel); if (btn != QMessageBox::Yes) return false; // now remove that sub-resource bool result = res->deleteSubResource(curSubResource); if (!result) { // report failure QMessageBox::critical(this, tr("Delete Sub-Resource", "[[msgbox title]]"), tr("Deleting sub-resource failed.")); return false; } // close the corresponding tab. slotResourceClose(viewc, true); return true; } bool KLFLibBrowser::slotResourceOpen() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; QUrl url = KLFLibOpenResourceDlg::queryOpenResource(QUrl(), this); if (url.isEmpty()) return false; bool r = openResource(url); if ( ! r ) { QMessageBox::critical(this, tr("Error"), tr("Failed to open library resource `%1'!") .arg(url.toString())); } return r; } bool KLFLibBrowser::slotResourceOpenExampleLibrary() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; QString importfname = QLatin1String(":/data/defaultlibrary.klf"); QUrl importliburl = QUrl::fromLocalFile(importfname); QString scheme = KLFLibBasicWidgetFactory::guessLocalFileScheme(importfname); if (scheme.isEmpty()) { // assume .klf if not able to guess scheme = "klf+legacy"; } importliburl.setScheme(scheme); QUrlQuery importliburlq(importliburl); importliburlq.addQueryItem("klfReadOnly", "true"); importliburlq.addQueryItem("klfDefaultSubResource", "Archive"); importliburl.setQuery(importliburlq); bool r = openResource(importliburl, NoChangeFlag, "default"); if (! r ) { QMessageBox::critical(this, tr("Error"), tr("Failed to open library resource `%1'!") .arg(importliburl.toString())); } return r; } bool KLFLibBrowser::slotResourceNew() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; KLFLibResourceEngine *resource = KLFLibCreateResourceDlg::createResource(QString(), this, this); if (resource == NULL) return false; return openResource(resource); } bool KLFLibBrowser::slotResourceSaveTo() { return false; // YET TO BE IMPLEMENTED... using the factories to get a save to... widget.. // KLFLibBrowserViewContainer *view = curView(); // if (view == NULL) { // qWarning("KLFLibBrowser::slotResourceProperties: NULL View!"); // return false; // } } void KLFLibBrowser::slotResourceDataChanged(const QList& /*entryIdList*/) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; // KLFLibResourceEngine *resource = qobject_cast(sender()); // if (resource == NULL) { // qWarning("KLFLibBrowser::slotResourceDataChanged: NULL sender or not resource!"); // return; // } KLFLibBrowserViewContainer *viewc = qobject_cast(sender()); if (viewc == NULL) { qWarning()<<"KLFLibBrowser::slotResourceDataChanged: NULL sender or not KLFLibBro.ViewCont.!"; return; } slotRefreshResourceActionsEnabled(); KLFAbstractLibView * view = viewc->view(); if (view == NULL) { qWarning()<<"KLFLibBrowser::slotResourceDataChanged: NULL view !!"; return; } slotEntriesSelected(view->selectedEntries()); } void KLFLibBrowser::slotResourcePropertyChanged(int propId) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; KLFLibResourceEngine *resource = qobject_cast(sender()); if (resource == NULL) { qWarning("KLFLibBrowser::slotResourcePropertyChanged: NULL sender or not resource!"); return; } slotUpdateForResourceProperty(resource, propId); } void KLFLibBrowser::slotUpdateForResourceProperty(KLFLibResourceEngine *resource, int propId) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; klfDbg("res="<tabResources->setTabText(u->tabResources->indexOf(view), displayTitle(resource)); } if (propId == KLFLibResourceEngine::PropLocked) { u->tabResources->refreshTabReadOnly(u->tabResources->indexOf(view), !resource->canModifyData(KLFLibResourceEngine::AllActionsData)); u->wEntryEditor ->setInputEnabled(resource->canModifyData(KLFLibResourceEngine::ChangeData)); u->wEntryEditor->displayEntries(view->view()->selectedEntries()); } } void KLFLibBrowser::slotSubResourcePropertyChanged(const QString& subResource, int propId) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; Q_UNUSED(subResource) ; klfDbg("subResource="<restoreWithStyle(); } void KLFLibBrowser::slotRestoreLatexOnly() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; KLFAbstractLibView * view = curLibView(); if ( view == NULL ) return; view->restoreLatexOnly(); } void KLFLibBrowser::slotDeleteSelected() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; KLFAbstractLibView * view = curLibView(); if ( view == NULL ) return; KLFLibResourceEngine * resource = view->resourceEngine(); if ( !resource->canModifyData(KLFLibResourceEngine::DeleteData) ) return; QList sel = view->selectedEntryIds(); klfDbg("selected "<title()), QMessageBox::Yes|QMessageBox::Cancel, QMessageBox::Cancel); if (res != QMessageBox::Yes) return; // abort action resource->deleteEntries(sel); } void KLFLibBrowser::slotRefreshResourceActionsEnabled() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; bool master = false; bool canrename = false; bool canrenamesubres = false; bool cansaveto = false; bool cannewsubres = false; bool candelsubres = false; uint resrolefl = 0; uint resfeatureflags = 0; KLFLibBrowserViewContainer * view = curView(); if ( view != NULL ) { master = true; KLFLibResourceEngine *res = view->resourceEngine(); canrename = res->canModifyProp(KLFLibResourceEngine::PropTitle); resfeatureflags = res->supportedFeatureFlags(); cansaveto = (resfeatureflags & KLFLibResourceEngine::FeatureSaveTo); resrolefl = view->resourceRoleFlags(); cannewsubres = (resfeatureflags & KLFLibResourceEngine::FeatureSubResources) && (res->canCreateSubResource()); candelsubres = (resfeatureflags & KLFLibResourceEngine::FeatureSubResources) && res->canDeleteSubResource(res->defaultSubResource()) ; canrenamesubres = (resfeatureflags & KLFLibResourceEngine::FeatureSubResources) && (resfeatureflags & KLFLibResourceEngine::FeatureSubResourceProps) && res->canModifySubResourceProperty(res->defaultSubResource(), KLFLibResourceEngine::SubResPropTitle) ; } u->aRename->setEnabled(canrename); u->aRenameSubRes->setEnabled(canrenamesubres); u->aProperties->setEnabled(master); u->aNewSubRes->setEnabled(master && cannewsubres); u->aDelSubRes->setEnabled(master && candelsubres); u->aSaveTo->setEnabled(master && cansaveto); u->aNew->setEnabled(true); u->aOpen->setEnabled(true); u->aClose->setEnabled(master && !(resrolefl & NoCloseRoleFlag)); } void KLFLibBrowser::slotEntriesSelected(const KLFLibEntryList& entries) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; klfDbg( "(): "<= 1) { klfDbg( "Tag of first selected entry="<wEntryEditor ->setInputEnabled(view->resourceEngine()->canModifyData(KLFLibResourceEngine::ChangeData)); } u->wEntryEditor->displayEntries(entries); u->btnDelete->setEnabled(entries.size() > 0); u->aDelete->setEnabled(u->btnDelete->isEnabled()); u->btnRestore->setEnabled(entries.size() == 1); emit libEntriesSelected(entries); } void KLFLibBrowser::slotAddCategorySuggestions(const QStringList& catlist) { klfDbg( "KLFLibBrowser: got category suggestions: "<wEntryEditor->addCategorySuggestions(catlist); } void KLFLibBrowser::slotShowContextMenu(const QPoint& pos) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; KLFAbstractLibView * view = curLibView(); if ( view == NULL ) return; QMenu *menu = new QMenu(view); QAction *a1 = menu->addAction(QIcon(":/pics/restoreall.png"), tr("Restore latex formula and style"), view, SLOT(restoreWithStyle())); QAction *a2 = menu->addAction(QIcon(":/pics/restore.png"), tr("Restore latex formula only"), view, SLOT(restoreLatexOnly())); menu->addSeparator(); // NOTE: the QKeySequences given here are only for display in the context menu. Their functionality // is due to additional QShortcuts declared in the constructor. (!) (reason: these actions are // short-lived, and having global actions would require keeping their enabled status up-to-date // + we want to add view-given context menu actions dynamically) QAction *acut = menu->addAction(QIcon(":/pics/cut.png"), tr("Cut"), this, SLOT(slotCut()), QKeySequence::Cut); QAction *acopy = menu->addAction(QIcon(":/pics/copy.png"), tr("Copy"), this, SLOT(slotCopy()), QKeySequence::Copy); QAction *apaste = menu->addAction(QIcon(":/pics/paste.png"), tr("Paste"), this, SLOT(slotPaste()), QKeySequence::Paste); menu->addSeparator(); QAction *adel = menu->addAction(QIcon(":/pics/delete.png"), tr("Delete from library"), this, SLOT(slotDeleteSelected()), QKeySequence::Delete); menu->addSeparator(); QMenu *copytomenu = new QMenu(menu); QMenu *movetomenu = new QMenu(menu); int k; QAction *acopythere, *amovethere; int n_destinations = 0; for (k = 0; k < pLibViews.size(); ++k) { if (pLibViews[k]->url() == view->url()) // skip this view continue; KLFLibResourceEngine *res = pLibViews[k]->resourceEngine(); QUrl viewurl = pLibViews[k]->url(); n_destinations++; acopythere = copytomenu->addAction(displayTitle(res), this, SLOT(slotCopyToResource())); acopythere->setProperty("resourceViewUrl", viewurl); amovethere = movetomenu->addAction(displayTitle(res), this, SLOT(slotMoveToResource())); amovethere->setProperty("resourceViewUrl", viewurl); if (!res->canModifyData(KLFLibResourceEngine::InsertData)) { acopythere->setEnabled(false); amovethere->setEnabled(false); } } QAction *acopyto = menu->addMenu(copytomenu); acopyto->setText(tr("Copy to")); acopyto->setIcon(QIcon(":/pics/copy.png")); QAction *amoveto = menu->addMenu(movetomenu); amoveto->setText(tr("Move to")); amoveto->setIcon(QIcon(":/pics/move.png")); menu->addSeparator(); menu->addMenu(pResourceMenu); // Needed for when user pops up a menu without selection (ie. short list, free white space under) KLFLibEntryList selected = view->selectedEntries(); bool cancopy = (selected.size() > 0) && n_destinations; bool canre = (selected.size() == 1); bool candel = view->resourceEngine()->canModifyData(KLFLibResourceEngine::DeleteData); bool canpaste = KLFAbstractLibEntryMimeEncoder::canDecodeMimeData(QApplication::clipboard()->mimeData()); a1->setEnabled(canre); a2->setEnabled(canre); adel->setEnabled(candel && selected.size()); acut->setEnabled(cancopy && candel); acopy->setEnabled(cancopy); apaste->setEnabled(canpaste); acopyto->setEnabled(cancopy); amoveto->setEnabled(cancopy && candel); // add view's own actions QList viewActions = view->addContextMenuActions(pos); if (viewActions.size()) menu->addSeparator(); // separate view's menu items from ours for (k = 0; k < viewActions.size(); ++k) { klfDbg( "Added action "<addAction(viewActions[k]); } menu->popup(view->mapToGlobal(pos)); } void KLFLibBrowser::slotMetaInfoChanged(const QMap& props) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; QWidget *w = u->tabResources->currentWidget(); KLFLibBrowserViewContainer *wviewc = qobject_cast(w); if (wviewc == NULL) { qWarning("Current view is not a KLFLibBrowserViewContainer or no current tab widget!"); return; } if (props.isEmpty()) { klfDbg("no changes!"); return; } KLFAbstractLibView * wview = wviewc->view(); if ( wview == NULL ) return; QList selected = wview->selectedEntryIds(); KLFLibResourceEngine *resource = wview->resourceEngine(); QList keys = props.keys(); QList values; int k; for (k = 0; k < keys.size(); ++k) values << props[keys[k]]; bool r = resource->changeEntries(selected, keys, values); if ( ! r ) { QMessageBox::warning(this, tr("Error"), tr("Failed to write meta-information!")); // and refresh display slotEntriesSelected(wview->selectedEntries()); return; } // ensure that exactly the modified items are selected, as view's refresh mechanism does // not garantee to preserve selection wview->selectEntries(selected); // if we categorized/tagged a formula in the history resource, copy it to the archive if the relevant // setting is enabled if (klfconfig.LibraryBrowser.historyTagCopyToArchive && !props.isEmpty()) { KLFLibBrowserViewContainer *vHistory = findSpecialResource(HistoryRoleFlag); KLFLibBrowserViewContainer *vArchive = findSpecialResource(ArchiveRoleFlag); klfDbg("vHistory="<selectedEntries(); if (entryList.isEmpty()) { qWarning()<view(); KLFLibResourceEngine *archiveRes = vArchive->resourceEngine(); if (archiveRes == NULL || archiveView == NULL) { qWarning()< insertedIds = archiveRes->insertEntries(entryList); if (!insertedIds.size() || insertedIds.contains(-1)) { QMessageBox::critical(this, tr("Error"), tr("Error copying the given items to the archive!")); } else { u->tabResources->setCurrentWidget(vArchive); // and select those items in archive that were inserted. archiveView->selectEntries(insertedIds); } } } } } } void KLFLibBrowser::slotCopyToResource() { slotCopyMoveToResource(sender(), false); } void KLFLibBrowser::slotMoveToResource() { slotCopyMoveToResource(sender(), true); } void KLFLibBrowser::slotCopyMoveToResource(QObject *action, bool move) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; QUrl destUrl = action->property("resourceViewUrl").toUrl(); if (destUrl.isEmpty()) { qWarning()<<"KLFLibBrowser::slotCopyMoveToResource(): bad sender property ! sender is a `" <metaObject()->className()<<"'; expected QAction with 'resourceViewUrl' property set."; return; } KLFAbstractLibView *sourceView = curLibView(); if (sourceView == NULL) { qWarning()<<"KLFLibBrowser::slotCopyMoveToResource(): source view is NULL!"; return; } KLFLibBrowserViewContainer *destViewC = findOpenUrl(destUrl); if (destViewC == NULL || destViewC->view() == NULL) { qWarning()<<"KLFLibBrowser::slotCopyMoveToResource(): can't find dest view url for URL="<view(); // now do the copy/move: slotCopyMoveToResource(destView, sourceView, move); } void KLFLibBrowser::slotCopyMoveToResource(KLFAbstractLibView *dest, KLFAbstractLibView *source, bool move) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; QList selectedids = source->selectedEntryIds(); KLFLibEntryList items = source->selectedEntries(); QList inserted = dest->resourceEngine()->insertEntries(items); if ( inserted.isEmpty() || inserted.contains(-1) ) { QString msg = move ? tr("Failed to move the selected items.") : tr("Failed to copy the selected items."); QMessageBox::critical(this, tr("Error"), msg, QMessageBox::Ok, QMessageBox::Ok); return; } if (move) source->resourceEngine()->deleteEntries(selectedids); } void KLFLibBrowser::slotCut() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; KLFAbstractLibView * view = curLibView(); if ( view == NULL ) return; if ( view->selectedEntries().size() == 0 || !view->resourceEngine()->canModifyData(KLFLibResourceEngine::DeleteData) ) return; QList selected = view->selectedEntryIds(); slotCopy(); view->resourceEngine()->deleteEntries(selected); } void KLFLibBrowser::slotCopy() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; // first determine who had widget focus QWidget *focusWidget = QApplication::focusWidget(); if (u->wEntryEditor->isAncestorOf(focusWidget)) { u->wEntryEditor->slotCopy(); return; } // otherwise perform the copy from the visible lib view KLFAbstractLibView * view = curLibView(); if ( view == NULL ) return; if ( view->selectedEntries().size() == 0 ) return; KLFLibEntryList elist = view->selectedEntries(); QVariantMap vprops; vprops["Url"] = view->url(); // originating URL QMimeData *mimeData = KLFAbstractLibEntryMimeEncoder::createMimeData(elist, vprops); QApplication::clipboard()->setMimeData(mimeData); } void KLFLibBrowser::slotPaste() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; KLFAbstractLibView * view = curLibView(); if ( view == NULL ) return; KLFLibEntryList elist; QVariantMap vprops; const QMimeData* mimeData = QApplication::clipboard()->mimeData(); bool result = KLFAbstractLibEntryMimeEncoder::decodeMimeData(mimeData, &elist, &vprops); if (!result) { QMessageBox::critical(this, tr("Error"), tr("The clipboard doesn't contain any appropriate data.")); return; } klfDbg( ": Pasting data! props="< inserted = view->resourceEngine()->insertEntries(elist); if (inserted.isEmpty() || inserted.contains(-1)) { QMessageBox::critical(this, tr("Error"), tr("Error pasting items")); } } void KLFLibBrowser::slotOpenAll() { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; QStringList exportFilterList; QStringList filterlist; QString exportFilter; QList locfiletypes = KLFLibBasicWidgetFactory::localFileTypes(); int k; for (k = 0; k < locfiletypes.size(); ++k) { exportFilterList << locfiletypes[k].filter; filterlist << locfiletypes[k].filepattern; } exportFilterList.prepend(tr("All Known Library Files (%1)").arg(filterlist.join(" "))); exportFilterList << tr("All Files (*)"); exportFilter = exportFilterList.join(";;"); QString selectedFilter; QString dir = klfconfig.LibraryBrowser.lastFileDialogPath; QString fn = QFileDialog::getOpenFileName(this, tr("Open Library File"), dir, exportFilter, &selectedFilter); if (fn.isEmpty()) return; klfconfig.LibraryBrowser.lastFileDialogPath = QFileInfo(fn).absolutePath(); int ifilter = exportFilterList.indexOf(selectedFilter); ifilter--; // index in locfiletypes now QString selectedScheme; if (ifilter >= 0 && ifilter < locfiletypes.size()) { selectedScheme = locfiletypes[ifilter].scheme; } else { selectedScheme = KLFLibBasicWidgetFactory::guessLocalFileScheme(fn); } if (!QFileInfo(fn).isReadable()) { qWarning()< exportUrls; KLFLibResourceEngine *exportRes = KLFLibExportDialog::showExportDialogCreateResource(this, &exportUrls); if (exportRes == NULL) { return false; } exportRes->setTitle(tr("Export %1").arg(QDateTime::currentDateTime() .toString(Qt::DefaultLocaleShortDate))); klfDbg("Export: to resource "<url().toString()<<". Export: "<createSubResource(subres); if (!r) { fail = true; qWarning()<title(); } else { if (res->supportedFeatureFlags() & KLFLibResourceEngine::FeatureSubResourceProps) { title = res->title() + ": " + res->subResourceProperty(usr, KLFLibResourceEngine::SubResPropTitle).toString(); } else { title = res->title() + ": " + usr; } } exportRes->setSubResourceProperty(subres, KLFLibResourceEngine::SubResPropTitle, title); pdlg.setDescriptiveText(tr("Exporting ... %3 (%1/%2)") .arg(k+1).arg(exportUrls.size()).arg(title)); QList elistwid = res->allEntries(usr); /** \bug ....... Add a 'KLFLibEntryList KLFLibResourceEngine::entryList(idList)' * function so that we don't have to manually get rid of ID's ! */ KLFLibEntryList elist; int j; for (j = 0; j < elistwid.size(); ++j) elist << elistwid[j].entry; QList insertedIds = exportRes->insertEntries(subres, elist); if (!insertedIds.size() || insertedIds.contains(-1)) { QMessageBox::critical(this, tr("Error"), tr("Error exporting items!")); } } // remove our dummy sub-resource that was created with the resource // name was set in klflibbrowser_p.h: KLFLibExportDialog::showExportDi...() exportRes->deleteSubResource(QLatin1String("export_xtra")); // important, as it will cause save() to be called on legacy engines, otherwise we will just // have a zombie resource waiting for something delete exportRes; return !fail; } bool KLFLibBrowser::slotExportSelection() { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; // need to fetch selection from current view KLFAbstractLibView *view = curLibView(); if (view == NULL) { qWarning("KLFLibBrowser::slotResourceProperties: NULL View!"); return false; } // select and open target file KLFLibEngineFactory *factory = KLFLibLegacyEngineFactory::findFactoryFor("klf+legacy"); if (factory == NULL) { qWarning()<schemeTitle(QLatin1String("klf+legacy")) + " (*.klf)"; QString path = klfconfig.LibraryBrowser.lastFileDialogPath; QString fileName = QFileDialog::getSaveFileName(this, tr("Export selection to file..."), path, filter); if (fileName.isEmpty()) { klfDbg("Canceled by user."); return false; } if (QFile::exists(fileName)) { // erase it. the file dialog already asked for overwrite confirmation. if ( ! QFile::remove(fileName) ) { QMessageBox::critical(this, tr("Error"), tr("Failed to overwrite file %1").arg(fileName)); qWarning()<selectedEntries(); // create file resource KLFLibWidgetFactory::Parameters param; param["klfScheme"] = QLatin1String("klf+legacy"); param["Filename"] = fileName; param["klfDefaultSubResource"] = tr("Export", "[[export selection default sub-resource name]]"); KLFLibResourceEngine *resource = factory->createResource(QLatin1String("klf+legacy"), param, this); if (resource == NULL) { QMessageBox::critical(this, tr("Error"), tr("Failed to create export file %1!").arg(fileName)); return false; } QList insertedIds = resource->insertEntries(entryList); if (!insertedIds.size() || insertedIds.contains(-1)) { QMessageBox::critical(this, tr("Error"), tr("Error exporting items!")); } // important, as it will cause save() to be called on legacy engines, otherwise we will just // have a zombie resource waiting for something delete resource; return true; } void KLFLibBrowser::slotStartProgress(KLFProgressReporter *progressReporter, const QString& text) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; klfDbg( ": min,max="<min()<<","<max() <<"; text="<startReportingProgress(progressReporter, text); pdlg->setProperty("klf_libbrowser_pdlg_want_hideautodelete", QVariant(true)); pdlg->installEventFilter(this); } bool KLFLibBrowser::event(QEvent *e) { if (e->type() == QEvent::KeyPress) { QKeyEvent *ke = (QKeyEvent*)e; if (ke->key() == Qt::Key_F8 && ke->modifiers() == 0) { hide(); e->accept(); return true; } } return QWidget::event(e); } void KLFLibBrowser::timerEvent(QTimerEvent *event) { QWidget::timerEvent(event); } void KLFLibBrowser::showEvent(QShowEvent *event) { // update some last-minute stuff // like the tab colors (which could have changed upon setting a skin) int k; for (k = 0; k < pLibViews.size(); ++k) { KLFLibBrowserViewContainer *viewc = pLibViews[k]; KLFLibResourceEngine *resource = viewc->resourceEngine(); u->tabResources->refreshTabReadOnly(u->tabResources->indexOf(viewc), !resource->canModifyData(KLFLibResourceEngine::AllActionsData)); } u->tabResources->setFocus(); // and call superclass QWidget::showEvent(event); } klatexformula-4.1.0/src/klfmainwin.h000644 000765 000024 00000033516 13660527435 020471 0ustar00philippestaff000000 000000 /*************************************************************************** * file klfmainwin.h * This file is part of the KLatexFormula Project. * Copyright (C) 2011 by Philippe Faist * philippe.faist at bluewin.ch * * * 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 of the License, 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., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ /* $Id$ */ #ifndef KLFMAINWIN_H #define KLFMAINWIN_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class KLFLibBrowser; class KLFStyleManager; class KLFSettings; class KLFLatexSyntaxHighlighter; class KLFLatexEdit; class KLFCmdIface; class KLFUserScriptSettings; class KLFExporter; class KLFMimeExportProfile; namespace Ui { class KLFMainWin; } class KLFMainWin; /** A helper interface class to open old PNG files, library files or abstract data, to fill in * the main window controls (latex and style), or possibly open a resource into library. * * Instances of subclasses will be invoked when: * - a file is given on command-line, see \ref canOpenFile() and \ref openFile() * - data is pasted or dropped in editor, see \ref supportedMimeTypes(), \ref canOpenData() and * \ref openData() * */ class KLF_EXPORT KLFAbstractDataOpener { public: KLFAbstractDataOpener(KLFMainWin *mainwin) : mMainWin(mainwin) { } virtual ~KLFAbstractDataOpener() { } /** Returns a list of mime-types we can handle */ virtual QStringList supportedMimeTypes() = 0; /** Is supposed to peek into \c file to try to recognize if its format is one which we can open. * The implementation of this function may also rely on the file name's extension. * * If the file is recognized as one this opener can open, then return TRUE, otherwise return FALSE. */ virtual bool canOpenFile(const QString& file) = 0; /** Is supposed to peek into \c data to try to recognize if its format is one which we can open. * No indication is given as to which format \c data is in. If the \c data is recognized as * a format this opener can open, return TRUE, otherwise, return FALSE. */ virtual bool canOpenData(const QByteArray& data) = 0; /** Actually open the file. You may use the mainWin() to perform something useful. * * Note: this function will be called for every file the main window tries to open. Do NOT assume * that the file given here is a file that passed the canOpenFile() function test. (Reason: * calling both canOpenFile() and openFile() may result into resources being loaded twice, which * is not optimal). * * This function should return FALSE if it is not capable of loading the given \c file. */ virtual bool openFile(const QString& file) = 0; /** Actually open the data. You may use the mainWin() to perform something useful. * * \c mimetype is the mime-type of the data. * * Note: the \c mimetype can be empty, in which case the opener should make no assumption * whatsoever as to the data's format, and try to parse data, and return FALSE if it * is not capable of loading the given data. In particular, it should not be assumed * that canOpenData() has already been called and returned true on this data. * * This function should return FALSE if it is not capable of loading the given \c data. */ virtual bool openData(const QByteArray& data, const QString& mimetype) = 0; protected: /** Get a pointer to the main window passed to the constructor. */ KLFMainWin * mainWin() { return mMainWin; } private: KLFMainWin *mMainWin; }; class KLFLatexPreviewThread; class KLFAboutDialog; class KLFWhatsNewDialog; class KLFMainWinPopup; struct KLFMainWinPrivate; /** * KLatexFormula Main Window * \author Philippe Faist <philippe.faist@bluewin.ch> */ class KLF_EXPORT KLFMainWin : public QMainWindow, public KLFDropDataHandler { Q_OBJECT Q_PROPERTY(QString widgetStyle READ widgetStyle WRITE setWidgetStyle) public: KLFMainWin(); virtual ~KLFMainWin(); /** called by main.cpp right after show(), just before entering into event loop. */ void startupFinished(); bool eventFilter(QObject *obj, QEvent *event); bool isExpandedMode() const; KLFStyle currentStyle() const; QFont txtLatexFont() const; QFont txtPreambleFont() const; /** The current configuration of the KLFBackend. Does not account for corrections, eg. overriding * bbox margins. */ KLFBackend::klfSettings backendSettings() const; /** This function accounts for corrections eg. overriding bbox margins. Use backendSettings() to get * the raw backend settings themselves. */ KLFBackend::klfSettings currentSettings() const; void applySettings(const KLFBackend::klfSettings& s); KLFBackend::klfOutput currentKLFBackendOutput() const; KLFBackend::klfInput currentInputState() const; QString currentInputLatex() const; enum altersetting_which { altersetting_LBorderOffset = 100, altersetting_TBorderOffset, altersetting_RBorderOffset, altersetting_BBorderOffset, altersetting_TempDir, altersetting_Latex, altersetting_Dvips, altersetting_Gs, altersetting_Epstopdf, altersetting_OutlineFonts, //!< bool given as an int value altersetting_CalcEpsBoundingBox, //!< bool given as an int value altersetting_WantSVG, //!< bool given as an int value altersetting_WantPDF //!< bool given as an int value }; KLFLibBrowser * libBrowserWidget(); KLFLatexSymbols * latexSymbolsWidget(); KLFStyleManager * styleManagerWidget(); KLFSettings * settingsDialog(); QMenu * styleMenu(); KLFLatexEdit *latexEdit(); KLFLatexSyntaxHighlighter * syntaxHighlighter(); KLFLatexSyntaxHighlighter * preambleSyntaxHighlighter(); KLFConfig * klfConfig(); QString widgetStyle() const; void registerHelpLinkAction(const QString& path, QObject *object, const char * member, bool wantUrlParam); void registerExporter(KLFExporter *exporter); void unregisterExporter(KLFExporter *exporter); void registerDataOpener(KLFAbstractDataOpener *dataopener); void unregisterDataOpener(KLFAbstractDataOpener *dataopener); bool canOpenFile(const QString& fileName); bool canOpenData(const QByteArray& data); bool canOpenData(const QMimeData *mimeData); QList registeredExporters(); QList registeredDataOpeners(); QList mimeExportProfileList(); //! Reimplemented from KLFDropDataHandler bool canOpenDropData(const QMimeData * data); // bool saveOutputToFile(const KLFBackend::klfOutput& output, const QString& fname, // const QString& exporterName); bool isApplicationVisible() const; signals: void evaluateFinished(const KLFBackend::klfOutput& output); void previewAvailable(const QImage& preview, const QImage& largePreview); void previewRealTimeError(const QString& errmsg, int errcode); // dialogs (e.g. stylemanager) should connect to this in case styles change unexpectedly void stylesChanged(); void applicationLocaleChanged(const QString& newLocale); void klfConfigChanged(); /** Emitted when view controls (eg. large preview button) are enabled/disabled */ void userViewControlsActive(bool active); /** Emitted when save controls (eg. save button) are enabled/disabled */ void userSaveControlsActive(bool active); void userActivity(); void userInputChanged(); /** emitted whenever the formula currently being edited is replaced by something else, like a restored * formula from the library or a blank input from clear button, etc. */ void inputCleared(); void aboutToCopyData(); void copiedData(const QString& profile); void aboutToDragData(); // void draggedDataWasDropped(const QString& mimeType); void fileOpened(const QString& fname, KLFAbstractDataOpener * usingDataOpener); void dataOpened(const QString& mimetype, const QByteArray& data, KLFAbstractDataOpener * usingDataOpener); void aboutToSaveAs(); /** \note if \c usingExporter is NULL, the built-in klfbackend saver was used */ void savedToFile(const QString& fileName, const QString& format, KLFExporter * usingExporter); public slots: void slotEvaluate(); void slotClear() { slotClearLatex(); } void slotClearLatex(); void slotClearAll(); void slotLibrary(bool showlib); void slotToggleLibrary(); void slotSymbols(bool showsymbs = true); void slotToggleSymbols(); void slotExpandOrShrink(); void slotExpand(bool expanded = true); void slotSetLatex(const QString& latex); void slotSetMathMode(const QString& mathmode); void slotSetPreamble(const QString& preamble); void slotSetUserScript(const QString& userScript); void slotShowUserScriptLog(); void slotReloadUserScripts(); /** If \c line is already in the preamble, then does nothing. Otherwise appends * \c line to the preamble text. */ void slotEnsurePreambleCmd(const QString& line); void slotSetDPI(int DPI); void slotSetFgColor(const QColor& fgcolor); void slotSetFgColor(const QString& fgcolor); void slotSetBgColor(const QColor& bgcolor); void slotSetBgColor(const QString& bgcolor); // will actually save only if output non empty. void slotEvaluateAndSave(const QString& output, const QString& format); void pasteLatexFromClipboard(QClipboard::Mode mode = QClipboard::Clipboard); bool openFile(const QString& file); bool openFiles(const QStringList& fileList); bool openData(const QMimeData *mimeData, bool *openerFound = NULL); //! Reimplemented from KLFDropDataHandler int openDropData(const QMimeData *mimeData); bool openData(const QByteArray& data); bool openLibFiles(const QStringList& files, bool showLibrary = true); bool openLibFile(const QString& file, bool showLibrary = true); bool executeURLCommandsFromFile(const QString& fname); bool loadDefaultStyle(); bool loadNamedStyle(const QString& sty); void slotDrag(); void slotCopy(); void slotSave(const QString& suggestedFname = QString::null); void slotSetExportProfile(const QString& exportProfile); void slotActivateEditor(); void slotActivateEditorSelectAll(); void slotShowBigPreview(); void slotLoadStyle(int stylenum); void slotLoadStyle(const KLFStyle& style); void slotSaveStyle(); void slotSaveStyleAsDefault(); void slotStyleManager(); void slotSettings(); void loadStyles(); void loadLibrary(); // load library stuff void loadLibrarySavedState(); void saveStyles(); void restoreFromLibrary(const KLFLibEntry& entry, uint restoreflags); void insertSymbol(const KLFLatexSymbol& symbol); /** Inserts a delimiter \c delim, and brings the cursor \c charsBack characters * back. Eg. you can insert \c "\mathrm{}" and bring the cursor 1 space back. */ void insertDelimiter(const QString& delim, int charsBack = 1); void saveSettings(); void saveLibraryState(); void loadSettings(); void addWhatsNewText(const QString& htmlSnipplet); void showAbout(); void showWhatsNew(); void showSettingsHelpLinkAction(const QUrl& link); void helpLinkAction(const QUrl& link); void setWidgetStyle(const QString& qtstyle); void setMacBrushedMetalLook(bool metallook); void refreshAllWindowStyleSheets(); void setTxtLatexFont(const QFont& f); void setTxtPreambleFont(const QFont& f); void setApplicationLocale(const QString& locale); void retranslateUi(bool alsoBaseUi = true); /** This function allows to temporarily modify a given setting with a new value. KLatexFormula * will NOT remember the new setting in later executions. * * Used eg. for command-line mode. * * Note you have to use the correct function for each setting, if the setting requires an int * use this function, if it requires a string use alterSetting(altersetting_which, QString). */ void alterSetting(int altersettingWhich, int ivalue); /** See alterSetting(altersetting_which, int) */ void alterSetting(int altersettingWhich, QString svalue); void setQuitOnClose(bool quitOnClose); void hideApplication(); void quit(); protected: bool event(QEvent *e); bool nativeEvent(const QByteArray & eventType, void * message, long * result); void childEvent(QChildEvent *e); void closeEvent(QCloseEvent *e); void hideEvent(QHideEvent *e); void showEvent(QShowEvent *e); void timerEvent(QTimerEvent *e); private: KLF_DECLARE_PRIVATE(KLFMainWin) ; Ui::KLFMainWin *u; private slots: void slotCycleParenModifiers(bool forward = true); void slotCycleParenModifiersBack() { slotCycleParenModifiers(false); } void slotCycleParenTypes(bool forward = true); void slotCycleParenTypesBack() { slotCycleParenTypes(false); } }; #endif klatexformula-4.1.0/src/klfcmdiface.h000644 000765 000024 00000004515 13660527435 020557 0ustar00philippestaff000000 000000 /*************************************************************************** * file klfcmdiface.h * This file is part of the KLatexFormula Project. * Copyright (C) 2011 by Philippe Faist * philippe.faist at bluewin.ch * * * 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 of the License, 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., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ /* $Id$ */ #ifndef KLF_CMDIFACE_H_ #define KLF_CMDIFACE_H_ #include #include #include #include struct KLFCmdIfacePrivate; class KLF_EXPORT KLFCmdIface : public QObject { Q_OBJECT public: struct Command { Command(const QString& o = QString(), const QString& s = QString(), const QVariantList& a = QVariantList()) : object(o), slot(s), args(a) { } Command(const Command& copy) : object(copy.object), slot(copy.slot), args(copy.args) { } QString object; QString slot; QVariantList args; }; KLFCmdIface(QObject *parent = NULL); ~KLFCmdIface(); void registerObject(QObject *target, const QString& objectHostName); static QUrl encodeCommand(const Command& command); static Command decodeCommand(const QUrl& url); public slots: void executeCommand(const QUrl& url); private: KLF_DECLARE_PRIVATE(KLFCmdIface) ; }; #endif klatexformula-4.1.0/src/klfliblegacyengine.cpp000644 000765 000024 00000103432 13660527435 022476 0ustar00philippestaff000000 000000 /*************************************************************************** * file klfliblegacyengine.cpp * This file is part of the KLatexFormula Project. * Copyright (C) 2011 by Philippe Faist * philippe.faist at bluewin.ch * * * 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 of the License, 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., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ /* $Id$ */ #include #include #include #include #include #include #include #include #include #include // qApp #include "klflib.h" #include "klflibview.h" #include "klfconfig.h" #include #include "klfliblegacyengine.h" #include "klfliblegacyengine_p.h" /** \page libfmt_legacy Library Export Format Specification * * \todo (needs doc..............) * * - refer to klfliblegacyengine.cpp * - very basically: format is * \code * stream << QString("KLATEXFORMULA_LIBRARY_EXPORT") << (qint16)2 << (qint16)1 * << resources << library; * // additionally, save our meta-data at the end (this will be ignored by previous versions * // of KLF) * stream << metadata; * \endcode * - resources is a KLFLegacyData::KLFLibraryResourceList * - library is a KLFLegacyData::KLFLibrary * - all current versions of KLF write the version '2.1', it's the compatiblity version that is * written, not the true version of the creating program. * - since 3.2, additional metadata (a QVariantMap) is appended at end of stream, will silently * be ignored by previous versions of klf. Klf 3.2 does not itself make use of the meta-data, * but it loads and saves it for compatibility with future versions will (as planned) will * support resource and sub-resource properties, stored in this data structure. */ quint32 KLFLegacyData::KLFLibraryItem::MaxId = 1; // debug QDebug& operator<<(QDebug& s, const KLFLegacyData::KLFLibraryItem& item) { return s << "KLFLegacyData::KLFLibraryItem(id="<> operator imports in a compatible way to KLF 2.0 KLF_EXPORT QDataStream& operator>>(QDataStream& stream, KLFLegacyData::KLFLibraryItem& item) { stream >> item.id >> item.datetime >> item.latex >> item.preview >> item.style; item.category = KLFLibEntry::categoryFromLatex(item.latex); item.tags = KLFLibEntry::tagsFromLatex(item.latex); return stream; } KLF_EXPORT QDataStream& operator<<(QDataStream& stream, const KLFLegacyData::KLFLibraryResource& item) { return stream << item.id << item.name; } KLF_EXPORT QDataStream& operator>>(QDataStream& stream, KLFLegacyData::KLFLibraryResource& item) { return stream >> item.id >> item.name; } KLF_EXPORT bool operator==(const KLFLegacyData::KLFLibraryItem& a, const KLFLegacyData::KLFLibraryItem& b) { return // a.id == b.id && // don't compare IDs since they should be different. // a.datetime == b.datetime && // same for datetime a.latex == b.latex && /* the following is unnecessary since category/tags information is contained in .latex a.category == b.category && a.tags == b.tags && */ // a.preview == b.preview && // don't compare preview: it's unnecessary and overkill a.style == b.style; } KLF_EXPORT bool operator<(const KLFLegacyData::KLFLibraryResource a, const KLFLegacyData::KLFLibraryResource b) { return a.id < b.id; } KLF_EXPORT bool operator==(const KLFLegacyData::KLFLibraryResource a, const KLFLegacyData::KLFLibraryResource b) { return a.id == b.id; } KLF_EXPORT bool resources_equal_for_import(const KLFLegacyData::KLFLibraryResource a, const KLFLegacyData::KLFLibraryResource b) { return a.name == b.name; } // ------------------------------------------- // KLFLibLegacyFileDataPrivate // static QMap KLFLibLegacyFileDataPrivate::staticFileDataObjects; bool KLFLibLegacyFileDataPrivate::load(const QString& fnm) { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME+"("+fnm+")") ; QString fname = (!fnm.isEmpty() ? fnm : filename); flagForceReadOnly = false; klfDbg("loading from file "<> s1; if (s1 == "KLATEXFORMULA_LIBRARY_EXPORT") { // opening an export file (*.klf) legacyLibType = ExportLibraryType; qint16 vmaj, vmin; stream >> vmaj >> vmin; // these are not needed, format has not changed in .klf export files. stream >> resources >> library; if (!stream.atEnd() && stream.status() == QDataStream::Ok) stream >> metadata; } else if (s1 == "KLATEXFORMULA_LIBRARY") { // opening a library file (~/.klatexformula/library) legacyLibType = LocalLibraryType; qint16 vmaj, vmin; stream >> vmaj >> vmin; if (vmaj <= 2) { stream.setVersion(QDataStream::Qt_3_3); } else { qint16 version; stream >> version; stream.setVersion(version); } quint32 lib_max_id; stream >> lib_max_id; // will not be used... // now read the library itself. stream >> resources >> library; // the meta-data cannot have been written by KLF 3.0--3.1 but we may possibly already have // written to this file with klf 3.2 if (!stream.atEnd() && stream.status() == QDataStream::Ok) stream >> metadata; } else if (s1 == "KLATEXFORMULA_HISTORY") { // opening a post-2.0, pre-2.1 "history" file (no "library" yet) legacyLibType = LocalHistoryType; qint16 vmaj, vmin; stream >> vmaj >> vmin; KLFLegacyData::KLFLibraryList history; quint32 lib_max_id; stream >> lib_max_id >> history; resources = KLFLegacyData::KLFLibraryResourceList(); KLFLegacyData::KLFLibraryResource historyresource; historyresource.id = KLFLegacyData::LibResource_History; historyresource.name = tr("History"); resources.append(historyresource); library = KLFLegacyData::KLFLibrary(); library[historyresource] = history; } else { qWarning("Error: Library file `%s' is invalid library file or corrupt!", qPrintable(fname)); flagForceReadOnly = true; return false; } // update KLFLibraryItem::MaxId int k; for (k = 0; k < resources.size(); ++k) { KLFLegacyData::KLFLibraryList ll = library[resources[k]]; int j; for (j = 0; j < ll.size(); ++j) { if (ll[j].id >= KLFLegacyData::KLFLibraryItem::MaxId) KLFLegacyData::KLFLibraryItem::MaxId = ll[j].id+1; } } haschanges = false; return true; } bool KLFLibLegacyFileDataPrivate::save(const QString& fnm) { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME+"('"+fnm+"')") ; if (flagForceReadOnly) { klfWarning("attempt to save a forced-read-only file! fnm="< 1) { qWarning("%s: Saving an old \"history\" resource. Only one resource can be saved, " "it will be the first: %s", KLF_FUNC_NAME, qPrintable(resources[0].name)); QMessageBox::warning(NULL, tr("Warning"), tr("Saving an old \"history\" resource. Only one resource can be saved, " "it will be the first: %1").arg(resources[0].name)); } // find history resource in our stream << QString("KLATEXFORMULA_HISTORY") << (qint16)2 << (qint16)0 << (quint32)KLFLegacyData::KLFLibraryItem::MaxId << liblist; break; } case LocalLibraryType: { stream << QString("KLATEXFORMULA_LIBRARY") << (qint16)2 << (qint16)1; // don't save explicitely QDataStream version: we're writing KLF 2.1-compatible; // version explicitely saved only since KLF >= 3.x. stream << (quint32)KLFLegacyData::KLFLibraryItem::MaxId << resources << library; // additionally, save our meta-data at the end (this will be ignored by previous versions // of KLF) stream << metadata; break; } case ExportLibraryType: default: if (llt != ExportLibraryType) { qWarning("%s: bad library type %d! Falling back to '.klf'-library-export type", KLF_FUNC_NAME, llt); } stream << QString("KLATEXFORMULA_LIBRARY_EXPORT") << (qint16)2 << (qint16)1 << resources << library; // additionally, save our meta-data at the end (this will be ignored by versions of KLF which // don't know about metadata...) stream << metadata; klfDbg("saved export-library type. resource count: "<translate("KLFMainWin", "History")) || ! QString::compare(resname, "History", Qt::CaseInsensitive) || ! QString::compare(resname, qApp->translate("KLFMainWin", "History"), Qt::CaseInsensitive) ) return KLFLegacyData::LibResource_History; if ( ! QString::localeAwareCompare(resname, "Archive") || ! QString::localeAwareCompare(resname, qApp->translate("KLFMainWin", "Archive")) || ! QString::compare(resname, "Archive", Qt::CaseInsensitive) || ! QString::compare(resname, qApp->translate("KLFMainWin", "Archive"), Qt::CaseInsensitive) ) return KLFLegacyData::LibResource_Archive; return defaultId; } int KLFLibLegacyFileDataPrivate::findResourceName(const QString& resname) { int k; for (k = 0; k < resources.size() && resources[k].name != resname; ++k) ; return k < resources.size() ? k : -1; } // ------------------------------------------- // static KLFLibLegacyEngine * KLFLibLegacyEngine::openUrl(const QUrl& url, QObject *parent) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; QString fname = klfUrlLocalFilePath(url); if (fname.isEmpty()) { klfDbgSt("Requested empty fname.") ; return NULL; } if ( ! QFileInfo(fname).isReadable() ) { qWarning("%s: file %s does not exist!", KLF_FUNC_NAME, qPrintable(fname)); return NULL; } if (url.scheme() != "klf+legacy") { qWarning("KLFLibLegacyEngine::openUrl(): unsupported scheme %s!", qPrintable(url.scheme())); return NULL; } QString legresname; QUrlQuery urlq(url); if (urlq.hasQueryItem("klfDefaultSubResource")) { legresname = urlq.queryItemValue("klfDefaultSubResource"); } return new KLFLibLegacyEngine(fname, legresname, url, parent); } // static KLFLibLegacyEngine * KLFLibLegacyEngine::createDotKLF(const QString& fname, QString legacyResourceName, QObject *parent) { QString fileName = KLFLibLegacyFileDataPrivate::canonicalFilePath(fname); QString lrname = legacyResourceName; if (QFile::exists(fileName)) { klfWarning("File "<legacyLibType = KLFLibLegacyFileDataPrivate::ExportLibraryType; KLFLegacyData::KLFLibraryResource res = { KLFLegacyData::LibResourceUSERMIN, legacyResourceName }; dd->resources << res; dd->library[res] = KLFLegacyData::KLFLibraryList(); // this will force a save dd->flagForceReadOnly = false; dd->haschanges = 1; delete dd; dd = NULL; QUrl url = QUrl::fromLocalFile(fileName); url.setScheme("klf+legacy"); if (lrname.isEmpty()) lrname = tr("Default Resource"); // default name...? QUrlQuery urlq(url); urlq.addQueryItem("klfDefaultSubResource", lrname); url.setQuery(urlq); klfDbgSt("fileName="<ref(); connect(d, SIGNAL(resourcePropertyChanged(int)), this, SLOT(updateResourceProperty(int))); updateResourceProperty(-1); // add at least one resource (baptized resname) if the library is empty if (d->resources.isEmpty()) { // create a resource KLFLegacyData::KLFLibraryResource res; res.name = resname; res.id = d->getReservedResourceId(resname, KLFLegacyData::LibResourceUSERMAX - 1); d->resources << res; // and initialize pLibrary to contain this one empty resource. d->library.clear(); d->library[res] = KLFLegacyData::KLFLibraryList(); d->haschanges = true; } setReadOnly(isReadOnly() || d->flagForceReadOnly); klfDbg("Opened KLFLibLegacyEngine resource `"<deref() ) { klfDbg("last reference to the private liblegacyenginedataprivate object d="<resources<<"\nlibrary:\n"<library) ; if (d->haschanges) d->save(); delete d; } } uint KLFLibLegacyEngine::compareUrlTo(const QUrl& other, uint interestFlags) const { // we can only test for these flags (see doc for KLFLibResourceEngine::compareUrlTo()) interestFlags = interestFlags & (KlfUrlCompareBaseEqual); return klfUrlCompare(url(), other, interestFlags); } bool KLFLibLegacyEngine::canModifyData(const QString& subResource, ModifyType modifytype) const { if ( ! KLFLibResourceEngine::canModifyData(subResource, modifytype) ) { klfDbg("base cannot modify resource engine...") ; return false; } KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return false ) ; #ifndef KLF_WS_WIN // seems like windows doesn't like to test directories to be writable ...? if ( QFile::exists(d->fileName()) // depending on whether the file itself exists, check if ? ! QFileInfo(d->fileName()).isWritable() // file itself writable : ! QFileInfo(QFileInfo(d->fileName()).absolutePath()).isWritable() ) { // or containing dir writable return false; } #endif return true; } bool KLFLibLegacyEngine::canModifyProp(int propid) const { // all resource properties are stored in QVariantMap return KLFLibResourceEngine::canModifyProp(propid); } bool KLFLibLegacyEngine::canRegisterProperty(const QString& /*propName*/) const { // all resource properties are stored in QVariantMap return canModifyProp(-1); } KLFLibEntry KLFLibLegacyEngine::entry(const QString& resource, entryId id) { KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return KLFLibEntry() ) ; int index = d->findResourceName(resource); if (index < 0) return KLFLibEntry(); KLFLegacyData::KLFLibraryList ll = d->library[d->resources[index]]; // find entry with id 'id' int k; for (k = 0; k < ll.size() && ll[k].id != (quint32)id; ++k) ; if (k == ll.size()) { return KLFLibEntry(); } return d->toLibEntry(ll[k]); } QList /* */ KLFLibLegacyEngine::allEntries(const QString& resource, const QList& /*wantedEntryProperties*/) { KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return QList() ) ; int rindex = d->findResourceName(resource); if (rindex < 0) return QList(); QList entryList; KLFLegacyData::KLFLibraryList ll = d->library[d->resources[rindex]]; int k; for (k = 0; k < ll.size(); ++k) { KLFLibEntryWithId e; e.entry = d->toLibEntry(ll[k]); e.id = ll[k].id; entryList << e; } return entryList; } QStringList KLFLibLegacyEngine::subResourceList() const { KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return QStringList() ) ; QStringList list; int k; for (k = 0; k < d->resources.size(); ++k) list << d->resources[k].name; return list; } bool KLFLibLegacyEngine::canCreateSubResource() const { // canModifyData is not sensitive to these arguments... return canModifyData(QString(), ChangeData); } bool KLFLibLegacyEngine::canRenameSubResource(const QString& subResource) const { return canModifyData(subResource, ChangeData); } bool KLFLibLegacyEngine::canDeleteSubResource(const QString& subResource) const { return subResource.length() && hasSubResource(subResource) && canModifyData(subResource, DeleteData) && subResourceList().size() > 1; } bool KLFLibLegacyEngine::createSubResource(const QString& subResource, const QString& /*subResourceTitle*/) { KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return false ) ; quint32 newId = KLFLegacyData::LibResourceUSERMIN; bool ok = true; int k; while (!ok && newId <= KLFLegacyData::LibResourceUSERMAX) { for (k = 0; k < d->resources.size() && d->resources[k].id != newId; ++k) ; if (k == d->resources.size()) ok = true; ++newId; } if (newId == KLFLegacyData::LibResourceUSERMAX) { qWarning()<getReservedResourceId(subResource, newId); d->resources.push_back(res); d->library[res] = KLFLegacyData::KLFLibraryList(); d->haschanges = true; emit subResourceCreated(subResource); return true; } bool KLFLibLegacyEngine::renameSubResource(const QString& subResource, const QString& subResourceNewName) { KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return false ) ; int rindex = d->findResourceName(subResource); if (rindex < 0) { qWarning()<resources[rindex]; // remove from library lists, keep the list KLFLegacyData::KLFLibraryList liblist = d->library.take(resref); // modify the resource data as requested resref.name = subResourceNewName; // see if the name we gave this resource is a 'reserved' name, eg. "History", or "Archive", that // have specific resource IDs. int possibleNewId = d->getReservedResourceId(subResource, -1); if (possibleNewId != -1) resref.id = possibleNewId; // re-insert into library list d->library[resref] = liblist; emit subResourceRenamed(subResource, subResourceNewName); return true; } bool KLFLibLegacyEngine::deleteSubResource(const QString& subResource) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; klfDbg("sub-resource: "<findResourceName(subResource); if (rindex < 0) { qWarning()<resources.takeAt(rindex); // remove from library lists, keep the list d->library.remove(res); emit subResourceDeleted(subResource); return true; } bool KLFLibLegacyEngine::save() { klfDbg( "() our url="<save(); } void KLFLibLegacyEngine::setAutoSaveInterval(int intervalms) { d->autoSaveTimer->stop(); if (intervalms > 0) { d->autoSaveTimer->setInterval(intervalms); d->autoSaveTimer->start(); } } QList KLFLibLegacyEngine::insertEntries(const QString& subResource, const KLFLibEntryList& entrylist) { klfDbg("subResource="<() ) ; if ( entrylist.size() == 0 ) return QList(); if (!canModifyData(subResource, InsertData)) { klfDbg("cannot modify data.") ; return QList(); } int index = d->findResourceName(subResource); if (index < 0) { klfDbg("cannot find sub-resource: "<(); } QList newIds; int k; for (k = 0; k < entrylist.size(); ++k) { KLFLegacyData::KLFLibraryItem item = d->toLegacyLibItem(entrylist[k]); d->library[d->resources[index]] << item; newIds << item.id; } d->haschanges = true; emit dataChanged(subResource, InsertData, newIds); klfDbg("finished inserting items. d="<resources <<"\nand library:\n"<library) ; return newIds; } bool KLFLibLegacyEngine::changeEntries(const QString& subResource, const QList& idlist, const QList& properties, const QList& values) { if (idlist.size() == 0) return true; if (!canModifyData(subResource, ChangeData)) return false; KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return false ) ; int index = d->findResourceName(subResource); if (index < 0) return false; const KLFLegacyData::KLFLibraryList& ll = d->library[d->resources[index]]; bool success = true; int k; for (k = 0; k < idlist.size(); ++k) { int libindex; int j; // find the entry for (libindex = 0; libindex < ll.size() && ll[libindex].id != (quint32)idlist[k]; ++libindex) ; if (libindex == ll.size()) { qWarning()<" { QString curcategory = d->library[d->resources[index]][libindex].category; QString curtags = d->library[d->resources[index]][libindex].tags; d->library[d->resources[index]][libindex].latex = KLFLibEntry::latexAddCategoryTagsComment(values[j].toString(), curcategory, curtags); break; } case KLFLibEntry::DateTime: d->library[d->resources[index]][libindex].datetime = values[j].toDateTime(); break; case KLFLibEntry::Preview: d->library[d->resources[index]][libindex].preview = QPixmap::fromImage(values[j].value()); break; case KLFLibEntry::Category: // remember that entry.latex has redundancy for category+tags in the form "%: ...\n% ...\n" { QString curlatex = KLFLibEntry::stripCategoryTagsFromLatex(d->library[d->resources[index]][libindex].latex); QString newcategory = values[j].toString(); QString curtags = d->library[d->resources[index]][libindex].tags; d->library[d->resources[index]][libindex].latex = KLFLibEntry::latexAddCategoryTagsComment(curlatex, newcategory, curtags); d->library[d->resources[index]][libindex].category = newcategory; break; } case KLFLibEntry::Tags: // remember that entry.latex has redundancy for category+tags in the form "%: ...\n% ...\n" { QString curlatex = KLFLibEntry::stripCategoryTagsFromLatex(d->library[d->resources[index]][libindex].latex); QString curcategory = d->library[d->resources[index]][libindex].category; QString newtags = values[j].toString(); d->library[d->resources[index]][libindex].latex = KLFLibEntry::latexAddCategoryTagsComment(curlatex, curcategory, newtags); d->library[d->resources[index]][libindex].tags = newtags; break; } break; case KLFLibEntry::Style: d->library[d->resources[index]][libindex].style = KLFLegacyData::KLFLegacyStyle::fromNewStyle(values[j].value()); break; default: qWarning()<library[d->resources[index]]; int kl; for (kl = 0; kl < ll2.size(); ++kl) klfDbg( "\t#"<haschanges = true; emit dataChanged(subResource, ChangeData, idlist); return success; } bool KLFLibLegacyEngine::deleteEntries(const QString& subResource, const QList& idlist) { KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return false ) ; if (idlist.isEmpty()) return true; if (!canModifyData(subResource, DeleteData)) return false; int index = d->findResourceName(subResource); if (index < 0) return false; // now remove the requested entries KLFLegacyData::KLFLibraryList *ll = & d->library[d->resources[index]]; bool success = true; int k; for (k = 0; k < idlist.size(); ++k) { int j; for (j = 0; j < ll->size() && ll->operator[](j).id != (quint32)idlist[k]; ++j) ; if (j == ll->size()) { qWarning("KLFLibLegacyEngine::deleteEntries: Can't find ID %d in library list in current resource.", idlist[k]); success = false; continue; } // remove this entry from list ll->removeAt(j); } d->haschanges = true; emit dataChanged(subResource, DeleteData, idlist); return success; } bool KLFLibLegacyEngine::saveTo(const QUrl& newPath) { KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return false ) ; if (newPath.scheme() == "klf+legacy") { return d->save(klfUrlLocalFilePath(newPath)); } return false; } bool KLFLibLegacyEngine::saveResourceProperty(int propId, const QVariant& value) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; QVariantMap m = d->metadata["ResProps"].toMap(); QString propName = propertyNameForId(propId); if ( propName.isEmpty() ) return false; if (m.contains(propName) && m[propName] == value) return true; // nothing to do m[propName] = value; d->metadata["ResProps"] = QVariant(m); d->haschanges = true; d->emitResourcePropertyChanged(propId); return true; } void KLFLibLegacyEngine::updateResourceProperty(int propId) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; klfDbg("property id="< resprops = d->metadata["ResProps"].toMap(); if (propId < 0) { // read and update all the properties KLFPropertizedObject::setAllProperties(resprops); // set some default values for some properties if they have not been set if (!KLFPropertizedObject::property(PropLocked).isValid()) KLFPropertizedObject::doSetProperty(PropLocked, QVariant(false)); if (!KLFPropertizedObject::property(PropAccessShared).isValid()) KLFPropertizedObject::doSetProperty(PropAccessShared, QVariant::fromValue(false)); if (!KLFPropertizedObject::property(PropTitle).isValid()) KLFPropertizedObject::doSetProperty(PropTitle, QFileInfo(d->fileName()).baseName()); } else { QString propName = KLFPropertizedObject::propertyNameForId(propId); KLFPropertizedObject::doSetProperty(propId, resprops[propName]); } emit resourcePropertyChanged(propId); } // ------------------------------------ QString KLFLibLegacyLocalFileSchemeGuesser::guessScheme(const QString& fileName) const { klfDbg("file "<> s1; klfDbg("read line: got magic "< #include #include #include //#include #include namespace Ui { class KLFStyleManager; } class KLFStyleListModel : public QStringListModel { Q_OBJECT public: KLFStyleListModel(QObject *parent = 0) : QStringListModel(parent) { } virtual ~KLFStyleListModel() { } virtual Qt::ItemFlags flags(const QModelIndex& index) const; virtual QString styleName(int row) const; virtual void setStyleName(int row, const QString& newname); Qt::DropActions supportedDropActions() const; QStringList mimeTypes() const; QMimeData *mimeData(const QModelIndexList& indexes) const; bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); signals: void internalMoveCompleted(int prevrow, int newrow); }; class KLFStyleManager : public QWidget { Q_OBJECT public: KLFStyleManager(KLFStyleList *ptr, QWidget *parent); ~KLFStyleManager(); signals: void refreshStyles(); public slots: void slotRefresh(); void slotDelete(); void slotMoveUp(); void slotMoveDown(); void slotRename(); void refreshActionsEnabledState(); void showActionsContextMenu(const QPoint& pos); void retranslateUi(bool alsoBaseUi = true); protected slots: void slotModelMoveCompleted(int previouspos, int newpos); private: Ui::KLFStyleManager *u; KLFStyleList *_styptr; QMenu *mActionsPopup; QAction *actPopupDelete; QAction *actPopupMoveUp; QAction *actPopupMoveDown; QAction *actPopupRename; KLFStyleListModel *mStyleListModel; QPoint _drag_init_pos; QListWidgetItem *_drag_item; int currentRow(); }; #endif klatexformula-4.1.0/src/klflibview.cpp000644 000765 000024 00000476530 13660527435 021032 0ustar00philippestaff000000 000000 /*************************************************************************** * file klflibview.cpp * This file is part of the KLatexFormula Project. * Copyright (C) 2011 by Philippe Faist * philippe.faist at bluewin.ch * * * 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 of the License, 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., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ /* $Id$ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "klfconfig.h" #include "klflibview.h" #include "klflibview_p.h" // --------------------------------------------------- /** \internal */ static QImage transparentify_image(const QImage& img, qreal factor) { // set the image opacity to factor (by multiplying each alpha value by factor) QImage img2 = img.convertToFormat(QImage::Format_ARGB32_Premultiplied); int k, j; for (k = 0; k < img.height(); ++k) { for (j = 0; j < img.width(); ++j) { QRgb c = img2.pixel(j, k); img2.setPixel(j, k, qRgba(qRed(c),qGreen(c),qBlue(c),(int)(factor*qAlpha(c)))); } } return img2; } /** \internal */ static QImage autocrop_image(const QImage& img, int alpha_threshold = 0) { // crop transparent borders int x, y; int min_x = -1, max_x = -1, min_y = -1, max_y = -1; // so first find borders for (x = 0; x < img.width(); ++x) { for (y = 0; y < img.height(); ++y) { if (qAlpha(img.pixel(x,y)) - alpha_threshold > 0) { // opaque pixel: include it. if (min_x == -1 || min_x > x) min_x = x; if (max_x == -1 || max_x < x) max_x = x; if (min_y == -1 || min_y > y) min_y = y; if (max_y == -1 || max_y < y) max_y = y; } } } return img.copy(QRect(QPoint(min_x, min_y), QPoint(max_x, max_y))); } /** \internal */ static float color_distinguishable_distance(QRgb a, QRgb b, bool aPremultiplied = false) { static const float C_r = 11.f, C_g = 16.f, C_b = 5.f; static const float C_avg = (C_r + C_g + C_b) / 3.f; // (?) really-> NO? ON SECOND THOUGHT, REMOVE THIS FACTOR // // * drkfactor reduces distances for dark colors, accounting for the fact that the eye // // distinguishes less dark colors than light colors // // * 0 <= qGray(...) <= 255 // // * drkfactor <= 1 -> reducing factor // float drkfactor = 1 - (qGray(b)/1000.f); static const float drkfactor = 1; float alpha = qAlpha(a)/255.f; QRgb m; if (aPremultiplied) m = qRgb((int)(qRed(a)+(1-alpha)*qRed(b)), (int)(qGreen(a)+(1-alpha)*qGreen(b)), (int)(qBlue(a)+(1-alpha)*qBlue(b))); else m = qRgb((int)(alpha*qRed(a)+(1-alpha)*qRed(b)), (int)(alpha*qGreen(a)+(1-alpha)*qGreen(b)), (int)(alpha*qBlue(a)+(1-alpha)*qBlue(b))); float dst = qMax( qMax(C_r*abs(qRed(m) - qRed(b)), C_g*abs(qGreen(m) - qGreen(b))), C_b*abs(qBlue(m) - qBlue(b)) ) * drkfactor / C_avg; // klfDbg("a="< distance="< threshold) { // ok we have one pixel at least we can distinguish. return true; } } } return false; } // ------------------------------------------------------- KLFAbstractLibView::KLFAbstractLibView(QWidget *parent) : QWidget(parent), pResourceEngine(NULL) { } void KLFAbstractLibView::setResourceEngine(KLFLibResourceEngine *resource) { if (pResourceEngine) disconnect(pResourceEngine, 0, this, 0); pResourceEngine = resource; connect(pResourceEngine, SIGNAL(dataChanged(const QString&, int, const QList&)), this, SLOT(updateResourceData(const QString&, int, const QList&))); connect(pResourceEngine, SIGNAL(resourcePropertyChanged(int)), this, SLOT(updateResourceProp(int))); connect(pResourceEngine, SIGNAL(defaultSubResourceChanged(const QString&)), this, SLOT(updateResourceDefaultSubResourceChanged(const QString&))); updateResourceEngine(); } void KLFAbstractLibView::updateResourceDefaultSubResourceChanged(const QString& /*subResource*/) { updateResourceEngine(); } void KLFAbstractLibView::wantMoreCategorySuggestions() { emit moreCategorySuggestions(getCategorySuggestions()); } QList KLFAbstractLibView::addContextMenuActions(const QPoint&) { return QList(); } // ------------------------------------------------------- QList KLFLibViewFactory::pRegisteredFactories = QList(); KLFLibViewFactory::KLFLibViewFactory(const QStringList& viewTypeIdentifiers, QObject *parent) : QObject(parent), pViewTypeIdentifiers(viewTypeIdentifiers) { registerFactory(this); } KLFLibViewFactory::~KLFLibViewFactory() { unRegisterFactory(this); } QString KLFLibViewFactory::defaultViewTypeIdentifier() { if (pRegisteredFactories.size() > 0) return pRegisteredFactories[0]->pViewTypeIdentifiers.first(); return QString(); } KLFLibViewFactory *KLFLibViewFactory::findFactoryFor(const QString& viewTypeIdentifier) { if (viewTypeIdentifier.isEmpty()) { if (pRegisteredFactories.size() > 0) return pRegisteredFactories[0]; // first registered factory is default return NULL; } int k; // walk registered factories, and return the first that supports this scheme. for (k = 0; k < pRegisteredFactories.size(); ++k) { if (pRegisteredFactories[k]->viewTypeIdentifiers().contains(viewTypeIdentifier)) return pRegisteredFactories[k]; } // no factory found return NULL; } QStringList KLFLibViewFactory::allSupportedViewTypeIdentifiers() { QStringList list; int k; for (k = 0; k < pRegisteredFactories.size(); ++k) list << pRegisteredFactories[k]->viewTypeIdentifiers(); return list; } void KLFLibViewFactory::registerFactory(KLFLibViewFactory *factory) { KLF_ASSERT_NOT_NULL( factory, "Attempt to register NULL factory!", return ) ; // WARNING: THIS FUNCTION IS CALLED FROM CONSTRUCTOR. NO VIRTUAL METHOD CALLS! if (factory->pViewTypeIdentifiers.size() == 0) { qWarning("KLFLibViewFactory::registerFactory: factory must provide at least one view type!"); return; } if (pRegisteredFactories.indexOf(factory) != -1) // already registered return; pRegisteredFactories.append(factory); } void KLFLibViewFactory::unRegisterFactory(KLFLibViewFactory *factory) { if (pRegisteredFactories.indexOf(factory) == -1) return; pRegisteredFactories.removeAll(factory); } // --------------------------------------------------- // static KLFFactoryManager KLFLibWidgetFactory::pFactoryManager; KLFLibWidgetFactory::KLFLibWidgetFactory(QObject *parent) : QObject(parent), KLFFactoryBase(&pFactoryManager) { } // static KLFLibWidgetFactory *KLFLibWidgetFactory::findFactoryFor(const QString& wtype) { return dynamic_cast(pFactoryManager.findFactoryFor(wtype)); } // static QStringList KLFLibWidgetFactory::allSupportedWTypes() { return pFactoryManager.allSupportedTypes(); } bool KLFLibWidgetFactory::hasCreateWidget(const QString& /*scheme*/) const { return false; } QWidget * KLFLibWidgetFactory::createPromptCreateParametersWidget(QWidget */*parent*/, const QString& /*scheme*/, const Parameters& /*par*/) { return NULL; } KLFLibWidgetFactory::Parameters /* */ KLFLibWidgetFactory::retrieveCreateParametersFromWidget(const QString& /*scheme*/, QWidget */*parent*/) { return Parameters(); } bool KLFLibWidgetFactory::hasSaveToWidget(const QString& /*scheme*/) const { return false; } QWidget *KLFLibWidgetFactory::createPromptSaveToWidget(QWidget */*parent*/, const QString& /*scheme*/, KLFLibResourceEngine* /*resource*/, const QUrl& /*defaultUrl*/) { return NULL; } QUrl KLFLibWidgetFactory::retrieveSaveToUrlFromWidget(const QString& /*scheme*/, QWidget */*widget*/) { return QUrl(); } // -------------------------------------------- KLF_EXPORT QDebug& operator<<(QDebug& dbg, const KLFLibModelCache::NodeId& n) { const char * skind = ( (n.kind == KLFLibModelCache::EntryKind) ? "EntryKind" : ((n.kind == KLFLibModelCache::CategoryLabelKind) ? "CategoryLabelKind" : "*UnknownKind*") ); return dbg.nospace() << "NodeId("<+"<getCategoryLabelNodeRef(a).categoryLabel, cache->getCategoryLabelNodeRef(b).categoryLabel) < 0; } // both are entrykind return entrysorter->operator()(cache->getEntryNodeRef(a).entry, cache->getEntryNodeRef(b).entry); } int entryProp = entrysorter->propId(); int sortorderfactor = (entrysorter->order() == Qt::AscendingOrder) ? 1 : -1; QString nodevaluea = cache->nodeValue(a, entryProp); QString nodevalueb = cache->nodeValue(b, entryProp); return sortorderfactor*QString::localeAwareCompare(nodevaluea, nodevalueb) < 0; } // --- void KLFLibModelCache::rebuildCache() { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; klfDbg(klfFmtCC("flavorFlags=%#010x", pModel->pFlavorFlags)); int k; // report progress #ifndef KLF_WS_MAC KLFProgressReporter progressReporter(0, 100, NULL); QString msg = QObject::tr("Updating View...", "[[KLFLibModelCache, progress text]]"); emit pModel->operationStartReportingProgress(&progressReporter, msg); progressReporter.doReportProgress(0); #endif klfDbgT("saving persistent indexes ..."); QModelIndexList persistentIndexes = pModel->persistentIndexList(); QList persistentIndexIds = pModel->persistentIdList(persistentIndexes); klfDbgT("... done saving persistent indexes."); pModel->beginResetModel(); // clear cache first pEntryCache.clear(); pCategoryLabelCache.clear(); // root category label MUST ALWAYS (in every display flavor) occupy index 0 in category label cache pCategoryLabelCache.append(CategoryLabelNode()); CategoryLabelNode& root = pCategoryLabelCache[0]; root.fullCategoryPath = "/"; root.categoryLabel = "/"; root.allChildrenFetched = false; QList wantedProps = minimalistEntryPropIds(); KLFLibResourceEngine::Query q; q.orderPropId = pLastSortPropId; q.orderDirection = pLastSortOrder; if (pModel->pFlavorFlags & KLFLibModel::CategoryTree) { // fetch only elements in root category KLFLib::PropertyMatch pmatch(KLFLibEntry::Category, KLFLib::StringMatch(QString(""))); q.matchCondition = KLFLib::EntryMatchCondition::mkPropertyMatch(pmatch); } q.wantedEntryProperties = minimalistEntryPropIds(); q.limit = pModel->pFetchBatchCount; // limit number of results KLFLibResourceEngine::QueryResult qr(KLFLibResourceEngine::QueryResult::FillEntryWithIdList); // query the resource klfDbgT("about to query resource..."); int count = pModel->pResource->query(pModel->pResource->defaultSubResource(), q, &qr); klfDbgT("resource returned "<pFetchBatchCount) { // we have fetched all children klfDbg("all children have been fetched.") ; root.allChildrenFetched = true; } const QList& everything = qr.entryWithIdList; QList::const_iterator it; k = 0; // used for progress reporting for (it = everything.begin(); it != everything.end(); ++it) { const KLFLibResourceEngine::KLFLibEntryWithId& ewid = *it; klfDbgT( "Adding entry id="<pResource->queryValues(pModel->pResource->defaultSubResource(), KLFLibEntry::Category); klfDbgT("... got categories. inserting them ..."); for (QVariantList::const_iterator vcit = vcatlist.begin(); vcit != vcatlist.end(); ++vcit) { QString cat = (*vcit).toString(); if (cat.isEmpty() || cat == "/") continue; // cacheFindCategoryLabel(categoryelements, createIfNotExists, notifyQtApi, newCreatedAreChildrenFetched) QStringList catelements = cat.split('/', QString::SkipEmptyParts); int i = cacheFindCategoryLabel(catelements, true, false, false); if (i < 0) { qWarning()<rowCount(QModelIndex()); int k; for (k = 0; k < pModel->rowCount(QModelIndex()); ++k) { QModelIndex i = pModel->index(k, 0, QModelIndex()); if (pModel->rowCount(i) < 6 || numRootItems < 6) { if (pModel->canFetchMore(i)) pModel->fetchMore(i); } } } fullDump(); // DEBUG pModel->endResetModel(); klfDbg("restoring persistent indexes ..."); QModelIndexList newPersistentIndexes = pModel->newPersistentIndexList(persistentIndexIds); // and refresh all persistent indexes pModel->changePersistentIndexList(persistentIndexes, newPersistentIndexes); klfDbg("... done restoring persistent indexes."); klfDbgT( " end of func" ) ; } QModelIndex KLFLibModelCache::createIndexFromId(NodeId nodeid, int row, int column) { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; if ( ! nodeid.valid() || nodeid == NodeId::rootNode()) return QModelIndex(); // if row is -1, then we need to find the row of the item if ( row < 0 ) { row = getNodeRow(nodeid); } // make sure all elements have been "fetched" up to this row klfDbg( ": nodeid="<createIndex(row, column, nodeid.universalId()); } KLFLibModelCache::NodeId KLFLibModelCache::getNodeForIndex(const QModelIndex& index) { if ( ! index.isValid() ) return NodeId(); NodeId n = NodeId::fromUID(index.internalId()); // perform validity check on 'n' if (n.kind == EntryKind) { if (n.index < 0 || n.index >= pEntryCache.size()) { qWarning()<= pCategoryLabelCache.size()) { qWarning()<= pEntryCache.size()) { qWarning()<<"KLFLibModelCache::getNodeRef: Invalid Entry Node Id: "<= pCategoryLabelCache.size()) { qWarning()<<"KLFLibModelCache::getNodeRef: Invalid Category Label Node Id: "<= pEntryCache.size()) { qWarning()<<"KLFLibModelCache::getEntryNodeRef: Invalid Entry Node "<= pCategoryLabelCache.size()) { qWarning()<<"KLFLibModelCache::getCat.LabelNode: Invalid Category Label Node "< n="<pFlavorFlags & KLFLibModel::CategoryTree) { QString c = KLFLibEntry::normalizeCategoryPath(noderef.fullCategoryPath); KLFLib::PropertyMatch pmatch(KLFLibEntry::Category, KLFLib::StringMatch(c)); q.matchCondition = KLFLib::EntryMatchCondition::mkPropertyMatch(pmatch); } q.orderPropId = pLastSortPropId; q.orderDirection = pLastSortOrder; q.limit = pModel->pFetchBatchCount; q.skip = noderef.children.size(); q.wantedEntryProperties = minimalistEntryPropIds(); KLFLibResourceEngine::QueryResult qr(KLFLibResourceEngine::QueryResult::FillEntryWithIdList); // _query()_ the resource int count = pModel->pResource->query(pModel->pResource->defaultSubResource(), q, &qr); if (count < 0) { qWarning()<startLayoutChange(false); pModel->beginInsertRows(createIndexFromId(n, -1, 0), noderef.children.size(), noderef.children.size() + qr.entryWithIdList.size()-1); // if we fetched all the remaining entries, then set allChildrenFetched to TRUE if (count < q.limit) { noderef.allChildrenFetched = true; } int k; for (k = 0; k < qr.entryWithIdList.size(); ++k) { const KLFLibResourceEngine::KLFLibEntryWithId& ewid = qr.entryWithIdList[k]; EntryNode e; e.entryid = ewid.id; e.minimalist = true; e.entry = ewid.entry; e.parent = n; pEntryCache.append(e); NodeId entryindex; entryindex.kind = EntryKind; entryindex.index = pEntryCache.size()-1; klfDbg("appending "<endInsertRows(); klfDbg("signal emitted. restore persistent indexes...") ; pModel->endLayoutChange(false); klfDbg("views notified, persistent indexes restored.") ; pIsFetchingMore = false; } void KLFLibModelCache::updateData(const QList& entryIdList, int modifyType) { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; klfDbg( "modifyType="< 10 && (entryIdList.size() > pEntryCache.size()/3 || entryIdList.size() > 100)) { // too big a modification, just rebuild the cache klfDbg("Performing full refresh.") ; rebuildCache(); return; } #ifndef KLF_WS_MAC // progress reporting [here, not above, because rebuildCache() has its own progress reporting] KLFProgressReporter progressReporter(0, entryIdList.size(), NULL); emit pModel->operationStartReportingProgress(&progressReporter, QObject::tr("Updating View...", "[[KLFLibModelCache, progress text]]")); progressReporter.doReportProgress(0); #endif switch (modifyType) { case KLFLibResourceEngine::InsertData: { // entries inserted QList entryList = pModel->pResource->entries(entryIdList); int k; for (k = 0; k < entryList.size(); ++k) { EntryNode en; en.entryid = entryList[k].id; en.minimalist = false; en.entry = entryList[k].entry; /** \todo ...... here the view is notified for each individual insert. would be better for * contiguous inserts to be notified once .... */ treeInsertEntry(en); qDebug("%s: entry ID %d inserted", KLF_FUNC_NAME, entryIdList[k]); #ifndef KLF_WS_MAC if (k % 20 == 0) progressReporter.doReportProgress(k+1); #endif } break; } case KLFLibResourceEngine::ChangeData: { // entry moved in category tree or just changed QList entryList = pModel->pResource->entries(entryIdList); int k; for (k = 0; k < entryIdList.size(); ++k) { klfDbg("modifying entry ID="<displayType() == KLFLibModel::LinearList) { // add as child of root element catindex = 0; } else if (pModel->displayType() == KLFLibModel::CategoryTree) { // find/create category label node (creating the full tree if needed) catindex = cacheFindCategoryLabel(catelements, true, notifyQtApi, rebuildingcache?false:true); } else { qWarning("Flavor Flags have unknown display type! flavorFlags=%#010x", pModel->pFlavorFlags); catindex = 0; } NodeId parentid = NodeId(CategoryLabelKind, catindex); // now actually create the entry cache node int index = pEntryCache.insertNewNode(entrynode); NodeId n = NodeId(EntryKind, index); // invalidate the node until the insert process is finished. // the (invalid but with correct info) entry needs to reside in the cache for qLowerBound() below. pEntryCache[index].parent = NodeId(); // now we determined the parent of the new entry in the category tree, we will actually // insert the item according to current sort instructions. Node& parentref = getNodeRef(parentid); QList & childlistref = parentref.children; int insertPos; if (rebuildingcache || pLastSortPropId < 0) { insertPos = childlistref.size(); // no sorting, just append the item } else { KLFLibModelSorter srt = KLFLibModelSorter(this, pModel->pEntrySorter, pModel->pFlavorFlags & KLFLibModel::GroupSubCategories); // Note: as long as we are instructed to insert the new item at the end, we need to fetchMore() to ensure // that all elements logically appearing before the new element are fetched. bool retry; do { retry = false; // qLowerBound returns an iterator. subtract begin() to get absolute index insertPos = qLowerBound(childlistref.begin(), childlistref.end(), n, srt) - childlistref.begin(); if (insertPos > childlistref.size()-10 && canFetchMore(parentid)) { fetchMore(parentid); retry = true; } } while (retry); // by fetching more, we may possibly have actually fetched the entry that we were instructed to insert // in the first place. Check. if (insertPos < childlistref.size() && childlistref[insertPos] == n) return; // job already done. } CategoryLabelNode &catLabelNodeRef = getCategoryLabelNodeRef(parentid); // and insert it again at the required spot if (notifyQtApi) { QModelIndex parentidx = createIndexFromId(parentid, -1, 0); pModel->beginInsertRows(parentidx, insertPos, insertPos); } qDebug("\tinserting (%d,%d) at pos %d in category '%s'", n.kind, n.index, insertPos, qPrintable(catLabelNodeRef.fullCategoryPath)); pEntryCache[n.index].parent = parentid; // set the parent, thus validating the node childlistref.insert(insertPos, n); // insert into list of children if (notifyQtApi) pModel->endInsertRows(); } KLFLibModelCache::EntryNode KLFLibModelCache::treeTakeEntry(const NodeId& nodeid, bool notifyQtApi) { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; klfDbg( "("<endRemoveRows(); n = parentid; } while (willRemoveParent); return entrynode; } KLFLibModelCache::IndexType /* */ KLFLibModelCache::cacheFindCategoryLabel(QStringList catelements, bool createIfNotExists, bool notifyQtApi, bool newlyCreatedAreChildrenFetched) { klfDbg( "catelmnts="<displayType() != KLFLibModel::CategoryTree) { qWarning("cacheFindCategoryLabel: but not in a category tree display type (flavor flags=%#010x)", pModel->pFlavorFlags); return 0; } QStringList catelementsparent = catelements.mid(0, catelements.size()-1); IndexType parent_index = cacheFindCategoryLabel(catelementsparent, true, notifyQtApi); KLFLibModelCache::KLFLibModelSorter srt = KLFLibModelCache::KLFLibModelSorter(this, pModel->pEntrySorter, pModel->pFlavorFlags & KLFLibModel::GroupSubCategories); // the category label node to add CategoryLabelNode c; c.allChildrenFetched = newlyCreatedAreChildrenFetched; c.fullCategoryPath = catelpath; c.categoryLabel = catelements.last(); // catelements is non-empty, see above // now create this last category label IndexType this_index = pCategoryLabelCache.insertNewNode(c); int insertPos; CategoryLabelNode & parentCatLabelNodeRef = pCategoryLabelCache[parent_index]; QList & childlistref = parentCatLabelNodeRef.children; if (pLastSortPropId < 0) { insertPos = childlistref.size(); // no sorting, just append the item } else { // qLowerBound returns an iterator. subtract begin() to get absolute index insertPos = qLowerBound(childlistref.begin(), childlistref.end(), NodeId(CategoryLabelKind, this_index), srt) - childlistref.begin(); } klfDbg( ": About to insert rows in "<beginInsertRows(parentidx, insertPos, insertPos); } qDebug("%s: Inserting this_index=%d in parent_index=%d 's children", KLF_FUNC_NAME, this_index, parent_index); childlistref.insert(insertPos, NodeId(CategoryLabelKind, this_index)); pCategoryLabelCache[this_index].parent = NodeId(CategoryLabelKind, parent_index); if (notifyQtApi) pModel->endInsertRows(); // and return the created category label index return this_index; } QString KLFLibModelCache::nodeValue(NodeId n, int entryProperty) { // return an internal string representation of the value of the property 'entryProperty' in node ptr. // or the category title if node is a category if (!n.valid() || n.isRoot()) return QString(); if (entryProperty < 0) { qWarning()<entrySorter()->entryValue(en.entry, entryProperty); } if (n.kind == CategoryLabelKind) return getCategoryLabelNodeRef(n).categoryLabel; qWarning()<entrySorter()->propId() == pLastSortPropId) { // already sorting according to that column if (sorter->entrySorter()->order() == pLastSortOrder) { // exact same sorting required, already done. return; } else { // opposite sorting (eg. Ascending instead of Descending) // -> reverse child list requireSimpleReverse = true; } } int k; // sort this category's children // This works both in LinearList and in CategoryTree display types. (In LinearList // display type, call this function on root category node) if (category.kind != CategoryLabelKind) return; if (category.index < 0 || category.index >= pCategoryLabelCache.size()) return; if (sorter->entrySorter()->propId() < 0) return; // no sorting required QList& childlistref = pCategoryLabelCache[category.index].children; if (requireSimpleReverse) { // reverse the child list (but not category list if flavor is to group them) int N = childlistref.size(); int firstEntryInd = 0; if (pModel->pFlavorFlags & KLFLibModel::GroupSubCategories) { for (firstEntryInd = 0; firstEntryInd < N && childlistref[firstEntryInd].kind != EntryKind; ++firstEntryInd) ; // in case the GroupSubCategories flag is false, firstEntryInd is zero -> reverse all } // swap all entries, skipping the grouped sub-categories for (k = 0; k < (N-firstEntryInd)/2; ++k) qSwap(childlistref[firstEntryInd+k], childlistref[N-k-1]); } else { qSort(childlistref.begin(), childlistref.end(), *sorter); // normal sort } // and sort all children's children for (k = 0; k < childlistref.size(); ++k) if (childlistref[k].kind == CategoryLabelKind) sortCategory(childlistref[k], sorter, false /* not root call */); if (rootCall) { pLastSortPropId = sorter->entrySorter()->propId(); pLastSortOrder = sorter->entrySorter()->order(); } } KLFLibModelCache::NodeId KLFLibModelCache::nextNode(NodeId n) { // klfDbg( "KLFLibModelCache::nextNode("< 0) { return nn.children[0]; } if (!nn.allChildrenFetched && canFetchMore(n)) { // we may have children, so try to fetch children fetchMore(n); // and recurse, now that more children have possibly been fetched. return nextNode(n); } // no children, find next sibling. NodeId parentid; while ( (parentid = nn.parent).valid() ) { Node parent = getNode(parentid); int row = getNodeRow(n); if (row+1 < parent.children.size()) { // there is a next sibling: return it return parent.children[row+1]; } if (!parent.allChildrenFetched && canFetchMore(parentid)) { // there is possibly a next sibling, it just possibly hasn't been fetched. fetchMore(parentid); // now that the more children has been fetched for this parent, try again: (by recursing) return nextNode(n); } // no next sibling, so go up the tree n = parentid; nn = parent; } // last entry passed return NodeId(); } KLFLibModelCache::NodeId KLFLibModelCache::prevNode(NodeId n) { if (!n.valid() || n.isRoot()) { // look for last node in tree. return lastNode(NodeId()); // NodeId() is accepted by lastNode. } // find previous sibling NodeId parentId = getNode(n).parent; Node parent = getNode(parentId); int row = getNodeRow(n); if (row > 0) { // there is a previous sibling: find its last node return lastNode(parent.children[row-1]); } // there is no previous sibling: so we can return the parent // except if parent is the root node, in which case we return an invalid NodeId. if (parentId == NodeId::rootNode()) return NodeId(); return parentId; } KLFLibModelCache::NodeId KLFLibModelCache::lastNode(NodeId n) { if (!n.valid()) n = NodeId::rootNode(); // root category Node nn = getNode(n); // get the last child of node 'n' // this includes fetching _all_ its children if applicable while (!nn.allChildrenFetched) { if (!canFetchMore(n)) { qWarning()< KLFLibModelCache::entryIdList(const QModelIndexList& indexlist) { // ORDER OF RESULT IS NOT GARANTEED != entryIdForIndexList() QList idList; int k; QList nodeIds; // walk all indexes and get their IDs for (k = 0; k < indexlist.size(); ++k) { NodeId n = getNodeForIndex(indexlist[k]); if ( !n.valid() || n.kind != EntryKind) continue; if ( nodeIds.contains(n) ) // duplicate, probably for another column continue; nodeIds << n; idList << getEntryNodeRef(n).entryid; } return idList; } QList KLFLibModelCache::entryIdForIndexList(const QModelIndexList& indexlist) { // ORDER OF RESULT GARANTEED != entryIdList() QList eidlist; int k; for (k = 0; k < indexlist.size(); ++k) { NodeId node = getNodeForIndex(indexlist[k]); if ( !node.valid() || node.kind != EntryKind ) { eidlist << (KLFLib::entryId) -1; continue; } eidlist << getEntryNodeRef(node).entryid; } return eidlist; } QModelIndexList KLFLibModelCache::findEntryIdList(const QList& eidlist) { klfDbg( ": eidlist="<= 0) { indexlist[i] = createIndexFromId(NodeId(EntryKind, k), -1, 0); if (++count == eidlist.size()) break; // found 'em all } } return indexlist; } KLFLibModelCache::NodeId KLFLibModelCache::findEntryId(KLFLib::entryId eId) { klfDbg("eId="<supportedFeatureFlags() & KLFLibResourceEngine::FeatureSubResources) == 0) return pResource->url(); // return URL with the default sub-resource (as we're displaying that one only) return pResource->url(KLFLibResourceEngine::WantUrlDefaultSubResource); } void KLFLibModel::setFlavorFlags(uint flags, uint modify_mask) { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; if ( (flags & modify_mask) == (pFlavorFlags & modify_mask) ) return; // no change uint other_flags = pFlavorFlags & ~modify_mask; pFlavorFlags = flags | other_flags; // stuff that needs update if (modify_mask & DisplayTypeMask) { updateCacheSetupModel(); } if (modify_mask & GroupSubCategories) { int col = columnForEntryPropertyId(pEntrySorter->propId()); Qt::SortOrder ord = pEntrySorter->order(); // force full re-sort sort(-1, ord); // by first setting to unsorted sort(col, ord); // and then re-sorting correctly } } uint KLFLibModel::flavorFlags() const { return pFlavorFlags; } void KLFLibModel::prefetch(const QModelIndexList& indexes) const { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; int k; for (k = 0; k < indexes.size(); ++k) { if (!indexes[k].isValid()) continue; KLFLibModelCache::NodeId p = pCache->getNodeForIndex(indexes[k]); if (!p.valid() || p.isRoot()) { klfDbg("Invalid index: indexes[k].row="<ensureNotMinimalist(p); } } QVariant KLFLibModel::data(const QModelIndex& index, int role) const { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; // KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; // klfDbg( "\tindex="<getCategoryLabelNodeRef(KLFLibModelCache::NodeId::rootNode()); // root node KLFLibModelCache::CategoryLabelNode p = cat_p; if (parent.isValid()) { KLFLibModelCache::NodeId pp = pCache->getNodeForIndex(parent); if (pp.kind != KLFLibModelCache::CategoryLabelKind) return QModelIndex(); if (pp.valid()) p = pCache->getCategoryLabelNodeRef(pp); } if (row < 0 || row >= p.children.size() || column < 0 || column >= columnCount(parent)) return QModelIndex(); klfDbgT(": row="<getNodeForIndex(index); if ( !p.valid() ) // invalid index return QModelIndex(); KLFLibModelCache::Node n = pCache->getNode(p); if ( ! n.parent.valid() ) // invalid parent (should never happen!) return QModelIndex(); return KLF_DEBUG_TEE( pCache->createIndexFromId(n.parent, -1 /* figure out row */, 0) ) ; } int KLFLibModel::rowCount(const QModelIndex &parent) const { KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ; if (parent.column() > 0) return 0; KLFLibModelCache::NodeId p = pCache->getNodeForIndex(parent); if (!p.valid()) p = KLFLibModelCache::NodeId::rootNode(); KLFLibModelCache::Node n = pCache->getNode(p); klfDbg( " parent="< entryids; QList entriesnodeids; int k; for (k = 0; k < indexes.size(); ++k) { KLFLibModelCache::NodeId n = pCache->getNodeForIndex(indexes[k]); if (!n.valid() || n.isRoot()) continue; if (n.kind != KLFLibModelCache::EntryKind) continue; if (entriesnodeids.contains(n)) continue; // skip duplicates (for ex. for other model column indexes) const KLFLibModelCache::EntryNode& en = pCache->getEntryNodeRef(n); entries << pResource->entry(en.entryid); entryids << en.entryid; entriesnodeids << n; } // klfDbg( "KLFLibModel::mimeData: Encoding entries "<setData("application/x-klf-internal-lib-move-entries", internalmovedata); return mimedata; } // private bool KLFLibModel::dropCanInternal(const QMimeData *mimedata) { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; if ( ! mimedata->hasFormat("application/x-klf-internal-lib-move-entries") || ! pResource->canModifyData(KLFLibResourceEngine::ChangeData)) return false; QByteArray imdata = mimedata->data("application/x-klf-internal-lib-move-entries"); QDataStream imstr(imdata); imstr.setVersion(QDataStream::Qt_4_4); QVariantMap vprop; imstr >> vprop; QUrl theirurl = vprop.value("Url").toUrl(); QUrl oururl = url(); bool ok = (oururl.toEncoded() == theirurl.toEncoded()); klfDbg( "drag originated from "<canModifyData(KLFLibResourceEngine::ChangeData)) && ! (KLFAbstractLibEntryMimeEncoder::canDecodeMimeData(mimedata) && pResource->canModifyData(KLFLibResourceEngine::InsertData)) ) { // cannot (change items with application/x-klf-internal-lib-move-entries) AND // cannot (insert items with any supported format, eg. application/x-klf-libentries) return false; } if (column > 0) return false; // imdata, imstr : "*i*nternal *m*ove" ; ldata, lstr : "entry *l*ist" bool useinternalmove = dropCanInternal(mimedata); if (useinternalmove) { klfDbg( "Dropping application/x-klf-internal-lib-move-entries" ) ; if ( !(pFlavorFlags & CategoryTree) ) return false; QByteArray imdata = mimedata->data("application/x-klf-internal-lib-move-entries"); QDataStream imstr(imdata); imstr.setVersion(QDataStream::Qt_4_4); QList idlist; QVariantMap vprop; imstr >> vprop >> idlist; // get the category we moved to KLFLibModelCache::NodeId pn = pCache->getNodeForIndex(parent); if (!pn.valid()) { pn = KLFLibModelCache::NodeId::rootNode(); } if (ItemKind(pn.kind) != CategoryLabelKind) { qWarning()<<"Dropped in a non-category index! (kind="<getCategoryLabelNodeRef(pn); // move, not copy: change the selected entries to the new category. QString newcategory = cn.fullCategoryPath; if (newcategory.endsWith("/")) newcategory.chop(1); bool r = pResource->changeEntries(idlist, QList() << KLFLibEntry::Category, QList() << QVariant(newcategory)); klfDbg( "Accepted drop of type application/x-klf-internal-lib-move-entries. Res="<createIndexFromId(nextnode, -1, 0); } QModelIndex KLFLibModel::walkPrevIndex(const QModelIndex& cur) { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; KLFLibModelCache::NodeId prevnode = pCache->prevNode(pCache->getNodeForIndex(cur)); return pCache->createIndexFromId(prevnode, -1, 0); } KLFLib::entryId KLFLibModel::entryIdForIndex(const QModelIndex& index) const { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; return entryIdForIndexList(QModelIndexList() << index) [0]; } QModelIndex KLFLibModel::findEntryId(KLFLib::entryId eid) const { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; return findEntryIdList(QList() << eid) [0]; } QList KLFLibModel::entryIdForIndexList(const QModelIndexList& indexlist) const { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; return pCache->entryIdForIndexList(indexlist); } QModelIndexList KLFLibModel::findEntryIdList(const QList& eidlist) const { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; return pCache->findEntryIdList(eidlist); } void KLFLibModel::setEntrySorter(KLFLibEntrySorter *entrySorter) { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; if (pEntrySorter == entrySorter) return; if (entrySorter == NULL) { qWarning()<*stepfunc)(curNode)).valid() ) { if ( pCache->searchNodeMatches(curNode, pSearchString, cs) ) { found = true; } if (t.elapsed() > 150) { pSearchCurNode = pCache->createIndexFromId(curNode, -1, 0); qApp->processEvents(); if (pSearchAborted) break; t.restart(); } } pSearchCurNode = pCache->createIndexFromId(curNode, -1, 0); if (found) { klfDbg( "found "<pFlavorFlags & KLFLibModel::CategoryTree) == 0 && nodeValue(nodeId, KLFLibEntry::Category).contains(searchString, cs)) { return true; } return false; } // bool KLFLibModel::changeEntries(const QModelIndexList& indexlist, int propId, const QVariant& value) // { // if ( indexlist.size() == 0 ) // return true; // no change... // QList idList = pCache->entryIdList(indexlist); // klfDbg( ": Changing entries "<fullDump(); // bool r = pResource->changeEntries(idList, QList() << propId, QList() << value); // // klfDbg( ": entries changed, full dump:" ) ; // // pCache->fullDump(); // // the resource will emit dataChanged() to the view's updateResourceData() for the model update // return r; // } // bool KLFLibModel::insertEntries(const KLFLibEntryList& entries) // { // if (entries.size() == 0) // return true; // nothing to do... // KLFLibEntryList elist = entries; // QList list = pResource->insertEntries(elist); // if ( list.size() == 0 || list.contains(-1) ) // return false; // error for at least one entry // return true; // } // bool KLFLibModel::deleteEntries(const QModelIndexList& indexlist) // { // if ( indexlist.size() == 0 ) // return true; // no change... // QList idList = pCache->entryIdList(indexlist); // if ( pResource->deleteEntries(idList) ) { // // will be automatically called via the call to resoruce->(modify-data)()! // // updateCacheSetupModel(); // return true; // } // return false; // } void KLFLibModel::completeRefresh() { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; updateCacheSetupModel(); } void KLFLibModel::redoSort() { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; // truly need to re-query the resource with our partial querying and fetching more system... updateCacheSetupModel(); return; /* // this does not work with partial querying and fetching more, we truly need to re-query the resource startLayoutChange(); KLFLibModelCache::KLFLibModelSorter srt = KLFLibModelCache::KLFLibModelSorter(pCache, pEntrySorter, pFlavorFlags & KLFLibModel::GroupSubCategories); pCache->sortCategory(KLFLibModelCache::NodeId::rootNode(), &srt); endLayoutChange(); */ } void KLFLibModel::sort(int column, Qt::SortOrder order) { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; // select right property ID int propId = entryColumnContentsPropertyId(column); // if property ID is preview, then request sort by DateTime (user friendliness) if (propId == KLFLibEntry::Preview) { propId = KLFLibEntry::DateTime; } pEntrySorter->setPropId(propId); pEntrySorter->setOrder(order); pCache->setSortingBy(propId, order); redoSort(); } QList KLFLibModel::persistentIdList(const QModelIndexList& persistentIndexes) { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; // save persistent indexes QList persistentIndexIds; int k; for (k = 0; k < persistentIndexes.size(); ++k) { PersistentId id; KLFLibModelCache::NodeId n = pCache->getNodeForIndex(persistentIndexes[k]); if (!n.valid()) { id.kind = (ItemKind)-1; } else { id.kind = n.kind; if (ItemKind(id.kind) == EntryKind) id.entry_id = pCache->getEntryNodeRef(n).entryid; else if (ItemKind(id.kind) == CategoryLabelKind) id.categorylabel_fullpath = pCache->getCategoryLabelNodeRef(n).fullCategoryPath; else qWarning("KLFLibModel::persistentIdList: Bad Node kind: %d!!", id.kind); } id.column = persistentIndexes[k].column(); persistentIndexIds << id; klfDbg("saved persistent id "<& persistentIndexIds) { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; QModelIndexList newPersistentIndexes; int k; for (k = 0; k < persistentIndexIds.size(); ++k) { // find node in new layout PersistentId id = persistentIndexIds[k]; QModelIndex index; if (ItemKind(id.kind) == EntryKind) { QModelIndexList ilist = pCache->findEntryIdList(QList() << id.entry_id); index = ilist[0]; } else if (id.kind == CategoryLabelKind) { int idx = pCache->cacheFindCategoryLabel(id.categorylabel_fullpath.split('/')); KLFLibModelCache::NodeId nodeId(KLFLibModelCache::CategoryLabelKind, idx); index = pCache->createIndexFromId(nodeId, -1, 0); } else { qWarning("%s: bad persistent id node kind! :%d", KLF_FUNC_NAME, id.kind); } newPersistentIndexes << index; klfDbg("restoring persistent id "<rebuildCache(); } // -------------------------------------------------------- KLFLibViewDelegate::KLFLibViewDelegate(QObject *parent) : QAbstractItemDelegate(parent), pSelModel(NULL), pTheTreeView(NULL), pPreviewSize(klfconfig.UI.labelOutputFixedSize) { pAutoBackgroundItems = true; } KLFLibViewDelegate::~KLFLibViewDelegate() { } QWidget * KLFLibViewDelegate::createEditor(QWidget */*parent*/, const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/) const { return 0; } bool KLFLibViewDelegate::editorEvent(QEvent */*event*/, QAbstractItemModel */*model*/, const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/) { return false; } /** \internal */ class _klf_block_progress_blocker { KLFLibResourceEngine *res; public: _klf_block_progress_blocker(KLFLibResourceEngine *r) : res(r) { if (res != NULL) res->blockProgressReporting(true); } ~_klf_block_progress_blocker() { if (res != NULL) res->blockProgressReporting(false); } }; void KLFLibViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; klfDbg( "\tindex="<background ) ; QColor bgcolor = p->background.color(); QList bglista, bglistb, bglist; // bglist << bgcolor // << QColor(255,255,255) // << QColor(220,220,220) // << QColor(180,190,190) // << QColor(200,200,200) // << QColor(150,150,150) // << QColor(100,100,100) // << QColor(50,50,50) // << QColor(0,0,0); bglist << bgcolor; // first try: default color (!) bglista = bglistb = bglist; int count; for (count = 0; count < 5; ++count) // suggest N (ever) darker colors bglista << bglista.last().darker(105+count*2); for (count = 0; count < 5; ++count) // and N (ever) lighter colors bglistb << bglistb.last().lighter(105+count*2); // build the full list, and always provide white, and black to be sure bglist << bglista.mid(1) << bglistb.mid(1) << QColor(255,255,255) << QColor(0,0,0); klfDbg( "alt. bg list is "<fillRect(option.rect, QColor(128,0,0)); } } void KLFLibViewDelegate::paintCategoryLabel(PaintPrivate *p, const QModelIndex& index) const { KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ; // klfDbg( "index="<isexpanded=" // <<(pTheTreeView?(pTheTreeView->isExpanded(index)?"true":"false"):"(N/A)") ); // klfDbg( "index has selected desc. ?="< 0) // paint only on first column return; // klfDbg( "index="<p->setPen(borderfadepen); } else { klfDbg("Don't need border fade pen for text "<p->setPen(normalpen); } p->p->drawText(p->innerRectText, Qt::AlignLeft|Qt::AlignVCenter, text); } else { // formatting required. // build a list of regions to highlight QList c; QTextCharFormat f_highlight; if (flags & PTF_HighlightSearchCurrent) f_highlight.setBackground(QColor(0,255,0,80)); f_highlight.setForeground(QColor(128,0,0)); f_highlight.setFontItalic(true); f_highlight.setFontWeight(QFont::Bold); int i = -1, ci, j; if (!pSearchString.isEmpty()) { while ((i = text.indexOf(pSearchString, i+1, Qt::CaseInsensitive)) != -1) c << ColorRegion(f_highlight, i, pSearchString.length()); } qSort(c); // klfDbg( "searchstr="< appliedfmts; for (i = ci = 0; i < text.length(); ++i) { // klfDbg( "Processing char "<